aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/cp')
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog974
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-1993613
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-19945412
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-19953797
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-19964053
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-19972614
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-19986894
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-19996794
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20007281
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20013901
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20024581
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20036912
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20046884
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20053528
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20063502
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20073343
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20083263
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20093746
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20104064
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20115033
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20123067
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20134295
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog.ptr75
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog.tree-ssa573
-rw-r--r--gcc-4.9/gcc/cp/Make-lang.in246
-rw-r--r--gcc-4.9/gcc/cp/NEWS408
-rw-r--r--gcc-4.9/gcc/cp/call.c9544
-rw-r--r--gcc-4.9/gcc/cp/cfns.gperf247
-rw-r--r--gcc-4.9/gcc/cp/cfns.h365
-rw-r--r--gcc-4.9/gcc/cp/class.c9484
-rw-r--r--gcc-4.9/gcc/cp/config-lang.in32
-rw-r--r--gcc-4.9/gcc/cp/cp-array-notation.c1447
-rw-r--r--gcc-4.9/gcc/cp/cp-cilkplus.c145
-rw-r--r--gcc-4.9/gcc/cp/cp-gimplify.c1620
-rw-r--r--gcc-4.9/gcc/cp/cp-lang.c223
-rw-r--r--gcc-4.9/gcc/cp/cp-objcp-common.c324
-rw-r--r--gcc-4.9/gcc/cp/cp-objcp-common.h156
-rw-r--r--gcc-4.9/gcc/cp/cp-tree.def479
-rw-r--r--gcc-4.9/gcc/cp/cp-tree.h6230
-rw-r--r--gcc-4.9/gcc/cp/cvt.c1774
-rw-r--r--gcc-4.9/gcc/cp/cxx-pretty-print.c2433
-rw-r--r--gcc-4.9/gcc/cp/cxx-pretty-print.h96
-rw-r--r--gcc-4.9/gcc/cp/decl.c14476
-rw-r--r--gcc-4.9/gcc/cp/decl.h50
-rw-r--r--gcc-4.9/gcc/cp/decl2.c5011
-rw-r--r--gcc-4.9/gcc/cp/dump.c498
-rw-r--r--gcc-4.9/gcc/cp/error.c3612
-rw-r--r--gcc-4.9/gcc/cp/except.c1363
-rw-r--r--gcc-4.9/gcc/cp/expr.c153
-rw-r--r--gcc-4.9/gcc/cp/friend.c611
-rw-r--r--gcc-4.9/gcc/cp/g++spec.c405
-rw-r--r--gcc-4.9/gcc/cp/init.c4263
-rw-r--r--gcc-4.9/gcc/cp/lambda.c1095
-rw-r--r--gcc-4.9/gcc/cp/lang-specs.h67
-rw-r--r--gcc-4.9/gcc/cp/lex.c716
-rw-r--r--gcc-4.9/gcc/cp/mangle.c3915
-rw-r--r--gcc-4.9/gcc/cp/method.c2058
-rw-r--r--gcc-4.9/gcc/cp/name-lookup.c6236
-rw-r--r--gcc-4.9/gcc/cp/name-lookup.h370
-rw-r--r--gcc-4.9/gcc/cp/operators.def157
-rw-r--r--gcc-4.9/gcc/cp/optimize.c661
-rw-r--r--gcc-4.9/gcc/cp/parser.c32131
-rw-r--r--gcc-4.9/gcc/cp/parser.h408
-rw-r--r--gcc-4.9/gcc/cp/pt.c21975
-rw-r--r--gcc-4.9/gcc/cp/ptree.c240
-rw-r--r--gcc-4.9/gcc/cp/repo.c377
-rw-r--r--gcc-4.9/gcc/cp/rtti.c1602
-rw-r--r--gcc-4.9/gcc/cp/search.c2691
-rw-r--r--gcc-4.9/gcc/cp/semantics.c10691
-rw-r--r--gcc-4.9/gcc/cp/tree.c4112
-rw-r--r--gcc-4.9/gcc/cp/type-utils.h55
-rw-r--r--gcc-4.9/gcc/cp/typeck.c9202
-rw-r--r--gcc-4.9/gcc/cp/typeck2.c2074
-rw-r--r--gcc-4.9/gcc/cp/vtable-class-hierarchy.c1346
74 files changed, 263073 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/cp/ChangeLog b/gcc-4.9/gcc/cp/ChangeLog
new file mode 100644
index 000000000..e0229906d
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog
@@ -0,0 +1,974 @@
+2014-03-24 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/60627
+ * parser.c (cp_parser_parameter_declaration_clause): Prevent 'auto' from
+ introducing an implicit function template parameter within an explicit
+ instantiation.
+
+2014-03-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/60574
+ * decl.c (grokdeclarator): Change permerror about 'virtual auto'
+ to error.
+
+2014-03-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/60384
+ * name-lookup.c (push_class_level_binding_1): Check identifier_p
+ on the name argument.
+
+2014-03-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/60572
+ * init.c (build_zero_init_1): Ignore fields with error_mark_node
+ type.
+
+2014-03-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51474
+ * call.c (build_new_method_call_1): Handle pure virtuals called by
+ NSDMIs too.
+
+2014-03-17 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/60390
+ * parser.c (cp_parser_member_declaration): Don't allow
+ finish_fully_implicit_template to consider friend declarations to be
+ class member templates.
+ (synthesize_implicit_template_parm): Handling winding back through class
+ scope to the class being defined in order to inject a template argument
+ list.
+
+ PR c++/60391
+ * parser.c (cp_parser_skip_to_end_of_block_or_statement): Unwind generic
+ function scope as per cp_parser_skip_to_end_of_statement.
+
+2014-03-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59571
+ * typeck2.c (check_narrowing): Use fold_non_dependent_expr_sfinae.
+
+2014-03-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/60532
+ PR c++/58678
+ * search.c (get_pure_virtuals): Handle abstract dtor here.
+ (dfs_get_pure_virtuals): Not here.
+
+ PR c++/58678
+ * search.c (dfs_get_pure_virtuals): Treat the destructor of an
+ abstract class as pure.
+
+2014-03-13 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/60383
+ * pt.c (maybe_process_partial_specialization): Check return value
+ of check_specialization_namespace.
+
+2014-03-13 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/60254
+ * semantics.c (finish_static_assert): Call cxx_constant_value only
+ if require_potential_rvalue_constant_expression returns true.
+
+2014-03-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/60389
+ * method.c (get_inherited_ctor): New.
+ * cp-tree.h (get_inherited_ctor): Declare it.
+ * semantics.c (is_valid_constexpr_fn): Use it.
+
+2014-03-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/60367
+ * call.c (convert_default_arg): Remove special handling for
+ CONSTRUCTOR.
+
+ PR c++/53492
+ * parser.c (cp_parser_class_head): Also check PRIMARY_TEMPLATE_P
+ when deciding whether to call push_template_decl for a member class.
+ * pt.c (push_template_decl_real): Return after wrong levels error.
+
+2014-03-08 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/60033
+ * pt.c (tsubst_copy): When retrieving a capture pack from a generic
+ lambda, remove the lambda's own template argument list prior to fetching
+ the specialization.
+
+ PR c++/60393
+ * parser.c (cp_parser_parameter_declaration_clause): Move generic
+ function template unwinding on error into a more general location, ...
+ (cp_parser_skip_to_end_of_statement): ... here.
+
+2014-03-07 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (check_g++_parallelize): Split dg.exp.
+
+ * parser.c (cp_parser_type_id_1): Only allow 'auto' in C++1y if
+ we're in a trailing return type.
+
+ * typeck.c (comp_template_parms_position): 'auto' and
+ 'decltype(auto)' are different from real template parms.
+
+ * parser.c (cp_parser_using_declaration): Consume the semicolon
+ after bare parameter pack error.
+
+ * cp-tree.h (REF_PARENTHESIZED_P): New.
+ * semantics.c (force_paren_expr): Set it.
+ * pt.c (do_auto_deduction): Check it.
+ (tsubst) [COMPONENT_REF]: Copy it.
+ * typeck.c (maybe_warn_about_useless_cast): Don't strip dereference.
+
+ * decl.c (create_array_type_for_decl): Only warn about invalid
+ C++1y VLA if flag_iso or warn_vla>0.
+ (grokdeclarator): Likewise.
+ * pt.c (tsubst): Likewise.
+ * semantics.c (finish_decltype_type): Likewise.
+ * typeck.c (cxx_sizeof_or_alignof_type): Likewise.
+ (cp_build_addr_expr_1): Likewise.
+ * init.c (build_new_1): Improve diagnostics.
+
+2014-03-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58609
+ * decl.c (check_initializer): Return NULL_TREE after error;
+ consistently use inform.
+
+2014-03-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (check_initializer): Remove dead code.
+
+2014-03-06 Marek Polacek <polacek@redhat.com>
+
+ PR c/60197
+ * typeck.c (check_return_expr): Call contains_cilk_spawn_stmt instead
+ of checking tree code.
+
+2014-03-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * parser.c (cp_lexer_set_source_position): New.
+ (cp_parser_mem_initializer): Use it.
+ (cp_parser_postfix_open_square_expression): Likewise.
+ (cp_parser_parenthesized_expression_list): Likewise.
+ (cp_parser_new_initializer): Likewise.
+ (cp_parser_jump_statement): Likewise.
+ (cp_parser_initializer): Likewise.
+ (cp_parser_functional_cast): Likewise.
+
+2014-03-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/60409
+ * semantics.c (force_paren_expr): Only add a PAREN_EXPR to a
+ dependent expression.
+
+ PR c++/60361
+ * parser.c (cp_parser_template_id): Don't set up a CPP_TEMPLATE_ID
+ if re-parsing might succeed.
+ * semantics.c (finish_id_expression): Use of a parameter outside
+ the function body is a parse error.
+
+ * parser.c (cp_parser_mem_initializer): Set input_location
+ properly for init-list warning.
+ (cp_parser_postfix_open_square_expression): Likewise.
+ (cp_parser_parenthesized_expression_list): Likewise.
+ (cp_parser_new_initializer): Likewise.
+ (cp_parser_jump_statement): Likewise.
+ (cp_parser_initializer): Likewise.
+ (cp_parser_functional_cast): Likewise.
+
+2014-03-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/60417
+ * typeck2.c (process_init_constructor_record): Set
+ CONSTRUCTOR_IS_DIRECT_INIT on {} for omitted initializers.
+
+ PR c++/60415
+ PR c++/54359
+ * parser.c (cp_parser_direct_declarator): Set declarator to
+ cp_error_declarator on invalid qualified-id.
+
+2014-03-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/60376
+ * parser.c (cp_parser_using_declaration): Early return when
+ cp_parser_nested_name_specifier errors out.
+
+2014-03-01 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/60377
+ * parser.c (cp_parser_parameter_declaration_clause): Unwind generic
+ function scope on parse error in function parameter list.
+
+2014-03-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * method.c (implicitly_declare_fn): Remove redundant
+ DECL_TEMPLATE_RESULT and STRIP_TEMPLATE uses.
+ * semantics.c (is_instantiation_of_constexpr): Likewise.
+ * error.c (dump_function_decl): Likewise.
+
+2014-03-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/60379
+ * semantics.c (begin_maybe_infinite_loop): Use
+ fold_non_dependent_expr_sfinae.
+
+2014-02-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/58845
+ * typeck.c (cp_build_binary_op): Sorry on vector&&vector.
+
+2014-02-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58610
+ * cp-tree.h (DECL_DELETED_FN): Use LANG_DECL_FN_CHECK.
+ * call.c (print_z_candidate): Remove STRIP_TEMPLATE use.
+ * lambda.c (maybe_add_lambda_conv_op): Likewise.
+
+2014-02-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/60253
+ * call.c (convert_arg_to_ellipsis): Return error_mark_node after
+ error_at.
+
+2014-02-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/60353
+ PR c++/55877
+ * decl2.c (tentative_decl_linkage): Don't mess with functions that
+ are not yet defined.
+
+2014-02-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/60347
+ PR lto/53808
+ * class.c (clone_function_decl): Don't note_vague_linkage_fn.
+ * init.c (build_vtbl_address): Do it here.
+
+ PR c++/59231
+ PR c++/11586
+ PR c++/14710
+ PR c++/57132
+ * pt.c (struct warning_sentinel): New.
+ (tsubst_copy_and_build): Use it instead of
+ c_inhibit_evaluation_warnings.
+ * typeck.c (maybe_warn_about_useless_cast): Remove
+ c_inhibit_evaluation_warnings check.
+
+ PR c++/54440
+ * pt.c (get_template_parm_index): New.
+ (fixed_parameter_pack_p_1, fixed_parameter_pack_p): New.
+ (process_template_parm): Allow bare packs in template template
+ parm template parms.
+ (coerce_template_parameter_pack): Handle fixed template template
+ parm packs and fixed packs not at the end of the parm list.
+ (coerce_template_parms): Handle template parm packs not at the end
+ of the parm list.
+ (gen_elem_of_pack_expansion_instantiation): Handle a decl expansion.
+
+ PR c++/60182
+ * pt.c (unify): Ignore alias templates when deducing a template
+ template parameter.
+
+ PR c++/60345
+ Revert:
+ DR 1571
+ * call.c (reference_binding): Recurse on user-defined conversion.
+ (convert_like_real) [ck_ref_bind]: Explain cv-qual mismatch.
+
+2014-02-25 Jason Merrill <jason@redhat.com>
+
+ DR 1571
+ * call.c (reference_binding): Recurse on user-defined conversion.
+ (convert_like_real) [ck_ref_bind]: Explain cv-qual mismatch.
+
+ * call.c (print_conversion_rejection): Handle n_arg of -2.
+ (build_user_type_conversion_1): Pass it.
+
+ PR c++/55877
+ * decl2.c (no_linkage_error): Handle C++98 semantics.
+ (reset_type_linkage): Move from decl.c.
+ (reset_type_linkage_1, reset_type_linkage_2, bt_reset_linkage_1)
+ (bt_reset_linkage_2, reset_decl_linkage): New.
+ (tentative_decl_linkage): Factor out of expand_or_defer_fn_1.
+ (cp_write_global_declarations): Move condition into no_linkage_error.
+ * decl.c (grokfndecl, grokvardecl): Use no_linkage_error.
+ * semantics.c (expand_or_defer_fn_1): Factor out
+ tentative_decl_linkage.
+ * cp-tree.h: Adjust.
+
+ * decl2.c (finish_static_data_member_decl): Diagnose static data
+ member in unnamed class.
+ * class.c (finish_struct_anon_r): Avoid redundant diagnostic.
+
+ PR lto/53808
+ * class.c (clone_function_decl): Call note_vague_linkage_fn for
+ defaulted virtual dtor.
+
+ DR 1286
+ PR c++/60328
+ * pt.c (get_underlying_template): Fix equivalence calculation.
+
+2014-02-25 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/60311
+ * parser.c (function_being_declared_is_template_p): Return false when
+ processing a template parameter list.
+ (cp_parser_parameter_declaration_clause): Don't set
+ auto_is_implicit_function_template_parm_p when processing a
+ template parameter list.
+
+ * parser.c (synthesize_implicit_template_parm): Inject new template
+ argument list appropriately when a generic member function
+ of a class template is declared out-of-line.
+
+ PR c++/60065
+ * parser.c (cp_parser_direct_declarator): Don't save and
+ restore num_template_parameter_lists around call to
+ cp_parser_parameter_declaration_list.
+ (function_being_declared_is_template_p): New predicate.
+ (cp_parser_parameter_declaration_list): Use
+ function_being_declared_is_template_p as predicate for
+ inspecting current function template parameter list length
+ rather than num_template_parameter_lists.
+
+2014-02-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/60146
+ * pt.c (tsubst_omp_for_iterator): Don't let substitution of the
+ DECL_EXPR initialize a non-class iterator.
+
+ PR c++/60312
+ * parser.c (cp_parser_template_type_arg): Check for invalid 'auto'.
+
+2014-02-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/58170
+ * parser.c (cp_parser_type_name): Always check dependency.
+ (cp_parser_type_specifier_seq): Call
+ cp_parser_parse_and_diagnose_invalid_type_name.
+
+ PR c++/60108
+ * semantics.c (expand_or_defer_fn_1): Check DECL_DEFAULTED_FN.
+
+ PR c++/60185
+ * parser.c (cp_parser_default_argument): Clear
+ current_class_ptr/current_class_ref like tsubst_default_argument.
+
+ PR c++/60252
+ * lambda.c (maybe_resolve_dummy): Check lambda_function rather
+ than current_binding_level.
+
+ PR c++/60186
+ * typeck2.c (massage_init_elt): Call fold_non_dependent_expr_sfinae.
+
+ PR c++/60187
+ * parser.c (cp_parser_enum_specifier): Call
+ check_for_bare_parameter_packs.
+
+ PR c++/59347
+ * pt.c (tsubst_decl) [TYPE_DECL]: Don't try to instantiate an
+ erroneous typedef.
+
+ PR c++/60241
+ * pt.c (lookup_template_class_1): Update DECL_TEMPLATE_INSTANTIATIONS
+ of the partial instantiation, not the most general template.
+ (maybe_process_partial_specialization): Reassign everything on
+ that list.
+
+ PR c++/60216
+ * pt.c (register_specialization): Copy DECL_DELETED_FN to clones.
+ (check_explicit_specialization): Don't clone.
+
+ PR c++/60219
+ * pt.c (coerce_template_parms): Bail if argument packing fails.
+
+ PR c++/60224
+ * decl.c (cp_complete_array_type, maybe_deduce_size_from_array_init):
+ Don't get confused by a CONSTRUCTOR that already has a type.
+
+ PR c++/60227
+ * call.c (build_array_conv): Don't crash on VLA.
+
+ PR c++/60248
+ * mangle.c (mangle_decl): Don't make an alias for a TYPE_DECL.
+
+ PR c++/60252
+ * lambda.c (maybe_resolve_dummy): Don't try to capture this
+ in declaration context.
+
+ DR 1591
+ PR c++/60051
+ * pt.c (unify): Only unify if deducible. Handle 0-length list.
+
+ PR c++/60250
+ * parser.c (cp_parser_direct_declarator): Don't wrap a
+ type-dependent expression in a NOP_EXPR.
+
+ PR c++/60251
+ * lambda.c (is_normal_capture_proxy): Handle VLA capture.
+
+ PR c++/60167
+ PR c++/60222
+ PR c++/58606
+ * parser.c (cp_parser_template_argument): Restore dereference.
+ * pt.c (template_parm_to_arg): Dereference non-pack expansions too.
+ (process_partial_specialization): Handle deref.
+ (unify): Likewise.
+
+2014-02-21 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/60052
+ PR c++/60053
+ * parser.c (cp_parser_parameter_declaration_list): Correctly reset
+ implicit_template_scope upon leaving an out-of-line generic member
+ function definition.
+
+2014-02-20 Kai Tietz <ktietz@redhat.com>
+
+ PR c++/58873
+ * parser.c (cp_parser_functional_cast): Treat NULL_TREE
+ valued type argument as error_mark_node.
+
+ PR c++/58835
+ * semantics.c (finish_fname): Handle error_mark_node.
+
+2014-02-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/60046
+ * pt.c (maybe_instantiate_noexcept): Don't instantiate exception
+ spec from template context.
+
+2014-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/56563
+ * cp-objcp-common.c (cp_function_decl_explicit_p): Remove
+ FUNCTION_FIRST_USER_PARMTYPE (decl) != void_list_node check.
+
+ PR c++/60267
+ * pt.c (tsubst_expr): Handle ANNOTATE_EXPR.
+
+2014-02-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/60225
+ * semantics.c (ensure_literal_type_for_constexpr_object): Use
+ strip_array_types.
+
+2014-02-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/60215
+ * semantics.c (cxx_eval_constant_expression, [COMPONENT_REF]):
+ During error recovery allow_non_constant may be false.
+
+2014-02-18 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/60190
+ * parser.c (cp_parser_lambda_declarator_opt): Pop template parameter
+ scope whenever a template parameter list has been started, independent
+ of whether the function call operator was well-formed or not.
+
+ PR c++/60064
+ * parser.c (cp_parser_member_declaration): Pop fully implicit template
+ scope for generic friend declarations as well as for non-friends.
+
+2014-02-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/60047
+ * method.c (implicitly_declare_fn): A constructor of a class with
+ virtual base classes isn't constexpr (7.1.5p4).
+
+2014-02-05 Jan Hubicka <hubicka@ucw.cz
+
+ * parser.c (synthesize_implicit_template_parm): Use grow_tree_vec.
+
+2014-02-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/58703
+ * parser.c (cp_parser_omp_declare_reduction): Save and free
+ declarator_obstack.
+
+2014-02-03 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53017
+ PR c++/59211
+ * tree.c (handle_init_priority_attribute): Call default_conversion on
+ the attribute argument.
+
+2014-02-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58871
+ * method.c (synthesized_method_walk): If vbases is non-null but
+ is_empty is true, likewise don't worry about the virtual bases.
+
+2014-02-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51219
+ * typeck2.c (process_init_constructor_record): Just skip unnamed
+ bit-fields.
+
+2014-01-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/59469
+ * pt.c (mark_decl_instantiated): Call mark_needed.
+
+ PR c++/58672
+ * decl2.c (handle_tls_init): Handle null init fn.
+
+ PR c++/55800
+ * decl2.c (get_tls_init_fn): Copy DECL_EXTERNAL from the variable.
+
+2014-01-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59082
+ * class.c (build_vfield_ref): Early return error_mark_node if
+ TYPE_VFIELD (type) is null.
+ (build_base_path): Check return value of build_vfield_ref.
+
+2014-01-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/59646
+ * call.c (convert_like_real) [ck_aggr]: Set TARGET_EXPR_LIST_INIT_P.
+ [ck_list]: Check for error_mark_node.
+ (build_aggr_conv): Set LOOKUP_NO_NARROWING and check_narrowing.
+
+ PR c++/57043
+ * pt.c (fn_type_unification): Don't do DEDUCE_EXACT check
+ during partial ordering.
+
+2014-01-31 Marek Polacek <polacek@redhat.com>
+
+ PR c/59963
+ * typeck.c (build_function_call_vec): Add dummy arg_loc parameter.
+
+2014-01-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/57899
+ * cp-tree.h (struct saved_scope): Add x_local_specializations.
+ (local_specializations): New macro.
+ * pt.c (local_specializations): Remove variable.
+
+2014-01-30 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR c++/58708
+ * parser.c (make_string_pack): Use double_int::from_buffer.
+
+2014-01-30 Marek Polacek <polacek@redhat.com>
+
+ PR c/59940
+ * typeck.c (build_ptrmemfunc1): Call convert_and_check with
+ input_location.
+ * cvt.c (cp_convert_and_check): Call warnings_for_convert_and_check
+ with input_location.
+ * call.c (build_conditional_expr_1): Call unsafe_conversion_p with
+ loc parameter.
+
+2014-01-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58843
+ * typeck.c (lookup_destructor): Check dtor_type for error_mark_node.
+
+2014-01-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58649
+ * pt.c (lookup_template_class_1): Check start_enum return value
+ for error_mark_node.
+
+2014-01-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (duplicate_decls, typename_hash, typename_compare):
+ Use TYPE_IDENTIFIER.
+ * error.c (dump_type): Likewise.
+ * mangle.c (dump_substitution_candidates): Likewise.
+
+2014-01-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/59633
+ * decl2.c (attributes_naming_typedef_ok): New.
+ * cp-tree.h: Declare it.
+ * decl.c (grokdeclarator): Check it.
+ * tree.c (no_linkage_check): Handle VECTOR_TYPE.
+
+2014-01-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/59707
+ * call.c (add_builtin_candidate): Catch dependent types.
+
+ PR c++/59989
+ * pt.c (expand_template_argument_pack): Correct
+ non_default_args_count calculation.
+
+ PR c++/58466
+ * pt.c (unify_pack_expansion): Call expand_template_argument_pack.
+
+ PR c++/59956
+ * friend.c (do_friend): Pass the TEMPLATE_DECL to add_friend if we
+ have a friend template in a class template.
+ * pt.c (tsubst_friend_function): Look through it.
+ (push_template_decl_real): A friend member template is
+ primary.
+
+2014-01-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58846
+ * decl.c (get_dso_handle_node): Don't crash if dso_handle_node
+ == error_mark_node.
+
+2014-01-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58674
+ * pt.c (instantiate_template_1): Check for error_mark_node the second
+ argument too.
+
+2014-01-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/59916
+ * optimize.c (maybe_thunk_body): Build a RETURN_EXPR for
+ cdtor_returns_this case.
+
+ PR c++/59315
+ * decl.c (cxx_maybe_build_cleanup): Call mark_used.
+
+2014-01-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58702
+ * semantics.c (finish_omp_reduction_clause): Check type for
+ error_mark_node.
+
+2014-01-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/59791
+ * pt.c (tsubst_decl) [VAR_DECL]: Allow in unevaluated context.
+ (tsubst_copy): Use it if lookup fails.
+
+ PR c++/59818
+ * pt.c (tsubst_function_type): Make sure we keep the same function
+ quals.
+
+ PR c++/58701
+ * semantics.c (build_anon_member_initialization): Stop walking
+ when we run out of COMPONENT_REFs.
+
+ PR c++/58632
+ * decl.c (lookup_and_check_tag): Ignore template parameters if
+ scope == ts_current.
+ * pt.c (check_template_shadow): Don't complain about the injected
+ class name.
+
+ * decl.c (duplicate_decls): Tweak.
+
+ PR c++/53756
+ * mangle.c (write_unqualified_name): Handle operator auto.
+
+2014-01-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/59823
+ Core DR 1138
+ * call.c (reference_binding): Pass LOOKUP_NO_TEMP_BIND for
+ list-initialization. A conversion to rvalue ref that involves
+ an lvalue-rvalue conversion is bad.
+ (convert_like_real): Give helpful error message.
+
+ PR c++/54652
+ * decl.c (duplicate_decls): Always use oldtype for TYPE_DECL.
+
+ PR c++/58504
+ * pt.c (tsubst_copy_and_build) [TRAIT_EXPR]: Use tsubst for
+ types.
+
+ PR c++/58606
+ * pt.c (template_parm_to_arg): Call convert_from_reference.
+ (tsubst_template_arg): Don't strip reference refs.
+
+ PR c++/58639
+ * call.c (build_aggr_conv): Reject value-initialization of reference.
+
+ PR c++/58812
+ PR c++/58651
+ * call.c (convert_like_real): Give helpful error about excess braces
+ for ck_rvalue of scalar type.
+
+ Core DR 1288
+ * call.c (reference_binding): Only elide braces if the single
+ element is reference-related.
+
+ PR c++/58814
+ * typeck.c (cp_build_modify_expr): Make the RHS an rvalue before
+ stabilizing.
+
+ PR c++/58837
+ * typeck.c (cp_truthvalue_conversion): Use explicit comparison for
+ FUNCTION_DECL.
+
+ PR c++/59097
+ * decl.c (compute_array_index_type): Don't call
+ maybe_constant_value for a non-integral expression.
+
+2014-01-24 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * call.c (magic_varargs_p): Replaced flag_enable_cilkplus with
+ flag_cilkplus.
+ * cp-gimplify.c (cp_genericize): Likewise.
+ * decl.c (grokfndecl): Likewise.
+ * parser.c (cp_parser_postfix_expression): Likewise.
+ (cp_parser_postfix_open_square_expression): Likewise.
+ (cp_parser_direct_declarator): Likewise.
+ (is_cilkplus_vector_p): Likewise.
+ (cp_parser_omp_clause_name): Likewise.
+ (cp_parser_omp_all_clauses): Likewise.
+ * pt.c (apply_late_template_attributes): Likewise.
+ * typeck.c (cp_build_array_ref): Likewise.
+ (cp_build_compound_expr): Likewise.
+ (check_return_expr): Likewise.
+
+2014-01-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/58550
+ * decl.c (grokdeclarator): Turn pedwarn about auto return type in
+ c++11 into error.
+
+ PR c++/59886
+ PR c++/59659
+ * typeck2.c (process_init_constructor_array): Don't create
+ RANGE_EXPR yet.
+
+2014-01-24 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck2.c (split_nonconstant_init_1): Fix num_split_elts
+ handling for RANGE_ARRAY case.
+
+2014-01-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57524
+ * name-lookup.c (push_using_directive): Use timevar_cond_start.
+
+2014-01-23 Marek Polacek <polacek@redhat.com>
+
+ PR c/59846
+ * typeck.c (cp_build_binary_op): Pass location to shorten_compare.
+
+2014-01-23 Marek Polacek <polacek@redhat.com>
+
+ PR c/58346
+ * typeck.c (pointer_diff): Give an error on arithmetic on pointer to
+ an empty aggregate.
+
+2014-01-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/55189
+ * cp-tree.h (struct language_function): Add infinite_loop and
+ infinite_loops.
+ (current_function_infinite_loop): New.
+ * semantics.c (begin_maybe_infinite_loop, end_maybe_infinite_loop)
+ (break_maybe_infinite_loop): New.
+ (finish_while_stmt_cond, finish_while_stmt, begin_do_stmt)
+ (finish_do_stmt, finish_for_cond, finish_for_stmt)
+ (begin_range_for_stmt): Use them.
+ * decl.c (finish_function): Don't warn about missing return
+ if current_function_infinite_loop.
+ * pt.c (instantiate_decl): Copy current_function_infinite_loop.
+ * parser.c (cp_parser_jump_statement): Call break_maybe_infinite_loop.
+
+ * call.c (build_op_delete_call): Use make_tree_vector and
+ release_tree_vector.
+
+2014-01-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58980
+ * parser.c (cp_parser_enum_specifier): Handle TYPENAME_TYPE as
+ nested_name_specifier.
+
+2014-01-23 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * parser.c (cp_parser_direct_declarator): When Cilk Plus is enabled
+ see if there is an attribute after function decl. If so, then
+ parse them now.
+ (cp_parser_late_return_type_opt): Handle parsing of Cilk Plus SIMD
+ enabled function late parsing.
+ (cp_parser_gnu_attribute_list): Parse all the tokens for the vector
+ attribute for a SIMD-enabled function.
+ (cp_parser_omp_all_clauses): Skip parsing to the end of pragma when
+ the function is used by SIMD-enabled function (indicated by NULL
+ pragma token). Added 3 new clauses: PRAGMA_CILK_CLAUSE_MASK,
+ PRAGMA_CILK_CLAUSE_NOMASK and PRAGMA_CILK_CLAUSE_VECTORLENGTH
+ (cp_parser_cilk_simd_vectorlength): Modified this function to handle
+ vectorlength clause in SIMD-enabled function and #pragma SIMD's
+ vectorlength clause. Added a new bool parameter to differentiate
+ between the two.
+ (cp_parser_cilk_simd_fn_vector_attrs): New function.
+ (is_cilkplus_vector_p): Likewise.
+ (cp_parser_late_parsing_elem_fn_info): Likewise.
+ (cp_parser_omp_clause_name): Added a check for "mask", "nomask"
+ and "vectorlength" clauses when Cilk Plus is enabled.
+ (cp_parser_omp_clause_linear): Added a new parameter of type bool
+ and emit a sorry message when step size is a parameter.
+ * parser.h (cp_parser::cilk_simd_fn_info): New field.
+ * decl.c (grokfndecl): Added flag_enable_cilkplus along with
+ flag_openmp.
+ * pt.c (apply_late_template_attributes): Likewise.
+
+2014-01-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/58809
+ * semantics.c (finish_omp_reduction_clause): Reject
+ BIT_AND_EXPR, BIT_IOR_EXPR and BIT_XOR_EXPR on COMPLEX_TYPEs.
+
+2014-01-22 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ PR c++/59482
+ * parser.c (cp_parser_class_head): Push the class before parsing
+ the base-clause, pop after it.
+
+2014-01-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * decl2.c (cpp_check): Revert prototype change.
+
+2014-01-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59270
+ PR c++/58811
+ * init.c (build_value_init_noctor): Don't pass error_mark_node to
+ build_value_init.
+
+2014-01-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59269
+ * init.c (build_value_init_noctor): Assert !TYPE_HAS_COMPLEX_DFLT
+ only when errorcount == 0.
+
+2014-01-17 Marek Polacek <polacek@redhat.com>
+
+ PR c++/59838
+ * cvt.c (ocp_convert): Don't segfault on non-existing
+ ENUM_UNDERLYING_TYPE.
+
+2014-01-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/59821
+ * tree.c (bot_manip): Update the location of builtin_LINE and
+ builtin_FILE calls.
+
+2014-01-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/59659
+ * typeck2.c (massage_init_elt): New.
+ (process_init_constructor_record)
+ (process_init_constructor_union): Use it.
+ (process_init_constructor_array): Use it. Use RANGE_EXPR.
+ (split_nonconstant_init_1): Handle it.
+ * semantics.c (cxx_eval_vec_init_1): Use force_rvalue.
+
+2014-01-09 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR c++/59631
+ * parser.c (cp_parser_postfix_expression): Added a new if-statement
+ and replaced an existing if-statement with else-if statement.
+ Changed an existing error message wording to match the one from the C
+ parser.
+
+2014-01-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/59614
+ * class.c (abi_tag_data): Add tags field.
+ (check_abi_tags): Initialize it.
+ (find_abi_tags_r): Support collecting missing tags.
+ (mark_type_abi_tags): Don't look at template args.
+ (inherit_targ_abi_tags): New.
+ (check_bases_and_members): Use it.
+ * cp-tree.h (ABI_TAG_IMPLICIT): New.
+ * mangle.c (write_abi_tags): Check it.
+
+2014-01-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/58856
+ * pt.c (num_innermost_template_parms): New.
+ (get_underlying_template): Use it.
+
+ PR c++/58965
+ * mangle.c (write_guarded_var_name): Handle null DECL_NAME.
+
+2014-01-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * semantics.c (trait_expr_value, [CPTK_IS_BASE_OF]): Implement
+ the letter of 20.11.6 about Base and Derived naming the same
+ class type modulo cv-qualifiers.
+
+2014-01-06 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/59635
+ * lambda.c (maybe_add_lambda_conv_op): Handle marking conversion
+ function as unimplemented for generic lambdas with varargs.
+
+ PR c++/59636
+ * parser.c (cp_parser_template_parameter): Early out with
+ error_mark_node if parameter declaration was not parsed.
+
+ PR c++/59629
+ * parser.c (cp_parser_lambda_expression): Save/reset/restore
+ auto_is_implicit_function_template_parm_p around lambda body.
+
+ PR c++/59638
+ * parser.c (cp_parser_init_declarator): Undo fully implicit
+ template parameter list when declarator is not a function.
+
+2014-01-03 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/58950
+ * cvt.c (convert_to_void): Handle VEC_PERM_EXPR and VEC_COND_EXPR.
+
+2014-01-03 Tobias Burnus <burnus@net-b.de>
+
+ PR c++/58567
+ * pt.c (tsubst_omp_for_iterator): Early return for error_mark_node.
+
+2014-01-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ Core DR 1442
+ PR c++/59165
+ * parser.c (cp_parser_perform_range_for_lookup): Don't pass true
+ as include_std to perform_koenig_lookup.
+ (cp_parser_postfix_expression): Adjust.
+ * pt.c (tsubst_copy_and_build): Likewise.
+ * semantics.c (perform_koenig_lookup): Remove bool parameter.
+ (omp_reduction_lookup): Adjust.
+ * name-lookup.c (lookup_arg_dependent_1): Remove bool parameter.
+ (lookup_arg_dependent): Likewise.
+ (lookup_function_nonclass): Adjust.
+ * name-lookup.h: Adjust declaration.
+ * cp-tree.h: Likewise.
+
+2014-01-02 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/59087
+ * parser.c (cp_parser_userdef_numeric_literal): Mention
+ -fext-numeric-literals in the message.
+
+2014-01-02 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/59641
+ * call.c (build_conditional_expr_1): Check the return value of
+ force_rvalue.
+
+2014-01-02 Marc Glisse <marc.glisse@inria.fr>
+
+ * call.c (convert_like_real): Check complain.
+
+2014-01-02 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/59378
+ * typeck.c (build_x_vec_perm_expr): Handle non-dependent arguments
+ in templates.
+
+2014-01-02 Richard Sandiford <rdsandiford@googlemail.com>
+
+ Update copyright years
+
+2014-01-02 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * cp-array-notation.c, cp-cilkplus.c, vtable-class-hierarchy.c: Use
+ the standard form for the copyright notice.
+
+Copyright (C) 2014 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-1993 b/gcc-4.9/gcc/cp/ChangeLog-1993
new file mode 100644
index 000000000..45ca571fa
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-1993
@@ -0,0 +1,613 @@
+Tue Dec 28 21:10:03 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-init.c (expand_vec_init): Remove comptypes test, as it is too
+ harsh here.
+
+Tue Dec 28 13:42:22 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-pt.c (do_pending_expansions): Decide to expand a template
+ member function, based upon it's class type, not the class type of
+ the first place it was declared.
+
+Tue Dec 28 05:42:31 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-class.c (is_normal): New routine, use to determine when the
+ given binfo is the normal one. (The one that should have the simple
+ vtable name.)
+ * cp-class.c (modify_other_vtable_entries): Use DECL_ASSEMBLER_NAME
+ to check if two fndecls are `the same'. Sometimes this routine can
+ modify the main vtable, and normal should be 1, in that case, so use
+ is_normal() to determine if this is the main vtable for the class.
+ Don't recurse down virtual bases, as they are shared, and we take
+ care of them elsewhere.
+ * cp-class.c (modify_vtable_entries): If we have already updated the
+ vtable with the new virtual, don't do it again.
+ * cp-class.c (finish_struct): Set CLASSTYPE_VFIELD_PARENT as
+ appropriate. Do virtual function overriding in virtual bases, after
+ normal overriding, so that the base function list in DECL_VINDEX is
+ not overridden, before we have a chance to run through the list.
+ Use DECL_ASSEMBLER_NAME to check if two fndecls are `the same'.
+ Make sure we pass the right address into modify_vtable_entries.
+ * cp-tree.h (CLASSTYPE_VFIELD_PARENT): New field to indicate which
+ binfo is the one that has the vtable that we based our vtable on.
+
+Fri Dec 24 09:40:52 1993 Michael Tiemann <tiemann@blues.cygnus.com>
+
+ * cp-typeck.c (c_expand_start_case): Use default_conversion to
+ convert expression from reference type if necessary.
+
+Wed Dec 22 17:58:43 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-typeck.c (build_unary_op): Make sure that it's a TREE_LIST before
+ trying to read its TREE_VALUE.
+
+ * cp-class.c (finish_struct_methods): Clear DECL_IN_AGGR_P here.
+ (finish_struct): Instead of here.
+
+Tue Dec 21 14:34:25 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.c (list_hash_lookup_or_cons): Make sure the type doesn't
+ have TYPE_PTRMEMFUNC_P set before we try to build its
+ CLASSTYPE_ID_AS_LIST.
+ (get_decl_list): Likewise, when trying to read it.
+
+ * cp-tree.h (VTABLE_NAME): No def with NO_{DOLLAR,DOT} defined.
+ (VTABLE_NAME_P): Use it instead of VTABLE_NAME_FORMAT.
+
+Mon Dec 20 13:35:03 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-typeck.c (rationalize_conditional_expr): New function.
+ (unary_complex_lvalue): Use it.
+ (build_modify_expr): Use it, since trying to do an ADDR_EXPR of it
+ with build_unary_op won't cut it. Don't wrap the COND_EXPR with a
+ SAVE_EXPR either.
+
+ * cp-decl2.c (explicit_warn_return_type): Deleted variable.
+ (lang_decode_option): Set warn_return_type, not explicit_*, for
+ -Wreturn-type and -Wall. This is what rest_of_compilation uses to
+ decide if it should go into jump_optimize or not.
+ * cp-tree.h (explicit_warn_return_type): Deleted.
+ * cp-decl.c (grokdeclarator): Use warn_return_type, not explicit_*.
+ (finish_function): Also complain about no return in a non-void fn if
+ we're being pedantic (don't rely on use of -Wreturn-type).
+
+Fri Dec 17 15:45:46 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-decl.c (grokdeclarator): Forbid declaration of a function as
+ static if it's being done inside another function.
+
+ * cp-search.c (compute_visibility): Check for friendship both ways.
+
+Fri Dec 17 14:28:25 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-cvt.c (build_default_binary_type_conversion): Make error
+ messages more helpful.
+
+ * cp-error.c (op_as_string): New function, returns "operator =="
+ given EQ_EXPR or suchlike.
+
+Fri Dec 17 13:28:11 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-call.c (print_n_candidates): New function.
+ (build_overload_call_real): Use it when we complain about a call
+ being ambiguous.
+
+Fri Dec 17 12:41:17 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-call.c (build_method_call): Fix checking for static call
+ context.
+
+ * cp-method.c (build_opfncall): Call build_indirect_ref on argument
+ to operator new.
+
+ * cp-init.c (build_new): Don't mess with rval when building
+ indirect ref.
+
+Thu Dec 16 16:48:05 1993 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-lex.c (default_assign_ref_body): Add check when TYPE_NESTED_
+ NAME(type) may not be exist. It's not a problem for old compiler.
+
+Thu Dec 16 14:46:06 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (CLASSTYPE_ALTERS_VISIBILITIES_P): Delete macro, it's
+ never used for anything.
+ (struct lang_type, member type_flags): Delete field
+ `alters_visibility', and up `dummy' by 1.
+ * cp-class.c (finish_base_struct): Delete code that copies the
+ setting of CLASSTYPE_ALTERS_VISIBILITIES_P.
+ (finish_struct): Delete code that sets it.
+
+Thu Dec 16 14:44:39 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c, cp-init.c, cp-typeck.c: Fix arguments to
+ build_method_call that I messed up before.
+
+ * cp-search.c (get_base_distance): If protect > 1, allow immediate
+ private base.
+
+ * cp-class.c (finish_base_struct): Set cant_synth_* correctly.
+ (finish_struct): Likewise. Well, nigh-correctly; it won't deal
+ properly with the case where a class contains an object of an
+ ambiguous base class which has a protected op=. Should be fixed
+ when the access control code gets overhauled.
+ (finish_struct_methods): Set TYPE_HAS_NONPUBLIC_* correctly.
+
+Thu Dec 16 12:17:06 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-lex.c (real_yylex): Turn the code back on that deals with
+ __FUNCTION__ and __PRETTY_FUNCTION__. Don't use lookup_name, to
+ avoid the ambiguity problems that led to it being turned off in the
+ first place.
+
+ * cp-method.c (hack_identifier): Also check for a TYPE_PTRMEMFUNC_P
+ to see if something is a method.
+
+Wed Dec 15 18:35:58 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-typeck.c (build_modify_expr): Avoid error messages on small
+ enum bit fields.
+ * cp-typeck.c (convert_for_assignment): Add missing argument to
+ cp_warning and cp_pedwarn calls.
+
+Wed Dec 15 18:25:32 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-parse.y (member_init): ANSI C++ doesn't forbid old-style base
+ initializers; it's just anachronistic.
+
+ * cp-decl.c (finish_decl): Don't require external-linkage arrays
+ to have a complete type at declaration time when pedantic.
+
+Tue Dec 14 11:37:23 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (pushdecl): Don't set DECL_CONTEXT if it's already set.
+
+ * cp-call.c (build_method_call): Don't dereference pointer given
+ as instance.
+
+ * cp-decl.c (finish_function): Don't pass pointer to
+ build_method_call.
+ (finish_function): Likewise.
+
+ * cp-typeck.c (build_x_function_call): Likewise.
+
+ * cp-method.c (build_component_type_expr): Likewise.
+
+ * cp-init.c (build_member_call): Likewise.
+ (build_new): Likewise.
+
+Mon Dec 13 18:04:33 1993 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-decl.c (xref_tag): Fix regression created by changes made
+ in Dec. 7 1993.
+ * cp-decl.c (xref_defn_tag): Fix parallel nested class problem.
+
+Fri Dec 10 12:40:25 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-call.c (compute_conversion_costs_ansi) [DEBUG_MATCHING]: Print
+ out the final evaluation of the function, so we can see if ELLIPSIS,
+ USER, and EVIL were set at the end.
+
+ * cp-call.c (convert_harshness_ansi): When the parm isn't an lvalue,
+ only go for setting TRIVIAL_CODE if we are dealing with types that
+ are compatible.
+
+Thu Dec 9 18:27:22 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-decl.c (flag_huge_objects): New flag to allow large objects.
+ * toplev.c (lang_options): Likewise.
+ * cp-decl2.c (flag_huge_objects, lang_f_options): Likewise.
+ * cp-decl.c (delta_type_node): New type for delta entries.
+ * cp-tree.h (delta_type_node): Likewise.
+ * cp-decl.c (init_decl_processing): Setup delta_type_node.
+ * cp-decl.c (init_decl_processing, build_ptrmemfunc_type): Use
+ delta_type_node instead of short_integer_type_node.
+ * cp-class.c (build_vtable_entry): Likewise.
+
+Thu Dec 9 16:19:05 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (OPERATOR_TYPENAME_P): Define outside of
+ NO_{DOLLAR,DOT} macro checks, so it always gets defined.
+ (VTABLE_NAME_P): Define for NO_DOT && NO_DOLLAR_IN_LABEL.
+
+Wed Dec 8 17:38:06 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-decl.c (finish_decl): Make sure things that can go into
+ "common", do go into common, if -fcommon is given.
+
+Wed Dec 8 13:01:54 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-call.c (print_harshness) [DEBUG_MATCHING]: New function.
+ (compute_conversion_costs_ansi) [DEBUG_MATCHING]: Print out
+ argument matching diagnostics to make instantly clear what the
+ compiler is doing.
+
+ * cp-call.c (convert_harshness_ansi): If the parm isn't an lvalue,
+ then check to see if the penalty was increased due to
+ signed/unsigned mismatch, and use a TRIVIAL_CODE if it wasn't.
+
+Tue Dec 7 18:29:14 1993 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-decl.c (xref_tag, pushtag): Fix nested class search/resolution
+ problem.
+
+Tue Dec 7 16:09:34 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-class.c (finish_struct): Before synthesizing methods, if no
+ methods have yet been declared then set nonprivate_method. Don't
+ set non_private method after synthesizing a method.
+
+ * cp-lex.c (extract_interface_info): If flag_alt_external_templates
+ is set, tie emitted code to the location of template instantiation,
+ rather than definition.
+
+ * cp-tree.h: Declare flag_alt_external_templates.
+
+ * cp-decl2.c (lang_decode_option): Support -falt-external-templates.
+
+ * toplev.c (lang_options): Likewise.
+
+Mon Oct 4 12:50:02 1993 Chip Salzenberg <chip@fin.uucp>
+
+ [changes propagated from 930810 snapshot]
+ * cp-decl.c (init_decl_processing): Make long long available for use
+ as SIZE_TYPE and PTRDIFF_TYPE.
+ (finish_decl): Allow file-scope static incomplete array.
+ (grokdeclarator): Don't pass on const and volatile fron function
+ value type to function type.
+ Warn here for volatile fn returning non-void type.
+ * cp-parse.y (attrib): Accept attributes `volatile' with alias
+ `noreturn', and `const'.
+ * cp-typeck.c (default_conversion): Don't lose const and volatile.
+ (build_binary_op_nodefault): Generate pedantic warning for comparison
+ of complete pointer type with incomplete pointer type.
+ (build_c_cast): Be careful that null pointer constant be INTEGER_CST.
+
+Tue Dec 7 10:46:48 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-init.c (expand_vec_init): When creating a temporary for copying
+ arrays, use the type of the source, not the target.
+
+ * cp-cvt.c (convert): Pass an argument for errtype to
+ convert_to_reference.
+
+ * cp-error.c (dump_expr, COMPONENT_REF & CALL_EXPR): Deal with
+ methods, -> and `this'.
+
+Mon Dec 6 17:12:33 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-error.c (parm_as_string): New function; returns `this' or arg
+ number. Corresponds to %P.
+ (dump_expr): Deal with method calls.
+
+ * cp-cvt.c (convert_to_reference): Stop using warn_for_assignment.
+ * cp-typeck.c (convert_for_assignment): Likewise.
+ (warn_for_assignment): Lose.
+
+Mon Dec 6 11:33:35 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-call.c (ideal_candidate_ansi): Delete code that was never
+ doing anything useful. Instead, sort once, and DO NOT wipe
+ out any codes with EVIL_CODE, since that's what we use as a
+ marker for the end of the list of candidates.
+
+ * cp-cvt.c (convert_to_aggr): Make sure to always set H_LEN.
+
+Mon Dec 6 12:49:17 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-init.c (get_aggr_from_typedef): New function, like
+ is_aggr_typedef but returns the _TYPE.
+
+ * cp-call.c, cp-init.c, cp-method.c: Eradicate err_name.
+
+Sun Dec 5 18:12:48 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-lex.c (readescape): Pedwarn when a hex escape is out of range.
+
+Thu Nov 25 23:50:19 1993 Chip Salzenberg <chip@fin.uucp>
+
+ Delay language context change until beginning of next decl.
+
+ * cp-lex.h (c_header_level): Removed.
+ (pending_lang_change): Declared.
+ * cp-lex.c (c_header_level): Renamed from in_c_header, made static.
+ (pending_lang_change): Defined.
+ (check_newline): Rework code that recognizes line number and
+ filename changes. Instead of pushing and popping lang context,
+ increment and decrement pending_lang_change.
+ (do_pending_lang_change): Push and pop lang context according
+ to value of pending_lang_change.
+ * cp-parse.y (extdefs): Use lang_extdef instead of extdef.
+ (extdef): Same as extdef, but call do_pending_lang_change() first.
+
+Mon Nov 15 15:39:15 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-typeck.c (build_binary_op_nodefault): Warn for ordered
+ compare of ptr with 0 only if pedantic in both cases.
+
+Thu Nov 25 13:31:37 1993 Chip Salzenberg <chip@fin.uucp>
+
+ Reinstate the below patch, which got lost in the Cygnus merge:
+ Tue Nov 23 13:59:24 1993 Hallvard B Furuseth (hbf@durin.uio.no)
+ * cp-parse.y (maybe_type_qual): Don't fail to set $$.
+
+Wed Nov 17 19:03:30 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-parse.y (attrib): Allow "ident(ident)" like the C front end.
+
+Fri Oct 22 20:43:37 1993 Paul Eggert <eggert@twinsun.com>
+
+ * cp-lex.c (real_yylex): Diagnose floating point constants
+ that are too large.
+
+Wed Nov 17 19:10:37 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-type2.c (build_functional_cast): ARM page 16: When a class
+ and an object, function or enumerator are declared in the same
+ scope with the same name, the class name is hidden.
+
+Wed Nov 17 19:07:18 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-call.c (convert_harshness_ansi): Distinguish float, double,
+ and long double from each other when overloading.
+ (compute_conversion_costs_{ansi,old}, build_method_call,
+ build_overlay_call_real, convert_to_aggr): Always set and
+ always use H_LEN member of candidate structure.
+
+Mon Oct 11 23:10:53 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-decl.c (duplicate_decls): Note redeclarations of library
+ functions, and generate distinct warnings for them.
+
+Mon Oct 4 12:26:49 1993 Chip Salzenberg <chip@fin.uucp>
+
+ Support format warnings in G++.
+
+ * cp-tree.h: Protect against multiple inclusion.
+ Declare all public functions in c-common.c (copy from c-tree.h).
+ (STDIO_PROTO): Define.
+ (warn_format): Declare.
+ (record_format_info): Remove declaration.
+ * cp-decl.c (init_decl_processing): Call init_function_format_info.
+ * cp-decl2.c (lang_decode_option): Make "-Wall" include warn_format.
+ * cp-typeck.c (build_function_call_real): Call check_function_format.
+ (record_format_info): Remove -- obsolete stub.
+
+Sat Jul 24 12:04:29 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-decl.c (duplicate_decls): Don't warn for non-extern var decl
+ following an extern one (for -Wredundant-decls).
+ * cp-parse.y (primary): In statement expression case, if compstmt
+ returns something other than a BLOCK, return it unchanged.
+
+Thu Dec 2 20:44:58 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp-decl.c (warn_extern_redeclared_static): New function made
+ from code extracted from pushdecl.
+ (duplicate_decls, pushdecl): Call new function.
+ (lookup_name_current_level): Allow for IDENTIFIER_GLOBAL_VALUE
+ to be a TREE_LIST when function is declared in 'extern "C" {}'.
+
+Fri Dec 3 16:01:10 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-class.c (duplicate_tag_error): Use cp_error.
+ (finish_base_struct): Check for ambiguity with direct base, and don't
+ generate op= or copy ctor if it exists.
+
+Fri Dec 3 15:32:34 1993 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-init.c (expand_member_init): When initializer name is null,
+ don't try to build it now because emit_base_init will handle it.
+
+Fri Dec 3 12:28:59 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-lex.c (init_lex): Initialize input_filename to "<internal>" for
+ code such as ExceptionHandler::operator=.
+
+Fri Dec 3 10:32:08 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (grokdeclarator): Don't try to print out dname when
+ complaining about arrays of references if decl_context==TYPENAME,
+ since it will be null.
+
+ * cp-decl2.c: Default to flag_ansi_overloading.
+
+Thu Dec 2 18:05:56 1993 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-call.c (build_method_call): Use binfo from instance if it's
+ different from binfo (basetype_path) passed from above.
+
+Wed Nov 17 19:14:29 1993 Chip Salzenberg <chip@fin.uucp>
+
+ cp-error.c (dump_expr): Use unsigned chars to output a
+ TREE_REAL_CST in hex.
+
+Thu Dec 2 11:05:48 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-class.c (finish_struct): Fix typo in setting
+ cant_synth_asn_ref.
+
+ * cp-tree.h (TYPE_NESTED_NAME): New macro, does
+ DECL_NESTED_TYPENAME (TYPE_NAME (NODE)).
+
+ * cp-lex.c (default_copy_constructor_body): Change
+ DECL_NAME (TYPE_NAME (btype)) to TYPE_NESTED_NAME (btype).
+ (default_assign_ref_body): Likewise.
+ (default_copy_constructor_body): Call operator= explicitly for
+ base classes that have no constructor.
+
+Thu Dec 2 10:47:15 1993 Michael Tiemann <tiemann@blues.cygnus.com>
+
+ * cp-call.c (build_method_call): If the instance variable is
+ converted to error_mark_node when we're trying to convert it to the
+ base type of a method we're looking up, return error_mark_node.
+
+Thu Dec 2 10:41:16 1993 Torbjorn Granlund <tege@cygnus.com>
+
+ * cp-typeck.c (build_binary_op_nodefault): In *_DIV_EXPR *_MOD_EXPR
+ cases, tests for unsigned operands by peeking inside a NOP_EXPR.
+
+Wed Dec 1 13:33:34 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-call.c (compute_conversion_costs_ansi): Use the size of struct
+ harshness_code, not the size of short, for clearing out the
+ ansi_harshness.
+
+ * cp-call.c (print_candidates): New function.
+ (build_method_call): When we had some candidates, but didn't get a
+ usable match, don't report that we got an error with the first
+ candidate. Instead, say there were no matches, and list the
+ candidates with print_candidates. In the second pass, make sure we
+ clear out ever_seen, so we can accurately count the number of
+ functions that qualified.
+
+Wed Dec 1 09:53:59 1993 Torbjorn Granlund <tege@cygnus.com>
+
+ * cp-typeck.c (build_binary_op_nodefault): Shorten for *_MOD_EXPR
+ only if op1 is known to be != -1.
+ (build_binary_op_nodefault): Handle *_DIV_EXPR likewise.
+
+Tue Nov 30 14:07:26 1993 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-method.c (hack_identifier): If the field itself is private, and
+ not from a private base class, say so.
+
+Mon Nov 29 03:00:56 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (grokdeclarator): Always warn on initialization of
+ const member.
+
+Wed Nov 24 00:49:35 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-class.c (finish_struct): Set TYPE_GETS_CONST_* properly.
+ (finish_base_struct): Set cant_synth_asn_ref properly.
+
+ * cp-lex.c (cons_up_default_function): Add section for operator=.
+ (default_assign_ref_body): New function, mostly cribbed from
+ default_copy_constructor_body.
+
+ * cp-class.c (base_info): Add members cant_synth_copy_ctor,
+ cant_synth_asn_ref, no_const_asn_ref.
+ (finish_base_struct): Update no_const_asn_ref, note that you should
+ update cant_synth_*, propagate TYPE_GETS_ASSIGN_REF.
+ (finish_struct): Add decls for cant_synth_*, no_const_asn_ref, and
+ initialize them properly. Set no_const_asn_ref properly. Set
+ cant_synth_* in some of the situations where they should be set.
+ Propagate TYPE_GETS_ASSIGN_REF. Use cant_synth_copy_ctor. Add call
+ to cons_up_default_function for operator=.
+
+Tue Nov 23 20:24:58 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-cvt.c (convert_force): Add code to perform casting of pointer
+ to member function types.
+ * cp-typeck.c (build_ptrmemfunc): Add FORCE parameter to indicate
+ when the conversion should be done, regardless.
+ * cp-tree.h (build_ptrmemfunc): Likewise.
+ * cp-type2.c (digest_init): Likewise.
+ * cp-typeck.c (convert_for_assignment): Likewise.
+
+Tue Nov 23 18:06:58 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-error.c (dump_expr): Do the right thing for variables of
+ reference type.
+
+ * cp-decl.c (grok_op_properties): Set TYPE_HAS_ASSIGN_REF
+ and its kin properly.
+ (xref_tag): Propagate TYPE_GETS_ASSIGN_REF.
+
+Tue Nov 23 12:26:13 1993 Mike Stump <mrs@cygnus.com>
+
+ * cp-method.c (build_opfncall): Don't count pointer to member
+ functions as aggregates here, as we don't want to look up methods in
+ them. The compiler would core dump if we did, as they don't have
+ normal names.
+ * cp-typeck.c (build_indirect_ref): Improve wording on error
+ message.
+
+Mon Nov 22 14:22:23 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (grok_op_properties): Allow operator?: with pedwarn
+ (since it's supported in other compiler bits).
+
+ * cp-method.c (report_type_mismatch): Use cp_error; ignore err_name
+ argument.
+
+ * cp-error.c (dump_function_decl): Don't print return type for
+ constructors and destructors.
+
+ * cp-cvt.c (cp_convert_to_pointer): Import code from
+ convert_to_pointer so we can return error_mark_node in the case of an
+ error, and to allow more meaningful error messages.
+ (build_type_conversion): Don't go through void* when trying
+ to convert to a pointer type.
+
+ * cp-decl.c (grokfndecl): Move call to grok_op_properties back
+ after grokclassfn so that it's dealing with the right decl.
+ (grok_op_properties): Don't assert !methodp for op new and op delete.
+
+ * cp-init.c (build_delete): Don't use TYPE_BUILT_IN (there are now
+ no uses of it in the compiler).
+
+ * cp-call.c (build_scoped_method_call): Fix for destructors of simple
+ types.
+ (build_method_call): Likewise.
+
+Fri Nov 19 12:59:38 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.c (count_functions): Abstraction function.
+
+ * cp-call.c (build_overload_call_real): Deal with new overloading
+ properly, remove dead code.
+
+ * gcc.c (default_compilers): Generate and use .ii files in the
+ intermediate stage of compiling C++ source.
+
+Fri Nov 19 11:26:09 1993 Jim Wilson <wilson@sphagnum.cygnus.com>
+
+ * cp-expr.c (cplus_expand_expr): Make call_target a valid memory
+ address before using it, so it can be later safely compared.
+
+Fri Nov 12 15:30:27 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-pt.c (tsubst): Deal with new overloading.
+
+ * cp-typeck.c (fntype_p): Is the arg function type?
+ (comp_target_parms): pedwarn on conversion from (anything) to (...).
+ (build_x_function_call): Deal with new overloading.
+
+ * cp-tree.c (decl_list_length): Deal with new overloading.
+ (decl_value_member): Like value_member, but for DECL_CHAINs.
+
+ * cp-decl.c (duplicate_decls): Deal with new overloading.
+ (start_decl): Likewise.
+
+ * cp-class.c (instantiate_type): Deal with new overloading.
+
+ * cp-call.c (convert_harshness_ansi): Deal with new overloading.
+ (convert_harshness_old): Deal with new overloading.
+ (build_overload_call_real): Likewise.
+
+Mon Nov 8 13:50:49 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.c (get_unique_fn): New function; returns FUNCTION_DECL
+ if unambiguous, NULL_TREE otherwise.
+ (get_first_fn): Returns the first appropriate FUNCTION_DECL.
+ (is_overloaded_fn): Returns whether or not the passed tree is
+ a function or list of functions.
+
+ * cp-init.c (init_init_processing): Use `get_first_fn' to find
+ the FUNCTION_DEFN for new and delete.
+
+ * cp-decl.c (push_overloaded_decl): Use new overloading strategy, cut
+ code size in half (I spit on special cases).
+
+Tue Sep 7 20:03:33 1993 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c: Allow references and template type parameters as well
+
+
+Copyright (C) 1993 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-1994 b/gcc-4.9/gcc/cp/ChangeLog-1994
new file mode 100644
index 000000000..8ff502f63
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-1994
@@ -0,0 +1,5412 @@
+Fri Dec 30 17:57:30 1994 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_bltn_desc): Handle bool as a built-in type.
+
+Fri Dec 30 14:20:21 1994 Mike Stump <mrs@cygnus.com>
+
+ * tree.c (layout_vbasetypes): Ensure that we don't loose alignment
+ on the complete type because of small virtual bases.
+
+Fri Dec 30 12:22:29 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (n_incomplete): Bump n_incomplete up to int to match C
+ front end.
+ (pushdecl): Also count decls pushed that are of a type being defined
+ as incomplete things.
+ * class.c (finish_struct): Move hack_incomplete_structures up to
+ just after we set it as not being defined, so that the decls we
+ build for RTTI don't count as incomplete.
+
+Thu Dec 29 18:20:57 1994 Mike Stump <mrs@cygnus.com>
+
+ * pt.c (tsubst): Fix problem with defining constructors in templated
+ classes with virtual bases.
+
+Wed Dec 28 08:31:00 1994 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (TYPEID): Strip top-level cv-qualifiers on typeid
+ expressions.
+ * gc.c (build_typeid): Likewise.
+
+Thu Dec 22 17:26:33 1994 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (build_up_reference): Fix breakage introduced on Nov 29,
+ don't assert on complex AGGR inits.
+
+Thu Dec 22 14:32:31 1994 Mike Stump <mrs@cygnus.com>
+
+ * method.c (build_overload_value): Handle pointer to members as
+ template arguments.
+
+Thu Dec 22 13:09:07 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (unary_complex_lvalue): Don't call sorry if we know how
+ to do take the address of a data member for a pointer to data
+ member.
+
+Thu Dec 22 10:04:19 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (grokdeclarator): Use the typedef name for linkage if the
+ type doesn't otherwise have a name.
+
+ * decl2.c (grokfield): Likewise.
+
+ * class.c (finish_struct): Since we reuse the TYPE_DECL for the
+ DECL_NAME of enums, structs and classes, we have to avoid trying to
+ put it in the TYPE_FIELDS again.
+
+Wed Dec 21 11:07:05 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (check_classfn): Ignore this parameter on static functions
+ when checking to see if we match.
+
+Tue Dec 20 17:47:02 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (unary_complex_lvalue): Handle address of non-left most
+ pointers to members by calling get_delta_difference.
+
+Mon Dec 19 22:40:53 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (check_classfn): Don't use decls_match yet, as it modifies
+ static functions to early.
+
+Thu Dec 19 22:37:48 1994 Mike Stump <mrs@cygnus.com>
+
+ * method.c (make_thunk): Handle encoding of positive thunk offsets.
+
+Sat Dec 17 13:29:50 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * Make-lang.in (.PHONY): Tell GNU make C++ and c++ are phony targets.
+
+Thu Dec 15 16:32:12 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (check_classfn): Use decls_match to check if this has
+ already been declared, as the DECL_ASSEMBLER_NAME may have been
+ changed via asm("new_name").
+ * decl.c (decls_match): Make public.
+
+Thu Dec 15 15:17:55 1994 Mike Stump <mrs@cygnus.com>
+
+ * *.[chy] (expand_aggr_init): Add fourth argument to handle
+ distinction between = init and (init) style of initializations.
+ * *.[chy] (finish_decl): Add fifth argument to handle
+ distinction between = init and (init) style of initializations.
+
+Tue Dec 13 19:16:05 1994 Mike Stump <mrs@cygnus.com>
+
+ Fix some random `explicit' bugs.
+
+ * cvt.c (convert_to_reference): Add third parameter to
+ convert_force.
+ (convert_force): Likewise.
+ * call.c (build_method_call): Likewise.
+ * decl2.c (setup_vtbl_ptr): Likewise.
+ * init.c (expand_virtual_init): Likewise.
+ (build_member_call): Likewise.
+ (build_delete): Likewise.
+ (build_vbase_delete): Likewise.
+ * typeck.c (build_component_addr): Likewise.
+ (build_c_cast): Likewise.
+ (build_modify_expr): Likewise.
+ * cp-tree.h (CONV_NONCONVERTING): Likewise. Add so that we can
+ distinguish the context in which the conversion appears. Add thrid
+ argument to build_c_cast.
+ * cvt.c (cp_convert): Pass whether or not we want to consider
+ non-converting constructors down to build_method_call.
+ * decl2.c (reparse_absdcl_as_casts): Add third argument to
+ build_c_cast.
+ * gc.c (build_m_desc): Likewise.
+ * init.c (build_new): Likewise.
+ * parse.y (expr_no_commas): Likewise.
+ (primary): Likewise.
+ * typeck.c (build_x_function_call): Likewise.
+ (build_static_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (build_c_cast): Likewise.
+ (build_ptrmemfunc): Likewise.
+ * typeck2.c (build_functional_cast): Likewise.
+ * init.c (expand_aggr_init): Added LOOKUP_ONLYCONVERTING to
+ expand_aggr_init_1 as inits are converted to the destination type.
+
+Tue Dec 13 16:18:57 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * Make-lang.in (cc1plus): Depends on c-pragma.o.
+
+ * Makefile.in (OBJ{DEP,}S): Add ../c-pragma.o.
+
+ * lex.c (check_newline): If the #pragma is not recognized by g++,
+ try machine-specific ones too.
+ (handle_sysv_pragma): Copied from c-lex.c.
+
+Mon Dec 12 23:53:06 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Fix Dec 6th change, build_new likes a
+ reference better.
+
+Mon Dec 12 18:01:00 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op): Lose checks on TYPE_PTRMEMFUNC_P with
+ IS_AGGR_TYPE, since now they will not both be set on the same type.
+
+ * pt.c (do_pending_expansions): Don't clear TREE_PUBLIC on
+ instantiations controlled by -fexternal-templates.
+
+ * decl.c (duplicate_decls): Don't complain about different values of
+ __attribute__ ((const)) and ((noreturn)).
+
+Fri Dec 9 18:17:37 1994 Doug Evans <dje@cygnus.com>
+
+ * Makefile.in (BISONFLAGS): Delete --yacc.
+ (PARSE_H): Depend on $(PARSE_C), for parallel makes.
+ (PARSE_C): Undo last patch.
+
+Fri Dec 2 10:44:36 1994 Mike Stump <mrs@cygnus.com>
+
+ * Makefile.in (BISONFLAGS): Add --yacc so that output winds up in
+ y.tab.c.
+
+Thu Dec 8 17:39:46 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_decl): Don't call obscure_complex_init for decls
+ of indeterminate size.
+
+Wed Dec 7 16:49:22 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (obscure_complex_init): Function to tweak the decl to
+ prevent expand_decl from tring to initialize it.
+ (finish_decl): Use it rather than writing the same code in three
+ different places.
+
+ * parse.y (bad_parm): Stop trying to support parms without types.
+
+Wed Dec 7 12:06:56 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (grokfield): Make asm specs on static member functions
+ work.
+
+Tue Dec 6 15:43:20 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Make a copy of the thrown object.
+
+Tue Dec 6 14:16:34 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y: : Has lower precedence than =.
+
+Tue Dec 6 12:46:17 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (pushdecl): Use DECL_NAME of VAR_DECLs to avoid namespace
+ manglings.
+ (grokvardecl): Add namespace into variable name.
+
+Tue Dec 6 11:26:55 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (current_namespace_id): New routine to transform a simple
+ name into a name in a namespace.
+ * decl.c (grokdeclarator): Use it.
+ * decl2.c (get_namespace_id): Find the name of the current
+ namespace.
+ (push_namespace, pop_namespace): Complete out missing
+ functionality.
+
+Mon Dec 5 17:11:51 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_struct): Don't use LONG_LONG_TYPE_SIZE, as it may
+ not be defined. Fix warning message for enums and restore warning
+ for non-enums.
+
+ * decl2.c (push_namespace): Dummy function.
+ (pop_namespace): Likewise.
+ (do_namespace_alias): Likewise.
+ (do_using_decl): Likewise.
+ (do_using_directive): Likewise.
+
+ * parse.y: New token NSNAME for namespace names.
+ (extdef): Add namespace, using definitions.
+ (using_decl): New rule for using declarations.
+ (any_id): New rule for identifiers with any degree of scoping.
+ (identifier): Add NSNAME.
+ (notype_identifier): Likewise.
+ (component_decl): Add using_decl.
+ (nested_name_specifier): Add NSNAME SCOPE.
+
+ * typeck.c (convert_for_assignment): Handle conversions between
+ enums and bool.
+
+ * decl.c (duplicate_decls): Only propagate DECL_MAIN_VARIANT on
+ FUNCTION_DECLs.
+
+Mon Dec 5 13:03:16 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (finish_struct): Give an error if one tries to declare a
+ bit-field's size greater than a long long, as the backend will dump.
+ It is not an error to declare an enum bit-field greater than its
+ precision. Warn if an enum bit-field is too small to hold all
+ its values.
+
+Mon Dec 5 11:41:50 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (convert_for_assignment): Use cp_convert instead of
+ convert so that we don't get static casts.
+
+Sun Dec 4 11:59:01 1994 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (cp_convert): Don't complain about int->enum conversion if
+ we are doing static casts.
+
+Fri Dec 2 18:32:41 1994 Mike Stump <mrs@cygnus.com>
+
+ * error.c (dump_expr): Do something more intelligent with SAVE_EXPRs
+ when dumping expressions in error messages.
+
+Fri Dec 2 17:04:27 1994 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_dynamic_cast): Change interface to libg++, ensure that
+ the return type is the right type, and make references work.
+
+Fri Dec 2 16:36:43 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (poplevel): Don't be confused by function-scope
+ declarations of non-nested functions.
+ (duplicate_decls): Propagate DECL_MAIN_VARIANT.
+ (pushdecl): Use duplicate_decls to copy info from old decl into new
+ function-scope one rather than doing it here.
+
+ * decl2.c (mark_inline_for_output): Deal with the DECL_MAIN_VARIANT
+ of this decl, in case this is a function-scope declaration.
+
+ * decl.c (finish_enum): Make sure that the type has the right
+ precision when we call fixup_*_type.
+
+Tue Nov 29 19:12:07 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (build_up_reference): Strip superfluous NOP_EXPRs; we do
+ want to build up references to rvalues if possible.
+ (cp_convert): Stick on a NOP_EXPR when converting to the same type.
+
+Tue Nov 29 11:28:59 1994 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (maybe_raises): Handle throw ().
+ * parse.y (ansi_raise_identifier): Grok type-ids in exception
+ specifications.
+ * tree.c (build_exception_variant): Use list compare to check if
+ two exception specifications match.
+ * decl.c (duplicate_decls, bad_specifiers): Enhance wording on error
+ messages.
+ * call.c (build_method_call): Remove TREE_RAISES.
+ * cvt.c (convert_to_aggr): Likewise.
+ * typeck.c (build_function_call_real, convert_arguments): Likewise.
+ * init.c (expand_aggr_init_1): Likewise.
+
+Tue Nov 29 09:50:39 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Add support for m68k and mips exception handling
+ support.
+
+Tue Nov 29 08:48:33 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_end_all_catch): Throw into outer context, if we
+ fall off end of catch handlers.
+
+Mon Nov 28 16:44:41 1994 Mike Stump <mrs@cygnus.com>
+
+ * Makefile.in: Make is easier to decide where parse.[ch] will be
+ built.
+
+Thu Nov 17 20:11:24 1994 Doug Evans <dje@cygnus.com>
+
+ * cp/Make-lang.in (CXX_INSTALL_NAME): Use program_transform_name.
+ (GXX_INSTALL_NAME): Likewise.
+ (CXX_CROSS_NAME): Use program_transform_cross_name.
+ (GXX_CROSS_NAME): Likewise.
+ (c++.install-man): Use program_transform_name on g++.1.
+ (c++.uninstall): Likewise.
+
+Mon Nov 28 13:53:03 1994 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (THROW): Fix precedence of throw expressions.
+
+Mon Nov 28 13:15:16 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_unary_op): Allow promotions from bool to int on
+ unary ~.
+
+Sun Nov 27 00:16:21 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (build_overload_name): Use DECL_ASSEMBLER_NAME for
+ classes when appropriate.
+ (build_overload_nested_name): When dealing with a function context,
+ use ASM_FORMAT_PRIVATE_NAME to tweak the name of the function to
+ avoid conflicts between local classes of the same name.
+
+Wed Nov 23 17:59:42 1994 Mike Stump <mrs@cygnus.com>
+
+ * gxx.gperf, parse.y, lex.h, hash.h, lex.c (init_lex), delc.c
+ (duplicate_decls, grokdeclarator), cp-tree.h: Add support for
+ `explicit'.
+ * cvt.c (convert_to_reference, cp_convert, build_type_conversion_1,
+ build_type_conversion): Use LOOKUP_ONLYCONVERTING in
+ build_method_calls so that non-converting constructors are not used.
+ * call.c (build_method_call): If we shouldn't use a non-converting
+ constructor, then don't.
+
+Wed Nov 23 14:46:56 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Don't try to synthesize methods yet.
+
+Tue Nov 22 12:45:21 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (push_template_decls): Create CONST_DECLs for template
+ constant parameters, not VAR_DECLs.
+
+Sat Nov 19 15:28:31 1994 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Can shorten shift only if
+ shift count is less than size in bits of arg0.
+
+Thu Nov 17 15:30:50 1994 Mike Stump <mrs@cygnus.com>
+
+ * gxx.gperf, hash.h, lex.c (init_lex, real_yylex), parse.y: Add new
+ ANSI keywords and, and_eq, bitand, bitor, explicit, namespace, not,
+ not_eq, or, or_eq, typename, using, xor, xor_eq to g++. Still need
+ to add support for explicit, namespace, typename, and using, support
+ for the rest is already in.
+
+Fri Nov 4 19:04:18 1994 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (get_bad_cast_node): New routine to support compile time
+ throws of bad_cast.
+ * gc.c (build_dynamic_cast): Support throwing of bad_cast at compile
+ time.
+
+Fri Nov 4 11:12:00 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Add hppa support.
+
+Fri Nov 4 10:50:50 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Add rs6000 support.
+
+Thu Nov 3 14:24:23 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (do_unwind): Add i[34]86 support.
+
+Thu Nov 3 00:10:46 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (do_pending_expansions): Unset TREE_PUBLIC on implicit
+ instantiations.
+
+Wed Nov 2 15:08:24 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * decl.c (finish_function): Emit types used in method parameters
+ into symbol table.
+
+Wed Nov 2 15:05:47 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (process_template_parm): Allow pointer to member function
+ template parameter types.
+ (uses_template_parms): Handle pointer to member function
+ CONSTRUCTORs.
+
+ * g++.c (main): Cast first argument of bzero to (char *).
+ Pass -lstdc++ instead of -lg++ unless we are invoked as 'g++'.
+
+Mon Oct 31 14:50:48 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * gc.c (build_dynamic_cast): Rewrite to make it work.
+ * class.c (finish_vtbls): Build more vtables if flag_rtti is on.
+ * class.c (modify_all_direct_vtables): Likewise.
+ * init.c (expand_direct_vtbls_init): Expand more vtables if
+ flag_rtti is on.
+ * decl.c (init_type_desc): Add default return.
+
+Tue Oct 25 17:13:09 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * tree.c (debug_binfo): Get rid of the initial size entry of
+ vtable.
+ * cp-tree.h: Change flag_dossier to flag rtti, define type
+ descriptor type nodes.
+ * decl.c (init_type_desc): New function to initialize type
+ descriptor type nodes.
+ * decl.c (record_builtin_type): Change flag_dossier to flag_rtti.
+ * lex.c (init_lex): Likewise.
+ * decl.c: Change variable flag_dossier to flag_rtti.
+ * decl.c (duplicate_decls): Get rid initial size entry of vtable.
+ * decl.c (hack_incomplete_structures): Take out assert 164.
+ * search.c (get_abstract_virtuals_1): Likewise.
+ * search.c (dfs_init_vbase_pointers): Change CLASSTYPE_DOSSIER to
+ CLASSTYPE_RTTI.
+ * parse.y: Likewise.
+ * class.c (prepare_fresh_vtable): For virtual bases, get right
+ offset.
+ * class.c (add_virtual_function): Change flag_dossier to
+ flag_rtti.
+ * class.c (modify_one_vtable): Modify the right rtti entry.
+ * class.c (override_one_vtable): Get rid of size entry.
+ * class.c (finish_struct): Change flag_dossier to flag_rtti, and
+ build extra vtables, build type descriptors for polymorphic
+ classes.
+ * gc.c (build_headof): Make headof() works correctly with new
+ rtti.
+ * gc.c (build_typeid): Make this function work with new rtti.
+ * gc.c (get_typeid): Make this function work with new rtti.
+ * gc.c (build_bltn_desc): New function for new rtti.
+ * gc.c (build_user_desc): Likewise.
+ * gc.c (build_class_desc): Ditto.
+ * gc.c (build_ptr_desc): Ditto.
+ * gc.c (build_attr_desc): Ditto.
+ * gc.c (build_func_desc): Ditto.
+ * gc.c (build_ptmf_desc): Ditto.
+ * gc.c (build_ptmd_desc): Ditto.
+ * gc.c (build_t_desc): Ditto.
+ * gc.c: Comment out old build_t_desc, build_i_desc, build_m_desc.
+
+Tue Oct 25 13:37:41 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (convert_harshness): Check for TREE_UNSIGNED differences
+ after checking for integral conversions.
+
+Wed Nov 30 19:13:50 1994 Mike Stump <mrs@cygnus.com>
+
+ * Version 2.6.3 released.
+
+Thu Nov 17 10:56:50 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck2.c (build_m_component_ref): Check the basetype of the
+ member pointer against the main variant of the object type.
+
+Mon Nov 14 14:21:52 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (convert_to_reference): Make sure that the original expr
+ gets its type back when converting a reference.
+
+ * method.c (build_overload_name): Clear numeric_outputed_need_bar here.
+ (build_decl_overload): Instead of here.
+
+Tue Nov 8 17:11:24 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (cp_convert): Don't build a TARGET_EXPR if we're not in a
+ function.
+
+ * typeck.c (convert_for_initialization): Handle initialization from
+ a TARGET_EXPR.
+
+Sun Nov 6 01:34:24 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (lookup_nested_type_by_name): Fix list-walking logic.
+ (tsubst): When replacing a TEMPLATE_TYPE_PARM, propagate
+ TYPE_READONLY and TYPE_VOLATILE from the argument.
+ (unify): When unifying with a TEMPLATE_TYPE_PARM, remove cv-quals
+ present in parm from arg.
+ (type_unification): Strip REFERENCE_TYPE from the argument type.
+ (unify): Don't strip REFERENCE_TYPE from the argument type.
+
+Sat Nov 5 22:42:15 1994 Greg McGary <gkm@magilla.cichlid.com>
+
+ * pt.c (do_type_instantiation): Check to see if there's a
+ IDENTIFIER_TEMPLATE on a class before calling
+ instantiate_member_templates().
+
+Sat Nov 12 06:35:42 1994 Mike Stump <mrs@cygnus.com>
+
+ * Version 2.6.2 released.
+
+Thu Nov 3 18:48:19 1994 Paul Eggert <eggert@twinsun.com>
+
+ * Makefile.in (spew.o, lex.o, pt.o):
+ Depend on $(srcdir)/parse.h, not parse.h.
+
+Tue Nov 1 19:19:41 1994 Mike Stump <mrs@cygnus.com>
+
+ * Version 2.6.1 released.
+
+Sun Oct 23 13:19:55 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c: Declare flag_access_control.
+ (struct lang_f_options): Add access-control.
+ * expr.c (cplus_expand_expr, NEW_EXPR): Unset flag_access_control
+ for the call to expand_aggr_init to copy the object out of the
+ pcc_struct_return slot.
+ * search.c (compute_access): if (!flag_access_control) return
+ access_public.
+
+Fri Oct 21 00:32:54 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * lex.c (cons_up_default_function): Don't try to defer method
+ synthesis now.
+
+ * decl.c (init_decl_processing): Use __pure_virtual for abort_fndecl
+ instead of abort, since the OSF/1 dynamic linker doesn't like to see
+ relocation entries for abort.
+
+ * tree.c (array_type_nelts_total): Use sizetype, not
+ integer_type_node.
+ (array_type_nelts_top): Likewise.
+
+Thu Oct 20 15:48:27 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (grokdeclarator): Added handling for catch parameters
+ (CATCHPARM).
+ * except.c (expand_start_catch_block): Use the new CATCHPARM context
+ instead of NORMAL.
+ * except.c (expand_throw): Don't let convert_to_reference complain
+ about what we are doing.
+
+Thu Oct 20 12:55:24 1994 Jim Wilson <wilson@cygnus.com>
+
+ * method.c (emit_thunk): Call instantiate_virtual_regs.
+
+Wed Oct 19 14:15:33 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_exception_blocks): Make sure throw code doesn't
+ get put in function that won't be output.
+
+Mon Oct 17 18:03:15 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (init_decl_processing): Make alloca a builtin.
+
+Thu Oct 27 21:10:25 1994 Craig Burley <craig@burley>
+
+ * g++.c (main): Only decrement "added" and set "library" to
+ NULL when "library" != NULL (just like 940829 fix).
+
+Mon Oct 17 15:56:11 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_catch_block): Make sure the false label
+ gets onto the permanent obstack, as it is used for the exception
+ table.
+
+Fri Oct 14 18:54:48 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (modify_one_vtable): Since the DECL_CONTEXT of fndecl can
+ be set just below, use current_fndecl instead.
+
+Fri Oct 14 15:12:22 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (expand_aggr_vbase_init_1): Don't call expand_aggr_init_1
+ with LOOKUP_SPECULATIVELY.
+ (expand_default_init): Abort if build_method_call returns NULL_TREE.
+
+ * typeck.c (build_modify_expr): Don't just build a MODIFY_EXPR if
+ the rhs is a TARGET_EXPR.
+
+ * parse.y (left_curly): Anonymous types are not affected by #pragma
+ interface/implementation.
+
+ * method.c (synthesize_method): Don't call setup_vtbl_ptr for the
+ default constructor if it isn't needed.
+
+ * lex.c (cons_up_default_function): Do synthesize methods for
+ anonymous types if necessary.
+
+Thu Oct 13 17:44:55 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (build_decl_overload): Set numeric_outputed_need_bar to 0.
+
+Wed Oct 12 13:27:57 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): Understand how to copy an aggregate.
+
+ * init.c (expand_default_init): Likewise. Also remove some of the
+ crufty code that assumes methods will not be synthesized properly.
+
+ * lex.c (cons_up_default_function): If the containing type has no
+ name, these functions should never need to be called, so just
+ declare them.
+
+ * lex.c (real_yylex): Use HOST_BITS_PER_WIDE_INT to determine the
+ bitmask for lexing character constants.
+
+ * call.c (build_method_call): Disable code that tries to do tricky
+ stuff with a default parameter that is a constructor call, but
+ actually does other tricky stuff that breaks things.
+
+Wed Oct 12 16:14:01 1994 Benoit Belley <belley@cae.ca>
+
+ * decl.c (finish_enum): Disable code which forces enums to be signed,
+ since this conflicts with their use as bitfields. type_promotes_to
+ handles promotion of enums of underlying unsigned types to signed
+ integer types.
+
+Wed Oct 12 13:24:03 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (type_promotes_to): Also promote enums to long if
+ appropriate.
+
+ * typeck.c (default_conversion): Don't expect type_promotes_to to
+ return a main variant.
+
+Wed Oct 12 12:19:45 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_scoped_method_call): Don't lose side effects in the
+ object expression when calling a non-existent destructor.
+
+Fri Sep 2 19:05:21 1994 Rohan Lenard <rjl@iassf.easams.com.au>
+
+ * call.c (build_scoped_method_call): Remove erroneous error message
+ when destructor call is written as a scoped call.
+
+Tue Oct 11 23:48:31 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * various: Cast pointer arguments to bzero and bcopy to char *.
+
+Tue Oct 11 19:34:32 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (get_derived_offset): Added a type parameter to limit how
+ far up the CLASSTYPE_VFIELD_PARENT chain we search.
+ * class.c (modify_one_vtable, fixup_vtable_deltas): When forming the
+ offset to put into the vtable for the this parameter, make sure we
+ don't offset from a parent of the DECL_CONTEXT of the function.
+
+Tue Oct 11 16:10:52 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (do_function_instantiation): Set DECL_EXTERNAL and
+ TREE_STATIC when setting DECL_INTERFACE_KNOWN.
+ (do_type_instantiation): Likewise.
+
+ * lex.c (cons_up_default_function): Set DECL_INTERFACE_KNOWN,
+ DECL_EXTERNAL and TREE_STATIC as appropriate.
+
+ * decl2.c (finish_file): Also synthesize methods that don't have
+ DECL_EXTERNAL set. Set interface_unknown before doing so.
+
+ * decl.c (start_function): If DECL_INTERFACE_KNOWN is set on the
+ function decl, don't muck with TREE_PUBLIC and DECL_EXTERNAL.
+
+Mon Oct 10 00:56:53 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * lex.c (cons_up_default_function): Mark methods in a template class
+ as template instances. Store the values of interface_unknown and
+ interface_only for do_pending_inlines.
+ (do_pending_inlines): Use them.
+
+ * decl2.c (finish_file): If we haven't seen a definition of a
+ function declared static, make the decl non-PUBLIC so compile_file
+ can give an error.
+
+Sun Oct 9 02:42:29 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (do_build_copy_constructor): Handle anonymous unions.
+ (do_build_assign_ref): Likewise.
+ (largest_union_member): Move from lex.c.
+
+Sat Oct 8 14:59:43 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ Re-implement g++'s vague linkage independent of TREE_PUBLIC.
+ * pt.c (instantiate_member_templates): Lose redundant
+ -fexternal-templates handling.
+ (tsubst): Set TREE_PUBLIC and DECL_EXTERNAL on new decls. Don't set
+ TREE_STATIC or DECL_INTERFACE_KNOWN.
+ (do_pending_expansions): Predicate on DECL_INTERFACE_KNOWN instead
+ of DECL_EXTERNAL for explicit instantiations.
+ (do_function_instantiation): Do the new thing.
+ (do_type_instantiation): Likewise.
+ (instantiate_template): Deal with member templates defined in a .cc
+ file with -fexternal-templates.
+ * except.c (expand_exception_blocks): Use DECL_LINKAGE_KNOWN to
+ decide whether to stick builtin_throw here.
+ * decl2.c (import_export_inline): Predicate on DECL_INTERFACE_KNOWN
+ rather than TREE_PUBLIC. Generally fix rules.
+ (finish_file): Use DECL_INITIAL to determine whether or not a method
+ has been synthesized, rather than TREE_ASM_WRITTEN.
+ * decl.c (warn_extern_redeclared_static): Use DECL_PUBLIC instead of
+ TREE_PUBLIC.
+ (pushdecl): Likewise.
+ (duplicate_decls): Likewise. Deal with DECL_DECLARED_STATIC and
+ DECL_INTERFACE_KNOWN.
+ (redeclaration_error_message): Fix checking for conflicting linkage.
+ (define_function): Set DECL_INTERFACE_KNOWN.
+ (grokfndecl): Function decls are PUBLIC until we are sure about
+ their linkage. Set DECL_DECLARED_STATIC as needed.
+ (start_function): Deal with linkage. Move pushdecl after linkage
+ magic.
+ (finish_function): Don't set TREE_ASM_WRITTEN on discarded inlines.
+ * cp-tree.h (lang_decl_flags): Add interface_known and
+ declared_static.
+ (DECL_INTERFACE_KNOWN): New macro.
+ (DECL_DECLARED_STATIC): New macro.
+ (DECL_PUBLIC): New macro.
+
+ Clean up bogus use of TREE_PUBLIC.
+ * class.c (alter_access): Fix mistaken use of TREE_PUBLIC (it
+ doesn't correspond to TREE_PROTECTED and TREE_PRIVATE).
+ * init.c (do_friend): Don't arbitrarily set TREE_PUBLIC.
+
+Wed Oct 5 13:44:41 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_overload_call_real): Don't immediately do
+ array->pointer conversion.
+
+ * pt.c (type_unification): If not passing to a reference, strip
+ cv-quals. Also handle array->pointer conversion.
+
+Tue Oct 4 17:45:37 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't warn about applying const to a
+ const typedef or template type parameter.
+
+ * decl2.c (finish_file): Also synthesize methods after walking the
+ vtables. Ugly ugly ugly.
+
+Mon Oct 3 15:02:41 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * various: Remove lingering remnants of old exception handling code.
+
+ * decl2.c (finish_file): Synthesize methods before walking the
+ vtables, so that the vtables get emitted as needed.
+
+ * decl.c (shadow_tag): Remove obsolete code for pushing tags and
+ dealing with exceptions.
+
+Mon Oct 3 13:05:27 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * Make-lang.in (g++-cross): Depend upon version.o and $(LIBDEPS).
+
+Mon Oct 3 02:59:28 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_file): Fix inline handling.
+
+Sun Oct 2 00:21:56 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokdeclarator): Handle redundant scope even better.
+ ({push,pop}_cp_function_context): Take toplev parameter.
+
+ * method.c (synthesize_method): Pass toplev parameter to
+ {push,pop}_cp_function_context depending on decl_function_context
+ (fndecl).
+
+ * typeck.c (build_x_unary_op): Unary & on OFFSET_REFs is always the
+ built-in version.
+
+ * method.c (synthesize_method): Don't be confused by __in_chrg
+ parameter.
+
+ * class.c (popclass): Set C_C_D like start_function does.
+
+ * decl.c (grokdeclarator): Handle redundant scope better.
+
+ * parse.y (expr_or_declarator): Add '(' expr_or_declarator ')' rule.
+ (direct_notype_declarator): Likewise.
+ (complex_direct_notype_declarator): Remove it here.
+
+Sat Oct 1 21:42:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (resolve_offset_ref): Fix types used in resolving .*
+ expressions.
+
+Sat Oct 1 15:18:49 1994 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ Beginnings of work to synthesize methods only when needed.
+ * call.c (build_method_call): Synthesize methods as necessary
+ (currently never necessary).
+ * class.c (popclass): Don't try to set C_C_D here, as it'll end up
+ on the wrong obstack.
+ * decl.c (push_cp_function_context): Mostly copied from
+ push_c_function_context.
+ (pop_cp_function_context): Similarly.
+ (finish_function): Reverse order of poplevel and pop_nested_class so
+ that current_class_decl is restored properly.
+ (start_function): Likewise.
+ (finish_function): Add parameter 'nested'. Don't call
+ permanent_allocation if (nested).
+ * various: Pass extra parameter to finish_function.
+ * decl2.c (finish_file): Reorganize end-of-file inline handling,
+ synthesizing methods as necessary.
+ * lex.c (cons_up_default_function): Call mark_inline_for_output.
+ Only synthesize methods immediately if #pragma implementation
+ (currently disabled).
+ (do_pending_inlines): Call synthesize_method.
+ * method.c (synthesize_method): New function; all method synthesis
+ goes through here. Calls do_build_assign_ref and
+ do_build_copy_constructor.
+ (build_default_constructor): Remove.
+ (build_dtor): Likewise.
+ (build_assign_ref): Rename to do_build_assign_ref and remove stuff
+ done by synthesize_method.
+ (build_copy_constructor): Similarly.
+
+Thu Sep 29 16:58:52 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (c_expand_return): Use magic so the backend can fixup the
+ assignment into the return register, so cleanups won't clobber it.
+
+Thu Sep 29 13:08:50 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (hack_identifier): Don't call assemble_external for
+ template decls.
+
+ * decl.c (finish_decl): Also end temporary allocation if the decl in
+ question has a type of error_mark_node.
+
+Wed Sep 28 21:45:00 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_modify_expr): When optimizing ?: on lhs, make sure
+ that if the ?: was a reference type, that the subparts will be also.
+
+Wed Sep 28 16:14:04 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * except.c (register_exception_table): Use Pmode, not PTRmode.
+
+Fri Sep 23 13:54:27 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (do_pending_inlines): Do method synthesis after the
+ pending_inlines have been reversed.
+
+Thu Sep 22 12:53:03 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl2.c (finish_file): Fix Brendan's fix: Only call
+ register_exception_table if there is a non-empty exception table.
+
+Thu Sep 22 12:03:46 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl2.c (finish_file): Only do register_exception_table if
+ -fhandle-exceptions is being used.
+
+Wed Sep 21 19:01:51 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * except.c (output_exception_table_entry): Simplify
+ by using assemble_integer.
+ (build_exception_table): Change to return a count.
+ Cleanup to use standard macros, instead of hard-wired
+ sparc asm format. Don't make __EXCEPTION_TABLE__ global.
+ (register_exception_table): New function. Generate call to builtin.
+ * decl2.c (finish_file): Call register_exception_table.
+ * cp-tree.h (build_exception_table): Fix prototype.
+
+Wed Sep 21 13:20:42 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * tree.c (break_out_calls): Don't try to duplicate the DECL_INITIAL.
+
+ * decl2.c (delete_sanity): Give an error at trying to delete a
+ function.
+
+Wed Sep 21 11:47:10 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (cons_up_default_function): Mark synthesized destructors
+ inline.
+
+ * decl.c (duplicate_decls): Ignore redeclarations of wchar_t as
+ something other than __wchar_t, complaining if -pedantic and not in
+ a system header.
+
+Tue Sep 20 09:43:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (xref_tag): Set up BINFO_INHERITANCE_CHAIN on base binfos
+ here.
+
+ * typeck.c (build_modify_expr): Require complete type after checking
+ for error_mark_node.
+
+ * call.c (build_method_call): Print parmtypes when complaining of
+ ambiguous call.
+
+ * typeck.c (build_modify_expr): Handle assignment to array from
+ non-array.
+
+ * decl.c (lookup_name_real): Deal with got_scope == error_mark_node.
+
+ * call.c (build_method_call): Don't bother with the exact match.
+
+Mon Sep 19 00:51:39 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (expand_aggr_init): If we munge the type of the variable,
+ also munge the type of the initializer.
+
+ * decl.c (grokdeclarator): Use <= when comparing to RID_LAST_MODIFIER.
+ (init_decl_processing): Push artificial declaration of wchar_t so
+ people don't have to declare it before they can use it.
+
+ * error.c (cp_line_of): Return lineno in lieu of 0.
+
+ * typeck.c (convert_for_assignment): Handle conversion of pmfs to
+ int and bool.
+ (build_component_ref): Fold the COMPONENT_REF in case it can be
+ reduced.
+
+ * typeck2.c (store_init_value): Don't pedwarn about non-constant
+ bracketed initializers for automatic variables.
+
+Sun Sep 18 10:12:12 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_decl): Don't say `typedef enum foo foo'.
+
+ * decl.c (start_decl): Don't set TREE_PUBLIC on template decls just
+ because they're affected by #pragma i/i. We'll deal with that when
+ they get instantiated.
+
+ * typeck.c (build_unary_op): Clean up cruft in ADDR_EXPR case.
+
+ * class.c (instantiate_type): Set TREE_CONSTANT on instantiated
+ ADDR_EXPRs if appropriate.
+
+ * decl.c (build_ptrmemfunc_type): Unset IS_AGGR_TYPE on pmf types.
+
+ * typeck.c (build_ptrmemfunc): Handle &overloaded_method as an
+ initializer properly.
+ * typeck2.c (digest_init): Likewise.
+
+ * tree.c (cp_build_type_variant): Like c_build_type_variant, except
+ it uses build_cplus_array_type.
+ * *.c: Use cp_build_type_variant instead of c_build_type_variant.
+
+ * pt.c (do_type_instantiation): Don't try to instantiate nested
+ enums.
+
+Tue Sep 13 10:56:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_up_reference): Handle preincrement and predecrement
+ properly.
+
+Tue Sep 13 09:51:59 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (finish_decl): Only lay out the rtl for DECL if it is, in
+ fact, static.
+
+Mon Sep 12 14:40:30 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (finish_decl): Lay out the rtl for DECL before doing
+ grok_reference_init, in case it's static.
+
+Mon Sep 12 12:45:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Don't synthesize constructors if the
+ class has a field with the same name as the class. Don't die on
+ classes with no constructors or destructors. Don't die if the head
+ and tail of the class are in different files.
+
+ * decl.c (grokdeclarator): Don't treat a function pointer field
+ with the same name as the class as a constructor.
+
+Fri Sep 9 13:17:00 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_c_cast): Pull constant values out of their
+ variables here.
+
+ * decl.c (duplicate_decls): Only propagate DECL_CHAIN in
+ FUNCTION_DECLs and TEMPLATE_DECLs.
+
+Thu Sep 8 10:07:48 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (duplicate_decls): Propagate DECL_CHAIN in all DECLs that
+ have it.
+
+ * pt.c (unify): REALs and INTEGERs only unify with their own genus.
+ (instantiate_member_templates): Don't muck with DECL_EXTERNAL and
+ TREE_PUBLIC unless -fexternal-templates.
+
+Wed Sep 7 13:17:10 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (do_type_instantiation): Call instantiate_member_templates.
+ Deal with specializations.
+ (tsubst): Don't stick the mangled name in DECL_NAME for function
+ instantiations. Don't push them, either.
+
+ * decl2.c (grokfield): Move code for generating the
+ DECL_ASSEMBLER_NAME for static members from here.
+ * method.c (build_static_name): To here.
+ * decl.c (grokvardecl): Call build_static_name.
+ (duplicate_decls): Keep old DECL_ASSEMBLER_NAME.
+
+Mon Sep 5 12:49:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): If -Wsynth, warn when selecting
+ synthesized op= over user-supplied one cfront would select.
+ * decl2.c (lang_decode_option): Handle -Wsynth.
+
+Fri Sep 2 15:11:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (finish_enum): Overhaul to fix several bugs.
+ (start_enum): Disable useless code.
+
+Thu Sep 1 16:04:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (c_expand_return): Warn about returning a reference to a
+ temporary.
+ (convert_arguments): Increment argument counter when using default
+ arguments, too.
+
+Wed Aug 31 14:29:22 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (finish_decl): If the type of decl is error_mark_node,
+ don't bother trying to do anything.
+
+ * typeck.c (convert_for_initialization): If the rhs contains a
+ constructor call, pretend the lhs type needs to be constructed.
+
+ * init.c (expand_default_init): If we stick the object inside the
+ initializer, mark the initializer used.
+
+Tue Aug 30 13:50:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (build_assign_ref): Return *this;
+ (build_assign_ref): Fix base assignment order.
+ (build_copy_constructor): Fix member init order.
+
+Mon Aug 29 13:54:39 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * g++.c (main): Remember to clear out SAW_SPECLANG after we see
+ its argument.
+
+Sat Aug 27 09:36:03 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (build_copy_constructor): Also copy virtual bases.
+
+Fri Aug 26 17:05:15 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (do_pending_inlines): Clear out pending_inlines before doing
+ any synthesis. Also first set deja_vu on all pending_inlines.
+
+ * method.c (build_assign_ref): Use build_member_call to invoke base
+ operator=, rather than build_modify_expr. And use
+ build_reference_type instead of TYPE_REFERENCE_TO.
+ (build_copy_constructor): Use TYPE_NESTED_NAME to identify the
+ basetype.
+
+ * decl2.c (grokfield): Don't complain about undefined local class
+ methods.
+
+ * class.c (finish_struct): Don't try to synthesize methods here.
+ * lex.c (do_pending_inlines): Instead, synthesize them here.
+ (init_lex): Initialize synth_obstack.
+ (cons_up_default_function): Stick synthesis request on
+ pending_inlines.
+
+Fri Aug 26 12:24:14 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (build_method_call) [PCC_STATIC_STRUCT_RETURN]: Also
+ accept an RTL_EXPR in what we're about to use for the instance,
+ since anything which would end up with pcc_struct_return set
+ inside cplus_expand_expr.
+
+ * cp-tree.h (cons_up_default_function): Note change of prototype.
+
+Thu Aug 25 23:05:30 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * class.c (finish_struct): Undid change from Aug 21 testing
+ CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING.
+ * parse.y (left_curly): Likewise, undid change from Aug 21.
+ * decl.c (xref_tag): Undid change from Aug 21, set
+ CLASSTYPE_INTERFACE correctly, and added comments.
+
+Thu Aug 25 00:36:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Rework approach to synthesized methods; don't go through the parser
+ anymore.
+ * class.c (finish_struct): Use new synthesis approach.
+ * lex.c (cons_up_default_function): Now just creates declaration,
+ not code.
+ (largest_union_member): #if 0 out.
+ (default_assign_ref_body): Likewise.
+ (default_copy_constructor_body): Likewise.
+ * method.c (build_default_constructor): New function to synthesize X().
+ (build_copy_constructor): Synthesize X(X&).
+ (build_assign_ref): Synthesize X::operator=(X&).
+ (build_dtor): Synthesize ~X().
+
+ * error.c (cp_line_of): If we're dealing with an artificial
+ TYPE_DECL, look at the type instead.
+
+Wed Aug 24 11:11:50 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (sort_member_init): Check warn_reorder.
+ * decl2.c (lang_decode_option): Handle -W{no-,}reorder.
+
+ * cp-tree.h (CLASSTYPE_SOURCE_LINE): New macro.
+ * error.c (cp_line_of): Use CLASSTYPE_SOURCE_LINE for aggregates.
+ * class.c (finish_struct): Set CLASSTYPE_SOURCE_LINE.
+
+Tue Aug 23 09:28:35 1994 Mike Stump <mrs@cygnus.com>
+
+ * error.c (dump_decl): Improve wording, so that error messages
+ dont't read template<, class foo>...
+
+Mon Aug 22 15:30:51 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (label_colon): Also match a TYPENAME as a label name,
+ since they may have declared a class by that name but have also
+ tried to have a local label under the same name.
+
+ * pt.c (coerce_template_parms): Call cp_error, not cp_error_at,
+ for the message so they know at what point it was instantiated.
+
+Sun Aug 21 23:07:35 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and
+ CLASSTYPE_VTABLE_NEEDS_WRITING for signatures up to left_curly time.
+ * decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and
+ CLASSTYPE_VTABLE_NEEDS_WRITING for signatures down to left_curly time.
+ * parse.y (left_curly): New final resting place for setting
+ CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING for signatures.
+
+ * class.c (finish_struct): Don't test for function/field name
+ conflicts in signatures, since all the fields are compiler-constructed.
+
+Fri Aug 19 14:04:47 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * method.c (build_overload_nested_name): In qualified name
+ mangling, the template with value instantiation will have numeric
+ at end and may mixed with the name length of next nested level.
+ Add a '_' in between.
+ * method.c (build_overload_name): Ditto.
+ * method.c (build_overload_identifier): Ditto.
+
+Thu Aug 18 16:24:43 1994 Mike Stump <mrs@cygnus.com>
+
+ * error.c (dump_decl): Handle NULL args.
+
+Thu Sep 29 16:15:36 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
+
+ * g++.c: Rework last change so it's done like collect.c (and
+ gcc.c).
+
+Wed Sep 14 10:17:27 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
+
+ * g++.c: Include <sys/errno.h> in case `errno' is a macro
+ as permitted by ANSI C.
+
+Thu Aug 18 12:48:09 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and
+ CLASSTYPE_VTABLE_NEEDS_WRITING up to left_curly time.
+ * decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and
+ CLASSTYPE_VTABLE_NEEDS_WRITING down to left_curly time.
+ * parse.y (left_curly): New final resting place for setting
+ CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING.
+
+Thu Aug 11 11:32:42 1994 H.J. Lu <hjl@nynexst.com>
+
+ * g++.c (main): Only decrement "added" and set "library" to
+ NULL when "library" != NULL.
+
+Sat Aug 13 00:14:52 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't set TREE_PUBLIC on a function decl
+ just because its class has a known interface.
+ (decls_match): Deal with new format of template parms.
+
+ * lex.c (cons_up_default_function): Don't play with TREE_PUBLIC and
+ DECL_EXTERNAL here.
+
+Fri Aug 12 01:55:15 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (pushtag): SET_DECL_ARTIFICIAL on gratuitous typedefs.
+ (xref_defn_tag): Likewise.
+ (pushdecl): Only allow artificial typedefs to be shadowed.
+
+ * init.c (emit_base_init): Pass the right binfos to
+ expand_aggr_init_1.
+
+ * class.c (delete_duplicate_fields_1): Make it work right.
+ (finish_struct): Catch function/field name conflict.
+
+ * decl2.c (check_classfn): Pass the function to cp_error, not just
+ the name.
+
+ * init.c (sort_member_init): Warn when order of member initializers
+ does not match order of member declarations.
+ (emit_base_init): Call expand_aggr_init_1 with LOOKUP_PROTECT.
+
+ * error.c (dump_expr): Handle lists of functions.
+
+ * decl.c (start_function): #pragma interface only affects functions
+ that would otherwise be static.
+ (finish_decl): Don't warn about an unused variable if it has both
+ constructor and destructor, since the 'resource allocation is
+ initialization' idiom is relatively common.
+
+ * typeck.c (comp_target_types): Don't handle TEMPLATE_TYPE_PARMs.
+ (comp_target_parms): Likewise.
+ (compparms): Never consider default parms.
+ (common_base_type): Don't choose a virtual baseclass if there is a
+ more derived class in common.
+ (build_conditional_expr): If pedantic, pedwarn about conversion to
+ common base in conditional expr.
+
+ * class.c (instantiate_type): Handle template instantiation better.
+
+ * typeck.c (convert_arguments): Don't try to get tricky and convert
+ to int directly when PROMOTE_PROTOTYPES is set, as it breaks
+ user-defined conversions.
+
+ * lex.c (check_for_missing_semicolon): Also give error at end of
+ file.
+
+ * call.c (build_method_call): Don't promote arrays to pointers here.
+
+ * typeck.c (convert_arguments): Don't require the actual parameter
+ to be of a complete type if the formal parameter is a reference.
+
+Thu Aug 11 15:21:40 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Soften 'static' on member function error
+ to pedwarn.
+
+ * init.c (build_new): Don't automatically save rval.
+ (build_offset_ref): Do field lookup with proper basetype_path.
+
+Thu Aug 11 12:46:54 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * errfn.c (cp_silent): Declare to mark when we should avoid
+ emitting warnings and errors.
+ (cp_error): Check it.
+ (cp_warning): Likewise.
+ (cp_pedwarn): Likewise.
+ (cp_compiler_error): Likewise.
+ (cp_error_at): Likewise.
+ (cp_warning_at): Likewise.
+ (cp_pedwarn_at): Likewise.
+ * call.c (compute_conversion_costs): Set CP_SILENT when we start
+ out, and make sure we turn it off before we leave.
+
+Thu Aug 11 00:02:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (grok_array_decl): Try computing *(A+B) if neither
+ argument is obviously an array.
+
+Wed Aug 10 15:32:04 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (c_expand_start_case): Do cleanups here.
+
+ * parse.y (xcond): Do bool conversion here, too.
+ (simple_stmt, SWITCH case): Don't do cleanups here.
+
+ * decl.c (duplicate_decls): Don't treat builtins that have been
+ explicitly declared specially.
+
+Tue Aug 9 01:16:09 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * tree.c (make_deep_copy): Support copying pointer, reference,
+ function, array, offset and method types.
+
+ * decl.c (init_decl_processing): Mark exit and abort as
+ BUILT_IN_NONANSI so that duplicate_decls is kinder about
+ redeclaration.
+ (duplicate_decls): Don't give two errors for redeclaring a C
+ function with the same parms but a different return type.
+
+ * parse.y (paren_cond_or_null): Do cleanup and bool conversion here.
+ (condition): Instead of here.
+ (simple_stmt, SWITCH case): Also do cleanup here.
+
+ * decl2.c (finish_anon_union): Only break out FIELD_DECLs.
+
+ * call.c (build_method_call): Don't throw away the side effects of
+ the object in a call to a non-existent constructor.
+ * parse.y (primary): Likewise.
+
+ * method.c (build_decl_overload): Oop.
+
+ * decl2.c (lang_decode_option): Deal with flag_no_nonansi_builtin,
+ warn about uselessness of specifying -fansi-overloading.
+
+ * method.c (build_decl_overload): Treat any non-member new with one
+ parameter as __builtin_new.
+
+ * decl.c (init_decl_processing): Setup built-in meanings of exit,
+ _exit and abort.
+
+Mon Aug 8 15:03:30 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_readonly_or_volatile): Put a space between const and
+ volatile if both apply.
+
+ * init.c (perform_member_init): Clean up after this initialization.
+ (emit_base_init): Clean up after each base init, not after all have
+ been done.
+ (expand_aggr_vbase_init_1): Clean up after this init.
+
+Sun Aug 7 14:55:05 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Deal with destroying references.
+
+ * parse.y (condition): Do bool_truthvalue_conversion here.
+ (paren_expr_or_null): And here.
+ (simple_if): Not here.
+ (simple_stmt): Or here.
+
+Sat Aug 6 22:29:45 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (paren_expr_or_null): Wrap the expression in a
+ CLEANUP_POINT_EXPR.
+ (condition): Likewise.
+
+Sat Aug 6 19:46:37 1994 Rohan Lenard <rjl@easams.com.au>
+
+ * call.c (build_scoped_method_call): Fix error message when
+ destructor call refers to a nonexistent type.
+
+Sat Apr 16 22:43:30 1993 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * lex.h (rid): Deleted RID_RAISES, it's never used.
+ Moved RID_PUBLIC, RID_PRIVATE, RID_PROTECTED, RID_EXCEPTION,
+ RID_TEMPLATE and RID_SIGNATURE to the end of the enumeration,
+ they don't need to be touched in `grokdeclarator.'
+ (RID_LAST_MODIFIER): Defined macro to be RID_MUTABLE.
+
+ * decl.c (grokdeclarator): Use RID_LAST_MODIFIER instead of
+ RID_MAX as loop limit for finding declaration specifiers.
+
+Sat Apr 3 21:59:07 1993 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * lex.c (debug_yytranslate): Moved to parse.y since it needs to
+ access `yytname,' which is static in parse.c.
+
+Fri Apr 2 23:36:57 1993 Gerald Baumgarnter <gb@cs.purdue.edu>
+
+ * cp-tree.h (GNU_xref_ref): Fixed typo in extern declaration, it
+ was `GNU_xref_def' instead of `GNU_xref_ref.'
+
+Fri Aug 5 14:20:16 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (do_function_instantiation): Don't set TREE_PUBLIC and
+ DECL_EXTERNAL on 'extern' instantiations; wait until EOF to do that.
+ (do_type_instantiation): Likewise.
+
+ * decl2.c (import_export_inline): Decides at EOF what an inline's
+ linkage should be.
+ (finish_file): Call it.
+
+ * decl.c (start_function): Don't rely on the settings of TREE_PUBLIC
+ and DECL_EXTERNAL from do_*_instantiation. Only set
+ DECL_DEFER_OUTPUT on inlines whose linkage might actually change.
+ (finish_function): Use DECL_DEFER_OUTPUT to decide which inlines to
+ mark for later consideration, rather than DECL_FUNCTION_MEMBER_P.
+
+Fri Aug 5 01:12:20 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (get_class_offset_1, get_class_offset): New routine to
+ find the offset of the class where a virtual function is defined,
+ from the complete type.
+ * class.c (modify_one_vtable, fixup_vtable_deltas): Use
+ get_class_offset instead of virtual_offset as get_class_offset will
+ always provide the right answer.
+ * tree.c (virtual_offset): Remove. It only ever worked some of the
+ time.
+
+Tue Aug 2 12:44:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Put back unary_complex_lvalue call
+ that I thought was redundant.
+
+ * typeck.c (c_expand_return): Fix a case I missed before.
+
+Sun Jul 31 17:54:02 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (unify): Strip cv-quals from template type arguments (when
+ 'const T*' is matched to 'const char*', that does not mean that T is
+ 'const char').
+
+Fri Jul 29 01:03:06 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (do_type_instantiation): Instantiate nested TAGS, not
+ typedefs. Third time's the charm?
+
+ * parse.y (template_parm): Support default template parms.
+ * pt.c (process_template_parm): Likewise.
+ (end_template_parm_list): Likewise.
+ (coerce_template_parms): Likewise.
+ (mangle_class_name_for_template): Likewise.
+ (push_template_decls): Likewise.
+ (unify): Likewise.
+ * method.c (build_overload_identifier): Likewise.
+ * error.c (dump_decl): Likewise.
+
+Wed Jul 27 17:47:00 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (do_type_instantiation): Only instantiate nested *classes*.
+
+Tue Jul 26 13:22:40 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (note_debug_info_needed): Also emit debugging information
+ for the types of fields.
+
+Mon Jul 25 00:34:44 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (lookup_template_class): Pass 'template' to
+ coerce_template_parms instead of 'in_decl', since it's a more
+ meaningful context.
+
+ * typeck.c (c_expand_return): Make sure any cleanups for the return
+ expression get run.
+ (build_c_cast): Use CONVERT_EXPR for conversion to void.
+
+ * pt.c (do_type_instantiation): Also instantiate nested types.
+
+ * typeck.c (convert_for_assignment): Don't die when comparing
+ pointers with different levels of indirection.
+
+ * decl.c (grokdeclarator): The sub-call to grokdeclarator for
+ class-local typedefs sets DECL_ARGUMENTS, so we need to clear it
+ out.
+
+ * decl2.c (finish_anon_union): Don't die if the union has no
+ members.
+
+ * decl.c (grokdeclarator): Undo changes to declspecs when we're done
+ so that 'typedef int foo, bar;' will work.
+
+ * decl2.c (finish_file): Don't call expand_aggr_init for
+ non-aggregates.
+
+Mon Jul 25 00:03:10 1994 Teemu Torma <tot@trema.fi>
+
+ * decl.c (finish_function): We can't inline constructors and
+ destructors under some conditions with -fpic, but don't unset
+ DECL_INLINE.
+
+Mon Jul 25 00:03:10 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_object_ref): Make sure 'datum' is a valid object.
+
+Sun Jul 24 14:19:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Don't set DECL_FIELD_BITPOS on
+ non-fields.
+ (finish_struct_methods): Use copy_assignment_arg_p.
+
+ * cvt.c (cp_convert): If expr is an OFFSET_REF, resolve it instead
+ of giving an error.
+
+ * typeck.c (build_binary_op_nodefault): Don't set result_type if we
+ don't know how to compare the operands.
+
+ * decl.c (grokdeclarator): Avoid seg fault when someone uses '__op'
+ as a declarator-id in their program. Like the Linux headers do.
+ Arrgh.
+
+ * tree.c (lvalue_p): Treat calls to functions returning objects by
+ value as lvalues again.
+
+ * typeck.c (build_component_addr): Use convert_force to convert the
+ pointer in case the component type is also a private base class.
+
+ * search.c (get_matching_virtual): Fix bogus warning of overloaded
+ virtual.
+
+ * pt.c (overload_template_name): Set DECL_ARTIFICIAL on the created
+ TYPE_DECL to fix bogus shadowing warnings.
+
+Fri Jul 22 01:15:32 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (expand_aggr_init_1): const and volatile mismatches do not
+ prevent a TARGET_EXPR from initializing an object directly.
+
+Tue Jul 19 17:55:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_up_reference): Allow building up references to
+ `this', don't warn about making references to artificial variables
+ (like `this').
+
+ * tree.c (lvalue_p): `this' is not an lvalue.
+
+ * call.c (build_method_call): Accept using a typedef name (or
+ template type parameter) for explicit destructor calls.
+
+Thu Jul 14 09:42:23 1994 Mike Stump <mrs@cygnus.com>
+
+ * Version 2.6.0 released.
+
+Wed Jul 13 03:57:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (hack_identifier): Put back old code so lists of
+ non-functions will be handled properly.
+
+ * cp-tree.h (TYPE_NEEDS_CONSTRUCTING): #if 0 out; this macro is now
+ defined in the language-independent tree.h.
+
+ * tree.c (count_functions): Avoid bogus warning when compiling this
+ function.
+
+Mon Jul 11 18:37:20 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_reference_init): Always save the initializer of a
+ reference.
+
+Fri Jul 8 17:41:46 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (cplus_expand_expr_stmt): Wrap statement expressions inside
+ CLEANUP_POINT_EXPRs so that the stack slots can be reused.
+ (disabled for now)
+
+Fri Jul 8 12:59:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (hack_identifier): Fix for new overloading.
+
+ * typeck.c (build_binary_op_nodefault): Don't mess with division by
+ zero.
+
+Fri Jul 8 13:20:28 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * decl2.c (finish_file): Only call walk_sigtables, if
+ flag_handle_signatures is turned on, don't waste time otherwise.
+
+Fri Jul 8 02:27:41 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (push_overloaded_decl): Don't create overloads of one when
+ shadowing a class type.
+ * typeck.c (build_x_function_call): Complain about overloads of one.
+
+ * decl.c (grokdeclarator): Don't try to treat a char* as a tree.
+ (grokdeclarator): Fix setting of TREE_STATIC.
+ (start_decl): Clear DECL_IN_AGGR_P after calling duplicate_decls.
+
+Thu Jul 7 22:20:46 1994 Gerald Baumgartner <gb@andros.cygnus.com>
+
+ * cp-tree.h (walk_sigtables): Created extern declaration.
+ * decl2.c (walk_sigtables): Created function, patterned after
+ walk_vtables, even though we only need it to write out sigtables.
+ (finish_sigtable_vardecl): Created function.
+ (finish_vtable_vardecl): Changed 0 to NULL_PTR.
+ (finish_file): Call walk_sigtables.
+
+ * sig.c (build_signature_table_constructor): Mark class member
+ function pointed to from signature table entry as addressable.
+
+Thu Jul 7 13:39:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_decl): Check new decl of static member variable
+ against the declaration in the class here.
+ (grokvardecl): Instead of here.
+
+ * class.c (prepare_fresh_vtable): Call import_export_vtable if not
+ -fvtable-thunks.
+ (build_vtable): Likewise.
+
+ * decl2.c (import_export_vtable): Move logic for deciding the
+ interface of a template class from here.
+ (import_export_template): To here.
+ (finish_vtable_vardecl): Call import_export_template before
+ import_export_vtable.
+
+Wed Jul 6 20:25:48 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c (init_exception_processing): Setup interim_eh_hook to
+ call lang_interim_eh.
+ * except.c (do_unwind): Propagate throw object value across
+ stack unwinding.
+ * except.c (saved_throw_value): Used to hold the value of the object
+ being thrown. It is always a reference to the real value.
+ * except.c (expand_start_catch_block): Add handling for the
+ value of the exception object.
+ * except.c (expand_start_catch_block): Add handler for the handler,
+ so that throws inside the handler go to the outer block.
+ * except.c (expand_end_catch_block): Likewise.
+ * parse.y (handler_args): Use parm instead, as the other doesn't yet
+ handle references correctly.
+
+Wed Jul 6 17:55:32 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl2.c (mark_vtable_entries): If -ftable-thunks, set the
+ vtable entry properly to abort.
+
+Tue Jul 5 14:07:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Downgrade division by zero
+ errors to warnings.
+
+ * call.c (build_overload_call_real): Handle fnname being a list of
+ functions.
+ * typeck.c (build_x_function_call): Pass list of functions to
+ build_overload_call, not just the name.
+ * tree.c (count_functions): Complain when called for invalid
+ argument.
+
+ * decl.c (grokdeclarator): Fix settings of TREE_STATIC, TREE_PUBLIC
+ and DECL_EXTERNAL on static members and initialized const members.
+ * decl2.c (grokfield): Reflect this change.
+
+Fri Jul 1 09:35:51 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (init): ANSI C++ does not forbid { }.
+
+Thu Jun 30 00:35:22 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (lang_decode_option): Set warn_nonvdtor along with -Wall.
+ warn_nonvdtor defaults to off.
+
+ * class.c (instantiate_type): Use comptypes rather than relying on
+ types to satisfy ==.
+
+ * decl.c (start_function): Set DECL_DEFER_OUTPUT on all inlines that
+ might be static.
+
+ * tree.c (build_cplus_new): Never build WITH_CLEANUP_EXPRs.
+
+ * decl.c (grok_reference_init): Deal with ADDR_EXPRs of TARGET_EXPRs.
+
+ * cvt.c (cp_convert): Pass 0 to with_cleanup_p arg of
+ build_cplus_new.
+
+Wed Jun 29 22:31:09 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (finish_file): Maybe consider static inlines multiple
+ times, in case they reference each other.
+
+Tue Jun 28 11:58:38 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * class.c (finish_struct): Don't `cons_up_default_function's
+ for signatures.
+ (finish_struct): Handle an empty method_vec correctly.
+
+ * decl.c (grokdeclarator): Don't warn about a signature being
+ empty in a signature pointer declaration if we only saw a
+ forward declaration of the signature. Changed `warning's into
+ `cp_warning's.
+
+ * sig.c (build_sigtable): Don't die if a null signature table
+ constructor is returned.
+ (build_signature_pointer_constructor): If the signature table
+ constructor is null, the _sptr field is set to a null pointer
+ and cast to the appropriate type. Make copies of all null
+ pointers so that the type null_pointer_node doesn't get changed.
+ (build_signature_table_constructor): Added comments.
+
+ * sig.c (build_signature_pointer_constructor): Complain if we
+ try to assign to/initialize a signature pointer/reference of
+ an undefined signature.
+
+Mon Jun 27 14:05:16 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * typeck2.c (store_init_value): Don't be pedantic about
+ non-constant initializers of signature tables/pointers/references.
+
+Fri Jun 24 16:49:41 1994 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * decl.c (grokdeclarator): If we are grokking an opaque typedef
+ in a signature, don't complain about it begin static.
+
+Wed Jun 29 16:44:45 1994 Mike Stump <mrs@cygnus.com>
+
+ Fixes a problem of the this pointer being wrong in virtual calls to
+ methods that are not overridden in more derived classes.
+
+ * class.c (fixup_vtable_delta): New routine. It will fixup the
+ delta entries in vtables, wheever they need updating.
+ * class.c (finish_struct): Call the new routine for all virtual
+ bases, as they can have different offsets, than those used in base
+ classes that we derive our vtable from.
+
+Tue Jun 28 23:49:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_binary_op): Use the types before default
+ conversions in the error message.
+
+ * *.c: Use c_build_type_variant instead of build_type_variant where
+ the type might be an array.
+
+ * call.c (build_method_call): Call build_type_variant and
+ build_reference_type in the right order.
+ * decl.c (record_builtin_type): Likewise.
+
+Wed Jun 29 16:58:53 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Call build_type_variant and
+ build_reference_type in the right order.
+ * decl.c (record_builtin_type): Likewise.
+
+Tue Jun 28 23:49:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_binary_op): Use the types before default
+ conversions in the error message.
+
+ * *.c: Use c_build_type_variant instead of build_type_variant where
+ the type might be an array.
+
+Sat Jun 25 11:50:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): Try UDC's before doing the
+ reinterpret_cast thang, though.
+
+Fri Jun 24 01:24:01 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (c_expand_return): Don't USE the return value location
+ after we've expanded the jump.
+
+ * decl2.c (finish_file): Make sure DECL_SAVED_INSNS is not 0 before
+ trying to write out an inline.
+
+ * cvt.c (build_up_reference): Also do address adjustment when the
+ target type uses MI.
+ (convert_to_reference): Try UDCs only after built-in conversions.
+ (build_type_conversion_1): Don't play games with the argument to the
+ method.
+ (build_type_conversion): #if 0 out code for binding to reference.
+
+Thu Jun 23 00:22:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (finish_file): Use TREE_SYMBOL_REFERENCED to decide
+ whether to emit inlines.
+
+ * decl.c (grokdeclarator): Set explicit_int for decls that just
+ specify, say, 'long'.
+
+ * init.c (do_friend): Do overload C functions (or call pushdecl,
+ anyaway).
+
+Wed Jun 22 13:40:49 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_up_reference): Don't call readonly_error.
+ (convert_to_reference): Propagate const and volatile from expr to
+ its type.
+
+ * tree.c (lvalue_p): Random CALL_EXPRs are not lvalues.
+
+ * cvt.c (build_up_reference): Break out WITH_CLEANUP_EXPR when
+ creating a temporary.
+ (convert_to_reference): Lose excessive and incorrect trickiness.
+ (cp_convert): Call build_cplus_new with with_cleanup_p set.
+
+ * typeck2.c (build_functional_cast): Likewise.
+
+Tue Jun 21 17:38:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): signed, unsigned, long and short all
+ imply 'int'.
+
+ * decl.c (grokdeclarator): Allow "this is a type" syntax.
+ (grok_reference_init): Simplify and fix.
+
+Sun Jun 19 17:08:48 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): pedwarn about a typedef that specifies no
+ type.
+
+Sat Jun 18 04:16:50 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_function): Move TREE_PUBLIC and DECL_EXTERNAL
+ tinkering to after call to pushdecl.
+
+Fri Jun 17 14:48:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Handle destructors for non-aggregate
+ types properly.
+
+Thu Jun 16 16:48:05 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Make sure that the name given for the
+ destructor matches the constructor_name of the instance.
+
+ * pt.c (do_function_instantiation): A non-extern instantiation
+ overrides a later extern one.
+ (do_type_instantiation): Likewise.
+
+Wed Jun 15 19:34:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (expand_aggr_init): Use TYPE_MAIN_VARIANT to get the
+ unqualified array type.
+
+ * cp-tree.h (EMPTY_CONSTRUCTOR_P): Tests whether NODE is a
+ CONSTRUCTOR with no elements.
+
+ * decl.c (various): Lose empty_init_node.
+ (finish_decl): Use EMPTY_CONSTRUCTOR_P, do the empty CONSTRUCTOR
+ thing depending on the value of DECL_COMMON instead of
+ flag_conserve_space, do the empty CONSTRUCTOR thing for types that
+ don't have constructors, don't treat a real empty CONSTRUCTOR
+ specially.
+
+ * typeck2.c (process_init_constructor): Don't treat empty_init_node
+ specially.
+
+Wed Jun 15 19:05:25 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (override_one_vtable): Don't forget to merge in an old
+ overrider when we wanted to reuse a vtable, but couldn't.
+
+Wed Jun 15 15:03:16 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_decl): Put statics in common again.
+
+ * decl.c (grokdeclarator): Return NULL_TREE for an error rather than
+ setting the type to error_mark_node.
+
+ * typeck.c (build_modify_expr): Build up a COMPOUND_EXPR for enum
+ bitfield assignments.
+
+Tue Jun 14 12:23:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_op_properties): Const objects can be passed by value.
+
+Mon Jun 13 03:10:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (import_export_vtable): Force implicit instantiations to
+ be interface_only when -fno-implicit-templates.
+
+ * decl.c (duplicate_decls): Redeclaring a class template name is an
+ error.
+
+ * pt.c (end_template_decl): Call GNU_xref_decl for class templates.
+ * xref.c (GNU_xref_decl): Support templates.
+
+Sat Jun 11 17:09:05 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_op_properties): Split out checking for whether this
+ function should suppress the default assignment operator.
+ * decl2.c (grok_function_init): Likewise.
+ (copy_assignment_arg_p): New function to do just that.
+ Now considers virtual assignment operators that take a base as an
+ argument to count as copy assignment operators.
+
+ * search.c (dfs_debug_mark): Lose checks for DWARF_DEBUG and
+ TREE_ASM_WRITTEN, as they are redundant.
+
+ * pt.c (end_template_decl): Don't try to set DECL_CLASS_CONTEXT on a
+ decl that has no LANG_SPECIFIC part.
+ (do_type_instantiation): Force the debugging information for this
+ type to be emitted.
+
+ * decl.c (start_decl): Clear up uses of various types of templates
+ (say sorry for static data members, rather than "invalid template").
+ (expand_static_init): Fix initialization of static data members of
+ template classes.
+
+Fri Jun 10 00:41:19 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Set DECL_CONTEXT on static data members.
+
+ * g++.c (main): Use -xc++-cpp-output for .i files.
+
+ * pt.c (tsubst): Give meaningful error about declaring template for
+ a copy constructor which was not declared in the class template.
+ (do_type_instantiation): Explicit instantiation before the class
+ template is an error.
+ (instantiate_template): Don't die if tsubst returns error_mark_node.
+
+Thu Jun 9 19:04:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Don't synthesize the copy assignment operator if the one in a base
+ class is pure virtual.
+ * cp-tree.h (TYPE_HAS_ABSTRACT_ASSIGN_REF): New macro to indicate
+ whether the type has a pure virtual copy assignment operator.
+ * class.c (finish_base_struct): Don't generate the copy assignment
+ operator if a base class has a pure virtual one.
+ * decl.c (grok_op_properties): Add disabled code to set
+ TYPE_HAS_ABSTRACT_ASSIGN_REF with comment pointing to where it is
+ actually set.
+ * decl2.c (grok_function_init): Set TYPE_HAS_ABSTRACT_ASSIGN_REF.
+
+ * decl2.c (import_export_vtable): Always treat template
+ instantiations as if write_virtuals >= 2, and treat implicit
+ instantiations as external if -fno-implicit-templates.
+ (finish_file): Output all pending inlines if
+ flag_keep_inline_functions.
+
+Wed Jun 8 20:48:02 1994 Mike Stump <mrs@cygnus.com>
+
+ * tree.c (layout_vbasetypes): Align virtual base classes inside
+ complete objects, so that we don't core dump on machines such as
+ SPARCs when we access members that require larger than normal
+ alignments, such as a double. Also, we bump up the total alignment
+ on the complete type, as necessary.
+
+Wed Jun 8 16:18:14 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * gxxint.texi (Free Store): New section with code for examining
+ cookie.
+ (Limitations of g++): Remove operator delete entry, since it is no
+ longer accurate. Fix access control entry.
+
+ * typeck.c (build_unary_op): Pedwarn about taking the address of or
+ incrementing a cast to non-reference type.
+ (build_modify_expr): Use convert instead of convert_force again.
+
+ * search.c (get_base_distance): Use IS_AGGR_TYPE_CODE to check for
+ class type, not == RECORD_TYPE.
+
+ * decl.c (grokdeclarator): Cope with grokfndecl returning NULL_TREE.
+
+ * typeck2.c (report_case_error): #if 0 out.
+ * lex.c (real_yylex): Lose RANGE.
+ * parse.y: Likewise.
+
+Tue Jun 7 18:17:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (simple_stmt, case ranges): Use ELLIPSIS instead of RANGE.
+
+Mon Jun 6 19:39:57 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_c_cast): Don't shortcut conversions to the same
+ type. Don't replace consts with their values here, since that's now
+ done in cp_convert.
+
+ * cvt.c (cp_convert): When converting to bool, take
+ integer_zero_node to false_node and all other INTEGER_CSTs to
+ true_node.
+ (build_type_conversion): Don't complain about multiple conversions
+ to float if we're not really converting.
+
+Fri Jun 3 02:10:56 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Implement 'extern template class A<int>;' syntax for suppressing
+ specific implicit instantiations.
+ * cp-tree.h: Update prototypes for do_*_instantiation.
+ * pt.c (do_pending_expansions): Don't compile 'extern' explicit
+ instantiations.
+ (do_function_instantiation): Set DECL_EXTERNAL on 'extern' explicit
+ instantiations.
+ (do_type_instantiation): Likewise.
+ * parse.y (explicit_instantiation): Support 'extern template class
+ A<int>;' syntax.
+ * decl.c (start_function): Don't modify the settings of TREE_PUBLIC
+ and DECL_EXTERNAL on explicit instantiations.
+
+ * cvt.c (cp_convert): Replace constants with their values before
+ converting.
+ (cp_convert): Consistently use 'e' instead of 'expr'.
+
+Thu Jun 2 03:53:30 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck2.c (build_x_arrow): Resolve OFFSET_REFs first.
+
+Wed Jun 1 18:57:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck2.c (digest_init): Handle initializing a pmf with an
+ overloaded method.
+ * typeck.c (build_ptrmemfunc): Handle overloaded methods.
+
+ * decl.c (pushtag): Use build_decl to make TYPE_DECLs.
+ (xref_defn_tag): Likewise.
+ * pt.c (process_template_parm): Likewise.
+ (lookup_template_class): Likewise.
+ (push_template_decls): Likewise.
+ (instantiate_class_template): Likewise.
+ (create_nested_upt): Likewise.
+ * class.c (finish_struct): Don't try to set DECL_CLASS_CONTEXT on
+ TYPE_DECLs.
+
+ * typeck.c (convert_arguments): Make sure type is not NULL before
+ checking its TREE_CODE.
+
+Wed Jun 1 17:40:39 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (get_derived_offset): New routine.
+ * class.c (finish_base_struct): Make sure we set BINFO_VTABLE and
+ BINFO_VIRTUALS when we choose a new base class to inherit from.
+ * class.c (modify_one_vtable): Use get_derived_offset to get the
+ offset to the most base class subobject that we derived this binfo
+ from.
+ * class.c (finish_struct): Move code to calculate the
+ DECL_FIELD_BITPOS of the vfield up, as we need might need it for
+ new calls to get_derived_offset in modify_one_vtable.
+
+Wed Jun 1 16:50:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_member_call): Use build_pointer_type instead of
+ TYPE_POINTER_TO.
+
+Wed Jun 1 11:11:15 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Make sure we have a DNAME set before we
+ try to use it in an error.
+
+Wed Jun 1 09:48:49 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (convert_arguments, convert_for_initialization): Don't
+ strip NOP_EXPRs, when we are converting to a reference.
+
+Wed Jun 1 01:11:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_modify_expr): Don't dereference references when
+ initializing them.
+
+ * decl2.c (grokfield): Don't check for grokdeclarator returning
+ error_mark_node any more.
+
+ * decl.c (grokfndecl): Return NULL_TREE instead of error_mark_node.
+ (start_method): Return void_type_node instead of error_mark_node.
+
+ * typeck.c (build_modify_expr): Resolve offset refs earlier.
+
+Tue May 31 16:06:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Resolve OFFSET_REFs in the object.
+
+ * typeck.c (build_modify_expr): Dereference references before trying
+ to assign to them.
+
+ * call.c (build_method_call): Don't confuse type conversion
+ operators with constructors.
+ * typeck2.c (build_functional_cast): Just call build_c_cast if there
+ was only one parameter.
+ * method.c (build_typename_overload): Don't set
+ IDENTIFIER_GLOBAL_VALUE on these identifiers.
+ * decl.c (grok_op_properties): Warn about defining a type conversion
+ operator that converts to a base class (or reference to it).
+ * cvt.c (cp_convert): Don't try to use a type conversion operator
+ when converting to a base class.
+ (build_type_conversion_1): Don't call constructor_name_full on an
+ identifier.
+ * cp-tree.h (DERIVED_FROM_P): Should be self-explanatory.
+
+ * decl.c (start_decl): Don't complain that error_mark_node is an
+ incomplete type.
+ (finish_decl): Check for type == error_mark_node.
+
+Mon May 30 23:38:55 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_function): Set DECL_DEFER_OUTPUT on implicit
+ instantiations and inline members.
+
+ * spew.c (yylex): Set looking_for_template if the next token is a '<'.
+
+ * lex.h: Declare looking_for_template.
+
+ * decl.c (lookup_name_real): Use looking_for_template to arbitrate
+ between type and template interpretations of an identifier.
+
+Sat May 28 04:07:40 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (instantiate_template): Zero out p if we found a
+ specialization.
+
+ * decl.c (grokdeclarator): Elucidate warning.
+ (grokdeclarator): If pedantic AND -ansi, complain about long long.
+
+ Make explicit instantiation work reasonably. It is now appropriate
+ to deprecate the use of -fexternal-templates.
+ * pt.c (instantiate_template): Set DECL_TEMPLATE_SPECIALIZATION or
+ DECL_IMPLICIT_INSTANTIATION on fndecl as appropriate.
+ (end_template_instantiation): Reflect changes in USE_TEMPLATE
+ semantics.
+ (do_pending_expansions): if (!flag_implicit_templates) DECIDE(0);
+ (do_function_instantiation): Don't set EXPLICIT_INST if
+ flag_external_templates is set. Do set TREE_PUBLIC and DECL_EXTERN
+ appropriately otherwise.
+ (do_type_instantiation): Set interface info for class. Set
+ TREE_PUBLIC and DECL_EXTERN for methods. Do none of this if
+ flag_external_templates is set.
+ * parse.y: Reflect changes in USE_TEMPLATE semantics.
+ * decl2.c: New flag flag_implicit_templates determines whether or
+ not implicit instantiations get emitted. This flag currently
+ defaults to true, and must be true for -fexternal-templates to work.
+ (finish_file): Consider flag_implement_inlines when
+ setting DECL_EXTERNAL. Consider flag_implicit_templates when
+ deciding whether or not to emit a static copy.
+ * decl.c (start_function): Set TREE_PUBLIC and DECL_EXTERNAL
+ properly for template instantiations.
+ (start_method): Set DECL_IMPLICIT_INSTANTIATION on methods of a
+ template class.
+ * cp-tree.h (CLASSTYPE_USE_TEMPLATE): Change semantics.
+ (DECL_USE_TEMPLATE): Parallel macro for FUNCTION and VAR_DECLs.
+ (various others): Accessor macros for the above.
+
+Fri May 27 13:57:40 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Division by constant zero is
+ an error.
+
+Fri May 27 13:50:15 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (override_one_vtable): Don't modify things we don't own.
+
+Fri May 27 01:42:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (finish_decl): Don't postpone processing the initializer of
+ a decl with DECL_EXTERNAL set, and do call rest_of_compilation for a
+ PUBLIC const at toplevel.
+ (grokdeclarator): pedwarn about initializing non-const or
+ non-integral statics in the class body.
+
+ * decl.c (pushtag): Don't try to set DECL_CLASS_CONTEXT on a
+ TYPE_DECL.
+
+ * call.c (convert_harshness): Dereference reference on rhs before
+ proceeding, properly grok passing const things to non-const
+ references.
+
+ * typeck.c (build_unary_op): Soften error about taking the address
+ of main() to a pedwarn.
+
+ * lex.c (default_copy_constructor_body): Unambiguously specify base
+ classes (i.e. A((const class ::A&)_ctor_arg) ).
+ (default_assign_ref_body): Likewise.
+
+Thu May 26 13:13:55 1994 Gerald Baumgartner <gb@mexican.cygnus.com>
+
+ * decl2.c (grokfield): Don't complain about local signature
+ method declaration without definition.
+
+ * call.c (convert_harshness): If `type' is a signature pointer
+ and `parmtype' is a pointer to a signature, just return 0. We
+ don't really convert in this case; it's a result of making the
+ `this' parameter of a signature method a signature pointer.
+
+ * call.c (build_method_call): Distinguish calling the default copy
+ constructor of a signature pointer/reference from a signature
+ member function call.
+
+Thu May 26 12:56:25 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (grokfield): Don't set TREE_PUBLIC on member function
+ declarations.
+
+ * decl.c (duplicate_decls): A previous function declaration as
+ static overrides a subsequent non-static definition.
+ (grokdeclarator): Don't set TREE_PUBLIC on inline method
+ declarations.
+
+Wed May 25 14:36:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Handle initialization of static const
+ members.
+ (finish_decl): Likewise.
+
+ * decl2.c (grokfield): Allow initialization of static const members
+ even when pedantic.
+
+ * decl2.c (grokfield): Deal with grokdeclarator returning
+ error_mark_node.
+
+ * decl.c (grok_ctor_properties): Return 0 for A(A) constructor.
+ (grokfndecl): Check the return value of grok_ctor_properties.
+ (start_method): Likewise.
+
+ * parse.y (absdcl): Expand type_quals inline.
+
+Tue May 24 19:10:32 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (pushtag): Use IS_AGGR_TYPE rather than checking for a
+ RECORD_TYPE.
+
+Tue May 24 18:09:16 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * cp-tree.h (VTABLE_NAME_FORMAT): If flag_vtable_thunks,
+ always use "__vt_%s".
+ * decl2.c (finish_vtable_vardecl): Don't consider abstract virtuals
+ when looking for a "sentinal" method (to decide on emitting vtables).
+ * decl2.c (finish_file): Scan all decls for thunks that need
+ to be emitted.
+ * decl2.c (finish_vtable_vardecl): Don't bother calling emit_thunk.
+ * method.c (make_thunk): Use a more meaningful label. If there
+ exists a matching top-level THUNK_DECL re-use it; otherwise
+ create a new THUNK_DECL (and declare it).
+ * method.c (emit_thunk): Make thunk external/public depending
+ on the underlying method.
+
+Tue May 24 00:22:04 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (tsubst): Use lookup_name_nonclass to find guiding decls, not
+ lookup_name.
+
+ * call.c (build_overload_call_real): Don't immediately pick a
+ function which matches perfectly.
+
+ * decl.c (grokdeclarator): Use c_build_type_variant for arrays.
+ (grokdeclarator): Warn about, and throw away, cv-quals attached to a
+ reference (like 'int &const j').
+
+ * typeck.c (convert_arguments): Don't mess with i for methods.
+ * call.c (build_method_call): Pass the function decl to
+ convert_arguments.
+
+ * typeck.c (comp_ptr_ttypes_real): New function. Implements the
+ checking for which multi-level pointer conversions are allowed.
+ (comp_target_types): Call it.
+ (convert_for_assignment): Check const parity on the ultimate target
+ type, too. And make those warnings pedwarns.
+
+Mon May 23 14:11:24 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_char): Use TARGET_* for character constants.
+
+Mon May 23 13:03:03 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * tree.c (debug_no_list_hash): Make static.
+
+ * decl.c (decls_match): Say the types don't match if newdecl ends up
+ with a null type, after we've checked if olddecl does.
+ (pushdecl): Check if the decls themselves match before looking for
+ an extern redeclared as static, to avoid inappropriate and incorrect
+ warnings.
+
+Fri May 20 14:04:34 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Make warning about duplicate short, etc.
+ a pedwarn.
+
+ * typeck.c (build_c_cast): Casting to function or method type is an
+ error.
+
+ * class.c (finish_struct): Make warning for anonymous class with no
+ instances a pedwarn.
+
+ * Makefile.in (stamp-parse): Expect a s/r conflict.
+
+ * typeck.c (build_modify_expr): pedwarn about using a non-lvalue
+ cast as an lvalue.
+
+Thu May 19 12:08:48 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (type_promotes_to): Make sure bool promotes to int rather
+ than unsigned on platforms where sizeof(char)==sizeof(int).
+
+Wed May 18 14:27:06 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_c_cast): Tack on a NOP_EXPR when casting to
+ another variant.
+ (build_modify_expr): Don't strip NOP_EXPRs, and don't get tricky
+ and treat them as lvalues.
+
+ * decl.c (shadow_tag): Do complain about forward declarations of
+ enums and empty declarations.
+ * parse.y: Don't complain about forward declarations of enums and
+ empty declarations.
+
+ * typeck.c (convert_for_assignment): Complain about changing
+ the signedness of a pointer's target type.
+
+ * parse.y (stmt): Move duplicated code for checking case values from
+ here.
+ * decl2.c (check_cp_case_value): To here. And add a call to
+ constant_expression_warning.
+
+ * typeck.c (convert_for_assignment): Don't complain about assigning
+ a negative value to bool.
+
+ * decl.c (init_decl_processing): Make bool unsigned.
+
+ * class.c (finish_struct): Allow bool bitfields.
+
+Wed May 18 12:35:27 1994 Ian Lance Taylor <ian@tweedledumb.cygnus.com>
+
+ * Make-lang.in (c++.install-man): Get g++.1 from $(srcdir)/cp.
+
+Wed May 18 03:28:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_type_conversion): Lose special handling of
+ truthvalues.
+
+ * search.c (dfs_pushdecls): Improve shadowing warning.
+
+Tue May 17 13:34:46 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_delete): Throw away const and volatile on `this'.
+
+ * decl.c (finish_enum): Put the constants in TYPE_VALUES again,
+ rather than the enumerators.
+ (pushtag): s/cdecl/c_decl/g
+
+Mon May 16 23:04:01 1994 Stephen R. van den Berg <berg@pool.informatik.rwth-aachen.de>
+
+ * cp/typeck.c (common_type): Attribute merging.
+ (comp_types): Utilize COMP_TYPE_ATTRIBUTES macro.
+
+ * cp/parse.y: Revamp attribute parsing.
+
+Mon May 16 01:40:34 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (shadow_tag): Also check for inappropriate use of auto and
+ register.
+
+ * method.c (build_overload_name): Clarify that the illegal case is a
+ pointer or reference to array of unknown bound.
+
+ * error.c (dump_type_prefix): Print references to arrays properly.
+
+ * typeck.c (various): Be more helpful in pointer
+ comparison diagnostics.
+
+ * tree.c (lvalue_p): MODIFY_EXPRs are lvalues again. Isn't this
+ fun?
+
+ * parse.y: Also catch an error after valid stmts.
+
+ * search.c (dfs_init_vbase_pointers): Don't abort because `this' is
+ const.
+
+ * typeck.c (convert_for_initialization): If call to
+ convert_to_reference generated a diagnostic, print out the parm
+ number and function decl if any.
+
+ * errfn.c (cp_thing): Check atarg1 to determine whether or not we're
+ specifying a line, not atarg.
+
+ * tree.c (build_cplus_method_type): Always make `this' const.
+
+ * decl2.c (grokclassfn): If -fthis-is-variable and this function is
+ a constructor or destructor, make `this' non-const.
+
+ * typeck.c (build_modify_expr): Don't warn specially about
+ assignment to `this' here anymore, since it will be caught by the
+ usual machinery.
+
+ * various: Disallow specific GNU extensions (variable-size arrays,
+ etc.) when flag_ansi is set, not necessarily when pedantic is set,
+ so that people can compile with -pedantic-errors for tighter const
+ checking and such without losing desirable extensions.
+
+ * typeck2.c (build_functional_cast): Call build_method_call with
+ LOOKUP_PROTECT.
+ (process_init_constructor): Only process FIELD_DECLs.
+
+ * decl.c (finish_decl): Also force static consts with no explicit
+ initializer that need constructing into the data segment.
+
+ * init.c (build_delete): Undo last patch, as it interferes with
+ automatic cleanups.
+
+Sat May 14 01:59:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c, class.h, cp-tree.h, cvt.c, decl2.c: Lose old overloading
+ code.
+
+ * init.c (build_delete): pedwarn about using plain delete to delete
+ an array.
+
+Fri May 13 16:45:07 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (comp_target_types): Be more helpful in contravariance
+ warnings, and make them pedwarns.
+
+ * decl.c (grokdeclarator): Use decl_context to decide whether or not
+ this is an access declaration.
+
+ * class.c (finish_struct_bits): Set TYPE_HAS_INT_CONVERSION if it
+ has a conversion to enum or bool, too.
+
+Fri May 13 16:31:27 1994 Mike Stump <mrs@cygnus.com>
+
+ * method.c (emit_thunk): Make declaration for
+ current_call_is_indirect local (needed for hppa).
+
+Fri May 13 16:16:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (uses_template_parms): Grok BOOLEAN_TYPE.
+ (tsubst): Likewise.
+
+Fri May 13 16:23:32 1994 Mike Stump <mrs@cygnus.com>
+
+ * pt.c (tsubst): If there is already a function for this expansion,
+ use it.
+ * pt.c (instantiate_template): Likewise.
+
+Fri May 13 10:30:42 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (implicitly_scoped_stmt, simple_stmt case): Use
+ kept_level_p for MARK_ENDS argument to expand_end_bindings, to avoid
+ generating debug info for unemitted symbols on some systems.
+
+ * cp-tree.h (build_static_cast, build_reinterpret_cast,
+ build_const_cast): Add declarations.
+
+Fri May 13 09:50:31 1994 Mike Stump <mrs@cygnus.com>
+
+ * search.c (expand_indirect_vtbls_init): Fix breakage from Apr 27
+ fix. We now try get_binfo, and if that doesn't find what we want,
+ we go back to the old method, which still sometimes fails.
+
+Fri May 13 01:43:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (initdcl): Call cplus_decl_attributes on the right
+ variable.
+ * decl2.c (cplus_decl_attributes): Don't call decl_attributes for
+ void_type_node.
+
+ * typeck.c (build_binary_op_nodefault): Change result_type for
+ comparison ops to bool.
+ (build_binary_op): Convert args of && and || to bool.
+ * cvt.c (build_default_binary_type_conversion): Convert args of &&
+ and || to bool.
+ (build_default_unary_type_conversion): Convert arg of ! to bool.
+ (type_promotes_to): bool promotes to int.
+
+Fri May 13 01:43:18 1994 Mike Stump <mrs@cygnus.com>
+
+ Implement the new builtin `bool' type.
+ * typeck.c (build_binary_op_nodefault): Convert args of && and || to
+ bool.
+ (build_unary_op): Convert arg of ! to bool.
+ * parse.y: Know true and false. Use bool_truthvalue_conversion.
+ * method.c (build_overload_value): Know bool.
+ (build_overload_name): Likewise.
+ * lex.c (init_lex): Set up RID_BOOL.
+ * gxx.gperf: Add bool, true, false.
+ * error.c (*): Know bool.
+ * decl.c (init_decl_processing): Set up bool, true, false.
+ * cvt.c (cp_convert): Handle conversion to bool.
+ (build_type_conversion): Likewise.
+ * *.c: Accept bool where integers and enums are accepted (use
+ INTEGRAL_CODE_P macro).
+
+Thu May 12 19:13:54 1994 Richard Earnshaw <rwe11@cl.cam.ac.uk>
+
+ * g++.c: Use #ifdef for __MSDOS__, not #if.
+
+Thu May 12 18:05:18 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (lang_f_options): Handle -fshort-temps. -fshort-temps
+ gives old behavior , and destroys temporaries earlier. Default
+ behavior now conforms to the ANSI working paper.
+
+Thu May 12 14:45:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_modify_expr): Understand MODIFY_EXPR as an lvalue.
+ Use convert_force to convert the result of a recursive call when we
+ are dealing with a NOP_EXPR. Don't automatically wrap MODIFY_EXPRs
+ in COMPOUND_EXPRs any more.
+ (various): Lose pedantic_lvalue_warning.
+ (unary_complex_lvalue): Understand MODIFY_EXPR.
+
+ * cvt.c (convert_to_reference): Allow DECL to be error_mark_node if
+ we don't know what we're initializing.
+
+Wed May 11 01:59:36 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): Modify to use convtype parameter.
+ Only create temporaries when initializing a reference, not when
+ casting.
+ (cp_convert): New main function.
+ (convert): Call cp_convert.
+ * cvt.c, decl.c, typeck.c: Fix calls to convert_to_reference.
+ * cp-tree.h (CONV_*): New constants used by conversion code for
+ selecting conversions to perform.
+
+ * tree.c (lvalue_p): MODIFY_EXPRs are no longer lvalues.
+
+ * typeck.c (build_{static,reinterpret,const_cast): Stubs that just
+ call build_c_cast.
+ * parse.y: Add {static,reinterpret,const}_cast.
+ * gxx.gperf: Likewise.
+
+ * typeck.c (common_type): Allow methods with basetypes of different
+ UPTs.
+ (comptypes): Deal with UPTs.
+ (build_modify_expr): Wrap all MODIFY_EXPRs in a COMPOUND_EXPR.
+
+ * pt.c (end_template_decl): Check for multiple definitions of member
+ templates.
+
+ * call.c (build_method_call): Complain about calling an abstract
+ virtual from a constructor.
+
+ * typeck.c (pointer_int_sum): Check for the integer operand being 0
+ after checking the validity of the pointer operand.
+
+ * typeck2.c (digest_init): Pedwarn about string initializer being
+ too long.
+
+Tue May 10 12:10:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (push_overloaded_decl): Only throw away a builtin if the
+ decl in question is the artificial one.
+
+ * parse.y (simple_stmt, switch): Use implicitly_scoped_stmt because
+ expand_{start,end}_case cannot happen in the middle of a block.
+
+ * cvt.c (build_type_conversion_1): Use convert again.
+
+Tue May 10 11:52:04 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck2.c (digest_init): Make sure we check for signed and
+ unsigned chars as well when warning about string initializers.
+
+ * init.c (emit_base_init): Check if there's a DECL_NAME on the
+ member before trying to do an initialization for it.
+
+Tue May 10 11:34:37 1994 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Don't do anything useful when cross compiling.
+
+Tue May 10 03:04:13 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (duplicate_decls): Fix up handling of builtins yet again.
+ (push_overloaded_decl): Likewise.
+
+ * cvt.c (convert): Don't look for void type conversion.
+
+Mon May 9 18:05:41 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (do_friend): Only do a pushdecl for friends, not
+ pushdecl_top_level.
+
+Mon May 9 13:36:34 1994 Jim Wilson <wilson@sphagnum.cygnus.com>
+
+ * decl.c (lookup_name_current_level): Put empty statement after
+ the label OUT to make the code valid C.
+
+Mon May 9 12:20:57 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Only complain about
+ comparing void * and a function pointer if void * is smaller.
+
+Sun May 8 01:29:13 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (lookup_name_current_level): Move through temporary binding
+ levels.
+
+ * parse.y (already_scoped_stmt): Revive.
+ (simple_stmt): Use it again.
+
+ * decl.c (poplevel): Always call poplevel recursively if we're
+ dealing with a temporary binding level.
+
+Sat May 7 10:52:28 1994 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (finish_decl): Make sure we run cleanups for initial values
+ of decls. Cures memory leak.
+ * decl.c (expand_static_init): Likewise for static variables.
+ * decl2.c (finish_file): Likewise for globals.
+
+Sat May 7 03:57:44 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (commonparms): Don't complain about redefining default
+ args.
+
+ * decl.c (duplicate_decls): Don't complain twice about conflicting
+ function decls.
+ (decls_match): Don't look at default args.
+ (redeclaration_error_message): Complain about redefining default
+ args.
+
+ * call.c (build_overload_call_real): Also deal with guiding
+ declarations coming BEFORE the template decl.
+
+ * pt.c (unify): Allow different parms to have different
+ cv-qualifiers.
+ (unify): Allow trivial conversions on non-template parms.
+
+Fri May 6 03:53:23 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (tsubst): Support OFFSET_TYPEs.
+ (unify): Likewise.
+
+ * decl2.c (finish_decl_parsing): Call push_nested_class with a type.
+
+ * init.c (build_offset_ref): Fix error message.
+ * search.c (lookup_field): Likewise.
+
+ * call.c (build_scoped_method_call): Pass binfo to
+ build_method_call.
+ * typeck.c (build_object_ref): Likewise.
+
+ * typeck2.c (binfo_or_else): Don't return a _TYPE.
+
+ * class.c (finish_struct): Don't complain about re-use of inherited
+ names or shadowing of type decls.
+ * decl.c (pushdecl_class_level): Likewise.
+
+ * decl.c (finish_enum): Set the type of all the enums.
+
+ * class.c (finish_struct): Don't get confused by access decls.
+
+ * cp-tree.h (TYPE_MAIN_DECL): New macro to get the _DECL for a
+ _TYPE. You can stop using TYPE_NAME for that now.
+
+ * parse.y: Lose doing_explicit (check $0 instead).
+ * gxx.gperf: 'template' now has a RID.
+ * lex.h (rid): Likewise.
+ * lex.c (init_lex): Set up the RID for 'template'.
+
+ * parse.y (type_specifier_seq): typed_typespecs or
+ nonempty_type_quals. Use it.
+ (handler_args): Fix bogus syntax.
+ (raise_identifier{,s}, optional_identifier): Lose.
+ * except.c (expand_start_catch_block): Use grokdeclarator to parse
+ the catch variable.
+ (init_exception_processing): The second argument to
+ __throw_type_match is ptr_type_node.
+
+ Fri May 6 07:18:54 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ change propagated from c-decl.c of snapshot 940429 ]
+ * cp/decl.c (finish_decl): Setting asmspec_tree should not
+ zero out the old RTL.
+
+Fri May 6 01:25:38 1994 Mike Stump <mrs@cygnus.com>
+
+ Add alpha exception handling support to the compiler.
+ Quick and dirty backend in except.c.
+
+ * cp/*: Remove most remnants of old exception handling support.
+ * decl.c (finish_function): Call expand_exception_blocks to put
+ the exception hanlding blocks at the end of the function.
+ * dec.c (hack_incomplete_structures): Make sure expand_decl_cleanup
+ comes after expand_decl_init.
+ * except.c: Reimplementation.
+ * expr.c (cplus_expand_expr): Handle THROW_EXPRs.
+ * lex.c (init_lex): Always have catch, try and throw be reserved
+ words, so that we may always parse exception handling.
+ * parse.y: Cleanup to support new interface into exception handling.
+ * tree.def (THROW_EXPR): Add.
+
+Thu May 5 17:35:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (simple_stmt, for loops): Use implicitly_scoped_stmt.
+ (various): Lose .kindof_pushlevel and partially_scoped_stmt.
+
+Thu May 5 16:17:27 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * parse.y (already_scoped_stmt): Move expand_end_binding() to
+ fix the unmatched LBB/LBE in stabs.
+
+Thu May 5 14:36:17 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (set_nested_typename): Set TREE_MANGLED on the new
+ identifiers.
+ (pushdecl): Check TREE_MANGLED.
+ (xref_tag): Likewise.
+ * cp-tree.h (TREE_MANGLED): This identifier is a
+ DECL_NESTED_TYPENAME (named to allow for future use to denote
+ mangled function names as well).
+
+ Implement inconsistency checking specified in [class.scope0].
+ * decl.c (lookup_name_real): Don't set ICV here after all.
+ (finish_enum): Also set the type of the enumerators themselves.
+ (build_enumerator): Put the CONST_DECL in the list instead of its
+ initial value.
+ (pushdecl_class_level): Check inconsistent use of a name in the
+ class body.
+ * class.c (finish_struct): Check inconsistent use of a name in the
+ class body. Don't set DECL_CONTEXT on types here anymore.
+ * parse.y (qualified_type_name): Note that the identifier has now
+ been used (as a type) in the class body.
+ * lex.c (do_identifier): Note that the identifier has now been used
+ (as a constant) in the class body.
+ * error.c (dump_decl): Print type and enum decls better.
+
+Thu May 5 09:35:35 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (build_modify_expr): Warn about assignment to `this'.
+
+Wed May 4 15:55:49 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_delete): Use the global operator delete when
+ requested.
+
+ * decl.c (lookup_name_real): If we find the type we're looking in a
+ base class while defining a class, set IDENTIFIER_CLASS_VALUE for
+ the type.
+
+ * class.c (finish_struct): Remove a couple of dependencies on
+ language linkage.
+
+ * decl.c (pushtag): Classes do nest in extern "C" blocks.
+ (pushdecl): Only set DECL_NESTED_TYPENAME on the canonical one for
+ the type.
+ (pushtag): Remove another dependency on the language linkage.
+
+ * lex.c (cons_up_default_function): Don't set DECL_CLASS_CONTEXT to
+ a const-qualified type.
+
+ * decl.c (push_overloaded_decl): Throw away built-in decls here.
+ (duplicate_decls): Instead of here.
+
+Wed May 4 15:27:40 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Do The Right
+ Thing (I hope) if we're using thunks.
+
+Wed May 4 13:52:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (specialization): aggr template_type_name ';'.
+ (named_class_head_sans_basetype): Use it.
+ (explicit_instantiation): Likewise.
+ (tmpl.2): Revert.
+
+ * cvt.c (build_type_conversion_1): Use convert_for_initialization,
+ rather than convert, to do conversions after the UDC.
+
+ * cp-tree.h (SHARED_MEMBER_P): This member is shared between all
+ instances of the class.
+
+ * search.c (lookup_field): If the entity found by two routes is the
+ same, it's not ambiguous.
+
+Wed May 4 12:10:00 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (lookup_name_real): Check for a NULL TREE_VALUE,
+ to prevent the compiler from crashing ...
+
+Wed May 4 11:19:45 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): If we don't have an object, check
+ basetype_path to figure out where to look up the function.
+
+ * typeck.c (convert_for_initialization): Pass TYPE_BINFO (type) to
+ build_method_call in case exp is NULL_TREE.
+
+Tue May 3 16:02:53 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ Give a vtable entries a unique named type, for the sake of gdb.
+ * class.c (build_vtable_entry): The address of a thunk now has
+ type vtable_entry_type, not ptr_type_node.
+ * method.c (make_thunk): Fix type of THUNK_DECL.
+ * class.c (add_virtual_function, override_one_vtable): Use
+ vfunc_ptr_type_node, instead of ptr_type_node.
+ * cp-tree.h (vfunc_ptr_type_node): New macro.
+ * decl.c (init_decl_processing): Make vtable_entry_type
+ be a unique type of pointer to a unique function type.
+
+Tue May 3 09:20:44 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (do_explicit): Sets doing_explicit to 1.
+ (explicit_instantiation): Use do_explicit rather than TEMPLATE
+ directly, add "do_explicit error" rule.
+ (datadef): Set doing_explicit to 0 after an explicit instantiation.
+ (tmpl.2): Don't instantiate if we see a ';' unless we're doing an
+ explicit instantiation.
+ (named_class_head_sans_basetype): Remove aggr template_type_name
+ ';' again.
+
+Mon May 2 23:17:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (lookup_nested_tag): Lose.
+
+ * decl2.c (grokfield): Set DECL_CONTEXT on TYPE_DECLs.
+ (lookup_name_nonclass): Lose.
+
+ * decl.c (poplevel_class): Add force parameter.
+ (lookup_name_real): Fix handling of explicit scoping which specifies
+ a class currently being defined. Add 'nonclass' argument.
+ (lookup_name, lookup_name_nonclass): Shells for lookup_name_real.
+
+ * class.c (finish_struct): Don't unset IDENTIFIER_CLASS_VALUEs here.
+ (popclass): Force clearing of IDENTIFIER_CLASS_VALUEs if we're being
+ called from finish_struct.
+
+Mon May 2 19:06:21 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (init_decl_processing), cp-tree.h: Removed memptr_type.
+ (It seeems redundant, given build_ptrmemfunc_type.)
+ * typeck.c (get_member_function_from_ptrfunc), gc.c (build_headof,
+ build_classof): Use vtable_entry_type instead of memptr_type.
+ * method.c (emit_thunk): Call poplevel with functionbody==0
+ to prevent DECL_INITIAL being set to a BLOCK.
+
+Mon May 2 15:02:11 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (named_class_head_sans_basetype): Add "aggr
+ template_type_name ';'" rule for forward declaration of
+ specializations.
+
+Mon May 2 15:02:11 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (instantiate_type): Deal with pmf's.
+
+ * Make-lang.in (cc1plus): Don't depend on OBJS or BC_OBJS, since
+ stamp-objlist does.
+
+ * Makefile.in (../cc1plus): Depend on OBJDEPS.
+ (OBJDEPS): Dependency version of OBJS.
+
+Mon May 2 12:51:31 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * search.c (dfs_debug_mark): Unmark TYPE_DECL_SUPPRESS_DEBUG, not
+ DECL_IGNORED_P.
+
+Fri Apr 29 12:29:56 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Clear out memory of local tags. And
+ typedefs.
+
+ * decl2.c (grokclassfn): Don't set DECL_CONTEXT to a cv-qualified
+ type.
+ * search.c (get_matching_virtual): Be more helpful in error message.
+
+ * *: Use DECL_ARTIFICIAL (renamed from DECL_SYNTHESIZED).
+
+ * lex.c (default_assign_ref_body): Expect TYPE_NESTED_NAME to work.
+ (default_copy_constructor_body): Likewise.
+
+ * class.c (finish_struct): Don't gratuitously create multiple decls
+ for nested classes.
+
+Thu Apr 28 23:39:38 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Avoid clobbering the arg types of other functions when reverting
+ static member functions.
+ * decl.c (revert_static_member_fn): Rearrange arguments, don't
+ require values for 'fn' and 'argtypes', add warning to comment
+ above.
+ (decls_match): Rearrange arguments in call to rsmf.
+ (grok_op_properties): Don't pass values for fn and argtypes.
+ * pt.c (instantiate_template): Don't pass values for fn and argtypes.
+
+Thu Apr 28 16:29:11 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * Make-lang.in (cc1plus): Depend on stamp-objlist.
+ * Makefile.in (BC_OBJS): Delete.
+ (OBJS): Cat ../stamp-objlist to get language independent files.
+ Include ../c-common.o.
+ (../cc1plus): Delete reference to BC_OBJS.
+
+Thu Apr 28 02:12:08 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (compute_access): No really, deal with static members
+ properly. Would I lie to you?
+
+ Implement lexical hiding of function declarations.
+ * pt.c (tsubst): Use lookup_name to look for function decls to guide
+ instantiation.
+ * method.c (build_opfncall): Use lookup_name_nonclass to look for
+ non-member functions.
+ * init.c (do_friend): Use lookup_name_nonclass to look for
+ functions.
+ * error.c (ident_fndecl): Use lookup_name to look for functions.
+ * decl2.c (lookup_name_nonclass): New function, skips over
+ CLASS_VALUE.
+ * decl.c (struct binding_level): Lose overloads_shadowed field.
+ (poplevel): Don't deal with overloads_shadowed.
+ (push_overloaded_decl): Do lexical hiding for functions.
+ * class.c (instantiate_type): Don't check non-members if we have
+ members with the same name.
+ * call.c (build_method_call): Use lookup_name_nonclass instead of
+ IDENTIFIER_GLOBAL_VALUE to check for non-member functions.
+ (build_overload_call_real): Likewise.
+
+ * decl.c (duplicate_decls): Check for ambiguous overloads here.
+ (push_overloaded_decl): Instead of here.
+
+ * decl.c (pushdecl): Back out Chip's last change.
+
+ * decl.c (grok_op_properties): Operators cannot be static members.
+
+ * cp-tree.h (DECL_SYNTHESIZED): DECL_SOURCE_LINE == 0
+ (SET_DECL_SYNTHESIZED): DECL_SOURCE_LINE = 0
+ * lex.c (cons_up_default_function): Use SET_DECL_SYNTHESIZED.
+
+ * method.c (do_inline_function_hair): Don't put friends of local
+ classes into global scope, either.
+
+ * typeck2.c (build_functional_cast): Don't look for a function call
+ interpretation.
+
+Thu Apr 28 15:19:46 1994 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h: Disable use of backend EH.
+
+Wed Apr 27 21:01:24 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * Make-lang.in (c++.distdir): mkdir tmp/cp first.
+ * Makefile.in (INCLUDES): Move definition to same place as
+ parent makefile.
+ (ALLOCA): Define.
+ (OLDAR_FLAGS): Delete.
+ (OLDCC): Define.
+ (DIR): Delete.
+ (CLIB): Define.
+ (####site): Delete.
+ (SUBDIR_USE_ALLOCA): Don't use ALLOCA if compiling with gcc.
+
+Wed Apr 27 19:10:04 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * decl.c (xref_tag): Not to use strstr(), it's not available on
+ all platforms.
+
+Wed Apr 27 18:10:12 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Resolve yet another class/pmf confusion.
+
+ * call.c (build_overload_call_real): Don't take the single-function
+ shortcut if we're dealing with an overloaded operator.
+
+Wed Apr 27 17:35:37 1994 Mike Stump <mrs@cygnus.com>
+
+ * search.c (get_base_distance): Search the virtual base class
+ binfos, incase someone wants to convert to a real virtual base
+ class.
+ * search.c (expand_indirect_vtbls_init): Use convert_pointer_to_real
+ instead of convert_pointer_to, as it now will work.
+
+Wed Apr 27 15:36:49 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): Don't complain about casting away
+ const and volatile.
+
+ * typeck.c (build_unary_op): References are too lvalues.
+
+Wed Apr 27 13:58:05 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (override_one_vtable): We have to prepare_fresh_vtable
+ before we modify it, not after, also, we cannot reuse an old vtable,
+ once we commit to a new vtable. Implement ambiguous overrides in
+ virtual bases as abstract. Hack until we make the class
+ ill-formed.
+
+Wed Apr 27 01:17:08 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (unary_expr): Expand new_placement[opt] and
+ new_initializer[opt] inline.
+
+ * search.c (lookup_fnfields): Don't throw away the inheritance
+ information here, either.
+ (compute_access): Handle static members properly.
+
+ * init.c (build_member_call): Always set basetype_path, and pass it
+ to lookup_fnfields.
+
+ * search.c (lookup_field): Deal properly with the case where
+ xbasetype is a chain of binfos; don't throw away the inheritance
+ information.
+ (compute_access): protected_ok always starts out at 0.
+
+ * init.c (resolve_offset_ref): Don't cast `this' to the base type
+ until we've got our basetype_path.
+
+ * cp-tree.h (IS_OVERLOAD_TYPE): aggregate or enum.
+
+ * cvt.c (build_up_reference): Use build_pointer_type rather than
+ TYPE_POINTER_TO.
+
+ * call.c (convert_harshness_ansi): Call type_promotes_to for reals
+ as well.
+
+ * cvt.c (type_promotes_to): Retain const and volatile, add
+ float->double promotion.
+
+ * decl.c (grokdeclarator): Don't bash references to arrays into
+ references to pointers in function parms. Use type_promotes_to.
+
+Tue Apr 26 23:44:36 1994 Mike Stump <mrs@cygnus.com>
+
+ Finish off Apr 19th work.
+
+ * class.c (finish_struct_bits): Rename has_abstract_virtuals to
+ might_have_abstract_virtuals.
+ * class.c (strictly_overrides, override_one_vtable,
+ merge_overrides): New routines to handle virtual base overrides.
+ * class.c (finish_struct): Call merge_overrides to handle overrides
+ in virtual bases.
+
+Tue Apr 26 12:45:53 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_function_call): Call build_function_call_real with
+ LOOKUP_NORMAL.
+
+ * *: Don't deal with TYPE_EXPRs.
+
+ * tree.c (lvalue_p): If the type of the expression is a reference,
+ it's an lvalue.
+
+ * cvt.c (convert_to_reference): Complain about passing const
+ lvalues to non-const references.
+ (convert_from_reference): Don't arbitrarily throw away const and
+ volatile on the target type.
+
+ * parse.y: Simplify and fix rules for `new'.
+
+ * decl.c (grok_op_properties): operator void is illegal.
+
+Mon Apr 25 02:36:28 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (components): Anonymous bitfields can still have declspecs.
+
+ * decl.c (pushdecl): Postpone handling of function templates like we
+ do C functions.
+
+ * search.c (expand_indirect_vtbls_init): Fix infinite loop when
+ convert_pointer_to fails.
+
+ * call.c (compute_conversion_costs_ansi): A user-defined conversion
+ by itself is better than that UDC followed by standard conversions.
+ Don't treat integers and reals specially.
+
+ * cp-tree.h: Declare flag_ansi.
+
+ * typeck.c (c_expand_return): pedwarn on return in void function
+ even if the expression is of type void.
+ (build_c_cast): Don't do as much checking for casts to void.
+ (build_modify_expr): pedwarn about array assignment if this code
+ wasn't generated by the compiler.
+
+ * tree.c (lvalue_p): A comma expression is an lvalue if its second
+ operand is.
+
+ * typeck.c (default_conversion): Move code for promoting enums and
+ ints from here.
+ * cvt.c (type_promotes_to): To here.
+ * call.c (convert_harshness_ansi): Use type_promotes_to. Also fix
+ promotion semantics for reals.
+
+Sun Apr 24 16:52:51 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * Make-lang.in (c++.install-common): Check for g++-cross.
+ * Makefile.in: Remove Cygnus cruft.
+ (config.status): Delete.
+ (RTL_H): Define.
+ (TREE_H): Use complete pathname, some native makes have minimal
+ VPATH support.
+ (*.o): Use complete pathname to headers in parent dir.
+ (doc, info, dvi): Delete.
+
+Sun Apr 24 16:52:51 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * Make-lang.in (c++.install-common): Check for g++-cross.
+ * Makefile.in: Remove Cygnus cruft.
+ (config.status): Delete.
+ (RTL_H): Define.
+ (TREE_H): Use complete pathname, some native makes have minimal
+ VPATH support.
+ (*.o): Use complete pathname to headers in parent dir.
+ (doc, info, dvi): Delete.
+
+Sun Apr 24 00:47:49 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (pushdecl): Avoid redundant warning on redeclaring function
+ with different return type.
+ (decls_match): Compare return types strictly.
+
+Fri Apr 22 12:55:42 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_type_conversion): Do try to convert through other
+ pointers. This will fail if the class defines multiple pointer
+ conversions.
+
+ * error.c (dump_type_prefix): Print out pointers to arrays properly.
+ (dump_type_suffix): Likewise. (was 'int *[]', now 'int (*)[]')
+
+ * typeck.c (build_unary_op): Disallow ++/-- on pointers to
+ incomplete type.
+
+ * decl.c (duplicate_decls): Check mismatched TREE_CODES after
+ checking for shadowing a builtin. If we're redeclaring a builtin
+ function, bash the old decl to avoid an ambiguous overload.
+
+ * cvt.c (convert_to_reference): Don't force arrays to decay here.
+
+ * tree.c (lvalue_p): A MODIFY_EXPR is an lvalue.
+
+ * decl.c (duplicate_decls): Don't assume that the decls will have
+ types.
+
+ Mon Apr 18 11:35:32 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940318 snapshot ]
+ * c-decl.c (pushdecl): Warn if type mismatch with another external decl
+ in a global scope.
+
+ Fri Apr 22 06:38:56 1994 Chip Salzenberg <chip@fin.uucp>
+
+ * cp/typeck2.c (signature_error): Use cp_error for "%T".
+
+ Mon Apr 18 11:59:59 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940415 snapshot ]
+ * cp/decl.c (duplicate_decls, pushdecl, builtin_function):
+ Use DECL_FUNCTION_CODE instead of DECL_SET_FUNCTION_CODE.
+
+ Mon Apr 18 11:55:18 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940409 snapshot ]
+ * cp/decl.c (duplicate_decls): Put new type in same obstack as
+ old ones, or permanent if old ones in different obstacks.
+
+ Mon Apr 18 11:48:49 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940401 snapshot ]
+ * cp/parse.y (attrib): Handle string args as expressions,
+ merging the two rules. `mode' attribute now takes a string arg.
+ Delete the rule for an identifier as arg.
+
+ Mon Apr 18 11:24:00 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940312 snapshot ]
+ * cp/typeck.c (pointer_int_sum): Multiplication should be done signed.
+ (pointer_diff): Likewise the division.
+
+ Sun Mar 6 19:43:39 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940304 snapshot ]
+ * cp/decl.c (finish_decl): Issue warning for large objects,
+ if requested.
+
+ Sat Feb 19 22:20:32 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940218 snapshot ]
+ * cp/parse.y (attrib): Handle attribute ((section ("string"))).
+ * cp/decl.c (duplicate_decls): Merge section name into new decl.
+
+ Tue Feb 8 09:49:17 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp/* changes propagated from c-* changes in 940206 snapshot ]
+ * cp/typeck.c (signed_or_unsigned_type): Check for any
+ INTEGRAL_TYPE_P not just INTEGER_TYPE.
+
+ Mon Dec 6 13:35:31 1993 Norbert Kiesel <norbert@i3.INformatik.rwth-aachen.DE>
+
+ * cp/decl.c (finish_enum): Start from 0 when determining precision
+ for short enums.
+
+ Fri Dec 3 17:07:58 1993 Ralph Campbell <ralphc@pyramid.COM>
+
+ * cp/parse.y (unary_expr): Look at $1 for tree_code rather than
+ casting $$.
+
+ Wed Nov 17 19:22:09 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp/typeck.c (build_binary_op_nodefault): Propagate code
+ from C front-end to optimize unsigned short division.
+ (build_conditional_expr): Fix bug in "1 ? 42 : (void *) 8".
+
+ Wed Nov 17 19:17:18 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp/call.c (convert_harshness_ansi): Given an (e.g.) char
+ constant, prefer 'const char &' to 'int'.
+
+ Wed Feb 3 13:11:48 1993 Chip Salzenberg <chip@fin.uucp>
+
+ * cp/class.c (finish_struct_methods): Handle multiple
+ constructors in fn_fields list.
+
+Fri Apr 22 12:48:10 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * class.c (finish_struct): Use TYPE_DECL_SUPPRESS_DEBUG to flag
+ types not to be dumped in stabs, like types in #pragma interface.
+ * decl.c (init_decl_processing): Use TYPE_DECL_SUPPRESS_DEBUG to
+ mark unknown type.
+
+Fri Apr 22 03:27:26 1994 Doug Evans <dje@cygnus.com>
+
+ * Language directory reorganization.
+ See parent makefile.
+
+Thu Apr 21 18:27:57 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * cp-tree.h (THUNK_DELTA): It is normally negative, so
+ use signed .i variant of frame_size rather than unsigned .u.
+ * cp-tree.h (VTABLE_NAME_FORMAT): If flag_vtable_thunks,
+ use "VT" rather than "vt" due to binary incompatibility.
+ * class.c (get_vtable_name): Use strlen of VTABLE_NAME_FORMAT,
+ rather than sizeof, since it is now an expression.
+ * class.c (modify_one_vtable): Modify to skip initial element
+ containing a count of the vtable.
+
+Thu Apr 21 00:09:02 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (check_newline): Force interface_unknown on main input file.
+
+ * pt.c (do_pending_expansions): Always emit functions that have been
+ explicitly instantiated.
+ (do_function_instantiation): Set DECL_EXPLICITLY_INSTANTIATED.
+ (do_type_instantiation): Set CLASSTYPE_VTABLE_NEEDS_WRITING and
+ DECL_EXPLICITLY_INSTANTIATED on all my methods.
+ * parse.y (explicit_instantiation): Call do_type_instantiation for
+ types.
+ * decl2.c (finish_vtable_vardecl): Call import_export_vtable.
+ * decl.c (start_function): Don't set DECL_EXTERNAL on a function
+ that has been explicitly instantiated.
+ * cp-tree.h (DECL_EXPLICITLY_INSTANTIATED): Alias for
+ DECL_LANG_FLAG_4.
+ * class.c: Move import_export_vtable to decl2.c, and comment out all
+ uses.
+
+Wed Apr 20 16:51:06 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (process_next_inline): Don't muck with DECL_INLINE.
+ (do_pending_inlines): Likewise.
+
+Tue Apr 19 22:25:41 1994 Mike Stump <mrs@cygnus.com>
+
+ Reimplement vtable building, and most vtable pointer setting.
+ Allows for earier maintenance, easier understandability, and most
+ importantly, correct semantics.
+
+ * class.c (build_vtable): Removed unneeded
+ SET_BINFO_VTABLE_PATH_MARKED.
+ * class.c (prepare_fresh_vtable): Likewise. Added argument.
+ * class.c (modify_vtable_entry): General cleanup.
+ * class.c (related_vslot, is_normal, modify_other_vtable_entries,
+ modify_vtable_entries): Removed.
+ * class.c (add_virtual_function): General cleanup.
+ * class.c (finish_base_struct): Setup BINFO_VTABLE and
+ BINFO_VIRTUALS as early as we can, so that modify_all_vtables can
+ work.
+ * class.c (finish_vtbls): New routine, mostly from
+ unmark_finished_struct.
+ * class.c (overrides): New routine.
+ * class.c (modify_one_vtable): New routine, mostly from
+ modify_other_vtable_entries and modify_vtable_entries.
+ * class.c (modify_all_direct_vtables, modify_all_indirect_vtables,
+ modify_all_vtables): New routines.
+ * class.c (finish_struct): Added arguemnt to prepare_fresh_vtable
+ call. General cleanup on how pending_hard_virtuals are handled.
+ General cleanup on modifying vtables. Use finish_vtbls, instead of
+ unmark_finished_struct.
+ * cp-tree.h (init_vtbl_ptrs, expand_direct_vtbls_init,
+ get_first_matching_virtual, get_matching_virtual,
+ expand_vbase_vtables_init, expand_indirect_vtbls_init): Update.
+ * cvt.c (convert_pointer_to_real): Cleanup error message.
+ * decl.c (grokfndecl): General cleanup.
+ * decl.c (finish_function): Change init_vtbl_ptrs call to
+ expand_direct_vtbls_init. Change expand_vbase_vtables_init call to
+ expand_indirect_vtbls_init.
+ * init.c (expand_virtual_init): Remove unneeded argument.
+ * init.c (init_vtbl_ptrs): Rename to expand_direct_vtbls_init, added
+ two arguments to make more general. Made more general. Now can be
+ used for vtable pointer initialization from virtual bases.
+ * init.c (emit_base_init): Change expand_vbase_vtables_init call to
+ expand_indirect_vtbls_init. Change init_vtbl_ptrs call to
+ expand_direct_vtbls_init.
+ * init.c (expand_virtual_init): General cleanup.
+ * init.c (expand_default_init): Change expand_vbase_vtables_init
+ call to expand_indirect_vtbls_init.
+ * init.c (expand_recursive_init_1): Change expand_vbase_vtables_init
+ call to expand_indirect_vtbls_init.
+ * init.c (expand_recursive_init): Change expand_vbase_vtables_init
+ call to expand_indirect_vtbls_init.
+ * search.c (get_first_matching_virtual): Rename to
+ get_matching_virtual. General cleanup and remove setting of
+ DECL_CONTEXT. That is now done in a cleaner way in
+ modify_vtable_entry and add_virtual_function.
+ * search.c (expand_vbase_vtables_init): Rename to
+ expand_indirect_vtbls_init. General cleanup. Use
+ expand_direct_vtbls_init to do hard work. Ensures that _all_ vtable
+ pointers from virtual bases are set up.
+ * search.c (bfs_unmark_finished_struct, unmark_finished_struct):
+ Removed.
+
+ * *.[chy]: Remove support for VTABLE_USES_MASK.
+
+Tue Apr 19 12:51:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): Use NOP_EXPRs to switch between
+ reference and pointer types instead of bashing the types directly.
+
+ * call.c (build_overload_call_real): Use the TREE_CODE to determine
+ whether the function is overloaded or not, rather than
+ TREE_OVERLOADED.
+ * *: Remove all uses of TREE_OVERLOADED.
+
+ * decl.c (grokdeclarator): Only complain about initializing const
+ fields when -ansi or -pedantic.
+
+Tue Apr 19 12:42:42 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * cp-tree.h (THUNK_DELTA): frame_size is now a union.
+
+Mon Apr 18 00:17:13 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Do overloading on a block-by-block basis, not function-by-function.
+ * decl.c: Lose overloads_to_forget.
+ (struct binding_level): Add overloads_shadowed field.
+ (poplevel): Restore overloads_shadowed.
+ (push_overloaded_decl): Use overloads_shadowed instead of
+ overloads_to_forget.
+ (finish_function): Don't look at overloads_to_forget.
+
+ Copy enum_overflow logic from c-decl.c.
+ * decl.c (start_enum): Initialize enum_overflow.
+ (build_enumerator): Use enum_overflow. Also use current_scope().
+
+ * search.c (current_scope): Move Brendan's comment from
+ build_enumerator here.
+
+ * typeck.c (convert_for_assignment): Change warnings to pedwarns for
+ discarding const/volatile.
+
+Sat Apr 16 01:18:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (comp_target_parms): Accept TEMPLATE_TYPE_PARMs on the rhs.
+ (comp_target_types): Likewise.
+
+ * decl.c (lookup_name): Don't unset got_scope here.
+
+ * spew.c (yylex): Only replace yylval with the TYPE_NESTED_NAME if
+ got_scope != NULL_TREE.
+
+Fri Apr 15 16:36:33 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Horrible kludge to prevent templates from being instantiated by
+ their base classes.
+ * parse.y (template_instantiate_once): Unset TYPE_BEING_DEFINED
+ before we get to left_curly.
+ * pt.c (instantiate_class_template): Set TYPE_BEING_DEFINED.
+
+ * error.c (dump_decl): If it's a typedef, print out the name of the
+ decl, not just the underlying type.
+
+ * decl.c (pushdecl): If the old duplicate decl was a TYPE_DECL,
+ update the IDENTIFIER_TYPE_VALUE of its name.
+
+ * decl2.c (finish_file): When processing the initializer for a
+ static member, pretend that the dummy function is a member of the
+ same class.
+
+Fri Apr 15 15:56:35 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * class.c (build_vtable_entry): Revert Apr 4 change.
+ * decl2.c (mark_vtable_entries): Replace pure virtual function
+ decl with abort's.
+
+Fri Apr 15 13:49:33 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_conditional_expr): Pedwarn on pointer/integer
+ mismatch, and don't pedwarn on 0/function pointer mismatch.
+
+ * typeck2.c (digest_init): Lose code for special handling of unions.
+ (process_init_constructor): Since they're handled just fine here.
+ Pedwarn on excess elements.
+
+ * decl2.c (grokfield): Complain about local class method declaration
+ without definition.
+
+Fri Apr 15 13:19:40 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * method.c (emit_thunk): Add extern declaration for
+ current_call_is_indirect (needed for hppa).
+
+Thu Apr 14 16:12:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Improve local class support; allow classes in different blocks to
+ have the same name.
+ * decl.c (pushtag): Support local classes better.
+ (pushdecl_nonclass_level): New function for pushing mangled decls of
+ nested types into the appropriate scope.
+ (xref_defn_tag): Use pushdecl_nonclass_level instead of
+ pushdecl_top_level.
+ (grokfndecl): Don't mess with IDENTIFIER_GLOBAL_VALUE for local
+ class methods.
+ * method.c (do_inline_function_hair): Likewise.
+
+ * class.c (finish_struct): It is legal for a class with no
+ constructors to have nonstatic const and reference members.
+
+Thu Apr 14 07:15:11 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (push_overloaded_decl): Avoid giving errors about
+ built-ins, since duplicate_decls will have given warnings/errors
+ for them.
+
+Thu Apr 14 03:45:12 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): Warn about casting pointer type to
+ reference type when this is probably not what they wanted.
+
+Wed Apr 13 13:12:35 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (finish_decl): Don't mindlessly set TREE_USED for
+ static consts any more (toplev.c has now been modified to
+ not emit warnings if they are unused).
+
+Wed Apr 13 00:22:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_op_properties): If op new/delete get here with
+ METHOD_TYPEs, do a revert_static_member_fn.
+
+ * cp-tree.h (IDENTIFIER_CLASS_TYPE_VALUE): Lose.
+ * init.c (is_aggr_typedef): Don't look at
+ IDENTIFIER_CLASS_TYPE_VALUE.
+ (get_aggr_from_typedef): Likewise.
+ (get_type_value): Likewise.
+ * call.c (build_scoped_method_call): Don't rely on overloaded
+ template names having IDENTIFIER_CLASS_VALUE set.
+
+ * parse.y (component_decl_1, fn.def2): Revert rules for
+ constructors.
+ (component_decl_1, fn.def2): Use $1 instead of $$, since $$ is being
+ clobbered.
+
+ * decl.c (start_function): Only warn about `void main()' if pedantic
+ || warn_return_type.
+
+Tue Apr 12 02:14:17 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Clean up overloading of the template name.
+ * class.c (pushclass): Overload the template name whenever pushing
+ into the scope of a template class, not just if it is
+ uninstantiated.
+ (popclass): Correspondingly.
+ * search.c (push_class_decls): Don't overload_template_name.
+ * pt.c (overload_template_name): Don't set IDENTIFIER_LOCAL_VALUE or
+ DECL_CONTEXT on things.
+ * parse.y (left_curly): Don't overload_template_name.
+ * class.c (finish_struct): Don't undo_template_name_overload.
+
+ * method.c (build_opfncall): Only pass one argument to global op
+ delete.
+
+ * call.c (build_method_call): Use TYPE_VEC_DELETE_TAKES_SIZE to
+ decide how many arguments to use for vec delete.
+
+ * decl.c (grok_op_properties): Be consistent in modifying
+ current_class_type.
+ (grokdeclarator): Only complain about function decls with no return
+ type if we're being pedantic.
+
+Mon Apr 11 00:10:53 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ Add support for operator new [] and operator delete [].
+
+ * tree.def: Add VEC_NEW_EXPR and VEC_DELETE_EXPR.
+ * ptree.c (print_lang_type): Indicate vec new/delete.
+ * parse.y: Support vec new/delete.
+ * method.c (build_decl_overload): Deal with vec new/delete.
+ (build_opfncall): Likewise.
+ * lex.c (init_lex): Set up values of ansi_opname and opname_tab for
+ vec new/delete. vec new uses "__vn", and vec delete uses "__vd".
+ * init.c (init_init_processing): Set up BIVN and BIVD.
+ (do_friend): Don't clean up after mistaken setting of TREE_GETS_NEW,
+ since it doesn't happen any more.
+ (build_new): Support vec new. Always call something.
+ (build_x_delete): Support vec delete.
+ (build_vec_delete): Lose dtor_dummy argument, add use_global_delete,
+ and pass it to build_x_delete.
+ * decl2.c (delete_sanity): Don't change behavior by whether or not
+ the type has a destructor. Pass use_global_delete to
+ build_vec_delete.
+ (coerce_delete_type): Make sure that the type returned has a first
+ argument of ptr_type_node.
+ * decl.c (init_decl_processing): Also declare the global vec
+ new/delete.
+ (grokdeclarator): Also force vec new/delete to be static.
+ (grok_op_properties): Note presence of vec new/delete, and play with
+ their args. If vec delete takes the optional size_t argument, set
+ TYPE_VEC_DELETE_TAKES_SIZE.
+ * cp-tree.h (TYPE_GETS_{REG,VEC}_DELETE): New macros to simplify
+ checking for one delete or the other.
+ (lang_type): gets_new and gets_delete are now two bits long. The
+ low bit is for the non-array version. Lose gets_placed_new.
+ (TYPE_VEC_DELETE_TAKES_SIZE): New macro indicating that the vec
+ delete defined by this class wants to know how much space it is
+ deleting.
+ (TYPE_VEC_NEW_USES_COOKIE): New macro to indicate when vec new must
+ add a header containing the number of elements in the vector; i.e.
+ when the elements need to be destroyed or vec delete wants to know
+ the size.
+ * class.c (finish_struct_methods): Also check for overloading vec
+ delete.
+ * call.c (build_method_call): Also delete second argument for vec
+ delete.
+
+ * decl.c (grokdeclarator): Correct complaints again.
+ (grokdeclarator): Fix segfault on null declarator.
+ (decls_match): Also accept redeclaration with no arguments if both
+ declarations were in C context. Bash TREE_TYPE (newdecl) here.
+ (duplicate_decls): Instead of here.
+
+ * parse.y (nested_name_specifier_1): Lose rules for dealing with
+ syntax errors nicely, since they break parsing of 'const i;'.
+
+ * decl.c (lookup_name): if (got_scope == current_class_type)
+ val = IDENTIFIER_CLASS_VALUE (name).
+
+ * search.c (lookup_nested_tag): Look in enclosing classes, too.
+
+ * spew.c (yylex): Only look one character ahead when checking for a
+ SCOPE.
+
+ * lex.c (check_newline): Read first nonwhite char before
+ incrementing lineno.
+
+ * decl.c (grokdeclarator): Don't claim that typedefs are variables
+ in warning.
+
+ * parse.y: Divide up uses of unqualified_id into
+ notype_unqualified_id and unqualified_id, so that TYPENAME can be
+ used as an identifier after an object.
+
+ * class.c (push_nested_class): Don't push into non-class scope.
+
+ * decl.c (grokdeclarator): If an identifier could be a type
+ conversion operator, but has no associated type, it's not a type
+ conversion operator.
+
+ * pt.c (unify): Check for equality of constants better.
+
+ * decl.c (grokdeclarator): Don't complain about access decls.
+
+Sun Apr 10 02:39:55 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): pedwarn about data definitions without
+ types here.
+
+ * parse.y (datadef): Don't pedwarn about decls without types here,
+ since that is valid for functions.
+ (fn.def2, component_decl): Support constructors with declmods again.
+ (nomods_initdecls): For decls without any mods, so that we don't try
+ to get declspecs from some arbitrary $0.
+
+ * search.c (lookup_field): Use cp_error.
+
+ * parse.y (nested_name_specifier_1): Don't check aggr/non-aggr type
+ here; it breaks destructors for non-aggr types.
+
+ * decl.c (lookup_name): Only look for TYPE_DECLs in base classes of
+ a type being defined, like the comment says.
+ If got_scope is not an aggregate, just return NULL_TREE.
+
+ * pt.c (create_nested_upt): Kung's code for creating types nested
+ within uninstantiated templates now lives here (it used to live in
+ hack_more_ids). It needs to be expanded.
+
+ * parse.y: Stop calling see_typename so much.
+
+ * decl.c (lookup_name): Deal with TTPs and UPTs.
+
+ * lex.c (real_yylex): Don't set looking_for_typename just because we
+ saw a 'new'.
+ (dont_see_typename): #if 0 out.
+
+ * spew.c (yylex): Increment looking_for_typename if the next
+ character is SCOPE, rather than setting it to 1; this way, the value
+ from seeing an aggr specifier will not be lost. This kinda relies
+ on looking_for_typename never being < 0, which is now true.
+
+ * parse.y (nested_name_specifier_1): Accept TEMPLATE_TYPE_PARMs,
+ too.
+ (named_class_head_sans_basetype): Accept template types, too. Oops.
+
+Fri Apr 8 16:39:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (reparse_decl_as_expr1): Handle SCOPE_REFs.
+
+ * parse.y: Lose START_DECLARATOR.
+
+ * search.c (lookup_nested_tag): New function to scan CLASSTYPE_TAGS
+ for a class.
+
+ * parse.y: Simplify fn.def2 and component_decl. Support 'enum
+ A::foo' syntax. Catch invalid scopes better.
+
+ * parse.y, lex.c: Lose TYPENAME_COLON.
+
+ * decl2.c (groktypefield): #if 0 out.
+
+ * decl.c (lookup_name): If the type denoted by got_scope is
+ currently being defined, look in CLASSTYPE_TAGS rather than FIELDS.
+
+ * class.c (push_nested_class): Don't try to push into
+ error_mark_node.
+
+Fri Apr 8 07:26:36 1994 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Makefile.in (stamp-parse): Update count of conflicts to 33.
+
+Thu Apr 7 17:47:53 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ A saner implementation of nested types that treats template types
+ no differently from non-template types. There are still some
+ shortcomings of our system; most notably, it is difficult to look
+ for a nested type that is hidden by another name, because of the way
+ we keep track of hidden types. But this shouldn't be a problem for
+ just about anyone. Perhaps lookup_field should be fixed up a bit.
+
+ * spew.c: Moved handling of nested types/scoping from the lexer
+ into the parser. Removed variable template_type_seen_before_scope.
+ Removed functions frob_identifier, hack_more_ids, and various cruft
+ that was #if 0'd out in the past, reducing the size of the file from
+ 1146 lines to 450 lines. We can't quite do away with spew.c yet,
+ though; we still need it for do_aggr () and checking for SCOPE after
+ the current identifier. And setting lastiddecl.
+
+ * parse.y: Moved handling of nested types/scoping from the lexer
+ into the parser, using a new global variable `got_scope'. Reduced
+ the number of states by 53. Implemented all uses of explicit global
+ scope. Removed terminals SCOPED_TYPENAME and SCOPED_NAME. Removed
+ nonterminals tmpl.1, scoped_base_class, id_scope, typename_scope,
+ scoped_typename. Added nonterminals nested_type,
+ qualified_type_name, complete_type_name, qualified_id, ptr_to_mem,
+ nested_name_specifier, global_scope, overqualified_id, type_name.
+ Changed many others. Added 9 new reduce/reduce conflicts, which are
+ nested type parallels of 9 that were already in the grammar for
+ non-nested types. Eight of the now 33 conflicts should be removed
+ in the process of resolving the late binding between variable and
+ function decls.
+
+ * gxxint.texi (Parser): Update.
+
+ * cp-tree.h (IS_AGGR_TYPE_CODE): Add UNINSTANTIATED_P_TYPE.
+
+ * lex.h: Add decl for got_scope.
+
+ * lex.c (see_typename): Claim to be the lexer when calling
+ lookup_name.
+
+ * decl.c (lookup_name): When called from the lexer, look at
+ got_scope and looking_at_typename; otherwise don't.
+
+Thu Apr 7 22:05:47 1994 Mike Stump <mrs@cygnus.com>
+
+ 31th Cygnus<->FSF merge.
+
+Thu Apr 7 17:47:53 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (mark_vtable_entries): Call this to mark all the
+ entries in the vtable addressable.
+ (finish_decl_parsing): Handle SCOPE_REFs.
+
+ * decl.c (decls_match): Always call compparms with strict == 1.
+ Handle the special case of C function redecl here.
+ (duplicate_decls): Only keep the old type if the new decl takes no
+ arguments.
+
+ * typeck.c (compparms): Also allow t1 to be ... if strict == 0.
+
+Thu Apr 7 16:17:50 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (build_vtable_entry): Fix breakage introduced Apr 5
+ 17:48:41.
+
+Wed Apr 6 16:05:10 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * init.c (build_virtual_init), search.c (build_vbase_vtables_init),
+ ch-tree.h: Every place these functions were called, the result was
+ immediately passed to expand_expr_stmt. Reduce redundancy by
+ calling expand_expr_init *inside* these functions. These
+ makes for a simpler interface, and we don't have to build
+ compound expressions. Hence, rename these function to:
+ expand_virtual_init and expand_vbase_vtables_init respectively.
+ * init.c, decl.c: Change callers of these functions.
+ * init.c, cp-tree.h (expand_virtual_init): Make static.
+
+ * decl2.c (finish_file): Check TREE_PUBLIC||TREE_ADDRESSABLE
+ rather than DECL_SAVED_INSNS before emitting inlines.
+
+Wed Apr 6 13:06:39 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * spew.c (init_spew): #if 0 out stuff used by arbitrate_lookup.
+
+ * decl.c (duplicate_decls): If this is a new declaration of an
+ extern "C" function, keep the type (for the argtypes).
+ (redeclaration_error_message): Don't check DECL_LANGUAGE here.
+ (decls_match): Call compparms with a value of strict dependent on
+ the value of strict_prototypes for DECL_LANGUAGE (oldecl).
+
+ * typeck.c (compparms): ... is only equivalent to non-promoting
+ parms if we're not being strict.
+
+ * parse.y (empty_parms): Don't check flag_ansi || pedantic here.
+
+ * decl.c (init_decl_processing): if (flag_ansi || pedantic)
+ strict_prototypes_lang_c = strict_prototypes_lang_cplusplus;
+
+ * decl2.c (grok_function_init): Don't set DECL_INITIAL on pure
+ virtuals.
+
+Tue Apr 5 17:48:41 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ Support for implementing vtables with thunks.
+ * tree.def (THUNK_DECL): New TREE_CODE.
+ * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY), tree.c
+ (fnaddr_from_vtable_entry): Handle flag_vtable_thunks case.
+ * cp-tree.h (memptr_type): New variable.
+ * class.c (build_vtable_entry): Build thunk if necessary.
+ * class.c (build_vfn_ref): If using thunks, don't need
+ to add delta field from vtable (there is none!).
+ * decl.c: Add memptr_type as well as vtable_entry_type.
+ If using thunks, the latter is just ptr_type_node.
+ * gc.c, typeck.c: Use memptr_typeChange, not vtable_entry_type.
+ * decl2.c (finish_vtable_vardecl): Handle thunks.
+ * expr.c (cplus_expand_expr): Support THUNK_DECL.
+
+ * decl.c (grokdeclarator): Set DECL_THIS_EXTERN if "extern".
+ * decl.c (start_function): Set current_extern_inline based on
+ DECL_THIS_EXTERN, not TREE_PUBLIC.
+ * decl.c (finish_function): Call mark_inline_for_output if needed,
+
+ Improve intelligence about when to emit inlines.
+ * cp-tree.h (lang_decl_flags): New field saved_inline.
+ * cp-tree.h (DECL_SAVED_INLINE): New macro.
+ * class.c (add_virtual_function): Don't set TREE_ADDRESSABLE.
+ * decl.h, decl.c (pending_addressable_inlines): Removed.
+ * decl2.c (pending_addressable_inlines): Renamed to saved_inlines.
+ * decl2.c (mark_inline_for_output): Do nothing if
+ DECL_SAVED_INLINE; otherwise set it (and add to saved_inlines list).
+ * decl2.c (finish_vtable_vardecl): SET_CLASSTYPE_INTERFACE_KNOWN
+ and set CLASSTYPE_INTERFACE_ONLY if there is a non-inline virtual.
+ * decl2.c (finish_file): Writing out inlines later, so we can
+ also handle the ones needed for vtbales.
+ * decl2.c (write_vtable_entries, finish_vtable_typedecl): Removed.
+
+ * cp-tree.h, class.c, decl2.c, search.c: Remove -fvtable-hack
+ and flag_vtable_hack. Use -fvtable-thunks and flag_vtable_thunks
+ instead. (The rationale is that these optimizations both break binary
+ compatibility, but should become the default in a future release.)
+
+Wed Apr 6 10:53:56 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (modify_vtable_entries): Never reset the DECL_CONTEXT
+ of a fndecl, as we might not be from that vfield.
+
+Tue Apr 5 17:43:35 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * class.c (add_virtual_function): Fix bug for pure virtual, so
+ that DECL_VINDEX of the dummy decl copied won't be error.
+ (see also Apr 4 change)
+
+Tue Apr 5 17:23:45 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * typeck.c (c_expand_return): Before checking that we're not
+ returning the address of a local, make sure it's a VAR_DECL.
+ (And don't worry about it being a TREE_LIST.)
+
+Tue Apr 5 13:26:42 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (YYDEBUG): Always define.
+ * lex.c (YYDEBUG): Likewise.
+
+Mon Apr 4 11:28:17 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * class.c (finish_struct): Backup out the change below, put the
+ new change for the same purpose. The change below breaks code.
+
+ * class.c (finish_struct): If pure virtual, copy node and make
+ RTL point to abort, then put in virtual table.
+ * decl2.c (grok_function_iit): Reinstate Mar 31 change.
+
+Sat Apr 2 03:12:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_new): pedwarn about newing const and volatile
+ types.
+
+ * tree.c (get_identifier_list): Only do the special handling
+ thing if we're dealing with the main variant of the record type.
+
+ * cvt.c (convert_to_reference): When converting between
+ compatible reference types, use the pointer conversion machinery.
+ Don't just blindly overwrite the old type.
+
+Fri Apr 1 17:14:42 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): When looking at global functions,
+ be sure to use instance_ptr for the first argument, not some version
+ of it that has been cast to a base class. Also do this before
+ comparing candidates.
+
+Thu Mar 31 19:50:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Constructors can be called for
+ const objects.
+
+Thu Mar 31 16:20:16 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * decl2.c (grok_func_init): Do not abort as rtl for pur virtual
+ functions. They can be defined somewhere else.
+
+Sat Jan 23 23:23:26 1994 Stephen R. van den Berg <berg@pool.informatik.rwth-aachen.de>
+
+ * decl.c (init_decl_processing): Declare __builtin_return_address
+ and __builtin_frame_address for C++ as well.
+
+Thu Mar 31 12:35:49 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck2.c (store_init_value): Integral constant variables are
+ always constant, even when doing -fpic.
+
+Sat Jan 23 23:23:26 1994 Stephen R. van den Berg <berg@pool.informatik.rwth-aachen.de>
+
+ * decl.c (redeclaration_error_message): Pass the types to
+ comptypes.
+
+Wed Mar 30 21:29:25 1994 Mike Stump <mrs@cygnus.com>
+
+ Cures incorrect errors about pure virtuals in a class, when they
+ have been overridden in a derived class.
+
+ * search.c (get_abstract_virtuals): Reimplement.
+ * search.c (get_abstract_virtuals_1): New routine.
+
+Wed Mar 30 14:10:04 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (push_template_decls): Make the pushed level pseudo
+ global.
+
+ * parse.y (extdefs): Don't pop everything if the current binding
+ level is pseudo_global.
+
+ * decl.c (pop_everything): Stop on reaching a pseudo-global
+ binding level.
+
+ * cp-tree.h (DECL_FUNCTION_MEMBER_P): Change to more reliable test.
+
+ * decl.c (duplicate_decls): Only copy DECL_SOURCE_{FILE_LINE} if
+ the old decl actually had an initializer.
+
+ * {various}: Clean up gcc -W complaints.
+
+ * cp-tree.h (DECL_FUNCTION_MEMBER_P): Currently defined to be
+ (DECL_CONTEXT (NODE) != NULL_TREE).
+
+ * parse.y (lang_extdef): Call pop_everything if necessary.
+
+ * decl.c (pop_everything): New function for popping binding
+ levels left over after a syntax error.
+ (pushdecl): Use DECL_FUNCTION_MEMBER_P to decide whether or not
+ a function is a member.
+
+Wed Mar 30 14:20:50 1994 Mike Stump <mrs@cygnus.com>
+
+ Cures calling a more base base class function, when a more derived
+ base class member should be called in some MI situations.
+
+ * search.c (make_binfo): Use more the more specialized base
+ binfos from the binfo given as the second argument to make_binfo,
+ instead of the unspecialized ones from the TYPE_BINFO.
+ * class.c (finish_base_struct): Likewise, update callers.
+ * search.c (dfs_get_vbase_types): Likewise.
+ * tree.c (propagate_binfo_offsets, layout_vbasetypes): Likewise.
+ * decl.c (xref_tag): Use NULL_TREE instead of 0.
+ * lex.c (make_lang_type): Likewise.
+
+Wed Mar 30 14:10:04 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (pushdecl): If pushing a C-linkage function, only do a
+ push_overloaded_decl.
+ (duplicate_decls): Standard overloading does not shadow built-ins.
+
+Tue Mar 29 00:54:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (end_template_decl): Don't call push_overloaded_decl.
+
+ * init.c (do_friend): Don't call push_overloaded_decl.
+
+ * decl.c (pushdecl): Call push_overloaded_decl for functions and
+ function templates.
+ (duplicate_decls): Functions and function templates are not
+ duplicates, but don't complain about calling this function to
+ compare them.
+ (push_overloaded_decl): Don't deal with linkage. Call
+ duplicate_decls.
+ (redeclaration_error_message): Deal with linkage.
+
+ * decl.c (start_function): If push_overloaded_decl returns an
+ older version of the function, deal with it.
+
+ * decl.c (start_function): Be sure only to push_overloaded_decl
+ for non-members.
+
+ * decl.c (grokfndecl): Put back clearing of DECL_CHAIN for
+ methods.
+ (start_function): Lose broken and redundant code for checking old
+ decl.
+
+ * init.c (add_friend): Give line numbers of both friend decls
+ when warning about re-friending.
+
+ * pt.c (tsubst): Use comptypes rather than == to compare the
+ types of the method as declared and as defined, since default
+ parameters may be different.
+
+ * call.c (build_method_call): Use brendan's candidate printing
+ routine.
+
+ * decl.c (start_method): Methods defined in the class body are
+ inline whether or not it's a template class.
+
+Mon Mar 28 16:39:26 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (initdcl0): Add "extern" to current_declspecs if
+ have_extern_spec && ! used_extern_spcec.
+
+ * tree.c (really_overloaded_fn): A fn with more than one
+ overload.
+
+ * pt.c (end_template_decl): Use really_overloaded_fn.
+
+ * decl.c (duplicate_decls): When smashing a decl into a previous
+ definition, keep the old file and line.
+ Don't deal with overloaded functions.
+ Lose old code for checking arg types of functions.
+ Check for overloaded C functions.
+ (pushdecl): Deal with overloaded functions.
+ (start_decl): Expect pushdecl to return an appropriate function decl.
+ (start_function): Likewise.
+ (push_overloaded_decl): Don't check for overloaded C functions.
+
+ * *.c: Stop using DECL_OVERLOADED, it being archaic.
+ TREE_OVERLOADED should probably go, too.
+
+Mon Mar 28 14:00:45 1994 Ron Guilmette <rfg@netcom.com>
+
+ * typeck.c (comp_target_types): Call comp_target_parms with
+ strict == 1.
+
+Sun Mar 27 00:07:45 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (empty_parms): Don't parse () as (...) in extern "C"
+ sections if we're compiling with -ansi or -pedantic.
+
+ * decl.c (decls_match): Don't treat (int) and (int&) as matching.
+
+ * decl2.c (grokfield): Don't pedwarn twice about initializing
+ field.
+
+ * decl.c (push_overloaded_decl): Warn about shadowing
+ constructor.
+ (redeclaration_error_message): Don't allow 'int a; int a;'
+
+ * cvt.c (build_up_reference): Only check for valid upcast if
+ LOOKUP_PROTECT is set, not just any flag.
+
+Fri Mar 25 01:22:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (check_newline): When we see a #pragma implementation,
+ also set it for the main input file.
+
+ * init.c (build_new): Convert array size argument to size_t.
+
+ * parse.y (primary): If we're doing a parenthesized type-id, call
+ groktypename before passing it to build_new.
+
+ * call.c (build_method_call): Deal properly with const and
+ volatile for instances of reference type.
+
+ * decl.c (store_return_init): Change 'if (pedantic) error' to 'if
+ (pedantic) pedwarn'.
+
+ * decl.c (grokdeclarator): Don't complain about putting `static'
+ and `inline' on template function decls.
+
+Thu Mar 24 23:18:19 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Preserve const & volatile on
+ `this'.
+
+Thu Mar 24 16:21:52 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (build_new, build_vec_delete): Use global new and delete
+ for arrays.
+ * decl2.c (delete_sanity): Likewise.
+
+Thu Mar 24 02:10:46 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): If i is an lvalue,
+ (int &)i -> *(int*)&i, as per 5.2.8p9 of the latest WP.
+ (convert_force): Call convert_to_reference with LOOKUP_COMPLAIN.
+
+Wed Mar 23 17:45:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (duplicate_decls): Also propagate DECL_TEMPLATE_MEMBERS
+ and DECL_TEMPLATE_INSTANTIATIONS.
+
+ * init.c (build_new): Handle array typedefs properly.
+
+Wed Mar 23 18:23:33 1994 Mike Stump <mrs@cygnus.com>
+
+ 30th Cygnus<->FSF merge.
+
+Wed Mar 23 00:46:24 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (modify_vtable_entries): Avoid running off the end of the
+ virtuals list when processing a virtual destructor.
+ * class.c (get_vtable_entry): Likewise.
+
+Wed Mar 23 00:23:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (duplicate_decls): If two template decls don't match,
+ just return 0.
+
+Tue Mar 22 23:49:41 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (convert_for_assignment): Don't pedwarn about
+ converting function pointer to void *.
+
+Tue Mar 22 22:23:19 1994 Mike Stump <mrs@cygnus.com>
+
+ Major revamp of pointer to member functions. Cures major
+ nonfunctionality when used in casts, and MI situations.
+
+ * cvt.c (convert_force): Update call site of build_ptrmemfunc.
+ * typeck.c (convert_for_assignment): Likewise.
+ * typeck2.c (digest_init): Likewise.
+ * typeck2.c (process_init_constructor): Simplify by moving code into
+ digest_init.
+ * typeck2.c (digest_init): Do default_conversions on init value, if
+ we are processing pointer to member functions.
+ * class.c (get_vfield_offset): Now non-static. Convert bit offset
+ into byte offset.
+ * cp-tree.h (get_vfield_offset): Likewise.
+ * typeck.c (get_member_function_from_ptrfunc): Convert down to right
+ instance, before fetching vtable pointer.
+ * typeck.c (get_delta_difference): New routine.
+ * typeck.c (build_ptrmemfunc): Revamp to handle casting better, also
+ get vtable pointer out of right subobject.
+
+Tue Mar 22 17:56:48 1994 Mike Stump <mrs@cygnus.com>
+
+ * search.c (get_binfo): Return NULL instead of aborting, when
+ passed a UNION_TYPE.
+
+Tue Mar 22 12:44:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ These patches implement handling of redefinition/redeclaration of
+ templates.
+
+ * typeck.c (comptypes): Simplify. All TEMPLATE_TYPE_PARMs are
+ considered compatible.
+
+ * parse.y (template_def): Pass defn argument to end_template_decl.
+
+ * pt.c (end_template_decl): Add defn argument. Check for
+ redefinition. Simplify.
+
+ * error.c (OB_UNPUT): New macro, to remove mistakes.
+ (aggr_variety): Subroutine of dump_aggr_type.
+
+ * decl.c (decls_match): Support templates.
+ (duplicate_decls): No longer static. Don't try to lay out template
+ decls.
+ (pushdecl): Simplify.
+
+ * cp-tree.h (DECL_TEMPLATE_MEMBERS): Use DECL_SIZE instead of
+ DECL_INITIAL.
+
+Mon Mar 21 11:46:55 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_decl): Support class template decls.
+ (dump_type): Don't adorn template type parms.
+
+ * decl.c (duplicate_decls): Save DECL_TEMPLATE_INFO from old decl
+ if it was a definition.
+ (redeclaration_error_message): Do the cp_error thang, and reject
+ redefinition of templates.
+
+Mon Mar 21 19:36:06 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (grokdeclarator): Set TREE_PUBLIC for METHOD_TYPE
+ in FIELD context, when appropriate. Also,
+ CLASSTYPE_INTERFACE_ONLY is irrelevant to setting TREE_PUBLIC.
+ Also, simplify check for bogus return specifiers.
+
+Mon Mar 21 11:46:55 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (after_type_declarator1): Expand type_quals.
+ (notype_declarator1): Likewise.
+ (absdcl1): Likewise.
+
+Sat Mar 19 01:05:17 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Treat class-local typedefs like static
+ members; i.e. 'typedef int f();' means that f is a function type,
+ not a method type.
+
+ * parse.y (decl): Change direct_* back to *.
+ (type_id): Change direct_abstract_declarator to absdcl.
+ (direct_declarator, direct_initdecls, direct_initdcl0): Remove again.
+
+Fri Mar 18 12:47:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ These two patches fix crashes on instantiating a template inside a
+ function with C linkage or containing labels.
+
+ * class.c (current_lang_stacksize): No longer static.
+
+ * decl.c (struct saved_scope): Add lang_base, lang_stack,
+ lang_name, lang_stacksize, and named_labels.
+ (push_to_top_level): Save them.
+ (pop_from_top_level): Restore them.
+
+ * gxxint.texi (Parser): Update.
+
+ These two patches finish moving the task of expr/declarator
+ ambiguity resolution from the lexer to the parser, and add one more
+ r/r conflict. START_DECLARATOR can now be nuked.
+
+ * parse.y (decl): Add "direct_" in typespec X rules.
+ (direct_declarator): New nonterminal for
+ direct_after_type_declarator and direct_notype_declarator.
+ (direct_initdecls): Like initdecls, but uses direct_initdcl0.
+ (direct_initdcl0): Like initdcl0, but uses direct_declarator.
+ (named_parm): Add typespec direct_declarator rule.
+
+ * spew.c (yylex): #if 0 out START_DECLARATOR insertion.
+
+ These two patches disable some excessive cleverness on the part of
+ g++; a non-class declaration always hides a class declaration in the
+ same scope, and g++ was trying to unhide it depending on the
+ enclosing expression.
+
+ * spew.c (arbitrate_lookup): #if 0 out.
+
+ * decl.c (lookup_name): Never call arbitrate_lookup.
+
+ * parse.y (complex_notype_declarator1): Add '*'
+ complex_notype_declarator1 and '&' complex_notype_declarator1 rules.
+
+ * parse.y (complex_direct_notype_declarator): Restore id_scope
+ see_typename TYPENAME rule, remove all other rules beginning with
+ those tokens.
+ (notype_unqualified_id): Add '~' see_typename IDENTIFIER rule.
+
+Thu Mar 17 17:30:01 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ These changes fix the compiler's handling of the functional cast/
+ object declaration ambiguities in section 6.8 of the ARM. They also
+ add 11 reduce/reduce conflicts. Sigh.
+
+ * parse.y: Add precedence decls for OPERATOR and '~'.
+ (notype_unqualified_id): New nonterminal, encompasses all of the
+ ANSI unqualified-id nonterminal except TYPENAMEs.
+ (expr_or_declarator): New nonterminal to delay parsing of code like
+ `int (*a)'.
+ (primary): Use notype_unqualified_id.
+ (decl): Add typespec initdecls ';' and typespec declarator ';'
+ rules.
+ (initdcl0): Deal with the above.
+ (complex_notype_declarator1): A notype_declarator that is not also
+ an expr_or_declarator.
+ (complex_direct_notype_declarator): A direct_notype_declarator that
+ doesn't conflict with expr_or_declarator. Use
+ notype_unqualified_id. Remove id_scope see_typename TYPENAME rule.
+ (functional_cast): New nonterminal, for the three functional cast
+ rules. So that they can be moved after
+ complex_direct_notype_declarator.
+ (see_typename): Don't accept type_quals any more.
+
+ * decl2.c (reparse_decl_as_expr): New function to deal with parse
+ nodes for code like `int (*a)++;'.
+ (reparse_decl_as_expr1): Recursive subroutine of the above.
+ (finish_decl_parsing): New function to deal with parse nodes for
+ code like `int (*a);'. See the difference?
+
+Thu Mar 17 12:16:10 1994 Mike Stump <mrs@cygnus.com>
+
+ These changes break binary compatibility in code with classes
+ that use virtual bases.
+
+ * search.c (dfs_get_vbase_types): Simplify and correct to make
+ sure virtual bases are initialized in dfs ordering.
+ * search.c (get_vbase_types): Simplify and make readable.
+
+Thu Mar 17 12:01:10 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y: s/ typename / type_id /g
+
+Wed Mar 16 17:42:52 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * parse.y (typespec): Add SCOPE TYPENAME for global scoped
+ type. e.g. ::B x.
+
+ * decl.c (complete_array_type): Fix a bug that in -pendantic
+ mode even there's no initializer, it will continue to build
+ default index.
+
+Wed Mar 16 17:43:07 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (direct_notype_declarator): Add PTYPENAME rule, remove
+ all of the scoped PTYPENAME rules.
+
+Wed Mar 16 16:39:02 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (build_offset_ref): The value of A::typedef_name is
+ always the TYPE_DECL, and never an error.
+
+Tue Mar 15 20:02:35 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (get_base_distance_recursive): Two binfos can only
+ represent the same object if they are both via_virtual.
+
+ * class.c (finish_base_struct): Check vbases for ambiguity, too.
+
+ * search.c (get_vbase_types): Accept binfo argument, too.
+
+Tue Mar 15 19:22:05 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * decl.c (complete_array_type): Complete TYPE_DOMAIN of the
+ initializer also, because back-end requires it.
+
+Tue Mar 15 15:33:31 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_expr): Support member functions (which show up as
+ OFFSET_REFs).
+
+Mon Mar 14 16:24:36 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (build_new): Set the return type of multidimensional
+ news correctly.
+
+Fri Mar 11 15:35:39 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * call.c (build_method_call): If basetype not equal to type
+ of the instance, use the type of the instance in building
+ destructor.
+
+Thu Mar 10 17:07:10 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * parse.y (direct_notype_declarator): Add push_nested_type for
+ 'template_type SCOPED_NAME' rule.
+
+Tue Mar 8 00:19:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (parm): Add typed_declspec1 {absdcl, epsilon} rules.
+
+Sat Mar 5 04:47:48 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (regcast_or_absdcl): New nonterminal to implement late
+ reduction of constructs like `int ((int)(int)(int))'.
+ (cast_expr): Use it.
+ (sub_cast_expr): Everything that can come after a cast.
+ (typed_declspecs1): typed_declspecs that are not typed_typespecs.
+ (direct_after_type_declarator): Lose PAREN_STAR_PAREN rule.
+ (direct_abstract_declarator): Replace '(' parmlist ')' rule with
+ '(' complex_parmlist ')' and regcast_or_absdcl.
+ (parmlist): Split
+ (complex_parmlist): Parmlists that are not also typenames.
+ (parms_comma): Enabler.
+ (named_parm): A parm that is not also a typename. Use declarator
+ rather than dont_see_typename abs_or_notype_decl. Expand
+ typed_declspecs inline.
+ (abs_or_notype_decl): Lose.
+ (dont_see_typename): Comment out.
+ (bad_parm): Break out abs_or_notype_decl into two rules.
+
+Fri Mar 4 18:22:39 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (reparse_decl_as_casts): New function to change parse
+ nodes for `(int)(int)(int)' from "function taking int and returning
+ function taking int and returning function taking int" to "... cast
+ to int, cast to int, cast to int".
+
+ * decl2.c (reparse_decl_as_expr): Recursive function to change
+ parse nodes for `A()()' from "function returning function returning
+ A" to "A().operator()".
+
+ * parse.y (primary): Replace `typespec LEFT_RIGHT' rule with
+ `typespec fcast_or_absdcl' rule.
+ (fcast_or_absdcl): New nonterminal to implement late reduction of
+ constructs like `A()()()()'.
+ (typename): Replace `typespec absdcl1' rule with
+ `typespec direct_abstract_declarator' rule.
+ (direct_abstract_declarator): Replace `LEFT_RIGHT type_quals' rule
+ with `fcast_or_absdcl type_quals' rule.
+
+Fri Mar 4 16:18:03 1994 Mike Stump <mrs@cygnus.com>
+
+ * tree.c (lvalue_p): Improve OFFSET_REF handling, so that it
+ matches Section 5.5.
+
+Fri Mar 4 14:01:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * error.c (dump_type_prefix): Don't print basetype twice for
+ pmfs.
+
+Fri Mar 4 13:24:33 1994 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (convert_arguments): Handle setHandler(A::handlerFn)
+ so that it is like setHandler(&A::handlerFn). Cures an `invalid
+ lvalue in unary `&''.
+
+Fri Mar 4 11:15:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * gxxint.texi (Copying Objects): New section discussing default
+ op= problems with virtual inheritance.
+
+ * decl2.c (grokoptypename): Just does grokdeclarator and
+ build_typename_overload, since the parser can't call grokdeclarator
+ directly.
+
+ * method.c (build_typename_overload): Set IDENTIFIER_GLOBAL_VALUE
+ and TREE_TYPE on generated identifiers.
+
+ * decl.c (grokdeclarator): Don't deal with TYPE_EXPRs anymore.
+
+ * parse.y (parm): Convert `const char *' to `__opPCc' here.
+
+ * error.c (dump_decl): Say sorry rather than my_friendly_aborting
+ if we can't figure out what to do.
+ (dump_type*): Likewise.
+
+ * typeck2.c (build_m_component_ref): 'component' is an expr, not
+ a decl. Also move the IS_AGGR_TYPE check after the stripping of
+ REFERENCE_TYPE.
+
+Fri Mar 4 04:46:05 1994 Mike Stump <mrs@cygnus.com>
+
+ * call.c (build_method_call): Handle b->setHandler(A::handlerFn)
+ so that it is like b->setHandler(&A::handlerFn). Cures an `invalid
+ lvalue in unary `&''.
+
+Thu Mar 3 12:38:15 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y: Add precedence specification for START_DECLARATOR.
+ (type_quals): Move before primary.
+ (typename): Move before typed_declspecs, add 'typespec absdcl1' rule.
+
+ * decl2.c (grokoptypename): Lose.
+
+ * decl.c (grokdeclarator): Parse TYPE_EXPRs in the initial scan,
+ rather than waiting until later.
+
+Wed Mar 2 14:12:23 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (unary_expr): Use 'typename' in 'new' rules, rather
+ than expanding it inline.
+ (typename): Expand empty option of (former) absdcl inline.
+ (abs_or_notype_decl): Likewise.
+ (absdcl): Lose empty rule.
+ (conversion_declarator): New nonterminal for 'typename' of 'operator
+ typename'.
+ (operator_name): Use it instead of absdcl.
+
+ * parse.y: Add precedence declarations for SCOPED_TYPENAME,
+ TYPEOF, and SIGOF.
+ (typed_declspecs): Accept typed_typespecs, rather than typespec
+ directly. Add rules with reserved_typespecquals.
+ (reserved_declspecs): Don't accept typespecqual_reserved at the
+ beginning of the list. The typed_declspecs rule will deal with this
+ omission.
+ (declmods): Accept nonempty_type_quals, rather than TYPE_QUAL
+ directly.
+
+ * parse.y (direct_notype_declarator,
+ direct_after_type_declarator, direct_abstract_declarator): Split up
+ the declarator1 nonterminals to match the draft standard and avoid
+ ambiguities.
+ (new_type_id, new_declarator, direct_new_declarator,
+ new_member_declarator): New nonterminals to implement the subset of
+ 'typename' allowed in new expressions.
+ (unary_expr): Use new_type_id instead of typename.
+ (after_type_declarator1, absdcl1): Fix semantics of member pointers.
+ (abs_member_declarator, after_type_member_declarator): Lose.
+
+ * parse.y (absdcl1): Don't require parens around
+ abs_member_declarator.
+ (abs_member_declarator): Lose see_typename from rules.
+ (after_type_member_declarator): Likewise.
+
+ * tree.c (get_identifier_list): New function, containing code
+ previously duplicated in get_decl_list and list_hash_lookup_or_cons.
+ (get_decl_list): Use it.
+ (list_hash_lookup_or_cons): Likewise.
+
+ * parse.y (typed_declspecs, declmods): It's not necessary to hash
+ the declspecs on class_obstack, so don't. This way typed_typespecs
+ can reduce to typed_declspecs.
+
+Wed Mar 2 14:29:18 1994 Jason Merrill <jason@cygnus.com>
+
+ * cvt.c (build_up_reference): If we aren't checking visibility,
+ also allow base->derived conversions.
+
+Mon Feb 28 15:14:29 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * typeck.c (build_c_cast): Remove bogus hack when converting
+ to a reference type.
+
+ * cp-tree.h (lang_decl::vbase_init_list, DECL_VBASE_INIT_LIST):
+ Removed, not used.
+ (lang_stype::methods, lang_decl::next_method): New fields.
+ (CLASSTYPE_METHODS, DECL_NEXT_METHOD): New macros.
+ * decl.c (duplicate_decls): Preserve DECL_NEXT_METHOD.
+
+ * cp-tree.h, decl2.c (flag_vtable_hack): New flag.
+ * decl2.c (finish_vtable_vardecl): If flag_vtable_hack,
+ and !CLASSTYPE_INTERFACE_KNOWN, try to use the presence of
+ a non-inline virtual function to control emitting of vtables.
+ * class.c (finish_struct): Build CLASSTYPE_METHODS list.
+ * search.c (build_vbase_vtables_init): Don't assemble_external
+ (yet) if flag_vtable_hack.
+ * class.c (build_vfn_ref): Likewise.
+
+Mon Feb 28 14:54:13 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (component_decl): Don't include "typed_declspecs
+ declarator ';'" speedup, since it breaks enums.
+
+Fri Feb 25 15:43:44 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * class.c (finish_struct): Minor optimization for building
+ fn_fields list.
+
+Fri Feb 25 15:23:42 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_function): Fix detection of function overloading.
+
+Thu Feb 24 22:26:19 1994 Mike Stump <mrs@cygnus.com>
+
+ * lex.c (check_newline): #pragma interface can take a string
+ argument, just like #pragma implementation. #pragma implementation
+ checks for garbage on the line, line #pragma interface does. Main
+ input files do not auto implement like named files, #pragma
+ implementation must be used explicitly.
+
+Thu Feb 24 17:09:01 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y (components): Handle list of one again.
+ (notype_components): Likewise.
+ (after_type_declarator1): Take maybe_raises out again.
+
+ * gxxint.texi (Parser): Document additional r/r conflict.
+
+Wed Feb 23 14:42:55 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * gxxint.texi (Parser): Add node.
+
+ * Makefile.in (stamp-parse): Update expected conflict count.
+
+ * parse.y (various): Replace "declmods declarator" with "declmods
+ notype_declarator". The comment saying that "declmods declarator ';'"
+ corresponds to "int i;" was wrong; it corresponds to "const i;".
+ (component_decl): Add "typed_declspecs declarator ';'" rule; this
+ *does* correspond to "int i;". Change "declmods components" to
+ "declmods notype_components".
+ (components): Don't deal with a list of one anymore.
+ (notype_components): New nonterminal, corresponds to notype_declarator.
+ ({after_,no}type_component_decl{,0}): More new nonterminals.
+ ({after_,no}type_declarator): Fold in START_DECLARATOR token.
+ Eliminates four reduce/reduce conflicts.
+
+ (expr): Depend on nontrivial_exprlist instead of nonnull_exprlist.
+ (nontrivial_exprlist): New nonterminal: A list of at least two
+ expr_no_commas's.
+ (nonnull_exprlist): Depend on nontrival_exprlist.
+ Eliminates four reduce/reduce conflicts.
+
+ (named_class_head): Move intermediate code block into separate
+ nonterminal so that we can stick %prec EMPTY on it.
+
+ Add more %prec EMPTY's to eliminate remaining shift/reduce
+ conflicts.
+
+ (after_type_declarator): Add maybe_raises to fndecl rules.
+ (after_type_declarator_no_typename): Remove.
+ For correctness.
+
+ Document remaining reduce/reduce conflicts.
+
+Tue Feb 22 12:10:32 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (get_base_distance): Only bash BINFO_INHERITANCE_CHAIN
+ (TYPE_BINFO (type)) if we care about the path.
+
+ * tree.c (lvalue_p): A COND_EXPR is an lvalue if both of the
+ options are.
+
+Mon Feb 21 19:59:40 1994 Mike Stump <mrs@cygnus.com>
+
+ * Makefile.in (mostlyclean): lex.c is a source file, don't
+ remove.
+
+Sat Feb 19 01:27:14 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * parse.y: Eliminate 20 shift/reduce conflicts.
+
+Fri Feb 18 11:49:42 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (type_unification): Add subr argument; if set, it means
+ that we are calling ourselves recursively, so a partial match is OK.
+ (unify): Support pointers to methods and functions.
+ (tsubst): Support method pointers.
+ * decl.c (build_ptrmemfunc_type): No longer static, so that
+ tsubst can get at it.
+
+ * init.c (is_aggr_typedef): Pretend template type parms are
+ aggregates.
+ * decl2.c (build_push_scope): If cname refers to a template type
+ parm, just grin and nod.
+
+ * call.c (build_overload_call_real): Pass subr argument to
+ type_unification.
+ * pt.c (do_function_instantiation): Likewise.
+ * class.c (instantiate_type): Likewise.
+
+ * search.c (get_base_distance): If BINFO is a binfo, use it and
+ don't mess with its BINFO_INHERITANCE_CHAIN.
+
+ * cvt.c (convert_to_reference): Fix temporary generation.
+ If ambiguous, return error_mark_node.
+
+ * init.c (build_new): Put back some necessary code.
+
+Thu Feb 17 15:39:47 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_new): Deal with array types properly.
+
+ * search.c (get_binfo): Become a shell for get_base_distance.
+ (get_binfo_recursive): Lose.
+ (get_base_distance_recursive): Find the path to the via_virtual base
+ that provides the most access.
+ (get_base_distance): Likewise.
+
+ * parse.y (explicit_instantiation): Syntax is 'template class
+ A<int>', not 'template A<int>'.
+
+ * typeck.c (convert_for_initialization): Remove bogus warning.
+
+ * parse.y (datadef): Revert patch of Oct 27.
+
+Thu Feb 17 15:12:29 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * class.c (build_vfn_ref): Cast delta field to ptrdiff_type_node,
+ rather than integer_type_node. Does wonders for the Alpha.
+
+Thu Feb 17 13:36:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (build_ptrmemfunc_type): Make sure that the pmf type
+ goes onto the same obstack as its target type.
+
+Wed Feb 16 00:34:46 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (convert_to_reference): If converting via constructor
+ on local level, go back to build_cplus_new approach.
+
+ * tree.c (build_cplus_new): If with_cleanup_p, set cleanup slot
+ to error_mark_node to prevent expand_expr from building a cleanup
+ for this variable.
+
+ * lex.c (default_assign_ref_body): Return *this from the memcpy
+ version, too.
+
+ * decl.c (grok_reference_init): Just return if called with
+ error_mark_node, don't worry about initializing non-const reference
+ with temporary.
+
+ * cvt.c (convert_to_reference): Do the right thing for
+ non-aggregate reference conversions, pedwarn when generating a
+ non-const reference to a temporary.
+
+ * class.c (finish_struct): TYPE_HAS_COMPLEX_{INIT,ASSIGN}_REF and
+ TYPE_NEEDS_CONSTRUCTING all depend on TYPE_USES_VIRTUAL_BASECLASSES
+ again.
+
+Tue Feb 15 19:47:19 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_reference_init): Pawn off a lot of the work on
+ convert_to_reference. Generally do the right thing.
+
+ * cvt.c (convert_to_reference): Conform to the initial comment;
+ i.e. don't create temps if decl != error_mark_node. Handle
+ cleanups better for temps that do get created. Don't pretend
+ that we can use an 'A' to initialize a 'const double &' just by
+ tacking on a NOP_EXPR. Support LOOKUP_SPECULATIVELY.
+
+ * call.c (build_method_call): Set TREE_HAS_CONSTRUCTOR on
+ constructor calls.
+
+Mon Feb 14 14:50:17 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grok_reference_init): Make a temporary for initializing
+ const reference from constant expression.
+
+Mon Feb 14 11:31:31 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * cp-tree.h, decl.c (set_identifier_local_value): Deleted function.
+ * decl.c (pushdecl): Define decl in correct binding_level
+ (which isn't always the inner_binding_level).
+
+ * cvt.c (build_up_reference): Don't ever call expand_aggr_init.
+ It's ugly, and I don't think it's the right thing to do.
+
+ * cp-tree.h, class.c, decl.c, decl2.c, sp/search.c:
+ Remove NEW_CLASS_SCOPING, assuming it is always 1.
+ * decl.c (pop_decl_level): Removed; manually inlined.
+
+Sun Feb 13 19:04:56 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.h (candidate): Add basetypes field.
+
+ * call.c (build_method_call): Do access checking after choosing a
+ function, not before.
+
+ * Makefile.in (cvt.o, call.o, method.o): Depend on class.h.
+ (mostlyclean): Remove ../cc1plus.
+
+Fri Feb 11 11:52:26 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Don't allow adjusting access to a field
+ of a base class if a local field has the same name.
+
+ * error.c (dump_type_prefix): Output basetype for METHOD_TYPEs.
+
+Thu Jan 13 17:55:51 1994 Gnanasekaran Swaminathan <gs4t@virginia.edu>
+
+ * cp-tree.h (DESTRUCTOR_NAME_P): Do not confuse AUTO_TEMP names
+ with destructor names when either NO_DOLLAR_IN_LABEL or
+ NO_DOT_IN_LABEL are not defined.
+
+ Now `template <class T, T f(T&), const T*> class A {...}' works.
+
+ * pt.c (grok_template_type): Substitute template parm types
+ with actual types in complex type as well.
+ (coerce_template_parms): Update the grok_template_type ()
+ function call.
+
+ * pt.c (tsubst): Traverse method list using DECL_CHAIN.
+
+ * decl.c (grok_op_properties): Allow operator++/-- to have
+ default arguments.
+
+ * typeck2.c (store_init_value): Don't abort when called to
+ initialize a type that needs constructing with a CONSTRUCTOR.
+
+ * init.c (expand_aggr_init_1, CONSTRUCTOR case): If
+ store_init_value fails, build and expand an INIT_EXPR. If
+ store_init_value succeeds, call expand_decl_init.
+
+Fri Feb 11 02:49:23 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (build_vbase_path): Use complete_type_p instead of
+ resolves_to_fixed_type_p to determine if the virtual bases are in
+ their right place for the type of expr. Cures problem of thinking a
+ virtual base class is one place, when it is in fact someplace else.
+
+Fri Feb 11 00:26:46 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (resolve_offset_ref): Make sure we first convert to
+ intermediate type, if given, when dealing with members off `this'.
+ Solves an incorrrect `type `foo' is not a base type for type
+ `multiple'' when it is infact, a base type.
+
+Thu Feb 10 21:49:35 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (modify_other_vtable_entries): Use get_binfo, instead
+ of binfo_value. Solves problem with compiler giving a `base class
+ `B' ambiguous in binfo_value (compiler error)' on complex MI
+ herarchies, when a virtual function is first defied in a virtual
+ base class.
+
+Thu Feb 10 17:19:32 1994 Mike Stump <mrs@cygnus.com>
+
+ * class.c (build_vbase_path): Don't complain about ambiguous
+ intermediate conversion when converting down to a virtual base
+ class, even if they might seem to be ambiguous.
+
+Thu Feb 10 12:18:26 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck2.c (build_functional_cast): #if 0 out constructor
+ inheritance code, improve error messages.
+
+ * class.c (finish_base_struct): Complain about base with only
+ non-default constructors in derived class with no constructors.
+
+ * decl.c (grokdeclarator): Fix detection of virtual new/delete.
+
+Wed Feb 9 22:02:32 1994 Mike Stump <mrs@cygnus.com>
+
+ * search.c (build_mi_virtuals, add_mi_virtuals,
+ report_ambiguous_mi_virtuals): Removed unneeded code.
+ * class.c (finish_struct_bits): Likewise.
+
+Wed Feb 9 11:27:17 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * pt.c (end_template_instantiation): Push decl before
+ pop_from_top_level.
+
+ * typeck2.c (build_m_component_ref): Make sure datum is of
+ aggregate type.
+
+ * init.c (get_type_value): New function, returns
+ IDENTIFIER_TYPE_VALUE or IDENTIFIER_CLASS_TYPE_VALUE or NULL_TREE.
+
+ * call.c (build_method_call): Don't die on call to destructor for
+ non-type.
+
+ * decl.c (grokdeclarator): Complain about virtual op new and op
+ delete, make static virtuals unvirtual instead of unstatic.
+
+ * typeck.c (build_c_cast): Also call default_conversion on
+ methods.
+
+ * decl.c (grokdeclarator): Don't complain about anonymous
+ bitfields.
+
+ * parse.y (simple_stmt, for loops): Move the continue point after
+ the cleanups.
+
+ * class.c (finish_struct): Fix setting of
+ TYPE_HAS_COMPLEX_INIT_REF.
+
+Tue Feb 8 13:21:40 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * init.c (build_new): Deal with `new double (1)'.
+
+ * class.c (finish_struct): TYPE_HAS_COMPLEX_*_REF are supersets of
+ TYPE_HAS_REAL_*_REF, but TYPE_HAS_COMPLEX_INIT_REF is independent of
+ TYPE_NEEDS_CONSTRUCTING.
+
+ * decl.c (duplicate_decls): Propagate access decls.
+
+ * typeck2.c (process_init_constructor): Accept empty_init_node
+ for initializing unions.
+
+ * class.c, lex.c, cp-tree.h: Use
+ TYPE_HAS_COMPLEX_ASSIGN_REF where TYPE_HAS_REAL_ASSIGN_REF was used
+ before, use TYPE_HAS_COMPLEX_INIT_REF for TYPE_NEEDS_CONSTRUCTING in
+ some places.
+
+ * decl.c (finish_decl): Don't complain about uninitialized const
+ if it was initialized before.
+
+Mon Feb 7 18:12:34 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * lex.c (default_assign_ref_body): Don't deal with vbases for
+ now.
+
+ * decl.c (finish_decl): Fix reversed logic for objects and other
+ things that need to be constructed but have no initializer.
+
+ * class.c (finish_struct): Don't set TYPE_HAS_* flags that are
+ set by grok_op_properties or finish_decl.
+
+ * decl.c: Don't warn about extern redeclared inline unless
+ -Wextern-inline is given.
+ * decl2.c (lang_decode_option): Likewise.
+ * cp-tree.h: Likewise.
+
+Mon Feb 7 17:29:24 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (pushdecl_with_scope): Fix thinko. Add forward
+ declaration.
+
+ * decl.c (pushdecl_with_scope): New function.
+ * decl.c (pushdecl_top_level): Use new function.
+ * decl.c (pushtag): Initialize newdecl.
+ * decl.c (pushtag): Push new type decl into correct scope.
+
+Mon Feb 7 14:42:03 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c, cvt.c, init.c, search.c, cp-tree.h:
+ Eradicate LOOKUP_PROTECTED_OK.
+
+Mon Feb 7 13:57:19 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (pushtag, xref_tag), cp-tree.h: Add extra parameter
+ 'globalize' to signify implicit declarations.
+ * decl.c (globalize_nested_type, maybe_globalize_type): Removed.
+ * decl.c (set_identifier_type_value_with_scope): New function.
+ * decl.c (set_identifier_local_value): Simplify.
+ * spew.c (yylex, do_addr): Modify to return a _DEFN if a
+ forward declaration (followed by ';' and not preceded by 'friend').
+ * class.c, decl.c, except.c, init.c, parse.y,
+ pt.c, search.c: Add new argument to calls to xref_tag and
+ pushtag.
+
+Mon Feb 7 00:22:59 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.h (ACCESSIBLY_UNIQUELY_DERIVED_P): New macro, means what
+ ACCESSIBLY_DERIVED_FROM_P meant before.
+ (ACCESSIBLY_DERIVED_FROM_P): Now disregards ambiguity.
+
+ * cvt.c (build_up_reference): Call get_binfo with PROTECT == 1.
+
+ * search.c (get_base_distance_recursive): Members and friends of
+ a class X can implicitly convert an X* to a pointer to a private or
+ protected immediate base class of X.
+ (get_binfo_recursive): Likewise.
+ (get_base_distance): Ignore ambiguity if PROTECT < 0.
+ (get_binfo): Lose multiple values of PROTECT.
+ (compute_access): Protected is OK if the start of the
+ search is an accessible base class of current_class_type.
+
+ * method.c (build_opfncall): Do check access on operator new here.
+
+ * decl.c (finish_function): Don't check access on operator new
+ here.
+
+Sun Feb 6 14:06:58 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (xref_tag): The base of a derived struct is NOT always
+ public. Duh.
+
+ * pt.c (do_explicit_instantiation): New function, called from
+ parser to do explicit function instantiation.
+ (type_unification): Allow the args list to be terminated with
+ void_list_node.
+ (do_pending_expansions): Look at i->interface for non-member
+ templates.
+
+ * parse.y (datadef): Move explicit_instantiation here.
+ (structsp): From here.
+ (datadef): Complain about `int;'.
+
+Sun Feb 6 12:33:18 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * pt.c (end_template_instantiation), cp-tree.h: Remove unused
+ second parameter, and simplify first from a TREE_LIST where
+ we only care about its TREE_VALUE to just the value (an IDENTIFIER).
+ * pt.c (instantiate_member_templates): Simplify argument list
+ from a TREE_LIST to just an IDENTIFIER.
+ * lex.c (yyprint): PRE_PARSED_CLASS_DECL is now just an IDENTIFIER.
+ * parse.y (template_instantiate_once): Simplify accordingly.
+ * decl.c (inner_binding_level): New. Use various places to
+ simplify.
+
+Sun Feb 6 02:49:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck2.c (build_functional_cast): int() -> int(0).
+
+Sat Feb 5 00:53:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Don't do a bitwise copy for op= if the
+ class has a virtual function table.
+
+ * typeck.c (convert_for_initialization): Restore warnings about
+ not using defined op=. Should really be my_friendly_aborts, I
+ s'pose.
+
+Fri Feb 4 14:21:00 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Tidy up conditions for doing bitwise
+ copies of objects.
+
+ * decl.c (build_default_constructor): #if 0 out.
+
+ * *: Eradicate TYPE_GETS_{ASSIGNMENT,ASSIGN_REF,CONST_ASSIGN_REF,
+ CONST_INIT_REF}, TYPE_HAS_REAL_CONSTRUCTOR.
+
+ * decl.c (grokdeclarator): Don't return void_type_node for
+ friends being defined here.
+
+ * init.c (perform_member_init): Only do the init if it's useful.
+
+ * lex.c (default_copy_constructor_body): If we don't need to do
+ memberwise init, just call __builtin_memcpy.
+ (default_assign_ref_body): Likewise.
+
+ * decl.c (grokdeclarator): If friendp && virtualp, friendp = 0.
+
+Fri Feb 4 13:02:56 1994 Mike Stump <mrs@cygnus.com>
+
+ * lex.c (reinit_parse_for_method, cons_up_default_function):
+ Don't give warn_if_unknown_interface warning when it came from a
+ system header file.
+ * pt.c (end_template_decl, instantiate_template): Likewise.
+ * decl.c (start_decl): Likewise.
+
+Fri Feb 4 00:41:21 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't try to set TYPE_WAS_ANONYMOUS on
+ enums.
+
+ * decl2.c (constructor_name_full): Use IS_AGGR_TYPE_CODE instead of
+ IS_AGGR_TYPE, since we don't know it's a type.
+
+Thu Feb 3 11:36:46 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't complain about anonymous unions.
+
+ * cp-tree.h (TYPE_WAS_ANONYMOUS): This struct was originally
+ anonymous, but had a name given to it by a typedef.
+
+ * decl.c (grokdeclarator): When renaming an anonymous struct, set
+ TYPE_WAS_ANONYMOUS.
+
+ * decl2.c (constructor_name_full): Use TYPE_WAS_ANONYMOUS.
+
+ * cp-tree.h (DECL_UNDEFINED_FRIENDS): #if 0 out.
+
+ * init.c (xref_friend): Don't set up DECL_UNDEFINED_FRIENDS.
+ (embrace_waiting_friends): Don't use DECL_UNDEFINED_FRIENDS.
+
+ * decl.c (grokdeclarator): Set TYPE_NESTED_NAME properly on nested
+ anonymous structs that get typedef'd.
+
+ * decl.c (grokdeclarator): Always return void_type_node for
+ friends.
+
+ * error.c (dump_function_decl): Don't use DECL_CLASS_CONTEXT for
+ friends.
+ (dump_function_decl): Don't print out default args for
+ a function used in an expression.
+
+ * decl.c (grokdeclarator): Give error on abstract declarator used
+ in an invalid context (i.e. `void (*)();').
+
+ * error.c (cp_line_of): Support _TYPE nodes.
+ (cp_file_of): Likewise.
+
+ * cvt.c (build_up_reference): Don't abort if passed a SAVE_EXPR;
+ it can happen for the RHS of an assignment stmt where the LHS is
+ a COND_EXPR.
+
+ * init.c (expand_aggr_init_1): Deal with bracketed initializer
+ lists properly.
+
+ * class.c (finish_struct): Deal with enumerators and typedefs
+ again.
+
+Wed Feb 2 11:30:22 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Tidy up loop over fields.
+
+ * errfn.c (cp_thing): Don't advance twice after a format.
+
+ * class.c (finish_struct): Complain about needing a constructor
+ if a member has only non-default constructors, and don't try to
+ generate a default constructor.
+
+ * decl.c (finish_decl): Also do the constructor thing if
+ TYPE_NEEDS_CONSTRUCTING is set (for arrays).
+
+ * search.c (unuse_fields): New function: mark all fields in this
+ type unused.
+ (dfs_unuse_fields): Helper function.
+
+ * class.c (pushclass): If the new class is the same as the old
+ class, still unuse the fields.
+ (unuse_fields): Move to search.c.
+
+ * decl.c (grok_op_properties): Add friendp argument.
+ (grokfndecl): Pass it.
+ (start_method): Likewise.
+
+ * decl2.c (delete_sanity): Add use_global_delete parameter to catch
+ ::delete calls.
+
+ * parse.y (unary_expr): Pass new parameter to delete_sanity.
+
+ * lex.c (default_copy_constructor_body): Don't choke if the union
+ has no fields.
+ (default_assign_ref_body): Likewise.
+
+ * call.c (compute_conversion_costs_ansi): Do the right thing for
+ ellipsis matches.
+
+ * decl.c (push_to_top_level): Optimize.
+
+ * decl.c (start_function): Look for the lexical scope of a friend
+ in DECL_CLASS_CONTEXT.
+
+ * init.c (do_friend): Set DECL_CLASS_CONTEXT on global friends.
+
+Tue Feb 1 15:59:24 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.h (TREE_GETS_PLACED_NEW): New macro.
+
+ * init.c (init_init_processing): Don't assign BIN/BID to the
+ IDENTIFIER_GLOBAL_VALUEs of their respective operators.
+ (build_new): Check TREE_GETS_PLACED_NEW.
+
+ * decl.c (grok_op_properties): Don't set TREE_GETS_NEW for a decl of
+ op new with placement, set TREE_GETS_PLACED_NEW.
+
+ * cp-tree.h (ANON_UNION_P): New macro. Applies to decls.
+
+ * class.c (finish_struct): Don't treat anonymous unions like
+ other aggregate members. Do synthesize methods for unions without
+ a name, since they may or may not be "anonymous unions".
+
+ * decl2.c (grok_x_components): Wipe out memory of synthesized methods
+ in anonymous unions.
+
+ * lex.c (default_copy_constructor_body): Support unions.
+ (default_assign_ref_body): Likewise.
+
+Mon Jan 31 12:07:30 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.h: Fix documentation of LOOKUP_GLOBAL, add prototypes.
+
+ * error.c (args_as_string): New function (%A), like type_as_string
+ except NULL_TREE -> "..."
+
+ * call.c (build_overload_call_real): Fix for new overloading.
+
+ * decl.c (grok_op_properties): Set all of the TYPE_OVERLOADS_* flags
+ here.
+
+ * parse.y (operator_name): Instead of here.
+
+ * typeck2.c (build_functional_cast): Treat a TREE_LIST as a list
+ of functions.
+
+ * call.c (build_overload_call_real): Support LOOKUP_SPECULATIVELY.
+
+ * method.c (build_opfncall): Don't need to massage return value
+ any more, call build_overload_call with all flags.
+
+ * typeck.c (build_x_binary_op): Put back speculative call to
+ build_opfncall.
+ (build_x_unary_op): Likewise.
+ (build_x_conditional_expr): Likewise.
+
+Mon Jan 31 10:00:30 1994 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (build_type_conversion_1): Change call to pedwarn into
+ warning, and conditionalize upon warn_cast_qual.
+
+Fri Jan 28 11:48:15 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * search.c (lookup_field): If xbasetype is a binfo, copy it to
+ avoid clobbering its inheritance info.
+
+ * call.c (build_method_call): Don't overwrite basetype_path with
+ TYPE_BINFO (inst_ptr_basetype) if they have the same type.
+
+ * search.c (compute_access): Fix handling of protected inheritance
+ and friendship with the enclosing class.
+
+ * typeck2.c (store_init_value): Allow passing of TREE_CHAIN for
+ initialization of arbitrary variable.
+
+ * typeck2.c (build_functional_cast): Only try calling a method if
+ one exists.
+
+ * decl.c (grokdeclarator): Move handling of constructor syntax
+ initialization into first loop for generality.
+ (parmlist_is_random): Lose.
+
+ * lex.c (cons_up_default_function): Set TREE_PARMLIST on arguments
+ to default function.
+
+Thu Jan 27 19:26:51 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokparms): Abort if we get called with something we don't
+ expect.
+
+Thu Jan 27 17:37:25 1994 Mike Stump <mrs@cygnus.com>
+
+ * call.c (build_overload_call_real): Change argument complain to
+ flags to match style of rest of code. Pass it down to
+ build_function_call_real as necessary.
+ * call.c (build_overload_call, build_overload_call_maybe): Change
+ argument complain to flags to match style of rest of code.
+ * cp-tree.h (build_function_call_real): Added fourth flags
+ argument.
+ * cvt.c (convert_to_reference): Only give warning messages, if
+ LOOKUP_COMPLAIN is set.
+ * typeck.c (build_x_function_call): Change simple complain
+ argument to build_overload_call_maybe and build_overload_call, to
+ LOOKUP_COMPLAIN to match style of rest of code.
+ * typeck2.c (build_functional_cast): Likewise.
+ * typeck.c (build_function_call_real): Add flags, so that we can
+ not complain, if we don't want to complain. Complain about
+ arguments, if we are complaining, otherwise don't.
+ * typeck.c (build_function_call, build_function_call_maybe):
+ Stick in flags argument.
+ * typeck.c (build_x_binary_op, build_x_unary_op,
+ build_x_conditional_expr, build_x_compound_expr): Follow style of
+ build_x_indirect_ref, as it is more correct and more common.
+
+Thu Jan 27 14:36:20 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Don't check for being called with
+ a pointer.
+
+ * decl2.c (finish_file): Don't play with DECL_CLASS_CONTEXT for the
+ static initializer function.
+
+ * init.c (build_member_call): Use convert_force here, too.
+
+ * search.c (compute_access): Only treat static members specially
+ if they are referenced directly.
+
+Wed Jan 26 18:28:14 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * gxxint.texi (Access Control): New node.
+
+ * search.c (current_scope): New function; returns whichever of
+ current_class_type and current_function_decl is the most nested.
+ (compute_access): Total overhaul to make it clearer and more
+ correct. Don't use the cache for now; in the only situation where
+ it was used before, it gained nothing. This frees up three of the
+ DECL_LANG_FLAGs for possible other use!
+
+ * cp-tree.h: #if 0 out DECL_PUBLIC & friends.
+
+ * typeck.c (build_component_ref_1): Don't check DECL_PUBLIC.
+
+ * call.c (build_method_call): Use convert_force to cast `this' --
+ rely on the access checking for the method itself.
+
+ * init.c (is_friend): Do the nesting thing, handle types. I am
+ my own friend.
+ (is_friend_type): Become a shell for is_friend.
+ (add_friend): Never stick in ctype.
+ Why are the friendship functions in init.c, anyway?
+
+Wed Jan 26 17:50:00 1994 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (build_type_conversion_1): Don't conditionalize call to
+ pedwarn upon pedantic.
+
+Wed Jan 26 17:20:46 1994 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (convert_to_reference): Add 8.4.3 checking so that one
+ gets a warning if one tries to initialize a non-const & from a
+ non-lvalue.
+ * cvt.c (convert_to_reference): Use %P format for argument
+ numbers in warnings.
+
+Wed Jan 26 14:35:06 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (build_delete): Follow style in call.c to construct the
+ virtual call to the desctructor, as that code is right. Fixes a
+ problem of the compiler saying a pointer conversion is ambiguous.
+
+Wed Jan 26 11:28:14 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.h (VTABLE_NAME_P): Change other occurrence of
+ VTABLE_NAME_FORMAT to VTABLE_NAME.
+
+ * *: s/visibility/access/g
+
+Tue Jan 25 18:39:12 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_modify_expr): Don't smash references if INIT_EXPR.
+
+Tue Jan 25 13:54:29 1994 Mike Stump <mrs@cygnus.com>
+
+ * init.c (build_delete): Back out Jan 17th & 18th pacthes, as
+ they break libg++.
+
+Tue Jan 25 13:11:45 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (duplicate_decls): Fix pointer arithmetic.
+
+Mon Jan 24 15:50:06 1994 Chip Salzenberg <chip@fin.uucp>
+
+ [ cp-* changes propagated from c-* changes in 940114 snapshot ]
+ * cp-parse.y (maybe_attribute): Allow multiple __attribute__
+ clauses on a declaration.
+
+Mon Jan 24 17:06:23 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Do synthesize methods for anon
+ structs, just not unions.
+
+Mon Jan 24 13:50:13 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * decl.c (xref_tag): Handle anonymous nested type.
+ * decl.c (globalize_nested_type): Add no globalize bit check.
+ * spew.c (hack_more_ids): Templated nested decl not push top
+ level.
+
+ * parse.y: Get rid of 'goto do_components'. It is much better
+ for debugging.
+
+ * decl.c (is_anon_name): Get rid of the function and use the
+ macro ANON_AGGRNAME_P.
+ * pt.c: Ditto.
+
+Fri Jan 21 14:06:02 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct): Don't synthesize any methods for
+ anonymous structs/unions.
+
+ * typeck.c (build_modify_expr): Don't treat pmf's as class objects.
+
+Thu Jan 20 18:56:46 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * method.c (build_opfncall): Call build_indirect_ref on
+ synthesized instance for operator delete.
+
+ * pt.c (type_unification): Don't abort if called with a list of
+ types in ARGS.
+
+ * class.c (instantiate_type): Deal with function templates.
+
+Thu Jan 20 16:55:35 1994 Jim Wilson <wilson@sphagnum.cygnus.com>
+
+ * Makefile.in (CC): Default to cc not gcc.
+
+Thu Jan 20 13:47:54 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_modify_expr): Call constructor if appropriate.
+
+ * decl.c (push_to_top_level): Clear out class-level bindings cache.
+
+Wed Jan 19 13:51:22 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (resolve_scope_to_name): Work recursively (previously only
+ looked down one level).
+
+ * lex.c (do_pending_inlines): If we're still dealing with the last
+ batch of inlines, don't start working on a new one.
+
+ * Makefile.in (stamp-parse): Update conflict count.
+ (TAGS): Fix.
+
+ * parse.y (explicit_instantiation): New rule; implements
+ 'template A<int>' syntax (though not 'template foo(int)' yet).
+ (structsp): Add explicit_instantiation.
+
+Tue Jan 18 13:53:05 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * class.c (finish_struct, etc.): Simplify decision to synthesize
+ a destructor.
+
+ * call.c, class.c, cp-tree.h, decl.c, init.c,
+ ptree.c, search.c, typeck.c, typeck2.c: Nuke
+ TYPE_NEEDS_CONSTRUCTOR (change all calls to TYPE_NEEDS_CONSTRUCTING).
+ * init.c (expand_aggr_init_1): Don't try non-constructor methods
+ of initializing objects.
+ (build_new): Don't try other methods if the constructor lookup fails.
+
+ * class.c (finish_base_struct): Set cant_have_default_ctor and
+ cant_synth_copy_ctor properly.
+ (finish_struct): Likewise.
+
+Mon Jan 17 13:58:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_modify_expr_1): #if 0 out again.
+ (build_modify_expr): #if 0 out memberwise init code again.
+
+ * lex.c (default_copy_constructor_body): Be const-correct.
+ (default_assign_ref_body): Likewise.
+
+ * init.c (perform_member_init): Use TYPE_HAS_CONSTRUCTOR to decide
+ whether or not to use it, rather than TYPE_NEEDS_CONSTRUCTING.
+ (expand_aggr_init): Disable silent conversion from initializer list
+ to list of args for a constructor.
+
+ * class.c (base_info): Lose needs_default_ctor.
+ (finish_base_struct): Likewise.
+ (finish_struct): Likewise.
+
+ * decl.c (init_decl_processing): Don't turn off flag_default_inline
+ just because flag_no_inline is on.
+ (finish_decl): Use TYPE_HAS_CONSTRUCTOR to decide to use
+ constructor.
+
+ * class.c (finish_struct): Synthesize default ctor whenever
+ allowed.
+
+ * Makefile.in (TAGS): Don't try to run etags on cp-parse.y.
+
+Sat Jan 15 18:34:33 1994 Mike Stump <mrs@cygnus.com>
+
+ * Makefile.in, configure: Handle the C++ front-end in a
+ subdirectory.
+ * cp-*: Move C++ front-end to cp/*.
+
+Fri Jan 14 14:09:37 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-typeck.c (build_function_call_real): Modify to match other
+ instances of taking the address of the function.
+
+ * cp-class.c (finish_struct): Set TYPE_HAS_REAL_CONSTRUCTOR to 1 if
+ there are non-synthesized constructors.
+ Only set TYPE_NEEDS_CONSTRUCTOR if TYPE_HAS_REAL_CONSTRUCTOR.
+ Always generate copy constructor if possible.
+
+ * cp-tree.h (lang_type): Add has_real_constructor bitfield.
+ (TYPE_HAS_REAL_CONSTRUCTOR): Define.
+
+ * cp-lex.c (default_copy_constructor_body): Use init syntax
+ for all bases.
+
+ * cp-type2.c (store_init_value): Only give error for initializer list
+ if TYPE_HAS_REAL_CONSTRUCTOR.
+
+Thu Jan 13 15:38:29 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-tree.h (DECL_SYNTHESIZED): Add defn.
+ (lang_decl): Add synthesized bitfield to decl_flags.
+
+ * cp-lex.c (cons_up_default_function): Use DECL_SYNTHESIZED to mark
+ artificial methods, rather than a line # of 0.
+
+Fri Jan 14 18:25:29 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * cp-decl (xref_tag): Fix a bug in conflict type.
+ * cp-parse.y: Add SCOPED_NAME for uninstantiated template nested
+ type reference.
+ * cp-spew.c (yylex): Generated SCOPED_NAME token.
+ * cp-lex.c (yyprint): Handle SCOPED_NAME.
+
+Fri Jan 14 17:00:29 1994 Mike Stump <mrs@cygnus.com>
+
+ * cp-decl.c (pushdecl): Revert patch from Jan 11 19:33:03, as it is
+ not right.
+
+Thu Jan 13 14:00:35 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * cp-decl2.c (grok_x_components): Fix a bug that enum type does not
+ have type_flags.
+
+Thu Jan 13 11:39:34 1994 Mike Stump <mrs@cygnus.com>
+
+ Ensure that all vtable pointers are initialized with all the right
+ values.
+
+ * cp-class.c (is_normal): Changed to reflect new meaning of
+ CLASSTYPE_VFIELD_PARENT.
+ * cp-class.c (maybe_fixup_vptrs): Use of
+ CLASSTYPE_NEEDS_VIRTUAL_REINIT here is misguided. Use
+ BINFO_MODIFIED instead.
+ * cp-class.c (finish_struct): Changed to reflect new meaning of
+ CLASSTYPE_VFIELD_PARENT.
+ * cp-decl.c (get_binfo_from_vfield): Removed, unneeded now.
+ * cp-decl.c (finish_function): Use init_vtbl_ptrs, instead of open
+ coding it here.
+ * cp-init.c (init_vfields): Changed name to init_vtbl_ptrs, and
+ re-implement.
+ * cp-init.c (emit_base_init): Use new name init_vtbl_ptrs.
+ * cp-tree.h (vfield_parent): Changed to integer.
+ * cp-tree.h (CLASSTYPE_VFIELD_PARENT): Changed docs to reflect new
+ meaning.
+ * cp-tree.h (init_vtbl_ptrs): Added init_vtbl_ptrs.
+
+Wed Jan 12 18:24:16 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * cp-decl.c (xref_tag): Re-implement globalize nested type.
+ * cp-decl2.c (grok_x_components): Ditto.
+ * cp-parse.y: Ditto.
+ * cp-tree.h (lang_type): Add no_globalize bit in type_flags.
+
+Wed Jan 12 14:08:09 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (grokdeclarator): Don't set TREE_PUBLIC on friend
+ decls with a definition attached.
+
+ * cp-typeck.c (build_modify_expr): Undo previous change in the case
+ of INIT_EXPRs.
+
+Tue Jan 11 19:33:03 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-typeck.c (build_modify_expr): Replace code for generating
+ assignment semantics for classes with an error.
+ (build_modify_expr_1): #if 0 out.
+
+ * cp-decl.c (pushdecl): Patch bogus design of pushdecl
+ behavior for overloaded functions (it doesn't push anything).
+
+ * cp-class.c (finish_struct): When generating default op=,
+ set TYPE_HAS_ASSIGNMENT.
+
+Mon Jan 10 18:48:06 1994 Mike Stump <mrs@cygnus.com>
+
+ * cp-cvt.c (convert): Make {double, clashing enum} -> enum
+ invalid.
+ * cp-typeck.c (convert_for_assignment): Simplify.
+ * cp-decl2.c (warn_enum_clash): Removed.
+ * invoke.texi (-Wenum-clash): Removed.
+ * toplev.c (-Wenum-clash): Removed.
+
+Mon Jan 10 17:48:37 1994 Kung Hsu <kung@mexican.cygnus.com>
+
+ * cp-decl.c (finish_decl): Fix incorrect popclass call.
+
+ * cp-decl.c (is_anon_name): New function, check whether the name
+ is anonymous name generated by compiler.
+ * cp-decl.c (grokdeclarator): Allow nested SCOPE_REF
+ * cp-spew.c (hack_more_ids): Handle nested type in template.
+ * cp-parse.y: Handle nested type reference in uninstantiated
+ template.
+ * cp-call.c (build_method_call): Handle uninstantiated template
+ case.
+ * cp-pt.c (search_nested_type_in_tmpl): New function, search nested
+ type in template.
+ * cp-pt.c (lookup_nested_type_by_name): New function, lookup nested
+ type by name.
+ * cp-pt.c (tsubst): Handle nested type search by name.
+
+Mon Jan 10 14:32:18 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-init.c (build_member_call): Propagate qualifiers to new type.
+
+ * cp-call.c (build_method_call): Count functions the new way.
+
+Fri Jan 7 19:03:26 1994 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cp-decl.c (pushtag): Set DECL_ASSEMBLER_NAME for nested classes,
+ too.
+
+Tue Jan 4 16:45:51 1994 Kung Hsu <kung@cirdan.cygnus.com>
+
+ * cp-parse.y: Change to handle whether to globalize nested class.
+ * cp-decl.c (xref_tag, maybe_globalize_type): Likewise.
+
+Mon Jan 3 22:22:32 1994 Gerald Baumgartner <gb@cygnus.com>
+
+ * Makefile.in cp-call.c cp-class.c cp-cvt.c cp-decl.c cp-decl2.c
+ cp-error.c cp-init.c cp-lex.c cp-lex.h cp-method.c cp-parse.y
+ cp-spew.c cp-tree.c cp-tree.h cp-type2.c cp-typeck.c cp-xref.c
+ gplus.gperf toplev.c: Incorporated C++ signature extension.
+ * cp-sig.c: New file, contains most of signature processing.
+ * cp-hash.h: Regenerated from gplus.gperf.
+
+ * gcc.1 g++.1: Added explanation for the `-fhandle-signatures'
+ and `-fno-handle-signatures' command line flags.
+
+ * gcc.texi: Changed the last-modification date.
+ * invoke.texi: Added `-fhandle-signatures' in the list of
+ C++ language options. Added explanation for this option.
+
+
+
+Copyright (C) 1994 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-1995 b/gcc-4.9/gcc/cp/ChangeLog-1995
new file mode 100644
index 000000000..b5ca4ec34
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-1995
@@ -0,0 +1,3797 @@
+Thu Dec 28 11:13:15 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_builtin_throw): Use RETURN_ADDR_OFFSET instead of
+ NORMAL_RETURN_ADDR_OFFSET.
+ (end_eh_unwinder): Likewise.
+
+Wed Dec 27 22:18:16 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_dynamic_cast): Make sure we don't cast away const
+ when dealing with references, and make sure we handle dynamic
+ casting to a cv qualified reference.
+
+Thu Dec 21 23:50:35 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (struct eh_context): New structure top hold eh context
+ information.
+ (push_eh_context): New routine.
+ (pop_eh_context): Likewise.
+ * decl.c (push_cp_function_context): Use them.
+ (pop_cp_function_context): Likewise.
+
+Wed Dec 20 12:42:51 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Also prune uninteresting functions in the
+ inline emission loop.
+
+Wed Dec 20 02:32:07 1995 Jeffrey A Law <law@cygnus.com>
+
+ * sig.c (build_signature_table_constructor): Mark functions
+ in the signature as referenced.
+
+Tue Dec 19 22:36:56 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Do all the vtable/synthesis stuff before
+ the inline emission stuff.
+
+Mon Dec 18 15:51:33 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h, decl2.c (flag_weak): New flag to control the use of
+ weak symbols.
+ * lang-options.h: Add -f{no-,}weak.
+ * decl.c (init_decl_processing): If the target does not support weak
+ symbols, don't use them.
+ * decl2.c, pt.c: s/SUPPORTS_WEAK/flag_weak/.
+
+Sun Dec 17 21:13:23 1995 Rusty Russell <rusty@adelaide.maptek.com.au>
+
+ * init.c (expand_member_init): warning for base init after members.
+
+Fri Dec 15 15:32:18 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (build_expr_type_conversion): Don't convert to a reference
+ type.
+
+Thu Dec 14 16:05:58 1995 Mike Stump <mrs@cygnus.com>
+
+ * method.c (report_type_mismatch): Improve wording for volatile
+ mismatches.
+
+Thu Dec 14 14:16:26 1995 Mike Stump <mrs@cygnus.com>
+
+ * init.c (expand_aggr_init_1): Use expand_aggr_init_1 instead of
+ expand_assignment, as the later doesn't handle things that have
+ copy constructors well. The compiler would do bitwise copying,
+ instead of ctor calling in some cases.
+
+Wed Dec 13 17:05:54 1995 Paul Eggert <eggert@twinsun.com>
+
+ * g++.c (my_strerror): Return "cannot access" if errno is 0.
+ (pfatal_with_name, perror_exec): Don't assume that
+ the returned value from my_strerror contains no '%'s.
+ (concat): Remove.
+ (sys_nerror): Declare only if HAVE_STRERROR is not defined.
+
+Wed Dec 13 16:22:38 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ Lose CLASSTYPE_METHODS/DECL_NEXT_METHOD chain; make
+ TYPE_METHODS/TREE_CHAIN mean what they used to.
+ * decl2.c (constructor_name_full): Refer to CLASSTYPE_METHOD_VEC
+ instead of TYPE_METHODS.
+ * decl.c (duplicate_decls): Lose references to DECL_NEXT_METHOD.
+ * tree.c (tree_copy_lang_decl_for_deferred_output): Likewise.
+ * cp-tree.h (CLASSTYPE_METHODS): Lose.
+ (CLASSTYPE_METHOD_VEC): Point to lang_spec->methods instead of
+ TYPE_METHODS.
+ (struct lang_decl): Lose next_method field.
+ (DECL_NEXT_METHOD): Lose.
+ * class.c (finish_struct_methods): Don't mess with TYPE_METHODS.
+ (finish_struct): Just use TYPE_METHODS; we don't need fn_fields
+ anymore.
+ (finish_struct_methods): Don't mess with the TREE_CHAINs in
+ fn_fields.
+
+ * search.c (add_conversions): Don't use TREE_CHAIN to traverse method
+ vector.
+
+ * call.c (build_method_call): Synthesize here even when not inlining.
+ * typeck.c (build_function_call_real): Likewise.
+
+Wed Dec 13 15:02:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * cp/lex.c (check_newline): If DBX_DEBUGGING_INFO and write_symbols
+ == DBX_DEBUG, call dbxout_start_new_source_file and
+ dbxout_resume_previous_source_file when appropriate.
+
+Tue Dec 12 20:38:55 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (start_anon_func): Push to the top level.
+ (end_anon_func): Pop from the top level.
+
+Mon Dec 11 18:56:14 1995 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (build_cleanup): New routine to build cleanups.
+ * decl.c (expand_static_init): Use build_cleanup to build a cleanup
+ call at ctor time and use atexit to run it later.
+ * decl2.c (build_cleanup): New routine, taken from finish_file.
+ (finish_file): Use build_cleanup instead, and don't put function
+ local statics in global dtor list.
+
+Wed Dec 6 14:34:29 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Ensure that we have cleanups, if we try
+ and expand cleanups.
+
+Wed Dec 6 11:48:21 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Add logic to manage dynamic cleanups for
+ the EH object.
+ (expand_end_catch_block): Use the magic of expand_goto, instead of
+ emit_jump so that we get the cleanup for any catch clause parameter
+ and the cleanup for the exception object. Update to reflect label
+ changes.
+ (push_eh_cleanup): New routine to register a cleanup for an
+ exception object.
+ (empty_fndecl): Used to default cleanup actions to
+ nothing.
+ (init_exception_processing): Setup empty_fndecl. Setup
+ saved_cleanup.
+ (expand_start_catch_block): Update to reflect label changes. Call
+ push_eh_object to register the cleanup for the EH object.
+ (start_anon_func): New routine to start building lambda expressions
+ from trees.
+ (end_anon_func): New routine to end them.
+ (struct labelNode): Change so that we can use tree labels, or rtx
+ labels.
+ (saved_cleanup): Object to check for dynamic cleanups for the
+ exception handling object.
+ (push_label_entry): Change so that we can use tree labels, or rtx
+ labels.
+ (pop_label_entry): Likewise.
+ (top_label_entry): Likewise.
+ (expand_start_all_catch): Use tree label instead of rtx label, so
+ that we can get the magic of expand_goto.
+ (expand_end_all_catch): Update to reflect label changes.
+
+ * class.c (build_vfn_ref): Remove building_cleanup logic, as we now
+ use UNSAVE_EXPRs.
+ * typeck.c (get_member_function_from_ptrfunc): Remove remnants of
+ building_cleanup logic, as we now use UNSAVE_EXPRs.
+ * cp-tree.h (unsave_expr): Declare it.
+ * decl.c (building_cleanup): Remove.
+ (maybe_build_cleanup): Remove building_cleanup logic, and use
+ UNSAVE_EXPR instead.
+
+Sun Dec 3 01:34:58 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_t_desc): Update error message to say <typeinfo>.
+
+Thu Nov 30 12:30:05 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (pushdecl): Only warn about shadowing a local variable if
+ warn_shadow is true.
+
+Sun Nov 26 16:06:55 1995 Rusty Russell <rusty@adelaide.maptek.com.au>
+
+ * typeck.c (build_binary_op_nodefault): Added warning about
+ comparisons between different enum types with -Wall, unless
+ -fenum-int-equiv set.
+
+Wed Nov 22 15:44:02 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (finish_struct_1): Skip down to the inner type in
+ multidimensional arrays. Ensures ctors will be made for types that
+ need constructing.
+
+Wed Nov 22 14:19:22 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (last_dtor_insn): New to track the last compiler generated
+ insn in a dtor.
+ (store_parm_decls): Set it.
+ (finish_function): Use it to see if the dtor is empty. Avoid doing
+ vtable setup all the time, if we can.
+ (struct cp_function): Add last_dtor_insn.
+ (push_cp_function_context): Save it.
+ (pop_cp_function_context): Restore it.
+
+Wed Nov 22 11:52:19 1995 Paul Russell <Rusty.Russell@adelaide.maptek.com.au>
+
+ * typeck.c (build_unary_op): Set TREE_NO_UNUSED_WARNING to avoid
+ warnings.
+
+Tue Nov 21 17:15:23 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (expand_target_expr): Make sure targets get put into the
+ current temp_slot_level, so that the free_temp_slots call will reuse
+ them.
+
+Tue Nov 21 13:32:03 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (finish_struct_1): Delay delta fixups for virtual bases
+ until after we have done the hard virtuals, to avoid a bogus `every
+ virtual function must have a unique final overrider' for virtual
+ functions that are only overridden by hard virtuals.
+
+Thu Nov 9 13:35:30 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (do_function_instantiation): Don't try to find a file-scope
+ template for a member function.
+
+Tue Nov 14 06:20:35 1995 Mike Stump <mrs@cygnus.com>
+
+ * g++.c (main): Add handling of -nodefaultlibs.
+
+Mon Nov 13 15:45:34 1995 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (INDIRECT_BIND): Add a way for the frontend to
+ distinguish between direct bindings of reference variables, and
+ indirect bindings of reference variables.
+ * cvt.c (build_up_reference): Use it.
+ * typeck.c (convert_arguments): Use it to indicate this is an
+ indirect binding.
+ * decl.c (cp_finish_decl): Ensure that we reuse stack slots as fast
+ as they are unused.
+ (expand_static_init): Likewise.
+ (cplus_expand_expr_stmt): Likewise.
+ * decl2.c (finish_file): Likewise.
+ * init.c (perform_member_init): Likewise.
+ (emit_base_init): Likewise.
+ (expand_aggr_vbase_init_1): Likewise.
+
+Fri Nov 10 09:18:09 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (push_namespace): Rewrite to use build_lang_decl, so we
+ get a DECL_LANG_SPECIFIC node.
+ * cp-tree.h (lang_decl_flags): Add new member `level'.
+ (NAMESPACE_LEVEL): Don't use decl.arguments, instead use the
+ decl_flags level member.
+
+Mon Nov 6 18:36:13 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (build_method_call): Make sure instance has a
+ TYPE_LANG_SPECIFIC node before we dive into it.
+
+Sat Nov 4 20:01:52 1995 Jason Molenda <crash@phydeaux.cygnus.com>
+
+ * method.c (make_thunk): Use TREE_SET_CODE to set thunk's tree code.
+
+Thu Nov 2 17:56:57 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (duplicate_decls): When smashing decls, smash staticness in
+ the usual way.
+
+Thu Nov 2 16:44:02 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (poplevel): Handle the merging of subblocks of cleanups
+ when finishing blocks that have already been created (usually due to
+ the fixup goto code). Fixes bad debugging information.
+
+Wed Nov 1 12:33:53 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (hack_identifier): Don't abort when we get a TREE_LIST
+ that's not a list of overloaded functions.
+
+Wed Nov 1 11:38:58 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl2.c (mark_vtable_entries): Check DECL_LANG_SPECIFIC on fn
+ before trying to use DECL_ABSTRACT_VIRTUAL_P.
+
+Tue Oct 31 11:56:55 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (mark_used): New function for hooking into setting of
+ TREE_USED on decls.
+ * call.c (build_method_call): Use it.
+ * class.c (instantiate_type): Likewise.
+ * init.c (build_offset_ref): Likewise. Don't call assemble_external
+ for all like-named functions.
+ * method.c (hack_identifier): Likewise.
+ (emit_thunk): Don't call assemble_external.
+ (make_thunk): Create thunk as a FUNCTION_DECL so that it
+ gets the right mode and ENCODE_SECTION_INFO works.
+
+ * parse.y: Use mark_used. Pass operator names to do_identifier.
+ * lex.c (do_identifier): Handle operator names.
+
+ * decl2.c (grokclassfn): Tweak __in_chrg attributes.
+
+Thu Oct 26 16:45:58 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * errfn.c: Include stdio.h.
+ (cp_sprintf): Take out decl of sprintf, and cast sprintf to errorfn*.
+
+Wed Oct 25 18:58:41 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck2.c (digest_init): Always convert initializers to the
+ right type.
+
+Wed Oct 25 13:25:24 1995 Mike Stump <mrs@cygnus.com>
+
+ * init.c (member_init_ok_or_else): Don't allow member initializers
+ for indirect members, as it is invalid.
+
+Wed Oct 25 11:35:28 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't allow `friend signed ()'.
+
+Fri Oct 20 10:30:59 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (for.init.statement): Catch compound statements inside for
+ initializations, if we're being pedantic.
+
+Fri Oct 20 10:03:42 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (lookup_tag): Return NULL_TREE if we don't find what we are
+ looking for.
+
+Thu Oct 19 14:26:10 1995 Mike Stump <mrs@cygnus.com>
+
+ * error.c (dump_expr): Don't core dump when a boolean expression is
+ used as a default argument.
+
+Thu Oct 19 10:36:30 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_bits): Check aggregate_value_p instead of
+ RETURN_IN_MEMORY.
+
+Wed Oct 18 18:12:32 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_bits): Also set TREE_ADDRESSABLE on a
+ BLKmode type that would otherwise be returned in registers.
+
+Mon Oct 16 12:32:19 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * g++.c (WITHLIBC): New macro.
+ (main): Declare saw_libc. Use WITHLIBC if `-lc' was used; set
+ saw_libc and pass it at the end if it was set.
+
+Wed Oct 11 16:30:34 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (fn.def1): Call split_specs_attrs in
+ declmods notype_declarator case.
+
+Sun Nov 26 14:47:42 1995 Richard Kenner <kenner@mole.gnu.ai.mit.edu>
+
+ * Version 2.7.2 released.
+
+Mon Nov 20 14:05:00 1995 Mike Stump <mrs@cygnus.com>
+
+ * g++.c (pfatal_with_name): Add missing third argument to concat.
+
+Thu Oct 26 13:59:54 1995 Mike Stump <mrs@cygnus.com>
+
+ * init.c (expand_aggr_init): Handle cv qualifiers on the object's
+ type.
+
+Sat Nov 11 08:25:55 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Version 2.7.1 released.
+
+Thu Nov 2 17:02:47 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (convert_harshness): Handle references to arrays.
+
+Fri Oct 27 14:20:21 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (comp_target_types): Check multi-level pointer
+ conversions in both directions.
+
+Tue Oct 17 21:39:05 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (explicit_instantiation): Fix 'extern template' with no
+ return type.
+
+Mon Oct 16 14:35:20 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (explicit_instantiation): Support automatic instantiation
+ of constructors.
+ (named_class_head_*): Support out-of-class definition of nested
+ types.
+
+Wed Oct 11 12:20:56 1995 Mike Stump <mrs@cygnus.com>
+
+ * search.c (envelope_add_decl): New routine. Fix so that
+ methods are hidden in the same way that other members are.
+ (dfs_pushdecls): Cleanup and move functionality out of line,
+ into envelope_add_decl.
+
+Tue Oct 10 15:46:01 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (mark_addressable): Only call assemble_external if we
+ have started the output file.
+
+Tue Oct 10 11:27:18 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_function): Fix earlier cv-quals change.
+
+Mon Oct 9 23:53:05 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (complex_direct_notype_declarator): Only push the class if
+ we are not already in the class.
+
+Mon Oct 9 11:22:03 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * decl.c (duplicate_decls): Call merge_machine_decl_attributes.
+ Update olddecl's attributes too.
+ (grokdeclarator): #if 0 out call to build_decl_attribute_variant.
+ * typeck.c (common_type): Call merge_machine_type_attributes.
+
+Fri Oct 6 14:44:27 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (mark_addressable): Add missing call to
+ assemble_external.
+
+Wed Oct 4 15:06:39 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (store_parm_decls): Make sure the unwinder start comes
+ before the exception specification start.
+ * except.c (expand_exception_blocks): Make sure the unwinder end
+ comes after the terminate protected catch clause region and after
+ the end of the exception specification region.
+
+Wed Oct 4 12:47:02 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (real_yylex): Fix identifier case for linemode.
+ (handle_sysv_pragma): Don't abort when we see a pragma we don't
+ recognize.
+
+Tue Oct 3 14:09:46 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (store_parm_decls): Add a call to start_eh_unwinder.
+ * except.c (init_exception_processing): __throw doesn't take any
+ arguments.
+ (expand_builtin_throw): Likewise. Always use Pmode, instead of SImode
+ for all pointers. Use expand_builtin_return_addr to unwind the
+ first level off the stack.
+ (do_unwind): Always use Pmode, instead of SImode for all pointers.
+ (expand_exception_blocks): Add a call to end_eh_unwinder.
+ (start_eh_unwinder, end_eh_unwinder): New routines to build machine
+ independent stack unwinders for function/method calls.
+
+Mon Oct 2 17:20:42 1995 Mike Stump <mrs@cygnus.com>
+
+ * tree.c (unsave_expr_now): Make sure we process the argument list
+ of any called functions. Fixes incorrect code generation for
+ cleanups.
+
+Mon Oct 2 13:04:16 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Save function if it
+ needs it. Cures core dump on things like (this->*(f()))().
+
+Sat Sep 23 22:51:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_function): Conform to gcc cv-quals convention (no
+ expression has a cv-qualified type) in RESULT_DECLs.
+ * method.c (make_thunk): Likewise.
+
+Fri Sep 22 10:21:13 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (pushtag): Add in the namespace name for the tag.
+
+Thu Sep 21 13:11:13 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (maybe_base_class_list, base_class_list, base_class,
+ base_class_access_list): Make sure we see the typenames for base
+ classes.
+ * lex.c (see_typename): Instead of failing to see a typename when
+ there is no next token, perfer a typename, and get the next token.
+
+Wed Sep 20 12:35:27 1995 Michael Meissner <meissner@cygnus.com>
+
+ * decl.c (init_decl_processing): Add __builtin_expect.
+
+Tue Sep 19 16:48:11 1995 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Don't allow leftover conversions to
+ or from pointer to member functions, they must all be handled before
+ this point.
+
+Fri Sep 15 17:14:47 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (resolve_offset_ref): Fix wording of non-static member
+ being referenced as a static.
+
+Fri Sep 15 12:39:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_indirect_ref): Only bash pointer if we actually
+ call build_expr_type_conversion.
+
+Thu Sep 14 18:24:56 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * cvt.c (build_expr_type_conversion): Handle conversion from
+ reference.
+ * typeck.c (build_indirect_ref): Avoid infinite recursion.
+
+Thu Sep 14 17:23:28 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (expand_start_early_try_stmts): New routine to start a try
+ block at the start of the function, for function-try-blocks.
+ * cp-tree.h (expand_start_early_try_stmts): Declare it.
+ * parse.y (function_try_block): Use it, instead of doing it here, as
+ we don't want to include rtl.h here, as that conflicts with RETURN
+ in the parser.
+
+Wed Sep 13 18:32:24 1995 Mike Stump <mrs@cygnus.com>
+
+ * lex.c (reinit_parse_for_block): Support saving inline
+ function-try-blocks, uses peekyylex.
+ * parse.y (eat_saved_input): New rule, permit the parser to see that
+ END_OF_SAVED_INPUT is ok, as it can see this when parsing the
+ handlers of a function-try-block.
+ (fndef): Use it.
+ (component_decl): Make sure TRY and RETURN can come after fn.def2.
+ * spew.c (peekyylex): New routine to peek at what will come next.
+
+Wed Sep 13 16:52:06 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (comptypes): Tighten up comparisons of template type
+ parms.
+
+ * decl.c (duplicate_decls): Turn off whining about virtual functions
+ redeclared inline for now.
+
+Wed Sep 13 11:13:40 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (store_in_parms): New routine to put things before we
+ put base inits.
+ * cp-tree.h (store_in_parms): Declare it.
+ * decl.c (store_parm_decls): Use it to makr sure the starting of the
+ eh spec comes before base inits.
+ (finish_function): Use sequences instead of the obsolete
+ reorder_insns.
+ * parse.y (fndef): Enhance readability and maintainability. Update
+ to include function_try_block syntax.
+ (function_try_block): Add.
+
+Tue Sep 12 17:43:07 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (convert_harshness): Use comptypes, not ==, to check if
+ TYPE and PARMTYPE are equivalent on a function type.
+
+Tue Sep 12 17:31:33 1995 Douglas Rupp <drupp@cs.washington.edu>
+
+ * Make-lang.in (cc1plus): Removed unnecessary $(exeext).
+
+Mon Sep 11 23:24:07 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Never allocate storage for thrown pointer
+ to objects.
+
+Mon Sep 11 19:36:45 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_catch_block): Pointers to objects come
+ back from catch matching already dereferenced, don't dereference
+ again.
+
+Mon Sep 11 15:46:28 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Only decay the throw expression, don't do
+ any default conversions. This is so that one can throw and catch
+ characters, and not have them match integers.
+
+Mon Sep 11 13:46:45 1995 Mike Stump <mrs@cygnus.com>
+
+ * error.c (dump_aggr_type): Deal with anonymous unions that don't
+ have a TYPE_NAME.
+
+Fri Sep 8 20:40:27 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lex.c (handle_sysv_pragma): Deal with getting a comma from yylex.
+
+Fri Sep 8 15:51:41 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_end_eh_spec): Handle empty EH specifications.
+
+Fri Sep 8 15:27:22 1995 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (expand_start_eh_spec): Declare new routine.
+ (expand_end_eh_spec): Likewise.
+ * decl.c (store_parm_decls): Call expand_start_eh_spec to process
+ exception specifications.
+ * except.c (expand_leftover_cleanups): Remove unused parameter.
+ (expand_end_catch_block): Likewise.
+ (expand_exception_blocks): Likewise.
+ (expand_start_eh_spec): New routine to mark the start of an
+ exception specification region.
+ (expand_end_eh_spec): New routine to mark the end of an exception
+ specification region.
+ (expand_exception_blocks): Call expand_end_eh_spec to process
+ exception specifications.
+
+Fri Sep 8 14:40:48 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * lex.c (do_identifier): Use global binding in preference of
+ dead for local variable.
+
+Wed Sep 6 19:32:59 1995 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (build_exception_variant): Remove used first argument.
+ * decl.c (duplicate_decls): Likewise.
+ (grokfndecl): Likewise.
+ (revert_static_member_fn): Likewise.
+ * decl2.c (grok_method_quals): Likewise.
+ * tree.c (build_exception_variant): Likewise.
+ * typeck.c (common_type): Likewise.
+ * decl2.c (grokclassfn): After changing the type, call
+ build_exception_variant, if necessary.
+
+Tue Sep 5 15:56:27 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Run cleanups for the throw expression.
+
+Wed Aug 30 15:24:38 1995 Stephen L. Favor <sfavor@tigger.intecom.com>
+
+ * except.c (expand_builtin_throw): Moved gen_label_rtx calls beyond
+ the store_parm_decls call which does initialization in the emit_*
+ code concerning label numbering.
+
+Thu Aug 31 09:01:07 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_internal_throw): Let the frontend be responsible
+ for managing all frontend EH parameters, the backend routine only
+ needs to deal with backend values. type and value are no longer
+ passed to __throw.
+ (init_exception_processing): Likewise.
+ (expand_start_all_catch): Likewise.
+ (expand_end_all_catch): Likewise.
+ (expand_leftover_cleanups): Likewise.
+ (expand_end_catch_block): Likewise.
+ (expand_builtin_throw): Likewise.
+ (expand_throw): Likewise.
+
+Tue Aug 29 15:04:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cp-tree.h (DECL_REAL_CONTEXT): Give the real declaration context
+ for a decl.
+ * decl.c (cp_finish_decl): Use it.
+
+Tue Aug 29 10:30:27 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_internal_throw): Oops, almost forgot type and
+ value are now trees.
+
+Mon Aug 28 17:57:45 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ Fix the attribute handling to make sure they get noted before we
+ create the function's RTL, in case they can affect that.
+ * decl.c (grokfndecl): New arg ATTRLIST. Run
+ cplus_decl_attributes before creating the decl's rtl.
+ (grokdeclarator): New arg ATTRLIST, passed down into grokfndecl.
+ (shadow_tag, groktypename, start_decl, start_method): Pass a
+ NULL_TREE to grokdeclarator's new last arg.
+ * decl2.c (grokfield): New arg ATTRLIST, passed into grokdeclarator.
+ (grokbitfield, grokoptypename): Pass a NULL_TREE to
+ grokdeclarator's new last arg.
+ * except.c (expand_start_catch_block): Likewise.
+ * pt.c (process_template_parm, end_template_decl,
+ do_function_instantiation): Likewise.
+ * cp-tree.h (grokfield): Add arg.
+ (grokdeclarator): Move the prototype from here...
+ * decl.h: ...to here.
+ * lex.c (cons_up_default_function): Pass NULL_TREE to grokfield
+ ATTRLIST argument.
+ * parse.y: Create a list for the grokfield arg where appropriate,
+ and pass it down instead of calling cplus_decl_attributes.
+
+Mon Aug 28 15:07:24 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Always allow turning on exception handling. Allow cross
+ compilations to use EH.
+
+Thu Aug 24 17:39:24 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (saved_pc, saved_throw_type, saved_throw_value): Use
+ trees, instead of rtxs, and don't depend on using special machine
+ dependent registers.
+ (expand_internal_throw): Likewise.
+ (init_exception_processing): Likewise.
+ (expand_start_all_catch): Likewise.
+ (expand_end_all_catch): Likewise.
+ (expand_start_catch_block): Likewise.
+ (expand_leftover_cleanups): Likewise.
+ (expand_end_catch_block): Likewise.
+ (expand_builtin_throw): Likewise.
+ (expand_throw): Likewise.
+
+Wed Aug 23 17:25:51 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (build_expr_type_conversion): Handle conversions to
+ reference types.
+
+Wed Aug 23 15:33:59 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (do_unwind): Work around backend bug with -fpic.
+
+Tue Aug 22 17:20:07 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl2.c (flag_new_for_scope): Add a new mode that follows ANSI
+ for-scoping, but supports (and warns about) old programs.
+ Make the new mode (with value 1) the default.
+ (lang_f_options): The on-value for flag_new_for_scope is now 2.
+ * cp-tree.h (DECL_DEAD_FOR_LOCAL, DECL_ERROR_REPORTED): New macros
+ (DECL_SHADOWED_FOR_VAR): Likewise.
+ * decl.c (struct binding_level): New fields dead_vars_from_for
+ and is_for_scope.
+ (note_level_for_for): New function.
+ (poplevel): Special processing if is_for_scope.
+ (pushdecl): Warn if for-scope variable shadows local.
+ * lex.c (do_identifier): Handle old (non-ANSI) for scoping,
+ and warn if conflicts.
+ * parse.y (FOR): Call note_level_for_for.
+
+Mon Aug 21 10:28:31 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (import_export_inline): Class interface hackery does not
+ apply to synthesized methods.
+
+Sun Aug 20 16:29:00 1995 Mike Stump <mrs@cygnus.com>
+
+ * search.c (virtual_context): Find the right context more often.
+ Solves a `recoverable compiler error, fixups for virtual function'
+ problem.
+
+Sun Aug 20 13:53:24 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_all_catch): Ensure that we always transfer
+ control to the right EH handler, by rethrowing the end label on the
+ region, instead of hoping we are nested and falling through.
+ (expand_leftover_cleanups): Likewise.
+ (end_protect): Since we now rethrow the end label, put a
+ nop after it, so that outer regions are recognized.
+ * init.c (build_vec_delete_1): New routine to handle most of vector
+ deleting, all code moved here from build_vec_delete.
+ (build_array_eh_cleanup): Use build_vec_delete_1 to do all the real
+ work.
+ (expand_vec_init): If the array needs partial destructing, setup an
+ EH region to handle it.
+ (build_vec_delete): Move lots of code to build_vec_delete_1, use
+ build_vec_delete_1 to do the grunt work.
+
+Sat Aug 19 14:25:33 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ Handle decl attributes properly for function definitions without
+ previous attribute-loaded declarations.
+ * decl.c (start_function): New arg ATTRS. Add a call to
+ cplus_decl_attributes with it before we create the RTL.
+ * cp-tree.h (start_function): Update prototype.
+ * parse.y (fn.def1): Pass ATTRS into start_function instead of
+ trying to call cplus_decl_attributes too late. Pass a NULL_TREE
+ for other use.
+ * decl2.c (finish_file): Pass NULL_TREE as fourth arg to
+ start_function.
+ * method.c (synthesize_method): Likewise.
+ * except.c (expand_builtin_throw): Likewise for start on __throw.
+
+Sat Aug 19 13:36:08 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (set_rtti_entry): Turn on -fvtable-thunk -frtti support.
+ This changes -fvtable-thunks vtable layout, so a recompile will be
+ necessary, if you use -fvtable-thunks.
+ (get_vtable_entry): Use n, instead of i to be consistent with the
+ rest of the compiler.
+ (get_vtable_entry_n): Likewise.
+ (add_virtual_function): Add a slot for the tdesc, if -fvtable-thunks
+ are being used.
+ (finish_struct_1): Likewise.
+ (skip_rtti_stuff): New routine to collapse similar code from many
+ different parts of the compiler. I think I got them all.
+ (modify_one_vtable): Use it.
+ (fixup_vtable_deltas1): Likewise.
+ (override_one_vtable): Likewise.
+ * decl2.c (mark_vtable_entries): Likewise.
+ * tree.c (debug_binfo): Likewise.
+ * search.c (expand_upcast_fixups): Likewise.
+ (get_abstract_virtuals_1): Likewise. Use virtuals, instead of tmp to
+ consistent with the rest of the compiler.
+ (get_abstract_virtuals): Likewise.
+ * cp-tree.h (skip_rtti_stuff): New routine, declare it.
+ * gc.c (build_headof): Support -fvtable-thunk and -frtti together.
+ (build_typeid): Likewise.
+ (build_classof): Remove old style way of doing rtti. Remove support
+ for `classof' and `headof'.
+ * gxx.gperf: Likewise.
+ * hash.h: Likewise.
+ * parse.y: Likewise.
+
+Fri Aug 18 17:31:58 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (start_function): Clear ctor_label and dtor_label.
+
+ * class.c (finish_struct_1): Fix handling of access decls.
+
+Tue Aug 15 19:21:54 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_struct): Only do minimal processing here, so it
+ can be used for class template definitions, as well.
+ (finish_struct_1): New function with the rest of the code.
+
+Tue Aug 15 09:46:16 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (prepare_fresh_vtable): On second though, always build the
+ offset (see Aug 10 change), unless -fvtable-thunks is given. It
+ does this by calling the new routine set_rtti_entry.
+ (finish_struct): Likewise.
+ (set_rtti_entry): New routine to update the rtti information at the
+ start of the vtable.
+
+Mon Aug 14 12:21:22 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * error.c (dump_decl, case IDENTIFIER_NODE): Only work on a dtor
+ if it's declared in the C++ language spec.
+ (dump_function_decl): Likewise.
+ (dump_function_name): Likewise.
+ (ident_fndecl): Make sure we got something back from lookup_name.
+ * decl.c (start_function): Likewise.
+
+Fri Aug 11 16:52:15 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Don't call build_new when calling a
+ constructor without an instance.
+
+Thu Aug 10 20:00:17 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (prepare_fresh_vtable): Always build the offset to the
+ complete object, as it doesn't cost much. This allows dynamic_cast
+ to void * to work when -frtti isn't given.
+ (finish_struct): Likewise.
+
+Thu Aug 10 16:31:28 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (build_eh_type): Split out some functionality to new
+ routine named build_eh_type_type.
+ (build_eh_type_type): New routine.
+ (expand_start_catch_block): Use build_eh_type_type, as we never want
+ the dynamic type of the catch parameter, just the static type.
+ Fixes core dumps when -frtti is used and one catchs pointers to
+ classes.
+
+Thu Aug 10 14:55:29 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_builtin_throw): Since we now use normal calling
+ conventions for __throw, we have to remove the first layer off the
+ stack, so that the next context we search for handlers is the outer
+ context instead of the context that had the call to __throw, if we
+ don't immediately find the desired context.
+
+Tue Aug 8 17:44:23 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * tree.c (cp_expand_decl_cleanup): Returns int, not tree.
+ * cp-tree.h: Update.
+
+ * parse.y (template_type_parm): Add support for `typename'.
+
+Tue Aug 8 12:06:31 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_internal_throw): New internal routine to throw a
+ value.
+ (expand_end_all_catch, expand_leftover_cleanups): All throwers
+ changed to use `expand_internal_throw' instead of jumping to throw
+ label.
+ (expand_end_catch_block, expand_throw): Likewise.
+ (throw_label): Removed.
+ (expand_builtin_throw): Changed so that EH parameters are passed by
+ normal function call conventions. Completes Aug 4th work.
+
+Fri Aug 4 17:17:08 1995 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (expand_builtin_throw): Declare it.
+ * decl2.c (finish_file): Call expand_builtin_throw.
+ * except.c (make_first_label): Remove.
+ (init_exception_processing): Don't use a LABEL_REF for throw_label,
+ instead use a SYMBOL_REF, this is so that we don't use LABEL_REFs in
+ other functions that don't really appear in those functions. This
+ solves a problem where cc1plus consumed exponential amounts of
+ memory when -Wall was used.
+ (expand_end_all_catch, expand_leftover_cleanups,
+ expand_end_catch_block, expand_throw): Change all uses of
+ throw_label to match new style.
+ (do_unwind): Rename parameter to inner_throw_label, as it is now
+ different from throw_label. Also, assume that our caller will wrap
+ the passed label with a LABEL_REF, if needed.
+ (expand_builtin_throw): Make external, change so that the generated
+ throw is now a real function.
+ (expand_exception_blocks): Never generate throw code inside another
+ function.
+
+Fri Aug 4 12:20:02 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (grokdeclarator): Move checking of mutable const objects
+ and mutable static objects down, as we might decide during parsing
+ to unset staticp or constp (for example, when const is part of the
+ object being pointed to).
+
+Thu Aug 3 17:13:43 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (output_exception_table_entry): Enhance portability to
+ weird machines.
+ (emit_exception_table): Likewise.
+
+Thu Aug 3 16:41:38 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_ptrmemfunc): Handle casting of pointer to
+ non-virtual member functions.
+
+Wed Aug 2 11:58:25 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_typeid): Strip cv qualifiers so that const T&, T&, T
+ and const T all match.
+
+Wed Aug 2 11:25:33 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (build_eh_type): Strip cv qualifiers so that const T&,
+ T&, T and const T all match.
+
+Tue Aug 1 14:20:16 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Fix up comments, cleanup code and eliminate exceptNode,
+ exceptStack, exceptstack, push_except_stmts, pop_except_stmts,
+ new_except_stack, push_last_insn, pop_last_insn, insn_save_node and
+ InsnSave. Also, numerous speed improvements, and correctness
+ improvements. Double faulting in all situations should now be
+ handled correctly.
+ (expand_start_all_catch): Instead of having many terminate protected
+ regions, just have one.
+ (expand_start_catch_block): No longer have to protect
+ false_label_rtx, as it isn't used for EH region marking.
+ (expand_end_catch_block): Expand out EH cleanups here by using
+ expand_leftover_cleanups.
+ (expand_end_all_catch): Use sequences instead of playing with insn
+ links directly.
+ (expand_exception_blocks): Likewise. Also protect all catch clauses
+ with one terminate region.
+
+Mon Jul 31 13:24:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (report_type_mismatch): Don't talk about an object
+ parameter for non-methods.
+
+Sun Jul 30 13:13:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_struct): Catch private and protected members of
+ anonymous unions here.
+ * decl2.c (finish_anon_union): And here.
+ * parse.y: Instead of here.
+
+ * errfn.c (ARGSLIST): Support passing four args.
+ * error.c (cv_as_string): New function.
+ (cp_printers): Add it.
+ * call.c (build_method_call): Report 'const' at end of pseudo-decl.
+
+ * method.c (report_type_mismatch): Deal with a bad_arg of 0.
+
+ * init.c (expand_aggr_init): Handle volatile objects, too.
+
+Sat Jul 29 13:42:03 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (struct binding_level): Keep list of incomplete decls.
+ (print_binding_level): Use list_length to count them.
+ (pushdecl): Build up the list.
+ (hack_incomplete_structures): Walk it and prune completed decls.
+
+Fri Jul 28 15:26:44 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (comp_target_types): Don't check const and volatile for
+ function types.
+ (comp_ptr_ttypes_real): Likewise.
+
+Thu Jul 27 15:40:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (comp_target_types): Fix.
+
+Thu Jul 27 15:10:48 1995 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (unsave_expr_now, build_unsave_expr,
+ cp_expand_decl_cleanup): Declare new routines.
+ * decl.c (cp_finish_decl, store_parm_decls,
+ hack_incomplete_structures): Change all cals from
+ expand_decl_cleanup to cp_expand_decl_cleanup.
+ * gc.c (protect_value_from_gc): Likewise.
+ * expr.c (cplus_expand_expr): Handle UNSAVE_EXPRs.
+ * tree.c (unsave_expr): New routine to build an UNSAVE_EXPR.
+ (unsave_expr_now): Backend routine used by tree expander.
+ (cp_expand_decl_cleanup): Wrap second argument in an UNSAVE_EXPR to
+ work around a limitation in the backend. The backend uses the
+ cleanups multiple times, on disjoint control flows, so we cannot
+ pass unsaved SAVE_EXPRs to the backend.
+ * tree.def (UNSAVE_EXPR): New tree code.
+ * typeck.c (c_expand_return): Move goto/return code up inside
+ conditional, as we don't always want to do this, we only want to do
+ this when we don't otherwise finish with this control flow.
+
+Thu Jul 27 10:38:43 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (typespec): Only complain about typeof if we're not
+ getting it from a system header.
+
+Thu Jul 27 10:26:23 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ Clean up prefix attribute handling.
+ * parse.y (reserved_declspecs): Link prefix attributes with declspecs.
+ (declmods): Likewise.
+ (all rules that reference typed_declspecs and declmods): Call
+ split_specs_attrs or strip_attrs to separate declspecs and attrs.
+ (lang_extdef): Delete resetting of prefix_attributes.
+ (template_def, notype_declarator rule): Use NULL_TREE for
+ prefix_attributes.
+ (condition): Use NULL_TREE for prefix_attributes.
+ (setattrs): Deleted.
+ (nomods_initdcl0): Set prefix_attributes to NULL_TREE.
+ (component_decl): Delete resetting of prefix_attributes.
+ (component_decl_1, notype_components rule): Use NULL_TREE for
+ prefix_attributes.
+ (simple_stmt): Delete resetting of prefix_attributes.
+
+Mon Jul 24 13:37:53 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (convert_harshness): Deal with reference conversions before
+ others. Actually do array->pointer decay. Call comp_target_types
+ with pointer types rather than their targets.
+
+ * typeck.c (comp_target_types): Avoid assigning D const * to B *.
+
+Mon Jul 24 08:54:46 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * pt.c (to_be_restored): Move decl to global scope.
+
+Sat Jul 22 12:22:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_decl): Put back clearing of DECL_IN_AGGR_P.
+
+Fri Jul 21 17:09:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokdeclarator): Downgrade error about 'extern int A::i'
+ to pedwarn.
+
+ * pt.c (instantiate_template): Also avoid instantiation if the
+ function has already been declared to be a specialization.
+
+ * decl2.c (check_classfn): Ignore cname argument, and return the
+ matching function.
+
+ * decl.c (start_decl): Handle declarations of member functions
+ outside of the class (i.e. specialization declarations).
+
+Thu Jul 20 10:34:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_struct): Don't mess with the type of bitfields.
+
+ * various.c: s/TYPE_POINTER_TO/build_pointer_type/.
+
+Thu Jul 20 01:43:10 1995 Mike Stump <mrs@cygnus.com>
+
+ * init.c (expand_aggr_init): Assume LOOKUP_ONLYCONVERTING if init
+ is not a parameter list (TREE_LIST).
+ (expand_default_init): If LOOKUP_ONLYCONVERTING is set, then set
+ LOOKUP_NO_CONVERSION so that we don't allow two-level conversions,
+ but don't set it otherwise.
+
+Wed Jul 19 20:32:01 1995 Mike Stump <mrs@cygnus.com>
+
+ * init.c (expand_default_init): Don't allow two-level conversions
+ during construction.
+
+Wed Jul 19 18:06:37 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_headof): The type of dyncasting to a pointer to cv
+ void, should be pointer to cv void.
+
+Wed Jul 19 17:25:43 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_dynamic_cast): Allow casting in const.
+
+Wed Jul 19 16:34:27 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_const_cast): If we are passed error_mark_node,
+ return it.
+
+Wed Jul 19 15:24:48 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * class.c (push_nested_class): Make sure TYPE is non-nil.
+
+ * cvt.c (type_promotes_to): Watch for error_mark_node on the
+ incoming TYPE.
+
+Wed Jul 19 13:23:12 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu>
+
+ * cp-tree.h (SIGTABLE_VT_OFF_NAME): Renamed from SIGTABLE_OFFSET_NAME.
+ (SIGTABLE_VB_OFF_NAME): New macro.
+ (vt_off_identifier): Renamed from offset_identifier.
+ (vb_off_identifier): Added extern declaration.
+
+ * decl.c (vt_off_identifier): Renamed from offset identifier.
+ (vb_off_identifier): New variable to hold the identifier for the
+ sigtable field vb_off.
+ (init_decl_processing): Initialize vb_off_identifier.
+ Renamed vt_off_identifier from offset_identifier.
+ * sig.c (build_signature_method_call): Renamed offset_identifier and
+ local variable offset to vt_off_identifier and vt_off, respectively.
+ * sig.c (build_signature_table_constructor): Renamed offset to vt_off.
+
+ * decl.c (init_decl_processing): Add vb_off field to
+ sigtable_entry_type. Reorder fields so that pfn gets properly
+ aligned at a 64 bit boundary on the Alpha.
+ * sig.c (build_signature_table_constructor): Build the constructor
+ according to the new layout. Set the vb_off field to -1 for now.
+
+ * decl.c (init_decl_processing): Align sigtable_entry_type on word
+ boundaries instead of double word boundaries to save space.
+
+Tue Jul 18 16:58:37 1995 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (cp_convert): Always call build_cplus_new for a ctor.
+
+Tue Jul 18 14:24:53 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (opt.component_decl_list): Only forbid private/protected
+ in anonymous unions. We need to make this know when the type is
+ defined for an object, to not give the error.
+
+Mon Jul 17 14:22:44 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (opt.component_decl_list): Don't allow access control
+ as private or protected for union members.
+
+Sun Jul 16 14:01:00 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * lex.c (check_newline): For 'p' case, move goto skipline line to
+ before end brace for 'pragma'.
+
+Fri Jul 7 13:55:58 1995 Mike Stump <mrs@cygnus.com>
+
+ * g++.1: Tiny updates.
+
+Fri Jul 7 13:05:20 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (cp_finish_decl): Only destruct local static variables if
+ they are constructed, and only construct the first time control
+ passes completely through its declaration (if not initialized with a
+ constant-expression).
+ (expand_static_init): Likewise.
+
+Wed Jul 5 14:05:04 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (comptypes, case OFFSET_REF): If either offset basetype
+ is a TEMPLATE_TYPE_PARM, give a match.
+
+Fri Jun 30 15:42:57 1995 Mike Stump <mrs@cygnus.com>
+
+ * method.c (build_overload_value): Handle encoding of null pointer
+ constants (or any pointer with a constant numeric value) for
+ templates.
+
+Fri Jun 30 13:45:51 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (convert_harshness): Add QUAL_CODE when we're faced with
+ const vs non-const for void conversions.
+
+Fri Jun 30 10:19:52 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_all_catch): Fix problem with finding an
+ outer nested try block when there is no code to separate it from an
+ inner try block.
+
+Fri Jun 30 02:22:26 1995 Mike Stump <mrs@cygnus.com>
+
+ * search.c (dfs_pushdecls): Consume 2 or 3 orders of magnitude less
+ memory please when virtual bases are used.
+
+Thu Jun 29 19:03:47 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (build_vbase_path): Avoid testing things that cannot be
+ null to see if they are null.
+ * cvt.c (convert_pointer_to_vbase): Remove code that doesn't work.
+ * decl.c (finish_function): Pass a type into the new
+ convert_pointer_to_vbase instead of a binfo.
+ * search.c (convert_pointer_to_vbase): Rewritten to use get_vbase
+ and convert_pointer_to_real.
+ (expand_indirect_vtbls_init): Use convert_pointer_to_vbase instead
+ of the more cryptic call to get_vbase.
+
+Thu Jun 29 09:35:05 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (BOOL_TYPE_SIZE): Fix broken SLOW_BYTE_ACCESS check.
+
+Thu Jun 29 03:43:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (instantiate_template): Don't strip 'this' twice.
+
+ * pt.c (coerce_template_parms): Allow null pointer constants.
+
+ * decl.c (revert_static_member_fn): But only if DECL_ARGUMENTS is
+ set.
+
+Wed Jun 28 18:39:03 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (revert_static_member_fn): Also remove 'this' from
+ DECL_ARGUMENTS.
+ * decl2.c (check_classfn): Don't revert this function until we get a
+ match.
+
+Wed Jun 28 14:07:27 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (component_decl): Clear PREFIX_ATTRIBUTES here.
+
+Wed Jun 28 11:05:13 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_file): Handle global vector news.
+ * init.c (build_new): Encode vector news so that later we will know
+ how many elements there are.
+
+Mon Jun 26 13:38:06 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * expr.c (cplus_expand_expr): Don't mess with temp slots.
+
+ * decl2.c (warn_if_unknown_interface): Don't crash if tinst_for_decl
+ returns null.
+
+ * decl2.c (check_classfn): Use revert_static_member_fn.
+ * decl.c (revert_static_member_fn): Diagnose static member functions
+ declared const or volatile.
+
+ * decl2.c (grokfield): Check for missing default args here, too.
+ (check_default_args): Function to do the checking.
+ * decl.c (pushdecl): Use it.
+
+ * decl.c (pushdecl): Don't warn about shadowing a member of `this'
+ if there is no `this'.
+
+Sun Jun 25 11:34:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Downgrade 'called before definition'
+ to a warning, as it ought to go away after Monterey.
+
+Sat Jun 24 14:18:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (coerce_template_parms): Don't do extra checking on pointer
+ to member arguments.
+
+ * class.c (finish_struct): const and reference members don't prevent
+ a class from being an aggregate.
+
+ * class.c (finish_struct): Signatures are always aggregates.
+
+Fri Jun 23 17:20:29 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (check_classfn): Improve error message.
+
+ * pt.c (tsubst): Handle PROMOTE_PROTOTYPES.
+
+Thu Jun 22 01:50:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (comptypes): Don't ignore method quals.
+
+ * class.c (finish_struct): Non-abstract virtuals are always USED.
+
+ * decl.c (build_ptrmemfunc_type): The underlying union type isn't
+ IS_AGGR_TYPE, either.
+ * class.c (finish_struct): Use CLASSTYPE_NON_AGGREGATE instead.
+ * cp-tree.h: Likewise.
+
+ * cp-tree.h (lang_type): Add aggregate.
+ (CLASSTYPE_AGGREGATE): New macro.
+ (TYPE_NON_AGGREGATE_CLASS): Likewise.
+ * class.c (finish_struct): Determine whether a class is an
+ aggregate.
+ * decl.c (cp_finish_decl): Check TYPE_NON_AGGREGATE_CLASS instead of
+ TYPE_NEEDS_CONSTRUCTING.
+ * typeck2.c (digest_init): Check TYPE_NON_AGGREGATE_CLASS for
+ subobjects, too.
+
+ * pt.c (tsubst, PARM_TYPE): Propagate DECL_ARTIFICIAL.
+
+ * decl.c (start_function): For pre-parsed functions, layout all of
+ the parm decls again.
+ (grokvardecl): TREE_PUBLIC depends on DECL_THIS_EXTERN, not
+ DECL_EXTERNAL.
+
+ * pt.c (coerce_template_parms): Improve checking for invalid
+ template parms.
+
+Wed Jun 21 12:01:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Forbid declaration of a static member
+ with the same name as its enclosing class.
+
+Mon Jun 19 10:28:14 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_function): Clear current_class_decl.
+
+ * typeck.c (build_conditional_expr): Use convert (boolean_type_node
+ instead of truthvalue_conversion.
+
+ * class.c (finish_struct): A data member with the same name as the
+ class doesn't suppress constructors.
+
+Fri Jun 16 18:11:39 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu>
+
+ * decl.c (start_function): If current_class_decl is a signature
+ pointer, don't dereference it but set C_C_D to current_class_decl.
+
+Fri Jun 16 17:06:28 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (duplicate_decls): Complain about virtual functions
+ redeclared to be inline.
+
+Fri Jun 16 13:20:38 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (get_unique_name): New routine to name unnamed namespaces.
+ (push_namespace): Use get_unique_name for naming unnamed namespaces.
+
+Thu Jun 15 15:00:41 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y: Call cplus_decl_attributes with prefix_attributes where
+ appropriate.
+
+Wed Jun 14 19:24:49 1995 Mike Stump <mrs@cygnus.com>
+
+ * search.c (get_vbase): New routine to switch hierarchies from the
+ CLASSTYPE_VBASECLASSES to the normal one.
+ (expand_indirect_vtbls_init): Use get_vbase to figure out how we
+ want to convert to a vbase pointer.
+
+Mon Jun 12 17:50:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (instantiate_class_template): Add the new instantiation to
+ template_classes.
+ (do_pending_expansions): Call instantiate_member_templates on all of
+ the classes in template_classes.
+
+Mon Jun 12 12:36:59 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (complete_array_type): Fill in the TYPE_DOMAIN of our
+ TYPE_MAIN_VARIANT if it is not filled in.
+ * init.c (build_delete): If the TYPE_DOMAIN is not set, give an
+ error instead of core dumping.
+
+Mon Jun 12 10:41:40 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (can_convert): Also check for distance > 0.
+ (can_convert_arg): Likewise.
+ (user_harshness): Likewise.
+
+Fri Jun 9 19:17:21 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * g++.c (MATH_LIBRARY): Provide default.
+ (main): Always link with the math library if we link with libstdc++.
+
+ * decl.c (start_function): Complain about redefinition of a function
+ even when the pending_inline version is compiled after the other
+ version.
+
+Thu Jun 8 15:44:38 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * gc.c (build_dynamic_cast): Build up a reference to a parameter of
+ aggregate type.
+
+Wed Jun 7 15:31:57 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_vec_delete): Resolve an offset ref before we try to
+ use it.
+
+Wed Jun 7 14:19:32 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): If the class lacks a constructor or
+ assignment operator, return error_mark_node.
+ (common_type): Use build_cplus_array_type.
+
+Tue Jun 6 09:41:27 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (dont_allow_type_definitions): New variable set when types
+ cannot be defined.
+ (finish_struct): Use it.
+ * cp-tree.h (dont_allow_type_definitions): Define it.
+ * parse.y (primary, handler_seq): Set it.
+
+Mon Jun 5 18:49:38 1995 Mike Stump <mrs@cygnus.com>
+
+ * method.c (build_opfncall): Use DECL_CHAIN, not TREE_CHAIN for
+ results from lookup_fnfields. Always give warning/error on bad
+ code.
+
+Mon Jun 5 11:39:37 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (member_init_ok_or_else): Don't allow initialization of
+ an ancestor's member from within a constructor.
+
+Mon Jun 5 11:20:34 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu>
+
+ * sig.c (build_signature_table_constructor): Use DECL_CONTEXT
+ instead of DECL_CLASS_CONTEXT for calculating the vfield offset so
+ abstract virtual functions are handled correctly.
+
+ * sig.c (build_signature_table_constructor): Store the correct
+ delta in signature table entries. It does not yet work for
+ classes with virtual base classes as implementations of signatures.
+ (build_signature_method_call): Add the delta to the object_ptr
+ before generating the function call.
+
+ * call.c (build_method_call): Make instance_ptr the signature
+ pointer itself instead of dereferencing the optr.
+ * sig.c (build_signature_method_call): Dereference the optr for the
+ direct and virtual calls.
+
+ * sig.c (build_signature_table_constructor): Make the tag for
+ default implementations -1 instead of 2.
+ (build_signature_method_call): Change the generated conditional
+ expression correspondingly.
+
+ * sig.c (build_signature_pointer_constructor): Deleted the sorry
+ message that said we can't handle multiple inheritance for
+ implementations of signatures
+ (build_signature_method_call): Use the offset from the sigtable
+ entry instead of the vptr field from the signature pointer for
+ building a virtual function call.
+
+ * class.c (build_vfn_ref): Deleted signature specific code, we don't
+ call this function anymore from build_signature_method_call.
+
+ * cp-tree.h (SIGNATURE_VPTR_NAME): Deleted. We use the right vptr
+ field in the object now instead of in the signature pointer/ref.
+ (build_vptr_ref): Deleted extern declaration.
+ * sig.c (build_vptr_ref): Deleted.
+ (build_signature_pointer_or_reference_type): Deleted construction of
+ the vptr field.
+ (build_signature_pointer_constructor): Deleted initialization of/
+ assignment to the vptr field.
+
+ * sig.c (build_signature_table_constructor): Convert the signature
+ table entry fields to their correct types.
+
+ * sig.c (build_signature_table_constructor): Don't call digest_init
+ for the fields of a sigtable entry, it's wasted time.
+
+ * sig.c (build_signature_table_constructor): Correctly set the
+ offset and index fields of a sigtable entry. Build the constructor
+ the way digest_init does, digest_init can't handle initializing an
+ anonymous union inside a struct.
+ (build_signature_method_call): Use the index field instead of the
+ delta field to get the vtable index.
+
+ * decl.c (init_decl_processing): Fix number of fields for building
+ sigtable_entry_type.
+
+ * cp-tree.h (tag_identifier, offset_identifier): Added extern decls.
+ (SIGTABLE_CODE_NAME): Renamed to SIGTABLE_TAG_NAME.
+ (SIGTABLE_PFN_NAME): Deleted, we'll use VTABLE_PFN_NAME instead.
+ * decl.c (tag_identifier, offset_identifier): New variables to
+ hold the identifiers for the sigtable fields tag and offset.
+ (init_decl_processing): Initialize these variables.
+ (init_decl_processing): Use these variables to build the
+ sigtable_entry_type structure. Rename the code and offset fields
+ to tag and delta, respectively; add offset and index fields. Changed
+ types of fields from short_integer_type_node to delta_type_node.
+ * sig.c (build_signature_table_constructor): Rename code and offset
+ to tag and delta, respectively.
+ (build_signature_method_call): Likewise. Use above variables.
+
+Thu Jun 1 17:03:51 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (lookup_name_real): Don't try to look anything up in an
+ erroneous object.
+
+Fri Jun 2 10:30:14 1995 Mike Stump <mrs@cygnus.com>
+
+ * method.c (build_overload_int): New routine. Break out
+ functionality from build_overload_value so we can reuse it.
+ (build_overload_value): Handle pointer to member functions as value
+ parameters for templates.
+ (build_overload_identifier): Since template parameters are shared
+ among all instantiations, we have to substitute in the real types
+ in TREE_TYPE (parm).
+ pt.c (coerce_template_parms): Likewise.
+ (push_template_decls): Likewise.
+ (grok_template_type): Deleted as template parameters are shared
+ among all instantiations.
+
+Wed May 31 19:10:32 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (grokdeclarator): Always give errors on constant overflow
+ for array indices.
+
+Wed May 31 11:39:43 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (commonparms): Don't abort if simple_cst_equal returns < 0.
+ (build_c_cast): Don't tack on a NON_LVALUE_EXPR when casting to
+ reference type.
+ (build_indirect_ref): Fix check for *&.
+
+Fri Jun 16 06:54:03 1995 Mike Stump <mrs@cygnus.com>
+
+ * Version 2.7.0 released.
+
+Fri Jun 16 15:07:29 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (DEMANGLER_PROG): Add LIBS.
+
+Thu Jun 15 15:00:41 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (define_function): Don't set DECL_INTERFACE_KNOWN.
+
+Wed Jun 7 20:00:31 1995 Mike Stump <mrs@cygnus.com>
+
+ * *.[chy]: Change all callers of finish_decl to cp_finish_decl.
+ * decl.c (finish_decl): New routine to handle call backs from the
+ mid end (declare_hidden_char_array).
+
+Wed Jun 7 19:02:50 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_function): Handle setting C_C_D here.
+ (set_C_C_D): Removed.
+ (struct saved_scope): Remove class_decl.
+ (push_to_top_level): Don't save current_class_decl.
+ (pop_from_top_level): Don't restore current_class_decl or C_C_D.
+ (struct cp_function): Add C_C_D.
+ (push_cp_function_context): Save C_C_D.
+ (pop_cp_function_context): Restore C_C_D.
+
+Fri Jun 2 11:05:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (set_C_C_D): New function. suspend_momentary before
+ building C_C_D.
+ (pop_from_top_level): Call it.
+ (start_function): Likewise.
+ (pop_cp_function_context): Likewise.
+
+ * class.c, cp-tree.h, decl.c, decl2.c, parse.y: Lose all references
+ to current_vtable_decl, CLASSTYPE_INST_VAR and CLASSTYPE_VTBL_PTR.
+
+ * decl.c (push_cp_function_context): Save current_class_decl.
+ (pop_cp_function_context): Restore current_class_decl and set C_C_D.
+ (pop_from_top_level): Don't use CLASSTYPE_INST_VAR to set C_C_D.
+ (start_function): Likewise.
+
+ * class.c (popclass): Don't mess with current_class_decl,
+ current_vtable_decl, or C_C_D.
+
+Mon May 29 12:45:10 1995 Paul Eggert <eggert@twinsun.com>
+
+ * Make-lang.in (c++.mostlyclean): Remove $(DEMANGLER_PROG).
+
+Wed May 24 15:55:18 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (duplicate_decls): Check simple_cst_equal result against 0.
+ * decl2.c (finish_anon_union): Likewise.
+ * method.c (largest_union_member): Likewise.
+
+Wed May 24 14:41:11 1995 H.J. Lu <hjl@nynexst.com>
+
+ * Make-lang.in (cxxmain.o): Replace single quotes with backslashes.
+
+Mon May 22 17:38:48 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (g++, g++-cross, cc1plus, DEMANGLER_PROG):
+ Use $@ instead of output name so works even if have .exe.
+ (cxxmain.o): Use cp if ln -s fails.
+ (c++.install-man): Use $(exeext) in executable names.
+ (c++.mostlyclean, stage[1-4]): Use $(objext) in object file names.
+ * Makefile.in (../cc1plus): Use $(exeext) in name of executable.
+
+Wed May 24 01:39:03 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): Parms can be null, duh.
+
+Tue May 23 01:32:09 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * call.c (build_method_call): If convert_arguments failed, just bail.
+
+Fri May 19 10:31:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (convert_force): Pass LOOKUP_NORMAL to cp_convert.
+
+ * tree.c (copy_to_permanent): Oops.
+
+Fri May 19 10:01:07 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (break_out_target_exprs): Add decl.
+
+Thu May 18 13:02:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_function): Move *all* interface handling stuff after
+ the pushdecl.
+
+ * tree.c (mapcar): Renamed from make_deep_copy and generalized.
+ (perm_manip): Return t if permanent, otherwise 0.
+ (copy_to_permanent): Use them.
+ (bot_manip): Helper for break_out_target_exprs.
+ (break_out_target_exprs): New function. Uses mapcar.
+
+ * typeck.c (convert_arguments): Use it.
+
+ * method.c (hack_identifier): Use convert_from_reference to
+ dereference a reference.
+
+Wed May 17 17:54:54 1995 Mike Stump <mrs@cygnus.com>
+
+ * call.c (convert_harshness): Move reference bashing before pointer
+ to member bashing.
+
+Wed May 17 16:57:53 1995 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (convert_to_reference): Only complain, if complaints are
+ wanted.
+ * typeck.c (build_function_call_real): Likewise. If
+ LOOKUP_SPECULATIVELY is set and something won't work, return
+ NULL_TREE.
+ * cvt.c (cp_convert): Likewise. Pass flags down to build_method_call.
+ (convert): Pass LOOKUP_NORMAL to cp_convert.
+ * typeck.c (convert_for_assignment): Likewise.
+ (convert_force): Pass LOOKUP_COMPLAIN to cp_convert.
+ (convert_arguments): Get out early if we get an error_mark_node.
+ (convert_for_initialization): Use cp_convert instead of convert so
+ that we can pass flags down.
+ * cp-tree.h (LOOKUP_SPECULATIVELY): Added documentation.
+
+Wed May 17 01:43:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck2.c (store_init_value): Don't take the MAIN_VARIANT of the
+ decl type.
+
+ * class.c (finish_struct): Don't complain about a class with no
+ user-defined constructors but with a member that has no default
+ constructor, as this is OK for aggregates.
+
+ * expr.c (cplus_expand_expr, NEW_EXPR): If this is an explicit
+ constructor call, mark slot addressable.
+
+Tue May 16 18:37:51 1995 Douglas Rupp <drupp@cs.washington.edu>
+
+ * g++.c: Changed WINNT to _WIN32.
+
+Tue May 16 12:40:16 1995 Jason Merrill <jason@lisa.cygnus.com>
+
+ * lex.c (handle_sysv_pragma): Don't use token_buffer.
+
+Tue May 16 12:05:26 1995 Mike Stump <mrs@cygnus.com>
+
+ * call.c (resolve_scope_to_name): Add initial semantic support for
+ namespaces.
+ * class.c (finish_struct): Likewise.
+ * cp-tree.h (NAMESPACE_LEVEL): Likewise.
+ * cvt.c (build_up_reference, convert_to_reference): Likewise.
+ * decl.c (binding_level::namespace_p, suspend_binding_level): Likewise.
+ (resume_binding_level, toplevel_bindings_p): Likewise
+ (namespace_bindings_p, declare_namespace_level): Likewise.
+ (resume_level, push_namespace, pop_namespace): Likewise.
+ (pop_everything, pushtag, duplicate_decls, pushdecl): Likewise.
+ (implicitly_declare, lookup_namespace_name): Likewise.
+ (lookup_name_real, start_decl, make_temporary_for_reference): Likewise.
+ (obscure_complex_init, finish_decl, expand_static_init): Likewise.
+ (grokvardecl, grokdeclarator, parmlist_is_exprlist): Likewise.
+ (store_parm_decls, hack_incomplete_structures): Likewise.
+ * decl2.c (get_temp_name, finish_anon_union): Likewise.
+ (current_namespace, push_namespace, pop_namespace): Likewise.
+ (do_namespace_alias, do_toplevel_using_decl): Likewise.
+ (do_class_using_decl): Likewise.
+ * error.c (dump_decl): Likewise.
+ * init.c (build_member_call, build_offset_ref): Likewise.
+ * lex.c (identifier_type): Likewise.
+ * parse.y (lang_extdef, using_decl, extdef): Likewise.
+ (component_decl_1, nested_name_specifier_1): Likewise.
+ * spew.c (yylex): Likewise.
+ * tree.def (NAMESPACE_DECL): Likewise.
+
+Tue May 16 11:55:35 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (push_overloaded_decl): Return the new decl even if it
+ can't be pushed.
+
+Tue May 16 11:00:37 1995 Jason Merrill <jason@lisa.cygnus.com>
+
+ * typeck.c (decay_conversion): Split out from default_conversion.
+ (default_conversion): Call it.
+ (build_binary_op): Likewise.
+ (build_binary_op_nodefault): Use decay_conversion for truth ops.
+
+Mon May 15 12:47:56 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (warn_extern_redeclared_static): This is a pedwarn.
+ (duplicate_decls): Always use the old decl's linkage info. Don't
+ play with linkage of consts.
+ (pushdecl): Don't play with linkage of consts.
+ (redeclaration_error_message): Don't complain about an old public
+ decl and a new non-public decl here.
+ (grokvardecl): Handle linkage of consts here.
+ (grokdeclarator): An 'extern inline' is public. Pass constp to
+ grokvardecl.
+ (start_function): Wait until after the pushdecl to do some linkage
+ stuff.
+
+ * decl2.c (import_export_vtable): Make duplicates weak rather than
+ static if supported.
+ (import_export_inline): Likewise.
+ * pt.c (do_pending_expansions): Likewise.
+
+ * class.c (build_vbase_path): flag_assume_nonnull_objects only
+ affects reference conversion.
+
+ * init.c (emit_base_init): Build up an RTL_EXPR and add it to
+ rtl_expr_chain.
+ * decl.c, decl2.c: s/base_init_insns/base_init_expr/.
+
+Tue May 16 07:06:28 1995 Paul Eggert <eggert@twinsun.com>
+
+ * method.c (numeric_output_need_bar): Renamed from misspelling.
+
+ * typeck.c (build_ptrmemfunc): Fix misspellings in messages.
+
+Sun May 14 10:26:22 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * lang-options.h, lang-specs.h: New files.
+
+Thu May 11 00:31:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (default_conversion): Don't check for BLKmode before
+ pulling out the decl_constant_value.
+
+ * decl.c (start_function): Clear named_labels and shadowed_labels.
+
+ * typeck.c (build_function_call_real): Also synthesize methods here.
+
+Wed May 10 00:55:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_file): Synthesize exported methods before the
+ reconsider loop.
+
+ * parse.y: Move declaration of flag_new_for_scope to file scope.
+
+Tue May 9 19:10:33 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c: Add flag_new_for_scope for new -ffor-scope flag.
+ * parse.y (FOR): Conditionalize the pushing and popping of scope for
+ the for-init-statement upon the new flag_new_for_scope.
+ * parse.y (try_block): Simplify and use compstmt.
+
+Mon May 8 12:41:52 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (define_function): Mark function decl artificial.
+
+Sun May 7 00:51:28 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (simple_stmt, FOR): Put back push/pop for condition scope.
+
+ * decl2.c (grokclassfn): DECLs don't have cv-qualified types.
+ * tree.c (build_cplus_method_type): Likewise.
+
+ * cp-tree.h (SET_DECL_ARTIFICIAL): Just set DECL_ARTIFICIAL to 1.
+
+ * typeck.c (build_function_call_real): If convert_arguments failed,
+ just bail.
+ (convert_arguments): If one of the arguments is error_mark_node,
+ just bail.
+
+Sat May 6 02:39:41 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (duplicate_decls): Don't check DECL_NOT_REALLY_EXTERN for
+ decls that don't include it.
+
+Fri May 5 14:23:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (duplicate_decls): Decls that have DECL_INTERFACE_KNOWN or
+ DECL_NOT_REALLY_EXTERN set aren't extern decls.
+
+ * typeck.c (build_indirect_ref): Don't call default_conversion for a
+ parameter of reference_type.
+ * cvt.c (convert_from_reference): Just use build_indirect_ref.
+
+ * pt.c (do_type_instantiation): Only instantiate member functions
+ that actually come from templates.
+
+Fri May 5 09:46:05 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y: Generalized cleanup of poplevels, and compound statements
+ and compound statements in try blocks. Rewritten `for' rule so that
+ the scope of variables declared in the for clause is shortened to
+ span just to the end of the statement, instead of the whole
+ containing block.
+
+Fri May 5 00:37:14 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (convert_harshness): Handle pointers to members better.
+
+Thu May 4 16:00:26 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (delete_sanity): Do access control here.
+ * init.c (build_delete): Instead of here.
+
+ * Make-lang.in: Build c++filt.
+
+Wed May 3 02:59:53 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (cplus_decl_attributes): If we just modified a TYPE_DECL,
+ update our IDENTIFIER_TYPE_VALUE.
+
+Fri Apr 28 07:58:41 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * lex.c (cons_up_default_function): Fix linkage of #pragma
+ implemented functions.
+
+Thu Apr 27 16:56:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (build_overload_name): Simplify and fix repeated type
+ folding.
+
+ * decl.c (grokdeclarator): Prohibit pointers to void or reference
+ members.
+
+Thu Apr 27 09:49:07 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck2.c (process_init_constructor): Make sure initializers are
+ fully digested.
+
+Thu Apr 27 01:11:55 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * lex.c (cons_up_default_function): Always defer synthesis.
+
+Thu Apr 27 00:20:37 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (mark_inline_for_output): Don't play with pending_inline
+ stuff.
+
+Wed Apr 26 17:48:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (user_harshness): New function; like build_type_conversion,
+ but doesn't actually build anything.
+ (compute_conversion_costs): Use it instead of build_type_conversion.
+
+Wed Apr 26 17:11:25 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_function_call_real): Improve error message for
+ calling a non-function.
+
+ * method.c (hack_identifier): Lose check for calling a data member.
+
+Wed Apr 26 16:59:13 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck2.c (build_functional_cast): Remove very old cruft.
+ Seems like good code is generated without it.
+
+Wed Apr 26 00:47:16 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (do_build_assign_ref): Fix handling of anonymous unions.
+ (do_build_copy_constructor): Likewise.
+
+ * parse.y (simple_stmt, SWITCH): Call {push,pop}_switch.
+
+ * decl.c (push_switch): New function.
+ (pop_switch): Likewise.
+ (define_case_label): Check for jumping over initialization.
+
+ * call.c (build_method_call): Check for an inline function being
+ called before its definition has been seen.
+ * typeck.c (build_function_call_real): Likewise.
+
+ * decl.c (duplicate_decls): Check for a function being redeclared
+ inline after its address has been taken.
+
+ * typeck.c (build_conditional_expr): Handle related class lvalues.
+
+Tue Apr 25 13:20:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (do_pending_expansions): Don't expand unused templates.
+
+ * parse.y (component_decl): Accept a lone semicolon.
+
+Tue Apr 25 00:25:56 1995 Jason Merrill <jason@rtl.cygnus.com>
+
+ * call.c (build_method_call): Don't allow an RTL_EXPR to serve as the
+ object parameter anymore.
+
+ * expr.c (cplus_expand_expr): Don't create RTL_EXPRs with no insns.
+
+Mon Apr 24 12:35:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (simple_stmt, decl case): Clear prefix_attributes.
+ (lang_extdef): Likewise.
+
+ * parse.y (maybe_parmlist): New rule for use in declarators where
+ this could either be a list of expressions or parameters. Calls
+ suspend_momentary before deciding which.
+ (direct_after_type_declarator): Use it.
+ (complex_direct_notype_declarator): Use it.
+
+ * pt.c (tsubst): Propagate attributes const and noreturn.
+
+ * typeck.c (build_modify_expr): If warn_synth, call build_opfncall
+ before doing the default thing.
+
+Thu Apr 27 21:49:36 1995 Doug Evans <dje@cygnus.com>
+
+ * typeck.c (common_type): Call lookup_attribute instead of
+ value_member.
+
+Tue Apr 25 18:07:43 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in: Change "realclean" to "maintainer-clean".
+
+Sun Apr 23 12:32:38 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_file): Fix broken linked list handling.
+
+Fri Apr 21 18:08:43 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_base_struct): Don't set TYPE_HAS_COMPLEX_*_REF
+ as often.
+ (finish_struct): Likewise.
+
+ * various: Use TYPE_HAS_TRIVIAL_* instead of TYPE_HAS_COMPLEX_*.
+
+ * cp-tree.h (TYPE_HAS_TRIVIAL_INIT_REF): New macro.
+ (TYPE_HAS_TRIVIAL_ASSIGN_REF): New macro.
+
+Fri Apr 21 15:52:22 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * typeck.c (c_expand_return): Only expand a returned TARGET_EXPR if
+ it is of the same type as the return value.
+
+Fri Apr 21 03:01:46 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_file): Reconsider if synthesizing a method wrote
+ out its assembly.
+
+ * typeck.c (convert_for_initialization): Don't call a trivial copy
+ constructor.
+
+ * typeck2.c (store_init_value): Only abort if the type has a
+ non-trivial copy constructor.
+
+ * typeck.c (c_expand_return): If we're returning in a register and
+ the return value is a TARGET_EXPR, expand it. Only do
+ expand_aggr_init if we're returning in memory.
+ (expand_target_expr): Function to expand a TARGET_EXPR.
+ (build_modify_expr): Use it.
+
+ * tree.c (build_cplus_new): Layout the slot.
+
+ * expr.c (cplus_expand_expr): Use expand_call to expand the call
+ under a NEW_EXPR, so the target is not discarded.
+
+Thu Apr 20 14:59:31 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_dynamic_cast): Tighten error checking.
+
+Thu Apr 20 11:23:54 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * expr.c (cplus_expand_expr): Only abort if the returned target is
+ different from what we expected if the type has a non-trivial copy
+ constructor.
+
+ * decl2.c (cplus_decl_attributes): Attributes applied to a template
+ really apply to the template's result.
+
+ * tree.c (lvalue_p): Check IS_AGGR_TYPE instead of TREE_ADDRESSABLE
+ to decide whether to consider a CALL_EXPR an lvalue.
+
+ * class.c (finish_struct_bits): Only set TREE_ADDRESSABLE if the
+ type has a non-trivial copy constructor.
+
+ * decl.c (start_function): If interface_known, unset
+ DECL_NOT_REALLY_EXTERN on the function.
+
+Wed Apr 19 16:53:13 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (do_function_instantiation): Handle explicit instantiation of
+ member functions.
+ (do_type_instantiation): Handle 'inline template class foo<int>',
+ meaning just spit out the vtable.
+
+ * lex.c (cons_up_default_function): Set DECL_NOT_REALLY_EXTERN on
+ the consed functions.
+
+ * decl2.c (import_export_inline): Set DECL_INTERFACE_KNOWN.
+
+Wed Apr 19 16:28:17 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c, class.c, decl2.c, gc.c, init.c, parse.y, pt.c, search.c,
+ typeck.c: Include output.h.
+
+Wed Apr 19 14:57:21 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu>
+
+ * call.c (build_method_call): Allow a signature member functions to
+ be called from a default implementation.
+
+Wed Apr 19 10:21:17 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c (finish_repo): Remember what directory we are in.
+
+ * search.c (expand_upcast_fixups): Don't mess with abort_fndecl.
+
+ * repo.c: Use obstacks instead of fixed-size buffers. Don't spit
+ out the second copy of the symbol name. Don't remember COLLECT_GCC.
+
+Wed Apr 19 02:32:40 1995 Mike Stump <mrs@cygnus.com>
+
+ * search.c (virtual_context): New function to get the virtual
+ context of a function.
+ (expand_upcast_fixups): New function to generate runtime vtables.
+ (fixup_virtual_upcast_offsets): Likewise.
+ (expand_indirect_vtbls_init): Use fixup_virtual_upcast_offsets to
+ ensure that the this offsets for upcasts from virtual bases into
+ other virtual bases or non-virtual bases are correct at construction
+ time and destruction time.
+ * class.c (fixup_vtable_deltas): Modify to fixup all offsets in all
+ vtables in all virtual bases, instead of just one vtable in each
+ virtual base.
+ (fixup_vtable_deltas1): Likewise.
+
+Tue Apr 18 03:57:35 1995 Michael Meissner <meissner@cygnus.com>
+
+ * Makefile.in (lex.o): Add dependency on c-pragma.h.
+
+ * lex.c (handle_sysv_pragma): Use NULL_PTR and NULL_TREE as
+ appropriate, instead of 0.
+
+Mon Apr 17 12:28:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (pushdecl): Use decls_match, not duplicate_decls, for
+ comparing local and global decls.
+
+Fri Apr 14 01:46:52 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (convert_arguments): Only prohibit passing to ... of
+ types with non-trivial copy constructors.
+
+ * repo.c (repo_template_used): Don't try to mess with no id.
+
+Fri Apr 14 23:32:50 1995 Per Bothner <bothner@rtl.cygnus.com>
+
+ * decl.c (duplicate_decls): Use cp_warning_at for redundant-decls.
+
+Thu Apr 13 15:37:42 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (current_tinst_level): Delete declaration, since it's
+ static inside pt.c.
+
+ * typeck.c (build_modify_expr): Catch incompatible array assignment.
+
+ * parse.y (attribute_list, attrib): Rewrite actions to feed the
+ right stuff to decl_attributes.
+
+Thu Apr 13 11:24:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * search.c (dfs_debug_mark): Check for magic virtual like
+ import_export_vtable.
+
+ * typeck.c (build_binary_op_nodefault): Don't call cp_pedwarn with
+ four args.
+
+Wed Apr 12 12:02:57 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (finish_file): Move prevtable pass before needs_messing_up
+ decision.
+
+Tue Apr 11 11:20:27 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_decl): If we're writing out a static data member of
+ a class, we want the debug info for that class.
+
+ * gc.c (build_t_desc): Check linkage of a class properly.
+
+ * class.c (finish_struct): Set the 'headof' offset for the main
+ vtable properly.
+ (prepare_fresh_vtable): Fix typeinfo pointer here.
+ (modify_one_vtable): Instead of here.
+
+Mon Apr 10 12:15:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c (repo_get_id): New function to return the interesting
+ identifier for a repo entity.
+ (repo_template_used): Use it.
+ (repo_template_instantiated): Mark the id as chosen.
+ (init_repo): Record whether or not the id was chosen.
+ (finish_repo): Note if an id was newly chosen.
+
+ * pt.c (do_function_instantiation): Call repo_template_instantiated.
+ (do_type_instantiation): Likewise. Don't diagnose multiple
+ instantiation.
+
+ * decl2.c (finish_file): Use DECL_NOT_REALLY_EXTERN when deciding
+ whether or not to synthesize a method.
+
+ Undo these changes:
+ * class.c (finish_vtbls): Build more vtables if flag_rtti is on.
+ * class.c (modify_all_direct_vtables): Likewise.
+ * init.c (expand_direct_vtbls_init): Expand more vtables if
+ flag_rtti is on.
+
+Sat Apr 8 17:45:41 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_headof): Use ptrdiff_type_node instead of
+ integer_type_node on pointer arithmetic.
+
+Sat Apr 8 11:57:04 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): Undo previous change.
+
+Thu Apr 6 01:23:50 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * Makefile.in (compiler): Remove ../cc1plus before rebuilding it.
+
+ * repo.c (get_base_filename): Put the .rpo file in the directory
+ with the object file, not the source.
+
+ * typeck.c (build_conditional_expr): Handle pmf's better.
+
+ * repo.c (finish_repo): Also use ASM_OUTPUT_LABELREF to print out
+ the name of the symbol.
+
+Wed Apr 5 15:24:12 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c (open_repo_file): Make repo filename DOS-compliant.
+ (*): Also write a new repo file if some previously-used
+ templates are no longer used. Only remember the identifier.
+
+ * lex.c (cons_up_default_function): If this function belongs to a
+ template class, call repo_template_used for it.
+
+ * repo.c (repo_template_used): Using a class means using its vtable,
+ if any.
+ (finish_repo): Likewise.
+
+ * typeck.c (build_modify_expr): Only wrap TARGET_EXPRs in RTL_EXPRs
+ if the type has a complex copy constructor.
+
+ * decl2.c (lang_decode_option): -frepo implies
+ -fno-implicit-templates.
+
+ * decl.c (start_function): Clear current_{base,member}_init_list.
+
+ * lex.c (init_lex): Also unset *_eq if ! flag_operator_names.
+
+Tue Apr 4 16:11:08 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (struct cp_function): Add {base,member}_init_list.
+ (push_cp_function_context): Save current_{base,member}_init_list.
+ (pop_cp_function_context): Restore them.
+
+Mon Apr 3 16:55:08 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c (get_base_filename): Take filename parm, fix logic bug.
+
+ * typeck.c (build_compound_expr): Do not warn about a compound expr
+ in which the first expression has no side effects.
+ (build_x_compound_expr): Warn here instead.
+ (build_conditional_expr): Don't warn about a conditional expression
+ between an enum and the type it promotes to.
+
+ * init.c (build_new): Handle initialization of arrays of builtins
+ properly.
+
+Mon Apr 3 15:08:04 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * repo.c: Include config.h to get definitions of bcopy and rindex
+ on systems that don't have them (e.g., SVR4).
+
+Mon Apr 3 14:41:55 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_table): Pass NULL_TREE instead of init to
+ finish_decl so that it won't try and do error checking on the
+ initializer.
+
+Mon Apr 3 10:45:50 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c (get_base_filename): Analyze COLLECT_GCC_OPTIONS to
+ determine whether this compile used -c -o.
+ (open_repo_file): Use get_base_filename. Remove the extension.
+ (finish_repo): Spit out the values of main_input_filename,
+ COLLECT_GCC and COLLECT_GCC_OPTIONS.
+
+ * parse.y (structsp): Add TYPENAME_KEYWORD complex_type_name.
+
+Sun Apr 2 23:43:51 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * search.c (compute_access): Don't try to do access control on
+ nested types.
+
+Fri Mar 31 10:14:23 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c: New file to handle things repo.
+
+ * pt.c (instantiate_template): Call repo_template_used if the
+ definition is accessible.
+ (mark_function_instantiated): Split out from
+ do_function_instantiation.
+ (mark_class_instantiated): Split out from do_type_instantiation.
+
+ * parse.y (template_instantiate_once): Call repo_template_used.
+
+ * lex.c (lang_init): Call init_repo.
+
+ * decl2.c: Handle flag_use_repository.
+ (finish_file): Call finish_repo.
+
+ * decl.c (start_method): Call repo_template_used if this is a
+ template method.
+
+ * Makefile.in (CXX_OBJS): Add repo.o.
+ (repo.o): Add dependencies.
+
+ * Make-lang.in (CXX_SRCS): Add repo.c.
+
+ * decl.c (start_function): If DECL_INTERFACE_KNOWN and
+ DECL_NOT_REALLY_EXTERN are both set, unset DECL_EXTERNAL.
+
+ * typeck.c (build_binary_op_nodefault): Identify the invalid operand
+ types used.
+
+ * decl.c (duplicate_decls): Propagate DECL_NOT_REALLY_EXTERN.
+
+Thu Mar 30 17:54:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Tidy up use of build_type
+ and result_type. When checking for comparison between signed
+ and unsigned, use result_type rather than the (possibly shortened)
+ type of op0. Also, don't warn about equality comparison of a
+ signed operand to an unsigned constant that fits in the signed
+ type.
+
+ * method.c (do_build_copy_constructor): Reverse
+ current_base_init_list after we've built it up.
+
+Thu Mar 30 14:35:18 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (build_throw): Never warn about the value of throw not
+ being used.
+
+Thu Mar 30 13:16:54 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_catch_block): Check for bad catch parameter
+ declarations.
+
+Thu Mar 30 13:06:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_function): Only set DECL_NOT_REALLY_EXTERN if
+ DECL_EXTERNAL is not already set.
+
+Thu Mar 30 11:26:24 1995 Mike Stump <mrs@cygnus.com>
+
+ * method.c (emit_thunk): Let poplevel know that the last level is
+ for a function so it can create a BLOCK_NODE and set DECL_INITIAL.
+
+Thu Mar 30 11:15:06 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (import_export_inline): Don't set DECL_NOT_REALLY_EXTERN
+ here.
+
+ * decl.c (grokdeclarator): OK, don't abort if we see a decl with
+ METHOD_TYPE.
+ (finish_function): Set DECL_EXTERNAL and DECL_NOT_REALLY_EXTERN on
+ all deferred inlines.
+
+Wed Mar 29 19:35:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cp-tree.h (DECL_THIS_INLINE): New macro.
+ (DECL_NOT_REALLY_EXTERN): New macro.
+ (DECL_THIS_STATIC): New macro.
+
+ * decl.c: Lose all references to current_extern_inline. Break
+ inline semantics into DECL_INLINE for actual inlining and
+ DECL_THIS_INLINE for the linkage wierdness. Use DECL_THIS_STATIC.
+ * decl2.c: Use DECL_NOT_REALLY_EXTERN to indicate that we want to
+ emit an inline here. Associated changes.
+ * lex.c: Likewise.
+ * pt.c: Likewise.
+ * typeck.c: Likewise.
+
+ * call.c (build_method_call): Don't bother trying to handle inlines
+ specially.
+ * cvt.c (convert_to_aggr): Likewise.
+
+ * pt.c (do_function_instantiation): Handle instantiation of
+ public inlines, too.
+
+Wed Mar 29 16:04:25 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (init_exception_processing): Change the interface for
+ __throw_type_match and add decl for new rtti matching routine
+ __throw_type_match_rtti.
+ (build_eh_type): New routine to build a run time descriptor for the
+ expression given.
+ (expand_start_catch_block): Update to use new calling convention for
+ the matcher.
+ (expand_throw): Update to use build_eh_type.
+
+Mon Mar 27 07:14:33 1995 Warner Losh <imp@village.org>
+
+ * g++.c: Removed __NetBSD__ from conditional.
+ Declare strerror if HAVE_STRERROR is defined; otherwise
+ declare sys_errlist and sys_nerr.
+ (my_strerror): New function.
+
+Tue Mar 28 14:16:35 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * search.c (get_binfo): Don't try to be so clever.
+
+ * tree.c (copy_to_permanent): Also suspend_momentary().
+
+ * cvt.c (cp_convert_to_pointer): Hand off to convert_fn_pointer even
+ if the types are the same.
+
+ * decl.c (start_function): Handle extern inlines more like C++ says
+ we should.
+
+ * init.c (build_member_call): Hand constructor calls off to
+ build_functional_cast.
+
+ * typeck2.c (build_functional_cast): Use DECL_NESTED_TYPENAME to get
+ the name of the type.
+
+Tue Mar 28 13:13:56 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Check for the decl returned by
+ grokfndecl to be null before using build_decl_attribute_variant.
+
+Mon Mar 27 18:04:41 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_new): Use build_pointer_type instead of
+ TYPE_POINTER_TO.
+
+Fri Mar 24 12:11:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_conditional_expr): Handle pmfs.
+ (convert_for_assignment): Fix pmf support.
+
+ * cvt.c (convert_fn_ptr): Support !flag_vtable_thunks.
+ (cp_convert_to_pointer): Handle pmfs.
+ (cp_convert): Pass pmfs to cp_convert_to_pointer.
+
+ * typeck.c (common_type): Handle inheritance for pmfs.
+
+ * typeck2.c (build_m_component_ref): Do access control.
+
+ * typeck.c (comp_target_types): Check for conversion to void *
+ before checking trickier conversions.
+
+ * decl.c (duplicate_decls): Propagate DECL_ABSTRACT_VIRTUAL_P.
+
+ * pt.c (push_tinst_level): Complain if template instantiation depth
+ is greater than max_tinst_depth.
+
+ * typeck.c (common_type): Assume that we can call common_type to
+ unify the target type of a pointer.
+
+Thu Mar 23 00:48:44 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_file): Don't synthesize methods at
+ finish_vtable_prevardecl time. Do synthesize methods that are not
+ used, but are public and not external.
+
+ * cvt.c (build_type_conversion): Only give an error if for_sure.
+
+ * typeck.c (comp_target_types): Only support pointer conversions if
+ nptrs > 0.
+
+Wed Mar 22 19:30:15 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_new): Catch use of an initializer list where it
+ shouldn't be.
+
+Wed Mar 22 16:21:07 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_new): Wrap alloc_expr in an RTL_EXPR if nelts is
+ non-constant.
+
+ * decl2.c: temp_name_counter is now public.
+
+ * decl.c (struct cp_function): Add temp_name_counter field.
+ (push_cp_function_context): Save it.
+ (pop_cp_function_context): Restore it.
+
+ * typeck.c (common_type): Handle unifying function types, and unify
+ unmatched things to void* with a compiler_error, rather than
+ silently like before.
+
+Wed Mar 22 15:10:34 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_prevtable_vardecl, finish_vtable_vardecl): Revert
+ Brendan's last change and fix latent problem that causes TD entries
+ to not come out when the things that need them has yet to be
+ expanded.
+
+Wed Mar 22 15:12:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault, comparison ops): Update type0
+ and type1, since we might have changed op0 or op1.
+
+Wed Mar 22 13:33:45 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * typeck.c (common_type): Don't mess up templates.
+
+Wed Mar 22 04:56:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (common_type): Handle ptms properly. Also handle
+ T* -> void*.
+ (build_binary_op_nodefault): New variable build_type controls what
+ type is given to the expression when it is created. Set this to
+ boolean_type_node for comparison ops instead of using result_type.
+ (comp_target_types): Allow T * -> void *.
+
+ * cvt.c (cp_convert_to_pointer): Do access control when converting
+ ptms, too.
+
+Tue Mar 21 17:25:06 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (extern_lang_string): Catch use of linkage specs that
+ aren't all naming the same language.
+
+ * class.c (finish_struct): Delete accidental duplicate code.
+
+Tue Mar 21 14:00:57 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Disable pedwarns about
+ comparing functions and incomplete types.
+
+ * decl.c (finish_function): Only unset current_function_decl if
+ !nested.
+ (duplicate_decls): Last change went too far; we only want to stop
+ checking for value/reference ambiguity.
+
+Tue Mar 21 01:26:39 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (build_generic_desc): Zap the DECL_SIZE so that we can lay it
+ out fresh, as the new type may be larger.
+
+Mon Mar 20 19:01:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * expr.c (extract_init): Try to expand the RTL for the
+ initialization and figure out what it will look like so we can avoid
+ run-time initialization. Disabled for now.
+ (extract_scalar_init): Helper for scalar initialization.
+ (extract_aggr_init): Helper for aggregate initialization.
+
+ * decl.c (duplicate_decls): Don't complain about ambiguous
+ declarations.
+ (obscure_complex_init): Now returns a tree. Call extract_init if
+ we're optimizing and this is a toplevel decl.
+ (finish_decl): Update accordingly.
+
+ * lex.c (check_newline): If we're just changing files (not pushing
+ or popping), update input_file_stack->name.
+
+Mon Mar 20 17:55:04 1995 Mike Stump <mrs@cygnus.com>
+
+ * pt.c (type_unification): Only TEMPLATE_DECLs are handled right now
+ in the transitive unification code.
+
+Mon Mar 20 16:07:50 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (shadow_tag): Don't allow inline, virtual, or explicit on
+ non-functions.
+ (grokdeclarator): Don't allow friends to be defined in local classes.
+
+Sat Mar 18 04:03:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_prevtable_vardecl): Use DECL_DECLARED_STATIC
+ rather than DECL_SAVED_INSNS to decide whether or not this method
+ was declared inline.
+
+ * method.c (synthesize_method): Turn off DECL_INLINE if
+ function_cannot_inline_p thinks we're too large.
+
+ * typeck.c (build_indirect_ref): Use build_expr_type_conversion.
+
+Fri Mar 17 17:47:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (instantiate_type): Handle pmfs.
+
+ * typeck.c (convert_for_assignment): Check types when assigning one
+ pmf to another.
+
+ * decl.c (define_label): Fix logic for printing out the name of the
+ label in an error message.
+
+ * error.c (dump_expr): Support ARRAY_REF.
+
+Fri Mar 17 17:43:02 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Call build_t_desc here.
+ (finish_prevtable_vardecl): Instead of here.
+
+Fri Mar 17 14:40:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (expand_static_init): Also use expand_aggr_init if the
+ initializer is a TREE_LIST.
+ (grokdeclarator): Only pedwarn about extra qualification if -pedantic.
+
+ * pt.c (unify): Fix unification of return type.
+
+ * expr.c (fixup_result_decl): Use store_expr, rather than
+ emit_move_insn, to move the return value into the place where
+ callers will expect it.
+
+Thu Mar 16 22:05:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_offset_ref): Call assmble_external on functions.
+ * typeck.c (build_component_ref): Likewise.
+
+Thu Mar 16 20:28:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (struct saved_scope): Add members base_init_list and
+ member_init_list.
+ (push_to_top_level): Save current_base_init_list and
+ current_member_init_list to them.
+ (pop_from_top_level): Put it back.
+
+Thu Mar 16 19:21:14 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (instantiate_template): Call assemble_external.
+
+Thu Mar 16 18:07:54 1995 Brendan Kehoe <brendan@phydeaux.cygnus.com>
+
+ * class.c: Include rtl.h, to get NULL_RTX.
+ (finish_struct): Also zero out DECL_SAVED_INSNS, to avoid problems
+ on hosts with different sizes for each part of the union.
+ * tree.c: Also include rtl.h.
+ (layout_basetypes): Same change for DECL_SAVED_INSNS.
+
+Thu Mar 16 13:57:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (unify): Fix array domain unification for 64-bit targets.
+
+ * decl2.c (finish_file): Push bizarre type decl before walking the
+ vtables the first time.
+ (walk_vtables): OK, don't set prev to vars if the vardecl_fn messed
+ with TREE_CHAIN (prev).
+
+ * init.c (emit_base_init): Use convert_pointer_to_real instead of
+ convert_pointer_to when converting to a direct base.
+
+Wed Mar 15 20:26:29 1995 Mike Stump <mrs@cygnus.com>
+
+ * pt.c (type_unification): Handle transitive unification better.
+
+Wed Mar 15 13:56:16 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (walk_vtables): Always set prev to vars.
+ (mark_vtable_entries): Call assemble_external on the vtable entries.
+
+ * class.c (finish_struct): Set the vtable's size to NULL_TREE before
+ calling layout_decl, so that it gets updated properly.
+
+ Finally re-enable dynamic synthesis. This time it works.
+ * method.c (synthesize_method): Pass decl_function_context (fndecl)
+ to {push,pop}_cp_function_context.
+ * decl.c (push_cp_function_context): Now takes a tree argument.
+ (pop_cp_function_context): Likewise.
+ * call.c (build_method_call): Enable synthesis.
+ * lex.c (cons_up_default_function): Likewise.
+
+Tue Mar 14 19:14:19 1995 Doug Evans <dje@chestnut.cygnus.com>
+
+ * parse.y (setattrs): Chain onto prefix_attributes rather than
+ setting it.
+
+Wed Mar 15 13:00:00 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (pushdecl): Check if the type of the VAR_DECL is an
+ error_mark_node before trying to read TYPE_LANG_SPECIFIC.
+
+Mon Mar 13 21:00:28 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator, case ARRAY_REF): Wrap the exp with fold,
+ and convert the size and integer_one_node to the index type.
+
+Mon Mar 13 08:01:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Save the instance
+ argument, and tack it onto the front of the COND_EXPR to make the
+ semantics come out right. Grab the instance argument from
+ '*instance_ptrptr', rather than having it passed in separately.
+
+ * various: Change various consed-up comparison operations to have
+ boolean type. Remove the instance argument in calls to
+ get_member_function_from_ptrfunc.
+
+ * error.c (dump_expr): Dump true and false as "true" and "false".
+
+ * decl2.c (finish_file): Also set DECL_STATIC_FUNCTION_P on the
+ global init function.
+
+ * decl.c (finish_function): Only set DECL_EXTERNAL here if the
+ inline function is public.
+
+Sat Mar 11 00:58:03 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (is_friend): Be more careful about checking
+ DECL_CLASS_CONTEXT on non-member functions.
+
+ * decl2.c (finish_vtable_vardecl): Don't bother calling
+ assemble_external here.
+ (prune_vtable_vardecl): New function that just splices out the
+ vtable decl from the top-level decls.
+ (import_export_inline): Unset DECL_EXTERNAL at first.
+ (finish_file): Don't bother calling assemble_external here. Do
+ splice out all of the vtables.
+
+Fri Mar 10 14:42:29 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_function): If we're not emitting the function yet,
+ call assemble_external for it.
+
+ * decl2.c (finish_prevtable_vardecl): Don't call mark_vtable_entries
+ here.
+ (finish_vtable_vardecl): Don't do the linkage deduction thing here.
+ Also don't splice out the current vtable if it is unused.
+ (finish_file): Move the second walk_vtables and the synthesis check
+ inside the 'reconsider' loop. Move thunk emission after the
+ 'reconsider' loop.
+
+Thu Mar 9 16:28:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * pt.c (tsubst): Don't bother calling cp_build_type_variant, since it
+ was passing bogus values for readonly and volatile from the original
+ template decl, not the resultant type of the tsubst call.
+
+ * class.c (duplicate_tag_error): Use cp_error_at to point out the
+ previous definition of the tag.
+
+Thu Mar 9 10:46:17 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_function): Clear base_init_insns and protect_list.
+ (struct cp_function): Add base_init_insns field.
+ (push_cp_function_context): Also save base_init_insns.
+ (pop_cp_function_context): Also restore base_init_insns.
+
+Wed Mar 8 13:31:44 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (member_init_ok_or_else): Check for initializing a static
+ member here.
+ (emit_base_init): Instead of here.
+
+Tue Mar 7 16:03:26 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Disable synthesis as needed.
+ * lex.c (cons_up_default_function): Likewise.
+
+Tue Mar 7 10:14:29 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y: New rules to allow attributes in a prefix position.
+ (prefix_attributes): New variable. Pass it into cplus_decl_attributes.
+ (setattr): New rule.
+ (reserved_declspecs, declmods): Catch attributes here.
+ * decl2.c (cplus_decl_attributes): Add PREFIX_ATTRIBUTES argument.
+ * decl.c (duplicate_decls): Pass DECL_MACHINE_ATTRIBUTES to
+ descendent typedef.
+ (grokdeclarator): Added code to support machine attributes.
+ * Makefile.in (stamp-parse): Expect 5 shift/reduce failures.
+
+Mon Mar 6 15:07:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Don't synthesize methods outside of a
+ function.
+
+ Make base initialization more re-entrant so that synthesis on the
+ fly will work (and, eventually, template instantiation on the fly).
+ * init.c (sort_member_init): Don't bother with members that can't be
+ initialized. Reorganize a bit. Don't initialize base members here.
+ (sort_base_init): New function, like sort_member_init, but for base
+ classes. Steals some code from emit_base_init.
+ (emit_base_init): Simplify. Call sort_{member,base}_init before
+ doing any initialization, so we don't have to save
+ current_{member,base}_init_list in push_cp_function_context.
+ (expand_aggr_vbase_init_1): Adjust for sort_base_init.
+ (expand_aggr_vbase_init): Simplify.
+ * decl.c (struct cp_function): Add protect_list field.
+ (push_cp_function_context): Also save protect_list.
+ (pop_cp_function_context): Also restore protect_list.
+ * call.c (build_method_call): Enable synthesis at point of call.
+ * lex.c (cons_up_default_function): Likewise.
+
+ * parse.y: Turn -ansi checks back into -pedantic checks.
+
+ * init.c (build_new): Fix -fcheck-new for array new.
+
+Sat Mar 4 15:55:42 1995 Fergus Henderson <fjh@cs.mu.oz.au>
+
+ * typeck.c (build_compound_expr): warn if left-hand operand of
+ comma expression has no side-effects.
+
+Fri Mar 3 15:16:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (primary): Change 'object qualified_id *' rules to 'object
+ overqualified_id *'.
+
+Fri Mar 3 12:48:17 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (unary_expr): Catch doing sizeof an overloaded function.
+ Make the error look the same as the one we issue in c_sizeof.
+
+ * typeck.c (build_binary_op_nodefault): Give an error for trying
+ to compare a pointer-to-member to `void *'.
+
+Fri Mar 3 11:28:50 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_unary_op): Handle bool increment with smoke and
+ mirrors here, rather than in expand_increment where it belongs,
+ because Kenner doesn't agree with me.
+
+Fri Mar 3 00:08:10 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokparms): Catch a PARM_DECL being used for a default
+ argument as well.
+
+Thu Mar 2 20:05:54 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_new): Don't allow new on a function type.
+
+ * parse.y (primary): Avoid a crash when seeing if the arg is of
+ the same type as that given for the typespec in an explicit dtor call.
+
+Thu Mar 2 00:49:38 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_function): Change test for calling
+ mark_inline_for_output.
+
+Wed Mar 1 11:23:46 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): Complain if
+ build_default_binary_type_conversion fails.
+
+ * init.c (expand_default_init): Handle arguments of unknown type
+ properly.
+
+ * cvt.c (build_expr_type_conversion): Only complain about ambiguity
+ if 'complain'.
+ * various: Pass 'complain'.
+
+ * typeck.c (comptypes): Be more picky about comparing UPTs.
+
+Wed Mar 1 11:03:41 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): If declarator is null, say that the
+ type used has an incomplete type.
+
+Wed Mar 1 10:06:20 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (instantiate_template): Copy the template arguments to the
+ permanent_obstack. Also use simple_cst_equal to compare them when
+ looking for a previous instantiation.
+
+ * tree.c (make_deep_copy): Support copying INTEGER_TYPEs (assuming
+ they are array domain types).
+
+Tue Feb 28 23:24:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cp-tree.h: Define WANT_* constants for passing to
+ build_expr_type_conversion.
+ * cvt.c (build_expr_type_conversion): New function to build
+ conversion to one of a group of suitable types.
+ (build_default_binary_type_conversion): Use it.
+ * decl2.c (grok_array_decl): Likewise.
+ * typeck.c (build_unary_op): Likewise.
+ (build_array_ref): Tidy up a bit.
+ (build_binary_op): Likewise.
+
+Tue Feb 28 19:57:31 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't allow decl of an argument as `void'.
+
+Tue Feb 28 17:23:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (typed_declspecs1): Add 'typespec reserved_typespecquals
+ reserved_declspecs' rule.
+
+ * parse.y (expr_or_declarator): Remove notype_qualified_id rule.
+ (direct_notype_declarator): Likewise.
+ (complex_direct_notype_declarator): Add notype_qualified_id rule.
+
+ * lex.c (real_yylex): Handle :> digraph properly.
+
+Tue Feb 28 12:26:29 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Check if it's a friend, not if it's
+ non-virtual, that's being initialized. Move the check up to
+ before FRIENDP would get cleared. Catch an unnamed var/field
+ being declared void. Say just `field' instead of `structure field'
+ in the error message. Only go for the operator name if DECLARATOR
+ is non-null.
+
+Tue Feb 28 00:08:01 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (start_function): Complain about abstract return type.
+ (grokdeclarator): Complain about declaring constructors and
+ destructors to be const or volatile. Complain about declaring
+ destructors to be static.
+
+ * pt.c (uses_template_parms): Handle pmfs.
+
+ * decl.c (grokdeclarator): Don't call variable_size for array bounds
+ that only depend on template constant parameters.
+
+Mon Feb 27 15:38:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * error.c (dump_decl): Only look to see if it's a vtable if we
+ actually have a name to check out.
+
+Mon Feb 27 13:37:53 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (convert_to_aggr): Lose misleading shortcut.
+
+Sun Feb 26 17:27:32 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * decl.c (set_nested_typename): Always set DECL_IGNORED_P,
+ not just for dwarf.
+
+Sun Feb 26 00:10:18 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't allow a static member to be
+ declared `register'.
+
+ * init.c (make_friend_class): Move up to a pedwarn for the warning
+ about a class declaring friends with itself.
+
+ * decl.c (grokdeclarator): You can't do `volatile friend class foo'
+ or `inline friend class foo'. Only try to make a friend out of
+ TYPE if we didn't already reset it to integer_type_node.
+
+Sat Feb 25 22:32:03 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Don't allow initialization of a
+ non-virtual function.
+
+ * decl.c (start_function): Do a pedwarn if we're changing `main'
+ to have an int return type.
+
+Sat Feb 25 00:02:05 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): Handle simple assignment from
+ TARGET_EXPRs by building up an RTL_EXPR to force expansion. Whew.
+
+Fri Feb 24 18:27:14 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Also don't allow virtual outside of a
+ class decl for a scope method definition performed at global binding.
+
+ * init.c (build_offset_ref): Don't allow creation of an OFFSET_REF
+ of a bitfield.
+
+ * decl.c (grokdeclarator): Don't allow a const to be declared mutable.
+
+ * typeck.c (build_binary_op): Return an error_mark_node if either
+ one of the args turned into an error_mark_node when we tried to
+ use default_conversion.
+
+ * typeck.c (build_unary_op): Forbid using postfix -- on a bool.
+
+ * decl.c (grokdeclarator): Allow `signed' and `unsigned' to be
+ used on `__wchar_t'.
+
+Fri Feb 24 13:59:53 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (end_protect_partials): Do it the right way.
+
+Wed Feb 22 15:42:56 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Upgrade warning about
+ comparing distinct pointer types to pedwarn.
+
+ * typeck2.c (digest_init): Cope with extra braces.
+
+ * typeck.c (build_binary_op_nodefault): Use tree_int_cst_sgn instead
+ of INT_CST_LT (..., interger_zero_node).
+
+Wed Feb 22 14:45:52 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * except.c [!TRY_NEW_EH] (end_protect_partials): Define dummy
+ function for systems that don't have EH.
+
+Tue Feb 21 19:18:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (can_convert_arg): Like can_convert, but takes an arg as
+ well.
+
+ * pt.c (type_unification): Allow implicit conversions for parameters
+ that do not depend on template parameters.
+
+Tue Feb 21 18:43:48 1995 Douglas Rupp <drupp@cs.washington.edu>
+
+ * Make-lang.in, config-lang.in: ($exeext): New macro.
+ * Make-lang.in: Try a "cp" if "ln" fails.
+ * cp-tree.h (decl_attributes): Added argument.
+ * decl2.c (cplus_decl_attribute): Add arg to decl_attributes.
+ * cp/g++.c: Added #ifdefs for sys/file.h and process.h for NT.
+ Modified spawnvp to have to correct number of arguments for OS/2, NT.
+
+Tue Feb 21 18:36:55 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (finish_function): Add calls to end_protect_partials to end
+ the exception region that protects constructors so that partially
+ constructed objects can be partially destructed when the constructor
+ throws an exception.
+ * init.c (perform_member_init, sort_member_init, emit_base_init):
+ Added support for partially constructed objects.
+ * init.c (build_partial_cleanup_for): New routine to do partial
+ cleanups of a base class.
+ * decl2.c (finish_file): Move the emitting of the exception table
+ down, after we emit all code that might have exception regions in
+ them.
+ * except.c (end_protect_partials, might_have_exceptions_p): New
+ routines.
+ (emit_exception_table): Always output table if called.
+ * cp-tree.h (protect_list, end_protect_partials,
+ might_have_exceptions_p, emit_exception_table): Added.
+
+Tue Feb 21 16:05:59 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * gc.c (build_typeid): Pass a NULL_TREE, not the bogus, unused
+ address of a local variable.
+ * class.c (build_vfn_ref): Only try to build the PLUS_EXPR if we
+ were given a non-null PTR_TO_INSTPTR.
+
+Tue Feb 21 01:53:18 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (duplicate_decls): Always lay out the merged decl.
+
+ * decl2.c (finish_vtable_vardecl): Don't do vtable hack on templates.
+ (finish_prevtable_vardecl): Likewise.
+
+ * method.c (synthesize_method): Set interface_{unknown,only}
+ according to the settings for our class, not the file where it comes
+ from.
+
+Sat Feb 18 12:26:48 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Handle systems that define __i386__ but not __i386.
+
+Fri Feb 17 15:31:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (reparse_decl_as_expr): Support being called without a
+ type argument.
+
+ * parse.y (primary): Add '(' expr_or_declarator ')'. Adds 4 r/r
+ conflicts. Sigh.
+
+Fri Feb 17 12:02:06 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (template_def, fndef, fn.def1, return_init, condition,
+ initdcl0, initdcl, notype_initdcl0, nomods_initdcl0,
+ component_decl_1, after_type_component_declarator0,
+ notype_component_declarator0, after_type_component_declarator,
+ notype_component_declarator, after_type_component_declarator,
+ full_parm, maybe_raises, exception_specification_opt): Fix up,
+ include exception_specification_opt maybeasm maybe_attribute and
+ maybe_init if missing. Rename maybe_raises to
+ exception_specification_opt to match draft wording. Use maybe_init
+ to simplify rules.
+
+Fri Feb 17 01:54:46 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_new): Set TREE_NO_UNUSED_WARNING on COMPOUND_EXPRs
+ built for news of scalar types.
+
+Thu Feb 16 17:48:28 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Update code for warning
+ about signed/unsigned comparisons from C frontend. Realize that the
+ code in the C frontend is, if anything, even more bogus. Fix it.
+ (build_binary_op): Undo default_conversion if it wasn't useful.
+
+ * typeck.c (build_unary_op, ADDR_EXPR): Lose bogus special case for
+ PRE*CREMENT_EXPR.
+
+ * decl2.c (import_export_vtable): Don't try the vtable hack
+ if the class doesn't have any real non-inline virtual functions.
+ (finish_vtable_vardecl): Don't bother trying to find a non-inline
+ virtual function in a non-polymorphic class.
+ (finish_prevtable_vardecl): Likewise.
+
+ * decl2.c (import_export_vtable): Use and set DECL_INTERFACE_KNOWN.
+
+ * cp-tree.h (DECL_INTERFACE_KNOWN): Use DECL_LANG_FLAG_5.
+
+ * init.c (expand_virtual_init): Always call assemble_external.
+
+ * class.c (build_vfn_ref): Always call assemble_external.
+ (build_vtable): Always call import_export_vtable.
+ (prepare_fresh_vtable): Likewise.
+ (add_virtual_function): Don't bother setting TREE_ADDRESSABLE.
+
+Thu Feb 16 03:28:49 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_struct): Use TYPE_{MIN,MAX}_VALUE to determine
+ whether an enumerated type fits in a bitfield.
+
+Wed Feb 15 15:38:12 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (grow_method): Update method_vec after growing the class
+ obstack.
+
+Wed Feb 15 13:42:59 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (handler_seq): Push a level for the catch parameters.
+
+Wed Feb 15 12:42:57 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (emit_base_init): Update BINFO_INHERITANCE_CHAIN on my
+ bases, in case they've been clobbered.
+
+Wed Feb 15 12:07:29 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (finish_base_struct): Set up BINFO_INHERITANCE_CHAIN here,
+ so that one day it will always be valid.
+ * tree.c (propagate_binfo_offsets, layout_vbasetypes): Likewise.
+
+ * cp-tree.h (copy_binfo): Removed, unused.
+ * tree.c (copy_binfo): Likewise.
+
+Wed Feb 15 00:05:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_new): Save the allocation before calling
+ expand_vec_init on it.
+
+ * decl.c (finish_enum): The TYPE_PRECISION of the enum type mush
+ match the TYPE_PRECISION of the underlying type for constant folding
+ to work.
+
+Tue Feb 14 15:31:25 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (push_eh_entry, expand_start_all_catch,
+ expand_leftover_cleanups, expand_end_catch_block): Keep track of
+ the context in which the exception region occurs.
+ (build_exception_table): If the region was not output, don't output
+ the entry in the eh table for it.
+
+Tue Feb 14 02:15:43 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (expand_default_init): Only use a previous constructor call
+ if it's a call to our constructor. Does the word "Duh" mean
+ anything to you?
+
+ * decl.c (grokparms): Fine, just don't call
+ convert_for_initialization at all. OK? Happy now?
+
+Mon Feb 13 02:23:44 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cp-tree.h (CLASSTYPE_FIRST_CONVERSION): Make sure that the class
+ method vector has a second element before returning it.
+
+ * decl.c (grokparms): Don't strip REFERENCE_TYPE before calling
+ convert_for_initialization.
+
+Sun Feb 12 03:57:06 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_modify_expr): Compare function name to
+ constructor_name (current_class_type) instead of current_class_name.
+
+ * decl.c (grokparms): Don't do anything with the return value of
+ convert_for_initialization.
+
+ * error.c (dump_decl): Also dump_readonly_or_volatile on the decl.
+
+ * decl.c (duplicate_decls): Tweak error message.
+
+ * typeck.c (build_const_cast): Implement checking.
+ (build_reinterpret_cast): Implement some checking.
+
+ * cp-tree.h (CONV_FORCE_TEMP): Require a new temporary when
+ converting to the same aggregate type.
+ (CONV_STATIC_CAST): Include it.
+ (CONV_C_CAST): Likewise.
+ * cvt.c (convert_force): Use CONV_C_CAST instead of CONV_OLD_CONVERT.
+ (cp_convert): Only force a new temporary if CONV_FORCE_TEMP.
+
+Fri Feb 10 16:18:52 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (build_c_cast): Use non_lvalue to tack something on
+ where necessary.
+
+ * decl.c (auto_function): Now a function.
+ * except.c (init_exception_processing): terminate, unexpected,
+ set_terminate, and set_unexpected have C++ linkage.
+
+ * typeck.c (build_unary_op, TRUTH_NOT_EXPR): Use convert instead of
+ truthvalue_conversion for converting to bool, as it handles
+ user-defined conversions properly.
+ (condition_conversion): Likewise.
+
+ * except.c (expand_throw): Don't call convert_to_reference.
+ Pass the correct parameters to build_new.
+
+ * method.c (do_build_assign_ref): Don't use access control when
+ converting to a base reference here.
+ (do_build_copy_constructor): Or here.
+
+ * init.c (build_new): Unset TREE_READONLY on the dereferenced
+ pointer before assigning to it.
+
+ * decl.c (maybe_build_cleanup): Don't bother stripping const here.
+
+ * decl2.c (delete_sanity): You can now delete pointer to const.
+
+Fri Feb 10 13:28:38 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * decl.c (finish_function): Don't rely on actual parameters being
+ evaluated left-to-right.
+ * except.c (expand_end_catch_block): Likewise.
+
+Fri Feb 10 00:52:04 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * tree.c (real_lvalue_p): Like lvalue_p, but class temps aren't
+ considered lvalues.
+ * cvt.c (convert_to_reference): Use real_lvalue_p instead of
+ lvalue_p.
+
+ * cvt.c (build_type_conversion_1): Don't call convert on aggregate
+ types.
+ (convert_to_reference): Fix erroneous text substitution.
+
+ * typeck2.c (initializer_constant_valid_p): Update from C frontend.
+ Add new argument to all callers.
+
+ * typeck.c (convert_arguments): Check for error_mark_node before
+ trying to do anything with the actual parameter.
+
+ * typeck.c (condition_conversion): Build up a CLEANUP_POINT_EXPR and
+ fold it.
+ (bool_truthvalue_conversion): Remove. Fix all callers to call
+ truthvalue_conversion instead.
+ (various): Fold CLEANUP_POINT_EXPRs.
+
+ * parse.y (conditions): Call condition_conversion rather than
+ building up a CLEANUP_POINT_EXPR.
+
+ * pt.c (end_template_decl): Don't warn_if_unknown_interface here
+ under -falt-external-templates.
+
+Thu Feb 9 05:24:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_new): Complain about new of const type without
+ initializer. Other cleanup.
+
+ * call.c (compute_conversion_costs): Don't call
+ build_type_conversion with a reference type; convert to the target
+ type and check its lvaluetude.
+ * cvt.c (convert_to_reference): Likewise.
+
+ * cvt.c (build_type_conversion_1): There will never be any need to
+ dereference references here now.
+
+Thu Feb 9 00:37:47 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_builtin_throw): Make sure we only `use' the
+ value of return_val_rtx.
+
+Wed Feb 8 15:45:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (structsp): Don't complain about declaring a type being
+ defined to be a friend.
+
+ * decl2.c (warn_if_unknown_interface): Note the template in question
+ and the point of instantiation, for -falt-external-templates.
+ * lex.c (reinit_parse_for_method): Pass the decl to
+ warn_if_unknown_interface.
+ * pt.c (instantiate_template): Likewise.
+ (end_template_decl): Likewise.
+
+ * decl.c (set_nested_typename): Set IDENTIFIER_TYPE_VALUE on the
+ nested name again, to make local classes work a bit better.
+
+ * typeck.c (build_function_call_real): Dereference reference after
+ checking for incomplete type.
+
+ * init.c (build_new): Accept new of const and volatile types.
+
+Wed Feb 8 14:04:16 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl.c (grokdeclarator): Fix error message.
+
+Wed Feb 8 03:16:15 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (convert_for_initialization): Do bash arrays when
+ converting to a reference to non-array.
+
+Tue Feb 7 15:50:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (cp_convert): Don't call convert_to_reference, or
+ automatically dereference references. Do pass reference conversions
+ to cp_convert_to_pointer.
+ (cp_convert_to_pointer): Support references.
+
+ * call.c (build_method_call): Don't build up a reference to the
+ parameter here; let build_overload_call handle that.
+
+ * typeck.c (build_c_cast): Call convert_to_reference directly if
+ converting to a reference type.
+ * method.c (do_build_copy_constructor): Likewise.
+ * method.c (do_build_copy_constructor): Likewise.
+ (do_build_assign_ref): Likewise.
+
+ * call.c (build_method_call): Dereference a returned reference.
+ * typeck.c (build_function_call_real): Likewise.
+
+ * decl.c (xref_basetypes): Check for unions with basetypes here.
+ (xref_tag): Instead of here.
+
+ * pt.c (process_template_parm): Template type parm decls are
+ artificial.
+
+Mon Feb 6 04:32:09 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (typed_declspecs): Add missing semicolon.
+ (do_xref_defn): Resurrect.
+ (named_class_head_sans_basetype): Move template specialization
+ definition cases to named_class_head_sans_basetype_defn.
+
+ * decl2.c (grokfield): Call pushdecl_class_level after setting the
+ TYPE_NAME, not before.
+
+Sun Feb 5 02:50:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (convert_harshness): Don't call sorry here. Don't allow
+ conversions between function pointer types if pedantic.
+
+ * pt.c (overload_template_name): Pass globalize=1 to xref_tag.
+
+ * lex.c (cons_up_default_function): Use the full name for the return
+ type of op=.
+
+ * decl.c (set_nested_typename): Don't worry about anonymous types,
+ as they already have a unique name.
+ (pushdecl): Remove redundant set_nested_typename
+ (xref_tag): Split out base handling into xref_basetypes.
+
+ * cp-tree.h (TYPE_INCOMPLETE): New macro; TEMPLATE_TYPE_PARMs are
+ not considered incomplete even though their definition is unknown.
+
+ * decl.c (xref_defn_tag): Lose.
+ (xref_tag): xref_next_defn = ! globalize.
+ (pushdecl): Don't set DECL_NESTED_TYPENAME on artificial decls. The
+ ones that should have it set will have it set by pushtag.
+ (pushdecl_class_level): Likewise.
+ (pushtag): Tidy up a bit.
+ (set_nested_typename): Push a decl for the nested typename from
+ here, rather than from xref_defn_tag.
+
+ * parse.y (do_xref): Lose.
+ (named_class_head): If we see 'class foo:' we know it's a
+ definition, so don't worry about base lists for non-definitions.
+
+ * pt.c (push_template_decls): Template parm decls are artificial.
+
+ * decl.c (duplicate_decls): Restore check for qualifier
+ disagreement for non-functions.
+ (decls_match): Remove check for qualifier disagreement.
+
+Fri Feb 3 14:58:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grok_reference_init): Convert initializer from
+ reference.
+ * typeck.c (convert_for_initialization): Likewise.
+
+ * decl.c (duplicate_decls): Propagate DECL_NESTED_TYPENAME.
+
+ * cvt.c (cp_convert): Don't convert to the same class type by just
+ tacking on a NOP_EXPR.
+ (convert_to_reference): Use comp_target_types instead of comptypes
+ so that we don't allow conversions two levels down.
+
+Thu Feb 2 15:07:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (build_vbase_path): Bash types to make the backend happy.
+ * cvt.c (build_up_reference): Bash the types bashed by
+ build_vbase_path to be reference types instead of pointer types.
+ (convert_to_reference): Likewise.
+
+ * typeck.c (build_c_cast): Don't strip NOPs if we're converting to a
+ reference type.
+
+ * parse.y (structsp): Put back error for 'struct B: public A;'.
+
+Wed Feb 1 23:02:06 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Add support for mips systems that don't define __mips
+ but do define mips, like Ultrix.
+
+Wed Feb 1 22:39:07 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Add support for exception handling on the Alpha.
+
+Wed Feb 1 10:12:14 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_file): Fix bug in Jan 31st change.
+
+Tue Jan 31 16:59:15 1995 Gerald Baumgartner <gb@lorenzo.cs.purdue.edu>
+
+ * sig.c (build_signature_pointer_or_reference_type): Don't set
+ IS_AGGR_TYPE for signature pointers/reference so expand_default_init
+ doesn't expect to find a copy constructor.
+ * call.c (build_method_call): Treat signature pointers/reference
+ as if IS_AGGR_TYPE were set.
+
+Tue Jan 31 13:28:56 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (get_typeid): Pawn off error messages to build_t_desc.
+ (build_t_desc): Inform the user here if they try and build
+ with -frtti and don't include <typeinfo.h>.
+
+ * decl2.c (finish_prevtable_vardecl): Support rescanning.
+ (finish_file): Move finish_prevtable_vardecl up to before the global
+ initializers are done as tdecls are initialized in the global
+ initializer. Also Pick up any new tdecls or vtables needed by
+ synthesized methods.
+
+ * class.c (finish_struct): Simplify. We have to do rtti scanning at
+ end, so we might as well do all of it there.
+
+Tue Jan 31 05:35:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Fix -fthis-is-variable for 32-bit
+ targets, too.
+
+Tue Jan 31 00:11:04 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_prevtable_vardecl): New routine, mostly split from
+ finish_vtable_vardecl. It has the first half functionality from
+ that routine.
+ * decl2.c (finish_vtable_vardecl): Update to not include stuff not
+ in finish_prevtable_vardecl.
+ * decl2.c (finish_file): Call finish_prevtable_vardecl.
+ * gc.c (build_generic_desc): Allow it to be called when not at the
+ global binding layer, but behave as if we were.
+ (build_t_desc): Rearrange a bit so that it really works and is
+ easier to follow.
+ * class.c (finish_struct): Don't decide on tdecls here, as we have
+ to wait until the end of the file in general to decide whether or
+ not they come out.
+
+Mon Jan 30 01:00:40 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_delete): Check access to operator delete before
+ calling the destructor.
+ * method.c (build_opfncall, DELETE_EXPR): build_method is allowed to
+ return error_mark_node.
+ * call.c (build_method_call): Use the one-argument op delete even if
+ it's an error.
+
+ * init.c (build_new): Fix -fthis-is-variable support.
+ * call.c (build_method_call): Likewise.
+
+ * call.c (convert_harshness): Make conversion from a pointer to bool
+ worse than conversion to another pointer.
+
+Sat Jan 28 16:46:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_new): Check new return value if -fcheck-new.
+
+ * lex.c (check_newline): Clear end_of_file when we're done, too.
+
+Sat Jan 28 10:38:39 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Make rtti TD tables follow
+ vtables whereever they go.
+
+ * gc.c (build_t_desc): Remove old way of setting it up, as it wasn't
+ right.
+
+Sat Jan 28 09:10:44 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Now set the
+ interface/implementation of vtables on the first virtual function,
+ if one exists, otherwise we use the old method. This is a major win
+ in terms of cutting down the size of objects and executables in
+ terms of text space and data space. Now most of the savings that
+ #pragma interface/implementation gives is automatic in a fair number
+ of cases.
+
+Sat Jan 28 04:57:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokdeclarator): Discard the template parameters in a
+ template constructor declaration so that the function is always
+ named constructor_name (ctype).
+
+ * lex.c (check_newline): Use ungetc to put back the character before
+ calling HANDLE_PRAGMA.
+
+Fri Jan 27 17:23:47 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (check_classfn): If the cname is T<int> and fn_name is T,
+ make sure we still match them.
+
+Fri Jan 27 16:32:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y: Add END_OF_LINE token.
+
+ * lex.c (check_newline): Set linemode when we see a # directive, and
+ unset it when we're done. Turn all 'return's into 'goto skipline'.
+ Fix all uses of '\n', since we won't see it anymore. Put back the
+ character we read before checking for a sysv or target pragma.
+ (real_yylex): If we see an EOF in linemode, return END_OF_LINE.
+ (handle_sysv_pragma): Don't look at the input stream; quit when we
+ see an END_OF_LINE token.
+
+ * input.c (getch): Return EOF if we're in line mode and at the end
+ of a line.
+ (put_back): Don't put back an EOF.
+
+Thu Jan 26 19:26:34 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Do the newing of the exception object
+ before we load the type descriptor or the address so that we don't
+ wipe any of the values out.
+
+Thu Jan 26 19:20:00 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (init_exception_processing): Don't use r12 on the rs6000.
+
+Tue Jan 24 16:36:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokparms): Don't try to build up a reference at this point.
+
+ * typeck2.c (build_functional_cast): Don't assume that a NOP_EXPR
+ will suffice to convert from integer_zero_node.
+
+Wed Jan 25 15:02:09 1995 David S. Miller <davem@nadzieja.rutgers.edu>
+
+ * class.c (instantiate_type): Change error message text.
+ * typeck2.c (store_init_value): Likewise.
+
+Mon Jan 23 21:57:14 1995 Mike Stump <mrs@cygnus.com>
+
+ * pt.c (tsubst): When we copy a node, don't forget to copy
+ TREE_CHAIN, we use it later.
+
+Mon Jan 23 03:33:47 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (convert_for_assignment): Initialize variable before use.
+
+Fri Jan 20 01:17:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * g++.c (main): Link with both libstdc++ and libg++ if called as
+ something ending with "g++", otherwise only libstdc++. Move -lm to
+ the end of the line.
+
+Thu Jan 19 15:43:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Don't mess with 'this' before calling
+ compute_conversion_costs.
+
+Wed Jan 18 15:40:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * search.c (get_matching_virtual): Give line number for previous
+ declaration.
+
+ * call.c (convert_harshness): Handle conversions to references
+ better.
+
+ * cvt.c (build_up_reference): OK, handle {MIN,MAX}_EXPR *properly*.
+
+Wed Jan 18 15:21:38 1995 Mike Stump <mrs@cygnus.com>
+
+ * class.c (instantiate_type): Use DECL_CHAIN to walk lists instead,
+ as the TREE_CHAIN for methods will take us to the next differently
+ named function, DECL_CHAIN won't.
+
+Wed Jan 18 14:26:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * tree.c (lvalue_p): Handle {MIN,MAX}_EXPR.
+
+ * decl2.c (lang_decode_option): -Wall implies -Wparentheses.
+ warn_parentheses defaults to 0.
+
+ * decl.c (grokparms): Put back call to require_instantiated_type.
+
+Tue Jan 17 19:56:15 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (exception_section): Use the data section on the rs6000.
+ Change calling convention for named_section.
+
+Wed Jan 17 18:20:57 1994 Fergus Henderson <fjh@munta.cs.mu.oz.au>
+
+ * cp-tree.h: Make if (x=0) warn with wall
+ * parse.y: Make if (x=0) warn with wall
+
+Tue Jan 17 14:12:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (BOOL_TYPE_SIZE): BITS_PER_WORD if SLOW_BYTE_ACCESS,
+ BITS_PER_UNIT otherwise.
+
+ * search.c (get_matching_virtual): Don't check the binfo if the
+ types are the same.
+
+ * cvt.c (cp_convert): Just call truthvalue_conversion to convert to
+ bool.
+
+Mon Jan 16 13:28:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * various: Use boolean_type_node, boolean_true_node,
+ boolean_false_node.
+
+ * search.c (get_matching_virtual): Allow covariant returns that
+ don't require pointer adjustment.
+
+ * typeck.c (build_conditional_expr): Don't call default_conversion
+ on ifexp.
+
+ * cvt.c (build_up_reference): Handle MIN_EXPR and MAX_EXPR.
+
+ * decl.c (grokdeclarator): Upgrade warning about &const to pedwarn.
+
+Sun Jan 15 22:17:32 1995 David Binderman <dcb@lovat.fmrco.COM>
+
+ * pt.c (do_function_instantiation): Free targs once we're done.
+
+Sun Jan 15 22:17:32 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (BOOL_TYPE_SIZE): Defaults to BITS_PER_WORD.
+ (init_decl_processing): Use BOOL_TYPE_SIZE instead of CHAR_TYPE_SIZE
+ for bool.
+
+Sat Jan 14 05:33:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (finish_file): We need to mess up if there are any
+ variables in the list, not just if there is one with a constructor.
+
+Fri Jan 13 14:42:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (duplicate_decls): Propagate DECL_STATIC_{CON,DE}STRUCTOR.
+ (finish_function): Handle DECL_STATIC_{CON,DE}STRUCTOR.
+ (finish_function): Trust rest_of_compilation.
+
+ * decl2.c (finish_file): Also call functions designated as static
+ constructors/destructors.
+
+ * decl.c (grokdeclarator): Allow access decls of operator functions.
+ (grokparms): Only do convert_for_initialization if the initializer
+ has a type.
+ (duplicate_decls): Put back push_obstacks_nochange call.
+
+ * lex.c (real_yylex): Downgrade complaint about the escape sequence
+ being too large from pedwarn to warning.
+
+ * decl.c (grokdeclarator): Don't complain about long long in system
+ headers.
+
+ * lex.c (real_yylex): Handle digraphs.
+
+Thu Jan 12 12:17:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (init_decl_processing): -f{no-,}strict-prototype only
+ affects C linkage declarations now.
+
+ * typeck.c (comp_target_types): Grok simple contravariant conversions.
+ (common_type): t1 and t2 are interchangeable.
+
+ * various: Test return value of comp_target_types differently in
+ different places; it now returns -1 for a contravariant conversion
+ (which is fine in symmetric cases).
+
+ (common_type): Prefer long double to double even when
+ they have the same precision.
+
+ * decl.c (grokparms): Call convert_for_initialization to check
+ default arguments.
+
+ * init.c (build_new): void_type_node has a size (of 0).
+
+ * decl.c (decls_match): Also check for agreement of TREE_READONLY
+ and TREE_THIS_VOLATILE.
+ (push_class_level_binding): Properly handle shadowing of
+ nested tags by fields.
+
+ * search.c (dfs_pushdecls): Likewise.
+
+ * decl2.c (finish_file): Don't second-guess self-initialization.
+
+ * cvt.c (convert_to_reference): Work with expr directly, rather than
+ a copy.
+
+ * decl.c (push_overloaded_decl): Only shadow artificial TYPE_DECLs.
+
+ * init.c (add_friend): Downgrade duplicate friend message from
+ pedwarn to warning.
+
+ * decl.c (duplicate_decls): Push obstacks before calling common_type.
+
+Thu Jan 12 17:15:21 1995 Michael Ben-Gershon <mybg@cs.huji.ac.il>
+
+ * except.c (push_eh_entry): Set LABEL_PRESERVE_P flag for
+ exception table labels.
+ (expand_start_all_catch): Likewise.
+ (expand_leftover_cleanups): Likewise.
+ (expand_end_catch_block): Likewise.
+ * except.c (make_first_label): New function.
+ (expand_start_all_catch): Add a call to make_first_label() before
+ using a label as a jump destination.
+ (expand_end_all_catch): Likewise.
+ (expand_leftover_cleanups): Likewise.
+ (expand_end_catch_block): Likewise.
+ (expand_builtin_throw): Likewise.
+ (expand_throw): Likewise.
+ * except.c: Add ARM processor support for exception handling.
+
+Thu Jan 12 12:17:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ (complete_array_type): Copy code from C frontend.
+
+ * lex.c (real_yylex): Don't multiply the length of a wide string
+ literal by WCHAR_BYTES.
+
+ * decl.c (pushdecl): Check for redeclaration of wchar_t here.
+ (duplicate_decls): Instead of here.
+ (define_label): Complain about a label named wchar_t.
+ (grokdeclarator): Complain about declarations of
+ operator-function-ids as non-functions.
+
+ * typeck.c (unary_complex_lvalue): Also wrap prefix -- and ++ in
+ COMPOUND_EXPRs.
+ (build_unary_op): Wrap unary plus in a NON_LVALUE_EXPR.
+
+ * lex.c (real_yylex): Don't skip whitespace when reading the next
+ character after ->.
+
+Wed Jan 11 16:32:49 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c: Allow cc1plus to be built with native compiler on rs6000.
+ (expand_start_all_catch): Add assemble_external calls for various
+ routines we call.
+ (expand_leftover_cleanups): Likewise.
+ (expand_start_catch_block): Likewise.
+ (do_unwind): Likewise.
+ (expand_builtin_throw): Likewise.
+
+Wed Jan 11 01:05:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (pushtag): Only look for a previous decl in the current
+ binding level. Use explicit global scope in DECL_NESTED_TYPENAME.
+
+ * gxx.gperf: Add __signature__ and __sigof__ keywords.
+
+ * decl2.c (lang_decode_option): -ansi does not set flag_no_asm. It
+ does set flag_no_gnu_keywords and flag_operator_names.
+
+ * lex.c (init_lex): 'overload' is not a keyword unless -traditional.
+ Unset extension keywords if -fno-gnu-keywords.
+ Allow operator names ('bitand') if -foperator-names.
+ Never unset 'asm'; -fno-asm only affects 'typeof'.
+
+ * decl.c (lookup_name_real): The got_object special lookup only
+ applies to types.
+
+Tue Jan 10 18:07:51 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * spew.c (yylex): Also use DECL_NESTED_TYPENAME if got_object is set.
+
+ * parse.y (primary): Unset got_object after all rules that use the
+ 'object' nonterminal.
+ (object): Set got_object.
+
+ * lex.h: Declare got_object.
+
+ * decl.c (lookup_name_real): Also lookup names in the context of an
+ object specified.
+
+Tue Jan 10 14:30:30 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Use ptrdiff_type_node
+ for things that have to be added to pointers, not size_type. Cures
+ problems with pointer to members on Alphas.
+ (build_binary_op_nodefault): Likewise.
+ (get_delta_difference_: Likewise.
+ (build_ptrmemfunc): Likewise.
+
+Tue Jan 10 01:49:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (pushtag): Stick the new decl in TYPE_NAME before pushing
+ it.
+
+ * typeck.c (build_component_ref): Don't build up a COMPONENT_REF
+ when dealing with overloaded member functions; just act like
+ build_offset_ref.
+ (commonparms): Remove misleading comment.
+
+ * decl.c (duplicate_decls): Complain about repeated default
+ arguments here.
+ (redeclaration_error_message): Instead of here.
+ (pushdecl): Complain about missing default arguments here.
+ (grokparms): Instead of here.
+ (lookup_name_current_level): Also match on DECL_ASSEMBLER_NAME.
+ (grok_reference_init): Do not complain about missing initializer if
+ declared 'extern'.
+
+ * search.c (lookup_field): Don't return a TYPE_DECL if there is a
+ function alternative and want_type is not set.
+
+Mon Jan 9 18:16:23 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (pushtag): Don't set TYPE_NAME to an identifier. Do push
+ the decl when the type has no TYPE_NAME.
+ (lookup_nested_type): Don't assume that type has TYPE_NAME set.
+ (lookup_name_real): Call lookup_field with want_type =
+ prefer_type.
+
+ * search.c (lookup_field): Handle want_type properly in the presence
+ of fields with the same name.
+
+ * decl.c (set_nested_typename): Set nested name for file-scope types
+ to include leading ::.
+ (pushdecl): Set the nested typename if the decl doesn't have one,
+ rather than if the type's canonical decl doesn't have one.
+
+Mon Jan 9 03:44:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (convert_for_assignment): Complain about contravariance
+ violation here.
+ (comp_target_types): Instead of here.
+ (build_unary_op): resolve_offset_ref before checking for a valid
+ type.
+
+ * spew.c (yylex): Decrement looking_for_typename after we see a
+ _DEFN.
+
+ * decl.c (pushdecl): Don't install an artificial TYPE_DECL in
+ IDENTIFIER_LOCAL_VALUE if we already have a decl with that name.
+
+ * typeck.c (convert_for_assignment): Converting pointers to bool
+ does not need a cast.
+
+Sun Jan 8 18:16:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (instantiate_type): Initialize nsubsts parm.
+
+ * pt.c (do_function_instantiation): Likewise.
+
+Sat Jan 7 14:37:05 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (tsubst): Use TREE_STATIC instead of DECL_INLINE &&
+ DECL_SAVED_INSNS to determine whether or not we've seen a definition
+ of this function.
+ (instantiate_template): Likewise.
+
+ * call.c (convert_harshness): Allow const reference binding when
+ called from the overloading code, but not when called from
+ can_convert (since it isn't a conversion).
+ (convert_harshness): Put back some disabled code.
+
+Fri Jan 6 14:10:57 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (convert_harshness): There is no implicit conversion from
+ void* to other pointer types (unless the parameter is (void*)0).
+ (convert_harshness): Non-lvalues do not convert to reference types.
+
+ * class.c (finish_struct_methods): Still set
+ TYPE_HAS_{INT,REAL}_CONVERSION.
+
+ * call.c (can_convert): Don't use aggregate initialization.
+
+ * cp-tree.h: Declare lookup_conversions.
+
+Thu Jan 5 21:08:00 1995 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (simple_stmt): Fix duplicate case value error messages to
+ be more readable.
+
+Wed Jan 4 16:44:19 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cvt.c (build_type_conversion): Total rewrite to use
+ convert_harshness instead of reproducing conversion logic here. Now
+ much shorter.
+
+ * call.c (convert_harshness): Support conversions to bool.
+ (can_convert): Checks whether a conversion is less harsh
+ than USER_CODE, for build_type_conversion.
+
+ * search.c (add_conversions): Function for passing to dfs_walk which
+ adds all the type conversion operators in the current type to a list.
+ (lookup_conversions): Calls dfs_walk with add_conversions and return
+ the list.
+ (dfs_walk): Don't require a qfn.
+
+ * cp-tree.h: Lose CLASSTYPE_CONVERSIONS hackery.
+ (CLASSTYPE_FIRST_CONVERSION): Points to elt 1 of CLASSTYPE_METHOD_VEC.
+
+ * class.c (finish_struct_bits): Lose CLASSTYPE_CONVERSIONS hackery.
+ (grow_method): A separate function for building onto the growing
+ method vector.
+ (finish_struct_methods): Use it. Put all type conversion operators
+ right after the constructors. Perhaps we should sort the methods
+ alphabetically?
+
+Mon Jan 2 14:42:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Lose another misleading shortcut.
+
+
+Copyright (C) 1995 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-1996 b/gcc-4.9/gcc/cp/ChangeLog-1996
new file mode 100644
index 000000000..d13f24567
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-1996
@@ -0,0 +1,4053 @@
+Tue Dec 31 20:25:50 1996 Mike Stump <mrs@cygnus.com>
+
+ * search.c (expand_upcast_fixups): Fix bogus code generation
+ problem where the generated code uses the wrong index into the
+ runtime built vtable on the stack. Old code could clobber random
+ stack values.
+
+Tue Dec 31 15:16:56 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (perform_member_init): Make sure the partial EH cleanups
+ live on the function_obstack.
+
+Fri Dec 27 10:31:40 1996 Paul Eggert <eggert@twinsun.com>
+
+ * Make-lang.in (g++spec.o): Don't use $< with an explicit target;
+ this isn't portable to some versions of `make' (e.g. Solaris 2.5.1).
+
+Tue Dec 24 10:24:03 1996 Jeffrey A Law <law@cygnus.com>
+
+ * decl.c (grokvardecl): Avoid ANSI style initialization.
+
+Sun Dec 22 04:22:06 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Tweak arg types for a FUNCTION_TYPE.
+
+Fri Dec 20 17:09:25 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Call grok_{ctor,op}_properties.
+
+Fri Dec 20 12:17:12 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * g++spec.c (lang_specific_driver): Put missing hyphen in front of
+ arguments we compare against. Start the count of I at 1, not 0,
+ since argv[0] is still the command.
+
+Thu Dec 19 11:53:57 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * lang-specs.h: Accept .cp as an C++ extension.
+
+Mon Dec 16 22:43:31 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (ptr_reasonably_similar): Add decl.
+
+Thu Dec 12 15:00:35 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokvardecl): Change SPECBITS parm to be the SPECBITS_IN
+ pointer. New local SPECBITS with the parm's value.
+ (grokdeclarator): Pass &specbits down.
+
+ * parse.y (expr_no_commas): Make sure $$ is not an error_mark_node
+ before we try to do C_SET_EXP_ORIGINAL_CODE on it.
+
+ * search.c (envelope_add_decl): Check that the CLASSTYPE_CID of
+ CONTEXT is not 0 before we try to use TYPE_DERIVES_FROM.
+
+ * decl.c (cplus_expand_expr_stmt): Only expand the expr if EXP is
+ not an error_mark_node.
+
+Sat Dec 7 17:20:22 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (TYPE_MAIN_DECL): Use TYPE_STUB_DECL.
+ * *.c: Use TYPE_MAIN_DECL instead of TYPE_NAME where appropriate.
+
+Fri Dec 6 14:40:09 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): When giving an anonymous struct a name,
+ replace TYPE_NAME instead of TYPE_IDENTIFIER (so TYPE_STUB_DECL is
+ not affected).
+
+ * typeck2.c (build_m_component_ref): If component is a pointer
+ to data member, resolve the OFFSET_REF now.
+
+ * call.c (convert_like): Don't go into infinite recursion.
+
+ * pt.c (coerce_template_parms): Use tsubst_expr for non-type args.
+
+ * class.c (finish_struct_1): Set DECL_ARTIFICIAL on the vptr.
+ * tree.c (layout_basetypes): And on the vbase ptr.
+
+Thu Dec 5 02:11:28 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (BOOL_TYPE_SIZE): Define in terms of POINTER_SIZE or
+ CHAR_TYPE_SIZE so bool is always the same size as another type.
+
+ * decl.c (pushtag): Set DECL_IGNORED_P for DWARF, too.
+
+Tue Dec 3 23:18:37 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (grok_x_components): Remove synthesized methods from
+ TYPE_METHODS of an anonymous union, complain about member
+ functions.
+ * decl.c (shadow_tag): Wipe out memory of synthesized methods in
+ anonymous unions.
+ (finish_function): Just clear the DECL_RTL of our arguments.
+
+Fri Nov 29 21:54:17 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Emit DWARF debugging info for static data
+ members.
+
+ * pt.c (tsubst): If t is a stub decl, return the stub decl for type.
+
+Wed Nov 27 14:47:15 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * typeck.c (build_component_ref): Don't die if COMPONENT isn't a
+ IDENTIFIER_NODE.
+
+Wed Nov 27 16:05:19 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Make-lang.in (g++-cross$(exeext)): Fix typo.
+
+Wed Nov 27 08:14:00 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ Make the g++ driver now be a standalone program, rather than one
+ that tries to run the gcc driver after munging up the options.
+ * Make-lang.in (g++.c, g++spec.o): New rules.
+ (g++.o): New rule, based on gcc.o with -DLANG_SPECIFIC_DRIVER
+ added.
+ (g++$(exeext)): New rule, based on xgcc rule.
+ (g++-cross$(exeext)): Now just copies g++$(exeext) over.
+ * g++spec.c: New file.
+ * g++.c: Removed file.
+
+Tue Nov 26 19:01:09 1996 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (build_up_reference): Arrange for any temporary values
+ that have been keep in registers until now to be put into memory.
+
+Mon Nov 25 15:16:41 1996 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (c++.stage[1234]): Depend upon stage[1-4]-start, so
+ that make -j3 bootstrap works better.
+
+Sun Nov 24 02:09:39 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (pushtag): Do pushdecl for anon tags.
+
+Thu Nov 21 16:30:24 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (c_expand_return): Fix logic.
+ (unary_complex_lvalue): Avoid unused warning on address of INIT_EXPR.
+
+Wed Nov 20 18:47:31 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * g++.c (main): Make sure arglist has a final NULL entry. Add
+ PEXECUTE_LAST to the flags passed to pexecute, as otherwise
+ stdin/stdout of the invoked program are redirected to
+ nowheresville.
+
+Tue Nov 19 16:12:44 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (implicitly_declare): Set DECL_ARTIFICIAL.
+
+Tue Nov 19 15:48:19 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (resolve_offset_ref): Handle obj.vfn better.
+ * typeck.c (build_component_ref): Set TREE_TYPE on result from
+ build_vfn_ref.
+
+Tue Nov 19 13:14:33 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (convert_for_assignment): Also handle anachronistic
+ implicit conversions from (::*)() to cv void*.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+
+Mon Nov 18 17:05:26 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (handle_cp_pragma): Fix bogus warning.
+
+Mon Nov 18 16:10:43 1996 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Avoid thinking a POINTER_TYPE
+ (METHOD_TYPE) is a TYPE_PTRMEMFUNC_P.
+
+Thu Nov 14 23:18:17 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_1): Support DWARF2_DEBUG.
+ * search.c (dfs_debug_mark): Likewise.
+ * decl2.c (finish_vtable_vardecl): Likewise.
+ * decl.c (pushtag, finish_enum): Likewise.
+ * lex.c (check_newline): Use debug_* instead of calling *out
+ functions directly.
+
+Thu Nov 14 15:21:46 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Make-lang.in (cplib2.ready): Add else clause to avoid problems
+ on some picky hosts.
+
+Wed Nov 13 12:32:07 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_1): A class has a non-trivial copy
+ constructor if it has virtual functions.
+
+ * cvt.c (cp_convert): Always call a constructor.
+
+ * call.c (reference_binding): Still tack on a REF_BIND
+ for bad conversions.
+ (build_user_type_conversion_1): Propagate ICS_BAD_FLAG.
+
+ * typeck.c (convert_arguments): Pass LOOKUP_ONLYCONVERTING.
+ (c_expand_return): Likewise.
+ * typeck2.c (digest_init): Likewise for { }.
+ * init.c (expand_aggr_init_1): Keep the CONSTRUCTOR handling.
+ * cvt.c (cp_convert): Handle failure better.
+
+Wed Nov 13 11:51:20 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * g++.c (main): Also set PEXECUTE_SEARCH, to make the invocation
+ of GCC be path-relative.
+
+Wed Nov 13 11:27:16 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Make-lang.in (g++-cross): G++-cross doesn't need version.o, but
+ it does need choose-temp.o and pexecute.o.
+
+Wed Nov 13 07:53:38 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * g++.c (error) [!HAVE_VPRINTF]: Put error back for the only time
+ that we still use it.
+ (P_tmpdir, R_OK, W_OK, X_OK) [__MSDOS__]: Delete unnecessary macros.
+
+Wed Nov 13 02:00:26 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (expand_default_init): Avoid calling constructors to
+ initialize reference temps.
+
+ * cvt.c (convert_to_reference): Fix.
+
+Tue Nov 12 19:10:07 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (cp_convert): Simplify for flag_ansi_overloading.
+ (convert_to_reference): Likewise.
+ * typeck.c (convert_for_initialization): Likewise.
+ * init.c (expand_default_init): Likewise.
+ (expand_aggr_init_1): Likewise.
+ * cp-tree.h (CONV_NONCONVERTING): Lose.
+ * typeck.c (build_c_cast): Lose allow_nonconverting parm.
+ * *.c: Adjust.
+ * call.c (build_user_type_conversion_1): Assume LOOKUP_ONLYCONVERTING.
+
+Tue Nov 12 16:29:04 1996 Brendan Kehoe <brendan@canuck.cygnus.com>
+
+ * pt.c (tsubst_expr): Reverse args to expand_start_catch_block.
+
+Tue Nov 12 15:26:17 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (expand_aggr_init_1): Don't crash on non-constructor
+ TARGET_EXPR.
+
+Tue Nov 12 14:00:50 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * g++.c: Include gansidecl.h.
+ (VPROTO, PVPROTO, VA_START): Delete.
+ (choose_temp_base_try, choose_temp_base, perror_exec,
+ run_dos) [__MSDOS__]: Delete fns.
+ (pfatal_with_name): Delete fn.
+ (temp_filename): Declare like in gcc.c.
+ (pexecute, pwait, choose_temp_base): Declare from gcc.c.
+ (error_count, signal_count): Define.
+ (error): Delete both definitions.
+ (PEXECUTE_{FIRST,LAST,SEARCH,VERBOSE}): Define from gcc.c.
+ (pfatal_pexecute): Add fn from gcc.c.
+ (main): Rename local VERBOSE var to VERBOSE_FLAG. Rewrite the
+ code to use the pexecute stuff also used by gcc.c.
+ (MIN_FATAL_STATUS): Define.
+ * Make-lang.in (g++): Add dependency on and linking with
+ choose-temp.o and pexecute.o.
+
+ * cp-tree.h: Include gansidecl.h.
+ (STDIO_PROTO): Delete #undef/#define.
+ * cvt.c (NULL): Delete #undef/#define.
+ * expr.c (NULL): Likewise.
+ * init.c (NULL): Likewise.
+ * rtti.c (NULL): Likewise.
+ * xref.c (NULL): Likewise.
+
+ * cp-tree.h (build_user_type_conversion): Add prototype.
+ * call.c (build_user_type_conversion): Delete prototype. Correct
+ decl of FLAGS arg to be an int.
+ * cvt.c (build_user_type_conversion): Likewise.
+
+Tue Nov 12 12:16:20 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.def: Add TRY_BLOCK and HANDLER.
+ * except.c (expand_start_catch_block): Support templates.
+ * parse.y (try_block, handler_seq): Likewise.
+ * pt.c (tsubst_expr): Support TRY_BLOCK and HANDLER.
+
+Mon Nov 11 13:57:31 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (current_template_args): New fn.
+ (push_template_decl): Use it.
+ * decl.c (grokdeclarator): Use it.
+
+ * decl2.c (build_expr_from_tree): Dereference ref vars.
+
+ * decl.c (grokdeclarator): Generalize handling of TYPENAME_TYPEs in
+ the decl-specifier-seq.
+
+ * decl.c (grok_op_properties): Don't force the type of a conversion
+ op to be complete. Don't warn about converting to the same type
+ for template instantiations.
+
+ * decl2.c (finish_file): Don't call instantiate_decl on synthesized
+ methods.
+
+Mon Nov 11 13:20:34 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * typeck.c (get_delta_difference): Remove previous bogusness.
+ Don't give errors if force is set.
+
+Fri Nov 8 17:38:44 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Don't emit debug info.
+ * decl.c (pushdecl): Lose obsolete code.
+ (grokdeclarator): Still do the long long thing after complaining.
+ * search.c (note_debug_info_needed): Don't do anything if we're in a
+ template.
+ * method.c (synthesize_method): For non-local classes,
+ push_to_top_level first.
+
+Fri Nov 8 11:52:28 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * typeck.c (get_delta_difference): Add no_error parameter.
+ (build_ptrmemfunc): Call get_delta_difference with no_error set;
+ we don't want error messages when converting unrelated
+ pointer-to-member functions.
+
+Thu Nov 7 11:16:24 1996 Mike Stump <mrs@cygnus.com>
+
+ * error.c (dump_expr): Improve the wording on error messages that
+ involve pointer to member functions.
+
+Tue Nov 5 17:12:05 1996 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Move code for conversions from
+ (::*)() to void* or (*)() up a bit, so that we can convert from
+ METHOD_TYPEs as well.
+
+Tue Nov 5 14:54:17 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (get_tinfo_fn): Make sure 'type' is permanent.
+ There are no 'member' types.
+ (get_tinfo_fn_dynamic): Diagnose typeid of overloaded fn.
+ (build_x_typeid): Handle errors.
+
+Mon Nov 4 17:43:12 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (convert_for_assignment): Handle anachronistic implicit
+ conversions from (::*)() to void* or (*)().
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (cp_convert_to_pointer_force): Remove cp_convert_to_pointer
+ conversions from here.
+ * decl2.c (lang_decode_option): Add -W{no-,}pmf-conversions.
+ * lang-options.h: Likewise.
+ * decl2.c (warn_pmf2ptr): Define.
+ * cp-tree.h: Declare it.
+ * typeck2.c (digest_init): Allow pmfs down into
+ convert_for_initialization.
+
+Sun Nov 3 09:43:00 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (c_expand_return): Fix for returning overloaded fn.
+
+Fri Nov 1 08:53:17 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (DIRECT_BIND): Change from INDIRECT_BIND.
+ * decl.c (grok_reference_init): Pass DIRECT_BIND.
+ * cvt.c (build_up_reference): Don't mark 'this' addressable. Use
+ DIRECT_BIND.
+ * call.c (convert_like): Don't pass INDIRECT_BIND.
+ * typeck.c (convert_arguments): Likewise.
+ * typeck.c (mark_addressable): Allow &this if flag_this_is_variable.
+
+Thu Oct 31 17:08:49 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (mark_addressable): Support TARGET_EXPR, unify with
+ similar code in build_up_ref.
+ * cvt.c (build_up_reference): Drastically simplify.
+
+Mon Oct 28 12:45:05 1996 Jeffrey A Law <law@cygnus.com>
+
+ * typeck.c (signed_or_unsigned_type): If the given type already
+ as the correct signedness, then just return it.
+
+ * typeck.c ({un,}signed_type): If can't do anything, call
+ signed_or_unsigned_type.
+
+Thu Oct 24 14:21:59 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * decl2.c (copy_assignment_arg_p): Don't buy the farm if
+ current_class_type is NULL.
+
+Wed Oct 23 00:43:10 1996 Jason Merrill <jason@gerbil.cygnus.com>
+
+ * class.c (finish_struct_1): Avoid empty structs by adding a field
+ so layout_type gets the mode right.
+
+ * typeck.c (c_expand_return): Drastically simplify.
+
+Mon Oct 21 22:34:02 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (decay_conversion): Handle overloaded methods.
+
+Fri Oct 18 16:03:48 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): A TARGET_EXPR has side-effects.
+
+Thu Oct 17 11:31:59 1996 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (convert_to_pointer_force): Add code to support pointer to
+ member function to pointer to function conversions.
+ * init.c (resolve_offset_ref): Add code to allow faked up objects,
+ ignoring them if they are not used, and giving an error, if they
+ are needed.
+ * typeck.c (get_member_function_from_ptrfunc): Fold e1 to improve
+ code, and so that we can give an error, if we needed an object,
+ and one was not provided.
+ (build_c_cast): Don't call default_conversion when we want to
+ convert to pointer to function from a METHOD_TYPE.
+
+Mon Oct 14 00:28:51 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Make-lang.in (cplib2.ready): Fix logic.
+
+ * decl.c (shadow_tag): Only complain about non-artificial function
+ members.
+
+ * class.c (finish_struct_1): Add synthesized methods to TYPE_METHODS.
+
+Fri Oct 11 16:12:40 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * expr.c (cplus_expand_expr): Pre-tweak call_target like
+ expand_inline_function would.
+
+ * pt.c (mark_decl_instantiated): If extern_p, call
+ mark_inline_for_output.
+
+Thu Oct 10 15:58:08 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (unary_complex_lvalue): Add code to handle intermediate
+ pmd conversions.
+
+ * typeck.c (get_delta_difference): Fix wording, as we can be used
+ for pointer to data members.
+
+Tue Oct 8 12:43:51 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * pt.c (tsubst): If the function decl isn't a member of this
+ template, return a copy of the decl (including copying the
+ lang-specific part) so we don't hose ourselves later.
+
+Thu Oct 3 16:24:28 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct): Remove DWARF-specific tag handling.
+ * decl.c (pushtag): Likewise.
+ (finish_function): Always clear DECL_ARGUMENTS on function decls with
+ no saved RTX.
+ * decl2.c (finish_file): Emit DWARF debugging info for static data
+ members.
+
+Wed Oct 2 21:58:01 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * decl.c (duplicate_decls): Make sure the old DECL_LANG_SPECIFIC
+ isn't the same as the new one before we whack it.
+
+Mon Sep 30 13:38:24 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c, cp-tree.h, cvt.c, decl.c, decl2.c, gxx.gperf, hash.h,
+ lex.c, method.c, parse.y, typeck.c, typeck2.c: Remove
+ warn_traditional and warn_strict_prototypes; remove ancient
+ 'overload' code; remove references to flag_traditional.
+
+Mon Sep 30 12:58:40 1996 Mike Stump <mrs@cygnus.com>
+
+ * input.c (sub_getch): Handle 8-bit characters in string literals.
+
+Sun Sep 29 03:12:01 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (mapcar): Handle CONSTRUCTORs.
+ (copy_to_permanent): Handle expression_obstack properly.
+
+ * Make-lang.in (cplib2.txt): Also depend on the headers.
+
+ * rtti.c (get_tinfo_var): Don't assume that POINTER_SIZE ==
+ INT_TYPE_SIZE.
+ (expand_class_desc): Use USItype for offset field.
+ * tinfo.h (struct __class_type_info): Likewise.
+
+ * method.c (build_overload_int): TYPE_PRECISION should be applied
+ to types.
+
+Sat Sep 28 14:44:50 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_new_op): A COND_EXPR involving void must be a
+ builtin.
+
+Fri Sep 27 16:40:30 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_x_component_ref): New fn.
+ (build_object_ref): Use it.
+ * parse.y (primary): Use it.
+ * decl2.c (build_expr_from_tree): Use it.
+ * cp-tree.h: Declare it.
+
+ * decl.c (start_decl): Variable-sized arrays cannot be initialized.
+ * error.c (dump_type_suffix): Handle variable arrays.
+
+Fri Sep 27 13:14:05 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Make-lang.in (exception.o): Put back compiling it with -fPIC.
+
+Fri Sep 27 03:00:09 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_name_real): Don't try to look up anything in a
+ TYPENAME_TYPE.
+
+ * tinfo2.cc (__throw_type_match_rtti): Oops.
+
+Thu Sep 26 22:11:05 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Make-lang.in (exception.o): Use -fno-PIC for now.
+
+Thu Sep 26 10:59:00 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (build_dynamic_cast): Pass tinfo fns rather than
+ calling them.
+ (get_tinfo_fn_dynamic): Extracted from build_typeid.
+ * tinfo2.cc (__dynamic_cast): Adjust.
+
+ * rtti.c (build_typeid): Use resolves_to_fixed_type_p.
+ (build_x_typeid): Likewise.
+
+ * parse.y: Call build_x_typeid instead of build_typeid.
+ * cp-tree.def: Add TYPEID_EXPR.
+ * pt.c (tsubst_copy): Handle typeid.
+ * decl2.c (build_expr_from_tree): Likewise.
+ * rtti.c (build_x_typeid): Throw bad_typeid from here.
+ (build_typeid): Not here.
+ * cp-tree.h: Declare build_x_typeid.
+
+Wed Sep 25 17:26:16 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (convert_like): Pull out constant values.
+
+ * tree.c (mapcar): Use build_cplus_array_type, not build_array_type.
+
+Wed Sep 25 17:28:53 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * decl.c (init_decl_processing): Create short int types before
+ creating size_t in case a machine description needs to use
+ unsigned short for size_t.
+
+Tue Sep 24 18:18:44 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Make-lang.in (exception.o): Turn off pic.
+
+ * tinfo2.cc (__throw_type_match_rtti): Fix cv-variants of the same
+ type, multi-level ptr conversions.
+
+ * rtti.c (call_void_fn): Renamed and genericized from throw_bad_cast.
+ (throw_bad_cast): Use it.
+ (throw_bad_typeid): New fn.
+ (build_typeid): Throw bad_typeid as needed.
+ Use build_call.
+ (synthesize_tinfo_fn): Handle functions and arrays before checking
+ for cv-quals.
+
+ * Remove .h from standard C++ headers, add new.h, move into inc
+ subdirectory.
+
+ * exception*: Remove pointer from object, constructors. Add
+ default exception::what that uses type_info::name. Add
+ __throw_bad_typeid.
+
+ * init.c (build_new): Don't add a cookie to new (void *) T[2].
+
+Mon Sep 23 15:21:53 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Make-lang.in: Building C++ code depends on cc1plus.
+
+Mon Sep 23 12:38:40 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (struct saved_scope): Declare PROCESSING_TEMPLATE_DECL as
+ a HOST_WIDE_INT, not a tree.
+
+Mon Sep 23 12:36:02 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * exception.cc: Don't include <stdlib.h>.
+
+ * Make-lang.in (c++.clean): Remove cplib2.*.
+
+Mon Sep 23 09:42:19 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * parse.y (component_decl_1, component_costructor_declarator case):
+ Pass attributes/prefix_attributes in tree list.
+
+Mon Sep 23 01:18:50 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo{,2}.cc: #include <stddef.h> instead of <stdlib.h>.
+
+Sun Sep 22 05:31:22 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (do_identifier): Don't do deferred lookup in a template
+ header.
+
+ * typeck2.c (store_init_value): Oops.
+
+ * new.{h,cc}, exception.{h,cc}, typeinfo.h, tinfo{2.cc,.cc,.h}:
+ New files for C++ lang-support library.
+ * Make-lang.in (CXX_EXTRA_HEADERS): Define.
+ (CXX_LIB2FUNCS): Define.
+ And rules for building the C++ lang-support code.
+ * config-lang.in (headers): Define.
+ (lib2funcs): Define.
+
+Sat Sep 21 19:17:28 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (build_expr_from_tree): If CONSTRUCTOR has a type, call
+ digest_init.
+ * pt.c (tsubst_copy): Compute type for CONSTRUCTOR.
+ * typeck2.c (store_init_value): Check for initializing pmf with { }
+ here.
+ (process_init_constructor): Not here.
+
+Thu Sep 19 16:41:07 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (begin_template_parm_list): Increment
+ processing_template_decl here.
+ (end_template_parm_list): Not here.
+ (process_template_parm): No need to add 1 to it now.
+ * *.c: Use processing_template_decl instead of current_template_parms
+ to check for being in a template.
+
+ * pt.c (uses_template_parms): Handle SCOPE_REF. Fix CONSTRUCTOR.
+ (tsubst_copy): Handle CONSTRUCTOR.
+ (instantiate_decl): Set up context properly for variables.
+ * decl2.c (build_expr_from_tree): Handle CONSTRUCTOR.
+ * class.c (finish_struct): Reverse CLASSTYPE_TAGS.
+
+Wed Sep 18 13:30:20 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lex.c (enum tree_node_kind) [GATHER_STATISTICS]: Put the enum back.
+
+Wed Sep 18 04:24:07 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (make_thunk): Call comdat_linkage before setting the
+ TREE_CODE.
+
+ * decl2.c (comdat_linkage): Use make_decl_one_only.
+ (import_export_decl): Likewise.
+ * decl.c (init_decl_processing): Check supports_one_only instead of
+ SUPPORTS_WEAK.
+
+Sat Sep 14 08:34:41 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (grokfield): Tighten checking for access decls.
+
+ * decl.c (make_typename_type): Resolve references to
+ current_class_type. Set CLASSTYPE_GOT_SEMICOLON.
+ (lookup_name_real): Types that depend on a template parameter get
+ an implicit 'typename' unless they're in the current scope.
+ (start_decl_1): We don't care about incomplete types that depend
+ on a template parm.
+ (grokdeclarator): Resolve 'typename's in the type specifier that
+ refer to members of the current scope.
+
+ * call.c (build_over_call): Remove 'inline called before
+ definition' diagnostic.
+ (build_method_call): Likewise.
+ * decl.c (duplicate_decls): Downgrade 'used before declared
+ inline' to a warning, only with -Winline.
+
+Fri Sep 13 17:31:40 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Fix include paths, add @DASH_C_FLAG@ to compile.
+
+Wed Sep 11 22:38:13 1996 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * call.c (build_method_call): When calling a signature
+ default implementation, as in other cases, let instance_ptr simply
+ be instance.
+
+Wed Sep 11 22:14:44 1996 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (simple_stmt): Cleanup and use do_poplevel ().
+
+Wed Sep 11 22:10:48 1996 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_catch_block): Add a pushlevel so that -g
+ works on hppa and SPARC.
+
+Wed Sep 11 10:18:06 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (build_indirect_ref): Catch PTR being an error_mark_node.
+
+Mon Sep 9 19:51:14 1996 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * call.c (build_over_call): Check first whether DECL_CONTEXT exists
+ before testing whether it's a signature.
+
+Sun Sep 8 16:06:57 1996 Gerald Baumgartner <gb@cs.purdue.edu>
+
+ * call.c (build_new_method_call): Don't complain about signature
+ pointers and references not being an aggr type.
+ (build_this): If a signature pointer or reference was passed in,
+ just return it.
+ (build_new_method_call): If instance is a signature pointer, set
+ basetype to the signature type of instance.
+ * sig.c (build_signature_method_call): Deleted basetype and
+ instance parameters, they can be found as the DECL_CONTEXT of
+ function and as the first argument passed in.
+ * cp-tree.h: Changed declaration of build_signature_method_call.
+ * call.c (build_method_call): Deleted first two arguments in call
+ of build_signature_method_call.
+ (build_over_call): Added call to build_signature_method_call.
+
+Thu Sep 5 16:51:28 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_c_cast): Don't tack a non_lvalue_expr onto a
+ target_expr.
+
+Thu Sep 5 10:05:38 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cvt.c (convert_to_reference): Use %#T, not %#D, for error.
+
+Wed Sep 4 17:16:09 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * except.c (expand_start_try_stmts): Move to except.c in the backend.
+ (expand_end_try_stmts): Remove.
+
+ * init.c (perform_member_init): Use add_partial_entry () instead
+ of directly manipulating lists.
+ (emit_base_init): Likewise.
+
+Wed Sep 4 12:14:36 1996 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_exception_blocks): Always make sure USE and
+ CLOBBER insns that came at the end still do, the backend relies
+ upon this.
+
+Wed Sep 4 07:44:48 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): We can only use a TARGET_EXPR of the
+ right type.
+
+Tue Sep 3 19:26:05 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (convert_to_reference): Revert last change, don't complain
+ about temp without target decl.
+
+Tue Sep 3 10:22:56 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (grokdeclarator): Don't core dump when void() is given.
+
+Tue Sep 3 02:38:56 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (copy_args_p): Don't crash.
+
+Fri Aug 30 14:26:57 1996 Mike Stump <mrs@cygnus.com>
+
+ * pt.c (tsubst): And support template args inside the exception
+ specification.
+
+ * pt.c (tsubst): Add support for exception specifications in
+ template functions.
+
+Fri Aug 30 10:01:55 1996 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.def (DECL_STMT): Eliminate the throw spec field, only 3
+ fields now.
+ * cp-tree.h (start_decl): Eliminate the throw spec parameter.
+ (start_function): Likewise.
+ (start_method): Likewise.
+ (grokfield): Likewise.
+ (make_call_declarator): Add throw spec parameter.
+ (set_quals_and_spec): Add routine.
+ * lex.c (set_quals_and_spec): Likewise.
+ * decl.h (grokdeclarator): Eliminate the throw spec parameter.
+ * decl.c (shadow_tag): Eliminate the throw spec parameter to
+ grokdeclarator.
+ (groktypename): Likewise.
+ (start_decl): Eliminate the throw spec parameter. Eliminate the
+ throw spec parameter to grokdeclarator. Eliminate the throw spec
+ field in DECL_STMT.
+ (cp_finish_decl): Eliminate the throw spec field in DECL_STMT.
+ (grokfndecl): Remove useless set of raises.
+ (grokdeclarator): Eliminate the throw spec parameter. Eliminate
+ the throw spec parameter to start_decl. Pull the throw spec out
+ of the call declarator.
+ (grokparms): Eliminate the throw spec parameter to grokdeclarator.
+ (start_function): Eliminate the throw spec parameter. Eliminate
+ the throw spec parameter to grokdeclarator.
+ (start_method): Likewise.
+ * decl2.c (grokfield): Likewise.
+ (grokbitfield): Eliminate the throw spec parameter to grokdeclarator.
+ (grokoptypename): Likewise.
+ (finish_file): Eliminate the throw spec parameter to
+ start_function. Add throw spec to make_call_declarator.
+ * except.c (init_exception_processing): Add throw spec to
+ make_call_declarator. Eliminate the throw spec parameter to
+ start_decl.
+ (expand_start_catch_block): Eliminate the throw spec parameter to
+ grokdeclarator.
+ (expand_builtin_throw): Add throw spec to make_call_declarator.
+ Eliminate the throw spec parameter to start_function.
+ (start_anon_func): Likewise.
+ * lex.c (make_call_declarator): Add throw spec parameter.
+ (set_quals_and_spec): New routine.
+ (cons_up_default_function): Add throw spec to make_call_declarator.
+ Eliminate the throw spec parameter to grokfield.
+ * method.c (synthesize_method): Eliminate the throw spec parameter
+ to start_function.
+ * pt.c (process_template_parm): Eliminate the throw spec parameter
+ to grokdeclarator.
+ (tsubst): Add throw spec to make_call_declarator.
+ (tsubst_expr): Eliminate the throw spec parameter to start_decl.
+ (do_function_instantiation): Eliminate the throw spec parameter to
+ grokdeclarator. Eliminate the throw spec parameter to
+ start_function.
+ * rtti.c (synthesize_tinfo_fn): Eliminate the throw spec parameter
+ to start_function.
+ * parse.y (datadef): Remove non-winning optimization.
+ (decl): Likewise.
+ (fndef): Remove ambiguous error productions uncovered by grammar
+ fixing.
+ (constructor_declarator): Add exception_specification_opt here.
+ (component_constructor_declarator): Likewise.
+ (direct_after_type_declarator): Likewise.
+ (complex_direct_notype_declarator): Likewise.
+ (direct_abstract_declarator): Likewise.
+ (fn.def1): Remove exception_specification_opt.
+ (fn.def2): Likewise.
+ (condition): Likewise.
+ (initdcl0): Likewise.
+ (initdcl): Likewise.
+ (notype_initdcl0): Likewise.
+ (nomods_initdcl0): Likewise.
+ (component_decl_1): Likewise.
+ (component_declarator): Likewise.
+ (after_type_component_declarator0): Likewise.
+ (after_type_component_declarator): Likewise.
+ (notype_component_declarator): Likewise.
+
+Wed Aug 28 01:40:30 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): Also use an INIT_EXPR when
+ initializing anything from an rvalue.
+
+ * call.c (build_over_call): Call stabilize_reference when building
+ an INIT_EXPR instead of calling the copy ctor.
+
+ * call.c (joust): Extend the previous change to all comparisons.
+
+ * decl2.c, method.c, lex.c: Use MAKE_DECL_ONE_ONLY and
+ NO_LINKAGE_HEURISTICS.
+
+ * decl2.c (finish_file): Emit any statics that weren't already.
+
+ * typeck.c (build_static_cast): Implement.
+ * tree.c (build_cplus_new): Handle getting a TARGET_EXPR.
+ * decl.c (grokparms): Use can_convert_arg instead of
+ implicit_conversion directly.
+ (copy_args_p): New fn.
+ * cvt.c (convert_to_reference): Don't complain about temp with
+ static_cast.
+ (build_up_reference): Handle TARGET_EXPRs.
+ * call.c (build_over_call): Elide unnecessary temps.
+ (can_convert*): Use new overloading code.
+
+Tue Aug 27 13:12:21 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c: Move TYPE_PTR*_MACROS ...
+ * cp-tree.h: To here.
+ * typeck.c (build_reinterpret_cast): Implement.
+
+ * call.c (add_builtin_candidate): Use TYPE_PTROB_P instead of
+ ptr_complete_ob.
+ (joust): If we're comparing a function to a builtin and the worst
+ conversion for the builtin is worse than the worst conversion for the
+ function, take the function.
+
+ * typeck.c (build_const_cast): Implement.
+ (comp_ptr_ttypes_const): Like comp_ptr_ttypes, for const_cast.
+ (comp_ptr_ttypes_reinterpret): Like cpt, for reinterpret_cast.
+
+Tue Aug 27 13:14:58 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * rtti.c (build_dynamic_cast): Don't try to dereference exprtype
+ too early. Make sure we explode if exprtype turns out to be a
+ NULL_TREE when it shouldn't be.
+
+Tue Aug 27 10:56:21 1996 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h: New routine make_call_declarator.
+ * lex.c (make_call_declarator): Define it.
+ * except.c (init_exception_processing): Use it.
+ (expand_builtin_throw): Likewise.
+ (start_anon_func): Likewise.
+ * decl2.c (finish_file): Likewise.
+ * lex.c (cons_up_default_function): Likewise.
+ * parse.y: Likewise.
+ * pt.c (tsubst): Likewise.
+
+Mon Aug 26 17:40:03 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (groktypefield): Remove unused code.
+
+Mon Aug 26 17:00:33 1996 Mike Stump <mrs@cygnus.com>
+
+ * gxx.gperf: Change TYPE_QUAL into CV_QUALIFIER.
+ * parse.y: Likewise. Change maybe_type_qual into maybe_cv_qualifier.
+ Change type_quals into cv_qualifiers. Change nonempty_type_quals into
+ nonempty_cv_qualifiers.
+ * hash.h: Rebuild.
+
+ * lex.c (make_pointer_declarator): Change type_quals into
+ cv_qualifiers.
+ (make_reference_declarator): Likewise.
+
+Thu Aug 22 01:09:22 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_function): Only check interface_* for templates
+ with flag_alt_external_templates.
+
+ * call.c (build_new_op): Check for comparison of different enum types.
+ (build_over_call): Fix arg # output.
+
+ * typeck.c (build_component_ref): Handle pre-found TYPE_DECL.
+
+Wed Aug 21 00:13:15 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_new_op): Check for erroneous args.
+
+ * call.c (build_new_method_call): Add missing args to cp_error.
+
+ * tree.c (error_type): Don't print reference-to-array.
+
+ * typeck.c (convert_for_assignment): Don't say contravariance for
+ removing const.
+
+Tue Aug 20 13:23:00 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): Diagnose bad convs for `this'.
+
+ * lex.c (cons_up_default_function): Set DECL_ARTIFICIAL
+ on _ctor_arg.
+
+ * call.c (convert_like): Handle bad convs.
+ (build_over_call): Handle bad convs better.
+
+ * decl2.c: -fansi-overloading is now the default.
+
+ * call.c (build_new_method_call): Check for erroneous args.
+
+ * pt.c (instantiate_class_template): Propagate
+ TYPE_USES_MULTIPLE_INHERITANCE.
+
+Tue Aug 20 13:09:57 1996 Mike Stump <mrs@cygnus.com>
+
+ * call.c (enforce_access): Add static to routine.
+
+Sun Aug 18 14:35:54 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_user_type_conversion_1): Fix bad handling.
+ (compare_ics): Likewise.
+
+Sat Aug 17 21:54:11 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (standard_conversion): Oops.
+
+Sat Aug 17 16:28:11 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * g++.c: Update test for win32 (&& ! cygwin32).
+
+Sat Aug 17 03:45:31 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (comp_ptr_ttypes_real): Handle OFFSET_TYPEs properly.
+ (ptr_reasonably_similar): New fn.
+ * call.c (BAD_RANK): New rank.
+ (ICS_BAD_FLAG): New macro.
+ (standard_conversion): Handle almost-right pointer conversions.
+ (reference_binding): Handle bad rvalue bindings.
+ (add_*_candidate): Stuff.
+ (build_over_call): Pass bad conversions to convert_for_initialization.
+ (compare_ics): Handle bad convs.
+ (joust): Likewise.
+
+Fri Aug 16 15:02:19 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * init.c (expand_vec_init): Use ptrdiff_type_node instead of
+ integer_type_node when computing pointer offsets.
+
+Fri Aug 16 01:28:32 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (lvalue_type): New fn.
+ (error_type): New fn.
+ * call.c (op_error): Use error_type.
+ (add_conv_candidate): Use lvalue_type.
+ (add_builtin_candidates): Likewise.
+ * error.c (args_as_string): Use error_type.
+
+Thu Aug 15 17:27:13 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_decl): Evaluate DECL_INITIAL of a VAR_DECL here.
+ (tsubst): Not here.
+
+ * decl.c (init_decl_processing): With -ansi, __null's type is the
+ signed integral type with the same number of bits as a pointer.
+ Introduce a new variable null_node for it.
+ * cp-tree.h: Adjust.
+ * call.c (null_ptr_cst_p): Adjust.
+
+Thu Aug 15 17:09:54 1996 Mike Stump <mrs@cygnus.com>
+
+ * except.c (do_unwind): Mark %i7 as used on the SPARC so we can
+ optimize.
+
+Thu Aug 15 01:36:49 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (import_export_decl): Ignore #pragma interface for tinfo
+ fns of classes without virtual functions.
+
+ * call.c (add_function_candidate): Handle `this' specially.
+ (compare_ics): Likewise.
+
+Tue Aug 13 12:16:10 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_conditional_expr): Fix handling of __null.
+
+ * decl2.c (comdat_linkage): New fn.
+ (import_export_vtable): Use it.
+ (import_export_decl): Use it.
+ * method.c (make_thunk): Use it.
+
+Mon Aug 12 00:09:18 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (end_template_decl): If we don't actually have parms, return.
+ * parse.y (template_header): Accept 'template <>'.
+
+ * errfn.c: Allow 5 args.
+
+Sun Aug 11 15:20:58 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (make_temp_vec): New fn.
+ * pt.c (push_template_decl): Handle partial specs.
+ (instantiate_class_template): Likewise.
+ (more_specialized): Use get_bindings.
+ (more_specialized_class): New fn.
+ (get_class_bindings): New fn.
+ (most_specialized_class): New fn.
+ (do_function_instantiation): List candidates for ambiguous case.
+ * decl.c (duplicate_decls): Lose reference to DECL_TEMPLATE_MEMBERS.
+ (shadow_tag): Call push_template_decl for partial specializations.
+ * parse.y: Likewise.
+ * cp-tree.h (DECL_TEMPLATE_SPECIALIZATIONS): Replaces
+ DECL_TEMPLATE_MEMBERS.
+ * call.c (print_z_candidates): Reduce duplication.
+
+Fri Aug 9 14:36:08 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (lang_decode_option): Allow -fansi-overloading.
+
+Thu Aug 8 17:04:18 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (get_bindings): New fn.
+ (most_specialized): Likewise.
+ (do_function_instantiation): Use them.
+ (add_maybe_template): New fn.
+ * cp-tree.h (DECL_MAYBE_TEMPLATE): New macro.
+ * call.c (build_new_op): Handle guiding decls.
+ (build_new_function_call): Likewise.
+ * decl2.c (finish_file): Likewise.
+
+ * decl2.c (mark_used): Do synthesis here.
+ * call.c (build_method_call): Not here.
+ (build_over_call): Or here.
+ * typeck.c (build_function_call_real): Or here.
+ * tree.c (bot_manip): Call mark_used on functions used in default
+ args.
+
+Thu Aug 8 17:48:16 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * decl2.c (import_export_vtable): Delete code that disabled vtable
+ heuristic on systems with ASM_OUTPUT_EXTERNAL.
+
+Wed Aug 7 12:44:11 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_x_function_call): Handle static call context
+ better.
+
+ * decl.c (finish_function): Set the DECL_CONTEXT of the result to
+ the function, not its outer block.
+
+ * call.c (build_field_call): Pass fields on to build_opfncall
+ regardless of TYPE_OVERLOADS_CALL_EXPR.
+ (build_method_call): Pass on to build_new_method_call sooner.
+
+ * typeck.c (build_ptrmemfunc): Just return what instantiate_type
+ gives us.
+ * class.c (instantiate_type): Don't put a POINTER_TYPE to
+ METHOD_TYPE on an expression. Also make a copy of rhs instead of
+ modifying it.
+
+Tue Aug 6 12:58:46 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (compare_ics): Handle qual_conv after lvalue_conv.
+ (add_builtin_candidate): Don't take enums for ++.
+ (build_new_method_call): Handle non-aggregates and field calls.
+ Move new overloading code from...
+ * cvt.c: Here.
+
+ * decl.c (grokparms): Don't check default args in templates.
+
+Mon Aug 5 17:17:06 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (build_new_op): Fix args to build_unary_op.
+ (add_builtin_candidates): Don't call type_promotes_to on float.
+
+ * decl.c (grokparms): Check the type of the default arg.
+
+ * cvt.c (build_new_op): Pass non-overloaded cases on rather than
+ returning NULL_TREE.
+
+ * typeck.c (build_x_binary_op): Avoid doing extra work.
+ (build_x_unary_op): Likewise.
+ (build_x_conditional_expr): Likewise.
+ * cvt.c (build_over_call): Return.
+ (add_builtin_candidate): Fix MEMBER_REF.
+ (build_new_op): Likewise.
+
+Mon Aug 5 17:07:47 1996 Mike Stump <mrs@cygnus.com>
+
+ * method.c (build_overload_name): Put bug fix into code but leave
+ disabled for now so we can be bug compatible with older releases
+ that do repeats incorrectly. In the future, we can enable it.
+
+Mon Aug 5 13:46:28 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (convert_like): Don't call build_cplus_new twice.
+
+ * call.c, cp-tree.h, cvt.c, decl2.c, init.c, method.c, pt.c, typeck.c:
+ Control new overloading code with -fansi-overloading.
+
+Sun Aug 4 15:29:11 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (build_over_call): Call build_cplus_new.
+ * call.c (build_method_call): Likewise.
+ * typeck.c (build_function_call_real): Likewise.
+ (build_conditional_expr): If both operands are TARGET_EXPRs, wrap
+ the COND_EXPR in a TARGET_EXPR so they use the same slot.
+
+ * cvt.c (build_up_reference): Propagate INDIRECT_BIND to
+ recursive calls.
+ * typeck.c (complete_type): Propagate
+ TYPE_NEEDS_{CONSTRUCTING,DESTRUCTOR}.
+
+Sat Aug 3 14:05:07 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (joust): More ?: kludging. Sigh.
+ (build_over_call): Don't try to synthesize global fns.
+
+ * search.c (lookup_conversions): Use binfo marking.
+
+Sat Aug 3 12:33:42 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * search.c (build_mi_matrix): Use the correct value of cid
+ when determining the new mi_size.
+
+Sat Aug 3 01:27:41 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (add_builtin_candidates): Do consider type conversion ops
+ for the first parms of += et al.
+ (strip_top_quals): New fn.
+ (reference_binding): Use it instead of TYPE_MAIN_VARIANT.
+ (implicit_conversion): Likewise.
+ (add_builtin_candidates): Be careful about arrays.
+ (build_new_method_call): Handle vtable optimization.
+
+Fri Aug 2 01:26:59 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (LOOKUP_NO_TEMP_BIND): New flag.
+ * cvt.c (reference_binding): Use it.
+ (implicit_conversion): Use it.
+ (add_builtin_candidate, COND_EXPR): Use it.
+
+ * cvt.c (build_new_function_call): Check for error args.
+
+ * typeck.c (comptypes): Just check DERIVED_FROM_P, not UNIQUELY.
+
+ * gxx.gperf: Add __null.
+ * hash.h: Regenerate.
+ * lex.h: Add RID_NULL.
+ * lex.c (init_lex): Create null_pointer_node here, stick it in
+ RID_NULL.
+ * decl.c (init_decl_processing): Still set its type here.
+ * cvt.c (cp_convert_to_pointer): Don't produce null_pointer_node.
+ (convert_to_pointer_force): Likewise.
+ (null_ptr_cst_p): Check for null_pointer_node; only accept (void*)0
+ if (! pedantic).
+ * call.c (convert_harshness): Use null_ptr_cst_p.
+ * typeck.c (convert_for_assignment): Likewise. Don't produce
+ null_pointer_node.
+
+ * error.c (args_as_string): Handle lists of actual args, too.
+ * cvt.c (null_ptr_cst): Support (void*)0 for now.
+ (build_user_type_conversion_1): Improve diagnostics.
+ (build_new_function_call): Likewise.
+ (build_object_call): Likewise.
+ (build_new_method_call): Likewise. Move call before def diagnostic...
+ (build_over_call): Here.
+
+ * cvt.c (build_new_method_call): Don't complain about no match if
+ LOOKUP_SPECULATIVELY.
+ (build_over_call): Fix 'this' for virtual fn.
+ (build_new_method_call): Add diagnostic.
+
+Thu Aug 1 16:45:09 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (add_function_candidate): Expect 'this' and 'in_chrg' for
+ constructors to be passed in.
+ (build_over_call): Likewise.
+ (build_user_type_conversion_1): Pass them in.
+ (convert_like): Likewise.
+ (build_object_call): Handle overloaded conversions.
+ (build_over_call): Pass the right args to build_vfn_ref.
+ (standard_conversion): Fix pmf convs.
+ (joust): Handle comparing statics and non-statics.
+ (build_new_method_call): New fn.
+ * call.c (build_method_call): Call it if NEW_OVER.
+
+Thu Aug 1 16:06:14 1996 Mike Stump <mrs@cygnus.com>
+
+ * lex.c (do_identifier): Don't use %O on IDENTIFIER_OPNAME_Ps, use
+ %D instead.
+
+Thu Aug 1 15:24:02 1996 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Use maybe_build_cleanup_and_delete
+ instead of just maybe_build_cleanup so that we deallocate the
+ thrown object.
+
+Thu Aug 1 15:18:00 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl2.c (finish_prevtable_vardecl): Make non-static for pt.c's use.
+ * cp-tree.h (finish_prevtable_vardecl): Add decl.
+
+Thu Aug 1 11:53:51 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * pt.c (instantiate_class_template): Call complete_type. Also, if
+ we're at the end of the file and we just instantiated a template
+ class with a vtable, call finish_prevtable_vardecl.
+
+ * error.c (dump_decl): Don't explode (or explode more gracefully
+ as appropriate) if the object being dumped has a null type.
+ (dump_expr): Likewise.
+
+ * search.c (build_mi_matrix): Ensure that mi_size is large enough,
+ by counting the number of nodes that we'll need before allocating
+ the array.
+ (lookup_fnfields): Fix comment.
+ (breadth_first_search): Fix comment.
+
+Wed Jul 31 09:57:05 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Propagate TYPE_PACKED and
+ TYPE_ALIGN.
+ * class.c (finish_struct): Call cplus_decl_attributes here.
+ (finish_struct_1): Not here.
+ * cp-tree.h: Adjust.
+
+ * pt.c (type_unification): New parameter STRICT.
+ (unify): If STRICT, don't allow cv addition or base deduction.
+ * call.c, class.c, cvt.c, cp-tree.h: Adjust.
+
+Tue Jul 30 13:06:13 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (get_template_base{_recursive}): New fns.
+ * pt.c (more_specialized): New fn.
+ (do_function_instantiation): Use it.
+ (unify): Handle base deduction.
+ * cvt.c (joust): Use more_specialized.
+ Don't arbitrarily choose between non-builtin candidates.
+ (build_over_call): Call require_complete_type.
+
+ * decl.c (start_function): Statics are static even in a #pragma
+ interface file.
+
+ * decl2.c (import_export_vtable): Disable vtable heuristic on
+ systems with ASM_OUTPUT_EXTERNAL.
+
+ * cvt.c (compare_ics): Fix comparison of PMEM_CONV and BASE_CONV.
+ (standard_conversion): No std conv to enum type.
+
+ * cvt.c (standard_conversion): Fix order of args to DERIVED_FROM_P
+ for ptm's.
+
+ * cvt.c (reference_binding): Bind directly to a base subobject of
+ a class rvalue.
+
+ * cvt.c (build_new_op): Enforce access control.
+
+Tue Jul 30 09:22:53 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * typeck2.c (process_init_constructor): When scanning the
+ union for a named field, skip things that aren't FIELD_DECLs.
+
+ * method.c (synthesize_method): Don't scan fndecl's rtl if
+ we're at the end of the file; just assume the function can't
+ be inlined.
+
+Mon Jul 29 15:48:30 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (build_builtin_candidate): Stick a dummy conversion in if
+ it failed.
+
+ * cvt.c (build_user_type_conversion_1): Handle overloaded
+ conversion ops.
+
+ * cvt.c (add_builtin_candidates): Don't consider type conversion
+ operators for the first parameter of operator=.
+
+Mon Jul 29 15:33:55 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * typeck.c (complete_type): Only call layout_type if we're not
+ expanding a template.
+
+Mon Jul 29 14:40:38 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (compare_ics): Oops.
+
+ * cvt.c (op_error): Oops.
+
+ * cp-tree.def: Add RVALUE_CONV, rename EXACT_CONV to IDENTITY_CONV.
+ * cvt.c: Add IDENTITY_RANK before others. Use real_lvalue_p.
+ (build_conv): Use them.
+ (implicit_conversion): Use them.
+ (convert_like): Handle them.
+ (build_new_op): Handle builtin COND_EXPR again.
+ (add_builtin_candidates): Strip cv-quals. Fix oops. Include enums
+ in lists of types for COND_EXPR.
+ (add_builtin_candidate): Add enum candidates for COND_EXPR.
+
+Mon Jul 29 12:05:40 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * typeck.c (build_modify_expr): Always attempt to build a call to
+ the assignment operator, even if we're using a default one.
+ (convert_for_initialization): Call complete_type.
+
+Mon Jul 29 11:25:08 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (reference_binding): A REF_BIND gets the reference type.
+ (implicit_conversion): Likewise.
+ (convert_like): Likewise.
+ (compare_ics): Likewise.
+ (compare_qual): Likewise.
+ (print_z_candidates): Handle no candidates.
+ (build_new_op): Don't handle builtin COND_EXPR for now.
+
+Sat Jul 27 11:27:47 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * cvt.c (build_builtin_candidate): Init local var in an ANSI way.
+
+Fri Jul 26 01:07:22 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (joust): If the candidates are the same, arbitrarily pick one.
+
+ * cvt.c (build_builtin_candidate): Oops.
+ (build_new_op): Oops.
+
+ * method.c (build_opfncall): Pass COND_EXPR on.
+ * cvt.c (build_builtin_candidate): Reorganize, support COND_EXPR.
+ (add_builtin_candidate{,s}): Likewise.
+ (add_builtin_candidates): Likewise.
+ (print_z_candidates, op_error, build_new_op): Likewise.
+ (type_decays_to): New fn.
+ * lex.c (init_lex): Just say ?: for COND_EXPR.
+
+Thu Jul 25 09:33:33 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (complete_type): Call layout_type rather than building
+ a new array type.
+
+ * cvt.c (add_builtin_candidate): Pointer arithmetic candidates
+ only use ptrdiff_t.
+
+Wed Jul 24 12:45:08 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c: Always compile the new overloading code (but don't use it).
+ (implicit_conversion): Add a BASE_CONV when converting to
+ the same class type.
+ (convert_like): Handle BASE_CONV.
+
+Tue Jul 23 12:46:30 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (build_new_op): Support {MAX,MIN}_EXPR.
+ (add_builtin_candidate): Likewise.
+
+ NEW_OVER changes:
+ * typeck.c (build_x_function_call): Try an operator function
+ whenever we call an object of class type.
+ * method.c (build_opfncall): Pass CALL_EXPRs through.
+ * cvt.c (implicit_conversion): Do const-ref case first.
+ (add_conv_candidate, build_object_call, op_error): New fns.
+ (ptr_complete_ob, TYPE_PTROB_P): void is not an object type.
+ ({add,build}_builtin_candidate{,s}, print_z_candidates): Display
+ builtin candidates.
+ (build_new_op): Handle CALL_EXPR. Don't try to decay void.
+ Fall back on preincrement handling. Use op_error.
+ Handle warn_synth.
+ (convert_like): Pass INDIRECT_BIND. Don't try to do anything with
+ an error_mark_node.
+ (build_over_call): Handle PROMOTE_PROTOTYPES and ellipsis promotions
+ properly.
+
+Mon Jul 22 16:21:55 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * pt.c (tsubst_expr): Handle CONTINUE_STMT.
+
+Mon Jul 22 15:38:58 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_component_ref_1): Use build_component_ref
+ instead of open coding it here.
+
+Mon Jul 22 12:18:54 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * g++.c (main): Don't link with -lg++.
+
+ NEW_OVER changes:
+ * cvt.c (convert_to_reference): Don't use convert_from_reference on
+ result of build_type_conversion.
+ (cp_convert): Only call build_method_call for ctors if
+ build_type_conversion failed.
+ (ptr_complete_ob): New function.
+ (TYPE_PTR{,OB,MEM}_P): New macros.
+ ({add,build}_builtin_candidate{,s}): New functions.
+ (print_z_candidates): Handle builtins.
+ (build_user_type_conversion_1): Don't use conversion fns for
+ converting to a base type.
+ (build_user_type_conversion_1): Set ICS_USER_FLAG on AMBIG_CONVs.
+ (build_user_type_conversion): Use convert_from_reference.
+ (build_new_op): New function.
+ (build_over_call): Fix handling of methods.
+ (compare_ics): Handle AMBIG_CONV properly.
+ * typeck2.c: Increment abort count.
+ * method.c (build_opfncall): Forward most requests to build_new_op.
+ * cp-tree.h (IS_OVERLOAD_TYPE): Tweak.
+
+Fri Jul 19 17:59:29 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * error.c (dump_expr, case CONSTRUCTOR, case CAST_EXPR): Take out
+ invalid second argument to dump_expr_list.
+
+Fri Jul 19 14:04:05 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (lookup_name_real): Make sure we do obj->X::i correctly.
+
+Thu Jul 18 14:48:23 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * decl2.c (import_export_vtable): ASM_OUTPUT_EXTERNAL, not
+ ASSEMBLE_EXTERNAL.
+
+Mon Jul 15 17:48:43 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck2.c (process_init_constructor): New pedwarn for using { }
+ to initialize a pointer to member function.
+ * typeck.c (build_ptrmemfunc1): Avoid use of digest_init so that
+ we can avoid the new error.
+
+Mon Jul 15 15:42:03 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_ptrmemfunc1): New function to hide details of
+ pointer to member functions better.
+
+Mon Jul 15 14:23:02 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (resolve_offset_ref): Resolve OFFSET_REFs that are
+ methods into the actual method, as we know the implied object is
+ not used.
+
+Mon Jul 15 13:08:29 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (maybecomma_warn): Only emit the pedwarn if we're not
+ inside a system header.
+
+Fri Jul 12 16:30:05 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * call.c (build_method_call): Call complete_type on the
+ instance type.
+
+Thu Jul 11 17:16:40 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_component_ref): Always build up an OFFSET_REF
+ for obj_ptr->func so that we can know which object to use in a
+ method call.
+
+Wed Jul 10 19:36:37 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_ptrmemfunc): Remove sorry, now we can cast
+ around things. Also improve maintainability.
+
+Wed Jul 10 18:20:11 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * decl.c (grokdeclarator): Check for overflow when evaluating an
+ array dimension.
+
+Wed Jul 10 17:26:19 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (cp_convert): Don't check for ambiguity with constructor
+ if NEW_OVER.
+
+ * typeck.c (build_x_function_call): Pass function overload
+ questions to new overloading code if NEW_OVER.
+ * init.c (expand_aggr_init_1): Only check for type conversion ops
+ if we're doing copy-initialization (i.e. LOOKUP_ONLYCONVERTING).
+ Don't check for ambiguity with constructor if NEW_OVER.
+ * cvt.c (convert_to_reference): Dereference the result of a type
+ conversion operator.
+ (build_conv): Propagate ICS_USER_FLAG.
+ (implicit_conversion): Call instantiate_type.
+ Pass LOOKUP_ONLYCONVERTING instead of LOOKUP_NORMAL.
+ (add_function_candidate): Fix cv-quals on argtype.
+ (print_z_candidates): New function.
+ (build_new_function_call): Call it.
+ (build_user_type_conversion_1): If LOOKUP_ONLYCONVERTING, don't
+ consider non-converting constructors.
+ Call print_z_candidates.
+ Return an AMBIG_CONV for an ambiguous conversion.
+ (build_user_type_conversion): Handle AMBIG_CONV.
+ (convert_like): Fix test for building TARGET_EXPR.
+ Call instantiate_type.
+ Handle AMBIG_CONV and LVALUE_CONV.
+ (build_over_call): Handle 0 args and ellipsis.
+ * cp-tree.def: Add AMBIG_CONV.
+
+Tue Jul 9 17:48:48 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (lookup_name_real): If we find mem in obj when parsing
+ `obj->mem', make sure we return the right value.
+
+Tue Jul 9 16:11:28 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * search.c (get_base_distance): Call complete_type.
+
+Tue Jul 9 12:46:34 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (store_bindings): Make static.
+
+Mon Jul 8 16:42:31 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (expand_aggr_init_1): Don't check type conversions if
+ NEW_OVER.
+
+ * cvt.c (z_candidate): Put back template field.
+ (add_function_candidate): Set it.
+ (add_template_candidate): Likewise.
+ (joust): Use it.
+ (compare_qual): Handle references and pointers to members.
+ (compare_ics): Handle reference bindings.
+
+ * decl.c (duplicate_decls): Propagate DECL_ONE_ONLY.
+
+Mon Jul 8 16:18:56 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * call.c (compute_conversion_costs): Call complete_type.
+
+ * tree.c (vec_binfo_member): Use comptypes instead of comparing
+ pointers, so we can handle template parameters.
+
+Fri Jul 5 16:51:53 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): We have to call complete_type
+ here; let's make it explicit instead of a side effect of an
+ error check.
+
+Wed Jul 3 16:29:51 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (z_candidate): Remove template field.
+ (reference_binding): Handle binding to temporary.
+ (implicit_conversion): Likewise.
+ (add_function_candidate): Handle artificial constructor parms.
+ Handle functions with too few parms.
+ (add_template_candidate): New function.
+ (build_user_type_conversion_1): Handle constructors.
+ (convert_like): Likewise.
+ (build_over_call): Likewise.
+ (build_new_function_call): Support templates.
+ (compare_ics): Fix reference, inheritance handling.
+
+Mon Jul 1 22:58:18 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * decl.c: Add signed_size_zero_node.
+ (init_decl_processing): Build it.
+ * class.c (prepare_fresh_vtable): Use it instead of size_zero_node
+ when we're trying to make a negative delta.
+
+Mon Jul 1 17:56:19 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ Stop doing this damn index==strchr variable name confusion.
+ * class.c (add_virtual_function): Change local var INDEX to be
+ named IDX.
+ (add_method): Likewise.
+ * lex.c (print_parse_statistics): Likewise.
+ * search.c (make_memoized_table_entry): Likewise.
+ (lookup_fnfields_here): Likewise.
+ (lookup_field): Likewise.
+ (lookup_fnfields): Likewise.
+ (get_baselinks): Likewise.
+ * sig.c (build_signature_table_constructor): Likewise.
+ (build_signature_method_call): Likewise.
+ * typeck.c (build_x_array_ref): Change INDEX parm to be named IDX.
+ (get_member_function_from_ptrfunc): Likewise.
+ (build_ptrmemfunc): Change local var INDEX to be IDX.
+ (c_expand_start_case): Likewise.
+
+Sat Jun 29 14:05:46 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Move user-defined type conversion
+ handling to before extraction of TYPE_PTRMEMFUNC_FN_TYPE.
+ (convert_to_reference): Use build_type_conversion to convert to
+ the reference type directly.
+ (standard_conversion): Fix void* case, non-conversions.
+ (reference_binding): Fix expr == 0 case, non-conversions.
+ (convert_like): Support REF_BIND.
+ (compare_qual): Split out from compare_ics.
+ (compare_ics): Use it, handle icses with only a qual_conv.
+
+ * init.c (expand_vec_init): Don't crash if decl is NULL.
+
+Fri Jun 28 11:52:51 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: New file, configury for Mac MPW.
+ * mpw-make.sed: New file, makefile editing for MPW.
+
+Thu Jun 27 15:18:30 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Call repo_template_used.
+
+ * search.c (lookup_conversions): Only lookup conversions in
+ complete types.
+
+Thu Jun 27 12:59:53 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.def: Renamed from tree.def, to avoid confusion with
+ gcc's tree.def.
+ * cp-tree.h, lex.c: Include cp-tree.def.
+ * Makefile.in (CXX_TREE_H): Reference cp-tree.def.
+
+Wed Jun 26 18:29:47 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * init.c (build_vec_delete_1): Call complete_type.
+
+Mon Jun 24 17:17:32 1996 Mike Stump <mrs@cygnus.com>
+
+ * except.c (start_anon_func): Make sure anonymous functions are
+ never external.
+
+Fri Jun 21 15:10:58 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (finish_function): If function_depth > 1, set nested.
+
+ * decl2.c (grokbitfield): Revert Bob's change.
+ * class.c (finish_struct_1): Fix handling of named bitfield widths.
+
+Thu Jun 20 23:35:38 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (add_pending_template): Handle types.
+ (lookup_template_class): With -fexternal-templates, just add the class
+ to pending_templates instead of instantiating it now.
+ * decl2.c (finish_file): Handle types in pending_templates.
+
+Thu Jun 20 14:08:40 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * decl2.c (grokbitfield): Handle constant decls appropriately.
+ Give an appropriate error message now instead of spewing core
+ later.
+
+Thu Jun 20 13:01:51 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c: Don't turn on thunks by default for now.
+
+Wed Jun 19 11:37:04 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (complete_type): Handle error_mark_node.
+ (common_type, OFFSET_TYPE): Handle template_type_parms.
+
+Tue Jun 18 10:02:15 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_decl): If at_eof, call import_export_decl
+ regardless of DECL_INLINE.
+
+ * typeck.c (mark_addressable): Set TREE_ADDRESSABLE on CONSTRUCTORs.
+
+ * class.c (finish_struct_bits): Copy TYPE_SIZE.
+
+ * rtti.c (build_dynamic_cast): Support templates.
+ * tree.def: Support DYNAMIC_CAST_EXPR.
+ * pt.c (tsubst_copy): Likewise.
+ * decl2.c (build_expr_from_tree): Likewise.
+
+Mon Jun 17 15:23:36 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_static_cast): Support templates.
+ (build_const_cast): Likewise.
+ * tree.def: Support CONST/STATIC_CAST_EXPR.
+ * pt.c (tsubst_copy): Likewise.
+ * decl2.c (build_expr_from_tree): Likewise.
+
+Sun Jun 16 12:33:57 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Don't trust
+ TREE_SYMBOL_REFERENCED for vtables of local classes.
+
+Fri Jun 14 18:13:36 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst_copy): Handle operator T.
+
+Wed Jun 12 17:52:40 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_delete): Move creation of PARMS inside test of
+ TYPE_HAS_DESTRUCTOR, since it's never used outside of that block.
+
+Tue Jun 11 15:09:18 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * typeck.c (build_conditional_expr): Don't assume that
+ the arguments to ?: are always pointers or records.
+
+Tue Jun 11 13:56:23 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (import_export_decl): Still emit static/weak/comdat
+ copies of inline template functions with -fno-implicit-templates.
+
+Tue Jun 11 11:42:13 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * init.c (build_delete): Determine the complete basetype
+ path to the destructor we're calling.
+
+Fri Jun 7 15:30:10 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * decl.c (build_enumerator): Always copy the INTEGER_CST used to
+ initialize the enum, because we really and truly don't know where
+ it came from.
+ (start_enum): Don't copy integer_zero_node because
+ build_enumerator will do it.
+
+Fri Jun 7 11:11:09 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (finish_function): Do access control on base destructors.
+
+ * pt.c (tsubst, case FUNCTION_DECL): Set up
+ IDENTIFIER_GLOBAL_VALUE for member functions so pushdecl doesn't
+ hose us.
+
+Fri Jun 7 10:37:33 1996 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (build_up_reference): If we have already extended the
+ lifetime of the temporary, don't try it again.
+ * typeck.c (c_expand_return): Don't try and convert the return
+ value twice when we want a reference, once is enough.
+
+Tue Jun 4 15:41:45 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst_expr, case DECL_STMT): Don't pass
+ LOOKUP_ONLYCONVERTING at all for now.
+
+ * search.c (add_conversions): Put the conversion function in
+ TREE_VALUE, the basetype in TREE_PURPOSE.
+ * cvt.c (build_type_conversion): Adjust.
+ * cvt.c (build_expr_type_conversion): Adjust.
+ * call.c (user_harshness): Adjust.
+
+Mon Jun 3 15:30:52 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (emit_thunk): Pretend this is a FUNCTION_DECL for the
+ backend's benefit.
+
+Mon Jun 10 18:58:19 1996 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_start_catch_block): Add a dummy region, if we
+ get an error, so that we can avoid core dumping later.
+
+Fri May 31 14:56:13 1996 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (OFFSET_REF): Remove.
+ * tree.def (CP_OFFSET_REF): Rename to OFFSET_REF.
+ * expr.c (cplus_expand_expr): Cleanup callers of expand_expr.
+ * init.c (expand_aggr_init_1): Likewise.
+ (build_new): Likewise.
+ * typeck.c (expand_target_expr): Likewise.
+
+Fri May 31 14:22:08 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_modify_expr): Don't use TREE_VALUE on a
+ TARGET_EXPR.
+
+Wed May 29 17:04:33 1996 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (build_up_reference): Redo how and when temporaries are
+ created.
+ * decl.c (grok_reference_init): Don't try and be smart about
+ running cleanups.
+
+Wed May 29 16:02:08 1996 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (build_up_reference): Add NULL_TREE to all calls to build
+ (TARGET_EXPR...), now that it has 4 arguments.
+ * tree.c (build_cplus_new): Likewise.
+
+Thu May 23 16:40:30 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * error.c (dump_expr, case CAST_EXPR): Handle T() properly.
+
+ * pt.c (instantiate_decl): Don't call push/pop_cp_function_context.
+ * decl.c (struct saved_scope): Remove named_labels,
+ {base,member}_init_list.
+ (maybe_push_to_top_level): Don't set them. Call
+ push_cp_function_context if appropriate.
+ (pop_from_top_level): Likewise.
+
+ * method.c (do_build_assign_ref): Remove obsolete check of
+ TYPE_HAS_ASSIGN_REF (basetype).
+
+ * decl.c (grokfndecl): Diagnose user definition of
+ implicitly-declared methods.
+
+Thu May 23 12:13:08 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * method.c (do_build_copy_constructor): Add code to give
+ meaningful error messages instead of crashing.
+ (do_build_assign_ref): Don't synthesize assignment operators for
+ classes containing reference or const members.
+
+ * class.c (struct base_info): Remove cant_synth_copy_ctor
+ and cant_synth_asn_ref.
+ (finish_base_struct): Remove the code that tries to conditionalize
+ synthesis of copy constructors & assignment operators based on
+ access permissions. Instead, let it fail when it tries to
+ synthesize the copy constructor. This will give meaningful error
+ messages instead of silently generating code to perform a bitcopy.
+
+Wed May 22 11:45:19 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * lex.c (real_yylex): Remove old-n-crufty #if 0 code for
+ determining types for constant values.
+
+ * decl.c (struct named_label_list): Use instead of stuffing
+ random items into a TREE_LIST node.
+ (named_label_uses): Use the new struct.
+ (poplevel): Likewise.
+ (lookup_label): Likewise.
+ (define_label): Add an error message to tell the user the line
+ where the goto is located in addition to the destination of the
+ goto.
+ (init_decl_processing): Use NULL instead of NULL_TREE to initialize
+ named_label_uses.
+ (finish_function): Likewise.
+
+ (start_decl): Complain about defining a static data member
+ in a different type from which it was declared.
+
+Wed May 22 09:33:23 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (build_expr_type_conversion): Adjust.
+
+Tue May 21 11:21:56 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_method_call): Always convert 'this' to the
+ appropriate type.
+
+ * search.c (add_conversions): Put the conversion function in
+ TREE_VALUE, the type in TREE_PURPOSE.
+ * cvt.c (build_type_conversion): Adjust.
+ * call.c (user_harshness): Adjust.
+
+ * method.c (emit_thunk): Call temporary_allocation and
+ permanent_allocation around the ASM_OUTPUT_MI_THUNK case, too.
+
+ * tree.c (build_cplus_array_type): Handle tweaking of
+ TYPE_MAIN_VARIANT here.
+ * typeck.c (common_type): Not here.
+
+ * typeck.c (complete_type): Only try to complete an array type if
+ it has a domain.
+
+Mon May 20 14:55:59 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokvardecl): Call complete_type.
+ (grokdeclarator): Call complete_type for PARM_DECLs.
+
+Fri May 17 16:41:17 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Re-set
+ CLASSTYPE_GOT_SEMICOLON after calling finish_struct_1.
+
+Fri May 17 14:56:55 1996 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (cp_expand_decl_cleanup): Remove, the backend is now
+ smart enough to do it right.
+ * tree.c (cp_expand_decl_cleanup): Likewise.
+ * decl.c (cp_finish_decl): Use expand_decl_cleanup instead of
+ cp_expand_decl_cleanup.
+ (store_parm_decls): Likewise.
+ (hack_incomplete_structures): Likewise.
+ * except.c (push_eh_cleanup): Likewise.
+
+Fri May 17 13:13:51 1996 Mike Stump <mrs@cygnus.com>
+
+ * expr.c (expand_expr, cond UNSAVE_EXPR): Move from the C++
+ frontend to the backend where it belongs.
+ * tree.c (unsave_expr): Likewise.
+ (unsave_expr_now): Likewise.
+ * tree.def (UNSAVE_EXPR): Likewise.
+ * cp-tree.h (unsave_expr): Likewise.
+ (unsave_expr_now): Likewise.
+
+Fri May 17 11:02:41 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (emit_base_init): Make sure the partial EH cleanups live
+ on the function_obstack.
+
+Thu May 16 15:29:33 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * expr.c (do_case): Don't try to dereference null TREE_TYPEs
+ when checking for pointer types.
+
+Thu May 16 13:38:58 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Remove obsolete check for
+ access declarations.
+
+Thu May 16 13:34:15 1996 Mike Stump <mrs@cygnus.com>
+
+ * call.c (build_overload_call): Simplify calls to
+ build_overload_call by removing last parameter.
+ (build_method_call): Likewise.
+ * cp-tree.h: Likewise.
+ * method.c (build_opfncall): Likewise.
+ * typeck.c (build_x_function_call): Likewise.
+
+Thu May 16 13:15:43 1996 Mike Stump <mrs@cygnus.com>
+
+ * call.c (default_parm_conversions): Factor out common code.
+ (build_method_call): Use it.
+ (build_overload_call_real): Use it.
+
+Wed May 15 14:46:14 1996 Mike Stump <mrs@cygnus.com>
+
+ * call.c (build_method_call): Allow implicit & on METHOD_TYPEs,
+ but pedwarn as the code is bogus.
+ * typeck.c (decay_conversion): Likewise.
+ (build_function_call_real): Use build_addr_func instead of
+ default_conversion. Don't allow pointer-to-method functions down
+ here.
+ (build_unary_op): Use real pointer-to-member functions instead of
+ fake ones.
+ (build_ptrmemfunc): Use build_addr_func instead of build_unary_op.
+ (convert_for_assignment): Removed some obsolete code.
+ * decl2.c (reparse_absdcl_as_expr): Pass current_class_ref to
+ build_x_function_call instead of current_class_ptr. Only call
+ digest_init once on an initializer, we do this just checking
+ TREE_TYPE.
+ (build_expr_from_tree): Pass current_class_ref to
+ build_x_function_call instead of current_class_ptr.
+ * init.c (build_member_call): Likewise.
+ * pase.y: Likewise.
+ * error.c (dump_expr): Handle OFFSET_REFs better.
+ * pt.c (unify): Handle pointer-to-member functions better.
+ * decl.c (finish_function): Clear out current_class_ref just like
+ we do for current_class_ptr.
+
+ * typeck.c (get_delta_difference): Handle virtual bases better.
+
+Tue May 14 16:37:37 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * sig.c (build_signature_table_constructor): Use the delta for
+ the original basetype for this virtual function with thunks.
+ (build_signature_method_call): We still need to adjust 'this'
+ with thunks.
+
+Tue May 14 16:27:25 1996 Mike Stump <mrs@cygnus.com>
+
+ * call.c (build_addr_func): New routine. Used to get the `real'
+ address of a function or a method. Needed to avoid getting a
+ pointer-to-member function.
+ (build_call): New routine to build CALL_EXPRs.
+ (build_method_call): Use it.
+ * cvt.c (convert_to_aggr): Likewise.
+ * typeck.c (build_function_call_real): Likewise.
+ * sig.c (build_signature_table_constructor): Use build_addr_func.
+ * cp-tree.h (build_call, build_addr_func): Declare them.
+
+Tue May 14 12:47:47 1996 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (LOOKUP_AGGR): Remove, unused.
+ * parse.y: Remove uses of LOOKUP_AGGR.
+
+Tue May 14 12:07:51 1996 Mike Stump <mrs@cygnus.com>
+
+ * *.[chy]: Rename current_class_decl to current_class_ptr, and
+ C_C_D to current_class_ref.
+
+Mon May 13 16:55:23 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (convert_harshness): Tighten up pointer conversions.
+
+Sat May 11 04:33:50 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Surround DECL_ONE_ONLY with ifdef.
+ (finish_file): Likewise.
+
+Fri May 10 11:09:57 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (convert_fn_ptr): We don't use thunks for pmfs.
+
+ * method.c (emit_thunk): Set flag_omit_frame_pointer in default
+ code.
+
+Thu May 9 18:18:30 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c: Turn on thunks by default where supported.
+
+Tue May 7 20:39:57 1996 Mike Stump <mrs@cygnus.com>
+
+ * cp-tree.h (build_overload_call_maybe): Removed.
+ * call.c (build_overload_call_real): Invert meaning of last arg to
+ be require_complete.
+ (build_overload_call): Likewise.
+ * typeck.c (build_x_function_call): Use build_overload_call_real
+ instead of build_overload_call_maybe.
+
+Mon May 6 01:23:32 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Don't try to emit functions that haven't
+ been compiled.
+
+Fri May 3 09:30:13 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Oops.
+
+ * decl.c (maybe_push_to_top_level): Do save previous_class_*.
+ Also store the bindings from previous_class_values.
+ (pop_from_top_level): Restore them.
+
+Thu May 2 21:56:49 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Only write out vtable if its
+ symbol has been referenced.
+ (finish_file): Re-join synthesis/vtable loop with inline emission
+ loop, disable inlining when an inline is output.
+
+Thu May 2 17:20:02 1996 Mike Stump <mrs@cygnus.com>
+
+ * except.c (init_exception_processing): Setup saved_in_catch.
+ (push_eh_cleanup): Reset __eh_in_catch.
+ (expand_start_catch_block): Set __eh_in_catch.
+
+Thu May 2 16:21:17 1996 Mike Stump <mrs@cygnus.com>
+
+ * except.c (push_eh_cleanup): Add tracking for whether or not we
+ have an active exception object.
+ (expand_builtin_throw): Use it to make sure a rethrow without an
+ exception object is caught.
+
+Thu May 2 11:26:41 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (maybe_push_to_top_level): Clear out class-level bindings
+ cache.
+
+Wed May 1 11:26:52 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Also use sentries for vars with
+ DECL_ONE_ONLY or DECL_WEAK set (should any such happen to be
+ created).
+
+ * lex.c (handle_cp_pragma): Disable #pragma
+ interface/implementation if SUPPORTS_ONE_ONLY > 1.
+
+Tue Apr 30 11:25:46 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (emit_thunk): Wrap default case in
+ temporary/permanent_allocation.
+
+ * method.c (make_thunk): Use DECL_ONE_ONLY.
+ (emit_thunk): Call assemble_end_function.
+
+Mon Apr 29 15:38:29 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (import_export_vtable): Use DECL_ONE_ONLY.
+ (import_export_decl): Likewise.
+ (finish_prevtable_vardecl): Disable vtable hack if
+ SUPPORTS_ONE_ONLY > 1.
+
+Mon Apr 29 14:32:47 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_modify_expr): PREINCREMENT_EXPR and
+ PREDECREMENT_EXPRs take two arguments, not one.
+
+Mon Apr 29 00:27:53 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (build_vtable_entry): Don't build thunks for abstract
+ virtuals.
+
+ * lex.c (real_yylex): Fix handling of __PRETTY_FUNCTION__ like C
+ frontend.
+
+Sat Apr 27 16:45:35 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (set_rtti_entry): Use size_zero_node.
+ (build_vtable): Likewise.
+
+Sat Apr 27 14:48:57 1996 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * class.c (finish_struct_1): Pass size_zero_node to set_rtti_entry.
+ (prepare_fresh_vtable): Likewise.
+
+Fri Apr 26 13:14:14 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (emit_thunk): Call mark_used on the target function.
+
+ * call.c (build_method_call): Don't warn about pending templates.
+
+Thu Apr 25 14:55:44 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Fix list walking logic.
+
+ * typeck2.c (check_for_new_type): Only warn if -pedantic.
+
+Wed Apr 24 15:41:15 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * class.c (finish_struct_1): Remove old code for
+ dont_allow_type_definitions.
+ * cp-tree.h: Likewise.
+ * spew.c: Make sure cp-tree.h is included before parse.h, so the
+ definition of flagged_type_tree is found before it is used.
+ * lex.c: Likewise.
+ * parse.y: Added the ftype member to the type union, and changed a
+ number of rules to use it instead of ttype. Added calls to
+ check_for_new_type() as appropriate.
+ * typeck2.c (check_for_new_type): New function for checking
+ if a newly defined type appears in the specified tree.
+ * cp-tree.h: Add new type flagged_type_tree. Add a prototype
+ for check_for_new_type().
+
+Wed Apr 24 00:36:21 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Only use a sentry if the decl is public.
+
+ * pt.c (tsubst_expr, DECL_STMT): If we don't have an initializer,
+ don't pass LOOKUP_ONLYCONVERTING.
+
+Tue Apr 23 17:18:47 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * typeck.c (common_type): Fix the ARRAY_TYPE case so it
+ properly keeps track of const and volatile type modifiers.
+
+Tue Apr 23 10:52:56 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (cp_tree_equal): C++ version of simple_cst_equal.
+ * pt.c (comp_template_args): Use it.
+
+ * rtti.c (get_tinfo_fn, build_dynamic_cast, expand_*_desc): Call
+ assemble_external for artificial function decls.
+
+ * decl.c (cp_finish_decl): Oops.
+
+Mon Apr 22 17:28:27 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (import_export_decl): Put static data member templates
+ into common storage, or make them weak, depending on whether they
+ are dynamically or statically initialized.
+ (get_sentry): New function.
+ (finish_file): Do import_export_decl for static data members before
+ building the init/fini functions. Don't init/fini a variable that's
+ EXTERNAL. Use a sentry for variables in common. Fix mismatching
+ push/pop_temp_slots.
+ * decl.c (cp_finish_decl): If DECL_NOT_REALLY_EXTERN, do the
+ expand_static_init thang.
+ * method.c (get_id_2): New function.
+
+Mon Apr 22 15:32:45 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * parse.y (empty_parms): Make sure we use C++-style prototypes
+ when we're declaring member functions.
+
+Sun Apr 21 10:08:22 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (CONFLICTS): 16 s/r conflicts.
+ * parse.y (self_template_type): New nonterminal.
+
+Thu Apr 18 08:56:54 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (make_typename_type): Handle getting a TYPE_DECL for a
+ name.
+ * parse.y (base_class.1): Allow 'typename foo::bar'.
+
+ * lex.c (check_newline): Remove #pragma code that plays with the
+ input stream, since we now deal with tokens. Clear nextchar when
+ we're done.
+ (handle_cp_pragma): Use real_yylex.
+ (handle_sysv_pragma): Don't do skipline here. Only call real_yylex
+ in one place.
+
+ * lex.c (check_for_missing_semicolon): Handle SELFNAME.
+
+ * lex.c (handle_cp_pragma): Fix "#pragma implementation".
+
+Wed Apr 17 16:51:33 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y: New token SELFNAME for potential constructor.
+ * spew.c (yylex): Handle it.
+ * lex.c (identifier_type): Produce it.
+
+ * parse.y (complete_type_name): In :: case, don't push class binding.
+ (complex_type_name): Likewise.
+
+Wed Apr 17 15:02:40 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_reinterpret_cast): Handle pointer to member
+ functions.
+
+Wed Apr 17 12:28:26 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lex.c (handle_cp_pragma): New function, with decl, doing the cc1plus
+ pragmas.
+ (check_newline): Put the vtable/unit/implementation/interface pragma
+ code into handle_cp_pragma, replacing it with a call.
+ (handle_sysv_pragma): Give int return type, and take FINPUT and TOKEN
+ args. Get the next token after handling the pragma token.
+
+Wed Apr 17 10:28:34 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Avoid doing base analysis on pmfs.
+ (convert_to_pointer_force): Likewise.
+
+ * init.c (build_new): Fix array new without -fcheck-new.
+
+Tue Apr 16 13:44:58 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h, call.c, class.c, decl.c, parse.y, pt.c, rtti.c,
+ tree.c: Lose TYPE_NESTED_NAME.
+
+ * parse.y (nested_name_specifier_1): Don't treat non-identifiers
+ as identifiers.
+
+ * tree.def: Add VEC_INIT_EXPR.
+ * expr.c (cplus_expand_expr): Handle it.
+ * init.c (build_new): Use it instead of the RTL_EXPR nastiness and
+ the extra file-scope symbol nastiness.
+
+Mon Apr 15 16:21:29 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (make_thunk): Thunks are static.
+ (emit_thunk): Use ASM_OUTPUT_MI_THUNK if it's defined.
+
+ * decl2.c (mark_vtable_entries): Emit thunks as needed.
+ (finish_file): Don't emit them here.
+
+Sun Apr 14 11:34:39 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (build_dynamic_cast): Handle null pointers.
+ (ifnonnull): New function.
+
+Fri Apr 12 09:08:27 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * call.c (build_method_call): Remember the original basetype we
+ were called with. Give an error message instead of trying
+ (incorrectly) to call a non-static member function through a
+ non-inherited class.
+
+ * search.c (expand_upcast_fixups): Mark the new fixup as
+ DECL_ARTIFICIAL.
+
+Thu Apr 11 03:57:09 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_new): Use a TARGET_EXPR for alloc_expr.
+
+ * class.c (set_rtti_entry): Fix for thunks.
+
+ * decl2.c (import_export_decl): Still emit typeinfo fns for
+ cv-variants of builtin types.
+
+ * rtti.c (expand_class_desc): Set up base_info_type_node here.
+ (init_rtti_processing): Instead of here.
+
+Wed Apr 10 14:17:13 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (init_rtti_processing): Do init regardless of -frtti.
+ (build_typeid): Only complain about taking dynamic typeid without
+ -frtti.
+
+ * decl2.c: flag_rtti defaults to 1.
+
+ * rtti.c (get_tinfo_var): The general class case is now smaller.
+ (init_rtti_processing): Pack the latter three fields of base_info
+ into 32 bits.
+
+Wed Apr 10 13:50:14 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (expand_member_init): Don't dump if name is NULL_TREE.
+
+Wed Apr 10 12:56:02 1996 Mike Stump <mrs@cygnus.com>
+
+ * search.c (make_memoized_table_entry): Undefer the pop, if necessary.
+ (push_memoized_context): Split out code to undefer pop_type_level to
+ (clear_memoized_cache): here.
+ (pop_memoized_context): We can only handle one layer of deferral of
+ pop_type_level so clear the cache, if there was a previous level.
+
+Tue Apr 9 23:06:09 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (init_rtti_processing): Build up base_info_type_node.
+ (expand_class_desc): Use one pointer to an array of base_info
+ structs, passed using a CONSTRUCTOR.
+
+Tue Apr 9 14:20:57 1996 Mike Stump <mrs@cygnus.com>
+
+ * class.c (build_vbase_path): Remove block extern for
+ flag_assume_nonnull_objects here.
+ (build_vfn_ref): Split out functionality into build_vtbl_ref.
+ (build_vtbl_ref): New routine.
+ (build_vtable): Set up rtti info here.
+ (add_virtual_function): Note in CLASSTYPE_RTTI the best
+ place where we can get the rtti pointers from to avoid having to
+ search around for a place.
+ (finish_base_struct): Likewise.
+ (finish_struct_1): Likewise. Never create totally new vtables
+ with totally new vtable pointers for rtti. Disable code to layout
+ vtable pointers better until we want to break binary
+ compatibility.
+ * rtti.c (build_headof_sub): New routine to convert down to a
+ sub-object that has an rtti pointer in the vtable.
+ (build_headof): Use it. Also, use build_vtbl_ref now to be more
+ maintainable.
+ (build_dynamic_cast): Make sure we have saved it, if we need to.
+ * search.c (dfs_init_vbase_pointers): Disable code that deals with
+ a more efficient vtable layout, enable later.
+ * call.c (flag_assume_nonnull_objects): Moved declaration to
+ * cp-tree.h: here. Declare build_vtbl_ref.
+ * pt.c (instantiate_class_template): Use NULL_TREE instead of 0 in
+ function calls that want a tree.
+
+Tue Apr 9 12:10:26 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (build_dynamic_cast): Handle downcasting to X* given
+ other X subobjects in the most derived type. Ack.
+
+ * rtti.c (build_dynamic_cast): No need to strip cv-quals here,
+ get_typeid will do it for us.
+ (get_typeid_1): Break out call-building for expand_*_desc to use.
+ (get_typeid): Call it.
+ (expand_*_desc): Likewise.
+ * decl.c (init_decl_processing): Don't set TYPE_BUILT_IN on char *
+ and void *.
+ (init_decl_processing): Lose builtin_type_tdescs lossage.
+ * decl2.c (finish_vtable_vardecl): Remove obsolete code.
+
+Mon Apr 8 17:23:23 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * pt.c (tsubst): When calling set_nested_typename, use
+ TYPE_NESTED_NAME (current_class_type) instead of
+ current_class_name.
+
+ * decl.c (pushdecl): Likewise.
+ (pushdecl_class_level): Likewise.
+ (grokdeclarator): Use NULL_TREE instead of 0 in the call to
+ set_nested_typename.
+
+Sun Apr 7 10:44:31 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (synthesize_tinfo_fn): Handle arrays.
+
+ * cp-tree.h (DECL_REALLY_EXTERN): New macro.
+
+Sat Apr 6 13:56:27 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (throw_bad_cast): Use entry point __throw_bad_cast.
+ (init_rtti_processing): Lose bad_cast_type.
+ (build_dynamic_cast): Use throw_bad_cast.
+
+ * rtti.c (synthesize_tinfo_fn): Handle enums and pmfs.
+
+ * decl2.c (finish_file): Don't synthesize artificial functions
+ that are external and not inline.
+
+ * rtti.c (get_tinfo_fn): If at_eof, call import_export_decl.
+
+ * decl2.c (finish_file): Handle having new inlines added to
+ saved_inlines by synthesis.
+
+ * rtti.c (get_bad_cast_node): Don't require <typeinfo>.
+
+Fri Apr 5 17:02:09 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ RTTI rewrite to initialize nodes as needed, not require that
+ users #include <typeinfo>, complete functionality and reduce wasted
+ space.
+ * rtti.c (init_rtti_processing): New fn.
+ (build_typeid): The vtable entry is now a function.
+ (get_tinfo_var): New fn.
+ (get_tinfo_fn): Likewise.
+ (get_typeid): Use it.
+ (build_dynamic_cast): Declare and use entry point __dynamic_cast.
+ (build_*_desc): Rename to expand_*_desc and rewrite to use entry
+ points __rtti_*.
+ (add_uninstantiated_desc, get_def_to_follow, build_t_desc): Lose.
+ (synthesize_tinfo_fn): New fn.
+ * method.c (build_t_desc_overload): Lose.
+ (build_overload_with_type): More generic.
+ * decl.c (init_decl_processing): Call init_rtti_processing.
+ * class.c (set_rtti_entry): Use get_tinfo_fn.
+ * decl2.c (mark_vtable_entries): Mark the rtti function.
+ (finish_prevtable_vardecl): Don't build_t_desc.
+ (import_export_decl): Handle tinfo functions.
+ (finish_file): Likewise.
+ * typeck.c (inline_conversion): New fn.
+ (build_function_call_real): Use it.
+ * cp-tree.h: Add decls.
+
+ * method.c (hack_identifier): Also convert component_refs from
+ references.
+
+ * lex.c (cons_up_default_function): Use the type, not the name, in
+ declspecs.
+
+ * decl2.c (import_export_vtable): Fix weak vtables.
+
+Fri Apr 5 13:30:17 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * search.c (get_base_distance_recursive): Fix access checks for
+ protected bases.
+
+Fri Apr 5 11:02:06 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (unary_complex_lvalue): Delete unneeded decl, it's in
+ cp-tree.h.
+ (convert_harshness): Add prototypes wrapped by PROTO.
+ * decl2.c (grok_function_init): Likewise.
+ (do_toplevel_using_decl): Change to void return type.
+ * class.c (build_vtable_entry): Remove decl of make_thunk.
+ (merge_overrides): Fix order of arg definitions.
+ (finish_vtbls): Likewise.
+ (fixup_vtable_deltas): Likewise.
+ (modify_all_direct_vtables): Likewise.
+ (modify_all_indirect_vtables): Likewise.
+ * search.c (get_base_distance_recursive): Likewise.
+ (get_abstract_virtuals_1): Likewise.
+ (fixup_virtual_upcast_offsets): Likewise.
+ (lookup_fnfields_1): Add prototypes wrapped by PROTO.
+ * init.c (perform_member_init): Fix order of arg definitions.
+ (expand_aggr_init_1): Add prototypes wrapped by PROTO.
+ * cp-tree.h (make_thunk): Add decl.
+ (overload_template_name, push_template_decl): Add decls.
+ (do_toplevel_using_decl): Change to void return type.
+ (vec_binfo_member): Add decl.
+
+Thu Apr 4 13:33:10 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (mark_addressable, convert_for_assignment,
+ convert_for_initialization, pointer_int_sum, pointer_diff,
+ unary_complex_lvalue): Add prototypes wrapped by PROTO.
+ (convert_sequence): #if 0 fn decl, since definition also is.
+
+Thu Apr 4 11:00:53 1996 Mike Stump <mrs@cygnus.com>
+
+ * rtti.c (build_dynamic_cast): Make sure we strip qualifiers on
+ cast to pointer types for type searching.
+
+Wed Apr 3 17:10:57 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (get_delta_difference): Use cp_error, not error, in the
+ case where BINFO == 0.
+
+Wed Apr 3 12:01:02 1996 Mike Stump <mrs@cygnus.com>
+
+ * call.c (build_method_call): Fix wording of error messages so
+ constructors come out right.
+
+Tue Apr 2 16:06:59 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * decl.c (push_overloaded_decl): Don't warn about hidden
+ constructors when both the type and the function are declared
+ in a system header file.
+
+Mon Apr 1 09:03:13 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * class.c (finish_struct_1): Propagate the TYPE_PACKED
+ flag for the type to the type's fields.
+
+Sat Mar 30 12:14:33 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (complex_parmlist, ELLIPSES): Take out ARM-based warning.
+
+Fri Mar 29 15:51:36 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * class.c (base_info, finish_base_struct): Replace
+ needs_virtual_dtor with base_has_virtual.
+
+ (finish_struct_1): Remove the old code that tried to make default
+ destructors virtual. Use base_has_virtual when checking if we need
+ to add a vtable entry for the rtti code.
+
+Fri Mar 29 14:02:36 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (push_template_decl): Complain about template decl with
+ inappropriate declaration.
+
+Fri Mar 29 12:15:35 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * typeck.c (build_x_unary_op): Remove bogus check for taking
+ the address of a member function.
+
+Fri Mar 29 11:56:02 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (constructor_declarator): Only push the class if
+ we are not already in the class.
+
+Fri Mar 29 09:41:02 1996 Jeffrey A. Law <law@cygnus.com>
+
+ * method.c (emit_thunk): Remove current_call_is_indirect nonsense.
+ Add additional argument to INIT_CUMULATIVE_ARGS.
+
+Thu Mar 28 16:41:39 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (shadow_tag): Fix error about anon union with methods.
+
+ * parse.y (self_reference): Only generate a self-reference if this
+ is a non-template class.
+ (opt.component_decl_list): Only use it if it was generated.
+
+ * parse.y (component_decl_1): Use constructor_declarator.
+ (fn.def2): Likewise.
+ (notype_component_declarator0): Likewise.
+
+Thu Mar 28 15:11:35 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * typeck.c (build_x_unary_op): Add checks for taking the address
+ of a TARGET_EXPR or of a member function, and give appropriate
+ warnings.
+
+Thu Mar 28 14:49:26 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (process_template_parm): Allow template type parms to be
+ used as types for template const parms.
+
+Wed Mar 27 15:51:19 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (expand_vec_init): Ensure the eh cleanups are on the
+ function_obstack.
+
+Wed Mar 27 10:14:30 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_name_real): Be even more picky about the
+ ambiguous lookup warning.
+ (grokdeclarator): Tweak SCOPE_REF constructor declarators here.
+ * parse.y (constructor_declarator): Rather than here.
+
+ * parse.y (constructor_declarator): New nonterminal.
+ (fn.def1): Use it.
+ (explicit_instantiation): Likewise.
+
+Tue Mar 26 13:41:33 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ Add implicit declaration of class name at class scope.
+ * decl.c (lookup_name_real): Restrict pedwarn about ambiguous lookup.
+ * parse.y (self_reference): New nonterminal.
+ (opt.component_decl_list): Use it.
+ (fn.def1): Add nested_name_specifier type_name cases.
+ * class.c (build_self_reference): New function.
+ (finish_struct): Handle access_default later, move self-reference
+ decl to the end.
+ * pt.c (lookup_template_class): Handle getting a TYPE_DECL.
+ * cp-tree.h: Adjust.
+
+ * pt.c (do_function_instantiation): Separate handling of member
+ functions and non-member functions properly.
+
+Mon Mar 25 14:23:22 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (process_template_parm): Improve error for 'volatile class K'.
+
+ * class.c (finish_struct_1): Check the right slot for destructors.
+
+ * decl.c (start_enum): Complain about enum templates.
+
+Mon Mar 25 13:25:31 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (resolve_offset_ref): Offset pointers to member data by one.
+ * typeck.c (unary_complex_lvalue): Likewise.
+
+Mon Mar 25 13:30:42 1996 Bob Manson <manson@charmed.cygnus.com>
+
+ * typeck.c (c_expand_return): Check for a returned local
+ array name, similar to the check for an ADDR_EXPR.
+
+Mon Mar 25 13:07:19 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (cp_finish_decl): Don't build cleanups for static
+ variables here.
+
+Fri Mar 22 17:57:55 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_modify_expr): Fix error messages to be more
+ accurate.
+ * cp-tree.h (assop_as_string): Parallel to op_as_string, but for
+ assignment operators.
+ * error.c (assop_as_string): Likewise. Add support for `%Q' for
+ assignment operators.
+
+Fri Mar 22 13:48:29 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Call bad_specifiers for typedefs. Also
+ give an error if initialized. pedwarn about nested type with the
+ same name as its enclosing class.
+
+ * pt.c (tsubst, case TYPE_DECL): Set DECL_CONTEXT.
+
+ * typeck.c (require_complete_type): Be sure to instantiate the
+ MAIN_VARIANT of the type.
+
+ * decl2.c (finish_file): Instantiate pending templates before
+ processing static constructors and destructors.
+
+ * pt.c (instantiate_decl): Don't instantiate functions at toplevel
+ unless at_eof.
+
+Fri Mar 22 09:30:17 1996 Bob Manson <manson@beauty.cygnus.com>
+
+ * decl2.c (delete_sanity): If error_mark_node is passed
+ in as an expression, quit while we're ahead.
+
+ * decl.c (grokdeclarator): Give an error message if `friend'
+ is combined with any storage class specifiers.
+
+Wed Mar 20 14:51:55 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (named_complex_class_head_sans_basetype): Don't crash on
+ definition of nonexistent nested type.
+
+ * error.c (dump_decl, case TYPE_DECL): Fix decision for whether or
+ not to say 'typedef'.
+
+Wed Mar 20 00:11:47 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (struct lang_type): Make search_slot a tree, not a char*.
+ * search.c (dfs_walk, dfs_init_vbase_pointers,
+ expand_upcast_fixups): Remove cast of CLASSTYPE_SEARCH_SLOT.
+ (dfs_find_vbases): Remove cast for CLASSTYPE_SEARCH_SLOT init.
+
+Tue Mar 19 17:56:03 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (build_throw): Support minimal parse.
+ * pt.c (tsubst_copy): Support THROW_EXPR.
+ * decl2.c (build_expr_from_tree): Likewise.
+
+ * pt.c (mangle_class_name_for_template): Always allocate
+ scratch_firstobj.
+
+Tue Mar 19 16:34:31 1996 Bob Manson <manson@beauty.cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Give an appropriate error
+ when trying to cast from an incomplete type.
+
+Tue Mar 19 16:00:33 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Don't bother setting up
+ CLASSTYPE_TAGS explicitly, as the nested types will add
+ themselves.
+
+Tue Mar 19 15:48:43 1996 Bob Manson <manson@beauty.cygnus.com>
+
+ * decl.c (shadow_tag): Remove old error check for usage of
+ an enum without a previous declaration.
+ (xref_tag): Add error message about usage of enums without a
+ previous declaration.
+
+Tue Mar 19 09:21:35 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (do_identifier): Only do name consistency check if we're
+ parsing.
+
+ * pt.c (push_template_decl): Don't crash if we get a member defn
+ that doesn't match.
+
+ * decl.c (xref_tag_from_type): New function to do an xref without
+ always having to figure out code_type_node.
+ * cp-tree.h: Declare it.
+ * pt.c (instantiate_class_template): Use it for friend classes.
+ (lookup_template_class): Use it.
+
+ * typeck2.c (build_functional_cast): Pull out a single parm before
+ passing it to build_c_cast.
+
+Tue Mar 19 09:07:15 1996 Bob Manson <manson@beauty.cygnus.com>
+
+ * expr.c (do_case): Give an error message if a pointer is
+ given as a case value.
+
+Mon Mar 18 21:57:54 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_c_cast): Don't pull single TEMPLATE_DECL out of
+ an overload list.
+
+ * lex.c (cons_up_default_function): Really, now, interface hackery
+ does not apply to synthesized methods.
+
+Mon Mar 18 18:20:57 1996 Mike Stump <mrs@cygnus.com>
+
+ * call.c (build_method_call): Ctors and dtors now have special names
+ with respect to lookups.
+ * class.c (add_method): Likewise.
+ (grow_method): Likewise.
+ (finish_struct_methods): Likewise.
+ (warn_hidden): Likewise.
+ (finish_struct_1): Likewise.
+ * cvt.c (convert_to_reference): Likewise.
+ (convert_to_aggr): Likewise.
+ (cp_convert): Likewise.
+ * decl2.c (check_classfn): Likewise.
+ * init.c (expand_member_init): Likewise.
+ (expand_default_init): Likewise.
+ (expand_aggr_init_1): Likewise.
+ (build_offset_ref): Likewise.
+ (build_new): Likewise.
+ (build_delete): Likewise.
+ * lex.c (do_inline_function_hair): Likewise.
+ * search.c (lookup_field_1): Likewise.
+ (lookup_fnfields_here): Likewise.
+ (lookup_field): Likewise.
+ (lookup_fnfields): Likewise.
+ (get_virtual_destructor): Likewise.
+ (dfs_debug_mark): Likewise.
+ (dfs_pushdecls): Likewise.
+ (dfs_compress_decls): Likewise.
+ * tree.c (layout_basetypes): Likewise.
+ * typeck.c (build_component_ref): Likewise.
+ (build_x_function_call): Likewise.
+ (build_modify_expr): Likewise.
+ (convert_for_initialization): Likewise.
+ (build_functional_cast): Likewise.
+ * cp-tree.h (CLASSTYPE_FIRST_CONVERSION): Likewise.
+ (CTOR_NAME): New.
+ (DTOR_NAME): New.
+ * decl.c (ctor_identifier): New.
+ (dtor_identifier): New.
+ (init_decl_processing): Set them.
+
+Mon Mar 18 18:00:51 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_component_ref): Don't get confused by fields whose
+ context has no type name, like pointer to member functions.
+
+Mon Mar 18 13:19:03 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Handle typedef without declarator.
+
+ * pt.c (tsubst): Handle SCOPE_REF in declarator.
+
+ * parse.y (bad_parm): Catch another case of missing `typename'.
+
+ * lex.c (yyprint): Handle TYPE_DECLs.
+
+ * decl.c (start_function): Don't try to be clever.
+
+ * lex.c: Lose compiler_error_with_decl.
+ * typeck2.c: Lose error_with_aggr_type.
+ (incomplete_type_error): Use cp_* instead of old functions.
+ (readonly_error): Likewise.
+ * typeck.c (convert_arguments): Likewise.
+ * search.c (lookup_nested_field): Likewise.
+ * method.c (make_thunk): Likewise.
+ * decl.c (grokparms): Likewise.
+ * cp-tree.h: Update.
+
+ * tree.c (min_tree_cons): Call copy_to_permanent for the purpose
+ and value.
+
+Mon Mar 18 11:25:52 1996 Bob Manson <manson@beauty.cygnus.com>
+
+ * method.c (build_opfncall): When deleting a pointer to an
+ array, build a new pointer to the tree past any ARRAY_TYPE
+ nodes.
+
+Mon Mar 18 10:11:46 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (lookup_name_real): Initialize local var TYPE to NULL_TREE.
+
+Fri Mar 15 11:03:57 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_decl): Only call import_export_decl if at_eof
+ and ! DECL_INLINE.
+
+ * decl.c (finish_function): Don't set nested based on
+ hack_decl_function_context.
+ * parse.y (function_try_block): Check for nested function.
+ (pending_inlines): Likewise.
+
+ * decl2.c (build_expr_from_tree): If a unary op already has a
+ type, just return it.
+
+ * decl2.c (finish_prevtable_vardecl): Use ADJUST_VTABLE_LINKAGE.
+
+ * decl2.c (walk_vtables): vardecl_fn returns int; return 1 if it does.
+ (finish_file): Check the return value of walk_vtables.
+ (finish_prevtable_vardecl): Return int.
+ (finish_vtable_vardecl): Likewise.
+ (prune_vtable_vardecl): Likewise.
+ * lex.c (set_vardecl_interface_info): Likewise.
+ * cp-tree.h: Adjust return types.
+
+ * class.c (delete_duplicate_fields_1): Don't complain about
+ duplicate nested types if they're the same type.
+ (finish_struct): Remove check for duplicate.
+ * decl2.c (grokfield): Don't check for typedef of anonymous type.
+
+Thu Mar 14 10:00:19 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h: Lose SIGNATURE_GROKKING_TYPEDEF.
+
+ * decl.c (grokdeclarator): Lose special handling of class-level
+ typedef. Lose SIGNATURE_GROKKING_TYPEDEF. Set
+ SIGNATURE_HAS_OPAQUE_TYPEDECLS later.
+
+ * cvt.c (convert_pointer_to_real): Retain cv-quals in conversion.
+
+ * pt.c (tsubst_copy): Strip cv-quals from destructor name types.
+
+ * search.c (compute_access): Fix handling of anonymous union
+ members.
+ * class.c (finish_struct_anon): Propagate TREE_{PRIVATE,PROTECTED}
+ from anonymous unions to their members.
+
+ * typeck.c (build_x_function_call): For static member functions,
+ hand off to build_member_call.
+
+Wed Mar 13 14:03:34 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_component_ref): Handle OFFSET_REFs.
+
+ * init.c (expand_vec_init): Fix init == 0 case.
+
+Tue Mar 12 14:36:02 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_new): pedwarn about init and array new.
+ (expand_vec_init): Handle lists, use convert_for_initialization.
+
+ * typeck.c (convert_for_initialization): Pass LOOKUP_NO_CONVERSION
+ when converting to an aggregate type.
+ * cvt.c (cp_convert): Pass it through.
+
+ * typeck.c (build_conditional_expr): Handle user-defined
+ conversions to slightly different types.
+
+ * decl.c (grokdeclarator): Force an array type in a parm to be
+ permanent.
+
+ * decl2.c (do_using_directive): Sorry.
+ (do_namespace_alias): Likewise.
+ * lex.c (real_yylex): Warn about using the `namespace' keyword.
+
+Sun Mar 10 22:26:09 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (datadef): Move call to note_list_got_semicolon up.
+
+Fri Mar 8 11:47:26 1996 Mike Stump <mrs@cygnus.com>
+
+ * tree.c (unsave_expr): Don't unsave, UNSAVE_EXPRs.
+
+Fri Mar 8 11:29:06 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (cp_finish_decl): The exception regions have to be
+ nested, not overlapping. We start the exception region for a
+ decl, after it has been fully built, and all temporaries for it
+ have been cleaned up.
+
+Thu Mar 7 17:46:06 1996 Mike Stump <mrs@cygnus.com>
+
+ * tree.c (vec_binfo_member): Don't core dump if we have no bases.
+
+Thu Mar 7 14:11:49 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.def: Add RETURN_INIT.
+ * pt.c (instantiate_decl): Handle RETURN_INIT.
+ * decl.c (store_return_init): Handle minimal_parse_mode.
+
+ * tree.c (cp_build_type_variant): Just return an error_mark_node.
+ * decl.c (make_typename_type): Don't try to get the file and line
+ of an identifier.
+ * typeck.c (comptypes): Handle TYPENAME_TYPE.
+
+Wed Mar 6 18:47:50 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (poplevel): Make sure we clear out and restore old local
+ non-VAR_DECL values by default when they go out of scope.
+
+Wed Mar 6 09:57:36 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (build_overload_value): Use DECL_ASSEMBLER_NAME in
+ referring to addresses of variables and functions.
+
+ * error.c (dump_expr): Support SIZEOF_EXPR.
+
+ * init.c (do_friend): Use the return value of check_classfn.
+
+ * typeck.c (convert_arguments): Call complete_type.
+
+ * method.c (hack_identifier): After giving an error, set value to
+ error_mark_node.
+
+Tue Mar 5 16:00:15 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (hack_decl_function_context): Kludge around DECL_CONTEXT
+ lossage for local classes.
+ * cp-tree.h: Declare it.
+ * decl.c (lookup_name_real): Evil, painful hack for local classes.
+ (grokfndecl): Set DECL_CLASS_CONTEXT and DECL_NO_STATIC_CHAIN here.
+ Use hack_decl_function_context.
+ (grokdeclarator): Don't set DECL_NO_STATIC_CHAIN here.
+ (start_function): Use hack_decl_function_context.
+ (finish_function): Likewise.
+ * method.c (synthesize_method): Likewise.
+ * lex.c (process_next_inline): Likewise.
+ (do_pending_inlines): Likewise.
+ * decl2.c (finish_file): Unset DECL_STATIC_FUNCTION_P when we're
+ done with it.
+
+Mon Mar 4 22:38:39 1996 Gerald Baumgartner <gb@alexander.cs.purdue.edu>
+
+ * sig.c (build_signature_pointer_or_reference_type): Align
+ signature pointers/references on 8-byte boundaries so they can be
+ grabbed 2 words at a time on a SPARC.
+
+Tue Mar 5 10:21:01 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (hack_identifier): Requiring a static chain is now a
+ hard error.
+ * decl.c (grokdeclarator): Set DECL_NO_STATIC_CHAIN on nested
+ functions.
+
+Mon Mar 4 20:03:33 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_offset_ref): Call complete_type.
+
+ * decl.c (pop_from_top_level): Always pop previous_class_type.
+
+ * parse.y: Handle multiple decls in a for-init-statement.
+ * pt.c (tsubst_expr): Likewise.
+
+ * pt.c (tsubst): Use tsubst_expr for the second operand of an
+ ARRAY_REF.
+
+ * decl.c (maybe_push_to_top_level): Don't save previous_class_type.
+ (poplevel_class): Set it here.
+ (pop_from_top_level): Pop it here if we're returning to class scope.
+ * class.c (pushclass): Don't set it here.
+
+ * decl.c (maybe_push_to_top_level): Save current_template_parms,
+ and clear it if !pseudo.
+ (pop_from_top_level): Restore it.
+
+ * decl2.c (finish_file): Push the dummy each time we walk the list
+ of vtables.
+
+ * error.c (dump_expr): Support LOOKUP_EXPR and actually do
+ something for CAST_EXPR.
+
+Mon Feb 19 14:49:18 1996 Rusty Russell <rusty@adelaide.maptek.com.au>
+
+ * cvt.c (cp_convert): Warn about implicit conversion of the
+ address of a function to bool, as it is always true.
+
+Fri Feb 23 23:06:01 1996 Rusty Russell <rusty@adelaide.maptek.com.au>
+
+ * typeck.c (c_expand_return): Fix warning for local externs returned.
+
+Mon Mar 4 15:03:11 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (mapcar): Propagate const and volatile properly.
+
+ * typeck.c (complete_type): Be sure to instantiate the
+ MAIN_VARIANT of the type.
+
+ * method.c (synthesize_method): Class interface hackery does not
+ apply to synthesized methods.
+
+Mon Mar 4 14:05:23 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (comp_template_args): Use comptypes rather than just
+ checking for TEMPLATE_TYPE_PARM equivalence.
+
+ * typeck.c (build_x_function_call): Call complete_type before
+ checking TYPE_OVERLOADS_CALL_EXPR.
+
+Mon Mar 4 18:48:30 1996 Manfred Hollstein <manfred@lts.sel.alcatel.de>
+
+ * g++.c (main): Check also for new define ALT_LIBM.
+
+Fri Mar 1 13:09:33 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): If we don't have a pattern
+ yet, that's OK.
+ (coerce_template_parms): If we see a local class, bail.
+
+ * decl.c (grok_reference_init): Make sure there's a type before
+ checking its code.
+
+ * pt.c (do_function_instantiation): Avoid crashing on invalid decls.
+ (push_template_decl): Likewise.
+
+ * parse.y (named_class_head): Set
+ CLASSTYPE_TEMPLATE_SPECIALIZATION here if we have basetypes.
+
+ * decl.c (xref_tag): Diagnose redeclaration of template
+ type-parameter name.
+
+ * error.c (dump_type): Handle anonymous template type parms.
+
+ * pt.c (instantiate_template): Use TYPE_MAIN_DECL instead of
+ TYPE_STUB_DECL.
+ (coerce_template_parms): Likewise.
+
+Thu Feb 29 16:26:01 1996 Mike Stump <mrs@cygnus.com>
+
+ * class.c (instantiate_type, case {ARRAY,INDIRECT}_REF,
+ case ADDR_EXPR): Don't modify rhs if a subinstantiation fails.
+
+Thu Feb 29 08:20:25 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_template): Take the MAIN_VARIANT of the type
+ before trying to get its STUB_DECL.
+ (coerce_template_parms): Likewise.
+
+ * parse.y (template_type_parm): If they didn't use 'class',
+ pretend they did after giving an error.
+
+ * pt.c (coerce_template_parms): Diagnose use of local class.
+
+ * decl.c (grok_reference_init): Use instantiate_type.
+
+ * error.c (dump_expr): Handle TEMPLATE_DECLs.
+
+ * parse.y (named_class_head): Diagnose mismatching types and tags.
+
+ * decl.c (pushdecl): Type decls and class templates clash with
+ artificial type decls, not hide them.
+
+ * decl.c (redeclaration_error_message): Diagnose redefinition of
+ templates properly.
+ (duplicate_decls): Diagnose disallowed overloads for template
+ functions, too.
+
+ * decl.c (start_decl): Call complete_type before checking for a
+ destructor.
+
+ * pt.c (tsubst): Use tsubst_expr on the elts of a VEC.
+
+ * decl.c (xref_tag): A TEMPLATE_TYPE_PARM is a match.
+
+Wed Feb 28 09:28:44 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grok_op_properties): Don't check for operator++(int) in
+ a template.
+
+ * tree.c (perm_manip): Return a copy of variable and function
+ decls with external linkage.
+
+ * tree.def: Change some of the min tree codes to type "1".
+ * pt.c (uses_template_parms): Handle 'e's, return 1 for LOOKUP_EXPRs.
+ * method.c (build_overload_int): Emit something arbitrary for
+ anything but an INTEGER_CST if we're in a template.
+
+ * decl.c (cp_finish_decl): Call complete_type before deciding
+ whether or not to lay out the decl.
+
+ * lex.c (do_identifier): Check for DECL_INITIAL before using it.
+
+Tue Feb 27 16:35:32 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (build_x_arrow): Call complete_type.
+
+ * pt.c (add_pending_template): Broken out.
+ (lookup_template_class): If -fexternal-templates, call it for all
+ the methods of implemented types.
+ (instantiate_class_template): Instead of instantiating them here.
+ (instantiate_decl): Handle -fexternal-templates earlier.
+
+Tue Feb 27 15:51:32 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * search.c, lex.c, decl.c, class.c, cp-tree.h: Don't wrap the
+ memoized lookup stuff inside GATHER_STATISTICS.
+
+Tue Feb 27 10:38:08 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_decl): Complain about array of incomplete type
+ here.
+ (grokdeclarator): Not here.
+
+ * parse.y (template_parm): Expand full_parm inline so we can set
+ the rule's precedence.
+
+ * pt.c (tsubst_expr): If we're in a template, just do tsubst_copy.
+ (tsubst): tsubst_expr the DECL_INITIAL of FIELD_DECLs.
+ * decl2.c (grokbitfield): Don't check for integer constant here.
+ * class.c (finish_struct_1): Check here.
+
+ * decl.c (define_label): Make the min decl go on permanent_obstack.
+
+ * pt.c (unify): Don't handle CONST_DECLs.
+ (uses_template_parms): Don't check DECL_INITIAL on a CONST_DECL.
+ (tsubst_copy): Likewise.
+
+ * lex.c (do_identifier): Do pull the DECL_INITIAL out of a
+ CONST_DECL for a template parm.
+
+Mon Feb 26 12:48:18 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Complain about array of incomplete type
+ here.
+ (start_decl_1): Not here.
+
+ * pt.c (tsubst): Handle pointer-to-function declarators.
+
+ * method.c (hack_identifier): If pedantic, diagnose local class
+ methods that require a static chain.
+
+ * decl.c (grok_op_properties): No longer static.
+ * cp-tree.h: Declare it.
+ * pt.c (tsubst): Call it for operators.
+ Use tsubst_copy for TREE_VECs.
+
+ * parse.y (template_arg): The expr has precedence like '>'.
+
+Fri Feb 23 14:51:52 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (coerce_template_parms): Don't coerce an expression using
+ template parms.
+ (uses_template_parms): Also check DECL_INITIAL in CONST_DECLs.
+ (tsubst): Don't use build_index_2_type if the max_value uses template
+ parms.
+ * method.c (build_overload_int): Emit something arbitrary for an
+ expression using template parms.
+
+ * parse.y (template_close_bracket): New non-terminal to catch use
+ of '>>' instead of '> >' in template class names.
+ (template_type): Use it.
+ * Makefile.in (CONFLICTS): Causes one more r/r conflict.
+
+ * tree.def: Add CAST_EXPR.
+ * typeck2.c (build_functional_cast): Use CAST_EXPR instead of
+ CONVERT_EXPR for minimal_parse_mode.
+ * typeck.c (build_c_cast): Likewise.
+ * pt.c (tsubst_copy): Likewise.
+ * decl2.c (build_expr_from_tree): Likewise.
+ * error.c (dump_expr): Likewise.
+
+Fri Feb 23 10:36:46 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * except.c (SetTerminate, SetUnexpected): Put back global vars.
+ (init_exception_processing): Put back decl/init of
+ set_unexpected_fndecl and set_terminate_fndecl, needed to get the
+ fns from libstdc++.
+
+ * decl.c (struct binding_level): Delete ACCEPT_ANY bitfield.
+ (declare_uninstantiated_type_level, uninstantiated_type_level_p):
+ Delete unused fns.
+ * cp-tree.h (declare_uninstantiated_type_level,
+ uninstantiated_type_level_p): Delete prototypes.
+
+Thu Feb 22 19:36:15 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst_expr): Add default return.
+
+Thu Feb 22 16:47:24 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * error.c (fndecl_as_string): Delete unused arg CNAME.
+ * sig.c (build_signature_table_constructor,
+ build_signature_method_call): Fix calls.
+
+ * class.c (the_null_vtable_entry): Delete var definition.
+ (init_class_processing): Delete tree the_null_vtable_entry init.
+ * decl.c (no_print_{functions, builtins}): Declare as static.
+ (__tp_desc_type_node): #if 0 var definition.
+ (init_type_desc): #if 0 init of __tp_desc_type_node.
+ (vb_off_identifier): Move var decl into init_decl_processing.
+ (current_function_assigns_this): Declare as static.
+ (int_ftype_ptr_ptr_int, void_ftype_ptr_int_int): Delete var decls.
+ (init_decl_processing): Delete init of void_ftype_ptr_ptr_int.
+ Move decls of string_ftype_ptr_ptr and int_ftype_string_string here.
+ * decl2.c (delete_sanity): Delete definition/mod of local var ELT_SIZE.
+ * init.c (BI_header_type, BI_header_size): Declare as static.
+ * pt.c (template_classes): Delete unused var.
+ (add_pending_template): Delete decl for non-existent fn.
+ (lookup_template_class): Delete vars CODE and TAG_CODE.
+ (instantiate_template): Delete unused var TARGS.
+ * cp-tree.h (vb_off_identifier, current_function_assigns_this):
+ Delete decls.
+ (__tp_desc_type_node): #if 0 var decl.
+ (fndecl_as_string): Fix prototype.
+
+Thu Feb 22 15:56:19 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.def: Add GOTO_STMT.
+ * pt.c (tsubst_expr): Support goto and labels.
+ * decl.c (define_label): Support minimal parsing.
+ * parse.y (simple_stmt): Likewise.
+
+Thu Feb 22 15:30:12 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * xref.c (GNU_xref_member): Only define/set var I if
+ XREF_SHORT_MEMBER_NAMES is defined, to match when it's actually
+ used.
+ (GNU_xref_end_scope): Delete unused fifth arg TRNS.
+ (GNU_xref_end): Fix call.
+ * decl.c (poplevel, poplevel_class, finish_method): Fix calls.
+ * cp-tree.h (GNU_xref_end_scope): Fix prototype.
+
+ * tree.c (build_exception_variant): Delete unused vars I, A, T,
+ T2, and CNAME.
+ (layout_vbasetypes): Delete unused var NONVIRTUAL_VAR_SIZE.
+ (mapcar): Delete unused var CODE.
+ (build_cplus_new): Delete unused arg WITH_CLEANUP_P.
+ (break_out_cleanups): Fix call.
+ (bot_manip): Likewise.
+ * call.c (build_method_call): Likewise.
+ * cvt.c (build_up_reference, convert_to_reference, cp_convert):
+ Likewise.
+ * typeck.c (unary_complex_lvalue, build_modify_expr,
+ convert_for_initialization): Likewise.
+ * typeck2.c (build_functional_cast): Likewise.
+ * cp-tree.h (build_cplus_new): Fix prototype.
+
+ * repo.c (open_repo_file): Delete unused var Q.
+ (repo_compile_flags, repo_template_declared,
+ repo_template_defined, repo_class_defined, repo_inline_used,
+ repo_vtable_used, repo_tinfo_used): #if 0 unused fns.
+ (repo_get_id, repo_vtable_used): Declare as static.
+ * cp-tree.h (mark_{decl,class}_instantiated, finish_repo): Add
+ prototypes.
+
+Thu Feb 22 14:53:35 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (pending_inlines): Add function_try_block case.
+
+ * pt.c (unify): Fix for template const parms.
+
+Thu Feb 22 13:24:15 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lex.c (extract_interface_info): Delete forward decl.
+ (default_copy_constructor_body, default_assign_ref_body): Delete
+ decls for non-existent functions.
+ (synth_firstobj, inline_text_firstobjs): Delete unused vars.
+ (init_lex): Delete setting them.
+ (cons_up_default_function): Delete unused vars FUNC_BUF,
+ FUNC_LEN, and COMPLEX. Delete code setting COMPLEX. Delete old
+ #if 0'd synth code.
+ (toplevel, expression_obstack): Delete unused extern decls.
+ (tree_node_kind): Delete unused enum.
+ (tree_node_counts, tree_node_sizes): Wrap with #ifdef
+ GATHER_STATISTICS.
+ (tree_node_kind_names): Delete unused extern decl.
+ (synth_obstack): Delete unused var.
+ (init_lex): Don't set it.
+ (init_parse): Add decl before use.
+ (reduce_count): Only define #ifdef GATHER_STATISTICS && REDUCE_LENGTH.
+ (current_unit_{name, language}): Delete unused vars.
+ (check_newline): Don't bother setting them, just accept the #pragma.
+ * cp-tree.h (init_repo, peek_yylex): Add prototypes.
+ (current_unit_{name, language}): Delete decls.
+
+ * search.c: Wrap all of the memoized functions, macros, and
+ variables inside #ifdef GATHER_STATISTICS.
+ (lookup_field, lookup_fnfields): Likewise.
+ (init_search_processing): Likewise.
+ (reinit_search_statistics): Wrap whole function.
+ * lex.c (reinit_lang_specific): Wrap call to reinit_search_statistics.
+
+ * decl.c (finish_function): Only call pop_memoized_context if
+ GATHER_STATISTICS is defined.
+ (start_function): Likewise for push_memoized_context.
+ * class.c (pushclass, popclass): Likewise.
+
+ * cp-tree.h (CLASSTYPE_MTABLE_ENTRY): Move definition from here...
+ * search.c (CLASSTYPE_MTABLE_ENTRY): ... to here.
+
+ * cvt.c (cp_convert): Delete unused local var FORM.
+ * cp-tree.h (can_convert, can_convert_arg, real_lvalue_p): Add
+ prototypes.
+
+Thu Feb 22 13:19:44 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (do_poplevel): Oops; really return what we get from
+ poplevel this time.
+
+Thu Feb 22 11:41:44 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (is_aggr_type): Add prototype.
+
+ * cp-tree.h ({push,pop}_cp_function_context): Add decls.
+ * method.c ({push,pop}_cp_function_context): Delete decls.
+ * except.c (start_eh_unwinder, end_eh_unwinder): Declare as void.
+ (SetUnexpected, SetTerminate): Delete unused vars.
+ (init_exception_processing): Don't set SetUnexpected or
+ SetTerminate. Don't set SET_UNEXPECTED_FNDECL or SET_TERMINATE_FNDECL.
+ (output_exception_table_entry): Delete unused array LABEL.
+ (expand_internal_throw): Delete unused var PARAMS.
+ (expand_start_catch_block): Delete unused var CLEANUP.
+ (emit_exception_table): Delete unused var EH_NODE_DECL.
+ (expand_builtin_throw): Delete unused vars UNWIND_AND_THROW and
+ GOTO_UNWIND_AND_THROW. Don't set them.
+ (end_eh_unwinder): Add top decl.
+ (pop_rtl_from_perm): Delete unused decl of PERMANENT_OBSTACK.
+ (exception_section, push_rtl_perm, do_function_call,
+ lang_interim_eh, push_eh_cleanup, eh_outer_context,
+ expand_end_eh_spec, end_eh_unwinder): Declare as static.
+ (saved_pc, saved_throw_type, saved_throw_value, saved_cleanup,
+ throw_used): Likewise.
+ * cp-tree.h (expand_end_eh_spec): Delete prototype.
+
+ * search.c (dfs_mark, dfs_mark_vtable_path,
+ dfs_unmark_vtable_path, dfs_mark_new_vtable,
+ dfs_unmark_new_vtable, dfs_clear_search_slot,
+ dfs_search_slot_nonempty_p, bfs_markedp, bfs_unmarkedp,
+ bfs_marked_vtable_pathp, bfs_unmarked_vtable_pathp,
+ bfs_marked_new_vtablep, bfs_unmarked_new_vtablep): #if 0 unused
+ functions.
+ (n_fields_searched, n_calls_lookup_field, n_calls_lookup_field_1,
+ n_calls_lookup_fnfields, n_calls_lookup_fnfields_1,
+ n_calls_get_base_type, n_outer_fields_searched, n_contexts_saved):
+ Only define #ifdef GATHER_STATISTICS.
+ (reinit_search_statistics): Only init some vars if GATHER_STATISTICS
+ is defined.
+ (vbase_decl): Delete var definition.
+ (init_search): Delete old decl.
+ (init_vbase_pointers): Delete building of VBASE_DECL, since it's
+ never actually used.
+ (expand_indirect_vtbls_init): Delete init of VBASE_DECL.
+ (get_base_distance_recursive): Delete unused fourth arg
+ BASETYPE_PATH. Fix call .
+ (get_base_distance): Fix call.
+ (push_class_decls): Delete unused var ID.
+ (make_memoized_table_entry): Declare as static.
+ (breadth_first_search): Declare as static.
+ (tree_has_any_destructor_p): Declare as static.
+ (pop_class_decls): Delete unused arg pop_class_decls.
+ * class.c (popclass): Fix call to pop_class_decls.
+ * cp-tree.h (make_memoized_table_entry, breadth_first_search,
+ tree_has_any_destructor_p): Delete prototypes.
+
+ * rtti.c (build_ptmf_desc): Delete unused arg TYPE.
+ (build_t_desc): Fix call. Delete unused vars ELEMS and TT.
+ (build_dynamic_cast): Delete unused local vars TMP1 and RETVAL.
+ (build_user_desc): Delete unused var T.
+ (build_class_desc): Delete unused vars T and OFF.
+ (build_t_desc): Delete unused var NAME_STRING.
+ (build_headof): Make static.
+ (get_bad_cast_node): Likewise.
+ (get_def_to_follow): Likewise.
+ * cp-tree.h (init_type_desc): Add prototype.
+ (build_headof): Remove prototype.
+
+Thu Feb 22 00:54:22 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Only look for matching decls at file scope for
+ non-member functions.
+
+ * call.c (build_scoped_method_call): Handle scoped destructor
+ calls in templates.
+
+ * decl.c (*_top_level): Also save previous_class_values.
+
+ * pt.c (tsubst_expr): Support do {} while loops.
+ * parse.y (simple_stmt): Likewise.
+ * tree.def: Likewise.
+
+ * method.c (build_overload_identifier): For a class nested in a
+ template class, don't mangle in the template parms from our
+ context.
+
+ * lex.c, cp-tree.h: Remove support for template instantiations in
+ the pending_inlines code.
+ * pt.c: Remove dead functions and unused arguments.
+ (uses_template_parms): TYPENAME_TYPEs always use template parms.
+ * parse.y: Stop passing anything to end_template_decl.
+ * tree.c (print_lang_statistics): Only print tinst info #ifdef
+ GATHER_STATISTICS.
+
+Wed Feb 21 16:57:33 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (expand_recursive_init{,_1}): Delete decls.
+ (sort_member_init): Delete unused var INIT.
+ (emit_base_init): Delete unused var X.
+ (build_offset_ref): Delete unused var CNAME.
+ (sort_member_init): Delete unused var FIELDS_TO_UNMARK.
+ (emit_base_init): Delete unused local var BASE. Delete extern
+ decl of IN_CHARGE_IDENTIFIER.
+ (build_delete): Delete unused local var VIRTUAL_SIZE.
+
+ * init.c (build_vec_delete): Delete unused third arg ELT_SIZE.
+ (build_delete): Fix call.
+ * decl2.c (delete_sanity): Likewise.
+ * cp-tree.h (build_vec_delete): Update prototype.
+
+ * typeck.c (common_base_type): Delete unused var TMP.
+ (build_binary_op): Delete local var ARGS_SAVE.
+ (build_array_ref): Delete unused var ITYPE.
+ (c_expand_return): Delete unused var USE_TEMP.
+
+ * typeck.c (compexcepttypes): Delete unused arg STRICT.
+ (comptypes): Fix calls.
+ * decl.c (duplicate_decls): Likewise.
+ * cp-tree.h (compexcepttypes): Delete extra arg.
+
+ * decl2.c (check_classfn): Delete unused second arg CNAME.
+ * decl.c (start_decl, grokfndecl): Fix calls.
+ * init.c (do_friend): Likewise.
+ * cp-tree.h (check_classfn): Update prototype.
+
+ * cp-tree.h (signature_error, import_export_vtable,
+ append_signature_fields, id_in_current_class, mark_used,
+ copy_assignment_arg_p): Add decls.
+ * decl2.c (mark_used): Delete decl.
+
+ * class.c (n_*): Wrap with #ifdef GATHER_STATISTICS.
+
+ * class.c (get_vtable_entry): Disable unused function.
+ (doing_hard_virtuals): Delete unused static global var.
+ (finish_struct_1): Don't init DOING_HARD_VIRTUALS.
+ (prepare_fresh_vtable): Delete unused vars PATH and RESULT.
+ (overrides): Delete unused vars RETTYPE and BASE_RETTYPE.
+ (modify_one_vtable): Delete unused var OLD_RTTI.
+ (finish_struct_anon): Delete unused vars OFFSET and X.
+ (finish_struct_bits): Delete unused var METHOD_VEC.
+ (get_basefndecls): Delete unused var PURPOSE. Delete unused
+ for-scope local variable METHODS.
+
+ * call.c (user_harshness): Delete unused/unneeded arg PARM.
+ (ideal_candidate): Delete unused args BASETYPE and PARMS.
+ (build_method_call): Delete unused args passed into ideal_candidate.
+ (build_overload_call_real): Likewise. Delete unused var OVERLOAD_NAME.
+ * cp-tree.h (synthesize_method): Add decl.
+
+ * decl.c (note_level_for_for): Give void return type.
+ (pushdecl_nonclass_level): Likewise.
+ (finish_function): Delete unused vars VFIELDS and ALLOCATED_THIS.
+ (poplevel): Delete unused var IMPLICIT_TRY_BLOCK.
+ (suspend_binding_level): Delete unused var LEVEL.
+ (duplicate_decls): Delete unused var CTYPE.
+ (duplicate_decls): Delete unused var PREVIOUS_C_DECL.
+ (init_decl_processing): Delete unused vars FLOAT_ENDLINK and
+ PTR_ENDLINK.
+ (grokdeclarator): Delete unused var C.
+ (grokdeclarator): Delete unused var SIZE_VARIES.
+ (grokparms): Delete unused var SAW_VOID.
+ (start_function): Delete unused var OLDDECL.
+ (cplus_expand_expr_stmt): Delete unused var
+ REMOVE_IMPLICIT_IMMEDIATELY.
+
+ * cp-tree.h (pushdecl_nonclass_level): Fix prototype.
+
+ * Makefile.in (CONFLICTS): Update to 12 shift/reduce.
+
+Wed Feb 21 00:06:17 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (build_min): Set TREE_COMPLEXITY to lineno.
+ (build_min_nt): Likewise.
+ * pt.c (do_pushlevel): Emit line note.
+ (do_poplevel): Return what we get from poplevel.
+ (tsubst_expr): Set lineno from TREE_COMPLEXITY in stmt nodes.
+ * parse.y: Use do_pushlevel and do_poplevel.
+ * cp-tree.h: Declare do_poplevel.
+
+ * cp-tree.h: Declare at_eof.
+ * decl.c (cp_finish_decl): Pass it to rest_of_decl_compilation.
+ * decl2.c (import_export_decl): Renamed from import_export_inline.
+ (finish_file): Call it to do interface handling for statics.
+ * pt.c (tsubst_copy): Call mark_used on variables and functions
+ used here.
+
+ * decl2.c (finish_file): Don't emit statics we can't generate.
+ * pt.c (instantiate_decl): Don't set interface on instantiations
+ we can't generate.
+
+ * cp-tree.h (struct tinst_level): Change 'classname' to 'decl'.
+ * tree.c (print_lang_statistics): Print max template depth.
+ * pt.c (push_tinst_level): Dump entire instantiation context.
+ (instantiate_class_template): Use it and pop_tinst_level.
+ (instantiate_decl): Likewise.
+
+ * call.c class.c cp-tree.h decl.c decl2.c error.c lex.c method.c
+ pt.c ptree.c tree.def: Remove all traces of UNINSTANTIATED_P_TYPE.
+
+Tue Feb 20 18:21:51 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c class.c cp-tree.h cvt.c decl.c decl2.c error.c expr.c
+ init.c lex.c method.c parse.y pt.c repo.c search.c spew.c tree.c
+ tree.def typeck.c typeck2.c xref.c: Massive, systemic changes for
+ the new template implementation.
+
+Tue Feb 20 17:14:29 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl2.c (check_cp_case_value): Use STRIP_TYPE_NOPS.
+
+Thu Feb 15 18:44:42 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (cp_finish_decl): Delay emitting the debug information for
+ a typedef that has been installed as the canonical typedef, if the
+ type has not yet been defined.
+
+Thu Feb 15 09:39:08 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (grokfield): Still call pop_nested_class for access decls.
+
+Wed Feb 14 17:30:04 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (lookup_label): Call label_rtx.
+
+ * decl.c (make_binding_level): New function.
+ (pushlevel, pushlevel_class): Call it instead of explicit
+ duplicate calls to xmalloc.
+
+ * decl.c (init_decl_processing): Delete useless build_pointer_type
+ call.
+
+ * decl.c (float_ftype_float, ldouble_ftype_ldouble): Add definitions.
+ (sizet_ftype_string): Delete variable.
+ (init_decl_processing): Add built-in functions fabsf, fabsl,
+ sqrtf, sqrtl, sinf, sin, sinl, cosf, cos, cosl. New local
+ variable strlen_ftype, used for strlen.
+
+Wed Feb 14 16:21:25 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (push_to_top_level): Start from current_binding_level
+ again for now; the stl hacks depend on g++ being broken in this
+ way, and it'll be fixed in the template rewrite.
+
+ * tree.def: Add USING_DECL.
+ * decl2.c (do_class_using_decl): Implement.
+ (grokfield): Pass access decls off to do_class_using_decl instead of
+ grokdeclarator.
+ * error.c (dump_decl): Handle USING_DECLs.
+ * decl.c (grokdeclarator): Remove code for handling access decls.
+ * class.c (finish_struct_1): Adjust accordingly, treat using-decls
+ as access decls for now.
+ (finish_struct): Don't check USING_DECLs for other uses of the name.
+
+ * search.c (get_matching_virtual): Use cp_error_at.
+
+Wed Feb 14 10:36:58 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (comptypes): Default COMP_TYPE_ATTRIBUTES to 1, to
+ match c-typeck.c.
+ (self_promoting_args_p): Move the check that TYPE is non-nil
+ before trying to look at its main variant.
+ (unsigned_type, signed_type): Add checking of DI/SI/HI/QI nodes.
+
+ * cp-tree.h (DECL_WAITING_FRIENDS, SET_DECL_WAITING_FRIENDS):
+ Delete macros.
+ * init.c (xref_friend, embrace_waiting_friends): Delete functions.
+ (do_friend): Delete call to xref_friend.
+ * class.c (finish_struct_1): Delete call to embrace_waiting_friends.
+
+ * typeck.c (convert_sequence): #if 0 unused function.
+
+ * cp-tree.h (DECL_IN_MEMORY_P): New macro w/ the check that used to
+ be in decl_in_memory_p.
+ (decl_in_memory_p): Delete decl.
+ * expr.c (decl_in_memory_p): Delete fn.
+ * typeck.c (mark_addressable): Use DECL_IN_MEMORY_P.
+
+ * decl.c (cp_finish_decl): Use DECL_IN_MEMORY_P.
+
+Tue Feb 13 12:51:21 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_1): Check for a pure-specifier on a
+ non-virtual function here.
+
+ * decl2.c (grok_function_init): Don't check whether the function
+ is virtual here.
+ (grokfield): Don't call check_for_override here.
+
+ * decl.c (push_to_top_level): Start from inner_binding_level,
+ check class_shadowed in class levels.
+
+Mon Feb 12 17:46:59 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (resume_level): Ignore things that don't have names, instead
+ of core dumping.
+
+Mon Feb 12 15:47:44 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl2.c (grokfield): Set DECL_VINDEX properly for FUNCTION_DECLs.
+
+Sat Feb 10 17:59:45 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_1): Set DECL_VINDEX properly on a
+ synthesized dtor.
+
+ * parse.y (complete_type_name): Bind global_scope earlier.
+ (complex_type_name): Likewise.
+ (qualified_type_name): Remove.
+
+Thu Feb 8 15:15:14 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokfndecl): Move code that looks for virtuals in base
+ classes...
+ * class.c (check_for_override): ... to a new function.
+ (finish_struct_1): Call it.
+
+ * cp-tree.h: Declare warn_sign_compare.
+
+ * typeck.c (build_binary_op_nodefault): Check warn_sign_compare
+ rather than extra_warnings to decide whether to warn about
+ comparison of signed and unsigned.
+
+ * decl2.c (lang_decode_option): Handle warn_sign_compare. -Wall
+ implies -Wsign-compare. -Wall doesn't imply -W.
+
+Wed Feb 7 15:27:57 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_component_ref): Fix to handle anon unions in base
+ classes as well.
+
+Wed Feb 7 14:29:12 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * class.c (resolves_to_fixed_type_p): Delete code dealing with
+ a WITH_CLEANUP_EXPR, since we don't generate them any more.
+ * cvt.c (build_up_reference): Likewise.
+ * decl.c (grok_reference_init): Likewise.
+ (cp_finish_decl): Likewise.
+ * error.c (dump_expr): Likewise.
+ * tree.c (real_lvalue_p): Likewise.
+ (lvalue_p): Likewise.
+ (build_cplus_new): Likewise.
+ (unsave_expr_now): Likewise.
+ * typeck.c (unary_complex_lvalue, build_modify_expr,
+ c_expand_return): Likewise.
+
+Tue Feb 6 13:39:22 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ Make the C++ front-end pay attention to attributes for structures.
+ * class.c (finish_struct): New argument ATTRIBUTES, passed down into
+ finish_struct_1.
+ (finish_struct_1): New argument ATTRIBUTES; call cplus_decl_attributes.
+ Take out old round_up_size use and setting the DECL_ALIGN possibly
+ using it. Take out setting of TYPE_ALIGN to round_up_size, which
+ can override what the attribute set.
+ * cp-tree.h (finish_struct): Update prototype.
+ * parse.y (template_instantiate_once): Pass a NULL_TREE for the
+ attributes to finish_struct.
+ (structsp): For a CLASS decl, add maybe_attribute to rule and pass that
+ value down into finish_struct.
+ * Makefile.in (CONFLICTS): Switch to 7 shift/reduce conflicts.
+
+Tue Feb 6 13:12:15 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (poplevel): Re-word dead for local handling.
+ (pushdecl): Remove useless DECL_DEAD_FOR_LOCAL test.
+ (cp_finish_decl): If is_for_scope, check for duplicates so
+ we can disable is_for_scope. Otherwise, preserve_temp_slots.
+
+ * lex.c (do_identifier): Use global binding in preference of
+ dead for local variable.
+
+Mon Feb 5 17:46:46 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (initializing_context): Handle anon union changes, the
+ context where fields of anon unions can be initialized now has to be
+ found by walking up the TYPE_CONTEXT chain.
+
+Fri Feb 2 14:54:04 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * decl.c (start_decl): #ifdef out code to set DECL_COMMON
+ if ASM_OUTPUT{,_ALIGNED}_BSS is defined.
+ (obscure_complex_init): If bss is supported, always set
+ DECL_INITIAL to error_mark_node.
+
+Thu Feb 1 16:19:56 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (is_friend): Make sure there's a context before we see if
+ it's an aggr type.
+
+Thu Feb 1 15:44:53 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (is_friend): Classes are not friendly with nested classes.
+
+Thu Feb 1 15:27:37 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * lex.c (check_newline): Pass last character read to HANDLE_PRAGMA,
+ and record its result.
+
+Thu Feb 1 09:27:01 1996 Mike Stump <mrs@cygnus.com>
+
+ * class.c (finish_struct_anon): Switch around code to not move anon
+ union elements around, nor mess up their contexts, nor offsets,
+ instead we now build up the right number of COMPONENT_REFs for all
+ the anon unions that may be present at build_component_ref time.
+ * typeck.c (lookup_anon_field): New routine to handle field lookup
+ on fields without names. We find them, based upon their unique type
+ instead.
+ * typeck.c (build_component_ref): Allow FIELD_DECL components.
+ Handle finding components in anonymous unions, and ensure that a
+ COMPONENT_REF is built for each level as necessary.
+
+Tue Jan 30 18:18:23 1996 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (build_up_reference): Make the INDIRECT_BIND case come after
+ code that ensures that copy ctors are used if appropriate.
+
+Tue Jan 30 17:35:14 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_vec_delete): Only give an error if base isn't an
+ error_mark_node.
+
+Mon Jan 29 17:09:06 1996 Mike Stump <mrs@cygnus.com>
+
+ * spew.c (do_aggr): `new struct S;' isn't a forward declaration.
+ (yylex): If we see `new', keep slurping.
+
+Thu Jan 25 18:31:36 1996 Mike Stump <mrs@cygnus.com>
+
+ * class.c (finish_struct_1): Move code for handling anon unions...
+ (finish_struct_anon): to here. Fixup so that we do the offset
+ calculations right, and so that the fields are physically moved to
+ the containers's chain.
+
+Thu Jan 25 18:27:37 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (grokdeclarator): Avoid trying to get an operand off an
+ identifier node.
+
+Wed Jan 24 11:25:30 1996 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * typeck.c (pointer_int_sum): Use TYPE_PRECISION (sizetype) not
+ POINTER_SIZE to agree with expr.c.
+
+Thu Jan 25 13:01:23 1996 Mike Stump <mrs@cygnus.com>
+
+ * search.c (lookup_field): Don't report ambiguities if protect is 0,
+ instead return NULL_TREE.
+
+Wed Jan 24 13:01:26 1996 Mike Stump <mrs@cygnus.com>
+
+ * class.c (finish_struct_1): Call warn_hidden if we want warnings
+ about overloaded virtual functions.
+ (warn_hidden): New routine to warn of virtual functions that are
+ hidden by other virtual functions, that are not overridden.
+ (get_basefndecls): New routine, used by warn_hidden.
+ (mark_overriders): New routine, used by warn_hidden.
+ * search.c (get_matching_virtual): Remove old warning that just
+ isn't very useful.
+
+Tue Jan 23 12:26:10 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (output_builtin_tdesc_entries): #if 0 the function definition.
+
+ * typeck.c (null_ptr_cst_p): Delete unused fn.
+ (build_function_call_maybe): Delete unused fn.
+
+ * expr.c (extract_init): #if 0 the code after unconditional return 0
+ for now.
+
+ Delete old cadillac code.
+ * edsel.c: Remove file.
+ * Make-lang.in (CXX_SRCS): Take edsel.c off the list.
+ * Makefile.in (CXX_OBJS): Delete edsel.o.
+ (edsel.o): Delete rule.
+ * cp-tree.h (flag_cadillac): Delete var decl.
+ * lang-options.h: Delete "-fcadillac" and "-fno-cadillac".
+ * decl2.c (flag_cadillac): Delete var definition.
+ (lang_decode_option): Delete handling of -fcadillac and -fno-cadillac.
+ (grokfield): Delete code depending on flag_cadillac.
+ (finish_anon_union): Likewise.
+ * class.c (finish_struct_1): Likewise.
+ (pushclass): Likewise.
+ (popclass): Likewise.
+ (push_lang_context): Likewise.
+ (pop_lang_context): Likewise.
+ * decl.c (init_decl_processing): Likewise.
+ (start_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (xref_tag): Likewise.
+ (finish_enum): Likewise.
+ (start_function): Likewise.
+ (finish_function): Likewise.
+ (finish_stmt): Likewise.
+ * lex.c (lang_init): Likewise.
+ (check_newline): Likewise.
+
+ * lex.c (do_pending_inlines): Delete synthesized method kludge.
+
+ Delete defunct, ancient garbage collection implementation.
+ * rtti.c: New file with the RTTI stuff from gc.c.
+ * gc.c: Removed file (moved the remaining stuff into rtti.c).
+ * Makefile.in (CXX_OBJS): Replace gc.o with rtti.o.
+ (rtti.o): New rule, replacing gc.o.
+ * Make-lang.in (CXX_SRCS): Replace gc.c with rtti.c.
+ * cp-tree.h: Delete gc-related fn decls.
+ (DECL_GC_OFFSET): Delete macro.
+ (flag_gc): Delete extern decl.
+ * decl.c (current_function_obstack_index): Delete var decl.
+ (current_function_obstack_usage): Delete var decl.
+ (start_function): Delete clearing of current_function_obstack_index
+ and current_function_obstack_usage.
+ (init_decl_processing): Delete code relying on -fgc.
+ Delete call to init_gc_processing.
+ (cp_finish_decl): Delete calls to build_static_gc_entry and
+ type_needs_gc_entry. Delete gc code setting DECL_GC_OFFSET.
+ (store_parm_decls): Delete -fgc calls to cp_expand_decl_cleanup
+ and to expand_expr of a __gc_main call.
+ (maybe_gc_cleanup): Delete var decl.
+ (finish_function): Delete call to expand_gc_prologue_and_epilogue.
+ * decl2.c (flag_gc): Delete var decl.
+ (lang_f_options): Delete offering of -fgc.
+ (lang_decode_option): Delete -fgc and -fno-gc handling.
+ (get_temp_regvar): Delete gc code.
+ * init.c (build_new): Delete gc code.
+ * lex.c (init_lex): Delete checking of flag_gc.
+
+ * typeck.c (convert_arguments): Delete gc code.
+ (build_component_addr): Delete -fgc warning.
+ (build_modify_expr): Delete gc code.
+
+ * decl2.c (build_push_scope): Delete fn.
+ * cp-tree.h (build_push_scope): Delete decl.
+
+ * search.c (clear_search_slots): Delete fn.
+ * cp-tree.h (clear_search_slots): Delete decl.
+
+ * search.c (tree_needs_constructor_p): Delete fn.
+ * cp-tree.h (tree_needs_constructor_p): Delete decl.
+
+ * tree.c (id_cmp): Delete fn.
+
+ * tree.c (set_fnaddr_from_vtable_entry): Delete fn.
+ * cp-tree.h (set_fnaddr_from_vtable_entry): Delete decl.
+
+ * tree.c (decl_value_member): Delete fn.
+ * cp-tree.h (decl_value_member): Delete decl.
+
+ * tree.c (list_hash_lookup_or_cons): Delete fn.
+ * cp-tree.h (list_hash_lookup_or_cons): Delete decl.
+
+ * method.c (cplus_exception_name): Delete fn.
+ (EXCEPTION_NAME_{PREFIX, LENGTH}): Delete macros.
+
+ * spew.c (shift_tokens): Delete fn.
+
+Mon Jan 22 17:49:33 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (init_exception_processing): Pass 1 to needs_pop in calls
+ to cp_finish_decl.
+ * parse.y: Likewise.
+
+Mon Jan 22 17:34:29 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * tree.c (build_cplus_staticfn_type): Delete function definition;
+ never used.
+ * cp-tree.h (build_cplus_staticfn_type): Delete decl.
+
+ * tree.c (virtual_member): Delete function definition; never used.
+ * cp-tree.h (virtual_member): Delete decl.
+
+Fri Jan 19 18:03:14 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_component_ref): Handle getting vbase pointers
+ out of complex multiple inheritance better.
+
+Fri Jan 19 16:27:40 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_object_ref): Make sure we use the real type, not
+ any reference type.
+
+Fri Jan 19 16:01:47 1996 Mike Stump <mrs@cygnus.com>
+
+ * tree.c (build_exception_variant): Don't create new types if we
+ don't have to, also build new types on the right obstack.
+
+Fri Jan 19 14:09:44 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (store_bindings): Split out from push_to_top_level.
+ (push_to_top_level): Call it for b->type_shadowed on class binding
+ levels.
+
+Fri Jan 19 13:53:14 1996 Mike Stump <mrs@cygnus.com>
+
+ * search.c (expand_upcast_fixups): Fix so that offsets stored in
+ vbase_offsets are always right. Fixes a problem where virtual base
+ upcasting and downcasting could be wrong during conversions on this
+ during virtual function dispatch at ctor/dtor time when dynamic
+ vtable fixups for deltas are needed. This only sounds easier than
+ it is. :-)
+ (fixup_virtual_upcast_offsets): Change to reflect new calling
+ convention for expand_upcast_fixups.
+
+Fri Jan 19 12:23:08 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl2.c (grokbitfield): Strip the NOPs from WIDTH before we
+ check that it's usable as the bitfield width.
+
+Wed Jan 17 21:22:40 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl2.c (grokfield): Call cplus_decl_attributes with the attrlist.
+ Pass a null tree to grokdeclarator for its ATTRLIST arg, since it's
+ only ever used for functions in it.
+
+Wed Jan 17 12:10:38 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (qualified_type_name): Use the TYPE_DECL, not the type.
+ (nested_type): Likewise.
+ (nested_name_specifier): Use lastiddecl.
+
+ * decl.c (grokdeclarator): Adjust accordingly.
+ * init.c (expand_member_init): Likewise.
+ * parse.y (base_class): Likewise.
+ * typeck2.c (build_functional_cast): Likewise.
+
+ * typeck2.c (build_functional_cast): Fill in name after we've
+ checked for non-aggr type.
+
+Wed Jan 17 10:18:01 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (warn_pointer_arith): Default to on.
+
+Tue Jan 16 12:45:38 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (is_rid): New function.
+ * decl.c (grokdeclarator): Diagnose reserved words used as
+ declarator-ids.
+
+Tue Jan 16 11:39:40 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (get_decl_list): Don't lose cv-quals.
+
+ * decl.c (grokdeclarator): Fix SCOPE_REF handling and diagnose
+ typespecs used as declarator-ids.
+
+Tue Jan 16 11:09:42 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (poplevel): When popping a level, don't give a warning for
+ any subblocks that already exist.
+
+Tue Jan 16 00:25:33 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_object_ref): Finish what I started.
+
+ * parse.y (qualified_type_name): Don't check TYPE_BUILT_IN.
+
+ * decl2.c (constructor_name_full): Handle TEMPLATE_TYPE_PARMs.
+
+ * decl.c (grokdeclarator): Also accept TEMPLATE_TYPE_PARM as a
+ scope.
+
+Mon Jan 15 16:19:32 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (xref_tag): Handle passing a type in directly.
+
+ * parse.y (qualified_type_name): Pull out the type.
+ (nested_type): Likewise.
+ Take types directly instead of as identifiers.
+ * call.c (build_scoped_method_call): Take types directly instead of
+ as identifiers.
+ * decl.c (xref_basetypes): Likewise.
+ * init.c (expand_member_init): Likewise.
+ (build_member_call): Likewise.
+ (build_offset_ref): Likewise.
+ * typeck2.c (build_scoped_ref): Likewise, remove bogus code.
+ * method.c (do_build_assign_ref): Likewise.
+ * decl.c (grokdeclarator): Handle a type appearing as the
+ declarator-id for constructors.
+ * method.c (do_build_copy_constructor): current_base_init_list now
+ uses the types directly, not their names.
+ * init.c (sort_base_init): Likewise.
+ (expand_member_init): Likewise.
+ * init.c (is_aggr_type): New function, like is_aggr_typedef.
+
+Mon Jan 15 08:45:01 1996 Jeffrey A Law <law@cygnus.com>
+
+ * tree.c (layout_basetypes): Call build_lang_field_decl instead
+ of build_lang_decl if first arg is a FIELD_DECL.
+
+Thu Jan 11 14:55:07 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (cp_finish_decl): Only clear TREE_USED if DECL_NAME is
+ non-empty.
+ * except.c (expand_start_catch_block): Set TREE_USED to avoid
+ warnings about the catch handler.
+
+Mon Jan 8 17:35:12 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_modify_expr): Use a COMPOUND_EXPR instead of
+ expand_target_expr.
+
+Thu Jan 4 12:30:32 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ Fix access control to use trees rather than integers.
+ * class.c (access_{default, public, protected, private,
+ default_virtual, public_virtual, private_virtual}_node): Add
+ definitions.
+ (init_class_processing): Do creation of those nodes.
+ * cp-tree.h (access_type): Delete enum decl.
+ (access_{default, public, protected, private, default_virtual,
+ public_virtual, private_virtual}_node): Add decls.
+ (compute_access): Change return type.
+ * search.c (compute_access): Have tree return type, instead of enum.
+ (lookup_field): Declare THIS_V and NEW_V to be tree nodes.
+ * lex.c (real_yylex): Use yylval.ttype for giving the value of the
+ access_* node for each of RID_{PUBLIC, PRIVATE, PROTECTED}.
+ * parse.y (VISSPEC): Make ttype rather than itype.
+ (base_class_access_list): Likewise.
+ * *.[cy]: Change all refs of `access_public' to `access_public_node',
+ etc.
+ * call.c (build_method_call): Make ACCESS be a tree.
+ * class.c (alter_access, finish_struct_1, filter_struct): Likewise.
+ * cvt.c (convert_to_aggr): Likewise.
+ * init.c (build_offset_ref, resolve_offset_ref, build_delete):
+ Likewise.
+ * method.c (hack_identifier): Likewise.
+ * typeck.c (build_component_ref_1, build_component_ref): ): Likewise.
+
+Thu Jan 4 11:02:20 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (pointer_int_sum, pointer_diff): Make code agree with C
+ frontend, and make it more consistent with respect to
+ warn_pointer_arith.
+
+Tue Jan 2 00:13:38 1996 Rusty Russell <rusty@adelaide.maptek.com.au>
+
+ * decl.c (pushdecl): Check for duplicate parameter names.
+
+Wed Jan 3 09:25:48 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (expand_static_init): Call assemble_external for atexit.
+
+Wed Jan 3 07:55:19 1996 Mike Stump <mrs@cygnus.com>
+
+ * except.c (do_unwind): Remove some generated dead code.
+ (eh_outer_context): New routine, factor out some common code from
+ expand_builtin_throw and end_eh_unwinder. Add code to do return
+ address masking for the PA.
+ (expand_builtin_throw): Use eh_outer_context instead of open coding
+ it here.
+ (end_eh_unwinder): Likewise.
+
+Tue Jan 2 17:00:56 1996 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Call assemble_external for __empty, if we
+ use it.
+
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-1997 b/gcc-4.9/gcc/cp/ChangeLog-1997
new file mode 100644
index 000000000..2c34b8db4
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-1997
@@ -0,0 +1,2614 @@
+Mon Dec 22 11:36:27 1997 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (add_builtin_candidate): Add default case in enumeration
+ switch.
+ (build_new_op): Likewise.
+ (convert_like): Likewise.
+ * cvt.c (build_expr_type_conversion): Likewise.
+ * tree.c (real_lvalue_p): Likewise.
+ (lvalue_p): Likewise.
+ (cp_tree_equal): Likewise.
+ * typeck.c (comptypes): Likewise.
+ (build_component_ref): Likewise.
+ (build_function_call_real): Likewise.
+ (build_binary_op_nodefault): Likewise.
+ (build_unary_op): Likewise.
+ (build_modify_expr): Likewise.
+ * typeck2.c (initializer_constant_valid_p): Likewise.
+
+Sun Dec 21 15:59:00 1997 Nick Clifton <nickc@cygnus.com>
+
+ * decl2.c (lang_decode_option): Add support for -Wunknown-pragmas.
+
+Thu Dec 18 14:51:50 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (coerce_template_parms): Make sure to digest_init if
+ possible.
+
+ * decl.c (duplicate_decls): Make the newdecl virtual if the
+ olddecl was, just as is done with other attributes of olddecl.
+
+Thu Dec 18 14:43:19 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (unary_complex_lvalue): Ignore op0 when taking the
+ address of an OFFSET_REF.
+
+ * cp-tree.def: Add AGGR_INIT_EXPR.
+ * error.c, tree.c, typeck.c: Replace uses of NEW_EXPR with
+ AGGR_INIT_EXPR where appropriate.
+ * expr.c (cplus_expand_expr): Likewise. Simplify.
+
+ * decl2.c (finish_file): Remove call to register_exception_table.
+
+Wed Dec 17 17:08:52 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * pt.c (instantiate_class_template): Don't do injection when
+ processing_template_decl is true, as pollutes current_binding_level
+ for base classes.
+
+Wed Dec 17 21:17:39 1997 Peter Schmid <schmid@ltoi.iap.physik.tu-darmstadt.de>
+
+ * pt.c (maybe_fold_nontype_arg): Add prototype.
+
+Tue Dec 16 10:31:20 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (mapcar): Handle TRY_CATCH_EXPR et al.
+ * error.c (dump_expr): Likewise.
+
+Mon Dec 15 12:22:04 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_function_call_real): Remove "inline called before
+ definition" pedwarn.
+
+ * pt.c (coerce_template_parms): Use maybe_fold_nontype_arg.
+
+Sun Dec 14 22:34:20 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Fix base conversion of pm's.
+
+ * pt.c (type_unification_real): Change __null to type void* with
+ a warning.
+
+Sun Dec 14 20:38:35 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * call.c (implicit_conversion): Don't call
+ build_user_type_conversion_1 with a NULL expr, since it will
+ crash.
+
+ * pt.c (unify): Don't try to unify array bounds if either array is
+ unbounded.
+
+Fri Dec 12 16:09:14 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * errfn.c (cp_pedwarn, cp_pedwarn_at, cp_error_at, cp_warning_at):
+ Replace extern decls with casts.
+
+ * decl.c (expand_start_early_try_stmts): Don't mess with a sequence.
+ Update last_parm_cleanup_insn.
+ (store_after_parms): Remove.
+ * cp-tree.h: Adjust.
+
+Thu Dec 11 22:18:37 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (comdat_linkage): Also set DECL_COMDAT.
+ (finish_file): Check DECL_COMDAT instead of weak|one_only.
+ (import_export_vtable): Use make_decl_one_only instead of
+ comdat_linkage for win32 tweak.
+ (import_export_decl): Likewise.
+ * pt.c (mark_decl_instantiated): Likewise.
+
+ * decl2.c (finish_file): Lose handling of templates in pending_statics.
+
+Thu Dec 11 21:12:09 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Lose call to expand_builtin_throw.
+ * except.c (expand_builtin_throw): Remove.
+ * cp-tree.h: Remove ptr_ptr_type_node.
+ * decl.c: Likewise.
+
+Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
+
+ * decl.c (ptr_ptr_type_node): Define.
+ (init_decl_processing): Initialize it.
+ * cp-tree.h: Declare it.
+ * exception.cc (__cp_exception_info): Use __get_eh_info.
+ (__cp_push_exception): Likewise.
+ (__cp_pop_exception): Likewise.
+
+ From Scott Snyder <snyder@d0sgif.fnal.gov>:
+ * except.c (expand_builtin_throw): Use get_saved_pc_ref instead of
+ saved_pc.
+ (init_exception_processing): Removed saved_pc initialization.
+
+Wed Dec 10 11:04:45 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_decl): Defer all templates but inline functions.
+
+Mon Dec 8 23:17:13 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (expand_vec_init): Don't fold a list of parameters.
+
+ * decl.c (copy_args_p): Handle copy elision for types with virtual
+ bases.
+ * call.c (build_over_call): Likewise.
+
+Sun Dec 7 22:38:12 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (lookup_template_function): Copy the template arguments,
+ not just the list containing them, to the permanent obstack.
+
+Sun Dec 7 15:53:06 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (expand_start_catch_block): suspend_momentary for the
+ terminate handler.
+
+ * error.c (dump_decl): Handle LOOKUP_EXPR.
+
+Sun Dec 7 15:45:07 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * rtti.c (build_dynamic_cast): Copy the cast-to type to the
+ permanent obstack if we are processing a template decl.
+ * typeck.c (build_static_cast): Likewise.
+ (build_const_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+
+ * pt.c (coerce_template_parms): Coerce some expressions, even
+ when processing_template_decl.
+
+Sun Dec 7 01:46:33 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * typeck.c (build_binary_op_nodefault, pointer_diff): Symmetric
+ handling of pointer difference expressions.
+
+ * typeck.c (comp_target_types): Comparison of function/method types
+ is independent of nptrs.
+
+Sun Dec 7 01:40:27 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (tsubst): Avoid creating pointer to reference and
+ reference to reference types.
+
+Sat Dec 6 01:29:37 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (do_id): New nonterminal.
+ (template_id): Use it.
+
+Fri Dec 5 01:17:34 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (template_id): do_identifier for PFUNCNAMEs, too.
+ * spew.c (yylex): Don't do_identifier here.
+ * decl2.c (build_expr_from_tree): Revert last change.
+
+ * decl2.c (build_expr_from_tree): Expand the name for a method call.
+ * parse.y (object_template_id): Don't try to take the DECL_NAME.
+
+Wed Dec 3 20:02:39 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_new): Use a TARGET_EXPR instead of SAVE_EXPR for
+ alloc_expr.
+ * call.c (build_op_delete_call): Adjust.
+
+ * except.c (expand_end_catch_block): Lose rethrow region.
+ (expand_start_catch_block): Likewise.
+ (expand_end_catch_block): Don't expand_leftover_cleanups.
+
+Wed Dec 3 13:24:04 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * pt.c (tsubst): Remove tree_cons call (places redundant info into
+ DECL_TEMPLATE_INSTANTIATION).
+
+Wed Dec 3 11:44:52 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (is_overloaded_fn): Handle getting a fn template.
+ (really_overloaded_fn): Likewise.
+ * error.c (dump_decl): Handle TEMPLATE_ID_EXPRs better.
+ * pt.c (check_explicit_specialization): Tweak.
+ (determine_explicit_specialization): Tweak.
+
+ * tree.c, cp-tree.h (get_target_expr): New fn.
+
+Wed Dec 3 08:47:27 1997 Paul Eggert <eggert@twinsun.com>
+
+ * pt.c (check_explicit_specialization): Fix misspelling in
+ diagnostic: `preceeded'.
+ * typeck.c (get_delta_difference): Fix misspelling in diagnostic:
+ `conversiona'.
+
+1997-12-02 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (determine_explicit_specialization): Avoid an internal
+ error for bad specializations.
+
+ * method.c (build_overload_value): Handle SCOPE_REF.
+
+Tue Dec 2 19:18:50 1997 Mike Stump <mrs@wrs.com>
+
+ * class.c (prepare_fresh_vtable): Enable even more complex MI
+ vtable names.
+
+Tue Dec 2 01:37:19 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * exception.cc (__check_eh_spec): Optimize a bit.
+
+ * exception.cc (__cp_pop_exception): Lose handler arg.
+ * except.c (do_pop_exception): Likewise.
+ (push_eh_cleanup): Let the cleanup mechanism supply the handler.
+ (expand_end_catch_block): Likewise.
+
+Fri Nov 28 01:58:14 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (check_explicit_specialization): Complain about using a
+ template-id for a non-specialization.
+
+Fri Nov 28 12:35:19 1997 Scott Christley <scottc@net-community.com>
+
+ * repo.c: Prototype rindex only if needed.
+ * xref.c: Likewise.
+
+Fri Nov 28 01:56:35 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * error.c (dump_decl): Handle TEMPLATE_ID_EXPR.
+
+Thu Nov 27 00:59:46 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_const_cast): Handle references here instead of
+ handing off to convert_to_reference.
+
+ * except.c: Lose Unexpected, SetTerminate, SetUnexpected,
+ TerminateFunctionCall.
+ (init_exception_processing): Likewise. Terminate et al are now
+ the fns, not ADDR_EXPRs.
+ (various): Lose redundant assemble_external calls.
+ (do_unwind): s/BuiltinReturnAddress/builtin_return_address_fndecl/.
+
+ * cp-tree.h (struct lang_decl_flags): Add comdat.
+ (DECL_COMDAT): New macro.
+ * decl.c (duplicate_decls): Propagate it.
+ (cp_finish_decl): Handle it.
+ * decl2.c (import_export_decl): Just set DECL_COMDAT on VAR_DECLs.
+
+ * class.c: Remove static pending_hard_virtuals.
+ (add_virtual_function): Take pointers to pending_virtuals
+ and pending_hard_virtuals.
+ (finish_struct_1): Pass them. Declare pending_hard_virtuals.
+
+Wed Nov 26 20:28:49 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (import_export_vtable): If we support one_only but not
+ weak symbols, mark instantiated template vtables one_only.
+ (import_export_decl): Likewise for tinfo functions.
+ (finish_vtable_vardecl): Also write out vtables from explicitly
+ instantiated template classes.
+ * pt.c (mark_class_instantiated): Revert last change.
+
+ * except.c (expand_throw): Call mark_used on the destructor.
+
+Wed Nov 26 15:13:48 1997 Jeffrey A Law (law@cygnus.com)
+
+ * lex.c (lang_init): Enable flag_exceptions by default if no
+ command line switch was specified.
+
+1997-11-26 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (unify): Handle `void' template parameters in
+ specializations.
+
+Wed Nov 26 01:11:24 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (build_dynamic_cast): Handle template case here.
+ (build_dynamic_cast_1): Not here.
+
+ * typeck2.c (digest_init): Make copies where appropriate.
+
+ * decl2.c (delete_sanity): resolve_offset_ref.
+
+ * except.c: Call terminate without caching so many bits.
+
+ * except.c (expand_start_catch_block): Fix catching a reference
+ to pointer.
+
+Tue Nov 25 11:28:21 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_new): Copy size to the saveable obstack.
+
+ * init.c (build_new): Stick a CLEANUP_POINT_EXPR inside the
+ TRY_CATCH_EXPR for now.
+
+Mon Nov 24 12:15:55 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (mark_addressable): Don't assume a FUNCTION_DECL
+ has DECL_LANG_SPECIFIC.
+
+ * exception.cc (struct cp_eh_info): Add handlers field.
+ (__cp_push_exception): Initialize it.
+ (__cp_pop_exception): Decrement it. Don't pop unless it's 0.
+ (__throw_bad_exception): Remove.
+ * except.c (call_eh_info): Add handlers field.
+ (get_eh_handlers): New fn.
+ (push_eh_cleanup): Increment handlers.
+
+Fri Nov 21 12:22:07 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (expand_start_eh_spec): Use the try/catch code.
+ (expand_end_eh_spec): Likewise. Call __check_eh_spec instead of
+ doing everything inline.
+ (init_exception_processing): throw_type_match now takes
+ const void pointers.
+ * exception.cc (__check_eh_spec): New fn.
+ * inc/exception: Neither terminate nor unexpected return.
+ * decl.c: Make const_ptr_type_node public.
+ * tinfo2.cc (__throw_type_match_rtti): Take the typeinfos constly.
+
+ * except.c (expand_start_catch_block): We only need the rethrow
+ region for non-sjlj exceptions.
+ (expand_end_catch_block): Likewise. Use outer_context_label_stack.
+
+Thu Nov 20 14:40:17 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Make-lang.in (CXX_LIB2FUNCS): Add new op new and op delete objs.
+ (various.o): Likewise.
+ * inc/new: Add placement deletes. Add throw specs for default new.
+ * new.cc (set_new_handler): Move here from libgcc2.
+ * new1.cc (new (nothrow)): Catch a bad_alloc thrown from the handler.
+ (new): Move from libgcc2. Throw bad_alloc.
+ * new2.cc: Move the rest of the op news and op deletes from libgcc2.
+ * decl.c (init_decl_processing): Update exception specs on new and
+ delete.
+
+ * method.c (build_decl_overload_real): Don't mess with global
+ placement delete.
+
+ * init.c (build_new): Check for null throw spec, not nothrow_t.
+
+ * decl.c (duplicate_decls): Don't complain about different exceptions
+ from an internal declaration.
+
+ * call.c (build_op_delete_call): Fix check for member fns again.
+
+ * decl2.c (import_export_decl): Interface hackery affects
+ virtual synthesized methods.
+
+Wed Nov 19 18:24:14 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_decl): Don't just complain about a mismatched
+ scope, fix it.
+
+ * decl.c (make_implicit_typename): Handle case where t is not
+ actually from context.
+ * tree.c (get_type_decl): Lose identifier case.
+ * spew.c (yylex): Lose useless call to identifier_typedecl_value.
+ * parse.y (nonnested_type): Just use lookup_name.
+ (complex_type_name): Just use IDENTIFIER_GLOBAL_VALUE.
+
+Wed Nov 19 11:45:07 1997 Michael Tiemann <tiemann@axon.cygnus.com>
+
+ * error.c (dump_function_name): Test DECL_LANG_SPECIFIC in case
+ T was built in C language context (for example, by
+ output_func_start_profiler).
+
+Wed Nov 19 10:39:27 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (make_implicit_typename): New fn.
+ (lookup_name_real): Use it. Use current_class_type as the context.
+
+Mon Nov 17 23:42:03 1997 Bruno Haible <haible@ilog.fr>
+
+ * pt.c (do_poplevel): Don't prohibit jumps into this contour.
+
+Mon Nov 17 02:01:28 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * friend.c (do_friend): Warn about non-template friends in templates.
+
+ * call.c (build_op_delete_call): Fix handling of inherited delete.
+
+ * search.c (dfs_record_inheritance): Ignore template type parms.
+
+Sat Nov 15 00:30:51 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_new_op): Fix copy error.
+ (build_op_new_call): New fn.
+ (build_op_delete_call): New fn.
+ * cp-tree.h: Declare them.
+ * init.c (build_new): Use them. Support placement delete.
+ (build_x_delete): Use build_op_delete_call.
+ (build_delete): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+ (coerce_delete_type): Don't complain about placement delete.
+
+Thu Nov 13 01:52:36 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_new_function_call): Remove unused 'obj' parm.
+ * cp-tree.h, typeck.c: Adjust.
+
+ * init.c (build_new): Make the cleanup last longer.
+ (expand_vec_init): Call do_pending_stack_adjust.
+
+Wed Nov 12 11:04:33 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (do_type_instantiation): Fix typo.
+ (mark_class_instantiated): If we support one_only but not weak
+ symbols, don't mark this as known.
+
+ * init.c (build_new): Handle vec delete in EH cleanup.
+
+Wed Nov 12 08:11:55 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * call.c (build_method_call): Call complete_type before checking
+ for destructor.
+
+Sun Nov 9 01:29:55 1997 Jim Wilson (wilson@cygnus.com)
+
+ * decl.c (add_block_current_level): Delete.
+ * init.c (build_vec_delete_1): Delete build_block and
+ add_block_current_level calls.
+
+Wed Nov 12 00:48:16 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_new): Handle freeing allocated memory when the
+ constructor throws.
+
+ * call.c (build_new_method_call): Fix flags arg.
+
+ * pt.c (do_type_instantiation): Don't try to instantiate
+ member templates.
+ (mark_decl_instantiated): If we support one_only but not
+ weak symbols, mark this one_only.
+ * decl2.c (import_export_vtable): Don't defer handling of vtables
+ if MULTIPLE_SYMBOL_SPACES.
+
+Tue Nov 11 12:02:12 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (expand_end_catch_block): Lose call to __sjpopnthrow.
+
+Tue Nov 11 02:53:44 1997 Jason Merrill <jason@lasher.cygnus.com>
+
+ * except.c (do_pop_exception): Return a value.
+
+Mon Nov 10 20:25:31 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_new_method_call): Handle getting a
+ TEMPLATE_ID_EXPR around a TEMPLATE_DECL. Don't look for a field
+ if we got template parms.
+ * typeck.c (build_x_function_call): Remember the TEMPLATE_ID_EXPR,
+ not just the args.
+ * decl2.c (build_expr_from_tree): Tweak last change.
+ * pt.c (tsubst_copy): Use get_first_fn instead of TREE_VALUE.
+ (maybe_fold_nontype_arg): Split out from tsubst_copy.
+ * tree.c (get_first_fn): Just return a TEMPLATE_ID_EXPR.
+
+Mon Nov 10 20:08:38 1997 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * pt.c (tsubst_copy): Handle explicit template arguments in
+ function calls.
+ * typeck.c (build_x_function_call): Likewise.
+ * decl2.c (build_expr_from_tree): Lookup function name if it
+ hasn't been done.
+
+ * pt.c (tsubst): Instantiate template functions properly when
+ template parameter does not appear in function arguments and return
+ type.
+ (comp_template_args): Handle member templates required by tsubst.
+
+Mon Nov 10 20:08:38 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Tweak conditions for pedwarn in
+ previous change.
+
+Mon Nov 10 20:08:29 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * pt.c (coerce_template_parms): Tweak error message.
+
+ * decl.c (grokdeclarator): If -Wreturn-type, warn everytime a
+ return type defaults to `int', even if there are storage-class
+ specifiers.
+
+Mon Nov 10 03:04:20 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ Complete nested exception support.
+ * except.c (do_pop_exception): Split out...
+ (push_eh_cleanup): From here. Handle the EH region by hand.
+ (expand_start_catch_block): Add a new level for the catch parm.
+ Move the rethrow region outside the two cleanup regions.
+ Protect the initializer for the catch parm with terminate.
+ (expand_end_catch_block): Likewise. End the region for the eh_cleanup.
+ * exception.cc (__cp_pop_exception): Now takes two parms. Handle
+ popping off the middle of the stack.
+ * tree.c (lvalue_p, real_lvalue_p): Handle TRY_CATCH_EXPR,
+ WITH_CLEANUP_EXPR, and UNSAVE_EXPR.
+ (build_cplus_new): Only wrap CALL_EXPRs.
+ * init.c (expand_default_init): Handle a TRY_CATCH_EXPR around
+ the constructor call.
+
+Sun Nov 9 18:00:26 1997 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (c++.distdir): Make inc subdirectory.
+
+Fri Nov 7 11:57:28 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Put back some code.
+
+Thu Nov 6 11:28:14 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Remove redundant code.
+ * method.c (emit_thunk): Don't let the backend defer generic thunks.
+
+Wed Nov 5 23:52:50 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (call_eh_info): Split out...
+ (push_eh_info): From here.
+ (expand_builtin_throw): Use it.
+ (expand_start_catch_block): Move region start back.
+
+Tue Nov 4 13:45:10 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * lex.c (MULTIBYTE_CHARS): #undef if cross compiling.
+ (real_yylex): Record wide strings using target endianness, not host.
+
+1997-11-03 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * repo.c (rindex): Add decl unconditionally.
+ (get_base_filename, open_repo_file): Don't cast rindex.
+ * xref.c (rindex): Add decl unconditionally.
+ (index): Remove unused decl.
+ (open_xref_file): Don't cast rindex.
+
+Sun Nov 2 15:04:12 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (build_vbase_path): Propagate the result type properly.
+
+1997-11-01 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * except.c (expand_builtin_throw) [!DWARF2_UNWIND_INFO]: Replace
+ remaining use of saved_throw_type with a call to get_eh_type.
+
+1997-10-31 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lex.c (FILE_NAME_NONDIRECTORY): Delete macro.
+ (file_name_nondirectory): New function, doing the same as the macro.
+ (set_typedecl_interface_info): Use it instead of the macro.
+ (check_newline): Likewise.
+ (handle_cp_pragma): Likewise.
+
+ * repo.c (get_base_filename): Cast result of rindex to char*.
+ (open_repo_file): Likewise.
+ * xref.c (open_xref_file): Likewise.
+ * error.c (dump_char): Make its arg int, not char.
+
+ * except.c (push_eh_info): Pass the number of fields - 1 down, not
+ the exact number of fields.
+
+Fri Oct 31 01:47:57 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ Support for nested exceptions.
+ * tinfo2.cc (__is_pointer): New fn.
+ * exception.cc (struct cp_eh_info): Define.
+ (__cp_exception_info, __uncatch_exception): New fns.
+ (__cp_push_exception, __cp_pop_exception): New fns.
+ * except.c: Lose saved_throw_{type,value,cleanup,in_catch}.
+ Lose empty_fndecl.
+ (init_exception_processing): Likewise. __eh_pc is now external.
+ (push_eh_info): New fn.
+ (get_eh_{info,value,type,caught}): New fns.
+ (push_eh_cleanup): Just call __cp_pop_exception.
+ (expand_start_catch_block): Use push_eh_info. Start the eh region
+ sooner.
+ (expand_end_eh_spec): Use push_eh_info.
+ (expand_throw): Call __cp_push_exception to set up the exception info.
+ Just pass the destructor or 0 as the cleanup. Call __uncatch_exception
+ when we rethrow.
+ (expand_builtin_throw): Don't refer to empty_fndecl.
+
+Thu Oct 23 02:01:30 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_decl): SET_DECL_IMPLICIT_INSTANTIATION on new decl.
+
+1997-10-22 Brendan Kehoe <brendan@cygnus.com>
+
+ * method.c (build_template_parm_names, build_decl_overload_real):
+ Add static to definitions.
+ * pt.c (add_to_template_args, note_template_header,
+ processing_explicit_specialization, type_unification_real): Likewise.
+ ({determine,check}_explicit_specialization): Use a single string for
+ error messages.
+
+Mon Oct 20 12:06:34 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (expand_exception_blocks): Call do_pending_stack_adjust.
+ (expand_end_catch_block): Likewise.
+ (expand_end_eh_spec): Likewise.
+
+Mon Oct 20 11:44:20 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * decl.c (duplicate_decls): Handle template specializations
+ correctly.
+ * error.c (dump_function_name): Fix printing of specializations of
+ member functions that are not member templates.
+ * cp-tree.h (processing_specialization): Make global.
+ * pt.c (processing_specialization): Likewise.
+ * lex.c (cons_up_default_function): Save and restore
+ processing_specialization to avoid confusion.
+
+Mon Oct 20 10:52:22 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (init_decl_processing): Give null_node unknown* type.
+ * typeck.c (comp_target_types): Handle UNKNOWN_TYPE.
+ (common_type): Likewise.
+ * error.c (args_as_string): Recognize null_node.
+
+Sun Oct 19 09:13:01 1997 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * typeck.c (rationalize_conditional_expr): Handle {MIN,MAX}_EXPR.
+ (unary_complex_lvalue): Call it for {MIN,MAX}_EXPR.
+
+ * decl.c (init_decl_processing): Call using_eh_for_cleanups.
+
+ * Make-lang.in (g++): Include prefix.o.
+
+Thu Oct 16 15:31:09 1997 Judy Goldberg <judygold@sanwafp.com>
+
+ * pt.c (determine_explicit_specialization): Initialize "dummy"
+ to keep Purify quiet.
+
+Thu Oct 16 00:14:48 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (build_overload_value): Handle TEMPLATE_CONST_PARMs here.
+ (build_overload_int): Not here.
+
+Wed Oct 15 00:35:28 1997 Mike Stump <mrs@wrs.com>
+
+ * class.c (build_type_pathname): Remove.
+ (prepare_fresh_vtable): Fix problem with complex MI vtable names.
+
+1997-10-14 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (unary_expr): Give a pedwarn if someone tries to use the
+ &&label GNU extension.
+
+Tue Oct 14 12:01:00 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * decl.c (pushtag): Unset DECL_ASSEMBLER_NAME before setting it,
+ so as to avoid incorrect manglings.
+ * method.c (build_decl_overload_real): Don't mangle return types
+ for constructors.
+
+Tue Oct 14 11:46:14 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (scratchalloc, build_scratch_list, make_scratch_vec,
+ scratch_tree_cons): Define as macros for now.
+ * call.c, class.c, cvt.c, decl.c, decl2.c, except.c, expr.c, init.c,
+ lex.c, method.c, parse.y, pt.c, rtti.c, search.c, tree.c, typeck.c,
+ typeck2.c: Use them and the expression_obstack variants.
+
+Mon Oct 13 17:41:26 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * decl.c (store_return_init): Allow classes with explicit ctors to
+ be used with the named return values extension.
+
+Fri Oct 10 12:21:11 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_decl): Fix previous change.
+
+Thu Oct 9 12:08:21 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Fix thinko.
+ (instantiate_decl): Really use the original template.
+
+ * call.c (build_new_method_call): Use simple constructor_name for
+ error messages.
+
+Wed Oct 8 22:44:42 1997 Jeffrey A Law <law@cygnus.com>
+
+ * method.c (build_underscore_int): Don't use ANSI specific
+ features.
+
+Wed Oct 8 00:18:22 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_prevtable_vardecl): Check DECL_REALLY_EXTERN
+ for our key method; it might have been inlined by -O3.
+
+Tue Oct 7 23:00:12 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * decl.c (make_typename_type): Do not try to call lookup_field for
+ non-aggregate types.
+
+Tue Oct 7 22:52:10 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_reinterpret_cast): Tweak.
+
+Tue Oct 7 22:45:31 1997 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * typeck.c (build_reinterpret_cast): Converting a void pointer
+ to function pointer with a reinterpret_cast produces a warning
+ if -pedantic is issued.
+
+Tue Oct 7 22:43:43 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * typeck.c (c_expand_return): Don't warn about returning a
+ reference-type variable as a reference.
+
+Tue Oct 7 21:11:22 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (build_static_name): Fix typo.
+
+1997-10-07 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (duplicate_decls): Make sure DECL_LANG_SPECIFIC is set on
+ OLDDECL before we try to do DECL_USE_TEMPLATE.
+
+Tue Oct 7 00:48:36 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (duplicate_decls): Don't warn about template instances.
+
+ * typeck.c (mark_addressable): Lose ancient code that unsets
+ DECL_EXTERNAL.
+
+ * pt.c (do_decl_instantiation): Lose support for instantiating
+ non-templates.
+
+ * call.c (build_new_function_call): Fix handling of null explicit
+ template args.
+ (build_new_method_call): Likewise.
+
+Mon Oct 6 23:44:34 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * method.c (build_underscore_int): Fix typo.
+
+1997-10-06 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * tree.c (print_lang_statistics): #if 0 call to
+ print_inline_obstack_statistics until its definition is checked in.
+
+Mon Oct 6 09:27:29 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Move dump_tree_statistics to end.
+
+ * pt.c (instantiate_decl): Look for the original template.
+ (tsubst): Set DECL_IMPLICIT_INSTANTIATION on partial instantiations
+ of member templates.
+
+Wed Oct 1 08:41:38 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (g++FAQ.*): New rules.
+ (CONFLICTS): Update.
+ * g++FAQ.texi: Moved from libg++.
+
+ * parse.y (PFUNCNAME): Only specify the type once.
+
+1997-10-01 Brendan Kehoe <brendan@lasher.cygnus.com>
+
+ * lex.c (real_yylex): Clean up the code to fully behave the way
+ the c-lex.c parser does for complex and real numbers.
+
+Tue Sep 30 08:51:36 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (build_decl_overload_real): Reformat.
+
+Tue Sep 30 00:18:26 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (synthesize_method): If at_eof, determine our linkage.
+
+1997-09-29 Paul Eggert <eggert@twinsun.com>
+
+ * lex.c (real_yylex): Treat `$' just like `_', except issue a
+ diagnostic if !dollars_in_ident or if pedantic.
+
+ * lang-specs.h (@c++): -ansi no longer implies -$.
+
+ * decl2.c (lang_decode_option):
+ -traditional and -ansi now do not mess with
+ dollars_in_ident.
+
+Mon Sep 29 19:57:51 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * Makefile.in (parse.o, decl.o): Also depend on
+ $(srcdir)/../except.h $(srcdir)/../output.h.
+ (decl2.o): Also depend on $(srcdir)/../expr.h ../insn-codes.h
+ $(srcdir)/../except.h $(srcdir)/../output.h.
+ (typeck.o, init.o): Also depend on $(srcdir)/../expr.h
+ ../insn-codes.h.
+
+ * call.c, cp-tree.h, decl.c, tree.c: Finish prototyping.
+
+ * expr.c (cplus_expand_expr): Make it static.
+
+ * decl2.c, init.c, typeck.c: Include "expr.h".
+ (expand_expr): Use proper values when calling the function.
+
+Mon Sep 29 11:05:54 1997 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * lang-options.h: New -Wold-style-cast flag.
+ * cp-tree.h (warn_old_style_cast): New variable.
+ * decl2.c (warn_old_style_cast): Likewise.
+ (lang_decode_option): Support -Wold-style-cast.
+ (reparse_absdcl_as_casts): Produce old-style-cast warning.
+
+Mon Sep 29 09:20:53 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * decl.c (cp_finish_decl): Allow expand_aggr_init to set
+ TREE_USED, reset value based on already_used.
+
+ * init.c (expand_member_init): Revert change.
+
+Mon Sep 29 08:57:53 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h, decl.c, decl2.c, pt.c:
+ Lose DECL_C_STATIC and DECL_PUBLIC. Don't pretend statics are public.
+
+ * decl2.c (lang_decode_option): Add missing ;.
+
+Sat Sep 27 16:22:48 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * friend.c (do_friend): Disable injection for all template-derived
+ decls.
+ * decl2.c (lang_decode_option): Handle -fguiding-decls.
+ * parse.y (notype_template_declarator): New nonterminal.
+ (direct_notype_declarator): Use it.
+ (complex_direct_notype_declarator): Likewise.
+ (object_template_id): Accept any kind of identifier after TEMPLATE.
+ (notype_qualified_id): Don't add template declarators here.
+
+Sat Sep 27 16:21:58 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * call.c (add_template_candidate): Add explicit_targs parameter.
+ (build_scoped_method_call): Use it.
+ (build_overload_call_real): Likewise.
+ (build_user_type_conversion_1): Likewise.
+ (build_new_function_call): Likewise.
+ (build_object_call): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+ (build_new_function_call): Handle TEMPLATE_ID_EXPR.
+ (build_new_method_call): Likewise.
+
+ * class.c (finish_struct_methods): Add specialization pass to
+ determine which methods were specializing which other methods.
+ (instantiate_type): Handle TEMPLATE_ID_EXPR.
+
+ * cp-tree.def (TEMPLATE_ID_EXPR): New tree code.
+
+ * cp-tree.h (name_mangling_version): New variable.
+ (flag_guiding_decls): Likewise.
+ (build_template_decl_overload): New function.
+ (begin_specialization): Likewise.
+ (reset_specialization): Likewise.
+ (end_specialization): Likewise.
+ (determine_explicit_specialization): Likewise.
+ (check_explicit_specialization): Likewise.
+ (lookup_template_function): Likewise.
+ (fn_type_unification): Add explicit_targs parameter.
+ (type_unification): Likewise.
+
+ * decl.c (duplicate_decls): Add smarts for explicit
+ specializations.
+ (grokdeclarator): Handle TEMPLATE_ID_EXPR, and function
+ specializations.
+ (grokfndecl): Call check_explicit_specialization.
+
+ * decl2.c (lang_decode_option): Handle -fname-mangling-version.
+ (build_expr_from_tree): Handle TEMPLATE_ID_EXPR.
+ (check_classfn): Handle specializations.
+
+ * error.c (dump_function_name): Print specialization arguments.
+
+ * friend.c (do_friend): Don't call pushdecl for template
+ instantiations.
+
+ * init.c (build_member_call): Handle TEMPLATE_ID_EXPR.
+
+ * lang-options.h: Add -fname-mangling-version, -fguiding-decls,
+ and -fno-guiding-decls.
+
+ * lex.c (identifier_type): Return PFUNCNAME for template function
+ names.
+
+ * method.c (build_decl_overload_real): New function.
+ (build_template_parm_names): New function.
+ (build_overload_identifier): Use it.
+ (build_underscore_int): New function.
+ (build_overload_int): Use it. Add levels for template
+ parameters.
+ (build_overload_name): Likewise. Also, handle TYPENAME_TYPEs.
+ (build_overload_nested_names): Handle template type parameters.
+ (build_template_decl_overload): New function.
+
+ * parse.y (YYSTYPE): New ntype member.
+ (nested_name_specifier): Use it.
+ (nested_name_specifier_1): Likewise.
+ (PFUNCNAME): New token.
+ (template_id, object_template_id): New non-terminals.
+ (template_parm_list): Note specializations.
+ (template_def): Likewise.
+ (structsp): Likewise.
+ (fn.def2): Handle member template specializations.
+ (component_decl_1): Likewise.
+ (direct_notype_declarator): Handle template-ids.
+ (component_decl_1): Likewise.
+ (direct_notype_declarator): Handle template-ids.
+ (primary): Handle TEMPLATE_ID_EXPR, and template-ids.
+
+ * pt.c (processing_specializations): New variable.
+ (template_header_count): Likewise.
+ (type_unification_real): New function.
+ (processing_explicit_specialization): Likewise.
+ (note_template_header): Likewise.
+ (is_member_template): Handle specializations.
+ (end_template_decl): Call reset_specialization.
+ (push_template_decl): Handle member template specializations.
+ (tsubst): Likewise.
+ (tsubst_copy): Handle TEMPLATE_ID_EXPR.
+ (instantiate_template): Handle specializations.
+ (instantiate_decl): Likewise.
+ (fn_type_unification): Handle explicit_targs.
+ (type_unification): Likewise. Allow incomplete unification
+ without an error message, if allow_incomplete.
+ (get_bindings): Use new calling sequence for fn_type_unification.
+
+ * spew.c (yylex): Handle PFUNCNAME.
+
+ * tree.c (is_overloaded_fn): Handle TEMPLATE_ID_EXPR.
+ (really_overloaded_fn): Likewise.
+ (get_first_fn): Handle function templates.
+
+ * typeck.c (build_x_function_call): Use really_overloaded_fn.
+ Handle TEMPLATE_ID_EXPR.
+ (build_x_unary_op): Likewise.
+ (build_unary_op): Likewise.
+ (mark_addressable): Templates whose address is taken are marked
+ as used.
+
+1997-09-25 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * decl.c (init_decl_processing): Declare __builtin_constant_p as
+ accepting any kind of type, not only int.
+
+Fri Sep 26 00:22:56 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (get_matching_virtual): Notice virtual bases when sorrying
+ about covariant returns.
+
+ * parse.y (member_init): Also imply typename here. Remove ancient
+ extension for initializing base members.
+
+Thu Sep 25 11:11:13 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ Handle multi-level typenames and implicit typename in base list.
+ * parse.y (typename_sub{,[0-2]}): New rules.
+ (structsp, rule TYPENAME_KEYWORD): Use typename_sub.
+ (nonnested_type): New rule.
+ (complete_type_name): Use it.
+ (base_class.1): Use typename_sub and nonnested_type.
+ (nested_name_specifier): Don't elide std:: here.
+ * decl.c (make_typename_type): Handle getting a type for NAME.
+ (lookup_name_real): Turn std:: into :: here.
+
+ Rvalue conversions were removed in London.
+ * call.c (is_subseq): Don't consider lvalue transformations.
+ (build_conv): LVALUE_CONV and RVALUE_CONV get IDENTITY_RANK.
+ (joust): Re-enable ?: kludge.
+
+1997-09-22 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (start_function): Up warning of no return type to be a
+ pedwarn.
+
+Mon Sep 22 14:15:34 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * init.c (expand_member_init): Don't set TREE_USED.
+ * decl.c (cp_finish_decl): Mark decls used if type has TREE_USED
+ set,don't clear TREE_USED wholesale.
+
+Sat Sep 20 15:31:00 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): Do require_complete_type before
+ build_cplus_new.
+
+Thu Sep 18 16:47:52 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (lookup_field): Call complete_type in all cases.
+
+ * decl.c (finish_function): Just warn about flowing off the end.
+
+Wed Sep 17 10:31:25 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokparms): Don't bash a permanent list node if we're
+ in a function.
+
+1997-09-17 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Makefile.in (CONFLICTS): Fix s/r conflict count to 18.
+
+Tue Sep 16 14:06:56 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_new_op): Give better error for syntactically
+ correct, but semantically invalid, use of undeclared template.
+
+ * call.c (compare_qual): Handle pmfs.
+
+ * decl.c (store_parm_decls): last_parm_cleanup_insn is the insn
+ after the exception spec.
+
+Mon Sep 15 11:52:13 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (null_ptr_cst_p): Integer type, not integral type.
+
+ * call.c (joust): Disable warnings until they can be moved to the
+ right place.
+
+Fri Sep 12 16:11:13 1997 Per Bothner <bothner@cygnus.com>
+
+ * Makefile.in, config-lang.in: Convert to autoconf.
+
+Thu Sep 11 17:14:55 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_name_real): Add implicit 'typename' to types from
+ base classes.
+
+ * pt.c (most_specialized_class): Fix typo.
+ (tsubst): Move constant folding to TREE_VEC case.
+
+Thu Sep 11 10:08:45 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (do_poplevel): Don't warn about unused local variables
+ while processing_template_decl since we don't always know whether
+ or not they will need constructing/destructing.
+
+ * pt.c (uses_template_parms): Check the values of an enumeration
+ type to make sure they don't depend on template parms.
+
+ * decl.c (make_typename_type): Don't lookup the field if the
+ context uses template parms, even if we're not
+ processing_template_decl at the moment.
+
+ * pt.c (coerce_template_parms): Avoid looking at the
+ TYPE_LANG_DECL portion of a typename type, since there won't be
+ one.
+ (tsubst): Do constant folding as necessary to make sure that
+ arguments passed to lookup_template_class really are constants.
+
+Wed Sep 10 16:39:26 1997 Jim Wilson <wilson@cygnus.com>
+
+ * Make-lang.in (LN, LN_S): New macros, use where appropriate.
+
+Wed Sep 10 11:21:55 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (expand_builtin_throw): #ifndef DWARF2_UNWIND_INFO.
+ * decl2.c (finish_file): Only register exception tables if we
+ need to.
+
+ * decl.c (init_decl_processing): Add __builtin_[fs]p.
+
+Tue Sep 9 19:49:38 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (unify): Just return 0 for a TYPENAME_TYPE.
+
+Tue Sep 9 17:57:25 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * error.c (dump_decl): Avoid crashing when presented with a
+ uninitialized constant, as can occur with a template parameter.
+ (dump_expr): Make sure that there are enough levels of
+ current_template_parms before we start diving through them.
+
+1997-09-09 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (build_indirect_ref): Heed FLAG_VOLATILE similar to
+ c-typeck.c.
+
+Tue Sep 9 09:36:39 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * except.c (expand_throw): Call build_delete for all
+ exception types, not just objects with destructors.
+
+Mon Sep 8 02:33:20 1997 Jody Goldberg <jodyg@idt.net>
+
+ * decl.c (current_local_enum): Remove static.
+ * pt.c (tsubst_enum): Save and restore value of current_local_enum
+ in case template is expanded in enum decl.
+ (instantiate_class_template): Use new tsubst_enum signature.
+ (tsubst_expr): Likewise.
+
+Mon Sep 8 01:21:43 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (begin_member_template_processing): Take a function as
+ argument, not a set of template arguments. Use the template
+ parameters, rather than the arguments. Handle non-type parameters
+ correctly. Push a binding level for the parameters so that multiple
+ member templates using the same parameter names can be declared.
+ (end_member_template_processing): Pop the binding level.
+ (push_template_decl): Mark member templates as static when
+ appropriate.
+
+ * lex.c (do_pending_inlines): Pass the function, not its template
+ arguments, to begin_member_template_processing.
+ (process_next_inline): Likewise.
+ (do_pending_defargs): Likewise.
+
+ * error.c (dump_expr): Obtain the correct declaration for a
+ TEMPLATE_CONST_PARM.
+
+ * call.c (add_template_conv_candidate): New function.
+ (build_object_call): Handle member templates, as done in the other
+ build_ functions.
+
+Sat Sep 6 10:20:27 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * decl.c (replace_defag): Undo previous change.
+ * lex.c (do_pending_defargs): Deal with member templates.
+
+ * pt.c (is_member_template): Avoid crashing when passed a
+ non-function argument.
+
+Fri Sep 5 17:27:38 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (grow_method): Remove check for redeclaration.
+
+Fri Sep 5 01:37:17 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * cp-tree.h (INNERMOST_TEMPLATE_PARMS): New macro.
+ (DECL_INNERMOST_TEMPLATE_PARMS): Likewise.
+ (PRIMARY_TEMPLATE_P): Use it.
+ * call.c (build_overload_call_real): Use it.
+ * class.c (instantiate_type): Likewise.
+ * decl.c (decls_match): Likewise.
+ * method.c (build_overload_identifier): Likewise.
+ * pt.c (push_template_decl): Likewise.
+ (classtype_mangled_name): Likewise.
+ (lookup_template_class): Likewise.
+
+ * cp-tree.h (DECL_NTPARMS): Change name from DECL_NT_PARMS to
+ DECL_NTPARMS to conform to usage elsewhere.
+ * call.c (add_template_candidate): Likewise.
+ * class.c (instantiate_type): Likewise.
+ * pt.c (instantiate_template): Likewise.
+ (get_bindings): Likewise.
+
+ * class.c (grow_method): Use DECL_FUNCTION_TEMPLATE_P instead of
+ is_member_template.
+
+ * pt.c (unify): Undo changes to allow multiple levels of template
+ parameters.
+ (type_unification): Likewise.
+ (fn_type_unification): Likewise.
+ (get_class_bindings): Likewise.
+ * cp-tree.h (Likewise).
+
+ * decl.c (replace_defarg): Check that the type of the default
+ parameter does not invlove a template type before complaining
+ about the initialization.
+
+ * error.c (dump_expr): Deal with template constant parameters in
+ member templates correctly.
+
+ * pt.c (is_member_template): Deal with class specializations
+ correctly.
+ (tsubst): Handle "partial instantiation" of member templates
+ correctly.
+
+Wed Sep 3 12:30:24 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (type_unification): Change calling sequence to allow for
+ multiple levels of template parameters.
+ (tsubst_expr): Likewise.
+ (tsubst): Likewise.
+ (tsubst_copy): Likewise.
+ (instantiate_template): Likewise.
+ (unify): Likewise.
+ * call.c (build_overload_call_real): Use it.
+ (add_builtin_candidate): Use it.
+ (build_new_method_call): Use it.
+ * class.c (instantiate_type): Use it.
+ * decl.c (grokdeclarator): Use it.
+ * decl2.c (finish_file): Use it.
+ * method.c (build_overload_identifier): Use it.
+
+ * call.c (add_template_candidate): Add additional parameter for
+ the function return type. Call fn_type_unification istead of
+ type_unification.
+ (build_user_type_conversion_1): Handle member templates.
+ (build_new_function_call): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+
+ * class.c (grow_method): Don't give an error message indicating
+ that two member templates with the same name are ambiguous.
+ (finish_struct): Treat member template functions just like member
+ functions.
+
+ * cp-tree.h (check_member_template): Add declaration.
+ (begin_member_template_processing): Likewise.
+ (end_member_template_processing): Likewise.
+ (fn_type_unification): Likewise.
+ (is_member_template): Likewise.
+ (tsubst): Change prototype.
+ (tsubst_expr): Likewise.
+ (tsubst_copy): Likewise.
+ (instantiate_template): Likewise.
+ (get_bindings): Likewise.
+
+ * decl.c (decls_match): Handle multiple levels of template
+ parameters.
+ (pushdecl): Handle template type params just like other type
+ declarations.
+ (push_class_level_binding): Return immediately if the
+ class_binding_level is NULL.
+ (grokfndecl): If check_classfn() returns a member_template, use
+ the result of the template, not the template itself.
+
+ * decl2.c (check_member_template): New function. Check to see
+ that the entity declared to be a member template can be one.
+ (check_classfn): Allow redeclaration of member template functions
+ with different types; the new functions can be specializations or
+ explicit instantiations.
+
+ * error.c (dump_decl): Handle multiple levels of template
+ parameters.
+ (dump_function_decl): Update to handle function templates.
+
+ * lex.c (do_pending_inlines): Set up template parameter context
+ for member templates.
+ (process_next_inline): Likewise.
+
+ * method.c (build_overload_identifier): Adjust for multiple levels
+ of template parameters.
+
+ * parse.y (fn.def2): Add member templates.
+ (component_decl_1): Likewise.
+
+ * pt.c (begin_member_template_processing): New function.
+ (end_member_template_processing): Likewise.
+ (is_member_template): Likewise.
+ (fn_type_unification): Likewise.
+ (current_template_parms): Return a vector of all the template
+ parms, not just the innermost level of parms.
+ (push_template_decl): Deal with the possibility of member
+ templates.
+ (lookup_template_class): Likewise.
+ (uses_template_parms): Likewise.
+ (tsubst): Modify processing to TEMPLATE_TYPE_PARM and
+ TEMPLATE_CONST_PARM to deal with multiple levels of template
+ arguments. Add processing of TEMPLATE_DECL to produce new
+ TEMPLATE_DECLs from old ones.
+ (do_decl_instantiation): Handle member templates.
+
+ * search.c (lookup_fnfields_1): Handle member template conversion
+ operators.
+
+ * tree.c (cp_tree_equal): Check the levels, as well as the
+ indices, of TEMPLATE_CONST_PARMs.
+
+ * typeck.c (comptypes): Check the levels, as well as the indices,
+ fo TEMPLATE_TYPE_PARMs.
+ (build_x_function_call): Treat member templates like member
+ functions.
+
+Wed Sep 3 11:09:25 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (c_expand_return): Always convert_for_initialization
+ before checking for returning a pointer to local.
+
+ * pt.c (type_unification): If strict and the function parm doesn't
+ use template parms, just compare types.
+
+Wed Sep 3 10:35:49 1997 Klaus Espenlaub <kespenla@student.informatik.uni-ulm.de>
+
+ * method.c (build_overloaded_value): Replace direct call
+ to the floating point emulator with REAL_VALUE_TO_DECIMAL macro.
+
+Wed Sep 3 00:02:53 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (convert_arguments): Don't arbitrarily choose the first
+ of a set of overloaded functions.
+
+Tue Sep 2 12:09:13 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (real_yylex): Don't elide __FUNCTION__.
+
+ * method.c (build_overload_value): Add in_template parm.
+ (build_overload_int): Likewise.
+ (build_overload_identifier): Pass it.
+
+ * decl.c (duplicate_decls): Don't bash a previous template
+ definition with a redeclaration.
+
+ * pt.c (unify): float doesn't match double.
+
+ * pt.c (do_type_instantiation): Handle getting a _TYPE or a
+ TYPE_DECL. Handle getting non-template types.
+ * parse.y (explicit_instantiation): Use typespec instead of
+ aggr template_type.
+
+Tue Sep 2 10:27:08 1997 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (build_ptrmemfunc1): Clean up ptr->int cast warnings.
+
+Mon Sep 1 13:19:04 1997 Eugene Mamchits <eugin@ips.ras.ru>
+
+ * call.c (add_builtin_candidate): Add missing TREE_TYPE.
+ (compare_ics): Likewise.
+
+Mon Sep 1 13:19:04 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (joust): Warn about choosing one conversion op over
+ another because of 'this' argument when the other return type is
+ better.
+ (source_type): New fn.
+
+ * call.c (build_new_op): Strip leading REF_BIND from first operand
+ to builtin operator.
+
+ * decl2.c (mark_vtable_entries): Mark abort_fndecl as used when we
+ use its RTL.
+
+Thu Aug 28 09:45:23 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (null_ptr_cst_p): Remove support for (void*)0.
+
+Wed Aug 27 02:03:34 1997 Jeffrey A Law <law@cygnus.com>
+
+ * typeck.c (expand_target_expr): Make definition match declaration.
+
+ * class.c (get_basefndecls): Make definition match declaration.
+
+Mon Aug 25 14:30:02 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * input.c (sub_getch): Eventually give up and release the input file.
+
+ * decl.c (cp_finish_decl): If #p i/i, put inline statics in the
+ right place.
+
+ * call.c (joust): Tweak message.
+
+Sat Aug 23 18:02:59 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * error.c (type_as_string): Put const/volatile on template type
+ parameters where appropriate.
+
+Sat Aug 23 17:47:22 1997 Jeffrey A Law <law@cygnus.com>
+
+ * call.c (strictly_better): Make arguments unsigned ints.
+
+Thu Aug 21 18:48:44 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (real_yylex): Refer to __complex instead of complex.
+
+Thu Aug 21 22:25:46 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * lex.c (real_yylex): Don't use getc directly.
+
+Wed Aug 20 17:25:08 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (is_subseq): Don't try to be clever.
+
+Wed Aug 20 03:13:36 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
+
+ * parse.y, pt.c: Include "except.h".
+ * call.c, class.c, class.h, cp-tree.h, cvt.c, decl.c, decl2.c,
+ error.c, except.c, expr.c, friend.c, g++spec.c, init.c, input.c,
+ lex.c, lex.h, method.c, parse.y, pt.c, repo.c, rtti.c, search.c,
+ sig.c, spew.c, tree.c, typeck.c, typeck2.c, xref.c: Finish
+ prototyping.
+
+Wed Aug 20 01:34:40 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (mark_vtable_entries): Instead of replacing pure
+ virtuals with a reference to __pure_virtual, copy the decl and
+ change the RTL.
+
+Tue Aug 19 02:26:07 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (lookup_nested_type_by_name): Handle typedef wierdness.
+
+ * typeck2.c (my_friendly_abort): Report bugs to egcs-bugs@cygnus.com.
+
+ * pt.c (instantiate_class_template): Call repo_template_used
+ before finish_prevtable_vardecl.
+
+ * call.c (is_subseq): New fn.
+ (compare_ics): Use it.
+
+ * repo.c (finish_repo): Don't crash on no args.
+
+ * parse.y (named_complex_class_head_sans_basetype): Handle
+ explicit global scope.
+ * decl2.c (handle_class_head): New fn.
+
+ * pt.c (unify): Add CONST_DECL case.
+
+Thu Aug 14 10:05:13 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * rtti.c (permanent_obstack): Fix decl to not be a pointer.
+
+ * cp-tree.h (report_type_mismatch): Add prototype.
+ * call.c (build_overload_call_real): Remove erroneous fourth
+ argument to report_type_mismatch.
+ (build_user_type_conversion_1): Remove erroneous second arg to
+ tourney.
+ (build_new_function_call): Likewise.
+ (build_object_call): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+
+Wed Aug 13 19:19:25 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * error.c (dump_decl): Don't bother processing a function with no
+ DECL_LANG_SPECIFIC.
+
+ * method.c (emit_thunk): Call init_function_start in the macro case.
+
+Wed Aug 13 10:46:19 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
+
+ * decl2.c (DEFAULT_VTABLE_THUNKS): Define to be 0 if not
+ defined and used to set flag_vtable_thunks.
+
+Tue Aug 12 20:13:57 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y: Don't clear the inlines from their obstack until they've
+ all been processed.
+
+ * decl.c (duplicate_decls): Don't complain about exception
+ specification mismatch if flag_exceptions is off.
+
+Mon Aug 11 15:01:56 1997 Marc Lehmann <pcg@goof.com>
+
+ * Make-lang.in (c++.distclean): Remove g++.c on make distclean.
+
+Sun Aug 10 12:06:09 1997 Paul Eggert <eggert@twinsun.com>
+
+ * cp-tree.h: Replace STDIO_PROTO with PROTO in include files.
+ * cvt.c, error.c, except.c, expr.c, friend.c, init.c, rtti.c:
+ Include <stdio.h> before include files that formerly used STDIO_PROTO.
+
+ * decl.c, g++spec.c, lex.c, method.c, repo.c:
+ Include "config.h" first, as per autoconf manual.
+
+Fri Aug 8 11:47:48 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (duplicate_decls): Tweak wording.
+ * lex.c (do_pending_defargs): Don't die if we see a default arg
+ that isn't a DEFAULT_ARG.
+ * error.c (dump_expr): Handle DEFAULT_ARG.
+
+ * decl2.c (lang_decode_option): Handle -fhandle-exceptions.
+ * lang-options.h: Add -fhandle-exceptions.
+
+ * class.c (build_vtable): Vtables are artificial.
+ (prepare_fresh_vtable): Likewise.
+
+Wed Aug 6 11:02:36 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (ocp_convert): After converting to the target type, set
+ LOOKUP_NO_CONVERSION.
+
+ * call.c (joust): Warn about potentially confusing promotion rules
+ with -Wsign-promo.
+ * cp-tree.h, lang-options.h, decl2.c: Support -Wsign-promo.
+
+Tue Aug 5 15:15:07 1997 Michael Meissner <meissner@cygnus.com>
+
+ * exception.cc: Declare __terminate_func with noreturn attribute.
+
+Fri Aug 1 03:18:15 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y: Break out eat_saved_input, handle errors.
+ (function_try_block): Use compstmt instead of compstmt_or_error.
+
+Thu Jul 31 17:14:04 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (build_cplus_new): Don't set TREE_ADDRESSABLE.
+
+Fri Jul 4 01:45:16 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * Make-lang.in (cplib2.txt, cplib2.ready): Instead of checking for
+ existence of cc1plus check whether $(LANGUAGES) contains C++.
+
+Wed Jul 30 13:04:21 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * method.c (do_build_copy_constructor): When copying an anonymous
+ union member loop around to handle nested anonymous unions. Use
+ the offset of the member relative to the outer structure, not the
+ union.
+
+Tue Jul 29 21:17:29 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (resolve_args): New fn.
+ (build_new_function_call): Use it.
+ (build_object_call): Likewise.
+ (build_new_method_call): Likewise.
+
+Mon Jul 28 16:02:36 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): tsubst all default parms from templates.
+
+Wed Jul 23 13:36:25 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (struct cp_function): Add static_labelno.
+ (push_cp_function_context): Save it.
+ (pop_cp_function_context): Restore it.
+
+Tue Jul 22 14:43:29 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_component_ref_1): Convert from reference.
+
+Tue Jul 22 11:06:23 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (current_declspecs, prefix_attributes): Initialize to
+ NULL_TREE.
+
+ * parse.y (initdcl0): Make sure CURRENT_DECLSPECS is non-nil
+ before we try to force it to be a TREE_LIST.
+ (decl): Make sure $1.t is non-nil.
+
+Sun Jul 20 11:53:07 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (uses_template_parms): Handle template first-parse codes.
+
+ * decl.c (cp_finish_decl): Only warn about user-defined statics.
+
+Fri Jul 18 17:56:08 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (unify): Handle BOOLEAN_TYPE.
+
+ * cp-tree.h: Lose PARM_DEFAULT_FROM_TEMPLATE.
+ * pt.c (tsubst): Don't set it.
+ * call.c (build_over_call): Use uses_template_parms.
+
+Thu Jul 17 18:06:30 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (build_overload_nested_name): Use static_labelno
+ instead of var_labelno.
+ (build_qualified_name): New fn.
+ (build_overload_name): Split out from here.
+ (build_static_name): Use build_qualified_name.
+ * decl.c (cp_finish_decl): Statics in extern inline functions
+ have comdat linkage.
+ (start_function): Initialize static_labelno.
+
+Thu Jul 17 11:20:17 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * class.c (finish_struct_methods): Add check of warn_ctor_dtor_privacy
+ before "all member functions in class [] are private".
+
+Wed Jul 16 23:47:08 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (do_scoped_id): convert_from_reference.
+ * init.c (build_offset_ref): Likewise.
+
+Wed Jul 16 12:34:29 1997 Benjamin Kosnik <bkoz@lisa.cygnus.com>
+
+ * error.c (dump_expr): Check TREE_OPERAND before dump_expr_list.
+
+Mon Jul 14 03:23:46 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Promote index
+ before saving it.
+
+Sun Jul 13 00:11:52 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (layout_basetypes): Move non-virtual destructor warning.
+ * decl.c (xref_basetypes): Remove non-virtual destructor warning.
+
+Sat Jul 12 12:47:12 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Call add_defarg_fn for the function
+ type, too.
+ * lex.c (add_defarg_fn): Adjust.
+ (do_pending_defargs): Adjust. Don't skip the first parm.
+
+Fri Jul 11 01:39:50 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (build_enumerator): Global enumerators are also readonly.
+
+ * rtti.c (build_dynamic_cast_1): Renamed from build_dynamic_cast.
+ (build_dynamic_cast): Call it and convert_from_reference.
+
+ * lex.c (add_defarg_fn): New fn.
+ (snarf_defarg): Don't add to defarg_types.
+ (do_pending_defargs): Lose defarg_types. All fns we process now
+ have defargs.
+ * decl.c (grokfndecl): Call add_defarg_fn.
+
+ * Makefile.in (CONFLICTS): Expect 18 s/r conflicts.
+ * cp-tree.def: Add DEFAULT_ARG.
+ * spew.c (yylex): Call snarf_defarg as appropriate.
+ * parse.y: New tokens DEFARG and DEFARG_MARKER.
+ (defarg_again, pending_defargs, defarg, defarg1): New rules.
+ (structsp): Use pending_defargs.
+ (parms, full_parm): Use defarg.
+ * lex.c (init_lex): Initialize inline_text_firstobj.
+ (do_pending_inlines): Never pass the obstack to feed_input.
+ (process_next_inline): Call end_input instead of restore_pending_input.
+ (clear_inline_text_obstack, reinit_parse_for_expr, do_pending_defargs,
+ finish_defarg, feed_defarg, snarf_defarg, maybe_snarf_defarg): New fns.
+ * input.c (end_input): New fn.
+ (sub_getch): At the end of some fed input, just keep returning EOF
+ until someone calls end_input.
+ Remove 'obstack' field from struct input_source.
+ * decl.c (grokparms): Handle DEFAULT_ARG.
+ (replace_defarg): New fn.
+ * cp-tree.h (DEFARG_LENGTH, DEFARG_POINTER): New macros.
+
+Wed Jul 9 13:44:12 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (implicit_conversion): If nothing else works, try binding
+ an rvalue to a reference.
+
+Wed Jul 9 13:04:38 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * decl.c (init_decl_processing): Fix Jun 30 patch -- move
+ ifndef for Cygwin32 to include SIGSEGV.
+
+Thu Jul 3 01:44:05 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_1): Only complain about pointers without
+ copy stuff if there are any constructors.
+
+ * rtti.c (build_dynamic_cast): Call complete_type on the types.
+
+ * decl.c (grokfndecl): If the function we chose doesn't actually
+ match, die.
+
+ * decl2.c (grokclassfn): Don't specify 'const int' for the
+ artificial destructor parm.
+
+ * pt.c (type_unification): If we are called recursively, nothing
+ decays.
+
+Mon Jun 30 17:53:21 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * decl.c (init_decl_processing): Stop trying to catch signals
+ other than SIGABRT since the Cygwin32 library doesn't support
+ them correctly yet. This fixes a situation in which g++ causes
+ a hang on SIGSEGVs and other such signals in our Win32-hosted
+ tools.
+
+Mon Jun 30 14:50:01 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (mapcar, case CALL_EXPR): Handle all the parse node data.
+
+Fri Jun 27 15:18:49 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (store_init_value): Always return the value if our
+ type needs constructing.
+
+ * method.c (hack_identifier): Convert class statics from
+ reference, too.
+
+Thu Jun 26 11:44:46 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Make-lang.in (cplib2.ready): Add $(LANGUAGES) dependency.
+
+Thu Jun 19 16:49:28 1997 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (c_expand_return): Make sure we clean up temporaries at
+ the end of return x;
+
+Thu Jun 19 12:28:43 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lex.c (check_for_missing_semicolon): Also check for CV_QUALIFIER.
+
+Tue Jun 17 18:35:57 1997 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_builtin_throw): Add support
+ -fno-sjlj-exceptions -fPIC exception handling on the SPARC.
+
+Mon Jun 16 01:24:37 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * repo.c (extract_string): Null-terminate.
+
+ * cp-tree.h (TI_SPEC_INFO): New macro.
+ (CLASSTYPE_TI_SPEC_INFO): New macro.
+ * pt.c (push_template_decl): Correctly determine # of template parms
+ for partial specs.
+
+ * call.c (compare_ics): Really fix 'this' conversions.
+
+ * pt.c (do_decl_instantiation): Don't crash on explicit inst of
+ non-template fn.
+
+ * pt.c (push_template_decl): Complain about mismatch in # of
+ template parms between a class template and a member template.
+
+Sun Jun 15 02:38:20 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (synthesize_method): You can't call
+ function_cannot_inline_p after finish_function.
+ * decl.c (finish_function): Turn on flag_inline_functions and turn
+ off DECL_INLINE before handing a synthesized method to the
+ backend.
+
+Thu Jun 12 17:35:28 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (synthesize_method): Remove July 30 change to never set
+ DECL_INLINE if at_eof.
+
+Thu Jun 12 15:25:08 1997 Mike Stump <mrs@cygnus.com>
+
+ * xref.c (GNU_xref_member): Ensure that the node has a
+ decl_lang_specific part before checking DECL_FRIEND_P.
+
+Thu Jun 12 12:36:05 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Diagnose non-class types used
+ as bases.
+
+Wed Jun 11 17:33:40 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_conditional_expr): Use convert_for_initialization
+ instead of convert_and_check.
+
+Wed Jun 11 12:31:33 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.y (typespec): Don't pedwarn for typeof.
+
+Tue Jun 10 00:22:09 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * repo.c (finish_repo): Only check changes if we would write a
+ repo file.
+
+ * call.c (compare_ics): Fix handling of 'this' conversions.
+
+ * pt.c (do_decl_instantiation): Support static data too. Rename
+ from do_function_instantiation.
+ * cp-tree.h: Adjust.
+ * parse.y: Adjust.
+
+ * repo.c (extract_string): New fn.
+ (get_base_filename): Use it.
+ (init_repo): Compare old args with current args.
+
+Mon Jun 9 14:25:30 1997 Mike Stump <mrs@cygnus.com>
+
+ * Makefile.in, Make-lang.in: Protect C-ls with a comment
+ character, idea from Paul Eggert <eggert@twinsun.com>.
+
+Mon Jun 9 01:52:03 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (c_expand_return): Be more persistent in looking for
+ returned temps.
+
+ * cvt.c (build_up_reference): Use NOP_EXPR for switching from
+ pointer to reference.
+
+ * class.c (build_vbase_path): Don't do anything if PATH has no steps.
+
+Sun Jun 8 03:07:05 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_member_call, build_offset_ref):
+ Use do_scoped_id instead of do_identifier.
+
+ * cvt.c (convert): Remove bogosity.
+
+Sat Jun 7 20:50:17 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cvt.c (build_up_reference): Do checks of ARGTYPE and
+ TARGET_TYPE before trying to use get_binfo.
+
+Fri Jun 6 17:36:39 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (build_up_reference): Call get_binfo to get access control.
+
+ * decl2.c (import_export_decl): If we don't support weaks, leave
+ statics undefined.
+
+Fri Jun 6 15:55:49 1997 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_builtin_throw): Add support for machines that
+ cannot access globals after throw's epilogue when
+ -fno-sjlj-exceptions is used.
+
+Thu Jun 5 16:28:43 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y: 'std::' becomes '::'.
+ * lex.c (real_yylex): Remove 'namespace' warning.
+ * init.c (build_member_call): Ignore 'std::'.
+ (build_offset_ref): Likewise.
+ * decl2.c (do_using_directive): Ignore 'using namespace std;'.
+ (do_toplevel_using_decl): Ignore 'using std::whatever'.
+ * decl.c (push_namespace): Just sorry.
+ (pop_namespace): Nop.
+ (init_decl_processing): Declare std namespace.
+
+Tue Jun 3 18:08:23 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (push_class_decls): A name which ambiguously refers to
+ several instantiations of the same template just refers to the
+ template.
+
+Tue Jun 3 12:30:40 1997 Benjamin Kosnik <bkoz@cirdan.cygnus.com>
+
+ * decl.c (build_enumerator): Fix problem with unsigned long
+ enumerated values being smashed to ints, causing overflow
+ when computing next enumerated value (for enum values around
+ MAX_VAL).
+
+Mon Jun 2 17:40:56 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_component_ref): Only call mark_used on a decl.
+
+Thu May 29 15:54:17 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (build_c_cast): Make the check for a ptr to function
+ more specific before possible default_conversion call.
+
+Thu May 29 13:02:06 1997 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_exception_blocks): Simplify and fix and make
+ sure we don't end a region in a sequence, as expand_end_bindings
+ doesn't like it.
+
+Wed May 28 17:08:03 1997 Mike Stump <mrs@cygnus.com>
+
+ * except.c (init_exception_processing): Mark terminate as not
+ returning so that the optimizer can optimize better.
+
+Tue May 27 19:49:19 1997 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (convert): Don't do any extra work, if we can avoid it
+ easily.
+
+Tue May 27 18:21:47 1997 Mike Stump <mrs@cygnus.com>
+
+ * *.[chy]: Change cp_convert to ocp_convert, change convert to
+ cp_convert. convert is now reserved for the backend, and doesn't
+ have the semantics a frontend person should ever want.
+
+Fri May 23 10:58:31 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lang-specs.h: Define __EXCEPTIONS if exceptions are enabled.
+ Lose -traditional support.
+
+Thu May 22 15:41:28 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (get_tinfo_var): Use TYPE_PRECISION (sizetype).
+
+ * parse.y (self_reference): Do it for templates, too.
+ * class.c (pushclass): Don't overload_template_name; the alias
+ generated by build_self_reference serves the same purpose.
+
+ * tree.c (list_hash): Make static, take more args.
+ (list_hash_lookup): Likewise.
+ (list_hash_add): Make static.
+ (list_hash_canon): Lose.
+ (hash_tree_cons): Only build a new node if one isn't already in the
+ hashtable.
+ (hash_tree_chain): Use hash_tree_cons.
+ * cp-tree.h: Adjust.
+ * decl.c (grokfndecl): Just check IDENTIFIER_GLOBAL_VALUE instead
+ of calling lookup_name.
+
+Wed May 21 18:24:19 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): TYPE_VALUES for an enum
+ doesn't refer to the CONST_DECLs.
+
+Tue May 20 21:09:32 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * rtti.c (get_tinfo_var): Either INT_TYPE_SIZE or 32, whichever
+ is bigger.
+ (expand_class_desc): Convert the last argument to a sizetype.
+
+Tue May 20 13:55:57 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * gxx.gperf (__complex, __complex__, __imag, __imag__, __real,
+ __real__): Add reswords.
+ * hash.h: Regenerate.
+ * lex.h (rid): Add RID_COMPLEX.
+ (RID_LAST_MODIFIER): Set to RID_COMPLEX.
+ * lex.c (init_lex): Add building of RID_COMPLEX.
+ (real_yylex): General cleanup in line with what c-lex.c also has,
+ sans the cruft for traditional; add handling of SPEC_IMAG, complex
+ types, and imaginary numeric constants.
+ * parse.y (REALPART, IMAGPART): Add tokens.
+ (unary_expr): Add REALPART and IMAGPART rules.
+ * cp-tree.h (complex_{integer,float,double,long}_type_node): Declare.
+ * decl.c (complex_{integer,float,double,long}_type_node): Define
+ types.
+ (init_decl_processing): Set up the types.
+ (grokdeclarator): Add handling of RID_COMPLEX. Set and use
+ DEFAULTED_INT instead of EXPLICIT_INT when we default to int type.
+ * call.c (build_new_op): Add REALPART_EXPR and IMAGPART_EXPR cases.
+ * cvt.c (cp_convert): Handle COMPLEX_TYPE.
+ * error.c (dump_type_prefix, dump_type, dump_type_suffix): Add
+ COMPLEX_TYPE case.
+ * method.c (build_overload_name): Add handling of the different
+ COMPLEX_TYPEs, prefixing them with `J'.
+ * pt.c (process_template_parm): Don't let them use a COMPLEX_TYPE
+ as a template parm.
+ (uses_template_parms, tsubst, unify): Add COMPLEX_TYPE case.
+ * tree.c (lvalue_p): Add REALPART_EXPR and IMAGPART_EXPR cases.
+ (mapcar): Handle COMPLEX_CST.
+ * typeck.c (build_binary_op_nodefault): Handle COMPLEX_TYPE.
+ (common_type): Add code for complex types.
+ (build_unary_op): Add REALPART_EXPR and IMAGPART_EXPR cases.
+ (convert_for_assignment): Likewise.
+ (mark_addressable): Add REALPART_EXPR and IMAGPART_EXPR cases.
+
+Mon May 19 12:26:27 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Don't pass the MINUS_EXPR for an array domain to
+ tsubst_expr, as it might try to do overload resolution.
+
+Sat May 17 10:48:31 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Oops.
+
+Fri May 16 14:23:57 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.def: Add TAG_DEFN.
+ * pt.c (tsubst_enum): New fn.
+ (instantiate_class_template): Use it.
+ (tsubst_expr): Support TAG_DEFN.
+ (tsubst): Support local enums.
+ (tsubst_copy): Likewise.
+ * decl.c (finish_enum): Likewise.
+ (start_enum): If this is a local enum, switch to permanent_obstack.
+
+Wed May 14 19:08:28 1997 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (store_parm_decls): Set last_parm_cleanup_insn here.
+ (finish_function): Put the base init code for constructors just
+ after the parm cleanup insns.
+ (struct cp_function): Add last_parm_cleanup_insn.
+ (push_cp_function_context): Likewise.
+ (pop_cp_function_context): Likewise.
+
+Tue May 13 15:51:20 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst_copy): Handle BIT_NOT_EXPR.
+
+Wed May 7 11:17:59 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * method.c (emit_thunk) [ASM_OUTPUT_MI_THUNK]: Build up the RTL
+ for THUNK_FNDECL before we switch to temporary allocation.
+
+Mon May 5 14:46:53 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_new_op): Handle null arg2 for ?:.
+
+Thu May 1 18:26:37 1997 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_exception_blocks): Ensure that we flow through
+ the end of the exception region for the exception specification.
+ Move exception region for the exception specification in, so that
+ it doesn't protect the parm cleanup. Remove some obsolete code.
+ * decl.c (store_parm_decls): Likewise.
+ (finish_function): Likewise.
+
+Tue Apr 29 15:38:54 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_new): Fix nothrow handling.
+
+Tue Apr 29 14:29:50 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (emit_base_init): Don't warn about the initialization
+ list for an artificial member.
+
+Fri Apr 25 17:47:59 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * expr.c (do_case): Handle !START case for the error msg.
+
+Fri Apr 25 11:55:23 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c, lang-options.h: New option -Weffc++.
+ * class.c, decl.c, init.c, typeck.c: Move Effective C++ warnings
+ to -Weffc++.
+
+ * decl2.c (finish_prevtable_vardecl): Change NO_LINKAGE_HEURISTICS
+ to MULTIPLE_SYMBOL_SPACES.
+
+Wed Apr 23 18:06:50 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (emit_thunk, generic case): Set current_function_is_thunk.
+
+ * method.c (emit_thunk, macro case): Set up DECL_RESULT.
+
+ * typeck.c (c_expand_return): Don't complain about returning void
+ to void in an artificial function.
+ * method.c (make_thunk): Change settings of READONLY/VOLATILE,
+ don't set DECL_RESULT, set DECL_ARTIFICIAL.
+ (emit_thunk, generic code): Also set up DECL_LANG_SPECIFIC.
+
+Wed Apr 23 14:43:06 1997 Mike Stump <mrs@cygnus.com>
+
+ * init.c (init_decl_processing): Add support for setjmp/longjmp based
+ exception handling.
+ * except.c (init_exception_processing): Likewise.
+ (expand_end_catch_block): Likewise.
+ (expand_exception_blocks): Likewise.
+ (expand_throw): Likewise.
+ * exception.cc (__default_terminate): Likewise.
+
+ * init.c (perform_member_init): Use new method of expr level
+ cleanups, instead of cleanups_this_call and friends.
+ (emit_base_init): Likewise.
+ (expand_aggr_vbase_init_1): Likewise.
+ (expand_vec_init): Likewise.
+ * decl.c (cp_finish_decl): Likewise.
+ (expand_static_init): Likewise.
+ (store_parm_decls): Likewise.
+ (cplus_expand_expr_stmt): Likewise.
+ * decl2.c (finish_file): Likewise.
+
+ * Make-lang.in (exception.o): Ok to compile with -O now.
+
+ * decl.c (maybe_build_cleanup_1): We no longer have to unsave, as
+ we know it will be done later by the backend.
+
+ * decl2.c (lang_f_options): Remove support for short temps.
+ * lang-options.h: Likewise.
+
+Wed Apr 23 04:12:06 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (varargs_function_p): New fn.
+ * method.c (emit_thunk): Replace broken generic code with code to
+ generate a heavyweight thunk function.
+
+Tue Apr 22 02:45:18 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (process_template_parm): pedwarn about floating-point parms.
+
+ * decl.c (grokdeclarator): inline no longer implies static.
+
+ * spew.c (yylex): Always return the TYPE_DECL if we got a scope.
+
+Mon Apr 21 15:42:27 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (check_for_override): The signature of an overriding
+ function is not changed.
+
+ * call.c (build_over_call): Move setting of conv into the loop.
+ Note: this change, along with the related changes of the 18th thru
+ the 20th of April, fix an infinite loop problem in conversions.
+
+Sun Apr 20 16:24:29 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_user_type_conversion_1): Really ignore rvalue
+ conversions when looking for a REFERENCE_TYPE.
+
+ * cvt.c (build_up_reference): Eviscerate, use build_unary_op.
+ * cp-tree.h (TREE_REFERENCE_EXPR): #if 0.
+ * typeck.c (decay_conversion): Don't set TREE_REFERENCE_EXPR.
+ (build_unary_op): Likewise.
+ * call.c (build_over_call): See through a CONVERT_EXPR around the
+ ADDR_EXPR for on a temporary.
+ * typeck.c (c_expand_return): See through a CONVERT_EXPR around
+ the ADDR_EXPR for a local variable.
+
+Fri Apr 18 12:11:33 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_user_type_conversion_1): If we're trying to
+ convert to a REFERENCE_TYPE, only consider lvalue conversions.
+ (build_new_function_call): Print candidates.
+ (implicit_conversion): Try a temp binding if the lvalue conv is BAD.
+ (reference_binding): Binding a temporary of a reference-related type
+ is BAD.
+
+Thu Apr 17 14:37:22 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * inc/typeinfo (type_info::before): Add cv-qualifier-seq.
+ * tinfo2.cc (type_info::before): Likewise.
+
+Mon Apr 14 12:38:17 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (implicit_conversion): Oops.
+
+Fri Apr 11 02:18:30 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (implicit_conversion): Try to find a reference conversion
+ before binding a const reference to a temporary.
+
+Wed Apr 2 12:51:36 1997 Mike Stump <mrs@cygnus.com>
+
+ * exception.cc (__default_unexpected): Call terminate by default,
+ so that if the user overrides terminate, the correct function will
+ be called.
+
+Wed Mar 19 14:14:45 1997 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (left_curly): Avoid trying to use any fields of
+ error_mark_node, as there aren't any.
+
+Thu Mar 13 16:33:22 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (do_identifier): Avoid breaking on overloaded methods
+ as default arguments.
+
+Wed Mar 12 13:55:10 1997 Hans-Peter Nilsson <Hans-Peter.Nilsson@axis.se>
+
+ * call.c (add_template_candidate): Initialize the variable "dummy".
+
+Mon Mar 10 15:13:14 1997 Brendan Kehoe <brendan@canuck.cygnus.com>
+
+ * decl.c (start_decl): Make sure TYPE isn't an error_mark_node
+ before we try to use TYPE_SIZE and TREE_CONSTANT on it.
+
+Fri Mar 7 13:19:36 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (comp_ptr_ttypes, more_specialized): Add decl.
+ (debug_binfo): Delete decl, not needed.
+
+ * tree.c (fnaddr_from_vtable_entry, function_arg_chain,
+ promotes_to_aggr_type): Delete fns.
+ * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY,
+ SET_FNADDR_FROM_VTABLE_ENTRY, FUNCTION_ARG_CHAIN,
+ PROMOTES_TO_AGGR_TYPE): Delete alternates to #if 1.
+
+ * decl.c (pending_invalid_xref{,_file,_line}): Delete unused vars.
+
+ * friend.c (is_friend_type): Delete fn.
+ * cp-tree.h (is_friend_type): Delete decl.
+
+ * decl.c (original_result_rtx, double_ftype_double,
+ double_ftype_double_double, int_ftype_int, long_ftype_long,
+ float_ftype_float, ldouble_ftype_ldouble, last_dtor_insn): Make static.
+ * typeck.c (original_result_rtx, warn_synth): Delete extern decls.
+
+ * decl.c (push_overloaded_decl{,_top_level}): Make static, adding
+ fwd decls.
+ * cp-tree.h (push_overloaded_decl{,_top_level}): Delete decls.
+
+ * decl.c (pushdecl_nonclass_level): #if 0, unused.
+ * cp-tree.h (pushdecl_nonclass_level): #if 0 decl.
+
+ * lex.c (reinit_lang_specific): #if 0, unused.
+ * cp-tree.h (reinit_lang_specific): #if 0 decl.
+
+ * decl.c (revert_static_member_fn): Make static, adding fwd decl.
+ * cp-tree.h (revert_static_member_fn): Delete decl.
+
+ * class.c (root_lang_context_p): Delete fn.
+ * cp-tree.h (root_lang_context_p): Delete decl.
+
+ * decl.c (set_current_level_tags_transparency): #if 0, unused.
+ * cp-tree.h (set_current_level_tags_transparency): #if 0 decl.
+
+ * lex.c (set_vardecl_interface_info): Make static.
+ * cp-tree.h (set_vardecl_interface_info): Delete decl.
+
+ * call.c (find_scoped_type): Make static.
+ * cp-tree.h (find_scoped_type): Delete decl.
+
+ * search.c (convert_pointer_to_vbase): Make static.
+ * cp-tree.h (convert_pointer_to_vbase): Delete decl.
+
+ * decl.c (const_ptr_type_node): Likewise.
+ * cp-tree.h (const_ptr_type_node): Delete decl.
+
+ * typeck.c (common_base_type): Make static.
+ * cp-tree.h (common_base_types): Delete erroneous decl.
+
+ * pt.c (classtype_mangled_name): Make static.
+ * cp-tree.h (classtype_mangled_name): Delete decl.
+
+ * lex.c (check_newline): Make static.
+ * cp-tree.h (check_newline): Delete decl.
+
+ * typeck.c (build_x_array_ref): Delete fn, same idea as
+ grok_array_decl.
+ * cp-tree.h (build_x_array_ref): Delete decl.
+
+ * lex.c (copy_decl_lang_specific): Delete fn, same idea as
+ copy_lang_decl.
+ * cp-tree.h (copy_decl_lang_specific): #if 0 decl.
+
+ * class.c (build_vtable_entry): Make static.
+ * cp-tree.h (build_vtable_entry): Delete decl.
+
+ * class.c (build_vbase_pointer): Make static.
+ * cp-tree.h (build_vbase_pointer): Delete decl.
+
+ * sig.c (build_sptr_ref): Add forward decl and make static.
+ * cp-tree.h (build_sptr_ref): Delete decl.
+
+ * call.c (build_new_method_call): Add forward decl and make static.
+ * cp-tree.h (build_new_method_call): Delete decl.
+
+ * call.c (build_object_call): Make static.
+ * class.c (check_for_override, complete_type_p, mark_overriders):
+ Likewise.
+ * decl.c (cp_function_chain): Likewise.
+ * lex.c (set_typedecl_interface_info, reinit_parse_for_block):
+ Likewise.
+ * pt.c (comp_template_args, get_class_bindings, push_tinst_level):
+ Likewise.
+ * tree.c (build_cplus_array_type_1): Likewise.
+ * typeck.c (comp_ptr_ttypes_{const,real,reinterpret}): Likewise.
+ (comp_target_parms): Likewise.
+
+ * init.c (build_builtin_call): Make static.
+ * cp-tree.h (build_builtin_call): Delete decl.
+
+ * typeck.c (binary_op_error): Delete decl.
+ * cp-tree.h (binary_op_error): Likewise.
+
+Thu Mar 6 16:13:52 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (build_method_call): Compare against error_mark_node
+ directly, rather than the ERROR_MARK tree code.
+ * cvt.c (cp_convert): Likewise.
+ * decl.c (print_binding_level): Likewise.
+ (duplicate_decls): Likewise.
+ (grokdeclarator): Likewise.
+ (grokdeclarator): Likewise.
+ * init.c (expand_aggr_init_1): Likewise.
+ (decl_constant_value): Likewise.
+ * method.c (build_opfncall): Likewise.
+ (hack_identifier): Likewise.
+ * typeck.c (build_modify_expr): Likewise.
+
+ * typeck.c (build_c_cast): Don't decl TYPE as register tree.
+
+Sun Mar 2 02:54:36 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * pt.c (unify): Strip NOP_EXPR wrappers before unifying integer values.
+
+ * pt.c (coerce_template_parms): Add new error message.
+
+ * method.c (build_overload_value): Implement name mangling for
+ floating-point template arguments.
+
+ * method.c (build_overload_int, icat, dicat): Fix mangling of template
+ arguments whose absolute value doesn't fit in a signed word.
+
+Mon Mar 3 12:14:54 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * friend.c: New file; put all of the friend stuff in here.
+ * init.c: Instead of here.
+ * Makefile.in (CXX_OBJS): Add friend.o.
+ (friend.o): Add dependencies.
+ * Make-lang.in (CXX_SRCS): Add $(srcdir)/cp/friend.c.
+
+Sun Mar 2 11:04:43 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_scoped_method_call): Complain if the scope isn't a
+ base.
+
+Wed Feb 26 11:31:06 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (left_curly): Don't crash on erroneous type.
+
+ * init.c (build_delete): Fix type of ref.
+
+Tue Feb 25 12:41:48 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (get_vbase_1): Renamed from get_vbase.
+ (get_vbase): Wrapper, now non-static.
+ (convert_pointer_to_vbase): Now static.
+
+ * call.c (build_scoped_method_call): Accept a binfo for BASETYPE.
+ * init.c (build_delete): Pass one.
+ (build_partial_cleanup_for): Use build_scoped_method_call.
+ * decl.c (finish_function): Pass a binfo.
+
+Mon Feb 24 15:00:12 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): Only synthesize non-trivial copy ctors.
+
+ * typeck.c (build_c_cast): Lose other reference to flag.
+
+ * call.c (build_field_call): Don't look for [cd]tor_identifier.
+ * decl2.c (delete_sanity): Remove meaningless use of
+ LOOKUP_HAS_IN_CHARGE.
+ * decl.c (finish_function): Use build_scoped_method_call instead
+ of build_delete for running vbase dtors.
+ * init.c (build_delete): Call overload resolution code instead of
+ duplicating it badly.
+
+Thu Feb 20 15:12:15 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): Call mark_used before trying to elide
+ the call.
+
+ * decl.c (implicitly_declare): Don't set DECL_ARTIFICIAL.
+
+Wed Feb 19 11:18:53 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (build_modify_expr): Always pedwarn for a cast to
+ non-reference used as an lvalue.
+
+Wed Feb 19 10:35:37 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Convert from 0 to a pmf properly.
+
+Tue Feb 18 15:40:57 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (handler): Fix template typo.
+
+Sun Feb 16 02:12:28 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * error.c (lang_decl_name): New fn.
+ * tree.c (lang_printable_name): Use it.
+
+Fri Feb 14 16:57:05 1997 Mike Stump <mrs@cygnus.com>
+
+ * g++spec.c: Include config.h so that we can catch bzero #defines
+ from the config file.
+
+Tue Feb 11 13:50:48 1997 Mike Stump <mrs@cygnus.com>
+
+ * new1.cc: Include a declaration for malloc, to avoid warning, and
+ avoid lossing on systems that require one (ones that define malloc
+ in xm.h).
+
+Mon Feb 10 22:51:13 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * decl2.c (max_tinst_depth): New variable.
+ (lang_decode_option): Parse "-ftemplate-depth-NN" command line
+ option.
+ * pt.c (max_tinst_depth): Variable moved.
+ * lang-options.h: Declare "-ftemplate-depth-NN" command line option
+ as legal.
+
+Fri Feb 7 15:43:34 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (xref_basetypes): Allow a base class that depends on
+ template parms to be incomplete.
+
+ * decl2.c (build_expr_from_tree): Support typeid(type).
+ * rtti.c (get_typeid): Support templates.
+ (expand_si_desc, expand_class_desc): Fix string length.
+ (expand_ptr_desc, expand_attr_desc, expand_generic_desc): Likewise.
+
+Tue Feb 4 11:28:24 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (unify, case TEMPLATE_CONST_PARM): Use cp_tree_equal.
+
+ * pt.c (tsubst): Put it back for -fno-ansi-overloading.
+
+Mon Feb 3 18:41:12 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst, case FUNCTION_DECL): Lose obsolete code that
+ smashes together template and non-template decls of the same
+ signature.
+
+Thu Jan 30 19:18:00 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Don't recurse for the type of a TYPENAME_TYPE.
+
+Wed Jan 29 11:40:35 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (duplicate_decls): Next route, pedwarn about different
+ exceptions if -pedantic *or* olddecl !DECL_IN_SYSTEM_HEADER.
+
+Tue Jan 28 20:43:29 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (HAS_DEFAULT_IMPLEMENTATION): Delete macro.
+ (struct lang_type): Delete has_default_implementation member.
+ Increase dummy to 21.
+ * decl.c (start_method): Delete usage.
+
+ * cp-tree.h (build_call, null_ptr_cst_p, in_function_p,
+ store_after_parms, start_decl_1, auto_function): Add decls.
+ (get_arglist_len_in_bytes, declare_implicit_exception,
+ have_exceptions_p, make_type_decl, typedecl_for_tag,
+ store_in_parms, pop_implicit_try_blocks, push_exception_cleanup,
+ build_component_type_expr, cplus_exception_name,
+ {make,clear}_anon_parm_name, dont_see_typename): Removed decls.
+ * call.c (build_this): Make static.
+ (is_complete): Likewise.
+ (implicit_conversion): Likewise.
+ (reference_binding): Likewise.
+ (standard_conversion): Likewise.
+ (strip_top_quals): Likewise.
+ (non_reference): Likewise.
+ (build_conv): Likewise.
+ (user_harshness): Likewise.
+ (rank_for_ideal): Likewise.
+ * decl.c (start_decl_1): Delete forward decl.
+ (push_decl_level): Make static.
+ (resume_binding_level): Make static.
+ (namespace_bindings_p): Make static.
+ (declare_namespace_level): Make static.
+ (lookup_name_real): Make static.
+ (duplicate_decls): Make static. Take register off NEWDECL and
+ OLDDECL parm decls.
+ * decl2.c (get_sentry): Make static.
+ (temp_name_p): Delete fn.
+ * except.c (auto_function): Delete decl.
+ * lex.c (handle_{cp,sysv}_pragma): Make static.
+ (handle_sysv_pragma) [HANDLE_SYSV_PRAGMA]: Add forward decl.
+ * method.c (do_build_{copy_constructor,assign_ref}): Make static.
+ * pt.c (tsubst_expr_values): Make static.
+ * rtti.c (combine_strings): Delete decl.
+
+Tue Jan 28 16:40:40 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (push_template_decl): Handle getting a typedef.
+
+ * call.c (build_new_function_call): Complain about void arg.
+
+Tue Jan 28 15:25:09 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (duplicate_decls): Give pedwarn of different exceptions
+ if -pedantic, instead of olddecl !DECL_IN_SYSTEM_HEADER.
+
+Mon Jan 27 19:21:29 1997 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Don't expand the cleanup tree here,
+ since we are not going to write the rtl out. Fixes problem with
+ -g -O on SPARC.
+
+Mon Jan 27 16:24:35 1997 Sean McNeil <sean@mcneil.com>
+
+ * Make-lang.in: Add $(exeext) as necessary.
+
+Mon Jan 27 13:20:39 1997 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (handler_seq): Must have at least one catch clause.
+
+Sat Jan 25 12:00:05 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (add_builtin_candidate): Restore ?: hack.
+
+ * decl.c (grok_op_properties): More warnings.
+
+Sat Jan 25 08:50:03 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (duplicate_decls): On second thought, do it as a pedwarn
+ still but only if !DECL_IN_SYSTEM_HEADER (olddecl).
+
+ * decl.c (duplicate_decls): Scale back to a warning, and only do
+ 'em if -pedantic.
+
+Fri Jan 24 17:52:54 1997 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (duplicate_decls): pedwarn mismatched exception
+ specifications.
+
+Thu Jan 23 18:18:54 1997 Mike Stump <mrs@cygnus.com>
+
+ * call.c (build_new_method_call): Don't display the invisible
+ argument for controlling virtual bases.
+
+Thu Jan 23 16:48:10 1997 Mike Stump <mrs@cygnus.com>
+
+ * new: Add nothrow new and delete, bad_alloc and throw specifications
+ for delete.
+ * decl.c (init_decl_processing): Add throw specification for delete.
+ * new.cc (nothrow): Define.
+ * lex.c (real_yylex): Removing warning that throw and friends are
+ keywords.
+ * new1.cc (operator new (size_t sz, const nothrow_t&)): Define.
+ * new2.cc (operator new[] (size_t sz, const nothrow_t&): Define.
+ * Make-lang.in: Add new{1,2}.{cc,o}.
+
+Thu Jan 23 16:39:06 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (cons_up_default_function): Fix return type of synth op=.
+
+ * init.c (emit_base_init): Add warnings for uninitialized members
+ and bases.
+
+ * decl.c (xref_basetypes): Add warning for non-polymorphic type
+ with destructor used as base type.
+
+ * decl.c (grok_op_properties): Add warning for op= returning void.
+ * typeck.c (c_expand_return): Add warning for op= returning anything
+ other than *this.
+
+ * class.c (finish_struct_1): Add warning for class with pointers
+ but not copy ctor or copy op=.
+
+ * cp-tree.h (TI_PENDING_TEMPLATE_FLAG): New macro.
+ * pt.c (add_pending_template): Use it instead of LANG_FLAG_0.
+ (instantiate_template): If -fexternal-templates, add this
+ instantiation to pending_templates.
+
+ * decl2.c (copy_assignment_arg_p): Disable old hack to support
+ Booch components.
+
+Tue Jan 21 18:32:04 1997 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (cp_convert): pedwarn enum to pointer conversions.
+
+Mon Jan 20 17:59:51 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (standard_conversion): Handle getting references. Tack
+ on RVALUE_CONV here. Do it for non-class types, too.
+ (reference_binding): Pass references to standard_conversion.
+ (implicit_conversion): Likewise.
+ (add_builtin_candidate): Disable one ?: kludge.
+ (convert_like): Handle RVALUE_CONVs for non-class types.
+ (joust): Disable the other ?: kludge.
+
+Mon Jan 20 14:53:13 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (init_decl_processing): Add code to build up common
+ function types beforehand, to avoid creation then removal of
+ things already in the hash table.
+
+Mon Jan 20 14:43:49 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (finish_function): Also zero out DECL_INCOMING_RTL for
+ the arguments.
+
+ * error.c (dump_expr, TEMPLATE_CONST_PARM): Don't require
+ current_template_parms.
+
+Fri Jan 17 10:25:42 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (lookup_field): Don't return a function, check want_type.
+
+Thu Jan 16 18:14:35 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_new): Make sure PLACEMENT has a type.
+
+Thu Jan 16 17:40:28 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_new): Support new (nothrow).
+
+Wed Jan 15 12:38:14 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_decl): Also do push_to_top_level before setting
+ up DECL_INITIAL.
+
+ * cp-tree.h (PARM_DEFAULT_FROM_TEMPLATE): New macro.
+ * pt.c (tsubst): Defer instantiation of default args.
+ * call.c (build_over_call): Until here.
+
+Wed Jan 15 10:08:10 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * search.c (lookup_field): Make sure we have an
+ IDENTIFIER_CLASS_VALUE before we try to return it.
+
+Thu Jan 9 07:19:01 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (build_method_call): Delete unused var PARM.
+ (build_overload_call_real): Likewise.
+ (build_object_call): Delete unused var P.
+ (build_new_op): Likewise.
+ * decl.c (builtin_type_tdescs_{arr, len, max}): #if 0 out static
+ var definitions, which are never used.
+ (shadow_tag): Delete unused var FN.
+ * expr.c (cplus_expand_expr): Delete unused var ORIGINAL_TARGET.
+ * init.c (build_new): Delete unused var ALLOC_TEMP.
+ * method.c (hack_identifier): Delete unused var CONTEXT.
+ (do_build_copy_constructor): Delete unused var NAME.
+ (synthesize_method): Delete unused var BASE.
+ * pt.c (lookup_template_class): Delete unused var CODE_TYPE_NODE.
+ * rtti.c (build_headof): Delete unused var VPTR.
+ (get_typeid): Delete unused var T.
+ * typeck.c (build_conditional_expr): Delete unused vars ORIG_OP1
+ and ORIG_OP2.
+ (build_ptrmemfunc): Delete unused vars U and NINDEX.
+ * typeck2.c (build_functional_cast): Delete unused var BINFO.
+
+Wed Jan 8 13:09:54 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (lookup_field): Use IDENTIFIER_CLASS_VALUE to look up
+ things in a type being defined.
+ * decl.c (finish_enum): Reverse the values so that they are in
+ the correct order.
+
+ * pt.c (instantiate_class_template): Don't initialize
+ BINFO_BASETYPES until the vector is filled out.
+ (unify): Don't abort on conflicting bindings, just fail.
+ (instantiate_decl): Do push_tinst_level before any tsubsting.
+
+ * method.c (build_overload_value): Handle getting a
+ TEMPLATE_CONST_PARM for a pointer.
+
+Tue Jan 7 14:00:58 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (expand_member_init): Don't give 'not a base' error for
+ templates.
+
+ * pt.c (instantiate_decl): Call import_export_decl later.
+
+ * pt.c (instantiate_class_template): Return a value.
+
+ * parse.y (extension): New rule for __extension__.
+ (extdef, unary_expr, decl, component_decl): Use it.
+
+Tue Jan 7 09:20:28 1997 Mike Stump <mrs@cygnus.com>
+
+ * class.c (base_binfo): Remove unused base_has_virtual member.
+ (finish_base_struct): Likewise.
+ (finish_struct_1): Likewise.
+
+
+
+Copyright (C) 1997 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-1998 b/gcc-4.9/gcc/cp/ChangeLog-1998
new file mode 100644
index 000000000..008f5c360
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-1998
@@ -0,0 +1,6894 @@
+Tue Dec 22 15:09:25 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (cvt.o): Depend on toplev.h.
+
+ * cp-tree.h (check_template_shadow, pod_type_p): Add prototypes.
+
+ * cvt.c: Include toplev.h.
+
+ * except.c (get_eh_caught, get_eh_handlers): Hide prototypes and
+ definitions.
+
+ * init.c (expand_vec_init): Initialize variable `itype'.
+
+ * lex.c (yyerror): Cast the argument passed to a ctype function to
+ an unsigned char.
+
+ * method.c (build_mangled_C9x_name): Wrap prototype and definition
+ in "HOST_BITS_PER_WIDE_INT >= 64".
+
+ * typeck.c (build_binary_op): Mark parameter `convert_p' with
+ ATTRIBUTE_UNUSED.
+
+1998-12-22 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (TYPE_RAISES_EXCEPTIONS): Improve documentation.
+ * tree.c (build_exception_variant): Don't crash on empty throw
+ specs.
+
+1998-12-18 DJ Delorie <dj@cygnus.com>
+
+ * cvt.c (convert_to_reference): Check for both error_mark_node
+ and NULL_NODE after call to convert_for_initialization.
+
+1998-12-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * error.c (interesting_scope_p): New fn.
+ (dump_simple_decl): Use it.
+ (dump_expr, case CONSTRUCTOR): Force a & for a PMF.
+ (dump_expr, case OFFSET_REF): Print ->* if appropriate.
+
+1998-12-16 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (resolve_address_of_overloaded_function): Do conversion
+ to correct type here, rather than ...
+ (instantiate_type): Here.
+
+ * cp-tree.h (DECL_TEMPLATE_PARM_P): New macro.
+ (DECL_TEMPLATE_TEMPLATE_PARM_P): Use it.
+ (decl_template_parm_p): Remove.
+ * decl.c (pushdecl): Don't set DECL_CONTEXT for a template
+ parameter.
+ * lex.c (do_identifier): Use DECL_TEMPLATE_PARM_P.
+ * pt.c (push_inline_template_parms_recursive): Set it.
+ (decl_template_parm_p): Remove.
+ (check_template_shadow): Use DECL_TEMPLATE_PARM_P.
+ (process_template_parm): Set it.
+
+Wed Dec 16 16:33:58 1998 Dave Brolley <brolley@cygnus.com>
+
+ * lang-specs.h (default_compilers): Pass -MD, -MMD and -MG to cc1plus
+ if configured with cpplib.
+
+1998-12-15 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (poplevel): Make sure ns_binding is initialized.
+
+ * decl.c (finish_function): Undo inadvertent change in previous
+ patch.
+
+1998-12-14 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (pushclass): Tweak handling of class-level bindings.
+ (resolve_address_of_overloaded_function): Update pointer-to-member
+ handling.
+ (instantiate_type): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ * decl.c (pop_binding): Take the DECL to pop, not just the name.
+ Deal with `struct stat' hack.
+ (binding_level): Add to documentation.
+ (push_binding): Clear BINDING_TYPE.
+ (add_binding): New function.
+ (push_local_binding): Use it.
+ (push_class_binding): Likewise.
+ (poplevel): Adjust calls to pop_binding.
+ (poplevel_class): Likewise.
+ (pushdecl): Adjust handling of TYPE_DECLs; add bindings for hidden
+ declarations to current binding level.
+ (push_class_level_binding): Likewise.
+ (push_overloaded_decl): Adjust handling of OVERLOADs in local
+ bindings.
+ (lookup_namespace_name): Don't crash when confronted with a
+ TEMPLATE_DECL.
+ (lookup_name_real): Do `struct stat' hack in local binding
+ contexts.
+ (build_ptrmemfunc_type): Adjust documentation.
+ (grokdeclarator): Don't avoid building real array types when
+ processing templates unless really necessary.
+ (finish_method): Adjust calls to pop_binding.
+ * decl2.c (reparse_absdcl_as_expr): Recursively call ourselves,
+ not reparse_decl_as_expr.
+ (build_expr_from_tree): Deal with a template-id as the function to
+ call in a METHOD_CALL_EXPR.
+ * pt.c (convert_nontype_argument): Tweak pointer-to-member handling.
+ (maybe_adjust_types_For_deduction): Don't do peculiar things with
+ METHOD_TYPEs here.
+ (resolve_overloaded_unification): Handle COMPONENT_REFs. Build
+ pointer-to-member types where necessary.
+ * tree.c (build_cplus_array_type_1): Don't avoid building real
+ array types when processing templates unless really necessary.
+ (build_exception_variant): Compare the exception lists correctly.
+
+1998-12-13 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.def (CPLUS_BINDING): Update documentation.
+ * cp-tree.h (LOCAL_BINDING_P): New macro.
+ (lang_identifier): Rename local_value to bindings.
+ (tree_binding): Make `scope' of type `void*', not `tree'.
+ (BINDING_SCOPE): Update documentation.
+ (IDENTIFIER_LOCAL_VALUE): Remove.
+ (IDENTIFIER_CLASS_VALUE): Document.
+ (IDENTIFIER_BINDING): New macro.
+ (IDENTIFIER_VALUE): Likewise.
+ (TIME_IDENTIFIER_TIME): Likewise.
+ (TIME_IDENTIFIER_FILEINFO): Likewise.
+ (IMPLICIT_TYPENAME_P): Likewise.
+ (set_identifier_local_value): Remove.
+ (push_local_binding): New function.
+ (push_class_binding): Likewise.
+ * class.c (pushclass): Update comments; use push_class_binding.
+ * decl.c (set_identifier_local_value_with_scope): Remove.
+ (set_identifier_local_value): Likewise.
+ (push_binding): New function.
+ (pop_binding): Likewise.
+ (binding_level): Update documentation. Remove shadowed.
+ (BINDING_LEVEL): New macro.
+ (free_binding_nodes): New variable.
+ (poplevel): Adjust for new name-lookup scheme. Don't mess up
+ BLOCK_VARs when doing for-scope extension. Remove effectively
+ dead code.
+ (pushlevel_class): Tweak formatting.
+ (poplevel_class): Adjust for new name-lookup scheme.
+ (print_binding_level): Likewise.
+ (store_bindings): Likewise.
+ (pushdecl): Likewise.
+ (pushdecl_class_level): Likewise.
+ (push_class_level_binding): Likewise.
+ (push_overloaded_decl): Update comments. Adjust for new
+ name-lookup scheme.
+ (lookup_name_real): Likewise.
+ (lookup_name_current_level): Likewise.
+ (cp_finish_decl): Likewise.
+ (require_complete_types_for_parms): Likewise. Remove misleading
+ #if 0'd code.
+ (grok_parms): Likewise. Don't call
+ require_complete_types_for_parms here.
+ (grok_ctor_properties): Don't treat templates as copy
+ constructors.
+ (grop_op_properties): Or as assignment operators.
+ (start_function): Document. Adjust for new name-lookup scheme.
+ (finish_function): Likewise.
+ * decl2.c (do_local_using_decl): Use push_local_binding.
+ * lex.c (begin_definition_of_inclass_inline): New function, split
+ out from ...
+ (do_pending_inlines): Here, and ...
+ (process_next_inline): Here.
+ (get_time_identifier): Use TIME_IDENTIFIER_* macros.
+ (init_filename_times): Likewise.
+ (extract_interface_info): Likewise.
+ (ste_typedecl_interface_info): Likewise.
+ (check_newline): Likewise.
+ (dump_time_statistics): Likewise.
+ (handle_cp_pragma): Likewise.
+ (do_identifier): Adjust for new name-lookup scheme.
+ * parse.y (function_try_block): Return ctor_initializer_opt value.
+ (fndef): Use it.
+ (fn.defpen): Pass appropriate values to start_function.
+ (pending_inline): Use functor_try_block value, and pass
+ appropriate values to finish_function.
+ * pt.c (is_member_template): Update documentation; remove handling
+ of FUNCTION_DECLs. As per name, this function should deal only in
+ TEMPLATE_DECLs.
+ (decl_template_parm_p): Change name of olddecl parameter to decl.
+ (check_template_shadow): Adjust for new name-lookup scheme.
+ (lookup_template_class): Likewise.
+ (tsubst_decl): Tweak so as not to confuse member templates with
+ copy constructors and assignment operators.
+ (unify): Handle UNION_TYPEs.
+ * ptree.c (print_lang_identifier): Adjust for new name-lookup scheme.
+ (lang_print_xnode): Adjust for new name-lookup scheme.
+ * typeck.c (mark_addressable): Likewise.
+ (c_expand_return): Likewise.
+
+1998-12-08 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Allow field with same name as class
+ in extern "C".
+
+ * decl.c (lookup_name_real): Don't limit field lookup to types.
+ * class.c (check_member_decl_is_same_in_complete_scope): No error
+ if icv and x are the same.
+ * lex.c (do_identifier): Tweak error message.
+
+1998-12-10 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (start_enum): Use push_obstacks, not
+ end_temporary_allocation.
+ (finish_enum): Call pop_obstacks.
+
+1998-12-10 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (instantiate_type): Return error_mark_node rather than
+ junk.
+
+1998-12-09 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (most_specialized_instantiation): New function.
+ (print_candidates): Likewise.
+ * class.c (validate_lhs): Remove.
+ (resolve_address_of_overloaded_function): New function, split out
+ and then substantially reworked, from ...
+ (instantiate_type): Use it. Simplify.
+ * cvt.c (convert_to_reference): Complain when caller has indicated
+ that's the right thing to do. Don't crash if instantiate_type
+ fails.
+ * pt.c: Substitute `parameters' for `paramters' throughout.
+ (print_candidates): Don't make it static.
+ (most_specialized_instantiation): Split out from ...
+ (most_specialized): Here.
+
+Wed Dec 9 15:33:01 1998 Dave Brolley <brolley@cygnus.com>
+
+ * lex.c (lang_init_options): Initialize cpplib.
+ * decl2.c (parse_options,cpp_initialized): Removed.
+ (lang_decode_option): Move initialization of cpplib to
+ lang_init_options.
+
+1998-12-09 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokdeclarator): Update the name of the TEMPLATE_DECL, as
+ well as the TYPE_DECL, when a typedef name is assigned to a
+ previously anonymous type.
+
+1998-12-08 Andrew MacLeod <amacleod@cygnus.com>
+
+ * cp/except.c (call_eh_info): Use __start_cp_handler instead of
+ __cp_eh_info for getting the eh info pointer. Add table_index to
+ field list.
+ (push_eh_cleanup): Don't increment 'handlers' data field.
+ (process_start_catch_block): Don't set the 'caught' field.
+
+ * cp/exception.cc (CP_EH_INFO): New macro for getting the
+ exception info pointer within library routines.
+ (__cp_eh_info): Use CP_EH_INFO.
+ (__start_cp_handler): Get exception info pointer, set caught field,
+ and increment the handlers field. Avoids this being done by handlers.
+ (__uncatch_exception, __check_eh_spec): Use CP_EH_INFO macro.
+ (uncaught_exception): Use CP_EH_INFO macro.
+
+Tue Dec 8 10:48:21 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Make-lang.in (cxxmain.o): Depend on $(DEMANGLE_H), not demangle.h
+
+Mon Dec 7 17:56:06 1998 Mike Stump <mrs@wrs.com>
+
+ * lex.c (check_newline): Add support for \ as `natural'
+ characters in file names in #line to be consistent with #include
+ handling. We support escape processing in the # 1 "..." version of
+ the command. See also support in cp/lex.c.
+
+1998-12-07 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cp/decl2.c: s/data/opts/ when initializing cpp_reader
+ structure.
+
+1998-12-07 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (build_typename_type): Set DECL_ARTIFICIAL.
+
+ * error.c (dump_simple_decl): Also print namespace context.
+ (dump_function_decl): Likewise.
+
+ * decl2.c (ambiguous_decl): Don't print old value if it's
+ error_mark_node.
+
+ * decl.c (lookup_name_real): Fix handling of local types shadowed
+ by a non-type decl. Remove obsolete code.
+ * cp-tree.h (DECL_FUNCTION_SCOPE_P): New macro.
+
+ * lang-options.h: Add -fpermissive.
+ * decl2.c: Likewise.
+ * cp-tree.h: Add flag_permissive.
+ * decl.c (init_decl_processing): If neither -fpermissive or -pedantic
+ were specified, set flag_pedantic_errors.
+ * call.c (build_over_call): Turn dropped qualifier messages
+ back into pedwarns.
+ * cvt.c (convert_to_reference): Likewise.
+ * typeck.c (convert_for_assignment): Likewise.
+
+1998-12-05 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (coerce_new_type): Use same_type_p.
+ (coerce_delete_type): Likewise.
+
+ * call.c (check_dtor_name): Return 1, not error_mark_node.
+
+1998-12-04 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (handle_cp_pragma): Disable #pragma interface/implementation
+ if MULTIPLE_SYMBOL_SPACES.
+
+ * pt.c (check_template_shadow): New fn.
+ * decl2.c (grokfield): Use it.
+ * decl.c (pushdecl): Likewise.
+ (pushdecl_class_level): Likewise.
+ (start_method): Likewise.
+ (xref_tag): Don't try to use 't' if we're defining.
+
+ * call.c (check_dtor_name): Just return an error_mark_node.
+ * pt.c (lookup_template_class): Complain about using non-template here.
+ * parse.y (apparent_template_type): Not here.
+
+ * pt.c (check_explicit_specialization): Complain about specialization
+ with C linkage.
+
+ * lang-options.h: Add -f{no-,}implicit-inline-templates.
+
+ * pt.c (convert_nontype_argument): Don't assume that any integer
+ argument is intended to be a constant-expression.
+
+1998-12-03 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (handle_using_decl): Fix comment. Don't lookup
+ constructors in base classes.
+ (validate_lhs): Fix typo in comment.
+ * search.c (lookup_field_1): Don't return a USING_DECL.
+
+ * cp-tree.h (DECL_ACCESS): Improve documentation.
+
+ * decl.c (expand_static_init): Don't set the initialization-done
+ flag until the initialization is done.
+
+1998-12-02 Mark Mitchell <mark@markmitchell.com>
+
+ * decl2.c (validate_nonmember_using_decl): Complain about using
+ declarations for class members.
+
+1998-11-29 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (process_init_constructor): Use same_type_p.
+
+ * decl.c (check_tag_decl): Don't warn about null decl inside a
+ class.
+
+ * pt.c (unify, case OFFSET_TYPE): Pass down 'strict' rather than
+ UNIFY_ALLOW_NONE.
+ (convert_nontype_argument): Use TYPE_PTRMEMFUNC_FN_TYPE.
+ (resolve_overloaded_unification): Strip baselinks.
+
+Fri Nov 27 13:07:23 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * g++spec.c: Don't prototype xmalloc.
+
+1998-11-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (expand_throw): Use TYPE_PTR_P to check for pointers.
+
+ * decl.c (check_tag_decl): Do complain about null friend decl at
+ file scope.
+
+1998-11-25 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * lex.c (make_lang_type): Clear the whole struct lang_type, not
+ only the first multiple of sizeof (int).
+
+1998-11-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_decl): An explicit specialization of a static data
+ member is only a definition if it has an initializer.
+
+ * except.c (expand_throw): Use cp_finish_decl for the throw temp.
+ * cvt.c (build_up_reference): Pass DIRECT_BIND down into
+ cp_finish_decl.
+ * init.c (expand_default_init): Check for DIRECT_BIND instead of
+ DECL_ARTIFICIAL.
+
+ * call.c (build_over_call): Use build_decl.
+
+ * except.c (expand_throw): Just use convert, not
+ build_reinterpret_cast.
+
+ * lex.c (handle_generic_pragma): Use token_buffer.
+
+ * decl.c (check_tag_decl): Don't complain about null friend decl.
+
+1998-11-24 Dave Pitts <dpitts@cozx.com>
+
+ * Make-lang.in (DEMANGLER_PROG): Move the output arguments to the
+ first position.
+ * lex.c (check_newline): Use ISALPHA.
+ (readescape): Use ISGRAPH.
+ (yyerror): Use ISGRAPH.
+
+1998-11-24 Nathan Sidwell <nathan@acm.org>
+
+ * search.c (get_abstract_virtuals): Do not use initial
+ CLASSTYPE_ABSTRACT_VIRTUALS.
+ * typeck2.c (abstract_virtuals_error): Show location of abstract
+ declaration.
+ * call.c (build_new_method_call): Use
+ CLASSTYPE_ABSTRACT_VIRTUAL, rather than recalculate.
+ * class.c (finish_struct_bits): Don't bother working out whether
+ get_abstract_virtuals will do anything, just do it.
+
+1998-11-24 Graham <grahams@rcp.co.uk>
+
+ * typeck.c (build_component_ref): Remove unused statement.
+
+1998-11-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (add_method): Catch invalid overloads.
+
+ * class.c (add_method): Build up OVERLOADs properly for conversion ops.
+ * search.c (lookup_conversions): Handle getting real OVERLOADs.
+ (add_conversions): Likewise. Revert last change.
+ * call.c (add_conv_candidate): Pass totype to add_candidate instead
+ of fn. Don't add a new candidate if the last one was for the same
+ type.
+ (print_z_candidates): Handle getting a type as a function.
+ (joust): If we got two conversion candidates to the same type,
+ just pick one.
+ (build_object_call): Lose 'templates'.
+ (build_user_type_conversion_1): Handle getting real OVERLOADs.
+
+1998-11-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (process_init_constructor): If there are elements
+ that don't have initializers and they need to have constructors
+ run, supply them with initializers.
+
+ * class.c (finish_struct_1): A class with a 0-width bitfield is
+ still empty.
+
+1998-11-23 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (instantiate_class_template): Don't try to figure out what
+ specialization to use for a partial instantiation. Correct
+ typos in a couple of comments. Avoid calling uses_template_parms
+ multiple times.
+
+1998-11-23 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * method.c (process_overload_item): Add call to
+ build_mangled_C9x_name for intTI_type_nodes.
+ (build_mangled_C9x_name): Add prototype, define.
+ * decl.c (init_decl_processing): Add names for
+ TImode_type_node.
+
+1998-11-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (named_class_head): Update CLASSTYPE_DECLARED_CLASS.
+
+ * class.c (finish_struct_1): Set things up for 0-width bitfields
+ like we do for others.
+
+ * decl.c (check_tag_decl): New fn.
+ (shadow_tag): Split out from here.
+ * decl2.c (grok_x_components): Call it.
+
+1998-11-22 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c: Lose warn_about_return_type.
+ (grokdeclarator): Always complain about implicit int, except for
+ `main () { ... }'.
+
+ * decl.c (tag_name): New fn.
+ (xref_tag): Complain about using typedef-name after class-key.
+
+ * init.c (expand_vec_init): Also keep going if from_array.
+
+ * tree.c (is_overloaded_fn): Also handle the output of
+ build_offset_ref.
+
+ * decl.c (grokdeclarator): Use constructor_name when comparing
+ field name against enclosing class.
+ * class.c (finish_struct_anon): Likewise.
+
+1998-11-22 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (poplevel): Remove code to handle KEEP == 2.
+ (finish_function): Don't confuse BLOCK-order when
+ processing a destructor.
+
+1998-11-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (require_complete_types_for_parms): Call layout_decl
+ after we've completed the type.
+
+1998-11-21 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl2.c (validate_nonmember_using_decl): Allow using templates
+ from the global namespace.
+
+1998-11-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ Handle specifying template args to member function templates.
+ * tree.c (build_overload): Always create an OVERLOAD for a template.
+ * search.c (add_conversions): Handle finding an OVERLOAD.
+ * decl2.c (check_classfn): Likewise.
+ * lex.c (identifier_type): See through a baselink.
+ * parse.y (do_id): Don't call do_identifier if we got a baselink.
+ * class.c (instantiate_type, case TREE_LIST): Recurse.
+
+ * decl.c (grokdeclarator): Allow a boolean constant for array
+ bounds, odd as that sounds.
+
+ * pt.c (unify): Be more strict about non-type parms, except for
+ array bounds.
+ (UNIFY_ALLOW_INTEGER): New macro.
+
+1998-11-19 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Make-lang.in (mandir): Replace all uses of $(mandir) by $(man1dir).
+
+1998-11-19 Jason Merrill <jason@yorick.cygnus.com>
+
+ * semantics.c (begin_class_definition): Call
+ maybe_process_partial_specialization before push_template_decl.
+ Don't call push_template_decl for a specialization.
+ * search.c (lookup_field): Do return a member template class.
+ * decl2.c (handle_class_head): Handle member template classes.
+
+ * decl.c (grokdeclarator): A parm type need not be complete.
+
+ * pt.c (convert_nontype_argument): Fix thinko.
+
+1998-11-18 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (PTRMEM_CST_CLASS): Fix typo.
+ (global_delete_fndecl): New variable.
+ * decl.c (global_delete_fndecl): Define it.
+ (init_decl_processing): Set it.
+ * init.c (build_builtin_delete_call): Use it.
+ * tree.c (mapcar): Recursively call mapcar for the type of EXPR
+ nodes.
+
+1998-11-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (cplus_expand_expr_stmt): Always complain about unresolved
+ type.
+
+ * tree.c (lvalue_p_1): An INDIRECT_REF to a function is an lvalue.
+ * call.c (build_object_call): Also support references to functions.
+ * typeck.c (convert_for_initialization): Don't decay a function
+ if the target is a reference to function.
+
+ * search.c (add_conversions): Get all the overloads from a class.
+
+ * decl.c (grok_ctor_properties): Complain about any constructor
+ that will take a single arg of the class type by value.
+
+ * typeck2.c (build_functional_cast): Can't create objects of
+ abstract classes this way.
+ * cvt.c (ocp_convert): Likewise.
+
+ * decl.c (grokfndecl): Member functions of local classes are not
+ public.
+
+1998-11-18 Mark Mitchell <mark@markmitchell.com>
+
+ * Make-lang.in (cc1plus): Add dependency on hash.o.
+
+1998-11-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (get_abstract_virtuals): Complain about virtuals with
+ no final overrider.
+ * typeck2.c (abstract_virtuals_error): Remove handling for virtuals
+ with no final overrider.
+ * class.c (override_one_vtable): Don't set DECL_ABSTRACT_VIRTUAL_P
+ on virtuals with no final overrider.
+
+ * lex.c (reinit_parse_for_block): Add a space after the initial ':'.
+
+ * class.c (finish_struct_1): Don't remove zero-width bit-fields until
+ after layout_type.
+
+ * friend.c (do_friend): Don't set_mangled_name_for_decl.
+
+ * class.c (finish_struct_anon): Complain about non-fields.
+ * decl2.c (build_anon_union_vars): Likewise.
+
+ * decl.c (grokdeclarator): Normal data members can't have the same
+ name as the class, either.
+ * class.c (finish_struct_anon): Neither can members of an
+ anonymous union.
+
+1998-11-17 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (TYPE_ALIAS_SET): Document language-dependent uses.
+ (TYPE_BINFO): Likewise.
+ (IS_AGGR_TYPE): Tweak.
+ (SET_IS_AGGR_TYPE): New macro.
+ (CLASS_TYPE_P): Tweak.
+ (lang_type): Group mark bitfields together. Remove linenum.
+ (CLASSTYPE_SOURCE_LINE): Remove macro.
+ (CLASSTYPE_MARKED_N): New macro.
+ (SET_CLASSTYPE_MARKED_N): Likewise.
+ (CLEAR_CLASSTYPE_MARKED_N): Likewise.
+ (CLASS_TYPE_MARKED_*): Use them.
+ (SET_CLASSTYPE_MARKED_*): Likewise.
+ (CLEAR_CLASSTYPE_MARKED_*): Likewise.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
+ (TYPE_TEMPLATE_INFO): Handle TEMPLATE_TEMPLATE_PARMs as well.
+ (TYPENAME_TYPE_FULLNAME): Use TYPE_BINFO rather than CLASSTYPE_SIZE.
+ * class.c (class_cache_obstack): New variable.
+ (class_cache_firstobj): Likewise.
+ (finish_struct): Don't set CLASSTYPE_SOURCE_LINE.
+ (pushclass): Free the cache, when appropriate.
+ (popclass): Tidy.
+ (maybe_push_cache_obstack): Use class_cache_obstack.
+ * decl.c (include hash.h).
+ (typename_hash): New function.
+ (typename_compare): Likewise.
+ (build_typename_type): Check the hash table to avoid creating
+ duplicates.
+ (build_ptrmemfunc_type): Use SET_IS_AGGR_TYPE.
+ (grokdeclarator): Use CLASS_TYPE_P.
+ (xref_basetypes): Likewise.
+ (start_function): Likewise. Don't put current_class_ref on the
+ permanent obstack.
+ * error.c (dump_type_real): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO
+ and TYPE_TI_ARGS.
+ * lex.c (note_got_semicolon): Use CLASS_TYPE_P.
+ (make_lang_type): Don't create TYPE_LANG_SPECIFIC and associated
+ fields for types other than class types. Do clear TYPE_ALIAS_SET
+ for types other than class types, though.
+ * method.c (build_overload_identifier): Use CLASS_TYPE_P and
+ TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ * pt.c (process_template_parm): Don't set
+ CLASSTYPE_GOT_SEMICOLON.
+ (lookup_template_class): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ Coerce arguments on the momentary obstack.
+ (for_each_template_parm): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ (instantiate_class_template): Calculate template arguments on the
+ momentary obstack. Tidy.
+ (tsubst_template_arg_vector): Use make_temp_vec.
+ (tsubst_aggr_type): Put template arguments on the momentary
+ obstack.
+ (tsubst_decl): Likewise.
+ (tsubst): Copy the array bounds index to the permanent obstack
+ before building index types. Use new macros.
+ (unify): Use new macros.
+ (do_type_instantiation): Likewise.
+ * search.c (lookup_fnfields_1): Use new macros.
+ (dfs_pushdecls): Build envelopes on the cache obstack.
+ (dfs_compress_decls): Use new macros.
+ (push_class_decls): Build on the cache obstack.
+ * semantics.c (finish_typeof): Don't set CLASSTYPE_GOT_SEMICOLON.
+ * sign.c (build_signature_pointer_or_reference_type): Use
+ SET_IS_AGGR_TYPE.
+ * tree.c (make_binfo): Check CLASS_TYPE_P.
+ (copy_template_template_parm): Adjust.
+ (make_temp_vec): Use push_expression_obstack.
+ * typeck.c (complete_type): Use new macros.
+ (comptypes): Likewise.
+
+1998-11-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Add diagnostics for invalid array, reference
+ and pointer to member types.
+
+1998-11-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (my_friendly_abort): Don't fatal twice in a row.
+
+ * typeck.c (c_expand_start_case): Use build_expr_type_conversion.
+ Simplify.
+
+ * parse.y (structsp): Fix cut-and-paste error.
+
+ * init.c (build_new): Complain about non-integral size.
+
+ * parse.y (unary_expr): Complain about defining types in sizeof.
+
+ * typeck.c (expr_sizeof): Complain about sizeof an overloaded fn.
+
+ * rtti.c (build_x_typeid): Complain about typeid without
+ including <typeinfo>.
+ (get_typeid): Likewise. Complain about typeid of incomplete type.
+ (get_tinfo_fn_dynamic): Likewise.
+ (get_typeid_1): Not static anymore.
+ * except.c (build_eh_type_type): Use get_typeid_1.
+
+ * rtti.c (build_dynamic_cast_1): Give errors for dynamic_cast to
+ ambiguous or private bases. Fix warning for reference cast.
+
+1998-11-16 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (DECL_TEMPLATE_INSTANTIATED): New macro.
+ * decl.c (duplicate_decls): Remove special-case code to deal with
+ template friends, and just do the obvious thing.
+ * pt.c (register_specialization): Tweak for clarity, and also to
+ clear DECL_INITIAL for an instantiation before it is merged with a
+ specialization.
+ (check_explicit_specialization): Fix indentation.
+ (tsubst_friend_function): Handle both definitions in friend
+ declaration and outside friend declarations.
+ (tsubst_decl): Don't clear DECL_INITIAL for an instantiation.
+ (regenerate_decl_from_template): Tweak accordingly.
+ (instantiate_decl): Likewise.
+
+1998-11-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (cplus_expand_expr_stmt): Promote warning about naked
+ member function reference to error.
+ * cvt.c (ocp_convert): Complain about converting an overloaded
+ function to void.
+
+ * init.c (build_offset_ref): Just return a lone static member
+ function.
+
+ * decl.c (cp_finish_decl): Only complain about real CONSTRUCTORs,
+ not internal ones.
+
+ * typeck.c (build_binary_op_nodefault): Improve error handling.
+
+ * decl.c (grokfndecl): Complain about making 'main' a template.
+
+ * typeck.c (string_conv_p): Don't convert from wchar_t[] to char*.
+
+ * call.c (build_method_call): Handle a BIT_NOT_EXPR around a
+ TYPE_DECL in a template.
+
+1998-11-15 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (my_friendly_abort): Add URL in the other case, too.
+
+ * decl.c (struct cp_function): Add named_label_uses.
+ (push_cp_function_context): Save it.
+ (pop_cp_function_context): Restore it.
+ (define_label): Also complain about jumping into the scope of
+ non-POD objects that don't have constructors.
+ * tree.c (pod_type_p): New fn.
+
+ * pt.c (instantiate_class_template): Clear TYPE_BEING_DEFINED sooner.
+ * rtti.c (synthesize_tinfo_fn): Call import_export_decl here.
+ (get_tinfo_fn): Not here.
+ * repo.c (repo_get_id): Abort if we get called for an incomplete
+ type.
+
+1998-11-13 Mark Mitchell <mark@markmitchell.com>
+
+ * except.c (expand_throw): Make sure first argument to
+ __cp_push_exception is of type `void*' to avoid spurious error
+ messages.
+
+1998-11-11 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (try_one_overload): Take orig_targs again. Only check for
+ mismatches against them; we don't care what a previous call found.
+ (resolve_overloaded_unification): Adjust.
+
+ * search.c (lookup_field): Don't return anything for a non-type
+ field from a dependent type.
+ * decl.c (grokdeclarator): Resolve SCOPE_REFs of the current class
+ in an array declarator.
+ (start_decl): Push into the class before looking for the field.
+
+1998-11-08 Mark Mitchell <mark@markmitchell.com>
+
+ * method.c (build_overload_value): Handle REFERENCE_TYPE.
+
+1998-11-08 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (grokdeclarator): Allow namespace-scoped members if they
+ are friends.
+
+1998-11-08 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst_decl): Don't mess with the global value of an
+ un-mangled DECL_ASSEMBLER_NAME.
+
+1998-11-03 Christopher Faylor <cgf@cygnus.com>
+
+ * decl.c (init_decl_processing): Remove CYGWIN conditional
+ since CYGWIN is now able to deal with trapping signals.
+
+Sat Nov 7 15:48:02 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h: Don't include gansidecl.h.
+ * exception.cc: Include gansidecl.h (since we don't include config.h)
+ * g++spec.c: Don't include gansidecl.h.
+
+1998-11-06 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (lang_decl_flags): Add defined_in_class. Decrease
+ size of dummy.
+ (DECL_DEFINED_IN_CLASS_P): New macro.
+ (TEMPLATE_PARMS_FOR_INLINE): Document.
+ (check_static_variable_definition): New function.
+ * decl.c (cp_finish_decl): Set DECL_DEFINED_IN_CLASS_P, if
+ appropriate.
+ (check_static_variable_definition): Split out from ...
+ (grokdeclarator): Here.
+ * pt.c (check_default_tmpl_args): New function, split out from ...
+ (push_template_decl_real): Here.
+ (instantiate_template): Fix comment.
+
+1998-11-04 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (CP_TYPE_CONST_P): Make {0,1}-valued.
+ (CP_TYPE_VOLATILE_P): Likewise.
+ (CP_TYPE_RESTRICT_P): Likewise.
+
+1998-11-03 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (tsubst): Use build_index_type, not build_index_2_type.
+
+1998-11-02 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (instantiate_type): Be more helpful.
+
+ * decl2.c (import_export_decl): Call import_export_class.
+
+ * cp-tree.h (EMPTY_CONSTRUCTOR_P): Check !TREE_HAS_CONSTRUCTOR.
+ * decl2.c (build_expr_from_tree): Propagate TREE_HAS_CONSTRUCTOR.
+ * pt.c (tsubst_copy): Likewise.
+
+1998-11-02 Mark Mitchell <mark@markmitchell.com>
+
+ * init.c (expand_vec_init): Fix off-by-one error.
+
+1998-11-02 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * parse.y (apparent_template_type): New type.
+ (named_complex_class_head_sans_basetype): Use it.
+ * Makefile.in (CONFLICTS): One new conflict.
+ * parse.c: Regenerated.
+
+1998-11-01 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (COMPARE_STRICT): New macro.
+ (COMPARE_BASE): Likewise.
+ (COMPARE_RELAXED): Likewise.
+ (COMPARE_REDECLARATION): Likewise.
+ (same_type_p): Likewise.
+ (same_or_base_type_p): Likewise.
+ * call.c (standard_conversion): Use them, in place of comptypes
+ with numeric arguments.
+ (reference_binding): Likewise.
+ (convert_like): Likewise.
+ (build_over_call): Likewise.
+ (is_subseq): Likewise.
+ (is_properly_derived_from): Likewise.
+ (compare_ics): Likewise.
+ (joust): Likewise.
+ * class.c (delete_duplicate_fields_1): Likewise.
+ (resolves_to_fixed_type_p): Likewise.
+ (instantiate_type): Likewise. Remove #if 0'd code.
+ * decl.c (decls_match): Likewise. Use COMPARE_REDECLARATION here.
+ (pushdecl): Likewise.
+ (lookup_name_real): Likewise.
+ (grokdeclarator): Likewise. Check for illegal array declarations.
+ (grokparms): Likewise.
+ (grok_op_properties): Likewise.
+ * decl2.c (check_classfn): Likewise.
+ * friend.c (is_friend): Likewise.
+ (make_friend_class): Likewise.
+ * init.c (expand_aggr_init): Likewise.
+ (expand_vec_init): Likewise.
+ * pt.c (is_member_template_class): Remove declaration.
+ (is_specialization_of): Use COMPARE_* and new macros.
+ (comp_template_parms): Likewise.
+ (convert_nontype_argument): Likewise.
+ (coerce_template_template_parms): Likewise.
+ (template_args_equal): Likewise.
+ (lookup_template_class): Likewise.
+ (type_unification_real): Likewise.
+ (unify): Likewise.
+ (get_bindings_real): Likewise.
+ * search.c (covariant_return_p): Likewise.
+ (get_matching_virtual): Likewise.
+ * sig.c (match_method_types): Likewise.
+ * tree.c (vec_binfo_member): Likewise.
+ (cp_tree_equal): Likewise.
+ * typeck.c (common_type): Likewise.
+ (comp_array_types): Likewise. Get issues involving unknown array
+ bounds right.
+ (comptypes): Update comments. Use new flags.
+ (comp_target_types): Use new macros.
+ (compparms): Likewise.
+ (comp_target_parms): Likewise.
+ (string_conv_p): Likewise.
+ (build_component_ref): Likewise.
+ (build_indirect_ref): Likewise.
+ (build_conditional_expr): Likewise.
+ (build_static_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (build_modify_expr): Likewise.
+ (convert_for_assignment): Likewise.
+ (comp_ptr_ttypes_real): Likewise.
+ (ptr_reasonably_similar): Likewise.
+ (comp_ptr_ttypes_const): Likewise.
+
+1998-10-31 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (build_dynamic_cast_1): Fix cut-and-paste error.
+
+1998-10-30 Mark Mitchell <mark@markmitchell.com>
+
+ * decl2.c (delete_sanity): Pass integer_zero_node, not
+ integer_two_node, to build_vec_delete.
+ * init.c (build_array_eh_cleanup): Remove.
+ (expand_vec_init_try_block): New function.
+ (expand_vec_init_catch_clause): Likewise.
+ (build_vec_delete_1): Don't deal with case that auto_delete_vec
+ might be integer_two_node anymore.
+ (expand_vec_init): Rework for initialization-correctness and
+ exception-correctness.
+ * typeck2.c (process_init_constructor): Make mutual exclusivity
+ of cases more obvious.
+
+1998-10-29 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_name_real): OK, only warn if not lexing.
+ Simplify suggested fix.
+
+ * cp-tree.h (IDENTIFIER_MARKED): New macro.
+ * search.c (lookup_conversions): Use breadth_first_search.
+ (add_conversions): Avoid adding two conversions to the same type.
+ (breadth_first_search): Work with base binfos, rather
+ than binfos and base indices.
+ (get_virtual_destructor): Adjust.
+ (tree_has_any_destructor_p): Adjust.
+ (get_matching_virtual): Adjust.
+
+ * pt.c (push_template_decl_real): Generalize check for incorrect
+ number of template parms.
+ (is_member_template_class): #if 0.
+
+1998-10-29 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.in (cc1plus): Put CXX_OBJS, and thence @extra_cxx_objs@,
+ last.
+
+1998-10-28 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * lex.c: Call check_newline from lang_init always. After
+ calling cpp_start_read, set yy_cur and yy_lim to read from the
+ cpplib token buffer.
+
+1998-10-28 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (instantiate_type): Don't consider templates for a normal
+ match.
+
+ * class.c (finish_struct_1): Don't complain about non-copy
+ assignment ops in union members.
+
+ * class.c (build_vtable): Don't pass at_eof to import_export_vtable.
+ (prepare_fresh_vtable): Likewise.
+ (finish_struct_1): Don't call import_export_class.
+ * decl2.c (finish_vtable_vardecl): Do import/export stuff.
+ (finish_prevtable_vardecl): Lose.
+ (finish_file): Don't call it.
+ * pt.c (instantiate_class_template): Likewise.
+ * cp-tree.h: Remove it.
+
+ * init.c (build_delete): Reset TYPE_HAS_DESTRUCTOR here.
+ * decl.c (finish_function): Not here.
+ (start_function): Do set DECL_INITIAL.
+
+ * pt.c (push_template_decl_real): Complain about default template
+ args for enclosing classes.
+
+ * call.c (add_function_candidate): Treat conversion functions
+ as coming from the argument's class.
+ * cp-tree.h (DECL_CONV_FN_P): New fn.
+ (DECL_DESTRUCTOR_P): Also check DECL_LANGUAGE.
+ * class.c (add_method): Use DECL_CONV_FN_P.
+ * decl2.c (check_classfn): Likewise.
+ * error.c (dump_function_name): Likewise.
+ (dump_function_decl): Likewise.
+ * pt.c (fn_type_unification): Likewise.
+ * search.c (add_conversions): Likewise.
+
+1998-10-27 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (do_identifier): Also generate LOOKUP_EXPR for RESULT_DECL.
+ * method.c (hack_identifier): Also check for using RESULT_DECL
+ from outer context.
+
+1998-10-27 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokdeclarator): Use type_quals, rather than constp,
+ consistently.
+
+1998-10-27 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (standard_conversion): instantiate_type here.
+ (reference_binding): And here.
+ (implicit_conversion): Not here.
+ (build_op_delete_call): No need to cons up an OVERLOAD.
+ * cvt.c (cp_convert_to_pointer): instantiate_type here.
+ (convert_to_reference): And here.
+ * decl.c (grok_reference_init): Not here.
+ (grokparms): Or here.
+ * typeck2.c (digest_init): Or here.
+ * typeck.c (decay_conversion): Take the address of overloaded
+ functions, too.
+ (require_instantiated_type): Lose.
+ (convert_arguments): Don't handle unknown types here.
+ (build_c_cast): Likewise.
+ (build_binary_op): Gut.
+ (build_conditional_expr): Don't require_instantiated_type.
+ (build_modify_expr): Likewise.
+ (build_static_cast): Don't instantiate_type.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (convert_for_initialization): Likewise.
+ (build_ptrmemfunc): Use type_unknown_p.
+ (convert_for_assignment): Also do default_conversion on overloaded
+ functions. Hand them off to ocp_convert.
+
+1998-10-26 Mark Mitchell <mark@markmitchell.com>
+
+ * error.c (dump_decl): Deal with TEMPLATE_DECLs that are
+ VAR_DECLs. Handle vtables whose DECL_CONTEXT is not a type.
+
+ * class.c (finish_struct_1): Use build_cplus_array_type to build
+ array types.
+ * decl.c (init_decl_processing): Likewise.
+ * except.c (expand_end_eh_spec): Likewise.
+ * search.c (expand_upcast_fixups): Simplify very slightly.
+
+1998-10-26 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Complain about a variable using
+ constructor syntax coming back null from start_decl.
+
+ * friend.c (make_friend_class): Complain about trying to make
+ a non-class type a friend.
+
+ * decl.c (grokfndecl): Set DECL_INITIAL for a defn here.
+ (start_function): Not here.
+
+1998-10-26 Brendan Kehoe <brendan@cygnus.com>
+
+ * decl.c (grokdeclarator): Disallow `explicit' in a friend declaration.
+
+1998-10-26 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (process_init_constructor): Only skip anonymous fields
+ if they are bitfields.
+
+ * cp-tree.def (TYPEOF_TYPE): New code.
+ * error.c (dump_type_real): Handle it.
+ * pt.c (tsubst): Likewise.
+ * tree.c (search_tree): Likewise.
+ * semantics.c (finish_typeof): New fn.
+ * parse.y (typespec): Use it.
+ * cp-tree.h: Declare it.
+
+1998-10-26 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * cp-tree.h (FORMAT_VBASE_NAME): Make definition unconditional.
+
+1998-10-26 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (convert_arguments): Don't handle pmf references
+ specially.
+
+ * init.c (build_member_call): Don't try to convert to the base type
+ if it's ambiguous or pedantic.
+
+ * typeck2.c (check_for_new_type): Only depend on pedantic for
+ C-style casts.
+
+1998-10-25 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokdeclarator): Set DECL_NONCONVERTING_P for all
+ non-converting constructors.
+
+1998-10-24 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * gxxint.texi: Correct documentation for n, N, Q, and B.
+
+1998-10-23 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (condition): Convert VAR_DECL from reference to indirect
+ reference.
+
+1998-10-23 Andrew MacLeod <amacleod@cygnus.com>
+
+ * exception.cc (__cp_pop_exception): Free the original exception
+ value, not the potentially coerced one.
+
+1998-10-23 Mark Mitchell <mark@markmitchell.com>
+
+ * Makefile.in (hash.h): Run gperf when necessary.
+
+ * cp-tree.h (CP_TYPE_READONLY): Remove.
+ (CP_TYPE_VOLATILE): Likewise.
+ (CP_TYPE_QUALS): New macro.
+ (CP_TYPE_CONST_P): Likewise.
+ (CP_TYPE_VOLATILE_P): Likewise.
+ (CP_TYPE_RESTRICT_P): Likewise.
+ (CP_TYPE_CONST_NON_VOLATILE_P): Likewise.
+ (cp_build_type_variant): Rename to ...
+ (cp_build_qualified_type): New function.
+ (c_apply_type_quals_to_decl): Declare.
+ (SIGNATURE_POINTER_NAME_FORMAT): Modify to allow `restrict'.
+ (SIGNATURE_REFERENCE_NAME_FORMAT): Likewise.
+ (cp_type_qual_from_rid): New function.
+ (compparms): Remove unused parameter. All callers changed.
+ (cp_type_quals): New function.
+ (at_least_as_qualified_p): Likewise.
+ (more_qualified_p): Likewise.
+
+ * call.c (standard_conversion): Replace calls to
+ cp_build_type_variant with cp_build_qualified_type. Use
+ CP_TYPE_QUALS to get qualifiers and at_least_as_qualified_p to
+ compare them. Use CP_TYPE_* macros to check qualifiers.
+ (reference_binding): Likewise.
+ (implicit_conversion): Likewise.
+ (add_builtin_candidates): Likewise.
+ (build_over_call): Likewise.
+ * class.c (overrides): Compare all qualifiers, not just `const',
+ on method declarations.
+ * cvt.c (convert_to_reference): More CP_TYPE_QUALS conversion, etc.
+ (convert_pointer_to_real): Likewise.
+ (type_promotes_to): Likewise.
+ * decl.c (check_for_uninitialized_const_var): New function.
+ (init_decl_processing): More CP_TYPE_QUALS conversion, etc.
+ (cp_finish_decl): Use check_for_uninitialized_const_var.
+ (grokdeclarator): More CP_TYPE_QUALS conversion, etc. Update to
+ handle `restrict'.
+ (grok_ctor_properties): Likewise.
+ (grok_op_properties): Likewise.
+ (start_function): Likewise.
+ (rever_static_member_fn): Likewise.
+ * decl2.c (grok_method_quals): Likewise.
+ (grokfield): Likewise.
+ * error.c (dump_readonly_or_volatile): Rename to ...
+ (dump_qualifiers): New function. Handle `restrict'.
+ (dump_type_real): Use it.
+ (dump_aggr_type): Likewise.
+ (dump_type_prefix): Likewise.
+ (dump_type_suffix): Likewise.
+ (dump_function_decl): Likewise.
+ (cv_as_string): Likewise.
+ * gxx.gperf: Add __restrict and __restrict__.
+ * gxxint.texi: Document `u' as used for `__restrict', and a few
+ other previously undocumented codes.
+ * hash.h: Regenerated.
+ * init.c (expand_aggr_init): More CP_TYPE_QUALS conversion, etc.
+ (build_member_call): Likewise.
+ (build_new_1): Likewise.
+ * lex.c (init_parse): Add entry for RID_RESTRICT.
+ (cons_up_default_function): More CP_TYPE_QUALS conversion, etc.
+ (cp_type_qual_from_rid): Define.
+ * lex.h (enum rid): Add RID_RESTRICT.
+ * method.c (process_modifiers): Deal with `restrict'.
+ * parse.y (primary): More CP_TYPE_QUALS conversion, etc.
+ * parse.c: Regenerated.
+ * pt.c (convert_nontype_argument): More CP_TYPE_QUALS conversion, etc.
+ (tsubst_aggr_type): Likewise.
+ (tsubst): Likewise.
+ (check_cv_quals_for_unify): Likewise.
+ (unify): Likewise.
+ * rtti.c (init_rtti_processing): Likewise.
+ (build_headof): Likewise.
+ (get_tinfo_var): Likewise.
+ (buidl_dynamic_cast_1): Likewise. Fix `volatile' handling.
+ (expand_class_desc): Likewise.
+ (expand_attr_desc): Likewise.
+ (synthesize_tinfo_fn): Likewise.
+ * search.c (covariant_return_p): Likewise. Fix `volatile' handling.
+ (get_matching_virtual): Likewise.
+ (expand_upcast_fixups): Likewise.
+ * sig.c (build_signature_pointer_or_reference_name): Take
+ type_quals, not constp and volatilep.
+ (build_signature_pointer_or_reference_type): Likewise.
+ (match_method_types): More CP_TYPE_QUALS conversion, etc.
+ (build_signature_pointer_constructor): Likewise.
+ (build_signature_method_call): Likewise.
+ * tree.c (build_cplus_array_type): Likewise.
+ (cp_build_type_variant): Rename to ...
+ (cp_build_qualified_type): New function. Deal with `__restrict'.
+ (canonical_type_variant): More CP_TYPE_QUALS conversion, etc.
+ (build_exception_variant): Likewise.
+ (mapcar): Likewise.
+ * typeck.c (qualif_type): Likewise.
+ (common_type): Likewise.
+ (comptypes): Likewise.
+ (comp_cv_target_types): Likewise.
+ (at_least_as_qualified_p): Define.
+ (more_qualified_p): Likewise.
+ (comp_cv_qualification): More CP_TYPE_QUALS conversion, etc.
+ (compparms): Likewise.
+ (inline_conversion): Likewise.
+ (string_conv_p): Likewise.
+ (build_component_ref): Likewise.
+ (build_indirect_ref): Likewise.
+ (build_array_ref): Likewise.
+ (build_unary_op): Likewise.
+ (build_conditional_expr): Likewise.
+ (build_static_cast): Likewise.
+ (build_c_cast): Likewise.
+ (build_modify_expr): Likewise.
+ (convert_For_assignment): Likewise.
+ (comp_ptr_ttypes_real): Likewise.
+ (cp_type_quals): New function.
+
+1998-10-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (CP_TYPE_READONLY): New macro to handle arrays.
+ (CP_TYPE_VOLATILE): Likewise.
+ * decl.c (grokdeclarator): Use them.
+ * tree.c (canonical_type_variant): Likewise.
+
+1998-10-22 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (named_class_head): Push into class while parsing the
+ base class list.
+ * decl2.c (push_scope, pop_scope): New functions.
+ * cp-tree.h: Declare them.
+ * init.c (build_new_1): Delay cleanup until end of full expression.
+
+1998-10-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_component_ref): Use of a type here is an error.
+
+1998-10-19 Jason Merrill <jason@yorick.cygnus.com>
+
+ Revamp references to member functions.
+ * method.c (hack_identifier): Call build_component_ref for a
+ reference to a member function.
+ * typeck.c (build_component_ref): Only return a single function
+ if it's static. Otherwise, return a COMPONENT_REF.
+ (build_x_function_call): Handle a COMPONENT_REF.
+ (build_unary_op): Handle all unknown-type things.
+ * decl2.c (arg_assoc): Handle COMPONENT_REF.
+ * class.c (instantiate_type): Complain if the function we get is a
+ nonstatic member function. Remove code for finding "compatible"
+ functions.
+ * pt.c (tsubst_copy): Handle NOP_EXPR.
+ * tree.c (build_dummy_object): New fn.
+ (maybe_dummy_object): New fn.
+ (is_dummy_object): New fn.
+ * cp-tree.h: Declare them.
+ * cvt.c (cp_convert_to_pointer): Use maybe_dummy_object.
+ * error.c (dump_expr, case OFFSET_REF): Use is_dummy_object.
+ * init.c (build_member_call): Use maybe_dummy_object and
+ is_dummy_object.
+ (build_offset_ref): Use maybe_dummy_object.
+ (resolve_offset_ref): Use is_dummy_object.
+ * typeck.c (build_x_function_call): Call build_dummy_object.
+ (unary_complex_lvalue): Call is_dummy_object.
+
+ * typeck.c (build_component_addr): Make sure field is a field.
+
+ * call.c (build_new_op): Delete obsolete code.
+
+ * pt.c (tsubst, TEMPLATE*PARM*): Abort if we don't have any args.
+
+1998-10-18 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl2.c (validate_nonmember_using_decl): Fix using-directives of
+ std if std is ignored.
+
+1998-10-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokvardecl): Fix thinko.
+
+ * decl.c (grokdeclarator): Embedded attrs bind to the right,
+ not the left.
+
+ * parse.y (fn.def2): Fix 'attrs' format.
+
+1998-10-18 Alastair J. Houghton <ajh8@doc.ic.ac.uk>
+
+ * Makefile.in (CONFLICTS): Update.
+ * parse.y (expr_or_declarator_intern): New rule.
+ (expr_or_declarator, direct_notype_declarator, primary,
+ functional_cast): Use it.
+ (notype_declarator_intern): New rule.
+ (notype_declarator, complex_notype_declarator): Use it.
+
+1998-10-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokfndecl): Set DECL_CONTEXT to namespace if appropriate.
+ (grokvardecl): Likewise.
+
+Sat Oct 17 23:27:20 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (make_method_vec): Cast 1st argument of `bzero' to (PTR).
+ (add_method): Likewise for arguments 1 & 2 of `bcopy'.
+
+ * decl.c (signal_catch): Mark with ATTRIBUTE_NORETURN.
+
+ * pt.c (process_partial_specialization): Cast 1st argument of
+ `bzero' to (PTR).
+
+ * tree.c (build_base_fields): Cast `base_align' to (int) when
+ comparing against one.
+
+1998-10-16 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (lookup_name_real): Handle template parameters for member
+ templates where said parameters have the same name as the
+ surrounding class.
+
+ * decl.c (expand_static_init): Build cleanups before entering the
+ anonymous function used to do them to avoid access-checking
+ confusion.
+
+ * decl.c (grokfndecl): Add back call to cplus_decl_attributes
+ accidentally removed by previous change, and make DECL_RTL here.
+ * class.c (add_method): Don't make DECL_RTL here.
+
+ * pt.c (for_each_template_parm): Don't examine uninstantiated
+ default arguments.
+
+1998-10-16 Dave Brolley <brolley@cygnus.com>
+
+ * lex.c (real_yylex): Fix unaligned access of wchar_t.
+
+1998-10-16 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (add_method): Fix documentation to reflect previous
+ changes. Check for duplicate method declarations here.
+ * decl.c (decls_match): Handle FUNCTION_DECL vs TEMPLATE_DECL
+ correctly; such things never match.
+ (grokfndecl): Don't look for duplicate methods here.
+ * decl2.c (check_classfn): Don't assume names are mangled.
+ Don't add bogus member function declarations to a class before the
+ class type is complete.
+ (grokfield): Reformat error message.
+ * method.c (set_mangled_name_for_decl): Don't mangle names while
+ processing_template_decl.
+
+1998-10-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_indirect_ref): Complain about a pointer to data
+ member, too.
+ * typeck2.c (build_m_component_ref): Don't indirect a pointer to
+ data member.
+ * init.c (resolve_offset_ref): Don't undo the above.
+
+ * cp-tree.h (DECL_C_BIT_FIELD, SET_DECL_C_BIT_FIELD): New macros.
+ (struct lang_decl_flags): Add `bitfield'.
+ * class.c (finish_struct_1): Use DECL_C_BIT_FIELD instead of
+ DECL_BIT_FIELD.
+ * decl2.c (grokbitfield, grok_alignof): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * typeck.c (build_component_addr, expr_sizeof): Likewise.
+ * cvt.c (build_up_reference): Don't crash if taking the address
+ returns error_mark_node.
+
+ * decl.c (grokfndecl): Also check ctype when checking for ::main().
+
+1998-10-15 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokfndecl): ::main and __builtin_* get C linkage.
+ Do mangling here.
+ (grokdeclarator): Instead of here.
+ * friend.c (do_friend): Lose special handling of ::main and
+ __builtin_*.
+ * cp-tree.h (DECL_MAIN_P): Check for C linkage.
+
+ * spew.c (yylex): Clear looking_for_typename if we got
+ 'enum { ... };'.
+
+1998-10-15 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (maybe_warn_about_overly_private_class): Improve error
+ messages for class with only private constructors.
+
+ * cp-tree.def (TYPENAME_TYPE): Add to documentation.
+ * cp-tree.h (TYPENAME_TYPE_FULLNAME): Document.
+ (build_typename_type): New function.
+ * decl.c (build_typename_type): Broken out from ...
+ (make_typename_type): Use it.
+ * search.c (lookup_field): Likewise.
+
+1998-10-14 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * pt.c (convert_nontype_argument): Check against type_referred_to.
+ * decl.c (grokvardecl): Check for declarator name before building
+ DECL_ASSEMBLER_NAME.
+
+1998-10-14 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (lookup_template_class): Add comment.
+ (instantiate_class_template): Don't mark the _TYPE node for
+ member class templates as an instantiation.
+
+1998-10-14 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokfndecl): Fix my thinko.
+
+1998-10-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo2.cc (fast_compare): Remove.
+ (before): Just use strcmp.
+ * tinfo.cc (operator==): Just use strcmp.
+
+1998-10-13 Klaus-Georg Adams <Klaus-Georg.Adams@chemie.uni-karlsruhe.de>
+
+ * decl.c (grokfndecl): Don't check for linkage in `extern "C"'
+ declarations.
+
+1998-10-13 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (specializations_of_same_template_p): Remove.
+ * search.c (get_template_base): Don't use it.
+ (get_template_base_recursive): Likewise.
+ * pt.c (specializations_of_same_template_p): Remove.
+ (unify): Don't use it.
+ (lookup_template_class): Find the correct parent when setting
+ CLASSTYPE_TI_TEMPLATE.
+
+1998-10-12 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo.cc (operator==): Always compare names.
+
+1998-10-12 Herman ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+
+ * decl.c (start_function): Fix cut-and-paste error.
+
+1998-10-12 Jason Merrill <jason@yorick.cygnus.com>
+
+ * inc/typeinfo: Add #pragma interface.
+ (operator!=): Just call operator==.
+ * tinfo.cc: Add #pragma implementation.
+ (operator==): Move from inc/typeinfo and tinfo2.cc.
+ Check __COMMON_UNRELIABLE instead of _WIN32.
+
+ * typeck2.c (my_friendly_abort): Add URL.
+
+1998-10-12 Alastair J. Houghton <ajh8@doc.ic.ac.uk>
+
+ * decl.c (start_method): Added extra parameter for attributes.
+ * cp-tree.h (start_method): Update prototype.
+ * parse.y (fn.def2): Update start_method parameter list.
+
+1998-10-11 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (specializations_of_same_template_p): Declare.
+ * pt.c (specializations_of_same_template_p): New function.
+ (unify): Use it.
+ * search.c (get_template_base): Use it.
+ (get_template_base_recursive): Likewise.
+
+1998-10-10 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * decl2.c (start_objects): Add new variable `joiner' and
+ initialize it properly.
+
+1998-10-09 Mark Mitchell <mark@markmitchell.com>
+
+ * search.c (expand_upcast_fixups): Tweak to match 1998-10-07
+ change to vtable types.
+
+ * cvt.c (ocp_convert): Avoid infinite recursion caused by
+ 1998-10-03 change.
+
+1998-10-08 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (resolve_overloaded_unification): New fn.
+ (try_one_overload): Likewise.
+ (unify): Don't fail on unknown type.
+ (type_unification_real): Likewise. Use resolve_overloaded_unification
+ to handle an overloaded argument.
+ (template_args_equal): Split out...
+ (comp_template_args): From here.
+ (determine_specialization): Also allow a template with more
+ parms than were explicitly specified.
+ * cp-tree.h: Add template_args_equal.
+ * call.c (resolve_args): Remove TEMPLATE_ID_EXPR code.
+
+Thu Oct 8 15:58:30 1998 Anthony Green <green@cygnus.com>
+
+ * semantics.c (finish_asm_stmt): Revert my 1998-09-28
+ change.
+
+Thu Oct 8 06:00:19 1998 Jeffrey A Law (law@cygnus.com)
+
+ * typeck.c (unsigned_type): Only return TItype nodes when
+ HOST_BITS_PER_WIDE_INT is >= 64 bits.
+ (signed_type): Likewise.
+ * decl.c (intTI_type_node, unsigned_intTI_type_node): Only declare
+ when HOST_BITS_PER_WIDE_INT is >= 64 bits.
+ (init_decl_processing): Only create TItype nodes when
+ HOST_BITS_PER_WIDE_INT is >= 64 bits.
+ * cp-tree.h (intTI_type_node, unsigned_intTI_type_node): Only declare
+ when HOST_BITS_PER_WIDE_INT is >= 64 bits.
+
+Wed Oct 7 12:32:44 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (hash.h): Add -L KR-C -F ', 0, 0' flags to gperf.
+ (gxx.gperf): Update comments describing invocation flags.
+ (hash.h): Regenerate using gperf 2.7.1 (19981006 egcs).
+
+1998-10-07 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (finish_struct_1): Add commentary on previous change.
+
+ * cp-tree.h (vtbl_ptr_type_node): New variable.
+ * class.c (build_vtbl_ref): Don't indirect through the vptr; it's
+ already of the right type.
+ (finish_struct_1): Make the vptr be of type vtbl_ptr_type_node.
+ Simplify code to grow vtable.
+ * decl.c (vtbl_ptr_type_node): Define.
+ (init_decl_processing): Initialize it.
+
+1998-10-06 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.def (PTRMEM_CST): New tree node.
+ * cp-tree.h (ptrmem_cst): New type.
+ (lang_type): Remove local_typedecls.
+ (dummy): Increase to 12 bits from 11.
+ (CLASSTYPE_LOCAL_TYPEDECLS): Remove.
+ (PTRMEM_CST_CLASS): New macro.
+ (PTRMEM_CST_MEMBER): Likewise.
+ (current_access_specifier): New variable.
+ (current_class_type): Remove duplicate declaration.
+ (finish_struct): Change prototype.
+ (unreverse_member_declarations): New function.
+ (pushdecl_class_level): Change prototype.
+ (grok_enum_decls): Remove.
+ (fixup_anonymous_union): New function.
+ (grok_x_components): Change prototype.
+ (tsubst_chain): Remove.
+ (finish_member_template_decl): Likewise.
+ (check_explicit_specialization): Fix indentation.
+ (finish_class_definition): Change prototype.
+ (finish_member_class_template): Likewise.
+ (finish_member_declaration): New function.
+ (check_multiple_declarators): Likewise.
+ * class.c (class_stack_node_t): New type.
+ (current_class_base): Remove.
+ (current_class_stack): Change type.
+ (current_access_specifier): New variable.
+ (grow_method): Remove.
+ (check_member_decl_is_same_in_complete_scope): Break out from
+ finish_struct.
+ (make_method_vec): New function.
+ (free_method_vec): Likewise.
+ (add_implicitly_declared_members): Break out from finish_struct_1.
+ (free_method_vecs): New variable.
+ (add_method): Rework for direct use from parser.
+ (handle_using_decl): Watch for NULL_TREE while iterating through
+ CLASSTYPE_METHOD_VEC.
+ (finish_struct_methods): Don't build CLASSTYPE_METHOD_VEC here;
+ just do some error-checking.
+ (warn_hidden): Change iteration through CLASSTYPE_METHOD_VEC.
+ (finish_struct_1): Simplify. Use add_implicitly_declared_members.
+ (finish_struct): Change prototype. Simplify; fields and methods
+ are already set up at this point.
+ (init_class_processing): Set up current_class_stack.
+ (pushclass): Save current_access_specifier.
+ (popclass): Restore it.
+ (currently_open_class): Simplify.
+ (build_self_reference): Remove use of CLASSTYPE_LOCAL_TYPEDECLS.
+ * decl.c (saved_scope): Add access_specifier.
+ (maybe_push_to_top_level): Save it.
+ (pop_from_top_level): Restore it.
+ (maybe_process_template_type_declaration): Use
+ finish_member_declaration.
+ (pushtag): Likewise.
+ (pushdecl_class_level): Don't return a value.
+ (fixup_anonymous_union): Break out from grok_x_components.
+ (shadow_tag): Use it.
+ (xref_tag): Complain about using an elaborated type specifier to
+ reference a template type parameter or typedef name.
+ (xref_basetypes): Don't set CLASSTYPE_LOCAL_TYPEDECLS.
+ (current_local_enum): Remove.
+ (build_enumerator): Call finish_member_declaration.
+ (grok_enum_decls): Remove.
+ * decl2.c (grok_x_components): Simplify.
+ (check_classfn): Change iteration through CLASSTYPE_METHOD_VEC.
+ (grokfield): Don't set CLASSTYPE_LOCAL_TYPEDECLS.
+ (merge_functions): Add to comment.
+ (arg_assoc_type): Prototype.
+ (arg_assoc): Pass as many arguments as there are parameters.
+ * error.c (dump_expr): Handle PTRMEM_CST. Improve handling of
+ OFFSET_REF.
+ * expr.c (cpls_expand_expr): Remove dead code. Handle
+ PTRMEM_CST.
+ * friend.c (do_friend): Lookup friends when in nested classes.
+ Change comments.
+ * init.c (build_offset_ref): Do lookup even for classes that are
+ only partially defined.
+ (decl_constant_value): Remove dead code.
+ * method.c (build_overload_value): Remove hack where by TYPE was
+ not a TYPE. Handle PTRMEM_CST.
+ (build_template_parm_names): Don't pass a PARM_DECL where a TYPE
+ should go.
+ * parse.y (components, notype_components, component_decl,
+ component_decl_1, component_declarator, component_declarator0):
+ Now all are itype rather than ttype. Rework to add members to
+ classes on the fly.
+ (typesqpecqual_reserved): Use check_multiple_declarators.
+ (structsp): Update class to finish_class_definition.
+ (do_xref_defn): Unsplit into named_class_head.
+ (access_specifier): Set current_access_specifier.
+ * pt.c (set_current_access_from_decl): New function.
+ (finish_member_template_decl): Don't take the parameters.
+ (comp_template_args): Make more robust.
+ (lookup_template_class): Don't use current_local_enum.
+ (for_each_template_parm): Handle PTRMEM_CST.
+ (instantiate_class_template): Use set_current_access_from_decl,
+ finish_member_declaration and unreverse_member_declarations. Set
+ lineno/input_filename before generating implicit member functions.
+ (type_unification_real): Don't assume back-unification happens
+ only for the last argument.
+ (regenerate_decl_from_template): Call pushclass a bit earlier.
+ (tsubst_chain): Remove.
+ (tsubst_enum): Use set_current_access_from_decl.
+ (set_mangled_name_for_template_decl): Fix indentation.
+ * search.c (lookup_fnfields_1): Change iteration through
+ CLASSTYPE_METHOD_VEC.
+ (dfs_pushdecls): Likewise.
+ (dfs_compress_decls): Likewise.
+ (add_conversions): Likewise.
+ * semantics.c (finish_class_definition): Don't take components.
+ Change call to finish_struct.
+ (finish_member_declaration): New function.
+ (finish_member_class_template): Don't take template parameters.
+ Change call to grok_x_components. Call finish_member_template_decl.
+ (check_multiple_declarators): New function.
+ * sig.c (append_signature_fields): Work from the TYPE_METHODS, not
+ a passed in fieldlist.
+ * tree.c (search_tree): Handle PTRMEM_CST.
+ (mapcar): Likewise.
+ * typeck.c (unary_complex_lvalue): Build PTRMEM_CSTs, not
+ INTEGER_CSTs, for pointer-to-data members.
+
+ * call.c (resolve_args): Resolve template specializations, if
+ possible.
+
+Tue Oct 6 07:57:26 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (spew.o): Depend on toplev.h.
+
+ * call.c (compare_ics): Initialize variables `deref_from_type2',
+ `deref_to_type1' and `deref_to_type2'.
+
+ * except.c (get_eh_type): Hide prototype and definition.
+ (process_start_catch_block_old): Remove unused static prototype.
+
+ * pt.c (tsubst_decl): Initialize variable `argvec'.
+
+ * spew.c: Include toplev.h.
+
+1998-10-05 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_decl): Do save and restore file position.
+
+1998-10-05 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * method.c (build_decl_overload_real): Clear
+ numeric_output_need_bar after __.
+
+1998-10-05 Nathan Sidwell <nathan@acm.org>
+
+ * call.c (build_new_method_call): Issue 'incomplete type' error,
+ if class is not defined.
+
+1998-10-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (build_object_call): Move declaration of variable
+ `fn' into the scope where it is used. Don't access variable
+ `fn' when it is uninitialized, instead use `fns'.
+
+1998-10-04 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * errfn.c (cp_thing): Print buf as a string not as a printf format
+ to avoid problems with the operator%. Consequently, `%%' sequences
+ in format are copied as `%' in buf.
+
+1998-10-04 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (pop_tinst_level): Call extract_interface_info.
+ (instantiate_decl): Don't save and restore file position.
+
+ * decl.c (cp_finish_decl): Make statics in extern inlines and
+ templates common, if possible and the target doesn't support weak
+ symbols.
+
+ * decl.c (grokdeclarator): Remove redundant calls to
+ build_type_variant and some duplicated code.
+ * sig.c (build_signature_reference_type): Only take the type parm.
+ (build_signature_pointer_type): Likewise.
+ * tree.c (build_cplus_method_type): Adjust.
+ * cp-tree.h: Update.
+
+1998-10-04 Mark Mitchell <mark@markmitchell.com>
+
+ * call.c (build_over_call): Make pedwarns about dropped qualifiers
+ into full-fledged errors.
+ * cvt.c (convert_to_reference): Likewise.
+ * typeck.c (convert_for_assignment): Likewise.
+
+ * search.c (expand_upcast_vtables): In addition to unsetting
+ TREE_READONLY, remove top-level const type qualifier.
+
+1998-10-03 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (current_class_ptr, current_class_ref): Clarify
+ documentation.
+ * cvt.c (ocp_convert): Don't expect fold to remove all trivial
+ NOP type conversions.
+ * decl.c (decls_match): Use comptypes directly; ignore
+ qualifiers on the DECL.
+ (duplicate_decls): Remove qualifier checks on DECL.
+ (grokdeclarator): Make the type built up include top-level
+ qualifiers.
+ * decl2.c (do_dtors): Fix spelling error.
+ * error.c (dump_simple_decl): Don't look at qualifiers on the decl
+ when printing type information.
+ * init.c (build_new_1): Add documentation. Deal with the fact
+ that type of allocated memory now contains qualifiers.
+ * lex.c (is_global): Improve error-recovery.
+ * sig.c (build_member_function_pointer): Don't cast away const
+ on fields of sigtable_entry_type.
+ * tree.c (lvalue_type): Don't look at top-level qualifiers on
+ expressions.
+ * typeck.c (decay_conversion): Likewise.
+ (build_component_ref): Make sure the type of the COMPONENT_REF
+ contains top-level qualifiers, as appropriate. Improve
+ error-handling.
+ (build_indirect_ref): Simplify. Don't strip top-level qualifiers.
+ (build_array_ref): Likewise.
+ (build_unary_op): Improve error-recovery.
+ (unary_complex_lvalue): Make taking the address a bound member
+ function an error, not a sorry.
+ (build_conditional_expr): Look at the type qualifiers, not the
+ qualifiers on the expression itself.
+
+1998-10-03 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (merge_functions): Remove duplicates.
+
+ * decl2.c: Add -f{no-,}implicit-inline-templates.
+ (import_export_decl): Check it.
+
+ * decl.c (lookup_name_real): Template parms also take precedence
+ over implicit typename. Only warn if yylex.
+
+ * typeck.c (build_conditional_expr): Only fold if ifexp is an
+ INTEGER_CST.
+
+ * decl2.c (finish_vtable_vardecl): Check DECL_INTERFACE_KNOWN
+ instead of linkage.
+
+1998-10-01 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (FORMAT_VBASE_NAME): New macro.
+ * class.c (build_vbase_pointer): Use it.
+ * rtti.c (expand_class_desc): Likewise.
+ * tree.c (build_vbase_pointer_fields): Likewise.
+
+Thu Oct 1 10:43:45 1998 Nick Clifton <nickc@cygnus.com>
+
+ * decl.c (start_decl): Add invocation of
+ SET_DEFAULT_DECL_ATTRIBUTES, if defined.
+ (start_function): Add invocation of
+ SET_DEFAULT_DECL_ATTRIBUTES, if defined.
+
+ * lex.c: Replace occurrences of HANDLE_SYSV_PRAGMA with
+ HANDLE_GENERIC_PRAGMAS.
+
+1998-09-28 Anthony Green <green@cygnus.com>
+
+ * semantics.c (finish_asm_stmt): Always permit volatile asms.
+
+1998-09-28 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokdeclarator): Tighten checks for invalid
+ destructors. Improve error-messages and error-recovery.
+ * decl2.c (check_classfn): Don't assume that mangled destructor
+ names contain type information.
+
+1998-09-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (get_base_distance): Remove assert.
+
+ * decl2.c (build_anon_union_vars): Don't process a field with no
+ name.
+ (finish_anon_union): Also complain about local anon unions with no
+ members.
+
+1998-09-25 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (lookup_namespace_name): If the name is a namespace,
+ return it immediately.
+
+Fri Sep 25 11:45:38 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (define_case_label): Remove unused parameter.
+ (check_java_method): Likewise.
+ (grokclassfn): Likewise.
+ (expand_aggr_init): Likewise.
+ (build_x_delete): Likewise.
+ (maybe_end_member_template_processing): Likewise.
+ (unshare_base_binfos): Add prototype.
+ (string_conv_p): Likewise.
+ (my_friendly_abort): Mark with ATTRIBUTE_NORETURN.
+
+ * cvt.c (build_up_reference): Remove unused parameter
+ `checkconst', all callers changed.
+ (build_type_conversion): Mark parameter `code' with
+ ATTRIBUTE_UNUSED.
+ (build_expr_type_conversion): Initialize variable `conv'.
+
+ * decl.c (push_namespace): Initialize variable `d'.
+ (define_case_label): Remove unused parameter `decl', all callers
+ changed.
+
+ * decl2.c (lang_decode_option): If !USE_CPPLIB, mark parameter
+ `argc' with ATTRIBUTE_UNUSED.
+ (grokclassfn): Remove unused parameter `cname', all callers
+ changed.
+ (check_java_method): Likewise for parameter `ctype'.
+ (copy_assignment_arg_p): Mark parameter `virtualp' with
+ ATTRIBUTE_UNUSED.
+ (finish_prevtable_vardecl): Likewise for parameter `prev'.
+
+ * expr.c (extract_init): Likewise for parameters `decl' and `init'.
+
+ * init.c (expand_aggr_init_1): Remove unused parameter
+ `alias_this', all callers changed.
+ (expand_aggr_init): Likewise.
+ (expand_default_init): Likewise.
+ (build_new_1): Initialize variable `susp'.
+ (build_x_delete): Remove unused parameter `type', all callers
+ changed.
+
+ * lex.c (set_typedecl_interface_info): Mark parameter `prev' with
+ ATTRIBUTE_UNUSED.
+ (readescape): Use (unsigned) value in shift.
+ (real_yylex): Likewise. Likewise. Also cast `sizeof' to int when
+ comparing to a signed quantity.
+
+ * pt.c (maybe_end_member_template_processing): Remove unused
+ parameter `decl', all callers changed.
+ (check_explicit_specialization): Add braces around empty body in
+ an else-statement.
+ (current_template_args): Initialize variable `args'.
+ (lookup_template_class): Likewise for variable `prev_local_enum'.
+ (tsubst_decl): Likewise for variable `r'.
+ (set_mangled_name_for_template_decl): Initialize variable
+ `context'.
+
+ * spew.c (scan_tokens): Change type of parameter `n' to unsigned.
+ Likewise for variable `i'.
+ (yylex): Initialize variable `trrr'.
+
+ * typeck.c (compparms): Mark variable `strict' with
+ ATTRIBUTE_UNUSED.
+
+ * xref.c (simplify_type): Cast argument of ctype function to
+ `unsigned char'.
+
+1998-09-24 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (language_lvalue_valid): Remove.
+ * decl.c (grokdeclarator): Don't disallow references to functions.
+ * tree.c (lvalue_p_1): New function, combining duplicated
+ code from ...
+ (lvalue_p): Use it.
+ (real_lvalue_p): Likewise.
+ * typeck.c (language_lvalue_valid): Remove.
+ (build_modify_expr): Treat FUNCTION_TYPEs as readonly, even though
+ they don't have TREE_READONLY set.
+ * typeck2.c (readonly_error): Add case for FUNCTION_DECLs.
+
+1998-09-24 Benjamin Kosnik <bkoz@loony.cygnus.com>
+
+ * spew.c (yylex): Give diagnostic.
+ * hash.h (is_reserved_word): Add export.
+ * gxx.gperf: Likewise.
+ * lex.h (rid): Add RID_EXPORT.
+ * lex.c (init_parse): Likewise.
+
+Tue Sep 22 21:01:19 1998 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * friend.c (do_friend): Make warning a full sentence.
+
+1998-09-22 Mark Mitchell <mark@markmitchell.com>
+
+ * parse.y (component_decl_list): Improve error-recovery.
+
+1998-09-22 Benjamin Kosnik <bkoz@loony.cygnus.com>
+
+ * decl.c (make_typename_type): Move error to point where name
+ variable can be used by dump_type.
+
+1998-09-22 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokfndecl): Improve error-recovery.
+ * decl2.c (grokfield): Likewise.
+ * pt.c (finish_member_template_decl): Likewise.
+
+1998-09-20 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * method.c (hack_identifier): Finding multiple members is always
+ an error.
+
+1998-09-21 Per Bothner <bothner@cygnus.com>
+
+ * Make-lang.in (c++-filt): Link libiberty.a after cxxmain.o.
+
+Mon Sep 21 01:53:05 1998 Felix Lee <flee@cygnus.com>
+
+ * lex.c (init_lex): Use getenv ("LANG"), not GET_ENVIRONMENT ().
+
+1998-09-20 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (maybe_warn_about_overly_private_class): Reformat.
+
+1998-09-17 Andrew MacLeod <amacleod@cygnus.com>
+
+ * exception.cc (__cplus_type_matcher): Realign some code.
+
+1998-09-16 Mark Mitchell <mark@markmitchell.com>
+
+ * Make-lang.in (tinfo.o): Use CXXFLAGS when compiling.
+ (tinfo2.o): Likewise.
+ (exception.o): Likewise.
+ (new.o): Likewise.
+ (opnew.o): Likewise.
+ (opnewnt.o): Likewise.
+ (opvnew.o): Likewise.
+ (opvnewnt.o): Likewise.
+ (opdel.o): Likewise.
+ (opdelnt.o): Likewise.
+ (opvdel.o): Likewise.
+ (opvdelnt.o): Likewise.
+
+1998-09-16 Richard Henderson <rth@cygnus.com>
+
+ * decl.c (init_decl_processing): Kill __builtin_fp and __builtin_sp.
+
+1998-09-15 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * call.c (build_field_call): Handle static data members too.
+
+ * typeck.c (comptypes): When comparing pointer types, check
+ whether referred types match even in strictest modes.
+
+1998-09-15 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h: Revert previous change.
+ (finish_struct_methods): Remove declaration.
+ * class.c: Revert previous change.
+ (maybe_warn_about_overly_private_class): New function.
+ (finish_struct_methods): Declare here, and make static. Remove
+ unnecessary parameters. Tidy slightly. Use
+ maybe_warn_about_overly_private_class.
+ (finish_struct_1): Adjust. Remove check for private constructors,
+ now done elsewhere.
+ (finish_struct): Adjust.
+
+1998-09-15 Andrew MacLeod <amacleod@cygnus.com>
+
+ * except.c (expand_start_catch_block): No need to check for new
+ exception model.
+ (process_start_catch_block_old): Deleted.
+ (process_start_catch_block): Add call to start_decl_1().
+ (expand_end_catch_block): Add call to end_catch_handler().
+ * exception.cc (__cplus_type_matcher): Only check the exception
+ language if there is an exception table.
+
+1998-09-15 Andrew MacLeod <amacleod@cygnus.com>
+
+ * search.c (expand_indirect_vtbls_init): Mark temporary stack slots
+ as used to prevent conflicts with virtual function tables.
+
+1998-09-14 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (lang_type): Add has_non_private_static_mem_fn.
+ (CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN): New macro, to access it.
+ * class.c (maybe_class_too_private_p): New function.
+ (finish_struct_methods): Use it.
+ (finish_struct_1): Likewise.
+ (finish_struct): Set CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN if
+ appropriate.
+
+ * pt.c (check_specialization_scope): Fix spelling error.
+ (check_explicit_specialization): Remove code to handle explicit
+ specializations in class scope; they are now correctly diagnosed
+ as errors.
+
+1998-09-10 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (pushdecl): Don't copy types if the
+ DECL_ABSTRACT_ORIGIN of the new decl matches the TYPE_NAME of the
+ type.
+
+1998-09-09 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * class.c (get_enclosing_class): New function.
+ (is_base_of_enclosing_class): Likewise.
+ * cp-tree.h (get_enclosing_class): Declare.
+ (is_base_of_enclosing_class): Likewise.
+ * pt.c (coerce_template_parms): Use them.
+
+1998-09-09 Jason Merrill <jason@yorick.cygnus.com>
+
+ * g++spec.c (lang_specific_driver): Check whether MATH_LIBRARY is
+ null to decide whether to use it.
+
+ * error.c (dump_type_real): Handle NAMESPACE_DECL.
+ * parse.y (base_class.1): Avoid crash on error.
+
+1998-09-08 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (make_typename_type): If context is a namespace, the code
+ is in error.
+
+1998-09-08 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * parse.y (nomods_initdcl0): Set up the parser stack correctly.
+
+1998-09-08 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (anonymous_namespace_name): Declare.
+ * decl.c: Define it.
+ (push_namespace): Use anonymous_namespace_name, rather than local
+ static anon_name.
+ * error.c (dump_decl): If a namespace is named
+ anonymous_namespace_name, call it {anonymous}.
+
+ * decl.c (grokparms): Distinguish between references and pointers
+ in error message.
+
+1998-09-08 Richard Henderson <rth@cygnus.com>
+ Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (process_partial_specialization): Consistently allocate
+ and zero tpd.parms based on ntparms. Use tpd2.parms, not
+ tpd.parms, where appropriate.
+
+Sun Sep 6 00:00:51 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (INCLUDES): Update after recent toplevel gcc
+ reorganizations.
+
+1998-09-05 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (TI_PENDING_SPECIALIZATION_FLAG): Remove.
+ * class.c (finish_struct): Remove hackery to deal with explicit
+ specializations in class scope.
+ * decl.c (grokfndecl): Improve error-recovery.
+ * decl2.c (grokfield): Likewise.
+ * pt.c (check_specialization_scope): New function.
+ (begin_specialization): Call it.
+ (process_partial_specialization): New function, split out from
+ push_template_decl. Check partial specializations more
+ stringently.
+ (push_template_decl): Call it.
+ (check_explicit_specialization): Don't attempt to handle explicit
+ specializations in class scope.
+ (template_parm_data): Document. Add current_arg and
+ arg_uses_template_parms.
+ (mark_template_parm): Set it.
+ (tsubst_arg_types): Remove unused variable.
+ * semantics.c (begin_class_definition): Tweak.
+
+1998-09-04 Mark Mitchell <mark@markmitchell.com>
+
+ * inc/typeinfo (type_info::type_info(const char*)): Make
+ `explicit'.
+
+ * cp-tree.h (hash_tree_cons_simple): New macro.
+ * pt.c (tsubst_arg_types): New function. Use hash_tree_cons.
+ (coerce_template_parms): Use make_temp_vec, instead of
+ make_tree_vec. Document this behavior.
+ (lookup_template_class): Likewise.
+ (tsubst, cases METHOD_TYPE, FUNCTION_TYPE): Use tsubst_arg_types.
+ Remove dead code (and add assertion to check its deadness). Fix
+ bug w.r.t. exception specifications.
+
+1998-09-03 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (import_export_vtable): Always make artificials comdat.
+ (import_export_decl): Likewise.
+ * pt.c (mark_decl_instantiated): Likewise.
+
+1998-09-03 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (finish_globally_qualified_member_call_expr):
+ Rename to ...
+ (finish_qualified_call_expr).
+ * semantics.c: Likewise.
+ * parse.y (primary): Use it.
+ * method.c (hack_identifier): Remove redundant code.
+
+ * init.c (resolve_offset_ref): Call convert_from_reference to
+ handle members of reference type. Improve error recovery.
+
+1998-09-03 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * cp-tree.h: Declare warn_nontemplate_friend.
+ * decl2.c (lang_decode_option): Set.
+ * lang-options.h: Add -Wnon-template-friend.
+ * friend.c (do_friend): Use to toggle non-template function warning.
+
+1998-09-03 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (finish_enum): Don't resolve CONST_DECLs to their
+ corresponding INTEGER_CSTs when processing_template_decl.
+ * pt.c (tsubst_enum): Tweak accordingly.
+
+1998-09-03 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * decl.c (pushdecl_class_level): Add warning here.
+ (pushdecl): Tweak.
+
+1998-09-02 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (convert_pointer_to_real): Tidy.
+ * search.c (get_base_distance_recursive): Simplify.
+ (get_base_distance): Likewise.
+
+ * pt.c (unify): Only special-case INTEGER_TYPE if it uses template
+ parms.
+
+Wed Sep 02 09:25:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * lex.c (check_newline): Call HANDLE_PRAGMA before
+ HANDLE_SYSV_PRAGMA if both are defined. Generate warning messages
+ if unknown pragmas are encountered.
+ (handle_sysv_pragma): Interpret return code from
+ handle_pragma_token (). Return success/failure indication rather
+ than next unprocessed character.
+ (pragma_getc): New function: retrieves characters from the
+ input stream. Defined when HANDLE_PRAGMA is defined.
+ (pragma_ungetc): New function: replaces characters back into the
+ input stream. Defined when HANDLE_PRAGMA is defined.
+
+1998-09-01 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (output_vtable_inherit): Use %cDIGIT in the operands.
+ * class.c (build_vtable_entry_ref): Likewise.
+
+1998-09-01 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION): New macro.
+ * decl2.c (import_export_decl): Likewise.
+ * pt.c (instantiate_decl): Use it.
+
+1998-09-01 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_name_real): Also do implicit typename thing for
+ artificial TYPE_DECLs.
+ * search.c (lookup_field): Likewise.
+ (lookup_fnfields, lookup_field): Adjust for implicit typename kludge.
+ * semantics.c (begin_constructor_declarator): Use enter_scope_of.
+ (enter_scope_of): Extract type from implicit typename.
+ (begin_class_definition): Likewise.
+ * lex.c (identifier_type): Handle implicit typename when checking
+ for SELFNAME.
+
+ * cp-tree.h: Declare flag_strict_prototype.
+ * lex.c (do_scoped_id, do_identifier): Don't implicitly_declare if
+ -fstrict-prototype.
+ * decl.c (init_decl_processing): If -f{no,-}strict-prototype wasn't
+ specified, set it to the value of pedantic.
+
+1998-09-01 Mark Mitchell <mark@markmitchell.com>
+
+ * decl2.c (arg_assoc): Handle template-id expressions as arguments.
+
+1998-08-31 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (finish_enum): Handle member enums of classes declared in
+ template functions.
+
+ * decl2.c (grok_x_components): Strip attributes before calling
+ groktypename.
+
+1998-08-31 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h, decl2.c: Remove support for -fall-virtual,
+ -fenum-int-equivalence and -fno-nonnull-objects.
+ * class.c (check_for_override): Remove support for -fall-virtual.
+ (finish_struct_1): Likewise.
+ * call.c (build_new_op): Remove support for -fenum-int-equivalence.
+ * typeck.c (build_binary_op_nodefault): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ * call.c (build_vfield_ref): Remove support for -fno-nonnull-objects.
+ * class.c (build_vbase_path): Likewise.
+
+Sun Aug 30 22:16:31 1998 H.J. Lu (hjl@gnu.org)
+
+ * Makefile.in (INTERFACE): New, set to 1.
+
+1998-08-30 Mark Mitchell <mark@markmitchell.com>
+
+ * error.c (dump_decl): Use CP_DECL_CONTEXT, not DECL_CONTEXT, when
+ comparing with global_namespace.
+ (dump_aggr_type): Likewise.
+
+ * decl.c (grokfndecl): Issue error on declaration of friend
+ templates with explicit template arguments.
+
+ * pt.c (convert_template_argument): New function, split out
+ from...
+ (coerce_template_parms): Here.
+ (tsubst): Attempt better error-recovery.
+
+1998-08-28 Benjamin Kosnik <bkoz@loony.cygnus.com>
+
+ * pt.c (decl_template_parm_p): Add checks for
+ TEMPLATE_TEMPLATE_PARM.
+
+1998-08-28 Mark Mitchell <mark@markmitchell.com>
+
+ * lex.c (do_identifier): Fix thinko in previous change.
+
+1998-08-28 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (dfs_search, binfo_for_vtable, dfs_bfv_helper): New fns.
+ * decl2.c (output_vtable_inherit): Call binfo_for_vtable.
+
+1998-08-28 Richard Henderson <rth@cygnus.com>
+
+ Add support for discarding unused virtual functions.
+ * lang-options.h: Add -fvtable-gc.
+ * cp-tree.h: Add flag_vtable_gc.
+ * decl2.c (output_vtable_inherit): New fn.
+ (finish_vtable_vardecl): Call it.
+ * class.c (build_vtable_entry_ref): New fn.
+ (build_vtbl_ref): Call it.
+
+1998-08-28 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (build_enumerator): Take the enumeration type as a
+ parameter.
+ * decl.c (finish_enum): Don't set the TREE_TYPE for the
+ enumeration constant values if we're processing_template_decls.
+ Don't set the type for the CONST_DECLs either; that's done in
+ build_enumerator.
+ (build_enumerator): Take the enumeration type as a
+ parameter.
+ * lex.c (do_identifier): Don't resolve enumeration constants while
+ processing template declarations, even if they happen to be
+ TEMPLATE_PARM_INDEXs.
+
+ * parse.y (current_enum_type): New variable.
+ (primary): Don't allow statement-expression in local classes just
+ as we don't in global classes.
+ (structsp): Use current_enum_type.
+ (enum_list): Likewise.
+ * pt.c (tsubst_enum): Don't check for NOP_EXPRs introduced by
+ finish_enum; they no longer occur.
+
+ * cp-tree.h (finish_base_specifier): New function.
+ * parse.y (base_class): Use it.
+ * semantics.c (finish_base_specifier): Define it.
+
+ * parse.y (structsp): Warn on use of typename outside of template
+ declarations.
+
+1998-08-27 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (handle_cp_pragma): Remove #pragma vtable.
+ * lang-options.h: Remove +e options.
+ * decl2.c (lang_decode_option): Likewise.
+ (import_export_vtable): Don't check write_virtuals.
+ (finish_vtable_vardecl, finish_file): Likewise.
+ * search.c (dfs_debug_mark): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+ * class.c (build_vtable, finish_vtbls, finish_struct_1): Likewise.
+
+ * call.c (build_over_call): Check flag_elide_constructors.
+ * decl2.c: flag_elide_constructors defaults to 1.
+ * typeck.c (convert_arguments): Remove return_loc parm.
+ (build_function_call_real): Adjust.
+
+ * search.c: Tear out all mi_matrix and memoize code.
+ (lookup_field, lookup_fnfields): Use scratch_tree_cons.
+ * lang-options.h: Remove documentation for -fhandle-exceptions,
+ -fmemoize-lookups and -fsave-memoized.
+ * cp-tree.h: Lose mi_matrix and memoize support.
+ * decl2.c: Ignore -fmemoize-lookups and -fsave-memoized.
+ * class.c: Lose struct class_level.
+ (pushclass, popclass): Lose memoize support.
+ * init.c (build_offset_ref): Likewise.
+
+ Never change BINFO_INHERITANCE_CHAIN.
+ * init.c (emit_base_init): Change modification of
+ BINFO_INHERITANCE_CHAIN to an assert.
+ * search.c (get_base_distance_recursive): Likewise.
+ (get_base_distance): Likewise.
+ (lookup_member): Likewise.
+ (convert_pointer_to_single_level): Likewise.
+ (lookup_field): Likewise. Lose setting TREE_VIA_* on TREE_LISTs.
+ (lookup_fnfields): Likewise.
+ * tree.c (propagate_binfo_offsets): Don't call unshare_base_binfos.
+ (unshare_base_binfos): Don't call propagate_binfo_offsets.
+ (layout_basetypes): Call propagate_binfo_offsets instead of
+ unshare_base_binfos.
+ * decl.c (xref_basetypes): Call unshare_base_binfos.
+ * pt.c (instantiate_class_template): Likewise.
+ * tree.c (reverse_path): Remove 'copy' parm; always make a
+ temporary copy.
+ * class.c (build_vbase_path): Just call it.
+ * search.c (compute_access): Likewise. Don't re-reverse.
+
+1998-08-27 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (build_vbase_path): Use reverse_path.
+ (finish_base_struct): Move warnings for inaccessible bases to
+ layout_basetypes.
+ (modify_one_vtable): Remove check of TREE_USED (binfo).
+ (fixup_vtable_deltas1): Likewise.
+ * cp-tree.h (BINFO_INHERITANCE_CHAIN): Document here.
+ (xref_tag): Remove binfos parameter.
+ (make_binfo): Remove chain parameter.
+ (reverse_path): Add copy parameter.
+ * decl.c (init_decl_processing): Change calls to xref_tag.
+ (xref_tag): Remove binfos parameter.
+ (xref_basetypes): Change calls to make_binfo.
+ * decl2.c (grok_x_components): Change calls to xref_tag.
+ (handle_class_head): Likewise.
+ * friend.c (do_friend): Likewise.
+ * lex.c (make_lang_type): Change calls to make_binfo.
+ * parse.y (structsp): Change calls to xref_tag.
+ (named_complex_class_head_sans_basetype): Likewise.
+ (named_class_head): Likewise.
+ * rtti.c (init_rtti_processing): Likewise.
+ * search.c (compute_access): Change calls to reverse_path.
+ (dfs_get_vbase_types): Change calls to make_binfo.
+ (get_vbase_types): Remove dead code.
+ * tree.c (unshare_base_binfos): Change calls to make_binfo.
+ (layout_basetypes): Warn here about inaccessible bases.
+ (make_binfo): Remove chain parameter.
+ (reverse_path): Add copy parameter.
+
+1998-08-27 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c: #if 0 complete_type_p.
+ * init.c (build_java_class_ref, build_new_1): Remove unused locals.
+ * method.c (process_overload_item): Likewise.
+ * typeck.c (comp_target_types): Likewise.
+
+ Stop sharing binfos for indirect virtual bases.
+ * tree.c (propagate_binfo_offsets): Unshare vbases, too.
+ (layout_basetypes): Likewise.
+ (unshare_base_binfos): Copy vbases, too.
+ * cp-tree.h (BINFO_VIA_PUBLIC, BINFO_BASEINIT_MARKED,
+ BINFO_VBASE_INIT_MARKED): Remove obsolete macros.
+ (BINFO_PUSHDECLS_MARKED, SET_BINFO_PUSHDECLS_MARKED,
+ CLEAR_BINFO_PUSHDECLS_MARKED): New macros.
+ * search.c (lookup_field, lookup_fnfields, lookup_member): Remove
+ reference to BINFO_VIA_PUBLIC.
+ (marked_pushdecls_p, unmarked_pushdecls_p): New fns.
+ (push_class_decls): Use them.
+ (dfs_pushdecls): Use SET_BINFO_PUSHDECLS_MARKED.
+ (dfs_compress_decls): Use CLEAR_BINFO_PUSHDECLS_MARKED.
+
+1998-08-27 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (build_enumerator): Set DECL_CONTEXT for the
+ CONST_DECLs.
+
+1998-08-26 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (finish_enum): Change prototype.
+ * decl.c (finish_enum): Use TYPE_VALUES, rather than taking a
+ VALUES parameter. Don't try to compute mins/maxs if
+ processing_template_decl.
+ * parse.y (structsp): Use new calling sequence for finish_enum.
+ * pt.c (tsubst_enum): Likewise. Take the new type as input.
+ (lookup_template_class): Remove unused variables. Tweak.
+ Register enums on instantiation list before substituting
+ enumeration constants.
+ (tsubst_decl): Remove unused variables.
+ (regenerate_decl_from_template): Likewise.
+
+ * decl.c (duplicate_decls): Don't obliterate the
+ DECL_TEMPLATE_INFO for a template if we're not replacing it with
+ anything.
+
+ * lex.c (do_identifier): Fix typo in comment.
+
+Wed Aug 26 10:54:51 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * errfn.c: Remove stdarg.h/varargs.h.
+ * tree.c: Likewise.
+
+1998-08-25 Brendan Kehoe <brendan@cygnus.com>
+
+ * pt.c (tsubst_copy): Only do typename overloading on an
+ IDENTIFIER_NODE that happens to look like a typename if it actually
+ has a type for us to use.
+
+1998-08-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (comp_cv_target_types): Split out...
+ (comp_target_types): From here. Don't allow cv-qual changes under
+ a pointer if nptrs == 0. Fix OFFSET_TYPE handling.
+ (build_ptrmemfunc): Pass 1 to nptrs.
+ * cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes.
+
+1998-08-25 Mark Mitchell <mark@markmitchell.com>
+
+ * search.c (dependent_base_p): Don't compare a binfo to
+ current_class_type; use the TREE_TYPE of the binfo instead.
+
+ * cp-tree.h (CLASS_TYPE_P): Revise definition.
+
+1998-08-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (duplicate_decls): Don't complain about different
+ exceptions from an internal decl even if pedantic.
+
+ * typeck.c (convert_for_assignment): Converting from pm of vbase
+ to derived is an error, not a sorry.
+
+ * call.c (build_over_call): Use convert_pointer_to_real for 'this'.
+ * class.c (fixed_type_or_null): Rename from
+ resolves_to_fixed_type_p. Return the dynamic type of the
+ expression, if fixed, or null.
+ (resolves_to_fixed_type_p): Use it. Return 0 if the dynamic type
+ does not match the static type.
+ (build_vbase_path): Rename 'alias_this' to 'nonnull'. Use
+ resolves_to_fixed_type_p again.
+
+1998-08-24 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (tsubst_decl): Move special case code for dealing with
+ tricky friend templates here from ...
+ (regenerate_decl_from_template): Here.
+
+1998-08-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_decl): Remove redundant linkage check.
+
+1998-08-24 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * typeck.c (c_expand_return): Handle the case that valtype
+ is wider than the functions return type.
+
+1998-08-24 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (CLASS_TYPE_P): New macro.
+ * decl.c (grokdeclarator): Use it instead of IS_AGGR_TYPE.
+ * pt.c (process_template_parm): Undo previous change.
+
+1998-08-24 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * cp-tree.h: Declare.
+ * pt.c (decl_template_parm_p): New function.
+ * decl.c (pushdecl): Check decls for redeclaring template parms.
+ (xref_tag): Make redeclaration an error, print decl.
+ * decl2.c (grokfield): Check field_decls for redeclaration as well.
+
+1998-08-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (primary): Fix up the type of string constants.
+
+1998-08-24 Mark Mitchell <mark@markmitchell.com>
+
+ * typeck.c (convert_for_initialization): Move check for odd uses
+ of NULL to avoid duplicate warnings.
+
+1998-08-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (lvalue_type): Fix for arrays.
+ * typeck.c (string_conv_p): New fn.
+ (convert_for_assignment): Use it.
+ (build_unary_op): Use lvalue_type.
+ * call.c (standard_conversion, convert_like): Use string_conv_p.
+ (add_function_candidate): Use lvalue_type.
+ * cvt.c (convert_to_reference): Likewise.
+ * decl2.c (lang_decode_option): Ignore -traditional.
+ * decl.c (init_decl_processing): flag_writable_strings inhibits
+ flag_const_strings.
+
+1998-08-24 Andrew MacLeod <amacleod@cygnus.com>
+
+ * lang-options.h (lang_options): Add fconst-strings to the list
+ of valid options.
+ * decl2.c (lang_f_options, lang_decode_option): Likewise.
+
+1998-08-24 Nathan Sidwell <nathan@acm.org>
+
+ * lex.c (real_yylex): Don't warn about long long constants if
+ we're allowing long long.
+
+1998-08-24 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (pushdecl): Use IDENTIFIER_NAMESPACE_VALUE instead of
+ accessing bindings directly.
+
+ * search.c (my_tree_cons): Reimplement.
+
+ * lang-specs.h: Remove __HONOR_STD.
+ * inc/exception, inc/new, inc/new.h, inc/typeinfo: Likewise.
+
+1998-08-23 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokdeclarator): Complain about in-class initialization
+ of aggregates and/or references.
+ * pt.c (process_template_parm): Clear IS_AGGR_TYPE for
+ TEMPLATE_TYPE_PARMs.
+
+ * decl2.c (grok_array_decl): Add comment.
+ (mark_used): Don't instantiate an explicit instantiation.
+ * friend.c (make_friend_class): Remove bogus comment. Fix check
+ for partial specializations.
+ * pt.c (check_explicit_specialization): Don't
+ SET_DECL_EXPLICIT_INSTANTIATION here.
+ (mark_decl_instantiated): Or here.
+ (do_decl_instantiation): Do it here, instead. Add checks for
+ duplicate explicit instantiations, etc. Tidy.
+ (do_type_instantiation): Likewise.
+ (instantiate_decl): Improve comments. Complain about explicit
+ instantiations where no definition is available.
+
+ * cp-tree.h (ansi_null_node): Remove.
+ * call.c (build_over_call): Warn about converting NULL to an
+ arithmetic type.
+ * cvt.c (build_expr_type_conversion): Likewise. Use
+ null_ptr_cst_p instead of expanding it inline.
+ * decl.c (ansi_null_node): Remove.
+ (init_decl_processing): Make null_node always have integral type.
+ * except.c (build_throw): Warn about converting NULL to an
+ arithmetic type.
+ * lex.c (init_parse): Remove handling of ansi_null_node.
+ * pt.c (type_unification_real): Don't convert NULL to void* type.
+ * typeck.c (build_binary_op_nodefault): Fix NULL warnings.
+ (convert_for_assignment): Warn about converting NULL to an
+ arithmetic type.
+ (convert_for_initialization): Likewise.
+
+1998-08-20 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (search_tree, no_linkage_helper, no_linkage_check): New fn.
+ * pt.c (coerce_template_parms): Use no_linkage_check.
+ * decl.c (grokvardecl): Likewise.
+ (grokfndecl): Likewise. Members of anonymous types have no linkage.
+
+ * method.c (process_overload_item): Remove useless code.
+
+1998-08-20 Per Bothner <bothner@cygnus.com>
+
+ Handle new'ing of Java classes.
+ * init.c (build_class_classref): New function.
+ (build_new_1): If type is TYPE_FOR_JAVA: Call _Jv_AllocObject;
+ constructor does not return this; don't need to exception-protect.
+
+ * pt.c (lookup_template_class): Copy TYPE_FOR_JAVA flag.
+ * decl2.c (acceptable_java_type): Handle template-derived types.
+
+1998-08-20 Per Bothner <bothner@cygnus.com>
+
+ * decl2.c (import_export_vtable): Suppress vtables for Java classes.
+
+1998-08-20 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (duplicate_decls): Always merge the old and new patterns
+ for templates, regardless of whether or not the new one has
+ DECL_INITIAL. Don't throw away specializations. Merge
+ DECL_SAVED_TREE.
+ * pt.c (tsubst_decl): Use the right pattern when calculating the
+ complete args for a new template instance.
+ (do_decl_instantiation): Fix typo in comment.
+ (regenerate_decl_from_template): Deal with tricky friend template
+ case.
+ (instantiate_decl): Likewise.
+
+Thu Aug 20 09:09:45 1998 Jeffrey A Law (law@cygnus.com)
+
+ * init.c (build_builtin_delete_call): Add missing assemble_external
+ call.
+
+1998-08-20 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (notype_unqualified_id): Also accept ~A<int>.
+
+1998-08-19 Mark Mitchell <mark@markmitchell.com>
+
+ * typeck.c (build_binary_op_nodefault): Warn on use of NULL in
+ arithmetic.
+ * except.c (build_throw): Warn when NULL is thrown, even with
+ -ansi. Use ansi_null_node, rather than integer_zero_node, in the
+ thrown expression.
+
+ * cp-tree.h (ansi_null_node): New variable.
+ * decl.c (ansi_null_node): New variable.
+ (init_decl_processing): Initialize its type.
+ * lex.c (init_parse): Initialize its value. Use ansi_null_node
+ for null_node in non-ANSI mode.
+ * typeck.c (build_binary_op_nodefault): Use ansi_null_node in
+ place of null_node to avoid spurious errors.
+
+1998-08-17 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (enter_scope_of): New function.
+ * parse.y (complex_direct_notype_declarator): Use it.
+ * semantics.c (enter_scope_of): New function.
+
+1998-08-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokparms): No, here.
+
+ * decl.c (grokdeclarator): Catch parm with pointer to array of
+ unknown bound here...
+ * method.c (process_overload_item): ...not here.
+
+ * gxxint.texi: Remove obsolete documentation of overloading code.
+
+ * decl.c (finish_enum): Also set TYPE_SIZE_UNIT.
+ * class.c (finish_struct_bits): Likewise.
+
+ * tree.c (lvalue_type): Fix for arrays.
+ * typeck.c (build_unary_op): Use lvalue_type.
+ * call.c (add_function_candidate): Likewise.
+ * cvt.c (convert_to_reference): Likewise.
+
+ * decl2.c (lang_decode_option): Ignore -traditional.
+
+ * init.c (build_offset_ref): Don't mess with error_mark_node.
+ * lex.c (do_scoped_id): Use cp_error.
+
+ * rtti.c (get_tinfo_fn): Don't mess with the context for now.
+
+1998-08-17 Benjamin Kosnik <bkoz@loony.cygnus.com>
+
+ * decl.c (grokdeclarator): Allow anonymous types to be cv-qualified.
+
+Mon Aug 17 10:40:18 1998 Jeffrey A Law (law@cygnus.com)
+
+ * cp-tree.h (set_identifier_local_value): Provide prototype.
+
+ * decl2.c (do_namespace_alias): Remove unused variables `binding'
+ and `old'.
+
+Fri Aug 14 16:42:27 1998 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.in: Rename BBISON to BISON so that it can be properly
+ inherited from the parent makefile.
+
+1998-08-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lang-options.h: Add -finit-priority.
+ * decl2.c: Likewise. Check flag_init_priority instead of
+ USE_INIT_PRIORITY.
+
+ * decl2.c (setup_initp): New fn.
+ (start_objects, finish_objects, do_ctors): Handle init_priority.
+ (do_dtors, finish_file): Likewise.
+
+1998-08-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst_copy): Hush warning.
+
+ * rtti.c (get_tinfo_fn): Also set DECL_IGNORED_P.
+
+1998-08-12 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (print_template_context): Don't abort when instantiating a
+ synthesized method.
+
+ * decl.c (grokdeclarator): Issue errors on namespace qualified
+ declarators in parameter lists or in class scope.
+
+1998-08-09 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (check_explicit_specialization): Don't abort on bogus
+ explicit instantiations.
+
+1998-08-07 Mark Mitchell <mark@markmitchell.com>
+
+ * typeck.c (require_complete_type): Use complete_type_or_else.
+ (complete_type_or_else): Always return NULL_TREE on failure, as
+ documented.
+
+ * pt.c (tsubst_aggr_type): Prototype.
+ (tsubst_decl): New function, split out from tsubst. Set
+ input_filename and lineno as appropriate.
+ (pop_tinst_level): Restore the file and line number saved in
+ push_tinst_level.
+ (instantiate_class_template): Set input_filename and lineno as
+ appropriate.
+ (tsubst): Move _DECL processing to tsubst_decl. Make sure the
+ context for a TYPENAME_TYPE is complete.
+
+ * decl2.c (grokbitfield): Issue errors on bitfields declared with
+ function type.
+ (do_dtors): As in do_ctors, pretend to be a member of the same
+ class as a static data member while generating a call to its
+ destructor.
+
+ * cvt.c (cp_convert_to_pointer): Handle NULL pointer
+ conversions, even in complex virtual base class hierarchies.
+
+1998-08-06 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (ENUM_TEMPLATE_INFO): New macro.
+ (TYPE_TEMPLATE_INFO): Likewise.
+ (SET_TYPE_TEMPLATE_INFO): Likewise.
+ (ENUM_TI_TEMPLATE): Likewise.
+ (ENUM_TI_ARGS): Likewise.
+ (lookup_nested_type_by_name): Remove.
+ * decl.c (maybe_process_template_type_declaration): Handle enums.
+ (start_enum): Don't check for primary-template enum declarations
+ here.
+ (finish_enum): Clean up, document. Make sure template enum
+ constants get the correct type.
+ (build_enumerator): Copy initializers for template enumerations,
+ too.
+ (grok_enum_decls): Document.
+ * lex.c (do_identifier): Document use of LOOKUP_EXPR a bit
+ better. Build LOOKUP_EXPRs for local variables, even if they are
+ TREE_PERMANENT.
+ * pt.c (tsubst_enum): Remove field_chain parameter.
+ (template_class_depth): Include the depth of surrounding function
+ contexts.
+ (push_template_decl): Check for primary-template enum declarations
+ here. Deal with enumeration templates.
+ (lookup_template_class): Likewise.
+ (for_each_template_parm): Likewise.
+ (instantiate_class_template): Don't call tsubst_enum directly,
+ call tsubst instead, to instantiate enums. Deal with all
+ field_chain issues here, not in tsubst_enum.
+ (lookup_nested_type_by_name): Remove.
+ (tsubst_aggr_type): Revise handling of enumeration types.
+ (tsubst): Likewise.
+ (tsubst_copy): Likewise.
+ (tsubst_expr): Call tsubst, not tsubst_enum for TAG_DEFNs.
+
+1998-08-04 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (pushtag): Don't mangle the name of a TYPE_DECL if it
+ uses template parameters.
+ * method.c (build_template_parm_names): Use the full set of
+ template arguments for tsubst'ing.
+ (build_overload_identifier): Pass the full set of template
+ arguments to build_template_parm_names, not just the
+ innermost_args.
+ * pt.c (TMPL_ARGS_DEPTH): Define using
+ TMPL_ARGS_HAVE_MULTIPLE_LEVELS, for clarity.
+ (NUM_TMPL_ARGS): New macro.
+ (add_outermost_template_args): Deal with the case where the outer
+ args will be completely discarded.
+ (coerce_template_parms): Use the full set of template arguments
+ for tsubst'ing. Simplify. Add some asserts. Improve
+ error messages.
+ (lookup_template_class): Pass the full set of template arguments
+ to coerce_template_parms.
+ (tsubst): Add assertion.
+ (do_type_instantiation): Don't instantiate member template
+ classes.
+
+ * init.c (build_offset_ref): Deal with a TEMPLATE_ID_EXPR whose
+ name is a LOOKUP_EXPR, rather than an IDENTIFIER_NODE.
+
+1998-08-03 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (set_mangled_name_for_decl): Change return type to void.
+
+ * decl.c (lookup_name_real): A namespace-level decl takes priority
+ over implicit typename. Avoid doing the same lookup twice.
+
+ * search.c (dependent_base_p): New fn.
+ (dfs_pushdecls, dfs_compress_decls): Use it.
+
+ * typeck.c (get_member_function_from_ptrfunc): Don't try to handle
+ virtual functions if the type doesn't have any.
+
+1998-08-03 Mark Mitchell <mark@markmitchell.com>
+
+ * decl2.c (grokfield): Don't mangle the name of a TYPE_DECL if it
+ uses template parameters.
+
+1998-08-02 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.def (LOOKUP_EXPR): Document. Remove second argument.
+ * cp-tree.h (DECL_TI_TEMPLATE): Improve documentation.
+ * lex.c (do_identifier): Don't use a second argument, or a type,
+ when building LOOKUP_EXPRs.
+ (do_identifier): Likewise.
+ (do_scoped_id): Likewise.
+ * method.c (hack_identifier): Improve error message.
+ * pt.c (lookup_template_function): Don't needlessly call
+ copy_to_permanent or build_min.
+ (tsubst_copy): Remove #if 0'd code. tsubst into LOOKUP_EXPRs if
+ necessary.
+ (do_decl_instantiation): Improve error message.
+ * tree.c (mapcar, case LOOKUP_EXPR): Don't be sorry; make a copy.
+ (build_min): Copy the type to the permanent obstack, too.
+
+1998-08-01 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (init_init_processing): Remove BI* handling.
+ (build_builtin_call): Remove.
+ (build_builtin_delete_call): New fn.
+ (build_delete): Use it.
+
+1998-07-31 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (PROCESSING_REAL_TEMPLATE_DECL_P): New macro.
+ (maybe_check_template_type): New function.
+ * decl.c (maybe_process_template_type_declaration): New function,
+ split out from pushtag Call maybe_check_template_type.
+ (pushtag): Use it. Use PROCESSING_REAL_TEMPLATE_DECL_P.
+ (xref_tag): Use PROCESSING_REAL_TEMPLATE_DECL_P.
+ * friend.c (do_friend): Use PROCESSING_REAL_TEMPLATE_DECL_P.
+ * pt.c (template_class_depth_real): Generalization of ...
+ (template_class_depth): Use it.
+ (register_specialization): Use duplicate_decls for duplicate
+ declarations of specializations.
+ (maybe_check_template_type): New function.
+ (push_template_decl_real): Fix comment.
+ (convert_nontype_argument): Likewise.
+ (lookup_template_class): Likewise. Avoid an infinite loop on
+ erroneous code.
+ (tsubst_friend_function): Fix comment.
+ (tsubst, case FUNCTION_DECL): Deal with a DECL_TI_TEMPLATE that is
+ an IDENTIFIER_NODE.
+ * semantics.c (begin_function_definition): Use
+ reset_specialization to note that template headers don't apply
+ directly to declarations after the opening curly for a function.
+
+1998-07-29 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (push_overloaded_decl): Use current_namespace instead of
+ DECL_CONTEXT (decl) to determine where we go.
+
+ * decl.c (lookup_name_real): Fix typo.
+
+1998-07-28 Mark Mitchell <mark@markmitchell.com>
+
+ * friend.c (is_friend): Be lenient with member functions to deal
+ with nested friends.
+
+1998-07-28 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_1): Convert integer_zero_node to
+ ssizetype before passing it to set_rtti_entry.
+ * typeck2.c (initializer_constant_valid_p): Allow conversion of 0
+ of any size to a pointer.
+
+1998-07-27 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (TI_USES_TEMPLATE_PARMS): Remove.
+ (build_template_decl_overload): Remove.
+ (set_mangled_name_for_decl): New function.
+ (innermost_args): Remove is_spec parameter.
+ (most_specialized, most_specialized_class): Remove declarations.
+ (lookup_template_class): Add entering_scope parameter.
+ (maybe_process_partial_specialization): New function.
+ (finish_template_decl): Likewise.
+ (finish_template_type): Likewise.
+ * class.c (finish_struct): Clean up processing of member template
+ specializations.
+ * decl.c (pushtag): Fix formatting.
+ (lookup_tag): Improve handling of pseudo-global levels.
+ (make_typename_type): Adjust call to lookup_template_class.
+ (shadow_tag): Use maybe_process_partial_specialization.
+ (xref_tag): Improve handling of member friends.
+ (start_function): Call push_nested_class before
+ push_template_decl. Don't call push_template_decl for
+ specializations.
+ * decl2.c (grok_x_components): Don't call xref_tag for
+ template instantiations. Handle UNION_TYPEs like RECORD_TYPEs.
+ (grokclassfn): Use set_mangled_name_for_decl.
+ (arg_assoc_class): Adjust call to innermost_args.
+ (mark_used): Don't call instantiate_decl for a TEMPLATE_DECL.
+ * error.c (dump_function_name): Improve printing of template
+ function names.
+ * friend.c (is_friend): Don't compare types of decls to determine
+ friendship, unless flag_guiding_decls.
+ (make_friend_class): Partial specializations cannot be friends.
+ (do_friend): Use set_mangled_name_for_decl. Call
+ push_template_decl_real instead of push_template_decl.
+ * method.c (build_decl_overload_real): Remove prototype. Give it
+ external linkage.
+ (build_overload_identifier): Adjust call to innermost_args.
+ (build_template_decl_overload): Remove.
+ (set_mangled_name_for_decl): New function.
+ * parse.y (.finish_template_type): New non-terminal.
+ (template_def): Use finish_template_decl. Use template_extdef
+ instead of extdef.
+ (template_extdef, template_datadef): New non-terminals, containing
+ only those rules for things which can be templates.
+ (datadef): Tidy.
+ (template_type, self_template_type): Use .finish_template_type.
+ (named_class_head): Use maybe_process_partial_specialization.
+ * pt.c (mangle_class_name_for_template): Remove context parameter.
+ (get_class_bindings): Remove outer_args parameter.
+ (complete_template_args): Remove.
+ (add_outermost_template_args): New function.
+ (register_specialization): Return the specialization.
+ (unregister_specialization): New function.
+ (tsubst_template_parms): Likewise.
+ (most_specialized, most_specialized_class): Prototype here as
+ static.
+ (original_template): Rename to most_general_template.
+ (tsubst_template_parms): New function.
+ (set_mangled_name_for_template_decl): Likewise.
+ (TMPL_ARGS_DEPTH): New macro.
+ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Adjust.
+ (TMPL_ARGS_LEVEL): New macro.
+ (SET_TMPL_ARGS_LEVEL): Likewise.
+ (TMPL_ARG): Likewise.
+ (SET_TMPL_ARG): Likewise.
+ (TMPL_ARGS_DEPTH): Likewise.
+ (finish_member_template_decl): Use finish_template_decl.
+ (maybe_process_partial_specialization): New function, split out
+ from tsubst.
+ (inline_needs_template_parms): Use TMPL_PARMS_DEPTH.
+ (maybe_begin_member_template_processing): Use new macros.
+ (is_member_template): Likewise.
+ (is_member_template_class): Likewise.
+ (add_to_template_args): Likewise. Deal with multiple levels of
+ args.
+ (maybe_process_partial_specialization): New function.
+ (retrieve_specialization): Add consistency check.
+ (determine_specialization): Return full argument list.
+ (check_explicit_specialization): Tweak friend handling. Use full
+ argument lists. Simplify.
+ (current_template_args): Use new macros.
+ (push_template_decl_real): Change ill-named mainargs to specargs.
+ Check that a partial specialization actually specializes at least
+ one parameter. Improve friend handling. Modify for full
+ template arguments.
+ (classtype_mangled_name): Don't mangle the names of
+ specializations.
+ (lookup_template_class): Add entering_scope parameter. Use it to
+ avoid finding a template type when an instantiation is required.
+ Simplify. Use full template arguments.
+ (tsubst_friend_function): Use unregister_specialization. Use new
+ macros. Use full template arguments.
+ (tsubst_friend_class): Substitute, using tsubst_template_parms,
+ into the template parameters before passing them to
+ redeclare_class_template.
+ (instantiate_class_template): Simplify. Use full template
+ arguments. Adjust calls to get_class_bindings. Use
+ SET_IDENTIFIER_TYPE_VALUE where needed. Improve friend handling.
+ (innermost_args): Use new macros.
+ (tsubst_aggr_type): New function, split out from tsubst.
+ (tsubst): Use tsubst_aggr_type, tsubst_template_parms, new calling
+ conventions for lookup_template_class. Refine handling of partial
+ instantiations. Remove calls to complete_template_args.
+ Simplify. Add consistency checks. Use set_mangled_name_for_decl
+ and set_mangled_name_for_template_decl.
+ (tsubst_copy): Use tsubst_aggr_type.
+ (instantiate_template): Use full template arguments.
+ (more_specialized): Improve formatting.
+ (more_specialized_class): Adjust calls to get_class_bindings.
+ (get_bindings_real): Don't call complete_template_args.
+ (most_specialized): Don't overwrite input; create a new list.
+ (most_specialized_class): Use most_general_template.
+ (regenerate_decl_from_template): Use unregister_specialization.
+ Use full template arguments.
+ (instantiate_decl): Use full template arguments.
+ (set_mangled_name_for_template_decl): New function.
+ * semantics.c (begin_class_definition): Use
+ maybe_process_partial_specialization.
+ (finish_member_class_template): New function.
+ (finish_template_decl): Likewise.
+ (finish_template_type): Likewise.
+ (typeck.c): Don't crash after issuing a compiler_error.
+ * Makefile.in (CONFLICTS): Adjust; we removed a s/r conflict.
+
+1998-07-27 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (build_functional_cast): Handle default-initialization.
+
+ * call.c (build_over_call): Pass 1 to popclass.
+
+ * parse.y (direct_notype_declarator): Add precedence declaration
+ to notype_unqualified_id case.
+ * Makefile.in (EXPECT): Adjust.
+
+ * tree.c (ovl_member): Fix for single function in OVL.
+
+1998-07-27 Dave Brolley <brolley@cygnus.com>
+
+ * c-lex.c (yylex): Fix boundary conditions in character literal and
+ string literal loops.
+
+1998-07-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_name_real): OK, do return the from_obj value
+ unless got_object depends on template parms.
+
+ * parse.y (nested_name_specifier_1): Pull out the TYPE_MAIN_VARIANT.
+
+ * pt.c (coerce_template_parms): Also complain about local enums.
+
+ * cp-tree.h: Add prototype for set_identifier_local_value.
+ * decl.c (set_identifier_local_value_with_scope): Make static,
+ prototype.
+ * search.c (covariant_return_p): Likewise.
+ * except.c (build_terminate_handler, alloc_eh_object): Likewise.
+
+ * call.c (build_method_call): Only pull out the type of a destructor
+ if it's a template type parm.
+ * decl.c (lookup_name_real): Never return the from_obj value.
+
+1998-07-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (process_start_catch_block_old): Call start_decl_1 for
+ catch parm.
+ * decl.c (start_decl_1): Avoid duplicate error.
+
+ * init.c (expand_default_init): Only perform the initialization if
+ it will do something.
+
+1998-07-23 H.J. Lu (hjl@gnu.org)
+
+ * parse.y (base_class): Check for invalid base class.
+
+1998-07-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (import_export_template): Fold in...
+ (import_export_class): ...to here. Handle dllimport/export.
+
+ * class.c (build_vtable): Pass at_eof to import_export_vtable.
+ (prepare_fresh_vtable): Likewise.
+ * decl2.c (import_export_class): Split out...
+ (finish_prevtable_vardecl): From here.
+ * class.c (finish_struct_1): Call import_export_class if at_eof.
+
+ * decl.c (start_function): #if 0 mysterious code I wrote and have
+ forgotten why.
+ * rtti.c (get_tinfo_fn): If this is for a class type, set
+ DECL_CONTEXT.
+
+1998-07-22 Jason Merrill <jason@yorick.cygnus.com>
+
+ * inc/exception: Change terminate and unexpected to ().
+
+ * parse.y (named_class_head_sans_basetype_defn): A
+ named_class_head_sans_basetype followed by '{' or ':' is a defn.
+
+1998-07-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (canonical_type_variant): New fn to handle arrays.
+ * cp-tree.h (CANONICAL_TYPE_VARIANT): Remove.
+ * pt.c (unify, default case): Also fold arg. Fix array bounds case.
+ * method.c (process_overload_item): Use build_overload_value for
+ arrays.
+
+1998-07-20 Dave Brolley <brolley@cygnus.com>
+
+ * lex.c (mbchar.h): #include it.
+ (GET_ENVIRONMENT): New macro.
+ (init_parse): Set character set based on LANG environment variable.
+ (real_yylex): Handle multibyte characters in character literals.
+ (real_yylex): Handle multibyte characters in string literals.
+
+1998-07-19 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (do_identifier): Look for class value even if we don't
+ have a global value. Do implicit declaration if parsing is 2.
+ * semantics.c (finish_call_expr): Pass 2 if we're doing Koenig
+ lookup.
+
+1998-07-19 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (pushtag): Revert previous change.
+ * pt.c (lookup_template_class): Don't put out debugging
+ information for types that use template parameters.
+
+ * decl.c (pushtag): Don't put out debugging information for
+ compiler-generated typedefs.
+
+ * error.c (dump_type_real): Don't crash when presented with
+ intQI_type_node or the like.
+
+ * semantics.c (finish_translation_unit): Fix spelling error in
+ comment.
+
+1998-07-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_name_real): Pull out single function here.
+ (select_decl): Not here.
+ (unqualified_namespace_lookup): Use CP_DECL_CONTEXT.
+
+ * decl.c (qualify_lookup): Tweak again.
+
+ * pt.c (lookup_template_class): Don't mess with the context of the
+ instantiation.
+ * decl2.c (current_decl_namespace): Remove special handling for
+ templates.
+
+ * pt.c (tsubst, case FUNCTION_DECL): Fix getting complete args for
+ a member template specialization.
+
+ * tree.c (ovl_member): Use decls_match to compare functions.
+ * decl.c (decls_match): Check the context of a function.
+
+ * parse.y (primary): Use notype_unqualified_id instead of IDENTIFIER
+ in Koenig lookup support rules.
+ * semantics.c (finish_call_expr): Handle the new cases.
+
+ * typeck.c (build_x_function_call): Handle overloaded methods.
+
+ * decl.c (grokvardecl): Don't call build_static_name for extern "C".
+
+1998-07-16 Mark Mitchell <mark@markmitchell.com>
+
+ * semantics.c (finish_object_call_expr): Revert previous change.
+ * call.c (build_new_method_call): Likewise. Instead, convert
+ TYPE_DECLs to IDENTIFIERs here, in the presence of templates.
+
+1998-07-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (qualify_lookup): Handle templates.
+
+ * decl2.c (do_using_directive): Don't pass ancestor.
+ * decl.c (push_using_directive): Calculate ancestor.
+
+ * decl2.c (do_nonmember_using_decl): Allow for type shadowing.
+ * decl.c (pushdecl): Move type shadowing handling from here...
+ (duplicate_decls): ...to here.
+ * decl.c (set_identifier_local_value_with_scope): New fn.
+ (pushdecl): Use it.
+ (set_identifier_local_value, lookup_type_current_level): New fns.
+ * decl2.c (do_local_using_decl): Handle types and binding level
+ stuff properly.
+
+ * init.c (build_offset_ref): Don't call mark_used on an OVERLOAD.
+ * decl.c (select_decl): Extract a lone function from an OVERLOAD.
+ (lookup_namespace_name): Likewise.
+ * typeck.c (build_unary_op): Not here anymore.
+
+ * decl2.c (do_class_using_decl): Make sure we get an identifier.
+ * class.c (handle_using_decl): Ignore TYPE_DECLs.
+
+ * decl.c (qualify_lookup): New fn.
+ (lookup_name_real): Use it.
+
+1998-07-16 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl2.c (add_using_namespace): When directly using a namespace
+ that was indirect before, promote it.
+
+ * cp-tree.h (LOOKUP_PREFER_TYPES, LOOKUP_PREFER_NAMESPACES,
+ LOOKUP_PREFER_BOTH, LOOKUP_NAMESPACES_ONLY, LOOKUP_TYPES_ONLY,
+ LOOKUP_QUALIFIERS_ONLY, LOOKUP_TEMPLATES_EXPECTED): New macros.
+ * decl.c (select_decl): Replace two flag parameters by one.
+ (unqualified_namespace_lookup): Likewise, pass flag.
+ (lookup_flags): New function.
+ (lookup_name_real): Compute flags, pass them.
+ (lookup_namespace_name): Call with zero-flag.
+ * decl2.c (ambiguous_decl): Add flag parameter, complain only
+ according to flags.
+ (lookup_using_namespace, qualified_lookup_using_namespace):
+ Add flag parameter, pass them through.
+ * lex.c (do_scoped_id): Call with zero-flag.
+
+1998-07-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (convert_for_assignment): Use comptypes.
+
+1998-07-16 Mark Mitchell <mark@markmitchell.com>
+
+ * semantics.c (finish_object_call_expr): Move test for the
+ function called being a TYPE_DECL to ...
+ * call.c (build_new_method_call): Here.
+
+1998-07-15 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (arg_assoc_class): Also look at template arguments, if any.
+ (arg_assoc): Handle error_mark_node and multiple levels of TREE_LIST.
+
+ * lex.c (looking_for_typename): Don't initialize.
+
+ * decl2.c (ambiguous_decl): Clarify error message.
+
+ * decl.c (push_using_directive): Iterate over namespaces used
+ indirectly.
+
+1998-07-15 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl2.c (add_using_namespace): Iterate over namespaces used
+ indirectly.
+
+ * decl.c (lookup_name_real): Accept namespace aliases as locals.
+ (cat_namespace_levels): Ignore aliases.
+ (duplicate_decls): Ignore duplicate aliases.
+ * decl2.c (do_namespace_alias): Process block level namespace
+ aliases. Store alias with pushdecl. Remove odr errors.
+ * parse.y (namespace_alias): New non-terminal.
+ (extdef): Use it.
+
+1998-07-15 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (arg_assoc_type): Handle METHOD_TYPE like FUNCTION_TYPE.
+ Handle TEMPLATE_TYPE_PARM.
+ (arg_assoc): Rewrite.
+
+ * pt.c (complete_template_args): Don't look at the context unless
+ we have to.
+
+ * method.c (build_decl_overload_real): Fix namespace handling.
+
+ * typeck.c (build_unary_op): Extract a lone function from an
+ OVERLOAD.
+
+ * call.c (build_scoped_method_call): Handle getting a namespace
+ for basetype in a destructor call.
+ (check_dtor_name): Handle enums.
+
+ * parse.y (using_directive): New nonterminal.
+ (extdef, simple_stmt): Use it.
+
+1998-07-14 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl2.c (add_function): Move error message ...
+ (arg_assoc_namespace): ... from here.
+
+1998-07-14 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (namespace_qualifier): Fix multiple level handling.
+ * decl2.c (namespace_ancestor): Use CP_DECL_CONTEXT.
+ (arg_assoc): Don't skip the first argument of a function.
+
+Tue Jul 14 20:09:22 1998 Jeffrey A Law (law@cygnus.com)
+
+ * search.c (my_tree_cons): Clean up.
+
+1998-07-14 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (joust): Don't warn about "confusing" conversions to the
+ same type.
+
+1998-07-14 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * class.c (push_nested_class): Complain about namespaces.
+ * decl.c (start_decl): Enter the object's namespace.
+ (cp_finish_decl): Leave it.
+ (grokdeclarator): Likewise.
+ * decl2.c (check_decl_namespace): New function.
+ (finish_file): Call it.
+ * parse.y (complex_direct_notype_declarator): Set complexity
+ of namespace-qualified ids to -1, enter the namespace.
+
+ * method.c (build_template_decl_overload): Expect _DECL as first
+ parameter. Put context temporarily into current_namespace.
+ * pt.c (check_explicit_specialization): Change caller.
+ (tsubst): Likewise.
+
+ * init.c (build_offset_ref): Call mark_used and
+ convert_from_reference for namespace members.
+
+Mon Jul 13 23:25:28 1998 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * search.c (my_tree_cons): The bitfield is at index 2.
+
+Mon Jul 13 17:21:01 1998 Nick Clifton <nickc@cygnus.com>
+
+ * lang-options.h: Format changed to work with new --help support
+ in gcc/toplev.c
+
+1998-07-12 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl2.c (build_expr_from_tree): Change calls of do_identifier.
+ Do Koenig lookup in CALL_EXPR.
+ (arg_assoc): Handle error_mark.
+ * lex.c (is_global): New function.
+ (do_identifier): Expect arguments for Koenig lookup.
+ * parse.y (primary): Add rules for calls of unqualified function calls.
+ (do_id): Change call of do_identifier.
+ * pt.c (finish_stmt_expr): Likewise.
+ * semantics.c (finish_id_expr): Likewise.
+ (finish_call_expr): Add integer parameter to indicate
+ argument-dependent lookup.
+
+ * decl.c (struct binding_level): New field using_directives.
+ (push_using_decl): Not sorry anymore.
+ (push_using_directive): New function.
+ (lookup_tag): Use CP_DECL_CONTEXT to iterate.
+ (unqualified_namespace_lookup): New function, code from ...
+ (lookup_name_real): ... here.
+ * decl2.c (lookup_using_namespace): Pass using list instead of
+ initial scope.
+ (validate_nonmember_using_decl): New function.
+ (do_nonmember_using_decl): New function.
+ (do_toplevel_using_decl): Use them.
+ (do_local_using_decl): New function.
+ (do_using_directive): Support block-level directives.
+ * parse.y (simple_stmt): Support using declarations and
+ directives.
+ (namespace_qualifier, namespace_using_decl): New non-terminals.
+
+ * xref.c (classname): New function.
+ (GNU_xref_hier): Change class and base parameters to tree.
+ * decl.c (xref_baseypes): Change caller.
+ * friend.c (make_friend_class): Likewise.
+
+1998-07-12 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * typeck.c (comptypes, case TEMPLATE_TEMPLATE_PARM): Add parameter
+ comparison.
+
+ * pt.c (for_each_template_parm, case TEMPLATE_DECL): If it is a
+ template template parameter, record its use.
+ (for_each_template_parm, case TEMPLATE_TEMPLATE_PARM): Traverse
+ its template arguments if exists.
+
+ * pt.c (coerce_template_template_parms): New function equivalent
+ to coerce_template_parms when IS_TMPL_PARM is true.
+ (coerce_template_parms): Use it. Remove the IS_TMPL_PARM parameter,
+ all callers changed.
+
+ (coerce_template_parms): Access ARGLIST properly when creating a
+ new vector. Only accept implicit TYPE_DECL as valid argument for
+ a template template parameter when it is a base class of
+ current_class_type. Don't display error message when COMPLAIN is
+ false.
+
+1998-07-12 Klaus Kaempf (kkaempf@progis.de)
+
+ * repo.c (get_base_filename): Use file_name_nondirectory.
+ (open_repo_file): Likewise.
+ * cp-tree.h (file_name_nondirectory): Add prototype.
+
+1998-07-12 Jason Merrill <jason@yorick.cygnus.com>
+
+ * friend.c (do_friend): Pull the identifier out of declarator.
+ Use cp_error and friends.
+ * decl2.c (qualified_lookup_using_namespace): Fix call to
+ purpose_member.
+ * decl.c (lookup_name_real): Don't call complete_type on a namespace.
+ (grokvardecl): Use DECL_CLASS_SCOPE_P.
+ * cvt.c (convert_pointer_to_real): Check for error_mark_node sooner.
+ * class.c (warn_hidden): Fix for OVERLOAD.
+ From grahams@rcp.co.uk:
+ * cp-tree.h (DEFARG_NODE_CHECK): New macro.
+ (DEFARG_LENGTH, DEFARG_POINTER): Use it.
+
+Sun Jul 12 01:20:57 1998 Jeffrey A Law (law@cygnus.com)
+
+ * g++.1 (-traditional): Remove duplicated documentation.
+
+1998-07-11 Mark Mitchell <mark@markmitchell.com>
+
+ * method.c (flush_repeats): Add nrepeats parameter.
+ (issue_nrepeats): Likewise.
+ (is_back_referenceable_type): New function. Don't back-reference
+ TEMPLATE_TYPE_PARMs as well as simple types like integers.
+ (build_mangled_name_for_type): Likewise.
+ (build_mangled_name_for_type_with_Gcode): Likewise.
+ (lasttype): Remove.
+ (nrepeats): Likewise.
+ (Nrepeats): Likewise.
+ (start_squangling): Don't clear the variables removed above.
+ (end_squangling): Likewise.
+ (flush_repeats): Tidy. Use nrepeats parameter rather than
+ Nrepeats global.
+ (issue_nrepeats): Likewise, but with nrepeats global. Use
+ is_backreferenceable_type.
+ (build_overload_nested_name): Tidy. Add comment. Use
+ build_mangled_name_for_type.
+ (build_underscore_int): Comment.
+ (build_overload_scope_ref): Use build_mangled_name_for_type.
+ (build_overload_int): Likewise.
+ (build_template_template_parm_names): Tidy.
+ (build_template_parm_names): Use build_mangled_name_for_type.
+ (build_overload_identifier): Add comments.
+ (build_mangled_name_for_type_with_Gcode): Split out from
+ build_mangled_name.
+ (build_mangled_name_for_type): Use it.
+ (build_mangled_name): Rework to use build_mangled_name_for_type
+ and to not use global nrepeats/Nrepeats. Tidy.
+ (process_modifiers): Tidy.
+ (check_btype): Use is_backreferenceable_type. Add comment.
+ Rename `node' to `type'.
+ (process_overload_item): Set numeric_output_need_bar here.
+ Use build_mangled_name_for_type. Tidy.
+ (build_decl_overload_real): Tidy. Don't use Nrepeats. Use
+ build_mangled_name_for_type.
+
+ * pt.c (push_template_decl_real): Don't look at DECL_TEMPLATE_INFO
+ for TYPE_DECLs.
+
+1998-07-08 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * cp-tree.h (warn_long_long): Define.
+ * decl.c (grokdeclarator): Add flag `warn_long_long' as guard for
+ warning "ANSI C++ does not support `long long'".
+ * decl2.c (warn_long_long): Define.
+ (lang_decode_option): Parse -Wlong-long, -Wno-long-long options.
+
+1998-07-07 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (xref_tag): Handle attributes between 'class' and name.
+ * parse.y (aggr): Likewise.
+ * semantics.c (finish_class_definition): Likewise.
+ * Makefile.in (EXPECTED): Adjust.
+
+ * cp-tree.h: Declare flag_optional_diags and warn_multichar.
+ * decl2.c: Define them.
+ (lang_decode_option): Handle them.
+ * lang-options.h: Add -foptional-diags.
+ * class.c (finish_struct): Don't complain about multiple meanings of
+ name if -fno-optional-diags.
+ * decl.c (pushdecl_class_level): Likewise.
+ * lex.c (real_yylex): Check warn_multichar.
+
+1998-07-06 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_tag): Use CP_DECL_CONTEXT.
+
+ * tree.c (make_binfo): Fix length.
+
+1998-06-30 Benjamin Kosnik <bkoz@bliss.nabi.net>
+
+ * decl2.c (lang_decode_option): Remove warn_template_debugging.
+ * lang-options.h: Likewise.
+
+Mon Jun 29 20:17:40 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * except.c (build_eh_type_type_ref): Remove unused variable `susp'.
+ (process_start_catch_block): Likewise for variables
+ `false_label_rtx', `call_rtx' and `return_value_rtx'.
+
+1998-06-29 Brendan Kehoe <brendan@cygnus.com>
+
+ * tree.c (build_srcloc): Make sure we allocate this node on the
+ permanent obstack.
+
+Sat Jun 27 23:34:18 1998 Fred Fish <fnf@ninemoons.com>
+
+ * g++spec.c (NEED_MATH_LIBRARY): Define to 1 if not already defined.
+ (lang_specific_driver): Initialize need_math with NEED_MATH_LIBRARY.
+ (lang_specific_driver): Only add -lm automatically if need_math is
+ nonzero.
+
+Sat Jun 27 12:22:56 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Make-lang.in (g++): Depend on mkstemp.o. Link in mkstemp.o
+
+Sat Jun 27 07:36:09 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (EXPR_H): New dependency variable.
+ (decl2.o): Depend on $(EXPR_H).
+ (typeck.o): Likewise.
+ (init.o): Likewise.
+ (expr.o): Likewise.
+
+1998-06-25 Benjamin Kosnik <bkoz@lisa.cygnus.com>
+
+ * decl.c (start_enum): Put local enums on permanent_obstack.
+
+1998-06-25 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (c_get_alias_set): Declare.
+ * decl.c (init_decl_processing): Set lang_get_alias_set.
+
+1998-06-25 Andrew MacLeod <amacleod@cygnus.com>
+
+ * cp-tree.h (mark_all_runtime_matches): Add function prototype.
+ * except.c (mark_all_runtime_matches): Set TREE_SYMBOL_REFERENCED
+ flag for all function decls which are in the exception table.
+ * exception.cc (__cplus_type_matcher): Check for CATCH_ALL_TYPE match.
+ * decl2.c (finish_file): Call mark_all_runtime_matches to make sure
+ code is emitted for any referenced rtti function.
+
+1998-06-25 Dave Brolley <brolley@cygnus.com>
+
+ * lang-specs.h: Use new | syntax to eliminate
+ string concatenation.
+
+1998-06-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (CP_DECL_CONTEXT): New macro.
+ * decl2.c (is_namespace_ancestor, lookup_using_namespace): Use it.
+ * method.c (build_overload_nested_name): Likewise.
+ * sig.c (build_signature_pointer_or_reference_type): Don't set
+ DECL_CONTEXT.
+
+1998-06-24 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ Set DECL_CONTEXT for globals to NULL_TREE instead of global_namespace.
+ * cp-tree.h (FROB_CONTEXT): New macro.
+ (DECL_MAIN_P): ::main should have a DECL_CONTEXT of NULL_TREE.
+ * decl.c (namespace_binding): Replace NULL_TREE with
+ global_namespace.
+ (set_namespace_binding, pop_namespace, lookup_name_real): Likewise.
+ * decl2.c (is_namespace_ancestor, lookup_using_namespace):
+ Likewise.
+ * decl.c (pushtag): Use FROB_CONTEXT.
+ (pushdecl, make_typename_type, define_function, grokdeclarator):
+ Likewise.
+ * decl2.c (set_decl_namespace, do_namespace_alias): Likewise.
+ * pt.c (push_template_decl_real, lookup_template_class, tsubst):
+ Likewise.
+ * decl2.c (decl_namespace): Return global_namespace if no context.
+ * method.c (build_overload_nested_name): Expect null as context.
+ * pt.c (mangle_class_name_for_template): Do nothing for null
+ contexts.
+ (lookup_template_class): Allow for null id_context.
+
+1998-06-25 Richard Henderson <rth@cygnus.com>
+
+ * method.c (emit_thunk): Set current_function_is_thunk for the
+ ASM_OUTPUT_MI_THUNK case as well.
+
+1998-06-23 Andrew MacLeod <amacleod@cygnus.com>
+
+ * exception.cc (__cplus_type_matcher): Get a match_info pointer
+ instead of an exception table entry as a parameter.
+
+1998-06-23 Andrew MacLeod <amacleod@cygnus.com>
+
+ * parse.y (function_try_block): Don't call start_catch_handler.
+ * except.c (call_eh_info): Remove coerced field from declaration.
+ (build_eh_type_type_ref): New function to create an address of a
+ rtti function for the new style exception tables.
+ (expand_start_catch_block): Split function, this contains the
+ common part.
+ (process_start_catch_block_old): New function to perform the rest
+ of expand_start_catch_block under old style exceptions.
+ (process_start_catch_block_old): New function to perform the rest
+ of expand_start_catch_block under new style exceptions.
+ (expand_end_catch_block): Only pop the false label off the stack under
+ the old style of exceptions.
+ * semantics.c (finish_try_block): Don't call start_catch_handler.
+ * exception.cc (struct cp_eh_info): Add original_value field.
+ (__cplus_type_matcher): Perform type matching on the original exception
+ value, and if we have a match, set the current value.
+ (__cp_push_exception): Set the original exception value.
+
+1998-06-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (joust): Fix confusing conversion warning.
+
+ * call.c (build_op_delete_call): Add placement parm. Check
+ LOOKUP_SPECULATIVELY.
+ * cp-tree.h, decl2.c, init.c: Adjust.
+ * decl.c (finish_function): Use it.
+
+ * pt.c (tsubst): Diagnose creating void fields or variables.
+
+Mon Jun 22 08:50:26 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (build_scoped_method_call): Remove unused variable `tmp'.
+
+ * cp-tree.h (check_dtor_name): Add prototype.
+
+ * init.c (expand_member_init): Remove unused variables
+ `ptr_type_node', `parm' and `rval'.
+
+ * ptree.c (print_lang_type): Use HOST_WIDE_INT_PRINT_DEC specifier
+ in call to fprintf.
+ (lang_print_xnode): Likewise.
+
+ * typeck2.c (enum_name_string): Cast argument to sprintf to long
+ and use %ld specifier.
+
+ * xref.c (GNU_xref_end_scope): Use HOST_WIDE_INT_PRINT_DEC
+ specifier in call to fprintf.
+ (GNU_xref_member): Cast argument to sprintf to int.
+
+Fri Jun 19 23:22:42 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * typeck2.c (pop_init_level): Warn about implicit zero initialization
+ of struct members.
+
+Thu Jun 18 09:32:32 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h: Prototype function `check_java_method'.
+
+1998-06-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct): Make conflicting use of id a pedwarn.
+ * decl.c (pushdecl_class_level): Likewise.
+
+1998-06-17 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (convert_nontype_argument): Issue an error when presented
+ with an integer (real) constant that cannot be simplified to an
+ INT_CST (REAL_CST).
+
+ * cp-tree.h (c_get_alias_set): Remove declaration added in
+ 1998-06-13 change that should never have been checked in.
+
+1998-06-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Change % in format strings
+ to %%.
+
+ * decl.c (grokvardecl): Don't build_static_name for decls that
+ aren't at namespace scope.
+
+ * init.c (perform_member_init): Catch default-initialization of
+ references.
+
+1998-06-17 Mark Mitchell <mark@markmitchell.com>
+
+ * errfn.c (cp_thing): Handle the `%%' formatting sequence.
+
+1998-06-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (hack_identifier): Complain about getting a namespace
+ or class template.
+ * typeck.c (decay_conversion): Remove check for namespaces.
+ * typeck2.c (incomplete_type_error): Likewise.
+ * parse.y (template_arg): Add PTYPENAME expansion.
+
+1998-06-16 Andrew MacLeod <amacleod@cygnus.com>
+
+ * decl.c (grokvardecl): Don't build external assembler names for
+ TYPENAMEs in other namespaces as there is no declarator.
+ * error.c (cp_file_of, cp_line_of): Don't extract file or line number
+ info from DECL_CONTEXT if it is NULL.
+
+1998-06-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (check_dtor_name): Split out.
+ (build_scoped_method_call): Use it.
+ (build_method_call): Use it.
+ * init.c (build_offset_ref): Use it.
+
+ * typeck.c (build_static_cast): Fix handling of pointers to members.
+
+ * decl.c (finish_function): Just return nothing from a constructor.
+ * typeck.c (c_expand_return): Complain about returning a void
+ expression from a destructor.
+
+1998-06-13 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (alter_access): Accept a BINFO explaining how to get
+ from the entity whose accessed is being altered to the type doing
+ the altering.
+ (handle_using_decl): New function containing code split out from ...
+ (finish_struct_1): Here.
+
+ * cp-tree.h (complete_type_or_else): Declare.
+ * init.c (build_new_1, build_delete): Use it.
+ * typeck.c (require_complete_type): Use complete_type, rather than
+ expanding it inline.
+ (complete_type_or_else): New function.
+ (build_component_ref): Use it.
+ (pointer_int_sum): Make sure the type pointed to is complete.
+ (pointer_diff): Likewise.
+
+ * pt.c (for_each_template_parm): Traverse the TYPE_CONTEXT for
+ types.
+
+ * search.c (get_matching_virtual): Note that member templates
+ cannot override virtual functions.
+
+1998-06-12 Brendan Kehoe <brendan@cygnus.com>
+
+ * pt.c (check_explicit_specialization): If DECLARATOR turned into
+ an error_mark_node from lookup_template_function, return the same.
+ (determine_specialization): Also make sure TEMPLATE_ID isn't an
+ error_mark_node, before we try to read its operands.
+ * decl.c (grokdeclarator): If we got an error_mark_node from
+ check_explicit_specialization, just return it right back.
+
+1998-06-12 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (instantiate_type): Don't treat template-ids that don't
+ specify any template arguments as equivalent to ordinary
+ identifiers. Use OFFSET_REF instead of SCOPE_REF to refer to
+ pointer-to-members for member templates. Tidy slightly.
+ * cp-tree.def (TEMPLATE_ID_EXPR): Revise documentation.
+ * init.c (build_offset_ref): Handle template-ids like ordinary
+ identifiers, for the most part, but store a TEMPLATE_ID_EXPR in the
+ offset part of the OFFSET_REF.
+ * typeck.c (build_unary_op): Change check for unknown types to
+ look for OFFSET_REFs, not SCOPE_REFs.
+
+1998-06-11 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (is_member_template_class): New function.
+ (push_template_decl_real): Use it.
+
+1998-06-11 Benjamin Kosnik <bkoz@elmo.cygnus.com>
+
+ * friend.c (do_friend): Add support for nested classes using
+ member functions of the enclosing class as friends.
+
+1998-06-10 Mark Mitchell <mark@markmitchell.com>
+
+ * call.c (convert_default_arg): Make global, not static.
+ (convert_arg_for_ellipsis): Split out from ...
+ (build_over_call): Here.
+ * cp-tree.h (convert_default_arg); Declare.
+ (convert_arg_to_ellipsis): Likewise.
+ (do_member_init): Remove.
+ * init.c (do_member_init): Remove; this code is dead.
+ (expand_member_init): Remove much of this code; it is dead.
+ * typeck.c (convert_arguments): Use convert_default_arg and
+ convert_arg_for_ellipsis, rather than duplicating here.
+
+ * call.c (convert_like): Don't fail silently if
+ build_user_type_conversion fails. Always return error_mark_node
+ for failure.
+
+1998-06-10 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (covariant_return_p): Complain about ambiguous base.
+
+ * typeck.c (build_component_ref): Diagnose ref to nested type.
+
+1998-06-10 Brendan Kehoe <brendan@cygnus.com>
+
+ * decl.c (grokparms): Check that INIT isn't an error_mark_node
+ before giving error about invalid type for default arg.
+
+1998-06-10 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_method_call): Fix thinko.
+
+1998-06-10 Dave Brolley <brolley@cygnus.com>
+
+ * decl2.c (lang_decode_option): New argc/argv interface.
+ * cp-tree.h (lang_decode_option): New argc/argv interface.
+ * lang-specs.h (default_compilers): Only call cpp if -E, -M or -MM is
+ specified for cpplib-enabled compilers.
+ * lex.c (lang_init): Don't check_newline for cpplib.
+ (init_parse): Don't initialize cpplib here.
+
+1998-06-10 Brendan Kehoe <brendan@cygnus.com>
+
+ * typeck.c (build_component_ref): Make sure FIELD has a lang_specific
+ piece before checking DECL_MUTABLE_P.
+
+1998-06-10 John Carr <jfc@mit.edu>
+
+ * tree.c (debug_binfo): Make printf format match arguments.
+
+ * error.c (OB_PUTI): Make printf format match arguments.
+
+1998-06-10 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (perform_member_init): Handle default-initialization.
+
+ * except.c (build_throw): Handle throwing NULL.
+
+ * typeck.c (build_x_function_call): Use resolve_offset_ref.
+
+ * search.c (compute_access): Only strip an anonymous union
+ for a FIELD_DECL.
+
+ * call.c (add_builtin_candidates): Tweak.
+
+ * cvt.c (build_expr_type_conversion): Restore code for conversion
+ from class types.
+ * decl2.c (delete_sanity): Use it. Clean up.
+
+ * typeck.c (comp_ptr_ttypes_real): Fix cv-qual comparisons.
+
+1998-06-10 Branko Cibej <branko.cibej@hermes.si>
+
+ * typeck.c (c_expand_return): Don't warn about void expressions on
+ return statements in functions returning void.
+
+1998-06-09 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (fn_type_unification): Revise documentation. Tidy.
+ (type_unification): Likewise.
+
+1998-06-09 Andrew MacLeod <amacleod@cygnus.com>
+
+ * semantics.c (finish_try_block): Rename expand_start_catch, and delete
+ expand_end_catch.
+ * parse.y (function_try_block): Rename expand_start_catch, and delete
+ expand_end_catch.
+ * except.c (expand_end_eh_spec): Rename expand_start_catch, and delete
+ expand_end_catch.
+
+1998-06-09 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (lookup_member): New fn.
+ * class.c (finish_struct_1): Use it.
+ * decl.c (lookup_name_real): Use it.
+
+Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (decl2.o): Depend on dwarf2out.h and dwarfout.h.
+
+ * cp-tree.h: Add prototype for `maybe_print_template_context' and
+ `maybe_make_one_only'.
+
+ * decl.c (auto_function): Remove unused variable `decl'.
+
+ * decl2.c: Include dwarf2out.h and dwarfout.h.
+
+ * lex.c: Remove redundant declarations of `set_float_handler' and
+ `asm_out_file'.
+
+1998-06-08 Andrew MacLeod <amacleod@cygnus.com>
+
+ * except.c (init_exception_processing): Remove NEW_EH_MODEL compile
+ time flag. Call __cp_eh_info instead of __cp_exception_info.
+ * exception.cc (struct cp_eh_info): Remove NEW_EH_MODEL flag.
+ (__cp_exception_info): Return offset into cp_eh_info structure to
+ match what use to be the start of this structure.
+ (__cp_eh_info): New function to return a pointer to cp_eh_info struct.
+ (__cplus_type_matcher, __cp_push_exception): Remove NEW_EH_MODEL
+ compile time flag.
+ (__uncatch_exception, __check_eh_spec, std::uncaught_exception): Call
+ __cp_eh_info instead of __cp_exception_info.
+
+1998-06-08 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (cp_finish_decl): Disable inlining of extern inlines
+ with static variables.
+
+1998-06-08 Mark Mitchell <mark@markmitchell.com>
+
+ * init.c (build_offset_ref): Correct previous change to use build,
+ not build_min.
+
+1998-06-07 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (instantiate_type): Handle pointer-to-members where the
+ member is a template.
+ * init.c (build_offset_ref): Likewise.
+ * typeck.c (build_unary_op): Likewise.
+
+1998-06-07 Richard Henderson <rth@cygnus.com>
+
+ * lex.c (lang_init_options): New function.
+ (lang_init): Remove flag_exceptions == 2 hack.
+
+1998-06-05 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (envelope_add_decl): Tweak for implicit typename.
+
+ * call.c (joust): Also warn about confusing conversion op/constructor
+ overload resolution.
+
+ * spew.c (yylex): Also return the TYPE_DECL if got_object.
+ Don't clear got_object after '~'.
+ * call.c (build_scoped_method_call): Tweak destructor handling.
+ (build_method_call): Likewise.
+ * pt.c (tsubst_copy, case METHOD_CALL_EXPR): Don't mess with
+ TYPE_MAIN_VARIANT for destructors.
+ * semantics.c (finish_object_call_expr): Complain about calling a
+ TYPE_DECL.
+
+1998-06-05 Per Bothner <bothner@cygnus.com>
+
+ * g++spec.c (lang_specific_pre_link, lang_specific_extra_ofiles):
+ Define - update needed by gcc.c change.
+
+1998-06-05 Jason Merrill <jason@yorick.cygnus.com>
+
+ * error.c (cp_printers): Use 'o' instead of '_' for the null entry.
+
+1998-06-05 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * cp-tree.h (DECL_NAMESPACE_ALIAS, ORIGINAL_NAMESPACE): Declare.
+ * decl.c (lookup_name_real): Add namespaces_only parameter.
+ If set, return only NAMESPACE_DECLs.
+ (select_decl): Likewise.
+ (identifier_type_value): Give additional parameter.
+ (lookup_name_nonclass): Likewise.
+ (lookup_name): Likewise.
+ (find_binding): Skip namespace aliases.
+ (binding_for_name): Likewise.
+ (push_namespace): Check for namespace aliases.
+ (lookup_name_namespace_only): New function.
+ (begin_only_namespace_names, end_only_namespace_names): New functions.
+ * decl2.c (set_decl_namespace): Skip namespace aliases.
+ (do_using_directive): Likewise.
+ (do_namespace_alias): Produce namespace aliases, fix alias
+ redeclaration.
+ * error.c (dump_decl): Support SCOPE_REF.
+ * parse.y (extdef): Wrap lookup with namespace_only for namespace
+ aliases and using declarations.
+
+1998-06-04 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (really_overloaded_fn): Only see through one TREE_LIST.
+
+ * error.c (dump_expr): Clean up NEW_EXPR case.
+
+1998-06-04 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ Suggested by Brendan Kehoe
+ * decl2.c (do_toplevel_using_decl): When decl is a TYPE_DECL,
+ treat it as using ::decl.
+
+ * decl2.c (arg_assoc_type): Process unknown_type_node and OFFSET_TYPE.
+
+ * tree.c (mapcar): Support NEW_EXPR.
+
+ * error.c (dump_expr): Support NEW_EXPR.
+
+1998-06-03 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (make_thunk): Use overload machinery to make name.
+ * search.c (covariant_return_p): New fn.
+ (get_matching_virtual): Use it.
+
+ * init.c (build_new_1): Fix check for void.
+
+1998-06-01 Per Bothner <bothner@cygnus.com>
+
+ * cp-tree.h (TYPE_FOR_JAVA): New macro.
+ * decl.c, cp-tree.h (java_byte_type_node, java_short_type_node,
+ java_int_type_node, java_long_type_node, java_float_type_node,
+ java_double_type_node, java_char_type_node, java_boolean_type_node):
+ New "primitive" types, with predefined names __java_byte etc.
+ (record_builtin_java_type): New function.
+ (init_decl_processing): Make Java types with record_builtin_java_type.
+ (pushtag, grokdeclarator): Set TYPE_FOR_JAVA if in extern "JAVA".
+ (xref_baseypes): If base class was TYPE_FOR_JAVA, so is this class.
+ (grokfndecl): Call check_java_method for Java classes.
+ * method.c (is_java_type): Removed. Replaced with TYPE_FOR_JAVA.
+ (process_overload_item): Match types against specific
+ java_XX_type_node types, rather than using is_java_type.
+ * class.c (finish_struct_1): Don't add default copy constructor
+ or operator= if TYPE_FOR_JAVA.
+ (pop_lang_conext): Restore strict_prototyp proper if Java.
+ * decl2.c (acceptable_java_type, check_java_method): New functions.
+ * pt.c (instantiate_class_template): Copy TYPE_FOR_JAVA from pattern.
+ (tsubst): Move common statement after if statement.
+ * typeck.c (comptypes): If strict, TYPE_FOR_JAVA must match.
+
+1998-06-01 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (for_each_template_parm): Use first_rtl_op.
+
+ * tree.c (build_cplus_array_type_1): Also check index_type for
+ template parms.
+
+1998-05-31 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Always copy BINFO_BASETYPES.
+
+1998-05-29 scott snyder <snyder@d0sgif.fnal.gov>
+
+ * tree.c (layout_basetypes): If we change TYPE_SIZE, change
+ TYPE_SIZE_UNIT too.
+
+1998-05-29 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokdeclarator): Don't complain about in-class
+ initialization of static consts if we don't really know the type
+ of the variable.
+
+1998-05-29 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (DECL_DESTRUCTOR_P): New macro.
+ * method.c (build_destructor_name): New fn.
+ * decl2.c (maybe_retrofit_in_chrg): Split out...
+ (grokclassfn): From here. Reorganize.
+ * decl.c (grok_ctor_properties): Make sure ctors for types with
+ vbases have the in_chrg parm.
+ * pt.c (instantiate_class_template): Update
+ TYPE_USES_VIRTUAL_BASECLASSES from tsubsted bases. Don't call
+ grok_*_properties.
+ (tsubst): Call grok_ctor_properties and maybe_retrofit_in_chrg.
+
+1998-05-28 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (instantiate_decl): Make test for whether or not static
+ variables should be instantiated early match its comment.
+
+1998-05-28 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_decl): Always pedwarn about vacuously redeclaring
+ a member.
+ (start_function): Call check_default_args.
+ * decl2.c (grokfield): Don't call check_default_args.
+ (check_default_args): Use cp_error_at.
+ * lex.c (do_pending_defargs): Call check_default_args.
+
+1998-05-27 Brendan Kehoe <brendan@cygnus.com>
+
+ * call.c (build_method_call): Make sure get_type_value returns
+ something before we try to use its TYPE_MAIN_VARIANT.
+ (build_scoped_method_call): Likewise.
+
+1998-05-27 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (digest_init): Complain about getting a TREE_LIST to
+ initialize an array.
+
+ * search.c (expand_upcast_fixups): Don't set DECL_CONTEXT and
+ DECL_VIRTUAL_P.
+
+ * friend.c (do_friend): Clarify template warning.
+
+1998-05-27 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (shadow_label): Don't treat decls as identifiers.
+ (maybe_push_to_top_level): Clear shadowed_labels.
+
+ * pt.c (instantiate_decl): Reset lineno and filename after calling
+ regenerate_decl_from_template.
+
+ * decl.c (grokdeclarator): Don't try to use TYPE_OBSTACK on an
+ error_mark_node.
+
+1998-05-27 Kevin Buhr <buhr@stat.wisc.edu>
+
+ * parse.y (base_class): Use is_aggr_type, not IS_AGGR_TYPE.
+
+1998-05-26 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * pt.c (process_template_parm): Accept TYPENAME_TYPE nodes.
+ (convert_nontype_argument): Handle cases when nontype template
+ parameters become classes after substitution.
+
+1998-05-26 Mark Mitchell <mark@markmitchell.com>
+
+ * friend.c (is_friend): Use comptypes, rather than == to compare
+ types. Modify for new representation of template friends.
+ (make_friend_class): Likewise.
+ * pt.c (tsubst_friend_class): Undo 1998-05-21 change. Tweak.
+ (instantiate_class_template): Deal with template friends.
+
+ * decl.c (store_parm_decls): Remove redundant call to
+ expand_main_function.
+
+1998-05-26 Benjamin Kosnik <bkoz@loony.cygnus.com>
+
+ * decl.c (start_decl): Check for DECL_LANG_SPECIFIC before
+ DECL_USE_TEMPLATE.
+
+1998-05-26 Per Bothner <bothner@cygnus.com>
+
+ * language_as_string: Handle lang_java.
+
+1998-05-26 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (pushdecl): Don't copy the type_decl.
+
+1998-05-26 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * class.c (pushclass): Always store TYPE_MAIN_VARIANT in
+ current_class_type.
+ * decl.c (grokdeclarator): Put typedefs on the type's obstack.
+
+ * parse.y (complex_direct_notype_declarator): Use $1 to access
+ scope of notype_qualified_id.
+
+1998-05-26 Dave Brolley <brolley@cygnus.com>
+
+ * lex.c (parse_options,yy_cur,yy_lim): Add for cpplib.
+ (init_parse): Initialize cpplib interface.
+
+ * Makefile.in (CXX_OBJS): Make sure dependencies never end with an
+ empty continuation.
+
+1998-05-26 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (pushtag): Avoid crashing on erroneous input.
+
+1998-05-25 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (push_namespace): Only produce one unique name for
+ anonymous namespaces.
+ (get_unique_name): Remove.
+
+1998-05-25 Mark Mitchell <mark@markmitchell.com>
+
+ * call.c (tourney): Don't do any extra comparisons.
+
+ * decl2.c (build_anon_union_vars): Don't crash on empty sub-unions.
+
+ * cp-tree.h (processing_template_parmlist): Declare.
+ * decl.c (pushtag): Don't call push_template_decl when we
+ shouldn't.
+ * pt.c (processing_template_parmlist): New variable.
+ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): New macro.
+ (complete_template_args): Use it.
+ (add_to_template_args): Likewise.
+ (innermost_args): Likewise.
+ (tsubst): Likewise.
+ (begin_template_parm_list): Use processing_template_parmlist.
+ (end_template_parm_list): Likewise.
+
+ * cp-tree.h (ANON_UNION_TYPE_P): New macro.
+ * decl.c (grokdeclarator): Use it.
+ * decl2.c (grok_x_components): Likewise.
+ * init.c (initializing_context): Likewise.
+ * method.c (do_build_copy_constructor): Likewise.
+ (do_build_assign_ref): Likewise.
+ * search.c (compute_access): Likewise.
+ * typeck.c (build_component_ref): Likewise.
+
+ * decl.c (grokdeclarator): Don't give a cv-qualified version of an
+ unnamed type a typedef name "for linkage purposes".
+
+ * pt.c (lookup_template_class): Don't look at
+ IDENTIFIER_CLASS_VALUE when there's no current_class_type.
+
+ * method.c (build_overload_int): Handle error cases gracefully.
+
+ * pt.c (instantiate_decl): Handle static member variables
+ correctly.
+
+ * pt.c (tsubst): Use the tsubst'd type when producing new
+ TEMPLATE_PARM_INDEX nodes.
+
+1998-05-24 Mark Mitchell <mark@markmitchell.com>
+
+ * tree.c (cp_tree_equal): Handle pointers to member functions.
+
+ * call.c (maybe_handle_implicit_object): Handle QUAL_CONVs. Make
+ sure the type of the REF_BIND is a reference type.
+ (maybe_handle_ref_bind, compare_ics): Rename reference_type to
+ target_type for clarity.
+
+ * parse.y (xcond): Move call to condition_conversion ...
+ * semantics.c (finish_for_cond): Here.
+ * parse.c: Regenerated.
+
+1998-05-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (push_namespace): Namespaces have type void.
+ * typeck2.c (incomplete_type_error): Complain about namespace
+ used as expression.
+ * typeck.c (decay_conversion): Likewise.
+
+1998-05-24 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * error.c (dump_expr): Support namespaces.
+
+1998-05-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.def: Add SRCLOC.
+ * cp-tree.h: Add struct tree_srcloc and accessor macros.
+ * tree.c (build_srcloc, build_srcloc_here): New fns.
+ * pt.c (add_pending_template): Use build_srcloc_here.
+ (push_tinst_level): Update last_template_error_tick before erroring.
+ (instantiate_decl): Restore lineno and input_filename before
+ calling add_pending_template.
+ * decl2.c (finish_file): Set up lineno and input_filename for
+ pending templates.
+
+1998-05-22 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lang_print_error_function): New fn.
+ (init_decl_processing): Set print_error_function to use it.
+ * errfn.c (cp_thing): Don't call maybe_print_template_context here.
+
+ * call.c (maybe_handle_ref_bind): Propagate ICS_USER_FLAG and
+ ICS_BAD_FLAG.
+
+ * cvt.c (ocp_convert): Don't set LOOKUP_NO_CONVERSION for
+ copy-initialization.
+
+ * class.c (build_vtable_entry): Use int_fits_type_p.
+ (build_vtable): Pass a signed offset to build_vtable_entry.
+ (prepare_fresh_vtable, modify_one_vtable, fixup_vtable_deltas1,
+ set_rtti_entry): Likewise.
+
+1998-05-22 Per Bothner <bothner@cygnus.com>
+
+ * cp-tree.h: Add comments documenting which LANG_FLAGS are used.
+ (C_TYPE_VARIABLE_SIZE, C_DECL_VARIABLE_SIZE): Removed, not used.
+
+1998-05-22 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (print_template_context): Use fprintf instead of cp_error.
+
+ * pt.c (determine_specialization): Just return an error_mark_node.
+ Also print the decl we want in error messages. If we complain,
+ return error_mark_node.
+ (tsubst_friend_function): Set lineno and input_filename so
+ error messages will be useful.
+ (instantiate_template): Just return an error_mark_node.
+ (check_explicit_specialization): Don't mess with a returned
+ error_mark_node.
+
+ * pt.c (print_template_context): Add new argument.
+ (maybe_print_template_context): New fn.
+ (push_tinst_level): Increment tinst_level_tick.
+ (pop_tinst_level): Likewise.
+ * errfn.c (cp_thing): Call maybe_print_template_context. Use
+ xrealloc instead of xmalloc.
+
+ * typeck.c (build_unary_op, CONVERT_EXPR): Propagate TREE_CONSTANT.
+
+1998-05-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst_friend_class): Don't call redeclare_class_template
+ if the template we looked up is the same as the one we already
+ have.
+
+Thu May 21 11:54:44 1998 Dave Brolley <brolley@cygnus.com>
+
+ * lex.c: (handle_sysv_pragma): FILE* parameter not used.
+ (cpp_reader,parse_in): Add for cpplib.
+ (check_newline): Call handle_sysv_pragma with new interface.
+ (check_newline): Call GET_DIRECTIVE_LINE, not get_directive_line.
+
+ * input.c: (yy_cur,yy_lim,yy_get_token,GETC): Add for cpplib.
+ (sub_getch): Call GETC for cpplib.
+
+ * cp-tree.h: (get_directive_line): Different prototype for cpplib.
+ (GET_DIRECTIVE_LINE): Macro wrapper for get_directive_line.
+
+ * Makefile.in (CXX_OBJS): Add @extra_cxx_objs@ for cpplib.
+
+1998-05-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (maybe_make_one_only): New fn.
+ (import_export_vtable): Use it.
+ (import_export_decl): Likewise.
+ * pt.c (mark_decl_instantiated): Likewise.
+
+1998-05-21 Mark Mitchell <mmitchell@usa.net>
+
+ * decl2.c (find_representative_member): Rename to ...
+ (build_anon_union_vars): New function.
+ (finish_anon_union): Fix stupidity of previous change.
+
+1998-05-20 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokfndecl): Handle definition of specialization in
+ friend declaration.
+
+ * error.c (dump_decl): Fix LOOKUP_EXPR handling.
+
+1998-05-20 Mark Mitchell <mmitchell@usa.net>
+
+ * class.c (delete_duplicate_fields_1): Use DECL_DECLARES_TYPE_P
+ to look for type declarations.
+ (finish_struct): Deal with templates on the CLASSTYPE_TAGS list.
+ * cp-tree.h (DECL_DECLARES_TYPE_P): New macro.
+ (finish_member_class_template): Declare.
+ * decl.c (pushtag): Put member class templates on the
+ CLASSTYPE_TAGS list, just as for ordinary member classes.
+ (pushdecl_class_level): Use DECL_DECLARES_TYPE_P.
+ (lookup_tag): Look for IDENTIFIER_CLASS_VALUEs, just as with
+ IDENTIFIER_NAMESPACE_VALUEs.
+ * parse.y (component_decl): Move code to ...
+ * semantics.c (finish_member_class_template): New function.
+ Don't put member class templates on the list of components for a
+ class.
+ * parse.c: Regenerated.
+ * pt.c (classtype_mangled_name): Don't try DECL_CONTEXT on types.
+ In fact, don't use DECL_CONTEXT at all here.
+
+1998-05-20 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (record_unknown_type): New function.
+ (init_decl_processing): Call it for the unknown and global type
+ nodes.
+
+1998-05-20 Mark Mitchell <mmitchell@usa.net>
+
+ * decl2.c (find_representative_member): New function.
+ (finish_anon_union): Use it.
+
+ * cp-tree.h (MAIN_NAME_P): New macro.
+ (DECL_MAIN_P): Likwise.
+ * decl.c (pushdecl): Avoid crashing on redefinitions of `main'.
+ (grokfndecl): Use the new macros.
+ (grokdeclarator): Likewise.
+ (start_function): Likewise.
+ (store_parm_decls): Likewise.
+ (finsh_function): Likewise.
+ * friend.c (do_friend): Likewise.
+ * typeck.c (build_function_call_real): Likewise.
+ (build_unary_op): Likewise.
+
+Wed May 20 02:16:01 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (start_objects, finish_objects, do_dtors,
+ do_ctors): Split out from...
+ (finish_file): ...here.
+
+Tue May 19 20:36:23 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (is_overloaded_fn): Don't abort on placeholders from
+ push_class_decls.
+
+Tue May 19 15:16:22 1998 Brendan Kehoe <brendan@cygnus.com>
+
+ * class.c (is_empty_class): Return 0 if TYPE is an error_mark_node.
+
+ * error.c (dump_expr): Handle an ARROW_EXPR.
+
+Tue May 19 15:13:39 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * decl.c (saveable_obstack): Declare.
+ (pushdecl): Copy TYPE_DECLs to the same obstack as the type they
+ declare, if necessary.
+
+Tue May 19 14:50:27 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * call.c (compare_qual): Remove.
+ (is_subseq): Tweak.
+ (is_properly_derived_from): New function.
+ (maybe_handle_ref_bind): Likewise.
+ (maybe_handle_implicit_object): Likewise.
+ (compare_ics): Modify substantially to bring into conformance with
+ the standard.
+ * cp-tree.h (TYPE_PTRMEMFUNC_OBJECT_TYPE): New macro.
+ (comp_cv_qualification): Declare.
+ (comp_cv_qual_signature): Likewise.
+ * typeck.c (comp_cv_qualification): Likewise.
+ (comp_cv_qual_signature): Likewise.
+
+Tue May 19 10:05:02 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (parse.o): Depend on toplev.h.
+
+ * class.c (typecode_p): Remove prototype and definition.
+
+ * cp-tree.h (currently_open_class, is_empty_class, member_p):
+ Add prototype.
+
+ * decl.c (push_overloaded_decl_top_level): Remove prototype and
+ definition.
+
+ * errfn.c (cp_error): Cast function pointer `error' to (errorfn *)
+ in call to `cp_thing'.
+ (cp_warning): Likewise for function pointer `warning'.
+
+ * except.c (do_function_call): Remove prototype and definition.
+ (call_eh_info): Wrap variable `t1' in macro NEW_EH_MODEL.
+
+ * method.c (is_java_type): Add prototype and make it static.
+
+ * parse.y: Include toplev.h.
+
+ * pt.c (type_unification): Remove unused variable `arg'.
+ (instantiate_decl): Likewise for `save_ti'.
+
+ * tree.c (propagate_binfo_offsets): Likewise for `base_binfos'.
+
+Tue May 19 02:43:25 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_member_call): Handle template_ids.
+ * parse.y (primary): Add global_scope template_id.
+
+Mon May 18 23:22:52 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (get_sentry): Use end_temporary_allocation.
+ Don't declare permanent_obstack.
+
+Mon May 18 12:28:44 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * parse.y (.finish_new_placement): New non-terminal.
+ (unary_expr, new_type_id): Use it.
+ * parse.c: Regenerated.
+
+Mon May 18 12:20:27 1998 Brendan Kehoe <brendan@cygnus.com>
+
+ * pt.c (redeclare_class_template): Say where the original definition
+ of the template-parameter's default argument appeared.
+
+Mon May 18 03:00:57 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): Tweak empty class handling.
+
+ * decl.c (make_typename_type): Use currently_open_class.
+
+ * class.c (instantiate_type): Don't abort on TREE_NONLOCAL_FLAG.
+
+Mon May 18 01:43:01 1998 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (lookup_name_real): Don't look at IDENTIFIER_LOCAL_VALUE
+ for a type unless it is one.
+
+ * class.c (finish_struct_1): Use OVL_CURRENT in error message.
+
+Mon May 18 01:24:08 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (program_transform_name, objdir): Define.
+
+ * Makefile.in (BISON): Use bison from the build tree if it exists.
+ (FLEX): Likewise.
+
+Sun May 17 14:52:08 1998 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * typeck.c (type_unknown_p): Return true for TREE_LIST also.
+
+ * call.c (build_method_call): Use TYPE_MAIN_VARIANT on typedefs.
+
+Sun May 17 14:51:41 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_scoped_method_call): Likewise.
+
+Sun May 17 13:53:48 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * init.c (build_new_1): Call suspend_momentary around the creation
+ of values that must be saved for exception handling.
+ * parse.y (.build_new_placement): New non-terminal.
+ (unary_expr, new_placement): Use it.
+ * parse.c: Regenerated.
+
+Sun May 17 12:32:08 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (duplicate_decls): Use CANONICAL_TYPE_VARIANT to compare
+ old and new types.
+
+ * pt.c (tsubst): Make sure that BINFO_TYPE of new binfos is the
+ canonical type.
+
+ * call.c (build_over_call): Don't use IS_SIGNATURE on a namespace.
+
+Fri May 15 20:28:00 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_decl): Revert problem change.
+
+ * Makefile.in (CONFLICTS): Fix.
+
+Fri May 15 15:34:02 1998 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * decl.c (duplicate_decls): Clean up, add DECL_DATA_AREA bits.
+
+Fri May 15 00:46:05 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_1): Use BINFO_SIZE.
+
+ * decl.c (start_decl): Use 'tem'.
+
+Thu May 14 16:30:47 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * exception.cc: Include eh-common.h.
+ (struct cp_eh_info): Add eh_info struct with NEW_EH_MODEL.
+ (__cplus_type_matcher): First stab at new C++ runtime type matcher.
+ (__cp_push_exception): Initialize eh_info struct as well.
+ * except.c: Remove local structs and include eh-common.h.
+ (init_exception_processing): Set language and version codes.
+ (call_eh_info): Add presence of eh_info to runtime description of
+ struct cp_eh_info.
+ (expand_end_eh_spec): Call start_catch_block() and end_catch_block().
+ * semantics.c (finish_try_block): Call start_catch_block() and
+ end_catch_block().
+ * parse.y (function_try_block): Call start_catch_block() and
+ end_catch_block().
+
+Thu May 14 12:27:34 1998 Brendan Kehoe <brendan@cygnus.com>
+
+ * typeck.c (original_type): New function.
+ (common_type): Use it to get the DECL_ORIGINAL_TYPE for T1 and T2,
+ to see if they're actually the same.
+ * cp-tree.h (original_type): Declare.
+
+Wed May 13 12:54:30 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (lex.o): Depend on output.h.
+
+ * call.c (add_function_candidate): Remove unused variable `cand'.
+ (add_conv_candidate): Likewise.
+ (build_builtin_candidate): Likewise.
+
+ * cp-tree.h: Add prototype for `types_overlap_p'.
+
+ * decl.c (signal_catch): Mark parameter `sig' with ATTRIBUTE_UNUSED.
+
+ * decl2.c (merge_functions): Remove unused variables `tmp' and
+ `tempn'.
+
+ * error.c (expr_as_string): Mark parameter `v' with ATTRIBUTE_UNUSED.
+ (code_as_string): Likewise.
+ (language_as_string): Likewise.
+ (parm_as_string): Likewise.
+ (op_as_string): Likewise.
+ (assop_as_string): Likewise.
+ (cv_as_string): Likewise.
+
+ * lex.c: Include output.h.
+
+ * pt.c (type_unification): Cast first argument of `bzero' to a char*.
+
+ * search.c (dfs_no_overlap_yet): Mark parameter `t' with
+ ATTRIBUTE_UNUSED.
+
+ * tinfo.cc (__class_type_info::dcast): Change the type of variable
+ `i' from int to size_t.
+
+ * typeck.c (language_lvalue_valid): Mark parameter `exp' with
+ ATTRIBUTE_UNUSED.
+
+Tue May 12 21:37:49 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * error.c (dump_simple_decl): Use DECL_CLASS_SCOPE_P and/or
+ DECL_NAMESPACE_SCOPE_P.
+ (lang_decl_name): Likewise.
+ * pt.c (tsubst_friend_function, tsubst): Likewise.
+ * decl.c (pushdecl, redeclaration_error_message, start_decl,
+ cp_finish_decl, start_function): Likewise.
+ * class.c (finish_struct_1): Likewise.
+ * call.c (build_over_call): Likewise.
+ (compare_ics): Use DERIVED_FROM_P.
+
+Tue May 12 07:24:18 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * cp-tree.h (CANONICAL_TYPE_VARIANT): New macro.
+ * method.c (build_mangled_name): Use it.
+ (build_decl_overload_real): Likewise.
+
+ * error.c (dump_simple_decl): New function, broken out from ...
+ (dump_decl): Use it.
+
+Mon May 11 11:38:07 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * ptree.c (lang_print_xnode): Add missing `break'.
+
+ * pt.c (tsubst): Remove duplicate check for IDENTIFIER_NODE.
+
+ * call.c (add_template_candidate): Adjust for changes to
+ fn_type_unification.
+ (add_template_candidate_real): Likewise.
+ (add_template_conv_candidate): Likewise.
+ (build_user_type_conversion_1): Likewise.
+ (build_new_function_call): Likewise.
+ (build_object_call): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+ * class.c (instantiate_type): Likewise.
+ * cp-tree.h (unification_kind_t): New type.
+ (fn_type_unification): Adjust prototype.
+ (type_unificaiton): Likewise.
+ * pt.c (UNIFY_ALLOW_NONE): New macro.
+ (UNIFY_ALLOW_MORE_CV_QUAL): Likewise.
+ (UNIFY_ALLOW_LESS_CV_QUAL): Likewise.
+ (UNIFY_ALLOW_DERIVED): Likewise.
+ (unify): Change prototype.
+ (maybe_adjust_types_for_deduction): New function.
+ (check_cv_quals_for_unify): Likewise.
+ (determine_specialization): Adjust.
+ (fn_type_unification): Likewise.
+ (type_unification): Likewise.
+ (type_unification_real): Likewise. Use
+ maybe_adjust_types_for_deduction. Fix mishandling of
+ back-unification of template functions passed as arguments. Pass
+ appropriate combination of UNIFY_ALLOW_* to unify.
+ (unify): Remove unused NTPARMS parameter. Use
+ check_cv_quals_for_unify. Remove bogus code that allowed
+ too-generous unification in order to adhere more closely to standard.
+ (get_bindings_real): Adjust.
+ (get_class_bindings): Likewise.
+
+ * method.c (build_overload_identifier): Only use the innermost
+ template arguments when mangling.
+ * pt.c (tsubst_template_argument_vector): New function.
+ (complete_template_args): Deal with the situation where the
+ extra_args contain more than one level of arguments.
+ (lookup_template_class): Deal with member template classes, which
+ may have more than one level of arguments.
+ (tsubst): Don't tsbust into the TREE_TYPE of an IDENTIFIER_NODE.
+ Improve handling of member template classes. Use
+ DECL_PRIMARY_TEMPLATE instead of inline expansion. Use
+ tsubst_template_argument_vector where appropriate.
+ (regenerate_decl_from_template): Break out from ...
+ (instantiate_decl): Here.
+
+ * lex.c (yyprint): Remove TYPENAME_ELLIPSIS.
+ * parse.h: Regenerated.
+ * parse.c: Really regenerated.
+
+ * cp-tree.h (finish_unary_op_expr): New function.
+ (finish_id_expr): Likewise.
+ (begin_new_placement): Likewise.
+ (finish_new_placement): Likewise.
+ (finish_declarator): Likewise.
+ (finish_translation_unit): Likewise.
+ (finish_parmlist): Likewise.
+ (begin_class_definition): Likewise.
+ (finish_class_definition): Likewise.
+ (finish_default_args): Likewise.
+ (finish_inline_definitions): Likewise.
+ * parse.y (GCC_ASM_KEYWORD): Remove.
+ (TYPENAME_ELLIPSIS): Likewise.
+ * parse.c: Regenerated.
+ Use new functions in semantics.c in the actions for many rules.
+ * gxx.gperf (GCC_ASM_KEYWORD): Just use ASM_KEYWORD.
+ * hash.h: Regenerated.
+ * semantics.c (finish_expr_stmt): Allow NULL expr.
+ (finish_unary_op_expr): New function, containing
+ code previously in parse.y.
+ (finish_id_expr): Likewise.
+ (begin_new_placement): Likewise.
+ (finish_new_placement): Likewise.
+ (finish_declarator): Likewise.
+ (finish_translation_unit): Likewise.
+ (finish_parmlist): Likewise.
+ (begin_class_definition): Likewise.
+ (finish_class_definition): Likewise.
+ (finish_default_args): Likewise.
+ (finish_inline_definitions): Likewise.
+
+Sun May 10 23:43:13 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * typeck.c (build_c_cast): Don't decay arrays and functions to
+ pointer type when converting to a class type.
+
+Sun May 10 22:53:56 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (DECL_NAMESPACE_SCOPE_P): New macro.
+ (DECL_CLASS_SCOPE_P): Likewise.
+
+Sun May 10 22:48:22 1998 H.J. Lu (hjl@gnu.org)
+
+ * class.c (finish_struct_1): Use OVL_CURRENT on TREE_VEC_ELT.
+ * decl2.c (constructor_name_full): Likewise.
+
+Sun May 10 22:48:12 1998 Mike Stump <mrs@wrs.com>
+
+ * tree.c (mapcar): Add OVERLOAD support.
+
+ * init.c (resolve_offset_ref): We must use basetype_path before we
+ destroy it with a call to convert_pointer_to.
+
+Sat May 9 14:44:37 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (currently_open_class): New fn.
+ * decl.c (lookup_name_real): Use it.
+ * search.c (lookup_field): Likewise.
+
+Fri May 8 23:32:42 1998 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * cp-tree.def (OVERLOAD): New node.
+ * cp-tree.h (BINDING_TYPE, SET_IDENTIFIER_GLOBAL_VALUE,
+ SET_IDENTIFIER_NAMESPACE_VALUE): Define.
+ (NAMESPACE_BINDING): Remove.
+ (IDENTIFIER_GLOBAL_VALUE, IDENTIFIER_NAMESPACE_VALUE): Use
+ namespace_binding.
+ (OVL_FUNCTION, OVL_CHAIN, OVL_CURRENT, OVL_NEXT, OVL_USED):
+ Define.
+ (tree_overload): New struct.
+ (IDENTIFIER_TYPE_VALUE): Use identifier_type_value.
+ (REAL_IDENTIFIER_TYPE_VALUE): Define.
+ (IDENTIFIER_HAS_TYPE_VALUE): Use IDENTIFIER_TYPE_VALUE.
+ (lang_decl_flags): Remove in_namespace.
+ (lang_decl): Remove chain.
+ (DECL_CHAIN, DECL_NAMESPACE): Remove.
+ (flag_honor_std): Declare extern.
+ (identifier_type_value, pushdecl_namespace_level, push_using_decl,
+ namespace_binding, set_namespace_binding,
+ lookup_function_nonclass, cat_namespace_levels,
+ set_decl_namespace, lookup_arg_dependent, binding_init, ovl_cons,
+ scratch_ovl_cons, ovl_member, build_overload): Declare.
+ (decl_list_length, get_namespace_id, current_namespace_id,
+ overloaded_globals_p): Remove.
+ (lookup_using_namespace, qualified_lookup_using_namespace): Change
+ return type.
+ (push_scratch_obstack): New macro.
+ * call.c (add_function_candidate): Special-case type of OVERLOAD node.
+ (build_user_conversions_1): Iterate using OVL_NEXT for ctors,
+ convs, fns.
+ (build_new_function_call): Iterate using OVL_CHAIN.
+ Print DECL_NAME in when reporting ambiguities.
+ (build_object_call): Iterate using OVL_NEXT for fns, convs.
+ (build_new_op): Call lookup_function_nonclass.
+ Iterate using OVL_NEXT.
+ (build_op_delete_call): Change detection of members.
+ Do not wrap TREE_LIST around fields and single global functions.
+ (build_over_call): Don't push a class level if the context is a
+ namespace.
+ (build_new_method_call): Iterate using OVL_NEXT.
+ * class.c (add_method): Chain overloaded members using
+ build_overload. Remove copying of method.
+ (grow_method): When iterating through the obstack, expect OVERLOAD
+ nodes. Chain overload members.
+ (finish_struct_methods): Chain overload members. Unpack OVERLOAD
+ nodes in call to get_baselinks.
+ (duplicate_tag_error): Expect OVERLOAD nodes when unchaining.
+ (finish_struct_1): Iterate over ctor using OVL_NEXT. Handle
+ fdecls that are OVERLOAD nodes.
+ (validate_lhs): New function.
+ (instantiate_type): Do not copy OVERLOAD nodes. Remove dead
+ code. Use DECL_NAME in error messages. Split code between global
+ and member function processing.
+ * decl.c (global_type_node): New static variable.
+ (in_std): New global.
+ (struct binding_level): New field usings.
+ (resume_binding_level): Assert that we are not in a class.
+ (toplevel_bindings_p): Just check for namespace_p or
+ pseudo_global.
+ (resume_level): Remove.
+ (find_binding): New function.
+ (binding_for_name): Call it.
+ (namespace_binding, set_namespace_binding): New functions.
+ (push_namespace): Associate binding level with new namespace,
+ resume_binding_level for existing namespace. Remove old code.
+ Fake std by counting.
+ (store_bindings): Use REAL_IDENTIFIER_TYPE_VALUE.
+ (maybe_push_to_top_level): Save current namespace.
+ (pop_from_top_level): Restore saved namespace.
+ (pop_namespace): Call suspend_binding_level. Remove old code.
+ (cat_namespace_levels): New function.
+ (set_identifier_type_value_with_scope): For namespace bindings,
+ set BINDING_TYPE, and use global_type_node.
+ Use REAL_IDENTIFIER_TYPE_VALUE otherwise.
+ (identifier_type_value): New function.
+ (pushtag): If no context, use current_namespace.
+ (duplicate_decls): Don't process DECL_CHAIN.
+ (pushdecl): Set DECL_CONTEXT to current_namespace, if it is not
+ already set. Never reset it to NULL_TREE. Lookup global variables
+ in their namespace. Push overloaded templates if they are on
+ namespace level.
+ (pushdecl_namespace_level): New function.
+ (pushdecl_top_level): Implement using pushdecl_namespace_level.
+ (pushdecl_using_decl): New function.
+ (overloaded_globals_p): Remove.
+ (push_overloaded_decl): Create OVERLOAD nodes, and iterate through
+ them. Use namespace_binding and set_namespace_value.
+ (redeclaration_error_message): Complain if the declarations come
+ from different namespaces.
+ (lookup_tag): On namespace level, look in the BINDING_TYPE.
+ (lookup_namespace_name): Pass tree_bindings from stack. Remove
+ old code.
+ (select_decl): New function.
+ (lookup_name_real): Call it for qualified and unqualified lookup.
+ Pass tree_bindings from the stack.
+ If prefer_type is 1, also accept namespaces.
+ (lookup_function_nonclass): New function.
+ (init_decl_processing): Set the binding level of the global
+ namespace to global_binding_level.
+ Build a proper type list for __builtin_apply.
+ Initialize std_node to "fake std" if flag_honor_std is set.
+ Initialize global_type_node.
+ Allocated bad_alloc in namespace std if flag_honor_std.
+ (define_function): Set the DECL_CONTEXT to the current_namespace.
+ (start_decl): A namespace is not considered as a context here. If
+ the DECL_CONTEXT is a namespace, push the decl.
+ (cp_finish_decl): Check for namespaces used as initializers.
+ (grokfndecl): Add namespace parameter. Remove processing of
+ DECL_CHAIN.
+ (grokvardecl): Add namespace parameter.
+ (grokdeclarator): Process SCOPEs that are namespaces. For
+ mangling, temporarily set the DECL_CONTEXT on anonymous structs.
+ (start_function): Check for contexts that are namespaces.
+ Set context for declarations that have not been pushed.
+ (store_parm_decls): Check for ::main only.
+ (finish_function): Likewise.
+ (start_method): Check for contexts that are namespaces.
+ (start_method): Remove DECL_CHAIN processing.
+ * decl2.c (flag_honor_std): Declare.
+ (lang_decode_option): Set it if -fhonor-std or -fnew-abi is given.
+ (decl_namespace_list): New static global.
+ (grok_x_components): Ignore namespaces as type contexts.
+ (check_classfn): Expect OVERLOAD nodes.
+ (grokfield): Remove DECL_CHAIN processing.
+ (finish_file): Call cat_namespace_levels.
+ (merge_functions): New function.
+ (ambiguous_decl): Rewrite.
+ (lookup_using_namespace): Produce tree_bindings.
+ (qualified_lookup_using_namespace): Likewise.
+ (set_decl_namespace, decl_namespace, current_decl_namespace,
+ push_decl_namespace, pop_decl_namespace): New functions.
+ (arg_lookup): New struct.
+ (add_function, arg_assoc_namespace, arg_assoc_class,
+ arg_assoc_type, arg_assoc_args, arg_assoc, lookup_arg_dependent):
+ New functions.
+ (get_namespace_id, current_namespace_id): Remove.
+ (do_toplevel_using_decl): Rewrite.
+ (do_class_using_decl): Complain about namespace qualifiers.
+ (do_using_directive): Sorry if not on namespace level. Complain
+ about unknown namespaces.
+ * error.c (dump_aggr_type): Check for namespace contexts.
+ * except.c (init_exception_processing): Push terminate into std.
+ * friend.c (is_friend): A namespace is not a context, here.
+ * init.c (expand_member_init): Remove DECL_CHAIN processing.
+ (build_offset_ref): Process OVERLOAD nodes.
+ * lang-specs.h (__HONOR_STD): Define if -fnew-abi or -fhonor-std.
+ * lex.c (identifier_type): Loop using OVL_CHAIN.
+ (see_typename): Set looking_for_typename to 2.
+ (real_yylex): Likewise.
+ (do_identifier): Expect OVERLOAD nodes instead of TREE_LISTs.
+ (do_scoped_id): Expect OVERLOAD nodes.
+ Change calling convention for qualified_lookup_using_namespace.
+ (build_lang_decl): Don't set in_namespace anymore.
+ * method.c (typevec_size): New global.
+ (build_overload_nested_name): Return if global_namespace.
+ Otherwise, always expect a declaration context.
+ (build_qualified_name): Likewise.
+ Make sure we don't write beyond typevec_size.
+ (build_decl_overload_real): Likewise.
+ Allocate one extra slot for the namespace.
+ (hack_identifier): Mark code dead.
+ Process OVERLOAD and NAMESPACE_DECL nodes.
+ * parse.y (program): Pop namespaces until in global namespace.
+ (extdef): In a using-declaration, don't discard the identifier if
+ there is no declaration.
+ (left_curly): Ignore type contexts which are namespaces.
+ (typename_sub2): Use IDENTIFIER_TYPE_VALUE to retrieve the type
+ used as scope.
+ * pt.c (template_class_depth): Expect types to be namespaces.
+ (determine_specialization): Simplify by expecting OVERLOAD nodes.
+ (push_template_decl): Push into namespace level.
+ Reset ctx if it is a namespace.
+ Set DECL_CONTEXT to current_namespace if not set already.
+ Ignore real contexts that are namespaces.
+ (mangle_class_name_for_template): Skip global_namespace.
+ Mangle other namespaces as declarations.
+ (lookup_template_function): Set type of OVERLOAD nodes to unknown.
+ (lookup_template_class): Push into namespace of context.
+ If the context is a namespace, set it to global_namespace.
+ Use id_context for mangling.
+ (for_each_template_parm): Handle OVERLOAD and NAMESPACE_DECL nodes.
+ (tsubst_friend_function): Ignore namespace contexts.
+ Push into namespace level.
+ (tsubst): Handle NAMESPACE_DECL nodes.
+ Remove DECL_CHAIN processing.
+ (type_unification_real): Recognize OVERLOAD instead of TREE_LIST nodes.
+ * ptree.c (print_lang_identifier): Print bindings.
+ (lang_print_xnode): Print OVERLOAD nodes.
+ * rtti.c (init_rtti_processing): Push type_info into std.
+ * search.c (lookup_fnfields_here): Expect OVERLOAD nodes.
+ (lookup_fnfields_1, get_virtuals_named_this, get_matching_virtual,
+ dfs_debug_mark, dfs_pushdecls, dfs_compress_decls, add_conversions,
+ lookup_fnfields_here): Likewise.
+ Process all nodes, instead of going through TREE_CHAIN.
+ * sig.c (build_signature_pointer_or_reference_type): Set context
+ to global_namespace.
+ (build_signature_table_constructor): Expect OVERLOAD nodes.
+ * spew.c (yylex): Save old setting of looking_for_typename.
+ * tree.c (decl_list_length): Remove.
+ (binding_init): New function.
+ (count_functions): Rewrite.
+ (is_overloaded_fn): Expect OVERLOAD nodes.
+ (really_overloaded_fn, get_first_fn, lvalue_type): Likewise.
+ (ovl_cons, scratch_ovl_cons, build_overload, build_overload_after,
+ ovl_member): New functions.
+ * typeck.c (require_complete_type): Expect OVERLOAD nodes.
+ (type_unknown_p): Likewise.
+ (require_instantiated_type): Likewise.
+ (build_component_ref): Declare code dead.
+ (build_x_function_call): Create and expect OVERLOAD nodes.
+ (build_function_call_real): Check for ::main only.
+ (build_unary_op): Likewise. Expect OVERLOAD nodes.
+ (convert_for_assignment): Check for TREE_LIST before accessing
+ TREE_VALUE.
+ * decl.c (duplicate_decls): Check for namespace bindings instead
+ of global bindings.
+ (pushdecl, push_overloaded_decl, lookup_tag, lookup_name_real,
+ lookup_name_current_level, start_decl, xref_tag,
+ finish_enum): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * search.c (lookup_field): Likewise.
+ (lookup_fnfields): Likewise.
+ (dfs_debug_mark): Likewise.
+ * decl.c (poplevel): Use SET_IDENTIFIER_TYPE_VALUE.
+ (poplevel_class, pop_from_top_level): Likewise.
+ * decl2.c (finish_method): Likewise.
+ * class.c (build_vtable): Use SET_IDENTIFIER_GLOBAL_VALUE.
+ * decl.c (record_builtin_type): Likewise.
+ (init_decl_processing, grokfndecl): Likewise.
+ * lex.c (get_time_identifier, do_identifier, do_scoped_id): Likewise.
+ (make_lang_type): Likewise.
+ * parse.y (make_thunk): Likewise.
+ * pt.c (tsubst): Likewise.
+ * tree.c (debug_binfo): Likewise.
+ * exception.cc, new.cc, new1.cc, new2.cc, tinfo.cc, tinfo.h,
+ tinfo2.cc, inc/new.h: Add std qualifications.
+ * inc/new: Wrap with namespace std if __HONOR_STD.
+ * inc/typeinfo: Likewise.
+
+Fri May 8 00:43:50 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_user_type_conversion_1): Handle second_conv
+ properly for templates.
+
+Thu May 7 17:09:25 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * method.c (build_decl_overload_real): Set TREE_USED flag to
+ zero for build_type_variants nodes as well.
+
+Wed May 6 19:27:09 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Don't tsubst the type of an IDENTIFIER_NODE.
+
+Wed May 6 16:49:48 1998 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.in (call.o, class.o, decl.o, decl2.o, errfn.o, error.o,
+ except.o, expr.o, friend.o, init.o, lex.o, method.o, pt.o, repo.o,
+ rtti.o, search.o, semantics.o, sig.o, tree.o, typeck.o, typeck2.o,
+ xref.o): Add toplev.h dependencies.
+
+Wed May 6 16:44:58 1998 Jeffrey A Law (law@cygnus.com)
+
+ * errfn.c (cp_error, cp_warning): Remove declarations for
+ error and warning respectively.
+
+Wed May 6 14:28:18 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c: Convert to using ctype macros defined in system.h.
+ * method.c: Likewise.
+ * xref.c: Likewise.
+ * lex.c: Likewise. Also remove redundant system header stuff.
+
+Wed May 6 06:36:41 1998 Robert Lipe <robertl@dgii.com>
+
+ * call.c, class.c, decl.c, decl2.c, errfn.c, error.c, except.c,
+ expr.c, friend.c, init.c, lex.c, method.c, pt.c, repo.c, rtti.c,
+ search.c, semantics.c, sig.c, tree.c, typeck.c, typeck2.c,
+ xref.c: Add include of toplev.h.
+
+Wed May 6 02:33:39 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (perm_manip): Also regenerate the RTL of an extern.
+ (copy_to_permanent): Use end_temporary_allocation.
+
+Tue May 5 23:54:04 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (expand_vec_init): The initialization of each array
+ element is a full-expression.
+
+Tue May 5 18:24:13 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * method.c (build_mangled_name): Add a call to build_type_variant
+ to get the right type.
+
+Tue May 5 01:25:03 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in: Add .SUFFIXES.
+
+ * cp-tree.def: Remove NAMESPACE_DECL.
+
+Sun May 3 01:32:14 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): Do evaluate arg even if it has empty
+ class type.
+ * decl.c (start_function): Don't push a member function.
+
+Thu Apr 30 18:59:23 1998 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.in (g++FAQ.info): Put -o option before input file.
+
+Thu Apr 30 13:05:33 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * gxxint.texi: Add info for squangling codes K and B.
+
+Tue Apr 28 13:22:01 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * semantics.c (begin_stmt_expr): Avoid duplicating the effect of
+ the expression in templates.
+ (finish_stmt_expr): Likewise.
+
+1998-04-28 Brendan Kehoe <brendan@cygnus.com>
+
+ * decl2.c (ambiguous_decl): Fix NAME parm to be a tree, not int.
+
+Mon Apr 27 13:58:10 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * decl.c (maybe_push_to_top_level): Always clear
+ current_template_parms and processing_template_decl.
+ (pushtag): Remove check of current_class_type and some comments,
+ since maybe_push_to_top_level no longer creates confusion.
+
+Sun Apr 26 12:10:18 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * cp-tree.h (CLASSTYPE_IS_TEMPLATE): New macro.
+ (DECL_CLASS_TEMPLATE_P): Likewise.
+ (DECL_PRIMARY_TEMPLATE): Likewise.
+ (PRIMARY_TEMPLATE_P): Use it.
+ (push_template_decl_real): New function.
+ (redeclare_class_template): Take new template parameters as
+ input.
+ (is_specialization_of): New function.
+ (comp_template_args): Declare.
+ * decl.c (pushtag): Handle friend template classes.
+ (xref_tag): Likewise. Use new calling convention for
+ redeclare_class_template.
+ * decl2.c (grok_x_components): Handle friend templates.
+ * friend.c (is_friend): Use is_specialization_of where
+ appropriate. Deal with friend class templates.
+ (make_friend_class): Let a class template be friends with itself.
+ * pt.c (comp_template_args): Remove declaration.
+ (tsubst_friend_class): New function.
+ (push_template_decl_real): New function.
+ (push_template_decl): Use it.
+ (redeclare_class_template): Adjust for new calling convention.
+ (comp_template_args): Give it external linkage.
+ (instantiate_class_type): Use tsubst_friend_class to deal
+ with friend templates.
+ * typeck.c (comptypes): Use comp_template_args, rather than
+ expanding it inline.
+ * parse.y (component_decl): Handle a nested template type
+ like other component type declarations.
+
+ * pt.c (check_explicit_specialization): Handle overloaded
+ constructors correctly.
+
+ * pt.c (mabybe_get_template_decl_from_type_decl): New function.
+ (lookup_template_class): Use it.
+
+Thu Apr 23 21:19:06 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.def: Add WRAPPER. USER_CONV now only has two ops.
+ * cp-tree.h: Add WRAPPER support.
+ * call.c (add_candidate): Split out from add_*_candidate fns.
+ (build_over_call): Take the candidate instead of function and args.
+ Enforce access control here. Emit overload warnings here.
+ (add_warning): New fn.
+ (joust): Add WARN parm. If not set, call add_warning instead of
+ printing a warning. Re-enable some warnings.
+ (tourney): Pass it.
+ (convert_like): Adjust.
+ (build_new_op): Adjust.
+ (build_new_function_call): Adjust.
+ (build_user_type_conversion_1): Adjust.
+ (USER_CONV_FN): Adjust.
+ * tree.c (build_expr_wrapper, build_expr_ptr_wrapper,
+ build_int_wrapper): New fns.
+
+Thu Apr 23 18:27:53 1998 Mark P. Mitchell <mmitchell@usa.net>
+
+ * pt.c (unify): Fix typo in previous change.
+
+Thu Apr 23 09:32:58 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * error.c (dump_type_real): Declare canonical_name.
+
+ * typeck.c (comp_target_types): Fix PMFs.
+
+Wed Apr 22 13:24:48 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * class.c (finish_struct): Set TREE_PRIVATE and TREE_PROTECTED for
+ the DECL_RESULTs of a member TEMPLATE_DECL, not just the
+ TEMPLATE_DECL.
+
+ * pt.c (tsubst): Decrease the template-level of
+ TEMPLATE_TEMPLATE_PARMS. Likewise for the DECL_INITIAL of a
+ TEMPLATE_PARM_INDEX.
+ (template_decl_level): New function.
+ (unify): Make sure to record unifications for template
+ parameters, even when the parameters exactly match the arguments.
+ Combine duplicated code for TEMPLATE_TEMPLATE_PARMs and
+ TEMPLATE_TYPE_PARMS. Don't try to unify template parameters that
+ aren't from the level we're currently working on.
+
+Tue Apr 21 22:00:04 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * errfn.c (cp_thing): Use xrealloc, not xmalloc, to copy memory.
+
+ * decl2.c (check_member_template): Set DECL_IGNORED for member
+ class templates, too.
+
+ * decl2.c (grokfield): Remangle the name of a member TYPE_DECL.
+
+Tue Apr 21 18:59:11 1998 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * decl.c (duplicate_decls): Only check DECL_FRIEND_P if function.
+
+Tue Apr 21 14:22:00 1998 Jeffrey A Law (law@cygnus.com)
+
+ * cp-tree.h (intTI_type_node, unsigned_intTI_type_node): Declare.
+ * decl.c (intTI_type_node, unsigned_intTI_type_node): Define.
+ (init_decl_processing): Handle TI types.
+ * typeck.c (unsigned_type, signed_type): Handle TI types.
+
+Sat Apr 18 15:25:21 1998 Jim Wilson <wilson@cygnus.com>
+
+ * g++spec.c (lang_specific_driver): New argument in_added_libraries.
+ New local added_libraries. Increment count when add library to
+ arglist.
+
+Fri Apr 17 21:25:00 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * cp-tree.h (type_as_string_real): New function.
+ * pt.c (mangle_class_name_for_template): Use it.
+ * error.c (dump_aggr_type): Change prototype.
+ (dump_type_prefix): Likewise.
+ (dump_type_suffix): Likewise.
+ (dump_type_real): Convert from dump_type. If desired, the
+ "canonica" name of a typedef, i.e., the name of the underlying
+ type, can be printed.
+ (dump_type): Call dump_type_real.
+
+Fri Apr 17 14:30:45 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (lang_decode_option): -fnew-abi implies -fvtable-thunks.
+
+ * typeck.c (comp_target_types): Tweak pedantic case.
+ (comp_target_parms): Tweak pedantic case. Clean up somewhat.
+ Return -1 or 1 instead of 1 or 2.
+ (compparms): Remove STRICT handling.
+ (convert_for_assignment): Fix handling of pmfs.
+
+Fri Apr 17 14:04:16 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * typeck.c (comp_target_types): Handle references like pointers.
+ (comp_target_parms): Note that return code from comp_target_types
+ can be negative to indicate failure.
+
+Fri Apr 17 09:10:52 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * Make-lang.in (c++.all.build): Don't depend on $(DEMANGLER_PROG),
+ which requires a working target compiler to build.
+
+Fri Apr 17 08:57:35 1998 Jeffrey A Law (law@cygnus.com)
+
+ * tree.c (avoid_overlap): Add prototype.
+
+ * spew.c (num_tokens): Add prototype.
+ (nth_noken, add_token, consume_token, debug_yychar): Likewise.
+
+ * search.c (dfs_check_overlap): Add prototype.
+ (dfs_no_overlap_yet): Likewise.
+
+ * pt.c (original_template): Add prototype.
+ (inline_needs_template_parms): Likewise.
+ (push_inline_template_parms_recursive): Likewise.
+ (retrieve_specialization, register_specialization): Likewise.
+ (print_candidates, reduce_template_parm_level): Likewise.
+ (build_template_decl, mark_template_parm): Likewise.
+ (tsubst_friend_function, get_bindings_real): Likewise.
+
+ * method.c (start_squangling): Add prototype.
+ (end_squangling, check_ktype, issue_ktype): Likewise.
+ (build_overloaded_scope_ref, check_btype): Likewise.
+ (build_mangled_template_parm_index): Likewise.
+
+ * lex.c (init_cpp_parse): Add prototype.
+ (handle_cp_pragma, handle_sysv_pragma): Likewise.
+ (reduce_cmp, token_cmp): Likewise.
+
+ * except.c (call_eh_info): Add prototype.
+ (push_eh_info, get_eh_info, get_eh_value, get_eh_type): Likewise.
+ (get_eh_caught, get_eh_handlers, do_pop_exception): Likewise.
+
+ * decl2.c (is_namespace_ancestor): Add prototype.
+ (namespace_ancestor, add_using_namespace): Likewise.
+ (ambiguous_decl): Likewise.
+
+ * decl.c (indent): Add prototype.
+
+ * call.c (add_template_candidate_real): Add prototype.
+
+Fri Apr 17 01:57:12 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (build_expr_from_tree): Just return a PMF.
+
+Fri Apr 17 00:45:12 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * typeck2.c (process_init_constructor): Don't strip cv-qualifiers
+ when doing initializations.
+
+ * pt.c (unify): Use comptypes to compare type args.
+
+Fri Apr 17 00:24:22 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (duplicate_decls): Fix check for when it's safe to free
+ the new decl.
+
+ * pt.c (mangle_class_name_for_template): Don't pass a typedef type
+ to type_as_string.
+
+Thu Apr 16 17:47:30 1998 Jeffrey A Law (law@cygnus.com)
+
+ * pt.c (build_template_parm_index): Add prototype.
+
+ * search.c (my_tree_cons): Don't clear words outside the
+ newly allocated node.
+
+Wed Apr 15 15:34:44 1998 Dave Brolley <brolley@cygnus.com>
+
+ * lex.c (init_parse): Now returns char* containing the filename.
+
+Wed Apr 15 13:20:06 1998 John Carr <jfc@mit.edu>
+ Jeff Law <law@cygnus.com>
+
+ * errfn.c: Rework to avoid problems when HOST_WIDE_INT is longer
+ than a pointer.
+
+Sun Apr 12 22:31:19 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * cvt.c (cp_convert_to_pointer): Use TYPE_PRECISION.
+
+Fri Apr 10 12:16:49 1998 Benjamin Kosnik <bkoz@loony.cygnus.com>
+
+ * decl.c (duplicate_decls): Don't warn for redundant decls if
+ friend: let add_friend take care of it.
+
+Thu Apr 9 02:40:48 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * sig.c (build_signature_pointer_constructor): Don't set
+ TREE_HAS_CONSTRUCTOR for a signature pointer.
+ * cvt.c (ocp_convert): Don't force a temporary for internal structs.
+ * init.c (resolve_offset_ref): Warn about implicit & on pmfs
+ here, too.
+ * typeck.c (build_unary_op): Only allow taking the address of a
+ real constructor.
+ * typeck2.c (digest_init): Simplify.
+ (store_init_value): Don't pedwarn about using { } for pmfs.
+
+Thu Apr 9 22:16:57 1998 Per Bothner <bothner@cygnus.com>
+
+ * cp-tree.h (start_decl): Update prototype.
+ * decl.c (start_decl): Like the C version, new parameters
+ for the attributes. Call cplus_decl_attributes here,
+ (pushdecl): Like C version, do build_type_copy if TYPE_DECL,
+ (grokdeclarator): Pass NULL for new start_decl arguments.
+ * pt.c (tsubst_expr): Likewise.
+ * parse.y: Merge cplus_decl_attribute calls into start_decl calls.
+ * typeck.c (common_type): Check TYPE_MAIN_VARIANT.
+ * lex.c (build_lang_decl): Add lang_name_java.
+ * class.c (push_lang_context): Add lang_name_java.
+ * method.c (build_mangled_name): Check for is_java_type.
+
+Thu Apr 9 22:16:57 1998 Benjamin Kosnik <bkoz@loony.cygnus.com>
+
+ * decl.c (grokdeclarator): Check TYPE_MAIN_VARIANT.
+ * call.c (build_scoped_method_call): Check for TREE_CODE for
+ VOID_TYPE instead of type == void_type_node.
+ (build_method_call): Likewise.
+ * decl.c (lookup_name_real): Likewise.
+ (grokdeclarator): Likewise.
+ (start_decl): Likewise.
+ (grokparms): Likewise.
+ (start_function): Likewise.
+ (finish_function): Likewise.
+ (start_method): Likewise.
+
+Thu Apr 9 00:18:44 1998 Dave Brolley (brolley@cygnus.com)
+
+ * lex.c (finput): New variable.
+ (init_cpp_parse): Renamed from init_parse.
+ (init_parse): Handle !USE_CPPLIB. Call init_cpp_parse when finished.
+ (finish_parse): New function.
+ * cp-tree.h (init_lex, init_parse): Remove declarations.
+
+Mon Apr 6 02:25:05 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_call): Still evaluate the actual argument.
+ * class.c (is_empty_class): Update for -fnew-abi.
+
+ * decl2.c: -fnew-abi implies -fsquangle.
+
+ * method.c (do_build_assign_ref): Don't do anything to copy
+ an empty class.
+ (do_build_copy_constructor): Likewise.
+ * call.c (build_over_call): Likewise.
+
+Sat Apr 4 18:43:58 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (avoid_overlap): Return a value.
+
+Sat Apr 4 12:52:35 1998 Jeffrey A Law (law@cygnus.com)
+
+ * method.c (check_btype): Add missing argument to xrealloc.
+ (check_ktype): Likewise.
+
+Fri Apr 3 02:22:59 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ Implement empty base optimization.
+ * class.c (finish_struct_1): Add vbase fields earlier. Set
+ CLASSTYPE_SIZE of an empty base to 0. Types with bases can be empty.
+ * search.c (dfs_check_overlap, dfs_no_overlap_yet): New fns.
+ (types_overlap_p): New fn.
+ * tree.c (avoid_overlap): New fn.
+ (build_base_fields): Use it to avoid overlapping empty bases.
+ * cp-tree.h, decl2.c, lang-options.h: Add -fnew-abi.
+
+ * decl.c (cplus_expand_expr_stmt): Strip unused INDIRECT_REFs.
+
+ Re-implement allocation of base class subobjects.
+ * tree.c (unshare_base_binfos): New fn.
+ (layout_basetypes): Use it. Now handles offsets of both virtual and
+ non-virtual bases, after layout_type.
+ (layout_vbasetypes): Remove.
+ (build_base_fields): Generate FIELD_DECLs for each non-virtual base.
+ (build_vbase_pointer_fields): Split out from old layout_basetypes.
+ * class.c (finish_base_struct): Lose offset handling code.
+ Move nonvdtor warning here. Don't mess with t_binfo anymore.
+ (finish_struct_1): Don't mess with t_binfo anymore. Use fns above.
+ * cp-tree.h: Adjust.
+
+Thu Apr 2 14:25:13 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h: Lose CLASSTYPE_VBASE_SIZE, some unused stuff.
+ * decl.c, decl2.c, pt.c, ptree.c, lex.c: Likewise.
+ * class.c (duplicate_tag_error): Likewise.
+ (finish_struct_1): Set CLASSTYPE_SIZE, CLASSTYPE_MODE, CLASSTYPE_ALIGN.
+ * tree.c (layout_vbasetypes): Update from layout_record, remove
+ var_size support, use CLASSTYPE_SIZE instead of CLASSTYPE_VBASE_SIZE.
+ (layout_basetypes): Likewise.
+
+Wed Apr 1 18:22:25 1998 Jeffrey A Law (law@cygnus.com)
+
+ * class.c, Make sure system.h is included just after config.h.
+ Delete lingering stdio and errno references too.
+ * decl.c, errfn.c, parse.y, ptree.c search.c, xref.c: Likewise.
+
+Wed Apr 1 15:38:36 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * friend.c (is_friend): Fix access control for local classes.
+
+ * class.c (is_empty_class): New fn.
+ * call.c (build_call): Don't pass empty class objects to a function.
+
+Wed Apr 1 14:58:35 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * call.c (build_over_call): Do name resolution for default
+ arguments of function templates in the scope of the templates.
+
+Tue Mar 31 13:43:57 1998 Jeffrey A Law (law@cygnus.com)
+
+ * call.c: Include system.h. Remove includes, declarations and
+ defines provided by system.h.
+ * class.c, cvt.c, decl.c, decl2.c, errfn.c error.c: Likewise.
+ * except.c, expr.c friend.c, g++spec.c, init.c, input.c: Likewise.
+ * lex.c, parse.y, pt.c, ptree.c repo.c rtti.c, search.c: Likewise.
+ * semantics.c, sig.c, spew.c, tree.c, typeck.c: Likewise.
+ * typeck2.c, xref.c: Likewise.
+ * Makefile.in: Dependencies updated as appropriate.
+ * Make-lang.in: Likewise.
+
+Mon Mar 30 12:15:00 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (fn_type_unification): Allow incomplete unification without
+ an immediate error message.
+
+Mon Mar 30 08:55:42 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (member_p): New fn.
+ * decl2.c (finish_file): Only set DECL_STATIC_FUNCTION_P for
+ initializing class members.
+
+ * cp-tree.def (TEMPLATE_PARM_INDEX): Class 'x'.
+ * ptree.c (lang_print_xnode): Handle TEMPLATE_PARM_INDEX.
+
+ * call.c (build_method_call): Handle non-scoped destructors, too.
+ * pt.c (tsubst_copy): Likewise.
+
+ * pt.c (print_template_context): Split out...
+ (push_tinst_level): ...from here.
+
+ * friend.c (is_friend): Don't pass a type to decl_function_context.
+
+ * typeck.c (convert_for_initialization): Always hand off
+ conversions to class type.
+
+Sun Mar 29 20:01:59 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * friend.c (is_friend): Local classes have the same access as the
+ enclosing function.
+
+Sun Mar 29 00:47:32 1998 Jeffrey A Law (law@cygnus.com)
+
+ * typeck.c (expand_target_expr): Delete dead function.
+
+ * search.c: Put various prototypes inside #ifdef MI_MATRIX.
+
+ * repo.c (save_string): Delete dead function.
+
+ * method.c (thunk_printable_name): Delete dead function.
+
+ * lex.c (yynextch): Delete dead function.
+
+ * expr.c (tree_extract_aggr_init): #if 0 out.
+
+ * except.c (do_unwind): Delete dead function.
+ (easy_expand_asm): Likewise.
+
+ * cvt.c (build_conversion_type_1): Delete dead function.
+
+ * cp-tree.h (push_expression_obstack): Declare.
+
+ * call.c (source_type): #if 0 out.
+
+ * class.c (alter_access): Remove unused label. Add braces
+ around empty else clause.
+
+ * lex.c (yyprint): Fix argument to printf.
+
+Sat Mar 28 17:43:52 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (tsubst): Clear TREE_USED for new FUNCTION_DECLs.
+
+ * pt.c (instantiate_class_template): Make sure template
+ arguments are permanent.
+ * init.c (resolve_offset_ref): Don't go looking around in
+ template types.
+
+ * semantics.c: Add routines to handle expressions, and some
+ declaration processing.
+ * parse.y: Use them.
+ (current_class_depth): Move declaration to cp-tree.h.
+ * parse.c: Regenerated.
+ * cp-tree.h: Use them.
+ (current_class_depth): Declare.
+ * pt.c (tsubst_copy): Use begin_stmt_expr and finish_stmt_expr.
+
+Fri Mar 27 20:23:18 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * error.c (dump_decl): Be a bit more explicit with template
+ type arguments, when verbose.
+
+Fri Mar 27 18:16:40 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * inc/exception: Reorder closing braces.
+
+Fri Mar 27 13:22:18 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (redeclare_class_template): New function.
+ * cp_tree.h (redeclare_class_template): Declare it.
+ * decl.c (xref_tag): Use it.
+
+Thu Mar 26 11:16:30 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): Check IS_AGGR_TYPE, not
+ TYPE_LANG_SPECIFIC.
+ * typeck.c (convert_arguments): Likewise.
+
+ * decl.c (grokdeclarator): Remove const and volatile from type after
+ setting constp and volatilep.
+
+ * class.c (finish_struct_1): Don't warn about bool bitfield larger
+ than one bit.
+
+Thu Mar 26 10:25:52 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (convert_nontype_argument): STRIP_NOPS where appropriate.
+
+Thu Mar 26 10:24:05 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * call.c (build_object_call): Complain about ambiguous operator(),
+ rather that crashing.
+ (build_new_op): Likewise.
+ (build_op_delete_call): Likewise.
+
+Thu Mar 26 10:23:24 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * cvt.c (perform_qualification_conversions): Use comp_target_types
+ instead of comp_ptr_ttypes.
+
+Wed Mar 25 16:10:50 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * cp-tree.h (enforce_access): Declare.
+ * call.c (enforce_access): Make it extern, not static.
+ * class.c (alter_access): Use enforce_access; modify code for ISO
+ compliance, rather than ARM rules.
+
+Wed Mar 25 12:10:45 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * cp-tree.h: Fix typo.
+
+Wed Mar 25 02:01:02 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * expr.c (cplus_expand_expr): Only do PCC_STATIC_STRUCT_RETURN thing
+ if (aggregate_value_p (type)).
+
+ * decl2.c (constructor_name_full): Handle TYPENAME_TYPE.
+
+Tue Mar 24 16:12:01 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * tree.c (mapcar): When dealing with a DECL, use it's constant
+ value, if any.
+ * pt.c (lookup_template_class): Don't mangle the names of template
+ classes whose arguments are unknown.
+
+ * pt.c (tsubst_expr): Handle GOTO_STMT correctly.
+
+Tue Mar 24 12:21:55 1998 Benjamin Kosnik <bkoz@lisa.cygnus.com>
+
+ * decl.c (init_decl_processing): Set TYPE_PRECISON for bools to 1.
+
+Tue Mar 24 12:21:48 1998 Jim Wilson <wilson@cygnus.com>
+
+ * decl.c (init_decl_processing): Initialize TYPE_MAX_VALUE for
+ boolean_type_node to 1.
+
+Tue Mar 24 10:23:47 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * error.c (dump_expr): Remove unused variable `l'.
+
+ * pt.c (for_each_template_parm): New function, created by
+ converting uses_template_parms.
+ (tree_fn_t): New typedef.
+ (uses_template_parms): Use it.
+ (mark_template_parm): New function.
+ (push_template_decl): Check that the argument list of a partial
+ specialization uses all the template parameters.
+
+ * Make-lang.in (c++filt): Don't delete cxxmain.c after we're done
+ with it; we might want it for debugging.
+ * cp-tree.h (type_unification): Change interface.
+ * class.c (finish_struct_1): Skip nested template types, just like
+ ordinary nested types.
+ (instantiate_type): Use new interface to type_unification.
+ * lex.c (init_lex): Add __sz as opname for sizeof.
+ * method.c (build_overload_scope_ref): New function.
+ (build_overload_int): Handle complex expressions. Set
+ numeric_output_need_bar if necessary.
+ (build_overload_value): Handle non-PARM_DECL nodes; this
+ routine is now used by build_overload_int. Remove some
+ assignments to numeric_output_need_bar. Use
+ build_overload_scope_ref.
+ (build_qualified_name): Note that some template mangled names end
+ with digits, and set numeric_output_need_bar appropriately. Use
+ build_underscore_int.
+ * pt.c (unify): Change interface.
+ (type_unification_real): Likewise.
+ (determine_specialization): Use new interfaces.
+ (tsubst): Deal gracefully with situations in which the argument
+ vector is not fully filled.
+ (fn_type_unification): Use new interfaces.
+ (type_unification): Likewise. Remove NOP_EXPR hack.
+ (type_unification_real): Likewise.
+ (unify): Likewise. Deal with unification of complex expressions.
+
+Mon Mar 23 12:24:37 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (complete_template_args): Initialize skip properly.
+
+ * decl.c (make_typename_type): Revert.
+ (make_implicit_typename): Remove.
+ (lookup_name_real): Don't call it. Call lookup_field if we see a
+ TYPE_DECL from a template base.
+ * search.c (lookup_field): Do implicit typename stuff.
+
+Sun Mar 22 00:50:42 1998 Nick Clifton <nickc@cygnus.com>
+ Geoff Noer <noer@cygnus.com>
+
+ * Makefile.in: Various fixes for building cygwin32 native toolchains.
+ * Make-lang.in: Likewise.
+
+Fri Mar 20 18:07:39 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * pt.c (tsubst, TEMPLATE_TEMPLATE_PARM): Simplify.
+
+Fri Mar 20 10:42:07 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (make_implicit_typename): Rewrite removed code.
+ (make_typename_type): Call it if the type we look up comes from
+ a base that uses template parms.
+
+ * pt.c (complete_template_args): Rewrite.
+ (tsubst, FUNCTION_DECL): Use it.
+
+Fri Mar 20 08:12:43 1998 H.J. Lu (hjl@gnu.org)
+
+ * semantics.c (finish_asm_stmt): Fix combine strings. Call
+ c_expand_asm_operands () if output_operands, input_operands or
+ clobbers is not NULL_TREE.
+
+Fri Mar 20 00:10:19 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * pt.c (complete_template_args): New function.
+ (get_bindings): Deal with specializations of function templates
+ with return type containing parameters from outer class
+ templates.
+ (tsubst, TEMPLATE_TEMPLATE_PARM): When reducing parameter level,
+ substitute arguments and compose a new type.
+
+Thu Mar 19 19:01:48 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (tsubst): Clear DECL_PENDING_INLINE_INFO for new
+ FUNCTION_DECLs.
+
+Thu Mar 19 11:51:58 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (make_implicit_typename): Lose useless code.
+
+ * call.c (standard_conversion): Handle A* -> const A* properly.
+
+ * pt.c (get_bindings_real): Rename from get_bindings. Add
+ check_rettype parm.
+ (get_bindings): Pass 1.
+ (get_bindings_overload): Pass 0.
+
+Wed Mar 19 09:08:12 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (check_explicit_specialization): When reverting a static
+ member function, also remove the `this' parameter from
+ last_function_parms.
+
+Thu Mar 19 02:27:48 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst_copy, CONST_DECL): Don't bother tsubsting
+ a function context.
+
+ * decl.c (store_bindings): Use free_binding_vecs.
+ (pop_from_top_level): Likewise.
+
+Wed Mar 18 12:41:43 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (make_implicit_typename): Only change the type of a
+ TYPENAME_TYPE.
+
+Wed Mar 18 10:09:51 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * semantics.c: New file, containing routines to perform the
+ semantic phase of parsing.
+ * parse.y: Use it.
+ * pt.c (tsubst_expr): Likewise.
+ * cp-tree.h: Declare the various functions in semantics.c.
+ Provide macros to access _STMT tree nodes.
+ * cp-tree.def: Add ASM_STMT tree node.
+ * Makefile.in, Make-lang.in: Add dependencies on and for
+ semantics.c.
+
+Wed Mar 18 00:24:10 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (push_template_decl): Only check primary templates.
+
+ * pt.c (check_explicit_specialization): Complain about default args
+ in explicit specialization.
+
+ * parse.y (nomods_initdcl0): Also call cp_finish_decl for a
+ constructor_declarator.
+
+Tue Mar 17 14:44:54 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * typeck2.c (build_x_arrow): Don't crash when an aggregate type
+ has no overloaded operator ->.
+
+ * call.c (build_field_call): Don't crash when presented with a
+ field that is actually a nested type.
+
+ * decl.c (pushtag): Deal with friend class injection in local
+ classes.
+
+ * call.c (build_object_call): Don't crash if OBJ is a
+ pointer-to-member-function.
+
+Tue Mar 17 11:40:26 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (push_template_decl): Complain about template with C linkage,
+ anonymous template class.
+
+Mon Mar 16 12:10:39 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (pushclass): Only use the mi_matrix stuff #ifdef MI_MATRIX.
+ * search.c: Likewise.
+
+ * lex.c (do_pending_defargs): Only call
+ maybe_{begin,end}_member_template_processing for FUNCTION_DECLs.
+
+ * parse.y (initdcl0_innards): Move maybeasm back into initdcl0 et al.
+
+Mon Mar 16 10:47:22 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * parse.y: Deal with CONSTRUCTORS in new_initializers.
+
+Mon Mar 16 10:54:21 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (tsubst_copy): Deal with BIND_EXPR in a way that more
+ closely mimics the behavior in parse.y.
+ (tsubst_expr): Return the resulting BLOCK when making a tsubst'ing
+ into a compound statement.
+
+Sun Mar 15 02:07:26 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (TEMPLATE_PARMS_FOR_INLINE): New macro.
+ * pt.c (inline_needs_template_parms): New fn.
+ (original_template): New fn.
+ (push_inline_template_parms_recursive): New fn.
+ (maybe_begin_member_template_processing): Use them.
+ (maybe_end_member_template_processing): Likewise.
+ (is_member_or_friend_template): Rename to is_member_template.
+ Member functions of local classes are never member templates.
+
+Sun Mar 15 01:14:22 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * lex.c (do_identifier): Handle TEMPLATE_DECL that was
+ added in the class scope to catch redefinition error.
+
+ * pt.c (reduce_template_parm_level): Also copy
+ the DECL_TEMPLATE_PARMS field.
+
+Sun Mar 15 10:54:08 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (tsubst): Clear TYPE_REFERENCE_TO when creating a
+ reduced-level template type parameter.
+
+Sun Mar 15 12:26:02 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * cp-tree.h (struct lang_decl_flags): Add needs_final_overrider.
+ (DECL_NEEDS_FINAL_OVERRIDER_P): New macro.
+ * class.c (override_one_vtable): Set DECL_NEEDS_FINAL_OVERRIDER_P.
+ * decl.c (duplicate_decls): Propagate it.
+ * typeck2.c (abstract_virtuals_error): Use two loops to emit
+ abstract virtual functions and virtual functions which need a
+ final overrider separately.
+
+Thu Mar 12 09:39:40 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * lang-specs.h: Properly put brackets around array elements in
+ initializer.
+
+ * typeck.c (build_binary_op_nodefault): Correctly place parens around
+ && and || in expression.
+
+Thu Mar 12 09:26:04 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * call.c (default_parm_conversions): Remove prototype definition.
+ (build_method_call): Remove unused variable result.
+
+ * cvt.c (ocp_convert): Remove unused variable conversion.
+
+ * decl2.c (ambiguous_decl): Add explicit parameter definition for name.
+
+ * except.c (do_unwind): #if 0 definition of unused variables fcall
+ and next_pc.
+
+ * expr.c (extract_scalar_init): #if 0 prototype and function
+ definition.
+
+ * init.c (expand_aggr_init_1): Remove unused variable init_type.
+ (build_new_1): Remove unused variable t.
+
+ * pt.c (instantiate_class_template): Remove unused variable newtag;
+ cast called function return value to void.
+ (do_decl_instantiation): Remove unused variables name and fn.
+
+ * tree.c (get_type_decl): Add default return to shut up compiler from
+ complaining control reaches end of non-void function.
+
+ * typeck.c (build_x_conditional_expr): Remove unused variable rval.
+
+Thu Mar 12 09:12:15 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * call.c (default_parm_conversions): Remove prototype definition.
+ (build_method_call): Remove unused variable result.
+ (build_over_call): Add default case in enumeration switch.
+
+Thu Mar 12 08:39:13 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * decl2.c (lang_decode_option): Change j's type to size_t.
+
+ * tree.c (layout_vbasetypes): record_align and desired_align are of
+ type unsigned int; const_size and nonvirtual_const_size likewise.
+
+Wed Mar 11 07:25:20 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * parse.y (new_initializer): Make sure all initializers are
+ lists.
+
+Tue Mar 10 07:32:36 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * decl2.c (import_export_decl): Mark tinfo functions for
+ cv-qualified versions of class types as DECL_NOT_REALLY_EXTERN.
+
+Fri Mar 6 23:27:35 1998 Jeffrey A Law (law@cygnus.com)
+
+ * method.c: Fix typo.
+
+Fri Mar 6 10:06:59 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * method.c: Include "system.h" to get stdlib.h, stdio.h,
+ ctype.h, string.h, etc.
+ (issue_nrepeats): Add default case in enumeration switch.
+ (check_btype): Likewise.
+ (process_overload_item): Likewise.
+
+ * Makefile.in (method.o): Depend on system.h.
+
+Wed Mar 4 22:26:53 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * lex.c (do_scoped_id): Fix parenthesizing.
+
+Wed Mar 4 12:11:53 1998 Michael Tiemann <tiemann@axon.cygnus.com>
+
+ * rtti.c (get_tinfo_fn_dynamic): If this function is called an
+ FLAG_RTTI is unset, initialize type info machinery and continue
+ with FLAG_RTTI enabled.
+ (get_typeid): Likewise.
+
+Wed Mar 4 11:47:55 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (unary_complex_lvalue): &D::i has type B::* if i comes
+ from B.
+
+Wed Mar 4 11:28:08 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (finish_member_template_decl): Deal more gracefully with
+ invalid declarations.
+
+Tue Mar 3 01:38:17 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c, decl.c, decl2.c, init.c, rtti.c, typeck.c, typeck2.c,
+ cp-tree.h: Clean up more old overloading code, old RTTI code, and
+ some formatting quirks.
+
+ * call.c, class.c, cp-tree.h, cvt.c, decl.c, init.c, lex.c,
+ method.c, pt.c, ptree.c, typeck.c: Remove support for
+ -fno-ansi-overloading and overloading METHOD_CALL_EXPR.
+ * class.h: Remove.
+ * Makefile.in: Adjust.
+
+ * pt.c (unify): Don't allow reduced cv-quals when strict.
+
+ * call.c, class.c, pt.c, cp-tree.h: Remove nsubsts parm from
+ *type_unification* and unify.
+
+Mon Mar 2 12:11:06 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (explicit_template_type): Remove TEMPLATE keyword.
+ (nested_name_specifier): And add it before this use.
+ (typename_sub0): And this use. Also add use without the keyword.
+ (typename_sub1): Likewise.
+ * pt.c (instantiate_class_template): Don't actually instantiate
+ anything if our type uses template parms.
+
+Mon Mar 2 11:04:59 1998 Jim Wilson <wilson@cygnus.com>
+
+ * decl.c (start_function): Don't call temporary_allocation for a
+ nested function.
+
+Sun Mar 1 21:06:37 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Don't mess with friends if
+ our type uses template parms.
+
+Sat Feb 28 12:06:44 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (nested_name_specifier): Use explicit_template_type.
+ (typename_sub): Allow a template_type, an explicit_template_type,
+ or an implicit template type at the end.
+ * lex.c (yyprint): Handle a PTYPENAME being a TEMPLATE_DECL.
+ * decl.c (make_typename_type): Handle template-id where the name
+ is a TEMPLATE_DECL.
+ * call.c (build_scoped_method_call): Handle member template
+ destructor call.
+ * pt.c (tsubst_copy, METHOD_CALL_EXPR): Don't assume a member
+ destructor is represented by the type.
+
+ * cp-tree.h (TYPENAME_TYPE_FULLNAME): New macro.
+ * parse.y (nested_name_specifier): Add 'template' case.
+ (explicit_template_type): New rule.
+ (typename_sub): Use it.
+ * decl.c (make_typename_type): Handle getting a template-id for NAME.
+ * pt.c (tsubst): Likewise.
+
+Fri Feb 27 11:17:50 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (add_to_template_args): Fix thinko.
+ (instantiate_class_template): Call it later.
+
+ * pt.c (get_class_bindings): Add outer_args parm.
+ (most_specialized_class): Likewise.
+ (instantiate_class_template): Pass it.
+ (more_specialized_class): Likewise.
+ (lookup_template_class): Get context from template if none
+ was specified.
+ (finish_member_template_decl): Don't do anything with a
+ partial specialization.
+ * decl2.c (check_member_template): Use IS_AGGR_TYPE instead of
+ AGGREGATE_TYPE_P.
+ * class.c (finish_struct): Member class templates have already been
+ checked for name clashes.
+ * decl.c (pushdecl_with_scope): Handle pushing at class level.
+
+Fri Feb 27 02:25:16 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst, TEMPLATE_DECL): Support member class templates.
+ (tsubst, *_PARM): Support multiple levels of template classes.
+ (instantiate_class_template): Look up the pattern from the
+ original template.
+ (lookup_template_class): Handle getting a template for d1.
+ (push_template_decl): Correct setting of 'primary'.
+ (reduce_template_parm_level): Add 'levels' parm.
+ (finish_member_template_decl): Support member class templates.
+ (template_class_depth): Handle multiple levels.
+ * parse.y (component_decl_1, fn.def2): Remove member template case.
+ (component_decl): Add member template cases.
+ * decl2.c (check_member_template): We now handle member template
+ classes.
+ * decl.c (pushtag): Handle member templates.
+ * method.c (do_inline_function_hair): Don't touch
+ IDENTIFIER_GLOBAL_VALUE.
+ * init.c (build_offset_ref): If name isn't an identifier, just
+ return it.
+ * spew.c (yylex): Handle PTYPENAME like TYPENAME.
+
+ * typeck.c (get_delta_difference): Do adjust for conversions to
+ and from virtual base.
+
+Wed Feb 25 09:51:29 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (get_delta_difference): Give hard error for conversion
+ from virtual base.
+
+ * cp-tree.h: Tweak formatting.
+
+Wed Feb 25 00:35:33 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (push_namespace): Handle redeclaration error.
+
+ * cp-tree.h (IDENTIFIER_NAMESPACE_VALUE): New macro.
+ (IDENTIFIER_NAMESPACE_BINDINGS): New macro.
+ (NAMESPACE_BINDING): New macro.
+ (IDENTIFIER_GLOBAL_VALUE): Use NAMESPACE_BINDING.
+ * *.c: Use them.
+
+ * pt.c (push_template_decl): Use innermost_args.
+
+ * decl.c (get_unique_name): Tweak from earlier in the name.
+
+Tue Feb 24 22:15:04 1998 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * cp-tree.def: Add CPLUS_BINDING node.
+ * cp-tree.h (tree_binding): New struct.
+ (BINDING_SCOPE, BINDING_VALUE): New macros.
+ (current_namespace, global_namespace): Declare extern.
+ (struct lang_decl_flags): New field in_namespace.
+ (DECL_NAMESPACE_USING, DECL_NAMESPACE_USERS): New macros.
+ (DECL_NAMESPACE, SET_DECL_NAMESPACE): New macros.
+ (TREE_INDIRECT_USING): New macro.
+ * decl2.c (current_namespace, global_namespace): Declare. The
+ value is a NAMESPACE_DECL now, not a TREE_LIST.
+ (is_namespace_ancestor, namespace_ancestor): New static functions.
+ (add_using_namespace, ambiguous_decl): Likewise.
+ (lookup_using_namespace): New support function for lookup_name.
+ (qualified_lookup_using_namespace): New support function for
+ do_scoped_id and lookup_namespace_name.
+ (get_namespace_id): Mark as obsolete.
+ (current_namespace_id): Likewise.
+ (do_namespace_alias): Implement.
+ (do_using_directive): Implement as call to add_using_namespace.
+ * decl.c (binding_for_name): New function.
+ (push_namespace, pop_namespace): Implement.
+ (push_decl): Don't install a FUNCTION_DECL in the global branch.
+ (lookup_namespace_name): Implement using qualified lookup.
+ (lookup_name_real): For global scoping, lookup in
+ global_namespace. For namespace scoping, lookup in given
+ namespace. For unscoped lookup, iterate over namespace,
+ considering using directives.
+ (init_decl_processing): Initialize global_namespace.
+ (grokvardecl): Build assembler name as static name for globals.
+ (grokdeclarator): Remove old namespace mangling.
+ (xref_tag): When installing a global binding for the
+ tag, make sure we have an identifier.
+ * method.c (build_overload_nested_name): Mangle namespaces.
+ (build_qualified_name): Likewise.
+ (build_decl_overload_real): Likewise.
+ * lex.c (build_lang_decl): Set namespace for new declaration to
+ current_namespace.
+ (do_scoped_id): Find global names in global or current
+ namespace, or using qualified namespace lookup, depending on
+ context.
+ * init.c (build_member_call): When scope is namespace, use
+ build_x_function_call instead.
+ (build_offset_ref): When scope is namespace, collapse processing
+ to lookup_namespace_name instead.
+ * error.c (dump_decl): Support NAMESPACE_DECL.
+ * decl.c (pushdecl): Bind globals to current namespace.
+ (push_overloaded_decl): Likewise.
+ (lookup_tag): Likewise.
+ (lookup_name_current_level): Likewise.
+ (xref_tag): Likewise.
+ (start_function): Likewise.
+ * lex.c (do_identifier): Likewise.
+ (identifier_typedecl_value): Likewise.
+ (real_yylex): Likewise.
+ * method.c (do_inline_function_hair): Likewise.
+ * parse.y (unscoped): Likewise.
+ * pt.c (check_explicit_specialization): Likewise.
+ (lookup_template_class): Likewise.
+ * rtti.c (call_void_fn): Likewise.
+ * sig.c (build_sigtable): Likewise.
+ * ptree.c (lang_print_xnode): New function.
+
+Tue Feb 24 01:40:24 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Don't instantiate if pedantic
+ and the args use template parms.
+
+ * pt.c (push_tinst_level): If the instantiation uses template parms,
+ fail silently.
+ * decl.c (xref_basetypes): Do call complete_type for basetypes
+ that involve template parameters.
+
+Tue Feb 24 00:36:43 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (process_init_constructor): Fix labeled init check.
+
+Mon Feb 23 05:08:55 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c, call.c, decl.c, method.c, cp-tree.h: Remove unused NARGS
+ argument to tsubst and friends.
+
+ * pt.c (tsubst, FUNCTION_DECL): Tidy.
+
+ * typeck.c (build_x_function_call): Handle static member function
+ templates like non-templates. Handle friend templates like normal
+ function templates.
+ * pt.c (tsubst, *_PARM): Don't use orig_level.
+ (get_bindings): Don't call add_to_template_args.
+ (instantiate_template): Likewise.
+ (tsubst, FUNCTION_DECL): Call add_to_template_args as appropriate.
+ * ptree.c (print_lang_type): Print index/level for template parms.
+
+Mon Feb 23 02:52:29 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * Make-lang.in (cc1plus): Note that cc1plus depends on
+ cp/cp-tree.h and cp/cp-tree.def.
+
+ * cp-tree.def (TEMPLATE_CONST_PARM): Remove.
+ (TEMPLATE_PARM_INDEX): New tree code, used to indicate a
+ position in a template parameter list.
+ * cp-tree.h (template_parm_index): New structure, used as the tree
+ structure for a TEMPLATE_PARM_INDEX.
+ (TEMPLATE_PARM_IDX): New macro.
+ (TEMPLATE_PARM_LEVEL): Likewise.
+ (TEMPLATE_PARM_DESCENDANTS): Likewise.
+ (TEMPLATE_PARM_ORIG_LEVEL): Likewise.
+ (TEMPLATE_PARM_DECL): Likewise.
+ (TEMPLATE_TYPE_PARM_INDEX): Likewise.
+ (TEMPLATE_TYPE_ORIG_LEVEL): Likewise.
+ (TEMPLATE_TYPE_DECL): Likewise.
+ (TEMPLATE_CONST_IDX): Remove.
+ (TEMPLATE_CONST_LEVEL): Likewise.
+ (TEMPLATE_CONST_SET_INFO): Likewise.
+ (TEMPLATE_TYPE_SET_INFO): Likewise.
+ (TEMPLATE_TYPE_IDX): Redefine in terms of TEMPLATE_PARM_INDEX
+ node.
+ (TEMPLATE_TYPE_LEVEL): Likewise.
+ * decl.c (decls_match): Call comp_template_parms, rather than
+ expanding it inline.
+ (duplicate_decls): If two template declarations are being merged,
+ then their TEMPLATE_INFOs should be merged as well.
+ (grokfndecl): Save template-id information when declaring a friend
+ with explicit template arguments. Pass arguments to
+ check_explicit_specialization via correct convention; at some
+ point check_explicit_specialization changed, but these call-sites
+ did not.
+ (grokdeclarator): Tidy up slightly.
+ * decl2.c (check_classfn): Tidy up slightly. Don't assume that
+ two template functions with the same DECL_ASSEMBLER_NAME the same,
+ since the names are not yet mangled.
+ * error.c (dump_decl): Use TEMPLATE_PARM_INDEX instead of
+ TEMPLATE_CONST_PARM.
+ (dump_expr): Likewise. Use the TEMPLATE_PARM_DECL to get at the
+ decl for a non-type parameter, rather than printing `<tparm ...>'.
+ * friend.c (is_friend): Handle TEMPLATE_DECL friends.
+ (do_friend): Deal with template friends.
+ * lex.c (do_pending_inlines): Call
+ maybe_begin_member_template_processing, rather than
+ conditionally calling begin_member_template_processing.
+ (process_next_inline): Likewise. Call
+ maybe_end_member_template_processing, rather than
+ conditionally calling end_member_template_processing.
+ (do_pending_defargs): Likewise.
+ (do_identifier): Use TEMPLATE_PARM_INDEX instead of
+ TEMPLATE_CONST_PARM.
+ * method.c (build_mangled_template_parm_index): New function.
+ (build_overload_value): Use it.
+ (build_overload_name): Likewise.
+ * pt.c (finish_member_template_decl): Allow friend declarations.
+ (template_class_depth): New function.
+ (is_member_template): Rename, and modify, to become...
+ (is_member_or_friend_template): New function.
+ (end_member_template_processing): Rename, and modify, to become...
+ (maybe_end_member_template_processing).
+ (build_template_parm_index): New function.
+ (reduce_template_parm_level): New function.
+ (process_template_parm): Modify to use build_template_parm_index.
+ (push_template_decl): Deal with friend templates.
+ (uses_template_parms): Use TEMPLATE_PARM_INDEX instead of
+ TEMPLATE_CONST_PARM.
+ (tsubst_friend_function): New function.
+ (instantiate_class_template): Generate the DECL_FRIENDLIST
+ for a new instantiation by using tsubst_friend_function rather
+ than just tsubst.
+ (tsubst): Don't tsubst into a type which is a TEMPLATE_DECL.
+ Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM, and the
+ appropriate new macros. Use reduce_template_parm_level to
+ generate lower-level template parameters. Handle tsubst'ing into
+ TEMPLATE_DECLS that declare TEMPLATE_TEMPLATE_PARMS. Don't forget
+ to tsubst the DECL_CONTEXT and DECL_CLASS_CONTEXT of newly created
+ templates. Similarly for the template parameters for a new
+ template.
+ (tsubst_copy): Tidy up slightly. Use TEMPLATE_PARM_INDEX instead
+ of TEMPLATE_CONST_PARM. Handle TYPE_DECLs by tsubsting into them.
+ (unify): Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM.
+ (get_bindings): Call add_to_template_args if necessary.
+ (instantiate_decl): Handle instantiations of friend templates.
+ * search.c (lookup_field_1): Don't treat the TYPE_FIELDS of a
+ TEMPLATE_TYPE_PARM as a list of fields; it's not!
+ * spew.c (yylex): Do a little manual constant propagation to
+ clarify the code.
+
+Sun Feb 22 19:53:29 1998 Jeffrey A Law (law@cygnus.com)
+
+ * error.c: Include sys/types.h.
+
+Thu Feb 19 14:49:09 1998 Jeffrey A Law (law@cygnus.com)
+
+ * method.c (build_mangled_name): Start CPP directives in column zero.
+
+Thu Feb 19 10:36:48 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (process_init_constructor): Sorry about non-trivial
+ labeled initializers.
+ * parse.y (initlist): Re-enable labeled initializers.
+
+Thu Feb 19 10:15:55 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * pt.c (coerce_template_parms): Add a new parameter, is_tmpl_parm,
+ all callers changed. Rely on the new parameter instead of arg
+ being a TREE_LIST when determine whether we are working inside
+ template template parameter. Clean up is_type test.
+
+Thu Feb 19 10:04:12 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Preserve TREE_CONSTANT.
+ * typeck2.c (initializer_constant_valid_p): Allow conversions
+ between pointers and references.
+
+1998-02-19 Brendan Kehoe <brendan@cygnus.com>
+
+ * typeck.c (build_unary_op): Only warn about incr/decr a pointer
+ if pedantic || warn_pointer_arith.
+
+Thu Feb 19 09:37:21 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * pt.c (unify): Handle TEMPLATE_DECL.
+
+1998-02-18 Brendan Kehoe <brendan@cygnus.com>
+
+ * cp-tree.h (strip_attrs): Remove decl.
+
+1998-02-18 Doug Evans <devans@cygnus.com>
+
+ * decl.c (duplicate_decls): Call merge_machine_decl_attributes.
+ Update olddecl's attributes too.
+ (strip_attrs): Remove function.
+ * typeck.c (common_type): Call merge_machine_type_attributes.
+
+Tue Feb 17 14:07:52 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * parse.y (initdcl0_innards): New grammar symbol.
+ (nomods_initdecls, nomods_initdcl0): Change type from itype to
+ none, since the resulting value is never used.
+ (parse_decl): New function.
+ (datadef): Remove redundant actions.
+ (initdcl0, notype_initdcl0, nomods_initdcl0): Use initdcl0_innards.
+ * parse.c: Regenerated.
+
+Tue Feb 17 11:54:16 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (simple_stmt): Use getdecls() to check for decl.
+
+Sat Feb 14 11:50:51 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Make-lang.in (DEMANGLER_INSTALL_NAME, DEMANGLER_CROSS_NAME): New
+ macros.
+ (c++.install-common): Install c++filt properly as native or as cross
+ variant.
+ (c++.uninstall): Add c++filt.
+
+Fri Feb 13 14:55:37 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (standard_conversion): Fix multi-level ptr conversions.
+
+Fri Feb 13 14:06:22 1998 Mike Stump <mrs@wrs.com>
+
+ * init.c (build_new): Propagate error_mark_node up.
+
+Fri Feb 13 13:24:32 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (simple_stmt): If the condition isn't a declaration,
+ start the controlled block after the test.
+
+Fri Feb 13 02:26:10 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * call.c (build_over_call): Convert builtin abs, labs and fabs to
+ tree-codes.
+ * decl.c (init_decl_processing): Re-enable abs, labs and fabs as
+ builtins.
+
+Fri Feb 13 01:36:42 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (standard_conversion): A BASE_CONV replaces an RVALUE_CONV.
+
+Fri Feb 13 00:21:59 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h: Add access_protected_virtual_node.
+ * class.c (init_class_processing): Initialize it.
+ * decl.c (xref_basetypes): Use it.
+ * parse.y (base_class_access_list): Likewise.
+
+ * Make-lang.in (DEMANGLER_PROG): Add $(exeext).
+ (c++.install-common): Install c++filt.
+
+Thu Feb 12 12:46:51 1998 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * decl.c (shadow_tag): Give error for typedef-ing built-in types.
+
+Wed Feb 11 23:28:05 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * call.c (reference_binding): Use comptypes when comparing
+ TYPE_MAIN_VARIANTS to handle non-canonical array/index types.
+
+Wed Feb 11 16:42:04 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * tree.c (is_overloaded_fn): Use really_overloaded_fn.
+ (really_overloaded_fn): Move check here from is_overloaded_fn.
+ (get_first_fn): Use really_overloaded_fn and is_overloaded_fn.
+
+Wed Feb 11 15:54:18 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * typeck.c (build_ptrmemfunc): Type-check pointer-to-member
+ conversions.
+
+Mon Feb 9 22:23:31 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * cp-tree.h (push_template_decl): Return the decl passed in, or an
+ equivalent duplicate.
+ * decl.c (pushtag): Use the return value from push_template_decl.
+ (duplicate_decls): When duplicating a template declaration, merge
+ the DECL_TEMPLATE_RESULTs as well.
+ (make_implicit_typename): Don't try to dive into typename types to
+ find a context for making a new implicit typename.
+ (start_decl): Use the return value from push_template_decl.
+ (grokdeclarator): Complain about declarations list `const operator
+ int'. Since we don't correctly handle in-class initializations of
+ non-static data members, complain about this (now illegal)
+ practice. Issue an error for initializations of non-const statics
+ since that is illegal as well, and since we don't handle that case
+ correctly either.
+ (start_function): Use the return value from push_template_decl.
+ (start_method): Likewise.
+ * decl2.c (grokfield): Likewise. Since the change to
+ grokdeclarator ensures that all initialized fields are in fact
+ static, remove a redundant test for TREE_PUBLIC.
+ * parse.y (initlist): Disable labeled initializers since they do
+ not work as per the documentation, and since they do not use the
+ same syntax as the C front end.
+ * pt.c (push_template_decl): Return the decl passed in, or an
+ equivalent duplicate.
+ (lookup_template_class): When searching in a nested context,
+ use the right arguments.
+ (uses_template_parms): Handle the DECL_INITIAL for a CONST_DECL.
+ * typeck.c (build_component_ref): Assign the correct type to the
+ result of build_vfn_ref.
+
+Tue Feb 10 23:56:46 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (convert_nontype_argument): Fix typo.
+ (check_explicit_specialization): Allow old-style specialization
+ of class template members.
+
+Tue Feb 10 20:36:52 1998 Jason Merrill <jason@yorick.cygnus.com>
+ Manfred Hollstein <manfred@s-direktnet.de>
+
+ * decl.c (grokdeclarator): Use DECL_USE_TEMPLATE instead
+ when deciding to override DECL_ASSEMBLER_NAME.
+
+Tue Feb 10 15:30:55 1998 Andrew MacLeod <amacleod@torpedo.to.cygnus.com>
+
+ * decl2.c (lang_f_options): Add -fsquangle to option processing list.
+ * cp-tree.h (flag_do_squangling): Add declaration.
+ * lang-options.h: Add -fsquangle and -fno-squangle.
+ * method.c: Add macros and static variables for squangling.
+ (build_overload_name): Rename to build_mangled_name, add logic for B
+ compression, and split into process_modifiers and
+ process_overload_item.
+ (process_modifiers): New function, to handle constant, reference,
+ and pointer types.
+ (process_overload_item): New function, handles issue of type codes.
+ (build_overload_name): New function, start squangling and call
+ build_mangled_name.
+ (ALLOCATE_TYPEVEC, DEALLOCATE_TYPEVEC): Remove macro and expand inline.
+ (start_squangling): New function to initialize squangling structs.
+ (end_squangling): New function to destroy squangling structs.
+ (nrepeats): Rename variable to Nrepeats.
+ (issue_nrepeats): New function for issuing 'n' type repeats.
+ (check_ktype): New function to check for type K name compression.
+ (build_overload_nested_name): Add a check for K name compression.
+ (build_qualified_name): Add a check for K name compression and don't
+ use DECL_ASSEMBLER_NAME when squangling is on.
+ (check_btype): New function, checks for B type compression.
+ (build_static_name, build_decl_overload_real): Initiate squangling.
+ (build_typename_overload, build_overload_with_type): Initiate
+ squangling
+
+Sun Feb 8 23:47:38 1998 scott snyder <sss@d0linux01.fnal.gov>
+
+ * method.c (make_thunk): Avoid name buffer overflow.
+
+Sat Feb 7 16:48:54 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_decl): Call cp_finish_decl for vars even if we
+ don't define them yet.
+
+ * parse.y (nomods_initdcl0): Add constructor_declarator case.
+
+Fri Feb 6 21:32:25 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * config-lang.in (diff_excludes): Use basename only.
+
+Thu Feb 5 19:10:40 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo2.cc: Add tinfo for signed char.
+
+Thu Feb 5 14:38:23 1998 Mike Stump <mrs@wrs.com>
+
+ * search.c (compute_access): Handle protected constructors in derived
+ classes as accessible.
+
+Wed Feb 4 01:26:49 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * expr.c (cplus_expand_expr, PCC_STATIC_STRUCT_RETURN code):
+ Call convert_from_reference sooner.
+
+Tue Feb 3 23:50:52 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * cvt.c (ocp_convert): Obtain the constant values from constant
+ decls even if the destination type is the same as the type of the
+ decl.
+
+ * decl2.c (finish_file): Make sure that static inlines with
+ definitions are not marked DECL_EXTERNAL before returning.
+
+Tue Feb 3 22:43:42 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c: Lose arg_looking_for_template.
+ (lookup_name_real): Likewise.
+ * parse.y: Lose processing_template_arg, template_arg1.
+ (primary): Likewise.
+ * spew.c (yylex): Set lastiddecl for PTYPENAMEs, too.
+
+Tue Feb 3 22:04:01 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * error.c (dump_decl): Fix type of default arguments for template
+ template parameters and nontype template parameters.
+ * parse.y (template_parm): Handle invalid default template
+ template arguments here.
+
+ * parse.y (template_parm): Use template_arg instead of PTYPENAME
+ for default template template argument.
+ * pt.c (coerce_template_parms): Merge default template argument
+ codes. Can treat RECORD_TYPE as template name if it is implicitly
+ created. Fix argument index in error message.
+ * typeck.c (comptypes): Merge template argument comparison codes in
+ TEMPLATE_TEMPLATE_PARM and RECORD_TYPE.
+
+Tue Jan 6 01:42:44 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * lex.c (file_name_nondirectory): Also check for '/'.
+
+Mon Feb 2 11:24:22 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * parse.y (primary): Deal with statement-expressions in
+ templates.
+ * pt.c (tsubst_copy): Handle BIND_EXPR.
+ * tree.c (mapcar): Likewise.
+
+ * call.c (add_template_candidate_real): Pass extra parameter to
+ fn_type_unification.
+ * cp-tree.h (fn_type_unification): Add parameter.
+ * pt.c (fn_type_unification): Add additional parameter to deal with
+ static member functions.
+ (get_bindings): Deal with static member functions.
+
+ * cp-tree.h (DECL_NONSTATIC_MEMBER_FUNCTION_P): New macro.
+ (revert_static_member_fn): Declare.
+ * decl.c (revert_static_member_fn): Remove declaration. Change
+ linkage from internal to external.
+ (cp_finish_decl): Deal with virtual functions in classes local to
+ template functions.
+ * decl2.c (finish_file): Don't forget to emit increment/decrement
+ expressions in initializers for file-scope variables.
+ * parse.y (typename_sub2): If the typename doesn't names a
+ template, rather than a type, issue an error message.
+ * pt.c (check_explicit_specialization): Handle specializations of
+ static member functions.
+ (coerce_template_parms): Handle offset references to lists of
+ member functions.
+ * search.c (note_debug_info_needed): Don't crash when handed a
+ type which is being defined.
+ * typeck.c (complete_type): Don't crash when handed NULL_TREE;
+ that can happen with some illegal code.
+
+Mon Feb 2 00:57:38 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (user_harshness): Initialize `code' to 0.
+ (build_method_call): Initialize `candidates', `cp' and `len' to 0.
+ (null_ptr_cst_p): Add parentheses around && within ||.
+ (standard_conversion): Likewise.
+ (z_candidate): Likewise.
+ (build_user_type_conversion_1): Initialize `args' to NULL_TREE.
+ (build_object_call): Likewise for `mem_args'.
+ (build_new_op): Likewise for `mem_arglist'. Add `return' from
+ default case in enumeration switch.
+
+ * class.c (build_vtable_entry): Add explicit braces to avoid
+ ambiguous `else'.
+ (build_class_init_list): Likewise.
+ (finish_struct_1): Initialize `width' to 0.
+ (instantiate_type): Initialize `name' to NULL_TREE. Add
+ explicit braces to avoid ambiguous `else'.
+
+ * cvt.c (convert_to_aggr): Add explicit braces to avoid ambiguous
+ `else'.
+
+ * decl.c (grok_reference_init): Eliminate unused parameter, all
+ callers changed.
+ (record_builtin_type): Initialize `tdecl' to NULL_TREE.
+ (init_decl_processing): Initialize `vb_off_identifier' to NULL_TREE.
+ (cp_finish_decl): Initialize `ttype' to NULL_TREE.
+ (grokdeclarator): Add parentheses around && within ||. Add
+ explicit braces to avoid ambiguous `else'.
+ (grokparms): Initialize `type' to NULL_TREE.
+ (xref_tag): Remove unused label `just_return'.
+ (finish_enum): Initialize `minnode' and `maxnode' to NULL_TREE.
+ (finish_function): Initialize `cond' and `thenclause' to NULL_TREE.
+ (hack_incomplete_structures): Add parentheses around assignment
+ used as truth value.
+
+ * decl2.c (coerce_delete_type): Hide definition of `e3'.
+
+ * error.c: Include <stdlib.h>.
+ (dump_expr): Change the type of `i' to size_t. Remove unused
+ label `error'.
+
+ * except.c (init_exception_processing): Remove unused variable `d'.
+ (expand_throw): Likewise for `label'.
+
+ * friend.c (add_friends): Add explicit braces to avoid ambiguous
+ `else'.
+
+ * init.c (sort_member_init): Initialize `last_field' to NULL_TREE.
+ (sort_base_init): Likewise for `binfo'.
+ (expand_member_init): Likewise for `rval'.
+ (build_member_call): Add parentheses around assignment used as
+ truth value.
+ (build_offset_ref): Add explicit braces to avoid ambiguous `else'.
+ (build_new): Initialize `nelts' to NULL_TREE. Initialize
+ `old_immediate_size_expand' to 0.
+ (build_new_1): Initialize `nelts' and `alloc_node' to NULL_TREE.
+ (build_vec_delete_1): Remove unused variable `block'.
+ (expand_vec_init): Initialize `itype' to NULL_TREE.
+
+ * lex.c: Include <strings.h> if we don't have <string.h>. Protect
+ declaration of `index' and `rindex' with autoconf macros.
+ (reinit_parse_for_expr): Remove unused variables
+ `look_for_semicolon' and `look_for_lbrac'.
+ (cons_up_default_function): Initialize `args' to NULL_TREE.
+ (readescape): Initialize `firstdig' to 0.
+ (real_yylex): Add parentheses around assignment used as truth value.
+
+ * method.c: Include <strings.h> if we don't have <string.h>.
+ Protect declaration of `index' with autoconf macro.
+
+ * parse.y (primary): Add explicit braces to avoid ambiguous `else'.
+ Initialize `type' to NULL_TREE.
+ (structsp): Remove unused variable `id'.
+
+ * pt.c (coerce_template_parms): Add explicit braces to avoid
+ ambiguous `else'.
+ (lookup_template_class): Initialize `template' to NULL_TREE.
+ (instantiate_class_template): Remove unused variable `name' and `e'.
+ (tsubst): Likewise for `i'. Initialize `last' to NULL_TREE.
+ (do_poplevel): Initialize `saved_warn_unused' to 0.
+ (type_unification): Remove unused varable `parm'.
+ (unify): Likewise for `j'.
+
+ * repo.c (init_repo): Add parentheses around assignment used as
+ truth value.
+ (finish_repo): Remove unused varable `p'.
+
+ * search.c (get_binfo): Initialize `type' to NULL_TREE.
+ (get_base_distance): Likewise.
+ (lookup_field): Initialize `rval_binfo_h', `type', `basetype_path'
+ and `new_v' to NULL_TREE.
+ (lookup_fnfields): Likewise for `rval_binfo_h'.
+ (breadth_first_search): Add parentheses around assignment used as
+ truth value.
+ (get_template_base): Initialize `type' to NULL_TREE.
+
+ * sig.c (append_signature_fields): Initialize `last_mfptr' to
+ NULL_TREE.
+ (build_signature_table_constructor): Likewise for
+ `last_rhs_field', `pfn' and `vt_off'.
+ (build_sigtable): Likewise for `init'.
+
+ * tree.c (break_out_calls): Initialize `t2' to NULL_TREE.
+ (propagate_binfo_offsets): Likewise for `delta'.
+ (hash_tree_cons): Initialize hashcode to 0.
+ (can_free): Likewise for `size'.
+ (cp_tree_equal): Add explicit braces to avoid ambiguous `else'.
+
+ * typeck.c (convert_sequence): Hide prototype.
+ (common_type): Add explicit braces to avoid ambiguous `else'.
+ (comp_target_types): Likewise.
+ (build_x_function_call): Initialize `ctypeptr' to NULL_TREE.
+ (build_function_call_real): Add explicit braces to avoid ambiguous
+ `else'.
+ (convert_arguments): Initialize `called_thing' to 0.
+ (convert_for_initialization): Initialize `savew' and `savee' to 0.
+
+ * typeck2.c (incomplete_type_error): Initialize `errmsg' to 0.
+ (digest_init): Initialize `old_tail_contents' to NULL_TREE.
+ (build_x_arrow): Likewise for `last_rval'.
+
+ * xref.c (GNU_xref_decl): Initialize `cls' to 0.
+
+Sun Feb 1 12:45:34 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * decl.c (init_decl_processing): Use set_sizetype.
+ * decl2.c (sizetype): Don't declare.
+ * typeck.c (c_sizeof): Convert result of *_DIV_EXPR to sizetype.
+ (c_sizeof_nowarn, build_binary_op_nodefault): Likewise.
+ (build_component_addr, unary_complex_lvalue): Likewise.
+ * rtti.c (expand_class_desc): Likewise.
+ * class.c (get_vfield_offset): Likewise.
+
+Thu Jan 29 10:39:30 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (convert_nontype_argument): Move check for is_overloaded_fn
+ early to avoid bogus error. Handle overloaded function
+ names provided as template arguments correctly.
+ (coerce_template_parms): Don't mishandle overloaded functions when
+ dealing with template template parameters.
+ (lookup_template_class): Issue an error message, rather than
+ crashing, when the TYPE_DECL provided is not a template type.
+
+Wed Jan 28 23:14:44 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (instantiate_type): Don't just return a known type if
+ it's wrong.
+
+Wed Jan 28 11:04:07 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * class.c (instantiate_type): Remove handling of FUNCTION_DECL
+ since that code could never be reached.
+
+ * error.c (dump_decl): Avoid aborting in the midst of printing an
+ error message about an illegal template declaration.
+
+ * parse.y (structsp): Print an error message, rather than crashing,
+ when a class-head does not name a class.
+
+ * pt.c (convert_nontype_argument): Allow REAL_TYPE and COMPLEX_TYPE
+ template arguments as a g++ extension.
+
+ * cp-tree.def (ALIGNOF_EXPR): New tree code.
+ * decl2.c (grok_alignof): If processing_template_decl, just store
+ the expression.
+ * typeck.c (c_alignof): Likewise.
+ * decl2.c (build_expr_from_tree): Handle ALIGNOF_EXPR.
+ * error.c (dump_expr): Likewise.
+ * pt.c (tsubst_copy): Likewise.
+ * tree.c (cp_tree_equal): Likewise.
+ * pt.c (uses_template_parms): Correctly determine whether or not a
+ SIZEOF_EXPR/ALIGNOF_EXPR uses template parameters so that constant
+ folding can be done.
+
+ * cp-tree.h (grok_enum_decls): Remove type parameter.
+ * decl.c (grok_enum_decls): Likewise.
+ * decl2.c (grok_x_components): Call grok_enum_decls
+ unconditionally, since it will do nothing if there is no
+ current_local_enum. Use the new calling sequence.
+ * pt.c (tsubst_enum): Use the new calling sequence for
+ grok_enum_decls.
+
+ * decl.c (start_function): Make member functions of local classes
+ in extern inline functions have comdat linkage here...
+ (grokdeclarator): Rather than here.
+
+Wed Jan 28 10:55:47 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (convert_nontype_argument): Use decl_constant_value.
+
+Tue Jan 27 16:42:21 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * call.c (add_template_candidate_real): New function.
+ (add_template_candidate): Use it.
+ (add_template_conv_candidate): Likewise.
+ (joust): Pass extra argument to more_specialized.
+ * class.c (instantiate_type): Handle a single FUNCTION_DECL.
+ (is_local_class): Remove.
+ (finish_struct): Check TI_PENDING_SPECIALIZATION_FLAG.
+ * cp-tree.h (is_local_class): Remove.
+ (perform_array_to_pointer_conversion): Likewise.
+ (finish_member_template_decl): Add.
+ (check_explicit_specialization): Return a tree, not an int.
+ (more_specialized): Take additional argument.
+ (get_bindings): Likewise.
+ (TI_PENDING_SPECIALIZATION_FLAG): New macro.
+ * cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes.
+ (perform_array_to_pointer_conversion): Remove.
+ * decl.c (saved_scope): Add processing_specialization,
+ processing_explicit_instantiation fields.
+ (maybe_push_to_top_level): Save them.
+ (pop_from_top_level): Restore them.
+ (grokfndecl): Use new return value from
+ check_explicit_specialization.
+ (start_decl): Don't check flag_guiding_decls before pushing
+ decls.
+ (cp_finish_decl): Remove previous (bogus) change.
+ (grok_declarator): Use decl_function_context rather than
+ is_local_class.
+ * decl2.c (finish_file): Pass extra argument to get_bindings.
+ (build_expr_from_tree): Let build_x_component_ref check
+ validity of arguments rather than doing it here.
+ * lex.c (cons_up_default_function): Remove code fooling with
+ processing_specialization, processing_explicit_instantiation
+ flags, as that is now done in {maybe_push_top,pop_from}_top_level.
+ * method.c (build_overload_identifier): Mangle local classes in
+ template functions correctly.
+ * parse.y (finish_member_template_decl): Move to pt.c.
+ * pt.c (finish_member_template_decl): Moved here from parse.y.
+ (print_candidates): New function.
+ (determine_specialization): Change interface. Properly look for
+ most specialized versions of template candidates.
+ (check_explicit_specialization): Fully process explicit
+ instantiations.
+ (push_template_decl): Avoid looking at CLASSTYPE fields in
+ FUNCTION_DECLS.
+ (determine_overloaded_function): Remove.
+ (convert_nontype_argument): Change name from
+ convert_nontype_parameter. Use determine_overloaded_function
+ instead of instantiate_type.
+ (mangle_class_name_for_template): Handle type contexts as well as
+ function contexts.
+ (classtype_mangled_name): Likewise.
+ (lookup_template_class): Likewise.
+ (tsubst): Likewise.
+ (more_specialized): Take explicit template arguments as a
+ parameter.
+ (most_specialized): Likewise.
+ (get_bindings): Likewise. Check that return types match before
+ proclaiming a function a match.
+ (do_decl_instantiation): Remove code searching for function to
+ instantiate; that is now done in check_explicit_specialization.
+ (add_maybe_template): Pass extra argument to get_bindings.
+ * tree.c (really_overloaded_fn): Use is_overloaded_fn to simplify
+ implementation.
+ * typeck.c (build_component_ref): Check for invalid arguments.
+
+Tue Jan 27 01:44:02 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * expr.c (cplus_expand_expr, AGGR_INIT_EXPR): Don't check that
+ return_target and call_target are equivalent.
+
+ * pt.c (type_unification_real): Just accept function parms that
+ don't use any template parms.
+
+Sun Jan 25 03:30:00 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (cp_finish_decl): When bailing on a comdat variable, also
+ unset DECL_NOT_REALLY_EXTERN.
+
+ * parse.y (typename_sub*): Fix std::.
+
+Sat Jan 24 12:13:54 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * error.c (dump_decl): Fix type default template args.
+ (dump_type): Hand TEMPLATE_DECL off to dump_decl.
+
+Fri Jan 23 18:34:37 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * lex.c (DIR_SEPARATOR): Define to be '/' if not already defined.
+ (file_name_nondirectory): Use.
+
+Wed Jan 21 10:29:57 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * pt.c (coerce_template_parms): Don't access elements of ARGLIST
+ that are not really present. Substitute default arguments in
+ template template arguments. Correctly convert TEMPLATE_DECL to
+ TEMPLATE_TEMPLATE_PARM.
+ (comp_template_args): TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM
+ are no longer treated specially here.
+ * parse.y (template_template_parm): Fix copy error.
+ * decl.c (grokdeclarator): Warn about missing `typename' for nested
+ type created from template template parameters.
+ * parse.y (bad_parm): Likewise
+
+ * class.c (finish_struct): Handle TEMPLATE_TEMPLATE_PARM.
+ (push_nested_class): Likewise.
+ * cp-tree.def (TEMPLATE_TEMPLATE_PARM): New tree code.
+ * cp-tree.h (DECL_TEMPLATE_TEMPLATE_PARM_P): New macro.
+ (copy_template_template_parm): Declare.
+ * decl.c (arg_looking_for_template): New variable.
+ (lookup_name_real): Handle TEMPLATE_TEMPLATE_PARM.
+ Try to return TEMPLATE_DECL or TEMPLATE_TEMPLATE_PARM
+ node if arg_looking_for_template is nonzero.
+ (pushdecl): Handle TEMPLATE_TEMPLATE_PARM.
+ (grok_op_properties, xref_tag, xref_basetypes): Likewise.
+ (grokdeclarator): Handle TEMPLATE_DECL.
+ * decl2.c (constructor_name_full): Handle TEMPLATE_TEMPLATE_PARM.
+ * error.c (dump_type): Add TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM.
+ (dump_type_prefix, dump_type_suffix): Handle TEMPLATE_TEMPLATE_PARM.
+ (dump_decl): Handle unnamed template type parameters.
+ Handle template template parameters.
+ (dump_function_name): Handle template template parameters.
+ * init.c (is_aggr_typedef, is_aggr_type, get_aggr_from_typedef):
+ Handle TEMPLATE_TEMPLATE_PARM.
+ * method.c (build_template_template_parm_names): New function.
+ (build_template_parm_names): Handle TEMPLATE_DECL.
+ (build_overload_nested_name, build_overload_name):
+ Handle TEMPLATE_TEMPLATE_PARM.
+ * parse.y (maybe_identifier): New nonterminal.
+ (template_type_parm): Use it.
+ (template_template_parm, template_arg1): New nonterminal.
+ (template_parm): Add template_template_parm rules.
+ (template_arg): Set processing_template_arg.
+ (template_arg1): Rules moved from template_arg.
+ (primary, nonnested_type): Set arg_looking_for_template if we are
+ processing template arguments.
+ * pt.c (begin_member_template_processing): Handle TEMPLATE_DECL.
+ (process_template_parm): Handle template template parameters.
+ (coerce_template_parms, comp_template_args): Likewise.
+ (mangle_class_name_for_template, lookup_template_class): Likewise.
+ (uses_template_parms): Handle TEMPLATE_DECL and
+ TEMPLATE_TEMPLATE_PARM.
+ (current_template_args): Handle TEMPLATE_DECL.
+ (tsubst, tsubst_copy, unify): Handle TEMPLATE_TEMPLATE_PARM.
+ * search.c (dfs_walk, dfs_record_inheritance):
+ Handle TEMPLATE_TEMPLATE_PARM.
+ * tree.c (copy_template_template_parm): New function.
+ (mapcar): Handle TEMPLATE_TEMPLATE_PARM.
+ * typeck.c (comptypes): Handle TEMPLATE_TEMPLATE_PARM.
+
+Mon Jan 19 22:40:03 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * decl.c (start_decl): Don't allow duplicate definitions of static
+ data members.
+
+ * call.c (build_user_type_conversion_1): Handle user-defined
+ template conversion operators correctly.
+
+ * decl2.c (build_expr_from_tree): Issue an error message if the
+ object in a COMPONENT_REF is a TEMPLATE_DECL.
+
+ * typeck.c (incomplete_type_error): Handle TEMPLATE_TYPE_PARMs.
+
+ * class.c (is_local_class): New function.
+ * cp-tree.h (is_local_class): Declare it.
+ (last_tree): Likewise.
+ (begin_tree): Likewise.
+ (end_tree): Likewise.
+ (lookup_template_class): Change prototype.
+ * decl.c (cp_finish_decl): Check for NULL where necessary.
+ Consider FUNCTION_DECLS to declare objects with top-level binding,
+ when calling make_decl_rtl.
+ (grokdeclarator): Give members of local classes internal linkage.
+ (start_function): Remove declaration of last_tree.
+ (finish_function): Set flag_keep_inline_functions around call to
+ rest_of_compilation if we are processing a member function in a
+ local class.
+ (start_method): Call push_template_decl for member functions of
+ local classes in template functions.
+ * decl2.c (import_export_decl): Don't give external linkage to
+ instantiations of templates with internal linkage.
+ * parse.y (last_tree): Remove declaration.
+ (template_type): Pass extra parameter to lookup_template_class.
+ (self_template_type): Likewise.
+ (structsp): Move call to reset_specialization into left_curly.
+ (left_curly): Call reset_specialization, and begin_tree.
+ * pt.c (saved_trees): New variable.
+ (mangle_class_name_for_template): Change prototype. Use
+ additional function context to name local classes in templates
+ correctly.
+ (classtype_mangled_name): Pass the context.
+ (push_template_decl): Handle local classes and templates, and
+ member functions for such classes.
+ (convert_nontype_parameter): Fix handling of pointer-to-member
+ constants.
+ (lookup_template_class): Handle local classes in templates.
+ (tsubst): Likewise. Don't assume that template instantiations
+ have external linkage; pay attention to the template declaration.
+ (mark_decl_instantiated): Likewise.
+ (begin_tree): New function.
+ (end_tree): Likewise.
+
+ * decl.c (xref_basetypes): Don't call complete_type for basetypes
+ that involve template parameters; that can lead to infinite
+ recursion unnecessarily.
+
+ * pt.c (register_specialization): Do not register specializations
+ that aren't ready to be registered yet.
+ (check_explicit_specialization): Handle explicit specialization of
+ constructors and destructors.
+ (build_template_decl): New function.
+ (push_template_delc): Handle out-of-class specializations of
+ member templates.
+
+ * pt.c (check_explicit_specialization): Set up the template
+ information before registering the specialization.
+ (coerce_template_parms): Fix thinko.
+ (tsubst): Handle specializations of member templates correctly.
+
+ * class.c (finish_struct_methods): Remove calls to
+ check_explicit_specialization from here.
+ (finish_struct): And insert them here.
+ * cp-tree.h (perform_qualification_conversions): New function.
+ (perform_array_to_pointer_conversion): Likewise.
+ (begin_explicit_instantiation): Likewise.
+ (end_explicit_instantiation): Likewise.
+ (determine_specialization): Renamed from
+ determine_explicit_specialization.
+ (comp_template_parms): New function.
+ (processing_explicit_instantiation): New variable.
+ * cvt.c (perform_qualification_conversions): New function.
+ (perform_array_to_pointer_conversion): Likewise.
+ * decl.c (duplicate_decls): Don't consider template functions
+ alike unless they have the same parameters. Refine handling of
+ instantiation/specialization mismatches.
+ (start_decl): Don't call pushdecl for template specializations,
+ since they don't affect overloading.
+ (start_function): Likewise.
+ (grokfndecl): Call check_explicit_specialization a little later.
+ Don't call duplicate_decls for memberm template specializations.
+ (grokdeclarator): Don't update template_count for classes that are
+ themselves specializations. Remove use of `2' as parameter to
+ grokfndecl since that value isn't used.
+ * lex.c (cons_up_default_function): Save and restore
+ processing_explicit_instantiation around calls to grokfield.
+ * parse.y (finish_member_template_decl): New function.
+ (component_decl_1): Use it.
+ (fn.def2): Likewise.
+ (template_arg_list_opt): New nonterminal.
+ (template_type): Use it.
+ (self_template_type): Likewise.
+ (template_id): Likewise.
+ (object_template_id): Likewise.
+ (notype_template_declarator): Likwise.
+ (begin_explicit_instantiation): Likewise.
+ (end_explicit_instantiation): Likewise.
+ (explicit_instantiation): Use them.
+ * pt.c (coerce_template_parms): Add parameters.
+ (processing_explicit_instantiation): New variable.
+ (convert_nontype_parameter): New function.
+ (determine_overloaded_function): Likewise.
+ (begin_explicit_instantiation): Likewise.
+ (end_explicit_instantiation): Likewise.
+ (retrieve_specialization): Likewise.
+ (register_specialization): Likewise.
+ (processing_explicit_specialization): Removed.
+ (determine_specialization): Handle specializations of member
+ functions of template class instantiations.
+ (check_explicit_specialization): Refine to conform to standard.
+ (comp_template_parms): New function.
+ (coerce_template_parms): Call convert_nontype_parameter.
+ (tsubst): Refine handling of member templates. Use
+ register_specialization.
+ (instantiate_template): Use retrieve_specialization.
+ (do_decl_instantiation): Likewise.
+ (instantiate_decl): Likewise.
+ (type_unification): Improve handling of explicit template
+ arguments.
+ * tree.c (mapcar): Return error_mark_node, rather than aborting,
+ on VAR_DECLS, FUNCTION_DECLS, and CONST_DECLS.
+ * typeck.c (build_unary_op): Call determine_specialization, rather
+ than determine_explicit_specialization.
+
+Mon Jan 19 13:18:51 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (build_up_reference): A TARGET_EXPR has side effects.
+
+Fri Jan 16 11:40:50 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * error.c (dump_decl): For enum tags, output the tag, not its value.
+
+1998-01-13 Brendan Kehoe <brendan@cygnus.com>
+
+ * decl.c (init_decl_processing): Only call init_rtti_processing
+ FLAG_RTTI is set.
+
+Mon Jan 12 01:35:18 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_new_1): Split out from build_new.
+ (build_new): Just return a NEW_EXPR.
+ * expr.c (cplus_expand_expr): Handle NEW_EXPR.
+
+ * decl2.c (get_temp_regvar): Tweak.
+
+ * cp-tree.h (TREE_CALLS_NEW): Comment out.
+ * class.c (resolves_to_fixed_type_p): Remove use.
+ * method.c (build_opfncall): Likewise.
+ * call.c (build_new_op): Likewise.
+
+Wed Jan 7 23:47:13 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * exception.cc (__eh_alloc, __eh_free): New fns.
+ (__cp_push_exception, __cp_pop_exception): Use them.
+ (__uncatch_exception): Call terminate here if no exception.
+ * except.c (build_terminate_handler): New fn.
+ (expand_start_catch_block): Use it.
+ (expand_exception_blocks): Likewise.
+ (alloc_eh_object): New fn.
+ (expand_throw): Use it. Protect exception init with terminate.
+ * typeck.c (build_modify_expr): Remove code that ignores trivial
+ methods.
+
+
+
+Copyright (C) 1998 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-1999 b/gcc-4.9/gcc/cp/ChangeLog-1999
new file mode 100644
index 000000000..b321e9897
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-1999
@@ -0,0 +1,6794 @@
+1999-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (VF_NORMAL_VALUE): Remove.
+ * class.c (struct base_info): Remove vfield, vfields, and rtti.
+ (set_primary_base): New function, split out from ...
+ (finish_base_struct): ... here. Rename to ...
+ (determine_primary_base): ... this. Simplify.
+ (create_vtable_ptr): Tweak accordingly.
+ (finish_struct_1): Simplify.
+
+ * cp-tree.h (CLASSTYPE_VBASECLASSES): Update documentation.
+ (CLASSTYPE_N_BASECLASSES): Likewise.
+ (BINFO_FOR_VBASE): New macro.
+ (get_vbase_types): Change prototype.
+ * class.c (build_vbase_path): Use BINFO_FOR_VBASE.
+ (prepare_fresh_vtable): Likewise.
+ (finish_vtbls): Likewise.
+ (get_class_offset_1): Likewise.
+ (modify_all_indirect_vtables): Likewise.
+ (build_vbase_pointer_fields): Likewise.
+ * decl.c (xref_basetypes): Don't set CLASSTYPE_VBASECLASSES here.
+ * init.c (sort_base_init): Use BINFO_FOR_VBASE.
+ (expand_member_init): Likewise.
+ * search.c (get_base_distance): Likewise.
+ (lookup_field_queue_p): Likewise.
+ (virtual_context): Likewise.
+ (get_vbase_types): Don't return a value. Set
+ CLASSTYPE_VBASECLASSES here.
+ * typeck.c (get_delta_difference): Use BINFO_FOR_VBASE.
+
+1999-12-30 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (fixup_inline_methods): Clear CLASSTYPE_INLINE_FRIENDS.
+
+1999-12-29 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (create_vtable_ptr): Put the vtable at the beginning of
+ the class, not the end, in the new ABI.
+ * tree.c (propagate_binfo_offsets): Do the right thing for the new
+ ABI.
+
+1999-12-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_type): Add nearly_empty_p. Adjust dummy.
+ (CLASSTYPE_NEARLY_EMPTY_P): New macro.
+ * class.c (check_bases): Update CLASSTYPE_NEARLY_EMPTY_P.
+ (check_field_decls): Likewise.
+ (check_bases_and_members): Likewise.
+
+1999-12-28 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (do_inline_function_hair): Remove.
+ * class.c (layout_class_type): New function, split out from
+ finish_struct_1.
+ (fixup_pending_inline): Likewise.
+ (fixup_inline_methods): New function.
+ * method.c (fixup_pending_inline): Remove.
+ (do_inline_function_hair): Likewise.
+
+ * decl.c (BOOL_TYPE_SIZE): Bools always have size `1' under the
+ new ABI.
+
+ * cp-tree.h (lang_type): Replace abstract_virtuals with pure_virtuals.
+ (CLASSTYPE_ABSTRACT_VIRTUALS): Rename to ...
+ (CLASSTYPE_PURE_VIRTUALS): ... this.
+ (lang_decl_flags): Replace abstract_virtual with pure_virtual.
+ (DECL_ABSTRACT_VIRTUAL_P): Rename to ...
+ (DECL_PURE_VIRTUAL_P): ... this.
+ (get_abstract_virtuals): Rename to ...
+ (get_pure_virtuals): ... this.
+ * call.c (build_new_method_call): Replace DECL_PURE_VIRTUAL_P with
+ DECL_ABSTRACT_VIRTUAL_P. Replace CLASSTYPE_ABSTRACT_VIRTUALS with
+ CLASSTYPE_PURE_VIRTUALS.
+ * class.c (build_vtable_entry): Likewise.
+ (finish_struct_bits): Likewise. Call get_pure_virtuals, not
+ get_abstract_virtuals.
+ (build_vtbl_initializer): Likewise.
+ (override_one_vtable): Likewise.
+ (check_methods): Likewise.
+ * decl.c (duplicate_decls): Likewise.
+ (redeclaration_error_message): Likewise.
+ (lang_mark_tree): Likewise.
+ * decl2.c (grok_function_init): Likewise.
+ (import_export_vtable): Likewise.
+ (import_expor_class): Likewise.
+ * typeck2.c (abstract_virtuals_error): Likewise.
+ * xref.c (GNU_xref_member): Likewise.
+ * search.c (get_abstract_virtuals): Rename to get_pure_virtuals.
+
+1999-12-26 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cp-tree.h: Replace ENABLE_CHECKING with ENABLE_TREE_CHECKING
+ throughout.
+
+1999-12-26 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (store_return_init): Use mode of old RTL generated for
+ DECL_RESULT, not the mode of DECL_RESULT itself.
+ * semantics.c (finish_named_return_value): Set DECL_UNINLINABLE
+ for functions that used named return values.
+
+1999-12-24 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (expand_body): Use
+ note_deferral_of_defined_inline_function.
+
+1999-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (dequeue_and_dump): Handle CTOR_STMTs.
+
+1999-12-22 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+ * error.c (dump_decl): Support named return values.
+
+1999-12-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_VFIELD_PARENT): Update comments.
+ (CLASSTYPE_HAS_PRIMARY_BASE_P): New macro.
+ (CLASSTYPE_PRIMARY_BINFO): Likewise.
+ * class.c (check_methods): Don't set TYPE_HAS_COMPLEX_INIT_REF,
+ TYPE_NEEDS_CONSTRUCTING, and CLASSTYPE_NON_AGGREGATE here.
+ (check_bases_and_members): Set them here instead.
+ (create_vtable_ptr): New function, split out from ...
+ (finish_struct_1): ... here. Use it. Tidy. Use
+ CLASSTYPE_HAS_PRIMARY_BASE_P and CLASSTYPE_PRIMARY_BINFO.
+ * search.c (dfs_init_vbase_pointers): Handle seeing TYPE_VFIELD as
+ the first field in the class.
+ * tree.c (layout_basetypes): Use CLASSTYPE_N_BASECLASSES. Handle
+ seeing TYPE_VFIELD as the first field in the class.
+
+ * cp-tree.h (TYPE_VIRTUAL_P): Rename to ...
+ (TYPE_POLYMORPHIC_P): ... this.
+ (TYPE_USES_COMPLEX_INHERITANCE): Rename to ...
+ (TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P): ... this.
+ (TREE_CALLS_NEW): Remove.
+ (TREE_MANGLED): Likewise.
+ * call.c (build_vfield_ref): Use TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P,
+ and TYPE_POLYMORPHIC_P.
+ * class.c (check_bases): Likewise.
+ (finish_base_struct): Likewise.
+ (finish_struct_bits): Likewise.
+ (check_for_override): Likewise.
+ (finish_struct_1): Likewise.
+ (get_vfield_name): Likewise.
+ * decl.c (xref_basetypes): Likewise.
+ * decl2.c (import_export_class): Likewise.
+ (import_export_decl): Likewise.
+ * error.c (dump_function_decl): Likewise.
+ * pt.c (instantiate_class_template): Likewise.
+ * repo.c (repo_inline_used): Likewise.
+ * rtti.c (build_headof): Likewise.
+ (get_tinfo_fn_dynamic): Likewise.
+ (build_x_typeid): Likewise.
+ (get_tinfo_var): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ (synthesize_tinfo_fn): Likewise.
+ * search.c (lookup_field_1): Likewise.
+ (dfs_debug_mark): Likewise.
+ (maybe_suppress_debug_info): Likewise.
+ * typeck.c (build_component_ref): Likewise.
+ (build_component_addr): Likewise.
+ * typeck2.c (process_init_constructor): Likewise.
+
+1999-12-20 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (strip_all_pointer_quals): New static function.
+ (build_static_cast): Use it. Don't use at_least_as_qualified_p.
+
+1999-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Add CPTI_DSO_HANDLE.
+ (dso_handle_node): New macro.
+ (flag_use_cxa_atexit): New variable.
+ (declare_global_var): New function.
+ (start_anon_func): Remove declaration.
+ (end_anon_func): Likewise.
+ * decl.c (get_atexit_node): New function, split out from
+ destroy_local_static. Handle flag_use_cxa_atexit.
+ (get_dso_handle_node): Likewise.
+ (start_cleanup_fn): Renamed from start_anon_func. Moved here from
+ except.c. Handle flag_use_cxa_atexit.
+ (end_cleanup_fn): Renamed from end_anon_func. Moved here from
+ except.c.
+ (declare_global_var): New variable.
+ (destroy_local_static): Handle flag_use_cxa_atexit.
+ * decl2.c (flag_use_cxa_atexit): New variable.
+ (lang_f_options): Likewise.
+ * except.c (start_anon_func): Remove.
+ (end_anon_func): Liekwise.
+ * lang-options.h: Add -fuse-cxa-atexit and -fno-use-cxa-atexit.
+ * rtti.c (get_tinfo_var): Use declare_global_var.
+
+1999-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (check_field_decls): Don't return a value.
+ (avoid_overlap): Moved here from tree.c.
+ (build_base_fields): Likewise.
+ (check_bases): New function, split out from finish_base_struct.
+ (check_bases_and_members): New function, split out from
+ finish_struct_1.
+ (struct base_info): Remove cant_have_default_ctor,
+ cant_have_const_ctor, cant_have_asn_ref.
+ (finish_base_struct): Split semantic analysis into check_bases.
+ (finish_struct_methods): Fix bogus assertion.
+ (check_field_decls): Call finish_struct_anon here.
+ (build_vbase_pointer_fields): Use CLASSTYPE_N_BASECLASSES.
+ (finish_struct_1): Use check_bases_and_members. Reorganize.
+ * cp-tree.h (CLASSTYPE_VBASECLASSES): Improve documentation.
+ (build_base_fields): Don't declare.
+ * tree.c (avoid_overlap): Remove.
+ (build_base_fields): Likewise.
+
+ * optimize.c (struct inline_data): Remove scope_stmt.
+ (remap_block): Don't use insert_block_after_note. Don't update
+ scope_stmt.
+ (expand_call_inline): Don't update scope_stmt.
+ (optimize_function): Don't initialize scope_stmt.
+ * semantics.c (expand_stmt): Set NOTE_BLOCK for newly emitted
+ NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END notes.
+
+1999-12-15 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (handle_using_decl): Get TYPE_FIELDS and TYPE_METHODS
+ out of the class, rather than taking them as parameters.
+ (build_vbase_pointer_fields): Move here from tree.c.
+ (build_vtbl_or_vbase_field): New function.
+ (check_methods): Likewise.
+ (remove_zero_width_bitfields): Likewise.
+ (add_virtual_function): Use tree_cons instead of temp_tree_cons.
+ (delete_duplicate_fields_1): Tidy. Don't delete duplicate
+ USING_DECLs here.
+ (finish_struct_methods): Handle the case where there are no
+ methods here.
+ (get_basefndecls): Use tree_cons instead of temp_tree_cons.
+ (check_field_decls): Call delete_duplicate_fields here.
+ (finish_struct_1): Tidy. Use check_methods and
+ remove_zero_width_bitfields.
+ * cp-tree.h (build_vbase_pointer_fields): Remove.
+ * decl.c (grokdeclarator): Use tree_cons instead of
+ temp_tree_cons.
+ * decl2.c (qualified_lookup_using_namespace): Use tree_cons
+ instead of temp_tree_cons.
+ * lex.c (cons_up_default_function): Remove dead code.
+ * method.c (fixup_pending_inline): New function, split out from ...
+ (do_inline_function_hair): ... here.
+ * tree.c (build_vbase_pointer_fields): Remove.
+
+1999-12-15 Jason Merrill <jason@casey.cygnus.com>
+
+ * tree.c (walk_tree): Walk operand subtrees in forward order.
+ * optimize.c (expand_call_inline): Likewise.
+ (optimize_function): Initialize id->scope_stmt to something useful.
+ (remap_block): Assume id->scope_stmt has a useful value.
+
+1999-12-15 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (build_c_cast): Expand warning message. Move pointer
+ alignment warning to after the cast. Don't warn about pointer
+ alignment when given a pointer to incomplete.
+
+1999-12-15 Richard Henderson <rth@cygnus.com>
+
+ * cp-tree.h (make_aggr_type): Declare.
+ * lex.c (cp_make_lang_type): Don't SET_IS_AGGR_TYPE.
+ (make_aggr_type): New.
+
+ * decl.c (build_typename_type, init_decl_processing): Use it.
+ (build_ptrmemfunc_type, xref_tag): Likewise.
+ * except.c (call_eh_info): Likewise.
+ * init.c (init_init_processing): Likewise.
+ * pt.c (process_template_parm, lookup_template_class): Likewise.
+ * rtti.c (expand_class_desc): Likewise.
+ * semantics.c (begin_class_definition, finish_typeof): Likewise.
+ * tree.c (copy_template_template_parm): Likewise.
+
+1999-12-15 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.def (TEMPLATE_PARM_INDEX): Calculate size using
+ sizeof (struct tree_common).
+
+1999-12-14 Jason Merrill <jason@casey.cygnus.com>
+
+ * optimize.c (expand_call_inline): Set BLOCK_ABSTRACT_ORIGIN on the
+ outermost block to point to the inlined function decl.
+
+ * error.c (dump_decl): operator==, not operator ==.
+ (op_to_string): Likewise.
+
+ * decl.c (compute_array_index_type): Handle null name.
+
+ * decl2.c (ambiguous_decl): Fix to match comment.
+ (lookup_using_namespace): Adjust.
+
+ * decl2.c (import_export_class): Don't ignore dllimport.
+
+1999-12-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (check_field_decls): Split out from ...
+ (finish_struct_1): ... here. Use it. Tidy.
+
+ * cp-tree.h (remap_save_expr): Add walk_subtrees parameter.
+ * optimize.c (copy_body_r): Pass it.
+ * tree.c (remap_save_expr): Clear walk_subtrees for an
+ already-handled SAVE_EXPR.
+ (cp_unsave_r): Pass walk_subtrees to remap_save_expr.
+
+ * dump.c (dequeue_and_dump): Dump DECL_NAMESPACE_ALIAS.
+ * ir.texi (DECL_NAMESPACE_ALIAS): Document it.
+
+ * error.c (dump_expr): Handle EXPR_WITH_FILE_LOCATION.
+
+1999-12-14 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * class.c (finish_base_struct): Allow multiple COM base classes
+ as well as non-COM bases as long as it's not the leftmost.
+
+1999-12-13 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * lex.c (saving_parse_to_obstack): New global.
+ (reinit_parse_for_block): Use.
+ (reinit_parse_for_expr): Use.
+ (check_newline): Use.
+
+1999-12-13 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (initialize_inlined_parameters): Take FN to which the
+ parameters belong as an argument.
+ (expand_call_inline): Expand calls into the parameter
+ initializations before pushing the function onto the list of
+ functions we are presently expanding.
+
+1999-12-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (get_vtable_name): Use a literal format string and
+ VTABLE_NAME_PREFIX macro instead of VTABLE_NAME_FORMAT.
+ (prepare_fresh_vtable): Likewise.
+
+ * cp-tree.h (VTABLE_NAME_PREFIX): Define this instead of
+ VTABLE_NAME_FORMAT.
+
+ * decl.c (make_rtl_for_local_static): Remove unused variable `type'.
+
+ * init.c (build_vec_init): Initialize variable `try_body'.
+
+ * lex.c (yyerror): Don't call a variadic function with a
+ non-literal format string.
+
+ * optimize.c (optimize_function): Call memset, not bzero.
+
+ * pt.c (for_each_template_parm_r): Add static prototype.
+
+1999-12-09 Andreas Jaeger <aj@suse.de>
+
+ * except.c (expand_throw): Add static attribute to match
+ prototype.
+
+ * Makefile.in (semantics.o): Add dependency on output.h.
+ * semantics.c: Include output.h for declaration of
+ make_function_rtl.
+
+1999-12-09 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (init_decl_processing): Reenable inlining on trees.
+ (finish_function): Likewise.
+ * expr.c (cplus_expand_expr): Don't handle AGGR_INIT_EXPR here.
+ * semantics.c (simplify_aggr_init_exprs): New function.
+ (expand_body): Use it.
+ * tree.c (walk_tree): Special-case TARGET_EXPRs since they
+ sometimes present the same sub-tree twice.
+
+ * dump.c (dequeue_and_dump): Abbreviate `class' as `cls', not
+ `csl'.
+
+ * semantics.c (finish_switch_cond): Do conversions here, not ...
+ * typeck.c (c_expand_start_case): Here.
+
+ * semantics.c (do_poplevel): Remove unused variable.
+
+1999-12-06 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (walk_tree): Don't recurse into DECL_INITIAL or DECL_SIZE
+ unless we're declaring the variable in question.
+
+1999-12-06 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (init_decl_processing): #if 0 last patch.
+ (finish_function): Likewise.
+
+1999-12-05 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (init_decl_processing): Set flag_inline_trees if
+ !flag_no_inline.
+
+ * cp-tree.h (calls_setjmp_p): Declare.
+ * decl.c (finish_function): Mark functions that call setjmp as
+ uninlinable.
+ * optimize.c (calls_setjmp_r): New function.
+ (calls_setjmp_p): Likewise.
+
+1999-12-04 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (expand_call_inline): Wrap the expanded call in an
+ EXPR_WITH_FILE_LOCATION node to get correct line numbers for
+ inlined functions.
+
+ * optimize.c (inline_data): Remove fns_top. Add scope_stmt. Add
+ in_target_cleanup_p.
+ (remap_decl): New function.
+ (remap_block): Likewise.
+ (copy_scope_stmt): Likewise.
+ (copy_body_r): Use remap_decl and copy_scope_stmt.
+ (copy_body): Use VARRAY_TOP_TREE.
+ (initialize_inlined_parameters): Likewise.
+ (declare_return_variable): Likewise.
+ (inlinable_function_p): Check flag_inline_trees.
+ (expand_call_inline): Handle SCOPE_STMTs and TARGET_EXPRs
+ specially. Use VARRAY_PUSH_TREE. Create a BLOCK for the
+ parameters of the inlined function.
+ (optimize_function): Prevent recursion into partially complete
+ functions.
+
+ * cp-tree.def (SCOPE_STMT): Take one operand.
+ * cp-tree.h (SCOPE_STMT_BLOCK): New macro.
+ (SCOPE_NULLIFIED_P): Redefine.
+ (SCOPE_NO_CLEANUPS_P): New macro.
+ (add_scope_stmt): Change prototype.
+ * decl.c (poplevel): Tidy. Warn about unused variables here.
+ Record SCOPE_STMT_BLOCKs.
+ (finish_function): Keep DECL_INITIAL for functions that might be
+ inlined.
+ * ir.texi: Document SCOPE_NO_CLEANUPS_P.
+ * semantics.c: Include rtl.h.
+ (add_scope_stmt): Return the new scope statement and, for an
+ end-of-scope statement, its matching begin statement. Don't set
+ SCOPE_NULLIFIED_P.
+ (do_pushlevel): Simplify, now that we are always
+ function-at-a-time.
+ (do_poplevel): Likewise. Record SCOPE_STMT_BLOCKs.
+ (expand_stmt): Don't call expand_start_bindings or
+ expand_end_bindings for a scope with SCOPE_NO_CLEANUPS_P set.
+ * tree.c (copy_tree_r): Clear SCOPE_STMT_BLOCK rather than setting
+ SCOPE_NULLIFIED_P.
+ * Makefile.in (semantics.o): Depend on RTL_H.
+
+ * decl2.c (pending_statics_used): Make it a macro.
+ (saved_inlines_used): Likewise.
+ (finish_static_data_member_decl): Use VARRAY_PUSH_TREE.
+ (mark_inline_for_output): Likewise.
+ (ssdf_decls_used): Remove.
+ (start_static_storage_duration_function): Use VARRAY_PUSH_TREE.
+ (generate_ctor_or_dtor_function): Adjust accordingly.
+
+1999-11-24 Geoffrey Keating <geoffk@cygnus.com>
+ Greg McGary <gkm@gnu.org>
+
+ * decl.c (duplicate_decls): Merge
+ DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT,
+ DECL_NO_CHECK_MEMORY_USAGE, DECL_NO_LIMIT_STACK.
+
+1999-12-02 Mike Stump <mrs@wrs.com>
+
+ * init.c (perform_member_init): Handle parse errors better.
+
+1999-12-01 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (min_tree_cons): Remove.
+ (scratch_ovl_cons): Likewise.
+ * decl.c (saveable_obstack): Don't declare.
+ (duplicate_decls): Tweak error-message.
+ (initialize_local_var): Explicitly mark the definition as static.
+ (finish_function): Call permanent_allocation, just so
+ that the middle-end sees the obstacks it expects.
+ (mark_cp_function_context): Likewise.
+ * init.c (build_new): Don't use min_tree_cons.
+ * lex.c (permanent_obstack): Don't declare.
+ (current_obstack, saveable_obstack): Likewise.
+ * spew.c (current_obstack, saveable_obstack): Likewise.
+ * tree.c (current_obstack, saveable_obstack): Likewise.
+ (scratch_ovl_cons): Remove.
+ (build_min_nt): Don't mess with obstacks.
+ (build_min): Likewise.
+ (min_tree_cons): Remove
+ * typeck.c (build_component_ref): Don't use scratch_ovl_cons.
+ (build_x_function_call): Likewise.
+ (build_c_cast): Don't use min_tree_cons.
+
+1999-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_decl): Robustify.
+
+1999-11-27 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_file): Call expand_body for inline functions
+ that will be written out but that do not yet have RTL.
+ * semantics.c (expand_body): Do not generate RTL For inline
+ functions that do not yet need to be written out.
+
+1999-11-25 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (CXX_SRCS): Add optimize.c.
+ * Makefile.in (CXX_OBJS): Add optimize.o.
+ (CXX_TREE_H): Add splay-tree.h, system.h, and $(CONFIG_H).
+ (spew.o, lex.o, decl.o, decl2.o, typeck2.o, typeck.o): Adjust.
+ (class.o, call.o, friend.o, init.o, method.o, cvt.o): Likewise.
+ (search.o, tree.o, ptree.o, rtti.o, except.o, expr.o): Likewise.
+ (xref.o, pt.o, error.o, errfn.o, repo.o, semantics.o): Likewise.
+ (dump.o): Likewise.
+ (optimize.o): New target.
+ * class.c: Don't include splay-tree.h.
+ * cp-tree.def (CTOR_COMPLETE): Rename to CTOR_STMT.
+ * cp-tree.h: Include splay-tree.h.
+ (DECL_UNINLINABLE): New macro.
+ (CTOR_BEGIN_P, CTOR_END_P): New macros.
+ (flag_inline_trees): New variable.
+ (local_variable_p): New function.
+ (nonstatic_local_decl_p): Likewise.
+ (optimize_function): Likewise.
+ (cplus_unsave_expr_now): Remove.
+ (copy_tree_r): Declare.
+ (remap_save_expr): Likewise.
+ * decl.c (local_variable_p): Don't
+ make it static.
+ (local_variable_p_walkfn): New function.
+ (make_rtl_for_local_static): Remove code to try to avoid writing
+ out static constants.
+ (emit_local_var): Fix indentation.
+ (nonstatic_local_decl_p): New function.
+ (check_default_argument): Use local_variable_p_walkfn, not
+ local_variable_p, when walking the tree.
+ (start_function): Set the DECL_CONTEXT for automatically generated
+ labels.
+ (finish_constructor_body): Use CTOR_STMT to mark the end of a
+ constructor.
+ * decl2.c: Don't include splay-tree.h.
+ (flag_inline_trees): Define.
+ * dump.c: Don't include
+ splay-tree.h.
+ * except.c (expand_end_catch_block): Fix comment formatting.
+ (expand_end_eh_spec): Set DECL_CONTEXT on temporary variables.
+ (expand_throw): Tidy comment.
+ * init.c (build_vec_delete_1): Use create_temporary_var.
+ * lex.c (cplus_tree_code_type): Make it static.
+ (cplus_tree_code_length): Likewise.
+ (cplus_tree_code_name): Likewise.
+ * optimize.c: New file.
+ * semantics.c (finish_goto_stmt): Set DECL_UNLINABLE for functions
+ with computed gotos.
+ (setup_vtbl_ptr): Mark the beginnings of constructors with
+ CTOR_STMT.
+ (expand_stmt): Handle CTOR_STMT, not CTOR_COMPLETE.
+ (expand_body): Call optimize_function. Save bodies if we're doing
+ inlining on trees.
+ * tree.c: Don't include splay-tree.h. Include insn-config.h and
+ integrate.h.
+ (copy_tree_r): Make it public.
+ (statement_code_p): New function.
+ (mark_local_for_remap_r): Likewise.
+ (cp_usave_r): Likewise.
+ (cp_unsave): Likewise.
+ (build_cplus_new): Set DECL_CONTEXT for temporary variables.
+ (walk_tree): Walk into `s' class nodes. Walk statement chains.
+ (copy_tree_r): Handle 's' class nodes. Restore chains for
+ statements. Nullify scopes. Don't copy types.
+ (init_tree): Set lang_unsave to cp_unsave.
+ (remap_save_expr): Define.
+ * ir.texi: Document CTOR_STMT.
+
+1999-11-24 Jason Merrill <jason@casey.cygnus.com>
+
+ * search.c (note_debug_info_needed): Do perform this optimization
+ for dwarf2.
+ (maybe_suppress_debug_info): Likewise. Start by clearing
+ TYPE_DECL_SUPPRESS_DEBUG.
+
+1999-11-24 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_decl): Copy TREE_ASM_WRITTEN for VAR_DECLs.
+
+ * decl2.c (finish_vtable_vardecl): Don't prune vtables here.
+
+1999-11-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (pushdecl, grokdeclarator): Don't call a variadic
+ function with a non-literal format string.
+
+ * lex.c (do_identifier): Likewise.
+
+ * typeck.c (build_unary_op): Likewise.
+
+1999-11-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_NEEDED_P): Tweak to match documentation.
+
+1999-11-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (CTOR_COMPLETE): New tree node.
+ * decl.c (finish_constructor_body): Add it, to mark the end of the
+ constructor.
+ (finish_function): Don't call end_protect_partials here.
+ * ir.texi (CTOR_COMPLETE): Document it.
+ * semantics.c (expand_stmt): Handle it.
+
+ * cp-tree.def (FUNCTION_NAME): New tree node.
+ * cp-tree.h (current_function_name_declared): Tweak documentation.
+ (lang_decl_flags): Add pretty_function_p, adjust dummy.
+ (DECL_PRETTY_FUNCTION_P): New macro.
+ * decl.c (cp_finish_decl): Handle declarations of __FUNCTION__,
+ etc., in a template function. Use at_function_scope_p instead of
+ expanding it inline.
+ * pt.c (tsubst_decl): Handle DECL_PRETTY_FUNCTION_P declarations
+ specially.
+ (tsubst): Handle FUNCTION_NAME.
+ (tsubst_copy): Likewise.
+ (instantiate_decl): Prevent redeclarations of __PRETTY_FUNCTION__,
+ etc. in instantiation.
+ * semantics.c (begin_compound_stmt): Declare __FUNCTION__, etc.,
+ even in template functions.
+ (setup_vtbl_ptr): Don't declare __PRETTY_FUNCTION in the
+ conditional scope at the top of a destructor.
+
+ * error.c (dump_function_decl): Use `[ with ... ]' syntax for
+ specializations too.
+
+1999-11-22 Nathan Sidwell <nathan@acm.org>
+
+ * semantics.c (finish_unary_op_expr): Only set TREE_NEGATED_INT
+ when actually negative.
+
+ * typeck.c (convert_for_assignment): Expand comment about
+ strange NULL check, moved from ...
+ (convert_for_initialization): ... here. Remove unneeded
+ code.
+
+1999-11-21 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+ * cp-tree.h (build_vec_delete): Remove `auto_delete' argument.
+ * init.c (build_vec_delete, build_vec_delete_1): Likewise.
+ Always destruct virtual bases of array components, but never
+ delete them.
+ (build_vec_init): Adjust invocations.
+ (build_delete): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+
+1999-11-19 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (grok_method_quals): Return this pointer qualifiers.
+ * decl.c (grokdeclarator): Adjust calls to grok_method_quals.
+ * decl2.c (grok_method_quals): Accept `restrict' as applying to
+ the object pointer. Return such qualifiers.
+ (grokclassfn): Apply this pointer qualifiers. Cleanup unused
+ variables.
+
+1999-11-18 Mark Mitchell <mark@codesourcery.com>
+
+ * except.c (expand_end_catch_block): Fix typo.
+ (expand_exception_blocks): Simplify. Don't call
+ expand_leftover_cleanups.
+
+1999-11-15 Jason Merrill <jason@casey.cygnus.com>
+
+ * cp-tree.h, decl.c (compute_array_index_type): Make nonstatic.
+ * pt.c (tsubst, case INTEGER_TYPE): Call it.
+ Check uses_template_parms.
+
+ * class.c (finish_struct): If we're a local class in a template
+ function, add a TAG_DEFN.
+ * pt.c (lookup_template_class): If this is a local class in a
+ template function, call pushtag.
+ (tsubst_expr, case TAG_DEFN): Handle classes, too.
+
+ Emit debug info with the vtable.
+ * search.c (maybe_suppress_debug_info): New function...
+ * class.c (finish_struct_1): ...split out from here.
+ * cp-tree.h: Declare it.
+ * decl2.c (finish_vtable_vardecl): Override TYPE_DECL_SUPPRESS_DEBUG
+ if we're writing out the vtable.
+ * decl.c, search.c (dfs_debug_mark, dfs_debug_unmarked_p,
+ note_debug_info_needed): #if 0 out.
+
+1999-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_LOCAL_FUCNTION_P): New macro.
+ * call.c (equal_functions): Use DECL_LOCAL_FUCNTION_P, not
+ TREE_PERMANENT.
+ * decl.c (pushdecl): Set DECL_LOCAL_FUNCTION_P.
+ * decl2.c (lookup_arg_dependent): Use it.
+
+ * cp-tree.h (cp_finish_decl): Change prototype.
+ (finish_static_data_member_decl): Likewise.
+ (push_permanent_obstack): Remove declaration.
+ (push_expression_obstack): Likewise.
+ (push_scratch_obstack): Likewise.
+ (DECL_TEMPLATE_PARM_P): Robustify.
+ (SET_DECL_TEMPLATE_PARM_P): New macro.
+ * class.c (add_method): Don't manipulate obstacks.
+ (finish_vtbls): Likewise.
+ * cvt.c (build_up_reference): Adjust calls to cp_finish_decl.
+ * decl.c (binding_for_name): Don't manipulate obstacks.
+ (maybe_push_to_top_level): Likewise.
+ (pop_from_top_level): Likewise.
+ (duplicate_decls): Likewise.
+ (pushdecl): Likewise.
+ (implicitly_declare): Likewise.
+ (build_typename_type): Likewise.
+ (start_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (finish_decl): Likewise.
+ (destroy_local_static): Likewise.
+ (expand_static_init): Likewise.
+ (complete_array_type): Likewise.
+ (grokvardecl): Likewise.
+ (build_ptrmemfnc_type): Likewise.
+ (grokdeclarator): Likewise.
+ (xref_tag): Likewise.
+ (xref_basetypes): Likewise.
+ (start_enum): Likewise.
+ (finish_enum): Likewise.
+ (start_function): Likewise.
+ (finish_function): Likewise.
+ (start_method): Adjust call to cp_finish_decl.
+ * decl2.c (finish_static_data_member_decl): Don't manipulate
+ obstacks.
+ (grokfield): Likewise.
+ (grokbitfield): Likewise.
+ (get_temp_name): Likewise.
+ (get_sentry): Likewise.
+ (fnish_file): Likewise.
+ (lookup_arg_dependent): Likewise.
+ * except.c (call_eh_info): Likewise.
+ (push_eh_info): Likewise.
+ (do_pop_exception): Likewise.
+ (initialize_handler_parm): Likewise.
+ (expand_end_eh_spec): Likewise.
+ (alloc_eh_object): Likewise.
+ (expand_throw): Likewise.
+ * expr.c (extract_scalar_init): Likewise.
+ * init.c (build_java_class_ref): Likewise.
+ * lex.c (get_time_identifier): Likewise.
+ (snarf_defarg): Likewise.
+ (add_defarg_fn): Likewise.
+ (is_global): Simplify.
+ (do_identifier): Don't check TREE_PERMANENT.
+ * method.c (emit_thunk): Don't manipulate obstacks.
+ * parse.y (condition): Adjust call to cp_finish_decl.
+ (primary): Likewise.
+ (initdcl): Likewise.
+ (initdcl0_innards): Likewise.
+ (nomods_initdcl0): Likewise.
+ * pt.c (push_inline_template_parms_recursive): Use
+ SET_DECL_TEMPLATE_PARM_P.
+ (process_template_parm): Likewise.
+ (lookup_template_class): Don't manipulate obstacks.
+ (instantiate_class_template): Adjust call to
+ finish_static_data_member_decl.
+ (tsubst_decl): Don't manipulate obstacks.
+ (tsubst_expr): Likewise.
+ (instantiate_template): Likewise.
+ (instantiate_decl): Adjust calls to cp_finish_decl.
+ * rtti.c (call_void_fn): Don't manipulate obstacks.
+ (get_tinfo_var): Likewise.
+ (get_tinfo_fn_unused): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ (expand_si_desc): Likewise.
+ (expand_class_desc): Likewise.
+ (expand_ptr_desc): Likewise.
+ (expand_attr_desc): Likewise.
+ (expand_generic_desc): Likewise.
+ (synthesize_tinfo_fn): Likewise.
+ * search.c (expand_upcast_fixups): Likewise.
+ * semantics.c (finish_asm_stmt): Likewise.
+ (finish_named_return_value): Likewise.
+ (begin_class_definition): Likewise.
+ (finish_class_definition): Likewise.
+ (finish_typeof): Likewise.
+ * tree.c (build_cplus_method_type): Likewise.
+ (reverse_path): Likewise.
+ (copy_template_template_parm): Likewise.
+ (build_expr_ptr_wrapper): Likewise.
+ (push_expression_obstack): Remove.
+ (push_permanent_obstack): Likewise.
+ * typeck.c (mark_addressable): Likewise.
+
+1999-11-13 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_conditional_expr): Use build_target_expr_with_type.
+ (convert_like): Likewise.
+ (build_over_call): Likewise.
+ * cp-tree.h (build_target_expr): Remove.
+ (build_target_expr_with_type): New function.
+ * cvt.c (build_up_reference): Use get_target_expr.
+ * decl.c (build_target_expr): Move to ...
+ * tree.c (build_target_expr): Here. Make it static.
+ (build_target_expr_with_type): New function. Set DECL_CONTEXT on
+ the temporary VAR_DECLs.
+ (get_target_expr): Use it.
+
+1999-11-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (duplicate_decls): Propagate DECL_DEFER_OUTPUT.
+ * decl2.c (comdat_linkage): Set DECL_DEFER_OUTPUT.
+ * rtti.c (get_tinfo_fn_unused): Split out from get_tinfo_fn.
+ * class.c (set_rtti_entry): Use it.
+
+1999-11-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cplus_expand_expr_stmt): Don't call break_out_cleanups
+ here.
+ * semantics.c (finish_expr_stmt): Call it here instead. Move
+ default_conversion logic to semantic-analysis time.
+
+1999-11-12 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (synthesize_tinfo_fn): Set DECL_DEFER_OUTPUT.
+
+Fri Nov 12 12:56:32 MST 1999 Diego Novillo <dnovillo@cygnus.com>
+
+ * init.c (init_init_processing): Re-instated Nov 11 patch after
+ approval.
+
+Fri Nov 12 10:42:02 MST 1999 Diego Novillo <dnovillo@cygnus.com>
+
+ * init.c (init_init_processing): Undo patch from Nov 11, 1999.
+ Patch had not been approved yet.
+
+1999-11-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (compute_array_index_type): New function, split out from
+ grokdeclarator.
+ (create_array_type_for_decl): Likewise.
+ (grokdeclarator): Use them.
+
+ * semantics.c (expand_stmt): Don't suspend_momentary or
+ resume_momentary.
+
+Thu Nov 11 12:42:11 MST 1999 Diego Novillo <dnovillo@cygnus.com>
+
+ * init.c (init_init_processing): Header information for
+ arrays allocated via `new' should have the same alignment used by
+ malloc.
+
+1999-11-10 Mark Mitchell <mark@codesourcery.com>
+
+ * error.c (dump_function_name): Don't crash if given a friend
+ pseudo-instantiation.
+
+ * cp-tree.h (build_enumerator): Change prototype.
+ * decl.c (enum_next_value): Remove.
+ (enum_overflow): Likewise.
+ (init_decl_processing): Don't register enum_next_value as a root.
+ (start_enum): Clear TYPE_VALUES for a redefined enum.
+ (finish_enum): Reset the type of enumeration constants.
+ (build_enumerator): Fix indentation. Don't copy CONST_DECLs when
+ we don't need to. Maintain the TYPE_VALUES list and look there
+ for the previously defined enumeration constant. Let enumeration
+ constants have the type of their values until the enumeration type
+ is complete.
+ * parse.y (enumlist_opt, enumlist, enumerator): Don't return a value.
+ (structsp): Adjust.
+ * parse.c: Regenerated.
+ * pt.c (tsubst_enum): Adjust according to build_enumerator changes.
+
+Wed Nov 10 12:43:21 1999 Philippe De Muyter <phdm@macqel.be>
+ Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h: Test `GCC_VERSION', not `HAVE_GCC_VERSION'.
+
+1999-11-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (language_function): Remove x_last_dtor_insn and
+ x_last_parm_cleanup_insn.
+ * decl.c (last_dtor_insn): Remove.
+ (last_parm_cleanup_insn): Likewise.
+ (expand_start_early_try_stmts): Don't set them.
+ (store_parm_decls): Likewise.
+ (save_function_data): Or save them.
+ (mark_lang_function): Or mark them.
+
+1999-11-08 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (store_parm_decls): Generate cleanup code at
+ semantic-analysis time. Destroy objects in the correct order.
+
+1999-11-07 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (begin_new_placement): Remove.
+ (finish_new_placement): Likewise.
+ * class.c (finish_struct_1): Don't suspend_momentary or
+ resume_momentary.
+ * decl.c (grokdeclarator): Likewise.
+ (maybe_build_cleanup_1): Likewise.
+ * except.c (push_eh_cleanup): Likewise.
+ (build_terminate_handler): Likewise.
+ * init.c (build_new_1): Likewise.
+ * parse.y (parse_decl): Change prototype.
+ (initdecls, notype_initdecls, initdcl): Don't return int.
+ (initdcl0, notype_initdcl0, initdcl0_innards): Likewise.
+ (.begin_new_placement): Remove.
+ (.finish_new_placement): Likewise.
+ (nonmomentary_expr): Likewise.
+ (suspend_mom): Likewise.
+ (condition): Don't suspend_momentary, resume_momentary, or keep
+ track of need to resume.
+ (unary_expr): Likewise.
+ (new_placement): Likewise.
+ (decl): Likewise.
+ (structsp): Likewise.
+ (new_type_id): Likewise.
+ (maybe_parmlist): Likewise.
+ (direct_after_type_declaration): Likewise.
+ (direct_new_declarator): Likewise.
+ (direct_abstract_declaration): Likewise.
+ * parse.c: Regenerated.
+ * pt.c (tsubst_expr): Don't suspend_momentary or resume_momentary.
+ * semantics.c (begin_new_placement): Remove.
+ (finish_new_placement): Likewise.
+
+1999-11-05 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * cp-tree.h (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK): New macro.
+ (DECL_TEMPLATE_INFO): Use it.
+ * decl.c (warn_extern_redeclared_static): Do nothing for
+ TEMPLATE_DECLs.
+ * decl2.c (mark_used): Explicitly check for function or variable.
+ * semantics.c (finish_unary_op_expr): Check whether result is also
+ an INTEGER_CST.
+
+1999-11-05 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (typeck2.o): Depend on output.h.
+ * typeck2.c: Include output.h.
+
+ * decl.c (flag_ansi): Remove declaration.
+
+ * pt.c (tinst_level_tick): Make it static.
+ (last_template_error_tick): Likewise.
+
+ * cp-tree.h (mapcar): Remove declaration.
+ (search_tree): Likewise.
+ (walk_tree_fn): New typedef.
+ (walk_tree): New function.
+ * tree.c (bot_manip): Change prototype. Adjust to be called via
+ walk_tree.
+ (bot_replace): Likewise.
+ (no_linkage_helper): Likewise.
+ (copy_tree_r): New function.
+ (search_tree): Rename, and adjust, to become ...
+ (walk_tree): New function.
+ (mapcar): Remove.
+ (target_remap): Remove.
+ (target_remap_count): Likewise.
+ (break_out_target_exprs): Use walk_tree.
+ * decl.c (local_variable_p): Change prototype.
+ (check_default_argument): Use walk_tree.
+ * pt.c (for_each_template_parm_r): New function, split out from ...
+ (for_each_template_parm): Here. Use it, via walk_tree.
+
+1999-11-03 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (check_bitfield_decl): New function, split out from
+ finish_stuct_1.
+ (check_field_decl): Likewise. Recursively examine members of
+ anonymous structs.
+ (finish_struct_1): Use them.
+ * cp-tree.h (ANON_UNION_TYPE_P): New macro.
+
+1999-11-02 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokfndecl): Remove dead code.
+
+ * dump.c (dequeue_and_dump): Fix thinko for catch-clauses.
+
+1999-11-02 Scott Snyder <snyder@fnal.gov>
+
+ * decl2.c (build_expr_from_tree): Handle REALPART_EXPR and
+ IMAGPART_EXPR.
+ * pt.c (tsubst_copy): Likewise.
+
+1999-11-01 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (maybe_make_one_only): Always make things comdat on
+ ELF targets, too.
+
+1999-10-31 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (finish_function): Call free_after_parsing for functions
+ we are not immediately turning into RTL.
+
+1999-10-31 Brendan Kehoe <brendan@cygnus.com>
+
+ * cp-tree.h (flag_dump_translation_unit): Add decl.
+
+Sat Oct 30 22:42:50 1999 Stephen L Moshier <moshier@mediaone.net>
+
+ * lex.c (yylex): Accept 'f' in mantissa of hex float constant.
+
+1999-10-30 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pop_cp_function_context): Don't call free on a NULL
+ pointer.
+ * semantics.c: Include ggc.h.
+ (expand_body): Do garbage-collection after processing a template
+ function. Clear DECL_SAVED_TREE after generating RTL for a
+ function.
+ * Makefile.in (semantics.o): Depend on ggc.h.
+
+1999-10-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (make_typename_type): Change prototype.
+ * decl.c (make_typename_type): Only complain if so requested.
+ * parse.y (nested_name_specifier): Adjust calls.
+ (typename_sub0): Likewise.
+ (typename_sub1): Likewise.
+ * parse.c: Regenerated.
+ * pt.c (convert_template_argument): Pass complain to
+ make_typename_type.
+ (tsubst): Likewise.
+
+1999-10-28 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (finish_handler): End the scope of the handler
+ before attaching it to the statement-tree.
+
+1999-10-28 Ian Lance Taylor <ian@zembu.com>
+
+ * rtti.c (build_dynamic_cast_1): Give a better error message for
+ an attempt to dynamic_cast from a non-polymorphic type.
+
+1999-10-27 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (make_temp_vec): Remove.
+ (make_scratch_vec): Likewise.
+ * call.c (add_function_candidate): Use make_tree_vec.
+ (add_conv_candidate): Likewise.
+ (build_builtin_candidate): Likewise.
+ (add_template_candidate_real): Likewise.
+ * class.c (resolve_address_of_overloaded_function): Likewise.
+ * decl.c (start_function): Don't fool with the momentary obstack.
+ (finish_function): Likewise.
+ * init.c (expand_direct_vtbls_init): Likewise.
+ (begin_init_stmts): Likewise.
+ (finish_init_stmts): Likewise.
+ * pt.c (add_to_template_args): Use make_tree_vec.
+ (check_explicit_specialization): Likewise.
+ (coerce_template_parms): Likewise.
+ (lookup_template_class): Don't fool with the momentary obstack.
+ (instantiate_class_template): Likewise.
+ (tsubst_template_arg_vector): Use make_tree_vec.
+ (tsubst_aggr_type): Don't fool with the momentary obstack.
+ (tsubst_decl): Likewise. Use make_tree_vec.
+ (try_one_overload): Likewise.
+ (try_class_unification): Don't fool with the momentary obstack.
+ (get_bindings_real): Use make_tree_vec.
+ (set_mangled_name_for_template_decl): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Don't fool with the momentary obstack.
+ * semantics.c (finish_expr_stmt): Likewise.
+ (finish_do_stmt): Likewise.
+ (finish_for_expr): Likewise.
+ (finish_switch_cond): Likewise.
+ (do_pushlevel): Likewise.
+ (do_poplevel): Likewise.
+ * tree.c (make_temp_vec): Remove.
+
+ * dump.c (dequeue_and_dump): Dump HANDLERs and SAVE_EXPRs. Dump
+ CLEANUP_P for a TRY_BLOCK.
+ * ir.texi: Document SAVE_EXPR.
+
+Tue Oct 26 23:29:56 1999 Jeffrey A Law (law@cygnus.com)
+
+ * call.c (build_over_call): Check that the built-in function is
+ of class BUILT_IN_NORMAL before trying to recongize it as BUILT_IN_ABS.
+ * typeck.c (build_function_call_real): Similarly.
+
+1999-10-26 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (poplevel): Don't set BLOCK_TYPE_TAGS. Don't call
+ remember_end_note.
+
+1999-10-24 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (push_overloaded_decl_1): Use pushdecl.
+
+ * decl.c (auto_function): Replace #ifdef'd __inline with just
+ plain inline.
+ * lex.c (my_get_run_time): Likeise.
+ (yyprint): Likewise.
+ (identifier_type): Likewise.
+ * method.c (start_squangling): Likewise.
+ (end_squangling): Likewise.
+ (icat): Likewise.
+ (old_backref_index): Likewise.
+ (flush_repeats): Likewise.
+ (issue_ktype): Likewise.
+ * parse.y (empty_parms): Likewise.
+ * parse.c: Regenerated.
+
+1999-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (dequeue_and_dump): Replace several uses of
+ queue_and_dump_index with dump_child.
+
+1999-10-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * expr.c: Include tm_p.h.
+
+1999-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (SCOPE_PARTIAL_P): New macro.
+ (pushlevel_temporary): Remove.
+ (add_scope_stmt): New function.
+ * decl.c (pushlevel_temporary): Remove.
+ (poplevel): Use add_scope_stmt.
+ (start_decl_1): Likewise.
+ * semantics.c (add_scope_stmt): New function.
+ (do_pushlevel): Use it.
+ (do_poplevel): Use it.
+ (expand_stmt): Check SCOPE_PARTIAL_P.
+
+ * cp-tree.def (EMPTY_CLASS_EXPR): New tree node.
+ * call.c (build_call): Use EMPTY_CLASS_EXPR instead of RTL_EXPR.
+ * expr.c (cplus_expand_expr): Expand it.
+ * ir.texi: Document EMPTY_CLASS_EXPR.
+
+1999-10-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_NAMESPACE_SCOPE_P): Don't treat template
+ parameters as having namespace scope.
+
+1999-10-19 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (PARM_CAN_BE_ARRAY_TYPE): Remove.
+ (mangling_flags): New type.
+ (build_overload_int): Change prototype.
+ (build_overload_value): Likewise.
+ (numeric_output_need_bar): Improve comment.
+ (mangle_expression): New function, broken out from ...
+ (build_overload_int): Here.
+ (build_overload_value): Adjust for use of mangling flags. Don't
+ warn about real-valued template parameters here. Do handle
+ complex expressions involving real-valued template parameters.
+ (build_template_parm_names): Encase non-type template parameters
+ in underscores, if necessary.
+ (process_overload_item): Remove conditional on
+ PARM_CAN_BE_ARRAY_TYPE.
+
+1999-10-17 Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (dequeue_and_dump): Handle CLEANUP_POINT_EXPR.
+
+ * ir.texi: Clean up documentation of RETURN_INIT.
+
+1999-10-15 Greg McGary <gkm@gnu.org>
+
+ * lex.c (lang_init_options): Set flag_bounds_check as "unspecified".
+ (lang_init): Set default for flag_bounds_check if still "unspecified".
+
+1999-10-13 Andrew Haley <aph@cygnus.com>
+
+ * class.c (finish_struct_1): Force alignment of non-bitfields to
+ BITS_PER_UNIT.
+
+Wed Oct 13 22:01:35 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * typeck2.c (process_init_constructor): Handle empty constructors.
+
+1999-10-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lang_mark_tree): Mark NAMESPACE_LEVEL.
+
+ * pt.c (tsubst, case INTEGER_TYPE): Be more explicit in zero-size
+ array error.
+
+1999-10-13 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (make_rtl_for_local_static): Don't create register RTL
+ for addressable constants.
+
+1999-10-13 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (build_x_va_arg): Prototype new function.
+ * call.c (build_x_va_arg): Define it.
+ * parse.y (unary_expr): Call build_x_va_arg.
+
+ * cp-tree.h (convert_type_from_ellipsis): Prototype new function.
+ * call.c (convert_type_from_ellipsis): Define it.
+ * decl.c (init_decl_processing): Set lang_type_promotes_to.
+
+ * tree.c (lvalue_p_1): Accept VA_ARG_EXPR with aggregates.
+
+1999-10-11 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (fixed_type_or_null): Always set *nonnull.
+
+1999-10-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h: Use HAVE_GCC_VERSION instead of explicitly testing
+ __GNUC__ and __GNUC_MINOR__.
+
+1999-10-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (make_rtl_for_local_static): New function.
+ * decl.c (make_rtl_for_nonlocal_decl): Move code to create RTL for
+ local statics ...
+ (make_rtl_for_local_static): Here.
+ * semantics.c (expand_stmt): Use make_rtl_for_local_static.
+
+1999-10-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * method.c: Include tm_p.h.
+
+1999-10-7 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * cp-tree.h (cp_make_lake_type): Renamed from make_lang_type.
+ * lex.c (cp_make_lake_type): Likewise.
+ * tree.c (init_tree): Init make_lang_type_fn.
+
+1999-10-07 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_expr): Set DECL_TEMPLATE_INSTANTIATED for a catch
+ parameter.
+
+ * semantics.c (expand_stmt): Don't pretend to have asmspecs for
+ local statics if we don't really have them.
+
+ * ir.texi: Improve documentation for STMT_EXPR. Describe
+ CLEANUP_POINT_EXPR.
+
+1999-10-07 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (build_vtable_entry_ref): Use finish_asm_stmt.
+
+1999-10-07 Greg McGary <gkm@gnu.org>
+
+ * class.c (finish_struct_1): Use simpler method of
+ removing elements of a singly-linked list which doesn't
+ lose for classes without data members.
+
+1999-10-07 Mark Mitchell <mark@codesourcery.com>
+
+ * friend.c (make_friend_class): Robustify.
+
+ * semantics.c (finish_object_call_expr): Reject calls to template
+ types.
+
+1999-10-06 Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (dequeue_and_dump): Dump all three operands to a COND_EXPR.
+
+ * cp-tree.h (CLASSTYPE_VFIELD): Remove.
+ * call.c (build_vfield_ref): Use TYPE_VFIELD, not
+ CLASSTYPE_VFIELD.
+ * class.c (get_vfield_offset): Likewise.
+ (finish_base_struct): Likewise.
+ (modify_one_vtable): Likewise.
+ (fixup_vtable_deltas): Likewise.
+ (finish_struct_1): Likewise.
+ * init.c (expand_virtual_init): Likewise.
+ * search.c (lookup_field_1): Likewise.
+ (expand_upcast_fixups): Likewise.
+ * typeck.c (build_component_ref): Likewise.
+ (build_binary_op_nodefault): Likewise.
+
+ * dump.c (dqueue_and_dump): Dump TYPE_VFIELD.
+ * ir.texi: Document TYPE_VFIELD.
+
+1999-10-06 Brendan Kehoe <brendan@cygnus.com>
+
+ * decl.c (grokdeclarator): Only warn about nonzero arrays if
+ !in_system_header (linux socketbits.h can give this for
+ __cmsg_data, which is using a GNU extension).
+
+1999-10-05 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (start_static_storage_duration_function): Push the
+ function declaration so it ends up in namespace scope.
+
+ * dump.c (DUMP_CHILDREN): Remove.
+ (DUMP_BINFO): Adjust.
+ (struct dump_node_info): Remove dump_children_p.
+ (queue_and_dump_type): Remove dump_children_p parameter.
+ (queue): Don't set dump_children_p.
+ (dump_child): Pass DUMP_NONE, instead of DUMP_CHILDREN, to
+ queue_and_dump_index.
+ (dequeue_and_dump): Unconditionally print children. Adjust calls
+ to functions mentioned above.
+ (dump_node): Pass DUMP_NONE, instead of DUMP_CHILDREN to queue.
+
+ * ir.texi: Document BIND_EXPR, LOOP_EXPR, and EXIT_EXPR.
+ * dump.c (dequeue_and_dump): Dump them.
+
+ * method.c (synthesize_method): Call setup_vtbl_ptr for destructors.
+
+ * decl.c (start_function): Set current_in_charge_parm for
+ constructors, too, where appropriate.
+ * search.c (fixup_all_virtual_upcast_offsets): New function.
+ (expand_indirect_vtbls_init): Use it.
+
+1999-10-04 Nathan Sidwell <nathan@acm.org>
+
+ * decl2.c (grok_alignof): Don't decay lvalues.
+
+ * init.c (build_new): Remove unused variable.
+
+1999-10-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct language_function): Remove static_labelno.
+ (static_labelno): Remove macro.
+ * method.c (build_overload_nested_name): Make static_labelno
+ static here.
+
+ * pt.c (instantiate_decl): Use DECL_SAVED_TREE, not DECL_INITIAL,
+ to decide whether or not a function is defined.
+
+ * call.c (build_over_call): Don't set TREE_SIDE_EFFECTS for
+ situations where make_node will do it automatically.
+ * decl.c (grok_reference_init): Likewise.
+ (expand_static_init): Likewise.
+ (do_static_initialization): Likewise.
+ * init.c (perform_member_init): Likewise.
+ (expand_aggr_init_1): Likewise.
+ (build_new_1): Likewise.
+ * method.c (do_build_copy_constructor): Likewise.
+ (do_build_assign_ref): Likewise.
+ * search.c (expand_upcast_fixups): Likewise.
+ * semantics.c (finish_stmt_expr): Likewise.
+ * typeck.c (build_unary_op): Likewise.
+ (check_return_expr): Likewise.
+
+1999-10-04 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_vec_delete_1): Fold COND_EXPRs.
+
+1999-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (VEC_INIT_EXPR): Remove.
+ * cp-tree.h (struct stmt_tree): New type.
+ (struct saved_scope): Remove firstobj. Add x_saved_tree,
+ x_stmt_tree.
+ (class_cache_firstobj): Remove.
+ (struct language_function): Remove stmts_are_full_exprs_p,
+ x_last_tree, and x_last_expr_type. Add x_stmt_tree.
+ (current_stmt_tree): New macro.
+ (last_tree): Adjust.
+ (last_expr_type): Likewise.
+ (doing_semantic_analysis_p): Simplify.
+ (stmts_are_full_exprs_p): Adjust.
+ (begin_tree): Remove prototype.
+ (end_tree): Likewise.
+ (begin_stmt_tree): Change prototype.
+ (finish_stmt_tree): Likewise.
+ (building_stmt_tree): Simplify.
+ * decl.c (mark_stmt_tree): New function.
+ (mark_saved_scope): Use it.
+ (start_function): Rearrange slightly to call begin_stmt_tree
+ earlier.
+ (save_function_data): Tweak.
+ (finish_function): Adjust call to finish_stmt_tree.
+ (mark_lang_function): Use mark_stmt_tree.
+ * expr.c (cplus_expand_expr): Don't handle VEC_INIT_EXPR.
+ * init.c (build_new_1): Remove creation of VEC_INIT_EXPR.
+ (build_vec_init): Remove creation of stand-in initializer.
+ * pt.c (begin_tree): Remove.
+ (end_tree): Likewise.
+ * semantics.c (SET_LAST_STMT): New macro. Use it throughout.
+ (begin_compound_stmt): Handle a compound-statement outside of a
+ function.
+ (begin_stmt_expr): Handle a statement-expression outsidef of a
+ function.
+ (finish_stmt_expr): Likewise.
+ (begin_class_definition): Don't call begin_tree.
+ (finish_inline_definitions): Don't call end_tree.
+ (begin_stmt_tree): Take a pointer to tree, not a function as input.
+ (finish_stmt_tree): Likewise.
+ * tree.c (search_tree): Don't handle VEC_INIT_EXPR.
+ (mapcar): Likewise.
+
+ * parse.y (simple_stmt): Don't call finish_stmt unnecessarily.
+ * parse.c: Regenerated.
+
+ * dump.c (dqueue_and_dump): Dump bitfieldness.
+
+ * tree.c (lvalue_p_1): Use DECL_C_BIT_FIELD to check for
+ bitfields, rather than DECL_BIT_FIELD.
+ * ir.texi: Document how to tell whether or not a field is a
+ bitfield.
+
+ * lex.c (make_lang_type): Fix typo in comment.
+
+1999-10-01 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (decay_conversion): Strip cv-quals from non-class rvalues.
+
+1999-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_decl): If the type of a template instantiation is
+ bogus, so is the whole instantiation.
+
+1999-09-30 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (initialize_local_var): Handle static variables here.
+ (cp_finish_decl): Tweak handling of function-scope static
+ variables.
+ * semantics.c (expand_stmt): Handle DECL_STMTs for static
+ variables.
+
+ * method.c (emit_thunk): Don't crash when -fsyntax-only.
+
+ * cp-tree.h (lang_decl_flags): Add global_ctor_p and
+ global_dtor_p. Add init_priority.
+ (DECL_ACCESS): Adjust accordingly.
+ (DECL_GLOBAL_CTOR_P, DECL_GLOBAL_DTOR_P): New macros.
+ (GLOBAL_INIT_PRIORITY): Likewise.
+ * decl.c (lang_mark_tree): Adjust accordingly.
+ (start_objects): Set DECL_GLOBAL_CTOR_P, DECL_GLOBAL_DTOR_P,
+ and GLOBAL_INIT_PRIORITY.
+ * dump.c (dequeue_and_dump): Print them.
+ * ir.texi: Document them.
+
+ * decl2.c (struct priority_info_s): Remove initialization_sequence
+ and destruction_sequence.
+ (start_static_storage_duration_function): Return the body of the
+ function. Convert for function-at-a-time mode.
+ (generate_inits_for_priority): Remove.
+ (finish_static_storage_duration_function): Change prototype.
+ Adjust for function-at-a-time mode.
+ (do_static_initialization): Likewise.
+ (do_static_destruction): Likewise.
+ (do_static_initialization_and_destruction): Remove.
+ (start_static_initialization_or_destruction): New function.
+ (finish_static_initialization_or_destruction): Likewise.
+ (get_priority_info): Don't manipulation initialization_sequence or
+ destruction_sequence.
+ (prune_vars_needing_no_initialization): New function.
+ (write_out_vars): Likewise.
+ (finish_file): Use the various new functions instead of the old.
+
+Thu Sep 30 00:13:27 1999 Dirk Zoller <duz@rtsffm.com>
+
+ * cp-tree.h (warn_float_equal): Declare.
+ * decl2.c (warn_float_equal): Define.
+ (lang_decode_option): Recognize -W[no-]float-equal.
+ * typeck.c (build_binary_op_nodefault): Conditionally warn
+ about equality tests of floating point types.
+
+1999-09-29 Jason Merrill <jason@yorick.cygnus.com>
+
+ Support normal type_info-based EH mechanisms with -fno-rtti.
+ * except.c (build_eh_type_type): Remove special -fno-rtti handling.
+ (build_eh_type_type_ref): Likewise.
+ (build_eh_type): Remove.
+ (expand_throw): Call build_eh_type_type, not build_eh_type.
+ * decl2.c (import_export_decl): Don't associate the tinfo fn with
+ the vtable if -fno-rtti.
+ * decl.c (init_decl_processing): Always init_rtti_processing.
+
+ * rtti.c (get_typeid): Don't complain about -fno-rtti.
+
+ * class.c (class_cache_obstack, class_obstack): Remove.
+ (init_class_processing): Don't initialize class_obstack.
+ (push_cache_obstack): Remove.
+ (pushclass): Don't call it.
+ * cp-tree.h: Remove prototype for push_cache_obstack.
+ * decl.c (decl_obstack, decl_stack, push_decl_level): Remove.
+ (pushlevel_class): Don't push_decl_level.
+ (poplevel_class): Don't pop_stack_level.
+ (push_class_level_binding): Don't push_cache_obstack.
+ (init_decl_processing): Don't initialize decl_obstack.
+ * search.c (push_class_decls): Don't push_cache_obstack.
+ * tree.c (list_hash_add): Put hash node on permanent_obstack.
+ (hash_tree_cons): Don't mess with obstacks.
+ (print_lang_statistics): Don't print stats for class_obstack and
+ decl_obstack.
+
+1999-09-29 Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (dequeue_and_dump): Dump DECL_EXTERNAL.
+ * ir.texi: Document DECL_EXTERNAL.
+
+ * dump.c (dequeue_and_dump): Improve support for dumping THUNK_DECLs.
+ * ir.texi: Document THUNK_DECLs.
+
+ * cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Move here from pt.c.
+ (TMPL_ARGS_DEPTH, TMPL_ARGS_LEVEL, SET_TMPL_ARGS_LEVEL): Likewise.
+ (TMPL_ARG, SET_TMPL_ARG, NUM_TMPL_ARGS, TMPL_PARMS_DEPTH): Likewise.
+ * error.c (dump_template_bindings): Remove unused parameter.
+ Handle multiple levels of template parameters.
+ (dump_template_decl): Use `parms', not `args', for template
+ parameters. Fix thinko.
+ (dump_function_decl): Use DECL_TEMPLATE_INSTANTIATION. Don't pass
+ flags to dump_template_bindings.
+ * pt.c (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Move to cp-tree.h.
+ (TMPL_ARGS_DEPTH, TMPL_ARGS_LEVEL, SET_TMPL_ARGS_LEVEL): Likewise.
+ (TMPL_ARG, SET_TMPL_ARG, NUM_TMPL_ARGS, TMPL_PARMS_DEPTH): Likewise.
+ (tsubst_copy): Clarify variable name.
+ (most_general_template): Robustify.
+
+1999-09-29 Nathan Sidwell <nathan@acm.org>
+
+ * error.c (dump_template_parms): Don't use TS_PEDANTIC_NAME
+ to change primary template rendering.
+
+1999-09-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (UPT_TEMPLATE): Remove.
+ (UPT_PARMS): Likewise.
+ (DECL_NEEDED_P): New macro.
+ * decl2.c (finish_vtable_vardecl): Use it.
+ (finish_objects): Don't crash with -fsyntax-only.
+ (finish_file): Use DECL_NEEDED_P. Don't prune vtables when
+ -fsyntax-only.
+ * pt.c (tsubst_friend_function): Remove FIXME that talks about
+ obstacks.
+ (tsubst_expr): Correct handling of function try-blocks.
+ * semantics.c: Include flags.h.
+ (expand_body): Don't do RTL generation if -fsyntax-only.
+ * Makefile.in (semantics.o): Depends on flags.h.
+
+1999-09-28 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * pt.c (most_general_template): Adjust declaration.
+
+ * cp-tree.h: (most_general_template): Declare.
+
+ * error.c (dump_template_value): Rename to ...
+ (dump_template_argument): This.
+ (dump_template_argument_list): New function.
+ (dump_type): Use it.
+ (dump_template_parameter): New function.
+ (dump_template_decl): Use it.
+ (dump_template_bindings): New function.
+ (dump_function_decl): Use it. Pretty print function template
+ instantiations.
+
+1999-09-28 Nathan Sidwell <nathan@acm.org>
+
+ * decl.c (grokdeclarator): Distinguish parameter context for
+ diagnostics. Tidy up missing type diagnostic.
+ Diagnose `explicit' in one place. Diagnose `mutable' in one place.
+
+1999-09-28 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi: Improve documentation for TARGET_EXPR.
+
+1999-09-27 Nathan Sidwell <nathan@acm.org>
+
+ Augment stringification of trees.
+ * cp-tree.h (tree_string_flags): New error stringifying enumeration.
+ (fndecl_as_string, type_as_string_real, args_as_string,
+ code_as_string, language_as_string, parm_as_string,
+ op_as_string, assop_as_string, cv_as_string): Remove.
+ (type_as_string, decl_as_string, expr_as_string): Adjust prototype.
+ (context_as_string): Declare new function.
+ * error.c (cp_printers): Move definition.
+ (OB_UNPUT): Remove.
+ (OB_END_TEMPLATE_ID): Adjust.
+ (interesting_scope_p): Remove.
+ (dump_scope): New static function.
+ (dump_qualifiers): Adjust prototype, reimplement.
+ (dump_template_value): Use tree_string_flags.
+ (dump_type_real): Move back to dump_type.
+ (dump_type): Adjust prototype. Use tree_string_flags.
+ (dump_aggr_type): Likewise. Use dump_template_parms.
+ (dump_type_prefix): Adjust prototype. Use tree_string_flags.
+ Return pad flag.
+ (dump_type_suffix): Adjust prototype. Use tree_string_flags.
+ (dump_simple_decl): Likewise.
+ (dump_decl): Likewise. Use dump_template_decl.
+ (dump_template_decl): New static function broken out of dump_decl.
+ (dump_function_decl): Adjust prototype. Use tree_string_flags.
+ (dump_parameters): Likewise. Prefix space.
+ (dump_exception_spec): Adjust prototype. Use tree_string_flags.
+ (dump_function_name): Likewise. Use dump_template_parms.
+ (dump_template_parms): New static function broken out of
+ dump_function_name.
+ (dump_expr_list): Adjust prototype. Use tree_string_flags.
+ (dump_expr): Likewise.
+ (fndecl_as_string): Removed
+ (type_as_string_real): Removed
+ (dump_binary_op): Adjust prototype. Use tree_string_flags.
+ (dump_unary_op): Likewise.
+ (type_as_string): Likewise.
+ (expr_as_string): Likewise.
+ (decl_as_string): Likewise.
+ (context_as_string): New function.
+ (lang_decl_name): Adjust.
+ (decl_to_string): New static print callback.
+ (expr_to_string): Likewise.
+ (fndecl_to_string): Likewise.
+ (code_as_string): Renamed to ...
+ (code_to_string): ... here. Adjust.
+ (language_as_string): Renamed to ...
+ (language_to_string): ... here. Adjust.
+ (parm_as_string): Renamed to ...
+ (parm_to_string): ... here.
+ (op_as_string): Renamed to ...
+ (op_to_string): ... here.
+ (assop_as_string): Renamed to ...
+ (assop_to_string): ... here.
+ (type_to_string): New static print callback.
+ (args_as_string): Renamed to ...
+ (args_to_string): ... here. Adjust.
+ (cv_as_string): Renamed to ...
+ (cv_to_string): ... here. Adjust.
+ * pt.c (mangle_class_name_for_template): Use tree_string_flags.
+ (print_template_context): Likewise.
+
+1999-09-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (expand_throw): Remove prototype.
+ * except.c (expand_throw): Make it static. Use tree-generation
+ functions, rather than RTL-generation functions.
+ (build_throw): Use it.
+ * expr.c: Include except.h.
+ (cplus_expand_expr): Don't call expand_throw here.
+ * Makefile.in (expr.o): Depend on except.h.
+ * ir.texi: Update documentation for THROW_EXPR.
+
+ * decl.c (start_function): Set x_dont_save_pending_sizes rather
+ than calling get_pending_sizes.
+ * init.c (build_new): Don't save and restore
+ immediate_size_expand; instead, assert that it has the expected
+ value already.
+
+1999-09-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c (compiler_error): Add missing call to va_end().
+
+1999-09-25 Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (dequeue_and_dump): Handle RESULT_DECL.
+ * ir.texi: Document RESULT_DECL and DECL_RESULT.
+
+ * cp-tree.h (check_return_expr): New function.
+ * decl.c (finish_constructor_body): New function.
+ (pushdecl): Put global friend functions in namespace binding
+ level, not the class binding level.
+ (finish_destructor_body): Make sure the dtor_label is always
+ defined. Fix typo in comment.
+ (finish_function): Move generation of constructor-termination code
+ to semantic-analysis time. Move generation of implicit `main'
+ return value to semantic-analysis time.
+ * semantics.c (finish_return_stmt): Generate goto's to
+ ctor_label/dtor_label here. Use check_return_expr to do semantic
+ analysis on the returned expression.
+ * typeck.c (maybe_warn_about_returning_address_of_local): New
+ function split out from c_expand_return.
+ (check_return_expr): Likewise.
+ (c_expand_return): Just generate the RTL for the return.
+
+1999-09-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CPTI_CLEANUP_TYPE): New macro.
+ (cleanup_type): Likewise.
+ (search_tree): Change prototype.
+ * decl.c (local_variable_p): Adjust for new interface to
+ search_tree.
+ (check_default_argument): Likewise.
+ * error.c (dump_expr): Handle INIT_EXPR.
+ * except.c (expand_throw): Don't make cleanup_type a local static.
+ * expr.c (cplus_expand_expr): Don't handle NEW_EXPR.
+ * init.c (build_new): Call build_new_1 directly, rather than
+ building a NEW_EXPR.
+ (build_new_1): Tidy. Don't build a VEC_INIT_EXPR except when
+ processing file-scope initializers.
+ * lex.c (init_parse): Add an opname_tab entry for INIT_EXPR.
+ * tree.c: Include splay-tree.h
+ (no_linkage_helper): Adjust for new interface to search_tree.
+ (search_tree): Pass around pointers to tree nodes, rather than the
+ nodes themselves. Handle VEC_INIT_EXPR.
+ (no_linkage_check): Adjust for new interface to search_tree.
+ (mapcar): Handle VEC_INIT_EXPR.
+ (target_remap): New variable.
+ (bot_manip): Use it.
+ (bot_replace): New function.
+ (break_out_target_exprs): Use it to remap all variables used in a
+ default argument expression.
+ * typeck.c (build_modify_expr): Don't crash when outside a
+ function and presented with an INIT_EXPR assignment
+ * Makefile.in (tree.o): Depend on splay-tree.h.
+
+Fri Sep 24 10:48:10 1999 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * decl.c (duplicate_decls): Use DECL_BUILT_IN_CLASS rather than
+ DECL_BUILT_IN.
+ (builtin_function): New arg CLASS. Arg CODE now of type int. All
+ callers changed.
+ Set the builtin's DECL_BUILT_IN_CLASS.
+
+1999-09-24 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pushdecl): Don't make local declarations of extern
+ variables give the variable a DECL_CONTEXT for the function.
+ (make_rtl_for_nonlocal_decl): Don't fuss with obstacks. Simplify.
+ Don't accidentally make RTL for local declarations.
+ (emit_local_var): Handle declarations with asm-specifiers here.
+
+1999-09-23 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi: Improve documentation for TARGET_EXPRs. Discuss
+ STMT_IS_FULL_EXPR_P.
+
+ * cp-tree.h (language_function): Add cannot_inline.
+ * decl.c (start_function): Restore current_function_cannot_inline
+ from the saved value.
+ (save_function_data): Save current_function_cannot_inline.
+ * decl2.c (start_objects): Change prototype. Build the function
+ in function-at-a-time mode.
+ (finish_objects): Likewise.
+ (generate_ctor_or_dtor_function): Adjust accordingly.
+
+ * cp-tree.h (DECL_ANON_UNION_ELEMS): New macro.
+ * decl2.c (finish_anon_union): Set DECL_ANON_UNION_ELEMS.
+ Don't call expand_anon_union_decl here
+ * semantics.c (exapnd_stmt): Call it here, instead.
+ * typeck.c (mark_addressable): Addressed variables are implicitly
+ used.
+
+1999-09-23 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * cp-tree.h (VAR_OR_FUNCTION_DECL_CHECK): New macro.
+ (RECORD_OR_UNION_TYPE_CHECK, LANG_IDENTIFIER_CAST): Likewise.
+ (DEFARG_NODE_CHECK): Remove; replace with DEFAULT_ARG_CHECK.
+ * cp-tree.h: Add tree checking macros to various tree access
+ macros.
+ * ptree.c (print_lang_decl): Test for function or variable
+ before accessing template info.
+
+1999-09-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c: Get WCHAR_TYPE_SIZE from wchar_type_node.
+ * lang-specs.h: If -fshort-wchar, override __WCHAR_TYPE__.
+ * decl2.c (lang_f_options): Add -fshort-wchar.
+ * cp-tree.h: Declare flag_short_wchar.
+ * decl.c (init_decl_processing): If -fshort-wchar, use 'short unsigned
+ int' for wchar_t.
+
+1999-09-23 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * ir.texi: Fix formatting errors and typos.
+
+1999-09-22 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi: Document CLEANUP_STMT, SCOPE_STMT, and START_CATCH_STMT.
+
+ * decl.c (pushdecl): Do create a binding for extern "C" functions,
+ but not for their DECL_ASSEMBLER_NAMEs.
+ (lookup_name_current_level): Fix formatting.
+ (xref_tag): Likewise.
+ * decl2.c (start_objects): Mark static constructors and
+ destructors as used.
+
+1999-09-22 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (define_case_label): Don't crash if we're not in a switch.
+
+ * decl2.c (lang_decode_option): Don't bother explicitly ignoring flags.
+ * lang-options.h: Restore -fthis-is-variable. Remove help strings
+ for unsupported flags.
+
+1999-09-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (lang_decode_option): Accept and ignore -finit-priority.
+ Accept and warn about -fthis-is-variable.
+
+1999-09-21 Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (dequeue_and_dump): Handle START_CATCH_STMT,
+ CLEANUP_STMT, and SCOPE_STMT.
+
+ * decl2.c (lang_decode_option): Adjust, in the wake of recent
+ changes to option processing.
+
+1999-09-21 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * typeck.c (get_member_function_from_ptrfunc): Allow extraction of
+ function pointer from pmfs with no object given.
+ (convert_for_assignment): Do not return error when converting
+ pmfs.
+
+1999-09-21 Alex Samuel <samuel@codesourcery.com>
+
+ * lex.c (internal_filename): New variable.
+ (INTERNAL_FILENAME): New macro.
+ (init_parse): Allocate internal_filename and mark as root. Use it
+ instead of a string constant.
+
+1999-09-21 Nathan Sidwell <nathan@acm.org>
+
+ Reimplement dynamic cast and catch matching.
+ * cp-tree.h (get_dynamic_cast_base_type): Prototype new function
+ * search.c (dynamic_cast_base_recurse): New function.
+ (get_dynamic_cast_base_type): New function for dynamic cast.
+ * rtti.c (build_dynamic_cast_1): Determine source and target
+ class relationship. Call __dynamic_cast_2.
+ * tinfo.h (__user_type_info::upcast): New catch dispatcher.
+ (__user_type_info::dyncast): New dynamic cast dispatcher.
+ (__user_type_info::sub_kind): New nested enumeration.
+ (__user_type_info::contained_p): sub_kind predicate.
+ (__user_type_info::contained_public_p): Likewise.
+ (__user_type_info::contained_nonpublic_p): Likewise.
+ (__user_type_info::contained_nonvirtual_p: Likewise.
+ (__user_type_info::upcast_result): New nested struct.
+ (__user_type_info::dyncast_result): New nested struct.
+ (*::do_upcast): New catch function.
+ (*::do_dyncast): New dynamic cast function.
+ (__user_type_info::find_public_subobj): New dynamic cast
+ helper dispatcher.
+ (*::do_find_public_subobj): New dynamic cast helper function.
+ * tinfo.cc (__user_type_info::upcast): Define catch dispatcher.
+ (__user_type_info::dyncast): Define dynamic cast dispatcher.
+ (*::do_upcast): Define catch function.
+ (*::do_dyncast): Define dynamic cast function.
+ (*::do_find_public_subobj): Define dynamic cast helper function.
+ * tinfo2.cc (__throw_type_match_rtti_2): Use upcast.
+ (__dynamic_cast): Backwards compatibility wrapper. Use dyncast.
+ (__dynamic_cast_2): New dynamic cast runtime.
+
+1999-09-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (finish_stmt_expr): Change prototype.
+ * expr.c (cplus_expand_expr): Adjust call accordingly.
+ * init.c (finish_init_stmts): Likewise.
+ * parse.y (primary): Likewise.
+ * pt.c (tsubst_copy): Likewise.
+ * semantics.c (finish_stmt_expr): Don't take two parameters.
+ Don't remove generated BLOCKs from the block-tree.
+
+ Remove support for assigning to `this'.
+ * NEWS: Note that fact.
+ * class.c (build_vbase_path): Don't check flag_this_is_variable.
+ * cp-tree.h (EXPR_STMT_ASSIGNS_THIS): Remove.
+ (language_function): Remove assigns_this, just_assigned_this, and
+ x_base_init_expr. Add x_vcalls_possible_p. Add vtbls_set_up_p.
+ (base_init_expr): Remove.
+ (current_vcalls_possible_p): New macro.
+ (vtbls_set_up_p): Likewise.
+ (emit_base_init): Change prototype.
+ * decl.c (finish_destructor_body): New function, split out from
+ finish_function.
+ (current_function_assigns_this): Remove.
+ (current_function_just_assigned_this): Likewise.
+ (start_function): Don't set them.
+ (finish_function): Don't check them. Don't emit
+ base-initialization code here. Generate code for destructors when
+ doing semantic analysis.
+ (finish_stmt): Don't check current_function_just_assigned_this.
+ * decl2.c (lang_f_options): Remove this-is-variable.
+ (lang_decode_option): Likewise.
+ (grokclassfn): Don't check flag_this_is_variable.
+ * init.c (emit_base_init): Return the expression generated.
+ (construct_virtual_bases): Don't push/pop obstacks. Fix
+ typo.
+ (build_new_1): Don't check flag_this_is_variable.
+ (get_temp_regvar): Don't set DECL_REGISTER.
+ (build_vec_init): Don't call use_variable.
+ * lang-options.h: Remove "-fthis-is-variable" and
+ "-fno-this-is-variable".
+ * pt.c (tsubst_expr): Don't check EXPR_STMT_ASSIGNS_THIS.
+ * search.c (expand_upcast_fixups): Use finish_expr_stmt, not
+ expand_expr_stmt.
+ * semantics.c (finish_expr_stmt_real): Rename to ...
+ (finish_expr_stmt): This. Remove assigned_this parameter.
+ (begin_if_stmt): Call do_pushlevel before starting the statement.
+ (begin_compound_stmt): Don't declare __FUNCTION__ in scope-less
+ blocks.
+ (setup_vtbl_ptr): Emit initialization code for bases and members
+ at semantic-analysis time. Emit code to initialize vtables in
+ destructors here.
+ (expand_stmt): Use finish_expr_stmt, not finish_expr_stmt_real.
+ Don't handle CTOR_INITIALIZER any more.
+ * typeck.c (build_modify_expr): Don't check for assignments to
+ this.
+ (c_expand_return): Don't suggest assigning to `this'.
+
+ * Makefile.in (decl.o): Depend on RTL_H.
+ (decl2.o): Likewise.
+ (class.o): Likewise.
+ (call.o): Likewise.
+ (method.o): Likewise.
+ (search.o): Likewise.
+ (tree.o): Likewise.
+ (pt.o): Likewise.
+
+ * decl.c (duplicate_decls): When a builtin function is redeclared
+ as static, make sure it is mangled correctly.
+
+ * ir.texi (CTOR_INITIALIZER): Remove mention. Fix typo. Add
+ detail about the statement-tree.
+
+1999-09-20 Nathan Sidwell <nathan@acm.org>
+
+ * parse.y (primary): Use build_functional_cast for CV_QUALIFIER.
+
+1999-09-20 Nick Clifton <nickc@cygnus.com>
+
+ * decl2.c (lang_decode_option): Extend comment.
+
+Mon Sep 20 10:49:05 1999 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * typeck.c: Include "tm_p.h".
+
+1999-09-19 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi: New file.
+
+1999-09-19 Paul Burchard <burchard@pobox.com>
+
+ * semantics.c (expand_stmt): Initialize return value.
+
+1999-09-18 Paul Burchard <burchard@pobox.com>
+
+ * gxxint.texi: G++ now implements namespaces.
+
+1999-09-18 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pop_label): Don't warn about unused labels more than
+ once.
+ * semantics.c (finish_goto_stmt): Always marked used labels as
+ used.
+
+ * decl.c (layout_var_decl): Change prototype. Call layout_decl
+ even when the declaration is external.
+ (cp_finish_decl): Adjust call to layout_var_decl.
+ * pt.c (tsubst_expr): Make sure to initialize stmt before using it.
+
+1999-09-18 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * typeck.c (get_member_function_from_ptrfunc): Always consider
+ virtuality inside member pointer.
+
+1999-09-17 Mark Mitchell <mark@codesourcery.com>
+
+ Turn on function-at-a-time processing.
+ * cp-tree.h (doing_semantic_analysis_p): New macro.
+ (SF_DEFAULT): Define to zero, not SF_EXPAND.
+ (start_handler_parms): Change prototype.
+ (expand_start_catch_block): Likewise.
+ (expand_end_catch_block): Likewise.
+ (expand_start_eh_spec): Likewise.
+ (expand_end_eh_spec): Declare.
+ (finish_handler_parms): Change prototype.
+ (begin_catch_block): Declare.
+ (finish_handler): Change prototype.
+ (do_pushlevel): Declare.
+ (do_poplevel): Likewise.
+ * decl.c (pushlevel): Don't create
+ binding levels when not doing semantic analysis.
+ (poplevel): Don't pop them.
+ (pushdecl): Assert that we are never called when not doing
+ semantic analysis.
+ (pushdecl_top_level): Use push_to_top_level.
+ (make_label_decl): Don't fiddle with obstacks. Make RTL For the
+ label when expanding.
+ (cp_finish_decl): Only inject for-scope variables when doing
+ semantic analysis. Add comments.
+ (start_handler_parms): Return the handler parm.
+ (start_function): Reorganize. Don't clear DECL_INITIAL if it is
+ already set. Reinitialize from saved function data if available.
+ Don't pushlevel when not doing semantic analysis.
+ (store_parm_decls): Only generate RTL when expanding. Only
+ pushdecl when doing semantic analysis. Set
+ current_eh_spec_try_block if appropriate.
+ (finish_function): Simplify. Use do_pushlevel and do_poplevel.
+ Combine common code. Don't poplevel when not doing semantic
+ analysis.
+ (push_cp_function_context): Don't expand functions without an
+ explicit call to expand_body.
+ (mark_lang_function): Make eh_spec_try_block and
+ x_scope_stmt_stack.
+ * except.c (expand_end_eh_spec): Don't
+ declare.
+ (process_start_catch_block): Likewise.
+ (push_eh_cleanup): Use finish_decl_cleanup.
+ (initialize_handler_parm): New function.
+ (expand_start_catch_block): Use it.
+ (expand_end_catch_block): Use tree-generation functions, not
+ RTL-generation functions.
+ (expand_start_eh_spec): Likewise.
+ (expand_end_eh_spec): Likewise.
+ (expand_exception_blocks): Simplify.
+ (start_anon_func): Use do_pushlevel.
+ (end_anon_func): Use do_poplvel. Call expand_body for the
+ function.
+ * expr.c (do_case): Don't call define_case_label.
+ * init.c (create_temporary_var): Set DECL_CONTEXT for local
+ variables.
+ * method.c (emit_thunk): Call expand_body for the
+ thunk.
+ (sythesize_method): Likewise.
+ * parse.y (handler_args): Give it ttype.
+ (eat_saved_input): Call expand_body.
+ (base_init): Use do_pushlevel.
+ (pending_inline): Call expand_body.
+ (handler): Adjust calls to finish_handler_parms and
+ finish_handler.
+ (handler_args): Don't call expand_start_catch_block. Return the
+ catch parameter. * pt.c (tsubst_expr): Adjust HANDLER handling.
+ * parse.c: Regenerated.
+ * rtti.c (synthesize_tinfo_fn): Call finish_function.
+ * semantics.c (do_pushlevel): Give it external linkage. Build
+ SCOPE_STMTs.
+ (do_poplevel): Likewise.
+ (finish_case_label): Call define_case_label when doing semantic
+ analysis.
+ (finish_goto_stmt): Create RTL for labels.
+ (finish_function_try_block): Set in_function_try_handler
+ unconditionally.
+ (finish_function_handler_sequence): Unset it.
+ (finish_handler_parms): Use expand_start_catch_block even when
+ building a statement-tree.
+ (begin_catch_block): New function.
+ (finish_handler): Move a little RTL-generation logic here.
+ (finish_decl_cleanup): Allow cleanups for empty declarations.
+ (finish_named_return_value): Don't pushdecl when not doing
+ semantic analysis.
+ (expand_stmt): Don't do semantic analysis for variable
+ declarations. Handle START_CATCH_STMT. Call expand_label
+ directly for a LABEL_STMT. Tweak handling of GOTO_STMT. Adjust
+ HANDLERs. Handle SCOPE_STMT, CTOR_INITIALIZER, and RETURN_INIT.
+ (expand_body): Let expand_stmt handle CTOR_INITIALIZER,
+ RETURN_INIT and function try blocks.
+
+ * cp-tree.h (language_function): Add x_eh_spec_try_block. Add
+ x_scope_stmt_stack. Add x_in_charge_parm.
+ (current_eh_spec_try_block): New macro.
+ (current_scope_stmt_stack): Likewise.
+ (current_in_charge_parm): Likewise.
+ * decl.c (start_function): Initialize current_in_charge_parm.
+ (finish_function): Use current_in_charge_parm rather than looking
+ up __in_chrg.
+ * search.c (expand_indirect_vtbls_init): Likewise.
+
+ * cp-tree.def (CLEANUP_STMT): Fix spelling in dumps.
+ (TRY_BLOCK): Likewise.
+ (HANDLER): Likewise.
+ (START_CATCH_STMT): New tree node.
+ (SCOPE_STMT): Likewise.
+ * cp-tree.h (SCOPE_BEGIN_P): New macro.
+ (SCOPE_NULLIFIED_P): Likewise.
+ (struct lang_decl_flags): Add pending_inline_p. Adjust dummy.
+ (struct lang_decl): Add saved_language_function.
+ (DECL_PENDING_INLINE_INFO): Adjust documentation.
+ (DECL_PENDING_INLINE_P): New macro.
+ (TYPE_TI_ARGS): Fix typo in comment.
+ (DECL_SAVED_TREE): Add to documentation.
+ (DECL_SAVED_FUNCTION_DATA): New macro.
+ (START_CATCH_TYPE): Likewise.
+ (SCOPE_END_P): New macro.
+ (declare_parm_level): Don't declare.
+ * decl.c (mark_lang_function): New function, split out from
+ mark_cp_function_context.
+ (save_function_data): New function.
+ (declare_parm_level): Remove.
+ (finish_function): Use save_function_data to squirrel away
+ important stuff for later use.
+ (mark_cp_function_context): Use mark_function_data.
+ (lang_mark_tree): Likewise.
+ * lex.c (begin_definition_of_inclass_inline): Set
+ DECL_PENDING_INLINE_P.
+ (store_pending_inline): Clear it.
+ * pt.c (tsubst_decl): Likewise.
+
+1999-09-17 Nathan Sidwell <nathan@acm.org>
+
+ * call.c (perform_implicit_conversion): Deal with error_mark_node.
+
+1999-09-17 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (warn_extern_redeclared_static): Don't get confused by
+ static member functions.
+ (duplicate_decls): Merge DECL_THIS_STATIC.
+
+ * decl.c (expand_static_init): Make sure assignments to local
+ statics actually occur.
+
+1999-09-17 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (poplevel_class): Declare.
+ * class.c (popclass): Use poplevel_class, not poplevel.
+ * decl.c (poplevel_class): Don't make it static. Don't return a
+ value.
+ (poplevel): Don't call poplevel_class; abort in a class
+ binding level is seen.
+ * semantics.c (finish_translation_unit): Use pop_everything.
+ * parse.y (member_init): Allow errors.
+ (pending_inline): Call finish_function.
+ * parse.c: Regenerated.
+ * Makefile.in (CONFLICTS): Adjust.
+
+1999-09-17 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c: Reduce code duplication.
+ (dump_template_value): New function.
+ (dump_type_real): Use it.
+ (dump_decl): Likewise.
+ (dump_function_name): Likewise.
+ (dump_function_decl): Don't be too talkative about function return
+ type variety.
+
+1999-09-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c (init_cpp_parse): Call xcalloc, not malloc/bzero.
+
+ * xref.c (SALLOC): Call xstrdup, not xmalloc/strcpy.
+
+1999-09-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Also call check_global_declarations for
+ the pending_statics list.
+
+1999-09-15 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (cp_pragma_implementation): Allow #pragma implementation
+ in header files.
+
+1999-09-15 Richard Henderson <rth@cygnus.com>
+
+ * lex.c (mark_impl_file_chain): Follow the next chain.
+
+1999-09-15 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (warn_extern_redeclared_static): Simplify. Catch
+ problems with extern "C" functions redeclared as static.
+ (duplicate_decls): When a builtin is redeclared static, make the
+ new function have internal linkage.
+
+1999-09-15 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (build_expr_from_tree): Handle VA_ARG_EXPR.
+ * pt.c (tsubst_copy): Likewise.
+ * tree.c (search_tree): Likewise.
+ (mapcar): Likewise.
+
+1999-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * typeck2.c (ack): Don't declare progname.
+
+1999-09-14 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+ * lex.c (cp_pragma_interface, cp_pragma_implementation): Copy
+ filenames with ggc_alloc_string.
+
+1999-09-14 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (build_target_expr): Set TREE_SIDE_EFFECTS on the
+ TARGET_EXPR.
+ * call.c (build_over_call): Don't set TREE_SIDE_EFFECTS on
+ the TARGET_EXPR.
+ * cvt.c (build_up_reference): Likewise.
+ * tree.c (build_cplus_new): Likewise.
+ (get_target_expr): Likewise.
+
+Tue Sep 14 01:45:10 1999 Marc Espie <espie@cvs.openbsd.org>
+
+ * Makefile.in: Prepend $(SHELL) to move-if-change calls.
+
+1999-09-13 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (build_target_expr): New function.
+ * call.c (build_conditional_expr): Use build_target_expr.
+ (convert_like): Likewise.
+ (build_over_call): Likewise.
+ * cvt.c (build_up_reference): Likewise.
+ * decl.c (build_cleanup_on_safe_obstack): Fold into ...
+ (destroy_local_var): Here.
+ (build_target_expr): New function.
+ * tree.c (build_cplus_new): Use it.
+ (get_target_expr): Likewise.
+
+1999-09-13 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (expr_sizeof): Don't decay arrays and functions.
+ Remove misleading comment.
+ (build_compound_expr): Don't decay arrays.
+
+1999-09-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_conditional_expr): Always use a TARGET_EXPR for
+ class rvalues again.
+
+Sun Sep 12 23:29:07 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (g++spec.o): Depend on system.h and gcc.h.
+
+ * g++spec.c: Include gcc.h.
+ (lang_specific_driver): Constify a char*. Call xcalloc, not
+ xmalloc/bzero. All calls to the function pointer parameter now
+ explicitly call `fatal'.
+
+1999-09-12 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (implicit_conversion): Robustify. Handle OFFSET_REFs.
+ * cvt.c (ocp_convert): Complete the from and destination types.
+ Adjust warning about functions always being `true' in conditionals.
+ * decl.c (duplicate_decls): Don't play funny games with abort.
+ * error.c (dump_expr): Handle OVERLOADs.
+ * spew.c (probe_obstack): Remove.
+ * typeck.c (condition_conversion): Use perform_implicit_conversion.
+
+1999-09-12 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * cp-tree.h (auto_function, define_function): Adjust prototypes.
+ * decl.c (define_function): Lose FUNCTION_CODE arg. All callers
+ changed.
+ (auto_function): Likewise, for CODE arg.
+ Move code to set DECL_BUILT_IN and DECL_FUNCTION_CODE to...
+ (builtin_function): ... here.
+
+1999-09-11 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (add_decl_to_level): Remove TREE_PERMANENT assertion.
+ (init_decl_processing): Don't set TREE_PERMANENT for the
+ error_mark_node.
+ (start_decl): Don't rebuild non-permanent ARRAY_TYPEs.
+ (grokdeclarator): Likewise.
+ (grokparms): Don't check TREE_PERMANENT when building up lists.
+ * decl2.c (grokfield): Don't assert TREE_PERMANENT.
+ (mark_inline_for_output): Likewise.
+ * expr.c (cplus_expand_expr): Don't check TREE_PERMANENT.
+ * init.c (build_offset_ref): Don't check TREE_PERMANENT.
+ * lex.c (check_newline): Don't check ggc_p; it is always one.
+ * pt.c (process_template_parm): Don't check TREE_PERMANENT.
+ * spew.c (yylex): Don't copy_node or probe_obstacks for
+ non-permanent CONSTANTs and STRINGs.
+ * tree.c (build_cplus_array_type_1): Don't fuss with
+ TREE_PERMANENT on ARRAY_TYPEs.
+
+ * cp-tree.def (CLEANUP_STMT): New node.
+ * cp-tree.h (language_function): Add name_declared.
+ (current_function_name_declared): New macro.
+ (CLEANUP_DECL): New macro.
+ (CLEANUP_EXPR): Likewise.
+ (emit_local_var): Likewise.
+ (finish_decl_cleanup): New function.
+ * cvt.c (build_up_reference): Simplify.
+ (ocp_convert): Remove dead code.
+ * decl.c (start_decl): Remove call to add_decl_stmt.
+ (grok_reference_init): Adjust, to handle bindings temporaries to
+ references. Remove dead code.
+ (initialize_local_var): Don't generate RTL for
+ declarations here, or build cleanups here. Don't fuss with
+ obstacks. Replace expand_start_target_temps calls with explicit
+ setting of stms_are_full_exprs_p.
+ (destroy_local_var): New function.
+ (emit_local_var): Likewise.
+ (cp_finish_decl): Use them, as appropriate.
+ (start_function): Announce template functions.
+ (store_parm_decls): Don't call declare_function_name here.
+ (finish_stmt): Don't start emit base-initialization code when just
+ building the statement-tree.
+ * init.c (create_temporary_var): Move add_decl_stmt call ...
+ (get_temp_regvar): Here.
+ * pt.c (tsubst_expr): Make DECL_INITIAL look like what
+ cp_finish_decl would expect. Don't call add_decl_stmt.
+ * semantics.c (begin_compound_stmt): Call declare_function_name,
+ if appropriate.
+ (finish_decl_cleanup): New function.
+ (expand_stmt): Use emit_local_var to output variables.
+ (expand_body): Set current_function_name_declared.
+
+1999-09-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (finish_cleanup_try_block): New function.
+ * semantics.c (finish_cleanup_try_block): Add comment.
+
+Fri Sep 10 10:32:32 1999 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * cp-tree.h: Delete declarations for all tree nodes now moved to
+ global_trees.
+ * decl.c: Delete their definitions.
+ (SHORT_TYPE_SIZE, INT_TYPE_SIZE, LONG_TYPE_SIZE, LONG_LONG_TYPE_SIZE,
+ FLOAT_TYPE_SIZE, DOUBLE_TYPE_SIZE, LONG_DOUBLE_TYPE_SIZE): Don't
+ provide defaults.
+ (init_decl_processing): Call build_common_tree_nodes and
+ build_common_tree_nodes_2 instead of building their nodes here.
+ Don't add gc roots for them.
+
+1999-09-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (language_function): Rename expanding_p to
+ x_expanding_p. Rename named_label_uses to x_named_label_uses.
+ (expanding_p): Adjust accordingly.
+ (TREE_VIA_PRIVATE): Fix typo in comment.
+ (DECL_REFERENCE_SLOT): Remove.
+ (SET_DECL_REFERENCE_SLOT): Likewise.
+ * decl.c (named_label_uses): Adjust. Remove chicken comment.
+ (push_overloaded_decl): Don't truncate the chain of bindings when
+ adding an overloaded function.
+ (grok_reference_init): Don't use DECL_REFERENCE_SLOT.
+ (initialize_local_var): Fix typo in comment.
+ (store_parm_decls): Don't set DECL_REFERENCE_SLOT. Tidy up.
+ * decl2.c (start_objects): Make the fact that we are expanding
+ the generated function right away explicit.
+ (start_static_storage_duration_function): Likewise.
+ (finish_file): Fix typo in comment.
+ * init.c (build_vec_init): Correct bugs in handling cleanups.
+ * semantics.c (maybe_convert_cond): New function.
+ (FINISH_COND): Always store the condition, even if there's
+ a declaration.
+ (finish_if_stmt_cond): Use maybe_convert_cond.
+ (finish_while_stmt_cond): Likewise.
+ (finish_do_stmt): Likewise.
+ (finish_for_cond): Likewise.
+ (expand_cond): Adjust.
+
+ * cp-tree.h (FN_TRY_BLOCK_P): New macro.
+ * init.c (perform_member_init): Remove obstack machinations.
+ (expand_cleanup_for_base): Likewise.
+ (finish_init_stmts): Mark the statement-expression as used.
+ * method.c (emit_thunk): Use tree-generating functions, not
+ RTL.
+ (do_build_copy_constructor): Likewise.
+ (do_build_assign_ref): Likewise.
+ (synthesize_method): Likewise. Keep track of line numbers.
+ * pt.c (tsubst_expr): Handle various kinds of try blocks.
+ * semantics.c (expand_stmts): Remove.
+ (begin_function_try_block): Set FN_TRY_BLOCK_P.
+ (finish_function_try_block): Be careful rechaining
+ function try blocks.
+ (expand_stmt): Loop through all the statements at a given level.
+ (exapnd_body): Be careful with line-numbers here too. Prepare for
+ being called directly from the parser.
+
+ * cp-tree.h (finish_function): Adjust prototype.
+ * decl.c (finish_function): Return the function compiled.
+ * pt.c (instantiate_decl): Don't play games with obstacks.
+ * tree.c (mapcar): Handle OFFSET_REF and BIT_FIELD_REF.
+ (search_tree): Likewise.
+ * typeck.c: Fix typo in comment.
+ * typeck2.c (store_init_value): Add comment.
+
+ * cp-tree.h (CPTI_ATEXIT): New macro.
+ (atexit_node): Likewise.
+ * decl.c (destroy_local_static): New function, broken out from ...
+ (expand_static_init): Here.
+
+ * rtti.c (get_tinfo_var): These should always be global
+ (expand_si_desc): Use tree, not RTL, functions to generate code.
+ (expand_class_desc): Likewise.
+ (expand_ptr_desc): Likewise.
+ (expand_attr_desc): Likewise.
+ (expand_generic_desc): Likewise.
+ (synthesize_tinfo_fn): Likewise.
+
+1999-09-09 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (RECHAIN_STMTS): Remove `last' parameter.
+ (RECHAIN_STMTS_FROM_LAST): Remove. Replace all uses with
+ RECHAIN_STMTS.
+ (RECHAIN_STMST_FROM_CHAIN): Likewise.
+
+ * parse.y (simple_stmt): Fix typo in last change.
+
+ * cp-tree.h (EXPR_STMT_ASSIGNS_THIS): New macro.
+ (STMT_IS_FULL_EXPR_P): Likewise.
+ (STMT_LINENO_FOR_FN_P): Likewise.
+ (prep_stmt): New function.
+ (building_stmt_tree): Tweak for safety.
+ * pt.c (tsubst_expr): Use prep_stmt throughout.
+ (add_tree): Move it to semantics.c
+ * semantics.c (add_tree): Move it here.
+ (finish_expr_stmt_real): New function.
+ (finish_expr_stmt): Use it.
+ (finish_if_stmt_cond): Use FINISH_COND.
+ (finish_while_stmt_cond): Likewise.
+ (finish_for_cond): Likewise.
+ (finish_stmt_tree): Tweak line-number handling.
+ (prep_stmt): New function.
+ (expand_stmt): Use it.
+
+ * cp-tree.h (begin_switch_stmt): Adjust prototype.
+ (finish_switch_cond): Likewise.
+ * parse.y (simple_stmt): Adjust accordingly.
+ * parse.c: Regenerated.
+ * pt.c (tsubst_expr): Adjust accordingly.
+ * semantics.c (expand_cond): New function.
+ (FINISH_COND): New macro.
+ (begin_switch_stmt): Build the SWITCH_STMT here.
+ (finish_switch_stmt_cond): Not here.
+ (expand_stmt): Adjust calls to begin_switch_stmt and
+ finish_switch_cond. Use expand_cond throughout.
+
+ * dump.c (dequeue_and_dump): Dump types for constants.
+ Describe DECL_ARG_TYPE more intuitively.
+ Handle ARRAY_REF.
+
+ * decl.c (lang_mark_tree): Mark TYPE_LANG_SPECIFIC.
+ (lang_cleanup_tree): Remove.
+ * lex.c (make_lang_type): Use ggc_alloc to allocate
+ TYPE_LANG_SPECIFIC.
+
+ Reorganize per-function data.
+ * cp-tree.h (saved_scope): Add function_decl, bindings.
+ (language_function): Rename binding_level to bindings.
+ (cp_function_chain): Use the current_function, not the
+ outer_function_chain.
+ (current_class_ptr): Make it work, even when there's no
+ current function.
+ (current_class_ref): Likewise.
+ (SF_DEFAULT, SF_PRE_PARSED, SF_INCLASS_INLINE, SF_EXPAND): New
+ macros.
+ (clear_temp_name): Remove.
+ * decl.c (check_function_type): New function, broken out from
+ start_function.
+ (current_binding_level): Adjust definition.
+ (pushlevel): Simplify.
+ (poplevel): Don't use named_label_uses when we're outside
+ a function scope.
+ (mark_saved_scope): Mark function_decl and bindings.
+ (maybe_push_to_top_level): Don't unconditionally push a new
+ function context. Save bindings and the current_function_decl.
+ Don't clear named_labels.
+ (pop_from_top_level): Pop function context if appropriate.
+ (init_decl_processing): Set init_lang_status and free_lang_status,
+ rather than save_lang_status and restore_lang_status.
+ (start_function): Take SF_* flags. Don't clear per-function data.
+ Reorder and simplify to use new per-function data code. Add
+ asserts.
+ (store_parm_decls): Don't call init_function_start here.
+ (finish_function): Adjust for new handling of per-function data.
+ (push_cp_function_context): Simplify.
+ (mark_cp_function_context): Change binding_level to bindings.
+ * decl2.c (clear_temp_name): Remove.
+ (start_objects): Use SF flags to start_function.
+ (start_static_storage_duration_function): Likewise.
+ * except.c (start_anon_func): Remove redundant calls to
+ push_function_context_to. Use SF flags to start function.
+ (end_anon_func): Remove redundant call to pop_function_context
+ from.
+ * lex.c (reinit_parse_for_function): Don't initialize per-function
+ data.
+ * method.c (emit_thunk): Clear current_function after calling
+ assemble_end_function. Use SF flags for start_function.
+ (synthesize_method): Use SF flags for start_function.
+ * parse.c: Regenerated.
+ * parse.y (fn.defpen): Likewise.
+ (pending_inline): Clear current_function, even if something goes
+ wrong.
+ * pt.c (instantiate_decl): Use SF flags to start_function.
+ Don't save and restore expanding_p.
+ (add_tree): Handle the case where we are outside any function.
+ (end_tree): Likewise.
+ * rtti.c (sythesize_tinfo_fn): Use SF flags to start_function.
+ * semantics.c (begin_function_definition): Likewise.
+ (expand_body): Likewise.
+
+1999-09-09 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (convert_to_void): Prototype new function.
+ (require_complete_type_in_void): Remove prototype.
+ * cvt.c (convert_to_void): New function.
+ (ocp_convert): Use convert_to_void.
+ * decl.c (cplus_expand_expr_stmt): Likewise, for complete
+ expressions.
+ * typeck.c (require_complete_type_in_void): Remove function.
+ (build_compound_expr): Use convert_to_void.
+ (build_static_cast): Likewise.
+ (build_c_cast): Likewise.
+ * semantics.c (finish_expr_stmt): Do not decay full expressions.
+
+ * typeck.c (build_x_compound_expr): Add FIXME.
+
+1999-09-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (scratch_tree_cons): Remove.
+ * call.c: Replace all uses of expr_tree_cons, saveable_tree_cons,
+ and perm_tree_cons with plain tree_cons.
+ * class.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * except.c: Likewise.
+ * expr.c: Likewise.
+ * init.c: Likewise.
+ * lex.c: Likewise.
+ * method.c: Likewise.
+ * parse.y: Likewise.
+ * pt.c: Likewise.
+ * repo.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * typeck.c: Likewise.
+ * parse.c: Regenerated.
+ * tree.c (build_srcloc): Simplify.
+
+1999-09-08 Bruce Korb autogen@linuxbox.com
+
+ * Makefile.in: Give the gperf user a hint about why "gperf -F" fails.
+
+1999-09-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Remove permanent_attr.
+ Remove next.
+ (LANG_DECL_PERMANENT): Remove.
+ * decl.c (duplicate_decls): Don't mess about with obstacks trying
+ to free memory.
+ (lang_mark_tree): Mark DECL_LANG_SPECIFIC.
+ * lex.c (free_lang_decl_chain): Remove.
+ (build_lang_decl): Don't use obstacks.
+ (retrofit_lang_decl): Likewise.
+ (copy_lang_decl): Likewise.
+
+ * cp-tree.h (saved_scope): Remove old_binding_level and
+ function_decl. Tidy up.
+ * decl.c (mark_saved_scope): Don't set them.
+ (maybe_push_to_top_level): Clear memory.
+
+ * decl.c (layout_var_decl): Change prototype. Don't complete
+ types for external objects.
+ (check_initializer): Likewise. Tidy.
+ (initialize_local_var): Complete types here.
+ (cp_finish_decl): Not here. Reorganize a little.
+ (grokvardecl): Don't complete types here.
+
+ * decl.c (start_function): Clear last_dtor_insn and
+ last_parm_cleanup_insn.
+ (push_cp_function_context): Just copy over a little of
+ the old context, not all of it.
+
+ * cp-tree.h (copy_to_permanent): Remove.
+ (permanent_p): Likewise.
+ * decl.c (building_typename_type): Don't use copy_to_permanent.
+ (start_decl): Likewise.
+ (grok_reference_init): Likewise.
+ (cp_finish_decl): Likewise.
+ * init.c (build_new_1): Don't use mapcar.
+ (build_vec_delete_1): Don't use copy_to_permanent.
+ (build_vec_init): Likewise.
+ * parse.y (primary): Likewise.
+ * parse.c: Regenerated.
+ * pt.c (push_template_decl_real): Don't use copy_to_permanent.
+ (lookup_template_class): Likewise.
+ (tsubst_friend_function): Likewise.
+ (instantiate_class_template): Likewise.
+ (tsubst_decl): Likewise.
+ (tsubst): Likewise.
+ (instantiate_template): Likewise.
+ (unify): Likewise.
+ * rtti.c (get_tinfo_fn): Likewise.
+ (build_dynamic_cast): Likewise.
+ * semantics.c (finish_if_stmt_cond): Likewise.
+ (finish_while_stmt_cond): Likewise.
+ (finish_do_stmt): Likewise.
+ (finish_for_cond): Likewise.
+ (finish_for_expr): Likewise.
+ (finish_cleanup): Likewise.
+ (add_decl_stmt): Likewise.
+ (finish_named_return_value): Likewise.
+ (finish_qualified_call_expr): Likewise.
+ * tree.c (perm_manip): Remove.
+ (build_exception_variant): Don't use copy_to_permanent.
+ (permanent_p): Remove.
+ (copy_to_permament): Remove.
+ (build_min_nt): Don't use copy_to_permanent.
+ (build_min): Likewise.
+ (min_tree_cons): Likewise.
+ * typeckc.c (build_static_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+
+1999-09-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (ggc_p): Set it to 1.
+ (mark_saved_scope): Add prototype.
+
+1999-09-07 Richard Henderson <rth@cygnus.com>
+
+ * cp-tree.h (C_PROMOTING_INTEGER_TYPE_P): Delete.
+ * typeck.c (self_promoting_args_p): Delete.
+
+1999-09-07 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (binfo_for_vtable): Use CLASSTYPE_VFIELD_PARENT.
+ (dfs_bfv_queue_p, dfs_bfv_helper, struct bfv_info): Remove.
+
+1999-09-07 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (tree.o): Depend on ggc.h.
+ * class.c (make_method_vec): Remove.
+ (free_method_vec): Likewise.
+ (free_method_vecs): Remove.
+ (add_method): Don't use them.
+ * cp-tree.def (PTRMEM_CST): Make it longer.
+ (TEMPLATE_PARM_INDEX): Make it shorter.
+ * cp-tree.h (BINDING_HAS_LEVEL_P): New macro.
+ (template_parm_index): Remove RTL field.
+ (ptrmem_cst): Add RTL field.
+ (finish_function): Removed parameter.
+ (process_next_inline): Change prototype.
+ (init_cplus_unsave): Rename to init_tree.
+ (binding_init): Remove.
+ * decl.c (free_binding_nodes): Remove.
+ (push_binding): Don't use them. Set BINDING_HAS_LEVEL_P.
+ (pop_binding): Don't use free_binding_nodes.
+ (free_binding_vecs): Remove.
+ (store_bindings): Don't use them.
+ (pop_from_top_level): Likewise.
+ (lookup_namespace_name): Simplify.
+ (build_typename_type): Don't use obstack_free.
+ (unqualified_namespace_lookup): Simplify.
+ (lookup_name_real): Simplify.
+ (start_function): Remove comment about leaks.
+ (finish_function): Removed nested parameter. Call
+ expand_end_bindings even when building_stmt_tree.
+ Call ggc_push_context and ggc_pop_context around
+ rest_of_compilation, if necessary.
+ (mark_cp_function_context): Handle a NULL language-context.
+ (lang_mark_false_label_stack): Fix typo.
+ (lang_mark_tree): Handle CPLUS_BINDING, OVERLOAD,
+ TEMPLATE_PARM_INDEX. Handle the funny TYPE_LANG_SPECIFIC on
+ pointer to method types.
+ (lang_cleanup_tree): Use free to free TYPE_LANG_SPECIFIC.
+ * decl2.c (finish_objects): Adjust call to finish_function.
+ (finish_static_store_duration_function): Likewise.
+ (do_nonmember_using_decl): Remove call to binding_init.
+ * except.c (end_anon_func): Adjust call to finish_function.
+ * lex.c (mark_impl_file_chain): New function.
+ (init_parse): Call init_tree, not init_cplus_unsave.
+ Add GC roots.
+ (cp_pramga_interface): Use xmalloc, not permalloc.
+ (cp_pragma_implementation): Likewise.
+ (begin_definition_of_inclass_inline): Simplify.
+ (process_next_inline): Adjust prototype.
+ (do_scoped_id): Don't call binding_init.
+ (make_lang_type): Allocate TYPE_LANG_SPECIFIC with xmalloc.
+ * method.c (emit_thunk): Adjust call to finish_function.
+ (synthesize_method): Likewise.
+ * parse.y (%union): Add a new `pi' variant.
+ (PRE_PARSED_FUNCTION_DECL): Use it.
+ (fn.defpen): Likewise.
+ (fndef): Adjust call to finish_function.
+ * pt.c (instantiate_decl): Likewise.
+ * rtti.c (syntheisze_tinfo_fn): Likewise.
+ * semantics.c (expand_body): Likewise.
+ * tree.c: Include ggc.h.
+ (mark_list_hash): New function.
+ (binding_init): Remove.
+ (init_cplus_unsave): Rename to ...
+ (init_tree): This. Add GC roots.
+
+1999-09-05 Mark Mitchell <mark@codesourcery.com>
+
+ Get ready for garbage collection.
+ * Makefile.in (CXX_TREE_H): Add varray.h
+ (lex.o): Depend on ggc.h.
+ (decl.o): Likewise.
+ (decl2.o): Likewise.
+ (method.o): Likewise.
+ (search.o): Likewise.
+ (pt.o): Likewise.
+ (repo.o): Likewise.
+ * class.c: Include ggc.h.
+ (current_class_name): Remove.
+ (current_class_type): Likewise.
+ (current_access_specifier): Likewise.
+ (previous_class_type): Likewise.
+ (previous_class_values): Likewise.
+ (class_cache_firstobj): Likewise.
+ (current_lang_base): Likewise.
+ (current_lang_stack): Likewise.
+ (current_lang_stacksize): Likewise.
+ (lang_name_c): Likewise.
+ (lang_name_cplusplus): Likewise.
+ (lang_name_java): Likewise.
+ (current_lang_name): Likewise.
+ (base_layout_decl): Likewise.
+ (access_default_node): Likewise.
+ (access_public_node): Likewise.
+ (access_protected_node): Likewise.
+ (access_private_node): Likewise.
+ (access_default_virtual_node): Likewise.
+ (access_public_virtual_node): Likewise.
+ (access_protected_virtual_node): Likewise.
+ (access_private_virtual_node): Likewise.
+ (signed_zero_node): Likewise.
+ (init_class_processing): Don't build base_layout_decl.
+ (push_lang_context): Adjust now that current_lang_base is a varray.
+ (pop_lang_context): Likewise.
+ * cp-tree.h: Include varray.h.
+ (cp_global_trees): Add access_default, access_public,
+ access_protected, access_private, access_default_virtual,
+ access_public_virtual, access_protected_virtual,
+ access_private_virtual, ctor_identifier, delta2_identifier,
+ delta_identifier, dtor_identifier, in_charge_identifier,
+ index_identifier, nelts_identifier, this_identifier,
+ pfn_identifier, pfn_or_delta2_identifier, vptr_identifier,
+ lang_name_c, lang_name_cplusplus, lang_name_java,
+ empty_except_spec, null, jclass, minus_one, terminate.
+ (saved_scope): Move here from decl.c. Define globals in terms of
+ saved_scope: current_namespace, current_class_name,
+ current_class_type, current_access_specifier, current_lang_stack,
+ current_lang_base, current_lang_name, current_function_parms,
+ current_template_parms, processing_template_decl,
+ processing_specialization, processing_explicit_instantiation,
+ previous_class_type, previous_class_values, class_cache_firstobj.
+ (scope_chain): New variable.
+ (init_pt): New function.
+ * decl.c (current_namespace): Remove.
+ (this_identifier, in_charge_identifier, ctor_identifier): Likewise.
+ (dtor_identifier, pfn_identifier, index_identifier): Likewise.
+ (delta_identifier, delta2_identifier): Likewise.
+ (pfn_or_delta2_identifier, tag_identifier): Likewise
+ (vt_off_identifier, empty_except_spec, null_node): Likewise.
+ (current_function_parms, current_lang_base): Remove.
+ (current_lang_stack, previous_class_values): Remove.
+ (class_binding_level): Macroize.
+ (saved_scope): Remove.
+ (current_saved_scope): Rename to scope_chain.
+ (mark_saved_scope): Adjust for new scope structure.
+ (maybe_push_to_top_level): Likewise.
+ (pop_from_top_level): Likewise.
+ (duplicate_decls): Adjust now that current_lang_base is a varray.
+ (build_typename_type): Call ggc_add_tree_hash_table_root.
+ (init_decl_processing): Call init_pt. Call push_to_top_level to
+ set up globals. Add GC roots.
+ (xref_basetypes): Adjust now that current_lang_base is a varray.
+ * decl.h (this_identifier): Remove.
+ (in_charge_identifier): Likewise.
+ * decl2.c: Don't include varray.h.
+ (current_namespace): Remove.
+ (init_decl2): Add GC roots.
+ * except.c (Terminate): Remove.
+ (init_exception_processing): Use terminate_node instead.
+ (build_terminate_handler): Likewise.
+ * init.c (nc_nelts_field_id): Remove.
+ (minus_one): Likewise.
+ (init_init_processing): Use minus_one_node and nelts_identifier
+ instead. Add GC roots.
+ (jclass_node): Remove.
+ (build_new_1): Use nelts_identifier.
+ (build_vec_init): Likewise.
+ (build_vec_delete): Likewise.
+ * lex.c: Include ggc.h.
+ (defarg_fn): Move declaration early.
+ (defarg_parms): Likewise.
+ (init_parse): Add GC roots.
+ (handle_cp_pragma): Remove redundant declaration of
+ pending_vtables.
+ * method.c: Include ggc.h.
+ (btypelist): Make it a varray. All uses changed.
+ (ktypelist): Likewise.
+ (init_method): Add GC roots.
+ * pt.c: Don't include varray.h. Include ggc.h.
+ (current_template_parms): Remove.
+ (processing_template_decl): Likewise.
+ (processing_specialization): Likewise.
+ (processing_explicit_instantiation): Likewise.
+ (init_pt): New function.
+ * repo.c: Include ggc.h.
+ (init_repo): Add GC roots.
+ * search.c: Don't include varray.h.
+ (_vptr_name): Remove.
+ (lookup_field_1): Use vtpr_identifier instead.
+ (expand_indirect_vtbls_init): Remove redundant declaration of
+ in_charge_identifier.
+ (init_search_processing): Use vptr_identifier.
+
+1999-09-05 Richard Henderson <rth@cygnus.com>
+ Bernd Schmidt <bernds@cygnus.co.uk>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (parse.o): Depend on ggc.h.
+ (decl2.o): Depend on ggc.h.
+ (init.o): Depend on ggc.h.
+ * cp-tree.h (init_decl2): Declare.
+ (cp_parse_init): Likewise.
+ * decl.c (ggc_p): Define to zero.
+ (mark_saved_scope): New function.
+ (init_decl_processing): Call cp_parse_init, and cp_decl2.
+ Register GC roots.
+ (expand_static_init): Add GC roots.
+ * decl2.c: Include ggc.h.
+ (init_decl2): New function.
+ * init.c: Include ggc.h.
+ (init_init_processing): Add GC roots.
+ * parse.y: Include ggc.h.
+ (cp_parse_init): New function.
+
+1999-09-04 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (init_decl_processing): Set mark_lang_status.
+ (lang_mark_false_label_stack): Adjust prototype.
+ * decl2.c (grok_function_init): Remove extraneous declaration of
+ abort_fndecl.
+
+ * Make-lang.in (cc1plus): Remove dependency on GGC.
+ * Makefile.in (OBJS): Don't mention ggc-simple.o.
+ (OBJDEPS): Don't mention ggc-simple.o.
+
+ * Make-lang.in (cc1plus): Depend on $(GGC).
+ * Makefile.in (OBJS): Add ggc-simple.o.
+ (OBJDEPS): Likewise.
+ * cp-tree.h (language_function): Rename members to `x_' versions;
+ we now have x_named_labels, x_ctor_label, x_dtor_label,
+ x_base_init_list, x_member_init_list, x_base_init_expr,
+ x_current_class_ptr, x_current_class_ref, x_last_tree,
+ x_last_expr_type, x_last_dtor_insn, x_last_parm_cleanup_insn, and
+ x_result_rtx.
+ (dtor_label, ctor_label, current_base_init_list,
+ current_member_init_list, base_init_expr, current_class_ptr,
+ current_class_ref, last_tree, last_expr_type): Adjust accordingly.
+ * decl.c: Include ggc.h.
+ (last_dtor_insn): Adjust to use x_ names.
+ (last_parm_cleanup_insn): Likewise.
+ (original_result_rtx): Likewise.
+ (named_labels): Likewise.
+ (mark_binding_level): New function.
+ (mark_cp_function_context): Likewise.
+ (mark_false_label_stack): Likewise.
+ (lang_mark_tree): Likewise.
+ (lang_cleanup_tree): Likewise.
+
+1999-09-03 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (CXX_TREE_H): Include function.h.
+ (decl.o): Don't depend on function.h.
+ (decl2.o): Likewise.
+ (typeck.o): Likewise.
+ (init.o): Likewise.
+ (method.o): Likewise.
+ * cp-tree.h: Include function.h.
+ (cp_function): Rename to language_function. Remove next.
+ (cp_function_chain): Make it a macro, not a variable.
+ (push_cp_function_context): Don't declare.
+ (pop_cp_function_context): Likewise.
+ * decl.c: Don't include function.h.
+ (push_cp_function_context): Make it static. Make it suitable for
+ a save_lang_status callback.
+ (pop_cp_function_context): Likewise.
+ (maybe_push_to_top_level): Call push_function_context_to, not
+ push_cp_function_context.
+ (pop_from_top_level): Call pop_function_context_from, not
+ pop_cp_function_context.
+ (init_decl_processing): Set save_lang_status and
+ restore_lang_status. Call push_function_context_to, not
+ push_cp_function_context.
+ (cp_function_chain): Remove.
+ * decl2.c: Don't include function.h.
+ * except.c: Don't include function.h.
+ (start_anon_func): Call push_function_context_to, not
+ push_cp_function_context.
+ (end_anon_func): Call pop_function_context_from, not
+ pop_cp_function_context.
+ * init.c: Don't include function.h.
+ * lex.c (begin_definition_of_inclass_inline): Call
+ push_function_context_to, not push_cp_function_context.
+ (process_next_inline): Call pop_function_context_from, not
+ pop_cp_function_context.
+ * method.c: Don't include function.h.
+ (synthesize_method): Call push_function_context_to, not
+ push_cp_function_context. Call pop_function_context_from, not
+ pop_cp_function_context.
+ * typeck.c: Don't include function.h.
+
+ * decl.c (expand_static_init): Tweak handling of static
+ initializations for objects without constructors.
+
+1999-09-03 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (build_indirect_ref): Reject dereference of pointer to
+ void.
+
+1999-09-02 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_function): Move here, from decl.c.
+ (cp_function_chain): Declare.
+ (dtor_label): New macro, instead of variable.
+ (ctor_label): Likewise.
+ (current_base_init_list): Likewise.
+ (current_member_init_list): Likewise.
+ (base_init_expr): Likewise.
+ (current_class_ptr): Likewise.
+ (current_class_ref): Likewise.
+ (last_tree): Likewise.
+ (last_expr_type): Likewise.
+ (current_function_returns_value): Likewise.
+ (current_function_returns_null): Likewise.
+ (current_function_just_assigned_this): Likewise.
+ (current_function_parms_stored): Likewise.
+ (temp_name_counter): Likewise.
+ (static_labelno): Likewise.
+ (expanding_p): Likewise.
+ (stmts_are_full_exprs_p): Likewise.
+ (in_function_try_handler): Likewise.
+ (lang_type): Remove nested type_flags. All uses changed.
+ * call.c (ctor_label): Remove.
+ (dtor_label): Likewise.
+ * class.c (current_class_ptr): Remove.
+ (current_class_ref): Likewise.
+ * decl.c (static_labelno): Remove.
+ (dtor_label): Likewise.
+ (last_dtor_insn): New macro, instead of variable.
+ (last_parm_cleanup_insn): Likewise.
+ (original_result_rtx): Likewise.
+ (in_function_try_handler): Remove.
+ (named_label_uses): New macro, instead of variable.
+ (named_labels): Likewise.
+ (current_function_returns_value): Remove.
+ (current_function_returns_null): Likewise.
+ (current_function_assigns_this): New macro, instead of variable.
+ (current_function_just_assigned_this): Likewise.
+ (current_binding_level): Likewise.
+ (init_decl_processing): Call push_cp_function_context.
+ (cp_function): Move to cp-tree.h
+ (cp_function_chain): Make it global.
+ (temp_name_counter): Remove.
+ (push_cp_function_context): Simplify.
+ (pop_cp_function_context): Likewise.
+ * decl2.c (temp_name_counter): Remove.
+ * init_c (current_base_init_list): Likewise.
+ (current_member_init_list): Likewise.
+ (base_init_expr): Likewise.
+ * method.c (static_labelno): Likewise.
+ * pt.c (last_tree): Likewise.
+ * semantics.c (expanding_p): Likewise.
+ (stmts_are_full_exprs_p): Likewise.
+ (last_expr_type): Likewise.
+ * typeck.c (dtor_label): Likewise.
+ (ctor_label): Likewise.
+
+1999-09-01 Alex Samuel <samuel@codesourcery.com>
+
+ * decl2.c (arg_assoc_template_arg): New prototype. New function.
+ (arg_assoc_class): Use arg_assoc_template_arg for template
+ arguments.
+ (arg_assoc): Likewise.
+ * pt.c (mangle_class_name_for_template): Allow member template
+ template arguments.
+
+1999-09-02 Nathan Sidwell <nathan@acm.org>
+
+ * call.c (build_conditional_expr): Warn on enum mismatches.
+ (convert_arg_to_ellipsis): Move non-pod check to after
+ conversion.
+
+1999-09-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gxx.gperf (hash, is_reserved_word): Add prototypes.
+
+ * init.c (build_vec_init): Initialize variable `try_block'.
+
+ * lex.c (init_parse): Call memcpy, not bcopy, to avoid casts.
+ Likewise for bzero/memset.
+ (token_getch, token_put_back): Add static prototypes. Remove
+ `inline' from the definitions.
+ (retrofit_lang_decl): Call memset, not bzero, to avoid casts.
+
+1999-09-01 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_type): Move align into type_flags.
+ (CLASSTYPE_ALIGN): Adjust accordingly.
+ * call.c (direct_reference_binding): Remove misleading comment.
+
+1999-08-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * parse.y (language_string): Constify.
+
+1999-08-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * repo.c (getpwd): Don't prototype.
+ * xref.c (getpwd): Likewise
+
+1999-08-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (LIBS, LIBDEPS): Link with & depend on libiberty.a.
+ Remove hacks for stuff which now comes from libiberty.
+
+1999-08-30 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (IS_AGGR_TYPE_2): Fix typo.
+
+1999-08-30 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (begin_init_stmts): Declare.
+ (finish_init_stmts): Likewise.
+ * cvt.c (build_up_reference): Wrap the declaration of a temporary
+ in a statement-expression so that we will see it when expanding
+ tree structure later.
+ * init.c (begin_init_stmts): Don't make it static.
+ (finish_init_stmts): Likewise.
+
+ * cp-tree.h (start_handler_parms): New function.
+ (expand_start_catch_block): Take only one parameter.
+ (start_handler_parms): New function.
+ * decl.c (start_handler_parms): Define it.
+ * except.c (process_start_catch_block): Take only one parameter.
+ Don't call grokdeclarator here.
+ (expand_start_catch_block): Don't call grokdeclarator here,
+ either.
+ * parse.y (handler_args): Adjust call to
+ expand_start_catch_block. Use start_handler_parms.
+ * pt.c (push_template_decl_real): Make permanent lists have
+ permanent elements.
+ (tsubst_expr): Adjust calls to expand_start_catch_block
+ appropriately.
+ * semantics.c (expand_stmt): Likewise.
+
+1999-08-29 Alex Samuel <samuel@codesourcery.com>
+
+ * pt.c (push_template_decl_real): Use template declaration from
+ class type if it exists.
+
+1999-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TYPE_NEEDS_CONSTRUCTING): Remove #if 0'd definition.
+ (maybe_inject_for_scope_var): Declare it.
+ (initialize_local_var): Likewise.
+ * decl.c (maybe_inject_for_scope_var): Make it global.
+ (initialize_local_var): Likewise. Move cleanup handling here,
+ from cp_finish_decl.
+ (make_rtl_for_nonlocal_decl): Use
+ push_obstacks_nochange/pop_obstacks, rather than
+ end_temporary_allocation/resume_temporary_allocation.
+ (cp_finish_decl): Try to complete the type of a variable when it
+ is declared. Move cleanup-handling to initialize_local_var.
+ (expand_static_init): Use tree-building code, rather than
+ RTL-building code.
+ * decl2.c (get_temp_name): Assert non-initializedness of
+ temporaries.
+ * init.c (create_temporary_var): Move RTL-assigning code to ...
+ (get_temp_regvar): Here.
+ * pt.c (tsbust_expr): Fix indentation. Call cp_finish_decl here.
+ * semantics.c (expand_stmt): Don't call cp_finish_decl here. Just
+ call initialize_local_var to generate initialization code.
+
+1999-08-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (fndecl_as_string, type_as_string,
+ type_as_string_real, args_as_string, decl_as_string,
+ expr_as_string, code_as_string, language_as_string,
+ parm_as_string, op_as_string, assop_as_string, cv_as_string,
+ lang_decl_name, cp_file_of, lang_printable_name): Constify a char*.
+
+ * errfn.c (cp_printer): Likewise.
+
+ * error.c (cp_printer, fndecl_as_string, type_as_string_real,
+ type_as_string, expr_as_string, decl_as_string, lang_decl_name,
+ cp_file_of, code_as_string, language_as_string, parm_as_string,
+ op_as_string, assop_as_string, args_as_string, cv_as_string):
+ Likewise.
+
+ * tree.c (lang_printable_name): Likewise.
+
+1999-08-28 Richard Henderson <rth@cygnus.com>
+
+ * decl2.c (arg_assoc_class): Bail if the class is a builtin type.
+
+1999-08-28 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (strip_array_types): New function.
+ * decl.c (maybe_deduce_size_from_array_init): New function, split
+ out from cp_finish_decl.
+ (layout_var_decl): Likewise.
+ (maybe_commonize_var): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (initialize_local_var): Likewise.
+ (build_cleanup_on_safe_obstack): Likewise.
+ (check_initializer): Likewise.
+ (make_rtl_for_nonlocal_decl): Likewise.
+ (cp_finish_decl): Use them.
+ * typeck.c (strip_array_types): New function.
+
+ * cp-tree.def (LABEL_STMT): New tree node.
+ * cp-tree.h (LABEL_STMT_LABEL): New macro.
+ (shadow_label): Remove.
+ (declare_local_label): New function.
+ (finish_label_decl): Likewise.
+ * decl.c (make_label_decl): New function, split out from
+ lookup_label.
+ (shadowed_labels): Remove.
+ (binding_level): Add shadowed_labels.
+ (clear_binding_level): Remove.
+ (push_binding_level): Just bzero the new binding level.
+ (pushlevel): Fix indentation.
+ (pop_label): New function.
+ (pop_labels): Likewise, split out from poplevel.
+ (poplevel): Pop local labels. Use pop_labels.
+ (maybe_push_to_top_level): Don't clear shadowed_labels.
+ (lookup_label): Use make_label_decl.
+ (shadow_label): Remove.
+ (declare_local_label): New function.
+ (define_label): Simplify.
+ (start_function): Don't clear shadowed_labels.
+ (cp_function): Remove shadowed_labels.
+ (push_cp_function_context): Don't save shadowed_labels.
+ (pop_cp_function_context): Don't restore it.
+ * dump.c (dequeue_and_dump): Handle LABEL_STMT.
+ * parse.y (label_decl): Use finish_label_decl.
+ * pt.c (tsubst_expr): Handle LABEL_STMTs, and local label
+ declarations.
+ * semantics.c (finish_label_stmt): Add a LABEL_STMT when
+ building_stmt_tree.
+ (finish_label_decl): New function.
+ (expand_stmt): Handle LABEL_STMTs and local label declarations.
+
+1999-08-26 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (lookup_label): Build labels on the permanent obstack
+ when building statement trees. Don't build RTL for labels when
+ building statement trees.
+ * semantics.c (finish_goto_stmt): Use LABEL_DECLs even when
+ building statement trees.
+ (finish_label_stmt): Likewise.
+ (expand_stmt): Adjust accordingly.
+ * pt.c (tsubst_expr); Likewise.
+ (do_decl_instantiation): Robustify.
+
+ * cp-tree.h (AGGR_INIT_VIA_CTOR_P): New macro.
+ * tree.c (build_cplus_new): Set it.
+ * expr.c (cplus_expand_expr): Use it.
+ * dump.c (deque_and_dump): Handle AGGR_INIT_EXPR.
+
+ * decl.c (store_parm_decls): Reset immediate_size_expand.
+ (finish_function): Likewise.
+
+ * tree.c (cplus_unsave_expr_now): Don't return a value.
+
+ * semantics.c (do_poplevel): Always initialize the return value.
+
+1999-08-26 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * cp-tree.h (cplus_unsave_expr_now) : Correct return type.
+ * tree.h (cplus_unsave_expr_now) : Same.
+
+1999-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokdeclarator): Amend comment.
+ * except.c (expand_start_catch_block): Call push_template_decl for
+ catch-block parameters.
+ * method.c (synthesize_method): Build an empty compound statement
+ for the body of a constructor.
+
+1999-08-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (cp_build_qualified_type_real): If we're asking for the
+ same quals we already have, just return.
+
+1999-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (SUBOBJECT): New tree node.
+ * cp-tree.h (CLEANUP_P): New macro.
+ (SUBOBJECT_CLEANUP): Likewise.
+ (keep_next_level): Add parameter.
+ (get_temp_regvar): Don't declare.
+ (emit_base_init): Remove parameter.
+ (expand_aggr_init): Rename to build_aggr_init.
+ (expand_vec_init): Rename to build_vec_init.
+ (do_pushlevel): Remove.
+ (do_poplevel): Likewise.
+ (finish_cleanup): New function.
+ (finish_subobject): Likewise.
+ (stmts_are_full_exprs_p): New variable.
+ * decl.c (keep_next_level): Add parameter.
+ (cp_finish_decl): Use build_aggr_init, not
+ expand_aggr_init. Use finish_expr_stmt to expand the code.
+ (expand_static_init): Use tree-generating, not RTL-generating,
+ functions to handle the initialization.
+ (start_function): Remove dead code. Always have a momentary
+ obstack inside the function, even before hitting the first curly
+ brace.
+ (cplus_expand_expr_stmt): Move calls to
+ expand_{start,end}_target_temps into semantics.c.
+ (cp_function): Add stmts_are_full_exprs_p.
+ (push_cp_function_context): Save it.
+ (pop_cp_function_context): Restore it.
+ * decl2.c (get_temp_regvar): Move to init.c.
+ (do_static_initialization): Use build_{aggr,vec}_init.
+ (do_static_destruction): Fix typo in comment.
+ * dump.c (dequeue_and_dump): Handle INIT_EXPR.
+ * except.c (expand_throw): Use create_temporary_var.
+ * expr.c (cplus_expand_expr): Use build_{aggr,vec}_init.
+ * init.c (expand_vec_init_try_block): Remove.
+ (expand_vec_init_catch_clause): Likewise.
+ (get_temp_regvar): New function.
+ (begin_init_stmts): Likewise.
+ (finish_init_stmts): Likewise.
+ (perform_member_init): Use build_{aggr,vec}_init. Build up tree
+ structure here.
+ (emit_base_init): Likewise. Remove unused parameter.
+ (expand_virtual_init): Likewise.
+ (expand_cleanup_for_base): Use finish_subobject.
+ (expand_aggr_vbase_init_1): Simplify.
+ (construct_virtual_bases): Use tree-generating functions to build
+ up initialization.
+ (expand_aggr_init): Likewise. Rename to build_aggr_init.
+ (expand_default_init): Likewise.
+ (expand_aggr_init_1): Likewise.
+ (expand_vec_init): Rename to build_vec_init.
+ * method.c (do_build_copy_constructor): Use tree-generating
+ functions. Don't call clear_last_expr.
+ (do_build_assign_ref): Likewise.
+ (synthesize_method): Call clear_last_expr here.
+ * parse.y (base_init): Don't call clear_last_expr here.
+ (nodecls): Likewise.
+ * pt.c (tsubst_expr): Handle a TRY_BLOCK with CLEANUP_P set.
+ * semantics.c (do_pushlevel): Move to here.
+ (do_poplevel): Likewise.
+ (stmts_are_full_exprs_p): New variable.
+ (finish_expr_stmt): Handle logic for temoprary cleanup here.
+ (finish_for_stmt): Use finish_expr_stmt.
+ (finish_cleanup): New function.
+ (finish_function_try_block): Fix indentation.
+ (finish_subobject): New function.
+ (setup_vtbl_ptr): Call keep_next_level here.
+ (finish_stmt_expr): Handle a block with no scope inside the
+ statement-expression.
+ (expand_stmt): Handle a TRY_BLOCK with CLEANUP_P set. Handle
+ SUBOBJECT.
+ * tree.c (search_tree): Handle INIT_EXPR.
+ (mapcar): Likewise.
+ * typeck.c (build_modify_expr): Don't build an RTL_EXPR.
+ * typeck2.c (store_init_value): Change expand_aggr_init to
+ build_aggr_init in comment.
+
+1999-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (dequeue_and_dump): Dump TARGET_EXPRs.
+
+1999-08-25 Nathan Sidwell <nathan@acm.org>
+
+ * decl2.c (handle_class_head): Be graceful about additional
+ scope qualifiers. Adjust comments to reflect reality.
+
+1999-08-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_conditional_expr): Fix typo.
+ * typeck.c (build_modify_expr, COND_EXPR): Make sure we've got an
+ lvalue before trying to mess with the sides.
+
+ * error.c (dump_expr, CONVERT_EXPR): Handle (void) properly.
+
+Mon Aug 23 22:17:20 1999 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * g++spec.c (lang_specific_driver): Add room for NULL in arglist.
+
+1999-08-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * exception.cc (__cplus_type_matcher): Call __throw_type_match_rtti_2.
+ Return arbitrary pointer or NULL.
+ (check_eh_spec): Call __throw_type_match_rtti_2.
+ * tinfo.h (*::dcast): Return int. Add valp parm.
+ * tinfo.cc (*::dcast): Likewise. Adjust to allow for null pointers.
+ * tinfo2.cc (__throw_type_match_rtti_2): Likewise.
+ (__throw_type_match_rtti): Now just a wrapper.
+
+ * except.c: Lose CatchMatch, FirstExceptionMatch, and Unwind.
+ (init_exception_processing): Don't initialize them.
+
+1999-08-23 Paul Burchard <burchard@pobox.com>
+
+ * decl.c (check_default_argument): Fix typo.
+
+1999-08-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (STMT_EXPR): Fix typo in node name.
+
+ * dump.c (dump_next_stmt): New function.
+ (dequeue_and_dump): Use it.
+
+ * pt.c (tsubst_copy): Make sure to initialize return value for a
+ STMT_EXPR, even when processing_template_decl.
+ * semantics.c (finish_stmt_expr): A statement-expression whose
+ last statement is not an expression-statement has type `void'.
+
+1999-08-20 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (finish_stmt_expr): Fix typo in comment.
+ * tree.c (search_tree): Handle EXIT_EXPR, LOOP_EXPR.
+ (mapcar): Likewise.
+ * init.c (build_vec_delete_1): Make the children of a permanent
+ BIND_EXPR permanent.
+ * pt.c (register_specialization): Don't register a specialization
+ more than once.
+
+1999-08-18 Andrew Haley <aph@cygnus.com>
+
+ * method.c (process_overload_item): Call build_mangled_C9x_name ()
+ for all integer parameter types larger than long long.
+
+1999-08-19 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (redeclare_class_template): Merge default template
+ arguments in both directions.
+
+ * typeck.c (common_type): Undo 1999-08-18 change. Remove
+ compiler_error message.
+
+1999-08-19 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h: Declare flag_use_repository.
+ * pt.c (do_decl_instantiation): Don't complain about duplicate
+ instantiation with -frepo.
+ (do_type_instantiation): Likewise.
+
+ * pt.c (push_template_decl_real): Complain about everything
+ that isn't a valid template.
+
+ * decl2.c (import_export_decl): If -fnew-abi, class linkage doesn't
+ affect inlines.
+
+1999-08-19 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (PSEUDO_DTOR_EXPR): New tree code.
+ * decl2.c (build_expr_from_tree): Handle it.
+ * error.c (dump_expr): Likewise.
+ * pt.c (for_each_template_parm): Likewise.
+ (tsubst_copy): Likewise.
+ * tree.c (search_tree): Likewise.
+ * semantics.c (finish_pseudo_destructor_call): Create it.
+
+1999-08-18 Mark Mitchell <mark@codesourcery.com>
+
+ * search.c (setup_class_bindings): Robustify.
+ * typeck.c (common_type): Use same_type_p, not pointer equality,
+ to compare types.
+
+ * cp-tree.h (build_lang_field_decl): Remove.
+ * class.c (build_vtable): Replace calls to build_lang_field_decl
+ with build_lang_decl.
+ (prepare_fresh_vtable): Likewise.
+ (finish_struct_1): Likewise.
+ (init_class_processing): Likewise.
+ * decl.c (push_using_decl): Likewise.
+ (init_decl_processing): Likewise.
+ (grokvardecl): Likewise.
+ (build_ptrmemfunc_type): Likewise.
+ (grokdeclarator): Likewise.
+ (build_enumerator): Likewise.
+ * decl2.c (grok_x_components): Likewise.
+ (do_class_using_decl): Likewise.
+ * except.c (call_eh_info): Likewise.
+ * init.c (init_init_processing): Likewise.
+ * rtti.c (expand_class_decl): Likewise.
+ * tree.c (build_base_fields): Likewise.
+ (build_vbase_pointer_fields): Likewise.
+ * lex.c (build_lang_decl): Build declarations on the permanent
+ obstack if we're building statmeent trees.
+ (retrofit_lang_decl): Handle both the full lang_decl and also the
+ smaller lang_decl_flags here.
+ (build_lang_field_decl): Remove.
+ * pt.c (push_template_decl_real): Issue errors for variable
+ declarations that are not static members.
+
+1999-08-18 Richard Henderson <rth@cygnus.com>
+
+ * tree.c (search_tree): Handle TRUTH_{AND,OR,XOR}_EXPR too.
+ (mapcar): Likewise.
+
+1999-08-17 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (back_end_hook): New variable.
+ * decl2.c (back_end_hook): Define it.
+ (finish_file): If it's non-NULL, call it.
+
+ * decl.c (add_decl_to_level): New function.
+ (push_local_binding): Use it.
+ (find_binding): Fix typo in comment.
+ (pushdecl): Use add_decl_to_level. Put templates on the
+ corresponding namespace-scope binding levels.
+ * dump.c (dequeue_and_dump): Print the specializations of a
+ template.
+ * pt.c (push_template_decl_real): Don't push a template multiple
+ times.
+
+1999-08-17 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CALL_DECLARATOR_PARMS): New macro.
+ (CALL_DECLARATOR_QUALS): Likewise.
+ (CALL_DECARATOR_EXCEPTION_SPEC): Likewise.
+ * decl.c (grokdeclarator): Adjust to use them.
+ * decl2.c (grokfield): Likewise.
+ (reparse_absdcl_as_casts): Likewise.
+ * lex.c (make_call_declarator): Likewise.
+ (set_quals_and_spec): Likewise.
+ * pt.c (tsubst): Likewise.
+ * tree.c (mapcar): Remove special hack to handle third operand of
+ a CALL_EXPR.
+
+1999-08-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CAN_HAVE_FULL_LANG_DECL_P): New macro.
+ * class.c (build_vtable): Use build_lang_field_decl to build the
+ VAR_DECLs for vtables.
+ (prepare_fresh_vtable): Likewise.
+ * decl.c (duplicate_decls): Only copy DECL_SAVED_TREE if
+ CAN_HAVE_FULL_LANG_DECL_P.
+ (push_using_decl): Use build_lang_decl to build USING_DECLs.
+ (grokdeclarator): Use build_lang_decl to build TYPE_DECLs.
+ * lex.c (retrofit_lang_decl): Check CAN_HAVE_FULL_LANG_DECL_P.
+ (build_lang_field_decl): Likewise.
+ (copy_lang_decl): Use CAN_HAVE_FULLLANG_DECL_P to decide how much
+ to copy.
+
+ * cp-tree.def (STMT_EXPR): New tree node.
+ * cp-tree.h (STMT_EXPR_STMT): New macro.
+ (store_return_init): Change prototype.
+ (finish_named_return_value): New function.
+ (expand_stmt): Likewise.
+ (expand_body): Likewise.
+ (begin_stmt_tree): Likewise.
+ (finish_stmt_tree): Likewise.
+ (expanding_p): New variable.
+ (last_expr_type): Likewise.
+ (building_stmt_tree): New macro.
+ * decl.c (start_function): Use building_stmt_tree, not
+ processing_template_decl, where appropriate.
+ (store_parm_decls): Likewise.
+ (store_return_init): Move most of the body to semantics.c.
+ (finish_function): Use building_stmt_tree.
+ (finish_stmt): Clear last_expr_type here.
+ (cp_function): Add expanding_p, last_tree, last_expr_type.
+ (push_cp_function_context): Save them.
+ (pop_cp_function_context): Restore them.
+ * decl2.c (setup_vtbl_ptr): Move to semantics.c.
+ * error.c (dump_expr): Handle STMT_EXPR.
+ * except.c (expand_start_catch_block): Use building_stmt_tree.
+ Use add_decl_stmt.
+ * expr.c (cplus_expand_expr): Handle STMT_EXPR.
+ (do_case): Move add_tree call to semantics.c.
+ * parse.y (return_init): Use finish_named_return_value.
+ (for.init.statement): Use finish_expr_stmt.
+ * parse.c: Regenerated.
+ * pt.c (do_pushlevel): Move to semantics.c.
+ (do_poplevel): Likewise.
+ (tsubst_copy): Handle STMT_EXPR instead of BIND_EXPR.
+ (tsubst_expr): Don't expand all the way to RTL here. Handle
+ RETURN_INIT and CTOR_INITIALIZER.
+ (instantiate_decl): Call expand_body after tsubst'ing into
+ DECL_SAVED_TREE.
+ * semantics.c (expand_stmts): New function.
+ (expanding_p): New variable.
+ (last_expr_type): Likewise.
+ (finish_expr_stmt): Use building_stmt_tree.
+ (begin_if_stmt): Likewise.
+ (finish_if_stmt_cond): Likewise.
+ (finish_then_clause): Likewise.
+ (begin_else_clause): Likewise.
+ (finish_else_clause): Likewise.
+ (begin_while_stmt): Likewise.
+ (finish_while_stmt_cond): Likewise.
+ (finish_while_stmt): Likewise.
+ (finish_do_body): Likewise.
+ (finish_do_stmt): Likewise.
+ (finish_return_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (fnish_for_init_stmt): Likewise.
+ (finish_for_cond): Likewise.
+ (finish_for_expr): Likewise.
+ (finish_for_stmt): Likewise.
+ (finish_break_stmt): Likewise.
+ (finish_continue_stmt): Likewise.
+ (finish_switch_cond): Likewise.
+ (finish_switch_stmt): Likewise.
+ (finish_case_label): Call add_tree here if necessary.
+ (finish_goto_statement): Use building_stmt_tree.
+ (begin_try_block): Likewise.
+ (begin_function_try_block): Likewise.
+ (finish_try_block): Likewise.
+ (finish_function_try_block): Likewise.
+ (finish_handler_sequence): Likewise.
+ (finish_function_handler_sequence): Likewise.
+ (begin_handler): Likewise.
+ (finish_handler_parms): Likewise.
+ (finish_handler): Likewise.
+ (begin_compound_stmt): Likewise.
+ (finish_compound_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ (finish_label_stmt): Likewise.
+ (finish_named_return_value): New function.
+ (setup_vtbl_ptr): Moved here from decl2.c.
+ (do_pushlevel): Moved here from pt.c.
+ (do_poplevel): Likewise.
+ (begin_stmt_expr): Use building_stmt_tree.
+ (finish_stmt_expr): Likewise. Build a STMT_EXPR, not a BIND_EXPR,
+ when building_stmt_tree.
+ (begin_stmt_tree): New function.
+ (finish_stmt_tree): Likewise.
+ (expand_stmt): Likewise.
+ (expand_body): Likewise.
+ * tree.c (build_cplus_method_type): Make sure the argument types
+ end up on the same obstack as the METHOD_TYPE.
+ (search_tree): Handle COMPOUND_EXPR, MODIFY_EXPR,
+ THROW_EXPR, STMT_EXPR.
+ (mapcar): Break out common cases. Handle COMPOUND_EXPR,
+ MODIFY_EXPR, THROW_EXPR, STMT_EXPR, RTL_EXPR. Abort, rather than
+ sorry, if an unsupported node is encountered.
+ * typeck.c (require_complete_type_in_void): Handle BIND_EXPR.
+ (c_expand_return): Don't call add_tree here.
+
+1999-08-15 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (check_default_tmpl_args): Don't check in local scopes.
+ (tsubst_decl): Make sure the declaration is on a saveable
+ obstack. Clear DECL_DEAD_FOR_LOCAL when making a copy of a local
+ variable.
+ (tsubst_expr): Adjust now that DECL_STMTs really contain DECLs.
+
+1999-08-14 Jason Merrill <jason@yorick.cygnus.com>
+
+ Speed up Koenig lookup.
+ * decl.c (unqualified_namespace_lookup): Nonstatic. Add spacep parm
+ to return namespaces we've looked at.
+ * decl2.c (lookup_using_namespace): Likewise.
+ (add_function): Don't call ovl_member.
+ (lookup_arg_dependent): Initialize k.namespaces to the list of
+ namespaces seen in unqualified lookup.
+ * call.c (equal_functions): Move here from tree.c.
+ (joust): Use it to handle duplicate candidates.
+ * tree.c (ovl_member): Use ==.
+
+1999-08-13 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (DECL_STMT): Make it smaller.
+ * cp-tree.h (lang_decl_flags): Move saved_tree to ...
+ (lang_decl): ... here. Add next.
+ (DECL_SAVED_TREE): Adjust accordingly.
+ (DECL_IMPLICIT_TYPEDEF_P): New macro.
+ (SET_DECL_IMPLICIT_TYPEDEF_P): Likewise.
+ (DECL_STMT_DECL): Likewise.
+ (create_implicit_typedef): New function.
+ (maybe_push_decl): Likewise.
+ (tsubst_default_argument): New function.
+ (at_function_scope_p): Likewise.
+ (add_decl_stmt): Likewise.
+ (push_permanent_obstack): Likewise.
+ * call.c (convert_default_arg): Use tsubst_default_argument.
+ * class.c (add_method): Use push_permanent_obstack.
+ (build_self_reference): Create a TEMPLATE_DECL for the
+ self-reference, if necessary.
+ * decl.c (pseudo_global_level_p): Only look at the current binding
+ level.
+ (push_binding): Use push_permanent_obstack.
+ (create_implicit_typedef): New function.
+ (pushtag): Use it.
+ (duplicate_decls): Use push_permanent_obstack.
+ (maybe_push_decl): New function.
+ (start_decl): Use it. Remove dead code. Use add_decl_stmt.
+ (start_decl_1): Remove dead code.
+ (cp_finish_decl): Remove DECL_STMT handling here. Don't use
+ pseudo_global_level_p.
+ (grokvardecl): Create DECL_LANG_SPECIFIC for a VAR_DECL in a
+ template.
+ (grokdeclarator): Likewise, for TYPE_DECLs. Don't use
+ pseudo_global_level_p.
+ * decl2.c (grokfield): Call push_template_decl for a TYPE_DECL in
+ a template.
+ (get_sentry): Use push_permanent_obstack.
+ * dump.c (dequeue_and_dump): Enable DECL_STMT.
+ * except.c (call_eh_info): Use push_permanent_obstack.
+ (build_eh_type_ref): Likewise.
+ (do_pop_exception): Likewise.
+ (expand_eh_spec): Likewise.
+ (alloc_eh_object): Likewise.
+ (expand_throw): Likewise.
+ * init.c (build_java_class_ref): Likewise.
+ * lex.c (get_time_identifier): Likewise.
+ (free_lang_decl_chain): Correct type.
+ (retrofit_lang_decl): Adjust accordingly.
+ (build_lang_field_decl): Likewise.
+ * lex.h (free_lang_decl_chain): Likewise.
+ * parse.y (lang_extdef): Don't use pseudo_global_level_p.
+ * parse.c: Regenerated.
+ * pt.c (tsubst_default_arguments): New function.
+ (retrieve_local_specialization): Likewise.
+ (register_local_specialization): Likewise.
+ (push_template_decl_real): Use DECL_IMPLICIT_TYPEDEF_P. Just use
+ pseudo_global_level_p to determine whether or not a template is
+ primary.
+ (lookup_template_class): Likewise. Use create_implicit_typedef.
+ (instantiate_class_template): Call tsubst_default_arguments for
+ member functions, if appropriate.
+ (tsubst_default_argument): New function.
+ (tsubst_decl): Use it. Change TYPE_DECL handling to match VAR_DECLs.
+ * search.c (at_function_scope_p): New function.
+ * semantics.c (finish_asm_stmt): Use push_permanent_obstack.
+ (finish_label_stmt): Likewise.
+ (add_decl_stmt): New function.
+ (begin_class_definition): Likewise.
+ (finish_typeof): Likewise.
+ * tree.c (copy_template_template_parm): Likewise.
+ (copy_to_permanent): Likewise.
+ (push_permanent_obstack): Define.
+ (mark_addressable): Use it.
+ * typeck.c (mark_addressable): Likewise.
+
+1999-08-13 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * cp-tree.h (init_cplus_unsave): New.
+ (cplus_unsave_expr_now): New.
+ * lex.c (init_parse): Call init_cplus_unsave.
+ * tree.c (init_cplus_unsave): New.
+ (cplus_unsave_expr_now): New.
+
+1999-08-13 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst): Back out 1999-08-06 patch. Use fold and
+ decl_constant_value to simplify array bounds.
+
+1999-08-11 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lang-options.h: Add -fms-extensions.
+ * cp-tree.h: Declare flag_ms_extensions.
+ * decl2.c: Define it.
+ * class.c (instantiate_type): Don't complain about taking the address
+ of a bound member function if -fms-extensions.
+ * typeck.c (build_unary_op): Likewise.
+ * decl.c (grokdeclarator): Or about implicit int.
+ * init.c (resolve_offset_ref): Or about implicit '&'.
+
+1999-08-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (minimal_parse_mode): Remove.
+ (finish_label_stmt): New function.
+ * decl.c (saved_scope): Remove minimal parse mode.
+ (maybe_push_to_top_level): Don't save it.
+ (pop_from_top_level): Don't restore it.
+ (define_label): Split out template-handling code to semantics.c.
+ (start_decl): Don't use minimal_parse_mode.
+ (cp_finish_decl): Likewise.
+ (start_function): Don't increment it.
+ (store_return_init): Don't use it.
+ (finish_function): Don't decrement it.
+ * parse.y (label_colon): Use finish_label_stmt throughout.
+ * parse.c: Regenerated.
+ * pt.c (minimal_parse_mode): Don't define it.
+ (tsubst_expr): Use finish_label_stmt.
+ * semantics.c (finish_label_stmt): New function.
+
+ * dump.c (queue): Be careful when computing bitmasks.
+ (dequeue_and_dump): Describe binfos as binfos, not as
+ vectors.
+
+ * parse.y (pedantic): Give it itype. Adjust usage accordingly
+ throughout.
+ * parse.c: Regenerated.
+
+ * Make-lang.in (CXX_SRCS): Remove sig.c.
+ * Makefile.in (CXX_OBJS): Remove sig.o.
+ (sig.o): Remove.
+ * cp-tree.h (CPTI_OPAQUE_TYPE): Remove.
+ (CPTI_SIGNATURE_TYPE): Likewise.
+ (CPTI_SIGTABLE_ENTRY_TYPE): Likewise.
+ (opaque_type_node): Likewise.
+ (signature_type_node): Likewise.
+ (sigtable_entry_type): Likewise.
+ (flag_handle_signatures): Likewise.
+ (lang_type): Remove is_signature, is_signature_pointer,
+ is_signature_reference, has_opaque_typedecls,
+ sigtables_has_been_generated. Adjust dummy. Remove signature,
+ signature_pointer_to, signature_reference_to.
+ (IS_SIGNATURE): Remove.
+ (SET_SIGNATURE): Remove.
+ (CLEAR_SIGNATURE): Remove.
+ (IS_SIGNATURE_POINTER): Remove.
+ (IS_SIGNATURE_REFERENCE): Remove.
+ (SIGNATURE_HAS_OPAQUE_TYPEDECLS): Remove.
+ (SIGTABLE_HAS_BEEN_GENERATED): Remove.
+ (CLASSTYPE_SIGNATURE): Remove.
+ (SIGNATURE_TYPE): Remove.
+ (SIGNATURE_METHOD_VEC): Remove.
+ (SIGNATURE_POINTER_TO): Remove.
+ (SIGNATURE_REFERENCE_TO): Remove.
+ (lang_decl_flags): Remove is_default_implementation. Rename
+ memfunc_pointer_to to saved_tree.
+ (IS_DEFAULT_IMPLEMENTATION): Remove.
+ (DECL_MEMFUNC_POINTER_TO): Remove.
+ (DECL_MEMFUNC_POINTING_TO): Remove.
+ (DECL_SAVED_TREE): Adjust definition.
+ (tag_types): Remove signature_type_node.
+ (SIGNATURE_FIELD_NAME): Remove.
+ (SIGNATURE_FIELD_NAME_FORMAT): Likewise.
+ (SIGNATURE_OPTR_NAME): Likewise.
+ (SIGNATURE_SPTR_NAME): Likewise.
+ (SIGNATURE_POINTER_NAME): Likewise.
+ (SIGNATURE_POINTER_NAME_FORMAT): Likewise.
+ (SIGNATURE_REFERENCE_NAME): Likewise.
+ (SIGNATURE_REFERNECE_NAME_FORMAT): Likewise.
+ (SIGTABLE_PTR_TYPE): Likewise.
+ (SIGTABLE_NAME_FORMAT): Likewise.
+ (SIGTABLE_NAME_FORMAT_LONG): Likewise.
+ (SIGTABLE_TAG_NAME): Likewise.
+ (SIGTABLE_VB_OFF_NAME): Likewise.
+ (SIGTABLE_VT_OFF_NAME): Likewise.
+ (finish_base_specifiers): Change prototype.
+ (build_signature_pointer_type): Remove.
+ (build_signature_reference_type): Remove.
+ (build_signature_pointer_constructor): Remove.
+ (build_signature_method_call): Remove.
+ (build_optr_ref): Likewise.
+ (append_signature_fields): Likewise.
+ (signature_error): Likewise.
+ * call.c (build_this): Remove signature support.
+ (build_over_call): Likewise.
+ (build_new_method_call): Likewise.
+ * class.c (add_implicitly_declared_members): Likewise.
+ (finish_struct_1): Likewise.
+ (finish_struct): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_pointer_force): Likewise.
+ (ocp_convert): Likewise.
+ * decl.c (sigtable_decl_p): Remove.
+ (init_decl_processing): Remove support for signatures.
+ (cp_finish_decl): Likewise.
+ (grokdeclarator): Likewise.
+ (grokparms): Likewise.
+ (xref_tag): Likewise.
+ (start_function): Likewise.
+ (start_method): Likewise.
+ * decl2.c (finish_sigtable_vardecl): Remove.
+ (flag_handle_signatures): Remove.
+ (lang_f_options): Remove handle-signatures.
+ (grokfield): Remove support for signatures.
+ (grokbitfield): Likewise.
+ (finish_file): Likewise.
+ (reparse_absdcl_as_casts): Likewise.
+ * error.c (dump_type_real): Likewise.
+ (dump_function_decl): Likewise.
+ * friend.c (make_friend_class): Likewise.
+ * gxx.gperf: Remove __signature__, signature, __sigof__, sigof.
+ * hash.h: Regenerated.
+ * init.c (build_new_1): Remove support for signatures.
+ * lang-options.h: Remove -fhandle-signatures,
+ -fno-handle-signatures.
+ * lex.c (init_parse): Remove support for signatures.
+ (yyprint): Likewise.
+ * lex.h (rid): Remove RID_SIGNATURE.
+ * method.c (build_decl_overload_real): Remove support for
+ signatures.
+ (hack_identifier): Likewise.
+ * parse.y (base_class): Likewise.
+ (base_class.1): Likewise.
+ (access_specifier): Likewise.
+ * search.c (lookup_member): Likewise.
+ * semantics.c (finish_qualified_object_call_expr): Likewise.
+ (finish_template_type_parm): Likewise.
+ (begin_class_definition): Likewise.
+ (finish_base_specifier): Likewise.
+ * sig.c: Remove.
+ * tree.c (build_cplus_method_type): Remove support for signatures.
+ * typeck.c (require_complete_type): Likewise.
+ (c_sizeof): Likewise.
+ (c_alignof): Likewise.
+ (build_object_ref): Likewise.
+ (build_component_ref): Likewise.
+ (build_indirect_ref): Likewise.
+ (build_c_cast): Likewise.
+ (build_modify_expr): Likewise.
+ (convert_for_initialization): Likewise.
+ * typeck2.c (signature_error): Remove.
+ (store_init_value): Remove support for signatures.
+ (digest_init): Likewise.
+ (build_x_arrow): Likewise.
+ (build_functional_cast): Likewise.
+ * xref.c (GNU_xref_decl): Likewise.
+
+1999-08-10 Martin v. Löwis <martin@mira.isdn.cs.tu-berlin.de>
+
+ * lex.c (do_identifier): Remove unnecessary lookup of class field.
+
+1999-08-09 Martin v. Löwis <martin@mira.isdn.cs.tu-berlin.de>
+
+ * decl2.c (set_decl_namespace): Do not complain about non-matching
+ decls if processing a template.
+
+1999-08-09 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (build_ptrmemfunc_type): Handle qualified
+ pointer-to-member types here.
+ * tree.c (cp_build_qualified_type_real): Simplify handling here.
+
+1999-08-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c (lang_identify): Likewise.
+
+1999-08-09 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * Makefile.in: Update dependencies.
+ * class.c (finish_struct_1): Don't initialize DECL_SAVED_INSNS with
+ NULL_RTX.
+ * decl.c: Include "function.h"
+ (cleanup_label, return_label): Delete declarations.
+ (store_parm_decls): Don't initialize DECL_SAVED_INSNS with NULL_RTX.
+ (finish_function): Rename last_parm_insn variable to
+ fn_last_parm_insn. Don't compare DECL_SAVED_INSNS to NULL_RTX.
+ * decl2.c: Include "function.h".
+ (rtl_expr_chain): Delete declaration.
+ * method.c: Include "function.h"
+ * tree.c (build_vbase_pointer_fields): Don't initialize
+ DECL_SAVED_INSNS with NULL_RTX.
+ * typeck.c: Include "function.h"
+
+1999-08-09 Jason Merrill <jason@yorick.cygnus.com>
+
+ * semantics.c (begin_function_try_block, finish_function_try_block,
+ finish_function_handler_sequence): New fns.
+ * parse.y (function_try_block): Use them.
+ * pt.c (instantiate_decl): Likewise.
+
+ * cp-tree.h: Declare in_function_try_handler.
+ * decl.c: Define it.
+ (start_function): Clear it.
+ (struct cp_function, push_cp_function_context): Save it.
+ (pop_cp_function_context): Restore it.
+ * parse.y (function_try_block): Set and clear it.
+ * except.c (expand_end_catch_block): Rethrow if we reach the end
+ of a function-try-block handler in a ctor or dtor.
+ * typeck.c (c_expand_return): Complain about returning from a
+ function-try-block handler of a ctor.
+
+ * parse.y (function_try_block): Call end_protect_partials
+ before expand_start_all_catch.
+
+1999-08-08 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (struct binding_level): Add eh_region field.
+ (push_binding_level): Set it.
+ (define_label): Complain about jumping into an EH block.
+
+ * ptree.c (print_lang_type): Print the real type of a PMF.
+ Print what exceptions a fn type throws.
+
+1999-08-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (count_fields, add_fields_to_vec): Add static prototype.
+
+ * cp-tree.h (opname_tab, assignop_tab, operator_name_string,
+ get_id_2, composite_pointer_type, dump_node_to_file): Constify a
+ char*.
+
+ * decl.c (named_label_list, cp_finish_decl, grokdeclarator):
+ Constify a char*.
+
+ * decl2.c (finish_static_data_member_decl, grokfield): Constify a
+ char*.
+
+ * dump.c (queue_and_dump_index, dump_int, dump_string,
+ dump_string_field, dequeue_and_dump, dump_node_to_file): Constify
+ a char*.
+ (dump_stmt): Add static prototype.
+
+ * errfn.c (cp_thing): Constify a char*.
+
+ * error.c (dump_unary_op, dump_binary_op, aggr_variety,
+ dump_aggr_type, dump_global_iord, dump_decl, dump_function_name,
+ dump_expr): Constify a char*.
+
+ * lex.c (extend_token_buffer_to, pragma_getc, pragma_ungetc,
+ read_line_number): Add static prototype.
+ (opname_tab, assignop_tab, operator_name_string): Constify a char*.
+ (real_yylex): Move label `letter' into the scope where it is used.
+
+ * method.c (build_mangled_template_parm_index, build_overload_int,
+ build_decl_overload_real, get_id_2): Constify a char*.
+
+ * search.c (check_final_overrider): Make static.
+
+ * typeck.c (composite_pointer_type): Constify a char*.
+
+1999-08-06 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (maybe_get_template_decl_from_type_decl): Make sure that
+ we're looking at a class.
+
+ * decl.c (lookup_name_real): Set the complain flag if we're
+ looking for a namespace member.
+
+ * lex.c (real_yylex): We can have a number with no digits.
+
+ * cvt.c (cp_convert_to_pointer): Don't force pmf conversions.
+
+ * search.c (binfo_from_vbase): New fn.
+ * cp-tree.h: Declare it.
+ * cvt.c (cp_convert_to_pointer): Use it to diagnose conversion
+ from pointer to member of virtual base.
+ * typeck.c (get_delta_difference): Likewise.
+
+1999-08-06 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * pt.c (tsubst): Use build_index_type to build in-template array
+ index type. Fixes g++.oliva/dwarf1.C.
+ * decl.c (grokdeclarator): Likewise, just for consistency, as it
+ doesn't seem to trigger the bug without it.
+
+1999-08-06 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (add_exception_specifier): Use complete_type.
+
+1999-08-06 Mark Mitchell <mark@codesourcery.com>
+
+ * error.c (dump_expr): Handle EXACT_DIV_EXPR.
+ (dump_binary_op): Bulletproof.
+ * lex.c (init_parse): Set opname_tab[EXACT_DIV_EXPR].
+ * tree.c (search_tree): Don't enumerate all the nodes of classes
+ `1', `2', and `<'; handle them generically. Don't be sorry about
+ "unrecognized tree codes"; just abort.
+ (no_linkage_check): Don't do linkage checks for templates.
+
+ * tree.c (cp_build_qualified_type_real): Handle
+ pointer-to-member-function types correctly.
+
+1999-08-05 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (pushdecl): Only give an error for shadowing a parm
+ from *this* function.
+
+Thu Aug 5 02:40:42 1999 Jeffrey A Law (law@cygnus.com)
+
+ * typeck2.c: Update URLs and mail addresses.
+
+1999-08-04 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (empty_except_spec): New global var.
+ (compexcepttypes): Remove prototype.
+ (comp_except_specs): Prototype new global function.
+ (add_exception_specifier): Prototype new global function.
+ * decl.c (empty_except_spec): Define new global var.
+ (duplicate_decls): Use comp_except_specs, reword error message.
+ (init_decl_processing): Initialize empty_except_spec.
+ Adjust build_exception_variant calls.
+ * parse.y (exception_specification_opt): Use empty_except_spec.
+ (ansi_raise_identifier): Call check_for_new_type.
+ (ansi_raise_identifiers): Use add_exception_specifier.
+ * pt.c (tsubst): Use add_exception_specifier to build exception
+ specifier.
+ * search.c (check_final_overrider): New static function, broken
+ out of get_matching_virtual. Check throw specifiers, reword
+ diagnostics.
+ (get_matching_virtual): Use check_final_overrider.
+ * tree.c (build_exception_variant): Use comp_except_specs.
+ * typeck.c (compexcepttypes): Remove.
+ (comp_except_types): New static function, helper for
+ comp_except_specs. Compare two types as exception specifiers.
+ (comp_except_specs): New global function, compare two exception
+ specifiers.
+ (comptypes): Adjust for comp_except_specs.
+ * typeck2.c (add_exception_specifier): New global function.
+
+ * class.c (check_for_override): Reword error message.
+
+1999-08-03 Nathan Sidwell <nathan@acm.org>
+
+ * call.c (convert_arg_to_ellipsis): Use pod_type_p.
+ * cp-tree.h (struct lang_type): Added non_pod_class flag.
+ (CLASSTYPE_NON_POD_P): New macro to access it.
+ * class.c (finish_struct_1): Determine non-PODness.
+ Check for arrays of pointers (-Weffc++).
+ Remove array inspection duplicated code.
+ * tree.c (pod_type_p): Detect non-pod non-aggregate types.
+ Use CLASSTYPE_NON_POD_P.
+
+1999-08-03 Nathan Sidwell <nathan@acm.org>
+
+ * class.c (duplicate_tag_error): Preserve template information.
+
+1999-08-03 Nathan Sidwell <nathan@acm.org>
+
+ * decl.c (start_enum): Show location of previous definition.
+ * parse.y (enumlist_opt): New reduction.
+ (structsp): Simplify enum rules to use enumlist_opt.
+
+1999-08-03 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (yyprint): Handle PFUNCNAME.
+
+ * decl2.c (build_expr_from_tree, case METHOD_CALL_EXPR): Only
+ build_expr_from_tree on the args of a TEMPLATE_ID_EXPR.
+
+1999-08-03 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * decl.c (start_decl): Set attributes before duplicate_decls call.
+
+1999-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (CXX_SRCS): Add dump.c.
+ * Makefile.in (CXX_OBJS): Add dump.o.
+ (dump.o): New target.
+ * cp-tree.h (DECL_CONV_FN_P): Document.
+ (DECL_OVERLOADED_OPERATOR_P): New function.
+ (TYPE_PTRMEM_CLASS_TYPE): New macro.
+ (TYPE_PTRMEM_POINTED_TO_TYPE): Likewise.
+ (PTRMEM_CST_CLASS): Use TYPE_PTRMEM_CLASS_TYPE.
+ (ASM_VOLATILE_P): New macro.
+ (STMT_LINENO): Likewise.
+ (cp_namespace_decls): New function.
+ (dump_node_to_file): New function.
+ * decl.c (cp_namespace_decls): New function.
+ (walk_namespaces_r): Use it.
+ (wrapup_globals_for_namespace): Likewise.
+ * decl2.c (flag_dump_translation_unit): New variable.
+ (lang_decode_option): Handle -fdump-translation-unit.
+ (finish_file): If flag_dump_translation_unit is set, dump the
+ translation unit.
+ * dump.c: New file.
+ * lang-options.h: Add -fdump-translation-unit.
+ * pt.c (tsubst_template_parms): Robustify.
+ (tsubst_decl): Use DECL_OVERLOADED_OPERATOR_P.
+ (tsubst_expr): Use STMT_LINENO.
+ * semantics.c (finish_asm_stmt): Eliminate duplicate code. Check
+ for invalid cv-qualifiers even while building templates.
+
+1999-08-02 Richard Henderson <rth@cygnus.com>
+
+ * call.c: Include defaults.h instead of expr.h.
+ * decl.c: Likewise.
+ * pt.c: Likewise.
+ * typeck.c: Include defaults.h.
+
+1999-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * lex.c (errorcount, sorrycount): Don't declare.
+ * repo.c (errorcount, sorrycount): Likewise.
+ * typeck2.c (errorcount, sorrycount): Likewise.
+
+1999-08-02 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * call.c (convert_default_arg, build_over_call): Change all uses of
+ PROMOTE_PROTOTYPES, so that it tests it as a C expression.
+ Ensure expr.h is included.
+ * decl.c (grokparams): Ditto.
+ * pt.c (tsubst_decl): Ditto.
+ * typeck.c (convert_arguments): Ditto.
+
+1999-08-02 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (mark_overriders): Fix order of args to overrides.
+ (warn_hidden): Likewise. Fix for having virtual and non-virtual
+ functions with the same name.
+
+1999-08-02 Richard Henderson <rth@cygnus.com>
+
+ * cp-tree.h (TYPE_PTRMEMFUNC_P): Check TYPE_LANG_SPECIFIC non-null.
+
+1999-08-01 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_conditional_expr): Fix typo in comment.
+
+1999-08-01 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * decl.c (finish_stmt): Don't declare and test cond_stack, loop_stack,
+ case_stack; use in_control_zone_p.
+ * typeck.c (c_expand_return): Likewise.
+
+1999-07-31 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * except.c (catch_clauses): Delete declaration.
+
+1999-07-30 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_conditional_expr): Call convert_from_reference to
+ avoid reference/non-reference type confusion. Fix typo.
+
+1999-07-30 Richard Henderson <rth@cygnus.com>
+
+ * typeck2.c (initializer_constant_valid_p): Moved to c-common.c.
+ * cp-tree.h (initializer_constant_valid_p): Remove.
+
+1999-07-28 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (conditional_conversion): Don't build BASE_CONVs for
+ conversions between things that have the same type.
+ (build_conditional_expr): Tweak.
+ (convert_like): Some BASE_CONVs really do require the generation
+ of code.
+
+ * init.c (perform_member_init): Don't go through build_modify_expr
+ for simple initializations.
+
+1999-07-27 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (DECL_VIRTUAL_CONTEXT): New macro.
+ * typeck.c (expand_ptrmemfunc_cst): Calculate delta correctly for
+ virtual functions and MI. Simplify.
+
+ * method.c: Remove prototype for largest_union_member.
+ * pt.c (determine_specialization): Fix uninitialized warning.
+ * lex.c (real_yylex): Likewise.
+
+1999-07-27 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (override_one_vtable): Adjust the use of BINFO_VIRTUALS
+ here too.
+
+ * cp-tree.h (BINFO_VIRTUALS): Document new format.
+ * class.c (modify_one_vtable): Change prototype accordingly.
+ (modify_all_vtables): Likewise.
+ (modify_all_direct_vtables): Likewise.
+ (modify_all_indirect_vtables): Likewise.
+ (build_vtable_entry_for_fn): New function.
+ (set_rtti_entry): Simplify for new BINFO_VIRTUALS format.
+ (modify_vtable_entry): Likewise.
+ (add_virtual_function): Likewise.
+ (build_vtbl_initializer): New function.
+ (finish_vtbls): Simplify for new BINFO_VIRTUALS format.
+ (fixup_vtable_deltas1): Likewise.
+ (fixup_vtable_deltas): Likewise.
+ (override_one_vtable): Likewise.
+ (finish_struct_1): Likewise.
+
+ * error.c (dump_expr): Likewise.
+ * search.c (get_abstract_virtuals_1): Likewise.
+ (get_abstract_virtuals): Likewise.
+ (expand_upcast_fixups): Likewise.
+ * tree.c (debug_binfo): Likewise.
+ * decl2.c (mark_vtable_entries): Don't bash abstract virtuals to
+ __pure_virtual here.
+
+1999-07-26 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (build_cplus_new): Adjust call to abstract_virtuals_error
+ as per 1999-07-26 change.
+
+ * typeck.c (c_sizeof): Don't allow non-static data members.
+ (expr_sizeof): Likewise.
+
+1999-07-26 Jason Merrill <jason@yorick.cygnus.com>
+
+ * input.c (feed_input): Only touch lineno and input_filename
+ if !USE_CPPLIB. Save the old values before setting the new ones.
+
+ * input.c (feed_input): Add file, line parms.
+ * lex.c (begin_definition_of_inclass_inline, feed_defarg): Adjust.
+ (real_yylex): Check linemode before input_redirected().
+
+ * typeck.c (c_expand_return): Downgrade pedwarn about returning NULL
+ from op new to warning.
+
+1999-07-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (ncp_convert): Rename to perform_implicit_conversion.
+ * call.c: All uses changed.
+ * typeck.c: Likewise.
+
+1999-07-26 Nathan Sidwell <nathan@acm.org>
+
+ * exception.cc (__cplus_type_matcher): Match __eh_matcher
+ prototype.
+
+1999-07-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CP_INTEGRAL_TYPE_P): New macro.
+ (ARITHMETIC_TYPE_P): Adjust definition for standard conformance.
+ (strip_top_quals): Declare.
+ (ncp_convert): Likewise.
+ (type_after_usual_arithmetic_conversions): Likewise.
+ (composite_pointer_type): Likewise.
+ * call.c (strip_top_quals): Don't make it static.
+ (promoted_arithmetic_type_p): New function.
+ (conditional_conversion): Likewise.
+ (null_ptr_cst_p): Allow `false' as a NULL pointer constant.
+ (standard_conversion): Use same_type_p. Don't build BASE_CONVs
+ for converting a type to itself.
+ (reference_binding): Honor LOOKUP_NO_TEMP_BIND.
+ (implicit_conversion): Make sure the from and to types are
+ complete.
+ (add_builtin_candidate): Correct handling of ?: operator.
+ (add_builtin_candidates): Improve documentation.
+ (build_conditional_expr): New function.
+ (can_convert): Implement in terms of can_convert_arg.
+ (ncp_convert): New function.
+ * typeck.c (type_after_usual_arithmetic_conversions): New
+ function, split out from common_type.
+ (composite_pointer_type): New function, split out from
+ build_conditional_expr.
+ (common_type): Use type_after_usual_arithmetic_conversions.
+ Remove redundant attribute merging.
+ (comptypes): Tidy. Handle COMPLEX_TYPE.
+ (build_binary_op_nodefault): Use null_ptr_cst_p.
+ (build_conditional_expr): Remove.
+ (convert_for_assignment): Use new conversion functions.
+
+ * cp-tree.h (abstract_virtuals_error): Change declaration.
+ * typeck2.c (abstract_virtuals_error): Check to see if an error
+ occurred, and return a boolean value accordingly.
+ (build_functional_cast): Adjust accordingly.
+ * class.c (finish_struct_1): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ * decl.c (cp_finish_decl): Likewise.
+ (grokparams): Likewise.
+ (grok_op_properties): Likewise.
+ (start_function): Likewise.
+ * init.c (build_new_1): Likewise.
+
+ * pt.c (unify): Don't get confused by pointers-to-member functions.
+
+ * search.c (build_cplus_new): Robustify.
+
+1999-07-24 Richard Henderson <rth@cygnus.com>
+
+ * gxx.gperf (__builtin_va_arg): New.
+ * parse.y (VA_ARG): New token.
+ (unary_expr): Recognize it.
+
+Sun Jul 25 15:24:21 1999 Jeffrey A Law (law@cygnus.com)
+
+ * g++FAQ.texi: Deleted per Joe Buck's request.
+ * Makefile.in: Corresponding changes.
+
+1999-07-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c: Sync with C frontend.
+ (whitespace_cr): New fn.
+ (skip_white_space): Use it.
+ (init_parse): Reorder.
+ (yyprint): Support CONSTANT.
+ (pragma_getc, pragma_ungetc): Bring back.
+ (read_line_number): Change in_system_header directly.
+ (handle_generic_pragma, handle_cp_pragma, yyerror): Move up in file.
+ (parse_float): Update to C version.
+ (yylex): Handle '$' under the letter case.
+ Remove looking_for_typename handling.
+ Support hex floating point constants.
+ Follow C's lead for choosing type of integer constants.
+ Rearrange stuff to match C frontend.
+ (yyungetc, reinit_parse_for_block, yylex): Support indent_level.
+ * spew.c (yylex): Clear looking_for_typename if we see a TYPESPEC.
+
+1999-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (reference_binding): Tweak.
+ (mayble_handle_implicit_object): Use direct_reference_binding to
+ create the right implicit conversion sequence.
+
+1999-07-22 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (convert_nontype_argument): Don't call decl_constant_value
+ if we're converting to a reference type.
+
+ * call.c (NEED_TEMPORARY_P): New macro.
+ (standard_conversion): Set it, for derived-to-base conversions.
+ (reference_related_p): New function.
+ (reference_compatible_p): Likewise.
+ (convert_class_to_reference): Likewise.
+ (direct_reference_binding): Likewise.
+ (reference_binding): Rework for standards-compliance.
+ (convert_like): Adjust accordingly.
+ (maybe_handle_ref_bind): Simplify; the right conversion sequences
+ are now built up in reference_binding.
+ (initialize_reference): New function.
+ * cp-tree.h (ICS_USER_FLAG): Document.
+ (ICS_THIS_FLAG): Likewise.
+ (ICS_BAD_FLAG): Likewise.
+ (NEED_TEMPORARY_P): Likewise.
+ (cp_lvalue_kind): New type.
+ (real_lvalue_p): Return it.
+ * error.c (dump_expr): Provide more accurate representation for
+ AGGR_INIT_EXPRs.
+ * init.c (expand_default_init): Do not try to perform implicit
+ conversions for a brace-enclosed initializer.
+ * search.c (lookup_conversions): Document.
+ * tree.c (lvalue_p_1): Return a cp_lvalue_kind. Calculate
+ appropriately.
+ (real_lvalue_p): Adjust accordingly.
+ (lvalue_p): Likewise.
+ (build_cplus_new): Don't allow the creation of an abstract class.
+ * typeck.c (convert_for_initialization): Use initialize_reference.
+
+1999-07-21 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * lex.c (real_yylex) : Correct the test for overflow when lexing
+ integer literals.
+
+1999-07-20 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (warn_extern_redeclared_static): Check DECL_ARTIFICIAL,
+ not DECL_BUILT_IN, to determine if a function is internally declared.
+ (duplicate_decls): Likewise. Improve handling of builtins.
+ (push_overloaded_decl): Remove special handling of builtins.
+
+ * cp-tree.h (ANON_AGGR_TYPE_P): Use CLASS_TYPE_P.
+
+ * decl.c (grokdeclarator): Pull out decl_constant_value in
+ templates, too.
+
+ * class.c (finish_struct, finish_struct_1): Remove 'warn_anon' parm.
+ * cp-tree.h, pt.c, semantics.c: Adjust.
+ * method.c (largest_union_member): Remove.
+
+ * lang-specs.h (c++-cpp-output): Pass -fpreprocessed.
+
+ * lex.c (token_getch, token_put_back): New fns.
+ (real_yylex): Use them.
+
+ * lex.c (lang_init): Generalize.
+ (lang_init_options): Tell cpplib this is C++.
+ (nextchar): Remove. Replace uses with put_back.
+ (skip_white_space): Handle linemode here. Optimize for cpplib.
+ (extend_token_buffer_to): New fn.
+ (extend_token_buffer): Use it.
+ (read_line_number, check_newline): Just deal with tokens.
+ (real_yylex): More cpplib optimizations. Simplify. Don't produce
+ EXTERN_LANG_STRING, LEFT_RIGHT or PAREN_STAR_PAREN here.
+ * spew.c (yylex): Produce LEFT_RIGHT and EXTERN_LANG_STRING.
+ * parse.y (PAREN_STAR_PAREN): Remove.
+ * input.c: Don't use the putback machinery with cpplib.
+ (sub_getch): Fold back into getch.
+ (getch): Don't handle linemode here.
+ (feed_input): Unget any text in the token buffer.
+
+ * lex.c (set_typedecl_interface_info, set_vardecl_interface_info,
+ nextyychar, nextyylval): Remove.
+
+1999-07-20 Michael Tiemann <tiemann@holodeck.cygnus.com>
+ Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (indent_level): New variable.
+ (init_parse): Set cpp_token to CPP_DIRECTIVE.
+ (consume_string): Make this smart about USE_CPPLIB.
+ (yyungetc): Use put_back function.
+ (pragma_getc, pragma_ungetc): Functions deleted.
+ (check_newline): Rewrite to be intelligent about USE_CPPLIB.
+ Also, call HANDLE_PRAGMA with getch, yyungetc, not pragma_getc and
+ pragma_ungetc.
+ (real_yylex): Rewrite to be intelligent about USE_CPPLIB.
+ Also, clean up cases where we redundantly set token_buffer[0].
+ (read_line_number): New fn.
+ * input.c (feed_input): Use integrated cpplib if USE_CPPLIB.
+ (end_input): Call cpp_pop_buffer if USE_CPPLIB.
+ (sub_getch): Conditionalize out code that's not appropriate if
+ USE_CPPLIB.
+ (put_back): Rewrite in case USE_CPPLIB is defined.
+ (input_redirected): Ditto.
+
+Tue Jul 20 11:24:19 1999 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * cp-tree.h: Delete lots of declarations of tree nodes; replaced by
+ c_global_trees and accessor macros defined in c-common.h.
+ (cp_tree_index): New enumeration.
+ (cp_global_trees): Declare new array. Add accessor macros for it, and
+ delete declarations of tree nodes replaced by it.
+ (builtin_function): Delete macro, add declaration for new function.
+ Include c-common.h.
+ * decl.c: Delete definitions for tree nodes that were replaced by
+ cp_global_trees and c_global_trees.
+ (init_decl_processing): Call c_common_nodes_and_builtins; delete code
+ to generate the common builtins here.
+ (builtin_function): New function.
+ * decl2.c (abort_fndecl): Delete declaration.
+ * except.c (expand_builtin_return_address): Delete declaration.
+ (builtin_return_address_fndecl): Delete variable.
+ (const_ptr_type_node): Delete declaration.
+ * lex.c (cons_up_default_function): Delete declaration of
+ void_list_node.
+ * parse.y (void_list_node): Delete declaration.
+ * rtti.c (type_info_type_node, tinfo_fn_id, tinfo_fn_type):
+ Delete variables.
+ (const_string_type_node): Delete declaration.
+ * search.c (abort_fndecl): Delete declaration.
+ * Makefile.in: Update dependencies.
+
+1999-07-19 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (check_default_tmpl_args): Move test for missing default
+ arguments here, from ...
+ (end_template_parm_list): Here.
+
+1999-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (lookup_nested_type): Remove.
+ (pushtag): Don't call it.
+
+Sat Jul 17 23:51:30 1999 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (INTERFACE): Bump to 2.
+
+1999-07-17 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * typeck2.c (my_friendly_abort): Updated URL with bug reporting
+ instructions to gcc.gnu.org. Removed e-mail address.
+
+1999-07-17 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (determine_specialization): Tighten error-checking.
+ (end_template_parm_list): Likewise.
+
+1999-07-14 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (check_default_tmpl_args): Handle friends defined in the
+ class just like member functions defined in the class.
+
+1999-07-09 Michael Tiemann <tiemann@happy.cygnus.com>
+ Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (struct lang_decl): Added field for storing sorted
+ FIELD_DECLs (used in TYPE_DECLs).
+ (DECL_PENDING_INLINE_INFO): Adjusted to use 'u' union.
+ (DECL_SORTED_FIELDS): New macro.
+ * class.c (method_name_cmp): New function.
+ (finish_struct_methods): Modified to support sorting and searching
+ methods.
+ (finish_struct_anon): Changed code in inner loop to use ELT rather
+ than UELT (which required an extra indirection for every reference).
+ (field_decl_cmp): New function to support sorting FIELD_DECLs.
+ (finish_struct_1): Sort fields.
+ * search.c (lookup_field_1): Use DECL_SORTED_FIELDS if we have them.
+ (lookup_fnfields_1): Search sorted methods in METHOD_VEC.
+ Also, switch to using array indexing rather than a changing pointer.
+ * ptree.c (print_lang_decl): Handle TYPE_DECLs that have
+ DECL_SORTED_FIELDS.
+
+1999-07-09 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (reparse_absdcl_as_casts): Don't warn about old-style
+ casts in system headers or extern "C" blocks.
+
+ * pt.c (do_decl_instantiation): Downgrade duplicate instantiation
+ errors to pedwarn.
+
+1999-07-09 Michael Tiemann <tiemann@happy.cygnus.com>
+
+ * decl2.c (write_virtuals): Deleted declaration.
+ * cp-tree.h (write_virtuals): Deleted extern declaration.
+ * class.c (finish_struct_1): Removed #if 0'd code that mentions
+ write_virtuals.
+ * semantics.c (begin_class_definition): Rewrite code to not depend
+ on write_virtuals.
+
+ * lex.c (cp_pragma_interface): New function.
+ (cp_pragma_implementation): Likewise.
+ (handle_cp_pragma): Call them.
+
+ * typeck.c (comptypes): Simplify C code in look_hard.
+
+ * xref.c (PALLOC): Use xcalloc, not calloc.
+ (SALLOC): Use xmalloc, not malloc.
+
+ * rtti.c (synthesize_tinfo_fn): Add missing call to pop_momentary.
+
+ * search.c (note_debug_info_needed): Don't search if WRITE_SYMBOLS
+ is NO_DEBUG.
+
+ * decl.c (duplicate_decls): If a redeclaration doesn't match the
+ initial declaration, then don't save the inline info and by all
+ means don't mark the function as a builtin function.
+
+ * decl.c (lookup_name_real): Set NONCLASS to 1 if
+ CURRENT_CLASS_TYPE is 0.
+
+ * class.c (duplicate_tag_error): Set TYPE_NONCOPIED_PARTS to
+ NULL_TREE.
+
+ * ptree.c (print_lang_type): Added vtable-needs-writing.
+
+Wed Jul 7 01:26:47 1999 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * decl2.c (mark_vtable_entries): Fix check for rtti offset.
+
+1999-07-06 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * typeck.c (unsigned_type,signed_type,signed_or_unsigned_type) :
+ Merged into c-common.
+
+1999-07-05 Dave Brolley <brolley@cygnus.com>
+
+ * lex.c (errorcount): Declare it.
+ (finish_parse): Update errorcount for when using CPPLIB.
+
+1999-07-05 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (IS_AGGR_TYPE): Include instantiated template template
+ parameters.
+ (IMPLICIT_TYPENAME_TYPE_DECL_P): New macro.
+ * decl.c (push_class_binding): Use it.
+ (lookup_name_real): Likewise.
+
+1999-07-02 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * cp-tree.h (widest_integer_literal_type_node,
+ widest_unsigned_literal_type) : New.
+ * decl.c (widest_integer_literal_type_node,
+ widest_unsigned_literal_type) : New.
+ (init_decl_processing): Handle/use the two new types.
+ * lex.c (real_yylex): Same.
+ * typeck.c (unsigned_type,signed_type,signed_or_unsigned_type) :
+ Same.
+
+1999-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokdeclarator): Don't give names "for linkage purposes"
+ to anonymous cv-qualified types.
+
+1999-07-01 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * lex.c (real_yylex) : Change integer literal overflow handling to
+ be like c-lex.c.
+
+ * lex.c (real_yylex): Improve 'integer constant out of range' messages.
+
+1999-06-28 Richard Henderson <rth@cygnus.com>
+
+ * decl.c (cp_finish_decl): Fix typo in cp_warning_at call.
+
+1999-06-28 Jason Merrill <jason@yorick.cygnus.com>
+
+ * error.c (dump_type_real): Handle TREE_LIST again.
+
+ * typeck.c (comp_target_parms): Don't complain about
+ converting from () to (...) if !flag_strict_prototype.
+
+ * decl.c (grokdeclarator): Update the names of all variants when
+ de-anonymizing.
+
+1999-06-21 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (expand_aggr_vbase_init): Rename to
+ construct_virtual_bases. Conditionalize construction here,
+ rather than ...
+ (emit_base_init): Here.
+
+1999-06-19 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (finish_asm_stmt): Apply decay conversions to
+ input operands.
+
+ * decl.c (expand_static_init): When building an anonymous function
+ for use with atexit, compute its body before and after entering
+ the function.
+
+ * error.c (dump_expr): Handle BIND_EXPR, LOOP_EXPR, and
+ EXIT_EXPR.
+
+1999-06-18 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (expand_aggr_vbase_init): Add flag parameter.
+ (build_partial_cleanup_for): Remove, inlining into ..
+ (expand_cleanup_for_base): ... here. Take flag parameter.
+ (emit_base_init): Pass the in_chrg parameter to
+ emit_aggr_vbase_init.
+ (emit_aggr_vbase_init): Pass it to expand_cleanup_for_base.
+
+1999-06-16 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (import_export_decl): Use same_type_p, rather than
+ relying on pointer-equality for types.
+
+ * method.c (do_build_copy_constructor): Simplify.
+
+ * call.c (build_method_call): Remove bogus code for two-argument
+ delete.
+ * init.c (build_new_1): Expand on comment, and remove dead code.
+
+ * init.c (expand_cleanup_for_base): New function, split out
+ from ...
+ (emit_base_init): Here.
+ (expand_aggr_vbase_init): Use it.
+
+1999-06-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (class_cache_firstobj): Declare.
+ (maybe_push_cache_obstack): Rename to push_cache_obstack.
+ * class.c (permanent_obstack): Remove declaration.
+ (class_cache_firstobj): Make it global.
+ (add_method): Don't use permanent_obstack directly.
+ (pushclass): Only free the class_cache_obstack if we know how far
+ back to free it.
+ (maybe_push_cache_obstack): Rename to push_cache_obstack.
+ * decl.c: Remove dead comment.
+ (saved_scope): Add class_cache_firstobj.
+ (push_to_top_level): Save it.
+ (pop_from_top_level): Restore it.
+ (push_class_level_binding): Use push_cache_obstack, not
+ maybe_push_cache_obstack.
+ * search.c (push_class_decls): Likewise.
+
+1999-06-14 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * pt.c (tsubst_friend_function): Push into namespace of friend
+ function before pushdecl'ing it.
+
+1999-06-14 Nathan Sidwell <nathan@acm.org>
+
+ * call.c (build_new_op): Remove REF_BIND from all operands.
+
+1999-06-13 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * init.c (build_new_1): Look up operator delete even if there was
+ no explicit new placement.
+
+1999-06-08 Nathan Sidwell <nathan@acm.org>
+
+ * except.c (complete_ptr_ref_or_void_ptr_p): New function, broken out
+ of ...
+ (build_throw): ... here. Call it.
+ (process_start_catch_block): Call it.
+
+1999-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ * search.c (convert_pointer_to_single_level): Reimplement without
+ using get_binfo.
+
+1999-06-06 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (is_back_referenceable_type): Back-reference bools when
+ not squangling.
+
+1999-06-07 Dave Brolley <brolley@cygnus.com>
+
+ * lex.c (real_yylex): Replace unused bytes from bad multibyte char.
+ * input.c (putback_buffer): New structure type.
+ (putback): Replaces putback_char member.
+ (putback): Replaces putback_char static variable.
+ (feed_input): Use putback.
+ (end_input): Use putback.
+ (sub_getch): Use putback.
+ (put_back): Use putback.
+
+1999-06-05 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokdeclarator): Fix typo in last change.
+
+1999-06-04 Jason Merrill <jason@yorick.cygnus.com>
+
+ * semantics.c (finish_if_stmt_cond): Copy cond to permanent_obstack.
+ (finish_while_stmt_cond, finish_do_stmt, finish_for_cond): Likewise.
+
+1999-06-04 Nathan Sidwell <nathan@acm.org>
+
+ * except.c (build_throw): Check throw expression validity.
+
+1999-06-03 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokdeclarator): Don't treat arbitrary types as unsigned
+ just because flag_signed_bitfields is false.
+
+1999-06-03 Nathan Sidwell <nathan@acm.org>
+
+ * semantics.c (begin_class_definition): Update the struct's
+ location here ...
+ * class.c (finish_struct): ... rather than here.
+
+ * decl.c (make_typename_type): Don't rely on uninitialized
+ variable.
+
+1999-05-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (ALL_CFLAGS): Add '-W -Wall'.
+
+1999-05-31 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (build_cplus_array_type_1): Use push_obstacks_nochange
+ and friends rather than messing with current_obstack directly.
+ (cp_build_qualified_type_real): Rework ARRAY_TYPE
+ allocation to match practice throughout the rest of the
+ compiler.
+
+1999-05-30 Mark Mitchell <mark@codesourcery.com>
+
+ * lex.c (make_lang_type): Create TYPE_BINFO for
+ TEMPLATE_TYPE_PARMs just like for non-template types.
+
+ * decl.c (start_decl): Move checks on initialization to ...
+ (cp_finish_decl): Here. Tidy formatting slightly.
+
+1999-05-28 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (add_binding): Don't complain about a redeclaration of a
+ semantically identical typedef in a local scope.
+
+1999-05-28 Nathan Sidwell <nathan@acm.org>
+
+ * decl.c (complete_array_type): Allocate off same obstack. Fix
+ DO_DEFAULT comment to match reality.
+
+ * friend.c (make_friend_class): Fix diagnostic typo.
+
+1999-05-28 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (lookup_namespace_name): Handle getting a
+ TEMPLATE_ID_EXPR.
+ (expand_static_init): Don't call pushdecl for implicitly declared
+ `atexit' used to register destructors.
+
+1999-05-25 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (finish_vtbls): Copy BINFO_VIRTUALs before using it to
+ initialize a vtable.
+
+ * cp-tree.h (NAMESPACE_LEVEL): Reformat.
+ (lang_decl_flags): Document MEMFUNC_POINTER_TO. Save four bytes
+ by combining TEMPLATE_INFO and LEVEL into a single union.
+ (DECL_TEMPLATE_INFO): Reformat.
+ (DECL_SAVED_TREE): Document.
+ (DECL_TEMPLATE_INJECT): Remove.
+ * class.c (finish_struct): Remove code to deal with
+ DECL_TEMPLATE_INJECT.
+
+ * decl.c (maybe_process_template_type_declaration): Handle all new
+ types in templates uniformly.
+ * method.c (bulid_overload_identifier): Use CP_DECL_CONTEXT, not
+ DECL_CONTEXT.
+ * pt.c (lookup_template_class): Inject template instantiations of
+ forward-declarations.
+ (instantiate_class_template): Remove code processing
+ DECL_TEMPLATE_INJECT.
+
+ * pt.c (lookup_template_class): Tweak lookup to find member
+ templates.
+
+ * pt.c (tsubst_expr, case ASM_STMT): Don't tsubst into
+ ASM_CV_QUAL.
+ * semantics.c (finish_asm_stmt): Make strings permanent if they're
+ used in a template.
+
+1999-05-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (casts_away_constness, casts_away_constness_r): Strip both
+ parts of pointer to data member types.
+
+1999-05-24 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (mark_vtable_entries): Don't make a copy of a function,
+ and then make it look like `abort'. Just use `abort' instead.
+
+ * typeck.c (build_static_cast): Don't allow static_casts that cast
+ away constness.
+ (casts_away_constness_r): New function.
+ (casts_away_constness): Likewise.
+
+ * decl.c (lookup_tag): Remove code no longer needed after
+ name-lookup improvements.
+ * decl2.c (handle_class_head): Make error-recovery more robust.
+ * friend.c (make_friend_class): Reject templated typename types.
+ * lex.c (is_global): A template parameter isn't global.
+ * parse.y (class_head): Robustify.
+ * parse.c: Regenerated.
+
+1999-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (for_each_template_parm): Walk into TYPENAME_TYPEs,
+ INDIRECT_REFs, and COMPONENT_REFs. Handle FIELD_DECLs.
+
+ * cp-tree.h (push_nested_namespace): Declare.
+ (pop_nested_namespace): Likewise.
+ * decl.c (push_nested_namespace): New function.
+ (pop_nested_namespace): Likewise.
+ * pt.c (instantiate_class_template): Use them.
+
+ * tree.c (mapcar): Handle NON_LVALUE_EXPR.
+
+ * cp-tree.h (cplus_expand_constant): Declare.
+ * cvt.c (convert_to_pointer): Expand PTRMEM_CSTs when they're
+ converted from one pointer-to-object type to another.
+ * expr.c (cplus_expand_constant): Don't make it static.
+ * typeck.c (build_component_ref): Don't crash when presented with
+ a component which is a TEMPLATE_DECL.
+ (build_ptrmemfunc): Tidy. Clarify comment. Make sure that even a
+ cast from a pointer-to-member constant to its own type does not
+ result in a valid non-type template argument.
+
+1999-05-21 Mark Mitchell <mark@codesourcery.com>
+ Nathan Sidwell <nathan@acm.org>
+
+ * Make-lang.in (cc1plus): Make it depend on gxx.gperf.
+ * cp-tree.h: Fix typo in documentation on pointers-to-members.
+ (cp_build_qualified_type): Make it a macro.
+ (cp_build_qualified_type_real): Declare.
+ * decl.c (grokdeclarator): Remove misleading comment. Avoid
+ problem with template parameters and restrict-qualification.
+ * gxx.gperf: Replace NORID with RID_UNUSED throughout.
+ * hash.h: Regenerated.
+ * lex.h (rid): Move RID_FIRST_MODIFIER and RID_LAST_MODIFIER into
+ the enumeration.
+ (NORID): Remove definition.
+ * pt.c (tsubst_aggr_type): Use cp_build_qualified_type_real.
+ (tsubst): Likewise. Remove special handling for FUNCTION_TYPEs.
+ (fn_type_unification): Check that the function type resulting from
+ the deduction is legal.
+ (check_cv_quals_for_unify): Don't handle FUNCTION_TYPEs specially.
+ (unify): Use cp_build_qualified_type_real.
+ * tree.c (build_cplus_array_type_1): Handle error_marks as inputs.
+ (cp_build_qualified_type): Rename to ...
+ (cp_build_qualified_type_real): Add additional COMPLAIN parameter
+ and modify appropriately.
+
+ * typeck.c (build_ptrmemfunc): Handle PTRMEM_CSTs carefully to
+ reveal optimization opportunities.
+
+ * pt.c (tsubst): Don't issue error messages when we're not
+ complaining, even if we see a qualified function type.
+ (check_cv_quals_for_unify): Don't allow a qualified function
+ type.
+
+1999-05-20 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (instantiate_type): Downgrade errors for object-dependent
+ memfn refs to pedwarn.
+
+1999-05-20 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokdeclarator): Don't treat [] as indicating a
+ zero-sized array in a typedef.
+
+ * call.c (build_object_call): Don't look at DECL_NAME for a type.
+ (pt.c): Or CP_TYPE_QUALS for an ERROR_MARK.
+ (typeck.c): Or TYPE_MAIN_VARIANT for a type.
+
+ * pt.c (for_each_template_parm): Rework to match documentation.
+ Don't be fooled by a COMPONENT_REF with no TREE_TYPE.
+
+1999-05-20 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_1): Still check for ANON_AGGR_TYPE_P.
+
+ * class.c (finish_base_struct): Allow non-COM bases for COM classes
+ except at the leftmost position.
+ (modify_one_vtable, fixup_vtable_deltas1, override_one_vtable):
+ Pass the binfo's class, not the most derived, to skip_rtti_stuff.
+ * search.c (get_abstract_virtuals, expand_upcast_fixups): Likewise.
+
+ * tree.c (lvalue_p_1): A NOP_EXPR can be an lvalue.
+ (build_cplus_new): Make sure that what we return is of the right type.
+
+1999-05-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (make_ptrmem_cst): New function.
+ * expr.c (cplus_expand_constant): Split out from ...
+ (cplus_expand_expr): Here. Use cplus_expand_constant.
+ (init_cplus_expand): Set lang_expand_constant.
+ * pt.c (convert_nontype_argument): Use make_ptrmem_cst.
+
+ * tree.c (make_ptrmem_cst): Define.
+ * typeck.c (unary_complex_lvalue): Use make_ptrmem_cst.
+ * typeck2.c (initializer_constant_valid_p): Use make_ptrmem_cst.
+
+1999-05-19 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (build_template_decl): Copy DECL_NONCONVERTING_P.
+
+ * decl2.c (start_static_storage_duration_function): Fix comment.
+ (finish_file): Create static storage duration functions lazily.
+
+1999-05-19 Jason Merrill <jason@yorick.cygnus.com>
+
+ Implement anonymous structs.
+ * cp-tree.h (ANON_AGGR_TYPE_P): Rename from ANON_UNION_TYPE_P.
+ * class.c, decl.c, decl2.c, init.c, pt.c, search.c, typeck.c: Adjust.
+ * class.c (finish_struct_1): Remove redundant check for anon struct.
+ * decl.c (fixup_anonymous_aggr): Renamed from fixup_anonymous_union.
+ (check_tag_decl): Check for anonymous struct here.
+ * decl2.c (build_anon_union_vars): Catch anon struct at file scope.
+ * init.c (sort_member_init, emit_base_init): Handle getting fields
+ as well as names in current_member_init_list.
+ (perform_member_init): Handle getting an anon aggr.
+ * method.c (do_build_assign_ref): Don't descend into anon aggrs.
+ (do_build_copy_constructor): Likewise.
+
+1999-05-19 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (cp_build_qualified_type): Don't allow qualified function
+ types.
+
+Wed May 19 02:50:53 1999 Arvind Sankar <arvinds@mit.edu>
+
+ * gxxint.texi: Fix typo.
+
+1999-05-19 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (find_scoped_type, resolve_scope_to_name): Lose.
+ * class.c (finish_struct_1): Use CLASS_TYPE_P.
+ * ptree.c (print_lang_type): Likewise.
+ * typeck.c (build_modify_expr, c_expand_asm_operands): Use
+ IS_AGGR_TYPE_CODE.
+ * typeck2.c (digest_init): Likewise.
+
+1999-05-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (joust): Compare the types of the conv ops, not the
+ target types of the conversions.
+
+Tue May 18 00:21:34 1999 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * lang-specs.h: Define __GNUC__ and __GNUC_MINOR__ only if -no-gcc
+ was not given.
+
+1999-05-17 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (TEMPLATE_ID_EXPR): Update documentation.
+ * decl.c (grokfndecl): Don't allow inline declarations of friend
+ template specializations, or friend template specializations with
+ default arguments.
+ * pt.c (tsubst): Handle substitution into array types that does
+ not yield a fixed upper bound, even when not processing a
+ template.
+ (tsubst_copy): Deal with the fact that the second operand to a
+ TEMPLATE_ID_EXPR may be NULL_TREE, a TREE_LIST, or a TREE_VEC.
+ * search.c (marked_pushdecls_p): Don't descend into
+ TEMPLATE_TYPE_PARMs and the like.
+ (unmarked_pushdecls_p): Likewise.
+
+ * call.c (build_over_call): Don't throw away
+ initializations/copies of empty classes; use MODIFY_EXPR and
+ INIT_EXPR as for non-empty classes.
+ * class.c (finish_struct_1): Put the padding byte for an empty
+ class on the TYPE_NONCOPIED_PARTS list for the class.
+
+1999-05-16 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (build_expr_from_tree): Handle COMPONENT_REFs that
+ indicate a reference to a field that is a qualified name.
+
+1999-05-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_objects): Don't use .?tors.* if we don't have
+ ASM_OUTPUT_CONSTRUCTOR.
+
+ * friend.c (do_friend): Add attrlist arg. Remove support for
+ getting a non-decl as 'decl'.
+ * decl.c (grokfndecl): Remove attrlist arg. Don't set attrs or
+ rtl.
+ (grokdeclarator): Adjust.
+ * cp-tree.h: Adjust.
+
+1999-05-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (permanent_p): New function.
+ * init.c (build_new_1): Use mapcar, not copy_node, to copy a
+ possibly complex tree node.
+ * tree.c (mapcar): Adjust comments, and follow coding standards in
+ conditional.
+ (permanent_p): New function.
+
+1999-05-13 Per Bothner <bothner@cygnus.com>
+
+ * class.c (push_lang_context): Turn off DECL_IGNORED_P for
+ primitive Java types, if we actually see `extern "Java"'.
+
+1999-05-10 18:21 -0400 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * lang-specs.h: Pass -$ to the preprocessor.
+
+1999-05-10 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_offset_ref): Wrap baselinks in OFFSET_REF, too.
+ Don't bother wrapping an OFFSET_TYPE around unknown_type_node.
+ (resolve_offset_ref): Don't handle a raw baselink.
+ * cvt.c (build_expr_type_conversion): Likewise.
+ * typeck.c (decay_conversion, build_c_cast, convert_for_assignment,
+ convert_for_initialization): Likewise.
+ * class.c (instantiate_type): Handle seeing a baselink under an
+ OFFSET_REF.
+ * error.c (dump_expr): Likewise.
+ * pt.c (for_each_template_parm): Likewise.
+ (resolve_overloaded_unification): Likewise.
+ * tree.c (is_overloaded_fn, really_overloaded_fn): Likewise.
+ * typeck.c (expr_sizeof): Also complain about other permutations
+ of overloaded functions.
+
+1999-05-07 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (resolve_offset_ref): Don't return a raw method.
+ Use BASELINK_P.
+ * typeck.c (decay_conversion): Don't handle a raw method.
+ Resolve all OFFSET_REFs.
+ (get_member_function_from_ptrfunc): 0 is a valid vtable index.
+ (build_binary_op_nodefault): Handle resolving overloaded fns. Use
+ same_type_p for pmf bits. Don't use build_binary_op to compare
+ raw pointers to methods.
+ (convert_for_assignment): Check for OFFSET_REF, not OFFSET_TYPE,
+ to decide when to call resolve_offset_ref.
+ (build_c_cast, convert_for_initialization): Likewise.
+ * cvt.c (build_expr_type_conversion): Likewise.
+
+1999-05-06 Nathan Sidwell <nathan@acm.org>
+
+ * call.c (build_new_method_call): Use TYPE_MAIN_VARIANT of class.
+
+1999-05-05 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (start_objects): Don't let static constructors and
+ destructors get inlined.
+
+ * parse.y (nested_name_specifier): Make sure ordinary types are
+ complete, just like template types.
+ * parse.c: Regenerated.
+
+ * pt.c (check_explicit_specialization): Improve error messages.
+
+1999-05-04 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * typeck.c (string_conv_p): Use same_type_p to check whether we
+ try to convert between char and wchar_t.
+
+1999-05-03 Mark Mitchell <mark@codesourcery.com>
+
+ * search.c (lookup_field_r): Set the TREE_TYPE of an ambiguous
+ lookup to error_mark_node here.
+ (lookup_member): Revise documentation. Add comments. Don't set
+ the TREE_TYPE to error_mark_node here, and don't build up an extra
+ TREE_LIST for ambiguous lookups.
+ (setup_class_bindings): Adjust accordingly.
+ (push_class_decls): Revise out-of-date comments.
+
+ * typeck.c (build_const_cast): Tighten checks for legality.
+
+1999-05-02 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * init.c (build_member_call): Lookup names coming from
+ namespace-scoped LOOKUP_EXPR.
+
+1999-05-03 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gxxint.texi: Add documentation for 'I'.
+
+1999-05-02 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * tinfo.cc (operator==): Qualify type_info with std::.
+
+1999-05-02 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Remove comdat. Updated dummy.
+ (DECL_COMDAT): Remove definition.
+
+1999-05-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (wrapup_globals_for_namespace): Fix thinko in previous
+ change.
+
+1999-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable): Use build_lang_decl when building
+ vtables, not just build_decl.
+ (prepare_fresh_vtable): Likewise.
+ * decl.c (wrapup_globals_for_namespace): Mark vtables as
+ DECL_EXTERNAL when calling wrapup_global_declarations.
+ * decl2.c (priority_info_s): Add initializations_p and
+ destructions_p members.
+ (finish_vtable_vardecl): Use TREE_SYMBOL_REFERENCED, not TREE_USED,
+ when deciding what vtables to write out.
+ (ssdf_decls): New variable.
+ (ssdf_decls_used): Likewise.
+ (start_static_storage_duration_function): Deal with being called
+ multiple times. Avoid inlining this function.
+ (generate_inits_for_priority): Deal with reuse of priority map.
+ (get_priority_info): Clear initializations_p and destructions_p.
+ (do_static_initialization): Tweak comment.
+ (do_static_destruction): Likewise. Fix condition on sentries for
+ destruction.
+ (generate_ctor_or_dtor_function): Call all of the static storage
+ duration functions.
+ (generate_ctor_or_dtor_function_for_priority): Check
+ initializations_p and destructions_p to see what priorities need
+ initialization functions.
+ (finish_file): Rework to generate multiple static storage duration
+ functions, rather than just one.
+
+ * typeck.c (build_const_cast): Tweak last change to handle
+ templates correctly.
+
+ * typeck.c (build_const_cast): Disallow use of const_cast to
+ anything but a pointer or reference type.
+
+1999-04-30 Nathan Sidwell <nathan@acm.org>
+
+ * decl.c (cp_finish_decl): Don't permit arrays of abstract or
+ signature type.
+
+1999-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (do_static_destruction): Remove obsolete FIXME comment.
+ (finish_file): Indent comments properly.
+
+1999-04-29 Richard Henderson <rth@cygnus.com>
+
+ * decl2.c (do_static_initialization): Call do_pending_stack_adjust.
+ (do_static_destruction): Likewise.
+
+1999-04-29 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (TYPE_NOTHROW_P): New macro.
+ * decl2.c (delete_sanity): Warn on deleting void *.
+ * init.c (build_new_1): Use TYPE_NOTHROW_P.
+ * typeck.c (c_expand_return): cp_pedwarn on returning NULL from
+ throwing operator new.
+
+1999-04-28 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (build_component_addr): Remove prototype.
+ * typeck.c (build_component_addr): Make static. Remove MSG
+ argument.
+ (build_component_addr): Remove MSG parameter, clean up
+ comment.
+ (build_x_function_call): Use cp_error.
+ (build_unary_op): Adjust call of build_component_addr.
+
+1999-04-28 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_friend_class): Check for NULL.
+
+Wed Apr 28 11:42:22 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * search.c (binfo_for_vtable): Initialize bfvi.var.
+
+1999-04-27 Nathan Sidwell <nathan@acm.org>
+
+ * rtti.c (build_x_typeid): Check rtti is enabled.
+
+1999-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ * search.c (is_subobject_of_p): Make sure we're looking at the
+ right baseclasses.
+
+1999-04-26 Marc Espie <espie@cvs.openbsd.org>
+
+ * Make-lang.in (cplib2.ready): Don't depend on phony targets.
+
+1999-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_file): Tweak handling of extern inlines so that
+ they are not unnecessarily put out.
+
+ * search.c (is_subobject_of_p): Handle TEMPLATE_TYPE_PARMs and
+ such as base classes.
+
+1999-04-22 Brendan Kehoe <brendan@cygnus.com>
+
+ * tree.c (build_exception_variant): Fix typo: use the chain of U,
+ not trying V, while cycling through U.
+
+1999-04-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Remove returns_first_arg and
+ preserves_first_arg. Enlarge dummy accordingly.
+ (DECL_TINFO_FN_P): New macro.
+ (SET_DECL_TINFO_FN_P): Likeiwse.
+ (DECL_RETURNS_FIRST_ARG): Remove.
+ (DECL_PRESERVES_THIS): Likewise.
+ (DECL_INIT_PRIORITY): New macro.
+ (finish_struct_1): Change prototype.
+ (cat_namespace_levels): Remove prototype.
+ (vtable_decl_p): New prototype.
+ (vtype_decl_p): Likewise.
+ (sigtable_decl_p): Likewise.
+ (walk_globals_pred): New typedef.
+ (walk_globals_fn): Likewise.
+ (walk_globals): New prototype.
+ (walk_namespaces_fn): New typedef.
+ (walk_namespaces): New prototype.
+ (wrapup_globals_for_namespace): Likewise.
+ (walk_vtables): Remove prototype.
+ (walk_sigtables): Likewise.
+ (instantiate_pending_templates): New prototype.
+ * class.c (finish_struct_1): Don't return a value.
+ * decl.h (pending_statics): Remove declaration.
+ * decl.c (walk_namespaces_r): New function.
+ (walk_globals_r): Likewise.
+ (vtable_decl_p): Likewise.
+ (vtype_decl_p): Likewise.
+ (sigtable_decl_p): Likewise.
+ (walk_namespaces): Likewise.
+ (walk_globals_data): New type.
+ (walk_globals): New function.
+ (wrapup_globals_for_namespace): Likewise.
+ (expand_static_init): Remove assertion. Remove redundancy in
+ conditional. Don't put static data members in static_aggregates
+ Tidy.
+ (finish_function): Remove redundancy in conditional. Don't set
+ DECL_RETURNS_FIRST_ARG.
+ (cat_namespace_levels): Remove.
+ * decl2.c: Include splay-tree.h and varray.h.
+ (priority_info_s): New structure.
+ (finish_vtable_vardecl): Change prototype. Adjust for new calling
+ conventions.
+ (prune_vtable_vardecl): Likewise.
+ (finish_sigtable_vardecl): Likewise.
+ (setup_initp): Remove.
+ (do_dtors): Remove.
+ (do_ctors): Remove.
+ (start_static_storage_duration_function): New function.
+ (generate_inits_for_priority): Likewise.
+ (finish_static_storage_duration_function): Likewise.
+ (get_priority_info): Likewise.
+ (do_static_initialization): Likewise.
+ (do_static_destruction): Likewise.
+ (do_static_initialization_and_destruction): Likewise.
+ (generate_ctor_or_dtor_function): Likewise.
+ (generate_ctor_and_dtor_functions_for_priority): Likewise.
+ (pending_statics): Make it a varray.
+ (pending_statics_used): New variable.
+ (saved_inlines): Make it a varray.
+ (saved_inlines_used): New variable.
+ (finish_static_data_member): Change method of updating
+ pending_statics.
+ (mark_inline_for_output): Remove #if 0'd code. Change method of
+ updating saved_inlines.
+ (walk_vtables): Remove.
+ (walk_sigtables): Likewise.
+ (import_export_decl): Use DECL_TINFO_FN_P.
+ (pending_templates): Remove declaration.
+ (maybe_templates): Likewise.
+ (static_aggregates_initp): Likewise.
+ (setup_initp): Likewise.
+ (finish_objects): Simplify.
+ (INITIALIZE_P_IDENTIFIER): New macro.
+ (PRIORITY_IDENTIFIER): New macro.
+ (SSDF_IDENTIFIER): New macro.
+ (initialize_p_decl): New variable.
+ (priority_decl): Likewise.
+ (ssdf_decl): Likewise.
+ (priority_info_map): Likewise.
+ (finish_file): Recode output of static intializers and other
+ file-scope finalization tasks.
+ * error.c (OB_END_TEMPLATE_ID): New macro.
+ (dump_type_real): Use it.
+ (dump_decl): Likewise.
+ (dump_function_name): Likewise.
+ * lex.c (set_typedecl_interface_info): Adjust for new walk_globals
+ interface.
+ (check_newline): Use walk_globals, not walk_vtables.
+ * pt.c (pending_tempalte_expansions): Remove.
+ (set_vardecl_interface_info): Likewise.
+ (pending_templates): Make static.
+ (maybe_templates): Likewise.
+ (instantiate_class_template): Adjust call to finish_struct_1.
+ (instantiate_pending_templates): New function.
+ * rtti.c (get_tinfo_fn): Use SET_DECL_TINFO_FN_P.
+ * tree.c (static_aggregates_initp): Remove.
+ (cp_valid_lang_attribute): Don't use it; use DECL_INIT_PRIORITY
+ instead.
+ * Makefile.in (decl2.o): Depend on varray.h and splay-tree.h.
+
+ * gxx.gperf (RETURN): Rename to RETURN_KEYWORD to avoid clashes
+ with the RTL code RETURN.
+ * hash.h: Regenerated.
+ * lex.c (reinit_parse_for_block): Use RETURN_KEYWORD.
+ * parse.y: Replace RETURN with RETURN_KEYWORD throughout.
+ * parse.c: Regenerated.
+ * pt.c: Include varray.h. Include rtl.h since varray.h requires
+ it.
+ (inline_parm_levels): New variable.
+ (inline_parm_levels_used): Likewise.
+ (maybe_begin_member_template_processing): Update them.
+ (maybe_end_member_template_processing): Use them, rather than
+ guessing how many levels to pop.
+
+ * decl.c (make_typename_type): Tighten error-checking.
+
+1999-04-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (build_binary_op): Remove unneeded parameter.
+ * class.c (build_vrable_entry_ref): Adjust call to
+ build_binary_op.
+ * decl.c (expand_static_init): Likewise.
+ (grokdeclarator): Likewise.
+ (finish_function): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+ (do_dtors): Likewise.
+ (do_ctors): Likewise.
+ * error.c (dump_type_suffix): Likewise.
+ * expr.c (cplus_expand_expr): Likewise.
+ * init.c (resolve_offset_ref): Likewise.
+ (build_new): Likewise.
+ (build_new_1): Likewise.
+ (build_vec_delete_1): Likewise.
+ (expand_vec_init_catch_clause): Likewise.
+ (build_delete): Likewise.
+ * pt.c (tsubst): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Likewise.
+ * search.c (expand_upcast_fixups): Likewise.
+ (expand_direct_vtbls_init): Likewise.
+ * typeck.c (get_member_function_from_ptrfunc): Likewise.
+ (build_binary_op_nodefault): Likewise.
+ (point_int_sum): Likewise.
+ (pointer_diff): Likewise.
+ (build_unary_op): Likewise.
+ (build_modify_expr): Likewise.
+ (get_delta_difference): Likewise.
+ (build_ptrmemfunc): Likewise.
+ (expand_ptrmemfunc_cst): Likewise.
+
+1999-04-20 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokfndecl): Always call cplus_decl_attributes.
+ * decl2.c (grokfield): Pass attrlist to grokdeclarator.
+
+1999-04-19 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (finish_static_data_member_decl): New function.
+ * decl2.c (finish_static_data_member_decl): Split out from ...
+ (grokfield): Here.
+ * pt.c (instantiate_class_template): Use it here instead of
+ trying to fake it.
+ (tsubst_decl): Don't set DECL_ASSEMBLER_NAME;
+ finish_static_data_member_decl will do that. Explicit set
+ DECL_EXTERNAL to match non-template processing.
+
+1999-04-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (finish_class_definition): Add parameter.
+ * parse.y (structsp): Use it. Don't call pop_scope here.
+ * parse.c: Regenerated.
+ * semantics.c (finish_class_definition): Pop it here.
+
+1999-04-17 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (xref_tag): Revise handling of nested template
+ declarations.
+ * pt.c (check_explicit_specialization): Tweak handling of friend
+ templates in template classes.
+ (tsubst_friend_class): Handle friend declarations for nested
+ member template classes.
+
+1999-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (finish_struct): Remove unused variable.
+ (pushclass): Likewise.
+ (invalidate_class_lookup_cache): Likewise.
+ * cp-tree.def (TYPENAME_TYPE): Improve documentation.
+ * decl.c (build_typename_type): Make sure TYPENAME_TYPE_FULLNAME
+ doesn't get obliterated.
+ (make_typename_type): Handle template classes correctly.
+
+ * cp-tree.h (TREE_NONLOCAL_FLAG): Remove.
+ (storetags): Declare.
+ * class.c (finish_struct): Don't use TREE_NONLOCAL_FLAG.
+ (pushclass): Likewise. Use storetags to install tag declarations,
+ not pushtag.
+ (invalidate_class_lookup_cache): Don't use TREE_NONLOCAL_FLAG.
+ * decl.c (storetags): Make it global.
+ (push_class_binding): Set INHERITED_VALUE_BINDING_P for an
+ implicit typename declaration.
+ (pushtag): Tidy. Don't use TREE_NONLOCAL_FLAG.
+ * method.c (hack_identifier): Likewise.
+ * search.c (lookup_member): Likewise.
+
+ * decl.c (warn_about_implicit_typename_lookup): New function.
+ (lookup_name_real): Use it. Rework handling of implicit typename
+ extension.
+
+1999-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lookup_nested_field): Remove.
+ * class.c (push_nested_class): Handle UNION_TYPEs.
+ (pop_nested_class): Likewise.
+ * decl.c (lookup_name_real): Don't call lookup_nested_field.
+ (start_decl): Use push_nested_class, not just pushclass.
+ (cp_finish_decl): Use pop_nested_class, not just popclass.
+ * search.c (lookup_nested_field): Remove.
+
+ * cp-tree.h (lang_type): Add documentation.
+ * decl2.c (handle_class_head): Create template declarations here,
+ as appropriate.
+ * parse.y (class_head): Return whether or not we entered a new
+ scope, as well as the type named.
+ (named_class_head): Likewise.
+ (named_complex_class_head_sans_basetype): Likewise.
+ (structsp): Adjust accordingly. Pop scope when required.
+ * parse.c: Regenerated.
+ * pt.c (check_default_tmpl_args): Robustify.
+ (redeclare_class_template): Likewise.
+ (instantiate_class_template): An instantiation of an
+ anonymous union is itself an anonymous union.
+ * semantics.c (begin_class_definition): Don't create template
+ declarations here.
+
+1999-04-15 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (after_type_declarator_intern): New nonterminal.
+ (after_type_declarator): Use it.
+ (direct_after_type_declarator): Likewise. Move above
+ nonnested_type to fix reduce/reduce conflict resolution.
+ (declmods): Reducing from just 'attributes' has EMPTY precedence.
+ * Makefile.in (CONFLICTS): Update.
+
+ * decl.c (define_label): Downgrade error for jumping over a
+ non-POD decl to pedwarn.
+
+1999-04-14 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (popclass): Change declaration.
+ (pop_nested_class): Likewise.
+ (poplevel_class): Remove declaration.
+ * call.c (convert_default_argument): Pass no arguments to
+ popclass.
+ * class.c (finish_struct_1): Likewise.
+ (finish_struct): Likewise.
+ (popclass): Remove argument. Simplify code accordingly.
+ (pop_nested_class): Likewise.
+ * decl.c (poplevel_class): Declare it here, and make it static.
+ (poplevel): Handle class scopes.
+ (poplevel_class): Don't take an rgument. Simplify.
+ (pop_everything): Pass no arguments to pop_nested_class.
+ (cp_finish_decl): Pass no arguments to popclass.
+ (grokdeclarator): Pass no arguments to pop_nested_class.
+ (finish_function): Likewise.
+ * decl2.c (grokfield): Likewise.
+ (pop_scope): Pass no arguments to popclass.
+ * lex.c (do_pending_defargs): Pass no arguments to pop_nested_class.
+ * pt.c (instantiate_class_template): Move call to pushclass, and
+ document. Pass no arguments to popclass.
+ (regenerate_decl_from_template): Likewise.
+
+1999-04-14 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_unary_op): Handle taking the address of a unique
+ bound non-static member function.
+
+1999-04-13 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * lang-options.h (-Wdeprecated): New flag.
+ * decl2.c (warn_deprecated): New flag.
+ (lang_decode_option): Deprecated this-is-variable,
+ external-templates, alt-external-templates.
+ Support -Wdeprecated.
+ * errfn.c (cp_deprecated): New function.
+
+1999-04-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (setup_initp): Compare DECL_ASSEMBLER_NAME instead
+ of the decls themselves.
+
+ * pt.c (tsubst_function_type): Copy attributes over.
+
+ * tree.c (cp_valid_lang_attribute): New fn. Handle init_priority
+ and com_interface.
+ * cp-tree.h: Add prototype.
+ * decl.c (init_decl_processing): Set valid_lang_attribute.
+
+1999-04-13 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (finish_struct_1): Look at the const-ness of the field's
+ type, not the TREE_READONLY-ness of the declaration.
+ * method.c (synthesize_method): Likewise.
+ * pt.c (tsubst_decl): Call c_apply_type_quals_to_decl when
+ creating new declarations.
+
+1999-04-13 Mike Stump <mrs@wrs.com>
+
+ * decl2.c (import_export_decl): Because vtables always reference
+ virtual functions, even if they are inlined, don't allow
+ -fno-implement-inlines to not emit them, instead, emit them with
+ the vtable.
+ * decl.c (start_function): Likewise.
+
+1999-04-12 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (struct lang_type): Add com_interface.
+ (CLASSTYPE_COM_INTERFACE): New macro.
+ * class.c (set_rtti_entry): COM interface classes have no RTTI
+ entries in their vtables; adjust.
+ (add_virtual_function, finish_base_struct, skip_rtti_stuff,
+ modify_one_vtable, fixup_vtable_deltas1, override_one_vtable,
+ finish_struct_1): Likewise.
+ * decl2.c (mark_vtable_entries): Likewise.
+ * rtti.c (build_headof, get_tinfo_fn_dynamic): Likewise.
+ * search.c (get_abstract_virtuals_1, get_abstract_virtuals,
+ expand_upcast_fixups): Likewise.
+ * tree.c (debug_binfo): Likewise.
+
+ * cp-tree.h (COMPARE_NO_ATTRIBUTES): New macro.
+ * typeck.c (comptypes): If we get it, ignore attributes.
+ * class.c (instantiate_type): Use BASELINK_P. Change complain
+ parameter to flags; 2 means ignore attributes.
+ * call.c (build_op_delete_call): Pass it.
+
+ * decl.c (xref_tag): Only complain once about using a typedef-name
+ with 'struct'. Downgrade to pedwarn.
+
+ * decl.c (grokdeclarator): Allow [] syntax for zero-length array.
+
+ * parse.y (absdcl_intern): New nonterminal.
+ (absdcl, direct_abstract_declarator): Use it.
+
+ * pt.c (lookup_template_class): Look through implict typename.
+
+1999-04-11 Mark Mitchell <mark@codesourcery.com>
+
+ * friend.c (add_friend): Deal gracefully with error_mark_node.
+ * method.c (build_overload_value): Handle pointers-to-members as
+ template parameters.
+
+ * decl.c (push_binding): Fix typo in comment.
+
+1999-04-10 Mark Mitchell <mark@codesourcery.com>
+
+ * error.c (dump_type_real): If a typename is a template-id, put
+ out the template arguments.
+ (dump_expr): Handle TEMPLATE_ID_EXPR.
+ * pt.c (lookup_template_class): Now that full arguments are
+ available everywhere, remove code that tried to guess them.
+
+1999-04-09 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (make_typename_type): Complain if we don't find a type
+ when trying to make a typename type for a non-template type.
+
+1999-04-09 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_decl): Pass attributes to grokdeclarator.
+ (grokdeclarator): Handle attributes on constructor-syntax
+ initializers.
+
+1999-04-08 Mark Mitchell <mark@codesourcery.com>
+
+ * error.c (dump_expr): Don't crash on INDIRECT_REFs whose operands
+ don't have types.
+
+ * search.c (template_self_reference_p): Tweak.
+
+1999-04-07 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (build_offset_ref): Don't build yet another weird data
+ structure to describe overloaded functions.
+
+1999-04-06 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BASELINK_P): New macro.
+ (SET_BASELINK_P): Likewise.
+ * init.c (build_member_call): Remove needless assignment in if
+ statement.
+ * search.c (lookup_field_r): Fix handling when we are looking
+ specifically for a type; these are not hidden by functions and
+ variables.
+ (lookup_member): Use SET_BASELINK_P.
+ * tree.c (is_overloaded_fn): Use BASELINK_P.
+ (really_overloaed_fn): Likewise.
+ (get_first_fn): Likewise.
+
+1999-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (lookup_name_current_level): Tweak, and improve
+ documentation.
+
+ * class.c (maybe_fixup_vptrs): Remove declaration.
+ (build_class_init_list): Likewise.
+ * decl.c (pushdecl_class_level): Call check_template_shadow here
+ ...
+ (push_class_level_binding): ... not here.
+ * search.c (dfs_push_type_decls): Only avoid
+ template-self-reference TYPE_DECLs if they are from base classes.
+
+1999-04-04 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (check_template_shadow): Don't treat OVERLOADs as _DECL
+ nodes. Tidy.
+
+1999-04-03 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (maybe_fixup_vptrs, build_class_init_list): Lose.
+ (finish_struct_1): Don't call build_class_init_list.
+
+1999-04-02 Mark Mitchell <mark@codesourcery.com>
+
+ * tinfo.h (__class_type_info): Fix illegal declaration.
+
+ * cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
+ * cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
+ (IDENTIFIER_CLASS_VALUE): Improve documentation.
+ (is_properly_derived_from): Declare.
+ (invalidate_class_lookup_cache): Likewise.
+ (maybe_maybe_note_name_used_in_class): Likewise.
+ (note_name_declared_in_class): Likewise.
+ (push_using_decl): Remove duplicate declaration.
+ (id_in_current_class): Remove declaration.
+ (push_class_binding): Change prototype.
+ (clear_identitifer_class_values): Declare.
+ * call.c (is_properly_derived_from): Make it global.
+ (build_new_function_call): Be careful about updating candidates.
+ (build_new_method_call): Handle COMPONENT_REFs. Don't crash when
+ asked to make illegal calls.
+ * class.c: Include splay-tree.h.
+ (class_stack_node): Add names_used slot.
+ (check_member_decl_is_same_in_complete_scope): Remove.
+ (add_method): Fix comment. Push the declaration into class
+ scope.
+ (finish_struct_1): When popping the class, pop the bindings too.
+ Remove check for data member/function member conflict.
+ (finish_struct): Remove calls to
+ check_member_decl_is_same_in_complete_scope. Change calls to
+ popclass.
+ (pushclass): Clear names_used in the class stack entry.
+ Use invalidate_class_lookup_cache to remove cached entries, rather
+ than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
+ before entering a new class. Remove dead code. Don't mess with
+ current_function_decl when pushing declarations.
+ (invalidate_class_lookup_cache): New function, split out from ...
+ (popclass): Here. Clean up names_used on our way out.
+ (instantiate_type): Adjust.
+ (build_self_reference): Don't push the declaration here.
+ (maybe_note_name_used_in_class): New function.
+ (note_name_declared_in_class): Likewise.
+ * decl.c (add_binding): Change prototype.
+ (find_class_binding_level): New function.
+ (innermost_nonclass_level): Likewise.
+ (current_binding_level): Update documentation.
+ (inner_binding_level): Remove. Replace with current_binding_level
+ throughout.
+ (push_binding_level): Remove special handling of
+ class_binding_level.
+ (pop_binding_level): Likewise. Use find_class_binding_level.
+ (suspend_binding_level): Likewise.
+ (global_bindings_p): Use innermost_nonclass_level.
+ (toplevel_bindings_p): Likewise.
+ (namespace_bindings_p): Likewise.
+ (pseudo_global_level_p): Likewise.
+ (push_binding): Clear INHERITED_VALUE_BINDING_P.
+ (add_binding): Check for illegal multiple declarations. Return a
+ value indicating whether or not the new binding was legal.
+ (push_local_binding): Skip over class binding levels. Check
+ return value from add_binding.
+ (push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
+ note_name_declared_in_class.
+ (pushlevel_class): Remove "fake out the rest of the compiler"
+ code.
+ (poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
+ (clear_identifier_class_values): New function.
+ (pop_from_top_level): Use it.
+ (pop_everything): Tweak.
+ (maybe_process_template_type_declaration): Don't push the
+ declaration for the template here.
+ (pushtag): Don't push tag declarations into class scope here.
+ (pushdecl): Apply DeMorgan's law for readability.
+ (pushdecl_class_level): Remove special-case code for
+ TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
+ (push_class_level_bindng): Deal with inherited bindings.
+ (lookup_name_real): Remove special-case code for
+ TYPE_BEING_DEFINED, and some implicit typename magic.
+ (grokdeclarator): Handle COMPONENT_REF for a template function.
+ (build_enumerator): Don't call pushdecl_class_level here.
+ (id_in_current_class): Remove.
+ * decl2.c (grokfield): Don't call pushdecl_class_level or
+ check_template_shadow.
+ * errfn.c (cp_file_of): Don't declare.
+ (cp_line_of): Likewise.
+ * error.c (dump_decl): Handle an OVERLOAD.
+ (cp_file_of): Likewise.
+ (cp_line_of): Likewise.
+ * init.c (build_member_call): Handle a COMPONENT_REF.
+ * lex.c (do_identifier): Call maybe_note_name_used_in_class, not
+ pushdecl_class_level.
+ * method.c (hack_identifier): Build COMPONENT_REFs for references
+ to member templates as well as member functions. Remove dead
+ code.
+ * parse.y (left_curly): Remove.
+ (nonnested_type): Call maybe_note_name_used_in_class, not
+ pushdecl_class_level.
+ * parse.c: Regenerated.
+ (nested_name_specifier_1): Likewise.
+ * pt.c (check_explicit_specialization): Adjust, for robustness.
+ (check_template_shadow): Handle OVERLOADs.
+ (build_template_decl): Set DECL_CONSTRUCTOR_P on the
+ TEMPLATE_DECL, if appropriate.
+ * search.c (envelope_add_decl): Remove.
+ (dfs_pushdecls): Likewise.
+ (dfs_compress_decls): Likewise.
+ (dfs_push_decls): New function.
+ (dfs_push_type_decls): Likewise.
+ (setup_class_bindings): Likewise.
+ (template_self_reference_p): Likewise.
+ (lookup_field_r): Use it.
+ (looup_member): Remove old comment. Deal with ambiguity.
+ (push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
+ and remove envelope processing.
+ * semantics.c (begin_class_definition): Let pushclass push
+ declarations for base classes.
+ (finish_member_declaration): Push declarations into class scope.
+ * typeck.c (build_component_ref): Just put an OVERLOAD into the
+ COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
+ (build_x_function_call): Deal with OVERLOAD. Handle template-ids.
+ * Makefile.in (class.o): Depend on splay-tree.h.
+
+Wed Mar 31 11:30:43 1999 Nathan Sidwell <nathan@acm.org>
+
+ * cvt.c (convert_pointer_to_real): Use same_type_p.
+ * typeck.c (comp_target_types): Use same_type_p.
+
+1999-03-31 Jason Merrill <jason@yorick.cygnus.com>
+
+ * semantics.c (begin_inline_definitions,
+ finish_inline_definitions): Rename from finish_default_args and
+ begin_inline_definitions, respectively, to something that isn't a
+ total lie. :)
+ * parse.y (structsp): Adjust.
+
+ * tree.c (hash_tree_cons): Remove obsolete via_* parms.
+ (list_hash_lookup): Likewise.
+ (hash_tree_chain): Adjust.
+ * pt.c (tsubst): Adjust.
+ (tsubst_arg_types): Use plain hash_tree_cons.
+ * cp-tree.h (hash_tree_cons_simple): Lose.
+ * parse.y (declmods, nonempty_cv_qualifiers): Use hash_tree_cons.
+
+Wed Mar 31 10:48:29 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (hash.h): Generate using gperf language 'C', not
+ 'KR-C', so gperf uses the `const' keyword on strings.
+
+ * gxx.gperf (resword): Const-ify a char*.
+
+1999-03-30 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (IDENTIFIER_AS_DESC, IDENTIFIER_AS_LIST,
+ CLASSTYPE_BASELINK_VEC, CLASSTYPE_N_SUPERCLASSES,
+ CLASSTYPE_N_BASECLASSES, CLASSTYPE_MAX_DEPTH,
+ CLASSTYPE_BASE_INIT_LIST, CLASSTYPE_AS_LIST, CLASSTYPE_ID_AS_LIST,
+ CLASSTYPE_BINFO_AS_LIST): Remove cruft.
+ * class.c, lex.c, parse.y, ptree.c, search.c, semantics.c,
+ tree.c: Adjust.
+
+1999-03-29 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (lang_decode_option): Remove -Wsign-promo from -Wall.
+
+1999-03-28 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (fn_type_unification): Ignore 'this' parm from conversion ops.
+
+1999-03-27 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (add_friend): Declare.
+ (add_friends): Likewise.
+ * friend.c (add_friend): Make it global. Don't add to
+ DECL_BEFRIENDING_CLASSES if the befriending class is a template.
+ (add_friends): Make it global.
+ (make_friend_class): Don't add to DECL_BEFRIENDING_CLASSES if the
+ befriending class is a template.
+ * parse.y (component_decl_1): Fix typo in comment.
+ * parse.c: Regenerated.
+ * pt.c (instantiate_class_template): Use add_friend and
+ add_friends rather that duplicating some of their functionality
+ here.
+
+1999-03-27 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_field_call): Unify 'this' and non-'this' cases.
+
+ * typeck.c (build_indirect_ref): Check for 'this' sooner.
+
+Fri Mar 26 10:20:34 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (op_error): Const-ify a char*.
+ (add_candidate, source_type, add_warning): Add static prototype.
+ (print_z_candidates): Const-ify a char*.
+
+ * class.c (resolve_address_of_overloaded_function,
+ fixed_type_or_null, build_vtable_entry_ref): Add static prototype.
+ (get_vtable_name, finish_struct_1): Const-ify a char*.
+
+ * cvt.c (convert_to_reference): Likewise.
+
+ * decl.c (redeclaration_error_message, record_builtin_type,
+ record_unknown_type, member_function_or_else, bad_specifiers):
+ Likewise.
+ (find_binding, select_decl, unqualified_namespace_lookup,
+ lookup_flags, qualify_lookup, record_builtin_java_type, tag_name):
+ Add static prototype.
+ (warn_extern_redeclared_static, duplicate_decls, pushdecl,
+ implicitly_declare, record_builtin_java_type, define_function,
+ grok_op_properties, tag_name): Const-ify a char*.
+
+ * cp-tree.h (FORMAT_VBASE_NAME): Allow parameter `BUF' to be const.
+ (define_function, finish_builtin_type): Const-ify a char*.
+ (cp_error, cp_error_at, cp_warning, cp_warning_at, cp_pedwarn,
+ cp_pedwarn_at, cp_compiler_error, cp_sprintf): Add prototype args.
+ (file_name_nondirectory): Const-ify a char*.
+ (init_filename_times): Don't prototype.
+ (compiler_error): Prototype.
+ (yyerror, init_repo): Const-ify a char*.
+ (build_srcloc): Don't prototype.
+ (build_x_indirect_ref, build_indirect_ref, build_component_addr):
+ Const-ify a char*.
+ (warn_for_assignment): Don't prototype.
+ (convert_for_initialization, readonly_error, check_for_new_type,
+ GNU_xref_begin, GNU_xref_file, GNU_xref_ref, GNU_xref_call):
+ Const-ify a char*.
+
+ * decl2.c (acceptable_java_type, output_vtable_inherit,
+ setup_initp, start_objects, finish_objects, do_dtors, do_ctors,
+ merge_functions, decl_namespace, validate_nonmember_using_decl,
+ do_nonmember_using_decl): Add static prototype.
+ (lang_f_options): Const-ify a char*.
+ (finish_builtin_type): Likewise.
+ (add_function, arg_assoc_namespace, arg_assoc_class): Add static
+ prototype.
+
+ * errfn.c: Include cp-tree.h.
+ (cp_thing): Add static prototype.
+ (compiler_error): Don't protoptype.
+ (cp_compiler_error): Cast `compiler_error' to `errorfn' before
+ passing it to `cp_thing'.
+
+ * error.c (interesting_scope_p): Add static prototype.
+
+ * except.c (build_eh_type_type, build_eh_type_type_ref): Const-ify
+ a char*.
+
+ * init.c (compiler_error): Don't prototype.
+ (member_init_ok_or_else): Const-ify a char*.
+ (build_java_class_ref): Add static prototype.
+
+ * lex.c (compiler_error): Don't prototype.
+ (get_time_identifier, interface_strcmp, extend_token_buffer,
+ handle_cp_pragma): Const-ify a char*.
+ (is_global, init_filename_times): Add static prototype.
+ (file_name_nondirectory, cplus_tree_code_name): Const-ify a char*.
+ (compiler_error): Change from fixed args to variable args.
+ (yyerror): Const-ify a char*.
+
+ * parse.y (cond_stmt_keyword): Const-ify a char*.
+ (parse_decl): Add static prototype.
+
+ * pt.c (template_args_equal, print_template_context): Likewise.
+ (print_candidates, check_default_tmpl_args): Const-ify a char*.
+ (instantiate_class_template): Likewise.
+
+ * repo.c (get_base_filename, open_repo_file, init_repo): Likewise.
+
+ * rtti.c (call_void_fn, expand_generic_desc, expand_si_desc,
+ expand_class_desc, expand_ptr_desc, expand_attr_desc): Likewise.
+
+ * search.c (lookup_field_info, lookup_member): Likewise.
+ (lookup_member): Cast the first argument of `bzero' to a PTR.
+
+ * sig.c (compiler_error): Don't prototype.
+ (build_signature_pointer_or_reference_nam): Const-ify a char*.
+ (get_sigtable_name, build_member_function_pointer): Likewise.
+
+ * tree.c (compiler_error): Don't prototype.
+ (no_linkage_helper, build_srcloc): Add static prototype.
+ (build_vbase_pointer_fields): Const-ify a char*.
+ (__eprintf): Don't unnecessarily handle `const' when !__STDC__.
+
+ * typeck.c (compiler_error): Don't prototype.
+ (convert_for_assignment): Const-ify a char*.
+ (comp_cv_target_types): Add static prototype.
+ (build_x_indirect_ref, build_indirect_ref, convert_arguments,
+ build_component_addr, build_unary_op, convert_for_initialization):
+ Const-ify a char*.
+
+ * typeck2.c (ack): Add static prototype and change from fixed args
+ to variable args.
+ (readonly_error, check_for_new_type): Const-ify a char*.
+
+ * xref.c (_XREF_FILE, find_file, filename, fctname, declname,
+ fixname, open_xref_file, classname, GNU_xref_begin): Likewise.
+ (GNU_xref_file): Likewise. Also use `xmalloc' instead of `malloc'.
+ (GNU_xref_end_scope, GNU_xref_ref, GNU_xref_decl, GNU_xref_call,
+ gen_assign, GNU_xref_member): Const-ify a char*.
+
+1999-03-25 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * gxxint.texi: Remove old discussion on copying virtual bases.
+
+1999-03-25 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * Make-lang.in: Remove all references to g++.o/g++.c.
+ Link g++ from gcc.o.
+
+1999-03-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (comdat_linkage): Treat vtables like functions.
+
+1999-03-25 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_decl): tsubst into DECL_BEFRIENDING_CLASSES.
+
+1999-03-25 Nathan Sidwell <nathan@acm.org>
+
+ * decl.c (init_decl_processing): Add `signed' type as a synonym
+ for `int'.
+
+1999-03-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (common_type): Handle cv-qual unification for pointers
+ to members.
+
+ * decl.c (unqualified_namespace_lookup): Return error_mark_node
+ on error.
+ (lookup_name_real): Set LOOKUP_COMPLAIN when *not* parsing.
+ * lex.c (do_identifier): If we got error_mark_node, call
+ lookup_name again.
+
+1999-03-24 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * class.c (finish_struct_1): Always reset TYPE_FIELDS for empty
+ classes.
+
+1999-03-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_name_real): Do nested field lookup regardless of
+ TYPE_BEING_DEFINED.
+
+1999-03-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_type): Remove has_assignment and
+ has_real_assignment. Add befriending_classes.
+ (TYPE_HAS_ASSIGNMENT): Remove.
+ (TYPE_HAS_REAL_ASSIGNMENT): Likewise.
+ (CLASSTYPE_BEFRIENDING_CLASSES): New macro.
+ (lang_decl): Document.
+ (DECL_BEFRIENDING_CLASSES): New macro.
+ (FRIEND_NAME): Move declaration to more obvious location.
+ (FRIEND_DECLS): Likewise.
+ * class.c (finish_struct_1): Don't use TYPE_HAS_REAL_ASSIGNMENT.
+ * decl.c (duplicate_decls): Copy DECL_BEFRIENDING_CLASSES.
+ (fixup_anonymous_union): Don't use TYPE_HAS_ASSIGNMENT.
+ (grok_op_properties): Likewise.
+ * friend.c (is_friend): Use FRIEND_NAME and FRIEND_DECLS.
+ (add_friend): Likewise. Don't do weird things with assignment
+ operators. Update DECL_BEFRIENDING_CLASSES.
+ (add_friends): Don't do weird things with assignment operators.
+ (make_friend_class): Likewise. Update
+ CLASSTYPE_BEFRIENDING_CLASSES.
+ * pt.c (instantiate_class_template): Don't set
+ TYPE_HAS_ASSIGNMENT.
+ (tsubst_copy): Substitute the TREE_TYPE for more unary
+ expressions.
+ * ptree.c (print_lang_type): Don't look at TYPE_HAS_ASSIGNMENT.
+ * search.c (protected_accessible_p): New function.
+ (friend_accessible_p): Likewise.
+ (accessible_p): Use them.
+
+1999-03-23 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (convert_nontype_argument): Don't create things that aren't
+ PTRMEM_CSTs when applying a qualification conversion to a
+ PTRMEM_CST.
+
+1999-03-23 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (OBJS): Don't mention hash.o.
+ (OBJDEPS): Likewise.
+
+1999-03-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Set at_eof to 2 after expanding ctors.
+ * decl.c (expand_static_init): Make sure we don't add any after
+ then.
+
+ * decl.c (cp_finish_decl): Move intelligence about handling
+ DECL_COMDAT for variables from here...
+ * decl2.c (comdat_linkage): ...to here.
+ (maybe_make_one_only): Tweak.
+ (import_export_decl): Call comdat_linkage for variables, too.
+ (finish_file): Handle template statics properly.
+
+1999-03-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TYPE_PTRMEMFUNC_P): Use TYPE_PTRMEMFUNC_FLAG.
+ Document internals of pointer-to-member-functions.
+ (DELTA2_FROM_PTRMEMFUNC): Make it call delta2_from_ptrmemfunc.
+ (PFN_FROM_PTRMEMFUNC): Likewise.
+ (build_type_conversion): Remove unused parameter.
+ (build_ptrmemfunc1): Declare.
+ (expand_ptrmemfunc_cst): New function.
+ (delta2_from_ptrmemfunc): Likewise.
+ (pfn_from_ptrmemfunc): Likewise.
+ * cvt.c (cp_convert_to_pointer): Remove unused parameter to
+ build_type_conversion. Use TYPE_PTRMEM_P for readability.
+ (convert_to_reference): Remove unused parameter to
+ build_type_conversion.
+ (ocp_convert): Likewise.
+ (build_user_type_conversion): Likewise.
+ * error.c (dump_expr): Handle NULL pointer-to-member functions.
+ * expr.c (cplus_expand_expr): Handle PTRMEM_CSTs for functions.
+ * method.c (build_overload_value): Don't go splitting CONSTRUCTORs
+ open when handling pointer-to-member functions.
+ * pt.c (convert_nontype_argument): Clean up error messages. Be
+ more stringent with pointers-to-members.
+ * typeck.c (build_ptrmemfunc1): Don't declare. Make it global.
+ (build_unary_op): Tidy ever-so-slightly.
+ (build_conditional_expr): Remove extra parameter to
+ build_type_conversion.
+ (build_ptrmemfunc): Build PTRMEM_CSTs if we know what function
+ we're using.
+ (expand_ptrmemfunc_cst): Define.
+ (delta2_from_ptrmemfunc): Likewise.
+ (pfn_from_ptrmemfunc): Likewise.
+
+1999-03-19 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (build_member_call): Handle template-id expressions
+ correctly.
+ * typeck.c (build_x_function_call): Likewise.
+
+1999-03-19 Chip Salzenberg <chip@perlsupport.com>
+
+ * friend.c (make_friend_class): Avoid core dump when
+ not-yet-defined friend type lacks TYPE_LANG_SPECIFIC().
+
+1999-03-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_function): Suppress normal linkage heuristics
+ for #pragma interface under MULTIPLE_SYMBOL_SPACES.
+
+1999-03-19 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * Make-lang.in: ($(INTL_TARGETS)): Depend on cp/parse.c.
+ ($(srcdir)/cp/parse.c): Moved from ../Makefile.in.
+
+1999-03-17 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (named_complex_class_head_sans_basetype):
+ Do not push a scope for error_mark_node.
+ (maybe_base_class_list): Likewise.
+
+ * decl.c (start_decl): Check for error_mark_node as a type.
+ Detected by g++.brendan/array-refs.C.
+ (start_decl_1): Likewise. Detected by g++.bugs/900322_01.C.
+ (maybe_build_cleanup_1): Likewise. Detected by
+ g++.jason/incomplete1.C.
+
+ * tree.c (build_dummy_object): Use void_zero_node instead of the
+ error_mark_node.
+ (is_dummy_object): Check for such a node.
+ Detected by g++.bob/inherit1.C
+
+1999-03-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (old_backref_index): Split out...
+ (flush_repeats): From here. Rename back from try_old_backref.
+ (build_mangled_name): Put back some old-style repeat handling.
+
+Mon Mar 15 21:57:16 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c: Don't include setjmp.h.
+ (parse_float): New static function.
+ (pf_args): New struct.
+ (real_yylex): Use them in call to `do_float_handler'.
+
+1999-03-15 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (xref_basetypes): Set CLASSTYPE_VBASECLASSES here.
+ * tree.c (layout_basetypes): Not here.
+ * search.c (dfs_search): Remove; no longer used.
+
+1999-03-12 Mark Mitchell <mark@markmitchell.com>
+
+ * decl2.c (validate_nonmember_using_decl): Issue sensible
+ error-messages on bogus qualifiers.
+
+1999-03-14 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (add_function_candidate): Fix uninitialized variable.
+
+ * Makefile.in (search.o): Add dependency on varray.h.
+
+1999-03-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (duplicate_decls): Use same_type_p.
+ * method.c (try_old_backref): Renamed from flush_repeats. Use
+ same_type_p. Don't try to handle repeats. Return success.
+ (is_back_referenceable_type): Return 0 if TYPE_FOR_JAVA. Support
+ calls from old-style code, too.
+ (check_ktype): Use same_type_p.
+ (check_btype): Use same_type_p. Don't pull out TYPE_MAIN_VARIANT.
+ (build_qualified_name): Simplify logic.
+ (process_overload_item): Strip typedefs and quals at the top.
+ (build_mangled_name_for_type_with_Gcode): Remove call to
+ type_canonical_variant.
+ (build_mangled_name): Likewise. Remove support for old-style
+ repeats, which have been disabled since 2.7.2. Don't mess with
+ TREE_USED.
+ (build_decl_overload_real): Don't mess with TREE_USED.
+
+1999-03-13 Nathan Sidwell <nathan@acm.org>
+
+ * error.c (cp_printers): Add 'F' escape character.
+ (dump_type_real): Remove TREE_LIST (fnargs) printing.
+ Functionality moved to dump_parameters.
+ (dump_type_suffix): Use dump_parameters and dump_exception_spec.
+ (dump_function_decl): Extend meaning of V parameter. Use
+ dump_parameters and dump_exception_spec.
+ (dump_parameters): New static function.
+ (dump_exception_spec): New static function.
+ (fndecl_as_string): Change argument semantics. Use
+ dump_function_decl directly.
+
+ * sig.c (build_signature_table_constructor): Use cp_error.
+
+1999-03-13 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * semantics.c (finish_switch_cond): Handle error cases gracefully.
+ Detected by g++.law/enum5.C.
+
+ * typeck.c (build_modify_expr): Check for errors after resolving
+ offsets. Detected by g++.brendan/static1.C.
+
+ * decl.c (complete_array_type): Ignore initial_value if it is an
+ error. Detected by g++.benjamin/17930.C.
+
+ * typeck2.c (process_init_constructor): Return error if one argument
+ is in error. Detected by g++.benjamin/13478.C.
+
+1999-03-12 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (select_decl): Allow class templates when we need types.
+ * decl2.c (ambiguous_decl): Likewise.
+
+1999-03-12 Mark Mitchell <mark@markmitchell.com>
+
+ * lex.c (do_identifier): Correct call to enforce_access.
+ * search.c (accessible_p): Tweak comment.
+
+1999-03-10 Mark Mitchell <mark@markmitchell.com>
+
+ * semantics.c (begin_class_definition): Call build_self_reference.
+ (finish_member_declaration): Set DECL_CONTEXT for TYPE_DECLs.
+
+ * search.c (assert_canonical_unmarked): Fix typo in prototype.
+
+ * search.c (dfs_canonical_queue): New function.
+ (dfs_assert_unmarked_p): Likewise.
+ (assert_canonical_unmarked): Likewise.
+ (access_in_type): Use it.
+ (accessible_p): Likewise. Walk the whole tree when umarking.
+
+ * sig.c (build_signature_table_constructor): Use accessible_p
+ instead of compute_access.
+
+1999-03-09 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (add_builtin_candidates): Handle overloaded conversion ops.
+
+1999-03-09 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (flag_access_control): Declare.
+ (TREE_VIA_PPUBLIC): Document.
+ (DECL_NONSTATIC_MEMBER_P): New macro.
+ (enforce_access): Return an indication of whether or not access
+ was permitted.
+ (build_self_reference): Change prototype.
+ (compute_access): Replace with ...
+ (accessible_p): New function.
+ (dfs_walk): Change prototype.
+ (dfs_unmark): Likewise.
+ (markedp): Likewise.
+ * call.c (enforce_access): Use accessible_p.
+ * class.c (build_self_reference): Insert the declaration into the
+ list of members for this type, and make it public.
+ * decl.c (xref_basetypes): Avoid ill-timed recursion.
+ * init.c (build_offset_ref): Use lookup_member, not three separate
+ name-lookups. Call enforce_access rather than checking for
+ illegal accesses here.
+ (resolve_offset_ref): Likewise.
+ * lex.c (do_identifier): Likewise.
+ * method.c (hack_identifier): Likewise.
+ * parse.y (self_reference): Remove.
+ (opt_component_decl_list): Don't use it.
+ * parse.c: Regenerated.
+ * pt.c (print_candidates): Generalize to handle lists of
+ overloaded functions.
+ (instantiate_class_template): Don't rely on TREE_VIA_PRIVATE; it's
+ not set.
+ (get_template_base): Use new calling convention for dfs_walk.
+ * search.c: Include varray.h. Add prototypes.
+ (dfs_walk): Accept a data pointer to pass to the work functions.
+ All callers changed. All work functions changed.
+ (breadth_first_search): Rename to bfs_walk, and make consistent
+ with dfs_walk.
+ (dfs_walk_real): New function.
+ (canonical_binfo): New function.
+ (context_for_name_lookup): Likewise.
+ (shared_marked_p): Likewise.
+ (shared_unmarked_p): Likewise.
+ (lokup_field_queue_p): Likewise.
+ (lookup_field_r): Generalize to handle both functions and fields.
+ (lookup_field): Just call lookup_member.
+ (lookup_fnfields): Likewise.
+ (lookup_member): Move body of lookup_field here and generalize.
+ (dfs_accessible_queue_p): Likewise.
+ (dfs_accessible_p): Likewise.
+ (dfs_access_in_type): Likewise.
+ (access_in_type): Likewise.
+ (compute_access): Remove, and replace with ...
+ (accessible_p): New function.
+ (vbase_types): Remove.
+ (vbase_decl_ptr_intermediate): Likewise.
+ (vbase_decl_ptr): Likewise.
+ (vbase_init_result): Likewise.
+ (closed_envelopes): Likewise.
+ (bvtable): Likewise.
+
+1999-03-09 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (add_function_candidate): Check for proper number of args
+ before checking the validity of those args.
+
+1999-03-06 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (struct lang_type): Add anon_union field.
+ (ANON_UNION_TYPE_P): Use it instead of examining type.
+ (SET_ANON_UNION_TYPE_P): New macro.
+ * decl.c (check_tag_decl): Use it.
+
+ * search.c (compute_access): Handle non-type contexts earlier, and
+ handle NULL_TREE.
+
+ * tree.c (build_exception_variant): Use copy_to_permanent.
+
+ * decl2.c (setup_initp): Give statics with no priority the default
+ priority here.
+ (do_dtors, do_ctors, finish_file): Remove special handling of
+ non-prioritized statics.
+
+1999-03-05 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (ANON_UNION_TYPE_P): Robustify.
+ * decl.c (make_typename_type): Don't issue an error if an
+ immediate lookup fails; it migt be resolved later.
+ * friend.c (is_friend): Add comment.
+ * search.c (breadth_first_search): Add POSTFN and DATA
+ parameters. Tidy. All callers changed.
+ (lookup_field_queue_p): New function.
+ (lookup_field_r): Likewise.
+ (lookup_field_post): Likewise.
+ (lookup_field): Use them, via breadth_first_search, instead of
+ duplicating logic.
+ (compute_access): Robustify.
+ (lookup_fnfield_info): New structure.
+
+1999-03-05 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst, case ARRAY_REF): Use tsubst_expr again.
+
+1999-03-03 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c, decl2.c, method.c, pt.c: Add 'static' to make SunOS 4
+ cc happy.
+
+ * decl2.c (import_export_class): Also return if
+ CLASSTYPE_INTERFACE_ONLY is set.
+
+1999-03-03 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (push_overloaded_decl): Only overwrite the old binding if
+ there was one.
+ * decl2.c (do_local_using_decl): Fix loop termination.
+
+1999-03-02 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (determine_specialization): Don't declare.
+ * pt.c (determine_specialization): Make it static. Eliminate
+ complain parameter. Note that decl is always non-NULL now, and
+ simplify accordingly.
+
+ * decl.c (maybe_push_to_top_level): Always call
+ push_cp_function_context.
+ (pop_from_top_level): Always call pop_cp_function_context.
+
+1999-02-26 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (complete_type_or_else): Add VALUE arg, for helpful
+ diagnostics.
+ * cp-tree.h (complete_type_or_else): Added VALUE parameter.
+ * init.c (build_new_1): Extra arg to complete_type_or_else.
+ (build_delete): Likewise.
+ * typeck.c (require_complete_type): Likewise.
+ (pointer_int_sum): Likewise.
+ (pointer_diff): Likewise.
+ (build_component_ref): Likewise.
+
+ * typeck2.c (incomplete_type_error): Always use cp_error.
+ Show declaration of undefined type, if appropriate.
+ Deal with UNKNOWN_TYPE nodes.
+
+ * typeck.c (require_complete_type): Use TYPE_SIZE as
+ size_zero_node to mean incomplete type.
+ (require_complete_type_in_void): New function.
+ (build_compound_expr): Call complete_type_in_void for LHS.
+ (build_c_cast): Call complete_type_in_void for void cast.
+ * cvt.c (ocp_convert): Call complete_type_in_void for void cast.
+ * decl.c (cplus_expand_expr_stmt): Void expression checks moved to
+ require_complete_type_in_void. Call it.
+ * cp-tree.h (require_complete_type_in_void): Prototype new function.
+
+ * typeck.c (convert_arguments): Use alternative format for
+ function decls. Don't require_complete_type here. Simplify
+ diagnostic printing.
+ (convert_for_initialization): Don't require_complete_type on RHS yet.
+ * call.c (convert_arg_to_ellipsis): Call require_complete_type.
+
+ * call.c (build_over_call): Cope with qualified void return type.
+ * semantics.c (finish_call_expr): Likewise.
+ * typeck.c (build_function_call_real): Likewise.
+ (c_expand_return): Likewise.
+ * decl2.c (reparse_absdcl_as_expr): Cope with qualified void type.
+
+ * call.c (print_z_candidates): Use alternate print format, to be
+ consistent with (pt.c) print_candidates.
+ * method.c (hack_identifier): List candidate members.
+ * search.c (lookup_field): Build ambiguous list, and show it, if
+ ambiguous.
+
+1999-02-26 Mark Mitchell <mark@markmitchell.com>
+
+ * typeck.c (decay_conversion): Don't confuse constant array
+ variables with their initializers.
+
+ * decl.c (duplicate_decls): Copy DECL_TEMPLATE_INSTANTIATED when
+ merging decls.
+ * pt.c (regenerate_decl_from_template): Tweak for clarity.
+ (instantiate_decl): Mark a decl instantiated before regenerating
+ it to avoid recursion.
+ * tree.c (mapcar): Don't call decl_constant_value unless we know
+ something is TREE_READONLY_DECL_P.
+
+ * class.c (check_for_override): Don't stop checking when we find
+ the first overridden function. Delete #if 0'd code.
+ * search.c (get_matching_virtual): Likewise.
+
+1999-02-25 Richard Henderson <rth@cygnus.com>
+
+ * lang-specs.h: Define __FAST_MATH__ when appropriate.
+
+1999-02-24 Mike Stump <mrs@wrs.com>
+
+ * typeck.c (convert_for_assignment): Allow boolean integral constant
+ expressions to convert to null pointer.
+
+1999-02-24 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (lookup_namespace_name): Resolve namespace aliases.
+
+ * class.c (push_nested_class): Allow namespaces.
+
+ * decl2.c (set_decl_namespace): Add friendp parameter.
+ * decl.c (grokfndecl): Pass it.
+ (grokvardecl): Likewise.
+ * cp-tree.h: Change declaration.
+
+1999-02-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Allow an array of explicit size zero.
+
+1999-02-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * errfn.c: Change varargs code to look like toplev.c.
+
+ * method.c (process_modifiers): Don't prepend 'U' for char or
+ wchar_t.
+
+1999-02-20 Craig Burley <craig@jcb-sc.com>
+
+ * Make-lang.in (cplib2.ready): Don't consider updating
+ cplib2 stuff if the current directory isn't writable, as
+ it won't work (such as during a `make install').
+
+Sun Feb 21 20:38:00 1999 H.J. Lu (hjl@gnu.org)
+
+ * decl2.c (start_objects): Make file scope constructors and
+ destructors local to the file if ASM_OUTPUT_CONSTRUCTOR and
+ ASM_OUTPUT_DESTRUCTOR are defined.
+
+1999-02-19 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (CLASSTYPE_METHOD_VEC): Adjust comment.
+ (fn_type_unification): Adjust prototype.
+ (lookup_fnfields_1): Declare.
+ * call.c (add_template_candidate_real): Adjust call to
+ fn_type_unification.
+ * class.c (add_method): Don't allow duplicate declarations of
+ constructors or destructors.
+ (resolve_address_of_overloaded_function): Remove unused variable.
+ Adjust call to fn_type_unification.
+ * decl.c (grokfndecl): Be more robust in the face of illegal
+ specializations.
+ * decl2.c (check_classfn): Remove hokey handling of member
+ templates.
+ * pt.c (determine_specialization): Improve comments. Adjust to
+ handle template argument deduction as per the standard.
+ (check_explicit_specialization): Fix comment spacing. Handle
+ type-conversion operators correctly. Improve error-recovery.
+ (fn_type_unification): Remove EXTRA_FN_ARG parameter.
+ (get_bindings_real): Simplify handling of static members.
+ * search.c (lookup_fnfields_1): Make it have external linkage.
+ * typeck.c (compparms): Fix comment.
+ (build_unary_op): Don't try to figure out which template
+ specialization is being referred to when when the address-of
+ operator is used with a template function.
+
+Thu Feb 18 23:40:01 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (lvalue_or_else): Qualify a char* with the `const'
+ keyword to match an analogous change at the top level.
+
+ * tree.c (lvalue_or_else): Likewise.
+
+1999-02-17 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (xref_basetypes): Comment.
+ * pt.c (instantiate_class_template): Use xref_basetypes.
+
+1999-02-16 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (tsubst): Change prototype.
+ (tsubst_expr): Likewise.
+ (tsubst_copy): Likewise.
+ (type_unification): Remove prototype.
+ * call.c (convert_default_arg): Adjust call to tsubst_expr.
+ * class.c (resolve_address_of_overloaded_function): Just use
+ fn_type_unification.
+ * decl.c (grokdeclarator): Adjust call to tsubst.
+ * method.c (build_template_parm_names): Likewise.
+ * pt.c (GTB_VIA_VIRTUAL): New macro.
+ (GTB_IGNORE_TYPE): Likewise.
+ (resolve_overloaded_unification): Add `complain' parameter.
+ (try_one_overload): Likewise.
+ (tsubst_template_arg_vector): Likewise.
+ (tsubst_template_parms): Likewise.
+ (tsubst_aggr_type): Likewise.
+ (tsubst_arg_types): Likewise.
+ (tsubst_call_declarator_parms): Likewise.
+ (unify): Remove explicit_mask.
+ (type_unification_real): Likewise.
+ (get_template_base_recursive): Likewise.
+ (coerce_template_template_parms): Provide prototype.
+ (tsubst_function_type): Likewise.
+ (try_class_unification): New function.
+ All callers changed to use new complain parameter.
+ (get_template_base): Use try_class_unification.
+ (unify): Adjust handling of classes derived from template types.
+ (fn_type_unification): Substitute explicit arguments before
+ unification.
+
+1999-02-16 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * decl.c (pushdecl): Remove dead code.
+
+1999-02-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_objects): Fix code I missed in previous change.
+
+1999-02-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokfndecl): Return NULL_TREE instead of error_mark_node.
+ (grokdeclarator): Don't expect error_mark_node from grokfndecl.
+
+ * pt.c (maybe_process_partial_specialization): Complain about
+ 'template <>' on non-specialization.
+
+1999-02-10 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Catch weird declarators.
+ * decl2.c (finish_file): Don't abort because of namespace parsing
+ failure.
+ (check_decl_namespace): Remove.
+
+1999-02-09 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (get_template_base): Don't declare.
+ (dfs_walk): Declare.
+ (dfs_unmark): Likewise.
+ (markedp): Likewise.
+ * pt.c (unify): Remove duplicate declaration. Pass tparms and
+ targs to get_template_base.
+ (get_template_base_recursive): Move here from search.c. Check to
+ see that the base found can be instantiated to form the desired
+ type.
+ (get_template_base): Likewise.
+ (get_class_bindings): Simplify.
+ * search.c (get_template_base_recursive): Move to pt.c.
+ (get_template_base): Likewise.
+ (markedp): Make it global.
+ (dfs_walk): Likewise.
+ (dfs_unmark): Likewise.
+
+1999-02-07 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (maybe_process_partial_specialization): Complain about
+ specialization in wrong namespace.
+ * tree.c (decl_namespace_context): New fn.
+
+1999-02-06 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * decl2.c (arg_assoc_type): Handle TEMPLATE_TEMPLATE_PARM.
+ * pt.c (coerce_template_template_parms): Handle nested
+ template template parameters.
+
+Sat Feb 6 18:08:40 1999 Jeffrey A Law (law@cygnus.com)
+
+ * typeck2.c: Update email addresses.
+
+1999-02-04 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * pt.c (unify): Call coerce_template_parms with the COMPLAIN flag
+ turned off.
+
+1999-02-04 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (retrofit_lang_decl): Split out...
+ (build_lang_decl): From here.
+ * decl.c (pushdecl): Call it for functions generated by the middle
+ end that don't have DECL_LANG_SPECIFIC.
+ * cp-tree.h: Declare it.
+
+ * decl2.c: Remove flag_init_priority. Always enable initp stuff.
+ (start_objects, finish_objects): Only use special
+ init_priority code if the user specified a priority.
+ (do_ctors, do_dtors): Use DEFAULT_INIT_PRIORITY for the non-initp
+ objects.
+
+Wed Feb 3 22:50:17 1999 Marc Espie <Marc.Espie@liafa.jussieu.fr>
+
+ * Make-lang.in (GXX_OBJS): Remove choose-temp.o, pexecute.o and
+ mkstemp.o. Get them from libiberty now.
+ (DEMANGLER_PROG): Simlarly, remove getopt.o getopt1.o.
+
+Tue Feb 2 22:38:48 1999 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * decl2.c (lang_decode_option): Use read_integral_parameter.
+
+1999-02-01 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (tsubst, case TYPENAME_TYPE): Check TYPE_BEING_DEFINED
+ before calling complete_type_or_else.
+
+Mon Feb 1 09:49:52 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * input.c (inline): Don't define, its handled by system.h.
+
+Sun Jan 31 20:34:29 1999 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * decl2.c: Don't define flag_no_ident here. Don't process
+ -f(no-)ident here.
+ * cp-tree.h: Don't declare flag_no_ident here.
+ * lang-specs.h: Map -Qn to -fno-ident.
+
+1999-01-28 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (struct tree_binding): Replace scope field with a union.
+ (BINDING_SCOPE): Adjust.
+ * decl.c (BINDING_LEVEL): Adjust.
+
+1999-01-26 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Set up the DECL_INITIAL of
+ member constants.
+
+ * init.c (expand_member_init): Pull out TYPE_MAIN_VARIANT in
+ a ctor initializer.
+
+ * tree.c (equal_functions): Fix name in prototype.
+
+ * decl.c (push_local_binding): Add FLAGS argument.
+ (pushdecl, push_overloaded_decl): Pass it.
+ * decl2.c (do_local_using_decl): Likewise.
+ * cp-tree.h: Adjust prototype.
+ * decl.c (poplevel): Fix logic.
+
+ * decl.c (push_local_binding): Also wrap used decls in a TREE_LIST.
+ (poplevel): Handle that. Fix logic for removing TREE_LISTs.
+ (cat_namespace_levels): Don't loop forever.
+
+1999-01-25 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (build_reinterpret_cast): Fix typo in duplicated test.
+
+1999-01-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (resolve_address_of_overloaded_function): Mark the
+ chosen function used.
+
+ * call.c (build_call): Make sure that a function coming in has
+ been marked used already.
+ * decl.c (expand_static_init): Call mark_used instead of
+ assemble_external.
+ * except.c (call_eh_info, do_pop_exception, expand_end_eh_spec,
+ alloc_eh_object, expand_throw): Likewise.
+ * init.c (build_builtin_delete_call): Likewise.
+ * rtti.c (call_void_fn, get_tinfo_fn, build_dynamic_cast_1,
+ expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc,
+ expand_generic_desc): Likewise.
+
+1999-01-25 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * tree.c (equal_functions): New function.
+ (ovl_member): Call it.
+
+1999-01-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Fix conversion of 0 to pmf.
+
+1999-01-25 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (decls_match): Return 1 if old and new are identical.
+ (push_overloaded_decl): Set OVL_USED when PUSH_USING.
+
+1999-01-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_function): Make member functions one_only on windows.
+ * decl2.c (import_export_decl): Likewise.
+
+ * decl.c (grokdeclarator): Don't complain about implicit int in
+ a system header. Change same-name field check to not complain in
+ a system header instead of within extern "C".
+
+1999-01-21 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (PUSH_GLOBAL): New macro.
+ (PUSH_LOCAL): Likewise.
+ (PUSH_USING): Likewise.
+ (namespace_bindings_p): Declare.
+ (push_overloaded_decl): Likewise.
+ * decl.c (push_overloaded_decl): Don't make it static. Check for
+ illegal declarations after using declarations here.
+ (namespace_bindings_p): Likewise.
+ (duplicate_decls): Don't consider declarations from different
+ namespaces to be the same.
+ (pushdecl): Use symbolic PUSH_ constants in calls to
+ push_overloaded_decl.
+ (push_overloaded_decl_1): Likewise.
+ * decl2.c (validate_nonmember_using_decl): Tweak `std' handling.
+ (do_nonmember_using_decl): Check for illegal using declarations
+ after ordinary declarations here.
+ (do_local_using_decl): Call pushdecl to insert declarations.
+
+1999-01-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Fix lang_c -> lang_name_c typo.
+
+1999-01-21 Mark Mitchell <mark@markmitchell.com>
+
+ * tree.c (build_cplus_array_type_1): Don't call build_array_type
+ for types involving template parameters.
+
+ * cp-tree.h (PARM_DECL_EXPR): Delete.
+ (convert_default_arg): Change prototype.
+ (check_default_argument): Declare.
+ (search_tree): Likewise.
+ * call.c (convert_default_arg): Take the function to which the
+ default argument belongs as a parameter, and do any necessary
+ instantiation here, instead of ...
+ (build_over_call): Here.
+ * decl.c (local_variable_p): New function.
+ (check_default_argument): Likewise, split out and tidied from ...
+ (grokparms): Here.
+ * error.c (dump_expr): Don't set PARM_DECL_EXPR.
+ * pt.c (tsubst_call_declarator_parms): New function.
+ (for_each_template_parm): Handle ARRAY_REFs. Do the obvious thing
+ with CALL_EXPRs, rather than trying to be clever.
+ (tsubst): Use tsubst_call_declarator_parms.
+ * tree.c (search_tree): Don't make it static.
+ * typeck.c (convert_arguments): Use new interface to
+ convert_default_arg.
+
+1999-01-20 Mark Mitchell <mark@markmitchell.com>
+
+ * error.c (dump_function_decl): Don't print the argument types for
+ a function when the verbosity level is negative.
+
+ * call.c (build_over_call): Check format attributes at call-time.
+
+ * pt.c (tsubst_copy): Fix comment.
+ (unify): Don't allow unification with variable-sized arrays.
+
+ * semantics.c (finish_stmt_expr): When processing a template make
+ the BIND_EXPR long-lived.
+
+1999-01-19 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Make vtables comdat here.
+ (import_export_vtable): Not here.
+
+1999-01-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_component_ref): Wrap an OVERLOAD around a unique
+ non-static member function.
+
+1999-01-18 Nathan Sidwell <nathan@acm.org>
+
+ * class.c (instantiate_type): Only diagnose illegal address of member
+ function if complaining.
+
+ * decl.c (lookup_name_real): Remove duplicate code.
+
+1999-01-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (copy_template_template_parm): Use permanent_obstack.
+
+1999-01-18 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * pt.c (unify): Remove restrictions on deduction of argument
+ of template template parameters.
+
+1999-01-18 Nathan Sidwell <nathan@acm.org>
+
+ * rtti.c (build_dynamic_cast_1): Resolve OFFSET_REF exprs.
+
+ * class.c (resolve_address_of_overloaded_function): Show list of
+ all candidates, when none of them match.
+
+1999-01-18 Chip Salzenberg <chip@perlsupport.com>
+
+ * typeck.c (comp_ptr_ttypes_reinterpret): Per ANSI, tighten up
+ definition of 'casting away const' in reinterpret_cast<>.
+
+1999-01-18 Graham <grahams@rcp.co.uk>
+
+ * cvt.c: Add include for decl.h, remove extern for
+ static_aggregates which is now provided by decl.h.
+
+ * Makefile.in (cvt.o): Add dependency for decl.h and missing
+ dependencies for convert.h and flags.h.
+
+1999-01-18 Nathan Sidwell <nathan@acm.org>
+
+ * decl2.c (do_dtors): Set current location to that of the
+ decl, for sensible diagnostics and debugging.
+ (check_classfn): Issue `incomplete type' error, if
+ class is not defined.
+
+1999-01-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h: Add prototype for bound_pmf_p.
+
+1999-01-16 Jason Merrill <jason@yorick.cygnus.com>
+ Manfred Hollstein <manfred@s-direktnet.de>
+
+ * decl.c (grokdeclarator): Don't make 'main(){}' an error with only
+ -Wreturn-type.
+
+1999-01-16 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (struct lang_type): Added has_mutable flag.
+ (CLASSTYPE_HAS_MUTABLE): New macro to access it.
+ (TYPE_HAS_MUTABLE_P): New macro to read it.
+ (cp_has_mutable_p): Prototype for new function.
+ * class.c (finish_struct_1): Set has_mutable from members.
+ * decl.c (cp_finish_decl): Clear decl's TREE_READONLY flag, if
+ it contains a mutable.
+ * typeck.c (cp_has_mutable_p): New function.
+
+1999-01-15 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (process_template_parm): Ignore top-level qualifiers on
+ non-type parameters.
+
+ * decl.c (start_function): Use current_function_parms in the call
+ to require_complete_type_for_parms, not the probably empty
+ DECL_ARGUMENTS.
+
+1999-01-14 Jason Merrill <jason@yorick.cygnus.com>
+
+ * semantics.c (finish_asm_stmt): Don't warn about redundant volatile.
+
+ * decl2.c (import_export_class): MULTIPLE_SYMBOL_SPACES only means
+ that we don't suppress the other copies.
+ * lex.c (handle_cp_pragma): Likewise.
+
+1999-01-13 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokdeclarator): Undo 1998-12-14 change.
+ * tree.c (build_cplus_array_type_1): Likewise.
+ * pt.c (instantiate_class_template): Remove misleading comment.
+ (tsubst_aggr_type): Substitute if there are template parameters,
+ regardless of whether or not they use template arguments.
+ (unify): Likewise, but for unification.
+
+1999-01-12 Richard Henderson <rth@cygnus.com>
+
+ * cp-tree.h (flag_permissive): Declare extern.
+
+1999-01-06 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (IDENTIFIER_TYPENAME_P): Use OPERATOR_TYPENAME_FORMAT
+ here.
+ (lang_type): Add is_partial_instantiation. Decrease width of
+ dummy.
+ (PARTIAL_INSTANTIATION_P): New macro.
+ (OPERATOR_TYPENAME_P): Remove.
+ * decl.c (unary_op_p): Use IDENTIFIER_TYPENAME_P, not
+ OPERATOR_TYPENAME_P.
+ (grok_op_properties): Likewise.
+ * friend.c (do_friend): Handle friends that are member functions
+ correctly.
+ * lex.c (init_parse): Use OPERATOR_TYPENAME_FORMAT.
+ * pt.c (instantiate_class_template): Rework for clarity. Avoid
+ leaving TYPE_BEING_DEFINED set in obscure cases. Don't do
+ any more partial instantiation than is absolutely necessary for
+ implicit typename. Set PARTIAL_INSTANTIATION_P.
+ (tsubst_decl): Use IDENTIFIER_TYPENAME_P.
+ * semantics.c (begin_class_definition): Handle partial
+ specializations of a type that was previously partially
+ instantiated.
+
+Wed Jan 6 03:18:53 1999 Mark Elbrecht <snowball3@usa.net.
+
+ * g++spec.c (LIBSTDCXX): Provide default definition.
+ (lang_specific_driver): Use LIBSTDCXX instead of "-lstdc++".
+
+Tue Jan 5 22:11:25 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (g++.o): Depend on prefix.h.
+
+1999-01-04 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (bound_pmf_p): New fn.
+ * typeck.c (build_c_cast): Use it.
+
+ * decl.c (grok_op_properties): Use same_type_p.
+
+
+Copyright (C) 1999 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2000 b/gcc-4.9/gcc/cp/ChangeLog-2000
new file mode 100644
index 000000000..7be14cd5b
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2000
@@ -0,0 +1,7281 @@
+2000-12-29 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (init_decl_processing): Fix sign of wchar_type_node.
+
+2000-12-29 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (pushclass): Remove #if 0'd code.
+ * cp-tree.h (overload_template_name): Remove.
+ * decl.c (store_bindings): Simplify.
+ (pop_from_top_level): Likewise.
+ * pt.c (overload_template_name): Remove.
+ (instantiate_decl): Don't call push_to_top_level if it's not
+ needed.
+
+2000-12-28 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (register_local_specialization): Don't return a value.
+ (lookup_template_class): Use move-to-front heuristic when looking
+ up template instantiations.
+ (instantiate_decl): Only push_to_top_level when we're actually
+ going to instantiate the template.
+
+2000-12-29 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * search.c (binfo_for_vtable): Return least derived class, not
+ most. Handle secondary vtables.
+
+2000-12-22 Jason Merrill <jason@redhat.com>
+
+ * pt.c (more_specialized): Don't optimize len==0.
+ (fn_type_unification): If we're adding the return type, increase len.
+
+ * typeck.c (build_binary_op): Fix pmf comparison logic.
+
+ * call.c (joust): Use DECL_NONSTATIC_MEMBER_FUNCTION_P, not
+ DECL_STATIC_FUNCTION_P.
+
+ * semantics.c (genrtl_finish_function): Don't try to jump to
+ return_label unless it exists.
+
+ In partial ordering for a call, ignore parms for which we don't have
+ a real argument.
+ * call.c (joust): Pass len to more_specialized.
+ (add_template_candidate_real): Strip 'this', pass len.
+ * pt.c (more_specialized): Pass len down. Lose explicit_args parm.
+ (get_bindings_order): New fn. Pass len down.
+ (get_bindings_real): Strip 'this', pass len.
+ (fn_type_unification): Likewise.
+ (type_unification_real): Succeed after checking 'len' args.
+ (most_specialized_instantiation): Lose explicit_args parm.
+ * class.c (resolve_address_of_overloaded_function): Strip 'this',
+ pass len.
+
+2000-12-21 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_decl): A FUNCTION_DECL has DECL_RESULT, not
+ DECL_TEMPLATE_RESULT.
+
+ * search.c (lookup_field_r): Call lookup_fnfields_1, not
+ lookup_fnfields_here.
+
+ * parse.y (typename_sub2): Return the TYPE_DECL, not the type.
+
+ * call.c (build_object_call): Also allow conversions that return
+ reference to pointer to function.
+ (add_conv_candidate): Handle totype being ref to ptr to fn.
+ (build_field_call): Also allow members of type reference to function.
+ Lose support for calling pointer to METHOD_TYPE fields.
+
+ * error.c (dump_expr): Handle *_CAST_EXPR.
+
+ * typeck2.c (build_scoped_ref): Always convert to the naming class.
+
+ * tree.c (break_out_cleanups): Lose.
+ * cp-tree.h: Remove prototype.
+ * typeck.c (build_component_ref): Don't break_out_cleanups.
+ (build_compound_expr): Likewise.
+ * semantics.c (finish_expr_stmt): Likewise.
+
+2000-12-20 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h: Update declarations.
+ * decl.c (finish_case_label): Return the new stmt node.
+ * semantics.c (finish_goto_stmt): Likewise.
+ (finish_expr_stmt, finish_return_stmt): Likewise.
+ (finish_break_stmt, finish_continue_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ * parse.y (already_scoped_stmt): Set STMT_LINENO.
+ (compstmt, implicitly_scoped_stmt, stmt): Likewise.
+ (simple_if, simple_stmt): Return the new stmt node.
+ (save_lineno): New.
+
+2000-12-18 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * cp-tree.h: Don't declare warn_long_long.
+
+2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * tree.c (no_linkage_helper): Use CLASS_TYPE_P instead of
+ IS_AGGR_TYPE.
+
+2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (unify): Handle when both ARG and PARM are
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+
+2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (reduce_template_parm_level): Set DECL_ARTIFICIAL and
+ DECL_TEMPLATE_PARM_P.
+
+2000-12-15 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Reorganize. Now with 100% fewer SAVE_EXPRs!
+
+ * init.c (build_new_1): Don't strip quals from type.
+
+ * decl.c (pushdecl): Don't check for linkage on a non-decl.
+
+ * call.c (build_op_delete_call): See through ARRAY_TYPEs.
+
+ * call.c (build_new_function_call): Lose space before paren in
+ error message.
+ (build_new_method_call): Likewise.
+
+ * typeck2.c (build_m_component_ref): Propagate quals from datum.
+
+2000-12-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (check_explicit_specialization): Propagate default
+ function arguments to explicit specializations.
+
+2000-12-13 DJ Delorie <dj@redhat.com>
+
+ * typeck.c (build_binary_op): Do signed/unsigned warnings for >?
+ and <? operators.
+
+2000-12-08 Jason Merrill <jason@redhat.com>
+
+ * error.c (dump_function_name): Don't let the user see __comp_ctor.
+
+ Clean up copy-initialization in overloading code.
+ * call.c (build_user_type_conversion_1): Die if we are asked to
+ convert to the same or a base type.
+ (implicit_conversion): Avoid doing so. Lose reference binding code.
+ (convert_like_real): Treat BASE_CONV and RVALUE_CONV as implicit
+ direct-initialization. Also do direct-init part of copy-init.
+ (build_user_type_conversion): Don't provide context to convert_like.
+ * cvt.c (ocp_convert): build_user_type_conversion will now provide
+ the constructor call for copy-init.
+
+ * pt.c (tsubst_decl): Call clone_function_decl here if this is an
+ instantiation of a member template.
+ (do_decl_instantiation): Not here.
+
+2000-12-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (check_field_decls): Don't special case anonymous
+ fields in error messages.
+ (note_name_declared_in_class): Use %D on diagnostic.
+
+ * tree.c (pod_type_p): Use strip_array_types.
+ (cp_valid_lang_attribute): Likewise.
+ * typeck.c (cp_type_quals): Strip arrays separately, to avoid
+ multiple evaluations.
+ (cp_has_mutable_p): Use strip_array_types.
+
+2000-12-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (sufficient_parms_p): Declare new function.
+ * call.c (sufficient_parms_p): New function, broken out of ...
+ (add_function_candidate): ... here. Use it.
+ (add_conv_candidate): Use it.
+ * decl.c (grok_ctor_properties): Use it.
+
+2000-12-07 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (copy_body_r): Set STMT_IS_FULL_EXPR_P on EXPR_STMT.
+
+2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (lang_decode_option): Handle -Wformat-security.
+
+2000-12-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (verify_class_unification): New function.
+ (get_class_bindings): Use it.
+ (try_class_unification): Tidy.
+ (unify): Handle when argument of a template-id is not
+ template parameter dependent.
+ (template_args_equal): Handle when TREE_CODE's do not match.
+
+2000-12-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * lang-specs.h (c++): When invoking the stand-alone preprocessor
+ for -save-temps, pass all relevant -Defines to it, and then don't
+ pass them to cc1plus.
+
+2000-12-05 Will Cohen <wcohen@redhat.com>
+
+ * decl.c (finish_case_label): Cleared
+ more_cleanups_ok in surrounding function scopes.
+ (define_label): Likewise.
+
+2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (IDENTIFIER_VIRTUAL_P): Document.
+ (get_matching_virtual): Remove.
+ (look_for_overrides): Declare new function.
+ * decl.c (grokfndecl): Don't set IDENTIFIER_VIRTUAL_P or
+ DECL_VINDEX here.
+ * class.c (check_for_override): Move base class iteration code
+ to look_for_overrides.
+ * search.c (next_baselink): Remove.
+ (get_virtuals_named_this): Remove.
+ (get_virtual_destructor): Remove.
+ (tree_has_any_destructors_p): Remove.
+ (struct gvnt_info): Remove.
+ (check_final_overrider): Remove `virtual' from error messages.
+ (get_matching_virtuals): Remove. Move functionality to ...
+ (look_for_overrides): ... here, and ...
+ (look_for_overrides_r): ... here. Set DECL_VIRTUAL_P, if found
+ to be overriding.
+
+2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (get_delta_difference): If via a virtual base,
+ return zero.
+ * cvt.c (cp_convert_to_pointer): If via a virtual base, do no
+ adjustment.
+
+2000-12-04 Richard Henderson <rth@redhat.com>
+
+ * error.c (dump_tree): Use output_add_string not OB_PUTS.
+
+2000-12-04 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_type): Mangle VECTOR_TYPE with "U8__vector".
+ (write_builtin_type): Pass intSI_type_node and the like through
+ type_for_mode.
+ * method.c (process_overload_item): Mangle VECTOR_TYPEs with 'o'.
+ Pass intSI_type_node and the like through type_for_mode.
+ * decl2.c (arg_assoc_type): Handle VECTOR_TYPE like COMPLEX_TYPE.
+ * pt.c (tsubst, unify): Likewise.
+ * tree.c (walk_tree): Likewise.
+ * error.c (dump_type): Likewise.
+ (dump_type_prefix, dump_type_suffix): Don't bother with VECTOR_TYPE.
+
+ * Make-lang.in: Tweak top comment for emacs.
+ (cp/TAGS): Restore.
+
+ * except.c (expand_throw): Use push_throw_library_fn for _Jv_Throw.
+
+ * class.c (clone_function_decl): Robustify.
+
+2000-12-04 Michael Matz <matzmich@cs.tu-berlin.de>
+
+ * decl.c (store_bindings): Only search in the non modified
+ old_bindings for duplicates.
+
+2000-12-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (dump_function_decl): Use DECL_VIRTUAL_P, not
+ TYPE_POLYMORPHIC_P.
+
+ * typeck.c (build_static_cast): Remove unused variable.
+
+2000-12-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c: Fix typo in comment.
+
+2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (warn_format): Remove definition.
+ (lang_decode_option): Handle -Wformat-nonliteral,
+ -Wno-format-extra-args and -Wno-format-y2k. Use set_Wformat.
+
+2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Don't define.
+ (init_decl_processing): Don't create string_type_node,
+ const_string_type_node, wint_type_node, intmax_type_node,
+ uintmax_type_node, default_function_type, ptrdiff_type_node and
+ unsigned_ptrdiff_type_node. Adjust position of call to
+ c_common_nodes_and_builtins.
+ (identifier_global_value): New function.
+
+2000-12-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (standard_conversion): Reject pointer to member
+ conversions from ambiguous, inaccessible or virtual bases.
+ * typeck.c (build_static_cast): Don't check pointers to members
+ specially.
+
+2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (do_build_copy_constructor): Preserve cv
+ qualifications when accessing source object members.
+ (do_build_assign_ref): Likewise. Remove separate diagnostics for
+ unnamed fields.
+
+2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (do_build_assign_ref): Construct appropriately
+ CV-qualified base reference. Don't allow const casts in base
+ conversion.
+
+2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_over_call): Use VOID_TYPE_P. Don't die on
+ incomplete return type.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (base_class.1): Produce a _TYPE not a _DECL.
+ * semantics.c (finish_base_specifier): Accept a _TYPE not a
+ _DECL.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (yyerror): Cope if yylval.ttype is NULL.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Diagnose undefined template contexts.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Do type access control on friend
+ class.
+
+2000-11-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokfndecl): Undo COMPONENT_REF damage caused by
+ bison parser ickiness.
+ * pt.c (tsubst_friend_function): Enter namespace scope when
+ tsubsting the function name.
+ * cp-tree.h (DECL_TI_TEMPLATE): Update comment to reflect reality.
+
+2000-11-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (binfo_from_vbase): Return the virtual base's binfo.
+ * cvt.c (cp_convert_to_pointer): Add force parameter.
+ Allow conversions via virtual base if forced.
+ (convert_to_pointer_force): Adjust call to cp_convert_to_pointer.
+ (ocp_convert): Likewise.
+ * search.c (binfo_from_vbase): Return the virtual base's binfo.
+ * typeck.c (get_delta_difference): Adjust handling of virtual
+ bases.
+
+2000-11-26 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (struct list_hash): Remove.
+ (list_hash_table): Make it be an htab.
+ (struct list_proxy): New type.
+ (list_hash_eq): New function.
+ (list_hash_pieces): Renamed from ...
+ (list_hash): ... this.
+ (list_hash_lookup): Remove.
+ (list_hash_add): Remove.
+ (hash_tree_cons): Use the generic hashtable.
+ (mark_list_hash): Remove.
+ (init_tree): Create the hashtable.
+
+2000-11-25 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * method.c (build_mangled_C9x_name): Rename to
+ build_mangled_C99_name. Change C9X references in comments to
+ refer to C99.
+
+2000-11-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (unary_expr): Move VA_ARG from here ...
+ (primary): ... to here.
+
+2000-11-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c (finish_id_expr): If type is error_mark, return
+ error_mark.
+
+2000-11-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Simplify loop exit constructs.
+ Cope when there is no partial instantiation of a template
+ template member.
+
+2000-11-23 J"orn Rennecke <amylaar@redhat.com>
+
+ * Make-lang.in (g++spec.o, cxxmain.o): Depend on $(CONFIG_H).
+
+2000-11-22 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (mangle_conv_op_name_for_type): Don't use `__op'
+ prefix.
+
+ * pt.c (do_decl_instantiate): Explicitly clone constructors and
+ destructors that haven't already been cloned.
+
+2000-11-20 Richard Henderson <rth@redhat.com>
+
+ * parse.y (yyparse_1): Rename the parser entry point.
+
+2000-11-20 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (write_name): Use <unscoped-name> for names directly in
+ function scope.
+ (write_unscoped_name): Accept names directly in function scope.
+
+2000-11-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * lex.c (rid_to_yy, RID_EXPORT): Make unique keyword.
+ * parse.y (extdef): Add EXPORT reduction.
+ * spew.c (yylex): Don't skip export here.
+
+2000-11-19 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (init_decl_processing): Correct name of pure virtual
+ function under the new ABI.
+ * rtti.c (throw_bad_cast): Likewise, for bad cast function.
+ (throw_bad_typeid): Likewise for bad typeid function.
+
+2000-11-18 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokparms): Don't even function types of `void' type,
+ either.
+ * mangle.c (write_type): Don't crash when confronted with the
+ error_mark_node.
+
+ * decl.c (grokparms): Don't create parameters of `void' type.
+
+2000-11-17 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * lex.c (mark_impl_file_chain): Delete.
+ (init_parse): Remove call to ggc_add_string_root. No need to
+ ggc_strdup a string constant. Do not add impl_file_chain to GC
+ roots.
+ (handle_pragma_implementation): No need to ggc_strdup main_filename.
+
+2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_expr, DECL_STMT): Instantiate decl's type.
+
+2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (PARMLIST_ELLIPSIS_P): New macro.
+ * decl.c (grokdeclarator): Don't reject void parms here.
+ (require_complete_types_for_parms): Simplify, use
+ complete_type_or_else.
+ (grokparms): Remove bitrot. Remove funcdef parm.
+ Deal with ellipsis parm lists here.
+ * semantics.c (finish_parmlist): Don't append void_list_node
+ here. Set PARMLIST_ELLIPSIS_P.
+
+2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck2.c (incomplete_type_error): Reorganize to avoid
+ excessive diagnostics.
+
+2000-11-16 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * lex.c (struct impl_files, internal_filename): Constify a char *.
+
+2000-11-16 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_special_name_constructor): Don't generate
+ assembler junk when confronted with an old-style constructor.
+ (write_special_name_destructor): Likewise.
+ (mangle_decl_string): Do it here instead.
+
+2000-11-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (op_error): Make error messages clearer.
+
+2000-11-15 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (wrapup_globals_for_namespace): Don't mark things
+ TREE_ASM_WRITTEN when they're not.
+
+2000-11-15 Jason Merrill <jason@redhat.com>
+
+ * typeck2.c (friendly_abort): Uncount the error before handing
+ off to fancy_abort.
+
+2000-11-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (lookup_anon_field): Cope with qv qualifiers.
+
+2000-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Fix typo in comment.
+ * typeck.c (expr_sizeof): Don't crash on errors.
+
+2000-11-14 Jim Wilson <wilson@redhat.com>
+
+ * lang-specs.h: Add %2 after %(cc1_options).
+
+2000-11-14 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (c_sizeof): Be strict about casting result value
+ back to c_size_type_node.
+ (expr_sizeof, c_sizeof_nowarn, c_alignof): Likewise.
+
+2000-11-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * typeck.c (build_unary_op): Use boolean_increment from
+ c-common.c, moving the relevant code there.
+
+2000-11-11 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (mark_addressable): Don't call put_var_into_stack.
+
+ * decl.c (maybe_commonize_var): Set DECL_UNINLINABLE for statics
+ in inlines.
+
+2000-11-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (grokdeclarator, save_function_data): Use memcpy, not bcopy.
+ * lex.c (copy_lang_decl): Likewise.
+
+2000-11-09 Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (cp_dump_tree): Don't dump function bodies here.
+
+ * Make-lang.in (CXX_C_OBJS): Add c-dump.o.
+ (dump.o): Update dependency list.
+ * cp-tree.h (DECL_MAYBE_TEMPLATE): Remove.
+ (flag_dump_translation_unit): Likewise.
+ (CP_TYPE_QUALS): Adjust definition.
+ (DECL_C_BIT_FIELD): Remove.
+ (SET_DECL_C_BIT_FIELD): Likewise.
+ (CLEAR_DECL_C_BIT_FIELD): Likewise.
+ (add_maybe_template): Likewise.
+ (strip_array_types): Likewise.
+ (dump_node_to_file): Likewise.
+ (cp_dump_tree): New function.
+ * decl.c (init_decl_processing): Set lang_dump_tree.
+ * decl2.c (flag_dump_translation_unit): Remove.
+ * dump.c: Move most of it to ../c-dump.c.
+ (cp_dump_tree): New function.
+ * pt.c (add_maybe_template): Remove.
+ * typeck.c (strip_array_types): Likewise.
+
+2000-11-07 Eric Christopher <echristo@redhat.com>
+
+ * decl.c (init_decl_processing): Change definition of
+ __wchar_t to wchar_t. Remove artificial declaration of
+ wchar_t.
+ * lex.c: Change instances of __wchar_t to wchar_t.
+
+2000-11-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * lex.c (do_identifier): Don't lookup_name for operators.
+ * parse.y (operator): Save looking_for_typename.
+ (unoperator): Restore it.
+ * spew.c (frob_opname): Use nth_token for lookahead.
+
+2000-11-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grok_op_properties): Always use coerce_new_type and
+ coerce_delete_type.
+ * decl2.c (coerce_new_type): Use c_size_type_node. Preserve
+ exception specification. Tidy up.
+ (coerce_delete_type): Preserve exception specification. Tidy up.
+
+2000-11-07 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
+ (push_binding_level), error.c (cp_tree_printer), pt.c
+ (process_partial_specialization, tsubst_template_arg_vector),
+ search.c (lookup_member): Use memset () instead of bzero ().
+
+2000-11-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (build_ptrmemfunc_type): Allow error_mark_node.
+
+2000-11-05 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (c++.distdir): Remove.
+
+2000-11-04 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (do_nonmember_using_decl): Allow `extern "C"'
+ declarations from different namespaces to be combined.
+
+2000-11-03 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * decl.c: Include tm_p.h.
+
+2000-11-03 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * tree.c (cp_tree_equal): Use memcmp () instead of bcmp ().
+
+2000-11-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * dump.c (dequeue_and_dump), lex.c (interface_strcmp), method.c
+ (build_overload_value), repo.c (open_repo_file), xref.c
+ (open_xref_file): Use strchr () and strrchr () instead of index ()
+ and rindex ().
+
+2000-11-01 Bernd Schmidt <bernds@redhat.co.uk>
+
+ * call.c (build_over_call): Call fold on the CALL_EXPR.
+
+2000-11-01 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (dump_template_decl): Separate template hearders with
+ space not comma.
+
+2000-10-31 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c: Move TFF_ macros into cp-tree.h. Throughout, replace
+ TS_* flags with corresponding TFF_*. Adjust prototypes of
+ functions (which used to take a tree_string_flags) to take an int.
+
+ * cp-tree.h (enum tree_string_flags): Remove
+ (TFF_PLAIN_IDENTIFIER, TFF_NAMESPACE_SCOPE, TFF_CLASS_SCOPE,
+ TFF_CHASE_NAMESPACE_ALIAS, TFF_CHASE_TYPEDEF, TFF_DECL_SPECIFIERS,
+ TFF_CLASS_KEY_OR_ENUM, TFF_RETURN_TYPE,
+ TFF_FUNCTION_DEFAULT_ARGUMENTS, TFF_EXCEPTION_SPECIFICATION,
+ TFF_TEMPLATE_HEADER, TFF_TEMPLATE_DEFAULT_ARGUMENTS,
+ TFF_TEMPLATE_NAME, TFF_EXPR_IN_PARENS, TFF_SCOPE): New macros.
+ (type_as_string, decl_as_string, expr_as_string,
+ context_as_string): Adjust prototype.
+
+ * class.c (dump_class_hierarchy_r): Use TFF_PLAIN_IDENTIFIER
+ instead of TS_PLAIN.
+
+ * pt.c (mangle_class_name_for_template): Use TFF_CHASE_TYPEDEF
+ instead of TF_CHASE_TYPEDEFS. Use TFF_PLAIN_IDENTIFIER instead of
+ plain `0'.
+
+2000-10-30 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_EXTERNAL_LINKAGE_P): New macro.
+ (linkage_kind): New enumeration.
+ (decl_linkage): New function.
+ * decl2.c (comdat_linkage): Extend comment.
+ * error.c (dump_function_decl): Print the arguments used to
+ instantiate a template, even when not printing the type of the
+ function.
+ * pt.c (convert_nontype_argument): Use DECL_EXTERNAL_LINKAGE_P,
+ not TREE_PUBLIC, to test for external linkage.
+ * tree.c (decl_linkage): New function.
+
+2000-10-28 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (instantiate_decl): Always instantiate static data members
+ initialized in-class.
+
+2000-10-27 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * Make-lang.in: Move all build rules here from Makefile.in,
+ adapt to new context. Wrap all rules that change the current
+ directory in parentheses. Expunge all references to $(P).
+ When one command depends on another and they're run all at
+ once, use && to separate them, not ;. Add OUTPUT_OPTION to
+ all object-file generation rules. Delete obsolete variables.
+
+ * Makefile.in: Delete.
+ * config-lang.in: Delete outputs= line.
+
+2000-10-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (dump_function_decl): Print no space between
+ `ptr-operator' the `type-specifier' of the return type.
+ (dump_type_prefix): Make sure we put space at the appropriate
+ place.
+
+2000-10-23 Jason Merrill <jason@redhat.com>
+
+ * call.c (equal_functions): Also call decls_match for extern "C" fns.
+
+2000-10-22 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_conditional_expr): Use ocp_convert to force
+ rvalue conversion.
+
+2000-10-22 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (standard_conversion): Use RVALUE_CONVs for all
+ expressions that satisfy lvalue_p, not just those that satisfy
+ real_lvalue_p.
+
+ * optimize.c (copy_body_r): Don't treat CALL_EXPRs specially.
+
+ * typeck.c (c_sizeof): Return an expression of `size_t' type,
+ not one with TYPE_IS_SIZETYPE set.
+ (dubious_conversion_warnings): Remove special-case code.
+
+2000-10-21 Geoffrey Keating <geoffk@cygnus.com>
+
+ * decl2.c (arg_assoc_type): Handle VECTOR_TYPE.
+ * error.c (dump_type): Handle VECTOR_TYPE like POINTER_TYPE.
+ (dump_type_prefix): Print vector-of-int as 'int vector'.
+ (dump_type_suffix): Handle VECTOR_TYPE like POINTER_TYPE.
+ * tree.c (walk_tree): Handle VECTOR_TYPE.
+
+ * decl.c (init_decl_processing): Call MD_INIT_BUILTINS.
+
+2000-10-21 Jason Merrill <jason@redhat.com>
+
+ * parse.y (operator): Set got_object from got_scope.
+ Set looking_for_typename.
+ * decl.c (lookup_name_real): Clear val after setting from_obj.
+ Reorganize diagnostic.
+
+2000-10-20 Jason Merrill <jason@redhat.com>
+
+ * tree.c (walk_tree): Don't walk into default args.
+
+ * error.c (dump_expr): Use host_integerp.
+
+2000-10-20 David Edelsohn <edelsohn@gnu.org>
+
+ * typeck2.c (abstract_virtuals_error): Use "because" instead of
+ "since" in error message.
+
+2000-10-20 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * typeck.c (dubious_conversion_warning): Suppress if TYPE_IS_SIZETYPE.
+
+2000-10-20 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * decl.c (revert_static_member_fn): Fixed typo.
+
+2000-10-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (subobject_offset_fn): New type.
+ (dfs_record_base_offsets): Remove.
+ (record_base_offsets): Likewise.
+ (dfs_search_base_offsets): Likewise.
+ (record_subobject_offset): New function.
+ (check_subobject_offset): Likewise.
+ (walk_subobject_offsets): Likewise.
+ (record_subobject_offsets): Likewise.
+ (layout_conflict_p): Reimplement.
+ (layout_nonempty_base_or_field): Correct handling of type
+ conflicts during layout.
+ (layout_empty_base): Likewise.
+ (build_base_field): Adjust to handle new representation of empty
+ base offset table.
+ (build_base_fields): Likewise.
+ (layout_virtual_bases): Likewise.
+ (splay_tree_compare_integer_csts): New function.
+ (layout_class_type): Use a splay_tree, rather than a varray, to
+ represent the offsets of empty bases.
+
+ * cp-tree.h (DECL_ANTICIPATED): Don't require a FUNCTION_DECL.
+ * decl.c (select_decl): Don't return declarations that are
+ DECL_ANTICIPATED.
+
+2000-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Add CPTI_FAKE_STD.
+ (fake_std_node): New macro.
+ * decl.c (in_std): Rename to ...
+ (in_fake_std): ... this.
+ (flag_no_builtin): Remove.
+ (flag_no_nonansi_builtin): Likewise.
+ (walk_namespaces_r): Use fake_std_node.
+ (push_namespace): Use std_identifier.
+ (pop_namespace): Use in_fake_std.
+ (lookup_name_real): Use fake_std_node.
+ (init_decl_processing): When -fhonor-std, create the `std'
+ namespace. Don't create a dummy fake_std_node in that case.
+ Adjust call to c_common_nodes_and_builtins. Use std_identifier.
+ (builtin_function): Put builtins whose names don't begin
+ with `_' in the std namespace.
+ * decl2.c (flag_no_builtin): Remove.
+ (flag_no_nonansi_builtin): Likewise.
+ (set_decl_namespace): Use fake_std_node.
+ (validate_nonmember_using_decl): Likewise.
+ (do_using_directive): Likewise.
+ (handle_class_head): Likewise.
+ * dump.c (dequeue_and_dump): Likewise.
+ * except.c (init_exception_processing): Use std_identifier.
+ * init.c (build_member_call): Use fake_std_node.
+ * rtti.c (init_rtti_processing): Use std_identifier.
+
+2000-10-17 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (back_end_hook): Remove declaration.
+ * decl2.c (back_end_hook): Remove definition.
+
+ * dump.c (dequeue_and_dump): Dump TREE_USED.
+
+2000-10-17 Brad Lucier <lucier@math.purdue.edu>
+
+ * spew.c (snarf_defarg): Cast 2nd arg to obstack_blank to (int).
+
+2000-10-17 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (WINT_TYPE): Define.
+ (init_decl_processing): Create types unsigned_ptrdiff_type_node,
+ c_size_type_node, signed_size_type_node and wint_type_node.
+
+2000-10-17 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (warn_missing_format_attribute): New variable.
+ (lang_decode_option): Decode -Wmissing-format-attribute.
+
+2000-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (qualify_type): Remove.
+ (composite_pointer_type): Fix handling of conversions to `cv void*'.
+
+2000-10-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (parse.c, parse.h): Fix think-o in last patch.
+
+2000-10-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (parse.c, parse.h): Create atomically.
+
+2000-10-12 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (current_obstack): Remove.
+ * decl.c (ggc_p): Remove.
+ (start_decl): Don't use decl_tree_cons.
+ (grokdeclarator): Don't use build_decl_list.
+ (start_function): Don't use decl_tree_cons.
+ (finish_function): Don't mess with obstacks.
+ * decl2.c (grok_x_components): Don't use build_decl_list.
+ * lex.c (make_call_declarator): Don't call decl_tree_cons.
+ (implicitly_declare_fn): Don't call build_decl_list.
+ * parse.y (frob_specs): Don't call build_decl_list or
+ decl_tree_cons.
+ (expr_or_declarator_intern): Don't call decl_tree_cons.
+ (primary): Don't call build_decl_list.
+ (fcast_or_absdcl): Likewise.
+ (typed_declspecs): Don't call decl_tree_cons.
+ (reserved_declspecs): Don't call build_decl_list.
+ (declmods): Likewise.
+ (reserved_typespecquals): Likewise.
+ (aggr): Likewise.
+ (new_type_id): Likewise.
+ (cv_qualifiers): Likewise.
+ (after_type_declarator_intern): Likewise.
+ (notype_declarator_intern): Likewise.
+ (absdcl_intern): Likewise.
+ (named_parm): Likewise.
+ * pt.c (most_specialized_class): Likewise.
+ * repo.c (temporary_obstack): Make it a structure, not a pointer.
+ (init_repo): Initialize it.
+ * search.c (current_obstack): Remove.
+ * typeck2.c (add_exception_specifier): Don't call build_decl_list.
+
+2000-10-09 Richard Henderson <rth@cygnus.com>
+
+ * Make-lang.in (CXX_EXTRA_HEADERS): Remove.
+ (c++ language support bits for libgcc): Remove.
+ (c++.clean): Remove cplib2.txt cleanup.
+ * config-lang.in (headers, lib2funcs): Remove.
+
+ * exception.cc, new.cc, new1.cc, new2.cc: Remove files.
+ * tinfo.cc, tinfo.h, tinfo2.cc, vec.cc: Remove files.
+ * inc/cxxabi.h, inc/exception, inc/new: Remove files.
+ * inc/new.h, inc/typeinfo: Remove files.
+
+2000-10-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (INTMAX_TYPE, UINTMAX_TYPE): Define if not already
+ defined.
+ (init_decl_processing): Initialize intmax_type_node and
+ uintmax_type_node.
+
+2000-10-06 Richard Henderson <rth@cygnus.com>
+
+ * cp-tree.h (struct cp_language_function): Remove x_result_rtx.
+ (original_result_rtx): Remove.
+ * decl.c (save_function_data): Don't clear x_result_rtx.
+ (mark_lang_function): Don't mark it either.
+ * expr.c (fixup_result_decl): Remove.
+ * semantics.c (genrtl_named_return_value): Frob the return decl
+ before calling emit_local_var.
+ (genrtl_finish_function): Don't call fixup_result_decl.
+ Always emit the jump to return_label.
+
+2000-10-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Set current access for enum.
+ (tsubst_enum): Set file & line for enum decl.
+
+ * spew.c (yylex): Remove unused variable.
+
+2000-10-05 Richard Henderson <rth@cygnus.com>
+
+ * semantics.c (genrtl_finish_function): Don't init or check
+ can_reach_end; remove noreturn and return value checks.
+
+2000-10-05 Tom Tromey <tromey@cygnus.com>
+
+ * init.c (build_java_class_ref): Use `build_static_name' with a
+ suffix, not a prefix, to build the class object's name.
+
+2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (access_kind): Fix comment typo.
+ * decl2.c (grokfield): Fix diagnostic typo.
+ * semantics.c (finish_template_type): Fix comment typo.
+ (finish_qualified_object_call_expr): Likewise.
+
+2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_expr, DECL_STMT case): Don't process if
+ tsubsting fails.
+
+2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (frob_id): New static function.
+ (frob_opname): Use it.
+ (yylex): Use it.
+
+2000-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (lang_mark_false_label_stack): Remove.
+ * lex.c (cp_mang_lang_type): Use ggc_alloc_cleared.
+
+2000-09-30 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * gxxint.texi: Use @email for formatting email addresses.
+
+2000-09-29 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c: Remove direct obstack manipulation. Replace with
+ output_buffer-based formatting. Adjust calls to removed macros.
+ (obstack_chunk_alloc, obstack_chunk_free): Remove.
+ (OB_INIT, OB_PUTC, OB_PUTC2, OB_PUTS, OB_PUTID, OB_PUTCP,
+ OB_FINISH, OB_PUTI, OB_END_TEMPLATE): Likewise.
+
+2000-09-24 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi: Move to ../c-tree.texi.
+
+2000-09-20 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (get_guard): Check DECL_FUNCTION_SCOPE_P.
+
+2000-09-21 Andreas Jaeger <aj@suse.de>
+
+ * errfn.c: Move declaration of cp_printer and cp_printers to ...
+ * cp-tree.h: ... here.
+
+ * error.c: Remove declaration of cp_printer.
+
+2000-09-20 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (mark_local_for_remap_r): Handle CASE_LABELs.
+
+2000-09-20 Hans-Peter Nilsson <hp@axis.com>
+
+ * except.c: Delete #if 0:d EXCEPTION_SECTION_ASM_OP-default and
+ users.
+
+2000-09-18 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_function): Robustify.
+
+2000-09-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (check_function_format): Accept a `status' parameter.
+
+ * call.c, typeck.c: Updates calls to `check_function_format'.
+
+2000-09-17 Geoffrey Keating <geoffk@cygnus.com>
+
+ * decl2.c (handle_class_head): Always push some scope even
+ in the error case.
+
+2000-09-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct cp_language_function): Remove
+ x_scope_stmt_stack and name_declared.
+ (current_scope_stmt_stack): Remove.
+ (function_name_declared_p): New macro.
+ (struct lang_decl_flags): Use c_lang_decl as a base class.
+ (context): Remove.
+ (struct lang_decl): Replace saved_tree with context.
+ (DECL_FRIEND_CONTEXT): Adjust accordingly.
+ (SET_DECL_FRIEND_CONTEXT): Likewise.
+ (DECL_VIRTUAL_CONTEXT): Likewise.
+ (DECL_SAVED_TREE): Remove.
+ (C_DECLARED_LABEL_FLAG): Likewise.
+ (cplus_expand_expr_stmt): Don't declare.
+ (add_decl_stmt): Likewise.
+ (add_scope_stmt): Likewise.
+ * decl.c (mark_stmt_tree): Remove.
+ (case_compare): Likewise.
+ (finish_case_label): Use c_add_case_label.
+ (init_decl_processing): Set more language-specific hooks.
+ (build_enumerator): Fix typo in comment.
+ (cplus_expand_expr_stmt): Remove.
+ (mark_lang_function): Use mark_c_language_function.
+ (lang_mark_tree): Use c_mark_lang_decl.
+ * decl2.c: Change order of inclusion.
+ * except.c: Likewise.
+ * expr.c (cplus_expand_expr): Remove handling of STMT_EXPR. Fall
+ back on c_expand_expr.
+ * friend.c: Include expr.h.
+ * init.c: Change order of inclusion.
+ * Makefile.in: Update dependencies.
+ * lex.h (free_lang_decl_chain): Remove.
+ * optimize.c (maybe_clone_body): Use function_name_declared_p.
+ * pt.c (build_template_decl): Don't copy DECL_VIRTUAL_CONTEXT if
+ it doesn't exist.
+ (instantiate_decl): Use function_name_declared_p.
+ * semantics.c (lang_expand_expr_stmt): Remove.
+ (set_current_function_name_declared): Likewise.
+ (current_function_name_declared): Likewise.
+ (begin_compound_stmt): Use function_name_declared_p.
+ (add_decl_stmt): Remove.
+ (setup_vtbl_ptr): Use function_name_declared_p.
+ (add_scope_stmt): Remove.
+ (current_scope_stmt_stack): New function.
+ (cp_expand_stmt): Don't handle SCOPE_STMTs.
+ (expand_body): Use function_name_declared_p.
+ * tree.c (cp_statement_code_p): Don't include SCOPE_STMT.
+ * typeck.c: Change order of includes.
+ (convert_sequence): Remove.
+
+2000-09-14 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * lex.c (reswords): Add _Complex.
+
+2000-09-14 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (cplib2.txt): Depend on cp/Makefile.
+
+2000-09-13 J. David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * init.c (begin_init_stmts): Don't use // comments.
+
+2000-09-12 Jason Merrill <jason@redhat.com>
+
+ * decl.c (maybe_deduce_size_from_array_init): Set do_default for
+ all non-extern arrays.
+
+ * decl.c (grokdeclarator): Complain about 'friend T' for implicit
+ typenames, too. Downgrade complaint to pedwarn.
+ (xref_tag): Warn about surprising behavior of 'friend struct T'.
+ * decl2.c (handle_class_head): Generate a TYPENAME_TYPE for
+ 'class This::Inherited'.
+
+2000-09-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (finish_case_label): Given the LABEL_DECL a
+ DECL_CONTEXT.
+
+2000-09-12 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (TFF_PLAIN_IDENTIFIER, TFF_NAMESPACE_SCOPE,
+ TFF_CLASS_SCOPE, TFF_CHASE_NAMESPACE_ALIAS, TFF_CHASE_TYPDEF,
+ TFF_DECL_SPECIFIERS, TFF_CLASS_KEY_OR_ENUM, TFF_RETURN_TYPE,
+ TFF_FUNCTION_DEFAULT_ARGUMENTS, TFF_EXCEPTION_SPECIFICATION,
+ TFF_TEMPLATE_HEADER, TFF_TEMPLATE_DEFAULT_ARGUMENTS, TFF_SCOPE):
+ New macros.
+ (sorry_for_unsupported_tree, print_scope_operator,
+ print_left_paren, print_right_paren, print_left_bracket,
+ print_right_bracket, print_whitespace): Likewise.
+ (aggr_variety): Rename to class_key_or_enum.
+ (print_type): Rename to print_type_id.
+ (print_type_specifier_seq, print_simple_type_specifier,
+ print_elaborated_type_specifier,
+ print_rest_of_abstract_declarator,
+ print_parameter_declaration_clause, print_exception_specification,
+ print_nested_name_specifier, print_template_id,
+ typedef_original_name, print_template_argument_list_start,
+ print_template_argument_list_end): New functions.
+
+2000-09-11 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi: Add more documentation.
+
+2000-09-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct saved_scope): Remove x_function_parms.
+ (current_function_parms): Don't define.
+ (struct cp_language_function): Remove parms_stored.
+ (current_function_just_assigned_this): Don't define.
+ (current_function_parms_stored): Likewise.
+ (static_ctors): Declare.
+ (static_dtors): Likewise.
+ (SF_EXPAND): Don't define.
+ (expand_start_early_try_stmts): Remove declaration.
+ (store_parm_decls): Likewise.
+ * decl.c (static_ctors): Don't declare.
+ (static_dtors): Likewise.
+ (struct binding_level): Remove this_block.
+ (poplevel): Remove dead code.
+ (set_block): Likewise.
+ (mark_binding_level): Don't mark this_block.
+ (mark_saved_scope): Don't mark x_function_parms.
+ (init_decl_processing): Don't add current_function_parms as a GC
+ root.
+ (check_function_type): Change prototype.
+ (start_function): Remove RTL-generation code.
+ (expand_start_early_try_stmts): Remove.
+ (store_parm_decls): Give it internal linkage. Remove
+ RTL-generation code.
+ (finish_function): Remove RTL-generation code.
+ * decl2.c (static_ctors): Fix formatting.
+ (static_dtors): Likewise.
+ * method.c (use_thunk): Don't call store_parm_decls.
+ (synthesize_method): Likewise.
+ * optimize.c (maybe_clone_body): Likewise.
+ * parse.y (fn.def2): Likewise.
+ (.set_base_init): Likewise.
+ (nodecls): Likewise.
+ * pt.c (instantiate_decl): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Likewise.
+ * semantics.c (genrtl_try_block): Simplify.
+ (expand_body): Use genrtl_start_function and
+ genrtl_finish_function.
+ (genrtl_start_function): New function.
+ (genrtl_finish_function): Likewise.
+
+2000-09-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (cp_tree_printer, case 'P'): Append break.
+
+2000-09-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (frob_opname): Declare.
+ * parse.y (saved_scopes): New static variable.
+ (cp_parse_init): Adjust.
+ (do_id): If lastiddecl is NULL, do do_identifier.
+ (operator): Save scope information.
+ (unoperator): New reduction. Restore scope information.
+ (operator_name): Append unoperator. Call frob_opname.
+ * spew.c (frob_opname): Define.
+
+2000-09-10 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl.c, rtti.c: Include defaults.h if not already included.
+ Don't define the *_TYPE_SIZE macros.
+
+2000-09-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (push_switch): Change prototype.
+ (check_cp_case_value): Remove declaration.
+ (decl_constant_value): Likewise.
+ * decl.c (struct cp_switch): Add switch_stmt and cases.
+ (case_compare): New function.
+ (push_switch): Set switch_stmt. Initialize cases.
+ (pop_switch): Clean up cases.
+ (define_case_label): Rename to ...
+ (finish_case_label): ... this. Do semantic analysis for case
+ labels here.
+ (start_function): Correct comment.
+ * decl2.c (check_cp_case_value): Remove.
+ * expr.c (do_case): Remove.
+ * pt.c (tsubst_expr): Adjust call to finish_case_label.
+ * semantics.c (genrtl_do_poplevel): Remove declaration.
+ (RECHAIN_STMTS): Remove.
+ (finish_break_stmt): Use build_break_stmt.
+ (finish_continue_stmt): Use build_continue_stmt.
+ (finish_switch_cond): Adjust condition here, rater than in
+ c_expand_start_case.
+ (finish_case_label): Remove.
+ * typeck.c (c_expand_return): Remove.
+ (c_expand_start_case): Likewise.
+
+2000-09-07 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi: Document type nodes.
+
+2000-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (init_cp_semantics): Declare.
+ (genrtl_try_block): Don't declare.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_named_return_value): Likewise.
+ * lex.c (init_parse): Call init_cp_semantics.
+ * semantics.c (genrtl_try_block): Give it internal linkage.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_named_return_value): Likewise.
+ (lang_expand_stmt): Rename to ...
+ (cp_expand_stmt): ... this. Only handle C++-specific nodes.
+ (init_cp_semantics): Define.
+
+ * decl.c (initialize_local_var): Remove RTL-generating code.
+ * semantics.c (genrtl_try_block): Fix formatting.
+
+ Move statement-tree facilities from C++ to C front-end.
+ * cp-tree.h (cp_tree_index): Remove CPTI_VOID_ZERO.
+ (void_zero_node): Remove.
+ (stmt_tree): Likewise.
+ (scope_chain): Adjust.
+ (language_function): Rename to cp_language_function.
+ (cp_function_chain): Adjust.
+ (current_stmt_tree): Remove.
+ (last_tree): Likewise.
+ (last_expr_type): Likewise.
+ (struct lang_decl): Adjust.
+ (STMT_IS_FULL_EXPR_P): Remove.
+ (add_tree): Remove.
+ (begin_stmt_tree): Likewise.
+ (finish_stmt_tree): Likewise.
+ (walk_tree_fn): Likewise.
+ (walk_stmt_tree): Likewise.
+ * class.c (finish_struct): Replace use of add_tree with add_stmt.
+ * decl.c (mark_stmt_tree): Adjust type.
+ (init_decl_processing): Don't build void_zero_node.
+ (initialize_local_var): Adjust usage of current_stmt_tree.
+ (finish_enum): Use add_stmt, not add_tree.
+ (save_function_data): Adjust use of language_function.
+ (finish_constructor_body): Use add_stmt, not add_tree.
+ (finish_destructor_body): Likewise.
+ (push_cp_function_context): Adjust use of language_function.
+ (pop_cp_function_context): Likewise.
+ (mark_lang_function): Likewise.
+ (mark_cp_function_context): Likewise.
+ * init.c (build_aggr_init): Adjust use of current_stmt_tree.
+ (build_vec_init): Likewise.
+ * semantics.c (SET_LAST_STMT): Remove.
+ (RECHAIN_STMTS): Don't use it.
+ (stmts_are_full_exprs_p): Adjust use of current_stmt_tree.
+ (current_stmt_tree): Define.
+ (add_tree): Remove.
+ (finish_goto_stmt): Use add_stmt, not add_tree.
+ (finish_expr_stmt): Likewise.
+ (begin_if_stmt): Likewise.
+ (finish_then_clause): Likewise.
+ (begin_while_stmt): Likewise.
+ (begin_do_stmt): Likewise.
+ (finish_return_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_break_stmt): Likewise.
+ (finish_continue_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (finish_case_label): Likewise.
+ (begin_try_block): Likewise.
+ (begin_function_try_block): Likewise.
+ (begin_handler): Likewise.
+ (begin_catch_block): Likewise.
+ (begin_compound_stmt): Likewise.
+ (begin_asm_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ (finish_label_stmt): Likewise.
+ (add_decl_stmt): Likewise.
+ (finish_subobject): Likewise.
+ (finish_decl_cleanup): Likewise.
+ (finish_named_return_value): Likewise.
+ (setup_vtbl_ptr): Likewise.
+ (add_scope_stmt): Likewise.
+ (finish_stmt_expr): Likewise.
+ (prune_unused_decls): Remove.
+ (begin_stmt_tree): Likewise.
+ (finish_stmt_tree): Likewise.
+ (prep_stmt): Adjust use of current_stmt_tree.
+ (lang_expand_stmt): Likewise.
+ * tree.c (statement_code_p): Remove.
+ (cp_statement_code_p): New function.
+ (walk_stmt_tree): Remove.
+ (init_tree): Set lang_statement_code_p.
+
+2000-09-06 Zack Weinberg <zack@wolery.cumb.org>
+
+ Integrated preprocessor.
+
+ * Make-lang.in, Makefile.in: Remove all references to input.c,
+ gxx.gperf, and hash.h. Add ../c-lex.o to C_OBJS.
+ * gxx.gperf, hash.h, input.c: Delete.
+ * lang-specs.h: Pass -lang-c++ to cc1plus so cpplib is
+ initialized properly.
+
+ * class.c (fixup_pending_inline): Take a tree, not a
+ struct pending_inline *. All callers changed.
+ (init_class_processing): Set RID_PUBLIC, RID_PRIVATE,
+ RID_PROTECTED entries in ridpointers[] array here.
+ * decl.c (duplicate_decls): Do not refer to struct
+ pending_inline.
+ (record_builtin_type, init_decl_processing): Use RID_MAX not
+ CP_RID_MAX.
+ (grokdeclarator): Use C_IS_RESERVED_WORD.
+ * decl2.c (lang_decode_option): Ignore -lang-c++ for sake of
+ cpplib.
+ (grok_x_components): Do not inspect pending_inlines chain.
+
+ * cp-tree.h (struct lang_identifier): Add rid_code entry.
+ (C_IS_RESERVED_WORD, C_RID_CODE, C_RID_YYCODE): New.
+ (flag_no_gnu_keywords, flag_operator_names, rid_to_yy): Declare.
+ (DEFARG_LENGTH, struct pending_inline, TIME_IDENTIFIER_TIME,
+ TIME_IDENTIFIER_FILEINFO): Kill.
+ Update prototypes.
+ * lex.h: Expunge cp_rid. Rewrite RIDBIT macros to use just a
+ single 32-bit word.
+ * parse.y: Call do_pending_inlines unconditionally.
+ reinit_parse_for_method is now snarf_method. fn.defpen is no
+ longer necessary. Remove unnecessary <itype> annotation on
+ SCOPE. Do not refer to end_of_file or struct pending_inline.
+ * semantics.c (begin_inline_definitions): Call
+ do_pending_inlines unconditionally.
+
+ * lex.c: Remove all code now shared with C front end.
+ Initialize cpplib properly if USE_CPPLIB. Put reserved words
+ into the get_identifier table. Rewrite pragma handling to
+ work with the registry. Move code to save tokens for later
+ processing to spew.c.
+
+ * spew.c: Rewrite everything in terms of token streams instead
+ of text. Move routines here from lex.c / input.c as
+ appropriate. GC-mark trees hanging off the pending inlines
+ chain.
+
+2000-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ * NEWS: Mention that the named return value extension has been
+ deprecated.
+ * cp-tree.h (original_result_rtx): Define.
+ (TREE_REFERENCE_EXPR): Remove.
+ (DECL_VPARENT): Likewise.
+ (pushdecl_nonclass_level): Likewise.
+ (store_return_init): Likewise.
+ (reinit_lang_specific): Likewise.
+ (genrtl_named_return_value): Change prototype.
+ * decl.c (original_result_rtx): Remove.
+ (cp_finish_decl): Don't build DECL_STMTs for RESULT_DECLs.
+ Do not generate RTL for local variables here.
+ (store_return_init): Remove.
+ * semantics.c (genrtl_named_return_value): Simplify. Fold in
+ store_return_init.
+ (finish_named_return_value): Adjust accordingly. Warn that this
+ extension is deprecated.
+ (lang_expand_stmt): Adjust call to genrtl_named_return_value.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (type_unification_real): Replace switch with if.
+ (unify): Tsubst non-type parms before comparing.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (dump_typename): New function, broken out of ...
+ (dump_type): ... here. Use it.
+ * typeck.c (same_type_p): Use cp_tree_equal for TYPENAME_TYPE.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (build_offset_ref): Deal with namespace scoped
+ TEMPLATE_ID_EXPRs.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (resolve_address_of_overloaded_function): Add
+ explanation message.
+ * decl.c (define_case_label): Reformat explanation.
+ * decl2.c (finish_static_data_member_decl): Likewise.
+ (grokfield): Likewise.
+ * friend.c (do_friend): Likewise.
+
+2000-09-05 Zack Weinberg <zack@wolery.cumb.org>
+
+ * tree.c (walk_tree): Expose tail recursion.
+ (walk_stmt_tree): New function.
+ * cp-tree.h: Prototype walk_stmt_tree.
+ * semantics.c (prune_unused_decls): Operate on SCOPE_STMTs not
+ the BLOCKs directly. If a BLOCK has no variables after
+ pruning, discard it.
+ (finish_stmt_tree): Use walk_stmt_tree. No need to save and
+ restore the line number.
+
+2000-09-05 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (CXX_TREE_H): Add dependency on HTAB_H.
+ (pt.o): Remove dependency on HTAB_H.
+ * cp-tree.h: Include hashtab.h.
+ (walk_tree): Change prototype.
+ (walk_tree_without_duplicates): New function.
+ * decl.c (check_default_argument): Use it.
+ * optimize.c (remap_decl): Adjust calls to walk_tree.
+ (copy_body): Likewise.
+ (expand_calls_inline): Likewise.
+ (calls_setjmp_p): Use walk_tree_without_duplicates.
+ * pt.c: Don't include hashtab.h.
+ (for_each_template_parm): Use walk_tree_without_duplicates.
+ * semantics.c (finish-stmt_tree): Likewise.
+ (expand_body): Likewise.
+ * tree.c (walk_tree): Add additional parameter.
+ (walk_tree_without_duplicates): New function.
+ (count_trees): Use it.
+ (verify_stmt_tree): Adjust call to walk_tree.
+ (find_tree): Use walk_tree_without_duplicates.
+ (no_linkage_check): Likewise.
+ (break_out_target_exprs): Adjust call to walk_tree.
+ (cp_unsave): Likewise.
+
+2000-09-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.def (BOUND_TEMPLATE_TEMPLATE_PARM): New tree code.
+ (TEMPLATE_TEMPLATE_PARM): Adjust comment.
+ * cp-tree.h (TYPE_BINFO): Adjust comment.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
+ (TEMPLATE_TYPE_PARM_INDEX): Likewise.
+ (IS_AGGR_TYPE): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
+ (TYPE_TEMPLATE_INFO): Likewise.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): Likewise.
+ * class.c (push_nested_class): Likewise.
+ * decl.c (lookup_name_real): Likewise.
+ (grokdeclarator): Likewise.
+ (grok_op_properties): Likewise.
+ (xref_tag): Likewise.
+ (xref_basetypes): Likewise.
+ * decl2.c (constructor_name_full): Likewise.
+ (arg_assoc_template_arg): Add TEMPLATE_TEMPLATE_PARM case.
+ (arg_assoc_type): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
+ * error.c (dump_type): Split TEMPLATE_TEMPLATE_PARM case.
+ (dump_type_prefix): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (dump_type_suffix): Likewise.
+ * init.c (is_aggr_type): Use BOUND_TEMPLATE_TEMPLATE_PARM
+ instead.
+ (get_aggr_from_typedef): Likewise.
+ * mangle.c (write_type): Split TEMPLATE_TEMPLATE_PARM case.
+ (write_expression): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (write_template_parm): Likewise.
+ (write_template_template_parm): Check tree code instead of
+ using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ * method.c (build_overload_nested_name): Add
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+ (process_overload_item): Split TEMPLATE_TEMPLATE_PARM case.
+ * parse.y (bad_parm): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ * pt.c (convert_template_argument): Check tree code instead of
+ using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ (for_each_template_parm_r): Split TEMPLATE_TEMPLATE_PARM case.
+ (for_each_template_parm): Adjust comment.
+ (tsubst): Add BOUND_TEMPLATE_TEMPLATE_PARM. Reorganize.
+ (tsubst_copy): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (unify): Add BOUND_TEMPLATE_TEMPLATE_PARM. Reorganize. Use
+ template_args_equal to compare template template parameter cases.
+ * ptree.c (print_lang_type): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ * search.c (lookup_field_1): Use BOUND_TEMPLATE_TEMPLATE_PARM
+ instead.
+ * tree.c (copy_template_template_parm): Decide whether to create
+ a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM node.
+ (walk_tree): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (copy_tree_r): Likewise.
+ * typeck.c (comptypes): Likewise. Check tree code instead of
+ using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+
+2000-09-04 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * decl.c (finish_function): Move the code for handling functions
+ marked with the constructor and destructor attributes inside the
+ expand_p block.
+
+2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (resolve_offset_ref): Deal with TEMPLATE_ID_EXPR.
+
+2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Remove abort.
+ * tree.c (get_type_decl): Allow error_mark_node.
+
+2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (arg_assoc): Deal with COMPONENT_REFs inside
+ TEMPLATE_ID_EXPRs.
+
+2000-09-03 Mark Mitchell <mark@codesourcery.com>
+
+ * operators.def (ALIGNOF_EXPR, MAX_EXPR, MIN_EXPR): Change
+ new ABI mangling.
+
+2000-09-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (named_class_head): Check for TYPENAME_TYPE. Simplify
+ union tag mismatch error reporting.
+
+2000-09-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_scoped_method_call): Check it is not a namespace.
+
+2000-08-30 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (LOCAL_CLASS_P): Use decl_function_context.
+
+ * tree.c (bot_manip): Check TREE_CONSTANT rather than
+ !TREE_SIDE_EFFECTS. Call break_out_target_exprs and
+ build_target_expr_with_type for the non-AGGR_INIT_EXPR case.
+
+ * decl.c (start_function): Always call make_function_rtl.
+
+2000-08-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * semantics.c (prune_unused_decls): New function.
+ (finish_stmt_tree): Call it via walk_tree.
+
+2000-08-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * class.c (build_secondary_vtable): Constify a char *.
+ * decl.c (init_decl_processing): Initialize function_id_node,
+ pretty_function_id_node, and func_id_node.
+ * input.c (struct input_source): Constify 'str'.
+ (feed_input): Constify first argument.
+ * mangle.c (write_identifier): Constify argument.
+ * pt.c (mangle_class_name_for_template): Constify argument.
+
+2000-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (mark_addressable): Remove code that pokes around in
+ RTL.
+
+2000-08-28 Jason Merrill <jason@redhat.com>
+
+ * lex.c (file_name_nondirectory): Move to toplev.c.
+
+ * cp-tree.h (LOCAL_CLASS_P): New macro.
+ * class.c (finish_struct_1): Use it.
+
+2000-08-27 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Remove unexplained voodoo.
+ (write_encoding): Pass another argument to write_name.
+ (write_name): Add ignore_local_scope parameter. Fix handling of
+ local names.
+ (write_nested_name): Use write_unqualified_name.
+ (write_prefix): Likewise. Skip out on FUNCTION_DECLs.
+ (write_template_prefix): Use write_unqualified_name.
+ (write_component): Remove.
+ (write_local_name): Add parameter. Use direct local entity to
+ discriminator calculation.
+ (write_class_enum_type): Pass another argument to write_name.
+ (write_template_template_arg): Likewise.
+ (make_guard_variable): Likewise.
+
+2000-08-27 Jason Merrill <jason@redhat.com>
+
+ * decl.c (pushdecl): Matching decls for local externs are found in
+ the current level. Propagate linkage information from previous
+ declarations.
+
+2000-08-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi (Expressions): Fix typo.
+
+2000-08-25 Greg McGary <greg@mcgary.org>
+
+ * tree.c (init_tree): Use ARRAY_SIZE.
+
+2000-08-25 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_tree_printer): Rework.
+
+2000-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (CXX_LIB2FUNCS): Remove cp-demangle.o and
+ dyn-string.o.
+ (CXX_LIB2SRCS): Remove cp-demangle.c and dyn-string.c.
+ (cp-demangle.o): Remove target.
+ (dyn-string.o): Likewise.
+
+ * decl.c (grokfndecl): Require that `main' return an `int'.
+ * mangle.c (write_encoding): Don't mangle return types for
+ conversion functions.
+
+2000-08-25 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (tree_formatting_info): New data type.
+ (tree_being_formatted): New macro.
+ (tree_formatting_flags): Likewise.
+ (put_whitespace): Likewise.
+ (print_tree_identifier): Likewise.
+ (print_identifier): Likewise.
+ (cp_tree_printer, print_function_argument_list, print_declaration,
+ print_expression, print_function_declaration,
+ print_function_parameter, print_type, print_cv_qualifier): New
+ functions.
+ (init_error): Initialize lang_printer.
+
+2000-08-24 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_ptrmemfunc): Just reinterpret if there's no
+ adjustment necessary.
+
+2000-08-24 Greg McGary <greg@mcgary.org>
+
+ * cp-tree.h (MAIN_NAME_P): Remove macro.
+
+2000-08-24 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (print_instantiation_context): Don't forget to flush the
+ buffer.
+
+2000-08-23 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_ptrmemfunc): Save the input pmf.
+
+ * method.c (process_modifiers): Use same_type_p.
+
+2000-08-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_CLONED_FUNCTION_P): Check DECL_LANG_SPECIFIC.
+ * mangle.c (write_function_type): Change prototype.
+ (write_encoding): Don't mangle return types for
+ constructors or destructors.
+ (write_type): Adjust call to write_function_type.
+ * pt.c (instantiate_template): Instantiate alternate entry points
+ when instantiating the main function.
+
+2000-08-23 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_print_error_function): Don't use embedded '\n' in
+ output_printf.
+
+2000-08-23 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl.c (init_decl_processing): Remove bogus initialization.
+ * error.c (lang_print_error_function): Restore here.
+ (init_error): Initialize print_error_function.
+
+2000-08-22 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * decl2.c (arg_assoc): Revert my 2000-08-11 change.
+
+2000-08-22 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * Makefile.in (error.o): Depends on diagnostic.h
+
+ * cp-tree.h (problematic_instantiation_changed,
+ record_last_problematic_instantiation, current_instantiation,
+ print_instantiation_context): Declare.
+ (maybe_print_template_context): Remove.
+
+ * decl.c (init_decl_processing): Set print_error_function to NULL.
+ (lang_print_error_function): Remove, since we're using a new
+ machinery.
+
+ * error.c: #include diagnostic.h
+ (function_category): New function.
+ (cp_diagnostic_starter): Likewise.
+ (cp_diagnostic_finalizer): Likewise.
+ (cp_print_error_function): Likewise.
+ (maybe_print_instantiation_context): Likewise.
+ (print_instantiation_full_context): Likewise.
+ (print_instantiation_partial_context): Likewise.
+ (print_instantiation_context): Define.
+ (init_error): Initialize diagnostic pager and finalizer.
+
+ * pt.c (problematic_instantiation_changed): Define.
+ (record_last_problematic_instantiation): Likewise.
+ (current_instantiation): Likewise.
+ (maybe_print_template_context): Remove.
+ (print_template_context): Likewise.
+ (current_tinst_level): Make static to reflect Brendan Kehoe's
+ change of 1995-04-13.
+ (push_tinst_level): Call print_instantiation_context.
+
+2000-08-21 Nix <nix@esperi.demon.co.uk>
+
+ * lang-specs.h: Do not process -o or run the assembler if
+ -fsyntax-only.
+
+2000-08-21 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (flag_hosted, flag_noniso_default_format_attributes): New
+ variables.
+ * decl2.c (lang_decode_option): Disable gettext attributes for
+ -ansi.
+
+2000-08-21 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (lang_init_options): Default diagnostic message maximum
+ length to 80, when line-wrapping.
+
+2000-08-20 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Clear the entire
+ vtbl_init_data. Start keeping track of the functions for which we
+ have created vcall offsets here.
+ (dfs_build_vcall_offset_vtbl_entries): Remove.
+ (build_vcall_offset_vtbl_entries): Reimplement.
+ (add_vcall_offset_vtbl_entries_r): New function.
+ (add_vcall_offset_vtbl_entries_1): Likewise. Tweak logic for
+ computing when vcall offsets are necessary.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (member_function_or_else): Use cp_error ... %T.
+ (grokdeclarator): Likewise.
+ (start_method): Likewise.
+ * friend.c (make_friend_class): Use cp_pedwarn ... %T.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (grokfield): Set CLASSTYPE_GOT_SEMICOLON on class
+ TYPE_DECLs.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (PTRMEM_OK_P): New macro.
+ (itf_ptrmem_ok): New enumeration value.
+ * class.c (resolve_address_of_overloaded_function): Add PTRMEM
+ argument. Diagnose implicit pointer to member.
+ (instantiate_type): Don't diagnose implicit pointer to member
+ here. Pass itf_ptrmem_ok if ok. Adjust calls to
+ resolve_address_of_overloaded_function.
+ * init.c (build_offset_ref): Set PTRMEM_OK_P.
+ (resolve_offset_ref): Don't diagnose implicit pointer to member here.
+ * semantics.c (finish_parenthesized_expr): Clear OFFSET_REFs here.
+ * typeck.c (build_x_unary_op): Calculate PTRMEM_OK_P.
+ (build_unary_op): Deal with single non-static member in
+ microsoft-land.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (arg_assoc_type): Cope with TYPENAME_TYPE.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (enum_name_string): Remove prototype.
+ (report_case_error): Remove prototype.
+ * cp/typeck2.c (enum_name_string): Remove.
+ (report_case_error): Remove.
+ * error.c (dump_expr): Deal with enum values directly.
+ Correctly negate integer constant.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h (__cxa_vec_new2, __cxa_vec_new3): Declare.
+ (__cxa_vec_delete2, __cxa_vec_delete3): Declare.
+ * vec.cc (__cxa_vec_new2, __cxa_vec_new3): Implement.
+ (__cxa_vec_delete2, __cxa_vec_delete3): Implement.
+ (__cxa_vec_new): Use __cxa_vec_new2.
+ (__cxa_vec_delete): Use __cxa_vec_delete2.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.cc (__cxa_vec_new): Set "C" linkage.
+ (__cxa_vec_ctor): Likewise.
+ (__cxa_vec_cctor): Likewise.
+ (__cxa_vec_dtor): Likewise.
+ (__cxa_vec_delete): Likewise.
+ * inc/cxxabi.h (__cxa_vec_new): Set "C" linkage.
+ (__cxa_vec_ctor): Likewise.
+ (__cxa_vec_cctor): Likewise.
+ (__cxa_vec_dtor): Likewise.
+ (__cxa_vec_delete): Likewise.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (instantiate_type): Reinstate local variable
+ deleted in previous change.
+
+ * cvt.c (cp_convert_to_pointer): Pass itf_complain, not
+ itf_no_attributes.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (instantiate_type_flags): New enumeration.
+ (instantiate_type): Change parameter.
+ * class.c (instantiate_type): Adjust prototype. Adjust.
+ * call.c (standard_conversion): Adjust instantiate_type call.
+ (reference_binding): Likewise.
+ (build_op_delete_call): Likewise.
+ (convert_like_real): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_reference): Likewise.
+ * pt.c (convert_nontype_argument): Likewise.
+ * typeck.c (build_binary_op): Likewise.
+ (build_ptrmemfunc): Likewise.
+ (convert_for_assignment): Likewise.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTR_AGGR_TAG): New global tree node.
+ (current_aggr): Define.
+ * decl.c (grokdeclarator): Make sure a friend class is an
+ elaborated type specifier.
+ * parse.y (current_aggr): Remove static definition.
+ (cp_parse_init): Adjust.
+ (structsp): Clear and restore current_aggr.
+ (component_decl_list): Clear current_aggr.
+
+ * error.c (dump_type, case TYPENAME_TYPE): Don't emit the
+ aggregate tag on the typename's context.
+
+ * pt.c (tsubst_friend_class): Return error_mark_node, if
+ parms becomes NULL.
+ (instantiate_class_template): Ignore error_mark_node friend types.
+
+2000-08-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cvt.c (warn_ref_binding): New static function, broken out of ...
+ (convert_to_reference): ... here. Use it.
+
+2000-08-11 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * parse.y (template_arg): Add rule for template qualified with
+ global scope.
+
+2000-08-11 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * decl2.c (add_function): Reorganize.
+ (arg_assoc): Do not consider function template decls.
+
+2000-08-11 Jason Merrill <jason@redhat.com>
+
+ * decl.c (lookup_name_real): Don't forget the TYPENAME_TYPE we're
+ looking inside.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (resolve_scope_to_name): Remove unused prototype.
+ (lookup_nested_tag): Likewise.
+
+ * decl2.c (grokfield): Fix comment to reflect many types of _DECLs
+ can be produced.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (named_complex_class_head_sans_basetype): Remove
+ always true if.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (build_expr_from_tree, case METHOD_CALL_EXPR): Build
+ explicit TEMPLATE_ID_EXPR args.
+ (build_expr_from_tree, case CALL_EXPR): Likewise.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (check_tag_decl): Diagnose typename's which don't
+ declare anything.
+
+2000-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (build_aggr_init): Reject bogus array initializers
+ early.
+
+2000-08-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (build_dynamic_cast_1): Set "C" linkage for new abi
+ runtime.
+ * cp/tinfo.cc (__dynamic_cast): Likewise.
+ * cp/inc/cxxabi.h (__dynamic_cast): Likewise.
+
+2000-08-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cvt.c (convert_to_pointer_force): Fix error message when
+ attempting to cast from ambiguous base.
+
+2000-08-08 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_aggr_type): Bail if creating the argvec fails.
+ (tsubst_template_arg_vector): Likewise.
+
+ * decl2.c (build_anon_union_vars): Choose the largest field; don't
+ assume that one will be as large as the union.
+
+2000-08-07 Kazu Hirata <kazu@hxi.com>
+
+ * cp-tree.h (CLASSTYPE_HAS_PRIMARY_BASE_P): Fix a comment typo.
+ * decl.c (pop_labels): Likewise.
+
+2000-08-04 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * inc/cxxabi.h (__pbase_type_info): Changed member names to match
+ specifications.
+ (__pointer_to_member_type_info): Likewise.
+ (__base_class_info): Likewise.
+ (__class_type_info): Likewise.
+ (__si_class_type_info): Likewise.
+ (__vmi_class_type_info): Likewise.
+ * tinfo.cc (__si_class_type_info::__do_find_public_src):
+ Changed member names to match specifications.
+ (__vmi_class_type_info::__do_find_public_src): Likewise.
+ (__si_class_type_info::__do_dyncast): Likewise.
+ (__vmi_class_type_info::__do_dyncast): Likewise.
+ (__si_class_type_info::__do_upcast): Likewise.
+ (__vmi_class_type_info::__do_upcast): Likewise.
+ * tinfo2.cc (__pbase_type_info::__do_catch): Likewise.
+ (__pbase_type_info::__pointer_catch): Likewise.
+ (__pointer_type_info::__pointer_catch): Likewise.
+ (__pointer_to_member_type_info::__pointer_catch): Likewise.
+
+2000-08-04 Zack Weinberg <zack@wolery.cumb.org>
+
+ * Make-lang.in (cc1plus): Depend on $(BACKEND), not stamp-objlist.
+ * Makefile.in: Add C_OBJS, BACKEND; delete OBJS, OBJDEPS.
+ (cc1plus): Link with $(BACKEND) and $(C_OBJS).
+
+2000-08-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (add_method): Change prototype.
+ * class.c (add_method): Remove FIELDS parameter. Add ERROR_P.
+ Don't double the size of the method vector in the error case.
+ (handle_using_decl): Adjust call to add_method.
+ (add_implicitly_declared_members): Likewise.
+ (clone_function_decl): Likewise.
+ * decl2.c (check_classfn): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+
+2000-08-04 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (flag_isoc94): New variable.
+
+2000-08-02 Jason Merrill <jason@redhat.com>
+
+ * pt.c (do_type_instantiation): Add complain parm; don't complain
+ if called recursively.
+ * cp-tree.h, parse.y: Adjust.
+
+2000-08-02 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl2.c: Silently ignore -Wstrict-prototypes; warn about
+ -Wno-strict-prototypes.
+
+ * g++spec.c: Adjust type of second argument to
+ lang_specific_driver, and update code as necessary.
+
+ * cp-tree.h: Don't prototype min_precision here.
+ (my_friendly_assert): Cast expression to void.
+ * semantics.c (do_poplevel): Initialize scope_stmts.
+
+2000-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_NEEDED_P): Tweak.
+
+2000-07-28 Jason Merrill <jason@redhat.com>
+
+ * lang-specs.h: Use %i in rule for .ii files.
+
+2000-07-31 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Rename cpp to cpp0 and/or tradcpp to tradcpp0.
+
+2000-07-30 Mark Mitchell <mark@codesourcery.com>
+
+ Allow indirect primary bases.
+ * cp-tree.h (struct lang_type): Remove vfield_parent. Add
+ primary_base.
+ (CLASSTYPE_VFIELD_PARENT): Remove.
+ (CLASSTYPE_PRIMARY_BINFO): Reimplement.
+ (BINFO_PRIMARY_BINFO): Remove.
+ (CLASSTYPE_HAS_PRIMARY_BASE_P): Reimplement.
+ (BINFO_VBASE_PRIMARY_P): Likewise.
+ (BINFO_PRIMARY_BASE_OF): New macro.
+ (BINFO_INDIRECT_PRIMARY_P): Likewise.
+ (get_primary_binfo): New function.
+ * decl.c (lang_mark_tree): Make lang_type::primary_base.
+ * class.c (vcall_offset_data_s): Rename to ...
+ (vtbl_init_data_s): ... this. Rename primary_p to primary_vtbl_p,
+ and add ctor_vtbl_p.
+ (get_derived_offset): Use get_primary_binfo.
+ (dfs_mark_primary_bases): Adjust handling of virtual primary
+ bases.
+ (mark_primary_bases): Likewise.
+ (set_primary_base): Take a binfo, not an integer, as a
+ representation of the primary base.
+ (indirect_primary_base_p): Remove.
+ (determine_primary_base): Adjust for indirect primary bases.
+ (dfs_find_final_overrider): Fix typo in coment.
+ (update_vtable_entry_for_fn): Use get_primary_binfo.
+ (layout_nonempty_base_or_field): Tweak.
+ (build_base_fields): Adjust for new primary base semantics.
+ (dfs_propagate_binfo_offsets): Remove.
+ (propagate_binfo_offsets): Rewrite.
+ (dfs_set_offset_for_shared_vbases): Remove.
+ (layout_virtual_bases): Don't use it.
+ (layout_class_type): Set CLASSTYPE_SIZE correctly under the new
+ ABI.
+ (finish_struct_1): Set CLASSTYPE_PRIMARY_BINFO, not
+ CLASSTYPE_VFIELD_PARENT.
+ (dfs_get_primary_binfo): New function.
+ (get_primary_binfo): Likewise.
+ (dump_class_hierarchy_r): Tweak printing of primary bases.
+ (build_vtbl_initializer): Fix typo in comments. Use
+ vtbl_init_data.
+ (build_vcall_and_vbase_vtbl_entries): Likewise.
+ (build_vbaes_offset_vtbl_entries): Likewise.
+ (dfs_build_vcall_offset_vtbl_entries): Adjust setting of
+ BV_VCALL_INDEX to handle indirect primary bases.
+ (build_vcall_offset_vtbl_entries): Use vtbl_init_data.
+ (build_rtti_vtbl_entries): Likewise.
+ * search.c (get_shared_vbase_if_not_primary): Tweak.
+ (find_vbase_instance): Likewise.
+ (binfo_for_vtable): Simplify.
+ * tree.c (unshare_base_binfos): Clear BINFO_PRIMARY_BASE_OF.
+ (make_binfo): Make it have 11 entries.
+
+2000-07-30 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (DECL_TEMPLATE_ID_P): Remove.
+ (CLASSTYEP_TEMPLATE_ID_P): Check template info, and context when
+ ascertaining primaryness.
+ (G): Remove template_args.
+ (decl_is_template_id): New function.
+ (write_encoding): Use decl_is_template_id.
+ (write_name): Likewise. Handle type_decls. Get main variant of
+ type decls.
+ (write_nested_name): Likewise.
+ (write_prefix): Likewise.
+ (write_template_prefix): Likewise.
+ (write_special_name_constructor): Remove defunct production from
+ comment.
+ (write_bare_function_type): Remove comment about absent parameter.
+ (write_template_template_arg): Add missing grammar production to
+ comment.
+
+2000-07-27 Jason Merrill <jason@redhat.com>
+
+ * decl.c (duplicate_decls): If common_type produces a non-typedef
+ type for a typedef, just use the old type.
+
+2000-07-27 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (function_depth): Declare.
+ (verify_stmt_tree): Likewise.
+ (find_tree): Likewise.
+ * decl.c (function_depth): Give it external linkage.
+ * optimize.c (optimize_function): Increment and decrement it.
+ * tree.c (verify_stmt_tree_r): New function.
+ (verify_stmt_tree): Likewise.
+ (find_tree_r): Likewise.
+ (find_tree): Likewise.
+
+2000-07-27 Jason Merrill <jason@redhat.com>
+
+ * pt.c (for_each_template_parm_r, case RECORD_TYPE): Use
+ TYPE_PTRMEMFUNC_P.
+ * cp-tree.h (TYPE_TEMPLATE_INFO): Check for TYPE_LANG_SPECIFIC.
+
+2000-07-26 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_cleanup_fn): Mark the function as `inline'.
+ * decl2.c (get_guard): Call cp_finish_decl, not
+ rest_of_decl_compilation, for local guards.
+ * lex.c (do_identifier): Remove unused variable.
+
+2000-07-26 Marc Espie <espie@cvs.openbsd.org>
+
+ * parse.y: Add missing ';'.
+
+2000-07-26 Mark Mitchell <mark@codesourcery.com>
+
+ * parse.y (empty_parms): Use `()', not `(...)', when in the scope
+ of `extern "C++"'.
+
+2000-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ Kill strict_prototype. Backwards compatibility only for
+ non NO_IMPLICIT_EXTERN_C systems.
+ * cp-tree.h (flag_strict_prototype): Remove.
+ (strict_prototype): Remove.
+ (strict_prototypes_lang_c, strict_prototypes_lang_cplusplus): Remove.
+ * decl.c (maybe_push_to_top_level): Adjust.
+ (pop_from_top_level): Adjust.
+ (decls_match): Only allow sloppy parm matching for ancient
+ system headers.
+ (init_decl_processing): Adjust.
+ (grokdeclarator): Adjust.
+ * decl2.c (flag_strict_prototype): Remove.
+ (strict_prototype): Remove.
+ (strict_prototypes_lang_c, strict_prototypes_lang_cplusplus): Remove.
+ (lang_f_options): Remove "strict-prototype".
+ (unsupported-options): Add "strict-prototype".
+ * lex.c (do_identifier): Adjust.
+ (do_scoped_id): Adjust.
+ * parse.y (empty_parms): Adjust.
+ * class.c (push_lang_context): Adjust.
+ (pop_lang_context): Adjust.
+ * typeck.c (comp_target_parms): Adjust.
+
+2000-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (poplevel): Deal with anonymous variables at for scope.
+ (maybe_inject_for_scope_var): Likewise.
+
+2000-07-25 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl.c: Remove all signal handling code, now done in toplev.c.
+
+2000-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (make_rtl_for_nonlocal_decl): Rework.
+
+ * pt.c (lookup_template_class): Ensure that TYPE_CONTEXT is set
+ correctly.
+
+2000-07-20 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cp-tree.h: Use __FUNCTION__ not __PRETTY_FUNCTION__.
+ Define my_friendly_assert and my_friendly_abort as macros
+ which may call friendly_abort. Prototype friendly abort, not
+ my_friendly_abort or my_friendly_assert.
+ * decl.c (signal_catch): Report the signal caught in the error
+ message. Call fatal directly.
+ * typeck2.c (ack, my_friendly_assert): Delete.
+ (my_friendly_abort): Rename to friendly_abort. Expect file,
+ line, and function parameters. Report the abort code, then
+ call fancy_abort. Do not mask an abort if errors have
+ already occurred.
+
+2000-07-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (comp_target_parms): Remove obsolete parameter.
+ (comp_target_types): Adjust.
+
+2000-07-17 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (mark_addressable): Never set TREE_USED.
+ * call.c (build_call): Don't abort on calls to library functions
+ that have been declared normally.
+
+ * typeck.c (build_binary_op): Fix grammar in warning.
+
+ * exception.cc (__eh_free): Fix prototype.
+
+ * decl2.c (finish_decl_parsing): Handle TEMPLATE_ID_EXPR.
+
+ * decl.c (pushdecl): Handle seeing an OVERLOAD in
+ IDENTIFIER_NAMESPACE_VALUE.
+
+2000-07-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (THUNK_VCALL_OFFSET): Update documentation.
+ * method.c (use_thunk): Correct handling of vcall offsets.
+
+2000-07-14 Zack Weinberg <zack@wolery.cumb.org>
+
+ * .cvsignore: parse.h and parse.c have no cp- prefix.
+
+2000-07-13 Mark Mitchell <mark@codesourcery.com>
+
+ * .cvsignore: New file.
+
+2000-07-13 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Use the new named specs. Remove unnecessary braces.
+
+2000-07-12 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in ($(PARSE_H)): Depend directly on parse.y.
+ * parse.c: Remove.
+ * parse.h: Likewise.
+
+2000-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Add pointers to virtual bases after
+ base classes under the old ABI.
+
+2000-07-10 Benjamin Chelf <chelf@codesourcery.com>
+
+ * semantics.c (finish_for_stmt): Remove call to emit_line_note.
+ (finish_continue_stmt): Likewise.
+ (begin_for_stmt): Remove call to note_level_for_for.
+ (finish_goto_stmt): Change call from build_min_nt
+ to build_stmt.
+ (finish_expr_stmt): Likewise.
+ (begin_if_stmt): Likewise.
+ (begin_while_stmt): Likewise.
+ (finish_while_stmt): Likewise.
+ (finish_return_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_for_stmt): Likewise.
+ (finish_break_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (finish_case_label): Likewise.
+ (genrtl_try_block): Likewise.
+ (begin_try_block): Likewise.
+ (begin_handler): Likewise.
+ (begin_compound_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ (finish_label_stmt): Likewise.
+ (add_decl_stmt): Likewise.
+ (finish_subobject): Likewise.
+ (finish_decl_cleanup): Likewise.
+ (finish_named_return_value): Likewise.
+ (setup_vtbl_ptr): Likewise.
+ (add_scope_stmt): Likewise.
+ * decl.c (finish_constructor_body): Likewise.
+ (finish_destructor_body): Likewise.
+ * optimize.c (copy_body_r): Likewise.
+ (initialize_inlined_parameters): Likewise.
+ (declare_return_variable): Likewise.
+ (expand_call_inline): Likewise.
+
+2000-07-10 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (expand_body): Sync interface information
+ at the end of function body expansion.
+
+2000-07-09 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Bail early if the call to new fails.
+
+ * decl.c (compute_array_index_type): Check specifically for
+ an INTEGER_CST, not just TREE_CONSTANT.
+
+ * decl.c (duplicate_decls): Don't call duplicate_decls on
+ the DECL_TEMPLATE_RESULT.
+ (decls_match): Return 0 if the DECL_TEMPLATE_RESULTs have different
+ codes.
+
+ * error.c (dump_template_bindings): Don't crash if we had an
+ invalid argument list.
+
+ * typeck.c (c_expand_start_case): Do narrowing here.
+ * semantics.c (finish_switch_cond): Not here.
+
+2000-07-09 Hidvegi Zoli <hzoli@austin.ibm.com>
+
+ * parse.y (asm_clobbers): Do string concatenation.
+
+2000-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pushtag): Don't put local classes in template functions
+ on the local_classes list.
+
+2000-07-04 Scott Snyder <snyder@fnal.gov>
+
+ * decl2.c (get_guard): Add missing return for old ABI local
+ variable case.
+
+2000-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (char_type_p): New function.
+ * decl.c (init_decl_processing): Don't initialize
+ signed_wchar_type_node or unsigned_wchar_type_node.
+ (complete_array_type): Handle brace-enclosed string-constants.
+ * rtti.c (emit_support_tinfos): Remove #if 0'd code.
+ * tree.c (char_type_p): New function.
+ * typeck2.c (digest_init): Use char_type_p.
+
+2000-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst): Don't layout type, if it's error_mark.
+
+2000-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_pending_templates): Reset template level.
+
+2000-07-05 Jason Merrill <jason@redhat.com>
+
+ * call.c (joust): Don't complain about `operator char *()' beating
+ `operator const char *() const'.
+
+2000-07-04 scott snyder <snyder@fnal.gov>
+ Jason Merrill <jason@redhat.com>
+
+ * repo.c (repo_get_id): Handle the case where a class with virtual
+ bases has a null TYPE_BINFO_VTABLE.
+
+2000-07-04 Kevin Buhr <buhr@stat.wisc.edu>
+ Jason Merrill <jason@redhat.com>
+
+ * parse.y (member_init): Just pass in the type.
+ * init.c (expand_member_init): Handle getting a type.
+
+2000-07-04 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+ Jason Merrill <jason@redhat.com>
+
+ * decl.c (finish_function): Warn if a function has no return
+ statement.
+ Suggested by Andrew Koenig.
+ * typeck.c (check_return_expr): Do set current_function_returns_value
+ if we got an error_mark_node.
+
+2000-07-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (push_decl_namespace): Push the original namespace.
+
+2000-07-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_class_template): Set CLASSTYPE_VBASECLASSES.
+ * semantics.c (begin_class_definition): Clear it.
+
+2000-07-02 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (genrtl_goto_stmt): Remove declaration.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (genrtl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+
+ * init.c (begin_init_stmts): Remove call to
+ genrtl_begin_compound_stmt.
+ (finish_init_stmts): Remove call to genrtl_finish_compound_stmt.
+
+ * semantics.c (lang_expand_stmt): Changed call to
+ genrtl_compound_stmt to ignore return value.
+
+2000-07-02 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (canonicalize_for_substitution): Return the canonical
+ variant of a type.
+
+ * decl.c (duplicate_decls): Preserve DECL_ORIGINAL_TYPE for a
+ TYPE_DECL.
+ * typeck.c (commonparms): Remove obstack manipulations.
+
+2000-07-01 Benjamin Chelf <chelf@codesourcery.com>
+
+ * Make-lang.in (cc1plus$(exeext)): Added c-semantics.o.
+
+ * Makefile.in (OBJS): Added ../c-semantics.o.
+ (OBJDEPS): Likewise.
+
+ * cp-tree.h (TREE_LANG_FLAG_?): Moved common documentation to
+ ../c-common.h.
+ (struct stmt_tree): Added comment.
+ (current_function_name_declared): Removed.
+ (stmts_are_full_exprs_p): Likewise.
+ (genrtl_do_pushlevel): Likewise.
+ (genrtl_clear_out_block): Likewise.
+ (COMPOUND_STMT_NO_SCOPE): Moved to ../c-common.h.
+ (DECL_ANON_UNION_ELEMS): Likewise.
+ (emit_local_var): Likewise.
+ (make_rtl_for_local_static): Likewise.
+ (do_case): Likewise.
+ (expand_stmt): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (c_expand_asm_operands): Likewise.
+ (c_expand_return): Likewise.
+ (c_expand_start_case): Likewise.
+
+ * decl.c (make_rtl_for_local_static): Moved to c-semantics.c.
+ (emit_local_var): Likewise.
+ (initialize_local_var): Change reference to
+ stmts_are_full_exprs_p to call to stmts_are_full_exprs_p().
+ Change reference to stmts_are_full_exprs_p to
+ current_stmt_tree->stmts_are_full_exprs_p.
+ (push_cp_function_context): Likewise.
+
+ * expect.c (expand_throw): Change reference to
+ stmts_are_full_exprs_p.
+
+ * init.c (build_aggr_init): Change reference to
+ stmts_are_full_exprs_p.
+ (build_vec_init): Likewise.
+
+ * optimize.c (maybe_clone_body): Change reference to
+ current_function_name_declared to
+ cp_function_chain->name_declared.
+
+ * pt.c (instantiate_decl): Change reference to
+ current_function_name_declared to
+ cp_function_chain->name_declared.
+
+ * semantics.c (expand_cond): Moved declaration to c-common.h.
+ (genrtl_do_pushlevel): Moved to c-semantics.c.
+ (genrtl_clear_out_block): Likewise.
+ (genrtl_goto_stmt): Likewise.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (gerntl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (expand_cond): Likewise.
+ (expand_stmt): Renamed to ...
+ (lang_expand_stmt): ... this.
+ (lang_expand_expr_stmt): Initialize.
+ (set_current_function_name_declared): Likewise.
+ (stmts_are_full_exprs_p): Likewise.
+ (current_function_name_declared): Likewise.
+ (anon_aggr_type_p): Likewise.
+ (do_poplevel): Change reference to
+ stmts_are_full_exprs_p to call to stmts_are_full_exprs_p().
+ Change reference to stmts_are_full_exprs_p to
+ current_stmt_tree->stmts_are_full_exprs_p.
+ (add_tree): Likewise.
+ (finish_expr_stmt): Likewise.
+ (prep_stmt): Likewise.
+ (lang_expand_stmt): Likewise.
+ (begin_compound_stmt): Change reference to
+ current_function_name_declared to
+ cp_function_chain->name_declared and call to
+ current_function_name_declared().
+ (setup_vtbl_ptr): Likewise.
+ (genrtl_do_poplevel): Removed.
+
+2000-06-30 Jason Merrill <jason@redhat.com>
+
+ * init.c (init_init_processing): Go back to aligning like
+ double_type_node for old ABI.
+ (get_cookie_size): Make cookie larger if we get a type that needs
+ more alignment.
+ (build_vec_delete): Call it.
+
+ * typeck.c (qualify_type_recursive): New fn.
+ (composite_pointer_type): Use it.
+ (build_binary_op): Use composite_pointer_type.
+
+2000-06-24 Carlos O'Ryan <coryan@cs.wustl.edu>
+ Jason Merrill <jason@redhat.com>
+
+ * typeck.c (check_return_expr): Don't complain about returning
+ NULL from operator new if -fcheck-new.
+ * cp-tree.h: Declare flag_check_new here.
+ * init.c: Not here.
+
+2000-06-28 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (find_substitution): Use same_type_p.
+ (write_encoding): Don't check for substitutions.
+
+2000-06-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (expr_no_comma_rangle): New non-terminal.
+ (template_parm): Use it for default parameter case.
+ (template_arg): Use it.
+ (expr_no_commas): Remove commented out undefined extensions.
+ * Makefile.in (CONFLICTS): Adjust to 33 s/r & 48 r/r.
+ * parse.h, parse.c: Rebuilt.
+
+2000-06-30 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (genrtl_asm_stmt): Don't decay input operands here.
+ (finish_asm_stmt): Do it here, instead.
+
+ * cp-tree.h (ridpointers): Don't declare.
+ * decl.c (record_builtin_type): Use CP_RID_MAX instead of RID_MAX.
+ (record_builtin_java_type): Likewise.
+ (init_decl_processing): Likewise.
+ * lex.c: Move inclusion of lex.h.
+ (ridpointers): Don't define.
+ (init_parse): Initialize ripdointers. Use CP_RID_MAX instead of
+ RID_MAX.
+ * lex.h (enum rid): Rename to ...
+ (enum cp_rid): ... this.
+ (ridpointers): Don't declare.
+ * parse.y: Move inclusion of lex.h.
+ * parse.c: Regenerated.
+ * spew.c: Move inclusion of lex.h.
+
+ * cp-tree.h (struct language_function): Remove temp_name_counter.
+ (temp_name_counter): Remove.
+ (get_temp_name): Change prototype.
+ (get_guard): New function.
+ (get_guard_cond): Likewise.
+ (set_guard): Likewise.
+ * cvt.c (build_up_reference): Adjust call to get_temp_name.
+ * decl.c (expand_static_init): Use get_guard and friends to
+ implement guard variables.
+ * decl2.c (get_temp_name): Assume that the variables created are
+ always static.
+ (get_sentry): Rename to ...
+ (get_guard): ... this. Implement new ABI guard variables.
+ (get_guard_bits): New function.
+ (get_guard_cond): Likewise.
+ (set_guard): Likewise.
+ (start_static_initialization_or_destruction): Use them.
+ (do_static_initialization): Replace sentry with guard throughout.
+ (do_static_destruction): Likewise.
+ * init.c (create_temporary_var): Add comment.
+
+2000-06-28 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (find_substitution): Use same_type_p.
+ (write_encoding): Don't check for substitutions.
+
+2000-06-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (expr_no_comma_rangle): New non-terminal.
+ (template_parm): Use it for default parameter case.
+ (template_arg): Use it.
+ (expr_no_commas): Remove commented out undefined extensions.
+ * Makefile.in (CONFLICTS): Adjust to 33 s/r & 48 r/r.
+ * parse.h, parse.c: Rebuilt.
+
+2000-06-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (flag_const_strings): Remove.
+ (warn_parentheses): Likewise.
+ (warn_format): Likewise.
+ (common_type): Likewise.
+ (default_conversion): Likewise.
+ (build_binary_op): Likewise.
+ (cp_build_binary_op): New macro.
+ * call.c (build_new_op): Use cp_build_binary_op instead of
+ build_binary_op.
+ * class.c (build_vtable_entry_ref): Likewise.
+ * decl.c (expand_static_init): Likewise.
+ (compute_array_index_type): Likewise.
+ (build_enumerator): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+ (start_static_initialization_or_destruction): Likewise.
+ * error.c (dump_type_suffix): Likewise.
+ * init.c (resolve_offset_ref): Likewise.
+ (build_new): Likewise.
+ (build_new_1): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_vec_init): Likewise.
+ (build_delete): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Likewise.
+ (synthesize_tinfo_var): Likewise.
+ * search.c (expand_upcast_fixups): Likewise.
+ (fixup_all_virtual_upcast_offsets): Likewise.
+ * typeck.c (build_array_ref): Likewise.
+ (get_member_function_from_ptrfunc): Likewise.
+ (build_binary_op): Add parameter.
+ (pointer_int_sum): Use cp_build_binary_op.
+ (pointer_diff): Likewise.
+ (build_modify_expr): Likewise.
+ (get_delta_difference): Likewise.
+ (build_ptrmemfunc): Likewise.
+
+2000-06-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (SET_DECL_ARTIFICIAL): Remove.
+ * decl.c (create_implicit_typedef): Adjust.
+ * decl2.c (build_artificial_parm): Adjust.
+ * method.c (implicitly_declare_fn): Adjust.
+ * pt.c (push_inline_template_parms_recursive): Adjust.
+ (process_template_parm): Adjust.
+ (overloaded_template_name): Adjust.
+ * semantics.c (finish_template_template_parm): Adjust.
+
+2000-06-28 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLEAR_BINFO_NEW_VTABLE_MARKED): Remove.
+ * class.c (update_vtable_entry_for_fn): Correct logic for deciding
+ where to emit thunks.
+ (build_vtt): Adjust call to build_vtt_inits.
+ (build_vtt_inits): Add parameter to indicate whether or not
+ sub-VTTs for virtual bases should be included. Adjust handling of
+ construction vtables.
+ (get_matching_base): New function.
+ (dfs_build_vtt_inits): Rename to ...
+ (dfs_build_secondary_vptr_vtt_inits): Adjust handling of
+ construction vtables.
+ (dfs_fixup_binfo_vtbls): Likewise.
+ (build_ctor_vtbl_groups): Build construction vtables for virtual
+ bases, too.
+ (accumulate_vtbl_inits): Tweak logic for deciding whether or not
+ to build construction vtbls.
+ (dfs_accumulate_vtbl_inits): Adjust handling of
+ construction vtables.
+
+ * pt.c (tsubst, case TEMPLATE_TEMPLATE_PARM): Handle cv-qualified
+ types correctly.
+
+2000-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokfndecl): Set DECL_CONTEXT for static functions too.
+
+2000-06-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (hides): Remove.
+ (is_subobject_of_p): Add most_derived parameter. Use
+ CANONICAL_BINFO.
+ (lookup_field_queue_p): Adjust.
+ (lookup_field_r): Adjust.
+
+2000-06-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (handle_class_head): Bash typedefs to the type's main
+ decl.
+
+2000-06-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (genrtl_begin_stmt_expr): Rename to ...
+ (begin_global_stmt_expr): ... this.
+ (genrtl_finish_stmt_expr): Rename to ...
+ (finish_global_stmt_expr): ... this.
+ * init.c (begin_init_stmts): Adjust calls.
+ (finish_init_stmts): Likewise.
+ * semantics.c (genrtl_begin_stmt_expr): Rename to ...
+ (begin_global_stmt_expr): ... this.
+ (genrtl_finish_stmt_expr): Rename to ...
+ (finish_global_stmt_expr): ... this.
+
+2000-06-25 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * search.c (lookup_member): Fix typo in comment.
+
+2000-06-24 Jason Merrill <jason@redhat.com>
+
+ * decl.c (pushdecl): Don't set DECL_CONTEXT from current_namespace.
+ (push_namespace): Set DECL_CONTEXT for a new NAMESPACE_DECL.
+
+2000-06-24 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (complex_direct_notype_declarator): Support global_scope.
+ * Makefile.in: Adjust conflict count.
+
+2000-06-23 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * parse.y (template_arg): Convert TEMPLATE_DECL
+ that is a template template parameter to
+ TEMPLATE_TEMPLATE_PARM here.
+
+ * cp-tree.def (TEMPLATE_TEMPLATE_PARM): Adjust comment.
+ * cp-tree.h (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): New macro.
+ (copy_template_template_parm): Adjust prototype.
+ * decl.c (grokdeclarator): Remove dead code.
+ * pt.c (process_template_parm): Tidy.
+ (lookup_template_class): Construct nodes in
+ copy_template_template_parm.
+ (tsubst): Pass TEMPLATE_DECL rather than IDENTIFIER_NODE to
+ lookup_template_class. Use TYPE_TI_TEMPLATE.
+ * tree.c (copy_template_template_parm): Add NEWARGS
+ parameter.
+ (mapcar): Adjust call to copy_template_template_parm.
+ * typeck.c (comptypes): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL.
+ * method.c (build_template_template_parm_names): Change error
+ code to avoid compilation warning.
+
+ * gxxint.texi: Document template template parameter
+ name mangling.
+
+2000-06-21 Alex Samuel <samuel@codesourcery.com>
+
+ * Make-lang.in (CXX_LIB2FUNCS): Add cp-demangle.o and dyn-string.o.
+ (CXX_LIB2SRCS): Add cp-demangle.c and dyn-string.c.
+ (cp-demangle.o): New rule.
+ (dyn-string.o): Likewise.
+ * inc/cxxabi.h (__cxa_demangle): New declaration.
+
+2000-06-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BV_USE_VCALL_INDEX_P): New macro.
+ (BV_GENERATE_THUNK_WITH_VTABLE_P): Likewise.
+ (lang_decl_flags): Add generate_with_vtable_p. Make vcall_offset
+ a tree, not an int.
+ (THUNK_GENERATE_WITH_VTABLE_P): New macro.
+ (make_thunk): Change prototype.
+ (emit_thunk): Rename to use_thunk.
+ (mangle_thunk): Change prototype.
+ * class.c (get_derived_offset): Simplify.
+ (copy_virtuals): Clear BV_USE_VCALL_INDEX_P and
+ BV_GENERATE_THUNK_WITH_VTABLE_P.
+ (build_primary_vtable): Simplify.
+ (add_virtual_function): Use BV_FN, rather than TREE_VALUE.
+ (dfs_find_base): Remove.
+ (update_vtable_entry_for_fn): Correct bug in finding the base
+ where a virtual function was first declared. Figure out whether
+ or not to emit a vcall-thunk with the vtables in which it appears.
+ Correct logic for deciding whether to use an ordinary thunk, or a
+ vcall thunk.
+ (finish_struct_1): Remove unnecssary code.
+ (build_vtbl_initializer): Use ssize_int for the running counter of
+ negative indices.
+ (build_vtbl_initializer): Only use vcall thunks where necessary.
+ Mark thunks as needing to be emitted with their vtables, or not.
+ (build_vbase_offset_vtbl_entries): Adjust for use of ssize_int in
+ indices. Use size_binop.
+ (dfs_build_vcall_offset_vtbl_entries): Don't rely on
+ BINFO_PRIMARY_MARKED_P here. Use BV_FN consistently. Use
+ size_binop.
+ (build_rtti_vtbl_entries): Adjust call to build_vtable_entry.
+ (build_vtable_entry): Mark thunks as needing to be emitted with
+ their vtables, or not.
+ * decl.c (lang_mark_tree): Mark the vcall_offset in a thunk.
+ * decl2.c (mark_vtable_entries): Use use_thunk instead of
+ emit_thunk.
+ * dump.c (dequeue_and_dump): Remove dead code. Dump new thunk
+ information.
+ * error.c (dump_expr): Use BV_FN.
+ * mangle.c (mangle_thunk): Adjust now that vcall_offset is a tree,
+ not an int.
+ * method.c (make_thunk): Likewise.
+ (emit_thunk): Rename to use_thunk. Allow callers to decide
+ whether or not to actually emit the thunk. Adjust for changes in
+ representation of vcall offsets.
+ * search.c (dfs_get_pure_virtuals): Use BV_FN.
+ * semantics.c (emit_associated_thunks): New function.
+ (expand_body): Use it.
+ * ir.texi: Adjust descriptions of thunks.
+
+2000-06-22 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_decl, case FUNCTION_DECL): Clear DECL_SAVED_TREE.
+ (tsubst_friend_function): Copy it here.
+
+ * decl.c (grok_op_properties): Fix typo.
+
+ * decl2.c (delete_sanity): Clarify warning, avoid failure on
+ deleting void*.
+
+ * pt.c (check_explicit_specialization): Clarify error.
+
+ * decl.c (pushdecl): Also pull out one of the FUNCTION_DECLs from
+ an old OVERLOAD when we're declaring a non-function.
+ (pushdecl, destroy_local_var): Check for error_mark_node.
+ (warn_extern_redeclared_static): Also bail early if
+ we're a CONST_DECL.
+ (push_overloaded_decl): Ignore an old error_mark_node.
+
+2000-06-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_x_va_arg): Check if in a template decl.
+ * pt.c (tsubst_copy, case VA_ARG_EXPR): Use build_x_va_arg.
+
+2000-06-20 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (push_lang_context): TYPE_NAME gets you to the Java
+ types DECLs.
+ * decl.c (check_goto): Computed gotos assumed OK.
+
+2000-06-20 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_decl, case TYPE_DECL): Fix test for TYPE_DECLs
+ for which we don't need to look for instantiations.
+
+2000-06-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (program): Always call finish_translation_unit.
+ * parse.c, parse.h: Rebuilt.
+
+2000-06-20 Zack Weinberg <zack@wolery.cumb.org>
+
+ * method.c: Don't include hard-reg-set.h.
+
+2000-06-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (get_base_offset): Cope when vbase field is in a base.
+
+2000-06-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_conditional_expr): Use VOID_TYPE_P.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_void): Likewise.
+ * error.c (dump_expr): Likewise.
+ * except.c (complete_ptr_ref_or_void_ptr_p): Likewise.
+ * init.c (build_delete): Likewise.
+ * method.c (emit_thunk): Likewise.
+ * optmize.c (declare_return_variable): Likewise.
+ * rtti.c (get_tinfo_decl_dynamic): Likewise.
+ (get_typeid): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ * typeck.c (composite_pointer_type): Likewise.
+ (common_type): Likewise.
+ (build_indirect_ref): Likewise.
+ (build_binary_op): Likewise.
+ (build_x_compound_expr): Likewise.
+ (check_return_expr): Likewise.
+ * typeck2.c (add_exception_specifier): Likewise.
+
+ * mangle.c (write_method_parms): Use direct comparison for end
+ of parmlist.
+
+2000-06-19 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (genrtl_try_block): Declare function.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_do_pushlevel): Likewise.
+ (genrtl_clear_out_block): Likewise.
+ (genrtl_goto_stmt): Likewise.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (genrtl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+ (genrtl_named_return_value): Likewise.
+ (genrtl_begin_stmt_expr): Likewise.
+ (genrtl_finish_stmt_expr): Likewise.
+ (finish_for_stmt): Removed first argument.
+ (finish_switch_stmt): Likewise.
+
+ * semantics.c (genrtl_try_block): Define function.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_do_pushlevel): Likewise.
+ (genrtl_clear_out_block): Likewise.
+ (genrtl_goto_stmt): Likewise.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (genrtl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+ (genrtl_named_return_value): Likewise.
+ (genrtl_begin_stmt_expr): Likewise.
+ (genrtl_finish_stmt_expr): Likewise.
+ (finish_for_stmt): Removed first argument and generate rtl
+ specific code.
+ (finish_switch_stmt): Likewise.
+ (do_poplevel): Removed generate rtl specific code.
+ (do_pushlevel): Likewise.
+ (add_tree): Likewise.
+ (finish_goto_stmt): Likewise.
+ (finish_expr_stmt): Likewise.
+ (begin_if_stmt): Likewise.
+ (finish_if_stmt_cond): Likewise.
+ (finish_then_clause): Likewise.
+ (begin_else_clause): Likewise.
+ (finish_else_clause): Likewise.
+ (finish_if_stmt): Likewise.
+ (clear_out_block): Likewise.
+ (begin_while_stmt): Likewise.
+ (finish_while_stmt_cond): Likewise.
+ (finish_while_stmt): Likewise.
+ (begin_do_stmt): Likewise.
+ (finish_do_body): Likewise.
+ (finish_do_stmt): Likewise.
+ (finish_return_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_for_init_stmt): Likewise.
+ (finish_for_cond): Likewise.
+ (finish_for_expr): Likewise.
+ (finish_break_stmt): Likewise.
+ (finish_continue_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (finish_switch_cond): Likewise.
+ (finish_case_label): Likewise.
+ (begin_try_block): Likewise.
+ (begin_function_try_block): Likewise.
+ (finish_try_block): Likewise.
+ (finish_cleanup_try_block): Likewise.
+ (finish_cleanup): Likewise.
+ (finish_function_try_block): Likewise.
+ (finish_handler_sequence): Likewise.
+ (finish_function_handler_sequence): Likewise.
+ (begin_handler): Likewise.
+ (finish_handler_parms): Likewise.
+ (begin_catch_block): Likewise.
+ (finish_handler): Likewise.
+ (begin_compound_stmt): Likewise.
+ (finish_compound_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ (finish_label_stmt): Likewise.
+ (finish_label_decl): Likewise.
+ (finish_subobject): Likewise.
+ (finish_decl_cleanup): Likewise.
+ (finish_named_return_value): Likewise.
+ (begin_stmt_expr): Likewise.
+ (finish_stmt_expr): Likewise.
+
+ * decl.c (initialize_local_var): Changed call to finish_expr_stmt
+ to call genrtl_expr_stmt when appropriate.
+
+ * init.c (begin_init_stmts): Changed calls to begin_stmt_expr and
+ begin_compound_expr to call genrtl_begin_stmt_expr and
+ genrtl_begin_compound_expr when appropriate.
+ (finish_init_stmts): Changed calls to finish_compound_expr and
+ finish_stmt_expr to call genrtl_finish_compound_expr and
+ genrtl_finish_stmt_expr when appropriate.
+ (expand_default_init): Changed call to finish_expr_stmt to call
+ genrtl_expr_stmt when appropriate.
+ (build_vec_init): Likewise.
+
+ * parse.y (simple_stmt): Removed first argument from call to
+ finish_for_stmt. Removed first argument from call to
+ finish_switch_stmt.
+
+ * parse.c: Regenerated.
+
+ * pt.c (tsubst_expr): Removed first argument from call to
+ finish_for_stmt. Removed first argument from call to
+ finish_switch_stmt.
+
+2000-06-16 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (enum cplus_tree_code): Changed __DUMMY to
+ CP_DUMMY_TREE_CODE. Remove #include "c-common.def".
+
+ * lex.c (cplus_tree_code_type[]): Removed #include "c-common.def".
+ (cplus_tree_code_length[]): Likewise.
+ (cplus_tree_code_name[]): Likewise.
+ (init_parse): Added call to add_c_tree_codes. Changed
+ LAST_AND_UNUSED_TREE_CODE to LAST_C_TREE_CODE.
+
+2000-06-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (finish_mem_initializers): Declare.
+ (count_trees): Likewise.
+ * parse.y (base_init): Use finish_mem_initializers.
+ * semantics.c (finish_mem_initializers): New function.
+
+ * tree.c (count_trees_r): Prototype. Use DATA parameter to store
+ the number of trees.
+ (n_trees): Remove.
+ (count_trees): Don't use it.
+
+2000-06-15 Jason Merrill <jason@redhat.com>
+
+ * tree.c (count_trees): New debugging function.
+
+ * typeck.c (build_x_function_call): Use DECL_FUNCTION_TEMPLATE_P.
+ * init.c (build_member_call): Pull out the name of a DECL.
+
+ * Makefile.in (semantics.o, pt.o): Depend on TIMEVAR_H.
+ * semantics.c (expand_body): Push to TV_INTEGRATION here.
+ * optimize.c (optimize_function): Not here.
+ * pt.c (instantiate_decl): Push to TV_PARSE.
+
+2000-06-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct language_function): Remove x_base_init_list
+ and x_member_init_list.
+ (current_base_init_list): Remove.
+ (current_member_init_list): Likewise.
+ (setup_vtbl_ptr): Change prototype.
+ (emit_base_init): Likewise.
+ (expand_member_init): Likewise.
+ (reinit_parse_for_function): Remove.
+ * decl.c (save_function_data): Don't clear x_base_init_list and
+ x_member_init_list.
+ (mark_language_function): Don't mark them.
+ * init.c (perform_member_init): Tweak comment.
+ (sort_member_init): Take the list of initializers as an argument.
+ (sort_base_init): Likewise.
+ (emit_base_init): Likewise.
+ (expand_member_init): Return the initializer. Don't use global
+ variables.
+ * lex.c (reinit_parse_for_function): Remove.
+ * method.c (build_template_parm_names): Correct substitution.
+ (do_build_copy_constructor): Don't use current_member_init_list
+ and current_base_init_list.
+ (synthesize_method): Likewise.
+ * parse.y (base_init): Split mem-initializers into
+ base-initializers and field-initializers.
+ (member_init_list): Build up the list here.
+ (member_init): Return the initializer.
+ (fn.depfn): Don't use reinit_parse_for_function.
+ * parse.c: Regenerated.
+ * pt.c (convert_nontype_argument): Don't make an ADDR_EXPR of the
+ ERROR_MARK.
+ (tsubst_expr): Don't use current_member_init_list
+ and current_base_init_list.
+ (tsubst_expr_values): Rename to ...
+ (tsubst_initializer_list): ... this. Use convert_from_reference.
+ * semantics.c (setup_vtbl_ptr): Don't use current_member_init_list
+ and current_base_init_list.
+ (begin_function_definition): Don't call reinit_parse_for_function.
+
+ * dump.c (dequeue_and_dump): Use TREE_VEC_LENGTH with vectors.
+
+ * error.c (dump_expr): Handle ADDR_EXPRs with REFERENCE_TYPE
+ correctly.
+
+ * cp-tree.h (DECL_PENDING_INLINE_P): Relax checking.
+
+2000-06-14 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (IF_COND): Move to c-common.h.
+ (THEN_CLAUSE): Likewise.
+ (ELSE_CLAUSE): Likewise.
+ (WHILE_COND): Likewise.
+ (WHILE_BODY): Likewise.
+ (DO_COND): Likewise.
+ (DO_BODY): Likewise.
+ (RETURN_EXPR): Likewise.
+ (EXPR_STMT_EXPR): Likewise.
+ (FOR_INIT_STMT): Likewise.
+ (FOR_COND): Likewise.
+ (FOR_EXPR): Likewise.
+ (FOR_BODY): Likewise.
+ (SWITCH_COND): Likewise.
+ (SWITCH_BODY): Likewise.
+ (CASE_LOW): Likewise.
+ (CASE_HIGH): Likewise.
+ (GOTO_DESTINATION): Likewise.
+ (COMPOUND_BODY): Likewise.
+ (ASM_CV_QUAL): Likewise.
+ (ASM_STRING): Likewise.
+ (ASM_OUTPUTS): Likewise.
+ (ASM_INPUTS): Likewise.
+ (ASM_CLOBBERS): Likewise.
+ (DECL_STMT_DECL): Likewise.
+ (STMT_EXPR_STMT): Likewise.
+ (LABEL_STMT_LABEL): Likewise.
+ (SCOPE_BEGIN_P): Likewise.
+ (SCOPE_END_P): Likewise.
+ (SCOPE_STMT_BLOCK): Likewise.
+ (SCOPE_NULLIFIED_P): Likewise.
+ (SCOPE_NO_CLEANUPS_P): Likewise.
+ (SCOPE_PARTIAL_P): Likewise.
+ (ASM_VOLATILE_P): Likewise.
+ (STMT_LINENO): Likewise.
+ (STMT_LINENO_FOR_FN_P): Likewise.
+
+ * cp-tree.def: Removed SRCLOC, SIZEOF_EXPR, ARROW_EXPR,
+ ALIGNOF_EXPR, EXPR_STMT, COMPOUND_STMT, DECL_STMT, IF_STMT,
+ FOR_STMT, WHILE_STMT, DO_STMT, RETURN_STMT, BREAK_STMT,
+ CONTINUE_STMT, SWITCH_STMT, GOTO_STMT, LABEL_STMT, ASM_STMT,
+ SCOPE_STMT, CASE_LABEL, STMT_EXPR.
+
+ * Makefile.in (CXX_TREE_H): Added $(srcdir)/../c-common.def.
+
+ * Make-lang.in (CXX_SRCS): Added $(srcdir)/c-common.def.
+ (cc1plus$(exeext)): Added $(srcdir)/c-common.def.
+
+ * lex.c (cplus_tree_code_type[]): Added '#include "c-common.def"'.
+ (cplus_tree_code_length[]): Added '#include "c-common.def"'.
+ (cplus_tree_code_name[]): Added '#include "c-common.def"'.
+
+2000-06-14 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BINFO_OVERRIDE_ALONG_VIRTUAL_PATH): New macro.
+ * class.c (dfs_find_final_overrider): Set it appropriately.
+ (dfs_built_vtt_inits): Check BINFO_OVERRIDE_ALONG_VIRTUAL_PATH to
+ avoid unneeded secondary vptrs.
+
+2000-06-13 Jakub Jelinek <jakub@redhat.com>
+
+ * class.c (build_secondary_vtable): Set DECL_USER_ALIGN.
+ (check_bitfield_decl, check_field_decl): Likewise.
+ (build_vtbl_or_vbase_field, build_base_field): Likewise.
+ (layout_class_type): Set DECL_USER_ALIGN resp. CLASSTYPE_USER_ALIGN.
+ * decl.c (record_unknown_type): Set TYPE_USER_ALIGN.
+ (xfer_tag, finish_enum): Likewise.
+ * decl2.c (finish_builtin_type): Likewise.
+ * init.c (init_init_processing): Likewise.
+ * pt.c (instantiate_class_template): Likewise.
+ * rtti.c (get_tinfo_decl, synthesize_tinfo_fn): Set DECL_USER_ALIGN.
+ * cp-tree.h (struct lang_type): Add user_align member.
+ (CLASSTYPE_USER_ALIGN): Define.
+
+2000-06-13 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * Make-lang.in (c++.install-common): Install g++-cross in
+ $(gcc_tooldir)/bin as g++ and c++; g++ in $(bindir) as
+ $(target_alias)-g++ and $(target_alias)-c++.
+
+2000-06-12 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (vcall_offset_data_s): Add last_init and fns.
+ (overrides): Rename to same_signature_p.
+ (dfs_find_final_overrider): Adjust accordingly.
+ (mark_overriders): Likewise.
+ (warn_hidden): Likewise.
+ (build_vtbl_initializer): Reorganize machinery for building things
+ at negative offsets.
+ (build_vcall_and_vbase_vtbl_entries): Likewise.
+ (build_vbase_offset_vtbl_entries): Likewise.
+ (dfs_build_vcall_offset_vtbl_entries): Correct order of vcall
+ offset entries. Do not create two entries for functions with the
+ same signature.
+ (build_vcall_offset_vtbl_entries): Initialize vod->fns.
+ (build_rtti_vtbl_entries): Reorganize machinery for building things
+ at negative offsets.
+
+ * optimize.c (expand_call_inline): Don't recurse into the code
+ used to initialize the parameters more than once.
+
+2000-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (NESTED_TEMPLATE_MATCH): Fix typo in comment.
+ (is_std_substitution): Don't check CLASSTYPE_USE_TEMPLATE here.
+ (find_substitution): Only use the `Sa' substitution for
+ std::allocator, not instantiations of it.
+ (write_template_prefix): Move comment. Only use a TREE_LIST to
+ represent substitutions for a member template.
+ (write_array_type): Mangle array dimensions correctly.
+ * optimize.c (maybe_clone_body): Copy more information from the
+ cloned function.
+ * pt.c (regenerate_decl_from_template): Preserve DECL_USE_TEMPLATE
+ on the regenerated declaration.
+
+2000-06-11 Chip Salzenberg <chip@valinux.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable): Clarify comment.
+ (build_ctor_vtbl_group): Pass the most derived type to
+ build_vtable.
+
+2000-06-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (compare_options): Don't needlessly cast away const-ness.
+
+2000-06-10 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (add_binding): Handle duplicate declarations of external
+ variables.
+
+2000-06-09 Chip Salzenberg <chip@valinux.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_number): Take an unsigned HOST_WIDE_INT as an
+ argument.
+ (write_signed_number): New macro.
+ (write_unsigned_number): Likewise.
+ (write_source_name): Use them.
+ (write_number): Handle signed and unsigned values.
+ (write_integer_cst): Use tree_int_cst_sgn, and use
+ write_unsigned_number or write_signed_number as appropriate.
+ (write_discriminator): Use write_unsigned_number or
+ write_signed_number as appropriate.
+ (write_template_arg_literal): Likewise.
+ (write_array_type): Use tree_low_cst.
+ (write_template_parm): Use write_unsigned_number or
+ write_signed_number as appropriate.
+ (write_substitution): Adjust call to write_number.
+ (write_type): Get the TYPE_MAIN_VARIANT before mangling it.
+ (write_expression): Handle non-type template arguments of
+ reference type correctly.
+ (mangle_thunk): Use write_signed_number.
+
+2000-06-09 Chip Salzenberg <chip@valinux.com>
+
+ * mangle.c (find_substition): Don't mangle objects with typename
+ substitutions (e.g. "cin" as "Si").
+
+2000-06-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * call.c (add_candidate): Use ggc_alloc_cleared.
+ * decl.c (lookup_label): Likewise.
+ * lex.c (retrofit_lang_decl): Likewise.
+
+2000-06-09 Jason Merrill <jason@casey.soma.redhat.com>
+
+ * semantics.c (expand_body): Push to TV_EXPAND.
+ * optimize.c (optimize_function): Push to TV_INTEGRATION.
+ * decl.c (start_function): Always call announce_function.
+
+ * tinfo2.cc: Just declare abort.
+
+2000-06-09 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (DEF_OPERATOR): Say `operator@' -not- `operator @'
+ whenever @ is a symbolic name.
+
+2000-06-08 Jakub Jelinek <jakub@redhat.com>
+
+ * method.c (make_thunk): Clear DECL_VTT_PARM in thunk.
+
+2000-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pushdecl): Look up functions by DECL_NAME, not
+ DECL_ASSEMBLER_NAME.
+
+2000-06-06 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (c_language): Define.
+
+2000-06-06 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (lang_init_options): Tweak.
+
+ * decl2.c: Remove #inclusion of diagnostic.h
+ (lang_decode_option): Move diagnostic formatting options to
+ toplevel.
+
+ * lang-options.h: Remove documentation for diagnostic options.
+
+ * Makefile.in (lex.o): Depends upon diagnostic.h
+
+2000-06-06 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (redeclaration_error_message): If two TEMPLATE_DECLs have
+ the same DECL_RESULT, it's not a redefinition.
+ * pt.c (tsubst_decl): Remove code to handle illegal
+ specializations.
+
+2000-06-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * exception.cc: (__eh_alloc, __eh_free): Moved to libgcc2.c
+
+2000-06-05 Jason Merrill <jason@casey.soma.redhat.com>
+
+ * search.c (maybe_suppress_debug_info): Don't check
+ CLASSTYPE_INTERFACE_ONLY if CLASSTYPE_INTERFACE_KNOWN isn't set.
+
+ * pt.c (mark_decl_instantiated): Do SET_DECL_EXPLICIT_INSTANTIATION
+ here if extern_p.
+
+ Remember instantiation context in deferred instantiations.
+ * cp-tree.h (struct tinst_level): Remove.
+ (TINST_DECL, TINST_LINE, TINST_FILE): New macros.
+ * pt.c (current_tinst_level): Now a tree.
+ (print_template_context, push_tinst_level, pop_tinst_level,
+ tinst_for_decl): Adjust.
+ (reopen_tinst_level): New fn.
+ (init_pt): Register current_tinst_level as a root.
+ (add_pending_template): Put current_tinst_level in TREE_PURPOSE
+ of the pending templates list.
+ (instantiate_pending_templates): Adjust. Call reopen_tinst_level.
+ * lex.c (extract_interface_info): Adjust.
+ * decl2.c (warn_if_unknown_interface): Adjust.
+
+2000-06-05 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (indirect_primary_base_p): New function.
+ (determine_primary_base): Use it.
+
+2000-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ Update new-abi dynamic cast algorithm.
+ * tinfo.cc (__class_type_info::__dyncast_result): Add
+ whole_details. Adjust constructor.
+ (__vmi_class_type_info::__do_dyncast): Adjust for vmi_flags.
+ Avoid unnecessary searching.
+ (__dynamic_cast): Adjust for __dyncast_result::whole_details.
+
+2000-06-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (init_decl_processing): Don't call record_component_aliases.
+ * tree.c (build_cplus_array_type_1): Likewise.
+
+2000-06-04 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi: Correct typo.
+ * mangle.c (write_expression): Handle non-type template arguments
+ with reference type.
+ * method.c (build_overload_value): Likewise.
+ * pt.c (convert_nontype_argument): Explicitly represent conversion
+ to a reference with an ADDR_EXPR.
+ (unify): Always unify arguments in left-to-right order.
+
+2000-06-03 Alex Samuel <samuel@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (CXX_SRCS): Add mangle.c.
+ * Makefile.in (CXX_OBJS): Add mangle.o.
+ (mangle.o): New rule.
+
+ * class.c (local_classes): New variable.
+ * class.c (get_vtable_name): Use mangle_vtable_for_type for new ABI.
+ (get_vtt_name): Use mangle_vtt_name for new ABI.
+ (init_class_processing): Initialize local_classes.
+ (build_ctor_vtbl_group): Use mangle_ctor_vtbl_for_type for new ABI.
+ * cp-tree.h (cp_tree_index): Add CPTI_STD_IDENTIFIER.
+ (std_identifier): New macro.
+ (DECL_VOLATILE_MEMFUNC_P): New macro.
+ (DECL_NAMESPACE_STD_P): Likewise.
+ (local_classes): Declare.
+ (get_mostly_instantiated_function_type): Declare.
+ (init_mangle): Declare.
+ (mangle_decl): Likewise.
+ (mangle_type_string): Likewise.
+ (mangle_type): Likewise.
+ (mangle_typeinfo_for_type): Likewise.
+ (mangle_typeinfo_string_for_type): Likewise.
+ (mangle_vtbl_for_type): Likewise.
+ (mangle_vtt_for_type): Likewise.
+ (mangle_ctor_vtbl_for_type): Likewise.
+ (mangle_thunk): Likewise.
+ (mangle_conv_op_name_for_type): Likewise.
+ (mangle_guard_variable): Likewise.
+ * decl.c (pushtag): Keep track of local classes.
+ (initialize_predefined_identifiers): Initialize std_identifier.
+ (init_decl_processing): Use std_identifier.
+ (start_decl): Don't treat instantiations as specializations.
+ (grokdeclarator): Likewise.
+ (grokvardecl): Call mangle_decl for new ABI. Only set mangled
+ name for fully-instantiated templates.
+ * decl2.c (grokclassfn): Use set_mangled_name_for_decl for
+ destructors with the new ABI.
+ (finish_static_data_member_decl): Use mangle_decl under the new ABI.
+ (grokfield): Use mangle_type for new ABI.
+ (grokoptypename): Use mangle_conv_op_for_type for new ABI.
+ (get_sentry): Use mangle_guard_variable for new ABI.
+ (start_static_initialization_or_destruction): Likewise.
+ * expr.c (extract_aggr_init): Remove.
+ (extract_scalar_init): Likewise.
+ (extract_init): Remove #if 0'd code.
+ * mangle.c: New function.
+ * method.c (build_mangled_name): Assert not flag_new_abi.
+ (build_static_name): Likewise.
+ (build_decl_overload_real): Likewise.
+ (build_typename_overload): Likewise.
+ (build_overload_with_type): Likewise.
+ (build_overload_name): Likewise.
+ (get_ctor_vtbl_name): Likewise.
+ (start_squangling): Likewise.
+ (get_id_2): Likewise.
+ (set_mangled_name_for_decl): Call mangle_decl for new ABI.
+ (init_method): Call init_mangle for new ABI.
+ (make_thunk): Call mangle_thunk for new ABI.
+ * operators.def: Correct new ABI manglings for the `%' operator.
+ Add `::' operator.
+ * pt.c (build_template_decl): Copy DECL_OVERLOADED_OPERATOR_P and
+ DECL_ASSIGNMENT_OPERATOR_P to the TEMPLATE_DECL.
+ (lookup_template_class): Call mangle_decl for new ABI.
+ (get_mostly_instantiated_function_type): New function.
+ (set_mangled_name_for_template_decl): Use it.
+ (tsubst_decl): Use set_mangled_name_for_decl for destructors with
+ the new ABI. Use mangle_conv_op_name_for_type for instantiated
+ conversion op names.
+ * rtti.c (tinfo_name): Call mangle_type_string for new ABI.
+ (get_tinfo_decl): Call mangle_typeinfo_for_type for new ABI.
+ (tinfo_base_init): Likewise. Mangle typeinfo string name with
+ mangle_typeinfo_string_for_type.
+
+2000-06-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TMPL_ARGS_LEVEL): Clarify comment.
+ (INNERMOST_TEMPLATE_ARGS): New macro.
+ (innermost_args): Remove.
+ (get_innermost_template_args): New function.
+ * decl2.c (arg_assoc_class): Use INNERMOST_TEMPLATE_ARGS.
+ * error.c (dump_function_decl): Be caution when using
+ most_general_template.
+ * method.c (build_template_parm_names): Use
+ INNERMOST_TEMPLATE_ARGS.
+ * pt.c (add_to_template_args): Tidy comment
+ (get_innermost_template_args): New function.
+ (check_explicit_specialization): Clear DECL_INITIAL for a new
+ specialization.
+ (process_partial_specialization): Use INNERMOST_TEMPLATE_ARGS.
+ Tidy.
+ (push_template_decl): Always register specializations of the most
+ general template.
+ (convert_template_argument): Use INNERMOST_TEMPLATE_ARGS.
+ (coerce_template_parms): Likewise.
+ (lookup_template_class): Likewise.
+ (innermost_args): Remove.
+ (tsubst_decl): Use INNERMOST_TEMPLATE_ARGS.
+ (tsubst_decl): Handle tricky specializations. Use
+ get_innermost_template_args.
+ (instantiate_template): Simplify handling of partial
+ instantiations.
+ (get_class_bindings): Use INNERMOST_TEMPLATE_ARGS.
+ (most_general_template): Reimplement, in a more straightforward
+ manner.
+ (regenerate_decl_from_template): Tweak formatting. Use
+ TMPL_ARGS_DEPTH for clarity.
+ (set_mangled_name_for_template_decl): Use INNERMOST_ARGS.
+
+ * dump.c (dequeue_and_dump): Dump information about thunks.
+
+2000-06-01 Richard Henderson <rth@cygnus.com>
+
+ * decl.c (init_decl_processing): Set lang_get_alias_set first thing.
+
+2000-06-01 Richard Henderson <rth@cygnus.com>
+
+ * decl2.c (unsupported_options): Fix typo, make const.
+ (lang_decode_option): Fix bsearch argument order.
+
+2000-06-01 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (resolve_offset_ref): Remove check for TREE_ADDRESSABLE
+ on FIELD_DECLs.
+
+2000-05-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * cp-tree.h (c_get_alias_set): Deleted.
+ * Makefile.in (decl.o): Include ../expr.h.
+ * decl.c (expr.h): Include.
+ (init_decl_processing): Call record_component_aliases for arrays.
+ (grokdeclarator): Likewise.
+ Set TREE_ADDRESSABLE for fields that aren't bitfields.
+ * tree.c (build_cplus_array_type_1): Call record_component_aliases.
+
+2000-05-31 Mark Mitchell <mark@codesourcery.com>
+
+ Remove guiding declaration support.
+ * cp/cp-tree.h (flag_dump_translation_unit): Make it const.
+ (flag_guiding_decls): Remove.
+ * call.c (build_user_type_conversion_1): Remove support for
+ guiding decls.
+ (build_new_function_call): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+ * decl.c (start_function): Likewise.
+ * friend.c (is_friend): Likewise.
+ (do_friend): Likewise.
+ * decl2.c ((flag_dump_translation_unit): Make it const.
+ (flag_guiding_decls): Remove.
+ (unsupported_options): New variable
+ (compare_options): New function.
+ (lang_decode_option): Use them.
+
+ * decl.c (build_cp_library_fn): Set DECL_CONTEXT.
+
+ * method.c (mangle_expression): Adjust test for legal expression
+ operators.
+
+ * pt.c (instantiate_decl): Save and restore the local
+ specializations list.
+
+2000-05-30 Jason Merrill <jason@decepticon.cygnus.com>
+
+ * decl.c (grok_reference_init): Pass LOOKUP_ONLYCONVERTING.
+
+2000-05-30 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (add_template_candidate_real): Handle member template
+ constructors for classes with virtual bases.
+ (build_user_type_conversion_1): Use in_charge_arg_for_name.
+ (build_new_method_call): Use DECL_NONSTATIC_MEMBER_FUNCTION_P.
+
+ * ir.texi: Update thunk documentation.
+
+ * call.c (joust): Fix handling of overloaded builtin operators.
+
+2000-05-30 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cp-tree.h (DECL_ANTICIPATED): New macro.
+ Document new use of DECL_LANG_FLAG_7.
+ * decl.c (builtin_function): Set DECL_ANTICIPATED on builtins
+ in the user namespace.
+ * lex.c (do_identifier): If the identifier's declaration has
+ DECL_ANTICIPATED on, it has not yet been declared. But do not
+ replace it with an ordinary implicit declaration.
+
+ * tinfo2.cc: Include stdlib.h.
+
+2000-05-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_ALIGN_UNIT): New macro.
+ * class.c (layout_empty_base): Use CLASSTYPE_ALIGN_UNIT, not
+ CLASSTYPE_ALIGN.
+
+2000-05-28 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Use skip_leading_substring instead
+ of plain strncmp.
+
+2000-05-28 Alexandre Oliva <aoliva@cygnus.com>
+
+ * operators.def (<?): Duplicated, should have been...
+ (>?): this. Fixed.
+
+2000-05-27 Alex Samuel <samuel@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (ansi_opname): Make it a macro.
+ (ansi_assopname): Likewise.
+ (struct lang_decl_flags): Add assignment_operator_p.
+ (struct lang_decl): Add operator_code.
+ (DECL_VTT_PARM): Adjust.
+ (DECL_OVERLOADED_OPERATOR_P): Return the operator_code for an
+ overloaded operator.
+ (SET_OVERLOADED_OPERATOR_CODE): New macro.
+ (DECL_ASSIGNMENT_OPERATOR_P): New macro.
+ (DECL_ARRAY_DELETE_OPERATOR_P): Adjust.
+ (opname_tab): Remove.
+ (assignop_tab): Likewise.
+ (operator_name_info_t): New type.
+ (operator_name_info): New variable.
+ (assignment_operator_name_info): Likewise.
+ (build_cp_library_fn): Remove declaration.
+ (push_cp_library_fn): Likewise.
+ (operator_name_string): Likewise.
+ (build_decl_overload): Likewise.
+ * call.c (print_z_candidates): Simplify.
+ (build_object_call): Adjust usage of ansi_opname. Use
+ DECL_OVERLOADED_OPERATOR_P.
+ (op_error): Adjust operator name lookup.
+ (build_conditional_expr): Adjust usage of ansi_opname.
+ (build_new_op): Likewise.
+ (build_op_delete_call): Likewise.
+ (build_over_call): Likewise.
+ (joust): Use DECL_OVERLOADED_OPERATOR_P.
+ * decl.c (duplicate_decls): Copy operator_code.
+ (init_decl_processing): Adjust parameters to push_cp_library_fn.
+ (builtin_function): Adjust parameters to build_library_fn_1.
+ (build_library_fn_1): Accept an overloaded operator code.
+ (build_library_fn): Pass ERROR_MARK.
+ (build_cp_library_fn): Accept an overloaded operator code.
+ (push_cp_library_fn): Likewise.
+ (grokfndecl): Tweak.
+ (grokdeclarator): Simplify code to compute names of overloaded
+ operators. Adjust use of ansi_opname.
+ (ambi_op_p): Work on tree_codes, not identifiers.
+ (unary_op_p): Likewise.
+ (grok_op_properties): Likewise.
+ (start_function): Use DECL_OVERLOADED_OPERATOR_P.
+ (lang_mark_tree): Don't try to mark the operator_code.
+ * decl2.c (grok_function_init): Use DECL_OVERLOADED_OPERATOR_P.
+ * error.c (dump_decl): Remove special handling for operator
+ names.
+ (dump_function_name): Likewise.
+ (dump_expr): Adjust name lookup of operators.
+ (op_to_string): Simplify.
+ (assop_to_string): Likewise.
+ * init.c (build_new_1): Adjust use of ansi_opname.
+ * lex.c (opname_tab): Remove.
+ (assignop_tab): Likewise.
+ (ansi_opname): Likewise.
+ (ansi_assopname): Likewise.
+ (operator_name_string): Likewise.
+ (reinit_lang_specific): Likewise.
+ (operator_name_info): New variable.
+ (assignment_operator_name_info): Likewise.
+ (init_operators): New function.
+ (init_parse): Use it.
+ (do_identifier): Adjust use of ansi_opname.
+ * method.c (mangle_expression): Don't use ansi_opname for
+ mangling.
+ (build_decl_overload_real): Use DECL_OVERLOADED_OPERATOR_P.
+ (build_decl_overload): Remove.
+ (build_typename_overload): Use OPERATOR_TYPENAME_FORMAT directly.
+ (do_build_assign_ref): Adjust use of ansi_opname.
+ (synthesize_method): Likewise.
+ (implicitly_declare_fn): Likewise.
+ * operators.def: New file.
+ * parse.y (operator): Adjust use of ansi_opname.
+ * pt.c (tsubst_decl): Use IDENTIFIER_OPNAME_P.
+ (set_mangled_name_for_template_decl): Don't play games with
+ current_namespace.
+ (special_function_p): Adjust use of ansi_opname.
+ * typeck.c (check_return_expr): Likewise.
+ * Make-lang.in (cc1plus): Depend on operators.def.
+ * Makefile.in (lex.o): Likewise.
+ (decl.o): Likewise.
+
+2000-05-27 Zack Weinberg <zack@wolery.cumb.org>
+
+ * Make-lang.in (cplib2.ready): Eradicate.
+
+2000-05-27 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * method.c (mangle_expression): Use TREE_CODE_LENGTH.
+ * tree.c (break_out_calls, build_min_nt): Use TREE_CODE_LENGTH.
+ (built_min, cp_tree_equal): Likewise.
+
+2000-05-26 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_nonempty_base_or_field): Replace
+ `record_layout_info' with `record_layout_info_s'.
+
+2000-05-26 Jason Merrill <jason@casey.soma.redhat.com>
+
+ Fix goto checking.
+ * cp-tree.h (struct language_function): x_named_labels is now
+ a struct named_label_list*.
+ * decl.c (struct named_label_use_list): Renamed from...
+ (struct named_label_list): ...this. New struct.
+ (push_binding_level): Don't set eh_region.
+ (note_level_for_eh): New fn.
+ (pop_label): Take label and old value directly.
+ (pop_labels): Adjust for new named_labels format.
+ (lookup_label): Likewise.
+ (poplevel): Note characteristics of a binding level containing a
+ named label. Mess with named label lists earlier.
+ (mark_named_label_lists): New fn.
+ (mark_lang_function): Call it.
+ (use_label): New fn, split out from...
+ (make_label_decl): ...here. Don't call it.
+ (decl_jump_unsafe, check_previous_goto, check_previous_goto_1,
+ check_previous_gotos): New fns, split out from...
+ (define_label): ...here.
+ (check_switch_goto): New fn.
+ (define_case_label): Call it.
+ (check_goto): New fn.
+ * semantics.c (finish_goto_stmt): Call it and use_label.
+ (begin_compound_stmt): If we're a try block, call note_level_for_eh.
+ (expand_stmt): Never pass 1 as DONT_JUMP_IN to expand_end_bindings.
+
+2000-05-26 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable_entry_ref): Correct usage of
+ get_vtbl_decl_for_binfo.
+
+ * decl2.c (grokclassfn): Set DECL_LANGUAGE here.
+ * method.c (implicitly_declare_fn): Not here.
+
+2000-05-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTI_PTMD_DESC_TYPE): Rename to ...
+ (CPTI_PTMD_DESC_TYPE): ... here.
+ (ptmd_desc_type_node): Rename to ...
+ (ptm_desc_type_node): ... here.
+ * decl.c: Likewise.
+ * rtti.c (ptmd_initializer): Rename to ...
+ (ptm_initializer): ... here.
+ (sythesize_tinfo_var): Adjust. Deal with pointer to member
+ function.
+ (create_tinfo_types): Adjust.
+
+2000-05-25 Mark Mitchell <mark@codesourcery.com>
+
+ Finish implementation of VTTs.
+ * cp-tree.h (cp_tree_index): Add CPTI_VTT_PARM_TYPE and
+ CPTI_VTT_PARM_IDENTIFIER.
+ (vtt_parm_identifier): New macro.
+ (vtt_parm_type): Likewise.
+ (BINFO_SUBVTT_INDEX): Likewise.
+ (BINFO_VPTR_INDEX): Likewise.
+ (struct lang_decl): Add vtt_parm.
+ (DECL_VTT_PARM): New macro.
+ (DECL_USE_VTT_PARM): Likewise.
+ (DECL_NEEDS_VTT_PARM_P): Likewise.
+ (get_vtt_name): Declare.
+ (build_artificial_parm): Likewise.
+ (fixup_all_virtual_upcast_offsets): Likewise.
+ (expand_indirect_vtbls_init): Remove.
+ * call.c (build_new_method_call): Pass the vtt to subobject
+ constructors and destructors.
+ * class.c (get_vtt_name): Give it external linkage.
+ (build_clone): Handle the magic VTT parameters for clones.
+ (clone_function_decl): Fix typo in comment.
+ (build_vtt): Keep track of the indices in the VTTs where various
+ entities are stored.
+ (build_vtt_inits): Likewise.
+ (dfs_build_vtt_inits): Likewise.
+ (build_ctor_vtbl_group): Tweak type of construction vtables.
+ (dfs_accumulate_vtbl_inits): Build vtables for all bases, even
+ primary bases, when building construction vtables.
+ * decl.c (duplicate_decls): Handle DECL_VTT_PARM.
+ (initialize_predefined_identifiers): Add vtt_parm_identifier.
+ (init_decl_processing): Initialize vtt_parm_type.
+ (grokfndecl): Use DECL_OVERLOADED_OPERATOR_P.
+ (lang_mark_tree): Make vtt_parm.
+ * decl2.c (build_artificial_parm): New function.
+ (maybe_retrofit_in_chrg): Use it. Add VTT parameters.
+ (grokclassfn): Use build_artificial_parm.
+ * init.c (initialize_vtbl_ptrs): Call
+ fixup_all_virtual_upcast_offsets directly.
+ (perform_member_init): Use the complete subobject destructor for
+ member cleanups.
+ (build_vtbl_address): New function.
+ (expand_virtual_init): Handle VTTs.
+ * optimize (maybe_clone_body): Likewise.
+ * search.c (fixup_all_virtual_upcast_offsets): Give it external
+ linkage.
+ (expand_indirect_vtbls_init): Remove.
+ * semantics.c (setup_vtbl_ptr): Fix typos in comment.
+ * tree.c (make_binfo): Make them bigger.
+
+2000-05-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h (__pbase_type_info): Define, based on
+ __pointer_type_info.
+ (__pointer_type_info): Derive from __pbase_type_info. Adjust.
+ (__pointer_to_member_type_info): Likewise.
+ * tinfo2.cc (__pbase_type_info::~__pbase_type_info): Implement.
+ (__pointer_to_member_type_info::__is_pointer_p): Remove.
+ (__pointer_type_info::__do_catch): Rename to ...
+ (__pbase_type_info::__do_catch): ... here. Adjust.
+ (__pbase_type_info::__pointer_catch): Implement.
+ (__pointer_type_info::__pointer_catch): Adjust.
+ (__pointer_to_member_type_info::__pointer_catch): Adjust.
+
+2000-05-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.h (__user_type_info::contained_virtual_p): New
+ predicate.
+ * tinfo.cc (__user_type_info::do_upcast): Fix bug with diamond
+ shaped hierarchy.
+ (__vmi_class_type_info::__do_upcast): Fix bug with NULL pointer to
+ diamond shaped hierarchy. Add early out for mixed diamond and
+ duplicate shaped hierarchy.
+
+2000-05-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (build_delete): Change prototype.
+ (build_vec_delete): Likewise.
+ * call.c (build_scoped_method_call): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_method_call): Likewise.
+ * decl.c (finish_destructor_body): Likewise.
+ (maybe_build_cleanup_1): Likewise. Rename to ...
+ (maybe_build_cleanup): ... this.
+ * decl2.c (delete_sanity): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_cleanup): Likewise.
+ * init.c (perform_member_init): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_dtor_call): Simplify.
+ (build_delete): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_vbase_delete): Likewise.
+ (build_vec_delete): Likewise.
+
+ * init.c (sort_member_init): Fix typo in error message generation
+ code.
+
+2000-05-15 Donald Lindsay <dlindsay@cygnus.com>
+
+ * semantics.c (begin_class_definition): make the packed
+ attribute be sensitive to the "-fpack-struct" command line flag
+
+2000-05-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ Update new-abi upcast algorithm.
+ * inc/cxxabi.h (__class_type_info::__do_upcast): Change
+ prototype and meaning of return value.
+ (__si_class_type_info::__do_upcast): Likewise.
+ (__vmi_class_type_info::__do_upcast): Likewise.
+ * tinfo.cc (__class_type_info::__upcast_result): Replace
+ whole2dst with part2dst. Adjust ctor.
+ (__class_type_info::__do_upcast): Adjust call of worker function.
+ (__class_type_info::__do_upcast): Adjust.
+ (__si_class_type_info::__do_upcast): Adjust. Use parent's
+ __do_upcast.
+ (__vmi_class_type_info::__do_upcast): Likewise. Fix private
+ virtual base in diamond hierarchy bug.
+
+2000-05-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Rename mutable_flag to uninlinable
+ and bitfield to tinfo_fn_p.
+ (DECL_TINFO_FN_P): Adjust.
+ (SET_DECL_TINFO_FN_P): Likewise.
+ (DECL_MUTABLE_P): Likewise.
+ (DECL_C_BIT_FIELD): Likewise.
+ (SET_DECL_C_BIT_FIELD): Likewise.
+ (CLEAR_DECL_C_BIT_FIELD): Likewise.
+ (DECL_UNINLINABLE): Likewise.
+ * class.c (alter_access): Call retrofit_lang_decl if ncessary.
+ (handle_using_decl): Remove assertion.
+ (build_vtbl_or_vbase_field): Use build_decl, not build_lang_decl,
+ to build FIELD_DECLs.
+ (build_base_field): Likewise.
+ (layout_class_type): Likewise.
+ * decl.c (init_decl_processing): Likewise.
+ (build_ptrmemfunc_type): Likewise.
+ (grokdeclarator): Likewise.
+ * decl2.c (grok_x_components): Likewise.
+ * except.c (call_eh_info): Likewise.
+ * init.c (init_init_processing): Likewise.
+ * rtti.c (expand_class_desc): Likewise.
+ (create_pseudo_type_info): Likewise.
+ (get_vmi_pseudo_type_info): Likewise.
+ (create_tinfo_types): Likewise.
+ * ptree.c (print_lang_decl): Adjust.
+ * typeck.c (build_component_ref): Don't check DECL_LANG_SPECIFIC
+ before checking DECL_MUTABLE_P.
+
+ * decl2.c (maybe_retrofit_in_chrg): Don't create in-charge
+ parameters for template functions.
+ * pt.c (tsubst_decl): Make sure we call maybe_retrofit_in_chrg for
+ destructors as well as constructors.
+
+2000-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_ctor_vtbl_group): Set inits.
+ * optimize.c (maybe_clone_body): Set DECL_INLINE and
+ DECL_THIS_INLINE appropriately for clones.
+
+ * cp-tree.h (IDENTIFIER_TYPENAME_P): Use a flag, not strncmp.
+ (DECL_CONV_FN_P): Simplify.
+ (DECL_OPERATOR): Remove.
+ (language_to_string): Declare.
+ * decl.c (duplicate_decls): Fix typo in comment.
+ (grokdeclarator): Adjust use of IDENTIFIER_TYPENAME_P.
+ (grok_op_properties): Use DECL_CONV_FN_P instead of
+ IDENTIFIER_TYPENAME_P.
+ * dump.c (dequeue_and_dump): Dump the language linkage of
+ declarations.
+ * error.c (language_to_string): Give it external linkage.
+ * method.c (build_typename_overload): Set IDENTIFIER_TYPENAME_P.
+ (implicitly_declare_fn): Set DECL_LANGUAGE.
+ * pt.c (check_explicit_specialization): Use DECL_CONV_FN_P, not
+ IDENTIFIER_TYPENAME_P.
+ (tsubst_decl): Likewise.
+ (tsubst_copy): Adjust use of IDENTIFIER_TYPENAME_P.
+ * semantics.c (finish_member_declaration): Don't mark members of
+ classes declared in an extern "C" region as extern "C".
+
+2000-05-22 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl2.c (qualified_lookup_using_namespace): Look through
+ namespace aliases.
+
+ * decl.c (push_using_decl): Return the old decl on namespace level.
+
+2000-05-21 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (SET_BINFO_NEW_VTABLE_MARKED): Add sanity checks.
+ (VTT_NAME_PREFIX): New macro.
+ (CTOR_VTBL_NAME_PREFIX): Likewise.
+ (get_ctor_vtbl_name): New function.
+ * class.c (get_vtable_name): Simplify.
+ (get_vtt_name): New function.
+ (get_vtable_decl): Don't set IDENTIFIER_GLOBAL_VALUE.
+ (dfs_mark_primary_bases): Update the CLASSTYPE_VBASECLASSES list
+ when a virtual base becomes primary.
+ (finish_struct_1): Set CLASSTYPE_VFIELDS a little earlier. Build
+ VTTs.
+ (finish_vtbls): Adjust calls to accumulate_vtbl_inits to pass in
+ additional parameters.
+ (dfs_finish_vtbls): Don't clear BINFO_NEW_VTABLE_MARKED.
+ (initialize_array): New function.
+ (build_vtt): Likewise.
+ (build_vtt_inits): Likewise.
+ (dfs_build_vtt_inits): Likewise.
+ (dfs_fixup_binfo_vtbls): Likewise.
+ (build_ctor_vtbl_group): Likewise.
+ (initialize_vtable): Use initialize_array.
+ (accumulate_vtbl_inits): Reimplement to handle construction
+ vtables.
+ (dfs_accumulate_vtbl_inits): Likewise.
+ (bulid_vtbl_initializer): Adjust parameter name.
+ * method.c (build_typename_overload): Remove #if 0'd code.
+ (get_ctor_vtbl_name): New function.
+ * search.c (dfs_walk_real): Use BINFO_N_BASETYPES.
+ (init_vbase_pointers): Don't mess with the TREE_CHAIN of a binfo.
+
+ * cp-tree.h (struct lang_type): Remove search_slot.
+ (CLASSTYPE_SEARCH_SLOT): Remove.
+ (emit_base_init): Change prototype.
+ (initialize_vtbl_ptrs): Likewise.
+ (expand_indirect_vtbls_init): Likewise.
+ (clear_search_slots): Remove.
+ * decl.c (lang_mark_tree): Don't mark search_slot.
+ * init.c (initialize_vtbl_ptrs): Simplify.
+ (emit_base_init): Likewise.
+ * search.c (struct vbase_info): Document decl_ptr.
+ (convert_pointer_to_single_level): Remove.
+ (dfs_find_vbases): Remove.
+ (dfs_init_base_pointers): Simplify.
+ (dfs_clear_vbase_slots): Remove.
+ (dfs_vtable_path_unmark): New function.
+ (init_vbase_pointers): Simplify.
+ (expand_upcast_fixups): Don't rely on CLASSTYPE_SEARCH_SLOT.
+ (expand_indirect_vtbls_init): Simplify. Don't call
+ mark_all_temps_used.
+ * semantics.c (setup_vtbl_ptr): Adjust calls to emit_base_init and
+ initialize_vtbl_ptrs.
+
+2000-05-20 Zack Weinberg <zack@wolery.cumb.org>
+
+ * except.c: Add static prototypes.
+
+2000-05-20 H.J. Lu <hjl@gnu.org>
+
+ * Make-lang.in (cplib2.ready): Also depend on cc1plus$(exeext).
+
+2000-05-19 Mark Mitchell <mark@codesourcery.com>
+
+ Don't create a separate copy of virtual bases for the
+ CLASSTYPE_VBASECLASSES list.
+ * cp-tree.h (CLASSTYPE_VBASECLASSES): Change documentation.
+ (BINFO_FOR_VBASE): Remove.
+ (CANONICAL_BINFO): Adjust.
+ (binfo_for_vbase): New function.
+ * class.c (build_vbase_pointer_fields): Use binfo_for_vbase
+ instead of BINFO_FOR_VBASE.
+ (build_vbase_pointer): Likewise.
+ (build_secondary_vtable): Likewise.
+ (dfs_mark_primary_bases): Likewise.
+ (mark_primary_bases): Likewise.
+ (layout_nonempty_base_or_field): Likewise.
+ (dfs_set_offset_for_shared_vbases): Likewise.
+ (dfs_set_offset_for_unshared_vbases): Likewise.
+ (layout_virtual_bases): Likewise. Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (dump_class_hierarchy_r): Use binfo_for_vbase
+ instead of BINFO_FOR_VBASE.
+ (dump_class_hierarchy): Likewise.
+ (finish_vtbls): Likewise.
+ (build_vtbl_initializer): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (build_vbase_offset_vtbl_entries): Use binfo_for_vbase.
+ * decl.c (finish_destructor_body): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ * init.c (sort_base_init): Use binfo_for_vbase.
+ (construct_virtual_bases): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (expand_member_init): Use binfo_for_vbase.
+ (build_vbase_delete): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ * method.c (do_build_copy_constructor): Likewise.
+ * rtti.c (get_base_offset): Use binfo_for_vbase.
+ (expand_class_desc): Remove #if 0'd code.
+ * search.c (struct vbase_info): Remove vbase_types.
+ (get_base_distance): Use binfo_for_vbase.
+ (lookup_field_queue_p): Use CANONICAL_BINFO.
+ (get_shared_vbase_if_not_primary): Use binfo_for_vbase.
+ (get_pure_virtuals): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (dfs_find_vbases): Use binfo_for_vbase.
+ (dfs_init_vbase_pointers): Likewise.
+ (init_vbase_pointers): Don't initialize vi.vbase_types.
+ (virtual_context): Use binfo_for_vbase.
+ (fixup_all_virtual_upcast_offsets): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (expand_indirect_vtbls_init): Simplify.
+ (dfs_get_vbase_types): Don't replicate virtual bases.
+ (find_vbase_instance): Use binfo_for_vbase.
+ (binfo_for_vbase): New function.
+ * typeck.c (get_delta_difference): Use binfo_for_vbase.
+
+2000-05-17 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_anon_union): Generalize error messages to handle
+ anonymous structures.
+ * init.c (perform_member_init): Remove `name' parameter.
+ (build_field_list): New function.
+ (sort_member_init): Handle anonymous union initialization order
+ correctly. Check for multiple initializations of the same union.
+ (emit_base_init): Don't look up fields by name here.
+ (expand_member_init): Record the result of name lookup for future
+ reference.
+ * typeck.c (build_component_ref): Fix formatting.
+
+2000-05-17 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * decl.c (pop_label): Replace warn_unused with warn_unused_label.
+ * typeck.c (build_x_compound_expr): Replace warn_unused with
+ warn_unused_value.
+
+ * decl2.c (lang_decode_option): Update -Wall unused flags by
+ calling set_Wunused.
+
+2000-05-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-treeh (BINFO_NEW_VTABLE_MARKED): Update documentation.
+ * init.c (dfs_vtable_path_unmark): Remove.
+ * search.c (marked_new_vtable_p): Likewise.
+ (unmarked_new_vtable_p): Likewise.
+ (dfs_search_slot_nonempty_p): Likewise.
+ (dfs_mark): Likewise.
+ (dfs_vtable_path_unmark): Likewise.
+ (dfs_find_vbases): Don't set BINFO_NEW_VTABLE_MARKED.
+ (dfs_int_vbase_pointers): Don't clear BINFO_VTABLE_PATH_MARKED.
+ (dfs_init_vbase_pointers): Remove special-case new ABI code.
+ (dfs_clear_vbase_slots): Don't clear BINFO_NEW_VTABLE_MARKED.
+ (init_vbase_pointers): Simplify.
+ (expand_indirect_vtbls_init): Likewise.
+
+ * class.c (copy_virtuals): New function.
+ (build_primary_table): Use it.
+ (build_secondary_vtable): Likewise.
+ (modify_vtable_entry): Use NULL_TREE, not integer_zero_node, to
+ indicate that no vcall offset is required.
+ (add_virtual_function): Likewise.
+ (modify_all_vtables): Likewise.
+ (dfs_finish_vtbls): Adjust call to build_vtbl_initializer.
+ (dfs_accumulate_vtbl_inits): Likewise.
+ (build_vtbl_initializer): Make changes to handle construction
+ vtables.
+ (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (build_rtti_vtbl_entries): Likewise.
+ (build_vtable_entries): Handle a NULL vcall_index.
+
+2000-05-15 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Fix thinko.
+
+2000-05-14 Jason Merrill <jason@casey.cygnus.com>
+
+ * except.c (check_handlers): New fn.
+ * cp-tree.h: Declare it.
+ * semantics.c (finish_handler_sequence): Call it.
+ (finish_function_handler_sequence): Likewise.
+ (finish_handler_parms): Set TREE_TYPE on the handler.
+ * cp-tree.h (PUBLICLY_UNIQUELY_DERIVED_P): New macro.
+ * search.c (get_base_distance_recursive): If protect>1, ignore
+ special access.
+ (get_base_distance): Don't reduce watch_access.
+
+2000-05-13 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c: #include diagnostic.h.
+ (lang_init_options): Set default prefixing rules.
+
+ * lang-options.h: Add -fdiagnostics-show-location=.
+
+ * decl2.c: #include diagnostic.h.
+ (lang_decode_option): Handle -fdiagnostics-show-location=.
+
+2000-05-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.cc: Revert my 2000-05-08 and 2000-05-07 changes.
+ * vec.cc: Revert my 2000-05-07 change.
+
+2000-05-11 Jason Merrill <jason@casey.cygnus.com>
+
+ * class.c (check_field_decls): Complain about non-static data
+ members with same name as class in class with constructor.
+
+2000-05-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (grokdeclarator): Allow non-static data members with
+ same name as class.
+
+2000-05-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cp-tree.h: Constify tree_srcloc.filename, tinst_level.file,
+ and pending_inline.filename. Update prototypes.
+ * decl.c (define_label): Constify filename parameter.
+ * decl2.c (warn_if_unknown_interface): Constify local char *.
+ * input.c Constify input_source.filename. Don't declare
+ input_filename or lineno. Constify filename parameter to feed_input.
+ * lex.c (init_parse): Constify parameter and return value.
+ (cp_pragma_interface, cp_pragma_implementation): Constify
+ filename argument.
+ (reinit_parse_for_method, reinit_parse_for_block,
+ reinit_parse_for_expr, feed_defarg, handle_cp_pragma):
+ Constify local char *.
+ * pt.c: Don't declare lineno or input_filename.
+ (print_template_context, tsubst_friend_function, tsubst_decl,
+ tsubst, instantiate_decl): Constify local char *.
+ * semantics.c (expand_body): Constify local char *.
+ * tree.c (build_srcloc): Constify filename parameter.
+ * typeck.c (c_expand_asm_operands): Constify filename
+ parameter.
+
+2000-05-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.cc (__dynamic_cast): Use a reinterpret_cast. Fix
+ offsetof expansion.
+
+2000-05-08 Branko Cibej <branko.cibej@hermes.si>
+
+ * inc/cxxabi.h: Fix typos in comment.
+ (__base_class_info::__offset): Use a static_cast.
+
+2000-05-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h: Use __SIZE_TYPE_ and __PTRDIFF_TYPE__ in place
+ of std::size_t and std::ptrdiff_t respectively.
+ * tinfo.cc: Likewise.
+ * vec.cc: Likewise.
+
+2000-05-06 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (build_c_cast): Don't warn integer->pointer size
+ mismatch for constants.
+
+2000-05-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (ptmd_initializer): Set non-public, if class is
+ incomplete.
+
+ * inc/cxxabi.h (__dynamic_cast): Explicitly say extern "C++".
+ (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
+ __cxa_vec_delete): Likewise.
+ * tinfo.cc (__dynamic_cast): Likewise.
+ * vec.cc (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
+ __cxa_vec_delete): Likewise.
+
+2000-05-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DELTA_FROM_VTABLE_ENTRY): Remove.
+ (SET_FNADDR_FROM_VTABLE_ENTRY): Likewise.
+ (lang_decl_flags): Add vcall_offset.
+ (THUNK_VCALL_OFFSET): Use it.
+ * decl.c (lang_mark_tree): Don't mark DECL_ACCESS for a thunk.
+ * method.c (make_thunk): Create the lang_decl here, not in
+ emit_thunk.
+ (emit_thunk): Make generic thunks into ordinary functions once
+ they have been fed to expand_body.
+ * semantics.c (expand_body): Set current_function_is_thunk here.
+
+2000-05-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (update_vtable_entry_for_fn): Prototype.
+
+ * pt.c (tsubst_decl): Initialize variables `argvec', `gen_tmpl'
+ and `tmpl'.
+
+ * search.c (dfs_build_inheritance_graph_order): Prototype.
+
+2000-05-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (special_function_kind): Add various kinds of
+ destructors.
+ (special_function_p): New function.
+ * class.c (overrides): Don't let one kind of destructor override
+ another.
+ * decl2.c (mark_used): Use DECL_NON_THUNK_FUNCTION_P when deciding
+ whether or not to instantiate a template.
+ * tree.c (special_function_p): Define.
+
+2000-05-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (THUNK_DECL): Remove.
+ * cp-tree.h (DECL_THUNK_P): New macro.
+ (DECL_NON_THUNK_FUNCTION_P): Likewise.
+ (DECL_EXTERN_C_FUNCTION_P): Likewise.
+ (SET_DECL_THUNK_P): Likewise.
+ (DELTA_FROM_VTABLE_ENTRY): Use DECL_THUNK_P.
+ (FNADDR_FROM_VTABLE_ENTRY): Likewise.
+ (DECL_MAIN_P): Use DECL_EXTERN_C_FUNCTION_P.
+ * decl.c (decls_match): Use DECL_EXTERN_C_P.
+ (duplicate_decls): Likewise.
+ (pushdecl): Likewise. Adjust thunk handling.
+ (grokfndecl): Use DECL_EXTERN_C_P.
+ * decl2.c (mark_vtable_entries): Use DECL_THUNK_P.
+ * dump.c (dequeue_and_dump): Remove THUNK_DECL handling.
+ * except.c (nothrow_libfn_p): Use DECL_EXTERN_C_P.
+ * expr.c (cplus_expand_expr): Remove THUNK_DECL handling.
+ * method.c (make_thunk): Use SET_DECL_THUNK_P. Set
+ DECL_NO_STATIC_CHAIN.
+ (emit_thunk): Don't play games with TREE_CODE on thunks. Don't
+ set DECL_DESTRUCTOR_P or DECL_CONSTRUCTOR_P on a thunk.
+ * search.c (covariant_return_p): Remove THUNK_DECL handling.
+ * ir.texi: Update.
+
+2000-05-01 Jason Merrill <jason@casey.cygnus.com>
+
+ * tree.c (walk_tree): Set lineno.
+
+2000-05-01 Mark Mitchell <mark@codesourcery.com>
+
+ * exception.cc: Update license notice.
+ * new.cc: Likewise.
+ * new1.cc: Likewise.
+ * new2.cc: Likewise.
+ * tinfo.cc: Likewise.
+ * tinfo2.cc: Likewise.
+ * vec.cc: Likewise.
+ * inc/cxxabi.h: Likewise.
+ * inc/exception: Likewise.
+ * inc/new: Likewise.
+ * inc/new.h: Likewise.
+ * inc/typeinfo: Likewise.
+
+2000-05-01 Jason Merrill <jason@casey.cygnus.com>
+
+ * tree.c (build_target_expr_with_type): If we already have a
+ TARGET_EXPR, just return it.
+
+ * optimize.c (initialize_inlined_parameters): Don't generate an
+ EXPR_STMT if we can just use DECL_INITIAL.
+ * decl.c (emit_local_var): Only make the initialization a
+ full-expression if stmts_are_full_exprs_p.
+
+2000-05-01 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (same_type_ignoring_top_level_qualifiers_p): New
+ macro.
+ * call.c (standard_conversion): Use it.
+ (direct_reference_binding): Likewise.
+ (build_over_call): Likewise.
+ (is_properly_derived_from): Likewise.
+ (compare_ics): Likewise.
+ * class.c (resolves_to_fixed_type_p): Likewise.
+ * optimize.c (declare_return_variable): Likewise.
+ * pt.c (is_specialization_of): Likewise.
+ (unify): Likewise.
+ * typeck.c (comp_target_parms): Likeiwse.
+ (build_static_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (comp_ptr_ttypes_real): Likewise.
+ (comp_ptr_ttypes_const): Likewise.
+ * typeck2.c (process_init_constructor): Likewise.
+
+2000-04-30 Scott Snyder <snyder@fnal.gov>
+
+ * decl.c (finish_destructor_body): Use the base destructor when
+ destroying virtual bases.
+
+2000-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * expr.c (cplus_expand_expr): Preserve temporaries when expanding
+ STMT_EXPRs.
+ * optimize.c (struct inline_data): Add target_exprs field.
+ (declare_return_variable): When a function returns an aggregate,
+ use the variable declared in the TARGET_EXPR as the remapped
+ DECL_RESULT.
+ (expand_call_inline): Update the pending target_exprs stack.
+ (optimize_function): Initialize the stack.
+
+ * decl2.c (finish_file): Fix typo in comment.
+
+ * method.c (emit_thunk): Don't try to return a `void' value.
+
+ * optimize.c (initialize_inlined_parameters): If the parameter is
+ addressable, we need to make a new VAR_DECL, even if the
+ initializer is constant.
+
+2000-04-28 Cosmin Truta <cosmint@cs.ubbcluj.ro>
+
+ * decl.c (grok_op_properties): Add an extra check of argtypes.
+
+2000-04-27 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (copy_body_r): Use STRIP_TYPE_NOPS when copying
+ variables.
+ (initialize_inlined_parameters): Try to avoid creating new
+ VAR_DECLs.
+
+2000-04-27 Alex Samuel <samuel@codesourcery.com>
+
+ * lex.c (my_get_run_time): Remove.
+ (init_filename_times): Use get_run_time instead of my_get_run_time.
+ (check_newline): Likewise.
+ (dump_time_statistics): Likewise.
+ * decl2.c (finish_file): Push and pop timevar TV_VARCONST instead
+ of computing elapsed time explicitly.
+
+2000-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TREE_READONLY_DECL_P): Use DECL_P.
+ * init.c (decl_constant_value): Check TREE_READONLY_DECL_P.
+ * call.c (convert_like_real): Don't test TREE_READONLY_DECL_P
+ before calling decl_constant_value.
+ * class.c (check_bitfield_decl): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ (convert): Likewise.
+ * decl.c (compute_array_index_type): Likewise.
+ (build_enumerator): Likewise.
+ * decl2.c (check_cp_case_value): Likewise.
+ * pt.c (convert_nontype_argument): Likewise.
+ (tsubst): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+ (build_compound_expr): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_c_cast): Likewise.
+ (convert_for_assignment): Likewise.
+
+2000-04-26 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (finish_function): Don't play games with DECL_INLINE.
+
+2000-04-25 Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
+
+ * ir.texi: Correct typo.
+
+2000-04-25 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (grokdeclarator): Reject VLAs as members.
+
+2000-04-24 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * call.c (standard_conversion): Accept conversion between
+ COMPLEX_TYPEs.
+
+ * cvt.c (ocp_convert): Handle conversion to COMPLEX_TYPE.
+
+2000-04-24 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl2.c (finish_file): Remove double setup for accounting
+ compile time.
+
+2000-04-24 Robert Lipe <robertlipe@usa.net>
+
+ * cp-tree.h (lang_type): Member `language' now ENUM_BITFIELD.
+
+2000-04-23 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * new.cc (set_new_handler): Needs to be in std::.
+
+2000-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl): Remove pretty_function_p.
+ (DECL_PRETTY_FUNCTION_P): Use TREE_LANG_FLAG_0, not a bit in the
+ language-specific node.
+ * decl.c (cp_make_fname_decl): Use build_decl, not
+ build_lang_decl, to build the variables.
+ (grokvardecl): Don't call build_lang_decl for local variables in
+ templates.
+ (grokdeclarator): Don't call build_lang_decl for local type
+ declarations in templates.
+ * lex.c (retrofit_lang_decl): Use ggc_alloc_obj to allocated
+ zero'd memory, rather than calling memset.
+ * pt.c: Include hashtab.h.
+ (local_specializations): New variable.
+ (retrieve_local_specialization): Use it.
+ (register_local_specialization): Likewise.
+ (tsubst_decl): Don't assume local variables have
+ DECL_LANG_SPECIFIC.
+ (instantiate_decl): Set up local_specializations.
+ * Makefile.in (HTAB_H): New variable.
+
+2000-04-23 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (c_expand_asm_operands): Restore the original
+ contents of the output list.
+
+2000-04-22 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi: Document complex number representation.
+
+2000-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (init_rtti_processing): Set tinfo_var_id in new-abi.
+ (target_incomplete_p): New function.
+ (tinfo_base_init): Create comdat NTBS name variable.
+ (ptr_initializer): Add non_public parameter. Calculate it.
+ (ptmd_initializer): Likewise.
+ (synthesize_tinfo_var): Adjust. Emit incomplete class tinfo.
+ (create_real_tinfo_var): Add non_public parameter. Use it.
+ Push proxy into global namespace.
+ * inc/cxxabi.h (__pointer_type_info::incomplete_class_mask):
+ New enumeration.
+ * inc/typeinfo (type_info::before, type_info::operator==):
+ Compare __name addresses.
+
+ * tinfo2.cc: Remove new-abi builtins comment.
+
+2000-04-20 Jason Merrill <jason@casey.cygnus.com>
+
+ * typeck.c (build_x_function_call): Resolve an OFFSET_REF.
+
+ * call.c (joust): Exit early if we get the same function, too.
+
+ * decl2.c (key_method): Return NULL_TREE for template classes.
+ (import_export_class): Don't need to check for template classes.
+
+2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lex.c: Remove references to cccp.c.
+
+2000-04-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Remove const_memfunc and
+ volatile_memfunc. Add destructor_attr. Adjust dummy.
+ (DECL_DESTRUCTOR_P): Use destructor_attr.
+ (DECL_CONST_MEMFUNC_P): Reimplement.
+ (DECL_VOLATILE_MEMFUNC_P): Remove.
+ * class.c (finish_struct_methods): Use CLASSTYPE_DESTRUCTORS.
+ (overrides): Use DECL_DESTRUCTOR_P.
+ (check_for_override): Likewise.
+ * decl.c (start_function): Likewise.
+ * decl2.c (grokfclassfn): Likewise.
+ (check_classfn): Likewise.
+ (grok_function_init): Likewise.
+
+2000-04-17 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (grokfield): Issue error on illegal data member
+ declaration.
+
+2000-04-17 Mark P Mitchell <mark@codesourcery.com>
+
+ * method.c (make_thunk): Set DECL_CONTEXT for a THUNK_DECL.
+
+2000-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable_entry): Don't build thunks for type-info
+ functions.
+
+2000-04-16 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (decls_match): Allow a redeclaration of a builtin to
+ specify args while the builtin did not.
+
+2000-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (THUNK_DECL): Add to documentation.
+ * cp-tree.h (flag_huge_objects): Declare.
+ * class.c (modify_vtable_entry): Tidy.
+ (update_vtable_entry_for_fn): Split out from dfs_modify_vtables.
+ Calculate delta appropriately for the new ABI.
+ (dfs_modify_vtables): Use it.
+ (modify_all_vtables): Fix thinko in code to add overriding copies
+ of functions to primary vtables.
+ (build_clone): Fix typo in comment.
+ (clone_function_decl): Correct order of destructors in vtable.
+ (build_vbase_offset_vtbl_entries): Adjust comment.
+ (dfs_vcall_offset_queue_p): Remove.
+ (dfs_build_vcall_offset_vtbl_entries): Update BV_VCALL_INDEX.
+ (build_vcall_offset_vtbl_entries): Juse use dfs_skip_vbases.
+ (build_vtable_entry): Correct check for pure virtual functions.
+ Don't declare flag_huge_objects.
+ * decl.c (flag_huge_objects): Remove declaration.
+ * method.c (make_thunk): Tweak mangling for vcall offset thunks.
+ Use int_size_in_bytes.
+ (emit_thunk): Handle vcall offset thunks.
+
+2000-04-15 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl2.c (parse_time, varconst_time): Delete declarations.
+ (finish_file): Delete LINENO declaration.
+ START_TIME and THIS_TIME now long.
+
+2000-04-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_base_field): Reformat comment.
+
+ * inc/cxxabi.h (stddef.h): Comment inclusion.
+ (__base_class_info::__offset): Comment shift.
+
+2000-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (IDENTIFIER_CTOR_OR_DTOR_P): New macro.
+ (cp_tree_index): Add CPTI_PUSH_EXCEPTION_IDENTIFIER.
+ (cp_push_exception_identifier): New macro.
+ (DECL_COMPLETE_DESTRUCTOR_P): New macro.
+ (DECL_BASE_DESTRUCTOR_P): Likewise.
+ (DECL_DELETING_DESTRUCTOR_P): Likewise.
+ (get_vtbl_decl_for_binfo): Fix formatting.
+ (in_charge_arg_for_name): New macro.
+ (maybe_build_cleanup_and_delete): Remove declaration.
+ * call.c (build_field_call): Use IDENTIFIER_CTOR_OR_DTOR_P.
+ (in_charge_arg_for_name): New function.
+ (build_new_method_call): Use it. Handle cloned destructors.
+ (build_clone): Don't make the base constructor virtual.
+ Automatically defer generated functions.
+ (clone_function_decl): Handle destructors, too.
+ (clone_constructors_and_destructors): Likewise.
+ (create_vtable_ptr): Don't create a vtable entry for a cloned
+ function.
+ * decl.c (predefined_identifier): Add ctor_or_dtor_p.
+ (initialize_predefined_identifiers): Update appropriately.
+ (finish_destructor_body): Simplify.
+ (maybe_build_cleanup_and_delete): Remove.
+ * except.c (expand_throw): Handle new-ABI destructors.
+ * init.c (expand_cleanup_for_base): Use base_dtor_identifier.
+ (build_dtor_call): New function.
+ (build_delete): Use it. Simplify.
+ * optimize.c (maybe_clone_body): Handle destructors.
+ * search.c (lookup_field_queue_p): Use IDENTIFIER_CTOR_OR_DTOR_P.
+
+ * exception.cc (cleanup_fn): New typedef.
+ (CALL_CLEANUP): New macro.
+ (cp_eh_info): Use them.
+ (__cp_push_exception): Likewise.
+ (__cp_pop_exception): Likewise.
+
+2000-04-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Add CPTI_DTOR_IDENTIFIER.
+ (complete_dtor_identifier): New macro.
+ (CLASSTYPE_FIRST_CONVERSION): Remove.
+ (CLASSTYPE_CONSTRUCTOR_SLOT): New macro.
+ (CLASSTYPE_DESTRUCTOR_SLOT): Likewise.
+ (CLASSTYPE_FIRST_CONVERSION_SLOT): Likewise.
+ (CLASSTYPE_CONSTRUCTORS): Likewise.
+ (CLASSTYPE_DESTRUCTORS): Likewise.
+ (lang_decl): Add cloned_function.
+ (DECL_COMPLETE_CONSTRUCTOR_P): New macro.
+ (DECL_BASE_CONSTRUCTOR_P): Likewise.
+ (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P): Likewise.
+ (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P): Likewise.
+ (DECL_CLONED_FUNCTION_P): Likewise.
+ (DECL_CLONED_FUNCTION): Likewise.
+ (clone_function_decl): Declare.
+ (maybe_clone_body): Likewise.
+ * call.c (build_user_type_conversion_1): Call complete object
+ constructors in the new ABI.
+ (build_new_method_call): Don't add in-charge parameters under the
+ new ABI.
+ * class.c (add_method): Use DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P,
+ DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P, CLASSTYPE_CONSTRUCTOR_SLOT, and
+ CLASSTYPE_DESTRUCTOR_SLOT.
+ (build_clone): New function.
+ (clone_function_decl): Likewise.
+ (clone_constructors_and_destructors): Likewise.
+ (check_bases_and_members): Use it.
+ * decl.c (iniitialize_predefined_identifiers): Initialize
+ complete_dtor_identifier.
+ (finish_function): Don't add extra code to a clone.
+ (lang_mark_tree): Mark cloned_function.
+ * decl2.c (mark_used): Don't bother trying to instantiate things
+ we synthesized.
+ * dump.c (dequeue_and_dump): Don't dump CP_DECL_CONTEXT twice.
+ * method.c (set_mangled_name_for_decl): Don't treat clones as
+ constructors.
+ (synthesize_method): Sythesize cloned functions, not the clones.
+ * optimize.c (inline_data): Update comment on ret_label.
+ (remap_block): Don't assume DECL_INITIAL exists.
+ (copy_body_r): Allow ret_label to be NULL.
+ (maybe_clone_body): Define.
+ * pt.c (tsubst_decl): Handle clones.
+ (instantiate_clone): New function.
+ (instantiate_template): Use it.
+ (set_mangled_name_for_template_decl): Don't treat clones as
+ constructors.
+ * search.c (lookup_fnfields_1): Use CLASSTYPE_CONSTRUCTOR_SLOT,
+ CLASSTYPE_DESTRUCTOR_SLOT, and CLASSTYPE_FIRST_CONVERSION_SLOT.
+ * semantics.c (expand_body): Clone function bodies as necessary.
+
+ * optimize.c (remap_decl): Avoid sharing structure for arrays
+ whose size is only known at run-time.
+ * tree.c (copy_tree_r): Don't copy PARM_DECLs.
+
+ * cp-tree.h (lang_decl_flags): Rename constructor_for_vbase_attr
+ to has_in_charge_parm_p.
+ (DECL_CONSTRUCTOR_FOR_VBASE_P): Rename to ...
+ (DECL_HAS_IN_CHARGE_PARM_P): ... this.
+ (DECL_COPY_CONSTRUCTOR_P): New macro.
+ * call.c (add_function_candidate): Use DECL_HAS_IN_CHARGE_PARM_P.
+ (build_user_type_conversion_1): Likewise.
+ (convert_like_real): Likewise.
+ (build_over_call): Likeiwse. Use DECL_COPY_CONSTRUCTOR_P.
+ * decl.c (grokdeclarator): Use DECL_HAS_IN_CHARGE_PARM_P.
+ (copy_args_p): Likewise.
+ (grok_ctor_properties): Likewise.
+ (start_function): Likewise.
+ * decl2.c (maybe_retrofit_in_charge): Likewise. Set it.
+ * error.c (dump_function_decl): Use DECL_HAS_IN_CHARGE_PARM_P.
+ * init.c (emit_base_init): Use DECL_COPY_CONSTRUCTOR_P.
+ * method.c (do_build_copy_constructor): Use
+ DECL_HAS_IN_CHARGE_PARM_P.
+ (synthesize_method): Likewise.
+ * pt.c (instantiate_template): Remove goto.
+ * tree.c (build_cplus_method_type): Remove mention of obstacks in
+ comment.
+
+ * cp-tre.h (finish_function): Change prototype.
+ * decl.c (end_cleanup_fn): Adjust caller.
+ (finish_function): Take only one parameter.
+ * decl2.c (finish_objects): Adjust caller.
+ (finish_static_storage_duration_function): Likewise.
+ * method.c (emit_thunk): Likewise.
+ * parse.y: Likewise.
+ * parse.c: Regenerated.
+ * pt.c (instantiate_decl): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Likewise.
+ * semantics.c (expand_body): Likewise.
+
+ * cp-tree.h (copy_decl): New function.
+ * class.c (finish_struct_1): Use it.
+ * lex.c (copy_decl): Define it.
+ * pt.c (tsubst_decl): Likewise.
+ * tree.c (copy_template_template_parm): Likewise.
+
+ * cp-tree.h (lang_type): Remove has_nonpublic_ctor and
+ has_nonpublic_assign_ref.
+ (TYPE_HAS_NONPUBLIC_CTOR): Don't declare.
+ (TYPE_HAS_NONPUBLIC_ASSIGN_REF): Likewise.
+ * class.c (finish_struct_methods): Don't set
+ TYPE_HAS_NONPUBLIC_CTOR or TYPE_HAS_NONPUBLIC_ASSIGN_REF.
+ (interface_only): Don't declare.
+ (interface_unknown): Likewise.
+
+2000-04-11 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * tree.h (HAVE_TEMPLATES): Remove definition.
+ * lang-options.h (-fthis-is-variable): Remove documentation.
+
+2000-04-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * class.c (instantiate_type): Handle object-relative template-id.
+
+ * semantics.c (finish_expr_stmt): Call convert_to_void here.
+ * decl.c (cplus_expand_expr_stmt): Not here.
+
+ * rtti.c (build_dynamic_cast_1): Call non_lvalue.
+ Initialize exprtype earlier.
+
+ * parse.y (fn.def1): Check for defining types in return types.
+
+ * decl.c (check_tag_decl): Notice extra fundamental types.
+ Diagnose empty decls in classes, too.
+
+ * decl.c (grokdeclarator): Don't override an anonymous name if no
+ declarator was given.
+
+ * cvt.c (convert_to_void): Call resolve_offset_ref.
+
+ * typeck.c (build_x_function_call): Abort if we get an OFFSET_REF.
+
+ * decl2.c (decl_namespace): Handle getting a type.
+
+ * typeck.c (build_c_cast): Re-enable warning for cast between
+ pointer and integer of different size.
+
+2000-04-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h (__pointer_type_info): Add restrict and
+ incomplete flags.
+ (__pointer_type_info::__pointer_catch): New virtual function.
+ (__pointer_to_member_type_info): Derive from
+ __pointer_type_info. Adjust.
+ (__pointer_to_member_type_info::__do_catch): Remove.
+ (__pointer_to_member_type_info::__is_pointer_p): Declare.
+ (__pointer_to_member_type_info::__pointer_catch): Declare.
+ * rtti.c (qualifier_flags): Add restrict flag.
+ (ptmd_initializer): Reorder members.
+ (create_tinfo_types): Expand comments. Reorder
+ ptmd_desc_type_node members.
+ * tinfo2.cc (__pointer_to_member_type_info::__is_pointer_p):
+ Implement.
+ (__pointer_type_info::__do_catch): Move specific code into
+ __pointer_catch. Call it.
+ (__pointer_type_info::__pointer_catch): Non-pointer-to-member
+ specific catch checking. Fix void conversion check.
+ (__pointer_to_member_type_info::__do_catch): Remove.
+ (__pointer_to_member_type_info::__pointer_catch): Implement.
+
+2000-04-10 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * lex.c (init_parse): Remove traces of classof and headof.
+ * decl2.c (flag_operator_names): Default to 1.
+ (lang_decode_option): Do not set it for -ansi.
+
+2000-04-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct lang_decl): Remove main_decl_variant.
+ (DECL_MAIN_VARIANT): Remove.
+ * decl.c (duplicate_decls): Don't set it.
+ (start_function): Likewise.
+ (lang_mark_tree): Don't mark it.
+ * decl2.c (defer_fn): Don't use it.
+ * lex.c (retrofit_lang_decl): Don't set it.
+ * pt.c (tsubst_decl): Likewise.
+ * ptree.c (print_lang_decl): Don't print it.
+ * typeck.c (mark_addressable): Don't use it.
+
+2000-04-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.cc: Include <new> and <exception>.
+ (__cxa_vec_ctor): Use __cxa_vec_dtor for cleanup.
+ (__cxa_vec_dtor): Catch dtor exceptions, and rethrow or
+ terminate.
+ (__cxa_vec_delete): Catch dtor exceptions.
+
+2000-04-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ Prepend __ to implementation defined names.
+ * inc/typeinfo (type_info): Rename _name to __name.
+ (type_info::type_info): Rename parameter.
+ (type_info::operator==, type_info::operator!=,
+ type_info::before): Likewise.
+ (type_info::is_pointer_p, type_info::is_function_p,
+ type_info::do_catch, type_info::do_upcast): Prepend __. Rename
+ parameters.
+ * inc/cxxabi.h
+ (__fundamental_type_info::__fundamental_type_info) Rename parameters.
+ (__pointer_type_info::__pointer_type_info): Likewise.
+ (__pointer_type_info::is_pointer_p,
+ __pointer_type_info::do_catch): Prepend __. Rename parameters.
+ (__array_type_info::__array_type_info): Rename parameters.
+ (__function_type_info::__function_type_info): Likewise.
+ (__function_type_info::is_function_p): Prepend __.
+ (__enum_type_info::__enum_type_info): Rename parameters.
+ (__pointer_to_member_type_info::__pointer_to_member_type_info):
+ Likewise.
+ (__pointer_to_member_type_info::do_catch): Prepend __. Rename
+ parameters.
+ (__base_class_info::is_virtual_p, is_public_p, offset): Prepend __.
+ (__class_type_info::__class_type_info): Rename parameters.
+ (__class_type_info::sub_kind): Prepend __. Adjust member names.
+ (__class_type_info::upcast_result,
+ __class_type_info::dyncast_result): Prepend __. Move definition
+ into tinfo.cc.
+ (__class_type_info::do_upcast, __class_type_info::do_catch,
+ __class_type_info::find_public_src,
+ __class_type_info::do_dyncast,
+ __class_type_info::do_find_public_src): Prepend __. Rename
+ parameters.
+ (__si_class_type_info::__si_class_type_info): Rename parameters.
+ (__si_class_type_info::do_upcast, __si_class_type_info::do_dyncast,
+ __si_class_type_info::do_find_public_src): Prepent __. Rename
+ parameters.
+ (__vmi_class_type_info::__vmi_class_type_info): Rename parameters.
+ (__vmi_class_type_info::do_upcast, __vmi_class_type_info::do_dyncast,
+ __vmi_class_type_info::do_find_public_src): Prepent __. Rename
+ parameters.
+ (__dynamic_cast): Rename parameters.
+ * tinfo.cc (type_info::is_pointer_p, type_info::is_function_p,
+ type_info::do_catch, type_info::do_upcast): Prepend __.
+ (contained_p, public_p, virtual_p, contained_public_p,
+ contained_nonpublic_p, contained_nonvirtual_p): Adjust.
+ (__class_type_info::do_catch,
+ __class_type_info::do_upcast): Prepend __. Adjust.
+ (__class_type_info::__upcast_result,
+ __class_type_info::__dyncast_result): Move from inc/cxxabi.h.
+ Adjust.
+ (__class_type_info::find_public_src): Prepend __. Adjust.
+ (__class_type_info::do_find_public_src,
+ __si_class_type_info::do_find_public_src,
+ __vmi_class_type_info::do_find_public_src): Likewise.
+ (__class_type_info::do_dyncast,
+ __si_class_type_info::do_dyncast,
+ __vmi_class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_upcast,
+ __si_class_type_info::do_upcast,
+ __vmi_class_type_info::do_upcast): Likewise.
+ (__dynamic_cast): Adjust.
+ * tinfo2.cc (__pointer_type_info::is_pointer_p): Prepend __.
+ (__function_type_info::is_function_p): Likewise.
+ (__pointer_type_info::do_catch): Likewise. Adjust.
+ (__pointer_to_member_type_info::do_catch): Likewise. Adjust.
+ (__throw_type_match_rtti_2): Adjust.
+ (__is_pointer): Adjust.
+
+2000-04-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Add CPTI_COMPLETE_CTOR_IDENTIFIER.
+ (complete_ctor_identifier): New macro.
+ (special_function_kind): Add sfk_copy_constructor and
+ sfk_assignment_operator.
+ (LOOKUP_HAS_IN_CHARGE): Remove.
+ (cons_up_default_function): Rename to ...
+ (implicitly_declare_fn): ... this.
+ * call.c (build_new_method_call): Add in-charge parameters for
+ constructors here.
+ * class.c (add_implicitly_declared_members): Change parameter name
+ from cant_have_assignment to cant_have_const_assignment.
+ Replace calls to cons_up_default_function to implicitly_declare_fn.
+ * cvt.c (ocp_convert): Use complete_ctor_identifier.
+ * decl.c (initialize_predefined_identifiers): Initialize it.
+ (start_function): Use DECL_CONSTRUCTOR_FOR_VBASE_P instead of
+ complex expression.
+ * init.c (expand_default_init): Don't calculate the in-charge
+ parameter here.
+ (build_new_1): Likewise.
+ * lex.c (cons_up_default_function): Move to method.c.
+ * method.c (synthesize_method): Use DECL_DESTRUCTOR_P.
+ (implicitly_declare_fn): New function.
+ * typeck.c (build_static_cast): Use complete_ctor_identifier.
+ (build_modify_expr): Likewise.
+ * typeck2.c (build_functional_cast): Likewise.
+
+ Under the new ABI, constructors don't return `this'.
+ * cp-tree.h (warn_reorder): Declare.
+ (special_function_kind): New enum.
+ (global_base_init_list): Remove declaration.
+ (emit_base_init): Don't return a value.
+ (check_base_init): Don't declare.
+ (is_aggr_typedef): Likewise.
+ * decl.c (check_special_function_return_type): New function.
+ (return_types): Remove.
+ (grokdeclarator): Use check_special_function_return_type.
+ (start_function): Don't initialize ctor_label under the new ABI.
+ (finish_construtor_body): Don't create a corresponding LABEL_STMT.
+ * init.c (begin_init_stmts): Move to top of file.
+ (finish_init_stmts): Likewise.
+ (warn_reorder): Don't declare.
+ (emit_base_init): Don't create a STMT_EXPR here. Don't return a
+ value.
+ (check_base_init): Remove.
+ (is_aggr_typedef): Likewise.
+ (build_new_1): Don't use the return value of a constructor.
+ * semantics.c (setup_vtbl_ptr): Don't use the return value
+ of emit_base_init.
+ * typeck.c (check_return_expr): Don't magically convert return
+ statements into `return this' in constructors under the new ABI.
+
+ * cp-tree.h (cp_tree_index): Add CPTI_BASE_CTOR_IDENTIFIER,
+ CPTI_BASE_DTOR_IDENTIFIER, and CPTI_DELETING_DTOR_IDENTIFIER.
+ (base_ctor_identifier): New macro.
+ (base_dtor_identifier): Likewise.
+ (deleting_dtor_identifier): Likewise.
+ * decl.c: Don't include obstack.h.
+ (obstack_chunk_alloc): Don't define.
+ (obstack_chunk_free): Likewise.
+ (struct predefined_identifier): New type.
+ (initialize_predefined_identifiers): New function.
+ (init_decl_processing): Use it.
+ (debug_temp_inits): Remove.
+ (start_method): Don't call preserve_data.
+ (hack_incomplete_structures): Update comment.
+ * init.c (init_init_processing): Don't initialize
+ nelts_identifier.
+ (build_offset_rf): Remove dead code.
+ (build_delete): Use CLASSTYPE_N_BASECLASSES.
+ * search.c (init_search_processing): Don't initialize
+ vptr_identifier.
+
+2000-04-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * typeck.c (build_binary_op): Call `tree_expr_nonnegative_p' to elide
+ some sign_compare warnings.
+
+2000-04-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ Rename abi::__vmi_class_type_info members.
+ * inc/cxxabi.h (__vmi_class_type_info): Rename details, n_bases,
+ base_list, detail_masks members to vmi_flags, vmi_base_count,
+ vmi_bases and vmi_flags_masks respectively.
+ (__vmi_class_type_info::vmi_flags_masks): Rename
+ details_unknown_mask to flags_unknown_mask.
+ * tinfo.cc (__class_type_info::do_upcast): Adjust.
+ (__vmi_class_type_info::do_find_public_src): Adjust.
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Adjust.
+
+2000-04-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.cc (convert_to_base): New function.
+ (get_vbase_offset): Remove. Move into convert_to_base.
+ (__vmi_class_type_info::do_find_public_src): Adjust.
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Adjust.
+
+2000-04-06 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo.cc (operator=): Use __builtin_strcmp.
+ * tinfo2.cc (before): Likewise.
+
+2000-04-06 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Rename saved_inline to deferred.
+ (DECL_SAVED_INLINE): Rename to ...
+ (DECL_DEFERRED_FN): ... this.
+ (in_function_p): Remove declaration.
+ (mark_inline_for_output): Rename to ...
+ (defer_fn): ... this.
+ * decl.c (finish_function): Adjust call to mark_inline_for_output.
+ (in_function_p): Remove definition.
+ * decl2.c (saved_inlines): Rename to ...
+ (deferred_fns): ... this.
+ (saved_inlines_used): Rename to ...
+ (deferred_fns_used): ... this.
+ (mark_inline_for_output): Rename to ...
+ (defer_fn): ... this.
+ (finish_file): Adjust accordingly.
+ (init_decl2): Likewise.
+ * lex.c (cons_up_default_function): Likewise.
+ * pt.c (mark_decl_instantiated): Likewise.
+ (instantiate_decl): Don't set DECL_DEFER_OUTPUT under any
+ circumstances.
+ * rtti.c (get_tinfo_decl): Adjust call to mark_inline_for_output.
+ * semantics.c (expand_body): Defer more functions.
+
+2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.cc: New file.
+ * Make-lang.in (CXX_LIB2FUNCS): Add it.
+ (vec.o): Build it.
+ * inc/cxxabi.h (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
+ __cxa_vec_delete): Declare.
+
+2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (dfs_class_hint_mark): New static function.
+ (dfs_class_hint_unmark): New static function.
+ (class_hint_flags): Use them.
+
+2000-04-05 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * decl2.c: Make flag_honor_std dependent on ENABLE_STD_NAMESPACE.
+
+2000-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (instantiate_decl): Change prototype.
+ * decl2.c (mark_used): Adjust call.
+ * optimize.c (inlinable_function_p): Adjust handling of templates.
+ * pt.c (do_decl_instantiation): Adjust call to instantiate_decl.
+ (do_type_instantiation): Likewise.
+ (instantiate_decl): Defer more templates.
+ (instantiate_pending_templates): Adjust logic to handle inline
+ friend functions.
+
+ * Makefile.in (GGC_H): New variable. Use it throughout in place
+ of ggc.h.
+
+ * call.c: Don't include obstack.h. Include ggc.h.
+ (obstack_chunk_alloc): Don't define.
+ (obstack_chunk_free): Likewise.
+ (add_candidate): Allocate the z_candidate with ggc_alloc_obj.
+ * decl.c (push_switch): Use xmalloc to allocate the cp_switch.
+ (pop_switch): Free it.
+
+ * decl2.c (grokclassfn): Set TREE_READONLY for PARM_DECLs.
+
+ * dump.c (dequeue_and_dump): Don't try to print the bit_position
+ if we don't have a DECL_FIELD_OFFSET.
+
+Wed Apr 5 15:12:18 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * optimize.c (calls_setjmp_r): Use setjmp_call_p instead of
+ special_function_p.
+
+2000-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cfns.gperf (hash, libc_name_p): Prototype.
+
+ * rtti.c (build_dynamic_cast_1): Constification.
+
+ * search.c (dfs_debug_unmarkedp, dfs_debug_mark): Unhide prototypes.
+
+ * semantics.c (deferred_type_access_control): Prototype.
+
+2000-04-04 Mark Mitchell <mark@codesourcery.com>
+
+ Correct many new ABI issues regarding vbase and vcall offset
+ layout.
+ * cp-tree.h (BINFO_VTABLE): Document.
+ (struct lang_type): Tweak formatting.
+ (BINFO_PRIMARY_BINFO): Add to documentation.
+ (CLASSTYPE_VSIZE): Fix typo in comment.
+ (CLASSTYPE_VBASECLASSES): Update documentation.
+ (BINFO_VBASE_MARKED): Remove.
+ (SET_BINFO_VBASE_MARKED): Likewise.
+ (CLEAR_BINFO_VBASE_MARKED): Likewise.
+ (BINFO_FIELDS_MARKED): Remove.
+ (SET_BINFO_FIELDS_MARKED): Likewise.
+ (CLEAR_BINFO_FIELDS_MARKED): Likewise.
+ (enum access_kind): New enumeration.
+ (num_extra_vtbl_entries): Remove declaration.
+ (size_extra_vtbl_entries): Likewise.
+ (get_vtbl_decl_for_binfo): New function.
+ (dfs_vbase_unmark): Remove declaration.
+ (mark_primary_bases): Likewise.
+ * class.c (SAME_FN): Remove.
+ (struct vcall_offset_data_s): Move definition.
+ (build_vbase_pointer): Use `build', not `build_binary_op', to
+ access the vbase pointer under the new ABI.
+ (build_vtable_entry_ref): Use get_vtbl_decl_for_binfo.
+ (build_primary_vtable): Likewise.
+ (dfs_mark_primary_bases): Move here from search.c.
+ (mark_primary_bases): Likewise.
+ (determine_primary_bases): Under the new ABI, don't make a base
+ class a primary base just because we don't yet have any virtual
+ functions.
+ (layout_vtable_decl): Use get_vtbl_decl_for_binfo.
+ (num_vfun_entries): Remove.
+ (dfs_count_virtuals): Likewise.
+ (num_extra_vtbl_entries): Likewise.
+ (size_extra_vtbl_entries): Likewise.
+ (layout_virtual_bases): Iterate in inheritance graph order under
+ the new ABI.
+ (finish_struct_1): Use TYPE_VFIELD, not CLASSTYPE_VSIZE, to
+ indicate that a vfield is present.
+ (init_class_processing): Initialize access_public_node, etc., from
+ ak_public, etc.
+ (get_vtbl_decl_for_binfo): New function.
+ (dump_class_hierarchy_r): Likewise.
+ (dump_class_hierarchy): Use it.
+ (finish_vtbls): Build the vtbls in inheritance graph order.
+ (dfs_finish_vtbls): Adjust call to build_vtbl_initializer.
+ (initialize_vtable): Use get_vtbl_decl_for_binfo.
+ (accumulate_vtbl_inits): Add comments explaining why a pre-order
+ walk is required.
+ (dfs_accumulate_vtbl_inits): Set BINFO_VTABLE to the location
+ where the vptr points, even for primary vtables.
+ (build_vtbl_initializer): Adjust handling of vbase and vcall
+ offsets.
+ (build_vcall_and_vbase_vtable_entries): New function.
+ (dfs_build_vbase_offset_vtbl_entries): Remove.
+ (build_vbase_offset_vtbl_entries): Reimplement.
+ (dfs_build_vcall_offset_vtbl_entries): Don't include virtuals that
+ were already handled in a primary base class vtable.
+ (build_vcall_offset_vtbl_entries): Adjust.
+ (build_rtti_vtbl_entries): Adjust.
+ * decl2.c (output_vtable_inherit): Use get_vtbl_decl_for_binfo.
+ * init.c (expand_virtual_init): Simplify.
+ * repo.c (repo_get_id): Use get_vtbl_decl_for_binfo.
+ * rtti.c (create_pseudo_type_info): Adjust calculation of vptr.
+ * search.c (BINFO_ACCESS): New macro.
+ (SET_BINFO_ACCESS): Likewise.
+ (dfs_access_in_type): Manipulate access_kinds, not access nodes.
+ (access_in_type): Likewise.
+ (dfs_accessible_p): Likewise.
+ (protected_accessible_p): Likewise.
+ (lookup_fnfields_1): Adjust documentation.
+ (dfs_mark_primary_bases): Move to class.c
+ (mark_primary_bases): Likewise.
+ (dfs_vbase_unmark): Remove.
+ (virtual_context): Use BINFO_FOR_VBASE.
+ (dfs_get_vbase_types): Simplify.
+ (dfs_build_inheritance_graph_order): New function.
+ (get_vbase_types): Use it.
+ * tree.c (debug_binfo): Use get_vtbl_decl_for_binfo.
+
+ * tinfo.cc (get_vbase_offset): New function.
+ (__vmi_class_type_info::do_find_public_src): Use it.
+ (__vmi_class_type_info::do_dyncast): Likewise.
+ (__vmi_class_type_info::do_upcast): Likewise.
+
+2000-04-03 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Pass -fno-show-column to the preprocessor.
+
+2000-03-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (class_hint_flags): Rename flags.
+ (class_initializer): Remove flags.
+ (synthesize_tinfo_var): Combine offset and flags. Add flags
+ for __vmi_class_type_info.
+ (create_tinfo_types): Remove flags from __class_type_info and
+ __si_class_type_info. Merge flags and offset from
+ base_class_type_info.
+ * inc/cxxabi.h (__base_class_info): Merge offset and vmi_flags.
+ (__base_class_info::is_virtual_p): Adjust.
+ (__base_class_info::is_public_p): Adjust.
+ (__base_class_info::offset): New accessor.
+ (__class_type_info::details): Remove member.
+ (__class_type_info::__class_type_info): Lose details.
+ (__class_type_info::detail_masks): Remove.
+ (__si_class_type_info::__si_class_type_info): Lose details.
+ (__vmi_class_type_info::details): New member.
+ (__vmi_class_type_info::__vmi_class_type_info): Adjust.
+ (__vmi_class_type_info::detail_masks): New member.
+ * tinfo.cc (__class_type_info::do_upcast): Initialize result
+ with unknown_details_mask.
+ (__vmi_class_type_info::do_find_public_src): Adjust
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Set result details, if
+ needed. Adjust.
+ (__dynamic_cast): Temporarily #if out optimization.
+
+2000-03-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (get_tinfo_decl): Mark used.
+ (emit_tinfo_decl): Don't optimize polymorphic type_info. Only
+ mark as dealt with, if we output it.
+
+2000-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c: Reorganize to put virtual function table initialization
+ machinery at the end of the file.
+
+2000-03-28 Jason Merrill <jason@casey.cygnus.com>
+
+ * class.c (finish_struct): Use bitsize_zero_node.
+ * pt.c (instantiate_class_template): Likewise.
+
+2000-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ Put RTTI entries at negative offsets in new ABI.
+ * class.c (dfs_build_vbase_offset_vtbl_entries): Put the first
+ vbase offset at index -3, not -1.
+ (build_vtabe_offset_vtbl_entries): Use unmarked_vtable_pathp, not
+ dfs_vtable_path_unmarked_real_bases_queue_p to walk bases.
+ (dfs_build_vcall_offset_vtbl_entries): Don't use skip_rtti_stuff.
+ (build_rtti_vtbl_entries): New function.
+ (set_rtti_entry): Remove.
+ (build_primary_vtable): Don't use it.
+ (build_secondary_vtable): Likewise.
+ (start_vtable): Remove.
+ (first_vfun_index): New function.
+ (set_vindex): Likewise.
+ (add_virtual_function): Don't call start_vtable. Do call
+ set_vindex.
+ (set_primary_base): Rename parameter.
+ (determine_primary_base): Likewise.
+ (num_vfun_entries): Don't use skip_rtti_stuff.
+ (num_extra_vtbl_entries): Include RTTI information.
+ (build_vtbl_initializer): Use build_rtti_vtbl_entries.
+ (skip_rtti_stuff): Remove.
+ (dfs_modify_vtables): Don't use it.
+ (modify_all_vtables): Don't use start_vtable. Do use set_vindex.
+ (layout_nonempty_base_or_field): Update size handling.
+ (create_vtable_ptr): Tweak.
+ (layout_class_type): Adjust parameter names.
+ (finish_struct_1): Simplify.
+ * cp-tree.h (CLASSTYPE_VSIZE): Tweak documentation.
+ (skip_rtti_stuff): Remove.
+ (first_vfun_index): New function.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
+ (dfs_vtable_path_marked_real_bases_queue_p): Remove.
+ (marked_vtable_pathp): Declare.
+ (unmarked_vtable_pathp): Likewise.
+ * error.c (dump_expr): Use first_vfun_index to calculate vtable
+ offsets.
+ * rtti.c (build_headof): Look for RTTI at negative offsets.
+ (get_tinfo_decl_dynamic): Likewise.
+ (tinfo_base_init): Don't take the address of the TINFO_VTABLE_DECL
+ here.
+ (create_pseudo_type_info): Do it here instead. Adjust so that
+ vptr points at first virtual function.
+ * search.c (marked_vtable_pathp): Make it global.
+ (unmarked_vtable_pathp): Likewise.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
+ (dfs_vtable_path_marked_real_bases_queue_p): Likewise.
+ (dfs_get_pure_virtuals): Don't use skip_rtti_stuff.
+ (get_pure_virtuals): Likewise.
+ (expand_upcast_fixups): Likewise.
+ * tree.c (debug_binfo): Likewise.
+ * tinfo.cc (__dynamic_cast): Look for vtable_prefix at appropriate
+ negative offset.
+
+2000-03-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (check_field_decl): Fix typo.
+ (build_vtbl_or_vbase_field): Don't clear DECL_SAVED_INSNS.
+ (check_methods): Likewise.
+ (check_field_decls): Likewise.
+ Use DECL_CONTEXT, not DECL_FIELD_CONTEXT.
+ * cp-tree.h (DECL_SHADOWED_FOR_VAR, DECL_TEMPLATE_RESULT):
+ Use DECL_RESULT_FLD, not DECL_RESULT.
+ * decl.c (xref_tag): Use DECL_TEMPLATE_RESULT.
+ * lex.c (identifier_type): Likewise.
+ * pt.c (determine_specialization, lookup_template_class): Likewise.
+ (tsubst_friend_function, tsubst_decl, instantiate_template): Likewise.
+ (resolve_overloaded_unification, more_specialized): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+ * typeck.c (build_x_function_call): Likewise.
+
+2000-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_empty_base): Handle empty bases with non-byte
+ alignment.
+ (build_base_field): Likewise.
+ (layout_virtual_bases): Likewise.
+
+ * class.c (finish_struct_1): Fix typo in this change:
+
+ Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+2000-03-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokdeclarator): Count partial specializations when
+ keeping track of how many template classes have been seen.
+
+ * dump.c (dequeue_and_dump): Dump DECL_TEMPLATE_RESULT.
+
+2000-03-25 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_vbase_pointer_fields): layout_field now place_field.
+ (get_vfield_offset): Use byte_position.
+ (set_rtti_entry): Set OFFSET to ssizetype zero.
+ (get_binfo_offset_as_int): Deleted.
+ (dfs_record_base_offsets): Use tree_low_cst.
+ (dfs_search_base_offsets): Likewise.
+ (layout_nonempty_base_or_field): Reflect changes in RLI format
+ and call byte_position.
+ (layout_empty_base): Convert offset to ssizetype.
+ (build_base_field): use rli_size_unit_so_far.
+ (dfs_propagate_binfo_offsets): Do computation in proper type.
+ (layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
+ (layout_class_type): Reflect changes in RLI names and fields.
+ (finish_struct_1): Set DECL_FIELD_OFFSET.
+ * dump.c (dequeue_and_dump): Call bit_position.
+ * expr.c (cplus_expand_constant): Use byte_position.
+ * rtti.c (expand_class_desc): Use bitsize_one_node.
+ * typeck.c (build_component_addr): Use byte_position and don't
+ special case for zero offset.
+
+2000-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (vtype_decl_p): Use TYPE_POLYMORPHIC_P.
+
+ * rtti.c (get_tinfo_decl): Set comdat linkage on new-abi
+ tinfo object.
+ (emit_tinfo_decl): Only emit polymorphic tinfo's when emitting
+ vtable.
+
+2000-03-20 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * call.c (check_dtor_name, build_new_method_call): Use TYPE_P and
+ DECL_P macros.
+ * decl.c (push_class_binding, poplevel, pushtag, lookup_namespace_name,
+ make_typename_type, check_initializer, cp_finish_decl,
+ xref_tag): Likewise.
+ * decl2.c (grokfield, build_expr_from_tree, build_expr_from_tree,
+ decl_namespace, arg_assoc_template_arg, arg_assoc,
+ validate_nonmember_using_decl, do_class_using_decl): Likewise.
+ * error.c (dump_template_argument, dump_expr, cp_file_of, cp_line_of,
+ args_to_string): Likewise.
+ * friend.c (is_friend): Likewise.
+ * lex.c (note_got_semicolon, note_list_got_semicolon,
+ is_global): Likewise.
+ * method.c (build_overload_nested_name, build_overload_value,
+ build_qualified_name, build_qualified_name, hack_identifier): Likewise.
+ * parse.y (typename_sub, typename_sub1): Likewise.
+ * pt.c (push_inline_template_parms_recursive, check_template_shadow,
+ process_partial_specialization, convert_template_argument,
+ template_args_equal, add_pending_template, lookup_template_class,
+ for_each_template_parm_r, maybe_fold_nontype_arg,
+ tsubst, instantiate_template, type_unification_real, unify,
+ instantiate_pending_templates, set_mangled_name_for_template_decl):
+ Likewise.
+ * repo.c (repo_get_id, repo_template_used): Likewise.
+ * search.c (lookup_field_1): Likewise.
+ * tree.c (walk_tree, get_type_decl, cp_tree_equal, member_p): Likewise.
+ * xref.c (classname): Likewise.
+
+2000-03-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BINFO_FOR_VBASE): Adjust documentation.
+ (CANONICAL_BINFO): New macro.
+ (BINFO_NEW_VTABLE_MARKED): Use it.
+ (SET_BINFO_NEW_VTABLE_MARKED): Likewise.
+ (CLEAR_BINFO_NEW_VTABLE_MARKED): Likewise.
+ * class.c (dfs_build_vbase_offset_vtbl_entries): Use BINFO_TYPE,
+ not TREE_TYPE.
+ (build_primary_vtable): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ (build_secondary_vtable): Likewise.
+ (dfs_finish_vtbls): Likewise.
+ (dfs_accumulate_vtbl_inits): Likewise.
+ (accumulate_vtbl_inits): New function.
+ (finish_vtbls): Make sure that virtual bases come after
+ non-virtual bases in the vtable group.
+ (record_base_offsets): Don't save and restore TREE_VIA_VIRTUAL.
+ (finish_struct_1): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ * search.c (struct vbase_info): Move definition.
+ (marked_new_vtable_p): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ (unmarked_new_vtable_p): Likewise.
+ (dfs_mark_vtable_path): Remove.
+ (dfs_mark_new_vtable): Remove.
+ (dfs_unmark_new_vtable): Likewise.
+ (dfs_clear_search_slot): Likewise.
+ (dfs_find_vbases): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ (dfs_clear_vbase_slots): Likewise.
+ (init_vbase_pointers): LIkewise.
+
+2000-03-22 Jason Merrill <jason@casey.cygnus.com>
+
+ * typeck.c (type_after_usual_arithmetic_conversions): Prefer a
+ SIZETYPE to a non-SIZETYPE.
+
+2000-03-21 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_virtual_bases): Adjust names in conditionally
+ compiled code.
+
+ * class.c (record_base_offsets): New function.
+ (layout_conflict_p): Likewise.
+ (layout_nonempty_base_or_field): Use it.
+ (layout_empty_base): New function.
+ (build_base_field): Use it.
+ (build_base_fields): Update comment.
+ (layout_virtual_bases): Fold in a little code form
+ layout_basetypes. Use layout_empty_base.
+ (layout_basetypes): Remove.
+ (end_of_class): New function.
+ (layout_class_type): Use it. Adjust.
+
+ * cp-tree.h (CLASSTYPE_VBASECLASSES): Fix typo in comment.
+ (fntype_p): Remove.
+ * search.c (dfs_skip_nonprimary_vbases_unmarkedp): Fix typo in
+ comment.
+ (dfs_skip_nonprimary_vbases_markedp): Likewise.
+ * typeck.c (fntype_p): Remove.
+
+ * cp-tree.h (TI_SPEC_INFO): Remove.
+ (CLASSTYPE_TI_SPEC_INFO): Likewise.
+ * pt.c (process_partial_specialization): Likewise.
+
+ * class.c (build_base_field): Fix thinko in computation of binfo
+ offsets.
+
+ * tree.c (mark_local_for_remap_p): Mark variables declared in
+ TARGET_EXPRs as well.
+
+2000-03-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (require_complete_type, complete_type,
+ complete_type_or_else, c_sizeof, c_sizeof_nowarn,
+ build_array_ref, convert_arguments, pointer_diff,
+ build_x_unary_op, build_unary_op, build_c_cast,
+ build_modify_expr): Use COMPLETE_TYPE_P etc.
+ * call.c (is_complete, convert_like_real,
+ build_new_method_call): Likewise.
+ * class.c (build_vbase_pointer_fields, check_bases,
+ build_base_field, finish_struct_1, pushclass): Likewise.
+ * cvt.c (cp_convert_to_pointer, convert_to_void): Likewise.
+ * decl.c (maybe_process_template_type_declaration, pushtag,
+ pushdecl, redeclaration_error_message, start_decl, start_decl_1,
+ layout_var_decl, check_initializer, cp_finish_decl,
+ grokdeclarator, require_complete_types_for_parms,
+ grok_op_properties, xref_tag, xref_basetypes,
+ check_function_type): Likewise.
+ * decl2.c (check_classfn, reparse_absdcl_as_casts): Likewise.
+ * friend.c (do_friend): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * parse.y (structsp): Likewise.
+ * pt.c (maybe_process_partial_specialization,
+ tsubst_friend_function, instantiate_class_template, tsubst,
+ do_type_instantiation, instantiate_pending_templates): Likewise.
+ * repo.c (repo_get_id): Likewise.
+ * rtti.c (build_typeid, get_typeid, build_dynamic_cast_1,
+ synthesize_tinfo_var, emit_support_tinfos): Likewise.
+ * search.c (lookup_fnfields_1, lookup_conversions): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+ * tree.c (build_cplus_method_type): Likewise.
+ * typeck2.c (digest_init, build_functional_cast,
+ add_exception_specifier): Likewise.
+ * parse.h, parse.c: Regenerated.
+
+2000-03-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h: New header file. Define new-abi entry points.
+ (__pointer_type_info::target): Rename member to ...
+ (__pointer_type_info::type): ... here.
+ (__base_class_info::type): Rename member to ...
+ (__base_class_info::base): ... here.
+ * Make-lang.in (CXX_EXTRA_HEADERS): Add cxxabi.h
+ * cp-tree.h (CPTI_ABI): New global tree enumeration.
+ (abi_node): New global tree node.
+ * decl.c (abi_node): Document.
+ (init_decl_processing): Initialize abi_node.
+ * rtti.c (build_dynamic_cast_1): Use abi_node for new-abi.
+ (get_vmi_pseudo_type_info): Likewise.
+ (create_tinfo_types): Likewise.
+ (emit_support_tinfos): Likewise.
+ * tinfo.h (cxxabi.h): Include for new-abi.
+ Move rtti class definitions to new header file.
+ * tinfo.cc (abi): Use the namespace.
+ (std): Move new abi rtti classes from here ...
+ (__cxxabiv1): ... to here.
+ * tinfo2.cc (cxxabi.h): Include for new-abi.
+ Move rtti class definitions to new header file.
+ (std): Move new abi rtti classes from here ...
+ (__cxxabiv1): ... to here.
+ * inc/typeinfo (__class_type_info): Move into __cxxabiv1
+ namespace.
+
+2000-03-20 Jed Wing <jedwin@zloty.ugcs.caltech.edu>
+ Jason Merrill <jason@casey.cygnus.com>
+
+ * method.c (build_overload_int): Use host_integerp.
+
+2000-03-20 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * init.c (build_offset_ref): Handle the case of a templated member
+ function.
+
+2000-03-19 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * except.c (expand_exception_blocks): Clear catch_clauses_last.
+
+2000-03-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLEAR_DECL_C_BIT_FIELD): New macro.
+ * class.c (check_bitfield_decl): Turn illegal bitfields into
+ non-bitfields.
+ (dfs_propagate_binfo_offsets): Adjust for new size_binop
+ semantics.
+ (dfs_offset_for_unshared_vbases): Likewise.
+ * cvt.c (cp_convert_to_pointer): Convert NULL to a
+ pointer-to-member correctly under the new ABI.
+ * expr.c (cplus_expand_constant): Don't use cp_convert when
+ turning an offset into a pointer-to-member.
+ * init.c (resolve_offset_ref): Don't adjust pointers-to-members
+ when dereferencing them under the new ABI.
+ * typeck.c (get_member_function_from_ptrfunc): Tweak calculation
+ of pointers-to-members under the new ABI.
+
+ * class.c (check_bitfield_decl): Remove restriction on really long
+ bitfields.
+ (layout_class_type): Implement new ABI handling of bitfields
+ longer than their types.
+
+2000-03-18 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (extdefs): Call ggc_collect.
+ * parse.c: Regenerated.
+
+2000-03-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_base_field): Use TYPE_ALIGN to examine a type.
+ (note_name_declared_in_class): Use OVL_CURRENT to get at a
+ potential overload.
+
+2000-03-17 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_vbase_path): Use integer_zerop.
+ (build_vtable_entry): Use tree_low_cst.
+ (get_vfield_offset): Use bit_position.
+ (dfs_modify_vtables): New variable vindex_val; `i' is HOST_WIDE_INT.
+ Use tree_low_cst.
+ (check_bitfield_decl): Set DECL_SIZE using convert.
+ (build_base_field): Set DECL_SIZE and DECL_SIZE_UNIT using size_binop.
+ (layout_virtual_bases): DSIZE is unsigned HOST_WIDE_INT.
+ Use tree_low_cst.
+ (finish_struct_1): Use bit_position.
+ (dump_class_hierarchy): Use tree_low_cst.
+ * cp-tree.h (min_precision): Add declaration.
+ * decl.c (xref_tag, xref_basetypes): Use tree_low_cst.
+ * error.c (dump_type_suffix): Use host_integerp and tree_low_cst.
+ (dump_expr): Use integer_zerop, host_integerp, and tree_low_cst.
+ * expr.c (cplus_expand_constant): Use bit_position.
+ * init.c (build_vec_init): Use host_integerp and tree_low_cst.
+ * rtti.c (get_base_offset): Use bit_position.
+ * typeck.c (build_binary_op): Use integer_zerop, compare_tree_int,
+ host_integerp, and tree_low_cst.
+ (pointer_int_sum): Use integer_zerop.
+ (build_component_addr): Use bit_position.
+
+2000-03-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (require_complete_type): Don't assume size_zero_node.
+ (complete_type_or_else): Likewise.
+
+2000-03-16 Steven Grady <grady@digitaldeck.com>
+ Jason Merrill <jason@casey.cygnus.com>
+
+ * rtti.c (build_dynamic_cast_1): Improve diagnostics.
+
+2000-03-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (grokfield): Bail out if type is error_mark_node.
+
+2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo2.cc (__ptr_to_member_data): Rename to ...
+ (__pointer_to_member_data): ... here. Adjust.
+ * rtti.c (create_tinfo_types): Adjust.
+
+2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTI_REF_DESC_TYPE, ref_desc_type_node): Remove.
+ * decl.c (ref_desc_type_node): Undocument.
+ * rtti.c (ptr_ref_initializer): Rename to ...
+ (ptr_initializer): ... here. Adjust comments.
+ (ptmd_initializer): Fix comment thinko.
+ (synthesize_tinfo_var): Remove REFERENCE_TYPE case.
+ (create_tinfo_types): Remove ref_desc_type_node init.
+ * tinfo2.cc (__reference_type_info): Remove.
+
+2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Remove obsolete comment.
+
+ * typeck.c (build_ptrmemfunc1): Kill uninitialized warning.
+
+2000-03-14 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h: Tweak documentation.
+ * class.c (build_vbase_pointer_fields): Layout the fields, too.
+ (avoid_overlap): Remove.
+ (get_binfo_offset_as_int): New function.
+ (dfs_serach_base_offsets): Likewise.
+ (layout_nonempty_base_or_field): Likewise.
+ (build_base_field): Layout fields here. Avoid placing two objects
+ of the same type at the same address, under the new ABI.
+ (build_base_fields): Adjust accordingly.
+ (create_vtable_ptr): Return the new field, but don't attach it to
+ TYPE_FIELDS.
+ (remove_base_field): Remove.
+ (remove_base_fields): Remove.
+ (layout_basetypes): Adjust accordingly.
+ (layout_class_type): Call layout_field for each field, rather than
+ just making a wholesale call to layout_type.
+
+2000-03-14 Jeff Sturm <jsturm@sigma6.com>
+
+ * except.c (expand_throw): Fix typo in _Jv_Sjlj_Throw.
+
+2000-03-13 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (grokfndecl): Set TREE_NOTHROW if TYPE_NOTHROW_P.
+
+ * except.c (dtor_nothrow): New fn.
+ (do_pop_exception): Use it. Take type parm.
+ (push_eh_cleanup): Take type parm.
+ (expand_start_catch_block): Pass it.
+ (build_eh_type_type_ref): Accept null type.
+
+2000-03-12 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (revert_static_member_fn): Change prototype.
+ * decl.c (grokfndecl): Adjust call to revert_static_member_fn.
+ (grok_op_properties): Likewise.
+ (start_function): Likewise.
+ (revert_static_member_fn): Simplify.
+ * pt.c (check_explicit_specialization): Adjust call to
+ revert_static_member_fn.
+
+2000-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (scope_kind): New type.
+ (tmpl_spec_kind): Likewise.
+ (declare_pseudo_global_level): Remove.
+ (pseudo_global_level_p): Rename to template_parm_scope_p.
+ (pushlevel): Remove declaration.
+ (begin_scope): New function.
+ (finish_scope): Likewise.
+ (current_tmpl_spec_kind): Likewise.
+ * decl.c (struct binding_level): Shorten parm_flag to 2 bits.
+ Shorten keep to 2 bits. Rename pseudo_global to template_parms_p.
+ Add template_spec_p.
+ (toplevel_bindings_p): Adjust.
+ (declare_pseudo_global_level): Remove.
+ (pseudo_global_level_p): Rename to template_parm_scope_p.
+ (current_tmpl_spec_kind): New function.
+ (begin_scope): Likewise.
+ (finish_scope): Likewise.
+ (maybe_push_to_top_level): Adjust.
+ (maybe_process_template_type_declaration): Likewise.
+ (pushtag): Likewise.
+ (pushdecl_nonclass_level): Likewise.
+ (lookup_tag): Likewise.
+ (grokfndecl): Handle member template specializations. Share
+ constructor and non-constructor code.
+ * decl2.c (check_classfn): Handle member template specializations.
+ * pt.c (begin_template_parm_list): Use begin_scope.
+ (begin_specialization): Likewise.
+ (end_specialization): Likewise.
+ (check_explicit_specialization): Use current_tmpl_spec_kind.
+ Handle member template specializations.
+ (end_template_decl): Use finish_scope. Remove call to
+ get_pending_sizes.
+ (push_template_decl_real): Remove bogus error message.
+ (tsubst_decl): Fix typo in code contained in comment.
+ (instantiate_template): Handle member template specializations.
+ (most_general_template): Likewise.
+
+2000-03-11 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (whitespace_cr): Compress consecutive calls to warning().
+ (do_identifier): Ditto for error().
+
+ * pt.c (convert_nontype_argument): Ditto for cp_error().
+ (convert_template_argument): Ditto for cp_pedwarn().
+
+2000-03-11 Jason Merrill <jason@casey.cygnus.com>
+
+ * exception.cc (__check_null_eh_spec): New fn.
+ * except.c (expand_end_eh_spec): Call it if the spec is throw().
+
+2000-03-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (push_throw_library_fn): Take the FUNCTION_TYPE.
+ * except.c (expand_end_eh_spec): Add the return type.
+ * rtti.c (throw_bad_cast): Add the parmtypes.
+ (throw_bad_typeid): Likewise.
+
+ * semantics.c (expand_stmt): Only leave out rtl for unused
+ artificials, and set DECL_IGNORED_P on them as well.
+ * decl.c (wrapup_globals_for_namespace): Likewise.
+
+2000-03-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (maybe_commonize_var): Skip all artificial decls.
+ * pt.c (tsubst_decl): Don't copy TREE_ASM_WRITTEN.
+
+2000-03-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * lang-options.h, decl2.c: Add -fno-enforce-eh-specs.
+ * cp-tree.h: Declare flag_enforce_eh_specs.
+ * decl.c (store_parm_decls, finish_function): Check it.
+
+ C library functions don't throw.
+ * Makefile.in (cfns.h): New target.
+ (except.o): Depend on it.
+ * Make-lang.in (cc1plus): Depend on cfns.gperf.
+ * cfns.gperf: New file.
+ * cfns.h: Generated.
+ * except.c: Include it.
+ (nothrow_libfn_p): New fn.
+ * decl.c (grokfndecl): Use it.
+ * cp-tree.h: Declare it.
+
+ * decl.c (push_overloaded_decl_1, auto_function,
+ define_function): Lose.
+ (build_library_fn_1): New static fn.
+ (builtin_function): Use it.
+ (get_atexit_node): Use build_library_fn_ptr.
+ (build_library_fn, build_cp_library_fn, build_library_fn_ptr,
+ build_cp_library_fn_ptr, push_library_fn, push_cp_library_fn,
+ push_void_library_fn, push_throw_library_fn): New fns.
+ * cp-tree.h: Declare them.
+ (cp_tree_index): Remove CPTI_BAD_CAST, CPTI_BAD_TYPEID.
+ (throw_bad_cast_node, throw_bad_typeid_node): Lose.
+ * except.c (init_exception_processing, call_eh_info, do_pop_exception,
+ (expand_end_eh_spec, alloc_eh_object, expand_throw): Use above fns.
+ * rtti.c (build_runtime_decl): Lose.
+ (throw_bad_cast, throw_bad_typeid, get_tinfo_decl,
+ build_dynamic_cast_1, expand_si_desc, expand_class_desc,
+ expand_ptr_desc, expand_attr_desc, expand_generic_desc): Use above fns.
+
+ * call.c (build_call): Remove result_type parm.
+ Call mark_used on unused artificial fns.
+ * init.c, method.c, typeck.c, except.c, rtti.c: Adjust.
+
+2000-03-09 Jason Merrill <jason@casey.cygnus.com>
+
+ * call.c (build_call): Set TREE_NOTHROW on the CALL_EXPR as
+ appropriate.
+ * decl.c (define_function): Set TREE_NOTHROW on the FUNCTION_DECL.
+ * except.c (call_eh_info, alloc_eh_object, expand_throw): Set
+ TREE_NOTHROW or TREE_THIS_VOLATILE on the function as appropriate.
+ * rtti.c (build_runtime_decl, get_tinfo_decl, build_dynamic_cast_1,
+ expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc,
+ expand_generic_desc): Likewise.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * exception.cc (__cp_pop_exception): Cleanup the original object.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grok_op_properties): Merge conversion to void warning
+ with other silly op warnings.
+
+2000-03-08 Jason Merrill <jason@casey.cygnus.com>
+
+ * typeck2.c (process_init_constructor): Set TREE_PURPOSE of
+ array CONSTRUCTOR elements. Don't use expr_tree_cons.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (cp_make_fname_decl): New function.
+ (wrapup_globals_for_namespace): Don't emit unused static vars.
+ (init_decl_processing): Remove comment about use of
+ array_domain_type. Set make_fname_decl.
+ (cp_finish_decl): Remove __FUNCTION__ nadgering.
+ * semantics.c (begin_compound_stmt): Remove
+ current_function_name_declared flagging.
+ (expand_stmt): Don't emit unused local statics.
+ * typeck.c (decay_conversion): Don't treat __FUNCTION__ decls
+ specially.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (convert_for_assignment): Don't look at array
+ initializer.
+ * call.c (convert_like_real): Likewise.
+
+2000-03-07 Jason Merrill <jason@casey.cygnus.com>
+
+ Add initial support for '\uNNNN' specifier.
+ * lex.c (read_ucs): New fn.
+ (readescape, skip_white_space): Call it.
+ (is_extended_char, is_extended_char_1): New fns.
+ (utf8_extend_token): New fn, #if 0'd out.
+ (real_yylex): Treat extended chars like letters.
+
+ * search.c (note_debug_info_needed): Walk the bases even if we
+ weren't deferring the type itself.
+
+2000-03-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (finish_objects): Constify a char*.
+
+ * method.c (emit_thunk): Likewise.
+
+2000-03-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (dubious_conversion_warnings): Look through
+ REFERENCE_TYPE.
+
+2000-03-06 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (dfs_modify_vtables): I is now unsigned.
+ (check_bitfield_decl): Use tree_int_cst_sgn and compare_tree_int.
+ (build_base_field): Add casts of TREE_INT_CST_LOW to HOST_WIDE_INT.
+ * error.c (dump_expr): Cast TREE_INT_CST_HIGH to unsigned.
+ * init.c (build_vec_init): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
+ * method.c (build_overload_int): Cast TREE_INT_CST_HIGH to unsigned.
+ * typeck.c (build_binary_op, case TRUNC_DIV_EXPR):
+ Call integer_all_onesp.
+ * typeck2.c (process_init_constructor): Use compare_tree_int.
+
+ * lang-specs.h (as): Don't call if -syntax-only.
+
+2000-03-06 Mark Mitchell <mark@codesourcery.com>
+
+ * expr.c (cplus_expand_expr, case STMT_EXPR): Don't set
+ RTL_EXPR_HAS_NO_SCOPE after all.
+
+2000-03-05 Mark Mitchell <mark@codesourcery.com>
+
+ * expr.c (cplus_expand_expr, case STMT_EXPR): Use
+ expand_start_stmt_expr and expand_end_stmt_expr directly. Set
+ RTL_EXPR_HAS_NO_SCOPE.
+
+ * pt.c (instantiate_decl): Clear TI_PENDING_TEMPLATE_FLAG a little
+ later.
+
+ * dump.c (dequeue_and_dump): Dump SCOPE_NO_CLEANUPS_P.
+
+2000-03-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (convert_like): Macrofy.
+ (convert_like_with_context): New macro.
+ (convert_like_real): Renamed from convert_like. Add calling
+ context parameters, for diagnostics. Add recursive flag. Call
+ dubious_conversion_warnings for outer conversion.
+ (build_user_type_conversion): Use convert_like_with_context.
+ (build_over_call): Likewise. Don't warn about dubious
+ conversions here. Adjust convert_default_arg calls.
+ (convert_default_arg): Add context parameters for diagnostics.
+ Pass through to convert_like_with_context.
+ * cp-tree.h (convert_default_arg): Add context parameters.
+ (dubious_conversion_warnings): Prototype new function.
+ * typeck.c (convert_arguments): Adjust convert_default_arg call.
+ (dubious_conversion_warnings): New function, broken
+ out of convert_for_assignment.
+ (convert_for_assignment): Adjust.
+
+2000-03-03 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl2.c (key_method): Break out from...
+ (import_export_vtable, import_export_class): ...here.
+
+ * decl.c (finish_function): Don't mess with flag_keep_inline_functions.
+ * decl2.c (finish_vtable_vardecl): Don't check decl_function_context.
+
+ * search.c (note_debug_info_needed, dfs_debug_mark,
+ dfs_debug_unmarkedp): Uncomment. Adjust for new scheme.
+ * decl2.c (finish_vtable_vardecl): Call note_debug_info_needed.
+
+2000-03-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Remove obsolete obstack comments, fix
+ typos.
+
+2000-03-02 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TYPE_NEEDS_DESTRUCTOR): Rename to ...
+ (TYPE_HAS_NONTRIVIAL_DESTRUCTOR): ... this.
+ (TYPE_HAS_TRIVIAL_DESTRUCTOR): New macro.
+ (lang_type): Split gets_new into has_new and has_array_new.
+ (TYPE_VEC_NEW_USES_COOKIE): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (TYPE_GETS_NEW): Split into ...
+ (TYPE_HAS_NEW_OPERATOR): ... this, and ...
+ (TYPE_HAS_ARRAY_NEW_OPERATOR): ... this.
+ (DECL_ARRAY_DELETE_OPERATOR_P): New macro
+ (build_op_new_call): Don't declare.
+ (build_new_1): Likewise.
+ * call.c (build_op_new_call): Remove.
+ * class.c (check_bases): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+ instead of TYPE_NEEDS_DESTRUCTOR.
+ (finish_struct_bits): Likewise.
+ (add_implicitly_declared_members): Likewise.
+ (check_field_decl): Likewise.
+ (check_methods): Set TYPE_VEC_DELETE_TAKES_SIZE here, and set it
+ correctly under the new ABI.
+ * decl.c (start_decl_1): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+ instead of TYPE_NEEDS_DESTRUCTOR.
+ (initialize_local_var): Likewise.
+ (destroy_local_var): Likewise.
+ (cp_finish_decl): Likewise.
+ (register_dtor_fn): Likewise.
+ (grok_op_properties): Set TYPE_HAS_NEW_OPERATOR and
+ TYPE_HAS_ARRAY_NEW_OPERATOR, not TYPE_HAS_NEW. Don't set
+ TYPE_VEC_DELETE_TAKES_SIZE here.
+ (xref_basetypes): Set TYPE_HAS_NEW_OPERATOR and
+ TYPE_HAS_ARRAY_NEW_OPERATOR, not TYPE_HAS_NEW.
+ (store_parm_decls): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (finish_destructor_body): Likewise.
+ (maybe_build_cleanup_1): Likewise.
+ * decl2.c (do_static_destruction): Likewise.
+ * init.c (build_new_1): Make it static.
+ (perform_member_init): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (expand_cleanup_for_base): Likewise.
+ (get_cookie_size): New function.
+ (build_new_1): Handle array-new cookies correctly under the new
+ ABI.
+ (build_vec_delete_1): Likewise.
+ (build_vec_init): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (build_delete): Likewise.
+ (build_vec_delete): Handle array-new cookies correctly under the new
+ ABI.
+ * lex.c (do_identifier): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ * pt.c (instantiate_class_template): Set TYPE_HAS_NEW_OPERATOR and
+ TYPE_HAS_ARRAY_NEW_OPERATOR.
+ * ptree.c (print_lang_type): Check them.
+ * search.c (context_for_name_lookup): Fix typo in comment.
+ (tree_has_any_destructor_p): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ * tree.c (break_out_cleanups): Likewise.
+ (build_cplus_array_test_1): Likewise.
+ (cp_build_qualified_type_real): Likewise.
+ * typeck.c (complete_type): Likewise.
+
+ * g++spec.c (lang_specific_driver): Add -fnew-abi at the start of
+ the command-line, not the end.
+
+2000-03-01 Jason Merrill <jason@casey.cygnus.com>
+
+ * pt.c (instantiate_decl): Clear TI_PENDING_TEMPLATE_FLAG.
+
+2000-03-02 Tom Tromey <tromey@cygnus.com>
+
+ * cp-tree.h (build_java_class_ref): Declare.
+ * init.c (build_java_class_ref): No longer static.
+ * except.c (expand_throw): Generate a Java-style `throw' if the
+ thrown object is a "Java" object.
+ (initialize_handler_parm): Generate a Java-style lookup of
+ exception info if the caught object is a "Java" object.
+ (catch_language, catch_language_init): New globals.
+ (decl_is_java_type): New function.
+ (expand_start_catch_block): Don't call push_eh_info() or
+ push_eh_cleanup() when handling a Java-style "catch". Pass Java
+ class reference to build_catch_block.
+
+2000-03-02 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * typeck.c (comptypes): Treat sizetype like its language equivalent.
+
+2000-03-01 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * typeck.c (maybe_warn_about_returning_address_of_local): Reorganize
+ to merge reference/pointer code and fix incorrect warnings.
+
+2000-02-29 Jason Merrill <jason@casey.cygnus.com>
+
+ * search.c (protected_accessible_p): Use context_for_name_lookup.
+
+ * init.c (construct_virtual_bases): Fix thinko.
+ * typeck.c (expand_ptrmemfunc_cst): Fix thinko.
+
+2000-03-01 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (current_function_decl): Move to toplev.c.
+
+2000-02-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (fn_type_unification): Unify return type, whenever
+ provided.
+ (get_bindings_real): Only pass return type when necessary.
+ Remove explicit return type check.
+ * class.c (resolve_address_of_overloaded_function): Pass desired
+ return type to fn_type_unification.
+
+2000-02-28 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_vtbl_or_vbase_field, check_methods): Don't clear
+ DECL_FIELD_SIZE.
+ (check_bitfield_decl, check_field_decls): Set DECL_SIZE, not
+ DECL_FIELD_SIZE.
+ * rtti.c (expand_class_desc): Likewise.
+ * cp-tree.h (DECL_INIT_PRIORITY): Use underlying union name.
+ (THUNK_VCALL_OFFSET): Likewise.
+ (THUNK_DELTA): Reflect changes in ../tree.h.
+
+2000-02-28 Jason Merrill <jason@casey.cygnus.com>
+
+ * search.c (protected_accessible_p): Also allow the access if
+ the member is public in DERIVED. Lose TYPE parm.
+ (friend_accessible_p): Lose TYPE parm.
+ (accessible_p): Adjust.
+
+2000-02-27 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (dfs_build_vtable_offset_vtbl_entries): Don't use size_binop
+ on things that are not sizes; ssize_binop deleted.
+ Call size_diffop when appropriate.
+ (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (build_primary_vtable, build_secondary_vtable): Likewise.
+ (dfs_set_offset_for_unshared_vbases, dfs_modify_vtables): Likewise.
+ Variable I is HOST_WIDE_INT.
+ (get_vfield_offset): Pass proper types to size_binop.
+ (size_extra_vtbl_entries, layout_virtual_bases): Likewise.
+ (finish_struct_1): Likewise.
+ (skip_rtti_stuff): Arg N is now pointer to signed.
+ (layout_class_type): Use size_zero_node.
+ * cp-tree.h (skip_rtti_stuff): Arg N is pointer to signed.
+ * cvt.c (cp_convert_to_pointer): Pass proper types to size_binop.
+ * decl.c (complete_arry_type): Pass proper types to size_binop.
+ (xref_basetypes): BINFO_OFFSET is sizetype.
+ * error.c (dump_expr): Don't use size_binop non-sizes.
+ * expr.c (cplus_expand_constant): Pass proper types to size_binop.
+ * init.c (construct_virtual_bases): Fix type error.
+ (build_vec_delete_1): Pass proper type to size_binop and don't
+ fold result.
+ * lex.c (cp_make_lang_type): BINFO_OFFSET is sizetype.
+ * rtti.c (get_base_offset): Pass proper type to size_binop.
+ * search.c (dfs_find_vbases): Fix type error.
+ (expand_upcast_fixups): Arg to skip_rtti_stuff is pointer to signed.
+ (dfs_get_vbase_types): BINFO_OFFSET is sizetype.
+ * tree.c (debug_binfo): Variable N is signed.
+ Use HOST_WIDE_INT_PRINT_DEC.
+ * typeck.c (comptypes): sizetype is same as equivalent integer type.
+ (c_sizeof, c_sizeof_nowarn, expr_sizeof): Use TYPE_SIZE_UNIT,
+ size_one_node and size_zero_node.
+ (c_alignof): Use size_one_node.
+ (build_component_addr): Pass proper types to size_binop.
+ (expand_ptrmemfunc_cst): Don't use size_binop on non-sizes.
+
+2000-02-26 Jason Merrill <jason@casey.cygnus.com>
+
+ Implement class scope using-declarations for functions.
+ * class.c (handle_using_decl): Call add_method for used functions.
+ Use IDENTIFIER_CLASS_VALUE to check for conflicts.
+ (add_method): Used functions are hidden by local functions.
+ (check_bases_and_members): Handle using-decls before finalizing
+ CLASSTYPE_METHOD_VEC.
+ * call.c (add_function_candidate): Add ctype parm; if nonzero,
+ override the type of 'this' accordingly.
+ (add_template_candidate, add_template_candidate_real): Add ctype parm.
+ (convert_class_to_reference, build_user_type_conversion_1,
+ build_new_function_call, build_object_call, build_new_op,
+ build_new_method_call): Pass ctype parm.
+
+ * search.c (lookup_member): Put rval_binfo, not basetype_path, in
+ the baselink.
+ * call.c (convert_class_to_reference, build_user_type_conversion_1,
+ build_new_function_call, build_object_call, build_new_op,
+ build_new_method_call, build_op_delete_call): Don't get basetype_path
+ from a baselink.
+ * typeck.c (build_component_ref): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ (resolve_offset_ref): Don't call enforce_access.
+ Call build_scoped_ref.
+ * typeck2.c (build_scoped_ref): Simplify. Do nothing if it
+ would cause an error or if -pedantic.
+ * class.c (alter_access): Lose binfo parm.
+
+2000-02-26 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (simplify_aggr_init_exprs_p): Don't walk into
+ types.
+
+2000-02-25 Alfred Minarik <a8601248@unet.univie.ac.at>
+
+ * rtti.c (get_vmi_pseudo_type_info): Move __vmi_class_type_info
+ pseudo_type_info creation into the std namespace
+
+2000-02-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_NEEDED_P): Tweak to correct usage before EOF.
+ (import_export_class): Remove declaration.
+ * decl2.c (import_export_class): Make it static.
+ * dump.c (dequeue_and_dump): Handle PREDECREMENT_EXPR,
+ PREINCREMENT_EXPR, POSTDECREMENT_EXPR, POSTINCREMENT_EXPR,
+ EXPR_WITH_FILE_LOCATION.
+ * lex.c (check_newline): Tweak filename/lineno setting.
+ * semantics.c (begin_while_stmt): Fix typo in comment.
+
+2000-02-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * lang-options.h (-fmessage-length=): Add missing option.
+
+ * Make-lang.in (CXX_SRCS): Add .h files and sort list.
+
+2000-02-26 Zack Weinberg <zack@wolery.cumb.org>
+
+ * Make-lang.in: Delete refs to LIBGCC2_DEPS.
+
+2000-02-25 Jim Wilson <wilson@cygnus.com>
+
+ * optimize.c (expand_call_inline): Emit the return label before
+ evaluating the return value.
+
+2000-02-24 Mark Mitchell <mark@codesourcery.com>
+
+ * lex.c (check_newline): Use push_srcloc and pop_srcloc, rather
+ than duplicating functionality here.
+ * optimize.c: Include input.h.
+ (expand_call_inline): Use push_srcloc and pop_srcloc.
+ * parse.y (maybe_cv_qualifier): Remove calls to emit_line_note.
+ * parse.c: Regenerated.
+ * Makefile.in (lex.o): Depend on input.h.
+ (optimize.o): Likewise.
+
+2000-02-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Diagnose qualifiers on non-member
+ function type, rather than ICE.
+
+2000-02-23 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (grokdeclarator): Call decl_type_access_control.
+ * parse.y (parse_end_decl): Don't call decl_type_access_control if
+ decl is null.
+
+2000-02-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (decls_match): Remove obsolete static member nadgering.
+
+2000-02-21 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (grokdeclarator): Change ANSI to ISO.
+ * lex.c (consume_string, readescape, do_identifier): Likewise.
+ (parse_float, real_yylex): Likewise.
+ * parse.y (paren_expr_or_null, paren_cond_or_null): Likewise.
+ (unary_expr, new_initializer, cast_expr, primary, primary_no_id,
+ new_type_id, maybe_label_decls, simple_stmt,
+ for.init.statement): Likewise.
+ * pt.c (do_decl_instantiation, do_type_instantiation): Likewise.
+ * semantics.c (finish_named_return_value): Likewise.
+ * parse.c: Regenerate.
+
+2000-02-21 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CPTI_VTABLE_INDEX_TYPE): New macro.
+ (CPTI_CLASS_STAR_TYPE): Remove.
+ (vtable_index_type): Likewise.
+ (class_star_type_node): Remove.
+ (TYPE_PTRMEMFUNC_FN_TYPE): Adjust for the new ABI.
+ (build_binary_op_nodefault): Remove.
+ * call.c (build_new_op): Use build_binary_op instead of
+ build_binary_op_nodefault.
+ * decl.c (init_decl_processing): Remove class_star_type_node
+ initialization. Make delta_type_node ptrdiff_type_node under the
+ new ABI. Initialize vtable_index_type.
+ (build_ptrmemfunc_type): Build different structures for the new
+ ABI.
+ (build_enumerator): Use build_binary_op instead of
+ build_binary_op_nodefault.
+ * method.c (build_overload_value): Mangle pointers-to-members
+ appropriately under the new ABI.
+ * typeck.c (build_array_ref): Use build_binary_op instead of
+ build_binary_op_nodefault.
+ (get_member_function_from_ptrfunc): Adjust for the new ABI.
+ (build_binary_op_nodefault): Rename to ...
+ (build_binary_op): ... this. Remove old version. Adjust for
+ pointer-to-member comparisons under the new ABI.
+ (build_ptrmemfunc1): Remove dead code. Adjust for the new ABI.
+ (build_ptrmemfunc): Adjust for the new ABI.
+ (expand_ptrmemfunc_cst): Likewise.
+ (delta2_from_ptrmemfunc): Assert that we're not using the new ABI.
+ (pfn_from_ptrmemfunc): Adjust for the new ABI.
+
+2000-02-21 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * call.c (build_object_call): Compress consecutive calls to
+ cp_error.
+ (build_conditional_expr): Say 'ISO C++' not 'ANSI C++'.
+ (build_op_delete_call): Adjust message formatting.
+
+ * class.c (check_bases): Compress consecutive calls to
+ cp_pedwarn.
+ (finish_struct_anon): Say 'ISO C++'.
+
+ * decl.c (start_decl): Same here.
+ (grok_reference_init): Likewise.
+ (grokfndecl): Correct message formatting.
+ (grokfndecl): Improve diagnostic.
+ (check_static_variable_definition): Likewise. Say 'ISO C++'
+ (compute_array_index_type): Say 'ISO C++'
+ (create_array_type_for_decl): Compress consecutive calls to
+ cp_error.
+ (grokdeclarator): Say 'ISO C++'
+ (grok_op_properties): Likewise.
+
+ * decl2.c (delete_sanity): Clairify diagnostic.
+ (check_member_template): Same here.
+ (grok_function_init): Use consistent terminology.
+
+ * expr.c (do_case): Say 'ISO C++'
+
+ * friend.c (do_friend): Compress consecutive calls to warning.
+
+2000-02-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (merge_primary_and_secondary_vtables_p): New macro.
+ * class.c (build_secondary_vtable): Reorganize. Don't create a
+ new vtable under the new ABI.
+ (layout_vtable_decl): Don't add num_extra_vtbl_entries when
+ computing the size.
+ (build_vtbl_initializer): Don't return a CONSTRUCTOR; just return
+ the initializing elements.
+ (initialize_vtable): New function.
+ (dfs_finish_vtbls): Use it.
+ (dfs_accumulate_vtbl_inits): New function.
+ (finish_vtbls): Merge primary and secondary vtables under the new
+ ABI.
+ (finish_struct_1): Remove redundant call to layout_vtable_decl.
+ * init.c (expand_virtual_init): Deal with BINFO_VTABLEs that
+ aren't VAR_DECLs.
+
+ * class.c (build_vtable): New function, split out from ...
+ (get_vtable_decl): ... here, and ...
+ (build_secondary_vtable): ... here.
+
+ * pt.c (tsubst_decl): Fix formatting.
+
+2000-02-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_primary_vtable, layout_vtable_decl): Likewise.
+ (avoid_overlap, build_base_field): Likewise.
+ (build_base_field, build_base_fields, is_empty_class):
+ Test DECL_SIZE with integer_zero.
+ (layout_class_type): Set CLASSTYPE_SIZE_UNIT.
+ * cp-tree.h (struct lang_type): New field size_unit.
+ (CLASSTYPE_SIZE_UNIT): New macro.
+ * decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
+ (cp_finish_decl): Delete -Wlarger-than processing.
+ * optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
+ * pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
+ * tree.c (make_binfo): binfo vector is one entry longer.
+ (walk_tree): Walk DECL_SIZE_UNIT.
+
+2000-02-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (dfs_build_vcall_offset_vtbl_entries): Fix typo in
+ comment.
+ (build_vtable_entry): Don't assume all vtable entries are
+ functions.
+ (build_vtbl_initializer): Adjust accordingly.
+ (get_vtable_decl): Fix formatting.
+
+2000-02-18 Jason Merrill <jason@casey.cygnus.com>
+
+ * semantics.c (deferred_type_access_control): Walk the entire
+ type_lookups list.
+ (save_type_access_control): Rename from
+ initial_deferred_type_access_control. Just remember the value.
+ (decl_type_access_control): New fn.
+ (begin_function_definition): Use deferred_type_access_control, after
+ we've started the function. Set type_lookups to error_mark_node.
+ * parse.y (frob_specs, fn.def1): Adjust.
+ (parse_decl0, parse_field, parse_field0, parse_bitfield): New fns.
+ (parse_end_decl, parse_bitfield0, parse_method): New fns.
+ (fn.def2, initdcl, initdcl0_innards, nomods_initdcl0): Use them.
+ (after_type_component_declarator0): Likewise.
+ (after_type_component_declarator): Likewise.
+ (notype_component_declarator): Likewise.
+ * cp-tree.h: Adjust.
+
+ * decl.c (redeclaration_error_message): Allow redeclaration of
+ namespace-scope decls.
+
+2000-02-18 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * typeck2.c (my_friendly_abort): Use GCCBUGURL.
+
+2000-02-17 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_method): Don't set DECL_VIRTUAL_CONTEXT.
+ * decl2.c (grokclassfn): Likewise.
+
+ * ir.texi: Document DECL_TEMPLATE_INSTANTIATIONS.
+
+ * decl2.c (lang_decode_option): Don't set default message length
+ here.
+ * lex.c (lang_init_options): Set it here.
+
+2000-02-16 Mark Mitchell <mark@codesourcery.com>
+
+ Make DECL_CONTEXT mean the class in which a member function was
+ declared, even for a virtual function.
+ * cp-tree.h (DECL_CLASS_CONTEXT): Adjust.
+ (DECL_FRIEND_CONTEXT): New macro.
+ (DECL_REAL_CONTEXT): Remove.
+ (SET_DECL_FRIEND_CONTEXT): Likewise.
+ (DECL_VIRTUAL_CONTEXT): Adjust.
+ (DECL_CLASS_SCOPE_P): Use TYPE_P.
+ (add_friends): Remove.
+ (hack_decl_function_context): Likewise.
+ * call.c (build_new_function_call): Replace DECL_REAL_CONTEXT with
+ CP_DECL_CONTEXT.
+ (build_over_call): Fix indentation. Use DECL_CONTEXT
+ instead of DECL_CLASS_CONTEXT.
+ * class.c (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (add_method): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (strictly_overrides): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (build_vtbl_or_vbase_field): Don't set DECL_CLASS_CONTEXT.
+ (build_base_field): Likewise.
+ (finish_struct_1): Likewise.
+ (build_self_reference): Likewise.
+ * decl.c (push_class_binding): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (pushtag): Use decl_function_context, not
+ hack_decl_function_context.
+ (decls_match): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
+ (duplicate_decls): Use DECL_VIRTUAL_CONTEXT.
+ (pushdecl): Remove bogus code.
+ (start_decl): Use DECL_CONTEXT rather than DECL_CLASS_CONTEXT.
+ (cp_finish_decl): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
+ (grokfndecl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ Use decl_function_context, nothack_decl_function_context.
+ (grokvardecl): Don't set DECL_CLASS_CONTEXT.
+ (grokdeclarator): Likewise. Use decl_function_context, not
+ hack_decl_function_context.
+ (copy_args_p): Document. Don't use DECL_CLASS_CONTEXT.
+ (start_function): Use DECL_FRIEND_CONTEXT, not
+ DECL_CLASS_CONTEXT. Use decl_function_context, not
+ hack_decl_function_context.
+ (finish_function): Use decl_function_context, not
+ hack_decl_function_context.
+ (maybe_retrofit_in_chrg): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ (grokclassfn): Set DECL_VIRTUAL_CONTEXT, not DECL_CONTEXT.
+ (finish_static_data_member_decl): Don't set DECL_CLASS_CONTEXT.
+ (grokfield): Likewise.
+ (finish_builtin_type): Likewise.
+ (finish_vtable_vardec): Use decl_function_context, not
+ hack_decl_function_context.
+ (import_export_decl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (start_static_initialization_or_destruction): Likewise.
+ (finish_static_initialization_or_destruction): Likewise.
+ (mark_used): Adjust logic for deciding when to synthesize methods.
+ * dump.c (dequeue_and_dump): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ * error.c (dump_function_decl): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ * friend.c (is_friend): Likewise.
+ (add_friends): Remove.
+ (do_friend): Use SET_DECL_FRIEND_CONTEXT.
+ * lex.c (begin_definition_of_inclass_inline): Use
+ decl_function_context, not hack_decl_function_context.
+ (process_next_inline): Likewise.
+ (do_identifier): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
+ * method.c (set_mangled_name_for_decl): Use DECL_CONTEXT, not
+ DECL_CLASSS_CONTEXT.
+ (hack_identifier): Likewise.
+ (synthesize_method): Use decl_function_context, not
+ hack_decl_function_context.
+ * pt.c (template_class_depth_real): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (is_member_template): Use decl_function_context, not
+ hack_decl_function_context. Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ (build_template_decl): Set DECL_VIRTUAL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ (check_default_tmpl_args): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (push_template_decl_real): Likewise.
+ (instantiate_class_template): Don't call add_friends.
+ (tsubst_default_argument): Use DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (tsubst_decl): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
+ Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (set_meangled_name_for_template_decl): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ * repo.c (repo_inline_used): Likewise.
+ * search.c (current_scope): Adjust for new _CONTEXT macros.
+ (context_for_name_lookup): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (friend_accessible_p): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (lookup_fnfields_here):Likewise.
+ (check_final_overrider): Likewise.
+ (init_vbase_pointers): Likewise.
+ (virtual_context): Likewise.
+ * semantics.c (finish_member_declaration): Just set DECL_CONTEXT.
+ (expand_body): Use decl_function_context, not
+ hack_decl_function_context.
+ * tree.c (hack_decl_function_context): Remove.
+ * typeck.c (build_x_function_call): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ * typeck2.c (error_not_base_type): Likewise.
+
+2000-02-15 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (xref_tag): Don't SET_IDENTIFIER_NAMESPACE_VALUE.
+
+2000-02-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (g++spec.o): Depend on $(GCC_H), not gcc.h.
+
+2000-02-15 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * lang-specs.h: Add new __GNUC_PATCHLEVEL__ define to default spec.
+
+2000-01-16 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Enable automatic line wrapping.
+
+2000-02-13 Jason Merrill <jason@casey.cygnus.com>
+
+ * parse.y (frob_specs): Split out...
+ (parse_decl): From here.
+ (fn.def2): Call initial_deferred_type_access_control.
+ (after_type_component_declarator0): Call frob_specs.
+ (notype_component_declarator0): Likewise.
+ * search.c (friend_accessible_p): Nested classes are friends of their
+ enclosing classes.
+
+2000-02-10 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi (ADDR_EXPR): Document the fact that an ADDR_EXPR can be
+ used to create an implicit temporary.
+
+ * class.c (dfs_modify_vtables): Tweak calculation of functions to
+ override.
+
+2000-02-08 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (strip_all_pointer_quals): Use TYPE_MAIN_VARIANT, to
+ strip array element qualifiers too.
+
+2000-02-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (store_parm_decls): Don't build cleanups for parameters
+ while processing_template_decl.
+
+2000-02-07 Jason Merrill <jason@casey.cygnus.com>
+
+ * cp-tree.h (struct saved_scope): Add incomplete field.
+ (namespace_scope_incomplete): New macro.
+ * decl.c (pushdecl): Use it.
+ (hack_incomplete_structures): Use it. See through artificial
+ binding levels.
+ (mark_saved_scope): Mark it.
+
+ Implement access control for nested types.
+ * search.c (type_access_control): New fn.
+ (accessible_p): Now we do perform access control for types.
+ * semantics.c (deferred_type_access_control): New fn.
+ (initial_deferred_type_access_control): New fn.
+ (begin_function_definition): Call it. Add lookups parm.
+ * decl.c (struct binding_level): Add this_class field.
+ (pushlevel_class): Set it.
+ (mark_binding_level): Mark it.
+ (lookup_name_real): Use it. Call type_access_control.
+ (mark_saved_scope): Mark lookups field.
+ * cp-tree.h (flagged_type_tree): Add lookups field.
+ (struct saved_scope): Add lookups field.
+ (type_lookups): New macro.
+ * parse.y (declmods): Now <ftype>.
+ (parse_decl): Add lookups parm. Call
+ initial_deferred_type_access_control.
+ (lang_extdef): Clear type_lookups.
+ (typed_declspecs, declmods, typespec): Set lookups field.
+ (initdcl): Call deferred_type_access_control.
+ (fn.def1, fn.def2, typed_declspecs1, initdcl0_innards, nomods_initdcl0,
+ component_decl_1, named_parm): Adjust.
+ * friend.c (is_friend): Nested classes are friends of their
+ enclosing classes.
+
+ * class.c (currently_open_derived_class): New fn.
+ * method.c (hack_identifier): Use it.
+
+ * lex.c (do_identifier): Remove obsolete code.
+
+ * parse.y (typed_typespecs): Propagate new_type_flag properly.
+
+2000-02-05 Zack Weinberg <zack@wolery.cumb.org>
+
+ * tinfo.h: Remove apostrophes from C++ comment (xgettext
+ thinks this file is plain C).
+
+2000-02-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (call.o): Depend on $(EXPR_H).
+
+ * call.c: Include "expr.h".
+
+ * class.c (dump_class_hierarchy): Add prototype.
+
+ * search.c (dfs_get_pure_virtuals): Likewise.
+
+2000-02-1 Ulrich Drepper <drepper@redhat.com>
+
+ * parse.y (simple_stmt): Allow :: token in asm parameter list.
+ * parse.c: Rebuilt.
+
+2000-01-31 Jim Wilson <wilson@cygnus.com>
+
+ * class.c (build_vtbl_or_vbase_field): New parameter fcontext.
+ Store it in DECL_FCONTEXT.
+ (build_vbase_pointer_fields, create_vtable_ptr): Fix callers.
+
+2000-01-31 Jason Merrill <jason@casey.cygnus.com>
+
+ * tinfo.h (old abi): #include "tconfig.h".
+ * tinfo.cc (convert_to_base): Move into old abi section.
+
+2000-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BINFO_VIRTUALS): Tweak documentation.
+ (CLASSTYPE_PRIMARY_BINFO): Use BINFO_PRIMARY_BINFO.
+ (BINFO_PRIMARY_BINFO): New macro.
+ (BF_DELTA): Rename to ...
+ (BV_DELTA): ... this.
+ (BF_VCALL_INDEX): Rename to ...
+ (BV_VCALL_INDEX): ... this.
+ (BF_FN): Rename to ...
+ (BV_FN): ... this.
+ * class.c (build_vbase_path): Adjust for changes to reverse_path.
+ (set_rtti_entry): Rename BF_ macros to BV_ variants.
+ (modify_vtable_entry): Simplify.
+ (add_virtual_function): Rename BF_ macros to BV_ variants.
+ (build_vtable_initializer): Likewise.
+ (get_class_offset_1): Remove.
+ (dfs_get_class_offset): Likewise.
+ (get_class_offset): Likewise.
+ (dfs_find_final_overrider): New function.
+ (find_final_overrider): Likewise.
+ (modify_one_vtable): Remove.
+ (dfs_find_base): New function.
+ (dfs_modify_vtables): Fold modify_one_vtable in here. Use
+ find_final_overrider.
+ (modify_all_vtables): Adjust. Set BV_VCALL_INDEX on new
+ virtuals.
+ (dfs_fixup_vtable_deltas): Remove.
+ (override_one_vtable): Remove.
+ (merge_overrides): Likewise.
+ (layout_virtual_bases): Make sure BINFO_OFFSET is set right for
+ unreal chilren of virtual bases.
+ (finish_struct_1): Don't use merge_overrides. Don't use
+ dfs_fixup_vtable_deltas.
+ * tree.c (reverse_path): Return a TREE_LIST, not a chain of
+ BINFOs.
+
+2000-01-31 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+ Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo.h: Rename USItype to myint32, depend on BITS_PER_UNIT.
+
+2000-01-31 Alfred Minarik <a8601248@unet.univie.ac.at>
+
+ * exception.cc (__throw_bad_typeid): Add missing std::.
+
+2000-01-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (make_thunk): PROTO -> PARAMS.
+
+2000-01-31 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (new_abi_rtti_p): Use flag_new_abi.
+
+ Runtime support for new-abi rtti.
+ * inc/typeinfo (type_info::operator!=): Define in class.
+ (type_info::before, type_info::name, type_info::operator==,
+ type_info::operator!=): Define new ABI implementations.
+ (type_info::is_pointer_p, type_info::is_function_p): Declare
+ new virtual functions.
+ (type_info::do_catch, type_info::do_upcast): Likewise.
+
+ * tinfo.h (__base_class_info): Define new class.
+ (__class_type_info): Likewise.
+ (__si_class_type_info): Likewise.
+ (__vmi_class_type_info): Likewise.
+ (__dynamic_cast): Prototype.
+
+ * tinfo.cc: Conditionalize old and new rtti mechanisms.
+ (type_info::is_pointer_p): Define new function.
+ (type_info::is_function_p): Likewise.
+ (type_info::do_catch): Likewise.
+ (type_info::do_upcast): Likewise.
+ (vtable_prefix): New structure for vtable access.
+ (adjust_pointer): Define new template function.
+ (contained_p, public_p, virtual_p, contained_public_p,
+ contained_nonpublic_p, contained_nonvirtual_p): Define new
+ functions.
+ (nonvirtual_base_type): New local variable.
+ (__class_type_info::~__class_type_info): Define.
+ (__si_class_type_info::~__si_class_type_info): Likewise.
+ (__vmi_class_type_info::~__vmi_class_type_info): Likewise.
+ (__class_type_info::do_catch): Define new function.
+ (__class_type_info::do_upcast): Likewise.
+ (__class_type_info::find_public_src): Likewise.
+ (__class_type_info::do_find_public_src): Likewise.
+ (__si_class_type_info::do_find_public_src): Likewise.
+ (__vmi_class_type_info::do_find_public_src): Likewise.
+ (__class_type_info::do_dyncast): Likewise.
+ (__si_class_type_info::do_dyncast): Likewise.
+ (__vmi_class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_upcast): Likewise.
+ (__si_class_type_info::do_upcast): Likewise.
+ (__vmi_class_type_info::do_upcast): Likewise.
+ (__dynamic_cast): Likewise.
+
+ * tinfo2.cc (__fundamental_type_info): Define new class.
+ (__pointer_type_info): Likewise.
+ (__reference_type_info): Likewise.
+ (__array_type_info): Likewise.
+ (__function_type_info): Likewise.
+ (__enum_type_info): Likewise.
+ (__ptr_to_member_type_info): Likewise.
+ (__fundamental_type_info::~__fundamental_type_info): Define.
+ (__pointer_type_info::~__pointer_type_info): Likewise.
+ (__reference_type_info::~__reference_type_info): Likewise.
+ (__array_type_info::~__array_type_info): Likewise.
+ (__function_type_info::~__function_type_info): Likewise.
+ (__enum_type_info::~__enum_type_info): Likewise.
+ (__ptr_to_member_type_info::~__ptr_to_member_type_info): Likewise.
+ (__pointer_type_info::do_catch): Define new function.
+ (__ptr_to_member_type_info::do_catch): Define new function.
+
+ (__throw_type_match_rtti_2): Use new ABI interface, if enabled.
+ (__is_pointer): Likewise.
+
+ * exception.cc (__cplus_type_matcher): Deal with new-abi rtti.
+
+2000-01-30 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/class.c (build_vtable): Rename to build_primary_vtable.
+ (prepare_fresh_vtable): Rename to build_secondary_vtable.
+ (make_new_vtable): New function.
+ (modify_vtable_entry): Handle generation of new vtables correctly.
+ (modify_one_vtable): Remove unused parameter.
+ (dfs_fixup_vtable_deltas): Likewise.
+ (override_one_vtable): Use build_secondary_vtable.
+ (finish_struct_1): Use build_primary_vtable and
+ build_secondary_vtable.
+
+2000-01-28 Ulrich Drepper <drepper@redhat.com>
+
+ * cp/decl.c: Adjust variable names, comments, help strings.
+
+2000-01-29 Nathan Sidwell <nathan@acm.org>
+
+ * new2.cc (operator delete[]): Use operator delete, don't assume
+ implementation.
+
+2000-01-29 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Add argument to
+ build_vtable_entry call.
+
+2000-01-27 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (THUNK_DECL): Discuss vcall indices.
+ * cp-tree.h (BINFO_VIRTUALS): Update documentation.
+ (BF_DELTA): New macro.
+ (BF_VCALL_INDEX): Likewise.
+ (BF_FN): Likewise.
+ (THUNK_VCALL_OFFSET): Likewise.
+ (make_thunk): Change prototype.
+ * class.c (build_vtable_entry): Integrate
+ build_vtable_entry_for_fn. Handle vcall indices.
+ (build_vtable_entry_for_fn): Remove.
+ (set_rtti_entry): Handle vcall indices. Use BF_DELTA,
+ BF_VCALL_INDEX, BF_FN.
+ (modify_vtable_entry): Integrate common code from
+ modify_one_vtable and dfs_fixup_vtable_deltas.
+ (add_virtual_function): Set BF_VCALL_INDEX.
+ (build_vtbl_initializer): Simplify. Use BF_DELTA, BF_VCALL_INDEX,
+ and BF_FN.
+ (modify_one_vtable): Simplify.
+ (dfs_fixup_vtable_deltas): Likewise.
+ (override_one_vtable): Use BF_DELTA, BF_VCALL_INDEX, BF_FN.
+ * method.c (make_thunk): Handle vcall indices.
+
+2000-01-28 Nathan Sidwell <sidwell@codesourcery.com>
+
+ Compiler side new abi rtti (not enabled).
+ * cp-tree.h (new_abi_rtti_p): New macro.
+ (emit_support_tinfos): Prototype new function.
+ (tinfo_decl_p): Likewise.
+ (emit_tinfo_decl): Likwise.
+ * rtti.c (TINFO_PSEUDO_TYPE, TINFO_VTABLE_DECL): New accessor
+ macros.
+ (doing_runtime): New local static.
+ (init_rtti_processing): Add new-abi initializer.
+ (get_tinfo_decl): Add new-abi logic.
+ (tinfo_from_decl): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ (qualifier_flags): New static function.
+ (tinfo_base_init): Likewise.
+ (generic_initializer): Likewise.
+ (ptr_ref_initializer): Likewise.
+ (ptmd_initializer): Likewise.
+ (class_hint_flags): Likewise.
+ (class_initializer): Likewise.
+ (synthesize_tinfo_var): Likewise.
+ (create_real_tinfo_var): Likewise.
+ (create_pseudo_type_info): Likewise.
+ (get_vmi_pseudo_type_info): Likewise.
+ (create_tinfo_types): Likewise.
+ (emit_support_tinfos): New global function.
+ (tinfo_decl_p): New global predicate.
+ (emit_tinfo_decl): New global function.
+ * class.c (set_rtti_entry): Generalize for old and new rtti.
+ (build_vtbl_initializer): Likewise.
+ * decl2.c (finish_file): Likewise.
+
+2000-01-27 Jim Wilson <wilson@cygnus.com>
+
+ * optimize.c (remap_decl): Add walk_tree calls for DECL_SIZE (t)
+ and TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t))).
+
+2000-01-27 Mike Stump <mrs@wrs.com>
+
+ * decl.c (pushdecl): Fix up shadow warnings with respect to implicit
+ for scopes.
+
+2000-01-26 Jason Merrill <jason@casey.cygnus.com>
+
+ * pt.c (unify): Use fold, not maybe_fold_nontype_arg.
+
+2000-01-26 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * optimize.c (calls_setjmp_r): Supply new argument
+ to special_function_p.
+
+2000-01-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c: PROTO -> PARAMS.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * decl.c: Likewise.
+ * decl.h: Likewise.
+ * decl2.c: Likewise.
+ * dump.c: Likewise.
+ * errfn.c: Likewise.
+ * error.c: Likewise.
+ * except.c: Likewise.
+ * expr.c: Likewise.
+ * init.c: Likewise.
+ * input.c: Likewise.
+ * lex.c: Likewise.
+ * lex.h: Likewise.
+ * method.c: Likewise.
+ * optimize.c: Likewise.
+ * parse.y: Likewise.
+ * pt.c: Likewise.
+ * repo.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+ * xref.c: Likewise.
+
+2000-01-25 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Remove UNNE_EXPR.
+
+2000-01-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (vcall_offset_in_vtable_p): New macro.
+ * class.c (build_vbase_offset_vtbl_entries): Fix typo in commment.
+ (struct vcall_offset_data_s): New type.
+ (dfs_vcall_offset_queue_p): New function.
+ (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (build_vcall_offset_vtbl_entries): Likewise.
+ (layout_vtable_decl): Likewise.
+ (num_vfun_entries): Likewise.
+ (num_extra_vtbl_entries): Add the entries for vcall offsets.
+ (build_vtbl_initializer): Likewise.
+ (dfs_finish_vtabls): Use layout_vtable_decl.
+ (modify_one_vtables): Always duplicate vtables under the new ABI.
+ (finish_struct_1): Use layout_vtable_decl.
+
+2000-01-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (member_function_or_else): Change third arg from a format
+ specifier to an `enum overload_flags'. Callers changed.
+
+2000-01-25 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * typeck.c (composite_pointer_type, c_sizeof, expr_sizeof,
+ build_binary_op_nodefault, build_unary_op, build_reinterpret_cast,
+ build_const_cast, get_delta_difference, check_return_expr): Avoid
+ ANSI string concatenation usage.
+
+2000-01-24 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Put the fields required to make a
+ class non-empty at the end, not the beginning, of the TYPE_FIELDs
+ list.
+
+2000-01-24 Jason Merrill <jason@casey.cygnus.com>
+
+ * pt.c (maybe_fold_nontype_arg): Do nothing if we're not in a
+ template.
+
+ * decl2.c (mark_used): Do instantiate inlines that have been
+ explicitly instantiated.
+
+2000-01-24 Richard Henderson <rth@cygnus.com>
+
+ * call.c (build_over_call): Use expand_tree_builtin.
+ * typeck.c (build_function_call_real): Likewise.
+ (build_binary_op_nodefault): Handle unordered compares.
+
+2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (CPTI_BAD_CAST, CPTI_BAD_TYPEID, CPTI_DCAST): New
+ cp_tree_index values.
+ (throw_bad_cast_node, throw_bad_typeid_node, dynamic_cast_node):
+ New global node #defines for them.
+ * rtti.c (call_void_fn): Replace with ...
+ (build_runtime_decl): ... new static function.
+ (throw_bad_cast): Use throw_bad_cast_node and build_runtime_decl.
+ (throw_bad_typeid): Use throw_bad_typeid_node and build_runtime_decl.
+ (build_dynamic_cast_1): Always produce correctly typed result.
+ Explicitly produce type_info addresses. Use dynamic_cast_node.
+ * exception.cc (__throw_bad_cast): Return `void *'.
+ (__throw_bad_typeid): Return `const type_info &'.
+
+2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (get_vtable_decl): Prototype new function.
+ * class.c (get_vtable_decl): New function. Broken out from ...
+ (build_vtable): ... here. Use it.
+ * decl2.c (finish_vtable_vardecl): Ignore dummy vtables created
+ by get_vtable_decl.
+
+2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (CPTI_TP_DESC_TYPE, CPTI_ACCESS_MODE_TYPE,
+ CPTI_USER_DESC_TYPE, CPTI_CLASS_DESC_TYPE, CPTI_ATTR_DESC_TYPE,
+ CPTI_PTMF_DESC_TYPE): Remove cp_tree_index enumerations.
+ (CPTI_TI_DESC_TYPE, CPTI_REF_DESC_TYPE, CPTI_ARY_DESC_TYPE,
+ CPTI_ENUM_DESC_TYPE, CPTI_CLASS_DESC_TYPE, CPTI_SI_CLASS_DESC_TYPE,
+ CPTI_VMI_CLASS_DESC_TYPE, CPTI_BASE_DESC_TYPE): New enumerations.
+ (CPTI_TINFO_FN_ID, CPTI_TINFO_FN_TYPE): Rename to ...
+ (CPTI_TINFO_DECL_ID, CPTI_TINFO_DECL_TYPE): ... here.
+ (CPTI_TINFO_VAR_ID): New enumeration.
+ (__tp_desc_type_node, __access_mode_type_node,
+ __bltn_desc_type_node, __user_desc_type_node,
+ __class_desc_type_node, __ptr_desc_type_node,
+ __attr_desc_type_node, __func_desc_type_node,
+ __ptmf_desc_type_node, __ptmd_desc_type_node): Remove #defines.
+ (ti_desc_type_node, bltn_desc_type_node, ptr_desc_type_node,
+ ref_desc_type_node, ary_desc_type_node, func_desc_type_node,
+ enum_desc_type_node, class_desc_type_node,
+ si_class_desc_type_node, vmi_class_desc_type_node,
+ ptmd_desc_type_node, base_desc_type_node): New #defines.
+ (tinfo_fn_id, tinfo_fn_type): Rename to ...
+ (tinfo_decl_id, tinfo_decl_type): ... here. Adjust.
+ (tinfo_var_id): New enumeration.
+ (DECL_TINFO_FN_P): Augment comment.
+ * decl.c (cp_global_trees): Adjust documentation.
+ * rtti.c (init_rtti_processing): Adjust for tinfo_decl_id,
+ tinfo_decl_type and tinfo_var_id.
+ (get_tinfo_decl_dynamic): Adjust for tinfo_decl_type.
+ (build_typeid): Remove unused variable.
+ (get_tinfo_var): Use tinfo_var_id.
+ (tinfo_name): New static function.
+ (get_tinfo_decl): Adjust for tinfo_decl_id and tinfo_decl_type.
+ (tinfo_from_decl): Likewise.
+ (get_base_offset): New static function, broken out of
+ expand_class_desc.
+ (expand_si_desc): Use tinfo_name.
+ (expand_class_desc): Likewise. Lose local static variable.
+ Use base_desc_type_node. Use get_base_offset.
+ (expand_ptr_desc): Use tinfo_name.
+ (expand_attr_desc): Likewise.
+ (expand_generic_desc): Likewise.
+
+ * tinfo.cc (__GXX_ABI_VERSION): Test value and existence.
+ * tinfo.h (__GXX_ABI_VERSION): Test value and existence.
+
+2000-01-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (__eprintf): Remove declaration.
+ * tree.c (__eprintf): Remove definition.
+
+2000-01-23 Zack Weinberg <zack@rabi.columbia.edu>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_MARKED_N, SET_CLASSTYPE_MARKED_N,
+ CLEAR_CLASSTYPE_MARKED_N): Avoid signed vs. unsigned warnings.
+
+2000-01-23 Brad Lucier <lucier@math.purdue.edu>
+
+ * class.c (dump_class_hierarchy): Print HOST_WIDE_INT properly.
+
+2000-01-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (register_dtor_fn): New function.
+ * decl.c (destroy_local_static): Rename to ...
+ (register_dtor_fn): ... this. Give it external linkage.
+ (expand_static_init): Use it.
+ * decl2.c (do_static_initialization): Likewise, if using
+ __cxa_atexit.
+ (do_static_destruction): Check that __cxa_atexit is not in use.
+ (finish_file): Don't call do_static_destruction if using
+ __cxa_atexit.
+
+ * typeck.c (convert_arguments): Restore two-message error
+ reporting.
+
+2000-01-20 Nathan Sidwell <sidwell@codesourcery.com>
+
+ Remap dynamic cast hint values to be consistent across ABIs.
+ * search.c (dynamic_cast_base_recurse): Remap generated value.
+ (get_dynamic_cast_base_type): Adjust documentation.
+ * tinfo.h (__user_type_info::dyncast): Likewise.
+ (__user_type_info::find_public_subobj): Remap BOFF meaning.
+ * tinfo.cc (__si_type_info::do_dyncast): Remap BOFF meaning.
+ (__class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_find_public_subobj): Likewise.
+ * tinfo2.cc (__dynamic_cast): Remap BOFF parameter.
+
+2000-01-19 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * typeck.c (build_unary_op): Use cp_pedwarn, not pedwarn.
+
+ * typeck2.c (incomplete_type_error): Restore previous
+ cp_error and cp_error_at call sequence.
+
+2000-01-20 Brad Lucier <lucier@math.purdue.edu>
+
+ * class.c (dump_class_hierarchy): Make format agree with argument;
+ cast pointer to unsigned long and print with %lx.
+
+2000-01-19 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Set default line-wrap length to 72.
+
+ * typeck.c (composite_pointer_type, common_type,
+ comp_target_parms, c_sizeof, expr_sizeof, build_array_ref,
+ build_function_call_real, convert_arguments,
+ build_binary_op_nodefault, pointer_int_sum, pointer_diff,
+ build_unary_op, mark_addressable, build_compound_expr,
+ build_static_cast, build_reinterpret_cast, build_const_cast,
+ build_c_cast, build_modify_expr, get_delta_difference,
+ build_ptrmemfunc, check_return_expr): Replace 'ANSI C++' with
+ 'ISO C++'. Fusion consecutive calls to diagnostic message routines
+ into a single one.
+ * typeck2.c (readonly_error, abstract_virtuals_error,
+ process_init_constructor, check_for_new_type): Likewise.
+
+2000-01-19 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (bot_manip): Set DECL_CONTEXT for newly created
+ VAR_DECLs.
+
+2000-01-18 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (get_tinfo_fn_dynamic): Remove prototype.
+ (build_x_typeid): Likewise.
+ (get_tinfo_fn): Likewise.
+ (get_tinfo_fn_unused): Rename to ...
+ (get_tinfo_decl): ... here.
+ * rtti.c (build_headof): Replace logic error with assertion.
+ (get_tinfo_fn_dynamic): Rename to ...
+ (get_tinfo_decl_dynamic): ... here. Make static. Use
+ complete_type_or_else.
+ (build_x_typeid): Move into ...
+ (build_typeid): ... here. Adjust call to
+ get_tinfo_decl_dynamic. Use tinfo_from_decl. Simplify
+ throw_bad_typeid expression.
+ (get_tinfo_fn_unused): Rename to ...
+ (get_tinfo_decl): ... here. Adjust comment.
+ (get_tinfo_fn): Delete.
+ (tinfo_from_decl): New static function.
+ (get_typeid_1): Call get_tinfo_decl and tinfo_from_decl.
+ (get_typeid): Use complete_type_or_else.
+ (build_dynamic_cast_1): Adjust calls to
+ get_tinfo_decl_dynamic. Simplify throw_bad_cast expression.
+ * parse.y (primary): Adjust call to build_typeid.
+ * except.c (build_eh_type_type_ref): Adjust call to
+ get_tinfo_decl. Mark as used.
+ * class.c (set_rtti_entry): Adjust call to get_tinfo_decl.
+ * decl2.c (build_expr_from_tree): Adjust call to build_typeid.
+ * parse.c: Regenerated.
+
+2000-01-17 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (fixed_type_or_null): Don't clear NONNULL. Document
+ calling convention.
+ (resolves_to_fixed_type_p): Document calling convention.
+ * rtti.c (build_x_typeid): Initialize NONNULL.
+
+ * cp-tree.h (build_shared_int_cst): New function.
+ * call.c (build_over_call): Use DECL_VIRTUAL_CONTEXT, for clarity.
+ * class.c (modify_vtable_entry): Likewise.
+ (add_virtual_function): Split out code to generated shared
+ INTEGER_CSTs to build_share_int_cst.
+ (modify_all_vtables): Handle all the overridden functions here.
+ Add overridden functions from non-primary virtual bases to the
+ primary vtable.
+ (finish_struct_1): Adjust call to modify_all_vtables. Add
+ overridden functions from non-primary bases to the vtable.
+ * tree.c (build_shared_int_cst): New function.
+
+ * cp-tree.h (scratchalloc): Remove.
+ (build_scratch_list): Likewise.
+ * call.c (convert_class_to_reference): Replace build_scratch_list
+ and build_expr_list with build_tree_list.
+ (add_candidate): Replace scratchalloc with expralloc. Note memory
+ leak.
+ (build_user_type_conversion_1): Replace build_scratch_list
+ and build_expr_list with build_tree_list.
+ (build_new_op): Likewise.
+ (build_op_delete_call): Likewise.
+ (convert_like): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ * decl.c (start_decl): Likewise.
+ (start_function): Likewise.
+ (finish_destructor_body): Likewise.
+ (maybe_build_cleanup_1): Likewise.
+ * decl2.c (reparse_decl_as_expr): Likewise.
+ * init.c (perform_member_init): Likewise.
+ (expand_cleanup_for_base): Likewise.
+ (build_builtin_delete_call): Likewise.
+ (build_new_1): Likewise.
+ (build_delete): Likewise.
+ * method.c (do_build_assign_ref): Likewise.
+ * parse.y (already_scoped_stmt): Likewise.
+ (nontrivial_exprlist): Likewise.
+ (net_initializer): Likewise.
+ (initlist): Likewise.
+ * parse.c: Regenerated.
+ * rtti.c (build_x_typeid): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ * typeck.c (build_x_compound_expr): Likewise.
+ (build_static_cast): Likewise.
+ (build_modify_expr): Likewise.
+
+ * cp-tree.h (DECL_VINDEX): Add documentation.
+ * class.c (build_vtable_entry): Likewise.
+ (start_vtable): Add comment.
+ (add_virtual_function): Replace pending_hard_virtuals with
+ overridden_virtuals and pending_virtuals with new_virtuals.
+ Replace redundant assignments with assertions.
+ (check_for_override): Add comment.
+ (check_bases_and_members): Replace pending_hard_virtuals with
+ overridden_virtuals and pending_virtuals with new_virtuals.
+ (create_vtbl_ptr): Likewise.
+ (layout_class_type): Likewise.
+ (finish_struct_1): Likewise. Add comments.
+
+2000-01-16 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (finish_struct_1): Replace redundant code with
+ assertions.
+
+ * cp-tree.h (flag_new_abi): Move.
+ (flag_use_cxa_atexit): Likewise.
+ (flag_honor_std): Likewise.
+ (flag_rtti): Likewise.
+ (vbase_offsets_in_vtable_p): Define.
+ (vptrs_present_everywhere_p): Likewise.
+ (TYPE_CONTAINS_VPTR_P): Likewise.
+ (dfs_walk_real): Declare.
+ * class.c (build_vbase_pointer_fields): Check
+ vbase_offsets_in_vtable_p.
+ (dfs_build_vbase_offset_vtbl_entries): Record the vbase indices in
+ BINFO_VPTR_FIELD.
+ (build_vbase_offset_vtbl_entries): Simplify.
+ (build_vbase_offset_vtbl_entries): Adjust.
+ (build_vbase_pointer): Add ability to look up vbase offsets in
+ vtable.
+ (start_vtable): New function.
+ (add_virtual_function): Use it.
+ (determine_primary_base): Use TYPE_CONTAINS_VPTR_P.
+ (num_extra_vtbl_entries): Use vbase_offsets_in_vtable_p.
+ (build_vtbl_initializer): Take the type of the complete object as
+ input. Use it to correctly calculate vbase offsets.
+ (dfs_finish_vtbls): Pass the complete type to
+ build_vtbl_initializer.
+ (check_bases_and_members): Use TYPE_CONTAINS_VPTR_P.
+ (create_vtable_ptr): Create a vtable even if there are no
+ new virtual functions, under the new ABI.
+ (finish_struct_1): Likewise.
+ (get_vfield_name): Use TYPE_CONTAINS_VPTR_P.
+ * decl.c (exapnd_static_init): Remove call to
+ preserve_initializer.
+ * decl2.c (mark_vtable_entries): Tweak to handle vbase offsets in
+ vtables.
+ * init.c (initialize_vtbl_ptrs): Initialize them in pre-order.
+ (expand_virtual_init): Use vbase_offsets_in_vtable_p.
+ (construct_virtual_bases): Don't initialize virtual base pointers
+ under the new ABI.
+ (build_aggr_init): Clean up comment.
+ (expand_aggr_init_1): Likewise.
+ * rtti.c (expand_class_desc): Store the virtual function table
+ index where the vbase offset lives in the offset field.
+ * search.c (dfs_walk_real): Make it global.
+ (dfs_debug_mark): Use TYPE_CONTAINS_VPTR_P.
+ * tree.c (make_binfo): Don't clear BINFO_VPTR_FIELD.
+
+ * tinfo.h (USItype): Make it signed under the new ABI.
+ * tinfo.cc (convert_to_base): New function. Encapsulate base
+ conversion logic here.
+ (__class_type_info::do_upcast): Use it.
+ (__class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_find_public_subobj): Likewise.
+
+ * init.c (construct_virtual_bases): Don't look up the addresses of
+ virtual bases at run-time.
+
+ * class.c (build_vbase_pointer): Relocate.
+ (build_vbase_pointer_fields): Likewise.
+ (dfs_build_vbase_offset_vtbl_entries): Likewise.
+ (build_vbase_offset_vtbl_entries): Likewise.
+
+ * decl.c (init_decl_processing): Complain if -fnew-abi
+ -fno-vtable-thunks is used.
+
+ * decl2.c (lang_decode_option): Don't couple flag_honor_std to
+ flag_new_abi.
+
+2000-01-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (num_extra_vtbl_entries): New function.
+ (size_extra_vtbl_entries): Likewise.
+ (dfs_vtable_path_unmark): Likewise.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): Likewise.
+ (dfs_vtable_path_marked_real_bases_queue_p): Likewise.
+ * class.c (num_extra_vtbl_entries): New function.
+ (size_extra_vtbl_entries): Likewise.
+ (dfs_build_vbase_offset_vtbl_entries): New function.
+ (build_vbase_offset_vtbl_entries): Likewise.
+ (build_vtbl_initializer): Use it.
+ (finish_struct_1): Adjust vtable sizes (using
+ num_extra_vtbl_entries).
+ * expr.c (cplus_expand_expr): Assert that the DECL_RTL for a
+ THUNK_DECL is non-NULL before expanding it.
+ * init.c (expand_virtual_init): Adjust the vtable pointer by
+ size_extra_vtbl_entries before storing it.
+ * search.c (get_shared_vase_if_not_primary): Adjust prototype.
+ Handle TREE_LIST parameters here, not in the dfs_* functions.
+ (dfs_unmarked_real_bases_queue_p): Adjust.
+ (dfs_marked_real_bases_queue_p): Likewise.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): New function.
+ (dfs_vtable_path_marked_real_bases_queue_p): New function.
+ (dfs_vtable_path_unmark): Likewise.
+
+2000-01-14 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (copy_body_r): Clear the operand three of a
+ TARGET_EXPR when copying it.
+
+2000-01-14 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * method.c (build_decl_overload_real): Check whether we are in ::
+ before returning __builtin_new/delete.
+
+2000-01-13 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_friend_function): Improve comment.
+ (instantiate_decl): Avoid crashing when a "nested" function is
+ instantiated from the top level.
+
+ * dump.c (dqeueue_and_dump): Dump
+ DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION.
+
+2000-01-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c: If GATHER_STATISTICS, declare `n_build_method_call'.
+
+2000-01-13 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * g++spec.c (lang_specific_driver): Add -fnew-abi if
+ ENABLE_NEW_GXX_ABI defined.
+ * Make-lang.in (tinfo.o, tinfo2.o, exception.o, new.o,
+ opnew.o, opnewnt.o, opvnew.o, opvnewnt.o, opdel.o, opdelnt.o,
+ opvdel.o, opvdelnt.o): Use GXX_ABI_FLAG switch.
+
+2000-01-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_cleanup_fn): Call pushdecl.
+
+ * call.c (convert_class_to_reference): Fix typos.
+ (build_conditional_expr): Handle errors gracefully.
+ * class.c (push_nested_class): Likewise.
+ * cp-tree.h (VAR_FUNCTION_OR_PARM_DECL_CHECK): New macro.
+ (DECL_THIS_EXTERN): Use it.
+ (DECL_THIS_STATIC): Likewise.
+ * cvt.c (convert_to_void): Handle errors gracefully.
+ (build_expr_type_conversion): Likewise.
+ * decl.c (maybe_push_decl): Likewise.
+ (start_decl_1): Likewise.
+ (require_complete_types_for_parms): Likewise.
+ * parse.y (structsp): Likewise.
+ (base_class): Likewise.
+ * parse.c: Regenerated.
+ * pt.c (finish_member_template_decl): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+
+ * cp-tree.h (dfs_skip_vbases): New function.
+ (find_vbase_instance): Likewise.
+ * class.c (determine_primary_base): Allow a nearly empty base to
+ serve as a primary base class under the new ABI.
+ (get_class_offset_1): Rename to ...
+ (dfs_get_class_offset): ... this. Simplify. Don't issue error
+ messages here.
+ (get_class_offset): Use it. Issue error messages here.
+ (dfs_modify_vtables): Rely on dfs_unmarked_real_bases_queue_p to
+ find the right copies of virtual bases.
+ (fixup_vtable_deltas1): Rename to ...
+ (dfs_fixup_vtable_deltas): ... this. Adjust to handle virtual
+ bases as primary bases.
+ (fixup_vtable_deltas): Remove.
+ (override_one_vtable): Handle virtual bases as primary bases.
+ (merge_overrides): Likewise.
+ (finish_struct_1): Likewise.
+ (dump_class_hierarchy): Dump primary-ness of bases as well.
+ * search.c (mark_primary_bases): Use a pre-order traversal to
+ handle primary virtual bases.
+ (dfs_skip_vbases): New fiunction.
+ (expand_upcast_fixups): Adjust to handle primary virtual bases.
+ (fixup_virtual_upcast_offsets): Likewise.
+ (fixup_all_virtual_upcast_offsets): Likewise.
+ (dfs_find_vbase_instances): New function.
+ (find_vbase_instance): Likewise.
+
+2000-01-11 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * lex.c (DIR_SEPARATOR): Delete macro.
+
+2000-01-12 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Handle automatic line wrapping
+ option.
+
+2000-01-11 Mark Mitchell <mark@codesourcery.com>
+
+ * friend.c (do_friend): Don't resolve scopes when processing
+ template declarations, even if the qualifying scope doesn't
+ involve template parameters.
+
+2000-01-10 Mark Mitchell <mitchell@dumbledore.codesourcery.com>
+
+ * class.c (dfs_modify_vtables_queue_p): Remove.
+ (modify_all_vtables): Use dfs_unmarked_real_bases_queue_p
+ and dfs_marked_real_bases_queue_p instead of
+ dfs_modify_vtables_queue_p.
+
+ * class.c (build_vbase_path): Simplify.
+ (dfs_propagate_binfo_offsets): New function.
+ (propagate_binfo_offsets): Use it.
+ (remove_base_field): Simplify.
+ (dfs_set_offset_for_vbases): Remove.
+ (dfs_set_offset_for_shared_vbases): New function.
+ (dfs_set_offset_for_unshared_vbases): Likewise.
+ (layout_virtual_bases): Use them.
+ (layout_basetypes): Don't call propagate_binfo_offsets.
+ * search.c (dfs_get_vbase_types): Clone completely fresh binfos
+ for the vbases.
+
+ * class.c (build_base_field): New function, split out from ...
+ (build_base_fields): ... here. Use it. Allocate primary bases
+ first, under the new ABI.
+ (get_vtable_entry): Remove.
+ (remove_base_field): New function, split out from ...
+ (remove_base_fields): ... here. Adjust since primary bases come
+ first under the new ABI.
+
+ * cp-tree.h (expand_direct_vtbls_init): Remove declaration.
+ (initialize_vtbl_ptrs): New function.
+ (expand_indirect_vtbls_init): Change prototype.
+ (convert_pointer_to_vbase): Declare.
+ * init.c (expand_direct_vtbls_init): Remove.
+ (dfs_initialize_vtbl_ptrs): New function.
+ (initialize_vtbl_ptrs): Likewise.
+ (emit_base_init): Use initialize_vtbl_ptrs.
+ * search.c (convert_pointer_to_vbase): Make it global.
+ (expand_indirect_vtbls_init): Remove vtable initialization code.
+ * semantics.c (setup_vtbl_ptr): Use initialize_vtbl_ptrs.
+
+ * class.c (dfs_finish_vtbls): New function.
+ (finish_vtbls): Use it.
+ (dump_class_hierarchy): New function.
+
+ * cp-tree.h (BINFO_PRIMARY_MARKED_P): Change definition.
+ (BINFO_VBASE_PRIMARY_P): New macro.
+ (BINFO_VIRTUALS): Add to documentation.
+ (SET_BINFO_PRIMARY_MARKED_P): Remove.
+ (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
+ (dfs_mark_primary_bases_queue_p): Likewise.
+ (dfs_unmarked_real_bases_queue_p): New function.
+ (dfs_marked_real_bases_queue_p): Likewise.
+ * search.c (dfs_mark_primary_bases): Adjust.
+ (mark_primary_bases): Likewise.
+ (get_shared_vbase_if_not_primary): New function.
+ (dfs_unmarked_real_bases_queue_p): Likewise.
+ (dfs_marked_real_bases_queue_p): Likewise.
+ (dfs_get_pure_virtuals): Simplify.
+ (get_pure_virtuals): Likewise.
+
+2000-01-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c: Include tm_p.h.
+
+2000-01-07 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * lang-specs.h (__GXX_ABI_VERSION): New preprocessor macro.
+
+2000-01-06 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl2.c (comdat_linkage): Don't set DECL_DEFER_OUTPUT.
+ * pt.c (instantiate_decl): Defer comdat templates that might not be
+ needed.
+
+ * cp-tree.h (DECL_NEEDED_P): Also true if !DECL_COMDAT.
+ * decl2.c (finish_vtable_vardecl): Don't check !DECL_COMDAT.
+ (finish_file): Likewise.
+
+ * decl2.c (import_export_class): Undo 12/14 change.
+
+ * error.c (dump_decl): operator new, not operatornew.
+
+ * class.c (field_decl_cmp): A nontype is "greater" than a type.
+ * search.c (lookup_field_1): Look for the last field with the
+ desired name.
+
+2000-01-05 Nathan Sidwell <nathan@acm.org>
+
+ * decl2.c (lookup_arg_dependent): Deal with FNS not being a
+ FUNCTION_DECL.
+
+2000-01-05 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (build_static_cast): Don't strip target qualifiers
+ when casting from a class.
+
+2000-01-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (warn_hidden): Initialize variable `fndecl'.
+
+2000-01-03 Ulrich Drepper <drepper@cygnus.com>
+
+ * decl.c (flag_isoc9x): New variable to be able to use code in
+ c-common.c. For now always zero.
+
+2000-01-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_VBASECLASSES): Improve documentation.
+ * class.c (layout_basetypes): Don't set BINFO_INHERITANCE_CHAIN
+ or unshare_base_binfos for virtual bases here.
+ * search.c (dfs_get_vbase_types): Do it here.
+ (get_vbase_types): Adjust.
+
+2000-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_VFIELDS): Move definition.
+ (BINFO_PRIMARY_MARKED_P): Use flag 5.
+ (SET_BINFO_PRIMARY_MARKED_P): Likewise.
+ (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
+ (unmark_primary_bases): Remove declaration.
+ (unmarkedp): Declare.
+ (dfs_vbase_unmark): Likewise.
+ * class.c (determine_primary_base): Return immediately if there
+ are no base classes. Call mark_primary_bases here.
+ (modify_all_direct_vtables): Remove.
+ (modify_all_indirect_vtables): Remove.
+ (dfs_modify_vtables_queue_p): New function.
+ (dfs_modify_vtables): New function.
+ (modify_all_vtables): Use them.
+ (build_base_fields): Build FIELD_DECLs for primary virtual base
+ classes.
+ (create_vtable_ptr): Don't call determine_primary_base here.
+ (dfs_mark_primary_bases_and_set_vbase_offsets): Rename to ...
+ (dfs_set_offset_for_vbases): ... this.
+ (layout_virtual_bases): Use it.
+ (layout_class_type): Call determine_primary_base here.
+ * search.c (unmarkedp): Make it global.
+ (shared_marked_p): Simplify.
+ (shared_unmarked_p): Likewise.
+ (dfs_primary_bases_queue_p): Remove.
+ (dfs_unmark_primary_bases): Likewise.
+ (unmark_primary_bases): Likewise.
+ (mark_primary_bases): Simplify.
+ (get_pure_virtuals): Don't call mark_primary_bases here.
+ (dfs_vbase_unmark): New function.
+ (get_vbase_types): Simplify.
+
+ * class.c (struct base_info): Remove.
+ (determine_primary_base): Take has_virtual_p rather than a
+ base_info as input. Don't calculate max_has_virtual.
+ (finish_struct_bits): Remove max_has_virtual argument.
+ (create_vtable_ptr): Remove max_has_virtual_p argument.
+ (layout_virtual_bases): Remove max argument.
+ (layout_basetypes): Likewise.
+ (layout_class_type): Remove max_has_virtual_p argument.
+ (finish_struct_1): Remove max_has_virtual.
+
+ * cp-tree.h (dfs_mark_primary_bases_queue_p): New function.
+ (layout_basetypes): Remove.
+ * class.c (propagate_binfo_offsets): Moved here from tree.c.
+ Update to handle primary virtual bases.
+ (remove_base_fields): New function, split out from
+ layout_basetypes.
+ (dfs_mark_primary_bases_and_set_vbase_offsets): New function.
+ (layout_virtual_bases): New function, split out from
+ layout_basetypes. Update to handle primary virtual bases.
+ (layout_basetypes): Moved here from tree.c. Use
+ remove_base_fields and layout_virtual_bases.
+ * search.c (dfs_mark_primary_bases_queue_p): New function.
+ (mark_primary_bases): Use it.
+ * tree.c (CEIL): Remove.
+ (propagate_binfo_offsets): Remove.
+ (layout_basetypes): Remove.
+
+2000-01-01 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_N_BASECLASSES): Use BINFO_N_BASETYPES.
+ (BINFO_PRIMARY_MARKED_P): New macro.
+ (SET_BINFO_PRIMARY_MARKED_P): Likewise.
+ (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
+ (mark_primary_bases): New function.
+ (unmark_primary_bases): Likewise.
+ * search.c (get_abstract_virtuals_1): Remove.
+ (dfs_mark_primary_bases): New function.
+ (mark_primary_bases): Likewise.
+ (dfs_unmark_primary_bases): Likewise.
+ (unmark_primary_bases): Likewise.
+ (dfs_get_pure_virtuals): Likewise.
+
+2000-01-01 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (skip_rtti_stuff): Adjust prototype.
+ * class.c (skip_rtti_stuff): Reorganize parameters and return value.
+ (modify_one_vtable): Adjust.
+ (fixup_vtable_deltas1): Likewise.
+ (override_one_vtable): Likewise.
+ * search.c (get_abstract_virtuals_1): Likewise.
+ (get_pure_virtuals): Likewise.
+ (expand_upcast_fixups): Likewise.
+ * tree.c (debug_binfo): Likewise.
+
+ * class.c (build_vtable): Don't return a value. Don't rebuild
+ vtables for bases that have already been handled.
+ (prepare_fresh_vtable): Don't rebuild vtables for bases that have
+ already been handled.
+ (modify_one_vtable): Adjust accordingly.
+ (fixup_vtable_deltas1): Likewise.
+ (finish_struct_1): Likewise.
+
+2000-01-01 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * call.c (build_new_method_call): Also check destructors.
+
+
+
+Copyright (C) 2000 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2001 b/gcc-4.9/gcc/cp/ChangeLog-2001
new file mode 100644
index 000000000..2bdb9f1ab
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2001
@@ -0,0 +1,3901 @@
+2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_user_type_conversion_1): Use my_friendly_assert
+ rather than if ... abort.
+ * cvt.c (convert_to_reference): Likewise.
+ * semantics.c (setup_vtbl_ptr): Likewise.
+ * pt.c (lookup_template_class): Comment typo.
+
+2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5125
+ * pt.c (push_template_decl_real): Make sure DECL has
+ DECL_LANG_SPECIFIC.
+
+2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/335
+ * init.c (resolve_offset_ref): Copy cv qualifiers of this pointer
+ for non-reference fields.
+ * typeck.c (require_complete_type): Use resolve_offset_ref).
+
+2001-12-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/196
+ * parse.y (bad_parm): Better diagnostic when given a SCOPE_REF.
+
+2001-12-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/160
+ * typeck.c (build_modify_expr): Remove old unreachable code & tidy
+ up. Don't stabilize_references when initializing a reference.
+
+2001-12-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (lang_f_options): Const-ify.
+
+2001-12-20 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * config-lang.in (diff_excludes): Remove.
+
+2001-12-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/90
+ * typeck.c (build_function_call_real): Use original function
+ expression for errors.
+
+2001-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/3242
+ * class.c (add_method): Do compare 'this' quals when trying to match a
+ used function. Don't defer to another used function.
+
+2001-12-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_clone): Remove, fold into ...
+ (instantiate_template): ... here. Simplify by removing mutual
+ recursion.
+ * typeck2.c (build_m_component_ref): Don't cv qualify the function
+ pointed to by a pointer to function.
+ * class.c (delete_duplicate_fields_1): Typo.
+
+2001-12-18 Jason Merrill <jason@redhat.com>
+
+ C++ ABI change: destroy value arguments in caller.
+ * semantics.c (genrtl_start_function, genrtl_finish_function): Don't
+ create an extra binding level for the parameters.
+ * decl.c (store_parm_decls): Don't do parameter cleanups.
+
+2001-12-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_new_method_call): Use '%#V'.
+ * error.c (cv_to_string): Use V parameter to determine padding.
+
+2001-12-18 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * call.c, decl2.c, init.c: Use "built-in" and "bit-field"
+ spellings in messages.
+
+2001-12-17 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-tree.h: Delete #defines for cp_error, cp_warning,
+ cp_pedwarn, and cp_compiler_error.
+ * call.c, class.c, cp-tree.h, cvt.c, decl.c, decl2.c, error.c,
+ except.c, friend.c, init.c, lex.c, method.c, parse.y, pt.c,
+ rtti.c, search.c, semantics.c, spew.c, tree.c, typeck.c,
+ typeck2.c: Change calls to the above macros to use their
+ language-independent equivalents: error, warning, pedwarn, and
+ internal_error respectively.
+
+2001-12-16 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c (finish_file): Remove back_end_hook.
+
+2001-12-16 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * ChangeLog.1, ChangeLog.2, ChangeLog, NEWS, call.c, class.c,
+ cp-tree.h, decl.c, decl2.c, except.c, operators.def, optimize.c,
+ pt.c, rtti.c, semantics.c, typeck.c: Fix spelling errors.
+
+2001-12-15 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * lang-options.h: Use American spelling in messages.
+
+2001-12-13 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (parse.h): Separate rule, just depend on parse.c.
+
+ Use cleanups to run base and member destructors.
+ * init.c (push_base_cleanups): New function, split out from...
+ (build_delete): ...here. Lose !TYPE_HAS_DESTRUCTOR code.
+ * decl.c (finish_destructor_body): Move vbase destruction code to
+ push_base_cleanups.
+ (begin_function_body, finish_function_body): New fns.
+ (finish_function): Move [cd]tor handling and call_poplevel to
+ finish_function_body.
+ (pushdecl): Skip the new level.
+ * semantics.c (genrtl_try_block): Don't call end_protect_partials.
+ (setup_vtbl_ptr): Call push_base_cleanups.
+ * method.c (synthesize_method): Call {begin,end}_function_body.
+ * pt.c (tsubst_expr): Handle COMPOUND_STMT_BODY_BLOCK.
+ * cp-tree.h: Declare new fns.
+ * parse.y (function_body, .begin_function_body): New nonterminals.
+ (fndef, pending_inline, function_try_block): Use function_body.
+ (ctor_initializer_opt, function_try_block): No longer has a value.
+ (base_init): Remove .set_base_init token.
+ (.set_base_init, compstmt_or_error): Remove.
+ * Make-lang.in (parse.c): Expect two fewer s/r conflicts.
+
+ * optimize.c (maybe_clone_body): Fix parameter updating.
+
+2001-12-12 Jason Merrill <jason@redhat.com>
+
+ * decl.c (store_parm_decls): Remove parms_have_cleanups cruft.
+ * semantics.c (genrtl_start_function): Don't pass
+ parms_have_cleanups or push an extra binding level.
+ (genrtl_finish_function): Lose cleanup_label cruft.
+
+ * cp-tree.h (struct cp_language_function): Remove x_ctor_label.
+ (ctor_label): Remove.
+ * semantics.c (finish_return_stmt): Lose ctor_label support.
+ * decl.c (finish_constructor_body, mark_lang_function): Likewise.
+ * typeck.c (check_return_expr): Check DECL_DESTRUCTOR_P, not
+ dtor_label.
+
+ * call.c (build_new_method_call): Let resolves_to_fixed_type_p
+ check for [cd]tors.
+ * class.c (fixed_type_or_null, case INDIRECT_REF): Fix.
+
+ * decl.c (finish_function): Check VMS_TARGET, not VMS.
+
+ * decl.c (start_cleanup_fn): Remove redundant pushlevel.
+ (end_cleanup_fn): And poplevel.
+
+ * semantics.c (setup_vtbl_ptr): Always build a CTOR_INITIALIZER
+ if we're in a template.
+
+2001-12-12 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (DESTRUCTOR_DECL_PREFIX, DESTRUCTOR_NAME_P,
+ ANON_PARMNAME_FORMAT, ANON_PARMNAME_P, DESTRUCTOR_NAME_FORMAT,
+ THIS_NAME_P): Delete.
+ * spew.c (read_process_identifier): Remove DESTRUCTOR_NAME_P,
+ THIS_NAME_P and ANON_PARMNAME_P tests from warning about clash
+ with internal naming scheme.
+ * error.c (dump_decl): Remove DESTRUCTOR_NAME_P use.
+
+2001-12-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Deprecated implicit typename use.
+
+2001-12-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/51
+ * parse.y (frob_specs): Indicate it is a language linkage which
+ contained the extern.
+ * decl.c (grokdeclarator): Allow extern language linkage with
+ other specifiers.
+
+2001-12-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/72
+ * decl.c (add_binding): Don't reject duplicate typedefs involving
+ template parameters.
+
+2001-12-10 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * parse.y, semantics.c: Similarly.
+
+2001-12-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/87
+ * cp-tree.h (DECL_COPY_CONSTRUCTOR_P): Use copy_fn_p.
+ (copy_args_p): Rename to ...
+ (copy_fn_p): ... here.
+ (grok_special_member_properties): New function.
+ (grok_op_properties): Lose VIRTUALP parameter.
+ (copy_assignment_arg_p): Remove.
+ * call.c (build_over_call): Use copy_fn_p.
+ * decl.c (grokfndecl): Reformat. Adjust call to
+ grok_op_properties.
+ (copy_args_p): Rename to ...
+ (copy_fn_p): ... here. Reject template functions. Check for pass
+ by value.
+ (grok_special_member_properties): Remember special functions.
+ (grok_ctor_properties): Don't remember them here, just check.
+ (grok_op_properties): Likewise.
+ (start_method): Call grok_special_member_properties.
+ * decl2.c (grokfield): Likewise.
+ (copy_assignment_arg_p): Remove.
+ (grok_function_init): Don't remember abstract assignment here.
+ * pt.c (instantiate_class_template): Call
+ grok_special_member_properties.
+ (tsubst_decl): Adjust grok_op_properties call.
+
+2001-12-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * lex.c (rid_to_yy): Add RID_CHOOSE_EXPR and
+ RID_TYPES_COMPATIBLE_P.
+
+2001-12-08 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Add DIRECT_BIND flag in
+ call to build_aggr_init.
+ * cp-tree.h (DIRECT_BIND): Document new use of DIRECT_BIND.
+
+2001-12-08 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * parse.y: Replace uses of the string non-terminal with STRING.
+ Don't perform string concatentaion here.
+ (string): Remove non-terminal.
+ * semantics.c (finish_asm_stmt): Don't concatenate strings here.
+
+2001-12-05 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING): Define.
+ (LANG_HOOKS_TREE_INLINING_END_INLINING): Define.
+ * tree.c (cp_start_inlining, cp_end_inlining): New fns.
+ * pt.c (push_tinst_level): No longer static.
+ * cp-tree.h: Declare them.
+
+ * init.c (resolve_offset_ref): Don't check access for the base
+ conversion to access a FIELD_DECL.
+
+ * cp-tree.h (TYPE_REFFN_P): New macro.
+ * decl.c (bad_specifiers): Check it, too.
+
+ * rtti.c (create_pseudo_type_info): Set CLASSTYPE_INTERFACE_ONLY
+ on the __*_type_info type if we haven't seen a definition.
+
+2001-12-05 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl.c: Include c-common.h.
+ (shadow_warning): Move to c-common.c.
+
+2001-12-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (duplicate_decls): Don't copy DECL_NO_CHECK_MEMORY_USAGE.
+
+2001-12-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (end_template_parm_list): Clear TREE_CHAIN of each parm.
+
+2001-12-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/164
+ * init.c (sort_base_init): Allow binfos to be directly specified.
+ * method.c (do_build_copy_constructor): Explicitly convert to the
+ base instance.
+ (do_build_assign_ref): Likewise.
+
+2001-12-03 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * decl.c (xref_basetypes): Don't use C99 construct in tag_code
+ declaration and initialization.
+
+2001-12-03 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * typeck2.c: Remove leading capital from diagnostic messages, as
+ per GNU coding standards.
+
+2001-12-03 Mumit Khan <khan@nanotech.wisc.edu>
+
+ PR c++/3394
+ * decl.c (xref_basetypes): Handle attributes between
+ 'class' and name.
+
+2001-12-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/3381
+ * parse.y (named_complex_class_head_sans_basetype): Add new
+ reduction.
+ * Make-lang.in (parse.c): Adjust expected conflict count.
+
+2001-12-03 Jason Merrill <jason@redhat.com>
+
+ * class.c (finish_vtbls): Fill in BINFO_VPTR_FIELD in the
+ immediate binfos for our virtual bases.
+
+2001-12-02 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (build_java_interface_fn_ref): Similarly.
+ * except.c (is_admissible_throw_operand): Similarly.
+ * init.c (build_java_class_ref): Similarly.
+ * xref.c (open_xref_file): Similarly.
+
+2001-12-01 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * class.c (finish_struct): Remove trailing periods from messages.
+ * decl.c (check_tag_decl): Similarly.
+ * lex.c (cxx_set_yydebug): Similarly.
+ * typeck2.c (friendly_abort): Similarly.
+
+2001-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3048
+ * cp-tree.h (ovl_member): Remove.
+ * decl2.c (merge_functions): Handle extern "C" functions
+ specially.
+ * tree.c (ovl_member): Remove.
+
+2001-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/4842
+ * class.c (get_basefndecls): Take an IDENTIFIER_NODE, not a
+ FUNCTION_DECL, as input.
+ (mark_overriders): Remove.
+ (warn_hidden): Rework for the new ABI.
+
+2001-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3471
+ * call.c (convert_like_real): Do not build additional temporaries
+ for rvalues of class type.
+
+2001-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (UNIQUELY_DERIVED_FROM_P): Use lookup base.
+ (ACCESSIBLY_UNIQUELY_DERIVED_FROM_P): Likewise.
+ (PUBLICLY_UNIQUELY_DERIVED_FROM_P: Likewise.
+ (DERIVED_FROM_P): Likewise.
+ (enum base_access): Renumber, add ba_quiet bit mask.
+ (get_binfo): Remove.
+ (get_base_distance): Remove.
+ (binfo_value): Remove.
+ (ACCESSIBLY_DERIVED_FROM_P): Remove.
+ * call.c (standard_conversion): Use lookup_base.
+ * class.c (strictly_overrides): Likewise.
+ (layout_virtual_bases): Likewise.
+ (warn_about_ambiguous_direct_bases): Likewise.
+ (is_base_of_enclosing_class): Likewise.
+ (add_vcall_offset_vtbl_entries_1): Likewise.
+ * cvt.c (build_up_reference): Adjust comment.
+ * init.c (build_member_call): Reformat.
+ * search.c (get_binfo): Remove.
+ (get_base_distance_recursive): Remove.
+ (get_base_distance): Remove.
+ (lookup_base_r): Tweak.
+ (lookup_base): Add ba_quiet control. Complete the types here.
+ (covariant_return_p): Use lookup_base.
+ * tree.c (binfo_value): Remove.
+ (maybe_dummy_object): Use lookup_base.
+ * typeck.c (build_static_cast): Use lookup_base.
+ (get_delta_difference): Likewise.
+ * typeck2.c (binfo_or_else): Use lookup_base.
+ (build_scoped_ref): Add back error_mark_check.
+ (build_m_component_ref): Use lookup_base.
+
+2001-11-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (c++.generated-manpages): New dummy target.
+
+2001-11-27 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (cp-lang.o): Depends on c-common.h.
+ * cp-lang.c (c-common.h): Include.
+ (LANG_HOOKS_EXPAND_CONSTANT, LANG_HOOKS_SAFE_FROM_P): New hooks.
+ * decl.c (cxx_init_decl_processing): Don't set lang_safe_from_p.
+ * expr.c (init_cplus_expand): Don't set lang_expand_constant.
+
+2001-11-26 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c (c_language): Move to c-common.c.
+ * lex.c (cxx_post_options, cxx_init_options): Use c-common.c
+ functions.
+ (cxx_init): Update.
+
+2001-11-26 Jason Merrill <jason@redhat.com>
+
+ * call.c (joust): Remove COND_EXPR hack.
+
+2001-11-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * search.c (lookup_base_r): Declare bk in variable declaration
+ space.
+
+2001-11-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/3145
+ * class.c (build_vbase_pointer): Remove.
+ (build_vbase_path): Remove.
+ (build_base_path): New function.
+ * cp-tree.h (base_access, base_kind): New enumerations.
+ (build_base_path): Declare.
+ (convert_pointer_to_real): Remove.
+ (convert_pointer_to): Remove.
+ (lookup_base): Declare.
+ (convert_pointer_to_vbase): Remove.
+ * call.c (build_scoped_method_call): Use lookup_base &
+ build_base_path instead of convert_pointer_to_real,
+ get_base_distance & get_binfo.
+ (build_over_call): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_pointer_force): Likewise.
+ (build_up_reference): Likewise.
+ (convert_pointer_to_real): Remove.
+ (convert_pointer_to): Remove.
+ * init.c (dfs_initialize_vtbl_ptrs): Use build_base_path
+ instead of convert_pointer_to_vbase & build_vbase_path.
+ (emit_base_init): Use build_base_path instead of
+ convert_pointer_to_real.
+ (expand_virtual_init): Lose unrequired conversions.
+ (resolve_offset_ref): Use lookup_base and build_base_path
+ instead of convert_pointer_to.
+ * rtti.c (build_dynamic_cast_1): Use lookup_base &
+ build_base_path instead of get_base_distance & build_vbase_path.
+ * search.c (get_vbase_1): Remove.
+ (get_vbase): Remove.
+ (convert_pointer_to_vbase): Remove.
+ (lookup_base_r): New function.
+ (lookup_base): New function.
+ * typeck.c (require_complete_type): Use lookup_base &
+ build_base_path instead of convert_pointer_to.
+ (build_component_ref): Likewise.
+ (build_x_function_call): Likewise.
+ (get_member_function_from_ptrfunc): Likewise.
+ (build_component_addr): Likewise.
+ * typeck2.c (build_scoped_ref): Likewise.
+
+2001-11-22 Bryce McKinlay <bryce@waitaki.otago.ac.nz>
+
+ * cp-tree.h (CP_TYPE_QUALS): Removed.
+ * decl.c (cxx_init_decl_processing): Don't set lang_dump_tree.
+ * cp-lang.c: Set LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN and
+ LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN.
+ * dump.c (cp_dump_tree): Use void* dump_info argument to match
+ lang-hooks prototype.
+ * call.c, cp-tree.h, cvt.c, decl.c, init.c, mangle.c, method.c, pt.c,
+ rtti.c, semantics.c, tree.c, typeck.c, typeck2.c: All references to
+ CP_TYPE_QUALS changed to cp_type_quals.
+ * Make-lang.in: References to c-dump.h changed to tree-dump.h.
+ (CXX_C_OBJS): Remove c-dump.o.
+
+2001-11-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3637
+ * pt.c (lookup_template_class): Ensure that all specializations
+ are registered on the list corresponding to the most general
+ template.
+
+2001-11-20 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (non_reference): Add documentation.
+ (convert_class_to_reference): Do not strip reference types
+ from conversion operators.
+ (maybe_handle_ref_bind): Simplify.
+ (compare_ics): Correct handling of references.
+
+2001-11-19 John Wilkinson <johnw@research.att.com>
+
+ * dump.c (dump_op): New function.
+ (cp_dump_tree): Dump CLASSTYPE_TEMPLATE_SPECIALIZATION. Use
+ dump_op. Dump DECL_MUTABLE, access and staticness for VAR_DECLs.
+ DECL_PURE_VIRTUAL_P, DECL_VIRTUAL_P,
+
+2001-11-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR4629
+ * semantics.c (finish_sizeof): Make sure that expression created
+ while processing a template do not have a type.
+ (finish_alignof): Likewise.
+ * typeck.c (c_sizeof): Likewise.
+ (expr_sizeof): Likewise.
+
+2001-11-18 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * lex.c (cxx_finish): Call c_common_finish.
+ (finish_parse): Remove.
+
+2001-11-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl.c (create_array_type_for_decl): Check if NAME is NULL_TREE
+ when displaying error message about missing array bounds.
+
+2001-11-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * mangle.c (write_expression): Handle CAST_EXPR, STATIC_CAST_EXPR,
+ CONST_CAST_EXPR.
+ * operators.def: Add CAST_EXPR, STATIC_CAST_EXPR, CONST_CAST_EXPR.
+
+2001-11-16 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (print_class_statistics): Restore.
+
+2001-11-15 Jason Merrill <jason@redhat.com>
+
+ * method.c (use_thunk): Don't emit debugging information for thunks.
+
+ * parse.y: Add ... IDENTIFIER SCOPE and ... PTYPENAME SCOPE expansions.
+ * decl.c (make_typename_type): Handle getting a class template.
+ * search.c (lookup_field_r): A class template is good enough for
+ want_type.
+
+ * call.c (convert_like_real): Only use cp_convert for the bad part.
+ (standard_conversion): Also allow bad int->enum.
+ * typeck.c (ptr_reasonably_similar): Also allow functions to
+ interconvert. Pointers to same-size integers are reasonably
+ similar.
+
+ * cvt.c (convert_to_void): If we build a new COND_EXPR, always
+ give it void type.
+
+2001-11-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/3154
+ * init.c (sort_base_init): Remove unreachable code.
+ (expand_member_init): Adjust comment to reflect reality. Simplify
+ and remove unreachable code.
+
+2001-11-15 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (init_reswords, cxx_init_decl_processing): New.
+ (cxx_init): Update prototype.
+ * decl.c (init_decl_processing): Rename. Move null node init
+ to its creation time.
+ * lex.c (cxx_init_options): Update.
+ (cxx_init): Combine with old init_parse; also call
+ cxx_init_decl_processing.
+
+2001-11-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * decl.c (check_initializer): Try to complete the type of an
+ array element before checking whether it's complete. Don't
+ complain about arrays with complete element types but an
+ unknown size.
+ (cp_finish_decl): Build the hierarchical constructor before
+ calling maybe_deduce_size_from_array_init.
+
+2001-11-14 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in: Change all uses of $(manext) to $(man1ext).
+
+2001-11-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/4206
+ * parse.y (already_scoped_stmt): Remove.
+ (simple_stmt, WHILE & FOR): Use implicitly_scoped_stmt.
+
+2001-11-12 H.J. Lu <hjl@gnu.org>
+
+ * cvt.c (ocp_convert): Don't warn the address of a weak
+ function is always `true'.
+
+2001-11-09 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_PRINT_DECL, LANG_HOOKS_PRINT_TYPE,
+ LANG_HOOKS_PRINT_STATISTICS, LANG_HOOKS_PRINT_XNODE,
+ LANG_HOOKS_PRINT_IDENTIFIER, LANG_HOOKS_SET_YYDEBUG): Override.
+ * cp-tree.h (print_class_statistics): Remove.
+ (cxx_print_statistics, cxx_print_xnode, cxx_print_decl, cxx_print_type,
+ cxx_print_identifier, cxx_set_yydebug): New.
+ * lex.c (set_yydebug): Rename c_set_yydebug.
+ * ptree.c (print_lang_decl, print_lang_type, print_lang_identifier,
+ lang_print_xnode): Rename.
+ * tree.c (print_lang_statistics): Rename.
+
+2001-11-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (dump_array): Fix format specifier warning.
+
+2001-11-09 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_NAME): Override.
+ (struct lang_hooks): Constify.
+ * lex.c (cxx_init_options): Update.
+ (lang_identify): Remove.
+ * parse.y (language_string): Remove.
+
+2001-11-08 Andreas Franck <afranck@gmx.de>
+
+ * Make-lang.in (CXX_INSTALL_NAME, GXX_CROSS_NAME,
+ DEMANGLER_CROSS_NAME): Handle program_transform_name the way
+ suggested by autoconf.
+ (GXX_TARGET_INSTALL_NAME, CXX_TARGET_INSTALL_NAME): Define.
+ (c++.install-common): Use the transformed target alias names.
+
+2001-11-06 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * Make-lang.in: Update.
+ * cp-lang.c: Include langhooks-def.h.
+
+2001-11-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (tsubst_copy): Call tsubst for TYPEOF_EXPR.
+
+2001-11-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c (copy_lang_type): Add static prototype.
+
+2001-11-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (unify): Handle SCOPE_REF.
+
+2001-11-01 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.c (cp_copy_res_decl_for_inlining): Adjust
+ DECL_ABSTRACT_ORIGIN for the return variable.
+
+2001-10-31 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in: Replace $(INTL_TARGETS) with po-generated.
+
+2001-10-28 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * ChangeLog.1, ChangeLog.2, ChangeLog, class.c, decl2.c, search.c,
+ semantics.c, spew.c: Fix spelling errors.
+
+2001-10-27 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl2.c (validate_nonmember_using_decl): Handle NAMESPACE_DECL.
+
+2001-10-25 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-lang.c: Redefine LANG_HOOKS_CLEAR_BINDING_STACK to
+ pop_everything.
+
+2001-10-23 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * cp-lang.c (cxx_get_alias_set): New function.
+ Point LANG_HOOKS_GET_ALIAS_SET to it.
+
+2001-10-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.def (UNBOUND_CLASS_TEMPLATE): New tree node.
+ * cp-tree.h (make_unbound_class_template): Prototype new function.
+ * decl.c (make_unbound_class_template): New function.
+ * decl2.c (arg_assoc_template_arg): Handle UNBOUND_CLASS_TEMPLATE.
+ * error.c (dump_type): Likewise.
+ * mangle.c (write_type): Likewise.
+ * parse.y (template_parm): Likewise.
+ (template_argument): Use make_unbound_class_template.
+ * pt.c (convert_template_argument): Handle UNBOUND_CLASS_TEMPLATE.
+ (tsubst): Likewise.
+ (tsubst_copy): Likewise.
+ (unify): Likewise.
+ * tree.c (walk_tree): Likewise.
+ * typeck.c (comptypes): Likewise.
+
+2001-10-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * xref.c (GNU_xref_member): Use safe-ctype macros and/or fold
+ extra calls into fewer ones.
+
+2001-10-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * decl.c (duplicate_decls): Propagate DECL_UNINLINABLE.
+ Warn when merging inline with attribute noinline.
+ (start_decl, start_function): Warn if inline and attribute
+ noinline appear in the same declaration.
+
+2001-10-16 H.J. Lu <hjl@gnu.org>
+
+ * cp-tree.h (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): Defined
+ for tree checking disabled.
+
+2001-10-16 Hans-Peter Nilsson <hp@axis.com>
+
+ * cp-tree.h (VFIELD_NAME_FORMAT) [NO_DOLLAR_IN_LABEL &&
+ NO_DOT_IN_LABEL]: Adjust to match VFIELD_NAME.
+
+2001-10-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * pt.c (UNIFY_ALLOW_MAX_CORRECTION): Define.
+ (unify): Only handle MINUS_EXPR specially if the above flag is set
+ and the subtracted constant is 1. Clear the flag on recursive calls.
+ Set it when unifying the maximum value in an INTEGER_TYPE's range.
+
+2001-10-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * decl.c (bad_specifiers): Don't allow exception specifications
+ on any typedefs.
+
+2001-10-14 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/lex.c (init_cp_pragma): Similarly.
+
+2001-10-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (lookup_template_class): Build complete template arguments
+ for BOUND_TEMPLATE_TEMPLATE_PARM.
+
+2001-10-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (TYPE_BINFO): Update comment.
+ (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): New macro.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Use template_info.
+ (TYPENAME_TYPE_FULLNAME): Use TYPE_FIELDS.
+ (copy_type): Prototype new function.
+ * lex.c (copy_lang_decl): Gather tree node statistics.
+ (copy_lang_type): New function.
+ (copy_type): Likewise.
+ (cp_make_lang_type): Create lang_type for
+ BOUND_TEMPLATE_TEMPLATE_PARM. Set TYPE_BINFO for TYPENAME_TYPE
+ and BOUND_TEMPLATE_TEMPLATE_PARM.
+ * pt.c (tsubst): Use copy_type instead of copy_node.
+ * search.c (lookup_field_1): Ignore TYPENAME_TYPE.
+
+2001-10-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (determine_specialization): Ignore functions without
+ DECL_TEMPLATE_INFO.
+
+2001-10-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/4476
+ * typeck2.c (abstract_virtuals_error): Ignore incomplete classes.
+
+2001-10-11 Jason Merrill <jason_merrill@redhat.com>
+
+ * typeck2.c (store_init_value): Don't re-digest a bracketed
+ initializer.
+
+ * class.c (finish_struct_anon): Use TYPE_ANONYMOUS_P instead of
+ ANON_AGGR_TYPE_P.
+
+2001-10-11 Richard Henderson <rth@redhat.com>
+
+ * class.c (build_vtable_entry_ref): Create a VTABLE_REF instead
+ of an asm statement.
+ (build_vtbl_ref_1): Split out from build_vtbl_ref.
+ (build_vfn_ref): Use it to handle vtable descriptors before
+ calling build_vtable_entry_ref.
+ * decl2.c (output_vtable_inherit): Use assemble_vtable_inherit.
+
+2001-10-10 Richard Henderson <rth@redhat.com>
+
+ * parse.y (asm_operand): Allow named operands.
+ * semantics.c (finish_asm_stmt): Tweek for changed location
+ of the operand constraint.
+
+2001-10-09 Jason Merrill <jason_merrill@redhat.com>
+
+ * call.c (standard_conversion): Add bad conversion between
+ integers and pointers.
+ (convert_like_real): Don't use convert_for_initialization for bad
+ conversions; complain here and use cp_convert.
+ (build_over_call): Don't handle bad conversions specially.
+ (perform_implicit_conversion): Allow bad conversions.
+ (can_convert_arg_bad): New fn.
+ * cp-tree.h: Declare it.
+ * typeck.c (convert_for_assignment): Use it.
+ (ptr_reasonably_similar): Any target type is similar to void.
+
+2001-10-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * Make-lang.in (CXX_OBJS): Added cp-lang.o.
+ (cp/cp-lang.o): New rule.
+ * cp-tree.h: Declare hooks.
+ * tree.c: Make hooks non-static.
+ (init_tree): Don't initialize hooks here.
+ * lex.c: Likewise. Move definition of lang_hooks to...
+ * cp-lang.c: ... new file.
+
+2001-10-08 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (struct lang_decl_flags): Remove declared_inline.
+ (DECL_DECLARED_INLINE_P): Use the bit in struct c_lang_decl.
+
+2001-10-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (build_vtable_entry_ref): Const-ify.
+ * decl.c (predefined_identifier,
+ initialize_predefined_identifiers): Likewise.
+ * init.c (build_new_1): Likewise.
+ * lex.c (cplus_tree_code_type, cplus_tree_code_length, resword):
+ Likewise.
+
+2001-10-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * optimize.c (struct inline_data): Moved to ../tree-inline.c.
+ (INSNS_PER_STMT): Likewise.
+ (remap_decl, remap_block, copy_scopy_stmt, copy_body_r): Likewise.
+ (copy_body, initialize_inlined_parameters): Likewise.
+ (declare_return_variable, inlinable_function_p): Likewise.
+ (expand_call_inline, expand_calls_inline): Likewise.
+ (optimize_inline_calls, clone_body): Likewise.
+ * tree.c (walk_tree): Moved to ../tree-inline.c.
+ (walk_tree_without_duplicates): Likewise.
+ (copy_tree_r, remap_save_expr): Likewise.
+
+2001-10-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * Make-lang.in (cp/decl.o, cp/tree.o): Depend on tree-inline.h.
+ (cp/pt.o, cp/semantics.o, cp/optimize.o): Likewise.
+ * cp-tree.h (lang_decl): Moved inlined_fns to tree_decl.
+ (TREE_READONLY_DECL_P, DECL_INLINED_FNS): Moved to ../tree.h.
+ (flag_inline_trees): Moved declaration to ../tree-inline.h.
+ (walk_tree): Moved declaration to ../tree-inline.h.
+ (walk_tree_without_duplicates, copy_tree_r): Likewise.
+ (remap_save_expr): Likewise.
+ * decl.c: Include tree-inline.h.
+ (lang_mark_tree): Don't mark inlined_fns.
+ * decl2.c (flag_inline_trees): Moved defn to ../tree-inline.c.
+ * optimize.c: Include tree-inline.h.
+ (optimize_inline_calls): Move declaration to ../tree.h, as
+ non-static.
+ (remap_decl): Use language-independent constructs and hooks.
+ (remap_block, copy_body_r, declare_return_variable): Likewise.
+ (inlinable_function_p): Likewise. Don't test for
+ DECL_LANG_SPECIFIC before DECL_INLINED_FNS as inlined_fns is
+ no longer language-specific.
+ (optimize_inline_calls): Likewise. Make it non-static. Moved
+ call of dump_function to...
+ (optimize_function): Here...
+ (clone_body): New function, extracted from...
+ (maybe_clone_body): ... here. Build decl_map locally and pass
+ it on to clone_body.
+ * pt.c, semantics.c: Include tree-inline.h.
+ * tree.c: Likewise.
+ (cp_walk_subtrees): New language-specific hook for tree inlining.
+ (cp_cannot_inline_tree_fn, cp_add_pending_fn_decls,
+ cp_is_overload_p, cp_auto_var_in_fn_p,
+ cp_copy_res_decl_for_inlining): Likewise.
+ (walk_tree): Move language-specific constructs into...
+ (cp_walk_subtrees): this new function.
+ (copy_tree_r): Use language-independent constructs and hooks.
+ (init_tree): Initialize tree inlining hooks.
+ (remap_save_expr): Adjust prototype so that the declaration
+ does not require the definition of splay_tree.
+
+2001-10-03 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * rtti.c (get_tinfo_decl): Call typeinfo_in_lib_p with the type used
+ to build the declaration instead of the declaration itself.
+
+2001-10-02 Jason Merrill <jason_merrill@redhat.com>
+
+ * decl2.c (cxx_decode_option): Add 'else'.
+
+ * spew.c (end_input): No longer static.
+ * cp-tree.h: Declare it.
+ * parse.y (datadef): Add "error END_OF_SAVED_INPUT" expansion.
+
+2001-10-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * call.c (build_over_call), typeck.c (build_function_call_real):
+ Pass type attributes to check_function_format rather than name or
+ assembler name. Don't require there to be a name or assembler
+ name to check formats.
+
+2001-10-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (init_decl_processing): Don't call
+ init_function_format_info. Initialize lang_attribute_table
+ earlier.
+ (builtin_function): Call decl_attributes.
+ (insert_default_attributes): New.
+
+2001-10-01 Jason Merrill <jason_merrill@redhat.com>
+
+ * decl.c (grokdeclarator): Copy array typedef handling from C
+ frontend.
+
+ * decl.c (grokdeclarator): Copy too-large array handling from C
+ frontend.
+
+2001-09-29 Alexandre Oliva <aoliva@redhat.com>
+
+ * config-lang.in (target_libs): Added target-gperf, so that we
+ don't try to build it if C++ is disabled.
+
+2001-09-23 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in (CXX_OBJS): Take out cp/errfn.o.
+ (cp/errfn.o): Delete rule.
+ (cp/error.o): Depend on flags.h.
+ * errfn.c: Delete file.
+ * cp-tree.h: Declare warn_deprecated. Remove definitions of
+ TFF_NAMESPACE_SCOPE, TFF_CLASS_SCOPE, TFF_CHASE_NAMESPACE_ALIAS,
+ and TFF_TEMPLATE_DEFAULT_ARGUMENTS. #define cp_error, cp_warning,
+ cp_pedwarn, and cp_compiler_error to error, warning, pedwarn, and
+ internal_error respectively. Make cp_deprecated into a macro.
+ Don't define cp_printer typedef or declare cp_printers.
+ * error.c: Include flags.h.
+ Delete: struct tree_formatting_info, print_function_argument_list,
+ print_declaration, print_expression, print_function_declaration,
+ print_function_parameter, print_type_id, print_cv_qualifier_seq,
+ print_type_specifier_seq, print_simple_type_specifier,
+ print_elaborated_type_specifier, print_rest_of_abstract_declarator,
+ print_parameter_declaration_clause, print_exception_specification,
+ print_nested_name_specifier, and definition of cp_printers.
+ (locate_error): New function.
+ (cp_error_at, cp_warning_at, cp_pedwarn_at): Moved here and
+ rewritten in terms of locate_error and diagnostic.c.
+ (cp_tree_printer): Rename cp_printer; wire up to *_to_string
+ instead of deleted print_* routines. Handle %C, %L, %O, %Q also.
+ (init_error): Adjust to match.
+
+2001-09-22 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (CXX_C_OBJS): Add attribs.o.
+
+2001-09-21 Richard Henderson <rth@redhat.com>
+
+ * class.c (set_vindex): Mind TARGET_VTABLE_USES_DESCRIPTORS.
+ (build_vtbl_initializer): Likewise.
+ (build_vfn_ref): New.
+ * cp-tree.h: Declare it.
+ * call.c (build_over_call): Use it.
+ * decl2.c (mark_vtable_entries): Mark FDESC_EXPR.
+ * typeck.c (get_member_function_from_ptrfunc): Mind descriptors.
+
+2001-09-21 J"orn Rennecke <amylaar@redhat.com>
+
+ * decl.c (grokdeclarator): Use C syntax for attr_flags declaration.
+
+2001-09-21 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ Table-driven attributes.
+ * decl.c: Rename DECL_MACHINE_ATTRIBUTES to DECL_ATTRIBUTES.
+ * decl2.c (cplus_decl_attributes): Only take one attributes
+ parameter.
+ * cp-tree.c (cplus_decl_attributes): Update prototype.
+ * class.c (finish_struct), decl.c (start_decl, start_function),
+ decl2.c (grokfield), friend.c (do_friend), parse.y
+ (parse_bitfield): Update calls to cplus_decl_attributes.
+ * decl.c (grokdeclarator): Take a pointer to a single ordinary
+ attribute list.
+ * decl.h (grokdeclarator): Update prototype.
+ * decl2.c (grokfield): Take a single ordinary attribute list.
+ * friend.c (do_friend): Likewise.
+ * decl.c (shadow_tag, groktypename, start_decl,
+ start_handler_parms, grokdeclarator, grokparms, start_function,
+ start_method), decl2.c (grokfield, grokbitfield, grokoptypename),
+ parse.y (parse_field, parse_bitfield, component_decl_1), pt.c
+ (process_template_parm, do_decl_instantiation): Pass single
+ ordinary attribute lists around.
+ * decl.c (grokdeclarator): Correct handling of nested attributes.
+ Revert the patch
+ 1998-10-18 Jason Merrill <jason@yorick.cygnus.com>
+ * decl.c (grokdeclarator): Embedded attrs bind to the right,
+ not the left.
+ .
+ * cp-tree.h (cp_valid_lang_attribute): Remove declaration
+ (cp_attribute_table): Declare.
+ * decl.c (valid_lang_attribute): Don't define.
+ (lang_attribute_table): Define.
+ (init_decl_processing): Initialize lang_attribute_table instead of
+ valid_lang_attribute.
+ * tree.c (cp_valid_lang_attribute): Remove.
+ (handle_java_interface_attribute, handle_com_interface_attribute,
+ handle_init_priority_attribute): New functions.
+ (cp_attribute_table): New array.
+ * decl2.c (import_export_class): Don't use
+ targetm.valid_type_attribute.
+
+2001-09-15 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * Make-lang.in (cp/error.o): Depend on real.h
+ * error.c: #include "real.h"
+
+2001-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mangle.c (mangle_conv_op_name_for_type): Use concat in lieu of
+ xmalloc/strcpy/strcat.
+
+2001-09-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (warn_extern_redeclared_static, cp_make_fname_decl):
+ Const-ification.
+ * pt.c (tsubst_decl): Likewise.
+
+2001-09-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (lang_f_options): Const-ification.
+ * lex.c (cplus_tree_code_name): Likewise.
+ * spew.c (yyerror): Likewise.
+
+2001-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3986
+ * class.c (force_canonical_binfo_r): Check & move an indirect
+ primary base first.
+ (force_canonical_binfo): Check that it's not already
+ canonical.
+ (mark_primary_virtual_base): Remove BINFO parameter.
+ (mark_primary_bases): Adjust, set BINFO_LOST_PRIMARY_P here.
+
+2001-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove TYPE_NONCOPIED_PARTS.
+ * cp-tree.h (CLASSTYPE_INLINE_FRIENDS): Map onto
+ CLASSTYPE_PURE_VIRTUALS.
+ (TYPE_RAISES_EXCEPTIONS): Map onto TYPE_BINFO.
+ * class.c (duplicate_tag_error): Remove TYPE_NONCOPIED_PARTS.
+ (layout_class_type): Don't call fixup_inline_methods here ...
+ (finish_struct_1): ... call it here.
+
+2001-09-04 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Remove code deadling with
+ DECL_SAVED_INSNS.
+ * decl2.c (finish_file): Likewise.
+ * pt.c (instantiate_decl): Likewise.
+ * semantics.c (expand_body): Don't defer local functions if
+ they wouldn't be deferred for some other reason. Don't
+ generate RTL for functions that will not be emitted.
+ (genrtl_start_function): Remove code deadling with
+ DECL_SAVED_INSNS.
+ (genrtl_finish_function): Likewise.
+
+2001-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4203
+ * call.c (build_over_call): Do not optimize any empty base
+ construction.
+
+2001-08-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * error.c (dump_template_decl): Output template parameters
+ together with their specifiers.
+ Output `class' prefix for template template parameter.
+ (dump_decl): Fix formatting.
+
+2001-08-30 Kurt Garloff <garloff@suse.de>
+
+ * optimize.c (inlinable_function_p): Allow only smaller single
+ functions. Halve inline limit after reaching recursive limit.
+
+2001-08-30 Joern Rennecke <amylaar@redhat.com>
+ Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (build_vtable_entry_ref): Subtract in char*, not
+ ptrdiff_t.
+
+2001-08-23 Jason Merrill <jason_merrill@redhat.com>
+
+ * tree.c (cp_build_qualified_type_real): Use get_qualified_type.
+ (build_cplus_array_type): Use cp_build_qualified_type, not
+ TYPE_MAIN_VARIANT, to get an unqualified version.
+
+ * decl2.c (grok_alignof): Lose.
+ (build_expr_from_tree): Use expr_sizeof and c_alignof_expr.
+ * typeck.c (c_alignof): Lose.
+ * semantics.c (finish_sizeof, finish_alignof): New.
+ * parse.y: Use them.
+ * cp-tree.h: Declare them.
+
+2001-08-22 Jason Merrill <jason_merrill@redhat.com>
+
+ * pt.c (tsubst_expr): Hand off to the TREE_CHAIN of a statement.
+ Don't loop in COMPOUND_STMT, FOR_STMT or TRY_BLOCK.
+ * tree.c (cp_statement_code_p): A TAG_DEFN is a statement.
+
+2001-08-19 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck2.c (add_exception_specifier): Only require complete type if
+ not in processing template declaration.
+
+2001-08-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c: Cast argument to size_t, not HOST_WIDE_INT, in calls to
+ GNU_xref_start_scope and GNU_xref_end_scope.
+
+ * tree.c (TYPE_HASH): Moved to ../tree.h.
+
+2001-08-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cvt.c (convert_to_void): Preserve TREE_SIDE_EFFECTS
+ on COMPOUND_EXPRs.
+
+2001-08-14 Richard Henderson <rth@redhat.com>
+
+ * class.c, cp-tree.h (build_vfn_ref): Remove.
+ * call.c, rtti.c: Replace all refernces with build_vtbl_ref.
+
+2001-08-13 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_over_call): Mark COMPOUND_EXPRs generated for
+ empty class assignment as having side-effects to avoid
+ spurious warnings.
+
+2001-08-13 Zack Weinberg <zackw@panix.com>
+
+ * Make-lang.in (cp/except.o): Add libfuncs.h to dependencies.
+ * except.c: Include libfuncs.h.
+
+2001-08-11 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * decl.c (grokdeclarator): Clarify diagnostic message.
+
+2001-08-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl2.c (do_nonmember_using_decl): Replace using directive
+ with using declaration in the error message.
+
+2001-08-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (maybe_fold_nontype_arg): Use TREE_TYPE of ARG as the
+ criterion to avoid rebuilding expression tree instead of
+ processing_template_decl.
+
+2001-08-07 Jason Merrill <jason_merrill@redhat.com>
+
+ Support named return value optimization for inlines, too.
+ * decl.c (finish_function): Nullify returns here.
+ * semantics.c (genrtl_start_function): Not here.
+ (cp_expand_stmt): Don't mess with CLEANUP_STMTs.
+ (nullify_returns_r): No longer static. Just clear RETURN_EXPR.
+ Also nullify the CLEANUP_STMT for the nrv.
+ * cp-tree.h: Declare it.
+ * optimize.c (declare_return_variable): Replace the nrv with the
+ return variable.
+ * typeck.c (check_return_expr): Be more flexible on alignment check.
+ Ignore cv-quals when checking for a matching type.
+
+2001-08-09 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (finish_objects): Use target hooks instead of
+ assemble_constructor and assemble_destructor.
+
+2001-08-08 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * g++spec.c (lang_specific_driver): Quote argument after `-Xlinker'.
+
+2001-08-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3820
+ Stop using TYPE_NONCOPIED_PARTS.
+ * call.c (build_over_call): Be careful when copy constructing
+ or assigning to an empty class.
+ * class.c (check_bases_and_members): It has a
+ COMPLEX_ASSIGN_REF if it has a vptr.
+ (layout_class_type): Don't add empty class padding to
+ TYPE_NONCOPIED_PARTS.
+ (finish_struct_1): Don't add the VFIELD either.
+ * cp-tree.h (TYPE_HAS_TRIVIAL_INIT_REF): Mention _copy_
+ initialization.
+
+2001-08-07 Jason Merrill <jason_merrill@redhat.com>
+
+ * tree.c (walk_tree): Walk siblings even if !walk_subtrees.
+
+2001-08-06 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (finish_objects): Pass a symbol_ref and priority to
+ assemble_{constructor,destructor}. Remove priority handling.
+
+2001-08-05 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ Don't allow template-id in using-declaration.
+ * decl2.c (validate_nonmember_using_decl): Handle template-ids.
+ (do_class_using_decl): Likewise.
+
+2001-08-04 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * cp/spew.c (read_token): No need to pop buffers.
+
+2001-08-02 Stan Shebs <shebs@apple.com>
+
+ * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY): Remove, no longer used.
+ (fnaddr_from_vtable_entry): Remove decl.
+ * method.c (use_thunk): Update comment.
+
+2001-08-01 Andrew Cagney <ac131313@redhat.com>
+
+ * repo.c (get_base_filename): Change return value to const char
+ pointer.
+
+2001-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ Kill -fhonor-std.
+ * NEWS: Document.
+ * cp-tree.h (flag_honor_std): Remove.
+ (CPTI_FAKE_STD): Remove.
+ (std_node): Remove comment about it being NULL.
+ (fake_std_node): Remove.
+ * decl.c (in_fake_std): Remove.
+ (walk_namespaces_r): Remove fake_std_node check.
+ (push_namespace): Remove in_fake_std code.
+ (pop_namespace): Likewise.
+ (lookup_name_real): Remove fake_std_node check.
+ (init_decl_processing): Always create std_node. Always add
+ std:: things there.
+ (builtin_function): Always put non '_' fns in std.
+ * decl2.c (flag_honor_std): Remove.
+ (lang_f_options): Remove honor-std.
+ (unsupported_options): Add honor-std.
+ (set_decl_namespace): Remove fake_std_node check.
+ (validate_nonmember_using_decl): Likewise.
+ (do_using_directive): Likewise.
+ (handle_class_head): Likewise.
+ * dump.c (cp_dump_tree): Likewise.
+ * except.c (init_exception_processing): Adjust.
+ * init.c (build_member_call): Remove fake_std_node check.
+ (build_offset_ref): Likewise.
+ * lang-options.h: Remove -fhonor-std, -fno-honor-std.
+ * rtti.c (init_rtti_processing): Adjust.
+
+2001-07-31 Alexandre Petit-Bianco <apbianco@redhat.com>
+
+ * tree.c (cp_tree_equal): WITH_CLEANUP_EXPR node to use its second
+ operand while calling cp_tree_equal.
+
+2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ The 3.0 ABI no longer has vbase pointer fields.
+ * cp-tree.h (VBASE_NAME, VBASE_NAME_FORMAT, VBASE_NAME_P,
+ FORMAT_VBASE_NAME): Remove.
+ * method.c (do_build_copy_constructor): Adjust.
+ (do_build_assign_ref): Adjust.
+ * search.c (lookup_field_r): Adjust.
+ * typeck.c (build_component_ref): Adjust.
+
+ The 3.0 ABI always has a vtable pointer at the start of every
+ polymorphic class.
+ * rtti.c (build_headof_sub): Remove.
+ (build_headof): Adjust.
+ (get_tinfo_decl_dynamic): No need to check flag_rtti
+ here. Adjust.
+ (create_real_tinfo_var): Explain why we need a hidden name.
+
+2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3631
+ * class.c (update_vtable_entry_for_fn): The fixed adjustment
+ of a virtual thunk should be from declaring base.
+
+2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_ctor_vtable_bases_queue_p): Always walk into
+ the shared virtual base, so preserving inheritance graph order.
+
+2001-07-30 Andreas Jaeger <aj@suse.de>
+
+ * decl2.c: Remove unused var global_temp_name_counter.
+
+2001-07-28 Richard Henderson <rth@redhat.com>
+
+ * method.c (pending_inlines): Remove.
+
+2001-07-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (mark_primary_virtual_base): Don't adjust base
+ offsets here.
+ (dfs_unshared_virtual_bases): Adjust them here.
+ (mark_primary_bases): Explain why we adjust at the end.
+
+2001-07-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (finish_struct_1): When copying the primary base's
+ VFIELD, make sure we find it is at offset zero.
+
+2001-07-26 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (tsubst_template_parms): Call maybe_fold_nontype_arg and
+ tsubst_expr for default template arguments.
+
+2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3621
+ * spew.c (yylex): Only copy the token's lineno, if it is
+ nonzero.
+
+2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3624
+ * call.c (resolve_args): Simplify, call
+ convert_from_reference.
+ (build_new_op): Resolve and convert from reference ARG1
+ earlier. Adjust ARG2 & ARG3 resolve and conversion.
+
+2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (last_function_parm_tags): Remove.
+ (current_function_parm_tags): Remove.
+ (init_decl_processing): Adjust.
+ (start_function): Adjust.
+ (store_parm_decls): Adjust.
+
+ PR c++/3152
+ * decl.c (grokdeclarator): Detect when a function typedef is
+ declaring a function, and create last_function_parms correctly.
+
+2001-07-25 Jason Merrill <jason_merrill@redhat.com>
+
+ * call.c (joust): Only prefer a non-builtin candidate to a builtin
+ one if they have the same signature.
+
+ * cvt.c (build_up_reference): Take DECL parm. Check TREE_STATIC on
+ it rather than toplevel_bindings_p. Give it a mangled name if static.
+ (convert_to_reference): Adjust.
+ * decl2.c (get_temp_name): Lose.
+ * mangle.c (mangle_ref_init_variable): New fn.
+ (mangle_guard_variable): Strip the ref-init header.
+ * cp-tree.h: Adjust.
+ * decl.c (cp_finish_decl): Add the DECL_STMT after processing the
+ initializer.
+ (grok_reference_init): Always use DECL_INITIAL.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3416
+ * call.c (build_conditional_expr): Recheck args after
+ conversions.
+ * cp-tree.h (build_conditional_expr): Move to correct file.
+ * typeck.c (decay_conversion): Diagnose any unknown types
+ reaching here.
+ (build_binary_op): Don't do initial decay or default
+ conversions on overloaded functions.
+ (build_static_cast): Don't do a decay conversion here.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3543
+ * typeck.c (condition_conversion): Resolve an OFFSET_REF.
+ * expr.c (cplus_expand_expr): An OFFSET_REF should never get here.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_vtbl_or_vbase_field): Remove, move into ...
+ (create_vtbl_ptr): ... here.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_vbase_offset_vbtl_entries): Look for
+ non-primary base of which we are a sub vtable.
+
+2001-07-24 Phil Edwards <pme@sources.redhat.com>
+
+ * semantics.c (finish_this_expr): Remove unused code.
+
+2001-07-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ Simplify rtti, now we've only one ABI.
+ * cp-tree.h (cp_tree_index): Remove CPTI_TINFO_DECL_ID,
+ CPTI_TINFO_VAR_ID.
+ (tinfo_decl_id, tinfo_var_id): Remove.
+ (get_typeid_1): Remove.
+ * rtti.c
+ (init_rtti_processing): Remove tinfo_decl_id & tinfo_var_id.
+ (typeid_ok_p): New function.
+ (build_type_id): Call typeid_ok_p. Don't call tinfo_from_decl.
+ (get_tinfo_decl): Remove old abi documentation.
+ (tinfo_from_decl): Remove.
+ (get_type_id): Call typeid_ok_p. Absorb get_typeid_1.
+ (get_typeid_1): Remove.
+ (get_base_offset): Remove.
+ (synthesize_tinfo_var): Absorb get_base_offset.
+ (create_real_tinfo_var): Don't use tinfo_decl_id.
+
+2001-07-23 Graham Stott <grahams@redhat.com>
+
+ * cp/class.c (type_requires_array_cookie): Fix use of uninitialized
+ variable has_two_argument_delete_p.
+
+2001-07-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove flag_vtable_thunk. It is always on for the 3.0 ABI.
+ * cp-tree.h (CPTI_DELTA2_IDENTIFIER): Remove.
+ (CPTI_INDEX_IDENTIFIER): Remove.
+ (CPT_PFN_OR_DELTA2_IDENTIFIER): Remove.
+ (delta2_identifier): Remove.
+ (index_identifier): Remove.
+ (pfn_or_delta2_identifier): Remove.
+ (flag_vtable_thunks): Remove.
+ (VTABLE_DELTA2_NAME): Remove.
+ (VTABLE_INDEX_NAME): Remove.
+ (FNADDR_FROM_VTABLE_ENTRY): Adjust.
+ (vfunc_ptr_type_node): Adjust.
+ (VTABLE_NAME_PREFIX): Adjust.
+ (build_vfn_ref): Lose first parameter.
+ (fixup_all_virtual_upcast_offsets): Remove.
+ * decl.c (initialize_predefined_identifiers): Remove
+ delta2_identifier, index_identifier, pfn_or_delta2_identifier.
+ (init_decl_processing): Remove no-vtable-thunk code.
+ * decl2.c (flag_vtable_thunks): Remove.
+ (mark_vtable_entries): Remove no-vtable-thunk code.
+ * error.c (dump_decl): Remove no-vtable-thunk code.
+ (dump_expr): Adjust ptr to member function code.
+ * init.c (initialize_vtable_ptrs): Remove no-vtable-thunk
+ code.
+ * rtti.c (build_headof): Remove no-vtable-thunk code.
+ (get_tinfo_decl_dynamic): Adjust build_vfn_ref call.
+ * search.c (get_base_distance): Remove expand_upcast_fixups case.
+ (virtual_context) Remove.
+ (expand_upcast_fixups): Remove.
+ (fixup_virtual_upcast_offsets): Remove.
+ (fixup_all_virtual_upcast_offsets): Remove.
+ * typeck.c (get_member_function_from_ptrfunc): Remove
+ no-vtable-thunk code.
+ * call.c (build_over_call): Adjust call to build_vfn_ref.
+ * class.c (build_vfn_ref): Lose first parameter. Remove
+ no-vtable-thunk code.
+ (build_rtti_vtbl_entries): Remove no-vtable-thunk code.
+ (build_vtable_entry): Remove no-vtable-thunk code.
+
+2001-07-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove old-abi remnants. Remove comments about old abi
+ behavior. Remove references to 'new-abi' in comments.
+ * cp-tree.h: Adjust comments.
+ (vbase_offsets_in_vtable_p): Delete.
+ (vcall_offsets_in_vtable_p): Delete.
+ (vptrs_present_everywhere_p): Delete.
+ (all_overridden_vfuns_in_vtables_p): Delete.
+ (merge_primary_and_secondary_vtables_p): Delete.
+ (TYPE_CONTAINS_VPTR_P): Adjust.
+ (VTT_NAME_PREFIX): Remove.
+ (CTOR_VTBL_NAME_PREFIX): Remove.
+ (init_vbase_pointers): Remove.
+ * class.c: Adjust coments.
+ (build_vbase_pointer_fields): Delete.
+ (build_vbase_pointer): Remove old-abi code.
+ (build_secondary_vtable): Likewise.
+ (modify_all_vtables): Likewise.
+ (create_vtable_ptr): Likewise.
+ (layout_class_type): Likewise.
+ (finish_struct_1): Likewise.
+ (finish_vtbls): Likewise.
+ (dfs_finish_vtbls): Delete.
+ (build_vbase_offset_vtbl_entries): Remove old-abi code.
+ * cvt.c: Adjust comments.
+ * decl.c: Adjust comments.
+ * decl2.c: Adjust comments.
+ * init.c: Adjust comments.
+ (construct_virtual_bases): Remove old-abi code.
+ * lang-specs.h: Remove -fno-new-abi.
+ * mangle.c: Adjust comments.
+ * rtti.c: Adjust comments.
+ (get_base_offset): Remove old-abi-code.
+ * search.c: Adjust comments.
+ (dfs_init_vbase_pointers): Remove.
+ (dfs_vtable_path_unmark): Remove.
+ (init_vbase_pointers): Remove.
+ * semantics.c: Adjust comments.
+ (emit_associated_thunks): Remove old-abi code.
+ * typeck.c: Adjust comments.
+
+2001-07-20 Daniel Berlin <dan@cgsoftware.com>
+
+ * Make-lang.in (cp/optimize.o): Depend on $(PARAMS_H), not
+ params.h.
+
+2001-07-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (finish_struct_anon): Forbid nested classes.
+
+2001-07-19 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c: Don't include dwarfout.h and dwarf2out.h.
+ * optimize.c: Include debug.h.
+ (maybe_clone_body): Use debug hook.
+ * semantics.c: Include debug.h.
+ (expand_body): Use debug hook.
+
+2001-07-19 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * spew.c (read_token, yyerror): Remove CPP_INT, CPP_FLOAT cases.
+
+2001-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (type_requires_array_cookie): New function.
+ (check_methods): Don't try to figure out whether the type needs a
+ cookie here.
+ (check_bases_and_members): Set TYPE_VEC_NEW_USES_COOKIE here.
+ * cp-tree.h (TYPE_VEC_DELETE_TAKES_SIZE): Remove.
+ (TYPE_VEC_NEW_USES_COOKIE): Reimplement.
+ * pt.c (instantiate_class_template): Don't set
+ TYPE_VEC_DELETE_TAKES_SIZE.
+ * NEWS: Document ABI changes from GCC 3.0.
+
+2001-07-18 Xavier Delacour <xavier@fmaudio.net>,
+ Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * NEWS (Changes in GCC 3.0): Fix typo.
+
+2001-07-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (cplus_decl_attributes): Take a pointer to the node to
+ which attributes are to be attached, and a flags argument. Update
+ call to decl_attributes.
+ (grokfield): Update call to decl_attributes.
+ * class.c (finish_struct): Update call to cplus_decl_attributes.
+ * cp-tree.h (cplus_decl_attributes): Update prototype.
+ * decl.c (start_decl, grokdeclarator, start_function): Update
+ calls to decl_attributes and cplus_decl_attributes.
+ * friend.c (do_friend): Update call to cplus_decl_attributes.
+ * parse.y (parse_bitfield): Update call to cplus_decl_attributes.
+
+2001-07-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (make_rtl_for_nonlocal_decl): Set DECL_C_HARD_REGISTER
+ for `register' variables with an asm-specification.
+
+2001-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (finish_asm_stmt): Mark the output operands
+ to an asm addressable, if necessary.
+
+2001-07-11 Ben Elliston <bje@redhat.com>
+
+ * Revert this change -- there is a subtle bug.
+
+ PR c++/80
+ * decl.c (finish_enum): New "attributes" argument; pass it to
+ cplus_decl_attributes. Use a narrower type if the enum is packed.
+ * cp-tree.h (finish_enum): Adjust prototype.
+ * parse.y (enum_head): New non-terminal.
+ (structsp): Use it. Enums now may be preceded or followed by
+ optional attributes -- pass their chained tree to finish_enum().
+ * pt.c (tsubst_enum): Pass NULL_TREE for the new argument.
+
+2001-07-10 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_decl): Set DECL_CONTEXT for namespace-scope
+ variables.
+
+2001-07-10 Jason Merrill <jason_merrill@redhat.com>
+
+ * semantics.c (cp_expand_stmt): Fix for null
+ current_function_return_value.
+
+2001-07-10 Jan van Male <jan.vanmale@fenk.wau.nl>
+
+ * call.c (build_op_delete_call): Initialize fn.
+ (convert_like_real): Delete conditional.
+ (joust): Initialize *w and *l.
+ * class.c: Add prototype for binfo_ctor_vtable.
+ (get_primary_binfo): Initialize result.
+ * init.c (build_java_class_ref): Initialize name.
+
+2001-07-09 Erik Rozendaal <dlr@acm.org>
+
+ * typeck.c (unary_complex_lvalue): Do not duplicate the
+ argument to modify, pre-, or post-increment when used as an
+ lvalue and when the argument has side-effects.
+
+2001-07-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (start_decl): Don't call SET_DEFAULT_DECL_ATTRIBUTES.
+ (start_function): Don't call SET_DEFAULT_DECL_ATTRIBUTES. Call
+ cplus_decl_attributes even if attrs is NULL.
+ * friend.c (do_friend): Don't call SET_DEFAULT_DECL_ATTRIBUTES.
+
+2001-07-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (grokdeclarator), decl2.c (cplus_decl_attributes): Update
+ calls to decl_attributes.
+
+2001-07-06 Ira Ruben <ira@apple.com>
+
+ * cp-tree.def (TEMPLATE_DECL): Update comment. DECL_RESULT should
+ be DECL_TEMPLATE_RESULT.
+
+2001-07-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (copy_template_template_parm): Rename to ...
+ (bind_template_template_parm): ... here.
+ * tree.c (copy_template_template_parm): Rename to ...
+ (bind_template_template_parm): ... here. Remove the case when
+ NEWARGS is NULL_TREE.
+ (copy_tree_r): Don't copy TEMPLATE_TEMPLATE_PARM and
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+ * pt.c (lookup_template_class): Adjust.
+
+2001-07-05 Jason Merrill <jason_merrill@redhat.com>
+
+ * cvt.c (convert_lvalue): New fn.
+ * cp-tree.h: Declare it.
+ * method.c (do_build_assign_ref): Use it.
+ (do_build_copy_constructor): Convert parm to base types
+ before calling base constructors.
+
+ * typeck.c (check_return_expr): Check DECL_ALIGN instead of
+ DECL_USER_ALIGN. Check flag_elide_constructors instead of
+ optimize.
+ * semantics.c (cp_expand_stmt): Don't destroy the named return value.
+
+2001-07-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * optimize.c (optimize_inline_calls): New function, broken out
+ of ...
+ (optimize_function): ... here. Call it. Don't inline if it is
+ a thunk.
+ (dump_function): Print name of dump flag causing this dump.
+ * semantics.c (expand_body): Move thunk inline check to
+ optimize_function.
+
+2001-06-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * typeck.c (COMP_TYPE_ATTRIBUTES): Don't define.
+ (comptypes): Use target.comp_type_attributes.
+
+2001-06-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (flag_dump_class_layout): Remove unneeded declaration.
+
+2001-06-28 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * error.c (lang_print_error_function): Add a `diagnostic_context *'
+ parameter. Tweak.
+
+2001-06-27 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * decl2.c (import_export_class): Update.
+
+2001-06-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (init_error): Adjust settings.
+
+2001-06-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (init_error): Adjust settings.
+
+2001-06-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * except.c (initialize_handler_parm): Expect __cxa_begin_catch to
+ return pointers to data members by reference rather than by value.
+
+2001-06-18 Jason Merrill <jason_merrill@redhat.com>
+
+ Implement the Named Return Value optimization.
+ * cp-tree.h (struct cp_language_function): Add x_return_value.
+ (current_function_return_value): Now a macro.
+ * decl.c: Don't define it.
+ (define_label, finish_case_label): Don't clear it.
+ (init_decl_processing): Don't register it with GC.
+ * semantics.c (genrtl_finish_function): Don't check it for
+ no_return_label. Copy the RTL from the return value to
+ current_function_return_value and walk, calling...
+ (nullify_returns_r): ...this new fn.
+ * typeck.c (check_return_expr): Set current_function_return_value.
+
+2001-06-15 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (dfs_accumulate_vtbl_inits): Just point to the base we're
+ sharing a ctor vtable with. Merge code for cases 1 and 2.
+ (binfo_ctor_vtable): New fn.
+ (build_vtt_inits, dfs_build_secondary_vptr_vtt_inits): Use it.
+
+2001-06-14 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (dfs_find_final_overrider): Fix logic.
+
+ * class.c (update_vtable_entry_for_fn): Uncomment optimization to use
+ virtual thunk instead of non-virtual.
+ (get_matching_virtual): Uncomment.
+
+ * pt.c (unify): Don't recurse between the POINTER_TYPE and the
+ OFFSET_TYPE. If we're adding cv-quals, the extra ones would be on
+ PARM, not ARG.
+
+2001-06-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_accumulate_vtbl_inits): For case 2 & 3, make sure
+ we've not emerged from the hierarchy of RTTI_BINFO on reaching
+ a non-virtual base.
+
+2001-06-13 Mark Mitchell <mark@codesourcery.com>
+
+ * NEWS: Update release number.
+
+2001-06-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3130, c++/3131, c++/3132
+ * cp-tree.h (BINFO_UNSHARED_MARKED): New #define.
+ * class.c (force_canonical_binfo_r): Move
+ BINFO_UNSHARED_MARKED, BINFO_LOST_PRIMARY_P. Don't move
+ virtual bases unless they're primary and what they're primary
+ too has been moved.
+ (dfs_unshared_virtual_bases): Use BINFO_UNSHARED_MARKED. Cope
+ with morally virtual bases. Duplicate BINFO_LOST_PRIMARY_P and
+ BINFO_PRIMARY_BASE_OF. Clear BINFO_VTABLE for all but the most
+ derived binfo.
+ (mark_primary_bases): Use BINFO_UNSHARED_MARKED.
+ (layout_nonempty_base_or_field): Add most derived type
+ parameter. Adjust.
+ (layout_empty_base): Likewise.
+ (build_base_field): Likewise.
+ (build_base_fields): Likewise.
+ (propagate_binfo_offsets): Add most derived type
+ parameter. Skip non canonical virtual bases too.
+ (dfs_set_offset_for_unshared_vbases): Don't skip primary
+ bases. Do skip canonical bases.
+ (layout_virtual_bases): Adjust.
+ (layout_class_type): Adjust.
+ (dfs_get_primary_binfo): Build list of virtual primary base
+ candidates.
+ (get_primary_binfo): Check that the shared virtual primary
+ base candidate was found first.
+ (accumulate_vtbl_inits): Don't do anything for non-vptr
+ containing binfos. For case 1 primary virtual bases, keep
+ checking that we've not emerged from the hierarchy of RTTI_BINFO.
+
+2001-06-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3089
+ * class.c (dfs_accumulate_vtbl_inits): Always walk down the
+ hierarchy looking for primary bases for a ctor
+ vtable. Recursively call oneself, if we meet our primary via
+ this route and haven't met it yet via inheritance graph order.
+
+2001-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ * lang-options.h: Emit documentation for -fno-honor-std, not
+ -fhonor-std.
+
+2001-06-10 Alexandre Oliva <aoliva@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc) [vbit_in_delta]:
+ Don't clobber delta.
+ (expand_ptrmemfunc_cst) [ptrmemfunc_vbit_in_delta]: Adjust pfn.
+
+2001-06-10 Mark Mitchell <mark@codesourcery.com>
+ Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * Make-lang.in (cp/call.o): Depend on diagnostic.h
+ (cp/typeck.o): Depend on diagnostic.h
+ (cp/typeck2.o): Depend on diagnostic.h
+ (cp/repo.o): Depend on dignostic.h
+ * typeck.c: #include diagnostic.h
+ (convert_for_initialization): Remove extern declaration for
+ warningcount and errorcount.
+
+ * call.c: #include diagnostic.h
+ (convert_like_real): Remove extern declaration for warnincount and
+ errorcount.
+
+ * repo.c: #include diagnostic.h
+ * typeck2.c: #include diagnostic.h
+
+2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (duplicate_decls): Fix DECL_TEMPLATE_RESULT thinko
+ in previous change.
+
+2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2929
+ * friend.c (do_friend): Use push_decl_namespace for classes at
+ namespace scope.
+
+2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
+ Jason Merrill <jason_merrill@redhat.com>
+
+ PR c++/3061
+ * class.c (build_secondary_vtable): Use assert, rather than an error
+ message.
+ (dfs_fixup_binfo_vtbls): BINFO_VTABLE might be NULL.
+ (dfs_accumulate_vtbl_inits): A lost primary virtual base may
+ be between ORIG_BINFO and RTTI_BINFO, but neither of them.
+ Don't set BINFO_VTABLE for a primary virtual base.
+
+2001-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Update source position information
+ when a template function is defined.
+
+2001-06-07 Phil Edwards <pme@sources.redhat.com>
+
+ * lang-specs.h: Move -D_GNU_SOURCE to config/linux.h.
+
+2001-06-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2914
+ * decl.c (pushtag): Don't push into a complete type's scope.
+
+2001-06-06 Jason Merrill <jason_merrill@redhat.com>
+
+ * cp-tree.h (THUNK_GENERATE_WITH_VTABLE_P): Lose.
+ (struct lang_decl_flags): Lose generate_with_vtable_p.
+ (BV_GENERATE_THUNK_WITH_VTABLE_P): Lose.
+ * class.c (copy_virtuals): Adjust.
+ * decl2.c (mark_vtable_entries): Adjust.
+ * method.c (make_thunk, build_vtable_entry): Adjust.
+ * class.c (update_vtable_entry_for_fn): Only look as far as the
+ first defining class.
+ (build_vtbl_initializer): Put nothing in the slot for a function only
+ defined in a lost primary virtual base.
+ (add_vcall_offset_vtbl_entries_1): Use the same code for
+ the lost primary case and the normal case.
+ (dfs_unshared_virtual_bases): Don't lose a non-virtual primary base.
+ (get_vfield_offset, get_derived_offset): Lose.
+ (dfs_find_final_overrider): Use look_for_overrides_here.
+ (get_matching_virtual): New fn.
+ * semantics.c (emit_associated_thunks): Check BV_USE_VCALL_INDEX_P,
+ not BV_VCALL_INDEX.
+ * search.c (look_for_overrides_here): Split out from...
+ (look_for_overrides_r): Here.
+
+ * class.c (find_final_overrider): Return error_mark_node on error.
+
+ * decl2.c (key_method): #if 0 accidental change.
+
+2001-06-06 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * call.c (convert_default_arg): Use INTEGRAL_TYPE_P.
+ (build_over_call): Likewise.
+ * decl.c (grokparms): Likewise.
+ * pt.c (tsubst_decl): Likewise.
+ * typeck.c (convert_arguments): Likewise.
+
+2001-06-05 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (begin_class_definition): Robustify.
+
+ * pt.c (instantiate_decl): Tell the repository code about the
+ clones, not the cloned functions.
+ * repo.c (repo_template_used): Explicitly instantiate the cloned
+ function, not the clones.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_user_type_conversion_1): Set ICS_USER_FLAG and
+ ICS_BAD_FLAG on created conversion.
+ (compare_ics): Break out rank.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (xref_tag): Remove extraneous %s on dependent name
+ lookup warning.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (layout_vtable_decl): Fix off by one error on
+ build_index_type.
+ (build_vtt): Likewise.
+ (build_ctor_vtbl_group): Likewise.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (maybe_indent_hierarchy): New function.
+ (dump_class_hierarchy_r): Add flags. Dump extra binfo
+ information, if enabled. Use maybe_indent_hierarchy. Adjust
+ output format.
+ (dump_class_hierarchy): Adjust prototype. Adjust output format.
+ (dump_array, dump_vtable, dump_vtt): New functions.
+ (finish_struct_1): Adjust hierarchy dumping.
+ (initialize_vtable): Call dump_vtable.
+ (build_vtt): Call dump_vtt.
+ (build_ctor_vtbl_group): Call dump_vtable.
+ * decl2.c (flag_dump_class_layout): Remove.
+ (cxx_decode_option): Remove dump translation unit
+ and dump class hierarchy check. Call dump_switch_p.
+ (finish_file): Adjust dumping.
+ (dump.c): Only dump base classes if not TDF_SLIM.
+ Only dump namespace members if not TDF_SLIM.
+ * optimize.c (dump_function): New function.
+ (optimize_function): Call dump_function.
+ * semantics.c (expand_body): Use dump_enabled_p.
+
+2001-06-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/2936
+ Part missed from first commit
+ * decl2.c (finish_anon_union): Copy context.
+
+2001-05-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/2936
+ * optimize.c (remap_decl): Remap anonymous aggregate members too.
+
+2001-05-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/2823
+ * semantics.c (expand_body): Don't optimize thunks.
+
+2001-05-25 Sam TH <sam@uchicago.edu>
+
+ * cp-tree.h lex.h: Fix header include guards.
+
+2001-05-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (init_decl_processing): Tweak.
+
+2001-05-24 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Tidy.
+ (init_decl_processing): Always set flag_no_builtin.
+
+2001-05-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2184
+ * decl2.c (do_local_using_decl): Push the decls, even in a
+ template.
+
+2001-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (initialize_inlined_parameters): Don't set
+ TREE_READONLY for a VAR_DECL taking the place of an inlined
+ PARM_DECL.
+
+2001-05-22 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c, cp-tree.h, rtti.c: Remove com_interface attribute support.
+ * tree.c (cp_valid_lang_attribute): Warn about use of com_interface
+ attribute.
+
+2001-05-22 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * parse.y: Refer to compound literals as such, not as
+ constructor-expressions.
+
+2001-05-21 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_op_delete_call): Ignore exception-specifications
+ when looking for matching delete operators.
+ * init.c (build_new_1): Compute whether or not the allocation
+ function used is a placement allocation function or not, and
+ communicate this information to build_op_delete_call.
+
+2001-05-21 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (build_vtable_entry_ref): Lose vtbl parm. Fix for new abi.
+ (build_vtbl_ref): Adjust.
+ (dfs_accumulate_vtbl_inits): Set TREE_CONSTANT on the vtable address.
+ * decl2.c (lang_f_options): Remove huge-objects, vtable-thunks.
+ Re-add vtable-gc.
+ (unsupported_options): Correspondingly.
+
+ * decl2.c (maybe_make_one_only): Check flag_weak, not
+ supports_one_only().
+
+ * cp-tree.def (START_CATCH_STMT): Lose.
+ * dump.c (cp_dump_tree): Don't dump it. Do dump HANDLER_PARMS.
+ * tree.c (cp_statement_code_p): Don't case it.
+ * semantics.c (cp_expand_stmt): Likewise.
+ * cp-tree.h (START_CATCH_TYPE): Lose.
+ (HANDLER_TYPE): New.
+ * except.c (expand_start_catch_block): Don't start any blocks.
+ Return the type.
+ (expand_end_catch_block): Don't end any blocks.
+ * parse.y (handler): Don't pass anything from finish_handler_parms
+ to finish_handler.
+ * pt.c (tsubst_expr): Likewise.
+ * semantics.c (begin_handler): Call note_level_for_catch here.
+ (finish_handler_parms): Don't return anything.
+ (genrtl_catch_block, begin_catch_block): Lose.
+ (genrtl_handler): Call expand_start_catch here.
+
+2001-05-18 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (build_vtable): Set DECL_ASSEMBLER_NAME for vtables here.
+ (get_vtable_decl, build_vtt): Not here.
+
+2001-05-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2781
+ * optimize.c (update_cloned_parm): Copy addressability and other
+ flags.
+
+2001-05-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (determine_specialization): Ignore artificial functions.
+
+2001-05-20 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (struct lang_identifier, C_RID_YYCODE): Update.
+ (C_RID_CODE): Remove.
+ * lex.c (cxx_init_options): Call set_identifier_size. Update.
+ (init_parse): Don't do it here.
+
+2001-05-18 Diego Novillo <dnovillo@redhat.com>
+
+ * decl2.c (finish_objects): Use the original SYMBOL_REF from the
+ function declaration to avoid stripping the symbol's attributes.
+
+2001-05-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (pushdecl): Adjust error string.
+ (xref_tag): Adjust friend class injection warning. Remove the
+ inherited name from the class shadowed scope.
+
+2001-05-17 Mark Mitchell <mark@codesourcery.com>
+
+ * except.c (cp_protect_cleanup_actions): New function.
+ (init_exception_processing): Don't set protect_cleanup_actions
+ here. Do set lang_protect_cleanup_actions.
+
+2001-05-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (read_token): Call yyerror on all unexpected tokens.
+
+2001-05-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (member_init_ok_or_else): Take a tree rather than
+ string for name.
+ (expand_member_init): Adjust.
+
+2001-05-14 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * decl.c (duplicate_decls): Suppress warning about duplicate
+ decls if the first decl is a friend.
+
+2001-05-12 Zack Weinberg <zackw@stanford.edu>
+
+ * except.c (choose_personality_routine): Export. Add
+ explanatory comment. Take an enum languages, not a boolean.
+ (initialize_handler_parm): Adjust to match.
+ * cp-tree.h: Prototype choose_personality_routine.
+ * lex.c (handle_pragma_java_exceptions): New function.
+ (init_cp_pragma): Register #pragma GCC java_exceptions.
+
+2001-05-12 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * method.c (build_mangled_C99_name): Remove unused prototype.
+
+2001-05-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * cp-tree.h (ptrmemfunc_vbit_where_t): Declare type.
+ * typeck.c (get_member_function_from_ptrfunc,
+ build_ptrmemfunc, expand_ptrmemfunc_cst): Take
+ TARGET_PTRMEMFUNC_VBIT_LOCATION into account.
+
+ Reverted Geoff Keating's 2001-05-03's patch.
+
+2001-05-11 Ira Ruben <ira@apple.com>
+
+ * cp/cp-tree.h (C_EXP_ORIGINAL_CODE): Delete; declared in c-common.h.
+
+2001-05-11 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (finish_label_expr, lookup_label): Delete.
+ * parse.y: Update for '&&'; don't issue warning here.
+ * semantics.c (finish_label_expr): Delete.
+
+2001-05-07 Mark Mitchell <mark@codesourcery.com>
+
+ * splay-tree.h (splay_tree_max): New function.
+ (splay_tree_min): Likewise.
+
+2001-05-03 Geoffrey Keating <geoffk@redhat.com>
+
+ * cp-tree.h (enum cp_tree_index): Add CPTI_PFN_VFLAG_IDENTIFIER.
+ (pfn_vflag_identifier): Define.
+ Update comment about layout of pointer functions.
+ (build_ptrmemfunc1): Update prototype.
+ (expand_ptrmemfunc_cst): Update prototype.
+ * decl.c (initialize_predefined_identifiers): Initialize
+ pfn_vflag_identifier.
+ (build_ptrmemfunc_type): When FUNCTION_BOUNDARY < 16, add
+ an extra field to the type.
+ * expr.c (cplus_expand_constant): Pass 'flag' between
+ expand_ptrmemfunc_cst and build_ptrmemfunc1.
+ * typeck.c (get_member_function_from_ptrfunc): When
+ FUNCTION_BOUNDARY < 16, look at additional field to determine
+ if a pointer-to-member is a real pointer or a vtable offset.
+ (build_ptrmemfunc1): Add new parameter to contain extra field.
+ (build_ptrmemfunc): Pass the extra field around.
+ (expand_ptrmemfunc_cst): Add new parameter to return extra field.
+ (pfn_from_ptrmemfunc): Ignore the extra field.
+
+2001-05-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (flag_inline_trees): Update documentation.
+ * decl.c (init_decl_processing): Adjust handling of
+ flag_inline_functions and flag_inline_trees to support -O3.
+ (grokfndecl): Set DECL_INLINE on all functions if that's what
+ the user requested.
+ (save_function_data): Clear DECL_INLINE in
+ current_function_cannot_inline is non-NULL.
+ * decl2.c (flag_inline_trees): Update documentation.
+
+2001-05-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * dump.c (cp_dump_tree, USING_STMT case): New case.
+ * tree.c (cp_statement_code_p): Add USING_STMT.
+ * decl2.c (do_using_directive): Add the using directive statement.
+
+ * tree.c (walk_tree): Reformat an if block.
+
+2001-05-02 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (compute_array_index_type): Don't try to do anything with
+ the indices when processing a template.
+
+2001-05-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c: NULL_PTR -> NULL.
+ * class.c: Likewise.
+ * cvt.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * except.c: Likewise.
+ * init.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2001-05-02 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (do_using_directive): Revert previous patch.
+
+2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.def (USING_STMT): New statement node.
+ * cp-tree.h (USING_STMT_NAMESPACE): New macro.
+ * decl2.c (do_using_directive): Add USING_STMT to statement
+ tree. Don't emit errors when processing template decl.
+ * pt.c (tsubst_expr, USING_STMT case): New case.
+ * semantics.c (cp_expand_stmt, USING_STMT case): New case.
+
+2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_new_op): Convert args from reference here.
+ (build_conditional_expr): Don't convert here.
+
+2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (last_token_id): New static variable.
+ (read_token): Set it here.
+ (yyerror): Use it here.
+
+2001-04-30 Richard Henderson <rth@redhat.com>
+
+ * cvt.c: Downcase C_PROMOTING_INTEGER_TYPE_P invocations.
+ * decl.c: Likewise.
+
+2001-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * gxxint.texi: Remove.
+ * Make-lang.in: Remove all traces of gxxint.texi.
+
+2001-04-30 Mark P Mitchell <mark@codesourcery.com>
+
+ * decl2.c (start_static_initialization_or_destruction): Correct
+ logic to handle the -fno-use-cxa-atexit case.
+
+2001-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (update_cloned_parm): New function.
+ (maybe_clone_body): Use it. Update the `this' parameter too.
+
+2001-04-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (unsupported_options): Add new-abi.
+ * lang-options.h: Remove no longer supported options.
+
+2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * except.c (can_convert_eh): Don't check template parms,
+ typename types etc.
+
+2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * optimize.c (maybe_clone_body): Copy parameter names and locations.
+
+2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (adjust_clone_args): Prototype new function.
+ * class.c (adjust_clone_args): New function.
+ * decl.c (start_function): Call it for in charge ctors.
+
+2001-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (use_thunk): Make sure that thunks really are emitted
+ when requested.
+
+2001-04-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * mangle.c (write_chars): New macro.
+ (hwint_to_ascii): New function
+ (write_number): Use it.
+ (write_integer_cst): Deal with really big numbers.
+
+2001-04-25 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (maybe_clone_body): Copy TREE_PUBLIC before emitting
+ the clone.
+
+2001-04-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Set context of namespace scope
+ TYPE_DECLS.
+
+2001-04-24 Zack Weinberg <zackw@stanford.edu>
+
+ * cp/optimize.c: Include hashtab.h.
+ (struct inline_data): Add tree_pruner.
+ (expand_call_inline, expand_calls_inline): Use it when calling
+ walk_tree.
+ (optimize_function): Initialize and free tree_pruner.
+
+2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ Lazy __FUNCTION__ generation.
+ * cp-tree.def (FUNCTION_NAME): Remove.
+ * cp-tree.h (function_name_declared_p): Remove.
+ (cp_fname_init): Prototype.
+ * decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
+ don't call declare_function_name. Call start_fname_decls.
+ (cp_make_fname_decl): Adjust parameters. Generate the name. Don't
+ clobber the line number.
+ (cp_fname_init): New function.
+ (start_function): Call start_fname_decls.
+ (finish_function): Call finish_fname_decls.
+ * lex.c (reswords): Add slots for __FUNCTION__ et al.
+ (rid_to_yy): Add mappings for __FUNCTION__ et al.
+ * optimize.c (maybe_clone_body): Remove function_name_declared_p.
+ * parse.y (VAR_FUNC_NAME): New token.
+ (primary): Add VAR_FUNC_NAME.
+ * pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
+ generation.
+ (tsubst, FUNCTION_NAME case): Remove.
+ (tsubst_copy, FUNCTION_NAME case): Remove.
+ (tsubst_expr, DECL_STMT case): Be careful with a
+ DECL_PRETTY_FUNCTION_P.
+ (instantiate_decl): Remove function_name_declared_p.
+ * semantics.c (begin_compound_statement): Don't call
+ declare_function_name here.
+ (setup_vtbl_ptr). Don't save & restore function_name_declared_p.
+ (finish_translation_unit): Call finish_fname_decls.
+ (expand_body): Remove function_name_declared_p.
+ * typeck2.c (digest_init): Allow any ERROR_MARK.
+
+2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_decl): Use VOID_TYPE_P.
+ * semantics.c: Fix some typos.
+
+2001-04-23 Phil Edwards <pme@sources.redhat.com>
+
+ * cp/decl2.c (flag_honor_std): Always initialize to 1.
+
+2001-04-22 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * xref.c (GNU_xref_file): Use concat in lieu of xmalloc/sprintf.
+
+2001-04-23 Jason Merrill <jason_merrill@redhat.com>
+
+ * except.c (build_throw): Wrap the initialization of the exception
+ object in a MUST_NOT_THROW_EXPR.
+ (do_free_exception): #if 0.
+
+2001-04-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (finish_enum): Change prototype.
+ * decl.c (finish_enum): Reorganize.
+ * parse.y (structsp): Adjust calls to finish_enum.
+
+2001-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (cp_tree_equal): Adjust final switch formatting. Add
+ 't' case.
+
+2001-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_unshared_virtual_bases): Add ATTRIBUTE_UNUSED.
+ (layout_empty_base): Return at end flag.
+ (build_base_field): Likewise.
+ (build_base_fields): Likewise.
+ (layout_virtual_bases): Don't add 1 to eoc value.
+ (end_of_class): Use full size for empty bases.
+ (layout_class_type): Clear CLASSNEARLY_EMPTY_P if we appended
+ empty bases. Don't add 1 to eoc value. Only add trailing padding
+ if we're an empty class with no empty bases.
+ (dump_class_hierarchy): Dump size and alignment.
+
+2001-04-20 Jakub Jelinek <jakub@redhat.com>
+
+ * call.c (maybe_handle_ref_bind): Copy ICS_USER_FLAG and
+ ICS_BAD_FLAG.
+
+2001-04-20 Jakub Jelinek <jakub@redhat.com>
+
+ * search.c (lookup_field_r): If looking for type and non-TYPE_DECL
+ is found, look first if name does not match the structure name.
+
+2001-04-19 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_LANGUAGE): Don't assume DECL_LANG_SPECIFIC is
+ set.
+ (SET_DECL_LANGUAGE): New macro.
+ * decl.c (duplicate_decls): Use SET_DECL_LANGUAGE.
+ (pushdecl): Likewise.
+ (build_library_fn_1): Likewise.
+ (build_cp_library_fn): Likewise.
+ (grokfndecl): Likewise.
+ (grokvardecl): Mark `extern "C"' variables as having C linkage.
+ * decl2.c (grokclassfn): Use SET_DECL_LANGUAGE.
+ * lex.c (retrofit_lang_decl): Likewise.
+ * mangle.c (mangle_decl_string): Don't mangle the names of
+ variables declared with C language linkage.
+ * semantics.c (finish_member_declaration): Use SET_DECL_LANGUAGE.
+
+2001-04-18 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Don't restore
+ flag_access_control from uninitialized storage.
+
+2001-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TYPE_PTRMEM_CLASS_TYPE): Improve documentation.
+ * mangle.c (write_pointer_to_member_type): Fix mangling of
+ pointers to cv-qualified member function types.
+
+ * init.c (build_delete): Create a SAVE_EXPR for the address if
+ we're going to use it more than once.
+
+2001-04-13 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DELTA2_FROM_PTRMEMFUNC): Remove.
+ (expand_ptremfunc_cst): Change prototype.
+ (delta2_from_ptrmemfunc): Remove.
+ * expr.c (cplus_expand_constant): Adjust call to
+ expand_ptrmemfunc_cst.
+ * typeck.c (build_ptrmemfunc1): Simplify.
+ (build_ptrmemfunc): Make sure that casting a PTRMEM_CST still
+ results in a constant.
+ (expand_ptrmemfunc_cst): Remove idx and delta2 parameters.
+ (delta2_from_ptrmemfunc): Remove.
+ (pfn_from_ptrmemfunc): Adjust call to expand_ptrmemfunc_cst.
+
+2001-04-12 Jason Merrill <jason_merrill@redhat.com>
+
+ * cp-tree.h (decl_namespace_list): New macro.
+ (struct saved_scope): Add decl_ns_list.
+ * decl.c (mark_saved_scope): Mark it.
+ * decl2.c: Lose static decl_namespace_list.
+ (init_decl2): Don't save it.
+
+2001-04-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (warn_return_type, yylex): Delete redundant
+ declarations.
+
+ * decl.c (current_class_depth, global_namespace): Likewise.
+
+ * decl2.c (current_class_depth, flag_gnu_xref): Likewise
+
+ * repo.c (flag_use_repository): Likewise.
+
+2001-04-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (pedantic, convert, global_bindings_p, insert_block,
+ set_block, pushdecl, getdecls, gettags, init_decl_processing,
+ maybe_build_cleanup, copy_lang_decl, prep_stmt, lvalue_p,
+ lvalue_or_else, print_lang_statistics, comp_target_types,
+ unsigned_type, signed_type, signed_or_unsigned_type,
+ build_function_call, mark_addressable, incomplete_type_error):
+ Delete redundant declarations.
+
+2001-04-11 Jason Merrill <jason_merrill@redhat.com>
+
+ * cp-tree.h (TYPE_LINKAGE_IDENTIFIER): New macro.
+ (TYPE_ANONYMOUS_P): New macro.
+ (TAGGED_TYPE_P): New macro.
+ * decl.c (check_tag_decl): Use TYPE_ANONYMOUS_P.
+ (grokfndecl, grokvardecl, grokdeclarator): Likewise.
+ * tree.c (no_linkage_helper): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+ * pt.c (convert_template_argument): Likewise.
+ * lex.c (check_for_missing_semicolon): Likewise.
+
+2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_unshared_virtual_bases): New function.
+ (mark_primary_bases): Call it.
+ (check_bases): Ignore virtual bases when determining
+ nearly-emptiness.
+
+2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (make_thunk): Clear DECL_CLONED_FUNCTION.
+
+2001-04-11 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (maybe_clone_body): Copy DECL_NUM_STMTS from the
+ cloned function to the clone.
+
+2001-04-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (cp/semantics.o): Depend on $(EXPR_H).
+
+ * semantics.c: Include expr.h.
+
+2001-04-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (implicitly_declare_fn): Commonize code for copy ctor
+ and assignment op. Set TREE_USED for parameter.
+
+2001-04-10 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (find_final_overrider_data): Add `candidates'.
+ (dfs_find_final_overrider): Don't issue error messages
+ prematurely.
+ (find_final_overrider): Issue error messages here.
+ (build_base_field): Don't warn about amgibuous direct bases here.
+ (warn_about_ambiguous_direct_bases): New function.
+ (layout_class_type): Use it.
+
+2001-04-10 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (build_array_ref): Push the array reference inside
+ COMPOUND_EXPR and COND_EXPR.
+
+2001-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_THIS_INLINE): Rename to DECL_DECLARED_INLINE_P.
+ * decl.c (duplicate_decls): Adjust accordingly.
+ (maybe_commonize_var): Likewise.
+ (grokfndecl): Likewise.
+ (start_function): Likewise.
+ (start_method): Likewise.
+ * decl2.c (key_method): Likewise.
+ (import_export_decl): Likewise.
+ * method.c (implicitly_declare_fn): Likewise.
+ * optimize.c (maybe_clone_body): Likewise.
+
+2001-04-05 Benjamin Kosnik <bkoz@redhat.com>
+
+ * lang-specs.h: Add __DEPRECATED.
+
+2001-04-05 J"orn Rennecke <amylaar@redhat.com>
+
+ * search.c (get_dynamic_cast_base_type): When building a new
+ constant, set its type to ssizetype.
+
+2001-04-04 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (expand_call_inline): Only add newly inlined statements
+ into inlined_stmts.
+
+2001-04-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (OPERATOR_ASSIGN_FORMAT): Remove.
+ (OPERATOR_FORMAT): Likewise.
+ (OPERATOR_TYPENAME_FORMAT): Likewise.
+ * operators.def: Remove old name-mangling information.
+ * decl.c (grok_op_properties): Adjust accordingly.
+ * lex.c (init_operators): Likewise.
+ * rtti.c (get_tinfo_decl): Issue error messages about types that
+ have variable size.
+
+2001-04-03 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (import_export_decl): Don't call import_export_class
+ when processing an inline member function.
+ * semantics.c (expand_body): Call import_export_decl before
+ emitting inline functions.
+
+2001-03-28 Richard Henderson <rth@redhat.com>
+
+ IA-64 ABI Exception Handling:
+ * cp-tree.def (EH_SPEC_BLOCK): New.
+ (MUST_NOT_THROW_EXPR): New.
+ * cp-tree.h: Update changed function declarations.
+ (CPTI_PUSH_EXCEPTION_IDENTIFIER): Remove.
+ (CPTI_CALL_UNEXPECTED): New.
+ (struct cp_language_function): Rename x_eh_spec_try_block
+ to x_eh_spec_block.
+ (EH_SPEC_STMTS, EH_SPEC_RAISES): New.
+ * decl.c (current_binding_level): If no current function
+ bindings, revert to scope_chain.
+ (initialize_predefined_identifiers): Remove __cp_push_exception.
+ (store_parm_decls): Use begin_eh_spec_block.
+ (finish_function): Use finish_eh_spec_block.
+ (mark_lang_function): Update for name changes.
+ * decl2.c (finish_file): No mark_all_runtime_matches.
+ * dump.c (cp_dump_tree): Handle new tree codes.
+ * error.c (dump_expr) [BIND_EXPR]: Fix typo.
+ * except.c (catch_language_init, catch_language): Remove.
+ (init_exception_processing): Don't set language code.
+ Initialize call_unexpected_node, protect_cleanup_actions,
+ eh_personality_libfunc, lang_eh_runtime_type.
+ (call_eh_info, push_eh_info, get_eh_info, get_eh_value): Remove.
+ (get_eh_type, get_eh_caught, get_eh_handlers): Remove.
+ (prepare_eh_type): Split out type canonicalizations ...
+ (build_eh_type_type): ... from here.
+ (build_eh_type_type_ref): Remove.
+ (mark_all_runtime_matches): Remove.
+ (build_exc_ptr): New.
+ (do_begin_catch, do_end_catch): New.
+ (do_pop_exception): Remove.
+ (build_terminate_handler): Remove.
+ (choose_personality_routine): Split out language choice from ...
+ (initialize_handler_parm): ... here.
+ Use MUST_NOT_THROW_EXPR.
+ (expand_start_catch_block): Use do_begin_catch. Simplify Java
+ exception object handling.
+ (expand_start_eh_spec, expand_end_eh_spec): Remove.
+ (expand_exception_blocks, alloc_eh_object): Remove.
+ (begin_eh_spec_block, finish_eh_spec_block): New.
+ (do_allocate_exception, do_free_exception): New.
+ (expand_throw): Merge into ...
+ (build_throw): ... here. Update for abi.
+ * expr.c (cplus_expand_expr): No expand_internal_throw.
+ Handle MUST_NOT_THROW_EXPR.
+ * pt.c (tsubst_expr): Handle EH_SPEC_BLOCK.
+ * semantics.c (*) Update for except.h name changes.
+ (genrtl_try_block): No protect_with_terminate.
+ (genrtl_eh_spec_block): New.
+ (genrtl_handler): Don't emit the goto here.
+ (cp_expand_stmt): Handle EH_SPEC_BLOCK.
+ (genrtl_finish_function): Don't expand_exception_blocks.
+ * tree.c (cp_statement_code_p): Handle EH_SPEC_BLOCK.
+
+2001-03-28 Richard Henderson <rth@redhat.com>
+
+ * decl.c (struct named_label_list): Rename eh_region to
+ in_try_scope, add in_catch_scope.
+ (struct binding_level): Rename eh_region to is_try_scope,
+ add is_catch_scope.
+ (note_level_for_try): Rename from note_level_for_eh.
+ (note_level_for_catch): New.
+ (poplevel): Copy both is_try_scope and is_catch_scope to
+ the named_label_list struct.
+ (check_previous_goto_1): Don't check for catch block via
+ DECL_ARTIFICIAL; use in_try_scope instead.
+ (check_goto): Likewise.
+ * cp-tree.h (note_level_for_try, note_level_for_catch): Declare.
+ * except.c (expand_start_catch_block): Call note_level_for_catch.
+ * semantics.c (begin_compound_stmt): Update for note_level_for_try.
+
+2001-03-27 Richard Henderson <rth@redhat.com>
+
+ * except.c: Use USING_SJLJ_EXCEPTIONS instead of
+ exceptions_via_longjmp.
+
+2001-03-27 Phil Edwards <pme@sources.redhat.com>
+
+ * pt.c (check_default_tmpl_args): Make error messages clearer.
+
+2001-03-26 Phil Edwards <pme@sources.redhat.com>
+
+ * error.c: Also undefine 'A' macro used for cp_printers definition.
+
+2001-03-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in: Depend on $(SYSTEM_H), not system.h.
+
+2001-03-26 Mike Yang <yang@research.att.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (dump_access): New function.
+ (cp_dump_tree): Use it. Dump basetype information for class
+ types.
+
+2001-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (optimize.o): Depend on params.h.
+ (duplicate_decls): Copy DECL_NUM_STMTS, not DECL_FRAME_SIZE.
+ (init_decl_processing): Set flag_no_inline when doing
+ inlining-on-trees.
+ * optimize.c: Include params.h.
+ (struct inline_data): Improve documentation of FNS. Add
+ FIRST_INLINED_FN, INLINED_STMTS, and CLONING_P.
+ (INSNS_PER_STMT): New macro.
+ (remap_block): Use CLONING_P.
+ (inlinable_function_p): Don't inline big functions.
+ (expand_call_inline): Keep track of how much inlining we've done.
+ (optimize_function): Set FIRST_INLINED_FN.
+ (maybe_clone_body): Set CLONING_P.
+ * semantics.c (simplify_aggr_init_exprs_r): Fix typing problems in
+ tree nodes.
+ (genrtl_finish_function): Clear DECL_DEFER_OUTPUT before calling
+ rest_of_compilation. Clear DECL_RTL for local variables
+ afterwards.
+ (clear_decl_rtl): New function.
+
+2001-03-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement DR 209
+ * cp-tree.h (skip_type_access_control,
+ reset_type_access_control): Prototype.
+ * decl.c (grokdeclarator): Access of friends is not checked.
+ * parse.y (component_decl_list): Reset type access control.
+ * semantics.c (decl_type_access_control): Clear
+ current_type_lookups.
+ (save_type_access_control): Don't save if not deferring.
+ (skip_type_access_control, reset_type_access_control): New
+ functions.
+ (begin_class_definition): Do type access control for basetypes.
+ Start deferred access control.
+ (finish_class_definition): Resume immediate access control if
+ this is a local class.
+
+2001-03-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (add_method): Use memcpy/memmove, not bcopy.
+
+ * decl.c (duplicate_decls): Likewise.
+
+2001-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ * mangle.c (write_discriminator): Use `_0' for discriminator 1,
+ not `_'.
+
+2001-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (local_names): Define.
+ (push_local_name): New.
+ (grok_reference_init): Return init if initializing static reference
+ variable with non-constant instead of emitting it.
+ Move expand_static_init call to cp_finish_decl.
+ (layout_var_decl): Call push_local_name.
+ (maybe_commonize_var): Allow inlining functions even if they have
+ static local variables, use comdat_linkage for them if flag_weak.
+ (check_initializer): Call obscure_complex_init if
+ grok_reference_init returned nonzero.
+ (save_function_data): Clear x_local_names.
+ (pop_cp_function_context): Free x_local_names.
+ (mark_inlined_fns): Remove.
+ (mark_lang_function): Mark x_local_names.
+ (lang_mark_tree): Don't mark DECL_ACCESS for DECL_DISCRIMINATOR_P.
+ Mark inlined_fns as tree, remove call to mark_inlined_fns.
+ * class.c (alter_access): Ensure DECL_ACCESS is never set if
+ DECL_DISCRIMINATOR_P.
+ * cp-tree.h (cp_language_function): Add x_local_names.
+ (lang_decl_flags): Add discriminator into u2.
+ (lang_decl_inlined_fns): Remove.
+ (lang_decl): inlined_fns is now a TREE_VEC.
+ (DECL_DISCRIMINATOR_P, DECL_DISCRIMINATOR): Define.
+ * optimize.c (inlinable_function_p): DECL_INLINED_FNS is now a
+ TREE_VEC, not a custom structure.
+ (optimize_function): Likewise.
+ * mangle.c (discriminator_for_local_entity): Discriminate among
+ VAR_DECL local entities.
+ * search.c (dfs_access_in_type): If DECL_DISCRIMINATOR_P, DECL_ACCESS
+ is not valid.
+
+2001-03-22 Bryce McKinlay <bryce@albatross.co.nz>
+
+ Add support for Java interface method calls.
+ * cp-tree.h (struct lang_type): Add java_interface flag.
+ (TYPE_JAVA_INTERFACE): New macro.
+ * tree.c (cp_valid_lang_attribute): Handle "java_interface" attribute
+ by setting TYPE_JAVA_INTERFACE.
+ * call.c (java_iface_lookup_fn): New static.
+ (build_over_call): If calling a method declared in a
+ TYPE_JAVA_INTERFACE, call build_java_interface_fn_ref to generate the
+ expression which resolves the function address.
+ (build_java_interface_fn_ref): New function.
+
+2001-03-22 Richard Henderson <rth@redhat.com>
+
+ * Make-lang.in (cp/except.o): Don't depend on insn-flags.h.
+ * except.c: Don't include it.
+
+2001-03-22 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+ based on an idea from Joe Buck <jbuck@synopsys.com>
+
+ * parse.y (bad_decl, template_arg_list_ignore, arg_list_ignore):
+ New nonterminals.
+ (data_def, component_decl): Add reductions to bad_decl.
+
+2001-03-22 Jakub Jelinek <jakub@redhat.com>
+
+ * method.c (do_build_assign_ref): Don't use build_modify_expr for
+ anonymous aggregates, since they don't have assignment operator
+ method.
+ * decl.c (fixup_anonymous_aggr): Disallow ctors, dtors and copy
+ assignment operators for anonymous structure fields.
+
+2001-03-21 Jason Merrill <jason@redhat.com>
+
+ * pt.c (instantiate_decl): Abort if we see a member constant
+ instantiation that doesn't already have its initializer.
+ Downgrade explicit instantiation without definition to pedwarn.
+
+ * cp-tree.h (DECL_TINFO_FN_P, SET_DECL_TINFO_FN_P): Remove.
+ * class.c (build_vtable_entry): Don't check DECL_TINFO_FN_P.
+ (import_export_decl): Check tinfo_decl_p, not DECL_TINFO_FN_P.
+
+ * cp-tree.h (CLASSTYPE_VTABLE_NEEDS_WRITING): Remove.
+ (pending_vtables): Remove.
+ * decl2.c (pending_vtables): Remove.
+ (import_export_vtable): Use CLASSTYPE_INTERFACE_ONLY, not
+ CLASSTYPE_VTABLE_NEEDS_WRITING.
+ (import_export_class): Likewise.
+ (init_decl2): Don't mark pending_vtables.
+ * lex.c (handle_pragma_vtable): Just sorry.
+ * pt.c (instantiate_class_template): Don't mess with
+ CLASSTYPE_VTABLE_NEEDS_WRITING.
+ (mark_class_instantiated): Likewise.
+ * ptree.c (print_lang_type): Don't print it.
+ * semantics.c (begin_class_definition): Don't set it.
+
+ * pt.c (template_tail): Replace with last_pending_template.
+ (maybe_templates, maybe_template_tail): Remove.
+ (add_pending_template): Adjust.
+ (instantiate_pending_templates): Adjust.
+
+ * cp-tree.h (struct saved_scope): Remove lang_stack field.
+ (current_lang_stack): Remove.
+ * decl.c (maybe_push_to_top_level): Don't initialize it.
+ (duplicate_decls): Use current_lang_depth.
+ (xref_basetypes): Likewise.
+ * class.c (current_lang_depth): New fn.
+ (push_lang_context): Use more varray functionality.
+ (pop_lang_context): Likewise.
+
+ * error.c (GLOBAL_THING): Always use '__'.
+
+2001-03-21 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_clone): Clear DECL_ASSEMBLER_NAME.
+
+ * mangle.c (mangle_decl_string): Mangle the names of overloaded
+ operators, even when they have `extern "C"' linkage.
+
+2001-03-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (get_vtable_decl): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (add_method): Remove optimization involving comparison of
+ DECL_ASSEMBLER_NAME.
+ (build_vtbl_or_vbase_field): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (check_methods): Likewise.
+ (build_clone): Likewise.
+ (built_vtt): Likewise.
+ * cp-tree.h (DECL_NEEDED_P): Likewise.
+ * decl.c (pushtag): Likewise.
+ (duplicate_decls): Likewise.
+ (pushdecl): Likewise.
+ (builtin_function): Likewise.
+ (build_library_fn_1): Set DECL_LANGUAGE for library functions.
+ (build_cp_library_fn): Likewise.
+ (maybe_commonize_var): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (make_rtl_for_nonlocal_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (grokfndecl): Likewise.
+ (grokvardecl): Likewise.
+ (grokdeclarator): Likewise.
+ (start_function): Likewise.
+ (cp_missing_return_ok_p): Likewise.
+ * decl2.c (grokclassfn): Likewise.
+ (check_classfn): Likewise.
+ (finish_static_data_member_decl): Likewise.
+ (grokfield): Likewise.
+ * error.c (GLOBAL_IORD_P): Remove.
+ (dump_global_iord): Improve output.
+ (dump_decl): Avoid using DECL_ASSEMBLER_NAME.
+ * except.c (nothrow_libfn_p): Summarily reject any function not in
+ namespace-scope.
+ * init.c (build_java_class_ref): Don't explicitly set
+ DECL_ASSEMBLER_NAME after calling mangle_decl.
+ * mangle.c (mangle_decl_string): Handle extern "C" functions.
+ (mangle_decl): Set the DECL_ASSEMBLER_NAME for the decl.
+ * method.c (set_mangled_name_for_decl): Don't explicitly set
+ DECL_ASSEMBLER_NAME after calling mangle_decl.
+ (make_thunk): Explicitly set the DECL_ASSEMBLER_NAME and
+ IDENTIFIER_GLOBAL_VALUE for the thunk.
+ * pt.c (set_mangled_name_for_template_decl): Remove.
+ (check_explicit_specialization): Don't use it.
+ (looup_template_class): Don't set DECL_ASSEMBLER_NAME.
+ (tsubst_friend_function): Likewise.
+ (tsubst_decl): Likewise.
+ (regenerate_decl_from_template): Use COPY_DECL_ASSEMBLER_NAME.
+ * rtti.c (get_tinfo_decl): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (tinfo_base_init): Likewise.
+ (create_real_tinfo_var): Likewise.
+ * search.c (looup_field_1): Likewise.
+ * semantics.c (finish_named_return_value): Likewise.
+ * tree.c (init_tree): Set lang_set_decl_assembler_name.
+
+2001-03-15 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ Correct semantics restrictions checking in throw-expression.
+ * except.c (is_admissible_throw_operand): New function.
+ (build_throw): Use it.
+
+2001-03-14 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cp_make_fnname_decl): Set DECL_IGNORED_P on __FUNCTION__
+ and its ilk.
+
+2001-03-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_clone): Use COPY_DECL_RTL, DECL_RTL_SET_P, etc.
+ * cp-tree.h (DECL_IN_MEMORY_P): Likewise.
+ * decl.c (duplicate_decls): Likewise.
+ (builtin_function): Likewise.
+ (build_library_fn): Likewise.
+ (build_cp_library_fn): Likewise.
+ (check_initializer): Likewise.
+ (cp_finish_decl): Likewise.
+ * decl2.c (grokfield): Likewise.
+ (grok_function_init): Remove #if 0'd code.
+ (finish_anon_union): Use COPY_DECL_RTL, DECL_RTL_SET_P, etc.
+ * friend.c (do_friend): Likewise.
+ * init.c (get_temp_regvar): Likewise.
+ * method.c (make_thunk): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+ (tsubst_decl): Likewise.
+ (regenerate_decl_from_template): Likewise.
+ * semantics.c (genrtl_named_return_value): Likewise.
+ (expand_body): Likewise.
+ (genrtl_finish_function): Likewise.
+ * tree.c (cp_tree_equal): Likewise.
+
+2001-03-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (convert_like_real): Add extra semantics to INNER
+ parameter. Don't convert to temporary if a user conversion
+ gives us an lvalue that we're about to bind to a reference.
+ Set INNER to indicate pending reference binding on recursive
+ calls.
+
+2001-03-10 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/lex.c: Delete duplicate pending_lang_change.
+
+2001-03-10 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/lex.c (handle_pragma_interface, handle_pragma_implementation):
+ Similarly.
+ * cp/repo.c (get_base_filename, open_repo_file): Similarly.
+ * cp/cp-tree.h: Remove file_name_nondirectory prototype.
+
+2001-03-09 Zack Weinberg <zackw@stanford.edu>
+
+ * Make-lang.in: Add dependencies on $(TM_P_H) as appropriate.
+
+2001-03-08 Stan Shebs <shebs@apple.com>
+
+ * cp-tree.h (set_identifier_local_value): Remove unused decl.
+
+2001-03-06 Zack Weinberg <zackw@stanford.edu>
+
+ * spew.c: Remove references to CPP_OSTRING.
+
+2001-03-06 Andrew Haley <aph@redhat.com>
+
+ * typeck.c (convert_arguments): Check that we have an fndecl.
+
+2001-03-05 Andrew Haley <aph@redhat.com>
+
+ * typeck.c (convert_arguments): Don't do ellipsis conversion for
+ __built_in_constant_p.
+
+2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_static_cast): Allow enum to enum conversions
+ as per DR 128.
+
+2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (check_field_decls): Pointers to member do not a
+ non-pod struct make, as per DR 148.
+
+2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (joust): cp_pedwarn when using gnu extension concerning
+ worst conversion sequences.
+
+2001-03-01 Zack Weinberg <zackw@stanford.edu>
+
+ * decl.c: Replace all uses of 'boolean' with 'bool'.
+
+2001-03-01 Zack Weinberg <zackw@stanford.edu>
+
+ * lang-specs.h: Add zero initializer for cpp_spec field to
+ all array elements that need one. Don't put an #ifdef inside
+ the initializer list; set a default for CPLUSPLUS_CPP_SPEC and
+ use it.
+
+2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement using decls inside template functions.
+ * decl2.c (validate_nonmember_using_decl): Don't special case
+ fake_std_node in the global namespace. Don't reject early when
+ processing a template.
+ (do_local_using_decl): Add to statement tree. Don't do further
+ processing when building a template.
+ * pt.c (tsubst_expr, DECL_STMT case): Deal with USING_DECLs.
+
+2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (do_nonmember_using_decl): Don't complain if we find
+ same function. Do complain about ambiguating extern "C"
+ declarations.
+
+2001-02-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove floating point and complex type template constant parms.
+ * pt.c (convert_nontype_argument): Remove REAL_TYPE and
+ COMPLEX_TYPE extensions.
+ (invalid_nontype_parm_type_p): Likewise.
+
+2001-02-27 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * except.c (call_eh_info): Revert "match_function"'s type.
+
+2001-02-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ Fix ctor vtable vcall offsets.
+ * class.c (struct vtbl_init_data_s): Add rtti_binfo member.
+ (build_rtt_vtbl_entries): Lose RTTI_BINFO parameter.
+ (get_matching_base): Remove.
+ (get_original_base): New function.
+ (build_vtbl_initializer): Initialize vid.rtti_binfo.
+ Use a virtual thunk for a ctor vtable with an index
+ (add_vcall_offset_vtbl_entries_1): Check if binfo has lost a
+ primary base within a constructor vtable. Only set
+ BV_VCALL_INDEX when not a constructor vtable. Adjust vcall offset
+ when primary base has been lost.
+ * cp-tree.h (BINFO_VIRTUALS): Remove ambiguity from comment.
+
+2001-02-26 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * call.c (joust): Ensure more_specialized()'s argument length
+ parameter has correct value for constructors.
+
+2001-02-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * except.c (call_eh_info): Cleanup generation of cp_eh_info struct.
+
+ * decl.c (mark_inlined_fns): Prototype.
+
+2001-02-22 Mark Mitchell <mark@codesourcery.com>
+
+ * spew.c (yylex): Correct handling of friends.
+
+2001-02-22 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_encoding): Pass write_function_type the
+ FUNCTION_DECL for the function being encoded.
+ (write_function_type): Pass it along to write_bare_function_type.
+ (write_bare_function_type): Pass it along to write_method_parms.
+ (write_method_parms): Don't mangle the compiler-generated
+ parameters to a constructor or destructor.
+
+2001-02-22 Andreas Jaeger <aj@suse.de>
+
+ * optimize.c: Include toplev.h for
+ note_deferral_of_defined_inline_function prototype.
+
+2001-02-22 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (struct lang_decl_inlined_fns): New.
+ (struct lang_decls): Add inlined_fns.
+ (DECL_INLINED_FNS): New macro.
+ * optimize.c (struct inline_data): Add inlined_fns.
+ (declare_return_variable): Use VARRAY_ACTIVE_SIZE macro.
+ (inlinable_function_p): Likewise, fix typo in comment,
+ function is not inlinable if it already inlined function currently
+ being optimized.
+ (expand_call_inline): Add fn to inlined_fns if necessary.
+ (optimize_function): Initialize inlined_fns.
+ Save inlined_fns into DECL_INLINED_FNS after expanding inlines.
+ * decl.c (mark_inlined_fns): New function.
+ (lang_mark_tree): Call it.
+
+2001-02-21 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (struct lang_decl_flags): Remove uninlinable flag.
+ (DECL_UNINLINABLE): Move to middle-end.
+
+ * class.c (clone_function_decl): Set DECL_ABSTRACT on original fn.
+ * decl.c (duplicate_decls): Preserve DECL_ABSTRACT.
+ * class.c (build_clone): Set DECL_ABSTRACT_ORIGIN for the clone.
+ * optimize.c (maybe_clone_body): Set DECL_ABSTRACT_ORIGIN for the
+ parms and outer BLOCK. note_deferral_of_defined_inline_function.
+
+ * method.c (implicitly_declare_fn): Don't set DECL_ARTIFICIAL on
+ second parm of op=.
+
+2001-02-19 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (set_decl_namespace): Allow explicit instantiations in
+ any namespace.
+
+2001-02-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * optimize.c (expand_call_inline): Don't walk subtrees of type
+ nodes.
+
+2001-02-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_vcall_offset_vtbl_entries_1): Only add one entry
+ for a destructor.
+
+2001-02-18 Jason Merrill <jason@redhat.com>
+
+ Do put the VTT parameter in DECL_ARGUMENTS.
+ * cp-tree.h (struct cp_language_function): Add x_vtt_parm.
+ (current_vtt_parm): New macro.
+ (struct lang_decl_flags): Add has_vtt_parm_p, remove vtt_parm.
+ (DECL_HAS_VTT_PARM_P): New macro.
+ (DECL_VTT_PARM): Remove.
+ (FUNCTION_FIRST_USER_PARMTYPE, FUNCTION_FIRST_USER_PARM): New macros.
+ * decl.c (duplicate_decls): Only copy the operator code if
+ appropriate.
+ (start_function): Set current_vtt_parm.
+ (lang_mark_tree): Don't mark vtt_parm.
+ * decl2.c (maybe_retrofit_in_chrg): Do add the VTT parm to
+ DECL_ARGUMENTS. Set DECL_HAS_VTT_PARM_P.
+ * class.c (build_clone): Maybe remove the VTT parm.
+ * optimize.c (maybe_clone_body): Set up the VTT parm.
+ * pt.c (copy_default_args_to_explicit_spec): Preserve the VTT parm.
+ * call.c (build_over_call): Just allow the VTT arg.
+ * method.c (make_thunk): Don't set DECL_VTT_PARM.
+ (do_build_copy_constructor): Use FUNCTION_FIRST_USER_PARM.
+ (synthesize_method): Use FUNCTION_FIRST_USER_PARMTYPE.
+ * decl.c (grokdeclarator, copy_args_p, grok_ctor_properties): Likewise.
+ * error.c (dump_function_decl): Likewise.
+ * call.c (build_user_type_conversion_1, convert_like_real): Abort
+ if we try to call a constructor with in-charge or VTT parms.
+ * method.c (skip_artificial_parms_for): New fn.
+ * call.c (add_function_candidate, build_over_call): Call it.
+ * call.c (build_new_method_call): Use current_vtt_parm.
+ * init.c (expand_virtual_init): Likewise.
+ * class.c (same_signature_p): No longer static.
+ * cp-tree.h: Declare it.
+ * search.c (look_for_overrides_r): Use it.
+
+2001-02-17 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (new_abi_rtti_p): Remove.
+ (name_mangling_version): Likewise.
+ (flag_do_squangling): Likewise.
+ * class.c (build_rtti_vtbl_entries): Remove old ABI support.
+ * decl.c (grokfndecl): Likewise.
+ * decl2.c (name_mangling_version): Remove.
+ (flag_do_squangling): Likewise.
+ (lang_f_options): Remove `squangle'.
+ (unsupported_options): Add `squangle'.
+ (cxx_decode_option): Issue a warning about uses of
+ -fname-mangling-version.
+ (finish_file): Remove old ABI support.
+ * pt.c (check_explicit_specialization): Likewise.
+ (tsubst_decl): Likewise.
+ * rtti.c (init_rtti_processing): Likewise.
+ (build_headof): Likewise.
+ (get_tinfo_decl_dynamic): Likewise.
+ (tinfo_from_decl): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ (synthesize_tinfo_var): Likewise.
+ * init.c (build_new): Allow enumeration types for the array-bounds
+ in a direct-new-declarator.
+
+ * semantics.c (finish_typeof): Resolve OFFSET_REFs.
+
+ * pt.c (check_explicit_specialization): Copy TREE_PRIVATE and
+ TREE_PROTECTED from the template being specialized.
+
+2001-02-17 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (build_artificial_parm): Set TREE_READONLY.
+
+ * decl.c (bad_specifiers): Allow throw specs on things with
+ pointer-to-function or -member-function type.
+ * init.c (build_default_init): Don't use a CONSTRUCTOR to initialize
+ a pmf.
+
+2001-02-17 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (check_dtor_name): Handle template names correctly.
+
+2001-02-16 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_USE_VTT_PARM): Remove.
+ * decl2.c (maybe_retrofit_in_chrg): Don't create it.
+ * optimize.c (maybe_clone_body): Don't substitute it.
+ * call.c (build_new_method_call): Check in_chrg instead.
+ * init.c (expand_virtual_init): Likewise.
+
+2001-02-16 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl.c (check_tag_decl): Make sure a typedef for an anonymous
+ class-type introduces at least a type-name.
+
+2001-02-16 Jakub Jelinek <jakub@redhat.com>
+
+ * call.c (convert_like_real): Create a temporary for non-lvalue.
+
+2001-02-16 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * cp-tree.h: Fix typos in comments.
+
+2001-02-16 Jason Merrill <jason@redhat.com>
+
+ * optimize.c (remap_block): If we're compiling a clone, pass the
+ new block to insert_block.
+
+2001-02-16 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (finish_asm_stmt): Robustify.
+
+2001-02-15 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (push_template_decl_real): Don't remangle the name of a
+ class template.
+
+2001-02-15 Jim Meyering <meyering@lucent.com>
+
+ * Make-lang.in (c++.install-common): Depend on installdirs.
+ (c++.install-info): Likewise.
+ (c++.install-man): Likewise.
+
+2001-02-15 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck2.c (build_m_component_ref): Robustify.
+
+2001-02-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * friend.c (do_friend): Don't take the nested [template] class
+ into account when deciding whether to warn about the friend
+ function not referring to a template function.
+
+2001-02-14 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck.c (build_unary_op): Clarify error message.
+
+2001-02-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * parse.y (component_constructor_declarator): allow optional
+ parentheses around constructor class name.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (setup_vtbl_ptr): Move prototype to semantics.c
+ section.
+ * init.c (emit_base_init): Remove incorrect comment about
+ virtual bases.
+ * method.c (make_thunk): Fix comment alignment.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ Kill remnants of this is variable.
+ * cp-tree.h (flag_this_is_variable): Remove.
+ * decl2.c (flag_this_is_variable): Remove.
+ * class.c (fixed_type_or_null): Add cdtor parm. Adjust.
+ (build_vbase_path): The path is non-static, even in a cdtor.
+ (resolves_to_fixed_type_p): Add additional return value.
+ * search.c (init_vbase_pointers): Adjust.
+ * tree.c (lvalue_p_1): Adjust.
+ * typeck.c (mark_addressable): Adjust.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (unify): Don't check cv quals of array types.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (cp_build_qualified_type_real): Use CP_TYPE_QUALS to
+ check whether we already have the type.
+
+2001-02-13 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_DESTRUCTORS): Fix typo in comment.
+ * call.c (build_op_delete_call): Simplify to remove duplicate
+ code.
+ * class.c (clone_function_decl): Don't build the deleting variant
+ of a non-virtual destructor.
+ * decl.c (finish_destructor_body): Don't call delete if this is a
+ non-virtual destructor.
+ * init.c (build_delete): Explicitly call `operator delete' when
+ deleting an object with a non-virtual destructor.
+
+2001-02-13 Jason Merrill <jason@redhat.com>
+
+ * lang-specs.h: Add more __EXCEPTIONS.
+
+2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck2.c (process_init_constructor): Check
+ TREE_HAS_CONSTRUCTOR before issuing missing init warning.
+
+2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (maybe_adjust_types_for_deduction, DEDUCE_ORDER case):
+ Remove spurious information in comment. Allow further
+ adjustments of REFERENCE_TYPE args.
+
+2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * errfn.c (cp_deprecated): Tweak diagnostic text.
+ * parse.y (new_initializer): Deprecate initializer lists
+ extension.
+
+2001-02-12 Mark Mitchell <mark@codesourcery.com>
+
+ Remove old ABI support.
+
+2001-02-11 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (flag_vtable_thunks): Always set it to 1.
+ (flag_new_abi): Likewise.
+ * lang-specs.h: Remove conditional on ENABLE_NEW_GXX_ABI.
+
+ * Makefile.in (g++spec.o): Fix typo.
+
+2001-02-09 Jason Merrill <jason@redhat.com>
+
+ * lang-specs.h: Restore definition of __EXCEPTIONS.
+
+2001-02-08 Jason Merrill <jason@redhat.com>
+
+ * search.c (shared_member_p): New function.
+ (lookup_field_r): Use it.
+ * cp-tree.h (SHARED_MEMBER_P): Remove.
+
+ * method.c (process_overload_item): Handle template-dependent array
+ bounds.
+ * pt.c (type_unification_real): If we end up with undeduced nontype
+ parms, try again.
+
+ * decl.c (lookup_name_real): Tweak warning to refer to decls, not
+ types.
+
+ * typeck2.c (friendly_abort): Don't say anything if we have
+ earlier errors or sorries.
+
+ * decl.c (check_tag_decl): Notice attempts to redefine bool and
+ wchar_t. Ignore if in_system_header.
+
+ * decl.c (maybe_push_cleanup_level): New fn...
+ (start_decl_1): ...split out from here.
+ * cvt.c (build_up_reference): Use it.
+ * cp-tree.h: Declare it.
+
+2001-02-07 Mark Mitchell <mark@codesourcery.com>
+
+ * lang-specs.h: Use CPLUSPLUS_CPP_SPEC for the preprocessor
+ spec.
+
+2001-02-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Make sure it's a primary
+ template or template_template_parm when called from the parser.
+ (instantiate_template_class): Add assertion.
+
+2001-02-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * method.c (build_mangled_name) [old abi]: Protect flush_repeats()
+ from error_mark_node.
+
+2001-02-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ Fix specification and implementation bugs in V3 ABI
+ construction vtables.
+ * cp-tree.h (flag_dump_class_layout): New flag.
+ (BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P): Remove.
+ (BINFO_LOST_PRIMARY_P): New flag.
+ (SET_BINFO_NEW_VTABLE_MARKED): Adjust asserts.
+ (BINFO_PRIMARY_MARKED_P): Rename to ...
+ (BINFO_PRIMARY_P): ... here.
+ (binfo_via_virtual): New prototype.
+ * decl2.c (flag_dump_class_layout): New flag.
+ (cxx_decode_option): Set it. Adjust -fdump-translation-unit to
+ use `=' as a file name separator.
+ * init.c (dfs_initialize_vtbl_ptrs): Walk into virtual primary
+ bases.
+ (build_vtbl_address): If this is a virtual primary base, then
+ get the vtbl of what it is ultimately primary for.
+ * search.c (dfs_skip_nonprimary_vbases_unmarkedp): Adjust
+ for BINFO_PRIMARY_P.
+ (dfs_skip_nonprimary_vbases_markedp): Likewise.
+ (get_shared_vbase_if_not_primary): Likewise.
+ (dfs_get_pure_virtuals): Likewise.
+ (expand_upcast_fixups): Likewise.
+ (fixup_virtual_upcast_offsets): Likewise.
+ (dfs_find_vbase_instance): Likewise.
+ (find_vbase_instance): Likewise.
+ (binfo_from_vbase): Adjust comment to reflect reality.
+ (binfo_via_virtual): New function.
+ * class.c (VTT_TOP_LEVEL_P, VTT_MARKED_BINFO_P): New macros
+ for binfo walking during VTT construction.
+ (dfs_mark_primary_bases): Remove.
+ (force_canonical_binfo_r): New function.
+ (force_canonical_binfo): New function.
+ (mark_primary_virtual_base): New function.
+ (mark_primary_bases): Walk in inheritance graph order, use
+ mark_primary_virtual_base.
+ (determine_primary_base): Use some more intermediate variables.
+ (dfs_find_final_overrider): Don't check for overriding along a
+ virtual path.
+ (dfs_modify_vtables): Walk into primary virtual bases too.
+ (walk_subobject_offsets): Adjust for BINFO_PRIMARY_P.
+ (build_base_fields): Likewise.
+ (dfs_set_offset_for_unshared_vbases): Likewise.
+ (layout_virtual_bases): Likewise.
+ (end_of_class): Likewise.
+ (finish_struct_1): Call dump_class_hierarchy, if requested.
+ (dfs_get_primary_binfo): Use BINFO_TYPE for binfos.
+ (dump_class_hierarchy_r): Add stream parameter. Emit more information.
+ (dump_class_hierarchy): Add file parameter. Append to file, if
+ required.
+ (finish_vtbls): Adjust accumulate_vtbl_inits call.
+ Use canonical base for virtual bases.
+ (build_vtt): Add more comments. Adjust build_vtt_inits call.
+ (build_vtt_inits): Remove VIRTUAL_VTTS_P parm.
+ Only set BINFO_VPTR_INDEX on top level. Use VTT_TOP_LEVEL_P,
+ VTT_MARKED_BINFO_P for binfo walking. Use canonical vbase for
+ virtual VTTs.
+ (dfs_build_secondary_vptr_vtt_inits): Extract VTT_TOP_LEVEL_P
+ from DATA. We want virtual primary bases and all bases via virtual.
+ Only set BINFO_VPTR_INDEX for top level. Look up from a primary
+ virtual base when not a construction vtable.
+ (dfs_ctor_vtable_bases_queue_p): New DFS predicate.
+ (build_ctor_vtbl_group): Adjust accumulate_vtbl_inits call.
+ Use canonical bases when processing virtual bases.
+ (accumulate_vtbl_inits): We're interested in any base via a
+ virtual path.
+ (dfs_accumulate_vtbl_inits): If this is a primary virtual base
+ within a construction vtable, determine what is being overridden.
+ (build_vtbl_initializer): Add more comments
+ (add_vcall_offset_vtbl_entries_1): Adjust comment.
+ (build_rtti_vtbl_entries): Check if the base has lost its
+ primary.
+
+2001-02-05 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (g++spec.o): Adjust use of DRIVER_DEFINES.
+
+2001-02-04 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (pushdecl): Call abort instead of fatal.
+ * except.c (decl_is_java_type): Call fatal_error instead of fatal.
+ * init.c (build_new_1): Likewise.
+ (build_java_class_ref): Call internal_error and fatal_error, not fatal.
+ * decl.c (build_typename_type): hash_table_init now returns void.
+ decl.c (init_decl_processing): Make an error non-fatal.
+
+2001-02-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_INTERFACE_UNKNOWN): Fix formatting.
+ Document.
+ (CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN_X): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ * decl.c (maybe_commonize_var): Use the new name-mangling where
+ appropriate.
+ * decl2.c (comdat_linkage): Enhance comments. Make all
+ compiler-generated things static, if COMDAT is not available.
+ (get_tinfo_decl): Do not make typeinfo objects that belong in the
+ library COMDAT.
+ (tinfo_base_init): Use the correct mangled name for typeinfo
+ strings, and push them into the global scope.
+ (typeinfo_in_lib_p): New function.
+ (synthesize_tinfo_var): Use it.
+ (create_real_tinfo_var): Likewise.
+
+2001-02-03 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (push_class_binding): Use context_for_name_lookup instead
+ of CP_DECL_CONTEXT.
+ * search.c (context_for_name_lookup): Remove static. Check for NULL
+ context in the loop.
+ * cp-tree.h (context_for_name_lookup): Add prototype.
+
+2001-02-02 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (build_expr_ptr_wrapper, can_free): Remove.
+ * tree.c (build_expr_ptr_wrapper, can_free, permanent_obstack):
+ Remove.
+ * call.c (convert_class_to_reference, build_user_type_conversion_1,
+ add_warning): Change build_expr_ptr_wrapper to build_ptr_wrapper.
+
+2001-02-02 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (g++spec.o): Add DRIVER_DEFINES to the list
+ of macros used when compiling g++spec.c.
+ * g++spec.c (lang_specific_driver): Link with the shared
+ libgcc by default.
+
+2001-01-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (build_expr_from_tree), lex.c (make_pointer_declarator,
+ make_reference_declarator, make_call_declarator), method.c
+ (implicitly_declare_fn), parse.y (namespace_using_decl,
+ notype_unqualified_id, expr_or_declarator, new_type_id,
+ after_type_declarator, direct_after_type_declarator,
+ notype_declarator, complex_notype_declarator,
+ complex_direct_notype_declarator, qualified_id,
+ notype_qualified_id, overqualified_id, direct_new_declarator,
+ absdcl, direct_abstract_declarator, conversion_declarator), pt.c
+ (tsubst), semantics.c (begin_constructor_declarator): Use build_nt
+ instead of build_parse_node.
+
+2001-01-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (cp_tree_index): Delete CPTI_MINUS_ONE.
+ (minus_one_node): Moved to top level gcc directory. Renamed
+ to integer_minus_one_node.
+
+ * init.c (init_init_processing): Don't set minus_one_node.
+ (build_vec_init): Use integer_minus_one_node.
+
+ * rtti.c (get_tinfo_decl_dynamic): Likewise.
+
+2001-01-28 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (copy_body_r): If MODIFY_EXPR has both arguments
+ identical and they would be replaced with constant, remove
+ MODIFY_EXPR from the tree.
+
+2001-01-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in: Remove all dependencies on defaults.h.
+ * call.c: Don't include defaults.h.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * except.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2001-01-25 Jakub Jelinek <jakub@redhat.com>
+
+ * mangle.c (write_mangled_name, write_encoding): Mangle overloaded
+ operators even in "C" linkage.
+ * method.c (set_mangled_name_for_decl): Likewise.
+ * decl.c (grokfndecl): Call set_mangled_name_for_decl even for
+ overloaded operators in "C" linkage.
+
+2001-01-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_decl): Remove IN_DECL parameter.
+ (tsubst_arg_types): Check parameter is not void.
+ (tsubst): Adjust tsubst_decl call.
+
+2001-01-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (add_builtin_candidate): Quote std properly, from
+ previous change.
+
+2001-01-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (check_explicit_specialization): Clone constructors and
+ destructors.
+
+2001-01-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Don't presume DECL_LANG_SPECIFIC
+ indicates anything special about template depth. Make sure we
+ only count the user visible template classes.
+
+2001-01-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_conv): Typo in comment.
+ (add_builtin_candidate): Add more explanation.
+ Remove extra test for ENUMERAL_TYPE in {PRE,POST}INCREMENT_EXPR.
+ Allow ENUMERAL_TYPEs for relops and eqops. Add both candidates
+ when we have enumeral types.
+ (add_builtin_candidates): Add more explanation. Add ENUMERAL_TYPE
+ candidates for relops and eqops.
+ (joust): Simplify control flow. Allow a non-template user
+ function to hide a builtin.
+
+2001-01-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (unification_kind_t): Add DEDUCE_ORDER.
+ (more_specialized): Add deduction parameter.
+ * call.c (joust): Adjust more_specialized call.
+ * pt.c (UNIFY_ALLOW_OUTER_MORE_CV_QUAL,
+ UNIFY_ALLOW_OUTER_LESS_CV_QUAL): New unify flags.
+ (get_bindings_order): Remove.
+ (get_bindings_real): Add DEDUCE parameter.
+ (maybe_adjust_types_for_deduction): Return extra unify flags. Do
+ REFERENCE_TYPE jig for DEDUCE_ORDER.
+ (type_unification_real): Deal with DEDUCE_ORDER. Use result of
+ maybe_adjust_types_for_deduction.
+ (more_specialized): Add DEDUCE parameter. Call get_bindings_real
+ directly.
+ (try_one_overload): Use result of maybe_adjust_types_for_deduction.
+ (check_cv_quals_for_unify): Use new unify qualifier flags.
+ (unify): Clear new unify qualifier flags.
+ (get_bindings_real): Add DEDUCE parameter.
+ (get_bindings): Adjust call to get_bindings_real.
+ (get_bindings_overload): Likewise.
+ (most_specialized_instantiation): Adjust call to
+ more_specialized.
+
+2001-01-19 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (flag_vtable_thunks): Also depend on ENABLE_NEW_GXX_ABI.
+
+ * decl.c (init_decl_processing): Just force -fvtable-thunks on if
+ -fnew-abi.
+
+2001-01-19 Ute Pelkmann <scope.muc@t-online.de>
+
+ * decl2.c (arg_assoc_class): Fix double iteration logic.
+
+2001-01-19 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_delete): Always call convert_force to strip cv-quals.
+
+ * decl2.c (flag_new_abi): Depend on ENABLE_NEW_GXX_ABI.
+ * lang-specs.h: Default ABI depends on ENABLE_NEW_GXX_ABI.
+ * g++spec.c: Don't look at ENABLE_NEW_GXX_ABI.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (get_vbase_1): Count only virtual bases.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (duplicate_tag_error): Robustify flag clearing.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (lookup_template_class): Add complain parm.
+ * decl.c (lookup_namespace_name): Adjust call to
+ lookup_template_class.
+ (make_typename_type): Likewise.
+ * semantics.c (finish_template_type): Likewise.
+ * pt.c (lookup_template_class): Add complain parm. Adjust.
+ (tsubst_aggr_type): Pass COMPLAIN down to lookup_template_class.
+ (tsubst): Likewise.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (copy_default_args_to_explicit_spec): Preserve
+ object's CV quals. Reorganize.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_modify_expr): Say `initialization' for
+ INIT_EXPRs.
+ * init.c (build_default_init): Convert to enumeral type, if
+ needed.
+
+2001-01-18 Jakub Jelinek <jakub@redhat.com>
+
+ * parse.y (nomods_initdcl0): Properly set things up for
+ initdcl0_innards.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (UNIFY_ALLOW_OUTER_LEVEL): New unify flag.
+ (type_unification_real): Set it.
+ (unify): Use it.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (finish_destructor_body): Convert to vbase pointer here.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c (begin_class_definition): Check we're not inside a
+ template parm list.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (walk_tree, TREE_LIST): Don't walk the TREE_PURPOSE of
+ BASELINK_P.
+
+2001-01-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * typeck.c (build_function_call_real): Call fold on the CALL_EXPR.
+ * call.c (build_over_call): Add comment.
+
+2001-01-16 Daniel Berlin <dberlin@redhat.com>
+
+ * cvt.c (ocp_convert): Handle vector type conversion
+ * typeck2.c (digest_init): Handle vector type initializations
+
+2001-01-16 Phil Edwards <pme@sources.redhat.com>
+
+ * g++spec.c: Don't add libraries needlessly if -fsyntax-only
+ was given.
+
+2001-01-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (check_nontype_parm): Rename to ...
+ (invalid_nontype_parm_type_p): ... here.
+ (process_template_parm): Adjust.
+ (convert_template_argument): Adjust.
+
+2001-01-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (check_nontype_parm): New function.
+ (process_template_parm): Use it.
+ (convert_template_argument): Use it.
+ (convert_nontype_argument, RECORD_TYPE): Assert it's a ptr to
+ member.
+
+2001-01-14 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * tree.c: Add defaults.h
+ (cp_valid_lang_attribute): Incorporate SUPPORTS_INIT_PRIORITY.
+ * Make-lang.in (cp/tree.o): Add defaults.h.
+
+2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Add c-format.o.
+
+2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g++.1: Change to be ".so man1/gcc.1".
+
+2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (c++.info, c++.install-info): Build and install g++
+ internals info.
+ (c++.uninstall, c++.maintainer-clean): Remove g++ internals info.
+ ($(srcdir)/cp/g++int.info): New target.
+ * gxxint.texi: Add info directory entry. Use @@ in email address.
+ * .cvsignore: Update.
+
+2001-01-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_c_cast): Do template processing earlier.
+ Always pedwarn on array casts.
+
+2001-01-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * friend.c (make_friend_class): Make sure a templated class is
+ actually a template.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (get_guard): Set linkage from guarded decl.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (convert_default_arg): Check for unprocessed
+ DEFAULT_ARG.
+ * cp-tree.h (replace_defarg): Move to spew.c.
+ (maybe_snarf_defarg, add_defarg_fn, do_pending_defargs): Move to
+ spew.c, which is where they really are.
+ (done_pending_defargs): Declare.
+ (unprocessed_defarg_fn): Declare.
+ * decl.c (replace_defarg): Move to spew.c
+ * parse.y (structsp): Call done_pending_defargs.
+ * spew.c (defarg_fns): Rearrange list structure.
+ (defarg_fnsdone): New static variable.
+ (defarg_depfns): New static variable.
+ (init_spew): Adjust.
+ (add_defarg_fn): Store the type in TREE_TYPE.
+ (do_pending_defargs): Detect and deal with ordering constraints
+ and circularity.
+ (done_pending_defargs): New function.
+ (unprocessed_defarg_fn): New function.
+ (replace_defarg): Moved from decl.c. Robustify. Don't save
+ if circularity detected.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (unify): Check array has a domain, before checking
+ whether it is variable sized.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokparms): Unobfuscate and get correct diagnostic for
+ parameters with pointers to arrays of unknown bound.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (template_parm_header, template_spec_header): New
+ reductions. Split out from ...
+ (template_header): ... here. Use them.
+ (template_template_parm): Use template_parm_header.
+ * semantics.c (finish_template_template_parm): Add assert.
+
+2001-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_builtin_type): Fix thinko.
+
+ * pt.c (copy_default_args_to_explicit_spec_1): New function.
+ (copy_default_args_to_explicit_spec): Likewise.
+ (check_explicit_specialization): Use it.
+
+ * class.c (finish_struct_1): Remove last argument in call to
+ make_decl_rtl; use make_function_rtl instead of make_decl_rtl.
+ * decl.c (builtin_function): Likewise.
+ (build_cp_library_fn): Likewise.
+ (check_initializer): Likewise.
+ (make_rtl_for_nonlocal_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (start_function): Likewise.
+ * decl2.c (finish_anon_union): Likewise.
+ * friend.c (do_friend): Likewise.
+ * init.c (build_java_class_ref): Likewise.
+ * method.c (make_thunk): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+ * semantics.c (expand_body): Likewise.
+
+2001-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_CLONED_FUNCTION_P): Avoid wild reads by not
+ looking at DECL_CLONED_FUNCTION for non-functions.
+
+2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (dump_template_parameter): Use parm to determine how
+ to print default value.
+
+2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (duplicate_tag_error): Clear more flags.
+
+2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_new_method_call): Use binfo_for_vbase.
+
+2001-01-10 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * cp-tree.h (flag_cond_mismatch): Don't declare.
+ * decl2.c (flag_cond_mismatch): Don't define.
+ (lang_f_options): Remove cond-mismatch.
+ (unsupported_options): Add cond-mismatch.
+
+2001-01-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (handle_using_decl): Reject using of constructor name
+ of sourcing class. Allow injecting of a method with same name as
+ nested class. Fixup error messages.
+
+2001-01-09 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (lang_decode_option): Handle -Wformat=2.
+
+2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Rename defined_in_class to
+ initialized_in_class.
+ (DECL_DEFINED_IN_CLASS_P): Rename to ...
+ (DECL_INITIALIZED_IN_CLASS_P): ... here, to reflect true meaning.
+ * decl.c (duplicate_decls): Preseve DECL_INITIALIZED_IN_CLASS_P.
+ (cp_finish_decl): Adjust for DECL_INITIALIZED_IN_CLASS_P.
+ * pt.c (check_default_tmpl_args): Adjust for
+ DECL_INITIALIZED_IN_CLASS_P.
+ (instantiate_class_template): Likewise.
+ (instantiate_decl): Check DECL_INITIALIZED_IN_CLASS_P.
+
+ * class.c (finish_struct): Constify saved_filename.
+
+2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (duplicate_tag_error): Adjust diagnostic.
+ (finish_struct): Locally set location to start of struct.
+ * decl.c (fixup_anonymous_aggr): Use cp_error_at.
+
+2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (struct binding_level): Adjust class_shadowed comments
+ to reflect reality.
+ (push_class_level_binding): Adjust comments to reflect reality.
+ Set IDENTIFIER_CLASS_VALUE when replacing an existing binding.
+ Don't set TREE_VALUE on the class_shadowed list.
+
+2001-01-07 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * decl2.c (acceptable_java_type): Allow references too.
+ * init.c (build_java_class_ref): When using the new ABI, search
+ `class$' and have it mangled with `mangle_decl.'
+ * mangle.c (write_java_integer_type_codes): New function.
+ (write_builtin_type): Detect and mangle Java integer and real
+ types.
+
+2001-01-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (grokfield): Don't accept `asm' specifiers for
+ non-static data members.
+
+2001-01-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * expr.c (cplus_expand_expr): Don't reset `target'.
+
+2001-01-07 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/decl2.c (cxx_post_options): Call cpp_post_options.
+
+2001-01-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (template_datadef): Check for error_mark_node.
+
+2001-01-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.def (DEFAULT_ARG): Make `x' class.
+
+2001-01-04 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
+ (record_builtin_type): Make non-static.
+ (flag_short_double): Don't declare.
+ (init_decl_processing): Remove the creation of many tree nodes now
+ in c_common_nodes_and_builtins.
+ (build_void_list_node): New function.
+ * decl2.c (flag_short_double, flag_short_wchar): Don't define.
+ * cp-tree.h (flag_short_wchar): Don't declare.
+
+2001-01-04 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_conv): Don't use build1 for USER_CONV.
+ * pt.c (tsubst_copy): Or for PREINCREMENT_EXPR and similar nodes.
+
+2001-01-03 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * lex.c (lang_init): Call c_common_lang_init.
+
+2001-01-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (lookup_fnfields_here): Remove.
+ (look_for_overrides_r): Use lookup_fnfields_1.
+ Ignore functions from using declarations.
+
+2001-01-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement exceptions specifiers for implicit member functions.
+ * cp-tree.h (merge_exceptions_specifiers): Declare new function.
+ * method.c (synthesize_exception_spec): New function.
+ (locate_dtor, locate_ctor, locate_copy): New functions.
+ (implicitly_declare_fn): Generate the exception spec too.
+ * search.c (check_final_overrider): Check artificial functions
+ too.
+ * typeck2.c (merge_exception_specifiers): New function.
+
+2001-01-03 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_default_init): New fn.
+ (perform_member_init): Split out from here.
+ (build_new_1): Use it. Simplify initialization logic.
+ (build_vec_init): Take an array, rather than a pointer and maxindex.
+ Speed up simple initializations. Don't clean up if we're assigning.
+ * cp-tree.h: Adjust.
+ * decl2.c (do_static_initialization): Remove TREE_VEC case.
+ * parse.y (new_initializer): Return void_zero_node for ().
+ * typeck.c (build_modify_expr): Handle getting a CONSTRUCTOR.
+ * typeck2.c (digest_init): Only complain about user-written
+ CONSTRUCTORs.
+
+2000-12-22 Mike Stump <mrs@wrs.com>
+
+ * decl2.c: (max_tinst_depth): Increase to 50.
+
+2001-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (invalidate_class_lookup_cache): Zero the
+ previous_class_values.
+ * cp-tree.h (TMPL_PARMS_DEPTH): Use TREE_INT_CST_LOW, not
+ TREE_INT_CST_HIGH.
+ (CLASSTYPE_TEMPLATE_LEVEL): Likewise.
+ * decl.c (free_bindings): New variable.
+ (push_binding): Don't create a new binding if we have one on the
+ free list.
+ (pop_binding): Put old bindings on the free list.
+ (init_decl_processing): Use size_int, not build_int_2.
+ Register free_bindings as a GC root.
+ (cp_make_fname_decl): Use size_int, not build_int_2.
+ (push_inline_template_parms_recursive): Likewise.
+ (end_template_parm_list): Likewise.
+ (for_each_template_parm): Do not use walk_tree_without_duplicates.
+ (tsubst_template_parms): Use size_int, not build_int_2.
+ (tsubst): Likewise.
+ * rtti.c (get_vmi_pseudo_type_info): Likewise.
+
+2001-01-02 Richard Henderson <rth@redhat.com>
+
+ * parse.y (asm): Set ASM_INPUT_P.
+
+2001-01-02 Jason Merrill <jason@redhat.com>
+
+ * tree.c (cp_valid_lang_attribute): Don't set CLASSTYPE_COM_INTERFACE
+ for v3 ABI.
+
+ * typeck.c (cp_truthvalue_conversion): New fn.
+ * cvt.c (ocp_convert): Use it.
+
+ * cp-tree.h: Lose c-common.c decls.
+
+ * typeck.c (build_unary_op): Restore old &a.f diagnostic code.
+ * cvt.c (convert_to_void): Use type_unknown_p.
+
+ * typeck.c (strip_all_pointer_quals): Also strip quals from
+ pointer-to-member types.
+
+ * Make-lang.in (cp/TAGS): Use --no-globals. Ignore parse.c, and treat
+ parse.y as C.
+
+ * call.c (build_new_method_call): Do evaluate the object parameter
+ when accessing a static member.
+ * typeck.c (build_component_ref): Likewise.
+
+2001-01-02 Andreas Jaeger <aj@suse.de>
+
+ * decl.c (cp_missing_noreturn_ok_p): New.
+ (init_decl_processing): Set lang_missing_noreturn_ok_p.
+
+
+Copyright (C) 2001 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2002 b/gcc-4.9/gcc/cp/ChangeLog-2002
new file mode 100644
index 000000000..16dc2cd60
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2002
@@ -0,0 +1,4581 @@
+2002-12-31 Neil Booth <neil@daikokuya.co.uk>
+
+ * .cvsignore: Remove.
+
+2002-12-31 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * call.c, class.c, cp-lang.c, cp-tree.h, cvt.c, dump.c, error.c,
+ except.c, expr.c friend.c, g++spec.c, init.c, lang-options.h,
+ lang-specs.h, lex.c, mangle.c, method.c, optimize.c, parser.c,
+ pt.c, ptree.c, repo.c, rtti.c, search.c, semantics.c, tree.c,
+ typeck.c, typeck2.c: Replace "GNU CC" with "GCC" in the
+ copyright header.
+ * lex.h: parse.y is dead, so don't mention it. Also replace the
+ copyright header with the default GNU copyright header.
+
+2002-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (LOOKUP_TEMPLATES_EXPECTED): Remove.
+ (lookup_name_namespace_only): Likewise.
+ (begin_only_namespace_names): Likewise.
+ (end_only_namespace_names): Likewise.
+ * decl.c (only_namespace_names): Remove.
+ (qualify_lookup): Do not check LOOKUP_TEMPLATES_EXPECTED.
+ (lookup_name_real): Do not check only_namespace_names.
+ (lookup_name_namespace_only): Remove.
+ (begin_only_namespace_names): Likewise.
+ (end_only_namespace_names): Likewise.
+ * parser.c (cp_parser_nested_name_specifier_opt): Handle erroneous
+ nested-name-specifiers more gracefully.
+ (cp_parser_class_or_namespace_name): Avoid looking up namespace
+ names when they cannot possibly appear.
+ (cp_parser_template_name): Adjust call to cp_parser_lookup_name.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_namespace_name): Only look for namespace names.
+ (cp_parser_lookup_name): Add is_namespace parameter.
+ (cp_parser_lookup_name_simple): Adjust call to
+ cp_parser_lookup_name.
+
+ * parser.c (cp_parser_dependent_type_p): Fix thinko.
+
+2002-12-31 Neil Booth <neil@daikokuya.co.uk>
+
+ * .cvsignore: Update.
+
+2002-12-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (modify_vtable_entry): Remove unused variable.
+ (get_vcall_index): Always expect a non-thunk.
+ (update_vtable_entry_for_fn): Combine covariant adjustments, when
+ overriding a thunk. Pass get_vcall_index a non-thunk.
+
+ * decl2.c (finish_file): Mark undefined inlines as extern.
+
+2002-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (RETURN_INIT): Remove.
+ * cp-tree.h (DECL_IN_MEMORY_P): Remove.
+ (scope_kind): Add sk_block, sk_try, sk_catch, sk_for.
+ (note_level_for_for): Remove.
+ (note_level_for_try): Likewise.
+ (note_level_for_catch): Likewise.
+ (finish_named_return_value): Likewise.
+ (do_pushlevel): Change prototype.
+ (pending_lang_change): Remove.
+ * decl.c (begin_scope): Handle sk_block, sk_try, sk_catch,
+ sk_for.
+ (note_level_for_for): Remove.
+ (note_level_for_try): Likewise.
+ (note_level_for_catch): Likewise.
+ (maybe_inject_for_scope_var): Remove use of DECL_IN_MEMORY_P.
+ * parser.c (cp_parser_context_free_list): Make it "deletable".
+ (cp_parser_template_argument): Remove misleading comment.
+ * pt.c (tsubst_expr): Remove RETURN_INIT code.
+ * semantics.c (genrtl_named_return_value): Remove.
+ (do_pushlevel): Take a scope kind as an argument.
+ (begin_if_stmt): Adjust.
+ (begin_while_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_for_init_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (begin_handler): Likewise.
+ (begin_compound_stmt): Likewise.
+ (finish_named_return_value): Remove.
+ (cp_expand_stmt): Remove RETURN_INIT case.
+ * tree.c (cp_statement_code_p): Remove RETURN_INIT case.
+
+2002-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9112
+ * parser.c (cp_parser_direct_declarator): Handle erroneous
+ parenthesized declarators correctly.
+
+2002-12-31 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (pending_lang_change): Declare.
+
+2002-12-30 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_context_free_list): New variable.
+ (cp_parser_context_new): Use it.
+ (cp_parser_error): Check return code from
+ cp_parser_simulate_error.
+ (cp_parser_simulate_error): Return a value.
+ (cp_parser_id_expression): Optimize common case.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_class_specifier): Adjust call to
+ cp_parser_late_parsing_default_args.
+ (cp_parser_lookup_name): Optimize common case.
+ (cp_parser_late_parsing_for_member): Adjust call to
+ cp_parser_late_parsing_default_args.
+ (cp_parser_late_parsing_default_args): Add scope parameter.
+ (cp_parser_require): Avoid creating the error message unless it's
+ needed.
+ (cp_parser_parse_definitely): Place free'd contexts on the free
+ list.
+
+ * parser.c (cp_parser_declaration_seq_opt): Handle pending_lang_change.
+
+2002-12-30 David Edelsohn <edelsohn@gnu.org>
+
+ * parser.c (cp_parser_parameter_declaration_clause): Treat system
+ header as extern "C" if NO_IMPLICIT_EXTERN_C undefined.
+
+2002-12-30 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config-lang.in, Make-lang.in, operators.def, cp-tree.def:
+ GCC, not GNU CC.
+
+2002-12-30 Mark Mitchell <mark@codesourcery.com>
+
+ * parse.y: Remove.
+ * spew.c: Likewise.
+ * Make-lang.in (gt-cp-spew.h): Remove.
+ * cp-tree.h (do_pending_lang_change): Remove.
+ (do_identifier): Change prototype.
+ (finish_id_expr): Remove.
+ * decl.c (lookup_name_real): Remove yylex variable.
+ * decl2.c (build_expr_from_tree): Adjust call to do_identifier.
+ * lex.c (init_cpp_parse): Remove.
+ (reduce_cmp): Likewise.
+ (token_cmp): Likewise.
+ (yychar): Likewise.
+ (lastiddecl): Likewise.
+ (token_count): Likewise.
+ (reduce_count): Likewise.
+ (yyhook): Likewise.
+ (print_parse_statistics): Likewise.
+ (do_pending_lang_change): Likewise.
+ (do_identifier): Remove parsing parameter.
+ * lex.h (lastiddecl): Remove.
+ (looking_for_typename): Remove.
+ (looking_for_template): Likewise.
+ (pending_lang_change): Likewise.
+ (yylex): Likewise.
+ * semantics.c (finish_id_expr): Remove.
+
+ * decl.c (grokdeclarator): Diagnost "extern thread" and "static
+ thread" correctly.
+
+2002-12-30 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * decl.c, decl2.c, decl.h: GCC, not GNU CC. This is the C++ front
+ end, not the C front end.
+
+2002-12-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (THUNK_TARGET): New macro.
+ (THUNK_VIRTUAL_OFFSET): For result thunks it is always a binfo.
+ (finish_thunk): Remove offset parms.
+ * class.c (find_final_overrider): Look through thunks.
+ (get_vcall_index): Use THUNK_TARGET.
+ (update_vtable_entry_for_fn): Look through thunks. Set covariant
+ fixed offset here. Adjust finish_thunk call.
+ (build_vtbl_initializer): Adjust finish_thunk calls.
+ * mangle.c (mangle_call_offset): Remove superfluous if.
+ (mangle_thunk): Adjust.
+ * method.c (make_thunk): Adjust.
+ (finish_thunk): Adjust.
+ (thunk_adjust): Remove assert.
+ (use_thunk): Use THUNK_TARGET
+ * dump1.c (cp_dump_tree): Adjust thunk dumping.
+
+ PR c++/9054
+ * class.c (layout_class_type): Set TYPE_CONTEXT of type for base.
+ * dump.c (cp_dump_tree, RECORD_TYPE): Deal with type for base types.
+
+2002-12-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 4/n.
+ * decl2.c (grok_method_quals, warn_if_unknown_interface,
+ grok_x_components, cp_build_parm_decl, build_artificial_parm,
+ maybe_retrofit_in_chrg, grokclassfn, grok_array_decl,
+ delete_sanity, check_member_template, check_java_method,
+ check_classfn, finish_static_data_member_decl, grokfield,
+ grokbitfield, grokoptypename, grok_function_init,
+ cplus_decl_attributes, constructor_name, defer_fn,
+ build_anon_union_vars, finish_anon_union, coerce_new_type,
+ coerce_delete_type, comdat_linkage, maybe_make_one_only,
+ key_method, import_export_vtable, import_export_class,
+ output_vtable_inherit, import_export_decl, import_export_tinfo,
+ build_cleanup, get_guard, get_guard_bits, get_guard_cond,
+ set_guard, start_objects, finish_objects,
+ start_static_storage_duration_function,
+ finish_static_storage_duration_function, get_priority_info,
+ start_static_initialization_or_destruction,
+ finish_static_initialization_or_destruction,
+ do_static_initialization, do_static_destruction,
+ prune_vars_needing_no_initialization, write_out_vars,
+ reparse_decl_as_expr, finish_decl_parsing, namespace_ancestor,
+ add_using_namespace, merge_functions, ambiguous_decl,
+ lookup_using_namespace, lookup_using_namespace,
+ qualified_lookup_using_namespace, set_decl_namespace,
+ decl_namespace, current_decl_namespace, push_decl_namespace,
+ pop_decl_namespace, push_scope, pop_scope, add_function,
+ arg_assoc_namespace, arg_assoc_template_arg, arg_assoc,
+ lookup_arg_dependent, do_namespace_alias,
+ validate_nonmember_using_decl, do_nonmember_using_decl,
+ do_toplevel_using_decl, do_local_using_decl,
+ do_class_using_decl, do_using_directive, check_default_args,
+ mark_used, handle_class_head): Use C90 prototypings. Use booleans.
+ * parser.c (cp_parser_class_head): Use booleanss.
+ * decl.c (walk_globals, walk_vtables): Likewise.
+ * cp-tree.h (walk_globals_pred, walk_globals_fn, walk_vtables,
+ walk_globals): Change return type from 'int' to 'bool'.
+ * rtti.c (init_rtti_processing, build_headof, throw_bad_cast
+ throw_bad_typeid, get_tinfo_decl_dynamic, typeid_ok_p,
+ build_typeid, tinfo_name, get_tinfo_decl, get_tinfo_ptr,
+ get_typeid, ifnonnull, build_dynamic_cast_1, build_dynamic_cast,
+ qualifier_flags, tinfo_base_init, generic_initializer,
+ ptr_initializer, dfs_class_hint_mark, ptm_initializer,
+ dfs_class_hint_unmark, class_hint_flags, class_initializer,
+ typeinfo_in_lib_p, get_pseudo_ti_init, create_pseudo_type_info,
+ get_pseudo_ti_desc, create_tinfo_types, emit_support_tinfos,
+ unemitted_tinfo_decl_p, emit_tinfo_decl): Likewise.
+ * repo.c (repo_compile_flags, repo_template_declared,
+ repo_template_defined, repo_class_defined, repo_get_id,
+ repo_template_used, repo_vtable_used, repo_inline_used,
+ repo_tinfo_used, repo_template_instantiated, extract_string,
+ open_repo_file, afgets, init_repo, reopen_repo_file_for_write,
+ finish_repo): Likewise.
+ * ptree.c (cxx_print_decl, cxx_print_type, cxx_print_identifier,
+ cxx_print_xnode): Likewise..
+ * cp-lang.c (ok_to_generate_alias_set_for_type, cxx_get_alias_set,
+ cxx_warn_unused_global_decl, cp_expr_size): Likewise.
+ * cxxfilt.c (demangle_it, print_demangler_list, usage,
+ standard_symbol_characters, hp_symbol_characters, main, fatal):
+ Likewise.
+ (strip_underscore): Change type from 'int' to 'bool'.
+ (main): Use boolean constants.
+
+2002-12-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 3/n.
+ * cvt.c (cp_convert_to_pointer, convert_to_pointer_force,
+ build_up_reference, warn_ref_binding, convert_to_reference,
+ convert_from_reference, convert_lvalue, cp_convert, ocp_convert,
+ convert_to_void, convert, convert_force, build_type_conversion,
+ build_expr_type_conversion, type_promotes_to,
+ perform_qualification_conversions): Use C90 prototyping style.
+ * decl2.c (grok_array_decl): Use boolean constant.
+ (delete_sanity): Likewise.
+ * typeck.c (build_unary_op): Likewise.
+ * semantics.c (finish_switch_cond): Likewise.
+ * parser.c (cp_parser_direct_new_declarator): Likewise.
+ * init.c (build_new): Likewise.
+
+2002-12-27 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (po-generated): Remove parse.c.
+ (CXX_OBJS): Remove parse.o and spew.o. Add parser.o.
+ ($(srcdir)/cp/parse.h): Remove target.
+ ($(srcdir)/cp/parse.c): Likewise.
+ (gt-cp-parse.h): Likewise.
+ (gt-cp-parser.h): New target.
+ (c++.distclean): Do not remove parse.output.
+ (c++.maintainer-clean): Do not remove parse.c or parse.h.
+ (cp/spew.o): Remove target.
+ (cp/lex.o): Adjust dependencies.
+ (cp/pt.o): Likewise.
+ (cp/parse.o): Likewise.
+ (cp/TAGS): Do not mention parse.c.
+ (cp/parser.o): New target.
+ * NEWS: Mention the new parser.
+ * call.c (build_scoped_method_call): Simplify.
+ (build_method_call): Likewise.
+ (build_new_function_call): Adjust calls to add_function_candidate
+ and add_template_candidate.
+ (build_new_op): Improve handling of erroroneous operands.
+ (convert_default_arg): Remove circular argument processing.
+ (name_as_c_string): New function.
+ (build_new_method_call): Use it.
+ (perform_implicit_conversion): Use error_operand_p.
+ * class.c (finish_struct_anon): Use constructor_name_p.
+ (check_field_decls): Likewise.
+ (pop_nested_class): Use OVL_NEXT, not OVL_CHAIN.
+ (resolve_address_of_overloaded_function): Likewise.
+ (instantiate_type): Tweak pointer-to-member handling.
+ (get_primary_binfo): Remove incorrect assertion.
+ * config-lang.in (gtfiles): Add parser.c, remove parse.c.
+ * cp-tree.h (DEFARG_TOKENS): New macro.
+ (default_arg): New structure.
+ (cp_tree_node_structure_enum): Add TS_CP_DEFAULT_ARG.
+ (lang_tree_node): Add default_arg.
+ (cp_tree_index): Add CPTI_TYPE_INFO_REF_TYPE.
+ (type_info_ref_type): New macro.
+ (saved_scope): Make processing_explicit_instantiation a boolean.
+ (check_access): New field.
+ (unparsed_text): Remove.
+ (language_function): Remove unparsed_inlines.
+ (error_operand_p): New macro.
+ (lang_decl): Adjust pending_inline_info.
+ (DEFARG_POINTER): Remove.
+ (tag_types): Add typenames.
+ (lookup_ualified_name): Declare.
+ (lookup_name_real): Likewise.
+ (shadow_tag): Adjust prototype.
+ (get_scope_of_declarator): Declare it.
+ (process_next_inline): Remove it.
+ (check_for_missing_semicolon): Likewise.
+ (maybe_get_template_decl_from_type_decl): Declare it.
+ (finish_label_stmt): Adjust prototype.
+ (finish_non_static_data_meber): Declare it.
+ (finish_pseudo_destructor_call_expr): Rename to ...
+ (finish_pseudo_destructor_expr): ... this.
+ (finish_compound_literal): Declare it.
+ (begin_inline_definitions): Remove it.
+ (init_spew): Remove.
+ (peekyylex): Likewise.
+ (arbitrate_lookup): Likewise.
+ (frob_opname): Likewise.
+ (maybe_snarf_defarg): Likewise.
+ (add_defarg_fn): Likewise.
+ (do_pending_defargs): Likewise.
+ (done_pending_defargs): Likewise.
+ (unprocessed_defarg_fn): Likewise.
+ (replace_defarg): Likewise.
+ (end_input): Likewise.
+ (get_overloaded_fn): Likewise.
+ * cvt.c (convert_to_reference): Improve error handling.
+ * decl.c (lookup_name_real): Do not declare it static.
+ (maybe_push_to_top_level): Set check_access.
+ (identifier_type_value): Adjust call to lookup_name_real.
+ (lookup_qualified_name): New method.
+ (lookup_name_real): Remove special-case parsing code.
+ (lookup_name-nonclass): Adjust call to lookup_name_real.
+ (lookup_name_namespace_only): Likewise.
+ (lookup_name): Likewise.
+ (check_tag_decl): Return the type declared.
+ (shadow_tag): Likewise.
+ (register_dtor_fn): Tweak check_access.
+ (grokfndecl): Use constructor_name_p.
+ (get_scope_of_declarator): New function.
+ (grokdeclarator): Obscure tweaks for slightly different declarator
+ representations.
+ (start_method): Return error_mark_node to indicate failure.
+ (cp_tree_node_structure_enum): Use TS_CP_DEFAULT_ARG for DEFAULT_ARGs.
+ * decl2.c (constructor_name_full): Simplify.
+ (constructor_name): Use it.
+ (build_expr_from_tree): Adjust for changes to do new parser.
+ (push_scope): Improve robustness.
+ (validate_nonmember_using_decl): Process declarations, not names.
+ (do_class_using_decl): Likewise.
+ (handle_class_head): Do not mess with CLASSTYPE_DECLARED_CLASS
+ here.
+ * error.c (dump_expr): Handle IDENTIFIER_NODEs and BASELINKs.
+ * expr.c (cxx_expand_expr): Handle BASELINKs.
+ * init.c (member_init_ok_or_else): Issue more errors.
+ (build_offset_ref): Tweak handling of FUNCTION_DECLs.
+ * lex.c: Do not include parse.h.
+ (yypring): Do not declare.
+ (yylval): Likewise.
+ (make_reference_declarator): Remove error-generating code.
+ (rid_to_yy): Remove.
+ (cxx_init): Do not call init_spew.
+ (yypring): Remove.
+ (check_for_missing_semicolon): Remove.
+ * lex.h (got_scope): Remove.
+ (got_object): Remove.
+ * method.c (hack_identifier): Use finish_non_static_data_member.
+ (implicitly_declare_fn): Adjust use of constructor_name.
+ * parser.c: New file.
+ * pt.c (parse.h): Do not include it.
+ (maybe_get_template_decl_from_template): Do not declare it.
+ (finish_member_template_decl): Tweak.
+ (begin_explicit_instantiation): Adjust for
+ processing_explicit_instantiation being boolean.
+ (end_explicit_instantiation): Likewise.
+ (maybe_process_partial_specialization): Tighten specialization
+ test.
+ (retrieve_local_specialization): Adjust ue of hash table.
+ (eq_local_specializations): New function.
+ (register_local_specialization): Likewise.
+ (push_template_decl_real): Remove unnecessary test.
+ (maybe_get_template_decl_from_type_decl): Don't make it static.
+ (for_each_template_parm_r): Handle TYPEOF_TYPE.
+ (tsubst_copy): Use retrieive_local_specialization to handle
+ PARM_DECL. Adjust handling of CONST_DECLs. Handle BASELINKs.
+ Handle COMPONENT_REFs with pseudo-destructor-expressions.
+ Simplify handling of CALL_EXPR and METHOD_CALL_EXPR.
+ (tsubst_expr): Pass decls, not names, to do_local_using_decl.
+ (unify): Tweak handling of CONST_DECLs.
+ (regenerate_decl_from_template): Use push_nested_class.
+ (template_for_substitution): New funciton.
+ (instantiate_decl): Use it. Register parameters as local
+ specializations.
+ * rtti.c (init_rtti_processing): Set type_info_ref_type.
+ (build_typeid): Use it.
+ (get_typeid): Likeise.
+ * search.c (accessible_p): Use check_access, not
+ flag_access_control.
+ (adjust_result_of_qualified_name_lookup): Pay attention to the
+ context_class.
+ * semantics.c (finish_asm_stmt): Adjust error handling.
+ (finish_label_stmt): Return the statement.
+ (finish_non_static_data_member): New function.
+ (finish_class_expr): Handle BASELINKs.
+ (finish_call_expr): Handle PSEUDO_DTOR_EXPR.
+ (finish_object_call_expr): Simplify handling during templates.
+ (finish_pseudo_destructor_call_expr): Rename to ...
+ (finish_pseudo_dtor_expr): ... this.
+ (finish_compound_literal): New function.
+ (begin_inline_definitions): Remove.
+ (finish_sizeof): Remove special template handling.
+ * spew.c: Do not include parse.h.
+ * tree.c (get_overloaded_fn): Remove.
+ * typeck.c (build_class_member_access_expr): Handle
+ PSEUDO_DTOR_EXPR. Adjust handling of static member functions.
+ (lookup_destructor): New function.
+ (finish_class_member_access_expr): Use it.
+ (convert_arguments): Simplify.
+ (build_unary_op): Handle BASELINKs.
+
+2002-12-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4803
+ * decl2.c (mark_used): Defer inline functions.
+ (finish_file): Merge deferred_fns loops. Check all used
+ inline functions have a definition.
+ * method.c (make_thunk): Thunks are not inline.
+
+ PR c++/5116, c++/764
+ * call.c (build_new_op): Make sure template class operands are
+ instantiated.
+
+2002-12-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR C++/7964
+ * cp-tree.h (resolve_scoped_fn_name): Prototype.
+ * call.c (resolve_scoped_fn_name): New function. Deal with
+ more template expansion. Broken out of ...
+ * parse.y (parse_finish_call_expr): ... here. Call it.
+ * decl2.c (build_expr_from_tree, CALL_EXPR): Use
+ resolve_scoped_fn_name and build_call_from_tree.
+
+ PR c++/9053
+ * decl.c (duplicate_decls): Templates may be disambiguated by
+ return type.
+
+ PR c++/8702
+ * decl2.c (check_classfn): Use lookup_fnfield_1. List all
+ conversion operators on failure.
+
+2002-12-23 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 2/n.
+ * call.c (tourney, build_field_call, equal_functions, joust,
+ compare_ics, build_over_call, build_java_interface_fn_ref,
+ convert_like_real, op_error, build_object_call, resolve_args,
+ build_vfield_ref, check_dtor_name, build_scoped_method_call,
+ build_addr_func, build_call, build_method_call, null_ptr_cst_p,
+ sufficient_parms_p, build_conv, non_reference, strip_top_quals,
+ standard_conversion, reference_related_p,
+ reference_compatible_p, convert_class_to_reference,
+ direct_reference_binding, reference_binding,
+ ,implicit_conversion, is_complete, promoted_arithmetic_type_p,
+ add_template_conv_candidate, any_viable, any_strictly_viable,
+ build_this, splice_viable, print_z_candidates,
+ build_user_type_conversion, build_new_function_call,
+ conditional_conversion, build_conditional_expr, build_new_op,
+ build_op_delete_call, enforce_access, call_builtin_trap,
+ convert_arg_to_ellipsis, build_x_va_arg, cxx_type_promotes_to,
+ convert_default_arg, type_passed_as, convert_for_arg_passing,
+ in_charge_arg_for_name, is_properly_derived_from,
+ maybe_handle_implicit_object, maybe_handle_ref_bind,
+ source_type, add_warning, can_convert, can_convert_arg,
+ perform_implicit_conversion, can_convert_arg_bad,
+ initialize_reference, add_conv_candidate,
+ add_template_candidate_real, add_template_candidate): Ansify.
+
+2002-12-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/8572
+ * cp-tree.h (grokoptypename): Add SCOPE parameter.
+ * decl2.c (grokoptypename): Add SCOPE parameter. tsubst the type
+ if in a template scope.
+ * parse.y (unoperator): Return the scope.
+ (operator_name): Adjust grokoptypename call.
+
+2002-12-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (make_unbound_class_template): Use tsubst_flags_t.
+ * decl.c (make_unbound_class_template): Adjust. Check for tf_error.
+ * pt.c (tsubst) [OFFSET_TYPE]: Check for tf_error.
+
+2002-12-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Fix a typo.
+ * class.c: Fix comment typos.
+ * cp-tree.h: Likewise.
+
+2002-12-18 Jason Merrill <jason@redhat.com>
+
+ Handle anonymous unions at the tree level.
+ C++ ABI change: Mangle anonymous unions using the name of their
+ first named field (by depth-first search). Should not cause
+ binary compatibility problems, though, as the compiler previously
+ didn't emit anything for affected unions.
+ * cp-tree.def (ALIAS_DECL): New tree code.
+ * decl2.c (build_anon_union_vars): Build ALIAS_DECLs. Return the
+ first field, not the largest.
+ (finish_anon_union): Don't mess with RTL. Do set DECL_ASSEMBLER_NAME,
+ push the decl, and write it out at namespace scope.
+ * decl.c (lookup_name_real): See through an ALIAS_DECL.
+ (pushdecl): Add namespace bindings for ALIAS_DECLs.
+ * rtti.c (unemitted_tinfo_decl_p): Don't try to look at the name
+ of a decl which doesn't have one.
+ * typeck.c (build_class_member_access_expr): Don't recurse if
+ we already have the type we want.
+
+2002-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8099
+ * friend.c (make_friend_class): Allow partial specialization
+ when declaration is not a template friend.
+
+2002-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/3663
+ * pt.c (lookup_template_class): Copy TREE_PRIVATE and
+ TREE_PROTECTED to created decl nodes.
+
+2002-12-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_base_field): Do not set DECL_PACKED on the
+ FIELD_DECL.
+
+2002-12-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (struct tree_srcloc): Use location_t.
+ (SOURCE_LOCUS): New.
+ (SRCLOC_FILE, SRCLOC_LINE): Adjust.
+
+2002-12-17 Jason Merrill <jason@redhat.com>
+
+ * decl.c (finish_function): Also complain about no return in
+ templates.
+ * semantics.c (finish_return_stmt): Also call check_return_expr in
+ templates.
+ * typeck.c (check_return_expr): In a template, just remember that we
+ saw a return.
+
+2002-12-16 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Don't change the type
+ of the CALL_EXPR.
+
+ * semantics.c (do_pushlevel): Call pushlevel after adding the
+ SCOPE_STMT.
+ (do_poplevel): Call poplevel before adding the SCOPE_STMT.
+ * parse.y (function_body): Go back to using compstmt.
+ * decl.c (pushdecl): Skip another level to get to the parms level.
+
+ * call.c (build_new_method_call): Use is_dummy_object to determine
+ whether or not to evaluate the object parameter to a static member
+ function.
+
+2002-12-14 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Also prepend the
+ return slot for normal functions. Set CALL_EXPR_HAS_RETURN_SLOT_ADDR.
+ * tree.c (build_cplus_new): If the type isn't TREE_ADDRESSABLE,
+ don't bother with an AGGR_INIT_EXPR.
+ (cp_copy_res_decl_for_inlining): If the type isn't TREE_ADDRESSABLE,
+ just generate a new decl normally. Take return slot parm.
+ * cp-tree.h: Adjust prototype.
+
+2002-12-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR C++/8031
+ * cvt.c (convert_to_pointer_force): Don't try comparing against
+ erronous type.
+
+2002-12-13 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h: Have the multiple-include guards around
+ the entire file.
+
+2002-12-10 David Edelsohn <edelsohn@gnu.org>
+
+ * cp/spew.c (feed_input): Change limit to last_pos and pos to cur_pos
+ for SPEW_DEBUG.
+ (snarf_method): Same.
+ (snarf_defarg): Same.
+
+2002-12-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8372
+ * pt.c (tsubst_copy): Handle destructor names more correctly.
+
+2002-12-10 Matt Austern <austern@apple.com>
+
+ * cp-tree.h: get rid of needs_virtual_reinit bit.
+
+2002-12-09 Mark Mitchell <mark@codesourcery.com>
+
+ * NEWS: Document removal of in-class initialization extension for
+ static data members of non-arithmetic, non-enumeration type.
+ * decl.c (check_static_variable_definition): Do not allow that
+ extension.
+ * decl2.c (grokfield): Do not call digest_init when processing
+ templates.
+
+2002-12-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (dump_expr): Fix format specifier warning.
+
+2002-12-04 Geoffrey Keating <geoffk@apple.com>
+
+ * class.c (finish_struct_1): Correct comment.
+ * cp-tree.c (DECL_SORTED_FIELDS): Likewise.
+
+2002-12-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR C++/8799
+ * error.c (dump_expr): Don't ever try to dump a non-existent
+ expression.
+
+2002-12-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement covariant returns.
+ * cp-tree.h (IS_AGGR_TYPE_2): Remove.
+ (struct lang_decl_flags): Add this_thunk_p flag.
+ Rename vcall_offset to virtual_offset.
+ (struct lang_decl): Rename delta to fixed_offset.
+ (DECL_THIS_THUNK_P, DECL_RESULT_THUNK_P): New #defines.
+ (SET_DECL_THUNK_P): Add THIS_ADJUSTING arg.
+ (THUNK_DELTA, THUNK_VCALL_OFFSET): Rename to ...
+ (THUNK_FIXED_OFFSET, THUNK_VIRTUAL_OFFSET): ... here.
+ (make_thunk): Add this_adjusting arg.
+ (finish_thunk): Declare.
+ (mangle_thunk): Add this_adjusting arg.
+ * class.c (get_vcall_index): Use base function for lookup.
+ (update_vtable_entry_for_fn): Generate covariant thunk.
+ (finish_struct_1): Set DECL_VINDEX to NULL for thunks.
+ (build_vtbl_initializer): Use base function for lookup.
+ Finish covariant thunk here. Adjust thunk generation.
+ * dump.c (cp_dump_tree): Simplify DECL_GLOBAL_[CD]TOR_P handling.
+ Adjust thunk dumping.
+ * mangle.c (mangle_call_offset): New function.
+ (mangle_thunk): Adjust for covariant thunks.
+ * method.c (make_thunk): Adjust. Do not set name here.
+ (finish_thunk): New function. Set name here.
+ (use_thunk): Generate covariant thunks too.
+ (thunk_adjust): New function.
+ * search.c (covariant_return_p): Remove. Fold into ...
+ (check_final_overrider): ... here. Simplify.
+ * semantics.c (emit_associated_thunks): Walk covariant thunk lists.
+
+2002-12-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/8674
+ * call.c (build_over_call): Check specifically for TARGET_EXPR
+ when eliding.
+
+ PR c++/8461, c++/8625
+ * call.c (convert_for_arg_passing): Don't mess with error_mark_node.
+ (cp_convert_parm_for_inlining): Remove.
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
+ Remove.
+ * cp-tree.h (ADDR_IS_INVISIREF): Remove.
+ * except.c (stabilize_throw_expr): Remove ADDR_IS_INVISIREF code.
+
+ * call.c (build_user_type_conversion_1): Don't set ICS_BAD_FLAG on
+ an ambiguous conversion.
+
+2002-12-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8688
+ * decl.c (reshape_init): Handle erroneous initializers.
+
+2002-12-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8720
+ * spew.c (remove_last_token): Make sure that last_chunk is set
+ correctly.
+
+ PR c++/8615
+ * error.c (dump_expr): Handle character constants with
+ TREE_OVERFLOW set.
+
+2002-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ DR 180
+ * decl.c (grokdeclarator): Require class-key for all friend class.
+ Output the correct type and context in the error message.
+
+2002-12-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5919
+ * pt.c (unify): Use variably_modified_type_p to test validity of
+ template argument types.
+
+ PR c++/8727
+ * cp-tree.h (lang_type_class): Add typeinfo_var.
+ (CLASSTYPE_TYPEINFO_VAR): New macro.
+ * rtti.c (get_tinfo_decl): Use it.
+
+ PR c++/8663
+ * init.c (expand_member_init): Always get the main variant of a
+ base class.
+
+2002-12-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8332
+ PR c++/8493
+ * decl.c (cxx_init_decl_processing): Use size_type_node, not
+ c_size_type_node.
+ * decl2.c (coerce_new_type): Likewise.
+ * except.c (do_allocate_exception): Likewise.
+
+2002-11-30 Zack Weinberg <zack@codesourcery.com>
+
+ * call.c, class.c, cp-lang.c, cvt.c, cxxfilt.c, decl.c, decl2.c,
+ dump.c, error.c, except.c, expr.c, friend.c, g++spec.c, init.c,
+ lex.c, mangle.c, method.c, optimize.c, parse.y, pt.c, ptree.c,
+ repo.c, rtti.c, search.c, semantics.c, spew.c, tree.c, typeck.c,
+ typeck2.c: Include coretypes.h and tm.h.
+ * Make-lang.in: Update dependencies.
+
+2002-11-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8227
+ * decl.c (layout_var_decl): Deal gracefully with erroneous types.
+ (check_initializer): Validate the type of the initialized
+ variable, even if the initializer is absent.
+ * typeck.c (cp_type_quals): Deal gracefully with erroneous types.
+
+ PR c++/8214
+ * typeck.c (convert_for_assignment): Do not use
+ decl_constant_value on the operand.
+
+ PR c++/8511
+ * pt.c (instantiate_decl): Handle template friends defined outside
+ of the class correctly.
+
+2002-11-29 Joe Buck <jbuck@synopsys.com>
+
+ * parse.y (class_head_defn): Set CLASSTYPE_DECLARED_CLASS for
+ anonymous structs.
+
+2002-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (walk_subobject_offsets): Recur on binfos as well as on
+ types.
+ (layout_nonempty_base_or_field): Pass it a binfo when processing a
+ base class.
+ (layout_empty_base): Likewise.
+ (build_base_field): Likewise.
+
+2002-11-27 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_base_field): Make sure we get the canonical base
+ when descending through primary bases.
+
+2002-11-26 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (check_initializer): Don't error on initialisation of
+ a scalar with a brace-enclosed expression.
+
+2002-11-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (DECL_LANG_FLAG_4): Document more uses.
+ (template_parms_equal): Remove prototype.
+ * typeck.c (buuld_indirect_ref): Reformat.
+
+2002-11-25 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_vec_init): Use a FOR_STMT instead of an IF_STMT
+ and a DO_STMT.
+
+2002-11-25 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (cp_build_qualified_type_real): Correct handling of
+ array types.
+ * class.c (walk_subobject_offsets): Fix thinko.
+ (build_base_field): Record offsets of empty bases in primary
+ virtual bases.
+ (layout_class_type): Record offsets of empty bases in fields.
+
+ * search.c (is_subobject_of_p_1): Fix thinko.
+ (lookup_field_queue_p): Likewise.
+
+2002-11-24 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Reuse tail padding when laying out
+ virtual bases.
+
+2002-11-22 Mark Mitchell <mark@codesourcery.com>
+
+ * rtti.c (qualifier_flags): Fix thinko.
+
+2002-11-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 1/n.
+ * cp-tree.h (init_method, set_mangled_name_for_decl,
+ build_opfncall, hack_identifier, make_thunk, use_thunk,
+ synthesize_method, implicitly_declare_fn,
+ skip_artificial_parms_for, optimize_function, calls_setjmp_p,
+ maybe_clone_body): Remove use of PARAMS.
+
+ * method.c (do_build_assign_ref, do_build_copy_constructor,
+ synthesize_exception_spec, locate_dtor, locate_ctor, locate_copy):
+ Likewise.
+ (synthesize_method): Use 'bool' type and constants instead of
+ 'int'.
+ (locate_copy): Likewise.
+ (implicitly_declare_fn): Likewise.
+
+ * optimize.c (calls_setjmp_r, update_cloned_parm, dump_function):
+ Remove old-style declaration.
+ (maybe_clone_body): Use 'bool' type and constants.
+
+2002-11-21 Glen Nakamura <glen@imodulo.com>
+
+ PR c++/8342
+ * typeck.c (get_member_function_from_ptrfunc): Make sure that a
+ SAVE_EXPR for instance_ptr doesn't get evaluated first inside one
+ of the branches of a COND_EXPR.
+
+2002-11-19 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (for_each_template_parm): Free allocated memory.
+ * search.c (is_subobject_of_p_1): New function.
+ (is_subobject_of_p): Avoid walking virtual bases multiple times.
+
+2002-11-19 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * g++spec.c (lang_specific_spec_functions): New.
+
+2002-11-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * class.c: Likewise.
+ * decl2.c: Likewise.
+
+2002-11-14 Zack Weinberg <zack@codesourcery.com>
+
+ * search.c (dfs_push_decls): Do not try to reorder elements
+ 3..n of method_vec if method_vec has only two elements.
+ Reverse order of two tests to avoid accessing unallocated
+ memory.
+
+2002-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (dfs_find_final_overrider): Adjust so that the most
+ derived object is a binfo, rather than a class type.
+ (find_final_overrider): Likewise.
+ (add_vcall_offset_vtbl_entries_1): Simplify accordingly.
+ (add_vcall_offset): Likewise.
+
+2002-11-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8389
+ * pt.c (instantiate_template): Push class scope for member
+ functions.
+ (get_mostly_instantiated_function_type): Likewise. Don't call
+ tsubst on context. Remove CONTEXTP and TPARMSP parameters.
+ * cp-tree.h (get_mostly_instantiated_function_type): Adjust.
+ * mangle.c (write_encoding, write_unqualified_name): Adjust.
+
+2002-11-07 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_vcall_offset_vtbl_entries_1): Correct ordering of
+ vcall offfsets. Split out ...
+ (add_vcall_offset): ... new function.
+
+ PR c++/8338
+ * pt.c (for_each_template_parm): Add htab parameter.
+ (process_partial_specialization): Adjust call.
+ (push_template_decl_real): Likewise.
+ (pair_fn_data): Add visited.
+ (for_each_template_parm_r): Avoid walking duplicates more than
+ once.
+ (uses_template_parms): Adjust call to for_each_template_parm.
+
+2002-11-07 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_implicitly_declared_members): Put implicitly
+ declared functions at the end of TYPE_METHODs when -fabi-version
+ is at least 2.
+
+2002-11-05 Geoffrey Keating <geoffk@apple.com>
+
+ * decl2.c (finish_file): Correct spelling.
+
+2002-11-03 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_special_member_call): Do not try to lookup VTTs by
+ name.
+ * class.c (vtbl_init_data): Add generate_vcall_entries.
+ (get_vtable_decl): Do not look up virtual tables by name.
+ (copy_virtuals): Do not use BV_USE_VCALL_INDEX_P.
+ (set_primary_base): Do not set CLASSTYPE_RTTI.
+ (determine_primary_base): Likewise.
+ (get_matching_virtual): Remove.
+ (get_vcall_index): New function.
+ (update_vtable_entry_for_fn): Do not try to use virtual thunks
+ when they are not required. Assign vcall indices at this point.
+ (finish_struct_1): Do not set CLASSTYPE_NEEDS_VIRTUAL_REINIT.
+ Do update dynamic_classes.
+ (build_vtt): Do not add VTTs to the symbol table.
+ (build_ctor_vtbl_group): Likewise.
+ (build_vtbl_initializer): Simplify handling of vcall indices.
+ (build_vcall_offset_vtbl_entries): Pretend to build vcall offsets
+ for the most derived class.
+ (add_vcall_offset_vtbl_entries_1): But do not actually add them to
+ the vtable.
+ * cp-tree.h (dynamic_classes): New macro.
+ (lang_type_class): Remove rtti. Add vtables. Add vcall_indices.
+ (CLASSTYPE_RTTI): Remove.
+ (CLASSTYPE_NEEDS_VIRTUAL_REINIT): Remove.
+ (CLASSTYPE_VCALL_INDICES): New macro.
+ (CLASSTYPE_VTABLES): Likewise.
+ (BV_USE_VCALL_INDEX_P): Remove.
+ (build_vtable_path): Remove.
+ * decl2.c (finish_vtable_vardecl): Remove.
+ (key_method): Remove #if 0'd code.
+ (finish_vtable_vardecl): Rename to ...
+ (maybe_emit_vtables): ... this.
+ (finish_file): Use it.
+ * search.c (look_for_overrides_here): Update comment.
+
+2002-11-01 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/7353 redux
+ * decl2.c (grokfield): Reject TYPE_DECLs with initializers.
+
+2002-10-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/8186
+ * cp-tree.h (ADDR_IS_INVISIREF): New macro.
+ * call.c (convert_for_arg_passing): Set it.
+ * except.c (stabilize_throw_expr): Recurse for such an arg.
+
+2002-10-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Remove init_priority.
+ (lang_decl): Add delta.
+ (GLOBAL_INIT_PRIORITY): Remove.
+ (THUNK_DELTA): Revise definition.
+ * decl2.c (start_objects): Don't set GLOBAL_INIT_PRIORITY.
+ * dump.c (cp_dump_tree): Don't dump it.
+
+2002-10-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8160
+ * typeck2.c (process_init_constructor): Call complete_array_type.
+
+ PR c++/8149
+ * decl.c (make_typename_type): Issue errors about invalid results.
+
+2002-10-30 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ Core issue 287, PR c++/7639
+ * cp-tree.h (lang_type_class): Add decl_list field.
+ (CLASSTYPE_DECL_LIST): New macro.
+ (maybe_add_class_template_decl_list): Add declaration.
+ * class.c (duplicate_tag_error): Initialize CLASSTYPE_DECL_LIST.
+ (unreverse_member_declarations): Reverse CLASSTYPE_DECL_LIST.
+ (maybe_add_class_template_decl_list): New function.
+ (add_implicitly_declared_members): Use it.
+ * decl.c (maybe_process_template_type_declaration): Likewise.
+ (pushtag): Likewise.
+ * friend.c (add_friend): Likewise.
+ (make_friend_class): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+ (begin_class_definition): Initialize CLASSTYPE_DECL_LIST.
+ * pt.c (instantiate_class_template): Use CLASSTYPE_DECL_LIST
+ to process members and friends in the order of declaration.
+
+2002-10-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8287
+ * decl.c (finish_destructor_body): Create the label to jump to
+ when returning from a destructor here.
+ (finish_function_body): Rather than here.
+
+2002-10-25 Zack Weinberg <zack@codesourcery.com>
+
+ PR c++/7266
+ * decl.c (grokdeclarator): Check that TREE_OPERAND 0 of a
+ SCOPE_REF is not null before dereferencing it.
+
+2002-10-25 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_over_call): Use DECL_CONTEXT, not
+ DECL_VIRTUAL_CONTEXT.
+ * class.c (modify_vtable_entry): Don't mess with
+ DECL_VIRTUAL_CONTEXT.
+ (set_vindex): Remove.
+ (set_primary_base): Remove vfuns_p parameter.
+ (determine_primary_base): Likewise.
+ (modify_all_vtables): Likewise.
+ (layout_class_type): Likewise. Adjust calls to other functions
+ accordingly.
+ (finish_struct_1): Adjust calls to modified functions. Set
+ DECL_VINDEX here.
+ * cp-tree.h (lang_type_class): Remove vsize.
+ (CLASSTYPE_VSIZE): Remove.
+ (lang_decl): Remove thunks.
+ (DECL_THUNKS): Adjust.
+ (DECL_VIRTUAL_CONTEXT): Remove.
+ (duplicate_decls): Don't copy it.
+ * pt.c (build_template_decl): Don't set it.
+ (tsubst_decl): Likewise.
+ * typeck.c (expand_ptrmemfunc_cst): Don't use it.
+
+ * class.c (build_vtbl_initializer): Don't use build_vtable_entry.
+ (build_vtable_entry): Remove.
+ * cp-tree.h (BINFO_VIRTUALS): Expand documentation.
+ (lang_decl): Add thunks.
+ (DECL_THUNKS): New macro.
+ * decl.c (duplicate_decls): Copy it.
+ * method.c (make_thunk): Simplify, and add thunks to DECL_THUNKS.
+ * semantics.c (emit_associated_thunks): Simplify.
+
+2002-10-24 David Edelsohn <edelsohn@gnu.org>
+
+ PR c++/7228
+ * cp-tree.h (CLASSTYPE_READONLY_FIELDS_NEED_INIT): Check that
+ lang_type structure exists before accessing field.
+ (SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT): New macro.
+ (CLASSTYPE_REF_FIELDS_NEED_INIT): Similar.
+ (SET_CLASSTYPE_REF_FIELDS_NEED_INIT): New macro.
+ * class.c (check_field_decls): Use new macros.
+ * typeck2.c (process_init_constructor): Remove redundant check for
+ existence of lang_type structure.
+
+2002-10-24 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (end_of_base): New method.
+ (end_of_class): Use it. Check indirect virtual bases.
+
+ * class.c (check_field_decls): Fix typo.
+
+2002-10-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8067
+ * decl.c (maybe_inject_for_scope_var): Ignore __FUNCTION__ and
+ related variables.
+
+ PR c++/7679
+ * spew.c (next_token): Do not return an endless stream of
+ END_OF_SAVED_INPUT tokens.
+ (snarf_method): Add three END_OF_SAVED_INPUT tokens to the end of
+ the cached token stream.
+ (snarf_defarg): Likewise.
+
+2002-10-23 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-lang.c (cp_var_mod_type_p): New: C++ hook for
+ variably_modified_type_p.
+ * cp-tree.h: Remove prototype of variably_modified_type_p.
+ * tree.c (variably_modified_type_p): Remove; now implemented
+ in language-independent code.
+
+2002-10-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6579
+ * spew.c (snarf_parenthesized_expression): New function.
+ (snarf_block): Use it.
+
+2002-10-22 Richard Henderson <rth@redhat.com>
+
+ * method.c (use_thunk): Always compute vcall_value; assert that
+ it is not zero. Use can_output_mi_thunk; use output_mi_thunk
+ for vcall thunks as well.
+
+2002-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (empty_base_at_nonzero_offset_p): New function.
+ (layout_nonempty_base_or_field): Do not check for conflicts when
+ laying out a virtual base using the GCC 3.2 ABI.
+ (build_base_field): Correct checking for presence of empty classes
+ at nonzero offsets when clearing CLASSTYPE_NEARLY_EMPTY_P.
+
+ * class.c (include_empty_classes): Use normalize_rli.
+ (layout_class_type): Likewise.
+
+ * decl.c (reshape_init): Tweak handling of character arrays.
+
+ PR c++/8218
+ * cp-tree.h (lang_type_class): Add contains_empty_class_p.
+ (CLASSTYPE_CONTAINS_EMPTY_CLASS_P): New macro.
+ * class.c (check_bases): Update CLASSTYPE_CONTAINS_EMPTY_CLASS_P.
+ (check_field_decls): Likewise.
+ (layout_class_type): Likewise.
+ (finish_struct_1): Initialize it.
+ (walk_subobject_offsets): Use it to prune searches.
+
+2002-10-20 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (use_thunk): Compute the vcall index as a HOST_WIDE_INT.
+ * optimize.c (optimize_function): Replace ASM_OUTPUT_MI_THUNK with
+ TARGET_ASM_OUTPUT_MI_THUNK in comments.
+
+2002-10-18 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (start_decl): Point users of the old initialized-
+ typedef extension at __typeof__.
+
+2002-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (method.o): Depend on TARGET_H.
+ * method.c (target.h): Include it.
+ (use_thunk): Use target hooks. Use vcall thunks, if available.
+
+2002-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (base_derived_from): Make sure return value is a bool.
+
+2002-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (find_final_overrider_data_s): Remove overriding_fn and
+ overriding_base.
+ (dfs_base_derived_from): New function.
+ (base_derived_from): Likewise.
+ (dfs_find_final_overrider): Use base_derived_from.
+ (find_final_overrider): Adjust.
+
+2002-10-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/8080
+ * semantics.c (finish_for_cond, finish_while_cond): Don't mess
+ with condition decls in a template.
+
+2002-10-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (add_method): Compare template parms too.
+
+2002-10-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7584
+ * class.c (handle_using_decl): Allow the declaration used to be
+ from an ambiguous base.
+
+ * pt.c (convert_template_argument): Revert this change:
+ 2002-10-16 Mark Mitchell <mark@codesourcery.com>
+ * pt.c (convert_template_argument): Do not fold non-type
+ template rguments when inside a template.
+
+ * init.c (expand_default_init): Handle brace-enclosed initializers
+ correctly.
+
+2002-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_expression): Correct handling of enumeration
+ constants.
+ (write_template_arg): Likewise.
+ * pt.c (convert_template_argument): Do not fold non-type template
+ arguments when inside a template.
+
+ PR c++/7478
+ * cvt.c (convert_to_reference): Allow references as the incoming
+ type.
+
+2002-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7524
+ * method.c (do_build_assign_ref): Use cp_build_qualified_type, not
+ build_qualified_type.
+
+2002-10-15 Richard Henderson <rth@redhat.com>
+
+ * error.c (dump_expr): Use real_to_decimal directly, and with
+ the new arguments.
+
+2002-10-15 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (reshape_init): Fix typo.
+
+ * cp-tree.h (operator_name_info_t): Add arity.
+ * lex.c (init_operators): Initialize it.
+ * mangle.c (write_conversion_operator_name): New function.
+ (write_unqualified_name): Use it.
+ (write_template_args): Accept template arguments as a TREE_LIST.
+ (write_expression): Adjust handling of qualified names to match
+ specification.
+
+2002-10-15 Jason Merrill <jason@redhat.com>
+
+ * call.c (call_builtin_trap): New fn.
+ (convert_arg_to_ellipsis): Use it. Downgrade error to warning.
+ (build_call): Don't set current_function_returns_abnormally outside
+ a function.
+
+2002-10-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (check_field_decls): Remove empty_p parameter. Instead,
+ clear CLASSTYPE_EMPTY_P.
+ (build_base_field): Likewise.
+ (build_base_fields): Likewise.
+ (check_bases_and_members): Likewise.
+ (create_vtbl_ptr): Likewise.
+ (layout_class_type): Likewise. Ensure that empty classes have
+ size zero when used as base classes in the 3.2 ABI.
+ (finish_struct_1): Initialize CLASSTYPE_EMPTY_P and
+ CLASSTYPE_NEARLY_EMPTY_P. Adjust calls to avoid passing empty_p
+ parameter.
+ (is_empty_class): Correct definition when using post-3.2 ABI.
+ * cp-tree.h (lang_type_class): Add empty_p.
+ (CLASSTYPE_EMPTY_P): New macro.
+
+2002-10-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (build_delete): Do not apply save_expr for arrays.
+ (build_vec_delete): Likewise.
+
+2002-10-14 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (layout_var_decl): Call layout_decl even for variables
+ whose type is an array with unspecified bounds.
+
+ PR c++/7176
+ * lex.c (do_identifier): Add another option for the parsing
+ parameter.
+ * parse.y (do_id): Use it.
+
+2002-10-11 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PRs C++/6803, C++/7721 and C++/7803
+ * decl.c (grokdeclarator): Gracefully handle template-name as
+ decl-specifier.
+
+2002-10-11 Jason Molenda <jmolenda@apple.com>
+
+ * init.c (build_field_list): Provide uses_unions_p with a default
+ value.
+
+2002-10-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5661
+ * cp-tree.h (variably_modified_type_p): New function.
+ (grokdeclarator) Tighten check for variably modified types as
+ fields.
+ * pt.c (convert_template_argument): Do not allow variably modified
+ types as template arguments.
+ * tree.c (variably_modified_type_p): New function.
+
+ * NEWS: Document removal of "new X = ..." extension.
+ * class.c (initialize_array): Set TREE_HAS_CONSTRUCTOR on
+ brace-enclosed initializers.
+ * cp-tree.h (CP_AGGREGATE_TYPE_P): New macro.
+ (initialize_local_var): Remove declaration.
+ (expand_static_init): Likewise.
+ * decl.c (next_initializable_field): New function.
+ (reshape_init): Likewise.
+ (check_initializer): Use them. Build dynamic initializer for
+ aggregates here too.
+ (initialize_local_var): Simplify, and incorporate cleanup
+ insertion code as well.
+ (destroy_local_var): Remove.
+ (cp_finish_decl): Tidy.
+ (expand_static_init): Fold checks for whether or not a variable
+ needs initialization into this function. Simplify.
+ * decl2.c (do_static_initialization): Simplify.
+ * init.c (build_init): Do not set TREE_SIDE_EFFECTS when it will
+ be done for us automatically.
+ (expand_default_init): Handle brace-enclosed initializers
+ correctly.
+ (expand_aggr_init_1): Remove RTL-generation code.
+ (build_vec_init): Remove "new X = ..." support.
+ * parse.y (new_initializer): Likewise.
+ * rtti.c (get_pseudo_ti_init): Set TREE_HAS_CONSTRUCTOR on
+ brace-enclosed initializer.
+ (create_pseudo_type_info): Likewise.
+ * typeck2.c (store_init_value): Don't try to handle digest_init
+ being called more than once.
+ (digest_init): Tidy handling of brace-enclosed initializers.
+
+2002-10-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (typename_hash): Use htab_hash_pointer.
+
+2002-10-10 Jim Wilson <wilson@redhat.com>
+
+ * decl.c (duplicate_decls): Don't call decl_attributes.
+
+2002-10-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/7353
+ * decl.c (start_decl): Unconditionally issue error for
+ 'typedef foo = bar'.
+ (cp_finish_decl): Remove special case for TYPE_DECL with initializer.
+ (grokdeclarator): Remove redundant error for 'typedef foo = bar'.
+
+2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (prune_vtable_vardecl): Delete unused function.
+
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7754
+ * decl2.c (finish_anon_union): Do not expand anonymous unions when
+ procesing template functions.
+ * pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
+ type. Call layout_decl.
+ (tsubst_expr, case DECL_STMT): Handle anonymous unions.
+
+2002-10-07 Richard Henderson <rth@redhat.com>
+
+ * decl2.c, pt.c: Revert c++/7754 fix.
+
+2002-10-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7804
+ * error.c (dump_expr) [REAL_CST]: Output in decimal format.
+
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7931
+ * pt.c (for_each_template_parm_r): Handle BASELINKs.
+
+ PR c++/7754
+ * decl2.c (finish_anon_union): Do not expand anonymous unions when
+ procesing template functions.
+ * pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
+ type. Call layout_decl.
+ (tsubst_expr, case DECL_STMT): Handle anonymous unions.
+
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8006
+ * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Handle instances of template
+ template parameters.
+ (globals): Add entity and need_abi_warning.
+ (decl_is_template_id): Use TYPE_TEMPLATE_INFO, not
+ CLASSTYPE_TEMPLATE_INFO.
+ (is_std_substitution): Use CLASSTYPE_TI_TEMPLATE, not
+ TYPE_TI_TEMPLATE.
+ (write_prefix): Handle typename types correctly.
+ (write_template_prefix): Handle template template parameters
+ correctly.
+ (start_mangling): Add entity parameter.
+ (finish_mangling): Warn about names whose mangling will change.
+ (mangle_decl_string): Adjust.
+ (mangle_type_string): Likewise.
+ (mangle_special_for_type): Likewise.
+ (mangle_ctor_vtbl_for_type): Likewise.
+ (mangle_thunk): Likewise.
+ (mangle_guard_variable): Likewise.
+ (mangle_ref_init_variable): Likewise.
+
+2002-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7188.
+ * cp-tree.def (CTOR_INITIALIZER): Use one slot, not two.
+ * cp-tree.h (emit_base_init): Rename to ....
+ (emit_mem_initializers): ... this.
+ (expand_member_init): Change prototype.
+ * init.c (perform_member_init): Compute explicit, rather than
+ requiring it as a parameter.
+ (sort_member_init): Rename to ...
+ (sort_mem_initializers): ... this. Process bases and data members
+ together.
+ (sort_base_init): Remove.
+ (emit_base_init): Rename to ...
+ (emit_mem_initializers): ... this.
+ (expand_aggr_vbase_init_1): Remove.
+ (construct_virtual_bases): Rename to ...
+ (construct_virtual_base): ... this.
+ (expand_member_init): Rework handling of base initializers.
+ * method.c (do_build_copy_constructor): Use
+ finish_mem_initializers.
+ * parse.y (member_init): Adjust calls to expand_member_init.
+ * pt.c (tsubst_expr): Simplify CTOR_INITIALIZER case.
+ (tsubst_initializer_list): Use expand_member_init.
+ * semantics.c (finish_mem_intiailizers): Simplify.
+
+2002-10-02 Matt Austern <austern@apple.com>
+ * decl.c (walk_vtables_r): Fixed typo that caused result to
+ never get a nonzero value.
+
+2002-10-02 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/6627
+ * cp-tree.h (enum ptrmemfunc_vbit_where_t): Delete definition
+ from here, and move it to tree.h.
+ * decl.c (cxx_init_decl_processing): If storing the vbit
+ in function pointers, ensure that force_align_functions_log
+ is atleast one.
+
+2002-10-02 Matt Austern <austern@apple.com>
+
+ * class.c (check_field_decls): Changed warning about const member
+ variables so that it doesn't get issued for a class aggregate.
+
+2002-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Make sure array types are laid out,
+ even if the array bounds are unknown.
+
+2002-10-01 Steve Ellcey <sje@cup.hp.com>
+
+ * class.c (build_vtbl_initializer): Change build_c_cast
+ to build1.
+
+2002-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Make sure array types are laid out,
+ even if the array bounds are unknown.
+
+ * decl.c (cp_finish_decl): Correct check for dynamic
+ initialization of thread-local storage.
+
+2002-09-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (really_overloaded_fn): TEMPLATE_ID_EXPRs are also
+ overloaded.
+
+2002-09-30 Steve Ellcey <sje@cup.hp.com>
+
+ * class.c (build_vtbl_initializer): Add cast.
+ (add_vcall_offset_vtbl_entries_1):
+ Use TARGET_VTABLE_DATA_ENTRY_DISTANCE for offset.
+
+2002-09-30 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (walk_subobject_offsets): Correct the calculation of
+ offsets for virtual bases. Correct the counting of array
+ elements.
+ (layout_nonempty_base_or_field): Simplify. Correct the
+ calculation of offsets to be propagated through the binfo
+ hierarchy.
+ (build_base_field): Avoid creating a FIELD_DECL for empty bases.
+ Add the FIELD_DECL to TYPE_FIELDS.
+ (build_base_fields): Adjust accordingly.
+ (layout_virtual_bases): Use build_base_field.
+ (end_of_class): Return a tree, not an integer.
+ (warn_about_ambiguous_direct_bases): Rename to ...
+ (warn_about_ambiguous_bases): ... this.
+ (include_empty_classes): New function.
+ (layout_class_type): Create an alternative version of the type to
+ be used when as a base class type. Do not call
+ finish_record_layout until we are done laying out the class.
+ * cp-tree.h (lang_type_class): Remove size, size_unit. Add
+ as_base.
+ (CLASSTYPE_SIZE): Reimplement.
+ (CLASSTYPE_SIZE_UNIT): Likewise.
+ (CLASSTYPE_ALIGN): Likweise.
+ (CLASSTYPE_USER_ALIGN): Likewise.
+ (CLASSTYPE_AS_BASE): New macro.
+ (DECL_INITIALIZED_P): Likewise.
+ (extract_init): Remove prototype.
+ (build_forced_zero_init): Rename to ...
+ (build_zero_init): ... this.
+ (force_store_init_value): Remove.
+ * decl.c (obscure_complex_init): Remove.
+ (duplicate_decls): Copy DECL_INITIALIZED_P.
+ (check_initializer): Do not leave junk in DECL_INITIAL.
+ (cp_finish_decl): Handle zero-initialization of entities with
+ static storage duration.
+ * expr.c (extract_init): Remove.
+ * init.c (build_forced_zero_init): Remove.
+ (build_zero_init): New function.
+ (build_default_init): Use it.
+ (build_field_list): Skip FIELD_DECLs for base subobjects.
+ (push_base_cleanups): Likewise.
+ * method.c (do_build_assign_ref): Likewise.
+ (synthesize_exception_spec): Likewise.
+ * pt.c (tsubst_decl): Clear DECL_INITIALIZED_P.
+ (regenerate_decl_from_template): To not set DECL_INITIAL for a
+ static data member whose initialization took place in its class.
+ (instantiate_decl): Do not pass an initializer to cp_finish_decl
+ in that situation.
+ * search.c (dfs_push_decls): Skip FIELD_DECLs for base subobjects.
+ (dfs_unuse_fields): Likewise.
+ * tree.c (pod_type_p): Handle error_mark_node.
+ (zero_init_p): Likewise.
+ * typeck.c (lookup_anon_field): Skip FIELD_DECLs for base
+ subobjects.
+ * typeck2.c (store_init_value): Remove #if 0'd code.
+ (force_store_init_value): Remove.
+ (process_init_constructor): Use build_zero_init.
+
+2002-09-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7788
+ * rtti.c (unemitted_tinfo_decl_p): Check it has a field.
+
+2002-09-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h: Fix comment typos.
+ * decl.c: Likewise.
+ * pt.c: Likewise.
+
+2002-09-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/class.c (contains_empty_class_p): New method.
+ (walk_subobject_offsets): Correct computation of field offset.
+ (layout_empty_base): Correct placement of emtpy base classes.
+ (layout_class_type): Warn about ABI changes.
+
+2002-09-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/class.c (layout_virtual_bases): Do not round the size of the
+ type to a multiple of the alignment before laying out virtual bases.
+ (layout_class_type): Correct handling of bit-fields that are wider
+ than their type inside unions. Round the size of the type to a
+ even number of bytes when computing the size without virtual
+ bases.
+ * cp/cp-tree.h (abi_version_at_least): New macro.
+
+2002-09-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.2: Likewise.
+ * call.c: Likewise.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * except.c: Likewise.
+ * friend.c: Likewise.
+ * g++spec.c: Likewise.
+ * init.c: Likewise.
+ * lex.c: Likewise.
+ * mangle.c: Likewise.
+ * method.c: Likewise.
+ * operators.def: Likewise.
+ * optimize.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2002-09-18 Devang Patel <dpatel@apple.com>
+
+ * cp/cp-tree.h: New prototype for walk_vtabls().
+ * cp/decl.c (walk_vtables_r): New function.
+ (struct cp_binding_level): Add new members, namespaces,
+ names_size and vtables.
+ (add_decl_to_level): Add decl in namespaces or vtables
+ chain, if conditions match.
+ (walk_vtables): New function.
+ (walk_namespaces_r): Travers separate namespace chain
+ for namespace decls.
+ (wrapup_globals_for_namespace): Use names_size instead
+ of list_length().
+ * cp/decl2.c (finish_file): Use walk_vtables() instead of
+ walk_globals() to walk vtable decls.
+
+2002-09-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Use assert, not internal_error. Don't
+ ICE with invalid pointers & references.
+
+2002-09-17 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in: Remove all references to the demangler.
+ * cxxfilt.c: Moved to binutils.
+
+2002-09-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7718
+ * pt.c (tsubst_decl): Remove assert.
+
+ Remove DR 295 implementation.
+ * pt.c (check_cv_quals_for_unify): Disable function & method cases.
+ * tree.c (cp_build_qualified_type_real): Likewise. Don't warn
+ about ignoring volatile qualifiers.
+
+ * search.c (lookup_member): Correct documentation.
+
+2002-09-16 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (union lang_tree_node): Add chain_next option.
+
+2002-09-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (parse_finish_call_expr): Check lookup_member result.
+
+ PR c++/7015
+ * semantic.c (finish_asm_stmt): Fix operand/output_operands
+ thinko.
+ * typeck.c (c_expand_asm_operands): Protect from error_mark_node.
+
+2002-09-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7919
+ * call.c (build_over_call): Convert this pointer for fns found by
+ using decls.
+
+2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.1: Likewise.
+
+2002-09-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7768
+ * pt.c (build_template_decl): Copy DECL_DESTRUCTOR_P.
+
+2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * error.c: Fix comment formatting.
+ * except.c: Likewise.
+ * expr.c: Likewise.
+ * friend.c: Likewise.
+ * g++spec.c: Likewise.
+ * init.c: Likewise.
+ * lex.c: Likewise.
+ * mangle.c: Likewise.
+ * method.c: Likewise.
+ * optimize.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2002-09-13 Matt Austern <austern@apple.com>
+
+ PR C++/7828
+ * cp/cp-tree.h, cp/tree.c: New function non_cast_lvalue_p.
+ * cp/call.c: Change call-by-const-reference mechanism to use
+ non_cast_lvalue_p when deciding whether the create a temporary.
+ We need a temporary when passing, e.g. (long) x by const ref.
+
+2002-09-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (unify, ARRAY_TYPE): Element type can be more qualified.
+
+2002-09-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * decl.c: Fix comment formatting.
+ * decl2.c: Likewise.
+
+2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cp-lang.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+
+2002-09-11 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in: Build cp/cxxfilt.o from $(srcdir)/cp/cxxfilt.c,
+ and c++filt from cxxfilt.o + version.o + $(LIBDEPS).
+ * cxxfilt.c: New file: split from libiberty/cplus-dem.c, with
+ minor adjustments (use version_string, eliminate yet another
+ duplicate of xmalloc)
+
+2002-09-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (require_complete_eh_spec_types): Add prototype.
+
+2002-09-05 Jason Merrill <jason@redhat.com>
+
+ * typeck2.c (add_exception_specifier): Only pedwarn for an
+ incomplete type.
+ (require_complete_eh_spec_types): New fn.
+ (cxx_incomplete_type_diagnostic): Also support pedwarning.
+ * typeck.c (complete_type_or_diagnostic): Likewise.
+ * call.c (build_call): Call require_complete_eh_spec_types.
+ * rtti.c (get_pseudo_ti_desc): Give an error rather than aborting
+ on an incomplete type.
+
+2002-09-04 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (start_cleanup_fn): Clear interface_only before
+ start_function, restore it afterwards.
+
+2002-09-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (finish_builtin_type): Remove.
+ * decl2.c (finish_builtin_type): Move to common code.
+ * decl.c (build_ptrmemfunc_type): Adjust.
+ * rtti.c (create_pseudo_type_info): Adjust.
+ (create_tinfo_types): Adjust.
+
+2002-08-31 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (cp_expr_size): Allow initialization from a
+ CONSTRUCTOR.
+
+2002-08-30 Richard Henderson <rth@redhat.com>
+
+ PR opt/7515
+ * tree.c: Include target.h.
+ (cp_cannot_inline_tree_fn): Don't auto-inline functions that
+ don't bind locally.
+ * Makefile.in (tree.o): Update.
+
+2002-08-27 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_virtual_bases): Warn about bugs in G++ that
+ result in incorrect object layouts.
+ (layout_class_type): Likewise.
+
+2002-08-24 Matt Austern <austern@apple.com>
+
+ * tree.c (lvalue_p_1): Add argument for whether casts of lvalues
+ are allowable.
+ (real_lvalue_p): Update caller.
+ (lvalue_p): Ditto.
+ (non_cast_lvalue_or_else): New.
+ * tree.h: Declare it.
+ * typeck.c (build_unary_op): Use non_cast_lvalue_or_else.
+
+2002-08-22 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_class_member_access_expr): Handle COMPOUND_EXPR
+ and COND_EXPR specially; fix error message output.
+
+2002-08-22 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_expr): RETURN_EXPR is now RETURN_STMT_EXPR.
+ * semantics.c (nullify_returns_r): Likewise.
+
+2002-08-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Fix PR/7621
+ * typeck.c (finish_class_member_access_expr): Diagnose cases where
+ name lookup finds nothing.
+
+2002-08-15 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (finish_then_clause): Remove redundant assignment.
+ (finish_if_stmt, begin_switch_stmt, finish_switch_stmt): Move the
+ extra binding level outside the if/switch statement.
+ (finish_while_cond, finish_for_cond): Rewrite complex condition
+ into the loop body.
+
+2002-08-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * parse.y (sizeof, alignof, typeof): New non-terminals to
+ increment skip_evaluation. Replace terminals with them and
+ decrement skip_evaluation at the end of rules using them.
+ * decl2.c (mark_used): Don't assemble_external if
+ skipping evaluation.
+
+2002-08-15 Gabriel Dos Reis <gdr@nerim.net>
+
+ Fix PR/7504
+ * parse.y (parse_finish_call_expr): Handle incomplete
+ type used to name a scope.
+
+2002-08-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7598
+ * typeck.c (build_unary_op): Fold offsetof idiom. Fixes
+ regression caused by my 2002-08-08 patch.
+
+2002-08-13 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pushdecl_class_level): Honor requests to bind names to
+ OVERLOADs.
+
+2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (build_call_from_tree): Fix uninitialized variable.
+ * parse.y (parse_finish_call_expr): Likewise.
+ * repo.c (old_args, old_dir, old_main): Const-ify.
+
+2002-08-11 Gabriel Dos Reis <gdr@nerim.net>
+
+ * decl.c (duplicate_decls): Replace DECL_SOURCE_FILE
+ DECL_SOURCE_LINE with DECL_SOURCE_LOCATION.
+ * optimize.c (maybe_clone_body): Likewise.
+ * pt.c (tsubst_enum): Likewise.
+ (lookup_template_class): Likewise.
+ * tree.c (cp_copy_res_decl_for_inlining): Likewise.
+
+2002-08-10 Neil Booth <neil@daikokuya.co.uk>
+
+ * lang-specs.h: Remove -ansi.
+
+2002-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (maybe_dummy_object): Replace // with /* */
+
+2002-08-09 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (standard_conversion): Use build_ptrmem_type.
+ * cp-tree.h (build_ptrmem_type): New function.
+ (adjust_result_of_qualified_name_lookup): Likewise.
+ * decl.c (grokvardecl): Do not look for OFFSET_TYPEs to indicate
+ static data members.
+ (build_ptrmem_type): New function.
+ (grokdeclarator): Do not use build_offset_type when encountering a
+ qualified name.
+ * parse.y (parse_finish_call_expr): Use
+ adjust_result_of_qualified_name_lookup.
+ * search.c (adjust_result_of_qualified_name_lookup): New function.
+ * typeck.c (qualify_type_recursive): Use TYPE_PTRMEM_* rather than
+ accessing OFFSET_TYPEs directly.
+
+2002-08-08 Mike Stump <mrs@apple.com>
+
+ * call.c (add_builtin_candidate): legal -> valid, illegal -> invalid.
+ (type_decays_to): Likewise.
+ * class.c (find_final_overrider): Likewise.
+ (maybe_note_name_used_in_class): Likewise.
+ * decl.c (current_tmpl_spec_kind): Likewise.
+ (add_binding): Likewise.
+ (push_class_binding): Likewise.
+ (duplicate_decls): Likewise.
+ (layout_var_decl): Likewise.
+ (grokfndecl): Likewise.
+ (grokdeclarator): Likewise.
+ (check_default_argument): Likewise.
+ * decl2.c (handle_class_head): Likewise.
+ * error.c (dump_template_decl): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * pt.c (check_specialization_scope): Likewise.
+ (determine_specialization): Likewise.
+ (check_explicit_specialization): Likewise.
+ (maybe_check_template_type): Likewise.
+ (process_partial_specialization): Likewise.
+ (check_default_tmpl_args): Likewise.
+ (push_template_decl_real): Likewise.
+ (convert_template_argument): Likewise.
+ (try_class_unification): Likewise.
+ (get_bindings_real): Likewise.
+ (do_decl_instantiation): Likewise.
+ * semantics.c (begin_function_definition): Likewise.
+ (finish_member_declaration): Likewise.
+ (check_multiple_declarators): Likewise.
+ * typeck.c (comp_array_types): Likewise.
+ (comptypes): Likewise.
+ (expr_sizeof): Likewise.
+ (build_binary_op): Likewise.
+ (dubious_conversion_warnings): Likewise.
+ (check_return_expr): Likewise.
+
+2002-08-08 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_class_member_access_expr): Do not return
+ error_mark_node when no error has occurred.
+
+2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_component_addr): Remove.
+ (build_unary_op): Just check it's not a bitfield, and then build
+ an ADDR_EXPR.
+
+2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (convert_to_base): Correct check for error_mark_node.
+ (create_vtable_ptr): Remove unused VFUNS_P parm.
+
+2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp/Make-lang.in (c++.mostlyclean): Remove coverage files.
+
+2002-08-07 Mark Mitchell <mark@codesourcery.com>
+
+ Rework build_component_ref.
+ * call.c (build_vfield_ref): Do not go through build_component_ref.
+ (build_field_call): Use build_class_member_access_expr.
+ (build_user_type_conversion_1): Use BASELINK_FUNCTIONS.
+ (build_object_call): Likewise.
+ * class.c (convert_to_base): New function.
+ (type_requires_array_cookie): Use BASELINK_FUNCTIONS.
+ (instantiate_type): Handle BASELINKs.
+ * cp-tree.def (BASELINK): New tree code.
+ * cp-tree.h (BASELINK_P): Reimplement.
+ (SET_BASELINK_P): Remove.
+ (BASELINK_BINFO): Reimplement.
+ (BASELINK_FUNCTIONS): Likewise.
+ (BASELINK_ACCESS_BINFO): Likewise.
+ (BASELINK_OPTYPE): Likewise.
+ (convert_to_base): New function.
+ (name_p): Likewise.
+ (build_object_ref): Remove.
+ (build_component_ref_1): Likewise.
+ (build_component_ref): Likewise.
+ (build_x_component_ref): Likewise.
+ (build_class_member_access_expr): New function.
+ (finish_class_member_access_expr): Likewise.
+ (build_ptrmemfunc_access_expr): Likewise.
+ * decl.c (grokdeclarator): Handle BASELINKs.
+ * decl2. (build_expr_from_tree): Handle COMPONENT_REFs by using
+ finish_class_member_access_expr.
+ (arg_assoc): Handle BASELINKs.
+ (do_class_using_decl): Likewise.
+ * error.c (dump_decl): Likewise.
+ (dump_expr): Use build_ptrmemfunc_access_expr.
+ * except.c (dtor_nothrow): Use CLASSTYPE_DESTRUCTORS to find
+ destructors.
+ (build_throw): Use BASELINK_FUNCTIONS.
+ * init.c (perform_member_init): Use
+ build_class_member_access_expr.
+ (build_offset_ref): Handle BASELINKs. Use
+ build_class_member_access_expr.
+ * method.c (hack_identifier): Likewise.
+ * parse.y (do_id): Use BASELINK, not TREE_LIST.
+ (primary): Remove uses of build_object_ref.
+ * pt.c (lookup_template_function): Handle BASELINKs.
+ (resolve_overloaded_unification): Likewise.
+ * search.c (build_baselink): Build a BASELINK, not a TREE_LIST.
+ (lookup_field): Use BASELINK, not TREE_LIST.
+ (lookup_fnfiels): Likewise.
+ (setup_class_bindings): Likewise.
+ * semantics.c (finish_object_call_expr): Do not use
+ build_method_call when we already know what function is being
+ called.
+ * spew.c (identifier_type): Use BASELINK, not TREE_LIST.
+ * tree.c (really_overloaded_fn): Use OVL_CHAIN for OVERLOADs, not
+ TREE_CHAIN.
+ (name_p): New function.
+ * typeck.c (build_object_ref): Remove.
+ (build_component_ref_1): Likewise.
+ (build_x_component_ref): Likewise.
+ (build_class_member_access_expr): New function.
+ (finish_class_member_access_expr): Likewise.
+ (build_ptrmemfunc_access_expr): Likewise.
+ (get_member_function_from_ptrfunc): Use
+ build_ptrmemfunc_access_expr.
+ (build_binary_op): Likewise.
+ (build_unary_op): Likewise.
+ (build_ptrmemfunc): Likewise.
+ (pfn_from_ptrmemfunc): Likewise.
+ * typeck2.c (build_m_component_ref): Adjust comment.
+
+2002-08-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Update.
+ * cp-lang.c (LANG_HOOKS_DECODE_OPTION): Use c_common_decode_option.
+ * cp-tree.h (cxx_decode_option): Remove.
+ * decl2.c (compare_options, lang_f_options, unsupported_options,
+ cxx_decode_option): Remove.
+
+2002-08-06 Gabriel Dos Reis <gdr@nerim.net>
+
+ * typeck.c (build_x_unary_op): Handle pointer-to-member.
+
+2002-08-05 Geoffrey Keating <geoffk@redhat.com>
+
+ * class.c: Don't include obstack.h.
+ (popclass):
+ * decl2.c: Delete bogus comment.
+ * error.c: Don't include obstack.h.
+ * except.c: Likewise.
+ (dump_type): Correct comment.
+ * method.c: Don't include obstack.h.
+ * tree.c: Likewise.
+
+2002-08-04 Gabriel Dos Reis <gdr@nerim.net>
+
+ Fix PR/2213
+ * cvt.c (cp_convert_to_pointer): Reject conversions from integral
+ expressions to pointer-to-data-member of pointer-to-member-functions.
+
+2002-08-04 Geoffrey Keating <geoffk@redhat.com>
+
+ * cvt.c (ocp_convert): Delete obsolete code.
+ * parse.y (permanent_obstack): Delete declaration.
+ * pt.c (permanent_obstack): Delete declaration.
+ * repo.c (permanent_obstack): Delete declaration.
+ (open_repo_file): Use xmalloc instead of permanent_obstack.
+ (init_repo): Use xstrdup instead of permanent_obstack.
+
+2002-08-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (VF_DERIVED_VALUE): Remove.
+ * class.c (finish_struct_1): Use VF_BINFO_VALUE not VF_DERIVED_VALUE.
+
+2002-08-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR 7470.
+ C++ ABI change - vfunc ordering.
+ * class.c (add_virtual_function): Remove.
+ (dfs_modify_all_vtables): Take list of all declared
+ virtuals. Assign all that are not in primary base.
+ (check_for_override): Adjust comments.
+ (create_vtable_ptr): Take single list of virtuals. Build chain
+ of declared virtuals here.
+ (layout_class_type): Take single list of virtuals. Adjust.
+ (finish_struct_1): Keep virtuals on single list. Adjust.
+
+2002-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (build_member_call): Use build_new_method_call, not
+ build_method_call.
+
+2002-08-02 Krister Walfridsson <cato@df.lth.se>
+
+ * Make-lang.in (spew.o, lex.o, pt.o): Add path to parse.h dependencies.
+
+2002-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_method_call): Issue a more helpful error message
+ about ambiguous method names.
+
+2002-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (build_shared_int_cst): Make cache file scope, and
+ GTY it.
+
+2002-08-02 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
+ (cp_expr_size): New fn.
+ * call.c (build_over_call): Lose empty class hackery.
+ (convert_arg_to_ellipsis): Promote non-POD warning to error.
+ * typeck.c (build_modify_expr): Don't use save_expr on an lvalue.
+
+ * semantics.c (expand_body): Do tree optimization in the function
+ context, too.
+
+2002-08-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h: Move all warning and flag declarations to c-common.h.
+ * decl.c: Move all warning and flag variables to c-common.c.
+ * decl2.c: Move all warning and flag variables to c-common.c.
+ * lex.c (flag_digraphs): Remove.
+ (warn_traditional): Now in c-common.c.
+
+2002-07-31 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_field_call): Do not look up the field by name.
+ (build_method_call): Simplify.
+ (struct z_candidate): Add access_path and conversion_path. Remove
+ basetype_path.
+ (convert_class_to_reference): Adjust use of
+ add_function_candidate.
+ (add_candidate): Add conversion_path argument.
+ (add_function_candidate): Use it.
+ (add_conv_dndidate): Likewise.
+ (build_builtin_candidate): Likewise.
+ (add_template_candidate_real): Add conversion_path argument.
+ (add_template_conv_candidate): Likewise.
+ (add_template_candidate): Likewise.
+ (build_user_type_conversion_1): Use it.
+ (build_new_function_call): Remove name lookup code. Adjust use of
+ add_template_candidate and add_function_candidate.
+ (build_new_op): Likewise.
+ (convert_like_real): Use build_special_member_call.
+ (build_over_call): Use cand->conversion_path.
+ (build_special_member_call): New method.
+ (build_new_method_call): Remove name lookup code.
+ * cp-tree.def (OFFSET_REF): Update documentation.
+ (TEMPLATE_ID_EXPR): Likewise.
+ * cp-tree.h (BASELINK_ACCESS_BINFO): New macro.
+ (BASELINK_OPTYPE): Likewise.
+ (build_new_method_call): Adjust prototype.
+ (build_special_member_call): New method.
+ (build_baselink): New method.
+ (build_offset_ref_call_from_tree): Likewise.
+ (build_call_from_tree): Likewise.
+ (finish_qualified_call_expr): Remove.
+ (finish_call_expr): Adjust prototype.
+ (build_x_function_call): Remove.
+ * cvt.c (ocp_convert): Use build_special_member_call.
+ * decl2.c (reparse_absdcl_as_expr): Use finish_call_expr.
+ (build_expr_from_tree): Adjust handling for TEMPLATE_ID_EXPR and
+ CALL_EXPR.
+ (build_offset_ref_call_from_tree): New function.
+ (build_call_from_tree): Likewise.
+ * init.c (expand_cleanup): Use build_special_member_call.
+ (expand_default_init): Likewise.
+ (build_member_call): Use finish_call_expr.
+ (build_new_1): Use build_special_member_call.
+ (push_base_cleanups): Likewise.
+ * method.c (do_build_assign_ref): Likewise.
+ * parse.y (template_id): Do not pass a COMPONENT_REF to
+ lookup_template_function.
+ (primary): Use parse_finish_call_epxr, not finish_call_expr.
+ (parse_finish_call_expr): New function.
+ * pt.c (lookup_template_function): Add assertions.
+ * search.c (lookup_base): Allow T to be a binfo.
+ (build_baselink): New function.
+ (lookup_member): Use it.
+ * semantics.c (finish_call_expr): Do not do name lookup.
+ (finish_object_call_expr): Remove #if 0'd code.
+ (finish_qualified_call_expr): Remove.
+ * typeck.c (build_x_function_call): Remove.
+ (build_static_case): Use build_special_member_call.
+ * typeck2.c (build_functional_cast): Likewise.
+
+2002-07-30 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * lang-specs.h: Remove __GXX_ABI_VERSION, moved to gcc.c.
+
+2002-07-30 Gabriel Dos Reis <gdr@nerim.net>
+
+ * cp-tree.h (VF_DERIVED_VALUE): Restore from previous deletion.
+
+2002-07-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_VFIELDS, VF_*, BV_*): Add more
+ documentation.
+
+2002-07-29 Alan Modra <amodra@bigpond.net.au>
+
+ * cp-tree.h: Comment typo fix.
+
+2002-07-29 Richard Earnshaw <rearnsha@arm.com>
+
+ * spew.c (space_for_token): Allocate zeroed memory for a new token
+ chunk.
+
+2002-07-27 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (builtin_function_1): No need to explicitly mark
+ BUILT_IN_RETURN and BUILT_IN_EH_RETURN as noreturn.
+
+2002-07-27 Roger Sayle <roger@eyesopen.com>
+
+ * decl2.c (cxx_decode_option): Support -fno-builtin-foo.
+
+2002-07-26 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_over_call): Likewise.
+ (cp_convert_parm_for_inlining): New fn.
+ (convert_for_arg_passing): New fn.
+ (convert_default_arg, build_over_call): Use it.
+ (type_passed_as): New fn.
+ * pt.c (tsubst_decl): Use it.
+ * decl2.c (cp_build_parm_decl): New fn.
+ (build_artificial_parm): Use it.
+ (start_static_storage_duration_function): Likewise.
+ * decl.c (start_cleanup_fn, grokdeclarater): Likewise.
+ (grokparms): Don't mess with DECL_ARG_TYPE.
+ * typeck.c (convert_arguments): Use convert_for_arg_passing.
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
+ Define.
+ * cp-tree.h: Declare new fns.
+
+2002-07-26 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h (flag_operator_names): Remove.
+ * decl2.c (flag_operator_names): Remove.
+ (lang_f_options): Remove operator-names.
+ * lex.c (D_OPNAME): Remove.
+ (reswords): Remove operator names.
+ (rid_to_yy): Remove operator names.
+ (init_reswords): No need to handle D_OPNAME.
+ * spew.c (read_process_identifier): There are no operator
+ names.
+
+2002-07-26 Jason Merrill <jason@redhat.com>
+
+ * dump.c (cp_dump_tree): Call c_dump_tree.
+ * Make-lang.in (CXX_C_OBJS): Add c-dump.o.
+
+2002-07-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * error.c (print_whitespace): Remove.
+ * g++spec.c (LIBUNWIND): Move.
+ * mangle.c (mangled_position, write_signed_number): Remove.
+
+2002-07-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * decl2.c (cxx_decode_option): Similarly.
+
+2002-07-25 Gabriel Dos Reis <gdr@nerim.net>
+
+ * cp-tree.h (cxx_sizeof_nowarn): Now a macro.
+ (cxx_sizeof_or_alignof_type): Take a third argument.
+ (cxx_sizeof): Adjust definition.
+ (cxx_alignof): Likewise.
+ * init.c (build_delete): Use cxx_sizeof_nowarn to reflect reality.
+ * typeck.c (cxx_sizeof_or_alignof_type): Take a third argument for
+ complaining.
+ (c_sizeof_nowarn): Remove definition.
+ (build_unary_op): Use cxx_sizeof_nowarn.
+
+2002-07-24 Geoffrey Keating <geoffk@redhat.com>
+
+ * tree.c (cp_build_qualified_type_real): When copying
+ pointer-to-method types, unshare the record that holds
+ the cached pointer-to-member-function type.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h (FILE_FUNCTION_PREFIX_LEN): Remove.
+
+2002-07-23 Gabriel Dos Reis <gdr@nerim.net>
+
+ Fix PR/7363:
+ * typeck.c (cxx_sizeof_or_alignof_type): New function.
+ (c_sizeof): Remove definition.
+ (expr_sizeof): Use cxx_sizeof.
+ * decl2.c (build_expr_from_tree): Use cxx_sizeof_or_alignof_type.
+ * decl.c (finish_destructor_body): Use cxx_sizeof.
+ * semantics.c (finish_alignof): Likewise.
+ (finish_alignof): Use cxx_alignof.
+ * cp-tree.h (cxx_sizeof, cxx_alignof): New macros.
+ (cxx_sizeof_or_alignof_type): Declare.
+ (my_friendly_assert): Move to ../c-common.h.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * class.c, method.c, pt.c, search.c: Don't define obstack macros.
+
+2002-07-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7347, c++/7348
+ * cp-tree.h (tsubst_flags_t): Add tf_parsing.
+ * decl.c (make_typename_type): Use it.
+ (make_unbound_class_template): Likewise.
+ (lookup_name_real): Don't call type_access_control if scope is
+ template parameter dependent.
+ * parse.y (template_arg): Call make_unbound_class_template with
+ tf_parsing set.
+ (nest_name_specifier): Call make_typename_type with tf_parsing set.
+ (typename_sub0): Likewise.
+ (typename_sub1): Likewise.
+ (instantiate_decl): Push class scope.
+ * pt.c (regenerate_decl_from_template): Call pushclass and popclass
+ for both static variable and member function template.
+ (instantiate_decl) Call pushclass and popclass when tsubst'ing type
+ and arguments.
+ * search.c (type_access_control): Do type access for TEMPLATE_DECL
+ too.
+
+2002-07-20 Roger Sayle <roger@eyesopen.com>
+
+ * decl2.c (cxx_decode_option): Simplify -fhandle-exceptions
+ test by using positive_option. Make whitespace consistent.
+
+2002-07-20 Gabriel Dos Reis <gdr@nerim.net>
+
+ * spew.c (struct unparsed_test): Replace 'filename' and 'lineno'
+ members with 'locus'. Adjust use throughout.
+ (struct feed): Likewise.
+ (alloc_unparsed_test): Change prototype, take a 'const location_t *'.
+ Adjust use.
+ (snarf_defarg): Use error(), not error_with_file_and_line().
+
+2002-07-19 Chris Demetriou <cgd@broadcom.com>
+
+ * lang-specs.h (@c++): Include "%2" (cc1plus_spec) wherever
+ cpp_options is included.
+
+2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/2862, c++/2863
+ * pt.c (determine_specialization): Compare the length of
+ TYPE_ARG_TYPES. Tidy.
+
+2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/3797
+ * decl.c (duplicate_decls): Don't propagate inlining parameters from
+ olddecl to newdecl when newdecl is a specialization of the
+ instantiation olddecl.
+
+2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/4802, c++/5387
+ * decl.c (make_typename_type): Use enforce_access.
+
+2002-07-17 Scott Snyder <snyder@fnal.gov>
+
+ PR c++/7320
+ * rtti.c (get_tinfo_decl): Set DECL_COMDAT.
+
+2002-07-12 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_method): Correct handling of conversion operators.
+
+2002-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7224
+ * class.c (add_method): Simplify.
+
+2002-07-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/7279
+ * tree.c (cp_copy_res_decl_for_inlining): Also copy
+ TREE_ADDRESSABLE.
+
+2002-07-10 Graham Stott <graham.stott@btinternet.com>
+
+ * pt.c (template_parm_this_level_p, push_template_decl_real):
+ Pass depth as int pointer.
+
+2002-07-11 Tim Josling <tej@melbpc.org.au>
+
+ Remove front end hard coding from gengtype.c.
+
+ * config-lang.in (gtfiles): Add files needed for this front end.
+
+2002-07-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (unqualified_name_lookup_error): Declare it.
+ (begin_function_definition): Adjust prototype.
+ * lex.c (unqualified_name_lookup_error): New function, split out
+ from ...
+ (do_identifier): ... here.
+ * parse.y (parse_begin_function_definition): New function.
+ (fn.def1): Use it.
+ * semantics.c (begin_function_definition): Accept decl-specifiers
+ and attributes as separate parameters.
+
+2002-07-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/6255
+ * decl.c (lookup_name_real): Build a new TYPENAME_TYPE rather than
+ modifying the old one.
+
+2002-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (constructor_name_p): Declare it.
+ (check_template_template_default_arg): Likewise.
+ * class.c (handle_using_decl): Use constructor_name_p.
+ * decl.c (grokdeclarator): Likewise.
+ * decl2.c (constructor_name_p): Define it.
+ * init.c (build_member_call): Use constructor_name_p.
+ * parse.y (template_parm): Use check_template_template_default_arg.
+ * pt.c (check_explicit_specialization): Use constructor_name_p.
+ * semantics.c (check_template_template_default_arg): New function.
+
+2002-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (can_complete_type_without_circularity): Add static to
+ function definition.
+
+2002-07-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (have_extern_spec): Declare it
+ * decl.c (have_extern_spec): Define it.
+ (start_decl): Eliminate use of used_extern_spec.
+ (start_function): Likewise.
+ * parse.y (have_extern_spec): Remove declaration.
+ (used_extern_spec): Likewise.
+ (frob_specs): Eliminate use of used_extern_spec.
+ (.hush_warning): Likewise.
+
+2002-07-07 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (cp/parse.o): Depend on decl.h.
+ * cp-tree.h (do_decl_instantiation): Change prototype.
+ * parse.y: Include decl.h.
+ (parse_decl_instantiation): New function.
+ (explicit_instantiation): Use it.
+ * pt.c (do_decl_instantiation): Accept a DECL, not a DECLARATOR
+ and DECLSPECS.
+
+2002-07-07 Roger Sayle <roger@eyesopen.com>
+
+ * error.c (dump_function_name): Use DECL_TEMPLATE_RESULT for
+ constructor and destructor tests when passed a TEMPLATE_DECL.
+
+2002-07-05 Jason Merrill <jason@redhat.com>
+
+ * cvt.c (cp_convert_to_pointer): Call force_fit_type for null
+ pointers.
+
+ PR optimization/7145
+ * tree.c (cp_copy_res_decl_for_inlining): Also copy DECL_INITIAL.
+
+2002-07-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ Repair damage on weak-impared targets caused by my previous patch.
+ * cp-tree.h (import_export_tinfo): Add parameter.
+ * decl2.c (import_export_tinfo): Add parameter, post adjust
+ DECL_COMDAT.
+ * rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by
+ import_export_tinfo.
+
+2002-07-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6944
+ * init.c (build_aggr_init): Remove qualifiers of init before calling
+ build_vec_init.
+ (build_vec_init): Flatten multi-dimensional array during cleanup.
+ (build_vec_delete_1): Abort if the type of each element is array.
+
+2002-07-03 Graham Stott <graham.stott@btinternet.com>
+
+ * pt.c (instantiate_class_template): Fix typo.
+
+2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * typeck2.c (cxx_incomplete_type_diagnostic): Fix typo caused
+ by CVS conflict in my last patch.
+
+2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6716
+ * pt.c (can_complete_type_without_circularity): New function.
+ (instantiate_class_template): Use it.
+ * typeck2.c (cxx_incomplete_type_diagnostic): Improve error
+ message due to incomplete fields.
+
+2002-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7112
+ * mangle.c (write_expression): Add mangling for sizeof when
+ applied to a type.
+ * operators.def: Remove stale comment.
+
+2002-06-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ...
+ (CPTI_TYPE_INFO_PTR_TYPE): ... this.
+ (tinfo_decl_type): Replace with ...
+ (type_info_ptr_type): ... this.
+ (import_export_tinfo): Declare.
+ (tinfo_decl_p): Rename to ...
+ (unemitted_tinfo_decl_p): ... this.
+ * decl2.c (import_export_decl): Break out tinfo handling into ...
+ (import_export_tinfo): ... here. New function.
+ (finish_file): Adjust.
+ * rtti.c (TINFO_REAL_NAME): New macro.
+ (init_rtti_processing): Create the tinfo types.
+ (get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr.
+ (get_tinfo_decl): Adjust.
+ (get_tinfo_ptr): New function.
+ (get_type_id): Use it.
+ (tinfo_base_init): Create vtable decl here, if it doesn't exist.
+ (ptr_initializer): Use get_tinfo_ptr.
+ (ptm_initializer): Likewise.
+ (synthesize_tinfo_var): Break into ...
+ (get_pseudo_ti_init): ... this. Just create the initializer.
+ (get_pseudo_ti_desc): .. and this.
+ (create_real_tinfo_var): Remove.
+ (create_pseudo_type_info): Don't create the vtable decl here.
+ (get_vmi_pseudo_type_info): Remove.
+ (create_tinfo_types): Adjust.
+ (tinfo_decl_p): Rename to ...
+ (unemitted_tinfo_decl_p): ... here. Adjust.
+ (emit_tinfo_decl): Adjust. Create the initializer.
+
+2002-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6695
+ * pt.c (tsubst_friend_class): Substitute into the context of the
+ friend before using it.
+
+2002-06-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (xref_tag): Change prototype.
+ (handle_class_head): Likewise.
+ (build_x_component_ref): Likewise.
+ * decl.c (cxx_init_decl_processing): Adjust call to xref_tag.
+ (xref_tag): Take attributes as a separate parameter.
+ (xref_tag_from_type): Adjust call to xref_tag.
+ * decl2.c (build_expr_from_tree): Adjust call to
+ build_x_component_ref.
+ (handle_class_head): Take attributes as a separate parameter.
+ * parse.y (parse_xref_tag): New function.
+ (parse_handle_class_head): Likewise.
+ (primary): Use parse_xref_tag.
+ (class_head_decl): Use parse_handle_class_head.
+ (class_head_defn): Likewise.
+ * rtti.c (init_rtti_processing): Adjust call to xref_tag.
+ (build_dynamic_cast_1): Likewise.
+ (create_pseudo_type_info): Likewise.
+ (emit_support_tinfos): Likewise.
+ * typeck.c (build_object_ref): Adjust call to
+ build_x_component_ref.
+ (build_x_component_ref): Remove protect parameter.
+
+2002-06-25 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_op_delete_call): Use BASELINK_FUNCTIONS.
+ * class.c (handle_using_decl): Likewise.
+ (instantiate_type): Likewise.
+ * cp-tree.h (BASELINK_FUNCTIONS): New macro.
+ (xref_basetypes): Change prototype.
+ (begin_mem_initializers): New function.
+ (get_overloaded_fn): Likewise.
+ * decl.c (xref_basetypes): Simplify.
+ * error.c (dump_expr): Use BASELINK_FUNCTIONS.
+ * init.c (build_offset_ref): Likewise.
+ * parse.y (base_init): Use begin_mem_initializers().
+ (structsp): Adjust call to xref_basetypes.
+ * pt.c (determine_specialization): Use BASELINK_FUNCTIONS.
+ (instantiate_class_template): Adjust call to xref_basetypes.
+ * semantics.c (begin_mem_initializers): New function.
+ * tree.c (is_overloaded_fn): Use BASELINK_FUNCTIONS.
+ (really_overloaded_fn): Likewise.
+ (get_overloaded_fn): New function.'
+ (get_first_fn): USe BASELINK_FUNCTIONS.
+
+2002-06-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (SCALAR_TYPE_P): New macro.
+ (check_for_out_of_scope_variable): New function.
+ (at_class_scope_p): Likewise.
+ (finish_fname): Likewise.
+ * class.c (finish_struct): Use at_function_scope_p.
+ * decl.c (check_for_out_of_scope_variable): New function, split
+ out from do_identifier.
+ (finish_enum): Use at_function_scope_p.
+ * lex.c (do_identifier): Use check_for_out_of_scope_variable.
+ * parse.y (VAR_FUNC_NAME): Give it <ttype>. Use finish_fname.
+ (primary): Use at_function_scope_p.
+ * search.c (at_class_scope_p): New function.
+ * semantics.c (finish_fname): Likewise.
+ (check_multiple_declarators): Use at_function_scope_p.
+
+2002-06-23 Mark Mitchell <mark@codesourcery.com>
+
+ * parse.y (parse_scoped_id): New function.
+ (primary): Use it.
+ * cp-tree.h (do_scoped_id): Adjust declaration.
+ * lex.c (do_scoped_id): Remove call to yylex.
+ * decl2.c (build_expr_from_tree): Adjust use of do_scoped_id.
+ * typeck2.c (add_exception_specifier): Use tree_cons, rather than
+ expanding it inline.
+
+2002-06-23 Matt Thomas <matt@3am-software.com>
+
+ * decl.c (finish_function): Change "#ifdef VMS_TARGET" to
+ "#if VMS_TARGET".
+
+2002-06-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mangle.c (integer_type_codes): Const-ify.
+
+2002-06-20 Richard Henderson <rth@redhat.com>
+
+ PR c++/6747
+ * typeck.c (mark_addressable): Don't test TREE_ADDRESSABLE early.
+ Call put_var_into_stack.
+
+2002-06-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * spew.c (remove_last_token): Use ARRAY_SIZE in lieu of explicit
+ array size calculation.
+
+2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6892
+ * pt.c (tsubst_expr): Handle FILE_STMT.
+
+2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6723
+ * pt.c (lookup_template_class): Don't build complete argument of
+ BOUND_TEMPLATE_TEMPLATE_PARM if appeared as a default template
+ argument.
+
+2002-06-19 Akim Demaille <akim@epita.fr>
+
+ * parse.y (TYPENAME): Rename as tTYPENAME to avoid the clash with
+ decl.h's TYPENAME.
+ * spew.c, lex.c: Adjust.
+ * parse.y (explicit_instantiation): Add empty action to override
+ the default $$ = $1 where it introduces a type clash.
+
+2002-06-14 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (begin_for_stmt): Push the 'for' scope before
+ adding the FOR_STMT.
+
+ C++ ABI changes.
+ * class.c (build_base_field): Set DECL_PACKED.
+ (layout_class_type): Don't use tail padding of PODs.
+ * mangle.c (write_unqualified_name): Fix template conversion op
+ mangling.
+
+2002-06-16 Richard Henderson <rth@redhat.com>
+
+ PR opt/6793
+ * tree.c (cp_cannot_inline_tree_fn): Don't short-circuit test
+ after template instantiation.
+
+2002-06-16 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h, decl2.c (flag_ms_extensions): Move to c-common.
+
+2002-06-15 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * cp-tree.h (compiler_error): Remove declaration.
+ * lex.c (compiler_error): Remove definition.
+
+2002-06-14 Steve Ellcey <sje@cup.hp.com>
+
+ * g++spec.c (LIBUNWIND): New.
+ (lang_specific_driver): Add it if USE_UNWIND_EXCEPTIONS is set.
+
+2002-06-13 Jessica Han <jessica@cup.hp.com>
+
+ * class.c (build_vtable): Use TARGET_VTABLE_ENTRY_ALIGN.
+ (build_vtbl_initializer): Honor TARGET_VTABLE_DATA_ENTRY_DISTANCE.
+ (build_vbase_offset_vtbl_entries): Likewise.
+ * rtti.c (build_headof): Likewise.
+ (get_tinfo_decl_dynamic): Likewise.
+ (create_pseudo_type_info): Likewise.
+
+2002-06-12 Stan Shebs <shebs@apple.com>
+
+ * mpw-config.in: Remove file, no longer used.
+ * mpw-make.sed: Ditto.
+
+2002-06-07 Zack Weinberg <zack@codesourcery.com>
+
+ * decl2.c: Update call to cpp_handle_option.
+
+2002-06-07 H.J. Lu (hjl@gnu.org)
+
+ * decl2.c (flag_use_cxa_atexit): Set to DEFAULT_USE_CXA_ATEXIT.
+
+2002-06-06 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_error_at): Fix typo.
+
+2002-06-04 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_diagnostic_starter): Adjust call.
+ (maybe_print_instantiation_context): Change prototype to take a
+ 'diagnostic_info *'.
+ (print_instantiation_full_context): Likewise.
+ (print_instantiation_partial_context): Likewise.
+ (cp_diagnostic_starter): Likewise.
+ (cp_diagnostic_finalizer): Likewise.
+ (cp_print_error_function): Likewise.
+ (cp_printer): Take a secondary parameter as a 'text_info *'.
+ Remove output_state savings. Adjust calls.
+
+2002-06-03 Geoffrey Keating <geoffk@redhat.com>
+
+ * pt.c (inline_parm_levels): Mark for GC.
+
+ * mangle.c (start_mangling): Allocate G.substitutions here...
+ (init_mangle): ... rather than here.
+ (finish_mangling): Clear the varray pointer when done with it.
+ * spew.c (yylexstring): Don't use VARRAY_FREE.
+ * search.c (bfs_walk): Don't use VARRAY_FREE.
+ * decl2.c (pending_statics): Use gengtype to mark.
+ (deferred_fns): Likewise.
+ (ssdf_decls): Likewise.
+ (init_decl2): Delete.
+ * decl.c (pop_from_top_level): Don't use VARRAY_FREE.
+ (cxx_init_decl_processing): Don't call init_decl2.
+ (cxx_pop_function_context): Don't use VARRAY_FREE.
+ * cp-tree.h (struct saved_scope): No need for special marking
+ of varrays.
+ (struct language_function): Likewise.
+ (local_classes): Use gengtype to mark.
+ (init_decl2): Delete prototype.
+ * class.c (init_class_processing): Don't use
+ ggc_add_tree_varray_root.
+ (build_vtbl_initializer): Don't use VARRAY_FREE.
+
+ * decl.c (typename_compare): Don't use same_type_p.
+
+ * decl.c: Include hashtab.h instead of hash.h.
+ (typename_hash): Update to use htab_h.
+ (typename_compare): Likewise.
+ (typename_htab): Use gengtype to mark.
+ (build_typename_type): Update to use htab_h.
+ * Make-lang.in (cp/decl.o): Use HASHTAB_H instead of hash.h.
+
+ * Make-lang.in (gt-cp-tree.h): New rule.
+ (cp/tree.o): Depend on gt-cp-tree.h.
+ * config-lang.in (gtfiles): Add cp/tree.c.
+ * tree.c: Include gt-cp-tree.h.
+ (list_hash_table): Use gengtype to mark.
+ (init_tree): Use gengtype to mark trees.
+
+ * Make-lang.in (cp/decl.o): Add debug.h dependency.
+ * call.c (struct z_candidate): Use gengtype.
+ (USER_CONV_CAND): Use WRAPPER_ZC.
+ (convert_class_to_reference): Use build_zc_wrapper.
+ (build_type_conversion_1): Likewise.
+ (build_over_call): Use WRAPPER_ZC.
+ (add_warning): Use build_zc_wrapper.
+ * cp-lang.c (LANG_HOOKS_MARK_TREE): Delete.
+ * cp-tree.h (struct lang_identifier): Use gengtype.
+ (struct template_parm_index_s): Likewise.
+ (struct ptrmem_cst): Likewise.
+ (struct tree_binding): Likewise.
+ (struct tree_overload): Likewise.
+ (struct tree_srcloc): Likewise.
+ (struct tree_wrapper): Likewise. Also modify to have a pointer
+ to struct z_candidate rather than void.
+ (enum cp_tree_node_structure_enum): New.
+ (union lang_tree_node): New.
+ (cxx_mark_tree): Delete prototype.
+ (cp_tree_node_structure): New prototype.
+ (build_ptr_wrapper): Delete prototype.
+ (build_int_wrapper): Delete prototype.
+ (build_zc_wrapper): New prototype.
+ * decl.c: Include debug.h
+ (cxx_mark_tree): Delete.
+ (cp_tree_node_structure): New.
+ * tree.c (build_ptr_wrapper): Delete.
+ (build_int_wrapper): Delete.
+ (build_zc_wrapper): New.
+
+ * cp-tree.h [! ENABLE_TREE_CHECKING] (LANG_TYPE_PTRMEM_CHECK):
+ Correct typo. Patch from k_fukui@highway.ne.jp.
+
+ * semantics.c (current_stmt_tree): Update for change to
+ struct language_function.
+ (finish_mem_initializers): Likewise.
+ * decl.c (cxx_init_decl_processing): Don't set mark_lang_status.
+ * cp-tree.h (struct language_function): Rename from
+ cp_language_function. Change all uses.
+ (cp_function_chain): Don't need to cast.
+
+ * class.c (duplicate_tag_error): Reset discriminator.
+ (check_bases_and_members): Update for data structure changes.
+ * cp-tree.h (struct lang_id2): Use gengtype.
+ (flagged_type_tree): Likewise.
+ (SET_LANG_ID): Use GGC on struct lang_id2.
+ (struct cp_language_function): Use gengtype. Remove field
+ 'x_vcalls_possible_p'.
+ (current_vcalls_possible_p): Delete.
+ (struct lang_type_header): New.
+ (struct lang_type_class): Rename from struct lang_type. Include
+ struct lang_type_header.
+ (struct lang_type_ptrmem): New.
+ (struct lang_type): New.
+ (LANG_TYPE_CLASS_CHECK): New. Use it in all the appropriate macros.
+ (LANG_TYPE_PTRMEM_CHECK): New. Use it in all the appropriate macros.
+ (TYPE_SET_PTRMEMFUNC_TYPE): Set discriminator, update for changes.
+ (struct lang_decl_flags): Use gengtype. Add discriminators.
+ (struct lang_decl): Use gengtype. Add and use discriminators.
+ Update the macros that reference moved fields.
+ (LANG_DECL_U2_CHECK): New function. Use it when appropriate.
+ (SET_DECL_THUNK_P): Set discriminator too.
+ (clear_inline_text_obstack): Delete prototype.
+ (finish_inline_definitions): Delete prototype.
+ (mark_pending_inlines): Delete prototype.
+ (lang_check_failed): New prototype.
+ * decl.c (struct named_label_use_list): Use gengtype.
+ (struct named_label_list): Likewise.
+ (mark_binding_level): Delete.
+ (mark_named_label_lists): Delete.
+ (push_local_name): Set discriminator on DECL_LANG_SPECIFIC.
+ (cxx_init_decl_processing): Use generated marker routine.
+ (begin_destructor_body): Delete dead set to
+ current_vcalls_possible_p.
+ (mark_lang_function): Delete.
+ (mark_cp_function_context): Delete.
+ (lang_mark_tree): Use generated marker routines.
+ * decl2.c (start_objects): Set discriminator when setting
+ GLOBAL_INIT_PRIORITY.
+ * lex.c (retrofit_lang_decl): Set discriminators.
+ (copy_lang_type): Update for changes to lang_type structure.
+ (cp_make_lang_type): Set discriminator.
+ * parse.y: Use gengtype on YYLVAL. Don't use dots in identifiers.
+ * search.c: Include ggc.h.
+ * semantics.c (anon_aggr_type_p): Use the macro, don't hand-code it.
+ (finish_inline_definitions): Delete.
+ * spew.c (struct token): Use gengtype.
+ (struct token_chunk): New.
+ (struct unparsed_text): Use gengtype. Store tokens in chunks.
+ (struct feed): Use gengtype.
+ (feed_obstack): Delete.
+ (feed): Mark as GC root.
+ (pending_inlines): Mark as GC root.
+ (pending_inlines_tail): Likewise.
+ (processing_these_inlines): Likewise.
+ (token_obstack): Make static.
+ (first_token): Likewise.
+ (init_spew): Don't initialize deleted things; use gengtype for roots.
+ (clear_inline_text_obstack): Delete.
+ (feed_input): Use GC for struct feed. Update for changes to
+ struct unparsed_text.
+ (mark_pending_inlines): Delete.
+ (next_token): Rename from add_token. Change all callers. Update
+ for changes to struct unparsed_text.
+ (space_for_token): New.
+ (remove_last_token): New.
+ (alloc_unparsed_text): New.
+ (snarf_block): Take an unparsed_text. Update for changes to struct
+ unparsed_text.
+ (snarf_method): Update for changes to struct unparsed_text.
+ (snarf_defarg): Update for changes to struct unparsed_text.
+ * tree.c (lang_check_failed): New.
+
+ * Make-lang.in (gt-cp-call.h gt-cp-decl2.h gt-cp-parse.h
+ gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h): New rules.
+ (cp/spew.o): Add dependency on gt-<filename>.h.
+ (cp/decl2.o): Add dependency on gt-<filename>.h.
+ (cp/call.o): Add dependency on gt-<filename>.h.
+ (cp/pt.o): Add dependency on gt-<filename>.h.
+ (cp/repo.o): Add dependency on gt-<filename>.h.
+ (cp/parse.o): Add dependency on gt-<filename>.h.
+ * call.c: Use gengtype for roots.
+ * config-lang.in (gtfiles): Add cp-tree.h decl.h lex.h call.c
+ decl2.c parse.y pt.c repo.c spew.c.
+ * cp-tree.h: Use gengtype for roots.
+ (struct saved_scope): Use GGC, gengtype.
+ (cp_parse_init): Delete prototype.
+ (init_pt): Delete prototype.
+ * decl.c: Use gengtype for roots.
+ (mark_saved_scope): Delete.
+ (cxx_init_decl_processing): Don't call deleted initilisation
+ routines.
+ (signed_size_zero_node): Delete, unused.
+ * decl.h: Use gengtype for roots.
+ * decl2.c: Use gengtype for roots.
+ * lex.h: Use gengtype for roots.
+ * parse.y: Use gengtype for roots.
+ (cp_parse_init): Delete.
+ * pt.c: Use gengtype for roots.
+ (init_pt): Delete.
+ * repo.c: Use gengtype for roots.
+ * spew.c: Use gengtype for roots.
+
+ * Make-lang.in: Allow for filename changes. Add gtype-cp.h.
+ (cp/decl.o): Add dependency on gtype-cp.h.
+ * decl.c: Remove use of add_deletable_root, use GTY marker instead.
+ Include gtype-cp.h. Allow for filename changes.
+
+ * Make-lang.in (cp/gt-decl.h): Generate using gengtype.
+ (cp/decl.o): Add cp/gt-decl.h dependency.
+ * config-lang.in (gtfiles): New.
+ * tree.h: Rename struct binding_level to struct cp_binding_level.
+ * decl.c: Rename struct binding_level to struct cp_binding_level.
+ Include cp/gt-decl.h.
+ (struct cp_binding_level): Use gengtype.
+ (make_binding_level): Use GGC on struct cp_binding_level.
+ (mark_binding_level): Use gt_ggc_m_cp_binding_level.
+ (cxx_init_decl_processing): Mark free_binding_level as
+ deletable.
+
+ * decl.c (mark_cp_function_context): Update calling sequence.
+
+ * decl.c (start_function): Don't free 'struct
+ cp_language_function'.
+ (pop_cp_function_context): Likewise.
+ (save_function_data): Allocate it using GC.
+ * semantics.c (genrtl_start_function): Don't free 'struct
+ cp_language_function'.
+
+2002-05-31 Matthew Woodcraft <mattheww@chiark.greenend.org.uk>
+
+ * lang-specs.h: Use cpp_debug_options.
+
+2002-05-28 Zack Weinberg <zack@codesourcery.com>
+
+ * mangle.c, tree.c: Include real.h.
+ * Make-lang.in: Update dependency lists.
+
+2002-05-25 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * lex.c: Don't include c-lex.h.
+ * parse.y, spew.c: Don't include c-lex.h; include c-pragma.h.
+
+2002-05-23 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * spew.c (yyungetc, snarf_block): Remove indent_level handling.
+
+2002-05-22 Richard Henderson <rth@redhat.com>
+
+ * decl.c (obscure_complex_init): Check for VAR_DECL
+ before using DECL_THREAD_LOCAL.
+
+2002-05-22 Richard Henderson <rth@redhat.com>
+
+ * decl.c (check_tag_decl): Handle RID_THREAD.
+ (obscure_complex_init): Reject run-time init of tls.
+ (grokvardecl, grokdeclarator): Handle RID_THREAD.
+ * lex.c (reswords): Add __thread.
+ (rid_to_yy): Map RID_THREAD to SCSPEC.
+
+2002-05-22 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_POST_OPTIONS): Use c_common_post_options.
+ * cp-tree.h (cxx_post_options): Kill.
+ * cp-lex.c (cxx_post_options): Kill.
+
+2002-05-21 Richard Henderson <rth@redhat.com>
+
+ * lex.c (rid_to_yy): Add RID_THREAD.
+
+2002-05-21 Alexandre Oliva <aoliva@redhat.com>
+
+ * init.c (build_vec_init): Test for trivial copy-assignment when
+ copy-assigning arrays.
+
+2002-05-20 Andreas Jaeger <aj@suse.de>
+
+ * init.c (build_default_init): Remove unused variable.
+
+2002-05-20 Alexandre Oliva <aoliva@redhat.com>
+
+ * call.c (any_strictly_viable): New.
+ (build_new_op): Use it for COMPOUND_EXPR and ADDR_EXPRs.
+
+2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * error.c (dump_type) [TYPEOF_TYPE]: Fix parenthesis printing.
+
+2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/186, DR 259
+ * pt.c (do_decl_instantiation): Don't complain explicit
+ instantiation after explicit specialization.
+ (do_type_instantiation): Likewise.
+
+2002-05-19 Alexandre Oliva <aoliva@redhat.com>
+
+ * cp-tree.h (complete_type_or_diagnostic): Changed prototype,
+ renamed from...
+ (complete_type_or_else): ... this. Redefined as macro.
+ (cxx_incomplete_type_diagnostic): Declare.
+ (cxx_incomplete_type_error): Define as macro.
+ * init.c (build_delete): Warn about incomplete types other than
+ void, and use the built-in operator delete for them.
+ * typeck.c (complete_type_or_diagnostic): Renamed from
+ complete_type_or_else. Added warn_only argument, passed to...
+ * typeck2.c (cxx_incomplete_type_diagnostic): ... this. Print
+ warnings or errors depending on new warn_only argument. Renamed
+ from...
+ (cxx_incomplete_type_error): ... this. New implementation in
+ terms of cxx_incomplete_type_diagnostic.
+
+2002-05-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/6611
+ * decl2.c (import_export_decl): If we clear
+ DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set.
+
+2002-05-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6620
+ * pt.c (verify_class_unification): Don't check if PARM is template
+ parameter dependent. Simplify.
+ (unify) [TEMPLATE_PARM_INDEX]: Handle when ARG is a template
+ parameter dependent expression.
+
+2002-05-14 Jason Merrill <jason@redhat.com>
+
+ * rtti.c (get_tinfo_decl): Don't call comdat_linkage.
+ Do set DECL_COMDAT.
+ (synthesize_tinfo_var): Take the public decl.
+ (create_real_tinfo_var): Likewise. Check DECL_COMDAT.
+ (emit_tinfo_decl): Adjust. Call import_export_decl.
+ * decl2.c (import_export_decl): Simplify tinfo decl handling.
+
+2002-05-14 Alexandre Oliva <aoliva@redhat.com>
+
+ * cp-tree.h (struct lang_type): Added non_zero_init.
+ (CLASSTYPE_NON_ZERO_INIT_P): New macro.
+ (zero_init_p, force_store_init_value, build_forced_zero_init): Declare.
+ * class.c (check_field_decls): Test non_zero_init.
+ * cvt.c (convert_to_pointer_force): Use cp_convert_to_pointer for
+ zero-to-NULL conversions.
+ * decl.c (obscure_complex_init): Don't reset DECL_INITIAL of a
+ type that needs zero-initialization without zeros.
+ (check_initializer_decl): Compute zero-initializer for types
+ that require a non-trivial one.
+ * init.c (build_forced_zero_init): New function.
+ (build_default_init): Use it.
+ * tree.c (zero_init_p): New function.
+ * typeck2.c (force_store_init_value): New function.
+ (process_init_constructor): Create non-trivial zero-initializers
+ for array members and class fields.
+
+2002-05-14 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * lang-specs.h: Remove redundant -lang-c++.
+
+2002-05-13 Jason Merrill <jason@redhat.com>
+
+ * class.c (build_vtbl_ref_1): Use fixed_type_or_null.
+ (fixed_type_or_null): See through reference vars.
+ (build_base_path): Vtable contents are constant.
+ * typeck.c (get_member_function_from_ptrfunc): Likewise.
+
+2002-05-12 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (ok_to_generate_alias_set_for_type): Backend-created
+ structs are safe.
+
+2002-05-09 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (flag_ansi): Remove.
+ * decl2.c (flag_ansi): Remove.
+ (cxx_decode_option): Set flag_iso and flag_undef.
+
+2002-05-09 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Reorganize.
+ Use subtraction rather than a bitmask to get the index.
+ * cvt.c (cp_convert_to_pointer): Bail on an error_mark_node.
+
+ * pt.c (tsubst_expr) [ASM_STMT]: Copy ASM_INPUT_P.
+
+2002-05-07 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * Make-lang.in (decl2.o): Update.
+ * cp-tree.h (warn_multichar): Remove.
+ * decl2.c: Include c-common.h.
+ (warn_multichar): Remove.
+
+2002-05-03 Jason Merrill <jason@redhat.com>
+
+ * tree.c (build_cplus_array_type): Only const and volatile get
+ special handling.
+
+ * decl.c (BOOL_TYPE_SIZE): Move default to defaults.h.
+
+2002-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ ABI change, returning simple classes from functions.
+ * class.c (finish_struct_bits): Only mark TREE_ADDRESSABLE if
+ TYPE_HAS_TRIVIAL_INIT_REF is false or
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR is true.
+
+2002-04-30 Jason Merrill <jason@redhat.com>
+
+ PR debug/6436
+ * decl.c (grokdeclarator): Don't override TYPE_NAME of an
+ anonymous class with a typedef if there are attributes.
+
+2002-04-29 Paul Eggert <eggert@twinsun.com>
+
+ * parse.y (nomods_initdcl0): Replace $<ttype>3 with $<ttype>$.
+
+2002-04-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6477
+ * decl.c (follow_tag_typedef): Check if TYPE_NAME (original) is
+ non-NULL first.
+
+2002-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6492
+ * pt.c (tsubst_friend_class): If the friend has an explicit scope,
+ enter that scope before name lookup.
+
+ PR c++/6486
+ * method.c (do_build_copy_constructor): Avoid building
+ cv-qualified reference types.
+
+2002-04-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5719
+ * decl.c (grok_op_properties): Assignment ops don't have to return
+ by value. operator% should.
+
+2002-04-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR c/6343
+ * decl.c (duplicate_decls): Call merge_weak.
+
+2002-04-26 Richard Henderson <rth@redhat.com>
+
+ * parse.y (malloced_yyss, malloced_yyvs): New.
+ (yyoverflow): Re-add. Set them.
+ (free_parser_stacks): New.
+
+2002-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6497
+ * method.c (do_build_assign_ref): Pass a derivation to
+ build_method_call when calling base class assignment operators.
+
+2002-04-26 Richard Henderson <rth@redhat.com>
+
+ * parse.y (yyoverflow): Revert.
+
+2002-04-26 Richard Henderson <rth@redhat.com>
+
+ PR c/3581
+ * parse.y (string): Remove. Update all uses to use STRING
+ instead, and not call combine_strings.
+ * rtti.c (tinfo_name): Use fix_string_type.
+ * semantics.c (finish_asm_stmt): Don't call combine_strings.
+ * spew.c (yylexstring): New.
+ (read_token): Use it.
+
+2002-04-25 Richard Henderson <rth@redhat.com>
+
+ PR c/2161
+ * parse.y (yyoverflow): New.
+
+2002-04-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/5607
+ * search.c (check_final_overrider): No longer static.
+ * class.c (update_vtable_entry_for_fn): Call it.
+ * cp-tree.h: Adjust.
+
+2002-04-25 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_SET_YYDEBUG): Remove.
+ * cp-tree.h (cxx_set_yydebug): Die.
+ * lex.c (YYDEBUG): Get from c-lex.h.
+ (cxx_set_yydebug): Remove.
+ * parse.y: Include c-lex.h.
+ (YYDEBUG): Get from c-lex.h.
+
+2002-04-24 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6438.
+ * cvt.c (convert_to_void): Don't unconditionally make COND_EXPRs
+ void.
+
+2002-04-24 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE,
+ LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE, LANG_HOOKS_ATTRIBUTE_TABLE):
+ Redefine.
+ * cp-tree.h (cp_attribute_table): Rename.
+ * decl.c (lang_attribute_table): Remove declaration.
+ (cxx_init_decl_processing): Don't set it.
+ * tree.c (cp_attribute_table): Rename.
+
+2002-04-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/6331
+ * method.c (do_build_copy_constructor): Use cp_build_qualified_type.
+ * typeck.c (build_modify_expr): Allow arrays to differ in cv-quals.
+ The pedwarn for array assignment is now unconditional.
+ * tree.c (build_cplus_array_type_1): Still process simple array types
+ normally in templates.
+
+ PR c++/6395
+ * decl.c (make_rtl_for_nonlocal_decl): Don't mess with #pragma i/i
+ stuff for comdats.
+
+2002-04-23 Jakub Jelinek <jakub@redhat.com>
+
+ * parse.y (check_class_key): Allow KEY to be union/enum/struct/class
+ node with attributes.
+
+2002-2-23 David O'Brien <obrien@FreeBSD.org>
+
+ * g++spec.c (MATH_LIBRARY_PROFILE, LIBSTDCXX_PROFILE): Add.
+ Use MATH_LIBRARY_PROFILE and LIBSTDCXX_PROFILE if profile flag given.
+
+2002-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6256:
+ * pt.c (tsubst_friend_class): Handle templates with explicit
+ nested names.
+
+ PR c++/6331:
+ * typeck.c (merge_types): Remember the cv-qualification of pointer
+ types when merging them.
+
+2002-04-20 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_FUNCTION_INIT,
+ LANG_HOOKS_FUNCTION_FREE, LANG_HOOKS_FUNCTION_MARK): Redefine.
+ * cp-tree.h (cxx_push_function_context, cxx_pop_function_context,
+ cxx_mark_function_context): New.
+ * decl.c (push_cp_function_context, pop_cp_function_context,
+ mark_cp_function_context): Rename for consistency.
+ (cxx_init_decl_processing): Don't set old hooks.
+
+2002-04-19 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (convert_type_from_ellipsis): Rename, update.
+ * cp-lang.c (LANG_HOOKS_TYPE_PROMOTES_TO): Redefine.
+ * cp-tree.h (convert_type_from_ellipsis): Rename.
+ * decl.c (cxx_init_decl_processing): Don't set hook.
+
+2002-04-18 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (build_new_method_call): Update.
+ * cp-lang.c (LANG_HOOKS_INCOMPLETE_TYPE_ERROR): Redefine.
+ * cp-tree.h (cxx_incomplete_type_error): New.
+ * decl.c (grokdeclarator, grokparms): Update.
+ * decl2.c (check_classfn): Update.
+ * pt.c (tsubst): Update.
+ * typeck.c (complete_type_or_else, expr_sizeof,
+ decay_conversion): Update.
+ * typeck2.c (incomplete_type_error): Rename.
+ (add_exception_specifier): Update.
+
+2002-04-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/5658
+ * search.c (setup_class_bindings): A class template qualifies as a
+ type binding.
+
+2002-04-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6316
+ * decl2.c (finish_file): Clear DECL_EXTERNAL in a separate loop
+ before expanding.
+
+2002-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (begin_init_stmts): Remove commented out code.
+ (finish_init_stmts): Set STMT_EXPR_NO_SCOPE.
+ * semantics.c (begin_gobal_stmt_expr): Adjust call to
+ expand_start_stmt_expr.
+
+2002-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (register_dtor_fn): Pass the address of dso_handle, not
+ dso_handle itself, to __cxa_atexit.
+
+2002-04-15 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * error.c (cxx_print_error_function): Adjust call to macros.
+
+2002-04-14 Jakub Jelinek <jakub@redhat.com>
+
+ * class.c (layout_virtual_bases): Do all dsize computation on trees.
+
+2002-04-14 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Don't do
+ gratuitious division and multiplication on
+ ptrmemfunc_vbit_in_delta targets.
+
+2002-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5373.
+ * semantics.c (finish_expr_stmt): Remember the type of the
+ expression before any conversions are performed.
+
+2002-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5189.
+ * call.c (add_template_candidate_real): Do not treat member
+ templates as copy constructors.
+
+2002-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Do not copy the RTL for a variable
+ declaration if the old variable had an incomplete type and the new
+ variable does not.
+ (complete_vars): Do not call layout_decl for completed variables.
+
+2002-04-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * decl.c (duplicate_decls): Don't try to unify an implicit typedef
+ with an explicit one.
+ (follow_tag_typedef): New.
+ (lookup_tag): Use it to extract the tag of an explicit typedef.
+ (xref_tag): Likewise.
+
+2002-04-11 Andrew Haley <aph@redhat.com>
+
+ * typeck.c (type_after_usual_arithmetic_conversions):
+ If two types have the same variant, return immediately.
+ When two floating-point operands are the same precision:
+ convert to float if one of the operands is float;
+ if neither operand is one of the standard types, return the type
+ of the first operand.
+
+2002-04-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5507
+ * decl.c (make_typename_type): Remove implicit typenameness.
+
+2002-04-09 Jason Merrill <jason@redhat.com>
+
+ PR optimization/6189
+ * semantics.c (genrtl_start_function): Don't free
+ DECL_SAVED_FUNCTION_DATA for inline functions.
+
+ * init.c (build_member_call): For now, don't convert to
+ intermediate base if it would cause an error.
+
+2002-04-08 Paolo Carlini <pcarlini@unitus.it>
+
+ * parse.y (namespace_qualifier, maybe_identifier,
+ begin_explicit_instantiation, end_explicit_instantiation,
+ apparent_template_type, .finish_template_type,
+ do_id, maybe_init, defarg_again, component_decl_1):
+ Add ending ';', in accordance with POSIX.
+
+2002-04-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5571
+ * class.c (layout_class_type): Remember incomplete static
+ variables.
+ (finish_struct_1): Call complete_vars, not
+ hack_incomplete_structures.
+ * cp-tree.h (hack_incomplete_structures): Rename to ...
+ (complete_vars): ... this.
+ (struct saved_scope): Remove incomplete.
+ (namespace_scope_incomplete): Remove.
+ * decl.c (struct binding_level): Remove incomplete.
+ (incomplete_vars): New variable.
+ (mark_binding_level): Don't mark incomplete.
+ (print_binding_level): Don't print it.
+ (mark_saved_scope): Don't mark incomplete.
+ (pushdecl): Use maybe_register_incopmlete_var.
+ (cxx_init_decl_processing): Register incomplete_vars for GC.
+ (start_decl_1): Clarify error message.
+ (hack_incomplete_vars): Remove.
+ (maybe_register_incomplete_var): New function.
+ (complete_vars): Likewise.
+
+2002-04-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/4934
+ * error.c (dump_expr) [CONVERT_EXPR]: Make sure TREE_TYPE (t) is
+ set before checking it.
+
+ PR c++/525
+ * init.c (build_member_call): Use build_scoped_ref.
+ (resolve_offset_ref): Likewise.
+ * call.c (build_scoped_method_call): Likewise.
+ * tree.c (maybe_dummy_object): Kludge around current_class_type being
+ wrong.
+ * typeck2.c (build_scoped_ref): Return the binfo via binfo_p parm.
+ * cp-tree.h: Adjust.
+
+ * init.c (push_base_cleanups): Just use build_scoped_method_call.
+
+ PR c++/6179
+ * method.c (implicitly_declare_fn): Pass unqualified type to
+ synthesize_exception_spec.
+
+2002-04-04 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Redefine.
+ * cvt.c: Update comment.
+ * init.c (expand_cleanup_for_base): Update.
+ * semantics.c (finish_parenthesized_expr): Update.
+ * typeck.c (cp_truthvalue_conversion): Update.
+
+2002-04-04 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (finish_eh_cleanup): New fn.
+ * cp-tree.h: Add prototype.
+ * init.c (perform_member_init, expand_cleanup_for_base): Use
+ finish_eh_cleanup.
+ * cp-tree.def (SUBOBJECT, CTOR_STMT): Remove.
+ * cp-tree.h: Remove references.
+ * decl.c (begin_constructor_body, end_constructor_body): Likewise.
+ * dump.c (cp_dump_tree): Likewise.
+ * pt.c (tsubst_expr): Likewise.
+ * semantics.c (genrtl_ctor_stmt, genrtl_subobject): Remove.
+ (cp_expand_stmt): Remove handling of CTOR_STMT and SUBOBJECT.
+ * tree.c (cp_statement_code_p): Likewise.
+
+ * init.c (build_new_1): Set CLEANUP_EH_ONLY on deleting cleanup.
+
+ PR c++/5636
+ * semantics.c (nullify_returns_r): Just set CLEANUP_EH_ONLY on
+ cleanup for nrv.
+
+ PR c++/5104
+ * typeck.c (comptypes) [FUNCTION_TYPE]: Don't compare exception
+ specifiers.
+ [METHOD_TYPE]: Use same code as FUNCTION_TYPE.
+
+2002-04-03 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c (cxx_warn_unused_global_decl): New.
+ (LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.
+
+2002-04-03 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): Redefine.
+ * tree.c (init_tree): Don't set hook.
+
+2002-04-03 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/5998:
+ * decl.c (duplicate_decls): Don't mess with assembler names when
+ redeclaring builtin functions as static.
+
+2002-04-01 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (build_addr_func): Update.
+ * class.c (resolve_address_of_overloaded_function): Update.
+ * cp-lang.c (LANG_HOOKS_MARK_ADDRESSABLE): Redefine.
+ * cp-tree.h (cxx_mark_addressable): New.
+ * decl.c (register_dtor_fn, cxx_maybe_build_cleanup): Update.
+ * decl2.c (build_cleanup): Update.
+ * except.c (build_throw): Update.
+ * init.c (resolve_offset_ref): Update.
+ * pt.c (convert_nontype_argument): Update.
+ * semantics.c (finish_asm_stmt, simplify_affr_init_exprs_r): Update.
+ * typeck.c (decay_conversion, build_array_ref, build_unary_op,
+ unary_complex_lvalue): Update.
+ (mark_addressable): Rename.
+
+2002-04-01 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/5998:
+ * decl.c (duplicate_decls): Overwrite the RTL when (and only
+ when) overwriting a built-in function. Don't use COPY_DECL_RTL,
+ but follow the SET_DECL_RTL idiom used elsewhere in the function.
+
+2002-04-01 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_SIGNED_TYPE, LANG_HOOKS_UNSIGNED_TYPE,
+ LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE): New.
+ * decl.c (grokdeclarator): Update.
+ * mangle.c (write_integer_cst): Update.
+ * typeck.c (build_binary_op): Update.
+
+2002-03-31 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_UNSAFE_FOR_REEVAL): Redefine.
+ * lex.c (cxx_init): Don't set hook.
+
+2002-03-31 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * Make-lang.in (error.o): Update.
+ * cp-lang.c (LANG_HOOKS_PRINT_ERROR_FUNCTION): Redefine.
+ * cp-tree.h (struct diagnostic_context): Predeclare.
+ (cxx_print_error_function): New.
+ * error.c: Include langhooks-def.h.
+ (lang_print_error_function): Rename. Update.
+ (init_error): Don't set hook.
+
+2002-03-29 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIZE):
+ Redefine.
+ * cvt.c (cp_convert_to_pointer, type_promotes_to): Use new hooks.
+ * decl.c (finish_enum): Similarly.
+ * error.c (dump_type): Similarly.
+ * lex.c (cxx_init): Similarly.
+ * mangle.c (write_builtin_type): Similarly.
+ * typeck.c (comptypes): Similarly.
+
+2002-03-28 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/5998:
+ * decl.c (cxx_init_decl_processing): Re-enable built-in functions
+ in the g++ front-end.
+ (duplicate_decl): Allow redefinition of anticipated built-ins.
+ Fix inlining problem by over-writing the old DECL_RTL.
+ (lookup_namespace_name): Fail to find an identifier in the
+ specified namespace if its still anticipated.
+ (builtin_function_1): New function split out from builtin_function
+ to create a builtin in the current namespace with given context.
+ (builtin_function): Call builtin_function_1 to define the
+ appropriate builtins in both the std and global namespaces.
+ (select_decl): Don't test for anticipated decls here.
+ (unqualified_namespace_lookup): Instead ignore them whilst
+ searching through scopes and namespaces.
+ * decl2.c (do_nonmember_using_decl): If a using declaration
+ specifies an anticipated built-in function, mark it as no longer
+ anticipated in that scope.
+ (ambiguous_decl): Avoid resolving to an anticipated decl.
+ * lex.c (do_scoped_id): Fail to find an identifier in the global
+ namespace if its still anticipated.
+
+2002-03-29 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_MAKE_TYPE): Redefine.
+ * cp-tree.h (cp_make_lang_type): Rename.
+ * lex.c (cp_make_lang_type): Rename.
+ (make_aggr_type): Update.
+ * tree.c (init_tree): Don't set make_lang_type_fn.
+
+2002-03-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6073
+ * class.c (finish_struct_1): Update static field's DECL_MODE even
+ if its type is a variant of t.
+
+2002-03-27 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Redefine.
+ * cp-tree.h (cxx_insert_default_attributes): New.
+ * decl.c (insert_default_attributes): Rename.
+
+2002-03-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/4884
+ * call.c (build_op_delete_call): Allow for the fact the placement
+ may be a COMPOUND_EXPR.
+
+2002-03-27 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_EXPAND_EXPR): Redefine.
+ * cp-tree.h (init_cplus_expand): Remove.
+ (cxx_expand_expr): New.
+ * expr.c (cplus_expand_expr): Rename cxx_expand_expr,
+ fix prototype.
+ (init_cplus_expand): Remove.
+ * lex.c (cxx_init): Don't call init_cplus_expand.
+
+2002-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/4884.
+ * init.c (build_new_1): Allow for the fact the result of
+ build_function_call may be a COMPOUND_EXPR.
+
+2002-03-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5682
+ * cp-tree.h (BINFO_PRIMARY_P): Explain meaning better.
+ (dfs_skip_nonprimary_vbases_unmarkedp): Remove.
+ (dfs_skip_nonprimary_vbases_markedp): Remove.
+ * search.c (get_shared_vbase_if_not_primary): Remove.
+ (dfs_skip_nonprimary_vbases_unmarkedp): Remove.
+ (dfs_skip_nonprimary_vbases_markedp): Remove.
+ (dfs_unmarked_real_bases_queue_p): Just get the canonical binfo.
+ (dfs_marked_real_bases_queue_p): Likewise.
+
+2002-03-26 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_MARK_TREE): Redefine.
+ * cp-tree.h (cxx_mark_tree): New.
+ * decl.c (lang_mark_tree): Rename cxx_mark_tree.
+
+2002-03-25 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (cxx_maybe_build_cleanup): New.
+ * decl.c (destroy_local_var, hack_incomplete_structures): Update.
+ (maybe_build_cleanup): Rename cxx_maybe_build_cleanup.
+ * tree.c (build_target_expr): Update.
+ * cp-lang.c (LANG_HOOKS_MAYBE_BUILD_CLEANUP): Redefine.
+
+2002-03-24 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c (cxx_decode_option): Handle -E.
+ * lang-specs.h (default_compilers): Preprocess with cc1plus.
+ * lex.c (cxx_init): Exit quickly if c_common_init returns NULL.
+
+2002-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6037
+ * decl.c (start_enum): Don't set TREE_ADDRESSABLE on TREE_LIST node.
+
+2002-03-23 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * error.c (dump_type): Be careful about implicit typenames.
+
+2002-03-21 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ PR C++/3656
+ * semantics.c (finish_base_specifier): Handle erronous base
+ classes.
+
+2002-03-22 Zack Weinberg <zack@codesourcery.com>
+
+ * error.c: Always use REAL_VALUE_TO_DECIMAL; don't test
+ REAL_IS_NOT_DOUBLE.
+
+2002-03-22 Jeff Knaggs <jknaggs@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Scale idx down to
+ an index into the vtable_entry array regardless of
+ TARGET_PTRMEMFUNC_VBIT_LOCATION.
+
+2002-03-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.c (cp_cannot_inline_tree_fn): Same.
+
+2002-03-21 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (pushdecl, pushlevel, poplevel, set_block,
+ insert_block, getdecls, global_bindings_p): New.
+
+2002-03-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4361
+ * mangle.c (struct globals) Add internal_mangling_p member.
+ (write_template_param): Do internal mangling, if needed.
+ (mangle_conv_op_name_for_type): Request internal mangling.
+
+2002-03-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/2136
+ * init.c (build_delete): Check access for a member op delete here.
+ * decl2.c (delete_sanity): Not here.
+
+2002-03-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/5118
+ * class.c (get_vfield_name): Use the constructor_name.
+
+2002-03-20 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_DECL_PRINTABLE_NAME): Redefine.
+ * cp-tree.h (lang_printable_name): Rename.
+ * error.c (lang_decl_name): Use new hook.
+ * lex.c (cxx_init): Remove old hook.
+ * pt.c (tsubst_decl): Use new hook.
+ * tree.c (lang_printable_name): Rename.
+
+2002-03-18 Eric Botcazou <ebotcazou@multimania.com>
+
+ PR c++/3882
+ * pt.c (tsubst_decl): Move __PRETTY_FUNCTION__ handling...
+ (tsubst_expr) [DECL_STMT]: ...here. And substitute the initializer
+ only after recording the declaration.
+
+2002-03-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/2039
+ * init.c (resolve_offset_ref): Hand off to build_component_ref.
+
+ PR c++/4222, c++/5995
+ * call.c (build_over_call): Fix empty class logic.
+
+ PR c++/3870
+ * cp-tree.h (struct saved_scope): Add last_parms field.
+ * decl.c (maybe_push_to_top_level): Save last_function_parms.
+ (pop_from_top_level): Restore it.
+
+ PR c++/4377
+ * mangle.c (write_expression): Strip NOP_EXPRs sooner. Also strip
+ NON_LVALUE_EXPRs.
+
+ PR c++/4003
+ * pt.c (tsubst_friend_function): Use decl_namespace_context.
+
+ PR c++/3948 -- C++ ABI change, followup to 2001-12-18 patch.
+ * class.c (finish_struct_bits): Also set TREE_ADDRESSABLE for a
+ type with a nontrivial destructor.
+
+2002-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/4460
+ * class.c (build_base_path): Virtual base layout is fixed in
+ in-charge [cd]tors.
+
+2002-03-17 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_PARSE_FILE): Redefine.
+ * parse.y (yyparse): Remove macro.
+
+2002-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/5757
+ * init.c (build_new_1): Pass the right pointer to op delete.
+
+2002-03-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4361
+ * cp-tree.h (CLASSTYPE_METHOD_VEC): Document where templated
+ conversion operators go.
+ (struct lang_decl_flags): Add template_conv_p and unused
+ bitfields.
+ (DECL_TEMPLATE_CONV_FN_P): New macro.
+ * call.c (build_user_type_conversion_1): Don't check second type
+ conversion of overload set first.
+ * class.c (add_method): Make sure templated conversion operators
+ all end up on slot 2.
+ * lex.c (do_identifier): A conversion operator token might be
+ satisfied by a templated conversion operator.
+ * pt.c (check_explicit_specialization): Use
+ CLASSTYPE_FIRST_CONVERSION_SLOT.
+ (template_parm_this_level_p): New function.
+ (push_template_decl_real): Determine DECL_TEMPLATE_CONV_FN_P.
+ * search.c (lookup_fnfields_1): Template conversions will be on
+ the first slot.
+ * typeck.c (build_component_ref): Preserve the type of an
+ conversion operator name on the overload type.
+ (build_x_function_call): Retrieve the conversion operator name.
+
+2002-03-15 Richard Henderson <rth@redhat.com>
+
+ * init.c (build_new_1): Use size_binop instead of cp_build_binary_op.
+
+2002-03-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLEANUP_DECL): Remove.
+ (CLEANUP_EXPR): Likewise.
+ * decl.c (destroy_local_var): Simplify.
+ (maybe_build_cleanup): Tidy.
+ * dump.c (cp_dump_tree): Remove handling of CLEANUP_STMT.
+ * semantics.c (cp_expand_stmt): Likewise.
+ * cp/tree.c (cp_statement_code_p): Likewise.
+
+2002-03-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/5857
+ * decl.c (duplicate_decls): Use merge_types instead of common_type.
+ * typeck.c (common_type): Just hand off to
+ type_after_usual_arithmetic_conversions and
+ composite_pointer_type.
+ (merge_types): New fn.
+ (commonparms): Use it instead of common_type.
+ (type_after_usual_arithmetic_conversions): Also handle COMPLEX_TYPE.
+ (composite_pointer_type): Also handle attributes.
+ * cp-tree.h: Declare merge_types.
+
+ * decl.c (make_rtl_for_nonlocal_decl): Also defer COMDAT
+ variables.
+ * decl2.c (maybe_make_one_only): Also mark the decl as needed.
+
+2002-03-14 Richard Henderson <rth@redhat.com>
+
+ * decl.c: Include c-pragma.h.
+ (start_decl, start_function): Invoke maybe_apply_pragma_weak.
+ * Make-lang.in: Update dependencies.
+
+2002-03-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/5908
+ * call.c (build_over_call): Set TREE_NO_UNUSED_WARNING too.
+ * cvt.c (convert_to_void): Preserve TREE_NO_UNUSED_WARNING.
+
+2002-03-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * mangle.c (write_builtin_type): Handle 128-bit integers even if
+ they are not a standard integer type.
+
+2002-03-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * cp-tree.h (init_init_processing): Remove declaration.
+ * init.c (BI_header_type, init_init_processing): Remove old ABI stuff.
+ * decl.c (cxx_init_decl_processing): Don't call init_init_processing.
+
+2002-03-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-lang.c (tree_code_type, tree_code_length, tree_code_name):
+ Define.
+ * decl.c (duplicate_decls): Use TREE_CODE_LENGTH, not
+ tree_code_length.
+ * lex.c (cplus_tree_code_type, cplus_tree_code_length,
+ cplus_tree_code_name): Delete.
+ (cxx_init): Don't call add_c_tree_codes, instead set
+ lang_unsafe_for_reeval. Don't try to copy into the various
+ tree_code arrays.
+
+2002-03-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5659
+ * decl.c (xref_tag): Don't set CLASSTYPE_DECLARED_CLASS here.
+ * decl2.c (handle_class_head): Set CLASSTYPE_DECLARED_CLASS for
+ definitions.
+
+2002-03-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ Revert 2001-03-26 Nathan Sidwell <nathan@codesourcery.com>,
+ DR209 is now not a defect.
+ * cp-tree.h (skip_type_access_control): Remove.
+ * decl.c (grokdeclarator): Do type access control for friend
+ declarations.
+ * semantics.c (decl_type_access_control): Don't reset
+ current_type_lookups.
+ (save_type_access_control): Always save the lookups.
+ (skip_type_access_control): Remove.
+ (finish_class_definition): Don't change type_lookups.
+
+2002-03-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ Revert 2000-12-01 Nathan Sidwell <nathan@codesourcery.com>,
+ It is incorrect.
+ * typeck.c (build_static_cast): Compare non-qualified types
+ with pointer to member conversions.
+
+2002-03-11 Dan Nicolaescu <dann@ics.uci.edu>
+ Daniel Berlin <dan@dberlin.org>
+
+ * cp-lang.c (ok_to_generate_alias_set_for_type): New function.
+ (cxx_get_alias_set): Use it.
+
+2002-03-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (stabilize_expr): Prototype.
+
+2002-03-08 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ * cp-tree.h (CLEAR_BINFO_MARKED): Make both parts of
+ conditional return void.
+
+2002-03-08 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_UNSAVE): Redefine.
+ * cp-tree.h (cxx_unsave): New.
+ * tree.c (cp_unsave): Rename cxx_unsave, update prototype.
+ (init_tree): Update.
+
+2002-03-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (cxx_init_decl_processing): Use ARRAY_SIZE in lieu of
+ explicit sizeof/sizeof.
+ * decl2.c (cxx_decode_option): Likewise.
+ * lex.c (init_reswords, REDUCE_LENGTH, TOKEN_LENGTH): Likewise.
+
+2002-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/775
+ * decl.c (lookup_tag): Only reject enum/class mismatch, not
+ class/union mismatch.
+ * parse.y (check_class_key): New function.
+ (structsp): Call it.
+
+2002-03-01 Michael Matz <matz@suse.de>
+
+ * typeck.c (cp_pointer_int_sum): Complete inner type which is
+ used later by size_in_bytes().
+
+2002-03-01 Phil Edwards <pme@gcc.gnu.org>
+
+ * cp-tree.h: Require __GNUC__ to be #defined.
+ (build_init): Add missing prototype.
+
+2002-03-01 Jason Merrill <jason@redhat.com>
+
+ * except.c: Don't include decl.h or obstack.h. Do include
+ tree-inline.h.
+ (build_throw): Destroy temporaries from the thrown
+ expression before calling __cxa_throw. Construct a thrown
+ temporary directly into the exception object.
+ (stabilize_throw_expr): New function.
+ (wrap_cleanups_r): New function.
+ * tree.c (stabilize_expr): New function.
+ * init.c (build_init): New function.
+ * Make-lang.in (cp/except.o): Adjust .h deps.
+
+2002-02-28 Jason Merrill <jason@redhat.com>
+
+ * search.c (lookup_base_r): Don't clear is_non_public just because
+ we found a friendly scope.
+
+ * decl.c (finish_function): Only warn about missing return
+ statement with -Wreturn-type.
+
+2002-02-28 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * class.c (build_clone): Update.
+ * cp-lang.c (LANG_HOOKS_DUP_LANG_SPECIFIC_DECL): Redefine.
+ * cp-tree.h (cxx_dup_lang_specific_decl): New.
+ * lex.c (copy_lang_decl): Rename cxx_dup_lang_specific_decl.
+ (copy_decl): Update.
+ * method.c (make_thunk): Update.
+
+2002-02-27 Zack Weinberg <zack@codesourcery.com>
+
+ * decl2.c: Delete traditional-mode-related code copied from
+ the C front end but not used, or used only to permit the
+ compiler to link.
+
+2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ PR c++/4093
+ * cp-tree.h (SET_BINFO_MARKED): Cast false part of condition
+ to void.
+
+2002-02-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/5746
+ * semantics.c (finish_switch_cond): Don't call get_unwidened
+ if error_mark_node.
+
+2002-02-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2645, DR 295
+ * cp-tree.h (tsubst_flags_t): Add tf_ignore_bad_quals,
+ tf_keep_type_decl.
+ (make_typename_type): Use tsubst_flags_t.
+ * decl.c (make_typename_type): Adjust. Return non-artificial
+ TYPE_DECLs, if required.
+ (grokdeclarator): Simplify CVR qualification handling. Allow bad
+ qualifiers on typedef types.
+ * decl2.c (handle_class_head): Adjust make_typename_type call.
+ * parse.y (nested_name_specifier): Likewise.
+ (typename_sub0): Likewise.
+ (typename_sub1): Likewise.
+ * pt.c (convert_template_argument): Adjust make_typename_type
+ return value.
+ (tsubst): Adjust cp_build_qualified_type_real calls.
+ (check_cv_quals_for_unify): Cope with allowing bad qualifications
+ on template type parms.
+ (instantiate_decl): Recheck substitutions to give warnings on bad
+ qualifications.
+ * tree.c (cp_build_qualified_type_real): Use tf_allow_bad_quals.
+
+2002-02-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp/decl.c (duplicate_decls): Merge always_inline attribute.
+
+ * cp/tree.c (cp_cannot_inline_tree_fn): Do not inline at -O0
+ unless DECL_ALWAYS_INLINE.
+
+2002-02-20 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck.c (cp_pointer_int_sum): Renamed from
+ pointer_int_sum, call pointer_int_sum.
+
+2002-02-20 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (duplicate_decls): Return 0 if issued error about
+ redeclaration.
+
+2002-02-19 Jason Merrill <jason@redhat.com>
+
+ ABI change: Mangle `void (A::*)() const' as
+ M1AKFvvE, not MK1AFvvE.
+ * mangle.c (write_function_type): Write cv-quals for member
+ function type here.
+ (write_pointer_to_member_type): Not here.
+
+2002-02-18 Jason Merrill <jason@redhat.com>
+
+ * pt.c (do_type_instantiation): Don't pedwarn if in_system_header.
+ (do_decl_instantiation): Likewise.
+
+2002-02-17 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ PR c++/5685
+ * decl.c (duplicate_decls): Make warning unconditional
+ if duplicate default argument declarations are present.
+
+2002-02-17 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck.c (build_binary_op) [BIT_XOR_EXPR]: Remove explicit
+ shortening.
+
+2002-02-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Set typedef_decl for all TYPE_DECLs,
+ remove incorrect comment. Move #if 0'd code to common path. Use
+ IMPLICIT_TYPENAME_P. Simplify & reformat ARRAY_TYPE duplication.
+
+2002-02-13 Jason Merrill <jason@redhat.com>
+
+ * decl.c (builtin_function): Set TREE_THIS_VOLATILE on return fns.
+ (finish_function): Don't warn if current_function_returns_null.
+
+ * typeck2.c (digest_init): Do handle values of vector type.
+
+ * typeck2.c (digest_init, process_init_constructor): Treat vectors
+ like arrays.
+
+2002-02-11 Jason Merrill <jason@redhat.com>
+
+ * parse.y (reserved_declspecs): Don't handle attributes.
+ (reserved_typespecquals): Handle them here.
+ * Make-lang.in (parse.c): Adjust expected conflicts.
+
+2002-02-08 Jakub Jelinek <jakub@redhat.com>
+
+ * parse.y (primary, primary_no_id): Use compstmt_or_stmtexpr
+ instead of compstmt.
+ (compstmt_or_stmtexpr): Renamed from compstmt.
+ (compstmt): In addition to compstmt_or_stmtexpr clear last_expr_type.
+
+2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ Rename instantiate_type_flags to tsubst_flags_t & expand use.
+ * cp-tree.h (instantiate_type_flags): Rename to ...
+ (tsubst_flags_t): ... here. Rename itf_complain to tf_error,
+ add tf_warning flag.
+ (instantiate_type): Adjust prototype.
+ (tsubst, tsubst_expr, tsubst_copy, lookup_template_class,
+ do_type_instantiation, cp_build_qualified_type_real): Likewise.
+ cp_build_qualified_type: Adjust.
+ * class.c (instantiate_type): Adjust parameter. Rename itf_* to
+ tf_*.
+ * call.c (standard_conversion): Rename itf_* to tf_*.
+ (reference_binding): Likewise.
+ (convert_like_real): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_reference): Likewise.
+ * decl.c (lookup_namespace_name): Use tf_* flags.
+ (make_typename_type): Likewise.
+ (grokdeclarator): Likewise.
+ * pt.c (convert_nontype_argument): Adjust COMPLAIN usage.
+ (coerce_template_template_parms, convert_template_argument,
+ coerce_template_parms, maybe_get_template_decl_from_type_decl,
+ lookup_template_class, tsubst_friend_function, tsubst_friend_class,
+ instantiate_class_template, tsubst_template_arg_vector,
+ tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument,
+ tsubst_decl, tsubst_arg_types, tsubst_function_type,
+ tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr,
+ instantiate_template, fn_type_unification,
+ resolve_overloaded_unification, verify_class_unification,
+ unify, get_bindings_real, do_type_instantiation,
+ regenerate_decl_from_template, instantiate_decl,
+ tsubst_initializer_list, tsubst_enum,
+ get_mostly_instantiated_function_type,
+ invalid_nontype_parm_type_p): Likewise.
+ * tree.c (cp_build_qualified_type_real): Likewise.
+ * typeck.c (build_binary_op): Rename itf_* to tf_*.
+ (build_ptrmemfunc): Likewise.
+ (convert_for_assignment): Likewise.
+
+2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/109
+ * decl.c (grokdeclarator): Allow friend declarations from
+ dependent types.
+ * decl2.c (handle_class_head): Don't push into template parm contexts.
+ * pt.c (push_template_decl_real): Template parm contexts are never
+ being defined.
+
+2002-02-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * class.c: Include target.h.
+ (check_bitfield_decl): Disregard EMPTY_FIELD_BOUNDARY,
+ BITFIELDS_NBYTES_LIMITED and PCC_BITFIELD_TYPE_MATTERS for MS
+ bit-field layout.
+ * Make-lang.in: Adjust deps.
+
+2002-02-05 Jason Merrill <jason@redhat.com>
+
+ * error.c (dump_type): Be more helpful about VECTOR_TYPE.
+
+2002-02-04 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (begin_switch_stmt): Clear SWITCH_TYPE.
+ (finish_switch_cond): Set SWITCH_TYPE.
+
+2002-02-04 Richard Henderson <rth@redhat.com>
+
+ * method.c (use_thunk): Always initialize the block tree. Reindent.
+ * semantics.c (expand_body): Emit thunks after function, not before.
+
+2002-02-04 Jason Merrill <jason@redhat.com>
+
+ * decl.c (start_function): Call cplus_decl_attributes immediately
+ after grokdeclarator.
+
+ * decl.c (start_function): Combine DECL_RESULT handling code.
+
+2002-02-03 Jason Merrill <jason@redhat.com>
+
+ * xref.c: Remove.
+ * Make-lang.in (CXX_OBJS): Remove cp/xref.o
+ (cp/xref.o): Remove dependencies.
+ * class.c (finish_struct_1, check_methods): Don't call xref fns.
+ (finish_struct_1): Likewise.
+ * friend.c (make_friend_class): Likewise.
+ * lex.c (cxx_init, cxx_finish, extract_interface_info): Likewise.
+ * spew.c (read_process_identifier): Likewise.
+
+2002-02-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/4872
+ * decl.c (finish_function): Warn about a non-void function with
+ no return statement and no abnormal exit.
+ * cp-tree.h (struct cp_language_function): Add returns_abnormally.
+ (current_function_returns_abnormally): New macro.
+ * call.c (build_call): Set it.
+
+ * typeck.c (build_component_ref): Always complain about offsetof
+ constructs on non-PODs. Only make it an error for members of
+ virtual bases.
+
+ * error.c (dump_scope): Don't add TFF_DECL_SPECIFIERS.
+ (dump_function_decl): Always dump parms.
+
+ * decl2.c (finish_static_data_member_decl): Complain about a local
+ class with a static data member.
+
+ PR c++/4286
+ * search.c (lookup_field_1): Don't xref a static data member
+ just because we looked it up.
+
+2002-01-31 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (parse.c): Handle .output file.
+
+ PR c++/3395
+ * decl.c (xref_tag): Remember early attributes in TYPE_ATTRIBUTES,
+ not TREE_TYPE.
+ * semantics.c (finish_class_definition): Adjust.
+
+ Allow attributes in parms and casts.
+ * parse.y (named_parm): Don't strip attrs.
+ (declmods): Remove 'attributes' production.
+ (nonempty_cv_qualifiers): Accept attributes.
+ (ATTRIBUTE): Give precedence.
+ * decl.c (groktypename): Handle attributes.
+ (grokparms): Likewise.
+
+2002-01-29 Jakub Jelinek <jakub@redhat.com>
+
+ * decl2.c (cxx_decode_option): Pass 0 as last argument to
+ cpp_handle_option.
+ * lang-specs.h: Use cpp_unique_options instead of cpp_options
+ when used together with cc1_options.
+
+2002-01-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5132
+ * typeck2.c (digest_init): Make sure non-array core type is
+ instantiated.
+ * decl2.c (reparse_absdcl_as_casts): Just store the type in the
+ constructor, rather than build a new one.
+ (build_expr_from_tree, CONSTRUCTOR case): Be careful with the
+ PURPOSE of constructor elts.
+
+2002-01-23 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in (parse.c): Adjust expected number of
+ shift-reduce conflicts.
+ (decl.o): Depend on diagnostic.h.
+ * decl.c: Include diagnostic.h.
+ (grokdeclarator): Check for null pointer.
+ (finish_function): Don't abort when
+ current_binding_level->parm_flag != 1, if errors have
+ occurred; throw away the statement tree and extra binding
+ levels, and continue.
+ * lex.c (note_list_got_semicolon): Check for null pointer.
+ * method.c (hack_identifier): Just return error_mark_node if
+ value is error_mark_node.
+ * parse.y (primary: TYPEID(type_id)): No need to use
+ TYPE_MAIN_VARIANT here.
+ (handler_seq): Accept an empty list of catch clauses and
+ generate a fake handler block to avoid later crashes.
+ (ansi_raise_identifier): Accept the error token too.
+ * semantics.c (begin_class_definition,
+ finish_class_definition): Check for error_mark_node.
+
+2002-01-23 Zack Weinberg <zack@codesourcery.com>
+
+ * typeck2.c (friendly_abort): Delete definition.
+ * cp-tree.h (friendly_abort): Don't prototype.
+ (my_friendly_assert): Use fancy_abort.
+
+2002-01-23 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ * cp-tree.h (my_friendly_abort): Remove.
+
+2002-01-23 Jakub Jelinek <jakub@redhat.com>
+
+ * spew.c (pending_inlines, pending_inlines_tail,
+ processing_these_inlines): Make static.
+ (mark_pending_inlines): Remove static.
+ (begin_parsing_inclass_inline): If in function, save pi
+ for GC to cp_function_chain->unparsed_inlines instead.
+ (process_next_inline): Likewise.
+ * cp-tree.h (struct cp_language_function): Add unparsed_inlines.
+ (mark_pending_inlines): Add prototype.
+ * decl.c (spew_debug): Remove unused extern.
+ (mark_lang_function): Call mark_pending_inlines.
+
+2002-01-23 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ * call.c, class.c, decl.c, decl2.c, error.c, expr.c, friend.c,
+ init.c, lex.c, mangle.c, method.c, pt.c, repo.c, rtti.c, search.c,
+ semantics.c, spew.c, tree.c, typeck.c, typeck2.c, xref.c:
+ Change my_fancy_abort() to abort().
+
+2002-01-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/5453
+ * class.c (fixed_type_or_null): Fix thinko.
+
+ PR c++/3331
+ * init.c (resolve_offset_ref): Use build_indirect_ref.
+
+ * decl2.c (grokclassfn): Don't set DECL_REGISTER on 'this'.
+
+2002-01-22 Jason Merrill <jason@redhat.com>
+
+ * parse.y (function_body): Suppress the block for the outermost
+ curly braces.
+ * decl.c (pushdecl): Don't try to skip it.
+ (begin_function_body): Keep the block we create, not the next one.
+ * init.c (emit_base_init): Don't mess with keep_next_level.
+
+ * class.c (build_base_path): Tweak formatting.
+
+2002-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ Fix regression introduced with patch for c++/775
+ * parse.y (class_head_defn): Check for template specializations
+ with a different class-key.
+
+2002-01-17 Jason Merrill <jason@redhat.com>
+
+ * decl.c (begin_constructor_body, begin_destructor_body): New fns.
+ (begin_function_body): Call them and keep_next_level.
+ * init.c (emit_base_init): Call keep_next_level.
+ * semantics.c (setup_vtbl_ptr): Lose.
+ * cp-tree.h (struct cp_language_function): Remove vtbls_set_up_p.
+ (vtbls_set_up_p): Lose.
+ * pt.c (tsubst_expr, CTOR_INITIALIZER): Call emit_base_init.
+ * method.c (do_build_copy_constructor): Likewise.
+ (synthesize_method): Call finish_mem_initializers.
+ * parse.y (nodecls): Likewise.
+
+ * error.c (dump_type_suffix): Print the exception specs before
+ recursing.
+ (dump_function_decl): Here, too.
+
+ * cp-tree.h (TMPL_PARMS_DEPTH): Cast to signed HOST_WIDE_INT.
+
+2002-01-10 Ira Ruben <ira@apple.com>
+
+ PR c++/907
+ * decl.c (start_method): Handle attrlist.
+
+2002-01-10 Jakub Jelinek <jakub@redhat.com>
+
+ * decl2.c (max_tinst_depth): Increase default limit to 500.
+
+2002-01-10 Graham Stott <grahams@redhat.com>
+
+ * spew.c (YYCHAR): Uppercase macro parameter and add
+ parenthesis.
+ (YYCODE): Likewise.
+ (NAME): Uppercase macro parameter.
+
+2002-01-09 Graham Stott <grahams@redhat.com>
+
+ * decl.h (grokdeclarator): Wrap long line.
+
+ * semantics.c (FINISH_COND): Uppercase macro paramaters and
+ add parenthesis.
+
+2002-01-08 Graham Stott <grahams@redhat.com>
+
+ * xref.c (FILE_NAME_ABSOLUTE_P): Add parenthesis.
+ (PALLOC): Uppercase macro parameter and whitespace.
+ (SALLOC): Uppercase macro parameter.
+ (SFREE): Uppercase macros parameter, add parenthese and
+ whitespace.
+ (STREQL): Uppercase macro parameter and whitespace.
+ (STRNEQ): Likewise.
+ (STRLSS): Likewise.
+ (STRLEQ): Likewise.
+ (STRGTR): Likewise.
+ (STRGEQ): Likewise.
+
+ * call.c (convert_like): Add parenthesis and wrap.
+ (convert_like_with_context): Likewise.
+ (ICS_RANK): Whitespace.
+ (NEED_TEMPORARY_P): Remove parenthesis.
+
+ * class.c (VTT_TOP_LEVEL_P): Uppercase macro parameter and
+ whitespace.
+ (VTT_MARKED_BINFO_P): Likewise.
+
+ * decl.c (BINDING_LEVEL): Add parenthesis.
+ (DEF_OPERATOR): Likewise.
+
+ * mangle.c (MANGLE_TRACE): Add parenthesis.
+ (MANGLE_TRACE_TREE): Likewise.
+ (write_signed_number): Likewise.
+ (write_unsigned_number): Likewise.
+
+ * pt.c (ccat): Uppercase macro parameter.
+ (cat): Likewise
+
+ * search.c (SET_BINFO_ACCESS): Add parenthesis.
+
+2002-01-07 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (coerce_new_type): Downgrade error for size_t mismatch
+ to pedwarn.
+
+ PR c++/3536
+ * method.c (make_thunk): If !flag_weak, give the thunk the
+ function's linkage.
+ (use_thunk): Here, too.
+
+2002-01-07 Graham Stott <grahams@redhat.com>
+
+ * error.c: Update copyright date.
+ (print_scope_operator): Add parenthesis.
+ (print_left_paren): Likewise.
+ (print_right_paren): Likewise.
+ (print_left_bracket): Likewise.
+ (print_right_bracket): Likewise.
+ (print_template_argument_list_start): Likewise.
+ (print_template_argument_list_end): Likewise.
+ (print_non_consecutive_character): Likewise.
+ (print_tree_identifier): Likewise.
+ (print_identifier): Likewise.
+ (NEXT_CODE): Uppercase macro parameter.
+ (ident_fndecl): Delete unused.
+ (GLOBAL_THING): Likewise.
+
+2002-01-06 Graham Stott <grahams@redhat.com>
+
+ * cp-tree.h (VAR_OR_FUNCTION_DECL_CHECK): Add parenthesis.
+ (VAR_FUNCTION_OR_PARM_DECL_CHECK): Likewise.
+ (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK) Likewise.
+ (RECORD_OR_UNION_TYPE_CHECK): Likewise.
+ (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): Likewise.
+ (C_IS_RESERVED_WORD): Uppercase macro parameter.
+ (C_RID_YYCODE) Likewise.
+ (ptrmem_cst): Use rtx.
+ (LOCAL_BINDING_P): Add whitespace.
+ (INHERITED_VALUE_BINDING_P): Likewise.
+ (BINDING_SCOPE): Wrap long line.
+ (BINDING_HAS_LEVEL_P): Remove parenthesis.
+ (BINDING_VALUE): Wrap long line.
+ (BINDING_TYPE): Whitespace.
+ (IDENTIFIER_GLOBAL_VALUE): Add parenthesis.
+ (SET_IDENTIFIER_GLOBAL_VALUE): Likewise.
+ (IDENTIFIER_NAMESPACE_VALUE): Likewise.
+ (SET_IDENTIFIER_NAMESPACE_VALUE: Likewise.
+ (same_type_p): Uppercase macro parameters.
+ (same_type_ignoring_top_level_qualifiers_p): Likewise.
+ (OVL_FUNCTION): Wrap long line.
+ (OVL_CHAIN): Whitespace.
+ (OVL_CURRENT): Add parenthesis and whitespace.
+ (OVL_NEXT): Whitespace.
+ (OVL_USED): Likewise.
+ (IDENTIFIER_TYPE_VALUE): Likewise.
+ (REAL_IDENTIFIER_TYPE_VALUE): Remove parenthesis.
+ (SET_IDENTIFIER_TYPE_VALUE): Add parenthesis and whitespace.
+ (LANG_ID_FIELD): Whitespace.
+ (SET_LANG_ID(NODE,VALUE,NAME): Likewise.
+ (IDENTIFIER_LABEL_VALUE): Whitespace and wrap.
+ (SET_IDENTIFIER_LABEL_VALUE): Whitespace.
+ (IDENTIFIER_IMPLICIT_DECL): Whitespace and wrap.
+ (SET_IDENTIFIER_IMPLICIT_DECL); Whitespace.
+ (IDENTIFIER_ERROR_LOCUS): Whitespace and wrap.
+ (SET_IDENTIFIER_ERROR_LOCUS); Whitespace.
+ (IDENTIFIER_VIRTUAL_P): Likewise.
+ (IDENTIFIER_OPNAME_P): Likewise.
+ (IDENTIFIER_TYPENAME_P): Remove parenthesis.
+ (C_TYPE_FIELDS_READONLY): Uppercase macro parameters.
+ (C_SET_EXP_ORIGINAL_CODE): Likewise.
+ (TYPE_ASSEMBLER_NAME_STRING): Wrap long line.
+ (TYPE_ASSEMBLER_NAME_LENGTH): Likewise.
+ (IS_AGGR_TYPE): Uppercase macro parameter.
+ (CLASS_TYPE_P): Likewise.
+ (IS_AGGR_TYPE_CODE): Uppercase macro parameter and parenthesis.
+ (IS_AGGR_TYPE_2): Whitespace.
+ (TAGGED_TYPE_P): Uppercase macro parameter.
+ (TYPE_BUILT_IN): Whitespace.
+ (TYPE_FOR_JAVA): Likewise.
+ (FUNCTION_ARG_CHAIN): Remove parenthesis.
+ (FUNCTION_FIRST_USER_PARMTYPE): Add parenthesis.
+ (FUNCTION_FIRST_USER_PARAM): Likewise.
+ (PROMOTES_TO_AGGR_TYPE): Whitespace.
+ (DERIVED_FROM_P): Add parenthesis and wrap.
+ (UNIQUELY_DERIVED_FROM_P): Likewise.
+ (ACCESSIBLY_UNIQUELY_DERIVED_P): Likewise.
+ (PUBLICLY_UNIQUELY_DERIVED_P): Likewise.
+ (CLASSTYPE_USE_TEMPLATE): Whitespace.
+ (CLASSTYPE_INLINE_FRIENDS): Remove parenthesis.
+ (TYPE_GETS_DELETE): Add parenthesis.
+ (TYPE_HAS_CONVERSION): Add parenthesis and wrap.
+ (TYPE_HAS_ASSIGN_REF): Likewise,
+ (TYPE_HAS_CONST_ASSIGN_REF): Likewise.
+ (TYPE_HAS_INIT_REF): Likewise.
+ (TYPE_HAS_CONST_INIT_REF): Likewise.
+ (TYPE_BEING_DEFINED): Likewise.
+ (TYPE_LANG_SPECIFIC): Likewise.
+ (CLASSTYPE_RTTI): Likewise.
+ (TYPE_OVERLOADS_CALL_EXPR): Likewise.
+ (TYPE_OVERLOADS_ARRAY_REF): Likewise.
+ (TYPE_OVERLOADS_ARROW): Likewise.
+ (TYPE_USES_MULTIPLE_INHERITANCE): Likewise.
+ (TYPE_USES_VIRTUAL_BASECLASSES): Add parenthesis.
+ (CLASSTYPE_METHOD_VEC): Likewise.
+ (CLASSTYPE_MARKED_N): Likewise.
+ (CLASSTYPE_MARKED): Likewise.
+ (CLASSTYPE_MARKED2): Likewise.
+ (CLASSTYPE_MARKED3): Likewise.
+ (CLASSTYPE_MARKED4): Likewise.
+ (CLASSTYPE_MARKED5): Likewise.
+ (CLASSTYPE_MARKED6): Likewise.
+ (SET_CLASSTYPE_MARKED): Whitespace.
+ (CLEAR_CLASSTYPE_MARKED): Likewise.
+ (SET_CLASSTYPE_MARKED2): Likewise.
+ (CLEAR_CLASSTYPE_MARKED2): Likewise.
+ (SET_CLASSTYPE_MARKED3): Likewise.
+ (CLEAR_CLASSTYPE_MARKED3): Likewise.
+ (SET_CLASSTYPE_MARKED4): Likewise.
+ (CLEAR_CLASSTYPE_MARKED4): Likewise.
+ (SET_CLASSTYPE_MARKED5): Likewise.
+ (CLEAR_CLASSTYPE_MARKED5): Likewise.
+ (SET_CLASSTYPE_MARKED6): Likewise.
+ (CLEAR_CLASSTYPE_MARKED6): Likewise.
+ (CLASSTYPE_TAGS): Likewise.
+ (CLASSTYPE_VSIZE): Likewise.
+ (CLASSTYPE_VBASECLASSES): Likewise.
+ (CANONICAL_BINFO): Add parenthesis.
+ (CLASSTYPE_SIZE(NODE): Likewise.
+ (CLASSTYPE_SIZE_UNIT): Likewise.
+ (CLASSTYPE_ALIGN(NODE): Likewise.
+ (CLASSTYPE_USER_ALIGN): Likewise.
+ (TYPE_JAVA_INTERFACE): Likewise.
+ (CLASSTYPE_PURE_VIRTUALS): Likewise.
+ (CLASSTYPE_NEEDS_VIRTUAL_REINIT): Whitespace and wrap.
+ (TYPE_HAS_DEFAULT_CONSTRUCTOR): Likewise.
+ (CLASSTYPE_HAS_MUTABLE): Likewise.
+ (CLASSTYPE_FRIEND_CLASSES): Likewise. Likewise.
+ (CLASSTYPE_DECLARED_CLASS): Whitespace and wrap.
+ (CLASSTYPE_READONLY_FIELDS_NEED_INIT): Likewise.
+ (CLASSTYPE_REF_FIELDS_NEED_INIT): Likewise.
+ (CLASSTYPE_INTERFACE_ONLY): Likewise.
+ (CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ (CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN_X): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ (CLASSTYPE_DEBUG_REQUESTED): Whitespace and wrap.
+ (BINFO_UNSHARED_MARKED): Whitespace.
+ (BINFO_MARKED): Whitespace and wrap.
+ (SET_BINFO_MARKED): Likewise.
+ (CLEAR_BINFO_MARKED): Likewise.
+ (BINFO_VTABLE_PATH_MARKED): Likewise.
+ (SET_BINFO_VTABLE_PATH_MARKED): Likewise.
+ (CLEAR_BINFO_VTABLE_PATH_MARKED): Likewise.
+ (BINFO_SUBVTT_INDEX): Remove parenthesis.
+ (BINFO_VPTR_INDEX): Likewise.
+ (BINFO_PRIMARY_BASE_OF): Likewise,
+ (CLASSTYPE_VFIELDS): Whitespace.
+ (VF_DERIVED_VALUE): Wrap long line.
+ (NAMESPACE_LEVEL): Whitespace.
+ (CAN_HAVE_FULL_LANG_DECL_P): Remove parenthesis.
+ (DEFARG_POINTER): Whitespace.
+ (DECL_NEEDED_P): Remove parenthesis.
+ (DECL_LANGUAGE): Whitespace.
+ (SET_DECL_LANGUAGE): Add parenthesis.
+ (DECL_CONSTRUCTOR_P): Whitespace and wrap.
+ (DECL_OVERLOADED_OPERATOR_P): Remove parenthesis.
+ (DECL_IN_AGGR_P): Whitespace.
+ (DECL_FRIEND_P): Likewise.
+ (DECL_BEFRIENDING_CLASSES): Likewise.
+ (DECL_STATIC_FUNCTION_P): Whitespace and wrap.
+ (DECL_NONCONVERTING_P): Whitespace.
+ (DECL_PURE_VIRTUAL_P): Likewise.
+ (DECL_NEEDS_FINAL_OVERRIDER_P): Likewise.
+ (DECL_PENDING_INLINE_INFO): Whitespace.
+ (DECL_SORTED_FIELDS): Likewise.
+ (DECL_DEFERRED_FN): Likewise.
+ (DECL_TEMPLATE_INFO): Likewise.
+ (CLASSTYPE_TEMPLATE_INFO): Whitespace and wrap.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO); Likewise.
+ (SET_TYPE_TEMPLATE_INFO): Add parenthesis.
+ (TMPL_ARGS_LEVEL): Likewise.
+ (SET_TMPL_ARGS_LEVEL): Likewise.
+ (INNERMOST_TEMPLATE_PARMS): Whitespace.
+ (C_TYPEDEF_EXPLICITLY_SIGNED): Uppercase macro parameter.
+ (INTEGRAL_CODE_P(CODE): Add parenthesis.
+ (CP_INTEGRAL_TYPE_P): Remove parenthesis.
+ (TYPE_HAS_CONSTRUCTOR): Whitespace.
+ (TREE_HAS_CONSTRUCTOR): Likewise.
+ (TYPE_HAS_DESTRUCTOR): Likewise.
+ (TYPE_HAS_REAL_ASSIGN_REF): Likewise.
+ (TYPE_HAS_COMPLEX_ASSIGN_REF): Likewise.
+ (TYPE_HAS_ABSTRACT_ASSIGN_REF): Likewise.
+ (TYPE_HAS_COMPLEX_INIT_REF): Likewise.
+ (TYPE_HAS_NONTRIVIAL_DESTRUCTOR): Likewise.
+ (TYPE_PTRMEMFUNC_P): Likewise.
+ (TYPE_PTRMEMFUNC_FLAG): Likewise.
+ (TYPE_GET_PTRMEMFUNC_TYPE): Likewise.
+ (TYPE_SET_PTRMEMFUNC_TYPE): Likewise.
+ (TYPE_PTRMEM_CLASS_TYPE): Remove parenthesis.
+ (TYPE_PTRMEM_POINTED_TO_TYPE): Likewise.
+ (DECL_ACCESS): Whitespace.
+ (DECL_GLOBAL_CTOR_P): Remove parenthesis.
+ (DECL_GLOBAL_DTOR_P): Likewise.
+ (GLOBAL_INIT_PRIORITY): Likewise.
+ (DECL_TEMPLATE_PARMS): Likewise.
+ (DECL_TEMPLATE_RESULT): Likewise.
+ (DECL_TEMPLATE_INSTANTIATIONS): Likewise.
+ (DECL_TEMPLATE_SPECIALIZATIONS): Likewise.
+ (DECL_IMPLICIT_TYPEDEF_P): Remove parenthesis.
+ (SET_DECL_IMPLICIT_TYPEDEF_P): Likewise.
+ (PRIMARY_TEMPLATE_P): Add parenthesis.
+ (DECL_USE_TEMPLATE): Whitespace.
+ (CLASSTYPE_IMPLICIT_INSTANTIATION): Likewise.
+ (SET_CLASSTYPE_IMPLICIT_INSTANTIATION): Likewise.
+ (CLASSTYPE_EXPLICIT_INSTANTIATION): Likewise.
+ (SET_CLASSTYPE_EXPLICIT_INSTANTIATION): Likewise.
+ (CALL_DECLARATOR_PARMS): Remove parenthesis.
+ (CALL_DECLARATOR_QUALS): Likewise.
+ (CALL_DECLARATOR_EXCEPTION_SPEC): Likewise.
+ (TEMP_NAME_P): Wrap.
+ (VFIELD_NAME_P): Likewise.
+ (B_SET): Uppercase macro parameters and add parenthesis.
+ (B_CLR): Likewise.
+ (B_TST): Likewise.
+ (LOOKUP_NAMESPACES_ONLY): Uppercase macro parameters.
+ (LOOKUP_TYPES_ONLY): Uppercase macro parameters.
+ (LOOKUP_QUALIFIERS_ONLY): Uppercase macro parameters.
+ (same_or_base_type_p): Likewise.
+ (cp_deprecated): Likewise.
+
+2002-01-05 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_body): Revert last change.
+
+2002-01-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/4122
+ * class.c (update_vtable_entry_for_fn): Set delta to zero for a
+ lost primary.
+
+ * class.c (build_vtbl_initializer): Check for a lost primary
+ before calculating the vtable entry to throw away.
+
+2002-01-02 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (expand_body): Call outlining_inline_function when
+ emitting an inline function out of line.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5116, c++/764 reversion
+ * call.c (build_new_op): Revert the instantiations. They are
+ incorrect.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5089
+ * decl2.c (reparse_absdcl_as_casts): Don't warn about casts to void.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3716
+ * pt.c (tsubst_aggr_type): Move pmf handling into tsubst.
+ (tsubst, case POINTER_TYPE): Handle pmfs here.
+ (tsubst, case OFFSET_TYPE): Check it is not an offset to
+ reference. If it is offset to FUNCTION_TYPE, create a METHOD_TYPE.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/35
+ * cp-tree.h (DECL_LANG_FLAG_0): Used for PARM_DECL too.
+ (DECL_TEMPLATE_PARM_P): A PARM_DECL might be one too.
+ * pt.c (process_template_parm): SET_DECL_TEMPLATE_PARM_P on the
+ PARM_DECL.
+ (tsubst_template_parms): Break up loop statements.
+ (tsubst_decl, case PARM_DECL): Copy DECL_TEMPLATE_PARM_P. Template
+ parm PARM_DECLs don't get promoted.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5123
+ * typeck.c (build_component_ref): Cope with a TEMPLATE_ID_EXPR.
+ (build_x_function_call): Cope with a COMPONENT_REF containing a
+ TEMPLATE_ID_EXPR.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5213
+ * pt.c (convert_template_argument): Be more careful determining
+ when RECORD_TYPE templates are or are not templates.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/775
+ * cp-tree.h (handle_class_head): Adjust prototype.
+ * decl2.c (handle_class_head): Add DEFN_P and NEW_TYPE_P
+ parameters. Use for all class heads.
+ * parse.y (named_class_head_sans_basetype, named_class_head,
+ named_complex_class_head_sans_basetype,
+ named_class_head_sans_basetype_defn,
+ unnamed_class_head): Remove.
+ (class_head, class_head_apparent_template): Recognize class heads
+ (class_head_decl, class_head_defn): New reductions. Process class
+ heads.
+ (structsp): Adjust class definition and class declaration
+ reductions.
+ (maybe_base_class_list): Give diagnostic on empty list.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4379
+ * typeck.c (build_x_unary_op): Don't destroy the OFFSET_REF on a
+ single non-static member.
+ (unary_complex_lvalue): If it cannot be a pointer to member, don't
+ make it so. Check it is not pointer to reference.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5132
+ * decl2.c (reparse_absdcl_as_casts): Don't digest_init if we
+ are processing a template decl.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5116, c++/764
+ * call.c (build_new_op): Make sure template class operands are
+ instantiated. Simplify arglist construction.
+
+
+
+Copyright (C) 2002 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2003 b/gcc-4.9/gcc/cp/ChangeLog-2003
new file mode 100644
index 000000000..6dfb50afb
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2003
@@ -0,0 +1,6912 @@
+2003-12-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13507
+ * decl.c (duplicate_decls): Use build_type_attribute_variant to
+ merge attributes.
+
+ PR c++/13494
+ * tree.c (build_cplus_array_type_1): Only build a minimal array
+ type for dependent types or domains.
+
+2003-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12774
+ * typeck.c (comp_array_types): Fold non-dependent domains for
+ ABI-1.
+
+2003-12-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13289
+ * semantics.c (finish_id_expression): Only check if the type of
+ a template argument is integral or enumeration when it is not
+ dependent.
+
+2003-12-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12403
+ * parser.c (cp_parser_template_declaration_after_export): Set up
+ template specialization scope in case of explicit specialization.
+
+2003-12-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13081
+ * decl.c (duplicate_decls): Preserve inline-ness when redeclaring
+ a function template.
+
+ PR c++/12613
+ * decl.c (reshape_init): Reject GNU colon-style designated
+ initializers in arrays.
+
+ PR c++/13009
+ * call.c (build_special_member_call): Do not assume that we have a
+ pointer to the complete object in an assignment operator.
+
+2003-12-28 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/13070
+ * decl.c (duplicate_decls): When setting the type of an anticipated
+ declaration, merge the existing type attributes.
+
+2003-12-25 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/13268, c++/13339
+ * class.c (add_method): Return early when method is error_mark_node.
+ * pt.c (tsubst_friend_function): Return early when new_friend is
+ error_mark_node.
+
+2003-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-lang.c (cp_expr_size): Return zero for empty classes.
+
+ * cp-tree.h (warn_if_uknown_interface): Remove unused function.
+ * decl2.c (warn_if_unknown_interface): Likewise.
+
+2003-12-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13387
+ * cp-lang.c (cxx_get_alias_set): Correct logic for a base type.
+
+2003-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_function): Do not check
+ flag_alt_external_templates or flag_external_templates.
+ * decl2.c (warn_if_unknown_interface): Likewise.
+ * lex.c (extract_interface_info): Likewise.
+ * pt.c (lookup_template_class): Likewise.
+
+ PR c++/12862
+ * name-lookup.c (pushdecl): Look up all namespace-scope entities
+ in their corresponding namespace.
+
+ PR c++/12397
+ * typeck.c (finish_class_member_access_expr): Don't tree
+ IDENTIFIER_NODEs as non-dependent expressions.
+
+2003-12-22 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/5050
+ * tree.c (cp_start_inlining): Remove.
+ (cp_end_inlining): Remove.
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING): Do not define.
+ (LANG_HOOKS_TREE_INLINING_END_INLINING): Do not define.
+ * cp-tree.h (cp_start_inlining): Do not declare.
+ (cp_end_inlining): Do not declare.
+
+2003-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12479
+ * parser.c (cp_parser_declaration_seq_opt): Only issue "extra ;"
+ pedwarn when not in a system header.
+
+2003-12-21 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Remove CPTI_RECORD_TYPE,
+ CPTI_UNION_TYPE, CPTI_ENUM_TYPE.
+ (record_type_node): Remove.
+ (union_type_node): Likewise.
+ (enum_type_node): Likewise.
+ * decl.c: Remove mention of above tree nodes in comment.
+ * lex.c (cxx_init): Do not assign to record_type_node,
+ union_type_node, or enum_type_node. Simplify handling of
+ class_type_node.
+
+ PR c++/11554
+ * init.c (sort_mem_initializers): Add warning.
+
+2003-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * cxx-pretty-print.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * error.c: Likewise.
+ * except.c: Likewise.
+ * init.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * semantics.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2003-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cvt.c: Remove uses of "register" specifier in
+ declarations of arguments and local variables.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * expr.c: Likewise.
+ * friend.c: Likewise.
+ * lex.c: Likewise.
+ * name-lookup.c: Likewise.
+ * repo.c: Likewise.
+ * search.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2003-12-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12795
+ * name-lookup.c (pushdecl): Do not treated any functions as being
+ "nested" in C++.
+
+2003-12-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/13371
+ * typeck.c (build_modify_expr): Stabilize lhs if we're narrowing.
+ * cvt.c (convert_to_void): Don't warn about the RHS of a comma
+ being useless if TREE_NO_UNUSED_WARNING is set.
+
+2003-12-18 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (struct lang_type_header): Remove __extension__.
+
+2003-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/12253
+ * init.c (build_vec_init): Initialization of an element from
+ an initializer list is also a full-expression.
+
+ * parser.c, pt.c, semantics.c: Rename constant_expression_p
+ to integral_constant_expression_p.
+
+2003-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13262
+ * pt.c (instantiate_decl): Wrap push_nested_class and
+ pop_nested_class around cp_finish_decl call for static member
+ variable.
+
+2003-12-18 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/9154
+ * parser.c (cp_parser_template_argument): A type-id followed by '>>'
+ is just an user typo, and should be accepted as last resort if any
+ other parsing fails.
+ (cp_parser_enclosed_template_argument_list): If the argument list is
+ parsed correctly, but the next token is '>>', emit a diagnostic.
+ (cp_parser_next_token_ends_template_argument): Accept '>>' as
+ delimiter of template argument, it will be later detected as a typo.
+
+2003-12-17 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in: Replace cp/g++.1 with $(docobjdir)/g++.1.
+
+2003-12-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10603
+ PR c++/12827
+ * parser.c (cp_parser_error): Help c_parse_error print good
+ messages if the next token is a keyword.
+ (cp_parser_parameter_declaration_list): When resynchronizing after
+ a bad parameter declaration, stop if a comma is found.
+ (cp_parser_parameter_declaration): Avoid backtracking.
+
+2003-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12696
+ * decl.c (reshape_init): Recover quickly from errors.
+
+2003-12-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9043
+ C++ ABI change: Mangling array indices in templates.
+ * decl.c (compute_array_index_type): Reorganize for earlier
+ template errors. Use value_dependent_expression_p for abi-2.
+ * mangle.c (write_array_type): Check broken mangling for
+ expression indices on abi-1
+
+2003-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12696
+ * decl.c (reshape_init): Recover quickly from errors.
+
+ PR c++/13275
+ * lex.c (reswords): Add "__offsetof" and "__offsetof__".
+ * parser.c (cp_parser): Add in_offsetof_p.
+ (cp_parser_new): Initialize it.
+ (cp_parser_primary_expression): Handle __offsetof__ (...).
+ (cp_parser_postfix_expression): Allow casts to pointer type and
+ uses of "->" in a constant expression if implementing offsetof.
+ (cp_parser_unary_expression): Allow the use of "&" in a constant
+ expression if implementing offsetof.
+
+2003-12-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): always construct an OVERLOAD
+ if the declaration comes from an using declaration.
+
+2003-12-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * semantics.c (finish_id_expression): Refactor the code to handle
+ template parameters, and emit a more informative error message
+ when they are used within an integral constant expression.
+
+2003-12-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13387
+ * class.c (finish_struct_1): Compute mode and alias set for
+ CLASSTYPE_AS_BASE.
+ * call.c (build_over_call): Use CLASSTYPE_AS_BASE for trivial
+ assignment of a class, as necessary.
+ * cp-lang.c (cxx_get_alias_set): The alias set as a base is the
+ same as for the complete type.
+
+ PR c++/13242
+ C++ ABI change. Mangling template parameters of reference type
+ * mangle.c (write_template_args): Remove unreachable code.
+ (write_template_arg): Look through an argument of reference type.
+
+2003-12-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): always construct an OVERLOAD
+ if the declaration comes from an using declaration.
+
+2003-12-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10926
+ * decl2.c (grokfield): Robustify.
+
+ PR c++/11116
+ * parser.c (cp_parser_throw_expression): Determine whether or not
+ an assignment-expression is present by doing one-token lookahead.
+
+ PR c++/13269
+ * parser.c (cp_parser_function_definition_after_declarator): Stop
+ scanning tokens when reaching EOF.
+
+ PR c++/12989
+ * typeck.c (cxx_sizeof_or_alignof_expr): Robustify.
+
+ PR c++/13310
+ * pt.c (dependent_template_p): Handle OVERLOADs.
+
+2003-12-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13243
+ PR c++/12573
+ * parser.c (cp_parser_postfix_expression): Tighten handling of
+ integral constant expressions.
+ (cp_parser_unary_expression): Likewise.
+ * pt.c (value_dependent_expression_p): Remove handling for
+ COMPONENT_REFs.
+
+2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (add_method): Disallow destructor for java classes.
+ * decl.c (xref_basetypes): Check java class inheritance.
+ * decl2.c (check_java_method): Skip artificial params.
+
+ PR c++/13241
+ C++ ABI change. Mangling of symbols in expressions.
+ * mangle.c (write_mangled_name): Add top_level flag. Rework for
+ nested and unnested mangling. Deal with abi version 1 and version
+ 2 differences.
+ (write_expression): Adjust write_mangled_name call.
+ (mangle_decl_string): Use write_mangled_name for all non-type decls.
+
+2003-12-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10779
+ PR c++/12160
+ * parser.c (struct cp_parser): Add in_template_argument_list_p.
+ (cp_parser_error): Use c_parse_error.
+ (cp_parser_name_lookup_error): New function.
+ (cp_parser_new): Initialize it.
+ (cp_parser_declarator): Add parenthesized_p parameter.
+ (cp_parser_nested_name_specifier_opt): Use
+ cp_parser_name_lookup_error.
+ (cp_parser_parenthesized_expression_list): Improve comments.
+ (cp_parser_condition): Adjust call to cp_parser_declarator.
+ (cp_parser_template_parameter): Adjust call to
+ cp_parser_parameter_declaration.
+ (cp_parser_template_argument_list): Set
+ in_template_argument_list_p.
+ (cp_parser_explicit_instantiation): Adjust call to
+ cp_parser_declarator.
+ (cp_parser_simple_type_specifier): Remove unncessary code.
+ (cp_parser_using_declaration): Use cp_parser_name_lookup_error.
+ (cp_parser_init_declarator): Handle member function definitions.
+ (cp_parser_direct_declarator): Adjust call to
+ cp_parser_declarator.
+ (cp_parser_type_id): Adjust call to cp_parser_declarator.
+ (cp_parser_parameter_declaration_list): Avoid backtracking where
+ possible.
+ (cp_parser_parameter_declaration): Add parenthesized_p parameter.
+ (cp_parser_function_definition): Remove.
+ (cp_parser_member_declaration): Do not backtrack to look for
+ function definitions.
+ (cp_parser_exception_declaration): Adjust call to
+ cp_parser_declarator.
+ (cp_parser_single_declaration): Handle function definitions via
+ cp_parser_init_declarator.
+ (cp_parser_save_member_function_body): New function.
+
+2003-12-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13106
+ * decl.c (finish_function): Check if return type is dependent before
+ issuing no return statement warning.
+
+2003-12-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13118
+ * cp-tree.h (lang_decl_u): Add thunk_alias member.
+ (THUNK_VIRTUAL_OFFSET): Must be a FUNCTION_DECL.
+ (THUNK_ALIAS_P): Remove.
+ (THUNK_ALIAS): Adjust.
+ * class.c (update_vtable_entry_for_fn): Get the vbase within the
+ overriding function's return type.
+ (dump_thunk): Adjust THUNK_ALIAS printing.
+ (build_vtbl_initializer): Adjust THUNK_ALIAS use.
+ * method.c (make_thunk): Revert 12881 test change. Clear
+ THUNK_ALIAS.
+ (finish_thunk): Adjust THUNK_ALIAS setting.
+ (use_thunk): Adjust THUNK_ALIAS use.
+ * semantics.c (emit_associated_thunks): Likewise.
+
+ PR c++/13114, c++/13115
+ * class.c (layout_empty_base): Propagate the move of an empty base
+ to offset zero.
+
+ PR c++/12881
+ * method.c (make_thunk): Deal with thunk aliases when searching
+ for a thunk. Robustify assertion.
+
+2003-12-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * mangle.c (conv_type_names): Holds IDENTIFIER_NODEs only.
+ (hash_type): Use TYPE_UID of the identifier's type.
+ (compare_type): Adjust.
+ (mangle_conv_op_name_for_type): Store identifier nodes only, use
+ TYPE_UID has hash value.
+
+2003-12-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_CONV_FN_P): Check that DECL_NAME is non-NULL.
+
+2003-12-08 Matt Austern <austern@apple.com>
+
+ PR c/13134
+ * decl.c (duplicate_decls): Copy visibility flag when appropriate.
+
+2003-12-09 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * init.c (build_new_1): Deal with an OVERLOAD set when
+ looking up for _Jv_AllocObject.
+ * except.c (build_throw): Likewise for _Jv_Throw.
+
+2003-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/11971
+ * tree.c (build_local_temp): Split out from build_cplus_new.
+ (force_target_expr): New fn.
+ * call.c (call_builtin_trap): Call it. Take a type parm.
+ (convert_arg_to_ellipsis): Pass it.
+ (build_x_va_arg): Use call_builtin_trap.
+
+ PR c++/11929
+ * call.c (magic_varargs_p): New fn.
+ (build_over_call): Do no ellipsis conversions for arguments to
+ functions with magic varargs.
+
+ * name-lookup.c, init.c, except.c: Revert Giovanni's patch from
+ yesterday.
+
+ Give the anonymous namespace a null DECL_NAME.
+ * cp-tree.h: Don't declare anonymous_namespace_name.
+ * decl.c: Don't define it.
+ * dump.c (cp_dump_tree): Don't check for it.
+ * cxx-pretty-print.c (pp_cxx_original_namespace_definition): Likewise.
+ * error.c (dump_decl): Likewise.
+ * name-lookup.c: Define it here.
+ (push_namespace): Put it in DECL_ASSEMBLER_NAME instead.
+ * mangle.c (write_unqualified_name): Adjust.
+
+2003-12-07 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): Always construct an
+ OVERLOAD unless the declaration is a built-in.
+ (set_namespace_binding): While binding OVERLOADs with only one
+ declaration, we still need to call supplement_binding.
+ * init.c (build_new_1): Deal with an OVERLOAD set when
+ looking up for _Jv_AllocObject.
+ * except.c (build_throw): Likewise for _Jv_Throw.
+
+2003-12-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13323
+ * class.c (same_signature_p): Handle conversion operators
+ correctly.
+ (check_for_override): Likewise.
+
+2003-12-06 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in (GXX_CROSS_NAME, CXX_CROSS_NAME): Delete.
+ (c++.install_common, cp/g++.1, c++.install-man): Adjust for above.
+ (c++.uninstall): Likewise.
+
+2003-12-05 Danny Smith <dannysmith@gcc.gnu.org>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13305
+ * parser.c (cp_parser_elaborated_type_specifier): Accept
+ attributes.
+
+2003-12-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13314
+ * parser.c (cp_parser_class_specifier): Match push_scope/pop_scope
+ calls.
+ (cp_parser_class_head): Likewise.
+
+2003-12-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13166
+ * parser.c (cp_parser_late_parsing_default_args): Make sure the
+ context is a class before calling push_nested_class and
+ pop_nested_class.
+
+2003-12-03 James E Wilson <wilson@specifixinc.com>
+
+ * g++spec.c (lang_specific_driver): Delete USE_LIBUNWIND_EXCEPTIONS
+ support.
+
+2003-12-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9127
+ * cp-tree.h (at_namespace_scope_p): New function.
+ * parser.c (cp_parser_class_head): Handle invalid explicit
+ specializations.
+ * search.c (at_namespace_scope_p): New function.
+
+ PR c++/13179
+ * semantics.c (finish_handler_parms): Do not call eh_type_info for
+ types used in templates.
+
+ PR c++/10771
+ * parser.c (cp_parser_check_for_invalid_template_id): New
+ function.
+ (cp_parser_simple_type_specifier): Use it.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_class_head): Likewise.
+
+2003-12-02 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/10126
+ * pt.c (convert_nontype_argument): Handle default conversions
+ while converting a pointer to member function.
+
+2003-12-02 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/12573
+ * pt.c (value_dependent_expression_p): Handle COMPONENT_REFs by
+ looking into them recursively.
+
+2003-12-02 Richard Henderson <rth@redhat.com>
+
+ * name-lookup.h (struct cp_binding_level): Use ENUM_BITFIELD.
+ * parser.c (struct cp_token): Likewise.
+ (struct cp_parser_token_tree_map_node): Likewise.
+ * lex.c (struct resword): Move const after ENUM_BITFIELD.
+
+2003-11-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9849
+ * parser.c (cp_lexer_prev_token): New function.
+ (cp_parser_skip_to_closing_parenthesis): Add consume_paren
+ parameter.
+ (cp_parser_nested_name_specifier_opt): Add is_declaration
+ parameter.
+ (cp_parser_nested_name_specifier): Likewise.
+ (cp_parser_class_or_namespace_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_template_id): Likewise.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_id_expression): Adjust calls to
+ cp_parser_nested_name_specifier_op, cp_parser_template_id,
+ cp_parser_class_name.
+ (cp_parser_unqualified_id): Likewise.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_pseudo_destructor_name): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_mem_initializer_id): Likewise.
+ (cp_parser_simple_type_specifier): Likewise.
+ (cp_parser_type_name): Likewise.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_qualified_namespace_specifier): Likewise.
+ (cp_parser_using_declaration): Likewise.
+ (cp_parser_using_directive): Likewise.
+ (cp_parser_ptr_operator): Likewise.
+ (cp_parser_declarator_id): Likewise.
+ (cp_parser_class_head): Likewise.
+ (cp_parser_base_specifier): Likewise.
+ (cp_parser_constructor_declarator_p): Likewise.
+ (cp_parser_direct_declarator): Fix typo in comment.
+ (cp_parser_parenthesized_expression_list): Adjust call to
+ cp_parser_skip_to_closing_parenthesis.
+ (cp_parser_selection_statement): Likewise.
+
+2003-11-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12924
+ * typeck.c (finish_class_member_access_expr): Handle TEMPLATE_ID_EXPR
+ with OVERLOAD and DECL nodes as the first operand.
+
+2003-11-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (tsubst) <ARRAY_REF>: Remove erroneous argument to build_nt.
+
+2003-11-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5369
+ * friend.c (is_friend): Handle member function of a class
+ template as template friend.
+ (do_friend): Likewise.
+ * decl2.c (check_classfn): Add template_header_p parameter.
+ * decl.c (start_decl): Adjust check_classfn call.
+ (grokfndecl): Likewise.
+ * pt.c (is_specialization_of_friend): New function.
+ (uses_template_parms_level): Likewise.
+ (push_template_decl_real): Use uses_template_parms_level.
+ (tsubst_friend_function): Adjust check_classfn call.
+ * cp-tree.h (check_classfn): Adjust declaration.
+ (uses_template_parms_level): Add declaration.
+ (is_specialization_of_friend): Likewise.
+
+2003-11-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12515
+ * pt.c (build_non_dependent_expr): Handle GNU extension to ?:
+ operator.
+
+2003-11-21 Jan Hubicka <jh@suse.cz>
+
+ * parser.c (cp_parser_postfix_expression): Initialize 's' to
+ NULL_TREE.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Make-lang.in (c++.extraclean): Delete.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Make-lang.in (check-g++, lang_checks): Add.
+
+2003-11-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12932
+ * class.c (currently_open_derived_class): Check if
+ current_class_type is NULL_TREE.
+ * semantics.c (finish_call_expr): Check if
+ currently_open_derived_class returns NULL_TREE.
+ * cp-tree.h (DERIVED_FROM_P): Add parenthesis around PARENT
+ parameter.
+
+2003-11-17 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Preevaluate placement args.
+ * call.c (build_op_delete_call): Don't expose placement args to
+ overload resolution.
+
+2003-11-16 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (c++.tags): Create TAGS.sub files in each directory
+ and TAGS files that include them for each front end.
+
+2003-11-15 Bernardo Innocenti <bernie@develer.com>
+
+ PR c++/2294
+ * name-lookup.c: Revert previous patch for PR c++/2294 to prevent
+ build failure on libjava.
+
+2003-11-14 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): Always construct an OVERLOAD
+ unless the declaration is a built-in.
+ (set_namespace_binding): While binding OVERLOADs with only one
+ declaration, we still need to call supplement_binding.
+
+2003-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12762
+ * parser.c (cp_parser_enclosed_template_argument_list): New
+ function.
+ (cp_parser_template_id): Use it.
+ (cp_parser_simple_type_specifier): Recognize invalid template
+ syntax.
+
+2003-11-14 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/2094
+ * pt.c (unify): Add support for PTRMEM_CST and
+ FIELD_DECL unification.
+
+2003-11-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * decl.c (grokfndecl): Change OK to type tree.
+
+2003-11-12 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (build_target_expr_with_type): Treate VA_ARG_EXPR like
+ CONSTRUCTOR.
+
+ * decl.c (cp_make_fname_decl): When creating a top-level
+ __FUNCTION__-like symbol, do register it with pushdecl.
+
+ * decl.c (finish_case_label): Do not check that we are within a
+ switch statement here.
+ * parser.c (struct cp_parser): Add in_iteration_statement_p and
+ in_switch_statement_p.
+ (cp_parser_new): Initialize them.
+ (cp_parser_labeled_statement): Check validity of case labels
+ here.
+ (cp_parser_selection_statement): Set in_switch_statement_p.
+ (cp_parser_iteration_statement): Set in_iteration_statement_p.
+ (cp_parser_jump_statement): Check validity of break/continue
+ statements here.
+
+ PR c++/12735
+ * cp-tree.h (duplicate_decls): Return a tree.
+ * decl.c (duplicate_decls): Clarify documentation. Return
+ error_mark_node to indicate a failed redeclaration.
+ * friend.c (do_friend): Handle that case.
+ * name-lookup.c (pushdecl): Likewise.
+
+2003-11-11 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_NAMESPACE_ASSOCIATIONS): New macro.
+ * name-lookup.c (parse_using_directive): New fn.
+ (is_associated_namespace): New fn.
+ (arg_assoc_namespace): Also check associated namespaces.
+ * name-lookup.h: Declare new fns.
+ * pt.c (maybe_process_partial_specialization): Allow
+ specialization in associated namespace.
+ * parser.c (cp_parser_using_directive): Accept attributes. Use
+ parse_using_directive.
+
+2003-11-10 Richard Henderson <rth@redhat.com>
+
+ * cvt.c (convert_to_void): Use void_zero_node after overload failure.
+
+2003-11-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/12832
+ * name-lookup.c (supplement_binding): Gracefully handle names
+ used at non-class scope prior declaration.
+
+2003-11-06 Matt Austern <austern@apple.com>
+
+ * decl.c (duplicate_decls): copy DECL_VISIBILITY field.
+ * method.c (use_thunk): give thunk same visibility as function.
+ * optimize.c (maybe_clone_body): copy DECL_VISIBILITY field.
+
+2003-11-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11616
+ * pt.c (instantiate_pending_templates): Save and restore
+ input_location.
+
+2003-11-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/2019
+ * friend.c (add_friend): Don't display previous declaration in
+ case of duplicate friend warning.
+
+2003-11-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9810
+ * call.c (build_over_call): Check access using primary template
+ if FN is a member function template.
+
+2003-11-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12796
+ * class.c (handle_using_decl): Set input_location before calling
+ error_not_base_type.
+
+2003-10-26 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10371
+ * semantics.c (finish_non_static_data_member): Handle when
+ both processing_template_decl and qualifying_scope are true.
+
+2003-10-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11076
+ * class.c (handle_using_decl): Swap arguments of error_not_base_type.
+ * parser.c (cp_parser_direct_declarator): Only resolve typename for
+ namespace scope declarations.
+
+2003-10-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12698, c++/12699, c++/12700, c++/12566
+ * cp-tree.h (THUNK_ALIAS_P, THUNK_ALIAS): New.
+ (debug_class, debug_thunks): New.
+ * class.c (dump_class_hierarchy_1): New break out from ...
+ (dump_class_hierarchy): ... here.
+ (dump_thunk, debug_thunks, debug_class): New.
+ (update_vtable_entry_for_fn): Add ssizetype casts. Correct
+ continued search for primary binfo via virtual.
+ (build_vtbl_initializer): Follow covariant thunk alias.
+ * method.c (make_thunk): Clear DECL_THUNKS of the thunk.
+ (finish_thunk): Look for an alias of the covariant thunk and point
+ to it.
+ (use_thunk): We should never use an alias.
+ * semantics.c (emit_associated_thunks): Do not emit aliases.
+
+ PR c++/12566
+ * cp-tree.h (cp_fname_init): Add TYPE pointer param.
+ * decl.c (cp_fname_init): Add TYPE pointer param. Set it. Don't
+ create an ad-hoc ERROR_MARK.
+ (cp_make_fname_decl): Adjust.
+ * pt.c (tsubst_expr): Adjust.
+
+2003-10-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/12726
+ * tree.c (build_target_expr_with_type): Don't call force_rvalue
+ for CONSTRUCTORs.
+
+2003-10-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cxx-pretty-print.c: Likewise.
+ * init.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2003-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11962
+ * typeck.c (build_x_conditional_expr): Handle missing middle
+ operands in templates.
+ * mangle.c (write_expression): Issue errors about attempts to
+ mangle a non-existant middle operator to the ?: operator.
+
+2003-10-21 Robert Bowdidge <bowdidge@apple.com>
+
+ * decl.c (cp_finish_decl): Remove clause intended for asm directives
+ in struct or class fields: this code is never executed.
+
+2003-10-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl.c (start_decl): Exit if push_template_decl returns
+ error_mark_node.
+
+2003-10-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Fix typos.
+ * call.c: Fix comment typos.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * cxx-pretty-print.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * init.c: Likewise.
+ * mangle.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2003-10-20 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (start_cleanup_fn): Set DECL_DECLARED_INLINE_P to deffer
+ the expansion.
+
+2003-10-20 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (c++.install-info): Remove.
+
+2003-10-20 Jason Merrill <jason@redhat.com>
+
+ * class.c (layout_class_type): Set DECL_ARTIFICIAL on padding
+ field.
+
+2003-10-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9781, c++/10583, c++/11862
+ * decl.c (cp_finish_decl): Exit immediately if decl is an
+ error_mark_node.
+ * pt.c (push_template_decl_real): Return error_mark_node for
+ invalid template declaration of variable.
+
+2003-10-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12495
+ * pt.c (lookup_template_class): Handle when current_class_type
+ is a local class.
+
+2003-10-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/2513
+ * decl.c (make_typename_type): Use dependent_type_p.
+ (make_unbound_class_template): Likewise.
+ * pt.c (instantiate_class_template): Increment
+ processing_template_decl during substitution of template friend
+ function. Preincrement processing_template_decl rather than
+ postincrement.
+ (get_mostly_instantiated_function_type): Increment
+ processing_template_decl during partial substitution of function
+ type.
+
+2003-10-15 Jan Hubicka <jh@suse.cz>
+
+ PR c++/12574
+ * decl2.c (cxx_callgraph_analyze_expr): Deal with baselink.
+
+2003-10-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/11878
+ * tree.c (build_target_expr_with_type): Call force_rvalue for
+ classes with non-trivial copy ctors.
+
+ PR c++/11063
+ * typeck.c (build_modify_expr): Call convert rather than abort.
+
+2003-10-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Breack out decl.c (3/n)
+ * name-lookup.c: Include flags.h
+ (lookup_name_current_level): Make static.
+ (add_decl_to_level): Likewise.
+ (push_local_binding): Likewise.
+ (push_overloaded_decl): Likewise.
+ (lookup_using_namespace): Likewise.
+ (qualified_lookup_using_namespace): Likewise.
+ (lookup_type_current_level): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (namespace_ancestor): Likewise.
+ (push_using_directive): Likewise.
+ * decl.c (pushdecl): Move to name-lookup.c.
+ (pushdecl_top_level_1): Likewise.
+ (pushdecl_top_level): Likewise.
+ (pushdecl_top_level_and_finish): Likewise.
+ (maybe_push_decl): Likewise.
+ (push_using_decl): Likewise.
+ (push_overloaded_decl): Likewise.
+ (make_anon_name): Likewise.
+ (anon_cnt): Likewise.
+ (clear_anon_tags): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (check_for_out_of_scope_variable): Likewise.
+ * Make-lang.in (cp/name-lookup.o): Depend on flags.h.
+ * decl.c (warn_extern_redeclared_static): Export.
+ * cp-tree.h (warn_extern_redeclared_static): Declare.
+
+2003-10-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Make-lang.in: Replace uses of $(target_alias) with
+ $(target_noncanonical).
+
+2003-10-13 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * ChangeLog: Add PR number to patch for PR c++/12370.
+
+2003-10-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.h (cxx_scope_find_binding_for_name): Don't export.
+ (binding_for_name): Likewise.
+ (cxx_binding_clear): Move to name-lookup.c.
+ * name-lookup.c (cxx_scope_find_binding_for_name): Now static.
+ (binding_for_name): Likewise.
+ * decl2.c (is_ancestor): Move to name-lookup.c
+ (namespace_ancestor): Likewise.
+ (add_using_namespace): Likewise.
+ (ambiguous_decl): Likewise.
+ (lookup_using_namespace): Likewise.
+ (qualified_lookup_using_namespace): Likewise.
+ (set_decl_namespace): Likewise.
+ (decl_namespace): Likewise.
+ (current_decl_namespace): Likewise.
+ (push_decl_namespace): Likewise.
+ (pop_decl_namespace): Likewise.
+ (push_scope): Likewise.
+ (pop_scope): Likewise.
+ (struct arg_lookup): Likewise.
+ (arg_assoc): Likewise.
+ (arg_assoc_args): Likewise.
+ (arg_assoc_type): Likewise.
+ (add_function): Likewise.
+ (arg_assoc_namespace): Likewise.
+ (arg_assoc_class): Likewise.
+ (arg_assoc_template_arg): Likewise.
+ (do_namespace_alias): Likewise.
+ (validate_nonmember_using_decl): Likewise.
+ (do_nonmember_using_decl): Likewise.
+ (do_toplevel_using_decl): Likewise.
+ (do_local_using_decl): Likewise.
+ (do_class_using_decl): Likewise.
+ (do_using_directive): Likewise.
+ (constructor_name_full): Likewise.
+ (constructor_name): Likewise.
+ (constructor_name_p): Likewise.
+
+2003-10-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Break out decl.c (2/n)
+ * name-lookup.c: Include diagnostic.h
+ (cxx_binding_free): Make static.
+ (cxx_binding_make): Likewise.
+ (binding_table_new): Likewise
+ (binding_table_free): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ (supplement_binding): Likewise.
+ * name-lookup.h (global_scope_name): Declare extern.
+ (global_type_node): Likewise.
+ (cxx_binding_free): Don't export.
+ (cxx_binding_make): Likewise.
+ (binding_table_new): Likewise.
+ (binding_table_free): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ * Make-lang.in (cp/name-lookup.o): Depend on $(DIAGNOSTIC_H)
+ * decl.c (lookup_namespace_name): Move to name-lookup.c
+ (select_decl): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_qualified_name): Likewise.
+ (lookup_name_real): Likewise.
+ (lookup_name_nonclass): Likewise.
+ (lookup_function_nonclass): Likewise.
+ (lookup_name): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (lookup_flags): Likewise.
+ (qualify_lookup): Likewise.
+ (lookup_tag): Likewise.
+ (lookup_tag_reverse): Likewise.
+ (getdecls): Likewise.
+ (storedecls): Remove.
+ (cxx_remember_type_decls): Move to name-lookup.c.
+ (global_bindings_p): Likewise.
+ (innermost_nonclass_level): Likewise.
+ (toplevel_bindings_p): Likewise.
+ (namespace_bindings_p): Likewise.
+ (kept_level_p): Likewise.
+ (innermost_scope_kind): Likewise.
+ (template_parm_scope_p): Likewise.
+ (push_binding): Likewise.
+ (push_local_binding): Likewise.
+ (add_decl_to_level): Likewise. Make extern.
+ (push_class_binding): Move to name-lookup.c.
+ (resume_level): Likewise. Rename to resume_scope.
+ (begin_scope): Move to name-lookup.c.
+ (indent): Likewise.
+ (binding_depth): Likewise.
+ (is_class_level): Likewise.
+ (cxx_scope_descriptor): Likewise.
+ (cxx_scope_debug): Likewise.
+ (namespace_scope_ht_size): Likewise.
+ (leave_scope): Likewise.
+ (pushlevel_class): Likewise.
+ (poplevel_class): Likewise.
+ (clear_identifier_class_values): Likewise.
+ (pushdecl_with_scope): Likewise.
+ (pushdecl_namespace_level): Likewise.
+ (pushdecl_class_level): Likewise.
+ (push_class_level_binding): Likewise.
+ (push_using_directive): Likewise.
+ (identifier_global_value): Likewise.
+ (keep_next_level_flag): Likewise.
+ (keep_next_level): Likewise.
+ (free_binding_level): Likewise.
+ (set_class_shadows): Likewise.
+ (maybe_push_cleanup_level): Likewise.
+ (cp_namespace_decls): Likewise.
+ (bt_print_entry): Likewise.
+ (print_binding_level): Likewise.
+ (print_other_binding_stack): Likewise.
+ (print_binding_stack): Likewise.
+ (push_namespace): Likewise.
+ (pop_namespace): Likewise.
+ (push_nested_namespace): Likewise.
+ (pop_nested_namespace): Likewise.
+ (cxx_saved_binding_make): Likewise.
+ (struct cxx_saved_binding_make): Likewise.
+ (store_bindings): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (push_to_top_level): Likewise.
+ (pop_from_top_level): Likewise.
+ (identifier_type_value): Likewise.
+ (set_identifier_type_value): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ (pop_everything): Likewise.
+ (pushtag): Likewise.
+ (follow_tag_typedef): Likewise.
+ (maybe_process_template_type_declaration): Likewise.
+ (pop_binding): Likewise.
+ * cp-tree.h: Move corresponding declarations to name-lookup.h
+
+2003-10-12 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cvt.c (ocp_convert): Move warning to C common code.
+
+2003-10-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/6392
+ * tree.c (build_cplus_array_type): Handle all quals the same.
+ (cp_build_qualified_type_real): Look through arrays first.
+
+ * tree.c (build_cplus_new): Use build_decl to create a VAR_DECL.
+ (build_target_expr_with_type): Likewise.
+
+ * pt.c (instantiate_class_template): Sanity check that our
+ enclosing class has been instantiated.
+
+2003-10-08 Giovanni Bajo <giovannibajo@libero.it>
+
+ * cp_tree.h: Added TFF_NO_FUNCTION_ARGUMENTS.
+ * error.c (dump_function_decl): Use it to skip the dump of the
+ arguments.
+ (dump_expr): When dumping a declaration found within an
+ expression, always set TFF_NO_FUNCTION_ARGUMENTS
+ in the flags.
+
+2003-10-08 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/11097
+ * pt.c (tsubst_decl): Substitute also the DECL_NAME node of
+ USING_DECL.
+
+2003-10-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10147
+ * call.c (initialize_reference): Tweak error message.
+ * cxx-pretty-print.h (cxx_pretty_printer_flags): Remove
+ pp_cxx_flag_qualified_id and pp_cxx_flag_global_scope.
+ * cxx-pretty-print.c (pp_cxx_id_expression): Always display
+ qualified entities using qualified names.
+
+ PR c++/12337
+ * init.c (build_new_1): Make sure that the expression returned is
+ not an lvalue.
+
+ PR c++/12344, c++/12236, c++/8656
+ * decl.c (start_function): Do not ignore attributes embedded in a
+ function declarator.
+
+2003-10-06 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (c++.info): Remove.
+ (c++.dvi): Remove.
+ (c++.generated-manpages): Replace with ...
+ (generated-manpages): ... this.
+
+2003-10-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (struct cp_binding_level): Move to name-lookup.h
+ (current_binding_level): Likewise.
+ (class_binding_level): Likewise.
+ * cp-tree.h (enum scope_kind): Likewise.
+
+2003-10-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.c (binding_entry_free): Nullify name and type
+ fields.
+
+2003-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12486
+ * typeck.c (finish_class_member_access_expr): Issue diagnostic
+ on erroneous use of qualified name.
+
+2003-09-30 Richard Henderson <rth@redhat.com>
+
+ PR c++/12370
+ * decl.c (duplicate_decls): Copy DECL_SAVED_INSNS too.
+
+2003-09-30 Kelley Cook <kelleycoook@wideopenwest.com>
+
+ * g++spec.c: Convert to ISO C90 prototypes.
+ * parser.c: Likewise.
+
+2003-09-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (pop_binding): Don't mess with nullifying binding->scope
+ here.
+ * name-lookup.c: Re-format.
+ (cxx_binding_free): Nullify binding->scope.
+
+2003-09-29 Jan Hubicka <jh@suse.cz>
+
+ PR C++/12047
+ * except.c (build_eh_type_type): Call mark_used on the type.
+
+2003-09-28 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (c_expand_asm_operands): Take location_t, instead of
+ individual file and line.
+
+2003-09-28 Andreas Jaeger <aj@suse.de>
+
+ * decl.c (cxx_builtin_type_decls): Convert to ISO C90 function
+ definition.
+ * init.c (push_base_cleanups): Likewise.
+ * decl2.c (finish_file): Likewise.
+ * mangle.c (init_mangle): Likewise.
+ (dump_substitution_candidates): Likewise.
+ * search.c: Likewise.
+
+2003-09-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.h (get_global_value_if_present): New function.
+ (is_typename_at_global_scope): Likewise.
+ * except.c (do_begin_catch): Use get_global_value_if_present.
+ (do_end_catch): Likewise.
+ (do_allocate_exception): Likewise.
+ (do_free_exception): Likewise.
+ (build_throw): Likewise.
+ * parser.c (cp_parser_member_declaration): Likewise.
+ * rtti.c (throw_bad_cast): Likewise.
+ (throw_bad_typeid): Likewise.
+ * decl.c (check_tag_decl): Use is_typename_at_global_scope.
+ (grokdeclarator): Likewise.
+ * cp-tree.h (global_namespace): Move to name-lookup.h
+ * call.c (call_builtin_trap): Tidy.
+
+2003-09-27 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11415
+ * parser.c (cp_parser_nested_name_specifier_opt): Issue correct
+ error message when parser->scope is global_namespace.
+
+2003-09-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h, name-lookup.h, decl.c, decl2.c: Remove reference to
+ macros BINDING_SCOPE, BINDING_VALUE and BINDING_TYPE.
+
+2003-09-26 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (pop_binding_level, suspend_binding_level,
+ find_class_binding_level): Merge into leave_scope. Remove.
+ (leave_scope): New function.
+ (poplevel): Update.
+ (poplevel_class): Likewise.
+ (pop_namespace): Likewise.
+
+2003-09-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5655
+ * parser.c (cp_parser_check_access_in_redeclaration): New function.
+ (cp_parser_member_declaration): Use it.
+ (cp_parser_template_declaration_after_export): Likewise.
+
+2003-09-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (scope_kind): Add new enumerator.
+ (keep_next_level): Change parameter type to bool.
+ (begin_scope): Change prototype.
+ (pushlevel): Remove declaration.
+ * decl.c (push_binding_level): Fold in begin_scope. Remove.
+ (struct cp_binding_level): Remove tag_tranparent field. Make keep
+ of bitsize one.
+ (keep_next_level_flag): Make a bool.
+ (cxx_scope_descriptor): Update scope names table
+ (make_cxx_scope): Fold in begin_scope. Remove..
+ (namespace_scope_ht_size): New function.
+ (begin_scope): Change prototype. Return a scope. Tidy.
+ (kept_level_p): Update.
+ (pushlevel): Remove.
+ (maybe_push_cleanup_level): Simplify.
+ (poplevel): Update for sk_cleanup and keep change.
+ (print_binding_level): Likewise.
+ (initial_push_namespace_scope): Fold in begin_scope. Remove.
+ (push_namespace): Update.
+ (pushtag): Likewise.
+ (lookup_tag): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (cxx_init_decl_processing): Likewise.
+ (start_function): Likewise.
+ (begin_function_body): Likewise.
+ (start_method): Likewise.
+ * pt.c (push_inline_template_parms_recursive): Likewise.
+ (begin_template_parm_list): Likewise.
+ (begin_specialization): Likewise.
+ * semantics.c (do_pushlevel): Likewise.
+ (begin_compound_stmt): Likewise.
+ (begin_stmt_expr): Likewise.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * class.c, cp-tree.h, decl.c, decl2.c, error.c, init.c,
+ method.c, optimize.c, pt.c, semantics.c, tree.c: Revert.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * class.c, cp-tree.h, decl.c, decl2.c, error.c, init.c,
+ method.c, optimize.c, pt.c, semantics.c, tree.c: Update for
+ DECL_SOURCE_LOCATION rename and change to const.
+
+2003-09-20 Richard Henderson <rth@redhat.com>
+
+ * decl.c, decl2.c, pt.c: Use %J in diagnostics.
+
+2003-09-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/157
+ * parser.c (cp_parser_direct_declarator): Clear
+ parser->num_template_parameter_lists when parsing function
+ parameters.
+ (cp_parser_constructor_declarator_p): Likewise.
+
+2003-09-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/495
+ * pt.c (tsubst_friend_class): Only use innermost template
+ arguments for the injected friend class template.
+
+2003-09-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12332
+ * pt.c (instantiate_class_template): Increment
+ processing_template_decl around the tsubst of a template member
+ function.
+
+2003-09-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (cxx_scope_descriptor): Fix thinko.
+ (struct cp_binding_level): Adjust type of binding_depth field.
+
+2003-09-18 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/12320
+ * call.c (type_passed_as): Check for incomplete type.
+ (convert_for_arg_passing): Likewise.
+
+2003-09-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9848
+ * optimize.c (maybe_clone_body): Don't set MARK_USED on parameters
+ here.
+ * semantics.c (expand_body): Set it here on the remaining clones.
+
+2003-09-18 Roger Sayle <roger@eyesopen.com>
+
+ * lex.c (init_operators): Remove operator_name_info for FFS_EXPR.
+ * class.c (instantiate_type): Remove FFS_EXPR case.
+
+2003-09-18 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * ChangeLog: Fix recent commit.
+
+2003-09-18 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * ChangeLog: Add PR number to patch for PR c++/12316.
+
+2003-09-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_type): Simplify. Use pp_type_specifier_seq for
+ "C" types.
+ * cxx-pretty-print.c (pp_cxx_type_specifier_seq): Fix thinko.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_body): Don't save/restore input_location.
+
+2003-09-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12266
+ * cp-tree.h (tsubst_flags_t): Add tf_conv.
+ * class.c (standard_conversion): Pass tf_conv to
+ instantiate_type.
+ (resolve_address_of_overloaded_function): Do not call mark_used
+ when just checking conversions.
+
+ PR debug/12066
+ * cp-lang.c (LANG_HOOKS_BUILTIN_TYPE_DECLS): Define.
+ * cp-tree.h (cxx_builtin_type_decls): Declare.
+ * decl.c (builtin_type_decls): New variables.
+ (cxx_builtin_type_decls): New function.
+ (record_builtin_type): Add to builtin_type_decls.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ PR c++/12316
+ * semantics.c (expand_or_defer_fn): Inc/dec function_depth.
+
+2003-09-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7939
+ * typeck.c (comptypes): Don't ICE when its first argument is
+ error_mark_node.
+ (compparms): Reverse the arguments of same_type_p.
+
+2003-09-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12184
+ * typeck.c (convert_arguments): Return error_mark_node for an
+ incomplete parameter. Make error message more informative.
+
+2003-09-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3907
+ * class.c (maybe_note_name_used_in_class): Refine test for whether
+ or not we are in a class scope.
+
+ * cp-tree.h (language_function): Remove x_expanding_p.
+ (expanding_p): Remove.
+ (doing_semantic_analysis_p): Remove.
+ (scope_kind): Add sk_function_parms, sk_class,
+ sk_namespace.
+ (innermost_scope_kind): New method.
+ * call.c (cxx_type_promotes_to): Use type_decays_to.
+ * cp-lang.c (LANG_HOOKS_PUSHLEVEL): Redefine.
+ (LANG_HOOKS_POPLEVEL): Likewise.
+ * decl.c (cp_binding_level): Remove parm_flag, template_parms_p,
+ template_spec_p, namespace_p, is_for_scope, is_try_scope, and
+ is_catch_scope. Add kind and explicit_spec_p.
+ (cxx_scope_descriptor): Use a lookup table.
+ (find_class_binding_level): Use "kind" field in binding_level, not
+ the various flags.
+ (pop_binding_level): Likewise.
+ (innermost_nonclass_level): Likewise.
+ (toplevel_bindings_p): Likewise.
+ (namespace_bindings_p): Likewise.
+ (template_parm_scope_p): Likewise.
+ (innermost_scope_kind): New method.
+ (current_tmpl_spec_kind): Use "kind" field in binding_level, not
+ the various flags.
+ (pushlevel): Remove check for doing_semantic_analysis_p.
+ (begin_scope): Simplify.
+ (add_decl_to_level): Use "kind" field in binding_level, not
+ the various flags.
+ (push_local_binding): Likewise.
+ (pop_label): Remove check for doing_semantic_analysis_p.
+ (poplevel): Use "kind" field in binding_level, not
+ the various flags.
+ (set_block): Remove check for doing_semantic_analysis_p.
+ (pushlevel_class): Use "kind" field in binding_level, not
+ the various flags.
+ (poplevel_class): Likewise.
+ (initial_push_namespace_scope): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ (pop_everything): Likewise.
+ (maybe_process_template_type_declaration): Likewise.
+ (pushtag): Likewise.
+ (pushdecl): Likewise.
+ (pushdecl_with_scope): Likewise.
+ (check_previous_goto_1): Likewise.
+ (define_label): Likewise.
+ (finish_case_label): Likewise.
+ (lookup_tag): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_name_real): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (record_builtin_type): Likewise.
+ (cp_make_fname_decl): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (cp_finish_decl): Remove check for doing_semantic_analysis_p.
+ (start_function): Use begin_scope, not pushlevel.
+ (finish_function): Use "kind" field in binding_level, not
+ the various flags.
+ (start_method): Use begin_scope, not pushlevel.
+ (make_label_decl): Do not check expanding_p.
+ (save_function-data): Do not set expanding_p.
+ (cxx_push_function_context): Do not clear expanding_p.
+ * semantics.c (cxx_expand_function_start): Do not set expanding_p.
+
+2003-09-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Make DECL_MODE match TYPE_MODE for
+ an bit-field whose width exceeds that of its type.
+
+2003-09-14 Geoffrey Keating <geoffk@apple.com>
+
+ * rtti.c (get_tinfo_decl): Set TREE_PUBLIC for typeinfo decls.
+
+2003-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * parser.c: Likewise.
+
+2003-09-13 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (finish_file): Check cgraph_assemble_pending_functions
+ during relaxation loop.
+
+2003-09-11 David Edelsohn <edelsohn@gnu.org>
+
+ * decl2.c (var_finalized_p): Swap arms of conditional.
+
+2003-09-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11788
+ * typeck.c (build_address): If it is a function, mark it used.
+ (build_unary_op): Do not lose object's side-effects when taking
+ address of static member function.
+ * class.c (resolve_address_of_overloaded_function): Use
+ tsubst_flags_t parameter. Only expect overload sets. Adjust.
+ (instantiate_type): Adjust flags passing. Do not lose object's
+ side-effects when taking address of static member function.
+
+2003-09-11 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_or_defer_fn): Update for new
+ cgraph_finalize_function argument.
+
+2003-09-10 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (cxx_callgraph_analyze_expr): Mark argument unused.
+
+2003-09-10 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (var_finalized_p): New.
+ (maybe_emit_vtables, write_out_vars, finish_file): Use it.
+
+2003-09-10 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (cxx_callgraph_analyze_expr): New, from corpse of
+ mark_member_pointers.
+ (lower_function): Remove.
+ * cp-tree.h: Update to match.
+ * cp-lang.c (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): New.
+ (LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION): Remove.
+
+2003-09-09 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_or_defer_fn): Update call to
+ cgraph_finalize_function.
+
+ * semantics.c (expand_or_defer_fn): Use cgraph_finalize_function
+ always.
+
+ * decl2.c (finish_file): Avoid out-of-bounds array reference
+ during memmove.
+
+2003-09-09 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (mark_member_pointers): Rename from
+ mark_member_pointers_and_eh_handlers and don't check eh handlers.
+
+2003-09-09 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
+
+ PR bootstrap/12168
+ * method.c (use_thunk): Clear DECL_RTL of copied nodes.
+
+2003-09-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-lang.c (LANG_HOOKS_REGISTER_BUILTIN_TYPE): Define to
+ c_register_builtin_type.
+
+ PR c++/11786
+ * decl2.c (add_function): Do not complain about seeing the same
+ non-function twice.
+ * semantics.c (perform_koenig_lookup): Improve documentation.
+
+ PR c++/5296
+ * pt.c (try_one_overload): Add addr_p parameter.
+ (resolve_overloaded_unification): Pass it.
+
+2003-09-08 Richard Henderson <rth@redhat.com>
+
+ * optimize.c (maybe_clone_body): Inc/dec function_depth.
+
+2003-09-08 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_function): Clear current_function_decl.
+ * decl2.c (mark_used): Don't push/pop gc context.
+ * optimize.c (optimize_function): Likewise.
+ * tree.c (cp_cannot_inline_tree_fn): Likewise.
+ * pt.c (instantiate_decl): Inc/dec function_depth instead.
+ * semantics.c (expand_body): Update for tree_rest_of_compilation
+ nested argument.
+
+2003-09-07 Gabriel Dos Reis <gcc@integrable-solutions.net>
+
+ PR c++/11762
+ * error.c (dump_decl): Handle namespace-alias-definition.
+ * decl.c (warn_extern_redeclared_static): There is no point in
+ checking changes in storage class specifier for a namespace
+ declaration.
+ (duplicate_decls): Tidy diagnostic message.
+ * cxx-pretty-print.c (pp_cxx_left_brace): New macro.
+ (pp_cxx_right_brace): Likewise.
+ (pp_cxx_original_namespace_definition): New function.
+ (pp_cxx_namespace_alias_definition): Likewise.
+ (pp_cxx_declaration): Use them. Handle NAMESPACE_DECLs.
+
+2003-09-07 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (maybe_emit_vtables, write_out_vars, finish_file):
+ Avoid re-emitting variables in unit-at-a-time mode.
+
+2003-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11867
+ * call.c (standard_conversion): Improve comments.
+ (perform_direct_initialization): Make sure we return an expression
+ of the correct type.
+ * typeck.c (build_static_cast): Check for ambiguity and
+ accessibility when performing conversions.
+
+2003-09-06 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (add_binding): Remove declaration.
+ * name-lookup.h (supplement_binding): Declare.
+ * decl.c (add_binding): Move to name-lookup.c.
+ (push_local_binding): Adjust.
+ (push_class_binding): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ * name-lookup.c (supplement_binding): Rename from add_binding.
+ Return a bool. Improve documentation.
+ (set_namespace_binding): Adjust.
+ * Make-lang.in (cp/name-lookup.o): Depend on toplev.h
+
+2003-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11794
+ * class.c (pushclass): Push dependent using decls for nested
+ classes of templates too.
+
+2003-09-06 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/11409
+ * class.c (resolve_address_of_overloaded_function): When building
+ list of matching non-template function decls, ignore anticipated
+ declarations of undeclared or shadowed GCC builtins.
+
+2003-09-06 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR c++/11595
+ * decl.c (define_label): Remove unreachable timevar pop.
+ Always return the decl, even if the definition is invalid.
+
+2003-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12167
+ * parser.c (cp_parser_late_parsing_default_args): Push & pop the
+ unparsed functions queue.
+
+2003-09-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12163
+ * call.c (perform_direct_initialization): Correct logic for
+ direct-initialization of a class type.
+
+ PR c++/12146
+ * pt.c (lookup_template_function): Robustify.
+
+2003-09-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11922
+ * pt.c (tsubst_qualified_id): Make sure we get a non-type.
+ (tsubst_expr, tsubst_copy_and_build): Pass false, not zero, as
+ is_type_p to lookup_qualified_name.
+
+ * semantics.c (finish_call_expr): Refactor some code.
+
+ PR c++/12037
+ * cp-tree.h (COMPOUND_EXPR_OVERLOADED): New.
+ (build_min_non_dep): Declare.
+ * tree.c (build_min): Propagate TREE_SIDE_EFFECTS.
+ (build_min_non_dep): New.
+ * cvt.c (convert_to_void): Don't explicitly copy
+ TREE_SIDE_EFFECTS, TREE_NO_UNUSED_WARNING.
+ * call.c (build_new_method_call): Use build_min_non_dep.
+ * decl2.c (grok_array_decl): Likewise.
+ (build_offset_ref_call_from_tree): Likewise.
+ * typeck.c (finish_class_member_access_expr,
+ build_x_indirect_ref, build_x_binary_op, build_x_unary_op,
+ build_x_conditional_expr, build_x_compound_expr): Likewise.
+ (build_static_cast, build_reinterpret_cast,
+ build_const_cast): Propagate TREE_SIDE_EFFECTS inside a template.
+ * typeck2.c (build_x_arrow): Use build_min_non_dep.
+ (build_functional_cast): Propagate TREE_SIDE_EFFECTS inside a
+ template.
+ * rtti.c (build_dynamic_cast_1): Set DECL_IS_PURE.
+ (build_dynamic_cast): Set TREE_SIDE_EFFECTS.
+ * pt.c (build_non_dependent_expr): Check COMPOUND_EXPR_OVERLOADED.
+
+2003-09-04 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (mark_member_pointers_and_eh_handlers): Update for
+ change in cgraph_mark_needed_node arguments.
+
+2003-09-02 Geoffrey Keating <geoffk@apple.com>
+
+ PR 12161
+ * decl2.c (mark_used): Use ggc_push_context/ggc_pop_context.
+ * tree.c (cp_cannot_inline_tree_fn): Likewise.
+
+2003-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (finish_sizeof, finish_alignof): Remove.
+ (expr_sizeof): Replace with ...
+ (cxx_sizeof_or_alignof_expr): ... here.
+ (cxx_sizeof_or_alignof_type): Make complain parameter a bool.
+ * parser.c (cp_parser_unary_expression): Commonize alignof and
+ sizeof handling.
+ * pt.c (tsubst_copy_and_build): Adjust alignof and sizeof
+ substitution.
+ * semantics.c (finish_sizeof, finish_alignof): Remove.
+ * typeck.c (cxx_sizeof_or_alignof_type): Complain parameter
+ becomes bool. Set TREE_READONLY.
+ (expr_sizeof): Replace with ...
+ (cxx_sizeof_or_alignof_expr): ... here. Clear TREE_SIDE_EFFECTS.
+
+2003-09-04 Mark Mitchell <mark@codesourcery.com>
+
+ Remove cast-as-lvalue extension.
+ * call.c (build_conditional_expr): Correct formatting.
+ (convert_like_real): Use lvalue_p, not non_cast_lvalue_p.
+ (initialize_real): Use real_lvalue_p, not real_non_cast_lvalue_p.
+ * cp-tree.h (non_cast_lvalue_p): Remove.
+ (real_non_cast_lvalue_p): Remove.
+ (non_cast_lvalue_or_else): Remove.
+ * tree.c (lvalue_p_1): Remove allow_cast_as_lvalue parameter.
+ (real_lvalue_p): Adjust call to lvalue_p_1.
+ (non_cast_lvalue_p): Remove.
+ (non_cast_lvalue_or_else): Remove.
+ (lvalue_p): Adjust call to lvalue_p_1.
+ (lvalue_or_else): Simplify.
+ * typeck.c (build_unary_op): Use lvalue_or_else, not
+ non_cast_lvalue_or_else.
+ (build_static_cast): Use real_lvalue_p, not real_non_cast_lvalue_p.
+
+2003-09-03 DJ Delorie <dj@redhat.com>
+
+ * decl.c (finish_function): Pass fndecl to aggregate_value_p.
+
+2003-09-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12053
+ * class.c (include_empty_classes): Correct logic for ABI version 1.
+
+2003-09-03 Richard Henderson <rth@redhat.com>
+
+ * optimize.c (optimize_function): Push/pop ggc context around
+ the call to optimize_inline_calls.
+
+2003-09-02 Scott Brumbaugh <scottb.lists@verizon.net>
+
+ PR c++/11553
+ * parser.c (cp_parser_decl_specifier_seq): Add check for a
+ duplicate friend decl-specifier.
+
+2003-09-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11847
+ * pt.c (convert_nontype_argument): Correct representation of
+ REFERENCE_TYPE expressions.
+
+ PR c++/11808
+ * cp-tree.h (KOENIG_LOOKUP_P): New macro.
+ (finish_call_expr): Change prototype.
+ * parser.c (cp_parser_postfix_expression): Adjust call to
+ finish_call_expr.
+ * pt.c (tsubst_copy_and_build): Use KOENIG_LOOKUP_P.
+ * semantics.c (finish_call_expr): Add koenig_p parameter.
+
+2003-09-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12114
+ * cp-tree.h (initialize_reference): Change prototype.
+ * call.c (initialize_reference): Add cleanup parameter.
+ * decl.c (grok_reference_init): Likewise.
+ (check_initializer): Likewise.
+ (cp_finish_decl): Insert a CLEANUP_STMT if necessary.
+ (duplicate_decls): When replacing an anticipated builtin, do not
+ honor TREE_NOTHROW.
+ * typeck.c (convert_for_initialization): Correct call to
+ initialize_reference.
+
+ PR c++/11972
+ * pt.c (dependent_type_p_r): Pass only the innermost template
+ arguments to any_dependent_template_arguments_p.
+
+2003-09-01 Josef Zlomek <zlomekj@suse.cz>
+
+ * error.c (dump_expr): Kill BIT_ANDTC_EXPR.
+ * lex.c (init_operators): Kill BIT_ANDTC_EXPR.
+ * pt.c (tsubst_copy): Kill BIT_ANDTC_EXPR.
+ * typeck.c (build_binary_op): Kill BIT_ANDTC_EXPR.
+ (tsubst_copy_and_build): Kill BIT_ANDTC_EXPR.
+
+2003-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12093
+ * pt.c (build_non_dependent_expr): Do not build a
+ NON_DEPENDENT_EXPR for a STRING_CST.
+
+ PR c++/11928
+ * search.c (add_conversions): Avoid adding two conversion
+ operators for the same type.
+
+2003-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6196
+ * pt.c (tsubst_copy_and_build): Correct handling of
+ address-of-label extension.
+ * semantics.c (finish_goto_stmt): The address of a label must go
+ through the lvalue-to-rvalue conversion.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+ Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_RTL_EXPAND_START): New.
+ (LANG_HOOKS_RTL_EXPAND_STMT): New.
+ * cp-tree.h (cxx_expand_function_start): Declare.
+ * decl.c (start_function): Use allocate_struct_function.
+ Move stmts_are_full_exprs_p assertion from expand_body.
+ Do not free_after_parsing or free_after_compilation.
+ (cxx_push_function_context): Move code to set struct function
+ data from genrtl_start_function.
+ * optimize.c (optimize_function): Don't inc/dec function_depth.
+ * semantics.c (expand_body): Use tree_rest_of_compilation.
+ (cxx_expand_function_start): Rename from genrtl_start_function,
+ omit bits done by tree_rest_of_compilation.
+ (genrtl_finish_function): Remove.
+ (clear_decl_rtl): Move to ../tree-optimize.c.
+
+2003-08-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/11811
+ * cxx-pretty-print.c (pp_cxx_canonical_template_parameter): New
+ function.
+ * cxx-pretty-print.h: Declare.
+ * error.c (dump_template_parameter): Use it.
+ (dump_type): Likewise.
+
+2003-08-28 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (decl_constant_value): Deal with COND_EXPR specially.
+ * call.c (build_conditional_expr): Revert previous patch.
+
+ PR optimization/5079
+ * call.c (build_conditional_expr): Use decl_constant_value to
+ simplify the arguments.
+
+2003-08-26 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * parser.c (struct cp_token): Use enum bitfields.
+ (CP_TOKEN_BLOCK_NUM_TOKENS): Make sure cp_token_block fits in a
+ 512B allocation unit.
+ (cp_parser_token_tree_map_node): Use enum bitfields.
+
+2003-08-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11871
+ * decl.c (push_class_level_binding): Correct old_decl value from
+ my 2003-07-29 reorganization.
+
+ * call.c (build_call): Don't set TREE_SIDE_EFFECTS here.
+ (build_new_method_call): Add goto finish.
+ * semantics.c (simplify_aggr_init_exprs_r): Don't set
+ TREE_SIDE_EFFECTS on a call.
+
+2003-08-25 Richard Henderson <rth@redhat.com>
+
+ * cxx-pretty-print.c (pp_cxx_class_name): Remove unused function.
+
+2003-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (pp_cxx_flag_default_argument): New flag.
+ (cxx_pretty_printer): Adjust base type.
+ (pp_cxx_function_specifier): Declare.
+ * cxx-pretty-print.c (pp_cxx_whitespace): New macro.
+ (pp_cxx_left_paren): Likewise.
+ (pp_cxx_right_paren): Likewise.
+ (pp_cxx_dot): Likewise.
+ (pp_cxx_arrow): Likewise.
+ (pp_cxx_semicolon): Likewise.
+ (pp_cxx_identifier): Likewise.
+ (pp_cxx_cv_qualifier_seq): Likewise.
+ (pp_cxx_storage_class_specifier): Likewise.
+ (pp_cxx_expression_list): Likewise.
+ (pp_cxx_space_for_pointer_operator): Likewise.
+ (pp_cxx_init_declarator): Likewise.
+ (pp_cxx_call_argument_list): Likewise.
+ (pp_cxx_nonconsecutive_character): Tidy.
+ (pp_cxx_conversion_function_id): New function.
+ (pp_cxx_template_id): Likewise.
+ (pp_cxx_template_keyword_if_needed): Likewise.
+ (pp_cxx_nested_name_specifier): Likewise.
+ (pp_cxx_unqualified_id): Tidy
+ (pp_cxx_qualified_id): Handle more nodes.
+ (pp_cxx_primary_expression): Tidy.
+ (pp_cxx_postfix_expression): Likewise.
+ (pp_cxx_new_expression): Tidy.
+ (pp_cxx_delete_expression): Likewise.
+ (pp_cxx_cast_expression): New function.
+ (pp_cxx_pm_expression): Tidy.
+ (pp_cxx_conditional_expression): Likewise.
+ (pp_cxx_assignment_operator): New function.
+ (pp_cxx_assignment_expression): Tidy.
+ (pp_cxx_expression): New function.
+ (pp_cxx_function_specifier): Likewise.
+ (pp_cxx_decl_specifier_seq): Likewise.
+ (pp_cxx_simple_type_specifier): Tidy.
+ (pp_cxx_type_specifier_seq): Likewise.
+ (pp_cxx_ptr_operator): New function.
+ (pp_cxx_implicit_parameter_type): Likewise.
+ (pp_cxx_parameter_declaration): Tidy.
+ (pp_cxx_parameter_declaration_clause): New function.
+ (pp_cxx_exception_specification): Likewise.
+ (pp_cxx_direct_declarator): Tidy.
+ (pp_cxx_declarator): Likewise.
+ (pp_cxx_ctor_initializer): New function.
+ (pp_cxx_function_definition): Likewise.
+ (pp_cxx_abstract_declarator): Tidy.
+ (pp_cxx_direct_abstract_declarator): Likewise.
+ (pp_cxx_type_id): Likewise.
+ (pp_cxx_exception_declaration): New function.
+ (pp_cxx_statement): Likewise.
+ (pp_cxx_simple_declaration): Likewise.
+ (pp_cxx_template_parameter_list): Likewise.
+ (pp_cxx_template_parameter): Likewise.
+ (pp_cxx_template_declaration): Likewise.
+ (pp_cxx_explicit_specialization): Likewise.
+ (pp_cxx_explicit_instantiation): Likewise.
+ (pp_cxx_declaration): Tidy.
+ (pp_cxx_pretty_printer_init): Initialize more fields.
+
+2003-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8795
+ * cp-tree.h (build_cplus_method_type): Remove.
+ * call.c (standard_conversion): Use build_method_type_directly
+ instead of build_cplus_method_type.
+ * class.c (build_clone): Likewise.
+ (adjust_clone_args): Likewise.
+ * decl.c (build_ptrmem_type): Likewise.
+ (grokdeclarator): Likewise.
+ (check_function_type): Likewise.
+ * decl2.c (grok_method_quals): Likewise.
+ (maybe_retrofit_in_chrg): Likewise.
+ * pt.c (copy_default_args_to_explicit_spec): Likewise.
+ (tsubst_function_type): Likewise.
+ (tsubst): Likewise.
+ * tree.c (build_cplus_method_type): Remove.
+ * typeck.c (merge_types): Use build_method_type_directly.
+
+2003-08-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/3765
+ * search.c (dfs_access_in_type): Fix typo in comment.
+ (dfs_accessible_queue_p): Likewise.
+ (dfs_accessible_p): Only terminate when a friend is found.
+ (accessible_p): Return immediately if access_in_type allows
+ access.
+
+2003-08-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/641, c++/11876
+ * friend.c (add_friend): Add complain parameter.
+ (make_friend_class): Likewise.
+ (do_friend): Adjust add_friend call.
+ * decl.c (grokdeclarator): Adjust make_friend_class call.
+ * parser.c (cp_parser_member_declaration): Likewise.
+ (cp_parser_template_declaration_after_export): Likewise.
+ * pt.c (instantiate_class_template): Adjust make_friend_class
+ and add_friend call.
+ * cp-tree.h (make_friend_class): Adjust declaration.
+ (add_friend): Likewise.
+
+2003-08-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/11283
+ * call.c (build_conditional_expr): Ignore cv-qual differences for
+ non-class types.
+
+2003-08-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11551
+ * parser.c (cp_parser_id_expression): Add declarator_p parameter.
+ (cp_parser_primary_expression): Adjust call to
+ cp_parser_id_expression.
+ (cp_parser_unqualified_id): Complain about the use of
+ typedef-names in a destructor declarator.
+ (cp_parser_postfix_expression): Adjust call to
+ cp_parser_id_expression.
+ (cp_parser_type_parameter): Likewise.
+ (cp_parser_template_argument): Likewise.
+ (cp_parser_declarator_id): Likewise.
+
+ PR c++/11919
+ * call.c (standard_conversion): Use same_type_p, not pointer
+ equality, to compare types.
+
+ PR c++/10762
+ * parser.c (cp_parser_using_declaration): Check for invalid uses
+ of template-ids here...
+ * decl2.c (do_class_using_decl): ... rather than here.
+
+2003-08-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11834
+ * pt.c (more_specialized): Bump processing_template_decl.
+
+2003-08-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/11614
+ * decl.c (grokdeclarator): Recognize a flexible array based on the
+ type, not the form of the declarator.
+
+2003-08-20 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (simplify_aggr_init_expr): Split out from
+ simplify_aggr_init_exprs_r. Convert slot address to match
+ the return type.
+ * cp-tree.h: Declare it.
+ * tree.c (cp_copy_res_decl_for_inlining): Don't clobber the
+ DECL_NAME of a user variable.
+
+2003-08-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11945
+ * pt.c (build_non_dependent_expr): Look inside COND_EXPR and
+ COMPOUND_EXPR.
+ * semantics.c (finish_expr_stmt): Always convert to void.
+ * typeck.c (build_x_compound_exp): Always convert to void.
+
+2003-08-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11684
+ * cp-tree.h (grok_op_properties): Change prototype.
+ * decl.c (grok_op_properties): Add complain parameter.
+ (grokfndecl): Pass it.
+ * pt.c (tsubst_decl): Adjust accordingly.
+
+ PR c++/10926
+ * decl.c (start_method): Return immediately if push_template_decl
+ does not like the declaration.
+ * pt.c (push_template_decl_real): Disallow member template
+ destructors.
+
+ PR c++/11036
+ * cp-tree.h (add_binding): Add prototype.
+ * class.c (add_method): Set TYPE_HAS_DESTRUCTOR if appropriate.
+ (maybe_warn_about_overly_private_class): Use
+ CLASSTYPE_DESTRUCTORS.
+ (pushclass): Adjust call to set_identifier_type_value.
+ * decl.c (add_binding): Give it external linkage.
+ (push_local_binding): Adjust call to add_binding.
+ (push_class_binding): Likewise.
+ (set_identifier_type_value_with_scope): Change prototype. Use
+ add_binding for global bindings.
+ (set_identifier_type_value): Adjust accordingly.
+ (pushtag): Likewise.
+ (pushdecl): Use set_identifier_type_value, not
+ set_identifier_type_value_with_scope.
+ (pushdecl_namespace_level): Adjust calls to
+ SET_IDENTIFIER_TYPE_VALUE to pass a DECL.
+ (pushdecl_class_level): Likewise.
+ (lookup_tag): Use select_decl.
+ (select_decl): Improve comment.
+ (record_builtin_type): Do not call pushdecl.
+ (cxx_init_decl_processing): Do not call xref_tag for bad_alloc.
+ (cp_finish_decl): Adjust call to set_identifier_type_value.
+ (check_elaborated_type_specifier): Improve checks for invalid uses
+ of typedefs.
+ (xref_tag): Adjust call to check_elaborated_type_specifier.
+ * decl2.c (grokclassfn): Do not set TYPE_HAS_DESTRUCTOR.
+ * name-lookup.c (set_namespace_binding): Use add_binding.
+ * parser.c (cp_parser_simple_type_specifier): Return a TYPE_DECL,
+ rather than an IDENTIFIER_NODE, to represent built-in types, if
+ requested by the caller.
+ (cp_parser_postfix_expression): Adjust call.
+ (cp_parser_type_specifier): Likewise.
+ (cp_parser_elaborated_type_specifier): Adjust call to
+ check_elaborated_type_specifier.
+ * typeck2.c (build_functional_cast): Do not perform name lookups.
+
+ PR c++/10717
+ * decl.c (expand_static_init): Remove unnecessary code.
+
+2003-08-19 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/10538, PR c/5582
+ * cp/cp-lang.c (LANG_HOOKS_DECL_UNINIT): Define.
+
+2003-08-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11174
+ * init.c (build_offset_ref): Perform access checking for
+ pointer to member correctly.
+
+2003-08-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-lang.c (LANG_HOOKS_INITIALIZE_DIAGNOSTICS): Fix spelling.
+
+2003-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11957
+ * cp-tree.h (finish_stmt_expr): Add bool parameter.
+ * init.c (finish_init_stmts): Pass true to finish_stmt_expr. Don't
+ adjust the stmt_expr here.
+ (build_vec_init): Use finish_stmt_expr_expr, convert result to
+ array type.
+ * parser.c (cp_parser_primar_expression): Adjust finish_stmt_expr
+ call.
+ * pt.c (tsubst_copy): Likewise.
+ * semantics.c (finish_stmt_expr): Add parameter.
+
+ * pt.c (instantiate_class_template): Push to class's scope before
+ tsubsting base.
+
+2003-08-17 Jan Hubicka <jh@suse.cz>
+
+ PR C++/11702
+ * semantics.c (finish_id_expression): Mark all functions as used.
+
+2003-08-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11512
+ * cvt.c (convert_to_void): Indicate which side of conditional has
+ no effects, and rhs of comma operator. Test for no sideeffect
+ expressions here and always build a convert expr.
+ * init.c (expand_default_init): Convert the init to void.
+ * typeck.c (build_x_compound_expr): Do not check for side effects
+ here.
+ (build_compound_expr): Do not convert lhs when building a
+ template.
+
+2003-08-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.def (NON_DEPENDENT_EXPR): Add operand.
+ * decl2.c (build_offset_ref_call_from_tree): Use
+ build_non_dependent_expr.
+ * error.c (dump_expr) <NON_DEPENDENT_EXPR case>: Dump the operand.
+ * pt.c (build_non_dependent_expr): Set operand.
+
+2003-08-14 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (mark_member_pointers): Rename to...
+ (mark_member_pointers_and_eh_tinfos): ... this one; deal with eh tinfos
+ (lower_function): Update call.
+ * except.c (eh_type_info): Break out from ...
+ (build_eh_type): ... here; tinfo is already used.
+ (finish_eh_spec_block): Mark tinfos as used.
+ * semantics.c (finish_handler_params): Mark tinfo as used.
+ * cp-tree.h (eh_type_info): Declare.
+
+2003-08-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_class_template): Set location before
+ substuting bases.
+
+ * decl.c (make_typename_type): Use my_friendly_assert.
+ * pt.c (tsubst_aggr_type): Rearrange context substitution.
+
+2003-08-14 Jan Hubicka <jh@suse.cz>
+
+ * method.c (use_thunk): Expand body directly.
+
+2003-08-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11703
+ * call.c (type_passed_as): Use TYPE_SIZE, not TYPE_PRECISION to
+ determine whether or not to promote types.
+ (convert_for_arg_passing): Likewise.
+ * decl2.c (cp_build_parm_decl): Do not set DECL_ARG_TYPE in
+ templates.
+ * pt.c (tsubst_decl): Do not expect it to be set.
+
+ PR c++/9512
+ PR c++/10923
+ * cp-tree.h (check_elaborated_type_specifier): Declare.
+ (handle_class_head): Remove.
+ (note_got_semicolon): Likewise.
+ (note_list_got_semicolon): Likewise.
+ (finish_class_definition): Likewise.
+ * decl.c (check_elaborated_type_specifier): Make it public.
+ Robustify.
+ (handle_class_head): Remove.
+ * parser.c (cp_parser_elaborated_type_specifier): Use
+ check_elaborated_type_specifier.
+ (cp_parser_class_specifier): Do not call finish_class_definition.
+ (cp_parser_class_head): Or handle_class_head. Check for
+ over-qualified names.
+ * semantics.c (finish_class_definition): Remove.
+
+ * parser.c (cp_parser_check_for_definition_in_return_type): New
+ function.
+ (cp_parser_simple_declaration): Adjust call to
+ cp_parser_init_declarator.
+ (cp_parser_decl_specifier_seq): Change type of
+ declares_class_or_enum parameter.
+ (cp_parser_explicit_instantiation): Adjust accordingly.
+ (cp_parser_type_specifier): Change type of
+ declares_class_or_enum parameter.
+ (cp_parser_init_declarator): Add declares_class_or_enum
+ parameter.
+ (cp_parser_parameter_declaration): Adjust call to
+ cp_parser_decl_specifier_seq.
+ (cp_parser_function_definition): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_single_declaration): Likewise.
+
+ * cp-tree.h (lang_type_class): Remove has_call_overloaded,
+ has_array_ref_overloaded, has_arrow_overloaded, and got_semicolon.
+ (TYPE_OVERLOADS_CALL_EXPR): Remove.
+ (TYPE_OVERLOADS_ARRAY_REF): Likewise.
+ (TYPE_OVERLOADS_ARROW): Likewise.
+ (CLASSTYPE_GOT_SEMICOLON): Likewise.
+ * class.c (check_bases): Do not set them.
+ (finish_struct_1): Likewise.
+ * decl.c (cp_finish_decl): Do not set CLASSTYPE_GOT_SEMICOLON.
+ (build_ptrmemfunc_type): Likewise.
+ (grok_op_properties): Do not set TYPE_OVERLOADS_*.
+ (start_function): Do not check CLASSTYPE_GOT_SEMICOLON.
+ * decl2.c (grokfield): Do not set CLASSTYPE_GOT_SEMICOLON.
+ * lex.c (note_got_semicolon): Remove.
+ (note_list_got_semicolon): Likewise.
+ * parser.c (cp_parser_simple_declaration): Do not call
+ note_list_got_semicolon.
+ * pt.c (list_eq): Remove.
+ (lookup_template_class): Do not set CLASSTYPE_GOT_SEMICOLON.
+ (instantiate_class_template): Do not set TYPE_OVERLOADS*.
+ (instantiate_class_template): Do not set CLASSTYPE_GOT_SEMICOLON.
+ * ptree.c (cxx_print_type): Do not print them.
+ * semantics.c (finish_member_class_template): Do not call
+ note_list_got_semicolon.
+
+2003-08-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * call.c (standard_conversion): Opaque pointers interconvert.
+
+ * testsuite/g++.dg/other/opaque-3.C: New.
+
+2003-08-11 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (merge_types): Handle cv-qualified pointer-to-member
+ types correctly.
+
+2003-08-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11789
+ * cp-tree.h (get_vbase): Remove.
+ (get_vbase_types): Remove.
+ * init.c (expand_member_init): Correct logic for looking up base
+ classes.
+
+2003-08-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_expr): Tidy.
+ * cxx-pretty-print.c (pp_cxx_nonconsecutive_character): New.
+ (pp_cxx_begin_template_argument_list): Likewise.
+ (pp_cxx_end_template_argument_list): Likewise.
+ (is_destructor_name): Likewise.
+ (pp_cxx_unqualified_id): Likewise.
+ (pp_cxx_qualified_id): Likewise.
+ (pp_cxx_id_expression): Likewise.
+ (pp_cxx_new_expression): Likewise.
+ (pp_cxx_delete_expression): Likewise.
+ (pp_cxx_pm_expression): Likewise.
+ (pp_cxx_type_specifier): Rework.
+ (pp_cxx_type_id): Likewise.
+ (pp_cxx_primary_expression): Likewise.
+ (pp_cxx_postfix_expression): Likewise.
+ (pp_cxx_unary_expression): Likewise.
+ (pp_cxx_multiplicative_expression): Likewise.
+ (pp_cxx_conditional_expression): Likewise.
+ (pp_cxx_assignment_expression): Likewise.
+ (pp_cxx_pretty_printer_init): Tidy.
+
+2003-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): non-NULL
+ NODE is always a TREE_VEC of nonzero size.
+ (NUM_TMPL_ARGS): NODE is always a TREE_VEC.
+ * decl2.c (arg_assoc): Template args will be a vec.
+ * error.c (dump_decl) <TEMPLATE_ID_EXPR case>: Call
+ dump_template_argument_list.
+ (dump_template_parms): Args will be a vec.
+ * parser.c (cp_parser_template_argument_list): Produce a
+ vector, not a list.
+ * pt.c (coerce_template_parms): Args are always vectors.
+ (mangle_class_name_for_template): Likewise.
+ (lookup_template_function): Likewise.
+ (lookup_template_class): Likewise.
+ (tsubst_template_args): Likewise.
+ (tsubst_baselink): Use tsubst_template_args.
+ (tsubst_qualified_id): Likewise.
+ (tsubst_copy) <TEMPLATE_ID_EXPR case>: Likewise.
+ (tsubst_copy_and_build) <TEMPLATE_ID_EXPR case>: Likewise.
+ (any_dependent_template_args_p): Args are always vectors.
+ * tree.c (cp_tree_equal): Add TEMPLATE_ID_EXPR case.
+
+ PR c++/11670
+ * call.c (convert_like_real): Add rvalue binding error message.
+ * error.c (dump_expr) <NOP_EXPR case>: Detect when the no expr is
+ really a cast.
+
+ PR c++/10530
+ * pt.c (dependent_type_p_r): A dependent template-id is a class
+ type with dependent template arguments, or a bound template
+ template parameter.
+ (type_dependent_expression_p): A template function decl cannot
+ have a dependent context.
+
+2003-08-07 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5767
+ * parser.c (cp_parser_class_name): Return immediately when scope
+ is error_mark_node.
+
+2003-08-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp/Make-lang.in (cp/call.o): Add dependency for target.h.
+
+ * cp/call.c (standard_conversion): Support opaque types.
+ Include target.h.
+ (strip_top_quals): Use cp_build_qualified_type instead of
+ TYPE_MAIN_VARIANT.
+
+ * cp/typeck.c (convert_for_assignment): Support opaque types.
+
+ * testsuite/g++.dg/other/opaque-1.C: New.
+
+ * testsuite/g++.dg/other/opaque-2.C: New.
+
+2003-08-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * decl.c (grokparms): Use cp_build_qualified_type instead
+ TYPE_MAIN_VARIANT.
+
+2003-08-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h: New file.
+ * cxx-pretty-print.c: Likewise.
+ * error.c (scratch_pretty_printer): Change type.
+ (init_error): Tidy.
+ (dump_aggr_type): Likewise.
+ (dump_global_iord): Likewise.
+ (dump_expr): Likewise.
+ (dump_char): Remove.
+ * cp-lang.c (LANG_HOOKS_INITIALIZE_DIAGNOSTITCS): Define.
+ (cxx_initialize_diagnostics): New function.
+ * Make-lang.in (CXX_OBJS): Add cp/cxx-pretty-print.o
+ (CXX_PRETTY_PRINT_H): New variable.
+ (cp/cxx-pretty-print.o): New rule.
+ (cp/cp-lang.o): Update dependence.
+ (cp/error.o): Likewise.
+
+2003-08-05 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cp-tree.h (struct lang_decl): Don't include c_lang_decl.
+ (DECL_DECLARED_INLINE_P): Remove.
+ * decl2.c (import_export_decl): Only look at DECL_DECLARED_INLINE_P
+ if decl is a FUNCTION_DECL. This never made sense, but now it is
+ required to avoid a tree check failure.
+ * decl.c (grokfndecl): Don't touch DID_INLINE_FUNC.
+ * optimize.c (maybe_clone_body): Likewise.
+
+2003-08-04 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (cxx_insert_default_attributes): Delete.
+ * cp-tree.h (cxx_insert_default_attributes): Don't prototype.
+ * cp-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Don't define.
+
+2003-08-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11704
+ * pt.c (type_dependent_expression_p): Cope with COMPONENT_REF with
+ unknown type.
+
+ PR c++/11766
+ * typeck.c (comp_ptr_ttypes_real): Don't loop on pointers to
+ member functions.
+
+2003-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9447
+ * cp-tree.def (USING_DECL): Document its type.
+ * class.c (pushclass): If we're entering a template, push any
+ dependent using decls it has.
+ * decl2.c (do_class_using_decl): Refactor. Type is NULL iff it is
+ a dependent scope.
+ * pt.c (tsubst_decl) <USING_DECL case>: Set type.
+ (tsubst): Remove USING_DECL checks.
+ (type_dependent_expression_p): Remove USING_DECL case.
+ * semantics.c (finish_member_declaration): A USING_DECL's type
+ indicates whether it is dependent.
+
+2003-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (pushclass): Remove unneeded parameter.
+ * class.c (pushclass): Remove unneeded MODIFY parm. Adjust.
+ (push_nested_class): Adjust pushclass call.
+ * pt.c (instantiate_class_template): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+
+2003-08-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * typeck2.c (add_exception_specifier): Use 'bool' where appropriate.
+
+2003-08-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11697
+ * decl.c (decls_match): Don't ignore the types of template
+ classes.
+
+ PR c++/11744
+ * pt.c (tsubst_copy_and_build): Refine Koenig lookup logic.
+
+2003-08-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8442, c++/8806
+ * decl.c (qualify_lookup): Accept TEMPLATE_DECL if types are
+ preferred.
+ (check_elaborated_type_specifier): Add allow_template_p
+ parameter. Check tag mismatch and class template.
+ (xref_tag): Add template_header_p parameter. Add assertion
+ that name is an IDENTIFIER_NODE. Remove implicit typename
+ warning. Simplify lookup process if globalize is true.
+ (cxx_init_decl_processing): Adjust call to xref_tag.
+ (xref_tag_from_type): Likewise.
+ * decl2.c (handle_class_head): Likewise.
+ * parser.c (cp_parser_elaborated_type_specifier,
+ cp_parser_class_head): Likewise.
+ * rtti.c (init_rtti_processing, build_dynamic_cast1,
+ tinfo_base_init, emit_support_tinfos): Likewise.
+ * class.c (is_base_of_enclosing_class): Remove.
+ * pt.c (convert_template_argument): Don't accept RECORD_TYPE as
+ template template argument.
+ * cp-tree.h (xref_tag): Adjust declaration.
+ (is_base_of_enclosing_class): Remove.
+ * NEWS: Document template template argument change.
+
+2003-08-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parser.c (cp_parser_init_declarator,
+ cp_paser_member_declaration): Reformat.
+ * pt.c (lookup_template_class, type_unification_real, unify,
+ type_dependent_expression_p): Reformat.
+
+ PR c++/11295
+ * cp-tree.h (tubst_flags_t): Add tf_stmt_expr_cmpd,
+ tf_stmt_expr_body.
+ (finish_stmt_expr_expr): Declare.
+ * parser.c (cp_parser_primary_expression): Tell
+ cp_parser_compount_statement that it is a statement expression.
+ (cp_parser_statement, cp_parser_labeled_statement,
+ cp_parser_compound_statement, cp_parser_statement_seq_opt): Add
+ in_statement_expr_p parameter.
+ (cp_parser_expression_statement): Likewise. Call
+ finish_stmt_expr_expr for final expression of a statement
+ expression.
+ (cp_parser_for_init_statement,
+ cp_parser_implicitly_scoped_statement,
+ cp_parser_already_scoped_statement, cp_parser_function_definition,
+ cp_parser_try_block, cp_parser_handled): Adjust.
+ * pt.c (tsubst_copy) <STMT_EXPR case>: Pass tf_stmt_expr.
+ (tsubst_expr): Process tf_stmt_expr and tf_stmt_exprs flags.
+ (tsubst_expr) <EXPR_STMT case>: Check tf_stmt_exprs flag.
+ * semantics.c (finish_expr_stmt): Do not deal with statement
+ expressions.
+ (begin_stmt_expr): Clear last_expr_type.
+ (finish_stmt_expr_expr): New.
+ (finish_stmt_expr): Process the value expression.
+
+ * typeck.c (build_compound_expr): If RHS is a TARGET_EXPR, put the
+ compound expr inside the target's initializer.
+
+ PR c++/11525
+ * parser.c (cp_parser_primary_expression): Do not set
+ non-constant-p merely because it is a dependent scope.
+
+ PR c++/9447
+ * decl2.c (do_class_using_decl): Set type to NULL_TREE.
+ * semantics.c (finish_expr_stmt): Do not convert to void in a
+ template.
+
+2003-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (coerce_template_parms): Refactor.
+ (fn_type_unification): Increment processing_template_decl when
+ tsubsting an incomplete set of explicit args.
+
+ PR c++/11347
+ * pt.c (instantiate_class_template): Increment
+ processing_template_decl around the tsubst of a template member
+ class.
+ (tsubst_qualified_id): Assert we do not have a dependent scope.
+
+ * pt.c (coerce_template_template_parms, lookup_template_class,
+ can_complete_type_without_circularity, instantiate_class_template,
+ tsubst_decl, unify): Reformat.
+
+2003-07-31 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (maybe_make_one_only): Use mark_referenced.
+ * method.c (use_thunk): Likewsie.
+
+2003-07-30 Jan Hubicka <jh@suse.cz>
+
+ * class.c (build_vtable_entry_ref): Kill.
+ (build_vtbl_ref_1): Do not call build_vtable_entry_ref.
+ (build_vfn_ref): Do not call build_vtable_entry_ref.
+ * cp-lang.c (LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE): Kill.
+ * cp-tree.h (prepare_assemble_variable): Kill.
+ * cp-decl.c (prepare_assemble_variable): Kill.
+
+2003-07-29 Geoffrey Keating <geoffk@apple.com>
+
+ * parser.c (cp_lexer_new_main): Use c_common_no_more_pch instead
+ of setting valid_pch by hand.
+
+2003-07-29 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * decl.c (finish_enum): Initialize underlying_type.
+
+2003-07-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9447
+ * decl.c (add_binding): Add bval local variable.
+ (push_class_level_binding): Likewise. Allow a USING_DECL to be
+ pushed.
+ * decl2.c (do_class_using_decl): The type of a using decl is
+ unknown.
+ * parser.c (cp_parser_postfix_expression): Refactor unqualified-id
+ function call lookup code.
+ * pt.c (tsubst): A USING_DECL will have unknown type.
+ (tsubst_copy_and_build): Allow a using decl.
+ (type_dependent_expression_p): A USING_DECL will make it
+ dependent.
+ * semantics.c (finish_member_declaration): Push a dependent using
+ declaration.
+
+2003-07-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11530
+ * parser.c (cp_parser_postfix_expression): Do not call mark_used.
+ * semantics.c (finish_id_expression): Call mark_used for all
+ declarations.
+
+2003-07-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11667
+ * call.c (standard_conversion): Allow all integral->enumeral
+ conversions, after marking them as bad.
+ * decl.c (finish_enum): Make sure that all enumerators are
+ properly converted to the underlying type.
+ (build_enumerator): Set DECL_CONTEXT for namespace-scope
+ enumeration types.
+ * pt.c (tsubst_copy): Adjust handling of CONST_DECLs accordingly.
+ (tsubst_enum): Tidy.
+
+ * Make-lang.in (typeck.o): Depend on convert.h.
+ (class.o): Likewise.
+ (rtti.o): Likewise.
+ * call.c: Include convert.h.
+ (convert_arg_to_ellipsis): Use convert_to_real.
+ * class.c: Include convert.h.
+ (build_base_path): Use convert_to_integer.
+ * rtti.c: Include convert.h.
+ (build_headof): Use convert_to_integer.
+ * typeck.c: Include convert.h.
+ (decay_conversion): Use convert_to_integer.
+ (build_unary_op): Use build_nop.
+ (get_delta_difference): Use convert_to_integer.
+ (build_ptrmemfunc): Avoid unnecessary conversions.
+
+2003-07-28 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (mark_member_pointers): Verify that member pointer points to
+ the function.
+
+2003-07-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (begin_compound_stmt): No scope arg is a bool.
+ (finish_compound_stmt): Remove no scope arg.
+ * decl.c (register_dtor_fn): Adjust begin_compound_stmt and
+ end_compound_stmt calls.
+ (expand_static_init, begin_destructor_body, begin_function_body,
+ finish_function_body): Likewise.
+ * decl2.c (start_objects, finish_objects,
+ start_static_storage_duration_function,
+ finish_static_storage_duration_function): Likewise.
+ * init.c (begin_init_stmts, finish_init_stmts,
+ construct_virtual_base, build_vec_init): Likewise.
+ * method.c (do_build_assign_ref, synthesize_method): Likewise.
+ * parser.c (cp_parser_compound_statement,
+ cp_parser_implicitly_scoped_statement,
+ cp_parser_already_scoped_statement): Likewise.
+ * pt.c (tsubst_expr): Likewise.
+ * semantics.c (begin_compound_stmt): No scope arg is a bool.
+ (finish_compound_stmt): Remove no scope arg.
+
+ * error.c (dump_expr) <COMPOUND_EXPR case>: A compound expr is
+ always dyadic.
+
+2003-07-27 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (standard_conversion): Tweak handling of
+ pointer-to-member types.
+ * pt.c (tsubst): Correctly qualify pointers-to-data member types.
+ * typeck.c (comp_ptr_ttypes_real): Check qualifiers on
+ pointer-to-data member types.
+
+2003-07-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parser.c (cp_parser_type_parameter): Reformat.
+ (cp_parser_parameter_declaration): Deprecate default args where
+ not allowed.
+
+2003-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cfns.h: Rebuilt.
+
+ * cp-tree.h (begin_init_stmts, finish_init_stmts): Remove.
+ (begin_global_stmt_expr, finish_global_stmt_expr): Remove.
+ * init.c (begin_init_stmts): Make static. Return is_global
+ value. Always call begin_stmt_expr.
+ (finish_init_stmts): Make static. Add is_global parm. Always
+ building a stmt tree.
+ (build_aggr_init): Adjust begin_init_stmts, finish_init_stmts calls.
+ (build_vec_init): Likewise. Always building a stmt tree.
+ (expand_default_init): Always building a stmt tree.
+ (get_temp_regvar): Likewise.
+ * semantics.c (begin_global_stmt_expr,
+ finish_global_stmt_expr): Remove.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (build_compound_expr): Take LHS & RHS args.
+ (build_x_compound_expr_from_list): Declare.
+ * typeck.c (build_x_compound_expr_from_list): New.
+ (build_x_compound_expr): Adjust.
+ (build_compound_expr): Remove unreachable code. Take two
+ parameters, adjust.
+ * decl.c (grok_reference_init): Use
+ build_x_compound_expr_from_list.
+ (expand_static_init): Adjust build_compound_expr call.
+ (cxx_maybe_build_cleanup): Likewise.
+ * init.c (perform_member_init): Use
+ build_x_compound_expr_from_list.
+ (build_new_1): Likewise.
+ (build_vec_delete): Adjust build_compound_expr calls.
+ (build_vbase_delete): Likewise.
+ * typeck2.c (store_init_value): Use
+ build_x_compound_expr_from_list.
+ (build_functional_cast): Likewise.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (enum tsubst_flags_t): Add tf_user.
+ * decl.c (make_typename_type): Pass it.
+ * pt.c (lookup_template_class): Use it.
+ (resolve_typename_type): Pass it.
+ * semantics.c (finish_template_type): Pass it.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11617
+ * cp-tree.h (qualified_name_lookup_error): Declare.
+ * pt.c (tsubst_qualified_id): Use qualified_name_lookup_error for
+ errors.
+ (tsubst_expr) <DECL_STMT case>: Likewise.
+ (tsubst_copy_and_build) <COMPONENT_REF case>: Likewise.
+ * semantics.c (qualified_name_lookup_error): New, broken out of ...
+ (finish_id_expression): ... here. Use it.
+
+2003-07-25 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ * cfns.gperf: Add '%%' delimiter to placate gperf 3.0.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11596
+ * pt.c (maybe_fold_nontype_arg, maybe_fold_nontype_args): Remove.
+ (tsubst_template_arg): New.
+ (tsubst_template_arg_vector): Rename to ...
+ (tsubst_template_args): ... this. Accept a TREE_LIST form. Use
+ tsubst_template_arg.
+ (coerce_template_parms): Use tsubst_template_arg for default
+ value.
+ (tsubst_template_parms): Likewise.
+ (tsubst_aggr_type): Adjust.
+ (tsubst_decl): Likewise.
+ (tsubst): Use tsubst_template_arg for a DOMAIN. Adjust.
+ (tsubst_copy) <TEMPLATE_ID_EXPR case>: Use tsubst_template_args.
+
+2003-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * Make-lang.in (cp/error.o): Depend on DIAGNOSTIC_H.
+ * error.c: Use the new pretty-printer framework.
+
+2003-07-24 Per Bothner <pbothner@apple.com>
+
+ * decl.c (pushdecl_class_level): Don't use push_srcloc/pop_srcloc
+ which causes errors messages to incorrectly mention included files.
+
+2003-07-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (convert_to_base_statically): Declare.
+ * call.c (build_special_member_call): Convert INSTANCE to the base
+ type.
+ * class.c (convert_to_base_statically): New method.
+ * init.c (construct_virtual_base): Use it.
+ * method.c (do_build_assign_ref): Fix typo in comment.
+
+2003-07-24 Jason Merrill <jason@redhat.com>
+
+ * decl.c: Just set truthvalue_* to boolean_*.
+
+2003-07-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (reshape_init): Remove unreachable code.
+
+2003-07-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11513
+ * cp-tree.h (PROCESSING_REAL_TEMPLATE_DECL_P): Use current_scope.
+
+2003-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11645
+ * cp-tree.h (accessible_base_p): Declare.
+ * call.c (build_over_call): Use it.
+ * search.c (accessible_base_p): New function, split out from ...
+ (lookup_base): ... here.
+
+ PR c++/11517
+ * call.c (build_conditional_expr): Use perform_implicit_conversion
+ and error_operand_p. Robustify.
+ * typeck.c (build_unary_op): Use perform_implicit_conversion.
+
+2003-07-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10953
+ * parser.c (cp_parser_nested_name_specifier): Reset scope on
+ failure.
+ (cp_parser_elaborated_type_specifier): Likewise.
+
+2003-07-22 Mark Mitchell <mark@codesourcery.com>
+
+ Eliminate use of POINTER_TYPE for pointers-to-members.
+ * call.c (standard_conversion): Rework pointer-to-member handling.
+ Add comments.
+ (add_builtin_candidate): Likewise.
+ (resolve_scoped_fn_name): Remove.
+ (build_conditional_expr): Rework pointer-to-member handling.
+ (compare_ics): Likewise.
+ * class.c (check_field_decls): Use TYPE_PTR_P.
+ * cp-lang.c (cp_var_mod_type_p): Rework pointer-to-member
+ handling.
+ * cp-tree.h (SCALAR_TYPE_P): Use TYPE_PTR_TO_MEMBER_P.
+ (TYPE_PTRMEM_P): Add comment.
+ (TYPE_PTR_P): Simplify.
+ (TYPE_PTROB_P): Correct definition.
+ (TYPE_PTR_TO_MEMBER_P): New macro.
+ (TYPE_PTRMEM_CLASS_TYPE): Adjust.
+ (TYPE_PTRMEM_POINTED_TO_TYPE): Likewise.
+ (resolved_scoped_fn_name): Remove declaration.
+ (build_offset_ref): Change prototype.
+ (resolve_offset_ref): Remove.
+ (comp_target_types): Remove.
+ * cvt.c (cp_convert_to_pointer): Rework pointer-to-member
+ handling.
+ (convert_to_reference): Use can_convert.
+ (ocp_convert): Improve error handling. Rework pointer-to-member
+ handling.
+ (perform_qualification_conversions): Rework pointer-to-member
+ handling.
+ * decl.c (build_ptrmem_type): Handle functions too.
+ (create_array_type_for_decl): Remove OFFSET_TYPE error message.
+ (grokdeclarator): Use OFFSET_TYPE for pointers to data members.
+ (grokparms): Remove OFFSET_TYPE error message.
+ * dump.c (cp_dump_tree): Rework pointer-to-member handling.
+ * error.c (dump_type_prefix): Likewise.
+ * expr.c (cplus_expand_constant): Use build_nop.
+ * init.c (build_offset_ref): Add address_p parameter. Fold in
+ necessary bits from resolve_offset_ref.
+ (resolve_offset_ref): Remove.
+ * parser.c (cp_parser_postfix_expression): Remove special case
+ code for OFFSET_TYPE.
+ * pt.c (convert_nontype_argument): Rework pointer-to-member
+ handling.
+ (convert_template_argument): Likewise.
+ (unify): Likewise.
+ (invalid_nontype_parm_type_p): Likewise.
+ (dependent_type_p_r): Likewise.
+ * rtti.c (get_tinfo_decl): Remove OFFSET_TYPE special case.
+ (target_incomplete_p_): Rework pointer-to-member
+ handling.
+ (get_pseudo_ti_init): Likewise.
+ (get_pseudo_ti_desc): Likewise.
+ * semantics.c (finish_qualified_id_expr): Adjust call to
+ build_offset_ref. Remove use of resolve_offset_ref.
+ * tree.c (pod_type_p): Use TYPE_PTR_TO_MEMBER_P.
+ * typeck.c (target_type): Use TYPE_PTRMEM_P.
+ (type_unknown_p): Remove obsolete code about the time before
+ non-dependent expressions were handled correctly.
+ (qualify_type_recursive): Remove.
+ (composite_pointer_type_r): New function.
+ (composite_pointer_type): Use it.
+ (merge_types): Remove dead comments.
+ (comp_cv_target_types): Remove.
+ (comp_target_types): Likewise.
+ (comp_target_parms): Likewise.
+ (cxx_sizeof_or_alignof_type): Remove OFFSET_TYPE error.
+ (build_indirect_ref): Use TYPE_PTR_TO_MEMBER_P.
+ (build_binary_op): Do not use of comp_target_types.
+ (pointer_diff): Remove OFFSET_TYPE case.
+ (build_unary_op): Adjust pointer-to-member handling.
+ (unary_complex_lvalue): Likewise.
+ (check_for_casting_away_constness): Add description parameter.
+ (build_static_cast): Pass it.
+ (build_reinterpret_cast): Use check_for_casting_away_constness.
+ (build_const_cast): Adjust pointer-to-member handling.
+ (build_c_cast): Likewise.
+ (convert_for_assignment): Remove OFFSET_TYPE error message.
+ (comp_ptr_ttypes_real): Adjust pointer-to-member handling.
+ (comp_ptr_ttypes_reinterpret): Remove.
+ (casts_away_constness_r): Adjust pointer-to-member handling.
+ (casts_away_constness): Liekwise.
+ (strip_all_pointer_quals): Remove.
+ * typeck2.c (digest_init): Adjust pointer-to-member handling.
+ (build_m_component_ref): Likewise.
+
+2003-07-22 Wolfgang Bangerth <bangerth@dealii.org>
+
+ * lex.c (unqualified_fn_lookup_error): Mention that the error
+ message needs to be kept in synch with the manual.
+
+2003-07-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11614
+ * decl.c (grokdeclarator): An array member is only a flexible
+ array member if the field itself is the array.
+
+2003-07-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10793
+ * decl.c (xref_basetypes): Handle error_mark_node.
+
+2003-07-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (enum cp_lvalue_kind): Add clk_packed.
+ * tree.c (lvalue_p_1): Set it.
+ * class.c (check_field): Don't allow non-packed non-POD fields to
+ be packed.
+ * call.c (reference_binding): Need a temporary for all bitfield
+ and packed fields.
+ (convert_like_real): Check it is ok to make a temporary here.
+
+2003-07-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (hack_identifier): Remove.
+ * method.c (hack_identifier): Remove.
+ * semantics.c (finish_id_expression): Expand hack_identifier
+ here. Simplify.
+
+2003-07-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c class.c decl.c decl2.c g++spec.c lex.c parser.c pt.c rtti.c
+ semantics.c typeck.c: Remove unnecessary casts.
+
+2003-07-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (hack_identifier): Remove.
+ * method.c (hack_identifier): Remove.
+ * semantics.c (finish_id_expression): Expand hack_identifier
+ here. Simplify.
+
+2003-07-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (finish_non_static_data_member): Add object param.
+ * method.c (hack_identifier): Adjust.
+ * pt.c (tsubst_copy_and_build) <COMPONENT_REF case>: Don't search
+ again for a FIELD_DECL.
+ * semantics.c (finish_non_static_data_member): Add object
+ parameter. Always save the DECL in the COMPONENT_REF.
+ * call.c (resolve_scoped_fn_name): Adjust.
+
+2003-07-17 Zack Weinberg <zack@codesourcery.com>
+
+ * pt.c (get_bindings): Make definition consistent with
+ forward declaration.
+
+2003-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7809
+ * friend.c (add_friend): Check access for member functions
+ and templates.
+
+2003-07-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10668
+ * typeck.c (build_class_member_access_expr): Improve diagnostic.
+
+2003-07-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11547
+ * cp-tree.h (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P): New
+ macro.
+ (DECL_PRETTY_FUNCTION_P): Use VAR_DECL_CHECK.
+ * decl.c (duplicate_decls): Merge
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+ * parser.c (cp_parser_postfix_expression): Adjust call to
+ cp_parser_initializer_list and
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_parenthesized_expression_list): Add non_constant_p.
+ (cp_parser_new_placement): Adjust call to
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_direct_new_declarator): Likewise.
+ (cp_parser_conditional_expression): Remove.
+ (cp_parser_constant_expression): Parse an assignment-expression,
+ not a conditional-expression.
+ (cp_parser_simple_declaration): Resolve expression/declaration
+ ambiguity more quickly.
+ (cp_parser_mem_initializer): Adjust call to
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_init_declarator): Keep track of whether or not the
+ initializer is a constant-expression.
+ (cp_parser_initializer): Add non_constant_p parameter.
+ (cp_parser_initializer_clause): Likewise.
+ (cp_parser_initializer_list): Likewise.
+ (cp_parser_attribute_list): Adjust call to
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_functional_cast): Likewise.
+ * pt.c (tsubst_decl): Copy
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+ (tsubst_expr): Tweak use of DECL_PRETTY_FUNCTION_P.
+ * semantics.c (finish_id_expression): Use
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+
+2003-07-16 Neil Booth <neil@daikokuya.co.uk>
+
+ * lang-options.h: Remove.
+
+2003-07-16 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/10962
+ * class.c (field_decl_cmp): Remove.
+ (resort_field_decl_cmp): Remove.
+ (resort_sorted_fields): Remove.
+ (add_fields_to_vec): Rename to ...
+ (add_fields_to_record_type): this.
+ (finish_struct_1): Change to be using
+ sorted_fields_type's fields.
+ * cp-tree.h (lang_decl): In lang_decl_u3
+ change sorted_fields to be a pointer to
+ sorted_fields_type.
+ (resort_sorted_fields): Remove prototype.
+ * search.c (lookup_field_1): Change to be using
+ sorted_fields_type's fields.
+
+2003-07-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5421
+ * decl.c (grokdeclarator): Handle TEMPLATE_ID_EXPR if friend
+ is a member of other class.
+ * friend.c (do_friend): Don't build TEMPLATE_DECL if friend
+ is a specialization of function template.
+
+2003-07-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10903
+ * pt.c (convert_nontype_argument): Fix thinko in diagnostic.
+ Improve.
+
+2003-07-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (LOOKUP_EXPR): Remove.
+ * cp-tree.h (cp_id_kind): Add CP_ID_KIND_UNQUALIFIED_DEPENDENT.
+ (LOOKUP_EXPR_GLOBAL): Remove.
+ (get_bindings): Remove.
+ (is_aggr_type_2): Remove.
+ * call.c (resolved_scoped_fn_name): Remove support for
+ LOOKUP_EXPR.
+ * decl.c (grokfndecl): Likewise.
+ (grokdeclarator): Likewise.
+ * error.c (dump_decl): Likewise.
+ (dump_expr): Likewise.
+ * friend.c (do_friend): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * lex.c (unqualified_fn_lookup_error): Use pedwarn. Do not create
+ LOOKUP_EXPRs
+ * mangle.c (write_expression): Remove support for LOOKUP_EXPR.
+ * parser.c (cp_parser_postfix_expression): Modify Koenig lookup
+ test.
+ * pt.c (get_bindings): Give it internal linkage.
+ (check_explicit_specialization): Remove support for LOOKUP_EXPR.
+ (lookup_template_function): Likewise.
+ (for_each_tempalte_parm_r): Likewise.
+ (tsubst_decl): Likewise.
+ (tsubst_qualified_id): Handle template template parameters.
+ (tsubst_copy): Remove support for LOOKUP_EXPR.
+ (tsubst_copy_and_build): Likewise.
+ (most_general_template): Likewise.
+ (value_dependent_expression_p): Likewise.
+ (type_dependent_expression_p): Note that IDENTIFIER_NODEs are
+ always dependent.
+ * semantics.c (perform_koenig_lookup): Do not create
+ IDENTIFIER_NODEs.
+ (finish_fname): Likewise.
+ (finish_id_expression): Likewise.
+ * tree.c (is_aggr_type_2): Remove.
+
+2003-07-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/11531
+ * typeck.c (check_return_expr): Fix thinko in diagnostic.
+
+2003-07-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10108
+ * pt.c (tsubst_decl) <TEMPLATE_DECL>: Add a check for
+ error_mark_node.
+
+2003-07-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11509
+ * pt.c (dependent_scope_ref_p): New function.
+ (value_dependent_expression_p): Use it.
+ (type_dependent_expression_p): Likewise.
+
+ * pt.c (tsubst_friend_function): Use reregister_specialization.
+
+ PR c++/7019
+ * cp-tree.h (lookup_qualified_name): Adjust prototype.
+ * decl.c (lookup_qualified_name): Add complain parameter. Adjust
+ call to is_aggr_type.
+ * parser.c (cp_parser_lookup_name): Adjust call to
+ lookup_qualified_name.
+ * pt.c (tsubst_qualified_id): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ * semantics.c (finish_qualified_id_expr): Deal with erroneous
+ expressions.
+
+2003-07-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/11510
+ * call.c (op_error): Properly format REALPART_EXPR and
+ IMAGPART_EXPR.
+ * error.c (dump_expr): Likewise.
+
+2003-07-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_expr): Handle EMPTY_CLASS_EXPR.
+
+2003-07-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/5293
+ * call.c (initialize_reference): Improve diagnostic.
+
+2003-07-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11154
+ * pt.c (more_specialized_class): Add full_args parameter.
+ (most_specialized_class): Adjust calls to more_specialized_class.
+ * cp-tree.h (more_specialized_class): Adjust declaration.
+
+2003-07-14 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * lex.c (enum tree_node_kind): Delete.
+
+2003-07-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11503
+ * cp-tree.h (DECL_SELF_REFERENCE_P): New macro.
+ (SET_DECL_SELF_REFERENCE_P): Likewise.
+ * class.c (build_self_reference): Use SET_DECL_SELF_REFERENCE_P.
+ * pt.c (tsubst_decl): Copy it.
+ * search.c (lookup_base): Use DECL_SELF_REFERENCE_P.
+
+ * pt.c (reregister_specialization): Fix thinko in previous change.
+
+ * cp-tree.h (cp_id_kind): New type.
+ (unqualified_name_lookup_error): Change prototype.
+ (unqualified_fn_lookup_error): New function.
+ (do_identifier): Remove.
+ (do_scoped_id): Likewise.
+ (tsubst_copy_and_build): Change prototype.
+ (reregister_specialization): New function.
+ (perform_koenig_lookup): Likewise.
+ (finish_id_expression): Likewise.
+ * call.c (build_method_call): Adjust call to
+ unqualified_name_lookup_error.
+ * decl.c (duplicate_decls): Use reregister_specialization.
+ * lex.c (is_global): Remove.
+ (unqualified_name_lookup_error): Return a value.
+ (do_identifier): Remove.
+ (do_scoped_id): Likewise.
+ (identifier_typedecl_value): Remove.
+ (unqualified_fn_lookup_error): New function.
+ * parser.c (cp_parser_id_kind): Remove.
+ (cp_parser_non_constant_id_expression): Remove.
+ (cp_parser_primary_expression): Use finish_id_expression.
+ (cp_parser_class_or_namespace_name): Use cp_id_kind, not
+ cp_parser_id_kind.
+ (cp_parser_postfix_expression): Use perform_koenig_lookup.
+ (cp_parser_template_argument): Use cp_id_kind.
+ (cp_parser_fold_non_dependent_expr): Adjust call to
+ tsubst_copy_and_build.
+ * pt.c (unregister_specialization): Rename to ...
+ (reregister_specialization): This.
+ (tsubst_friend_function): Use it.
+ (maybe_fold_nontype_arg): Adjust call to tsubst_copy_and_build.
+ (tsubst_qualified_id): Likewise.
+ (tsubst_expr): Likewise.
+ (tsubst_copy_and_build): Add function_p parameter. Use
+ finish_id_expression. Introduce RECUR macro.
+ (tsubst_non_call_postfix_expression): New function.
+ (regenerate_decl_from_template): Use reregister_specialization.
+ * semantics.c (perform_koenig_lookup): New function.
+ (finish_id_expression): Likewise.
+
+2003-07-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (push_access_scope_real): Remove.
+ (push_access_scope): Move code from push_access_scope_real.
+ (pop_access_scope): Don't check for TEMPLATE_DECL.
+ (instantiate_template): Defer access checking during template
+ substitution.
+ (regenerate_decl_from_template): Tidy.
+
+2003-07-11 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR c++/11437
+ * operators.def: Add definitions for __imag__, __real__.
+
+2003-07-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11050
+ * parser.c (cp_parser_expression_list): Rename to ...
+ (cp_parser_parenthesized_expression_list): ... here. Add attribute
+ parameter, parse the surounding parentheses.
+ (cp_parser_skip_to_closing_parenthesis): Add recover and or_comma
+ parameters. Return int.
+ (cp_parser_skip_to_closing_parenthesis or comma): Remove.
+ (cp_parser_postfix_expression): Adjust function call parsing.
+ (cp_parser_new_placement): Adjust.
+ (cp_parser_new_initializer): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_selection_statement): Likewise.
+ (cp_parser_mem_initializer): Likewise.
+ (cp_parser_asm_definition): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_declarator): Make
+ cdtor_or_conv_p an int ptr.
+ (cp_parser_direct_declarator): Likewise. Check for a parameter
+ list on cdtors & conv functions.
+ (cp_parser_initializer): Adjust.
+ (cp_parser_member_declaration): Adjust.
+ (cp_parser_attribute_list): Move code into
+ cp_parser_parens_expression_list.
+ (cp_parser_functional_cast): Adjust.
+ * pt.c (type_dependent_expression_p): Erroneous expressions are
+ non-dependent.
+
+2003-07-11 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (cp_finish_decl): Handle 'used' attribute.
+
+ * cp-lang.c (c_reset_state): New dummy routine.
+ * cp-tree.h (finish_file): Move prototype to c-common.h.
+ * parser.c (c_parse_file): Rename from yyparse; don't call finish_file.
+
+2003-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8327
+ * pt.c (tsubst_qualified_id): Implement suggested resolution for
+ Core Issue 2.
+ (type_dependent_expression_p): Likewise.
+
+2003-07-10 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_binary_op): Do not warn about signed
+ vs. unsigned comparisons in the bodies of templates.
+
+ PR c++/9411
+ * parser.c (cp_parser_postfix_expression): Check dependency of
+ functions.
+
+2003-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10032
+ * decl.c (cxx_init_decl_processing): With -pedantic, pedwarns are
+ still errors.
+
+ PR c++/10527
+ * error.c (decl_to_string): Do not print default argument
+ expressions.
+
+ * cp-tree.h (break_out_calls): Remove declaration.
+ * tree.c (break_out_calls): Remove.
+ * typeck.c (build_modify_expr): Avoid invalid sharing of trees.
+
+2003-07-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++ 9483
+ * class.c (check_field_decls): Pass DECL_NAME to constructor_name_p.
+ * decl2.c (constructor_name_p): Avoid repeated constructor_name
+ calls.
+ * decl.c (grokdeclarator): Refactor ctor/dtor detection.
+
+2003-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_x_unary_op): Take note of the fact that
+ PREINCREMENT_EXPR and POSTINCREMENT_EXPR are binary operations on
+ trees.
+
+ * parser.c (cp_parser_primary_expression): Preserve the form of
+ qualified expressions in templates, even if they are not
+ dependent.
+ * pt.c (convert_nontype_argument): Handle non-dependent SCOPE_REFs.
+ (tsubst_qualified_id): Likewise.
+ * search.c (accessible_p): Treat everything in the body of a
+ template as accessible.
+
+2003-07-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (NON_DEPENDENT_EXPR): New node.
+ * cp-tree.h (build_call_from_tree): Remove.
+ (build_member_call): Likewise.
+ (dependent_template_arg_p): Remove.
+ (any_dependent_template_arguments_p): New function.
+ (dependent_template_id_p): Likewise.
+ (any_type_dependent_arguments_p): Likewise.
+ (build_non_dependent_expr): Likewise.
+ (build_non_dependent_args): Likewise.
+ (build_x_compound_expr): Adjust prototype.
+ * call.c (build_new_method_call): Handle non-dependent expressions
+ correctly.
+ * decl2.c (grok_array_decl): Likewise.
+ (build_offset_ref_call_from_tree): Likewise.
+ (build_call_from_tree): Remove.
+ * error.c (dump_decl): Handle NON_DEPENDENT_EXPR.
+ (dump_expr): Likewise.
+ * init.c (build_member_call): Remove.
+ * mangle.c (write_expression): Update handling for template-ids.
+ * parser.c (cp_parser_primary_expression): Use
+ any_dependent_template_arguments_p. Update constant-expression
+ handling.
+ (cp_parser_postfix_expression): Use
+ any_type_dependent_arguments_p. Simplify call processing.
+ (cp_parser_unary_expression): Simplify.
+ (cp_parser_expression): Adjust for changes to
+ build_x_compound_expr.
+ (cp_parser_template_argument): Implement standard-conforming
+ parsing of non-type template arguments.
+ (cp_parser_direct_declarator): Use
+ cp_parser_fold_non_dependent_expr.
+ (cp_parser_fold_non_dependent_expr): New function.
+ (cp_parser_next_token_ends_template_argument_p): Likewise.
+ * pt.c (convert_template_argument): Do not call
+ maybe_fold_nontype_arg.
+ (tsubst_baselink): Likewise.
+ (tsubst_copy_and_build): Share common code. Make sizeof/alignof
+ processing work correctly for non-dependent expressions. Adjust
+ handling of COMPOUND_EXPR. Simplify call processing.
+ (value_dependent_expression_p): Deal with functional casts and
+ sizeof/alignof correctly.
+ (type_dependent_expression_p): Handle overloaded functions.
+ (any_type_dependent_arguments_p): New function.
+ (any_dependent_template_arguments_p): Likewise.
+ (dependent_template_p): Treat SCOPE_REFs as dependent.
+ (dependent_template_id_p): Simplify.
+ (build_non_dependent_expr): New function.
+ (build_non_dependent_args): Likewise.
+ * semantics.c (finish_stmt_expr): Don't make dependent
+ statement-expresions have void type.
+ (finish_call_expr): Handle non-dependent expressions
+ correctly.
+ * tree.c (lvalue_p_1): Treat NON_DEPENDENT_EXPRs as lvalues.
+ * typeck.c (cxx_sizeof_or_alignof_type): Give the expression
+ type size_t, even in templates.
+ (expr_sizeof): Likewise.
+ (finish_class_member_access_expr): Handle non-dependent expressions
+ correctly.
+ (build_x_indirect_ref): Likewise.
+ (build_x_binary_op): Likewise.
+ (build_x_unary_op): Likewise.
+ (build_x_conditional_expr): Likewise.
+ (build_x_compound_expr): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2003-07-09 Jan Hubicka <jh@suse.cz>
+
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New.
+ * decl.c (duplicate_decls): Use DECL_ESTIMATED_INSNS.
+ (start_function): Use DECL_ESTIMATED_INSNS.
+ * optimize.c (maybe_clone_body): Use DECL_ESTIMATED_INSNS.
+
+ * decl2.c (maybe_emit_vtables): Fix marking vtables as needed in
+ unit-at-a-time
+
+2003-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11030
+ * pt.c (instantiate_class_template): Don't call xref_tag to
+ inject name when the friend class is a specialization.
+
+2003-07-07 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (build_scoped_method_call): Remove.
+ (lookup_qualified_name): Remove parameter.
+ (tsubst_copy_and_build): Declare.
+ (finish_qualified_object_call_expr): Remove.
+ (check_accessibility_of_qualified_id): New function.
+ (finish_qualified_id_expr): Likewise.
+ (non_reference): Likewise.
+ (build_expr_from-tree): Remove.
+ * call.c (non_reference): Remove.
+ (build_scoped_method_call): Likewise.
+ (build_method_call): Use error_operand_p. Assert that we are not
+ processing a template.
+ (standard_conversion): Use non_reference.
+ * class.c (build_vtbl_entry_ref): Likewise.
+ (build_vtbl_ref_1): Likewise.
+ * cvt.c (build_expr_type_conversion): Use non_reference.
+ * decl.c (lookup_qualified_name): Remove flags parameter.
+ (grok_op_properties): Use non_reference.
+ * decl2.c (grok_array_decl): Likewise.
+ (build_expr_from_tree): Remove.
+ (build_offset_ref_call_from_tree): Update comment.
+ * error.c (parm_to_string): Call reinit_global_formatting_buffer.
+ * except.c (prepare_eh_types): Use non_reference.
+ (can_convert_eh): Likewise.
+ * init.c (build_dtor_call): Avoid using build_method_call.
+ * mangle.c (write_template_param): Remove misleading comment.
+ * method.c (locate_copy): Use non_reference.
+ * parser.c (cp_parser_scope_through_which_access_occurs): Remove.
+ (cp_parser_primary_expression): Do not create SCOPE_REFs is
+ non-dependent contexts.
+ (cp_parser_postfix_expression): Use finish_qualified_id_expr.
+ (cp_parser_direct_declarator): Use tsubst_copy_and_build, not
+ build_expr_from_tree.
+ (cp_parser_lookup_name): Adjust call to lookup_qualified_name.
+ Use check_accessibility_of_qualified_id.
+ * pt.c (maybe_fold_nontype_arg): Use tsubst_copy_and_build, not
+ build_expr_from_tree.
+ (tsubst_baselink): New function.
+ (tsubst_qualified_id): Likewise.
+ (tsubst_copy): Use them. Remove support for METHOD_CALL_EXPR.
+ (tsubst_expr): Adjust call to lookup_qualified_name.
+ (tsubst_copy_and_build): Handle SCOPE_REFs specially. Adjust
+ handling of CALL_EXPRs.
+ (value_dependent_expression_p): Use INTEGRAL_OR_ENUMERATION_TYPE_P.
+ * rtti.c (get_tinfo_decl_dynamic): Use non_reference.
+ * search.c (check_final_overrider): Likewise.
+ * semantics.c (check_accessibility_of_qualified_id): New function.
+ (finish_qualified_object_call_expr): Remove.
+ * typeck.c (target_type): Use non_reference.
+ (cxx_sizeof_or_alignof_type): Likewise.
+ (dubious_conversion_warnings): Likewise.
+ (convert_for_initialization): Likewise.
+ (non_reference): New function.
+
+2003-07-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (print_binding_level, print_other_binding_stack,
+ print_binding_stack): Merge uses of HOST_PTR_PRINTF with adjacent
+ stdio calls.
+ * ptree.c (cxx_print_decl, cxx_print_binding): Likewise.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * friend.c: Convert to ISO C90 prototypes.
+
+ * Make-lang.in ($(srcdir)/cp/cfns.h): Use ANSI-C as output
+ language.
+ * cfns.h: Regenerate.
+
+ * typeck.c: Convert remaining prototypes to ISO C90.
+ * search.c: Likewise.
+
+ * decl2.c (build_expr_from_tree): Convert prototype to ISO C90.
+ * semantics.c (expand_or_defer_fn): Likewise
+ * mangle.c (discriminator_for_string_literal): Likewise.
+ * g++spec.c (lang_specific_driver): Likewise.
+
+ * search.c (lookup_base_r): Remove unused variable.
+
+2003-07-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c: (genrtl_try_block) Adjust emit_line_note
+ calls.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * search.c (lookup_base_r): Remove unused variable.
+
+2003-07-06 Michael Chastain <mec@shout.net>
+
+ PR debug/10055
+ * lex.c (cxx_init): Call push_srcloc and pop_srcloc rather than
+ assigning to input_filename directly.
+
+2003-07-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * error.c: Likewise.
+ * method.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * typeck.c: Likewise.
+
+2003-07-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11345
+ * search.c (lookup_base_r): Remove is_non_public and
+ within_current_scope parameters. Remove other dead code.
+ (lookup_base): Adjust call to lookup_base_r.
+ (adjust_result_of_qualified_name_lookup): Improve comment.
+ * semantics.c (finish_call_expr): Use maybe_dummy_object.
+
+2003-07-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_HANDLE_FILENAME,
+ LANG_HOOKS_MISSING_ARGUMENT): Override.
+
+2003-07-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11431
+ * typeck.c (build_static_cast): Check for reference conversions
+ earlier.
+
+2003-07-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (perform_integral_promotions): Declare.
+ * call.c (build_addr_func): Use decay_conversion.
+ (convert_arg_to_ellipsis): Likewise. Remove misleading comment.
+ (convert_for_arg_passing): Use perform_integral_promotions.
+ * cvt.c (build_expr_type_conversion): Use decay_conversion.
+ (type_promotes_to): Do not return a cv-qualified type.
+ * decl.c (grok_reference_init): Fix formatting.
+ (get_atexit_node): Use decay_conversion.
+ (build_enumerator): Use perform_integral_promotions.
+ * init.c (build_vec_init): Use decay_conversion.
+ * semantics.c (finish_expr_stmt): Likewise.
+ (finish_switch_cond): Use perform_integral_promotions.
+ * typeck.c (default_conversion): Likewise.
+ (perform_integral_promotions): New function.
+ (build_indirect_ref): Use decay_conversion.
+ (build_array_ref): Use perform_integral_promotions.
+ (convert_arguments): Use decay_conversion.
+ (build_unary_op): Use perform_integral_promotions.
+ (build_c_cast): Use decay_conversion.
+ (build_modify_expr): Likewise.
+ (convert_for_initialization): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2003-07-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment typos.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * decl2.c: Likewise.
+ * decl.c: Likewise.
+ * init.c: Likewise.
+ * mangle.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2003-07-04 Zack Weinberg <zack@codesourcery.com>
+
+ * parser.c (cp_lexer_read_token): No need to handle string
+ constant concatenation.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (GCC_DIAG_STYLE, ATTRIBUTE_GCC_CXXDIAG): Define.
+ (cp_error_at, cp_warning_at, cp_pedwarn_at): Mark with
+ ATTRIBUTE_GCC_CXXDIAG.
+
+2003-07-03 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_addr_func): Handle bound pointers-to-members.
+ (build_method_call): Do not call resolve_offset_ref.
+ (implicit_conversion): Likewise.
+ (resolve_scoped_fn_name): Use finish_non_static_data_member, not
+ resolve_offset_ref.
+ (resolve_args): Do not call resolve_offset_ref.
+ (build_conditional_expr): Likewise.
+ (build_new_method_call): Likewise.
+ * cp-tree.def (OFFSET_REF): Update documentation.
+ * cvt.c (cp_convert_to_pointer): Update handling of conversions from
+ pointers to members to pointers.
+ (ocp_convert): Do not call resolve_offset_ref.
+ (convert_to_void): Likewise.
+ (build_expr_type_conversion): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+ * init.c (resolve_offset_ref): Simplify greatly.
+ (build_vec_delete): Do not call resolve_offset_ref.
+ * parser.c (cp_parser_postfix_expression): Call resolve_offset_ref
+ if appropriate.
+ (cp_parser_unary_expression): Use
+ cp_parser_simple_cast_expression.
+ (cp_parser_delete_expression): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_pm_expression): Use cp_parser_binary_op.
+ (cp_parser_simple_cast_expression): New function.
+ * rtti.c (build_dynamic_cast_1): Do not call resolve_offset_ref.
+ * semantics.c (finish_increment_expr): Likewise.
+ (finish_typeof): Likewise.
+ * tree.c (lvalue_p_1): Do not handle OFFSET_REF.
+ * typeck.c (require_complete_type): Do not handle OFFSET_REFs.
+ (decay_conversion): Do not call resolve_offset_ref.
+ (finish_class_member_access_expr): Likewise.
+ (convert_arguments): Likewise.
+ (build_x_binary_op): Handle DOTSTAR_EXPR.
+ (condition_conversion): Do not call resolve_offset_ref.
+ (unary_complex_lvalue): Likewise.
+ (build_static_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (build_c_cast): Likewise.
+ (build_modify_expr): Likewise.
+ (convert_for_assignment): Likewise.
+ (convert_for_initialization): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+ (build_m_component_ref): Simplify.
+
+ * call.c (build_scoped_method_call): Use convert_to_void.
+ (build_method_call): Likewise.
+ * class.c (check_field_decls): Remove dead code.
+ * cvt.c (convert_from_reference): Remove OFFSET_TYPE handling.
+ * decl2.c (grok_array_decl): Remove dead code.
+ (arg_assoc_type): Avoid relying on POINTER_TYPE over OFFSET_TYPE
+ as pointer-to-member representation.
+ * init.c (build_offset_ref): Tidy.
+ (build_vec_delete_1): Use convert_to_void.
+ * mangle.c (write_type): Avoid relying on POINTER_TYPE over OFFSET_TYPE
+ as pointer-to-member representation.
+
+2003-07-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9162
+ * decl.c (grokdeclarator): Return friend decls, not
+ void_type_node.
+ * decl2.c (grokfield): Alter friend decl check.
+ * parser.c (struct cp_parser): Document default_arg chain on
+ unparsed_functions_queue.
+ (cp_parser_save_default_args): New.
+ (cp_parser_init_declarator, cp_parser_function_definition,
+ cp_parser_member_declaration): Call it.
+ (cp_parser_class_specifier): Remove unused variable. Alter
+ processing of unparsed_functions_queue.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (add_method, check_field_decl): Fix format specifier.
+ * decl.c (duplicate_decls, pushdecl, check_goto,
+ fixup_anonymous_aggr, maybe_commonize_var, grokdeclarator,
+ start_enum): Likewise.
+ * decl2.c (ambiguous_decl): Likewise.
+ * pt.c (redeclare_class_template): Likewise.
+
+2003-07-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10219
+ * pt.c (type_unification_real): Don't unify exprs of error type.
+ * tree.c (error_type): Don't die on error_type.
+
+ PR c++/9779
+ * decl2.c (arg_assoc_class): Don't die on NULL type.
+ * typeck.c (type_unknown_p): Don't die on untyped expressions.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6949
+ * decl2.c (grokfield): Create TEMPLATE_DECLs for methods in local
+ classes.
+
+2003-07-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (locate_error): %P takes an `int', not a `tree'.
+
+2003-07-02 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (defer_fn): Set DECL_DEFER_OUTPUT.
+ (finish-file): Do not process function with DECL_DEFER_OUTPUT clear;
+ clear DECL_DEFER_OUTPUT once function is processed; avoid flags
+ massaging.
+
+ * cp-tree.h (DECL_NEEDED_P): Support unit-at-a-time
+ (expand_or_defer_fn): Declare.
+ (lower_function): Declare.
+ * decl.c (start_cleanup_fn): Use expand_or_defer_fn.
+ * decl2.c: Include cgraph.h and varpool.h
+ (maybe_emit_vtables): Make explicit instantations as needed.
+ (mark_member_pointers, lower_function): New functions.
+ (finish_file): Do unit-at-a-time.
+ * method.c (synthesize_method): Use expand_or_defer_fn.
+ * optimize.c (maybe_clone_body): Use expand_or_defer_fn.
+ * parser.c (cp_parser_function_definition_after_decl): Use
+ expand_or_defer_fn.
+ * pt.c (instantiate_decl): Likewise.
+ * semantics.c: Include cgraph.h
+ (expand_or_defer_fn): Break out from ...
+ (expand_body): ... here; deal with unit-at-a-time.
+ * cp-lang.c (LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION,
+ LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION): Define.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (resolve_scoped_fn_name): Return error_mark_node for
+ erroneous cases.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11149
+ * call.c (resolve_scoped_fn_name): Check that the qualifying scope
+ is a class type.
+
+2003-07-01 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/8046
+ * error.c (dump_decl): Handle BIT_NOT_EXPR as
+ pseudo destructor calls.
+
+2003-07-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (define_label): Replace filename and lineno
+ arguments with a location_t.
+ * decl.c (pop_label): Adjust define_label call.
+ (define_label): Replace filename and lineno arguments with a
+ location_t.
+ * semantics.c (finish_label): Adjust define_label call.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9559
+ * decl2.c (grokfield): Do not build NOP_EXPRs around the
+ error_mark_node.
+
+2003-06-30 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Update.
+ * cp-lang.c (c_language): Define.
+ (LANG_HOOKS_INIT_OPTIONS): Use common hook.
+ * cp-tree.h (cxx_init_options): Remove.
+ * lex.c: Don't include diagnostic.h.
+ (cxx_init_options): Remove.
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/4933
+ * error.c (dump_expr): Support correctly the COMPOUND_EXPR
+ tree generated within a template. Use dump_expr to dump an
+ expression sizeof.
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ * mangle.c (write_expression): Exit gracefully when trying to
+ mangle a CALL_EXPR.
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/10750
+ * parser.c (cp_parser_primary_expression): A VAR_DECL with a
+ (value- or type-) dependent expression as DECL_INITIAL is a
+ valid constant-expression (at parser time).
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/11106
+ * error.c (dump_decl): Call dump_decl to dump the DECL_NAME for a
+ USING_DECL, instead of print_tree_identifier.
+
+2003-06-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (language_to_string): Adjust declaration.
+ * dump.c (cp_dump_tree): Adjust usage.
+ * error.c (dump_char): Use output_formatted_scalar. Tidy.
+ (parm_to_string): Lose unused parameter. Tidy.
+ (expr_to_string): Likewise.
+ (code_to_string): Likewise.
+ (language_to_string): Likewise.
+ (op_to_string): Likewise.
+ (assop_to_string): Likewise.
+ (digit_buffer): Remove.
+ (dump_type): Format builtin vector type as __vector__.
+
+2003-06-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (print_integer): Remove.
+ (dump_type_suffix): Adjust.
+ (dump_expr): Likewise.
+
+2003-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (print_instantiation_partial_context): Take a
+ location_t.
+ (print_instantiation_full_context): Adjust.
+ (print_instantiation_context): Adjust.
+
+ * cp-tree.h (cp_line_of, cp_file_of): Remove.
+ * error.c (cp_line_of, cp_file_of): Merge into ...
+ (location_of): ... here. Make static, return a location_t.
+ (cp_error_at, cp_warning_at, cp_pedwarn_at): Adjust.
+
+2003-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10784
+ * call.c (joust): Move warn_conversion check outwards.
+
+2003-06-27 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (build_typename_type)
+ * mangle.c (write_template_template_arg)
+ * parser.c (cp_parser_scope_through_which_access_occurs)
+ * pt.c (push_access_scope_real, push_access_scope, pop_access_scope)
+ * repo.c (get_base_filename)
+ * semantics.c (maybe_convert_cond):
+ Mark the definition static, matching the forward declaration.
+
+2003-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10468
+ * pt.c (tsubst): Handle qualified TYPEOF_TYPEs correctly.
+
+2003-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10796
+ * decl.c (finish_enum): Implement DR377.
+
+ * decl.c (cp_finish_decl): Don't make variables with reference
+ type readonly while they are being initialized.
+
+2003-06-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11332
+ * typeck.c (build_static_cast): Avoid returning expressions with
+ reference type.
+
+2003-06-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_op_delete_call): Use strip_array_call. Correct
+ error message to say 'delete' or 'delete[]'.
+
+2003-06-26 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/8266
+ * pt.c (check_explicit_specialization): When looking up a
+ template function from an identifier outside class-scope, bind
+ it to CP_DECL_CONTEXT.
+
+2003-06-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10990
+ * search.c (lookup_base_r): Rely on accessible_p, rather than
+ trying to emulate that logic here.
+
+ PR c++/10931
+ * call.c (convert_like): Pass issue_conversion_warnings.
+ (convert_like_with_context): Likewise.
+ (convert_like_real): Add issue_conversion_warnings parameter.
+ (perform_direct_initialization_if_possible): New function.
+ * cp-tree.h (perform_direct_initialization_if_possible): Declare it.
+ * typeck.c (check_for_casting_away_constness): New function.
+ (build_static_cast): Rewrite.
+
+2003-06-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (enforce_access): Assert we get a binfo.
+ (build_op_delete_call): Pass a binfo to
+ perform_or_defer_access_check.
+ * class.c (alter_access): Likewise.
+ * decl.c (make_typename_type): Likewise.
+ (make_unbound_class_template): Likewise.
+ * lex.c (do_identifier): Likewise.
+ * method.c (hack_identifier): Likewise.
+ * parser.c (cp_parser_lookup_name): Likewise.
+ * search.c (lookup_member): Likewise. Move IDENTIFIER_CLASS_VALUE
+ test.
+ * semantics.c (finish_non_static_data_member): Likewise.
+ (perform_or_defer_access_check): Expect a binfo.
+ * typeck.c (comptypes): Expect types.
+
+ * mangle.c (find_substitution): Don't pass a non-type to same_type_p
+ * friend.c (make_friend_class): Likewise.
+ * pt.c (check_default_tmpl_args): Likewise.
+ (lookup_template_class): Likewise.
+
+2003-06-24 Jan Hubicka <jh@suse.cz>
+
+ * method.c (thunk_labelno): Move outside ifdef block to make garbage
+ collector happy.
+
+2003-06-24 Jan Hubicka <jh@suse.cz>
+
+ * class.c (build_vtable): Make vtables.
+ * cp-tree.h (DECL_VTABLE_OR_VTT_P): New macro.
+ * decl2.c (output_vtable_inherit): Rename to ...
+ (prepare_assemble_variable): ... this one; change interface.
+ (maybe_emit_vtables): Do not call output_vtable_inherit.
+ * cp-lang.c (LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE): Define.
+ * cp-tree.h (prepare_assemble_variable): New.
+
+2003-06-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * method.c: add prototype for make_alias_for_thunk.
+ (thunk_labelno, make_alias_for_thunk): only define
+ if ASM_OUTPUT_DEF is defined.
+
+2003-06-23 Jakub Jelinek <jakub@redhat.com>
+
+ * method.c (thunk_labelno): New variable.
+ (make_alias_for_thunk): New function.
+ (use_thunk): Use it if defined ASM_OUTPUT_DEF. Put the thunk
+ into the same section as the function it is calling.
+ Include gt-cp-method.h.
+ * Make-lang.in (gt-cp-method.h): Depend on s-gtype.
+ (cp/method.o): Depend on gt-cp-method.h.
+ * config-lang.in (gtfiles): Add $(srcdir)/cp/method.c.
+
+2003-06-23 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (register_dtor_fn): Mark cleanup as used.
+ * decl2.c (mark_vtable_entries): Skip nops.
+ * rtti.c (get_tinfo_ptr): Mark tinfo as used.
+ (build_dynamic_cast_1): Likewise.
+ (tinfo_base_init): Likewise.
+ (emit_tinfo_decl): Likewise.
+
+2003-06-23 Jakub Jelinek <jakub@redhat.com>
+
+ * mangle.c (hash_type): Val is the TREE_LIST itself, not a pointer
+ to it.
+
+2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10784
+ * call.c (joust): Warn about choosing conversion sequence only if
+ -Wconversion.
+
+2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10864
+ * call.c (op_error): Tidy.
+ * error.c (dump_expr): Properly format 'T()' when T is an
+ aggregate type.
+
+2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10915
+ * decl.c (grok_op_properties): Warn possible confusing conversion
+ only if -Wconversion.
+
+2003-06-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10749
+ * parser.c (cp_parser_class_head): See through dependent names
+ when parsing a class-head.
+
+ PR c++/10845
+ * pt.c (try_class_unification): Correct handling of member class
+ templates.
+
+2003-06-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c (genrtl_finish_function): Adjust
+ expand_function_end call.
+
+2003-06-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10939
+ * pt.c (tsubst_decl): Do not try to substitute into non-dependent
+ functions.
+ (value_dependent_expression_p): Correct logic for FUNCTION_DECLs.
+
+ PR c++/9649
+ * cp-tree.h (pushdecl_class_level): Change prototype.
+ (push_class_level_binding): Likewise.
+ * decl.c (add_binding): Reject duplicate static data members.
+ (pushdecl_class_level): Return a value indicating whether or not
+ the binding was valid.
+ (push_class_level_binding): Likewise.
+ * semantics.c (finish_member_declaration): Don't keep invalid
+ declarations.
+
+ PR c++/11041
+ * call.c (initialize_reference): Do not use cp_finish_decl to emit
+ temporary variables.
+ * cp-tree.h (static_aggregates): Declare.
+ (pushdecl_top_level_and_finish): Likewise.
+ * decl.c (pushdecl_top_level_1): New function.
+ (pushdecl_top_level): Use it.
+ (pushdecl_top_level_and_finish): New function.
+ (initialize_local_var): Remove redundant code.
+ (cp_finish_decl): Remove support for RESULT_DECLs. Don't check
+ building_stmt_tree.
+ * decl.h (static_aggregates): Remove.
+ * decl2.c (get_guard): Use pushdecl_top_level_and_finish.
+ * rtti.c (get_tinfo_decl): Use pushdecl_top_level_and_finish.
+ (tinfo_base_init): Likewise.
+
+2003-06-19 Matt Austern <austern@apple.com>
+
+ PR c++/11228
+ * init.c (build_zero_init): Assert that number of array elements
+ is an integer constant.
+ (build_default_init) Don't use build_zero_init for arrays with
+ variable number of elements.
+
+2003-06-19 Andreas Jaeger <aj@suse.de>
+
+ * cp-tree.h: Remove duplicated declarations.
+
+2003-06-18 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * pt.c: Convert to ISO C.
+ * semantics.c: Convert to ISO C.
+
+2003-06-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (comp_except_specs, compparms, cp_has_mutable_p,
+ at_least_as_qualified_p, more_qualified_p): Return bool.
+ * typeck.c: ANSIFY function definitions.
+ (comp_array_types): Take redeclaration bool parameter.
+ (comptypes): Rearrange STRICT handling.
+ (at_least_as_qualified_p, more_qualified_p,
+ comp_cv_qualification): Cache cv quals.
+ (compparms): Rearrange loop.
+
+2003-06-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (COMPARE_RELAXED): Rename to ...
+ (COMPARE_DERIVED): ... here. Adjust comment.
+ (resolve_typename_type_in_current_instantiation): Remove.
+ (cp_tree_equal, comptypes): Return a bool.
+ * cvt.c (convert_to_reference): Adjust comptypes call.
+ * pt.c (template_args_equal, unify,): Adjust cp_tree_equal call.
+ (resolve_typename_type_in_current_instantiation): Remove.
+ * tree.c (cp_tree_equal): Return bool. Cope with TEMPLATE_DECLs and
+ IDENTIFIER_NODEs. Abort if undeciderable. Adjust recursive
+ calls. Refactor code.
+ * typeck.c (comp_array_types): Return bool. Lose callback.
+ parameter. Adjust cp_tree_equal calls.
+ (comptypes): Return bool. Adjust strict handling. Remove relaxed
+ enumeration and java type handling. Deal with typename types here.
+ Adjust recursive and cp_tree_equals calls. Adjust base and derived
+ checking.
+ (comp_target_types): Remove unreachable code. Adjust
+ same_or_base_type_p calls.
+ (ptr_reasonably_similar): Adjust base and derived check.
+
+ * typeck.c (maybe_warn_about_returning_address_of_local): Remove
+ unused calculation.
+ (check_return_expr): Adjust error messages.
+ * cp-tree.def (SCOPE_REF): Correct comment.
+
+2003-06-17 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (mangle_conv_op_name_for_type): Correct sprintf format
+ string again.
+
+2003-06-17 Robert Abeles <rabeles@archaelogic.com>
+
+ * optimize.c (dump_function): Form complete flag name by
+ prefixing 'fdump-' to string returned by dump_flag_name().
+
+2003-06-17 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (mangle_conv_op_name_for_type): Correct sprintf format
+ string.
+
+2003-06-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/10929
+ * decl.c (grokfndecl): Don't mark a function inline for
+ -finline-functions if it isn't defined.
+
+2003-06-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10712
+ * class.c (handle_using_decl): Robustify.
+
+ PR c++/11105
+ * cp-tree.h (DECL_CONV_FN_TYPE): New method.
+ * mangle.c (struct globals): Remove internal_mangling_p.
+ (write_unqualified_name): Use DECL_CONV_FN_TYPE.
+ (write_template_parm): Don't write out the level number.
+ (conv_type_names): New variable.
+ (hash_type): New function.
+ (compare_type): Likewise.
+ (mangle_conv_op_name_for_type): Don't try to mangle conversion
+ operator names.
+ * search.c (lookup_conversion_operator): New function.
+ (lookup_fnfields_1): Use it.
+
+2003-06-17 Andreas Jaeger <aj@suse.de>
+
+ * except.c: Remove duplicate declaration of push_eh_cleanup.
+
+ * call.c: Remove extra declaration of inhibit_warnings.
+
+2003-06-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ 2003-06-16 Jens-Michael Hoffmann <jensmh@gmx.de>
+ * mangle.c: Convert to ISO C.
+
+2003-06-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp/decl.c, cp/pt.c, cp/search.c, cp/tree.c: Don't use the PTR
+ macro.
+
+2003-06-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * tree.c: Convert to ISO C.
+
+2003-06-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h: Follow spelling conventions.
+ * mangle.c: Likewise.
+ * method.c: Likewise.
+ * parser.c: Likewise.
+
+2003-06-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (start_function): Adjust init_function_start call.
+ * method.c (use_thunk): Likewise.
+ * semantics.c (genrtl_start_function): Likewise.
+
+2003-06-14 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Remove c-options.o.
+
+2003-06-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * lex.c: Convert to ISO C.
+
+ 2003-05-19 Jens-Michael Hoffmann <jensmh@gmx.de>
+ * init.c: removes use of PARAMS macro. Use ISO style function
+ declarations. (Not copyright-significant change.)
+
+ * rtti.c: Remove PARAMS.
+
+ * typeck2.c: Convert to ISO C.
+
+2003-06-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10635
+ * typeck.c (build_c_cast): Check that the destination type is
+ complete.
+
+2003-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10432
+ * cp-tree.h (finish_declarator): Remove.
+ * decl.c (cp_finish_decl): Make sure to pop_nested_class even for
+ erroneous declarations.
+ * semantics.c (finish_declarator): Remove.
+
+2003-06-11 Roger Sayle <roger@eyesopen.com>
+
+ * decl2.c (generate_ctor_or_dtor_function): Avoid expanding a
+ global static constructor/destructor if it will be empty, i.e.
+ either doesn't call any ctors/dtors or only calls pure or const
+ ctors/dtors.
+
+2003-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (tm_p.h): Include it.
+ * Make-lang.in (cp/mangle.o): Depend on $(TM_P_H).
+
+ PR c++/11131
+ * tree.c (cp_cannot_inline_fn): Check for "inline" before
+ instantiation.
+
+2003-06-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/10968
+ * pt.c (mark_decl_instantiated): Clear DECL_COMDAT.
+
+2003-06-10 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * decl.c (start_cleanup_fn): Move static 'counter' out, mark with GTY.
+ (start_cleanup_cnt): New.
+
+2003-06-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11131
+ * cp-tree.h (template_for_substitution): Declare.
+ * decl2.c (mark_used): Use it when figuring out whether or not a
+ function is inline.
+ * pt.c (template_for_substitution): Give it external linkage.
+ * tree.c (cp_cannot_inline_tree_fn): Instantiate as early as
+ possible.
+
+2003-06-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR 8861
+ * mangle.c (write_real_cst): New function. Implement
+ ABI-compliant mangling of floating-point literals when
+ -fabi-version>=2; provide backward compatibility with 3.3 when
+ -fabi-version=1 (with warning). Clarify commentary.
+ (write_template_arg_literal): Use write_real_cst.
+
+2003-06-07 Andreas Jaeger <aj@suse.de>
+
+ * cp/decl.c (xref_tag): Remove undefined macro NONNESTED_CLASSES.
+
+2003-06-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_DECODE_OPTON): Drop.
+ (LANG_HOOKS_HANDLE_OPTION): Override.
+ * cp-tree.h (cxx_init_options): Update.
+ * lex.c (cxx_init_options): Update.
+
+2003-06-05 Jan Hubicka <jh@suse.cz>
+
+ * Make-lang.in: Add support for stageprofile and stagefeedback
+
+2003-06-04 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * decl.c (grokdeclarator): Error_mark_node in, error_mark_node out.
+
+2003-06-04 Andreas Jaeger <aj@suse.de>
+
+ * g++spec.c (lang_specific_driver): Remove ALT_LIBM usage.
+
+2003-06-03 Jason Merrill <jason@redhat.com>
+
+ * cp/cp-tree.h (CP_AGGREGATE_TYPE_P): Accept vectors.
+
+ * cp/decl.c (reshape_init): Handle vectors.
+
+ * testsuite/g++.dg/init/array10.C: New.
+
+2003-06-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10940
+ * pt.c (check_explicit_specialization): Check for 'static'
+ earlier.
+
+2003-05-31 Diego Novillo <dnovillo@redhat.com>
+
+ * class.c (dump_array): Call CONSTRUCTOR_ELTS to access
+ the operand of a CONSTRUCTOR node.
+
+2003-05-31 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (cp_binding_level::this_entity): Rename from this_class.
+ (cxx_scope_descriptor): New function.
+ (cxx_scope_debug): Likewise.
+ (push_binding_level): Use it.
+ (pop_binding_level): Likewise.
+ (suspend_binding_level): Likewise.
+ (resume_binding_level): Likewise.
+ (pushlevel_class): Adjust use of this_class.
+ (pushtag): Likewise.
+ (lookup_name_real): Likewise.
+ (global_scope_name): New variable.
+ (initialize_predefined_identifiers): Initialize it.
+ (push_namespace): Use it.
+ (make_cxx_scope): New function.
+ (pushlevel): Use it.
+ (pushlevel_class): Likewise.
+ (push_binding_level): Simplify. Loose the last two arguments.
+ (make_binding_level): Remove.
+ (initial_push__namespace_scope): New function.
+ (push_namespace): Use it. Simplify.
+ (cxx_init_decl_processing): Likewise.
+ (declare_namespace_level): Remove.
+
+2003-05-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10956
+ * pt.c (instantiate_decl): Don't use full template arguments if
+ we are dealing with specializations.
+
+2003-05-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (ENABLE_SCOPE_CHECKING): Rename from DEBUG_BINDING_LEVELS.
+ (binding_depth): Unconditionally define.
+ (is_class_level): Likewise.
+ (indent): Likewise. Take an indenting parameter.
+ (push_binding_level): Remove conditional definittion.
+ (pop_binding_level): Likewise.
+ (suspend_binding_level): Likewise.
+ (resume_binding_level): Likewise.
+ (pushlevel): Likewise.
+ (pushlevel_class): Likewise.
+ (poplevel_class): Likewise.
+ (pop_everything): Likewise.
+
+2003-05-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.h (global_scope_p): New macro.
+ * decl.c (pop_binding_level): Use it. Don't refer directly to
+ global_binding_level.
+ (suspend_binding_level): Likewise.
+ (global_bindings_p): Likewise.
+ (print_other_binding_stack): Likewise.
+ (print_binding_stack): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (pushdecl_namespace_level): Likewise.
+ (cxx_init_decl_processing): Likewise.
+ (start_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (start_function): Likewise.
+ (global_binding_level): Remove.
+
+2003-05-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * parser.c (cp_parser_explicit_instantiation): Restore old
+ access before template instantiation.
+
+2003-05-23 Geoffrey Keating <geoffk@apple.com>
+
+ * lang-specs.h: Use -o to specify preprocessor's output file.
+ Make -no-integrated-cpp work when building PCH files.
+
+2003-05-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10682
+ * pt.c (instantiate_class_template): Use DECL_ARTIFICIAL to
+ check for implicitly created typedef to an enum.
+
+2003-05-21 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_vec_delete): Copy the address into a temporary
+ variable before calling build_vec_delete_1.
+ * decl2.c (delete_sanity): Don't call stabilize_reference.
+
+2003-05-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (register_specialization): Update the decl's location,
+ if necessary.
+ (check_explicit_specialization): Likewise.
+
+2003-05-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (dump_expr): Use HOST_WIDE_INT_PRINT_DOUBLE_HEX.
+
+2003-05-21 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/9738
+ * decl.c (duplicate_decls): Re-invoke make_decl_rtl
+ if the old decl had instantiated DECL_RTL.
+ (Base on Richard Henderson 2003-05-13 patch to c-decl.c).
+
+2003-05-19 Matt Austern <austern@apple.com>
+
+ * lang-options.h: Document -Wno-invalid-offsetof
+ * typeck.c (build_class_member_access_expr): Don't complain about
+ (Foo *)p->x for non-POD Foo if warn_invalid_offset is zero.
+
+2003-05-18 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * name-lookup.c (free_binding_entry): fix where the GTY markers are.
+ (binding_entry_make): Make entry->chain NULL after getting an entry.
+ fix the spelling of chain in a comment.
+ (binding_table_free): speed up by having temporary variable.
+ (binding_table_new): set table->chain to be NULL after allocating
+ a table.
+ (cxx_binding_make): use gcc_alloc instead of ggc_alloc_cleared and set
+ binding->previous to NULL after getting an binding for speed.
+
+2003-05-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (struct lang_type_class): Replace data member tags
+ with hash-table nested_udts.
+ (CLASSTYPE_NESTED_UTDS): Rename from CLASSTYPE_TAGS.
+ * class.c (unreverse_member_declarations): Don't touch
+ CLASSTYPE_TAGS.
+ (pushclass): Use cxx_remember_type_decls.
+ * decl.c (struct cp_binding_level): Replace data member tags with
+ hash-table type_decls.
+ (pop_binding_level): Handle level->type_decls.
+ (kept_level_p): Adjust.
+ (poplevel): Remove unused local variable.
+ (bt_print_entry): New function.
+ (print_binding_level): Use it.
+ (push_namespace): Build current_binding_level->type_decls.
+ (maybe_process_template_type_declaration): Adjust.
+ (pushtag): Likewise.
+ (clear_anon_tags): Use binding_table_remove_anonymous_types.
+ (gettags): Remove.
+ (cxx_remember_type_decls): Rename from storetags. Adjust.
+ (lookup_tag): Use binding_table_find_anon_type. Tidy.
+ (lookup_tag_reverse): Use binding_table_reverse_maybe_remap.
+ (cxx_init_decl_processing): Build global_binding_level->type_decls.
+ (store_parm_decls): Remove pointless code.
+ * name-lookup.c (free_binding_entry): New variable.
+ (ENTRY_INDEX): New macro.
+ (struct binding_table_s): New datatype.
+ (binding_entry_make): New function.
+ (binding_entry_free): Likewise.
+ (binding_table_construct): Likewise.
+ (binding_table_free): Likewise.
+ (binding_table_new): Likewise.
+ (binding_table_expand): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ (binding_table_remove_anonymous_types): Likewise.
+ (binding_table_foreach): Likewise.
+ * name-lookup.h (binding_table): New type.
+ (binding_entry): Likewise.
+ (bt_foreach_proc): Likewise.
+ (struct binding_entry_s): New datatype.
+ (SCOPE_DEFAULT_HT_SIZE): New macro.
+ (CLASS_SCOPE_HT_SIZE): Likewise.
+ (NAMESPACE_ORDINARY_HT_SIZE): Likewise.
+ (NAMESPACE_STD_HT_SIZE): Likewise.
+ (GLOBAL_SCOPE_HT_SIZE): Likewise.
+ (binding_table_new): Declare.
+ (binding_table_free): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ (binding_table_remove_anonymous_types): Likewise.
+ (binding_table_foreach): Likewise.
+ (binding_table_find): Likewise.
+ (cxx_remember_type_decls): Likewise.
+ * pt.c (bt_instantiate_type_proc): New function.
+ (do_type_instantiation): Use it.
+ * search.c (lookup_field_r): Use binding_table_find.
+
+2003-05-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * semantics.c (perform_deferred_access_checks): Don't discard
+ checked access.
+
+2003-05-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (cp_error_at, cp_warning_at, cp_pedwarn_at): Eliminate
+ libiberty VA_ macros, always use stdarg.
+ * rtti.c (create_pseudo_type_info): Likewise.
+ * tree.c (build_min_nt, build_min): Likewise.
+
+2003-05-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ptree.c (cxx_print_type, cxx_print_xnode): Use string
+ concatentation on HOST_WIDE_INT_PRINT_* format specifier to
+ collapse multiple function calls into one.
+ * tree.c (debug_binfo): Likewise.
+
+2003-05-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/5388
+ * call.c (conditional_conversion): Don't consider implicit
+ conversions if T2 is a base of T1.
+ * cp-tree.h (DERIVED_FROM_P, UNIQUELY_DERIVED_FROM_P): Make boolean.
+ (ACCESSIBLY_UNIQUELY_DERIVED_P, PUBLICLY_UNIQUELY_DERIVED_P): Likewise.
+
+ * parser.c (cp_parser_primary_expression): Convert a static data
+ member from reference.
+
+2003-05-15 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_op_delete_call): Avoid creating unnecessary types.
+ * class.c (instantiate_type): Remove tests for tf_no_attributes.
+ * cp-tree.h (tsubst_flags_t): Remove tf_no_attributes.
+ (COMPARE_NO_ATTRIBUTES): Remove.
+ * typeck.c (comptypes): Do not check COMPARE_NO_ATTRIBUTES.
+
+ PR c++/8385
+ * semantics.c (finish_typeof): Refine type-dependency check.
+
+2003-05-13 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_modify_expr): Don't always stabilize the lhs and
+ rhs. Do stabilize the lhs of a MODIFY_EXPR used on the lhs.
+
+2003-05-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * method.c (synthesize_method): Call push/pop_deferring_access_checks.
+
+2003-05-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10230, c++/10481
+ * semantics.c (finish_non_static_data_member): Handle when the
+ non-static member is not from a base of the current class type.
+
+2003-05-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10552
+ * pt.c (tsubst_copy): Handle TEMPLATE_DECL that is a member class
+ template and has dependent context.
+
+2003-05-10 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (instantiate_decl): Call push/pop_deferring_access_checks.
+
+2003-05-10 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9252
+ * cp-tree.h (saved_scope): Remove check_access field.
+ (tsubst_flags_t): Remove tf_parsing.
+ * decl.c (maybe_push_to_top_level): Don't initialize
+ scope_chain->check_access.
+ (make_typename_type, make_unbound_class_template): Don't use
+ tf_parsing.
+ (register_dtor_fn): Use push/pop_deferring_access_checks
+ instead of scope_chain->check_access.
+ * method.c (use_thunk): Likewise.
+ * parser.c (cp_parser_explicit_instantiation
+ (cp_parser_constructor_declarator_p): Don't call
+ push/pop_deferring_access_checks here.
+ (cp_parser_template_argument, cp_parser_class_name): Don't use
+ tf_parsing.
+ (yyparse): Check flag_access_control.
+ * pt.c (instantiate_class_template): Call
+ push/pop_deferring_access_checks.
+ * semantics.c (push_deferring_access_checks): Propagate
+ dk_no_check.
+ (perform_or_defer_access_check): Make sure basetype_path is
+ a type before comparison.
+ * call.c (build_op_delete_call, build_over_call): Use
+ perform_or_defer_access_check.
+ * class.c (alter_access): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * lex.c (do_identifier): Likewise.
+ * method.c (hack_identifier): Likewise.
+ * search.c (lookup_member): Likewise.
+ * semantics.c (finish_non_static_data_member): Likewise.
+ (simplify_aggr_init_exprs_r): Use push/pop_deferring_access_checks
+ instead of flag_access_control.
+
+2003-05-10 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9554
+ * parser.c (cp_parser_class_name): Remove check_access parameter.
+ All caller adjusted. Update declaration.
+ (cp_parser_lookup_name): Likewise.
+ * semantics.c (push_deferring_access_checks): Change parameter type
+ to enum deferring_kind. All caller adjusted.
+ (resume_deferring_access_checks): Adjust to use new enum.
+ (stop_deferring_access_checks): Likewise.
+ (perform_or_defer_access_check): Likewise.
+ * cp-tree.h (deferring_kind): New enum.
+ (deferred_access): Adjust field type.
+ (push_deferring_access_checks): Update declaration.
+
+2003-05-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10555, c++/10576
+ * pt.c (lookup_template_class): Handle class template with
+ multiple levels of parameters when one of the levels contain
+ errors.
+
+2003-05-08 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Don't reuse a TARGET_EXPR in an
+ expression. Undo some of the recent reorg.
+
+2003-05-07 Richard Henderson <rth@redhat.com>
+
+ PR c++/10570
+ * cfns.gperf: Comment out POSIX thread cancellation points,
+ plus abort and raise.
+ * cfns.h: Regenerate.
+
+2003-05-07 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_conditional_expr): Don't assume that the folded
+ expression has result_type.
+
+2003-05-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * typeck.c (build_unary_op): Deal with const qualifier in
+ invalid pointer-to-member earlier.
+
+2003-05-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/9537
+ * call.c (conditional_conversion): Build an RVALUE_CONV if
+ we're just changing the cv-quals.
+ (build_conditional_expr): Don't call convert to change
+ cv-quals.
+
+2003-05-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10496
+ * typeck.c (build_unary_op): Don't output const qualifier when
+ output invalid pointer-to-member diagnostics.
+
+2003-05-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl.c: Fix typos.
+
+2003-05-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/4494
+ * decl.c (start_function): Use same_type_p to check return type
+ of main.
+
+2003-05-03 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/10604
+ * cp/typeck.c (build_x_compound_expr): No need to check
+ extra_warnings as well as warn_unused_value.
+
+2003-05-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9364, c++/10553, c++/10586
+ * decl.c (make_typename_type): Don't crash on illegal code.
+
+2003-05-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (finish_struct): Use location_t and input_location
+ directly.
+ * decl.c (make_label_decl): Likewise.
+ (use_label): Likewise.
+ * decl2.c (warn_if_unknown_interface): Likewise.
+ (start_static_initialization_or_destruction): Likewise.
+ (generate_ctor_or_dtor_function): Likewise.
+ (finish_file): Likewise.
+ * error.c (print_instantiation_full_context): Likewise.
+ * init.c (create_temporary_var): Likewise.
+ * method.c (synthesize_method): Likewise.
+ * parser.c (cp_token): Likewise.
+ (cp_lexer_set_source_position_from_token): Likewise.
+ (cp_lexer_get_preprocessor_token): Likewise.
+ (cp_parser_statement): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+ (instantiate_class_template): Likewise.
+ (tsubst_decl): Likewise.
+ (tsubst): Likewise.
+ (instantiate_decl): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+ (expand_body): Likewise.
+
+2003-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (finish_struct): Rename lineno to input_line.
+ * decl.c (push_binding_level, pop_binding_level,
+ suspend_binding_level, resume_binding_level, make_label_decl,
+ use_label, start_function): Likewise.
+ * decl2.c (warn_if_unknown_interface,
+ start_static_initialization_or_destruction,
+ generate_ctor_or_dtor_function, finish_file): Likewise.
+ * error.c (cp_line_of, print_instantiation_full_context,
+ print_instantiation_context): Likewise.
+ * except.c (check_handlers_1, check_handlers): Likewise.
+ * init.c (create_temporary_var): Likewise.
+ * method.c (use_thunk, synthesize_method): Likewise.
+ * parser.c (cp_lexer_set_source_position_from_token,
+ cp_lexer_get_preprocessor_token): Likewise.
+ * pt.c (push_tinst_level, pop_tinst_level,
+ tsubst_friend_function, instantiate_class_template, tsubst_decl,
+ tsubst, tsubst_expr, instantiate_decl): Likewise.
+ * semantics.c (genrtl_try_block, finish_label_stmt,
+ begin_class_definition, expand_body,
+ genrtl_finish_function): Likewise.
+ * tree.c (build_min_nt, build_min): Likewise.
+
+2003-05-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (comdat_linkage): Don't externalize explicit
+ instantiations.
+
+2003-05-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10554
+ * decl2.c (do_class_using_decl): Check if operand 0 of SCOPE_REF
+ is not NULL.
+
+2003-05-01 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cp-tree.h (struct lang_id2): Remove. Move fields from here...
+ (struct lang_identifier): ... to here.
+ (LANG_ID_FIELD): Remove.
+ (SET_LANG_ID): Remove.
+ (IDENTIFIER_LABEL_VALUE): Adjust for new lang_identifier.
+ (SET_IDENTIFIER_LABEL_VALUE): Likewise.
+ (IDENTIFIER_IMPLICIT_DECL): Likewise.
+ (SET_IDENTIFIERL_IMPLICIT_DECL): Likewise.
+ (IDENTIFIER_ERROR_LOCUS): Likewise.
+ (SET_IDENTIFIER_ERROR_LOCUS): Likewise.
+
+2003-05-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8772
+ * pt.c (convert_template_argument): Correct diagnostic.
+
+2003-04-30 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9432, c++/9528
+ * decl2.c (validate_nonmember_using_decl): Handle SCOPE_REF.
+
+2003-04-30 Garbiel Dos Reis <gcc@integrable-solutions.net>
+
+ * decl.c (check_previous_goto_1): Adjust prototype.
+ (check_previous_goto): Adjust use.
+ (check_switch_goto): Likewise.
+ (use_label): Adjust.
+ (check_previous_goto_1): Don't use pedwarn_with_file_and_line.
+ (struct named_label_use_list): Use location_t datatype.
+
+2003-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10551
+ * pt.c (mark_decl_instantiated): Defer all explicit instantiations
+ that have not yet been written out.
+
+2003-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10549
+ * class.c (layout_class_type): Mark overlong bitfields as having
+ the maximum size permitted by their type, after layout.
+
+ PR c++/10527
+ * error.c (dump_expr): Correctly handling of NEW_EXPR.4
+
+2003-04-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * call.c (build_operator_new_call): Fix typo.
+ * lang-options.h: Likewise.
+
+2003-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10515
+ * cp-tree.h (lookup_field_1): Declare it.
+ * search.c (lookup_field_1): Make it public.
+ * decl.c (reshape_init): Handle designated initializers.
+
+ * decl.c (maybe_commonize_var): Further tweak support for systems
+ without weak symbols.
+
+2003-04-27 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (maybe_commonize_var): Fix thinko in last patch.
+
+2003-04-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10506
+ * method.c (use_thunk): Decrement immediate_size_expand.
+
+ PR c++/10503
+ * cp-tree.h (DECL_VAR_MARKED_P): New macro.
+ (DECL_MAYBE_TEMPLATE): Remove.
+ * class.c (fixed_type_or_null): Avoid infinite recursion.
+
+ * decl.c (maybe_commonize_var): Make the code match the comments.
+ * pt.c (instantiate_decl): Move call to import_export_decl.
+
+2003-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_file): Fix merge botch.
+
+2003-04-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_file): Don't call import_export_decl for
+ functions that are not defined.
+ (handle_class_head): Robustify.
+ * pt.c (instantiate_decl): Do not call cp_finish_decl for
+ variables that are not defined.
+
+2003-04-24 Sylvain Pion <Sylvain.Pion@mpi-sb.mpg.de>
+
+ * call.c (print_z_candidates): Fix off by one error.
+
+2003-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10337
+ * call.c (joust): Don't warn about conversion ops that are exact
+ or cv-conversions. Rearrange to avoid multiple type comparisons.
+
+2003-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10471
+ * call.c (build_cxx_call): Robustify.
+
+2003-04-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (lex.o): Remove mbchar.h.
+ * lex.c (MULTIBYTE_CHARS): Lose.
+ * parser.c (cp_lexer_get_preprocessor_token): CPP_OTHER handled
+ in c-lex.c.
+
+2003-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9847
+ * cp-tree.h (duplicate_tag_error): Remove.
+ * class.c (duplicate_tag_error): Remove.
+ * semantics.c (begin_class_definition): Return immediately for a
+ duplicate class definition.
+
+ PR c++/10451
+ * decl.c (grokdeclarator): Correct logic for "mutable" errors.
+
+2003-04-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10446
+ * search.c (lookup_fnfields_1): Handle empty slots in the method
+ vector.
+
+ PR c++/10428
+ * decl.c (check_elaborated_type_specifier): New function, split
+ out from ...
+ (xref_tag): ... here. Use the new function in more places.
+
+ * rtti.c (throw_bad_typeid): Use build_cxx_call.
+
+2003-04-21 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_over_call): Use build_cxx_call.
+ (build_cxx_call): New method, split out of build_over_call.
+ * cp-tree.h (language_function): Add can_throw.
+ (build_cxx_call): Declare it.
+ * decl.c (finish_function): If a function does not contain any
+ calls to functions that can throw an exception, indicate that
+ fact.
+ * decl2.c (mark_used): Do not defer the instantiation of
+ functions, if the current function does not throw.
+ * optimize.c (maybe_clone_body): Copy TREE_NOTHROW to the clones.
+ * pt.c (instantiate_decl): Make sure import_export_decl is called
+ before emitting things.
+ * rtti.c (throw_bad_cast): Use build_cxx_call.
+ (build_dynamic_cast_1): Likewise.
+ * typeck.c (build_function_call): Likewise.
+
+2003-04-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9881
+ * typeck.c (build_unary_op): Fold all COMPONENT_REF addr
+ expressions. Reverts my 2002-08-08 patch.
+
+ * typeck.c (comp_ptr_ttypes_real): Swap final && operands for
+ cheaper early exit.
+
+2003-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp/decl2.c (start_static_storage_duration_function): Take count
+ arg, don't check if it wraps round.
+ (generate_ctor_or_dtor_function): Add locus arg, use it.
+ (generate_ctor_and_dtor_functions_for_priority): Data arg is a
+ locus.
+ (finish_file): Set line numbers to past EOF for synthesized
+ functions.
+
+2003-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10405
+ * search.c (lookup_field_1): Final scan goes backwards for
+ types, forwards for non-types.
+
+2003-04-17 Roger Sayle <roger@eyesopen.com>
+
+ PR c/10375
+ * decl.c (duplicate_decls): Preserve "const", "noreturn" and
+ "nothrow" function attributes.
+
+2003-04-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10347
+ * pt.c (type_dependent_expression_p): Handle array new.
+
+2003-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10381
+ * parser.c (cp_parser_primary_expression): Reorganize logic for
+ dealing with name lookup failures.
+
+2003-04-15 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (mark_used): Don't instantiate anything if
+ skip_evaluation.
+
+2003-04-14 Ziemowit Laski <zlaski@apple.com>
+
+ * tree.c (build_cplus_array_type_1): Do not call
+ uses_template_parms() on a NULL index_type.
+
+2003-04-13 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (duplicate_decls): Preserve pure and malloc attributes.
+
+2003-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10300
+ * init.c (build_new_1): Reorganize.
+
+2003-04-12 Zack Weinberg <zack@codesourcery.com>
+
+ * class.c (initialize_array)
+ * decl.c (reshape_init)
+ * decl2.c (build_expr_from_tree)
+ * init.c (build_zero_init)
+ * pt.c (tsubst_copy, tsubst_copy_and_build)
+ * rtti.c (tinfo_base_init, generic_initializer, ptr_initializer)
+ (ptm_initializer, class_initializer, get_pseudo_ti_init)
+ * semantics.c (finish_compound_literal)
+ * typeck.c (build_ptrmemfunc1)
+ * typeck2.c (store_init_value, process_init_constructor)
+ (build_functional_cast): Use build_constructor.
+
+2003-04-12 Zack Weinberg <zack@codesourcery.com>
+
+ * call.c (print_z_candidates): Use gcc_gettext_width, not
+ strlen, to determine how much padding to use.
+
+2003-04-10 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c: Update all calls to shadow_warning.
+
+2003-04-10 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Correct handling for overlong
+ bit-fields whose width is the same as an integer type.
+
+2003-04-06 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-tree.def: Make fourth element for all 'c' and 'x' nodes zero.
+ * cp-lang.c (cp_tree_size): New function.
+ (LANG_HOOKS_TREE_SIZE): Override.
+
+ * cp-tree.h (SOURCE_LOCUS, SRCLOC_FILE, SRCLOC_LINE, struct
+ tree_srcloc, TS_CP_COMMON, TS_CP_SRCLOC): Kill.
+ (union lang_tree_node): Remove common and srcloc members.
+ (build_srcloc_here): Don't prototype.
+ * decl.c (cp_tree_node_structure): Kill SRCLOC case.
+ * pt.c (pending_templates): Correct comment.
+ * tree.c (build_srcloc, build_srcloc_here): Kill.
+
+2003-04-06 Zack Weinberg <zack@codesourcery.com>
+
+ * call.c: Include intl.h.
+ (print_z_candidate): Always use inform; get rid of errfn
+ argument. Reorganize so that all the strings get picked up
+ by xgettext. Note obligation of caller to pass first argument
+ through gettext.
+ (print_z_candidates): Update to match. Indent second and
+ successive candidates by strlen() of translated message.
+ (joust): Restructure ambiguous-conversion pedwarn so that
+ translators see a complete sentence. Update calls to
+ print_z_candidate.
+
+ * Make-lang.in (cp/call.o): Update dependencies.
+
+2003-04-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (set_current_binding_level): Delete, revert last change.
+ (current_binding_level): Modify to allow it as as lvalue.
+
+2003-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * name-lookup.c (find_binding): Pass appropriate pointer type to
+ POP_TIMEVAR_AND_RETURN.
+
+2003-04-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (cp-warn): Add $(STRICT_WARN).
+ * cp-tree.h: Don't insist on having GNUC.
+
+2003-04-03 Jason Merrill <jason@redhat.com>
+
+ * cvt.c (ocp_convert): Only abort if we try to convert an object
+ of TREE_ADDRESSABLE type.
+
+ * class.c (build_vtable): Set DECL_ALIGN here.
+ (get_vtable_decl): Not here.
+ (layout_vtable_decl): Or here.
+ (create_vtable_ptr): Or here.
+ (layout_class_type): Or here.
+ (check_bitfield_decl): Don't mess with field alignment.
+
+2003-04-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * operators.def (DEF_SIMPLE_OPERATOR, DEF_ASSN_OPERATOR,
+ DEF_ASSN_OPERATOR): Delete spurious semi-colon.
+ * rtti.c (dfs_class_hint_mark): Likewise.
+
+ * decl.c (push_local_name, push_class_level_binding,
+ maybe_inject_for_scope_var): Don't use POP_TIMEVAR_AND_RETURN in
+ functions returning void.
+ * decl2.c (add_using_namespace): Likewise.
+
+ * decl.c (print_binding_level, print_other_binding_stack,
+ print_binding_stack): Cast argument of %p specifier to void*.
+ * ptree.c (cxx_print_decl): Likewise.
+
+ * cp-tree.h (VAR_OR_FUNCTION_DECL_CHECK,
+ VAR_FUNCTION_OR_PARM_DECL_CHECK,
+ VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK, RECORD_OR_UNION_TYPE_CHECK,
+ BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK, LANG_TYPE_CLASS_CHECK,
+ LANG_TYPE_PTRMEM_CHECK, LANG_DECL_U2_CHECK): Add __extension__.
+
+ * decl.c (set_current_binding_level): New macro. Use throughout
+ when setting the current binding level.
+
+ * cp-tree.h (cp_lvalue_kind, base_access): Delete trailing comma
+ in enum.
+ * method.c (mangling_flags): Likewise.
+
+ * cp-tree.h (lang_type_header): Add __extension__ and use
+ CHAR_BITFIELD for members.
+
+2003-04-02 Geoffrey Keating <geoffk@apple.com>
+
+ PR other/9274
+ * mangle.c: Include gt-cp-mangle.h.
+ (subst_identifiers): Mark with GTY.
+ * config-lang.in (gtfiles): Add cp/mangle.c.
+ * Make-lang.in: (gt-cp-mangle.h): New rule.
+ (cp/mangle.o): Depends on gt-cp-mangle.h.
+
+2003-04-01 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config-lang.in (gtfiles): Add \$(srcdir)/cp/name-lookup.c
+ after \$(srcdir)/cp/name-lookup.h.
+ * name-lookup.c: (cxx_binding_make): Use ggc_alloc_clearedinstead
+ of ggc_alloc. Include gt-cp-name-lookup.h at the end of the file.
+ * Make-lang.in: (gt-cp-name-lookup.h): Is generated by gengtype.
+ (cp/name-lookup.o): Depends on gt-cp-name-lookup.h.
+
+2003-03-31 Jason Merrill <jason@redhat.com>
+
+ PR java/10145
+ * class.c (check_field_decl): Don't set DECL_ALIGN.
+
+2003-03-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7647
+ * decl.c (grokdeclarator): Tidy, slightly.
+ * search.c (lookup_field_1): Add want_type parameter.
+ (lookup_field_r): Adjust call to lookup_field_1.
+
+2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * Make-lang.in (cp/name-lookup.o): Add more dependencies.
+
+2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (binding_for_name: Move to name-lookup.h Adjust
+ prototype.
+ (cxx_scope_find_binding_for_name): Likewise.
+ * decl.c (find_binding: Move to name-lookup.c.
+ (binding_for_name): Likewise.
+ (cxx_scope_find_binding_for_name): Likewise.
+ (BINDING_LEVEL): Remove.
+ (push_binding): Tidy.
+ (push_class_binding): Likewise.
+ (pop_binding): Likewise.
+ (poplevel): Likewise.
+ (poplevel_class): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ (push_overloaded_decl): Likewise.
+ (lookup_tag): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_name_current_level): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (namespace_binding): Move to name-lookup.c.
+ (set_namespace_binding): Likewise.
+ * decl2.c (lookup_using_namespace): Tidy.
+ (qualified_lookup_using_namespace): Likewise.
+ (do_toplevel_using_decl): Likewise.
+ * name-lookup.c: Include "timevar.h"
+ * name-lookup.h (cxx_scope): Declare.
+ (struct cxx_binding): Lose member "has_level". Adjust "scope"
+ member declaration.
+ (BINDING_SCOPE): Adjust definition.
+ (BINDING_HAS_LEVEL_P): Remove.
+
+2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.c: New file.
+ * name-lookup.h: Likewise..
+ * decl.c (push_binding): Adjust use cxx_binding_make.
+ (free_bindings): Move to name-lookup.c
+ (pop_binding): Use cxx_binding_free.
+ (binding_for_name): Tidy.
+ * cp-tree.h: Include "name-lookup.h"
+ (cxx_binding_make): Move to name-lookup.h
+ (cxx_binding_clear): Likewise.
+ (struct cxx_binding): Likewise.
+ (LOCAL_BINDING_P): Likewise.
+ (INHERITED_VALUE_BINDING_P): Likewise.
+ (BINDING_SCOPE): Likewise.
+ (BINDING_HAS_LEVEL_P): Likewise.
+ (BINDING_VALUE): Likewise.
+ (BINDING_TYPE): Likewise.
+ * config-lang.in (gtfiles): Add cp/name-lookup.h
+ * Make-lang.in (cp/name-lookup.o): New rule.
+ (CXX_OBJS): Add cp/name-lookup.o
+ (CXX_TREE_H): Add cp/name-lookup.h
+
+2003-03-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/10245
+ * cvt.c (force_rvalue): New fn.
+ * call.c (build_conditional_expr): Use it.
+ * cp-tree.h: Declare it.
+
+2003-03-28 Mike Stump <mrs@apple.com>
+
+ * error.c (dump_expr): Add 0x to printed hex numbers to make
+ output match source code better.
+
+2003-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10218
+ * decl.c (grokfndecl): Return NULL_TREE for bogus out-of-class
+ definitions.
+
+ * decl2.c (generate_ctor_or_dtor_function): Tolerate a
+ non-existant ssdf_decls array.
+ (finish_file): Call generator_ctor_or_dtor_function when there are
+ static constructors or destructors and no other static
+ initializations.
+
+2003-03-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10047
+ * decl2.c (finish_file): Don't warn about explicitly instantiated
+ inline decls.
+
+2003-03-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10224
+ * pt.c (lookup_template_class): Only check instantiated args if
+ they do not contain template parameters.
+
+2003-03-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10158
+ * parser.c (cp_parser_function_definition): Set
+ DECL_INITIALIZED_IN_CLASS for members.
+ * pt.c (instantiate_decl): Only reduce the template args for
+ friends that are not defined in class.
+
+2003-03-25 Jason Merrill <jason@redhat.com>
+
+ * call.c (print_z_candidate): Change name of first arg to msgid.
+ (joust): Add comment for translators.
+
+2003-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9898, PR c++/383, DR 322
+ * pt.c (maybe_adjust_types_for_deduction) <DEDUCE_CONV>: Look
+ through reference types on both PARM and ARG.
+
+2003-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10119
+ * error.c (dump_expr) <BASELINK>: Use dump_expr.
+ * pt.c (maybe_fold_nontype_args): New function.
+ (tsubst_copy) <SCOPE_REF>: Subst any template_id args.
+ <TEMPLATE_ID_EXPR>: Break out folding code, call it.
+ (tsubst_copy_and_build) <TEMPLATE_ID_EXPR>: Call
+ maybe_fold_nontype_args.
+
+2003-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10026
+ * decl2.c (arg_assoc_type) <ERROR_MARK>: Don't die.
+
+2003-03-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7086
+ * typeck.c (cxx_mark_addressable): Adjust call to
+ gen_mem_addressof or put_var_into_stack.
+
+2003-03-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9978, c++/9708
+ * cp-tree.h (instantiate_template): Add tsubst_flags parameter.
+ * call.c (add_template_candidate_real): Adjust
+ instantiate_template call.
+ * class.c (resolve_address_of_overloaded_function): Likewise.
+ * decl.c (build_enumerator): Set TREE_CONSTANT.
+ * pt.c (check_instantiated_args): New.
+ (push_inline_template_parms_recursive): Set TREE_CONSTANT,
+ TREE_READONLY.
+ (build_template_parm_index): Copy TREE_CONSTANT, TREE_READONLY.
+ (reduce_template_parm_level): Likewise.
+ (process_template_parm): Likewise.
+ (check_explicit_specialization): Adjust instantiate_template call.
+ (convert_template_argument): Don't check non-type argument here.
+ (lookup_template_class): Check them here.
+ (tsubst_friend_function): Adjust instantiate_template call.
+ (instantiate_template): Add tsubst_flags parameter, use it. Check
+ instantiated args.
+
+2003-03-21 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c: Update calls to shadow_warning.
+
+2003-03-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9898
+ * error.c (dump_decl) [CONST_DECL]: Print '<enumerator>'.
+ (dump_expr) [CONSTRUCTOR]: Print default ctor as a function call.
+
+2003-03-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/decl2.c (arg_assoc_class): Correct check for namespace-scope
+ friends.
+ * cp/pt.c (instantiate_class_template): Fix formatting.
+
+2003-03-14 Matt Austern <austern@apple.com>
+
+ * cp-tree.h (unemitted_tinfo_decls): Declaration of a new varray.
+ (unemitted_tinfo_decl_p): Remove.
+ (emit_tinfo_decl): Change declaration to remove unused parameter.
+ * decl2.c (finish_file): Change tinfo emission to loop through
+ unemitted_tinfo_decls array instead of looping through all decls.
+ * rtti.c (unemitted_tinfo_decl_p): Declare as static, remove
+ unused second parameter.
+ (init_rtti_processing): initialize unemitted_tinfo_decls varray.
+ (get_tinfo_decls): push new tinfo decl on unemitted_tinfo_decls.
+ (emit_tinfo_decl): remove unused second parameter, add assertion
+ that decl hasn't already been emitted.
+
+2003-03-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * dump.c (cp_dump_tree), cp-tree.h (cp_dump_tree): Change return
+ type from 'int' to 'bool'. Replace 0 and 1 with true and false in
+ return statements.
+
+2003-03-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/8316, c++/9315, c++/10136
+ * call.c (print_z_candidate): Split out from...
+ (print_z_candidiates): ...here.
+ (joust): Use it.
+
+2003-03-17 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/10031
+ * decl.c (duplicate_decls): Use the new type when prototyping
+ anticipated decls, even when the types match. This defines the
+ exception list for the built-in function.
+
+2003-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/10091
+ * typeck.c (build_class_member_access_expr): Compare
+ TYPE_MAIN_VARIANTs.
+
+2003-03-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9639
+ * parser.c (cp_parser_declarator_id): Clear parser->scope.
+
+2003-03-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/9993
+ * decl.c (finish_function): Only allow the NRVO to use variables
+ declared at function scope.
+
+2003-03-17 Andreas Jaeger <aj@suse.de>
+
+ * Make-lang.in (cp/TAGS): Remove.
+
+2003-03-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9629
+ * cp-tree.h (struct language_function): Add in_base_initializer.
+ (in_base_initializer): define it.
+ (expand_member_init): Remove INIT param.
+ * init.c (expand_member_init): Remove INIT param, return the member.
+ (emit_mem_initializers): Set in_base_initializer.
+ * class.c (build_base_path): Check in_base_initializer.
+ * parser.c (cp_parser_mem_initializer): Set in_base_initializer.
+ * pt.c (tsubst_initializer_list): Likewise.
+
+2003-03-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (binding_for_name): Fix initialization thinko.
+
+2003-03-15 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Compile-time improvement: 2/n.
+ * cp-tree.h (struct cxx_binding): New datatype;
+ (struct lang_identifier): Use it.
+ (LOCAL_BINDING_P): Adjust definition.
+ (INHERITED_VALUE_BINDING_P): Likewise.
+ (BINDING_SCOPE): Likewise.
+ (BINDING_HAS_LEVEL_P): Likewise.
+ (BINDING_VALUE): Likewise.
+ (BINDING_TYPE): Likewise.
+ (IDENTIFIER_VALUE): Likewise.
+ (struct tree_binding): Remove.
+ (TS_CP_BINDING): Likewise.
+ ((union lang_tree_node): Remove field "binding".
+ (cxx_binding_clear): New macro.
+ (binding_for_name): Adjust return type.
+ (qualified_lookup_using_namespace): Adjust prototype.
+ (lookup_using_namespace): Adjust prototype.
+ (cxx_scope_find_binding_for_name): Declare.
+ * cp-tree.def: Remove CPLUS_BINDING definition.
+ * decl.c (push_binding): Adjust local variable type.
+ (add_binding): Likewise.
+ (push_class_binding): Likewise.
+ (pop_binding): Likewise.
+ (poplevel): Likewise.
+ (poplevel_class): Likewise.
+ (free_bindings): Adjust type.
+ (find_binding): Adjust return type, add a third parameter. Remove
+ non-useful assertion now that we use static typing.
+ (cxx_scope_find_binding_for_name): New function.
+ (binding_for_name): Use it. Adjust local variable type. Simplify.
+ (namespace_binding): Simplify.
+ (set_namespace_binding): Likewise.
+ (set_identifier_type_value_with_scope): Adjust local variable type.
+ (lookup_tag): Don't type-abuse of local variable 'old'.
+ (lookup_namespace_name): Likewise. Allocate binding on stack.
+ (select_decl): Adjust prototype.
+ (unqualified_namespace_lookup): Allocate binding on stack.
+ Don't type-abuse of local variable 'val'.
+ (lookup_name_real): Likewise.
+ (maybe_inject_for_scope_var): Adjust local variable type.
+ (cp_tree_node_structure): Remove CPLUS_BINDING case label.
+ (namespace_binding): Adjust logic, simplify.
+ (BINDING_LEVEL): Adjust definition.
+ (push_class_level_binding): Adjust local variable type.
+ (struct cxx_saved_binding): Adjust field 'binding' type.
+ * decl2.c (ambiguous_decl): Adjust prototype.
+ (lookup_using_namespace): Adjust local variable type.
+ (qualified_lookup_using_namespace): Catch type error and correct
+ ensueing logic error.
+ (do_nonmember_using_decl): Adjust local variable type. Allocate
+ temporary cxx_binding on stack.
+ (do_toplevel_using_decl): Adjust local variable type.
+ * ptree.c (cxx_print_cxx_binding): New function.
+ (cxx_print_identifier): Use it.
+ (cxx_print_xnode): Delete CPLUS_BINDING case label.
+
+2003-03-15 Roger Sayle <roger@eyesopen.com>
+
+ * tree.c (count_functions): Fix whitespace.
+
+2003-03-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Update.
+
+2003-03-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6440
+ * pt.c (maybe_process_partial_specialization): Handle
+ member class template when enclosing class template is
+ explicit specialized.
+ (most_general_template): Stop looking when DECL is already
+ specialized.
+
+2003-03-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/9420
+ * search.c (lookup_conversions): Call complete_type here.
+ * call.c (implicit_conversion): Not here.
+
+2003-03-13 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (do_nonmember_using_decl): Correct handling of
+ simultaneous type/non-type bindings.
+
+ * call.c (initialize_reference): Remove bogus assertion.
+ * decl.c (build_ptrmemfunc_type): Revert change of 2003-03-09.
+
+2003-03-12 Andrew Lewycky <andrew@mxc.ca>
+
+ PR c++/7050
+ * expr.c (cxx_expand_expr): Return const0_rtx for throw
+ expressions.
+
+2003-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9474
+ * decl2.c (do_nonmember_using_decl): Do not call duplicate decls
+ to merge old and new declarations.
+
+2003-03-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * g++.1: Remove.
+ * Make-lang.in (c++.generated-manpages): Build cp/g++.1.
+ (cp/g++.1): Build it from scratch in the build tree.
+ (c++.install-man): Depend on it. Install it from the build tree.
+ (c++.mostlyclean): Clean it.
+
+2003-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9474
+ * decl2.c (do_nonmember_using_decl): Do not call duplicate decls
+ to merge old and new declarations.
+
+ PR c++/9924
+ * decl2.c (do_nonmember_using_decl): Ignore anticipated builtins.
+
+2003-03-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/9820
+ * search.c (lookup_member): Fix handling of functions in a class
+ being defined.
+
+2003-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8700
+ * call.c (convert_class_to_reference): Adjust usage of
+ splice_viable.
+ (any_viable): Remove.
+ (splice_viable): Combine with any_viable.
+ (print_z_candidates): Avoid printing duplicates.
+ (build_user_type_conversion_1): Adjust usage of splice_viable.
+ (build_new_function_call): Likewise.
+ (build_operator_new_call): Likewise.
+ (build_object_call): Likewise.
+ (build_conditional_expr): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+ (joust): Remove spurious comment.
+ * cp-tree.h (DECL_FRIENDLIST): Correct documentation.
+ * decl2.c (arg_assoc_class): Simplify.
+ * friend.c (add_friend): Likewise.
+
+2003-03-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/8660
+ * decl2.c (check_classfn): A member template only matches a
+ member template.
+
+2003-03-11 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Update.
+ * lang-specs.h: Don't define __GNUG__ here.
+
+2003-03-10 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (perform_overload_resolution): New function.
+ (build_new_function_call): Use it.
+ (build_operator_new_call): Likewise.
+ (add_candidates): Add explicit_targs and template_only parameters.
+ (build_new_op): Adjust accordingly.
+ * cp-tree.h (build_operator_new_call): New function.
+ (build_function_call_real): Remove.
+ (build_function_call_maybe): Likewise.
+ * init.c (build_new_1): Use build_operator_new_call.
+ * typeck.c (build_function_call_real): Rename to ...
+ (build_function_call): ... this.
+
+2003-03-10 Devang Patel <dpatel@apple.com>
+
+ PR c++/9394
+ * g++spec.c (lang_specific_driver): Use DEFAULT_WORD_SWTCH_TAKES_ARG.
+
+2003-03-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/9798
+ * decl.c (push_using_directive): Push before recursing.
+
+ PR c++/9868, c++/9524
+ * call.c (resolve_scoped_fn_name): Handle the case of a function
+ pointer member.
+
+ * decl2.c (build_offset_ref_call_from_tree): Only mess with 'this'
+ argument in the pointer-to-member case.
+
+2003-03-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9373
+ * cp-lang.c (cxx_get_alias_set): Use alias set zero for
+ pointers to member functions.
+
+ PR c++/8534
+ * decl.c (build_ptrmemfunc_type): Do not allow default arguments
+ in pointer-to-member-function types.
+
+2003-03-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * expr.c (cplus_expand_constant): Use C90 prototype style.
+ (cxx_expand_expr): Likewise.
+
+2003-03-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9970
+ * decl.c (duplicate_decls): Only copy DECL_THUNKS for virtual
+ functions.
+
+2003-03-08 Geoffrey Keating <geoffk@apple.com>
+
+ * lang-specs.h (c++-header): Change .pch to .gch.
+
+2003-03-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h (cxx_init): Update prototype.
+ * lex.c (cxx_init): Similarly.
+
+2003-03-08 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9823
+ * cp-tree.h (begin_mem_initializers): Remove.
+ * parser.c (cp_parser_mem_initializer_list): Inline it here.
+ Do not call finish_mem_initializers if not in a constructor.
+ (cp_parser_class_head): Fix typo in error message.
+ * semantics.c (begin_mem_initializers): Remove.
+ * testsuite/g++.dg/parser/constructor1.C: New test.
+
+ PR c++/9809
+ * call.c (add_function_candidate): Skip builtin fuctions that have
+ not yet been declared.
+
+ PR c++/9982
+ * init.c (build_new_1): Correct logic for determining whether or
+ not to use an array cookie.
+
+ PR c++/9524
+ * parser.c (cp_parser_postfix_expression): Call
+ finish_non_static_data_member, even when processing_template_decl.
+
+ PR c++/9912
+ * cp-tree.h (is_ancestor): New function.
+ (handle_class_head): Change prototype.
+ * decl2.c (is_namespace_ancestor): Rename to ...
+ (namespace_anecestor): ... this.
+ (set_decl_namespace): Adjust accordingly.
+ (handle_class_head): Remove unnecessary parameters.
+ * parser.c (cp_parser_class_head): Check that
+ nested-name-specifiers are used appropriately.
+
+2003-03-07 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (reference_binding): Remove REF_IS_VAR parameter.
+ (implicit_conversion): Adjust call to reference_binding.
+ (make_temporary_var_for_ref_to_type): Add TYPE parameter.
+ (initialize_reference): Adjust handling for references bound to
+ rvalues.
+ * cp-tree.h (make_temporary_var_for_ref_to_temp): Change
+ prototype.
+ (real_non_cast_lvalue_p): New method.
+ * cvt.c (build_up_reference): Adjust use of
+ make_temporary_var_for_ref_to_temp.
+ * tree.c (real_non_cast_lvalue_p): New method.
+
+2003-03-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * except.c (init_exception_processing): Use C90 prototype style.
+ (cp_protect_cleanup_actions): Likewise.
+ (prepare_eh_type): Likewise.
+ (build_eh_type_type): Likewise.
+ (build_exc_ptr): Likewise.
+ (do_begin_catch): Likewise.
+ (dtor_nothrow): Likewise.
+ (do_end_catch): Likewise.
+ (push_eh_cleanup): Likewise.
+ (decl_is_java_type): Likewise.
+ (choose_personality_routine): Likewise.
+ (initialize_handler_parm): Likewise.
+ (expand_start_catch_block): Likewise.
+ (expand_end_catch_block): Likewise.
+ (begin_eh_spec_block): Likewise.
+ (finish_eh_spec_block): Likewise.
+ (do_allocate_exception): Likewise.
+ (do_free_exception): Likewise.
+ (wrap_cleanups_r): Likewise.
+ (stabilize_throw_expr): Likewise.
+ (build_throw): Likewise.
+ (complete_ptr_ref_or_void_ptr_p): Likewise.
+ (is_admissible_throw_operand): Likewise.
+ (nothrow_libfn_p): Likewise.
+ (can_convert_eh): Likewise.
+ (check_handlers_1): Likewise.
+ (check_handlers): Likewise.
+
+2003-03-06 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (merge_conversion_sequences): New function.
+ (build_conv): Set ICS_USER_FLAG for USER_CONVs.
+ (convert_class_to_reference): Correct handling of second
+ standard conversion sequence in a user-defined conversion
+ sequence.
+ (build_user_type_conversion_1): Use merge_conversion_sequences.
+ * cp-tree.def: Add comments for CONV nodes.
+ * rtti.c (get_tinfo_decl): Use build_address/build_nop.
+
+2003-03-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (init_error): Use C90 prototype style.
+ (dump_scope): Likewise.
+ (dump_qualifiers): Likewise.
+ (dump_template_argument): Likewise.
+ (dump_template_argument_list): Likewise.
+ (dump_template_parameter): Likewise.
+ (dump_template_bindings): Likewise.
+ (dump_type): Likewise.
+ (dump_typename): Likewise.
+ (class_key_or_enum): Likewise.
+ (dump_aggr_type): Likewise.
+ (dump_type_prefix): Likewise.
+ (dump_type_suffix): Likewise.
+ (dump_global_iord): Likewise.
+ (dump_simple_decl): Likewise.
+ (dump_decl): Likewise.
+ (dump_template_decl): Likewise.
+ (dump_function_decl): Likewise.
+ (dump_parameters): Likewise.
+ (dump_exception_spec): Likewise.
+ (dump_function_name): Likewise.
+ (dump_template_parms): Likewise.
+ (dump_char): Likewise.
+ (dump_expr_list): Likewise.
+ (dump_expr): Likewise.
+ (dump_binary_op): Likewise.
+ (dump_unary_op): Likewise.
+ (type_as_string): Likewise.
+ (expr_as_string): Likewise.
+ (decl_as_string): Likewise.
+ (context_as_string): Likewise.
+ (lang_decl_name): Likewise.
+ (cp_file_of): Likewise.
+ (cp_line_of): Likewise.
+ (decl_to_string): Likewise.
+ (expr_to_string): Likewise.
+ (fndecl_to_string): Likewise.
+ (code_to_string): Likewise.
+ (language_to_string): Likewise.
+ (parm_to_string): Likewise.
+ (op_to_string): Likewise.
+ (type_to_string): Likewise.
+ (assop_to_string): Likewise.
+ (args_to_string): Likewise.
+ (cv_to_string): Likewise.
+ (cxx_print_error_function): Likewise.
+ (cp_diagnostic_starter): Likewise.
+ (cp_diagnostic_finalizer): Likewise.
+ (cp_print_error_function): Likewise.
+ (function_category): Likewise.
+ (print_instantiation_full_context): Likewise.
+ (print_instantiation_partial_context): Likewise.
+ (maybe_print_instantiation_context): Likewise.
+ (print_instantiation_context): Likewise.
+ (cp_printer): Likewise.
+ (print_integer): Likewise.
+ (print_non_consecutive_character): Likewise.
+ (locate_error): Likewise.
+
+2003-03-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9965
+ * call.c (reference_binding): Add ref_is_var parameter.
+ (implicit_conversion): Adjust call to reference_binding.
+ (initialize_reference): Likewise.
+
+ PR c++/9400
+ * decl.c (pushdecl): Don't check for shadowing of DECL_ARTIFICIAL
+ PARM_DECLs.
+
+ PR c++/9791
+ * class.c (get_basefndecls): Use lookup_fnfields_1.
+
+2003-03-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9188
+ * parser.c (cp_parser_type_parameter): Remove redundant `expect'
+ in error message.
+ (cp_parser_single_declaration): Likewise.
+
+2003-03-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/9440
+ * call.c (build_conditional_expr): Use convert rather than an
+ explicit NOP_EXPR.
+
+2003-03-02 Matt Austern <austern@apple.com>
+
+ * decl.c (cp_binding_level): Add static_decls varray member.
+ (add_decl_to_level): Add static/inline namespace scope
+ declarations to static_decls array.
+ (wrapup_global_for_namespace): Pass static_decls only, instead of
+ all decls, to wrapup_global_declarations/check_global_declarations.
+ (push_namespace): Initialize static_decls for ordinary namespaces.
+ (cxx_init_decl_processing): Initialize static_decls for global
+ namespace.
+
+2003-03-05 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (end_of_class): Correct thinko.
+
+2003-03-04 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config-lang.in: Replace ${libstdcxx_version} by its value.
+
+2003-03-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (cxx_saved_binding): Declare.
+ (struct saved_scope): Adjust type of field 'old_binding'.
+ * decl.c (cxx_saved_binding_make): New macro.
+ (struct cxx_saved_binding): Define.
+ (store_bindings): Adjust prototype. Use cxx_saved_binding to save
+ C++ bindings.
+ (maybe_push_to_top_level): Adjust local variable type.
+ (pop_from_top_level): Likewise.
+
+2003-03-04 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in (c++.tags): New target.
+
+2003-03-04 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Update.
+
+2003-03-03 Jason Merrill <jason@redhat.com>
+
+ * decl.c (finish_enum): Do set the type in a template. Simplify.
+ * pt.c (tsubst_enum, tsubst_copy): Revert last patch.
+
+2003-03-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9878
+ * call.c (convert_class_to_reference): Correct conversion
+ sequences.
+ (reference_binding): Add ref_bound_directly_to_rvalue_p parameter.
+ (implicit_conversion): Adjust call to reference_binding.
+ (add_candidate): Change type of candidates parameter.
+ (add_function_candidate): Likewise.
+ (add_conv_candidate): Likewise.
+ (build_builtin_candidate): Likewise.
+ (add_builtin_candidate): Likewise.
+ (add_builtin_candidates): Likewise.
+ (add_template_candidate_real): Likewise.
+ (add_template_candidate): Likewise.
+ (add_template_conv_candidate): Likewise.
+ (build_user_type_conversion_1): Adjust accordingly.
+ (build_object_call): Likewise.
+ (build_conditional_expr): Likewise.
+ (add_candidates): Likewise.
+ (build_new_op): Likewise.
+ (convert_like_real): Use USER_CONV_CAND. Use build_nop.
+ (build_new_method_call): Adjust calls to add_function_candidate.
+ (make_temporary_var_for_ref_to_temp): New function.
+ (initialize_reference): Add decl parameter.
+ * class.c (build_rtti_vtbl_entries): Use build_address and
+ build_nop.
+ * cp-tree.h (initialize_reference): Change prototype.
+ (make_temporary_var_for_ref_to_temp): New function.
+ (build_type_conversion): Change prototype.
+ (build_address): New function.
+ (build_nop): Likewise.
+ * cvt.c (cp_convert_to_pointer): Adjust call to
+ build_type_conversion. Avoid indicating redundant NOP_EXPRs.
+ Use build_nop.
+ (convert_to_pointer_force): Use build_nop.
+ (build_up_reference): Use make_temporary_var_for_ref_to_temp.
+ (convert_to_reference): Adjust call to build_type_conversion.
+ (ocp_convert): Likewise.
+ (build_type_conversion): Remove for_sure parameter.
+ * decl.c (grok_reference_init): Use initialize_reference.
+ * typeck.c (build_address): New function.
+ (build_nop): Likewise.
+ (build_unary_op): Use them.
+ (build_ptrmemfunc): Tidy slightly.
+ (convert_for_initialization): Adjust call to
+ initialize_reference.
+ * typeck2.c (store_init_value): Remove #if 0'd code.
+
+2003-03-03 Jason Merrill <jason@redhat.com>
+
+ * decl.c (start_function): Clear DECL_NUM_STMTS.
+
+ * class.c (get_vtable_decl): Use vtbl_type_node.
+ (build_primary_vtable): Check for it.
+
+2003-03-02 Aldy Hernandez <aldyh@redhat.com>
+
+ * decl.c (check_initializer): Check for vector_opaque_p.
+
+2003-03-02 Ashif Harji <asharji@uwaterloo.ca>
+
+ * lang-specs.h (default_compilers): Add -no-integrated-cpp flag to
+ invoke an external cpp during compilation.
+
+2003-03-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (duplicate_decls): Convert use of warning_with_decl() to
+ that of warning().
+ (start_decl): Likewise.
+ (start_function): Likewise.
+
+2003-03-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Update.
+
+2003-02-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9892
+ * pt.c (instantiate_decl): Clear DECL_RTL for a VAR_DECL when
+ instantiating it.
+
+2003-02-28 Aldy Hernandez <aldyh@redhat.com>
+
+ * parser.c (cp_parser_init_declarator): Revert opaque
+ vector_opaque_p change.
+ Do not include target.h.
+
+2003-02-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9879
+ * cp-tree.h (build_zero_init): Add parameter.
+ * decl.c (cp_finish_decl): Adjust call.
+ * init.c (build_zero_init): Add nelts parameter. Adjust recursive
+ calls.
+ (build_default_init): Add nelts parameter. Adjust calls to
+ build_zero_init.
+ (build_new_1): Adjust call to build_default_init.
+ * typeck2.c (process_init_constructor): Adjust call to build_zero_init.
+
+2003-02-26 Devang Patel <dpatel@apple.com>
+
+ * decl.c (finish_enum): Merge two 'for' loops. Copy value node if
+ required. Postpone enum setting for template decls.
+ (build_enumerator): Delay copying value node until finish_enum
+ (). Remove #if 0'ed code.
+ * pt.c (tsubst_enum): Set TREE_TYPE and copy value node.
+ (tsubst_copy): Add check for enum type.
+
+2003-02-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9683
+ * decl2.c (prune_vars_needing_no_initialization): Do not throw
+ away initializations for DECL_EXTERNAL VAR_DECLs.
+ (finish_file): Adjust accordingly.
+ * pt.c (instantiate_decl): Do not defer VAR_DECLs.
+
+2003-02-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (add_binding): Time TV_NAME_LOOKUP.
+ (push_class_binding): Likewise.
+ (set_namespace_binding): Likewise.
+
+2003-02-24 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9836
+ * cp-tree.h (CLASSTYPE_PRIMARY_TEMPLATE): Do not skip from
+ specializations back to the main template.
+ * parser.c (cp_parser_diagnose_invalid_type_name):Adjust use.
+ * pt.c (resolve_typename_type): Likewise.
+
+2003-02-24 Jeffrey D. Oldham <oldham@codesourcery.com>
+
+ PR c++/9778
+ * pt.c (tsubst_copy_and_build): For a templated function inside a
+ scope, process template arguments.
+
+2003-02-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9602
+ * typeck2.c (abstract_virtuals_error): Don't check when
+ TYPE is still template parameter dependent.
+
+2003-02-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5333
+ * cp-tree.h (CLASSTYPE_PRIMARY_TEMPLATE): New macro.
+ * parser.c (cp_parser_diagnose_invalid_type_name): Use it.
+ * pt.c (instantiate_class_template): Don't try to instantiate
+ dependent types.
+ (resolve_typename_type): Use CLASSTYPE_PRIMARY_TEMPLATE.
+
+2003-02-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9749
+ * decl.c (grokdeclarator): Do not allow parameters with variably
+ modified types.
+
+2003-02-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (grow_bfs_bases): Remove. Fold into ...
+ (bfs_walk): ... here, fix fencepost error. Fix merge lossage
+ in previous patch.
+
+2003-02-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9729
+ * mangle.c (mangle_conv_op_name_for_type): Issue an error message
+ when the G++ 3.2 ABI prevents correct compilation.
+
+2003-02-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ Change base class access representation. Share virtual base
+ binfos.
+ * cp/call.c (build_special_member_call): Remove binfo_for_vbase
+ call.
+ * cp/class.c (build_base_path): Likewise.
+ (build_primary_vtable): Adjust BINFO_NEW_VTABLE_MARKED use.
+ (build_secondary_vtable): Remove FOR_TYPE arg. Adjust.
+ (make_new_vtable): Adjust.
+ (force_canonical_binfo_r): Delete.
+ (force_canonical_binfo): Delete.
+ (mark_primary_virtual_base): Delete.
+ (dfs_unshared_virtual_bases): Delete.
+ (mark_primary_bases): Adjust.
+ (maybe_warn_about_overly_private_class): Adjust.
+ (dfs_base_derived_from): Delete.
+ (base_derived_from): Follow the inheritance chain.
+ (struct find_final_overrider_data): Add vpath member.
+ (dfs_find_final_overrider): Adjust.
+ (dfs_find_final_overrider_q, dfs_find_final_overrider_post): New.
+ (find_final_overrider): Adjust.
+ (update_vtable_entry_for_fn): Adjust.
+ (modify_all_vtables): Adjust.
+ (walk_subobject_offsets): Adjust.
+ (layout_nonempty_base_or_field): Adjust.
+ (layout_empty_base): Remove last parameter. Adjust.
+ (build_base_field): Adjust.
+ (build_base_fields): Adjust.
+ (propagate_binfo_offsets): Remove last parameter. Adjust.
+ (dfs_set_offset_for_unshared_vbases): Delete.
+ (layout_virtual_bases): Adjust.
+ (finish_struct_1): Adjust.
+ (init_class_processing): Don't init access nodes.
+ (dfs_get_primary_binfo): Delete.
+ (get_primary_binfo): Adjust.
+ (dump_class_hierarchy_r): Remove most derived arg, add IGO
+ parameter. Adjust.
+ (dump_class_hierarchy): Adjust.
+ (finish_vtbls): Adjust.
+ (get_original_base): Delete.
+ (build_vtt_inits): Adjust.
+ (dfs_build_secondary_vptr_vtt_inits): Adjust.
+ (dfs_ctor_vtable_bases_queue_p): Adjust.
+ (build_ctor_vtbl_group): Adjust.
+ (dfs_accumulate_vtbl_inits): Adjust.
+ (build_vtbl_initializer): Adjust.
+ (build_vbase_offset_vtbl_entries): Adjust.
+ (add_vcall_offset_vtbl_entries_1): Adjust.
+ * cp/cp-tree.h (CPTI_ACCESS_*): Remove.
+ (access_*_node): Remove.
+ (CANONICAL_BINFO): Delete.
+ (BINFO_UNSHARED_MARKED): Remove.
+ (BINFO_MARKED): Set LANG_FLAG_0 directly.
+ (SET_BINFO_MARKED, CLEAR_BINFO_MARKED): Delete.
+ (BINFO_VTABLE_PATH_MARKED): Set LANG_FLAG_3 directly.
+ (SET_BINFO_VTABLE_PATH_MARKED, CLEAR_BINFO_VTABLE_PATH_MARKED):
+ Delete.
+ (BINFO_NEW_VTABLE_MARKED): Set LANG_FLAG_4 directly.
+ (SET_BINFO_NEW_VTABLE_MARKED): Adjust.
+ (SET_BINFO_PUSHDECLS_MARKED, CLEAR_BINFO_PUSHDECLS_MARKED):
+ Delete.
+ (BINFO_DEPENDENT_BASE_P): New.
+ (dfs_walk, dfs_walk_real): Queue function takes derived binfo and
+ index.
+ (markedp, unmarkedp): Adjust.
+ (dfs_unmarked_real_bases_queue_p, dfs_marked_real_bases_queue_p,
+ dfs_skip_vbases, marked_vtable_pathp, unmarked_vtable_pathp,
+ find_vbase_instance, binfo_for_vbase): Delete.
+ (copied_binfo, original_binfo): Declare.
+ (finish_base_specifier): Add virtual_p arg.
+ (unshare_base_binfos): Delete.
+ (copy_base_binfos): Declare.
+ (reverse_path): Delete.
+ * cp/decl.c (xref_basetypes): Access and virtuality passed
+ differently. Don't copy direct base binfos here. Call
+ copy_base_binfos.
+ * cp/init.c (dfs_initialize_vtbl_ptrs): Adjust.
+ (initialize_vtbl_ptrs): Adjust.
+ (expand_member_init): Adjust.
+ * cp/parser.c (cp_parser_base_specifier): Adjust.
+ * cp/pt.c (instantiate_class_template): Adjust.
+ (get_template_base_recursive): Adjust.
+ * cp/rtti.c (get_pseudo_ti_init): Adjust.
+ (get_pseudo_ti_desc): Adjust.
+ * cp/tree.c (unshare_base_binfos): Rename to ...
+ (copy_base_binfos): ... here, reimplement.
+ (make_binfo): Set BINFO_DEPENDENT_BASE_P.
+ (reverse_path): Remove.
+ * cp/typeck.c (get_delta_difference): Adjust error messages.
+ * cp/semantics.c (finish_base_specifier): Add virtual arg, adjust.
+ * cp/search.c (lookup_base_r): Adjust.
+ (dynamic_cast_base_recurse): Adjust.
+ (canonical_binfo): Remove.
+ (dfs_canonical_queue): Remove.
+ (dfs_assert_unmarked_p): Remove.
+ (assert_canonical_unmarked): Remove.
+ (shared_marked_p, shared_unmarked_p): Remove.
+ (BINFO_ACCESS, SET_BINFO_ACCESS): Use TREE_PUBLIC & TREE_PRIVATE.
+ (dfs_access_in_type): Adjust.
+ (access_in_type): Adjust.
+ (dfs_accessible_queue_p): Adjust.
+ (dfs_accessible_p): Adjust.
+ (is_subobject_of_p_1, is_subobject_of_p): Remove.
+ (struct lookup_field_info): Remove from_dep_base_p field.
+ (lookup_field_queue_p): Adjust, test BINFO_DEPENDENT_BASE_P.
+ (lookup_field_r): Remove dependent base code.
+ (lookup_member): Likewise.
+ (dfs_walk, dfs_walk_real): Add access arg to queue fn.
+ (dfs_unmarked_real_bases_queue_p): Remove.
+ (dfs_marked_real_bases_queue_p): Remove.
+ (dfs_skip_vbases): Remove.
+ (dfs_get_pure_virtuals): Adjust.
+ (markedp, unmarkedp): Adjust.
+ (marked_vtable_pathp, unmarked_vtable_pathp): Remove.
+ (marked_pushdecls_p, unmarked_pushdecls_p): Adjust.
+ (dfs_unmark): Adjust.
+ (dfs_get_vbase_types):Remove.
+ (dfs_build_inheritance_graph_order): Remove.
+ (get_vbase_types): Remove
+ (dfs_find_vbase_instance): Remove.
+ (find_vbase_instance): Remove.
+ (dfs_debug_unmarkedp): Adjust.
+ (dependent_base_p): Remove.
+ (dfs_push_type_decls): Adjust.
+ (dfs_push_decls): Adjust.
+ (dfs_no_overlap_yet): Adjust.
+ (copied_binfo): New function.
+ (original_binfo): New function.
+ (binfo_for_vbase): Remove.
+
+2003-02-18 Zack Weinberg <zack@codesourcery.com>
+
+ * cp/search.c (grow_bfs_bases): New subroutine of bfs_walk.
+ (bfs_walk): Rewritten using circular queue of BINFO_BASETYPES
+ vectors, for speed.
+
+2003-02-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9704
+ * class.c (layout_class_type): In the 3.2 ABI, take into account
+ trailing bit fields when computing CLASSTYPE_SIZE_UNIT.
+
+2003-02-18 Matt Austern <austern@apple.com>
+
+ * cp/cp-lang.c: Change lang hooks so that final_write_globals does
+ nothing for C++.
+ * cp/decl.c (wrapup_globals_for_namespace): Remove special
+ handling of global namespace.
+
+2003-02-18 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (rid_to_yy): Delete.
+ (C_RID_YYCODE): Delete.
+ (finish_file): Delete redundant declaration.
+
+2003-02-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/9623
+ * decl.c (reshape_init): Don't mess with initializer labels.
+
+ PR c++/9485
+ * parser.c (cp_parser_postfix_expression): Set idk properly for
+ object->scope::member.
+
+2003-02-18 Ben Elliston <bje@redhat.com>
+
+ PR other/7350
+ * decl.c (duplicate_decls): Fix typo in comment.
+
+2003-02-17 Michael Elizabeth Chastain <mec@shout.net>
+
+ PR debug/9717
+ * class.c (build_base_field): Mark fields for base classes with
+ DECL_IGNORED_P.
+
+2003-02-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9457
+ * pt.c (tsubst_copy_and_build) [CONSTRUCTOR]: Substitute
+ CONSTRUCTOR_ELTS only once.
+
+2003-02-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9459
+ * error.c (dump_type_prefix): Handle TYPEOF_TYPE.
+ (dump_type_suffix): Likewise.
+
+2003-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c: ANSIfy function declarations and definitions.
+ * cp-tree.h (lookup_field, lookup_member): Last parameter is a bool.
+ * call.c (build_method_call, resolve_scoped_fn_name,
+ build_java_interface_fn_ref): Adjust lookup_field, lookup_member
+ calls.
+ * class.c (handle_using_decl): Likewise.
+ * decl.c (make_typename_type, make_unmound_class_template,
+ start_decl, compute_array_index_type): Likewise.
+ * decl2.c (build_expr_from_tree, build_call_from_tree): Likewise.
+ * init.c (expand_member_init, build_member_call): Likewise.
+ * pt.c (tsubst_copy, tsubst_copy_and_build, do_decl_instantiation,
+ resolve_typename_type): Likewise.
+ * typeck.c (lookup_destructor, finish_class_member_access_exprm
+ build_prememfunc_access_expr): Likewise.
+
+2003-02-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl2.c: Include "timevar.h".
+ (namespace_ancestor): Time name lookup.
+ (add_using_namespace): Likewise.
+ (lookup_using_namespace): Likewise.
+ (qualified_lookup_using_namespace): Likewise.
+ (decl_namespace): Likewise.
+ (lookup_arg_dependent): Likewise.
+ * lex.c (do_identifier): Likewise.
+ (do_scoped_id): Likewise.
+ * pt.c (lookup_template_class): Likewise.
+
+2003-02-14 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * decl.c: (define_label): Fix warning for return 0 instead of NULL.
+
+2003-02-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c: Include "timevar.h".
+ (poplevel): Time name lookup.
+ (find_binding): Likewise.
+ (push_namespace): Likewise.
+ (pop_nested_namespace): Likewise.
+ (store_bindings): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (pop_from_top_level): Likewise.
+ (push_local_name): Likewise.
+ (pushtag): Likewise.
+ (pushdecl): Likewise.
+ (pushdecl_with_scope): Likewise.
+ (pushdecl_namespace_level): Likewise.
+ (pushdecl_top_level): Likewise.
+ (pushdecl_class_level): Likewise.
+ (push_class_level_binding): Likewise.
+ (push_using_decl): Likewise.
+ (push_using_directive): Likewise.
+ (push_overloaded_decl): Likewise.
+ (lookup_label): Likewise.
+ (define_label): Likewise.
+ (lookup_tag): Likewise.
+ (lookup_tag_reverse): Likewise.
+ (lookup_namespace_name): Likewise.
+ (select_decl): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_name_real): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (xref_tag): Likewise.
+
+ * Make-lang.in (cp/decl.o): Add dependency on timevar.h
+
+2003-02-12 Phil Edwards <pme@gcc.gnu.org>
+
+ * decl.c (build_enumerator): Remove unneeded test.
+
+2003-02-09 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * cp-tree.h (struct lang_type_header): Make all fields unsigned
+ char.
+
+2003-02-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7129
+ * call.c (z_candidate): Add args.
+ (convert_class_to_reference): Set it.
+ (implicit_conversion): Tidy.
+ (add_candidate): Add args parameter.
+ (add_function_candidate): Adjust call to add_candidate.
+ (add_conv_candidate): Likewise.
+ (build_builtin_candidate): Likewise.
+ (build_user_type_conversion_1): Eliminate wasteful tree_cons
+ usage.
+ (build_new_function_call): Likewise.
+ (build_object_call): Likewise.
+ (add_candidates): New function.
+ (build_new_op): Use it.
+ (covert_like_real): Adjust call to build_over_call.
+ (build_over_call): Remove args parameter.
+ * operators.def: Add <?= and >?=.
+
+2003-02-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * typeck.c (build_indirect_ref): Don't check flag_volatile.
+
+2003-01-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8849
+ * pt.c (resolve_overloaded_unification): Handle FUNCTION_DECL.
+
+2003-01-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX,
+ BINFO_PRIMARY_BASE_OF): Use BINFO_ELTS.
+ (BINFO_LANG_ELTS): New #define.
+ * tree.c (make_binfo): Use BINFO_LANG_ELTS.
+
+2003-01-30 Geoffrey Keating <geoffk@apple.com>
+
+ * cp/Make-lang.in: Remove -Wno-error from cp/decl.o.
+
+2003-01-30 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (check_field_decls): Only check C_TYPE_FIELDS_READONLY
+ for class types.
+ * cp-tree.h (C_TYPE_FIELDS_READONLY): Use a lang-specific bit
+ rather than TYPE_LANG_FLAG_0.
+ (TYPE_BUILT_IN): Remove.
+ (TYPE_DEPENDENT_P): New macro.
+ (TYPE_DEPENDENT_P_VALID): Likewise.
+ (lang_type_class): Add fields_readonly.
+ * decl.c (record_builtin_type): Don't set TYPE_BUILT_IN.
+ * pt.c (dependent_type_p_r): New function, split out from ...
+ (dependent_type_p): ... here. Memoize results.
+ * search.c (dependent_base_p): Use dependent_type_p, not
+ uses_template_parms.
+ * typeck.c (build_modify_expr): Only check C_TYPE_FIELDS_READONLY
+ for class types.
+
+2003-01-29 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_field_call): Use build_new_op, not build_opfncall.
+ (prep_operand): New function.
+ (build_new_op): Use it. Remove dead code.
+ * class.c (pushclass): Change "modify" parameter type from int to
+ bool.
+ (currently_open_class): Use same_type_p, not pointer equality.
+ (push_nested_class): Adjust calls to pushclass, remove modify
+ parameter.
+ * cp-tree.h (INTEGRAL_OR_ENUMERATION_TYPE_P): New macro.
+ (pushclass): Change prototype.
+ (push_nested_class): Likewise.
+ (grokoptypename): Remove.
+ (build_opfncall): Remove.
+ (value_dependent_expression_p): Declare.
+ (resolve_typename_type): Likewise.
+ (resolve_typename_type_in_current_instantiation): Likewise.
+ (enter_scope_of): Remove.
+ (tsubst): Remove.
+ (tsubst_expr): Likewise.
+ (tsubst_copy): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ * decl.c (warn_about_implicit_typename_lookup): Remove.
+ (finish_case_label): Return error_mark_node for erroneous labels.
+ (start_decl): Adjust calls to push_nested_class.
+ (grokfndecl): Call push_scope/pop_scope around call to
+ duplicate_decls.
+ (grokdeclarator): Do not call tsubst.
+ (start_function): Adjust calls to push_nested_class.
+ * decl2.c (grok_array_decl): Use build_new_op, not build_opfncall.
+ (check_classfn): Use push_scope/pop_scope around type comparisions.
+ (grokoptypename): Remove.
+ (push_sscope): Adjust call to push_nested_class.
+ * error.c (dump_type): Show cv-qualification of typename types.
+ * init.c (build_member_call): Use build_new_op, not
+ build_opfncall.
+ * method.c (build_opfncall): Remove.
+ * parser.c (cp_parser): Add allow_non_constant_expression_p and
+ non_constant_expression_p.
+ (cp_parser_constant_expression): Adjust prototype.
+ (cp_parser_resolve_typename_type): Remove.
+ (cp_parser_non_constant_expression): New function.
+ (cp_parser_non_constant_id_expression): Likewise.
+ (cp_parser_new): Set allow_non_constant_expression_p and
+ non_constant_expression_p.
+ (cp_parser_primary_expression): Reject `this' and `va_arg' in
+ constant-expressions. Note that dependent names aren't really
+ constant.
+ (cp_parser_postfix_expression): Reject conversions to non-integral
+ types in constant-expressions. Neither are increments or
+ decrements.
+ (cp_parser_unary_expression): Reject increments and decrements in
+ constant-expressions.
+ (cp_parser_direct_new_declarator): Adjust call to
+ cp_parser_constant_expression.
+ (cp_parser_cast_expression): Reject conversions to non-integral
+ types in constant-expressions.
+ (cp_parser_assignment_expression): Rejects assignments in
+ constant-expressions.
+ (cp_parser_expression): Reject commas in constant-expressions.
+ (cp_parser_labeled_statement): Adjust call to
+ cp_parser_constant_expression.
+ (cp_parser_direct_declarator): Simplify array bounds, even in
+ templates, when they are non-dependent. Use
+ resolve_typename_type, not cp_parser_resolve_typename_type.
+ (cp_parser_class_head): Use resolve_typename_type, not
+ cp_parser_resolve_typename_type.
+ (cp_parser_member_declaration): Adjust call to
+ cp_parser_constant_expression.
+ (cp_parser_constant_initializer): Likewise.
+ (cp_parser_constructor_declarator): Use resolve_typename_type, not
+ cp_parser_resolve_typename_type.
+ (cp_parser_late_parsing_default_args): Adjust call to
+ push_nested_class.
+ * pt.c (tsubst): Give it internal linkage.
+ (tsubst_expr): Likewise.
+ (tsubst_copy): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ (push_access_scope_real): Likewise.
+ (tsubst_friend_class): Likewise.
+ (instantiate_class_template): Adjust call to pushclass.
+ (value_dependent_expression_p): Give it external linkage.
+ Robustify.
+ (resolve_typename_type): New function.
+ * semantics.c (finish_call_expr): Use build_new_op, not
+ build_opfncall.
+ (begin_constructor_declarator): Remove.
+ (begin_class_definition): Adjust call to pushclass.
+ (enter_scope_of): Remove.
+ * typeck.c (comptypes): Resolve typename types as appropriate.
+ (build_x_indirect_ref): Use build_new_op, not build_opfncall.
+ (build_x_compound_expr): Likewise.
+ (build_modify_expr): Likewise.
+ (build_x_modify_expr): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2003-01-29 Fariborz Jahanian <fjahanian@apple.com>
+
+ * pt.c (last_pending_template) Declare GTY().
+
+2003-01-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8591
+ * parser.c (cp_parser_elaborated_type_specifier): Convert
+ TEMPLATE_DECL to TYPE_DECL only when processing template friends.
+ (cp_parser_maybe_treat_template_as_class): Remove redundant tests.
+
+2003-01-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9437
+ * pt.c (unify): Don't unify '*T' with 'U C::*'.
+
+ PR c++/3902
+ * parser.c (cp_parser_decl_specifier_seq): Cannot have constructor
+ inside a declarator.
+
+2003-01-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (update_vtable_entry_for_fn): Add index parameter.
+ Generate vcall thunk for covariant overriding from a virtual
+ primary base.
+ (dfs_modify_vtables): Adjust.
+
+2003-01-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9403
+ * parser.c (cp_parser_class_or_namespace_name): Reject duplicate
+ template keyword.
+ (cp_parser_base_specifier): Look for and consume a
+ TEMPLATE keyword. Replace switch with array index.
+
+ PR c++/795
+ * semantics.c (finish_non_static_data_member): Remember the
+ field's type even in a template.
+
+ PR c++/9415
+ * pt.c (tsubst_copy_and_build, CALL_EXPR): BASELINK exprs are
+ already scoped.
+
+ PR c++/8545
+ * parser.c (cp_parser_cast_expression): Be more tentative.
+
+2003-01-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (flagged_type_tree_s): Remove.
+ (check_for_new_type): Likewise.
+ * typeck2.c (check_for_new_type): Likewise.
+
+2003-01-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * dump.c: ANSIfy function declarations and definitions.
+
+ * cp-tree.h, decl.h: Get rid of PARAMS. Again.
+
+2003-01-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9354
+ * init.c (build_new): Set the type of the new-expression, even
+ when processing_templte_decl.
+
+ PR c++/9216
+ * parser.c (cp_parser_primary_expression): Improve error message
+ for templates used in an expression context.
+
+ PR c++/8696
+ * parser.c (cp_parser_decl_specifier_seq): Commit to tentative
+ parse when encountering "typedef".
+
+2003-01-22 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * class.c, parser.c: ANSIfy function definitions and declarations.
+
+2003-01-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9328
+ * error.c (dump_decl): For an OVERLOAD, just print the name of the
+ function; it doesn't make sense to try to print its type.
+ * semantics.c (finish_typeof): Issue errors about invalid uses.
+
+ PR c++/9298
+ * parser.c (cp_parser_consume_semicolon_at_end_of_statement): New
+ function.
+ (cp_parser_expression_statement): Use it.
+ (cp_parser_explicit_instantiation): Likewise.
+ * pt.c (do_decl_instantiation): Improve error handling logic.
+
+2003-01-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9384
+ * parser.c (cp_parser_using_declaration): Issue error messages
+ about name resolution failures here.
+
+ PR c++/9388
+ * class.c (currently_open_derived_class): Use dependent_type_p.
+ * cp-tree.h (dependent_type_p): New function.
+ (dependent_template_arg_p): Likewise.
+ (dependent_template_p): Likewise.
+ (type_dependent_expression_p): Likewise.
+ * parser.c (cp_parser_dependent_type_p): Remove.
+ (cp_parser_value_dependent_type_p): Likewise.
+ (cp_parser_type_dependent_expression_p): Likewise.
+ (cp_parser_dependent_template_arg_p): Likewise.
+ (cp_parser_dependent_template_id_p): Likewise.
+ (cp_parser_dependent_template_p): Likewise.
+ (cp_parser_diagnose_invalid_type_name): Replace
+ cp_parser_dependent_type_p with dependent_type_p, etc.
+ (cp_parser_primary_expresion): Likewise.
+ (cp_parser_nested_name_specifier_opt): Likewise.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_lookup_name): Likewise.
+ * pt.c (dependent_type_p): New function.
+ (value_dependent_expression_p): Likewise.
+ (type_dependent_expression_p): Likewise.
+ (dependent_template_arg_p): Likewise.
+ (dependent_template_id_p): Likewise.
+ (dependent_template_p): Likewise.
+
+ PR c++/9285
+ PR c++/9294
+ * parser.c (cp_parser_simple_declaration): Return quickly when
+ encountering errors.
+
+2003-01-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ Make-lang.in (cp/decl.o-warn): Add -Wno-error.
+
+2003-01-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/9167, c++/9358
+ * decl.c (require_complete_types_for_parms): Also update DECL_ARG_TYPE.
+
+2003-01-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/9342
+ * call.c (build_conditional_expr): Always do lvalue-rvalue
+ conversion.
+
+2003-01-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9294
+ * cp-tree.def (BASELINK): Make it class 'x', not class 'e'.
+ * cp-tree.h (BASELINK_BINFO): Adjust.
+ (BASELINK_FUNCTIONS): Likewise.
+ (BASELINK_ACCESS_BINFO): Likewise.
+ (tree_baselink): New structure.
+ (cp_tree_node_structure_enum): Add TS_CP_BASELINK.
+ (lang_tree_node): Add baselink.
+ * decl.c (cp_tree_node_structure): Add BASELINK case.
+ * search.c (build_baselink): Adjust.
+ * tree.c (cp_walk_subtrees): Add BASELINK case. Remove BASELINK_P
+ test from TREE_LIST case.
+
+ PR c++/9272
+ * parser.c (cp_parser_constructor_declarator_p): Do not assume
+ that a constructor cannot be declared outside of its own class.
+
+ * parser.c (cp_parser_resolve_typename_type): If the scope cannot
+ be resolved, neither can the qualified name.
+
+ * rtti.c (get_pseudo_ti_desc): Fix thinko.
+
+2003-01-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/8564
+ * init.c (build_vec_init): Re-add maxindex parm.
+ (perform_member_init, build_aggr_init): Pass it.
+ (build_new_1): Pass it. Use an incomplete array type for full_type.
+ * typeck.c (build_modify_expr): Pass it.
+ * cp-tree.h: Adjust.
+
+2003-01-16 Jeffrey D. Oldham <oldham@codesourcery.com>
+
+ * cp-tree.h (tsubst_copy_and_build): New declaration.
+ * pt.c (tsubst_copy): Remove 'build_expr_from_tree' from comment.
+ (tsubst_expr): Use 'tsubst_copy_and_build'. Update initial comment.
+ (tsubst_copy_and_build): New function.
+
+2003-01-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_type_class): Remove is_partial_instantiation.
+ (PARTIAL_INSTANTIATION_P): Remove.
+ (IMPLICIT_TYPENAME_P): Likewise.
+ (IMPLICIT_TYPENAME_TYPE_DECL_P): Likewise.
+ (build_typename_type): Remove declaration.
+ (parmlist_is_exprlist): Likewise.
+ * decl.c (build_typename_type): Make it static, remove third
+ parameter.
+ (push_class_binding): Don't do implicit typename stuff.
+ (make_typename_type): Likewise.
+ (lookup_name_real): Likewise.
+ (grokdeclarator): Don't try to convert declarations into
+ initializations. Don't do implicit typename stuff.
+ (parmlist_is_exprlist): Remove.
+ (xref_basetypes): Simplify.
+ * decl2.c (grokfield): Don't try to convert declarations into
+ initializations.
+ (build_anon_union_vars): Do this while processing templates, too.
+ (finish_anon_union): Likewise.
+ * error.c (dump_type): Remove implicit typename handling.
+ * parser.c (cp_parser_diagnose_invalid_type_name): New method.
+ (cp_parser_primary_expression): Correct handling of names not
+ found by unqualified name lookup in templates.
+ (cp_parser_nested_name_specifier_opt): Avoid checking dependency
+ of types when possible.
+ (cp_parser_simple_declaration): Complain intelligently about some
+ invalid declarations.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_constructor_declarator_p): Don't check when we're in a
+ function scope.
+ * pt.c (instantiate_class_template): Remove
+ PARTIAL_INSTANTIATION_P gunk.
+ * search.c (lookup_field_r): Don't build implicit typenames.
+ (marked_pushdecls_p): Don't enter dependent base types.
+ (unmarked_pushdecls_p): Likewise.
+ * semantics.c (begin_class_definition): Remove implicit typename
+ stuff.
+
+2003-01-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9212
+ * parser.c (cp_parser_direct_declarator): If accepting either
+ abstract or named, the name must be an unqualified-id.
+
+2003-01-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (layout_virtual_bases): Avoid signed/unsigned warning.
+
+2003-01-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (check_classfn): Fix uninitialized warning.
+ (build_anon_union_vars): Likewise.
+ * pt.c (tsubst_copy): Likewise.
+
+2003-01-14 Jeffrey D. Oldham <oldham@codesourcery.com>
+
+ Further conform g++'s __vmi_class_type_info to the C++ ABI
+ specification.
+ * rtti.c (dfs_class_hint_mark): Do not set hints not specified by
+ the specification.
+ (class_hint_flags): Likewise.
+
+2003-01-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * config-lang.in: Add semantics.c to gtfiles.
+ * cp-tree.h (flagged_type_tree_s): Remove lookups field.
+ (saved_scope): Likewise.
+ (type_lookups): Remove.
+ (deferred_access): New structure.
+ (type_access_control): Remove.
+ (save_type_access_control): Likewise.
+ (reset_type_access_control): Likewise.
+ (decl_type_access_control): Likewise.
+ (push_deferring_access_checks): Declare.
+ (resume_deferring_access_checks): Likewise.
+ (stop_deferring_access_checks): Likewise.
+ (pop_deferring_access_checks): Likewise.
+ (get_deferred_access_checks): Likewise.
+ (pop_to_parent_deferring_access_checks): Likewise.
+ (perform_deferred_access_checks): Likewise.
+ (perform_or_defer_access_check): Likewise.
+ * decl.c (make_typename_type): Use perform_or_defer_access_check.
+ (make_unbound_class_template): Likewise.
+ (grokdeclarator): Don't call decl_type_access_control.
+ * parser.c (cp_parser_context): Remove deferred_access_checks
+ and deferring_access_checks_p fields.
+ (cp_parser_context_new): Adjust.
+ (cp_parser): Remove access_checks_lists.
+ (cp_parser_defer_access_check): Remove.
+ (cp_parser_start_deferring_access_checks): Remove.
+ (cp_parser_stop_deferring_access_checks): Remove.
+ (cp_parser_perform_deferred_access_checks): Remove.
+ (cp_parser_nested_name_specifier_opt): Use new deferred access
+ functions.
+ (cp_parser_simple_declaration): Likewise.
+ (cp_parser_template_id): Likewise.
+ (cp_parser_function_definition): Likewise.
+ (cp_parser_class_specifier): Likewise.
+ (cp_parser_lookup_name): Likewise.
+ (cp_parser_single_declaration): Likewise.
+ (cp_parser_pre_parsed_nested_name_specifier): Likewise.
+ (cp_parser_parse_tentatively): Likewise.
+ (cp_parser_parse_definitely): Likewise.
+ (yyparse): Likewise.
+ (cp_parser_init_declarator): Remove access_checks parameter.
+ Use new deferred access functions.
+ (cp_parser_function_definition_from_specifiers_and_declarator):
+ Likewise.
+ (cp_parser_class_head): Remove deferring_access_checks_p and
+ saved_access_checks parameters. Use new deferred access functions.
+ (cp_parser_member_specification_opt): Don't call
+ reset_type_access_control.
+ * search.c (type_access_control): Remove.
+ * semantics.c: Include "gt-cp-semantics.h".
+ (deferred_type_access_control): Remove.
+ (deferred_access_stack): New variable.
+ (deferred_access_free_list): Likewise.
+ (push_deferring_access_checks): New function.
+ (resume_deferring_access_checks): Likewise.
+ (stop_deferring_access_checks): Likewise.
+ (pop_deferring_access_checks): Likewise.
+ (get_deferred_access_checks): Likewise.
+ (pop_to_parent_deferring_access_checks): Likewise.
+ (perform_deferred_access_checks): New function, adapted from
+ cp_parser_perform_deferred_access_checks.
+ (perform_or_defer_access_check): New function, adapted from
+ cp_parser_defer_access_check.
+ (current_type_lookups): Remove.
+ (deferred_type_access_control): Likewise.
+ (decl_type_access_control): Likewise.
+ (save_type_access_control): Likewise.
+ (reset_type_access_control): Likewise.
+ (begin_function_definition): Adjust.
+ (begin_class_definiton): Likewise.
+
+2003-01-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/8748
+ * class.c (build_base_path): Take the address before calling save_expr.
+
+ * call.c (build_user_type_conversion_1): Do set ICS_BAD_FLAG if
+ all the ambiguous conversions are bad.
+
+ * class.c (maybe_warn_about_overly_private_class): Don't stop
+ searching when we find a nonprivate method.
+
+ * typeck.c (build_class_member_access_expr): Use unary_complex_lvalue.
+
+2003-01-12 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (get_arglist_len_in_bytes): Remove.
+
+ PR c++/9264
+ * parser.c (cp_parser_elaborated_type_specifier): Handle erroneous
+ typeame types more robustly.
+
+2003-01-11 Phil Edwards <pme@gcc.gnu.org>
+
+ * parser.c: Fix comment typos.
+
+2003-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9099
+ * parser.c (cp_parser_scope_through_which_access_occurs): Handle
+ an object_type which is not a class type.
+
+2003-01-10 Geoffrey Keating <geoffk@apple.com>
+
+ * parser.c (cp_parser_late_parsing_for_member): Don't cast to void.
+ (cp_parser_late_parsing_default_args): Likewise.
+
+2003-01-10 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cfns.gperf: ANSIfy function declarations.
+ * cfns.h: Regenerate.
+ * cp-tree.h: ANSIfy function declarations.
+
+2003-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (reparse_absdcl_as_expr): Remove.
+ (reparse_absdcl_as_casts): Likewise.
+ (reparse_decl_as_expr): Likewise.
+ (finish_decl_parsing): Likewise.
+ * decl2.c (reparse_absdcl_as_expr): Remove.
+ (reparse_absdcl_as_casts): Likewise.
+ (repase_decl_as_expr): Likewise.
+ (finish_decl_parsing): Likewise.
+
+ PR c++/9128
+ PR c++/9153
+ PR c++/9171
+ * parser.c (cp_parser_pre_parsed_nested_name_specifier): New
+ function.
+ (cp_parser_nested_name_specifier_opt): Correct the
+ check_dependency_p false.
+ (cp_parser_postfix_expression): Fix formatting.
+ (cp_parser_decl_specifier_seq): Avoid looking for constructor
+ declarators when possible.
+ (cp_parser_template_id): Avoid performing name-lookup when
+ possible.
+ (cp_parser_class_head): Do not count specializations when counting
+ levels of templates.
+ (cp_parser_constructor_declarator_p): Return immediately if
+ there's no chance that the tokens form a constructor declarator.
+ * rtti.c (throw_bad_typeid): Add comment. Do not return an
+ expression with reference type.
+ (get_tinfo_decl_dynamic): Do not return an expression with
+ reference type.
+ (build_typeid): Add comment. Do not return an expression with
+ reference type.
+ * typeck.c (build_class_member_access_expr): Improve handling of
+ conditionals and comma-expressions as objects.
+
+2003-01-09 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cfns.gperf: ANSIfy function declarations.
+ * cfns.h: Regenerate.
+ * cp-tree.h: ANSIfy function declarations.
+ * parser.c: ANSIfy function declarations & definitions.
+
+ * decl.c (bad_specifiers): Fix parameter order error I introduced.
+
+2003-01-09 Geoffrey Keating <geoffk@apple.com>
+
+ Merge from pch-branch:
+
+ 2003-01-09 Geoffrey Keating <geoffk@apple.com>
+
+ Merge to tag pch-merge-20030102:
+
+ * semantics.c (finish_translation_unit): Don't call finish_file.
+ * parser.c: Don't include ggc.h.
+ (cp_lexer_new_main): Rename from cp_lexer_new, only create main lexer,
+ read first token here. Don't allow PCH files after the first
+ token is read.
+ (cp_lexer_new_from_tokens): Duplicate functionality from cp_lexer_new.
+ (cp_lexer_get_preprocessor_token): Allow LEXER to be NULL.
+ (cp_parser_new): Call cp_lexer_new_main before allocating GCed memory.
+ (cp_parser_late_parsing_for_member): Don't duplicate call to
+ cp_lexer_set_source_position_from_token.
+ (cp_parser_late_parsing_default_args): Likewise.
+ (yyparse): Call finish_file after clearing the_parser.
+
+ 2002-12-11 Geoffrey Keating <geoffk@apple.com>
+
+ * Make-lang.in: Remove $(GGC_H) from all dependencies.
+ (CXX_TREE_H): Add $(GGC_H).
+ * class.c: Don't include ggc.h.
+ (field_decl_cmp): Make parameters be 'const void *' to match qsort.
+ (method_name_cmp): Likewise.
+ (resort_data): New variable.
+ (resort_field_decl_cmp): New.
+ (resort_method_name_cmp): New.
+ (resort_sorted_fields): New.
+ (resort_type_method_vec): New.
+ (finish_struct_methods): Delete cast.
+ (finish_struct_1): Delete cast.
+ * cp-tree.h: Include ggc.h.
+ (struct lang_type_class): Add reorder attribute to field `methods'.
+ (union lang_decl_u3): Add reorder attribute to field `sorted_fields'.
+ (resort_sorted_fields): New prototype.
+ (resort_type_method_vec): New prototype.
+ * call.c: Don't include ggc.h.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * init.c: Likewise.
+ * lex.c: Likewise.
+ * method.c: Likewise.
+ * optimize.c: Likewise.
+ * parse.y: Likewise.
+ * pt.c: Likewise.
+ * repo.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+
+ * lang-specs.h: Remove comment.
+
+ 2002-12-03 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (struct operator_name_info_t): Mark for GTY machinery.
+ (operator_name_info): Mark to be saved for PCH, specify size.
+ (assignment_operator_name_info): Likewise.
+
+ 2002-11-19 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (anon_cnt): Mark to be saved for PCH.
+
+ 2002-10-25 Geoffrey Keating <geoffk@apple.com>
+
+ * lex.c (init_reswords): Delete now-untrue comment.
+ Allocate ridpointers using GGC.
+
+ 2002-10-04 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (union lang_decl_u2): Add tags to all fields.
+
+ * g++spec.c (lang_specific_driver): Don't include standard
+ libraries in `added'.
+
+ 2002-08-27 Geoffrey Keating <geoffk@redhat.com>
+
+ * decl2.c (finish_file): Call c_common_write_pch.
+ * Make-lang.in (CXX_C_OBJS): Add c-pch.o.
+
+ 2002-08-17 Geoffrey Keating <geoffk@redhat.com>
+
+ * g++spec.c (lang_specific_driver): Treat .h files as C++ header
+ files when using g++.
+ * lang-specs.h: Handle compiling C++ header files.
+
+2003-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (start_decl): Only check DECL_THREAD_LOCAL for VAR_DECLs.
+
+2003-01-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (push_access_scope_real): Call push_to_top_level for
+ function in namespace scope.
+ (pop_access_scope): Call pop_from_top_level for function in
+ namespace scope.
+
+2003-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (start_decl): Don't set DECL_COMMON for __thread variables.
+
+2003-01-09 Christian Cornelssen <ccorn@cs.tu-berlin.de>
+
+ * Make-lang.in (c++.install-common, c++.install-man,
+ c++.uninstall): Prepend $(DESTDIR) to destination paths in
+ all (un)installation commands.
+ (c++.install-common): Rewrite $(LN) commands to support
+ DESTDIR with "ln" as well as with "ln -s".
+
+2003-01-08 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_primary_expression): See through explicitly
+ scoped ALIAS_DECLs, too.
+
+2003-01-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * decl.c: Remove some #if 0 code.
+
+ * decl.c: ANSIfy function declarations.
+
+2003-01-07 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_asm_definition): Correct handling of omitted
+ operands.
+
+2003-01-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9030
+ * decl.c (make_typename_type): Check access only when tf_error.
+ (make_unbound_class_template): Likewise.
+ * pt.c (saved_access_scope): New variable.
+ (push_access_scope_real): New function.
+ (push_access_scope): Likewise.
+ (pop_access_scope): Likewise.
+ (tsubst_default_argument): Use them.
+ (instantiate_template): Likewise.
+ (regenerate_decl_from_template): Likewise.
+ (instantiate_decl): Likewise.
+ (get_mostly_instantiated_function_type): Likewise.
+
+2003-01-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * tree.c: Delete bogus #if 0 code.
+
+2003-01-07 Andreas Schwab <schwab@suse.de>
+
+ * class.c (layout_class_type): Don't use
+ PCC_BITFIELD_TYPE_MATTERS if not defined.
+
+2003-01-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9165
+ * decl2.c (build_cleanup): Mark the object as used.
+
+ * pt.c (retrieve_local_specialization): Revert 2003-01-05 change.
+ (hash_local_specialization): New function.
+ (register_local_specialization): Revert 2003-01-05 change.
+ (instantiate_decl): Use hash_local_specialization when creating
+ the local_specializations table.
+
+ * decl2.c (mark_used): Do not synthesize thunks.
+
+ * class.c (layout_class_type): Correct handling of unnamed
+ bitfields wider than their types.
+
+ PR c++/9189
+ * parser.c (cp_parser): Remove default_arg_types. Update
+ documentation for unparsed_functions_queues.
+ (cp_parser_late_parsing_default_args): Take a FUNCTION_DECL as the
+ parameter.
+ (cp_parser_new): Don't set parser->default_arg_types.
+ (cp_parser_function_definition): Adjust usage of
+ unparsed_funtions_queues.
+ (cp_parser_class_specifier): Don't mess with
+ parser->default_arg_types. Handle default argument processing in
+ a separate phase from function body processing.
+ (cp_parser_template_declaration_after_export): Adjust usage of
+ unparsed_functions_queues.
+ (cp_parser_late_parsing_for_member): Do not handle default
+ arguments.
+
+2003-01-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9109
+ * parser.c (cp_parser_declarator_kind): New enum.
+ (cp_parser_declarator): Adjust.
+ (cp_parser_direct_declarator): Adjust. Allow for either named or
+ abstract declarator. Prefer abstract, if possible. Allow
+ parenthesized function name.
+ (cp_parser_condition): Adjust cp_parser_declarator call.
+ (cp_parser_explicit_instantiation): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_type_id): Likewise.
+ (cp_parser_function_definition): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_parameter_declaration): Use cp_parser_declarator to do
+ the tentative parsing.
+ (cp_parser_exception_declaration): Likewise.
+
+2003-01-05 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_template_parameter): Adjust call to
+ cp_parser_parameter_declaration.
+ (cp_parser_parameter_declaration_list): Likewise.
+ (cp_parser_parameter_declaration): Replace
+ greater_than_is_operator_p with template_parm_p parameter. Do not
+ cache tokens for template default arguments.
+
+ * pt.c (retrieve_local_specialization): Use htab_find, not
+ htab_find_with_hash.
+ (register_local_specialization): Use htab_find_slot, not
+ htab_find_slot_with_hash.
+ (instantiate_decl): Pass a hash function to htab_create.
+
+2003-01-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * parser.c (cp_parser_binary_expression,
+ cp_parser_multiplicative_expression,
+ cp_parser_additive_expression, cp_parser_shift_expression,
+ cp_parser_relational_expression, cp_parser_equality_expression,
+ cp_parser_and_expression, cp_parser_exclusive_or_expression,
+ cp_parser_inclusive_or_expression,
+ cp_parser_logical_and_expression, cp_parser_logical_or_expression,
+ cp_parser_binary_expression): Const-ify.
+
+2003-01-04 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (use_thunk): Disable access control while building the
+ body of the thunk.
+
+2003-01-03 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cvt.c, decl.c, decl2.c: This is the C++ front end, not the C
+ front end.
+
+2003-01-03 Matt Austern <austern@apple.com>
+
+ * cp-tree.h (struct lang_type_class): add field for key method
+ (cp_global_trees): rename dynamic_classes to keyed_classes
+ (key_method): add definition
+ * class.c (finish_struct_1): compute class's key method, and add
+ the class to keyed_classes list if there is no key method.
+ * decl.c (finish_function): add class to keyed_classes list if we
+ see a definition of the class's key method.
+ * pt.c (instantiate_class_template): add template specialization
+ of a dynamic class to keyed_classes list.
+ * decl2.c (key_method): remove
+ (finish_file): iterate only through keyed_classes list when
+ deciding whether to emit vtables, remove class from its list after
+ we do the emission.
+
+2003-01-02 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_conditional_expr): Stabilize lvalues properly.
+ * cvt.c (ocp_convert): Don't build NOP_EXPRs of class type.
+ * tree.c (lvalue_p_1): Don't allow sloppy NOP_EXPRs as lvalues.
+ Don't allow CALL_EXPR or VA_ARG_EXPR, either.
+
+ * call.c (convert_like_real): Call decl_constant_value for an
+ IDENTITY_CONV even if there are no more conversions.
+
+ * cvt.c (build_up_reference): Don't push unnamed temps.
+
+ * decl2.c (do_namespace_alias): Namespace aliases are DECL_EXTERNAL.
+
+ * dump.c (cp_dump_tree): Don't try to dump class-specific fields
+ for a backend struct.
+
+ * except.c (wrap_cleanups_r, build_throw): Make
+ MUST_NOT_THROW_EXPRs void.
+ * init.c (expand_default_init): Update to handle MUST_NOT_THROW_EXPR.
+
+ * init.c (build_vec_delete_1): Pre-evaluate the base address.
+
+ * init.c (get_temp_regvar): Simplify logic.
+
+ * tree.c (cp_copy_res_decl_for_inlining): Only do debug tweaks if
+ our replacement is a decl.
+
+ * decl.c (cp_make_fname_decl): Push the decls inside the
+ outermost scope.
+
+2003-01-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/45, c++/3784
+ * tree.c (cp_tree_equal, TEMPLATE_PARM_INDEX): The types must be
+ the same too.
+
+2003-01-03 Graham Stott <graham.stott@btinternet.com>
+
+ * parser.c (struct cp_parser): Add access_checks_lists field
+ (cp_parser_simple_declaration): Use.
+ (cp_parser_init_declarator): Likewise.
+
+2003-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_declaration): Accept the __extension__
+ keyword before the declaration.
+
+ PR c++/2843
+ * parser.c (cp_parser_parameter_declaration): Allow attributes to
+ appear after the declarator.
+
+ * call.c (build_new_method_call): Fix typo in message format
+ string.
+
+2003-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_lexer_next_token_is): Declare it inline.
+ (cp_lexer_set_source_position_from_token): Likewise.
+ (cp_lexer_debugging_p): Likewise.
+ (cp_parser_parsing_tentatively): Likewise.
+ (cp_parser_nested_name_specifier_opt): Reduce the number of calls
+ to the cp_lexer_peek_token.
+
+ * parser.c (cp_parser_sizeof_operand): Do not evaluate the
+ expression.
+
+2003-01-02 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * cp/except.c, cp/expr.c, cp/friend.c, cp/g++spec.c,
+ cp/lang-options.h, cp/lang-specs.h, cp/lex.h, cp/ptree.c,
+ cp/repo.c: Fix copyright years.
+
+2003-01-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * lex.c: Remove superfluous include of cpplib.h.
+ (CONSTRAINT): Define without conditions.
+ (init_cp_pragma): Use c_register_pragma.
+
+
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2004 b/gcc-4.9/gcc/cp/ChangeLog-2004
new file mode 100644
index 000000000..602745f7e
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2004
@@ -0,0 +1,6884 @@
+2004-12-31 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/17799
+ * call.c (make_temporary_var_for_ref_to_temp): Set DECL_IGNORED_P.
+ * class.c (build_vtable): Don't conditionallize setting it
+ based on DWARF2_DEBUG.
+ (layout_class_type): Set DECL_IGNORED_P.
+ * decl2.c (get_guard): Likewise.
+ * rtti.c (get_tinfo_decl, build_lang_decl): Likewise.
+ * tree.c (build_local_temp): Likewise.
+
+2004-12-30 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_declarator): Split "name" field into
+ qualifying_scope and unqualified_name.
+ * decl.c (get_scope_of_declarator): Adjust accordingly.
+ (grokdeclarator): Likewise.
+ * decl2.c (grokfield): Likewise, and adjust call to
+ do_class_using_decl.
+ * name-lookup.c (do_class_using_decl): Split "decl" into
+ "scope" and "name". Remove unnecessary code.
+ * name-lookup.h (do_class_using_decl): Adjust declaration.
+ * parser.c (make_id_declarator): Split "id" into qualifying_scope
+ and unqualified_name.
+ (cp_parser_using_declaration): Adjust call to do_class_using_decl.
+ (cp_parser_direct_declarator): Adjust to handle the fact that
+ cp_parser_declarator_id no longer returns a SCOPE_REF.
+ (cp_parser_direct_declarator): Likewise.
+ (cp_parser_declarator_id): Do not create a SCOPE_REF for qualified
+ names.
+ (cp_parser_member_declaration): Adjust call to make_id_declarator.
+ (cp_parser_check_declarator_template_parameters): Do not expect a
+ SCOPE_REF.
+
+ * decl.c (duplicate_decls): Call ggc_free on declarations we will
+ not be needing any longer.
+
+ PR c++/19190
+ * cvt.c (convert_to_void): Do not use STRIP_NOPs.
+
+2004-12-28 Richard Henderson <rth@redhat.com>
+
+ PR inline-asm/15740
+ * semantics.c (finish_asm_stmt): Resolve asm names. Validate input
+ constraints. Mark memory inputs addressable.
+
+2004-12-27 Jason Merrill <jason@redhat.com>
+
+ * decl.c (expand_static_init): Don't use shortcut if
+ targetm.relaxed_ordering.
+
+2004-12-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19149
+ * decl.c (check_tag_decl): Robustify.
+
+2004-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17595
+ * parser.c (cp_parser_error): Issue better messages about
+ #pragma in locations where it is not permitted.
+
+ PR c++/17413
+ * pt.c (check_instantiated_args): Remove bogus SFINAE code.
+
+ * cvt.c (convert_to_void): Fix typo in comment.
+
+2004-12-23 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/18962
+ * pt.c (check_explicit_specialization): Use the argument list from
+ the definition in a template function specialization definition.
+
+2004-12-23 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/18733
+ * pt.c (check_explicit_specialization): Use special logic to validate
+ befriended specializations.
+
+2004-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ * rtti.c (emit_support_tinfos): Avoid using C99 semantics.
+
+ PR c++/18464
+ * call.c (build_this): In templates, do not bother with
+ build_unary_op.
+ * typeck.c (unary_complex_lvalue): In a template, always refuse
+ simplifications.
+
+ PR c++/18492
+ * cp-gimplify.c (cp_genericize): Relax assertion.
+
+ PR c++/11224
+ * cvt.c (convert_to_void): Warn about unused values.
+
+ PR c++/18257
+ * rtti.c (emit_support_tinfos): On systems without weak symbols,
+ emit the runtime library type-info objects as non-COMDAT.
+
+2004-12-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18378
+ * call.c (convert_like_real): Do not permit the use of a copy
+ constructor to copy a packed field.
+
+ PR c++/19063
+ * decl.c (grokdeclarator): Return error_mark_node, not
+ void_type_node, to indicate errors.
+ * parser.c (cp_parser_template_parameter_list): Robustify.
+ (cp_parser_template_parameter): Likewise.
+
+ PR c++/19034
+ * tree.c (cp_tree_equal): Handle OVERLOAD.
+
+2004-12-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * decl.c (define_label): Use POP_TIMEVAR_AND_RETURN.
+ * name-lookup.c (pushdecl_class_level): Likewise.
+
+2004-12-21 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * name-lookup.c (pushtag): Add missing POP_TIMEVAR_AND_RETURN.
+
+2004-12-21 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/18984
+ * cp-gimplify.c (cp_genericize_r): Don't insert first but instead
+ check to see if contains the pointer. Insert the statement before
+ returning.
+
+2004-12-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/14075
+ * decl.c (check_initializer): Check string initializer of array is
+ not parenthesized.
+ * cp-tree.h (PAREN_STRING_LITERAL_P): New.
+ * semantics.c (finish_parenthesized_expr): Mark a STRING_CST.
+ * error.c (dump_expr): <STRING_CST case> Add parens, if needed.
+
+ * cp-tree.def (TEMPLATE_TYPE_PARM,
+ BOUND_TEMPLATE_TEMPLATE_PARM, TYPE_OF_TYPE, TYPENAME_TYPE): Reorder
+ for better code efficiency.
+ * cp-tree.h (CLASS_TYPE_P): Short circuit IS_AGGR_TYPE check.
+ (CAN_HAVE_FULL_LANG_DECL_P): Reorder for better optimization.
+ (INTEGRAL_CODE_P, CP_INTEGRAL_TYPE_P,
+ INTEGRAL_OR_ENUMERATION_TYPE_P, SCALAR_TYPE_P,
+ CP_AGGREGATE_TYPE_P, TYPE_PTROB_P, TYPE_REF_OBJ_P,
+ TYPE_PTROBV_P): Likewise.
+
+ PR c++/18975
+ * method.c (do_build_copy_constructor): Refactor. Don't const
+ qualify a mutable field.
+ (do_build_assign_ref): Likewise.
+
+2004-12-20 Matt Austern <austern@apple.com>
+
+ PR c++/19044
+ * decl.c (make_rtl_for_nonlocal_decl): Use
+ set_builtin_user_assembler_name.
+
+2004-12-19 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (note_decl_for_pch): New function.
+ * class.c (build_clone): Call note_decl_for_pch.
+ * semantics.c (finish_member_declaration): Likewise.
+ (note_decl_for_pch): New function.
+
+2004-12-17 Steven Bosscher <stevenb@suse.de>
+
+ * init.c (build_zero_init): max_index is the number of
+ elements, minus 1.
+
+2004-12-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18721
+ * class.c (add_method): Do not push conversion operators into a
+ binding level.
+
+ * cp-tree.h (CLASSTYPE_PRIMARY_TEMPLATE_TYPE): Reformat.
+ * error.c (dump_decl): <TYPE_DECL case> Remove extraneous braces.
+
+2004-12-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18905
+ * cp-tree.h (integral_constant_value): Declare.
+ * call.c (null_ptr_cst_p): Use integral_constant_value, not
+ decl_constant_value.
+ (convert_like_real): Likewise.
+ * class.c (check_bitfield_decl): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ (convert): Remove unnecessary decl_constant_value call.
+ * decl.c (compute_array_index_type): Use integral_constant_value,
+ not decl_constant_value.
+ (build_enumerator): Likewise.
+ * decl2.c (grokfield): Likewise.
+ * init.c (decl_constant_value): Simplify.
+ (integral_constant_value): New.
+ * pt.c (fold_decl_constant_value): Use integral_constant_value,
+ remove subsequent check.
+ (tsubst): Use integral_constant_value, not decl_constant_value.
+ (tsubst_copy, unify): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+ (build_compound_expr): Remove unnecessary decl_constant_value
+ calls.
+ (build_static_cast_1, build_reinterpret_cast_1):
+ (convert_for_assignment): Remove comment about not calling
+ decl_constant_value.
+
+2004-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/18825
+ * pt.c (instantiate_class_template): Set input_location for
+ friend function.
+ (tsubst_friend_function): Don't set input_location here.
+ Make sure the context is complete if necessary.
+
+2004-12-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18981
+ * parser.c (cp_parser_lookup_name): Remove unneeded TYPENAME_TYPE
+ flag setting.
+
+2004-12-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18738
+ * decl.c (make_typename_type): Do not handle namespace-scoped
+ names here.
+ (tag_name): Handle typename_type.
+ (check_elaborated_type_specifier): Handle typenames.
+ * parser.c (cp_parser_diagnose_invalid_type_name): Improve
+ comment.
+ (cp_parser_elaborated_type_specifier): Use
+ cp_parser_diagnose_invalid_type_name.
+
+2004-12-14 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/18965
+ * init.c (build_zero_init): If the max_index is 0, there is no
+ need to create a RANGE_EXPR.
+
+2004-12-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18793
+ * cp-objcp-common.c (cp_expr_size): Loosen assertion.
+
+2004-12-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18949
+ * pt.c (tsubst_copy_and_build): <INDIRECT_REF case> Check that a
+ REFERENCE_REF_P is dereferencing a reference type.
+ * typeck.c (build_static_cast): Convert from reference even in a
+ template.
+ (build_reinterpret_cast, build_const_cast, build_c_cast): Likewise.
+
+2004-12-14 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * parser.c (cp_parser_uncommitted_to_tentative_parse_p): New function.
+ (cp_parser_name_lookup_error): Use it.
+ (cp_parser_check_for_invalid_template_id): Likewise.
+ (cp_parser_skip_to_closing_parenthesis): Likewise.
+ (cp_parser_nested_name_specifier_opt): Likewise.
+ (cp_parser_simple_declaration, cp_parser_template_id): Likewise.
+ (cp_parser_parameter_declaration_list): Likewise.
+ (cp_parser_parameter_declaration): Likewise.
+ (cp_parser_template_name): Let cp_parser_simulate_error perform
+ the checking.
+ (cp_parser_committed_to_tentative_parse): Remove.
+
+2004-12-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/18968
+ * class.c (build_base_path): Convert the zero constant to the correct
+ type when comparing.
+
+2004-12-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18925
+ * class.c (layout_class_type): Determine the visibility of static
+ data members.
+
+2004-12-12 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/12454
+ * cp-gimplify.c (gimplify_if_stmt): Optimize the case where the
+ condition is a constant and the unexecuted clause is empty.
+
+2004-12-10 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/18731
+ * parser.c (cp_parser_class_head): Reject typedef-name in class head.
+
+2004-12-09 Matt Austern <austern@apple.com>
+
+ PR c++/18514
+ * name-lookup.c (do_nonmember_using_decl): A real function
+ declaration takes precedence over an anticipated declaration.
+
+2004-12-09 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * parser.c (cp_parser_member_declaration): Fix comment typo.
+
+2004-12-09 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/18757
+ * parser.c (cp_parser_template_id): Don't create a CPP_TEMPLATE_ID
+ if parsing failed.
+
+2004-12-09 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/18073
+ * typeck.c (build_reinterpret_cast_1): Allow cast from vector type.
+
+2004-12-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/16681
+ * init.c (build_zero_init): Build a RANGE_EXPR for an array
+ initializer.
+
+2004-12-08 Kelley Cook <kcook@gcc.gnu.org>
+
+ * typeck.c: Remove DOS line endings.
+
+2004-12-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/18100
+ * decl.c (lookup_and_check_tag): Diagnose nested class with
+ the same name as enclosing class.
+
+2004-12-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18803
+ * cp-tree.h (REFERENCE_REF_P): New.
+ (CPTI_TYPE_INFO_TYPE): Rename to ...
+ (CPTI_CONST_TYPE_INFO_TYPE): ... here.
+ (CPTI_TYPE_INFO_REF_TYPE): Remove.
+ (type_info_type_node): Rename to ...
+ (const_type_info_type_node): ... here.
+ (type_info_ref_type): Remove.
+ * call.c (build_user_type_conversion): Reformat.
+ (resolve_args): Do not convert_from_reference.
+ (build_object_call): Call convert_from_reference.
+ (prep_operand): Do not convert_from_reference.
+ (build_new_method_call): Likewise.
+ * class.c (build_vfield_ref): Likewise.
+ * cvt.c (convert_to_reference): Likewise.
+ (convert_from_reference): Build INDIRECT_REF here, not with
+ build_indirect_ref.
+ (convert_force): Do not convert_from_reference.
+ (build_expr_type_conversion): Likewise.
+ * decl.c (grok_reference_init): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+ * except.c (initialize_handler_parm): Use POINTER_TYPE_P.
+ * init.c (build_dtor_call): Do not convert_from_reference.
+ * parser.c (cp_parser_template_argument): Unwrap indirected
+ reference. Allow TEMPLATE_PARM_INDEX as an object parm.
+ * pt.c (tsubst_copy_and_build) <case INDIRECT_REF>: Use
+ convert_from_reference, if indicated.
+ <case CALL_EXPR>: Do not convert_from_reference.
+ <case PARM_DECL, VAR_DECL>: Convert_from_reference if needed.
+ (tsubst_initializer_list): Do not convert_from_reference.
+ * rtti.c (init_rtti_processing): Adjust node creation.
+ (throw_bad_typeid): Use const_type_info_type_node.
+ Do not convert_from_reference.
+ (typeid_ok_p): Use const_type_info_type_node.
+ (build_typeid, get_typeid): Always return type_info typed node.
+ (build_dynamic_cast_1): Dont convert_from_reference. Refactor.
+ * semantics.c (finish_stmt_expr_expr): Do not
+ convert_from_reference.
+ (finish_id_expression): Convert_from_reference as appropriate.
+ * typeck.c (decay_conversion): Do not convert_from_reference.
+ (finish_class_member_access_expr): Likewise.
+ (build_indirect_ref): Use POINTER_TYPE_P.
+ (convert_arguments): Do not convert_from_reference.
+ (build_modify_expr): Likewise.
+ (convert_for_initialization): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2004-12-07 Ziemowit Laski <zlaski@apple.com>
+
+ * cp-tree.h (struct lang_type_class): Rename 'objc_protocols'
+ field to 'objc_info'.
+
+2004-12-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * pt.c: Replace a use of first_rtl_op with TREE_CODE_LENGTH.
+
+2004-12-07 Roger Sayle <roger@eyesopen.com>
+
+ * name-lookup.c (leave_scope): We only need to update
+ class_binding_level when leaving a class scope.
+
+2004-12-06 Ziemowit Laski <zlaski@apple.com>
+
+ * cp-tree.h (struct lang_type_class): Add 'objc_protocols' field.
+
+2004-12-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/17011, c++/17971
+ * pt.c (tsubst_copy) <FIELD_DECL case>: Check and diagnose
+ invalid field.
+ (tsubst_copy_and_build) <COMPONENT_REF case>: Check
+ error_mark_node after member substitution.
+ * semantics.c (finish_id_expression): Call
+ finish_non_static_data_member for non-dependent FIELD_DECL.
+
+2004-12-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18782
+ * decl.c (grokdeclarator): Make sure class in pointer to member is
+ not a namespace.
+
+2004-12-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18318
+ * parser.c (cp_parser_new_type_id): Move array size expression
+ checks from here ...
+ * init.c (build_new): ... to here.
+
+2004-12-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18758
+ * parser.c (cp_parser_class_head): Return NULL_TREE when
+ push_template_decl fails. Update comment.
+
+2004-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/15664, c++/18276
+ * pt.c (tsubst_decl) <TEMPLATE_DECL case>: Reorganize. Correctly
+ tsubst TEMPLATE_DECL that is a TEMPLATE_TEMPLATE_PARM.
+
+2004-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/18123
+ * parser.c (cp_parser_type_specifier): Catch template declaration
+ of enum.
+
+2004-12-01 Matt Austern <austern@apple.com>
+
+ * name-lookup.c (namespace_binding): Omit alias check for global
+ namespace.
+
+2004-12-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18729
+ * parser.c (cp_parser_class_name): Check decl's type is not
+ error_mark_node.
+
+ PR c++/17431
+ * call.c (standard_conversion): Add FLAGS parameter. Do not allow
+ derived to base conversion when checking constructor
+ accessibility.
+ (implicit_conversion): Pass FLAGS to standard_conversion.
+ (check_constructir_callable): Disallow conversion functions.
+
+2004-11-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * parser.c: Fix comment typos.
+
+2004-11-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18368
+ * parser.c (cp_parser_check_for_definition_in_return_type): Take
+ the defined type as a parameter, and inform the user about the
+ possibility of a missing semicolon.
+ (cp_parser_explicit_instantiation): Adjust call to
+ cp_parser_check_for_definition_in_return_type.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_member_declaration): Likewise.
+
+ PR c++/18674
+ * cp-tree.def (TYPENAME_TYPE): Remove discussion of implicit
+ typename from comments.
+ * cp-tree.h (TYPENAME_IS_ENUM_P): New macro.
+ (TYPENAME_IS_CLASS_P): Likewise.
+ (make_typename_type): Change prototype.
+ * decl.c (struct_typename_info): New type.
+ (typename_compare): Expect the second argument to be a
+ typename_info, not a tree.
+ (build_typename_type): Add tag_type parameter. Do not create a
+ new type until necessary.
+ (make_typename_type): Add tag_type parameter.
+ * error.c (TYPENAME_TYPE): Print tags other than "typename" if
+ appropriate.
+ * friend.c (make_friend_class): Adjust call to make_typename_type.
+ * parser.c (cp_parser_make_typename_type): Likewise.
+ (cp_parser_primary_expression): Adjust call to
+ cp_parser_lookup_name.
+ (cp_parser_unqualified_id): Adjust calls to cp_parser_class_name.
+ (cp_parser_class_or_namespace_name): Likewise.
+ (cp_parser_postfix_expression): Adjust calls to
+ make_typename_type.
+ (cp_parser_mem_initializer_id): Adjust calls to
+ cp_parser_class_name.
+ (cp_parser_type_parameter): Adjust calls to cp_parser_lookup_name.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_template_argument): Likewise.
+ (cp_parser_type_name): Adjust call to cp_parser_class_name.
+ (cp_parser_elaborated_type_specifier): Adjust calls to
+ make_typename_type and cp_parser_lookup_name.
+ (cp_parser_namespace_name): Likewise.
+ (cp_parser_class_name): Replace type_p parameter with tag_type.
+ Adjust calls to make_typename_type and cp_parser_lookup_name.
+ (cp_parser_class_head): Adjust calls to cp_parser_class_name.
+ (cp_parser_base_specifier): Likewise.
+ (cp_parser_lookup_name): Replace is_type parameter with tag_type.
+ Adjust calls to make_typename_type and lookup_qualified_name.
+ (cp_parser_lookup_name_simple): Adjust call to
+ cp_parser_lookup_name.
+ (cp_parser_constructor_declarator_p): Adjust call to
+ cp_parser_class_name.
+ * pt.c (convert_template_argument): Adjust all to
+ make_typename_type.
+ (tsubst_decl): Do not pre-substitute the type of the declaration.
+ (tsubst): Hand off declarations more quickly. Adjust call to
+ make_typename_type.
+
+ PR c++/18512
+ * parser.c (cp_parser_postfix_dot_deref_expression): Robustify.
+
+2004-11-29 Daniel Jacobowitz <dan@codesourcery.com>
+
+ PR c/7544
+ * Make-lang.in (cp/decl2.o): Update dependencies.
+ * decl2.c (finish_file): Call maybe_apply_pending_pragma_weaks.
+
+2004-11-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/18652
+ * name-lookup.c (pushtag): Change return type to tree.
+ * cp-tree.h (pushtag): Adjust declaration.
+ * decl.c (xref_tag, start_enum): Use return value of pushtag.
+ * pt.c (push_template_decl_real): Return immediately if
+ pushdecl_namespace_level returns error_mark_node.
+
+2004-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * pt.c: Fix a comment typo.
+
+2004-11-27 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ Friend class name lookup 4/n
+ * class.c (pushclass): Don't call cxx_remember_type_decls.
+ * cp-tree.h (clear_anon_tags): Remove declaration.
+ * decl.c (grokdeclarator): Don't call lookup_tag_reverse.
+ * name-lookup.c (binding_entry_free, binding_table_free): Comment
+ out functions.
+ (binding_table_find_anon_type, binding_table_reverse_maybe_remap,
+ binding_table_remove_anonymous_types, cxx_remember_type_decls,
+ bt_print_entry, clear_anon_tags, follow_tag_typedef, lookup_tag,
+ lookup_tag_reverse): Remove
+ (begin_scope, leave_scope, kept_level_p, print_binding_level):
+ Don't use type_decls field in cp_binding_level.
+ (maybe_process_template_type_declaration, pushtag): Set
+ CLASSTYPE_NESTED_UTDS directly.
+ * name-lookup.h (binding_table_remove_anonymous_types,
+ cxx_remember_type_decls, lookup_tag, lookup_tag_reverse): Remove
+ declaration.
+ (cp_binding_level): Remove type_decls field.
+
+2004-11-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * typeck.c: Fix a comment typo.
+
+2004-11-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18445
+ * class.c (instantiate_type): Treat NON_DEPENDENT_EXPRs with
+ unknown_type as non matching. Tidy up.
+ * pt.c (build_non_dependent_expr): Do not build a
+ NON_DEPENDENT_EXPR for a VAR_DECL.
+
+ PR c++/18001
+ * cp-tree.h (lvalue_or_else): Remove declaration.
+ * tree.c (lvalue_or_else): Remove.
+ * typeck.c (build_unary_op): Adjust call to lvalue_or_else.
+ (build_modify_expr): Likewise.
+
+ PR c++/18625
+ * decl.c (duplicate_decls): Return error_mark_node on error, as
+ specified.
+
+ PR c++/18466
+ * decl.c (grokvardecl): Keep track of whether or not a there was
+ explicit qualification.
+ * name-lookup.c (set_decl_namespace): Complain about explicit
+ qualification of a name within its own namespace.
+
+ PR c++/18545
+ * typeck.c (check_return_expr): Robustify.
+
+2004-11-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ Friend class name lookup 3/n, PR c++/3332
+ * name-lookup.c (push_inner_scope, pop_inner_scope): New functions.
+ (lookup_type_scope): Don't deal with name from user declaration
+ specially.
+ * name-lookup.h (push_inner_scope, pop_inner_scope): Add declarations.
+ * parser.c (cp_parser_class_specifier): Use push_inner_scope and
+ pop_inner_scope.
+
+2004-11-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ Friend class name lookup 2/n, PR c++/14513, c++/15410
+ * name-lookup.c (lookup_name_real): Simplify.
+ (lookup_type_scope): Add SCOPE parameter. Handle friend class
+ lookup.
+ * name-lookup.h (tag_scope): New enum type.
+ (lookup_type_scope): Adjust declaration.
+ * decl.c (lookup_and_check_tag, xref_tag, xref_tag_from_type):
+ Change bool parameter GLOBALIZED to TAG_SCOPE parameter SCOPE.
+ (start_enum): Likewise. Add assertion test that NAME is
+ IDENTIFIER_NODE. Use anonymous name for dummy ENUMERAL_TYPE in
+ case of error.
+ * cp-tree.h (xref_tag, xref_tag_from_type): Adjust declarations.
+ * parser.c (cp_parser_elaborated_type_specifier,
+ cp_parser_class_head): Adjust call to xref_tag.
+ * pt.c (lookup_template_class, instantiate_class_template):
+ Likewise.
+ * rtti.c (init_rtti_processing, build_dynamic_cast_1,
+ tinfo_base_init, emit_support_tinfos): Likewise.
+
+2004-11-25 Joseph S. Myers <joseph@codesourcery.com>
+
+ * g++spec.c, lex.c: Avoid ` as left quote in diagnostics.
+
+2004-11-24 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17473
+ * name-lookup.c (supplement_binding): Do not allow typedefs to be
+ redefined in class scope.
+
+ PR c++/18285
+ * parser.c (cp_parser_set_decl_type_spec): Do not try to allow
+ redefinitions of builtin types other that "bool" or "wchar_t".
+
+2004-11-24 Steven Bosscher <stevenb@suse.de>
+
+ * decl.c (cxx_init_decl_processing): Don't clear
+ flag_inline_functions.
+
+2004-11-24 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_function_type): Do not permit function types which
+ return arrays or functions.
+
+ PR c++/18586
+ * parser.c (cp_parser_init_declarator): Do not pop scope twice.
+
+ PR c++/18530
+ * cp-tree.h (CTOR_NAME): Remove.
+ (DTOR_NAME): Remove.
+ * decl.c (initialize_predefined_identifiers): Add spaces to the
+ end of constructor and destructor names.
+
+2004-11-24 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/8929
+ * decl.c (start_decl): Check for invalid specialization headers.
+
+2004-11-24 Paolo Bonzini <bonzini@gnu.org>
+
+ PR c++/16882
+
+ * call.c (standard_conversion): Move check for conversions between
+ vector pointers...
+ * typeck.c (ptr_reasonably_similar): ... here.
+
+2004-11-23 Ben Elliston <bje@au.ibm.com>
+
+ * cp-tree.h (context_as_string): Remove extern.
+ * error.c (context_as_string): Remove.
+
+ * cp-tree.h (cp_type_qual_from_rid): Remove extern.
+ * lex.c (cp_type_qual_from_rid): Remove.
+
+ * cp-tree.h (do_poplevel): Remove extern.
+ (check_multiple_declarators): Likewise.
+ * semantics.c (do_poplevel): Make static.
+ (check_multiple_declarators): Remove.
+
+ * cp-tree.h (check_final_overrider): Remove extern.
+ * search.c (check_final_overrider): Make static.
+
+ * cp-tree.h (build_artificial_parm): Remove extern.
+ * decl2.c (build_artificial_parm): Make static.
+
+2004-11-22 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/18354
+ * typeck.c (build_unary_op) <CONVERT_EXPR, NEGATE_EXPR>: Unify code.
+ Make sure the result is always a rvalue.
+
+2004-11-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * decl.c (start_preparsed_function): Call check_function_type even
+ in templates.
+ (require_complete_types_for_parms): Skip dependent types.
+ (check_function_type): Likewise.
+
+2004-11-16 Steven Bosscher <stevenb@suse.de>
+
+ * Make-lang.in (cp/decl.o, cp/search.o): Don't depend on stack.h.
+ * search.c: Don't include it.
+
+2004-11-15 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * cp-gimplify.c: Include pointer-set.h
+ (cp_genericize_r): Use pointer_sets instead of a hashtable.
+ Also instert the new statement for CLEANUP_STMT.
+ (cp_genericize): Use pointer_sets instead of a hashtable.
+ * Make-lang.in (cp-gimplify.o): Depend on pointer-set.h.
+
+2004-11-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ Friend class name lookup 1/n, PR c++/18471
+ * decl.c (lookup_and_check_tag): New function.
+ (xref_tag, start_enum): Use it.
+ (check_elaborated_type_specifier): Move TEMPLATE_TYPE_PARM check
+ before !DECL_IMPLICIT_TYPEDEF_P. Also display previously declared
+ location.
+ * name-lookup.c (lookup_name_current_level): Rename to ...
+ (lookup_name_innermost_nonclass_level): ... this.
+ (lookup_type_scope): New function.
+ * name-lookup.h (lookup_name_current_level): Rename to ...
+ (lookup_name_innermost_nonclass_level): ... this.
+ (lookup_type_scope): Add declaration.
+
+2004-11-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/17344
+ * pt.c (coerce_template_parms): Only emit error message about
+ invalid template argument when TF_ERROR.
+
+2004-11-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18389
+ * decl.c (start_decl): Make sure to set *pop_scope_p. Return
+ error_mark_node to indicate errors.
+
+ PR c++/18429
+ * parser.c (cp_parser_direct_declarator): Disallow non-constant
+ array bounds when not inside a function.
+
+ PR c++/18436
+ * pt.c (tsubst_copy_and_build): Do not do Koenig lookup when an
+ unqualified name resolves to a member function.
+
+ PR c++/18407
+ * pt.c (tsubst_copy_and_build): Handle qualified names used from a
+ derived class correctly.
+
+ * decl2.c (import_export_decl): Fix typo in comment.
+ * tree.c (pod_type_p): Likewise.
+
+2004-11-10 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * typeck.c (cxx_mark_addressable): Add braces around the first if.
+
+2004-11-10 Adam Nemet <anemet@lnxw.com>
+
+ PR middle-end/18160
+ * typeck.c (cxx_mark_addressable): Issue an error if address of an
+ explicit register variable is requested.
+
+2004-11-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18143
+ * cp-tree.h (NON_THUNK_FUNCTION_CHECK, THUNK_FUNCTION_CHECK): New.
+ (struct lang_decl_flags): Add thunk_p flag.
+ (struct lang_decl): Remove separate fixed_offset. Place
+ cloned_function and fixed_offset into union.
+ (DECL_CLONED_FUNCTION_P, DECL_CLONED_FUNCTION): Adjust.
+ (DECL_THUNK_P, SET_DECL_THUNK_P): Adjust.
+ (THUNK_FIXED_OFFSET): Adjust.
+ * method.c (make_thunk): Adjust.
+
+2004-11-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18369
+ * init.c (build_new_1): Handle parenthesized type-ids that name an
+ array type. Tidy.
+
+2004-11-09 Joseph S. Myers <joseph@codesourcery.com>
+
+ * call.c, class.c, decl.c, decl2.c, error.c, mangle.c, parser.c,
+ pt.c, search.c, semantics.c, typeck.c: Use %q, %< and %> for
+ quoting in diagnostics.
+ * parser.c (cp_parser_sizeof_operand): Use '' instead of `' for
+ quoting in printf format.
+ * decl.c (duplicate_decls, start_decl): Use %qD instead of
+ unquoted %D.
+
+2004-11-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * class.c, decl.c, lex.c, name-lookup.c, parser.c, pt.c,
+ search.c, typeck2.c: Fix comment formatting.
+
+2004-11-04 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR tree-optimization/18184
+ * cp-objcp-common.c (cxx_types_compatible_p): Do not treat pointers
+ of different modes or alias-all flags as equivalent.
+ * typeck.c (comptypes): Likewise.
+
+2004-11-04 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ DR 49, 100
+ * cp-tree.h (TYPE_REF_OBJ_P): New macro.
+ (TYPE_PTR_P, TYPE_PTROB_P, TYPE_PTROBV_P, TYPE_PTRFN_P,
+ TYPE_REFFN_P): Document.
+ (fold_decl_constant_value): New prototype.
+ * pt.c (convert_nontype_argument_function): Rewrite and extract
+ parts into...
+ (fold_decl_constant_value, convert_nontype_argument_function): New.
+ (lookup_template_class): Add comment about useless double call.
+ * mangle.c (write_expression): Strip conversions before lowering
+ pointer to members.
+ * cvt.c (ocp_convert): Check LOOKUP_COMPLAIN for a pedwarn. Disallow
+ enum to enum conversion.
+
+2004-11-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18124
+ * parser.c (cp_parser_type_parameter): Robustify.
+
+ PR c++/18155
+ * parser.c (cp_parser_single_declaration): Disallow template
+ typedefs.
+
+ PR c++/18177
+ * typeck.c (build_const_cast): Use error_operand_p.
+
+2004-11-02 Ziemowit Laski <zlaski@apple.com>
+
+ * cp-lang.c (cxx_types_compatible_p): Remove prototype and definition.
+ (LANG_HOOKS_TYPES_COMPATIBLE_P): Move to cp-objcp-common.h.
+ * cp-objcp-common.c (cxx_types_compatible_p): Moved definition here
+ from cp-lang.c.
+ * cp-objcp-common.h (cxx_types_compatible_p): Moved prototype here
+ from cp-lang.c.
+ (LANG_HOOKS_TYPES_COMPATIBLE_P): Moved here from cp-lang.c.
+
+2004-11-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18064
+ * search.c (check_final_overrider): Deprecate gnu covariant extension.
+
+2004-10-31 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Convert diagnostics to use quoting flag q 9/n
+ * typeck.c (build_x_unary_op, convert_member_func_to_ptr,
+ get_delta_difference): Use new quotation style.
+ * repo.c (reopen_repo_file_for_write): Likewise.
+ * pt.c (do_type_instantiation): Likewise.
+ * parser.c (cp_parser_diagnose_invalid_type_name):
+ * name-lookup.c (push_overloaded_decl, set_decl_namespace):
+ * error.c (cp_print_error_function,
+ print_instantiation_full_context): Likewise.
+ * decl.c (define_label, grok_reference_init,
+ maybe_deduce_size_from_array_init, revert_static_member_fn):
+ * decl2.c (check_classfn): Likewise.
+ * class.c (add_method, check_field_decls, layout_class_type,
+ resolve_address_of_overloaded_function): Likewise.
+ * call.c (build_x_va_arg, build_over_call): Likewise.
+
+2004-10-31 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Convert diagnostics to use quoting flag q 8/n
+ * cvt.c (cp_convert_to_pointer, warn_ref_binding,
+ convert_to_reference, ocp_convert, convert_to_void
+ cp_convert_to_pointer): Use new quotation style.
+
+2004-10-31 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15172
+ * typeck2.c (store_init_value): Use split_nonconstant_init even
+ for types that require construction.
+
+2004-10-28 Matt Austern <austern@apple.com>
+
+ PR c++/17542
+ * cp-tree.h (class_key_or_enum_as_string): Declare.
+ * error.c (class_key_or_enum): Rename to class_key_or_enum_as_string
+ and remove static qualifier.
+ * decl.c (shadow_tag): Warn about ignored attributes in class/struct/
+ union/enum declaration.
+
+2004-10-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * pt.c: Fix a comment typo.
+
+2004-10-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (composite_pointer_type): Remove comment about DR 195.
+ (build_reinterpret_cast_1): Revert DR195 patch. Only emit a
+ warning when being pedantic.
+ (build_reinterpet_cast, build_c_cast): Adjust.
+
+2004-10-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17695
+ * decl.c (grokdeclarator): Mark TYPE_DECLs as abstract when they
+ appear in a constructor/destructor that will be cloned.
+
+2004-10-28 Matt Austern <austern@apple.com>
+
+ PR c++/14124
+ * decl.c (finish_enum): Handle packed attribute.
+ * parser.c (cp_parser_enum_specifier): Process trailing attributes.
+
+2004-10-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17132
+ * pt.c (instantiate_class_template): Increment
+ processing_template_decl when substituting into a member class
+ template.
+
+2004-10-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17435
+ * call.c (convert_like_real): Fix formatting.
+ (initialize_reference): When binding a temporary to a base class,
+ ensure that the nominal copy made is to the derived class, not the
+ base class.
+
+ PR c++/18140
+ * parser.c (cp_parser_next_token_ends_template_argument_p): Do not
+ include ">>".
+
+2004-10-27 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * decl.c (bad_specifiers): Move the q after the %.
+
+2004-10-27 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * parser.c (cp_parser_diagnose_invalid_type_name): Move the q after
+ the %.
+
+2004-10-26 Mark Mitchell <mark@codesourcery.com>
+
+ * name-lookup.c (do_namespace_alias): Use FROB_CONTEXT.
+ * search.c (current_scope): Fix prototype.
+
+ PR c++/18093
+ * search.c (current_scope): Return the innermost non-block scope,
+ not the innermost non-block, non-namespace scope.
+ (at_namespace_scope_p): Adjust accordingly.
+ (dfs_accessible_post): Do not pass namespaces to is_friend.
+ (dfs_walk_once_accessible_r): Likewise.
+ * decl.c (grokvardecl): Adjust call to current_scope.
+ (build_enumerator): Likewise.
+ * parser.c (cp_parser_using_declaration): Likewise.
+ (cp_parser_direct_declarator): Use at_namespace_scope_p instead of
+ current_scope.
+ (cp_parser_class_head): Adjust call to current_scope.
+ * name-lookup.c (do_namespace_alias): Set the DECL_CONTEXT for the
+ alias.
+
+ PR c++/18020
+ * pt.c (tusbst_copy_and_build): Resolve enumeration constants to
+ their underlying values.
+
+ PR c++/18161
+ * typeck.c (build_binary_op): Honor build_type, even when in a
+ template.
+
+2004-10-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parser.c (cp_lexer_get_preprocessor_token): Remove unneeded
+ padding token checking.
+
+2004-10-25 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/18121
+ * decl.c (grokdeclarator) <case cdk_array>: Remove the call
+ layout_type as it is already done by create_array_type_for_decl.
+
+2004-10-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18095
+ * parser.c (eof_token): Make const, correctly initialize rid and
+ location fields.
+ (struct cp_lexer): Replace buffer_end pointer with buffer_length
+ count. Adjust.
+ (cp_lexer_new_main): Directly grow lexer's buffer here. Don't
+ zero it out.
+ (cp_lexer_new_from_tokens): Adjust.
+ (cp_lexer_grow_buffer): Remove.
+ (cp_lexer_peek_nth_token, cp_lexer_consume_token,
+ cp_lexer_purge_token): Add const casts.
+
+2004-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18073
+ PR c++/10841
+ * cp-tree.h (convert_to_base): Change prototype.
+ (build_ptrmemfunc): Likewise.
+ (convert_ptrmem): New function.
+ * call.c (struct conversion): Adjust documentation for base_p.
+ (standard_conversion): Set base_p for ck_pmem conversions as
+ appropriate.
+ (convert_like_real): Use convert_to_base for ck_pmem and ck_ptr
+ conversions.
+ * class.c (convert_to_base): Handle both pointers and objects.
+ Add nonnull parameter.
+ (build_vfield_ref): Adjust call to convert_to_base.
+ * cvt.c (cp_convert_to_pointer): Adjust call to build_ptrmemfunc.
+ (convert_force): Likewise.
+ * typeck.c (build_unary_op): Likewise.
+ (convert_ptrmem): New function.
+ (build_static_cast_1): Use it.
+ (build_reinterpret_cast): Allow conversions to vector types.
+ (get_delta_difference): Add c_cast_p parameter.
+ (build_ptrmemfunc): Likewise. Adjust calls to
+ get_delta_difference.
+
+2004-10-21 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/13560
+ * error.c (cp_error_at): Output the context as it might be
+ different file as the other location.
+
+2004-10-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * typeck.c: Fix a comment typo.
+
+2004-10-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13495
+ * decl.c (make_unbound_class_template): Add PARM_LIST parameter.
+ * cp-tree.h (make_unbound_class_template): Adjust prototype.
+ * parser.c (cp_parser_lookup_name): Adjust call to
+ make_unbound_class_template.
+ (cp_parser_single_declaration): Handle member class of class
+ template as template friend parsing correctly.
+ * friend.c (is_friend): Call is_specialization_of_friend for
+ template friend class.
+ (make_friend_class): Handle member class of class template as
+ template friend.
+ * pt.c (is_specialization_of_friend): Likewise.
+ (instantiate_class_template): Likewise.
+ (tsubst): Adjust call to make_unbound_class_template.
+
+2004-10-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (composite_pointer_type): Add comment about DR 195
+ (build_reinterpret_cast_1): Add for_reinterpret_cast_p parameter.
+ Allow function pointer conversions that DR195 suggests.
+ (build_reinterpret_cast, build_c_cast): Update
+ build_reinterpret_cast_1 calls.
+
+2004-10-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c, typeck.c: Fix comment typos.
+
+2004-10-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parser.c (cp_token_position): New typedef. Define VEC thereof.
+ (struct cp_lexer): Allow buffer and buffer_end to be NULL. Make
+ next_token and last_token cp_token_position. Make saved_tokens a
+ VEC(cp_token_position).
+ (eof_token): New static variable.
+ (CP_SAVED_TOKENS_SIZE): Rename to ...
+ (CP_SAVED_TOKEN_STACK): ... here.
+ (cp_lexer_new_main): Adjust main lexer creation and buffer
+ filling.
+ (cp_lexer_new_from_tokens): Do not copy the tokens, merely point
+ to the parent buffer. Do not append eof token.
+ (cp_lexer_destroy): Only free buffer if non-NULL. Free token
+ stack.
+ (cp_lexer_next_token, cp_lexer_prev_token): Remove.
+ (cp_lexer_token_position, cp_lexer_token_at): New.
+ (cp_lexer_saving_tokens): Adjust. Make inline.
+ (cp_lexer_advance_token, cp_lexer_token_difference): Remove.
+ (cp_lexer_peek_token_emit_debug_info): Fold into ...
+ (cp_lexer_peek_token): ... here.
+ (cp_lexer_peek_nth_token): Don't peek past EOF.
+ (cp_lexer_consume_token): Set next_token to eof_token, if reaching
+ EOF.
+ (cp_lexer_purge_token): Adjust eof setting.
+ (cp_lexer_purge_tokens_after): Likewise.
+ (cp_lexer_save_tokens): Push next_token directly.
+ (cp_lexer_commit_tokens): Adjust.
+ (cp_lexer_rollback_tokens): Pop next_token directly.
+ (cp_parser_check_for_invalid_template_id): Adjust token purging.
+ (cp_parser_translation_unit): Do not consume the EOF.
+ (cp_parser_nested_name_specifier_opt): Adjust token purging.
+ (cp_parser_template_id, cp_parser_template_name): Likewise.
+
+2004-10-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14035
+ * call.c (struct conversion): Add base_p.
+ (convert_like): Add c_cast_p argument.
+ (convert_like_with_conversion): Likewise.
+ (build_conv): Clear base_p.
+ (standard_conversion): Set it, for derived-to-base conversions.
+ (convert_like_real): Add c_cast_p parameter. Handle pointer
+ conversions directly rather than relying on ocp_convert.
+ (perform_direct_initialization_if_possible): Add c_cast_p
+ parameter.
+ * cp-tree.h (perform_direct_initialization_if_possible): Change
+ prototype.
+ (convert_member_func_to_ptr): New function.
+ * typeck.c (check_for_casting_away_constness): Add diag_fn
+ parameter.
+ (build_static_cast_1): New function, split out from ...
+ (build_static_cast): ... here. Use build_static_cast_1.
+ (build_reinterpret_cast_1): New function, split out from ...
+ (build_reinterpret_cast): ... here. Use build_reinterpret_cast_1.
+ (build_const_cast_1): New function, split out from ...
+ (build_const_cast): ... here. Use build_const_cast_1.
+ (build_c_cast): Rewrite to use build_const_cast_1,
+ build_static_cast_1, and build_reinterpret_cast_1.
+ (convert_member_func_to_ptr): New function.
+
+2004-10-19 Paolo Bonzini <bonzini@gnu.org>
+
+ PR c++/18047
+ * parser.c (enum cp_parser_prec): Give relational expressions
+ a higher precedence than equality expressions.
+
+2004-10-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (UNIQUELY_DERIVED_FROM_P): Adjust lookup_base call.
+ (ACCESSIBLY_UNIQUELY_DERIVED_P): Remove.
+ (PUBLICLY_UNIQUELY_DERIVED_P): Adjust lookup_base call.
+ (enum base_access): Reorganize.
+ (accessible_base_p, accessible_p): Add consider_local_p parameter.
+ * call.c (standard_conversion): Update comment about
+ DERIVED_FROM_P.
+ (enforce_access): Adjust accessible_p call.
+ (build_over_call): Adjust accessible_base_p call.
+ * class.c (convert_to_base): Adjust lookup_base call.
+ (build_vtbl_ref_1): Likewise.
+ (warn_about_ambiguous_bases): Likewise. Add early exit.
+ * cvt.c (convert_to_pointer_force) Adjust lookup_base call.
+ * search.c (accessible_base_p): Add consider_local_p parameter.
+ (lookup_base): Pass consider_local_p to accessible_base_p call.
+ (friend_accessible_p): Check whether scope is a class member.
+ Remove unnecessary class template check.
+ (accessible_p): Add consider_local_p parameter. Use it.
+ (adjust_result_of_qualified_name_lookup): Adjust lookup_base call.
+ * tree.c (maybe_dummy_object): Likewise.
+ * typeck.c (comp_except_type): Use PUBLICLY_UNIQUELY_DERIVED_P.
+ (build_class_member_access_expr): Adjust lookup_base call.
+ * typeck2.c (binfo_or_else): Likewise.
+ * rtti.c (build_dynamic_cast_1): Access can consider friendship
+ and current scope.
+
+2004-10-17 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/17743
+ * decl2.c (grokfield): Apply attributes also to TYPE_DECLs.
+
+2004-10-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/10479
+ * parser.c (cp_parser_parenthesized_expression_list): Fold
+ non-dependent expressions in attribute lists.
+
+2004-10-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17042
+ * decl.c (declare_global_var): Use the return value from pushdecl.
+
+ PR c++/14667
+ * parser.c (cp_parser_simple_declaration): Do not diagnose invalid
+ type names if we have already found a valid type.
+ (cp_parser_member_declaration): Likewise.
+
+ PR c++/17916
+ * parser.c (cp_parser_member_specification_opt): Handle
+ CPP_PRAGMA.
+
+2004-10-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * dump.c, g++spec.c, repo.c: Update copyright.
+
+2004-10-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * decl.c: Fix a comment typo.
+
+2004-10-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/16301
+ * name-lookup.c (parse_using_directive): If we have a
+ error_mark_node, do not set the decl namespace associations
+ on it.
+
+2004-10-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17976
+ * decl.c (cp_finish_decl): Do not call expand_static_init more
+ than once for a single variable.
+
+2004-10-14 Matt Austern <austern@apple.com>
+
+ * Make-lang.in (pt.o): depends on pointer-set.h
+ * cp-tree.h (cp_walk_subtrees): Last argument is pointer_set_t* now.
+ * pt.c (struct pair_fn_data): Use pointer_set_t, not htab_t
+ (for_each_template_parm): Convert from htab_t to pointer_set_t.
+ * tree.c (cp_walk_subtrees): Last argument is pointer_set_t* now.
+
+2004-10-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/17661
+ * semantics.c (finish_for_expr): Convert expression to void
+ so that we don't create temporaries for a?b:c.
+
+2004-10-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * search.c: Fix a comment typo.
+
+2004-10-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_modify_vtables): Simplify condition. Return
+ dfs_skip_bases as appropriate.
+ (modify_all_vtables): Walk in pre-order.
+ * search.c (dfs_walk_all, dfs_walk_once_r,
+ dfs_walk_once_accessible_r): Assert post order function never
+ returns dfs_skip_bases.
+
+ * search.c (struct lookup_base_data_s): New.
+ (lookup_base_r): Replace with ...
+ (dfs_lookup_base): ... this.
+ (lookup_base): Use dfs_walk_all.
+
+2004-10-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * search.c: Fix comment typos.
+
+2004-10-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15786
+ * parser.c (cp_parser_declarator): Add member_p parameter.
+ (cp_parser_condition): Adjust calls to cp_parser_declarator.
+ (cp_parser_explicit_instantiation): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_direct_declarator): Add member_p parameter. Do not
+ parse tentatively when parsing the parameters to a member.
+ (cp_parser_type_id): Adjust calls to cp_parser_declarator.
+ (cp_parser_parameter_declaration): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_exception_declaration): Likewise.
+
+ PR c++/17936
+ * cp-tree.h (CLASSTYPE_TEMPLATE_SPECIALIZATION): Add a comment.
+ * pt.c (optimize_specialization_lookup_p): Do not optimize lookups
+ for members of partial or explicit specializations.
+
+ PR c++/17929
+ * decl2.c (finish_anon_union): Robustify.
+
+2004-10-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (get_dynamic_cast_base_type): Rename to ...
+ (dcast_base_hint): ... here.
+ * rtti.c (build_dynamic_cast_1): Use dcast_base_hint.
+ * search.c (struct dcast_data_s): New.
+ (dynamic_cast_base_recurse): Remove. Replace with ...
+ (dfs_dcast_hint_pre, dfs_dcast_base_post): ... these. New.
+ (get_dynamic_cast_base_type): Rename to ...
+ (dcast_base_hint): ... here. Use dfs_walk_once_accessible.
+ (accessible_r): Remove.
+ (dfs_accessible_post): New, broken out of accessible_r.
+ (accessible_p): Use dfs_walk_once_accessible.
+ (dfs_walk_once_accessible_r): New. From accessible_r.
+ (dfs_walk_once_accessible): New. From acessible_p.
+
+ * cp-tree.h (SAME_BINFO_TYPE_P): New.
+ * class.c (build_base_path): Use SAME_BINFO_TYPE_P to compare
+ binfo types.
+ (convert_to_base_statically, determine_primary_bases,
+ update_vtable_entry_for_fn, dfs_modify_vtables, build_vtt_inits,
+ dfs_build_secondary_vptr_vtt_inits, build_ctor_vtbl_group,
+ accumulate_vtbl_inits, dfs_accumulate_vtbl_inits,
+ build_vtbl_initializer, add_vcall_offset_vtbl_entries_1): Likewise.
+ * init.c (expand_member_init): Likewise.
+ * search.c (lookup_base_r, dynamic_cast_base_recurse,
+ binfo_via_virtual, copied_binfo, binfo_for_vbase,
+ original_binfo): Likewise.
+ * tree.c (copy_binfo): Likewise.
+
+2004-10-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * semantics.c: Fix comment typos.
+
+2004-10-10 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/17554
+ part of c++/17657
+ middle-end/17703
+ * semantics.c (maybe_cleanup_point_expr): Call
+ fold_build_cleanup_point_expr.
+ (maybe_cleanup_point_expr_void): New function.
+ (add_decl_expr): Call maybe_cleanup_point_expr_void.
+ (finish_expr_stmt): Likewise.
+ (finish_return_stmt): Likewise.
+ (finish_for_expr): Likewise.
+ (finish_asm_stmt): Likewise.
+ * typeck.c (condition_conversion): Call
+ fold_build_cleanup_point_expr.
+
+2004-10-10 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/17907
+ * semantics.c (add_decl_expr): If the decl has a size which
+ has side effects then the decl expression needs a cleanup point.
+
+2004-10-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17393
+ * decl.c (grokdeclarator): Robustify error-recovery on invalid
+ declarations.
+
+2004-10-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Convert diagnostics to use quoting flag q 7/n
+ * typeck.c (composite_pointer_type_r, composite_pointer_type,
+ cxx_sizeof_or_alignof_type, cxx_sizeof_or_alignof_expr,
+ string_conv_p, build_class_member_access_expr,
+ build_class_member_access_expr, lookup_destructor,
+ finish_class_member_access_expr, build_indirect_ref,
+ get_member_function_from_ptrfunc, build_function_call,
+ convert_arguments, build_binary_op, pointer_diff, build_unary_op,
+ check_for_casting_away_constness, build_static_cast,
+ build_reinterpret_cast, build_const_cast, build_c_cast,
+ build_modify_expr, get_delta_difference, build_ptrmemfunc,
+ dubious_conversion_warnings, convert_for_assignment,
+ convert_for_initialization,
+ maybe_warn_about_returning_address_of_local, check_return_expr):
+ Use quoting marks.
+
+ * typeck2.c (error_not_base_type, readonly_error,
+ abstract_virtuals_error, cxx_incomplete_type_diagnostic,
+ store_init_value, digest_init, build_x_arrow,
+ build_m_component_ref, require_complete_eh_spec_types): Likewise.
+
+ * tree.c (cp_build_qualified_type_real,
+ handle_java_interface_attribute, handle_init_priority_attribute):
+ Likewise.
+
+ * semantics.c (finish_asm_stmt, finish_non_static_data_member,
+ finish_pseudo_destructor_expr,
+ check_template_template_default_arg, begin_class_definition,
+ finish_base_specifier, qualified_name_lookup_error,
+ finish_id_expression, finish_typeof): Likewise.
+
+ * search.c (lookup_base, check_final_overrider,
+ look_for_overrides_r): Likewise.
+
+ * rtti.c (get_tinfo_decl, build_dynamic_cast_1): Likewise.
+
+2004-10-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17867
+ * error.c (dump_expr): Correct handling of AGGR_INIT_EXPRs using a
+ constructor.
+
+ PR c++/17670
+ * init.c (build_new): Correct comments.
+ * parser.c (cp_parser_new_expression): Use NULL_TREE for nelts in
+ the non-array case.
+
+ PR c++/17821
+ * parser.c (cp_parser_postfix_dot_deref_expression): If the
+ pseduo-destructor-name production does not work, fall back to the
+ ordinary production.
+
+ PR c++/17826
+ * tree.c (cp_tree_equal): Handle a BASELINK.
+
+ PR c++/17524
+ * cp-tree.h (check_var_type): New function.
+ * decl.c (check_var_type): New function, split out from ...
+ (grokdeclarator): ... here.
+ * pt.c (tsubst_decl): Use check_var_type.
+
+ PR c++/17685
+ * decl.c (grokdeclarator): Disallow declarations of operators as
+ non-functions.
+
+2004-10-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/17868
+ * error.c (dump_expr): Add missing case for RDIV_EXPR.
+
+2004-10-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * pt.c, search.c: Fix comment typos.
+
+2004-10-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (dfs_walk, dfs_walk_real, dfs_unmark, markedp,
+ unmarkedp): Remove.
+ (dfs_skip_bases, dfs_walk_all, dfs_walk_once): New.
+ * class.c (struct find_final_overrider_data): Remove most_derived,
+ vpath_list and vpath fields. Add path field.
+ (dfs_find_final_ocerrider_1): Add DEPTH parameter. Adjust.
+ (dfs_find_final_overrider): Rename to ...
+ (dfs_find_final_overrider_pre): ... here. Adjust.
+ (dfs_find_final_overrider_post): Adjust.
+ (dfs_find_final_overrider_q): Fold into
+ dfs_find_final_overrider_pre.
+ (find_final_overrider): Adjust dfs searching.
+ (dfs_modify_vtables): Don't mark binfo here.
+ (modify_all_vtables): Use dfs_walk_once.
+ (build_vtt_inits): Likwise. Use dfs_walk_all.
+ (dfs_build_secondary_vptr_vtt_inits): Don't mark binfo here.
+ Return dfs_skip_bases as appropriate.
+ (dfs_fixup_binfo_vtbls): Return dfs_skip_bases as appropriate.
+ * init.c (dfs_initialized_vtbl_ptrs): Return dfs_skip_bases as
+ appropriate. Don't mark binfo here.
+ (initialize_vtbl_ptrs): Use dfs_walk_once.
+ * search.c (struct vbase_info): Remove unused struct.
+ (access_in_type): Use dfs_walk_once.
+ (dfs_access_in_type): Don't mark binfo here.
+ (dfs_accessible_queue_p, dfs_accessible_p) Remove.
+ Fold into ...
+ (accessible_r): ... here. New. Specialize dfs_walk_once.
+ (accessible_p): Use accessible_r.
+ (lookup_field_queue_p): Remove. Fold into ...
+ (lookup_field_r): ... here. Adjust.
+ (lookup_member): Use dfs_walk_all.
+ (dfs_walk_real, dfs_walk): Replace with ...
+ (dfs_walk_all, dfs_walk_once): ... these.
+ (dfs_walk_once_r, dfs_unmark_r): Workers for dfs_walk_once.
+ (dfs_unmark, unmarkedp, markedp): Remove.
+ (dfs_get_pure_virtuals): Don't mark binfo here.
+ (get_pure_virtuals): Use dfs_walk_once.
+ (dfs_debug_unmarked_p): Remove. Fold into ...
+ (dfs_debug_mark): ... here.
+ (note_debug_info_needed): Use dfs_walk_all.
+
+2004-10-07 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * pt.c (tsubst_expr) <case ASM_EXPR>: Look passed the
+ CLEANUP_POINT_EXPR to get the asm expression.
+
+2004-10-07 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (ICS_USER_FLAG): Remove comment about obsolete flag.
+ (DECL_MEMBER_TEMPLATE_P): New macro.
+ (is_member_template): Remove.
+ (class_method_index_for_fn): New function.
+ * pt.c (build_over_call): Use DECL_MEMBER_TEMPLATE_P.
+ * class.c (finish_struct_methods): Remove out-of-date comment.
+ * decl.c (copy_fn_p): Use DECL_MBMER_TEMPLATE_P.
+ * decl2.c (check_classfn): Use DECL_MEMBER_TEMPLATE_P and
+ class_method_index_for_fn.
+ * pt.c (is_member_template): Remove.
+ (is_member_template_class): Likewise.
+ (optimize_specialization_lookup_p): New function.
+ (retrieve_specialization): Optimize lookups for members that are
+ not member templates.
+ (register_specialization): Adjust accordingly.
+ (build_template_decl): Add member_template_p parameter. Set
+ DECL_MEMBER_TEMPLATE_P.
+ (process_partial_specialization): Adjust call to
+ retrieve_specialization.
+ (push_template_decl_real): Determine whether the template is a
+ member template.
+ (lookup_template_class): Use retrieve_specialization.
+ (tsubst_decl): Adjust call to retrieve_specialization.
+ (tsubst_exception_specification): New function.
+ (tsubst): Use it.
+ (tsubst_copy): Use DECL_MEMBER_TEMPLATE_P.
+ (instantiate_template): Adjust call to retrieve_specialization.
+ (regenerate_decl_from_template): Do not actually generate a new
+ DECL.
+ (instantiate_decl): Adjust call to retrieve_specialization.
+ (class_method_index_for_fn): New method.
+
+2004-10-07 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * parser.c (cp_parser_asm_definition): Look passed the
+ CLEANUP_POINT_EXPR to get the asm expression.
+
+2004-10-06 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/17368
+ * semantics.c (finish_asm_stmt): Asm expressions need cleanup
+ also.
+
+2004-10-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Convert diagnostics to use quoting flag q 6/n
+ * pt.c (finish_member_template_decl, check_specialization_scope,
+ maybe_process_partial_specialization, determine_specialization,
+ check_explicit_specialization, maybe_check_template_type,
+ process_partial_specialization, check_default_tmpl_args,
+ push_template_decl_real, redeclare_class_template,
+ convert_nontype_argument, coerce_template_parms,
+ lookup_template_class, push_tinst_level,
+ instantiate_class_template, tsubst_arg_types,
+ tsubst_function_type, tsubst, tsubst_qualified_id,
+ tsubst_copy_and_build, check_instantiated_args,
+ do_decl_instantiation, do_type_instantiation,
+ invalid_nontype_parm_type_p, check_specialization_namespace,
+ convert_template_argument, determine_specialization,
+ check_template_shadow, tsubst_decl
+ instantiate_pending_templates): Use quoting marks.
+
+2004-10-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/17829
+ * parser.c (cp_parser_postfix_expression): Inhibit Koenig when
+ unqualified lookup finds a member function.
+
+2004-10-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Convert diagnostics to use quoting flag q 5/n
+ * parser.c (cp_parser_name_lookup_error,
+ cp_parser_diagnose_invalid_type_name,
+ cp_parser_primary_expression, cp_parser_unqualified_id,
+ cp_parser_nested_name_specifier_opt, cp_parser_labeled_statement,
+ cp_parser_jump_statement, cp_parser_simple_declaration,
+ cp_parser_decl_specifier_seq, cp_parser_mem_initializer_id,
+ cp_parser_type_parameter, cp_parser_template_id,
+ cp_parser_template_name, cp_parser_direct_declarator,
+ cp_parser_parameter_declaration_list, cp_parser_class_head,
+ cp_parser_base_specifier, cp_parser_lookup_name,
+ cp_parser_late_parsing_default_args,
+ cp_parser_optional_template_keyword
+ cp_parser_elaborated_type_specifier, cp_parser_check_class_key,
+ cp_parser_check_access_in_redeclaration): Use quoting marks.
+
+ * name-lookup.c (supplement_binding, pushdecl,
+ check_for_out_of_scope_variable, validate_nonmember_using_decl,
+ do_nonmember_using_decl, lookup_tag, set_decl_namespace,
+ push_namespace, do_namespace_alias, do_using_directive,
+ ambiguous_decl, lookup_namespace_name, add_function): Likewise.
+
+ * method.c (use_thunk): Likewise.
+
+ * lex.c (unqualified_name_lookup_error,
+ unqualified_fn_lookup_error): Likewise.
+
+2004-10-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Convert diagnostics to use quoting flag q 4/n
+ * except.c (decl_is_java_type, build_throw,
+ is_admissible_throw_operand, check_handlers_1, check_handlers):
+ Use quoting formats.
+ * friend.c (add_friend, make_friend_class, do_friend): Likewise.
+ * init.c (sort_mem_initializers, emit_mem_initializers,
+ member_init_ok_or_else, expand_member_init, is_aggr_type,
+ build_offset_ref, build_java_class_ref): Likewise.
+
+2004-10-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Convert diagnostics to use quoting flag q 3/n
+ * decl.c (pop_label, duplicate_decls, redeclaration_error_message,
+ redeclaration_error_message, lookup_label, check_goto,
+ make_typename_type, make_unbound_class_template,
+ fixup_anonymous_aggr, check_tag_decl, start_decl, start_decl_1,
+ grok_reference_init, layout_var_decl, maybe_commonize_var,
+ check_for_uninitialized_const_var, reshape_init_array,
+ reshape_init, check_initializer, cp_finish_decl,
+ member_function_or_else, bad_specifiers, grokfndecl, grokvardecl,
+ check_static_variable_definition, compute_array_index_type,
+ create_array_type_for_decl, check_special_function_return_type,
+ grokdeclarator, check_default_argument, grokparms,
+ grok_ctor_properties, grok_op_properties,
+ check_elaborated_type_specifier, xref_tag, finish_enum,
+ build_enumerator, check_function_type, start_preparsed_function,
+ store_parm_decls): Use quoting formats.
+ * decl2.c (grok_array_decl, delete_sanity, check_member_template,
+ check_java_method, check_classfn, finish_static_data_member_decl,
+ grokfield, grokbitfield, grok_function_init,
+ build_anon_union_vars, coerce_new_type, coerce_delete_type,
+ check_default_args): Likewise.
+ * parser.c (cp_parser_decl_specifier_seq): Likewise.
+
+2004-10-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Convert diagnostics to use quoting flag q 2/n
+ * class.c (build_base_path, add_method, alter_access,
+ handle_using_decl, check_bases,
+ maybe_warn_about_overly_private_class, find_final_overrider,
+ warn_hidden, finish_struct_anon, add_implicitly_declared_members,
+ check_bitfield_decl, check_field_decls, layout_empty_base,
+ build_base_field, check_methods, layout_virtual_bases,
+ warn_about_ambiguous_bases, layout_class_type, finish_struct_1,
+ resolve_address_of_overloaded_function, instantiate_type,
+ note_name_declared_in_class): Use format flag "q" for quoting.
+
+2004-10-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Convert diagnostics to use quoting flag q 1/n
+ * error.c (locate_error): Ignore quoting flag q.
+ * call.c (build_user_type_conversion_1, build_operator_new_call,
+ build_object_call, op_error, build_conditional_expr,
+ build_new_op, build_op_delete_call, enforce_access,
+ convert_like_real, convert_arg_to_ellipsis, build_x_va_arg,
+ convert_default_arg, build_over_call, build_new_method_call,
+ joust, perform_implicit_conversion, initialize_reference): Use the
+ quoting flag q.
+
+2004-10-03 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/17797
+ * typeck.c (build_reinterpret_cast): Return if the inner type
+ is error_mark_node.
+
+2004-10-01 Jan Hubicka <jh@suse.cz>
+
+ * semantics.c (expand_body): Update call of tree_rest_of_compilation.
+
+2004-09-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (struct lang_decl): Shrink by reordering fields and
+ turning operator_code and fixed_offset into bitfields.
+
+2004-09-29 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * decl.c (duplicate_decls): Merge TREE_DEPRECATED.
+
+2004-09-29 Jason Merrill <jason@redhat.com>
+
+ PR tree-optimization/17697
+ * decl.c (duplicate_decls): Copy TREE_NOTHROW from newdecl to olddecl.
+
+2004-09-28 Jason Merrill <jason@redhat.com>
+
+ PR middle-end/17525
+ * class.c (build_base_field): Set TYPE_MODE.
+
+2004-09-28 Roger Sayle <roger@eyesopen.com>
+
+ PR driver/17537
+ * g++spec.c (lang_specific_driver): Unrecognized libraries, other
+ than -lc and -lm, may require linking against libstc++.
+
+2004-09-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tree.c: Fix a comment typo.
+
+2004-09-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (VTT_TOP_LEVEL_P, VTT_MARKED_BINFO_P): Remove.
+ (struct secondary_vptr_vtt_init_data_s): New.
+ (build_vtt_inits): Adjust dfs_walkers.
+ (dfs_build_secondary_vptr_vtt_inits): Caller data is a
+ secondary_vptr_vtt_init_data_s structure. Adjust.
+ (dfs_ctor_vtable_bases_queue_p): Remove.
+ (dfs_fixup_binfo_vtbls): No need to clear BINFO_MARKED. Simplify.
+
+ * pt.c (struct get_template_base_data_s): Remove.
+ (get_template_base_r): Fold into get_template_base.
+ (get_template_base): Walk base binfos directly in inheritance
+ graph order.
+
+2004-09-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17642
+ * cp-tree.h (fold_if_not_in_template): New function.
+ * call.c (build_conditional_expr): Use fold_if_not_in_template.
+ (build_cxx_call): Likewise.
+ * cvt.c (convert_to_complex): Likewise.
+ (ocp_convert): Likewise.
+ (convert): Likewise.
+ (convert_force): Likewise.
+ * decl.c (compute_array_index_type): Clear
+ processing_template_decl while folding array bounds.
+ * pt.c (convert_nontype_argument): Clear
+ processing_template_decl while processing non-type argument
+ initialization.
+ * tree.c (fold_if_not_in_template): New function.
+ * typeck.c (build_class_member_access_expr): Use
+ fold_if_not_in_template.
+ (build_array_ref): Likewise.
+ (build_binary_op): Likewise. Do not try to optimize computations
+ when processing templates.
+ (cp_pointer_int_sum): Use fold_if_not_in_template.
+ (pointer_diff): Likewise.
+ (build_unary_op): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (get_delta_difference): Likewise.
+ (expand_ptrmemfunc_cst): Likewise.
+ (dubious_conversion_warnings): Likewise.
+
+2004-09-27 Matt Austern <austern@apple.com>
+
+ * cp/parser.c (struct cp_token): New one-bit field , implicit_extern_c
+ (cp_lexer_get_preprocessor_token): Set implicit_extern_c for
+ tokens that come from headers that are implicitly extern "C".
+ (struct cp_parser): new one-bit field, implicit_extern_c.
+ (cp_parser_new): Set parser's implicit_extern_c to false.
+ (cp_parser_translation_unit): Pop lang context if we were in a
+ header that was implicitly extern "C".
+ (cp_parser_declaration_seq_opt): Push/pop lang context as
+ required by the token's and parser's implicit_extern_c.
+
+2004-09-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17585
+ * cp-tree.h (shared_member_p): Declare.
+ * search.c (shared_member_p): Give it external linkage.
+ * semantics.c (finish_qualified_id_expr): Use it.
+ (finish_id_expression): Likewise.
+
+ PR c++/17585
+ * semantics.c (finish_id_expression): Do not add "this->" to
+ static member functions.
+
+2004-09-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/17681
+ * error.c (dump_type): Change TREE_VEC case into TREE_BINFO.
+
+ * class.c (struct count_depth_data): Remove.
+ (dfs_depth_post, dfs_depth_q): Remove.
+ (find_final_overrider): Use number of vbase classes as depth
+ bound.
+
+ * cp-tree.h (types_overlap_p): Remove.
+ * search.c (struct overlap_info): Remove.
+ (dfs_check_overlap, dfs_no_overlap_yet, types_overlap_p): Remove.
+
+ * pt.c (GTB_VIA_VIRTUAL, GTB_IGNORE_TYPE): Remove.
+ (get_template_base_recursive): Remove. Replace with ...
+ (get_template_base_r): ... this.
+ (struct get_template_base_data_s): New.
+ (get_template_base): Use get_template_base_r via dfs_walk. Always
+ return NULL on failure.
+ (unify): Remove error_mark_node check from get_template_base result.
+
+2004-09-24 Paolo Bonzini <bonzini@gnu.org>
+
+ * parser.c (cp_parser_expression_stack): Clarify why it is
+ an array of NUM_PREC_VALUES elements.
+ (cp_parser_binary_expression): Clarify why we do not need to
+ handle stack overflow.
+
+2004-09-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/16889
+ * search.c (lookup_field_queue_p): Correct check for hidden base.
+
+ * search.c (bfs_walk): Remove.
+ (lookup_member): Use dfs_walk_real.
+ (dfs_walk_real): Move and adjust documentation from bfs_walk.
+
+2004-09-23 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (grokfndecl): If ::main is found not to return int,
+ correct it after issuing a diagnostic.
+ (grokdeclarator): If the incoming type was error_mark_node, do
+ not complain about declaring something with no type.
+ (start_function): Change check for ::main not returning int to
+ an assertion, as grokfndecl now catches this when the user did it.
+ * init.c (perform_member_init, sort_mem_initializers)
+ (emit_mem_initializers): Make most diagnostics be issued on
+ the line of current_function_decl, not whatever the current
+ input line is.
+ * parser.c (cp_lexer_peek_token_emit_debug_info): Surround
+ definition and declaration with #ifdef ENABLE_CHECKING.
+ Avoid unnecessary use of fprintf.
+ (cp_lexer_print_token, cp_lexer_debug_stream): Adjust stub
+ definitions to avoid warnings.
+ (cp_lexer_new_main): Add assertion that first token is not a
+ padding token.
+ (cp_lexer_new_from_token_array): Fold into ...
+ (cp_lexer_new_from_tokens): ... here. Add assertion that
+ first token is not a padding token.
+ (cp_lexer_set_source_position_from_token): Move nearer to callers.
+ Remove unused lexer argument.
+ (cp_lexer_peek_token): Just print debugging report (if enabled)
+ and return lexer->next_token.
+ (cp_lexer_skip_purged_tokens): Delete.
+ (cp_lexer_next_token_is, cp_lexer_next_token_is_not): Make
+ inline, simplify bodies.
+ (cp_lexer_peek_nth_token): Add debugging report a la
+ cp_lexer_peek_token.
+ (cp_lexer_consume_token): Correct commentary. Advance over
+ purged tokens here. Set current source position here, from
+ token to be returned. Avoid unnecessary use of fprintf.
+ (cp_lexer_purge_token): Advance next_token pointer over this and
+ subsequent purged tokens.
+ (cp_parser_error): Adjust source position to that of the
+ peeked token.
+ (cp_parser_push_lexer_for_tokens, cp_parser_pop_lexer): New functions.
+ (cp_parser_string_literal): Remove some excessive cleverness.
+ (cp_parser_enum_specifier): Call start_enum before consuming
+ the opening brace.
+ (cp_parser_member_declaration): Make the "extra semicolon"
+ diagnostic consistently-worded with the other place this is
+ diagnosed. Explicitly set the diagnostic location to the
+ location of the offending semicolon.
+ (cp_parser_enclosed_template_argument_list): Use %</%> quoting
+ in diagnostics. Do not use cp_parser_require. Set location
+ of diagnostics about improper use of '>>' to location of
+ offending token.
+ (cp_parser_late_parsing_for_member):
+ Use cp_parser_push_lexer_for_tokens and cp_parser_pop_lexer.
+ (cp_parser_late_parsing_default_args): Likewise. Manually
+ move some logic outside the loop.
+
+2004-09-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/17618
+ * cvt.c (cp_convert_to_pointer): Return early when the type is
+ an error_mark_node.
+
+2004-09-21 Fariborz Jahanian <fjahanian@apple.com>
+
+ PR c++/13989
+ PR c++/9844
+ * decl.c (grokfndecl): Add new argument "attrlist", use it
+ to call cplus_decl_attributes.
+ (start_function): Remove call to cplus_decl_attributes.
+ * cvt.c (ocp_convert): Add support to use type conversion
+ function to vector type.
+ * parser.c (cp_parser_conversion_type_id): Add attributes, if any,
+ to the parsed type.
+
+2004-09-23 Paolo Bonzini <bonzini@gnu.org>
+
+ PR c++/17596
+
+ * parser.c (cp_parser_token_tree_map_node,
+ cp_parser_pm_expression, cp_parser_additive_expression,
+ cp_parser_multiplicative_expression, cp_parser_shift_expression,
+ cp_parser_relational_expression, cp_parser_equality_expression,
+ cp_parser_and_expression, cp_parser_exclusive_or_expression,
+ cp_parser_inclusive_or_expression,
+ cp_parser_logical_and_expression,
+ cp_parser_logical_or_expression): Removed.
+ (enum cp_parser_prec, struct cp_parser_token_tree_map_node,
+ binops, binops_by_token): New.
+ (cp_parser_assignment_expression): Use cp_parser_binary_expression.
+ (cp_parser_new): Initialize binops_by_token.
+ (cp_parser_binary_expression): Rewritten.
+ (N_CP_TTYPES): New.
+
+2004-09-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * parser.c: Fix a comment typo.
+
+2004-09-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/17620
+ * decl.c (xref_basetypes): Look through typedefs before checking
+ for duplicate base.
+
+2004-09-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (unemitted_tinfo_decls): Make a VEC(tree).
+ * decl2.c (cp_finish_file): Adjust tinfo decl emission loop.
+ * rtti.c (unemitted_tinfo_decls): Make a VEC(tree).
+ (init_rtti_processing): Initialize it to something realistic.
+ (get_tinfo_decl): Adjust pushing the new decl.
+
+ * cp-tree.h (struct lang_type_class): Remove marked flags, add
+ diamond_shaped and repeated_base flags. Reorder to keep 8-bit blocks.
+ (TYPE_MARKED_P): New.
+ (CLASSTYPE_DIAMOND_SHAPED_P, CLASSTYPE_REPEATED_BASE_P): New.
+ (CLASSTYPE_MARKED_N, SET_CLASSTYPE_MARKED_N,
+ CLEAR_CLASSTYPE_MARKED_N): Remove.
+ (CLASSTYPE_MARKED_*, SET_CLASSTYPE_MARKED_*,
+ CLEAR_CLASSTYPE_MARKED_*): Remove.
+ * decl.c (xref_basetypes): Use TYPE_MARKED_P. Determine diamond
+ shaped and repeated base properties.
+ * lex.c (cxx_make_type): Don't clear TYPE_ALIAS_SET.
+ * rtti.c (dfs_class_hint_mark, dfs_class_hint_unmark,
+ class_hint_flags): Remove.
+ (get_pseudo_ti_init): Use CLASSTYPE_REPEATED_BASE_P and
+ CLASSTYPE_DIAMOND_SHAPED_P.
+
+2004-09-21 Ziemowit Laski <zlaski@apple.com>
+
+ * cp-lang.c (LANG_HOOKS_FOLD_OBJ_TYPE_REF): Moved here from
+ cp-objcp-common.h.
+ (objcp_tsubst_copy_and_build): Reformat function signature.
+ * cp-objcp-common.h (objcp_tsubst_copy_and_build): Likewise.
+ (LANG_HOOKS_FOLD_OBJ_TYPE_REF): Moved to cp-lang.c.
+
+2004-09-21 Zack Weinberg <zack@codesourcery.com>
+
+ * parser.c (cp_lexer_peek_token, cp_lexer_consume_token):
+ Don't handle CPP_PRAGMA tokens specially.
+ (cp_lexer_handle_pragma): Use cp_lexer_consume_token. Don't
+ purge the token; do clear token->value after processing. Add
+ assertion at beginning that token->value is nonzero.
+ (cp_parser_statement, cp_parser_declaration_seq_opt): Handle
+ CPP_PRAGMA as a full statement or declaration in its own right.
+
+2004-09-21 Matt Austern <austern@apple.com>
+
+ PR c++/15049
+ * decl.c (grokvardecl): Accept declarations of global variables
+ using anonymous types.
+
+2004-09-21 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/7503
+ * tree.c (lvalue_p_1): Disallow MIN_EXPR and MAX_EXPR as lvalues
+ if either operand has side-effects.
+ * typeck.c (rationalize_conditional_expr): Assert that neither
+ operand of MIN_EXPR or MAX_EXPR has side-effects.
+ (build_modify_expr): Add support for MIN_EXPR and MAX_EXPR.
+ Check that the "lhs" is a valid lvalue, i.e. that neither operand
+ of a MIN_EXPR or MAX_EXPR has a side-effect.
+
+2004-09-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (struct lang_type_header): Remove
+ uses_multiple_inheritance field.
+ (TYPE_USES_MULTIPLE_INHERITANCE): Remove.
+ (TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P): Remove.
+ (TYPE_USES_VIRTUAL_BASECLASSES): Remove.
+ (DECL_NEEDS_VTT_PARM_P): Use CLASSTYPE_VBASECLASSES.
+ (TYPE_CONTAINS_VPTR_P): Likewise.
+ * call.c (add_template_candidate_real): Use
+ CLASSTYPE_VBASECLASSES.
+ (build_special_member_call): Likewise.
+ * class.c (finish_struct_bits): Remove
+ TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P & TYPE_USES_VIRTUAL_BASECLASSES
+ bookkeeping.
+ (check_bases_and_members): Use TYPE_CONTAINS_VPTR_P.
+ (create_vtable_ptr): Remove TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P
+ bookkeeping.
+ (build_vtt_inits): Use CLASSTYPE_VBASECLASSES.
+ (accumulate_vtbl_inits, build_vbase_offset_vtbl_entries):
+ Likewise.
+ * decl.c (xref_basetypes): Remove TYPE_USES_MULTIPLE_INHERITANCE,
+ TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P, TYPE_USES_VIRTUAL_BASECLASSES
+ bookkeeping.
+ (cxx_maybe_build_cleanup): Use CLASSTYPE_VBASECLASSES.
+ * decl2.c (maybe_retrofit_in_chrg): Likewise.
+ * init.c (expand_member, push_base_cleanups): Likewise.
+ * pt.c (instantiate_class_template): Remove
+ TYPE_USES_MULTIPLE_INHERITANCE,
+ TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P, TYPE_USES_VIRTUAL_BASECLASSES
+ bookkeeping.
+ * ptree.c (cxx_print_type): Remove TYPE_USES_MULTIPLE_INHERITANCE
+ check.
+ * typeck2.c (process_init_constructor): Replace some sorrys with
+ asserts.
+
+2004-09-21 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * decl.c (reshape_init_array): Initialize max_index_cst to fix
+ bootstrap failure.
+
+2004-09-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17530
+ * pt.c (tsubst): Fix parentheses to accomodate emacs.
+ (tsubst_baselink): If we get a single function, mark it as used.
+
+2004-09-20 Matt Austern <austern@apple.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (make_rtl_for_nonlocal_decl, start_preparsed_function):
+ Apply lbasename to input_filename before passing to get_fileinfo.
+ * semantics.c (begin_class_definition): Likewise.
+ * lex.c (handle_pragma_interface): Apply get_fileinfo to the
+ correct filename. Rename variables to be less confusing.
+ (handle_pragma_implementation): Likewise. Disable "appears
+ after file is included" diagnostic.
+
+ * parser.c (struct cp_token): Add in_system_header fiag.
+ (CP_TOKEN_BLOCK_NUM_TOKENS, struct cp_token_block)
+ (CP_TOKEN_BUFFER_SIZE, cp_token_cache_push_token)
+ (CPP_NONE, cp_lexer_read_token): Delete.
+ (struct cp_lexer): Remove first_token, string_tokens,
+ main_lexer_p fields. Clarify comments.
+ (struct cp_token_cache): Now just a pair of pointers.
+ (CP_LEXER_BUFFER_SIZE): New #define.
+ (CPP_PURGED): New fake token type.
+ (cp_lexer_new_from_token_array, cp_lexer_destroy)
+ (cp_lexer_peek_token_emit_debug_info, cp_lexer_skip_purged_tokens)
+ (cp_lexer_handle_pragma, cp_token_cache_new, cp_parser_string_literal):
+ New functions.
+ (cp_lexer_new_from_tokens): Now a simple wrapper around
+ cp_lexer_new_from_token_array.
+ (cp_lexer_set_source_position_from_token): Also update
+ in_system_header.
+ (cp_lexer_next_token, cp_lexer_prev_token, cp_lexer_advance_token):
+ Don't wrap round.
+ (cp_lexer_token_difference): Dont handle wrapping round.
+ (cp_lexer_new_main): Enable pragma deferral and raw strings,
+ read the entire translation unit through c_lex_with_flags into
+ this lexer's buffer, then turn raw strings back off again.
+ (cp_lexer_grow_buffer): Adjust for buffer no longer being circular.
+ (cp_lexer_get_preprocessor_token): No need to handle not being
+ the main lexer. Set token->in_system_header too.
+ (cp_lexer_peek_token): Skip purged tokens. Feed pragma tokens
+ to cp_lexer_handle_pragma. No need to call cp_lexer_read_token.
+ (cp_lexer_peek_nth_token): Likewise.
+ (cp_lexer_purge_token): Mark the token PURGED, don't shift all
+ the other tokens down.
+ (cp_lexer_purge_tokens_after): Likewise.
+ (cp_lexer_save_tokens, cp_lexer_rollback_tokens): Don't worry
+ about there being no tokens.
+ (cp_lexer_print_token): Revise to give useful information on
+ all tokens.
+ (struct cp_parser): Add field translate_strings_p.
+ (cp_parser_new): Initialize it.
+ (cp_parser_translation_unit): Destroy the lexer when done.
+ (cp_parser_parameter_declaration): Restructure saving of
+ default arguments.
+ (cp_parser_save_member_function_body): Likewise.
+ (cp_parser_check_for_invalid_template_id)
+ (cp_parser_nested_name_specifier_opt, cp_parser_template_id):
+ Adjust calls to cp_lexer_advance_token.
+ (cp_parser_skip_to_closing_parenthesis, cp_parser_declaration):
+ No need to fiddle c_lex_string_translate.
+ (cp_parser_primary_expression, cp_parser_linkage_specification)
+ (cp_parser_asm_definition, cp_parser_asm_specification_opt)
+ (cp_parser_asm_operand_list, cp_parser_asm_clobber_list)
+ Use cp_parser_string_literal.
+ (cp_parser_attribute_list): Save and restore
+ parser->translate_strings_p, not c_lex_string_translate.
+ (cp_parser_cache_group): Delete.
+ (cp_parser_cache_group_1): Rename cp_parser_cache_group. Do
+ not take a cache argument.
+
+2004-09-20 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14179
+ * decl.c (reshape_init): Extract array handling into...
+ (reshape_init_array): New function. Use integers instead of trees
+ for indices. Handle out-of-range designated initializers.
+
+2004-09-20 Steven Bosscher <stevenb@suse.de>
+
+ * lex.c (cxx_init): Don't set the ridpointer for RID_NULL
+ to null_node.
+
+2004-09-19 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (determine_visibility): Allow class visibility
+ directives to override targetm.cxx.export_class_data.
+
+2004-09-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c, semantics.c: Follow spelling conventions.
+ * class.c: Fix a comment typo.
+
+2004-09-16 Geoffrey Keating <geoffk@apple.com>
+
+ PR pch/13361
+ * cp/lex.c (handle_pragma_interface): Duplicate string from tree.
+ (handle_pragma_implementation): Likewise.
+
+2004-09-17 Jeffrey D. Oldham <oldham@codesourcery.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * cp-tree.def: Use tree_code_class enumeration constants
+ instead of code letters.
+ * call.c, class.c, cp-gimplify.c, cp-lang.c, cxx-pretty-print.c
+ * mangle.c, pt.c, semantics.c, tree.c, typeck.c:
+ Update for new tree-class enumeration constants.
+
+2004-09-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16002
+ * parser.c (cp_parser_simple_declaration): Commit to tentative
+ parses after seeing a decl-specifier.
+ (cp_parser_simple_declaration): Eliminate spurious message.
+ (cp_parser_init_declarator): Adjust error message.
+
+ PR c++/16029
+ * lex.c (unqualified_name_lookup_error): Mark the dummy
+ declaration as used.
+
+ PR c++/17501
+ * parser.c (cp_parser_nested_name_specifier): Do not resolve
+ typename types if the user explicitly said "typename".
+
+2004-09-16 Andrew MacLeod <amacleod@redhat.com>
+
+ * error.c (dump_decl): Make sure there is lang_specific info before
+ checking for DTOR and CTOR decls.
+
+2004-09-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (copy_virtuals): Remove.
+ (build_primary_vtable): Use copy_list directly.
+ (build_secondary_vtable): Likewise.
+ (update_vtable_entry_for_fn): Clear BV_CALL_INDEX here.
+ (create_vtable_ptr): Likewise.
+
+2004-09-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * search.c: Follow spelling conventions.
+
+2004-09-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (struct lang_type_class): Make pure_virtuals a
+ VEC(tree).
+ (CLASSTYPE_INLINE_FRIENDS, CLASSTYPE_PURE_VIRTUALS): Update
+ comments.
+ * call.c (build_new_method_call): Don't confirm a pure virtual is
+ in CLASSTYPE_PURE_VIRTUALS. Reorder checks. Make it a warning.
+ * class.c (check_methods): CLASSTYPE_INLINE_FRIENDS is a VEC(tree).
+ (fixup_inline_methods, finish_struct): Likewise.
+ * decl.c (finish_method): Likewise.
+ * search.c (dfs_get_pure_virtuals, get_pure_virtuals):
+ CLASSTYPE_PURE_VIRTUALS is a VEC(tree).
+ * typeck2.c (abstract_virtuals_error): Likewise. Truncate the
+ vector to avoid repeating the list in error messages.
+
+2004-09-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_COMDAT_GROUP): Define.
+ * cp-tree.h (cxx_comdat_group): Declare.
+ * decl.c (cxx_comdat_group): New function.
+
+2004-09-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (get_pure_virtuals): Remove unused variables.
+
+ * cp-tree.h (struct lang_decl_flags): Remove
+ needs_final_overrider.
+ (DECL_NEEDS_FINAL_OVERRIDER_P): Remove.
+ * decl.c (duplicate_decls): Do not copy DECL_NEEDS_FINAL_OVERRIDER_P.
+ * class.c (finish_struct_bits): Correct comment about
+ CLASSTYPE_PURE_VIRTUALS.
+ * search.c (get_pure_virtuals): Remove useless loop.
+
+2004-09-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17324
+ * mangle.c (partially_mangled_name): New variable.
+ (partially_mangled_name_len): Likewise.
+ (save_partially_mangled_name): New function.
+ (restore_partially_mangled_name): Likewise.
+ (write_encoding): Save and restore partially mangled names around
+ calls to get_mostly_instantiated_function_type.
+ (write_unqualified_name): Likewise.
+
+2004-09-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (unify): Replace gcc_unreachable with gcc_assert.
+
+2004-09-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16162
+ * parser.c (cp_parser_id_expression): Correct value for
+ is_declarator.
+ (cp_parser_nested_name_specifier_opt): Look through typenames as
+ necessary.
+ (cp_parser_template_name): Honor check_dependency_p.
+
+ PR c++/16716
+ * parser.c (cp_parser_parse_and_diagnose_invalid_type_name):
+ Robustify.
+
+ PR c++/17327
+ * pt.c (unify): Add ENUMERAL_TYPE case. Replace sorry with
+ gcc_unreacable.
+
+2004-09-12 Richard Henderson <rth@redhat.com>
+
+ PR c++/16254
+ * semantics.c (maybe_cleanup_point_expr): Don't call fold.
+ * typeck.c (condition_conversion): Likewise.
+
+2004-09-11 Richard Henderson <rth@redhat.com>
+
+ PR c++/17404
+ * pt.c (cur_stmt_expr): Move from tsubst_expr.
+ (tsubst_expr) <case STMT_EXPR>: Move ...
+ (tsubst_copy_and_build): ... here.
+
+2004-09-10 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-tree.h (interface_only, interface_unknown): Delete declarations;
+ comment explaining them moved to c-common.h.
+ * lex.c (interface_only, interface_unknown, extract_interface_info):
+ Delete definitions.
+ (cxx_finish): Don't reset interface_unknown.
+ (handle_pragma_interface): Don't set interface_only and
+ interface_unknown; just the like-named fields in finfo.
+ (handle_pragma_implementation): Adjust comment.
+ * decl2.c (cp_finish_file): Don't reset interface_only and
+ interface_unknown.
+ * method.c (synthesize_method): Don't reset interface_unknown or
+ call extract_interface_info.
+ * pt.c (pop_tinst_level): Don't call extract_interface_info.
+ * decl.c (start_cleanup_fn): Don't save or restore interface_only
+ and interface_unknown.
+ (make_rtl_for_nonlocal_decl): Call get_fileinfo on input_filename
+ and use the result instead of the interface_only/interface_unknown
+ globals.
+ (start_preparsed_function): Likewise.
+ * lex.c (cxx_make_type): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+ (expand_body): Don't call extract_interface_info.
+
+2004-09-10 Ziemowit Laski <zlaski@apple.com>
+
+ * decl.c (objc_mark_locals_volatile): Make description of
+ routine more descriptive; only mark VAR_DECLs at each
+ binding level.
+
+2004-09-10 Richard Henderson <rth@redhat.com>
+
+ PR c++/17386
+ * call.c (build_vfield_ref): Move...
+ * class.c (build_vfield_ref): ... here. Convert datum to the
+ primary base containing the vptr.
+ (make_new_vtable): Simplify build_primary_vtable arguments.
+ (finish_struct_1): Do not duplicate TYPE_VFIELD.
+ * typeck.c (build_class_member_access_expr): Don't warn for
+ null object access to base fields.
+
+2004-09-10 Ziemowit Laski <zlaski@apple.com>
+
+ * decl.c (objc_get_current_scope, objc_mark_locals_volatile):
+ New functions, to be called from ObjC++.
+
+2004-09-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * class.c, cp-tree.h, decl.c, decl2.c, mangle.c,
+ name-lookup.h, parser.c, search.c, semantics.c, typeck2.c: Fix
+ comment typos.
+
+2004-09-09 Ziemowit Laski <zlaski@apple.com>
+
+ * typeck.c (build_c_cast): Preserve the cast if casting
+ to and from an Objective-C type.
+
+2004-09-09 Ziemowit Laski <zlaski@apple.com>
+
+ * Make-lang.in (cp/typeck.o): Depend on c-common.h.
+ * typeck.c: Include c-common.h.
+ (comptypes): For RECORD_TYPEs, call objc_comptypes() and
+ return the result if nonnegative.
+
+2004-09-09 Zack Weinberg <zack@codesourcery.com>
+
+ * decl2.c (import_export_class)
+ * lex.c (handle_pragma_interface):
+ Test MULTIPLE_SYMBOL_SPACES with if, not #ifdef.
+
+2004-09-08 Ziemowit Laski <zlaski@apple.com>
+
+ * Make-lang.in (cp/semantics.o): Depend on c-common.h.
+ * semantics.c: Include c-common.h.
+ (finish_compound_stmt): Call objc_clear_super_receiver().
+
+2004-09-08 Ziemowit Laski <zlaski@apple.com>
+
+ * cp-tree.h (do_poplevel): New prototype.
+ * semantics.c (do_poplevel): Make externally visible.
+
+2004-09-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (tree_pair_s): Define a GC'd vector.
+ * name-lookup.h (cxx_saved_binding, cp_class_binding): Likewise.
+ * semantics.c (deferred_access): Likewise.
+
+2004-09-06 Daniel Jacobowitz <dan@debian.org>
+
+ * semantics.c (expand_body): Assert that we are not nested.
+
+2004-09-06 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (build_enumerator): Use add_double and int_fits_type_p
+ instead of cp_build_binary_op, to avoid creating short-lived trees.
+ * parser.c (cp_parse_type_specifier <RID_ENUM>): Use two-token
+ lookahead instead of backtracking. Move some code to avoid a
+ conditional branch.
+ (cp_parser_enum_specifier): Avoid duplication of effort with caller.
+ Use cp_lexer_next_token_is/cp_lexer_next_token_is_not as appropriate.
+ (cp_parser_enumerator_list, cp_parser_enumerator_definition):
+ Use cp_lexer_next_token_is/cp_lexer_next_token_is_not as appropriate.
+
+2004-09-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl.c (grok_declarator): Remove a redundant semicolon.
+
+ * parser.c (cp_parser_decl_specifier_seq, cp_parser_type_specifier):
+ Correct comments describing function parameters.
+
+2004-09-03 Matt Austern <austern@apple.com>
+ Compile speed improvement.
+ * parser.c (cp_lexer_print_token): Only define if ENABLE_CHECKING set.
+ Otherwise define a stub macro that expands to nothing.
+ (cp_lexer_debugging_p): Only define if ENABLE_CHECKING set. Otherwise
+ define a stub macro that expands to 0.
+ (cp_lexer_start_debugging): Only define if ENABLE_CHECKING set.
+ (cp_lexer_stop_debugging): Likewise.
+ (cp_lexer_debug_stream): Only define if ENABLE_CHECKING set. Otherwise
+ define a stub macro that expands to NULL.
+ (cp_lexer_new_main): Only set debugging_p if ENABLE_CHECKING set.
+ (cp_lexer_new_from_tokens): Likewise.
+
+2004-09-03 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (finish_function): Clean out pointers we no longer need.
+
+2004-09-03 Jan Beulich <jbeulich@novell.com>
+
+ * g++spec.c (MATH_LIBRARY_PROFILE): Default to MATH_LIBRARY rather
+ than "-lm".
+
+2004-09-02 Paul Brook <paul@codesourcery.com>
+
+ * decl2.c (determine_visibility): Only check data visibility
+ for VAR_DECLS.
+
+2004-08-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_CONSTRUCTION_VTABLE_P): New macro.
+ * class.c (build_ctor_vtbl_group): Set DECL_CONSTRUCTION_VTABLE_P.
+ * decl2.c (determine_visibility): Honor
+ TARGET_CXX_EXPORT_CLASS_DATA.
+
+ * class.c (key_method): Rename to ...
+ (determine_key_method): ... this.
+ (finish_struct_1): Adjust accordingly.
+ * cp-tree.h (key_method): Declare.
+ * decl2.c (maybe_emit_vtables): Determine the key method here if
+ it has not already been done.
+
+2004-08-31 Ziemowit Laski <zlaski@apple.com>
+
+ * Make-lang.in (CXX_AND_OBJCXX_OBJS): Add cp/cp-objcp-common.o.
+ (cp/cp-lang.o): Depend on debug.h, gtype-cp.h and cp/cp-objcp-common.h.
+ (cp/cp-decl.c): Do not depend on gtype-cp.h.
+ (cp/cp-objcp-common.o): New target.
+ * cp-lang.c: Include debug.h, cp-objcp-common.h and gtype-cp.h.
+ (cxx_get_alias_set, cxx_warn_unused_global_decl, cp_expr_size,
+ cp_tree_size, cp_var_mod_type_p, cxx_initialize_diagnostics): Move
+ prototypes and definitions to cp-objcp-common.h and cp-objcp-common.c,
+ respectively.
+ (LANG_HOOKS_TREE_SIZE, LANG_HOOKS_FINISH,
+ LANG_HOOKS_CLEAR_BINDING_STACK, LANG_HOOKS_INIT_OPTIONS,
+ LANG_HOOKS_INITIALIZE_DIAGNOSTICS, LANG_HOOKS_HANDLE_OPTION,
+ LANG_HOOKS_HANDLE_FILENAME, LANG_HOOKS_MISSING_ARGUMENT,
+ LANG_HOOKS_POST_OPTIONS, LANG_HOOKS_GET_ALIAS_SET,
+ LANG_HOOKS_EXPAND_CONSTANT, LANG_HOOKS_EXPAND_EXPR,
+ LANG_HOOKS_EXPAND_DECL, LANG_HOOKS_PARSE_FILE,
+ LANG_HOOKS_DUP_LANG_SPECIFIC_DECL, LANG_HOOKS_TRUTHVALUE_CONVERSION,
+ LANG_HOOKS_SET_DECL_ASSEMBLER_NAME, LANG_HOOKS_MARK_ADDRESSABLE,
+ LANG_HOOKS_PRINT_STATISTICS, LANG_HOOKS_PRINT_XNODE,
+ LANG_HOOKS_PRINT_DECL, LANG_HOOKS_PRINT_TYPE,
+ LANG_HOOKS_PRINT_IDENTIFIER, LANG_HOOKS_PRINT_ERROR_FUNCTION,
+ LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, LANG_HOOKS_WRITE_GLOBALS,
+ LANG_HOOKS_FUNCTION_INIT, LANG_HOOKS_FUNCTION_FINAL,
+ LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P,
+ LANG_HOOKS_COMMON_ATTRIBUTE_TABLE, LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE,
+ LANG_HOOKS_ATTRIBUTE_TABLE, LANG_HOOKS_TREE_INLINING_WALK_SUBTREES,
+ LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN,
+ LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS,
+ LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P,
+ LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P,
+ LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P,
+ LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN,
+ LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN, LANG_HOOKS_EXPR_SIZE,
+ LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR,
+ LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION, LANG_HOOKS_MAKE_TYPE,
+ LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIZE,
+ LANG_HOOKS_SIGNED_TYPE, LANG_HOOKS_UNSIGNED_TYPE,
+ LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE, LANG_HOOKS_INCOMPLETE_TYPE_ERROR,
+ LANG_HOOKS_TYPE_PROMOTES_TO, LANG_HOOKS_REGISTER_BUILTIN_TYPE,
+ LANG_HOOKS_GIMPLIFY_EXPR, LANG_HOOKS_FOLD_OBJ_TYPE_REF): Move
+ hooks to cp-objcp-common.h.
+ (finish_file): New function.
+ * cp-objcp-common.c: New file.
+ * cp-objcp-common.h: New file.
+ * cp-tree.h (cp_finish_file): New prototype.
+ * decl.c: Do not include gtype-cp.h.
+ * decl2.c (finish_file): Rename to cp_finish_file.
+
+2004-08-31 Richard Henderson <rth@redhat.com>
+
+ PR c++/17221
+ * pt.c (tsubst_expr): Move OFFSETOF_EXPR handling ...
+ (tsubst_copy_and_build): ... here.
+
+2004-08-30 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (initialize_artificial_var): Declare.
+ * decl.c (initialize_artifical_var): New function.
+ * class.c (initialize_array): Remove.
+ (initialize_vtable): Use initialize_artificial_var.
+ (build_vtt): Likewise.
+ (build_ctor_vtbl_group): Likewise.
+
+2004-08-30 Richard Henderson <rth@redhat.com>
+
+ * class.c (build_base_path): Use build_address directly.
+ * typeck.c (build_unary_op): Don't lower &a.b to pointer
+ arithmetic directly.
+ * typeck2.c (store_init_value): Don't assume !TREE_CONSTANT
+ means !initializer_constant_valid_p.
+
+2004-08-30 Richard Henderson <rth@redhat.com>
+
+ * class.c (fixed_type_or_null): Use get_base_address before
+ assuming an ADDR_EXPR is non-null.
+
+2004-08-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * name-lookup.c (pop_binding, pushdecl,
+ set_identifier_type_value_with_scope, push_overloaded_decl,
+ arg_assoc_type): Replace abort with gcc_assert or gcc_unreachable.
+ * parser.c (cp_parser_diagnose_invalid_type_name,
+ cp_parser_postfix_expression, cp_parser_unary_expression,
+ cp_parser_check_declarator_template_para): Likewise.
+ * pt.c (push_inline_template_parms_recursive,
+ check_explicit_specialization, convert_nontype_argument,
+ coerce_template_template_parms, uses_template_parms,
+ instantiate_class_template, tsubst_decl, tsubst, tsubst_copy,
+ tsubst_expr, instantiate_template,
+ maybe_adjust_types_for_deduction, type_unification_real,
+ resolve_overloaded_unification, template_decl_level,
+ type_dependent_expression_p): Likewise.
+ * search.c (lookup_base_r): Likewise.
+ * semantics.c (finish_stmt_expr, simplify_aggr_init_expr): Likewise.
+ * tree.c (lvalue_p_1, count_functions, cxx_printable_name,
+ verify_stmt_tree_r, get_type_decl, stabilize_call): Likewise.
+ * typeck.c (common_type, get_member_function_from_ptrfunc,
+ build_binary_op, build_unary_op, expand_ptrmemfunc_cst): Likewise.
+ * typeck2.c (cxx_incomplete_type_diagnostic,
+ split_nonconstant_init_1, store_init_value,
+ process_init_constructor): Likewise.
+
+2004-08-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (check_dtor_name): Replace abort with gcc_assert or
+ gcc_unreachable.
+ (build_call, add_builtin_candidate, build_new_op,
+ convert_like_real, build_over_call, in_charge_arg_for_name,
+ source_type, joust): Likewise.
+ * class.c (build_simple_base_path, get_vcall_index,
+ finish_struct_1, instantiate_type, get_enclosing_class,
+ add_vcall_offset_vtbl_entries_1, cp_fold_obj_type_ref): Likewise.
+ * cp-gimplify.c (cp_genericize): Likewise.
+ * cp-lang.c (cp_expr_size, cp_tree_size): Likewise.
+ * cvt.c (cp_convert_to_pointer, ocp_convert): Likewise.
+ * decl.c (poplevel, make_unbound_class_template, reshape_init,
+ check_special_function_return_type, grokdeclarator,
+ grok_op_properties, tag_name, xref_tag, start_preparsed_function,
+ finish_function): Likewise.
+ * decl2.c (grokfield, maybe_emit_vtables):Likewise.
+ * error.c (dump_global_iord, dump_decl, dump_template_decl,
+ language_to_string): Likewise.
+ * except.c (choose_personality_routine): Likewise.
+ * friend.c (do_friend): Likewise.
+ * g++spec.c (lang_specific_driver): Likewise.
+ * init.c (build_zero_init, expand_default_init, build_new_1,
+ build_vec_delete_1, build_vec_init, build_dtor_call): Likewise.
+ * lex.c (retrofit_lang_decl, cp_type_qual_from_rid): Likewise.
+ * mangle.c (add_substitution, write_unscoped_name,
+ write_template_prefix, write_identifier,
+ write_special_name_destructor, write_type, write_builtin_type,
+ write_expression, write_template_param,
+ write_java_integer_type_codes): Likewise.
+ * method.c (implicitly_declare_fn): Likewise.
+
+2004-08-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (BINFO_PRIMARY_P): Use a binfo flag.
+ (BINFO_INDIRECT_PRIMARY_P): Remove.
+ * class.c (determine_primary_base): Rename to ...
+ (determine_primary_bases): ... here. Set all primary bases.
+ (set_primary_base): Remove.
+ (mark_primary_bases): Remove.
+ (build_simple_base_path, walk_subobject_offsets,
+ propagate_binfo_offsets, end_of_class): Adjust.
+ (layout_class_type): Rename determine_primary_base call.
+ (dump_class_hierarchy_r, dump_vtable): Adjust. Don't pass a binfo
+ to type_as_string.
+ (dfs_build_secondary_vptr_vtt_inits, dfs_accumulate_vtbl_inits,
+ build_rtti_vtbl_entries): Adjust.
+ * init.c (build_vtbl_address): Adjust.
+
+ * cp-tree.h (SET_BINFO_NEW_VTABLE_MARKED): Use gcc_assert.
+
+2004-08-28 Ziemowit Laski <zlaski@apple.com>
+
+ * Make-lang.in (CXX_OBJS): Split up into CXX_OBJS and
+ CXX_AND_OBJCXX_OBJS.
+ (CXX_C_OBJS): Include in CXX_AND_OBJCXX_OBJS instead of listing
+ separately on the link line.
+
+2004-08-28 Jason Merrill <jason@redhat.com>
+
+ * decl.c (expand_static_init): Avoid bogus warnings.
+
+2004-08-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/16851
+ * tree.c (stabilize_init): See through a COMPOUND_EXPR.
+
+ PR c++/13684
+ * decl.c (expand_static_init): Use thread-safety API.
+ (register_dtor_fn): Return the call, don't expand it.
+ * tree.c (add_stmt_to_compound): New fn.
+ (stabilize_call): Use it.
+
+2004-08-27 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.def (OFFSETOF_EXPR): New.
+ * parser.c (cp_parser_builtin_offsetof): Either built an
+ OFFSETOF_EXPR, or call fold_offsetof immediately.
+ * pt.c (tsubst_expr): Handle OFFSETOF_EXPR.
+
+2004-08-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (validate_conversion_obstack): Replace
+ my_friendly_assert with gcc_assert or gcc_unreachable.
+ (direct_reference_binding, merge_conversion_sequences,
+ build_user_type_conversion_1, perform_overload_resolution,
+ build_op_delete_call, enforce_access, call_builtin_trap,
+ build_over_call, build_special_member_call, build_new_method_call,
+ initialize_reference): Likewise.
+ * class.c (build_base_path, build_primary_vtable, alter_access,
+ check_bases, update_vtable_entry_for_fn, layout_empty_base,
+ clone_function_decl, adjust_clone_args,
+ type_requires_array_cookie, include_empty_classes,
+ finish_struct_1, resolve_address_of_overloaded_function,
+ instantiate_type, get_vtbl_decl_for_binfo, build_vtt_inits,
+ dfs_build_secondary_vptr_vtt_inits, build_ctor_vtbl_group,
+ accumulate_vtbl_inits, build_vtbl_initializer,
+ build_vbase_offset_vtbl_entries, build_rtti_vtbl_entries): Likewise.
+ * cvt.c (build_up_reference, convert_to_reference): Likewise.
+ * decl.c (poplevel, duplicate_decls, make_typename_type,
+ cxx_init_decl_processing, reshape_init, check_initializer,
+ make_rtl_for_nonlocal_decl, initialize_local_var, cp_finish_decl,
+ expand_static_init, grokfndecl, grokvardecl, build_ptrmem_type,
+ grokdeclarator, copy_fn_p, grok_op_properties, xref_tag,
+ xref_basetypes, start_preparsed_function, save_function_data,
+ finish_function, finish_method, maybe_register_incomplete_var,
+ complete_vars): Likewise.
+ * decl2.c (grok_array_decl, check_member_template,
+ check_classfn, finish_static_data_member_decl, coerce_new_type,
+ coerce_delete_type, import_export_class, decl_needed_p,
+ determine_visibility, import_export_decl, build_cleanup,
+ start_static_initialization_or_destructi, do_static_destruction,
+ prune_vars_needing_no_initialization,
+ build_offset_ref_call_from_tree): Likewise.
+ * error.c (dump_decl, dump_expr): Likewise.
+ * init.c (finish_init_stmts, build_zero_init,
+ expand_virtual_init, expand_default_init, expand_aggr_init_1,
+ build_offset_ref, build_new_1, build_delete, build_vbase_delete):
+ Likewise.
+ * mangle.c (write_method_parms, write_template_args,
+ write_expression, write_template_arg): Likewise.
+ * method.c (make_thunk, finish_thunk, use_thunk): Likewise.
+ * name-lookup.c (pop_binding, begin_scope, leave_scope,
+ resume_scope, push_using_decl, validate_nonmember_using_decl,
+ is_ancestor, poplevel_class, set_inherited_value_binding_p,
+ push_class_level_binding, do_class_using_decl, push_namespace,
+ pop_namespace, add_using_namespace, ambiguous_decl,
+ lookup_namespace_name, lookup_type_current_level,
+ maybe_process_template_type_declaration): Likewise.
+ * parser.c (cp_lexer_peek_nth_token,
+ cp_parser_parse_and_diagnose_invalid_typ,
+ cp_parser_translation_unit, cp_parser_template_id,
+ cp_parser_lookup_name, cp_parser_late_parsing_for_member): Likewise.
+ * pt.c (push_access_scope, finish_member_template_decl,
+ push_inline_template_parms_recursive, add_outermost_template_args,
+ get_innermost_template_args, begin_explicit_instantiation,
+ end_explicit_instantiation, retrieve_specialization,
+ is_specialization_of, is_specialization_of_friend,
+ register_specialization, check_explicit_specialization,
+ comp_template_parms, process_template_parm,
+ process_partial_specialization, convert_nontype_argument,
+ coerce_template_template_parms, coerce_template_parms,
+ mangle_class_name_for_template, lookup_template_function,
+ lookup_template_class, instantiate_class_template, tsubst_decl,
+ tsubst_function_type, tsubst, tsubst_qualified_id, tsubst_copy,
+ instantiate_template, fn_type_unification, type_unification_real,
+ get_template_base, regenerate_decl_from_template,
+ template_for_substitution, instantiate_decl,
+ get_mostly_instantiated_function_type, dependent_scope_ref_p,
+ value_dependent_expression_p, resolve_typename_type): Likewise.
+ * repo.c (repo_emit_p): Likewise.
+ * rtti.c (build_headof, get_tinfo_decl, get_pseudo_ti_init,
+ create_tinfo_types, emit_tinfo_decl): Likewise.
+ * search.c (lookup_base_r, lookup_base, lookup_field_1,
+ dfs_access_in_type, build_baselink, lookup_member,
+ adjust_result_of_qualified_name_lookup, copied_binfo): Likewise.
+ * semantics.c (perform_or_defer_access_check,
+ finish_non_static_data_member, finish_stmt_expr_expr,
+ finish_stmt_expr, finish_call_expr, finish_pseudo_destructor_expr,
+ finish_template_template_parm, finish_member_declaration,
+ emit_associated_thunks): Likewise.
+ * tree.c (build_target_expr_with_type, force_target_expr,
+ copy_binfo, get_first_fn, cp_tree_equal): Likewise.
+ * typeck.c (type_after_usual_arithmetic_conversions, comptypes,
+ cxx_sizeof_or_alignof_type, perform_integral_promotions,
+ build_class_member_access_expr, finish_class_member_access_expr,
+ build_ptrmemfunc_access_expr, build_unary_op,
+ unary_complex_lvalue, cxx_mark_addressable, build_modify_expr,
+ build_ptrmemfunc, expand_ptrmemfunc_cst, check_return_expr
+ * typeck2.c (complete_type_check_abstract,
+ abstract_virtuals_error, process_init_constructor,
+ add_exception_specifier): Likewise.
+
+2004-08-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Use ssize_int.
+ * decl.c (complete_array_type): Likewise.
+ * method.c (finish_thunk): Likewise.
+ * search.c (get_dynamic_base_type): Likewise.
+
+2004-08-26 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (DECL_FIELD_IS_BASE): New.
+ * class.c (build_base_field): Set it.
+ (build_simple_base_path): Use it.
+ (fixed_type_or_null): Don't consider base fields definitive.
+
+2004-08-25 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/16693
+ PR tree-optimization/16372
+ * decl.c (finish_enum): Make the precision of the enumerated type
+ the same width as the underlying integer type.
+
+2004-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17155
+ * lex.c (build_lang_decl): Set DECL_NO_STATIC_CHAIN for all C++
+ functions.
+
+ * mangle.c (get_identifier_nocopy): Add cast.
+
+ * cp-tree.h (mangle_type): Remove.
+ * mangle.c (globals): GTY it.
+ (mangle_obstack): New variable.
+ (name_obstack): Likewise.
+ (name_base): Likewise.
+ (write_char): Adjust accordingly.
+ (write_chars): Likewise.
+ (write_string): Likewise.
+ (start_mangling): Initialize G.substitutions only one. Add
+ ident_p parameter.
+ (finish_mangling): Use VARRAY_CLEAR to reclaim
+ storage in G.substitutions. Use obstack_finish.
+ (init_mangle): Adjust for changes to variable names above.
+ Initialize G.substitutions.
+ (mangle_decl_string): Adjust call to start_mangling.
+ (get_identifier_nocopy): New function.
+ (mangle_decl): Use it.
+ (mangle_type_string): Adjust call to start_mangling.
+ (mangle_special_for_type): Likewise.
+ (mangle_vtt_for_type): Likewise.
+ (mangle_ctor_vtbl_for_type): Likewise.
+ (mangle_thunk): Likewise.
+ (mangle_guard_variable): Likewise.
+ (mangle_ref_init_variable): Likewise.
+
+2004-08-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/14428
+ * pt.c (redeclare_class_template): Check the type of non-type and
+ template template parameter.
+
+2004-08-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (convert_class_to_reference): Adjust build_int_cst calls.
+ (build_user_type_conversion_1, convert_like_real,
+ build_java_interface_fn_ref, build_special_member_call): Likewise.
+ * class.c (finish_struct_1, build_vtbl_initializer): Likewise.
+ * cp-gimplify.c (cp_gimplify_expr): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ * decl.c (cxx_init_decl_processing, complete_array_type): Likewise.
+ * decl2.c (start_static_initialization_or_destruction,
+ generate_ctor_or_dtor_function): Likewise.
+ * except.c (build_throw): Likewise.
+ * mangle.c (write_integer_cst): Likewise.
+ * method.c (finish_thunk): Likewise.
+ * rtti.c (build_headof, get_tinfo_decl_dynamic,
+ build_dynamic_cast_1, ptr_initializer, ptm_initializer,
+ get_pseudo_ti_init): Likewise.
+ * search.c (get_dynamic_cast_base_type): Likewise.
+
+2004-08-25 Zack Weinberg <zack@codesourcery.com>
+
+ * class.c, search.c: Remove references to DWARF_DEBUG.
+
+2004-08-25 Adam Nemet <anemet@lnxw.com>
+
+ * repo.c (extract_string): Reset backquote after one character.
+ (get_base_filename): Fix indentation.
+
+2004-08-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (cxx_init_decl_processing): Adjust
+ build_common_tree_nodes call.
+
+2004-08-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/16889
+ * (is_subobject_of_p): Resurrect & optimize.
+ (lookup_field_r): Use it.
+
+2004-08-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/16706
+ * search.c (friend_accessible_p): Increment processing_template_decl
+ when deal with TEMPLATE_DECL of SCOPE.
+
+2004-08-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/17149
+ * semantics.c (check_accessibility_of_qualified_id): Defer check
+ if qualifying_type is a template parameter.
+
+2004-08-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17163
+ * pt.c (instantiate_decl): Do not try to apply
+ DECL_DECLARED_INLINED_P to a VAR_DECL.
+
+ * search.c (build_baselink): Fix typo in comment.
+
+2004-08-22 Andrew Pinski <apinski@apple.com>
+
+ Revert:
+ 2004-08-22 Andrew Pinski <apinski@apple.com>
+ PR c++/14029
+ * typeck.c (build_unary_op): Use &a.b if the folded lowered
+ expression is not constant.
+
+2004-08-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * name-lookup.c (pushdecl): Rename build_type_copy call.
+ * tree.c (cp_build_qualified_type_real,
+ build_exception_variant, handle_java_interface_attribute): Likewise.
+
+2004-08-22 Andrew Pinski <apinski@apple.com>
+
+ PR c++/14029
+ * typeck.c (build_unary_op): Use &a.b if the folded lowered
+ expression is not constant.
+
+2004-08-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17121
+ * decl.c (expand_static_init): Use DECL_FUNCTION_SCOPE_P.
+
+2004-08-21 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c++/17120
+ * pt.c (tsubst_copy_and_build): Avoid clearing TREE_NO_WARNING for
+ MODOP_EXPR.
+
+2004-08-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (register_specialization): Check DECL_TEMPLATE_SPECIALIZATION
+ before calling comp_template_args.
+
+2004-08-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Use build_int_cst for
+ negative size types.
+ * decl.c (complete_array_type): Likewise.
+ * method.c (finish_thunk): Likewise.
+
+2004-08-20 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * tree.c: Remove unused mark_local_for_remap_r.
+
+2004-08-19 Eric Christopher <echristo@redhat.com>
+
+ * cp-tree.h (cxx_unsave_expr_now): Delete prototype.
+ * tree.c (cxx_unsave_expr_now): Delete.
+ (cp_unsave_r): Ditto.
+
+2004-08-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15890
+ * pt.c (push_template_decl_real): Disallow template allocation
+ functions with fewer than two parameters.
+
+2004-08-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (build_shared_int_cst): Remove.
+ * tree.c (shared_int_cache): Remove.
+ (build_shared_int_cst): Remove.
+ * class.c (finish_struct_1): Use build_int_cst.
+
+2004-08-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (finish_enum): Do not copy value node early, copy
+ later.
+ * lex.c (cxx_init): Force null_node to be unique.
+
+2004-08-19 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c++/17041
+ * pt.c (tsubst_copy, tsubst_copy_and_build): Copy TREE_NO_WARNING
+ from input for MODOP_EXPR.
+
+2004-08-18 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (dependent_template_p): Fix typo in commment.
+
+ PR c++/17068
+ * pt.c (dependent_template_p): Treat IDENTIFIER_NODEs as
+ dependent.
+
+2004-08-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16246
+ * pt.c (unify): Tidy ARRAY_TYPE handling. Make sure that non-type
+ arguments have the same type as the corresponding parameter.
+
+ PR c++/16215
+ * parser.c (cp_parser_name_lookup_error): If parser->object_scope
+ is set use it for diagnostic purposes.
+ (cp_parser_pseudo_destructor_name): Remove special-case error
+ message.
+
+ PR c++/15871
+ * semantics.c (expand_or_defer_fn): Honor -fkeep-inline-functions.
+
+ PR c++/16965
+ * cp-tree.h (qualified_name_lookup_error): Add parameter.
+ * name-lookup.c (do_class_using_decl): Restrict set of entities
+ passed to cp_emit_debug_info_for_using more carefully.
+ (lookup_qualified_name): Allow lookup_member to return sets of
+ ambiguous entries.
+ * parser.c (cp_parser_lookup_name): Add ambiguous_p parameter.
+ (cp_parser_primary_expression): Handle ambiguous lookups.
+ (cp_parser_template_name): Adjust use of cp_parser_lookup_name.
+ (cp_parser_template_argument): Likewise.
+ (cp_parser_elaborate_type_specifier): Likewise.
+ (cp_parser_namespace_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_lookup_name_simple): Likewise.
+ * pt.c (tsubst_qualified_id): Handle ambiguous results.
+ (tsubst_expr): Likewise.
+ * semantics.c (qualified_name_lookup_error): Add decl paramter.
+ For ambiguous lookups, print candidates.
+
+2004-08-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6749
+ * pt.c (instantiate_pending_templates): Add int parameter. Don't
+ return anything.
+ * cp-tree.h (instantiate_pending_templates): Adjust prototype.
+ * decl2.c (finish_file): Adjust call to
+ instantiate_pending_templates.
+
+2004-08-15 Roger Sayle <roger@eyesopen.com>
+
+ * call.c (build_vfield_ref, build_call, build_conditional_expr,
+ convert_arg_to_ellipsis, build_x_va_arg, build_over_call,
+ build_java_interface_fn_ref, build_special_member_call,
+ build_new_method_call, initialize_reference): Replace calls to
+ build with calls to buildN.
+ * class.c (build_base_path, convert_to_base_statically,
+ build_vfn_ref, instantiate_type, dfs_accumulate_vtbl_inits,
+ build_vtbl_initializer): Likewise.
+ * cp-gimplify.c (genericize_try_block, genericize_catch_block,
+ gimplify_if_stmt, cp_genericize_r): Likewise.
+ * cvt.c (convert_to_void): Likewise.
+ * decl.c (check_initializer, finish_constructor_body,
+ finish_destructor_body): Likewise.
+ * error.c (dump_expr): Likewise.
+ * except.c (build_exc_ptr, expand_start_catch_block, build_throw):
+ Likewise.
+ * init.c (perform_member_init, expand_virtual_init,
+ expand_cleanup_for_base, build_init, expand_default_init,
+ build_offset_ref, decl_constant_value, build_new, build_new_1,
+ build_vec_delete_1, build_vec_init, build_delete,
+ push_base_cleanups, build_vec_delete): Likewise.
+ * mangle.c (write_integer_cst): Likewise.
+ * method.c (thunk_adjust, do_build_copy_constructor,
+ do_build_assign_ref): Likewise.
+ * pt.c (lookup_template_function, tsubst, tsubst_copy_and_build,
+ unify, build_non_dependent_expr): Likewise.
+ * rtti.c (build_headof, build_typeid, ifnonnull,
+ build_dyanmic_cast_1, tinfo_base_init): Likewise.
+ * semantics.c (begin_compound_stmt, finish_call_expr,
+ finish_pseudo_destructor_expr, finish_id_expression,
+ simplify_aggr_init_expr, finalize_nrv_r): Likewise.
+ * tree.c (build_target_expr, build_cplus_new, array_type_nelts_top,
+ array_type_nelts_total, stabilize_call): Likewise.
+ * typeck.c (decay_conversion, build_class_member_access_expr,
+ lookup_destructor, build_ptrmemfunc_access_expr, build_array_ref,
+ get_member_function_from_ptrfunc, build_binary_op, pointer_diff,
+ build_x_unary_op, build_unary_op, unary_complex_lvalue,
+ build_compound_expr, build_modify_expr, expand_ptrmemfunc_cst,
+ check_return_expr): Likewise.
+ * typeck2.c (split_nonconstant_1, split_nonconstant_init_1,
+ split_nonconstant_init, store_init_value, build_m_component_ref):
+ Likewise.
+
+2004-08-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (convert_class_to_reference,
+ build_user_type_conversion_1, convert_like_real,
+ build_java_interface_fn_ref, build_special_member_call): Use
+ build_int_cst.
+ * class.c (build_vtbl_initializer): Likewise.
+ * cp-gimplify.c (cp_gimplify_expr): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ * decl.c (cxx_init_decl_processing, complete_array_type): Likewise.
+ * decl2.c (start_static_initialization_or_destruction,
+ generate_ctor_or_dtor_function): Likewise.
+ * except.c (build_throw): Likewise.
+ * lex.c (cxx_init): Likewise.
+ * mangle.c (write_integer_cst): Likewise.
+ * rtti.c (build_headof, get_tinfo_decl_dynamic,
+ build_dynamic_cast_1, ptr_initializer, ptm_initializer,
+ get_pseudo_ti_init): Likewise.
+ * search.c (get_dynamic_cast_base_type): Likewise.
+ * tree.c (build_shared_int_cst): Likewise.
+
+2004-08-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16273
+ * class.c (count_depth_data): New type.
+ (dfs_depth_post): New function.
+ (dfs_depth_q): Likewise.
+ (find_final_overrider_data_s): Change type of vpath.
+ Add vpath_list.
+ (dfs_find_final_overrider_1): New function.
+ (dfs_find_final_overrider): Use it.
+ (dfs_find_final_overrider_q): Adjust use of vpath.
+ (dfs_find_final_overrider_post): Likewise.
+ (find_final_overrider): Use dfs_depth. Allocate and deallocate
+ vpath_list.
+
+2004-08-12 Jan Beulich <jbeulich@novell.com>
+
+ * parser.c (cp_parser_asm_definition): Properly consume scope operator
+ tokens preceding the clobbers. Don't check for scope operator
+ following inputs. Simplify inputs handling to match that now used for
+ clobbers.
+
+2004-08-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16698
+ * except.c (build_throw): Allocate cleanup_type and the function
+ for __cxa_throw separately.
+
+ PR c++/16853
+ * call.c (standard_conversion): Do not accept conversions between
+ pointers to members if the class types are unrelated.
+
+ PR c++/16618
+ * parser.c (cp_parser_builtin_offsetof): Cast to "const volatile
+ char &" instead of just "char &".
+
+ PR c++/16870
+ * pt.c (tsubst): Just return the unknown_type_node.
+
+2004-08-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16964
+ * parser.c (cp_parser_class_specifier): Robustify.
+
+ PR c++/16904
+ * pt.c (tsubst_copy_and_build): Complain about invalid
+ qualification.
+
+ PR c++/16929
+ * pt.c (tsubst_default_argument): Clear out current_class_ptr and
+ current_class_ref while tsubsting.
+
+2004-08-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16971
+ * parser.c (cp_parser_init_declarator): Robustify.
+
+2004-08-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * typeck2.c (process_init_constructor): Guard the missing field warning
+ with warn_missing_field_initializers rather than extra_warnings.
+
+2004-08-06 Paolo Bonzini <bonzini@gnu.org>
+
+ * class.c (instantiate_type) <ENTRY_VALUE_EXPR>: Do not handle.
+
+2004-08-05 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_preparsed_function): Move determine_visibility
+ call.
+ * decl2.c (determine_visibility): Incorporate dllexport testing.
+
+2004-08-05 Geoffrey Keating <geoffk@apple.com>
+
+ * g++spec.c (lang_specific_driver): An -Xlinker or -Wl, option
+ means that libstdc++ is needed.
+
+2004-08-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cvt.c (cp_convert_to_pointer): Adjust force_fit_type call.
+
+2004-08-04 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (make_rtl_for_nonlocal_decl): Set DECL_ASSEMBLER_NAME rather
+ than passing it as a parameter to rest_of_decl_compilation.
+ * decl2.c (grokfield): Use set_user_assembler_name.
+
+2004-08-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (complete_array_type): Don't gratuitously copy
+ maxindex. Its type is always set.
+
+2004-08-04 Paul Brook <paul@codesourcery.com>
+
+ * Make-lang.in (cp/semantics.o, cp/optimize.o): Depend on TARGET_H.
+ * cp-tree.h (struct language_function): Rename x_dtor_label to
+ x_cdtor_label.
+ (dtor_label): Rename ...
+ (cdtor_label): ... to this.
+ * decl.c (begin_constructor_body): Remove.
+ (check_special_function_return_type): Maybe change the return type.
+ (grokdeclarator): Pass the class type.
+ (start_preparsed_function): Constructors may need a return label.
+ (finish_constructor_body, finish_destructor_body): Set the return
+ value.
+ (begin_function_body): Don't call begin_constructor_body.
+ (finish_function): Don't warn for constructors or destructors.
+ (implicitly_declare_fn): Maybe change the return type.
+ * optimize.c: Include target.h.
+ (maybe_clone_body): Remap the function result.
+ * semantics.c: Include target.h.
+ (finish_return_stmt): Maybe jump to return label for constructors.
+
+2004-08-03 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable): Do not set DECL_VISIBILITY here.
+ (check_field_decls): Or here.
+ (check_methods): Or here.
+ (initialize_array): Don't mess with DECL_CONTEXT.
+ * cp-tree.h (start_decl): Adjust prototype.
+ (determine_visibility): New function.
+ * decl.c (duplicate_decls): Remove checks for hidden "operator
+ new".
+ (build_library_fn_1): Give all library functions default
+ visibility.
+ (start_decl): Add pop_scope_p parameter. Tidy.
+ (cp_finish_decl): Do not pop scopes here. Call
+ determine_visibility for variable definitions.
+ (start_preparsed_function): Call determine_visibility.
+ * decl2.c (determine_visibility): New function.
+ * method.c (use_thunk): Fix formatting.
+ * parser.c (cp_parser_condition): Adjust calls to start_decl.
+ (cp_parser_init_declarator): Likewise.
+ * pt.c (instantiate_decl): Always call pop_nested_class.
+ * rtti.c (get_tinfo_decl): Do not set DECL_VISIBILITY.
+ (tinfo_base_init): Likewise.
+
+2004-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16707
+ * name-lookup.c (validate_nonmember_using_decl): Robustify.
+
+2004-08-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16224
+ * name-lookup.c (decl_namespace): Remove.
+ (current_decl_namespace): Use decl_namespace_context instead of
+ decl_namespace.
+ (push_decl_namespace): Likewise.
+ (arg_assoc_class): Likewise.
+ (arg_assoc_type): Likewise.
+ * pt.c (check_specialization_namespace): New function.
+ (maybe_process_partial_specialization): Use it.
+ (register_specialization): Likewise.
+
+ PR c++/16489
+ * cp-tree.h (DECL_INTEGRAL_CONSTANT_VAR_P): New macro.
+ * call.c (null_ptr_cst_p): Handle variables with constant
+ initializers.
+ * pt.c (convert_nontype_argument): Use
+ DECL_INTEGRAL_CONSTANT_VAR_P.
+ * semantics.c (finish_id_expression): Likewise.
+
+ PR c++/16529
+ * decl.c (duplicate_decls): Reject duplicate namespace
+ declarations.
+
+ PR c++/16810
+ * typeck.c (build_ptrmemfunc): Loosen assertion.
+
+2004-08-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * call.c (z_candidate::template_decl): Rename from template.
+ (add_template_candidate_real): Adjust member reference.
+ (joust): Likewise.
+
+2004-07-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (IDENTIFIER_REPO_CHOSEN): Define.
+ (lang_decl_flags): Narrow the width of "languages". Add
+ repo_available_p.
+ (DECL_NEEDED_P): Remove.
+ (FOR_EACH_CLONE): New macro.
+ (DECL_REPO_AVAILABLE_P): Likewise.
+ (DECL_TINFO_P): Likewise.
+ (set_linkage_according_to_type): Declare.
+ (import_export_vtable): Remove.
+ (import_export_tinfo): Likewise.
+ (mark_needed): New function.
+ (decl_needed_p): Likewise.
+ (note_vauge_linkage_fn): Likewise.
+ (init_repo): Change prototype.
+ (repo_template_used): Remove.
+ (repo_template_instantiated): Likewise.
+ (repo_emit_p): New function.
+ (repo_export_class_p): Likewise.
+ (no_linkage_check): Change prototype.
+ * class.c (set_linkage_according_to_type): New function.
+ (build_vtable): Use it. Do not call import_export_vtable. Set
+ DECL_IGNORED_P if appropriate.
+ * decl.c (duplicate_decls): Preserve DECL_REPO_AVAILABLE_P.
+ (make_rtL_for_nonlocal_decls): Check for template instantiations
+ explicitly.
+ (grokfndecl): Adjust call to no_linkage_check.
+ (set_linkage_for_static_data_member): New function.
+ (grokvardecl): Use it. Adjust call to no_linkage_check.
+ (grokdeclarator): Use set_linkage_for_static_data_member.
+ * decl2.c (note_vague_linkage_fn): New function.
+ (note_vague_linkage_var): Likewise.
+ (finish_static_data_member_decl): Use it.
+ (import_export_vtable): Remove.
+ (import_export_class): Use repo_export_class_p.
+ (var_finalized_p): Simplify.
+ (maybe_emit_vtables): Simplify.
+ (mark_needed): New function.
+ (decl_needed_p): Likewise.
+ (import_export_decl): Add documentation and consistency checks.
+ Use repo_emit_p. Handle virtual tables and RTTI information
+ here.
+ (import_export_tinfo): Remove.
+ (write_out_vars): Call import_export_decl.
+ (cxx_callgraph_analyze_expr): Ensure that all vtables are emitted
+ whenever one is.
+ (finish_file): Use decl_needed_p. Do not call import_export_decl
+ for undefined static data members. Do not warn about undefined
+ inlines when using a repository.
+ (mark_used): Use note_vague_linkage_fn. Always defer template
+ instantiations.
+ * lex.c (cxx_init): Adjust call to init_repo. Always set
+ flag_unit_at_a-time.
+ * method.c (synthesize_method): Remove unncessary
+ import_export_decl call.
+ (implicitly_declare_fn): Use set_linkage_according_to_type.
+ * optimize.c (maybe_clone_body): Use FOR_EACH_CLONE.
+ * pt.c (instantiate_class_template): Don't redundantly add classes
+ to keyed_classes. Don't call repo_template_used.
+ (tsubst_decl): Set DECL_INTERFACE_KNOWN for instantiations of
+ templates with internal linkage.
+ (check_instantiated_args): Adjust call to no_linkage_check.
+ (instantiate_template): Use FOR_EACH_CLONE.
+ (mark_definable): New function.
+ (mark_decl_instantiated): Use it.
+ (do_decl_instantiation): Adjust tests for explicit instantiation
+ after "extern template".
+ (instantiate_class_member): Do not use repo_template_instantiated.
+ (do_type_instantiation): Simplify.
+ (instantiate_decl): Use mark_definable. Check repo_emit_p.
+ Simplify.
+ * repo.c (repo_get_id): Remove.
+ (original_repo): Remove.
+ (IDENTIFIER_REPO_USED): Remove.
+ (IDENTIFIER_REPO_CHOSEN): Remove.
+ Remove all #if 0'd code.
+ (repo_template_used): Remove.
+ (repo_template_instantiated): Remove.
+ (temporary_obstack_initialized_p): New variable.
+ (init_repo): Register with lang_post_pch_load. Avoid creating
+ identifiers unnecessarily. Don't use original_repo. Close the
+ file here.
+ (reopen_repo_file_for_write): Not here.
+ (finish_repo): Always write out a new repository file.
+ (repo_emit_p): New function.
+ (repo_export_class_p): Likewise.
+ * rtti.c (get_tinfo_decl): Use set_linkage_according_to_type.
+ (involves_incomplete_p): New function.
+ (tinfo_base_init): Use it.
+ (ptr_initializer): Remove non_public_ptr parameter.
+ (ptm_initializer): Likewise.
+ (get_pseudo_ti_init): Likewise.
+ (unemitted_tinfo_decl_p): Remove.
+ (emit_tinfo_decl): Use import_export_decl.
+ * semantics.c (expand_body): Move updates of static_ctors and
+ static_dtors to ...
+ (expand_or_defer_fn): ... here.
+ * tree.c (no_linkage_check): Add relaxed_p parameter.
+
+2004-07-28 Eric Christopher <echristo@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_UNSAFE_FOR_REEVAL): Delete.
+
+2004-07-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (struct tree_pair_s): New.
+ (typedef tree_pair_p): New.
+ (DEF_VEC_O(tree_pair_s)): New.
+ (struct lang_type_class): Make vcall_indices a VEC(tree_pair_s).
+ (CLASSTYPE_VCALL_INDICES): Update documentation.
+ * class.c (get_vcall_index): Adjust.
+ (add_vcall_offset): Adjust.
+
+2004-07-27 Kelley Cook <kcook@gcc.gnu.org>
+
+ * pt.c, typeck.c: Remove spurious carriage returns.
+
+2004-07-27 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/14429
+ * pt.c (coerce_template_template_parms) <PARM_DECL case>: Only check
+ when the type of ARG is not dependent.
+
+2004-07-26 Geoffrey Keating <geoffk@apple.com>
+
+ * g++spec.c (LIBSTDCXX_PROFILE): Default to LIBSTDCXX.
+ (lang_specific_driver): If the C++ or math library options don't
+ start with '-l', don't count them as added libraries.
+
+2004-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (xref_basetypes): Adjust base access vector creation.
+ * rtti.c (get_pseudo_ti_init, get_pseudo_ti_desc): Adjust base
+ access accesses.
+ * search.c (dynamic_cast_base_recurse, dfs_access_in_type): Likewise.
+
+2004-07-26 Niall Douglas <s_fsfeurope2@nedprod.com>
+ Brian Ryner <bryner@brianryner.com>
+
+ PR c++/15000
+ PR c++/9283
+ * class.c (check_field_decls): Apply hidden visibility if
+ -fvisibility-inlines-hidden and inlined unless otherwise specified
+ (build_vtable): Set vtable visibility to class visibility.
+ (check_field_decls): Default static member visibility to class
+ visibility.
+ (check_methods): Default method visibility to class visibility.
+ * cp-tree.h: Added CLASSTYPE_VISIBILITY and
+ CLASSTYPE_VISIBILITY_SPECIFIED macro.
+ * decl.c (duplicate_decls): New logic for merging definition decls
+ with declaration decls. Added ignore & warning when non default
+ applied to global operator new or delete.
+ * method.c, optimize.c, rtti.c: Added setting of VISIBILITY_SPECIFIED
+ wherever VISIBILITY was changed
+ * rtti.c (get_tinfo_decl): Set typeinfo visibility to class
+ visibility.
+ (tinfo_base_init): Set typeinfo name visibility to class visibility.
+
+2004-07-25 Bernardo Innocenti <bernie@develer.com>
+
+ * decl.c: Rename all identifiers named `class' to `cl'.
+ * cp-tree.h: Likewise.
+
+2004-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (TYPE_SET_PTRMEMFUNC_TYPE): Use GGC_CNEW.
+ * typeck2.c (abstract_virtuals_error): Use GGC_NEW.
+ * name-lookup.c (binding_entry_make): Use GGC_NEW.
+ (binding_table_construct): Use GGC_CNEWVEC.
+ (binding_table_new): Use GGC_NEW.
+ (cxx_binding_make): Likewise.
+ (begin_scope): Likewise.
+ (push_to_top_level): Use GCC_CNEW.
+ * parser.c (cp_token_cache_new): Likewise.
+ (cp_token_cache_push_token): Likewise.
+ (cp_lexer_new_main): Likewise.
+ (cp_lexer_new_from_tokens): Likewise.
+ (cp_parser_context_new): Likewise.
+ (cp_parser_new): Likewise.
+ (cp_lexer_new_from_tokens): Use GGC_NEWVEC.
+ * lex.c (cxx_make_type): Use GGC_CNEW.
+ (retrofit_lang_decl): Use GGC_NEWVAR.
+ (cxx_dup_lang_specific_decl): Likewise.
+ (copy_lang_type): Likewise.
+ * decl.c (use_label): Use GGC_NEW instead of ggc_alloc.
+ (save_function_data): Likewise.
+ (lookup_label): Use GGC_CNEW instead of ggc_alloc_cleared.
+ (cxx_push_function_context): Likewise.
+
+2004-07-25 Richard Henderson <rth@redhat.com>
+
+ * decl.c (start_preparsed_function): Set DECL_ARTIFICIAL and
+ DECL_IGNORED_P on RESULT_DECL.
+ * semantics.c (finalize_nrv): Copy them too.
+
+2004-07-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (lookup_conversion_operator): Avoid two loops.
+ (add_conversions): Remove.
+ (check_hidden_convs, split_conversions,
+ lookup_conversions_r): New.
+ (lookup_conversions): Use lookup_conversions_r.
+
+2004-07-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (get_template_base): Check type is completable.
+
+2004-07-21 Eric Christopher <echristo@redhat.com>
+
+ * decl.c (poplevel): Inline unused variable checking.
+ Change formatting.
+
+2004-07-21 Paolo Bonzini <bonzini@gnu.org>
+
+ * typeck.c (build_binary_op): Do not use RDIV_EXPR for
+ integer vectors.
+
+2004-07-21 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14497
+ * pt.c (check_explicit_specialization): Remove extension to accept
+ specializations without template headers. Fall-through to normal
+ processing.
+
+2004-07-21 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/509
+ * pt.c (determine_specialization): New parameter template_count.
+ Disambiguate between member templates and member functions counting
+ the template headers.
+ (check_explicit_specialization): Update caller.
+ (tsubst_friend_function): Likewise.
+
+2004-07-20 Steven Bosscher <stevenb@suse.de>
+
+ * cp-tree.def (TINST_LEVEL): Make it an 'x' node.
+ * cp-tree.h (tinst_level_t): New tree type.
+ (union lang_tree_node): Handle it.
+ (TINST_LOCATION): New accessor macro.
+ (make_tinst_level): New prototype.
+ * cp-lang.c (cp_tree_size): Handle TINST_LEVEL.
+ * decl.c (cp_tree_node_structure): Likewise.
+ * error.c (print_instantiation_full_context): Use TINST_LOCATION.
+ (print_instantiation_partial_context): Likewise.
+ * pt.c (pop_tinst_level): Likewise.
+ (push_tinst_level): Use make_tinst_level.
+ * tree.c (make_tinst_level): New function.
+ (cp_walk_subtrees): Walk TINST_DECL for a TINST_LEVEL node.
+
+2004-07-20 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_simple_type_specifier): Fix typo.
+
+ PR c++/16637
+ * parser.c (cp_parser_simple_type_specifier): Do not record usage
+ of globally-qualified names.
+
+2004-07-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/16175
+ * error.c (dump_type) <BOUND_TEMPLATE_TEMPLATE_PARM case>: Output
+ cv qualifier.
+
+2004-07-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16623
+ * cp-tree.h (lang_type_class): Add lazy_assignment_op.
+ (CLASSTYPE_LAZY_ASSIGNMENT_OP): New macro.
+ * class.c (add_implicitly_declared_members): Use
+ CLASSTYPE_LAZY_ASSIGNMENT_OP.
+ * method.c (lazily_declare_fn): Clear
+ CLASSTYPE_LAZY_ASSIGNMENT_OP.
+ * search.c (lookup_fnfields_1): Check it.
+
+2004-07-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (vec_binfo_member): Remove.
+ * tree.c (vec_binfo_member): Remove.
+
+ * cp-tree.h (struct lang_type_class): Remove vfields field.
+ (CLASSTYPE_VFIELDS): Remove.
+ (SET_BINFO_NEW_VTABLE_MARKED): Adjust.
+ * class.c (determine_primary_base): Remove CLASSTYPE_VFIELDS
+ handling.
+ (dfs_modify_vtables): Use TYPE_CONTAINS_VPTR_P.
+ (finish_struct_1): Remove CLASSTYPE_VFIELDS handling.
+ * init.c (dfs_initialize_vtbl_ptrs): Use TYPE_CONTAINS_VPTR_P.
+
+2004-07-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (DEF_VEC_P(tree)): Remove here.
+ (BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX, BINFO_PRIMARY_BASE_OF):
+ Moved to common.
+ (BINFO_LANG_SLOTS): Remove.
+ * tree.c (copy_binfo): Adjust BINFO creation and accessors.
+ * decl.c (xref_basetypes): Adjust BINFO creation and accessors.
+ * class.c (check_bases): Adjust BINFO accessors.
+ (determine_primary_base, finish_struct_bits,
+ maybe_warn_about_overly_private_class, warn_hidden,
+ walk_subobject_offsets, propagate_binfo_offsets, end_of_class,
+ warn_about_ambiguous_bases, get_vfield_name,
+ dump_class_hierarchy_r, build_vtt_inits, accumulate_vtbl_inits,
+ add_vcall_offset_vtbl_entries_r): Likewise.
+ * dump.c (cp_dump_tree): Likewise.
+ * init.c (sort_mem_initializers, expand_member_init, build_delete,
+ push_base_cleanups): Likewise.
+ * method.c (do_build_copy_constructor, do_build_assign_ref,
+ synthesize_exception_spec): Likewise.
+ name-lookup.c (arg_assoc_class): Likewise.
+ * pt.c (instantiate_class_template,
+ get_template_base_recursive): Likewise.
+ * rtti.c (get_pseudo_ti_init, get_pseudo_ti_desc): Likewise.
+ * typeck2.c (process_init_constructor): Likewise.
+ * search.c (lookup_base_r, dynamic_cast_base_recurse,
+ dfs_access_in_type, dfs_walk_real, look_for_overrides,
+ types_overlap_p, copied_binfo, original_binfo): Likewise.
+ (binfo_for_vtable): Remove
+
+2004-07-20 Steven Bosscher <stevenb@suse.de>
+
+ * cp-tree.h (struct lang_decl_flags): Unify the template_info and
+ thunk_alias, and the access and virtual_offset fields.
+ (THUNK_VIRTUAL_OFFSET, THUNK_ALIAS): Adjust.
+ * decl.c (finish_case_label): Update c_add_case_node call.
+
+2004-07-19 Mark Mitchell <mark@codesourcery.com>
+
+ Revert patch for PR c++/16623.
+
+2004-07-19 Kelley Cook <kcook@gcc.gnu.org>
+
+ * except.c: Remove two spurious carriage returns.
+
+2004-07-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16623
+ * cp-tree.h (lang_type_class): Add lazy_assignment_op.
+ (CLASSTYPE_LAZY_ASSIGNMENT_OP): New macro.
+ * class.c (add_implicitly_declared_members): Use
+ CLASSTYPE_LAZY_ASSIGNMENT_OP.
+ * method.c (lazily_declare_fn): Clear
+ CLASSTYPE_LAZY_ASSIGNMENT_OP.
+ * search.c (lookup_fnfields_1): Check it.
+
+2004-07-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (add_method): Delay adding the slot until the end.
+ (determine_primary_base): Adjust VEC_iterate invokation.
+ (resort_type_method_vec, finish_struct_methods, warn_hidden,
+ walk_subobject_offsets, end_of_class, warn_about_ambiguous_bases,
+ build_vtbl_initializer): Likewise.
+ * init.c (sort_mem_initializers, build_delete, push_base_cleanups,
+ build_vbase_delete): Likewise.
+ * method.c (do_build_copy_constructor): Likewise.
+ * name-lookup.c (new_class_binding, print_binding_level,
+ poplevel_class, store_class_bindings, push_to_top_level,
+ pop_from_top_level): Likewise.
+ * pt.c (check_explicit_specialization): Likewise.
+ * search.c (lookup_conversion_operator, lookup_fnfields_1,
+ get_pure_virtuals, add_conversions, dfs_check_overlap,
+ binfo_for_vbase): Likewise.
+
+2004-07-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12170
+ * pt.c (unify) <BOUND_TEMPLATE_TEMPLATE_PARM case>: Use only
+ innermost set of template arguments during deduction. Simplify.
+
+2004-07-19 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * typeck.c (build_modify_expr, build_x_modify_expr): Set
+ TREE_NO_WARNING on assignments with an operator other than '='.
+
+2004-07-10 Steven Bosscher <stevenb@suse.de>
+ Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * cp-tree.h (C_SET_EXP_ORIGINAL_CODE): Remove.
+ * decl2.c (grokfield): Don't check current_class_depth via
+ unused TREE_COMPLEXITY.
+ * semantics.c (finish_parenthesized_expr): Set TREE_NO_WARNING
+ to avoid the missing parentheses warning.
+ Don't set C_SET_EXP_ORIGINAL_CODE.
+
+2004-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (no_linkage_helper): Remove.
+ (no_linkage_check): Don't use walk_tree_without_duplicates.
+
+ * mangle.c (write_expression): Issue a sorry for zero-operand
+ functional casts.
+
+2004-07-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13092
+ * init.c (build_offset_ref): Build SCOPE_REF with non-null
+ TREE_TYPE for non-dependent names.
+ * typeck.c (build_x_unary_op): Handle non-dependent SCOPE_REF.
+ * pt.c (type_dependent_expression_p): Handle SCOPE_REF with
+ unknown_type_node as its TREE_TYPE.
+ * cxx-pretty_print.c (pp_cxx_unqualified_id): Handle BASELINK.
+ * error.c (dump_decl) <SCOPE_REF case>: Use pp_expression.
+ (dump_expr) <SCOPE_REF case>: Likewise.
+
+2004-07-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/16115
+ * call.c (type_passed_as): Make the invisible reference type
+ __restrict.
+ * cp-gimplify.c (gimplify_cleanup_stmt): Rename to
+ cp_genericize_r. Handle invisible reference lowering.
+ (is_invisiref_parm): New fn.
+ (cp_genericize): Adjust the types of invisible reference parms.
+ Don't repeat the walk for clones.
+ * decl.c (store_parm_decls): Don't generate any code for clones.
+
+2004-07-17 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * cp-tree.h (builtin_function): Declare.
+
+2004-07-16 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (finish_struct_methods): Remove unncessary code.
+ (add_implicitly_declared_members): Create declarations for default
+ constructors and copy constructors lazily.
+ * cp-tree.h (lang_type_class): Remove lazy_default_ctor and
+ lazy_copy_ctor.
+ (CLASSTYPE_LAZY_DEFAULT_CTOR): New macro.
+ (CLASSTYPE_LAZY_COPY_CTOR): Likewise.
+ * decl2.c (check_classfn): Robustify.
+ (locate_dtor): Handle empty CLASSTYPE_METHOD_VEC.
+ (locate_ctor): Handle lazy default constructors.
+ (locate_copy): Handle lazy copy constructors.
+ (implicitly_declare_fn): Make sure we're looking at the
+ TYPE_MAIN_VARIANT for a class before creating functions. Don't
+ set TYPE_HAS_CONSTRUCTOR.
+ (lazily_declare_fn): New function.
+ * name-lookup.c (constructor_name_full): Simplify.
+ * search.c (lookup_fnfields_1): Lazily create methods, as
+ necessary.
+ (lookup_for_overrides): Handle empty CLASSTYPE_METHOD_VEC.
+
+2004-07-16 Steven Bosscher <stevenb@suse.de>
+
+ * cp-tree.h (struct lang_type): Don't have three GTY options on a
+ single bit GTY desc.
+
+2004-07-16 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING): Die.
+ * cp-tree.h (cp_copy_res_decl_for_inlining): Remove.
+ * tree.c (cp_copy_res_decl_for_inlining): Remove.
+
+2004-07-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (finish_struct_bits): Use for loop.
+ (propagate_binfo_offsets): Do primary binfo outside of loop.
+
+ PR c++/16583
+ * dump.c (cp_dump_tree): Don't dump the bases if there's no
+ binfo.
+
+ * pt.c (tsubst) <TREE_BINFO case>: We should never get here.
+
+2004-07-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_type_class): Remove has_real_assign_ref and
+ has_abstract_assign_ref. Make methods a VEC(tree) *.
+ (TYPE_HAS_CONST_ASSIGN_REF): Add documentation.
+ (CLASSTYPE_CONSTRUCTORS): Adjust for changes to CLASSTYPE_METHOD_VEC.
+ (CLASSTYPE_DESTRUCTORS): Likewise.
+ (TYPE_HAS_REAL_ASSIGN_REF): Remove.
+ (TYPE_HAS_ABSTRACT_ASSIGN_REF): Likewise.
+ (add_method): Change prototoype.
+ * class.c (add_method): Remove error_p parameter. Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ (handle_using_decl): Adjust call to add_method.
+ (maybe_warn_about_overly_private_class): Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ (resort_type_method_vec): Likewise.
+ (finish_struct_methods): Likewise.
+ (check_for_override): Likewise.
+ (warn_hidden): Likewise.
+ (add_implicitly_declared_members): Defer creation of assignment
+ operators. Adjust call to add_method.
+ (clone_function_decl): Adjust call to add_method.
+ (check_bases_and_members): Don't set TYPE_HAS_REAL_ASSIGN_REF.
+ (finish_struct_1): Use CLASSTYPE_DESTRUCTORS.
+ * decl.c (grok_special_member_properties): Don't set
+ TYPE_HAS_ABSTRACT_ASSIGN_REF.
+ * decl2.c (check_classfn): Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ * method.c (locate_dtor): Use CLASSTYPE_DESTRUCTORS.
+ (locate_ctor): Use CLASSTYPE_CONSTRUCTORS.
+ (locate_copy): Adjust for changes to CLASSTYPE_METHOD_VEC.
+ (implicitly_declare_fn): Set DECL_SOURCE_LOCATION. Do not call
+ cp_finish_decl.
+ * pt.c (check_explicit_specialization): Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ (instantiate_class_template): Do not set
+ TYPE_HAS_ABSTRACT_ASSIGN_REF.
+ * ptree.c (cxx_print_type): Don't try to print
+ CLASSTYPE_METHOD_VEC.
+ * rtti.c (emit_support_tinfos): Use CLASSTYPE_DESTRUCTORS.
+ * search.c (lookup_field_r): Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ (lookup_fnfields): Likewise.
+ (lookup_conversion_operator): Likewise.
+ (lookup_fnfields_1): Likewise. Create assignment operators
+ lazily.
+ (look_for_overrides_here): Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ (add_conversions): Likewise.
+ * semantics.c (finish_member_declaration): Adjust call to add_method.
+
+2004-07-15 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (cxx_types_compatible_p): To the middle-end,
+ references and pointers are compatible.
+
+2004-07-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (xref_basetypes): Refactor.
+ * tree.c (copy_base_binfos): Replace with ...
+ (copy_binfo): ... this. Deep copy the given binfo, (not the just
+ bases of the given base).
+ * cp-tree.h (copy_base_binfo): Remove.
+ (copy_binfo): Declare.
+
+2004-07-15 Mark Mitchell <mark@codesourcery.com>
+
+ * name-lookup.c (set_inherited_value_binding_p): Add class_type
+ parameter.
+ (get_class_binding): Adjust.
+ (push_class_level_binding): Don't use set_inherited_value_binding_p.
+
+2004-07-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (finish_struct_bits): Don't set TYPE_HAS_CONVERSION here.
+ * decl.c (xref_basetypes): Set it here.
+
+ * class.c (check_bases): Don't set CLASSTYPE_NON_AGGREGATE here.
+ Don't check for incomplete base.
+ (get_vfield_name): Simplify while loop.
+ * decl.c (xref_basetypes): Set CLASSTYPE_NON_AGGREGATE here.
+
+2004-07-14 Mark Mitchell <mark@codesourcery.com>
+
+ * lex.c (cxx_make_type): Remove call to get_pointer_type.
+
+ * cp-tree.h (IDENTIFIER_VALUE): Remove.
+ (BINFO_PUSHDECLS_MARKED): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (push_class_decls): Likewise.
+ * name-lookup.h (push_class_binding): Remove.
+ (innermost_non_namespace_value): New function.
+ (outer_binding): Likewise.
+ * class.c (add_method): Push bindings before adding to
+ TYPE_METHODS.
+ (restore_class_cache): Do not restore class_shadowed.
+ (pushclass): Do not add USING_DECLs. Do not call
+ push_class_decls.
+ * config-lang.in (gtfiles): Remove $(srcdir)/cp/search.c.
+ * decl.c (pushdecl): Use outer_binding.
+ (poplevel): Set the scope for an out-of-scope for-loop declaration
+ appropriately.
+ (cp_finish_decl): Don't call maybe_inject_for_scope_var.
+ * name-lookup.c (new_class_binding): New function.
+ (push_binding): Use it.
+ (pushdecl): Use innermost_non_namespace_value.
+ (maybe_inject_for_scope_var): Remove.
+ (push_class_binding): Remove.
+ (set_inherited_value_binding_p): New function.
+ (get_class_binding): New function.
+ (push_class_level_binding): Assert that the current_class_type is
+ being defined.
+ (outer_binding): New function.
+ (innermost_non_namespace_value): Likewise.
+ (lookup_name_real): Use outer_binding.
+ (lookup_name_current_level): Ignore out-of-scope variables.
+ * pt.c (check_template_shadow): Use innermost_non_namespace_value.
+ (lookup_template_class): Likewise.
+ * search.c (dfs_push_type_decls): Remove.
+ (dfs_push_decls): Likewise.
+ (setup_class_bindings): Likewise.
+ (lookup_field_1): Handle USING_DECLs from dependent scopes.
+ (marked_pushdecls_p): Remove.
+ (unmarked_pushdecls_p): Remove.
+ (marked_identifiers): Remove.
+ (setup_class_bindings): Remove.
+ (dfs_push_type_decls): Remove.
+ (dfs_push_decls): Remove.
+ (push_class_decls): Remove.
+
+2004-07-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16518
+ PR c++/16337
+ * decl.c (grokvardecl): Make declspecs parameter const.
+ (grokdeclarator): Likewise. Adjust accordingly.
+ * decl.h (grokdeclarator): Adjust declaration.
+ * parser.c (cp_parser_init_declarator): Do not clear
+ decl_specifiers->attributes.
+
+ * cp-tree.h (lang_identifier): Remove class_value.
+ (IDENTIFIER_CLASS_VALUE): Remove.
+ (pop_class_decls): Likewise.
+ (init_search_processing): Likewise.
+ * class.c (handle_using_decl): Use lookup_member, not
+ IDENTIFIER_CLASS_VALUE.
+ (restore_class_cache): New function, split out from ...
+ (pushclass): ... here. Do not call clear_identifier_class_values.
+ (invalidate_class_lookup_cache): Do not clear
+ IDENTIFIER_CLASS_VALUE.
+ (popclass): Do not call pop_class_decls.
+ (maybe_note_name_used_in_class): Do not save names looked up after
+ the class is complete. Use lookup_member, not
+ IDENTIFIER_CLASS_VALUE.
+ * config-lang.in (gtfiles): Add $(srcdir)/cp/search.c.
+ * decl.c (cxx_init_decl_processing): Do not call
+ init_search_processing.
+ * method.c (do_build_copy_constructor): Remove unnecessary code.
+ (do_build_assign_ref): Likewise.
+ * name-lookup.c (pushdecl): Use lookup_member, not
+ IDENTIFIER_CLASS_VALUE.
+ (set_identifier_type_value_with_scope): Set TREE_TYPE on the
+ type_shadowed list.
+ (poplevel_class): Do not restore IDENTIFIER_CLASS_VALUE.
+ (push_class_binding): Do not set it.
+ (clear_identifier_class_values): Remove.
+ (push_class_level_binding): Do not set IDENTIFIER_CLASS_VALUE.
+ (store_binding): Do not save it.
+ (pop_from_top_level): Do not restore it.
+ * name-lookup.h (cxx_saved_binding): Remove class_value.
+ (clear_identifier_class_values): Remove.
+ * ptree.c (cxx_print_identifier): Do not print
+ IDENTIFIER_CLASS_VALUE.
+ * search.c (search_obstack): Remove.
+ (push_stack_level): Remove.
+ (pop_stack_level): Remove.
+ (search_level): Remove.
+ (search_stack): Remove.
+ (lookup_member): Don't check IDENTIFIER_CLASS_VALUE.
+ (setup_class_bindings): Use IDENTIFIER_MARKED, not
+ IDENTIFIER_CLASS_VALUE.
+ (marked_identifiers): New variable.
+ (push_class_decls): Clear IDENTIFIER_MARKED.
+ (pop_class_decls): Don't call pop_search_level.
+ (init_search_processing): Remove.
+
+2004-07-12 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (get_aggr_typedef): Remove.
+ * init.c (get_aggr_typedef): Likewise.
+
+ * name-lookup.c (push_class_level_binding): Simplify.
+
+2004-07-12 Andrew Pinski <apinski@apple.com>
+
+ PR c++/16475
+ Revert:
+ 2004-07-07 H.J. Lu <hongjiu.lu@intel.com>
+ PR c++/16276
+ * rtti.c (emit_tinfo_decl): Turn off DECL_ONE_ONLY if typeinfo
+ is not public.
+
+2004-07-12 Eric Christopher <echristo@redhat.com>
+
+ * parser.c (cp_parser_class_head): Remove unused variable.
+
+2004-07-12 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * decl.c (grok_op_properties): Reject [de-]allocation functions
+ declared in a namespace, or declared as static.
+
+2004-07-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (make_binfo): Remove.
+ * decl.c (xref_basetypes): Use make_tree_binfo directly.
+ * tree.h (copy_base_binfos): Likewise.
+ (make_binfo): Remove.
+
+ * call.c (build_user_type_conversion_1, build_new_op,
+ check_constructor_callable, build_temp,
+ perform_direct_initialization_of_possible): Pass type directly to
+ lookup_fnfields & build_special_member_call.
+ (build_special_member_call): Accept a type, and complete it.
+ * class.c (finish_stuct_bits): Copy the BINFOs here.
+ * cvt.c (ocp_convert): Pass type directly to
+ build_special_member_call.
+ * decl.c (build_ptrmemfunc_type): Call xref_bastypes here.
+ (xref_basetypes): Allocate the binfo here. Adjust.
+ * init.c (build_init, build_new_1): Pass type directly to
+ build_special_member_call.
+ * lex.c (cxx_make_type): Do not allocate binfo here.
+ * name-lookup.c (arg_assoc_class): Incomplete types have no binfo.
+ * parser.c (cp_parser_class_head): Always call xref_basetypes.
+ * pt.c (instantiate_class_template): Likewise. Inhibit access
+ checking for template friends.
+ * ptree.c (cxx_print_type): Adjust record printing.
+ * search.c (lookup_base): When taking a type, complete it before
+ looking for a binfo.
+ (lookup_member): Delay completing a type.
+ (push_class_decls): Don't walk an incomplete type.
+ (lookup_conversions): Likewise.
+ * semantics.c (finish_stmt_expr_expr): Pass type directly to
+ build_special_member_call.
+ * tree.c (copy_base_binfos): Adjust.
+ (make_binfo): Likewise.
+ * typeck.c (build_modify_expr): Pass type directly to
+ build_special_member_call.
+ * typeck2.c (process_init_constructor): Check a binfo exists.
+ (build_m_component_ref): Allow accessing an incomplete type.
+ (build_functional_cast): Pass type directly to
+ build_special_member_call.
+
+2004-07-12 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/2204
+ * config-lang.in (gtfiles): Add typeck2.c.
+ * Make-lang.in: Tweak typeck2.c dependencies, and add rule for
+ gt-cp-typeck2.h.
+ * cp-tree.h: Declare complete_type_check_abstract.
+ * typeck2.c (pat_calc_hash, pat_compare,
+ complete_type_check_abstract): New functions.
+ (abstract_virtuals_error): If the type is abstract, register the
+ declaration within abstract_pending_vars for further checks.
+ Inspect also dependent types. Handle IDENTIFIER_NODEs as decl.
+ * decl.c (cp_finish_decl): Do not strip array types.
+ (create_array_type_for_decl): Check for abstractness of the element
+ type.
+ (complete_vars): Call complete_type_check_abstract.
+ * class.c (finish_struct): Prepare a list of virtual functions for
+ template types, and call complete_vars on it to check for abstractness.
+
+2004-07-12 Paolo Bonzini <bonzini@gnu.org>
+
+ PR tree-optimization/14107
+ * decl.c (finish_function): Remove temporary band-aid.
+
+2004-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_operator_new_call): Avoid using push_to_top_level.
+ (build_new_op): Adjust call to lookup_function_nonclass.
+ * name-lookup.c (identifier_type_value): Adjust call to
+ lookup_name_real.
+ (lookup_name_real): Add block_p parameter.
+ (lookup_name_nonclass): Adjust call to lookup_name_real.
+ (lookup_function_nonclass): Likewise.
+ (lookup_name): Likewise.
+ * name-lookup.h (lookup_name_real): Change prototype.
+ (lookup_name_nonclass): Likewise.
+ * parser.c (cp_parser_lookup_name): Likewise.
+
+ * cp-tree.h (saved_scope): Make old_bindings a vector.
+ (unuse_fields): Remove.
+ * name-lookup.h (cxx_saved_binding): Define it.
+ * class.c (pushclass): Don't use unuse_fields.
+ * name-lookup.c (cxx_saved_binding_make): Remove.
+ (store_binding): Add new bindings to a vector, using an
+ accumulator style, rather than adding them to a list.
+ (store_bindings): Adjust accordingly.
+ (store_class_bindings): Likewise.
+ (push_to_top_level): Likewise.
+ (pop_from_top_level): Likewise.
+ * optimize.c (maybe_clone_body): Must push_to_top_level and
+ pop_from_top_level calls outside of loop.
+ * parser.c (cp_parser_class_specifier): Move push_scope/pop_scope
+ calls here from cp_parser_late_parsing_default_args.
+ (cp_parser_save_default_args): Record the class type in which the
+ function is declared.
+ (cp_parser_late_parsing_default_args): Do not call
+ push_nested_class/pop_nested_class.
+ * search.c (dfs_unuse_fields): Remove.
+ (unuse_fields): Remove.
+
+2004-07-11 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * cp-lang.c (LANG_HOOKS_MAYBE_BUILD_CLEANUP, LANG_HOOKS_PUSHLEVEL,
+ LANG_HOOKS_POPLEVEL, LANG_HOOKS_UPDATE_DECL_AFTER_SAVING): Remove.
+ * cp-tree.h (poplevel): Declare.
+ (set_block): Remove.
+ * decl.c (set_block): Remove.
+
+2004-07-10 Mike Stump <mrs@apple.com>
+
+ * decl2.c (import_export_class): Never export/import vtables
+ with inline key functions.
+
+2004-07-09 Steven Bosscher <stevenb@suse.de>
+
+ * typeck.c (c_expand_asm_operands): Remove.
+
+2004-07-09 Mike Stump <mrs@apple.com>
+
+ * typeck.c (build_class_member_access_expr): Skip null deref
+ warning when we don't dereference it.
+
+2004-07-09 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/8211
+ PR c++/16165
+ * class.c (check_field_decls): Improve -Weffc++ warning: do not
+ warn for pointers to functions/members, or for classes without
+ destructors.
+
+2004-07-08 Mark Mitchell <mark@codesourcery.com>
+
+ * name-lookup.h (struct cp_binding_level): Update documentation
+ for class_shadowed.
+
+2004-07-08 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/16169
+ * typeck.c (check_return_expr): Improve -Weffc++ warning: handle
+ returning CALL_EXPR, and non-reference return type.
+
+2004-07-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * name-lookup.c (push_binding): Use VEC_reserve.
+
+2004-07-08 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (expand_eh_spec_block): Remove.
+
+2004-07-07 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (saved_scope): Remove x_previous_class_type and
+ x_previous_class_values; add x_previous_class_level.
+ (previous_class_type): Remove.
+ (previous_class_values): Remove.
+ (previous_class_level): New macro.
+ * class.c (pushclass): Restore the identifier cache more
+ expeditiously.
+ (invalidate_class_lookup_cache): Use vector for class_shadowed and
+ previous_class_values.
+ * decl.c (poplevel): Likewise.
+ * name-lookup.c (cxx_binding_init): New function.
+ (cxx_binding_make): Use it.
+ (push_binding): For a binding in a class level, use a vector of
+ cp_class_binding nodes.
+ (push_binding_level): New function.
+ (begin_scope): Use it.
+ (leave_scope): Do not put class binding levels on the free list.
+ (print_binding_level): Adjust for the fact that class_shadowed is
+ a vector.
+ (poplevel_class): Likewise.
+ (clear_identifier_class_values): Likewise.
+ (push_class_level_binding): Likewise.
+ (set_class_shadows): Remove.
+ (store_binding): New function.
+ (store_class_bindings): New function.
+ (push_to_top_level): Use store_class_bindings as appropriate.
+ (pop_from_top_level): Use previous_class_level, not
+ previous_class_type.
+ * name-lookup.h (cp_class_binding): New type.
+ (cp_binding_level): Use a vector object for class_shadowed.
+ (push_binding_level): Declare.
+ (set_class_shadows): Remove.
+
+2004-07-07 Andrew Pinski <apinski@apple.com>
+
+ * class.c (instantiate_type): BUFFER_REF is dead.
+ * lex.c (init_operators): IN_EXPR is dead.
+
+2004-07-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/16334
+ * call.c (build_new_op): Give overload warnings for built-in
+ candidates.
+
+2004-07-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/16276
+ * rtti.c (emit_tinfo_decl): Turn off DECL_ONE_ONLY if typeinfo
+ is not public.
+
+2004-07-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_N_BASECLASSES): Remove.
+ * class.c (build_primary_vtable, check_bases,
+ determine_primary_base, finish_struct_bits,
+ maybe_warn_about_overly_private_class, dfs_find_final_overrider_q,
+ get_basefndecls, warn_hidden, walk_subobject_offsets,
+ build_base_fields, create_vtable_ptr, propagate_binfo_offsets,
+ layout_virtual_bases, end_of_class, warn_about_ambiguous_bases,
+ finish_struct_1, get_vfield_name, contains_empty_class_p,
+ dump_class_hierarchy_r, finish_vtbls, build_vtt_inits,
+ dfs_ctor_vtable_bases_queue_p, accumulate_vtbl_inits,
+ add_vcall_offset_vtbl_entries_r, cp_fold_obj_type_ref): Adjust
+ BINFO macros.
+ * decl.c (xref_basetypes): Likewise.
+ * dump.c (cp_dump_tree): Likewise.
+ * error.c (dump_expr): Likewise.
+ * init.c (sort_mem_initializers, expand_member_init,
+ push_base_cleanups): Likewise.
+ * method.c (do_build_copy_constructor, do_build_assign_reg,
+ synthesize_exception_spec): Likewise.
+ * name-lookup.c (arg_assoc_class): Likewise.
+ * pt.c (instantiate_class_template, tsubst,
+ get_template_base_recursive): Likewise.
+ * ptree.c (cxx_print_type): Likewise.
+ * rtti.c (get_psuedo_ti_init, get_pseudo_ti_desc): Likewise.
+ * search.c (lookup_base_r, dynamic_cast_base_recurse,
+ dfs_access_in_type, access_in_type, lookup_field_queue_p,
+ bfs_walk, dfs_walk_real, look_for_overrides, markedp, unmarkedp,
+ marked_pushdecls_p, unmarked_pushdecls_p, dfs_debug_markedp,
+ dfs_debug_unmarkedp, dfs_check_overlap, dfs_no_overlap_yet,
+ binfo_for_vtable, copied_binfo, original_binfo): Likewise
+ * tree.c (copy_base_binfos, make_binfo): Likewise.
+ * typeck.c (commmon_base_type): Likewise
+ * typeck2.c (process_init_constructor): Likewise
+
+2004-07-06 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * decl.c (check_tag_decl): Name redeclared type in diagnostic.
+
+2004-07-06 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/3671
+ * pt.c (convert_nontype_argument): Disallow conversions between
+ different enumeration types.
+
+2004-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (BINFO_MARKED): Remove.
+ (BINFO_VTABLE_PATH_MARKED, BINFO_NEW_VTABLE_MARKED,
+ BINFO_DEPENDENT_BASE_P, BINFO_LOST_PRIMARY_P,
+ BINFO_INDIRECT_PRIMARY_P): Use appropriate BINFO_FLAG_n.
+ (SET_BINFO_NEW_VTABLE_MARKED): Use BINFO_VIRTUAL_P.
+ * class.c (build_base_path): Use BINFO_VIRTUAL_P.
+ (mark_primary_bases, determine_primary_base, base_derived_from,
+ dfs_find_final_overrider, dfs_find_final_overrider_q,
+ dfs_find_inal_overrider_post, update_vtable_entry_for_fn,
+ dfs_modify_vtables, walk_subobject_offsets,
+ layout_nonempty_base_or_field, build_base_field,
+ build_base_fields, propagate_binfo_offsets, layout_virtual_bases,
+ end_of_class, get_vfield_name, dump_class_hierarchy, dump_vtable,
+ finish_vtbls, build_vtt_inits, dfs_build_secondary_vptr_vtt_inits,
+ build_ctor_vtbl_group, accumulate_vtble_inits,
+ dfs_accumulate_vtbls_inits, build_vbase_offset_vtbl_entries,
+ build_vcall_offset_vtbl_entries, add_vcall_offset_vtbl_entries_r,
+ add_vcall_offset_vtbl_entries_1): Likewise.
+ * decl.c (xref_basetypes): Incoming virtual base indicated by
+ TREE_TYPE. Adjust.
+ * dump.c (cp_dump_tree): Use BINFO_VIRTUAL_P.
+ * init.c (finish_init_stmts, sort_mem_initializers,
+ emit_mem_initializers, build_vtble_address, expand_member_init,
+ push_base_cleanups): Likewise.
+ * method.c (do_build_copy_constructor): Likewise.
+ * pt.c (instantiate_class_template,
+ get_template_base_recursive): Likewise.
+ * rtti.c (dfs_class_hint_mark, get_pseudo_ti_init,
+ get_pseudo_ti_desc): Likewise.
+ * search.c (lookup_base_r, dynamic_cast_base_recurse,
+ binfo_from_vbase, binfo_via_virtual, copied_binfo,
+ original_binfo): Likewise.
+ * semantics.c (finish_base_specifier): Virtualness is indicated
+ by TREE_TYPE.
+ * tree.c (copy_base_binfos): Use BINFO_VIRTUAL_P.
+
+2004-07-06 Mark Mitchell <mark@codesourcery.com>
+
+ Revert:
+ 2004-06-24 Jason Merrill <jason@redhat.com>
+ PR c++/16115
+ * decl.c (grokparms): Give the PARM_DECL reference type if the
+ parameter is passed by invisible reference.
+
+2004-07-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * cp-lang.c (cp_var_mod_type_p): Add extra arg.
+ * decl.c (grokdeclarator): Extra arg to variably_modified_type_p.
+ * pt.c (check_instantiated_args, unify): Likewise.
+
+2004-07-05 Phil Edwards <phil@codesourcery.com>
+
+ * Make-lang.in (check-c++, lang_checks): Add some comments.
+
+2004-07-05 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-mudflap.c: Delete file.
+ * Makefile.in: Remove all references to cp-mudflap.o.
+
+2004-07-05 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (cxx_init_decl_processing): Call
+ build_common_tree_nodes before creating the global NAMESPACE_DECL.
+
+2004-07-05 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/2518
+ * call.c (build_operator_new_call): Look only at global scope.
+
+2004-07-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (enforce_access): Expect TREE_BINFO.
+ * class.c (binfo_ctor_vtable): Check TREE_BINFO.
+ * cp-tree.h (RECORD_OR_UNION_TYPE_CHECK): Remove.
+ (BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX, BINFO_PRIMARY_BASE_OF):
+ Adjust.
+ (BINFO_LANG_ELTS): Remove.
+ (BINFO_LANG_SLOTS): New.
+ (TYPE_RAISES_EXCEPTIONS, ENUM_TEMPLATE_INFO): Use TYPE_LANG_SLOT_1.
+ (CLASSTYPE_TEMPLATE_INFO): Adjust.
+ * pt.c (tsubst): Split TREE_BINFO case from TREE_VEC case.
+ * search.c (lookup_member): Check TREE_BINFO.
+ * semantics.c (perform_or_defer_access_check): Likewise.
+ (check_accessibility_of_qualified_id): Check
+ deferred_access_no_check.
+ * tree.c (make_binfo): Use make_tree_binfo.
+
+2004-07-04 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (implicitly_declare_fn): Set linkage of generated
+ functions.
+
+2004-07-04 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (cxx_mark_addressable): Don't put_var_into_stack.
+
+2004-07-03 Scott Brumbaugh <scottb.lists@verizon.net>
+
+ PR c++/3761
+ * name-lookup.c (push_class_level_binding): Don't pass a
+ TREE_LIST of ambiguous names to check_template_shadow as it
+ only handles declarations. Instead, pull the declaration
+ out and pass that.
+
+2004-07-03 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14971
+ * pt.c (check_explicit_specialization): Clarify error message.
+
+2004-07-02 Richard Henderson <rth@redhat.com>
+
+ * tree.c (cp_unsave_r): Update remap_save_expr call.
+
+2004-07-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16240
+ * mangle.c (write_template_arg): Correct mangling.
+
+ PR c++/16297
+ * decl.c (grokdeclarator): Robustify.
+
+2004-07-01 Richard Henderson <rth@redhat.com>
+
+ * class.c (fixed_type_or_null): Don't handle RTL_EXPR.
+ * method.c (synthesize_method): Don't clear_last_expr.
+ * name-lookup.c (maybe_push_cleanup_level): Likewise.
+
+2004-07-01 Nick Clifton <nickc@redhat.com>
+
+ * decl2.c (import_export_class): Invoke the
+ import_export_class field in the gcc_target structure if it is not
+ empty.
+
+2004-06-30 Richard Henderson (rth@redhat.com>
+
+ * decl.c (start_preparsed_function): Don't set immediate_size_expand.
+ * method.c (use_thunk): Likewise.
+
+2004-06-30 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * call.c (build_over_call), typeck.c (build_function_call): Call
+ check_function_arguments instead of check_function_format.
+
+2004-06-30 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * call.c (build_over_call), typeck.c (build_function_call): Update
+ calls to check_function_format.
+
+2004-06-30 Richard Henderson <rth@redhat.com>
+
+ * call.c (build_over_call): Use __builtin_memcpy for copying
+ CLASS_AS_BASE rather than funny casting.
+
+2004-06-30 Richard Henderson <rth@redhat.com>
+
+ * init.c (build_new_1): Fill in TYPE_DOMAIN, TYPE_SIZE and
+ TYPE_SIZE_UNIT of full_type.
+
+2004-06-30 Per Bothner <per@bothner.com>
+
+ Conditionally compile support for --enable-mapped_location.
+ * decl.c (pop_label): Handle (imperfectly) USE_MAPPED_LOCATION case.
+ * decl2.c: If USE_MAPPED_LOCATION, don't do some line number
+ adjustments - which I don't understand.
+ * error.c (dump_decl): Rename "<interrnal>" to "<built-in>".
+ * error.c: Use LOCATION_FILE and EXPR_LOCATION macros.
+ (print_instantiation_partial_context): Use expand_location.
+ * decl.c (duplicate_decl): Use new DECL_IS_BUILTIN macro.
+ * name-lookup.c: Likewise.
+ * lex.c (cxx_init): Likewise. Also use BUILTINS_LOCATION.
+ * name-lookup.c: Use input_line macro.
+ * parser.c (cp_lexer_get_preprocessor_token): Use UNKNOWN_LOCATION.
+ (cp_parser_statement): Rename locaal variable statement_locus to
+ statement_location and use SET_EXPR_LOCATION macro.
+ * pt.c: Handle USE_MAPPED_LOCATION case. Use new macros.
+ * tree.c (cp_walk_subtrees): Likewise.
+
+2004-06-29 Per Bothner <per@bothner.com>
+
+ * tree.c (build_min_nt, build_min, build_min_non_dep):
+ Don't set TREE_COMPLEXITY from input_line.
+
+2004-06-29 Paul Brook <paul@codesourcery.com>
+
+ * init.c: Include target.h.
+ (get_cookie_size): Remove and replace with target hook.
+ Update callers.
+ (build_new_1): Store the element size in the cookie.
+
+2004-06-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/16260
+ * parser.c (cp_parser_template_declaration_after_export): Disable
+ access checks here ...
+ (cp_parser_class_specifier): ... not here.
+
+2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (VAR_OR_FUNCTION_DECL_CHECK,
+ VAR_FUNCTION_OR_PARM_DECL_CHECK, RECORD_OR_UNION_TYPE_CHECK,
+ BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): Use appropriate
+ TREE_CHECK macro.
+
+2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (struct deferred_access): Move to ...
+ * semantics.c (struct deferred_access): ... here. Adjust.
+ (deferred_access_stack): Make a VEC(deferred_access),
+ (deferred_access_free_list): Remove.
+ (deferred_access_no_check): New.
+ (push_deferring_access_checks, resume_deferring_access_checks,
+ stop_deferring_access_checks, pop_deferring_access_checks,
+ get_deferred_access_checks, pop_to_parent_deferring_access_checks,
+ perform_deferred_access_checks, perform_or_defer_access_check): Adjust.
+
+2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/16174
+ * call.c (build_temp): Declare.
+ (check_constructor_callable): New.
+ (reference_binding): Only set CHECK_COPY_CONSTRUCTOR if not for
+ CONSTRUCTOR_CALLABLE.
+ (convert_like_real, initialize_reference): Use
+ check_constructor_callable.
+ * cp-tree.h (LOOKUP_CONSTRUCTOR_CALLABLE): New.
+ (LOOKUP_*): Renumber.
+
+2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * friend.c (add_friend): Only perform access checks when context
+ is a class.
+ * lex.c (cxx_make_type): Only create a binfo for aggregate types.
+ * parser.c (cp_parser_class_specifier): Disable access checks here
+ when parsing the body of a templated class.
+ * semantics.c (perform_or_defer_access_checks): Reorder to allow
+ NULL binfos when not checking access.
+
+2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ Use vector API for vbase list.
+ * cp-tree.h: Include vec.h
+ (DEF_VEC_P (tree)): New type.
+ (struct lang_type_class): Change vbase's member type.
+ (binfo_for_vbase): Declare.
+ * class.c (determine_primary_base, base_derived_from,
+ update_vtable_entry_for_fn, walk_subobject_offsets, end_of_class,
+ warn_about_ambiguous_bases, dfs_accumulate_vtbl_inits,
+ build_vtbl_initializer): Adjust.
+ * decl.c (xref_basetypes): Adjust, accumulate upper bound of
+ vbases.
+ * init.c (sort_mem_initializers, expand_member_init,
+ push_base_cleanups): Adjust.
+ * method.c (do_build_copy_constructor): Adjust.
+ * search.c (get_pure_virtuals, copied_binfo, original_binfo): Adjust.
+ (binfo_for_vbase): New.
+ * tree.c (copy_base_binfos): Adjust.
+
+2004-06-28 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_set_decl_spec_type): Fix thinko.
+
+2004-06-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/14123
+ * cxx-pretty-print.c (pp_cxx_ptr_operator): Properly put
+ paranthesis in case of pointers to array members.
+ * error.c (dump_type_prefix): Likewise.
+ (dump_type_suffix): Maybe issue a whitespace when printing
+ ARRAY_TYPE.
+
+2004-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16193
+ * parser.c (cp_parser_set_decl_spec_type): Refine test for
+ redefinition of built-in types.
+
+2004-06-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (pp_template_argument_list_start): Remove.
+ (pp_template_argument_list_end): Likewise.
+ (pp_separate_with_comma): Use pp_cxx_separate_with.
+ (reinit_global_formatting_buffer): Remove.
+ (pp_non_consecutive_character): Likewise.
+ (dump_scope): Use pp_cxx_colon_colon.
+ (dump_template_parameter): Use pp_cxx_identifier,
+ pp_cxx_tree_identifier and pp_cxx_whitespace.
+ (dump_templat_bindings): Replace use of pp_string with sequence
+ of pp_cxx_whitespace and pp_equal.
+ (dump_type): Use pp_cxx_identifier, pp_cxx_tree_identifier,
+ pp_cxx_colon_colon, pp_cxx_whitespace throughout. Don't set
+ padding here.
+ (dump_aggr_type): Use pp_cxx_identifier amd pp_cxx_tree_identifier.
+ (dump_type_prefix): Don't set padding. Use pp_cxx_whitespace,
+ pp_cxx_left_parent, pp_cxx_colon_colon and pp_cxx_star troughout.
+ (dump_type_suffix): Use pp_cxx_right_paren, pp_cxx_left_bracket,
+ pp_cxx_right_bracket, pp_cxx_identifier throughout,
+ (dump_decl): Likewise.
+ (dump_template_decl): Likewise.
+ (dump_function_decl): Likewise. Set padding as appropriate.
+ (dump_parameters): Use pp_cxx_left_paren, pp_cxx_identifier and
+ pp_cxx_right_paren.
+ (dump_exception_spec): Likewise.
+ (dump_function_name): Use pp_cxx_tree_identifier and
+ pp_cxx_identifier.
+ (dump_template_parms): Use pp_cxx_begin_template_argument_list and
+ pp_cxx_end_template_argument_list.
+ (dump_expr): Use pp_cxx_left_paren, pp_cxx_right_paren,
+ pp_cxx_colon_colon, pp_cxx_identifier, pp_cxx_tree_identifier and
+ pp_cxx_whitespace throughout.
+ (dump_binary_op): Use pp_cxx_whitespace, pp_cxx_left_paren and
+ pp_cxx_right_paren.
+ (dump_unary_op): Likewise.
+ (reinit_cxx_pp): New function.
+ (type_as_string); Use it.
+ (expr_as_string): Likewise.
+ (decl_as_string); Likewise.
+ (context_as_string): Likewise.
+ (lang_decl_name): Likewise.
+ (decl_to_string): Likewise.
+ (expr_to_string): Likewise.
+ (parm_to_string): Likewise.
+ (type_to_string): Likewise.
+ (args_to_string): Likewise.
+ (cv_to_string): Likewise.
+
+2004-06-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_cv_quals): New type.
+ (cp_declarator): Use it instead of "tree" as appropriate.
+ (grok_method_quals): Adjust prototype.
+ (grokclassfn): Likewise.
+ (do_friend): Likewise.
+ * decl.c (grokfndecl): Use cp_cv_quals, not tree.
+ (grokdeclarator): Likewise.
+ * decl2.c (grok_method_quals): Likewise.
+ (grokclassfn): Likewise.
+ * friend.c (do_friend): Likewise.
+ * method.c (implicitly_declare_fn): Adjust call to grokclassfn.
+ * parser.c (make_call_declarator): Use cp_cv_quals, not tree.
+ (make_pointer_declarator): Likewise.
+ (make_reference_declarator): Likewise.
+ (make_ptrmem_declarator): Likewise.
+ (cp_parser_ptr_operator): Likewise.
+ (cp_parser_cv_qualifier_seq_opt): Likewise.
+ (cp_parser_cv_qualifier_opt): Remove.
+ (cp_parser_new_declarator_opt): Adjust call to
+ cp_parser_ptr_operator.
+ (cp_parser_conversion_declaration_opt): Likewise.
+ (cp_parser_declarator): Use cp_cv_quals, not tree.
+ (cp_parser_direct_declarator): Likewise.
+
+2004-06-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * call.c, cp-tree.h, cxx-pretty-print.c, decl.c, decl2.c:
+ Rename DECL_STMT to DECL_EXPR.
+ * init.c, name-lookup.c, parser.c, pt.c, semantics.c: Likewise.
+ * cp-lang.c (LANG_HOOKS_SAFE_FROM_P): Deleted.
+ * tree.c (cp_walk_subtrees): Don't call c_walk_subtrees.
+
+2004-06-26 Jan Hubicka <jh@suse.cz>
+
+ PR C++/14865
+ * decl2.c (maybe_emit_vtables): Always import_export_vtable for the
+ reachability analysis.
+
+2004-06-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-mudflap.c (mflang_flush_calls): Fix thinkos resulting from
+ 2004-06-23 change.
+
+2004-06-25 Paul Brook <paul@codesourcery.com>
+
+ * decl2.c (get_guard): Call targetm.cxx.guard_type.
+ (get_guard_bits, get_guard_cond): Call targetm.cxx.guard_mask_bit.
+
+2004-06-24 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokdeclarator): Restore error messages about __thread.
+ * parser.c (cp_parser_decl_specifier_seq): Likewise.
+
+2004-06-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/16115
+ * decl.c (grokparms): Give the PARM_DECL reference type if the
+ parameter is passed by invisible reference.
+
+2004-06-24 Andreas Schwab <schwab@suse.de>
+
+ * cp-tree.h (enum cp_storage_class): Remove trailing comma.
+
+2004-06-23 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (cp/lex.o): Do not depend on cp/lex.h.
+ (cp/decl.o): Likewise.
+ (cp/decl2.o): Likewise.
+ (cp/pt.o): Likewise.
+ (cp/semantics.o): Likewise.
+ * config-lang.in (gtfiles): Do not reference cp/lex.h.
+ * class.c: Do not include lex.h.
+ (add_implicitly_declared_members): Do not use
+ adding_implicit_members.
+ (check_bases_and_members): Do not talk about grok_x_components.
+ * cp/cp-tree.h (adding_implicit_members): Remove.
+ (cp_storage_class): New type.
+ (cp_decl_spec): Likewise.
+ (cp_decl_specifier_seq): Likewise.
+ (cp_parameter_declarator): Use it for the decl_specifiers field.
+ (check_tag_decl): Adjust prototype.
+ (shadow_tag): Likewise.
+ (groktypename): Likewise.
+ (start_decl): Likewise.
+ (start_function): Likewise.
+ (start_method): Likewise.
+ (grok_x_components): Remove.
+ (grokfield): Adjust prototype.
+ (grokbitfield): Likewise.
+ (finish_member_class_template): Remove.
+ * decl.c: Do not include lex.h.
+ (adding_implicit_members): Do not define.
+ (check_tag_decl): Do not use trees to represent decl-specifiers.
+ (shadow_tag): Likewise.
+ (groktypename): Likewise.
+ (start_decl): Likewise.
+ (grokvardecl): Likewise.
+ (grokdeclarator): Likewise.
+ (grokparms): Likewise.
+ (start_function): Likewise.
+ (start_method): Likewise.
+ * decl.h (grokdeclarator): Adjust prototype.
+ * decl2.c: Do not include lex.h.
+ (grok_x_components): Remove.
+ (grokfield): Do not use trees to represent decl-specifiers.
+ (grokbitfield): Likewise.
+ * lex.c: Do not include lex.h.
+ * lex.h: Remove.
+ * parser.c: Include target.h.
+ (clear_decl_specs): New function.
+ (cp_parser_translation_unit): Do not use trees to represent
+ decl-specifiers.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_new_type_id): Likewise.
+ (cp_parser_condition): Likewise.
+ (cp_parser_simple_declaration): Likewise.
+ (cp_parser_decl_specifier_seq): Likewise.
+ (cp_parser_function_specifier_opt): Likewise.
+ (cp_parser_conversion_type_id): Likewise.
+ (cp_parser_template_parameter): Likewise.
+ (cp_parser_explicit_instantiation): Likewise.
+ (cp_parser_type_specifier): Likewise.
+ (cp_parser_simple_type_specifier): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_type_id): Likewise.
+ (cp_parser_type_specifier_seq): Likewise.
+ (cp_parser_parameter_declaration): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_exception_declaration): Likewise.
+ (cp_parser_function_definition_from_specifiers_and_declarator):
+ Likewise.
+ (cp_parser_single_declaration): Likewise.
+ (cp_parser_save_member_function_body): Likewise.
+ (cp_parser_friend_p): Likewise.
+ (cp_parser_set_storage_class): New function.
+ (cp_parser_set_decl_spec_type): Likewise.
+ * pt.c: Do not include lex.h.
+ * semantics.c: Likewise.
+ (finish_member_class_template): Remove.
+
+2004-06-23 Roger Sayle <roger@eyesopen.com>
+
+ * call.c (build_cxx_call): Don't call expand_tree_builtin. No
+ longer take both "args" and "convert_args" as arguments.
+ (build_op_delete_call): Update call to build_cxx_call.
+ (build_over_call): Likewise, update call to build_cxx_call.
+ * cp-tree.h (build_cxx_call): Update funtion prototype.
+ * typeck.c (build_function_call): Don't call expand_tree_builtin.
+ * rtti.c (throw_bad_cast): Update call to build_cxx_call.
+ (throw_bad_typeid): Likewise.
+ (build_dynamic_cast_1): Likewise.
+
+2004-06-22 Richard Henderson <rth@redhat.com>
+
+ * class.c (build_vfn_ref): Take a pointer not object. Build
+ an OBJ_TYPE_REF.
+ (cp_fold_obj_type_ref): New.
+ * call.c (build_over_call): Update build_vfn_ref call.
+ * cp-lang.c (LANG_HOOKS_FOLD_OBJ_TYPE_REF): New.
+ * cp-tree.h (cp_fold_obj_type_ref): Declare.
+
+2004-06-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/16112
+ * cp-gimplify.c (cp_gimplify_init_expr): Look through
+ CLEANUP_POINT_EXPR.
+
+2004-06-21 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (NEW_EXPR): Add a fourth slot.
+ * cp-tree.h (PARMLIST_ELLIPSIS_P): Remove.
+ (TREE_PARMLIST): Likewise.
+ (CALL_DECLARATOR_PARMS): Likewise.
+ (CALL_DECLARATOR_QUALS): Likewise.
+ (CALL_DECLARATOR_EXCEPTION_SPEC): Likewise.
+ (cp_declarator_kind): New type.
+ (cp_parameter_declarator): Likewise.
+ (cp_declarator): Likewise.
+ (cp_error_declarator): Likewise.
+ (no_parameters): Likewise.
+ (groktypename): Change prototype.
+ (start_decl): Likewise.
+ (start_handler_parms): Likewise.
+ (get_scope_of_declarator): Likewise.
+ (start_function): Likewise.
+ (start_preparsed_function): New function.
+ (start_function): Change prototype.
+ (start_method): Likewise.
+ (grokfield): Likewise.
+ (grokbitfield): Likewise.
+ (build_new): Likewise.
+ (make_pointer_declarator): Remove.
+ (make_reference_declarator): Likewise.
+ (make_call_declarator): Likewise.
+ (set_quals_and_spec): Likewise.
+ (process_template_parm): Change prototype.
+ (begin_function_definition): Remove.
+ (finish_parmlist): Remove.
+ * decl.c (groktypename): Do not use trees to represent
+ declarators.
+ (start_decl): Likewise.
+ (start_handler_parms): Remove.
+ (get_scope_of_declarator): Reimplement.
+ (grokdeclarator): Do not use trees to represent declarators.
+ (grokparms): Likewise.
+ (start_function): Likewise.
+ (start_method): Likewise.
+ (build_void_list_mode): Do not use TREE_PARMLIST.
+ * decl.h (grokdeclarator): Change prototype.
+ * decl2.c (grok_method_quals): Robustify.
+ (grok_x_components): Do not use trees to represent declarators.
+ (grokfield): Likewise.
+ (grokbitfield): Likewise.
+ (start_objects): Build FUNCTION_DECLs, not declarators.
+ (start_static_storage_duration_function): Likewise.
+ * init.c (build_new): Simplify.
+ * lex.c (make_pointer_declarator): Remove.
+ (make_reference_declarator): Likewise.
+ (make_call_declarator): Likewise.
+ (set_quals_and_spec): Likewise.
+ * method.c (use_thunk): Use start_preparsed_function.
+ (synthesize_method): Likewise.
+ (implicitly_declare_fn): Build FUNCTION_DECLs, not declarators.
+ * optimize.c (maybe_clone_body): Use start_preparsed_function.
+ * parser.c (cp_error_declarator): New variable.
+ (declarator_obstack): Likewise.
+ (alloc_declarator): New function.
+ (make_declarator): Likewise.
+ (make_id_declarator): Likewise.
+ (make_pointer_declarator): Likewise.
+ (make_reference_declarator): Likewise.
+ (make_ptrmem_declarator): Likewise.
+ (make_call_declarator): Likewise.
+ (make_array_declarator): Likewise.
+ (no_parameters): New variable.
+ (make_parameter_declarator): Likewise.
+ (cp_parser_check_for_definition_in_return_type): Do not use trees
+ to represent declarators.
+ (cp_parser_translation_unit): Likewise.
+ (cp_parser_new_expression): Likewise.
+ (cp_parser_new_type_id): Likewise.
+ (cp_parser_new_declarator_opt): Likewise.
+ (cp_parser_direct_new_declarator): Likewise.
+ (cp_parser_condition): Likewise.
+ (cp_parser_declaration_statement): Likewise.
+ (cp_parser_declaration): Likewise.
+ (cp_parser_conversion_type_id): Likewise.
+ (cp_parser_conversion_declarator_opt): Likewise.
+ (cp_parser_template_parameter_list): Likewise.
+ (cp_parser_template_parameter): Likewise.
+ (cp_parser_explicit_instantiation): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_declarator): Likewise.
+ (cp_parser_direct_declarator): Likewise.
+ (cp_parser_type_id): Likewise.
+ (cp_parser_parameter_declaration_clause): Likewise.
+ (cp_parser_parameter_declaration_list): Likewise.
+ (cp_parser_parameter_declaration): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_exception_declaration): Likewise.
+ (cp_parser_check_declarator_template_parameters): Likewise.
+ (cp_parser_function_definition_from_specifiers_and_declarator):
+ Likewise.
+ (cp_parser_save_member_function_body): Likewise.
+ * pt.c (process_template_parm): Add is_non_type parameter.
+ (convert_template_argument): Adjust call to groktypename.
+ (tsubst_call_declarator_parms): Remove use of TREE_PARMLIST.
+ (tsubst): Do not expect declarators.
+ (tsubst_copy_and_build): Adjust NEW_EXPR case to handle additional
+ argument.
+ (instantiate_decl): Use start_preparsed_function.
+ * semantics.c (begin_function_definition): Remove.
+ (finish_parmlist): Remove.
+ * cp-mudflap.c (mflang_flush_calls): Build FUNCTION_DECLs, not
+ declarators.
+
+2004-06-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * call.c (build_vfield_ref): Add new operand for COMPONENT_REF.
+ (build_new_method_call): Likewise.
+ * decl.c (local_variable_p_walkfn): Don't walk into types.
+ * decl2.c (grok_array_decl): Add new operands for ARRAY_REF.
+ (build_anon_union_vars): Add new operand for COMPONENT_REF.
+ * init.c (buld_new): Add new operand for ARRAY_REF.
+ * method.c (do_build_copy_constructor): New op for COMPONENT_REF.
+ (do_build_assign_ref): Likewise.
+ * parser.c (cp_parser_direct_new_declarator): Add new operands
+ for ARRAY_REF.
+ (cp_parser_direct_declarator): Likewise.
+ * pt.c (tsubst): Likewise.
+ (tsubst_copy, tsubst_copy_and_build): Likewise; also add new operand
+ for COMPONENT_REF.
+ * semantics.c (finish_non_static_data_member): Add new operand
+ for COMPONENT_REF.
+ * typeck.c (build_class_member_access_expr): Likewise.
+ (build_class_member_access_expr, finish_class_member_access_expr):
+ Likewise.
+ (build_ptrmemfunc_access_expr): Likewise.
+ (build_array_ref): Add new operands for ARRAY_REF.
+ * typeck2.c (split_nonconstant_init_1): Likewise; COMPONENT_REF too.
+ * tree.c (count_trees_r, no_linkage_helper): Don't walk in types.
+
+2004-06-21 Richard Henderson <rth@redhat.com>
+
+ * dump.c (cp_dump_tree): Don't use dump_next_stmt.
+ * parser.c (cp_parser_jump_statement): Update commentary.
+ * pt.c (tsubst_expr): Use RETURN_EXPR.
+ * semantics.c (finish_return_stmt): Likewise.
+ (finalize_nrv_r): Likewise.
+ * typeck.c, typeck2.c: Update file start commentary.
+
+2004-06-21 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (finish_expr_stmt): Call verify_sequence_points.
+
+2004-06-20 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (add_decl_stmt): Declare.
+ * pt.c (tsubst_copy): Abort for CLEANUP_POINT_EXPR.
+ * semantics.c (maybe_cleanup_point_expr): New.
+ (add_decl_stmt, finish_expr_stmt, finish_return_stmt,
+ finish_for_expr, finish_switch_cond): Use it.
+ (finalize_nrv_r): Don't build an EXPR_STMT. Don't frob TREE_CHAIN.
+
+2004-06-20 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.def (CLEANUP_STMT, IF_STMT): Move from c-common.def.
+ * cp-gimplify.c (gimplify_if_stmt): Move from c-gimplify.c.
+ (cp_gimplify_expr): Call it.
+ (gimplify_cleanup_stmt): Move from c-gimplify.c.
+ (cp_genericize): New.
+ * decl.c (finish_function): Call it.
+ * cp-tree.h (cp_stmt_codes): Add CLEANUP_STMT, IF_STMT.
+ (CLEANUP_BODY, CLEANUP_EXPR, CLEANUP_DECL): Move from c-common.h.
+ (IF_COND, THEN_CLAUSE, ELSE_CLAUSE): Likewise.
+ (cp_genericize): Declare.
+ * cxx-pretty-print.c (pp_cxx_statement): Add CLEANUP_STMT, IF_STMT.
+ * dump.c (cp_dump_tree): Likewise.
+ * semantics.c (push_cleanup): Move from c-semantics.c.
+
+2004-06-20 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-lang.c (has_c_linkage): Implement.
+
+ * cp-tree.h (set_mangled_name_for_decl): Don't prototype.
+ * decl.c (duplicate_decls): Use COPY_DECL_RTL.
+ (builtin_function_1): Don't call make_decl_rtl.
+ (build_cp_library_fn): Don't call set_mangled_name_for_decl.
+ (grokvardecl): Don't call mangle_decl.
+ * except.c (nothrow_libfn_p): Look at DECL_NAME, not
+ DECL_ASSEMBLER_NAME.
+ * method.c (set_mangled_name_for_decl): Delete.
+ * name-lookup.c (pushdecl): When a local extern shadows a
+ file-scope declaration of the same object, give both DECLs the
+ same DECL_UID.
+ * typeck.c (cxx_mark_addressable): Don't set TREE_ADDRESSABLE
+ on DECL_ASSEMBLER_NAME.
+
+2004-06-19 Richard Henderson <rth@redhat.com>
+
+ * cp-gimplify.c: Remove unnecessary prototypes.
+ (cp_gimplify_stmt): Merge into ...
+ (cp_gimplify_expr): ... here. Move to end of file. Handle
+ stmts_are_full_exprs_p frobbing.
+ * cp-tree.h (cp_gimplify_stmt): Remove.
+ * pt.c (tsubst_expr): Merge prep_stmt and unify.
+ * tree.c (init_tree): Don't set lang_gimplify_stmt.
+
+2004-06-18 Richard Henderson <rth@redhat.com>
+
+ PR c++/16034
+ * semantics.c (begin_cond): New.
+ (finish_cond): Rewrite to handle template DECL_STMTs specially.
+ Assume that non-template decls go land before the conditional.
+ (simplify_loop_decl_cond): Likewise.
+ (begin_if_stmt, finish_if_stmt_cond, begin_while_stmt,
+ finish_while_stmt_cond, finish_for_init_stmt, finish_for_cond,
+ begin_switch_stmt, finish_switch_cond): Update to match.
+
+2004-06-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/16015
+ * semantics.c (simplify_aggr_init_expr): Don't return the slot.
+ (finish_stmt_expr_expr): Update type after conversions.
+ (finish_stmt_expr): Wrap initializer in CLEANUP_POINT_EXPR.
+ Handle void initializer.
+ * tree.c (build_cplus_new): Make AGGR_INIT_EXPRs void.
+
+2004-06-17 Geoffrey Keating <geoffk@apple.com>
+
+ * class.c (build_clone): Don't call defer_fn, let mark_used do it.
+ * cp-tree.h (defer_fn): Delete.
+ * decl2.c (defer_fn): Delete.
+ (finish_file): Simplify deferred_fns loops; check that
+ only used inline functions get into deferred_fns.
+ (mark_used): Inline previous contents of defer_fn.
+
+2004-06-16 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (COMPOUND_STMT_TRY_BLOCK, COMPOUND_STMT_BODY_BLOCK): Kill.
+ (BIND_EXPR_TRY_BLOCK, BIND_EXPR_BODY_BLOCK): New.
+ * cxx-pretty-print.c (pp_cxx_function_definition): Move handling
+ of CTOR_INITIALIZER ...
+ (pp_cxx_statement): ... here.
+ * decl.c (begin_function_body): Don't set COMPOUND_STMT_BODY_BLOCK.
+ (finish_function): Use alloc_stmt_list to zap entire function.
+ * parser.c (cp_parser_compound_statement): Update commentary.
+ * pt.c (tsubst_expr): Use BIND_EXPR instead of COMPOUND_STMT.
+ * semantics.c (begin_compound_stmt, finish_compound_stmt): Likewise.
+ (finish_stmt_expr): Don't look through COMPOUND_STMT.
+
+2004-06-16 Geoffrey Keating <geoffk@apple.com>
+
+ * pt.c (mark_decl_instantiated): Don't call defer_fn.
+
+2004-06-16 Richard Henderson <rth@redhat.com>
+
+ * parser.c (cp_parser_labeled_statement): Update commentary.
+ * pt.c (tsubst_expr): Use CASE_LABEL_EXPR.
+ * tree.c (mark_local_for_remap_r): Likewise.
+
+2004-06-16 Richard Henderson <rth@redhat.com>
+
+ * parser.c (cp_parser_asm_definition): Update commentary.
+ * pt.c (tsubst_expr): Use ASM_EXPR.
+ * semantics.c (finish_asm_stmt): Likewise.
+
+2004-06-16 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_destructor_body): Use LABEL_EXPR.
+ * parser.c (cp_parser_statement): Update commentary.
+ * pt.c (tsubst_expr): Use LABEL_EXPR, GOTO_EXPR.
+ * semantics.c (finish_goto_stmt, finish_label_stmt): Likewise.
+ * tree.c (mark_local_for_remap_r): Likewise.
+
+2004-06-16 Richard Henderson <rth@redhat.com>
+
+ PR c++/16012
+ * semantics.c (begin_for_stmt, begin_for_stmt): Do put the init
+ statement in FOR_INIT_STMT for templates.
+
+2004-06-15 Richard Henderson <rth@redhat.com>
+
+ * call.c (initialize_reference): Don't build CLEANUP_STMT here.
+ * cp-gimplify.c (cp_gimplify_stmt): Remove next_p argument.
+ (genericize_try_block): Use gimplify_stmt.
+ (genericize_catch_block, genericize_eh_spec_block): Likewise.
+ (cp_gimplify_init_expr): Remove STMT_EXPR special case.
+ (gimplify_must_not_throw_expr): Update voidify_wrapper_expr call.
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P): Remove.
+ (cp_tree_chain_matters_p): Remove.
+ * cp-tree.h (COMPOUND_STMT_TRY_BLOCK): New.
+ (COMPOUND_STMT_BODY_BLOCK): New.
+ (STATEMENT_LIST_NO_SCOPE, STATEMENT_LIST_TRY_BLOCK): New.
+ (EXPR_STMT_STMT_EXPR_RESULT): New.
+ (building_stmt_tree): Check cur_stmt_list.
+ (tf_stmt_expr_cmpd, tf_stmt_expr_body): Remove.
+ (BCS_NO_SCOPE, BCS_TRY_BLOCK, BCS_FN_BODY): New.
+ * decl.c (poplevel): Use pop_stmt_list for minding cleanups.
+ (cp_finish_decl): Use push_cleanup.
+ (start_function, finish_function): Use statement lists.
+ (finish_stmt): Do nothing.
+ * except.c (begin_eh_spec_block): Use statement lists.
+ (check_handlers_1, check_handlers): Likewise.
+ * init.c (construct_virtual_base): Don't add extra compound stmts.
+ (build_vec_init): Likewise.
+ * name-lookup.c (maybe_push_cleanup_level): Use statement lists.
+ * name-lookup.h (struct cp_binding_level): Add statement_list.
+ * parser.c (cp_parser_statement): Take the STMT_EXPR node, not a bool.
+ (cp_parser_labeled_statement, cp_parser_expression_statement,
+ cp_parser_statement_seq_opt): Likewise.
+ (cp_parser_compound_statement): Likewise. Take bool for try block.
+ (cp_parser_selection_statement): Tidy if processing.
+ (cp_parser_already_scoped_statement): Rewrite to do what it says.
+ * pt.c (tsubst_copy): Move STMT_EXPR to tsubst_expr.
+ (tsubst_expr): Rewrite STMT_EXPR processing. Handle STATEMENT_LIST.
+ Mind COMPOUND_STMT_TRY_BLOCK, EXPR_STMT_STMT_EXPR_RESULT.
+ * semantics.c (do_poplevel, do_pushlevel): Use statement lists.
+ (finish_cond): New, rewritten from FINISH_COND.
+ (simplify_loop_decl_cond): New.
+ (finish_expr_stmt): Avoid nested EXPR_STMTs.
+ (begin_if_stmt, finish_if_stmt_cond, finish_then_clause,
+ begin_else_clause, finish_else_clause, finish_if_stmt,
+ begin_while_stmt, finish_while_stmt_cond, finish_while_stmt,
+ begin_do_stmt, finish_do_body, begin_for_stmt, finish_for_init_stmt,
+ finish_for_cond, finish_for_stmt, begin_switch_stmt,
+ finish_switch_cond, finish_switch_stmt, begin_try_block,
+ finish_try_block, finish_cleanup_try_block, finish_function_try_block,
+ finish_handler_sequence, finish_function_handler_sequence,
+ begin_handler, finish_handler_parms, finish_handler,
+ begin_stmt_expr, finish_stmt_expr_expr, finish_stmt_expr): Rewrite
+ using statement lists.
+ (begin_compound_stmt): Replace has_no_scope argument with flags.
+ Update all callers. Use statement lists.
+ (finish_compound_stmt): Likewise.
+ (finish_decl_cleanup, finish_eh_cleanup): Use push_cleanup.
+ (current_scope_stmt_stack): Remove.
+ (simplify_aggr_init_expr): Don't muck with TREE_CHAIN.
+ * typeck2.c (split_nonconstant_init_1, split_nonconstant_init):
+ Rewrite with statement lists.
+
+2004-06-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * parser.c: Change all assignments of c_lex_string_translate
+ to true and false to 1 and 0.
+ (cp_lexer_read_token): Convert type of the translated string.
+ (cp_parser_skip_to_closing_parentheses): Preserve original
+ value of c_lex_string_translate, and set it to -1 while
+ running.
+ (cp_parser_cache_group): Likewise.
+ (cp_parser_cache_group_1): Renamed.
+ (cp_parser_asm_operand_list): Remove redundant setting of
+ c_lex_string_translate.
+ (cp_parser_primary_expression) [CPP_STRING, CPP_WSTRING]:
+ Handle chained strings.
+
+2004-06-12 Andrew Pinski <apinski@apple.com>
+
+ PR c++/14639
+ Revert:
+ 2004-06-02 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * cp-tree.h: Fix typo.
+
+ * cp-tree.h: Include cgraph.h
+ (DECL_NEEDED_P): Use cgraph_*node on the decl instead of
+ TREE_SYMBOL_REFERENCED on the DECL_ASSEMBLER_NAME of the decl.
+
+2004-06-12 Jason Merrill <jason@redhat.com>
+
+ PR tree-optimization/14107
+ * decl.c (finish_function): Warn about no return in all functions.
+
+2004-06-15 Paolo Bonzini <bonzini@gnu.org>
+
+ * cp-tree.h (struct language_function): Remove cannot_inline.
+ * decl.c (save_function_data): cannot_inline is no more.
+ (cxx_push_function_context): Likewise.
+ * decl2.c (start_objects, start_static_storage_duration_function):
+ Reset DECL_INLINE, set DECL_UNINLINABLE.
+
+2004-06-14 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/15967
+ * search.c (lookup_field): Propagate the ambiguity list.
+ (lookup_fnfields): Likewise.
+
+2004-06-14 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/15947
+ * parser.c (cp_parser_template_name): Ctors/dtors never need a
+ template keyword to disambiguate.
+
+2004-06-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15096
+ * decl.c (grokdeclarator): Ignore pointer-to-members when
+ computing template depth.
+
+ PR c++/14930
+ * name-lookup.c (pushtag): Do not try to put class declarations in
+ explicit specialization scopes.
+
+2004-06-11 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * decl.c (grokdeclarator): Do not depend on C99's _Bool's behavior.
+
+2004-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15862
+ * name-lookup.c (unqualified_namespace_lookup): Do not ignore type
+ bindings for undeclared built-ins.
+
+2004-06-11 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * typeck2.c (abstract_virtual_errors): Reword diagnostics, make them
+ appear at the correct location.
+
+2004-06-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/15875
+ Revert:
+ 2004-06-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ * init.c (build_offset_ref): Build SCOPE_REF with non-null
+ TREE_TYPE for non-dependent names.
+ * pt.c (type_dependent_expression_p): Handle SCOPE_REF with
+ unknown_type_node as its TREE_TYPE.
+ * cxx-pretty_print.c (pp_cxx_unqualified_id): Handle BASELINK.
+ * error.c (dump_decl) <SCOPE_REF case>: Use pp_expression.
+ (dump_expr) <SCOPE_REF case>: Likewise.
+
+2004-06-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15227
+ * parser.c (cp_parser_direct_declarator): Robustify.
+
+ PR c++/15877
+ * pt.c (tsubst_copy): Use decl_constant_value on enumeration
+ constants in non-dependent contexts.
+
+ PR c++/14211
+ PR c++/15076
+ * typeck.c (build_static_cast): Wrap casts in NON_LVALUE_EXPR when
+ necessary.
+
+2004-06-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/14791
+ * decl.c (duplicate_decls): Handle fileptr_type_node arguments
+ specially.
+
+2004-06-09 Mark Mitchell <mark@codesourcery.com>
+
+ Revert:
+ PR c++/15815
+ 2004-06-07 Mark Mitchell <mark@codesourcery.com>
+ * lex.c (handle_pragma_interface): Deprecate.
+ (handle_pragma_implementation): Likewise.
+
+2004-06-09 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * g++spec.c (lang_specific_driver): Remove check for -lm
+ and -lmath when check it see if it was the math library.
+
+2004-06-08 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/7841
+ * parser.c (cp_parser_direct_declarator): Reject constructor named
+ as qualified template-id.
+
+2004-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15815
+ * lex.c (handle_pragma_interface): Deprecate.
+ (handle_pragma_implementation): Likewise.
+
+2004-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15766
+ * parser.c (cp_parser_iteration_statement): Fix typo in error
+ message.
+
+ PR c++/14777
+ * pt.c (tsubst_default_argument): Do not defer access checks
+ while substituting into the default argument.
+
+ PR c++/15554
+ * pt.c (tsubst_copy): Do not try to substitute for an enumeration
+ constant in a non-dependent context.
+
+ PR c++/15057
+ * except.c (build_throw): Ensure that temp_expr has been
+ initialized.
+
+2004-06-06 Roger Sayle <roger@eyesopen.com>
+
+ * cp/cp-tree.h (lvalue_or_else): Add function prototype.
+
+2004-06-06 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/15503
+ * parser.c (cp_parser_mem_initializer_id): Gracefully reject
+ 'typename', and accept 'template'.
+
+2004-06-03 Andrew Pinski <pinskia@physics.uc.edu>
+ Jan Hubicka <jh@suse.cz>
+
+ PR c++/14639
+ * method.c (use_think): Do not mark thunk as referenced.
+
+2004-06-03 Matt Austern <austern@apple.com>
+
+ PR c++/15428
+ * decl2.c (maybe_emit_vtables): If TARGET_WEAK_NOT_IN_ARCHIVE_TOC
+ is nonzero, and if we see a noninline definition of a key method,
+ make the vtables nonweak.
+
+2004-06-02 Matt Austern <austern@apple.com>
+
+ * cp-tree.h (instantiate_decl): new boolean parameter,
+ undefined_ok. Current behavior is equivalent to its being 0.
+ * decl2.c (mark_used): Add new argument when calling instantiate_decl
+ * pt.c (mark_decl_instantiated): Unconditionally make
+ instantiations explicit unconditionally
+ (do_decl_instantiation): Don't call SET_DECL_EXPLICIT_INSTANTIATION,
+ since mark_decl_instantiated now does it.
+ (instantiate_class_member): New. Instantiate a member of an
+ explicitly instantiated class template.
+ (do_type_instantiation): Explicitly instantiate members of an
+ explicitly instantiated class template.
+ (instantiate_decl): if undefined_ok is nonzero, and if we're
+ trying to explicitly instantiated a template with no definition,
+ change it to an implicit instantiation.
+ (instantiate_pending_templates): Add new argument to instantiate_decl.
+ * tree.c (cp_cannot_inline_tree_fn): Likewise.
+
+2004-06-02 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * cp-tree.h: Fix typo.
+
+ * cp-tree.h: Include cgraph.h
+ (DECL_NEEDED_P): Use cgraph_*node on the decl instead of
+ TREE_SYMBOL_REFERENCED on the DECL_ASSEMBLER_NAME of the decl.
+
+2004-06-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/15142
+ * call.c (call_builtin_trap): Remove type parm.
+ (convert_arg_to_ellipsis): Change a non-POD argument to integer type.
+ (build_x_va_arg): Dereference a null pointer for a non-POD argument.
+
+2004-06-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13092
+ * init.c (build_offset_ref): Build SCOPE_REF with non-null
+ TREE_TYPE for non-dependent names.
+ * pt.c (type_dependent_expression_p): Handle SCOPE_REF with
+ unknown_type_node as its TREE_TYPE.
+ * cxx-pretty_print.c (pp_cxx_unqualified_id): Handle BASELINK.
+ * error.c (dump_decl) <SCOPE_REF case>: Use pp_expression.
+ (dump_expr) <SCOPE_REF case>: Likewise.
+
+2004-06-01 Richard Henderson <rth@redhat.com>
+ Andrew Pinski <pinskia@physics.uc.edu>
+
+ * lex.c (reswords): Rename "__offsetof" to "__builtin_offsetof".
+ * parser.c (struct cp_parser): Remove in_offsetof.
+ (cp_parser_new): Don't set it.
+ (cp_parser_unary_expression): Don't check it.
+ (cp_parser_postfix_open_square_expression): Split out from ...
+ (cp_parser_postfix_expression): ... here.
+ (cp_parser_postfix_dot_deref_expression): Likewise.
+ (cp_parser_builtin_offsetof): New.
+ (cp_parser_primary_expression): Use it.
+
+2004-06-01 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14932
+ * parser.c (cp_parser_postfix_expression): Allow subscript
+ operator in offsetof.
+
+2004-05-31 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15701
+ * friend.c (add_friend): Do not try to perform access checks for
+ functions from dependent classes.
+
+2004-05-31 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.c (pp_cxx_colon_colon): Expor.
+ (pp_cxx_begin_template_argument_list): Turn into a function.
+ (pp_cxx_end_template_argument_list): Likewise.
+ (pp_cxx_separate_with): Define.
+ (pp_cxx_unqualified_id): Tidy.
+ (pp_cxx_primary_expression): Likewise.
+ (pp_cxx_postfix_expression): Likewise.
+ (pp_cxx_expression): Likewise.
+ (pp_cxx_simple_type_specifier): Likewise.
+ (pp_cxx_type_specifier_seq): Likewise.
+ (pp_cxx_parameter_declaration_clause): Likewise.
+ (pp_cxx_exception_specification): Likewise.
+ (pp_cxx_direct_declarator): Likewise.
+ (pp_cxx_type_id): Likewise.
+ * cxx-pretty-print.h (pp_cxx_whitespace): Export from
+ cxx-pretty-print.c.
+ (pp_cxx_left_paren): Likewise.
+ (pp_cxx_right_paren): Likewise.
+ (pp_cxx_left_brace): Likewise.
+ (pp_cxx_right_brace): Likewise.
+ (pp_cxx_left_bracket): Likewise.
+ (pp_cxx_right_bracket): Likewise.
+ (pp_cxx_dot): Likewise.
+ (pp_cxx_identifier): Likewise.
+ (pp_cxx_tree_identifier): Likewise.
+ (pp_cxx_ampersand): New macro.
+ (pp_cxx_star): Likewise.
+ (pp_cxx_arrow): Likewise.
+ (pp_cxx_semicolon): Likewise.
+ (pp_cxx_complement): Likewise.
+ (pp_cxx_begin_template_argument_list): Declaree.
+ (pp_cxx_end_template_argument_list): Likewise.
+ (pp_cxx_colon_colon): likewise.
+
+2004-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * parser.c (cp_parser_simple_type_specifier): Explicitly test
+ against NULL_TREE.
+
+2004-05-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c, class.c, cp-tree.def, decl2.c, name-lookup.c, pt.c,
+ typeck.c: Fix comment formatting.
+
+2004-05-30 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * cp-lang.c (cp_expand_decl): Remove.
+ (LANG_HOOKS_EXPAND_DECL): Use c_expand_decl.
+
+2004-05-30 Andreas Jaeger <aj@suse.de>
+
+ * lang-specs.h: Add missing initializers for .ii.
+
+2004-05-28 Aldy Hernandez <aldyh@redhat.com>
+
+ * decl.c (cp_make_fname_decl): Free return value from
+ fname_as_string.
+
+2004-05-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15083
+ * decl2.c (delete_sanity): Set TREE_SIDE_EFFECTS on a DELETE_EXPR,
+ even in a templat.e
+ * init.c (build_new): Likewise.
+
+ PR c++/15640
+ * name-lookup.c (arg_assoc): Robustify.
+
+ PR c++/15471
+ * typeck.c (unary_complex_lvalue): Use context_for_name_lookup
+ when determining the scope to use for a pointer to member.
+ (lookup_anon_field): Give it external linkage.
+ * cp-tree.h (lookup_anon_field): Declare it.
+ * expr.c (cplus_expand_constant): Use it.
+
+2004-05-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14668
+ * parser.c (cp_parser_simple_type_specifier): Call
+ maybe_note_name_used_in_class.
+
+2004-05-28 Tom Marshall <tmarshall@real.com>
+
+ PR c++/15214
+ * class.c (finish_struct_1): Warn only if the dtor is non-private or
+ the class has friends.
+
+2004-05-27 Adam Nemet <anemet@lnxw.com>
+
+ PR c++/12883
+ * decl.c (complete_array_type): Set TYPE_NEEDS_CONSTRUCTING and
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR based on the underlying type.
+
+2004-05-24 Geoffrey Keating <geoffk@apple.com>
+
+ * method.c (implicitly_declare_fn): Don't call defer_fn; abort
+ if it might be needed.
+ * pt.c (mark_decl_instantiated): Only call defer_fn if
+ the function actually needs processing in finish_file.
+ * decl2.c (finish_file): Add check that elements in
+ deferred_fns_used are really needed there. Remove unnecessary
+ test of DECL_SAVED_TREE.
+
+2004-05-23 Paolo Bonzini <bonzini@gnu.org>
+
+ * Make-lang.in: No need to specify $(LIBCPP).
+
+2004-05-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15044
+ * parser.c (cp_parser_class_head): Robustify.
+
+ PR c++/15317
+ * parser.c (cp_parser_decl_specifier_seq): Correct error in
+ comment.
+ (cp_parser_constructor_declarator_p): Treat attributes
+ as decl-specifiers.
+
+ PR c++/15329
+ * typeck.c (build_unary_op): Do not attempt to resolve casts to
+ base classes in templates.
+
+2004-05-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15165
+ * pt.c (instantiate_template): Robustify.
+
+2004-05-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15025
+ * decl.c (xref_tag): Issue errors about redeclaring template
+ classes as non-template classes.
+
+2004-05-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14821
+ * name-lookup.c (supplement_binding): Allow redefinitions of
+ namespace aliases.
+
+ PR c++/14883
+ * parser.c (cp_parser_template_argument): Robustify.
+
+2004-05-23 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * class.c (alter_access): Use %E format specifier to print an
+ identifier node. Avoid looking at the IDENTIFIER_POINTER.
+ (push_lang_context): Likewise.
+ * decl.c (lookup_label): Likewise.
+ (grokdeclarator): Likewise.
+ * parser.c (cp_parser_check_for_invalid_template_id): Likewise.
+ * pt.c (do_type_instantiation): Likewise.
+ * tree.c (handle_java_interface_attribute): Likewise.
+ (handle_com_interface_attribute): Likewise.
+ (handle_init_priority_attribute): Likewise.
+
+2004-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15285
+ PR c++/15299
+ * pt.c (build_non_dependent_expr): Expand the set of tree nodes
+ recognized as overloaded functions.
+
+2004-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15507
+ * class.c (layout_nonempty_base_or_field): Do not try to avoid
+ layout conflicts for unions.
+
+ PR c++/15542
+ * typeck.c (build_x_unary_op): Instantiate template class
+ specializations before looking for "operator &".
+
+ PR c++/15427
+ * typeck.c (complete_type): Layout non-dependent array types, even
+ in templates.
+
+ PR c++/15287
+ * typeck.c (build_unary_op): Do not optimize "&x[y]" when in a
+ template.
+
+2004-05-22 Roger Sayle <roger@eyesopen.com>
+
+ * name-lookup.c (check_for_out_of_scope_variable): Avoid ICE by
+ returning when TREE_TYPE is error_mark_node.
+ * typeck.c (require_complete_type): Return error_mark_node if
+ value's type is an error_mark_node.
+
+2004-05-20 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * optimize.c (calls_setjmp_r): Remove.
+ (calls_setjmp_p): Remove.
+ * cp-tree.c (calls_setjmp_p): Remove.
+ * decl.c (finish_function): Do not call calls_setjmp_p.
+
+2004-05-18 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Use mark_decl_referenced.
+ * decl2.c (maybe_make_one_only): Likewise.
+ * method.c (use_thunk): Likewise.
+
+2004-05-18 Jason Merrill <jason@redhat.com>
+
+ * class.c (build_base_path): Tidy a bit.
+
+2004-05-14 Geoffrey Keating <geoffk@apple.com>
+
+ * name-lookup.c (struct scope_binding): New.
+ (EMPTY_SCOPE_BINDING): New.
+ (lookup_using_namespace): Take a scope_binding instead of a
+ cxx_binding.
+ (qualified_lookup_using_namespace): Likewise.
+ (cxx_binding_clear): Delete.
+ (do_nonmember_using_decl): Use a scope_binding instead of a
+ cxx_binding.
+ (lookup_tag): Don't call select_decl.
+ (ambiguous_decl): Don't return anything (and change callers to match).
+ Take a scope_binding as the second parameter.
+ (lookup_namespace_name): Use a scope_binding instead of a
+ cxx_binding.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_qualified_name): Likewise.
+ (select_decl): Take a scope_binding instead of a cxx_binding.
+ Use macros rather than hand-coding tests for type-ness.
+
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ * cp-gimplify.c: Rename from cp-simplify.c.
+ * Make-lang.in, optimize.c: Update.
+
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ Merge from tree-ssa-20020619-branch. See
+ ChangeLog.tree-ssa for details.
+
+ * Make-lang.in, call.c, class.c, cp-lang.c, cp-tree.def,
+ cp-tree.h, cvt.c, decl.c, decl2.c, error.c, except.c,
+ expr.c, init.c, name-lookup.h, optimize.c, parser.c,
+ pt.c, rtti.c, semantics.c, tree.c, typeck.c, typeck2.c:
+ Merged.
+ * cp-mudflap.c: New file.
+ * cp-simplify.c:: New file.
+
+2004-05-03 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14389
+ * decl2.c (check_classfn): For member templates, compare also the
+ template parameters to match the declaration.
+ * cp-tree.h: Adjust declaration of check_classfn.
+ * decl.c (start_decl, grokfndecl): Adjust callers of check_classfn.
+ * friend.c (do_friend): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+
+2004-05-01 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (reshape_init): Do not apply TYPE_DOMAIN to a VECTOR_TYPE.
+ Instead, dig into the representation type to find the array bound.
+
+2004-04-30 Jason Merrill <jason@redhat.com>
+
+ Refer to base members using COMPONENT_REFs where possible.
+ * class.c (build_simple_base_path): New fn.
+ (build_base_path): Use it for non-virtual base references.
+ (layout_class_type): Change base fields to their real type
+ after layout is done.
+ * cp-tree.h (IS_FAKE_BASE_TYPE): New macro.
+ * cp-lang.c (cxx_get_alias_set): Use it.
+
+2004-04-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * class.c, cp-tree.h, decl.c, decl2.c, pt.c, rtti.c: Fix
+ comment typos.
+
+2004-04-23 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/15064
+ * parser.c (cp_parser_postfix_expression): typeid operator cannot be
+ used in integral constant expressions.
+
+2004-04-22 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (build_aggr_init): Fix accidental use of C99 construct in
+ previous change.
+
+ * class.c (initialize_array): Don't set TREE_HAS_CONSTRUCTOR on
+ braced initializer.
+ * cp-tree.h (BRACE_ENCLOSED_INITIALIZER_P): New macro.
+ * decl.c (reshape_init): Use it.
+ * init.c (perform_member_init): Remove redundant condition.
+ (build_aggr_init): Adjust to handle brace-enclosed initializers
+ correctly.
+ (expand_default_init): Use BRACE_ENCLOSED_INITIALIZER_P.
+
+ * parser.c (cp_parser_initializer_clause): Do not set
+ TREE_HAS_CONSTRUCTOR on the initializer.
+ * rtti.c (tinfo_base_init): Likewise.
+ (generic_initializer): Likewise.
+ (ptr_initializer): Likewise.
+ (ptm_initializer): Likewise.
+ (class_initializer): Likewise.
+ (get_pseudo_ti_init): Likewise.
+ * typeck2.c (digest_init): Use BRACE_ENCLOSED_INITIALIZER_P.
+
+2004-04-22 Alan Modra <amodra@bigpond.net.au>
+
+ * name-lookup.c (anonymous_namespace_name): Make static.
+
+2004-04-19 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/14531
+ * class.c (build_base_path): Call fold whilst building the NULL
+ pointer check expression trees.
+
+2004-04-15 Bryce McKinlay <mckinlay@redhat.com>
+
+ * init.c (build_new_1): Don't use type size argument for Java
+ _Jv_AllocObject call.
+
+2004-04-09 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * method.c (make_alias_for_thunk): Remove preprocessor guard on
+ declaration and definition.
+
+2004-04-08 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/14808
+ * method.c (use_thunk): Test TARGET_USE_LOCAL_THUNK_ALIAS_P rather
+ than ASM_OUTPUT_DEF.
+
+2004-04-08 Jakub Jelinek <jakub@redhat.com>
+
+ * decl2.c (mark_used): Don't segfault if cfun != NULL but
+ current_function_decl == NULL.
+
+2004-04-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3518
+ * pt.c (check_cv_quals_for_unify): Ignore bogus CV quals at outer
+ level.
+
+2004-04-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * init.c (decl_constant_value): Don't look at DECL_INITIAL
+ of PARM_DECL.
+ * tree.c (bot_manip, build_min): Don't look at TREE_CONSTANT
+ or TREE_SIDE_EFFECTS of a type.
+
+2004-04-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/14007
+ * pt.c (check_cv_quals_for_unify): Correct logic for disallowed
+ cv-qualifier unification.
+ * tree.c (cp_build_qualified_type_real): Renable DR295 logic.
+
+2004-04-02 Jan Hubicka <jh@suse.cz>
+
+ * cp-lang. (LANG_HOOKS_UPDATE_DECL_AFTER_SAVING): Define.
+ * cp-tree.h (cp_update_decl_after_saving): Declare.
+ * tree.c (cp_update_decl_after_saving): Define.
+
+2004-04-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14803
+ * typeck.c (get_delta_difference): Call fold before returning the
+ value.
+
+2004-04-01 Richard Henderson <rth@redhat.com>
+
+ PR c++/14804
+ * decl.c (cp_finish_decl): Preserve TREE_READONLY more often.
+ * typeck2.c (split_nonconstant_init): Clear TREE_READONLY.
+
+2004-04-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14810
+ * name-lookup.c (maybe_push_cleanup_level): Robustify.
+
+2004-04-01 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (VTT_TOP_LEVEL_P): Use unsigned_flag directly.
+
+2004-03-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * call.c (joust): Use TYPE_UNSIGNED, not TREE_UNSIGNED.
+ * class.c (check_bitfield_decl): Likewise.
+ * cvt.c (type_promotes_to): Likewise.
+ * decl.c (finish_enum): Likewise.
+ * mangle.c (write_builtin_type): Likewise.
+ * semantics.c (finish_switch_cond, finish_unary_op_expr): Likewise.
+ * typeck.c (type_after_usual_arithmetic_conversions): Likewise.
+ (build_binary_op): Likewise.
+
+2004-03-31 Jan Hubicka <jh@suse.cz>
+
+ * tree.h (optimize_function): Kill prototype.
+ * optimize.c (dump_function, optimize_function, dump_finction): Kill.
+ * semantics.c (expand_body): Kill.
+
+2004-03-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14724
+ * decl.c (start_decl_1): Do not decide whether or not to create a
+ new cleanup level until after the type has been completed.
+
+ PR c++/14763
+ * pt.c (tsubst_default_argument): Clear current_function_decl.
+
+2004-03-30 Zack Weinberg <zack@codesourcery.com>
+
+ * name-lookup.c, parser.c: Use new shorter form of GTY markers.
+
+2004-03-29 Zack Weinberg <zack@codesourcery.com>
+
+ * error.c (dump_function_name): If T's DECL_LANG_SPECIFIC
+ is null, just print the literal name and return.
+
+2004-03-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cxx-pretty-print.c: Fix comment typos.
+
+2004-03-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cxx-pretty-print.c, cxx-pretty-print.h, decl.h, friend.c:
+ Update copyright.
+
+2004-03-23 Ziemowit Laski <zlaski@apple.com>
+
+ * Make-lang.in (cp/mangle.o): Depend on $(TARGET_H).
+ * mangle.c (write_type): Add call to 'mangle_fundamental_type'
+ target hook.
+
+2004-03-23 Zack Weinberg <zack@codesourcery.com>
+
+ PR 12267, 12391, 12560, 13129, 14114, 14133
+ * cp-lang.c (c_reset_state): Delete.
+ (push_file_scope, pop_file_scope): New stubs.
+ * parser.c (c_parse_file): Call sorry() here if called more than once.
+
+2004-03-23 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * typeck.c (build_c_cast): Only look at TREE_CONSTANT_OVERFLOW
+ for INTEGER_CST.
+
+2004-03-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.c (pp_cxx_parameter_declaration_clause): Declare.
+
+2004-03-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (enum pad): Remove.
+ (dump_qualifiers): Likewise.
+ (dump_type): Replace dump_qualifiers with pp_cxx_cv_qualifier_seq.
+ (dump_aggr_type): Likewise.
+ (dump_type_suffix): Likewise.
+ (dump_simple_decl): Likewise.
+ (dump_function_decl): Likewise.
+ (cv_to_string): Likewise.
+ (dump_type_prefix): Likewise. Adjust return void.
+ * cxx-pretty-print.c (pp_cxx_cv_qualifier_seq): Move to
+ cxx_pretty_print.h.
+ (pp_cxx_template_keyword_if_needed): Document.
+ (pp_cxx_qualified_id): Document case FUNCTION_DECL. Tidy.
+ (pp_cxx_expression): Handle NON_DEPENDENT_EXPR and
+ MUST_NOT_THROW_EXPR.
+
+2004-03-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14616
+ * decl.c (cp_finish_decl): Compute the size of arrays declared in
+ templates, if their type is non-dependent.
+
+2004-03-19 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_op_delete_call): Do not forget the placement
+ arguments when iterating through mutiple delete operators.
+
+ * cp-tree.h (svaed_scope): Remove last_parms.
+ (NEW_DELETE_OPNAME_P): New macro.
+ (last_function_parms): Remove.
+ (do_friend): Adjust prototype.
+ * decl.c (grokparms): Return the PARM_DECLs directly, rather than
+ using last_function_parms.
+ (grokfndecl): Take the PARM_DECLs as an argument, rather than
+ using last_function_parms.
+ (grokdeclarator): Adjust accordingly. Do not form METHOD_TYPEs
+ for class-specific operator new and operator delete.
+ (grok_op_properties): Do not look for allocation functions with
+ METHOD_TYPEs.
+ (start_function): Use DECL_ARGUMENTS instead of
+ last_function_parms.
+ * decl.h (last_function_parms): Do not declare.
+ * decl2.c (grokclassfn): Do not use last_function_parms.
+ * friend.c (do_friend): Remove parmdecls parameter.
+ * name-lookup.c (push_to_top_level): Do not save last_function_parms.
+ (pop_from_top_level): Do not restore it.
+ * pt.c (check_explicit_specialization): Do not adjust
+ last_function_parms.
+
+ * name-lookup.c (do_local_using_decl): Create a local binding for
+ types brought in via using declarations.
+
+ * name-lookup.c (lookup_arg_dependent): Handle block-scope
+ function declarations correctly.
+
+ * semantics.c (finish_id_expression): Correct handling of
+ conversion operators to dependent types.
+
+ * typeck.c (lookup_destructor): Allow the use of destructors from
+ base classes.
+
+2004-03-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * cxx-pretty-print.c (pp_cxx_unqualified_id): Use
+ TEMPLATE_TYPE_PARM_INDEX instead of TYPE_FIELDS.
+ * search.c (dfs_unuse_fields): Add two more TREE_CODES that mean
+ the field is named TEMPLATE_TYPE_PARM_INDEX.
+
+2004-03-19 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14545
+ * parser.c (cp_parser_functional_cast): A cast to anything
+ but integral or enumaration type is not an integral constant
+ expression.
+ * pt.c (value_dependent_expression_p): Handle cast expressions
+ without operands (such as "int()").
+
+2004-03-18 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (finish_pseudo_destructor_expr): Allow differing
+ cv-qualification between the type named by the
+ pseudo-destructor-name and the object-type.
+
+ * search.c (accessible_base_p): Handle non-proper bases.
+
+ * name-lookup.c (do_nonmember_using_decl): If a using declaration
+ refers to a single overloaded function, set the type of the
+ function.
+ * tree.c (lvalue_type): Simplify.
+ * typeck.c (type_unknown_p): Do not assume all OVERLOADs have an
+ unknown type.
+ (build_unary_op): Handle OVERLOADs with known types.
+
+ * decl.c (duplicate_decls): Do not destroy DECL_ARGUMENTS for
+ function templates.
+
+ * parser.c (cp_parser_postfix_expression): Handle the use of
+ "typename" in non-dependent contexts. Convert appropriately when
+ when using a qualified name after "->" or ".".
+
+ * call.c (conditional_conversion): Honor the requirement that some
+ conversions refer to the original object.
+
+2004-03-18 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_conditional_expr): Do not call force_rvalue for
+ operands of void_type when the conditional expression itself has
+ void type.
+ * name-lookup.c (pushdecl): Don't consider a declaration of a
+ function named "main" to be an overload of a type named "main".
+ * parser.c (cp_parser_template_name): Perform name lookup when the
+ template name is proceeded by "template" if the qualifying scope
+ is non-dependent.
+ * typeck.c (composite_pointer_type_r): Correctly handle
+ pointer-to-member types.
+ (build_const_cast): Likewise.
+
+2004-03-18 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * cp-tree.def (TEMPLATE_TYPE_PARM, TYPEOF_TYPE): Update comments.
+ * cp-tree.h (NEW_EXPR_USE_GLOBAL, DELETE_EXPR_USE_GLOBAL): Add check.
+ (DELETE_EXPR_USE_VEC, COMPOUND_EXPR_OVERLOADED): Likewise.
+ (KOENIG_LOOKUP_P, PTRMEM_OK_P, TEMPLATE_TYPE_PARM_INDEX): Likewise.
+ (TYPENAME_TYPE_FULLNAME): Add check and use type.values.
+ (TYPEOF_TYPE_EXPR): New macro.
+ * class.c (finish_struct_bits): Use TYPE_VFIELD and TYPE_METHODS.
+ * error.c (dump_type): Use TYPEOF_TYPE_EXPR.
+ * pt.c (tsubst): Likewise.
+ * semantics.c (finish_typeof): Likewise.
+ * search.c (dfs_unuse_fields): Handle TYPENAME_TYPE, TYPEOF_TYPE,
+ and TEMPLATE_TYPE_PARM.
+ * typeck.c (comptypes): Use TYPE_ORIG_SIZE_TYPE, not TYPE_DOMAIN.
+ (build_array_ref): Use TYPE_DOMAIN, not TYPE_VALUES.
+
+2004-03-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14586
+ * cp-tree.h (build_new_op): Change prototype.
+ (build_x_binary_op): Likewise.
+ * call.c (build_new_op): Add overloaded_p parameter.
+ * decl2.c (grok_array_decl): Adjust call to build_new_op.
+ * parser.c (cp_parser_binary_expression): Note that uses of
+ overloaded operators prevents an expression from being considered
+ an integral constant.
+ * pt.c (tsubst_copy_and_build): Adjust calls to build_new_op and/or
+ build_x_binary_op.
+ * semantics.c (finish_call_expr): Likewise.
+ * typeck.c (rationalize_conditional_expr): Likewise.
+ (build_x_indirect_ref): Likewise.
+ (build_x_binary_op): Likewise.
+ (build_x_unary_op): Likewise.
+ (build_x_compound_expr): Likewise.
+ (build_modify_expr): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2004-03-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-lang.c, ptree.c: Update copyright.
+
+2004-03-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14550
+ * parser.c (cp_parser_non_integral_constant_expression): Encode
+ more of the idiom that surrounded calls to this function within
+ the function itself
+ (cp_parser_primary_expression): Adjust accordingly.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_assignment_expression): Likewise.
+ (cp_parser_expression): Likewise.
+ (cp_parser_new_expression): Note that new-expressions are not
+ allowed in integral constant expressions.
+ (cp_parser_delete_expression): Likewise.
+
+2004-03-12 Matt Austern <austern@apple.com>
+
+ * decl2.c (maybe_make_one_only): Look at
+ TARGET_EXPLICIT_INSTANTIATION_ONE_ONLY when deciding whether
+ to make an explicit instantiation weak.
+ * method.c (use_thunk): Make sure we call comdat_linkage
+ when appropriate.
+ * pt.c (do_type_instantiation): On systems where weak symbols
+ don't go in a static archive's TOC, explicit instantiation of a
+ class must imply *explicit* instantiation of its memeber.
+
+2004-03-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c, cp-tree.h, pt.c: Fix comment typos.
+
+2004-03-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14510
+ * decl.c (xref_tag): Disregard non-type declarations when
+ looking up a tagged type.
+
+2004-03-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/14397
+ * call.c (convert_like_real): Build a const qualified temporary,
+ when testing ctor access.
+
+2004-03-09 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (initialize_reference): Fix typo.
+
+2004-03-09 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14409
+ * pt.c (determine_specialization): For member templates, match also
+ constness.
+
+ PR c++/14448
+ * parser.c (cp_parser_initializer_clause): Fold initializer if it is
+ non-dependent.
+ * pt.c (tsubst_copy_and_build): Handle NOP_EXPRs.
+
+2004-03-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14230
+ * call.c (initialize_reference): Handle initializers that are
+ class-member access expressions applies to rvalues.
+
+2004-03-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14432
+ * name-lookup.c (supplement_binding): Ignore functions that are
+ marked DECL_ANTICIPATED.
+
+2004-03-08 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14401
+ * class.c (check_field_decls): Complain about non-static data
+ members of reference type in unions. Propagate
+ CLASSTYPE_REF_FIELDS_NEED_INIT and
+ CLASSTYPE_READONLY_FIELDS_NEED_INIT from the types of non-static
+ data members.
+ * init.c (perform_member_init): Complain about mbmers with const
+ type that are not explicitly initialized.
+
+2004-03-08 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (check_methods): Don't use IDENTIFIER_ERROR_LOCUS.
+ * cp-tree.h (DECL_INVALID_OVERRIDER_P): New macro.
+ (lang_identifier): Remove implicit_decl and error_locus.
+ (IDENTIFIER_IMPLICIT_DECL): Remove.
+ (SET_IDENTIFIER_IMPLICTI_DECL): Likewise.
+ (IDENTIFIER_ERROR_LOCUS): Likewise.
+ (SET_IDENTIFIER_ERROR_LOCUS): Likewise.
+ (TYPE_ASSEMBLER_NAME_STRING): Likewise.
+ (TYPE_ASSEMBLER_NAME_LENGTH): Likewise.
+ (implicitly_declare): Remove.
+ * decl.c (warn_extern_redeclared_static): Remove check of
+ IDENTIFIER_IMPLICIT_DECL.
+ (duplicate_decls): Don't check IDENTIFIER_ERROR_LOCUS.
+ (implicitly_declare): Remove.
+ (grok_ctor_properties): Don't set IDENTIFIER_ERROR_LOCUS.
+ (start_function): Don't check IDENTIFIER_IMPLICIT_DECL.
+ (start_method): Don't check IDENTIFIER_ERROR_LOCUS.
+ * lex.c (unqualified_name_lookup_error): Create a dummy VAR_DECL
+ in the innermost scope, rather than at namespace scope.
+ * name-lookup.c (push_local_binding): Give it external linkage.
+ (pushdecl): Remove dead code.
+ * name-lookup.h (push_local_binding): Declare it.
+ * ptree.c (cxx_print_identifier): Don't print
+ IDENTIFIER_IMPLICIT_DECL or IDENTIFIER_ERROR_LOCUS.
+ * search.c (check_final_overrider): Use DECL_INVALID_OVERRIDER_P,
+ not IDENTIFIER_ERROR_LOCUS.
+ * typeck.c (build_function_call): Remove dead code.
+
+2004-03-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/13170
+ * decl.c (xref_tag): Remove attribute handling.
+ * cp-tree.h: Adjust prototype.
+ * decl.c, parser.c, rtti.c: Adjust callers.
+ * parser.c (cp_parser_class_head): Pass back attributes in the
+ class head.
+ (cp_parser_class_specifier): Adjust.
+
+2004-03-08 Matt Austern <austern@apple.com>
+
+ PR debug/14079
+ * name-lookup.c (add_decl_to_level): Add extern variables, as well
+ as static, to static_decls array.
+
+2004-03-05 Jason Merrill <jason@redhat.com>
+
+ * tree.c (list_hash_pieces): s/TYPE_HASH/TREE_HASH/.
+
+2004-03-04 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (grokfndecl): Update old incorrect comment.
+ (grokvardecl): Diagnose C++ variables of type with no linkage.
+
+2004-03-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14369
+ * pt.c (build_non_dependent_expr): Do not create a
+ NON_DEPENDENT_EXPR for a THROW_EXPR.
+
+2004-03-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/14369
+ * error.c (dump_expr): Handle THROW_EXPR.
+
+2004-03-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14360
+ * parser.c (cp_parser_postfix_expression): Do not perform Koenig
+ lookup if ordinary name-lookup finds a non-function.
+ * pt.c (tsubst_copy_and_build): Likewise.
+
+ PR c++/14361
+ * parser.c (cp_parser_late_parsing_default_args): Check that there
+ are no extra tokens after the end of the default-argument
+ expression.
+
+2004-03-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14324
+ * lex.c (retrofit_lang_decl): Treat entities with no linkage as
+ having C++ linkage for name-mangling purposes.
+
+ PR c++/14260
+ * parser.c (cp_parser_direct_declarator): Recognize constructor
+ declarators that use a template-id to name the class being
+ constructed.
+
+ PR c++/14337
+ * pt.c (tsubst_qualified_id): Handle dependent qualifying scopes.
+ (tsubst_expr): Do not call tsubst_copy, even when
+ processing_template_decl.
+
+2004-03-01 Jeff Law <law@redhat.com>
+
+ * init.c (build_vec_delete_1): Convert 2nd argument to NE_EXPR to
+ the proper type.
+
+2004-02-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14138
+ * name-lookup.h (push_scope): Change prototype.
+ * name-lookup.c (push_scope): Do not reenter the current class
+ scope.
+ * decl.c (grokfndecl): Check return code from push_scope before
+ calling pop_scope.
+ * decl2.c (check_classfn): Likewise.
+ * parser.c (cp_parser_conversion_function_id): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_direct_declarator): Likewise.
+ (cp_parser_class_specifier): Likewise.
+ (cp_parser_class_head): Likewise.
+ (cp_parser_lookup_name): Likewise.
+ (cp_parser_constructor_declarator_p): Likewise.
+ * pt.c (instantiate_class_template): Likewise.
+ (resolve_typename_type): Likewise.
+
+2004-02-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14267
+ * typeck.c (build_modify_expr): Remove more of the cast-as-lvalue
+ extension.
+
+ PR debug/12103
+ * class.c (update_vtable_entry_for_fn): Do not go through
+ covariance machinery if the type returned by an overrider is the
+ same as the original.
+
+2004-02-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix a comment typo.
+
+2004-02-27 Ziemowit Laski <zlaski@apple.com>
+
+ * tree.c (pod_type_p): Treat VECTOR_TYPEs as PODs.
+
+2004-02-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14278
+ * parser.c (cp_parser_parameter_declaration_list): Commit
+ to fewer tentative parses.
+
+2004-02-26 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14284
+ * pt.c (dependent_type_p_r): A template template parameter is a
+ dependent type.
+
+2004-02-26 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14246
+ * mangle.c (write_template_arg_literal): Don't rely on identity for
+ boolean constants.
+
+2004-02-24 Jason Merrill <jason@redhat.com>
+
+ * tree.c (build_exception_variant): Use check_qualified_type.
+
+2004-02-23 Zack Weinberg <zack@codesourcery.com>
+ Kazu Hirata <kazu@cs.umass.edu>
+
+ * decl.c (cxx_init_decl_processing): Don't check
+ flag_writable_strings.
+
+2004-02-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/14156
+ * typeck.c (maybe_warn_about_returning_address_of_location):
+ Change check for VAR_DECL to use DECL_P instead.
+
+2004-02-23 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14250
+ * cvt.c (build_expr_type_conversion): Type must be complete before
+ looking up for conversions.
+
+2004-02-23 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14143
+ * name-lookup.c (arg_assoc_class): Don't look into template
+ arguments if it is not a primary template.
+
+2004-02-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR c++/12007
+ * method.c (use_thunk): Always clone function argument tree.
+
+2004-02-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14199
+ * pt.c (tsubst_copy): Call mark_used for a PARM_DECL.
+
+ PR c++/14173
+ * semantics.c (begin_class_definition): Set TYPE_PACKED correctly
+ for all type variants.
+
+2004-02-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13927
+ * decl.c (duplicate_decls): Return error_mark_node for invalid
+ redeclarations.
+ * name-lookup.c (push_namespace): Ignore the return value from
+ pushdecl.
+ * pt.c (push_template_decl_real): Robustify.
+
+ PR c++/14186
+ * name-lookup.c (push_class_level_binding): Do not complain about
+ adding a binding for a member whose name is the same as the
+ enclosing class if the member is located in a base class of the
+ current class.
+
+2004-02-19 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14181
+ * parser.c (cp_parser_new_expression): Parse an ill-formed
+ direct-new-declarator after a parenthesized type-id to emit good
+ diagnostic.
+
+2004-02-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.def, cvt.c: Update copyright.
+
+2004-02-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11326
+ * cp-tree.h (abi_version_at_least): Remove.
+ * mangle.c: Include flags.h.
+
+2004-02-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13971
+ * call.c (build_conditional_expr): Handle conversions between
+ class types which result in differently cv-qualified type
+ variants.
+
+ PR c++/14086
+ * class.c (delete_duplicate_fields_1): Remove.
+ (delete_duplicate_fields): Likewise.
+ (finish_struct_anon): Remove check for members with the same name
+ as their enclosing class.
+ (check_field_decls): Do not call duplicate_fields.
+ * decl.c (grokdeclarator): Remove check for static data members
+ with the same name as their enclosing class.
+ * name-lookup.c (push_class_level_binding): Check for members with
+ the same name as their enclosing class.
+
+2004-02-15 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/14085
+ * error.c (dump_decl): Handle TEMPLATE_TYPE_PARM.
+
+2004-02-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13635
+ * pt.c (push_template_decl_real): Make sure DECL_TI_ARGS of DECL
+ has full set of arguments.
+
+2004-02-13 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/13927
+ * error.c (dump_decl) <ALIAS_DECL>: Dump as simple declarations.
+
+2004-02-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14122
+ * cp-tree.h (delete_sanity): Change prototype.
+ * decl2.c (delete_sanity): Make doing_vec a bool, not an int.
+ Remove dead code. Adjust code to warn about deleting an array.
+ * typekc.c (decay_conversion): Use build_address and build_nop.
+
+ PR c++/14108
+ * search.c (accessible_p): Do not check access in thunks.
+
+ PR c++/14083
+ * call.c (build_conditional_expr): Call force_rvalue on the
+ non-void operand in the case that one result is a throw-expression
+ and the other is not.
+
+2004-02-13 Ian Lance Taylor <ian@wasabisystems.com>
+
+ PR c++/9851
+ * parser.c (cp_parser_pseudo_destructor_name): Check for errors on
+ the type name and look ahead for ::~, and bail out early with a
+ better error message if the parse is going to fail.
+
+2004-02-12 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (conversion_kind): New type.
+ (conversion_rank): Likewise.
+ (conversion): Likewise.
+ (CONVERSION_RANK): New macro.
+ (conversion_obstack): New variable.
+ (obstack_initialized): Likewise.
+ (z_candidate): Change type of convs and second_conv.
+ (candidate_warning): New type.
+ (IDENTITY_RANK): Remove.
+ (EXACT_RANK): Likewise.
+ (PROMO_RANK): Likewise.
+ (STD_RANK): Likewise.
+ (PBOOL_RANK): Likewise.
+ (USER_RANK): Likewise.
+ (ELLIPSIS_RANK): Likewise.
+ (BAD_RANK): Likewise.
+ (ICS_RANK): Likewise.
+ (ICS_STD_RANK): Likewise.
+ (ICS_USER_FLAG): Likewise.
+ (ICS_ELLIPSIS_FLAG): Likewise.
+ (ICS_THIS_FLAG): Likewise.
+ (ICS_BAD_FLAG): Likewise.
+ (NEED_TEMPORARY_P): Likewise.
+ (CHECK_COPY_CONSTRUCTOR_P): Likewise.
+ (USER_CONV_CAND): Likewise.
+ (USER_CONV_FN): Likewise.
+ (conversion_obstack_alloc): New function.
+ (alloc_conversion): Likewise.
+ (validate_conversion_obstack): Likewise.
+ (alloc_conversions): Likewise.
+ (build_conv): Adjust to deal with new conversion data structures.
+ (build_identity_conv): New function.
+ (build_ambiguous_conv): Likewise.
+ (standard_conversion): Adjust to deal with new conversion data
+ structures.
+ (convert_class_to_reference): Likewise.
+ (direct_reference_binding): Likewise.
+ (reference_binding): Likewise.
+ (implicit_conversion): Likewise.
+ (add_candidate): Likewise.
+ (add_function_candidate): Likewise.
+ (add_conv_candidate): Likewise.
+ (build_builtin_candidate): Likewise.
+ (print_z_candidate): Likewise.
+ (merge_conversion_sequences): Likewise.
+ (build_user_type_conversion_1): Likewise.
+ (build_user_type_conversion): Likewise.
+ (build_new_function_call): Likewise.
+ (build_object_call): Likewise.
+ (conditional_conversion): Likewise.
+ (build_conditional_expr): Likewise.
+ (build_new_op): Likewise.
+ (build_op_delete_call): Likewise.
+ (convert_like_real): Likewise.
+ (build_over_call): Likewise.
+ (build_new_method_call): Likewise.
+ (is_subseq): Likewise.
+ (maybe_handle_implicit_object): Likewise.
+ (maybe_handle_ref_bind): Likewise.
+ (compare_ics): Likewise.
+ (source_type): Likewise.
+ (add_warning): Likewise.
+ (joust): Likewise.
+ (can_convert_arg): Likewise.
+ (can_convert_arg_bad): Likewise.
+ (perform_implicit_conversion): Likewise.
+ (perform_direct_initialization_if_possible): Likewise.
+ (initialize_reference): Likewise.
+ * cp-lang.c (cp_tree_size): Do not handle WRAPPER.
+ * cp-tree.def (WRAPPER): Likewise.
+ (IDENTITY_CONV): Remove.
+ (LVALUE_CONV): Likewise.
+ (QUAL_CONV): Likewise.
+ (STD_CONV): Likewise.
+ (PTR_CONV): Likewise.
+ (PMEM_CONV): Likewise.
+ (BASE_CONV): Likewise.
+ (REF_BIND): Likewise.
+ (USER_CONV): Likewise.
+ (AMBIG_CONV): Likewise.
+ (RVALUE_CONV): Likewise.
+ * cp-tree.h (tree_wrapper): Remove.
+ (WRAPPER_ZC): Remove.
+ (lang_tree_node): Remove wrapper.
+ (LOOKUP_SPECULATIVELY): Remove.
+ (build_op_delete_call): Adjust prototype.
+ (validate_conversion_obstack): Declare.
+ (build_zc_wrapper): Remove.
+ * cvt.c (convert_to_reference): Remove dead code.
+ (ocp_convert): Likewise.
+ * decl.c (redeclaration_error_message): Correct handling of
+ templates.
+ (finish_destructor_body): Do not use LOOKUP_SPECULATIVELY.
+ (cp_tree_node_structure): Remove WRAPPER case.
+ * decl2.c (finish_file): Call validate_conversion_obstack.
+ * init.c (build_new_1): Remove use of LOOKUP_SPECULATIVELY.
+ (build_op_delete_call): Likewise.
+ (build_x_delete): Likewise.
+ (build_delete): Adjust call to build_op_delete_call.
+ * pt.c (tsubst_friend_declaration): Adjust code to determine
+ whether or not a friend template is a definition.
+ (tsubst_decl): Clear DECL_INITIAL for new FUNCTION_DECLs.
+ * tree.c (build_zc_wrapper): Remove.
+
+2004-02-12 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-lang.c: Don't define LANG_HOOKS_BUILTIN_TYPE_DECLS.
+ * cp-tree.h: Don't declare cxx_builtin_type_decls.
+ * decl.c (builtin_type_decls, cxx_builtin_type_decls): Delete.
+ (record_builtin_type): Call debug_hooks->type_decl on the TYPE_DECL.
+
+2004-02-10 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (lookup_destructor): Fix typo in error message.
+
+2004-02-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c, parser.c, tree.c: Fix comment typos.
+
+2004-02-07 Zack Weinberg <zack@codesourcery.com>
+
+ Bug 13856
+ * optimize.c (maybe_clone_body): Don't update DECL_ESTIMATED_INSNS.
+ * decl.c (duplicate_decls, start_function): Likewise.
+
+2004-02-07 Zack Weinberg <zack@codesourcery.com>
+
+ * name-lookup.c (pushdecl): Issue shadow warnings directly.
+ * parser.c (free_parser_stacks): Delete.
+
+2004-02-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * rtti.c: Update copyright.
+
+2004-02-06 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14033
+ * decl.c (require_complete_types_for_parms): Do not insert
+ error_mark_node in the parameter list.
+
+2004-02-06 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14028
+ * parser.c (cp_parser_enclosed_template_argument_list): Emit straight
+ error when terminator can not be found.
+
+2004-02-05 Kelley Cook <kcook@gcc.gnu.org>
+
+ Make-lang.in (po-generated): Delete.
+
+2004-02-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c (type_passed_as): Replace PROMOTE_PROTOTYPES with
+ targetm.calls.promote_prototypes.
+
+2004-02-05 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ PR middle-end/13750
+ Revert:
+ 2004-01-15 Geoffrey Keating <geoffk@apple.com>
+ PR pch/13361
+ * cp/lex.c (handle_pragma_interface): Duplicate string from tree.
+ (handle_pragma_implementation): Likewise.
+
+2004-02-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13714
+ * typeck.c (lookup_destructor): Tweak error message.
+
+2004-02-05 Jan Hubicka <jh@suse.cz>
+
+ * tree.c (cp_cannot_inline_tree_fn): Allow inlining of comdat
+ functions.
+
+2004-02-05 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14008
+ * parser.c (cp_parser_diagnose_invalid_typename): Removed parsing
+ code, only emits the diagnostic now. Added lookup of the identifier
+ and support for qualified ids.
+ (cp_parser_parse_and_diagnose_invalid_type_name): New function.
+ Parse an (invalid) type name as id-expression within a declarator.
+ (cp_parser_simple_declaration): Use it.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_make_typename_type): New function. Handle errors through
+ cp_parser_diagnose_invalid_typename.
+ (cp_parser_elaborated_type_specifier): Use it.
+
+2004-02-04 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13932
+ * call.c (convert_like_real): Use "converting" rather than
+ "argument" as the descriptive keyword to
+ dubious_conversion_warnings.
+ * typeck.c (convert_for_assignment): Do not call
+ dubious_conversion_warnings.
+
+2004-02-04 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/13086
+ * init.c (build_delete): Emit a more informative error message in
+ case of an incomplete type, and on the correct source line.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * error.c, search.c: Update copyright.
+
+2004-02-04 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9941
+ * rtti.c (tinfo_base_init): Use import_export_tinfo to decide the
+ linkage for the typeinfo name string.
+
+2004-02-04 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13969
+ * cp-tree.h (fold_non_dependent_expr): New function.
+ * parser.c (cp_parser_fold_non_dependent_expr): Remove.
+ (cp_parser_template_argument): Use fold_non_dependent_expr.
+ (cp_parser_direct_declarator): Likewise.
+ * pt.c (fold_non_dependent_expr): New function.
+ (convert_nontype_argument): Use it.
+ (tsubst_qualified_id): Simplify.
+ (tsubst_copy_and_build): Likewise.
+
+2004-02-04 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cxx_push_function_context): Do not set
+ current_function_is_thunk.
+ * method.c (use_thunk): Set CALL_FROM_THUNK on the call to the
+ actual function.
+
+2004-02-04 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/13997
+ * pt.c (more_specialized_class): Increase processing_template_decl
+ while partial ordering.
+
+2004-02-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13925
+ * decl.c (start_function): Do not call pushdecl for any
+ instantiation or specialization of a primary template.
+
+2004-02-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13950
+ * parser.c (cp_parser_class_name): Robustify.
+
+ PR c++/13970
+ * parser.c (cp_parser_cache_group): Do not consume the EOF token.
+
+ PR c++/14002
+ * semantics.c (finish_id_expression): Do not return an
+ IDENTIFIER_NODE when lookup finds a PARM_DECL.
+
+2004-02-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13978
+ * pt.c (build_non_dependent_expr): Do not build
+ NON_DEPENDENT_EXPRs for FUNCTION_DECLs or TEMPLATE_DECLs.
+
+ PR c++/13968
+ * semantics.c (finish_id_expression): Do not return an
+ IDENTIFIER_NODE when lookup finds a VAR_DECL.
+
+ PR c++/13975
+ * parser.c (cp_parser_simple_declaration): When skipping to the
+ end of the statement swallow the terminating semicolon.
+
+2004-02-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13113
+ * init.c (build_offset_ref): Improve error recovery for invalid
+ uses of non-static member functions.
+
+ PR c++/13854
+ * cp-tree.h (cp_build_type_attribute_variant): New function.
+ * class.c (build_clone): Use cp_build_type_attribute_variant.
+ * decl.c (duplicate_decls): Likewise.
+ * pt.c (copy_default_args_to_explicit_spec): Likewise.
+ (tsubst_function_type): Likewise.
+ * tree.c (build_exception_variant): Check attributes before
+ concluding that two types are the same.
+ (cp_build_type-attribute_variant): New method.
+ * typeck.c (merge_types): Use cp_build_type_attribute_variant.
+
+ PR c++/13907
+ * call.c (convert_class_to_reference): Keep better track of
+ pedantically invalid user-defined conversions.
+
+2004-02-01 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/13957
+ * pt.c (tsubst_qualified_id): Improved error message when a type
+ is expected but not found.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * class.c: Fix comment typos.
+ * decl.c: Likewise.
+ * error.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * search.c: Likewise.
+ * typeck.c: Likewise.
+
+2004-01-30 Richard Henderson <rth@redhat.com>
+
+ PR c++/13693
+ * method.c (use_thunk): Don't force_target_expr for void thunks.
+ * tree.c (build_target_expr_with_type): Assert non-void type.
+ (force_target_expr): Likewise.
+
+2004-01-30 Michael Matz <matz@suse.de>
+
+ * parser.c (cp_parser_labeled_statement): Accept case ranges.
+
+2004-01-30 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ DR206
+ PR c++/13813
+ * decl.c (grokdeclarator): Check immediatly type completeness for
+ non-dependent types.
+
+2004-01-30 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/13683
+ * call.c (convert_arg_to_ellipsis): Don't emit a warning if within
+ a sizeof expression.block
+
+2004-01-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13883
+ * mangle.c (write_encoding): Correct encoding of member template
+ constructors.
+
+2004-01-28 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * parser.c (cp_parser_template_id): Parse tentatively `[:' after a
+ template name as it was `<::' (digraph typo).
+ (cp_parser_nth_token_starts_template_argument_list_p): New function.
+ (cp_parser_id_expression): Use it.
+ (cp_parser_nested_name_specifier_opt): Likewise.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_lexer_get_preprocessor_token): Use c_lex_with_flags.
+
+2004-01-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13791
+ * typeck.c (merge_types): Do not merge attributes into
+ TYPENAME_TYPEs.
+
+ PR c++/13736
+ * parser.c (cp_parser_direct_declarator): Do not prevent
+ backtracking inside a parenthesized declarator.
+ (cp_parser_parameter_declaration): Fix typo in comment.
+
+2004-01-28 Jan Hubicka <jh@suse.cz>
+
+ * semantics.c (expand_body) Do emit_associated_thunks before
+ expansion.
+
+2004-01-27 Devang Patel <dpatel@apple.com>
+
+ * name-lookup.c: Include "debug.h"
+ (do_namespace_alias): Invoke debug_hooks to emit debug info
+ for namespace alias.
+ (do_local_using_decl): Invoke debug_hooks to emit debug info
+ for using decl.
+ (do_class_using_decl): Same.
+ (do_toplevel_using_decl): Same.
+ (do_using_directive): Same.
+ (cp_emit_debug_info_for_using): New function.
+ * Make-lang.in (cp/parser.o): Depend on debug.h
+ (cp/name-lookup.o): Same.
+
+2004-01-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (language_function, lang_type_header): Use
+ BOOL_BITFIELD.
+ * name-lookup.h (cp_binding_level): Likewise.
+
+2004-01-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13663
+ * semantics.c (finish_for_expr): Check for unresolved overloaded
+ functions.
+
+ * class.c (add_method): Just check processing_template_decl to
+ determine whether or not we are within a template.
+ * decl2.c (maybe_retrofit_in_chrg): Likewise.
+ * init.c (decl_constant_value): Check the type of the declaration,
+ not TREE_READONLY.
+ * name-lookup.c (maybe_push_to_top_level): Rename to ...
+ (push_to_top_level): ... this.
+ * name-lookup.h (maybe_push_to_top_level): Do not declare it.
+ * pt.c (push_template_decl_real): Reorder condition for speed.
+ (convert_template_argument): Use dependency-checking functions in
+ place of uses_template_parms.
+ (lookup_template_class): Avoid calling uses_template_parms more
+ than once.
+ (uses_template_parms): Reimplement, using dependency-checking
+ functions.
+ (instantiate_class_template): Use push_to_top_level, not
+ maybe_push_to_top_level.
+ (type_unification_real): Simplify.
+ (type_dependent_expression_p): Handle OFFSET_REFs and
+ TEMPLATE_DECLs.
+ (any_dependent_template_arguments_p): Handle multiple levels of
+ template argument.
+ * semantics.c (expand_or_defer_fn): Do not check
+ uses_template_parms for template instantiations.
+ * typeck.c (comptypes): Avoid calling cp_type_quals.
+
+2004-01-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13833
+ * call.c (build_over_call): Do not convert arguments when
+ processing a template.
+ * pt.c (build_non_dependent_expr): Do not build a
+ NON_DEPENDENT_EXPR for arithmetic constants.
+
+2004-01-25 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/13810
+ * parser.c (cp_parser_type_parameter): When cp_parser_id_expression
+ returns a TYPE_DECL. no further lookup is required.
+ * semantics.c (check_template_template_default_arg): A TYPE_DECL
+ is invalid. Rework to give better diagnostics.
+
+2004-01-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13797
+ * pt.c (instantiate_class_template): Add an error_mark_node
+ check.
+ (tsubst_decl) <TEMPLATE_DECL case>: Likewise.
+
+2004-01-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/13701
+ * decl.c (finish_function): Move the call to
+ finish_fname_decls below the call to
+ finish_eh_spec_block.
+
+2004-01-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * optimize.c, typeck2.c: Update copyright.
+
+2004-01-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * Make-lang.in, call.c, class.c, decl2.c, except.c, expr.c,
+ init.c, mangle.c, typeck.c: Update copyright.
+
+2004-01-21 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * parser.c (cp_parser_class_specifier): Prevent garbage collection.
+
+2004-01-20 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in: Replace $(docdir) with doc.
+ (c++.info, c++.srcinfo): Dummy entry.
+ (c++.man, c++.srcman): New rules.
+ (c++.install-man): Revamp rule.
+
+2004-01-20 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in (CXX_INSTALL_NAME, GXX_INSTALL_NAME,
+ CXX_TARGET_INSTALL_NAME, GXX_TARGET_INSTALL_NAME): Define via a
+ immediate $(shell) instead of deferred backquote.
+
+2004-01-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13651
+ * parser.c (cp_parser_postfix_expression): When encountering
+ incomplete type on left-hand side of "->" or ".", treat the entire
+ expression as erroneous.
+
+ PR c++/13592
+ * call.c (build_field_call): Remove.
+ (n_build_method_call): Likewise.
+ (build_method_call): Likewise.
+ (build_new_method_call): Do not call build_field_call.
+ * class.c (n_build_method_call): Remove.
+ (print_class_statistics): Do not print it.
+ * cp-tree.h (build_method_call): Remove declaration.
+ (finish_object_call_expr): Likewise.
+ (build_new_1): Do not use build_method_call.
+ * parser.c (cp_parser_postfix_expression): Use finish_call_expr
+ when the function appearing on the right-hand-side of "." or "->"
+ is not actually a function.
+ * pt.c (tsubst_copy_and_build): Likewise.
+ * semantics.c (finish_object_call_expr): Remove.
+
+2004-01-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13710
+ * pt.c (tsubst): Use finish_typeof.
+
+2004-01-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/11725
+ * except.c (build_throw): In a template, set
+ current_function_returns_abnormally.
+
+2004-01-17 Fred Fish <fnf@intrinsity.com>
+
+ PR c++/11895
+ * decl.c (reshape_init): Handle VECTOR_TYPE like ARRAY_TYPE,
+ except don't call array_type_nelts() with a VECTOR_TYPE.
+
+2004-01-16 Jan Hubicka <jh@suse.cz>
+
+ * mangle.c (write_mangled_name): Remove inline modifier.
+
+2004-01-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13574
+ * decl.c (compute_array_index_type): Fix grammar in comment.
+ * init.c (build_zero_init): Handle zero-sized arrays correctly.
+
+ PR c++/13178
+ * call.c (name_as_c_string): Print conversion operator names
+ correctly.
+
+ PR c++/13478
+ * call.c (initialize_reference): Pass -1 for inner parameter to
+ convert_like_real.
+
+2004-01-15 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/13407
+ * parser.c (cp_parser_base_specifier): Check for an invalid
+ keyword `typename' and emit an user-friendly error message.
+
+2004-01-15 Geoffrey Keating <geoffk@apple.com>
+
+ PR pch/13361
+ * cp/lex.c (handle_pragma_interface): Duplicate string from tree.
+ (handle_pragma_implementation): Likewise.
+
+2004-01-15 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/9259
+ * typeck.c (build_class_member_access_expr): Allow to access members
+ of the currently open class.
+ (finish_class_member_access_expr): Likewise.
+
+2004-01-15 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/13659
+ * name-lookup.c (validate_nonmember_using_decl): Take scope and
+ name by value, instead of computing them.
+ (do_local_using_decl, do_toplevel_using_decl): Add scope and name
+ arguments. Pass them to validate_nonmember_using_decl.
+ * name-lookup.h (do_local_using_decl): Adjust.
+ (do_toplevel_using_decl): Likewise.
+ * parser.c (cp_parser_using_declaration): Likewise.
+ * pt.c (tsubst_expr): Likewise.
+
+2004-01-15 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/13594
+ PR c++/13658
+ * name-lookup.c (qualified_lookup_using_namespace): Search
+ strongly-associated namespaces first, and only then try other
+ namespaces.
+
+2004-01-15 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in (c++.srcextra): Dummy entry.
+
+2004-01-15 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/8856
+ * parser.c (cp_parser_template_name): Don't try to parse a
+ conversion-function-id, as it cannot be a template-name.
+ (cp_parser_simple_type_specifier): Check for invalid template-ids
+ even after a built-in type.
+
+2004-01-14 Jan Hubicka <jh@suse.cz>
+
+ PR c++/12850
+ * pt.c (instantiate_decl): Do not increase function_depth.
+
+2004-01-14 Danny Smith <dannysmith@users,sourceforge.net>
+
+ PR c++/9021
+ PR c++/11005
+ * parser.c (cp_parser_elaborated_type_specifier): Warn about
+ attributes and discard.
+ * decl.c (xref_tag): Don't overwite existing attributes with
+ NULL_TREE.
+
+2004-01-14 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/12335
+ * parser.c (cp_parser_lookup_name): Return error_mark_node if there
+ is no destructor while looking up a BIT_NOT_EXPR.
+
+2004-01-13 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * cxxfilt.c: Remove unused file.
+
+2004-01-14 Jan Hubicka <jh@suse.cz>
+
+ Partial fix to PR c++/12850
+ * decl2.c (mark_used): Do not proactively instantiate templates
+ when compiling in unit-at-a-time or not optimizing.
+ * optimize.c (maybe_clone_body): Do not increase function depth.
+
+2004-01-13 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/13474
+ * pt.c (tsubst) <INTEGER_TYPE>: Remove obsolete array index tweaking.
+
+2004-01-12 Steven Bosscher <stevenb@suse.de>
+
+ PR c++/13558
+ * parser.c (cp_parser_member_declaration): Any non-type is also
+ not a class or a function.
+
+2004-01-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/12815
+ * class.c (build_base_path): Do not mark vtable references as
+ TREE_CONSTANT.
+ (build_vtbl_ref_1): Likewise.
+
+2004-01-12 Richard Henderson <rth@redhat.com>
+
+ PR opt/10776
+ * typeck2.c (split_nonconstant_init_1, split_nonconstant_init): New.
+ (store_init_value): Use it.
+ * decl.c (check_initializer): Expect full initialization code
+ from store_init_value.
+ * init.c (expand_aggr_init_1): Likewise.
+ * decl2.c (maybe_emit_vtables): Abort if runtime init needed.
+
+2004-01-12 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): For non-POD class types, also copy
+ the DECL_SIZE and DECL_MODE of fields to the base class type.
+
+2004-01-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13289
+ * pt.c (instantiate_decl): Set DECL_TEMPLATE_INSTANTIATED before
+ calling regenerate_decl_from_template.
+
+2004-01-12 Scott Brumbaugh <scottb.lists@verizon.net>
+
+ PR c++/4100
+ * parser.c (cp_parser_decl_specifier_seq): Add check for a friend
+ decl-specifier occurring along with a class definition.
+
+2004-01-12 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * parser.c (cp_parser_decl_specifier_seq): Add parenthetical
+ clauses to comments describing declares_class_or_enum.
+ (cp_parser_type_specifier): Set *declares_class_or_enum to 0, not
+ false.
+
+2004-01-12 Jan Hubicka <jh@suse.cz>
+
+ * pt.c (for_each_template_parm): Do not check for duplicates.
+ (for_each_template_parm): Use walk_tree duplicate checking code.
+
+2004-01-11 Ian Lance Taylor <ian@wasabisystems.com>
+
+ PR c++/3478
+ * parser.c (cp_parser_decl_specifier_seq): If the first decl_spec
+ is error_mark_node, don't add any more decl_specs.
+ (cp_parser_init_declarator): After committing to a declaration, if
+ the decl_specifiers start with error_mark_node, issue an error and
+ change the type to "int".
+
+2004-01-09 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR bootstrap/7817
+ * Make-lang.in: Copy gcc.1 to g++.1 rather than using .so.
+
+2004-01-10 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ DR 337
+ PR c++/9256
+ * pt.c (tsubst): Substitution must fail if we are attempting to
+ create an array with element type that is an abstract class type.
+ * decl.c (cp_finish_decl): Strip pointers and array types recursively
+ before calling abstract_virtuals_error.
+
+2004-01-09 Alexandre Oliva <aoliva@redhat.com>
+
+ * name-lookup.c (qualified_lookup_using_namespace): Consider
+ strong using directives even if we've already found a binding.
+
+2004-01-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cxx_expand_expr): Change prototype.
+ * expr.c (cxx_expand_expr): Add alt_rtl parameter.
+
+2004-01-08 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/12573
+ * pt.c (value_dependent_expression_p): Handle COMPONENT_REFs by
+ looking into them recursively. They can be there because of the
+ new __offsetof__ extension.
+
+2004-01-07 Zack Weinberg <zack@codesourcery.com>
+
+ * parser.c (cp_parser_save_member_function_body): Mark the
+ definition static.
+
+2004-01-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13057
+ * class.c (build_clone): Copy type attributes from the original
+ function to the clone.
+
+ PR c++/12815
+ * class.c (build_vtbl_ref_1): Do not unconditionally mark vtable
+ references as constant.
+
+ PR c++/12132
+ * parser.c (cp_parser_explicit_instantiation): Improve error
+ recovery.
+ (cp_parser_require): Improve indication of the error location.
+
+ PR c++/13451
+ * parser.c (cp_parser_class_head): Reorder logic to check for
+ invalid qualification.
+
+2004-01-04 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13157
+ * name-lookup.c (lookup_using_namespace): Remove spacesp
+ parameter.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_qualified_name): Adjust accordingly.
+ (lookup_name_real): Likewise.
+ (lookup_arg_dependent): Do not eliminate the namespace of the
+ functions found by unqualified name lookup unless that is the
+ current namespace.
+
+2004-01-04 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * semantics.c (push_deferring_access_checks): Fix format.
+ (resume_deferring_access_checks): Likewise.
+ (stop_deferring_access_checks): Likewise.
+ (pop_deferring_access_checks): Likewise.
+ (get_deferred_access_checks): Likewise.
+ (pop_to_parent_deferring_access_checks): Likewise.
+ (perform_deferred_access_checks): Likewise.
+ (perform_or_defer_access_check): Likewise.
+
+2004-01-04 Richard Henderson <rth@redhat.com>
+
+ * call.c (build_over_call): Don't create a save_expr of an
+ aggregate, but rather its address.
+
+2004-01-04 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13529
+ * parser.c (cp_parser_postfix_expression): Allow "." to appear in
+ an offsetof expression.
+
+ * parser.c (cp_parser_parameter_declaration): Fix comment.
+
+ PR c++/12226
+ * call.c (CHECK_COPY_CONSTRUCTOR_P): New macro.
+ (reference_binding): Set it when appropriate.
+ (build_temp): New function, split out from ...
+ (convert_like_real): ... here. Honor CHECK_COPY_CONSTRUCTOR_P.
+ (initialize_reference): Likewise.
+
+ PR c++/13536
+ * parser.c (cp_parser): Add in_type_id_in_expr_p.
+ (cp_parser_new): Initialize it.
+ (cp_parser_postfix_expression): Set it.
+ (cp_parser_sizeof_operand): Likewise.
+ (cp_parser_parameteR_declaration): Do not commit early to tenative
+ parsers when in_type_id_in_expr_p is set.
+
+2004-01-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13094
+ * parser.c (cp_parser_template_argument): Don't call
+ make_unbound_class_template directly.
+ (cp_parser_lookup_name): Don't extract TEMPLATE_DECL from
+ UNBOUND_CLASS_TEMPLATE tree node.
+
+2004-01-02 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/12729
+ * method.c (use_thunk): Pass the CALL_EXPR through force_target_expr.
+
+2004-01-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13520
+ * cp-tree.h (DECL_UNBOUND_CLASS_TEMPLATE_P): New macro.
+ (DECL_FUNCTION_TEMPLATE_P): Use it.
+ (DECL_CLASS_TEMPLATE_P): Likewise.
+ * parser.c (cp_parser_lookup_name): Add is_template parameter.
+ (cp_parser_type_parameter): Adjust call to cp_parser_lookup_name.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_namespace_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_lookup_name_simple): Likewise.
+
+
+Copyright (C) 2004 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2005 b/gcc-4.9/gcc/cp/ChangeLog-2005
new file mode 100644
index 000000000..3269fa7f4
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2005
@@ -0,0 +1,3528 @@
+2005-12-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.c (pp_cxx_constant): New. Print
+ string-literal in parens if input program says so.
+ (pp_cxx_primary_expression): Hand off constant printing to
+ pp_cxx_constant.
+ (pp_cxx_pretty_printer_init): Set pp->c_base.constant.
+ (pp_cxx_expression): Use pp_cxx_constant for literals.
+ * error.c (dump_expr): Use pp_constant for literals.
+
+2005-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (make_thunk): Don't set comdat_linkage here.
+ (use_thunk): Make thunk one only here, if thunk target is
+ DECL_ONE_ONLY.
+
+2005-12-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25439
+ * decl.c (grokdeclarator): Remove dead code.
+ * ptree.c (cxx_print_xnode): Handle BASELINK.
+ * parser.c (make_id_declarator): Add sfk parameter.
+ (cp_parser_direct_declarator): Do not pass TYPE_DECLs to
+ make_id_declarator.
+ (cp_parser_declarator_id): Simplify BASELINKs here.
+ (cp_parser_member_declaration): Adjust calls to
+ make_id_declarator.
+
+2005-12-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23171, c++/23172, c++/25417.
+ * typeck.c (build_unary_op): Create temporary variables for
+ compound literals whose addresses are taken.
+ * init.c (expand_aggr_init_1): Use COMPOUND_LITERAL_P.
+ * decl.c (reshape_init_vector): Likewise.
+ (reshape_init): Give it external linkage.
+ (check_initializer): Use COMPOUND_LITERAL_P.
+ (initialize_artificial_var): Allow the initializer to be a
+ CONSTRUCTOR.
+ * call.c (make_temporary_var_for_ref_to_temp): Use
+ create_temporary_var.
+ * cp-tree.h (COMPOUND_LITERAL_P): New macro.
+ (rehape_init): Declare.
+ * typeck2.c (digest_init): Use COMPOUND_LITERAL_P.
+ * semantics.c (finish_compound_literal): Use reshape_init.
+
+2005-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/24671
+ * pt.c (instantiate_template): Handle SFINAE.
+
+2005-12-23 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * decl.c (grokdeclarator): Improve diagnostic for friend
+ declarations of class members.
+
+2005-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25369
+ * tree.c (really_overloaded_fn): Tweak comment.
+ * pt.c (tsubst_call_declarator_parms): Remove.
+ (tsubst_copy): Call mark_used on the member referenced by an
+ OFFSET_REF.
+ * semantics.c (finish_qualified_id_expr): Simplify.
+ * decl2.c (mark_used): Accept BASELINKs.
+
+ PR c++/25364
+ * typeck.c (build_unary_op): Pass DECLs not names to
+ build_offset_refs.
+ * init.c (build_offset_ref): Do not do name lookup. Do not call
+ mark_used.
+ * call.c (build_call): Simplify and tidy.
+ * semantics.c (finish_qualified_id_expr): Call mark_used.
+
+2005-12-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/23333
+ * parser.c (cp_parser_pure_specifier): Check for PURE_ZERO to
+ identify a single '0'.
+
+2005-12-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21228
+ * decl.c (use_eh_spec_block): New function.
+ (store_parm_decls): Use it.
+ (finish_function): Likewise.
+
+2005-12-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/24278
+ * init.c (expand_member_init): Print messages about baseclasses
+ using %T rather than %D.
+
+ PR c++/24915
+ * class.c (add_method): Do not treat templates as identical unless
+ their return types are the same.
+
+2005-12-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25300
+ * tree.c (build_qualified_name): Return error_mark_node for
+ erroneous input.
+
+2005-12-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25337
+ * pt.c (tsubst_copy_and_build): Permit dependent types for the
+ object in a class member access expression.
+
+2005-12-10 Terry Laurenzo <tlaurenzo@gmail.com>
+
+ PR java/9861
+ * mangle.c (write_bare_function_type): Mangle return type for
+ methods of Java classes
+
+2005-12-08 Théodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * call.c (build_conditional_expr): Print types in error messages.
+
+2005-12-07 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * expr.c (cxx_expand_expr): Call gcc_unreachable instead of abort.
+
+2005-12-07 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * cp-gimplify.c (gimplify_cp_loop): Use fold_build3.
+
+2005-12-07 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+
+ * Make-lang.in (c++.all.build, c++.install-normal): Remove.
+
+2005-12-07 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+
+ * Make-lang.in: Remove all dependencies on s-gtype.
+
+2005-12-06 Aldy Hernandez <aldyh@redhat.com>
+
+ PR C++/24138
+ * decl.c (reshape_init_array_1): Handle max_index of -1.
+
+2005-12-06 Roger Sayle <roger@eyesopen.com>
+
+ * typeck.c (build_binary_op): Issue warning if either operand of a
+ comparison operator is a string literal, except for testing equality
+ or inequality against NULL.
+
+2005-12-06 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/25263
+ * decl.c (compute_array_index_type): Check that itype is an
+ INTEGER_CST node before testing/clearing TREE_OVERFLOW.
+
+2005-12-05 Daniel Berlin <dberlin@dberlin.org>
+
+ * ptree.c (cxx_print_decl): Update to check for decl_common
+ structure.
+
+2005-12-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/24173
+ * decl.c (duplicate_decls): Don't rely on DECL_TEMPLATE_INFO after
+ clobbering newdecl.
+
+2005-12-02 Richard Guenther <rguenther@suse.de>
+
+ * semantics.c (simplify_aggr_init_expr): Use buildN instead
+ of build.
+
+2005-12-02 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * parser.c (cp_lexer_new_main): Usr GGC_RESIZEVEC instead of
+ ggc_realloc.
+ (cp_parser_template_argument_list): Use XRESIZEVEC instead of
+ xrealloc.
+ * class.c (pushclass): Likewise.
+
+2005-12-02 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl2.c (get_priority_info): Use XNEW, not xmalloc.
+ * decl.c (push_switch): Likewise.
+ * lex.c (handle_pragma_implementation): Likewise.
+ * cp-objcp-common.c (decl_shadowed_for_var_insert): Use GGC_NEW,
+ not ggc_alloc.
+ (cxx_initialize_diagnostics): Use XNEW, not xmalloc.
+ * class.c (init_class_processing): Use XNEWVEC, not xmalloc.
+ * g++spec.c (lang_specific_driver): Likewise.
+ * mangle.c (save_partially_mangled_name): Likewise.
+ * parser.c (cp_lexer_new_main): Use GGC_NEWVEC, not ggc_alloc.
+ (cp_parser_template_argument_list): Use XNEWVEC, nto xmalloc.
+ (cp_parser_sizeof_operand): Likewise.
+ * repo.c (open_repo_file, open_repo_file): Likewise.
+
+2005-12-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * parser.c (cp_parser_make_typename_type): Call make_typename_type
+ with tf_none instead of magic value 0.
+ (cp_parser_explicit_instantiation): Call do_type_instantiation
+ with tf_error instead of magic value 1.
+ (cp_parser_elaborated_type_specifier): Call make_typename_type
+ with tf_error instead of magic value 1.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_lookup_name): Likewise.
+
+2005-12-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * parser.c (cp_parser_declaration): Set token2.type to CPP_EOF,
+ not RID_MAX.
+
+2005-11-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/21123
+ * cp-gimplify.c (cp_genericize_r): Don't dereference invisible reference
+ parms in a thunk.
+
+2005-11-30 Ben Elliston <bje@au.ibm.com>
+
+ * typeck.c (build_x_unary_op): Correct spelling in error message.
+
+2005-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21166
+ * class.c (check_field_decls): Only set DECL_PACKED on a field
+ when its natural alignment is > BITS_PER_UNIT.
+
+2005-11-27 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/24979
+ * cp-tree.h (DECL_MAIN_P): Remove duplicate definition.
+
+2005-11-26 Richard Henderson <rth@redhat.com>
+
+ * lex.c: Update for pragma_lex rename.
+ * parser.c: Likewise.
+
+2005-11-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/9278
+ * decl.c (grokparms): Do not allow typedef-names in a '(void)'
+ parmlist.
+
+2005-11-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * typeck2.c (process_init_constructor_union): Remove check for
+ unnamed union members.
+
+2005-11-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * name-lookup.c (lookup_name_real): Merge two if's.
+
+2005-11-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * pt.c (instantiate_class_template): Clean-up.
+
+2005-11-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * pt.c (template_class_depth_real): Remove. Move functionality to ...
+ (template_class_depth): ... here, replacing count_specializations
+ with 0. Adjust comment.
+
+2005-11-24 Richard Guenther <rguenther@suse.de>
+ Dirk Mueller <dmueller@suse.de>
+
+ PR c++/14024
+ * typeck.c (build_reinterpret_cast_1): Use
+ strict_aliasing_warning.
+
+2005-11-23 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/24235
+ * pt.c (check_instantiated_args): Reword diagnostic message about
+ template argument involving local types.
+
+2005-11-23 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/21667
+ * typeck.c (build_array_ref): Avoid code duplicate. Use common
+ C/C++ diagnostic function warn_array_subscript_with_type_char.
+
+2005-11-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/22238
+ * error.c (resolve_virtual_fun_from_obj_type_ref): New.
+ (dump_expr): Use it in <case CALL_EXPR>.
+
+2005-11-21 Richard Henderson <rth@redhat.com>
+
+ * cp-objcp-common.h, name-lookup.c, name-lookup.h: Revert 11-18 patch.
+
+ * name-lookup.c (lookup_name): Remove prefer_type argument.
+ (lookup_name_prefer_type): New.
+ * decl.c (lookup_and_check_tag): Use them.
+ * pt.c (tsubst_friend_class): Likewise.
+ (lookup_template_class): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ * name-lookup.h (lookup_name_prefer_type): New.
+ (lookup_name): Remove declaration.
+
+2005-11-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8355
+ * decl.c (grokfndecl): Set up DECL_TEMPLATE_INFO before calling
+ set_decl_namespace.
+ * name-lookup.c (set_decl_namespace):
+
+2005-11-18 Mike Stump <mrs@apple.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_LOOKUP_NAME): Add.
+ * name-lookup.c (lookup_name_two): Remove.
+ (lookup_name_one): Add.
+ * name-lookup.h (lookup_name_two): Remove.
+ (lookup_name_one): Add.
+
+2005-11-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/24580
+ * method.c (locate_copy): Also use skip_artificial_parms here.
+ (synthesize_exception_spec): Use CLASS_TYPE_P rather than checking
+ for RECORD_TYPE.
+ (locate_ctor): Abort if we fail to find a default constructor.
+
+2005-11-15 Mike Stump <mrs@apple.com>
+
+ * name-lookup.c (lookup_name_two): Add.
+ * name-lookup.h: Likewise.
+
+2005-11-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/24667
+ * typeck.c (check_for_casting_away_constness): Use the diag_fn.
+ (build_const_cast_1): Call it, for C-style casts.
+
+2005-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/24687
+ * pt.c (check_explicit_specialization): Don't check for C linkage.
+ (push_template_decl_real): Likewise.
+ * parser.c (cp_parser_explicit_specialization): Check here.
+ (cp_parser_template_declaration_after_export): And here.
+
+ * parser.c (cp_lexer_get_preprocessor_token): Initialize keyword
+ field.
+
+2005-11-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/24580
+ * method.c (locate_ctor): Skip all artificial parms, not just
+ 'this'.
+
+2005-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (eof_token): Add initializer for ambiguous_p.
+
+2005-11-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/24817
+ * decl.c (check_redeclaration_exception_specification): New
+ function.
+ (duplicate_decls): Use it.
+ * error.c (fndecl_to_string): Print the template parameter list.
+
+ PR c++/20293
+ * cxx-pretty-print.c (pp_cxx_statement): Print qualifying scopes
+ for namespaces.
+ (pp_cxx_original_namespace_definition): Likewise.
+ * name-lookup.c (ambiguous_decl): Don't issue error messages;
+ instead return lists of ambiguous candidates.
+ (select_decl): Handle ambiguous namespace lookups.
+ * parser.c (cp_token): Add ambiguous_p.
+ (cp_lexer_get_preprocessor_token): Set it.
+ (cp_parser_diagnose_invalid_type_name): Avoid duplicate messages
+ when a qualified name uses an invalid scope.
+ (cp_parser_primary_expression): Print ambiguous candidates.
+ (cp_parser_type_parameter): Adjust comment to reflect new
+ parameter name for cp_parser_lookup_name.
+ (cp_parser_template_argument): Likewise.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_namespace_name): Likewise.
+ (cp_parser_class_name): Print ambiguous candidates.
+ (cp_parser_lookup_name): Rename ambiguous_p parameter to
+ ambiguous_decls. Use it to return a list of ambiguous candiates
+ when a lookup is ambiguous.
+ (cp_parser_lookup_name_simple): Adjust comment to reflect new
+ parameter name for cp_parser_lookup_name.
+
+2005-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/24780
+ * typeck.c (complete_type): Set TYPE_NEEDS_CONSTRUCTING
+ and TYPE_HAS_NONTRIVIAL_DESTRUCTOR flags for all variants
+ of array type.
+
+ PR c++/24761
+ * pt.c (tsubst_copy_asm_operands): New function.
+ (tsubst_expr) <case ASM_EXPR>: Use it.
+
+2005-11-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/19450
+ * decl.c (redeclaration_error_message): Issue diagnostics about
+ olddecl and newdecl disagreement on __thread property.
+ (grokdeclarator): Set DECL_TLS_MODEL on class static variables.
+
+2005-11-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/21123
+ * method.c (use_thunk): Use build_cplus_new instead of
+ force_target_expr.
+
+2005-11-06 Jason Merrill <jason@redhat.com>
+ James A. Morrison <phython@gcc.gnu.org>
+
+ PR c++/17256
+ * decl2.c (cp_finish_file): Fix conditions for undefined warning.
+ Set TREE_NO_WARNING instead of TREE_PUBLIC.
+ * pt.c (instantiate_pending_templates): Set DECL_INITIAL to avoid
+ a warning on a function we didn't instantiate because of excessive
+ recursion.
+
+2005-11-06 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (record_subobject_offsets): Don't record offsets past
+ biggest empty class for non-empty base classes.
+ (layout_class_type): Use TYPE_SIZE_UNIT, not TYPE_SIZE, when
+ keeping track of the size of emptyclasses.
+
+ PR c++/21308
+ * class.c (sizeof_biggest_empty_class): New variable.
+ (record_subobject_offsets): Don't record offsets past biggest
+ empty class for data members. Replace vbases_p parameter with
+ is_data_member parameter.
+ (build_base_field): Adjust call.
+ (layout_class_type): Likewise. Maintain
+ sizeof_biggest_empty_class.
+
+2005-11-05 Kazu Hirata <kazu@codesourcery.com>
+
+ * decl2.c, init.c, typeck.c: Fix comment typos.
+
+2005-11-04 Richard Guenther <rguenther@suse.de>
+
+ PR c++/22487
+ * init.c (build_vec_init): Build comparison of matching
+ types.
+
+2005-11-03 Josh Conner <jconner@apple.com>
+
+ PR c++/19989
+ pt.c (tsubst): Accept zero-length array if tf_error is set
+ in complain flags. Change error message for negative-
+ length array.
+
+2005-11-04 Joseph S. Myers <joseph@codesourcery.com>
+
+ * cp-tree.h (cp_cpp_error), error.c (cp_cpp_error): Take va_list*
+ parameter.
+
+2005-11-03 Joseph S. Myers <joseph@codesourcery.com>
+
+ PR c++/17964
+ * error.c (cp_cpp_error): New function.
+ * cp-tree.h (cp_cpp_error): Declare.
+ * parser.c (cp_lexer_new_main): Set CPP option client_diagnostic
+ and error callback after lexing.
+
+2005-11-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21627
+ * pt.c (register_specialization): Update inline flags on clones.y
+
+2005-11-03 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/24582
+ * decl.c (declare_local_label): Return 0 for variables
+ with error_mark_node as their types.
+
+2005-11-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22434
+ * call.c (build_conditional_expr): Do bad conversions, if there's
+ no other choice.
+
+ PR c++/24560
+ * parser.c (cp_parser_postfix_dot_deref_expression): Improve error
+ message for use of overloaded functions on LHS of "." operator.
+
+ PR c++/19253
+ * parser.c (cp_parser_postfix_expression): Use
+ cp_parser_elaborated_type_specifier to handle typename-types in
+ functional casts.
+ (cp_parser_enclosed_argument_list): Skip ahead to the end of the
+ template argument list if the closing ">" is not found.
+
+ PR c++/24569
+ * pt.c (instantiate_decl): Use cp_finish_decl, not
+ finish_static_data_member_decl.
+
+2005-10-28 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * decl.c (grokfndecl): Remove the setting
+ of the return type of the function type
+ of main after erroring about must returning
+ int.
+
+2005-10-28 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR C++/23229
+ * decl.c (grokfndecl): Create a new function type
+ after erroring out about main not returning int.
+
+2005-10-28 Josh Conner <jconner@apple.com>
+
+ PR c++/22153
+ * parser.c (cp_parser_member_declaration): Detect and handle
+ a template specialization.
+
+2005-10-28 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR C++/23426
+ * decl.c (start_decl): Check that the decl is an
+ error_mark_node before getting the type.
+ Remove the check for the decl's type being an
+ error_mark_node.
+
+2005-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/24260
+ * parser.c (cp_parser_init_declarator): Pass attributes to
+ grokfield.
+
+2005-10-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22618
+ * search.c (accessible_p): Check access in the outermost set of
+ template parameters.
+
+2005-10-20 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (grokdeclarator): Fix ambiguous pedwarn message.
+
+2005-10-18 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/22293
+ * decl.c (grokdeclarator): Reject unqualified destructors in
+ friend declarations.
+
+2005-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23293
+ * pt.c (convert_template_argument): Use canonical type variants in
+ template specializations.
+
+2005-10-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21383
+ * name-lookup.c (arg_assoc): Template args can be null in a
+ template-id-expr.
+
+ PR c++/22604
+ * class.c (update_vtable_entry_for_fn): Don't process invalid
+ covariant overriders.
+
+ PR c++/23118
+ * cp-tree.h (add_method): Add return value.
+ * class.c (add_method): Return success indicator.
+ * semantics.c (finish_member_declaration): Don't add an invalid
+ method to the method list.
+
+2005-10-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21908
+ * call.c (build_new_method_call): Do not show VTT parameters to
+ the user.
+
+2005-10-17 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/23440
+ * parser.c (cp_parser_statement): If the parser reached CPP_EOF,
+ only complain about missing statement.
+
+2005-10-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/24386
+ * cp-tree.h (BASELINK_QUALIFIED_P): New.
+ * pt.c (tsubst_copy_and_build): <CALL_EXPR case>: Use it.
+ * typeck.c (finish_class_member_access_expr): Set it.
+
+ PR c++/21353
+ * decl.c (check_default_argument): Don't check
+ processing_template_decl or uses_template_parms here.
+ (grokparms): Only call check_default_argument when not processing
+ a template decl.
+ * parser.c (cp_parser_late_parsing_default_arg): Call
+ check_default_argument when not processing a template decl.
+
+2005-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/24389
+ * decl2.c (mark_used): Use uses_template_parms instead of
+ dependent_type_p.
+ * init.c (constant_value_1): Handle uninstantiated templates
+ specially.
+ * pt.c (instantiate_decl): Add sanity check.
+
+2005-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22173
+ * typeck.c (check_template_keyword): Fix thinko.
+
+2005-10-16 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/23959
+ * decl.c (pop_switch): Only call c_do_switch_warnings
+ when not processing templates.
+
+2005-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22173
+ * cp-tree.h (QUALIFIED_NAME_IS_TEMPLATE): New macro.
+ (check_template_keyword): New function.
+ (finish_id_expression): Change prototoype.
+ (finish_qualified_id_expr): Change prototype.
+ (build_qualified_name): New function.
+ (finish_class_member_access_expr): Change prototype.
+ * init.c (build_offset_ref): Use build_qualified_name.
+ * mangle.c (write_expression): Likewise.
+ * parser.c (cp_parser_primary_expression): Remove qualifying_class
+ parameter. Add address_p and template_arg_p. Use
+ build_qualified_name.
+ (cp_parser_id_expression): Default *template_p to
+ template_keyword_p. Check for invalid uses of the template
+ keyword.
+ (cp_parser_postfix_expression): Eliminate special handling for
+ qualified names. Adjust call to cp_parser_primary_expression.
+ (cp_parser_postfix_dot_deref_expression): Adjust call to
+ cp_parser_id_expression and finish_class_member_access_expr.
+ (cp_parser_template_argument_list): Add comment.
+ (cp_parser_template_argument): Adjust use of
+ cp_parser_primary_expression. Remove call to
+ finish_qualified_id_expr.
+ (cp_parser_lookup_name): Use build_qualified_name.
+ * pt.c (tsubst): Use build_qualified_name.
+ (tsubst_qualified_id): Likewise. Adjust call to
+ finish_qualified_id_expr.
+ (tsubst_copy): Use build_qualified_name.
+ (tsubst_copy_and_build): Adjusts call to finish_id_expression and
+ finish_class_member_access_expr.
+ * semantics.c (finish_non_static_data_member): Use
+ build_qualified_name.
+ (finish_qualified_id_expr): Add template_p and template_arg_p
+ parameters.
+ (finish_id_expression): Remove qualifiying_class parameter. Add
+ template_p, done, address_p, and template_arg_p. Use
+ build_qualified_name. Adjust calls to
+ finish_class_member_acess_expr.
+ * tree.c (build_qualified_name): New function.
+ * typeck.c (check_template_keyword): New function.
+ (finish_class_member_access_expr): Add template_p argument. Check
+ for invalid uses of the template keyword.
+
+2005-10-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21347
+ * class.c (maybe_warn_about_overly_private_class): Lazy
+ constructors are public.
+
+2005-10-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19565
+ * call.c (convert_like_real): Rely on convert_and_check to issue
+ warnings about overflow and conversion to unsigned.
+ * decl.c (finish_enum): Use the location of the enumerators, not
+ the closing brace of the enumeration, when reporting warnings
+ about conversions.
+ (build_enumerator): Use error_mark_node for erroneous values.
+ * typeck2.c (digest_init): Remove reference to "signature pointer"
+ from comment.
+
+2005-10-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/17796
+ * optimize.c (update_cloned_parm): Add FIRST parameter. Use it.
+ (maybe_clone_body): Track the first clone.
+
+2005-10-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/23984
+ * class.c (build_base_path): The vtable is always the first thing
+ in the vtt.
+
+2005-10-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20721
+ * cp-tree.h (DECL_NONTRIVIALLY_INITIALIZED_P): New macro.
+ * decl.c (duplicate_decls): Merge it into new declarations.
+ (decl_jump_unsafe): Use it, rather than DECL_INITIAL.
+ (cp_finish_decl): Set it, when appropriate.
+
+ PR c++/22180
+ * call.c (build_new_method_call): Correct pretty-printing of
+ destructor names.
+ * pt.c (tsubst_qualified_id): Recognize invalid uses of "~T" as an
+ identifier.
+
+ PR c++/23694
+ * decl.c (start_method): Return error_mark_node for errors.
+
+ PR c++/23307
+ * pt.c (push_template_decl_real): Complain about attempts to
+ declare template variables.
+
+ PR c++/22352
+ * pt.c (tsubst_template_parms): Set processing_template_decl while
+ processing the parameters.
+ (tsubst_decl): Set processing_template_decl when substituting into
+ a TEMPLATE_DECL.
+
+ PR c++/22405
+ * pt.c (most_specialized_instantiation): Robustify.
+
+ PR c++/22464
+ * semantics.c (finish_id_expression): Issue errors about uses of
+ local variables in containing functions even in templates.
+
+2005-10-12 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR target/21801
+ PR target/23589
+ * class.c (finish_struct_1): Call
+ targetm.cxx.adjust_class_at_definition.
+
+
+2005-10-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21592
+ * pt.c (build_non_dependent_expr): Don't wrap a COMPONENT_REF
+ with already looked up member functions. Assert we're not
+ returning a NON_DEPENDENT_EXPR with unknown type.
+ * typeck.c (finish_class_member_access_expr): We can get
+ non-template-id-expr baselinks. If the lookup finds a baselink,
+ remember it even inside templates.
+
+ PR c++/23797
+ * parser.c (cp_parser_functional_cast): Cope when TYPE is not a
+ TYPE_DECL. Use dependent_type_p to check type.
+ * pt.c (uses_template_parms_p): Use dependent_type_p for a
+ TYPE_DECL.
+ (type_dependent_expression_p): Assert we've not been given a
+ TYPE_DECL.
+
+ PR c++/21117
+ * decl.c (check_function_type): Correctly overwrite incomplete
+ return type with void type.
+ * typeck.c (check_return_expr): If the function's return type is
+ void, don't try and convert a return expr.
+
+2005-10-12 David Edelsohn <edelsohn@gnu.org>
+
+ PR c++/23730
+ * call.c (build_object_call): If BINFO is NULL, bypass
+ lookup_fnfields and set fns to NULL_TREE.
+
+2005-10-12 Paolo Bonzini <bonzini@gnu.org>
+
+ PR c++/24052
+ * error.c (dump_expr): Pass LABEL_DECL to dump_decl. Print
+ an ADDR_EXPR of a LABEL_DECL as &&.
+
+2005-10-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/19964
+ * class.c (walk_subobject_offsets): Don't walk error_mark_node.
+
+2005-10-11 Ian Lance Taylor <ian@airs.com>
+
+ PR c++/8057
+ * cvt.c (convert_to_void): Don't warn about unused values when
+ processing a template declaration.
+
+2005-10-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21089
+ * call.c (convert_like_real): Use decl_constant_value, not
+ integral_constant_value.
+ * init.c (constant_value_1): New function.
+ (integral_constant_value): Use it.
+ (decl_constant_value): Likewise.
+ * typeck.c (decay_conversion): Use decl_constant_value, not
+ integral_constant_value.
+
+ PR c++/21369
+ * parser.c (cp_parser_elaborated_type_specifier): Don't treat
+ class types as templates if the type is not appearing as part of a
+ type definition or declaration.
+
+2005-10-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/24277
+ * pt.c (instantiate_decl): Call finish_static_data_member_decl for
+ static data members.
+
+2005-10-10 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23437
+ * parser.c (cp_parser_template_argument_list): Do not treat
+ contents of argument list as part of a constant expression.
+
+2005-10-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/24139
+ * decl.c (grokdeclarator): Do not require template parameter lists
+ for explicitly specialized class.
+ * error.c (dump_aggr_type): Do not dump template arguments for
+ non-primary specializations.
+ (dump_function_name): Likewise.
+
+ PR c++/24275
+ * pt.c (instantiate_decl): Instantiate the initializer of
+ a static data member in the namespace containing the class
+ containing the static data member.
+
+2005-10-08 James A. Morrison <phython@gcc.gnu.org>
+
+ PR c++/22172
+ * parser.c (cp_parser_postfix_expression) <RID_TYPENAME>: Treat nontype
+ scopes as nondependent.
+
+2005-10-06 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * call.c (resolve_args): Remove redundant test.
+
+2005-10-05 Paolo Bonzini <bonzini@gnu.org>
+
+ PR tree-optimization/21419
+ PR tree-optimization/24146
+ PR tree-optimization/24151
+
+ * semantics.c (finish_asm_stmt): Call readonly_error if outputs are
+ read-only. Set ASM_VOLATILE_P for asms without outputs.
+
+2005-10-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/23513
+ * call.c (joust): Adjust length count to more_specialized_fn.
+ * pt.c (more_specialized_fn): Cope with non-static member vs
+ non-member.
+
+2005-10-04 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/23125
+ * decl.c (make_rtl_for_nonlocal_decl): Use set_user_assembler_name
+ instead of change_decl_assembler_name.
+
+2005-10-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * error.c (dump_type) <UNKNOWN_TYPE>: Print reworded message.
+
+2005-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17775
+ * repo.c: Include flags.h.
+ (finish_repo): Add -frandom-seed to the arguments.
+
+2005-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22621
+ * parser.c (cp_parser_template_argument): Don't turn "T::f" into
+ "(*this).T::f".
+ * pt.c (convert_nontype_argument): Remove ??? comment.
+
+ PR c++/23840
+ * tree.c (lvalue_p_1): A VA_ARG_EXPR with class type is an lvalue,
+ when class rvalues are lvalues.
+
+2005-09-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16782
+ * decl.c (grokdeclarator): Always pedwarn about overqualified
+ member names.
+
+2005-09-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22147
+ * name-lookup.c (maybe_process_template_type_declaration): Don't
+ treat forward declarations of classes as templates just because
+ we're processing_template_decl.
+ * pt.c (tsubst_decl): Clear DECL_TEMPLATE_INFO for friend
+ functions.
+
+2005-09-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/13764
+ * cp-tree.h (FUNCTION_NEEDS_BODY_BLOCK): New macro.
+ * name-lookup.c (pushdecl_maybe_friend): Check it.
+ * decl.c (begin_function_body): Do nothing if it's false.
+ (finish_function_body): Ditto.
+ (outer_curly_brace_block): New fn.
+ (finish_function): Use it.
+
+2005-09-26 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/15855
+ * decl2.c (do_static_destruction): Remove.
+ (finish_static_initialization_or_destruction): Likewise.
+ (DECL_EFFECTIVE_INIT_PRIORITY): New macro.
+ (NEEDS_GUARD_P): Likewise.
+ (do_static_initialization): Rename to
+ do_static_initialization_or_destruction. Process all
+ initializers/destructors and handle common conditionalizing.
+ (start_static_initialization_or_destruction): Rename to
+ one_static_initialization_or_destruction. Handle only
+ decl-specific conditionalizing.
+ (cp_finish_file): Call do_static_initialization_or_destruction.
+
+2005-09-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/21983
+ * class.c (find_final_overrider): Move diagnostic about no unique final
+ overrider to...
+ (update_vtable_entry_for_fn): ... here.
+
+2005-09-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23993
+ * init.c (integral_constant_value): Use DECL_INTEGRAL_CONSTANT_VAR_P.
+
+2005-09-21 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/23965
+ * call.c (resolve_args): Return error_mark_node on arguments
+ whose TREE_TYPE is error_mark_node.
+
+2005-09-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/23947
+ * rtti.c (get_pseudo_ti_init): Recompute ti pointer after
+ get_tinfo_ptr calls.
+
+2005-09-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23914
+ * parser.c (cp_parser_enclosed_template_argument_list): Make sure
+ skip_evaluation is false when processing template arguments.
+
+ PR c++/21514
+ * pt.c (check_instantiated_args): Treat uses of anonymous types as
+ causing type-deduction failure.
+
+2005-09-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/23357
+ * cp-tree.def (SIZEOF_EXPR, ALIGNOF_EXPR): Change code class to
+ tcc_expression.
+
+2005-09-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23896
+ * pt.c (tsubst_aggr_type): Make sure skip_evaluation is false when
+ processing template arguments.
+
+ * pt.c (check_explicit_instantiation_namespace): Fix typo.
+
+ PR c++/13140
+ * decl.c (check_class_member_definition_namespace): New function.
+ (grokfndecl): Use it.
+ (grokvardecl): Likewise.
+ (grokdecl): Improve documentation.
+ * pt.c (check_explicit_instantiation_namespace): New function.
+ (register_specialization): Call check_specialization_namespace
+ when replacing an implicitly instantiated function.
+ (check_explicit_specialization): Ensure that DECL_CONTEXT is set
+ correctly for namespace-scope specializations.
+ (do_decl_instantiation): Use
+ check_explicit_instantiation_namespace.
+ (do_type_instantiation): Likewise.
+
+2005-09-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/23725
+ * error.c (dump_decl): <USING_DECL case> Use USING_DECL_SCOPE.
+
+2005-09-13 Bastian Blank <waldi@debian.org>
+
+ PR c++/16171
+ * mangle.c (find_substitution): Do not use special substitutions
+ for identifiers not in std::.
+
+2005-09-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23839
+ * typeck.c (cxx_mark_addressable): Only check DECL_HARD_REGISTER
+ for VAR_DECLs.
+
+2005-09-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23842
+ * pt.c (tsubst_default_argument): Do treat default argument
+ expressions as occurring in the context of the function called.
+
+2005-09-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23841
+ * parser.c (cp_parser_primary_expression): Recognize the closing
+ ">" of a template-argument-list after a floating-point literal as
+ the end of a cast expression.
+
+2005-09-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23789
+ * cvt.c (perform_qualification_conversions): Don't create
+ unnecessary NOP_EXPRs.
+ * pt.c (tsubst_template_arg): Use fold_non_dependent_expr.
+
+2005-09-12 Ian Lance Taylor <ian@airs.com>
+
+ PR g++/7874
+ * cp-tree.h (struct lang_decl_flags): Add hidden_friend_p
+ bitfield. Make dummy bitfield one bit smaller.
+ (DECL_HIDDEN_FRIEND_P): Define.
+ (pushdecl_maybe_friend): Declare.
+ (pushdecl_top_level_maybe_friend): Declare.
+ * decl.c (duplicate_decls): Add newdecl_is_friend parameter.
+ Change prototype and all callers. Add assertion that a
+ DECL_ARTIFICIAL FUNCTION_DECL is not DECL_HIDDEN_FRIEND_P. Set
+ DECL_ANTICIPATED and DECL_HIDDEN_FRIEND_P in duplicated decl if
+ appropriate.
+ * name-lookup.c (supplement_binding): Don't ignore a
+ DECL_HIDDEN_FRIEND_P.
+ (pushdecl_maybe_friend): Break out contents of pushdecl. Add
+ is_friend parameter. Set DECL_ANTICIPATED and
+ DECL_HIDDEN_FRIEND_P for a friend function.
+ (pushdecl): Just call pushdecl_maybe_friend.
+ (pushdecl_with_scope): Add is_friend parameter. Change prototype
+ and all callers.
+ (pushdecl_namespace_level): Likewise.
+ (push_overloaded_decl): Likewise. Check DECL_HIDDEN_FRIEND_P as
+ well as DECL_ANTICIPATED when checking for a builtin.
+ (do_nonmember_using_decl): Check DECL_HIDDEN_FRIEND_P as well as
+ DECL_ANTICIPATED when checking for a builtin.
+ (do_nonmember_using_decl): Likewise.
+ (pushdecl_top_level_1): Add is_friend parameter. Change all
+ callers.
+ (pushdecl_top_level_maybe_friend): New function.
+ (remove_hidden_names): New function.
+ (struct arg_lookup): Add args field.
+ (friend_of_associated_class_p): New static function.
+ (arg_assoc_namespace): Ignore hidden functions which are not
+ friends of an associated class of some argument.
+ (lookup_arg_dependent): Remove hidden functions from list passed
+ in. Initialize k.args.
+ * name-lookup.h (remove_hidden_names): Declare.
+ * friend.c (do_friend): Call pushdecl_maybe_friend instead of
+ pushdecl.
+ * call.c (add_function_candidate): Change DECL_ANTICIPATED test to
+ an assertion, with a check for DECL_HIDDEN_FRIEND_P.
+ (build_new_function_call): Add koenig_p parameter. Change
+ prototype and callers.
+ * pt.c (register_specialization): Add is_friend parameter. Change
+ all callers.
+ (push_template_decl_real): Change is_friend parameter to bool.
+ Change prototype and all callers.
+ (tsubst_friend_class): Call pushdecl_top_level_maybe_friend
+ instead of pushdecl_top_level.
+
+2005-09-11 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (build_anon_union_vars): Copy attributes from the base addr.
+ * pt.c (tsubst_decl): Substitute in DECL_VALUE_EXPR.
+
+2005-09-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * parser.c (cp_parser_translation_unit): Simplify. The while-block
+ was actually executed at most once.
+
+2005-09-09 Richard Henderson <rth@redhat.com>
+
+ PR debug/20998
+ * cp-tree.def (ALIAS_DECL): Remove.
+ * cp-lang.c (cp_init_ts): Remove support for it.
+ * error.c (dump_decl): Likewise.
+ * name-lookup.c (pushdecl): Likewise.
+ * semantics.c (finish_id_expression): Likewise.
+ * decl2.c (build_anon_union_vars): Use a VAR_DECL with
+ DECL_VALUE_EXPR instead.
+
+2005-09-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22252
+ * decl.c (start_preparsed_function): Do not pay attention to
+ #pragma interface for implicitly-defined methods.
+ * decl2.c (cp_finish_file): Do not complain about uses of inline
+ functions that have bodies, even if we decided not to emit the
+ body in this translation unit.
+ * semantics.c (note_decl_for_pch): Do not mess with linkage.
+ (expand_or_defer_fn): Make inline, non-template functions COMDAT
+ at this point.
+
+2005-09-08 Richard Henderson <rth@redhat.com>
+
+ PR debug/23190
+ * decl.c (wrapup_globals_for_namespace): Call
+ emit_debug_global_declarations.
+ * decl2.c (cp_finish_file): Likewise.
+
+2005-09-08 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23691
+ * decl2.c (mark_used): Instantiate static data members initialized
+ by constants, even in a template.
+
+2005-09-08 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR obj-c++/16816
+ * parser.c (cp_parser_objc_selector_expression): Treat CPP_SCOPE as
+ two CPP_COLON.
+
+2005-09-07 Richard Guenther <rguenther@suse.de>
+
+ * cp-gimplify.c (cp_gimplify_expr): Create empty CONSTRUCTOR
+ for EMPTY_CLASS_EXPR.
+
+2005-09-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/23075
+ * typeck.c (check_return_expr): Add no_warning argument. Set
+ *no_warning to true if "return-statement with no value, in function
+ returning" warning has been issued.
+ * cp-tree.h (check_return_expr): Adjust prototype.
+ * semantics.c (finish_return_stmt): Set TREE_NO_WARNING if
+ check_return_expr set *no_warning to true.
+
+2005-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (rvalue): New function.
+ * call.c (build_conditional_expr): Use it.
+ * init.c (build_new_1): Likewise.
+ * rtti.c (build_dynamic_cast_1): Likewise.
+ * tree.c (rvalue): New function.
+ * typeck.c (build_unary_op): Use it.
+ (build_static_cast_1): Likewise.
+
+ PR c++/9782
+ * init.c (build_new_1): Make sure the entire array type is
+ complete, not just its element types.
+
+2005-09-06 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * decl.c (check_elaborated_type_specifier): Remove redundant check.
+
+2005-09-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/23056
+ * typeck.c (ignore_overflows): New helper function.
+ (build_static_cast_1): Use it.
+
+2005-09-06 Kazu Hirata <kazu@codesourcery.com>
+
+ * cp-tree.h, decl.c, decl2.c, semantics.c: Fix comment typos.
+ Follow spelling conventions.
+
+2005-09-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23667
+ * pt.c (tsubst_decl): Clear DECL_TEMPLATE_INSTANTIATED when
+ copying a VAR_DECL.
+
+2005-09-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21440
+ * semantics.c (finish_stmt_expr_expr): Add an explicit
+ initialization to the last statement in the statement-expression.
+ * (finish_stmt_expr): Adjust accordingly.
+
+2005-09-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23699
+ * decl2.c (mark_used): Always instantiate static data members
+ initialized by constant expressions.
+ * pt.c (instantiate_decl): Instantiate the initializers for static
+ data members initialized by constant expressions.
+
+ PR c++/21687
+ * semantics.c (expand_or_defer_fn): Do not call ggc_collect when
+ finishing processing for a template function in a local class.
+ Revert:
+ 2005-09-02 Mark Mitchell <mark@codesourcery.com>
+ * parser.c (cp_parser_class_specifier): Push/pop GC contexts
+ around functions in local classes.
+
+2005-09-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21687
+ * parser.c (cp_parser_class_specifier): Push/pop GC contexts
+ around functions in local classes.
+
+2005-08-31 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR obj-c++/23640
+ * decl2.c (cp_finish_file): If this is obj-c++ and we need a static
+ init, call generate_ctor_or_dtor_function.
+
+2005-08-31 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/13377
+ * parser.c (cp_parser_lookup_name): Pass LOOKUP_COMPLAIN to
+ lookup_name_real on final parse.
+
+2005-08-31 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/23639
+ * semantics.c (qualified_name_lookup_error): Do not complain again
+ on invalid scope.
+
+2005-08-30 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/23586
+ * parser.c (cp_parser_namespace_name): Move diagnostic for
+ invalid namespace-name to here from ...
+ * name-lookup.c (do_namespace_alias): ... here and ...
+ (do_using_directive): ... here. Remove dead code.
+
+2005-08-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/23099
+ * cp-tree.h (saved_scope): Add skip_evaluation.
+ * decl.c (start_decl): Use DECL_INITIALIZED_IN_CLASS_P, not
+ DECL_INITIAL, to determine whether or not a static data member was
+ initialized in the class-specifier.
+ (cp_finish_decl): Add comment.
+ * init.c (integral_constant_value): Subtitute into the
+ initializers for static data members in templates.
+ * name-lookup.c (push_to_top_level): Save skip_evaluation.
+ (pop_from_top_level): Restore it.
+ * pt.c (instantiate_class_template): Do not substitute into the
+ intializers of static data members when instantiating a class.
+ (regenerate_decl_from_template): Simplify.
+ (instantiate_decl): Tidy. Substitute into the initializer for a
+ static data member even when the definition of the data member is
+ not available.
+
+2005-08-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19004
+ * pt.c (uses_template_parms): Handle IDENTIFIER_NODE.
+ (type_dependent_expression_p): Allow BASELINKs whose associated
+ functions are simply a FUNCTION_DECL.
+
+ PR c++/23491
+ * cp-tree.h (build_vec_init): Adjust prototype.
+ * init.c (perform_member_init): Adjust call to build_vec_init.
+ (build_aggr_init): Likewise.
+ (build_new_1): Do not call build_default_init for array types.
+ (build_vec_init): Add explicit_default_init_p parameter. Perform
+ default initialization of vector elements when set.
+ * typeck.c (build_modify_expr): Adjust call to build_vec_init.
+
+2005-08-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20817
+ * typeck.c (build_x_unary_op): Make sure OFFSET_REF is not for a
+ ->*.
+
+2005-08-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/22454
+ * parser.c (cp_lexer_peek_nth_token): Relax assert.
+
+2005-08-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/23044
+ * pt.c (tsubst_qualified_id): A SCOPE_REF can still remain.
+
+2005-08-22 James E Wilson <wilson@specifix.com>
+
+ PR tree-optimization/23426
+ * decl.c (grokdeclarator): Use TYPE_SIZE_UNIT not TYPE_SIZE for
+ array size check.
+
+2005-08-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/22233
+ * pt.c (push_template_decl_real): Return error_mark_node if the
+ number of template parameters does not match previous definition.
+
+2005-08-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/23089
+ * decl.c (require_complete_types_for_parms): Mark incomplete types
+ as invalid.
+
+2005-08-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * parser.c (cp_parser_nth_token_starts_template_argument_list_p):
+ Fix typo in leading comment.
+
+2005-08-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * name-lookup.c, ptree.c: Delete HOST_PTR_PRINTF.
+
+2005-08-15 Fariborz Jahanian <fjahanian@apple.com>
+
+ * cp-tree.h (can_convert_arg, fn_type_unification): New argument.
+ * call.c (add_template_candidate_real): Pass down 'flags' to
+ fn_type_unification.
+ (can_convert_arg): New 'flags' argument. Pass it to call to
+ implicit_conversion instead of LOOKUP_NORMAL.
+ (can_convert): Add LOOKUP_NORMAL to call to can_convert_arg.
+ * class.c (resolve_address_of_overloaded_function): Ditto.
+ (resolve_address_of_overloaded_function): Ditto.
+ * decl.c (reshape_init, check_default_argument): Ditto.
+ * typeck.c (build_ptrmemfunc): Ditto.
+ * pt.c (type_unification_real): Add 'flags' argument.
+ (fn_type_unification): Pass 'flags' to type_unification_real.
+ (type_unification_real): Pass new 'flags' argument to call to
+ can_convert_arg.
+
+2005-08-12 Giovanni Bajo <giovannibajo@libero.it>
+ Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21799
+ PR c++/8271
+ * pt.c (unify) <METHOD_TYPE>: Check this-pointer cv-qualifiers
+ explicitly.
+
+2005-08-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21799
+ Revert my 2005-07-08 patch
+ * pt.c (type_unification_real): Remove is_method_argument and
+ assoicated checks.
+ (fn_type_unification, unify): Adjust type_unification_real calls.
+
+2005-08-11 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/23266
+ * decl2.c (grokfield): Check that method is not static before
+ marking it as pure.
+
+2005-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/23219
+ * name-lookup.c (pushtag): Process the template type before
+ altering the identifier lookup fields. Remove unreachable code
+ creating an empty stub decl.
+
+2005-08-10 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/20646
+ * decl.c (grokdeclarator): Reset storage_class after error.
+
+2005-08-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/22508
+ * init.c (build_new_1): Check for empty candidate list.
+
+2005-08-06 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/23191
+ * pt.c (tsubst) <case METHOD_TYPE>: Check for error_mark_node
+ before calling build_exception_variant.
+
+2005-08-06 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/19498
+ * pt.c (tsubst_decl) <case TEMPLATE_DECL>: Return ERROR_MARK_NODE
+ if substitution of template args did not succeed.
+
+2005-08-06 Michael Matz <matz@suse.de>
+
+ * method.c (use_thunk): Call init_insn_lengths.
+
+2005-08-05 James A. Morrison <phython@gcc.gnu.org>
+
+ PR c++/22514
+ * name-lookup.c (cp_emit_debug_info_for_using): Do nothing if
+ sorrycount or errorcount are nonzero.
+
+2005-08-05 Mark Mitchell <mark@codesourcery.com>
+
+ * name-lookup.c (pushtag): Remove accidental commit from:
+ 2004-12-21 Mark Mitchell <mark@codesourcery.com>
+ PR c++/19063
+ * decl.c (grokdeclarator): Return error_mark_node, not
+ void_type_node, to indicate errors.
+ * parser.c (cp_parser_template_parameter_list): Robustify.
+ (cp_parser_template_parameter): Likewise.
+
+2005-08-01 Kazu Hirata <kazu@codesourcery.com>
+
+ * class.c, decl.c, name-lookup.c, pt.c, typeck.c, typeck2.c:
+ Fix comment typos.
+
+2005-07-29 Kazu Hirata <kazu@codesourcery.com>
+
+ * method.c: Fix a comment typo.
+
+2005-07-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22545
+ * call.c (add_builtin_candidate): Adjust for changes in
+ representation of pointer-to-member types.
+
+2005-07-28 Mike Stump <mrs@apple.com>
+
+ * pt.c (check_explicit_specialization): Add visibility logic.
+ (lookup_template_class): Likewise.
+ (instantiate_class_template): Likewise.
+
+2005-07-27 Devang Patel <dpatel@apple.com>
+
+ * name-lookup.c (pushtag): Do no set DECL_IGNORED_P bit.
+
+2005-07-25 Ian Lance Taylor <ian@airs.com>
+
+ * ptree.c (cxx_print_identifier): Print a leading space if the
+ indent level is 0.
+
+2005-07-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (convert_for_arg_passing): Check function pointers when
+ -Wmissing-format-attribute is activated.
+ * typeck.c (convert_for_assignment): Likewise.
+
+2005-07-22 Manfred Hollstein <mh@suse.com>
+
+ * parser.c (cp_parser_declaration): Fix unitialised warnings.
+
+2005-07-21 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * class.c (build_base_path): Fix typo.
+
+2005-07-21 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR C++/22358
+ * class.c (build_base_path): Convert BINFO_OFFSET to the correct type.
+
+2005-07-21 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * call.c: Fix comment typo(s).
+ * cxx-pretty-print.h: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+
+2005-07-20 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/2922
+ * semantics.c (perform_koenig_lookup): For dependent calls, just
+ return the set of functions we've found so far. Later, it will be
+ augmented by those found through argument-dependent lookup.
+ * name-lookup.c (lookup_arg_dependent): Implement DR 164 by removing
+ the optimization that skips namespaces where the functions were
+ originally found.
+
+2005-07-20 Giovanni Bajo <giovannibajo@libero.it>
+
+ Make CONSTRUCTOR use VEC to store initializers.
+ * call.c (convert_default_arg): Update call to digest_init.
+ * class.c (dump_class_hierarchy, dump_array): Update to cope with
+ VEC in CONSTRUCTOR_ELTS.
+ * cp-tree.h (EMPTY_CONSTRUCTOR_P): Likewise.
+ (finish_compound_literal, digest_init): Update declaration.
+ * decl.c (struct reshape_iter): New data type.
+ (reshape_init_array): Rename to...
+ (reshape_init_array_1): Update to cope with VEC in CONSTRUCTOR_ELTS.
+ (reshape_init): Rewrite from scratch. Split parts into...
+ (reshape_init_array, reshape_init_vector, reshape_init_class,
+ reshape_init_r): New functions.
+ (check_initializer): Update call to reshape_init. Remove obsolete
+ code.
+ (initialize_artificial_var, cp_complete_array_type): Update to cope
+ with VEC in CONSTRUCTOR_ELTS.
+ * decl2.c (grokfield): Update calls to digest_init.
+ (mark_vtable_entries): Update to cope with VEC in CONSTRUCTOR_ELTS.
+ * error.c (dump_expr_init_vec): New function.
+ (dump_expr): Use dump_expr_init_vec.
+ * init.c (build_zero_init, build_vec_init): Update to cope with VEC
+ in CONSTRUCTOR_ELTS.
+ (expand_default_init): Update call to digest_init.
+ * parser.c (cp_parser_postfix_expression): Use a VEC for the
+ initializers.
+ (cp_parser_initializer_list): Build a VEC of initializers.
+ * pt.c (tsubst_copy, tsubst_copy_and_build): Update to cope with VEC
+ in CONSTRUCTOR_ELTS.
+ * rtti.c (tinfo_base_init, generic_initializer, ptr_initializer,
+ ptm_initializer, class_initializer, get_pseudo_ti_init): Use
+ build_constructor_from_list instead of build_constructor.
+ * semantics.c (finish_compound_literal): Update call to digest_init.
+ * tree.c (stabilize_init): Update to cope with VEC in
+ CONSTRUCTOR_ELTS.
+ * typeck.c (build_ptrmemfunc1): Likewise.
+ * typeck2.c: (cxx_incomplete_type_error, split_nonconstant_init_1):
+ Likewise.
+ (store_init_value): Use build_constructor_from_list and update call
+ to digest_init.
+ (digest_init): Rewrite.
+ (process_init_constructor): Rewrite from scratch. Split into...
+ (process_init_constructor_array, picflag_from_initializer,
+ process_init_constructor_record, process_init_constructor_union):
+ New functions.
+ (PICFLAG_ERRONEOUS, PICFLAG_NOT_ALL_CONSTANT, PICFLAG_NOT_ALL_SIMPLE):
+ New macros.
+ (build_functional_cast): Use build_constructor_from_list instead of
+ build_constructor.
+
+2005-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22263
+ * cp-tree.h (instantiate_decl): Change prototype.
+ * decl2.c (mark_used): Adjust accordingly.
+ * pt.c (do_decl_instantiation): Likewise.
+ (instantiate_class_member): Likewise.
+ (instantiate_decl): Rename undefined_ok as expl_inst_class_mem_p.
+ Clear DECL_INTERFACE_KNOWN for an explicitly instantiated template
+ that has no definition available.
+ (instantiate_pending_templates): Adjust call to instantiate_decl.
+
+2005-07-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22139
+ * cp-tree.h (DECL_TEMPLATE_INFO): Improve documentation.
+ * decl.c (duplicate_decls): Re-register template specializations
+ for functions that have DECL_TEMLPLATE_INFO, even if they do not
+ have DECL_TEMPLATE_INSTANTIATION set.
+
+2005-07-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (diagnostic_fn_t): New.
+ (build_temp, convert_like_real): Use diagnostic_fn_t.
+
+2005-07-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22204
+ * repo.c (repo_emit_p): Robustify.
+
+2005-07-14 Daniel Berlin <dberlin@dberlin.org>
+
+ Fix PR c++/22452
+ * tree.c (decl_linkage): Don't check DECL_COMDAT on CONST_DECL.
+
+2005-07-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22132
+ * call.c (implicit_conversion): Add c_cast_p parameter.
+ (standard_conversion): Likewise. Allow conversions between
+ differently-qualified pointer types when performing a C-style
+ cast.
+ (add_function_candidate): Adjust callee.
+ (build_builtin_candidate): Likewise.
+ (build_user_type_conversion_1): Likewise.
+ (conditional_conversion): Likewise.
+ (can_convert_arg): Likewise.
+ (can_convert_arg_bad): Likewise.
+ (perform_implicit_conversion): Likewise.
+ * cp-tree.h (comp_ptr_ttypes_const): Declare.
+ * typeck.c (comp_ptr_ttypes_const): Give it external linkage.
+ Return bool.
+
+2005-07-12 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+ Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20172
+ * pt.c (tsubst_template_parms): Check for invalid non-type
+ parameters.
+
+2005-07-09 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * cp-lang.c (shadowed_var_for_decl, decl_shadowed_for_var_lookup,
+ decl_shadowed_for_var_insert): Move over to cp-objcp-common.c.
+ (cp_init_ts): Call init_shadowed_var_for_decl.
+ Remove include of gt-cp-cp-lang.h.
+ * cp-objcp-common.c (shadowed_var_for_decl,
+ decl_shadowed_for_var_lookup, decl_shadowed_for_var_insert): Moved from
+ cp-lang.c.
+ (init_shadowed_var_for_decl): New function to initialize
+ shadowed_var_for_decl.
+ Include gt-cp-cp-objcp-common.h.
+ * Make-lang.in (gt-cp-lang.h): Remove.
+ (gt-cp-cp-objcp-common.h): Add.
+ (cp/cp-lang.o): Remove dependancy on gt-cp-lang.h.
+ (cp/cp-objcp-common.o): Add dependancy on gt-cp-cp-objcp-common.h.
+ * config-lang.in (gtfiles): Remove cp-lang.c and Add cp-objcp-common.c.
+ * cp-tree (init_shadowed_var_for_decl): Add prototype.
+
+2005-07-08 Daniel Berlin <dberlin@dberlin.org>
+
+ * Make-lang.in: Add gt-cp-lang.h.
+ (cp-lang.o): Ditto.
+ * class.c (create_vtable_ptr): Stop setting DECL_ASSEMBLER_NAME on
+ the field.
+ * config-lang.in: Add cp-lang.c to gtfiles.
+ * cp-lang.c: Include hashtab.h.
+ (cp_init_ts): New function.
+ (LANG_HOOK_INIT_TS): Use macro.
+ (decl_shadowed_for_var_lookup): New function.
+ (decl_shadowed_for_var_insert): Ditto.
+ * cp-tree.h (THUNK_FUNCTION_CHECK): Use decl_common.
+ (NON_THUNK_FUNCTION_CHECK): Ditto.
+ (DECL_NAMESPACE_ASSOCIATIONS): Use decl_non_common.
+ (DECL_INIT_PRIORITY): Ditto.
+ (DECL_HAS_SHADOWED_FOR_VAR_P): Ditto.
+ (DECL_SHADOWED_FOR_VAR): Use hashtable.
+ (SET_DECL_SHADOWED_FOR_VAR): Ditto.
+ * decl.c (duplicate_decls): Update for new/updated structures.
+ (poplevel): Use SET_DECL_SHADOWED_FOR_VAR.
+ * decl2.c (start_static_initialization_or_destruction): Deal with
+ priority.
+ * pt.c (tsubst_decl): Check TS_DECL_WRTL before doing
+ SET_DECL_RTL.
+ * tree.c (handle_init_priority_attribute): Handle priority.
+
+2005-07-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21799
+ * pt.c (type_unification_real): Add is_method argument. Use it
+ for this pointer unification.
+ (fn_type_unification): Adjust type_unification_real call.
+ (unify): Likewise.
+
+2005-07-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (type_unification_real): Remove allow_incomplete argument.
+ Remove unreachable code.
+ (fn_type_unification): Adjust call to type_unification_real.
+ (unify): Likewise.
+
+2005-07-05 Paolo Bonzini <bonzini@gnu.org>
+
+ * Makefile.in (class.o, decl2.o): Adjust dependencies.
+ * class.c: Include tree-dump.h.
+ * decl2.c: Include tree-dump.h.
+
+2005-07-02 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * dump.c: Use dump_string_field.
+
+2005-07-03 Joseph S. Myers <joseph@codesourcery.com>
+
+ * cp-tree.h (GCC_DIAG_STYLE): #undef before defining. Change
+ minimum GCC version for format checking to 4.1.
+
+2005-07-02 Kazu Hirata <kazu@codesourcery.com>
+
+ * Make-lang.in (cc1plus-checksum.c): Use
+ build/genchecksum$(build_exeext), not build/genchecksum$(exeext).
+
+2005-07-02 Joseph S. Myers <joseph@codesourcery.com>
+
+ * name-lookup.c, parser.c: Use %q, %< and %> to quote in
+ diagnostics.
+
+2005-07-02 Zack Weinberg <zack@codesourcery.com>
+ Joseph S. Myers <joseph@codesourcery.com>
+
+ * error.c (location_of): Add comment.
+ (locate_error, cp_error_at, cp_warning_at, cp_pedwarn_at): Remove.
+ * cp-tree.h (cp_error_at, cp_warning_at, cp_pedwarn_at): Remove.
+ * call.c, class.c, decl.c, decl2.c, friend.c, init.c,
+ name-lookup.c, parser.c, pt.c, search.c, semantics.c, typeck.c,
+ typeck2.c: Use '+' flag instead of %J, cp_error_at, cp_warning_at
+ or cp_pedwarn_at. Mark up some diagnostic strings with N_.
+
+2005-06-30 Daniel Berlin <dberlin@dberlin.org>
+
+ * decl.c (require_complete_types_for_parms): Call relayout_decl
+ instead of layout_decl.
+
+2005-06-30 Zack Weinberg <zack@codesourcery.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * cp-lang.c: No need to include cxx-pretty-print.h.
+ * error.c (cp_printer): Update signature. No need to process
+ flags.
+ (print_instantiation_partial_context): Output last newline
+ with pp_base_newline.
+ * Make-lang.in: Update dependencies.
+
+2005-06-30 Steven Bosscher <stevenb@suse.de>
+
+ * decl.c (start_decl): Replace DECL_THREAD_LOCAL with
+ DECL_THREAD_LOCAL_P.
+ (cp_finish_decl): Likewise.
+ (grokvardecl): Set the default DECL_TLS_MODEL here.
+
+2005-06-28 Joseph S. Myers <joseph@codesourcery.com>
+
+ * cvt.c (ocp_convert): Use invalid_conversion hook.
+ * typeck.c (build_binary_op): Use invalid_binary_op hook.
+ (build_unary_op): Use invalid_unary_op hook.
+
+2005-06-28 Paul Brook <paul@codesourcery.com>
+
+ * Make-lang.in (cp/except.o): Depend on $(TARGET_H)
+ * except.c: Include target.h.
+ (init_exception_processing): Initialize unwind_resume_libfunc.
+ * doc/tm.texi: Document TARGET_ASM_TTYPE
+
+2005-06-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (build_over_call): Pass in named argument list to
+ `check_function_arguments'.
+ * typeck.c (build_function_call): Likewise.
+
+2005-06-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (lang_check_failed): Add noreturn attribute.
+
+2005-06-25 Kelley Cook <kcook@gcc.gnu.org>
+
+ * all files: Update FSF address in copyright headers.
+
+2005-06-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/19317
+ * semantics.c (simplify_aggr_init_expr): Use
+ CALL_EXPR_RETURN_SLOT_OPT, not CALL_EXPR_HAS_RETURN_SLOT_ADDR.
+
+2005-06-23 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * pt.c (register_specialization): Remove superfluous assertion.
+
+2005-06-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (convert_like_real): Add format attribute.
+ * typeck.c (check_for_casting_away_constness,
+ build_static_cast_1): Likewise.
+ * typeck2.c (readonly_error, cxx_incomplete_type_diagnostic):
+ Likewise.
+
+2005-06-17 Geoffrey Keating <geoffk@apple.com>
+
+ PR c++/17413
+ * pt.c (type_unification_real): Apply template type deduction even
+ to procedure parameters that are not dependent on a template
+ parameter.
+
+2005-06-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (get_tinfo_decl): Avoid caching tinfo_descs when it might
+ change.
+ (create_pseudo_type_info): First parameter is an int.
+
+2005-06-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20678
+ * error.c (dump_expr) <COMPONENT_REF case>: Check DECL_NAME is not
+ null.
+
+ * Make-lang.in: Reformat some long lines.
+ (gt-cp-rtti.h): New target.
+ (cp/rtti.o): Add dependency.
+ * config-lang.in (gtfiles): Add cp/rtti.c.
+ * cp-tree.h (CPTI_TI_DESC_TYPE, CPTI_BLTN_DESC_TYPE,
+ CPTI_PTR_DESC_TYPE, CPTI_ARY_DESC_TYPE, CPTI_FUNC_DESC_TYPE,
+ CPTI_ENUM_DESC_TYPE, CPTI_CLASS_DESC_TYPE,
+ CPTI_SI_CLASS_DESC_TYPE, CPTI_VMI_CLASS_DESC_TYPE,
+ CPTI_PTM_DESC_TYPE, CPTI_BASE_DESC_TYPE): Remove.
+ (ti_desc_type_node, bltn_desc_type_node, ptr_desc_type_node,
+ ary_desc_type_node, func_desc_type_node, enum_desc_type_node,
+ class_desc_type_node, si_class_desc_type_node,
+ vmi_class_desc_type_node, ptm_desc_type_node,
+ base_desc_type_node): Remove.
+ * decl.c: Adjust documentation of global trees.
+ * rtti.c (TINFO_PSEUDO_TYPE, TINFO_VTABLE_DECL,
+ TINFO_REAL_NAME): Remove.
+ (struct tinfo_s): New.
+ (enum tinfo_kind): New.
+ (tinfo_descs): New.
+ (get_tinfo_decl): Adjust use of tinfo descriptor.
+ (tinfo_base_init, generic_initializer, ptr_initializer,
+ ptm_initializer, class_initializer): Likewise.
+ (get_pseudo_ti_init): Take descriptor index. Adjust.
+ (create_pseudo_type_info): Likewise.
+ (get_pseudo_ti_desc): Return descriptor index. Adjust.
+ (create_tinfo_types): Adjust use of create_pseudo_type_info.
+ (emit_tinfo_decl): Adjust use of tinfo descriptor.
+
+2005-06-14 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (grokdeclarator): Only check TREE_OVERFLOW on INTEGER_CST.
+
+2005-06-13 Geoffrey Keating <geoffk@apple.com>
+
+ * Make-lang.in (c++.install-man): Doesn't really depend on installdirs.
+ (rule for installing g++.1 manpage): Does depend on installdirs.
+
+2005-06-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20789
+ * decl.c (cp_finish_decl): Clear runtime runtime initialization if
+ in-class decl's initializer is bad.
+
+ PR c++/21929
+ * parser.c (struct cp_parser): Document that scope could be
+ error_mark.
+ (cp_parser_diagnose_invalid_type_name): Cope with error_mark for
+ scope.
+ (cp_parser_nested_name_specifier): Return NULL_TREE on error.
+ (cp_parser_postfix_expression): Deal with null or error_mark
+ scope.
+ (cp_parser_elaborated_type_specifier): Adjust
+ cp_parser_nested_name_specifier call.
+
+ * parser (cp_parser_skip_to_end_of_block_or_statement): Cleanup.
+
+2005-06-12 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/21930
+ * error.c (dump_expr): UNARY_PLUS_EXPR need not handle void types.
+ Treat CONVERT_EXPR identically to NOP_EXPR.
+
+2005-06-10 Aldy Hernandez <aldyh@redhat.com>
+
+ PR c++/10611
+ * cvt.c (build_expr_type_conversion): Same.
+ * typeck.c (build_binary_op): Handle vectors.
+ (common_type): Same.
+ (type_after_usual_arithmetic_conversions): Same.
+
+2005-06-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/19497
+ * cp-tree.def (USING_DECL): Update documentation.
+ * cp-tree.h (DECL_DEPENDENT_P): New.
+ (USING_DECL_DECLS, USING_DECL_SCOPE): New.
+ * class.c (handle_using_decl): Move most of the processing to ...
+ * name-lookup.c (do_class_using_decl): ... here. Make stricter.
+ (push_using_decl): Use USING_DECL_SCOPE.
+ (cp_emit_debug_info_for_using): Make extern.
+ * cxx-pretty-print.c (pp_cxx_statement) <USING_DECL case>: Adjust.
+ * name-lookup.h (cp_emit_debug_info_for_using): Declare.
+ * pt.c (tsubst_decl) <USING_DECL case>: Use do_class_using_decl
+ when tsubsting.
+ (tsubst_expr): Use USING_DECL_SCOPE.
+ * search.c (lookup_field_1): Use DECL_DEPENDENT_P.
+ * semantics.c (finish_member_declaration): Likewise.
+
+2005-06-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/19894
+ * pt.c (tsubst): Reject pointer-to-member of type void.
+
+ PR c++/20563
+ * parser.c (cp_parser_label_declaration): Deal with invalid/missing
+ identifiers.
+
+2005-06-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.def (DEFAULT_ARG): Adjust documentation.
+ * cp-tree.h (DEFARG_INSTANTIATIONS): New.
+ (struct tree_default_arg): Add instantiations member.
+ * parser.c (cp_parser_late_parsing_default_args): Adjust to use a
+ VEC.
+ * pt.c (tsubst_arg_types): Likewise.
+
+ * parser.c (cp_parser_late_parsing_default_args): Fix overeager
+ assert in previous patch.
+
+2005-06-06 Jakub Jelinek <jakub@redhat.com>
+
+ * error.c (locate_error): Use gmsgid instead of msgid for argument
+ name.
+ (cp_error_at, cp_warning_at, cp_pedwarn_at): Likewise.
+
+2005-06-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR 21903
+ * cp-tree.def (DEFAULT_ARG): Document TREE_CHAIN use.
+ * parser.c (cp_parser_late_parsing_default_args): Propagate parsed
+ argument to any early instantiations.
+ * pt.c (tsubst_arg_types): Chain early instantiation of default arg.
+
+ PR c++/20637
+ * cp-tree.h (add_method): Add using_decl parameter.
+ * class.c (add_method): Add using_decl parameter. Adjust error
+ messages.
+ (handle_using_decl): Pass the using decl to add_method.
+ (clone_function_decl): Adjust add_member calls.
+ * decl2.c (check_classfn): Likewise.
+ * method.c (lazily_declare_fn): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+
+ * method.c (synthesize_method): Use inform, not warning.
+
+2005-06-06 Hans-Peter Nilsson <hp@axis.se>
+
+ * config-lang.in (target_libs): Remove target-gperf.
+
+2005-06-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21619
+ * cp-tree.h (DECL_IS_BUILTIN_CONSTANT_P): New macro.
+ * parser.c (cp_parser_postfix_expression): Allow non-constant
+ expressions as arguments to __builtin_constant_p.
+ * tree.c (builtin_valid_in_constant_expr_p): Use
+ DECL_IS_BUILTIN_CONSTANT_P.
+
+2005-06-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21853
+ * typeck.c (casts_away_constness_r): Do not drop cv-qualifiers on
+ the pointed-to type for a pointer-to-member.
+
+ PR c++/21336
+ * cp-tree.h (grok_op_properties): Remove friendp parameter.
+ * decl.c (grokfndecl): Adjust call.
+ (grok_op_properties): Determine the class of which the function is
+ a member by looking at its DECL_CONTEXT, not current_class_type.
+ * pt.c (tsubst_decl): Adjust call to grok_op_properties.
+
+2005-06-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (synthesize_method): Add addtional arg to warning call.
+
+ PR c++/21280
+ * Make-lang.in (method.o): Add diagnostic.h
+ * decl.c (start_preparsed_function): Use decl's location for file
+ info.
+ * decl2.c (cp_finish_file): Set input_location before synthesizing
+ a function.
+ (mark_used): When deferring a synthesized function, save current
+ location. Do not set function's location when actually
+ synthesizing it.
+ * method.c: #include diagnostic.h.
+ (synthesize_method): Set the functions source location. Show
+ needed location if errors are emitted.
+
+ * decl.c (start_decl): Simplify specialization handling. Remove
+ unneeded CLASSTYPE_TEMPLATE_INSTANTIATION check.
+ * mangle.c (discriminator_for_local_entity): Use VEC_index.
+
+ PR c++/20350
+ * decl.c (duplicate_decls): Copy all of DECL_USE_TEMPLATE.
+
+ PR c++/21151
+ * name-lookup.c (pushtag): Push local class even in a template.
+
+2005-05-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21165
+ * init.c (integral_constant_value): Check the type of the
+ initializer, not the decl.
+
+2005-05-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21784
+ * name-lookup.c (do_nonmember_using_decl): Ignore builtin
+ functions, even when the used name is not a function.
+
+2005-05-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * operators.def, optimize.c: Update copyright.
+
+2005-05-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21210
+ * call.c (standard_conversion): Permit conversions to complex
+ types if conversion to the corresponding scalar type would be
+ permitted.
+
+ PR c++/21340
+ * method.c (implicitly_declare_fn): Clear processing_template_decl
+ when generating implicit declaration.
+
+2005-05-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21614
+ * typeck.c (get_member_function_from_ptrfunc): Do not attempt
+ conversions to base classes of incomplete types.
+
+2005-05-27 Ian Lance Taylor <ian@airs.com>
+
+ * semantics.c (add_stmt): Add C++ frontend specific version.
+ * cp-tree.h (STMT_IS_FULL_EXPR_P): Define.
+ (stmts_are_full_exprs_p): Declare.
+
+2005-05-27 Roger Sayle <roger@eyesopen.com>
+ Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * cp-tree.def (UNARY_PLUS_EXPR): New C++ unary tree code.
+ * parser.c (cp_parser_unary_expression): Use UNARY_PLUS_EXPR instead
+ of CONVERT_EXPR.
+ (cp_parser_unary_expression): Likewise.
+ * typeck.c (build_unary_op): Likewise.
+ * call.c (add_builtin_candidate, build_new_op): Likewise.
+ * error.c (dump_expr): Likewise.
+ * pt.c (tsubst_copy, tsubst_copy_and_build): Likewise.
+ * decl.c (ambi_op_p, grok_op_properties): Likewise.
+ * dump.c (dump_op): Likewise.
+ * lex.c (init_operators): Likewise.
+ * operators.def ("+"): Likewise.
+ * cp-gimplify.c (cp_gimplify_expr): Handle UNARY_PLUS_EXPR like a
+ conversion, if the result and argument types differ.
+ * tree.c (fold_if_not_in_template): Fold UNARY_PLUS_EXPR much
+ like a NOP_EXPR when !processing_template_decl.
+
+ * cxx-pretty-print.c (pp_cxx_cast_expression): Prototype.
+ (pp_cxx_unary_expression): Handle new UNARY_PLUS_EXPR tree code.
+
+2005-05-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21455
+ * typeck.c (get_delta_difference): Cope with incomplete but equal
+ classes. Reorder if.
+
+ PR c++/21681
+ * parser.c (cp_parser_late_parsing_for_member): Disable access
+ checking for template functions.
+
+2005-05-26 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/21768
+ * pt.c (redeclare_class_template): Change error message according
+ to coding conventions.
+
+2005-05-26 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * call.c (build_op_delete_call): Fix quoting in error message.
+
+2005-05-25 Richard Henderson <rth@redhat.com>
+
+ PR libgcj/21692
+ * cp-tree.h (make_alias_for): Declare.
+ * decl2.c (build_java_method_aliases): New.
+ (cp_finish_file): Call it.
+ * method.c (make_alias_for): Split out from ...
+ (make_alias_for_thunk): ... here.
+
+2005-05-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/21686
+ * semantics.c (finish_id_expression): Fix quoting in error message.
+
+2005-05-25 DJ Delorie <dj@redhat.com>
+
+ * decl.c (duplicate_decls): Move warning control from if() to
+ warning(OPT_*).
+ * name-lookup.c (parse_using_directive): Likewise.
+ * parser.c (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ * tree.c (handle_com_interface_attribute): Likewise.
+
+2005-05-24 Ziemowit Laski <zlaski@apple.com>
+
+ * class.c (layout_class_type): Do not issue C++ ABI warnings
+ for ObjC structs.
+ * decl.c (objc_mark_locals_volatile): Streamline by calling
+ objc_volatilize_decl().
+ * parser.c (cp_parser_objc_message_expression): Allow simple
+ type specifiers (instead of merely type names) as message
+ receivers.
+ * pt.c (template_args_equal): Do not call objc_comptypes().
+ * typeck.c (composite_pointer_type): If both pointers are
+ ObjC-esque, arbitrarily choose the first; do not call
+ objc_comptypes().
+ (comptypes): Do not call objc_comptypes().
+ (convert_for_assignment): Call objc_compare_types().
+ (comp_ptr_ttypes_real): Call objc_type_quals_match() before
+ concluding that types do not match.
+
+2005-05-24 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR C++/21645
+ * optimize.c (update_cloned_parm): Copy the TYPE also from the
+ original one.
+
+2005-05-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/21495
+ * decl.c (grokdeclarator): Fix "storage class specified for"
+ error reporting.
+
+2005-05-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * parser.c: Fix comment typos.
+
+2005-05-18 Geoffrey Keating <geoffk@apple.com>
+
+ * Make-lang.in (cc1plus-dummy): New.
+ (cc1plus-checksum.c): New.
+ (cc1plus-checksum.o): New.
+ (cc1plus): Add cc1plus-checksum.o.
+
+2005-05-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR C++/19664
+ * decl2.c (determine_visibility): Don't set visibility to
+ hidden if it has been set explicitly by user.
+
+2005-05-17 Ziemowit Laski <zlaski@apple.com>
+ Mike Stump <mrs@apple.com>
+
+ Yet more Objective-C++...
+
+ * cp-objcp-common.h (cxx_get_alias_set): Move from
+ here...
+ (cxx_warn_unused_global_decl): Likewise.
+ (cp_expr_size): Likewise.
+ (cp_tree_size): Likewise.
+ (cp_var_mod_type_p): Likewise.
+ (cxx_initialize_diagnostics): Likewise.
+ (cxx_types_compatible_p): Likewise.
+ * cp-tree.h: to here.
+ (do_poplevel): Add.
+ * lex.c (D_OBJC): Add.
+ (init_reswords): Add.
+ * Make-lang.in (cp/pt.o): Add cp/cp-objcp-common.h.
+ * parser.c: Add c-common.h include.
+ * pt.c: Add c-common.h and cp-objcp-common.h includes.
+ (template_args_equal): Use objc_comptypes as well.
+ (tsubst_copy_and_build): Use objcp_tsubst_copy_and_build as well.
+ * semantics.c (do_poplevel): Remove static.
+
+ * decl.c (objc_mark_locals_volatile): Don't change decls that are
+ already ok.
+ * decl2.c (generate_ctor_or_dtor_function): Add code to initialize
+ Objective C++ early enough.
+ * lex.c (struct resword reswords): Add Objective-C++ support.
+ * parser.c (cp_lexer_get_preprocessor_token): Add Objective-C++.
+ (cp_parser_objc_message_receiver): Add.
+ (cp_parser_objc_message_args): Likewise.
+ (cp_parser_objc_message_expression): Likewise.
+ (cp_parser_objc_encode_expression): Likewise.
+ (cp_parser_objc_defs_expression): Likewise.
+ (cp_parser_objc_protocol_expression): Likewise.
+ (cp_parser_objc_selector_expression): Likewise.
+ (cp_parser_objc_expression): Likewise.
+ (cp_parser_objc_visibility_spec): Likewise.
+ (cp_parser_objc_method_type): Likewise.
+ (cp_parser_objc_protocol_qualifiers): Likewise.
+ (cp_parser_objc_typename): Likewise.
+ (cp_parser_objc_selector_p): Likewise.
+ (cp_parser_objc_selector): Likewise.
+ (cp_parser_objc_method_keyword_params): Likewise.
+ (cp_parser_objc_method_tail_params_opt): Likewise.
+ (cp_parser_objc_interstitial_code): Likewise.
+ (cp_parser_objc_method_signature): Likewise.
+ (cp_parser_objc_method_prototype_list): Likewise.
+ (cp_parser_objc_method_definition_list): Likewise.
+ (cp_parser_objc_class_ivars): Likewise.
+ (cp_parser_objc_identifier_list): Likewise.
+ (cp_parser_objc_alias_declaration): Likewise.
+ (cp_parser_objc_class_declaration): Likewise.
+ (cp_parser_objc_protocol_declaration): Likewise.
+ (cp_parser_objc_protocol_refs_opt): Likewise.
+ (cp_parser_objc_superclass_or_category): Likewise.
+ (cp_parser_objc_class_interface): Likewise.
+ (cp_parser_objc_class_implementation): Likewise.
+ (cp_parser_objc_end_implementation): Likewise.
+ (cp_parser_objc_declaration): Likewise.
+ (cp_parser_objc_try_catch_finally_statement): Likewise.
+ (cp_parser_objc_synchronized_statement): Likewise.
+ (cp_parser_objc_throw_statement): Likewise.
+ (cp_parser_objc_statement): Likewise.
+ (cp_parser_primary_expression): Add Objective-C++.
+ (cp_parser_statement): Likewise.
+ (cp_parser_declaration): Likewise.
+ (cp_parser_simple_type_specifier): Likewise.
+ (cp_parser_type_name): Likewise.
+ (cp_parser_parameter_declaration_list): Likewise.
+ (cp_parser_member_declaration) Likewise.
+ * tree.c: Include debug.h.
+ * typeck.c (composite_pointer_type): Add Objective-C++ support.
+ (finish_class_member_access_expr): Likewise.
+ (build_function_call): Allow objc to rewrite FUNCTION_DECLs.
+ (build_modify_expr): Allow objc to generate write barriers.
+
+ * Make-lang.in (cp/tree.o): Add debug.h.
+ * tree.c (lvalue_p_1, case CONST_DECL): Add.
+
+2005-05-18 Jan Hubicka <jh@suse.cz>
+
+ * method.c: Include tree-pass.h
+ (use_thunk): Lower body before expanding.
+
+2005-05-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/21454
+ * decl.c (maybe_deduce_size_from_array_init): Call
+ cp_apply_type_quals_to_decl after completing array type.
+
+2005-05-16 Richard Henderson <rth@redhat.com>
+
+ * decl.c (build_library_fn_1): Move setting TREE_NOTHROW ...
+ (build_library_fn): ... here.
+
+2005-05-12 Ian Lance Taylor <ian@airs.com>
+
+ * cp-tree.h (cp_stmt_codes): Don't define.
+ (statement_code_p): Declare.
+ (STATEMENT_CODE_P): Define.
+ * lex.c (statement_code_p): Define.
+ (cxx_init): Use actual codes in stmt_codes initializer, not
+ cp_stmt_codes macro. Initialize statement_code_p directly, rather
+ than using INIT_STATEMENT_CODES.
+
+2005-05-09 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_unary_op): Do not resort to address arithmetic
+ when taking the address of a COMPONENT_REF.
+
+2005-05-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * class.c (vtbl_init_data_s): Change the type of fns to
+ VEC(tree,gc)*.
+ (build_vtbl_initializer, add_vcall_offset, add_vcall_offset):
+ Use VEC instead of VARRAY.
+
+2005-05-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * mangle.c: Remove a reference to the MIPS -mint64 option.
+
+2005-05-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * decl.c (wrapup_globals_for_namespace): Use VEC instead of
+ VARRAY.
+ * name-lookup.c (add_decl_to_level, begin_scope): Likewise.
+ * name-lookup.h (cp_binding_level): Change the type of
+ static_decls to VEC(tree,gc)*.
+
+ * mangle.c (globals): Change the type of substitutions to
+ VEC(tree,gc)*.
+ (dump_substitution_candidates, add_substitution,
+ find_substitution, finish_mangling, init_mangle): Use VEC
+ instead of VARRAY.
+
+2005-05-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * decl2.c (spew_debug): Remove.
+
+ * decl2.c (ssdf_decls, start_static_storage_duration_function,
+ generate_ctor_or_dtor_function): Use VEC instead of VARRAY.
+
+ * decl2.c (pending_statics, note_vague_linkage_var,
+ cp_finish_file): Use VEC instead of VARRAY.
+ (pending_statics_used): Remove.
+
+2005-05-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * decl2.c (deferred_fns, note_vague_linkage_fn,
+ cp_finish_file): Use VEC instead of VARRAY.
+
+2005-05-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21352
+ * pt.c (build_non_dependent_expr): Use is_overloaded_fn.
+
+2005-05-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * pt.c: Fix a comment typo.
+
+2005-05-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h (language_function): Change the type of
+ x_local_names to VEC.
+ * decl.c (push_local_name): Adjust uses of local_names.
+
+2005-05-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * friend.c, lex.c, mangle.c, repo.c: Update copyright.
+
+2005-05-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * class.c (local_classes, init_class_processing): Use VEC
+ instead of VARRAY.
+ * cp-tree.h (local_classes): Likewise.
+ * mangle.c (discriminator_for_local_entity): Likewise.
+ * name-lookup.c (pushtag): Likewise.
+
+ * class.c (current_lang_depth, push_lang_context,
+ pop_lang_context): Use VEC instead of VARRAY.
+ * cp-tree.h (saved_scope): Use VEC for lang_base instead of
+ VARRAY.
+ * name-lookup.c (push_to_top_level): Use VEC instead of
+ VARRAY.
+
+2005-05-02 Paolo Bonzini <bonzini@gnu.org>
+
+ * semantics.c (finish_call_expr): Call resolve_overloaded_builtin
+ for BUILT_IN_MD built-ins.
+
+2005-05-02 Michael Matz <matz@suse.de>
+
+ PR c++/19542
+ * cp-tree.h (cp_tree_index): Remove CPTI_NULL, to be defined in C
+ common frontend.
+ (null_node): Remove.
+ * lex.c (cxx_init): Move null_node initialisation to C common frontend.
+
+2005-04-25 Ian Lance Taylor <ian@airs.com>
+
+ * cp-tree.def: Add EXPR_STMT.
+ * cp-tree.h (cp_stmt_codes): Add EXPR_STMT.
+ (EXPR_STMT_EXPR): Define.
+ * cp-gimplify.c: Include "flags.h".
+ (gimplify_expr_stmt): New static function.
+ (cp_gimplify_expr): Handle EXPR_STMT.
+ * cxx-pretty-print.c (pp_cxx_statement): Use pp_cxx_expression
+ rather than pp_expression.
+ (pp_cxx_statement): Handle EXPR_STMT.
+ * dump.c (cp_dump_tree): Handle EXPR_STMT.
+ * lex.c (cxx_init): Don't use c_common_stmt_codes in stmt_codes
+ initializer.
+
+2005-04-25 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR C++/21188
+ * rtti.c (ifnonnull): Cast the zero comparison operand
+ to the correct type.
+
+2005-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/20991
+ * class.c: Include cgraph.h.
+ (cp_fold_obj_type_ref): Set node->local.vtable_method.
+ * Make-lang.in (cgraph.o): Depend on $(CGRAPH_H).
+
+2005-04-12 Markus F.X.J. Oberhumer <markus@oberhumer.com>
+
+ * mangle.c (write_builtin_type): Handle integer types which are
+ not one of the shared integer type nodes and emit a "vendor
+ extended builtin type" with an encoding in the form of "u5int96".
+
+2005-04-24 Ian Lance Taylor <ian@airs.com>
+
+ * cp-tree.def (USING_STMT): Change class to tcc_statement.
+ (TRY_BLOCK, EH_SPEC_BLOCK, HANDLER, CLEANUP_STMT): Likewise.
+ (IF_STMT, FOR_STMT, WHILE_STMT, DO_STMT): Likewise.
+ (BREAK_STMT, CONTINUE_STMT, SWITCH_STMT): Likewise.
+
+2005-04-23 DJ Delorie <dj@redhat.com>
+
+ * call.c, class.c, cvt.c, decl.c, decl2.c, except.c, friend.c,
+ init.c, lex.c, mangle.c, method.c, name-lookup.c, parser.c,
+ repo.c, rtti.c, tree.c, typeck.c, typeck2.c: Adjust warning()
+ callers.
+
+2005-04-22 Per Bothner <per@bothner.com>
+
+ * decl.c (make_rtl_for_nonlocal_decl): Don't try get_fileinfo if
+ input_filename is NULL, as it is for (say) __PRETTY_FUNCTION__.
+
+2005-04-22 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/21087
+ * name-lookup.c (push_overloaded_decl): Do not overload with
+ non-duplicate anticipated built-in.
+
+2005-04-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h (THROW_NAME, AUTO_VTABLE_NAME, AUTO_TEMP_FORMAT,
+ VTABLE_BASE, VTABLE_NAME_PREFIX, STATIC_NAME_FORMAT): Remove.
+
+2005-04-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h: Adjust for new VEC API.
+ Define VEC(tree_pair_s,gc).
+ (struct save_scope): Adjust.
+ (struct lang_type_class): Adjust.
+ (unemitted_tinfo_decls): Adjust.
+ * class.c (add_method, resort_type_method_vec,
+ finish_struct_methods, struct find_final_overrider_data,
+ dfs_find_final_overrider_pre, find_final_overrider,
+ get_vcall_index, warn_hidden, walk_subobject_offsets,
+ check_methods, fixup_inline_methods, end_of_class,
+ warn_about_ambiguous_bases, finish_struct, build_vtbl_initializer,
+ add_vcall_offset): Adjust.
+ * decl.c (xref_basetypes, finish_method): Adjust.
+ * decl2.c (check_classfn): Adjust.
+ * init.c (sort_mem_initializers, push_base_cleanups): Adjust.
+ * method.c (do_build_copy_constructor): Adjust.
+ * name-lookup.c (new_class_binding, store_binding,
+ store_bindings, store_class_bindings): Adjust.
+ * name-lookup.h: Define VEC(cxx_saved_binding,gc),
+ VEC(cp_class_binding,gc).
+ (struct cp_binding_level): Adjust.
+ * parser.c: Define VEC(cp_token_position,heap).
+ (struct cp_lexer): Adjust.
+ (cp_lexer_new_main, cp_lexer_new_from_tokens, cp_lexer_destroy,
+ cp_lexer_save_tokens): Adjust.
+ * pt.c (retrieve_specialization,
+ check_explicit_specialization): Adjust.
+ * rtti.c (unemitted_tinfo_decls): Adjust.
+ (init_rtti_processing, get_tinfo_decl, get_pseudo_ti_init,
+ get_pseudo_ti_desc): Adjust.
+ * search.c (dfs_access_in_type, lookup_conversion_operator,
+ lookup_fnfields_1, dfs_walk_once, dfs_walk_once_accessible,
+ dfs_get_pure_virtuals, lookup_conversions_r, binfo_for_vbase): Adjust.
+ * semantics.c: Define VEC(deferred_access,gc).
+ (push_deferring_access_checks): Adjust.
+ * typeck2.c (abstract_virtuals_error): Adjust.
+
+2005-04-20 Ian Lance Taylor <ian@airs.com>
+
+ * cp-tree.def: Add STMT_EXPR.
+ * cp-tree.h (STMT_EXPR_NO_SCOPE): Define.
+ (STMT_EXPR_STMT): Define.
+ * cxx-pretty-print.c (pp_cxx_primary_expression): Handle
+ STMT_EXPR.
+ (pp_cxx_expression): Likewise.
+ (pp_cxx_statement): Call pp_cxx_statement, not pp_statement.
+ * dump.c (cp_dump_tree): Handle STMT_EXPR.
+
+2005-04-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * decl.c (expand_static_init): Call build2 and build3 instead
+ of build.
+
+ * cp-tree.h (VPTR_NAME, VPTR_NAME_P): Remove.
+
+2005-04-17 Ian Lance Taylor <ian@airs.com>
+
+ * cp-tree.def: Add SIZEOF_EXPR, ARROW_EXPR and ALIGNOF_EXPR.
+ * cxx-pretty-print.c (pp_cxx_postfix_expression): Handle
+ ARROW_EXPR.
+ (pp_cxx_unary_expression): Handle SIZEOF_EXPR and ALIGNOF_EXPR.
+ (pp_cxx_expression): Handle ARROW_EXPR, SIZEOF_EXPR, and
+ ALIGNOF_EXPR.
+ * typeck.c (cxx_sizeof_or_alignof_type): Update call to
+ c_sizeof_or_alignof_type for change in parameter type.
+
+2005-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21025
+ * typeck.c (cxx_sizeof_or_alignof_type): Check whether the type to
+ which sizeof/alignof is dependent, rather than just whether we are
+ processing_template_decl.
+
+2005-04-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h (LOOKUP_GLOBAL): Remove.
+ (LOOKUP_ONLYCONVERTING, DIRECT_BIND, LOOKUP_NO_CONVERSION,
+ LOOKUP_DESTRUCTOR, LOOKUP_NO_TEMP_BIND, LOOKUP_PREFER_TYPES,
+ LOOKUP_PREFER_NAMESPACES, LOOKUP_CONSTRUCTOR_CALLABLE): Adjust
+ their values.
+
+2005-04-15 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/14311
+ * semantics.c (finish_call_expr): Call resolve_overloaded_builtin.
+
+2005-04-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h (lang_type_class): Remove redefined. Move
+ java_interface into where redefined was. Increment the width
+ of dummy.
+ (TYPE_REDEFINED): Remove.
+
+2005-04-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h (SET_TMPL_ARG, ENUM_TI_TEMPLATE, ENUM_TI_ARGS,
+ CLASSTYPE_TEMPLATE_LEVEL): Remove.
+
+2005-04-11 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (determine_visibility): Don't use export_class_data.
+ (import_export_decl): Honor TARGET_CXX_CLASS_DATA_ALWAYS_WEAK and
+ TARGET_CXX_DETERMINE_CLASS_DATA_VISIBILITY.
+
+2005-04-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h (cxx_alignof): Remove.
+
+ * cp-tree.h (DECL_ARRAY_DELETE_OPERATOR_P): Remove.
+
+ * cp-tree.h (EXCEPTION_CLEANUP_NAME, B_SET, B_CLR, B_TST,
+ CONV_STATIC_CAST): Remove.
+
+ * pt.c (UNIFY_ALLOW_MAX_CORRECTION): Remove.
+
+ * cp-tree.h (VF_BINFO_VALUE, VF_BASETYPE_VALUE): Remove.
+
+ * cp-tree.h (cp_deprecated): Remove.
+
+2005-04-08 Ian Lance Taylor <ian@airs.com>
+
+ * cp-tree.def: Define FOR_STMT, WHILE_STMT, DO_STMT, BREAK_STMT,
+ CONTINUE_STMT, SWITCH_STMT.
+ * cp-tree.h (cp_stmt_codes): Add FOR_STMT, WHILE_STMT, DO_STMT,
+ BREAK_STMT, CONTINUE_STMT, SWITCH_STMT.
+ (WHILE_COND, WHILE_BODY): Define.
+ (DO_COND, DO_BODY): Define.
+ (FOR_INIT_STMT, FOR_COND, FOR_EXPR, FOR_BODY): Define.
+ (SWITCH_STMT_COND, SWITCH_STMT_BODY, SWITCH_STMT_TYPE): Define.
+ * cp-gimplify.c (enum bc_t): Define.
+ (struct cp_gimplify_ctx, ctxp): Define.
+ (push_context, pop_context): New static functions.
+ (begin_bc_block, finish_bc_block): New static functions.
+ (build_bc_goto): New static function.
+ (gimplify_cp_loop, gimplify_for_stmt): New static functions.
+ (gimplify_while_stmt, gimplify_do_stmt): Likewise.
+ (gimplify_switch_stmt): Likewise.
+ (cp_gimplify_expr): Handle FOR_STMT, WHILE_STMT, DO_STMT,
+ SWITCH_STMT, CONTINUE_STMT, BREAK_STMT.
+ (cp_genericize): Call push_context and pop_context.
+ * semantics.c (finish_break_stmt): Just call build_stmt
+ (BREAK_STMT) rather than build_break_stmt.
+ (finish_continue_stmt): Corresponding change.
+ * decl.c (pop_switch): Update call to c_do_switch_warnings for new
+ parameters.
+ * cxx-pretty-print.c (pp_cxx_statement): Handle SWITCH_STMT,
+ WHILE_STMT, DO_STMT, FOR_STMT, BREAK_STMT, CONTINUE_STMT.
+ * dump.c (cp_dump_tree): Likewise.
+
+2005-04-08 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20905
+ * parser.c (cp_parser_type_specifier_seq): Add is_condition
+ parameter.
+ (cp_parser_new_type_id): Pass it.
+ (cp_parser_condition): Likewise.
+ (cp_parser_conversion_type_id): Likewise.
+ (cp_parser_type_id): Likewise.
+ (cp_parser_type_specifier_seq): In a condition, do not allow
+ invalid type-specifier combinations.
+ (cp_parser_exception_declaration): Adjust call to
+ cp_parser_type_specifier_seq.
+
+ * cp-tree.def (TINST_LEVEL): Document TINST_IN_SYSTEM_HEADER_P.
+ * cp-tree.h (struct tinst_level): Add in_system_header_p.
+ (TINST_IN_SYSTEM_HEADER_P): New macro.
+ (make_tinst_level): Remove.
+ * pt.c (lookup_template_class): Preserve DECL_IN_SYSTEM_HEADER on
+ the instantiated class.
+ (push_tinst_level): Do not use make_tinst_level. Set
+ TINST_IN_SYSTEM_HEADER_P.
+ (pop_tinst_level): Likewise.
+ (instantiate_class_template): Set in_system_header.
+ (instantiate_pending_templates): Likewise.
+ * tree.c (make_tinst_level): Remove.
+
+2005-04-06 Joseph S. Myers <joseph@codesourcery.com>
+
+ * decl.c (start_decl): Apply pending #pragma weak regardless of
+ scope.
+
+2005-04-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20212
+ * pt.c (regenerate_decl_from_template): Copy attributes for
+ parameters from the pattern to the instantiation.
+
+2005-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20734
+ * cp-tree.def (OFFSET_REF): Correct comments.
+ * init.c (build_offset_ref): Remove misleading comment.
+ * typeck.c (build_unary_op): Handle pointer-to-member creation
+ here, rather than ...
+ (unary_complex_lvalue): ... here.
+
+2005-04-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/19312
+ * tree.c (stabilize_init): Don't bother trying to stabilize
+ something with no side-effects.
+
+2005-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20763
+ * decl.c (grokdeclarator): Correct attribute handling.
+
+2005-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19159
+ * decl2.c (import_export_decl): Use non-COMDAT external linkage
+ for virtual tables, typeinfo, etc. that will be emitted in only
+ one translation unit on systems without weak symbols.
+
+2005-04-04 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20679
+ * parser.c (cp_parser_template_name): Fix thinko.
+
+2005-04-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20746
+ * method.c (use_thunk): Protect covariant pointer return
+ adjustments from NULL pointers.
+
+2005-04-04 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (finish_objects): Revert my previous patch.
+ (cp_finish_file): Likewise.
+
+2005-04-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * pt.c: Fix comment typos.
+
+2005-04-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20723
+ * pt.c (more_specialized_fn): Member functions are unordered wrt
+ non-members. Conversion operators are unordered wrt other
+ functions.
+
+2005-04-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (add_template_candidates_real): Remove length parameter
+ from fn_type_unification call.
+ * class.c (resolve_address_of_overloaded_function): Likewise
+ * cp-tree.h (fn_type_unification): Remove length parameter.
+ * pt.c (get_bindings_overload): Remove.
+ (get_bindings_real): Rename to ...
+ (get_bindings): ... here. Remove length and strict
+ parameters. Change return type flag to boolean. Remove original
+ forwarding function.
+ (determine_specialization): Adjust get_bindings call.
+ (fn_type_unification): Remove length parameter. Adjust.
+ (type_unification_real): Remove length parameter. Adjust.
+ (resolve_overloaded_unification): Adjust get_bindings call.
+ (try_one_overload): Simplify confusing cascaded if control flow.
+ (unify): Remove length paramter from type_unification_real call.
+ (most_specialized_instantiation): Adjust get_bindings calls.
+ (most_specialized): Likewise.
+
+2005-03-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/19203, implement DR 214
+ * call.c (joust): Use more_specialized_fn.
+ * cp-tree.h (DEDUCE_ORDER): Remove.
+ (more_specialized): Replace with ...
+ (more_specialized_fn): ... this.
+ * pt.c (maybe_adjust_types_for_deduction): Remove DEDUCE_ORDER
+ case.
+ (type_unification_real): Remove DEDUCE_ORDER case.
+ (more_specialized): Replace with ...
+ (more_specialized_fn): ... this. Implement DR 214.
+ (most_specialized_instantiation): Use get_bindings_real directly.
+
+2005-03-31 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/18644
+ * call.c (build_new_op): Remove check for -Wsynth.
+
+2005-03-31 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (finish_objects): Mark ctor as needed.
+ (cp_finish_file): Output variables only in nonunit-at-a-time.
+
+2005-03-29 Richard Henderson <rth@redhat.com>
+
+ PR c/20519
+ * decl.c (cp_complete_array_type): Rename from complete_array_type.
+ Use the new complete_array_type in c-common.c. Update all callers.
+ * cp-tree.h (cp_complete_array_type): Update to match.
+
+2005-03-24 Geoffrey Keating <geoffk@apple.com>
+
+ * typeck.c (build_static_cast_1): Allow scalar_cast between
+ any integral, floating, or enumeration type.
+
+2005-03-24 Steven Bosscher <stevenb@suse.de>
+
+ * typeck.c (comptypes): First determine if the types are compatible
+ from a target-independent point of view. Check target attributes
+ last.
+
+ * class.c (build_base_path):
+ (build_vbase_offset_vtbl_entries):
+ (add_vcall_offset): Replace fold (buildN (...)) with fold_buildN.
+ * error.c (dump_expr): Likewise.
+ * init.c (build_zero_init, expand_cleanup_for_base,
+ build_vec_delete_1): Likewise.
+ * mangle.c (write_integer_cst): Likewise.
+ * method.c (thunk_adjust): Likewise.
+ * pt.c (convert_nontype_argument, tsubst, unify): Likewise.
+ * tree.c (cxx_print_statistics, array_type_nelts_total): Likewise.
+ * typeck.c (build_ptrmemfunc_access_expr,
+ (get_member_function_from_ptrfunc): Likewise.
+
+2005-03-23 Joseph S. Myers <joseph@codesourcery.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_TRUTHVALUE_CONVERSION): Remove.
+
+2005-03-23 Joseph S. Myers <joseph@codesourcery.com>
+
+ * cp-tree.h (perform_integral_promotions): Remove.
+ (default_conversion): Add.
+
+2005-03-22 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_warn_min_max): New function.
+ (cp_parser_binary_expression): Use it.
+ (cp_parser_assignment_operator_opt): Likewise.
+ (cp_parser_operator): Likewise.
+
+2005-03-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/19980
+ * decl.c (start_preparsed_function): Robustify.
+
+2005-03-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/20499
+ * parser.c (cp_parser_class_head): Return NULL_TREE when
+ encountering a redefinition.
+
+2005-03-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20465
+ PR c++/20381
+ * typeck.c (build_ptrmemfunc): Allow OFFSET_REF when processing a
+ template.
+
+2005-03-21 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/20461
+ PR c++/20536
+ * init.c (emit_mem_initializers): Don't crash on undefined
+ types.
+
+2005-03-21 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/20147
+ * semantics.c (finish_stmt_expr_expr): Return immediately
+ if error_operand_p (expr).
+
+2005-03-21 Joseph S. Myers <joseph@codesourcery.com>
+
+ * cp-tree.h (lvalue_or_else, lvalue_p): New.
+ * typeck.c (lvalue_or_else): New. Call lvalue_error.
+
+2005-03-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/20240
+ * decl.c (decls_match): Compare context of VAR_DECL.
+
+2005-03-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/20333
+ * parser.c (cp_parser_postfix_expression) <case RID_TYPENAME>:
+ Check the return value of cp_parser_nested_name_specifier.
+
+2005-03-18 Dale Johannesen <dalej@apple.com>
+
+ * cp/tree.c (cp_tree_equal): Handle SSA_NAME.
+
+2005-03-18 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/20463
+ * parser.c (cp_parser_diagnose_invalid_type_name):
+ Check TYPE_BINFO (current_class_type) before attempting
+ to emit inform messages.
+
+2005-03-17 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/19966
+ * cp-tree.h (grok_op_properties): Change return type to void.
+ * decl.c (grok_op_properties): Return early - don't check the
+ arity - in case of a static member or an operator that cannot
+ be non-member; tidy a bit.
+
+2005-03-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20186
+ * pt.c (contains_dependent_cast_p): Remove.
+ (fold_non_dependent_expr): Don't use it.
+ (value_dependent_expression_p): Use a switch statement.
+ reference_exprs can be dependent.
+
+2005-03-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/4403
+ PR c++/9783, DR433
+ * name-lookup.c (pushtag): Skip template parameter scope when
+ scope is ts_global. Don't push tag into template parameter
+ scope.
+ * pt.c (instantiate_class_template): Reorder friend class
+ template substitution to handle non-dependent friend class
+ that hasn't been previously declared.
+
+2005-03-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ Friend class name lookup 5/n
+ PR c++/1016
+ * cp-tree.h (pushtag): Adjust declaration.
+ * decl.c (lookup_and_check_tag): Call lookup_type_scope if
+ lookup_name fails.
+ (xref_tag): Adjust call to pushtag. Make hidden class visible.
+ (start_enum): Adjust call to pushtag.
+ * name-lookup.c (ambiguous_decl): Ignore hidden names.
+ (qualify_lookup): Change return type to bool.
+ (hidden_name_p): New function.
+ (lookup_namespace_name, unqualified_namespace_lookup,
+ lookup_name_real): Use it.
+ (lookup_type_scope): Update comments.
+ (maybe_process_template_type_declaration): Change parameter name
+ from globalize to is_friend.
+ (pushtag): Change globalize parameter of type int to tag_scope.
+ Hide name if introduced by friend declaration.
+ * name-lookup.h (hidden_name_p): Add declaration.
+ * parser.c (cp_parser_lookup_name): Don't deal with hidden name
+ here.
+ * pt.c (push_template_decl_real): Make hidden class template
+ visible.
+ (lookup_template_class, instantiate_class_template): Adjust call
+ to pushtag.
+ * semantics.c (begin_class_definition): Likewise.
+ * rtti.c (init_rtti_processing, build_dynamic_cast_1,
+ tinfo_base_init, emit_support_tinfos): Use ts_current instead of
+ ts_global.
+
+2005-03-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20157
+ * pt.c (determine_specialization): Reject non-specializations.
+
+2005-03-11 Per Bothner <per@bothner.com>
+
+ * cp-tree.h (struct cp_declarator): New id_loc field.
+ * cp/parser.c (cp_lexer_get_preprocessor_token): Set cp_token's
+ location using c_lex_with_flags, instead of input_location.
+ (cp_parser_direct_declarator): Set declarator's id_loc from
+ cp_token's id_loc.
+
+2005-03-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/18384, c++/18327
+ * decl.c (reshape_init_array): Use UHWI type for max_index_cst
+ and index. Convert max_index to size_type_node if it isn't
+ host_integerp (, 1).
+
+2005-03-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20208
+ * pt.c (tsubst_decl): Apply array-to-pointer and
+ function-to-pointer conversions to function arguments.
+ (regenerate_decl_from_template): Likewise.
+
+2005-03-09 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/16859
+ * decl.c (complete_array_type): In pedantic mode, return
+ 3 for an empty initializer list as the initializer for an
+ array of unknown bound (8.5.1/4).
+ (maybe_deduce_size_from_array_init): Fix final test to use
+ the above.
+
+2005-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20186
+ * pt.c (contains_dependent_cast_p): New.
+ (fold_non_dependent_expr): Call it.
+
+2005-03-08 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20142
+ * cp-tree.h (target_type): Remove.
+ * decl.c (layout_var_decl): Remove #if 0'd code.
+ (cp_finish_decl): Remove dead code.
+ * init.c (build_vec_init): When determining whether or not the
+ element type has an asignment operator, look through all array
+ dimensions.
+ * typeck.c (target_type): Remove.
+
+2005-03-07 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (finish_struct_1): Do not warn about non-virtual
+ destructors in Java classes.
+
+2005-03-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/19311
+ * init.c (build_offset_ref): Don't build non-dependent SCOPE_REF.
+ * pt.c (build_non_dependent_expr): Don't build NON_DEPENDENT_EXPR
+ for OFFSET_TYPE.
+ * typeck.c (build_x_unary_op): Don't build non-dependent SCOPE_REF.
+ Also set PTRMEM_OK_P for NON_DEPENDENT_EXPR.
+ (build_unary_op): Handle building ADDR_EXPR of OFFSET_REF inside
+ template.
+
+2005-03-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * name-lookup.c (push_overloaded_decl): Don't error if the new
+ decl matches the old one.
+ * decl.c (redeclaration_error_message): Likewise.
+
+2005-03-01 Per Bothner <per@bothner.com>
+
+ * decl.c (finish_function): Use SET_EXPR_LOCATION instead of
+ unavailable annotate_with_file_line, if USE_MAPPED_LOCATION.
+
+2005-03-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20232
+ * class.c (update_vtable_entry_for_fn): Don't crash on invalid
+ covariancy.
+
+ * cp-tree.g (THUNK_TARGET): Expand comment.
+ * method.c (use_thunk): Make sure we also use the target, if that
+ is a thunk.
+
+2005-02-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/20206
+ * decl.c (cxx_comdat_group): Put thunks for
+ TARGET_USE_LOCAL_THUNK_ALIAS_P (function) functions into the same
+ comdat group as the thunk target.
+
+2005-02-24 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * call.c, class.c, cp-tree.h, decl2.c, error.c, init.c, mangle.c,
+ parser.c: Fix comment typo(s).
+
+2005-02-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/20175
+ * decl.c (reshape_init): Don't warn about missing braces if STRING_CST
+ initializes a char/wchar_t array.
+
+2005-02-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19878
+ * decl.c (grokvardecl): Set DECL_INTERFACE_KNOWN for declarations
+ with internal linkage.
+
+2005-02-23 Alexandre Oliva <aoliva@redhat.com>
+
+ * decl.c (grokvardecl): Don't exempt anonymous types from having
+ linkage for variables that have linkage other than "C".
+
+2005-02-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-objcp-common.h, error.c: Update copyright.
+
+2005-02-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20073
+ * decl.c (start_decl_1): Don't clear TREE_READONLY.
+ (cp_finish_decl): Likewise.
+ (complete_vars): Call cp_apply_type_quals_to_decl.
+ * typeck.c (cp_apply_type_quals): Avoid setting TREE_READONLY in
+ cases where that's not valid.
+
+ PR c++/19991
+ * init.c (integral_constant_value): Iterate if the value of a decl
+ is itself a constant.
+
+ PR c++/20152
+ * parser.c (cp_parser_class_head): Check for redefintions here.
+ * semantics.c (begin_class_definition): Not here.
+
+ PR c++/20153
+ * decl2.c (build_anon_union_vars): Add type parameter.
+ (finish_anon_union): Pass it.
+
+ PR c++/20148
+ * error.c (dump_expr): Do not print the body of a BIND_EXPR.
+ Handle STATEMENT_LIST.
+
+ PR c++/19883
+ * parser.c (cp_parser_direct_declarator): Always complain about
+ non-constant array bounds when in a function scope.
+ * semantics.c (finish_id_expression): Do not mark dependent names
+ as non-constant.
+
+2005-02-21 Douglas Gregor <dgregor@cs.indiana.edu>
+
+ PR c++/19076
+ PR c++/6628
+ * cp-tree.h (cp_apply_type_quals_to_decl): Declared.
+ * decl.c (grokdeclarator): Pedwarn about qualifying a function
+ type.
+ Add qualifiers when declaring a typedef of a function type.
+ Member function pointers pick up the qualifiers of the typedef
+ used to declare them.
+ Don't complain about creating cv-qualified function types.
+ Complain about qualified function typedefs that are used to
+ declare non-static member functions or free functions.
+ Use cp_apply_type_quals_to_decl.
+ (start_preparsed_function): Use cp_apply_type_quals_to_decl.
+ (grokclassfn): Use cp_apply_type_quals_to_decl.
+ * error.c (dump_type_suffix): Print qualifiers for function
+ types.
+ * pt.c (tsubst_decl): Use cp_apply_type_quals_to_decl.
+ (tsubst): When substituting a function type into a member
+ pointer type, pass along the qualifiers.
+ (unify): Unify member pointers to member function pointers.
+ * tree.c (cp_build_qualified_type_real): Function types may be
+ qualified. This includes restrict qualifiers.
+ * typeck.c (cp_apply_type_quals_to_decl): New function to replace
+ use of c_apply_type_quals_to_decl. Drops qualifiers that are being
+ added to function types.
+
+2005-02-20 Zack Weinberg <zack@codesourcery.com>
+
+ PR 18785
+ * cp-objcp-common.h (LANG_HOOKS_TO_TARGET_CHARSET): Set to
+ c_common_to_target_charset. Delete bogus comment.
+
+2005-02-18 Richard Henderson <rth@redhat.com>
+
+ PR libstdc++/10606
+ * except.c (do_get_exception_ptr): New.
+ (expand_start_catch_block): Use it.
+
+2005-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (start_decl_1): Only check TYPE_NEEDS_CONSTRUCTING
+ if type is not error_mark_node.
+
+2005-01-20 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/19508
+ * decl2.c (grokfield): Do not apply attributes to template parameters
+ as they are ignored by tsubst anyway.
+
+2005-02-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/19813
+ * decl.c (start_decl_1): Clear TREE_READONLY flag if
+ its type has TYPE_NEEDS_CONSTRUCTING.
+ (complete_vars): Likewise.
+
+2005-02-17 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/20028
+ * class.c (finish_struct): Initialize TYPE_SIZE_UNIT of a
+ template along with TYPE_SIZE.
+
+ PR c++/20022
+ * semantics.c (perform_deferred_access_checks): Use
+ get_deferred_access_checks to get the top of the stack.
+
+2005-02-15 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/17788
+ * class.c (add_implicitly_declared_members, check_field_decl)
+ (check_field_decls, check_bases): Remove arguments, tests and
+ assignments of cant_have_default_ctor-related variables.
+
+2005-02-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * decl2.c (mark_used): Set the source location of the used decl to
+ the current input location here...
+ * method.c (synthesize_method): ... not here. Set input_location
+ from the decl instead.
+
+2005-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/19608
+ * parser.c (cp_parser_late_parsing_for_member): Use
+ current_function_decl as scope to push to and from.
+
+ PR c++/19884
+ * pt.c (check_explicit_specialization): Make sure namespace
+ binding lookup found an overloaded function.
+ (lookup_template_function): Just assert FNS is an overloaded
+ function.
+
+ PR c++/19895
+ * decl.c (grokdeclarator): Check for error mark node in ptrmem
+ construction.
+
+2005-02-14 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/17816
+ * decl.c (redeclaration_error_message): Report redefinition of
+ pure virtual function.
+
+2005-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/19891
+ * class.c (build_simple_base_path): Build the component_ref
+ directly.
+ (update_vtable_entry_for_fn): Walk the covariant's binfo chain
+ rather than using lookup_base.
+ * search.c (dfs_walk_once): Add non-recursive assert check.
+ * typeck.c (build_class_member_access_expr): It is possible for
+ the member type to be both const and volatile.
+
+2005-02-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/14479
+ PR c++/19487
+ * pt.c (maybe_check_template_type): Remove.
+ * cp-tree.h (maybe_check_template_type): Remove prototype.
+ * name-lookup.c (maybe_process_template_type_declaration): Don't
+ use maybe_check_template_type.
+
+2005-02-11 Richard Henderson <rth@redhat.com>
+
+ PR c++/19632
+ * pt.c (get_mostly_instantiated_function_type): Save and restore
+ flag_access_control instead of push/pop_access_scope.
+
+2005-02-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19755
+ * decl.c (reshape_init): Issue warnings about missing braces.
+
+2005-02-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.def, except.c, ptree.c: Update copyright.
+
+2005-02-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19811
+ * call.c (build_op_delete_call): Check COMPLETE_TYPE_P before
+ attempting name lookup.
+
+ * parser.c (cp_parser_unqualified_id): Initialize type_decl.
+
+ PR c++/19787
+ * call.c (initialize_reference): Robustify.
+
+ PR ++/19732
+ * decl.c (grokdeclarator): Check for invalid use of destructor
+ names.
+
+ PR c++/19762
+ * parser.c (cp_parser_unqualified_id): Avoid creating destructor
+ names with invalid types.
+
+ PR c++/19826
+ * parser.c (cp_parser_direct_declarator): Allow type-dependent
+ expressions as array bounds.
+
+ PR c++/19739
+ * parser.c (cp_parser_attributes_list): Allow empty lists.
+
+2005-02-08 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19733
+ * class.c (add_method): Don't set TYPE_HAS_DESTRUCTOR.
+ (check_bases): Give warnings about a base class with a
+ non-virtual destructor, even if it is implicit.
+ (finish_struct_bits): Don't copy TYPE_HAS_DESTRUCTOR.
+ (maybe_warn_about_overly_private_class): Don't use
+ TYPE_HAS_DESTRUCTOR.
+ (finish_struct_methods): Don't set TYPE_HAS_DESTRUCTOR.
+ (check_for_override): Give it external linkage.
+ (add_implicitly_declared_members): Generate destructors lazily.
+ (check_field_decls): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR, not
+ TYPE_HAS_DESTRUCTOR.
+ (check_bases_and_members): Call check_methods before
+ check_field_decls.
+ (check_bases_and_members): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR, not
+ TYPE_HAS_DESTRUCTOR.
+ (finish_struct_1): Do not use TYPE_HAS_DESTRUCTOR.
+ * cp-tree.def (PSEUDO_DTOR_EXPR): Document.
+ * cp-tree.h (TYPE_HAS_DESTRUCTOR): Remove.
+ (lang_type_class): Add lazy_destructor.
+ (CLASSTYPE_LAZY_DESTRUCTOR): New macro.
+ (CLASSTYPE_DESTRUCTORS): Robustify.
+ (TYPE_HAS_DESTRUCTOR): Remove.
+ (check_for_override): Declare.
+ (build_vbase_delete): Remove.
+ * cvt.c (convert_to_void): Issue errors about pseudo-destructor
+ expressions.
+ * decl.c (cxx_maybe_build_cleanup): Remove dead code.
+ * except.c (dtor_nothrow): Lazily create destructors if necessary.
+ (build_throw): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ * init.c (build_delete): Lazily create destructors, if necessary.
+ (build_vbase_delete): Remove.
+ * method.c (locate_dtor): Simplify.
+ (implicitly_declare_fn): Add support for destructors.
+ * parser.c (cp_parser_lookup_name): Lazily create destructors, if
+ necessary.
+ * pt.c (check_explicit_specialization): Don't use
+ TYPE_HAS_DESTRUCTOR.
+ (instantiate_class_template): Likewise.
+ * ptree.c (cxx_print_type): Don't print TYPE_HAS_DESTRUCTOR.
+ * rtti.c (emit_support_tinfos): Robustify.
+ * search.c (lookup_fnfields_1): Lazily create destructors.
+ * typeck.c (build_class_member_access_expr): Remove
+ PSEUDO_DTOR_EXPR handling.
+ (lookup_destructor): Likewise.
+
+2005-02-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cxx-pretty-print.c, cxx-pretty-print.h, decl.h: Update
+ copyright.
+
+2005-02-07 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_lexer_start_debugging): Avoid arithmetic operations
+ on boolean variables.
+ (cp_lexer_stop_debugging): Likewise.
+
+2005-02-03 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/17401
+ * parser.c (cp_parser_pure_specifier): Emit a specific error
+ message with an invalid pure specifier.
+ * decl2.c (grok_function_init): Remove.
+ (grokfield): An initializer for a method is a always a pure
+ specifier.
+
+2005-02-02 Matt Austern <austern@apple.com>
+
+ PR c++/19628
+ * cp-tree.h (builtin_valid_in_constant_expr_p): Declare.
+ * parser.c (cp_parser_postfix_expression): Accept function call in
+ constant expression if builtin_valid_in_constant_expr_p is true
+ for that function.
+ * pt.c (value_dependent_expression_p): Handle CALL_EXPRs properly.
+ * semantics.c (finish_id_expression): Accept function call in constant
+ expression if builtin_valid_in_constant_expr_p is true for that
+ function.
+ * tree.c (builtin_valid_in_constant_expr_p): New.
+
+2005-02-02 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/17413
+ * pt.c (check_instantiated_args): Improve error message.
+ Fix logic when to print its second part.
+
+2005-02-02 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * cp-tree.h (complete_type_or_else): Remove macro.
+ (complete_type_or_diagnostic): Rename to complete_type_or_else
+ and remove last argument.
+ * typeck.c (complete_type_or_diagnostic): Rename to
+ complete_type_or_else and remove last argument.
+
+2005-02-02 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * cp-tree.h (commonparms): Remove prototype.
+ (convert_arguments): Likewise.
+ (PFN_FROM_PTRMEMFUNC): Remove.
+ * typeck.c (commonparms): Make static.
+ (convert_arguments): Add prototype. Make static.
+ (PFN_FROM_PTRMEMFUNC): Replace by pfn_from_ptrmemfunc.
+
+2005-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_primary_expression): Don't complain about
+ floating-point literals in integral constant expressions when
+ !pedantic.
+
+2005-02-01 Alexandre Oliva <aoliva@redhat.com>
+
+ * parser.c (cp_parser_template_id): Revert comment patch too.
+
+ PR c++/18757
+ PR c++/19366
+ PR c++/19499
+ * parser.c (cp_parser_template_id): Revert 2004-12-09's patch.
+ Issue an error when creating the template id.
+ * pt.c (fn_type_unification): Return early if the explicit
+ template arg list is an error_mark_node.
+
+2005-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (build_enumerator): Do not issue duplicate error messages
+ about invalid enumeration constants.
+ * parser.c (cp_parser_non_integral_constant_expression): Always
+ set parser->non_integral_constant_expression_p.
+ (cp_parser_primary_expression): Add cast_p parameter. Issue
+ errors about invalid uses of floating-point literals in
+ cast-expressions.
+ (cp_parser_postfix_expression): Add cast_p parameter.
+ (cp_parser_open_square_expression): Pass it.
+ (cp_parser_parenthesized_expression_list): Add cast_p parameter.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_new_placement): Pass it.
+ (cp_parser_direct_new_declarator): Likewise.
+ (cp_parser_new_initializer): Likewise.
+ (cp_parser_cast_expression): Add cast_p parameter.
+ (cp_parser_binary_expression): Likewise.
+ (cp_parser_question_colon_clause): Likewise.
+ (cp_parser_assignment_expression): Likewise.
+ (cp_parser_expression): Likewise.
+ (cp_parser_constant_expression): If an integral constant
+ expression is invalid, return error_mark_node.
+ (cp_parser_expression_statement): Pass cast_p.
+ (cp_parser_condition): Likewise.
+ (cp_parser_iteration_statement): Likewise.
+ (cp_parser_jump_statement): Likewise.
+ (cp_parser_mem_initializer): Likewise.
+ (cp_parser_template_argument): Likewise.
+ (cp_parser_parameter_declaration): Likewise.
+ (cp_parser_initializer): Likewise.
+ (cp_parser_throw_expression): Likewise.
+ (cp_parser_attribute_list): Likewise.
+ (cp_parser_simple_cast_expression): Likewise.
+ (cp_parser_functional_cast): Likewise.
+ (cp_parser_late_parsing_default_args): Likewise.
+ (cp_parser_sizeof_operand): Save/restore
+ non_integral_constant_expression_p.
+
+2005-01-31 Mike Stump <mrs@apple.com>
+
+ * parser.c (cp_lexer_new_main): Get the first token, first, before
+ doing anything.
+
+2005-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_decl): Add missing parentheses.
+
+2005-01-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19555
+ * cp-tree.h (DECL_USE_TEMPLATE): Expand documentation.
+ * decl.c (duplicate_decls): Do not discard
+ DECL_IMPLICIT_INSTANTIATION when merging declarations.
+ (start_decl): Do not SET_DECL_TEMPLATE_SPECIALIZATION for
+ variables that do not have DECL_USE_TEMPLATE.
+
+ PR c++/19395
+ * decl.c (grokdeclarator): Refactor code so that qualified names
+ are never allowed as the declarator in a typedef.
+
+ PR c++/19367
+ * name-lookup.c (do_nonmember_using_decl): Avoid overloading
+ builtin declarations.
+
+ PR c++/19457
+ * call.c (convert_like_real): Inline call to
+ dubious_conversion_warnings here.
+ * cp-tree.h (dubious_conversion_warnings): Remove.
+ * semantics.c (finish_unary_op_expr): Copy INTEGER_CSTs before
+ setting TREE_NEGATED_INT.
+ * typeck.c (dubious_conversion_warnings): Remove.
+
+ PR c++/19349
+ * name-lookup.c (pushdecl_namespace_level): Avoid accessing free'd
+ memory.
+
+2005-01-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19253
+ * parser.c (cp_parser_diagnose_invalid_type_name): Commit to
+ tentative parses.
+
+ PR c++/19667
+ * pt.c (redeclare_class_template): Robustify.
+
+2005-01-27 Steven Bosscher <stevenb@suse.de>
+
+ * decl.c (finish_case_label): Use SWITCH_STMT accessor macros
+ instead of SWITCH_EXPR ones.
+ * pt.c (tsubst_expr): Likewise.
+ * semantics.c (begin_switch_stmt, finish_switch_cond,
+ finish_switch_stmt): Likewise.
+
+2005-01-26 J"orn Rennecke <joern.rennecke@st.com>
+
+ PR c++/18370
+ * parser.c (cp_parser_initializer_clause): Initialize *non_constant_p.
+
+2005-01-25 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * class.c (abort_fndecl_addr): New variable.
+ (build_vtbl_initializer): If we have a pure virtual function
+ share the abort function's address.
+ Include gt-cp-class.h at the end.
+ * config-lang.in (gtfiles): Add cp/class.c.
+
+2005-01-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * cxx-pretty-print.c (pp_cxx_statement): Add prototype. Make static.
+ (pp_cxx_function_definition): Make static.
+ * cxx-pretty-print.h (pp_cxx_statement): Remove prototype.
+ (pp_cxx_function_definition): Likewise.
+
+2005-01-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * name-lookup.c (print_binding_level): Make static.
+ (constructor_name_full): Make static inline.
+ (current_decl_namespace): Make static.
+ * name-lookup.h (constructor_name_full): Remove prototype.
+ (print_binding_level): Likewise.
+ (current_decl_namespace): Likewise.
+
+2005-01-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * decl.h (debug_bindings_indentation): Remove.
+
+2005-01-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * typeck.c: Fix a comment typo.
+
+2005-01-21 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/19208
+ * pt.c (fold_decl_constant_value): Always call fold_non_dependent_expr
+ at least once.
+ (tsubst): Use fold_decl_constant_value in place of a bare call to
+ integral_constant_value.
+
+2005-01-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * typeck.c (more_qualified_p): Remove.
+ * cp-tree.h: Remove the corresponding prototype.
+
+2005-01-19 Matt Austern <austern@apple.com>
+
+ * typeck.c (comptypes): Handle return code from objc_comptypes
+ correctly.
+
+2005-01-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h, name-lookup.h: Remove unused prototypes.
+
+2005-01-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/19375
+ * semantics.c (finish_id_expression): Disable access checking for
+ already lookuped FIELD_DECL.
+
+2005-01-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * decl.c (delete_block): Remove.
+ * cp-tree.h: Remove the corresponding prototype.
+
+ * decl.c (vtable_decl_p, vtype_decl_p, walk_globals_data,
+ walk_vtables_r, walk_vtables, walk_globals_r, walk_globals):
+ Remove.
+ * cp-tree.h: Remove the corresponding prototypes.
+
+ * tree.c (count_functions, bound_pmf_p, cp_is_overload_p,
+ cp_update_decl_after_saving, name_p): Remove.
+ * cp-tree.h: Remove the corresponding prototypes.
+
+2005-01-18 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/19472
+ * semantics.c (finish_asm_stmt): Strip nops off
+ input memory operands.
+
+2005-01-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * Make-lang.in, call.c, cvt.c, init.c, rtti.c, tree.c,
+ typeck2.c: Update copyright.
+
+2005-01-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * class.c (get_enclosing_class): Remove.
+ * cp-tree.h: Remove the corresponding prototypes.
+
+ * cvt.c (convert_lvalue): Remove.
+ * cp-tree.h: Remove the corresponding prototype.
+
+ * pt.c (tinst_for_decl): Remove.
+ * cp-tree.h: Remove the corresponding prototypes.
+
+ * tree.c (hash_chainon): Remove.
+ * cp-tree.h: Remove the corresponding prototypes.
+
+2005-01-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/19263
+ * typeck2.c (split_nonconstant_init_1) <case VECTOR_TYPE>: Put a copy
+ of CONSTRUCTOR's node into MODIFY_EXPR, as the original is modified.
+
+2005-01-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (cp-warn): Don't append $(WERROR).
+
+2005-01-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h: Fix a comment typo.
+
+2005-01-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/19298
+ * pt.c (tsubst_qualified_id): Call convert_from_reference.
+
+2005-01-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19244
+ * class.c (add_implicitly_declared_members): Remove dead code.
+ * decl.c (grokfndecl): Add sfk parameter. Use it do set
+ DECL_CONSTRUCTOR_P.
+ (grokdeclarator): Adjust calls to grokfndecl.
+ * method.c (implicitly_declare_fn): Improve documentation.
+ * parser.c (cp_parser_direct_declarator): Do not consider a
+ function to be a constructor if the containing class was
+ originally anonymous.
+
+2005-01-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/17154
+ * search.c (lookup_field_1): Handle using declaration in
+ class template partial specialization.
+
+2005-01-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/19258
+ * pt.c (push_access_scope): Handle friend defined in class.
+ (pop_access_scope): Likewise.
+
+2005-01-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/19270
+ * pt.c (tsubst_copy) <ARRAY_REF case>: Handle separately.
+ (tsubst_copy_and_build) <ARRAY_REF case>: Remove obsolete
+ array-new handling code. Use build_x_binary_op.
+
+2005-01-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/19030
+ * cp-tree.h (start_decl): Take pointer to pushed scope, not bool.
+ * name-lookup.h (push_scope): Return pushed scope, not flag.
+ * name-lookup.c (push_scope): Return scope that should be popped,
+ not a flag.
+ * decl.c (start_decl): Adjust.
+ (grokfndecl): Adjust scope push and pop.
+ * decl2.c (check_classfn): Likewise.
+ * parser.c (cp_parser_condition, cp_parser_conversion_function_id,
+ cp_parser_init_declarator, cp_parser_direct_declarator,
+ cp_parser_class_specifier, cp_parser_class_head,
+ cp_parser_lookup_name,
+ cp_parser_constructor_declarator_p): Likewise.
+ * pt.c (instantiate_class_template,
+ resolve_typename_type): Likewise.
+
+2005-01-03 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/14136
+ * parser.c (cp_parser_unqualified_id): Do not issue error message
+ for typedef-name as destructor declarator when performing an
+ uncommitted tentative parse.
+
+2005-01-01 Steven Bosscher <stevenb@suse.de>
+
+ PR middle-end/17544
+ * decl.c (finish_function): Fix comment. Annotate the compiler
+ generated return with the current file name and line 0.
+
+
+Copyright (C) 2005 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2006 b/gcc-4.9/gcc/cp/ChangeLog-2006
new file mode 100644
index 000000000..09df1ef21
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2006
@@ -0,0 +1,3502 @@
+2006-12-31 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/29731
+ * parser.c (cp_parser_primary_expression): Return error_mark_node when
+ a statement-expression is found outside of a function body.
+
+2006-12-28 Kazu Hirata <kazu@codesourcery.com>
+
+ * cp-tree.h (TYPE_NAMESPACE_SCOPE_P, TYPE_FUNCTION_SCOPE_P):
+ Remove.
+
+ * decl2.c: Fix a comment typo.
+
+2006-12-21 Andrew Pinski <pinskia@gmail.com>
+
+ PR C++/30225
+ * decl.c (cxx_builtin_function): Only copy the decl if adding
+ it to the std namespace.
+
+2006-12-21 Andrew Pinski <pinskia@gmail.com>
+
+ PR C++/30168
+ * optimize.c (update_cloned_parm): Copy DECL_GIMPLE_REG_P also.
+
+2006-12-22 Kazu Hirata <kazu@codesourcery.com>
+
+ * decl.c: Fix a coment typo.
+
+2006-12-18 Ian Lance Taylor <iant@google.com>
+
+ * decl.c (start_preparsed_function): Add support for
+ -Wmissing-declarations.
+
+2006-12-16 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/29475
+ * cp-tree.h (struct deferred_access_check): New structure to represent a
+ deferred access check. It replaces the previous representation as a tree.
+ (get_deferred_access_checks): Return a vector of struct
+ deferred_access_check instead of a tree list.
+ (perform_access_checks): Take a vector of struct deferred_access_check
+ instead of a tree list.
+ * semantics.c (struct deferred_access): Store the deferred access checks
+ as a vector of struct deferred_access_check instead of a tree list.
+ (push_deferring_access_checks): Handle the change in struct
+ deferred_access.
+ (get_deferred_access_checks): Likewise.
+ (pop_to_parent_deferring_access_checks): Likewise.
+ (perform_or_defer_access_check): Likewise.
+ (perform_access_checks): Take a vector of struct deferred_access_check
+ instead of a tree list.
+ * parser.c (struct tree_check): New structure to store various data
+ associated with a CPP_NESTED_NAME_SPECIFIER or CPP_TEMPLATE_ID token.
+ (struct cp_token): Changed the value field to be a union with a pointer to
+ a struct tree_check for CPP_NESTED_NAME_SPECIFIER or CPP_TEMPLATE_ID
+ tokens and a tree field for all other tokens.
+ (eof_token): Adjusted due to the change in struct cp_token.
+ (cp_lexer_get_preprocessor_token): Likewise.
+ (cp_lexer_purge_token): Likewise.
+ (cp_lexer_purge_tokens_after): Likewise.
+ (cp_lexer_print_token): Likewise.
+ (cp_parser_error): Likewise.
+ (cp_parser_identifier): Likewise.
+ (cp_parser_string_literal): Likewise.
+ (cp_parser_primary_expression): Likewise.
+ (cp_parser_unqualified_id): Likewise.
+ (cp_parser_parenthesized_expression_list): Likewise.
+ (cp_parser_storage_class_specifier_opt): Likewise.
+ (cp_parser_function_specifier_opt): Likewise.
+ (cp_parser_type_specifier): Likewise.
+ (cp_parser_simple_type_specifier): Likewise.
+ (cp_parser_initializer_list): Likewise.
+ (cp_parser_member_specification_opt): Likewise.
+ (cp_parser_attribute_list): Likewise.
+ (cp_parser_objc_expression): Likewise.
+ (cp_parser_objc_protocol_qualifiers): Likewise.
+ (cp_parser_objc_selector): Likewise.
+ (cp_parser_objc_declaration): Likewise.
+ (cp_parser_objc_statement): Likewise.
+ (cp_parser_omp_clause_name): Likewise.
+ (cp_parser_omp_clause_default): Likewise.
+ (cp_parser_omp_clause_schedule): Likewise.
+ (cp_parser_omp_parallel): Likewise.
+ (cp_parser_initial_pragma): Likewise.
+ (pragma_lex): Likewise.
+ (cp_parser_pre_parsed_nested_name_specifier): Likewise.
+ (cp_parser_nested_name_specifier_opt): Likewise.
+ Use cp_token::u::tree_check_value to save the token's value, the
+ associated deferred checks and its qualifying scope.
+ (cp_parser_template_id): Likewise.
+ (cp_parser_template_declaration_after_export): Adjusted the call to
+ get_deferred_access_checks.
+ (cp_parser_init_declarator): Take the access checks as a vector of struct
+ deferred_access_check instead of a tree list.
+ (cp_parser_single_declaration): Likewise.
+ (cp_parser_perform_template_parameter_access_checks): Likewise.
+ (cp_parser_simple_declaration): Adjusted the call to
+ cp_parser_init_declarator.
+ (cp_parser_explicit_specialization): Adjusted the call to
+ cp_parser_single_declaration.
+
+2006-12-13 Ian Lance Taylor <iant@google.com>
+
+ PR c++/19564
+ PR c++/19756
+ * parser.c (cp_parser_expression_stack_entry): Add field
+ lhs_type.
+ (cp_parser_binary_expression): Track tree code of left hand side
+ of expression. Use it when calling build_x_binary_op.
+ (cp_parser_selection_statement): Add if_p parameter. Change all
+ callers. Warn about ambiguous else.
+ (cp_parser_statement): Add if_p parameter. Change all callers.
+ (cp_parser_implicitly_scoped_statement): Likewise.
+ * typeck.c (build_x_binary_op): Add parameters arg1_code and
+ arg2_code. Change all callers. Call warn_about_parentheses.
+ * cp-tree.h (build_x_binary_op): Update declaration.
+
+2006-12-12 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * decl.c (build_enumerator): Update error message to match C
+ front-end.
+
+2006-12-11 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (var_finalized_p): Update for renamed varpool functions.
+
+2006-12-09 Zack Weinberg <zackw@panix.com>
+
+ * parser.c (yydebug, enum pragma_omp_clause): Delete.
+
+2006-12-07 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29732
+ * cp-tree.h (DECL_USE_TEMPLATE): Mention partial specializations.
+ (explicit_class_specialization_p): Declare.
+ * pt.c (explicit_class_specialization_p): New function.
+ * parser.c (cp_parser_init_declarator): Check correct number of
+ template parameters for in-class function definitions.
+ (cp_parser_check_declrator_template_parameters): Stop looking for
+ template classes when we find an explicit specialization.
+
+2006-12-07 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/29980
+ * cp_parser_elaborated_type_specifier: Check
+ the return value of check_elaborated_type_specifier.
+
+2006-12-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29730
+ * parser.c (cp_parser_init_declarator): Reject initialization of
+ functions.
+
+2006-12-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29729
+ * decl2.c (check_member_template): Move check for member
+ templates in local classes to ...
+ * parser.c (cp_parser_template_declaration_after_export):
+ ... here.
+
+ PR c++/29728
+ * decl.c (check_array_designated_initializer): New function.
+ (maybe_deduce_size_from_array_init): Use it.
+ (reshape_init_array): Likewise.
+
+2006-12-05 Aldy Hernandez <aldyh@redhat.com>
+
+ Merge from gimple-tuples-branch.
+
+ 2006-10-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (cp_gimplify_expr): Adjust for GIMPLE_MODIFY_STMT.
+ (cxx_omp_clause_apply_fn): Adjust for GIMPLE_MODIFY_STMT.
+ (cxx_omp_clause_copy_ctor): Same.
+ (cxx_omp_clause_assign_op): Same.
+
+ 2006-09-28 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-tree.h (union lang_tree_node): Gimple statements do not
+ have a TREE_CHAIN.
+ (TREE_INDIRECT_USING): Look in base.
+
+2006-12-04 Jan Hubicka <jh@suse.cz>
+
+ * cp-objcp-common.c (cp_expr_size): Return NULL in the case
+ size is undefined.
+
+2006-12-04 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29733
+ * pt.c (tsubst_decl): Disallow variables of function type.
+
+ PR c++/29632
+ * call.c (add_builtin_candidate): Do not permit NULL pointer
+ constants to be compared with template parameters.
+
+2006-12-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * pt.c (for_each_template_parm_r) <INTEGER_TYPE>: New case.
+ Call for_each_template_parm on TYPE_MIN_VALUE and TYPE_MAX_VALUE.
+
+2006-12-03 Richard Henderson <rth@redhat.com>
+ Andrew Pinski <pinskia@gmail.com>
+
+ PR C++/14329
+ * error.c (cp_printer) <'D'>: Handle DECL_DEBUG_EXPR.
+
+2006-12-02 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR C++/30033
+ * decl.c (cp_tree_node_structure): Handle STATIC_ASSERT.
+
+2006-12-02 Kazu Hirata <kazu@codesourcery.com>
+
+ * name-lookup.c: Follow spelling conventions.
+
+2006-12-01 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (poplevel): Check DECL_INITIAL invariant.
+ (duplicate_decls): Preserve DECL_INITIAL when eliminating
+ a new definition in favour of an old declaration.
+ (start_preparsed_function): Define and document value of
+ DECL_INITIAL before and after routine.
+ (finish_function): Check DECL_INITIAL invariant.
+ * parser.c
+ (cp_parser_function_definition_from_specifiers_and_declarator):
+ Skip duplicate function definitions.
+
+2006-12-01 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/30022
+ * typeck.c (type_after_usual_arithmetic_conversions):
+ Fix assertion for vector types.
+ (build_binary_op): Use temporary for inner type of vector types.
+
+2006-12-01 Ryan Mansfield <rmansfield@qnx.com>
+
+ PR c++/29066
+ * typeck.c (build_binary_op): Fix pointer to member function
+ comparison for ptrmemfunc_vbit_in_delta targets.
+
+2006-12-01 Dirk Mueller <dmueller@suse.de>
+
+ PR c++/18313
+ * decl.c (grokdeclarator): Warn for type qualifiers on return
+ type for non-dependent types.
+ * pt.c (tsubst_function_type): Warn for type qualifiers on
+ return type for dependent types.
+
+2006-11-30 Geoffrey Keating <geoffk@apple.com>
+
+ * rtti.c (get_tinfo_decl): Handle return value from
+ pushdecl_top_level_and_finish.
+
+2006-11-29 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/29022
+ * parser.c (cp_parser_class_head): Move processing
+ of any base classes to...
+ (cp_parser_class_specifier) ...here. Take an extra
+ tree* parameter for any base classes. Only process
+ them if the opening brace was found.
+
+2006-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/29735
+ * decl.c (grokfndecl): Check main's type after applying
+ attributes, not before.
+
+2006-11-27 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vcall_offset_vtbl_entries): Do not add vcall
+ entries for a primary construction virtual table.
+
+2006-11-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29886
+ * parser.c (cp_parser): Add in_function_body.
+ (cp_parser_new): Initialize it.
+ (cp_parser_primary_expression): Use parser->in_function_body
+ instead of at_function_scope_p.
+ (cp_parser_asm_definition): Likewise.
+ (cp_parser_direct_declarator): Likewise.
+ (cp_parser_class_specifier): Clear parser->in_function_body.
+ (cp_parser_constructor_declarator_p): Use parser->in_function_body
+ instead of at_function_scope_p.
+ (cp_parser_function_body_after_declarator): Set
+ parser->in_function_body.
+
+2006-11-21 Douglas Gregor <doug.gregor@gmail.com>
+
+ * cp-tree.def (STATIC_ASSERT): New.
+ * cp-objcp-common.c (cp_tree_size): Handle STATIC_ASSERT.
+ * error.c (dump_decl): Handle STATIC_ASSERT.
+ * cp-tree.h (STATIC_ASSERT_CONDITION): New.
+ (STATIC_ASSERT_MESSAGE): New.
+ (STATIC_ASSERT_SOURCE_LOCATION): New.
+ (struct tree_static_assert): New.
+ (enum cp_tree_node_structure_enum): Add TS_CP_STATIC_ASSERT.
+ (union lang_tree_node): Add static_assertion.
+ (finish_static_assert): Declare.
+ * cxx-pretty-print.c (pp_cxx_statement): Handle STATIC_ASSERT.
+ (pp_cxx_declaration): Handle STATIC_ASSERT.
+ * pt.c (instantiate_class_template): Handle
+ STATIC_ASSERT members.
+ (tsubst_expr): Handle STATIC_ASSERT statements.
+ * semantics.c (finish_static_assert): New.
+ * lex.c (D_CPP0X): New.
+ (reswords): Add static_assert keyword.
+ (init_reswords): If not flag_cpp0x, mask out C++0x keywords.
+ * parser.c (cp_parser_block_declaration): Parse static
+ assertions.
+ (cp_parser_static_assert): New.
+ (cp_parser_member_declaration): Parse static assertions.
+
+2006-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/29570
+ * decl.c (cp_finish_decl): Check for value dependent brace enclosed
+ scalar initializer.
+
+ PR c++/29734
+ * cp-tree.h (WANT_VECTOR): Define.
+ (WANT_ARITH): Add WANT_VECTOR.
+ * cvt.c (build_expr_type_conversion): Handle vector types.
+ * typeck.c (build_unary_op): Add WANT_VECTOR to
+ build_expr_type_conversion flags.
+
+2006-11-20 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/29475
+ * cp-tree.h (enforce_access, perform_or_defer_access_check): Added an
+ extra argument that represents the declaration to use to print
+ potential error messages.
+ * init.c (build_offset_ref): Adjusted the call to
+ perform_or_defer_access_check.
+ * class.c (alter_access, resolve_address_of_overloaded_function):
+ Likewise.
+ * decl.c (make_typename_type, make_unbound_class_template): Likewise.
+ * search.c (lookup_member): Likewise.
+ * friend.c (add_friend): Likewise.
+ * parser.c (cp_parser_template_id,
+ cp_parser_pre_parsed_nested_name_specifier): Likewise.
+ * semantics.c (finish_non_static_data_member,
+ check_accessibility_of_qualified_id, finish_id_expression): Likewise.
+ (pop_to_parent_deferring_access_checks, perform_access_checks,
+ perform_or_defer_access_check): Adjusted the call to enforce_access.
+ * call.c (enforce_access): Use the new extra argument to build the
+ error message.
+ (build_op_delete_call): Adjusted the call to
+ perform_or_defer_access_check.
+ (build_over_call): Likewise.
+
+2006-11-16 Dirk Mueller <dmueller@suse.de>
+
+ * name-lookup.c (begin_scope): Use GGC_CNEW instead of
+ GGC_NEW and memset.
+
+2006-11-13 Roger Sayle <roger@eyesopen.com>
+
+ * rtti.c (get_pseudo_ti_init): Ensure that the offset field of the
+ base type info initializer has the correct type.
+
+2006-11-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29518
+ * pt.c (coerce_template_parms): Do not skip_evaluation while
+ substituting template arguments.
+
+2006-11-11 Richard Guenther <rguenther@suse.de>
+
+ * typeck.c (build_unary_op): Remove handling of FIX_CEIL_EXPR,
+ FIX_FLOOR_EXPR and FIX_ROUND_EXPR.
+
+2006-11-03 Roger Sayle <roger@eyesopen.com>
+
+ * call.c (build_op_delete_call): Test user-visible type against
+ size_type_node, instead of against the internal type, sizetype.
+ * class.c (type_requires_array_cookie): Likewise.
+ * mangle.c (write_builtin_type) <INTEGER_TYPE>: Remove special
+ handling of TYPE_IS_SIZETYPE.
+ * typeck.c (type_after_usual_arithmetic_conversions): Remove
+ special case handling of TYPE_IS_SIZETYPE.
+ (comptypes): Likewise.
+
+2006-11-01 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * decl.c (get_atexit_node): Reference atexit, not __cxa_exit.
+ if targetm.cxx.use_atexit_for cxa_atexit.
+ (start_cleanup_fn): Likewise.
+ (register_dtor_fn): Likewise.
+
+2006-09-25 Geoffrey Keating <geoffk@apple.com>
+
+ * decl2.c (cp_write_global_declarations): Rename from
+ cp_finish_file.
+ * cp-lang.c (finish_file): Don't call cp_finish_file.
+ * cp-tree.h (cp_write_global_declarations): Rename from
+ cp_finish_file.
+ * cp-objcp-common.h (LANG_HOOKS_WRITE_GLOBALS): Define to
+ cp_write_global_declarations.
+
+2006-10-31 Geoffrey Keating <geoffk@apple.com>
+
+ * name-lookup.c (get_anonymous_namespace_name): New.
+ (push_namespace_with_attribs): Use get_anonymous_namespace_name.
+ * decl2.c (start_objects): Update for rename of
+ get_file_function_name_long.
+
+2006-10-30 Dirk Mueller <dmueller@suse.de>
+
+ PR c++/28704
+ * decl.c (grokdeclarator): Duplicate diagnostic message
+ for easier translation.
+ * decl.c (grokdeclarator): Fix line-wrapping.
+
+2006-10-30 Dirk Mueller <dmueller@suse.de>
+
+ PR c++/6321
+ * decl.c (grokfndecl): Use check_main_parameter_types.
+
+2006-10-30 Dirk Mueller <dmueller@suse.de>
+
+ PR c++/28669
+ * decl.c (grokfndecl): Duplicate warning message for
+ easier translation.
+
+2006-10-30 Dirk Mueller <dmueller@suse.de>
+
+ * typeck.c (build_unary_op): Fix indenting. Use G_().
+
+2006-10-29 Dirk Mueller <dmueller@suse.de>
+
+ PR c++/29089
+ * typeck.c (build_unary_op): Duplicate warning message
+ for easier translation.
+
+2006-10-29 Dirk Mueller <dmueller@suse.de>
+
+ PR c++/16307
+ * typeck.c (build_array_ref): Warn for char subscriptions
+ on pointers.
+
+2006-10-29 Kazu Hirata <kazu@codesourcery.com>
+
+ * decl.c: Fix a comment typo.
+
+2006-10-28 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR C++/29295
+ * typeck.c (build_unary_op): Use same_type_p when comparing to
+ boolean type.
+
+2006-10-29 Dirk Mueller <dmueller@suse.de>
+
+ PR c++/29033
+ * typeck.c (build_binary_op): Duplicate warning message
+ for better translation.
+
+2006-10-23 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+
+ * decl.c (builtin_function_1): Move common code to
+ add_builtin_function.
+ (builtin_function): Rename to cxx_builtin_function.
+ Change the signature.
+ * call.c: Include langhooks.h.
+ (build_java_interface_fn_ref): Replace calls to
+ builtin_function with add_builtin_function.
+ * Make-lang.in (cp/call.o): Depend on langhooks.h.
+ * cp-objcp-common.h (LANG_HOOKS_BUILTIN_FUNCTION): Define as
+ cxx_builtin_function.
+ * cp-tree.h (builtin_function): Rename to cxx_builtin_function.
+ Change the signature.
+
+2006-10-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20647
+ * rtti.c (tinfo_base_init): The type info string is always global.
+
+2006-10-20 Lee Millward <lee.millward@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28053
+ * decl2.c (grokbitfield): Detect invalid non-integral
+ types earlier when possible.
+
+2006-10-18 Mark Shinwell <shinwell@codesourcery.com>
+
+ PR c++/26884
+ * typeck2.c (digest_init): Raise error upon attempts to
+ initialize arrays with variables.
+
+2006-10-17 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/27952
+ * cp-tree.h (xref_basetypes): Return bool instead of void.
+ * decl.c (xref_basetypes): Adjust definition. Return false
+ if the class bases are invalid.
+ * parser.c (cp_parser_class_head): Check the return value
+ from xref_basetypes.
+
+2006-10-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28261
+ * parser.c (cp_lexer_next_token_is_decl_specifier_keyword): Add
+ comment.
+
+ PR c++/28261
+ * parser.c (cp_lexer_next_token_is_decl_specifier_keyword): New
+ function.
+ (cp_parser_constructor_declarator_p): Use it.
+ (cp_parser_check_type_definition): Return a value indicating
+ whether or not the definition is valid.
+ (cp_parser_enum_specifier): Skip invalid enum definitions.
+
+2006-10-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29039
+ * typeck2.c (build_functional_cast): Don't zero-initialize
+ non-PODs; instead, call their constructors.
+ * method.c (synthesize_method): Always build mem-initializers, if
+ we're synthesizing the default constructor.
+
+2006-10-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27270
+ * decl.c (reshape_init_class): Move check for designated
+ to ...
+ * parser.c (cp_parser_initializer_list): ... here.
+ * pt.c (tsubst_copy_and_build): Use finish_compound_literal.
+
+2006-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27270
+ * typeck2.c (process_init_constructor_array): Reword comment.
+ * pt.c (tsubst_copy_and_built): Call reshape_init before calling
+ digest_init.
+
+ PR c++/29408
+ * parser.c (cp_parser_using_declaration): Stop parsing when
+ something goes wrong with an access declaration.
+
+ PR c++/29435
+ * typeck.c (cxx_sizeof_or_alignof_type): Complete non-dependent
+ types when their sizes are required. Refine test for VLAs.
+
+ PR c++/28211
+ * parser.c (cp_parser_template_argument): Don't consider "&var" a
+ possible constant-expression.
+ * pt.c (convert_nontype_argument): Refine handling of arguments of
+ pointer type.
+
+2006-10-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28506
+ * parser.c (function_declarator_p): New function.
+ (cp_parser_init_declarator): Use it.
+ (cp_parser_member_declaration): Likewise.
+
+2006-10-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29318
+ * rtti.c (get_tinfo_decl): Refuse to create type info objects for
+ variably modified types.
+
+2006-10-12 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/27961
+ * decl.c (start_decl): Return error_mark_node if a
+ function is initialized like a variable.
+ (check_var_type): If a variable of field is declared void,
+ set the type to error_mark_node.
+ (grokdeclarator): Check the return type of check_var_type.
+ * class.c (finish_struct_1): Robustify.
+
+2006-10-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29175
+ * decl.c (check_initializer): Issue errors about trying to
+ initialize arrays whose elements have variable size.
+
+2006-10-11 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/29024
+ * cp-tree (struct cp_decl_specifier_seq): Rename to
+ conflicting_specifiers_p
+ * parser.c (cp_parser_set_storage_class): Set
+ conflicting_specifiers_p for the input decl specifier
+ if a typedef specifier is present. Rename uses of
+ multiple_specifiers_p to conflicting_specifiers_p.
+ (cp_parser_decl_specifier_seq) <RID_TYPEDEF>: If a storage
+ class specifier has already been set for this declaration,
+ set conflicting_specifiers_p to true on the decl_specs.
+ * decl.c (grokdeclarator): Rename uses of
+ multiple_specifiers_p to conflicting_specifiers_p.
+
+2006-10-10 Brooks Moses <bmoses@stanford.edu>
+
+ * Make-lang.in: Added "c++.pdf" target support.
+
+2006-10-10 Richard Guenther <rguenther@suse.de>
+
+ PR rtl-optimization/29323
+ * decl.c (finish_function): Set TREE_NOTHROW only for
+ functions that bind local.
+
+2006-10-09 Richard Henderson <rth@redhat.com>
+
+ Revert emutls patch.
+
+2006-10-04 Richard Henderson <rth@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (grokvardecl): Don't error if !have_tls.
+ (grokdeclarator): Likewise.
+ * parser.c (cp_parser_omp_threadprivate): Likewise.
+
+2006-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29020
+ * friend.c (do_friend): Improve comments; add assertion.
+ * parser.c (cp_parser_nested_name_specifier_opt): Resolve
+ typenames for qualified names used in declarations, even when
+ caching qualified name lookup.
+
+ PR c++/29138
+ * decl2.c (grokfield): Don't handle access declarations here.
+ * parser.c (cp_parser_using_declaration): Handle access
+ declarations too.
+ (cp_parser_block_declaration): Adjust calls to
+ cp_parser_using_declaration.
+ (cp_parser_member_declaration): Likewise. Use
+ cp_parser_using_declaration to look for access_declarations.
+
+2006-10-03 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/29291
+ * init.c (build_new): Check for invalid init.
+
+2006-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29226
+ * typeck.c (cxx_sizeof_or_alignof_type): Tidy. In templates, do
+ not try to actually evaluate sizeof for a VLA type.
+
+2006-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29105
+ * pt.c (tsubst_baselink): Substituteinto the qualifying scope.
+ * semantics.c (baselink_for_fns): Build a baselink, even when
+ processing a template.
+
+ PR c++/29080
+ * parser.c (cp_parser_postfix_dot_deref_expression): Use
+ BASELINK_ACCESS_BINFO as the qualifying scope when calling
+ adjust_result_of_qualified_name_lookup.
+
+2006-09-25 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/27329
+ PR c++/26938
+ * cp-tree.h (redeclare_class_template): Adjust declaration
+ to return bool instead of void.
+ * pt.c (redeclare_class_template): Update definition.
+ Return false on error.
+ * decl.c (xref_tag): Return error_mark_node if
+ redeclare_class_template returned false.
+
+ PR c++/27667
+ * cp-tree.h (begin_specialization): Return bool
+ instead of void.
+ * pt.c (check_specialization_scope): Likwise.
+ Adjust comment. Return false if a specialization
+ isn't permitted in the current scope.
+ (begin_specialization): Use the return value of
+ check_specialization_scope.
+ * parser.c (cp_parser_explicit_specialization): If
+ begin_specialization returned false, skip the rest
+ of the specialization.
+
+2006-09-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29016
+ * typeck.c (build_unary_op): Don't form an ADDR_EXPR around a
+ BASELINK.
+
+2006-09-21 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/28861
+ * decl.c (shadow_tag): Return error_mark_node
+ if maybe_process_partial_specialization failed.
+
+ PR c++/28303
+ * decl.c (grokdeclarator): Return error_mark_node on
+ declaration with two or more data types.
+
+2006-09-20 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR target/27650
+ * class.c (check_for_override): Remove dllimport from virtual
+ methods.
+
+2006-09-18 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR c++/29087
+ * parser.c (cp_parser_labeled_statement): Return nothing. Do
+ not take in_statement_expr and in_compound as arguments. Rename
+ to cp_parser_label_for_labeled_statement. Parse only the label,
+ not the statement.
+ (cp_parser_statement): Parse the statement of a labeled-statement
+ from here, using tail recursion.
+
+2006-09-14 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR C++/29002
+ * init.c (build_zero_init): If we have an error mark node for
+ the array size, return.
+
+2006-09-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28991
+ * cp-objcp-common.c (cxx_staticp): New function.
+ * cp-objcp-common.h (LANG_HOOOKS_STATICP): Use it.
+ * cp-tree.h (cxx_staticp): New function.
+
+2006-09-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/28996
+ * cvt.c (convert_to_void): Strip COMPONENT_REF to functions.
+
+2006-09-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28858
+ * parser.c (cp_parser_skip_until_found): Rename to
+ cp_parser_skip_to_end_of_template_parameter_list. Remove last two
+ parameters. Track levels of '< ... >'. Stop at '{', '}', or ';'.
+ Reorganize. Adjust comment.
+ (cp_parser_template_declaration_after_export): Adjust call.
+ (cp_parser_enclosed_template_argument_list): Likewise.
+
+2006-09-07 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR C++/28906
+ * init.c (build_new_1): Build a distinct type copy
+ for the array type that was returned from
+ build_cplus_array_type.
+
+2006-09-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/27371
+ * cvt.c (convert_to_void): Enable previous change.
+
+ PR c++/26957
+ * method.c (use_thunk): Clear DECL_HAS_VALUE_EXPR_P on copied
+ parms.
+
+2006-09-07 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/28284
+ * pt.c (fold_non_dependent_expr): Make sure expr is not
+ dereferenced if it is NULL.
+
+2006-09-06 Zak Kipling <zak@transversal.com>
+
+ PR c++/26195
+ * decl.c (make_rtl_for_nonlocal_decl),
+ (start_preparsed_function): Don't use lbasename on
+ input_filename when calling get_fileinfo.
+ * semantics.c (begin_class_definition): Likewise.
+ * lex.c (cxx_make_type): Likewise.
+ (handle_pragma_interface): Call get_fileinfo on input_filename,
+ not on the parameter to the directive.
+
+2006-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28903
+ * pt.c (tsubst): Use fold_non_dependent_expr to fold array
+ dimensions.
+
+ PR c++/28886
+ * pt.c (unify): Avoid unnecessary calls to fold_build2 for array
+ dimensions.
+
+2006-09-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/27371
+ * cvt.c (convert_to_void): Strip useless TARGET_EXPR.
+ * cp-tree.h (TARGET_EXPR_IMPLICIT_P): New macro.
+ * tree.c (build_cplus_new): Set it.
+
+ PR c++/26696
+ * cvt.c (convert_to_void): Replace a subexpression with no side
+ effects with void_zero_node.
+ * tree.c (is_overloaded_fn): Look through COMPONENT_REF.
+ (get_first_fn): Ditto.
+ * decl.c (grokdeclarator): No need to look through COMPONENT_REF.
+
+2006-09-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/26571
+ * parser.c (cp_parser_diagnose_invalid_type_name): Handle the case
+ where the name is a type used incorrectly.
+
+ PR c++/26671
+ * typeck.c (maybe_warn_about_returning_address_of_local): Look
+ through COMPONENT_REF and ARRAY_REF.
+
+ PR c++/26102
+ * name-lookup.c (do_class_using_decl): Try to find the base even
+ if bases_dependent_p.
+ * pt.c (type_dependent_expression_p): A USING_DECL is dependent.
+
+ PR c++/19809
+ * pt.c (tsubst_friend_function): Set DECL_INITIAL before pushdecl.
+
+2006-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR 23287 Revert my 2006-09-01 patch.
+ * parser.c: Reverted.
+ * pt.c: Reverted.
+
+2006-09-02 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/27670
+ PR c++/27493
+ PR c++/27494
+ PR c++/27397
+ * parser.c (cp_parser_template_parameter_list): Add
+ invalid template parameters to the parameter list as
+ error_mark_node.
+
+2006-09-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/28878
+ * except.c (build_throw): Only set current_function_returns_abnormally
+ if cfun is not NULL.
+
+ PR c++/26917
+ * repo.c (repo_file): Remove.
+ (open_repo_file, reopen_repo_file_for_write): Return fopened
+ FILE * instead of setting global repo_file variable.
+ (init_repo): Adjust caller.
+ (finish_repo): Likewise. Return instead of goto out before
+ reopen_repo_file_for_write has been called.
+
+2006-09-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/28705
+ * semantics.c (finish_call_expr): Add assert.
+ * name-lookup.c (lookup_arg_dependent): Check we found an overload
+ or an object.
+
+ PR c++/23287
+ * parser.c (cp_parser_id_expression): Add member_p
+ argument. Update all callers.
+ (cp_parser_unqualified_id): Likewise. Lookup a destructor name in
+ the object's scope, if valid.
+ (cp_parser_global_scope_opt): Add object_scope_valid_p. Update
+ callers.
+ (cp_parser_postfix_dot_deref_expression): Set object_scope.
+ * pt.c (tsubst_copy_and_build): Lookup dependent dtor name here.
+
+2006-08-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/26670
+ * class.c (check_field_decls): Don't unset TYPE_PACKED until all
+ the fields have been processed.
+
+2006-08-29 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR C++/28349
+ * call.c (build_x_va_arg): Remove the reference type
+ from the type before creating the pointer type.
+
+2006-08-29 J"orn Rennecke <joern.rennecke@st.com>
+
+ PR c++/28139
+ * except.c (expand_start_catch_block): Use correct types for bitwise
+ copy.
+
+2006-08-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/26670
+ * class.c (check_field_decls): Unset TYPE_PACKED (t) if one of the
+ fields can't be packed.
+
+ PR c++/26577
+ * cvt.c (convert_to_void): Don't automatically load from volatiles
+ of TREE_ADDRESSABLE type.
+
+2006-08-28 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28860
+ * cp-tree.h (maybe_process_partial_specialization): Return
+ tree instead of void.
+ * parser.c (cp_parser_class_head): Use return value of
+ maybe_process_partial_specialization.
+ * pt.c (maybe_process_partial_specialization): Return error_mark_node
+ for broken specializations, TYPE otherwise. Check for template
+ template parameters.
+
+2006-08-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28058
+ * pt.c (register_specialization): Return error_mark_node for
+ specialization-after-instantiation.
+ * decl2.c (mark_used): Mark the main function used when one of its
+ clones is used.
+
+2006-08-27 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/26573
+ * class.c (check_field_decls): Don't issue error about
+ local classes containing static data members.
+
+2006-08-26 Joseph S. Myers <joseph@codesourcery.com>
+
+ PR c++/24009
+ * parser.c (struct cp_token): Add input_file_stack_index.
+ (eof_token): Update.
+ (cp_lexer_get_preprocessor_token): Save input_file_stack_tick.
+ (cp_lexer_set_source_position_from_token): Restore input file
+ stack.
+
+2006-08-26 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/28736
+ PR c++/28737
+ PR c++/28738
+ * pt.c (process_template_parm): Store invalid template
+ parameters as a TREE_LIST with a TREE_VALUE of error_mark_node.
+ (push_inline_template_parms_recursive): Check for template
+ parameters having a TREE_VALUE of error_mark_node rather than
+ check the parameter itself.
+ (mangle_class_name_for_template): Likewise.
+ (comp_template_parms): When comparing the individual template
+ parameters, return 1 if either is error_mark_node.
+ (current_template_args): Robustify.
+ (redeclare_class_template): Likewise.
+
+2006-08-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28588
+ * class.c (resolve_address_of_overloaded_function): Add
+ access_path parameter. Perform access checks.
+ (instantiate_type): Adjust call to
+ resolve_address_of_overloaded_function. Remove unnecessary code.
+ * tree.c (is_overloaded_fn): Document. Return 2 when there are
+ acutally multiple functions.
+ (really_overloaded_fn): Use is_overloaded_fn.
+ * mangle.c (write_expression): Handle BASELINKs.
+ * cp-tree.h (really_overloaded_fn): Return bool.
+ (baselink_for_fns): Declare.
+ * search.c (lookup_member): Check access for single static
+ functions here.
+ * pt.c (convert_nontype_argument_function): Handle BASELINKs.
+ (tsubst_copy_and_build): Generate BASELINKs for template-ids.
+ * semantics.c (finish_call_expr): Use baselink_for_fns.
+ (baselink_for_fns): New function.
+ (finish_id_expression): Use it.
+ * parser.c (cp_parser_template_argument): Don't strip BASELINKs.
+
+ PR c++/28595
+ * pt.c (tsubst): Issue errors about attempts to create VLAs at
+ template-instantiation time.
+
+2006-08-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28853
+ * typeck2.c (cxx_incomplete_type_diagnostic): Handle template
+ template parameters. Improve error message for template type
+ parameters.
+
+ PR c++/28852
+ * cp-tree.h (grok_op_properties): Return bool instead of void.
+ * decl.c (grokfndecl): Discard invalid operator declarations.
+ (copy_fn_p): Revert change for PR 27547.
+ (grok_op_properties): Return error status (true on success).
+ * pt.c (tsubst_decl): Discard invalid operator declarations.
+
+2006-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28056
+ * decl.c (grokdeclarator): Disallow declarations with qualified
+ names in local scopes.
+
+2006-08-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/27787
+ * decl.c (make_typename_type): Only try and resolve it when
+ context is not dependent. Refactor.
+ * decl2.c (check_classfn): Push to class scope before looking for
+ the function.
+
+2006-08-24 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR driver/28528
+ * g++spec.c (lang_specific_driver): Always check if we need to
+ swallow a space-separated arg to '-x'.
+ * lang-specs.h: Don't create ouput files for '-xc++-header'
+ if -fsyntax-only.
+
+2006-08-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/27714
+ * pt.c (push_template_decl_real): A friend template with class
+ scope isn't primary.
+
+2006-08-23 Benjamin Smedberg <benjamin@smedbergs.us>
+
+ PR c++/28687
+ * rtti.c (build_dynamic_cast, build_dynamic_cast_1):
+ Move -fno-rtti check to be more specific.
+
+2006-08-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/23372
+ * call.c (build_over_call): Don't make a copy here if build_call
+ will make one too.
+
+2006-08-22 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR C++/28450
+ * cp/init.c (build_zero_init): Handle VECTOR_TYPE and
+ COMPLEX_TYPEs.
+
+2006-08-22 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/28420
+ * parser.c (cp_parser_postfix_expression): Make sure that the
+ saved value for parser->type_definition_forbidden_message is
+ restored before returning to avoid an invalid free().
+
+2006-08-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/28659
+ * typeck.c (merge_types): If either of the types have the right
+ attributes, return that one.
+
+ * tree.c (cp_build_type_attribute_variant): Make sure we aren't
+ doing this to class types.
+ * typeck.c (original_type): Deal with type quals properly.
+
+2006-08-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/27115
+ * semantics.c (finish_stmt_expr_expr): Don't try to voidify here,
+ just leave the expression as it is.
+ (finish_stmt_expr): If the statement-expression has class type,
+ wrap it in a TARGET_EXPR.
+ * cp-gimplify.c (cp_gimplify_init_expr): Don't bother with
+ CLEANUP_POINT_EXPR.
+ * except.c (build_throw): Give the CLEANUP_POINT_EXPR void type.
+
+2006-08-21 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/26269
+ * decl.c (duplicate_decls): Return early if either
+ newdecl or olddecl is error_mark_node.
+
+ PR c++/28505
+ * decl.c (grokdeclarator): Return early after
+ issuing diagnostic about an incomplete type.
+
+ PR c++/28741
+ * tree.c (decl_anon_ns_mem_p): Robustify.
+ * decl2.c (determine_visibility): Likewise.
+
+2006-08-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28341
+ * tree.c (cast_valid_in_integral_constant_expression_p): New
+ function.
+ * cp-tree.h (tsubst_copy_and_build): Adjust prototype.
+ * pt.c (tsubst_expr): Add integral_constant_expression_p
+ parameter.
+ (fold_non_dependent_expr): Adjust callers of
+ tsubst_{expr,copy_and_build}.
+ (tsubst_friend_function): Likewise.
+ (tsubst_template_arg): Likewise.
+ (tsubst_default_argument): Likewise.
+ (tsubst_decl): Likewise.
+ (tsubst): Likewise.
+ (tsubst_omp_clasuses): Likewise.
+ (regenerate_decl_fromp_template): Likewise.
+ (instantiate_decl): Likewise.
+ (tsubst_initializer_list): Likewise.
+ (tsubst_enum): Likewise.
+ (tsubst_expr): Use RECUR throughout.
+ (tsubst_copy_and_build): Change definition of RECUR. Do not allow
+ invalid casts in integral constant expressions.
+ * parser.c (cp_parser_postfix_expression): Use
+ cast_valid_in_integral_constant_expression_p.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_functional_cast): Likewise.
+
+ PR c++/28346
+ * pt.c (tsubst_qualified_id): Do not strip references from
+ OFFSET_REFs.
+
+2006-08-17 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28606
+ * parser.c (cp_parser_diagnose_invalid_type_name): Handle BIT_NOT_EXPR.
+ Fix formatting.
+ (cp_parser_parse_and_diagnose_invalid_type_name): Tighten condition
+ for valid type-names.
+ (cp_parser_unqualified_id): Fix error handling for destructors.
+
+ PR c++/28710
+ * decl.c (xref_tag): Improve error message. Return early on error.
+
+ PR c++/28711
+ * pt.c (tsubst_copy_and_build) <case CONSTRUCTOR>: Robustify.
+
+2006-08-17 Paolo Bonzini <bonzini@gnu.org>
+
+ PR c++/28573
+ * semantics.c (finish_offsetof): Add new argument to fold_offsetof.
+
+2006-08-16 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/28302
+ * typeck.c (build_unary_op <case BIT_NOT_EXPR:>): Don't call
+ perform_integral_promotions for non integral type.
+
+2006-08-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/28385
+ * pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Ignore quals from template
+ if arg is a function.
+
+2006-08-16 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28593
+ * init.c (build_new): Return early on invalid placement.
+
+2006-08-15 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/28594
+ * pt.c (process_template_parm): Robustify.
+
+2006-08-14 Steve Ellcey <sje@cup.hp.com>
+
+ PR c++/28288
+ PR c++/14556
+ * operators.def: Remove <?, ?>, <?=, and >?= operators.
+ * parser.c: Remove CPP_MIN, CPP_MAX, CPP_MIN_EQ, and CPP_MAX_EQ.
+ (cp_parser_warn_min_max): Remove.
+
+2006-08-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/28559
+ * parser.c (cp_parser_elaborated_type_specifier): Also ignore
+ attributes applied to a TYPENAME_TYPE.
+
+2006-08-09 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/28637
+ * pt.c (coerce_template_parms): Copy across the
+ invalid template arguments to the new template inner arguments.
+ (retrieve_specialization): Robustify.
+
+ PR c++/28638
+ * pt.c (coerce_template_template_parms): Robustify.
+
+ PR c++/28639
+ * error.c (dump_template_parms): Robustify.
+
+ PR c++/28640
+ * pt.c (redeclare_class_template): Robustify.
+
+ PR c++/28641
+ * pt.c (type_unification_real): Robustify.
+
+2006-08-03 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/28347
+ * decl.c (start_decl): Return error_mark_node if a
+ diagnostic was issed for an invalid typedef initialization.
+
+2006-08-03 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27508
+ * parser.c (cp_parser_unqualified_id): Check for invalid scopes
+ when parsing destructor names.
+
+ PR c++/28274
+ * decl.c (duplicate_decls): Call check_default_args here.
+ (start_preparsed_function): Do not call check_default_args.
+ * name-lookup.c (pushdecl_maybe_friend): Only call
+ check_default_args if duplicate_decls got bypassed.
+
+2006-08-02 Richard Guenther <rguenther@suse.de>
+
+ PR c++/28479
+ Revert
+ 2006-07-05 Richard Guenther <rguenther@suse.de>
+ Andrew Pinski <pinskia@gcc.gnu.org>
+
+ PR c++/27084
+ * cp-objcp-common.c (cxx_types_compatible_p): Ignore
+ top level qualifiers for pointer type comparisons.
+
+2006-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28557
+ * pt.c (tsubst_baselink): Substitute into BASELINK_OPTYPE.
+
+2006-07-31 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28523
+ * tree.c (stabilize_expr): Tweak documentation. Add assertion.
+ (stabilize_call): Tweak documentation.
+ (stabilize_init): Only call stabilize_call for calls.
+
+2006-08-01 Steve Ellcey <sje@cup.hp.com>
+
+ PR c++/28432
+ * decl2.c (check_classfn): Remove early return.
+ * search.c (lookup_member): Return NULL with bad type.
+
+2006-08-01 Steve Ellcey <sje@cup.hp.com>
+
+ PR c++/28256
+ * decl.c (check_initializer): Check for 1 initializer on scalar types.
+
+2006-08-01 Daniel Jacobowitz <dan@codesourcery.com>
+
+ PR debug/23336
+ * pt.c (tsubst_copy_and_build): Mark used enum types.
+ * semantics.c (finish_id_expression): Likewise.
+
+2006-07-31 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/6634
+ * decl.c (grokdeclarator): Check whether "long" or "short" was
+ specified for non-integral types.
+
+2006-07-28 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * Make-lang.in: Use $(HEADER_H) instead of header.h in dependencies.
+
+2006-07-28 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/27668
+ PR c++/27962
+ * pt.c (process_template_parm) Store invalid template
+ parameters as error_mark_node in the paramater list.
+ (push_inline_template_parms_recursive): Handle invalid
+ template parameters.
+ (comp_template_parms): Likewise.
+ (check_default_tmpl_arg): Likewise.
+ (coerce_template_template_parms): Likewise.
+ (mangle_class_name_for_template): Likewise.
+ (tsubst_template_parms): Likewise.
+ * error.c (dump_template_argument_list): Likewise.
+
+2006-07-28 Kazu Hirata <kazu@codesourcery.com>
+
+ * cp-tree.h: Fix a comment typo.
+
+2006-07-24 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27572
+ * decl.c (grokdeclarator): Return error_mark_node after invalid
+ typedef.
+
+2006-07-23 Daniel Jacobowitz <dan@codesourcery.com>
+
+ PR c++/28460
+ * decl.c (grokvardecl): Use FROB_CONTEXT.
+ * pt.c (register_specialization): Likewise.
+
+2006-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28025
+ * cp-tree.h (LOOKUP_HIDDEN): New macro. Reformat comments.
+ * name-lookup.c (unqualified_namespace_lookup): There is no way to
+ have a hidden name in non-namespace scopes.
+ * pt.c (tsubst_friend_class): Look for hidden names.
+ * decl.c (lookup_and_check_tag): Fix typo in comment.
+
+ * semantics.c (finish_compound_literal): Fix typo in comment.
+
+2006-07-21 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (determine_visibility): Don't propagate visibility from
+ type to decl.
+ (constrain_class_visibility): Don't warn in system headers.
+ Don't warn about pointer fields.
+
+2006-07-20 Mike Stump <mrs@apple.com>
+
+ * decl2.c (determine_visibility_from_class): Don't use hidden
+ visibility for explicit instantiations.
+
+2006-07-21 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28250
+ * pt.c (tsubst_expr): Only apply DECL_TEMPLATE_INSTANTIATED to
+ valid decls. Cleanup.
+
+ PR c++/28363
+ * semantics.c (check_template_template_default_arg): Simplify
+ error handling.
+
+2006-07-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/28407
+ * decl.c (grokvardecl): Set DECL_THIS_STATIC on file-scope
+ const variables with implicit internal linkage.
+ * tree.c (decl_linkage): Only return lk_external if it's set.
+
+ PR c++/28409
+ * decl2.c (constrain_visibility): Ignore the anonymous namespace
+ for extern "C" decls.
+ (VISIBILITY_STATIC): Rename to VISIBILITY_ANON.
+
+ * decl2.c (constrain_visibility): Remove specified and reason
+ parameters. Don't touch decls that already have explicit visibility.
+ (determine_visibility): Do copy DECL_VISIBILITY_SPECIFIED from
+ template.
+ (determine_visibility_from_class): Reverse sense of
+ DECL_VISIBILITY_SPECIFIED test for target-specific visibility rules.
+ (constrain_class_visibility): Only complain about member visibility
+ if the member type is another class. Don't change visibility of the
+ current class.
+
+2006-07-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28338
+ * decl.c (layout_var_decl): Don't call push_local_name here.
+ (initialize_artificial_var): Assert artificiality.
+ (cp_finish_decl): Call push_local_name here.
+
+2006-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28337
+ * typeck.c (build_binary_op): Short-circuit pointer arithmetic in
+ templates.
+
+2006-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28048
+ * semantics.c (check_accessibility_of_qualified_id): Robustify.
+
+ PR c++/28235
+ * pt.c (tsubst_decl): Handling substitutions into a static data
+ member from within the scope of the tempalte itself.
+
+2006-07-18 Lee Millward <lee.millward@gmail.com>
+
+ PR c++/28258
+ * method.c (locate_copy): Check for non_reference
+ returning error_mark_node.
+
+ PR c++/28260
+ * decl.c (duplicate_decls): Return error_mark_node
+ on ambiguous declaration.
+
+2006-07-18 Steve Ellcey <sje@cup.hp.com>
+
+ PR c++/27495
+ * search.c (adjust_result_of_qualified_name_lookup): Change
+ assert to part of if statement.
+
+2006-07-17 Steve Ellcey <sje@cup.hp.com>
+
+ PR c++/28291
+ * decl.c (reshape_init_class): Return error_mark_node on error.
+
+2006-07-17 Steve Ellcey <sje@cup.hp.com>
+
+ PR c++/28304
+ * decl2.c (check_classfn): Return NULL_TREE on error.
+
+2006-07-17 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28250
+ * name-lookup.c (pushdecl_maybe_friend): Return early on
+ error_mark_node.
+ * except.c (expand_start_catch_block): Use error_mark_node instead
+ of NULL_TREE for invalid decls.
+ * parser.c (cp_parser_exception_declaration): Return error_mark_node
+ on invalid catch parameter. Simplify.
+
+2006-07-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/28370
+ * decl2.c (note_vague_linkage_var): Removed.
+ (finish_static_data_member_decl): Add decl to pending_statics vector
+ directly. Do it even for non-public decls.
+
+2006-07-15 Lee Millward <lee.millward@gmail.com>
+
+ PR c++/28292
+ * decl2.c (acceptable_java_type): Robustify. Use
+ proper Boolean return type instead of return 1.
+ (check_java_method): Don't issue error about
+ type not being an acceptable Java parameter if
+ it's error_mark_node.
+
+ PR c++/28269
+ * parser.c (cp_parser_elaborated_type_specifier):
+ Return early if an invalid type was detected.
+
+2006-07-15 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28249
+ * parser.c (cp_parser_check_decl_spec): New function.
+ (cp_parser_decl_specifier_seq): Factor out check for repeated
+ decl-specifiers into cp_parser_check_decl_spec. Use it.
+ (cp_parser_type_specifier_seq): Use it.
+
+ PR c++/28294
+ * semantics.c (finish_offsetof): Use TREE_OPERAND for COMPONENT_REFs
+ only.
+
+ PR c++/28387
+ * decl2.c (cplus_decl_attributes): Check for invalid decls.
+
+2006-07-14 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28343
+ * decl.c (cp_finish_decl): Check asmspec_tree for error_mark_node.
+ * decl2.c (grokfield): Likewise.
+
+2006-07-12 Geoffrey Keating <geoffk@apple.com>
+
+ * decl2.c (determine_visibility): Don't change visibility of
+ function locals because of -fvisibility-inlines-hidden.
+
+2006-07-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/28217
+ * semantics.c (note_decl_for_pch): Don't premangle templates.
+
+2006-07-12 Martin Michlmayr <tbm@cyrius.com>
+
+ * typeck.c (string_conv_p): Remove spurious quotation mark in
+ warning.
+
+2006-07-07 Lee Millward <lee.millward@gmail.com>
+ Andrew Pinski <pinskia@gmail.com>
+
+ PR c++/27820
+ * decl.c (define_label): Return error_mark_node on error.
+ * semantics.c (finish_label_stmt): Don't call
+ add_stmt for invalid labels.
+
+2006-07-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/28279
+ * decl2.c (finish_static_data_member_decl): Don't assert
+ TREE_PUBLIC.
+
+2006-07-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/13983
+ PR c++/17519
+ * class.c (check_field_decls): Check TYPE_PACKED after
+ stripping array types.
+ (finish_struct_bits): Don't copy TYPE_SIZE here.
+
+ PR c++/18681
+ * friend.c (is_friend): Fix DR 45 implementation.
+
+2006-07-05 Richard Guenther <rguenther@suse.de>
+ Andrew Pinski <pinskia@gcc.gnu.org>
+
+ PR c++/27084
+ * cp-objcp-common.c (cxx_types_compatible_p): Ignore
+ top level qualifiers for pointer type comparisons.
+
+2006-07-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/28215
+ * method.c (make_thunk): Unset DECL_USE_TEMPLATE and
+ DECL_TEMPLATE_INFO.
+
+2006-06-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/26577
+ * call.c (build_new_method_call): Force evaluation of the
+ instance pointer, not the object.
+
+2006-06-30 Kazu Hirata <kazu@codesourcery.com>
+
+ * decl2.c: Fix a comment typo.
+
+2006-06-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/18698
+ * decl2.c (grokfield): Only try to treat the decl as an access
+ declaration if the scope is a class.
+
+2006-06-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/26905
+ PR c++/26612
+ PR c++/27000
+ PR c++/26984
+ PR c++/19134
+ * decl2.c (determine_visibility): Overhaul.
+ (determine_visibility_from_class): Likewise.
+ (min_vis_r, type_visibility, constrain_visibility): New fns.
+ (constrain_visibility_for_template): Likewise.
+ (constrain_class_visibility): Likewise.
+ * decl.c (cp_finish_decl): Call determine_visibility for function
+ decls, too.
+ * name-lookup.c (pushtag): Call determine_visibility.
+ * decl.c (duplicate_decls): Don't copy visibility from template to
+ specialization.
+ * pt.c (check_explicit_specialization): Likewise.
+ (lookup_template_class, tsubst_decl): Call determine_visibility.
+ * class.c (finish_struct_1): Call constrain_class_visibility.
+
+ PR c++/26905
+ PR c++/21675
+ PR c++/17470
+ * parser.c (cp_parser_explicit_instantiation): Pass the attributes
+ to grokdeclarator.
+ (cp_parser_type_specifier): Allow 'enum __attribute ((...)) E'.
+ (cp_parser_enum_specifier): Likewise.
+ (cp_parser_elaborated_type_specifier): Apply attributes if this
+ declares only the class.
+ (cp_parser_class_specifier): Apply leading attributes immediately.
+ * semantics.c (begin_class_definition): Add attributes parameter,
+ apply them to the type.
+
+ PR c++/21581
+ PR c++/25915
+ * tree.c (decl_anon_ns_mem_p): New function.
+ * cp-tree.h: Declare it.
+ * decl2.c (determine_visibility): Make anonymous namespace
+ members static.
+ (min_vis_r, constrain_visibility): Likewise.
+ * rtti.c (create_pseudo_type_info): Set TREE_PUBLIC on
+ pseudo-types.
+ * decl.c (cxx_init_decl_processing): Set TREE_PUBLIC on
+ global_namespace.
+ * name-lookup.c (push_namespace_with_attribs): Don't set TREE_PUBLIC
+ on anonymous namespaces.
+
+2006-06-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/27424
+ * pt.c (convert_template_argument): Pass all template arguments
+ on to coerce_template_template_parms.
+
+2006-06-25 Lee Millward <lee.millward@gmail.com>
+ Mark Mitchell <mark@codesuorcery.com>
+
+ PR c++/28054
+ * decl2.c (grokbitfied): Remove check for grokdeclarator
+ returning NULL_TREE, instead check for error_mark_node
+ to indicate failure.
+ * decl.c (grokdeclarator): Adjust block comment.
+
+2006-06-25 Lee Millward <lee.millward@gmail.com>
+
+ PR c++/28051
+ * mangle.c (mangle_conv_op_name_for_type): Check for
+ invalid types.
+ * name-lookup.c (push_class_level_binding): Robustify.
+ (do_class_using_decl): Return early if name is error_mark_node.
+
+2006-06-23 Steve Ellcey <sje@cup.hp.com>
+
+ PR c++/28114
+ * name-lookup.c (pushtag): Return if we have error_mark_node.
+
+2006-06-23 Steve Ellcey <sje@cup.hp.com>
+
+ PR c++/27019
+ * typeck2.c (process_init_constructor_array): Set ce->value on errors.
+
+2006-06-23 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28112
+ * parser.c (cp_parser_attribute_list): Skip attributes with invalid
+ arguments. Fix comment.
+
+ PR c++/11468
+ * init.c (build_new_1): Handle error_mark_nodes returned by
+ build_java_class_ref.
+ (build_java_class_ref): Do not abort compilation, but return
+ error_mark_node. Improve error message. Fix indentation.
+
+2006-06-23 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR target/27789
+ * decl.c (start_decl): Check that dllimports are not initialized.
+
+2006-06-22 Lee Millward <lee.millward@gmail.com>
+
+ PR c++/27805
+ * typeck2.c (build_m_component_ref): Use error_operand_p.
+
+ PR c++/27821
+ * decl.c (grokdeclarator): Return error_mark_node on
+ invalid uses of the scope resolution operator.
+
+2006-06-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28111
+ * pt.c (determine_specialization): Check for invalid decls.
+
+ PR c++/28110
+ * pt.c (unify) <case TEMPLATE_PARM_INDEX>: Check for invalid
+ parameters.
+
+ PR c++/28109
+ * rtti.c (get_tinfo_decl_dynamic): Robustify.
+
+2006-06-20 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/28052
+ * init.c (push_base_cleanups): Skip members with invalid types.
+ * typeck.c (build_class_member_access_expr): Robustify.
+
+2006-06-19 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (instantiate_template): Fix typo in comment.
+
+2006-06-19 Richard Guenther <rguenther@suse.de>
+
+ * parser.c (CP_LEXER_BUFFER_SIZE): Adjust to assure near
+ power-of-two token vector size.
+
+2006-06-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28016
+ * decl.c (cp_finsh_decl): Do not emit uninstantiated static data
+ members.
+
+ PR c++/27979
+ * call.c (standard_conversion): Strip cv-qualifiers from bitfield
+ types.
+
+ PR c++/27884
+ * decl.c (have_extern_spec): Remove.
+ (start_decl): Do not check have_extern_spec.
+ (start_function): Likewise.
+ * cp-tree.h (have_extern_spec): Remove.
+ * parser.c (cp_parser_linkage_specification): Don't set
+ have_extern_spec.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_parameter_declaration): Do not treat parameters as
+ within the scope of an unbraced linkage specification.
+
+2006-06-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27689
+ * cp-tree.h (CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P): New
+ macro.
+ * pt.c (unify): Use it.
+
+ PR c++/27666
+ * call.c (build_conditional_expr): Robustify.
+
+ PR c++/27640
+ * pt.c (instantiate_template): Set processing_template_decl to
+ zero while performing substitutions.
+
+2006-06-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27665
+ * parser.c (cp_parser_unqualified_id): Use constructor_name_p to
+ identify destructors.
+ (cp_parser_nested_name_specifier_opt): Remove invalid
+ optimization.
+ (cp_parser_template_id): Refine heuristic for determining whether
+ we are entering a scope.
+
+ PR c++/27648
+ * parser.c (cp_parser_declarator): Robustify.
+
+ PR c++/26559
+ * pt.c (tsubst_expr): Use finish_omp_atomic.
+ (value_dependent_expression_p): All CALL_EXPRs are dependent.
+ * semantics.c (finish_omp_atomic): Rework to use standard
+ paradigms for handling non-dependent expressions.
+
+2006-06-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * typeck.c (build_modify_expr): Tidy diagnostic message.
+
+2006-06-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28018
+ * typeck.c (build_modify_expr): Disallow array assignment.
+
+2006-06-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.def: Fix typo.
+
+2006-06-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27227
+ * decl.c (decls_match): Allow an extern "C" variable declarations
+ from different namespaces to match.
+ (duplicate_decls): Disallow redeclaring a variable with a
+ different linkage specification.
+
+2006-06-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/27793
+ * cp-tree.h (cxx_int_tree_map): New struct.
+ (struct language_function): Add extern_decl_map field.
+ * name-lookup.c (pushdecl_maybe_friend): Add x -> t mapping
+ to cp_function_chain->extern_decl_map hash table instead of
+ copying over DECL_UID.
+ * cp-gimplify.c (cxx_int_tree_map_eq, cxx_int_tree_map_hash): New
+ functions.
+ (cp_genericize_r): Remap DECL_EXTERN local decls using
+ cp_function_chain->extern_decl_map hash table.
+ * decl.c (finish_function): Clear extern_decl_map.
+
+2006-06-12 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27601
+ * semantics.c (finish_offsetof): Handle pseudo-destructors.
+
+ PR c++/27933
+ * name-lookup.c (lookup_qualified_name): Always return error_mark_node
+ if lookup fails.
+
+ PR c++/27951
+ * decl2.c (finish_anon_union): Return early if build_anon_union_vars
+ fails.
+
+2006-06-12 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/21210
+ * typeck2.c (build_functional_cast): Use cp_convert to construct
+ non-aggregate initializers instead of the user-level build_c_cast.
+
+2006-06-07 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27601
+ * cp-tree.h (finish_offsetof): Add prototype.
+ * semantics.c (finish_offsetof): New function.
+ * parser.c (cp_parser_builtin_offsetof): Call it instead of
+ fold_offsetof.
+ * pt.c (tsubst_copy_and_build): Likewise.
+
+2006-06-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27177
+ * call.c (standard_conversion): Require that the derived type be
+ complete when performing a derived-to-base conversion.
+
+2006-06-04 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27819
+ * decl.c (cp_finish_decl): Process initializers for static data
+ members with non-dependent initializers, even in templates.
+
+ PR c++/27722
+ * decl.c (maybe_deduce_size_from_array_init): If the declaration
+ is erroneous, give it an erroneous type.
+ (layout_var_decl): If the type is erroneous, give up.
+ (check_initializer): Likewise.
+
+ PR c++/27807
+ * cp-tree.h (TYPE_OBJ_P): New macro.
+ (TYPE_PTROB_P): Use it.
+ (TYPE_REF_OBJ_P): Likewise.
+ * semantics.c (finish_compound_literal): Do not permit compound
+ literals of non-object types.
+
+ PR c++/27806
+ * typeck.c (original_type): Robustify.
+
+2006-06-05 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27804
+ * init.c (constant_value_1): Return decl instead of error_mark_node
+ for invalid initializers.
+
+2006-06-01 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/27592
+ * rtti.c (build_dynamic_cast_1): Call c_common_truthvalue_conversion
+ on operand of the COND_EXPR for the null pointer check.
+
+2006-06-01 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/26740
+ * typeck.c (build_unary_op): Mark the function as being used.
+
+2006-06-01 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/26660
+ * parser.c (cp_parser_initial_pragma): Read one more token for
+ caller after reading PCH file in.
+
+2006-05-31 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27801
+ * call.c (perform_implicit_conversion): Do not actually perform
+ conversions in templates.
+
+ PR c++/26496
+ * call.c (resolve_args): Check for invalid uses of bound
+ non-static member functions.
+ * init.c (build_offset_ref): Return error_mark_node for errors.
+
+ PR c++/27385
+ * decl.c (reshape_init): Robustify.
+ (reshape_init_array_1): Likewise.
+
+2006-05-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27808
+ * parser.c (cp_parser_decl_specifier_seq): Issue errors about
+ "friend" specifiers that do not appear in class scopes.
+
+ PR c++/27803
+ * class.c (check_bitfield_decl): Ensure that all bitfields have
+ integral type.
+
+2006-05-29 Kazu Hirata <kazu@codesourcery.com>
+
+ * pt.c (convert_nontype_argument): Fix a typo in an error
+ message.
+
+2006-05-28 Kazu Hirata <kazu@codesourcery.com>
+
+ * decl.c, decl2.c, parser.c: Fix comment typos. Follow
+ spelling conventions.
+
+2006-05-24 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20103
+ * decl.c (cp_make_fname_decl): Don't set DECL_INITIAL to
+ error_mark_node to indicate an initialization is OK.
+ (start_decl): Likewise. Adjust call to start_decl_1.
+ (start_decl_1): Add initialized parameter. Simplify.
+ * except.c (initialize_handler_parm): Adjust call to
+ setart_decl_1.
+ (expand_start_catch_block): Let cp_finish_decl initialize catch
+ parameters.
+ * cp-tree.h (start_decl_1): Adjust prototype.
+ * pt.c (tsubst_expr): Don't set DECL_INITIAL to error_mark_node.
+ (instantiate_decl): Let cp_finish_decl handle initialization.
+ * semantics.c (finish_compound_literal): Create a temporary
+ variable for the literal.
+ * typeck.c (build_unary_op): Remove COMPOUND_LITERAL_P special
+ cases.
+ * decl2.c (finish_static_data_member_decl): Don't set
+ DECL_INITIAL.
+ (grokfield): Do not try to initialize functions.
+
+2006-05-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/20173
+ * pt.c (determine_specialization): Disallow partial
+ specializations of templates.
+
+2006-05-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27716
+ * typeck.c (build_modify_expr): Test arguments for error_operand_p.
+
+ * decl.c (grokdeclarator): Return error_mark_node instead of NULL_TREE.
+
+2006-05-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27210
+ * cp-tree.h (cp_save_expr): New function.
+ * init.c (build_new): Correct logic for zero-element array
+ warning. Use cp_save_expr.
+ * tree.c (cp_save_expr): New function.
+
+2006-05-21 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27398
+ * decl.c (grokdeclarator): Return error_mark_node instead of NULL_TREE
+ or void_type_node.
+
+2006-05-19 Mike Stump <mrs@apple.com>
+
+ * typeck.c (default_conversion): Remove static.
+
+2006-05-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/26433
+ * cp-tree.h (begin_function_try_block): Change prototype.
+ (finish_function_handler_sequence): Likewise.
+ * parser.c (cp_parser_function_try_block): Adjust calls.
+ * pt.c (tsubst_expr): Adjust calls.
+ * semantics.c (begin_function_try_block): Create an artificial
+ outer scope.
+ (finish_function_handler_sequence): Close it.
+
+2006-05-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27471
+ PR c++/27506
+ * typeck.c (decay_conversion): Convert bitfields to their declared
+ types here. Improve documentation. Avoid use of cp_convert.
+ (default_conversion): Make it static. Perform integral promotions
+ before lvalue-to-rvalue, function-to-pointer, and array-to-pointer
+ conversions.
+ * init.c (build_init): Remove.
+ (expand_default_init): Do not call rvalue.
+ * call.c (null_ptr_cst_p): Robustify.
+ (build_conditional_expr): Tidy.
+ * except.c (build_throw): Do not perform lvalue-to-rvalue
+ conversion on operand before initializing temporary.
+ * tree.c (convert.h): Include it.
+ (convert_bitfield_to_declared_type): Use convert_to_integer, not
+ cp_convert.
+ (rvalue): Don't convert bitfields to their declared type here.
+ * cp-tree.h (build_init): Remove.
+ (default_conversion): Likewise.
+ * typeck2.c (build_m_component_ref): Do not perform
+ lvalue-to-rvalue, function-to-pointer, or array-to-pointer
+ conversions here. Correct error message.
+
+2006-05-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/26122
+ * decl2.c (check_member_template): Remove checks for virtual
+ functions.
+ * parser.c (cp_parser_function_specifier_opt): Complain about
+ virtual templates.
+ (cp_parser_pure_specifier): Likewise.
+
+ PR c++/26068
+ * parser.c (cp_parser_set_storage_class): Check for
+ invalid uses of storage classes on unbraced linkage
+ specifications.
+ (cp_parser_decl_specifier_seq): Pass keywords, not storage classes,
+ to cp_parser_set_storage_class.
+
+2006-05-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/27491
+ * semantics.c (finish_compound_literal): Only set TREE_HAS_CONSTRUCTOR
+ on CONSTRUCTORs.
+
+ PR middle-end/27415
+ * parser.c (cp_parser_omp_parallel): Set OMP_PARALLEL_COMBINED
+ on combined parallel workshare constructs.
+ * pt.c (tsubst_expr): Copy OMP_PARALLEL_COMBINED flag.
+
+2006-05-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR driver/26885
+ * Make-lang.in (GXX_OBJS): Replace gcc.o with $(GCC_OBJS).
+
+2006-05-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27339
+ * cp-tree.h (perform_access_checks): New function.
+ * semantics.c (perform_access_checks): New function.
+ (perform_deferred_access_checks): Use it.
+ * parser.c (cp_parser_simple_declaration): Adjust call to
+ cp_parser_init_declarator.
+ (cp_parser_type_parameter): Do not defer checks in default
+ arguments.
+ (cp_parser_explicit_specialization): Adjust call to
+ cp_parser_single_declaration.
+ (cp_parser_init_declarator): Perform template-parameter access
+ checks.
+ (cp_parser_parameter_declaration): Do not defer checks for
+ template parameter default arguments.
+ (cp_parser_template_declaration_after_export): Gather access
+ checks for template parameters, and pass them to
+ cp_parser_single_declaration.
+ (cp_parser_template_parameter_access_checks): New function.
+ (cp_parser_single_declaration): Add checks parameter.
+
+ PR c++/27505
+ * call.c (convert_like_real): Convert bitfields to their declared
+ types when forming an rvalue.
+ * tree.c (convert_bitfield_to_declared_type): New function.
+ (rvalue): Use it.
+ * cp-tree.h (convert_bitfield_to_declare_type): Declare it.
+
+2006-05-15 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27582
+ * pt.c (any_dependent_template_arguments_p): Return early on invalid
+ argument list.
+
+ PR c++/27581
+ * search.c (adjust_result_of_qualified_name_lookup): Skip on
+ invalid context_class.
+
+ PR c++/27315
+ * pt.c (do_decl_instantiation): Return early on invalid decl.
+
+ PR c++/27559
+ * pt.c (push_template_decl_real): Return error_mark_node instead
+ of broken decl.
+
+ PR c++/27496
+ * pt.c (tsubst_friend_class): Return early on invalid friend
+ declarations.
+
+2006-05-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Make-lang.in (cp/decl.o): Add dependency on $(TARGET_H).
+ (cp/decl2.o): Likewise.
+ (cp/typeck.o): Likewise.
+ (cp/cvt.o): Likewise.
+ (cp/parser.o): Likewise.
+ (cp/call.o): Replace target.h with $(TARGET_H).
+
+2006-05-14 Alexandre Oliva <aoliva@redhat.com>
+
+ * pt.c (build_non_dependent_expr): Leave ADDR_EXPR of
+ COMPONENT_REF alone.
+
+2006-05-11 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27547
+ * decl.c (copy_fn_p): Return early on non-member functions.
+
+2006-05-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27447
+ * decl2.c (build_memfn_type): Skip invalid functions and class types.
+
+2006-05-06 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27427
+ * pt.c (convert_nontype_argument): Return early on invalid arguments.
+
+ * pt.c (process_template_parm): Remove superfluous temporary.
+
+ PR c++/27430
+ * pt.c (process_template_parm): Handle erroneous non-type parameters.
+
+ PR c++/27423
+ * typeck.c (convert_for_initialization): Skip erroneous types.
+
+ PR c++/27422
+ * typeck.c (convert_arguments): Return early on args with
+ invalid types.
+
+2006-05-03 Aldy Hernandez <aldyh@redhat.com>
+
+ PR/21391
+ * typeck.c (build_static_cast_1): Save casted types in used types
+ hash table.
+ (build_reinterpret_cast_1): Same.
+ * rtti.c (build_dynamic_cast_1): Same.
+
+2006-05-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/27359
+ * parser.c (cp_parser_omp_for_loop): Only call
+ cp_parser_abort_tentative_parse if cp_parser_parse_definitely was not
+ called.
+
+2006-05-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27102
+ * decl.c (grokdeclarator): Robustify checks for defining members
+ of incomplete types.
+
+ PR c++/27309
+ * class.c (add_method): Call grok_special_member_properties.
+ * decl.c (grokdeclarator): Don't call it here.
+ (copy_fn_p): A TEMPLATE_DECL is never a copy constructor or
+ assignment operator. Set TYPE_HAS_CONSTURCTOR if DECL is a
+ constructor.
+ (start_method): Don't call grok_special_member_properties.
+ * method.c (implicitly_declare_fn): Likewise.
+ * pt.c (instantiate_class_template): Likewise.
+ * decl2.c (grokfield): Likewise.
+
+2006-05-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/27337
+ * cp-gimplify.c (cxx_omp_privatize_by_reference): New function.
+ * cp-tree.h (cxx_omp_privatize_by_reference): New prototype.
+ * cp-objcp-common.h (LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE): Define.
+
+2006-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27094
+ * pt.c (tsubst_default_argument): Increment function_depth around
+ call to tsubst_expr.
+ * parser.c (cp_parser_parameter_declaration): Likewise.
+ * decl2.c (mark_used): Tidy.
+
+2006-04-30 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27278
+ * decl.c (grok_op_properties): Skip operators with invalid args
+ when checking for class-type or enum-type args.
+
+2006-04-29 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/27279
+ * decl.c (copy_fn_p): Skip functions with invalid first arg.
+
+2006-04-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27292
+ * tree.c (rvalue): Convert bitfields to their declared types.
+
+ PR c++/27102
+ * typeck2.c (cxx_incomplete_type_diagnostic): Handle
+ TYPENAME_TYPE.
+
+2006-04-24 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27292
+ * typeck.c (decay_conversion): Don't adjust bitfield types.
+ (perform_integral_promotions): Treat bitfield enums as enums, not
+ as short integer types.
+ * tree.c (rvalue): Convert bitfields to their correct types.
+
+2006-04-24 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/19963
+ * class.c (layout_class_type): Skip fields with invalid types.
+
+2006-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/26912
+ * cp-tree.h (build_this_parm): Declare.
+ (grok_method_quals): Remove.
+ (build_memfn_type): Declare.
+ (build_artificial_parm): Declare.
+ (do_friend): Remove quals parameter.
+ * decl.c (build_this_parm): New function.
+ (grokfndecl): Use it. Do not pass quals to grokclassfn.
+ (grokdeclarator): Rename quals to memfn_quals. Avoid allocating
+ unnecessary TYPE_DECLs. Correct qualification of member function
+ types. Tidy.
+ * method.c (implicitly_declare_fn): Use build_this_parm.
+ * friend.c (do_friend): Remove quals parameter.
+ * decl2.c (grok_method_quals): Remove.
+ (build_memfn_type): New function.
+ (build_artificial_parm): Give it external linkage.
+ (grokclassfn): Remove quals parameter. Do not build "this"
+ PARM_DECL here.
+
+ PR c++/26534
+ * cp-tree.h (is_bitfield_expr_with_lowered_type): New function.
+ * typeck.c (is_bitfield_expr_with_lowered_type): New function.
+ (decay_conversion): Convert bitfield expressions to the correct
+ type.
+ (build_modify_expr): Remove spurious conversions.
+ * class.c (layout_class_type): Modify the type of bitfields to
+ indicate a limited range.
+ * call.c (standard_conversion): Adjust the type of bitfield
+ expressions used in an rvalue context.
+ (build_conditional_expr): Likewise.
+
+2006-04-22 Kazu Hirata <kazu@codesourcery.com>
+
+ * decl.c: Fix comment typos.
+
+2006-04-21 Eric Christopher <echristo@apple.com>
+
+ * decl.c: Fix typo in function name.
+
+2006-04-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/26558
+ * parser.c (cp_parser_class_name): Check for invalid typenames.
+ Rearrange code.
+
+ PR c++/26739
+ * pt.c (tsubst_friend_function): Return early if
+ pushdecl_namespace_level fails.
+
+ PR c++/26036
+ * typeck.c (convert_arguments): Return error_mark_node instead of
+ error_mark_list.
+ * cp-tree.h (error_mark_list): Remove declaration.
+ * decl.c (error_mark_list): Remove definition.
+ (cxx_init_decl_processing): Do not initialize error_mark_list.
+
+ PR c++/10385
+ * rtti.c (build_dynamic_cast_1): Check for invalid conversions
+ before calling convert_to_reference.
+ * cvt.c (convert_to_reference): Assert that reftype is a
+ REFERENCE_TYPE.
+
+2006-04-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/27102
+ * class.c (currently_open_class): Tidy.
+ * decl.c (grokdeclarator): If we encounter an erroneous
+ declarator, assume that we have already issued an error message
+ and return. Return error_mark_node instead of NULL_TREE in more
+ places. Issue errors about function definitions that do not have
+ a function declarator. Check for complete types for all function
+ definitions.
+ * cp-tree.h (cp_error_declarator): Remove.
+ (currently_open_class): Change return type.
+ * parser.c (cp_parser_id_expression): Add optional_p parameter.
+ (cp_parser_parse_diagnose_invalid_type_name): Adjust calls.
+ (cp_parser_id_expression): Likewise.
+ (cp_parser_unqualified_id): If the name is optional, return
+ NULL_TREE.
+ (cp_parser_postfix_dot_deref_expression): Adjust calls.
+ (cp_parser_type_parameter): Likewise.
+ (cp_parser_unqualified_id): Likewise.
+ (cp_parser_direct_declarator): Likewise.
+ (cp_parser_declarator_id): Add optional_p parameter.
+ (cp_parser_function_definition_from_specifiers_and_declarator):
+ Assume that start_function indicates failure only if it has issued
+ an error.
+ (cp_parser_omp_var_list_no_open): Adjust calls.
+
+2006-04-17 Janis Johnson <janis187@us.ibm.com>
+
+ PR c++/26114, c++/26115
+ * typeck.c (cxx_mark_addressable): Restore check for extra_warnings.
+ * class.c (check_field_decls): Ditto.
+
+2006-04-17 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * init.c (build_offset_ref): Remove superfluous temporary.
+
+2006-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/26365
+ * typeck.c (finish_class_member_access_expr): Robustify
+
+2006-04-15 Kazu Hirata <kazu@codesourcery.com>
+
+ * Make-lang.in (cp/pt.o): Depend on vecprim.h.
+ * pt.c: Include vecprim.h.
+ (inline_parm_levels): Change the type to VEC(int,heap) *.
+ (inline_parm_levels_used): Remove.
+ (maybe_begin_member_template_processing,
+ maybe_end_member_template_processing): Use VEC instead of
+ VARRAY.
+
+ * cp/call.c: Fix comment typos.
+
+2006-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_init_declarator): Initialize local variables
+ aggressively.
+
+2006-04-12 Roger Sayle <roger@eyesopen.com>
+
+ * parser.c (cp_parser_init_declarator): Initialise
+ is_parenthesized_init to false to avoid compiler warning.
+
+2006-04-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (build_operator_new_call): Adjust prototype.
+ (build_new_method_call): Likewise.
+ (build_op_delete_call): Likewise.
+ * init.c (build_raw_new_expr): New function.
+ (build_new_1): Pass information as parameters, rather than
+ bundling it into a NEW_EXPR.
+ (build_new): Adjust accordingly.
+ (build_vec_delete_1): Adjust for changes to build_op_delete_call.
+ (build_delete): Likewise.
+ * decl.c (finish_destructor_body): Likewise.
+ * call.c (build_operator_new_call): Return the allocation function
+ used.
+ (build_op_delete_call): Take allocation function as parameter.
+ (build_special_member_call): Adjust call to build_new_method_call.
+ (build_new_method_call): Return function called.
+ * pt.c (tsubst_copy_and_build): Adjust call to
+ build_new_method_call.
+ * semantics.c (finish_call_expr): Likewise.
+ * parser.c (cp_parser_postfix_expression): Likewise.
+ * typeck2.c (cxx_incomplete_type_diagnostic): Refer to
+ "incomplete", not "undefined", types.
+
+ PR c++/26295
+ * decl.c (grokdeclarator): Remove namespace-handling code for
+ pointers-to-members.
+ * parser.c (cp_parser_ptr_operator): Check for qualified names
+ using namespaces.
+
+ PR c++/26122
+ * parser.c (cp_parser_init_declarator): Adjust logic for deciding
+ whether or not to look for a pure-specifier.
+ (cp_parser_member_declaration): Likewise.
+
+2006-04-08 Kazu Hirata <kazu@codesourcery.com>
+
+ * decl2.c, pt.c, semantics.c: Fix comment typos.
+
+2006-04-06 Roger Sayle <roger@eyesopen.com>
+
+ * call.c (null_ptr_cst_p): Add explicit TREE_CONSTANT_OVERFLOW check.
+
+2006-04-05 Jason Merrill <jason@redhat.com>
+
+ * name-lookup.c (push_namespace_with_attribs): Temporarily disable
+ default hidden visibility for anonymous namespace.
+
+2006-03-29 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/22494
+ * init.c (build_vec_delete_1): Convert BASE pointer's type to
+ the base pointer type to avoid a type mismatch in the EQ_EXPR.
+
+2006-03-24 Carlos O'Donell <carlos@codesourcery.com>
+
+ * search.c (maybe_suppress_debug_info): If
+ flag_emit_class_debug_always then don't suppress.
+
+2006-03-22 Jason Merrill <jason@redhat.com>
+
+ * name-lookup.c (push_namespace_with_attribs): Only apply hidden
+ visibility to anonymous namespaces if HAVE_GAS_HIDDEN.
+
+2006-03-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/26691
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Handle default arguments.
+
+2006-03-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/21581
+ * parser.c (cp_parser_declaration): Support attributes on
+ anonymous namespaces.
+ * name-lookup.c (push_namespace_with_attribs): Anonymous
+ namespaces default to hidden visibility.
+
+2006-03-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/21764, c++/19238
+ * decl.c (cp_finish_decl): Call determine_visibility later.
+ (start_preparsed_function): Likewise.
+ * cp-tree.h (CP_TYPE_CONTEXT, TYPE_NAMESPACE_SCOPE_P): New macros.
+ (TYPE_CLASS_SCOPE_P, TYPE_FUNCTION_SCOPE_P): New macros.
+ * name-lookup.h (struct cp_binding_level): Add has_visibility
+ bitfield.
+ * name-lookup.c: Include c-pragma.h.
+ (push_namespace_with_attribs): Split out from push_namespace.
+ Push visibility if appropriate. Set TREE_PUBLIC on namespaces.
+ (leave_scope): Pop visibility if appropriate.
+ * decl2.c (determine_visibility_from_class): Split out from...
+ (determine_visibility): ...here. Handle function scope and
+ nested classes.
+ (import_export_decl): Move visibility handling to
+ determine_visibility_from_class.
+ * parser.c (cp_parser_declaration, cp_parser_namespace_name): Allow
+ attributes on namespace declarations.
+
+2006-03-15 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/6634
+ * decl.c (grokdeclarator): Do not accept long long double.
+ Reorganize checks for invalid (combinations of) type modifiers.
+ Quote modifiers in messages.
+
+2006-03-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/16387, c++/16389
+ * typeck.c (cxx_alignof_expr, cxx_sizeof_expr): New functions.
+ (cxx_sizeof_or_alignof_expr): Split out from here.
+
+2006-03-09 Diego Novillo <dnovillo@redhat.com>
+
+ Merge from gomp-20050608-branch
+
+ 2006-02-02 Diego Novillo <dnovillo@redhat.com>
+
+ * decl.c (pop_labels_1): Use appropriate pointer casting.
+ (poplevel_named_label_1): Likewise.
+ (named_label_entry_hash): Likewise.
+ (named_label_entry_eq): Likewise.
+ (check_goto): Likewise.
+ (define_label): Likewise.
+
+ 2006-01-26 Diego Novillo <dnovillo@redhat.com>
+
+ * cp-tree.h (CP_OMP_CLAUSE_INFO): Use TREE_TYPE instead
+ of TREE_BLOCK.
+ * pt.c: Use OMP_CLAUSE_CODE and OMP_CLAUSE_OPERAND
+ instead of TREE_CODE/TREE_OPERAND.
+ * semantics.c: Likewise.
+ * parser.c: Likewise.
+
+ 2005-11-10 Diego Novillo <dnovillo@redhat.com>
+
+ * parser.c (cp_parser_omp_threadprivate): Emit diagnostic if
+ target does not support TLS.
+
+ 2005-11-09 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (redeclaration_error_message): Don't error about
+ DECL_THREAD_LOCAL_P mismatches if CP_DECL_THREADPRIVATE_P
+ (olddecl).
+
+ 2005-11-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/24735
+ * semantics.c (finish_omp_barrier, finish_omp_flush): New
+ functions.
+ * parser.c (cp_parser_omp_barrier): Call finish_omp_barrier.
+ (cp_parser_omp_flush): Call finish_omp_flush.
+ * cp-tree.h (finish_omp_barrier, finish_omp_flush): New
+ prototypes.
+
+ PR c++/24734
+ * pt.c (tsubst_expr): Handle OMP_MASTER and OMP_ORDERED.
+
+ 2005-11-03 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (finish_omp_threadprivate): Error on class-scope
+ variables.
+
+ 2005-11-02 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_all_clauses): If some clause
+ type is not allowed, don't remove just one of the
+ clauses, but all clauses added in that loop round.
+
+ * semantics.c (finish_omp_clauses): Fix function
+ comment. Don't handle non-const or mutable specially,
+ as const and not mutable is predetermined shared and
+ that leads to double error. Don't ICE if copyin var is
+ PARM_DECL.
+
+ PR c++/24613
+ * parser.c (cp_parser_pragma): Diagnose
+ PRAGMA_OMP_SECTION outside of PRAGMA_OMP_SECTIONS
+ construct.
+
+ * semantics.c (finish_omp_threadprivate): Error if V
+ is automatic variable or has incomplete type.
+
+ 2005-11-01 Diego Novillo <dnovillo@redhat.com>
+
+ * parser.c (cp_parser_omp_all_clauses): Use
+ OMP_CLAUSE_CHAIN instead of TREE_CHAIN.
+
+ 2005-11-01 Diego Novillo <dnovillo@redhat.com>
+
+ * parser.c (cp_parser_omp_all_clauses): When emitting an
+ error message, remove the invalid clause from the list.
+
+ 2005-10-31 Diego Novillo <dnovillo@redhat.com>
+
+ * parser.c (cp_parser_omp_parallel): Do not allow 'nowait' in
+ combined parallel+workshare directives.
+
+ 2005-10-31 Richard Henderson <rth@redhat.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_OMP_CLAUSE_DTOR):
+ Use cxx_omp_clause_dtor.
+ * cp-tree.h (CP_OMP_CLAUSE_INFO): New.
+ (cxx_omp_clause_dtor): New.
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): New.
+ (cxx_omp_clause_default_ctor): Use it.
+ (cxx_omp_clause_copy_ctor, cxx_omp_clause_assign_op):
+ Likewise.
+ (cxx_omp_clause_dtor): New.
+ * semantics.c (finish_omp_clauses): Rewrite cdtor
+ checking to fill in CP_OMP_CLAUSE_INFO. Don't
+ specialcase LASTPRIVATE for removal.
+ (cxx_omp_clause_default_ctor, cxx_omp_clause_copy_ctor,
+ cxx_omp_clause_assign_op): Move to cp-gimplify.c.
+
+ 2005-10-28 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (finish_omp_threadprivate): If
+ DECL_RTL_SET_P, call make_decl_rtl again so that
+ encode_section_info can update SYMBOL_REF's flags.
+
+ 2005-10-26 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (finish_omp_for): Don't segfault if COND
+ or INCR is NULL. If not calling c_finish_omp_for
+ right away and one of COND and INCR is NULL, issue
+ error and don't expand anything.
+
+ PR c++/24512
+ * cp-tree.h (finish_omp_for): Add PRE_BODY argument.
+ * semantics.c (finish_omp_for): Likewise. Set
+ OMP_FOR_PRE_BODY to PRE_BODY if deferring, add it
+ into the current statement list if not processing
+ template decl or pass it to c_finish_omp_for.
+
+ * parser.c (cp_parser_omp_for_loop): Expand optional DECL_EXPRs
+ into PRE_BODY statement list. Pass it to finish_omp_for.
+ * pt.c (tsubst_expr) <case OMP_FOR>: tsubst_expr also
+ OMP_FOR_PRE_BODY into PRE_BODY stmt list, pass it to
+ finish_omp_for. Put all the statements into sk_omp
+ scope.
+
+ 2005-10-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/24516
+ * parser.c (struct cp_parser): Rename in_iteration_statement
+ field to in_statement.
+ (IN_SWITCH_STMT, IN_ITERATION_STMT): Define.
+ (IN_OMP_BLOCK, IN_OMP_FOR): Change values.
+ (cp_parser_new, cp_parser_begin_omp_structured_block,
+ cp_parser_end_omp_structured_block,
+ cp_parser_omp_for_loop): Adjust for
+ in_iteration_statement renaming.
+ (cp_parser_selection_statement): Save
+ parser->in_iteration, or it temporarily with
+ IN_SWITCH_STMT for the
+ cp_parser_implicitly_scoped_statement call.
+ (cp_parser_iteration_statement): Adjust for
+ in_iteration_statement renaming. Use
+ IN_ITERATION_STMT rather than true.
+ (cp_parser_jump_statement): Adjust for
+ in_iteration_statement renaming and new values. Don't
+ error on break in a switch statement within OMP_FOR or
+ OpenMP structured block.
+
+ PR c++/24513
+ * parser.c (cp_parser_cache_group): Don't stop if next
+ token is CPP_PRAGMA_EOL and end is CPP_PRAGMA_EOL as
+ well. If current token is CPP_PRAGMA, consume
+ everything until CPP_PRAGMA_EOL inclusive.
+
+ 2005-10-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/24502
+ * semantics.c (finish_omp_for): Handle MODOP_EXPR in
+ addition to MODIFY_EXPR.
+
+ 2005-10-23 Richard Henderson <rth@redhat.com>
+
+ * cp-gimplify.c (struct cp_gimplify_ctx): Remove.
+ (bc_label): New.
+ (begin_bc_block, finish_bc_block): Use it.
+ (push_context, pop_context): Remove.
+ (cp_genericize): Don't use them. Assert bc_label is null.
+ * semantics.c (finish_omp_clauses): Create a fake data
+ element of TYPE for probing ctors.
+
+ 2005-10-23 Richard Henderson <rth@redhat.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR): New.
+ (LANG_HOOKS_OMP_CLAUSE_COPY_CTOR): New.
+ (LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP): New.
+ (LANG_HOOKS_OMP_CLAUSE_DTOR): New.
+ * semantics.c (finish_omp_clauses): Look through
+ arrays when looking up special member calls. Also
+ remove FIRSTPRIVATE when LASTPRIVATE fails.
+ (cxx_omp_clause_default_ctor, cxx_omp_clause_copy_ctor): New.
+ (cxx_omp_clause_assign_op): New.
+ * cp-tree.h: Declare them.
+
+ 2005-10-21 Richard Henderson <rth@redhat.com>
+
+ * decl.c (check_previous_goto_1): Return false if error.
+ (check_switch_goto): Likewise.
+ (finish_case_label): Don't emit the case label on error.
+ * parser.c (struct cp_parser): Revert
+ in_switch_statement_p changes.
+ (cp_parser_labeled_statement,
+ cp_parser_selection_statement): Likewise.
+ (cp_parser_begin_omp_structured_block): Don't save...
+ (cp_parser_end_omp_structured_block): or restore
+ in_switch_statement_p.
+
+ 2005-10-21 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (finish_omp_threadprivate): Set
+ decl_flags.u2sel when necessary.
+
+ 2005-10-21 Richard Henderson <rth@redhat.com>
+
+ * decl.c (poplevel_named_label_1): Restore creation of the
+ bad_decls list.
+ (decl_jump_unsafe): Check for error_mark_node types.
+ (check_goto): Don't check cdtor_label. Don't use identify_goto.
+ * semantics.c (finish_return_stmt): Do check_omp_return before
+ converting to cdtor_label goto.
+
+ 2005-10-21 Richard Henderson <rth@redhat.com>
+
+ PR c++/24451
+ * decl.c (check_omp_return): Return false on error.
+ * cp-tree.h (check_omp_return): Update decl.
+ * semantics.c (finish_return_stmt): Avoid adding
+ return on error.
+
+ 2005-10-21 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (struct language_function): Remove
+ x_named_label_uses.
+ Change x_named_labels to a hashtable.
+ (check_omp_return): Declare.
+ * decl.c (struct named_label_use_entry): Rename from
+ named_label_use_list. Remove label_decl.
+ (struct named_label_entry): Rename from
+ named_label_list. Remove old_value and next. Change
+ in_try_scope and in_catch_scope to bool. Add
+ in_omp_scope.
+ (pop_labels_1): New.
+ (pop_labels): Use it.
+ (pop_local_label, poplevel_named_label_1): New.
+ (poplevel): Use them.
+ (named_label_entry_hash, named_label_entry_eq): New.
+ (make_label_decl): Create named_labels. Move label
+ creation bits from lookup_label.
+ (declare_local_label): Tidy.
+ (identify_goto): Split out from ...
+ (check_previous_goto_1): Add exited_omp argument.
+ Handle omp scopes.
+
+ (use_label): Merge into...
+ (check_goto): ... here. Handle omp scopes.
+ (check_omp_return): New.
+ (check_previous_gotos): Merge into...
+ (define_label): ... here.
+ (save_function_data): Remove x_named_label_uses reference.
+ (finish_function): Likewise.
+ * name-lookup.h (sk_omp): New.
+ * name-lookup.c (begin_scope): Handle it.
+ * parser.c (cp_parser_omp_for): Don't create extra
+ compound stmt.
+
+ (cp_parser_omp_sections): Likewise.
+ * semantics.c (finish_return_stmt): Call check_omp_return.
+ (begin_omp_structured_block): Use sk_omp.
+ (finish_omp_structured_block): Use do_poplevel. Don't build a
+ MUST_NOT_THROW expression here.
+ (begin_omp_parallel, finish_omp_parallel): Don't create extra
+ compound statements.
+
+ 2005-10-21 Diego Novillo <dnovillo@redhat.com>
+
+ PR 24455
+ * cp/cp-tree.h (struct lang_decl_flags): Add field
+ threadprivate_p.
+ (CP_DECL_IS_THREADPRIVATE): Define.
+ * cp/semantics.c (finish_omp_threadprivate): Set. Do
+ not error out if CP_DECL_IS_THREADPRIVATE is set
+ already.
+ * cp/decl.c (duplicate_decls): Merge
+ CP_DECL_THREADPRIVATE_P.
+
+ 2005-10-20 Richard Henderson <rth@redhat.com>
+
+ * cp-gimplify.c (cp_gimplify_omp_for): New.
+ (cp_gimplify_expr): Call it.
+ * cp-tree.h (OMP_FOR_GIMPLIFYING_P): New.
+ * parser.c (struct cp_parser): Rename
+ in_iteration_statement_p to in_iteration_statement and
+ change to unsigned char. Similarly with
+ in_switch_statement. Update all users.
+ (IN_OMP_BLOCK, IN_OMP_FOR): New.
+ (cp_parser_labeled_statement): Diagnose case labels
+ binding closer to an openmp block nested than the
+ switch.
+ (cp_parser_jump_statement): Diagnose break and
+ continue labels binding closer to an openmp block than
+ an iteration or switch.
+ (cp_parser_omp_for_loop): Mark in_iteration_statement
+ for an omp for.
+ (cp_parser_begin_omp_structured_block): New.
+ (cp_parser_end_omp_structured_block): New.
+ (cp_parser_omp_structured_block): Use them.
+ (cp_parser_omp_for, cp_parser_omp_sections_scope): Likewise.
+ (cp_parser_omp_parallel): Likewise.
+
+ 2005-10-20 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (begin_omp_structured_block): New.
+ (finish_omp_structured_block): New.
+ (begin_omp_parallel, finish_omp_parallel): Use them.
+ * parser.c (cp_parser_omp_structured_block): Likewise.
+ (cp_parser_omp_for): Likewise.
+ (cp_parser_omp_sections_scope): Likewise.
+ * cp-tree.h: Declare them.
+
+ 2005-10-20 Richard Henderson <rth@redhat.com>
+
+ * parser.c (cp_parser_omp_master): Return the statement.
+ (cp_parser_omp_ordered): Likewise.
+ (cp_parser_omp_construct): Set the locus for them.
+
+ 2005-10-19 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (finish_omp_atomic): Revert to
+ uses_template_parms.
+
+ 2005-10-19 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (finish_omp_clauses): Avoid
+ DECL_THREAD_LOCAL_P on a PARM_DECL. Remove some
+ stub asserts guaranteed to fail.
+
+ 2005-10-19 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (OMP_ATOMIC_DEPENDENT_P, OMP_ATOMIC_CODE): New.
+ (finish_omp_clauses, finish_omp_for, finish_omp_atomic): New.
+ * parser.c (cp_parser_omp_clause_copyin): Remove.
+ (cp_parser_omp_all_clauses): Use cp_parser_omp_var_list instead.
+ Call finish_omp_clauses.
+ (cp_parser_omp_clause_if): Don't do error checking here.
+ (cp_parser_omp_clause_num_threads): Likewise.
+ (cp_parser_omp_clause_schedule): Likewise.
+ (cp_parser_omp_atomic): Use finish_omp_atomic.
+ (cp_parser_omp_for_loop): Don't discard DECL_EXPR.
+ Don't decompose assignment statment here. Use
+ finish_omp_for.
+
+ * pt.c (tsubst_omp_clauses): New.
+ (tsubst_expr): Handle OMP_PARALLEL, OMP_FOR, OMP_SECTIONS,
+ OMP_SINGLE, OMP_SECTION, OMP_CRITICAL, OMP_ATOMIC.
+ * semantics.c (finish_omp_clauses): New.
+ (begin_omp_parallel, finish_omp_parallel): Know Less about the
+ internals of the stmt_list stack.
+ (finish_omp_for, finish_omp_atomic): New.
+
+ 2005-10-18 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (cxx_omp_predetermined_sharing): New function.
+ * cp-tree.h (cxx_omp_predetermined_sharing): New prototype.
+ * cp-objcp-common.h
+ (LANG_HOOKS_OMP_PREDETERMINED_SHARING): Redefine.
+
+ 2005-10-18 Richard Henderson <rth@redhat.com>
+
+ * parser.c (cp_parser_omp_single): Use make_node and accessors
+ instead of build.
+
+ 2005-10-17 Richard Henderson <rth@redhat.com>
+
+ * parser.c (cp_parser_omp_for_loop): Handle declarations.
+
+ 2005-10-12 Richard Henderson <rth@redhat.com>
+
+ * Make-lang.in (CXX_C_OBJS): Add c-omp.o.
+ * cp-tree.h (begin_omp_parallel, finish_omp_parallel): Declare.
+ (finish_omp_threadprivate): Declare.
+ * parser.c (struct cp_lexer): Add in_pragma.
+ (cp_lexer_consume_token): Don't consume a PRAGMA_EOL
+ when in_pragma.
+ (cp_parser_skip_to_closing_parenthesis): Stop at PRAGMA_EOL.
+ (cp_parser_skip_to_end_of_statement): Likewise.
+ (cp_parser_skip_to_end_of_block_or_statement): Likewise.
+ (cp_parser_skip_to_closing_brace): Likewise.
+ (cp_parser_skip_to_pragma_eol): Reset in_pragma.
+ (cp_parser_require_pragma_eol): New.
+ (cp_parser_statement): Add in_compound argument;
+ update all callers.
+ Restart if a non-statement pragma seen outside a
+ compound.
+ (cp_parser_statement_seq_opt): Stop at PRAGMA_EOL.
+ (cp_parser_declaration_seq_opt): Likewise.
+ (cp_parser_member_specification_opt): Likewise.
+ (cp_parser_function_definition_after_decl): Likewise.
+ (cp_parser_skip_until_found): Likewise.
+ (cp_parser_cache_group): Likewise.
+ (enum pragma_omp_clause, cp_parser_omp_clause_name,
+ check_no_duplicate_clause,
+ cp_parser_omp_var_list_no_open,
+ cp_parser_omp_var_list, cp_parser_omp_clause_copyin,
+ cp_parser_omp_clause_default, cp_parser_omp_clause_if,
+ cp_parser_omp_clause_nowait,
+ cp_parser_omp_clause_num_threads,
+ cp_parser_omp_clause_ordered,
+ cp_parser_omp_clause_reduction,
+ cp_parser_omp_clause_schedule,
+ cp_parser_omp_all_clauses,
+ cp_parser_omp_structured_block, cp_parser_omp_atomic,
+ cp_parser_omp_barrier, cp_parser_omp_critical,
+ cp_parser_omp_flush, cp_parser_omp_for_loop,
+ cp_parser_omp_for, cp_parser_omp_master,
+ cp_parser_omp_ordered, cp_parser_omp_sections_scope,
+ cp_parser_omp_sections, cp_parser_omp_parallel,
+ cp_parser_omp_single, cp_parser_omp_threadprivate,
+ cp_parser_omp_construct): New.
+ (cp_parser_pragma): Handle OpenMP pragmas.
+ * semantics.c (finish_omp_threadprivate): New.
+ (begin_omp_parallel, finish_omp_parallel): New.
+
+ 2005-10-11 Richard Henderson <rth@redhat.com>
+
+ * parser.c (struct cp_token): Add pragma_kind.
+ (eof_token): Initialize it.
+ (cp_lexer_handle_pragma): Remove.
+ (cp_parser_initial_pragma): New.
+ (cp_lexer_new_main): Use it.
+ (cp_lexer_get_preprocessor_token): Initialize pragma_kind.
+ (cp_lexer_print_token): Don't handle CPP_PRAGMA.
+ (cp_parser_skip_to_pragma_eol): New.
+ (cp_parser_error): Use it.
+ (pragma_lex): New.
+
+ 2005-10-09 Richard Henderson <rth@redhat.com>
+
+ * lex.c (parse_strconst_pragma): Update for c_lex name change.
+ (handle_pragma_java_exceptions): Likewise.
+ * parser.c (cp_lexer_new_main): Likewise.
+
+ 2005-10-06 Richard Henderson <rth@redhat.com>
+
+ * parser.c (cp_lexer_new_main): Comment out defer_pragmas.
+ (cp_lexer_handle_pragma): Comment out
+ cpp_handle_deferred_pragma.
+
+ 2005-10-01 Richard Henderson <rth@redhat.com>
+
+ * name-lookup.c (lookup_name): Remove prefer_type argument.
+ (lookup_name_prefer_type): New function.
+ * name-lookup.h (lookup_name_prefer_type): Declare it.
+ * decl.c (lookup_and_check_tag): Use it.
+ * pt.c (tsubst_friend_class): Likewise. Update for
+ lookup_name change.
+ (lookup_template_class, tsubst_copy_and_build): Likewise.
+
+2006-03-06 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/15759
+ * tree.c (bot_manip): Don't call mark_used.
+
+2006-03-02 Mike Stump <mrs@apple.com>
+
+ * decl2.c (import_export_decl): Remove redundant call to
+ targetm.cxx.key_method_may_be_inline ().
+
+2006-03-02 Richard Sandiford <richard@codesourcery.com>
+
+ * decl.c (start_decl): Use have_global_bss_p when deciding
+ whether to make the decl common.
+
+2006-03-01 Mike Stump <mrs@apple.com>
+
+ PR darwin/25908
+ * decl2.c (import_export_decl): Fix ABI breakage on darwin.
+
+2006-02-24 Geoffrey Keating <geoffk@apple.com>
+
+ * except.c (expand_start_catch_block): Handle
+ flag_use_cxa_get_exception_ptr.
+
+2006-02-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/26291
+ * decl.c (grok_op_properties): Check for ellipsis in arguments of
+ operators.
+
+2006-02-20 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+
+ * Make-lang.in (C++): Remove.
+ (.PHONY): Remove C++.
+
+2006-02-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/26266
+ * cp-tree.h (cp_finish_decl): Adjust declaration.
+ (grokbitfield): Likewise.
+ (finish_static_data_member_decl): Likewise.
+ * init.c (constant_value_1): Ensure processing_template_decl when
+ folding non-dependent initializers for static data members of
+ dependent types. Return error_mark_node for erroneous
+ initailizers.
+ * class.c (get_vtable_decl): Use finish_decl, not cp_finish_decl.
+ * decl.c (cp_make_fname_decl): Adjust call to cp_finish_decl.
+ (cp_finish_decl): Add init_const_expr_p parameter. Set
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P here.
+ (finish_decl): Adjust call to cp_finish_decl.
+ (compute_array_index_type): Robustify.
+ (start_method): Use finish_decl, not cp_finish_decl.
+ * rtti.c (emit_tinfo_decl): Likewise.
+ * except.c (initialize_handler_parm): Adjust call to
+ cp_finish_decl.
+ (expand_start_catch_block): Likewise.
+ * cvt.c (build_up_reference): Adjust call to cp_finish_decl.
+ * pt.c (instantiate_class_template): Adjust call to
+ finish_static_data_member_decl.
+ (tsubst_expr): Use finish_decl, not cp_finish_decl.
+ (instantiate_decl): Adjust call to cp_finish_decl.
+ * name-lookup.c (pushdecl_top_level_1): Use finish_decl, not
+ cp_finish_decl.
+ * decl2.c (finish_static_data_member_decl): Add init_const_expr_p
+ parameter.
+ (grokfield): Likewise.
+ * parser.c (cp_parser_condition): Check for constant initializers.
+ (cp_parser_init_declarator): Adjust calls to grokfield and
+ cp_finish_decl. Don't set
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P here.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_objc_class_ivars): Likewise.
+
+2006-02-14 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * call.c (standard_conversion): Return NULL instead of 0.
+ (build_user_type_conversion_1): Likewise.
+ (tourney): Likewise.
+ * decl.c (redeclaration_error_message): Likewise.
+ * error.c (language_to_string): Likewise.
+
+2006-02-13 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * cp-tree.h (warn_hidden): Remove prototype.
+ * class.c (warn_hidden): Make static.
+
+ * cp-tree.h (build_type_conversion): Remove prototype.
+ * cvt.c (build_type_conversion): Add prototype, make static.
+
+ * cp-tree.h (push_tinst_level): Remove prototype.
+ (pop_tinst_level): Likewise.
+ * pt.c (push_tinst_level): Add prototype, make static.
+ (pop_tinst_level): Likewise.
+
+2006-02-13 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * decl.c (grokdeclarator): Return NULL_TREE instead of 0.
+ * typeck.c (unary_complex_lvalue): Likewise.
+
+2006-02-13 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * lex.c (parse_strconst_pragma): Return error_mark_node instead of
+ "(tree)-1" to indicate failure. Simplify.
+ (handle_pragma_interface): Test for error_mark_node instead of
+ "(tree)-1".
+ (handle_pragma_implementation): Likewise.
+
+2006-02-13 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/26151
+ * parser.c (cp_parser_decl_specifier_seq): Check for duplicate
+ decl-specifiers. Remove extra check for duplicate 'friend'.
+ * decl.c (grokdeclarator): Remove check for duplicate
+ decl-specifiers. Set longlong together with long_p.
+
+2006-02-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/24996
+ * except.c (build_throw): Add a CLEANUP_POINT_EXPR inside the
+ TRY_CATCH_EXPR or MUST_NOT_THROW_EXPR.
+
+2006-02-10 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * class.c (debug_class): Remove extern.
+ (debug_thunks): Likewise.
+
+2006-02-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * typeck.c (string_conv_p): Don't test for flag_const_strings.
+
+2006-02-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/25979
+ * cp-gimplify.c (cp_gimplify_expr): Don't call
+ cp_gimplify_init_expr for MODIFY_EXPRs.
+ * typeck2.c (split_nonconstant_init_1): Use INIT_EXPR.
+
+2006-02-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/26071
+ * decl.c (grokdeclarator): Set dname also for destructor.
+
+ PR c++/26070
+ * decl.c (grokdeclarator): Clear storage_class together with staticp.
+
+2006-02-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (tf_warning_or_error): Renamed from tf_warn_or_error.
+ (cp_build_qualified_type): Propogate renaming.
+ * call.c (convert_like_real): Likewise.
+ * cvt.c (cp_convert_to_pointer, convert_to_reference): Likewise.
+ * decl.c (make_typename_type, grokdeclarator): Likewise.
+ * pt.c (tsubst_friend_function, instantiate_class_template,
+ tsubst_default_argument, instantiate_decl,
+ tsubst_initializer_list, tsubst_enum): Likewise.
+ * semantics.c (finish_template_type): Likewise.
+ * typeck.c (build_ptrmemfunc, convert_for_assignment): Likewise.
+
+2006-02-07 Dirk Mueller <dmueller@suse.com>
+
+ * typeck.c (build_binary_op): Annotate div-by-zero
+ warnings to make -Wno-div-by-zero have an effect.
+
+2006-02-07 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9737
+ * pt.c (coerce_template_template_parms): Do not templates with
+ excess default arguments to match template template parameters
+ with fewer parameters.
+ (coerce_template_parms): Add use_default_args parameter; use
+ default arguments only when true.
+ (lookup_template_class): Adjust call to coerce_template_parms.
+ (fn_type_unification): Likewise.
+ (unify): Likewise.
+ (get_bindings): Likewise.
+ (dependent_type_p): Add assertions.
+
+2006-02-06 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (grokdeclarator): Don't bother checking for CHAR_TYPE.
+ * rtti.c (typeinfo_in_lib_p): Likewise.
+ * cp-tree.h (INTEGRAL_CODE_P, CP_INTEGRAL_TYPE_P): Likewise.
+ * name-lookup.c (arg_assoc_type): Likewise.
+
+2006-02-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (tf_warn_or_error): New substituion flag.
+ (cp_build_qualified_type): Use it.
+ * call.c (convert_like_real): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_reference): Likewise.
+ * decl.c (make_typename_type): Likewise.
+ (grokdeclarator): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+ (tsubst_friend_class): Likewise.
+ (instantiate_class_template): Likewise.
+ (tsubst_default_argument): Likewise.
+ (instantiate_decl): Likewise.
+ (tsubst_initializer_list): Likewise.
+ (tsubst_enum): Likewise.
+ * semantics.c (finish_template_type): Likewise.
+ * typeck.c (build_ptrmemfunc): Likewise.
+ (convert_for_assignment): Likewise.
+
+2006-02-03 Lee Millward <lee.millward@gmail.com>
+
+ * typeck.c (string_conv_p): Pass appropiate
+ OPT_Wxxxx values when calling warning().
+ (build_array_ref, cxx_mark_addressable): Likewise.
+ (check_return_expr): Likewise.
+
+ * init.c (perform_member_init): Likewise.
+ (sort_mem_initializers, emit_mem_initializers): Likewise.
+
+ * class.c (check_field_decls): Likewise.
+ (warn_about_ambiguous_bases): Likewise.
+
+ * decl.c (pop_label, poplevel): Likewise.
+ (duplicate_decls, grok_op_properties): Likewise.
+ (start_preparsed_function, finish_function): Likewise.
+
+ * name-lookup.c (pushdecl_maybe_friend): Likewise.
+ (pushdecl_maybe_friend): Likewise.
+
+ * parser.c (cp_parser_warn_min_max): Likewise.
+ (cp_parser_cast_expression): Likewise.
+
+ * method.c (lazily_declare_fn): Likewise.
+ * cvt.c (convert_to_void): Likewise.
+ * mangle.c (finish_mangling): Likewise.
+ * cp-gimplify.c (gimplify_expr_stmt): Likewise.
+
+2006-02-03 Mark Mitchell <mark@codesourcery.com>
+
+ * name-lookup.c (do_class_using_decl): Use IDENTIFIER_TYPENAME_P,
+ not IDENTIFIER_OPNAME_P.
+
+2006-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25342
+ * cp-tree.h (DECL_TEMPLATE_SPECIALIZATIONS): Revise
+ documentation.
+ * pt.c (determine_specialization): Use INNERMOST_TEMPLATE_PARMS,
+ not TREE_VALUE.
+ (instantiate_class_template): Simplify.
+ (verify_class_unification): Remove.
+ (unify): Document parameters. Use INNERMOST_TEMPLATE_ARGS to
+ permit multiple levels of template arguments.
+ (more_specialized_class): Simplify.
+ (get_class_bindings): Pass full arguments to unify. Fold
+ verify_class_unification into this function. Return full
+ arguments.
+ (most_specialized_class): Adjust for changes to
+ get_class_bindings. Issue errors here for ambiguity. Return the
+ fully deduced arguments for the most specialized class, in
+ addition to the partial specialization.
+
+2006-01-31 Ben Elliston <bje@au.ibm.com>
+
+ * mangle.c: Comment fix.
+
+2006-01-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * Make-lang.in (cp-warn): Include CXX_COMPAT_WARN.
+ * repo.c (extract_string, afgets): Use cast when converting from
+ void *.
+
+2006-01-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * call.c (alloc_conversion): Use cast when converting from void *.
+ (alloc_conversions): Likewise.
+ (add_candidate): Likewise.
+ (print_z_candidates): Likewise.
+ (add_warning): Likewise.
+ * pt.c (retrieve_local_specialization): Likewise.
+ (process_partial_specialization): Likewise.
+ (mangle_class_name_for_template): Likewise.
+ (tsubst_template_args): Likewise.
+ * typeck2.c (pat_calc_hash): Likewise.
+ (pat_compare): Likewise.
+ (abstract_virtuals_error): Likewise.
+ * class.c (method_name_cmp): Likewise.
+ (resort_method_name_cmp): Likewise.
+ (get_vfield_name): Likewise.
+ * decl2.c (generate_ctor_and_dtor_functions_for_priority): Likewise.
+ * lex.c (init_reswords): Likewise.
+ * rtti.c (create_pseudo_type_info): Likewise.
+ * search.c (dfs_lookup_base): Likewise.
+ (dfs_dcast_hint_pre): Likewise.
+ (dfs_dcast_hint_post): Likewise.
+ * tree.c (hash_tree_cons): Likewise.
+ * repo.c (extract_string): Likewise.
+ (afgets): Likewise.
+ * cp-objcp-common.c (decl_shadowed_for_var_lookup): Likewise.
+ * g++spec.c (lang_specific_driver): Likewise.
+
+2006-01-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * call.c (joust): Pass option code to warning. Use inform for
+ explanation.
+ * class.c (check_bases): Likewise.
+ (maybe_warn_about_overly_private_class): Likewise.
+ (check_field_decls): Likewise.
+ (layout_empty_base): Likewise.
+ (layout_virtual_bases): Likewise.
+ (layout_class_type): Likewise.
+
+2006-01-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25999
+ * decl.c (start_preparsed_function): Call maybe_apply_pragma_weak
+ here, not ...
+ (start_function): ... here.
+
+2006-01-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25855
+ * class.c (resolve_address_of_overloaded_function): Adjust use of
+ return value from most_specialized_instantiation.
+ * pt.c (determine_specialization): Avoid multiple calls to
+ get_bindings.
+ (most_specialized_instantiation): When a tie occurs, set the
+ current presumed champion to the next template. Return the
+ TREE_LIST node containing the template, rather than the template
+ itself.
+ (most_specialized): Remove.
+ * name-lookup.c (push_overloaded_decl): When duplicate_decls
+ indicates a failed redeclaration, report that to callers.
+
+2006-01-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/16021
+ * name-lookup.c (parse_using_directive): Require strong using to
+ name a nested namespace.
+
+2006-01-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ Revert:
+ * cp-tree.h (do_poplevel): Remove prototype.
+ * semantics.c (do_poplevel): Add prototype. Make static.
+
+ Revert:
+ * cp-tree.h (default_conversion): Remove prototype.
+ * typeck.c (default_conversion): Make static.
+
+2006-01-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * cp-tree.h (get_primary_binfo): Remove prototype.
+ (push_using_decl): Likewise.
+ (current_template_args): Likewise.
+ (more_specialized_class): Likewise.
+ (mark_class_instantiated): Likewise.
+ (default_conversion): Likewise.
+ (pfn_from_ptrmemfunc): Likewise.
+ * class.c (get_primary_binfo): Add prototype, make static, simplify.
+ * name-lookup.c (push_using_decl): Make static.
+ * pt.c (current_template_args): Likewise.
+ (more_specialized_class): Likewise.
+ (mark_class_instantiated): Likewise.
+ * typeck.c (default_conversion): Make static.
+ (pfn_from_ptrmemfunc): Add prototype, make static.
+
+2006-01-24 Dirk Mueller <dmueller@suse.de>
+
+ * typeck.c (build_binary_op): Use OPT_Wfloat_equal in warning().
+
+2006-01-24 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/25552
+ * parser.c (cp_parser_unqualified_id): Check that destructor name
+ and scope match.
+ * call.c (check_dtor_name): Do not expect a BIT_NOT_EXPR.
+ Adjust comment. Return early if possible.
+ Use same_type_p to compare types.
+ * typeck.c (lookup_destructor): Adjust call to check_dtor_name.
+
+2006-01-24 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c: Remove outdated comment.
+
+2006-01-23 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * cp-tree.h (do_poplevel): Remove prototype.
+ * semantics.c (do_poplevel): Add prototype. Make static.
+
+ * cp-tree.h (original_type): Remove prototype.
+ * typeck.c (original_type): Make static.
+
+ * cp-tree.h (declare_global_var): Remove prototype.
+ * decl.c (declare_global_var): Make static.
+
+ * cp-tree.h (implicitly_declare_fn): Remove prototype.
+ * method.c (implicitly_declare_fn): Make static.
+
+ * cp-tree.h (fold_decl_constant_value): Remove prototype.
+ * pt.c (fold_decl_constant_value): Make static.
+
+ * cp-tree.h (build_x_delete): Remove prototype.
+ * init.c (build_vec_delete_1): Call build_op_delete_call directly
+ and not via build_x_delete.
+ (build_x_delete): Remove.
+
+ * cp-tree.h (get_vtt_name): Remove prototype.
+ * class.c (get_vtt_name): Remove.
+ (build_vtt): Call mangle_vtt_for_type instead of get_vtt_name.
+
+2006-01-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * rtti.c (build_dynamic_cast): Fix comment.
+
+2006-01-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10891
+ * rtti.c (build_dynamic_cast): Reject dynamic_cast use if
+ -fno-rtti.
+
+2006-01-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25895
+ * class.c (build_base_path): Generate a NOP_EXPR instead of a
+ COMPONENT_REF if the base and derived classes are at the same
+ address.
+
+ PR c++/25856
+ * decl.c (begin_destructor_body): Robustify.
+
+ PR c++/25858
+ * parser.c (cp_parser_direct_declarator): Robustify.
+
+2006-01-20 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * parser.c (cp_lexer_next_token_is_keyword): Simplify.
+
+ * parser.c (clear_decl_specs): Remove prototype.
+
+ * parser.c (cp_parser_expression_fn): Remove.
+
+ * call.c (add_builtin_candidates): Remove superfluous return.
+ * name-lookup.c (do_toplevel_using_decl): Likewise.
+ * parser.c (cp_parser_type_specifier_seq): Likewise.
+ (cp_parser_save_default_args): Likewise.
+
+2006-01-20 Dirk Mueller <dmueller@suse.com>
+
+ PR c++/5520
+ * semantics.c (finish_if_stmt): Call empty_body_warning.
+ * parser.c (cp_parser_implicitly_scoped_statement):
+ Mark empty statement with an empty stmt.
+
+2006-01-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22136
+ * name-lookup.c (do_class_using_decl): Don't try to look up base
+ classes in templates with dependent base types.
+
+2006-01-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/25854
+ * pt.c (maybe_process_partial_specialization): Return early on
+ error_mark_node.
+
+2006-01-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/16829
+ * decl.c (start_preparsed_function): Check default arguments
+ unconditionally.
+ * name-lookup.c (pushdecl_maybe_friend): Check default arguments
+ of all functions and function templates.
+ * parser.c (cp_parser_late_parsing_default_args): Check default
+ arguments.
+ * decl2.c (check_default_args): Set missing default arguments to
+ error_mark_node.
+
+2006-01-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25836
+ * cp-tree.h (push_class_stack): New function.
+ (pop_class_stack): Likewise.
+ * class.c (class_stack_node): Add hidden field.
+ (pushclass): Clear it.
+ (push_class_stack): New function.
+ (pop_class_stack): Likewise.
+ (currently_open_class): Ignore hidden classes.
+ (currently_open_derived_class): Likewise.
+ * name-lookup.c (push_to_top_level): Call push_class_stack.
+ (pop_from_top_level): Call pop_class_stack.
+
+2006-01-18 Kazu Hirata <kazu@codesourcery.com>
+
+ * tree.c (find_tree_t, find_tree): Remove.
+ * cp-tree.h: Remove the prototype for find_tree.
+
+2006-01-18 Jakub Jelinek <jakub@redhat.com>
+
+ * search.c (lookup_conversions_r): Fix a pasto.
+
+2006-01-17 Eric Christopher <echristo@apple.com>
+
+ * call.c (convert_like_real): When issuing conversion
+ warnings, depend on OPT_Wconversion.
+ * cvt.c (build_expr_type_conversion): Ditto.
+
+2006-01-17 Kazu Hirata <kazu@codesourcery.com>
+
+ * name-lookup.c (lookup_namespace_name): Remove.
+ * name-lookup.h: Remove the prototype for
+ lookup_namespace_name.
+
+2006-01-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/25682
+ * decl.c (compute_array_index_type): After issuing not an integral
+ constant-expression error, set size to 1 to avoid ICEs later on.
+
+2006-01-16 Ian Lance Taylor <ian@airs.com>
+
+ * parser.c: Include "cgraph.h".
+ (cp_parser_asm_definition): Call cgraph_add_asm_node rather than
+ assemble_asm.
+
+2006-01-16 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+
+ * g++spec.c (lang_specific_spec_functions): Remove.
+
+2006-01-15 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (check_initializer): Fix thinko.
+
+2006-01-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25663
+ * parser.c (cp_parser_direct_declarator): Use cp_parser_error
+ instead of error.
+
+2006-01-13 Jason Merrill <jason@redhat.com>
+
+ * pt.c (check_explicit_specialization): Use CP_DECL_CONTEXT even more.
+
+ * name-lookup.c (set_decl_namespace): Use CP_DECL_CONTEXT.
+ * pt.c (check_explicit_specialization): Likewise.
+
+2006-01-12 Jason Merrill <jason@redhat.com>
+
+ PR libstdc++/24660
+ * pt.c (check_explicit_specialization): Handle namespace
+ association.
+ * name-lookup.c (set_decl_namespace): Likewise.
+
+2006-01-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/24824
+ * class.c (handle_using_decl): Pass correct scope to
+ cp_emit_debug_info_for_using.
+
+2006-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/25386
+ * tree.c (lvalue_p_1): Any part of a COMPONENT_REF affects
+ packedness.
+
+2006-01-06 Gabriel Dos Reis <gdr@integrablesolutions.net>
+
+ * parser.c (cp_parser_primary_expression): Document the grammar
+ for the built-in offsetof, a GNU extension.
+
+2006-01-04 Zdenek Dvorak <dvorakz@suse.cz>
+
+ PR c++/25632
+ * init.c (constant_value_1): Unshare use of DECL_INITIAL. Fix a typo
+ in condition.
+
+2006-01-04 Chris Lattner <sabre@gnu.org>
+
+ * typeck2.c: update copyright to 2006
+ (split_nonconstant_init_1): Set TREE_CONSTANT to true.
+
+2006-01-04 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/24782
+ * parser.c (cp_parser_nested_name_specifier_opt): Preserve access
+ checks, even when parsing tentatively.
+
+2006-01-04 Richard Henderson <rth@redhat.com>
+
+ Merge from gomp branch.
+ * lex.c (handle_pragma_java_exceptions): Fix whitespace.
+ * parser.c (struct cp_token): Add pragma_kind.
+ (eof_token): Update to match.
+ (struct cp_lexer): Add in_pragma; rearrange next for better packing.
+ (cp_parser_initial_pragma): New.
+ (cp_lexer_new_main): Use it. Don't bother clearing
+ c_lex_return_raw_strings.
+ (cp_lexer_get_preprocessor_token): Always initialize keyword
+ and pragma_kind fields. Handle CPP_PRAGMA.
+ (cp_lexer_consume_token): Don't allow CPP_PRAGMA_EOL when
+ in_pragma is set.
+ (cp_lexer_handle_pragma): Remove. Update callers to cp_parser_pragma.
+ (cp_lexer_print_token) <CPP_PRAGMA>: Don't print as a string.
+ (cp_parser_skip_to_pragma_eol): New.
+ (cp_parser_error): Use it.
+ (cp_parser_skip_to_closing_parenthesis): Stop at CPP_PRAGMA_EOL;
+ rearrange with switch statement.
+ (cp_parser_skip_to_end_of_statement): Likewise.
+ (cp_parser_skip_to_end_of_block_or_statement): Likewise.
+ (cp_parser_skip_to_closing_brace): Likewise.
+ (cp_parser_skip_until_found): Likewise.
+ (cp_parser_statement): Add in_compound argument; update callers.
+ Use it to decide how to handle pragma parsing.
+ (cp_parser_labeled_statement): Add in_compound argument; pass
+ it on to cp_parser_statement.
+ (cp_parser_statement_seq_opt): Stop at CPP_PRAGMA_EOL.
+ (cp_parser_declaration_seq_opt): Likewise.
+ (cp_parser_parameter_declaration): Likewise.
+ (cp_parser_member_specification_opt): Likewise.
+ (cp_parser_function_definition_after_decl): Likewise.
+ (cp_parser_cache_group): Handle CPP_PRAGMA/CPP_PRAGMA_EOL pairs.
+ (cp_parser_pragma): New.
+ (pragma_lex): New.
+
+2006-01-04 Dirk Mueller <dmueller@suse.com>
+
+ * decl.c (finish_constructor_body): create simple
+ compound stmt instead of a if(1) { } construct.
+
+2006-01-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25492
+ * name-lookup.c (push_class_level_binding): When a derived class
+ provides a type binding, eliminate any type binding from a base
+ class.
+
+ PR c++/25625
+ * repo.c (repo_emit_p): Always instantiate static data members
+ initialized by constant expressions, so that there values are
+ available.
+
+2006-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25635
+ * class.c (add_method): Set TYPE_HAS_CONVERSION for classes with a
+ conversion operator.
+ * decl.c (grokdeclarator): Do not set TYPE_HAS_CONVERSION here.
+
+ PR c++/25638
+ * class.c (add_method): Never associate more than one destructor
+ with a single class.
+
+ PR c++/25637
+ * cp-tree.h (do_friend): Adjust prototype.
+ * decl.c (grokfndecl): Make funcdef_flag a bool, not an int.
+ (grokdeclarator): Likewise. Refine check for invalid
+ declarations/definitions of member functions outside of their own
+ class.
+ * friend.c (do_friend): Make funcdef_flag a bool, not an int.
+
+ PR c++/25633
+ * parser.c (cp_parser_mem_initializer_list): Check result of
+ cp_parser_mem_initializer against error_mark_node, not NULL_TREE.
+ (cp_parser_mem_initializer): Return error_mark_node for failure.
+
+ PR c++/25634
+ * parser.c (cp_parser_template_parameter_list): Call
+ begin_template_parm_list and end_template_parm_list here.
+ (cp_parser_type_parameter): Not here.
+ (cp_parser_template_declaration_after_export): Or here.
+ (cp_parser_elaborated_type_specifier): Call
+ cp_parser_check_template_parameters.
+
+ * tree.c (build_target_expr_with_type): Use force_target_expr.
+
+ * decl2.c (mark_used): Fix typo in comment.
+
+2006-01-02 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * parser.c (cp_parser_using_declaration): Skip name-lookup on
+ invalid scope.
+
+
+
+Copyright (C) 2006 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2007 b/gcc-4.9/gcc/cp/ChangeLog-2007
new file mode 100644
index 000000000..817bab6db
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2007
@@ -0,0 +1,3343 @@
+2007-12-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/34111
+ * call.c (standard_conversion): Derived-to-base is considered a
+ standard conversion.
+
+2007-12-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34513
+ * parser.c (cp_parser_omp_parallel): For non-combined parallel
+ call cp_parser_statement rather than
+ cp_parser_already_scoped_statement.
+
+2007-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/34206
+ * pt.c (tsubst_aggr_type): Do nothing if the type already doesn't
+ use template parms.
+ (dependent_type_p_r): Handle the domain of an array.
+
+2007-12-18 Douglas Gregor <doug.gregor@gmail.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/32565
+ PR c++/33943
+ PR c++/33965
+ * pt.c (template_template_parm_bindings_ok_p): New; verifies
+ bindings of template template parameters after all template
+ arguments have been deduced.
+ (coerce_template_parms): Don't complain when COMPLAIN doesn't
+ include tf_error.
+ (fn_type_unification): Use template_template_parm_bindings_ok_p.
+ (unify): Deal with variadic, bound template template parameters.
+ (get_class_bindings): Use template_template_parm_bindings_ok_p.
+
+2007-12-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34488
+ * decl.c (grokdeclarator): Reject friend sfk_constructor
+ FUNCTION_TYPE.
+
+2007-12-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/34506
+ * parser.c (cp_parser_omp_all_clauses): Accept optional comma
+ in between clauses.
+
+2007-12-15 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/7081
+ * cp-lang.c (cp_classify_record): New.
+ (LANG_HOOKS_CLASSIFY_RECORD): Override.
+
+2007-12-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34238
+ * decl2.c (cp_write_global_declarations): Revert 2007-11-22 change.
+
+ PR c++/34364
+ * rtti.c (build_dynamic_cast): Call convert_from_reference even for
+ dynamic_cast in a template.
+
+2007-12-10 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/34059
+ * typeck.c (build_class_member_access_expr): Compute MEMBER_SCOPE from
+ MEMBER's BASELINK_ACCESS_BINFO instead of its BASELINK_BINFO.
+
+2007-12-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34395
+ * error.c (dump_type_prefix, dump_type_suffix): Handle
+ TYPE_PACK_EXPANSION.
+
+ PR c++/34394
+ * error.c (dump_expr): Handle ABS_EXPR.
+
+2007-12-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34178
+ PR c++/34340
+ * repo.c (repo_emit_p): Return 2 for DECL_INTEGRAL_CONSTANT_VAR_P
+ in class scope rather than DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+ Return 2 also if DECL_EXPLICIT_INSTANTIATION.
+ * decl2.c (import_export_decl): Don't make VAR_DECLs import_p when
+ flag_use_repository and repo_emit_p returned 2.
+
+2007-12-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34336
+ * tree.c (stabilize_call, stabilize_init): Do nothing if
+ processing_template_decl.
+
+2007-12-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34271
+ * semantics.c (finish_decltype_type): For SCOPE_REF issue an
+ error instead of assertion failure.
+ * parser.c (cp_parser_decltype): If closing paren is not found,
+ return error_mark_node.
+
+2007-12-04 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34101
+ * name-lookup.c (arg_assoc_template_arg): Recurse on argument
+ packs.
+ (arg_assoc_type): We don't need to handle TYPE_ARGUMENT_PACK here,
+ since arg_assoc_template_arg will deal with them (better).
+
+2007-12-04 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33509
+ * pt.c (tsubst_exception_specification): Handle substitutions into
+ member templates, where tsubst_pack_expansion returns a
+ TYPE_PACK_EXPANSION.
+
+2007-12-04 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33091
+ * pt.c (unify_pack_expansion): If we didn't deduce any actual
+ bindings for the template parameter pack, don't try to keep the
+ empty deduced arguments.
+ (unify): If a parameter is a template-id whose template argument
+ list contains a pack expansion that is not at the end, then we
+ cannot unify against that template-id.
+
+2007-12-02 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/34061
+ * pt.c (current_template_args): Use error_operand_p.
+
+2007-12-02 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/34273
+ * error.c (dump_decl): Handle TREE_BINFO.
+
+2007-12-01 Ollie Wild <aaw@google.com>
+
+ PR c++/8171
+ * typeck.c (build_binary_op): Add conversion of pointers to function
+ members appearing as operands to the equality operators.
+
+2007-11-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34275
+ * error.c (dump_expr): Handle OBJ_TYPE_REF.
+
+2007-11-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34270
+ * tree.c (lvalue_p_1) <case COND_EXPR>: Handle x ?: y
+ in templates.
+ * typeck.c (is_bitfield_expr_with_lowered_type) <case COND_EXPR>:
+ Likewise.
+
+ PR c++/34267
+ PR c++/34268
+ * parser.c (cp_parser_decltype): Don't call finish_id_expression
+ on ~type.
+ * semantics.c (finish_decltype_type): Issue error on types, TYPE_DECLs
+ and ~type early.
+
+2007-11-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/34181
+ * method.c (use_thunk): Don't inline the call in the thunk.
+
+ PR c++/34213
+ * tree.c (decl_linkage): Static data members and static member
+ functions in anonymous ns classes are lk_external.
+
+2007-11-26 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ PR c++/34081
+ * decl.c (start_preparsed_function): Pass
+ processing_template_decl for the new allocate_struct_function
+ parameter.
+
+2007-11-25 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (poplevel): Use BLOCK_CHAIN.
+
+2007-11-24 Ollie Wild <aaw@google.com>
+
+ * typeck.c (delta_from_ptrmemfunc): New function.
+ (get_member_function_from_ptrfunc): Call delta_from_ptrmemfunc.
+ (build_binary_op): Call delta_from_ptrmemfunc.
+
+2007-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/30293
+ PR c++/30294
+ * decl.c (cp_finish_decl): Disallow variable or field
+ definitions if extern "Java" aggregates.
+ (grokparms): Disallow parameters with extern "Java"
+ aggregates.
+ (check_function_type): Disallow function return values
+ with extern "Java" aggregates.
+ * init.c (build_new_1): Disallow placement new with
+ extern "Java" aggregates.
+
+2007-11-23 Mark Mitchell <mark@codesourcery.com>
+ Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/5310
+ * call.c (convert_like_real): Build a zero constant when __null is
+ converted to an integer type.
+
+2007-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34094
+ * decl2.c (cp_write_global_declarations): Issue error about static
+ data members in anonymous namespace which are declared and used,
+ but not defined.
+
+2007-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34089
+ * parser.c (cp_parser_class_head): Reject function template ids.
+
+ PR c++/28879
+ * tree.c (build_cplus_array_type_1): Don't pass any VLA types
+ when processing_template_decl to build_array_type.
+
+ PR c++/33962
+ * pt.c (more_specialized_fn): Don't segfault if one or
+ both argument list end with ellipsis.
+
+2007-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/30988
+ * semantics.c (finish_call_expr): Set
+ current_function_returns_abnormally if fn is noreturn FUNCTION_DECL
+ or OVERLOAD with all noreturn functions.
+
+2007-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34100
+ * pt.c (apply_late_template_attributes): Do nothing if decl's type is
+ error_mark_node.
+
+2007-11-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34054
+ PR c++/34056
+ PR c++/34057
+ PR c++/34058
+ PR c++/34060
+ * pt.c (find_parameter_packs_r): If ppd->set_packs_to_error,
+ set to error_mark_node the outermost POINTER_TYPE to the pack if
+ it is seen in a POINTER_TYPE.
+ (push_template_decl_real): If check_for_bare_parameter_packs
+ fails for function return type, set the return type to
+ integer_type_node. If check_for_bare_parameter_packs failed
+ for non-function, return error_mark_node.
+
+ PR c++/29225
+ * call.c (build_new_op): Call resolve_args before calling
+ build_over_call.
+
+2007-11-11 Tom Tromey <tromey@redhat.com>
+
+ PR c++/17577:
+ * lex.c (handle_pragma_implementation): Use cpp_included_before.
+
+2007-11-12 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/8570
+ * pt.c (redeclare_class_template): Update error message. Use a
+ note to show the previous declaration.
+ (tsubst_friend_class): Use the location of the friend template as
+ the input location before calling redeclare_class_template.
+
+2007-11-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34068
+ * semantics.c (finish_pseudo_destructor_expr): Handle
+ object == error_mark_node.
+
+2007-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/32241
+ * pt.c (tsubst_copy_and_build) <case COMPONENT_REF>: If object_type
+ is not scalar type, let finish_class_member_access_expr handle
+ diagnostics. Pass BIT_NOT_EXPR argument to
+ finish_pseudo_destructor_expr. Handle SCOPE_REF properly.
+
+2007-11-09 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33510
+ * decl.c (cp_complete_array_type): If any of the initializer
+ elements are pack expansions, don't compute the array size yet.
+
+2007-11-08 Andrew Pinski <pinskia@gmail.com>
+
+ PR c++/30297:
+ * tree.c (decl_linkage): Fields have no linkage.
+
+2007-11-08 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * class.c (build_ctor_vtbl_group): Lay out the new type and decl.
+
+2007-11-07 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33045
+ PR c++/33837
+ PR c++/33838
+ * semantics.c (finish_decltype_type): See through INDIRECT_REFs.
+ Be careful with ERROR_MARK_NODEs.
+ * parser.c (cp_parser_check_access_in_redeclaration): Handle NULL
+ argument.
+
+2007-11-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33501
+ * call.c (build_over_call): Don't check TREE_ADDRESSABLE
+ on incomplete type.
+
+2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33977
+ PR c++/33886
+ * tree.c (c_build_qualified_type): Define bridge to
+ cp_build_qualified_type.
+
+2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/31439
+ PR c++/32114
+ PR c++/32115
+ PR c++/32125
+ PR c++/32126
+ PR c++/32127
+ PR c++/32128
+ PR c++/32253
+ PR c++/32566
+ * typeck.c (check_return_expr): Pass address of retval to
+ check_for_bare_parameter_packs.
+ * class.c (build_base_field): Tolerate bases that have no layout
+ due to errors.
+ (end_of_base): Ditto.
+ * tree.c (canonical_type_variant): Be careful with
+ ERROR_MARK_NODE.
+ * cp-tree.h (check_for_bare_parameter_packs): Now accepts a
+ tree*.
+ * pt.c (find_parameter_pack_data): Add set_packs_to_error field,
+ which states whether parameter packs should be replaced with
+ ERROR_MARK_NODE.
+ (find_parameter_packs_r): Pass addresses to cp_walk_tree wherever
+ possible. If set_packs_to_error is set true, replace the parameter
+ pack with ERROR_MARK_NODE. Manage our own pointer sets.
+ (uses_parameter_packs): Don't set parameter packs to
+ ERROR_MARK_NODE.
+ (check_for_bare_parameter_packs): Now takes a pointer to a tree,
+ which may be modified (if it is a parameter pack). Instructs
+ find_parameter_packs_r to replace parameter packs with
+ ERROR_MARK_NODE (so that they won't cause errors later on).
+ (process_template_parm): Pass pointer to
+ check_for_bare_parameter_packs.
+ (process_partial_specialization): Replace pack expansions before
+ the end of the template argument list with ERROR_MARK_NODE.
+ (push_template_decl_real): Pass pointer to
+ check_for_bare_parameter_packs. Replace parameter packs not at the
+ end of the template parameter list with ERROR_MARK_NODE.
+ (convert_template_argument): Be more careful about using DECL_NAME
+ on only declarations.
+ (unify): Can't unify against ERROR_MARK_NODE.
+ * semantics.c (finish_cond): Pass pointer to
+ check_for_bare_parameter_packs.
+ (finish_expr_stmt): Ditto.
+ (finish_for_expr): Ditto.
+ (finish_switch_cond): Pass pointer to
+ check_for_bare_parameter_packs, and call it before we put the
+ condition into the statement.
+ (finish_mem_initializers): Pass pointer to
+ check_for_bare_parameter_packs.
+ (finish_member_declaration): Ditto.
+ * parser.c (cp_parser_base_clause): Ditto.
+
+2007-11-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/33168
+ * decl.c (cp_finish_decl): Call make_rtl_for_nonlocal_decl already
+ with the final TREE_READONLY flag in place. processing_template_decl
+ is known to be 0 in this part of function.
+
+ PR c++/33894
+ * cp-tree.h: Update comment - TYPE_LANG_FLAG_0 is not
+ OMP_ATOMIC_DEPENDENT_P in OMP_ATOMIC.
+ * pt.c (tsubst_expr): Assert OMP_ATOMIC_DEPENDENT_P.
+ * semantics.c (finish_omp_atomic): Revert most of the
+ 2007-02-05 changes, just keep the new representation of
+ OMP_ATOMIC_DEPENDENT_P OMP_ATOMIC.
+
+2007-11-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/33871
+ * decl2.c (constrain_visibility): Clear DECL_ONE_ONLY if marked
+ local.
+
+2007-11-05 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33996
+ PR c++/33235
+ PR c++/33930
+ * typeck.c (merge_types): Don't lose rvalue references when
+ merging types.
+ * call.c (build_over_call): Don't elide move constructors just
+ because the copy constructor is trivial (!).
+ (compare_ics): If comparing cv-qualifiers fails, we can still order
+ based on binding lvalues vs. rvalues.
+
+2007-11-05 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33939
+ * pt.c (unify_pack_expansion): bring handling of function call
+ arguments into line with type_unification_real.
+
+2007-11-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * typeck.c (build_binary_op): Use pedwarn instead of error for
+ consistency.
+
+2007-11-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33836
+ * parser.c (cp_parser_unary_expression): For &&label call
+ cp_parser_non_integral_constant_expression and return error_mark_node
+ if it returned true.
+
+ PR c++/33969
+ * decl.c (grokdeclarator): Don't call build_memfn_type if type
+ is neither FUNCTION_TYPE nor METHOD_TYPE.
+
+2007-11-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33516
+ * parser.c (cp_parser_nested_name_specifier_opt): Use
+ TYPE_MAIN_VARIANT (new_scope) as scope if new_scope is an incomplete
+ typedef of currently open class.
+
+2007-11-02 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33495
+ * error.c (dump_expr): Deal specially with statements.
+
+2007-11-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/30897
+ * pt.c (push_template_decl_real): Set DECL_CONTEXT on template
+ template parms.
+ (lookup_template_class): Use it to get the outer template args
+ for instantiating one.
+
+ PR c++/29236
+ * pt.c (reduce_template_parm_level): tsubst the parameters
+ of a template template parm.
+
+2007-11-01 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33955
+ * pt.c (find_parameter_packs_r): Handle TYPENAME_TYPE.
+
+2007-11-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/32384
+ * parser.c (cp_parser_postfix_dot_deref_expression): If
+ POSTFIX_EXPRESSION is type dependent, try to parse it as pseudo dtor
+ first and if that succeeds and type is SCALAR_TYPE_P, create
+ PSEUDO_DTOR_EXPR.
+
+ PR c++/32260
+ * rtti.c (enum_tinfo_kind): Fix TK_TYPE_INFO_TYPE comment.
+ (typeid_ok_p): Use the same alias set for abi::__type_info_pseudo
+ as for std::type_info.
+
+2007-10-31 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33494
+ * cxx-pretty-print.c (pp_cxx_typeid_expression,
+ pp_cxx_delete_expression): Change to static linkage.
+ * cxx-pretty-print.h: Adjust declarations.
+ * error.c (dump_expr, case EXPR_PACK_EXPANSION, TYPEID_EXPR,
+ MEMBER_REF, DOTSTAR_EXPR, DELETE_EXPR, VEC_DELETE_EXPR,
+ MODOP_EXPR): Forward to pp_expression.
+
+ * cxx-pretty-print.c (pp_cxx_expression, case NON_DEPENDENT_EXPR):
+ Fix typo.
+
+2007-10-31 Christian Bruel <christian.bruel@st.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/19531
+ * typeck.c (check_return_expr): Don't set named_return_value_okay_p
+ if retval is volatile.
+
+2007-10-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33616
+ * decl2.c (build_offset_ref_call_from_tree): Call
+ build_non_dependent_expr on object prior to building ADDR_EXPR from it
+ if FN is DOTSTAR_EXPR.
+
+2007-10-30 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/31993
+ PR c++/32252
+ * pt.c (find_parameter_packs_r): Fix typo in comment.
+ (convert_template_argument): Look at the pattern of a pack
+ expansion to determine what kind of entity we're converting.
+ (coerce_template_parameter_pack): When we have coerced a non-type
+ template parameter pack, substitute into the type of that pack.
+ (tsubst_pack_expansion): When our substitution of a parameter pack
+ is a "trivial" substitution of itself, just substitute into the
+ pack expansion rather than actually expanding.
+
+2007-10-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33841
+ * class.c (check_bitfield_decl): Don't set field's type to error_mark_node
+ for non-integral type bitfields. Return true if bitfield is correct, false
+ error has been diagnosed.
+ (check_field_decls): If check_bitfield_decl returned false, call also
+ check_field_decl.
+
+2007-10-28 Paolo Carlini <pcarlini@suse.de>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/30659
+ * pt.c (do_decl_instantiation): If the VAR_DECL is not a
+ class member error out and return.
+
+2007-10-27 Jakub Jelinek <jakub@redhat.com>
+
+ * error.c (reinit_cxx_pp): Initialize cxx_pp->enclosing_scope
+ to current_function_decl rather than 0.
+
+ PR c++/33844
+ * cxx-pretty-print.c (pp_cxx_pm_expression) <case MEMBER_REF>: Print
+ ->* rather than .*.
+ * error.c (dump_expr): Handle MEMBER_REF and DOTSTAR_EXPR.
+
+2007-10-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/5247
+ * call.c (convert_default_arg): Detect recursion.
+
+2007-10-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33842
+ * cxx-pretty-print.h (pp_cxx_offsetof_expression): New prototype.
+ * cxx-pretty-print.c (pp_cxx_primary_expression): Handle
+ OFFSETOF_EXPR.
+ (pp_cxx_offsetof_expression_1, pp_cxx_offsetof_expression): New
+ functions.
+ * error.c (dump_expr): Handle OFFSETOF_EXPR.
+
+2007-10-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/24791
+ * pt.c (get_template_info): New fn.
+ (template_class_depth): Use it.
+ (push_template_decl_real): Check that the template args of the
+ definition match the args of the previous declaration.
+
+2007-10-26 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/31988
+ * decl2.c (coerce_new_type): Do not allow a default argument for
+ the first parameter.
+
+2007-10-26 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33839
+ * parser.c (cp_parser_decltype): Return ERROR_MARK_NODE if we
+ don't see the leading '('. Only lookup names if we get an
+ IDENTIFIER_NODE.
+
+2007-10-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33744
+ * parser.c (cp_parser_parenthesized_expression_list): Set
+ greater_than_is_operator_p to true in between the parens.
+
+2007-10-26 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/31747
+ * decl.c (grokdeclarator): In case of conflicting specifiers
+ just return error_mark_node.
+
+2007-10-26 Ollie Wild <aaw@google.com>
+
+ * expr.c (cxx_expand_expr): Removed.
+ * cp-tree.h (exx_expand_expr): Removed.
+ * cp-objcp-common.h (LANK_HOOKS_EXPAND_EXPR): Replace cxx_expand_expr
+ with c_expand_expr.
+
+2007-10-25 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33843
+ * cxx-pretty-print.c (pp_cxx_unqualified_id): Deal with BIT_NOT_EXPR.
+
+2007-10-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/25950 (DR 391)
+ * call.c (struct conversion): Remove check_copy_constructor_p.
+ (reference_binding): Always bind a reference directly to a
+ compatible class rvalue. Pass down LOOKUP_NO_TEMP_BIND during
+ temporary creation.
+ (check_constructor_callable): Remove.
+ (convert_like_real): Don't call it.
+ (initialize_reference): Don't call check_constructor_callable.
+ (standard_conversion): Check LOOKUP_NO_CONVERSION instead of
+ LOOKUP_CONSTRUCTOR_CALLABLE. Don't require a temporary for base
+ conversions if LOOKUP_NO_TEMP_BIND.
+ (implicit_conversion): Pass through LOOKUP_NO_TEMP_BIND.
+ (build_user_type_conversion_1): Pass through LOOKUP_NO_TEMP_BIND for
+ second conversion.
+ * cp-tree.h (LOOKUP_CONSTRUCTOR_CALLABLE): Remove.
+
+2007-10-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33372
+ * semantics.c (finish_omp_clauses): Check !type_dependent_expression_p
+ before checking if its type is integral.
+
+2007-10-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/33620
+ * class.c (finish_struct_bits): Copy TYPE_ATTRIBUTES.
+ * pt.c (apply_late_template_attributes): Splice out dependent
+ attributes from DECL_ATTRIBUTES.
+
+ * decl.c (cxx_maybe_build_cleanup): Use build_address.
+
+2007-10-17 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * typeck.c (build_binary_op) : Use appropriate warning option
+ instead of unnamed warning.
+
+2007-10-16 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/31446
+ * pt.c (current_template_args): Do not change TREE_LIST elements
+ with a TREE_VALUE of error_mark_node.
+
+2007-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (cp_apply_type_quals_to_decl): Expand documentation.
+ * decl.c (start_decl): Tidy.
+ (start_decl_1): Call cp_apply_type_quals_to_decl after completing
+ the type.
+ (grokdeclarator): Clarify comment.
+
+2007-10-14 Andrew Pinski <pinskia@gmail.com>
+
+ PR c++/30303
+ * decl.c (grokfndecl): Return NULL after the "definition of
+ implicitly-declared" error happened.
+
+2007-10-12 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/26698
+ * call.c (build_user_type_conversion_1): Do not consider conversion
+ functions to convert a (possibly cv-qualified) object to the (possibly
+ cv-qualified) same object type (or a reference to it), to a (possibly
+ cv-qualified) base class of that type (or a reference to it).
+
+2007-10-12 Paolo Carlini <pcarlini@suse.de>
+
+ * pt.c (tsubst): Use template_parm_level_and_index.
+
+2007-10-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/32121
+ * parser.c (cp_parser_compound_statement): Handle label-declarations
+ at the beginning of the compound statement.
+ (cp_parser_block_declaration): Issue diagnostics about __label__
+ not at the beginning of a block.
+
+2007-10-11 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33461
+ * pt.c (coerce_template_parameter_pack): Do not pass error_mark_node
+ to convert_template_argument.
+ (coerce_template_parms): Return error_mark_node after fixed-length
+ error.
+ (tsubst_decl): Check for error_mark_node the return value of the
+ first tsubst in 'case VAR_DECL'.
+
+2007-10-08 Ollie Wild <aaw@google.com>
+
+ * typeck2.c (digest_init): Call cplus_expand_constant after
+ convert_for_initialization.
+ * cp-objcp-common.h (LANG_HOOKS_EXPAND_CONSTANT): Removed.
+ * expr.c (cplus_expand_constant): Updated function description.
+
+2007-10-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/20416
+ * call.c (initialize_reference): Handle local static reference
+ temps properly.
+
+2007-10-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/32470
+ * name-lookup.c (push_namespace_with_attrs): Fold back into...
+ (push_namespace): Here.
+ (handle_namespace_attrs): New fn for the attr code.
+ (leave_scope): Don't pop_visibility.
+ * name-lookup.h (struct cp_binding_level): Remove has_visibility.
+ * parser.c (cp_parser_namespace_definition): Call
+ handle_namespace_attrs and pop_visibility as appropriate.
+
+ PR c++/11756
+ * mangle.c (write_type) [TYPEOF_TYPE]: Just sorry.
+
+2007-10-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * decl.c (duplicate_decls): Preserve linkage flags for mere
+ redeclarations of gnu_inline definitions.
+
+2007-10-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/15764
+ * decl.c (wrap_cleanups_r): New fn.
+ (wrap_temporary_cleanups): New fn.
+ (initialize_local_var): Call it.
+
+2007-09-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/33094
+ * decl.c (make_rtl_for_nonlocal_decl): It's ok for a member
+ constant to not have DECL_EXTERNAL if it's file-local.
+
+2007-09-28 Ollie Wild <aaw@google.com>
+
+ Revert
+ 2007-09-27 Ollie Wild <aaw@google.com>
+
+ * typeck2.c (digest_init): Call cplus_expand_constant after
+ convert_for_initialization.
+ * cp-objcp-common.h (LANG_HOOKS_EXPAND_CONSTANT): Removed.
+ * expr.c (cplus_expand_constant): Updated function description.
+
+2007-09-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/10179
+ * class.c (layout_empty_base): Take rli parameter, update
+ rli->record_align if empty base has user-specified alignment.
+ (build_base_field): Pass rli to it.
+
+2007-09-28 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33213
+ * error.c (dump_decl): Deal with TYPE_PACK_EXPANSION.
+
+2007-09-28 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33118
+ * error.c (dump_expr): Deal with ARGUMENT_PACK_SELECT.
+ (dump_type): Use dump_template_argument for TYPE_ARGUMENT_PACK.
+ (dump_parameters): Just call dump_type for argument packs too.
+
+2007-09-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/31434
+ * tree.c (cp_build_qualified_type_real): Handle TYPE_PACK_EXPANSION
+ qualification by creating qualified PACK_EXPANSION_PATTERN and
+ then calling make_pack_expansion on it.
+
+2007-09-27 Ollie Wild <aaw@google.com>
+
+ * typeck2.c (digest_init): Call cplus_expand_constant after
+ convert_for_initialization.
+ * cp-objcp-common.h (LANG_HOOKS_EXPAND_CONSTANT): Removed.
+ * expr.c (cplus_expand_constant): Updated function description.
+
+2007-09-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/33571
+ * decl2.c (is_late_template_attribute): Don't crash on unknown
+ attribute.
+
+2007-09-27 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33493
+ * error.c (dump_expr): Deal with DELETE_EXPR and VEC_DELETE_EXPR.
+ * cxx-pretty-print.c (pp_cxx_delete_expression): Add missing
+ spaces in the formatting.
+ * cxx-pretty-print.h (pp_cxx_delete_expression): Declare.
+
+2007-09-27 Jakub Jelinek <jakub@redhat.com>
+
+ * error.c (cxx_print_error_function): Add third argument, pass
+ it over to lhd_print_error_function.
+ (cp_print_error_function): If diagnostic->abstract_origin, print
+ virtual backtrace.
+ * cp-tree.h (struct diagnostic_info): New forward decl.
+ (cxx_print_error_function): Add third argument.
+
+2007-09-25 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/33207
+ * name-lookup.c (pushtag): Do not create an implicit typedef before
+ the associated type declaration is known to be valid.
+
+2007-09-25 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.c (cxx_printable_name): Compare FUNCTION_DECL uids
+ rather than pointers.
+
+2007-09-24 Danny Smith <dannysmith@user.sourceforge.net>
+
+ PR c++/14688
+ * search.c (check_final_overrider): Fail if
+ targetm.comp_type_attributes returns 0.
+
+2007-09-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/33239
+ * pt.c (resolve_typename_type): Don't look things up in the original
+ template if it would mean losing template arguments.
+
+2007-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33506
+ * cp-tree.h (cxx_type_hash_eq): New prototype.
+ * cp-objcp-common.h (LANG_HOOKS_TYPE_HASH_EQ): Redefine.
+ * tree.c (cxx_type_hash_eq): New function.
+
+2007-09-24 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33185
+ * tree.c (cp_build_qualified_type_real): Build a canonical
+ ARRAY_TYPE if the original ARRAY_TYPE was not a canonical type.
+
+2007-09-24 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33112
+ PR c++/33185
+ * tree.c (cplus_array_compare): Compare pointers, not types.
+ (build_cplus_array_type_1): Store new array type into the hash
+ table before building the canonical type; build the canonical type
+ correctly.
+ (cp_build_qualified_type_real): Put all of the array types with
+ cv-qualified element types into the C++ array hash table, built as
+ variants of the unqualified versions.
+
+2007-09-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/16370
+ * decl.c (grokdeclarator): Look through implicit TYPE_DECLs
+ for deprecation warnings.
+
+2007-09-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/15269
+ * call.c (build_over_call): Warn about deprecated virtuals.
+
+ PR c++/19407
+ * cp-tree.h (ATTR_IS_DEPENDENT): New macro.
+ (MAYBE_TAGGED_TYPE_P): Remove.
+ * pt.c (apply_late_template_attributes): Check ATTR_IS_DEPENDENT
+ instead of calling is_late_template_attribute again.
+ (tsubst_decl) [TYPE_DECL]: Just check if the name is the tag.
+ (tsubst): A typedef is a TYPE_NAME != TYPE_MAIN_DECL.
+ Don't crash on typedefs from non-template classes.
+ * decl2.c (grokfield): Don't sorry about attrs on template parms.
+ (is_late_template_attribute): All attributes applied to template
+ parms or typename types are dependent. Static.
+ (splice_template_attributes): Pass decl through.
+ (save_template_attributes): Likewise.
+
+2007-09-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33496
+ * pt.c (tsubst_copy) <case SIZEOF_EXPR>: Handle error_mark_node
+ returned from tsubst_pack_expansion.
+ (tsubst_copy_and_build) <case SIZEOF_EXPR>: Likewise.
+ (tsubst_copy_and_build) <case CONSTRUCTOR>: Likewise.
+
+2007-09-20 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33460
+ * semantics.c (finish_id_expression): Use consistently
+ context_for_name_lookup.
+ * decl.c (fixup_anonymous_aggr): Fix error message for
+ anonymous struct (vs union).
+
+2007-09-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/7586
+ * pt.c (tsubst): Handle typedefs by looking for the specialization.
+ (retrieve_specialization): Only tagged types use
+ DECL_TEMPLATE_INSTANTIATIONS.
+ (instantiate_class_template): Push nested classes too.
+ (tsubst_decl) [TYPE_DECL]: Only check for canonical decl for
+ tagged types.
+ * cp-tree.h (MAYBE_TAGGED_TYPE_P): New macro.
+ * init.c (is_aggr_type): Remove redundant tests.
+ * class.c (push_nested_class): Use CLASS_TYPE_P.
+
+2007-09-20 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33459
+ * init.c (build_zero_init): If, recursively, build_zero_init
+ returns a NULL_TREE, do not append it to the VEC of constructors.
+
+2007-09-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/17743
+ * pt.c (apply_late_template_attributes): Set processing_template_decl.
+ (tsubst_decl) [TYPE_DECL]: Preserve naming typedef, pass
+ ATTR_FLAG_TYPE_IN_PLACE.
+ (tsubst): Do unqualified lookup to find typedefs from current class.
+ [ARRAY_TYPE]: Propagate alignment info.
+ * decl2.c (is_late_template_attribute): Only defer handling of
+ attribute aligned if the expression is dependent.
+ (save_template_attributes): If we're deferring any attributes,
+ make this a naming typedef.
+
+2007-09-18 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33462 (again)
+ * cxx-pretty-print.c (pp_cxx_va_arg_expression): Print
+ va_arg instead of __builtin_va_arg.
+
+2007-09-18 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33462
+ * cxx-pretty-print.c (pp_cxx_va_arg_expression): Add.
+ (pp_cxx_primary_expression): Use it.
+ * cxx-pretty-print.h (pp_cxx_va_arg_expression): Declare.
+ * error.c (dump_expr): Use it.
+
+2007-09-18 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33463
+ * cxx-pretty-print.c (pp_cxx_postfix_expression): Split
+ out case TYPEID_EXPR to...
+ (pp_cxx_typeid_expression): ... here; use pp_cxx_left_paren
+ and pp_cxx_right_paren.
+ * cxx-pretty-print.h (pp_cxx_typeid_expression): Declare.
+ * error.c (dump_expr): Use it.
+
+2007-09-18 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33464
+ * cxx-pretty-print.c (pp_cxx_trait_expression): Add.
+ (pp_cxx_primary_expression): Use it.
+ * cxx-pretty-print.h (pp_cxx_trait_expression): Declare.
+ * error.c (dump_expr): Use it.
+
+2007-09-16 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33124
+ * init.c (build_new): Remove warning for zero-element
+ allocations.
+
+2007-09-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/32756
+ * call.c (maybe_handle_implicit_object): Set this_p, clear
+ rvaluedness_matches_p.
+ (compare_ics): Do not compare rvaluedness matching when one of the
+ operands is an implicit object.
+
+2007-09-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/17743, c++/19163
+ * decl2.c (is_late_template_attribute): New fn.
+ (splice_template_attributes, save_template_attributes): New fns.
+ (cplus_decl_attributes): Call save_template_attributes.
+ * pt.c (apply_late_template_attributes): New fn.
+ (instantiate_class_template, tsubst_decl): Use it.
+ * cp-tree.h: Declare is_late_template_attribute.
+
+2007-09-13 Tom Tromey <tromey@redhat.com>
+
+ * parser.c (cp_lexer_new_main): Don't use
+ c_lex_return_raw_strings.
+ (cp_lexer_get_preprocessor_token): Update. Add special case when
+ lexer is NULL.
+
+2007-09-11 Jan Hubicka <jh@suse.cz>
+
+ * method.c (use_thunk): Use tree_rest_of_compilation
+ * cp-objecp-common.h (LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION): Kill.
+ (LANG_HOOKS_CALLGRAPH_EMIT_ASSOCIATED_THUNKS): Define.
+ * cp-tree.h (expand_body): Kill.
+ (emit_associated_thunks): Declare.
+ * semantics.c (emit_associated_thunks): Export.
+ (expand_body): Kill.
+
+2007-09-09 David Daney <ddaney@avtrex.com>
+
+ PR c++/33324
+ * init.c (build_new_1): Use POINTER_PLUS_EXPR instead of MINUS_EXPR
+ to calculate cookie_ptr.
+
+2007-09-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/33342
+ * pt.c (most_specialized_class): Set processing_template_decl
+ while tsubsting partial spec args.
+
+2007-09-06 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (get_guard): Copy visibility from the guarded variable.
+
+2007-09-06 Jan Hubicka <jh@suse.cz>
+
+ * semantics.c (expand_body): Do not mark arguments of clones used.
+
+2007-09-06 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/32674
+ * decl.c (cp_finish_decl): When processing_template_decl,
+ deal correctly with init as TREE_LIST.
+
+2007-09-06 Tom Tromey <tromey@redhat.com>
+
+ * decl.c (finish_function): Put return's location on line zero of
+ file.
+
+2007-09-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/15745
+ * except.c (prepare_eh_type): Use type_decays_to.
+
+ PR c++/15097
+ * init.c (build_delete): Use build_headof to get the address of the
+ complete object if we aren't using the deleting destructor.
+ * rtti.c (build_headof): No longer static.
+ * cp-tree.h: Declare it.
+
+2007-09-06 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (duplicate_decls): Set TREE_NOTHROW on __builtin_XX
+ decl if a prototype for XX is provided with throw().
+
+ PR c++/33289
+ * decl.c (builtin_function_1): Set DECL_ANTICIPATED also
+ on __*_chk non-__builtin_* decls.
+
+2007-09-05 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/30302
+ * semantics.c (finish_id_expression): Use context_for_name_lookup
+ insted of DECL_CONTEXT, to see through anonymous structs and unions.
+ * class.c (finish_struct_anon): Deal correctly with anonymous
+ structs (vs unions, as GNU extension) in error messages.
+
+2007-09-05 Jan Hubicka <jh@suse.cz>
+
+ * sematics.c (expand_body): Remove unnecesary import_export_decl
+ call, DECL_EXTERNAL checks and current_function_decl saving.
+
+2007-09-05 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/29731 (again)
+ * parser.c (cp_parser_primary_expression): Return error_mark_node
+ when a statement-expression is found in a template-argument list.
+
+2007-09-04 Jason Merrill <jason@redhat.com>
+
+ * except.c (initialize_handler_parm): Use
+ fold_build_cleanup_point_expr.
+
+ PR c++/31419
+ * call.c (reference_binding): Don't look for user-defined conversions
+ to the same type.
+
+ PR c++/31411
+ * except.c (initialize_handler_parm): Put a CLEANUP_POINT_EXPR inside
+ the MUST_NOT_THROW_EXPR.
+
+2007-09-04 Richard Sandiford <richard@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Call determine_visibility before
+ make_rtl_for_nonlocal_decl.
+
+2007-09-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/14032
+ * pt.c (most_specialized_class): Substitute outer template
+ arguments into the arguments of a member template partial
+ specialization.
+ (strip_innermost_template_args): New fn.
+
+2007-09-03 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * Make-lang.in (g++spec.o): Remove SHLIB_MULTILIB.
+
+2007-09-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (name_as_c_string): Supply a TYPE for CONST_CAST.
+ * decl.c (cp_make_fname_decl): Likewise,
+ * parser.c (cp_parser_string_literal): Likewise,
+ * tree.c (pod_type_p, zero_init_p): Use CONST_CAST_TREE.
+ * typeck.c (cp_type_quals, cp_type_readonly, cp_has_mutable_p):
+ Likewise,
+
+2007-09-02 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33208
+ * typeck.c (build_unary_op): Fix error message for
+ Boolean expression as operand to operator--.
+
+2007-09-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * tree.c (pod_type_p, zero_init_p): Use strip_array_types.
+ * typeck.c (cp_type_quals, cp_type_readonly, cp_has_mutable_p):
+ Likewise.
+
+2007-08-31 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/32597
+ * init.c (build_default_init): Make extern.
+ * cp-tree.h (build_default_init): Declare here.
+ * pt.c (tsubst_expr): When the instantiation of the initializer of
+ a variable results in an empty list, default-initialize the
+ variable.
+ (tsubst_copy_and_build): When the instantiation of the initializer
+ in a new expression results in an empty initializer list,
+ default-initialize it.
+
+2007-08-31 Douglas Gregor <doug.gregor@gmail.com>
+
+ * mangle.c (write_type): Change mangling of rvalue reference from
+ `RR' to `O'.
+
+2007-08-31 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (duplicate_decls): Remove duplicated line.
+
+2007-08-31 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33210
+ * cxx-pretty-print.c (pp_cxx_unqualified_id): Deal with
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+
+2007-08-31 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/32113
+ * search.c (lookup_member): Check the name argument for
+ error_mark_node.
+
+2007-08-31 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33212
+ * parser.c (cp_parser_trait_expr): Check rerurn value of
+ cp_parser_type_id.
+
+2007-08-30 Ollie Wild <aaw@google.com>
+
+ * cvt.c (cp_convert_to_pointer): Remove force parameter. Call
+ convert_ptrmem for pointer to member conversions.
+ (convert_to_pointer_force): Update cp_convert_to_pointer call.
+ (ocp_convert): Update cp_convert_to_pointer call.
+ * typeck.c (convert_ptrmem): Add conditional for null pointers to
+ members.
+ (build_static_cast_1): Check can_convert for conversions in either
+ direction.
+ (get_delta_difference_1): New function.
+ (get_delta_difference): Refactor to call get_delta_difference_1.
+
+2007-08-30 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (start_preparsed_function): Set
+ DECL_DISREGARD_INLINE_LIMITS for GNU_INLINE_P functions.
+
+2007-08-28 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33209
+ * error.c (dump_expr): Deal with TEMPLATE_TYPE_PARM and
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+
+2007-08-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/32596
+ PR c++/32400
+ * pt.c (check_explicit_specialization): Set DECL_INTERFACE_KNOWN
+ and DECL_NOT_REALLY_EXTERN if tmpl_func is not public.
+
+2007-08-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/29000
+ * pt.c (build_non_dependent_expr, type_dependent_expression_p):
+ Look inside STMT_EXPR.
+ * semantics.c (stmt_expr_value_expr): New fn.
+ * cp-tree.h: Declare it.
+
+ PR c++/28558
+ * decl.c (groktypename): Ignore attributes applied to class type.
+
+2007-08-28 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (duplicate_decls): Merge DECL_DISREGARD_INLINE_LIMITS.
+
+2007-08-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_expr): Handle COMPLEX_CST.
+ * cxx-pretty-print.c (pp_cxx_primary_expression): Likewise.
+ (pp_cxx_expression): Likewise.
+
+2007-08-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * decl.c (GNU_INLINE_P): New.
+ (duplicate_decls): Handle gnu_inline. Merge attributes and
+ some flags in overriding definitions.
+ (redeclaration_error_message): Handle gnu_inline.
+ (start_preparsed_function): Likewise.
+
+2007-08-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (sufficient_parms_p): Constify.
+ * class.c (same_signature_p): Likewise.
+ * cp-gimplify.c (is_invisiref_parm,
+ cxx_omp_privatize_by_reference): Likewise.
+ * cp-objcp-common.c (has_c_linkage): Likewise.
+ * cp-tree.h (NON_THUNK_FUNCTION_CHECK, THUNK_FUNCTION_CHECK,
+ sufficient_parms_p, same_signature_p, copy_fn_p, move_fn_p,
+ grok_ctor_properties, nothrow_libfn_p, skip_artificial_parms_for,
+ num_artificial_parms_for, comp_template_parms,
+ template_parameter_pack_p, any_dependent_template_arguments_p,
+ any_type_dependent_arguments_p, any_value_dependent_elements_p,
+ repo_export_class_p, cxx_omp_privatize_by_reference, pod_type_p,
+ zero_init_p, member_p, cp_lvalue_kind,
+ builtin_valid_in_constant_expr_p, decl_anon_ns_mem_p,
+ varargs_function_p, is_dummy_object, special_function_kind,
+ string_conv_p, type_unknown_p, comp_except_specs, compparms,
+ comp_cv_qualification, is_bitfield_expr_with_lowered_type,
+ unlowered_expr_type, ptr_reasonably_similar, cp_type_readonly,
+ cp_has_mutable_p, at_least_as_qualified_p,
+ invalid_nonstatic_memfn_p, lvalue_or_else, lvalue_p): Likewise.
+ * decl.c (copy_fn_p, move_fn_p, grok_ctor_properties): Likewise.
+ * except.c (nothrow_libfn_p): Likewise.
+ * method.c (skip_artificial_parms_for, num_artificial_parms_for):
+ Likewise.
+ * pt.c (comp_template_parms, template_parameter_pack_p,
+ any_type_dependent_arguments_p, any_value_dependent_elements_p,
+ any_dependent_template_arguments_p): Likewise.
+ * repo.c (repo_export_class_p): Likewise.
+ * semantics.c (anon_aggr_type_p): Likewise.
+ * tree.c (lvalue_p_1, real_lvalue_p, lvalue_p,
+ builtin_valid_in_constant_expr_p, decl_anon_ns_mem_p,
+ varargs_function_p, member_p, is_dummy_object, pod_type_p,
+ zero_init_p, special_function_p): Likewise.
+ * typeck.c (comp_array_types, type_unknown_p, comp_except_specs,
+ comp_array_types, at_least_as_qualified_p, comp_cv_qualification,
+ compparms, invalid_nonstatic_memfn_p,
+ is_bitfield_expr_with_lowered_type, unlowered_expr_type,
+ string_conv_p, ptr_reasonably_similar, cp_type_readonly,
+ cp_has_mutable_p, lvalue_or_else): Likewise.
+
+2007-08-25 Paolo Bonzini <bonzini@gnu.org>
+
+ * decl.c (cp_tree_node_structure): Kill TINST_LEVEL case.
+ * cp-objcp-common.c (cp_tree_size): Ditto.
+ * tree.c (cp_walk_subtrees): Ditto
+ * cp-tree.def (TINST_LEVEL): Go away.
+ * cp-tree.h (struct tinst_level_s): Rename to struct tinst_level,
+ move together with other non-tree structs.
+ (enum cp_tree_node_structure_enum): Nuke TS_CP_TINST_LEVEL.
+ (union lang_tree_node): Eliminate tinst_level field.
+ (TINST_DECL, TINST_LOCATION, TINST_IN_SYSTEM_HEADER_P): Annihilate.
+ (current_instantiation, outermost_tinst_level): Return
+ a "struct tinst_level *".
+
+ * error.c (print_instantiation_partial_context): Change second
+ parameter to a "struct tinst_level *". Replace accessor macros
+ with field access.
+ (print_instantiation_full_context): Likewise.
+ * lex.c (in_main_input_context): Likewise.
+
+ * pt.c (struct pending_templates): New.
+ (pending_templates, last_pending_template): Use it as a type.
+ (current_tinst_level): Change typo to "struct tinst_level *"
+ (reopen_tinst_level): Accept "struct tinst_level *", return decl.
+ (add_pending_template): Construct a "struct pending_template".
+ Replace TINST_LEVEL accessor macros with field access.
+ (push_tinst_level): Likewise, using GGC_NEW instead of make_node.
+ (pop_tinst_level): Likewise.
+ (instantiate_pending_templates): Likewise. Factor common code used
+ when an instantiation has been done.
+ (outermost_tinst_level): Replace tree_last with loop.
+ (current_instantiation): Return a "struct tinst_level *".
+
+2007-08-24 Ollie Wild <aaw@google.com>
+
+ * name-lookup.c (add_decl_to_level): Remove addition to vtables chain.
+ * name-lookup.h (cp_binding_level): Remove vtables member.
+
+2007-08-24 Richard Guenther <rguenther@suse.de>
+
+ * tree.c (cp_cannot_inline_tree_fn): Remove.
+ * cp-tree.h (cp_cannot_inline_tree_fn): Likewise.
+ * cp-objcp-common.h (LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN):
+ Remove define.
+
+2007-08-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/32567
+ * typeck.c (build_unary_op) <case PREINCREMENT_EXPR>: Return
+ error_mark_node right away if build_expr_type_conversion
+ returned it.
+
+ PR c++/32898
+ * name-lookup.c (set_decl_namespace): lookup_qualified_name failure
+ is error_mark_node rather than NULL_TREE.
+ * pt.c (check_explicit_specialization): Likewise.
+
+ PR c++/31941
+ * error.c (resolve_virtual_fun_from_obj_type_ref): Handle
+ TARGET_VTABLE_USES_DESCRIPTORS targets properly.
+
+2007-08-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/29365
+ * pt.c (outermost_tinst_level): New function.
+ * lex.c (in_main_input_context): New function.
+ * cp-tree.h: Declare it.
+ * decl2.c (constrain_class_visibility): Use it to avoid warning
+ about uses of the anonymous namespace in the main input file.
+
+2007-08-21 Jakub Jelinek <jakub@redhat.com>
+
+ * init.c (build_new_1): Use get_target_expr instead of save_expr.
+
+2007-08-20 Pawel Sikora <pluto@pld-linux.org>
+
+ PR c++/7302
+ * class.c (finish_struct_1): Warn when a class has virtual
+ functions and accessible non-virtual destructor.
+
+2007-08-20 Richard Guenther <rguenther@suse.de>
+
+ PR c++/22369
+ PR c++/22451
+ * call.c (build_new_method_call): Convert initializer to
+ the basetype.
+ * init.c (build_aggr_init): Do not fiddle with types.
+ (build_vec_delete_1): Use correct type for POINTER_PLUS_EXPR.
+ * except.c (build_throw): Do not drop qualifiers for the
+ pointer type.
+ * typeck.c (get_member_function_from_ptrfunc): Do not
+ fiddle with types, instead convert.
+ (build_ptrmemfunc1): Convert to the target type for
+ initialization.
+ (gfc_trans_allocate): Convert result to target type.
+ * cp-objcp-common.c (cxx_get_alias_set): Pointers to
+ pointer-to-member structures shall have alias set zero as well.
+
+2007-08-20 Richard Guenther <rguenther@suse.de>
+
+ * cp-objcp-common.h (LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P):
+ Remove.
+ * cp-tree.h (cp_auto_var_in_fn_p): Remove.
+ (nonstatic_local_decl_p): Likewise.
+ * tree.c (cp_auto_var_in_fn_p): Remove.
+ * decl.c (nonstatic_local_decl_p): Remove.
+
+2007-08-20 Richard Guenther <rguenther@suse.de>
+
+ * cp-objcp-common.h (LANG_HOOKS_TREE_INLINING_WALK_SUBTREES):
+ Remove define.
+ * tree.h (cp_walk_tree): New define to walk_tree_1 with
+ cp_walk_subtrees lh parameter.
+ (cp_walk_tree_without_duplicates): New define to
+ walk_tree_without_duplicates_1 with cp_walk_subtrees lh parameter.
+ * tree.c (count_trees): Call
+ cp_walk_tree_without_duplicates.
+ (verify_stmt_tree): Call cp_walk_tree.
+ (break_out_target_exprs): Likewise.
+ (WALK_SUBTREE): Likewise.
+ * cp-gimplify.c (cp_genericize): Likewise.
+ * cp-pt.c (find_parameter_packs_r): Likewise.
+ (uses_parameter_packs): Likewise.
+ (make_pack_expansion): Likewise.
+ (check_for_bare_parameter_packs): Likewise.
+ (for_each_template_parm): Likewise.
+ * decl.c (check_default_argument): Call
+ cp_walk_tree_without_duplicates.
+ * except.c (build_throw): Likewise.
+ * decl2.c (type_visibility): Likewise.
+ * semantics.c (expand_or_defer_fn): Likewise.
+ (finalize_nrv): Call cp_walk_tree.
+
+2007-08-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33025
+ * init.c (build_new_1): Rename placement_var variable to placement_expr.
+ Initialize it with save_expr rather than get_temp_regvar.
+
+2007-08-17 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR c++/28989
+ * tree.c (lvalue_p_1 <case SAVE_EXPR>): SAVE_EXPRs are never
+ lvalues.
+
+2007-08-17 Ollie Wild <aaw@google.com>
+
+ PR c++/31749
+ * name-lookup.c (do_nonmember_using_decl): Shift implicit type
+ declarations into appropriate slots for comparison. Fix type
+ comparison.
+
+2007-08-17 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/32112
+ * error.c (dump_decl): Deal with UNBOUND_CLASS_TEMPLATE.
+ * cxx-pretty-print.c (pp_cxx_unqualified_id): Likewise.
+
+2007-08-17 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/32870
+ * parser.c (cp_parser_class_head): Improve error message.
+
+2007-08-16 Seongbae Park <seongbae.park@gmail.com>
+
+ * pt.c (instantiate_decl): Set input_location
+ for the function end.
+
+2007-08-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-objcp-common.c (cxx_warn_unused_global_decl, cp_expr_size):
+ Constify.
+ * cp-tree.h (local_variable_p, nonstatic_local_decl_p,
+ class_tmpl_impl_spec_p, cp_auto_var_in_fn_p, cp_type_quals,
+ cxx_incomplete_type_diagnostic, cxx_incomplete_type_error,
+ cxx_warn_unused_global_decl, cp_expr_size): Likewise.
+ * decl.c (local_variable_p, nonstatic_local_decl_p): Likewise.
+ * tree.c (class_tmpl_impl_spec_p, cp_auto_var_in_fn_p): Likewise.
+ * typeck.c (cp_type_quals): Likewise.
+ * typeck2.c (cxx_incomplete_type_diagnostic,
+ cxx_incomplete_type_error): Likewise.
+
+2007-08-16 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/31132
+ * pt.c (tsubst_friend_function): When check_classfn
+ returns error_mark_node likewise return it.
+
+2007-08-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/32992
+ * typeck.c (check_return_expr): Don't NRV optimize vars in
+ anonymous unions.
+ * decl.c (finish_function): Comment fix.
+
+2007-08-15 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/33035
+ * pt.c (push_template_decl_real): Depending on TYPE_P
+ use either TYPE_CONTEXT or DECL_CONTEXT.
+
+2007-08-14 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (finish_omp_clauses): Strip a NOP_EXPR if
+ constructors and destructors return this.
+
+2007-08-14 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/27211
+ * decl2.c (check_classfn): Return error_mark_node in case of error;
+ in that case, do not call add_method.
+ * decl.c (start_decl): Deal with check_classfn returning
+ error_mark_node.
+ (grokfndecl): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+
+2007-08-14 Andrew Pinski <pinskia@gmail.com>
+
+ PR c++/30428
+ * typeck.c (build_binary_op): Disallow vector float types with
+ BIT_IOR_EXPR, BIT_AND_EXPR, and BIT_XOR_EXPR.
+
+2007-08-11 Ian Lance Taylor <iant@google.com>
+
+ * cp-objcp-common.c (cxx_get_alias_set): Change return type to
+ alias_set_type.
+ * cp-tree.h (cxx_get_alias_set): Update declaration.
+
+2007-08-10 Ollie Wild <aaw@google.com>
+
+ * name-lookup.c (do_nonmember_using_decl): Print an error for ambiguous
+ type lookups.
+ (ambiguous_decl): Construct tree of ambiguous types. Remove extaneous
+ function parameter.
+ (unqualified_namespace_lookup): Fix ambiguous_decl call.
+ (lookup_using_namespace): Fix ambiguous_decl call.
+ (qualified_lookup_using_namespace): Fix ambiguous_decl call.
+
+2007-08-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (name_as_c_string): Use CONST_CAST.
+ * decl.c (build_decl): Likewise.
+ * parser.c (cp_parser_string_literal): Likewise.
+
+2007-08-10 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/17763
+ * error.c (dump_expr): Consistently use the *_cxx_*
+ variants of the pretty-print functions.
+
+2007-08-10 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/22256
+ * decl.c (check_special_function_return_type): Just error
+ on return type specified for conversion operator.
+
+2007-08-09 Daniel Berlin <dberlin@dberlin.org>
+
+ * typeck2.c (readonly_error): Handle general expressions.
+ * error.c (dump_expr): Handle POINTER_PLUS_EXPR
+
+2007-08-06 Dan Hipschman <dsh@google.com>
+
+ * method.c (use_thunk): Use DECL_NAME instead of DECL_RTL to
+ access function name.
+
+2007-08-04 Alfred Minarik <a.minarik@aon.at>
+
+ PR pch/13676
+ * lang-specs.h: Add .hp, .hxx, .hpp, .h, .HPP, .tcc as c++ header.
+ * g++spec.c (lang_specific_driver): Check them.
+
+2007-08-06 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/19532
+ * pt.c (inline_needs_template_parms): Fix comment; change return type
+ to bool.
+
+2007-08-05 Volker Reichelt <v.reichelt@netcologne.de>
+
+ Revert:
+ 2007-03-26 Dirk Mueller <dmueller@suse.de>
+
+ * parser.c (cp_parser_member_declaration): Pedwarn
+ about stray semicolons after member declarations.
+
+2007-08-02 Lee Millward <lee.millward@gmail.com>
+
+ PR c++/30849
+ PR c++/30850
+ PR c++/30851
+ * parser.c (cp_parser_asm_definition): Detect and discard asm
+ statements with invalid inputs or outputs.
+ (cp_parser_asm_operand_list): Return error mark node if any
+ of the operands are invalid. Adjust documentation.
+
+2007-08-02 Nick Clifton <nickc@redhat.com>
+
+ * typeck.c: Change copyright header to refer to version 3 of the
+ GNU General Public License and to point readers at the COPYING3
+ file and the FSF's license web page.
+ * optimize.c, lang-specs.h, init.c, class.c, repo.c, decl.c,
+ config-lang.in, cp-tree.def, call.c, decl.h, ptree.c,
+ Make-lang.in, method.c, rtti.c, cp-objcp-common.c, g++spec.c,
+ cp-objcp-common.h, except.c, error.c, operators.def, cvt.c,
+ tree.c, mangle.c, cp-tree.h, dump.c, search.c, friend.c, expr.c,
+ cp-gimplify.c, cxx-pretty-print.c, cp-lang.c, typeck2.c, pt.c,
+ cxx-pretty-print.h, semantics.c, name-lookup.c, lex.c, decl2.c,
+ name-lookup.h, parser.c: Likewise.
+
+2007-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ PR middle-end/32668
+ * call.c (magic_varargs_p): Honor the "type generic" attribute.
+
+2007-07-30 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/32108
+ * semantics.c (finish_label_stmt): Reject the __label__
+ extension outside function scopes.
+
+2007-07-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * parser.c (eof_token): Un-constify.
+ (cp_lexer_new_main, cp_lexer_new_from_tokens, VEC_alloc,
+ cp_lexer_consume_token, cp_lexer_purge_token): Remove spurious
+ casts.
+
+2007-07-28 Kazu Hirata <kazu@codesourcery.com>
+
+ * pt.c, tree.c, typeck2.c: Fix comment typos.
+
+2007-07-28 Simon Martin <simartin@users.sourceforge.net>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/30917
+ * name-lookup.c (lookup_name_real): Non namespace-scope bindings can be
+ hidden due to friend declarations in local classes.
+
+2007-07-27 Douglas Gregor <doug.gregor@gmail.com>
+
+ * typeck.c (structural_comptypes): Compare DECLTYPE_TYPE nodes.
+ * cp-tree.def (DECLTYPE_TYPE): New.
+ * error.c (dump_type): Dump DECLTYPE_TYPE nodes.
+ (dump_type_prefix): Ditto.
+ (dump_type_suffix): Ditto.
+ * tree.c (DECLTYPE_TYPE): Walk DECLTYPE_TYPE nodes.
+ * mangle.c (write_type): Handle DECLTYPE_TYPE.
+ * cp-tree.h (IS_AGGR_TYPE): DECLTYPE_TYPE nodes can be aggregate
+ types.
+ (DECLTYPE_TYPE_EXPR): New.
+ (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P): New.
+ (finish_declared_type): Declare.
+ * cxx-pretty-print.c (pp_cxx_type_specifier_seq): Print
+ DECLTYPE_TYPE nodes.
+ (pp_cxx_type_id): Ditto.
+ * pt.c (for_each_template_parm_r): Walk DECLTYPE_TYPE children.
+ (tsubst): Substitute into a DECLTYPE_TYPE node.
+ (tsubst_copy): Ditto.
+ (unify): Cannot deduce anything from TYPEOF_TYPE or DECLTYPE_TYPE
+ nodes.
+ (dependent_type_p_r): DECLTYPE_TYPE types are always dependent.
+ * semantics.c (finish_typeof): TYPEOF_TYPE types need to use
+ structural equality (because we can't hash the expressions).
+ (finish_declared_type): New.
+ * lex.c (reswords): Add "decltype" keyword.
+ * parser.c cp_lexer_next_token_is_decl_specifier_keyword
+ (cp_parser_postfix_expression): Add member_access_only_p to
+ restrict postfix expression to member access expressions.
+ (cp_parser_unary_expression): Update call to
+ cp_parser_postfix_expression to reflect new parameter.
+ (cp_parser_declared_type): New.
+ (cp_parser_simple_type_specifier): Parse decltype types.
+
+2007-07-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/32346
+ * call.c (convert_for_arg_passing): Only widen bitfields to their
+ declared types if necessary.
+
+2007-07-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * parser.c (cp_parser_string_literal, cp_parser_sizeof_operand):
+ Constify.
+
+2007-07-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (typename_hash, typename_compare): Constify.
+ * mangle.c (hash_type, compare_type): Likewise.
+ * pt.c (eq_local_specializations, hash_local_specialization):
+ Likewise.
+ * tree.c (cplus_array_hash, cplus_array_compare, list_hash_eq,
+ list_hash): Likewise.
+ * typeck2.c (pat_compare): Likewise.
+
+2007-07-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (implicitly_declare_fn): Increase alignment if member
+ function pointer format requires it.
+
+2007-07-24 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/29001
+ * typeck.c (check_return_expr): Do not pass a null argument
+ to null_ptr_cst_p.
+
+2007-07-24 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/32561
+ * decl.c (redeclaration_error_message): Call DECL_ANON_UNION_VAR_P
+ only on VAR_DECL.
+
+2007-07-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/32839
+ * typeck.c (convert_arguments): Only use default args if we have
+ a function decl.
+
+ PR c++/30818
+ * typeck.c (structural_comptypes): No need to check
+ resolve_typename_type return value here.
+ * cp-tree.h (TYPENAME_IS_RESOLVING_P): New.
+ * pt.c (resolve_typename_type): Follow typename typedefs. Return
+ original type rather than error_mark_node in case of failure.
+ * parser.c (cp_parser_nested_name_specifier_opt): Adjust
+ resolve_typename_type result check.
+ (cp_parser_direct_declarator, cp_parser_head,
+ cp_parser_constructor_declarator_p): Likewise.
+
+2007-07-12 Kazu Hirata <kazu@codesourcery.com>
+
+ * pt.c (template_parms_variadic_p): Remove.
+ * cp-tree.h: Remove the prototype for template_parms_variadic_p.
+
+2007-07-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/30854
+ * error.c (dump_expr) <case AGGR_INIT_EXPR>: Pass true as last
+ argument to dump_aggr_init_expr_args instead of false.
+
+2007-07-11 Douglas Gregor <doug.gregor@gmail.com>
+
+ * typeck.c (comptypes): When USE_CANONICAL_TYPES, use the
+ canonical types; otherwise, fall back to structural type
+ comparisons. If ENABLE_CHECKING and USE_CANONICAL_TYPES, give an
+ internal compiler error if the canonical types are wrong.
+
+2007-07-11 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/32560
+ * parser.c (cp_parser_make_indirect_declarator): When the
+ the code argument is ERROR_MARK return cp_error_declarator.
+
+2007-07-09 Geoffrey Keating <geoffk@apple.com>
+
+ PR 32617
+ * decl.c (cxx_init_decl_processing): Don't set
+ force_align_functions_log.
+ (grokfndecl): Honour ptrmemfunc_vbit_in_pfn.
+ * typeck.c (cxx_alignof_expr): When alignof is used on a plain
+ FUNCTION_DECL, return its alignment.
+
+2007-07-09 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (start_preparsed_function): Do not promote return type.
+
+2007-07-08 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/30535
+ * pt.c (unify): Never pass error_mark_node to template_decl_level.
+
+2007-07-07 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/32232
+ * pt.c (resolve_overloaded_unification): Robustify. Return a
+ bool, not an int.
+ (type_unification_real): Adjust accordingly.
+
+2007-07-06 Richard Guenther <rguenther@suse.de>
+
+ * init.c (build_new_1): Use the correct pointer type.
+ * typeck2.c (build_m_component_ref): Likewise.
+
+2007-07-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/32245
+ * init.c (build_zero_init): Always build an initializer for
+ non-static storage.
+ * typeck2.c (build_functional_cast): Use build_zero_init.
+
+ PR c++/32251
+ * init.c (build_new_1): Always pass the allocation function to
+ build_op_delete_call.
+ * call.c (build_op_delete_call): Handle operator delete with a
+ variable-argument list. Do not issue an error when no matching
+ deallocation function is available for a new operator.
+
+ PR c++/31992
+ * cp-tree.h (any_value_dependent_elements_p): Declare it.
+ * decl.c (value_dependent_init_p): New function.
+ (cp_finish_decl): Use it.
+ * pt.c (value_dependent_expression_p): Use
+ any_value_dependent_elements_p.
+ * parser.c (cp_parser_primary_expression): Add comment about
+ treating dependent qualified names as integral
+ constant-expressions.
+
+2007-07-04 Douglas Gregor <doug.gregor@gmail.com>
+
+ * decl.c (build_ptrmemfunc_type): Always use structural equality
+ tests when comparing pointer-to-member-function types, because the
+ handling of TYPE_GET_PTRMEMFUNC_TYPE currently defeats canonical
+ types.
+
+2007-07-03 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (build_new): Tweak comment.
+
+2007-06-29 Dave Brolley <brolley@redhat.com>
+
+ PR c++/31743
+ * parser.c (cp_parser_new_type_id): Don't reduce a named array
+ type to its base type and number of elements here.
+ * init.c (build_new): Call complete_type_or_else to ensure that the
+ type is complete and to issue a diagnostic if it is not.
+ (build_new_1): Don't call complete_type_or_else here.
+
+2007-07-03 Richard Guenther <rguenther@suse.de>
+
+ PR c++/32609
+ * class.c (fixed_type_or_null): Re-lookup the hashtable slot
+ after recursing.
+
+2007-07-02 Simon Baldwin <simonb@google.com>
+
+ * parser.c (cp_parser_elaborated_type_specifier): Added a warning
+ for inner-style nested forward declarations that don't declare
+ anything useful.
+
+2007-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/31748
+ * semantics.c (finish_omp_clauses): Use %qD instead of %qE for
+ DECL_P in not a variable and appears more than once error messages.
+
+2007-07-01 Ollie Wild <aaw@google.com>
+
+ * name-lookup.c (ambiguous_decl): Fix case when new->value is hidden.
+ (select_decl): Remove function.
+ (unqualified_namespace_lookup): Populate binding by calling
+ ambiguous_decl. Remove select_decl call.
+ (lookup_qualified_name): Remove select_decl call.
+ * decl.c (lookup_and_check_tag): Check for ambiguous references.
+ * parser.c (cp_parser_elaborated_type_specifier): Skip redundant error
+ generation when name lookup is ambiguous.
+
+2007-06-29 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/31724
+ * init.c (build_new_1): Use structural equality on the copy of the
+ array type.
+
+2007-06-28 Geoffrey Keating <geoffk@apple.com>
+
+ * decl2.c (determine_visibility): Implement
+ flag_visibility_ms_compat effect on type info.
+ * decl.c (cxx_init_decl_processing): Implement
+ global effect of flag_visibility_ms_compat.
+
+2007-06-28 Geoffrey Keating <geoffk@apple.com>
+
+ * decl2.c (start_objects): Mark constructor-running function
+ as artificial.
+
+2007-06-26 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/32111
+ * decl.c (grokdeclarator): Reset friendp for member functions declared
+ friend of their own class.
+
+2007-06-23 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (determine_visibility): Don't look for dllexport here.
+ (determine_visibility_from_class): Tidy.
+
+2007-06-18 Simon Baldwin <simonb@google.com>
+
+ PR c++/31923
+ * parser.c (cp_parser_single_declaration): Added check for storage
+ class other than sc_none in parsed declaration, and a flag to indicate
+ if the call is part of an explicit template specialization parse.
+ * (cp_parser_explicit_specialization): Specialization check flag added
+ to call to cp_parser_single_declaration(), set true.
+ * (cp_parser_template_declaration_after_export): Specialization check
+ flag added to call to cp_parser_single_declaration(), set false.
+ * pt.c (check_explicit_specialization): Added code to copy visiblity
+ and linkage from the templated function to the explicit specialization.
+
+2007-06-15 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * typeck.c (build_binary_op): For templates build the
+ expression in pieces to avoid the assert in build2_stat.
+ (get_member_function_from_ptrfunc):
+ Change over to using POINTER_PLUS_EXPR and convert
+ the second operand to sizetype.
+ * typeck2.c (build_m_component_ref): Likewise.
+ * init.c (expand_virtual_init): Create a POINTER_PLUS_EXPR
+ instead of PLUS_EXPR for pointers.
+ (build_new_1): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_vec_delete): Likewise.
+ * class.c (build_base_path): Likewise.
+ (build_base_path): Likewise.
+ (convert_to_base_statically): Likewise.
+ (fixed_type_or_null): Handle POINTER_PLUS_EXPR.
+ (get_vtbl_decl_for_binfo): Handle POINTER_PLUS_EXPR
+ instead of PLUS_EXPR.
+ (dfs_accumulate_vtbl_inits): Create a POINTER_PLUS_EXPR
+ instead of PLUS_EXPR for pointers.
+ * call.c (build_special_member_call): Likewise.
+ * rtti.c (build_headof): Likewise.
+ Use sizetype instead of ptrdiff_type_node.
+ (tinfo_base_init): Create a POINTER_PLUS_EXPR
+ instead of PLUS_EXPR for pointers.
+ * except.c (expand_start_catch_block): Do a
+ NEGATIVE and then a POINTER_PLUS_EXPR instead
+ of a MINUS_EXPR.
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Convert
+ PLUS_EXPR on pointer types over to use
+ POINTER_PLUS_EXPR and remove the conversion
+ to the pointer types.
+ * method.c (thunk_adjust): Use POINTER_PLUS_EXPR for
+ adding to a pointer type. Use size_int instead of
+ ssize_int. Convert the index to sizetype before
+ adding it to the pointer.
+
+2007-06-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_VAR_MARKED_P): Remove.
+ (DECL_ANON_UNION_VAR_P): New macro.
+ * class.c (fixed_type_or_null): Tidy. Use a hash table, rather
+ than DECL_VAR_MARKED_P, to keep track of which variables we have
+ seen.
+ * decl.c (redeclaration_error_message): Complain about redeclaring
+ anonymous union members at namespace scope.
+ * decl2.c (build_anon_union_vars): Set DECL_ANON_UNION_VAR_P.
+
+2007-06-14 Geoff Keating <geoffk@apple.com>
+
+ * decl2.c (determine_visibility): Ensure that functions with
+ hidden types as parameters are hidden.
+
+ PR 31093
+ * decl2.c (determine_visibility): Remove duplicate code for
+ handling type info.
+
+2007-06-12 Ian Lance Taylor <iant@google.com>
+
+ PR libstdc++/29286
+ * init.c (avoid_placement_new_aliasing): New static function.
+ (build_new_1): Call it.
+
+2007-06-11 Rafael Ávila de Espíndola <espindola@google.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_SIGNED_TYPE): Remove.
+ (LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE): Remove.
+
+2007-06-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/32177
+ * semantics.c (finish_omp_for): Call fold_build_cleanup_point_expr
+ on init, the non-decl cond operand and increment value.
+
+2007-06-07 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/30759
+ * decl.c (check_initializer): Report an error when a brace enclosed
+ initializer is used for a non-aggregate type in C++98.
+ (redeclaration_error_message): Rewrote flag_cpp0x in terms of
+ cxx_dialect.
+ (grokdeclarator): Likewise.
+ (move_fn_p): Likewise.
+ * typeck.c (check_return_expr): Likewise.
+ * call.c (reference_binding): Likewise.
+ * error.c (cp_cpp_error): Likewise.
+ * pt.c (check_default_tmpl_args): Likewise.
+ (tsubst): Likewise.
+ * lex.c (init_reswords): Likewise.
+ * parser.c (p_parser_primary_expression): Likewise.
+ (TOKEN_PRECEDENCE): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_ptr_operator): Likewise.
+ (cp_parser_parameter_declaration): Likewise.
+ (cp_parser_enclosed_template_argument_list): Likewise.
+ (cp_parser_skip_to_end_of_template_parameter_list): Likewise.
+ (cp_parser_next_token_ends_template_argument_p): Likewise.
+
+2007-06-04 Simon Baldwin <simonb@google.com>
+
+ * decl.c (grokdeclarator): Readability change. Moved case labels
+ into direct switch statement scope.
+
+2007-06-04 Paolo Carlini <pcarlini@suse.de>
+
+ * call.c (convert_like_real): Remove pointless code.
+
+2007-05-31 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (get_atexit_fn_ptr_type): New function.
+ (get_atexit_node): Use it.
+ (start_cleanup_fn): Likewise.
+ (register_dtor_fn): Use the object's destructor, instead of a
+ separate cleanup function, where possible.
+ * cp-tree.h (CPTI_ATEXIT_FN_PTR_TYPE): New enumerator.
+ (atexit_fn_ptr_type_node): New macro.
+ * decl2.c (build_cleanup): Use build_address.
+
+2007-05-31 Daniel Berlin <dberlin@dberlin.org>
+
+ * typeck.c (build_binary_op): Include types in error.
+
+2007-05-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/31806
+ * decl.c (cp_finish_decl): Also clear was_readonly if a static var
+ needs runtime initialization.
+
+2007-05-31 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/32158
+ * semantics.c (finish_trait_expr): Complete the types.
+
+2007-05-30 Russell Yanofsky <russ@yanofsky.org>
+ Douglas Gregor <doug.gregor@gmail.com>
+ Pedro Lamarao <pedro.lamarao@mndfck.org>
+ Howard Hinnant <howard.hinnant@gmail.com>
+
+ PR c++/7412
+ PR c++/29939
+ * typeck.c (comptypes): Don't consider rvalue and lvalue
+ reference types to be equivalent.
+ (check_return_expr): Move from certain lvalues when returning
+ them.
+ * decl.c (grokdeclarator): Implement reference collapsing.
+ (copy_fn_p): Don't consider constructors taking rvalue references
+ to be copy constructors.
+ (move_fn_p): New.
+ * call.c (conversion): New "rvaluedness_matches_p" member.
+ (convert_class_to_reference): Require reference type as first
+ parameter instead of base type.
+ (reference_binding): Add logic to handle rvalue references.
+ (implicit_conversion): Update inaccurate comment.
+ (convert_like_real): Disable creation of temporaries that are
+ impossible to initialize for types with move constructors.
+ (build_over_call): Elide move constructors when possible.
+ (maybe_handle_implicit_object): Set "rvaluedness_matches_p".
+ (maybe_handle_ref_bind): Return conversion instead of type node.
+ (compare_ics): Add logic to use "rvaluedness_matches_p" values to
+ determine preferred conversion sequences.
+ * cp-tree.h (TYPE_REF_IS_RVALUE): New.
+ (LOOKUP_PREFER_RVALUE): New.
+ (DECL_MOVE_CONSTRUCTOR_P): New.
+ (struct cp_declarator): Add "reference" member for reference
+ types, with new "rvalue_ref" flag.
+ (cp_build_reference_type): Declare.
+ (move_fn_p): Declare.
+ * error.c (dump_type_prefix): Format rvalue reference types
+ correctly in error messages.
+ * except.c (build_throw): Move from certain lvalues when
+ throwing.
+ * mangle.c (write_type): Mangle rvalue references differently
+ than regular references.
+ * parser.c (make_reference_declarator): Add boolean parameter for
+ rvalue references.
+ (cp_parser_make_indirect_declarator): New.
+ (cp_parser_new_declarator_opt): Call
+ cp_parser_make_indirect_declarator.
+ (cp_parser_conversion_declarator_opt): Ditto.
+ (cp_parser_declarator): Ditto.
+ (cp_parser_ptr_operator): Parse "&&" tokens into rvalue reference
+ declarators.
+ * pt.c (tsubst): Implement reference collapsing.
+ (maybe_adjust_types_for_deduction): Implement special template
+ parameter deduction rule for rvalue references.
+ (type_unification_real): Update calls to
+ maybe_adjust_types_for_deduction.
+ (try_one_overload): Ditto.
+ (unify_pack_expansion): Ditto.
+ * tree.c (lvalue_p_1): Handle rvalue reference types.
+ (cp_build_reference_type): New.
+
+2007-05-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/31809
+ * decl.c (cp_finish_decl): Clear TREE_READONLY flag on TREE_STATIC
+ variables that need runtime initialization.
+
+2007-05-28 Andrew Pinski <Andrew_pinski@playstation.sony.com>
+
+ PR c++/31339
+ * typeck.c (build_unary_op <case PREINCREMENT_EXPR,
+ case POSTINCREMENT_EXPR, case PREDECREMENT_EXPR,
+ case POSTDECREMENT_EXPR>): Return the error_mark_node
+ if either the real or imaginary parts would an
+ error_mark_node.
+
+2007-05-25 Simon Martin <simartin@users.sourceforge.net>
+ Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/31745
+ * parser.c (cp_parser_skip_to_closing_brace): Return true if the next
+ token is a closing brace, false if there are no tokens left.
+ (cp_parser_namespace_alias_definition): Only consume the next token if
+ it is a closing brace.
+
+ * parser.c (cp_parser_class_specifier): Likewise.
+
+2007-05-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * semantics.c (finish_member_declaration): Fix a typo in the
+ last checkin.
+
+2007-05-25 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/31431
+ PR c++/31432
+ PR c++/31434
+ PR c++/31435
+ PR c++/31437
+ PR c++/31438
+ PR c++/31442
+ PR c++/31443
+ PR c++/31444
+ PR c++/31445
+ * error.c (dump_type): Dump TYPE_ARGUMENT_PACK nodes.
+ * cp-tree.h (check_for_bare_parameter_packs): Returns bool.
+ * pt.c (check_for_bare_parameter_packs): Return bool indicated
+ whether everything was okay. Fix indentation.
+ (push_template_decl_real): Check for bare parameter packs in
+ function parameters; where errors occur, mark the parameter types
+ with ERROR_MARK_NODEs to avert ICEs.
+ (coerce_template_parameter_pack): New.
+ (coerce_template_parms): Moved parameter pack coercion into
+ coerce_template_parameter_pack, and permit it anywhere in the
+ template parameter list (not just at the end). Parameter and
+ argument indices can vary (somewhat) separately now, so add
+ PARM_IDX and ARG_IDX.
+ (fn_type_unification): Don't set an argument pack as incomplete if
+ no argument pack was deduced.
+ (type_unification_real): If a type parameter is a parameter pack
+ and has not otherwise been deduced, it will be deduced to an empty
+ parameter pack.
+ (more_specialized_fn): Use the actual lengths of the argument
+ lists when comparing against expansions.
+ * semantics.c (finish_member_declaration): If a field's type has
+ bare parameter packs, error and set its type to ERROR_MARK_NODE.
+
+2007-05-24 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR target/27067
+ * mangle.c (mangle_decl): Call targetm.mangle_decl_assembler_name.
+
+2007-05-22 Ollie Wild <aaw@google.com>
+
+ * name-lookup.c (ambiguous_decl): Adds check for hidden types.
+ (unqualified_namespace_lookup): Adds check for hidden types.
+
+2007-05-22 Ollie Wild <aaw@google.com>
+
+ * decl.c (duplicate_decls): Verify namespace names are unique.
+
+2007-05-21 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cxx_maybe_build_cleanup): Handle
+ __attribute__((cleanup)).
+
+2007-05-19 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * cvt.c (cp_convert_and_check): Don't check warnings if the
+ conversion failed.
+
+2007-05-18 Geoffrey Keating <geoffk@apple.com>
+
+ * mangle.c (write_real_cst): Use 'unsigned long' for %lx.
+
+2007-05-14 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/29928
+ * rtti.c (get_tinfo_decl_dynamic, get_typeid): Try to complete the
+ type only if is a class type (5.2.8/4).
+
+2007-05-14 Rafael Ávila de Espíndola <espindola@google.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_UNSIGNED_TYPE): Remove.
+ * decl.c (grokdeclarator): Use unsigned_type_for instead of
+ c_common_unsigned_type.
+
+2007-05-11 Silvius Rus <rus@google.com>
+
+ * typeck.c (build_indirect_ref): Add call to
+ strict_aliasing_warning.
+ (build_reinterpret_cast_1): Condition call to
+ strict_aliasing_warning.
+
+2007-05-11 Jan Hubicka <jh@suse.cz>
+
+ * semantics.c (expand_or_defer_fn): Do not call c_record_cdtor_fn.
+ * decl2.c (start_objects): ctors and dtors are no longer public.
+ (cp_write_global_declarations): Do not call c_build_cdtor_fns.
+
+2007-05-07 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * typeck.c (build_unary_op): Remove code that used to
+ handle non lvalue increments/decrements.
+
+2007-05-07 Mike Stump <mrs@apple.com>
+
+ * parser.c (check_empty_body): Add.
+ (cp_parser_iteration_statement): Add call to check_empty_body.
+
+2007-05-05 Geoffrey Keating <geoffk@apple.com>
+
+ PR 31775
+ * mangle.c (write_mangled_name): Mangle static variable names.
+ (write_unqualified_name): Use local-source-name for
+ namespace-scope static variables.
+
+2007-05-04 Dirk Mueller <dmueller@suse.de>
+
+ * cp-tree.h (DECL_MAIN_P): only if -ffreestanding is
+ not in effect.
+
+2007-05-02 Seongbae Park <seongbae.park@gmail.com>
+
+ PR c++/31663
+ * decl2.c (constrain_class_visibility):
+ Use strip_pointer_or_array_types instead of strip_array_types.
+
+2007-04-28 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR C++/30221
+ * decl.c (reshape_init_r): Don't reshape the first element if it
+ is a pointer to member function.
+
+2007-04-27 Simon Baldwin <simonb@google.com>
+
+ * decl.c (grokparms): Changed message format from %qD to %qE.
+
+2007-04-27 Douglas Gregor <doug.gregor@gmail.com>
+
+ * error.c (maybe_warn_variadic_templates): Variadic templates are
+ now in C++0x, so only warn about them in C++98 mode.
+
+2007-04-26 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR C++/30016
+ * typeck.c (build_reinterpret_cast_1): Only allow conversion to
+ integeral types from vectors types.
+
+2007-04-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/31598
+ * semantics.c (finish_omp_clauses): Don't create CP_OMP_CLAUSE_INFO
+ for type dependent OMP_CLAUSE_DECLs.
+
+2007-04-24 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/31338
+ * cp-tree.h (ARITHMETIC_TYPE): Include COMPLEX_TYPE.
+ * typeck.c (type_after_usual_arithmetic_conversions): Adjust, as
+ COMPLEX_TYPE is now an ARITHMETIC_TYPE.
+ * init.c (build_zero_init): Adjust, as
+ COMPLEX_TYPE is now a SCALAR_TYPE.
+ * typeck2.c (digest_init): Allow brace-enclosed initializers for
+ COMPLEX_TYPE, even though that is now a SCALAR_TYPE.
+
+2007-04-25 Paolo Carlini <pcarlini@suse.de>
+
+ * semantics.c (classtype_has_nothrow_copy_or_assign_p): Adjust
+ per N2255; rename as classtype_has_nothrow_assign_or_copy_p.
+ (trait_expr_value): Adjust.
+
+2007-04-23 Simon Baldwin <simonb@google.com>
+
+ * decl.c (grokparms): Added new error for duplicate function
+ parameters names in function prototypes, to match gcc behavior.
+
+2007-04-23 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (finish_objects): Do not call target constructor/destructor
+ bits dirrectly.
+
+2007-04-21 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * cp-tree.h (lang_tree_node): Use GENERIC_NEXT
+ instead of checking GIMPLE_STMT_P in chain_next.
+
+2007-04-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/31513
+ * call.c (convert_for_arg_passing): Convert bitfields to their
+ declared types.
+
+2007-04-17 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/31517
+ * pt.c (value_dependent_expression_p): Handle MODOP_EXPRs.
+
+2007-04-16 Seongbae Park <seongbae.park@gmail.com>
+
+ PR c++/29365
+ * decl2.c (constrain_class_visibility):
+ Do not warn about the use of anonymous namespace in the main input file.
+
+2007-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (current_template_parms): Fix typo in comment.
+
+2007-04-15 Kazu Hirata <kazu@codesourcery.com>
+
+ * cp-tree.h, error.c: Fix comment typos.
+
+2007-04-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/31074
+ * call.c (reference_binding): Add c_cast_p parm. If true,
+ add quals to TO as needed to make it reference-compatible.
+
+2007-04-11 Jan Hubicka <jh@suse.cz>
+
+ * class.c (convert_to_base_statically): Fold produced tree; verify
+ that we are not processing template_decl.
+
+2007-04-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/31449
+ * class.c (build_base_path): Ensure that the converted pointer has
+ the same cv-qualification as the input.
+
+2007-04-09 Paolo Carlini <pcarlini@suse.de>
+
+ * tree.c (cp_tree_equal): Deal with TRAIT_EXPR.
+
+2007-04-08 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cp-objcp-common.h (LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS):
+ Do not set it.
+ (LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P): Do not set it.
+ * tree.c (cp_add_pending_fn_decls): Remove.
+ * cp-tree.h (cp_add_pending_fn_decls): Remove prototype.
+
+2007-04-07 Daniel Berlin <dberlin@dberlin.org>
+
+ Revert change removing staticp.
+
+2007-04-06 Daniel Berlin <dberlin@dberlin.org>
+
+ * cp-objcp-common.c (cxx_staticp): Remove.
+ * cp-objcp-common.h (LANG_HOOKS_STATICP): Remove.
+ * cp-tree.h (cxx_staticp):
+
+2007-04-04 Danny Smith <dannysmith.users.sourceforge.net>
+
+ * class.c (check_for_override): Don't remove dllmport attribute
+ of virtual methods.
+
+2007-04-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/30847
+ * typeck.c (build_modify_expr): For COND_EXPR on LHS, if RHS has void
+ type issue error and return early.
+
+2007-03-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/31187
+ * typeck.c (cp_type_readonly): New fn.
+ * cp-tree.h: Declare it.
+ * decl.c (start_decl): Set implicit DECL_THIS_STATIC here.
+ (cp_finish_decl): Not here.
+
+2007-03-31 Richard Guenther <rguenther@suse.de>
+
+ * optimize.c (maybe_clone_body): Replace splay-tree usage by
+ pointer-map.
+
+2007-03-31 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/31138
+ PR c++/31140
+ PR c++/31141
+ * parser.c (declarator_can_be_parameter_pack): New.
+ (cp_parser_template_parameter): Only parse the `...' if the
+ declarator can be a parameter pack.
+ (cp_parser_parameter_declaration): Ditto. Also, handle when TYPE
+ is NULL.
+ * pt.c (find_parameter_packs_r): Look into the bounds on integer
+ types (they could be used as array bounds).
+ (check_for_bare_parameter_packs): Deal with TEMPLATE_PARM_INDEX.
+ (tsubst_pack_expansion): Handle failure to expand parameter
+ packs.
+
+2007-03-30 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/26099
+ * cp-tree.h (enum cp_trait_kind, struct tree_trait_expr,
+ TRAIT_EXPR_TYPE1, TRAIT_EXPR_TYPE2, TRAIT_EXPR_KIND): Add.
+ (enum cp_tree_node_structure_enum, union lang_tree_node): Update.
+ (CLASS_TYPE_NON_UNION_P): Add.
+ (struct lang_type_class): Add has_complex_dflt.
+ (TYPE_HAS_COMPLEX_DFLT, TYPE_HAS_TRIVIAL_DFLT): Add.
+ (locate_copy, locate_ctor, locate_dtor, finish_trait_expr): Declare.
+ * cp-tree.def: Add TRAIT_EXPR.
+ * cp-objcp-common.c (cp_tree_size): Add TRAIT_EXPR case.
+ * lex.c (struct resword): Add __has_nothrow_assign,
+ __has_nothrow_constructor, __has_nothrow_copy, __has_trivial_assign,
+ __has_trivial_constructor, __has_trivial_copy,
+ __has_trivial_destructor, __has_virtual_destructor, __is_abstract,
+ __is_base_of, __is_class, __is_convertible_to, __is_empty, __is_enum,
+ __is_pod, __is_polymorphic, __is_union.
+ * parser.c (cp_parser_primary_expression): Deal with the new RIDs.
+ (cp_parser_trait_expr): New.
+ * semantics.c (finish_trait_expr, trait_expr_value
+ classtype_has_nothrow_copy_or_assign_p): New.
+ * method.c (locate_copy, locate_ctor, locate_dtor): Do not define
+ as static.
+ * decl.c (cp_tree_node_structure): Add TRAIT_EXPR.
+ * class.c (check_bases, check_field_decl, check_bases_and_members):
+ Deal with TYPE_HAS_COMPLEX_DFLT (t) too.
+ * pt.c (uses_template_parms, tsubst_copy_and_build,
+ value_dependent_expression_p, type_dependent_expression_p): Deal with
+ TRAIT_EXPR.
+ * tree.c (cp_walk_subtrees): Deal with TRAIT_EXPR.
+
+2007-03-29 Richard Guenther <rguenther@suse.de>
+
+ * tree.c (cp_walk_subtrees): Do not set input_location.
+
+2007-03-28 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/29077
+ * decl.c (grokfndecl): Properly setup decl if it is a constructor or a
+ destructor.
+
+2007-03-28 Douglas Gregor <doug.gregor@gmail.com>
+
+ * parser.c (struct cp_parser): Update comment for
+ greater_than_is_operator_p.
+ (cp_parser_primary_expression): In C++0x mode, a cast operator can
+ be terminated with a `>>' token when !GREATER_THAN_IS_OPERATOR_P.
+ (TOKEN_PRECEDENCE): In C++0x mode, `>>' is treated like `>' when
+ !GREATER_THAN_IS_OPERATOR_P.
+ (cp_parser_binary_expression): When -Wc++0x-compat, warn about
+ `>>' operators that will become two `>' tokens in C++0x.
+ (cp_parser_parameter_declaration): Treat `>>' like `>' in C++0x
+ mode, allowing it to terminate default arguments.
+ (cp_parser_enclosed_template_argument_list): In C++0x mode, treat
+ `>>' like two consecutive `>' tokens.
+ (cp_parser_skip_to_end_of_template_parameter_list): Ditto.
+ (cp_parser_next_token_ends_template_argument_p): In C++0x, `>>'
+ ends a template argument.
+
+2007-03-28 Douglas Gregor <doug.gregor@gmail.com>
+
+ * decl.c (redeclaration_error_message): Complain when redeclaring
+ a friend function with default template arguments (C++0x mode only).
+ * cp-tree.h (check_default_tmpl_args): Declare.
+ * pt.c (check_default_tmpl_args): In C++0x mode, permit default
+ template arguments in function templates. Add support for checking
+ the default template arguments of friend templates.
+ (push_template_decl_real): Fix call to check_default_tmpl_args.
+ (type_unification_real): If a template parameter has not been
+ deduced but provides a default template argument, substitute into
+ that default template argument.
+ * parser.c (cp_parser_init_declarator): When declaring (but not
+ defining!) a function template in C++0x mode, check for default
+ template arguments.
+
+2007-03-28 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/29993
+ * decl.c (grokdeclarator): Deal with cv-qualified function type
+ typedefs in the same way for member and non-member functions.
+
+2007-03-26 Dirk Mueller <dmueller@suse.de>
+
+ * parser.c (cp_parser_member_declaration): Pedwarn
+ about stray semicolons after member declarations.
+
+2007-03-26 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/30500
+ * pt.c (instantiate_decl): Set in_system_header.
+
+2007-03-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (current_tempalte_parms): Improve documentation.
+ * pt.c (current_template_args): Likewise.
+
+ PR c++/30863
+ * parser.c (cp_parser_parse_and_diagnose_invalid_type_name): Do
+ not consume tokens when failing.
+
+2007-03-22 Jim Wilson <wilson@specifix.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/31273
+ * call.c (standard_conversion): Use type_decays_to. Keep FCODE
+ consistent with FROM.
+
+2007-03-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_expr): Handle dependent names that designate types.
+ * cxx-pretty-print.c (pp_cxx_unqualified_id): Handle TYPENAME_TYPE.
+
+2007-03-17 Kazu Hirata <kazu@codesourcery.com>
+
+ * cp-tree.def, parser.c, pt.c: Fix comment typos.
+
+2007-03-16 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * cvt.c (cp_convert_and_check) : Define.
+ * cp-tree.h (cp_convert_and_check): Declare.
+ * call.c (convert_conversion_warnings): Rename to
+ conversion_null_warnings. The warning for floating-point to
+ integer is handled by convert_and_check in convert_like_real.
+ (convert_like_real): convert_conversion_warnings was renamed as
+ conversion_null_warnings.
+ * typeck.c (build_binary_op): Use cp_convert_and_check to warn for
+ overflow and changes of value during conversion.
+
+2007-03-15 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/30891
+ * parser.c (cp_parser_statement): If 'namespace' is found, this
+ only can be a namespace alias definition, so parse it now.
+ (cp_parser_namespace_alias_definition): if we find an open brace
+ instead of '=', then this is actually a misplaced namespace
+ definition.
+
+2007-03-15 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/24924
+ * decl.c (cxx_init_decl_processing): Move command-line options
+ processing to c-opts.c.
+
+2007-03-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ * ptree.c (cxx_print_type): Use formatting markup for integers
+ when printing template parameter index/level/orig level.
+ (cxx_print_xnode): Ditto.
+ * cp-tree.h (TEMPLATE_PARM_PARAMETER_PACK): Use TREE_LANG_FLAG_0.
+ (struct template_parm_index_s): Remove the PARAMETER_PACK member.
+ Make INDEX, LEVEL, and ORIG_LEVEL integers instead of
+ HOST_WIDE_INTs.
+ (struct saved_scope): Make X_PROCESSING_TEMPLATE_DECL an int,
+ rather than a HOST_WIDE_INT.
+ Turn X_PROCESSING_EXPLICIT_INSTANTIATION, SKIP_EVALUATION, and
+ NEED_POP_FUNCTION_CONTEXT into bool bitfields; reorder fields for
+ better bit-packing.
+ (struct language_function): Make RETURNS_VALUE, RETURNS_NULL,
+ RETURNS_ABNORMALLY, IN_FUNCTION_TRY_HANDLER, and
+ IN_BASE_INITIALIZER bool bitfields.
+ (struct cp_declarator): Make KIND a 4-bit field. Make
+ PARAMETER_PACK_P a bool bitfield just after KIND.
+ * pt.c (uses_parameter_packs): Destroy the pointer set.
+ (make_pack_expansion): Ditto.
+ (check_for_bare_parameter_packs): Ditto.
+ * name-lookup.c (push_to_top_level): Make need_pop a bool value.
+
+2007-03-14 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR c++/31165
+ * call.c (convert_default_arg): Instead of copying the node,
+ unshare it.
+
+2007-03-15 Dirk Mueller <dmueller@suse.de>
+
+ PR c++/30860
+ * call.c (convert_conversion_warnings): New..
+ (convert_like_real): .. factored out from here.
+ (convert_conversion_warnings): Add warning about
+ false being converted to NULL in argument passing.
+
+2007-03-14 Dirk Mueller <dmueller@suse.de>
+
+ * semantics.c (c_finish_if_stmt): Call empty_if_body_warning.
+ (finish_do_body): Warn about empty body in do/while statement.
+
+2007-03-14 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * class.c (warn_hidden): Add OPT_Woverloaded_virtual to warning.
+
+2007-03-14 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c/21438
+ * typeck.c (build_binary_op): Call warn_for_div_zero instead of
+ warning.
+
+2007-03-13 Alexandre Oliva <aoliva@redhat.com>
+
+ * repo.c (init_repo): Initialize random_seed saved options.
+ (finish_repo): Adjust.
+
+2007-03-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR bootstrap/30899
+ * Make-lang.in (doc/g++.1): Use $< to specify the location from
+ which to copy.
+
+2007-03-12 Seongbae Park <seongbae.park@gmail.com>
+
+ * decl.c (compute_array_index_type): New warning flag warn_vla.
+
+2007-03-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/30108
+ * call.c (convert_default_arg): Copy non-constant arguments.
+
+2007-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/31038
+ * parser.c (cp_parser_postfix_expression): Disallow compound
+ literals in constant expressions.
+
+ PR c++/30328
+ * semantics.c (finish_typeof): Use unlowered_expr_type.
+
+2007-03-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/30274
+ * cp-tree.h (unlowered_expr_type): New function.
+ * typeck.c (is_bitfield_expr_with_lowered_type): Handle
+ COMPOUND_EXPR, MODIFY_EXPR, and SAVE_EXPR.
+ (unlowered_expr_type): New function.
+ (build_unary_op): Disallow predecrements of bool bitfields.
+ * call.c (build_conditional_expr): Use unlowered_expr_type.
+ * pt.c (type_unification_real): Likewise.
+
+2007-03-09 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/20599
+ * typeck.c (check_return_expr): Check for bare parameter packs.
+ (comptypes): Compare template parameter packs and
+ type pack expansions.
+ * decl.c (grokdeclarator): Deal with the declaration of function
+ parameter packs.
+ (grokparms): Verify that the (optional) function parameter pack is
+ at the end of the parameter list.
+ (xref_basetypes): Handle pack expansions in the base class.
+ (cp_tree_node_structure): Handle ARGUMENT_PACK_SELECT.
+ * cp-tree.def (TYPE_ARGUMENT_PACK): New.
+ (NONTYPE_ARGUMENT_PACK): New.
+ (TYPE_PACK_EXPANSION): New.
+ (EXPR_PACK_EXPANSION): New.
+ (ARGUMENT_PACK_SELECT): New.
+ * cp-objcp-common.c (cp_tree_size): Compute size of
+ (NON)TYPE_ARGUMENT_PACK, (TYPE|EXPR)_PACK_EXPANSION, and
+ ARGUMENT_PACK_SELECT.
+ * error.c (dump_template_argument): Print template argument packs.
+ (dump_template_argument_list): Ditto.
+ (dump_template_parameter): Dump `...' for template type parameter
+ packs.
+ (dump_type): Dump TYPE_PACK_EXPANSION nodes.
+ (dump_parameters): Print function parameter packs.
+ (dump_template_parms): Print template argument packs.
+ (dump_expr): Dump EXPR_PACK_EXPANSION nodes.
+ (maybe_warn_variadic_templates): New.
+ * operators.def: Add ellipsis operator for EXPR_PACK_EXPANSION.
+ * tree.c (cp_walk_subtrees): Walk BASELINK, TYPE_ARGUMENT_PACK,
+ NONTYPE_ARGUMENT_PACK, TYPE_PACK_EXPANSION, EXPR_PACK_EXPANSION,
+ CAST_EXPR.
+ * mangle.c (write_type): Mangle TYPE_PACK_EXPANSION.
+ (write_template_arg): Write argument packs as separate arguments.
+ * cp-tree.h (struct template_parm_index_s): Add flag that
+ indicates that the template parameter is actually a parameter
+ pack.
+ (struct tree_argument_pack_select): New.
+ (enum cp_tree_node_structure_enum): Add TS_CP_ARGUMENT_PACK_SELECT.
+ (union lang_tree_node): Add argument_pack_select.
+ (FUNCTION_PARAMETER_PACK_P): New.
+ (PACK_EXPANSION_P): New.
+ (PACK_EXPANSION_PATTERN): New.
+ (SET_PACK_EXPANSION_PATTERN): New.
+ (PACK_EXPANSION_PARAMETER_PACKS): New.
+ (ARGUMENT_PACK_P): New.
+ (ARGUMENT_PACK_ARGS): New.
+ (SET_ARGUMENT_PACK_ARGS): New.
+ (ARGUMENT_PACK_INCOMPLETE_P): New.
+ (ARGUMENT_PACK_EXPLICIT_ARGS): New.
+ (TEMPLATE_PARM_PARAMETER_PACK): New.
+ (TEMPLATE_TYPE_PARAMETER_PACK): New.
+ (ARGUMENT_PACK_SELECT_FROM_PACK): New.
+ (ARGUMENT_PACK_SELECT_INDEX): New.
+ (ARGUMENT_PACK_SELECT_ARG): New.
+ (struct cp_declarator): Add parameter_pack_p flag.
+ (maybe_warn_variadic_templates): Declare.
+ (process_template_parm): Add bool parameter IS_PARAMETER_PACK, to
+ indicate a template parameter pack.
+ (uses_parameter_packs): Declare.
+ (template_parameter_pack_p): Declare.
+ (template_parms_variadic_p): Declare.
+ (make_pack_expansion): Declare.
+ (check_for_bare_parameter_packs): Declare.
+ * cxx-pretty-print.c (pp_cxx_unary_expression): Print
+ sizeof... expressions.
+ (pp_cxx_expression): Print pack expansions and non-type argument
+ packs.
+ (pp_cxx_exception_specification): Print pack expansions.
+ (pp_cxx_direct_declarator): Print ellipsis for parameter packs.
+ (pp_cxx_ctor_initializer): Print pack expansions.
+ (pp_cxx_type_id): Print pack expansions.
+ (pp_cxx_template_argument_list): Print argument packs.
+ (pp_cxx_template_parameter): Print ellipsis for template parameter
+ packs.
+ * pt.c (comp_template_parms): Compare template parameter packs.
+ (template_parameter_pack_p): New.
+ (template_parms_variadic_p): New.
+ (template_args_variadic_p): New.
+ (make_ith_pack_parameter_name): New.
+ (struct find_parameter_pack_data): New.
+ (find_parameter_packs_r): New.
+ (uses_parameter_packs): New.
+ (make_pack_expansion): New.
+ (check_for_bare_parameter_packs): New.
+ (expand_template_argument_pack): New.
+ (reduce_template_parm_level): Propagate parameter pack flag.
+ (process_template_parm): Add is_parameter_pack parameter to state
+ when the parameter is actually a parameter pack. Create template
+ parameter packs when is_parameter_pack is true.
+ (current_template_args): The argument for a template parameter
+ pack is an argument pack containing a single pack expansion.
+ (process_partial_specialization): When checking that non-type
+ argument expressions do not involve template parameters, loop over
+ the arguments in argument packs separately.
+ (push_template_decl_real): Check that the type of the declaration
+ does not have any bare parameter packs. Check that primary
+ templates have no more than one parameter pack, and that it comes
+ at the end of the template parameter list.
+ (convert_template_argument): Handle coercions for pack expansion
+ expressions by coercing the pattern then rebuilding the expansion.
+ (coerce_template_parms): When coercing the arguments for a
+ variadic template, pack "extra" arguments into an argument pack.
+ (coerce_template_template_parms): Cannot coerce between parameter
+ packs and non-pack parameters.
+ (template_args_equal): Compare PACK_EXPANSION_P expressions.
+ (comp_template_args): Expand all template arguments packs before
+ comparing template argument lists.
+ (mangle_class_name_for_template): Make argument packs as separate
+ template arguments.
+ (for_each_template_parm_r): No need to handle BASELINK.
+ (instantiate_class_template): Handle pack expansions in the base
+ class list.
+ (tsubst_pack_expansion): New.
+ (tsubst_template_args): Handle substitutions of argument packs and
+ pack expansion into template argument lists.
+ (tsubst_decl): Expand function parameter packs into separate
+ function parameters.
+ (tsubst_arg_types): Expand a type pack expansion into separate
+ argument types.
+ (tsubst_exception_specification): Handle pack expansions in
+ exception specifiers.
+ (tsubst): See through ARGUMENT_PACK_SELECT arguments when
+ replacing a template parameter with its argument. If we encounter
+ a substitution for an argument pack, just return the parameter
+ itself.
+ (tsubst_copy): sizeof(X...) returns the number of elements in
+ parameter pack X. See through ARGUMENT_PACK_SELECT when the
+ PARM_DECL is a parameter pack.
+ (tsubst_expr): Expression pack expansions and argument packs
+ cannot show up here; they will all be handled through function
+ calls, sizeof, and template argument lists.
+ (tsubst_copy_and_build): sizeof(X...) returns the number of
+ elements in parameter pack X. Handle pack expansions in TREE_LIST
+ and CONSTRUCTOR nodes.
+ (fn_type_unification): Handle "incomplete" explicit template
+ argument lists that specify some of the arguments for a template
+ parameter pack.
+ (type_unification_real): Unify arguments against pack expansions.
+ (template_parm_level_and_index): New, helper function.
+ (unify_pack_expansion): New.
+ (unify): Unify argument packs on an argument-by-argument basis,
+ handling variadic argument packs as well.
+ (more_specialized_fn): Handle unification of function parameter
+ packs. All things being equal, prefer non-variadic function
+ templates to variadic function templates.
+ (more_specialized_class): Prefer the variadic class template
+ partial specialization that binds fewer arguments to a parameter
+ pack.
+ (regenerate_decl_from_template): Expand function parameter packs
+ into separate parameters.
+ (instantiate_decl): Ditto.
+ (tsubst_initializer_list): Handle pack expansions for base-class
+ initializers.
+ (dependent_type_p_r): Determine dependent types in argument packs
+ and pack expansions.
+ (value_dependent_expression_p): Determine value-dependence of
+ non-type argument packs.
+ (dependent_template_arg_p): Handle argument packs.
+ * semantics.c (finish_cond): Check for bare parameter packs.
+ (finish_expr_stmt): Ditto.
+ (finish_for_expr): Ditto.
+ (finish_switch_cond): Ditto.
+ (finish_mem_initializers): Ditto.
+ * name-lookup.c (arg_assoc_type): Handle pack expansions and
+ argument packs.
+ * decl2.c (cp_build_parm_decl): Mark function parameter packs.
+ * parser.c (make_declarator): Declarator is not an expansion.
+ (make_pointer_declarator): Transfer parameter pack flag to outer
+ declarator.
+ (make_reference_declarator): Ditto.
+ (make_ptrmem_declarator): Ditto.
+ (make_call_declarator): Ditto.
+ (make_array_declarator): Ditto.
+ (cp_parser_postfix_expression): Allow pack expansion expressions
+ in the argument list for a call expression.
+ (cp_parser_parenthesized_expression_list): Add new parameter
+ ALLOW_EXPANSION_P. When true, parse the ellipsis to mean "expand
+ into separate arguments."
+ (cp_parser_new_placement): Allow pack expansion expressions.
+ (cp_parser_new_initializer): Ditto.
+ (cp_parser_mem_initializer_list): Allow ellipsis to create a
+ base-class initializer expansion.
+ (cp_parser_mem_initializer): Ditto.
+ (cp_parser_template_parameter_list): Keep track of whether the
+ template parameter is a template parameter pack.
+ (cp_parser_template_parameter): Parse the ellipsis to indicate a
+ template parameter pack.
+ (cp_parser_type_parameter): Ditto.
+ (cp_parser_template_argument_list): Parse the ellipsis to indicate
+ a pack expansion.
+ (cp_parser_direct_declarator): Parse the ellipsis to indicate that
+ this declarator is a parameter pack.
+ (cp_parser_parameter_declaration): The ellipsis does not end the
+ parameter declaration, because it might be a parameter pack. Parse
+ the ellipsis to indicate a parameter pack.
+ (cp_parser_initializer): Allow pack expansions.
+ (cp_parser_initializer_list): Allow ellipsis to create an
+ initializer expansion.
+ (cp_parser_base_clause): Allow ellipsis to create a base specifier
+ expansion.
+ (cp_parser_type_id_list): Allow ellipsis to create an exception
+ specifier expansion.
+ (cp_parser_attribute_list): Don't allow pack expansions.
+ (cp_parser_functional_cast): Allow pack expansions.
+ (cp_parser_sizeof_operand): Allow ellipsis following "sizeof" to
+ compute the length of a parameter pack.
+ (cp_parser_next_token_ends_template_argument_p): An ellipsis can
+ end a template argument.
+ * tree.c (cp_walk_subtrees): Walk BASELINK, TYPE_ARGUMENT_PACK,
+ NONTYPE_ARGUMENT_PACK, TYPE_PACK_EXPANSION, EXPR_PACK_EXPANSION,
+ CAST_EXPR.
+
+2007-03-09 Dirk Mueller <dmueller@suse.de>
+
+ * call.c (build_new_op): Call warn_logical_operator.
+
+2007-03-08 Volker Reichelt <v.reichelt@netcologne.de>
+
+ PR c++/30852
+ * semantics.c (finish_offsetof): Handle COMPOUND_EXPR.
+
+ PR c++/30534
+ * pt.c (any_template_arguments_need_structural_equality_p):
+ Robustify.
+
+2007-03-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * decl.c (grokdeclarator): Disable warnings for anonymous
+ bitfields.
+
+2007-03-05 Volker Reichelt <v.reichelt@netcologne.de>
+
+ * typeck2.c (readonly_error): Always emit a hard error.
+ Remove last argument.
+ * cp-tree.h (readonly_error): Adjust prototype.
+ * semantics.c (finish_asm_stmt): Adjust call to readonly_error.
+ * typeck.c (build_unary_op): Likewise.
+ (build_modify_expr): Likewise.
+
+2007-03-04 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/30895
+ * tree.c (cp_tree_equal): Properly handle COMPLEX_CST trees.
+
+2007-03-03 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/15787
+ * parser.c (struct cp_parser): New IN_IF_STMT.
+ (cp_parser_statement_seq_opt): Handle an unexpected 'else',
+ returning if parsing the body of an 'if' statement or issuing an
+ error and continuing.
+ (cp_parser_selection_statement): Set IN_IF_STMT bit when parsing
+ body of 'if'.
+ (cp_parser_jump_statement): Mask new IN_IF_STMT bit.
+
+2007-03-02 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/28253
+ * class.c (update_vtable_entry_for_fn): Properly handle invalid overriders
+ for thunks.
+
+2007-03-02 Geoffrey Keating <geoffk@apple.com>
+
+ * g++spec.c (lang_specific_driver): Add -lstdc++ when compiling
+ Objective-C++. Don't exit early if -shared-libgcc needs to be
+ added.
+
+2007-03-02 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * typeck.c (common_base_type): Delete unused function.
+
+2007-03-01 Brooks Moses <brooks.moses@codesourcery.com>
+
+ * Make-lang.in: Add dummy lang.install-pdf target.
+
+2007-03-01 Simon Baldwin <simonb@google.com>
+
+ PR c++/23689
+ * decl.c (check_tag_decl): Added new warning for typedef ignored
+ when it precedes an otherwise valid non-typedef declaration.
+
+2007-02-28 Sandra Loosemore <sandra@codesourcery.com>
+
+ * typeck.c (build_function_call): Store converted arguments
+ in a stack-allocated array instead of building a list.
+ (convert_arguments): Store arguments in the array passed in as an
+ argument, and return the actual number of arguments.
+ * call.c (build_call): Delete, and replace with...
+ (build_call_n, build_call_a): New.
+ (build_op_delete_call): Rewrite to avoid constructing argument lists.
+ (build_over_call): Store converted arguments in a stack-allocated
+ array instead of building a list.
+ (build_cxx_call): Pass arguments in an array instead of as a list.
+ (build_java_interface_fn_ref): Rewrite to avoid constructing
+ argument lists.
+ * tree.h: Update declarations to reflect above changes.
+ * method.c (use_thunk): Use a stack-allocated array to hold
+ the arguments instead of a list.
+ * rtti.c (throw_bad_cast): Update call to cxx_call.
+ (throw_bad_typeid): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ * init.c (build_builtin_delete_call): Use build_call_n.
+ * decl.c (expand_static_init): Likewise.
+ * except.c (cp_protect_cleanup_actions): Likewise.
+ * cp-gimplify.c (genericize_eh_spec_block): Likewise.
+ (gimplify_must_not_throw_expr): Likewise.
+ (cxx_omp_apply_fn): Use build_call_a.
+
+2007-02-26 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (expand_or_defer_fn): Call c_record_cdtor_fn.
+ * decl2.c (cp_write_gloabl_declarations): Call c_build_cdtor_fns.
+
+2007-02-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (static_ctors): Remove.
+ * cp-tree.h (static_dtors): Likewise.
+ * cp-objcp-common.c (decl_shadowed_for_var_lookup): Adjust for
+ refactoring of tree_map hierarchy.
+ (decl_shadowed_for_var_insert): Likewise.
+ * semantics.c (expand_body): Use c_expand_body.
+ (expand_or_defer_fn): Don't update static_ctors or static_dtors.
+ * decl2.c (static_ctors): Remove.
+ (static_dtors): Likewise.
+ (generate_ctor_or_dtor_function): Pass NULL_TREE to
+ objc_generate_static_init_call. Do not call static_[cd]tors.
+ (generate_ctor_and_dtor_functions_for_priority): Do not check for
+ static_[cd]tors.
+ (cp_write_global_declarations): Likewise.
+
+2007-02-23 Richard Guenther <rguenther@suse.de>
+
+ * class.c (note_name_declared_in_class): Make declaration
+ changes meaning a pedwarn.
+
+2007-02-22 Michael Matz <matz@suse.de>
+
+ PR c++/29433
+ * cp-tree.h (TFF_UNQUALIFIED_NAME): New formatting flag.
+ * error.c (dump_aggr_type, dump_simple_decl, dump_decl,
+ dump_function_decl): Guard emitting outer scopes by new flag.
+ * cp-lang.c (cxx_dwarf_name): New function.
+ (LANG_HOOKS_DWARF_NAME): Define to cxx_dwarf_name.
+ * pt.c (classtype_mangled_name, mangle_class_name_for_template):
+ Remove functions.
+ (push_template_decl_real, lookup_template_class): Remove calls
+ to above functions.
+
+2007-02-19 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_new_method_call): Ensure that explicit calls of
+ destructors have type "void".
+
+2007-02-19 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * typeck.c (build_binary_op): Replace -Wstring-literal-comparison
+ and -Walways-true with -Waddress.
+ * cvt.c (convert_to_void): Replace unconditional warning with
+ -Waddress.
+
+2007-02-18 Kazu Hirata <kazu@codesourcery.com>
+
+ * decl.c, tree.c: Fix comment typos.
+
+2007-02-15 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR C++/30158
+ * semantics.c (finish_stmt_expr_expr): Set TREE_TYPE of the
+ statement expression if we had an error mark node.
+
+2007-02-15 Sandra Loosemore <sandra@codesourcery.com>
+ Brooks Moses <brooks.moses@codesourcery.com>
+ Lee Millward <lee.millward@codesourcery.com>
+
+ * cp-tree.def (AGGR_INIT_EXPR): Adjust documentation.
+ Change class to tcc_vl_exp.
+
+ * call.c (build_call): Use build_call_list instead
+ of build3.
+ (build_over_call): Likewise.
+ (build_new_method_call): Use build_min_non_dep_call_list
+ instead of build_min_non_dep.
+
+ * error.c (dump_call_expr_args): New function.
+ (dump_aggr_init_expr_args): New function.
+ (dump_expr) <AGGR_INIT_EXPR, CALL_EXPR, INDIRECT_REF>: Use them.
+ Update to use new CALL_EXPR and AGGR_INIT_EXPR accessor macros.
+
+ * cvt.c (convert_to_void): Use build_call_array instead
+ of build3; use new AGGR_INIT_EXPR accessor macros.
+
+ * mangle.c (write_expression): Use TREE_OPERAND_LENGTH
+ instead of TREE_CODE_LENGTH.
+
+ * dump.c (cp_dump_tree) <AGGR_INIT_EXPR>: Update to use new
+ AGGR_INIT_EXPR accessor macros.
+
+ * cp-gimplify.c (cp_gimplify_init_expr): Use
+ AGGR_INIT_EXPR_SLOT to set the slot operand.
+
+ * cp-tree.h (AGGR_INIT_EXPR_FN): New macro.
+ (AGGR_INIT_EXPR_SLOT): New macro.
+ (AGGR_INIT_EXPR_ARG): New macro.
+ (aggr_init_expr_nargs): New macro.
+ (AGGR_INIT_EXPR_ARGP): New macro.
+ (aggr_init_expr_arg_iterator): New.
+ (init_aggr_init_expr_arg_iterator): New.
+ (next_aggr_init_expr_arg): New.
+ (first_aggr_init_expr_arg): New.
+ (more_aggr_init_expr_args_p): New.
+ (FOR_EACH_AGGR_INIT_EXPR_ARG): New.
+ (stabilize_aggr_init): New declaration.
+ (build_min_non_dep_call_list): Likewise.
+
+ * tree.c (process_aggr_init_operands): New function.
+ (build_aggr_init_array) New function.
+ (build_cplus_new): Update to use new CALL_EXPR and
+ AGGR_INIT_EXPR accessor macros. Replace use of build3 with
+ build_aggr_init_array.
+ (build_min_non_dep_call_list) New function.
+ (build_min_nt): Assert input code parameter is not a variable
+ length expression class.
+ (build_min, build_min_non_dep): Likewise.
+ (cp_tree_equal) <CALL_EXPR>: Iterate through the arguments
+ to check for equality instead of recursing. Handle tcc_vl_exp
+ tree code classes.
+ (stabilize_call): Update to only handle CALL_EXPRs, not
+ AGGR_INIT_EXPRs; use new CALL_EXPR accessor macros.
+ (stabilize_aggr_init): New function.
+ (stabilize_init): Use it.
+
+ * cxx-pretty-print.c (pp_cxx_postfix_expression)
+ <AGGR_INIT_EXPR, CALL_EXPR>: Update to use new CALL_EXPR and
+ AGGR_INIT_EXPR accessor macros and argument iterators.
+
+ * pt.c (tsubst_copy) <CALL_EXPR>: Replace build_nt with
+ build_vl_exp. Iterate through the operands, recursively
+ processing each one.
+ (tsubst_copy_and_build) <CALL_EXPR>: Update to use new
+ CALL_EXPR accessor macros.
+ (value_dependent_expression_p) <default>: Handle tcc_vl_exp
+ tree code classes. Use TREE_OPERAND_LENGTH instead of
+ TREE_CODE_LENGTH.
+
+ * semantics.c (finish_call_expr): Use build_nt_call_list
+ instead of build_nt.
+ (simplify_aggr_init_expr): Update to use new AGGR_INIT_EXPR
+ accessor macros. Use build_call_array to construct the
+ CALL_EXPR node instead of build3
+
+ * decl2.c (build_offset_ref_call_from_tree): Use
+ build_nt_call_list and build_min_non_dep_call_list instead
+ of build_min_nt and build_min_non_dep.
+
+ * parser.c (cp_parser_postfix_expression) <CPP_OPEN_PAREN>:
+ Use build_nt_call_list instead of build_min_nt.
+
+2007-02-15 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/28943
+ * call.c (build_conditional_expr): Improve error message.
+
+2007-02-13 Dirk Mueller <dmueller@suse.de>
+
+ * friend.c (do_friend): Annotate warning about friend
+ declarations in templates with OPT_Wnon_template_friend.
+ Convert informal message from warning() to inform().
+
+2007-02-12 Simon Martin <simartin@users.sourceforge.net>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14622
+ * pt.c (do_decl_instantiation): Detect type mismatches in explicit
+ instantiations for variables.
+
+2007-02-12 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR middle-end/7651
+ * cp-gimplify.c (gimplify_expr_stmt): Don't check extra_warnings.
+ Check warn_unused_value just once.
+
+2007-02-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/26988
+ * pt.c (determine_specialization): Use skip_artificial_parms_for.
+ (fn_type_unificiation): Likewise.
+ (get_bindings): Likewise.
+
+o2007-02-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR target/29487
+ * decl.c (finish_function): Use DECL_REPLACEABLE.
+ * tree.c (cp_cannot_inline_tree_fn): Likewise.
+
+2007-02-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * parser.c (cp_parser_primary_expression): Reformat overly long lines.
+
+2007-02-10 Richard Henderson <rth@redhat.com>, Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (grokvardecl): Don't error if !have_tls.
+ (grokdeclarator): Likewise.
+ * parser.c (cp_parser_omp_threadprivate): Likewise.
+
+2007-02-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/30703
+ * cp-gimplify.c (cp_genericize_r): Don't dereference invisiref
+ parameters and result decls in omp clauses.
+ (cxx_omp_privatize_by_reference): Pass also invisiref PARM_DECLs
+ by reference.
+
+2007-02-05 Dirk Mueller <dmueller@suse.de>
+
+ PR bootstrap/30510
+ * parser.c (cp_parser_class_specifier): Always initialize bases.
+
+2007-02-05 Paolo Bonzini <bonzini@gnu.org>
+
+ * cp-tree.h (OMP_ATOMIC_CODE): Delete.
+ (OMP_ATOMIC_DEPENDENT_P): Rewrite.
+ * pt.c (tsubst_expr): Adjust for new format of dependent OMP_ATOMIC
+ expressions.
+ * semantics.c (finish_omp_atomic): Store a whole expression node
+ in operand 1, and integer_zero_node in operand 0, for dependent
+ OMP_ATOMIC. Rewrite to make flow easier to understand.
+
+2007-02-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (grokdeclarator): Use OPT_Wreturn_type instead of 0.
+
+2007-02-04 Kazu Hirata <kazu@codesourcery.com>
+
+ * class.c, cp-tree.h, decl.c, decl2.c, g++spec.c, init.c,
+ parser.c, pt.c, tree.c, typeck.c: Follow spelling conventions.
+
+2007-02-03 Douglas Gregor <doug.gregor@gmail.com>
+
+ * parser.c (cp_lexer_get_preprocessor_token): Attach the C++0x
+ keyword warning to -Wc++0x-compat.
+
+2007-02-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (grokdeclarator): Update documentation.
+
+2007-02-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/30536
+ * decl.c (grokdeclarator): If __thread is used together with
+ a storage class other than extern and static, clear thread_p
+ after issuing diagnostics and fall through to checking the
+ storage class.
+
+2007-01-30 Roger Sayle <roger@eyesopen.com>
+
+ * error.c (dump_type_suffix): Avoid use of cp_build_binary_op when
+ calculating the size of an array (to avoid recursive errors).
+
+2007-01-30 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/24745
+ * typeck.c (build_binary_op): Fix logic for warning. Move warning
+ to -Wpointer-arith.
+ * call.c (convert_like_real): Don't warn when converting to
+ boolean type.
+
+2007-01-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * decl.c (pop_label): Replace warning with call to
+ warn_for_unused_label.
+
+2007-01-28 Andrew Pinski <pinskia@gmail.com>
+
+ PR C++/28988
+ * semantics.c (finish_pseudo_destructor_expr): Check the
+ destrutor name by calling check_dtor_name.
+
+2007-01-24 Douglas Gregor <dgregor@osl.iu.edu>
+
+ * lex.c (D_CPP0X): Rename.
+ (D_CXX0X): To this.
+ (reswords): D_CPP0X -> D_CXX0X.
+ (init_reswords): Ditto.
+ * parser.c (cp_lexer_get_preprocessor_token): Warn about the use
+ of C++0x keywords as identifiers.
+
+2007-01-23 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/27492
+ * decl.c (duplicate_decls): Don't reset DECL_INVALID_OVERRIDER_P for
+ function decls.
+
+2007-01-23 Ian Lance Taylor <iant@google.com>
+
+ * typeck.c (convert_for_assignment): Only warn about a = b = c
+ when converting to bool.
+
+2007-01-23 Roger Sayle <roger@eyesopen.com>
+
+ * call.c (null_ptr_cst_p): Replace use of TREE_CONSTANT_OVERFLOW with
+ TREE_OVERFLOW.
+ * typeck.c (ignore_overflows): Remove the remaining uses of
+ TREE_CONSTANT_OVERFLOW.
+
+2007-01-20 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (start_objects, start_static_storage_duration_function):
+ Do not make the functions uninlinable.
+
+2007-01-17 Ian Lance Taylor <iant@google.com>
+
+ * class.c (add_method): Call VEC_reserve_exact rather than passing
+ a negative size to VEC_reserve.
+
+2007-01-11 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/29573
+ * tree.c (cp_tree_equal): Properly handle MODOP_EXPR trees.
+
+2007-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28999
+ * decl.c (make_typename_type): If the qualified name is not a
+ type, issue an error.
+ * parser.c (cp_parser_elaborated_type_specifier): Fix comment
+ formatting.
+
+2007-01-08 Geoffrey Keating <geoffk@apple.com>
+
+ * rtti.c: Include target.h.
+ (emit_support_tinfos): If ! targetm.cxx.library_rtti_comdat (),
+ don't emit typeinfo for fundamental types as weak.
+ * Make-lang.in (cp/rtti.o): Update and correct dependencies.
+
+2007-01-08 Richard Guenther <rguenther@suse.de>
+
+ * cvt.c (cp_convert_to_pointer): Use build_int_cst_type.
+
+2007-01-08 Mark Shinwell <shinwell@codesourcery.com>
+
+ * call.c (standard_conversion): Pass flag to
+ vector_types_convertible_p to disallow emission of note.
+ * typeck.c (convert_for_assignment): Pass flag to
+ vector_types_convertible_p to allow emission of note.
+ (ptr_reasonably_similar): Pass flag to vector_types_convertible_p
+ to disallow emission of note.
+
+2007-01-07 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/28986
+ * typeck.c (build_binary_op): Call overflow_warning if
+ TREE_OVERFLOW_P is true for the result and not for any of the
+ operands.
+
+2007-01-06 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/19439
+ * class.c (add_method): Don't wait until template
+ instantiation time to complain about duplicate methods.
+
+2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c/19978
+ * semantics.c (finish_unary_op_expr): Warn only if result
+ overflowed and operands did not.
+
+2007-01-05 Ian Lance Taylor <iant@google.com>
+
+ * typeck.c (build_binary_op): Warn about comparing a non-weak
+ address to NULL.
+
+2007-01-05 Douglas Gregor <doug.gregor@gmail.com>
+
+ * pt.c (tsubst): Propagate the need for structural equality checks
+ when reducing the level of template parameters.
+
+2007-01-03 Kazu Hirata <kazu@codesourcery.com>
+
+ * pt.c: Fix a comment typo.
+
+2007-01-02 Ian Lance Taylor <iant@google.com>
+
+ * semantics.c (maybe_convert_cond): Optionally warn when using an
+ assignment as a condition.
+ * typeck.c (convert_for_assignment): Optionally warn about
+ assigning the result of an assignment to a bool.
+
+2007-01-02 Douglas Gregor <doug.gregor@gmail.com>
+
+ * pt.c (canonical_template_parms): Correct typo in comment.
+
+2007-01-02 Douglas Gregor <doug.gregor@gmail.com>
+
+ * typeck.c (structural_comptypes): Renamed from "comptypes".
+ (comptypes): Use canonical type information to perform fast type
+ comparison. When VERIFY_CANONICAL_TYPES, verify that the
+ canonical type comparison returns the same results as we would see
+ from the current, structural check. Support COMPARE_STRUCTURAL
+ when we need structural checks.
+ * decl.c (typename_compare): Fix comment.
+ (build_typename_type): TYPENAME_TYPE nodes require structural
+ equality checks, because they resolve different based on the
+ current class type.
+ (make_unbound_class_template): UNBOUND_CLASS_TEMPLATE nodes
+ require structural equality checks (for now).
+ (build_ptrmemfunc_type): Build the canonical pointer to member
+ function type.
+ (compute_array_index_type): Whenever we build a new index type
+ to represent the size of an array in a template, we need to mark
+ this index type as requiring structural equality. This goes for
+ arrays with value-dependent sizes with the current ABI, or all
+ arrays with ABI-1.
+ * tree.c (cplus_array_hash): New.
+ (struct cplus_array_info): New.
+ (cplus_array_compare): New.
+ (cplus_array_htab): New.
+ (build_cplus_array_type_1): Use a hash table to cache the array
+ types we build. Build the canonical array type for each array
+ type.
+ (cp_build_qualified_type_real): When building a cv-qualified array
+ type, use the hash table of array types and build canonical array
+ types as necessary.
+ (bind_template_template_parm): BOUND_TEMPLATE_TEMPLATE_PARM nodes
+ use structural equality (for now).
+ * cp-tree.h (COMPARE_STRUCTURAL): New.
+ * pt.c (canonical_template_parms): New.
+ (canonical_type_parameter): New.
+ (process_template_parm): Find the canonical type parameter.
+ (lookup_template_class): When we have named the primary template
+ type, set the canonical type for our template class to the primary
+ template type. If any of the template arguments need structural
+ equality checks, the template class needs structural equality
+ checks.
+ (tsubst): When reducing the level of a template template
+ parameter, we require structural equality tests for the resulting
+ parameter because its template parameters have not had their types
+ canonicalized. When reducing a template type parameter, find the
+ canonical reduced type parameter.
+ (any_template_arguments_need_structural_equality_p): New.
+
+
+Copyright (C) 2007 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2008 b/gcc-4.9/gcc/cp/ChangeLog-2008
new file mode 100644
index 000000000..5a69a5d20
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2008
@@ -0,0 +1,3263 @@
+2008-12-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38647
+ * parser.c (cp_parser_primary_expression) <case RID_FUNCTION_NAME>:
+ Return error_mark_node if cp_parser_non_integral_constant_expression
+ returns true.
+
+ PR c++/38640
+ * semantics.c (finish_decltype_type): Handle TEMPLATE_PARM_INDEX.
+
+2008-12-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38635
+ * parser.c (cp_parser_condition): Use cp_parser_require
+ instead of cp_lexer_consume_token to consume =.
+
+ PR c++/38637
+ * decl.c (start_enum): If enumtype is error_mark_node, exit early.
+
+2008-12-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38650
+ * semantics.c (finish_omp_for): Don't add CLEANUP_POINT_EXPR
+ around volatile iteration var in condition and/or increment
+ expression.
+
+2008-12-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38639
+ * pt.c (tsubst_omp_for_iterator): RECUR on whole init_expr instead of
+ just its type.
+
+2008-12-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/38597
+ * name-lookup.c (arg_assoc_type): Handle DECLTYPE_TYPE.
+
+2008-12-20 Jakub Jelinek <jakub@redhat.com>
+ Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/36921
+ * c-common.c (warn_about_parentheses): Remove ARG_UNUSED from
+ arg_left. Don't warn about X<=Y<=Z if comparison's type isn't
+ integral.
+
+2008-12-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38577
+ * call.c (build_new_method_call): Handle call being COMPOUND_EXPR
+ or NOP_EXPR.
+
+2008-12-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38427
+ * init.c (perform_member_init): For value-initialized
+ references call permerror instead of warning and don't emit any
+ INIT_EXPR.
+
+2008-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/38485
+ * parser.c (cp_parser_token_starts_cast_expression): An EOF
+ can't start a cast-expression.
+
+2008-12-17 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (describable_type): New function.
+ (finish_decltype_type): Use it for dependent exprs.
+ * cp-tree.h: Declare it.
+ * mangle.c (write_type) [DECLTYPE_TYPE]: Set skip_evaluation.
+ (write_expression): If skip_evaluation, use type stubs.
+ * tree.c (cp_tree_equal): Handle PARM_DECLs from different
+ declarations of a function.
+ * init.c (build_new): Do auto deduction if type is describable.
+ * decl.c (cp_finish_decl): Likewise.
+ * parser.c (cp_parser_omp_for_loop): Likewise.
+
+2008-12-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/35319
+ * mangle.c (write_builtin_type): Add mangling for decimal floating
+ point and fixed point types.
+ (write_type): Pass FIXED_POINT_TYPE along.
+
+2008-12-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/37971
+ * class.c (resolve_address_of_overloaded_function): Check
+ accessibility of member functions unless FLAGS indicates
+ otherwise.
+ * call.c (standard_conversion): Adjust flags passed to
+ instantiate_type.
+ (convert_default_arg): Do not perform access checks.
+ * cp-tree.h (tsubst_flags_t): Add tf_no_access_control.
+
+2008-12-08 Steve Ellcey <sje@cup.hp.com>
+
+ * decl2.c (mark_used): Remove assemble_external call.
+
+2008-12-08 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/38390
+ * name-lookup.c (kept_level_p): Don't forget the case of levels
+ having using directives.
+
+2008-12-08 Richard Henderson <rth@redhat.com>
+
+ PR 38240
+ * class.c (finish_struct_bits): Use SET_TYPE_MODE.
+ * decl.c (record_unknown_type): Likewise.
+ (start_enum, finish_enum): Likewise.
+
+2008-12-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35336
+ * error.c (dump_expr): Handle BIT_FIELD_REF.
+
+2008-12-05 Sebastian Pop <sebastian.pop@amd.com>
+
+ PR bootstrap/38262
+ * Make-lang.in (cc1plus-dummy, cc1plus): Add BACKENDLIBS,
+ remove GMPLIBS.
+
+2008-12-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/37906
+ * decl.c (grok_special_member_properties): Set TYPE_HAS_COMPLEX_DFLT
+ here.
+ * class.c (check_bases_and_members): Rather than assuming any
+ user-declared default constructor is complex here.
+
+2008-12-04 Richard Guenther <rguenther@suse.de>
+
+ PR c++/38334
+ * typeck.c (get_member_function_from_ptrfunc): Mark the vtbl
+ pointer access with TREE_NO_WARNING.
+
+2008-12-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/38232
+ * init.c (build_value_init): Do initial zero-initialization
+ of a class with an implicitly-defined constructor using
+ build_zero_init rather than in build_value_init.
+ (build_value_init_1): Fold into build_value_init.
+
+ PR c++/38256
+ * parser.c (cp_parser_conversion_type_id): Diagnose
+ 'operator auto' here.
+ * decl.c (grokdeclarator): Not here.
+
+ PR c++/38380
+ * decl.c (grokdeclarator): Only set DECL_NONCONVERTING_P
+ on explicit constructors.
+ * pt.c (tsubst_copy_and_build) [CONSTRUCTOR]: Propagate
+ CONSTRUCTOR_IS_DIRECT_INIT.
+
+2008-12-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/35782, c++/37860
+ * call.c (build_user_type_conversion_1): Remember
+ list-initialization.
+ (convert_like_real): Likewise.
+ (build_over_call): Don't require the copy constructor
+ for copy-list-initialization.
+ * cp-tree.h (TARGET_EXPR_LIST_INIT_P): New macro.
+
+ PR c++/37234
+ * decl.c (cp_finish_decl): Handle =default and =delete for
+ templates, too.
+
+2008-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38257
+ * parser.c (cp_parser_omp_for_loop): Handle auto.
+ * pt.c (tsubst_omp_for_iterator): Likewise.
+
+2008-11-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/38233
+ * init.c (perform_member_init): Fix value-initialization.
+ (build_value_init_1): Add assert to catch cases that will break
+ in the gimplifier.
+ (build_default_init): Remove.
+ * cp-tree.h: Remove its prototype.
+ * pt.c (tsubst_expr) [DECL_EXPR]: Use build_value_init for
+ value-initialization.
+
+ PR c++/38278
+ * parser.c (cp_parser_class_name): Only call
+ maybe_note_name_used_in_class if we actually found a class name.
+
+2008-11-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/28743
+ * decl2.c (check_classfn): Error rather than abort on parameter
+ list mismatch.
+
+2008-11-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/28513
+ * parser.c (cp_parser_class_name): Call maybe_note_name_used_in_class.
+
+ PR c++/37540
+ * call.c (build_over_call): Take the address of the function even
+ in a template.
+ (build_new_method_call): Remember the type of the called function
+ in a template.
+
+2008-11-19 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/37142
+ * pt.c (coerce_template_template_parm): Use the more robust
+ uses_template_parms instead of dependent_type_p.
+
+2008-11-19 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/35405
+ * pt.c (lookup_template_class): Check pointers before dereferencing
+ them.
+ * error.c (dump_template_decl): Likewise.
+
+2008-11-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/36410
+ * decl2.c (grokfield): Pass ATTR_FLAG_TYPE_IN_PLACE for a typedef
+ that names a class for linkage purposes.
+
+ PR c++/37563
+ * parser.c (cp_parser_pseudo_destructor_name): A pseudo-destructor
+ name is not a declaration.
+
+ PR c++/37256
+ * pt.c (instantiate_decl): Don't require a definition of
+ a template that is explicitly instantiated 'extern'.
+
+2008-11-18 Jason Merrill <jason@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37962
+ * parser.c (cp_parser_type_id): Complain about auto.
+ * decl.c (grokdeclarator): Complain about parameters and
+ conversion functions declared with auto.
+
+ * call.c (standard_conversion): Use CLASS_TYPE_P instead of
+ MAYBE_CLASS_TYPE_P.
+ * cp-tree.h (TYPE_NON_AGGREGATE_CLASS): Likewise.
+
+2008-11-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/36089
+ * init.c (constant_value_1): Handle TREE_LIST init.
+
+2008-11-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37561
+ * typeck.c (cp_build_unary_op): Don't call get_unwidened. Use
+ argtype instead of result_type.
+
+2008-11-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/38030
+ * semantics.c (finish_call_expr): Don't repeat arg-dep lookup
+ for a non-dependent call.
+
+ PR c++/37740
+ * call.c (build_aggr_conv): Increment i.
+
+2008-11-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/37932
+ * typeck2.c (process_init_constructor_record): Update bitfield
+ handling.
+ (check_narrowing): Update bitfield handling, print source type.
+
+2008-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/36478
+ Revert:
+ 2007-05-07 Mike Stump <mrs@apple.com>
+ * parser.c (check_empty_body): Add.
+ (cp_parser_iteration_statement): Add call to check_empty_body.
+
+2008-11-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/38007
+ * typeck.c (cp_build_modify_expr): Update bitfield handling.
+
+2008-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34269
+ * parser.c (cp_parser_simple_declaration): Don't commit
+ to tentative parse if parse errors were seen.
+
+ PR c++/35334
+ * error.c (dump_expr): Handle COMPLEX_EXPR.
+
+2008-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38021
+ * parser.c (cp_parser_enum_specifier): After parsing :,
+ parse definitely. Don't return early if type specifier
+ is erroneous.
+
+2008-11-06 David Edelsohn <edelsohn@gnu.org>
+
+ PR target/26397
+ * g++spec.c (LIBSTDCXX_STATIC): New.
+ (lang_spec_driver): Use LIBSTDCXX_STATIC when not
+ shared_libgcc.
+
+2008-11-05 Fabien Chene <fabien.chene@gmail.com>
+
+ PR c++/32519
+ * cp-tree.h: Fix DECL_NONSTATIC_MEMBER_P to handle member template
+ functions.
+
+2008-11-05 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/37742
+ * decl.c (start_preparsed_function): Use the correct type for
+ building the RESULT_DECL.
+
+2008-10-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37967
+ * decl.c (grokdeclarator): Diagnose auto function decl without
+ late return type and late return type function decl where type
+ is not auto.
+
+ PR c++/37965
+ * decl.c (cp_finish_decl): Diagnose type_uses_auto type with
+ no initializer.
+
+2008-10-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 11492
+ * class.c (check_bitfield_decl): Rename min_precision to
+ tree_int_cst_min_precision.
+ * decl.c (finish_enum): Likewise.
+
+2008-10-29 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/26997
+ * parser.c (cp_parser_token_starts_cast_expression): New.
+ (cp_parser_cast_expression): Peek the next token to decide whether
+ this could be a parenthesized constructor or is definitely an
+ actual cast.
+
+2008-10-24 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/7543
+ * typeck.c (build_x_binary_op): Update call to
+ warn_about_parentheses.
+ * parser.c (cp_parser_binary_expression): Add note about passing
+ the correct code for unary expressions.
+
+2008-10-24 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (check-c++-subtargets): New alias for
+ check-g++-subtargets.
+ (lang_checks_parallelized): Add check-g++.
+ (check_g++_parallelize): New variable.
+
+2008-10-21 Richard Guenther <rguenther@suse.de>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Remove.
+ (expand_or_defer_fn): Do not walk the function body to
+ simplify aggr_init_exprs.
+
+2008-10-20 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/37004
+ * typeck.c (cp_common_type): New. The same as
+ type_after_usual_arithmetic_conversions but without promotions.
+ (type_after_usual_arithmetic_conversions): Do the promotions and
+ call cp_common_type.
+ (common_type): Make it behave like the C version of this
+ function. Do not handle pointer types.
+ (common_pointer_type): Move handling of pointer types from
+ common_type to here.
+ (cp_build_binary_op): Use common_pointer_type instead of
+ common_type in call to pointer_diff.
+ Use cp_common_type instead of common_type.
+ * cp-tree.h (common_pointer_type): Declare.
+
+2008-10-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37819
+ * cp-gimplify.c (cp_genericize_r): Only fold_convert COND_EXPR
+ arguments if they don't already have COND_EXPR's type.
+
+2008-10-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/37650
+ * pt.c (push_template_decl_real): Check that current_template_parms
+ is not null.
+ (process_partial_specialization): Assert current_template_parms not
+ null.
+
+2008-10-13 Doug Evans <dje@google.com>
+
+ * cp-tree.h (DECL_MAIN_P): Fix parentheses around expression.
+
+2008-10-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37146
+ * cp-gimplify.c (cp_genericize_r): Fix up bitfield operands of
+ COND_EXPR.
+
+2008-10-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37568
+ * semantics.c (finalize_nrv_r): Clear DECL_INITIAL instead of
+ setting it to error_mark_node.
+
+2008-10-07 Steve Ellcey <sje@cup.hp.com>
+
+ * decl.c (start_cleanup_fn): Declare as inline.
+
+2008-10-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/37376, other mangling issues
+ * mangle.c (write_type): Update TYPE_PACK_EXPANSION mangling.
+ (write_member_name): Break out from...
+ (write_expression): ...here. Handle dependent COMPONENT_REF.
+ (write_template_arg): Wrap an argument pack in 'I'/'E'.
+ (write_builtin_type): Update char16/32_t mangling.
+ (write_nested_name, write_prefix): Don't forget template args
+ for typename types.
+ * operators.def: Add ARROW_EXPR, update COMPONENT_REF and
+ EXPR_PACK_EXPANSION.
+
+2008-10-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * typeck.c (build_x_indirect_ref): Add location argument.
+ (cp_build_binary_op): Pass location to warn_for_div_by_zero.
+ (cp_build_unary_op): Add location argument.
+ (cp_build_modify_expr): Same.
+ * class.c (build_base_path): Pass location to build_indirect_ref.
+ * semantics.c (handle_omp_for_class_iterator): Pass elocus to
+ build_modify_expr.
+
+2008-10-05 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/37410
+ * cp-gimplify.c (cp_gimplify_expr): For each USING_STMT
+ make sure an IMPORTED_DECL node is added to the BLOCK_VARS list
+ of the innermost containing BLOCK.
+
+2008-10-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/37719
+ * error.c (dump_function_decl): Save the exceptions in case of
+ error about incompatible specifications in a specialization.
+
+2008-10-01 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * tree.c (lvalue_p_1): COMPOUND_LITERAL_EXPR is also an lvalue.
+
+2008-09-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/37683
+ * parser.c (cp_parser_selection_statement): Fix uninitialized
+ variable.
+
+2008-09-30 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/37555
+ PR c++/37556
+ * decl.c (grokdeclarator): Set the type for typedefs to a
+ nested-name-specifier to error_mark_node.
+
+2008-09-30 Paolo Bonzini <bonzini@gnu.org>
+
+ * parser.c (cp_parser_selection_statement): Implement here the
+ -Wempty-body warning for `if' and `else' statements.
+ * semantics.c (finish_if_stmt): Do not call empty_body_warning.
+
+2008-09-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/37649
+ * name-lookup.c (maybe_process_template_type_declaration): Check
+ return value of push_template_decl_real for error_mark_node.
+
+2008-09-24 Aldy Hernandez <aldyh@redhat.com>
+
+ * semantics.c (finish_fname): Pass location to fname_decl.
+
+2008-09-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37533
+ * semantics.c (finish_omp_for): If processing_template_decl, just build
+ MODIFY_EXPR for init instead of calling cp_build_modify_expr.
+
+2008-09-23 Aldy Hernandez <aldyh@redhat.com>
+
+ * typeck.c (build_array_ref): Pass location to cp_build_binary_op.
+ (get_member_function_from_ptrfunc): Same.
+ (build_x_binary_op): Same.
+ (build_binary_op): Same.
+ (cp_build_binary_op): New location argument.
+ (pointer_diff): Pass location to cp_build_binary_op.
+ (cp_truthvalue_conversion): Pass location to build_binary_op.
+ (convert_ptrmem): Pass location to cp_build_binary_op.
+ (cp_build_modify_expr): Same.
+ (build_ptrmemfunc): Same.
+ * init.c (expand_cleanup_for_base): Pass location to
+ c_common_truthvalue_conversion.
+ (build_new_1): Pass location to cp_build_binary_op.
+ (build_vec_delete_1): Pass location to *build_binary_op,
+ c_common_truthvalue_conversion.
+ (build_vec_init): Same.
+ (build_delete): Same.
+ * decl.c (compute_array_index_type): Same.
+ * call.c (build_new_op): Same.
+ * rtti.c (build_dynamic_cast_1): Same.
+ * cp-tree.h: Add argument to cp_build_binary_op.
+ * semantics.c (handle_omp_for_class_iterator): Pass location to
+ *build_binary_op, c_common_truthvalue_conversion.
+ * decl2.c (get_guard_cond): Same.
+
+2008-09-17 Richard Guenther <rguenther@suse.de>
+
+ PR c++/22374
+ * rtti.c (build_dynamic_cast_1): Convert the COND_EXPR
+ result to the correct type.
+
+2008-09-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/37450
+ * name-lookup.c (pushdecl_maybe_friend): Don't return the old
+ parameter for duplicate.
+
+2008-09-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/37588
+ * name-lookup.c (lookup_type_scope): Look through sk_function_parms.
+
+2008-09-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37552
+ * typeck.c (build_array_ref): Use protected_set_expr_location instead
+ of SET_EXPR_LOCATION when ret might not be an expression.
+
+2008-09-17 Jan Hubicka <jh@suse.cz>
+
+ PR c++/18071
+ * cp/decl.c (start_method): Set DECL_NO_INLINE_WARNING_P.
+
+2008-09-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37531
+ * semantics.c (finish_compound_literal): Return error_mark_node if
+ type is errorneous.
+
+ PR c++/37532
+ * lex.c (init_reswords): Don't populate ridpointers for D_CONLY
+ reserved words.
+
+2008-09-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * decl.c (duplicate_decls): Call error_at.
+ (grokfndecl): New location argument. Use location if available.
+ (grokdeclarator): Pass declarator location to grokfndecl.
+ * cp-tree.h (struct cp_declarator): Update comment for id_loc.
+ * decl2.c (check_classfn): Use error_at.
+ * parser.c (cp_parser_init_declarator): Set function_start_locus
+ to brace location.
+ (cp_parser_member_declaration): Set id_loc for function declarators.
+
+2008-09-09 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/37500
+ * pt.c (tsubst_decl): Do not copy DECL_STRUCT_FUNCTION pointer.
+
+2008-09-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37417
+ * tree.c (array_type_nelts_top): Add size_one_node instead of
+ integer_one_node.
+
+2008-09-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/37439
+ * pt.c (tsubst_copy) [PARM_DECL]: Don't abort if the parm has
+ DECL_CONTEXT set.
+
+2008-09-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37389
+ * decl.c (build_enumerator): Handle previous value's DECL_INITIAL
+ being error_operand_p. Don't clear value if it was error_mark_node.
+
+2008-09-09 Paolo Bonzini <bonzini@gnu.org>
+
+ * cp-objcp-common.h (LANG_HOOKS_EXPAND_DECL): Remove.
+ * cp-tree.h: Don't mention DECL_ANON_UNION_ELEMS.
+ * semantics.c (anon_aggr_type_p): Remove.
+
+2008-09-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/37302
+ * parser.c (cp_parser_parameter_declaration_list): Process the
+ PARM_DECLs as we go and push them. Return a TREE_LIST.
+ (cp_parser_parameter_declaration_clause): Return a TREE_LIST.
+ (cp_parser_direct_declarator): Create a binding level and
+ suppress deprecated warnings in the parameter list.
+ (make_call_declarator): PARMS is now a tree.
+ * cp-tree.h (struct cp_declarator): Function parms are now a tree.
+ * decl.h (enum deprecated_states, deprecated_state): Move here.
+ * decl.c: From here.
+ (type_is_deprecated): New fn.
+ (grokparms): PARMLIST is a tree now. Warn about parms that
+ use deprecated types.
+ * mangle.c (write_expression): Handle PARM_DECL, CALL_EXPR and
+ 0-operand cast.
+ * pt.c (tsubst) [DECLTYPE_TYPE]: Set skip_evaluation.
+ (tsubst_copy) [PARM_DECL]: Handle a PARM_DECL used outside of a
+ function.
+ * name-lookup.c (pushtag): Look through function parameter scopes.
+ (pushdecl_maybe_friend): Don't set DECL_CONTEXT on a PARM_DECL
+ when we're parsing a function declarator.
+
+2008-09-05 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/37342
+ * tree.c (cp_build_qualified_type_real): Deal with sharing of
+ TYPE_LANG_SPECIFIC in the canonical types of pointer-to-method
+ types.
+
+2008-09-04 Ian Lance Taylor <iant@google.com>
+
+ * parser.c (check_no_duplicate_clause): Change code parameter to
+ enum omp_clause_code.
+
+2008-09-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/37348
+ * decl.c (cp_finish_decl): Only set
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P if decl is VAR_DECL.
+
+ PR c++/37189
+ * cp-tree.h (defer_mark_used_calls, deferred_mark_used_calls): New
+ extern decls.
+ * decl2.c (mark_used): If defer_mark_used_calls, push decl into
+ deferred_mark_used_calls vector and exit early.
+ * decl.c (defer_mark_used_calls, deferred_mark_used_calls): New
+ variables.
+ (finish_function): Set defer_mark_used_calls for the duration of the
+ function. Call mark_used on any queued decls.
+
+2008-09-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/37208
+ * call.c (build_over_call): Make =delete work with SFINAE.
+ * class.c (resolve_address_of_overloaded_function): Likewise.
+
+ * cp-tree.h (struct lang_decl_flags): Rename threadprivate_p to
+ threadprivate_or_deleted_p.
+ (CP_DECL_THREADPRIVATE_P): Adjust.
+ (DECL_DELETED_FN): Likewise.
+ (SD_UNINITIALIZED, SD_INITIALIZED, SD_DEFAULTED): New macros.
+ (SD_DELETED): New macro.
+ * parser.c (cp_parser_init_declarator): Use them.
+ * decl.c (start_decl): Use them.
+
+ * decl2.c (mark_used): Give =deleted error even in sizeof.
+
+ * typeck2.c (check_narrowing): Downgrade narrowing error to
+ permerror.
+
+2008-09-02 Aldy Hernandez <aldyh@redhat.com>
+
+ * typeck.c (build_array_ref): Use new location argument.
+ * class.c (build_vtbl_ref_1): Pass location to build_array_ref.
+ * call.c (build_new_op): Same.
+ * decl2.c (grok_array_decl): Same.
+ * cp-tree.h (build_array_ref): Add location argument to prototype.
+
+2008-09-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * typeck.c (build_x_indirect_ref): Add location argument.
+ * class.c (build_base_path): Pass location to build_indirect_ref.
+ * pt.c (tsubst_copy_and_build): Pass location to
+ finish_label_address_expr.
+ * parser.c (cp_parser_unary_expression): Same.
+
+2008-08-31 Jason Merrill <jason@redhat.com>
+
+ Implement late-specified return type using 'auto'.
+ * cp-tree.h (struct cp_declarator): Add late_return_type field to
+ function declarator.
+ * parser.c (cp_parser_late_return_type_opt): New fn.
+ (cp_parser_direct_declarator): Use it.
+ (make_call_declarator): Put it in the declarator.
+ * decl.c (grokdeclarator): Splice in late-specified return type.
+ * pt.c (splice_late_return_type): New fn.
+
+2008-08-29 Michael Meissner <gnu@the-meissners.org>
+
+ * decl.c (builtin_function_1): Take a bool argument to decide
+ whether to use pushdecl or pushdecl_top_level.
+ (duplicate_decls): Copy function specific target and optimization
+ options on duplicate declarations.
+ (cxx_builtin_function): Update builtin_function_1 call.
+ (cxx_builtin_function_ext_scope): New function, guarantee that the
+ declaration is done at global scope.
+
+ * cp-objcp-common.h (LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE): New
+ macro, define builtin function hook for delayed machine specific
+ builtins.
+
+ * cp-tree.h (cxx_builtin_function_ext_scope): Add declaration.
+
+2008-08-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/37288
+ * pt.c (dependent_type_p): Don't abort on auto outside of a template.
+
+2008-08-29 Jason Merrill <jason@redhat.com>
+
+ Implement C++0x 'auto' semantics.
+ * decl.c (start_decl_1): Don't complain about auto being incomplete.
+ (cp_finish_decl): Deduce auto.
+ * init.c (build_new): Handle 'new auto'.
+ * typeck2.c (cxx_incomplete_type_diagnostic): Give a different
+ message for auto than for normal template type parms.
+ * pt.c (type_dependent_expression_p): Handle { }.
+ (make_auto): New function.
+ (listify_autos): New function.
+ (do_auto_deduction): New function.
+ (is_auto): New function.
+ (type_uses_auto): New function.
+ * cp-tree.h: Declare them.
+ * parser.c (cp_parser_decl_specifier_seq): In C++0x mode, don't
+ treat auto as a declspec.
+ (cp_parser_simple_type_specifier): It's a type-specifier.
+
+2008-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_type): Add target-specific manglings for
+ non-fundamental types to the substitution table.
+ gcc/testsuite/
+
+2008-08-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/29635
+ PR fortran/23057
+ * name-lookup.c (do_using_directive, cp_emit_debug_info_for_using):
+ Adjust debug_hooks->imported_module_or_decl callers.
+
+2008-08-29 Jan Hubicka <jh@suse.cz>
+
+ * cp-gimplify.c (cp_gimplify_expr): Add PRED_CONTINUE heuristic.
+
+2008-08-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/37260
+ * decl.c (reshape_init_r): Check init for error_mark_node.
+
+2008-08-27 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/17880
+ * semantics.c (maybe_convert_cond): Call verify_sequence_points.
+ (finish_return_stmt): Likewise.
+ (finish_switch_condition): Likewise.
+
+2008-08-27 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * cp-tree.h: Fix #error directive.
+
+2008-08-26 Douglas Gregor <doug.gregor@gmail.com>
+
+ * typeck.c (type_after_usual_arithmetic_conversions): Don't do the
+ usual arithmetic conversions on scoped enumeration types.
+ (common_type): Ditto.
+ (default_conversion): Don't perform integral promotions on scoped
+ enumeration types.
+ (build_array_ref): Scoped enumeration types can't be used as
+ subscripts.
+ * decl.c (start_enum): If building a C++0x scoped enumeration,
+ enter its scope. If provided with an underlying type, check that
+ underlying type and set up the enumeration type accordingly.
+ (finish_enum): Only compute an underlying type if the underlying
+ type isn't already fixed, and only convert the enumerator values
+ now if we've just computed the underlying type. Finish the scope
+ of C++0x scoped enumerations.
+ (build_enumerator): For enumerations with a fixed underlying type,
+ check the enumerator values when the enumerator is defined.
+ (lookup_enumerator): New.
+ * call.c (standard_conversion): Don't allow assignment from
+ integers to scoped enumeration types, even with -fpermissive.
+ Don't convert from scoped enumerations to bool or any arithmetic
+ types.
+ (build_conditional_expr): Don't per the usual arithmetic
+ conversions for scoped enumeration types.
+ (convert_like_real): Check complain to see if we should
+ produce warnings.
+ * error.c (class_key_or_enum_as_string): Print scoped enums.
+ * cp-tree.h (MAYBE_CLASS_TYPE_P): Check CLASS_TYPE_P, not
+ TYPE_LANG_FLAG_5.
+ (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P): New.
+ (SCOPED_ENUM_P): New.
+ (UNSCOPED_ENUM_P): New.
+ (SET_SCOPED_ENUM_P): New.
+ (ENUM_UNDERLYING_TYPE): New.
+ * pt.c (lookup_template_class): Update the instantiation of enum
+ types to deal with C++0x scoped enumerations and underlying
+ types.
+ * name-lookup.c (begin_scope): Deal with scoped enumeration
+ scopes.
+ (lookup_qualified_name): Deal with lookup into enumeration types.
+ * name-lookup.h (enum scope_kind): Add sk_scoped_enum.
+ * parser.c (cp_parser_class_or_namespace_name): Rename to...
+ (cp_parser_qualifying_entity): ... this. Also, in C++0x mode,
+ parse a type-name that can be an enumeration type.
+ (cp_parser_nested_name_specifier_opt): Update with C++0x grammar.
+ (cp_parser_elaborated_type_specifier): Parse the
+ optional `struct' or `class' following enum (in C++0x).
+ (cp_parser_enum_specifier): Parse C++0x scoped enumerations and
+ enum-base clauses.
+
+2008-08-21 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * typeck.c: Update all calls to pedwarn.
+ * decl.c: Likewise.
+ * call.c: Likewise.
+ * error.c: Likewise.
+ * pt.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+
+2008-08-20 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/35158
+ * parser.c (cp_parser_omp_for_loop): Handle parenthesized
+ initializers.
+
+2008-08-20 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * parser.c: Update all calls to inform.
+ * typeck.c: Likewise.
+ * init.c: Likewise.
+ * class.c: Likewise.
+ * call.c: Likewise.
+ * method.c: Likewise.
+ * friend.c: Likewise.
+ * typeck2.c: Likewise.
+ * pt.c: Likewise.
+ * name-lookup.c: Likewise.
+ * lex.c: Likewise.
+
+2008-08-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/37156
+ * error.c (cp_print_error_function): Deal with recursive BLOCK trees.
+
+2008-08-18 Tomas Bily <tbily@suse.cz>
+
+ * tree.c (cp_tree_equal): Use CONVERT_EXPR_CODE_P.
+
+2008-08-18 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * typeck.c: Update all callers of permerror.
+ * init.c: Likewise.
+ * class.c: Likewise.
+ * decl.c: Likewise.
+ * call.c: Likewise.
+ * except.c: Likewise.
+ * cvt.c: Likewise.
+ * typeck2.c: Likewise.
+ * pt.c: Likewise.
+ * semantics.c: Likewise.
+ * name-lookup.c: Likewise.
+ * lex.c: Likewise.
+ * decl2.c: Likewise.
+ * parser.c: Likewise.
+
+2008-08-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/34485
+ * pt.c (check_template_shadow): Change to return a bool.
+ * name-lookup.c (push_class_level_binding): Early return if
+ check_template_shadow returns false.
+ * cp-tree.h (check_template_shadow): Adjust declaration.
+
+2008-08-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/34600
+ * decl.c (grokdeclarator): In case of extern and initializer, return
+ error_mark_node after the error.
+
+2008-08-13 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 30551
+ * decl.c (grokfndecl): Call check_main_parameters_type only if
+ -Wmain.
+
+2008-08-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/37087
+ * parser.c (cp_parser_class_head): Early return error_mark_node in
+ case of global qualification of class name or qualified name that
+ does not name a class.
+
+2008-08-09 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/12242
+ * cvt.c (ocp_convert): Warn for out-of-range conversions to enum.
+
+2008-08-09 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 36901
+ * cp-tree.h (struct diagnostic_context, struct diagnostic_info):
+ Delete forward declarations. Check that toplev.h has not been
+ included before this file. Include toplev.h and diagnostic.h.
+ * error.c (cp_cpp_error): Use DK_PEDWARN.
+ (cxx_incomplete_type_diagnostic): Update declaration.
+ (cxx_incomplete_type_error): Use DK_ERROR.
+ * typeck2.c (cxx_incomplete_type_diagnostic): Take a diagnostic_t
+ as argument. Use emit_diagnostic.
+ (cxx_incomplete_type_error): Use DK_ERROR.
+ (add_exception_specifier): Use diagnostic_t instead of custom
+ codes.
+ * typeck.c (complete_type_or_else): Update call to
+ cxx_incomplete_type_diagnostic.
+ * init.c (build_delete): Likewise.
+ * call.c (diagnostic_fn_t): Remove unused typedef.
+ (build_temp): Pass a pointer to diagnostic_t.
+ (convert_like_real): Use emit_diagnostic.
+ (joust): Check return value of warning before giving informative
+ note.
+ * friend.c (do_friend): Check return value of warning
+ before giving informative note.
+ * parser.c (cp_parser_template_id): Likewise.
+
+2008-08-09 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 7651
+ * class.c (check_bases_and_members): Warn with -Wuninitialized
+ instead of -Wextra.
+
+2008-08-08 Volker Reichelt <v.reichelt@netcologne.de>
+
+ PR c++/35985
+ * decl.c (xref_basetypes): Check base for MAYBE_CLASS_TYPE_P,
+ and make sure it is not a union.
+
+2008-08-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * semantics.c (finish_decltype_type): Initialize type.
+
+2008-08-07 Douglas Gregor <doug.gregor@gmail.com>
+
+ * semantics.c (finish_decltype_type): Handle calls to function
+ pointers and references to functions properly.
+
+2008-08-06 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/36460
+ * parser.c (cp_parser_template_argument): Don't assume that '>>'
+ following a type-id is an error when in C++0x mode.
+
+2008-08-06 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 26785
+ * decl.c (grokdeclarator): Use explicit location with permerror_at.
+
+2008-08-06 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 8715
+ * typeck.c (cp_build_binary_op): Move code to c-common.c.
+
+2008-08-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/37016
+ * decl.c (build_ptrmemfunc_type): Don't require structural
+ comparison of PMF types.
+ * tree.c (cp_build_qualified_type_real): Don't clear
+ a valid TYPE_PTRMEMFUNC_TYPE.
+ * typeck.c (cp_build_unary_op): Still do build_ptrmemfunc in
+ templates.
+
+2008-08-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/36963
+ * typeck2.c (check_narrowing): Allow narrowing conversion
+ from an explicit floating-point constant.
+
+ PR c++/37006
+ * pt.c (tsubst_decl): Leave DECL_INITIAL set on deleted
+ instantiations.
+
+2008-08-04 Simon Baldwin <simonb@google.com>
+
+ PR c++/36999
+ * parser.c (cp_parser_elaborated_type_specifier): Warn only when
+ the declaration's id is followed by a semicolon.
+
+2008-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/36405
+ * rtti.c (get_tinfo_decl_dynamic, get_typeid): Call
+ complete_type_or_else even for UNKNOWN_TYPE to get diagnostics.
+
+2008-07-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/36633
+ * init.c (build_new_1): Don't convert pointer to the data type
+ until we're actually going to treat it as that type.
+
+ PR c++/11309
+ * tree.c (build_aggr_init_expr): Split out...
+ (build_cplus_new): ...from here.
+ (stabilize_init): Don't mess with AGGR_INIT_EXPR either.
+ * init.c (build_new_1): new T() means value-initialization,
+ not default-initialization.
+ (build_vec_init): Likewise.
+ (build_value_init_1): Use build_aggr_init_expr.
+
+2008-07-30 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/36767
+ * decl2.c (fix_temporary_vars_context_r): New function.
+ (one_static_initialization_or_destruction): Make sure temporary
+ variables part of the initialiser have their DECL_CONTEXT()
+ properly set.
+
+2008-07-30 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 34389
+ * typeck.c (build_binary_op): Encapsulate code into
+ shorten_binary_op.
+
+2008-07-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/36852
+ * tree.c (cplus_array_hash, build_cplus_array_type_1): Hash on
+ TYPE_UID instead of pointers.
+
+2008-07-29 Jan Hubicka <jh@suse.cz>
+
+ * optimize.c (maybe_clone_body): Remove DECL_INLINE.
+ * decl.c (duplicate_decls): Likewise.
+ (grokfndecl): Likewise.
+ (start_method): Likewise.
+ * method.c (make_thunk, make_alias_for, implicitly_declare_fn):
+ Likewise.
+ * pt.c (register_specialization, regenerate_decl_from_template):
+ Likewise.
+ * decl2.c (grokfield): Likewise.
+
+2008-07-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 34985
+ * decl.c (duplicate_decls): Merge USED flags.
+
+2008-07-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/36943
+ * decl.c (reshape_init_r): Allow C++0x initializer lists.
+
+2008-07-28 Richard Guenther <rguenther@suse.de>
+
+ Merge from gimple-tuples-branch.
+
+ 2008-07-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_if_stmt): Set location on newly created
+ COND_EXPR.
+
+ 2008-07-18 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (finish_function): Call gimple_body after cp_genericize.
+
+ 2008-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * optimize.c: Include gimple.h instead of tree-gimple.h.
+ * Make-lang.in (cp-gimplify.o): Depend on tree-iterator.h.
+ * cp-gimplify.c: Rename tree-gimple.h to gimple.h. Include
+ tree-iterator.h.
+
+ 2008-07-16 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (maybe_clone_body): Clear DECL_SAVED_TREE for the clone.
+
+ 2008-07-14 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c (cp_gimplify_expr): Update comment.
+
+ 2008-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-tree.h (union lang_tree_node): Rename GENERIC_NEXT to
+ TREE_CHAIN.
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Rename
+ GIMPLE_MODIFY_STMT to MODIFY_EXPR.
+ (cxx_omp_clause_copy_ctor): Same.
+ (cxx_omp_clause_assign_op): Same.
+
+ 2008-05-28 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c (cp_gimplify_omp_for): Add pre_p argument. Tuplify.
+ (cp_gimplify_expr): Adjust caller.
+
+ 2008-05-11 Doug Kwan <dougkwan@google.com>
+
+ * init.c (build_vec_delete): Add type conversion for argument
+ 0 of POINTER_PLUS_EXPR.
+
+ 2008-04-29 Doug Kwan <dougkwan@google.com>
+
+ * decl2 (File): Include "gimple.h"
+ (cp_write_global_declarations): Use gimple_body instead of
+ DECL_SAVED_TREE.
+ * Make-lang.in (cp/decl2.o): Add $(GIMPLE_H)
+
+ 2008-04-10 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00913.html
+
+ * optimize.c (maybe_clone_body): Re-enable call to
+ clone_body.
+ * cp-gimplify.c (cp_gimplify_omp_for): Mark disabled
+ code with call to gimple_unreachable.
+ (cp_genericize): Fix handling of clone bodies.
+
+ 2008-04-04 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00413.html
+
+ * optimize.c (maybe_clone_body): Re-enable.
+
+ 2008-02-19 Diego Novillo <dnovillo@google.com>
+ Oleg Ryjkov <olegr@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00804.html
+
+ * cp-gimplify.c (gimplify_for_stmt): Change gimple_seq
+ argument to gimple_seq *. Update all users.
+ (gimplify_must_not_throw_expr): Likewise.
+
+ 2008-02-04 Oleg Ryjkov <olegr@google.com>
+
+ * except.c: Include gimple.h
+ (cp_protect_cleanup_actions): Convert to tuples.
+ * Make-lang.in (cp/except.o): Add dependency on gimple.h
+
+ 2007-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_cp_loop): Call tree_annotate_all_with_locus
+ instead of annotating each block manually.
+
+ 2007-10-30 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_cp_loop): Tuplify.
+ (gimplify_for_stmt): Same.
+ (gimplify_switch_stmt): Same.
+ (cp_gimplify_expr): [FOR_STMT]: Do not call gimplify_for_stmt. Return
+ GS_OK.
+ [WHILE_STMT]: Return GS_OK.
+ [SWITCH_STMT]: Same.
+ [CONTINUE_STMT]: Same.
+ [BREAK_STMT]: Same.
+ (cp_genericize): Set gimple_body() of cloned functions when needed.
+
+ 2007-10-29 Aldy Hernandez <aldy@quesejoda.com>
+
+ * cp-gimplify.c: Move build_gimple_eh_filter_tree here.
+ (cp_gimplify_init_expr): Convert to tuples.
+ (gimplify_must_not_throw_expr): Make function return a
+ gimplify_status and convert to tuples.
+
+ 2007-10-18 Aldy Hernandez <aldy@quesejoda.com>
+
+ * cp-gimplify.c (genericize_try_block): Enable and do not call
+ gimplify_stmt.
+ (genericize_catch_block): Same.
+ (genericize_eh_spec_block): Same.
+ Rename gimple_build_eh_filter_tree to build_gimple_eh_filter_tree.
+ (cp_gimplify_expr): Enable TRY_BLOCK, HANDLER, and EH_SPEC_BLOCK.
+
+ 2007-10-16 Aldy Hernandez <aldy@quesejoda.com>
+
+ * optimize.c (maybe_clone_body): Comment out call to clone_body.
+ * decl.c (finish_function): Use gimple_body instead of
+ DECL_SAVED_TREE.
+ * cp-tree.h (cp_gimplify_expr): Last 2 arguments are sequences.
+ * cp-gimplify.c (genericize_try_block): Comment out.
+ (genericize_catch_block): Same.
+ (genericize_eh_spec_block): Same.
+ (gimplify_cp_loop): Comment out calls to gimplify_stmt.
+ (gimplify_for_stmt): Comment out.
+ (gimplify_switch_stmt): Comment out call to gimplify_stmt.
+ (cp_gimplify_omp_for): Same.
+ (gimplify_must_not_throw_expr): Argument pre_p is a sequence.
+ Comment out call to gimplify_stmt and append_to_statement_list.
+ Rename gimple_build_eh_filter_tree to build_gimple_eh_filter_tree.
+ (cp_gimplify_init_expr): Arguments pre_p and post_p are sequences.
+ (cp_gimplify_expr): Same.
+ Comment out calls to genericize_*_block. Comment out call to
+ gimplify_for_stmt.
+
+2008-07-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/36944
+ * class.c (type_has_user_provided_default_constructor): Handle
+ default parameters.
+
+2008-07-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (push_library_fn): Add a parameter for the exceptions that
+ the function may throw.
+ (push_void_library_fn, push_throw_library_fn, expand_static_init):
+ Adjust.
+ (build_library_fn): Change to static.
+ * cp-tree.h: Adjust declarations.
+ * except.c (declare_nothrow_library_fn): New.
+ (do_get_exception_ptr, do_begin_catch, do_free_exception,
+ do_allocate_exception): Use the latter, adjust the declarations
+ (ie, add empty exception-specification), consistently with the
+ actual implementation in libsupc++.
+
+2008-07-25 Jan Hubicka <jh@suse.cz>
+
+ * typeck.c (inline_conversion): Remove.
+ (cp_build_function_call): Do not use inline_conversion.
+ * decl.c (duplicate_decls): Do not insist on inline being declared
+ early.
+ (start_cleanup_fn): Do not assume that INLINE flags prevent function
+ from being output. We now remove static functions always.
+ (finish_function): Do return warning on all static functions.
+ * call.c (build_over_call): Do not use inline_conversion.
+ * cp-tree.h (possibly_inlined_p): Declare.
+ (inline_conversion): Remove.
+ * pt.c (instantiate_decl): Use possibly_inlined_p predicate.
+ * decl2.c (cp_write_global_declarations): Likewise.
+ (mark_used): Likewise.
+ (possibly_inlined_p): New functions.
+
+2008-07-25 Jason Merrill <jason@redhat.com>
+
+ * class.c (type_has_user_provided_default_constructor): Handle
+ templates.
+
+2008-07-23 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (duplicate_decls): Update comment and unit-at-a-time.
+ (grogfndecl): Drop flag_inline_trees code.
+ * pt.c (instantiate_decl): Drop flag_iline_trees code.
+ * lex.c (cxx_init): Do not set unit-at-a-time.
+
+2008-07-23 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_unqualified_name): Avoid infinite recursion when
+ trying to mangle a decl with no name.
+
+ Implement defaulted/deleted functions as per N2346
+ * cp-tree.h (struct lang_decl_flags): Add defaulted_p bitfield.
+ (DECL_DELETED_FN): New macro.
+ (DECL_DEFAULTED_FN): New macro.
+ * class.c (user_provided_p): New fn.
+ (defaultable_fn_p): New fn.
+ (type_has_user_provided_constructor): New fn.
+ (type_has_user_provided_default_constructor): New fn.
+ (check_methods): A defaulted fn is still trivial.
+ (check_bases_and_members): Likewise.
+ * decl.c (grok_special_member_properties): Likewise.
+ (duplicate_decls): Complain about redeclaring a function as deleted.
+ (start_decl): initialized==2 means deleted.
+ (cp_finish_decl): Handle deleted/defaulted semantics.
+ * decl2.c (grokfield): Likewise.
+ (mark_used): Check DECL_DEFAULTED_FN instead of DECL_ARTIFICIAL.
+ Complain about using a deleted fn.
+ * init.c (build_value_init_1): Use type_has_user_provided_constructor.
+ (perform_member_init): Check for a user-provided default constructor
+ even if TYPE_NEEDS_CONSTRUCTING.
+ (build_new_1): Likewise.
+ * call.c (build_over_call): Don't call mark_used twice.
+ * method.c (implicitly_declare_fn): Set DECL_DEFAULTED_FN.
+ * search.c (check_final_overrider): Check for deleted mismatch.
+ * parser.c (cp_parser_init_declarator): Tell start_decl about =delete.
+ (cp_parser_pure_specifier): Handle =default and =delete.
+
+ * error.c (maybe_warn_cpp0x): Suggest -std=gnu++0x as well.
+
+2008-07-23 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 35058
+ * typeck.c: All calls to pedwarn changed.
+ * decl.c: All calls to pedwarn changed.
+ * call.c: All calls to pedwarn changed.
+ * error.c: All calls to pedwarn changed.
+ * typeck2.c: All calls to pedwarn changed.
+ * pt.c: All calls to pedwarn changed.
+ * name-lookup.c: All calls to pedwarn changed.
+ * parser.c: All calls to pedwarn changed.
+
+2008-07-21 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * call.c: Fix comment typos.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cxx-pretty-print.c: Likewise.
+ * decl.c: Likewise.
+ * init.c: Likewise.
+ * name-lookup.c: Likewise.
+ * operators.def: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2008-07-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36871
+ PR c++/36872
+ * semantics.c (classtype_has_nothrow_assign_or_copy_p): Only check
+ copy constructors and copy assignment operators proper.
+
+2008-07-21 Rafael Ávila de Espíndola <espindola@google.com>
+
+ * parser.c (cp_token): Remove in_system_header.
+ (eof_token): Remove in_system_header.
+ (cp_lexer_get_preprocessor_token): Don't set in_system_header.
+ (cp_lexer_set_source_position_from_token): Don't set in_system_header.
+ (cp_parser_member_declaration): Use in_system_header_at.
+ * pt.c (lookup_template_class): Don't set DECL_IN_SYSTEM_HEADER.
+ (pop_tinst_level): Don't set in_system_header.
+ (instantiate_class_template): Don't set in_system_header.
+ (instantiate_decl): Don't set in_system_header.
+ (instantiate_pending_templates): Don't set in_system_header.
+
+2008-07-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36870
+ * semantics.c (classtype_has_nothrow_assign_or_copy_p): Use
+ TYPE_NOTHROW_P, not TREE_NOTHROW.
+ (trait_expr_value): Likewise.
+
+2008-07-18 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/36407
+ * call.c (convert_like_real): Don't take the error code path
+ when a rvalue or base conversion has the bad_p field set.
+
+2008-07-18 Kris Van Hees <kris.van.hees@oracle.com>
+
+ * rtti.c (emit_support_tinfos): Add char16_type_node and
+ char32_type_node.
+ * typeck2.c (digest_init): Support char16_t and char32_t.
+
+2008-07-18 Kavih R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cvt.c (convert_to_void): Avoid C++ keywords.
+ * decl.c (walk_namespaces_r, wrapup_globals_for_namespace):
+ Likewise.
+ * friend.c (is_friend): Likewise.
+ * init.c (perform_member_init): Likewise.
+ * mangle.c (write_template_prefix, write_template_template_param):
+ Likewise.
+ * name-lookup.c (do_namespace_alias, do_using_directive,
+ parse_using_directive, ambiguous_decl, arg_assoc): Likewise.
+ * parser.c (cp_parser_template_id, cp_parser_namespace_definition,
+ cp_parser_objc_typename, cp_parser_objc_method_keyword_params):
+ Likewise.
+ * pt.c (is_specialization_of_friend, lookup_template_class,
+ push_tinst_level, instantiate_class_template,
+ tsubst_copy_and_build): Likewise.
+ * tree.c (add_stmt_to_compound): Likewise.
+ * typeck.c (finish_class_member_access_expr): Likewise.
+
+2008-07-17 Julian Brown <julian@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (determine_visibility): Allow target to override
+ visibility of class data.
+
+2008-07-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36855
+ * semantics.c (trait_expr_value): Update __has_trivial_destructor
+ semantics to the current WP (N2691).
+
+2008-07-16 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/13699
+ * name-lookup.c (lookup_extern_c_fun_binding_in_all_ns): New function.
+ (pushdecl_maybe_friend): Check if a redeclaration of extern C function
+ complies with exception specification constraints.
+
+2008-07-14 Jason Merrill <jason@redhat.com>
+
+ * lex.c (init_reswords): Always set D_OBJC.
+
+2008-07-11 Tom Tromey <tromey@redhat.com>
+ Ian Lance Taylor <iant@google.com>
+
+ * lex.c (struct resword, reswords): Don't define.
+ (D_EXT, D_ASM, D_OBJC, D_CXX0X): Don't define.
+ (init_reswords): Clarify mask code. Use c_common_reswords rather
+ than reswords.
+
+2008-07-11 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/13101
+ * decl.c (grokdeclarator): Warn about initializing variables
+ of storage class 'extern' only after the type of the declarator
+ has been properly computed.
+
+2008-07-11 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/31754
+ * cp-tree.h (struct cp_decl_specifier_seq): Add a location field. It
+ carries the location of the primary type.
+ * parser.c (cp_parser_check_type_definition): Update documentation.
+ (cp_parser_check_for_definition_in_return_type,
+ cp_parser_check_for_invalid_template_id,
+ cp_parser_set_decl_spec_type,
+ cp_parser_check_for_definition_in_return_type,
+ cp_parser_diagnose_invalid_type_name,
+ cp_parser_new_expression, cp_parser_explicit_instantiation,
+ cp_parser_type_specifier, cp_parser_simple_type_specifier,
+ cp_parser_omp_for_loop, cp_parser_pragma): Use location in error
+ messages.
+
+2008-07-11 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/31754
+ * pt.c, semantic.c:
+ * semantic.c (qualified_name_lookup_error, finish_id_expression):
+ Add a location_t parameter so that
+ error message can have a more accurate location.
+ * cp-tree.h: Updated prototype
+ * pt.c (tsubst_qualified_id): Use location in error messages.
+ * parser.c (cp_parser_postfix_expression,
+ cp_parser_objc_statement, cp_parser_trait_expr,
+ cp_parser_token_is_class_key,
+ cp_parser_uncommitted_to_tentative_parse_p,
+ cp_parser_check_for_invalid_template_id, cp_parser_is_string_literal,
+ cp_parser_error, cp_parser_name_lookup_error,
+ cp_parser_simulate_error, cp_parser_check_decl_spec,
+ cp_parser_check_decl_spec, cp_parser_non_integral_constant_expression,
+ cp_parser_diagnose_invalid_type_name,
+ cp_parser_parse_and_diagnose_invalid_type_name,
+ cp_parser_require_pragma_eol, cp_parser_make_typename_type,
+ cp_parser_string_literal, cp_parser_primary_expression,
+ cp_parser_primary_expression, cp_parser_unqualified_id,
+ cp_parser_nested_name_specifier_opt, cp_parser_postfix_expression,
+ cp_parser_postfix_dot_deref_expression, cp_parser_new_expression,
+ cp_parser_direct_new_declarator, cp_parser_builtin_offsetof,
+ cp_parser_label_for_labeled_statement, cp_parser_statement_seq_opt,
+ cp_parser_jump_statement, cp_parser_block_declaration,
+ cp_parser_simple_declaration, cp_parser_decl_specifier_seq,
+ cp_parser_function_specifier_opt, cp_parser_decltype,
+ cp_parser_mem_initializer_list, cp_parser_mem_initializer,
+ cp_parser_mem_initializer_id, cp_parser_template_parameter,
+ cp_parser_type_parameter, cp_parser_template_id,
+ cp_parser_template_name, cp_parser_template_argument): Likewise.
+
+2008-07-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36760
+ * pt.c (tsubst_function_type): Remove warning for type qualifiers
+ on function return type.
+
+2008-07-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36760
+ * pt.c (tsubst_function_type): Don't warn for type qualifiers
+ on function return type in case of system header.
+
+2008-07-09 Raksit Ashok <raksit@google.com>
+
+ * parser.c (cp_parser_postfix_expression): New warning based on flag
+ warn_disallowed_functions.
+
+2008-07-08 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/34963
+ * decl.c (grokdeclarator): Reset storage_class and staticp for friend
+ functions declared with a storage class qualifier.
+
+2008-07-03 Richard Guenther <rguenther@suse.de>
+
+ PR c++/36128
+ * typeck.c (cp_build_function_call): Move code to verify
+ builtin function arguments ...
+ * call.c (build_cxx_call): ... here.
+
+2008-07-02 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (cp/typeck2.o): Add $(REAL_H) dependency.
+
+ Implement WG21 N2672, Initializer List proposed wording
+ * cp-tree.h (enum cp_tree_index): Add CPTI_INIT_LIST_TYPE.
+ (struct lang_type_class): Add has_list_ctor bitfield.
+ (TYPE_HAS_LIST_CTOR): New macro.
+ (BRACE_ENCLOSED_INITIALIZER_P): Expect init_list_type_node.
+ (CONSTRUCTOR_IS_DIRECT_INIT): New macro.
+ (LOOKUP_NO_NARROWING): New macro.
+ (LOOKUP_NO_COPY_CTOR_CONVERSION): New macro.
+ * parser.c (cp_parse_braced_list): Split out from...
+ (cp_parser_initializer_clause): ...here.
+ (cp_parser_postfix_expression): Build up CONSTRUCTOR for compound
+ literal here.
+ (cp_lexer_next_token_is_not_keyword): New fn.
+ (cp_parser_parenthesized_expression_list): Handle { }.
+ (cp_parser_new_expression, cp_parser_new_initializer): Likewise.
+ (cp_parser_assignment_expression, cp_parser_condition): Likewise.
+ (cp_parser_jump_statement, cp_parser_simple_declaration): Likewise.
+ (cp_parser_mem_initializer, cp_parser_init_declarator): Likewise.
+ (cp_parser_initializer, cp_parser_functional_cast): Likewise.
+ (cp_parser_omp_for_loop, cp_parser_cache_group): Likewise.
+ (cp_parser_save_member_function_body): Likewise.
+ * call.c (conversion_kind): Add ck_list, ck_aggr.
+ (struct conversion): Add check_narrowing bitfield, conversion list.
+ (build_list_conv): New fn.
+ (build_aggr_conv): New fn.
+ (implicit_conversion): Call them.
+ (standard_conversion): Set check_narrowing if appropriate.
+ (add_function_candidate): Handle LOOKUP_NO_COPY_CTOR_CONVERSION.
+ (build_user_type_conversion_1): When converting from an init list,
+ we allow additional conversions except when calling a copy ctor.
+ (convert_like_real): Calling an explicit ctor for an init list is
+ ill-formed. Handle ck_list and ck_addr. Check narrowing.
+ (build_new_method_call): If CONSTRUCTOR_IS_DIRECT_INIT is set and
+ class doesn't have a list ctor, break the {} into a TREE_LIST.
+ (compare_ics): ck_list is better than other UDCs.
+ (set_up_extended_ref_temp): Split out from initialize_reference.
+ (is_std_init_list): New fn.
+ (is_list_ctor): New fn.
+ * decl.c (cxx_init_decl_processing): Create init_list_type_node.
+ (reshape_init_array_1): Pass it to build_constructor.
+ (reshape_init_class): Ditto.
+ (initialize_artificial_var): Pass the appropriate type.
+ (build_aggr_init_full_exprs): Split out from...
+ (check_initializer): ...here. Handle new semantics.
+ (build_init_list_var_init): New subroutine of check_initializer.
+ (grokdeclarator): Converting constructors can have more than one parm.
+ (grok_special_member_properties): Set TYPE_HAS_LIST_CTOR.
+ * init.c (expand_default_init): Only do digest_init for aggregates.
+ * rtti.c (tinfo_base_init): Pass init_list_type_node to
+ build_constructor_from_list.
+ (generic_initializer, ptr_initializer): Ditto.
+ (ptm_initializer, class_initializer): Ditto.
+ (get_pseudo_ti_init): Ditto.
+ * error.c (dump_type): Handle init_list_type_node.
+ (maybe_warn_cpp0x): New fn.
+ (maybe_varn_variadic_templates): Call it.
+ * cvt.c (ocp_convert): Handle conversion from { }.
+ * tree.c (build_array_of_n_type): New fn.
+ * typeck2.c (store_init_value): Use init_list_type_node.
+ (digest_init): Likewise.
+ (check_narrowing): New fn.
+ * semantics.c: (finish_compound_literal): Take CONSTRUCTOR instead
+ of vector of constructor elts. Handle non-aggregate types. Make
+ constant literals static.
+ * pt.c: (tsubst_copy_and_build): Adjust.
+ (unify): Handle { }.
+ * name-lookup.c (arg_assoc_type): Handle init_list_type_node.
+
+2008-07-01 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * typeck.c (comp_ptr_ttypes_real): Use vector_targets_convertible_p.
+ (comp_ptr_ttypes_const): Likewise.
+
+2008-07-01 Andrew Haley <aph@redhat.com>
+
+ * decl.c (finish_constructor_body): Don't set the return value of
+ the constructor if the constructor is that of a Java type.
+
+2008-06-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/36662
+ * decl2.c (is_late_template_attribute): If the first attribute
+ argument is IDENTIFIER_NODE, don't consider it when checking
+ if arguments are value or type dependent.
+
+2008-06-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36655
+ * pt.c (do_type_instantiation): In c++0x mode do not warn for
+ extern template.
+
+2008-06-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (cp-warn): Delete $(CXX_COMPAT_WARN).
+
+2008-06-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/36364
+ * repo.c (repo_emit_p): Put const static data members initialized
+ by const expr into *.rpo file, just return 2 if IDENTIFIER_REPO_CHOSEN
+ for it is 0.
+
+2008-06-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36655
+ * pt.c (do_decl_instantiation): In c++0x mode do not warn for
+ extern template.
+
+2008-06-24 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR c++/23194
+ * typeck.c (cp_build_function_call): Show example syntax in
+ diagnostic.
+
+2008-06-21 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * typeck.c (composite_pointer_type_r, cxx_sizeof_expr,
+ cxx_alignof_expr, check_template_keyword, cp_build_binary_op,
+ pointer_diff, cp_build_unary_op, build_x_compound_expr_from_list,
+ build_reinterpret_cast_1, cp_build_c_cast, check_return_expr): Change
+ pedwarn to permerror.
+ * init.c (perform_member_init, build_new_1, build_new): Likewise.
+ * decl.c (warn_extern_redeclared_static, duplicate_decls,
+ * identify_goto, check_previous_goto_1, check_goto, define_label,
+ check_tag_decl, start_decl, check_class_member_definition_namespace,
+ grokfndecl, grokdeclarator): Likewise.
+ * except.c (check_handlers): Likewise.
+ * typeck2.c (digest_init): Likewise.
+ * pt.c (check_specialization_namespace,
+ check_explicit_instantiation_namespace,
+ maybe_process_partial_specialization, check_explicit_specialization,
+ convert_template_argument, do_decl_instantiation,
+ do_type_instantiation, instantiate_decl): Likewise.
+ * semantics.c (finish_template_type_parm): Likewise.
+ * name-lookup.c (pushdecl_maybe_friend,
+ check_for_out_of_scope_variable): Likewise.
+ * decl2.c (finish_static_data_member_decl, build_anon_union_vars,
+ coerce_new_type): Likewise.
+ * parser.c (cp_parser_nested_name_specifier_opt,
+ cp_parser_mem_initializer, cp_parser_elaborated_type_specifier,
+ cp_parser_class_head, cp_parser_check_class_key): Likewise.
+ (cp_parser_parameter_declaration): Check flag_permissive instead of
+ flag_pedantic_errors.
+ * call.c (joust): Change pedwarn to warning.
+ * friend.c (make_friend_class): Likewise.
+
+2008-06-16 Jan Hubicka <jh@suse.cz>
+
+ * method.c: Include cgraph.h.
+ (use_thunk): Use cgraph_add_new_function instead of calling backend
+ directly.
+
+2008-06-15 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * parser.c: Fix comment typo.
+
+2008-06-14 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/35320
+ * decl2.c (grokbitfield): Receive the list of attributes, pass it to
+ grokdeclarator and apply it to the created declaration.
+ * cp-tree.h (grokbitfield): Update prototype.
+ * parser.c (cp_parser_member_declaration): Don't apply the attributes
+ since they are now applied in grokbitfield. Adjusted the call to
+ grokbitfield.
+ (cp_parser_objc_class_ivars): Likewise.
+
+2008-06-14 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/35317
+ * class.c (type_requires_array_cookie): Do not consider delete[]
+ operators with an ellipsis as second argument.
+
+2008-06-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/36408
+ * semantics.c (stmt_expr_value_expr): Don't crash on empty
+ STATEMENT_LIST.
+
+2008-06-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/35242
+ * pt.c (maybe_process_partial_specialization): Check the tree
+ returned by push_template_decl for error_mark_node.
+ * parser.c (cp_parser_class_head): Likewise, check the tree
+ returned by the latter.
+
+2008-06-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/35327
+ * decl.c (grokdeclarator): In case of wrong return type return
+ immediately error_mark_node.
+
+2008-06-06 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (cxx_omp_finish_clause, cxx_omp_create_clause_info,
+ dependent_omp_for_p, begin_omp_task, finish_omp_task,
+ finish_omp_taskwait): New prototypes.
+ (cxx_omp_clause_default_ctor): Add outer argument.
+ (finish_omp_for): Add new clauses argument.
+ * cp-gimplify.c (cxx_omp_finish_clause): New function.
+ (cxx_omp_predetermined_sharing): Moved from semantics.c, rewritten.
+ (cxx_omp_clause_default_ctor): Add outer argument.
+ (cp_genericize_r): Walk OMP_CLAUSE_LASTPRIVATE_STMT.
+ * cp-objcp-common.h (LANG_HOOKS_OMP_FINISH_CLAUSE): Define.
+ * parser.c (cp_parser_omp_for_loop): Parse collapsed for loops.
+ Add par_clauses argument. If decl is present in parallel's
+ lastprivate clause, change that clause to shared and add
+ a lastprivate clause for decl to OMP_FOR_CLAUSES.
+ Fix wording of error messages. Adjust finish_omp_for caller.
+ Add clauses argument. Parse loops with random access iterators.
+ (cp_parser_omp_clause_collapse, cp_parser_omp_clause_untied): New
+ functions.
+ (cp_parser_omp_for, cp_parser_omp_parallel): Adjust
+ cp_parser_omp_for_loop callers.
+ (cp_parser_omp_for_cond, cp_parser_omp_for_incr): New helper
+ functions.
+ (cp_parser_omp_clause_name): Handle collapse and untied
+ clauses.
+ (cp_parser_omp_clause_schedule): Handle auto schedule.
+ (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_COLLAPSE
+ and PRAGMA_OMP_CLAUSE_UNTIED.
+ (OMP_FOR_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_COLLAPSE.
+ (OMP_TASK_CLAUSE_MASK): Define.
+ (cp_parser_omp_task, cp_parser_omp_taskwait): New functions.
+ (cp_parser_omp_construct): Handle PRAGMA_OMP_TASK.
+ (cp_parser_pragma): Handle PRAGMA_OMP_TASK and
+ PRAGMA_OMP_TASKWAIT.
+ * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_COLLAPSE and
+ OMP_CLAUSE_UNTIED. Handle OMP_CLAUSE_LASTPRIVATE_STMT.
+ (tsubst_omp_for_iterator): New function.
+ (dependent_omp_for_p): New function.
+ (tsubst_expr) <case OMP_FOR>: Use it. Handle collapsed OMP_FOR
+ loops. Adjust finish_omp_for caller. Handle loops with random
+ access iterators. Adjust for OMP_FOR_{INIT,COND,INCR} changes.
+ (tsubst_expr): Handle OMP_TASK.
+ * semantics.c (cxx_omp_create_clause_info): New function.
+ (finish_omp_clauses): Call it. Handle OMP_CLAUSE_UNTIED and
+ OMP_CLAUSE_COLLAPSE.
+ (cxx_omp_predetermined_sharing): Removed.
+ * semantics.c (finish_omp_for): Allow pointer iterators. Use
+ handle_omp_for_class_iterator and dependent_omp_for_p. Handle
+ collapsed for loops. Adjust c_finish_omp_for caller. Add new
+ clauses argument. Fix check for type dependent cond or incr.
+ Set OMP_FOR_CLAUSES to clauses. Use cp_convert instead of
+ fold_convert to convert incr amount to difference_type. Only
+ fold if not in template. If decl is mentioned in lastprivate
+ clause, set OMP_CLAUSE_LASTPRIVATE_STMT. Handle loops with random
+ access iterators. Adjust for OMP_FOR_{INIT,COND,INCR}
+ changes.
+ (finish_omp_threadprivate): Allow static class members of the
+ current class.
+ (handle_omp_for_class_iterator, begin_omp_task, finish_omp_task,
+ finish_omp_taskwait): New functions.
+
+ * parser.c (cp_parser_binary_expression): Add prec argument.
+ (cp_parser_assignment_expression): Adjust caller.
+ * cp-tree.h (outer_curly_brace_block): New prototype.
+ * decl.c (outer_curly_brace_block): No longer static.
+
+2008-06-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36404
+ * pt.c (push_template_decl_real): Consistently return error_mark_node
+ on error.
+
+2008-06-02 Tomas Bily <tbily@suse.cz>
+
+ * typeck.c (is_bitfield_expr_with_lowered_type): Use CASE_CONVERT.
+ (cp_build_unary_op): Likewise.
+ (cp_build_indirect_ref): Use CONVERT_EXPR_P.
+ (maybe_warn_about_returning_address_of_local): Likewise.
+
+2008-05-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/35243
+ * pt.c (tsubst_initializer_list): Consistently check the tree
+ returned by tsubst_pack_expansion for error_mark_node.
+
+2008-05-27 Michael Matz <matz@suse.de>
+
+ PR c++/27975
+ * call.c (build_new_op): Make warning conditional on
+ OPT_Wenum_compare.
+
+2008-05-27 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/35909
+ * call.c (convert_like_real): Convert bitfield to desired type
+ before creating temporary.
+
+2008-05-26 Daniel Franke <franke.daniel@gmail.com>
+
+ * Makefile.in: Adjusted dependencies on c-incpath.o.
+
+2008-05-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/36237
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Call
+ fold_build_cleanup_point_expr on build_call_a results.
+
+ PR c++/36308
+ * semantics.c (omp_clause_info_fndecl): New function.
+ (finish_omp_clauses): Use it.
+
+2008-05-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/36023
+ * cp-tree.h (check_array_initializer): New prototype.
+ * decl.c (check_array_initializer): New function.
+ (check_initializer): Call it.
+ * semantics.c (finish_compound_literal): Call it for ARRAY_TYPEs.
+
+2008-05-21 Tom Tromey <tromey@redhat.com>
+
+ * mangle.c (save_partially_mangled_name): Remove.
+ (restore_partially_mangled_name): Likewise.
+ (write_encoding): Update.
+ (write_unqualified_name): Likewise.
+ (start_mangling): Always use name_obstack. Remove 'ident_p'
+ argument.
+ (get_identifier_nocopy): Remove.
+ (finish_mangling_internal): Rename from finish_mangling.
+ (finish_mangling): New function.
+ (finish_mangling_get_identifier): Likewise.
+ (partially_mangled_name, partially_mangled_name_len): Remove.
+ (mangle_decl_string): Change return type. Update.
+ (mangle_decl, mangle_type_string, mangle_special_for_type,
+ mangle_ctor_vtbl_for_type, mangle_thunk, mangle_guard_variable,
+ mangle_ref_init_variable): Update.
+
+2008-05-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/35331
+ * semantics.c (begin_class_definition): Extend checks on the first
+ argument.
+
+2008-05-12 Tomas Bily <tbily@suse.cz>
+
+ * typeck2.c (digest_init): Use CONVERT_EXPR_P.
+ * call.c (build_over_call): Likewise.
+ * error.c (dump_expr): Use CASE_CONVERT.
+ * class.c (fixed_type_or_null): Likewise.
+
+2008-05-11 Volker Reichelt <v.reichelt@netcologne.de>
+
+ * parser.c (cp_parser_omp_clause_reduction): Add missing "expected"
+ in error message.
+ (cp_parser_omp_clause_schedule): Remove superfluous "expected"
+ in error message.
+
+2008-05-07 Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ * decl.c (duplicate_decls): Merge in DECL_PURE_P, TREE_READONLY,
+ DECL_LOOPING_CONST_OR_PURE_P attributes.
+ * rtti.c (build_dynamic_cast_1): Rename DECL_IS_PURE to
+ DECL_PURE_P.
+
+2008-05-02 Simon Baldwin <simonb@google.com>
+
+ PR bootstrap/36108
+ * typeck.c (build_array_ref): Remove warn_array_subscript_range.
+
+2008-05-01 Simon Baldwin <simonb@google.com>
+
+ * typeck.c (build_array_ref): Call warn_array_subscript_range.
+
+2008-04-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35986
+ * pt.c (more_specialized_fn): Stop the loop even if there are no
+ arguments before ellipsis.
+
+2008-04-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35650
+ * parser.c (cp_parser_lookup_name): Look through single function
+ OVERLOAD.
+
+ PR c++/35987
+ * typeck.c (cp_build_modify_expr) <case PREINCREMENT_EXPR>: Don't build
+ COMPOUND_EXPR if the second argument would be error_mark_node.
+
+2008-04-28 Jason Merrill <jason@redhat.com>
+ Liu Guanwei <liu_gw@163.com>
+
+ PR c++/57
+ * parser.c (cp_parser_parameter_declaration): Handle < ambiguity
+ in default arguments.
+
+2008-04-25 Jan Hubicka <jh@suse.cz>
+
+ * typeck.c (check_return_expr): Update.
+ * decl.c (start_preparsed_function): Update.
+ * method.c (use_thunk): Update.
+
+2008-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35758
+ * cp-tree.h (cp_reconstruct_complex_type): New prototype.
+ * cp-objcp-common.h (LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE): Define.
+ * decl2.c (is_late_template_attribute): Only make vector_size
+ late tmpl attribute if argument is type or value dependent.
+ (cp_reconstruct_complex_type): New function.
+
+2008-04-24 Richard Guenther <rguenther@suse.de>
+
+ * typeck.c (cp_build_function_call): Call
+ check_builtin_function_arguments.
+
+2008-04-23 Paolo Bonzini <bonzini@gnu.org>
+
+ * typeck.c (get_member_function_from_ptrfunc): Don't set TREE_INVARIANT.
+ (build_ptrmemfunc1): Don't set TREE_INVARIANT.
+ * init.c (build_zero_init): Don't set TREE_INVARIANT.
+ * class.c (build_base_path): Don't set TREE_INVARIANT.
+ (build_vtbl_ref_1): Don't set TREE_INVARIANT.
+ (build_vtbl_initializer): Don't set TREE_INVARIANT.
+ * decl.c (build_enumerator): Don't set TREE_INVARIANT.
+ * rtti.c (tinfo_base_init): Don't set TREE_INVARIANT.
+ (generic_initializer): Don't set TREE_INVARIANT.
+ (ptr_initializer): Don't set TREE_INVARIANT.
+ (ptm_initializer): Don't set TREE_INVARIANT.
+ (class_initializer): Don't set TREE_INVARIANT.
+ * typeck2.c (process_init_constructor): Don't set TREE_INVARIANT.
+ * pt.c (push_inline_template_parms_recursive): Don't set TREE_INVARIANT.
+ (build_template_parm_index): Don't set TREE_INVARIANT.
+ (reduce_template_parm_level): Don't set TREE_INVARIANT.
+ (process_template_parm): Don't set TREE_INVARIANT.
+
+2008-04-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/35316
+ * semantics.c (finish_decltype_type): Check DECL_BIT_FIELD_TYPE
+ to see if DECL_BIT_FIELD_TYPE should be used, not some other flag.
+ * typeck.c (is_bitfield_expr_with_lowered_type): Likewise.
+
+2008-04-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35747
+ * semantics.c (finish_stmt_expr): Call pop_stmt_list even if the stmt
+ expression is errorneous.
+
+2008-04-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/35325
+ * tree.c (cp_tree_equal): Handle FIXED_CST.
+
+ PR c++/35678
+ * pt.c (template_template_parm_bindings_ok_p): Set
+ processing_template_decl while in this function.
+
+2008-04-18 Kris Van Hees <kris.van.hees@oracle.com>
+
+ * cvt.c (type_promotes_to): Support char16_t and char32_t.
+ * decl.c (grokdeclarator): Disallow signed/unsigned/short/long on
+ char16_t and char32_t.
+ * lex.c (reswords): Add char16_t and char32_t (for c++0x).
+ * mangle.c (write_builtin_type): Mangle char16_t/char32_t as vendor
+ extended builtin type "u8char{16,32}_t".
+ * parser.c (cp_lexer_next_token_is_decl_specifier_keyword): Support
+ RID_CHAR{16,32}.
+ (cp_lexer_print_token): Support CPP_STRING{16,32}.
+ (cp_parser_is_string_literal): Idem.
+ (cp_parser_string_literal): Idem.
+ (cp_parser_primary_expression): Support CPP_CHAR{16,32} and
+ CPP_STRING{16,32}.
+ (cp_parser_simple_type_specifier): Support RID_CHAR{16,32}.
+ * tree.c (char_type_p): Support char16_t and char32_t as char types.
+ * typeck.c (string_conv_p): Support char16_t and char32_t.
+
+2008-04-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/35773
+ * call.c (build_user_type_conversion_1): Represent second step of
+ copy-init with an rvalue conversion.
+ (convert_like_real) [ck_user]: Don't implicitly add it here.
+
+2008-04-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/35751
+ * decl.c (layout_var_decl): If extern or static var has variable
+ size, set TREE_TYPE (decl) to error_mark_node.
+
+2008-04-16 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR target/35921
+ * optimize.c (maybe_clone_body): Copy DECL_DLLIMPORT_P flag
+ to clone.
+
+2008-04-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/35708
+ * semantics.c (finish_compound_literal): Return a TARGET_EXPR,
+ not a pushed variable.
+
+2008-04-09 Volker Reichelt <v.reichelt@netcologne.de>
+
+ * call.c (build_op_delete_call): Fix quotation in warning message.
+ * decl.c (grokdeclarator): Quote keyword in error message.
+ * pt.c (check_for_bare_parameter_packs): Fix quotation in error
+ message.
+
+ * parser.c (cp_parser_check_type_definition): Print error string
+ directly rather than using "%s".
+ (cp_parser_postfix_expression): Fix quotation.
+ (cp_parser_decltype): Likewise.
+ (cp_parser_sizeof_operand): Fix quotation. Simplify.
+
+ * parser.c (cp_parser_non_integral_constant_expression): Build error
+ message with CONCAT rather than using "%s".
+ (cp_parser_primary_expression): Fix quotation.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_postfix_dot_deref_expression): Likewise.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_new_expression): Likewise.
+ (cp_parser_delete_expression): Likewise.
+
+ * parser.c (cp_parser_asm_specification_opt): Print CPP_CLOSE_PAREN
+ as `)', not as `('. Fix quotation.
+ (cp_parser_consume_semicolon_at_end_of_statement): Fix quotation.
+ (cp_parser_primary_expression): Likewise.
+ (cp_parser_nested_name_specifier_opt): Likewise.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_postfix_open_square_expression): Likewise.
+ (cp_parser_parenthesized_expression_list): Likewise.
+ (cp_parser_pseudo_destructor_name): Likewise.
+ (cp_parser_new_expression): Likewise.
+ (cp_parser_direct_new_declarator): Likewise.
+ (cp_parser_delete_expression): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_question_colon_clause): Likewise.
+ (cp_parser_builtin_offsetof): Likewise.
+ (cp_parser_trait_expr): Likewise.
+ (cp_parser_label_for_labeled_statement): Likewise.
+ (cp_parser_compound_statement): Likewise.
+ (cp_parser_selection_statement): Likewise.
+ (cp_parser_condition): Likewise.
+ (cp_parser_iteration_statement): Likewise.
+ (cp_parser_already_scoped_statement): Likewise.
+ (cp_parser_simple_declaration): Likewise.
+ (cp_parser_linkage_specification): Likewise.
+ (cp_parser_static_assert): Likewise.
+ (cp_parser_decltype): Likewise.
+ (cp_parser_conversion_function_id): Likewise.
+ (cp_parser_operator_function_id): Likewise.
+ (cp_parser_operator): Likewise.
+ (cp_parser_type_parameter): Likewise.
+ (cp_parser_template_id): Likewise.
+ (cp_parser_explicit_instantiation): Likewise.
+ (cp_parser_explicit_specialization): Likewise.
+ (cp_parser_enum_specifier): Likewise.
+ (cp_parser_namespace_definition): Likewise.
+ (cp_parser_namespace_alias_definition): Likewise.
+ (cp_parser_using_declaration): Likewise.
+ (cp_parser_using_directive): Likewise.
+ (cp_parser_asm_definition): Likewise.
+ (cp_parser_direct_declarator): Likewise.
+ (cp_parser_ptr_operator): Likewise.
+ (cp_parser_parameter_declaration_clause): Likewise.
+ (cp_parser_initializer_clause): Likewise.
+ (cp_parser_class_specifier): Likewise.
+ (cp_parser_member_specification_opt): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_pure_specifier): Likewise.
+ (cp_parser_constant_initializer): Likewise.
+ (cp_parser_base_clause): Likewise.
+ (cp_parser_exception_specification_opt): Likewise.
+ (cp_parser_try_block): Likewise.
+ (cp_parser_function_try_block): Likewise.
+ (cp_parser_handler): Likewise.
+ (cp_parser_throw_expression): Likewise.
+ (cp_parser_asm_operand_list): Likewise.
+ (cp_parser_attributes_opt): Likewise.
+ (cp_parser_label_declaration): Likewise.
+ (cp_parser_constructor_declarator_p): Likewise.
+ (cp_parser_template_declaration_after_export): Likewise.
+ (cp_parser_single_declaration): Likewise.
+ (cp_parser_objc_message_expression): Likewise.
+ (cp_parser_objc_message_args): Likewise.
+ (cp_parser_objc_encode_expression): Likewise.
+ (cp_parser_objc_defs_expression): Likewise.
+ (cp_parser_objc_protocol_expression): Likewise.
+ (cp_parser_objc_selector_expression): Likewise.
+ (cp_parser_objc_protocol_refs_opt): Likewise.
+ (cp_parser_objc_typename): Likewise.
+ (cp_parser_objc_method_keyword_params): Likewise.
+ (cp_parser_objc_superclass_or_category): Likewise.
+ (cp_parser_objc_try_catch_finally_statement): Likewise.
+ (cp_parser_objc_synchronized_statement): Likewise.
+ (cp_parser_objc_throw_statement): Likewise.
+ (cp_parser_omp_var_list_no_open): Likewise.
+ (cp_parser_omp_clause_default): Likewise.
+ (cp_parser_omp_clause_if): Likewise.
+ (cp_parser_omp_clause_num_threads): Likewise.
+ (cp_parser_omp_clause_reduction): Likewise.
+ (cp_parser_omp_clause_schedule): Likewise.
+ (cp_parser_omp_critical): Likewise.
+ (cp_parser_omp_for_loop): Likewise.
+ (cp_parser_omp_sections_scope): Likewise.
+
+ * parser.c (cp_parser_template_parameter_list): Simplify.
+
+2008-04-07 James E. Wilson <wilson@tuliptree.org>
+
+ * pt.c (tsubst_copy, case SIZEOF_EXPR): Initialize len.
+
+2008-04-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/35734
+ * class.c (type_has_user_nondefault_constructor): A template
+ counts as a nondefault constructor.
+
+2008-04-04 Paolo Bonzini <bonzini@gnu.org>
+
+ * decl.c (cxx_push_function_context): Delete.
+ (cxx_pop_function_context): Delete.
+ (start_preparsed_function): Merge cxx_push_function_context (!f->decl
+ code only).
+ * cp-objcp-common.h (LANG_HOOKS_FUNCTION_INIT,
+ LANG_HOOKS_FUNCTION_FINAL): Delete.
+ (LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P): Rename to
+ LANG_HOOKS_MISSING_NORETURN_OK_P.
+ * cp-tree.h (cxx_push_function_context, cxx_pop_function_context):
+ Delete prototype.
+ * semantics.c (current_stmt_tree): Fix comment.
+
+2008-04-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35741
+ * semantics.c (finish_offsetof): Undo effect of convert_from_reference
+ before calling fold_offsetof.
+
+2008-04-03 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in (c++_OBJS): New variable.
+
+2008-04-03 Paolo Bonzini <bonzini@gnu.org>
+
+ * optimize.c (clone_body): New, from tree-inline.c.
+
+2008-04-03 Paolo Bonzini <bonzini@gnu.org>
+
+ * method.c (synthesize_method): Use {push,pop}_function_context.
+ * name-lookup.c (push_to_top_level): Likewise.
+ * parser.c (cp_parser_late_parsing_for_member): Likewise.
+
+2008-03-30 Volker Reichelt <v.reichelt@netcologne.de>
+
+ PR c++/35578
+ * parser.c (cp_parser_decl_specifier_seq): Add location to error
+ message.
+
+2008-03-27 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in: Revert automatic dependency patch.
+
+2008-03-27 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR obj-c++/35704
+ * typeck.c (build_x_compound_expr): Use cp_build_compound_expr.
+ (build_compound_expr): New, for compatibility with C
+ build_compound_expr.
+ (cp_build_compound_expr): Renamed from build_compound_expr.
+ (build_c_cast): New, for compatibility with C build_c_cast.
+ (cp_build_c_cast): Renamed from build_c_cast.
+ * init.c (build_vec_delete_1): Fix calls to build_compound_expr.
+ * decl.c (cxx_maybe_build_cleanup): Ditto.
+ * cp-tree.h (build_compound_expr): Add C-compatibile prototype.
+ (cp_build_compound_expr): Renamed from build_compound_expr.
+ (build_c_cast): Add C-compatible prototype.
+ (cp_build_c_cast): Renamed from build_c_cast.
+ * typeck2.c (build_functional_cast): Use cp_build_c_cast.
+ * parser.c (cp_parser_cast_expression): Fix call to build_c_cast.
+
+2008-03-27 Douglas Gregor <doug.gregor@gmail.com>
+
+ * pt.c (tsubst_copy) <case SIZEOF_EXPR>: Cope with
+ tsubst_pack_expansion returning a pack expansion, or a TREE_VEC
+ ending in a pack expansion, both of which can occur when
+ substituting into a nested template.
+ (tsubst_copy_and_build) <case SIZEOF_EXPR>: When we're
+ instantiating the sizeof...(X) form, make tsubst_copy do the work.
+ * parser.c (cp_parser_template_parameter): Deal with unnamed
+ non-type template parameter packs identified by pack expansions in
+ the parameter type.
+
+2008-03-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35546
+ * pt.c (apply_late_template_attributes): Don't call tsubst on
+ first attribute argument if it is IDENTIFIER_NODE.
+
+ PR c++/35332
+ * error.c (dump_expr): Pass {,UN}ORDERED_EXPR, UN{LT,LE,GT,GE,EQ}_EXPR
+ and LTGT_EXPR to pp_expression.
+
+2008-03-26 Douglas Gregor <doug.gregor@gmail.com>
+
+ * pt.c (coerce_template_template_parm): Moved the body of the loop
+ of coerce_template_template_parms here, to make iteration over a
+ template argument pack simpler.
+ Also, allow matching of a template parameter pack in the template
+ template parameter to a template parameter in the template
+ template argument.
+ (coerce_template_template_parms): Deal with variadic template
+ template parameters. Use coerce_template_template_parm.
+ (unify): Make sure we coerce the template template argument's
+ template arguments to the template template parameter's template
+ parameters, not the other way around.
+
+2008-03-25 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in: Remove .o targets.
+ (cp/g++spec.o): Moved to cp/. Reduce to variable setting.
+ (GXX_OBJS): Update.
+ (c++_OBJS): New variable.
+ (CXX_TREE_H, CXX_PRETTY_PRINT_H): Remove.
+
+2008-03-25 Douglas Gregor <doug.gregor@gmail.com>
+
+ * typeck.c (composite_pointer_type_r): Add SFINAE support.
+ (composite_pointer_type): Ditto.
+ (common_type): Fix call to composite_pointer_type.
+ (cxx_sizeof_nowarn): New; used to be a macro.
+ (cxx_sizeof_expr): Add SFINAE support.
+ (cxx_alignof_expr): Ditto.
+ (decay_conversion): Fix calls for SFINAE support.
+ (rationalize_conditional_expr): Add SFINAE support.
+ (build_class_member_access_expr): Ditto.
+ (finish_class_member_access_expr): Ditto.
+ (build_x_indirect_ref): Ditto.
+ (build_indirect_ref): Original version renamed to
+ cp_build_indirect_ref; new version provides a bridge from
+ c-common.
+ (cp_build_indirect_ref): Was build_indirect_ref; added SFINAE
+ support.
+ (get_member_function_from_ptrfunc): Fix calls for SFINAE support.
+ (build_function_call): Original version renamed to
+ cp_build_function_call; new version provides a bridge from
+ c-common.
+ (cp_build_function_call): Was build_function_call; added SFINAE
+ support.
+ (convert_arguments): Add SFINAE support.
+ (build_x_binary_op): Ditto.
+ (build_binary_op): Original version renamed to cp_build_binary_op;
+ new version provides a bridge from c-common.
+ (cp_build_binary_op): Was build_binary_op; added SFINAE support.
+ (pointer_diff): Fix calls for SFINAE.
+ (build_x_unary_op): Add SFINAE support.
+ (condition_conversion): Fix calls for SFINAE.
+ (build_unary_op): Original version renamed to cp_build_unary_op;
+ new version provides a bridge from c-common.
+ (cp_build_unary_op): Was build_unary_op; added SFINAE support.
+ (unary_complex_lvalue): Fix calls for SFINAE.
+ (build_x_conditional_expr): Add SFINAE support.
+ (build_x_compound_expr_from_list): Fix calls for SFINAE.
+ (build_x_compound_expr): Add SFINAE support.
+ (convert_ptrmem): Fix calls for SFINAE.
+ (build_static_cast_1): Add SFINAE support.
+ (build_static_cast): Ditto.
+ (build_reinterpret_cast_1): Ditto.
+ (build_reinterpret_cast): Ditto.
+ (build_const_cast_1): Ditto.
+ (build_const_cast): Ditto.
+ (build_c_cast): Ditto.
+ (build_modify_expr): Original version renamed to
+ cp_build_modify_expr; new version provides a bridge from c-common.
+ (cp_build_modify_expr): Was build_modify_expr; added SFINAE
+ support.
+ (build_x_modify_expr): Add SFINAE support.
+ (build_ptrmemfunc): Fix calls for SFINAE.
+ (convert_for_assignment): Add SFINAE support.
+ (convert_for_initialization): Ditto.
+ (check_return_expr): Fix calls for SFINAE.
+ (lvalue_or_else): Add SFINAE support.
+ * init.c (perform_member_init): Fix calls for SFINAE.
+ (emit_mem_initializers): Ditto.
+ (expand_virtual_init): Ditto.
+ (expand_cleanup_for_base): Ditto.
+ (build_aggr_init): Add SFINAE support.
+ (expand_default_init): Ditto.
+ (expand_aggr_init_1): Fix calls for SFINAE.
+ (build_offset_ref): Ditto.
+ (build_new_1): Add SFINAE support.
+ (build_new): Ditto.
+ (build_vec_delete_1): Fix calls for SFINAE.
+ (get_temp_regvar): Ditto.
+ (build_vec_init): Add SFINAE support.
+ (build_dtor_call): Fix calls for SFINAE.
+ (build_delete): Ditto.
+ (push_base_cleanups): Ditto.
+ (build_vec_delete_1): Ditto.
+ * class.c (build_base_path): Fix calls for SFINAE.
+ (build_simple_base_path): Ditto.
+ (convert_to_base_statically): Ditto.
+ (build_vfn_ref): Ditto.
+ (resolve_address_of_overloaded_function): Ditto.
+ * decl.c (check_initializer): Fix calls for SFINAE.
+ (register_dtor_fn): Ditto.
+ (compute_array_index_type): Ditto.
+ (finish_enum): Ditto.
+ (start_preparsed_function): Ditto.
+ (cxx_maybe_build_cleanup): Ditto.
+ * call.c (convert_like): Add COMPLAIN argument.
+ (convert_like_with_context): Ditto.
+ (build_this): Fix calls for SFINAE.
+ (build_user_type_conversion): Ditto.
+ (resolve_args): Ditto.
+ (build_new_function_call): Add SFINAE support.
+ (build_operator_new_call): Fix calls for SFINAE.
+ (build_object_call): Add SFINAE support.
+ (build_conditional_expr): Ditto.
+ (build_new_op): Ditto.
+ (build_op_delete_call): Fix calls for SFINAE.
+ (build_temp): Ditto.
+ (convert_like_real): Add SFINAE support.
+ (build_x_va_arg): Fix calls for SFINAE.
+ (convert_default_arg): Ditto.
+ (build_over_call): Add SFINAE support.
+ (build_java_interface_fn_ref): Fix calls for SFINAE.
+ (build_special_member_call): Add SFINAE support.
+ (build_new_method_call): Ditto.
+ (perform_implicit_conversion): Ditto.
+ (perform_direct_initialization_if_possible): Ditto.
+ (initialize_reference): Fix calls for SFINAE.
+ * method.c (do_build_assign_ref): Fix calls for SFINAE.
+ * rtti.c (build_headof): Fix calls for SFINAE.
+ (get_tinfo_decl_dynamic): Ditto.
+ (get_typeid): Ditto.
+ (build_dynamic_cast_1): Add SFINAE support.
+ (build_dynamic_cast): Ditto.
+ (tinfo_base_init): Fix calls for SFINAE.
+ * except.c (do_get_exception_ptr): Fix calls for SFINAE.
+ (do_end_catch): Ditto.
+ (initialize_handler_parm): Ditto.
+ (expand_start_catch_block): Ditto.
+ (do_allocate_exception): Ditto.
+ (do_free_exception): Ditto.
+ (build_throw): Ditto.
+ * cvt.c (build_up_reference): Fix calls for SFINAE.
+ (convert_to_reference): Ditto.
+ (ocp_convert): Ditto.
+ (convert_to_void): Add SFINAE support.
+ * tree.c (build_dummy_object): Fix calls for SFINAE.
+ (stabilize_expr): Ditto.
+ * cp-tree.h (build_conditional_expr): Add tsubst_flags_t
+ parameter.
+ (build_new_method_call): Ditto.
+ (build_special_member_call): Ditto.
+ (build_new_op): Ditto.
+ (perform_implicit_conversion): Ditto.
+ (perform_direct_initialization_if_possible): Ditto.
+ (convert_to_void): Ditto.
+ (build_aggr_init): Ditto.
+ (build_new): Ditto.
+ (build_vec_init): Ditto.
+ (build_dynamic_cast): Ditto.
+ (finish_call_expr): Ditto
+ (cxx_sizeof_or_alignof_expr): Add COMPLAIN parameter.
+ (cxx_sizeof_nowarn): Remove macro; add function declaration.
+ (build_class_member_access_expr): Add tsubst_flags_t parameter.
+ (finish_class_member_access_expr): Ditto.
+ (build_x_indirect_ref): Ditto.
+ (cp_build_indirect_ref): New.
+ (cp_build_function_call): Add tsubst_flags_t parameter.
+ (build_x_unary_op): Ditto.
+ (cp_build_unary_op): New.
+ (build_x_conditional_expr): Add tsubst_flags_t parameter.
+ (build_x_compound_expr): Ditto.
+ (build_compound_expr): Ditto.
+ (build_static_cast): Ditto.
+ (build_reinterpret_cast): Ditto.
+ (build_const_cast): Ditto.
+ (build_c_cast): Ditto.
+ (build_x_modify_expr): Ditto.
+ (cp_build_modify_expr): New.
+ (convert_for_initialization): Add tsubst_flags_t parameter.
+ (cp_build_binary_op): Remove macro; add function declaration.
+ (invalid_nonstatic_memfn_p): Add tsubst_flags_t parameter.
+ (lvalue_or_else): Ditto.
+ (build_functional_cast): Ditto.
+ * typeck2.c (digest_init): Fix calls for SFINAE.
+ (process_init_constructor_array): Ditto.
+ (process_init_constructor_record): Ditto.
+ (build_x_arrow): Ditto.
+ (build_m_component_ref): Ditto.
+ (build_functional_cast): Add SFINAE support.
+ * pt.c (tsubst_copy_and_build): Add (more) SFINAE support.
+ * semantics.c (simplify_loop_decl_cond): Fix calls for SFINAE.
+ (finish_expr_stmt): Ditto.
+ (finish_for_expr): Ditto.
+ (finish_asm_stmt): Ditto.
+ (finish_non_static_data_member): Ditto.
+ (finish_qualified_id_expr): Ditto.
+ (finish_call_expr): Add SFINAE support.
+ (finish_increment_expr): Fix calls for SFINAE.
+ (finish_unary_op_expr): Ditto.
+ (simplify_aggr_init_expr): Ditto.
+ (finish_omp_clauses): Ditto.
+ (finish_omp_for): Ditto.
+ (finish_omp_barrier): Ditto.
+ (finish_omo_flush): Ditto.
+ * decl2.c (grok_array_decl): Fix calls or SFINAE.
+ (build_anon_union_vars): Ditto.
+ (get_guard_cond): Ditto.
+ (set_guard): Ditto.
+ (one_static_initialization_or_destruction): Ditto.
+ (do_static_initialization_or_destruction): Ditto.
+ (generate_ctor_or_dtor_function): Ditto.
+ (build_offset_ref_call_from_tree): Ditto.
+ * parser.c (cp_parser_postfix_expression): Fix calls for SFINAE.
+ (cp_parser_postfix_dot_deref_expression): Ditto.
+ (cp_parser_unary_expression): Ditto.
+ (cp_parser_new_expression): Ditto.
+ (cp_parser_cast_expression): Ditto.
+ (cp_parser_binary_expression): Ditto.
+ (cp_parser_question_colon_clause): Ditto.
+ (cp_parser_assignment_expression): Ditto.
+ (cp_parser_expression): Ditto.
+ (cp_parser_builtin_offsetof): Ditto.
+ (cp_parser_template_argument): Ditto.
+ (cp_parser_functional_cast): Ditto.
+
+2008-03-24 Tom Tromey <tromey@redhat.com>
+
+ * lex.c (handle_pragma_interface): Don't copy the filename.
+ (handle_pragma_implementation): Copy filename using xstrdup.
+
+2008-03-21 Paolo Carlini <pcarlini@suse.de>
+
+ * cp-tree.h (IS_AGGR_TYPE): Rename to MAYBE_CLASS_TYPE_P.
+ (SET_IS_AGGR_TYPE): Rename to SET_CLASS_TYPE_P.
+ (IS_AGGR_TYPE_CODE): Rename to RECORD_OR_UNION_CODE_P.
+ (PROMOTES_TO_AGGR_TYPE): Remove.
+ (CLASS_TYPE_P, TYPE_NON_AGGREGATE_CLASS): Adjust.
+ * typeck.c (unary_complex_lvalue, build_modify_expr,
+ convert_for_initialization): Adjust.
+ * init.c (is_aggr_type): Remove.
+ (is_class_type): Add.
+ (build_offset_ref, build_new_1, build_vec_delete_1, build_vec_init,
+ build_delete): Adjust.
+ * lex.c (make_aggr_type): Remove.
+ (make_class_type): Add.
+ (cxx_make_type): Adjust.
+ * class.c (finish_struct_1, fixed_type_or_null, is_empty_class):
+ Adjust.
+ * decl.c (build_typename_type, make_typename_type,
+ make_unbound_class_template, cxx_init_decl_processing,
+ check_tag_decl, groktypename, start_decl_1, layout_var_decl,
+ check_initializer, cp_finish_decl, build_ptrmemfunc_type, grokparms,
+ grok_op_properties, xref_tag, check_function_type): Adjust.
+ * call.c (check_dtor_name, standard_conversion, implicit_conversion,
+ add_builtin_candidate, add_builtin_candidates,
+ build_user_type_conversion_1, convert_like_real, build_cxx_call,
+ is_subseq, compare_ics): Adjust.
+ * method.c (use_thunk): Adjust.
+ * rtti.c (build_dynamic_cast_1, create_pseudo_type_info,
+ create_tinfo_types): Adjust.
+ * cvt.c (cp_convert_to_pointer, convert_to_pointer_force,
+ build_up_reference, convert_to_reference, convert_from_reference,
+ ocp_convert, build_expr_type_conversion): Adjust.
+ * tree.c (bind_template_template_parm, error_type): Adjust.
+ * dump.c (cp_dump_tree): Adjust.
+ * search.c (lookup_member): Adjust.
+ * friend.c (make_friend_class, do_friend): Adjust.
+ * typeck2.c (store_init_value, process_init_constructor_array,
+ process_init_constructor_record, build_x_arrow, build_m_component_ref,
+ build_functional_cast): Adjust.
+ * pt.c (finish_member_template_decl, process_template_parm,
+ lookup_template_class, tsubst_function_type, tsubst,
+ tsubst_copy_and_build, get_template_base, bt_instantiate_type_proc):
+ Adjust.
+ * semantics.c (begin_class_definition, finish_base_specifier,
+ finish_typeof, cxx_omp_predetermined_sharing, finish_decltype_type):
+ Adjust.
+ * name-lookup.c (constructor_name_p, push_overloaded_decl,
+ do_class_using_decl, lookup_qualified_name,
+ maybe_process_template_type_declaration): Adjust.
+ * decl2.c (grok_array_decl, check_member_template,
+ constrain_class_visibility): Adjust.
+ * parser.c (cp_parser_class_name): Adjust.
+
+2008-03-18 Paolo Bonzini <bonzini@gnu.org>
+
+ * cp-lang.c (LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS): Delete.
+
+2008-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/35548
+ * call.c (reference_binding): Check LOOKUP_NO_TEMP_BIND when binding
+ a temp directly to a reference as per DR391.
+
+2008-03-12 Richard Guenther <rguenther@suse.de>
+
+ PR c++/35469
+ Revert:
+ 2008-02-04 Richard Guenther <rguenther@suse.de>
+
+ PR java/35035
+ * decl.c (record_builtin_java_type): Make jboolean a
+ integer type again where its mode doesn't match that of bool.
+
+ 2008-01-25 Richard Guenther <rguenther@suse.de>
+
+ PR c++/33887
+ * decl.c (record_builtin_java_type): Make __java_boolean
+ a variant of bool.
+ * typeck.c (structural_comptypes): Move TYPE_FOR_JAVA check
+ after TYPE_MAIN_VARIANT check.
+
+2008-03-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35328
+ * semantics.c (finish_omp_clauses): Look through NOP_EXPR even
+ if errorcount.
+
+ PR c++/35337
+ * semantics.c (finish_omp_clauses): Use %qD instead of %qE for
+ DECL_P in not a variable and appears more than once error messages.
+
+2008-03-07 Paolo Bonzini <bonzini@gnu.org>
+
+ Revert:
+
+ 2008-02-06 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/35049
+ PR c++/35096
+ * typeck.c (structural_comptypes): Call cp_comptypes.
+ (comptypes): New; called from the C/C++ common bits to perform
+ strict checks.
+ (cp_comptypes): Renamed from comptypes, which is already used,
+ with a different signature, by the C++ front end.
+ (build_reinterpret_cast_1): Call cp_comptypes.
+ (ptr_reasonably_similar): Ditto.
+ * decl.c (decls_match): Ditto.
+ * cvt.c (convert_to_reference): Ditto.
+ * cp-tree.h (same_type_p): Ditto.
+ (same_or_base_type_p): Ditto.
+ (comptypes): Rename to cp_comptypes.
+ * pt.c (canonical_type_parameter): Call cp_comptypes.
+
+2008-03-07 Paolo Bonzini <bonzini@gnu.org>
+
+ * cp-objcp-common.c (cxx_types_compatible_p): Remove obsolete
+ test for equivalence between pointer and references.
+
+2008-03-02 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 24924
+ * class.c (finish_struct_anon): Use permerror instead of pedwarn.
+ (check_field_decls): Likewise.
+ (note_name_declared_in_class): Likewise.
+ * call.c (build_new_op): Likewise.
+ (convert_like_real): Likewise.
+ (build_over_call): Likewise.
+ * lex.c (unqualified_fn_lookup_error): Likewise.
+ * parser.c (cp_parser_template_id): Likewise.
+ * cvt.c (warn_ref_binding): Likewise.
+ (convert_to_reference): Likewise.
+ (ocp_convert): Likewise.
+ (convert_to_void): Use error instead of pedwarn.
+ * error.c (cp_cpp_error): Use pedantic_warning_kind.
+ * decl.c (compute_array_index_type): Use constant_expression_error.
+
+2008-03-01 Douglas Gregor <doug.gregor@gmail.com>
+
+ * parser.c (cp_lexer_next_token_is_decl_specifier_keyword): Note
+ that auto is either a storage class or a simple type specifier,
+ depending on the dialect.
+ (cp_parser_decl_specifier_seq): Complain about `auto' as a storage
+ specifier in C++98 mode, error in C++0x mode (since we don't
+ support auto as a type specifier, yet).
+ (cp_parser_storage_class_specifier_opt): Don't treat `auto' as a
+ storage specifier in C++0x mode.
+ (cp_parser_simple_type_specifier): Parse `auto' as a
+ simple-type-specifier, but error because we don't support it yet.
+
+2008-02-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * parser.c (cp_parser_nonclass_name): New.
+ (cp_parser_pseudo_destructor_name): Use it instead of
+ cp_parser_type_name.
+ (cp_parser_type_name): Move code to cp_parser_nonclass_name.
+
+2008-02-29 Tom Tromey <tromey@redhat.com>
+
+ * parser.c (struct cp_token) <input_file_stack_index>: Remove.
+ (cp_lexer_get_preprocessor_token): Update.
+ (cp_lexer_set_source_position_from_token): Don't call
+ restore_input_file_stack.
+ * lex.c (cxx_init): Don't use push_srcloc or pop_srcloc.
+
+2008-02-28 Richard Guenther <rguenther@suse.de>
+
+ Revert:
+ 2008-02-26 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (duplicate_decls): Remove decl from global mapping
+ before ggc_freeing it.
+
+2008-02-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35368
+ * rtti.c: Include c-pragma.h.
+ (push_abi_namespace, pop_abi_namespace): New functions.
+ (build_dynamic_cast_1, tinfo_base_init, get_pseudo_ti_index,
+ create_tinfo_types, emit_support_tinfos): Use them.
+ * Make-lang.in (cp/rtti.o): Depend on $(C_PRAGMA_H).
+
+2008-02-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/35315
+ * decl.c (grokdeclarator): Allow a typedef of an unnamed struct
+ to name the struct for linkage purposes even if it has attributes.
+ (start_decl): In that case, set ATTR_FLAG_TYPE_IN_PLACE.
+
+2008-02-26 Tom Tromey <tromey@redhat.com>
+
+ * parser.c (eof_token): Remove old location code.
+ (check_empty_body): Remove test of USE_MAPPED_LOCATION.
+ * decl2.c (generate_ctor_or_dtor_function): Remove old location
+ code.
+ (cp_write_global_declarations): Likewise.
+ * lex.c (cxx_init): Remove old location code.
+ (handle_pragma_implementation): Remove test of
+ USE_MAPPED_LOCATION.
+ * pt.c (tsubst): Remove old location code.
+ * error.c (cp_print_error_function): Remove test of
+ USE_MAPPED_LOCATION.
+ * decl.c (pop_label): Remove old location code.
+ (finish_function): Likewise.
+
+2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 26264
+ * call.c (magic_varargs_p): Remove BUILT_IN_STDARG_START.
+
+2008-02-26 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (duplicate_decls): Remove decl from global mapping
+ before ggc_freeing it.
+
+2008-02-26 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/35323
+ * name-lookup.c (arg_assoc_type): Handle FIXED_POINT_TYPE.
+
+2008-02-26 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * typeck.c (build_class_member_access_expr): Add appropriate
+ OPT_W* parameter to warning.
+ (build_reinterpret_cast_1): Likewise.
+ * name-lookup.c (push_overloaded_decl): Likewise.
+
+2008-02-25 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/35333
+ * error.c (dump_expr): Handle CONJ_EXPR.
+
+2008-02-25 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/35338
+ * error.c (dump_type): Handle FIXED_POINT_TYPE.
+ (dump_expr): Handle FIXED_CST.
+
+2008-02-24 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_declaration): Handle "inline namespace".
+ (cp_parser_namespace_definition): Likewise.
+
+ PR c++/33486
+ * name-lookup.c (arg_assoc_namespace): Look down into inline
+ namespaces, too.
+
+2008-02-23 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * typeck.c (check_for_casting_away_constness): Use 1 single
+ argument, the type of cast, to decide what diagnostics generate.
+ (build_static_cast_1): Remove unused code. Update call to
+ check_for_casting_away_constness.
+ (build_reinterpret_cast_1): Update call to
+ check_for_casting_away_constness.
+ (build_const_cast_1): Likewise.
+
+2008-02-24 Paolo Carlini <pcarlini@suse.de>
+
+ * error.c (dump_expr): Don't deal directly with NEW_EXPR (and
+ VEC_NEW_EXPR), forward to pp_expression.
+ * cxx-pretty-print.c (pp_cxx_new_expression): Fix FIXME.
+
+2008-02-24 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/34749
+ * friend.c (do_friend): Call cplus_decl_attributes earlier.
+
+2008-02-22 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR C++/34715
+ * decl.c (duplicate_decls): Merge DECL_DISREGARD_INLINE_LIMITS for
+ template decls' function decl.
+
+2008-02-22 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/35282
+ Revert:
+ 2008-02-14 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/28743
+ * pt.c (determine_specialization): In case of function templates,
+ when the type of DECL does not match FN there is no match.
+
+2008-02-22 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ PR c/19999
+ * typeck.c (build_binary_op): Warn about floating point
+ comparisons if FLOAT_TYPE_P, not only for REAL_TYPE.
+
+2008-02-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/34950
+ * pt.c (resolve_overloaded_unification): Set processing_template_decl
+ while we look for possible bindings.
+
+2008-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35028
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Handle vararg copy ctors.
+
+ PR c++/34964
+ PR c++/35244
+ * semantics.c (finish_omp_threadprivate): Do nothing for error_operand_p
+ vars. Afterwards ensure v is VAR_DECL.
+
+ PR c++/35078
+ * parser.c (cp_parser_omp_for_loop): If DECL has REFERENCE_TYPE, don't
+ call cp_finish_decl.
+ * semantics.c (finish_omp_for): Fail if DECL doesn't have integral type
+ early.
+
+2008-02-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/35023
+ PR c++/35024
+ PR c++/35026
+ * pt.c (finish_member_template_decl): If the type in a TYPE_DECL
+ is error_mark_node, return an error early.
+ (find_parameter_packs_r): Pass the pointer set along to recursive
+ calls of cp_walk_subtrees; don't try to manage the pointer set
+ ourselves.
+ (uses_parameter_packs): Pass the pointer set to cp_walk_tree.
+ (make_pack_expansion): Ditto.
+ (check_for_bare_parameter_packs): Ditto. Also, don't bother taking
+ a second pass through the tree with find_parameter_packs_r; that
+ second pass no longer does anything.
+ (push_template_decl_real): If we have an erroneous declaration,
+ set its type to error_mark_node before returning an error.
+
+2008-02-14 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34050
+ * pt.c (tsubst_initializer_list): Deal with the use of
+ VOID_TYPE_NODE to indicate value-initialization of the bases.
+
+2008-02-14 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/5645
+ PR c++/11159
+ * class.c (type_has_user_nondefault_constructor): New fn.
+ * cp-tree.h: Declare it.
+ * init.c (emit_mem_initializers): Use it for -W warning about
+ missing base initializer.
+
+2008-02-14 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/28743
+ * pt.c (determine_specialization): In case of function templates,
+ when the type of DECL does not match FN there is no match.
+
+2008-02-13 Jakub Jelinek <jakub@redhat.com>
+ Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/35138
+ * parser.c (cp_parser_pseudo_destructor_name): If next tokens
+ are not identifier :: ~, return before calling cp_parser_type_name.
+
+2008-02-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/34962, c++/34937, c++/34939
+ * decl2.c (is_late_template_attribute): Always defer attributes
+ vector_size and weak.
+
+ PR c++/34774
+ * pt.c (value_dependent_expression_p): Look into DECL_INITIAL
+ of enumerators, too.
+
+2008-02-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/34824
+ * call.c (convert_like_real): Pass LOOKUP_NO_CONVERSION to build_temp
+ if we're doing conversions to call a user-defined conversion function.
+
+2008-02-12 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR c++/29048
+ * semantics.c (finish_qualified_id_expr): Avoid duplicate access
+ check here, too.
+
+2008-02-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34862
+ * init.c (build_new_1): Don't create placement_expr before
+ constructing alloc_call. Verify that the pointer is passed by
+ value to operator new.
+
+2008-02-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/35097
+ * pt.c (tsubst): Don't look up a template typedef in an explicit
+ specialization.
+
+2008-02-11 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/35113
+ * tree.c (cp_build_qualified_type_real): When building a
+ cv-qualified array type, build it as a unique type with
+ build_cplus_array_type_1 and then adopt the unqualified type's
+ main variant.
+
+2008-02-11 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/35077
+ * decl.c (groktypename): Check grokdeclarator return.
+
+2008-02-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/34094
+ * decl2.c (cp_write_global_declarations): Don't write out static
+ data members with DECL_IN_AGGR_P set.
+
+2008-02-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/35116
+ * tree.c (build_target_expr_with_type): Handle void initializer.
+ (bot_manip): Remap slot before recursing.
+
+2008-02-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ PR other/35107
+ * Make-lang.in (cc1plus-dummy, cc1plus): Add $(GMPLIBS).
+
+2008-02-06 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/35056
+ * tree.c: Include tree-flow.h.
+ (build_target_expr): Check type compatibility.
+ * Make-lang.in (cp/tree.o): Depend on $(TREE_FLOW_H).
+ * call.c (convert_like_real): Convert bitfield to expected type.
+
+2008-02-06 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/35049
+ PR c++/35096
+ * typeck.c (structural_comptypes): Call cp_comptypes.
+ (comptypes): New; called from the C/C++ common bits to perform
+ strict checks.
+ (cp_comptypes): Renamed from comptypes, which is already used,
+ with a different signature, by the C++ front end.
+ (build_reinterpret_cast_1): Call cp_comptypes.
+ (ptr_reasonably_similar): Ditto.
+ * decl.c (decls_match): Ditto.
+ * cvt.c (convert_to_reference): Ditto.
+ * cp-tree.h (same_type_p): Ditto.
+ (same_or_base_type_p): Ditto.
+ (comptypes): Rename to cp_comptypes.
+ * pt.c (canonical_type_parameter): Call cp_comptypes.
+
+2008-02-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33553
+ * pt.c (tsubst) <case INTEGER_TYPE>: Don't issue error if max is
+ value dependent expression.
+
+2008-02-05 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/35074
+ * decl2.c (save_template_attributes): When we're modifying the
+ TYPE_MAIN_VARIANT to add new attributes, be sure to also modify
+ all of the other variants to add those same attributes. Otherwise,
+ the main variant will be inconsistent with those other variants.
+
+2008-02-04 Richard Guenther <rguenther@suse.de>
+
+ PR java/35035
+ * decl.c (record_builtin_java_type): Make jboolean a
+ integer type again where its mode doesn't match that of bool.
+
+2008-02-02 Jason Merrill <jason@redhat.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/33916
+ * init.c (build_value_init_1): New function.
+ (build_value_init): New function.
+ * typeck2.c (build_functional_cast): Call it.
+ * cp-gimplify.c (cp_gimplify_init_expr): Handle its output.
+
+ * cp-tree.h (TYPE_HAS_USER_CONSTRUCTOR): Rename from
+ TYPE_HAS_CONSTRUCTOR.
+ * class.c (finish_struct_bits, maybe_warn_about_overly_private_class,
+ add_implicitly_declared_members): Adjust.
+ (check_field_decls): Adjust. Remove warnings about reference/const
+ in class without constructor.
+ (check_bases_and_members): Adjust. Give those warnings here instead.
+ * decl.c (fixup_anonymous_aggr): Adjust.
+ (check_initializer): Adjust, clarify logic slightly.
+ (grok_special_member_properties): Adjust, only set if user-provided.
+ * rtti.c (create_tinfo_types): Don't set.
+ * cvt.c (ocp_convert): Remove exception for vtable_entry_type et al.
+ Use same_type_ignoring_top_level_qualifiers_p.
+ * pt.c (check_explicit_specialization): Adjust.
+ (instantiate_class_template): Adjust.
+
+2008-01-31 Douglas Gregor <doug.gregor@gmail.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34935
+ PR c++/34936
+ * typeck.c (structural_comptypes): Handle comparisons of
+ VOID_TYPE, BOOLEAN_TYPE, INTEGER_TYPE, FIXED_POINT_TYPE, and
+ REAL_TYPE nodes.
+ * mangle.c (write_builtin_type): Map down to the canonical type,
+ which will be one of the predefined type nodes.
+
+2008-01-29 Michael Meissner <michael.meissner@amd.com>
+
+ PR 35004
+ * cp-tree.h (struct full_lang_decl): Make tree_code bitfield 16
+ bits to allow for expansion of the number of middle end tree
+ codes.
+
+2008-01-29 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34055
+ PR c++/34103
+ PR c++/34219
+ PR c++/34606
+ PR c++/34753
+ PR c++/34754
+ PR c++/34755
+ PR c++/34919
+ PR c++/34961
+ * typeck.c (check_return_expr): Tweak call to
+ check_for_bare_parameter_packs.
+ * class.c (add_method): Be careful with error_mark_nodes.
+ * cp-tree.h (check_for_bare_parameter_packs): Remove "*" from
+ signature.
+ * pt.c (struct find_parameter_pack_data): Remove
+ SET_PACKS_TO_ERROR.
+ (find_parameter_packs_r): Don't use SET_PACKS_TO_ERROR.
+ (uses_parameter_packs): Don't set SET_PACKS_TO_ERROR.
+ (make_pack_expansion): Ditto.
+ (check_for_bare_parameter_packs): Parameter is now a tree, not a
+ tree*.
+ (process_template_parm): Tweak call to
+ check_for_bare_parameter_packs.
+ (push_template_decl_real): Tweak calls to
+ check_for_bare_parameter_packs. If bare parameter packs are found
+ in the list of exceptions, clear out that list after giving an
+ error.
+ * semantics.c (finish_cond): Tweak call to
+ check_for_bare_parameter_packs.
+ (finish_expr_stmt): Ditto.
+ (finish_for_expr): Ditto.
+ (finish_switch_cond): Ditto.
+ (finish_mem_initializers): Ditto.
+ (finish_member_declaration): Ditto.
+ (finish_static_assert): Check for bare parameter packs in the
+ condition.
+ * decl2.c (cplus_decl_attributes): Check for bare parameter packs in the
+ attributes of a declaration.
+ * parser.c (cp_parser_using_declaration): Tweak call to
+ check_for_bare_parameter_packs.
+ (cp_parser_base_clause): Ditto.
+
+2008-01-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/35007
+ * class.c (build_base_path): Fix !want_pointer case.
+
+2008-01-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/27177
+ * class.c (build_base_path): Fix previous change.
+
+2008-01-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34965
+ * error.c (dump_expr): Handle TRUTH_AND_EXPR, TRUTH_OR_EXPR
+ and TRUTH_XOR_EXPR.
+
+2008-01-26 Richard Guenther <rguenther@suse.de>
+
+ PR c++/34235
+ * typeck.c (build_binary_op): Remove code to shorten compares.
+
+2008-01-25 Richard Guenther <rguenther@suse.de>
+
+ PR c++/33887
+ * decl.c (record_builtin_java_type): Make __java_boolean
+ a variant of bool.
+ * typeck.c (structural_comptypes): Move TYPE_FOR_JAVA check
+ after TYPE_MAIN_VARIANT check.
+
+2008-01-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/27177
+ * class.c (build_base_path): Don't mess with virtual access if
+ skip_evaluation.
+ * call.c (standard_conversion): Don't check whether source type
+ is complete.
+
+ * decl2.c (is_late_template_attribute): Don't defer attribute
+ visibility just because the type is dependent.
+
+2008-01-25 Jason Merrill <jason@redhat.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/31780
+ * call.c (standard_conversion): Allow conversion from integer/real
+ to complex.
+ (compare_ics): Such a conversion is worse than a normal arithmetic
+ conversion.
+
+2008-01-25 Richard Guenther <rguenther@suse.de>
+
+ PR c++/33887
+ * cp-lang.c (LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS): Define
+ to true.
+
+2008-01-24 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/34603
+ * pt.c (push_template_decl_real): Return error_mark_node in case
+ of template definition of non-template.
+
+2008-01-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/34913
+ * decl2.c (is_late_template_attribute): Defer any attribute with
+ dependent args. Also defer type attributes if the type is dependent.
+
+2008-01-22 Jakub Jelinek <jakub@redhat.com>
+ Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/33984
+ * call.c (reference_binding): For bitfields use the declared bitfield
+ type.
+ (add_builtin_candidates): Likewise.
+ * class.c (layout_class_type): For bitfields copy over the
+ original type quals.
+
+2008-01-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/28560
+ * decl.c (groktypename): Also ignore attributes on dependent
+ possibly-class types.
+
+ PR c++/34912
+ * friend.c (do_friend): Check for prior declaration of a friend
+ function of a local class.
+ * name-lookup.c (lookup_name_innermost_nonclass_level):
+ No longer static.
+ * name-lookup.h: Declare it.
+
+2008-01-22 Tom Tromey <tromey@redhat.com>
+
+ PR c++/34829:
+ * init.c (build_new_1): Only disallow Java aggregates.
+
+2008-01-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34607
+ * semantics.c (finish_omp_for): Don't call c_finish_omp_for
+ if decl or init is error_mark_node.
+
+ PR c++/34918
+ * error.c (dump_expr): Handle VECTOR_CST.
+
+2008-01-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/33959
+ * pt.c (tsubst_aggr_type): Make sure our context is complete.
+
+ PR c++/34573
+ * pt.c (retrieve_local_specialization): Robustify.
+ (tsubst_pack_expansion, tsubst_decl): Remove redundant checks.
+
+ PR c++/34846
+ * pt.c (tsubst): Only call retrieve_local_specialization if the
+ original typedef was in a function template.
+
+ PR c++/34196
+ * decl.c (wrap_cleanups_r): Set TRY_CATCH_IS_CLEANUP.
+
+2008-01-21 Richard Guenther <rguenther@suse.de>
+
+ PR c++/34850
+ * error.c (cp_print_error_function): Deal with recursive
+ BLOCK trees.
+
+2008-01-20 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/34891
+ * error.c (dump_expr): Deal with VIEW_CONVERT_EXPR.
+
+2008-01-20 Paolo Carlini <pcarlini@suse.de>
+
+ PR c++/34776
+ PR c++/34486
+ * name-lookup.c (do_class_using_decl): Do not call constructor_name_p
+ on non-IS_AGGR_TYPE scope.
+ (constructor_name_p): Assert IS_AGGR_TYPE.
+
+2008-01-18 Ian Lance Taylor <iant@google.com>
+
+ PR c++/33407
+ * decl.c (duplicate_decls): Copy DECL_IS_OPERATOR_NEW flag.
+ (grok_op_properties): For NEW_EXPR and VEC_NEW_EXPR set
+ DECL_IS_OPERATOR_NEW flag.
+
+2008-01-16 Richard Guenther <rguenther@suse.de>
+
+ PR c++/33819
+ * typeck.c (is_bitfield_expr_with_lowered_type): Recurse
+ for conversions to type variants.
+
+2008-01-15 Andreas Tobler <a.tobler@schweiz.org>
+
+ * parser.c (cp_parser_template_parameter): Fix C90 issue with mixing
+ declaration and code. Update copyright year.
+
+2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34399
+ * friend.c (do_friend): Don't query TYPE_BEING_DEFINED unless we
+ know we have a class type.
+
+2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34751
+ * pt.c (coerce_template_parameter_pack): When substituting into
+ the type of a non-type template parameter pack. use the
+ deduced/substituted arguments.
+ * parser.c (declarator_can_be_parameter_pack): A pointer-to-member
+ can be a parameter pack with the ellipsis following it. When we
+ have an erroneous declaration, allow it to be a parameter pack.
+ (cp_parser_template_parameter): Complain about default
+ arguments on non-type template parameter packs, and parse them
+ using the new cp_parser_default_argument.
+ (cp_parser_parameter_declaration): Complain about parameter packs
+ with default arguments. Move parsing of default arguments into a
+ new function, cp_parser_default_argument.
+ (cp_parser_default_argument): New; extracted from
+ cp_parser_parameter_declaration.
+
+2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34051
+ PR c++/34055
+ PR c++/34102
+ PR c++/34103
+ * typeck.c (check_return_expr): If there are bare parameter packs
+ in the return value, set it to error_mark_node.
+ * tree.c (cp_walk_subtrees): Walk USING_DECL nodes.
+ * pt.c (find_parameter_packs_r): Look at the type of
+ IDENTIFIER_NODEs (e.g., for user-defined conversions).
+ (check_for_bare_parameter_packs): Flip the result: now returns
+ TRUE when there were bare parameter packs, FALSE otherwise.
+ (push_template_decl_real): Deal with flipped result of
+ check_for_bare_parameter_packs.
+ * semantics.c (finish_cond): If there are bare parameter packs in
+ the conditional, set it to error_mark_node.
+ (finish_expr_stmt): If there are bare parameter packs in the
+ expression, set it to error_mark_node.
+ (finish_for_expr): Ditto.
+ (finish_switch_cond): If there are bare parameter packs in
+ the conditional, set it to error_mark_node.
+ (finish_mem_initializers): If there are bare parameter packs in
+ the member initializer, set it to error_mark_node.
+ (finish_member_declaration): Check the attributes of the
+ declaration for bare parameter packs, and remove the attributes if
+ any have bare parameter packs.
+ * parser.c (cp_parser_using_declaration): Check the using
+ declaration for bare parameter packs.
+ (cp_parser_base_clause): If there are bare parameter packs in a
+ base specifier, don't add it to the chain.
+
+2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34314
+ * error.c (dump_simple_decl): Display ellipsis for template
+ non-type parameter packs.
+ (dump_decl): Display ellipsis for template type parameter packs.
+ (dump_template_decl): Display ellipsis for template template
+ parameter packs.
+ * pt.c (redeclare_class_template): When redeclaring a class
+ template, check for collisions between template parameters and
+ template parameter packs.
+
+2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33964
+ * pt.c (process_partial_specialization): Don't mark template
+ parameters that occur in non-deduced contexts.
+ (struct pair_fn_data): Add include_nondeduced_p.
+ (for_each_template_parm_r): Only visit non-deduced contexts if
+ include_nondeduced_p is set.
+ (for_each_template_parm): Added parameter include_nondeduced_p,
+ which states whether template parameters found in non-deduced
+ contexts should be visited.
+ (uses_template_parms): Visit all template parameters, even those
+ in non-deduced contexts.
+
+2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34052
+ * pt.c (check_default_tmpl_args): Check for parameter packs that
+ aren't at the end of a primary template.
+ (push_template_decl_real): Remove check for parameter packs that
+ aren't at the end of a primary template; that now happens in
+ check_default_tmpl_args.
+ * semantics.c (finish_template_template_parm): Use
+ check_default_tmpl_args to check for errors in the template
+ parameter list.
+
+2008-01-12 Doug Kwan <dougkwan@google.com>
+
+ * decl.c: (grokdeclarator): Use OPT_Wignored_qualifiers
+ instead of OPT_Wreturn_type in warning due to ignored return type
+ qualifiers.
+ * pt.c: (tsubst_function_type): Use OPT_Wignored_qualifiers
+ instead of OPT_Wreturn_type in warning due to ignored return type
+ qualifiers.
+
+2008-01-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33890
+ * semantics.c (finish_omp_for): Don't call
+ fold_build_cleanup_point_expr if processing_template_decl.
+
+2008-01-04 Paolo Carlini <pcarlini@suse.de>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34611
+ * error.c (dump_template_argument): Deal with TREE_LIST.
+
+2008-01-01 Douglas Gregor <doug.gregor@gmail.com>
+
+ * parser.c (cp_parser_check_decl_spec): Don't warn about "long
+ long" in C++0x mode; change the warning to note that "long long"
+ is only unsupported in C++98 mode.
+
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2009 b/gcc-4.9/gcc/cp/ChangeLog-2009
new file mode 100644
index 000000000..c39304c46
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2009
@@ -0,0 +1,3746 @@
+2009-12-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/42447
+ * pt.c (iterative_hash_template_arg): Don't rely on TYPE_CANONICAL
+ for ARRAY_TYPE.
+
+2009-12-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/41305, DR 384
+ * name-lookup.c (arg_assoc_class): Split out arg_assoc_class_only
+ and arg_assoc_bases.
+ (friend_of_associated_class_p): Remove.
+ (arg_assoc_namespace): Don't call it.
+ (arg_assoc_template_arg): Use arg_assoc_class_only for member
+ template context.
+ (arg_assoc_type): Handle UNION_TYPE and ENUMERAL_TYPE properly.
+
+ * name-lookup.c (arg_assoc): Handle TEMPLATE_ID_EXPR properly.
+
+2009-12-23 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42260
+ * cp-tree.h (lookup_conversions): Add new bool parameter to
+ declaration.
+ * search.c (lookup_conversion): Use new bool parameter in
+ definition.
+ * call.c (add_builtin_candidates): Don't lookup template conversion
+ (convert_class_to_reference, build_user_type_conversion_1,
+ build_op_call): Adjust.
+ * cvt.c (build_expr_type_conversion): Likewise
+
+2009-12-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/42466
+ * pt.c (reduce_template_parm_level): Check the type before
+ returning cached TEMPLATE_PARM_INDEX.
+
+ PR c++/42331
+ * typeck.c (cp_build_modify_expr): Fix thinko.
+
+2009-12-21 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_member_name): Move abi-version=1 code back to...
+ (write_expression): ...here.
+
+2009-12-21 Brian Hackett <bhackett1024@gmail.com>
+
+ * decl.c (finish_function): Rename pre-genericize event.
+
+2009-12-19 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42225
+ * pt.c (push_template_decl_real): Set DECL_CONTEXT of template type parms
+ to their containing template decl.
+ * typeck.c (comp_template_parms_position): Split this from
+ structural_comptypes.
+ (incompatible_template_type_parms_p): Renamed
+ incompatible_dependent_typedefs_p into this. Change the function to
+ handle comparison between TEMPLATE_TYPE_PARMs only.
+ (structural_comptypes): Use comp_template_parms_position in
+ TEMPLATE_TEMPLATE_PARM and BOUND_TEMPLATE_TEMPLATE_PARM cases.
+ Use incompatible_template_type_parms_p in TEMPLATE_TYPE_PARM case.
+ * mangle.c (decl_mangling_context): Template type parms don't have
+ a mangling context.
+ * tree.c (cp_set_underlying_type): Set type structural equality
+ only for TEMPLATE_TYPE_PARMs.
+
+2009-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/28300
+ PR c++/42062
+ * pt.c (check_specialization_namespace): Complain about
+ specialization at non-namespace scope.
+
+ PR c++/42415
+ * call.c (build_new_method_call): Complain about calling the
+ constructor directly.
+
+2009-12-18 Shujing Zhao <pearly.zhao@oracle.com>
+
+ PR c++/31665
+ * decl.c (duplicate_decls, grokdeclarator): Put the diagnostics in
+ full sentences for easy translation and wrapped into G_().
+ * typeck.c (build_x_unary_op): Likewise.
+
+2009-12-17 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * call.c (build_over_call, build_java_interface_fn_ref): Update
+ cp_build_indirect_ref calls.
+ * typeck2.c (build_m_component_ref): Likewise.
+
+2009-12-17 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * typeck.c (build_indirect_ref): Update the argument.
+ (build_x_indirect_ref): Likewise.
+ (cp_build_indirect_ref): Update the argument and emit the diagnostics
+ for easy translation.
+ (build_class_member_access_expr, build_array_ref,
+ get_member_function_from_ptrfunc): Update calls.
+ * cp-tree.h (build_x_indirect_ref, cp_build_indirect_ref): Update
+ prototypes.
+ * call.c (build_new_op, convert_like_real, build_x_va_arg,
+ build_over_call): Update calls.
+ * class.c (build_base_path, build_simple_base_path, build_vfn_ref):
+ Likewise.
+ * decl.c (start_preparsed_function): Likewise.
+ * except.c (expand_start_catch_block, build_throw): Likewise.
+ * init.c (emit_mem_initializers, expand_virtual_init,
+ expand_virtual_init, build_new_1, build_vec_init, build_delete,
+ build_vec_delete): Likewise.
+ * parser.c (cp_parser_unary_expression): Likewise.
+ * pt.c (tsubst_copy_and_build): Likewise.
+ * rtti.c (build_headof, get_tinfo_decl_dynamic, get_typeid): Likewise.
+ * semantics.c (finish_non_static_data_member, thisify_lambda_field):
+ Likewise.
+ * tree.c (build_dummy_object, stabilize_expr): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2009-12-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/42387
+ * decl.c (compute_array_index_type): Mark a VLA as dependent.
+
+2009-12-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/42358
+ * pt.c (iterative_hash_template_arg): Completely ignore
+ ARGUMENT_PACK_SELECT.
+
+2009-12-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/41183
+ * cp-tree.h (current_class_ptr): Give NULL even when cfun
+ has NULL cfun->language.
+
+2009-12-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/42364
+ * pt.c (function_parameter_expanded_from_pack_p): Don't require
+ a pack to have a name.
+ (tsubst_decl): Do typedef magic after applying attributes.
+
+2009-12-15 Paolo Bonzini <bonzini@gnu.org>
+ Shujing Zhao <pearly.zhao@oracle.com>
+
+ * Makefile.in (cp/pt.o): Depend on intl.h
+ * call.c (print_z_candidates): Make loop more compact,
+ choose head string depending on number of candidates,
+ extract creation of spaces string to intl.c.
+ * pt.c (print_overloaded_functions): Replace with...
+ (print_candidates_1): ... this rewrite.
+ (print_candidates): Rewrite to call print_candidates_1.
+ (most_specialized_class): Make loop more compact,
+ choose head string depending on number of candidates,
+ and size indents depending on translations.
+
+2009-12-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/42219
+ * typeck.c (error_type_p): New.
+ (ptr_reasonably_similar): Use it.
+ * cp-tree.h: Declare it.
+
+2009-12-11 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42225
+ * typeck.c (incompatible_dependent_typedefs_p): New function.
+ (structural_comptypes): Use it.
+ * cp-tree.h (cp_set_underlying_type): Declare ...
+ * tree.c (cp_set_underlying_type): ... new function.
+ * class.c (build_self_reference): Use cp_set_underlying_type
+ instead of set_underlying_type.
+ * decl2.c (grokfield): Likewise.
+ * name-lookup.c (pushdecl_maybe_friend): Likewise.
+
+2009-12-11 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42251
+ * pt.c (convert_template_argument): Avoid missing folding of SCOPE_REFs.
+
+2009-12-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/42317
+ * decl2.c (cp_write_global_declarations): Clear DECL_EXTERNAL
+ also on all other functions in the same comdat group.
+ * optimize.c (maybe_clone_body): Also optimize virtual implicit
+ dtors. For virtual comdat dtors tell cgraph that base and deleting
+ dtor are in the same comdat group.
+
+2009-12-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/42010
+ * cp-tree.h (DECL_DISCRIMINATOR_SET_P): New.
+ * mangle.c (discriminator_for_local_entity): Check it.
+
+ PR c++/42277
+ * semantics.c (finish_decltype_type): Defer handling of decltype
+ of a non-dependent COMPONENT_REF in a template.
+
+2009-12-04 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42218
+ * cxx-pretty-print.c (pp_cxx_unqualified_id): Print only innermost
+ template arguments.
+
+2009-12-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/41611
+ * decl2.c (get_guard): Don't use the same comdat group as the decl.
+
+ PR c++/42266
+ * cvt.c (convert_from_reference): Do nothing if TREE_TYPE is null.
+
+2009-12-03 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42217
+ * class.c (remove_zero_width_bit_fields): The width of the bit field is
+ in DECL_SIZE, not in DECL_INITIAL.
+
+2009-12-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/42256
+ * optimize.c (maybe_clone_body): Call emit_associated_thunks
+ after expand_or_defer_fn_1.
+
+2009-12-02 Taras Glek <taras@mozilla.com>
+
+ * parser.c (cp_parser_class_specifier): Back out my previous change.
+ * semantics.c (begin_class_definition): Back out my previous change.
+
+2009-12-02 Paolo Bonzini <bonzini@gnu.org>
+ Shujing Zhao <pearly.zhao@oracle.com>
+
+ PR c++/29917
+ * call.c (op_error): Accept a boolean to indicate no match/ambiguous
+ match, instead of a string. Callers adjusted.
+
+ PR c++/34836
+ * cp-tree.h (readonly_error_kind): New type.
+ (readonly_error): Adjust prototype with new argument.
+ * typeck2.c (readonly_error): Accept readonly_error_kind as argument
+ and add macro ERROR_FOR_ASSIGNMENT to emit diagnostics.
+ * semantics.c (finish_asm_stmt): Adjust readonly_error call.
+ * typeck.c (cp_build_unary_op, cp_build_modify_expr): Likewise.
+
+ * decl.c (grokparms, grok_op_properties): Put the diagnostics in full
+ sentences for easy translation and wrap the diagnostics into G_() when
+ needed.
+ (create_array_type_for_decl): Likewise.
+ * pt.c (tsubst): Likewise.
+ * typeck2.c (cp_build_unary_op): Wrap diagnostic into _().
+ * rtti.c (build_dynamic_cast_1): Likewise.
+ * Make-lang.in: Adjust.
+
+2009-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ * g++spec.c (lang_specific_driver): Remove unused saw_verbose_flag
+ variable.
+ * pt.c (tsubst_pack_expansion): Remove unused first_arg_pack variable.
+ * init.c (build_vec_init): Remove unused size variable.
+ * typeck2.c (check_narrowing): Remove unused was_decl variable.
+ * decl.c (poplevel): Remove unused tmp and real_functionbody
+ variables.
+ (decls_match): Remove unused tree_name variable.
+ (start_decl): Remove unused type variable.
+ * parser.c (cp_parser_type_parameter): Remove unused parameter_list
+ variable.
+ (cp_parser_template_id, cp_parser_explicit_instantiation,
+ cp_parser_declarator): Remove unused token variable.
+ (cp_parser_simple_type_specifier): Remove unused id variable.
+ (cp_parser_parameter_declaration): Remove unused
+ greater_than_is_operator_p variable.
+ (cp_parser_check_declarator_template_parameters): Remove unused
+ member variable.
+ (c_parse_file): Remove unused error_occurred variable.
+ * cp-gimplify.c (cp_gimplify_init_expr): Remove unused slot variable.
+ * typeck.c (cp_build_function_call_vec): Remove unused name variable.
+ * class.c (resolve_address_of_overloaded_function): Remove unused
+ is_reference variable.
+ (build_rtti_vtbl_entries): Remove unused basetype variable.
+ * mangle.c (write_template_param): Remove unused parm_level and
+ parm_type variables.
+
+2009-12-01 Taras Glek <taras@mozilla.com>
+
+ * parser.c (cp_parser_class_specifier): Set class location to that
+ of IDENTIFIER_NODE instead of '{' when possible.
+
+2009-12-01 Taras Glek <taras@mozilla.com>
+
+ * semantics.c (begin_class_definition): Do not overide locations with less precise ones.
+
+2009-12-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/41611
+ * decl2.c (get_guard): Copy DECL_COMDAT.
+ (comdat_linkage): Set DECL_COMDAT unconditionally.
+
+2009-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/3187
+ * optimize.c (cdtor_comdat_group): New function.
+ (maybe_clone_body): Also optimize DECL_COMDAT base/complete cdtors
+ and in that case put also the deleting dtor in the same comdat group
+ as base and complete dtor if dtor is virtual.
+
+2009-11-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/40371
+ * call.c (add_template_candidate_real): Early return NULL if
+ the arglist length is smaller than skip_without_in_chrg; tidy.
+
+2009-11-30 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42069
+ * pt.c (convert_template_argument): Strip typedefs from SCOPE_REFs.
+
+2009-11-29 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/36408
+ * semantics.c (empty_expr_stmt_p): Handle void_zero_node and fix
+ bad indentation.
+ * pt.c (tsubst_copy_and_build): Fix typo.
+
+2009-11-29 Jan Hubicka <jh@suse.cz>
+
+ * optimize.c (maybe_clone_body): Emit thunks associated to alias.
+ * Make-lang.in (method.o): Add dependency on gimple.h.
+ * method.c: Include gimple.h
+ (make_alias_for_thunk): Use same body alias instead of assemble_alias.
+ (use_thunk): Drop codegen; use cgraph_add_thunk; gimplify
+ generic thunks.
+ * semantics.c (expand_or_defer_fn): Emit associated thunks.
+
+2009-11-28 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/36408
+ * cp-tree.h (empty_expr_stmt_p): Declare ...
+ * semantics.c (empty_expr_stmt_p): ... this.
+ * pt.c (tsubst_copy_and_build) <STMT_EXPR>: Use it.
+
+2009-11-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/38656
+ * cxx-pretty-print.c (pp_cxx_expression): Handle TEMPLATE_ID_EXPR.
+
+2009-11-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/35112
+ * pt.c (print_overloaded_functions): New.
+ (print_candidates): Call the latter.
+ * parser.c (cp_parser_class_name): Do not duplicate the diagnostics
+ after the cp_parser_lookup_name call.
+
+2009-11-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/42026, DR 239
+ * parser.c (cp_parser_postfix_expression): A local extern also
+ prevents arg-dependent lookup.
+
+2009-11-26 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * decl.c (grokdeclarator): Remove period at end of diagnosic message.
+
+2009-11-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/10690
+ * rtti.c (get_tinfo_decl_dynamic): Call resolve_nondeduced_context.
+
+2009-11-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/42137
+ * parser.c (cp_parser_mem_initializer_id): Pass typename_type to
+ cp_parser_class_name.
+ (cp_parser_unqualified_id): Same, rather than class_type.
+
+ PR c++/11764
+ * parser.c (cp_parser_expression_statement): Give helpful error
+ for constructor name used as type.
+
+ * pt.c (determine_specialization): Give helpful error about missing
+ "template<>".
+
+2009-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/42095
+ * tree.c: Include cgraph.h.
+ (cp_fix_function_decl_p): Don't return true for same_body aliases.
+ * Make-lang.in (cp/tree.o): Depend on $(CGRAPH_H).
+
+2009-11-23 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/14777
+ * cp-tree.def <TEMPLATE_INFO>: Declare new kind of tree
+ node.
+ * cp-tree.h (struct tree_template_info,
+ struct qualified_typedef_usage_s): New.
+ (cp_tree_node_structure_enum): add TS_CP_TEMPLATE_INFO.
+ (union lang_tree_node): Add template_info.
+ (TI_TEMPLATE, TI_ARGS, TI_TYPEDEFS_NEEDING_ACCESS_CHECKING):
+ Adjust.
+ (build_template_info): Declare.
+ (get_types_needing_access_check): Adjust return type.
+ (add_typedef_to_current_template_for_access_check): Declare.
+ * cp-objcp-common.c (cp_tree_size): Handle TEMPLATE_INFO.
+ * semantics.c (add_typedef_to_current_template_for_access_check):
+ Split from ...
+ (check_accessibility_of_qualified_id): ... here.
+ * decl.c (make_typename_type): Use it.
+ * pt.c (build_template_info): Define.
+ (check_explicit_specialization, find_parameter_packs_r,
+ push_template_decl_real, lookup_template_class,
+ for_each_template_parm_r, tsubst_decl, tsubst): Use
+ build_template_info.
+ (get_types_needing_access_check): Adjust return type.
+ (append_type_to_template_for_access_check_1): Record the
+ location of the usage point of the typedef. Adjust to TEMPLATE_INFO.
+ (append_type_to_template_for_access_check): Add new location
+ parameter. Pass it to append_type_to_template_for_access_check_1.
+ Adjust to TEMPLATE_INFO.
+ (perform_typedefs_access_check): Temporarily set input_location to
+ the usage point of the typedef we are checking access for. Adjust
+ to new TEMPLATE_INFO tree node.
+ * tree.c (bind_template_template_parm): Use build_template_info.
+ * call.c (add_template_candidate_real): Likewise.
+ * decl.c (grokfndecl): Likewise.
+ (cp_tree_node_structure): Handle TEMPLATE_INFO.
+
+2009-11-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/9050, DR 147, DR 318
+ * parser.c (cp_parser_lookup_name): If the name matches the explicit
+ class scope, we're naming the constructor.
+ (cp_parser_constructor_declarator_p): Just use cp_parser_unqualified_id
+ if we have a nested-name-specifier.
+ (cp_parser_direct_declarator): Handle getting an overload set as a
+ constructor declarator.
+ (cp_parser_unqualified_id): Avoid looking up the constructor when
+ naming the destructor.
+ (cp_parser_diagnose_invalid_type_name): Give good
+ diagnostic for improper use of constructor as template.
+ * typeck.c (finish_class_member_access_expr): Give good diagnostic
+ about calling constructor.
+
+ * error.c (dump_aggr_type): Don't print A::A for injected-class-name.
+
+2009-11-20 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/38646
+ * pt.c (process_partial_specialization): Do not turn wrongly located
+ parameter pack arguments into error_mark_node.
+ Split too long lines into two.
+
+2009-11-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/42060
+ * except.c (build_throw): Check the tree returned by
+ decay_conversion for error_mark_node.
+
+2009-11-20 Shujing Zhao <pearly.zhao@oracle.com>
+
+ PR c++/29017
+ * cp-tree.h (composite_pointer_operation): New type.
+ (composite_pointer_type): Adjust prototype with new argument.
+ * typeck.c (composite_pointer_type): Accept
+ composite_pointer_operation as argument and emit diagnostic to be
+ visible to gettext and checked at compile time.
+ (composite_pointer_type_r): Likewise.
+ (common_pointer_type): Update call to composite_pointer_type.
+ (cp_build_binary_op): Likewise.
+ * call.c (build_conditional_expr): Likewise.
+
+2009-11-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/42115
+ * call.c (build_op_delete_call): Don't complain about using
+ op delete (void *, size_t) for placement delete if there's an
+ op delete (void *).
+
+ DR 176 permissiveness
+ * class.c (build_self_reference): Call set_underlying_type.
+ * decl.c (check_elaborated_type_specifier): Don't complain about
+ injected-class-name.
+ (type_is_deprecated): Use TYPE_MAIN_VARIANT.
+ * pt.c (convert_template_argument): Handle injected-class-name used
+ as template template argument.
+ * typeck2.c (abstract_virtuals_error): Use TYPE_MAIN_VARIANT.
+
+ PR c++/561
+ * decl.c (static_fn_type): Split out...
+ (revert_static_member_fn): ...from here.
+ * cp-tree.h: Declare it.
+ * class.c (resolve_address_of_overloaded_function): Use it to compare
+ pointers to member functions.
+ * typeck.c (build_static_cast_1): Call instantiate_type.
+
+2009-11-18 Shujing Zhao <pearly.zhao@oracle.com>
+
+ PR c++/40892
+ * error.c (maybe_warn_cpp0x): Accept enum cpp0x_warn_str as argument.
+ (maybe_warn_variadic_templates): Update the maybe_warn_cpp0x calls to
+ match the new declaration.
+ * cp-tree.h (cpp0x_warn_str): New type.
+ (maybe_warn_cpp0x): Adjust prototype with new argument.
+ * call.c (reference_binding): Update the maybe_warn_cpp0x calls.
+ * decl.c (reshape_init_r, check_initializer, grokdeclarator):
+ Likewise.
+ * parser.c (cp_parser_primary_expression)
+ (cp_parser_parenthesized_expression_list, cp_parser_new_initializer)
+ (cp_parser_assignment_expression, cp_parser_condition)
+ (cp_parser_jump_statement, cp_parser_mem_initializer)
+ (cp_parser_simple_type_specifier, cp_parser_elaborated_type_specifier)
+ (cp_parser_enum_specifier, cp_parser_initializer)
+ (cp_parser_pure_specifier, cp_parser_functional_cast): Likewise.
+
+2009-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/3187
+ * cp-tree.h (expand_or_defer_fn_1): New prototype.
+ * decl2.c (cp_write_global_declarations): Mark as !DECL_EXTERNAL
+ also all same_body aliases.
+ * semantics.c (expand_or_defer_fn): Move most of the function
+ except registering with cgraph to ...
+ (expand_or_defer_fn_1): ... here. New function.
+ * optimize.c: Include cgraph.h.
+ (maybe_clone_body): If in charge parm is not used and both base
+ and complete clones are created and are not comdat, tell cgraph
+ they have the same body.
+ * Make-lang.in (cp/optimize.o): Depend on $(CGRAPH_H).
+
+2009-11-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/42058
+ * typeck2.c (digest_init_r): Check init for error_operand_p.
+ * decl.c (reshape_init_class): Check return value of reshape_init_r
+ for error_mark_node.
+
+2009-11-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/42061
+ * call.c (reference_binding): Return NULL for initializer list with
+ error operand inside of it.
+
+ PR c++/42059
+ * typeck.c (cp_build_modify_expr): For initializer list call
+ check_array_initializer to make sure lhs isn't a VLA.
+
+2009-11-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/189, c++/9937, c++/13950, DR 176
+ * search.c (lookup_field_r): Allow lookup to find the
+ injected-class-name from a template base.
+ (template_self_reference_p): Remove.
+ * decl.c (make_typename_type): Diagnose ambiguity. Use
+ maybe_get_template_decl_from_type_decl.
+ * parser.c (cp_parser_template_name): Pass true to is_template
+ rather than use maybe_get_template_decl_from_type_decl.
+ (cp_parser_lookup_name): Use maybe_get_template_decl_from_type_decl.
+ * pt.c (maybe_get_template_decl_from_type_decl): Handle ambiguity.
+ Use DECL_SELF_REFERENCE_P.
+
+ * parser.c (cp_parser_parse_and_diagnose_invalid_type_name):
+ Avoid duplicate ambiguity error.
+ * error.c (dump_decl): Don't say "typedef" for injected-class-name.
+ * pt.c (convert_template_argument): Tweak logic.
+
+2009-11-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/42055
+ * pt.c (determine_specialization): Assign to candidates the return
+ value of the chainon called before print_candidates.
+
+2009-11-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/32056
+ * decl.h (enum decl_context): Add TPARM enumerator.
+ * decl.c (grokdeclarator): Per 14.1/2, error out if a storage class
+ is specified in a template parameter declaration.
+ * parser.c (cp_parser_template_parameter): Call grokdeclarator with
+ TPARM as third argument.
+
+2009-11-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/27425
+ PR c++/34274
+ * pt.c (expand_template_argument_pack): Handle null arg gracefully.
+ (convert_template_argument): Use %T for type.
+
+ PR c++/29363
+ * decl.c (create_implicit_typedef): Set TYPE_STUB_DECL here.
+ (cxx_init_decl_processing): Not here.
+ * name-lookup.c (pushtag): Or here.
+ * pt.c (lookup_template_class): Or here.
+
+ PR c++/35075
+ * pt.c (convert_nontype_argument): Give helpful error about
+ reference variable argument to reference template parameter.
+
+ PR c++/21008, DR 515
+ * semantics.c (finish_non_static_data_member): Don't check
+ derivation in a template.
+
+ PR c++/11987
+ * parser.c (cp_parser_direct_declarator): Give helpful error about
+ trying to define member of a dependent typedef.
+ * pt.c (resolve_typename_type): Don't resolve a typedef typename.
+ * tree.c (typedef_variant_p): New.
+ * cp-tree.h: Declare it.
+
+2009-11-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/27078
+ * parser.c (cp_parser_primary_expression): Don't give a duplicate
+ ambiguity error.
+
+ PR c++/39560
+ * decl2.c (build_anon_union_vars): Set DECL_ARTIFICIAL.
+
+ PR c++/37037
+ * decl.c (grokdeclarator): Don't generate a void PARM_DECL.
+
+ PR c++/42013
+ * call.c (build_conditional_expr): Check specifically for folding
+ to CALL_EXPR rather than TREE_SIDE_EFFECTS.
+
+ * typeck.c (cv_qualified_p): New fn.
+ (decay_conversion): Use it.
+ * cp-tree.h: Declare it.
+ * tree.c (rvalue): Use it and cv_unqualified.
+ * init.c (build_aggr_init): Likewise.
+
+ PR c++/42013
+ * call.c (build_conditional_expr): Don't fold a TREE_SIDE_EFFECTS
+ COND_EXPR in unevaluated context.
+
+2009-11-12 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (constrain_visibility): Clear WEAK and COMMON flags.
+
+2009-11-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/39131
+ * rtti.c (emit_support_tinfos): Add DFP types.
+
+ * call.c (build_op_delete_call): Downgrade error about
+ placement/non-placement confusion to permerror.
+
+2009-11-10 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_op_delete_call): Tweak error.
+
+ PR c++/34158
+ PR c++/36406
+ * call.c (non_placement_deallocation_fn_p): Split out...
+ (build_op_delete_call): ...from here. Use instantiate_type
+ for placement delete. Simplify logic.
+ * pt.c (primary_template_instantiation_p): Non-static.
+ * cp-tree.h: Declare it.
+
+2009-11-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/41972
+ * parser.c (cp_parser_template_argument): Accept SCOPE_REF around
+ VAR_DECL.
+
+ PR c++/41994
+ * pt.c (tsubst_baselink): tsubst the name.
+
+2009-11-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/37920
+ * pt.c (tsubst) [TYPEOF_TYPE]: Set cp_unevaluated_operand.
+
+ PR c++/18451
+ PR c++/40738
+ * cp-tree.h (cp_decl_specifier_seq): Add any_type_specifiers_p.
+ * parser.c (cp_parser_single_declaration): Call
+ cp_parser_parse_and_diagnose_invalid_type_name here, too.
+ (cp_parser_parameter_declaration): And here.
+ (cp_parser_parse_and_diagnose_invalid_type_name): Be
+ less picky about declarator form. Don't skip to
+ the end of the block if we're in a declarator.
+ (cp_parser_decl_specifier_seq): Set any_type_specifiers_p.
+ (cp_parser_simple_declaration): Check it.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_diagnose_invalid_type_name): Tweak error message.
+ (cp_parser_expression_statement): Likewise.
+ * decl2.c (grokfield): Mention decltype instead of typeof.
+
+2009-11-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/15946
+ * parser.c (cp_parser_check_template_parameters): Don't talk about
+ specialization at function scope.
+ (cp_parser_diagnose_invalid_type_name): Handle dependent scope.
+ (cp_parser_parse_and_diagnose_invalid_type_name): Likewise.
+ (cp_parser_expression_statement): Suggest typename.
+ * error.c (dump_decl) [SCOPE_REF]: Print the type here.
+ (dump_expr) [SCOPE_REF]: Call it.
+ (dump_type) [UNBOUND_CLASS_TEMPLATE]: Check TFF_UNQUALIFIED_NAME.
+ * cxx-pretty-print.c (pp_cxx_unqualified_id): Print class template
+ args.
+
+ PR c++/9381
+ * decl2.c (build_memfn_type): Preserve attributes.
+ (cp_reconstruct_complex_type): Likewise.
+ (maybe_retrofit_in_chrg): Likewise.
+ * class.c (adjust_clone_args): Likewise.
+ * call.c (standard_conversion): Use build_memfn_type.
+ * pt.c (tsubst): Likewise.
+ * decl.c (build_ptrmem_type): Likewise
+ (check_function_type): Preserve attributes.
+ * tree.c (cp_build_type_attribute_variant): Propagate exception
+ specs on METHOD_TYPE, too.
+ (strip_typedefs): Preserve exception specs and attributes.
+
+2009-11-06 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR c++/41536
+ * optimize.c (maybe_clone_body): Copy DECL_ATTRIBUTES and
+ DECL_DISREGARD_INLINE_LIMITS also.
+
+2009-11-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/41967
+ * parser.c (cp_parser_omp_for_loop): After diagnosing not perfectly
+ nested loop and parsing statements, don't cp_parser_require }, instead
+ exit the loop if next token is CPP_EOF.
+
+2009-11-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/34180
+ * method.c (do_build_copy_constructor): Don't drop cv-quals from
+ the field type.
+
+ PR c++/7046
+ * class.c (finish_struct): Store maximum_field_alignment in
+ TYPE_PRECISION.
+ * pt.c (instantiate_class_template): Set maximum_field_alignment.
+
+ PR c++/34870
+ * name-lookup.c (arg_assoc_class): Call complete_type.
+ * pt.c (instantiate_class_template): Call uses_template_parms
+ instead of dependent_type_p.
+
+ PR c++/41703
+ * pt.c (check_undeduced_parms): New subroutine of...
+ (more_specialized_fn): ...here. Undeduced template parms can make
+ a template less specialized than another.
+
+2009-11-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/39413
+ * search.c (lookup_base): Don't complete_type (base).
+
+ PR c++/35067
+ * method.c (use_thunk): Check DECL_WEAK as well as
+ DECL_ONE_ONLY.
+
+ PR c++/17365, DR 218
+ * name-lookup.c (add_function): Ignore non-functions.
+
+2009-11-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/36959
+ * decl2.c (cxx_callgraph_analyze_expr): Don't reference a function
+ just because a static variable in it is needed unless -frepo.
+
+ PR c++/41876
+ * parser.c (cp_parser_type_specifier_seq): Rename is_condition to
+ is_declaration.
+ (cp_parser_exception_declaration): Pass true.
+ (cp_parser_omp_for_loop): Likewise.
+
+ PR c++/41927
+ * typeck.c (build_x_binary_op): Don't do warn_parentheses
+ if we're in a SFINAE context.
+
+ PR c++/41815
+ * call.c (build_call_a): Strip cv-quals from rvalue result.
+
+ PR c++/40944
+ * call.c (initialize_reference): Add complain parm.
+ * typeck.c (convert_for_initialization): Pass it.
+ * decl.c (grok_reference_init): Likewise.
+ * cp-tree.h: Declare it.
+
+ PR c++/40687
+ * pt.c (do_auto_deduction): Diagnose inconsistent deduction.
+
+2009-11-02 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/37093
+ * pt.c (check_valid_ptrmem_cst_expr): New function.
+ (convert_nontype_argument): Use it to output an error for
+ illegal pointer to member expressions used as template arguments.
+
+2009-11-02 Jason Merrill <jason@redhat.com>
+
+ Restrict DR 757 change to C++0x mode.
+ * decl2.c (mark_used): Check cxx_dialect.
+ * decl.c (grokfndecl): Do check type linkage in C++98 mode.
+ (grokvardecl): Likewise.
+ * pt.c (check_instantiated_arg): Likewise.
+
+2009-11-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/41774
+ * name-lookup.c (handle_namespace_attrs): Pass 1 as last argument to
+ push_visibility.
+ * parser.c (cp_parser_namespace_definition): Pass 1 as argument to
+ pop_visibility.
+ * rtti.c (push_abi_namespace): Pass 2 as last argument to
+ push_visibility.
+ (pop_abi_namespace): Pass 2 as argument to pop_visibility.
+
+2009-10-31 Jason Merrill <jason@redhat.com>
+
+ * tree.c (cv_unqualified): New fn.
+ * cp-tree.h: Declare it.
+ * typeck.c (decay_conversion): Use it instead of TYPE_MAIN_VARIANT.
+
+ * rtti.c (tinfo_name): Fix lengths for private case.
+
+2009-10-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/41754
+ * call.c (compare_ics): Avoid bad union use when
+ comparing two ck_lists.
+
+2009-10-30 Jerry Quinn <jlquinn@optonline.net>
+
+ * mangle.c (mangle_type_string_for_rtti): Reapply 153734.
+ (needs_fake_anon): Likewise.
+ (write_name): Likewise.
+ (write_nested_name): Likewise.
+ * cp-tree.h (mangle_type_string_for_rtti): Likewise.
+ (get_anonymous_namespace): Likewise.
+ * name-lookup.c (get_anonymous_namespace_name): Likewise.
+ * rtti.c (tinfo_name): Likewise, with +1 in the second
+ build_string call fixed.
+ (tinfo_base_init): Likewise.
+
+2009-10-30 Jason Merrill <jason@redhat.com>
+
+ Revert:
+ * decl.c (cp_fname_init): Correct build_string argument.
+
+2009-10-30 Jerry Quinn <jlquinn@optonline.net>
+
+ * mangle.c (mangle_type_string_for_rtti): Revert 153734.
+ (needs_fake_anon): Likewise.
+ (write_name): Likewise.
+ (write_nested_name): Likewise.
+ * cp-tree.h (mangle_type_string_for_rtti): Likewise.
+ (get_anonymous_namespace): Likewise.
+ * name-lookup.c (get_anonymous_namespace_name): Likewise.
+ * rtti.c (tinfo_name): Likewise.
+ (tinfo_base_init): Likewise.
+
+2009-10-30 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/41863
+ * pt.c (iterative_hash_template_arg): articifial parms
+ don't have DECL_PARM_INDEX set. Do not hash it.
+
+2009-10-28 Jerry Quinn <jlquinn@optonline.net>
+
+ * mangle.c (mangle_type_string_for_rtti): Revert r149964.
+ (needs_fake_anon): Likewise.
+ (write_name): Likewise.
+ (write_nested_name): Likewise.
+ * cp-tree.h (mangle_type_string_for_rtti): Likewise.
+ (get_anonymous_namespace): Likewise.
+ * name-lookup.c (get_anonymous_namespace_name): Likewise.
+ * rtti.c (tinfo_name): Insert '*' in front of private names.
+ (tinfo_base_init): Use it.
+
+2009-10-28 Jason Merrill <jason@redhat.com>
+
+ Core issue 812, 861
+ * name-lookup.c (set_decl_namespace): Deal properly with inline
+ namespaces.
+ (qualified_lookup_using_namespace): Overhaul.
+ * pt.c (print_candidates): Handle getting an OVERLOAD.
+
+2009-10-28 Jason Merrill <jason@redhat.com>
+
+ * decl.c (cp_fname_init): Correct build_string argument.
+
+2009-10-27 Jason Merrill <jason@redhat.com>
+
+ Allow no-capture lambdas to convert to function pointer.
+ * semantics.c (maybe_add_lambda_conv_op): New.
+ * parser.c (cp_parser_lambda_expression): Call it.
+ (cp_parser_lambda_declarator_opt): Make op() static if
+ no captures.
+ * mangle.c (write_closure_type_name): Adjust.
+ * semantics.c (finish_this_expr): Adjust.
+ * decl.c (grok_op_properties): Allow it.
+ * call.c (build_user_type_conversion_1): Handle static conversion op.
+ (build_op_call): And op().
+
+2009-10-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/41828
+ * cp-lang.c (cxx_dwarf_name): Return NULL instead of
+ <anonymous ...> for anonymous aggregate names.
+
+2009-10-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/38796, Core issue 906
+ * cp-tree.h (DECL_DEFAULTED_OUTSIDE_CLASS_P): New.
+ (DECL_DEFAULTED_IN_CLASS_P): New.
+ * class.c (user_provided_p): Non-static.
+ (check_methods): Use it.
+ (check_bases_and_members): Check defaulted fns.
+ (defaultable_fn_p): Move and rename to...
+ * method.c (defaultable_fn_check): ...this.
+ (defaulted_late_check): New.
+ * pt.c (tsubst_decl): Call it.
+ * decl2.c (grokfield): Adjust.
+ * decl.c (cp_finish_decl): Adjust.
+ (grok_special_member_properties): Use user_provided_p.
+
+2009-10-26 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/41785
+ * pt.c (template_args_equal): Handle comparison of
+ an ARGUMENT_PACK_SELECT node with the arguments node it selects into.
+ * cp-tree.def: Fix a typo in the description of TYPE_PACK_EXPANSION.
+
+2009-10-26 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/41020
+ * decl.c (decls_match): Use DECL_IS_BUILTIN instead of
+ DECL_BUILT_IN.
+
+2009-10-23 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/40808
+ * mangle.c (write_template_args): Allow mangling of empty template
+ argument list. Updated function comments.
+
+2009-10-23 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (lambda_expr_this_capture): Use thisify_lambda_field.
+
+ * semantics.c (outer_lambda_capture_p): New fn.
+ (thisify_lambda_field): Factor out...
+ (add_default_capture): ...from here.
+ (finish_id_expression): Use them.
+
+ Core issue 899
+ * call.c (add_function_candidate): Only permit explicit conversion
+ ops if copy ctor was called with a single argument.
+
+ * call.c (initialize_reference): Tweak error message.
+
+2009-10-21 Jakub Jelinek <jakub@redhat.com>
+
+ * mangle.c (finish_mangling_get_identifier): Use
+ obstack_base (mangle_obstack) instead of name_base.
+
+2009-10-19 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_lexer_print_token, cp_parser_is_string_literal,
+ cp_parser_string_literal, cp_parser_primary_expression): Likewise.
+ (cp_lexer_get_preprocessor_token): Use C_LEX_STRING_JOIN instead
+ of C_LEX_RAW_STRINGS.
+
+2009-10-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/38888
+ * error.c (dump_template_bindings): Wrap argument packs in {}.
+
+ PR c++/38798
+ * parser.c (CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS): New.
+ (cp_parser_type_specifier): Don't try to parse a class-specifier
+ or enum-specifier in that case.
+ (cp_parser_trailing_type_id): New.
+ (cp_parser_late_return_type_opt): Call it.
+ (cp_parser_type_id_1): Add is_trailing_return parm.
+ (cp_parser_type_specifier_seq): Likewise.
+
+2009-10-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/39866
+ * call.c (print_z_candidates): Don't print deleted candidates.
+ (print_z_candidate): Note deleted candidates.
+
+2009-10-14 Larry Evans <cppljevans@suddenlink.net>
+
+ PR c++/40092
+ * tree.c (cp_tree_equal): Add test for TEMPLATE_PARM_PARAMETER_PACK
+ equality.
+
+2009-10-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/37875
+ * parser.c (cp_parser_decltype): Set greater_than_is_operator_p.
+
+ PR c++/37766
+ * pt.c (type_unification_real): Call convert_template_argument
+ for function default template arguments.
+ (check_default_tmpl_args): Suggest -std=c++0x when function default
+ template args seen in C++98 mode.
+
+2009-10-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/37204
+ * typeck.c (build_reinterpret_cast_1): Handle rvalue refs
+ properly.
+
+2009-10-11 Richard Guenther <rguenther@suse.de>
+
+ * tree.c (cp_free_lang_data): Drop anonymous aggregate names.
+
+2009-10-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/36816
+ * pt.c (maybe_adjust_types_for_deduction): Do rvalue ref adjustment
+ even when DEDUCE_EXACT.
+
+ PR c++/37177
+ * pt.c (resolve_nondeduced_context): New.
+ * cvt.c (convert_to_void): Call it.
+ * semantics.c (finish_decltype_type): Likewise.
+ * typeck.c (decay_conversion): Here too.
+ * pt.c (tsubst_decl): Don't clobber input_location.
+ Don't register a bad specialization.
+
+2009-10-07 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * cp-tree.h: Fix location of documentation for DECL_LANG_FLAG_7.
+
+2009-10-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/39863
+ * pt.c (tsubst_pack_expansion): Don't do anything now if we
+ have incomplete packs of different lengths.
+
+ PR c++/41038
+ * tree.c (build_qualified_name): Call convert_from_reference.
+
+2009-10-06 Jason Merrill <jason@redhat.com>
+
+ Fix lookup of initialized captures in unevaluated context.
+ * cp-tree.h (DECL_NORMAL_CAPTURE_P): New.
+ * name-lookup.c (qualify_lookup): Check it.
+ * parser.c (cp_parser_lambda_introducer): Pass explicit_init_p
+ to add_capture.
+ * semantics.c (add_capture): Set DECL_NORMAL_CAPTURE_P
+ on captures without explicit init.
+ (add_default_capture): Pass explicit_init_p.
+
+ Fix capture by copy of types with explicit copy constructor.
+ * cp-tree.h (TARGET_EXPR_DIRECT_INIT_P): New.
+ (DIRECT_INIT_EXPR_P): New.
+ * typeck.c (convert_for_initialization): Just return if
+ DIRECT_INIT_EXPR_P.
+ * semantics.c (build_lambda_object): Use
+ TARGET_EXPR_DIRECT_INIT_P for normal captures.
+
+2009-10-05 Jason Merrill <jason@redhat.com>
+
+ * parser.c: Mark lambda_scope and lambda_count for PCH.
+
+2009-10-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/41553
+ * parser.c (cp_parser_lambda_introducer): Avoid infinite loop on
+ parse error.
+
+2009-10-02 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_unnamed_type_name): Implement.
+ (local_class_index): Split out from...
+ (discriminator_for_local_entity): ...here.
+ (nested_anon_class_index): New.
+ * cp-tree.h (TYPE_FUNCTION_SCOPE_P): New.
+
+2009-10-02 Janis Johnson <janis187@us.ibm.com>
+
+ * call.c (convert_arg_to_ellipsis): Avoid promoting decimal32
+ to double.
+
+2009-10-01 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_lambda_expression): Compute visibility.
+ (no_linkage_lambda_type_p): Remove.
+ * cp-tree.h: Remove declaration.
+ * tree.c (no_linkage_check): Don't call it. Don't check template
+ args. Don't check TREE_PUBLIC Types.
+
+2009-10-01 Gabriel Dos Reis <gdr@cse.tamu.edu>
+ Jason Merrill <jason@redhat.com>
+
+ * decl.c (grokdeclarator): Set constexprness before announcing
+ friendship.
+
+2009-10-01 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * decl.c (record_builtin_java_type): Undo unintended change.
+ (cxx_init_decl_processing): Likewise.
+
+2009-10-01 Jason Merrill <jason@redhat.com>
+
+ * pt.c (register_specialization): Push DECL_SOURCE_LOCATION to the
+ clones.
+
+ * decl.c (grok_special_member_properties): Only adjust
+ TYPE_HAS_COMPLEX_* if the function is defaulted in the class body.
+ (cp_finish_decl): Push DECL_DELETED_FN/DECL_DEFAULTED_FN to the
+ clones.
+
+2009-09-30 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * decl.c (check_for_uninitialized_const_var): Check constexpr
+ variables too.
+ (grokdeclarator): Handle `constexpr'.
+ (check_tag_decl): Reject `constexpr'.
+ (check_function_type): Check constexpr functions.
+ * cp-tree.h (ds_constexpr): New cp_decl_spec enumerator.
+ (CLASSTYPE_LITERAL_P): New.
+ (lang_type_class::is_literal): New.
+ (lang_type_class::dummy): Adjust width.
+ (literal_type_p): Declare.
+ * parser.c (cp_parser_check_decl_spec): Print it.
+ (cp_parser_decl_specifier_seq): Accept "constexpr".
+ * semantics.c (validate_constexpr_fundecl): Define.
+ (literal_type_p): Define.
+
+2009-09-30 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (lambda_expr_this_capture): Fix default capture
+ of explicit capture of 'this'.
+
+2009-09-30 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_lambda_expression): Don't add __ to __this.
+
+2009-09-30 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (LANG_DECL_U2_CHECK): Check LANG_DECL_HAS_MIN.
+
+2009-09-29 John Freeman <jfreeman08@gmail.com>
+ Jason Merrill <jason@redhat.com>
+
+ Add support for lambda-expressions as per N2927.
+ * cp-tree.def (VEC_INIT_EXPR, LAMBDA_EXPR): New.
+ * cp-tree.h (LAMBDA_TYPE_P, LAMBDA_FUNCTION_P): New.
+ (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE): New.
+ (LAMBDA_EXPR_DEFAULT_CAPTURE_LIST): New.
+ (LAMBDA_EXPR_THIS_CAPTURE, LAMBDA_EXPR_CAPTURES_THIS_P): New.
+ (LAMBDA_EXPR_MUTABLE_P, LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P): New.
+ (LAMBDA_EXPR_RETURN_TYPE, LAMBDA_EXPR_LOCATION): New.
+ (LAMBDA_EXPR_EXTRA_SCOPE, LAMBDA_EXPR_DISCRIMINATOR): New.
+ (struct tree_lambda_expr): New.
+ (union lang_tree_node): Add lambda_expression.
+ (struct lang_type_class): Add lazy_move_ctor flag, lambda_expr field.
+ (CLASSTYPE_LAZY_MOVE_CTOR, CLASSTYPE_LAMBDA_EXPR): New.
+ (LAMBDA_TYPE_EXTRA_SCOPE, VEC_INIT_EXPR_SLOT): New.
+ (VEC_INIT_EXPR_INIT, DECLTYPE_FOR_LAMBDA_CAPTURE): New.
+ (DECLTYPE_FOR_LAMBDA_RETURN): New.
+ (enum special_function_kind): Add sfk_move_constructor.
+ (LAMBDANAME_PREFIX, LAMBDANAME_FORMAT, LAMBDANAME_P): New.
+ * parser.c (cp_parser_lambda_expression, cp_parser_lambda_introducer)
+ (cp_parser_lambda_declarator_opt, cp_parser_lambda_body): New.
+ (start_lambda_scope, record_lambda_scope, finish_lambda_scope): New.
+ (no_linkage_lambda_type_p): New.
+ (cp_parser_primary_expression): Recognize lambda expression.
+ (cp_parser_init_declarator): Note lambda scope.
+ (cp_parser_function_definition_after_declarator): Likewise.
+ (cp_parser_late_parsing_default_args): Likewise.
+ (cp_parser_skip_to_closing_parenthesis): Skip to end of lambda capture
+ lists, too.
+ (cp_parser_parameter_declaration): Don't defer lambda default args.
+ * semantics.c (finish_non_static_data_member, finish_id_expression):
+ Handle default capture for lambda expressions.
+ (finish_this_expr): Handle 'this' keyword inside of lambda expressions.
+ (outer_automatic_var_p): New.
+ (finish_decltype_type): Handle decltypes within lambda expressions.
+ (classtype_has_nothrow_assign_or_copy_p): Synthesized move constructor.
+ (build_lambda_expr, build_lambda_object, begin_lambda_type)
+ (lambda_return_type, lambda_capture_field_type, apply_lambda_return_type)
+ (capture_decltype, add_capture, add_default_capture)
+ (lambda_expr_this_capture): New.
+ * mangle.c (write_unnamed_type_name): New. Incomplete.
+ (write_closure_type_name): New.
+ (write_unqualified_name): Recognize unnamed, closure types.
+ (write_type): Do not write decltypes from lambda expressions.
+ (decl_mangling_context): New.
+ (write_name): Use it. Handle PARM_DECL scope.
+ (write_prefix): Likewise. Handle VAR_DECL/FIELD_DECL scope.
+ (write_compact_number): Factor out from...
+ (write_expression, write_template_param): ...here.
+ (discriminator_for_local_entity): Recognize lambdas.
+ (write_local_name): Handle PARM_DECL scope.
+ * typeck.c (structural_comptypes): Compare decltypes from lambda
+ expressions.
+ (check_return_expr): Deduce lambda return type from multiple return
+ statements.
+ * class.c (add_implicitly_declared_members): Add lazy move constructor
+ for lambda types.
+ (check_bases_and_members): Delete default constructor and assignment
+ operator for lambda types.
+ (maybe_note_name_used_in_class): Do not confuse lambda expression with
+ defining a class.
+ * decl.c (reshape_init_r): Array copy.
+ (grokfndecl): Synthesized move constructor.
+ (cp_tree_node_structure): Lambda expression.
+ * method.c (use_thunk): Synthesized move constructor.
+ (do_build_copy_constructor): Likewise.
+ (locate_copy): Likewise.
+ (implicitly_declare_fn): Likewise.
+ * cp-objcp-common.c (cp_tree_size): Handle LAMBDA_EXPR.
+ * error.c (dump_aggr_type): Recognize lambda type.
+ (dump_function_decl): Recognize lambda function.
+ (function_category): Likewise.
+ (dump_function_name): Hide lambda name.
+ * tree.c (build_array_copy, move): New.
+ (special_function_p): Synthesized move constructor.
+ (no_linkage_check): Handle lambdas.
+ * search.c (lookup_fnfields_1): Synthesized move constructor.
+ * cp-gimplify.c (cp_gimplify_init_expr, cp_gimplify_expr):
+ Handle VEC_INIT_EXPR.
+ * typeck2.c (digest_init_r): Array copy.
+ * pt.c (get_template_info): Don't touch typedefs.
+ (instantiate_decl): Don't resubstitute artificial decls.
+ (tsubst_decl, tsubst, tsubst_copy_and_build): Handle lambdas.
+ (lookup_template_class): Don't fall back on name lookup.
+ * name-lookup.c (make_lambda_name): New.
+ (pushdecl_class_level): Handle default capture for lambda expressions.
+ (qualify_lookup): Handle decltypes within lambda expressions.
+ (pushtag): Handle ts_within_enclosing_non_class in function scope.
+
+2009-09-28 Janis Johnson <janis187@us.ibm.com>
+
+ * mangle.c (write_builtin_type): Support decimal float types.
+
+2009-09-28 Richard Henderson <rth@redhat.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_EH_USE_CXA_END_CLEANUP): New.
+
+2009-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ * method.c (make_thunk, make_alias_for): Don't set
+ DECL_NO_STATIC_CHAIN.
+ * decl.c (builtin_function_1, grokfndecl): Likewise.
+ * lex.c (build_lang_decl): Likewise.
+
+2009-09-23 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/41065
+ * decl.c (cp_finish_decl): Record the types used by the global
+ variable declaration we've just parsed.
+
+2009-09-22 Dodji Seketeli <dodji@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_FUNCTION_PARAMETER_PACK_P,
+ LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P,
+ LANG_HOOKS_GET_GENERIC_FUNCTION_DECL): Initialize these
+ hooks for the c++ FE.
+ * cp-tree.h (function_parameter_pack_p, get_function_template_decl,
+ function_parameter_expanded_from_pack_p): Declare ...
+ * pt.c (function_parameter_pack_p, get_function_template_decl,
+ function_parameter_expanded_from_pack_p): ... new hooks.
+ (get_template_info): Make this more robust.
+ (template_args_variadic_p, make_ith_pack_parameter_name): Add a new
+ line between comment and function.
+ (get_template_argument_pack_elems): Fix comment.
+ (tsubst_decl): Arguments of function parameter packs are not
+ parameter packs themselves.
+
+2009-09-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/41421
+ * tree.c (trivial_type_p): Fix logic.
+
+2009-09-21 Jason Merrill <jason@redhat.com>
+
+ * name-lookup.c (push_class_level_binding): Sanity check.
+
+2009-09-18 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (determine_visibility): Make anonymous types internal.
+ (mark_used): Complain about types without linkage used in
+ decls with internal linkage.
+ (vague_linkage_fn_p): Split out from...
+ * decl.c (maybe_commonize_var): ...here.
+ (grokdeclarator): Adjust linkage when a typedef gives linkage name.
+ * tree.c (no_linkage_check): Check the enclosing class and template
+ arguments.
+
+ * cp-tree.h (TYPE_NAMESPACE_SCOPE_P): New.
+
+ * pt.c (get_pattern_parm): New.
+ (listify): Split out from...
+ (listify_autos): ...here.
+ (unify): Deduce std::initializer_list for T.
+ * call.c (build_over_call): Warn about it.
+
+2009-09-17 Andrew Pinski <pinskia@gcc.gnu.org>
+
+ PR c++/39365
+ * typeck.c (cp_build_unary_op): Check TREE_CODE for bools instead of
+ using same_type_p.
+ (convert_for_assignment): Likewise.
+ * cvt.c (type_promotes_to): Likewise.
+
+2009-09-14 Richard Henderson <rth@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (finish_asm_stmt): Update decl.
+ * parser.c (cp_parser_asm_definition): Parse asm goto.
+ (cp_parser_asm_label_list): New.
+ * pt.c (tsubst_copy_asm_operands): Don't recurse on labels.
+ (tsubst_expr): Handle asm labels.
+ * semantics.c (finish_asm_stmt): Add and use labels parameter.
+
+2009-09-14 Richard Henderson <rth@redhat.com>
+
+ * except.c (init_exception_processing): Don't call
+ default_init_unwind_resume_libfunc.
+ (cp_protect_cleanup_actions): Return the decl to call.
+ (build_exc_ptr): Use __builtin_eh_pointer.
+ * optimize.c (clone_body): Set eh_lp_nr, not eh_region.
+
+2009-09-13 Richard Guenther <rguenther@suse.de>
+ Rafael Avila de Espindola <espindola@google.com>
+
+ * except.c (init_exception_processing): Do not set
+ lang_eh_runtime_type.
+ (choose_personality_routine): Do not set eh_personality_decl,
+ set pragma_java_exceptions.
+ * cp-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
+ (LANG_HOOKS_EH_PERSONALITY): Likewise.
+ (cp_eh_personality_decl): New.
+ (cp_eh_personality): Likewise.
+ * Make-lang.in (cp-lang.o): Add $(EXPR_H) and $(EXCEPT_H)
+ dependencies.
+
+2009-09-13 Wei Guozhi <carrot@google.com>
+
+ PR c++/3187
+ * cp/optimize.c (build_delete_destructor_body): New function.
+ (maybe_clone_body): Call build_delete_destructor_body for
+ deleting destructor.
+
+2009-09-10 Jason Merrill <jason@redhat.com>
+
+ * repo.c (extract_string, get_base_filename, init_repo): constify.
+
+2009-09-09 Jason Merrill <jason@redhat.com>
+
+ * error.c (find_typenames_r): Also add decltypes.
+
+2009-09-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/28293
+ * decl2.c (grokfield): Check for explicit template argument lists.
+
+2009-09-09 Jack Howarth <howarth@bromo.med.uc.edu>
+
+ PR bootstrap/41180
+ * Make-lang.in: Remove redundant code from linkage for darwin10.
+
+2009-09-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/39923
+ * decl.c (build_init_list_var_init): Check return value of
+ perform_implicit_conversion.
+
+2009-09-08 Jason Merrill <jason@redhat.com>
+
+ * class.c (currently_open_class): Make sure we're dealing with the
+ main variant.
+
+ * cp-tree.h (enum overload_flags): Remove OP_FLAG.
+ * method.c (lazily_declare_fn): Check for dtorness in ABI warning.
+
+ * name-lookup.c (is_class_level): Remove.
+ (push_binding_level, leave_scope, resume_scope): Adjust.
+ (pushlevel_class): Adjust.
+ (poplevel_class): Make sure we're on class_binding_level.
+
+ * decl.c (grokmethod): Rename from start_method.
+ (finish_method): Remove.
+ * cp-tree.h: Adjust.
+ * parser.c (cp_parser_save_member_function_body): Adjust.
+
+2009-09-03 Doug Kwan <dougkwan@google.com>
+
+ * tree.c (cp_fix_function_decl_p): New.
+ (cp_free_lang_data): New.
+
+2009-09-03 Diego Novillo <dnovillo@google.com>
+
+ * Make-lang.in (decl2.o): Add dependency on $(POINTER_SET_H).
+ * decl2.c: Include pointer-set.h.
+ (collect_candidates_for_java_method_aliases): New.
+ (cp_write_global_declarations): Call it.
+ Add local variable CANDIDATES. If set, call
+ build_java_method_aliases.
+ (build_java_method_aliases): Add argument CANDIDATES.
+ Use it to determine if FNDECL should get a hidden alias.
+ * cp-objcp-common.h (LANG_HOOKS_FREE_LANG_DATA): Define.
+ * cp-tree.h (cp_free_lang_data): Declare.
+
+2009-09-03 Richard Guenther <rguenther@suse.de>
+
+ * method.c (use_thunk): Use cgraph_finalize_function to hand
+ off thunks to the cgraph.
+ * semantics.c (emit_associated_thunks): Do not emit thunks
+ for really extern functions.
+
+2009-09-03 Diego Novillo <dnovillo@google.com>
+
+ * cp-lang.c (lang_hooks): Remove const qualifier.
+
+2009-09-02 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (describable_type): Don't pretend to be in a template.
+
+ * ptree.c (cxx_print_type) [DECLTYPE_TYPE]: Print the expression.
+
+2009-09-01 Alexandre Oliva <aoliva@redhat.com>
+
+ * cp-tree.h (TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS): New.
+ * cp-lang.c (cxx_dwarf_name): Pass it.
+ * error.c (count_non_default_template_args): Take flags as
+ argument. Adjust all callers. Skip counting of default
+ arguments if the new flag is given.
+
+2009-09-01 Dodji Seketeli <dodji@redhat.com>
+
+ PR bootstrap/41205
+ * pt.c (make_ith_pack_parameter_name): Don't use strnlen that is a
+ GNU extension.
+
+2009-09-01 Richard Guenther <rguenther@suse.de>
+
+ * cp-objcp-common.c (cp_expr_size): Use tree_expr_size.
+ * cp-objcp-common.h (LANG_HOOKS_EXPR_SIZE): Do not define.
+
+2009-09-01 Richard Guenther <rguenther@suse.de>
+
+ * cp-objcp-common.h (LANG_HOOKS_MARK_ADDRESSABLE): Remove.
+
+2009-08-31 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/30161
+ * cp-tree.h (get_template_info): Parameter should be const.
+ (CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P): Fix typo.
+ (get_template_argument_pack_elems,
+ get_primary_template_innermost_parameters,
+ get_template_innermost_arguments, template_template_parameter_p):
+ Declare ...
+ * pt.c (get_template_argument_pack_elems,
+ get_template_innermost_parameters, get_template_innermost_arguments,
+ template_template_parameter_p):
+ ... New C++ front end implementation of new language hooks.
+ (primary_template_instantiation_p): New private helper.
+ (make_ith_pack_parameter_name): Use snprintf and strnlen instead of
+ printf and strlen.
+ (get_template_info): Const-ify parameter.
+ * cp-lang.c (LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS,
+ LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS,
+ LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS,
+ LANG_HOOKS_GENERIC_TYPE_PARAMETER_DECL_P): Initialize these
+ interfaces for the C++ front-end.
+
+2009-08-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/41127
+ * parser.c (cp_parser_enum_specifier): Make sure the : is followed by a
+ type-specifier-seq before we commit.
+
+2009-08-28 Richard Guenther <rguenther@suse.de>
+
+ PR lto/41058
+ * cp-gimplify.c (cp_genericize_r): Do not leak zero-sized stores
+ into the generic IL.
+
+2009-08-27 Richard Guenther <rguenther@suse.de>
+
+ * class.c (build_vtbl_ref_1): Remove excess vertical space.
+ * Make-lang.in (CXX_TREE_H): Remove c-common.def dependency
+ tracked by $(TREE_H).
+ * semantics.c (expand_or_defer_fn): Zero DECL_SAVED_TREE.
+
+2009-08-26 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_builtin_candidate): Don't set LOOKUP_ONLYCONVERTING
+ if we're contextually converting to bool.
+ (build_conditional_expr): Likewise.
+ * typeck.c (condition_conversion): Likewise.
+
+ * call.c (build_conditional_expr): Fix logic errors.
+ (build_new_op): Remove dead COND_EXPR handling.
+
+2009-08-24 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_DEFERRED_FN): Remove.
+ (struct lang_decl_fn): Remove deferred flag.
+ * class.c (build_clone): Don't set it.
+ * decl2.c (note_vague_linkage_fn): Don't check or set it.
+ (mark_used): Don't check it.
+ * method.c (make_thunk, make_alias_for): Don't set it.
+
+ * decl2.c (mark_used): Streamline logic.
+
+ PR c++/41109
+ PR c++/41110
+ PR c++/41134
+ * cp-tree.h (DECL_ODR_USED): New macro.
+ (struct lang_decl_base): Add odr_used flag.
+ * decl.c (duplicate_decls): Propagate it. Use it for error.
+ * pt.c (register_specialization): Use it for error.
+ * decl2.c (mark_used): Use it as gating flag rather than TREE_USED.
+ (cp_write_global_declarations): Use it for error.
+ (tree_used_ok): Remove.
+ * cp-tree.h: Remove tree_used_ok.
+ * call.c (build_call_a): Don't call it.
+ * init.c (build_offset_ref): Likewise.
+
+2009-08-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/41131
+ * tree.c (lvalue_p_1) <case CONST_DECL>: Return clk_none if
+ not TREE_STATIC.
+
+2009-08-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/41119
+ PR c++/41120
+ * decl2.c (mark_used): Increment function_depth during synthesis.
+ * parser.c (cp_parser_default_argument): Not here.
+
+2009-08-19 Jakub Jelinek <jakub@redhat.com>
+
+ * method.c (use_thunk): Call free_after_compilation after
+ assemble_end_function.
+
+2009-08-17 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (build_ptrmemfunc_type): Keep variant chain intact.
+ Avoid useless copy.
+ (finish_enum): Keep variant chain intact.
+ * tree.c (cp_build_reference_type): Likewise.
+
+2009-08-16 Jason Merrill <jason@redhat.com>
+
+ Make TREE_USED match the [basic.def.odr] concept for FUNCTION_DECL
+ and VAR_DECL, so mark_used only has effect the first time.
+ * decl2.c (mark_used): Just return if TREE_USED is already set.
+ Don't set TREE_USED if cp_unevaluated_operand is set.
+ (tree_used_ok): New fn.
+ * init.c (build_offset_ref): Check it instead of TREE_USED.
+ * call.c (build_call_a): Likewise.
+ * cp-tree.h: Declare it.
+ (DECL_NO_LINKAGE_CHECKED): No longer needed.
+ (struct lang_decl_base): Remove no_linkage_checked bitfield.
+
+ * decl2.c (finish_static_data_member_decl): Don't set TREE_USED.
+
+ * decl2.c (mark_used): It's ok to synthesize for default args now.
+
+2009-08-10 Jason Merrill <jason@redhat.com>
+
+ Implement DR 757: It's OK for a decl to use a type without linkage
+ so long as the decl is defined in the current translation unit.
+ * decl2.c (no_linkage_decls): New vector.
+ (mark_used): Add decls that use types with no linkage.
+ (cp_write_global_declarations): Check that they are defined.
+ (decl_defined_p, no_linkage_error): New fns.
+ * cp-tree.h (DECL_NO_LINKAGE_CHECKED): New macro.
+ (struct lang_decl_base): Add flag.
+ * decl.c (grokfndecl): Don't check type linkage.
+ (grokvardecl): If the type has no linkage, just make sure
+ DECL_LANG_SPECIFIC is set.
+ * pt.c (check_instantiated_arg): Don't check type linkage.
+ * name-lookup.c (is_local_extern): New fn.
+ * name-lookup.h: Declare it.
+
+2009-08-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/40948
+ * init.c (build_vec_init): Evaluate the initializer before
+ starting the initialization try block.
+
+2009-08-05 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/36069
+ * typeck.c (convert_for_assignment): Do not warn for any boolean
+ variant. Use explicit location.
+
+2009-08-04 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/39987
+ * pt.c (tsubst_default_argument): Let access checks of the
+ default argument happen in the context of the current function.
+
+2009-08-04 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/16696
+ * call.c (build_new_op): Only try prefix operator if -fpermissive,
+ otherwise just error.
+
+2009-08-04 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/39706
+ * error.c (lang_decl_name): Print qualified names for decls
+ in namespace scope.
+
+2009-08-03 Jason Merrill <jason@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/40948
+ * init.c (build_vec_init): Look through a TARGET_EXPR around a
+ CONSTRUCTOR.
+
+2009-07-31 Jason Merrill <jason@redhat.com>
+ Douglas Gregor <doug.gregor@gmail.com>
+
+ Remove implicit binding of lvalues to rvalue references (N2831)
+ * call.c (convert_class_to_reference): Binding an lvalue to an
+ rvalue reference is bad. If the user-defined conversion is bad,
+ set bad_p before merging conversions.
+ (maybe_handle_ref_bind): Don't push down bad_p.
+ (reference_binding): Binding an lvalue to an rvalue reference is bad.
+ (convert_like_real): Give a helpful error about binding lvalue
+ to rvalue reference.
+ (reference_related_p): No longer static.
+ * typeck.c (build_typed_address): New.
+ (build_static_cast_1): Add static_cast from lvalue to &&.
+ * cp-tree.h: Adjust.
+
+2009-07-31 Jason Merrill <jason@redhat.com>
+
+ * call.c (reference_binding): Rename lvalue_p to is_lvalue.
+ Do direct binding of "rvalues" in memory to rvalue references.
+ * tree.c (lvalue_p_1): Can't be both non-addressable lvalue and
+ "rvalue" in memory.
+ * typeck.c (build_static_cast_1): Do direct binding of memory
+ "rvalues" to rvalue references.
+ * cvt.c (cp_fold_convert): New.
+ * cp-tree.h: Declare it.
+
+2009-07-31 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_address): Do fold away ADDR_EXPR of INDIRECT_REF.
+ * tree.c (rvalue): Use cp_build_qualified_type, not TYPE_MAIN_VARIANT.
+
+2009-07-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/14912
+ * cp-tree.h (enum tsubst_flags): Add tf_no_class_instantiations.
+ * error.c (count_non_default_template_args): Pass it.
+ * pt.c (tsubst) [TYPENAME_TYPE]: Don't complete type if it's set.
+
+2009-07-29 Richard Guenther <rguenther@suse.de>
+
+ PR c++/40834
+ * cp-gimplify.c (cp_genericize_r): Properly walk the BIND_EXPR
+ vars.
+
+2009-07-26 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/40749
+ * decl.c (grokdeclarator): Do not set TREE_NO_WARNING for functions
+ with a qualified return type.
+
+2009-07-24 Jason Merrill <jason@redhat.com>
+
+ Core issue 901
+ * call.c (build_op_delete_call): If this is for a new-expression
+ and the op delete is deleted, do nothing.
+
+ Core issue 702
+ * call.c (compare_ics): Give list-initialization of std::init_list
+ priority over conversion to scalar, too.
+
+2009-07-22 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (mangle_type_string_for_rtti): Rename to be clearer.
+ (needs_fake_anon): New.
+ (write_name): Check it.
+ (write_nested_name): Add a fake anonymous namespace scope if true.
+ * name-lookup.c (get_anonymous_namespace_name): No longer static.
+ * rtti.c, cp-tree.h: Adjust.
+
+2009-07-22 Richard Guenther <rguenther@suse.de>
+
+ PR c++/40799
+ * cp-gimplify.c (cp_gimplify_expr): Move handling of using
+ related exprs to ...
+ (cp_genericize_r): ... genericization stage.
+ (cp_genericize): Adjust.
+
+2009-07-21 Jason Merrill <jason@redhat.com>
+
+ Core issue 934
+ * call.c (reference_binding): Implement binding to { }.
+ (initialize_reference): Binding temporary to non-const && is fine.
+ * decl.c (grok_reference_init): Remove error for CONSTRUCTOR.
+
+ * decl.c (reshape_init_r): { T } is not an aggregate initializer
+ for class T.
+
+2009-07-17 Richard Guenther <rguenther@suse.de>
+
+ PR c/40401
+ * decl.c (finish_function): Do not emit unused result warnings
+ from here.
+ * cp-objcp-common.h (LANG_HOOKS_POST_GIMPLIFY_PASS): Use
+ c_warn_unused_result_pass.
+ * semantics.c (expand_or_defer_fn): Adjust assertion about IL status.
+ * optimize.c (clone_body): Clone in GENERIC.
+ (maybe_clone_body): Do not clear DECL_SAVED_TREE.
+ * decl2.c (cp_write_global_declarations): Fix body test.
+ Do not call cgraph_optimize.
+ * Make-lang.in (optimize.o): Add tree-iterator.h dependency.
+ * method.c (use_thunk): Register thunk with
+ cgraph_finalize_function.
+ * error.c (function_category): Guard access of DECL_LANG_SPECIFIC.
+
+2009-07-17 Richard Guenther <rguenther@suse.de>
+
+ * init.c (build_vec_delete_1): Do not set DECL_REGISTER on the
+ temporary pointer.
+
+2009-07-17 Aldy Hernandez <aldyh@redhat.com>
+ Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR 40435
+ * typeck.c, init.c, class.c, method.c, rtti.c, except.c, error.c,
+ tree.c, cp-gimplify.c, cxx-pretty-print.c, pt.c, semantics.c,
+ call.c, cvt.c, mangle.c: Add location argument to
+ fold_{unary,binary,ternary}, fold_build[123], build_call_expr,
+ build_size_arg, build_fold_addr_expr, build_call_array,
+ non_lvalue, size_diffop, fold_build1_initializer,
+ fold_build2_initializer, fold_build3_initializer,
+ fold_build_call_array, fold_build_call_array_initializer,
+ fold_single_bit_test, omit_one_operand, omit_two_operands,
+ invert_truthvalue, fold_truth_not_expr, build_fold_indirect_ref,
+ fold_indirect_ref, combine_comparisons, fold_builtin_*,
+ fold_call_expr, build_range_check, maybe_fold_offset_to_address,
+ round_up, round_down.
+
+2009-07-16 Jason Merrill <jason@redhat.com>
+
+ PR libstdc++/37907
+ Split POD into "standard-layout" and "trivial" as per N2230,
+ Support std::is_standard_layout and std::is_trivial traits.
+ * cp-tree.h (enum cp_trait_kind): Add CPTK_IS_STD_LAYOUT,
+ CPTK_IS_TRIVIAL.
+ (struct lang_type_class): Add non_std_layout.
+ (CLASSTYPE_NON_STD_LAYOUT): New.
+ * class.c (check_bases): Set it.
+ (check_field_decls): Likewise.
+ (check_bases_and_members): Likewise.
+ * parser.c (cp_parser_primary_expression): Handle RID_IS_STD_LAYOUT,
+ RID_IS_TRIVIAL.
+ (cp_parser_trait_expr): Likewise.
+ * semantics.c (trait_expr_value): Handle CPTK_IS_STD_LAYOUT,
+ CPTK_IS_TRIVIAL.
+ (finish_trait_expr): Likewise.
+ * tree.c (scalarish_type_p, trivial_type_p, std_layout_type_p): New.
+ (pod_type_p): Use them.
+ (type_has_nontrivial_copy_init, type_has_nontrivial_default_init): New.
+
+ Adjust bits of the language that no longer refer to POD types.
+ * call.c (convert_arg_to_ellipsis): Use type_has_nontrivial_copy_init
+ and TYPE_HAS_NONTRIVIAL_DESTRUCTOR rather than pod_type_p.
+ (build_x_va_arg): Likewise.
+ (call_builtin_trap): Remove.
+ * decl.c (declare_local_label): Use type_has_nontrivial_default_init
+ and TYPE_HAS_NONTRIVIAL_DESTRUCTOR rather than pod_type_p.
+ (cp_finish_decl): Likewise.
+ (check_previous_goto_1, check_goto): Adjust error.
+ * typeck.c (build_class_member_access_expr): Check
+ CLASSTYPE_NON_STD_LAYOUT rather than CLASSTYPE_NON_POD_P.
+
+2009-07-14 Taras Glek <tglek@mozilla.com>
+ Rafael Espindola <espindola@google.com>
+
+ * Make-lang.in: Added CP_PLUGIN_HEADERS and
+ c.install-target to export cp-tree.h cxx-pretty-print.h
+ name-lookup.h headers for plugins.
+
+2009-07-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/37276
+ * decl.c (decls_match): A non-extern-C declaration doesn't match
+ a builtin extern-C declaration.
+
+ PR c++/40746
+ * name-lookup.c (qualified_lookup_using_namespace): Don't stop
+ looking in used namespaces just because we found something on
+ another branch.
+
+ PR c++/40740
+ * semantics.c (perform_koenig_lookup): Handle empty template args.
+
+ * call.c (build_over_call): Use can_trust_pointer_alignment.
+
+2009-07-14 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/40705
+ PR c++/403057
+ * decl2.c (grokfield): Don't call set_underlying_type on typedef
+ decls that are type names.
+
+2009-07-13 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR C++/22154
+ * parser.c (cp_parser_elaborated_type_specifier): Accept typename in
+ front of qualified names.
+
+2009-07-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/36628
+ * tree.c (rvalue): Use lvalue_or_rvalue_with_address_p.
+
+ PR c++/37206
+ * cp-tree.h (enum cp_lvalue_kind_flags): Add clk_rvalueref.
+ * tree.c (lvalue_p_1): Return it. Remove
+ treat_class_rvalues_as_lvalues parm.
+ (real_lvalue_p): Disallow pseudo-lvalues here.
+ (lvalue_or_rvalue_with_address_p): New fn.
+ * call.c (initialize_reference): Use it instead of real_lvalue_p.
+
+ PR c++/40689
+ * init.c (build_new_1): Handle initializer list as array initializer.
+ (build_vec_init): Likewise.
+ * typeck.c (cp_build_modify_expr): Likewise.
+ * typeck2.c (process_init_constructor_array): Error rather than abort
+ if too many initializers.
+
+2009-07-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/40502
+ * error.c (cp_print_error_function): Check for NULL block.
+
+2008-07-09 Simon Martin <simartin@users.sourceforge.net>
+ Jason Merrill <jason@redhat.com>
+
+ * pt.c (perform_typedefs_access_check, get_types_needing_access_check,
+ append_type_to_template_for_access_check_1): Use CLASS_TYPE_P.
+
+2009-07-09 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/40684
+ * pt.c (type_unification_real): Use tsubst_template_arg instead
+ of tsubst to substitute default template arguments.
+
+2009-07-08 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/31246
+ * init.c (build_new_1): Set TREE_NO_WARNING for compiler-generated
+ code.
+ * cp-gimplify.c (genericize_eh_spec_block): Likewise.
+
+
+2009-07-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/35828
+ * pt.c (tsubst_decl): Don't abort if we didn't change anything
+ in a TEMPLATE_DECL's args.
+
+2009-07-07 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ * semantics.c (finalize_nrv_r): Replace EXPR_LOCUS by
+ EXPR_LOCATION.
+
+2009-07-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/37816
+ * decl.c (build_enumerator): Don't add enumerators for a
+ scoped enum to the enclosing class.
+
+ PR c++/40639
+ * decl.c (start_enum): Allow dependent underlying type.
+
+ PR c++/40633
+ * decl.c (finish_enum): Finish scope even in a template.
+
+2009-07-07 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ * init.c: Replace %J by an explicit location. Update all calls.
+ * decl.c: Likewise.
+ * typeck2.c: Likewise.
+ * pt.c: Likewise.
+ * name-lookup.c: Likewise.
+
+2009-07-06 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ * decl.c: Replace %H by an explicit location. Update all calls.
+ * except.c: Likewise.
+ * semantics.c: Likewise.
+ * parser.c: Likewise.
+
+2009-07-06 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/40557
+ * pt.c (perform_typedefs_access_check, get_types_needing_access_check,
+ append_type_to_template_for_access_check_1): Use
+ RECORD_OR_UNION_CODE_P.
+
+2009-07-04 Jason Merrill <jason@redhat.com>
+
+ * pt.c (retrieve_specialization): Don't get confused by a
+ using-declaration that brings in another instance of this template
+ from a base class.
+
+ * ptree.c (cxx_print_type): Fix logic.
+
+ * cp-tree.h (LANG_DECL_FN_CHECK): Fix non-checking version.
+
+ PR c++/40619
+ * cp-tree.h (struct lang_decl_parm): New.
+ (struct lang_decl): Add it.
+ (LANG_DECL_PARM_CHECK): New.
+ (DECL_PARM_INDEX): New.
+ * decl2.c (parm_index): Remove.
+ * lex.c (retrofit_lang_decl): Handle parms.
+ (cxx_dup_lang_specific_decl): Likewise.
+ * mangle.c (write_expression): Adjust.
+ * tree.c (cp_tree_equal): Adjust.
+ (decl_linkage): Only check DECL_COMDAT for functions and variables.
+ * parser.c (cp_parser_parameter_declaration_list): Set
+ DECL_PARM_INDEX.
+ * pt.c (iterative_hash_template_arg): Hash it.
+
+2009-07-03 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (struct lang_decl): Overhaul.
+ (struct lang_decl_flags): Remove.
+ (struct lang_decl_base): New.
+ (struct lang_decl_min): New.
+ (struct lang_decl_fn): New.
+ (struct lang_decl_ns): New.
+ (CAN_HAVE_FULL_LANG_DECL_P): Replace with LANG_DECL_HAS_MIN.
+ (LANG_DECL_MIN_CHECK): New.
+ (LANG_DECL_FN_CHECK): New.
+ (LANG_DECL_NS_CHECK): New.
+ (STRIP_TEMPLATE): New.
+ (NON_THUNK_FUNCTION_CHECK): Remove.
+ (DECL_DECLARES_FUNCTION_P): New.
+ (lots): Adjust.
+ * lex.c (retrofit_lang_decl, cxx_dup_lang_specific_decl): Adjust.
+ * decl.c (push_local_name, duplicate_decls): Adjust.
+ * decl2.c (start_objects): Don't set u2sel.
+ * semantics.c (finish_omp_threadprivate): Adjust.
+ * class.c (build_clone): Don't do much on TEMPLATE_DECLs.
+ (decl_cloned_function_p): Out-of-line implementation of macros.
+ (clone_function_decl, adjust_clone_args): Use DECL_CLONED_FUNCTION_P.
+ * mangle.c (write_unqualified_name): Don't check function flags
+ on non-functions.
+ * method.c (make_alias_for): Don't set DECL_CLONED_FUNCTION.
+ * pt.c (build_template_decl): Don't set function flags.
+ (check_default_tmpl_args): Check that it's a function.
+ (instantiate_template): Use DECL_ABSTRACT_ORIGIN to find the
+ cloned template.
+
+ * pt.c (tsubst_decl) [FUNCTION_DECL]: Don't tsubst
+ DECL_CLONED_FUNCTION.
+
+ * cp-tree.h (struct lang_type_class): Move sorted_fields here.
+ * class.c (finish_struct_1): Adjust.
+ * ptree.c (cxx_print_decl, cxx_print_type): Adjust.
+ * search.c (lookup_field_1): Adjust.
+
+ * cp-tree.h (CLASSTYPE_INLINE_FRIENDS): Remove.
+ * decl.c (finish_method): Don't add to it.
+ * class.c (fixup_pending_inline): Remove.
+ (fixup_inline_methods): Remove.
+ (finish_struct_1): Don't call it.
+
+ * error.c (dump_function_name): Handle null name.
+
+2009-07-02 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (cp_build_binary_op): Move warnings about use of NULL
+ in arithmetic earlier and allow comparisions of NULL with
+ pointers-to-members.
+
+2009-07-02 Jason Merrill <jason@redhat.com>
+
+ Use hash tables for template specialization lookup.
+ * pt.c (struct spec_entry): New type.
+ (decl_specializations, type_specializations): New hash tables.
+ (register_specialization, retrieve_specialization): Use them.
+ (reregister_specialization, lookup_template_class): Use them.
+ (eq_specializations, hash_tmpl_and_args, hash_specialization): New.
+ (iterative_hash_template_arg): New.
+ (init_template_processing): New
+ (process_partial_specialization): Don't look to see if we already
+ have this partial specialization.
+ (maybe_process_partial_specialization): Handle reassigning
+ full specializations when we get an explicit specialization
+ of the partial instantiation.
+ (tsubst_friend_function): Adjust specialization reassignment code.
+ (instantiate_template): Only do one lookup.
+ (instantiate_decl): Don't do any lookup.
+ * cp-tree.h: Declare init_template_processing.
+ * decl.c (duplicate_decls): Pass args to reregister_specialization.
+
+2009-07-01 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_CLASS_TEMPLATE_P): Use DECL_IMPLICIT_TYPEDEF_P.
+
+ * pt.c (register_specialization): Use duplicate_decls to merge
+ the argument with a previous specialization.
+ (check_explicit_specialization): Call register_specialization to
+ merge the TEMPLATE_DECL with a previous version.
+ (determine_specialization): Return the args even if fn is a template.
+
+2009-07-01 Ian Lance Taylor <iant@google.com>
+
+ * g++spec.c (lang_specific_driver): Bump num_args by 1.
+
+2009-06-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/40595
+ * pt.c (tsubst_pack_expansion): Handle unexpanded packs in an
+ EXPR_PACK_EXPANSION.
+
+2009-06-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/40274
+ * error.c (dump_template_parms): Pass all args to
+ count_non_default_template_args.
+ (count_non_default_template_args): Pull out the inner ones.
+
+2009-06-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * decl.c (duplicate_decls): Re-indent.
+
+2009-06-25 Ian Lance Taylor <iant@google.com>
+
+ * call.c (avoid_sign_compare_warnings): New static function.
+ (build_new_op): Call it.
+ * typeck.c (cp_build_binary_op): Don't call warn_sign_compare if
+ TREE_NO_WARNING is set on either operand.
+
+2009-06-25 Ian Lance Taylor <iant@google.com>
+
+ * g++spec.c (SKIPOPT): define.
+ (lang_specific_driver): Handle -static-libstdc++. Only add
+ LIBSTDCXX_STATIC if we add LIBSTDCXX.
+
+2009-06-25 Ian Lance Taylor <iant@google.com>
+
+ * cvt.c (convert_to_void): Only warn about COND_EXPR if neither
+ the second nor third operand has side effects.
+
+2009-06-25 Ian Lance Taylor <iant@google.com>
+
+ * parser.c (cp_parser_binary_expression): Increment
+ c_inhibit_evaluation_warnings while parsing the right hand side of
+ "true || x" or "false && x".
+ * typeck.c (cp_build_binary_op): Only call warn_for_sign_compare
+ if c_inhibit_evaluation_warnings is zero.
+
+2009-06-24 Jason Merrill <jason@redhat.com>
+
+ * error.c (dump_decl): Do say "typedef" for the injected class name.
+
+ * pt.c (lookup_template_class): Use currently_open_class,
+ compare template args later.
+
+ PR c++/40342
+ * decl.c (decls_match): Check DECL_TI_TEMPLATE too.
+ * class.c (resolve_address_of_overloaded_function): Fix typo.
+
+2009-06-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * class.c (get_vtable_decl): Replace finish_decl with cp_finish_decl.
+ * decl.c (finish_decl): Remove.
+ (declare_global_var): Replace finish_decl with cp_finish_decl.
+ (start_method): Same.
+ * rtti.c (emit_tinfo_decl): Same.
+ * pt.c (tsubst_expr): Same.
+ (instantiate_decl): Same.
+ * decl2.c (grokbitfield): Same.
+ * name-lookup.c (pushdecl_top_level_1): Same.
+ * cp-tree.h: Remove finish_decl.
+
+2009-06-16 David Edelsohn <edelsohn@gnu.org>
+
+ * g++-spec.c (LIBSTDCXX_STATIC): Default to NULL.
+ (lang_specific_driver): Always allocate extra argument.
+ Add LIBSTDCXX_STATIC to arglist if defined and linking
+ statically.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (cp/class.o): Depend upon gt-cp-class.h.
+ (cp/semantics.o): Depend upon gt-cp-semantics.h.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * parser.c (cp_unevaluated_operand): Define global variable.
+ (cp_parser_question_colon_clause): Increment
+ c_inhibit_evaluation_warnings when evaluating an expression which
+ will never be executed.
+ (cp_parser_decltype): Increment cp_unevaluated_operand and
+ c_inhibit_evaluation_warnings, not skip_evaluation.
+ (cp_parser_sizeof_operand): Likewise.
+ (cp_parser_enclosed_template_argument_list): Save
+ cp_unevaluated_operand and c_inhibit_evaluation_warnings, not
+ skip_evaluation.
+ * cp-tree.h (struct saved_scope): Remove skip_evaluation field.
+ Add unevaluated_operand and inhibit_evaluation_warnings fields.
+ (cp_unevaluated_operand): Declare.
+ * name-lookup.c (push_to_top_level): Save cp_unevaluated_operand
+ and c_inhibit_evaluation_warnings rather than skip_evaluation.
+ (pop_from_top_level): Restore cp_unevaluated_operand and
+ c_inhibit_evaluation_warnings rather than skip_evaluation.
+ * class.c (build_base_path): Check cp_unevaluated_operand rather
+ than skip_evaluation.
+ * typeck.c (build_class_member_access_expr): Likewise.
+ (cp_build_binary_op): Don't warn about bad shift counts if
+ c_inhibit_evaluation_warnings is non-zero.
+ * pt.c (coerce_template_parms): Save state of
+ cp_unevaluated_operand and c_inhibit_evaluation_warnings, not
+ skip_evaluation.
+ (tsubst_aggr_type): Likewise.
+ (tsubst_pack_expansion): Check cp_unevaluated_operand rather than
+ skip_evaluation.
+ (tsubst_copy): Likewise.
+ (tsubst): Set cp_unevaluated_operand and
+ c_inhibit_evaluation_warnings, not skip_evaluation.
+ (tsubst_copy_and_build): Likewise.
+ * call.c (convert_arg_to_ellipsis): Check cp_unevaluated_operand
+ rather than skip_evaluation.
+ * decl2.c (mark_used): Likewise.
+ * semantics.c (finish_non_static_data_member): Likewise.
+ * cvt.c (cp_convert_and_check): Check
+ c_inhibit_evaluation_warnings rather than skip_evaluation.
+ * mangle.c (write_type): Set cp_unevaluated_operand rather than
+ skip_evaluation.
+
+2009-06-15 Ian Lance Taylor <iant@google.com>
+
+ * parser.c (cp_parser_direct_declarator): Add braces around
+ variables declared before label.
+
+2009-06-15 Rafael Avila de Espindola <espindola@google.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_COMDAT_GROUP): Remove.
+ * cp-tree.h (cxx_comdat_group): Change signature.
+ * decl.c (duplicate_decls): Use DECL_COMDAT_GROUP.
+ (cxx_comdat_group): Change signature.
+ * decl2.c (comdat_linkage, maybe_make_one_only): Update call to
+ make_decl_one_only.
+ (constrain_visibility, get_guard): Use DECL_COMDAT_GROUP.
+ * method.c (use_thunk): Update call to make_decl_one_only.
+ * optimize.c (maybe_clone_body): Use DECL_COMDAT_GROUP
+
+2009-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * typeck.c (cp_build_binary_op): Pass location to overflow_warning.
+ (build_modify_expr): New arg.
+ * semantics.c (finish_unary_op_expr): Pass location to
+ overflow_warning.
+ (handle_omp_for_class_iterator): Pass location to build_modify_expr.
+ * typeck.c (cxx_sizeof_or_alignof_type): Pass location to
+ c_sizeof_or_alignof_type.
+ (build_array_ref): New argument.
+ (build_compound_expr): Same.
+ (build_const_cast): Same.
+ (build_ptrmemfunc): Pass location to build_c_cast.
+ * init.c (avoid_placement_new_aliasing): Pass location to
+ build_stmt.
+ (build_vec_delete_1): Pass location to cp_build_modify_expr,
+ build_compound_expr.
+ * class.c (build_vtbl_ref_1): Pass location to build_array_ref.
+ * decl.c (poplevel): Pass location to c_build_bind_expr.
+ (finish_case_label): Pass location to build_case_label.
+ (finish_constructor_body): Same.
+ (finish_destructor_body): Pass location to build_stmt.
+ (cxx_maybe_build_cleanup): Same, but to build_compound_expr.
+ * call.c (build_new_op): Pass location to build_array_ref.
+ (build_x_va_arg): Pass location to build_va_arg.
+ * except.c (expand_end_catch_block): Pass location to
+ build_stmt.
+ * cp-tree.h (build_array_ref): New argument.
+ (build_compound_expr): Same.
+ (build_c_cast): Same.
+ * cp-gimplify.c (gimplify_if_stmt): Pass location on down.
+ (gimplify_switch_stmt): Same.
+ * typeck2.c (split_nonconstant_init_1): Same.
+ * pt.c (tsubst_copy): Same.
+ * semantics.c (add_decl_expr): Same.
+ (do_poplevel): Same.
+ (push_cleanup): Same.
+ (finish_goto_stmt): Same.
+ (finish_expr_stmt): Same.
+ (begin_if_stmt): Same.
+ (begin_while_stmt): Same.
+ (begin_do_stmt): Same.
+ (finish_return_stmt): Same.
+ (begin_for_stmt): Same.
+ (finish_break_stmt): Same.
+ (finish_continue_stmt): Same.
+ (begin_switch_stmt): Same.
+ (begin_try_block): Same.
+ (begin_handler): Same.
+ (finish_asm_stmt): Same.
+ (finish_label_stmt): Same.
+ (finish_stmt_expr_expr): Same.
+ (finalize_nrv_r): Same.
+ (finish_omp_atomic): Same.
+ * name-lookup.c (do_using_directive): Same.
+ * decl2.c (grok_array_decl): Same.
+ * parser.c (cp_parser_cast_expression): Same.
+ (cp_parser_selection_statement): Same.
+ (cp_parser_implicitly_scoped_statement): Same.
+ (cp_parser_objc_selector_expression): Same.
+ (cp_parser_objc_synchronized_statement): Same.
+ (cp_parser_objc_throw_statement): Same.
+ (cp_parser_omp_critical): Same.
+ (cp_parser_omp_master): Same.
+ * typeck.c (build_function_call): Add location argument.
+ * init.c: Add location argument to all build_decl calls.
+ * class.c: Same.
+ * method.c: Same.
+ * rtti.c: Same.
+ * tree.c: Same.
+ * pt.c: Same.
+ * semantics.c: Same.
+ * lex.c: Same.
+ * decl2.c: Same.
+ * cp-gimplify.c: Same.
+ * decl.c: Same.
+ (cp_make_fname_decl): Add location argument. Pass location ot
+ build_decl.
+ (finish_case_label): Same.
+ * cp-tree.h (finish_case_label): Add location argument.
+ * parser.c (cp_parser_label_for_labeled_statement): Pass location to
+ finish_case_label.
+
+2009-06-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/40381
+ * decl2.c (mark_used): Return after complaining about deleted fn.
+
+2009-06-08 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_type_id_1): 'auto' type is ok with a
+ late-specified return type.
+
+2009-06-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/40373
+ * call.c (check_dtor_name): Return false even if
+ get_type_value (name) is error_mark_node.
+
+ PR c++/40370
+ PR c++/40372
+ * parser.c (cp_parser_direct_declarator): Don't set TREE_SIDE_EFFECTS
+ on error_mark_node. Check for VLAs outside of function context
+ before check whether to wrap bounds into a NOP_EXPR with
+ TREE_SIDE_EFFECTS.
+
+2009-06-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * repo.c (get_base_filename): Use aux_base_name rather than
+ alternate temporary file during second compare debug compilation.
+ (finish_repo): Skip during -fcompare-debug-second.
+
+2009-06-06 Ian Lance Taylor <iant@google.com>
+
+ * parser.c (cp_parser_label_for_labeled_statement): Support
+ attribute on labels if immediately followed by semicolon.
+ * semantics.c (finish_label_stmt): Return new label.
+ * pt.c (tsubst_expr): Handle attributes for LABEL_EXPR.
+
+2009-06-03 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (cc1plus-checksum.o): Depend upon $(CONFIG_H) and
+ $(SYSTEM_H).
+
+2009-06-02 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (maybe_deduce_size_from_array_init): Use relayout_decl.
+
+2009-06-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/40308
+ PR c++/40311
+ * typeck.c (cp_build_modify_expr): Always pass init-lists to the
+ conversion code.
+ * call.c (implicit_conversion): Allow init-list conversion to scalar
+ during direct-initialization, too. Mark the conversion bad if it
+ has too many levels of braces.
+ (convert_like_real): And give a helpful error.
+
+ PR c++/40306
+ PR c++/40307
+ * decl.c (cp_finish_decl): Handle auto deduction from ().
+ * typeck.c (build_x_indirect_ref): Handle dereferencing an operand
+ with dependent type that is known to be a pointer.
+
+2009-06-02 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/38089
+ * pt.c (register_specialization): Properly setup DECL_CONTEXT for
+ specializations in an invalid namespace.
+
+2009-06-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * error.c (print_instantiation_partial_context): Print column
+ numbers.
+
+2009-05-29 Ian Lance Taylor <iant@google.com>
+
+ * error.c (cp_printer): Don't use va_arg with enum type.
+
+2009-05-28 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/39754
+ * cp-tree.h (canonical_type_variant): Remove this function declaration.
+ (strip_typedefs): New function declaration.
+ * tree.c (strip_typedefs): New function definition.
+ (canonical_type_variant): Remove function definition.
+ * cvt.c (convert_from_reference): No need to use
+ canonical_type_variant.
+ * typeck.c (cp_build_indirect_ref): Likewise.
+ * error.c (dump_template_bindings): Use strip_typedefs instead of
+ canonical_type_variant.
+ * pt.c (convert_template_argument, unify): Likewise.
+ * mangle.c (canonicalize_for_substitution): Don't use
+ canonical_type_variant.
+
+2009-05-27 Jason Merrill <jason@redhat.com>
+
+ * call.c (implicit_conversion): Handle conversion from
+ initializer-list to scalar.
+ (convert_like_real): Likewise. Avoid crashing on list
+ initialization with bad conversions.
+ (can_convert): Use LOOKUP_EXPLICIT.
+ (can_convert_arg_bad): Add flags parm.
+ * cp-tree.h: Adjust.
+ * typeck.c (convert_for_assignment): Pass flags.
+
+2009-05-27 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (g++$(exeext)): Change $(COMPILER) to $(LINKER).
+ (cc1plus-dummy$(exeext), cc1plus$(exeext)): Likewise.
+
+2009-05-26 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (g++spec.o): Use $(COMPILER).
+ (g++$(exeext), cc1plus-dummy$(exeext)): Likewise.
+ (cc1plus$(exeext)): Likewise.
+
+2009-05-26 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/40007
+ * cp-tree.h (MEMBER_TYPES_NEEDING_ACCESS_CHECK): Remove this accessor.
+ (TI_TYPEDEFS_NEEDING_ACCESS_CHECKING): New accessor.
+ (get_types_needing_access_check): Declare new entry point.
+ * pt.c (append_type_to_template_for_access_check_1,
+ get_types_needing_access_check): New functions.
+ (perform_typedefs_access_check): Accept FUNCTION_DECLs and
+ RECORD_TYPEs rather than TEMPLATE_DECLs. Use the new
+ get_types_needing_access_check, no more
+ MEMBER_TYPES_NEEDING_ACCESS_CHECK.
+ (instantiate_class_template): Set input_location to the source
+ location of the most specialized template definition.
+ Perform access check using the RECORD_TYPE of the template, not its
+ associated most generic TEMPLATE_DECL.
+ (append_type_to_template_for_access_check): Augment function
+ comments. Use the new get_types_needing_access_check, not
+ MEMBER_TYPE_NEEDING_ACCESS_CHECK. Use the new
+ append_type_to_template_for_access_check_1 subroutine.
+
+2009-05-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/38064
+ * typeck.c (cp_build_binary_op): Allow ENUMERAL_TYPE in
+ arithmetic comparisons.
+ (cp_common_type): Handle scoped enums.
+
+ * call.c (promoted_arithmetic_type_p): Don't use INTEGRAL_TYPE_P.
+ (add_builtin_candidate, add_builtin_candidates): Likewise.
+ (convert_like_real): Likewise.
+ * class.c (check_bitfield_decl): Likewise.
+ * decl.c (check_static_variable_definition): Likewise.
+ (compute_array_index_type): Likewise.
+ * decl2.c (grokbitfield): Likewise.
+ * init.c (build_new_1): Likewise.
+ * pt.c (convert_nontype_argument): Likewise.
+ (current_instantiation): Likewise.
+ * tree.c (pod_type_p): Likewise.
+ * typeck.c (build_static_cast_1): Likewise.
+ (build_reinterpret_cast_1): Likewise.
+
+2009-05-22 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/38964
+ * init.c (avoid_placement_new_aliasing): Remove.
+ (build_new_1): Do not call it.
+
+2009-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (decl_needed_p): Consider dllexport'd functions needed.
+ * semantics.c (expand_or_defer_fn): Similarly.
+
+2009-05-20 Ian Lance Taylor <iant@google.com>
+
+ * parser.c (cp_parser_postfix_expression): Change args to a vec.
+ Release it when done.
+ (tree_vector): Define typedef. Define VEC functions.
+ (cp_parser_parenthesized_expression_list): Change return type to
+ vec. Change all callers.
+ (cp_parser_new_expression): Change placement and initializer to
+ vecs. Release them when done.
+ (cp_parser_new_placement): Change return type to vec. Change all
+ callers.
+ (cp_parser_new_initializer): Likewise.
+ * typeck.c (build_function_call_vec): Just call
+ cp_build_function_call_vec.
+ (cp_build_function_call): Just build a vec and call
+ cp_build_function_call_vec.
+ (cp_build_function_call_vec): New function based on old
+ cp_build_function_call.
+ (convert_arguments): Remove nargs and argarray parameters. Change
+ values to a vec. Change caller.
+ (build_x_compound_expr_from_vec): New function.
+ (cp_build_modify_expr): Build vec to pass to
+ build_special_member_call.
+ * call.c (struct z_candidate): Add first_arg field. Change args
+ field to vec.
+ (convert_class_to_reference): Handle first argument separately.
+ (add_candidate): Add first_arg parameter. Change args parameter
+ to vec. Change all callers.
+ (add_function_candidate, add_conv_candidate): Likewise.
+ (add_template_candidate_real, add_template_candidate): Likewise.
+ (add_template_conv_candidate): Likewise.
+ (build_user_type_conversion_1): Handle first argument separately.
+ (resolve_args): Change return type and parameter type to vecs.
+ Change all callers.
+ (perform_overload_resolution): Change args parameter to vec.
+ Change all callers.
+ (build_new_function_call, build_operator_new_call): Likewise.
+ (add_candidates): Likewise.
+ (build_op_call): New globally visible function, built from and
+ replacing static function build_object_call.
+ (build_new_op): Don't handle CALL_EXPR. Build vec, not tree_list,
+ of arguments.
+ (build_op_delete_call): Build vec to pass to
+ cp_build_function_call_vec.
+ (build_temp): Build vec to pass to build_special_member_call.
+ (convert_like_real): Likewise.
+ (perform_direct_initialization_if_possible): Likewise.
+ (build_over_call): Handle first_arg field. Use build_call_array
+ rather than build_call_list.
+ (build_special_member_call): Change args parameter to vec. Change
+ all callers.
+ (build_new_method_call): Likewise.
+ * init.c (expand_default_init): Change parms to vec.
+ (build_raw_new_expr): Change placement and init to vecs. Change
+ all callers.
+ (build_new_1, build_new): Likewise.
+ * class.c (resolve_address_of_overloaded_function): Build array to
+ pass to fn_type_unification.
+ * pt.c (tsubst_copy_and_build): For NEW_EXPR build vecs to pass to
+ build_new. For CALL_EXPR create a vec rather than a tree_list;
+ expand a pack if necessary.
+ (fn_type_unification): Change args parameter to const tree *. Add
+ nargs parameter. Change all callers.
+ (type_unification_real): Likewise.
+ (unify): Build array to pass to type_unification_real.
+ (get_bindings): Build array to pass to fn_type_unification.
+ (any_type_dependent_arguments_p): Change args parameter to a vec.
+ Change all callers.
+ (make_args_non_dependent): Renamed from build_non_dependent_args.
+ Change return type to void. Change parameter type to vec. Change
+ all callers.
+ (do_auto_deduction): Pass an array to type_unification_real.
+ * semantics.c (perform_koenig_lookup): Change args to vec. Change
+ all callers.
+ (finish_call_expr): Change args to vec. Change all callers. Call
+ build_op_call instead of passing CALL_EXPR to build_new_op.
+ (cxx_omp_create_clause_info): Allocate vec to pass to
+ build_special_member_call.
+ * decl2.c (build_offset_ref_call_from_tree): Change args parameter
+ to vec. Change all callers.
+ * name-lookup.c (lookup_function_nonclass): Likewise.
+ (struct arg_lookup): Change args to vec.
+ (arg_assoc_namespace): Handle args as a vec.
+ (arg_assoc_args_vec): New static function.
+ (lookup_arg_dependent): Change args parameter to vec. Change all
+ callers.
+ * method.c (do_build_assign_ref): Allocate vec to pass to
+ build_special_member_call.
+ * except.c (build_throw): Likewise.
+ * typeck2.c (build_functional_cast): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ * tree.c (build_min_non_dep_call_vec): Change last parameter to
+ vec. Change all callers.
+ * cp-tree.h: Update declarations.
+ * name-lookup.h: Update declarations.
+
+2009-05-20 Sandra Loosemore <sandra@codesourcery.com>
+
+ * typeck.c (default_conversion): Check targetm.promoted_type.
+ * decl.c (grokdeclarator): Check targetm.invalid_return_type.
+ (grokparms): Check targetm.invalid_parameter_type.
+ * cvt.c (ocp_convert): Check targetm.convert_to_type.
+ (build_expr_type_conversion): Check targetm.promoted_type.
+
+2009-05-19 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * typeck.c (build_binary_op): Allow % on integal vectors.
+
+2009-05-18 Jason Merrill <jason@redhat.com>
+
+ Implement explicit conversions ops as specified in N2437.
+ * decl.c (grokdeclarator): Handle explicit conversion ops.
+ (check_initializer): Pass flags to store_init_value.
+ * decl2.c (maybe_emit_vtables): Likewise.
+ * init.c (expand_aggr_init_1): Likewise.
+ * call.c (convert_class_to_reference): Take flags parm,
+ check DECL_NONCONVERTING_P.
+ (build_user_type_conversion_1): Check DECL_NONCONVERTING_P.
+ (add_builtin_candidates): Simplify getting type of conversion.
+ (build_object_call): Likewise. Check DECL_NONCONVERTING_P.
+ (implicit_conversion): Pass through LOOKUP_ONLYCONVERTING.
+ (reference_binding): Take flags parm. Direct-initialize copy parm.
+ (add_function_candidate): Direct-initialize the copy parm.
+ (add_conv_candidate): Use LOOKUP_IMPLICIT, not LOOKUP_NORMAL.
+ (build_builtin_candidate): Add LOOKUP_ONLYCONVERTING.
+ (conditional_conversion): Likewise.
+ (convert_like_real): Only complain about DECL_NONCONVERTING_P
+ constructors.
+ (perform_implicit_conversion_flags): Add flags parm to
+ perform_implicit_conversion. Improve diagnostics.
+ * cp-tree.h (LOOKUP_IMPLICIT): New macro.
+ (LOOKUP_COPY_PARM): New bit macro.
+ * cvt.c (build_expr_type_conversion): Check DECL_NONCONVERTING_P.
+ * typeck.c (convert_for_assignment): Take flags parm, pass it to
+ perform_implicit_conversion_flags.
+ (cp_build_modify_expr): Pass flags to convert_for_assignment.
+ (convert_for_initialization): Likewise.
+ * typeck2.c (store_init_value): Take flags parm, pass to
+ digest_init_flags.
+ (digest_init_flags): Add flags parm to digest_init.
+ (digest_init_r): Take flags parm, pass to convert_for_initialization.
+ (process_init_constructor_array): Pass it.
+ (process_init_constructor_record): Likewise.
+ (process_init_constructor_union): Likewise.
+
+2009-05-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/40139
+ * pt.c (tsubst_qualified_id): Retain the type if we aren't dealing
+ with a dependent type. Actually look up the destructor.
+ * semantics.c (finish_id_expression): Fix logic.
+ (finish_qualified_id_expr): Don't try to use 'this' if we aren't in
+ a function.
+ * typeck.c (build_x_unary_op): Diagnose taking the address of a
+ constructor or destructor.
+ * tree.c (get_first_fn): Handle OFFSET_REF.
+
+2009-05-17 Joseph Myers <joseph@codesourcery.com>
+
+ * tree.c (cxx_printable_name_internal): Allow consecutive
+ translated and untranslated cached copies of the name of the
+ current function.
+
+2009-05-15 Ian Lance Taylor <iant@google.com>
+
+ * cp-tree.h (enum cp_lvalue_kind_flags): Rename from
+ cp_lvalue_kind. Change all uses.
+ (enum base_access_flags): Rename from enum base_access. Change
+ all uses.
+ * parser.c (enum cp_parser_flags): Remove enum tag.
+
+2009-05-15 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR 16302
+ * call.c (build_new_op): Update calls to warn_logical_operator.
+
+2009-05-14 Ian Lance Taylor <iant@google.com>
+
+ * class.c (layout_class_type): Change itk to unsigned int.
+ * decl.c (finish_enum): Change itk to unsigned int.
+ * parser.c (cp_parser_check_decl_spec): Change ds to int. Remove
+ casts.
+
+2009-05-13 David Mandelin <dmandelin@mozilla.com>:
+
+ * decl.c (duplicate_decls): Preserve parameter attributes.
+
+2009-05-10 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (cxx_callgraph_analyze_expr): Use
+ cgraph_mark_address_taken.
+
+2009-05-10 Joseph Myers <joseph@codesourcery.com>
+
+ * call.c (name_as_c_string): Call type_as_string_translate.
+ Translate identifiers to locale character set.
+ * cp-tree.h (lang_decl_name): Update prototype.
+ (type_as_string_translate, decl_as_string_translate,
+ cxx_printable_name_translate): Declare.
+ * cxx-pretty-print.c (M_): Define.
+ (pp_cxx_unqualified_id, pp_cxx_canonical_template_parameter): Mark
+ English fragments for conditional translation with M_.
+ * decl.c (grokdeclarator): Translate identifiers to locale
+ character set for diagnostics.
+ * error.c (M_): Define.
+ (dump_template_bindings, dump_type, dump_aggr_type,
+ dump_type_prefix, dump_global_iord, dump_simple_decl, dump_decl,
+ dump_function_decl, dump_template_parms, dump_expr,
+ dump_binary_op, op_to_string, assop_to_string): Mark English
+ fragments for conditional translation with M_.
+ (type_as_string): Disable translation of identifiers.
+ (type_as_string_translate): New.
+ (expr_as_string): Disable translation of identifiers.
+ (decl_as_string): Disable translation of identifiers.
+ (decl_as_string_translate): New.
+ (lang_decl_name): Add parameter translate.
+ (args_to_string): Call type_as_string_translate.
+ (cp_print_error_function): Call cxx_printable_name_translate.
+ (print_instantiation_full_context,
+ print_instantiation_partial_context): Call
+ decl_as_string_translate.
+ * parser.c (cp_lexer_get_preprocessor_token): Use %qE for
+ identifier in diagnostic.
+ * tree.c (cxx_printable_name): Change to
+ cxx_printable_name_internal. Add parameter translate.
+ (cxx_printable_name, cxx_printable_name_translate): New wrappers
+ round cxx_printable_name_internal.
+
+2009-05-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c/36892
+ * call.c (build_call_a): Updated warn_deprecated_use call.
+ (build_over_call): Likewise.
+ * decl.c (grokdeclarator): Likewise.
+ (grokparms): Likewise.
+ * semantics.c (finish_id_expression): Likewise.
+ * typeck.c (build_class_member_access_expr): Likewise.
+ (finish_class_member_access_expr): Likewise.
+
+2009-05-06 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/17395
+ * pt.c (tsubst_copy) <case PARM_DECL>: We don't want to tsubst the
+ whole list of PARM_DECLs, just the current one.
+
+2009-05-05 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * cp-tree.h:
+ (opname_tab, assignop_tab, update_member_visibility, yyerror, yyhook,
+ mangle_compound_literal): Remove unused declarations.
+ (build_vfield_ref, cxx_print_statistics, clone_function_decl,
+ adjust_clone_args, maybe_push_cleanup_level, pushtag, make_anon_name,
+ pushdecl_top_level_maybe_friend, pushdecl_top_level_and_finish,
+ check_for_out_of_scope_variable, print_other_binding_stack,
+ maybe_push_decl, cxx_mark_addressable, force_target_expr,
+ build_target_expr_with_type, finish_case_label,
+ cxx_maybe_build_cleanup, begin_eh_spec_block, finish_eh_spec_block,
+ check_template_keyword, cxx_omp_predetermined_sharing,
+ cxx_omp_clause_default_ctor, cxx_omp_clause_copy_ctor,
+ cxx_omp_clause_assign_op, cxx_omp_clause_dtor, cxx_omp_finish_clause,
+ cxx_omp_privatize_by_reference): Rearrange the declarations line to
+ match the comment that indicates the .c file which the functions are
+ defined.
+ (cxx_print_xnode, cxx_print_decl, cxx_print_type,
+ cxx_print_identifier, cxx_print_error_function, pushdecl): Add comment.
+
+2009-05-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (cp_build_compound_expr): Require RHS to have a known
+ type.
+ * class.c (resolve_address_of_overloaded_function): Use
+ OVL_CURRENT for error message.
+ (instantiate_type): Forbid COMPOUND_EXPRs and remove code dealing
+ with them. Do not copy the node.
+
+2009-05-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/40013
+ * pt.c (tsubst): If magic NOP_EXPR with side-effects has no type,
+ set it from its operand's type after tsubst_expr.
+
+2009-05-04 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/28152
+ * parser.c (cp_lexer_get_preprocessor_token): Do not store the
+ canonical spelling for keywords.
+ (cp_parser_attribute_list): Use the canonical spelling for
+ keywords in attributes.
+
+2009-05-01 Joseph Myers <joseph@codesourcery.com>
+
+ * cxx-pretty-print.c (is_destructor_name, pp_cxx_unqualified_id,
+ pp_cxx_template_keyword_if_needed, pp_cxx_postfix_expression,
+ pp_cxx_new_expression, pp_cxx_delete_expression,
+ pp_cxx_unary_expression, pp_cxx_assignment_operator,
+ pp_cxx_assignment_expression, pp_cxx_expression,
+ pp_cxx_function_specifier, pp_cxx_decl_specifier_seq,
+ pp_cxx_simple_type_specifier, pp_cxx_type_specifier_seq,
+ pp_cxx_exception_specification, pp_cxx_direct_declarator,
+ pp_cxx_ctor_initializer, pp_cxx_type_id, pp_cxx_statement,
+ pp_cxx_namespace_alias_definition, pp_cxx_template_parameter,
+ pp_cxx_canonical_template_parameter, pp_cxx_template_declaration,
+ pp_cxx_declaration, pp_cxx_typeid_expression,
+ pp_cxx_va_arg_expression, pp_cxx_offsetof_expression,
+ pp_cxx_trait_expression): Mostly use pp_string and
+ pp_cxx_ws_string in place of pp_identifier and pp_cxx_identifier
+ for non-identifiers. Mark English strings for translation.
+ * cxx-pretty-print.h (pp_cxx_ws_string): Define.
+ * error.c (dump_template_parameter, dump_template_bindings,
+ dump_type, dump_aggr_type, dump_type_prefix, dump_simple_decl,
+ dump_decl, dump_template_decl, dump_function_decl,
+ dump_parameters, dump_exception_spec, dump_template_parms,
+ dump_expr, dump_binary_op, dump_unary_op, op_to_string,
+ assop_to_string, args_to_string, cp_print_error_function,
+ print_instantiation_full_context,
+ print_instantiation_partial_context): Mostly use pp_string and
+ pp_cxx_ws_string in place of pp_identifier and pp_cxx_identifier
+ for non-identifiers. Mark English strings for translation.
+ (dump_global_iord): Mark strings for translation; use longer
+ strings instead of substituting single words.
+ (function_category): Return a format string marked for
+ translation, not a single word or phrase to substitute in a longer
+ phrase.
+
+2009-04-28 Ben Elliston <bje@au.ibm.com>
+
+ PR c++/35652
+ Revert:
+
+ 2009-03-27 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * typeck.c (cp_pointer_sum): Adjust call to pointer_int_sum.
+
+2009-04-27 Ian Lance Taylor <iant@google.com>
+
+ * semantics.c (finish_omp_clauses): Change type of c_kind to enum
+ omp_clause_code.
+
+2009-04-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/39875
+ * cvt.c (convert_to_void) <case INDIRECT_REF>: Only warn about
+ -Wunused-value if implicit.
+
+2009-04-24 Ian Lance Taylor <iant@google.com>
+
+ * call.c (build_temp): Change 0 to enum constant.
+ * cp-tree.h (cp_lvalue_kind): Typedef to int rather than enum
+ type.
+ * cp-gimplify.c (cp_gimplify_expr): Add cast to enum type.
+ * decl2.c (constrain_visibility): Likewise.
+ * parser.c (cp_lexer_get_preprocessor_token): Likewise.
+ (cp_parser_flags): Typedef to int rather than enum type.
+ (cp_parser_expression_stack_entry): Change prec field to enum
+ cp_parser_prec.
+
+ * typeck.c (build_modify_expr): Add lhs_origtype parameter.
+ Change all callers.
+
+2009-04-22 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/39639
+ * parser.c (cp_parser_template_argument_list): Display an error
+ when an ellipsis is not preceded by a parameter pack. Also, warn
+ about variadic templates usage without -std=c++0x.
+
+2009-04-21 Taras Glek <tglek@mozilla.com>
+
+ * cp-tree.h: Update GTY annotations to new syntax.
+ * decl.c: Likewise.
+ * mangle.c: Likewise.
+ * name-lookup.c: Likewise.
+ * name-lookup.h: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * semantics.c: Likewise.
+ * typeck2.c: Likewise.
+
+2009-04-22 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/14875
+ * parser.c (cp_parser_error): Pass token->flags to c_parse_error.
+
+2009-04-21 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/35711
+ * typeck.c (check_for_casting_away_constness): We diagnose casting
+ away any qualifiers not just constness.
+ (casts_away_constness): Mention that it handles more than just
+ constness.
+
+2009-04-21 Joseph Myers <joseph@codesourcery.com>
+
+ * ChangeLog, ChangeLog-1993, ChangeLog-1994, ChangeLog-1995,
+ ChangeLog-1996, ChangeLog-1997, ChangeLog-1998, ChangeLog-1999,
+ ChangeLog-2000, ChangeLog-2001, ChangeLog-2002, ChangeLog-2003,
+ ChangeLog-2004, ChangeLog-2005, ChangeLog-2006, ChangeLog-2007,
+ ChangeLog-2008, ChangeLog.ptr, ChangeLog.tree-ssa, NEWS,
+ cfns.gperf: Add copyright and license notices.
+ * cfns.h: Regenerate.
+ * ChangeLog, ChangeLog-2004: Correct dates.
+
+2009-04-21 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR 16202
+ * tree.c (lvalue_p_1): Use const_tree.
+ Use CONST_CAST_TREE to avoid warning.
+ (lvalue_p): Returns bool, receives const_tree.
+
+2009-04-21 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/13358
+ * parser.c (cp_parser_check_decl_spec): Drop redundant flags.
+ * error.c (pedwarn_cxx98): New.
+ * cp-tree.h (pedwarn_cxx98): Declare.
+
+2009-04-20 Le-Chun Wu <lcwu@google.com>
+
+ PR c++/39803
+ * init.c (build_vec_init): Set TREE_NO_WARNING on the
+ compiler-generated INDIRECT_REF expression.
+
+2009-04-20 Ian Lance Taylor <iant@google.com>
+
+ * typeck.c (build_function_call_vec): New function.
+ (cp_build_function_call): Only pass first parameter to
+ objc_rewrite_function_call.
+ (build_modify_expr): Add rhs_origtype parameter. Change all
+ callers.
+ * decl.c (finish_decl): Add origtype parameter. Change all
+ callers.
+ * semantics.c (finish_call_expr): Pass VEC to
+ resolve_overloaded_builtin.
+
+2009-04-20 Ian Lance Taylor <iant@google.com>
+
+ * cp-tree.h (base_access): Change typedef to int.
+ * parser.c (cp_parser_omp_flush): Change 0 to OMP_CLAUSE_ERROR.
+ (cp_parser_omp_threadprivate): Likewise.
+ * pt.c (unify_pack_expansion): Add casts to enum type.
+
+2009-04-19 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/32061
+ PR c++/36954
+ * call.c (build_new_op): Save the original codes of operands
+ before folding.
+
+2009-04-18 Kazu Hirata <kazu@codesourcery.com>
+
+ * cp-tree.h: Remove the prototype for insert_block.
+ * decl.c (insert_block): Remove.
+
+2009-04-16 Ian Lance Taylor <iant@google.com>
+
+ * cp-tree.h (enum tsubst_flags): Rename from enum tsubst_flags_t.
+ (tsubst_flags_t): Change typedef from enum type to int.
+
+2009-04-16 Paolo Bonzini <bonzini@gnu.org>
+
+ * decl.c (check_initializer): Use TYPE_VECTOR_OPAQUE
+ instead of targetm.vector_opaque_p.
+
+2009-04-15 Le-Chun Wu <lcwu@google.com>
+
+ PR c++/39551
+ * call.c (build_over_call): Set TREE_NO_WARNING on the
+ compiler-generated INDIRECT_REF expression.
+ * cvt.c (convert_to_void): Emit warning when stripping off
+ INDIRECT_REF.
+
+2009-04-14 Diego Novillo <dnovillo@google.com>
+
+ * parser.c (cp_parser_type_specifier_seq): Move call to
+ invoke_plugin_callbacks ...
+ (cp_parser_type_specifier_seq): ... here.
+
+2009-04-14 Le-Chun Wu <lcwu@google.com>
+
+ * Make-lang.in: Modify dependencies of files including plugin.h.
+ * decl.c (finish_function): Call invoke_plugin_callbacks.
+ * parser.c (cp_parser_type_specifier): Call invoke_plugin_callbacks.
+
+2009-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/39763
+ * name-lookup.c (pushdecl_maybe_friend): Avoid all warnings
+ about shadowing by tentative parms.
+
+2009-04-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/39480
+ * call.c (build_over_call): Don't call memcpy if the target is
+ the same as the source.
+
+2009-04-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/39750
+ * pt.c (uses_template_parms): Handle CONSTRUCTOR.
+
+2009-04-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/39742
+ * call.c (joust): Don't crash on variadic fn.
+
+2009-04-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/28301
+ * parser.c (cp_parser_skip_to_end_of_block_or_statement): Return
+ if we see a close brace without an open brace.
+
+2009-04-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * parser.c (cp_parser_class_specifier): Remove the unused
+ has_trailing_semicolon.
+
+2009-04-10 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/20118
+ * parser.c (cp_parser_check_template_parameters): Take a
+ cp_declarator parameter.
+ (cp_parser_elaborated_type_specifier): Update to
+ cp_parser_check_template_parameters.
+ (cp_parser_class_head): Likewise.
+ (cp_parser_check_declarator_template_parameters): Likewise.
+ (cp_parser_check_template_parameters): Handle first the non-error
+ conditions. Give more accurate diagnostics if a declarator is
+ given.
+
+2009-04-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/25185
+ * error.c (dump_aggr_type): Chase template typedefs if
+ -fno-pretty-templates.
+
+2009-04-08 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/39637
+ * parser.c (cp_parser_enumerator_definition): Make sure the
+ initializer of the enumerator doesn't contain any bare parameter pack.
+
+2009-04-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/34691
+ * name-lookup.c (merge_functions): Keep multiple extern "C" functions.
+ * call.c (joust): Complain about mismatched default arguments
+ in extern "C" functions.
+ * class.c (resolve_address_of_overloaded_function): Handle multiple
+ extern "C" functions.
+ * pt.c (resolve_overloaded_unification): Likewise.
+
+2009-04-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/25185
+ * error.c (dump_function_decl): Don't pretty-print templates
+ if -fno-pretty-templates.
+ (count_non_default_template_args): Print all args if
+ -fno-pretty-templates.
+
+2009-04-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/35146
+ * pt.c (fn_type_unification): For DEDUCE_EXACT check that
+ the deduced template arguments give us the parameter types
+ we're looking for.
+
+2009-04-05 Giovanni Bajo <giovannibajo@libero.it>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/14912
+ * error.c (count_non_default_template_args): New fn.
+ (dump_template_parms): Call it.
+ (dump_template_argument_list): Call it. Add parms parm.
+ (dump_template_argument): Adjust call to dump_template_argument_list.
+ (dump_type, dump_decl): Likewise.
+ (dump_template_bindings): Refactor logic.
+
+2009-04-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/25185
+ * error.c (dump_template_bindings): Look through typedefs in
+ typename results.
+ (dump_type) [TYPENAME_TYPE]: Print the typedef name if any.
+ (find_typenames_r): Also collect typedefs.
+ * pt.c (unify): Strip typedefs.
+
+ PR c++/39608
+ * semantics.c (finish_id_expression): Don't assume a dependent
+ member of the current instantiation isn't a valid integral
+ constant expression. Check dependent_scope_p.
+ * pt.c (dependent_scope_p): Check TYPE_P.
+ (tsubst_copy): If args is null, just return.
+
+2009-04-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/25185
+ * error.c (find_typenames, find_typenames_r): New fns.
+ (dump_function_decl): Call find_typenames.
+ (dump_template_bindings): Print typenames as well.
+ * pt.c (tsubst): Non-static.
+ * cp-tree.h: Declare it.
+
+2009-04-02 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/26693
+ * decl2.c (grokfield): when a typedef appears in a
+ class, create the typedef variant type node for it.
+ (save_template_attributes): Creating typedef variant type node
+ here is now useless.
+ * decl.c (grokdeclarator): If the typedef'ed struct/class was
+ anonymous, set the proper type name to all its type variants.
+ (xref_basetypes) : Fixup the variant types after setting
+ TYPE_BINFO on REF.
+ * name-lookup.c (pushdecl_maybe_friend): Reuse the
+ set_underlying_type function to install typedef variant types.
+ * cp-tree.h (MEMBER_TYPES_NEEDING_ACCESS_CHECK): New template accessor
+ macro.
+ (append_type_to_template_for_access_check): New entry points.
+ * semantics.c (check_accessibility_of_qualified_id):
+ When a typedef that is a member of a class appears in a template,
+ add it to the template. It will be ...
+ * class.c (finish_struct_bits): Split type variant fixup into ...
+ (fixup_type_variants): A new entry point.
+ * pt.c (instantiate_class_template, instantiate_template ): ... access
+ checked at template instantiation time.
+ (resolve_type_name_type): The type name should be the name of the
+ main type variant.
+ (retrieve_specialization): Specializations of template typedefs aren't
+ to looked up in DECL_TEMPLATE_INSTANTIATIONS (tmpl).
+ (append_type_to_template_for_access_check): New entry point.
+ (tsubst_decl): For typedefs, build the variant type from the correct
+ original type.
+ (get_class_bindings): Fix function comment.
+ (perform_typedefs_access_check): New entry point.
+
+2009-03-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/34691
+ * name-lookup.c (pushdecl_maybe_friend): Diagnose mismatched
+ extern "C" declarations.
+
+ C++ DR 613
+ * semantics.c (finish_non_static_data_member): Allow such references
+ without an associated object in sizeof/decltype/alignof.
+
+ * ptree.c (cxx_print_decl): Pretty-print full name of
+ function/template.
+ (cxx_print_type): Pretty-print full name of class.
+
+ * decl.c (grokdeclarator): Reject pointer to qualified function
+ type.
+
+ PR c++/37806, core issue 547
+ * typeck.c (cp_apply_type_quals_to_decl): Don't apply any quals
+ to a typedef.
+ * tree.c (cp_build_qualified_type_real): Don't apply restrict to a
+ function type.
+ * decl.h (enum decl_context): Add TEMPLATE_TYPE_ARG.
+ * decl.c (groktypename): Add is_template_arg parameter.
+ (grokdeclarator): Allow function cv-quals on a template type arg.
+ * parser.c (cp_parser_new_type_id, cp_parser_type_id): Add
+ is_template_arg argument in calls to groktypename.
+ * cp-tree.h: Adjust prototype.
+ * error.c (dump_type_prefix, dump_type_suffix): Fix plain
+ FUNCTION_TYPE printing.
+
+ * mangle.c (write_expression): Mangle dependent name as
+ source-name.
+
+ PR c++/38030, 38850, 39070
+ * pt.c (type_dependent_expression_p_push): New fn.
+ (tsubst_copy_and_build) [CALL_EXPR]: Only do arg-dep lookup when the
+ substitution makes the call non-dependent. Preserve koenig_p.
+ * parser.c (cp_parser_postfix_expression): Only do arg-dep lookup
+ for non-dependent calls.
+ * semantics.c (finish_call_expr): Revert earlier changes.
+ * cp-tree.h: Revert change to finish_call_expr prototype.
+
+2009-03-29 Joseph Myers <joseph@codesourcery.com>
+
+ PR preprocessor/34695
+ * cp-tree.h (cp_cpp_error): Remove.
+ * error.c (cp_cpp_error): Remove.
+ * parser.c (cp_lexer_new_main): Set done_lexing instead of
+ client_diagnostic and error callback.
+
+2009-03-28 Paolo Bonzini <bonzini@gnu.org>
+
+ * cp/cp-objcp-common.h (LANG_HOOKS_STATICP): Remove.
+ * cp/cp-objcp-common.c (cxx_staticp): Remove.
+ * cp/cp-tree.h (cxx_staticp): Remove.
+
+2009-03-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/39554
+ * parser.c (cp_parser_postfix_expression): Don't call
+ warning_if_disallowed_function_p.
+
+2009-03-27 Jan Hubicka <jh@suse.cz>
+
+ * except.c (choose_personality_routine): Set terminate_node to abort
+ for java exceptions.
+
+2009-03-27 Dodji Seketeli <dodji@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/37959
+ * cp-objcp-common.h (LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P): Define.
+ (cp_function_decl_explicit_p): New prototype.
+ * cp-objcp-common.c (cp_function_decl_explicit_p): New function.
+
+2009-03-27 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR c++/38638
+ * parser.c (cp_parser_elaborated_type_specifier): If we have a
+ typename tag and don't have either a TYPE_DECL or a
+ TEMPLATE_ID_EXPR, set the type to NULL.
+
+2009-03-27 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/37647
+ * decl.c (grokdeclarator): Reject [con|de]stuctors in a non-class
+ scope.
+
+2009-03-27 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/29727
+ * decl.c (check_array_designated_initializer): Handle error_mark_node.
+
+2009-03-27 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/35652
+ * typeck.c (cp_pointer_sum): Adjust call to pointer_int_sum.
+
+2009-03-26 Andrew Haley <aph@redhat.com>
+
+ PR C++/39380
+ * decl2.c (possibly_inlined_p): If java exceptions are in use
+ don't inline a decl unless it is explicitly marked inline.
+ * lex.c: (pragma_java_exceptions): New variable.
+ (handle_pragma_java_exceptions): Set pragma_java_exceptions.
+ * cp-tree.h (pragma_java_exceptions): Declare new variable.
+
+2009-03-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/28274
+ * name-lookup.c (pushdecl_maybe_friend): Check default args later.
+
+2009-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/39495
+ * semantics.c (handle_omp_for_class_iterator): Swap cond operands and
+ code if iter is the second operand.
+ * parser.c (cp_parser_binary_expression): Add no_toplevel_fold_p
+ argument. If it is set, don't build the toplevel expression with
+ build_x_binary_op, but build2.
+ (cp_parser_assignment_expression, cp_parser_omp_for_incr): Adjust
+ callers.
+ (cp_parser_omp_for_cond): Don't assume the first operand of the
+ comparison must be decl.
+
+2009-03-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/37729
+ * pt.c (make_fnparm_pack): Split out from...
+ (instantiate_decl): ...here.
+ (tsubst_pack_expansion): Handle being called in a late-specified
+ return type.
+
+ PR c++/39526
+ * name-lookup.c (pushdecl_maybe_friend): Don't warn about shadowing
+ a parm with a parm.
+
+2009-03-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/28879
+ * parser.c (cp_parser_direct_declarator): In a template, wrap
+ non-constant expression in NOP_EXPR with TREE_SIDE_EFFECTS set.
+ * pt.c (tsubst): Preserve it in a partial instantiation.
+ (dependent_type_p_r): Don't check value_dependent_expression_p.
+ * decl.c (compute_array_index_type): Don't check
+ value_dependent_expression_p if TREE_SIDE_EFFECTS.
+
+ C++ core issue 703
+ * typeck2.c (check_narrowing): Don't complain about loss of
+ precision when converting a floating-point constant.
+
+2009-03-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/39495
+ * parser.c (cp_parser_omp_for_cond): Don't check lhs if decl is NULL.
+ (cp_parser_omp_for_loop): Always use cp_parser_omp_for_cond.
+
+2009-03-18 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (struct cp_token): Reorder fields for 64-bit hosts.
+ (eof_token): Adjust.
+
+2009-03-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/39425
+ * parser.c (cp_parser_explicit_specialization): Don't skip the
+ rest of the specialization when begin_specialization returns
+ false.
+
+2009-03-17 Jason Merrill <jason@redhat.com>
+
+ * decl.c (grokfndecl): Set DECL_CONTEXT on parms.
+ (duplicate_decls): Adjust DECL_CONTEXT of newdecl's parms.
+ * pt.c (check_explicit_specialization): Likewise.
+ (tsubst_copy) [PARM_DECL]: Return a dummy parm if we don't have a
+ local specialization.
+ * tree.c (cp_tree_equal) [PARM_DECL]: Check type and index, not name.
+ * decl2.c (parm_index): New fn.
+ * semantics.c (finish_decltype_type): Don't use describable_type.
+ * mangle.c (write_expression): Likewise. Mangle ALIGNOF_EXPR.
+ Give a sorry for unsupported codes rather than crash. Mangle
+ conversions with other than 1 operand. New mangling for PARM_DECL.
+ * operators.def (ALIGNOF_EXPR): Mangle as "az".
+
+2009-03-17 Jing Yu <jingyu@google.com>
+
+ PR middle-end/39378
+ * method.c (use_thunk): Change is_thunk from crtl to cfun.
+
+2009-03-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/39475
+ * semantics.c (check_trait_type): New.
+ (finish_trait_expr): Use it.
+
+2009-03-17 Jakub Jelinek <jakub@redhat.com>
+
+ * name-lookup.c (cp_emit_debug_info_for_using): Emit USING_STMTs
+ instead of calling imported_module_or_decl debug hook if
+ building_stmt_tree ().
+ * cp-gimplify.c (cp_gimplify_expr): Don't assert the first operand
+ is a NAMESPACE_DECL.
+
+ PR debug/37890
+ * name-lookup.c (do_namespace_alias): Don't call global_decl debug
+ hook at function scope.
+
+ PR debug/39471
+ * cp-gimplify.c (cp_gimplify_expr): Don't set DECL_NAME
+ on IMPORTED_DECL.
+
+2009-03-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/39371
+ * semantics.c (finish_switch_cond): Don't call get_unwidened.
+ * decl.c (finish_case_label): Pass SWITCH_STMT_TYPE as 3rd argument
+ instead of TREE_TYPE (cond).
+
+2009-03-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/39060
+ * parser.c (cp_parser_late_parsing_default_args): Continue
+ the loop when cp_parser_assignment_expression returns
+ error_mark_node.
+
+2009-03-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/39367
+ * init.c (build_new_1): Don't use a VLA type.
+ (build_vec_init): Handle getting a pointer for BASE.
+
+2009-03-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/37520
+ * cp-tree.h: Check NO_DOT_IN_LABEL before NO_DOLLAR_IN_LABEL
+ when mangling symbols.
+
+2009-03-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/33492
+ * error.c (dump_expr): Don't try to print THROW_EXPRs in full.
+
+2009-03-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * decl.c (record_builtin_java_type): Use canonicalized integer
+ types.
+
+2009-03-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/38908
+ * class.c (is_really_empty_class): New fn.
+ * cp-tree.h: Declare it.
+ * cp-objcp-common.c (cp_expr_size): Use it.
+
+ PR c++/13549
+ * semantics.c (perform_koenig_lookup): Handle TEMPLATE_ID_EXPR.
+ * parser.c (cp_parser_postfix_expression): Call it for
+ TEMPLATE_ID_EXPR.
+ * tree.c (is_overloaded_fn): Look through TEMPLATE_ID_EXPR.
+ (get_first_fn): Likewise.
+
+ PR c++/9634
+ PR c++/29469
+ PR c++/29607
+ Implement DR 224.
+ * decl.c (make_typename_type): Do look inside currently open classes.
+ * parser.c (cp_parser_lookup_name): Likewise.
+ (cp_parser_template_name): Likewise.
+ * pt.c (dependent_scope_p): New function.
+ * cp-tree.h: Declare it.
+ * class.c (currently_open_class): Return fast if T isn't a class.
+
+2009-02-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/37789
+ * parser.c (cp_parser_mem_initializer): Return error_mark_node
+ if cp_parser_mem_initializer_id returns error_mark_node.
+
+2009-02-24 Richard Guenther <rguenther@suse.de>
+
+ PR c++/39242
+ * pt.c (instantiate_decl): Do not instantiate extern, non-inline
+ declared functions.
+
+2009-02-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/36411
+ * pt.c (coerce_template_template_parms): Return 0 if parameter
+ is error_mark_node.
+
+2009-02-23 Jason Merrill <jason@redhat.com>
+
+ * pt.c (unify): Call maybe_adjust_types_for_deduction when
+ deducing from an initializer list.
+
+2009-02-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/39225
+ * decl.c (grokdeclarator): Handle ~identifier.
+
+2009-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/39175
+ * decl2.c (determine_visibility): If visibility changed and
+ DECL_RTL has been already set, call make_decl_rtl to update symbol
+ flags.
+
+2009-02-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/39188
+ * cp-tree.h (maybe_commonize_var): New.
+
+ * decl.c (maybe_commonize_var): Make it extern.
+
+ * decl2.c (finish_anon_union): Call maybe_commonize_var.
+
+2009-02-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/39219
+ * parser.c (cp_parser_enum_specifier): Apply all attributes.
+
+2009-02-18 Jason Merrill <jason@redhat.com>
+
+ * cfns.h: Tweak pathname for cfns.gperf.
+
+2009-02-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/39070
+ * semantics.c (finish_call_expr): Change koenig_p parm to int.
+ If -1, don't set KOENIG_LOOKUP_P but do keep hidden candidates.
+ * cp-tree.h: Adjust prototype.
+ * pt.c (tsubst_copy_and_build) [CALL_EXPR]: Pass -1.
+
+2009-02-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/38950
+ * pt.c (unify)[TEMPLATE_PARM_INDEX]: Convert to the tsubsted type.
+
+2009-02-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/39153
+ * decl2.c (cp_write_global_declarations):
+ Check DECL_DEFAULTED_FN, not DECL_ARTIFICIAL.
+
+ PR c++/30111
+ * init.c (build_value_init_noctor): Split out from...
+ (build_value_init): ...here.
+ (expand_aggr_init_1): Handle value-initialization.
+ * cp-tree.h: Add declaration.
+ * class.c (type_has_user_provided_constructor):
+ Handle non-class arguments.
+
+2009-02-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/38649
+ * class.c (defaultable_fn_p): Handle ... properly.
+
+ PR c++/36744
+ * tree.c (lvalue_p_1): Condition rvalue ref handling on
+ treat_class_rvalues_as_lvalues, too.
+
+2009-02-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/34397
+ * typeck.c (build_x_array_ref): New.
+ * cp-tree.h: Declare it.
+ * pt.c (tsubst_copy_and_build): Use it for case ARRAY_REF.
+
+2009-02-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/39109
+ * semantics.c (simplify_aggr_init_expr): Do zero-initialization here.
+ * init.c (build_value_init): Not here. Don't build a TARGET_EXPR.
+ * tree.c (get_target_expr): Handle AGGR_INIT_EXPR.
+ * cp-gimplify.c (cp_gimplify_init_expr): Remove special handling
+ for build_value_init TARGET_EXPR.
+ * cp-tree.h (AGGR_INIT_ZERO_FIRST): New macro.
+
+2009-02-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/35147
+ PR c++/37737
+ * cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Check TREE_VEC_LENGTH.
+
+2009-02-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/39095
+ * operators.def: Use COMPONENT_REF code for ->/pt operator again,
+ remove ./dt operator.
+ * mangle.c (write_expression): Handle COMPONENT_REF after handling
+ ADDR_EXPR, for COMPONENT_REF without ARROW_EXPR inside of it
+ write_string ("dt") instead of using operators.def.
+
+2009-02-03 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (cp_build_unary_op): Only complain about taking address
+ of main if pedantic.
+
+2009-02-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR inline-asm/39059
+ * parser.c (cp_parser_primary_expression): Reject FIXED_CSTs.
+
+ PR c++/39056
+ * typeck2.c (digest_init_r): Don't call process_init_constructor
+ for COMPLEX_TYPE.
+
+2009-02-03 Paolo Bonzini <bonzini@gnu.org>
+
+ PR c++/36897
+ * pt.c (convert_nontype_argument_function): Expect expr to be an
+ ADDR_EXPR.
+
+ PR c++/37314
+ * typeck.c (merge_types): Call resolve_typename_type if only
+ one type is a typename.
+
+2009-02-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/39054
+ * parser.c (cp_parser_unqualified_id): Don't wrap error_mark_node
+ in BIT_NOT_EXPR.
+
+2009-02-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/39053
+ * parser.c (cp_parser_pure_specifier): If there are no tokens left
+ do not call cp_lexer_consume_token.
+
+2009-01-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/39028
+ * parser.c (cp_parser_already_scoped_statement): Handle __label__
+ declarations.
+
+2009-01-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/33465
+ * error.c (dump_expr): Handle FIX_TRUNC_EXPR and FLOAT_EXPR.
+
+2009-01-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/38655
+ * error.c (dump_type_prefix, dump_type_suffix): Handle FIXED_POINT_TYPE.
+
+2009-01-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * typeck.c (invalid_nonstatic_memfn_p): Use
+ DECL_NONSTATIC_MEMBER_FUNCTION_P.
+
+2009-01-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/37554
+ * call.c (build_over_call): If convert_for_arg_passing returns
+ error_mark_node unconditionally return it.
+
+2009-01-22 Adam Nemet <anemet@caviumnetworks.com>
+
+ * class.c (check_field_decls): Also inherit packed for bitfields
+ regardless of their type.
+
+2009-01-22 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/38930
+ * decl2.c (grokfield): Reverting changes of PR c++/26693
+ (save_template_attributes): Likewise.
+ * decl.c (grokdeclarator): Likewise.
+ * name-lookup.c (pushdecl_maybe_friend): Likewise.
+ * cp-tree.h (MEMBER_TYPES_NEEDING_ACCESS_CHECK): Likewise.
+ (append_type_to_template_for_access_check): Likewise.
+ * semantics.c (check_accessibility_of_qualified_id): Likewise.
+ * pt.c (instantiate_class_template, instantiate_template ): Likewise.
+ (tsubst): Likewise.
+ (resolve_type_name_type): Likewise.
+ (append_type_to_template_for_access_check): Likewise.
+
+2009-01-21 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/26693
+ * decl2.c (grokfield): when a typedef appears in a
+ class, create the typedef variant type node for it.
+ (save_template_attributes): Creating typedef variant type node
+ here is now useless.
+ * decl.c (grokdeclarator): If the typedef'ed struct/class was
+ anonymous, set the proper type name to all its type variants.
+ * name-lookup.c (pushdecl_maybe_friend): Reuse the
+ set_underlying_type function to install typedef variant types.
+ * cp-tree.h (MEMBER_TYPES_NEEDING_ACCESS_CHECK): New template accessor
+ macro.
+ (append_type_to_template_for_access_check): New entry points.
+ * semantics.c (check_accessibility_of_qualified_id):
+ When a typedef that is a member of a class appears in a template,
+ add it to the template. It will be ...
+ * pt.c (instantiate_class_template, instantiate_template ): ... access
+ checked at template instantiation time.
+ (tsubst): Handle the case of being called with NULL args.
+ (resolve_type_name_type): The type name should be the name of the
+ main type variant.
+ (append_type_to_template_for_access_check): New entry point.
+
+2009-01-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/23287
+ * parser.c (cp_parser_unqualified_id): In a template,
+ accept ~identifier.
+ * typeck.c (lookup_destructor): Handle IDENTIFIER_NODE.
+
+2009-01-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/38877
+ * tree.c (lvalue_p_1): Allow non-fields in COMPONENT_REF.
+ * init.c (build_new): Don't call describable_type unless we
+ have an auto.
+
+ PR c++/29470
+ * pt.c (tsubst_decl) [USING_DECL]: Propagate access flags.
+
+ PR c++/38579
+ * search.c (protected_accessible_p): N doesn't vary.
+
+2009-01-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/38850
+ * pt.c (tsubst_copy_and_build): Tell finish_call_expr to
+ accept hidden friends.
+
+2009-01-15 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR C++/29388
+ * decl.c (grokdeclarator): Check for a non namespace/class context.
+
+2009-01-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/36334
+ PR c++/37646
+ * tree.c (lvalue_p_1): Handle BASELINK. A COMPONENT_REF to
+ a function isn't necessarily an lvalue. Take tree, not const_tree.
+ (lvalue_p, real_lvalue_p): Take tree, not const_tree.
+ * typeck.c (lvalue_or_else): Likewise.
+ * cp-tree.h: Adjust prototypes.
+
+2009-01-15 Steve Ellcey <sje@cup.hp.com>
+
+ PR c++/38357
+ * pt.c (tsubst): Check for NULL args.
+
+2009-01-15 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/38636
+ * name-lookup.c (pushtag): Don't create members to types that are not
+ being created.
+
+2009-01-14 Nick Clifton <nickc@redhat.com>
+
+ PR c++/37862
+ * parser.c: Pass cp_id_kind computed in
+ cp_parser_postfix_dot_deref_expression to
+ cp_parser_primary_expression.
+
+2009-01-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38795
+ * tree.c (cp_walk_subtrees): Handle REINTERPRET_CAST_EXPR,
+ STATIC_CAST_EXPR, CONST_CAST_EXPR and DYNAMIC_CAST_EXPR the same
+ as CAST_EXPR.
+
+2009-01-12 Jason Merrill <jason@redhat.com>
+ Steve Ellcey <sje@cup.hp.com>
+
+ PR c++/35109
+ * name-lookup.c (lookup_name_real): Keep looking past a hidden
+ binding.
+
+2009-01-12 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/36019
+ * pt.c (parameter_of_template_p): New function.
+ * cp-tree.h: Declare it.
+ * name-lookup.c (binding_to_template_parms_of_scope_p): New
+ function.
+ (outer_binding): Take template parameters in account when looking for
+ a name binding.
+
+2009-01-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/31488
+ * tree.c (pod_type_p): Return 1 for structs created by the back end.
+
+2009-01-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/32041
+ * parser.c (cp_parser_builtin_offsetof): Allow `->' in
+ offsetof member-designator, handle it as `[0].'.
+
+ PR c++/38794
+ * decl.c (start_function): If grokdeclarator hasn't returned
+ FUNCTION_DECL nor error_mark_node, issue diagnostics.
+
+2009-01-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/36254
+ * cp-gimplify.c (genericize_if_stmt): Renamed from ...
+ (gimplify_if_stmt): ... this.
+ (cp_gimplify_expr): Don't handle IF_STMT here.
+ (cp_genericize_r): Call genericize_if_stmt for IF_STMT.
+
+2009-01-10 Andrew Pinski <pinskia@gmail.com>
+
+ PR c++/38648
+ * typeck.c (cp_build_modify_expr): Check for NULL current_function_decl.
+
+ PR c++/36695
+ * typeck2.c (build_functional_cast): Check for reference type and NULL
+ PARMS.
+
+2009-01-09 Steve Ellcey <sje@cup.hp.com>
+
+ * typeck.c (cp_build_unary_op): Check for ERROR_MARK.
+
+2009-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35335
+ * error.c (dump_expr): Handle EXPR_STMT like BIND_EXPR.
+
+2009-01-09 John F. Carr <jfc@mit.edu>
+
+ PR c++/37877
+ * parser.c (cp_parser_class_specifier): Clear
+ parser->in_unbraced_linkage_specification_p while parsing class
+ specifiers.
+
+2009-01-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38725
+ * semantics.c (finish_goto_stmt): Convert destination to
+ void *.
+
+2009-01-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/35297
+ PR c++/35477
+ PR c++/35784
+ PR c++/36846
+ PR c++/38276
+ * pt.c (check_default_tmpl_args): Don't complain about
+ out-of-order parameter packs in the enclosing class
+ or parameter packs after default args.
+ (coerce_template_parms): If we have more than one
+ parameter pack, don't flatten argument packs.
+ (template_args_equal): Handle argument packs.
+ (comp_template_args): Don't flatten argument packs.
+ (check_instantiated_arg): Split out from...
+ (check_instantiated_args): Here. Handle arg packs.
+ (convert_template_argument): Just check that nontype argument
+ packs have the right type.
+
+2009-01-05 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/38472
+ * typeck.c (type_after_usual_arithmetic_conversions): Fix a typo.
+
+2009-01-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/38698
+ * typeck2.c (process_init_constructor_union): Handle union with
+ no fields.
+
+ * mangle.c (write_expression): Remove mangling for zero-operand
+ casts.
+
+ PR c++/38701
+ * decl.c (cp_finish_decl): Clear DECL_INITIAL for invalid
+ defaulting.
+
+ PR c++/38702
+ * class.c (defaultable_fn_p): Only operator== can be a copy
+ assignment operator.
+
+2009-01-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/38698
+ * typeck2.c (process_init_constructor_union): Handle excess
+ initializers.
+ (process_init_constructor_record): Likewise.
+
+ PR c++/38684
+ * typeck2.c (digest_init_r): Don't use process_init_constructor
+ for non-aggregate classes.
+
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2010 b/gcc-4.9/gcc/cp/ChangeLog-2010
new file mode 100644
index 000000000..5f563157c
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2010
@@ -0,0 +1,4064 @@
+2010-12-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/47068
+ * semantics.c (finish_id_expression): Don't note non-names
+ as being used in the class.
+
+2010-12-23 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_unary_expression): Remove redundant C++0x
+ check.
+
+2010-12-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/46626
+ * semantics.c (build_data_member_initialization): For CLEANUP_STMT
+ recurse into CLEANUP_BODY.
+
+2010-12-25 Kai Tietz <kai.tietz@onevision.com>
+
+ PR c++/15774
+ * decl.c (decls_match): Check for FUNCTION_DECL
+ also for identity of compatible attributes.
+
+2010-12-22 Nathan Froyd <froydnj@codesourcery.com>
+
+ * decl.c (decls_match, duplicate_decls): Use prototype_p.
+ * pt.c (push_template_decl_real): Likewise.
+
+2010-12-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/47003
+ * tree.c (stabilize_expr): Really stabilize scalar glvalues.
+
+2010-12-22 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+ * parser.c (cp_parser_unary_expression): Call pedwarn for alignof
+ with expression.
+
+2010-12-18 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_try_catch_finally_statement): Call
+ objc_maybe_warn_exceptions.
+ (cp_parser_objc_synchronized_statement): Same change.
+
+2010-12-18 Joseph Myers <joseph@codesourcery.com>
+
+ * pt.c (most_specialized_class): Use ngettext to determine
+ "candidates are:" / "candidate is" message.
+
+2010-12-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/46670
+ * pt.c (value_dependent_expression_p) [ARRAY_REF]: Handle
+ properly.
+
+2010-12-15 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/39859
+ PR c++/44522
+ PR c++/44523
+ * parser.c (struct cp_parser): Add colon_corrects_to_scope_p field.
+ (cp_parser_new): Initialize it.
+ (cp_parser_nested_name_specifier_opt): Auto-correct colons to
+ scopes if we are able to.
+ (cp_parser_question_colon_clause): Disallow colon correction.
+ (cp_parser_label_for_labeled_statement): Likewise.
+ (cp_parser_range_for): Likewise.
+ (cp_parser_enum_specifier): Likewise.
+ (cp_parser_class_head): Likewise.
+ (cp_parser_member_declaration): Likewise.
+
+2010-12-15 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/46852
+ * parser.c (cp_parser_class_specifier): Check for TYPE_P.
+
+2010-12-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/46815
+ * cp-gimplify.c (cp_genericize): When changing RESULT_DECL
+ into invisible reference, change also DECL_VALUE_EXPR of
+ NRV optimized variable.
+
+2010-12-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/42083
+ * init.c (build_value_init): Check build_special_member_call return
+ value for error_mark_node.
+
+2010-12-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/46930
+ * decl.c (grokdeclarator): Reject uninitialized constexpr
+ static data member.
+
+2010-12-14 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/45330
+ * cp-tree.h (suggest_alternatives_for): Add location_t parameter.
+ * name-lookup.c (suggest_alternatives_for): Likewise. Adjust.
+ * lex.c (unqualified_name_lookup_error): Adjust call to it.
+ * semantics.c (qualified_name_lookup_error): Move to...
+ * error.c (qualified_name_lookup_error): ...here. Call.
+ suggest_alternatives_for.
+
+2010-12-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/46873
+ PR c++/46877
+ * semantics.c (build_data_member_initialization): Handle
+ cv-qualified data member.
+
+2010-12-13 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/45388
+ * decl2.c (start_objects): Do not generate collect2 recognicable name
+ for static ctor.
+
+2010-12-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/46901
+ * typeck.c (convert_for_assignment): Fix typo in warning message.
+
+2010-12-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/46001
+ * decl.c (record_builtin_java_type): Call build_distinct_type_copy
+ on build_nonstandard_integer_type result for __java_* types.
+
+2010-12-10 Nathan Froyd <froydnj@codesourcery.com>
+
+ * decl.c (grokmethod): Test DECL_CLASS_SCOPE_P.
+ * error.c (dump_decl): Test DECL_FILE_SCOPE_P.
+
+2010-12-10 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.h (readonly_error_kind): Delete.
+ (readonly_error): Rename to...
+ (cxx_readonly_error): ...this. Change second argument to be an
+ enum lvalue_use.
+ * semantics.c (finish_asm_stmt): Call cxx_readonly_error.
+ * typeck.c (cp_build_unary_op): Likewise.
+ (cp_build_modify_expr): Likewise.
+ * typeck2.c (readonly_error): Rename to...
+ (cxx_readonly_error): ...this. Delegate to readonly_error for
+ most cases.
+
+2010-12-10 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_superclass_or_category): Recognize
+ Objective-C 2.0 class extensions. Added iface_p and
+ is_class_extension arguments.
+ (cp_parser_objc_class_interface): Updated call to
+ cp_parser_objc_superclass_or_category.
+ (cp_parser_objc_class_implementation): Same change.
+
+2010-12-09 Nathan Froyd <froydnj@codesourcery.com>
+
+ * call.c (print_conversion_rejection): Indent messages two spaces.
+
+2010-12-09 Nathan Froyd <froydnj@codesourcery.com>
+
+ * typeck.c (cp_build_indirect_ref): Call invalid_indirection_error.
+
+2010-12-09 Nathan Froyd <froydnj@codesourcery.com>
+
+ * typeck.c (composite_pointer_error): New function.
+ (composite_pointer_type_r, composite_pointer_type): Call it.
+
+2010-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/46348
+ * semantics.c (cxx_eval_vec_init_1): Handle value-init.
+ (cxx_eval_vec_init): Pass value_init arg.
+
+2010-12-08 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/45329
+ * call.c (struct conversion): Document bad_p field.
+ (enum rejection_reason_code): Define.
+ (struct conversion_info): Define.
+ (struct rejection_reason): Define.
+ (struct z_candidate): Add `reason' field.
+ (add_candidate): Add `reason' parameter. Store it in CAND.
+ (alloc_rejection, arity_rejection, arg_conversion_rejection):
+ New functions.
+ (bad_arg_conversion_rejection): New function.
+ (convert_class_to_reference): Add comment.
+ (remaining_arguments): New function.
+ (add_function_candidate): Record rejection reason and pass it to
+ add_candidate.
+ (add_conv_candidate, build_builtin_candidate): Likewise.
+ (add_template_candidate_real): Likewise.
+ (print_conversion_rejection): New function.
+ (print_z_candidate): Print CAND->REASON if it exists. Adjust
+ diagnostic strings.
+ (print_z_candidates): Add location_t argument. Adjust calling
+ sequence for print_z_candidate. Print header line directly.
+ (build_user_type_conversion_1): Add reason for rejection to
+ CAND. Adjust call to print_z_candidates.
+ (print_error_for_call_failure): New function.
+ (build_new_function_call): Call it. Adjust call to
+ print_z_candidates.
+ (build_operator_new_call): Likewise.
+ (build_op_call): Likewise.
+ (build_conditional_expr): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+
+2010-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/45822
+ * cp-tree.h (LOOKUP_DEFAULTED): New.
+ * call.c (add_function_candidate): Check it.
+ * method.c (synthesized_method_walk): Set it.
+ (do_build_copy_assign): Likewise.
+ * init.c (perform_member_init): Likewise.
+ (emit_mem_initializers): Likewise.
+
+ PR c++/46736
+ * decl.c (cp_finish_decl): Complain about an implicitly deleted
+ method defaulted outside the class.
+ * method.c (maybe_explain_implicit_delete): Don't check DECL_INITIAL.
+
+2010-12-07 Joseph Myers <joseph@codesourcery.com>
+
+ * rtti.c: Don't include assert.h.
+
+2010-12-07 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/45330
+ * cp-tree.h (suggest_alternatives_for, location_of): Declare.
+ * error.c (dump_expr): Handle TYPE_DECL.
+ (location_of): Unstaticize.
+ * name-lookup.c (suggest_alternatives_for): New function.
+ * lex.c (unqualified_name_lookup_error): Call it.
+
+2010-12-06 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * call.c: Include c-family/c-objc.h.
+ * decl.c: Same change.
+ * decl2.c: Same change.
+ * error.c: Same change.
+ * lex.c: Same change.
+ * parser.c: Same change.
+ * pt.c: Same change.
+ * semantics.c: Same change.
+ * typeck.c: Same change.
+ * Make-lang.in (cp/decl.o): Depend on c-family/c-objc.h.
+ (cp/decl2.o): Same change.
+ (cp/call.o): Same change.
+ (cp/error.o): Same change.
+ (cp/lex.o): Same change.
+ (cp/parser.o): Same change.
+ (cp/pt.o): Same change.
+ (cp/semantics.o): Same change.
+ (cp/typeck.o): Same change.
+ * config-lang.in (gtfiles): Added c-family/c-objc.h.
+
+2010-12-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/46645
+ * semantics.c (build_data_member_initialization): Remove assert.
+
+ PR c++/46058
+ * tree.c (lvalue_kind) [SCOPE_REF]: Handle non-dependent case.
+
+2010-12-03 Richard Guenther <rguenther@suse.de>
+
+ PR c/46745
+ * error.c (dump_expr): Handle MEM_REF.
+
+2010-12-03 Laurynas Biveinis <laurynas.biveinis@gmail.com>
+
+ * cp-tree.h (struct aggr_init_expr_arg_iterator_d): Remove GTY
+ tag.
+
+2010-12-02 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_throw_statement): Use
+ cp_parser_expression, not cp_parser_assignment_expression, to
+ parse the argument of a @throw.
+
+2010-12-01 Joseph Myers <joseph@codesourcery.com>
+
+ * cp-objcp-common.c, lex.c, typeck.c: Don't include toplev.h.
+ * Make-lang.in (cp/lex.o, cp/cp-objcp-common.o, cp/typeck2.o):
+ Update dependencies.
+
+2010-11-30 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * decl.c (finish_function): Call objc_finish_function when
+ compiling Objective-C++.
+ * call.c (standard_conversion): Do not call
+ objc_non_volatilized_type().
+ (implicit_conversion): Same change.
+ * typeck.c (comp_ptr_ttypes_real): Same change.
+
+2010-11-30 Joseph Myers <joseph@codesourcery.com>
+
+ * cp-gimplify.c, cp-lang.c, cvt.c, cxx-pretty-print.c, error.c,
+ except.c, expr.c, friend.c, init.c, mangle.c, name-lookup.c,
+ optimize.c, parser.c, rtti.c, tree.c, typeck2.c: Don't include
+ toplev.h.
+ * Make-lang.in: Dependencies for above files changed to remove
+ toplev.h.
+
+2010-11-29 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42260
+ * call.c (add_builtin_candidate): At this point the resulting type
+ of an indirection operator should be complete.
+
+2010-11-29 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/45383
+ Reverted patch for PR c++/42260
+ * cp-tree.h (lookup_conversions): Reverted "Add new bool parameter to
+ declarationE."
+ * search.c (lookup_conversion): Reverted "Use new bool parameter in
+ definition".
+ * call.c (add_builtin_candidates): Reverted "Don't lookup template
+ conversion"
+ (convert_class_to_reference, build_user_type_conversion_1,
+ build_op_call): Reverted "Adjust".
+ * cvt.c (build_expr_type_conversion): Reverted "Likewise".
+
+2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_try_catch_finally_statement): Parse
+ @catch(...) and pass NULL_TREE to objc_begin_catch_clause() in
+ that case. Improved error recovery. Reorganized code to be
+ almost identical to c_parser_objc_try_catch_finally_statement.
+
+2010-11-27 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ PR objc++/46222
+ * decl.c (grokdeclarator): Replaced an assert (for a case that can
+ never happen in C++, but could happen in ObjC++ for invalid code)
+ with a check that prints an error message and returns
+ error_mark_node.
+
+2010-11-23 Jeffrey Yasskin <jyasskin@google.com>
+
+ PR c++/46527
+ * pt.c (instantiate_decl): Propagate the template's location to
+ its instance.
+
+2010-11-20 Joseph Myers <joseph@codesourcery.com>
+
+ * name-lookup.c (handle_namespace_attrs): Don't check
+ HANDLE_PRAGMA_VISIBILITY.
+ * parser.c (cp_parser_namespace_definition): Don't check
+ HANDLE_PRAGMA_VISIBILITY.
+
+2010-11-20 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/16189
+ PR c++/36888
+ PR c++/45331
+ * parser.c (cp_lexer_set_token_position): New function.
+ (cp_lexer_previous_token_position): New function.
+ (cp_lexer_previous_token): Call it.
+ (cp_parser_class_specifier): Try to gracefully handle a missing
+ semicolon.
+
+2010-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/46538
+ * decl.c (cp_make_fname_decl): Return error_mark_node if
+ current_binding_level has already sk_function_parms kind.
+
+ PR c++/46526
+ * semantics.c (cxx_eval_call_expression): Unshare the result.
+
+2010-11-19 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_protocol_declaration): Pass attributes
+ to objc_declare_protocols.
+
+2010-11-18 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c/33193
+ * typeck.c (cp_build_unary_op): Call build_real_imag_expr for
+ REALPART_EXPR and IMAGPART_EXPR.
+
+2010-11-16 Jason Merrill <jason@redhat.com>
+
+ * call.c (convert_like_real): Don't make a temp for copy-list-init.
+ (build_over_call): Don't handle that here.
+ (build_new_method_call): Use COMPLETE_OR_OPEN_TYPE_P for error.
+
+ PR c++/46497
+ * call.c (build_over_call): Check for =delete even when trivial.
+
+ DR 1004
+ * decl.c (make_unbound_class_template): Handle using
+ injected-type-name as template.
+
+2010-11-15 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * typeck.c (cp_build_unary_op): Use
+ objc_build_incr_expr_for_property_ref to build the pre/post
+ increment/decrement of an Objective-C property ref.
+
+2010-11-13 Jason Merrill <jason@redhat.com>
+
+ * decl.c (cp_finish_decl): Use resolve_nondeduced_context for auto.
+ * init.c (build_new): Likewise.
+ * pt.c (tsubst_decl): Likewise.
+ (do_auto_deduction): Likewise.
+ (resolve_nondeduced_context): Use build_offset_ref and
+ cp_build_addr_expr.
+
+2010-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * Make-lang.in (g++spec.o): Use $(OPTS_H).
+
+2010-11-13 Ville Voutilainen <ville.voutilainen@gmail.com> <ville.voutilainen@symbio.com>
+
+ Core 1135, 1136, 1145, 1149
+ * method.c (defaultable_fn_check): Do not disallow defaulting a
+ non-public or explicit special member function on its first
+ declaration.
+
+2010-11-12 James Dennett <jdennett@google.com>
+
+ PR/39415
+ * typeck.c (build_static_cast_1): Convert to the target type
+ when doing static_cast<cv Derived*>(Base*).
+
+2010-11-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/46420
+ * pt.c (tsubst_copy_and_build) [TARGET_EXPR]: New case.
+ [CONSTRUCTOR]: Use the tsubsted type.
+
+ PR c++/46369
+ * semantics.c (cxx_eval_bit_field_ref): New.
+ (cxx_eval_constant_expression): Call it.
+
+2010-11-10 Joseph Myers <joseph@codesourcery.com>
+
+ * cvt.c (cp_convert_to_pointer): Use %' in diagnostic.
+ * decl.c (layout_var_decl, maybe_commonize_var, grokdeclarator):
+ Use %' in diagnostics.
+ * decl2.c (check_classfn): Use %' in diagnostic.
+ * init.c (build_java_class_ref): Use %' in diagnostic.
+ (build_delete): Remove trailing '.' from diagnostic.
+ * method.c (do_build_copy_assign, walk_field_subobs): Use %' in
+ diagnostics.
+ * name-lookup.c (pushdecl_maybe_friend): Use %' in diagnostic.
+ * parser.c (cp_parser_exception_specification_opt): Remove
+ trailing '.' from diagnostic.
+ (cp_parser_objc_interstitial_code): Use %qs for quoting in
+ diagnostic.
+ * pt.c (check_valid_ptrmem_cst_expr): Use %< and %> for quoting in
+ diagnostic.
+ * repo.c (reopen_repo_file_for_write): Use %' in diagnostic.
+
+2010-11-10 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/46065
+ * decl.c (poplevel_named_label_1): Use TREE_CHAIN if necessary.
+
+2010-11-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/45894
+ * tree.c (lvalue_kind): Don't crash if ref has NULL type.
+
+2010-11-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/46382
+ * semantics.c (check_constexpr_ctor_body): New fn.
+ * parser.c (cp_parser_ctor_initializer_opt_and_function_body): Call it.
+ * cp-tree.h: Declare it.
+
+ PR c++/46335
+ * tree.c (bot_manip): Check TREE_SIDE_EFFECTS as well.
+
+ Correct conversion/overflow behavior.
+ * cvt.c (ignore_overflows): Move here from typeck.c.
+ (ocp_convert): Use it.
+ (cp_fold_convert): Use it. Don't call rvalue.
+ * typeck.c (build_static_cast_1): Don't use it. Do call rvalue.
+ * error.c (location_of): Handle expressions, too.
+ * class.c (check_bitfield_decl): Set input_location around call to
+ cxx_constant_value.
+ * semantics.c (cxx_eval_outermost_constant_expr): Don't
+ print the expression if it already had TREE_OVERFLOW set.
+ (reduced_constant_expression_p): Check TREE_OVERFLOW_P for C++98, too.
+ (verify_constant): Allow overflow with a permerror if we're
+ enforcing.
+ (cxx_eval_outermost_constant_expr): Use verify_constant.
+ (adjust_temp_type): Use cp_fold_convert.
+ * decl.c (build_enumerator): Don't call constant_expression_warning.
+ * decl2.c (grokbitfield): Likewise.
+
+2010-11-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/46348
+ * init.c (perform_member_init): Use build_vec_init_expr for
+ value-init of arrays, too.
+ * cp-gimplify.c (cp_gimplify_expr): Use VEC_INIT_EXPR_VALUE_INIT.
+ * cp-tree.h (VEC_INIT_EXPR_IS_CONSTEXPR): New macro.
+ (VEC_INIT_EXPR_VALUE_INIT): New macro.
+ * semantics.c (potential_constant_expression): No longer static.
+ Check VEC_INIT_EXPR_IS_CONSTEXPR.
+ * tree.c (build_vec_init_expr): Handle value-init. Set
+ VEC_INIT_EXPR_IS_CONSTEXPR and VEC_INIT_EXPR_VALUE_INIT.
+
+2010-11-06 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/45332
+ * parser.c (cp_lexer_previous_token): New function.
+ (cp_parser_member_declaration): Use previous token for error
+ messages. Assume semicolon presence rather than grovelling for
+ the next one.
+
+2010-11-06 Joern Rennecke <amylaar@spamcop.net>
+
+ PR middle-end/46314
+ * method.c (make_alias_for_thunk):
+ Use targetm.asm_out.generate_internal_label.
+
+2010-11-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/45473
+ * search.c (look_for_overrides): A constructor is never virtual.
+
+2010-11-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/46160
+ * cp-gimplify.c (cp_gimplify_expr): Drop volatile MEM_REFs
+ on the RHS to avoid infinite recursion with gimplify_expr.
+
+2010-11-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/46304
+ * pt.c (tsubst_copy): Handle COMPLEX_CST.
+
+2010-11-04 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Fixed using the Objective-C 2.0 dot-syntax with class names.
+ * parser.c (cp_parser_primary_expression): Recognize Objective-C
+ 2.0 dot-syntax with class names and process it.
+ (cp_parser_nonclass_name): Recognize Objective-C 2.0 dot-syntax
+ with class names.
+ (cp_parser_class_name): Same change.
+ (cp_parser_simple_type_specifier): Tidied comments.
+
+2010-11-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/46298
+ * semantics.c (build_constexpr_constructor_member_initializers):
+ Handle an enclosing STATEMENT_LIST.
+
+ * semantics.c (speculative_access_check): New.
+ * cp-tree.h: Declare it.
+ * call.c (build_over_call): Use it.
+ * class.c (type_has_constexpr_default_constructor): Use locate_ctor.
+ * method.c (locate_ctor): Use push/pop_deferring_access_checks.
+
+2010-11-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/46293
+ * semantics.c (build_data_member_initialization): Handle
+ value-init of aggregate empty base.
+
+ PR c++/46289
+ * call.c (can_convert_array): New fn.
+ (build_aggr_conv): Use it.
+
+ PR c++/46289
+ * semantics.c (build_constexpr_constructor_member_initializers):
+ Avoid ICE on error.
+
+2010-11-02 Dodji Seketeli <dodji@redhat.com>
+
+ * cp-tree.h (enum tsubst_flags)<tf_no_class_instantiations>:
+ Remove.
+ * pt.c (tsubst): Remove the use of tf_no_class_instantiations.
+
+2010-11-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/46277
+ * init.c (expand_default_init): Avoid ICE if we can't figure out
+ which function is being called.
+
+2010-11-02 Nathan Froyd <froydnj@codesourcery.com>
+
+ * class.c (build_base_path, add_vcall_offset): Use build_zero_cst
+ instead of fold_convert.
+ * init.c (build_zero_init): Likewise.
+ * typeck.c (cp_build_binary_op): Likewise.
+
+2010-11-02 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/46170
+ PR c++/46162
+ * pt.c (check_valid_ptrmem_cst_expr): Add a complain parameter to
+ control diagnostic.
+ (convert_nontype_argument, convert_nontype_argument): Pass the
+ complain parameter down to check_valid_ptrmem_cst_expr.
+
+2010-11-02 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/45606
+ * cp-tree.h (TEMPLATE_TYPE_PARM_SIBLING_PARMS): Remove.
+ (struct template_parm_index_s)<num_siblings>: New field.
+ (TEMPLATE_PARM_NUM_SIBLINGS): New accessor.
+ (process_template_parm): Extend the API to accept the number of
+ template parms in argument.
+ (cp_set_underlying_type): Remove this.
+ * class.c (build_self_reference): Require canonical type equality
+ back on the self reference of class.
+ * decl2.c (grokfield): Require canonical type equality back on
+ typedef class fields.
+ * name-lookup.c (pushdecl_maybe_friend): Require canonical type
+ equality back on typedefs.
+ * parser.c (cp_parser_template_parameter_list): Do not require
+ canonical type equality on dependent types created during template
+ parameters parsing.
+ * pt.c (fixup_template_type_parm_type, fixup_template_parm_index)
+ (fixup_template_parm, fixup_template_parms): New private
+ functions.
+ (current_template_args): Declare this.
+ (process_template_parm): Pass the total number of template parms
+ to canonical_type_parameter.
+ (build_template_parm_index): Add a new argument to carry the total
+ number of template parms.
+ (reduce_template_parm_level, process_template_parm, make_auto):
+ Adjust.
+ (current_template_args): Fix this for template template
+ parameters.
+ (tsubst_template_parm): Split out of ...
+ (tsubst_template_parms): ... this.
+ (reduce_template_parm_level): Don't loose
+ TEMPLATE_PARM_NUM_SIBLINGS when cloning a TEMPLATE_PARM_INDEX.
+ (template_parm_to_arg): Extracted this function from
+ current_template_args. Make it represent invalid template parms
+ with an error_mark_node instead of a LIST_TREE containing an
+ error_mark_node.
+ (current_template_args): Use template_parm_to_arg.
+ (dependent_template_arg_p): Consider an invalid template argument
+ as dependent.
+ (end_template_parm_list): Do not update template sibling parms
+ here anymore. Use fixup_template_parms instead.
+ (process_template_parm): Pass the number of template parms to
+ canonical_type_parameter.
+ (make_auto): Require structural equality on auto
+ TEMPLATE_TYPE_PARM for now.
+ (unify)<BOUND_TEMPLATE_TEMPLATE_PARM>: Coerce template parameters
+ using all the arguments deduced so far.
+ (tsubst)<TEMPLATE_TYPE_PARM>: Pass the number of sibling parms to
+ canonical_type_parameter.
+ * tree.c (cp_set_underlying_type): Remove.
+ * typeck.c (get_template_parms_of_dependent_type)
+ (incompatible_dependent_types_p): Remove.
+ (structural_comptypes): Do not call incompatible_dependent_types_p
+ anymore.
+ (comp_template_parms_position): Re-organized. Take the length of
+ template parms list in account.
+
+2010-11-01 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (call_stack, call_stack_tick, cx_error_context): New.
+ (last_cx_error_tick, push_cx_call_context, pop_cx_call_context): New.
+ (cxx_eval_call_expression): Call push/pop_cx_call_context instead
+ of giving follow-on errors.
+ * error.c (maybe_print_constexpr_context): New.
+ (cp_diagnostic_starter): Call it.
+ * cp-tree.h: Declare cx_error_context.
+
+ * semantics.c (cxx_eval_constant_expression): Explain
+ unacceptable use of variable better.
+
+2010-11-01 Gabriel Dos Reis <gdr@cse.tamu.edu>
+ Jason Merrill <jason@redhat.com>
+
+ * call.c (null_ptr_cst_p): Use maybe_constant_value.
+ (set_up_extended_ref_temp): Support constant initialization.
+ (initialize_reference): Adjust.
+ * class.c (check_bitfield_decl): Use cxx_constant_value.
+ * cvt.c (ocp_convert): Don't use integral_constant_value when
+ converting to class type.
+ * decl.c (finish_case_label): Use maybe_constant_value.
+ (build_init_list_var_init): Support constant initialization.
+ (check_initializer): Likewise. Reorganize.
+ (cp_finish_decl): Likewise.
+ (expand_static_init): Likewise.
+ (compute_array_index_type): Use maybe_constant_value.
+ Add complain parm.
+ (create_array_type_for_decl, grokdeclarator): Pass it.
+ (build_enumerator): Use cxx_constant_value.
+ * decl2.c (grokfield): Use maybe_constant_init.
+ * except.c (check_noexcept_r): Handle constexpr.
+ (build_noexcept_spec): Use maybe_constant_value.
+ * init.c (expand_default_init): Support constant initialization.
+ (build_vec_init): Likewise.
+ (constant_value_1): Adjust.
+ (build_new_1): Adjust.
+ * parser.c (cp_parser_constant_expression): Allow non-integral
+ in C++0x mode.
+ (cp_parser_direct_declarator): Don't fold yet in C++0x mode.
+ (cp_parser_initializer_clause): Toss folded result if non-constant.
+ * pt.c (fold_decl_constant_value): Remove.
+ (convert_nontype_argument): Use maybe_constant_value. Give clearer
+ error about overflow.
+ (tsubst): Move array bounds handling into compute_array_index_type.
+ (value_dependent_expression_p): Handle constant CALL_EXPR.
+ (tsubst_decl): Don't set
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P yet.
+ (tsubst_expr) [DECL_EXPR]: Pass it into cp_finish_decl.
+ (instantiate_decl): Here too.
+ * semantics.c (finish_static_assert): Use maybe_constant_value.
+ (ensure_literal_type_for_constexpr_object): Make sure type is complete.
+ (potential_constant_expression): Use maybe_constant_value.
+ * tree.c (cast_valid_in_integral_constant_expression_p): Any cast
+ is potentially valid in C++0x.
+ * typeck2.c (store_init_value): Handle constant init.
+ (check_narrowing): Use maybe_constant_value.
+ (build_functional_cast): Set TREE_CONSTANT on literal T().
+ * cp-tree.h (DECL_INTEGRAL_CONSTANT_VAR_P): Remove.
+ (LOOKUP_ALREADY_DIGESTED): New.
+ (compute_array_index_type): Adjust prototype.
+
+ * semantics.c (constexpr_call): New datatype.
+ (constexpr_call_table): New global table.
+ (constexpr_call_hash): New.
+ (constexpr_call_equal): Likewise.
+ (maybe_initialize_constexpr_call_table): Likewise.
+ (lookup_parameter_binding): Likewise.
+ (cxx_eval_builtin_function_call): Likewise.
+ (cxx_bind_parameters_in_call): Likewise.
+ (cxx_eval_call_expression): Likewise.
+ (cxx_eval_unary_expression): Likewise.
+ (cxx_eval_binary_expression): Likewise.
+ (cxx_eval_conditional_expression): Likewise.
+ (cxx_eval_array_reference): Likewise.
+ (cxx_eval_component_reference): Likewise.
+ (cxx_eval_logical_expression): Likewise.
+ (cxx_eval_object_construction): Likewise.
+ (cxx_eval_constant_expression): Likewise.
+ (cxx_eval_indirect_ref): Likewise.
+ (cxx_constant_value): Likewise.
+ (cxx_eval_bare_aggregate): Likewise.
+ (adjust_temp_type): New.
+ (reduced_constant_expression_p): New.
+ (verify_constant): New.
+ (cxx_eval_vec_init, cxx_eval_vec_init_1): New.
+ (cxx_eval_outermost_constant_expr): New.
+ (maybe_constant_value, maybe_constant_init): New.
+ (cxx_eval_constant_expression): Use them.
+ * pt.c (iterative_hash_template_arg): No longer static.
+ * cp-tree.h: Declare fns.
+
+ * cp-tree.h (register_constexpr_fundef): Declare.
+ * decl.c (maybe_save_function_definition): New.
+ (finish_function): Use it.
+ * semantics.c (constexpr_fundef): New datatype.
+ (constexpr_fundef_table): New global table.
+ (constexpr_fundef_equal): New.
+ (constexpr_fundef_hash): Likewise.
+ (retrieve_constexpr_fundef): Likewise.
+ (validate_constexpr_fundecl): Store in the table.
+ (build_data_member_initialization): New fn.
+ (build_constexpr_constructor_member_initializers): New.
+ (register_constexpr_fundef): Define.
+ (is_this_parameter): New.
+ (get_function_named_in_call): Likewise.
+ (get_nth_callarg): Likewise.
+ (check_automatic_or_tls): New.
+ (morally_constexpr_builtin_function_p): New.
+ (potential_constant_expression): New.
+
+2010-11-01 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (decl_constant_var_p): New fn.
+ (decl_maybe_constant_var_p): New fn.
+ (mark_used): Rework instantiation of things needed for constant
+ expressions.
+ * cp-tree.h: Declare new fns.
+ * pt.c (instantiate_decl): Handle cp_unevaluated_operand.
+ (always_instantiate_p): Use decl_maybe_constant_var_p.
+ (instantiate_decl): Don't defer constexpr functions.
+ * repo.c (repo_emit_p): Use decl_maybe_constant_var_p.
+ * semantics.c (finish_id_expression): Use decl_constant_var_p.
+ Check for valid name in constant expr after mark_used.
+
+2010-10-31 Jason Merrill <jason@redhat.com>
+
+ * class.c (is_really_empty_class): Work when type is not complete.
+ (synthesized_default_constructor_is_constexpr): New.
+ (add_implicitly_declared_members): Use it.
+ (type_has_constexpr_default_constructor): Likewise.
+ * cp-tree.h: Declare it.
+ * method.c (synthesized_method_walk): Use it.
+
+ * decl.c (pop_switch): Use EXPR_LOC_OR_HERE.
+ * typeck.c (convert_for_assignment): Likewise.
+
+ * parser.c (cp_parser_diagnose_invalid_type_name): Give helpful
+ message about constexpr without -std=c++0x.
+
+ * decl.c (grokdeclarator): Don't ICE on constexpr non-static data
+ member.
+
+2010-10-30 Nathan Froyd <froydnj@codesourcery.com>
+
+ * class.c (layout_vtable_decl): Call build_array_of_n_type.
+ (build_vtt, build_ctor_vtabl_group): Likewise.
+
+2010-10-30 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Implemented Objective-C 2.0 @property, @synthesize and @dynamic.
+ * parser.c (cp_parser_objc_at_property_declaration): Removed
+ parsing of RID_COPIES and RID_IVAR. Updated call to
+ objc_add_property_declaration.
+ * typecheck.c (finish_class_member_access_expr): Call
+ objc_maybe_build_component_ref instead of objc_build_setter_call.
+ (cp_build_modify_expr): Call objc_maybe_build_modify_expr instead
+ of objc_build_getter_call.
+
+2010-10-27 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (cp_trait_kind): Add CPTK_IS_LITERAL_TYPE.
+ * cxx-pretty-print.c (pp_cxx_trait_expression): Handle it.
+ * semantics.c (trait_expr_value, finish_trait_expr): Likewise.
+ * parser.c (cp_parser_primary_expression): Handle RID_IS_LITERAL_TYPE.
+ (cp_parser_trait_expr): Likewise.
+
+2010-10-27 Gabriel Dos Reis <gdr@cse.tamu.edu>
+ Jason Merrill <jason@redhat.com>
+
+ * decl.c (finish_case_label): Use decl_constant_value.
+
+ * method.c (synthesized_method_walk): Track constexprness too.
+ (process_subob_fn, walk_field_subobs): Likewise.
+ (implicitly_declare_fn): Set DECL_DECLARED_CONSTEXPR_P.
+ (defaulted_late_check): Handle DECL_DECLARED_CONSTEXPR_P.
+ * class.c (add_implicitly_declared_members): Handle
+ constexpr default ctor.
+
+ * parser.c (cp_parser_ctor_initializer_opt_and_function_body):
+ Make sure a constexpr ctor has an empty body.
+ * class.c (type_has_constexpr_default_constructor): New.
+ * cp-tree.h: Declare it.
+ * init.c (perform_member_init): Complain about uninitialized
+ member in constexpr ctor.
+ (emit_mem_initializers): And uninitialized base.
+ * decl.c (check_tag_decl): Fix typo.
+
+ * semantics.c (valid_type_in_constexpr_fundecl_p): New fn.
+ (is_valid_constexpr_fn): New fn.
+ (validate_constexpr_fundecl): Use it.
+ * decl.c (validate_constexpr_redeclaration): New.
+ (duplicate_decls): Use it.
+ (cp_finish_decl): Call validate_constexpr_fundecl and
+ ensure_literal_type_for_constexpr_object here.
+ (start_decl): Not here. Don't ICE on constexpr reference.
+ (check_for_uninitialized_const_var): Don't handle constexpr specially.
+ (grokfndecl): Set DECL_DECLARED_CONSTEXPR_P.
+ (check_static_variable_definition): Give friendly message about
+ missing constexpr.
+ (grokdeclarator): Complain about typedef and volatile with constexpr.
+ Reorganize. Give sorry about non-static data members in C++0x mode.
+ (start_preparsed_function): Check validate_constexpr_fundecl here.
+ (check_function_type): Not here.
+ * decl2.c (finish_static_data_member_decl): Don't complain about
+ in-class init.
+ * parser.c (CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR): New.
+ (cp_parser_condition): Pass it to cp_parser_decl_specifier_seq.
+ (cp_parser_decl_specifier_seq): Handle it.
+ (cp_parser_explicit_instantiation): Diagnose inline and constexpr.
+
+ * class.c (check_bases): Propagate non-literality.
+ (check_field_decls): Likewise.
+ (finalize_literal_type_property): New.
+ (check_bases_and_members): Call it.
+ * cp-tree.h (TYPE_HAS_CONSTEXPR_CTOR): New.
+ (lang_type_class): Add has_constexpr_ctor field.
+ (DECL_DECLARED_CONSTEXPR_P): Strip template.
+ * decl.c (grok_special_member_properties): Set
+ TYPE_HAS_CONSTEXPR_CTOR.
+
+2010-10-27 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_integral_nontype_arg_conv): New.
+ * cp-tree.h: Declare it.
+ * pt.c (convert_nontype_argument): Use it.
+
+ * error.c (dump_simple_decl): Print constexpr.
+
+ * cvt.c (build_up_reference): Use target_type for the temporary var.
+
+ * except.c (build_throw): Set EXPR_LOCATION.
+
+ * tree.c (build_cplus_new): Handle CONSTRUCTOR.
+
+ * semantics.c (finish_compound_stmt): Avoid creating an
+ unnecessary BIND_EXPR.
+
+ * call.c (convert_like_real): Don't check narrowing if the element
+ is also an initializer-list.
+
+2010-10-27 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_at_property_declaration): Recognize
+ RID_ASSIGN, RID_COPY, RID_RETAIN, RID_READWRITE and RID_NONATOMIC.
+ Do not use objc_set_property_attr, but use local variables
+ instead. Detect repeated usage of setter, getter and ivar
+ attributes. Improved error processing when a setter name does not
+ end in ':'. Do not check for CPP_CLOSE_PAREN after we determined
+ that the token is a keyword. Updated call to
+ objc_add_property_declaration.
+
+2010-10-27 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_property_decl): Renamed to
+ cp_parser_objc_struct_declaration. Return the parsed trees
+ instead of calling objc_add_property_variable directly. Detect
+ missing or invalid declspecs. Implemented attributes. Do not eat
+ the ';' at the end. Exit loop whenever a non-comma is parsed, not
+ just EOF.
+ (cp_parser_objc_at_property): Renamed to
+ cp_parser_objc_at_property_declaration. Updated calls to
+ objc_add_property_variable, now objc_add_property_declaration, and
+ to cp_parser_objc_property_decl, now
+ cp_parser_objc_struct_declaration. Rewritten all code to be more
+ robust in dealing with syntax errors, and almost identical to the
+ one in c_parser_objc_at_property_declaration.
+ (cp_parser_objc_property_attrlist): Removed.
+ (cp_parser_objc_method_prototype_list): Updated call to
+ cp_parser_objc_at_property.
+ (cp_parser_objc_method_definition_list): Same change.
+ (cp_parser_objc_class_ivars): Detect a number of invalid
+ declarations of instance variables and produce errors when they
+ are found.
+
+2010-10-26 Jason Merrill <jason@redhat.com>
+
+ * tree.c (build_vec_init_expr): Split out from...
+ (build_array_copy): ...here.
+ * init.c (perform_member_init): Use it.
+ * cp-tree.h: Declare it.
+ * cp-gimplify.c (cp_gimplify_init_expr): Don't gimplify the slot for
+ VEC_INIT_EXPR and AGGR_INIT_EXPR here. Drop pre/post parameters.
+ (cp_gimplify_expr): Handle array default-initialization via
+ VEC_INIT_EXPR.
+
+ * tree.c (stabilize_expr): Handle xvalues properly.
+
+ * call.c (build_over_call): Use argarray[0] for 'this' argument.
+
+ * decl.c (finish_function): Don't look at function_depth.
+
+2010-10-25 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+ Implement opaque-enum-specifiers for C++0x.
+ * cp-tree.h (SET_OPAQUE_ENUM_P): New.
+ (OPAQUE_ENUM_P): New.
+ (ENUM_FIXED_UNDERLYING_TYPE_P): New.
+ (start_enum): Update prototype.
+ (finish_enum_value_list): New prototype.
+ * parser.c (cp_parser_elaborated_type_specifier): Issue a pedwarn if
+ "enum class" is used in an elaborated-type-specifier.
+ (cp_parser_enum_specifier): Rewrite to parse opaque-enum-specifiers.
+ * decl.c (copy_type_enum): New.
+ (finish_enum_value_list): New, with code from finish_enum.
+ (finish_enum): A lot of code removed. Added a gcc_assert.
+ (start_enum): Add parameters enumtype and is_new.
+ Rewrite to work with opaque-enum-specifiers.
+ * pt.c (maybe_process_partial_specialization): Allow for template
+ specialization of enumerations, with a pedwarn.
+ (lookup_template_class): Update call to start_enum. Call to
+ SET_OPAQUE_ENUM_P.
+ (tsubst_enum): Call to begin_scope, finish_scope and
+ finish_enum_value_list.
+
+2010-10-24 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Removed Objective-C++ specific replacement of cxx_printable_name.
+ * cp-objcp-common.h: Added LANG_HOOKS_DECL_PRINTABLE_NAME, set
+ to cxx_printable_name for both C++ and Objective-C++.
+ * cp-lang.h: Removed LANG_HOOKS_DECL_PRINTABLE_NAME.
+
+ * error.c (dump_decl): For Objective-C++, call
+ objc_maybe_printable_name here ...
+ * tree.c (cxx_printable_name_internal): ... instead of here.
+
+2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * tree.c (cxx_printable_name_internal): In Objective-C++, call
+ objc_maybe_printable_name.
+
+2010-10-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/46129
+ * pt.c (instantiate_class_template): Don't instantiate default
+ arguments.
+
+ PR c++/46103
+ * init.c (build_vec_init): Handle memberwise move.
+
+2010-10-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/46117
+ * call.c (add_function_candidate): Don't use TREE_VALUE on null
+ parmnode.
+
+2010-10-20 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_method_type): Mark inline. Return a
+ bool instead of calling objc_set_method_type.
+ (cp_parser_objc_method_signature): Updated calls to
+ cp_parser_objc_method_type and to objc_build_method_signature.
+ (cp_parser_objc_method_prototype_list): Updated calls to
+ objc_add_method_declaration. Use token->type to determine if it
+ is a class method or not.
+ (cp_parser_objc_method_definition_list): Same change.
+
+2010-10-20 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+ PR c++/46056
+ * parser.c (cp_convert_range_for): Call cp_finish_decl
+ instead of finish_expr_stmt.
+
+2010-10-20 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * cp-lang.c (finish_file): Removed.
+ * decl2.c (cp_write_global_declarations): Call
+ objc_write_global_declarations when compiling Objective-C++.
+
+2010-10-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/46046
+ * pt.c (add_to_template_args): Check extra_args for error_mark_node.
+ (coerce_template_parms): Likewise for args.
+
+2010-10-18 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Implemented parsing @synthesize and @dynamic for Objective-C++.
+ * parser.c (cp_parser_objc_method_definition_list): Recognize
+ RID_AT_SYNTHESIZE and RID_AT_DYNAMIC.
+ (cp_parser_objc_at_dynamic_declaration): New.
+ (cp_parser_objc_at_synthesize_declaration): New.
+
+2010-10-18 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_identifier_list): Check the return
+ value of cp_parser_identifier and react if it is error_mark_node.
+
+2010-10-18 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Merge from apple/trunk branch on FSF servers.
+
+ 2005-03-01 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4451818
+ * call.c (standard_conversion, implicit_conversion): Ignore
+ 'volatile' attribute of artificially volatized type in objc when
+ evaluating various conversion weights.
+
+ 2005-11-08 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4330422
+ * typeck.c (comp_ptr_ttypes_real): Remove the hack. un-volatize the
+ artiificially 'volatized' type before doing pointer comparison.
+
+2010-10-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/46015
+ * semantics.c (finish_goto_stmt): Call mark_rvalue_use on computed
+ goto destination.
+
+2010-10-17 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Merge from apple/trunk branch on FSF servers.
+
+ 2006-04-19 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4516785
+ * parser.c (cp_parser_simple_type_specifier): Don't lookup for
+ objc object types if type is scope qualified.
+
+2010-10-17 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Merge from apple/trunk branch on FSF servers.
+
+ 2006-03-27 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4133425
+ * lex.c (unqualified_name_lookup_error): Issue diagnostic
+ for private 'ivar' access.
+
+2010-10-17 Iain Sandoe <iains@gcc.gnu.org>
+
+ * parser.c (cp_parser_objc_visibility_spec): Update to use visibility
+ enum, and handle @package.
+
+2010-10-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/45983
+ * tree.c (cp_build_qualified_type_real): Don't reuse a variant
+ with a different typedef variant of the element type.
+
+2010-10-14 Iain Sandoe <iains@gcc.gnu.org>
+
+ merge from FSF apple 'trunk' branch.
+ 2006 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radars 4436866, 4505126, 4506903, 4517826
+ * typeck.c (finish_class_member_access_expr): Handle CLASS.property
+ syntax.
+ (cp_build_modify_expr): Likewise.
+ * parser.c (cp_parser_objc_method_prototype_list): Handle @property.
+ (cp_parser_objc_method_definition_list): Likewise.
+ (cp_parser_objc_property_decl): New.
+ (cp_parser_objc_property_attrlist): New.
+ (cp_parser_objc_at_property): New.
+
+2010-10-14 Richard Guenther <rguenther@suse.de>
+
+ PR lto/44561
+ * cp-tree.h (NULLPTR_TYPE_P): Adjust.
+ * decl.c (cxx_init_decl_processing): Build a NULLPTR_TYPE node,
+ use build_int_cst.
+ * error.c (dump_type): Handle NULLPTR_TYPE.
+ (dump_type_prefix): Likewise.
+ (dump_type_suffix): Likewise.
+ * mangle.c (write_type): Likewise.
+ * name-lookup.c (arg_assoc_type): Likewise.
+ * rtti.c (typeinfo_in_lib_p): Likewise.
+ * pt.c (tsubst): Likewise.
+
+2010-10-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/45984
+ * class.c (fixup_attribute_variants): New fn.
+ * cp-tree.h: Declare it.
+ * pt.c (instantiate_class_template): Call it.
+ * semantics.c (begin_class_definition): Call it.
+
+2010-10-13 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c (cp_eh_personality): Update call to
+ build_personality_function.
+ * except.c (choose_personality_routine): Update function comment.
+
+2010-10-13 Richard Guenther <rguenther@suse.de>
+
+ * tree.c (cp_free_lang_data): Free DECL_NAMESPACE_USERS and
+ clear DECL_CHAIN of NAMESPACE_DECLs.
+
+2010-10-11 Martin Jambor <mjambor@suse.cz>
+
+ PR c++/45562
+ * cp-tree.h (current_class_ref): Check that cp_function_chain is
+ non-NULL.
+ * call.c (build_cxx_call): Likewise.
+
+2010-10-10 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_default_argument): Handle DEFAULT_ARG.
+ (tsubst_default_arguments): Only do this once for cloned fns.
+ (tsubst): Use typedef_variant_p. Handle LANG_TYPE. Don't
+ handle expressions.
+ (tsubst_expr): Avoid calling tsubst_expr for non-expressions.
+ (tsubst_copy_and_build): Likewise.
+ (tsubst_initializer_list): Likewise.
+ (tsubst_copy): Change default to gcc_unreachable. Handle
+ OVERLOAD and PTRMEM_CST.
+
+2010-10-10 Jason Merrill <jason@redhat.com>
+
+ PR lto/45959
+ PR lto/45960
+ * pt.c (tsubst_copy) [INTEGER_CST]: Instantiate the type.
+
+2010-10-07 Andi Kleen <ak@linux.intel.com>
+
+ * Make-lang.in (c++_OBJS): Remove dummy-checksum.o.
+ (cc1plus-dummy): Remove.
+ (cc1plus-checksum): Change to run checksum over object files
+ and options only.
+
+2010-10-08 Joseph Myers <joseph@codesourcery.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_INIT_OPTIONS_STRUCT): Define.
+
+2010-10-07 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * cp-tree.def: Changed type of AT_ENCODE_EXPR from tcc_unary to
+ tcc_expression.
+ * cxx-pretty-print.c (pp_cxx_unary_expression): Added case for
+ AT_ENCODE_EXPR.
+ * error.c (dump_expr): Added case for AT_ENCODE_EXPR.
+ * pt.c (tsubst_copy): Added case for AT_ENCODE_EXPR.
+ (value_dependent_expression_p): Added case for AT_ENCODE_EXPR.
+ (type_dependent_expression_p): Added case for AT_ENCODE_EXPR.
+ * parser.c (cp_parser_objc_encode_expression): Updated comment.
+
+2010-10-07 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Merge from apple/trunk branch on FSF servers.
+
+ 2006-04-26 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4508851
+ * parser.c (cp_parser_objc_interstitial_code): Recognize
+ and parse RID_NAMESPACE keyword.
+
+2010-10-07 Iain Sandoe <iains@gcc.gnu.org>
+
+ * parser.c (cp_parser_objc_method_tail_params_opt): Peek new token after
+ finding ellipsis, before checking for attributes.
+
+2010-10-06 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Merge from apple/trunk branch on FSF servers.
+ * cp-tree.def: Added AT_ENCODE_EXPR here instead of to the no
+ longer existing gcc/c-common.def.
+
+ 2005-12-14 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4278774
+ * pt.c (tsubst_copy_and_build): Instantiate @endcode(T).
+ * parser.c (cp_parser_objc_encode_expression): Build a templatized
+ parse tree for @encode(T).
+
+ 2005-12-14 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4278774
+ * c-common.def: Add new expression code AT_ENCODE_EXPR.
+
+2010-10-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR c++/45908
+ * typeck.c (cp_build_addr_expr_1): Add check for incomplete types in
+ code folding offsetof-like computations.
+
+2010-10-05 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ PR objc++/31125
+ * parser.c (cp_parser_objc_class_interface): If no identifier
+ follows an @interface token, stop parsing the interface after
+ printing an error.
+ (cp_parser_objc_class_implementation): If no identifier follows an
+ @implementation token, stop parsing the implementation after
+ printing an error.
+
+2010-10-05 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ PR objc++/23707
+ * parser.c (cp_parser_objc_method_keyword_params): If the required
+ colon is not found while parsing parameters, stop parsing them.
+
+2010-10-05 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ PR objc++/31126
+ * parser.c (cp_parser_objc_class_ivars): Do not eat the EOF or
+ @end after detecting it. Print an error if @end is found without
+ a '}'.
+ (cp_parser_objc_method_prototype_list): Do not eat the EOF after
+ detecting it. Fixed reading the next token when continuing
+ because of an error in a method signature. Print an error if EOF
+ is found without an '@end'.
+ (cp_parser_objc_method_definition_list): Same change.
+
+2010-10-05 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Merge from apple/trunk branch on FSF servers:
+
+ 2005-10-17 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4290840
+ * parser.c (cp_parser_objc_method_keyword_params): Check for valid
+ method parameters and issue error.
+ (cp_parser_objc_method_definition_list): Check for invalid tokens
+ which cannot start a function definition.
+
+ 2005-10-14 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4294425
+ * parser.c (cp_parser_objc_message_args): Check for missing message
+ arguments and syntax error.
+
+ 2005-10-13 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4261146
+ * parser.c (cp_parser_objc_class_ivars): Check for @end/eof while
+ looking for '}'.
+
+ 2005-08-15 Ziemowit Laski <zlaski@apple.com>
+
+ Radar 4093475
+ * parser.c (cp_parser_objc_interstitial_code): Catch stray
+ '{' and '}' tokens and issue appropriate errors.
+
+ 2005-08-02 Ziemowit Laski <zlaski@apple.com>
+
+ Radar 4185810
+ (cp_parser_statement_seq_opt): In addition to '}' and
+ end-of-file, a statement sequence may also be terminated
+ by a stray '@end'.
+
+2010-10-05 Joseph Myers <joseph@codesourcery.com>
+
+ * cp-tree.h (cxx_print_error_function,
+ cxx_initialize_diagnostics): Declare using diagnostic_context
+ typedef.
+
+2010-10-04 Andi Kleen <ak@linux.intel.com>
+
+ * Make-lang.in (g++, cc1plus): Add + to build rule.
+
+2010-10-04 Jason Merrill <jason@redhat.com>
+
+ * tree.c (decl_storage_duration): New.
+ * cp-tree.h: Declare it.
+ (duration_kind): Return values.
+
+2010-10-03 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (require_complete_type_sfinae): Add complain parm to...
+ (require_complete_type): ...this function.
+ (cp_build_array_ref, convert_arguments): Use it.
+ (convert_for_initialization, cp_build_modify_expr): Likewise.
+ * cp-tree.h: Declare it.
+ * call.c (build_over_call): Use it.
+
+2010-09-30 Iain Sandoe <iains@gcc.gnu.org>
+
+ merge from FSF 'apple/trunk' branch.
+ 2006-01-30 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4386773
+ * cp/parser.c (cp_parser_objc_interstitial_code): For
+ @optional/@required set the optional/required flag.
+
+2010-09-30 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_lexer_get_preprocessor_token): Tidied up comments
+ and indentation when finding an Objective-C++ CPP_AT_NAME token.
+
+2010-09-29 Richard Guenther <rguenther@suse.de>
+
+ * cp-tree.h (CP_DECL_CONTEXT): Check DECL_FILE_SCOPE_P.
+ (CP_TYPE_CONTEXT): Similar.
+ (FROB_CONTEXT): Frob global_namespace to the global
+ TRANSLATION_UNIT_DECL.
+ * decl.c (cxx_init_decl_processing): Build a TRANSLATION_UNIT_DECL,
+ set DECL_CONTEXT of global_namespace to it.
+ (start_decl): Use CP_DECL_CONTEXT and test TYPE_P
+ instead of zeroing context.
+ (cp_finish_decl): Use DECL_FILE_SCOPE_P.
+ (grokfndecl): Likewise.
+ (start_preparsed_function): Likewise.
+ * name-lookup.c (maybe_push_decl): Use DECL_NAMESPACE_SCOPE_P.
+ (namespace_binding): Use SCOPE_FILE_SCOPE_P.
+ * pt.c (template_class_depth): Use CP_TYPE_CONTEXT.
+ (is_specialization_of_friend): Use CP_DECL_CONTEXT.
+ (push_template_decl_real): Likewise.
+ (tsubst_friend_class): Likewise. Adjust context comparisons.
+ (instantiate_class_template): Use CP_TYPE_CONTEXT.
+ (tsubst): Do not substitute into TRANSLATION_UNIT_DECL.
+ * cxx-pretty-print.c (pp_cxx_nested_name_specifier): Use
+ SCOPE_FILE_SCOPE_P.
+
+2010-09-29 Yao Qi <yao@codesourcery.com>
+
+ * decl.c (get_atexit_node): Fix typo.
+
+2010-09-28 Jason Merrill <jason@redhat.com>
+
+ * tree.c (lvalue_kind): Rename from lvalue_p_1, make nonstatic.
+ (real_lvalue_p): Take const_tree.
+ * cp-tree.h: Adjust.
+ * typeck.c (lvalue_or_else): Make temporary arg a permerror.
+ (cp_build_addr_expr_1): Likewise.
+
+2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
+
+ Partially merged from apple/trunk branch on FSF servers:
+ 2006-04-26 Fariborz Jahanian <fjahanian@apple.com>
+ Radar 3803157 (method attributes)
+
+ * parser.c (cp_parser_objc_method_keyword_params): Handle attributes.
+ (cp_parser_objc_method_tail_params_opt): Likewise.
+ (cp_parser_objc_method_signature): Likewise.
+ (cp_parser_objc_method_maybe_bad_prefix_attributes): New.
+ (cp_parser_objc_method_prototype_list): Handle attributes.
+ (cp_parser_objc_method_definition_list): Likewise.
+
+2010-09-28 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c: Include "target.h".
+ (cp_eh_personality): Use targetm.except_unwind_info.
+ * Make-lang.in (cp-lang.o): Update deps.
+
+2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
+
+ * parser.c (cp_parser_objc_valid_prefix_attributes): New.
+ (cp_parser_declaration): Parse prefix attributes for ObjC++.
+ (cp_parser_objc_protocol_declaration): Handle attributes.
+ (cp_parser_objc_class_interface): Likewise.
+ (cp_parser_objc_declaration): Likewise.
+
+2010-09-27 Jason Merrill <jason@redhat.com>
+
+ Require lvalues as specified by the standard.
+ * typeck.c (lvalue_or_else): Use real_lvalue_p.
+ (cp_build_addr_expr_1): Split out of cp_build_unary_op.
+ (cp_build_addr_expr, cp_build_addr_expr_strict): Interfaces.
+ (decay_conversion, get_member_function_from_ptrfunc): Adjust.
+ (build_x_unary_op, build_reinterpret_cast_1): Adjust.
+ (build_const_cast_1): Adjust.
+ * cp-tree.h: Declare new fns.
+ * call.c (build_this, convert_like_real, build_over_call): Adjust.
+ (initialize_reference): Adjust.
+ * class.c (build_base_path, convert_to_base_statically): Adjust.
+ (build_vfn_ref, resolve_address_of_overloaded_function): Adjust.
+ * cvt.c (build_up_reference, convert_to_reference): Adjust.
+ * decl.c (register_dtor_fn): Adjust.
+ * decl2.c (build_offset_ref_call_from_tree): Adjust.
+ * except.c (initialize_handler_parm): Adjust.
+ * init.c (build_offset_ref, build_delete, build_vec_delete): Adjust.
+ * rtti.c (build_dynamic_cast_1, tinfo_base_init): Adjust.
+ * tree.c (stabilize_expr): Adjust.
+
+2010-09-27 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Merge from apple/trunk branch on FSF servers:
+
+ 2005-12-15 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4229905
+ * typeck.c (composite_pointer_type): Call objc_have_common_type
+ when comparing two objective-c pointer types.
+
+ 2005-07-18 Ziemowit Laski <zlaski@apple.com>
+
+ Radar 4175534
+ * call.c (standard_conversion): Do not issue warnings when
+ comparing ObjC pointer types.
+
+ 2005-06-22 Ziemowit Laski <zlaski@apple.com>
+
+ Radar 4154928
+ * call.c (standard_conversion): Allow for a pointer conversion
+ between any two ObjC pointer types.
+ * typeck.c (composite_pointer_type): Determine common type
+ for two ObjC pointer types.
+
+2010-09-24 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (finish_function): Use decl_replaceable_p
+ * method.c (make_alias_for_thunk): Update call of
+ cgraph_same_body_alias.
+
+2010-09-24 Jason Merrill <jason@redhat.com>
+
+ * decl.c (compute_array_index_type): Remember type dependence of
+ array bound.
+ * pt.c (dependent_type_p_r): Don't recompute it here.
+
+ * error.c (dump_expr) [CASE_CONVERT]: Print conversion between
+ reference and pointer to the same type as "*" or "&".
+
+2010-09-24 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * typeck.c (warn_args_num): Use warning 'too many arguments to
+ method [methodname]' for an Objective-C method instead of the less
+ satisfactory 'too many arguments to function' (with no method
+ name).
+
+2010-09-21 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_expression) [SCOPE_REF]: Only do -fabi-version=1
+ special handling if we know the member.
+
+2010-09-18 Jason Merrill <jason@redhat.com>
+
+ * call.c (compare_ics): Do lvalue/rvalue reference binding
+ comparison for ck_list, too.
+
+2010-09-15 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (finish_id_expression): Diagnose use of function
+ parms in evaluated context outside function body.
+
+ * decl2.c (grokbitfield): Diagnose non-integral width.
+
+ * call.c (convert_like_real): Use the underlying type of the
+ reference for the temporary.
+
+2010-09-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/45635
+ * class.c (build_vtbl_initializer): Use fn instead of init's operand
+ as first argument to FDESC_EXPR.
+
+2010-09-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/45665
+ * decl.c (grokdeclarator): Check build_memfn_type return value
+ for error_mark_node.
+
+2010-09-13 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+ * semantics.c (finish_for_stmt): Always test flag_new_for_scope.
+ (begin_range_for_stmt): Likewise.
+
+2010-09-11 Rodrigo Rivas <rodrigorivascosta@gmail.com>
+
+ Implement range-based for-statements.
+ * cp-tree.def (RANGE_FOR_STMT): New.
+ * cp-tree.h (RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY): New.
+ (cp_convert_range_for): Declare.
+ * pt.c (tsubst_expr): Add RANGE_FOR_STMT.
+ (tsubst_copy_and_build): perform_koenig_lookup takes extra argument.
+ * semantics.c (begin_range_for_stmt): New.
+ (finish_range_for_decl): New.
+ (finish_for_stmt): Accept also RANGE_FOR_STMT.
+ (perform_koenig_lookup): Add extra argument include_std.
+ * parser.c (cp_parser_c_for): New with code from
+ cp_parser_iteration_statement().
+ (cp_parser_range_for): New.
+ (cp_convert_range_for): New.
+ (cp_parser_iteration_statement): Add range-for support.
+ (cp_parser_condition): Adjust comment.
+ (cp_parser_postfix_expression): perform_koenig_lookup takes extra
+ argument.
+ * dump.c (cp_dump_tree): Add RANGE_FOR_STMT.
+ * cxx-pretty-print.c: Likewise.
+ * lex.c (cxx_init): Likewise.
+ * name-lookup.c (lookup_function_nonclass): Add extra argument
+ include_std.
+ (lookup_arg_dependent): Likewise.
+ * name-lookup.h: Likewise.
+
+2010-09-10 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+ PR c++/43824
+ * error.c (maybe_warn_cpp0x): Add new warning
+ CPP0X_INLINE_NAMESPACES.
+ * parser.c (cp_parser_namespace_definition): Likewise.
+ * cp-tree.h (cpp0x_warn_str): Likewise.
+
+2010-09-10 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (reshape_init_vector): For VECTOR_TYPEs, use
+ TYPE_VECTOR_SUBPARTS instead of TYPE_DEBUG_REPRESENTATION_TYPE.
+
+2010-09-10 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/45605
+ * cp/class.c (build_vtbl_initializer): Avoid wrong type conversion in
+ ADDR_EXPR.
+
+2010-09-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/45588
+ * pt.c (tsubst) <case INTEGER_TYPE>: Call mark_rvalue_use
+ before calling fold_decl_constant_value.
+
+2010-09-07 Arnaud Charlet <charlet@adacore.com>
+
+ * cp-tree.h (build_enumerator): Add new location_t parameter.
+ (build_lang_decl_loc): New function.
+ * decl.c (build_enumerator): New parameter loc. Use it when calling
+ build_decl. Replace build_lang_decl with build_lang_decl_loc.
+ * pt.c (tsubst_enum): Adjust call to build_enumerator.
+ * parser.c (cp_parser_enumerator_definition): Ditto.
+ * lex.c (build_lang_decl_loc): New function.
+
+2010-09-06 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/45200
+ PR c++/45293
+ PR c++/45558
+ * tree.c (strip_typedefs): Strip typedefs from the context of
+ TYPENAME_TYPEs.
+
+2010-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (cp_build_binary_op): Call do_warn_double_promotion.
+ * call.c (build_conditional_expr): Likewise.
+ (convert_arg_to_ellipsis): Likewise.
+
+2010-09-06 Arnaud Charlet <charlet@adacore.com>
+
+ * parser.c (make_pointer_declarator, make_reference_declarator,
+ make_call_declarator, make_array_declarator): Set declarator->id_loc.
+ (cp_parser_init_declarator): Adjust location of decl if appropriate.
+
+2010-09-06 Jason Merrill <jason@redhat.com>
+
+ * call.c (implicit_conversion): Fix value-init of enums.
+ (convert_like_real): Likewise.
+
+ * decl.c (cp_finish_decl): Don't change init for auto deduction.
+
+ * pt.c (fold_non_dependent_expr_sfinae): Split out from...
+ (fold_non_dependent_expr): ...here.
+ (convert_nontype_argument): Use it. Take complain parm.
+ Use perform_implicit_conversion instead of ocp_convert.
+ Allow cv-qual changes.
+ (convert_template_argument): Pass complain down.
+ (tsubst_template_arg): Suppress constant expression warnings.
+ Don't fold here.
+
+ * method.c (synthesized_method_walk): In constructors, also check
+ subobject destructors.
+
+ * semantics.c (finish_compound_literal): Always build a
+ TARGET_EXPR.
+
+2010-08-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/45043
+ * decl.c (grokdeclarator): Use MAIN_NAME_P only on IDENTIFIER_NODEs.
+
+2010-08-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/45423
+ * parser.c (cp_parser_omp_atomic): Handle boolean
+ {PRE,POST}_INCREMENT.
+
+2010-08-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/44991
+ * parser.c (cp_parser_parameter_declaration): Pop parameter decls
+ after tentative parsing.
+
+2010-08-22 Joseph Myers <joseph@codesourcery.com>
+
+ * Make-lang.in (g++spec.o): Update dependencies.
+ * g++spec.c: Include opts.h
+ (MATH_LIBRARY, LIBSTDCXX): Remove initial "-l".
+ (lang_specific_driver): Use cl_decoded_option structures.
+
+2010-08-20 Nathan Froyd <froydnj@codesourcery.com>
+
+ * call.c: Use FOR_EACH_VEC_ELT.
+ * class.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * error.c: Likewise.
+ * except.c: Likewise.
+ * mangle.c: Likewise.
+ * method.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * repo.c: Likewise.
+ * semantics.c: Likewise.
+ * typeck2.c: Likewise.
+
+2010-08-19 Jason Merrill <jason@redhat.com>
+
+ * call.c (reference_related_p): Check for error_mark_node.
+ (add_function_candidate): Check it instead of
+ same_type_ignoring_top_level_qualifiers_p.
+
+ PR c++/45315
+ * init.c (build_new_1): Don't use build_value_init in a template.
+ (build_value_init): Make sure we don't.
+
+ PR c++/45307
+ * cp-gimplify.c (cp_gimplify_expr): Also remove assignment
+ of empty class CONSTRUCTOR.
+
+ * except.c (pending_noexcept, pending_noexcept_checks): New.
+ (perform_deferred_noexcept_checks): New.
+ (maybe_noexcept_warning): Split from...
+ (finish_noexcept_expr): ...here. Adjust.
+ * decl2.c (cp_write_global_declarations): Call
+ perform_deferred_noexcept_checks.
+ * cp-tree.h: And declare it.
+
+2010-08-18 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/45049
+ * name-lookup.c (push_overloaded_decl): Change DECL_CHAIN to
+ TREE_CHAIN.
+
+2010-08-17 Kai Tietz <kai.tietz@onevision.com>
+
+ * class.c (note_name_declared_in_class): Make in 'extern "C"' blocks,
+ or if -fms-extensions is enabled check, check permissive.
+
+2010-08-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/45236
+ * pt.c (lookup_template_class): Don't re-coerce outer parms.
+
+2010-08-09 Nathan Froyd <froydnj@codesourcery.com>
+
+ * call.c (add_builtin_candidates): Use VECs for local variable
+ `types'. Adjust remainder of function accordingly.
+
+2010-08-09 Nathan Froyd <froydnj@codesourcery.com>
+
+ * name-lookup.c (is_associated_namespace): Convert local variables
+ to be VECs instead of TREE_LISTs.
+
+2010-08-09 Nathan Froyd <froydnj@codesourcery.com>
+
+ * tree.c (varargs_function_p): Use stdarg_p.
+
+2010-08-07 Nathan Froyd <froydnj@codesourcery.com>
+
+ * parser.c (cp_default_arg_entry): Declare. Declare a VEC of it.
+ (cp_unparsed_functions_entry): Declare. Declare a VEC of it.
+ (cp_parser) [unparsed_functions_queues]: Rename to unparsed_queues.
+ Change type to a VEC.
+ (unparsed_funs_with_default_args): Define.
+ (unparsed_funs_with_definitions): Define.
+ (push_unparsed_function_queues): New function.
+ (cp_parser_new): Call it.
+ (pop_unparsed_function_queues): New function.
+ (cp_parser_class_specifier): Adjust processing of unparsed functions.
+ (cp_parser_template_declaration_after_export): Use VEC_safe_push.
+ (cp_parser_save_member_function_body): Likewise.
+ (cp_parser_late_parsing_for_member): Call push_unparsed_function_queues
+ and pop_unparsed_function_queues.
+ (cp_parser_late_parsing_default_args): Likewise.
+ (cp_parser_save_default_args): Use VEC_safe_push.
+
+2010-08-07 Nathan Froyd <froydnj@codesourcery.com>
+
+ * name-lookup.h (cp_label_binding): Declare. Declare a VEC type
+ containing it.
+ (cp_binding_level): Convert shadowed_labels and dead_vars_from_for
+ fields to VECs.
+ * decl.c (poplevel): Adjust for type changes.
+ (declare_local_label): Likewise.
+
+2010-08-06 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (complete_type_or_maybe_complain): Split out from...
+ (complete_type_or_else): Here.
+ (build_class_member_access_expr): Call it.
+ (finish_class_member_access_expr): Likewise.
+ * call.c (build_special_member_call): Likewise.
+ * cvt.c (build_expr_type_conversion): Likewise.
+ * init.c (build_new): Likewise.
+ * typeck2.c (build_functional_cast): Likewise.
+ * cp-tree.h: Declare it.
+
+ * init.c (build_value_init): Add complain parm.
+ (build_value_init_noctor): Likewise.
+ (perform_member_init): Pass it.
+ (expand_aggr_init_1): Likewise.
+ (build_new_1): Likewise.
+ (build_vec_init): Likewise.
+ * pt.c (tsubst_expr): Likewise.
+ * typeck2.c (build_functional_cast): Likewise.
+ * cp-tree.h: Adjust.
+ * tree.c (build_target_expr_with_type): Handle error_mark_node.
+
+ * typeck.c (decay_conversion): Any expression with type nullptr_t
+ decays to nullptr.
+
+2010-07-30 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ PR c++/45112
+ * decl.c (duplicate_decls): Merge DECL_USER_ALIGN and DECL_PACKED.
+
+2010-07-27 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_expr) [DECL_EXPR]: Handle getting an AGGR_INIT_EXPR
+ from build_value_init.
+ * init.c (build_value_init_noctor): Give error for unknown array
+ bound.
+
+2010-07-27 Joseph Myers <joseph@codesourcery.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_MISSING_ARGUMENT): Remove.
+
+2010-07-27 Joseph Myers <joseph@codesourcery.com>
+
+ * cp-objcp-common.c (cxx_initialize_diagnostics): First call
+ c_common_initialize_diagnostics.
+ * cp-objcp-common.h (LANG_HOOKS_OPTION_LANG_MASK,
+ LANG_HOOKS_COMPLAIN_WRONG_LANG_P): Define.
+
+2010-07-21 Jason Merrill <jason@redhat.com>
+
+ * tree.c (cp_tree_equal): Fix CONSTRUCTOR handling.
+
+ * parser.c (cp_parser_init_declarator): Pass LOOKUP_NORMAL
+ to cp_finish_decl.
+
+2010-07-20 Jeffrey Yasskin <jyasskin@google.com>
+
+ PR c++/44641
+ * pt.c (instantiate_class_template): Propagate the template's
+ location to its instance.
+
+2010-07-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/44967
+ * pt.c (tsubst_copy_and_build): Rework last change.
+
+ PR c++/44967
+ * pt.c (tsubst_copy_and_build): Handle partial substitution of
+ CALL_EXPR.
+
+2010-07-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/44996
+ * semantics.c (finish_decltype_type): Correct decltype
+ of parenthesized rvalue reference variable.
+
+ PR c++/44969
+ * tree.c (cp_tree_equal): Compare type of *CAST_EXPR.
+ * pt.c (iterative_hash_template_arg): Hash type of *CAST_EXPR.
+
+2010-07-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44969
+ * typeck.c (build_x_compound_expr_from_list): Add tsubst_flags_t
+ parameter.
+ * cp-tree.h: Adjust declaration.
+ * init.c (perform_member_init): Adjust caller.
+ * decl.c (grok_reference_init, cp_finish_decl): Likewise.
+ * typeck2.c (store_init_value): Likewise.
+ (build_functional_cast): Pass complain argument to
+ build_x_compound_expr_from_list.
+
+2010-07-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/32505
+ * pt.c (process_partial_specialization): Diagnose partial
+ specialization after instantiation.
+ (most_specialized_class): Add complain parm.
+
+ * ptree.c (cxx_print_xnode): Handle TEMPLATE_INFO.
+
+2010-07-15 Nathan Froyd <froydnj@codesourcery.com>
+
+ * init.c (build_new_1): Use cp_build_function_call_nary instead of
+ cp_build_function_call.
+
+2010-07-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/44909
+ * call.c (add_function_candidate): If we're working on an implicit
+ declaration, don't consider candidates that won't match.
+ * typeck.c (same_type_ignoring_top_level_qualifiers_p): Now a fn.
+ * cp-tree.h (same_type_ignoring_top_level_qualifiers_p): Adjust.
+
+ Revert:
+ * cp-tree.h (struct lang_type_class): Add has_user_opeq.
+ (TYPE_HAS_USER_OPEQ): New.
+ * decl.c (grok_special_member_properties): Set it.
+ * class.c (add_implicitly_declared_members): Don't lazily declare
+ constructors/operator= if a base or member has a user-declared one.
+ (check_bases_and_members, check_bases): Adjust.
+ (check_field_decls, check_field_decl): Adjust.
+
+2010-07-15 Anatoly Sokolov <aesok@post.ru>
+
+ * decl.c (integer_three_node): Remove.
+ (cxx_init_decl_processing): Do not initialize the integer_three_node.
+ * cp-tree.h (integer_three_node): Remove.
+
+2010-07-15 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.h: Carefully replace TREE_CHAIN with DECL_CHAIN.
+ * call.c: Likewise.
+ * class.c: Likewise.
+ * cp-gimplify.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * init.c: Likewise.
+ * mangle.c: Likewise.
+ * name-lookup.c: Likewise.
+ * optimize.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2010-07-14 Jason Merrill <jason@redhat.com>
+
+ * init.c (sort_mem_initializers): Rename "field_type" to "ctx".
+ (build_field_list): Cache field type.
+
+ Implement C++0x unrestricted unions (N2544)
+ * class.c (check_field_decl): Loosen union handling in C++0x.
+ * method.c (walk_field_subobs): Split out from...
+ (synthesized_method_walk): ...here. Set msg before loops.
+ (process_subob_fn): Check for triviality in union members.
+ * init.c (sort_mem_initializers): Splice out uninitialized
+ anonymous unions and union members.
+ (push_base_cleanups): Don't automatically destroy anonymous unions
+ and union members.
+
+2010-07-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/44909
+ * cp-tree.h (struct lang_type_class): Add has_user_opeq.
+ (TYPE_HAS_USER_OPEQ): New.
+ * decl.c (grok_special_member_properties): Set it.
+ * class.c (add_implicitly_declared_members): Don't lazily declare
+ constructors/operator= if a base or member has a user-declared one.
+ (check_bases_and_members, check_bases): Adjust.
+ (check_field_decls, check_field_decl): Adjust.
+ * method.c (synthesized_method_walk): Initialize check_vdtor.
+
+ PR c++/44540
+ * mangle.c (write_type): Canonicalize.
+ (canonicalize_for_substitution): Retain cv-quals on FUNCTION_TYPE.
+ (write_CV_qualifiers_for_type): Ignore them in abi>=5.
+
+2010-07-13 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44908
+ * call.c (convert_like_real): Adjust convert_ptrmem call, pass
+ complain argument.
+ * typeck.c (get_delta_difference): Update prototype, add a
+ tsubst_flags_t parameter; update get_delta_difference_1 calls and
+ add checks for error_mark_node.
+ (get_delta_difference_1): Update prototype, add a tsubst_flags_t
+ parameter; update lookup_base call.
+ (build_ptrmemfunc): Update prototype, add a tsubst_flags_t
+ parameter; update get_delta_difference call and add check for
+ error_mark_node.
+ (convert_ptrmem): Update prototype, add a tsubst_flags_t
+ parameter; update get_delta_difference call and add check for
+ error_mark_node; update build_ptrmemfunc call.
+ (build_static_cast_1): Adjust convert_ptrmem call.
+ (expand_ptrmemfunc_cst): Adjust get_delta_difference call.
+ (cp_build_unary_op): Adjust build_ptrmemfunc call.
+ * cvt.c (cp_convert_to_pointer, convert_force): Adjust convert_ptrmem
+ and build_ptrmemfunc calls.
+ * cp-tree.h: Update build_ptrmemfunc and convert_ptrmem prototypes.
+
+2010-07-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44907
+ * call.c (build_temp): Add tsubst_flags_t complain parameter;
+ adjust build_special_member_call call, pass complain.
+ (convert_like_real): Adjust build_temp call, pass complain.
+
+2010-07-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/43120
+ * cp-tree.h (BV_LOST_PRIMARY): New macro.
+ * class.c (update_vtable_entry_for_fn): Fix covariant thunk logic.
+ Set BV_LOST_PRIMARY.
+ (build_vtbl_initializer): Check BV_LOST_PRIMARY.
+
+2010-07-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/43120
+ * class.c (update_vtable_entry_for_fn): Fix handling of dummy
+ virtual bases for covariant thunks.
+
+2010-07-08 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ * cp-tree.h: Do not include toplev.h.
+
+2010-07-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/44703
+ * call.c (is_std_init_list): Look through typedefs.
+
+ PR c++/44778
+ * init.c (build_offset_ref): If scope isn't dependent,
+ don't exit early. Look at TYPE_MAIN_VARIANT.
+ * pt.c (tsubst_copy) [OFFSET_REF]: Do substitution.
+
+ * error.c (dump_function_decl): Don't crash on null DECL_NAME.
+
+2010-07-06 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * cp-tree.h (impl_conv_void): New type.
+ (convert_to_void): Adjust prototype.
+ * cvt.c (convert_to_void): Use impl_conv_void, emit and adjust the
+ diagnostic for easy translation. Change caller.
+ * typeck.c: Update call to convert_to_void.
+ * semantics.c: Likewise.
+ * init.c: Likewise.
+
+2010-07-05 Nathan Froyd <froydnj@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Call add_local_decl.
+ * optimize.c (clone_body): Adjust for new type of cfun->local_decls.
+
+2010-07-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * pt.c (tsubst): Early declare code = TREE_CODE (t) and use it
+ throughout.
+
+2010-07-05 Shujing Zhao <pearly.zhao@oracle.com>
+
+ PR c++/22138
+ * parser.c (cp_parser_primary_expression): Error if local template is
+ declared.
+
+2010-07-02 Le-Chun Wu <lcwu@google.com>
+
+ PR/44128
+ * name-lookup.c (pushdecl_maybe_friend): Warn when a local decl
+ (variable or type) shadows another type.
+
+2010-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/44780
+ * typeck.c (convert_for_assignment): When converting a convertible
+ vector type or objc++ types, call mark_rvalue_use.
+ * typeck2.c (build_m_component_ref): Use return values from
+ mark_rvalue_use or mark_lvalue_use.
+ * class.c (build_base_path): Likewise.
+ * call.c (build_conditional_expr): Likewise.
+
+2010-07-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44039
+ * pt.c (tsubst_baselink): Return error_mark_node if lookup_fnfields
+ returns NULL_TREE.
+
+2010-07-01 Richard Guenther <rguenther@suse.de>
+
+ * cp-gimplify.c (cp_gimplify_expr): Open-code the rhs
+ predicate we are looking for, allow non-gimplified
+ INDIRECT_REFs.
+
+2010-06-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44628
+ * typeck.c (cp_build_unary_op): Early return error_mark_node when
+ arg is NULL_TREE too.
+ * call.c (convert_class_to_reference): Return error_mark_node when
+ expr is NULL_TREE.
+
+2010-06-30 Michael Matz <matz@suse.de>
+
+ * repo.c (finish_repo): Fix typo.
+
+2010-06-30 Nathan Froyd <froydnj@codesourcery.com>
+
+ * parser.c (cp_parser_omp_for_loop): Use a VEC for for_block.
+
+2010-06-30 Nathan Froyd <froydnj@codesourcery.com>
+
+ * repo.c (pending_repo): Change type to a VEC.
+ (finish_repo): Adjust for new type of pending_repo.
+ (repo_emit_p): Likewise.
+
+2010-06-30 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ * tree.c: Include gimple.h. Do not include tree-flow.h
+ * decl.c: Do not include tree-flow.h
+ * Make-lang.in: Adjust dependencies.
+
+2010-06-29 Nathan Froyd <froydnj@codesourcery.com>
+
+ * decl.c (incomplete_var): Declare. Declare VECs containing them.
+ (incomplete_vars): Adjust comment. Change type to a VEC.
+ (maybe_register_incomplete_var): Adjust for new type.
+ (complete_vars): Adjust iteration over incomplete_vars.
+
+2010-06-29 Nathan Froyd <froydnj@codesourcery.com>
+
+ * decl.c (struct named_label_entry): Change type of bad_decls field
+ to a VEC.
+ (poplevel_named_label_1): Adjust for new type of bad_decls.
+ (check_goto): Likewise.
+
+2010-06-29 Jason Merrill <jason@redhat.com>
+
+ Enable implicitly declared move constructor/operator= (N3053).
+ * class.c (add_implicitly_declared_members): A class with no
+ explicitly declared copy or move constructor gets both declared
+ implicitly, and similarly for operator=.
+ (check_bases): A type with no copy ctor does not inhibit
+ a const copy ctor in a derived class. It does mean the derived
+ one is non-trivial.
+ (check_field_decl): Likewise.
+ (check_bases_and_members): A nonexistent copy ctor/op= is non-trivial.
+ * tree.c (type_has_nontrivial_copy_init): Adjust semantics.
+ (trivially_copyable_p): Likewise.
+ * call.c (convert_like_real): Use type_has_nontrivial_copy_init.
+ * class.c (finish_struct_bits): Likewise.
+ * tree.c (build_target_expr_with_type): Likewise.
+ * typeck2.c (store_init_value): Likewise.
+
+ Enable implicitly deleted functions (N2346)
+ * class.c (check_bases_and_members): Adjust lambda flags.
+ * method.c (implicitly_declare_fn): Set DECL_DELETED_FN if appropriate.
+
+ * decl2.c (mark_used): Adjust error for use of deleted function.
+
+ Machinery to support implicit delete/move.
+ * cp-tree.h: (struct lang_type_class): Add lazy_move_assign,
+ has_complex_move_ctor, has_complex_move_assign bitfields.
+ (CLASSTYPE_LAZY_MOVE_ASSIGN): New.
+ (TYPE_HAS_COMPLEX_MOVE_ASSIGN): New.
+ (TYPE_HAS_COMPLEX_MOVE_CTOR): New.
+ (enum special_function_kind): Add sfk_move_assignment.
+ (LOOKUP_SPECULATIVE): New.
+ * call.c (build_over_call): Return early if it's set.
+ (build_over_call): Use trivial_fn_p.
+ * class.c (check_bases): If the base has no default constructor,
+ the derived one is non-trivial. Handle move ctor/op=.
+ (check_field_decl): Likewise.
+ (check_bases_and_members): Handle move ctor/op=.
+ (add_implicitly_declared_members): Handle CLASSTYPE_LAZY_MOVE_ASSIGN.
+ (type_has_move_constructor, type_has_move_assign): New.
+ * decl.c (grok_special_member_properties): Handle move ctor/op=.
+ * method.c (type_has_trivial_fn, type_set_nontrivial_flag): New.
+ (trivial_fn_p): New.
+ (do_build_copy_constructor): Use it.
+ (do_build_assign_ref): Likewise. Handle move assignment.
+ (build_stub_type, build_stub_object, locate_fn_flags): New.
+ (locate_ctor): Use locate_fn_flags.
+ (locate_copy, locate_dtor): Remove.
+ (get_dtor, get_default_ctor, get_copy_ctor, get_copy_assign): New.
+ (process_subob_fn, synthesized_method_walk): New.
+ (maybe_explain_implicit_delete): New.
+ (implicitly_declare_fn): Use synthesized_method_walk,
+ type_has_trivial_fn, and type_set_nontrivial_flag.
+ (defaulted_late_check): Set DECL_DELETED_FN.
+ (defaultable_fn_check): Handle sfk_move_assignment.
+ (lazily_declare_fn): Clear CLASSTYPE_LAZY_* early. Don't declare
+ implicitly deleted move ctor/op=.
+ * search.c (lookup_fnfields_1): Handle sfk_move_assignment.
+ (lookup_fnfields_slot): New.
+ * semantics.c (omp_clause_info_fndecl): Remove.
+ (cxx_omp_create_clause_info): Use get_default_ctor, get_copy_ctor,
+ get_copy_assign, trivial_fn_p.
+ (trait_expr_value): Adjust call to locate_ctor.
+ * tree.c (special_function_p): Handle sfk_move_assignment.
+
+ * class.c (type_has_virtual_destructor): New.
+ * cp-tree.h: Declare it.
+ * semantics.c (trait_expr_value): Use it.
+
+ * call.c (build_over_call): Only give warnings with tf_warning.
+
+ * name-lookup.c (pop_scope): Handle NULL_TREE.
+
+ * cp-tree.h (TYPE_HAS_ASSIGN_REF): Rename to TYPE_HAS_COPY_ASSIGN.
+ (TYPE_HAS_CONST_ASSIGN_REF): Rename to TYPE_HAS_CONST_COPY_ASSIGN.
+ (TYPE_HAS_INIT_REF): Rename to TYPE_HAS_COPY_CTOR.
+ (TYPE_HAS_CONST_INIT_REF): Rename to TYPE_HAS_CONST_COPY_CTOR.
+ (TYPE_HAS_COMPLEX_ASSIGN_REF): Rename to TYPE_HAS_COMPLEX_COPY_ASSIGN.
+ (TYPE_HAS_COMPLEX_INIT_REF): Rename to TYPE_HAS_COMPLEX_COPY_CTOR.
+ (TYPE_HAS_TRIVIAL_ASSIGN_REF): Rename to TYPE_HAS_TRIVIAL_COPY_ASSIGN.
+ (TYPE_HAS_TRIVIAL_INIT_REF): Rename to TYPE_HAS_TRIVIAL_COPY_CTOR.
+ (CLASSTYPE_LAZY_ASSIGNMENT_OP): Rename to CLASSTYPE_LAZY_COPY_ASSIGN.
+ (sfk_assignment_operator): Rename to sfk_copy_assignment.
+ * decl.c, call.c, class.c, init.c, method.c, pt.c, ptree.c: Adjust.
+ * search.c, semantics.c, tree.c: Adjust.
+
+ * pt.c (dependent_scope_ref_p): Remove.
+ (value_dependent_expression_p): Don't call it.
+ (type_dependent_expression_p): Here either.
+ * init.c (build_offset_ref): Set TREE_TYPE on a qualified-id
+ if the scope isn't dependent.
+
+ * pt.c (convert_nontype_argument): Use mark_lvalue_use if we want
+ a reference.
+
+ PR c++/44587
+ * pt.c (has_value_dependent_address): New.
+ (value_dependent_expression_p): Check it.
+ (convert_nontype_argument): Likewise. Call decay_conversion before
+ folding if we want a pointer.
+ * semantics.c (finish_id_expression): Don't add SCOPE_REF if the
+ scope is the current instantiation.
+
+2010-06-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/44682
+ * class.c (build_base_path): If want_pointer, call mark_rvalue_use
+ on expr.
+
+2010-06-28 Steven Bosscher <steven@gcc.gnu.org>
+
+ * init.c: Do not include except.h.
+ * decl.c: Likewise.
+ * expr.c: Likewise.
+ * cp-lang.c: Likewise.
+ * pt.c: Likewise.
+ * semantics.c: Likewise.
+ * decl2.c: Likewise.
+ * except.c: Likewise.
+ (init_exception_processing): Do not set the removed
+ lang_protect_cleanup_actions here.
+ (cp_protect_cleanup_actions): Make non-static and remove prototype.
+ (doing_eh): New, moved from except.c but removed the do_warning flag.
+ (expand_start_catch_block): Update doing_eh call.
+ (expand_end_catch_block): Likewise.
+ (build_throw): Likewise.
+ * cp-tree.h: Prototype cp_protect_cleanup_actions.
+ * cp-objcp-common.h: Set LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS to
+ cp_protect_cleanup_actions.
+ * Make-lang.in: Update dependencies.
+
+2010-06-26 Jason Merrill <jason@redhat.com>
+
+ * call.c (add_function_candidate): Set LOOKUP_COPY_PARM for any
+ constructor called with a single argument that takes a reference
+ to the constructor's class.
+ (BAD_CONVERSION_RANK): New.
+ (compare_ics): Use it to compare bad ICSes.
+
+2010-06-25 Joseph Myers <joseph@codesourcery.com>
+
+ * lang-specs.h: Remove +e handling.
+
+2010-06-24 Andi Kleen <ak@linux.intel.com>
+
+ * parser.c: (cp_parser_question_colon_clause):
+ Switch to use cp_lexer_peek_token.
+ Call warn_for_omitted_condop. Call pedwarn for omitted
+ middle operand.
+
+2010-06-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/44619
+ * typeck2.c (build_m_component_ref): Call mark_lvalue_use on
+ datum and mark_rvalue_use on component.
+
+ PR c++/44627
+ * error.c (dump_expr): Don't look at CALL_EXPR_ARG (t, 0) if
+ the CALL_EXPR has no arguments.
+
+2010-06-21 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (comp_except_specs): Fix ce_derived with noexcept.
+
+ * semantics.c (check_trait_type): Check COMPLETE_TYPE_P for array
+ element type.
+
+2010-06-17 Nathan Froyd <froydnj@codesourcery.com>
+
+ * name-lookup.c (struct arg_lookup): Convert namespaces and
+ classes fields to VEC.
+ (arg_assoc_namespace): Adjust for new type of namespaces.
+ (arg_assoc_class): Adjust for new type of classes.
+ (lookup_arg_dependent): Use make_tree_vector and
+ release_tree_vector.
+ * typeck2.c (build_x_arrow): Use vec_member.
+
+2010-06-17 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/44486
+ * error.c (dump_decl): Better wording for anonymous namespace.
+
+2010-06-16 Nathan Froyd <froydnj@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Adjust computation of new_position
+ and which entry to add padding for.
+
+2010-06-16 Jason Merrill <jason@redhat.com>
+
+ * except.c (check_noexcept_r): Return the problematic function.
+ (finish_noexcept_expr): Give -Wnoexcept warning. Add complain parm.
+ * pt.c (tsubst_copy_and_build): Pass it.
+ * parser.c (cp_parser_unary_expression): Likewise.
+ * cp-tree.h: Adjust prototype.
+
+ * method.c (defaulted_late_check): Give the defaulted method
+ the same exception specification as the implicit declaration.
+
+2010-06-15 Jason Merrill <jason@redhat.com>
+
+ * class.c (add_implicitly_declared_members): Implicit assignment
+ operators can also be virtual overriders.
+ * method.c (lazily_declare_fn): Likewise.
+
+ * call.c (convert_like_real): Give "initializing argument of"
+ information for ambiguous conversion. Give source position
+ of function.
+
+ * call.c (print_z_candidates): Do print viable deleted candidates.
+ (joust): Don't choose a deleted function just because its worst
+ conversion is better than another candidate's worst.
+
+ * call.c (convert_like_real): Don't complain about
+ list-value-initialization from an explicit constructor.
+
+ * decl.c (duplicate_decls): Use DECL_IS_BUILTIN rather than test
+ DECL_SOURCE_LOCATION directly.
+
+ * class.c (type_has_user_provided_default_constructor): Use
+ sufficient_parms_p.
+
+ * call.c (is_subseq): Handle ck_aggr, ck_list.
+ (compare_ics): Treat an aggregate or ambiguous conversion to the
+ same type as involving the same function.
+
+2010-06-13 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * typeck.c (convert_for_assignment): Fix comment. Change message
+ format from %d to %qP.
+ (convert_for_initialization): Fix comment.
+
+2010-06-11 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * cp-tree.h (expr_list_kind): New type.
+ (impl_conv_rhs): New type.
+ (build_x_compound_expr_from_list, convert_for_initialization): Adjust
+ prototype.
+ (typeck.c (convert_arguments): Use impl_conv_rhs and emit the
+ diagnostics for easy translation. Change caller.
+ (convert_for_initialization): Use impl_conv_rhs and change caller.
+ (build_x_compound_expr_from_list): Use expr_list_kind and emit the
+ diagnostics for easy translation. Change caller.
+ * decl.c (bad_spec_place): New enum.
+ (bad_specifiers): Use it and emit the diagnostics for easy
+ translation. Change caller.
+ * pt.c (coerce_template_parms): Put the diagnostics in full sentence.
+
+2010-06-09 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.h (struct saved_scope): Change decl_ns_list field type
+ to a VEC.
+ * decl2.c (cp_write_global_declarations): Adjust for new type of
+ decl_namespace_list.
+ * name-lookup.c (current_decl_namespace): Likewise.
+ (push_decl_namespace): Likewise.
+ (pop_decl_namespace): Likewise.
+
+2010-06-09 Nathan Froyd <froydnj@codesourcery.com>
+
+ * call.c (build_java_interface_fn_ref): Call build_function_type_list
+ instead of build_function_type.
+ * decl.c (cxx_init_decl_processing): Likewise.
+ (declare_global_var): Likewise.
+ (get_atexit_node): Likewise.
+ (expand_static_init): Likewise.
+ * decl2.c (start_objects): Likewise.
+ (start_static_storage_duration_function): Likewise.
+ * except.c (init_exception_processing): Likewise.
+ (build_exc_ptr): Likewise.
+ (build_throw): Likewise.
+ * rtti.c (throw_bad_cast): Likewise.
+ (throw_bad_typeid): Likewise.
+ (build_dynamic_cast_1): Likewise.
+
+2010-06-09 Nathan Froyd <froydnj@codesourcery.com>
+
+ * call.c (build_call_n): Call XALLOCAVEC instead of alloca.
+ (build_op_delete_call): Likewise.
+ (build_over_call): Likewise.
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Likewise.
+ * pt.c (process_partial_specialization): Likewise.
+ (tsubst_template_args): Likewise.
+ * semantics.c (finish_asm_stmt): Likewise.
+
+2010-06-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (record_key_method_defined): New, broken out of ...
+ (finish_function): ... here. Call it.
+ (start_decl): Treat aliases as definitions.
+
+2010-06-08 Laurynas Biveinis <laurynas.biveinis@gmail.com>
+
+ * typeck2.c (abstract_virtuals_error): Use typed GC allocation.
+
+ * pt.c (maybe_process_partial_specialization): Likewise.
+ (register_specialization): Likewise.
+ (add_pending_template): Likewise.
+ (lookup_template_class): Likewise.
+ (push_tinst_level): Likewise.
+
+ * parser.c (cp_lexer_new_main): Likewise.
+ (cp_lexer_new_from_tokens): Likewise.
+ (cp_token_cache_new): Likewise.
+ (cp_parser_context_new): Likewise.
+ (cp_parser_new): Likewise.
+ (cp_parser_nested_name_specifier_opt): Likewise.
+ (cp_parser_template_id): Likewise.
+
+ * name-lookup.c (binding_entry_make): Likewise.
+ (binding_table_construct): Likewise.
+ (binding_table_new): Likewise.
+ (cxx_binding_make): Likewise.
+ (pushdecl_maybe_friend): Likewise.
+ (begin_scope): Likewise.
+ (push_to_top_level): Likewise.
+
+ * lex.c (init_reswords): Likewise.
+ (retrofit_lang_decl): Likewise.
+ (cxx_dup_lang_specific_decl): Likewise.
+ (copy_lang_type): Likewise.
+ (cxx_make_type): Likewise.
+
+ * decl.c (make_label_decl): Likewise.
+ (check_goto): Likewise.
+ (start_preparsed_function): Likewise.
+ (save_function_data): Likewise.
+
+ * cp-tree.h (TYPE_SET_PTRMEMFUNC_TYPE): Likewise.
+
+ * cp-objcp-common.c (decl_shadowed_for_var_insert): Likewise.
+
+ * class.c (finish_struct_1): Likewise.
+
+ * cp-tree.h (struct lang_type): Add variable_size GTY option.
+ (struct lang_decl): Likewise.
+
+ * parser.c (cp_parser_new): Update comment to not reference
+ ggc_alloc.
+
+2010-06-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/44366
+ * error.c (dump_parameters): Mask out TFF_SCOPE.
+ (dump_simple_decl): Don't print the scope of a PARM_DECL.
+ (dump_scope): Remove no-op mask.
+
+ PR c++/44401
+ * parser.c (cp_parser_lookup_name): Fix naming the constructor.
+
+ * cp-tree.h (COMPLETE_OR_OPEN_TYPE_P): New macro.
+ * init.c (build_offset_ref): Use it.
+ * pt.c (maybe_process_partial_specialization): Use it.
+ (instantiate_class_template): Use it.
+ * search.c (lookup_base): Use it.
+
+2010-06-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/44444
+ * expr.c (mark_exp_read): Handle INDIRECT_REF.
+ * cvt.c (convert_to_void): Handle INDIRECT_REF like
+ handled_component_p.
+
+ PR c++/44443
+ * decl.c (initialize_local_var): If TREE_USED is set on the type,
+ set also DECL_READ_P on the decl.
+
+2010-05-25 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/44188
+ * cp-tree.h (typedef_variant_p): Move this declaration to
+ gcc/tree.h.
+ * tree.c (typedef_variant_p): Move this definition to gcc/tree.c.
+ * decl.c (grokdeclarator): Do not rename debug info of an
+ anonymous tagged type named by a typedef.
+
+2010-06-05 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/44086
+ * class.c (check_field_decls): Move the call to
+ check_bitfield_decl before trying to set the
+ CLASSTYPE_READONLY_FIELDS_NEED_INIT flag.
+
+2010-06-05 Steven Bosscher <steven@gcc.gnu.org>
+
+ * typeck.c: Update include path for moved files.
+ * decl.c: Likewise.
+ * rtti.c: Likewise.
+ * cp-gimplify.c: Likewise.
+ * cp-lang.c: Likewise.
+ * pt.c: Likewise.
+ * semantics.c: Likewise.
+ * cxx-pretty-print.h: Likewise.
+ * decl2.c: Likewise.
+ * parser.c: Likewise.
+ * cp-objcp-common.c: Likewise.
+ * cp-tree.h: Likewise.
+ * name-lookup.c: Likewise.
+ * lex.c: Likewise.
+ * name-lookup.h: Likewise.
+ * config-lang.in: Update paths in gtfiles for files in c-family/.
+ * Make-lang.in: Likewise.
+
+2010-06-04 Magnus Fromreide <magfr@lysator.liu.se>
+
+ * cvt.c (cp_convert_to_pointer): Use null_ptr_cst_p.
+ * typeck.c (build_ptrmemfunc): Likewise.
+
+2010-06-04 Jason Merrill <jason@redhat.com>
+
+ * typeck2.c (merge_exception_specifiers): Adjust merging of
+ throw() and noexcept(true).
+
+ * pt.c (value_dependent_expression_p) [NOEXCEPT_EXPR]: Avoid
+ using an uninitialized variable.
+
+ * cxx-pretty-print.c (pp_cxx_unary_expression): Handle NOEXCEPT_EXPR.
+ (pp_cxx_expression): Likewise.
+
+ Implement noexcept-specification (15.4)
+ * parser.c (cp_parser_exception_specification_opt): Parse it.
+ Give -Wdeprecated warning about throw() specs.
+ * pt.c (tsubst_exception_specification): Handle it.
+ * error.c (dump_exception_spec): Handle it.
+ (dump_expr): Handle NOEXCEPT_EXPR.
+ * cxx-pretty-print.c (pp_cxx_exception_specification): Likewise.
+ * typeck.c (comp_except_specs): Handle compatibility rules.
+ Change exact parm to take an enum.
+ * typeck2.c (merge_exception_specifiers): Handle noexcept.
+ * except.c (nothrow_spec_p, type_noexcept_p): New fns.
+ (type_throw_all_p, build_noexcept_spec): New fns.
+ * cp-tree.h (TYPE_NOTHROW_P, TYPE_NOEXCEPT_P): Use them.
+ (comp_except_specs): Define ce_derived, ce_normal, ce_exact enums.
+ (cp_tree_index): Add CPTI_NOEXCEPT_TRUE_SPEC, CPTI_NOEXCEPT_FALSE_SPEC.
+ (noexcept_true_spec, noexcept_false_spec): New macros.
+ * name-lookup.c (pushdecl_maybe_friend): Adjust.
+ * search.c (check_final_overrider): Adjust.
+ * decl.c (check_redeclaration_exception_specification): Adjust.
+ (use_eh_spec_block): Use type_throw_all_p.
+ (cxx_init_decl_processing): Set noexcept_false_spec,noexcept_true_spec.
+ Give operator new a noexcept-specification in C++0x mode.
+ * tree.c (build_exception_variant, cxx_type_hash_eq): Adjust.
+ (cp_build_type_attribute_variant): Don't test TYPE_RAISES_EXCEPTIONS.
+
+ Implement noexcept operator (5.3.7)
+ * cp-tree.def (NOEXCEPT_EXPR): New.
+ * except.c (check_noexcept_r, finish_noexcept_expr): New.
+ * cp-tree.h: Declare finish_noexcept_expr.
+ * parser.c (cp_parser_unary_expression): Parse noexcept-expression.
+ * pt.c (tsubst_copy_and_build): And tsubst it.
+ (type_dependent_expression_p): Handle it.
+ (value_dependent_expression_p): Handle it.
+
+ * call.c (build_conditional_expr): Never fold in unevaluated context.
+ * tree.c (build_aggr_init_expr): Propagate TREE_NOTHROW.
+ * semantics.c (simplify_aggr_init_expr): Likewise.
+ * typeck.c (merge_types): Call merge_exception_specifiers.
+ * decl.c (duplicate_decls): Check DECL_SOURCE_LOCATION rather than
+ DECL_ANTICIPATED for preferring new type.
+
+2010-06-04 Joseph Myers <joseph@codesourcery.com>
+
+ * g++spec.c (lang_specific_driver): Use GCC-specific formats in
+ diagnostics.
+
+2010-06-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/44412
+ * typeck.c (build_class_member_access_expr): Call mark_exp_read
+ on object for static data members.
+
+2010-06-04 Jakub Jelinek <jakub@redhat.com>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/44362
+ * call.c (build_conditional_expr): If both arg2 and arg3 are lvalues
+ with the same type, call mark_lvalue_use on both.
+
+2010-06-03 Nathan Froyd <froydnj@codesourcery.com>
+
+ * class.c (struct vtbl_init_data_s): Remove last_init field.
+ (struct secondary_vptr_vtt_init_data_s): Change type of inits field
+ to a VEC.
+ (finish_vtbls): Use a VEC rather than a TREE_LIST for the accumulated
+ initializers.
+ (build_vtt): Likewise.
+ (initialize_vtable): Take a VEC instead of a tree.
+ (build_vtt_inits): Change return type to void. Take a VEC **
+ instead of a tree *; accumulate results into said VEC.
+ (build_ctor_vtbl_group): Use a VEC rather than a TREE_LIST for the
+ accumulated initializers. Pass the vtable to accumulate_vtbl_inits.
+ (accumulate_vtbl_inits): Add extra vtable tree parameter; take a VEC
+ instead of a tree.
+ (dfs_accumulate_vtbl_inits): Likewise. Change return type to void.
+ (build_vtbl_initializer): Add VEC parameter; accumulate initializers
+ into it.
+ (dfs_build_secondary_vptr_vtt_inits): Use CONSTRUCTOR_APPEND_ELT
+ rather than tree_cons.
+ (build_vbase_offset_vtbl_entries): Likewise.
+ (add_vcall_offset): Likewise.
+ (build_rtti_vtbl_entries): Likewise.
+ * cp-tree.h (initialize_artificial_var): Take a VEC instead of a tree.
+ * decl.c (initialize_artificial_var): Use build_constructor instead
+ of build_constructor_from_list.
+
+2010-06-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/44294
+ * class.c (layout_class_type): Check MAX_FIXED_MODE_SIZE on
+ bit-field.
+
+2010-06-02 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * parser.c (cp_parser_mem_initializer_list): Change error text.
+
+2010-06-02 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-objcp-common.c (shadowed_var_for_decl): Change into
+ tree_decl_map hashtab from tree_map.
+ (decl_shadowed_for_var_lookup, decl_shadowed_for_var_insert): Adjust.
+ (init_shadowed_var_for_decl): Adjust initialization.
+
+ PR c++/44361
+ * cvt.c (convert_to_void): If implicit is NULL, call mark_rvalue_use
+ instead of calling mark_exp_read only when not an assignment.
+
+ PR debug/44367
+ * semantics.c (finalize_nrv): Don't copy DECL_ARTIFICIAL, DECL_IGNORED_P,
+ DECL_SOURCE_LOCATION and DECL_ABSTRACT_ORIGIN from var to result.
+ Set DECL_VALUE_EXPR on var.
+
+2010-06-02 Jason Merrill <jason@redhat.com>
+
+ * error.c (dump_type): Improve typedef handling.
+
+ PR c++/9726
+ PR c++/23594
+ PR c++/44333
+ * name-lookup.c (same_entity_p): New.
+ (ambiguous_decl): Multiple declarations of the same entity
+ are not ambiguous.
+
+2010-06-01 Jason Merrill <jason@redhat.com>
+
+ DR 990
+ * call.c (add_list_candidates): Prefer the default constructor.
+ (build_aggr_conv): Treat missing initializers like { }.
+ * typeck2.c (process_init_constructor_record): Likewise.
+ * init.c (expand_default_init): Use digest_init for
+ direct aggregate initialization, too.
+
+ * call.c (add_list_candidates): Split out...
+ (build_user_type_conversion_1): ...from here.
+ (build_new_method_call): And here.
+ (implicit_conversion): Propagate LOOKUP_NO_NARROWING.
+
+ PR c++/44358
+ * call.c (build_list_conv): Set list-initialization flags properly.
+
+2010-06-01 Nathan Froyd <froydnj@codesourcery.com>
+
+ * typeck2.c (build_x_arrow): Make types_memoized a VEC.
+
+2010-06-01 Arnaud Charlet <charlet@adacore.com>
+ Matthew Gingell <gingell@adacore.com>
+
+ * Make-lang.in (CXX_C_OBJS): Add c-ada-spec.o.
+ * decl2.c: Include langhooks.h and c-ada-spec.h.
+ (cpp_check, collect_source_refs, collect_ada_namespace,
+ collect_all_refs): New functions.
+ (cp_write_global_declarations): Add handling of -fdump-ada-spec.
+ * lang-specs.h: Ditto.
+
+2010-05-29 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.h (cp_build_function_call_nary): Declare.
+ * typeck.c (cp_build_function_call_nary): Define.
+ * decl.c (register_dtor_fn): Use it instead of
+ cp_build_function_call.
+ (cxx_maybe_build_cleanup): Likewise.
+ * decl2.c (generate_ctor_or_dtor_function): Likewise.
+ * except.c (do_get_exception_ptr): Likewise.
+ (do_begin_catch): Likewise.
+ (do_allocate_exception): Likewise.
+ (do_free_exception): Likewise.
+ (build_throw): Likewise. Use cp_build_function_call_vec instead
+ of cp_build_function_call.
+ (do_end_catch): Likewise.
+
+2010-05-29 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.h (struct cp_decl_specifier_seq): Move type_location field up.
+ (struct cp_declarator): Move id_loc field up.
+
+2010-05-29 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cp-tree.h (ATTRIBUTE_GCC_CXXDIAG): Remove. Require that
+ this file is included before c-common.h. Define GCC_DIAG_STYLE
+ before including diagnostic-core.h and toplev.h.
+ (pedwarn_cxx98): Use ATTRIBUTE_GCC_DIAG.
+ * pt.c: Include cp-tree.h before c-common.h.
+
+2010-05-29 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree.c (c_register_addr_space): Add stub.
+
+2010-05-28 Joseph Myers <joseph@codesourcery.com>
+
+ * g++spec.c (lang_specific_driver): Use fatal_error instead of
+ fatal.
+
+2010-05-28 Dodji Seketeli <dodji@redhat.com>
+
+ Revert fix of PR c++/44188
+ * cp-tree.h (typedef_variant_p): Revert moving this declaration to
+ gcc/tree.h.
+ * tree.c (typedef_variant_p): Revert moving this definition to
+ gcc/tree.c.
+ * decl.c (grokdeclarator): Revert naming typedef handling.
+
+2010-05-27 Joseph Myers <joseph@codesourcery.com>
+
+ * call.c: Include diagnostic-core.h instead of diagnostic.h.
+ * cp-lang.c: Don't include diagnostic.h
+ * name-lookup.c: Include diagnostic-core.h instead of
+ diagnostic.h.
+ (cp_emit_debug_info_for_using): Use seen_error.
+ * optimize.c: Include diagnostic-core.h instead of diagnostic.h.
+ * parser.c: Include diagnostic-core.h instead of diagnostic.h.
+ * pt.c (iterative_hash_template_arg): Use seen_error.
+ * repo.c: Include diagnostic-core.h instead of diagnostic.h.
+ * typeck2.c: Include diagnostic-core.h instead of diagnostic.h.
+ * Make-lang.in (cp/cp-lang.o, cp/typeck2.o, cp/call.o, cp/repo.o,
+ cp/optimize.o, cp/parser.o, cp/name-lookup.o): Update
+ dependencies.
+
+2010-05-25 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/44188
+ * cp-tree.h (typedef_variant_p): Move this declaration to
+ gcc/tree.h.
+ * tree.c (typedef_variant_p): Move this definition to gcc/tree.c.
+ * decl.c (grokdeclarator): Do not rename debug info of an
+ anonymous tagged type named by a typedef.
+
+2010-05-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/43555
+ * decl.c (grokdeclarator) [cdk_pointer et al]: Force evaluation of
+ anonymous VLA size.
+
+2010-05-27 Kai Tietz <kai.tietz@onevision.com>
+
+ PR bootstrap/44287
+ * rtti.c (emit_support_tinfos): Check for NULL_TREE.
+ * class.c (layout_class_type): Likewise.
+ * decl.c (finish_enum): Likewise.
+ * mangle.c (write_builitin_type): Likewise.
+
+2010-05-26 Kai Tietz <kai.tietz@onevision.com>
+
+ * cp-tree.h (cp_decl_specifier_seq): Add new bifield
+ explicit_int128_p.
+ * decl.c (grokdeclarator): Handle __int128.
+ * parser.c (cp_lexer_next_token_is_decl_specifier_ke): Likewise.
+ (cp_parser_simple_type_specifier): Likewise.
+ * rtti.c (emit_support_tinfos): Add int128 nodes for rtti.
+ * typeck.c (cp_common_type): Handle __int128.
+ * mangle.c (integer_type_codes): Add itk_int128 and
+ itk_unsigned_int128.
+
+2010-05-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/43382
+ * pt.c (tsubst_pack_expansion): Don't get confused by recursive
+ unification.
+
+2010-05-26 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cp-lang.c: Do not include expr.h.
+
+2010-05-26 Steven Bosscher <steven@gcc.gnu.org>
+
+ * decl.c: Do not include rtl.h
+ * semantics.c: Likewise.
+
+2010-05-25 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cp-tree.h: Do not include splay-tree.h.
+ (struct prtmem_cst): Remove unused field and false comment.
+ * typeck.c: Do not include rtl.h, expr.h, and tm_p.h.
+ * optimize.c: Do not inclde rtl.h, insn-config.h, and integrate.h.
+ * init.c: Do not include rtl.h and expr.h.
+ * class.c: Do not include rtl.h. Include splay-tree.h.
+ (build_clone): Use plain NULL instead of NULL_RTX.
+ * decl.c: Do not include expr.h. Explain why rtl.h has to be
+ included. Include splay-tree.h.
+ * method.c: Do not include rtl.h and expr.h.
+ (use_thunk): Use plain NULL instead of NULL_RTX.
+ * except.c: Do not include rtl.h, expr.h, and libfuncs.h.
+ * tree.c: Do not include rtl.h, insn-config.h, integrate.h,
+ and target.h. Include splay-tree.h.
+ * expr.c: Do not include rtl.h and expr.h.
+ * pt.c: Do not include obstack.h and rtl.h.
+ (tsubst_friend_function): Use plain NULL instead of NULL_RTX.
+ (tsubst_decl): Likewise.
+ (instantiate_decl): Likewise.
+ * semantics.c: Do not include exprt.h and debug.h. Explain why
+ rtl.h has to be included.
+ * decl2.c: Do not include rtl.h and expr.h. Include splay-tree.h.
+ * call.c: Do not include rtl.h and expr.h.
+ * search.c: Do not include obstack.h and rtl.h.
+ * friend.c: Do not include rtl.h and expr.h.
+ * Make-lang.in: Update dependencies.
+
+2010-05-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/18249
+ * parser.c (non_integral_constant): Add NIC_NONE.
+ (required_token): Add RT_NONE.
+ (cp_parser_unary_expression): Initialize non_constant_p
+ to NIC_NONE.
+ (cp_parser_asm_definition): Initialize missing to RT_NONE.
+ (cp_parser_primary_expression, cp_parser_postfix_expression,
+ cp_parser_cast_expression, cp_parser_binary_expression,
+ cp_parser_functional_cast): Fix formatting.
+
+2010-05-25 Shujing Zhao <pearly.zhao@oracle.com>
+
+ PR c++/18249
+ * parser.c: Remove inclusion of dyn-string.h.
+ (non_integral_constant): New enum.
+ (name_lookup_error): New enum.
+ (required_token): New enum.
+ (cp_parser_required_error): New function.
+ (cp_parser_require): Change the type of variable token_desc to
+ required_token and use cp_parser_required_error.
+ (cp_parser_require_keyword): Likewise.
+ (cp_parser_error): Use gmsgid as parameter.
+ (cp_parser_name_lookup_error): Change the type of variable desired to
+ name_lookup_error and put the diagnostic in the full sentences. Change
+ caller.
+ (cp_parser_non_integral_constant_expression): Change the type of the
+ variable thing to non_integral_constant and put the diagnostics in
+ full sentences. Change caller.
+
+2010-05-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR middle-end/44100
+ * typeck.c (cp_build_unary_op): Fold offsetof-like computations.
+
+2010-05-24 Joseph Myers <joseph@codesourcery.com>
+
+ * error.c (cp_diagnostic_starter): Update call to
+ diagnostic_build_prefix.
+ (cp_print_error_function,
+ print_instantiation_partial_context_line): Check show_column flag
+ in context.
+
+2010-05-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/41510
+ * decl.c (check_initializer): Don't wrap an init-list in a
+ TREE_LIST.
+ * init.c (build_aggr_init): Don't assume copy-initialization if
+ init has CONSTRUCTOR_IS_DIRECT_INIT.
+ * call.c (build_new_method_call): Sanity check.
+
+2010-05-24 Nathan Froyd <froydnj@codesourcery.com>
+
+ * rtti.c (tinfo_base_init): Use build_constructor instead of
+ build_constructor_from_list. Don't cons a tree node for
+ returning.
+ (generic_initializer): Use build_constructor_single instead of
+ build_constructor_from_list.
+ (ptr_initializer): Use build_constructor instead of
+ build_constructor_from_list
+ (ptm_initializer): Likewise.
+ (class_initializer): Likewise. Take varargs instead of TRAIL.
+ (get_pseudo_ti_init): Adjust calls to class_initializer. Use
+ build_constructor instead of build_constructor_from_list.
+
+2010-05-22 Steven Bosscher <steven@gcc.gnu.org>
+
+ * semantics.c: Include bitmap.h.
+ * Make-lang.in: Update dependencies.
+
+2010-05-22 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (maybe_emit_vtables): Produce same comdat group when outputting
+ comdat vtables.
+ (cxx_callgraph_analyze_expr): Remove code marking vtables needed.
+
+2010-05-21 Joseph Myers <joseph@codesourcery.com>
+
+ * cxx-pretty-print.c: Correct merge error.
+
+2010-05-21 Joseph Myers <joseph@codesourcery.com>
+
+ * error.c: Include tree-diagnostic.h and tree-pretty-print.h.
+ (cp_print_error_function): Use diagnostic_abstract_origin macro.
+ (cp_printer): Handle %K here using percent_K_format.
+ * cxx-pretty-print.c: Include tree-pretty-print.h.
+ * Make-lang.in (cp/error.o, cp/cxx-pretty-print.o): Update
+ dependencies.
+
+2010-05-21 Steven Bosscher <steven@gcc.gnu.org>
+
+ * error.c, tree.c, typeck2.c, cxx-pretty-print.c, mangle.c:
+ Clean up redundant includes.
+
+2010-05-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/30298
+ * decl.c (xref_basetypes): Return false in case of ill-formed
+ redefinition.
+
+2010-05-19 Jason Merrill <jason@redhat.com>
+
+ * call.c (reference_binding): Use cp_build_qualified_type_real
+ and cp_type_quals consistently.
+ (add_function_candidate): Likewise.
+ (build_conditional_expr): Likewise.
+ (convert_like_real): Likewise.
+ (type_passed_as): Likewise.
+ * class.c (add_method): Likewise.
+ (same_signature_p): Likewise.
+ (layout_class_type): Likewise.
+ * decl.c (cxx_init_decl_processing): Likewise.
+ (cp_fname_init): Likewise.
+ (grokdeclarator): Likewise.
+ * decl2.c (cp_reconstruct_complex_type): Likewise.
+ * init.c (build_new_1): Likewise.
+ * method.c (do_build_copy_constructor): Likewise.
+ (implicitly_declare_fn): Likewise.
+ * pt.c (tsubst_aggr_type): Likewise.
+ (tsubst): Likewise.
+ * rtti.c (init_rtti_processing): Likewise.
+ (build_headof): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ (tinfo_base_init): Likewise.
+ (emit_support_tinfos): Likewise.
+ * semantics.c (capture_decltype): Likewise.
+ * tree.c (cv_unqualified): Likewise.
+ * typeck.c (composite_pointer_type): Likewise.
+ (string_conv_p): Likewise.
+
+ * mangle.c (write_CV_qualifiers_for_type): Tweak.
+
+ * call.c (initialize_reference): Use CP_TYPE_CONST_P.
+ * decl.c (start_decl): Likewise.
+ * semantics.c (finish_compound_literal): Likewise.
+ * typeck.c (check_return_expr): Use CP_TYPE_VOLATILE_P.
+ (cp_type_readonly): Remove.
+ * cp-tree.h: Remove declaration.
+
+ * typeck.c (merge_types): Preserve memfn quals.
+
+ * decl.c (grokdeclarator): Don't check quals on fn type.
+ * typeck.c (cp_apply_type_quals_to_decl): Likewise.
+ * tree.c (cp_build_qualified_type_real): Simplify qualifier checking.
+
+ PR c++/44193
+ * typeck.c (type_memfn_quals): New fn.
+ (apply_memfn_quals): New fn.
+ (cp_type_quals): Return TYPE_UNQUALIFIED for FUNCTION_TYPE.
+ (cp_type_readonly): Use cp_type_quals.
+ * cp-tree.h: Add declarations.
+ * tree.c (cp_build_qualified_type_real): Don't set, but do
+ preserve, quals on FUNCTION_TYPE.
+ (strip_typedefs): Use apply_memfn_quals and type_memfn_quals.
+ * decl.c (build_ptrmem_type): Likewise.
+ (grokdeclarator): Likewise.
+ (static_fn_type): Likewise.
+ * decl2.c (change_return_type): Likewise.
+ (cp_reconstruct_complex_type): Likewise.
+ * pt.c (tsubst_function_type): Likewise.
+ (unify): Likewise.
+ (tsubst): Likewise. Drop special FUNCTION_TYPE substitution code.
+
+2010-05-18 Nathan Froyd <froydnj@codesourcery.com>
+
+ * tree.c (build_min_non_dep_call_vec): Update comment.
+
+2010-05-17 Jason Merrill <jason@redhat.com>
+
+ * call.c (struct z_candidate): Add explicit_targs field.
+ (add_template_candidate_real): Set it.
+ (build_over_call): Use it to control init-list warning.
+
+ PR c++/44157
+ * call.c (build_over_call): Limit init-list deduction warning to
+ cases where the argument is actually an init-list.
+
+ PR c++/44158
+ * call.c (build_over_call): Don't do bitwise copy for move ctor.
+
+2010-05-17 Dodji Seketeli <dodji@redhat.com>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/44108
+ * decl.c (compute_array_index_type): Call mark_rvalue_use.
+
+2010-05-15 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (TYPE_NOEXCEPT_P): New macro.
+ * except.c (begin_eh_spec_block): Use MUST_NOT_THROW_EXPR if
+ TYPE_NOEXCEPT_P.
+ (finish_eh_spec_block): Adjust.
+
+2010-05-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/44148
+ * pt.c (tsubst): Unshare template argument.
+
+2010-05-15 Steven Bosscher <steven@gcc.gnu.org>
+
+ * decl.c: Include tree-iterator.h, as fixup for tree-inline.h changes.
+ * Make-lang.in: Fix dependencies accordingly.
+
+2010-05-14 Jason Merrill <jason@redhat.com>
+
+ C++ DR 475
+ * except.c (build_throw): Simplify, adjust for DR 475.
+
+ PR c++/44127
+ * except.c (dtor_nothrow): Return nonzero for type with
+ trivial destructor.
+
+ PR c++/44127
+ * cp-gimplify.c (gimplify_must_not_throw_expr): Use
+ gimple_build_eh_must_not_throw.
+
+2010-05-14 Martin Jambor <mjambor@suse.cz>
+
+ * cp-lang.c (LANG_HOOKS_FOLD_OBJ_TYPE_REF): Remove both its undef
+ and define.
+
+2010-05-14 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * call.c (build_new_method_call): Change warning text.
+ * typeck2.c (build_functional_cast): Change error text.
+
+2010-05-14 Shujing Zhao <pearly.zhao@oracle.com>
+
+ PR c++/30566
+ * name-lookup.c (pushdecl_maybe_friend): Avoid the warnings about
+ shadowing the outer parameter or variables by the declaration of
+ nested function in nested structure or class. Warn the shadowing by
+ the declaration of nested lambda expression.
+
+2010-05-13 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (cp_build_array_ref): Factor out from...
+ (build_array_ref): ...here. Drop complain parm.
+ (build_new_op): Adjust.
+ * class.c (build_vtbl_ref_1): Adjust.
+ * decl2.c (grok_array_decl): Adjust.
+ * cp-tree.h: Adjust prototypes.
+
+2010-05-13 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (cp_finish_decl): Do not worry about used attribute.
+
+2010-05-12 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_array_ref): Take complain parm.
+ * cp-tree.h: Add it to prototype.
+ * call.c (build_new_op): Pass it.
+ * class.c (build_vtbl_ref): Pass it.
+ * decl2.c (grok_array_decl): Pass it.
+
+ PR bootstrap/44048
+ PR target/44099
+ * cp-tree.def (NULLPTR_TYPE): Remove.
+ * cp-tree.h (NULLPTR_TYPE_P): New.
+ (SCALAR_TYPE_P): Use it.
+ (nullptr_type_node): New.
+ (cp_tree_index): Add CPTI_NULLPTR_TYPE.
+ * decl.c (cxx_init_decl_processing): Call record_builtin_type on
+ nullptr_type_node.
+ * cvt.c (ocp_convert): Use NULLPTR_TYPE_P instead of NULLPTR_TYPE.
+ * cxx-pretty-print.c (pp_cxx_constant): Likewise.
+ * error.c (dump_type, dump_type_prefix, dump_type_suffix): Likewise.
+ * mangle.c (write_type): Likewise.
+ * name-lookup.c (arg_assoc_type): Likewise.
+ * typeck.c (build_reinterpret_cast_1): Likewise.
+ * rtti.c (typeinfo_in_lib_p): Likewise.
+ (emit_support_tinfos): Remove local nullptr_type_node.
+
+ * cp-tree.h (UNKNOWN_TYPE): Remove.
+ * decl.c (cxx_init_decl_processing): Use LANG_TYPE instead.
+ * error.c (dumy_type, dump_type_prefix, dump_type_suffix): Likewise.
+ * typeck2.c (cxx_incomplete_type_diagnostic): Likewise.
+ * class.c (instantiate_type): Check unknown_type_node rather than
+ UNKNOWN_TYPE.
+ * name-lookup.c (maybe_push_decl): Likewise.
+ * rtti.c (get_tinfo_decl_dynamic): Likewise.
+ (get_typeid): Likewise.
+ * semantics.c (finish_offsetof): Likewise.
+
+ PR c++/20669
+ * call.c (add_template_candidate_real): If deduction fails, still
+ add the template as a non-viable candidate.
+ (equal_functions): Handle template candidates.
+ (print_z_candidate): Likewise.
+ (print_z_candidates): Likewise.
+ (build_new_function_call): Likewise.
+
+ * cp-tree.h (LOOKUP_LIST_ONLY): New.
+ * call.c (add_candidates): Enforce it.
+ (build_new_method_call): Try non-list ctor if no viable list ctor.
+ (build_user_type_conversion_1): Likewise.
+
+ * call.c (add_candidates): Distinguish between type(x) and
+ x.operator type().
+ (convert_class_to_reference): Set LOOKUP_NO_CONVERSION.
+ (build_new_method_call): Give better error for conversion op.
+
+ * call.c (add_candidates): Add first_arg and return_type parms.
+ Add special constructor/conversion op handling.
+ (convert_class_to_reference): Use it.
+ (build_user_type_conversion_1): Likewise.
+ (build_op_call): Likewise.
+ (build_new_method_call): Likewise.
+ (build_new_op): Adjust.
+ (perform_overload_resolution): Adjust.
+
+2010-05-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/34272
+ PR c++/43630
+ PR c++/34491
+ * pt.c (process_partial_specialization): Return error_mark_node
+ in case of unused template parameters in partial specialization.
+
+2010-05-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/44062
+ * semantics.c (finish_expr_stmt): Don't call mark_exp_read here...
+ * cvt.c (convert_to_void): ... but here. If expr is a COMPOUND_EXPR,
+ look at its second operand.
+
+2010-05-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/44017
+ * semantics.c (baselink_for_fns): Revert earlier change.
+
+ PR c++/44045
+ * typeck.c (cp_build_modify_expr): Complain about assignment to
+ array from init list.
+
+2010-05-10 Fabien Chêne <fabien.chene@gmail.com>
+
+ PR c++/43719
+ * decl.c (check_initializer): strip array type before checking for
+ uninitialized const or ref members.
+
+2010-05-07 Fabien Chêne <fabien.chene@gmail.com>
+
+ PR c++/43951
+ * init.c (diagnose_uninitialized_cst_or_ref_member_1): Returns the
+ error count. Emit errors only if compain is true.
+ (build_new_1): Do not return error_mark_node if
+ diagnose_uninitialized_cst_or_ref_member_1 does not diagnose any
+ errors. Delay the check for user-provided constructor.
+ (perform_member_init): Adjust.
+ * cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Change the
+ prototype.
+
+2010-05-06 Magnus Fromreide <magfr@lysator.liu.se>
+ Jason Merrill <jason@redhat.com>
+
+ Add support for C++0x nullptr.
+ * cp-tree.def: Add NULLPTR_TYPE.
+ * cp-tree.h: Add nullptr_node.
+ (cp_tree_index): Add CPTI_NULLPTR.
+ (SCALAR_TYPE_P): Add NULLPTR_TYPE.
+ * call.c (null_ptr_cst_p): Handle nullptr.
+ (standard_conversion): Likewise.
+ (convert_arg_to_ellipsis): Likewise.
+ * mangle.c (write_type): Likewise.
+ * name-lookup.c (arg_assoc_type): Likewise.
+ * parser.c (cp_parser_primary_expression): Likewise.
+ * typeck.c (cp_build_binary_op): Likewise.
+ (build_reinterpret_cast_1): Likewise.
+ * error.c (dump_type): Likewise.
+ (dump_type_prefix, dump_type_suffix): Likewise.
+ * decl.c (cxx_init_decl_processing): Likewise.
+ * cxx-pretty-print.c (pp_cxx_constant): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ * rtti.c (typeinfo_in_lib_p, emit_support_tinfos): Put
+ nullptr_t tinfo in libsupc++.
+
+2010-05-06 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (simplify_aggr_init_expr): Use INIT_EXPR.
+
+2010-04-22 Jakub Jelinek <jakub@redhat.com>
+ Dodji Seketeli <dodji@redhat.com>
+
+ PR c/18624
+ * cp-tree.h (mark_exp_read, rvalue_use, lvalue_use, type_use):
+ Declare ...
+ * expr.c (mark_exp_read, rvalue_use, lvalue_use, type_use): ... new fns.
+ * typeck.c (cxx_sizeof_expr, cxx_alignof_expr): Call type_use.
+ (decay_conversion, perform_integral_promotions): Call rvalue_use.
+ (cp_build_unary_op): Call lvalue_use.
+ * decl.c (unused_but_set_errorcount): New variable.
+ (poplevel): Issue -Wunused-but-set-variable diagnostics.
+ (duplicate_decls): Merge DECL_READ_P flags.
+ (start_cleanup_fn): Set DECL_READ_P flag.
+ (finish_function): Issue -Wunused-but-set-parameter diagnostics.
+ * tree.c (rvalue): Call rvalue_use.
+ * pt.c (convert_nontype_argument): Likewise.
+ * semantics.c (finish_expr_stmt, finish_asm_stmt, finish_typeof,
+ finish_decltype_type): Likewise.
+ * call.c (convert_like_real) <ck_identity, ck_user>: Call rvalue use.
+ (build_x_va_arg, build_new_method_call, build_over_call): Call lvalue_use
+ or rvalue_use depending on the expr.
+ * init.c (build_new, build_delete): Likewise.
+ * rtti.c (build_typeid, build_dynamic_cast_1): Likewise.
+
+2010-05-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/43787
+ * cp-gimplify.c (cp_gimplify_expr): Remove copies of empty classes.
+ * call.c (build_over_call): Don't try to avoid INIT_EXPR copies here.
+
+2010-05-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/43028
+ * pt.c (unify): Check each elt for error_mark_node.
+
+2010-05-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/38064
+ * typeck.c (cp_build_binary_op): Allow enums for <> as well.
+
+2010-05-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/43705
+ * call.c (build_new_method_call): Return error_mark_node if fns is
+ NULL_TREE.
+
+2010-05-03 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/43953
+ * pt.c (most_specialized_class): Pretend we are processing
+ a template decl during the call to coerce_template_parms.
+
+2010-05-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/42810
+ PR c++/43680
+ * decl.c (finish_enum): Use the TYPE_MIN_VALUE and TYPE_MAX_VALUE
+ from the selected underlying type unless -fstrict-enums. Set
+ ENUM_UNDERLYING_TYPE to have the restricted range.
+ * cvt.c (type_promotes_to): Use ENUM_UNDERLYING_TYPE.
+ * class.c (check_bitfield_decl): Likewise.
+
+2010-05-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/43951
+ * init.c (build_new_1): Revert the accidental checkin in
+ revision 158918.
+
+2010-04-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/43868
+ * cxx-pretty-print.c (pp_cxx_decl_specifier_seq): Move pmf handling...
+ (pp_cxx_type_specifier_seq): ...here.
+
+2010-04-30 Steven Bosscher <steven@gcc.gnu.org>
+
+ * optimize.c, parser.c, mangle.c, cp-tree.h: Do not include varray.h.
+ * Make-lang.in: Don't include varray.h dependency in CXX_TREE_H.
+
+2010-04-30 Shujing Zhao <pearly.zhao@oracle.com>
+
+ PR c++/43779
+ * typeck.c (warn_args_num): New function.
+ (convert_arguments): Use warn_args_num to print the diagnostic
+ messages.
+
+2010-04-29 Fabien Chêne <fabien.chene@gmail.com>
+
+ PR c++/43890
+ * init.c (diagnose_uninitialized_cst_or_ref_member): check for
+ user-provided constructor while recursing.
+
+2010-04-28 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/9335
+ * error.c (print_instantiation_partial_context_line): Handle
+ recursive instantiation.
+ (print_instantiation_partial_context): Likewise.
+
+2010-04-27 Jason Merrill <jason@redhat.com>
+
+ * init.c (perform_member_init): Check CLASS_TYPE_P.
+
+2010-04-27 Fabien Chêne <fabien.chene@gmail.com>
+
+ PR c++/29043
+ * init.c (perform_member_init): check for uninitialized const or
+ reference members, including array types.
+
+2010-04-24 Jason Merrill <jason@redhat.com>
+
+ * tree.c (get_fns): Split out from get_first_fn.
+ * cp-tree.h: Declare it.
+ * search.c (shared_member_p): Use it.
+ * semantics.c (finish_qualified_id_expr): Simplify.
+ (finish_id_expression): Simplify.
+
+ * semantics.c (finish_non_static_data_member): Call maybe_dummy_object
+ whenever object is NULL_TREE. Don't do 'this' capture here.
+ (finish_qualified_id_expr): Pass NULL_TREE.
+ (finish_id_expression): Likewise.
+ (lambda_expr_this_capture): Likewise.
+
+ * semantics.c (finish_qualified_id_expr): Use maybe_dummy_object
+ rather than checking current_class_ref directly.
+ (finish_call_expr): Likewise.
+
+ PR c++/43856
+ * name-lookup.c (qualify_lookup): Disqualify lambda op().
+ * class.c (current_nonlambda_class_type): New fn.
+ * semantics.c (nonlambda_method_basetype): New.
+ * cp-tree.h: Declare them.
+ * tree.c (maybe_dummy_object): Handle implicit 'this' capture.
+
+ * semantics.c (baselink_for_fns): Correct BASELINK_BINFO.
+
+ PR c++/43875
+ * semantics.c (lambda_return_type): Complain about
+ braced-init-list.
+
+ PR c++/43790
+ * tree.c (cv_unqualified): Handle error_mark_node.
+
+ PR c++/41468
+ * call.c (convert_like_real) [ck_ambig]: Just return error_mark_node
+ if we don't want errors.
+
+ PR c++/41468
+ * class.c (convert_to_base): Add complain parameter. Pass
+ ba_quiet to lookup_base if we don't want errors.
+ (build_vfield_ref): Pass complain to convert_to_base.
+ * call.c (convert_like_real): Likewise.
+ (initialize_reference): Likewise.
+ (perform_direct_initialization_if_possible): Pass complain to
+ convert_like_real.
+ * cp-tree.h: Adjust.
+
+2010-04-27 Fabien Chêne <fabien.chene@gmail.com>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/42844
+ * decl.c (check_for_uninitialized_const_var): Handle classes that need
+ constructing, too.
+ (check_initializer): Call it for classes that need constructing, too.
+ * class.c (in_class_defaulted_default_constructor): New.
+ * cp-tree.h: Declare it.
+
+2010-04-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/9335
+ * init.c (constant_value_1): Treat error_mark_node as a constant
+ if DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P is set.
+ * cvt.c (ocp_convert): Handle getting error_mark_node from
+ integral_constant_value.
+ * decl.c (compute_array_index_type): Likewise.
+
+2010-04-20 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/43800
+ PR c++/43704
+ * typeck.c (incompatible_dependent_types_p): If one of the
+ compared types if not a typedef then honour their main variant
+ equivalence.
+
+2010-04-20 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (TYPE_REF_IS_RVALUE): Remove.
+
+2010-04-19 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/43704
+ * typeck.c (structural_comptypes): Test dependent typedefs
+ incompatibility before testing for their main variant based
+ equivalence.
+
+2010-04-19 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (SCOPED_ENUM_P, UNSCOPED_ENUM_P, SET_SCOPED_ENUM_P): Use
+ ENUM_IS_SCOPED bit instead of TYPE_LANG_FLAG_5.
+
+2010-04-18 Eric Botcazou <ebotcazou@adacore.com>
+
+ * decl.c (cxx_init_decl_processing): Remove second argument in call to
+ build_common_tree_nodes.
+
+2010-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/36625
+ * parser.c (cp_parser_parenthesized_expression_list): Change
+ is_attribute_list parm to int to indicate whether or not to
+ handle initial identifier specially.
+ (cp_parser_attribute_list): Use attribute_takes_identifier_p.
+
+2010-04-13 Jason Merrill <jason@redhat.com>
+
+ * call.c (type_decays_to): Check MAYBE_CLASS_TYPE_P instead of
+ CLASS_TYPE_P.
+ * parser.c (cp_parser_lambda_expression): Complain about lambda in
+ unevaluated context.
+ * pt.c (iterative_hash_template_arg): Don't crash on lambda.
+
+2010-04-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/43641
+ * semantics.c (maybe_add_lambda_conv_op): Use build_call_a and tweak
+ return value directly.
+
+ * call.c (type_decays_to): Call cv_unqualified for non-class type.
+
+2010-04-12 Fabien Chene <fabien.chene@gmail.com>
+
+ PR c++/25811
+ * cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Declare.
+ * init.c (build_new_1): Check for uninitialized const members and
+ uninitialized reference members, when using new without
+ new-initializer. Call diagnose_uninitialized_cst_or_ref_member.
+ (diagnose_uninitialized_cst_or_ref_member): Define, call
+ diagnose_uninitialized_cst_or_ref_member_1.
+ (diagnose_uninitialized_cst_or_ref_member_1): New function.
+
+2010-04-12 Richard Guenther <rguenther@suse.de>
+
+ PR c++/43611
+ * semantics.c (expand_or_defer_fn_1): Do not keep extern
+ template inline functions.
+
+2010-04-09 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/28584
+ * typeck.c (cp_build_c_cast): Warn for casting integer to larger
+ pointer type.
+
+2010-04-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/43016
+ * decl.c (start_preparsed_function): Do defer nested functions.
+
+ PR c++/11094, DR 408
+ * cp-tree.h (VAR_HAD_UNKNOWN_BOUND, SET_VAR_HAD_UNKNOWN_BOUND): New.
+ * decl2.c (finish_static_data_member_decl): Set it.
+ * decl.c (duplicate_decls): Propagate it.
+ * pt.c (tsubst_decl): Don't substitute the domain of an array
+ VAR_DECL if it's set.
+ (regenerate_decl_from_template): Substitute it here.
+ (type_dependent_expression_p): Return true if it's set.
+ * semantics.c (finish_decltype_type): Instantiate such a variable.
+ * typeck.c (cxx_sizeof_expr): Likewise.
+ (strip_array_domain): New.
+
+ PR c++/43145
+ * name-lookup.c (current_decl_namespace): Non-static.
+ (pop_nested_namespace): Sanity check.
+ * cp-tree.h: Declare current_decl_namespace.
+ * decl.c (grokvardecl): Use it instead of current_namespace.
+ (grokfndecl): Likewise.
+
+ PR c++/38392
+ * pt.c (tsubst_friend_function): Instatiate a friend that has already
+ been used.
+
+ * pt.c (print_template_statistics): New.
+ * cp-tree.h: Declare it.
+ * tree.c (cxx_print_statistics): Call it.
+
+ PR c++/41970
+ * decl.c (grokvardecl): Tweak warning message.
+ (grokfndecl): Likewise.
+
+2010-04-07 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42697
+ *pt.c (tsubst_decl): Get the arguments of a specialization from
+ the specialization template, not from the most general template.
+
+2010-04-07 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/40239
+ * typeck2.c (process_init_constructor_record):
+ value-initialize members that are are not explicitely
+ initialized.
+
+2010-04-07 Jie Zhang <jie@codesourcery.com>
+
+ PR c++/42556
+ * typeck2.c (split_nonconstant_init_1): Drop empty CONSTRUCTOR
+ when all of its elements are non-constant and have been split out.
+
+2010-04-06 Taras Glek <taras@mozilla.com>
+ Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_class_specifier): Set class location to that
+ of IDENTIFIER_NODE instead of '{' when possible.
+ * semantics.c (begin_class_definition): Do not overide locations
+ with less precise ones.
+
+2010-04-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/43648
+ * name-lookup.c (constructor_name_p): Allow X::~X even for typedefs.
+
+ PR c++/43621
+ * pt.c (maybe_update_decl_type): Check the return value from
+ push_scope.
+
+2010-04-01 Jason Merrill <jason@redhat.com>
+
+ * decl.c (next_initializable_field): No longer static.
+ * cp-tree.h: Declare it.
+ * call.c (build_aggr_conv): Fail if there are more initializers
+ than initializable fields.
+
+ * semantics.c (maybe_add_lambda_conv_op): Use null_pointer_node
+ instead of void_zero_node.
+
+2010-03-31 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/43558
+ * cp-tree.h (TEMPLATE_TYPE_PARM_SIBLING_PARMS): New accessor macro.
+ * pt.c (end_template_parm_list): Store sibling template parms of
+ each TEMPLATE_TYPE_PARMs into its TEMPLATE_TYPE_PARM_SIBLING_PARMS.
+ (push_template_decl_real): Don't store the containing template decl
+ into the DECL_CONTEXT of TEMPLATE_TYPE_PARMs anymore.
+ * typeck.c (get_template_parms_of_dependent_type): Get sibling parms
+ of a TEMPLATE_TYPE_PARM from TEMPLATE_TYPE_PARM_SIBLING_PARMS.
+ Simplify the logic.
+
+2010-03-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/43076
+ * pt.c (push_template_decl_real): Deal better with running out of
+ scopes before running out of template parms.
+
+ PR c++/41185
+ PR c++/41786
+ * parser.c (cp_parser_direct_declarator): Don't allow VLAs in
+ function parameter context. Don't print an error if parsing
+ tentatively.
+
+ PR c++/43559
+ * pt.c (more_specialized_fn): Don't control cv-qualifier check
+ with same_type_p.
+
+2010-03-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/43509
+ * parser.c (cp_parser_qualifying_entity): Do accept enum names in
+ c++0x mode, but not other type-names.
+
+2010-03-26 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/43327
+ * pt.c (add_to_template_args): Support NULL ARGS;
+ (most_specialized_class): call coerce_template_parms on
+ template arguments passed to get_class_bindings. Use
+ add_to_template_args.
+ (unify): Handle VAR_DECLs.
+
+2010-03-26 Dodji Seketeli <dodji@redhat.com>
+
+ * cp-tree.h (get_template_parms_at_level): Change unsigned parm
+ into int.
+ * pt.c (get_template_parms_at_level): Adjust.
+
+2010-03-25 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/43206
+ * cp-tree.h (get_template_parms_at_level): Declare ...
+ * pt.c (get_template_parms_at_level): ... new function.
+ * typeck.c (get_template_parms_of_dependent_type): If a template
+ type parm's DECL_CONTEXT isn't yet set, get its siblings from
+ current_template_parms. Use get_template_parms_at_level. Remove
+ useless test.
+ (incompatible_dependent_types_p): If we get empty parms from just one
+ of the template type parms we are comparing then the template parms are
+ incompatible.
+
+2010-03-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/43502
+ * parser.c (make_declarator): Initialize id_loc.
+ (cp_parser_lambda_declarator_opt): And set it.
+
+2010-03-23 Jason Merrill <jason@redhat.com>
+
+ Make lambda conversion op and op() non-static.
+ * semantics.c (maybe_add_lambda_conv_op): Make non-static.
+ Also add the thunk function returned by the conversion op.
+ Mark the conversion deleted if the op() is variadic.
+ * decl2.c (mark_used): Give helpful message about deleted conversion.
+ * parser.c (cp_parser_lambda_declarator_opt): Don't make op() static.
+ * semantics.c (finish_this_expr): Adjust.
+ * mangle.c (write_closure_type_name): Adjust.
+ * decl.c (grok_op_properties): Don't allow it.
+ * call.c (build_user_type_conversion_1): No static conversion ops.
+ (build_op_call): Or op().
+
+ * decl2.c (change_return_type): Fix 'this' quals.
+
+2010-03-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/43333
+ * tree.c (pod_type_p): Use old meaning in C++98 mode.
+
+ PR c++/43281
+ * pt.c (contains_auto_r): New fn.
+ (do_auto_deduction): Use it.
+ (tsubst): Don't look at TREE_TYPE of a TEMPLATE_TYPE_PARM.
+
+2010-03-20 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/43081:
+ * decl2.c (grokfield): Handle invalid initializers for member
+ functions.
+
+2010-03-20 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/43375
+ * method.c (make_alias_for): Avoid crashing when DECL_LANG_SPECIFIC
+ is NULL.
+ * decl2.c (vague_linkage_p): Likewise.
+
+2010-03-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/43418
+ * parser.c (cp_parser_for_init_statement): Use NULL_TREE, not
+ false, in the cp_parser_expression_statement call.
+
+2010-03-05 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (mangle_decl): Give name collision error even without
+ ASM_OUTPUT_DEF.
+
+2010-03-04 Marco Poletti <poletti.marco@gmail.com>
+
+ * pt.c (process_partial_specialization): Use error_n instead of
+ error.
+
+2010-03-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/12909
+ * mangle.c (mangle_decl): Handle VAR_DECL, too.
+
+2010-03-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/12909
+ * mangle.c: Include cgraph.h.
+ (mangle_decl): If the mangled name will change in a later
+ ABI version, make the later mangled name an alias.
+ * method.c (make_alias_for): Copy DECL_ARGUMENTS.
+ * Make-lang.in (mangle.o): Depend on cgraph.h.
+ * method.c (make_alias_for): Handle VAR_DECL, too.
+ * decl2.c (vague_linkage_p): Rename from vague_linkage_fn_p.
+ * tree.c (no_linkage_check): Adjust.
+ * decl.c (maybe_commonize_var): Adjust.
+ * cp-tree.h: Adjust.
+
+2010-03-01 Marco Poletti <poletti.marco@gmail.com>
+
+ * pt.c (redeclare_class_template): Use error_n and inform_n.
+
+2010-02-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/42748
+ * cp-tree.h (push_tinst_level): Declare.
+ (pop_tinst_level): Likewise.
+ * pt.c (push_tinst_level): Give it external linkage.
+ (pop_tinst_level): Likewise.
+ * mangle.c (mangle_decl_string): Set the source location to that
+ of the decl while mangling.
+
+2010-02-27 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/42054
+ * pt.c (redeclare_class_template): Return false if there are erroneous
+ template parameters.
+
+2010-02-24 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ * pt.c (push_tinst_level): Replace -ftemplate-depth- with
+ -ftemplate-depth=.
+
+2010-02-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/12909
+ * mangle.c (write_type): Give -Wabi warning for old vector mangling.
+
+ * class.c (layout_class_type): Don't give -Wabi warning for a bug
+ in a previous ABI version.
+
+2010-02-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/43143
+ * typeck2.c (digest_init_r): Accept value init of array.
+
+2010-02-22 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/43126
+ * typeck.c (convert_arguments): Update error message.
+
+2010-02-22 Mike Stump <mikestump@comcast.net>
+
+ PR c++/43125
+ * decl.c (duplicate_decls): Merge DECL_PRESERVE_P.
+
+2010-02-21 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/23510
+ * error.c (print_instantiation_partial_context_line): New.
+ (print_instantiation_partial_context): Print at most 12 contexts,
+ skip the rest with a message.
+
+2010-02-21 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42824
+ * pt.c (lookup_template_class): Better support of specialization
+ of member of class template implicit instantiation.
+
+2010-02-20 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/35669
+ * call.c (conversion_null_warnings): Replace -Wconversion with
+ -Wconversion-null.
+ * cvt.c (build_expr_type_conversion): Likewise.
+
+2010-02-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/42837
+ * class.c (create_vtable_ptr): Set DECL_PACKED if type is packed.
+
+ PR c++/43108
+ * typeck.c (cp_build_binary_op): Adapt mixed complex/non handling from
+ C build_binary_op.
+ * cp-tree.h (WANT_VECTOR_OR_COMPLEX): Rename from WANT_VECTOR.
+ * cvt.c (build_expr_type_conversion): Allow COMPLEX_TYPE.
+
+ PR c++/43070
+ * semantics.c (finish_goto_stmt): Don't call decay_conversion.
+
+ PR c++/26261
+ PR c++/43101
+ * pt.c (tsubst_qualified_id): Do normal lookup in non-dependent scope.
+ (maybe_update_decl_type): New fn.
+ * parser.c (cp_parser_init_declarator): Use it.
+
+ PR c++/43109
+ * semantics.c (begin_class_definition): Don't crash on unnamed ns.
+
+2010-02-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/43075
+ * call.c (build_over_call): Don't create zero-sized assignments.
+ * cp-gimplify.c (cp_genericize_r): Don't remove them here.
+ * cp-objcp-common.c (cp_expr_size): Remove.
+ * cp-tree.h: Remove prototype.
+
+ PR c++/43069
+ * name-lookup.c (set_decl_namespace): Don't copy DECL_CONTEXT if the
+ decl we looked up doesn't match.
+
+ PR c++/43093
+ * cp-gimplify.c (cp_gimplify_expr) [INIT_EXPR]: Return if we don't
+ have an INIT_EXPR anymore.
+
+ PR c++/43079
+ * pt.c (convert_nontype_argument): Change assert to test.
+
+2010-02-16 Jason Merrill <jason@redhat.com>
+
+ * cp-gimplify.c (cp_gimplify_expr): Fix error recovery.
+
+ PR c++/43031
+ * cp-gimplify.c (cp_gimplify_expr) [MODIFY_EXPR]: Use
+ VIEW_CONVERT_EXPR for conversions between structural equality types
+ that the back end can't tell are the same.
+
+ PR c++/43036
+ * tree.c (build_cplus_array_type): Set TYPE_MAIN_VARIANT to strip
+ cv-quals from element here.
+ (cp_build_qualified_type_real): Not here. Preserve typedef name.
+
+2010-02-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/41997
+ * semantics.c (finish_compound_literal): Use
+ cp_apply_type_quals_to_decl when creating a static variable.
+
+2010-02-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/43024
+ * name-lookup.h (current_binding_level): Check for null
+ cp_function_chain.
+
+2010-02-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/43054
+ * tree.c (cp_tree_equal): Correct CALL_EXPR logic.
+
+2010-02-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/43033
+ * name-lookup.c (pushdecl_maybe_friend): Check default args of t
+ instead of x.
+
+2010-02-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/41896
+ * semantics.c (outer_lambda_capture_p): Revert.
+ (add_capture): Only finish_member_declaration if
+ we're in the lambda class.
+ (register_capture_members): New.
+ * cp-tree.h: Declare it.
+ * parser.c (cp_parser_lambda_expression): Call it.
+
+2010-02-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/41896
+ * semantics.c (outer_lambda_capture_p): Use current_function_decl
+ instead of current_class_type.
+
+2010-02-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/42983, core issue 906
+ * method.c (defaultable_fn_check): Check virtualness.
+
+2010-02-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/43016
+ * semantics.c (maybe_add_lambda_conv_op): Set DECL_INTERFACE_KNOWN.
+
+2010-02-10 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * Make-lang.in (cp/cvt.o, cp/parser.o, cp/search.o): Depend on intl.h.
+ * cvt.c (warn_ref_binding): Wrap the messages into G_() for easy
+ translation.
+ * parser.c (cp_parser_postfix_expression, cp_parser_new_type_id)
+ (cp_parser_cast_expression, cp_parser_condition, cp_parser_decltype)
+ (cp_parser_parameter_declaration)
+ (cp_parser_exception_specification_opt)
+ (cp_parser_exception_declaration): Likewise.
+ * pt.c (check_default_tmpl_args): Likewise.
+ * search.c (lookup_field_r): Likewise.
+
+2010-02-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/42399
+ * pt.c (tsubst_copy_and_build): Propagate LAMBDA_EXPR_LOCATION.
+
+2010-02-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/42370
+ * decl2.c (change_return_type): New fn.
+ * semantics.c (apply_lambda_return_type): Use it.
+ * cp-tree.h: Declare it.
+
+2010-02-05 Richard Guenther <rguenther@suse.de>
+
+ * Make-lang.in (cp/cp-lang.o): Depend on gt-cp-cp-lang.h.
+ * cp-lang.c: Include gt-cp-cp-lang.h.
+ * config-lang.in (gtfiles): Add cp/cp-lang.c.
+
+2010-02-05 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42915
+ * typeck.c (get_template_parms_of_dependent_type): Try getting
+ the template parameters fromt the type itself first.
+
+2010-02-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/4926
+ PR c++/38600
+ * mangle.c (write_unqualified_id): Split out from write_expression.
+ (write_unqualified_name): Call it.
+ (write_member_name): Likewise.
+ (write_expression): Support TEMPLATE_ID_EXPR.
+ Disambiguate operator names.
+
+ PR c++/12909
+ * mangle.c (write_type) [VECTOR_TYPE]: Change mangling with
+ -fabi-version=4.
+
+2010-02-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/41090
+ * decl.c (cp_finish_decl): Add local statics to cfun->local_decls.
+ * optimize.c (clone_body): Remap their initializers when making base
+ variants.
+ (maybe_clone_body): Complain if multiple clones aren't safe.
+
+2010-01-29 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42758
+ PR c++/42634
+ PR c++/42336
+ PR c++/42797
+ PR c++/42880
+ * cp-tree.h (NON_DEFAULT_TEMPLATE_ARGS_COUNT,
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT,
+ GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT): New accessor macros.
+ * pt.c (coerce_template_parms, type_unification_real,
+ expand_template_argument_pack, coerce_template_parameter_pack):
+ Set the non default template args count.
+ (current_template_args): Always set non defaulted
+ template args count when compiled with --enable-checking
+ (tsubst_template_args, type_unification_real): Propagate the non
+ defaulted template args count.
+ * error.c (get_non_default_template_args_count): Renamed
+ count_non_default_template_args into this. Don't calculate the
+ non default template argument count anymore. Use the new
+ accessor macros above to get it.
+ (dump_template_argument_list, dump_type, dump_decl,
+ dump_template_parms): Adjust.
+ * parser.c (cp_parser_template_argument_list): Always set defaulted
+ template args count when compiled with --enable-checking.
+
+2010-01-29 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * decl.c (redeclaration_error_message): Wrap the return messages into
+ G_() for easy translation.
+
+2010-01-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/42880
+ * semantics.c (begin_class_definition): Don't use type_as_string.
+
+2010-01-28 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42713
+ PR c++/42820
+ * typeck.c (get_template_parms_of_dependent_type): Factorized
+ this out of incompatible_template_type_parms_p
+ (incompatible_dependent_types_p): Renamed
+ incompatible_template_type_parms_p into this. Make it detect
+ two incompatible dependent typedefs too.
+ (structural_comptypes): Use incompatible_dependent_types_p.
+ * pt.c (get_template_info):
+ Handle BOUND_TEMPLATE_TEMPLATE_PARAM.
+
+2010-01-20 Janis Johnson <janis187@us.ibm.com>
+ Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_type): Mangle transparent record as member type.
+ * semantics.c (begin_class_definition): Recognize decimal classes
+ and set TYPE_TRANSPARENT_AGGR.
+
+2010-01-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/42338
+ * mangle.c (write_expression): Handle tree codes that have extra
+ arguments in the middle-end.
+
+2010-01-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/42038
+ * except.c (expand_start_catch_block): Deal correctly with
+ do_begin_catch returning error_mark_node.
+
+2010-01-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/41788
+ * class.c (layout_class_type): Set packed_maybe_necessary for packed
+ non-PODs.
+
+ PR c++/41920
+ * semantics.c (build_lambda_object): Call mark_used on captured
+ variables.
+
+ PR c++/40750
+ * decl.c (grokdeclarator): Clear type_quals for a member function
+ declared using a typedef. Don't complain about adding cv-quals
+ to a function typedef in C++0x mode.
+
+2010-01-20 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (create_array_type_for_decl): Remove set but not used
+ variable error_msg. Remove break stmts after return stmts.
+
+2010-01-19 Dodji Seketeli <dodji@redhat.com>
+
+ * error.c (dump_template_parms, count_non_default_template_args):
+ Revert fix of PR c++/42634.
+
+2010-01-18 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42634
+ * error.c (dump_template_parms): Use innermost template
+ arguments before calling count_non_default_template_args.
+ (count_non_default_template_args): We are being called with
+ template innermost arguments now. There is no need to ensure
+ that again.
+
+2010-01-18 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42766
+ * cvt.c (build_expr_type_conversion): Look through OVERLOAD.
+
+2010-01-17 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42697
+ *pt.c (tsubst_decl): Revert commit for PR c++/42697.
+
+2010-01-17 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42697
+ *pt.c (tsubst_decl): Get the arguments of a specialization from
+ the specialization template, not from the most general template.
+
+2010-01-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/42761
+ * semantics.c (finish_decltype_type): Within a template, treat
+ unresolved CALL_EXPR as dependent.
+
+2010-01-15 Dodji Seketeli <dodji@redhat.com>
+
+ * error.c (dump_template_parms,count_non_default_template_args):
+ Revert changes of PR c++/42634.
+
+2010-01-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/42674
+ * decl.c (finish_function): Don't emit -Wreturn-type warnings in
+ functions with noreturn attribute.
+
+2010-01-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/42701
+ * call.c (build_new_method_call): Don't free the vec here.
+
+ PR c++/42655
+ * call.c (convert_like_real): Do full decay_conversion for ck_rvalue.
+
+2010-01-13 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42634
+ * error.c (dump_template_parms): Use innermost template
+ arguments before calling count_non_default_template_args.
+ (count_non_default_template_args): We are being called with
+ template innermost arguments now. There is no need to ensure
+ that again.
+
+2010-01-07 Dodji Seketeli <dodji@redhat.com>
+
+ c++/40155
+ * pt.c (unify_pack_expansion): In non-deduced contexts, re-use template
+ arguments that were previously deduced.
+
+2010-01-05 Jason Merrill <jason@redhat.com>
+
+ * pt.c (unify_pack_expansion): Handle deduction from init-list.
+ * call.c (build_over_call): Don't complain about it.
+
+2010-01-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/42555
+ * pt.c (tsubst_decl): Don't apply type attributes in place.
+
+ PR c++/42567
+ * semantics.c (describable_type): Remove decltype comment and
+ semantics.
+
+
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2011 b/gcc-4.9/gcc/cp/ChangeLog-2011
new file mode 100644
index 000000000..506598965
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2011
@@ -0,0 +1,5033 @@
+2011-12-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51397
+ * semantics.c (finish_static_assert): Use %s instead of %E for
+ the error message.
+
+2011-12-27 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/23211
+ * name-lookup.c (do_class_using_decl): Use dependent_scope_p
+ instead of dependent_type_p, to check that a non-dependent
+ nested-name-specifier of a class-scope using declaration refers to
+ a base, even if the current scope is dependent.
+ * parser.c (cp_parser_using_declaration): Set
+ USING_DECL_TYPENAME_P to 1 if the DECL is not null. Re-indent a
+ 'else' close to the prior modification.
+
+2011-12-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/51507
+ * search.c (at_function_scope_p): Also check cfun.
+ * pt.c (tsubst_pack_expansion): Check it instead of
+ cp_unevaluated_operand.
+ (instantiate_template_1): Use push_to_top_level.
+
+ * tree.c (dependent_name): OFFSET_REF and BASELINK
+ are not dependent names.
+
+2011-12-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/51611
+ * cp-tree.h (CONVERT_EXPR_VBASE_PATH): New.
+ * class.c (build_base_path): Defer vbase conversion in an NSDMI.
+ * tree.c (bot_replace): Expand it here.
+ * cp-gimplify.c (cp_genericize_r): Make sure deferred conversion
+ doesn't leak into GENERIC.
+
+2011-12-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51305
+ * semantics.c (massage_constexpr_body): Reorder conditionals, make
+ sure a BIND_EXPR embedded in a MUST_NOT_THROW_EXPR is handled.
+
+2011-12-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51621
+ * tree.c (diagnose_non_constexpr_vec_init): For value initialization
+ pass void_type_node, not void_zero_node, to build_vec_init_elt.
+
+2011-12-20 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/49951
+ * decl.c (cxx_maybe_build_cleanup): Don't set location of the call
+ to the destructor.
+
+2011-12-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51612
+ * semantics.c (is_valid_constexpr_fn): In case of constexpr
+ constructors also check for virtual base classes.
+
+2011-12-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51328
+ * pt.c (convert_template_argument): Early error out and return
+ error_mark_node for invalid uses of destructors as types.
+
+2011-12-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/51530
+ * pt.c (unify): Handle NULLPTR_TYPE.
+
+ PR c++/51526
+ * semantics.c (build_data_member_initialization): Handle
+ delegating constructor.
+ (build_constexpr_constructor_member_initializers): Likewise.
+
+ PR c++/51553
+ * cp-tree.h (LOOKUP_LIST_INIT_CTOR): Rename from
+ LOOKUP_NO_COPY_CTOR_CONVERSION.
+ (add_list_candidates): Set it earlier.
+ (add_candidates): Don't check explicit on ctors when it's set.
+ (add_function_candidate): Check it even when LOOKUP_ONLYCONVERTING
+ is set.
+
+ PR c++/51553
+ * call.c (add_function_candidate): Allow conversions for the copy
+ parm in list-initialization unless the argument is an init-list.
+
+2011-12-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/51619
+ * semantics.c (cxx_eval_vec_init_1): If init is NULL for
+ multidimensional array, just set eltinit to NULL_TREE.
+
+ * cp-gimplify.c (gimplify_must_not_throw_expr): Use
+ gimple_seq_add_stmt_without_update instead of gimplify_seq_add_stmt.
+
+2011-12-19 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51477
+ * search.c (lookup_member): Get out early on invalid base type.
+
+2011-12-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/51489
+ * semantics.c (cxx_eval_outermost_constant_expr): Check for
+ conversion from pointer to integer here.
+ (cxx_eval_constant_expression) [NOP_EXPR]: Not here.
+
+2011-12-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * semantics.c (finish_compound_literal): Don't call check_narrowing
+ if !(complain & tf_warning_or_error).
+
+2011-12-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/51588
+ * parser.c (cp_parser_ptr_operator): Reject pointer to member of enum.
+
+2011-12-17 Richard Henderson <rth@redhat.com>
+
+ PR bootstrap/51072
+ * config-lang.in: Revert last change.
+
+2011-12-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/51586
+ * parser.c (cp_parser_check_class_key): Handle error_mark_node.
+
+ PR c++/51587
+ * decl.c (start_enum): Avoid using ENUM_UNDERLYING_TYPE on a
+ non-enum.
+
+2011-12-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/51416
+ * init.c (build_value_init_noctor): Check for incomplete type.
+
+2011-12-16 Richard Henderson <rth@redhat.com>
+
+ PR bootstrap/51072
+ * config-lang.in (target_libs): Include target-libitm.
+
+2011-12-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/51461
+ * decl.c (check_static_variable_definition): Check COMPLETE_TYPE_P
+ before literal_type_p.
+
+ PR c++/51331
+ * class.c (convert_to_base_statically): Just call
+ build_simple_base_path.
+ (build_simple_base_path): Check field offset.
+
+2011-12-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/51458
+ * decl.c (has_designator_problem): New.
+ (reshape_init_r): Check for improper use of
+ designated initializers.
+
+2011-12-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/51463
+ * decl.c (grokdeclarator): Set DECL_INITIAL of decl
+ to error_mark_node to disallow NSDMI if declspecs->storage_class
+ is sc_static.
+ * parser.c (cp_parser_late_parse_one_default_arg): Return early
+ if default_arg is error_mark_node.
+
+ PR c/51360
+ * semantics.c (finish_omp_clauses): For OMP_CLAUSE_NUM_THREADS_EXPR
+ and OMP_CLAUSE_SCHEDULE_CHUNK_EXPR call mark_rvalue_use.
+
+2011-12-15 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51473
+ * decl.c (check_tag_decl): Error out on auto specifier with no
+ declarator.
+
+2011-12-15 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR libstdc++/51365
+ * cp-tree.h (CPTK_IS_FINAL): Add.
+ * parser.c (cp_parser_translation_unit): Handle RID_IS_FINAL.
+ (cp_parser_primary_expression, cp_parser_trait_expr): Likewise.
+ * semantics.c (trait_expr_value, finish_trait_expr): Handle
+ CPTK_IS_FINAL.
+ * cxx-pretty-print.c (pp_cxx_trait_expression): Likewise.
+
+2011-12-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/51554
+ * semantics.c (cxx_eval_indirect_ref): Fix sanity check.
+
+ PR c++/51248
+ * decl.c (copy_type_enum): Also update variants.
+ (finish_enum): Allow variants of complete enums.
+
+2011-12-14 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51475
+ * call.c (struct conversion)<u.next>: Update comment.
+ (next_conversion): New static function.
+ (convert_like_real): Use it.
+
+ PR c++/51476
+ * pt.c (convert_nontype_argument): Don't call maybe_constant_value
+ for PTRMEM_CST nodes.
+
+2011-12-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/51406
+ PR c++/51161
+ * typeck.c (build_static_cast_1): Fix cast of lvalue to
+ base rvalue reference.
+
+2011-12-13 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51464
+ * semantics.c (begin_lambda_type): Check begin_class_definition return
+ value for error_mark_node.
+ * parser.c (cp_parser_lambda_expression): Check begin_lambda_type
+ return value for error_mark_node.
+
+2011-12-13 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/14258
+ * cp-tree.h (USING_DECL_TYPENAME_P): New macro.
+ * parser.c (cp_parser_nonclass_name): Handle using declarations
+ that refer to a dependent type.
+ (cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if
+ the using declaration refers to a dependent type.
+
+2011-12-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/51496
+ * parser.c (cp_parser_omp_for_loop): When determining whether
+ to use cp_parser_omp_for_incr or cp_parser_expression and when
+ calling cp_parser_omp_for_incr, use real_decl instead of decl.
+
+2011-12-12 Torvald Riegel <triegel@redhat.com>
+
+ * semantics.c (finish_transaction_stmt, build_transaction_expr):
+ Accept new noexcept parameter and handle it.
+ * cp-tree.h (finish_transaction_stmt, build_transaction_expr): Adapt
+ declarations.
+ * parser.c (cp_parser_exception_specification_opt): Extract
+ noexcept-specification parsing to ...
+ (cp_parser_noexcept_specification_opt): ...here. Allow for parsing
+ non-constexpr noexcept arguments.
+ (cp_parser_transaction, cp_parser_transaction_expression): Parse
+ and handle noexcept-specifications.
+ (cp_parser_function_transaction): Adapt to finish_transaction_stmt
+ change.
+ * pt.c (tsubst_expr): Adapt to new noexcept parameters when
+ building transactions.
+
+2011-12-12 Torvald Riegel <triegel@redhat.com>
+
+ * cp-tree.def (MUST_NOT_THROW_EXPR): Add condition parameter.
+ * cp-tree.h (MUST_NOT_THROW_COND): New.
+ (build_must_not_throw_expr): Declare.
+ * dump.c (cp_dump_tree): Dump MUST_NOT_THROW_EXPR condition.
+ * except.c (build_must_not_throw_expr): New.
+ (initialize_handler_parm): Use it.
+ (begin_eh_spec_block, wrap_cleanups_r): Adapt to condition.
+ * pt.c (tsubst_expr): Handle MUST_NOT_THROW_EXPR.
+
+2011-12-12 Richard Guenther <rguenther@suse.de>
+
+ PR lto/51262
+ * tree.c (cp_free_lang_data): No longer clear anonymous names.
+
+2011-12-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/51151
+ * call.c (perform_implicit_conversion_flags): Remove earlier kludge.
+ * parser.c (cp_parser_omp_for_loop): Use cp_parser_omp_for_incr
+ in templates even if decl isn't type-dependent.
+
+2011-12-09 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51289
+ * cp-tree.h (TYPE_TEMPLATE_INFO): Rewrite this accessor macro to
+ better support aliased types.
+ (TYPE_ALIAS_P): Don't crash on TYPE_NAME nodes that are not
+ TYPE_DECL.
+ * pt.c (find_parameter_packs_r): Handle types aliases.
+ (push_template_decl_real): Check for bare parameter packs in the
+ underlying type of an alias template.
+
+2011-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/51318
+ * typeck.c (build_x_conditional_expr): Restrict glvalue games to C++11.
+
+ PR c++/51459
+ * pt.c (tsubst_expr) [DECL_EXPR]: Handle capture proxies properly.
+ * semantics.c (insert_capture_proxy): No longer static.
+ * cp-tree.h: Declare it.
+
+2011-12-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/51401
+ * decl.c (grokdeclarator): Error for auto on non-static data members.
+
+ PR c++/51429
+ * typeck2.c (cxx_incomplete_type_diagnostic): Don't
+ ICE if TREE_OPERAND (value, 1) is overloaded.
+
+ PR c++/51229
+ * decl.c (reshape_init_class): Complain if d->cur->index is
+ INTEGER_CST.
+ * parser.c (cp_parser_initializer_list): If cp_parser_parse_definitely
+ fails, clear designator.
+
+ PR c++/51369
+ * init.c (build_value_init): Allow array types even when
+ processing_template_decl.
+
+2011-12-07 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/51420
+ * parser.c (lookup_literal_operator): Check that declaration is an
+ overloaded function.
+
+2011-12-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/51430
+ * pt.c (tsubst_decl): Don't call strip_array_domain on
+ error_mark_node.
+
+2011-12-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51431
+ * init.c (build_value_init): Check build_aggr_init_expr return
+ value for error_mark_node.
+
+2011-12-06 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51427
+ * parser.c (cp_parser_check_class_key): Add note about earlier
+ declaration.
+
+2011-12-05 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/51319
+ * semantics.c (finish_id_expression): Strip using declarations
+ early in the function.
+
+2011-12-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51399
+ * init.c (perform_member_init): Early return if init is error_mark_node.
+
+2011-12-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51414
+ * semantics.c (finish_underlying_type): Use %qT, not %qE for the
+ error message.
+
+2011-12-05 Jason Merrill <jason@redhat.com>
+
+ * init.c (expand_default_init): Unshare args in ctor delegation.
+
+2011-12-05 Ville Voutilainen <ville.voutilainen@gmail.com>
+ Pedro Lamarão <pedro.lamarao@gmail.com>
+
+ Implement C++11 delegating constructors.
+ * cp-tree.h (enum cpp0x_warn_str): Add CPP0X_DELEGATING_CTORS.
+ * error.c (maybe_warn_cpp0x): Adjust.
+ * parser.c (cp_parser_mem_initializer_list): Use it. Diagnose
+ multiple initializers if a delegating initializer is present.
+ * call.c (build_special_member_call): Convert an assert into an if.
+ * init.c (perform_target_ctor): New.
+ (emit_mem_initializers): Use it.
+ (expand_member_init, expand_default_init): Adjust.
+
+2011-12-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51404
+ * typeck2.c (build_functional_cast): Early return error_mark_node
+ for invalid uses of 'auto'.
+ * parser.c (cp_parser_direct_declarator): When
+ cp_parser_constant_expression returns error do not produce further
+ diagnostic for the bound.
+
+2011-12-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51313
+ * call.c (null_ptr_cst_p): STRIP_NOPS in c++11 mode too.
+
+2011-12-01 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_new_method_call_1): Handle aggregate initialization.
+ * tree.c (stabilize_init): Handle CONSTRUCTOR.
+
+2011-12-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51326
+ * call.c (build_user_type_conversion_1): Early return NULL if
+ expr is NULL_TREE.
+
+2011-12-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51367
+ * pt.c (unify_inconsistency): Use either %qT or %qE depending on
+ whether parm is a type or non-type parameter.
+
+2011-11-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/51009
+ * name-lookup.c (push_to_top_level): Set stmts_are_full_exprs_p.
+ * decl.c (build_aggr_init_full_exprs): Just assert that it's true.
+ (check_initializer): Here too.
+
+2011-11-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51299
+ * rtti.c (ifnonnull): Use nullptr_node.
+ (build_dynamic_cast_1): Call cp_truthvalue_conversion instead
+ of c_common_truthvalue_conversion.
+
+2011-11-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51227
+ * pt.c (instantiate_class_template_1): If lambda_function (type)
+ is NULL_TREE do not instantiate_decl.
+
+2011-11-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51290
+ * class.c (build_base_path): For the null pointer check use
+ nullptr_node instead of integer_zero_node.
+
+2011-11-22 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51145
+ * decl.c (check_elaborated_type_specifier): Gracefully handle
+ error_mark_node. Accept bound template template parameters.
+ Update diagnostics for alias template specializations. Update
+ comment.
+ * parser.c (cp_parser_elaborated_type_specifier): Use
+ check_elaborated_type_specifier for simple-template-ids as well.
+
+2011-11-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51265
+ * semantics.c (finish_decltype_type): Handle PTRMEM_CST.
+
+2011-11-22 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51143
+ * parser.c (cp_parser_alias_declaration): Don't allow type
+ definition in templates.
+
+2011-11-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51196
+ * typeck.c (cp_build_binary_op, [case EQ_EXPR]): For targets having
+ TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta, do here
+ the -Wzero-as-null-pointer-constant warning for pmf == 0.
+
+2011-11-21 Torvald Riegel <triegel@redhat.com>
+
+ * pt.c (tsubst_copy_and_build): Handle TRANSACTION_EXPR.
+
+2011-11-21 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/50958
+ * parser.c (lookup_literal_operator): New.
+ (cp_parser_userdef_char_literal): Use it.
+ (cp_parser_userdef_numeric_literal): Use it.
+ (cp_parser_userdef_string_literal): Use lookup_name.
+
+2011-11-20 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_pack_expansion): Fix SFINAE.
+
+ PR c++/48322
+ * cp-tree.h (PACK_EXPANSION_EXTRA_ARGS): New.
+ * cp-tree.def (EXPR_PACK_EXPANSION): Add an operand for it.
+ * pt.c (tsubst_pack_expansion): Set and use it.
+ (iterative_hash_template_arg): Hash it.
+ (template_args_equal): Compare it.
+ (comp_template_args_with_info): Handle nulls.
+ * tree.c (cp_walk_subtrees): Walk it.
+ * typeck.c (structural_comptypes): Compare it.
+ * ptree.c (cxx_print_type): Print it.
+
+ * pt.c (type_unification_real): Set input_location
+ during default arg instantiation.
+
+2011-11-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51230
+ * pt.c (unify_inconsistency): Handle non-type parameters better.
+ * error.c (dump_expr): Handle TEMPLATE_TEMPLATE_PARM.
+
+2011-11-20 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51194
+ * pt.c (lookup_template_class_1): Go out early if the type of the
+ template is error_mark_node.
+
+2011-11-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51216
+ * semantics.c (potential_constant_expression_1): Handle IF_STMT,
+ DO_STMT, FOR_STMT, and WHILE_STMT.
+
+2011-11-18 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/51188
+ * search.c (lookup_field_1): Handle USING_DECLs for the storted
+ case.
+
+2011-11-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51150
+ * pt.c (tsubst_copy_and_build): Handle FIX_TRUNC_EXPR.
+
+2011-11-18 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51191
+ * pt.c (primary_template_instantiation_p): Don't forget to
+ consider alias declarations.
+
+2011-11-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/51186
+ * decl.c (grokdeclarator): Improve C++98 trailing return diagnostic.
+
+ N3203
+ * class.c (add_implicitly_declared_members): Update move
+ conditions.
+
+ PR c++/51137
+ * class.c (build_base_path): Don't do calculation in templates.
+
+2011-11-15 Torvald Riegel <triegel@redhat.com>
+
+ * parser.c (cp_parser_transaction_expression): Require parentheses
+ when parsing transaction expressions.
+
+2011-11-14 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/51107
+ * typeck.c (check_literal_operator_args): Add processing_specialization
+ to check for void template fn. Test for exact arity for non-template fn.
+
+2011-11-14 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/6936
+ PR c++/25994
+ PR c++/26256
+ PR c++/30195
+ * search.c (lookup_field_1): Look through USING_DECL.
+ (lookup_field_r): Call lookup_fnfields_slot instead of
+ lookup_fnfields_1.
+ * semantics.c (finish_member_declaration): Remove the check that
+ prevents USING_DECLs from being verified by
+ pushdecl_class_level. Call add_method for using declarations that
+ designates functions if the using declaration is in a template
+ class. Set DECL_IGNORED_P on class-scope using declarations.
+ * typeck.c (build_class_member_access_expr): Handle USING_DECLs.
+ * class.c (check_field_decls): Keep using declarations.
+ (add_method): Remove two diagnostics about conflicting using
+ declarations.
+ * parser.c (cp_parser_nonclass_name): Handle USING_DECLs.
+ * decl.c (start_enum): Call xref_tag whenever possible.
+ * cp-tree.h (strip_using_decl): Declare, and reident the previous
+ function.
+ * name-lookup.c (strip_using_decl): New function.
+ (supplement_binding_1): Call strip_using_decl on decl and
+ bval. Perform most of the checks with USING_DECLs stripped. Also
+ check that the target decl and the target bval does not refer to
+ the same declaration. Allow pushing an enum multiple times in a
+ template class. Adjustment to diagnose using redeclarations. Call
+ diagnose_name_conflict.
+ (push_class_level_binding): Call strip_using_decl on decl and
+ bval. Perform most of the checks with USING_DECLs stripped. Return
+ true if both decl and bval refer to USING_DECLs and are dependent.
+ (diagnose_name_conflict): New function.
+
+2011-11-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/986
+ * call.c (set_up_extended_ref_temp): Warn about references
+ bound to non-static reference members.
+ * init.c (perform_member_init): Pass in the member.
+
+ PR c++/51060
+ * cp-gimplify.c (cp_gimplify_expr): Leave clobbers alone.
+
+2011-11-11 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/50976
+ * typeck.c (check_literal_operator_args): Reorganize test for string
+ operators so size_t search depends on finding string first.
+
+2011-11-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/50372
+ * pt.c (convert_nontype_argument_function): Allow decls with
+ internal linkage in C++11.
+ (convert_nontype_argument): Likewise.
+
+ PR c++/50973
+ * decl2.c (mark_used): Defer synthesis of virtual functions.
+ * method.c (use_thunk): Make sure the target function has
+ DECL_INTERFACE_KNOWN.
+
+ PR c++/51079, DR 495
+ * call.c (joust): Check the second conversion sequence
+ before checking templates.
+
+2011-11-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50837
+ * pt.c (tsubst_copy_and_build) [IDENTIFIER_NODE]: In C++11 mode
+ pass allow_non_integral_constant_expression_p = true to
+ finish_id_expression.
+
+2011-11-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/50972
+ * pt.c (maybe_instantiate_noexcept): Check the return value of
+ push_tinst_level.
+
+ PR c++/51046
+ * parser.c (cp_parser_range_for): check_for_bare_parameter_packs.
+
+ PR c++/51029
+ * class.c (build_base_path): Don't ICE in fold_non_dependent_expr.
+
+ * Make-lang.in (check_g++_parallelize): Add dg-torture.exp.
+ (check-c++0x): Obsolete.
+
+ * pt.c (invalid_nontype_parm_type_p): Avoid printing "<type error>".
+
+ * pt.c (convert_nontype_argument): Only integral arguments
+ get early folding.
+
+ * parser.c (cp_parser_alias_declaration): Don't do semantic
+ processing if parsing failed.
+
+2011-11-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51045
+ * init.c (build_new_1, build_vec_delete_1, build_delete):
+ Use nullptr_node.
+
+2011-11-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51047
+ * search.c (lookup_member): Change to take also a tsubst_flags_t
+ parameter.
+ (lookup_field, lookup_fnfields): Adjust calls.
+ * typeck.c (lookup_destructor, finish_class_member_access_expr,
+ build_ptrmemfunc_access_expr): Likewise.
+ * class.c (handle_using_decl, maybe_note_name_used_in_class):
+ Likewise.
+ * pt.c (resolve_typename_type): Likewise.
+ * semantics.c (lambda_function): Likewise.
+ * parser.c (cp_parser_perform_range_for_lookup,
+ cp_parser_lookup_name): Likewise.
+ * friend.c (make_friend_class): Likewise.
+ * name-lookup.c (pushdecl_maybe_friend_1, get_class_binding,
+ do_class_using_decl, lookup_qualified_name): Likewise.
+ * cp-tree.h (lookup_member): Adjust declaration.
+
+2011-11-09 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51043
+ * cp-tree.h (TYPE_ALIAS_P, TYPE_TEMPLATE_INFO): Don't crash on
+ NULL TYPE_NAME.
+
+ PR c++/51027
+ * parser.c (cp_parser_alias_declaration): Require ';' at the end
+ of the declaration.
+
+2011-11-09 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/51032
+ * decl2.c (check_member_template): Accept alias templates and ...
+ * parser.c (cp_parser_alias_declaration): ... use it here.
+
+2011-11-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/50835
+ * typeck.c (build_x_conditional_expr): Preserve lvalue/xvalueness.
+ * tree.c (lvalue_kind) [NON_DEPENDENT_EXPR]: Return clk_ordinary
+ in C++98.
+
+2011-11-08 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/51010
+ * error.c (dump_expr): Handle SSA_NAMEs.
+
+2011-11-07 Richard Henderson <rth@redhat.com>
+ Aldy Hernandez <aldyh@redhat.com>
+ Torvald Riegel <triegel@redhat.com>
+
+ Merged from transactional-memory.
+
+ * call.c (build_new_function_call): Call tm_malloc_replacement.
+ * class.c (check_bases): Compute transaction attributes for the
+ class based on its base classes.
+ (look_for_tm_attr_overrides, set_one_vmethod_tm_attributes,
+ set_method_tm_attributes): New.
+ (finish_struct_1): Call set_method_tm_attributes.
+ * cp-tree.h (begin_transaction_stmt, finish_transaction_stmt,
+ build_transaction_expr): Declare.
+ (TRANSACTION_EXPR_IS_STMT): New.
+ * decl.c (push_cp_library_fn): Set attribute to transaction_safe.
+ * except.c (do_get_exception_ptr): Apply transaction_pure.
+ (do_begin_catch): Mark _ITM_cxa_begin_catch transaction_pure and
+ record as transactional-memory wrapper.
+ (do_end_catch): Similarly for _ITM_cxa_end_catch.
+ (do_allocate_exception): Similarly for _ITM_cxa_allocate_exception.
+ (build_throw): Similarly for _ITM_cxa_throw. Make __cxa_rethrow pure.
+ * parser.h (struct cp_parser): Add in_transaction flag.
+ * parser.c (enum non_integral_constant): Add NIC_TRANSACTION.
+ (cp_parser_non_integral_constant_expression): Handle NIC_TRANSACTION.
+ (enum required_token): Add transaction tokens.
+ (cp_parser_transaction, cp_parser_transaction_expression,
+ cp_parser_function_transaction, cp_parser_transaction_cancel,
+ cp_parser_txn_attribute_opt): New.
+ (cp_parser_unary_expression): Handle RID_TRANSACTION*.
+ (cp_parser_statement, cp_parser_function_definition_after_declarator,
+ cp_parser_token_starts_function_definition_p): Same.
+ (cp_parser_required_error): Handle RT_TRANSACTION*.
+ * pt.c (tsubst_expr): Handle TRANSACTION_EXPR.
+ * semantics.c (begin_transaction_stmt, finish_transaction_stmt,
+ build_transaction_expr): New.
+
+2011-11-08 Dodji Seketeli <dodji@redhat.com>
+
+ Fix context handling of alias-declaration
+ * decl.c (start_decl): Update comment.
+ * error.c (dump_alias_template_specialization): Dump the context
+ of the specialization.
+ * parser.c (cp_parser_alias_declaration): Call pop_scope on the
+ pushed scope yielded by start_decl.
+
+2011-11-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50864
+ * parser.c (cp_parser_postfix_dot_deref_expression): Reject invalid
+ uses of '->' and '.' as postfix-expression in namespace scope.
+
+2011-11-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/50848
+ * pt.c (tsubst_copy_and_build) [CALL_EXPR]: Don't crash
+ if lookup finds a non-function.
+
+ PR c++/50863
+ * parser.c (cp_parser_initializer_list): Parse C99
+ array designators tentatively.
+
+ PR c++/50870
+ * pt.c (tsubst_copy): Handle NAMESPACE_DECL.
+ (tsubst_copy_and_build) [COMPONENT_REF]: Handle a still-dependent
+ object.
+
+2011-11-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * pt.c (tsubst_copy_and_build): Fix qualified_name_lookup_error
+ call in case COMPONENT_REF.
+
+2011-11-07 Jason Merrill <jason@redhat.com>
+ Dodji Seketeli <dodji@redhat.com>
+
+ Support C++11 alias-declaration
+ PR c++/45114
+ * cp-tree.h (TYPE_DECL_ALIAS_P, TYPE_ALIAS_P)
+ (DECL_TYPE_TEMPLATE_P, DECL_ALIAS_TEMPLATE_P): New accessor
+ macros.
+ (TYPE_TEMPLATE_INFO): Get template info of an alias template
+ specializations from its TYPE_DECL.
+ (SET_TYPE_TEMPLATE_INFO): Set template info of alias template
+ specializations into its TYPE_DECL.
+ (DECL_CLASS_TEMPLATE_P): Re-write using the new
+ DECL_TYPE_TEMPLATE_P.
+ (enum cp_decl_spec): Add new ds_alias enumerator.
+ (alias_type_or_template_p, alias_template_specialization_p):
+ Declare new functions.
+ * parser.c (cp_parser_alias_declaration): New static function.
+ (cp_parser_check_decl_spec): Add "using" name for the `alias'
+ declspec.
+ (cp_parser_type_name): Update comment. Support simple-template-id
+ representing alias template specializations in c++0x mode.
+ (cp_parser_qualifying_entity): Update comment. Use
+ cp_parser_type_name.
+ (cp_parser_block_declaration): Handle alias-declaration in c++11.
+ Update comment.
+ (cp_parser_template_id): Handle specializations of alias
+ templates.
+ (cp_parser_member_declaration): Add alias-declaration production
+ to comment. Support alias-declarations.
+ (cp_parser_template_declaration_after_export): Handle alias
+ templates in c++11.
+ * decl.c (make_typename_type, make_unbound_class_template): Accept
+ alias templates.
+ (grokdeclarator): Set TYPE_DECL_ALIAS_P on alias
+ declarations.
+ * decl2.c (grokfield): Move template creation after setting up the
+ TYPE_DECL of the alias, so that the TEMPLATE_DECL of the alias
+ template actually carries the right type-id of the alias
+ declaration.
+ * pt.c (alias_type_or_template_p)
+ (alias_template_specialization_p): Define new public functions.
+ (maybe_process_partial_specialization): Reject partial
+ specializations of alias templates.
+ (primary_template_instantiation_p): Consider alias template
+ instantiations.
+ (push_template_decl_real): Assert that TYPE_DECLs of alias
+ templates are different from those of class template. Store
+ template info onto the TYPE_DECL of the alias template.
+ (convert_template_argument): Strip aliases from template
+ arguments.
+ (lookup_template_class_1): Handle the creation of the
+ specialization of an alias template.
+ (tsubst_decl): Create a substituted copy of the TYPE_DECL of an
+ member alias template.
+ (tsubst): Handle substituting into the type of an alias template.
+ Handle substituting UNBOUND_CLASS_TEMPLATE into
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+ (do_type_instantiation): Better diagnostics when trying to
+ explicitely instantiate a non-class template.
+ * search.c (lookup_field_1, lookup_field_r): Support looking up
+ alias templates.
+ * semantics.c (finish_template_type): For instantiations of alias
+ templates, return the TYPE_DECL of the actual alias and not the
+ one of the aliased type.
+ * error.c (dump_alias_template_specialization): New static
+ function.
+ (dump_type): Handle printing of alias templates and their
+ specializations. templates.
+ (dump_aggr_type): For specialization of alias templates, fetch
+ arguments from the right place.
+ (dump_decl): Print an alias-declaration like `using decl = type;'
+ (dump_template_decl): Support printing of alias templates.
+
+2011-11-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/35688
+ * decl2.c (constrain_visibility): Return void. Add tmpl parm
+ which gives the constraint priority over an attribute.
+ (constrain_visibility_for_template, determine_visibility): Adjust.
+ * pt.c (instantiate_class_template_1): Call determine_visibility.
+
+ PR c++/33255
+ * decl.c (save_function_data): Clear local_typedefs.
+
+ * decl.c (cp_finish_decl): Only make_tree_vector if we're calling
+ check_initializer.
+
+2011-11-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/35688
+ * decl2.c (constrain_visibility): Check decl_has_visibility_attr
+ rather than DECL_VISIBILITY_SPECIFIED.
+
+2011-11-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/47695
+ * decl2.c (mark_used): Early return false after error or sorry.
+ * cp-tree.h (mark_used): Adjust declaration.
+ * semantics.c (finish_id_expression): Check mark_used return value.
+
+2011-11-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/48370
+ * decl.c (cp_finish_decl): Mostly revert previous change.
+
+2011-11-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/26714
+ * init.c (perform_member_init): Strip TARGET_EXPR around NSDMI.
+ Do temporary lifetime extension.
+
+ PR c++/48370
+ * decl.c (cp_finish_decl): Run cleanups in the right order.
+
+2011-11-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR c++/50608
+ * semantics.c (finish_offsetof): Adjust call to fold_offsetof.
+ * typeck.c (cp_build_addr_expr_1): Call fold_offsetof_1.
+
+2011-11-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * typeck.c (build_indirect_ref): Use ATTRIBUTE_UNUSED.
+ * mangle.c (write_unnamed_type_name): Likewise.
+
+2011-11-04 Magnus Fromreide <magfr@lysator.liu.se>
+
+ * parser.c (cp_parser_enumerator_list): Do not warn about
+ trailing commas in C++0x mode.
+
+2011-11-04 Olivier Goffart <olivier@woboq.com>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/50965
+ * class.c (check_field_decls): NSDMI makes a class non-aggregate.
+
+2011-11-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/48420
+ * call.c (conversion_null_warnings): For 'false' to NULL pointer,
+ just check that TREE_TYPE (expr) is a BOOLEAN_TYPE.
+
+2011-11-04 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/50941
+ * parser.c (cp_parser_userdef_string_literal): Fix string length.
+
+2011-11-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/48370
+ * call.c (extend_ref_init_temps, extend_ref_init_temps_1): New.
+ (set_up_extended_ref_temp): Use it. Change cleanup parm to VEC.
+ (initialize_reference): Just call convert_like.
+ * decl.c (grok_reference_init): Just call initialize_reference.
+ (build_init_list_var_init): Remove.
+ (check_initializer): Change cleanup parm to VEC. Handle references
+ like other types. Call perform_implicit_conversion instead
+ of build_init_list_var_init. Don't use build_aggr_init for
+ aggregate initialization of arrays.
+ (cp_finish_decl): Change cleanup to VEC.
+ * typeck2.c (store_init_value): Call extend_ref_init_temps.
+ Use build_vec_init for non-constant arrays.
+ * init.c (expand_aggr_init_1): Adjust.
+ (build_vec_init): Avoid re-converting an initializer
+ that's already digested.
+ * mangle.c (mangle_ref_init_variable): Add a discriminator.
+ * cp-tree.h: Adjust.
+ * typeck.c (convert_for_initialization): Adjust.
+ * decl2.c (maybe_emit_vtables): Adjust.
+
+2011-11-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/50930
+ * init.c (build_aggr_init): Don't set LOOKUP_ONLYCONVERTING
+ if the initializer has TARGET_EXPR_DIRECT_INIT_P.
+ (expand_default_init): An initializer with TARGET_EXPR_DIRECT_INIT_P
+ or TARGET_EXPR_LIST_INIT_P doesn't need more processing.
+ * tree.c (bot_manip): Propagate TARGET_EXPR_IMPLICIT_P,
+ TARGET_EXPR_LIST_INIT_P, TARGET_EXPR_DIRECT_INIT_P.
+ * call.c (convert_like_real): Set TARGET_EXPR_DIRECT_INIT_P
+ as appropriate on list-value-initialization.
+
+ * parser.c (cp_parser_decl_specifier_seq): Change "C++0x" to
+ "C++11" in warnings.
+ (cp_lexer_get_preprocessor_token): Likewise.
+ (cp_parser_binary_expression): Likewise.
+
+2011-11-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50810
+ * typeck2.c (check_narrowing): Adjust OPT_Wnarrowing diagnostics.
+ (digest_init_r): Call check_narrowing irrespective of the C++ dialect.
+ * decl.c (check_initializer): Likewise.
+ * semantics.c (finish_compound_literal): Likewise.
+
+2011-11-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50956
+ * typeck.c (build_const_cast_1): Fix -Wcast-qual for false
+ comp_ptr_ttypes_const.
+
+2011-11-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * Make-lang.in (g++spec.o): Pass SHLIB instead of SHLIB_LINK.
+
+2011-11-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44277
+ * cvt.c (cp_convert_to_pointer): Warn for zero as null pointer
+ constant.
+ * typeck.c (cp_truthvalue_conversion): Handle pointers and member
+ function pointers under c_inhibit_evaluation_warnings; use
+ nullptr_node for data member pointers.
+ (cp_build_binary_op): Tweak, just forward to cp_convert op1,
+ either a nullptr_node or an integer_zero_node.
+ (build_ptrmemfunc): Use nullptr_node.
+ * init.c (build_zero_init_1): Likewise.
+
+2011-11-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/50500
+ DR 1082
+ * search.c (lookup_fnfields_idx_nolazy): Split out from...
+ (lookup_fnfields_1): ...here.
+ (lookup_fnfields_slot_nolazy): Use it.
+ * cp-tree.h: Declare it.
+ * class.c (type_has_move_assign): Use it.
+ (type_has_user_declared_move_assign): Likewise.
+
+2011-10-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/50920
+ * class.c (check_field_decl): Change c++0x in diags to c++11.
+ * error.c (maybe_warn_cpp0x): Likewise.
+ * parser.c (cp_parser_diagnose_invalid_type_name): Likewise.
+ * pt.c (check_default_tmpl_args): Likewise.
+
+2011-10-31 Diego Novillo <dnovillo@google.com>
+
+ * mangle.c (get_mangled_id): Factor from ...
+ (mangle_decl): ... here.
+ Call get_mangled_id.
+
+2011-10-25 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * NEWS (GCC 2.95): Refer to GNU/Linux instead of Linux.
+ (EGCS 1.0): Ditto.
+
+2011-10-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50901
+ * call.c (build_new_op_1): Handle ABS_EXPR together with the
+ other unary EXPR.
+
+2011-10-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ Revert:
+ 2011-10-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50864
+ * pt.c (tsubst_copy_and_build): Fix qualified_name_lookup_error
+ call in case COMPONENT_REF.
+
+2011-10-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * pt.c (unify_pack_expansion): Initialize bad_old_arg and bad_new_arg.
+
+2011-10-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50864
+ * pt.c (tsubst_copy_and_build): Fix qualified_name_lookup_error
+ call in case COMPONENT_REF.
+
+2011-10-27 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (cxx_eval_outermost_constant_expr): Check
+ cp_has_mutable_p.
+ (cxx_eval_component_reference): Check DECL_MUTABLE_P.
+
+2011-10-27 Roberto Agostino Vitillo <ravitillo@lbl.gov>
+
+ PR c++/30066
+ * decl2.c (determine_hidden_inline): New function.
+ (determine_visibility): fvisibility-inlines-hidden affects inline
+ functions.
+
+2011-10-27 Dodji Seketeli <dodji@redhat.com>
+
+ * cp-tree.h (DECL_DECLARES_TYPE_P): Fix comment.
+
+2011-10-26 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (check_literal_operator_args): Avoid building types.
+
+2011-10-26 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ Implement C++11 user-defined literals.
+ * cp-objcp-common.c: (cp_tree_size) Return size of USERDEF_LITERAL tree.
+ * cp-tree.h: (UDLIT_OP_*, UDLIT_OPER_P): Literal operator
+ name tools. New tree code for user-defined literals.
+ * cxx-pretty-print.h: (pp_cxx_userdef_literal) New.
+ * cxx-pretty-print.c: (pp_cxx_userdef_literal) New.
+ (pp_cxx_primary_expression, pp_cxx_expression): Use it.
+ * decl.c: (cp_tree_node_structure): Return new tree code.
+ (duplicate_decls): Check for raw vs. template operator conflicts.
+ (grokfndecl, grokdeclarator): New checks for literal operators.
+ * error.c: (dump_expr): Warn about user-defined literals
+ in C++98 mode. (dump_function_name): Pretty printing.
+ * mangle.c: (write_literal_operator_name): New.
+ (write_unqualified_id, write_unqualified_name): Use it.
+ * parser.c: (cp_parser_operator): Handle operator"".
+ (cp_parser_userdef_char_literal, cp_parser_userdef_numeric_literal,
+ cp_parser_userdef_string_literal): New.
+ (cp_parser_primary_expression): Handle new user-defined literal tokens
+ with new functions.
+ * semantics.c: (potential_constant_expression_1): Add
+ user-defined literals.
+ * typeck.c (check_raw_literal_operator,
+ check_literal_operator_args): New.
+
+2011-10-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * typeck.c (cp_build_addr_expr_1): Use BASELINK_P.
+ * class.c (instantiate_type): Likewise.
+ * pt.c (convert_nontype_argument_function, uses_template_parms,
+ tsubst_copy, resolve_nondeduced_context, type_dependent_expression_p):
+ Likewise.
+ * semantics.c (finish_decltype_type): Likewise.
+ * decl2.c (mark_used): Likewise.
+ * name-lookup.c (arg_assoc): Likewise.
+
+2011-10-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50870
+ * typeck.c (non_reference): Pass NULL_TREE through.
+
+2011-10-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/50866
+ PR c++/41449
+ * semantics.c (maybe_cleanup_point_expr_void): No longer static.
+ * typeck2.c (split_nonconstant_init_1): Use it.
+ * cp-tree.h: Declare it.
+ * decl.c (wrap_cleanups_r): Stop at CLEANUP_POINT_EXPR.
+
+ PR c++/49996
+ * tree.c (stabilize_init): Stabilize scalar elements of a
+ CONSTRUCTOR, too.
+
+2011-10-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50858
+ * typeck.c (composite_pointer_type_r): Check return value of
+ composite_pointer_type_r for error_mark_node.
+
+2011-10-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50861
+ * pt.c (tsubst_copy_and_build): Check return value of
+ tsubst_copy_and_build for error_mark_node.
+
+2011-10-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50841
+ Revert:
+ 2011-10-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50810
+ * typeck2.c (check_narrowing): Adjust OPT_Wnarrowing diagnostics.
+ (digest_init_r): Call check_narrowing irrespective of the C++ dialect.
+ * decl.c (check_initializer): Likewise.
+ * semantics.c (finish_compound_literal): Likewise.
+
+2011-10-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50810
+ * typeck2.c (check_narrowing): Adjust OPT_Wnarrowing diagnostics.
+ (digest_init_r): Call check_narrowing irrespective of the C++ dialect.
+ * decl.c (check_initializer): Likewise.
+ * semantics.c (finish_compound_literal): Likewise.
+
+2011-10-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/45385
+ * init.c (build_vec_init): Early return error_mark_node if
+ maxindex is -1.
+
+2011-10-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/31423
+ * typeck2.c (cxx_incomplete_type_diagnostic): Improve error message
+ for invalid use of member function.
+
+2011-10-21 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ PR c++/50811
+ * parser.c (cp_parser_class_head): Parse virt-specifiers
+ regardless of whether an id is present
+
+2011-10-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/41449
+ * typeck2.c (split_nonconstant_init_1): Handle EH cleanup of
+ initialized subobjects.
+
+2011-10-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/13657
+ * class.c (instantiate_type): Fix error message.
+
+2011-10-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/50793
+ * tree.c (bot_manip): Propagate AGGR_INIT_ZERO_FIRST.
+
+2011-10-19 Roland Stigge <stigge@antcom.de>
+
+ PR translation/49704
+ * semantics.c (potential_constant_expression_1): Use "AST" instead of
+ "ast" in sorry message.
+
+2011-10-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/38761
+ PR c++/40872
+ * decl.c (duplicate_decls, make_typename_type, grokdeclarator): Use
+ G_() in error message strings to facilitate translation.
+ * semantics.c (finish_id_expression): Likewise.
+ * parser.c (cp_parser_nested_name_specifier_opt,
+ cp_parser_parameter_declaration): Likewise.
+
+2011-10-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/50531
+ * pt.c (instantiate_decl): Recognize when a function defaulted
+ outside the class is already instantiated.
+
+ PR c++/50742
+ * decl.c (check_previous_goto_1): Handle using-decl.
+
+2011-10-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/50500
+ DR 1082
+ * class.c (type_has_user_declared_move_constructor): New.
+ (type_has_user_declared_move_assign): New.
+ (add_implicitly_declared_members): Add lazy copy ops
+ even if there's a move.
+ * method.c (lazily_declare_fn): Delete implicit copies
+ if there's a move.
+ (maybe_explain_implicit_delete): Explain this. Use inform rather
+ than error.
+ * cp-tree.h: Declare new fns.
+
+2011-10-18 Diego Novillo <dnovillo@google.com>
+
+ * parser.c: Remove ENABLE_CHECKING markers around debugging
+ routines.
+ (cp_lexer_dump_tokens): Add arguments START_TOKEN and CURR_TOKEN.
+ Make static
+ When printing CURR_TOKEN surround it in [[ ]].
+ Start printing at START_TOKEN.
+ Update all users.
+ (cp_debug_print_tree_if_set): New.
+ (cp_debug_print_context): New.
+ (cp_debug_print_context_stack): New.
+ (cp_debug_print_flag): New.
+ (cp_debug_print_unparsed_function): New.
+ (cp_debug_print_unparsed_queues): New.
+ (cp_debug_parser_tokens): New.
+ (cp_debug_parser): New.
+ (cp_lexer_start_debugging): Set cp_lexer_debug_stream to stderr.
+ (cp_lexer_stop_debugging): Set cp_lexer_debug_stream to NULL.
+ * parser.h (cp_lexer_dump_tokens): Remove declaration.
+ (cp_debug_parser): Declare.
+
+2011-10-17 Michael Spertus <mike_spertus@symantec.com>
+
+ * cp-tree.def: Add BASES as a new tree code.
+ * cp-tree.h (enum cp_trait_kind): Add CPTK_BASES, CPTK_DIRECT_BASES.
+ (BASES_TYPE, BASES_DIRECT): Define.
+ (calculate_bases, finish_bases, calculate_direct_bases): Declare.
+ * parser.c (cp_parser_trait_expr, cp_parser_template_argument_list,
+ (cp_parser_simple_type_specifier, cp_parser_save_nsdmi): Use them.
+ * pt.c (find_parameter_packs_r, tsubst_pack_expansion): Likewise.
+ * semantics.c (calculate_bases, finish_bases, calculate_direct_bases,
+ dfs_calculate_bases_pre, dfs_calculate_bases_post,
+ calculate_bases_helper): Define.
+
+2011-10-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/50736
+ * parser.c (cp_parser_lambda_introducer): Check for more
+ invalid captures.
+
+2011-10-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44524
+ * typeck.c (build_class_member_access_expr): Provide a better error
+ message for X.Y where X is a pointer to class type.
+ (finish_class_member_access_expr): Likewise.
+
+2011-10-15 Tom Tromey <tromey@redhat.com>
+ Dodji Seketeli <dodji@redhat.com>
+
+ * error.c (cp_diagnostic_starter): Pass the relevant location to
+ diagnostic_report_current_module.
+ (cp_diagnostic_finalizer): Call virt_loc_aware_diagnostic_finalizer.
+
+2011-10-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/48489
+ * typeck.c (finish_class_member_access_expr): Fix error call
+ for TREE_CODE (access_path) == TREE_BINFO.
+
+2011-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50732
+ * semantics.c (finish_trait_expr): Do not try to instantiate the
+ the base type of an __is_base_of trait.
+ (check_trait_type): Return a tree; use complete_type_or_else.
+
+2011-10-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/50563
+ * parser.c (cp_parser_cache_group): Handle end==CPP_COMMA.
+ (cp_parser_save_nsdmi): Pass it.
+
+ PR c++/50707
+ * method.c (walk_field_subobs): Check for NSDMI before
+ complaining about uninitialized fields.
+
+ * pt.c (tsubst_decl) [FIELD_DECL]: Use void_zero_node
+ instead of error_mark_node as a placeholder.
+
+2011-10-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/38174
+ * call.c (add_builtin_candidate): If two pointers have a composite
+ pointer type, generate a single candidate with that type.
+
+2011-10-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/50614
+ * cp-tree.h (VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK): New.
+ (DECL_TEMPLATE_INFO): Use it.
+ * pt.c (tsubst_decl) [FIELD_DECL]: Set DECL_TEMPLATE_INFO
+ if the decl has an NSDMI.
+ * init.c (perform_member_init): Use it.
+
+ PR c++/50437
+ * cp-tree.h (struct tree_lambda_expr): Add closure field.
+ (LAMBDA_EXPR_CLOSURE): New.
+ * pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Likewise.
+ * semantics.c (build_lambda_object): Use it instead of TREE_TYPE.
+ (begin_lambda_type, lambda_function, add_capture): Likewise.
+ (add_default_capture, lambda_expr_this_capture): Likewise.
+
+2011-10-13 Diego Novillo <dnovillo@google.com>
+
+ * cp-tree.h (struct language_function): Rename in_function_try_handler
+ to x_in_function_try_handler.
+ Rename in_base_initializer to x_in_base_initializer.
+ Update all users.
+
+2011-10-13 Diego Novillo <dnovillo@google.com>
+
+ * class.c (sorted_fields_type_new): Factor out of ...
+ (finish_struct_1): ... here.
+
+2011-10-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/50618
+ * init.c (expand_aggr_init_1): Don't zero-initialize virtual
+ bases of a base subobject.
+
+2011-10-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50594
+ * decl.c (cxx_init_decl_processing): Add
+ __attribute__((externally_visible)) to operator new and
+ operator delete library fn.
+
+2011-10-11 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * decl.c (duplicate_decls): Delete old interface with two parallel
+ arrays to hold standard builtin declarations, and replace it with
+ a function based interface that can support creating builtins on
+ the fly in the future. Change all uses, and poison the old
+ names. Make sure 0 is not a legitimate builtin index.
+ * except.c (build_eh_type_type): Ditto.
+ (choose_personality_routine): Ditto.
+ * semantics.c (finish_omp_atomic): Ditto.
+ (finish_omp_barrier): Ditto.
+ (finish_omp_flush): Ditto.
+ (finish_omp_taskwait): Ditto.
+
+2011-10-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/49855
+ PR c++/49896
+ * cp-tree.def (IMPLICIT_CONV_EXPR): New.
+ * call.c (perform_implicit_conversion_flags): Build it
+ instead of NOP_EXPR.
+ * cp-objcp-common.c (cp_common_init_ts): It's typed.
+ * cxx-pretty-print.c (pp_cxx_cast_expression): Handle it.
+ (pp_cxx_expression): Likewise.
+ * error.c (dump_expr): Likewise.
+ * semantics.c (potential_constant_expression_1): Likewise.
+ * tree.c (cp_tree_equal): Likewise.
+ (cp_walk_subtrees): Likewise.
+ * pt.c (iterative_hash_template_arg): Likewise.
+ (for_each_template_parm_r): Likewise.
+ (type_dependent_expression_p): Likewise.
+ (tsubst_copy, tsubst_copy_and_build): Handle IMPLICIT_CONV_EXPR
+ and CONVERT_EXPR.
+ * cp-tree.h (IMPLICIT_CONV_EXPR_DIRECT_INIT): New.
+
+2011-10-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50611
+ * pt.c (tsubst_copy_and_build): If (complain & tf_error) is false
+ do not call unqualified_name_lookup_error.
+
+2011-10-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50660
+ * call.c (conversion_null_warnings): Don't look through references.
+
+2011-10-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/38980
+ * init.c (constant_value_1): Add bool parameter.
+ (decl_constant_value_safe): Add.
+ (integral_constant_value): Adjust.
+ (decl_constant_value): Adjust.
+ * cp-tree.h (decl_constant_value_safe): Declare.
+ * typeck.c (decay_conversion): Use decl_constant_value_safe.
+ * call.c (convert_like_real): Likewise.
+
+2011-10-09 Jakub Jelinek <jakub@redhat.com>
+ Diego Novillo <dnovillo@google.com>
+
+ * pt.c (reregister_specialization): Use htab_find instead of
+ htab_find_slot with INSERT.
+ (maybe_process_partial_specialization, lookup_template_class_1): Change
+ slot variable type to void ** to avoid aliasing problems.
+ (register_specialization): Likewise. Use slot != NULL instead of
+ more expensive !optimize_specialization_lookup_p (tmpl) test.
+
+2011-10-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/34927
+ * typeck2.c (abstract_virtuals_error_sfinae): Don't produce duplicate
+ inform messages in case of cloned destructor.
+
+2011-10-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/39164
+ * decl.c (grokfndecl): Diagnose redefinition of defaulted fn.
+
+2011-10-02 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_pack_expansion): Re-use ARGUMENT_PACK_SELECTs.
+ Change unsubstituted_packs to bool.
+
+ * parser.c (cp_parser_range_for): Don't try to deduce from {}
+ in a template.
+
+ PR c++/35722
+ Implement N2555 (expanding pack expansion to fixed parm list)
+ * pt.c (coerce_template_parms): Allow expanding a pack expansion
+ to a fixed-length argument list.
+ (unify_pack_expansion): Handle explicit args properly.
+ (unify) [TREE_VEC]: Handle pack expansions here.
+ [TYPE_ARGUMENT_PACK]: Not here.
+ (tsubst_pack_expansion): Don't try to do partial substitution.
+ (pack_deducible_p): New.
+ (fn_type_unification): Use it.
+ (find_parameter_packs_r): Take the TYPE_MAIN_VARIANT
+ of a type parameter.
+ (check_non_deducible_conversion): Split from type_unification_real.
+ (unify_one_argument): Split from type_unification_real...
+ (unify_pack_expansion): ...and here. Drop call_args_p parm.
+ (type_unification_real, unify, more_specialized_fn): Adjust.
+
+ * class.c (fixed_type_or_null): Handle NSDMI.
+ * method.c (walk_field_subobs): Disable NSDMI noexcept checking
+ for now.
+
+2011-09-30 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (TREE_NEGATED_INT): Remove.
+ * semantics.c (finish_unary_op_expr): Don't set it.
+
+2011-09-30 Janis Johnson <janisjo@codesourcery.com>
+
+ PR c++/44473
+ * mangle.c (write_type): Handle CV qualifiers for decimal classes.
+
+2011-09-26 Andi Kleen <ak@linux.intel.com>
+
+ * repo.c (finish_repo): Use HOST_WIDE_INT_PRINT_HEX_PURE.
+
+2011-09-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/45278
+ * typeck.c (cp_build_binary_op): With -Wextra, warn for ordered
+ comparison of pointer with zero.
+
+2011-09-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/31489
+ * parser.c (cp_parser_elaborated_type_specifier): For RECORD_TYPE,
+ set CLASSTYPE_DECLARED_CLASS.
+
+2011-09-27 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (duplicate_decls): If compatible stpcpy prototype
+ is seen, set implicit_built_in_decls[BUILT_IN_STPCPY].
+
+2011-09-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/45012
+ * pt.c (tsubst_copy_and_build) [CONST_DECL]: Don't pull out
+ constant value if we're still in a template.
+
+ PR c++/46105
+ * typeck.c (structural_comptypes): Ignore cv-quals on typename scope.
+
+ PR c++/50508
+ * semantics.c (cxx_eval_logical_expression): Use tree_int_cst_equal
+ rather than ==.
+
+2011-09-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/45487
+ * error.c (dump_template_bindings): Separate bindings with semicolons
+ instead of commas.
+
+2011-09-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/50512
+ * call.c (compare_ics): Only consider rvaluedness_matches_p
+ if the target type is the same or it too differs in rvalueness.
+
+ PR c++/50523
+ * call.c (implicit_conversion): Mask out inappropriate LOOKUP
+ flags at the top of the function.
+
+ * pt.c (tsubst_copy) [PARM_DECL]: Handle 'this' in NSDMI.
+
+2011-09-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * pt.c (convert_nontype_argument): Handle NULLPTR_TYPE.
+
+2011-09-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/26747
+ * cp-gimplify.c (get_bc_label): Remove obsolete diagnostics.
+
+2011-09-25 Jason Merrill <jason@redhat.com>
+
+ * parser.c (inject_this_parameter): Split out from
+ cp_parser_late_return_type_opt.
+ (cp_parser_class_specifier_1): Use it for NSDMIs.
+ * tree.c (bot_replace): Replace NSDMI 'this' with real 'this'.
+
+2011-09-24 Jason Merrill <jason@redhat.com>
+
+ * except.c (expr_noexcept_p): Split out from finish_noexcept_expr.
+ * cp-tree.h: Declare it.
+ * method.c (walk_field_subobs): Use it.
+
+ * init.c (perform_member_init): Instantiate NSDMI here.
+ * pt.c (tsubst_decl) [FIELD_DECL]: Not here.
+
+ Handle deferred parsing of NSDMIs.
+ * parser.h (cp_unparsed_functions_entry): Add nsdmis field.
+ * parser.c (unparsed_nsdmis, cp_parser_save_nsdmi): New.
+ (cp_parser_late_parse_one_default_arg): Split out from
+ cp_parser_late_parsing_default_args.
+ (cp_parser_late_parsing_nsdmi): New.
+ (push_unparsed_function_queues): Set it.
+ (cp_parser_parameter_declaration): Save the '=' token.
+ (cp_parser_template_parameter): Likewise.
+ (cp_parser_default_argument): Call cp_parser_initializer
+ rather than cp_parser_initializer_clause.
+ (cp_parser_class_specifier_1): Parse unparsed_nsdmis.
+ (cp_parser_member_declaration): Handle nsdmis.
+ * decl2.c (grokfield): Handle DEFAULT_ARG for a function.
+
+ Implement C++11 non-static data member initializers.
+ * cp-tree.h (enum cpp_warn_str): Add CPP0X_NSDMI.
+ * error.c (maybe_warn_cpp0x): Handle it.
+ * call.c (convert_like_real) [ck_user]: Don't complain about
+ using an explicit constructor for direct-initialization.
+ * class.c (check_field_decl): Fix ancient typo.
+ (check_field_decls): NSDMIs make the default ctor non-trivial.
+ * decl.c (cp_finish_decl): Record NSDMI.
+ (grokdeclarator): Allow NSDMI.
+ * decl2.c (grokfield): Allow NSDMI. Correct LOOKUP flags.
+ * init.c (perform_member_init): Use NSDMI.
+ * method.c (walk_field_subobs): Check for NSDMI.
+ * parser.c (cp_parser_member_declaration): Parse { } init.
+ * semantics.c (register_constexpr_fundef): Don't talk about
+ a return statement in a constexpr constructor.
+ (cxx_eval_call_expression): Check DECL_INITIAL instead of
+ DECL_SAVED_TREE.
+
+2011-09-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44267
+ * class.c (build_base_path): Add a tsubst_flags_t parameter.
+ (convert_to_base): Adjust call.
+ * typeck.c (build_class_member_access_expr,
+ get_member_function_from_ptrfunc, build_static_cast_1): Likewise.
+ * init.c (dfs_initialize_vtbl_ptrs, emit_mem_initializers): Likewise.
+ * method.c (do_build_copy_constructor, do_build_copy_assign): Likewise.
+ * rtti.c (build_dynamic_cast_1): Likewise.
+ * typeck2.c (build_scoped_ref, build_m_component_ref): Likewise.
+ * call.c (build_over_call, build_special_member_call): Likewise.
+ * cvt.c (cp_convert_to_pointer, convert_to_pointer_force,
+ build_up_reference): Likewise.
+ * cp-tree.h (build_base_path): Adjust declaration.
+
+2011-09-23 Jason Merrill <jason@redhat.com>
+
+ Core 253 - allow const objects with no initializer or
+ user-provided default constructor if the defaulted constructor
+ initializes all the subobjects.
+ PR c++/20039
+ PR c++/42844
+ * class.c (default_init_uninitialized_part): New.
+ * cp-tree.h: Declare it.
+ * decl.c (check_for_uninitialized_const_var): Use it.
+ * init.c (perform_member_init): Likewise.
+ (build_new_1): Likewise.
+ * method.c (walk_field_subobs): Likewise.
+
+2011-09-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50258
+ * decl.c (check_static_variable_definition): Allow in-class
+ initialization of static data member of non-integral type in
+ permissive mode.
+
+2011-09-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50491
+ * semantics.c (potential_constant_expression_1): Handle USING_DECL.
+
+2011-09-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50371
+ * pt.c (invalid_nontype_parm_type_p): Handle NULLPTR_TYPE.
+
+2011-09-22 Jonathan Wakely <jwakely.gcc@gmail.com>
+ Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50344
+ * friend.c (make_friend_class): cv-qualification is ok in a
+ friend declaration.
+
+2011-09-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50454
+ * decl.c (grokdeclarator): Consistently handle both __int128
+ and unsigned __int128 with -pedantic; suppress diagnostic in
+ system headers.
+
+2011-09-20 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_TEMPLOID_INSTANTIATION): New.
+ (DECL_GENERATED_P): New.
+ * class.c (finalize_literal_type_property): Use them.
+ * semantics.c (is_instantiation_of_constexpr): Likewise.
+ (register_constexpr_fundef): Likewise.
+
+ * call.c (convert_default_arg): Avoid redundant copy.
+ * tree.c (bot_manip): Copy everything.
+
+2011-09-20 Roberto Agostino Vitillo <ravitillo@lbl.gov>
+
+ * call.c (build_new_method_call_1): Use non-virtual lookup
+ for final virtual functions.
+
+2011-09-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/50424
+ * call.c (set_flags_from_callee): Split out from build_call_a.
+ * cp-tree.h: Declare it.
+ * tree.c (bot_manip): Call it.
+
+2011-09-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/50365
+ * parser.c (cp_parser_late_return_type_opt): Check quals parameter
+ for clearing current_class_ptr, too.
+
+2011-09-14 Diego Novillo <dnovillo@google.com>
+
+ * name-lookup.c (lookup_arg_dependent): Use conditional
+ timevars.
+ * decl.c (xref_tag): Likewise.
+
+2011-09-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50391
+ * pt.c (regenerate_decl_from_template): Don't pass an error_mark_node
+ to build_exception_variant.
+
+2011-09-13 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/48320
+ * pt.c (template_parameter_pack_p): Support TEMPLATE_PARM_INDEX
+ nodes. Add a comment.
+ (arg_from_parm_pack_p): New static function, factorized out from
+ tsubst_pack_expansion and extended to support non-type parameter
+ packs represented with TEMPLATE_PARM_INDEX nodes.
+ (tsubst_pack_expansion): Use arg_from_parm_pack_p.
+
+2011-09-12 Jason Merrill <jason@redhat.com>
+
+ * pt.c (type_unification_real): Fix handling of DEDUCE_CONV
+ with no deducible template parameters.
+ * call.c (rejection_reason_code): Add rr_template_conversion.
+ (print_z_candidate): Handle it.
+ (template_conversion_rejection): New.
+ (build_user_type_conversion_1): Use it.
+
+ * call.c (merge_conversion_sequences): Set bad_p and user_conv_p
+ on all of the second conversion sequence.
+ (build_user_type_conversion_1): Set bad_p on the ck_user conv.
+ (convert_like_real): Handle bad ck_ref_bind with user_conv_p in the
+ first section. Fix loop logic.
+ (initialize_reference): Call convert_like for diagnostics when
+ we have a (bad) conversion.
+
+ * call.c (convert_class_to_reference)
+ (convert_class_to_reference_1): Remove.
+ (reference_binding): Use build_user_type_conversion_1 instead.
+
+ * call.c (initialize_reference): Add flags parm.
+ * decl.c (grok_reference_init): Likewise.
+ (check_initializer): Pass it.
+ * typeck.c (convert_for_initialization): Likewise.
+ * cp-tree.h: Adjust.
+
+ * cp-tree.h (LOOKUP_NO_RVAL_BIND): New.
+ * call.c (conditional_conversion): Use it.
+ (reference_binding): Fix handling of xvalues.
+
+2011-09-09 Jason Merrill <jason@redhat.com>
+
+ * call.c (implicit_conversion): Check BRACE_ENCLOSED_INITIALIZER_P
+ before forcing instantiation.
+
+2011-09-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50324
+ * typeck2.c (digest_init_r): Call complete_type_or_maybe_complain
+ instead of complete_type_or_else.
+
+2011-09-08 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/33255 - Support -Wunused-local-typedefs warning
+ * name-lookup.c (pushdecl_maybe_friend_1): Use the new
+ record_locally_defined_typedef.
+ * decl.c (finish_function): Use the new
+ maybe_warn_unused_local_typedefs.
+ (grokfield): Use the new record_locally_defined_typedef.
+ * parser.c (lookup_name): Use the new maybe_record_typedef_use.
+
+2011-09-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50309
+ * decl.c (grokdeclarator): Check u.function.exception_specification
+ for error_mark_node.
+
+2011-09-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/50298
+ * parser.c (cp_parser_member_declaration): Don't require a constant
+ rvalue here in C++0x.
+
+ * pt.c (type_unification_real): Correct complain arg for tsubsting
+ default template args.
+
+ * pt.c (tsubst_aggr_type): Check TYPE_P before tsubsting.
+
+2011-09-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/50296
+ * semantics.c (register_constexpr_fundef): Call is_valid_constexpr_fn.
+ (cx_check_missing_mem_inits): Handle bases and empty trivial members.
+ (validate_constexpr_fundecl): Remove.
+ * decl.c (start_preparsed_function): Don't call it.
+ * cp-tree.h: Don't declare it.
+
+2011-09-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/49267
+ * call.c (reference_binding): Don't set is_lvalue for an rvalue
+ reference rfrom.
+
+ PR c++/49267
+ PR c++/49458
+ DR 1328
+ * call.c (reference_binding): Set rvaluedness_matches_p properly
+ for reference to function conversion ops.
+ (compare_ics): Adjust.
+
+ * class.c (trivial_default_constructor_is_constexpr): Rename from
+ synthesized_default_constructor_is_constexpr.
+ (type_has_constexpr_default_constructor): Adjust.
+ (add_implicitly_declared_members): Call it instead.
+ (explain_non_literal_class): Explain about non-constexpr default ctor.
+ * cp-tree.h: Adjust.
+ * method.c (synthesized_method_walk): Adjust.
+ * semantics.c (explain_invalid_constexpr_fn): Handle defaulted
+ functions, too.
+
+ PR c++/50248
+ Core 1358
+ * init.c (perform_member_init): Don't diagnose missing inits here.
+ (emit_mem_initializers): Or here.
+ * method.c (process_subob_fn): Don't instantiate constexpr ctors.
+ * semantics.c (cx_check_missing_mem_inits): New.
+ (explain_invalid_constexpr_fn): Call it.
+ (register_constexpr_fundef): Likewise. Leave
+ DECL_DECLARED_CONSTEXPR_P set when the body is unsuitable.
+ (cxx_eval_call_expression): Adjust diagnostics.
+ (cxx_eval_constant_expression): Catch use of 'this' in a constructor.
+
+2011-08-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/50084
+ * cp-tree.h (cp_decl_specifier_seq): Rename user_defined_type_p
+ to type_definition_p.
+ * parser.c (cp_parser_set_decl_spec_type): Likewise.
+ * decl.c (grokdeclarator): Check it.
+
+ PR c++/50089
+ * semantics.c (finish_id_expression): Use
+ current_nonlambda_class_type for qualified-ids.
+
+ PR c++/50114
+ * decl.c (poplevel): Disable for scope compatibility hack
+ in C++11 mode.
+
+ PR c++/50220
+ * semantics.c (add_capture): Call complete_type for copy.
+
+ PR c++/50234
+ * semantics.c (cxx_eval_component_reference): Handle
+ value-initialization for omitted initializers.
+
+2011-08-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/50224
+ * semantics.c (finish_id_expression): Mark captured variables used.
+
+2011-08-29 Jakub Jelinek <jakub@redhat.com>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/50207
+ * class.c (finish_struct_1): Complain if the first field is
+ artificial.
+
+2011-08-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/50209
+ Core DR 994
+ * parser.c (cp_parser_default_argument): Use
+ cp_parser_initializer_clause.
+ (cp_parser_late_parsing_default_args): Likewise.
+
+2011-08-26 Jason Merrill <jason@redhat.com>
+
+ Core DR 342
+ PR c++/48582
+ * pt.c (check_valid_ptrmem_cst_expr): A null member pointer value
+ is valid in C++11.
+ (convert_nontype_argument): Likewise. Implicitly convert nullptr
+ and do constant folding.
+ * mangle.c (write_template_arg_literal): Mangle null member
+ pointer values as 0.
+ * call.c (null_member_pointer_value_p): New.
+ * cp-tree.h: Declare it.
+
+2011-08-25 Jason Merrill <jason@redhat.com>
+
+ * call.c (convert_like_real): Remove redundant complain checks.
+
+ PR c++/50157
+ * call.c (convert_like_real): Exit early if bad and !tf_error.
+
+2011-08-23 Jason Merrill <jason@redhat.com>
+
+ * typeck2.c (build_functional_cast): Don't try to avoid calling
+ build_value_init.
+ * pt.c (instantiate_class_template_1): Don't copy TYPE_HAS_* flags.
+
+2011-08-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/49045
+ Core 1321
+ * tree.c (dependent_name): New.
+ (cp_tree_equal): Two calls with the same dependent name are
+ equivalent even if the overload sets are different.
+
+2011-08-23 Jason Merrill <jason@redhat.com>
+
+ * tree.c (build_target_expr): Set TREE_CONSTANT on
+ literal TARGET_EXPR if the value is constant.
+ * typeck2.c (build_functional_cast): Don't set it here.
+
+2011-08-23 Jason Merrill <jason@redhat.com>
+
+ Core 903 (partial)
+ * call.c (null_ptr_cst_p): Only 0 qualifies in C++11.
+
+2011-08-23 Jason Merrill <jason@redhat.com>
+
+ Core 975
+ * decl.c (cxx_init_decl_processing): Initialize
+ dependent_lambda_return_type_node.
+ * cp-tree.h (cp_tree_index): Add CPTI_DEPENDENT_LAMBDA_RETURN_TYPE.
+ (dependent_lambda_return_type_node): Define.
+ (DECLTYPE_FOR_LAMBDA_RETURN): Remove.
+ * semantics.c (lambda_return_type): Handle overloaded function.
+ Use dependent_lambda_return_type_node instead of
+ DECLTYPE_FOR_LAMBDA_RETURN.
+ (apply_lambda_return_type): Don't check dependent_type_p.
+ * pt.c (tsubst_copy_and_build): Handle lambda return type deduction.
+ (instantiate_class_template_1): Likewise.
+ (tsubst): Don't use DECLTYPE_FOR_LAMBDA_RETURN.
+ * mangle.c (write_type): Likewise.
+ * typeck.c (structural_comptypes): Likewise.
+ (check_return_expr): Handle dependent_lambda_return_type_node.
+
+2011-08-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/50024
+ * semantics.c (maybe_constant_value): Don't try to fold { }.
+ * pt.c (build_non_dependent_expr): Don't wrap { }.
+ * init.c (build_value_init): Allow scalar value-init in templates.
+
+2011-08-23 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (potential_constant_expression_1): Allow 'this'.
+
+2011-08-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/50158
+ * typeck.c (cp_build_modify_expr): Call mark_rvalue_use on rhs
+ if it has side-effects and needs to be preevaluated.
+
+2011-08-23 Siddhesh Poyarekar <siddhesh.poyarekar@gmail.com>
+
+ PR c++/50055
+ * except.c (begin_eh_spec_block): Build EH_SPEC block on the
+ same line as the function.
+
+2011-08-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/46862
+ * class.c (finish_struct_1): If TYPE_TRANSPARENT_AGGR is set on a type
+ which doesn't have any fields, clear it and diagnose.
+
+2011-08-18 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+ Marc Glisse <marc.glisse@normalesup.org>
+
+ PR libstdc++-v3/1773
+ * mangle.c (decl_mangling_context): Call
+ targetm.cxx.decl_mangling_context.
+ (write_unscoped_name): Use decl_mangling_context.
+
+2011-08-18 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/45625
+ * pt.c (parameter_of_template_p): Handle comparison with DECLs of
+ template parameters as created by process_template_parm.
+
+2011-08-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/50086
+ * pt.c (unify_pack_expansion): Correct overloaded unification
+ logic.
+
+ * pt.c (instantiate_class_template_1): If DECL_PRESERVE_P is set
+ on a member function or static data member, call mark_used.
+
+ PR c++/50054
+ * typeck2.c (cxx_incomplete_type_diagnostic): Handle
+ init_list_type_node.
+
+2011-08-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/50075
+ * name-lookup.c (local_bindings_p): New.
+ * name-lookup.h: Declare it.
+ * lex.c (unqualified_name_lookup_error): Use it.
+
+ PR c++/50059
+ * error.c (dump_expr): Handle MODIFY_EXPR properly.
+
+ * decl.c (grok_reference_init): Handle constexpr here.
+ * call.c (initialize_reference): Not here.
+
+2011-08-12 David Li <davidxl@google.com>
+
+ * class.c (update_vtable_entry_for_fn): Set
+ LOST_PRIMARY bit properly.
+
+2011-08-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/50034
+ * call.c (convert_arg_to_ellipsis): force_rvalue only in
+ potentially evaluated context.
+
+2011-08-12 Richard Guenther <rguenther@suse.de>
+
+ * call.c (build_over_call): Instead of memcpy use an
+ assignment of two MEM_REFs.
+
+2011-08-11 Romain Geissler <romain.geissler@gmail.com>
+ Brian Hackett <bhackett1024@gmail.com>
+
+ * decl.c (cp_finish_decl): Invoke callbacks on finish_decl event.
+
+2011-08-10 Richard Guenther <rguenther@suse.de>
+
+ * call.c (build_over_call): Call memcpy unconditionally.
+
+2011-08-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/50020
+ * semantics.c (finish_call_expr): Don't look at 'this' if we
+ had an explicit object argument.
+
+ PR c++/50011
+ * typeck2.c (check_narrowing): Fix integer logic.
+
+2011-08-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * Make-lang.in (g++$(exeext)): Add $(EXTRA_GCC_LIBS).
+
+2011-08-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/48993
+ * semantics.c (potential_constant_expression_1) [CALL_EXPR]: Sorry
+ on 'this' in a constructor.
+
+ PR c++/49921
+ * semantics.c (finish_decltype_type): Call invalid_nonstatic_memfn_p.
+
+ PR c++/49669
+ * init.c (perform_member_init): Handle invalid array initializer.
+
+ PR c++/49988
+ * semantics.c (cxx_eval_array_reference): Handle failure to
+ reduce the array operand to something we can work with.
+
+2011-08-05 Gabriel Charette <gchare@google.com>
+
+ * decl.c (finish_function): Remove unecessary line 0 hack.
+
+2011-08-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/47453
+ * typeck.c (build_x_compound_expr_from_list): Also complain
+ about ({...}).
+
+ PR c++/49812
+ * typeck.c (cp_build_unary_op) [POSTINCREMENT_EXPR]: Strip cv-quals.
+
+ PR c++/49983
+ * parser.c (cp_parser_range_for): Only do auto deduction in
+ template if the range is non-dependent.
+
+ * init.c (perform_member_init): Always build_aggr_init
+ for a class member with an explicit mem-initializer.
+
+ * pt.c (unify) [TEMPLATE_TYPE_PARM]: Allow VLA for C++0x 'auto'.
+
+2011-08-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/49905
+ * decl.c (cxx_init_decl_processing): Add alloc_size (1) attribute
+ for operator new and operator new []. Call init_attributes.
+
+2011-08-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/43886
+ * parser.c (cp_parser_lambda_body): Clear local_variables_forbidden_p.
+
+ PR c++/49577
+ * typeck2.c (check_narrowing): Check unsigned mismatch.
+ * semantics.c (finish_compound_literal): check_narrowing.
+
+ PR c++/49593
+ * pt.c (find_parameter_packs_r): Handle CONSTRUCTOR.
+
+ PR c++/49803
+ * init.c (sort_mem_initializers): Initialize uses_unions_p here.
+ (build_field_list): Not here.
+
+ PR c++/49834
+ * parser.c (build_range_temp): Split out from...
+ (cp_convert_range_for): ...here.
+ (do_range_for_auto_deduction): New.
+ (cp_parser_range_for): Use it.
+
+2011-08-02 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (finish_omp_atomic): Adjust prototype.
+ (cxx_omp_const_qual_no_mutable): New prototype.
+ (finish_omp_taskyield): New prototype.
+ * parser.c (cp_parser_omp_atomic): (cp_parser_omp_atomic): Handle
+ parsing OpenMP 3.1 atomics. Adjust finish_omp_atomic caller.
+ (cp_parser_omp_clause_name): Handle final and mergeable clauses.
+ (cp_parser_omp_clause_final, cp_parser_omp_clause_mergeable): New
+ functions.
+ (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_FINAL
+ and PRAGMA_OMP_CLAUSE_MERGEABLE.
+ (OMP_TASK_CLAUSE_MASK): Allow final and mergeable clauses.
+ (cp_parser_omp_taskyield): New function.
+ (cp_parser_pragma): Handle PRAGMA_OMP_TASKYIELD.
+ (cp_parser_omp_clause_reduction): Handle min and max.
+ * pt.c (tsubst_expr) <case OMP_ATOMIC>: Handle OpenMP 3.1 atomics.
+ (tsubst_omp_clauses): Handle OMP_CLAUSE_FINAL and
+ OMP_CLAUSE_MERGEABLE.
+ * semantics.c (finish_omp_atomic): Add OPCODE, V, LHS1 and RHS1
+ arguments. Handle OpenMP 3.1 atomics. Adjust c_finish_omp_atomic
+ caller.
+ (finish_omp_clauses): Don't complain about const qualified
+ predetermined vars and static data members in firstprivate clause.
+ Handle OMP_CLAUSE_FINAL and OMP_CLAUSE_MERGEABLE. Handle MIN_EXPR
+ and MAX_EXPR.
+ (finish_omp_taskyield): New function.
+ * cp-gimplify.c (cxx_omp_const_qual_no_mutable): New function.
+ (cxx_omp_predetermined_sharing): Use it.
+
+2011-08-02 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_call_a): Also check at_function_scope_p.
+
+2011-08-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/49932
+ * mangle.c (write_prefix): Handle decltype.
+
+ PR c++/49924
+ * semantics.c (cxx_eval_vec_init_1): Fix logic.
+
+ PR c++/49813
+ * semantics.c (potential_constant_expression_1): Allow any builtin.
+ (morally_constexpr_builtin_function_p): Remove.
+
+2011-07-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/49867
+ * parser.c (cp_parser_lambda_expression): Also clear in_statement
+ and in_switch_statement_p.
+ (cp_parser_class_specifier): Likewise.
+
+2011-07-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/49808
+ * pt.c (tsubst) [TEMPLATE_PARM_INDEX]: Call convert_from_reference.
+ (convert_nontype_argument, tsubst_template_arg): Handle its output.
+
+2011-07-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/49813
+ * semantics.c (potential_constant_expression_1): Handle FMA_EXPR.
+
+2011-07-27 Jeffrey Yasskin <jyasskin@google.com>
+
+ * pt.c (build_template_decl): Copy the function_decl's
+ source location to the new template_decl.
+
+2011-07-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/49776
+ * typeck.c (cp_build_modify_expr): Check digest_init return value
+ for error_mark_node.
+
+2011-07-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR bootstrap/49845
+ * parser.c (cp_parser_perform_range_for_lookup): Always assign *being
+ and *end before returning.
+
+2011-07-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/49838
+ * parser.c (cp_parser_perform_range_for_lookup): Early return if
+ error_operand_p (range).
+
+2011-07-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/49823
+ * parser.c (cp_parser_qualifying_entity): Handle templates.
+
+2011-07-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/49793
+ * typeck2.c (check_narrowing): Downgrade permerror to pedwarn.
+ Make conditional on -Wnarrowing.
+
+2011-07-22 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Warn about the use of final/override in non-c++0x mode, and
+ add __final for non-c++0x mode.
+ * cp-tree.h (cpp0x_warn_str): Add CPP0X_OVERRIDE_CONTROLS.
+ * error.c (maybe_warn_cpp0x): Adjust.
+ * parser.c (cp_parser_virt_specifier_seq_opt): Use it. Add
+ '__final' as a non-c++0x alternative for 'final'.
+
+2011-07-22 Jason Merrill <jason@redhat.com>
+ Mark Glisse <marc.glisse@normalesup.org>
+
+ PR c++/30112
+ * decl.c (cp_finish_decl): Apply pragma redefine_extname in
+ other namespaces as well.
+ * name-lookup.c (c_linkage_bindings): Define.
+ (lookup_extern_c_fun_in_all_ns): Rename from
+ lookup_extern_c_fun_binding_in_all_ns. Return tree.
+ (pushdecl_maybe_friend_1): Adjust. Copy DECL_ASSEMBLER_NAME.
+
+2011-07-20 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_initializer_list): Handle C99 .id= and [N]=
+ designated initializer syntax.
+ * decl.c (check_array_designated_initializer): Add index parm.
+ (maybe_deduce_size_from_array_init): Pass it.
+ (reshape_init_array_1): Likewise.
+
+ PR c++/6709 (DR 743)
+ PR c++/42603 (DR 950)
+ * parser.c (token_is_decltype, cp_lexer_next_token_is_decltype): New.
+ (cp_parser_nested_name_specifier_opt): Allow decltype.
+ (cp_parser_qualifying_entity): Likewise.
+ (cp_parser_decltype): Replace source tokens with CPP_DECLTYPE.
+ (cp_parser_simple_type_specifier): Handle decltype as scope.
+ (cp_parser_base_specifier): Allow decltype.
+ (cp_parser_base_clause): Don't crash on null base.
+ * parser.h (CPP_KEYWORD, CPP_TEMPLATE_ID): Move to c-common.h.
+ (CPP_NESTED_NAME_SPECIFIER, N_CP_TTYPES): Likewise.
+
+2011-07-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/49785
+ * pt.c (coerce_template_parms): Handle non-pack after pack.
+
+2011-07-19 Richard Guenther <rguenther@suse.de>
+
+ * call.c (build_special_member_call): Use fold_build_pointer_plus.
+ * class.c (build_base_path): Likewise.
+ (convert_to_base_statically): Likewise.
+ (dfs_accumulate_vtbl_inits): Likewise.
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Likewise.
+ * except.c (expand_start_catch_block): Likewise.
+ * init.c (expand_virtual_init): Likewise.
+ (build_new_1): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_vec_delete): Likewise.
+ * rtti.c (build_headof): Likewise.
+ (tinfo_base_init): Likewise.
+ * typeck.c (get_member_function_from_ptrfunc): Likewise.
+ (cp_build_addr_expr_1): Likewise.
+ * typeck2.c (build_m_component_ref): Likewise.
+
+2011-07-18 Martin Jambor <mjambor@suse.cz>
+
+ * parser.c (cp_parser_parameter_declaration_list): Initialize
+ parenthesized_p.
+
+2011-07-16 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tinst_level_tick, last_template_error_tick): Replace with
+ last_error_tinst_level.
+ (push_tinst_level, pop_tinst_level): Adjust.
+ (problematic_instantiation_changed): Adjust.
+ (record_last_problematic_instantiation): Adjust.
+ * error.c (cp_print_error_function): Don't print
+ current_function_decl if we're in a template instantiation context.
+ (print_instantiation_full_context): Always print first line.
+
+2011-07-16 Nathan Froyd <froydnj@codesourcery.com>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/45329
+ PR c++/48934
+ * cp-tree.h (fn_type_unification): Add `bool' parameter.
+ * pt.c (enum template_base_result): Define.
+ (unify_success, unify_unknown): Define.
+ (unify_parameter_deduction_failure): Define.
+ (unify_invalid, unify_cv_qual_mismatch, unify_type_mismatch): Define.
+ (unify_parameter_pack_mismatch): Define.
+ (unify_parameter_pack_inconsistent): Define.
+ (unify_ptrmem_cst_mismatch, unify_vla_arg): Define.
+ (unify_expression_unequal, unify_inconsistency): Define.
+ (unify_method_type_error, unify_arity): Likewise.
+ (unify_too_many_parameters, unify_too_few_parameters): Define.
+ (unify_arg_conversion, unify_no_common_base): Define.
+ (unify_illformed_ptrmem_cst_expr): Define.
+ (unify_substitution_failure): Define.
+ (unify_inconsistent_template_template_parameters): Define.
+ (unify_template_deduction_failure): Define.
+ (unify_template_argument_mismatch): Define.
+ (unify_overload_resolution_failure): Define.
+ (comp_template_args_with_info): New function, split out from...
+ (comp_template_args): ...here. Call it.
+ (deduction_tsubst_fntype): Add `complain' parameter'. Pass it
+ to tsubst.
+ (unify): Add `explain_p' parameter. Pass to all relevant calls.
+ Call above status functions when appropriate.
+ (resolve_overloaded_unification, try_one_overload): Likewise.
+ (type_unification, type_unification_real): Likewise.
+ (unify_pack_expansion): Likewise.
+ (get_template_base, try_class_unification): Likewise.
+ (get_bindings, more_specialized_fn): Pass false to unification
+ calls.
+ (get_class_bindings, do_auto_deduction): Likewise.
+ (convert_nontype_argument): Likewise.
+ (fn_type_unification): Likewise. Pass tf_warning_or_error if
+ explain_p.
+ (get_template_base): Add `explain_p' parameter and pass it to
+ try_class_unification. Return an enum template_base_result.
+ * class.c (resolve_address_of_overloaded_function): Pass false to
+ fn_type_unification.
+ * call.c (enum rejection_reason_code): Add new codes.
+ (struct rejection_reason): Add template_unification field.
+ Add template_instantiation field.
+ (template_unification_rejection): Define.
+ (template_unification_error_rejection): Define.
+ (template_instantiation_rejection): Define.
+ (invalid_copy_with_fn_template_rejection): Define.
+ (add_template_candidate): Pass false to unify.
+ Provide more rejection reasons when possible.
+ (print_template_unification_rejection): Define.
+ (print_arity_rejection): Define, split out from...
+ (print_z_candidate): ...here. Add cases for new rejection
+ reasons.
+
+2011-07-15 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (check-g++-strict-gc): New.
+ (cp/except.o): Depend on gt-cp-except.h
+ * except.c: Include gt-cp-except.h.
+ * config-lang.in (gtfiles): Add cp/except.c.
+ * decl2.c (mark_used): Adjust constexpr condition, set
+ function_depth around template instantiation.
+ * parser.c (cp_parser_lambda_body): Set function_depth.
+ * semantics.c (maybe_add_lambda_conv_op): Likewise.
+
+ PR testsuite/49741
+ * Make-lang.in (check-c++0x): Use --extra_opts instead of--tool_opts.
+
+2011-07-13 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (check-c++0x): New.
+
+2011-07-13 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * typeck2.c (split_nonconstant_init_1): Pass the initializer directly,
+ rather than a pointer to it. Return true if the whole of the value
+ was initialized by the generated statements. Use
+ complete_ctor_at_level_p instead of count_type_elements.
+
+2011-07-12 Diego Novillo <dnovillo@google.com>
+
+ * name-lookup.h (cp_binding_level): Rename from cxx_scope.
+ Update all users.
+ (struct cp_binding_level): Fix indentation.
+
+2011-07-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/49672
+ * pt.c (extract_fnparm_pack): Split out from...
+ (make_fnparm_pack): ...here.
+ (instantiate_decl): Handle non-pack parms after a pack.
+ * semantics.c (maybe_add_lambda_conv_op): Don't in a template.
+
+ * decl2.c (decl_constant_var_p): Use decl_maybe_constant_var_p.
+
+ PR c++/44609
+ * cp-tree.h (struct tinst_level): Add errors field.
+ * pt.c (neglectable_inst_p, limit_bad_template_recurson): New.
+ (push_tinst_level): Don't start another decl in that case.
+ (reopen_tinst_level): Adjust errors field.
+ * decl2.c (cp_write_global_declarations): Don't complain about
+ undefined inline if its template was defined.
+ * mangle.c (mangle_decl_string): Handle failure from push_tinst_level.
+
+2011-07-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/49691
+ * parser.c (cp_parser_late_return_type_opt): Check quals parameter
+ rather than current_class_type to determine whether to set 'this'.
+ (cp_parser_direct_declarator): Pass -1 to quals if member_p is false.
+ (cp_parser_init_declarator): Pass down member_p.
+
+2011-07-09 Jason Merrill <jason@redhat.com>
+
+ * tree.c (build_vec_init_elt): Strip TARGET_EXPR.
+
+2011-07-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/45437
+ * typeck.c (cp_build_modify_expr): Preevaluate RHS.
+
+ * method.c (use_thunk): Use cgraph_add_to_same_comdat_group.
+ * optimize.c (maybe_clone_body): Likewise.
+ * semantics.c (maybe_add_lambda_conv_op): Likewise.
+
+ PR c++/45603
+ * decl.c (expand_static_init): Don't get confused by user
+ declaration of __cxa_guard_acquire.
+
+ * typeck.c (cp_apply_type_quals_to_decl): Don't check
+ COMPLETE_TYPE_P either.
+
+ PR c++/49673
+ * typeck.c (cp_apply_type_quals_to_decl): Don't check
+ TYPE_NEEDS_CONSTRUCTING.
+
+2011-07-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/49663
+ * pt.c (push_deduction_access_scope): Preserve
+ processing_template_decl across push_to_top_level.
+ And revert:
+ * class.c (pushclass): Accept NULL argument.
+ (popclass): Deal with popping null class.
+ * pt.c (push_access_scope, pop_access_scope): Use them rather than
+ push_to_top_level/pop_from_top_level.
+ * name-lookup.c (lookup_name_real_1): Check current_class_type.
+
+2011-07-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/49644
+ * typeck.c (cp_build_binary_op): For MULT_EXPR and TRUNC_DIV_EXPR with
+ one non-complex and one complex argument, call save_expr on both
+ operands.
+
+2011-07-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/49353
+ * semantics.c (expand_or_defer_fn_1): Clear DECL_EXTERNAL
+ on kept inlines.
+
+ PR c++/49568
+ * method.c (make_thunk, use_thunk): Copy DECL_COMDAT.
+
+2011-07-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/48157
+ * pt.c (tsubst_qualified_id): Preserve TEMPLATE_ID_EXPR in
+ partial instantiation.
+
+ PR c++/49598
+ * semantics.c (finish_id_expression): convert_from_reference.
+
+2011-07-05 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (cxx_init_decl_processing): Defer building common
+ tree nodes to c_common_nodes_and_builtins.
+
+2011-07-04 Jason Merrill <jason@redhat.com>
+
+ DR 1207
+ PR c++/49589
+ * mangle.c (write_expression): Handle 'this'.
+ * parser.c (cp_parser_postfix_dot_deref_expression): Allow
+ incomplete *this.
+ * semantics.c (potential_constant_expression_1): Check that
+ DECL_CONTEXT is set on 'this'.
+
+ * error.c (dump_template_bindings): Don't print typenames
+ for a partial instantiation.
+ (dump_function_decl): If we aren't printing function arguments,
+ print template arguments as <args> rather than [with ...].
+ (dump_expr): Don't print return type or template header.
+ [BASELINK]: Use BASELINK_FUNCTIONS rather than get_first_fn.
+ * pt.c (dependent_template_arg_p): Handle null arg.
+
+ * error.c (type_to_string): Avoid redundant akas.
+
+2011-07-01 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR c++/49605
+ * init.c (build_delete): Only warn for sfk_deleting_destructor.
+
+2011-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (cp/decl.o): Depend on pointer-set.h.
+ (cp/class.o): Likewise.
+ (cp/error.o): Likewise.
+ (cp/name-lookup.o): Likewise.
+ (cp/decl2.o): Likewise. Don't depend on $(POINTER_SET_H).
+
+2011-07-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/48261
+ * pt.c (lookup_template_function): Handle non-function.
+
+ PR c++/48593
+ * pt.c (tsubst_qualified_id): Check PTRMEM_OK_P.
+ * tree.c (build_qualified_name): Set PTRMEM_OK_P.
+ * semantics.c (finish_parenthesized_expr): Clear PTRMEM_OK_P on
+ SCOPE_REF, too.
+ * cp-tree.h (PTRMEM_OK_P): Apply to SCOPE_REF, too.
+ (QUALIFIED_NAME_IS_TEMPLATE): Switch to lang flag 1.
+
+ PR c++/48883
+ PR c++/49609
+ * pt.c (resolve_nondeduced_context): Call mark_used.
+
+ PR c++/49085
+ * semantics.c (finish_offsetof): Complain about incomplete type.
+
+2011-06-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/49387
+ * rtti.c (get_tinfo_decl): Call complete_type.
+
+ PR c++/49569
+ * method.c (implicitly_declare_fn): Set DECL_PARM_LEVEL and
+ DECL_PARM_INDEX on rhs parm.
+
+ * pt.c (iterative_hash_template_arg): Use cp_tree_operand_length.
+
+ PR c++/49355
+ * tree.c (stabilize_init): Handle aggregate initialization.
+
+ PR c++/48481
+ * name-lookup.c (struct arg_lookup): Add fn_set.
+ (add_function): Check it.
+ (lookup_arg_dependent_1): Initialize it.
+
+2011-06-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/49216
+ * init.c (build_new_1): Pass {} down to build_vec_init.
+ (build_vec_init): Handle it.
+
+ DR 1207
+ PR c++/49003
+ * cp-tree.h (struct saved_scope): Add x_current_class_ptr,
+ x_current_class_ref.
+ (current_class_ptr, current_class_ref): Use them.
+ * decl.c (build_this_parm): Handle getting the class type.
+ * parser.c (cp_parser_late_return_type_opt): Set up 'this'
+ for use within the trailing return type.
+
+ * pt.c (tsubst_decl) [VAR_DECL]: In unevaluated operand,
+ don't tsubst DECL_INITIAL unless our type use auto.
+
+ PR c++/49520
+ * semantics.c (constexpr_fn_retval): Handle CLEANUP_POINT_EXPR here.
+ (massage_constexpr_body): Not here.
+
+ PR c++/49554
+ * semantics.c (lambda_proxy_type): New.
+ (build_capture_proxy): Use it.
+ * cp-tree.h (DECLTYPE_FOR_LAMBDA_PROXY): New.
+ * pt.c (tsubst) [DECLTYPE_TYPE]: Use them.
+
+ PR c++/45923
+ * class.c (explain_non_literal_class): New.
+ (finalize_literal_type_property): Call it.
+ * cp-tree.h: Declare it.
+ * semantics.c (ensure_literal_type_for_constexpr_object): Call it.
+ (is_valid_constexpr_fn): Likewise.
+ (massage_constexpr_body): Split out from...
+ (register_constexpr_fundef): ...here.
+ (is_instantiation_of_constexpr): New.
+ (expand_or_defer_fn_1): Leave DECL_SAVED_TREE alone in that case.
+ (explain_invalid_constexpr_fn): New.
+ (cxx_eval_call_expression): Call it.
+ (potential_constant_expression_1): Likewise. Avoid redundant errors.
+ * method.c (process_subob_fn): Diagnose non-constexpr.
+ (walk_field_subobs): Likewise.
+ (synthesized_method_walk): Don't shortcut if we want diagnostics.
+ (explain_implicit_non_constexpr): New.
+ (defaulted_late_check): Use it.
+ * call.c (build_cxx_call): Remember location.
+
+ * method.c (maybe_explain_implicit_delete): Use pointer_set
+ instead of htab.
+
+ * class.c (finalize_literal_type_property): Update conditions.
+ * method.c (defaulted_late_check): Set TYPE_HAS_CONSTEXPR_CTOR.
+
+ * tree.c (build_vec_init_expr): Don't add TARGET_EXPR.
+ * typeck2.c (digest_init_r): Handle VEC_INIT_EXPR.
+ * semantics.c (cxx_eval_vec_init_1): Correct type.
+
+ * init.c (build_value_init): Decide whether or not to zero-initialize
+ based on user-providedness of default ctor, not any ctor.
+ (build_value_init_noctor): Adjust assert.
+
+ DR 990
+ * call.c (convert_like_real) [ck_user]: Handle value-initialization.
+ (build_new_method_call_1): Likewise.
+ * init.c (expand_default_init): Handle direct list-initialization
+ of aggregates.
+
+2011-06-27 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (union lang_tree_node): Use it in chain_next expression.
+
+2011-06-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/49528
+ * semantics.c (potential_constant_expression_1): Check
+ for non-literality rather than cleanup.
+ (cxx_eval_constant_expression): Likewise.
+
+ PR c++/49528
+ * semantics.c (potential_constant_expression_1): A TARGET_EXPR
+ with a cleanup isn't constant.
+ (cxx_eval_constant_expression): Likewise.
+ * init.c (expand_default_init): Use maybe_constant_init.
+
+2011-06-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/46400
+ * cp-tree.h (union lang_tree_node): Use TYPE_NEXT_VARIANT
+ instead of TYPE_CHAIN for chain_next for types.
+
+2011-06-23 Gabriel Charette <gchare@google.com>
+
+ * name-lookup.h (cp_binding_level): Removed unused
+ member names_size. Update all users.
+
+2011-06-23 Jason Merrill <jason@redhat.com>
+
+ * typeck2.c (build_functional_cast): Strip cv-quals for value init.
+ * init.c (build_zero_init_1): Not here.
+
+ PR c++/35255
+ * pt.c (resolve_overloaded_unification): Fix DR 115 handling.
+
+2011-06-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44625
+ * decl2.c (build_anon_union_vars): Early return error_mark_node
+ for a nested anonymous struct.
+
+2011-06-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/49507
+ * decl2.c (mark_used): Don't call synthesize_method for
+ functions defaulted outside the class.
+
+ * optimize.c (maybe_clone_body): Set linkage flags before
+ cgraph_same_body_alias.
+
+ PR c++/49440
+ * class.c (set_linkage_according_to_type): Hand off to
+ determine_visibility.
+
+ PR c++/49395
+ * init.c (build_zero_init_1): Strip cv-quals from scalar types.
+
+ PR c++/36435
+ * pt.c (most_specialized_instantiation): Do check return types.
+
+2011-06-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/49260
+ * call.c (build_call_a): Set cp_function_chain->can_throw here.
+ (build_cxx_call): Not here.
+
+2011-06-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/49172
+ * decl.c (cp_finish_decl): Adjust init_const_expr_p for refs.
+ (grokdeclarator): constexpr doesn't apply const for refs.
+ * parser.c (cp_parser_initializer_clause): Don't call
+ maybe_constant_value here.
+ * call.c (initialize_reference): Handle constexpr.
+
+ PR c++/49482
+ * semantics.c (maybe_add_lambda_conv_op): Call mark_exp_read for
+ static fn parameters.
+
+ * call.c (add_builtin_candidates): Use cv_unqualified rather than
+ TYPE_MAIN_VARIANT.
+ * pt.c (tsubst_arg_types): Likewise.
+ * except.c (build_throw): Use cv_unqualified.
+
+ PR c++/49418
+ * call.c (cxx_type_promotes_to): Don't strip cv-quals.
+ * semantics.c (lambda_return_type): Strip them here.
+
+2011-06-21 Andrew MacLeod <amacleod@redhat.com>
+
+ * semantics.c: Add sync_ or SYNC__ to builtin names.
+
+2011-06-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/49216
+ * init.c (build_vec_init): Don't try to use a CONSTRUCTOR when
+ base is a pointer.
+ * typeck2.c (process_init_constructor_array): Use {} for classes,
+ too.
+ * call.c (convert_like_real): Handle substitution failure.
+
+ PR c++/48138
+ * pt.c (canonicalize_type_argument): New.
+ (convert_template_argument, unify): Use it.
+
+ PR c++/47080
+ * call.c (rejection_reason_code): Add rr_explicit_conversion.
+ (print_z_candidate): Handle it.
+ (explicit_conversion_rejection): New.
+ (build_user_type_conversion_1): Reject an explicit conversion
+ function that requires more than a qualification conversion.
+
+ PR c++/47635
+ * decl.c (grokdeclarator): Don't set ctype to an ENUMERAL_TYPE.
+
+ PR c++/48138
+ * tree.c (strip_typedefs): Use build_aligned_type.
+
+ PR c++/49205
+ * call.c (sufficient_parms_p): Allow parameter packs too.
+
+ PR c++/43321
+ * semantics.c (describable_type): Remove.
+ * cp-tree.h: Likewise.
+ * decl.c (cp_finish_decl): Don't call it.
+ * init.c (build_new): Likewise.
+ * parser.c (cp_parser_omp_for_loop): Likewise.
+ * pt.c (tsubst_decl): Likewise.
+ (do_auto_deduction): If we fail in a template, try again
+ at instantiation time.
+
+ PR c++/43831
+ * parser.c (cp_parser_lambda_introducer): Complain about redundant
+ captures.
+ * semantics.c (add_capture): Likewise.
+ (register_capture_members): Clear IDENTIFIER_MARKED.
+
+2011-06-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/49458
+ * call.c (convert_class_to_reference_1): Allow binding function
+ lvalue to rvalue reference.
+
+ PR c++/43912
+ Generate proxy VAR_DECLs for better lambda debug info.
+ * cp-tree.h (FUNCTION_NEEDS_BODY_BLOCK): Add lambda operator().
+ (LAMBDA_EXPR_PENDING_PROXIES): New.
+ (struct tree_lambda_expr): Add pending_proxies.
+ * name-lookup.c (pushdecl_maybe_friend_1): Handle capture shadowing.
+ (qualify_lookup): Use is_lambda_ignored_entity.
+ * parser.c (cp_parser_lambda_expression): Don't adjust field names.
+ Call insert_pending_capture_proxies.
+ (cp_parser_lambda_introducer): Use this_identifier.
+ (cp_parser_lambda_declarator_opt): Call the object parameter
+ of the op() "__closure" instead of "this".
+ (cp_parser_lambda_body): Call build_capture_proxy.
+ * semantics.c (build_capture_proxy, is_lambda_ignored_entity): New.
+ (insert_pending_capture_proxies, insert_capture_proxy): New.
+ (is_normal_capture_proxy, is_capture_proxy): New.
+ (add_capture): Add __ to field names here, return capture proxy.
+ (add_default_capture): Use this_identifier, adjust to expect
+ add_capture to return a capture proxy.
+ (outer_lambda_capture_p, thisify_lambda_field): Remove.
+ (finish_id_expression, lambda_expr_this_capture): Adjust.
+ (build_lambda_expr): Initialize LAMBDA_EXPR_PENDING_PROXIES.
+ * pt.c (tsubst_copy_and_build): Check that LAMBDA_EXPR_PENDING_PROXIES
+ is null.
+
+ * name-lookup.c (pushdecl_maybe_friend_1): Do check for shadowing
+ of artificial locals.
+
+ * parser.c (cp_parser_lambda_expression): Clear
+ LAMBDA_EXPR_THIS_CAPTURE after parsing.
+ * pt.c (tsubst_copy_and_build): Make sure it isn't set.
+
+ * cp-tree.h (struct tree_lambda_expr): Change common to typed.
+ Move non-pointers to end of struct.
+
+ * pt.c (tsubst_decl): Handle DECL_VALUE_EXPR on reference.
+ * decl.c (check_initializer): Handle DECL_VALUE_EXPR_P.
+
+ * semantics.c (finish_non_static_data_member): Preserve dereference
+ in template.
+
+2011-06-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/44160
+ * parser.c (cp_parser_lambda_body): Share code between
+ simple and complex cases instead of using cp_parser_function_body.
+
+ PR c++/45378
+ * decl.c (check_initializer): Check narrowing.
+
+ PR c++/49229
+ * pt.c (tsubst_decl) [FUNCTION_DECL]: Handle substitution failure.
+
+ PR c++/49251
+ * semantics.c (finish_id_expression): Mark even dependent
+ variables as used.
+
+ PR c++/49420
+ * error.c (dump_template_argument): Don't try to omit default
+ template args from an argument pack.
+
+2011-06-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/49412
+ * decl.c (get_dso_handle_node): Mark __dso_handle hidden if
+ assembler supports hidden visibility.
+
+2011-06-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/49107
+ * cp-tree.h (DEFERRED_NOEXCEPT_SPEC_P): Handle overload.
+ * method.c (defaulted_late_check): Only maybe_instantiate_noexcept
+ if the declaration had an exception-specifier.
+ (process_subob_fn): Don't maybe_instantiate_noexcept.
+ * pt.c (maybe_instantiate_noexcept): Handle overload.
+ * typeck2.c (nothrow_spec_p_uninst): New.
+ (merge_exception_specifiers): Add 'fn' parm. Build up overload.
+ * typeck.c (merge_types): Adjust.
+
+ * pt.c (deduction_tsubst_fntype): Don't save input_location.
+ (maybe_instantiate_noexcept): Likewise.
+
+2011-06-14 Joseph Myers <joseph@codesourcery.com>
+
+ * Make-lang.in (cp/method.o): Update dependencies.
+ * method.c: Include common/common-target.h.
+ (use_thunk): Use targetm_common.have_named_sections.
+
+2011-06-14 Steve Ellcey <sje@cup.hp.com>
+
+ * decl.c (cxx_init_decl_processing): Use ptr_mode instead of Pmode.
+
+2011-06-14 Jason Merrill <jason@redhat.com>
+
+ * error.c (type_to_string): Print typedef-stripped version too.
+
+ PR c++/49117
+ * call.c (perform_implicit_conversion_flags): Print source type as
+ well as expression.
+
+ PR c++/49389
+ * typeck2.c (build_m_component_ref): Preserve rvalueness.
+
+ PR c++/49369
+ * class.c (build_base_path): Fix cv-quals in unevaluated context.
+
+ PR c++/49290
+ * semantics.c (cxx_fold_indirect_ref): Local, more permissive copy
+ of fold_indirect_ref_1.
+ (cxx_eval_indirect_ref): Use it.
+
+2011-06-11 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (cp_write_global_declarations): Process aliases; look trhough
+ same body aliases.
+
+2011-06-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/41769
+ * decl.c (grokdeclarator): Reject operator names in parameters.
+
+2011-06-10 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (clear_decl_external): New functoin.
+ (cp_write_global_declarations): Use it.
+
+2011-06-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cp-tree.h (error_operand_p): Remove.
+
+2011-06-09 David Krauss <potswa@mac.com>
+
+ PR c++/49118
+ * typeck2.c (build_x_arrow): Push fake template context
+ to produce diagnostic on acyclic endless operator-> drill-down.
+ * call.c (build_new_op): Change Boolean overload status
+ value to a pointer to the overload function.
+ * cp-tree.h: Likewise.
+ * typeck.c: Likewise.
+ * parser.c: Likewise.
+ * decl2.c: Likewise.
+ * pt.c: Likewise.
+
+2011-06-09 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (maybe_constant_value): Handle overflowed input.
+ (non_const_var_error): Handle non-constant DECL_INITIAL.
+
+ * pt.c (build_non_dependent_expr): Use fold_non_dependent_expr_sfinae.
+
+ * parser.c (cp_parser_constant_expression): Just return the
+ non-constant expression.
+
+ * semantics.c (finish_compound_literal): Set TREE_HAS_CONSTRUCTOR.
+
+2011-06-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/29003
+ * decl.c (grokdeclarator): Reject operator names in typedefs.
+
+2011-06-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/49107
+ * cp-tree.def (DEFERRED_NOEXCEPT): New.
+ * cp-tree.h (struct tree_deferred_noexcept): New.
+ (DEFERRED_NOEXCEPT_PATTERN, DEFERRED_NOEXCEPT_ARGS): New.
+ (DEFERRED_NOEXCEPT_SPEC_P): New.
+ (enum cp_tree_node_structure_enum): Add TS_CP_DEFERRED_NOEXCEPT.
+ (union lang_tree_node): Add tree_deferred_noexcept.
+ (maybe_instantiate_noexcept): Declare.
+ * cp-objcp-common.c (cp_tree_size): Handle DEFERRED_NOEXCEPT.
+ * error.c (dump_exception_spec): Likewise.
+ * cxx-pretty-print.c (pp_cxx_exception_specification): Likewise.
+ * ptree.c (cxx_print_xnode): Likewise.
+ * tree.c (cp_tree_equal): Likewise.
+ * decl.c (cp_tree_node_structure): Likewise.
+ (duplicate_decls): Call maybe_instantiate_noexcept.
+ * except.c (build_noexcept_spec): Handle DEFERRED_NOEXCEPT.
+ (nothrow_spec_p, type_noexcept_p, type_throw_all_p): Check
+ DEFERRED_NOEXCEPT_SPEC_P.
+ * typeck2.c (merge_exception_specifiers): Likewise.
+ * decl2.c (mark_used): Call maybe_instantiate_noexcept.
+ * method.c (process_subob_fn, defaulted_late_check): Likewise.
+ * pt.c (tsubst_exception_specification): Add defer_ok parm.
+ Build DEFERRED_NOEXCEPT.
+ (maybe_instantiate_noexcept): New.
+ (tsubst, regenerate_decl_from_template, instantiate_decl): Adjust.
+ * search.c (check_final_overrider): Call maybe_instantiate_noexcept.
+
+ * semantics.c (potential_constant_expression_1): Handle destructor
+ call.
+
+2011-06-08 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (struct tinst_level): Add chain_next GTY
+ markup.
+
+2011-06-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/49322
+ * pt.c (deduction_tsubst_fntype): Don't free the tinst entry
+ if a pending_template entry is pointing at it.
+
+2011-06-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/48969
+ PR c++/44175
+ * error.c (subst_to_string): New.
+ (cp_printer): Use it for 'S'.
+ (print_instantiation_partial_context_line): Handle subst context.
+ * pt.c (push_tinst_level): Handle subst context.
+ (deduction_tsubst_fntype): Don't track specific substitutions.
+ Use push_tinst_level.
+
+ * pt.c (deduction_tsubst_fntype): Use push_deduction_access_scope.
+ (fn_type_unification): Don't call push_deduction_access_scope here.
+
+2011-06-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/48780
+ * typeck.c (perform_integral_promotions): Don't promote scoped enums.
+ * call.c (convert_arg_to_ellipsis): Promote them here in old ABI.
+
+2011-06-06 Nicola Pero <nicola.pero@meta-innovation.com>,
+
+ PR obj-c++/48275
+ * parser.c (cp_parser_objc_at_property_declaration): Allow setter
+ and getter names to use all the allowed method names.
+
+2011-06-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/49298
+ * semantics.c (potential_constant_expression_1): Handle FIELD_DECL.
+
+ PR objc++/49221
+ * decl.c (cp_finish_decl): Check DECL_FUNCTION_SCOPE_P rather than
+ at_function_scope_p.
+
+ PR c++/49134
+ * tree.c (build_target_expr): Deal with ARM ABI tweaks.
+
+2011-06-04 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * init.c (build_delete): Warn when deleting type with non-virtual
+ destructor.
+
+2011-06-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/49276
+ * mangle.c (write_nested_name): Use CP_DECL_CONTEXT instead of
+ DECL_CONTEXT.
+
+2011-06-01 Jason Merrill <jason@redhat.com>
+
+ * pt.c (build_non_dependent_expr): Remove special handling of
+ REFERENCE_REF_P.
+
+ PR c++/44175
+ * pt.c (template_args_equal): Handle one arg being NULL_TREE.
+ (deduction_tsubst_fntype): Handle excessive non-infinite recursion.
+
+ PR c++/49253
+ * typeck2.c (build_x_arrow): Don't use build_min_nt.
+
+2010-05-31 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/48010
+ * name-lookup.c (supplement_binding_1): If the old binding was a
+ type name, also check that the DECL actually refers to the same
+ type or is not a type.
+
+2011-05-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/44870
+ * tree.c (lvalue_kind): Recurse on NON_DEPENDENT_EXPR. Handle
+ ARROW_EXPR, TYPEID_EXPR, and arbitrary class-valued expressions.
+ (build_min_non_dep): Preserve reference refs.
+ (build_min_non_dep_call_vec): Likewise
+
+2011-05-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/49223
+ * semantics.c (finish_omp_clauses): Call require_complete_type
+ even for copyin/copyprivate clauses. Only call
+ cxx_omp_create_clause_info if inner_type is COMPLETE_TYPE_P.
+
+2011-05-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/46124
+ * parser.c (cp_parser_lambda_expression): Improve error recovery.
+ (cp_parser_lambda_declarator_opt): Likewise. Return bool.
+
+2011-05-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/47277
+ * parser.c (cp_parser_pseudo_destructor_name): Commit to parse
+ after we see the ~.
+
+ * mangle.c (mangle_decl_string): Make sure we don't try to mangle
+ templates.
+
+ PR c++/47049
+ * semantics.c (maybe_add_lambda_conv_op): Fix COMDAT sharing.
+ * decl.c (start_preparsed_function): Don't call comdat_linkage for
+ a template.
+
+ PR c++/47132
+ * mangle.c (write_expression): Handle MODOP_EXPR.
+
+ PR c++/47277
+ * parser.c (cp_parser_unqualified_id): Don't check
+ constructor_name_p for enums.
+
+ PR c++/47687
+ * pt.c (dependent_type_p_r): Avoid infinite recursion.
+
+ PR c++/48284
+ * error.c (dump_expr) [COMPONENT_REF]: Use pp_cxx_dot
+ with INDIRECT_REF of REFERENCE_TYPE.
+
+ PR c++/49181
+ * pt.c (get_mostly_instantiated_function_type): Use push_access_scope.
+
+2011-05-27 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.h (building_stmt_tree): Delete.
+ * decl.c (save_function_data): Tweak initializer for x_cur_stmt_list.
+ (build_aggr_init_full_exprs): Call building_stmt_list_p
+ instead of building_stmt_tree.
+ (initialize_local_var): Likewise.
+ (finish_function): Likewise.
+ * decl2.c (finish_anon_union): Likewise.
+ * init.c (begin_init_stmts): Likewise.
+ (finish_init_stmts): Likewise.
+ (expand_aggr_init_1): Likewise.
+ * name-lookup.c (do_local_using_decl): Likewise.
+ (do_namespace_alias): Likewise.
+ (do_using_directive): Likewise.
+ (cp_emit_debug_info_for_using): Likewise.
+ * semantics.c (add_stmt): Assert that stmt_list_stack is non-empty.
+
+2011-05-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/42056
+ * typeck2.c (build_functional_cast): Complain early for invalid uses
+ of 'auto' and set type to error_mark_node.
+
+2011-05-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/47721
+ * parser.c (cp_parser_member_declaration): Allow friend T.
+ * friend.c (make_friend_class): Ignore non-classes.
+ * pt.c (instantiate_class_template_1): Handle TEMPLATE_TYPE_PARM.
+
+ DR 1004
+ * pt.c (convert_template_argument): Don't complain about using
+ injected-class-name as template template argument.
+
+ PR c++/47956
+ * decl.c (check_static_variable_definition): Now static.
+ (cp_finish_decl): Call it here.
+ (grokdeclarator): Not here.
+ * pt.c (instantiate_class_template_1): Or here.
+ * cp-tree.h: Don't declare it.
+
+2011-05-26 Janis Johnson <janis187@us.ibm.com>
+ Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/2288
+ PR c++/18770
+ * name-lookup.h (enum scope_kind): Add sk_cond.
+ * name-lookup.c (pushdecl_maybe_friend): Get scope of shadowed local.
+ Detect and report error for redeclaration from for-init or if
+ or switch condition.
+ (begin_scope): Handle sk_cond.
+ * semantics.c (begin_if_stmt): Use sk_cond.
+ (begin switch_stmt): Ditto.
+
+2011-05-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/48211
+ * name-lookup.h (cp_class_binding): Make base a pointer.
+ * name-lookup.c (new_class_binding): Adjust.
+ (poplevel_class): Adjust.
+
+ PR c++/48424
+ * decl.c (grokparms): Function parameter packs don't need to
+ go at the end.
+ * pt.c (type_unification_real): But they aren't deduced otherwise.
+
+2011-05-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/48536
+ * decl.c (build_enumerator): If incremented enumerator won't fit in
+ previous integral type, find one it will fit in.
+
+ PR c++/48599
+ * decl.c (create_array_type_for_decl): Complain about array of auto.
+
+ PR c++/44994
+ PR c++/49156
+ * error.c (dump_template_bindings): Set processing_template_decl
+ for a partial instantiation.
+
+ PR c++/45401
+ * decl.c (grokdeclarator): Don't change type when adding rvalue ref
+ to another reference type.
+
+ PR c++/44311
+ * decl.c (case_conversion): New.
+ (finish_case_label): Use it.
+
+ * ptree.c (cxx_print_xnode): Handle ARGUMENT_PACK_SELECT.
+
+ PR c++/45698
+ * pt.c (dependent_template_arg_p): See through ARGUMENT_PACK_SELECT.
+
+ PR c++/46005
+ * decl.c (grokdeclarator): Complain about auto typedef.
+
+ PR c++/46245
+ * decl.c (grokdeclarator): Complain later for auto parameter.
+ * pt.c (splice_late_return_type): Handle use in a template
+ type-parameter.
+
+ PR c++/46696
+ * typeck.c (cp_build_modify_expr): Check DECL_DEFAULTED_FN.
+
+ PR c++/47184
+ * parser.c (cp_parser_parameter_declaration): Recognize
+ list-initialization.
+ (cp_parser_direct_declarator): Check for the closing
+ paren before parsing definitely.
+
+ PR c++/48935
+ * parser.c (cp_parser_constructor_declarator_p): Don't check
+ constructor_name_p for enums.
+ (cp_parser_diagnose_invalid_type_name): Correct error message.
+
+ PR c++/45418
+ * init.c (perform_member_init): Handle list-initialization
+ of array of non-trivial class type.
+
+ PR c++/45080
+ * pt.c (instantiate_class_template_1): Call maybe_add_lambda_conv_op.
+ * semantics.c (lambda_function): Check COMPLETE_OR_OPEN_TYPE_P.
+
+ PR c++/48292
+ * pt.c (tsubst_decl) [PARM_DECL]: Handle partial instantiation of
+ function parameter pack.
+ (tsubst_pack_expansion): Likewise.
+
+ * cp-objcp-common.c (cp_common_init_ts): TYPE_ARGUMENT_PACK has
+ TS_COMMON.
+
+2011-05-25 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-objcp-common.c (cp_common_init_ts): Mark CTOR_INITIALIZER
+ as TS_TYPED.
+
+ PR c++/49136
+ * semantics.c (cxx_eval_bit_field_ref): Handle the
+ case when BIT_FIELD_REF doesn't cover only a single field.
+
+2011-05-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/49042
+ * pt.c (get_mostly_instantiated_function_type): Use
+ push_deferring_access_checks rather than set flag_access_control.
+
+2011-05-24 Nicola Pero <nicola.pero@meta-innovation.com>,
+
+ * parser.c (cp_parser_objc_class_ivars): Deal gracefully with a
+ syntax error in declaring an ObjC instance variable.
+
+2011-05-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/48884
+ * class.c (pushclass): Accept NULL argument.
+ (popclass): Deal with popping null class.
+ * pt.c (push_access_scope, pop_access_scope): Use them rather than
+ push_to_top_level/pop_from_top_level.
+ (push_deduction_access_scope, pop_defarg_context): New.
+ (fn_type_unification): Use them.
+ * name-lookup.c (lookup_name_real_1): Check current_class_type.
+
+2011-05-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (grokdeclarator): Use current_class_name.
+
+2011-05-24 Joseph Myers <joseph@codesourcery.com>
+
+ * Make-lang.in (GXX_OBJS): Remove prefix.o.
+ (g++$(exeext)): Use libcommon-target.a.
+ (CXX_C_OBJS): Remove prefix.o.
+
+2011-05-23 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_copy_and_build): Use current_class_name.
+
+ PR c++/49102
+ * call.c (convert_arg_to_ellipsis): Call force_rvalue.
+
+ PR c++/49105
+ * typeck.c (cp_build_c_cast): Don't strip cv-quals when
+ converting to reference.
+ (build_static_cast_1): Update for glvalues.
+
+ PR c++/49105
+ * typeck.c (build_const_cast_1): Handle rvalue references.
+
+ PR c++/47263
+ * decl.c (use_eh_spec_block): Do use an EH spec block for a
+ lambda op().
+
+ PR c++/49058
+ * call.c (splice_viable): Be strict in templates.
+
+ PR c++/47336
+ * error.c (dump_template_bindings): Suppress access control.
+
+ PR c++/47544
+ * pt.c (instantiate_decl): Handle =default.
+
+ PR c++/48617
+ * pt.c (invalid_nontype_parm_type_p): Allow DECLTYPE_TYPE.
+
+2011-05-23 Nathan Froyd <froydnj@codesourcery.com>
+
+ * call.c (build_over_call): Tweak call to check_function_arguments.
+ * typeck.c (cp_build_function_call_vec): Likewise.
+
+2011-05-23 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR c++/18016
+ * init.c (perform_member_init): Check for self-initialization.
+
+2011-05-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/48647
+ * typeck.c (composite_pointer_type_r): Return error_mark_node
+ on error in SFINAE context.
+
+2011-05-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/48945
+ * decl.c (grokdeclarator): Don't add set const function-cv-qual
+ for constexpr fns to memfn_quals, just add it to the type.
+ (revert_static_member_fn): Don't complain about quals.
+ (check_static_quals): New.
+ (grokfndecl): Call it.
+ (start_preparsed_function): Don't call revert_static_member_fn.
+
+ PR c++/48945
+ * decl.c (revert_static_member_fn): Ignore const on constexpr fn.
+
+ PR c++/48780
+ * cvt.c (type_promotes_to): Don't promote scoped enums.
+
+ PR c++/49066
+ * decl.c (duplicate_decls): Preserve DECL_DELETED_FN.
+
+ PR c++/48873
+ * tree.c (stabilize_expr): Fix typo.
+
+ DR 1073
+ PR c++/49082
+ * typeck.c (comp_except_specs): noexcept(false) is not compatible
+ with throw(type-list).
+ * typeck2.c (merge_exception_specifiers): noexcept(false)
+ beats any more limited specification.
+
+ PR c++/24163
+ PR c++/29131
+ * pt.c (tsubst_copy_and_build) [CALL_EXPR]: Avoid repeating
+ unqualified lookup.
+ * semantics.c (perform_koenig_lookup): Add complain parm.
+ * cp-tree.h: Adjust.
+ * parser.c (cp_parser_postfix_expression): Adjust.
+ (cp_parser_perform_range_for_lookup): Adjust.
+
+2011-05-20 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (finish_call_expr): SET_EXPR_LOCATION.
+
+2011-05-20 Joseph Myers <joseph@codesourcery.com>
+
+ * Make-lang.in (GXX_OBJS): Remove intl.o and version.o.
+
+2011-05-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/49043
+ * decl.c (check_omp_return): Stop searching on sk_function_parms.
+
+ PR c++/48869
+ * method.c (get_dtor, get_copy_ctor): Add COMPLAIN argument,
+ pass it down to locate_fn_flags.
+ * cp-tree.h (get_dtor, get_copy_ctor): Adjust prototypes.
+ * semantics.c (cxx_omp_create_clause_info): Adjust callers.
+ * cp-gimplify.c: Include splay-tree.h.
+ (splay_tree_compare_decl_uid, omp_var_to_track,
+ omp_cxx_notice_variable): New functions.
+ (struct cp_genericize_omp_taskreg): New type.
+ (struct cp_genericize_data): Add omp_ctx field.
+ (cp_genericize_r): Attempt to determine implicitly determined
+ firstprivate class type variables.
+ (cp_genericize): Clear omp_ctx.
+ * Make-lang.in (cp/cp-gimplify.o): Depend on $(SPLAY_TREE_H).
+
+2011-05-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/48948
+ PR c++/49015
+ * class.c (finalize_literal_type_property): Do check
+ for constexpr member functions of non-literal class.
+ (finish_struct): Don't call check_deferred_constexpr_decls.
+ * cp-tree.h: Don't declare it.
+ (DECL_DEFERRED_CONSTEXPR_CHECK): Remove.
+ * decl.c (grok_special_member_properties): Don't check it
+ (grokfnedcl): Don't call validate_constexpr_fundecl.
+ (start_preparsed_function): Do call it.
+ * pt.c (tsubst_decl): Don't call it.
+ (instantiate_class_template_1): Don't call
+ check_deferred_constexpr_decls.
+ * semantics.c (literal_type_p): Check for any incompleteness.
+ (ensure_literal_type_for_constexpr_object): Likewise.
+ (is_valid_constexpr_fn): Revert deferral changes.
+ (validate_constexpr_fundecl): Likewise.
+ (register_constexpr_fundef): Likewise.
+ (check_deferred_constexpr_decls): Remove.
+
+2011-05-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/48969
+ * pt.c (deduction_tsubst_fntype): Use a VEC initially.
+
+2011-05-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cxx-pretty-print.c: Update comment.
+ * semantics.c (trait_expr_value, finish_trait_expr):
+ Reorder the cases.
+ * parser.c (cp_parser_primary_expression): Likewise.
+
+2011-05-15 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR c++/48994
+ * parser.c (cp_parser_perform_range_for_lookup): Call complete_type.
+
+2011-05-13 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Implement final on class.
+ * class.c (check_bases): Diagnose derivation from a final class.
+ * cp-tree.h (lang_type_class): Add is_final and adjust dummy.
+ (CLASSTYPE_FINAL): New.
+ * parser.c (cp_parser_class_head): Parse class-virt-specifier, set
+ CLASSTYPE_FINAL.
+ * pt.c (instantiate_class_template_1): Copy CLASSTYPE_FINAL.
+
+2011-05-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/48969
+ * pt.c (deduction_tsubst_fntype): New.
+ (fn_type_unification): Use it.
+ (init_template_processing): Initialize hash table.
+ (print_template_statistics): Print hash table stats.
+
+ * call.c (build_op_call): Use timevar_cond_start/stop.
+ (build_user_type_conversion): Likewise.
+
+2011-05-12 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_DEFERRED_CONSTEXPR_CHECK): New.
+ * semantics.c (validate_constexpr_fundecl): Set it.
+ (check_deferred_constexpr_decls): Clear it.
+ (register_constexpr_fundef): Make sure it isn't set.
+ * decl.c (grok_special_member_properties): Check it.
+
+2011-05-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/48948
+ * semantics.c (validate_constexpr_fundecl): Defer checking if
+ an argument type is being defined.
+ (is_valid_constexpr_fn): Add defer_ok parm.
+ (cxx_eval_call_expression): Adjust.
+ (check_deferred_constexpr_decls): New.
+ (literal_type_p): Make sure type isn't being defined.
+ (ensure_literal_type_for_constexpr_object): Handle type being defined.
+ * cp-tree.h: Declare check_deferred_constexpr_decls.
+ * decl.c (grokfndecl): Call validate_constexpr_fundecl here.
+ (start_preparsed_function, cp_finish_decl): Not here.
+ * class.c (finalize_literal_type_property): Don't call
+ validate_constexpr_fundecl.
+ (finish_struct): Call check_deferred_constexpr_decls.
+ * pt.c (tsubst_decl): Call validate_constexpr_fundecl.
+ (instantiate_class_template): Call check_deferred_constexpr_decls.
+
+ * semantics.c (validate_constexpr_fundecl): Check DECL_TEMPLATE_INFO
+ rather than DECL_TEMPLATE_INSTANTIATION.
+ (cxx_eval_call_expression): Likewise.
+
+ * semantics.c (register_constexpr_fundef): Add to hash table here.
+ (validate_constexpr_fundecl): Not here.
+
+ * decl.c (grokdeclarator): Only set DECL_DECLARED_CONSTEXPR_P once.
+
+ * pt.c (build_non_dependent_expr): Don't check null_ptr_cst_p,
+ do call maybe_constant_value in C++0x mode.
+ * semantics.c (cxx_eval_constant_expression): Handle TEMPLATE_DECL.
+
+ PR c++/48745
+ * pt.c (value_dependent_expr_p): Handle CONSTRUCTOR.
+
+2011-05-11 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.h (TYPENAME_TYPE_FULLNAME, TYPEOF_TYPE_EXPR): Use
+ TYPE_VALUES_RAW.
+ (UNDERLYING_TYPE_TYPE, DECLTYPE_TYPE_EXPR): Likewise.
+ (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P): Likewise.
+ (TEMPLATE_TYPE_PARM_INDEX): Likewise.
+
+2011-05-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/48930
+ * class.c (type_build_ctor_call): New.
+ * cp-tree.h: Declare it.
+ * decl.c (check_initializer): Use it instead of
+ TYPE_NEEDS_CONSTRUCTING.
+ * init.c (build_value_init, build_value_init_noctor): Likewise.
+ (perform_member_init, expand_aggr_init_1, build_new_1): Likewise.
+ (build_vec_init): Likewise.
+ * typeck2.c (process_init_constructor_array): Likewise.
+ (process_init_constructor_record): Likewise.
+
+ PR c++/48736
+ * pt.c (tsubst_copy_and_build): Handle substitution of a pack
+ expansion producing another expansion.
+
+2011-05-10 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Fixes for override/final.
+ * class.c (check_for_override): Diagnose final on a nonvirtual
+ member function, diagnose override for a virtual with no matching
+ override. Don't fiddle around with DECL_VINDEX.
+
+2011-05-10 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.def (EXPR_PACK_EXPANSION): Add an operand.
+ * cp-objcp-common.c (cp_common_init_ts): Mark it as TS_TYPED.
+ * cp-tree.h (PACK_EXPANSION_PARAMETER_PACKS): Use the new
+ operand of EXPR_PACK_EXPANSION.
+ (cp_tree_operand_length): Declare.
+ * tree.c (cp_tree_operand_length): Define.
+ (cp_tree_equal): Call it.
+ * pt.c (value_dependent_expr_P): Likewise.
+ * mangle.c (write_expression): Likewise.
+
+2011-05-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/48737
+ PR c++/48744
+ * decl.c (reshape_init): Take a complain parameter and do
+ not call error if tf_error is not set.
+ (check_initializer, reshape_init_r, reshape_init_array,
+ reshape_init_array_1, reshape_init_vector, reshape_init_class):
+ Adjust.
+ * typeck2.c (digest_init_r): Take a complain parameter and
+ pass it to convert_for_initialization.
+ (digest_init, digest_init_flags, process_init_constructor_array,
+ process_init_constructor_record, process_init_constructor_union,
+ process_init_constructor, digest_init_r): Adjust.
+ * init.c (expand_default_init, build_new_1): Likewise.
+ * typeck.c (cp_build_modify_expr): Likewise.
+ * decl2.c (grokfield): Likewise.
+ * call.c (convert_like_real, convert_default_arg): Likewise.
+ * semantics.c (finish_compound_literal): Pass complain to
+ reshape_init and digest_init.
+ * cp-tree.h: Adjust declarations.
+
+2011-05-07 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/48859
+ * init.c (diagnose_uninitialized_cst_or_ref_member_1): stop the
+ recursion if there is user defined constructor.
+
+2011-05-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/34772
+ * decl.c (initialize_local_var): Use DECL_INITIAL for simple
+ initialization.
+
+2011-05-08 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Implement final/override for member functions.
+ * class.c (check_for_override): Check for DECL_OVERRIDE_P.
+ * cp-tree.h (DECL_OVERRIDE_P, DECL_FINAL_P): New.
+ (cp_virt_specifiers, enum virt_specifier): New.
+ * decl.c (set_virt_specifiers): New.
+ (grokdeclarator): Use them. Diagnose virt-specifiers on non-fields.
+ * parser.c (make_call_declarator): add virt-specifiers parameter.
+ (cp_parser_lambda_declarator_opt): Adjust.
+ (cp_parser_direct_declarator): Likewise.
+ (cp_parser_virt_specifier_seq_opt): New.
+ * search.c (check_final_overrider): Diagnose attempts to override
+ a final member function.
+
+2011-05-09 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/48574
+ * class.c (fixed_type_or_null): Use type_dependent_p_push to test
+ if the instance has a dependent initializer.
+
+2011-05-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/48816
+ * cxx-pretty-print.c (pp_cxx_template_declaration): Remove
+ effectively unused variable.
+
+2011-05-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ * name-lookup.h (global_bindings_p): Adjust prototype.
+ * name-lookup.c (global_bindings_p): Return bool.
+
+2011-05-06 Jason Merrill <jason@redhat.com>
+
+ * decl.c (stabilize_save_expr_r): Set *walk_subtrees as
+ appropriate.
+
+ PR c++/48909
+ * semantics.c (cxx_eval_conditional_expression): Check
+ integer_zerop instead.
+ (potential_constant_expression_1): Likewise.
+
+ PR c++/48911
+ * semantics.c (cxx_eval_array_reference): Handle implicit
+ initializers.
+
+2011-05-06 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.h (type_of_this_parm, class_of_this_parm): New functions.
+ * call.c (standard_conversion): Call class_of_this_parm.
+ * cxx-pretty-print.c (pp_cxx_implicit_parameter_type): Likewise.
+ (pp_cxx_direct_abstract_declarator): Likewise.
+ * decl2.c (change_return_type): Likewise.
+ (cp_reconstruct_complex_type): Likewise.
+ * error.c (dump_type_suffix, dump_function_decl): Likewise.
+ * mangle.c (write_function_type): Likewise.
+ * pt.c (unify): Likewise.
+ * typeck.c (merge_types, type_memfn_quals): Likewise.
+ * decl.c (build_this_parm): Call type_of_this_parm.
+
+2011-05-06 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/48838
+ * cp-tree.h (non_static_member_function_p): Declare new function.
+ * tree.c (non_static_member_function_p): Define it.
+ * semantics.c (finish_call_expr): Use it.
+
+2011-05-05 Nathan Froyd <froydnj@codesourcery.com>
+
+ * decl.c (finish_case_label): Omit the loc argument to
+ build_case_label.
+
+2011-05-05 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (REFERENCE_REF_P): Just check the type.
+ * cvt.c (convert_from_reference): Adjust.
+ * pt.c (build_non_dependent_expr): Adjust.
+ * semantics.c (finish_offsetof): Adjust.
+ * tree.c (lvalue_kind): Use it.
+
+ PR c++/48873
+ * tree.c (stabilize_expr): Don't make gratuitous copies of classes.
+
+2011-05-05 Eric Botcazou <ebotcazou@adacore.com>
+
+ * decl.c (start_preparsed_function): Do not set
+ dont_save_pending_sizes_p.
+
+2011-05-05 Joseph Myers <joseph@codesourcery.com>
+
+ * parser.c (cp_parser_objc_method_definition_list): Update call to
+ objc_start_method_definition.
+
+2011-05-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/48749
+ * class.c (resolves_to_fixed_type_p): Don't look closely
+ in templates.
+
+2011-05-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/28501
+ * call.c (add_builtin_candidate): Handle REALPART_EXPR and
+ IMAGPART_EXPR.
+
+2011-05-02 Lawrence Crowl <crowl@google.com>
+
+ * decl.c: (push_local_name): Change TV_NAME_LOOKUP to start/stop.
+ (poplevel): Refactor POP_TIMEVAR_AND_RETURN to plain code.
+ Change TV_NAME_LOOKUP to start/stop.
+ (define_label): Refactor timevar calls out to a wrapper function.
+ Change TV_NAME_LOOKUP to start/stop.
+ (xref_tag): Likewise.
+ (lookup_label): Refactor timevar calls out to a wrapper function.
+ Change TV_NAME_LOOKUP to start_cond/stop_cond.
+
+ * pt.c: (instantiate_class_template): Add a wrapper to push/pop new
+ TV_TEMPLATE_INST.
+ (instantiate_template): Add a wrapper to push/pop new TV_TEMPLATE_INST.
+ (lookup_template_class): Refactor timevar calls out to a wrapper
+ function. Change use of TV_NAME_LOOKUP to TV_TEMPLATE_INST.
+ (instantiate_decl): Change TV_PARSE to TV_TEMPLATE_INST.
+
+ * name-lookup.c: (store_bindings): Change TV_NAME_LOOKUP to start/stop.
+ (poplevel_class): Change TV_NAME_LOOKUP to start_cond/stop_cond.
+ (push_namespace): Likewise.
+ (pop_nested_namespace): Likewise.
+ (pushdecl_namespace_level): Likewise.
+ (store_class_bindings): Likewise.
+ (push_to_top_level): Likewise.
+ (identifier_type_value): Refactor timevar calls out to a wrapper
+ function. Change TV_NAME_LOOKUP to start/stop.
+ (find_binding): Likewise.
+ (push_using_decl): Likewise.
+ (lookup_arg_dependent): Likewise.
+ (push_using_directive): Likewise.
+ (qualified_lookup_using_namespace): Refactor POP_TIMEVAR_AND_RETURN
+ to plain code. Change TV_NAME_LOOKUP to start/stop.
+ (lookup_type_current_level): Likewise. Refactor inner return to
+ break.
+ (pushdecl_class_level): Refactor POP_TIMEVAR_AND_RETURN to plain
+ code. Change TV_NAME_LOOKUP to start_cond/stop_cond.
+ (pushdecl_top_level_1): Likewise.
+ (lookup_using_namespace): Likewise.
+ (pushdecl_with_scope): Refactor timevar calls out to a wrapper
+ function. Change TV_NAME_LOOKUP to start_cond/stop_cond.
+ (push_overloaded_decl): Likewise.
+ (push_class_level_binding): Likewise.
+ (namespace_binding): Likewise.
+ (set_namespace_binding): Likewise.
+ (supplement_binding): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_name_real): Likewise.
+ (lookup_type_scope): Likewise.
+ (namespace_ancestor): Likewise.
+ (lookup_name_innermost_nonclass_level): Likewise.
+ (pushtag): Likewise.
+ (pop_from_top_level): Likewise.
+ (pushdecl_maybe_friend): Refactor timevar calls out to a wrapper
+ function. Change TV_NAME_LOOKUP to start_cond/stop_cond. Wrap long
+ lines.
+ (add_using_namespace): Refactor timevar calls out to a wrapper
+ function. Change TV_NAME_LOOKUP to start_cond/stop_cond. Bypass
+ wrapper on call to self.
+
+ * decl2.c: (cp_write_global_declarations): Add start/stop of
+ new TV_PHASE_DEFERRED, TV_PHASE_CGRAPH, TV_PHASE_CHECK_DBGINFO.
+ Remove push/pop calls to TV_VARCONST.
+
+ * parser.c: Add include of "timevar.h".
+ (cp_parser_explicit_instantiation): Add push/pop calls to
+ TV_TEMPLATE_INST.
+ (cp_parser_enum_specifier): Add push/pop calls to new TV_PARSE_ENUM.
+ (cp_parser_class_specifier): Add wrapper to add push/pop calls to
+ TV_PARSE_STRUCT.
+ (cp_parser_function_definition_from_specifiers_and_declarator): Add
+ push/pop calls to new TV_PARSE_FUNC or TV_PARSE_INLINE.
+ (cp_parser_late_parsing_for_member): Add push/pop calls to
+ new TV_PARSE_INMETH.
+
+ * call.c: Add include of "timevar.h".
+ (convert_class_to_reference): Wrap and add push/pop calls to
+ TV_OVERLOAD.
+ (build_op_call): Likewise.
+ (build_conditional_expr): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+ (build_user_type_conversion): Reorganize to single return and add
+ push/pop calls to TV_OVERLOAD.
+ (perform_overload_resolution): Likewise.
+
+ * Make-lang.in: Add dependence of call.o and parser.o on $(TIMEVAR_H).
+
+2011-05-02 Jason Merrill <jason@redhat.com>
+
+ * tree.c (build_vec_init_expr): Take complain parm.
+ (build_vec_init_elt): Likewise. Free arg vector.
+ (diagnose_non_constexpr_vec_init, build_array_copy): Adjust.
+ * cp-tree.h (VEC_INIT_EXPR_SLOT): Use VEC_INIT_EXPR_CHECK.
+ (VEC_INIT_EXPR_INIT): Likewise.
+ Adjust build_vec_init_expr declaration.
+ * init.c (perform_member_init): Adjust.
+
+ Revert:
+ PR c++/40975
+ * cp-tree.def (VEC_INIT_EXPR): Add third operand.
+ * cp-tree.h (VEC_INIT_EXPR_NELTS): New.
+ * cp-gimplify.c (cp_gimplify_expr) [VEC_INIT_EXPR]: Handle it.
+ * tree.c (build_vec_init_expr): Handle getting pointer/nelts.
+ (build_vec_init_elt): Don't expect an array type.
+ (build_array_copy): Adjust.
+ * init.c (perform_member_init): Adjust.
+ (build_new_1): Use build_vec_init_expr.
+
+ PR c++/48834
+ * tree.c (build_vec_init_expr): Set TREE_SIDE_EFFECTS.
+ Protect an explicit target.
+
+ PR c++/48446
+ * decl.c (stabilize_save_expr_r, stabilize_vla_size): New.
+ (compute_array_index_type): Revert earlier 48446 changes.
+ (grokdeclarator): Use stabilize_vla_size.
+
+2011-05-02 Dmitry Gorbachev <d.g.gorbachev@gmail.com>
+ Eric Botcazou <ebotcazou@adacore.com>
+
+ * parser.c (cp_parser_init_declarator): Set pushed_scope to NULL_TREE
+ instead of inappropriate zero values.
+
+2011-05-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/47969
+ * decl.c (compute_array_index_type): Check build_expr_type_conversion
+ return value for NULL_TREE.
+
+2011-04-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/48606
+ * init.c (perform_member_init): Check build_value_init return
+ value for error_mark_node.
+
+2011-04-29 Diego Novillo <dnovillo@google.com>
+ Le-Chun Wu <lcwu@google.com>
+
+ * call.c (conversion_null_warnings): Also handle assignments
+ when warning about NULL conversions.
+
+2011-04-29 Le-Chun Wu <lcwu@google.com>
+
+ * cp-tree.h (LOOKUP_EXPLICIT_TMPL_ARGS): Define.
+ * call.c (build_new_function_call): Set it for TEMPLATE_ID_EXPRs.
+ (build_over_call): Use it to determine whether to emit a NULL
+ warning for template function instantiations.
+ (build_new_method_call): Set LOOKUP_EXPLICIT_TMPL_ARGS if
+ EXPLICIT_TARGS is set.
+
+2011-04-29 Nicola Pero <nicola.pero@meta-innovation.com>,
+ Mike Stump <mikestump@comcast.net>
+
+ * Make-lang.in ($(srcdir)/cp/cfns.h): Enable the dependency only
+ in maintainer mode. Use the --output-file option of gperf instead
+ of > to prevent creating an empty cp/cfns.h when gperf is not
+ available.
+
+2011-04-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/48798
+ * semantics.c (finish_base_specifier): cv-qualified base class
+ is fine, per DR 484.
+
+2011-04-28 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/48656
+ * semantics.c (finish_call_expr): Don't forget BASELINK nodes when
+ considering call expressions involving a member function.
+
+2011-04-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/48530
+ * tree.c (build_cplus_new): Check build_target_expr return
+ value for error_mark_node.
+
+2011-04-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/48771
+ * semantics.c (literal_type_p): Reference types are literal types,
+ per the FDIS.
+ (valid_type_in_constexpr_fundecl_p): Remove.
+ (is_valid_constexpr_fn): Adjust.
+
+2011-04-27 Jason Merrill <jason@redhat.com>
+
+ PR libstdc++/48760
+ Implement list-initialization of _Complex.
+ * decl.c (reshape_init_r): Allow {real,imag} for _Complex.
+ (check_initializer): Likewise.
+ * call.c (build_complex_conv): New.
+ (implicit_conversion): Call it.
+ (convert_like_real): Handle it.
+ * typeck2.c (check_narrowing): Handle it.
+
+ * init.c (build_vec_delete_1): Look for sfk_deleting_destructor to
+ decide whether to delete.
+ (build_vec_init): Pass sfk_complete_destructor.
+
+ PR c++/40975
+ * cp-tree.def (VEC_INIT_EXPR): Add third operand.
+ * cp-tree.h (VEC_INIT_EXPR_NELTS): New.
+ * cp-gimplify.c (cp_gimplify_expr) [VEC_INIT_EXPR]: Handle it.
+ * tree.c (build_vec_init_expr): Handle getting pointer/nelts.
+ (build_vec_init_elt): Don't expect an array type.
+ (build_array_copy): Adjust.
+ * init.c (perform_member_init): Adjust.
+ (build_new_1): Use build_vec_init_expr.
+
+ * class.c (resolve_address_of_overloaded_function): Don't
+ change OVERLOAD to TREE_LIST.
+ * pt.c (print_candidates_1): Remove nonsensical assert.
+
+ PR c++/48046
+ * parser.c (cp_parser_diagnose_invalid_type_name): Commit
+ to tentative parse sooner.
+
+2011-04-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/42687
+ * parser.c (cp_parser_primary_expression): Set *idk to
+ CP_ID_KIND_NONE for a parenthesized identifier.
+
+ * ptree.c (cxx_print_type) [TYPENAME_TYPE]: Dump fullname.
+ (cxx_print_identifier): Correct indentation.
+
+ PR c++/48530
+ * decl.c (cxx_maybe_build_cleanup): Add complain parm.
+ * tree.c (force_target_expr): Add complain parm.
+ (build_target_expr_with_type): Likewise.
+ (get_target_expr_sfinae): Split out.
+ (build_vec_init_expr, bot_manip): Adjust.
+ * init.c (build_vec_delete, build_vec_delete_1): Add complain parm.
+ (build_delete, build_dtor_call): Likewise.
+ (perform_direct_initialization_if_possible): Adjust.
+ (build_vec_init): Handle error return.
+ * cvt.c (force_rvalue): Add complain parm.
+ Call build_special_member_call directly.
+ * decl2.c (delete_sanity): Add complain parm.
+ (build_cleanup): Adjust.
+ * pt.c (tsubst_copy_and_build, tsubst_expr): Adjust.
+ * semantics.c (finish_stmt_expr_expr): Adjust.
+ (finish_compound_literal): Adjust.
+ * parser.c (cp_parser_delete_expression): Adjust.
+ * typeck2.c (build_functional_cast): Adjust.
+ * cp-tree.h: Adjust.
+
+2011-04-26 Martin Jambor <mjambor@suse.cz>
+
+ * class.c (cp_fold_obj_type_ref): Remove.
+ * cp-tree.h (cp_fold_obj_type_ref): Remove declaration.
+
+2011-04-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cp-tree.def: Add a new UNDERLYING_TYPE tree code.
+ * cp-tree.h (enum cp_trait_kind): Add CPTK_UNDERLYING_TYPE, tidy.
+ (UNDERLYING_TYPE_TYPE): Add.
+ * cp-objcp-common.c (cp_common_init_ts): Mark UNDERLYING_TYPE
+ as TS_COMMON.
+ * parser.c (cp_lexer_next_token_is_decl_specifier_keyword,
+ cp_parser_simple_type_specifier): Handle UNDERLYING_TYPE.
+ (cp_parser_trait_expr): Deal with RID_UNDERLYING_TYPE; tidy.
+ * semantics.c (finish_underlying_type): New.
+ * typeck.c (structural_comptypes): Handle UNDERLYING_TYPE.
+ * error.c (dump_type, dump_type_prefix, dump_type_suffix): Likewise.
+ * cxx-pretty-print.c (p_cxx_type_id): Likewise.
+ * tree.c (cp_walk_subtrees): Likewise.
+ * pt.c (for_each_template_parm_r, tsubst, unify,
+ dependent_type_p_r): Likewise.
+ * mangle.c (write_type): Sorry for __underlying_type.
+
+2011-04-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/48707
+ * decl.c (type_dependent_init_p): New.
+ (cp_finish_decl): Check it.
+ * pt.c (any_type_dependent_elements_p): New.
+ * cp-tree.h: Declare it.
+
+2011-04-20 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (finish_compound_literal): Don't put an array
+ with a dtor in a static variable.
+
+ * call.c (build_over_call): Handle trivial dtor.
+
+ * search.c (lookup_fnfields_slot): Call complete_type.
+
+ PR c++/48594
+ * decl2.c (build_offset_ref_call_from_tree): Move
+ non-dependency of object outside condition.
+
+ PR c++/48657
+ * decl.c (cp_finish_decl): Simplify template handling.
+
+2011-04-20 Jim Meyering <meyering@redhat.com>
+
+ * tree.c (cxx_printable_name_internal): Remove useless if-before-free.
+
+2011-04-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/46304
+ * typeck.c (cp_build_binary_op): Fold COMPLEX_EXPR.
+
+ PR c++/45267
+ * decl.c (duplicate_decls): Keep always_inline attribute
+ in sync with DECL_DISREGARD_INLINE_LIMITS.
+
+2011-04-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/48569
+ * typeck2.c (build_functional_cast): Handle VOID_TYPE.
+
+ PR c++/48537
+ * init.c (build_value_init): Handle UNION_TYPE the same.
+
+2011-04-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/48632
+ * parser.c (cp_parser_omp_for_loop): Don't use cp_parser_omp_for_incr
+ for type dependent pointers.
+
+2011-04-18 Jim Meyering <meyering@redhat.com>
+
+ * pt.c (type_unification_real): Fix typo in comment: s/in in/in/.
+
+2011-04-17 Jan Hubicka <jh@suse.cz>
+
+ * semantics.c (finish_goto_stmt): Do set UNINLINABLE flag on computed
+ gotos.
+
+2011-04-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/48531
+ * typeck2.c (build_functional_cast): Disallow array type.
+
+ * tree.c (get_target_expr): Handle VEC_INIT_EXPR.
+
+2011-04-17 Jan Hubicka <jh@suse.cz>
+
+ * class.c (cp_fold_obj_type_ref): Drop vtable_method.
+
+2011-04-15 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+ Implement N3271
+ * parser.c (cp_convert_range_for): Split into
+ cp_parser_perform_range_for_lookup.
+ (cp_parser_perform_range_for_lookup): New.
+ (cp_parser_range_for_member_function): New.
+ (cp_parser_for_init_statement): Correct error message.
+ * semantics.c (finish_call_expr): Accept COMPONENT_REF.
+
+2011-04-14 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_protocol_declaration): Updated for
+ change from objc_declare_protocols() to objc_declare_protocol().
+
+2011-04-14 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR objc++/48479
+ * typeck.c (cxx_mark_addressable) [CONST_DECL]: Mark addressable
+ and return immediately.
+
+2011-04-14 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.def (SWITCH_STMT): Add an extra operand.
+ * cp-objcp-common.c (cp_common_init_ts): Mark it as TS_TYPED.
+ * cp-tree.h (SWITCH_STMT_SCOPE): Define.
+ * semantics.c (begin_switch__stmt): Pass scope to build_stmt.
+ (finish_switch_stmt): Use SWITCH_STMT_SCOPE instead of TREE_CHAIN.
+
+2011-04-14 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.def (IF_STMT): Add an extra operand.
+ * cp-objcp-common.c (cp_common_init_ts): Mark it as TS_TYPED.
+ * cp-tree.h (IF_SCOPE): Define.
+ * semantics.c (begin_if_stmt): Pass scope to build_stmt.
+ (finish_if_stmt): Use IF_SCOPE instead of TREE_CHAIN.
+
+2011-04-14 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-tree.def (FOR_STMT, RANGE_FOR_STMT): Add an extra operand.
+ * cp-objcp-common.c (cp_common_init_ts): Mark them as TS_TYPED.
+ * cp-tree.h (FOR_SCOPE, RANGE_FOR_SCOPE): Define.
+ * semantics.c (begin_for_stmt): Pass an extra arg to build_stmt.
+ Use FOR_SCOPE instead of TREE_CHAIN.
+ (begin_range_for_stmt): Likewise, with RANGE_FOR_SCOPE.
+ (finish_for_stmt): Likewise.
+
+2011-04-14 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_postfix_expression): Fix flags passed to
+ build_new_method_call.
+ * semantics.c (finish_call_expr): Likewise.
+
+ PR c++/48531
+ * init.c (build_value_init_noctor): Check complain consistently.
+
+ PR c++/48557
+ * typeck.c (cp_build_binary_op): Don't decay void operands.
+
+ PR c++/48446
+ * decl.c (compute_array_index_type): Use get_temp_regvar instead
+ of variable_size.
+ * init.c (get_temp_regvar): No longer static.
+ * cp-tree.h: Declare it.
+
+2011-04-14 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_class_declaration): Updated for change
+ in objc_declare_class().
+
+2011-04-14 Nathan Froyd <froydnj@codesourcery.com>
+
+ * decl.c (poplevel): Use block_chainon.
+
+2011-04-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/48594
+ * decl2.c (build_offset_ref_call_from_tree): Fix calling a functor
+ or pointer to (non-member) function.
+
+2011-04-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/48570
+ * semantics.c (cxx_eval_array_reference): Handle reading from
+ wchar_t, char16_t and char32_t STRING_CST.
+
+2011-04-13 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/48574
+ * class.c (fixed_type_or_null): We cannot determine the dynamic
+ type of a reference variable if its initializer is dependent.
+
+2011-04-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/48581
+ * pt.c (tsubst_copy_and_build) [CALL_EXPR]: Don't complain about
+ unqualified lookup failing if we're still in a template.
+
+2011-04-12 Nathan Froyd <froydnj@codesourcery.com>
+
+ * cp-lang.c (cp_init_ts): Call cp_common_init_ts. Move
+ tree_contains_struct initialization to...
+ * cp-objcp-common.c (cp_common_init_ts): ...here. Use MARK_*
+ macros.
+ * cp-objcp-common.h (cp_common_init_ts): Declare.
+ * cp-tree.h (union lang_tree_node): Check for TS_COMMON before
+ calling TREE_CHAIN.
+
+2011-04-12 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_message_expression): Updated call
+ to objc_build_message_expr.
+
+2011-04-12 Martin Jambor <mjambor@suse.cz>
+
+ * class.c (cp_fold_obj_type_ref): Call cgraph_get_node instead of
+ cgraph_get_create_node.
+ * decl2.c (cp_write_global_declarations): Call cgraph_get_node
+ instead of cgraph_get_create_node.
+ * method.c (make_alias_for_thunk): Call cgraph_get_node
+ instead of cgraph_get_create_node, assert it returns non-NULL.
+ (use_thunk): Likewise.
+ * optimize.c (maybe_clone_body): Call cgraph_same_body_alias only
+ when flag_syntax_only is not set. Call cgraph_get_node instead of
+ cgraph_get_create_node.
+ (maybe_clone_body): Call cgraph_get_node instead of
+ cgraph_get_create_node.
+
+2011-04-12 Martin Jambor <mjambor@suse.cz>
+
+ * class.c (cp_fold_obj_type_ref): Call cgraph_get_create_node
+ instead of cgraph_node.
+ * decl2.c (cxx_callgraph_analyze_expr): Likewise.
+ (cp_write_global_declarations): Likewise.
+ * optimize.c (maybe_clone_body): Likewise.
+ * semantics.c (maybe_add_lambda_conv_op): Likewise.
+ * mangle.c (mangle_decl): Likewise.
+ * method.c (make_alias_for_thunk): Likewise.
+ (use_thunk): Likewise.
+
+2011-04-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/48535
+ * decl.c (cp_complete_array_type_or_error): New.
+ * semantics.c (finish_compound_literal): Use it.
+ * cp-tree.h: Declare it.
+
+ PR c++/48535
+ * semantics.c (finish_compound_literal): Handle references.
+
+ PR c++/48535
+ * semantics.c (finish_compound_literal): Take complain parm.
+ (build_lambda_object): Adjust.
+ * cp-tree.h: Adjust.
+ * call.c (convert_like_real): Adjust.
+ * decl.c (check_initializer): Adjust.
+ * parser.c (cp_parser_postfix_expression): Adjust.
+ (cp_parser_functional_cast): Adjust.
+ * pt.c (tsubst_copy_and_build): Adjust.
+ * typeck2.c (process_init_constructor_record): Adjust.
+
+ PR c++/48534
+ * cvt.c (ocp_convert): Use build_nop to convert to underlying type
+ of scoped enum.
+
+ PR c++/48523
+ * tree.c (maybe_dummy_object): Use build_x_indirect_ref rather
+ than cp_build_indirect_ref.
+
+ PR c++/48457, Core 1238
+ * call.c (reference_binding): Allow rvalue reference to bind to
+ function lvalue.
+ * tree.c (lvalue_kind): Functions are always lvalues.
+
+2011-04-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/48500
+ * semantics.c (potential_constant_expression_1) [CALL_EXPR]: Check
+ arguments even if we don't know the function.
+
+ PR c++/48481
+ * tree.c (build_overload): Allow an unwrapped FUNCTION_DECL
+ at the end of the chain.
+ * pt.c (dependent_template_p): Use OVL_CURRENT/NEXT.
+ (iterative_hash_template_arg): Likewise.
+
+ PR c++/48481
+ * cp-tree.h (OVL_ARG_DEPENDENT): New.
+ * name-lookup.c (add_function): Set it.
+ * semantics.c (finish_call_expr): Free OVERLOADs if it's set.
+
+ PR c++/48481
+ * call.c (build_user_type_conversion_1): Use lookup_fnfields_slot.
+ Release unused vector.
+
+ PR c++/48451
+ * pt.c (fn_type_unification): Don't clear incomplete pack flag.
+ (type_unification_real): Clear it here instead.
+
+ PR c++/48468
+ * except.c (build_noexcept_spec): Propagate error_mark_node.
+ (finish_noexcept_expr): Likewise.
+
+ PR c++/48452
+ * typeck.c (build_x_compound_expr_from_list): Return error_mark_node
+ in SFINAE context.
+
+ PR c++/48450
+ * call.c (resolve_args): Take complain.
+ (build_new_function_call, build_operator_new_call): Pass it.
+ (build_op_call, build_new_op, build_new_method_call): Pass it.
+
+ PR c++/48450
+ * typeck.c (check_for_casting_away_constness): Take complain.
+ (build_static_cast_1, build_reinterpret_cast_1): Pass it.
+ (build_const_cast_1): Pass it. Take full complain parm.
+ (build_const_cast, cp_build_c_cast): Adjust.
+
+ * tree.c (build_aggr_init_expr): Always return error_mark_node
+ on abstract violation.
+
+ PR c++/48450
+ * tree.c (build_cplus_new, build_aggr_init_expr): Take complain.
+ (bot_manip): Adjust.
+ * cp-tree.h: Adjust.
+ * call.c (convert_like_real, build_cxx_call): Adjust.
+ (perform_direct_initialization_if_possible): Adjust.
+ * cvt.c (ocp_convert): Adjust.
+ * init.c (build_value_init): Adjust.
+ * semantics.c (maybe_add_lambda_conv_op): Adjust.
+ * typeck.c (unary_complex_lvalue, cp_build_modify_expr): Adjust.
+ * typeck2.c (build_functional_cast): Adjust.
+
+ * init.c (build_value_init_noctor): Handle REFERENCE_TYPE at top
+ level.
+ (perform_member_init): Not here.
+ * typeck2.c (build_functional_cast): Limit REFERENCE_TYPE special
+ case to templates.
+ (abstract_virtuals_error_sfinae): Remove RESULT_DECL special case.
+
+ PR c++/48449
+ * typeck2.c (build_functional_cast): Check complain consistently.
+ Use build_value_init and abstract_virtuals_error_sfinae.
+ (abstract_virtuals_error_sfinae): Split out.
+ * cp-tree.h: Declare it.
+ * init.c (build_new_1): Use it.
+ (build_value_init_noctor): Handle FUNCTION_TYPE.
+
+ * semantics.c (finish_decltype_type): Simplify handling of unknown
+ type.
+
+ * semantics.c (finish_decltype_type): Add complain parm.
+ * cp-tree.h: Adjust.
+ * parser.c (cp_parser_decltype): Adjust.
+ * pt.c (tsubst): Adjust.
+
+ PR c++/48450
+ * cvt.c (ocp_convert): Handle converting scoped enum to bool.
+
+2011-03-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/48277
+ * semantics.c (finish_call_expr): Remove assert.
+
+ PR c++/48280
+ * method.c (defaultable_fn_check): Templates are not defaultable.
+
+ * parser.c (cp_parser_init_declarator): Avoid redundant
+ cp_finish_decl for member declarations.
+
+2011-03-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/48212
+ * semantics.c (non_const_var_error): Just return if DECL_INITIAL
+ is error_mark_node.
+
+2011-03-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/48369
+ * semantics.c (potential_constant_expression_1): Handle
+ UNORDERED_EXPR and ORDERED_EXPR.
+
+ PR c++/48281
+ * semantics.c (finish_compound_literal): Do put static/constant
+ arrays in static variables.
+
+ * call.c (convert_like_real) [ck_list]: Build up the
+ initializer_list object directly.
+ * decl.c (build_init_list_var_init): Adjust.
+
+ * call.c (convert_like_real): Correct TREE_CONSTANT on CONSTRUCTOR.
+ * decl.c (reshape_init_array_1): Likewise.
+
+2011-03-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/48265
+ * pt.c (value_dependent_expression_p) [VAR_DECL]: Make sure
+ the variable is constant before looking at its initializer.
+
+ PR c++/48319
+ * pt.c (value_dependent_expression_p): Handle TEMPLATE_ID_EXPR.
+
+ PR c++/48089
+ * semantics.c (potential_constant_expression_1): Change error about
+ use of *this in constructor into sorry.
+
+ PR c++/48296
+ * decl.c (cp_finish_decl): Defer validation of constexpr member
+ functions.
+ * class.c (finalize_literal_type_property): Validate them here.
+ * semantics.c (is_valid_constexpr_fn): Don't check completeness.
+
+ * semantics.c (is_valid_constexpr_fn): Specify input location.
+
+2011-03-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/48313
+ * pt.c (maybe_adjust_types_for_deduction): Handle T&& deduction
+ from overloaded function.
+
+ Core 1232
+ * call.c (build_array_conv): New.
+ (implicit_conversion): Use it.
+
+ * call.c (reference_binding): Allow direct binding to an array
+ rvalue.
+
+ Core 898
+ * parser.c (cp_parser_compound_statement): Add function_body parm.
+ Complain about non-body compound-stmt in constexpr fn.
+ (cp_parser_primary_expression, cp_parser_statement): Adjust.
+ (cp_parser_implicitly_scoped_statement): Adjust.
+ (cp_parser_function_body, cp_parser_try_block): Adjust.
+ (cp_parser_handler, cp_parser_objc_synchronized_statement): Adjust.
+ (cp_parser_objc_try_catch_finally_statement): Adjust.
+
+ Core 898
+ * semantics.c (constexpr_fn_retval): New. Allow using-declaration
+ and using-definition.
+ (register_constexpr_fundef): Call it.
+
+ * except.c (build_noexcept_spec): Call cxx_constant_value after
+ converting to bool.
+
+2011-03-25 Kai Tietz <ktietz@redhat.com>
+
+ * lex.c (interface_strcmp): Handle dos-paths.
+ (handle_pragma_implementation): Use filename_cmp instead of
+ strcmp.
+ (in_main_input_context): Likewise.
+
+2011-03-25 Jason Merrill <jason@redhat.com>
+
+ Core 1135
+ * method.c (defaulted_late_check): Check for exception spec mismatch.
+ (defaultable_fn_check): Allow exception spec and virtual.
+ * class.c (check_for_override): A virtual dtor is non-trivial.
+
+ PR c++/48289
+ * pt.c (build_non_dependent_expr): Keep dereferences outside the
+ NON_DEPENDENT_EXPR.
+
+2011-03-25 Kai Tietz <ktietz@redhat.com>
+
+ * decl.c (decls_match): Replace target hook
+ call of comp_type_attributes by version in tree.c file.
+ * search.c (check_final_overrider): Likewise.
+ * typeck.c (structural_comptypes): Likewise.
+
+2011-03-21 Kai Tietz <ktietz@redhat.com>
+
+ PR target/12171
+ * cxx-pretty-print.c (pp_cxx_ptr_operator):
+ Display allowed attributes for function pointer types.
+ * error.c (dump_type_prefix): Likewise.
+
+ * tree.c (cxx_attribute_table): Adjust table.
+
+2011-03-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/48162
+ * semantics.c (finish_call_expr): Allow TARGET_EXPR for now.
+
+ PR c++/48118
+ * call.c (build_over_call): Don't skip ck_rvalue.
+
+2011-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/47504
+ * semantics.c (cxx_eval_constant_expression) [NOP_EXPR]: Don't let
+ the conversion set TREE_OVERFLOW.
+
+ Core 1212
+ * semantics.c (finish_decltype_type): Return T&& for xvalue.
+ * typeck.c (unlowered_expr_type): Preserve cv-quals.
+
+ PR c++/48166
+ * decl.c (revert_static_member_fn): Strip function-cv-quals.
+
+2011-03-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/48089
+ * semantics.c (potential_constant_expression_1): Don't allow *this
+ in a constructor.
+ (register_constexpr_fundef): Use potential_rvalue_constant_expression.
+
+ PR c++/47301
+ * decl.c (compute_array_index_type): Don't bother trying to deal
+ with literal classes in ABI v1.
+
+ PR c++/46336
+ * decl.c (duplicate_decls): Return NULL_TREE for clashing
+ C functions.
+
+ PR c++/47570
+ * semantics.c (cxx_eval_constant_expression) [COMPOUND_EXPR]: Don't
+ use the generic binary expression handling.
+
+2011-03-16 Diego Novillo <dnovillo@google.com>
+
+ * Make-lang.in (CXX_PARSER_H): New.
+ (cp/parser.o): Add dependency on CXX_PARSER_H.
+ Add dependency on tree-pretty-print.h
+ (cp/cp-lang.o): Add dependency on CXX_PARSER_H.
+ * cp-lang.c: Include parser.h.
+ * parser.c: Include parser.h.
+ (struct cp_token): Add bitfield purged_p.
+ Update all users.
+ Move to parser.h.
+ (CPP_PURGED): Remove. Update all users.
+ (struct cp_lexer): Change field buffer to be a VEC of cp_token.
+ Remove field buffer_length.
+ Update all users.
+ Move to parser.h.
+ (struct tree_check): Move to parser.h.
+ (cp_token_position): Likewise.
+ (struct cp_token_cache): Likewise.
+ (CPP_KEYWORD): Likewise.
+ (CPP_TEMPLATE_ID): Likewise.
+ (CPP_NESTED_NAME_SPECIFIER): Likewise.
+ (N_CP_TTYPES): Likewise.
+ (enum cp_parser_status_kind): Likewise.
+ (struct cp_parser_context): Likewise.
+ (struct cp_default_arg_entry_d): Likewise.
+ (struct cp_unparsed_functions_entry_d): Likewise.
+ (struct cp_parser): Likewise.
+ (cp_lexer_dump_tokens): New.
+ (cp_lexer_debug_tokens): New.
+ (cp_lexer_finished_p): New.
+ (cp_lexer_alloc): Factor out of cp_lexer_new_main.
+ (cp_lexer_new_main): Re-write main lexing loop to push
+ tokens into the new VEC buffer.
+ (cp_lexer_print_token): Improve printing of CPP_NUMBER tokens.
+ Do not abort if the token type is not recognized, just print
+ its code.
+ * parser.h: New file.
+ * config-lang.in (gtfiles): Add cp/parser.h.
+
+2011-03-16 Jason Merrill <jason@redhat.com>
+
+ Core 1148
+ * typeck.c (check_return_expr): Fix conditions for setting
+ LOOKUP_PREFER_RVALUE.
+
+ * call.c (build_over_call): Remove require_complete_type_sfinae call.
+
+ PR c++/48132
+ * decl.c (check_array_designated_initializer): Allow integer index.
+ (reshape_init_array_1): Set index on the elements.
+
+2011-03-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/48113
+ * typeck.c (convert_for_initialization): Use
+ perform_implicit_conversion_flags.
+ * call.c (standard_conversion): If LOOKUP_PREFER_RVALUE, set
+ rvaluedness_matches_p on ck_rvalue.
+ (convert_like_real) [ck_rvalue]: And restore it here.
+
+ PR c++/48115
+ * call.c (convert_arg_to_ellipsis): Handle incomplete type.
+
+2011-03-16 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_abort_tentative_parse): Make sure we haven't
+ committed to this tentative parse.
+
+ PR c++/47999
+ * semantics.c (finish_call_expr): Preserve reference semantics
+ in templates.
+
+ * call.c (convert_default_arg): Use LOOKUP_IMPLICIT.
+
+2011-03-16 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-objcp-common.c (cp_function_decl_explicit_p): Don't crash if
+ DECL_LANG_SPECIFIC is NULL.
+
+2011-03-15 Jason Merrill <jason@redhat.com>
+
+ Core 1074
+ * pt.c (value_dependent_expression_p) [NOEXCEPT_EXPR]: Don't
+ check value_dependent_expression_p on the operand.
+
+ * semantics.c (push_cx_call_context): Return bool.
+ (cxx_eval_call_expression): Handle excess depth.
+
+ Core 1191
+ * method.c (synthesized_method_walk): Cleanups don't affect the
+ triviality of a constructor, but do affect deletion and exception
+ specification.
+
+2011-03-15 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+ * decl2.c (cp_check_const_attributes): New.
+ (cplus_decl_attributes): Call cp_check_const_attributes.
+
+2011-03-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/34758
+ * call.c (convert_default_arg): Use DECL_ORIGIN of fn. Check for
+ recursion first.
+ (push_defarg_context, pop_defarg_context): New.
+ * parser.c (cp_parser_late_parsing_default_args): Use them.
+ * cp-tree.h: Declare them.
+
+2011-03-11 Dodji Seketeli <dodji@redhat.com>
+
+ * call.c (add_builtin_candidate)<case INDIRECT_REF>: The type of
+ the argument of the indirection operator should not be dependent.
+ Fix the comment.
+
+2011-03-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/47125
+ * pt.c (tsubst) [TYPENAME_TYPE]: Only give errors if tf_error.
+
+ PR c++/47144
+ * parser.c (cp_parser_template_type_arg): Set
+ type_definition_forbidden_message.
+
+ PR c++/47808
+ * decl.c (compute_array_index_type): Discard folding
+ if it didn't produce a constant.
+
+2011-03-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/48035
+ * init.c (build_zero_init_1): Extracted from build_zero_init.
+ Add FIELD_SIZE argument, if non-NULL and field bit_position
+ as not smaller than that, don't add that field's initializer.
+ Pass DECL_SIZE as last argument to build_zero_init_1
+ for DECL_FIELD_IS_BASE fields.
+ (build_zero_init): Use build_zero_init_1.
+
+2011-03-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/48029
+ * pt.c (iterative_hash_template_arg): Remove special case for
+ ARRAY_TYPE.
+
+ PR c++/47198
+ * parser.c (cp_parser_single_declaration): Just return if
+ cp_parser_parse_and_diagnose_invalid_type_name complained.
+
+2011-03-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/44629
+ * pt.c (unify): An unresolved overload is a nondeduced context.
+
+2011-03-09 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/47714
+ * method.c (use_thunk): Clear addressable flag of thunk arguments.
+
+2011-03-08 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/47705
+ * pt.c (convert_nontype_argument): Only call decay_conversion on
+ arrays.
+
+2011-03-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/47488
+ * mangle.c (write_template_arg_literal) [STRING_CST]: Sorry.
+
+ PR c++/47705
+ * pt.c (convert_nontype_argument): Don't crash on non-pointer
+ argument to pointer parameter.
+
+ PR c++/45651
+ * pt.c (instantiate_decl): Don't clear DECL_INTERFACE_KNOWN on
+ !TREE_PUBLIC decls.
+
+2011-03-08 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/47957
+ * name-lookup.c (binding_to_template_parms_of_scope_p): Only
+ consider scopes of primary template definitions. Adjust comments.
+
+2011-03-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/48003
+ * pt.c (convert_nontype_argument): Fix -fpermissive allowing
+ integer overflow.
+ * semantics.c (potential_constant_expression_1): Check TREE_OVERFLOW.
+
+ PR c++/48015
+ * init.c (constant_value_1): Always require init to be TREE_CONSTANT.
+
+ PR c++/48008
+ * mangle.c (write_type): Strip cv-quals from FUNCTION_TYPE here.
+ (write_CV_qualifiers_for_type): Not here.
+
+2011-03-06 Joseph Myers <joseph@codesourcery.com>
+
+ * lang-specs.h: Match -save-temps* instead of -save-temps.
+
+2011-03-05 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_expression): Change ABI v6 to v5.
+ (write_type): Likewise.
+
+2011-03-04 Jan Hubicka <jh@suse.cz>
+
+ PR lto/47497
+ * optimize.c (maybe_clone_body): Update call of cgraph_same_body_alias
+ and cgraph_add_thunk.
+ * method.c (make_alias_for_thunk, use_thunk): Likewise.
+ * mangle.c (mangle_decl): Likewise.
+
+2011-03-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/47971
+ * pt.c (tsubst_copy_and_build) [PSEUDO_DTOR_EXPR]: Use tsubst for type.
+ (tsubst_copy) [default]: Just return t if !ENABLE_CHECKING.
+
+ PR c++/46220
+ * search.c (check_final_overrider): Allow pointer to same incomplete
+ class type with different cv-quals.
+
+2011-03-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/47974
+ * pt.c (tsubst_template_args): Check argument t for error_mark_node.
+
+2011-03-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/47950
+ * pt.c (tsubst_copy_and_build) [TARGET_EXPR]: Retain TREE_CONSTANT.
+
+2011-03-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/47950
+ * parser.c (cp_parser_condition): Don't fold_non_dependent_expr here.
+
+ PR c++/47774
+ * tree.c (build_vec_init_elt): Split out from...
+ (build_vec_init_expr): ...here.
+ (diagnose_non_constexpr_vec_init): New fn.
+ * semantics.c (potential_constant_expression_1): Use it.
+ * cp-tree.h: Declare it.
+
+2011-03-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/46159
+ * parser.c (cp_parser_primary_expression): Don't warn about a
+ failed tentative parse.
+
+ PR c++/47200
+ * semantics.c (cxx_bind_parameters_in_call): Don't call
+ adjust_temp_type on non-constant args.
+
+ PR c++/47851
+ * call.c (standard_conversion): Provide requested cv-quals on
+ class rvalue conversion.
+
+ PR c++/46282
+ * decl2.c (grokbitfield): Handle type-dependent width.
+
+2011-02-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/47873
+ * class.c (update_vtable_entry_for_fn): Check BINFO_LOST_PRIMARY_P
+ after checking for a non-thunk.
+
+2011-02-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/47904
+ * tree.c (cp_tree_equal): Compare DECL_PARM_LEVEL.
+ * pt.c (iterative_hash_template_arg): And hash it.
+
+ PR c++/47897
+ * semantics.c (non_const_var_error): Split out from...
+ (cxx_eval_constant_expression): ...here.
+ (potential_constant_expression_1) [VAR_DECL]: Use it.
+ Allow dependent variables.
+
+2011-02-24 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_constant_expression): Set
+ non_integral_constant_expression correctly for C++0x too.
+ (cp_parser_static_assert): Allow non-constant expression.
+ (cp_parser_direct_declarator): Expect non_constant_p to be set
+ properly for C++0x.
+ * pt.c (value_dependent_expression_p): Handle TYPEID_EXPR.
+ * semantics.c (maybe_constant_value): Check type_unknown_p too.
+ (potential_rvalue_constant_expression): New.
+ (require_potential_rvalue_constant_expression): New.
+
+2011-02-23 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_PARM_LEVEL): New.
+ (struct lang_decl_parm): Add level field.
+ * name-lookup.c (function_parm_depth): New fn.
+ * name-lookup.h: Declare it.
+ * parser.c (cp_parser_parameter_declaration_list): Use it.
+ * mangle.c (struct globals): Add parm_depth field.
+ (write_bare_function_type): Adjust it.
+ (write_expression): Include the level delta in PARM_DECL mangling
+ for abi >= 6.
+
+ * semantics.c (finish_decltype_type): Remove shortcut for decltype
+ of id-expression.
+ * mangle.c (write_type) [DECLTYPE_TYPE]: Strip it here for abi < 6.
+
+2011-02-23 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/46868
+ * parser.c (cp_parser_class_specifier): Require a closing brace
+ to attempt error recovery.
+
+2011-02-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/47833
+ * pt.c (struct pending_template): Add chain_next GTY option.
+ * decl.c (struct named_label_use_entry): Likewise.
+
+2011-02-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/47242
+ * semantics.c (build_lambda_object): Bail out if a field is
+ error_mark_node.
+
+2011-02-22 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/47666
+ * class.c (dfs_declare_virt_assop_and_dtor)
+ (declare_virt_assop_and_dtor): New static functions.
+ (add_implicitly_declared_members): Use
+ declare_virt_assop_and_dtor.
+
+2011-02-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/47207
+ * decl2.c (decl_constant_var_p): A constexpr var needs an
+ initializer to be constant.
+ * semantics.c (cxx_eval_constant_expression): Complain about
+ constexpr var used in its own initializer.
+ * call.c (set_up_extended_ref_temp): Set
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P too.
+
+2011-02-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/47199
+ * semantics.c (cxx_eval_call_expression): Call
+ cxx_eval_constant_expression in trivial shortcut.
+
+ PR c++/46831
+ * call.c (convert_class_to_reference): Don't try to set up a
+ second conv sequence for non-viable candidates.
+
+ PR c++/47703
+ * error.c (location_of): Handle non-tagged types.
+
+ PR c++/46472
+ * method.c (process_subob_fn): Instantiate constexpr templates.
+ * optimize.c (maybe_clone_body): Propagate DECL_DECLARED_CONSTEXPR_P.
+
+2011-02-20 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/46394
+ * pt.c (tsubst_pack_expansion): do not use
+ cp_tree_equal/same_type_p to detect an expansion of a parameter
+ pack.
+
+2011-02-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/47503
+ * semantics.c (cxx_eval_call_expression): Shortcut trivial copy.
+
+2011-02-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/47795
+ * semantics.c (finish_non_static_data_member): Early return if
+ object is error_mark_node.
+
+2011-02-18 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/47208
+ * pt.c (do_auto_deduction): Do not mention error_mark_node in
+ diagnostics.
+ * semantics.c (finish_id_expression): Do not pass erroneous decl
+ to decl_constant_var_p.
+
+2011-02-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/47783
+ * cvt.c (convert_from_reference): Call mark_exp_read.
+
+2011-02-11 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/47172
+ * pt.c (finish_call_expr): Consider a call expression that has a
+ dependent "this" pointer as being dependent. Add comments.
+ (dependent_type_p, type_dependent_expression_p): Update comments.
+
+2011-02-16 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/47326
+ * pt.c (tsubst_copy)<case SIZEOF_EXPR>: Ensure that even pack
+ expansion arguments are not evaluated.
+
+2011-02-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/47704
+ * cp-tree.h (ENUM_FIXED_UNDERLYING_TYPE_P): Use TYPE_LANG_FLAG_5
+ instead of TYPE_LANG_FLAG_3.
+ * pt.c (lookup_template_class): Copy over
+ ENUM_FIXED_UNDERLYING_TYPE_P.
+
+2011-02-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/46807
+ * method.c (synthesized_method_walk): Always exit early for
+ trivial fn in C++98 mode.
+
+2011-02-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/47482
+ * parser.c (cp_parser_enumerator_definition): Call
+ fold_non_dependent_expr.
+
+2011-02-09 Jason Merrill <jason@redhat.com>
+
+ * decl.c (cp_make_fname_decl): Set DECL_THIS_STATIC at toplevel.
+ * semantics.c (finish_fname): Only return the name if we're in
+ a function.
+
+ * decl.c (build_enumerator): Don't perform integral promotions on
+ non-integral constants.
+
+ * cvt.c (convert_to_void): Handle null op1.
+
+ * class.c (type_has_constexpr_default_constructor): Make sure the
+ caller stripped an enclosing array.
+ * init.c (perform_member_init): Strip arrays before calling it.
+
+ PR c++/47511
+ * semantics.c (potential_constant_expression_1): Handle TEMPLATE_DECL.
+
+2011-02-03 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/47398
+ * tree.c (cp_tree_equal)<TEMPLATE_PARM_INDEX>: Take the number of
+ template parameters in account.
+
+2011-02-03 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c++/46890
+ * parser.c (cp_parser_class_specifier): Fix setting of
+ want_semicolon.
+
+2011-01-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/47416
+ * semantics.c (build_data_member_initialization): Handle
+ STATEMENT_LIST always instead of just for CLEANUP_BODY.
+
+2011-01-31 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * g++spec.c (lang_specific_driver) [HAVE_LD_STATIC_DYNAMIC] Use
+ LD_STATIC_OPTION, LD_DYNAMIC_OPTION.
+
+2011-01-29 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/47311
+ * cp-tree.h (fixup_template_parms): Declare.
+ * pt.c (end_template_parm_list): Do not fixup template parms here.
+ (fixup_template_parms): Remove static. Fix typo in the
+ comments. Remove useless code statement.
+ (fixup_template_parm): For a template template parameter, fixup
+ its attributes before fixing up its type.
+ * parser.c
+ (cp_parser_template_declaration_after_export): After parsing
+ template parameters fixup their types.
+
+2011-01-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/47476
+ * semantics.c (potential_constant_expression_1): Handle
+ TRUTH_XOR_EXPR.
+
+2011-01-26 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ PR c++/43601
+ * semantics.c (expand_or_defer_fn_1): Handle it.
+ * decl2.c (decl_needed_p): Likewise.
+
+2011-01-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/47041
+ * semantics.c (build_constexpr_constructor_member_initializers):
+ Handle trivial copy.
+
+2011-01-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/47388
+ * semantics.c (begin_for_stmt): If -fno-for-scope, don't
+ assume init must be NULL if scope is NULL.
+ (begin_range_for_stmt): Likewise.
+
+2011-01-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/46552
+ * semantics.c (cxx_eval_constant_expression): Handle OFFSET_REF.
+
+ PR c++/46977
+ * semantics.c (potential_constant_expression_1): Split out from
+ potential_constant_expression. Add want_rval parm. Handle
+ template expression forms. Don't enforce restriction on address
+ of automatic variable here. Add a couple of diagnostics that
+ had been missing.
+ (require_potential_constant_expression): New entry point.
+ (build_data_member_initialization, register_constexpr_fundef): Adjust.
+ (maybe_constant_value): Check potential_constant_expression.
+ * pt.c (fold_non_dependent_expr_sfinae): Likewise.
+ * tree.c (build_vec_init_expr): Adjust.
+
+2011-01-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/47303
+ * decl2.c (finish_anon_union): Only call mangle_decl if TREE_STATIC
+ or DECL_EXTERNAL.
+
+2011-01-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/47067
+ * semantics.c (base_field_constructor_elt): New fn.
+ (cxx_eval_bare_aggregate): Use it.
+ (build_data_member_initialization): Leave COMPONENT_REF for
+ vfield inits.
+
+2011-01-14 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+ * parser.c (cp_parser_range_for): Remove the "unused variable" warning
+ workaround.
+
+2011-01-15 Giovanni Funchal <gafunchal@gmail.com>
+ Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR c++/33558
+ * decl.c (grokdeclarator): Reject mutable reference members.
+
+2011-01-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/47289
+ * pt.c (coerce_template_parms): Fix error recovery.
+
+ PR c++/46903
+ * typeck2.c (check_narrowing): Only check arithmetic types.
+
+ PR c++/46688
+ * tree.c (build_vec_init_expr): Handle flexible array
+ properly.
+
+2011-01-13 Kai Tietz <kai.tietz@onevision.com>
+
+ PR c++/47213
+ * cp-tree.h (CLASSTYPE_VISIBILITY): Use
+ TYPE_MAIN_DECL instead of TYPE_NAME.
+ (CLASSTYPE_VISIBILITY_SPECIFIED): Likewise.
+ * decl2.c (determine_visibility): Add check
+ of CLASS_TYPE_P for underlying_type.
+
+2011-01-12 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+
+ * cp-tree.h (begin_for_scope): New prototype.
+ (begin_for_stmt): Update prototype.
+ (begin_range_for_stmt): Update prototype.
+ * init.c (build_vec_init): Update call to begin_for_stmt.
+ * parser.c (cp_parser_for): New.
+ (cp_parser_c_for): Add three new parameters.
+ (cp_parser_range_for): Likewise. Most parsing code removed.
+ (cp_parser_iteration_statement): Call cp_parser_for instead of
+ cp_parser_c_for and cp_parser_range_for.
+ (cp_parser_for_init_statement): Add new parameter and return type.
+ (cp_parser_block_declaration): Update call to
+ cp_parser_simple_declaration.
+ (cp_parser_simple_declaration): Add new parameter.
+ Update call to cp_parser_init_declarator.
+ (cp_parser_init_declarator): Add new parameter.
+ * pt.c (tsubst_expr): Update call to begin_for_stmt.
+ * semantics.c (begin_for_scope): New.
+ (begin_for_stmt): Add two new parameters.
+ (begin_range_for_stmt): Likewise.
+
+2011-01-12 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * parser.c (cp_parser_objc_at_property_declaration): Improved
+ error message.
+
+2011-01-11 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/46955
+ * cp-lang.c (get_template_innermost_arguments_folded)
+ (get_template_argument_pack_elems_folded)
+ (template_arg_needs_folding, fold_cplus_constants): New static
+ functions.
+ (LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS): Set this hook to
+ get_template_innermost_arguments_folded.
+ (LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS): Set this hook to
+ get_template_argument_pack_elems_folded.
+
+2011-01-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/46658
+ * init.c (build_new_1): Handle value-init in templates differently.
+
+ PR c++/45520
+ * tree.c (maybe_dummy_object): Check current_class_ref against
+ context, not current_class_type.
+
+2011-01-08 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ PR objc/47078
+ * parser.c (cp_parser_objc_typename): If the type is unknown, for
+ error recovery purposes behave as if it was not specified so that
+ the default type is used.
+
+2011-01-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/47022
+ * pt.c (tsubst_copy_and_build): Use tsubst instead of tsubst_copy
+ for the second build_x_va_arg argument.
+
+2011-01-05 Tom Tromey <tromey@redhat.com>
+
+ * typeck.c (cp_build_addr_expr_1): Update call to lvalue_error.
+ (lvalue_or_else): Likewise.
+
+2011-01-01 Kai Tietz <kai.tietz@onevision.com>
+
+ PR target/38662
+ * tree.c (cxx_type_hash_eq):
+ Allow METHOD_TYPE, too.
+
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2012 b/gcc-4.9/gcc/cp/ChangeLog-2012
new file mode 100644
index 000000000..a57051ebf
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2012
@@ -0,0 +1,3067 @@
+2012-12-28 Kai Tietz <ktietz@redhat.com>
+
+ * rtti.c (LONGPTR_T): New helper-macro.
+ (get_pseudo_ti_init): Initialize offset_type by LONGPTR_T
+ type instead of 'long' type.
+ (create_tinfo_types): Use for offset/flags field LONGPTR_T
+ type instead of 'long' type.
+
+2012-12-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/55724
+ * pt.c (type_unification_real): Re-combine post-deduction loops.
+
+2012-12-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/55685
+ * pt.c (tsubst_copy_and_build): Don't use SIZEOF_EXPR_TYPE_P in
+ templates.
+
+ PR c++/42315
+ * decl.c (maybe_deduce_size_from_array_init): Don't change the
+ variable type.
+
+2012-12-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/55652
+ * typeck2.c (merge_exception_specifiers): Don't call operand_equal_p
+ if noex is NULL.
+
+2012-12-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/54883
+ * decl2.c (min_vis_r): Handle anon visibility for enums.
+
+2012-12-11 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53094
+ * tree.c (cp_tree_equal): Handle VECTOR_CST.
+ * semantics.c (cxx_eval_bare_aggregate): Protect a dereference.
+ Handle VECTOR_CST.
+
+2012-12-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/55643
+ * expr.c (mark_exp_read): Handle FLOAT_EXPR similarly to NOP_EXPR.
+
+2012-12-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/54416
+ * pt.c (maybe_process_partial_specialization): Don't accept
+ definition of a specialization without the appropriate header.
+
+ * pt.c (maybe_process_partial_specialization): Handle aliases first.
+
+2012-12-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/55619
+ * semantics.c (finish_asm_stmt): Don't call decay_conversion
+ on input operands that can be only in memory.
+
+2012-12-10 Eric Botcazou <ebotcazou@adacore.com>
+
+ * Make-lang.in (cp/typeck.o): Add dependency on $(PARAMS_H).
+ (cp/name-lookup.o): Likewise.
+
+2012-12-10 Steven Bosscher <steven@gcc.gnu.org>
+
+ * decl2.c (cp_write_global_declarations): Return after writing a PCH.
+
+2012-12-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/55127
+ * search.c (accessible_in_template_p): New.
+ * cp-tree.h: Declare it.
+ * pt.c (instantiation_dependent_scope_ref_p): New.
+ (value_dependent_expression_p): Use it.
+ (instantiation_dependent_r): Likewise.
+ * semantics.c (finish_decltype_type): Handle SCOPE_REF.
+
+ PR c++/55419
+ * tree.c (build_target_expr): Don't set TREE_CONSTANT.
+
+2012-12-07 Aldy Hernandez <aldyh@redhat.com>
+
+ PR c++/55513
+ * semantics.c (cxx_eval_builtin_function_call): Set non_constant_p
+ after folding.
+
+2012-12-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * tree.c (build_aggr_init_expr): Remove tsubst_flags_t parameter.
+ (build_cplus_new): Adjust.
+ * cp-tree.h: Adjust declaration.
+ * init.c (build_value_init): Adjust.
+
+2012-12-07 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/54401
+ * parser.c (cp_parser_alias_declaration): Commit to tentative
+ parse when see the '=' token. Get out if the type-id is invalid.
+ Update function comment.
+ (cp_parser_member_declaration): Don't try to parse a using
+ declaration if we know that we expected an alias declaration; that
+ is, if we see the '=' token after the identifier.
+
+2012-12-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/54325
+ * tree.c (build_aggr_init_expr): Don't check for abstract class.
+ (build_cplus_new): Check here instead.
+
+ PR c++/55058
+ * pt.c (tsubst): Keep the quals when looking through a typedef.
+
+ PR c++/55249
+ * tree.c (build_vec_init_elt): Use the type of the initializer.
+
+ PR c++/54744
+ * pt.c (resolve_typename_type): Check TYPENAME_IS_RESOLVING_P on scope.
+ * init.c (expand_member_init): Check for being in a template first.
+ * parser.c (cp_parser_mem_initializer_list): Only check class types
+ for equivalence to the current class.
+
+ PR c++/54913
+ * semantics.c (finish_qualified_id_expr): convert_from_reference
+ after building a SCOPE_REF.
+
+2012-12-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/54207
+ * except.c (build_noexcept_spec): Avoid direct comparison
+ with boolean_true_node or boolean_false_node, instead use
+ operand_equal_p and/or INTEGER_CST check.
+ * pt.c (tsubst_exception_specification): Likewise.
+ * typeck2.c (merge_exception_specifiers): Likewise.
+
+2012-12-06 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/55573
+ * semantics.c (adjust_temp_type): Handle VECTOR_CST.
+
+2012-12-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/54947
+ * parser.c (cp_parser_initializer_list): Don't require an
+ expression in [] to be constant until we know it's a C99
+ designator.
+
+ PR c++/55015
+ PR c++/53821
+ * semantics.c (maybe_add_lambda_conv_op): Revert earlier change.
+ * decl.c (start_preparsed_function): Make local class methods comdat
+ in templates, too.
+
+ PR c++/54653
+ * parser.c (cp_parser_class_head): A partial specialization scope
+ counts as a template.
+ * pt.c (tsubst_template_parms): Handle template template parm parms.
+ (tsubst_decl) [TEMPLATE_DECL]: Handle getting a template template
+ argument back.
+
+ PR c++/55564
+ * pt.c (unify) [ARRAY_TYPE]: Unify the element type before the bounds.
+
+2012-12-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54170
+ * cvt.c (cp_convert_to_pointer): Don't discard side-effects from
+ expressions of nullptr_t.
+ * typeck.c (build_ptrmemfunc): Likewise.
+
+2012-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/55542
+ * pt.c (make_ith_pack_parameter_name): Return NULL if
+ name is NULL.
+ (tsubst_decl): Call make_ith_pack_parameter_name even if
+ DECL_NAME is NULL.
+
+2012-11-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/53137
+ * pt.c (tsubst_expr) [DECL_EXPR]: Set LAMBDA_EXPR_THIS_CAPTURE here.
+ (tsubst_copy_and_build) [LAMBDA_EXPR]: And clear it here.
+ (instantiate_class_template_1): Not here.
+
+2012-11-29 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53094
+ * cvt.c (ocp_convert): Call convert_to_vector.
+
+2012-11-29 Kai Tietz <ktietz@redhat.com>
+
+ PR target/53912
+ * class.c (dump_class_hierarchy_r): Cast from pointer via uintptr_t.
+ (dump_vtable): Likewise.
+
+2012-11-29 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/52654
+ * parser.c (cp_parser_string_literal): Add overflow_type arg.
+ (cp_parser_userdef_numeric_literal): Warn on numeric overflow.
+
+2012-11-28 Andrew Pinski <apinski@cavium.com>
+
+ PR bootstrap/54279
+ * Make-lang.in (g++$(exeext)): Rename to
+ (xg++$(exeext)): This.
+ (g++-cross$(exeext)): Use xg++$(exeext) instead of g++$(exeext).
+ (c++.start.encap): Likewise.
+ (c++.install-common): Likewise.
+
+2012-11-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/55446
+ * init.c (build_vec_init): Do not early return error_mark_mode
+ when integer_all_onesp (maxindex).
+
+2012-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/54046
+ * cp-objcp-common.h (LANG_HOOKS_BLOCK_MAY_FALLTHRU): Redefine.
+ * cp-objcp-common.c (cxx_block_may_fallthru): New function.
+ * cp-tree.h (cxx_block_may_fallthru): New prototype.
+
+2012-11-23 Markus Trippelsdorf <markus@trippelsdorf.de>
+
+ PR c++/55418
+ * method.c (implicitly_declare_fn): Properly initialize trivial_p.
+
+2012-11-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/55137
+ * semantics.c (verify_constant): Track overflow separately.
+ (reduced_constant_expression_p): Don't check it here.
+ (cxx_eval_constant_expression): Check it on CSTs.
+ (cxx_eval_outermost_constant_expr): Treat overflows as non-constant
+ at this point, but still return the folded version.
+ (potential_constant_expression_1): Don't check overflow.
+
+ * call.c (extend_ref_init_temps_1): Recompute TREE_CONSTANT for
+ the ADDR_EXPR.
+
+2012-11-20 Diego Novillo <dnovillo@google.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * name-lookup.c: Replace all vec<T, A>() initializers
+ with vNULL.
+ * semantics.c: Likewise.
+
+2012-11-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/55368
+ * parser.c (cp_parser_member_declaration): Emit an error in case
+ of stray comma at end of member declaration.
+
+2012-11-19 Jason Merrill <jason@redhat.com>
+
+ * class.c (one_inheriting_sig): Don't inherit base copy ctors.
+
+ PR c++/55262
+ * method.c (implicitly_declare_fn): Set DECL_PARM_INDEX on
+ the parms of an inheriting ctor.
+
+ PR c++/55261
+ * class.c (add_implicitly_declared_members): Use
+ lookup_fnfields_slot to get the base constructors.
+
+2012-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/54630
+ * class.c (fixed_type_or_null_ref_ht): New variable.
+ (fixed_type_or_null): Use it instead of local static ht.
+
+2012-11-17 Diego Novillo <dnovillo@google.com>
+
+ Adjust for new vec API (http://gcc.gnu.org/wiki/cxx-conversion/cxx-vec)
+
+ * Make-lang.in: Remove dependencies on vecir.h and vecprim.h everywhere.
+ * call.c: Use new vec API in vec.h.
+ * class.c: Likewise.
+ * cp-gimplify.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * error.c: Likewise.
+ * except.c: Likewise.
+ * init.c: Likewise.
+ * mangle.c: Likewise.
+ * method.c: Likewise.
+ * name-lookup.c: Likewise.
+ * name-lookup.h: Likewise.
+ * parser.c: Likewise.
+ * parser.h: Likewise.
+ * pt.c: Likewise.
+ * repo.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2012-11-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * semantics.c (finish_id_expression): Tidy diagnostic message.
+
+2012-11-16 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/54875
+ * pt.c (lookup_template_class_1): Look at the type of the
+ potential member enum of class template to determine if we are
+ actually substituting into a member enum of class template.
+
+2012-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/55337
+ * tree.c (cp_tree_equal) <case ALIGNOF_EXPR>: Use SIZEOF_EXPR_TYPE_P
+ only on SIZEOF_EXPR.
+
+2012-11-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/54903
+ * decl2.c (mark_used): Don't complain about auto in templates.
+
+ PR c++/37276
+ * decl.c (decls_match): Remove #ifdef around earlier fix.
+
+2012-11-13 Jason Merrill <jason@redhat.com>
+
+ * class.c (finish_struct_1): Check virtual functions
+ for missing ABI tags.
+
+ PR c++/55275
+ * pt.c (maybe_process_partial_specialization): Update
+ DECL_SOURCE_LOCATION for new specializations.
+
+2012-11-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/55323
+ * init.c (emit_mem_initializers): Skip arguments == error_mark_node.
+
+2012-11-14 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/11750
+ * call.c (build_new_method_call_1): Check that the instance type
+ and the function context are the same before setting the flag
+ LOOKUP_NONVIRTUAL.
+
+2012-11-13 Sriraman Tallam <tmsriram@google.com>
+
+ * class.c (mark_versions_used): Remove.
+ (resolve_address_of_overloaded_function): Call target hook
+ for versioned functions. Refactor to call
+ get_function_versions_dispatcher.
+ * decl.c (duplicate_decls): Add comments.
+ * cp/call.c (get_function_version_dispatcher): Expose function.
+ (mark_versions_used): Expose function.
+ * cp/cp-tree.h (mark_versions_used): New declaration.
+ (get_function_version_dispatcher): Ditto.
+
+2012-11-13 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/54466
+ * pt.c (lookup_template_class_1): TYPE_STUB_DECL should be
+ accessed on the main variant of the type.
+
+2012-11-12 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ * parser.c (cp_parser_objc_class_ivars):
+ Index declspecs.locations by ds_typedef rather than ds_thread.
+
+2012-11-09 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/54413
+ * decl.c (grokfndecl): Adjust calls to interpret_x_suffix.
+
+2012-11-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/54859
+ * pt.c (check_instantiated_arg): Don't complain about dependent args.
+
+ * tree.c (cxx_attribute_table): Add abi_tag attribute.
+ (check_abi_tag_redeclaration, handle_abi_tag_attribute): New.
+ * class.c (find_abi_tags_r, check_abi_tags): New.
+ (check_bases, check_field_decl): Call check_abi_tags.
+ * decl.c (redeclaration_error_message): Call
+ check_abi_tag_redeclaration.
+ * mangle.c (tree_string_cmp, write_abi_tags): New.
+ (write_unqualified_name): Call write_abi_tags.
+
+2012-11-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/55226
+ Revert:
+ 2012-10-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54922
+ * semantics.c (cx_check_missing_mem_inits): Handle anonymous union
+ members.
+
+2012-11-07 Florian Weimer <fweimer@redhat.com>
+
+ * init.c (build_new_1): Do not check for arithmetic overflow if
+ inner array size is 1.
+
+2012-11-05 Sriraman Tallam <tmsriram@google.com>
+
+ * class.c (add_method): Change assembler names of function versions.
+ (mark_versions_used): New static function.
+ (resolve_address_of_overloaded_function): Create dispatcher decl and
+ return address of dispatcher instead.
+ * decl.c (decls_match): Make decls unmatched for versioned
+ functions.
+ (duplicate_decls): Remove ambiguity for versioned functions.
+ Delete versioned function data for merged decls.
+ * decl2.c (check_classfn): Check attributes of versioned functions
+ for match.
+ * call.c (get_function_version_dispatcher): New function.
+ (mark_versions_used): New static function.
+ (build_over_call): Make calls to multiversioned functions
+ to call the dispatcher.
+ (joust): For calls to multi-versioned functions, make the most
+ specialized function version win.
+
+2012-10-31 Lawrence Crowl <crowl@google.com>
+
+ * decl2.c (var_finalized_p): Rename varpool_node to
+ varpool_node_for_decl.
+ (maybe_emit_vtables): Likewise.
+
+2012-10-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54583
+ * tree.c (build_cplus_array_type): Set TREE_NO_WARNING on the
+ TYPE_SIZE of VLAs.
+
+2012-10-31 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/54955
+ * parser.c (cp_nth_tokens_can_be_std_attribute_p): Recognize the
+ 'Alignas' keyword as the beginning of a c++11 attribute specifier.
+ Update the comment of the function.
+ (cp_next_tokens_can_be_gnu_attribute_p): Update the comment of the
+ function.
+
+2012-10-29 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR c++/54930
+ * typeck.c (maybe_warn_about_returning_address_of_local): Use
+ OPT_Wreturn_local_addr.
+
+2012-10-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/55081
+ * typeck2.c (store_init_value): Call fold_non_dependent_expr
+ and maybe_constant_init even for C++98.
+
+2012-10-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54984
+ * init.c (build_new): Don't turn a null *init into a pointer to
+ empty vector orig_init.
+
+2012-10-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53761
+ * class.c (finish_struct_1): Reject aggregates decorated with
+ __transparent_union__ which cannot be made transparent because
+ the type of the first field has a different ABI from the class
+ overall.
+
+2012-10-25 Jason Merrill <jason@redhat.com>
+
+ Core 1402
+ * call.c (joust): An implicitly deleted move function is
+ worse than any non-deleted function.
+ * method.c (process_subob_fn): No special rules for move.
+ (synthesized_method_walk, implicitly_declare_fn): Likewise.
+ Warn about virtual base with non-trivial move assignment.
+ * cp-tree.h (struct lang_decl_fn): Remove suppress_implicit_decl.
+ (FNDECL_SUPPRESS_IMPLICIT_DECL): Remove.
+
+ * semantics.c (finish_omp_threadprivate): Call complete_type.
+
+ * class.c (one_inherited_ctor): Warn about variadic inherited ctor.
+
+2012-10-25 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/54427
+ * typeck.c (build_x_conditional_expr): Handle VEC_COND_EXPR.
+ * call.c (build_conditional_expr_1): Likewise.
+
+2012-10-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/34892
+ * parser.c (cp_parser_template_parameter): When
+ cp_parser_parameter_declaration parsed a default argument don't
+ see if *is_parameter_pack needs setting.
+
+2012-10-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54922
+ * semantics.c (cx_check_missing_mem_inits): Handle anonymous union
+ members.
+
+2012-10-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/54844
+ * pt.c (tsubst_copy, tsubst_copy_and_build) <case SIZEOF_EXPR>: Use
+ tsubst instead of tsubst_copy* on types.
+
+ PR c++/54988
+ * decl2.c (cplus_decl_attributes): Don't return early
+ if attributes is NULL.
+
+2012-10-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54501
+ * decl.c (reshape_init_array_1): Avoid infinite loops.
+
+2012-10-15 Alexandre Oliva <aoliva@redhat.com>
+ Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/17805
+ * call.c (build_new_op_1): Filter out operator functions that don't
+ satisfy enum-conversion match requirements.
+
+2012-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50080 (again)
+ * parser.c (cp_parser_optional_template_keyword): When -pedantic
+ and C++98 mode restore pre-Core/468 behavior.
+
+2012-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50080
+ * parser.c (cp_parser_optional_template_keyword): Implement
+ Core/468, allow outside template.
+
+2012-10-14 Jason Merrill <jason@redhat.com>
+ Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Implement C++11 inheriting constructors.
+ * cp-tree.h (cpp0x_warn_str): Add CPP0X_INHERITING_CTORS.
+ (DECL_INHERITED_CTOR_BASE, SET_DECL_INHERITED_CTOR_BASE): New.
+ (special_function_kind): Add sfk_inheriting_constructor.
+ * class.c (add_method): An inheriting ctor is hidden by a
+ user-declared one.
+ (one_inheriting_sig, one_inherited_ctor): New.
+ (add_implicitly_declared_members): Handle inheriting ctors.
+ * error.c (maybe_warn_cpp0x): Handle CPP0X_INHERITING_CTORS.
+ * init.c (emit_mem_initializers): Don't set LOOKUP_DEFAULTED
+ for an inheriting constructor.
+ * method.c (type_has_trivial_fn): Handle sfk_inheriting_constructor.
+ (type_set_nontrivial_flag): Likewise.
+ (add_one_base_init): Split out from...
+ (do_build_copy_constructor): ...here. Handle inheriting constructors.
+ (locate_fn_flags): Handle a list of arg types.
+ (synthesized_method_walk): Handle inheriting constructors.
+ (maybe_explain_implicit_delete): Likewise.
+ (deduce_inheriting_ctor): New.
+ (implicitly_declare_fn): Handle inheriting constructors.
+ * name-lookup.c (push_class_level_binding_1): An inheriting constructor
+ does not declare the base's name.
+ (do_class_using_decl): Allow inheriting constructors.
+ * pt.c (template_parms_to_args): Split from current_template_args.
+ (add_inherited_template_parms): New.
+ (tsubst_decl): Handle inheriting constructors.
+ * tree.c (special_function_p): Handle inheriting constructors.
+
+2012-10-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/54381
+ * semantics.c (finish_call_expr): Pass array of 3 sizeof_arg
+ trees and locs (corresponding to first 3 arguments) to
+ sizeof_pointer_memaccess_warning.
+
+2012-10-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/24449
+ * decl.c (grokfndecl): When checking for ::main declarations
+ use PROCESSING_REAL_TEMPLATE_DECL_P().
+
+2012-10-12 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53055
+ * call.c (build_new_op_1): Pass RO_ARROW_STAR to cp_build_indirect_ref.
+ * typeck.c (cp_build_indirect_ref): Handle RO_ARROW_STAR.
+
+2012-10-11 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_THUNKS): NULL_TREE for non-virtual functions.
+ (SET_DECL_THUNKS): New.
+ * decl.c (duplicate_decls): Adjust.
+ * method.c (make_thunk): Adjust.
+
+ * decl.c (grokdeclarator): Set DECL_GNU_TLS_P for static data
+ members, too.
+
+2012-10-09 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/53540 - using fails to be equivalent to typedef
+ * cp-tree.h (TYPE_TEMPLATE_INFO): For an alias that is not an
+ instance of alias template, don't look for its TEMPLATE_INFO in
+ its declaration.
+ (alias_template_specialization_p): Take const_tree.
+ * pt.c (alias_template_specialization_p): Take a const_tree.
+ Don't call primary_template_instantiation_p.
+ (primary_template_instantiation_p): Call
+ alias_template_specialization_p.
+
+2012-10-10 Dodji Seketeli <dodji@redhat.com>
+
+ * parser (cp_parser_statement): Parse c++11 attributes
+ tentatively.
+ (cp_parser_std_attribute_spec_seq): Do not warn too early about
+ using c++11 attributes in non c++11 mode.
+
+2012-10-10 Dehao Chen <dehao@google.com>
+
+ * cp-gimplify.c (cp_genericize_r): Set location for TRY expr.
+
+2012-10-09 Lawrence Crowl <crowl@google.com>
+
+ * Make-lang.in (class.o): Add dependence on hash-table.h.
+ (tree.o): Likewise.
+ (semantics.o): Likewise.
+ * class.c (fixed_type_or_null): Change to new type-safe hash table.
+ * tree.c (verify_stmt_tree): Likewise.
+ (verify_stmt_tree_r): Likewise.
+ * semantics.c (struct nrv_data): Likewise.
+
+2012-10-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54194
+ * typeck.c (build_x_binary_op): Update warn_about_parentheses call.
+ * parser.c (cp_parser_binary_expression): Use SET_EXPR_LOCATION
+ on current.lhs.
+
+2012-10-09 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/54427
+ * typeck.c (cp_build_binary_op): Handle mixed scalar-vector
+ operations.
+ [LSHIFT_EXPR, RSHIFT_EXPR]: Likewise.
+
+2012-10-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/54858
+ * tree.c (cp_tree_equal): Handle FIELD_DECL.
+
+2012-10-08 Jason Merrill <jason@redhat.com>
+
+ Allow dynamic initialization of thread_locals.
+ * decl.c: Define tls_aggregates.
+ (expand_static_init): Remove sorry. Add to tls_aggregates.
+ * cp-tree.h: Declare tls_aggregates.
+ * call.c (set_up_extended_ref_temp): Add to tls_aggregates.
+ * decl2.c (var_needs_tls_wrapper): New.
+ (var_defined_without_dynamic_init): New.
+ (get_tls_init_fn, get_tls_wrapper_fn): New.
+ (generate_tls_wrapper, handle_tls_init): New.
+ (cp_write_global_declarations): Call handle_tls_init and
+ enerate_tls_wrapper.
+ * mangle.c (write_guarded_var_name): Split out from..
+ (mangle_guard_variable): ...here.
+ (mangle_tls_init_fn, mangle_tls_wrapper_fn): Use it.
+ (decl_tls_wrapper_p): New.
+ * semantics.c (finish_id_expression): Replace use of thread_local
+ variable with a call to its wrapper.
+
+ * decl.c (get_thread_atexit_node): New.
+ (register_dtor_fn): Use it for TLS.
+
+ Partial implementation of C++11 thread_local.
+ * decl.c (cp_finish_decl): Remove errors about non-trivial
+ initialization and destruction of TLS variables.
+ (register_dtor_fn): Add sorry about TLS variables.
+ (expand_static_init): Add sorry about non-local TLS variables,
+ or error with __thread.
+ Don't emit thread-safety guards for local TLS variables.
+ (grokdeclarator): thread_local in a function implies static.
+ * decl.h: Adjust prototype.
+ * decl2.c (get_guard): Copy DECL_TLS_MODEL.
+ * parser.c (cp_parser_set_storage_class, cp_parser_set_decl_spec_type)
+ (set_and_check_decl_spec_loc): Take the token rather than the location.
+ Distinguish between __thread and thread_local.
+ (cp_parser_set_storage_class): Don't complain about thread_local before
+ extern/static.
+ (token_is__thread): New.
+ * call.c (make_temporary_var_for_ref_to_temp): Handle TLS.
+ * cp-tree.h (DECL_GNU_TLS_P): New.
+ (cp_decl_specifier_seq): Add gnu_thread_keyword_p.
+
+2012-10-08 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/53528 C++11 attribute support
+ * cp-tree.h (enum cpp0x_warn_str::CPP0X_ATTRIBUTES): New member.
+ (enum cp_decl_spec::ds_std_attribute): New enumerator.
+ (struct cp_decl_specifier_seq::std_attributes): New field.
+ (cxx_alignas_expr, warn_misplaced_attr_for_class_type): Declare
+ new functions.
+ (check_tag_decl): Take an extra parameter for explicit
+ instantiations.
+ * decl.c (warn_misplaced_attr_for_class_type): Extract from ...
+ (check_tag_decl): ... here. Add check for c++11 attributes being
+ applied to an explicit instantiation. Take an extra parameter for
+ explicit instantiations.
+ (grokdeclarator): Make sure a c++11 attribute after an array
+ declarator appertains to the array, an attribute after a function
+ declarator appertains to the function type, an attribute after a
+ declarator-id appertains to the entity being declared, and an
+ attribute after a pointer declarator appertain to the pointer.
+ * decl2.c (is_late_template_attribute): Use get_attribute_name.
+ * error.c (maybe_warn_cpp0x): Support
+ CPP0X_GENERALIZED_ATTRIBUTES.
+ * parser.c (cp_next_tokens_can_be_attribute_p)
+ (cp_next_tokens_can_be_gnu_attribute_p)
+ (cp_next_tokens_can_be_std_attribute_p)
+ (cp_nth_tokens_can_be_attribute_p)
+ (cp_nth_tokens_can_be_gnu_attribute_p)
+ (cp_nth_tokens_can_be_std_attribute_p)
+ (cp_parser_gnu_attribute_list, cp_parser_std_attribute)
+ (cp_parser_std_attribute_spec, cp_parser_std_attribute_spec_seq)
+ (cp_parser_attributes_opt, cp_parser_std_attribute_list): New
+ static functions.
+ (cp_parser_gnu_attributes_opt): Replace cp_parser_attributes_opt.
+ (cp_parser_gnu_attribute_list): Replace cp_parser_attribute_list.
+ (cp_parser_postfix_expression): Disallow "[[" tokens here.
+ (cp_parser_label_for_labeled_statement): Use take an extra
+ parameter for attributes.
+ (cp_parser_block_declaration): Use
+ cp_nth_tokens_can_be_std_attribute_p here.
+ (cp_parser_decl_specifier_seq): Likewise. Store C++11 attributes
+ that appears in in decl specifiers in cp_decl_specifier_seq::std_attributes.
+ declaration. Emit proper warning about misplaced c++11 attributes
+ for class type.
+ (cp_parser_explicit_instantiation): Adjust call to check_tag_decl.
+ (cp_parser_init_declarator): Parsing attributes here is no more a
+ GNU extension in c++-11.
+ (cp_parser_type_specifier_seq): Use
+ cp_next_tokens_can_be_attribute_p.
+ (cp_parser_direct_declarator): Likewise. Hang c++11 attributes
+ following the declarator to its syntactic construct. It'll later
+ be applied to the proper appertaining entity by grokdeclarator.
+ (cp_parser_ptr_operator): Likewise.
+ (make_declarator): Initialize cp_declarator::std_attribute.
+ (make_pointer_declarator, make_reference_declarator)
+ (make_ptrmem_declarator, cp_parser_make_indirect_declarator): Take
+ attributes that appertain to the pointer/reference in argument.
+ (cp_parser_ptr_operator): Take an out parameter for c++11
+ attributes. Update comments.
+ (cp_parser_new_declarator_opt)
+ (cp_parser_conversion_declarator_opt): Adjust.
+ (cp_parser_declarator): Likewise. Handle C++11 attributes.
+ Rename attributes to gnu_attribute for better legibility.
+ (cp_parser_simple_declaration): Update comment.
+ (cp_parser_class_specifier_1): Parse GNU attributes specifically
+ (cp_parser_enum_specifier): Accept only gnu attributes after the
+ specifier.
+ (cp_parser_member_declaration): Don't clear attributes -- intended
+ for the entity being declared -- too early because check_tag_decl
+ needs them.
+ (cp_parser_statement): Update comment. Parse optional c++11
+ attributes at the beginning of the relevant kind of statements and
+ ignore them, for now, unless when calling
+ cp_parser_label_for_labeled_statement.
+ (cp_parser_label_for_labeled_statement): Take c++11 attributes
+ in parameter.
+ * semantics.c (potential_constant_expression_1): Likewise.
+ * typeck.c (fundamental_alignment_p, cxx_alignas_expr): New public
+ functions.
+
+2012-10-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * pt.c (fold_non_dependent_expr_sfinae): Remove static specifier.
+ (tsubst_copy_and_build): Use get_target_expr_sfinae.
+ * call.c (build_conditional_expr_1, convert_like_real): Likewise.
+ * cvt.c (build_up_reference): Likewise.
+ (ocp_convert): Use abstract_virtuals_error_sfinae.
+ (build_up_reference): Propagate complain to cp_build_addr_expr.
+ * decl.c (compute_array_index_type): Use fold_non_dependent_expr_sfinae.
+ * cp-tree.h: Update declarations.
+
+ * cvt.c (build_expr_type_conversion): Tidy.
+
+ * tree.c (stabilize_aggr_init): Change to static.
+
+2012-10-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51422
+ * semantics.c (is_normal_capture_proxy): Return true for
+ error_mark_node as DECL_VALUE_EXPR.
+
+2012-10-05 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (SIZEOF_EXPR_TYPE_P): Define.
+ * tree.c (cp_tree_equal): Handle SIZEOF_EXPR with
+ SIZEOF_EXPR_TYPE_P.
+ * mangle.c (write_expression): Likewise.
+ * cxx-pretty-print.c (pp_cxx_unary_expression): Likewise.
+ * error.c (dump_expr): Likewise.
+ * parser.c (cp_parser_unary_expression): For sizeof call
+ cxx_sizeof_or_alignof_{type,expr} just for diagnostics and
+ return SIZEOF_EXPR with the operand.
+ * pt.c (tsubst_copy, tsubst_copy_and_build): For SIZEOF_EXPR,
+ call cxx_sizeof_or_alignof_{type,expr} for diagnostics, but
+ return SIZEOF_EXPR with tsubsted operand.
+ (value_dependent_expression_p): Handle SIZEOF_EXPR with
+ SIZEOF_EXPR_TYPE_P.
+ (instantiation_dependent_r): Likewise.
+ * call.c (null_ptr_cst_p): Call maybe_constant_value for C++98.
+ * semantics.c (finish_call_expr): Call
+ sizeof_pointer_memaccess_warning if needed.
+ (cxx_eval_constant_expression): Handle SIZEOF_EXPR.
+ (potential_constant_expression_1): Remove early exit for
+ C++98. Handle PROPERTY_REF.
+ * decl.c (duplicate_decls): When redeclaring a builtin function,
+ keep the merged decl builtin also if newdecl is a gnu_inline
+ inline definition.
+ (fold_sizeof_expr_r): New function.
+ (compute_array_index_type): Fold SIZEOF_EXPRs in itype.
+ * cp-gimplify.c (cp_genericize_r): Fold SIZEOF_EXPR.
+ * typeck.c (cp_build_binary_op): For warn_for_sign_compare
+ try harder using maybe_constant_value to get INTEGER_CSTs.
+
+ * decl.c (stabilize_vla_size): Call pointer_set_destroy
+ at the end.
+
+2012-10-04 Arnaud Charlet <charlet@adacore.com>
+
+ * decl2.c (cp_write_global_declarations): Fix handling of
+ -fdump-ada-spec*.
+
+2012-10-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/54777
+ * semantics.c (cxx_eval_constant_expression) <case COMPOUND_EXPR>: If
+ not ignoring the second operand, pass the original second operand
+ and not one with stripped nops to cxx_eval_constant_expression.
+
+2012-10-01 Jason Merrill <jason@redhat.com>
+
+ * decl.c (check_initializer): Set DECL_NONTRIVIALLY_INITIALIZED_P
+ for a constructor call.
+ (decl_jump_unsafe): So don't bother checking
+ type_has_nontrivial_default_init.
+ * call.c (set_up_extended_ref_temp): Set
+ DECL_NONTRIVIALLY_INITIALIZED_P.
+
+ * cp-tree.h (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK): New.
+ (DECL_FRIEND_P, DECL_ANTICIPATED): Use it.
+ (TYPE_FUNCTION_OR_TEMPLATE_DECL_P): New.
+ * name-lookup.c (hidden_name_p): Use it.
+
+ * cp-tree.h (DECL_PRETTY_FUNCTION_P): Just look at the name.
+ * decl.c (cp_make_fname_decl): Adjust.
+
+2012-09-30 Sharad Singhai <singhai@google.com>
+
+ * decl2.c (cp_write_global_declarations): Use a different method
+ to determine if the dump has ben initialized.
+
+2012-09-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54738
+ * decl2.c (build_offset_ref_call_from_tree): Add tsubst_flags_t
+ parameter.
+ * pt.c (tsubst_copy_and_build): Adjust.
+ * parser.c (cp_parser_postfix_expression): Likewise.
+ * cp-tree.h: Adjust declaration.
+
+2012-09-28 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/54372 - unused attribute inactive on dependant entities
+ * decl2.c (is_late_template_attribute): "unused" attribute is to
+ be applied at compile time.
+
+2012-09-25 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/29028 - Missed unused warning on using declaration
+ * decl.c (poplevel<warn_unused*>): Do not forget that some local
+ bindings are represented by a TREE_LIST.
+
+2012-09-25 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/53551 - -Wunused-local-typedefs misses uses
+ * decl.c (make_typename_type): Record the use of typedefs.
+
+2012-09-27 Jakub Jelinek <jakub@redhat.com>
+
+ * init.c (build_new_1): Don't test TREE_CONSTANT
+ of INTEGER_CST.
+
+2012-09-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54526
+ * parser.c (cp_parser_template_id): In C++11 mode simply accept
+ X<::A>.
+
+2012-09-25 Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ PR c++/50970
+ * typeck.c (cp_build_binary_op): Check side effects before generating
+ pfn and delta related expressions.
+
+2012-09-24 Lawrence Crowl <crowl@google.com>
+
+ * init.c (build_new_1): Change to new double_int API.
+ * decl.c (build_enumerator): Likewise.
+ * typeck2.c (process_init_constructor_array): Likewise.
+ * mangle.c (write_array_type): Likewise.
+
+2012-09-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50828
+ * error.c (dump_function_decl): Strip TFF_TEMPLATE_NAME from flags
+ at the outset.
+
+2012-09-24 Jason Merrill <jason@redhat.com>
+
+ * decl.c (get_atexit_node): Remove dead code.
+
+ * Make-lang.in (cp/parser.o): Depend on decl.h.
+
+2012-09-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52432
+ * pt.c (tsubst_copy_and_build): If tf_error is not set in the complain
+ argument don't call unqualified_name_lookup_error.
+
+2012-09-19 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/54581
+ * semantics.c (finish_decltype_type): Make vectors not opaque.
+
+2012-09-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/54575
+ * pt.c (instantiate_alias_template): New.
+ (tsubst): Use it.
+ (push_access_scope): Allow TYPE_DECL.
+
+2012-09-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/53661
+ * typeck2.c (check_narrowing): Avoid false positives on conversion
+ from enumeral type.
+
+2012-09-14 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/54427
+ * typeck.c (cp_build_binary_op) [LSHIFT_EXPR, RSHIFT_EXPR, EQ_EXPR,
+ NE_EXPR, LE_EXPR, GE_EXPR, LT_EXPR, GT_EXPR]: Handle VECTOR_TYPE.
+
+2012-09-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (make_typename_type): Only error out if tf_error is set
+ in complain.
+
+2012-09-13 Paolo Carlini <paolo.carlini@oracle.com>
+ Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/53210
+ * init.c (perform_member_init): Use OPT_Winit_self instead of
+ OPT_Wuninitialized.
+
+2012-09-13 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * typeck.c (build_indirect_ref, build_function_call,
+ build_function_call_vec, build_binary_op, build_unary_op,
+ build_compound_expr, build_c_cast, build_modify_expr): Remove
+ uses of ATTRIBUTE_UNUSED on the parameters.
+ * class.c (set_linkage_according_to_type, resort_type_method_vec,
+ dfs_find_final_overrider_post, empty_base_at_nonzero_offset_p):
+ Likewise.
+ * decl.c (local_variable_p_walkfn): Likewise.
+ * except.c (wrap_cleanups_r, check_noexcept_r): Likewise.
+ * error.c (find_typenames_r): Likewise.
+ * tree.c (verify_stmt_tree_r, bot_replace,
+ handle_java_interface_attribute, handle_com_interface_attribute,
+ handle_init_priority_attribute, c_register_addr_space): Likewise.
+ * cp-gimplify.c (cxx_omp_clause_default_ctor): Likewise.
+ * cp-lang.c (objcp_tsubst_copy_and_build): Likewise.
+ * pt.c (unify_success, unify_invalid, instantiation_dependent_r):
+ Likewise.
+ * semantics.c (dfs_calculate_bases_pre): Likewise.
+ * decl2.c (fix_temporary_vars_context_r, clear_decl_external):
+ Likewise.
+ * parser.c (cp_lexer_token_at, cp_parser_omp_clause_mergeable,
+ cp_parser_omp_clause_nowait, cp_parser_omp_clause_ordered,
+ cp_parser_omp_clause_untied): Likewise.
+ * mangle.c (write_unnamed_type_name,
+ discriminator_for_string_literal): Likewise.
+ * search.c (dfs_accessible_post, dfs_debug_mark): Likewise.
+ * lex.c (handle_pragma_vtable, handle_pragma_unit,
+ handle_pragma_interface, handle_pragma_implementation,
+ handle_pragma_java_exceptions): Likewise.
+
+2012-09-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/53839
+ * semantics.c (cxx_eval_indirect_ref): If we aren't looking for an
+ address, make sure the value is constant.
+
+ PR c++/54511
+ * pt.c (tsubst_decl) [VAR_DECL]: Handle DECL_ANON_UNION_VAR_P.
+
+ PR c++/53836
+ * pt.c (value_dependent_expression_p): A TREE_LIST initializer must
+ be dependent.
+
+2012-09-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54541
+ PR c++/54542
+ * call.c (build_cxx_call): Add tsubst_flags_t parameter, use
+ require_complete_type_sfinae.
+ (build_op_delete_call, build_over_call): Adjust.
+ * typeck.c (build_x_compound_expr_from_vec): Add tsubst_flags_t
+ parameter.
+ (cp_build_function_call_vec): Adjust.
+ * init.c (build_new_1): Likewise.
+ * rtti.c (throw_bad_cast, throw_bad_typeid, build_dynamic_cast_1):
+ Likewise.
+ * optimize.c (build_delete_destructor_body): Likewise.
+ * cp-tree.h: Adjust declarations.
+
+ * call.c (convert_arg_to_ellipsis): Use require_complete_type_sfinae.
+
+2012-09-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/54538
+ PR c++/53783
+ * pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Go back to using RECUR
+ for LAMBDA_EXPR_EXTRA_SCOPE except for function scope.
+
+ PR c++/54506
+ * decl.c (move_signature_fn_p): Split out from move_fn_p.
+ * method.c (process_subob_fn): Use it.
+ * cp-tree.h: Declare it.
+
+2012-09-07 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (sort_constexpr_mem_initializers): Tweak.
+
+2012-09-09 Mark Kettenis <kettenis@openbsd.org>
+
+ * decl.c (reshape_init_class): Avoid dereferencing a
+ past-the-end pointer.
+
+2012-09-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * pt.c (num_template_headers_for_class): Rework per the code
+ inline in cp_parser_check_declarator_template_parameters.
+ * parser.c (cp_parser_check_declarator_template_parameters):
+ Use num_template_headers_for_class.
+
+2012-09-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/54341
+ PR c++/54253
+ * semantics.c (sort_constexpr_mem_initializers): New.
+ (build_constexpr_constructor_member_initializers): Use it.
+ (cx_check_missing_mem_inits): Skip artificial fields.
+ * init.c (expand_aggr_init_1): Don't zero out a class
+ with no data.
+
+2012-09-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54191
+ * search.c (lookup_base): Add tsubst_flags_t parameter.
+ (adjust_result_of_qualified_name_lookup, check_final_overrider):
+ Adjust.
+ * name-lookup.c (do_class_using_decl): Adjust.
+ * typeck2.c (binfo_or_else, build_scoped_ref, build_m_component_ref):
+ Likewise.
+ * cvt.c (cp_convert_to_pointer, convert_to_pointer_force,
+ build_up_reference): Likewise.
+ * rtti.c (build_dynamic_cast_1): Likewise.
+ * tree.c (maybe_dummy_object): Likewise.
+ * call.c (build_conditional_expr_1, build_over_call): Likewise.
+ * cp-tree.h (UNIQUELY_DERIVED_FROM_P, PUBLICLY_UNIQUELY_DERIVED_P):
+ Remove.
+ (enum base_access_flags, ba_quiet): Remove.
+ (uniquely_derived_from_p, publicly_uniquely_derived_p): Declare.
+ * except.c (can_convert_eh): Adjust.
+ * decl.c (grokdeclarator): Likewise.
+ * typeck.c (comp_except_types, build_class_member_access_expr,
+ finish_class_member_access_expr, get_member_function_from_ptrfunc,
+ build_static_cast_1, get_delta_difference_1): Likewise.
+ * class.c (build_base_path, convert_to_base, build_vtbl_ref_1,
+ warn_about_ambiguous_bases): Likewise.
+ (uniquely_derived_from_p, publicly_uniquely_derived_p): Define.
+
+2012-09-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/54441
+ * decl.c (reshape_init_class): Handle invalid initializer for
+ 0-length array member.
+
+ * error.c (dump_type_suffix): Correct handling of 0-length arrays.
+
+ PR c++/54420
+ * cp-tree.h (LAMBDANAME_P): Remove.
+ (LAMBDA_TYPE_P): Check CLASSTYPE_LAMBDA_EXPR instead.
+ * cp-lang.c (cxx_dwarf_name): Likewise.
+ * error.c (dump_aggr_type): Likewise.
+ * semantics.c (begin_lambda_type): Set CLASSTYPE_LAMBDA_EXPR sooner.
+
+ PR c++/54198
+ * decl.c (check_default_argument): Set cp_unevaluated_operand
+ around call to perform_implicit_conversion_flags.
+
+ PR c++/54437
+ PR c++/51213
+ * pt.c (fn_type_unification): Call coerce_template_parms before
+ entering substitution context.
+
+2012-08-31 Paolo Carlini <paolo.carlini@oracle.com>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/18747
+ * pt.c (check_template_variable): New.
+ (num_template_headers_for_class): Split out...
+ * decl.c (grokdeclarator): ...from here.
+ (start_decl): Remove redundant diagnostic.
+ * cp-tree.h: Declare them
+ * parser.c (cp_parser_single_declaration): Call check_template_variable.
+
+2012-08-31 Ollie Wild <aaw@google.com>
+
+ PR c++/54197
+ * call.c (extend_ref_init_temps_1): Handle COMPOUND_EXPR trees.
+
+2012-08-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/50545
+ PR c++/51222
+ * pt.c (instantiation_dependent_r): New.
+ (instantiation_dependent_expression_p): New.
+ (value_dependent_expression_p): Use it. SCOPE_REF is always dependent.
+ * semantics.c (finish_decltype_type): Use it.
+ * cp-tree.h: Declare it.
+
+ * semantics.c (finish_qualified_id_expr): Handle building up a
+ non-dependent SCOPE_REF here.
+ (finish_id_expression): Not here.
+ * error.c (dump_decl) [SCOPE_REF]: Only pass TFF_UNQUALIFIED_NAME.
+
+ * friend.c (make_friend_class): Handle template template parameters.
+ * parser.c (cp_parser_template_declaration_after_export): Likewise.
+ * pt.c (tsubst_friend_class): Likewise.
+ (instantiate_class_template_1): Likewise
+ * decl.c (check_elaborated_type_specifier): Likewise.
+ (lookup_and_check_tag): Likewise.
+
+ * pt.c (get_class_bindings): Call coerce_template_parms. Add
+ main_tmpl parameter.
+ (more_specialized_class): Add main_tmpl parameter.
+ (most_specialized_class): Adjust calls.
+
+ * decl.c (cp_finish_decl): Check for invalid multiple initializers
+ even if the initializer is dependent.
+
+ * pt.c (instantiate_template_1): Keep processing_template_decl set
+ if there are dependent args.
+
+2012-08-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51421
+ * decl2.c (mark_used): Consistently return false after errors
+ about uses before deduction of auto.
+ * semantics.c (finish_id_expression): Check mark_used return
+ value and return error_mark_node in case of failure.
+
+2012-08-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/51213 (again)
+ * pt.c (deduction_tsubst_fntype): Remove.
+ (fn_type_unification): Check deduction depth and call
+ instantiate_template here. Handle default argument access checks.
+ (determine_specialization): Suppress access control.
+ (tsubst_decl): Check for excessive deduction depth.
+ (recheck_decl_substitution): Make sure access control is on.
+ (type_unification_real): Don't mess with access deferring here.
+ (get_bindings): Adjust for fn_type_unification return type.
+ * call.c (enum rejection_reason_code): Drop rr_template_instantiation.
+ (template_instantiation_rejection): Remove.
+ (struct rejection_reason): Change targs to num_targs.
+ (template_unification_rejection, print_z_candidate): Adjust.
+ (add_template_candidate_real): Adjust for fn_type_unification change.
+ * class.c (resolve_address_of_overloaded_function): Likewise.
+ * cp-tree.h: Adjust declaration.
+
+ * pt.c (tsubst_default_argument): Indicate where the default
+ argument is being instantiated for.
+ (tsubst_expr): Restore previous location.
+ (tsubst_copy_and_build): Set and restore location.
+ * call.c (build_new_method_call_1): Remember location of call.
+ * semantics.c (finish_call_expr): Here too.
+ * parser.c (cp_parser_omp_for_loop): Remember the location of the
+ increment expression.
+
+ * pt.c (resolve_overloaded_unification): Use coerce_template_parms
+ instead of get_bindings.
+ (resolve_nondeduced_context): Likewise.
+
+ * pt.c (register_specialization): Correct argument to
+ check_specialization_namespace.
+ (determine_specialization): Don't consider members of
+ unspecialized types.
+
+2012-08-23 Jason Merrill <jason@redhat.com>
+
+ * decl.c (compute_array_index_type): Use type_dependent_expression_p.
+
+2012-08-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/20420
+ * name-lookup.c (supplement_binding_1): Handle specially enums
+ only in class templates.
+ (validate_nonmember_using_decl): Enforce 7.3.3/10 about duplicate
+ using declarations at function scope.
+
+2012-08-21 Richard Guenther <rguenther@suse.de>
+
+ * cp-tree.h (TREE_INDIRECT_USING): Use TREE_LANG_FLAG_0 accessor.
+ (ATTR_IS_DEPENDENT): Likewise.
+ (ARGUMENT_PACK_INCOMPLETE_P): Use TREE_ADDRESSABLE instead of
+ TREE_LANG_FLAG_0 on TREE_VECs.
+
+2012-08-20 Florian Weimer <fweimer@redhat.com>
+
+ PR c++/19351
+ * call.c (build_operator_new_call): Add size_check argument and
+ evaluate it.
+ * cp-tree.h (build_operator_new_call): Adjust declaration.
+ * init.c (build_new_1): Compute array size check and apply it.
+
+2012-08-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/10416
+ * decl.c (poplevel): Check TYPE_HAS_NONTRIVIAL_DESTRUCTOR for
+ Wunused_variable too.
+
+2012-08-20 Diego Novillo <dnovillo@google.com>
+
+ * decl.c (poplevel): Start TV_NAME_LOOKUP conditionally.
+
+2012-08-20 Richard Guenther <rguenther@suse.de>
+
+ * name-lookup.c (store_binding_p): New predicate, split out from ...
+ (store_binding): ... here. Always store binding and require
+ target vector with enough space.
+ (store_bindings): Collect to store bindings and reserve space
+ for them, then store them.
+ (store_class_bindings): Likewise.
+
+2012-08-19 Mikael Morin <mikael@gcc.gnu.org>
+
+ * Make-lang.in: Fix typo.
+
+2012-08-17 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.def (SIZEOF_EXPR): Move to c-common.def.
+
+2012-08-14 Diego Novillo <dnovillo@google.com>
+
+ Merge from cxx-conversion branch. Re-write VEC in C++.
+
+ * call.c (add_function_candidate): Remove const qualifier
+ from call to VEC_index.
+
+2012-08-10 Richard Guenther <rguenther@suse.de>
+
+ * error.c (dump_expr): Handle anonymous SSA names.
+
+2012-08-07 Steven Bosscher <steven@gcc.gnu.org>
+
+ * error.c (print_instantiation_context): Pretty-print a newline before
+ diagnostic_flush_buffer.
+ * cxx-pretty-print.c (pp_cxx_function_definition): Use
+ pp_newline_and_flush instead of separate pp_newline and pp_flush.
+
+2012-08-06 Dodji Seketeli <dodji@redhat.com>
+
+ Avoid crashing on erroneous static_assert usage
+ * semantics.c (finish_static_assert): Don't crash on erroneous
+ message or condition.
+
+2012-08-06 Marc Glisse <marc.glisse@inria.fr>
+ Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54165
+ * typeck.c (build_static_cast_1): Move the conversion to void case
+ before the perform_direct_initialization_if_possible call.
+
+2012-08-03 Marc Glisse <marc.glisse@inria.fr>
+
+ * pt.c (tsubst_copy_and_build): Handle VECTOR_TYPE like scalars.
+ * cp-tree.h (scalarish_type_p): Declare.
+ * tree.c (scalarish_type_p): Make non-static.
+
+2012-08-02 Jason Merrill <jason@redhat.com>
+ Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51213 (again)
+ * pt.c (type_unification_real): Call push_deferring_access_checks /
+ pop_deferring_access_checks around the substitution of default
+ template args.
+ (instantiate_template_1): When the specialization returned by
+ retrieve_specialization has FNDECL_HAS_ACCESS_ERRORS set and we
+ are in a SFINAE context, simply return error_mark_node.
+ * cp-tree.h (FNDECL_RECHECK_ACCESS_P): Rename FNDECL_HAS_ACCESS_ERRORS.
+
+2012-07-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * pt.c (check_default_tmpl_args): Change is_primary and is_partial
+ parameters to bool type, adjust.
+ (push_template_decl_real): Tidy.
+ * parser.c (cp_parser_init_declarator): Adjust.
+ * decl.c (redeclaration_error_message): Likewise.
+ * cp-tree.h (check_default_tmpl_args): Update prototype.
+
+2012-07-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53624
+ * pt.c (check_default_tmpl_args): Don't check local types.
+
+2012-07-25 Sandra Loosemore <sandra@codesourcery.com>
+ Paul Brook <paul@codesourcery.com>
+
+ PR target/53633
+ * decl.c (finish_function): Check targetm.warn_func_return.
+
+2012-07-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/54086
+ * decl.c (grokdeclarator): Allow const and constexpr together.
+
+ PR c++/54020
+ * semantics.c (potential_constant_expression_1) [COND_EXPR]: Call
+ maybe_constant_value.
+
+ * cp-tree.h (tsubst_flags): Remove tf_no_access_control.
+ * call.c (standard_conversion): Don't set it.
+ * class.c (resolve_address_of_overloaded_function): Don't check it.
+ * decl.c (check_default_argument): Call
+ perform_implicit_conversion_flags.
+
+ * pt.c (print_candidates_1): Use inform instead of error.
+
+2012-07-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * pt.c (convert_template_argument, tsubst): Simplify fourth argument
+ to make_typename_type (complain & tf_error -> complain).
+
+2012-07-24 Steven Bosscher <steven@gcc.gnu.org>
+
+ * class.c (n_vtables, n_vtable_entries, n_vtable_searches,
+ n_vtable_elems, n_convert_harshness, n_compute_conversion_costs,
+ n_inner_fields_searched): Always define.
+ (build_primary_vtable): Convert #ifdef GATHER_STATISTICS to if-code.
+ (print_class_statistics): Convert #ifdef GATHER_STATISTICS to if-code.
+ * tree.c (depth_reached): Always define global.
+ (cxx_print_statistics): Convert #ifdef GATHER_STATISTICS to if-code.
+ * pt.c (depth_reached): Always define.
+ (push_tinst_level): Convert #ifdef GATHER_STATISTICS to if-code.
+ * search.c (n_fields_searched, n_calls_lookup_field,
+ n_calls_lookup_field_1, n_calls_lookup_fnfields,
+ n_calls_lookup_fnfields_1, n_calls_get_base_type,
+ n_outer_fields_searched, n_contexts_saved): Always define.
+ (lookup_field_1): Convert #ifdef GATHER_STATISTICS to if-code.
+ (lookup_member): Likewise.
+ (lookup_fnfields_idx_nolazy): Likewise.
+ (print_search_statistics): Likewise.
+ (reinit_search_statistics): Unconditionally re-set counters.
+ * lex.c (retrofit_lang_decl): Convert #ifdef GATHER_STATISTICS
+ to if-code.
+ (cxx_dup_lang_specific_decl): Likewise.
+ (copy_lang_type): Likewise.
+ (cxx_make_type): Likewise.
+
+2012-07-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/54038
+ * tree.c (build_cplus_array_type): Use build_cplus_array_type to build
+ canonical array type rather than mess with its TYPE_*_VARIANT.
+
+2012-07-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/54026
+ * typeck.c (cp_apply_type_quals_to_decl): Check COMPLETE_TYPE_P.
+
+ PR c++/54021
+ * call.c (build_cxx_call): Set optimize when folding
+ __builtin_constant_p in a constexpr function.
+
+2012-07-18 Jason Merrill <jason@redhat.com>
+
+ * pt.c (instantiate_decl): Don't recheck substitutions.
+
+2012-07-18 Paolo Carlini <paolo.carlini@oracle.com>
+ Jason Merrill <jason@redhat.com>
+
+ DR 1170
+ PR c++/51213
+ * semantics.c (perform_access_checks): Add complain parm, return bool.
+ (perform_deferred_access_checks): Likewise.
+ (perform_or_defer_access_check): Likewise.
+ (speculative_access_check): Remove.
+ * call.c (enforce_access): Add complain parm, return bool.
+ * decl.c, friend.c, class.c, init.c, parser.c: Adjust callers.
+ * search.c: Adjust callers.
+ * cp-tree.h (TINFO_RECHECK_ACCESS_P): New macro.
+ (FNDECL_RECHECK_ACCESS_P): New macro.
+ * method.c (synthesized_method_walk): Stop deferring access checks.
+ * pt.c (recheck_decl_substitution): New.
+ (instantiate_template_1): Set and check FNDECL_RECHECK_ACCESS_P.
+
+2012-07-18 Jason Merrill <jason@redhat.com>
+
+ * method.c (process_subob_fn): Make sure no_implicit_p is non-null
+ before trying to store through it.
+
+2012-07-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/53995
+ * decl.c (finish_enum_value_list): Only call
+ insert_late_enum_def_into_classtype_sorted_fields in class scope.
+
+ PR c++/53989
+ * tree.c (build_cplus_array_type): Also add TYPE_CANONICAL
+ to the list of variants.
+
+ * decl.c (xref_basetypes): Complain about incomplete template base.
+ * class.c (finish_struct): Adjust variants in templates, too.
+
+ PR c++/53549
+ * parser.c (cp_parser_class_head): Call xref_basetypes here.
+ (cp_parser_class_specifier_1): Not here.
+ * pt.c (tsubst_decl) [USING_DECL]: Check uses_template_parms
+ as well as DECL_DEPENDENT_P.
+
+2012-07-16 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (struct deferred_access_check): Add location.
+ * semantics.c (perform_access_checks): Use it.
+ (perform_or_defer_access_check): Store it.
+
+2012-07-16 Steven Bosscher <steven@gcc.gnu.org>
+
+ * dump.c (dump_stmt): Moved here from c-dump.c.
+ * optimize.c: Include dumpfile.h instead of tree-dump.h.
+ * class.c: Likewise.
+ * decl2.c: Likewise.
+ * Make-lang.in: Fix dependencies.
+
+2012-07-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/53953
+ * method.c (synthesized_method_walk): Initialize no_implicit_p sooner.
+
+2012-07-12 Jason Merrill <jason@redhat.com>
+
+ * pt.c (instantiate_decl): Check typedefs access here.
+ (instantiate_template_1): Not here.
+
+ * pt.c (deduction_tsubst_fntype): Just suppress access checking.
+ (instantiate_template_1): Set DECL_TI_TEMPLATE before access checking.
+ (push_deduction_access_scope, pop_deduction_access_scope): Remove.
+
+2012-07-11 Jason Merrill <jason@redhat.com>
+
+ DR 1402
+ * method.c (synthesized_method_walk): Replace uses of msg with diag.
+ Correct handling of virtual bases with move operations.
+ (process_subob_fn, walk_field_subobs): Replace uses of msg with diag.
+
+2012-07-11 Steven Bosscher <steven@gcc.gnu.org>
+
+ * method.c: Do not include tree-pass.h.
+
+2012-07-10 Jason Merrill <jason@redhat.com>
+
+ DR 1402
+ PR c++/53733
+ * cp-tree.h (FNDECL_SUPPRESS_IMPLICIT_DECL): New.
+ (struct lang_decl_fn): Add suppress_implicit_decl field.
+ * method.c (implicitly_declare_fn): Check it.
+ (process_subob_fn): Add no_implicit_p parm.
+ (walk_field_subobs, synthesized_method_walk): Likewise.
+ (maybe_explain_implicit_delete): Adjust.
+ (explain_implicit_non_constexpr): Adjust.
+
+ * method.c (synthesized_method_walk): Avoid changing
+ EH spec based on cleanups in other places, too.
+
+2012-07-09 Sterling Augustine <saugustine@google.com>
+
+ * error.c (lang_decl_name): Use TFF_UNQUALIFIED_NAME flag.
+
+2012-07-08 Steven Bosscher <steven@gcc.gnu.org>
+
+ * decl.c (cp_finish_decl): Add FIXME at add_local_decl call site.
+
+2012-07-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/53862
+ * pt.c (tsubst_arg_types): Add "end" parameter.
+ (check_undeduced_parms): Use it.
+
+ * cp-tree.h (DECL_DECLARES_TYPE_P): Check DECL_TYPE_TEMPLATE_P.
+
+ PR c++/53858
+ * name-lookup.c (ambiguous_decl): Use DECL_TYPE_TEMPLATE_P.
+
+2012-07-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/53039
+ * pt.c (arg_from_parm_pack_p): Go back to using same_type_p or
+ cp_tree_equal.
+
+ * cp-tree.h (TEMPLATE_PARM_NUM_SIBLINGS): Remove.
+ (struct template_parm_index_s): Remove num_siblings.
+ * pt.c (fixup_template_parms, fixup_template_parm_index): Remove.
+ (fixup_template_type_parm_type): Remove.
+ (build_template_parm_index): Remove num_siblings parm.
+ (process_template_parm): Likewise.
+ * parser.c (cp_parser_template_parameter_list): Adjust.
+ * tree.c (cp_tree_equal): Don't compare num_siblings.
+ * typeck.c (comp_template_parms_position): Likewise.
+
+ PR c++/50852
+ PR c++/53039
+ * tree.c (strip_typedefs_expr): New.
+ * cp-tree.h: Declare it.
+ * pt.c (convert_template_argument, unify): Use it.
+ * parser.c (cp_parser_template_declaration_after_export): Don't call
+ fixup_template_parms.
+
+2012-07-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/53848
+ PR c++/53524
+ * decl.c (build_enumerator): Don't use build_lang_decl_loc.
+
+2012-07-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/53812
+ * semantics.c (finish_goto_stmt): Surround computed goto argument
+ with CLEANUP_POINT_EXPR if needed.
+
+2012-07-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/53619
+ * pt.c (in_template_function): New.
+ * cp-tree.h: Declare it.
+ * class.c (build_base_path, resolves_to_fixed_type_p): Use it.
+
+ PR c++/53783
+ * pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Use tsubst
+ for LAMBDA_EXPR_EXTRA_SCOPE.
+
+ PR c++/53788
+ * pt.c (build_non_dependent_expr): Don't wrap a dummy object.
+
+ PR c++/53816
+ * class.c (resolves_to_fixed_type_p): Check uses_template_parms
+ (current_function_decl) instead of processing_template_decl.
+
+ PR c++/53821
+ * semantics.c (maybe_add_lambda_conv_op): Don't set
+ DECL_INTERFACE_KNOWN.
+
+ PR c++/53524
+ * call.c (build_conditional_expr_1): Don't warn about comparison of
+ two enumerators before their enumeration is complete.
+ (build_new_op_1): Call decay_conversion before warn_logical_operator.
+ * decl.c (build_enumerator): Set DECL_CONTEXT of an enumerator to
+ its enumeration.
+ * decl2.c (mark_used): Call used_types_insert for enums.
+ * semantics.c (finish_id_expression): Don't decay CONST_DECL.
+ (finish_member_declaration): Don't change DECL_CONTEXT of enumerators.
+ * class.c (check_field_decls): Don't change DECL_CONTEXT of enums.
+ * typeck.c (convert_for_assignment): Don't decay CONST_DECL.
+ (build_class_member_access_expr): Look through unscoped enums.
+ * search.c (context_for_name_lookup): Look through unscoped enums.
+ * pt.c (tsubst_copy_and_build): Don't decay CONST_DECL.
+ (tsubst_copy): Use DECL_CONTEXT to find the enumeration.
+ * tree.c (decl_linkage): Likewise.
+ * cvt.c (ocp_convert): Check decayed expr for enum range warning.
+
+2012-06-29 Steven Bosscher <steven@gcc.gnu.org>
+
+ * Make-lang.in: Remove tree-mudflap.o from CXX_AND_OBJCXX_OBJS.
+
+2012-06-27 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_check_for_invalid_template_id): tag_type parm.
+ (cp_parser_simple_type_specifier, cp_parser_class_head): Adjust.
+ (cp_parser_elaborated_type_specifier): Adjust.
+ * decl.c (duplicate_decls): Return error_mark_node on template
+ mismatch.
+
+ PR c++/53563
+ * parser.c (cp_parser_template_id): Add tag_type parm.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_id_expression, cp_parser_unqualified_id): Adjust.
+ (cp_parser_pseudo_destructor_name, cp_parser_type_name): Adjust.
+ (cp_parser_simple_type_specifier, cp_parser_class_name): Adjust.
+ (cp_parser_elaborated_type_specifier, cp_parser_class_head): Adjust.
+
+2012-06-27 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
+
+ PR C++/51033
+ * semantics.c (constexpr_call): Fix typo in comment.
+ (cxx_eval_vec_perm_expr): New.
+ (cxx_eval_constant_expression): Fold VEC_PERM_EXPRs.
+
+2012-06-26 Richard Guenther <rguenther@suse.de>
+
+ PR c++/53752
+ * mangle.c (write_array_type): Truncate the number-of-elements
+ result.
+
+2012-06-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/53498
+ PR c++/53305
+ * pt.c (tsubst_decl) [PARM_DECL]: Don't recurse into DECL_CHAIN
+ if cp_unevaluated_operand is set.
+ (tsubst_copy) [PARM_DECL]: Don't copy before tsubsting.
+
+ PR c++/52988
+ * typeck.c (decay_conversion): Don't discard side-effects from
+ expressions of nullptr_t.
+
+2012-06-25 Florian Weimer <fweimer@redhat.com>
+
+ * init.c (build_new_1): Warn about (T[N]) for variable N, and
+ reject T[M][N].
+
+ * parser.c (cp_parser_direct_new_declarator): Accept non-constant
+ expressions. Handled now in build_new_1.
+
+2012-06-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/53202
+ * semantics.c (build_data_member_initialization): Always keep
+ initializer for empty base.
+ (cxx_eval_bare_aggregate): Discard it here.
+
+ PR c++/53565
+ * pt.c (tsubst_omp_for_iterator): Simplify DECL_EXPR handling.
+ (tsubst_expr) [OMP_FOR]: Here, too.
+
+2012-06-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/53594
+ * class.c (check_bases_and_members): Avoid -Wuninitialized
+ diagnostics for non-static const members or references if they
+ use NSDMI.
+
+2012-06-16 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ * parser.c (cp_parser_direct_declarator): Move virt-specifier
+ parsing after late-specified return type parsing.
+
+2012-06-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/53651
+ * name-lookup.c (constructor_name_p): Don't try to look at the
+ name of a DECLTYPE_TYPE.
+
+2012-06-18 Lawrence Crowl <crowl@google.com>
+
+ * decl2.c (cp_write_global_declarations): Rename use of TV_PHASE_CGRAPH
+ to TV_PHASE_OPT_GEN.
+
+2012-06-18 Steven Bosscher <steven@gcc.gnu.org>
+
+ * decl.c (finish_function): Remove code conditional on VMS_TARGET.
+
+2012-06-15 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/51033
+ * semantics.c (literal_type_p): Handle VECTOR_TYPE.
+ (potential_constant_expression_1): Handle VEC_PERM_EXPR.
+ * parser.c (cp_parser_postfix_expression): Handle RID_BUILTIN_SHUFFLE.
+
+2012-06-09 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_expr) [TAG_DEFN]: Instantiate local class.
+ * class.c (finish_struct): Don't add a TAG_DEFN for a lambda.
+ * decl2.c (finish_static_data_member_decl): Avoid redundant error.
+
+ PR c++/53599
+ * name-lookup.c (pushtag_1): Add a DECL_EXPR for a local class.
+ * semantics.c (finish_cond): Build a COMPOUND_EXPR.
+ * pt.c (tsubst_expr) [COMPOUND_EXPR]: Handle.
+ [DECL_EXPR]: Don't call cp_finish_decl for an implicit typedef.
+ Don't return the decl.
+
+2012-06-11 Richard Guenther <rguenther@suse.de>
+
+ PR c++/53605
+ * mangle.c (write_array_type): Use double-ints for array domain
+ arithmetic.
+
+2012-06-07 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/51214
+ * cp-tree.h (insert_late_enum_def_into_classtype_sorted_fields):
+ Declare.
+ * class.c (insert_into_classtype_sorted_fields): New.
+ (add_enum_fields_to_record_type): New.
+ (count_fields): Adjust the comment.
+ (add_fields_to_record_type): Likewise.
+ (finish_struct_1): Move the code that inserts the fields for the
+ sorted case, into insert_into_classtype_sorted_fields, and call
+ it.
+ (insert_late_enum_def_into_classtype_sorted_fields): Define.
+ * decl.c (finish_enum_value_list): Call
+ insert_late_enum_def_into_classtype_sorted_fields if a late enum
+ definition is encountered.
+
+2012-06-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53567
+ * typeck.c (cp_perform_integral_promotions): New, like
+ perform_integral_promotions but also takes a tsubst_flags_t parameter.
+ (pointer_diff): Add tsubst_flags_t parameter.
+ (decay_conversion, cp_default_conversion, cp_build_array_ref,
+ cp_build_binary_op, cp_build_unary_op, build_static_cast_1,
+ build_reinterpret_cast_1, cp_build_modify_expr,
+ convert_for_assignment): Adjust.
+ * optimize.c (build_delete_destructor_body): Adjust.
+ * init.c (expand_virtual_init, expand_default_init, build_new_1,
+ build_new, build_vec_delete_1, build_vec_init, build_delete): Adjust.
+ (construct_virtual_base): Adjust LOOKUP_COMPLAIN -> 0.
+ * class.c (build_base_path): Adjust.
+ * decl.c (compute_array_index_type, finish_destructor_body): Likewise.
+ * method.c (synthesized_method_walk): Adjust flag and complain.
+ * rtti.c (ifnonnull): Add tsubst_flags_t parameter.
+ (build_typeid, build_dynamic_cast_1): Adjust.
+ * except.c (initialize_handler_parm): Likewise.
+ * typeck2.c (process_init_constructor_record): Likewise.
+ * pt.c (tsubst_friend_class): Don't change flags.
+ * semantics.c (finish_goto_stmt, handle_omp_for_class_iterator,
+ finish_static_assert): Likewise.
+ * parser.c (cp_parser_lookup_name): Just pass 0 as flags to
+ lookup_name_real.
+ * call.c (build_op_delete_call): Add tsubst_flags_t parameter.
+ (convert_like_real, convert_arg_to_ellipsis, convert_for_arg_passing):
+ Adjust.
+ (standard_conversion): Adjust LOOKUP_COMPLAIN -> 0.
+ (implicit_conversion): Mask out tf_error with a FIXME.
+ (build_user_type_conversion_1, build_new_op_1, build_over_call): Use
+ complain & tf_error instead of flags & LOOKUP_COMPLAIN.
+ * cvt.c (cp_convert_to_pointer, convert_to_pointer_force,
+ build_up_reference, convert_to_reference, cp_convert,
+ cp_convert_and_check, ocp_convert, convert_force): Add tsubst_flags_t
+ parameter.
+ (convert_to_reference, ocp_convert): Use complain & tf_error instead
+ of flags & LOOKUP_COMPLAIN.
+ (convert_force): Adjust LOOKUP_COMPLAIN -> 0.
+ * name-lookup.c (identifier_type_value_1, lookup_qualified_name,
+ lookup_name_real, lookup_function_nonclass, lookup_name,
+ lookup_name_prefer_type): Adjust LOOKUP_COMPLAIN -> 0.
+ * cp-tree.h: Adjust prototypes; remove LOOKUP_COMPLAIN.
+
+2012-06-06 Steven Bosscher <steven@gcc.gnu.org>
+
+ * decl.c: Do not include output.h.
+ (start_decl): Remove code for flag_conserve_space.
+
+2012-06-06 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/52841
+ * parser.c (cp_parser_alias_declaration): Return earlier
+ if an error occured.
+
+2012-06-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53524
+ * call.c (build_conditional_expr_1): Use OPT_Wenum_compare
+ to control enumeral mismatch in conditional expression too.
+
+2012-06-04 Sterling Augustine <saugustine@google.com>
+
+ * cp-tree.h: Declare decl_as_dwarf_string, lang_decl_dwarf_name.
+ * cp-lang.c (cxx_dwarf_name): Call them.
+
+2012-06-04 Steven Bosscher <steven@gcc.gnu.org>
+
+ * semantics.c: Do not include output.h.
+ * decl2.c: Likewise.
+ * friend.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+ * Make-lang.in: Fix dependencies.
+
+2012-06-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/52973
+ * parser.c (cp_parser_class_head): Apply attributes here.
+ * semantics.c (begin_class_definition): Not here.
+ * cp-tree.h: Adjust.
+
+ PR c++/52725
+ * parser.c (cp_parser_binary_expression): Bail early if we're parsing
+ tentatively and the LHS has a parse error.
+
+ PR c++/53137
+ * pt.c (instantiate_class_template_1): Set LAMBDA_EXPR_THIS_CAPTURE.
+ (instantiate_decl): Don't push_to_top_level for local class methods.
+ (instantiate_class_template_1): Or for local classes.
+
+ PR c++/53484
+ * pt.c (do_auto_deduction): Don't try to deduce from a
+ type-dependent initializer.
+
+2012-06-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/26155
+ * name-lookup.c (push_namespace): When error recovery is
+ impossible just error out in duplicate_decls.
+
+2012-05-31 Steven Bosscher <steven@gcc.gnu.org>
+
+ * call.c: Do not include output.h.
+ * class.c: Likewise.
+ * except.c: Likewise.
+ * friend.c: Likewise.
+ * init.c: Likewise.
+ * lex.c: Likewise.
+ * method.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+
+2012-05-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/53356
+ * tree.c (stabilize_init): Handle stabilizing a TARGET_EXPR
+ representing a bitwise copy of a glvalue.
+
+ * tree.c (stabilize_expr): Tweak logic.
+
+ PR c++/53356
+ * tree.c (stabilize_init): Side effects make the init unstable.
+
+2012-05-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53503
+ * semantics.c (potential_constant_expression_1): Handle LTGT_EXPR.
+
+2012-05-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53491
+ * tree.c (stabilize_expr): Handle exp of void type.
+
+2012-05-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/53220
+ * call.c (convert_like_real) [ck_list]: Take array address directly.
+ * typeck.c (decay_conversion): Reject decay of an array compound
+ literal.
+
+2012-05-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/32054
+ * parser.c (cp_parser_member_declaration): A storage class is not
+ allowed in a declaration of an anonymous aggregate in a class scope.
+
+2012-05-24 Uros Bizjak <ubizjak@gmail.com>
+
+ PR obj-c++/53441
+ * decl.c (grokdeclarator): Check that current_class_type is non-NULL
+ before calling constructor_name_p.
+
+2012-05-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/32080
+ * parser.c (cp_parser_ctor_initializer_opt_and_function_body,
+ cp_parser_function_body): Add a bool parameter, true when parsing
+ a function-try-block.
+ (cp_parser_function_try_block): Pass true to the above.
+ (cp_parser_function_definition_after_declarator,
+ cp_parser_function_transaction): Adjust.
+
+2012-05-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/29185
+ * decl2.c (delete_sanity): Extend 'deleting array' warning to
+ any array type.
+
+2012-05-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51184
+ * decl.c (grokdeclarator): Diagnose functions returning abstract
+ class types as TYPENAME.
+ * cp-tree.h (ABSTRACT_CLASS_TYPE_P): Add.
+ * except.c (is_admissible_throw_operand_or_catch_parameter): Use it.
+ * pt.c (tsubst): Likewise.
+ * semantics.c (trait_expr_value): Likewise.
+
+2012-05-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/40821
+ * parser.c (cp_parser_attributes_opt): Enforce error checking of
+ unbalanced parentheses in the presence of tentative parsing.
+
+2012-05-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/39681
+ * parser.c (cp_parser_new_type_id): Early return error_mark_node
+ if the cp_parser_type_specifier_seq call has type_specifier_seq.type
+ error_mark_node; tidy.
+ (cp_parser_new_expression): Always initialize nelts to NULL_TREE to
+ avoid uninitialized warnings.
+ (cp_parser_init_declarator, cp_parser_late_parse_one_default_arg):
+ Call cp_parser_skip_to_end_of_statement if cp_parser_initializer
+ returns error_mark_node.
+
+2012-05-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53371
+ * except.c (is_admissible_throw_operand): Rename to
+ is_admissible_throw_operand_or_catch_parameter and handle
+ catch parameter too.
+ (expand_start_catch_block): Use it.
+ (build_throw): Adjust.
+
+2012-05-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44516
+ * typeck.c (build_x_array_ref, build_x_conditional_expr,
+ build_x_compound_expr, build_x_modify_expr): Add location_t parameter.
+ (finish_class_member_access_expr, build_x_indirect_ref,
+ build_x_binary_op, build_x_compound_expr_from_list,
+ build_x_compound_expr_from_vec): Adjust callers.
+ * tree.c (build_min_nt_loc): New.
+ (build_min_nt): Remove.
+ * typeck2.c (build_x_arrow): Adjust callers.
+ * pt.c (tsubst_qualified_id, tsubst_omp_for_iterator,
+ tsubst_copy_and_build): Likewise.
+ * semantics.c (finish_mem_initializers, handle_omp_for_class_iterator,
+ finish_omp_atomic): Likewise.
+ * decl2.c (grok_array_decl, build_anon_union_vars): Adjust.
+ * parser.c (cp_parser_question_colon_clause,
+ cp_parser_assignment_expression, cp_parser_expression,
+ cp_parser_template_id, cp_parser_omp_for_loop): Likewise.
+ * cp-tree.h: Update.
+
+2012-05-16 Dodji Seketeli <dodji@redhat.com>
+
+ PR preprocessor/7263
+ * cp-tree.h (enum cp_decl_spec): Add new enumerators to cover all
+ the possible declarator specifiers so far.
+ (struct cp_decl_specifier_seq::locations): Declare new member.
+ (cp_decl_specifier_seq::{specs, type_location}): Remove.
+ (decl_spec_seq_has_spec_p): Declare new function.
+ * parser.c (cp_parser_check_decl_spec): Remove.
+ (set_and_check_decl_spec_loc): Define new static function.
+ (decl_spec_seq_has_spec_p): Define new public function.
+ (cp_parser_decl_specifier_seq, cp_parser_function_specifier_opt)
+ (cp_parser_type_specifier, cp_parser_simple_type_specifier)
+ (cp_parser_set_storage_class, cp_parser_set_decl_spec_type)
+ (cp_parser_alias_declaration): Set the locations for each
+ declspec, using set_and_check_decl_spec_loc.
+ (cp_parser_explicit_instantiation, cp_parser_init_declarator)
+ (cp_parser_member_declaration, cp_parser_init_declarator): Use the
+ new declspec location for specifiers. Use the new
+ decl_spec_seq_has_spec_p.
+ (cp_parser_type_specifier_seq): Use the new
+ set_and_check_decl_spec_loc. Stop using
+ cp_parser_check_decl_spec. Use the new decl_spec_seq_has_spec_p.
+ (, cp_parser_init_declarator): Use the new
+ set_and_check_decl_spec_loc.
+ (cp_parser_single_declaration, cp_parser_friend_p)
+ (cp_parser_objc_class_ivars, cp_parser_objc_struct_declaration):
+ Use the new decl_spec_seq_has_spec_p.
+ * decl.c (check_tag_decl): Use new decl_spec_seq_has_spec_p. Use
+ the more precise ds_redefined_builtin_type_spec location for
+ diagnostics about re-declaring C++ built-in types.
+ (start_decl, grokvardecl, grokdeclarator): Use the new
+ decl_spec_seq_has_spec_p.
+
+2012-05-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/11856
+ * pt.c (tsubst_copy_and_build): Increase / decrease
+ c_inhibit_evaluation_warnings around build_x_binary_op call.
+
+2012-05-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cp-tree.h (TYPE_PTRMEM_P): Rename to TYPE_PTRDATAMEM_P.
+ (TYPE_PTR_TO_MEMBER_P): Rename to TYPE_PTRMEM_P.
+ (TYPE_PTR_OR_PTRMEM_P): Add.
+ * typeck.c (composite_pointer_type_r, composite_pointer_type,
+ common_pointer_type, cp_build_indirect_ref, cp_build_binary_op,
+ cp_truthvalue_conversion, convert_ptrmem, build_static_cast_1,
+ build_reinterpret_cast_1, build_const_cast_1, comp_ptr_ttypes_real,
+ casts_away_constness_r, casts_away_constness): Adjust.
+ * init.c (build_zero_init_1): Adjust.
+ * class.c (check_field_decls): Likewise.
+ * decl.c (check_default_argument): Likewise.
+ * rtti.c (target_incomplete_p): Likewise.
+ * tree.c (zero_init_p): Likewise.
+ * cxx-pretty-print.c (pp_cxx_ptr_operator,
+ pp_cxx_abstract_declarator): Likewise.
+ * typeck2.c (build_m_component_ref): Likewise.
+ * pt.c (convert_nontype_argument, invalid_nontype_parm_type_p,
+ dependent_type_p_r): Likewise.
+ * call.c (null_member_pointer_value_p, standard_conversion,
+ add_builtin_candidate, build_conditional_expr_1, compare_ics):
+ Likewise.
+ * cp-objcp-common.c (cp_var_mod_type_p): Likewise.
+ * cvt.c (cp_convert_to_pointer, ocp_convert,
+ perform_qualification_conversions): Likewise.
+ * mangle.c (write_type): Likewise.
+ * name-lookup.c (arg_assoc_type): Likewise.
+
+2012-05-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * parser.c (struct cp_parser_expression_stack_entry): Add location_t
+ field.
+ (cp_parser_binary_expression): Rework to always update at the same
+ time tree_type and loc.
+ * call.c (print_z_candidate): Add location_t parameter.
+ (print_z_candidates, convert_like_real, joust): Adjust.
+
+2012-05-11 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/53209
+ * pt.c (tsubst_decl): Bail out if argvec is error_mark_node.
+
+2012-05-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53305
+ * pt.c (tsubst_copy: case PARM_DECL): Return error_mark_node if
+ tsubst_decl returns NULL_TREE.
+ * cxx-pretty-print.c (pp_cxx_simple_type_specifier): Handle
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+
+2012-05-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53158
+ * cvt.c (ocp_convert): Error out early for void -> bool conversions.
+ * typeck.c (decay_conversion): Use error_at.
+ * call.c (build_integral_nontype_arg_conv, convert_like_real,
+ convert_arg_to_ellipsis, perform_implicit_conversion_flags,
+ initialize_reference): Likewise.
+ * cvt.c (warn_ref_binding): Add location_t parameter.
+ (cp_convert_to_pointer, convert_to_reference, ocp_convert,
+ convert_to_void, ): Use error_at and warning_at.
+
+2012-05-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53301
+ * decl.c (check_default_argument): Fix typo (POINTER_TYPE_P
+ instead of TYPE_PTR_P) in zero-as-null-pointer-constant warning.
+
+2012-05-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53152
+ * call.c (op_error, build_new_op_1, build_new_op): Add location_t
+ parameter.
+ (build_conditional_expr_1): Adjust.
+ * typeck.c (build_x_indirect_ref, build_x_binary_op,
+ build_x_unary_op): Add location_t parameter.
+ (rationalize_conditional_expr, build_x_array_ref,
+ build_x_compound_expr, cp_build_modify_expr, build_x_modify_expr):
+ Adjust.
+ * typeck2.c (build_x_arrow): Add location_t parameter.
+ * semantics.c (finish_unary_op_expr): Likewise.
+ (finish_increment_expr, handle_omp_for_class_iterator): Adjust.
+ * decl2.c (grok_array_decl): Add location_t parameter.
+ * parser.c (cp_parser_postfix_open_square_expression,
+ cp_parser_postfix_dot_deref_expression, cp_parser_unary_expression,
+ cp_parser_binary_expression, cp_parser_builtin_offsetof,
+ do_range_for_auto_deduction, cp_convert_range_for,
+ cp_parser_template_argument, cp_parser_omp_for_cond): Pass the
+ location, adjust.
+ * pt.c (tsubst_copy_and_build): Adjust.
+ * tree.c (maybe_dummy_object): Likewise.
+ * cp-tree.h: Update declarations.
+
+2012-05-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * semantics.c (cxx_eval_constant_expression, case CONVERT_EXPR): Tidy.
+
+2012-05-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53166
+ * pt.c (instantiate_class_template_1): Increase / decrease
+ c_inhibit_evaluation_warnings around the tsubst_expr call
+ for STATIC_ASSERT_CONDITION.
+ (tsubst_expr, case STATIC_ASSERT): Likewise.
+ * typeck.c (cp_build_binary_op, case EQ_EXPR/NE_EXPR): Check
+ c_inhibit_evaluation_warnings in the OPT_Waddress warnings.
+
+2012-05-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53186
+ * call.c (build_over_call): Handle final member functions
+ and class types.
+ (build_new_method_call_1): Do not handle here.
+
+2012-05-02 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (grokdeclarator): Properly check for sizes that
+ cover more than half of the address-space.
+
+2012-04-30 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/51033
+ * typeck.c (cp_build_array_ref): Handle VECTOR_TYPE.
+ * decl2.c (grok_array_decl): Likewise.
+
+ PR c++/51314
+ * parser.c (cp_parser_sizeof_operand): Require parentheses for
+ sizeof...
+
+2012-04-30 Dodji Seketeli <dodji@redhat.com>
+
+ Fix location for static class members
+ * decl.c (grokdeclarator): Use the location carried by the
+ declarator for the DECL of the static class member.
+
+ Fix va_arg type location
+ * cp-tree.h (build_x_va_arg): Take an additional location
+ parameter.
+ * call.c (build_x_va_arg): Take a loc parameter for the location
+ of the type of the va_arg expression.
+ * parser.c (cp_parser_primary_expression): Pass the type of the
+ type in the va_arg expression to build_x_va_arg.
+ * pt.c (tsubst_copy): Adjust calls to build_x_va_arg.
+
+ Make conversion warnings work on NULL with -ftrack-macro-expansion
+ * call.c (conversion_null_warnings): Use the new
+ expansion_point_location_if_in_system_header.
+ * cvt.c (build_expr_type_conversion): Likewise.
+ * typeck.c (cp_build_binary_op): Likewise.
+
+2012-04-30 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ * typeck.c (convert_for_assignment): Replace
+ Wmissing-format-attribute with Wsuggest-attribute=format.
+ * call.c (convert_for_arg_passing): Likewise.
+
+2012-04-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53096
+ * class.c (check_bases_and_members): Implement core/1333, do not
+ disallow defaulted in the class body non-const ref special members.
+
+2012-04-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52363
+ * call.c (tourney, perform_overload_resolution,
+ build_operator_new_call, build_user_type_conversion_1,
+ build_user_type_conversion, perform_overload_resolution,
+ add_template_candidate, add_template_candidate_real,
+ add_template_conv_candidate, add_builtin_candidates,
+ add_builtin_candidate, build_builtin_candidate,
+ add_conv_candidate, add_function_candidate, implicit_conversion,
+ reference_binding, build_list_conv, conditional_conversion,
+ add_candidates, can_convert_array, build_aggr_conv,
+ build_array_conv, build_complex_conv, conditional_conversion):
+ Add tsubst_flags_t parameter.
+ (joust): Likewise, use it to handle SFINAE as if pedantic.
+ (add_list_candidates, build_integral_nontype_arg_conv,
+ perform_overload_resolution, build_new_function_call,
+ build_operator_new_call, build_op_call_1,
+ build_conditional_expr_1, build_new_op_1, convert_like_real,
+ convert_arg_to_ellipsis, convert_default_arg,
+ convert_for_arg_passing, build_over_call,
+ build_new_method_call_1, can_convert_arg, can_convert_arg_bad,
+ perform_implicit_conversion_flags,
+ perform_direct_initialization_if_possible,
+ initialize_reference): Adjust.
+ * typeck.c (casts_away_constness, casts_away_constness_r):
+ Add tsubst_flags_t parameter.
+ (convert_arguments, check_for_casting_away_constness,
+ build_static_cast_1, build_ptrmemfunc, convert_for_assignment):
+ Adjust.
+ * decl.c (reshape_init_r, check_default_argument): Likewise.
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Likewise.
+ * pt.c (convert_nontype_argument, check_non_deducible_conversion):
+ Likewise.
+ * init.c (build_new_1): Likewise.
+ * cvt.c (convert_to_reference, ocp_convert, build_type_conversion,
+ build_expr_type_conversion, ): Likewise.
+ * search.c (check_final_overrider): Likewise.
+ * cp-tree.h (build_user_type_conversion,
+ build_operator_new_call, can_convert, can_convert_arg,
+ can_convert_arg_bad, convert_default_arg,
+ convert_arg_to_ellipsis, convert_for_arg_passing):
+ Adjust declaration.
+
+2012-04-22 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (maybe_make_one_only): Mark keyed COMDATs as USED so they
+ gets finalized.
+
+2012-04-22 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/44774
+ * typeck.c (composite_pointer_type): Likewise.
+ (cxx_sizeof_or_alignof_type): Likewise.
+ (cp_build_array_ref): Likewise.
+ (cp_build_function_call_vec): Likewise.
+ (cp_build_addr_expr_1): Likewise.
+ (convert_member_func_to_ptr): Likewise.
+ * decl.c (check_tag_decl): Likewise.
+ (check_static_variable_definition): Likewise.
+ (compute_array_index_type): Likewise.
+ (create_array_type_for_decl): Likewise.
+ (grokdeclarator): Likewise.
+ (grok_op_properties): Likewise.
+ * error.c (maybe_warn_cpp0x): Likewise.
+ * pt.c (maybe_process_partial_specialization): Likewise.
+ (convert_template_argument): Likewise.
+ (do_decl_instantiation): Likewise.
+ (do_type_instantiation): Likewise.
+ * parser.c (cp_parser_primary_expression): Likewise.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_question_colon_clause): Likewise.
+ (cp_parser_lambda_introducer): Likewise.
+ (cp_parser_lambda_declarator_opt): Likewise.
+ (cp_parser_compound_statement): Likewise.
+ (cp_parser_jump_statement): Likewise.
+ (cp_parser_declaration_seq_opt): Likewise.
+ (cp_parser_enum_specifier): Likewise.
+ (cp_parser_enumerator_list): Likewise.
+ (cp_parser_initializer_list): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ * call.c (build_conditional_expr_1): Likewise.
+ * friend.c (make_friend_class): Likewise.
+ * name-lookup.c (pushdecl_maybe_friend_1): Likewise.
+
+2012-04-21 Jan Hubicka <jh@suse.cz>
+
+ * method.c (make_alias_for): Do not set TREE_SYMBOL_REFERENCED.
+ * decl2.c (mark_needed): Likewise.
+ (decl_needed_p): Do not test TREE_SYMBOL_REFERENCED.
+
+ * decl2.c (cxx_callgraph_analyze_expr): Remove.
+ * cp-objcp-common.h (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): Remove.
+ * cp-tree.h (cxx_callgraph_analyze_expr): Remove.
+
+2012-04-21 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR 35441
+ * typeck.c (cp_build_function_call_vec): Do not pretty-print
+ expressions when caret is enabled.
+
+2012-04-20 Jan Hubicka <jh@suse.cz>
+
+ PR target/53042
+ * decl2.c (maybe_emit_vtables): Do not initialize same_comdat_group
+ list when target has no support for it.
+
+2012-04-20 Michael Matz <matz@suse.de>
+
+ * error.c (pedwarn_cxx98): Move va_end call after user
+ of the va_list.
+
+2012-04-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52422
+ * cp-tree.h (build_addr_func, decay_conversion,
+ get_member_function_from_ptrfunc,
+ build_m_component_ref, convert_member_func_to_ptr):
+ Add tsubst_flags_t parameter.
+ * typeck.c (cp_default_conversion): Add.
+ (decay_conversion, default_conversion,
+ get_member_function_from_ptrfunc, convert_member_func_to_ptr):
+ Add tsubst_flags_t parameter and use it throughout.
+ (cp_build_indirect_ref, cp_build_array_ref,
+ cp_build_function_call_vec, convert_arguments, build_x_binary_op,
+ cp_build_binary_op, cp_build_unary_op, build_reinterpret_cast_1,
+ build_const_cast_1, expand_ptrmemfunc_cst,
+ convert_for_initialization): Adjust.
+ * init.c (build_vec_init): Adjust.
+ * decl.c (grok_reference_init, get_atexit_node): Likewise.
+ * rtti.c (build_dynamic_cast_1, tinfo_base_init): Likewise.
+ * except.c (build_throw): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+ (build_m_component_ref): Add tsubst_flags_t parameter and
+ use it throughout.
+ * pt.c (convert_nontype_argument): Adjust.
+ * semantics.c (finish_asm_stmt, maybe_add_lambda_conv_op): Likewise.
+ * decl2.c (build_offset_ref_call_from_tree): Likewise.
+ * call.c (build_addr_func): Add tsubst_flags_t parameter and
+ use it throughout.
+ (build_call_a, build_conditional_expr_1, build_new_op_1,
+ convert_like_real, convert_arg_to_ellipsis, build_over_call,
+ build_special_member_call): Adjust.
+ * cvt.c (cp_convert_to_pointer, force_rvalue,
+ build_expr_type_conversion): Likewise.
+
+2012-04-17 Tom de Vries <tom@codesourcery.com>
+
+ * cp-gimplify.c (begin_bc_block): Add location parameter and use as
+ location argument to create_artificial_label.
+ (finish_bc_block): Change return type to void. Remove body_seq
+ parameter, and add block parameter. Append label to STMT_LIST and
+ return in block.
+ (gimplify_cp_loop, gimplify_for_stmt, gimplify_while_stmt)
+ (gimplify_do_stmt, gimplify_switch_stmt): Remove function.
+ (genericize_cp_loop, genericize_for_stmt, genericize_while_stmt)
+ (genericize_do_stmt, genericize_switch_stmt, genericize_continue_stmt)
+ (genericize_break_stmt, genericize_omp_for_stmt): New function.
+ (cp_gimplify_omp_for): Remove bc_continue processing.
+ (cp_gimplify_expr): Genericize VEC_INIT_EXPR.
+ (cp_gimplify_expr): Mark FOR_STMT, WHILE_STMT, DO_STMT, SWITCH_STMT,
+ CONTINUE_STMT, and BREAK_STMT as unreachable.
+ (cp_genericize_r): Genericize FOR_STMT, WHILE_STMT, DO_STMT,
+ SWITCH_STMT, CONTINUE_STMT, BREAK_STMT and OMP_FOR.
+ (cp_genericize_tree): New function, factored out of ...
+ (cp_genericize): ... this function.
+
+2012-04-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52599
+ * semantics.c (build_constexpr_constructor_member_initializers):
+ Check for function-try-block as function-body.
+
+2012-04-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53003
+ * parser.c (cp_parser_member_declaration): Check that
+ initializer_token_start is non null before dereferencing it.
+
+2012-04-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/38543
+ * pt.c (determine_specialization): Instead of comparing the number
+ of parms, check that tsubst gives the right answer.
+
+ PR c++/52008
+ * pt.c (process_partial_specialization): Complain about a partial
+ specialization with fewer args than primary template parms.
+
+ PR c++/50830
+ * pt.c (convert_template_argument): Handle template template
+ argument packs.
+
+ PR c++/50303
+ * pt.c (tsubst_pack_expansion): Use tsubst_expr for template
+ template parameters.
+
+2012-04-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/49152
+ * call.c (op_error): Print types; when flag_diagnostics_show_caret
+ is false print expressions too.
+ (op_error_string): Add.
+
+2012-04-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/51148
+ * friend.c (make_friend_class): Call check_for_bare_parameter_packs.
+
+2012-04-16 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (collect_candidates_for_java_method_alias): Use FOR_EACH
+ walkers to walk cgraph and varpool.
+
+2012-04-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/47220
+ * pt.c (coerce_template_parameter_pack): Check for error_mark_node.
+
+ PR c++/52292
+ PR c++/52380
+ * pt.c (coerce_template_parms): Even if we aren't converting we
+ want to expand argument packs.
+
+ PR c++/52706
+ * mangle.c (write_type): nullptr_t is a builtin type.
+
+2012-04-14 Jan Hubicka <jh@suse.cz>
+
+ * tree.c: Update field referenced for new cgraph/varpool layout.
+ * decl2.c: Likewise.
+
+2012-04-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/52824
+ * pt.c (any_pack_expanson_args_p): New.
+ (coerce_template_parms): Use it.
+
+ PR c++/52905
+ * call.c (joust): Handle comparing list and non-list ctors.
+
+ PR c++/52915
+ * decl2.c (finish_anon_union): Use cp_finish_decl.
+ * error.c (dump_function_name): Avoid showing anonymous "name".
+
+2012-04-11 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/52465
+ * parser.c (cp_parser_class_name): Call strip_using_decl and
+ return the target decl.
+ * name-lookup.c (strip_using_decl): Returns NULL_TREE if the decl
+ to be stripped is NULL_TREE.
+ (qualify_lookup): Call strip_using_decl and perform some checks on
+ the target decl.
+
+2012-04-11 Jason Merrill <jason@redhat.com>
+
+ PR debug/45088
+ * decl.c (grokdeclarator): Strip the injected-class-name typedef
+ if we are building a declaration or compound type.
+
+ PR c++/52906
+ * decl.c (check_tag_decl): Don't complain about attributes if we
+ don't even have a type.
+
+2012-04-10 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ * cvt.c (convert_to_void): Update comment.
+
+2012-04-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/52596
+ * semantics.c (finish_non_static_data_member): In templates, pass
+ the decl to build_qualified_name.
+ * tree.c (lvalue_kind) [SCOPE_REF]: Handle FIELD_DECL.
+
+2012-04-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/52845
+ * decl.c (finish_function): Update fntype after deducing return type.
+
+2012-04-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/52796
+ * pt.c (tsubst_initializer_list): A pack expansion with no elements
+ means value-initialization.
+
+2012-04-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50043
+ * class.c (deduce_noexcept_on_destructor,
+ deduce_noexcept_on_destructors): New.
+ (check_bases_and_members): Call the latter.
+ * decl.c (grokfndecl): Call the former.
+ * method.c (implicitly_declare_fn): Not static.
+ * cp-tree.h (deduce_noexcept_on_destructor, implicitly_declare_fn):
+ Declare
+
+2012-03-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52718
+ * decl.c (check_default_argument): With -Wzero-as-null-pointer-constant
+ warn for a zero as null pointer constant default argument.
+
+2012-03-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/52685
+ * tree.c (copy_binfo): Handle BINFO_DEPENDENT_BASE_P.
+
+2012-03-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/52759
+ * decl.c (start_decl): Don't call maybe_apply_pragma_weak
+ if processing_template_decl.
+
+2012-03-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/52743
+ * call.c (compare_ics): Handle ck_aggr like ck_list.
+
+2012-03-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/52746
+ * typeck.c (lookup_destructor): Clear BASELINK_QUALIFIED_P if
+ we didn't get an explicit scope.
+ * pt.c (tsubst_baselink): Likewise.
+
+2012-03-28 Richard Guenther <rguenther@suse.de>
+
+ * typeck2.c (process_init_constructor_array): Use the proper
+ type for computing the array length.
+
+2012-03-27 Meador Inge <meadori@codesourcery.com>
+
+ PR c++/52672
+ * semantics.c (cxx_fold_indirect_ref): Don't attempt to fold
+ stripped child trees that are not pointer types.
+
+2012-03-21 Jason Merrill <jason@redhat.com>
+
+ Implement return type deduction for normal functions with -std=c++1y.
+ * cp-tree.h (FNDECL_USED_AUTO): New macro.
+ (LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P): Remove.
+ (dependent_lambda_return_type_node): Remove.
+ (CPTI_DEPENDENT_LAMBDA_RETURN_TYPE): Remove.
+ (struct language_function): Add x_auto_return_pattern field.
+ (current_function_auto_return_pattern): New.
+ (enum tsubst_flags): Add tf_partial.
+ * decl.c (decls_match): Handle auto return comparison.
+ (duplicate_decls): Adjust error message for auto return.
+ (cxx_init_decl_processing): Remove dependent_lambda_return_type_node.
+ (cp_finish_decl): Don't do auto deduction for functions.
+ (grokdeclarator): Allow auto return without trailing return type in
+ C++1y mode.
+ (check_function_type): Defer checking of deduced return type.
+ (start_preparsed_function): Set current_function_auto_return_pattern.
+ (finish_function): Set deduced return type to void if not previously
+ deduced.
+ * decl2.c (change_return_type): Handle error_mark_node.
+ (mark_used): Always instantiate functions with deduced return type.
+ Complain about use if deduction isn't done.
+ * parser.c (cp_parser_lambda_declarator_opt): Use 'auto' for
+ initial return type.
+ (cp_parser_lambda_body): Don't deduce return type in a template.
+ (cp_parser_conversion_type_id): Allow auto in C++1y.
+ * pt.c (instantiate_class_template_1): Don't mess with
+ LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P.
+ (tsubst_copy_and_build): Likewise.
+ (fn_type_unification, tsubst): Don't reduce the template parm level
+ of 'auto' during deduction.
+ (unify): Compare 'auto' specially.
+ (get_bindings): Change test.
+ (always_instantiate_p): Always instantiate functions with deduced
+ return type.
+ (do_auto_deduction): Handle error_mark_node and lambda context.
+ Don't check for use in initializer.
+ (contains_auto_r): Remove.
+ * search.c (lookup_conversions_r): Handle auto conversion function.
+ * semantics.c (lambda_return_type): Handle null return. Don't mess
+ with dependent_lambda_return_type_node.
+ (apply_deduced_return_type): Rename from apply_lambda_return_type.
+ * typeck.c (merge_types): Handle auto.
+ (check_return_expr): Do auto deduction.
+ * typeck2.c (add_exception_specifier): Fix complain check.
+
+2012-03-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52487
+ * class.c (check_field_decls): Call literal_type_p only
+ on complete types.
+
+2012-03-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/52671
+ * decl.c (check_tag_decl): Only use CLASSTYPE_TEMPLATE_INSTANTIATION
+ on CLASS_TYPE_P types.
+
+2012-03-20 Jason Merrill <jason@redhat.com>
+
+ * lex.c (init_reswords): Use >= for cxx_dialect test.
+ * parser.c (cp_parser_exception_specification_opt): Likewise.
+
+ * mangle.c (write_type): Handle 'auto'.
+ * init.c (build_new): Don't do auto deduction where it might
+ affect template mangling.
+
+ PR c++/52510
+ * decl.c (reshape_init_class): Handle repeated reshaping.
+ * search.c (lookup_field_1): Add sanity check.
+
+2012-03-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/14710
+ * cp-tree.h (xvalue_p, maybe_warn_about_useless_cast): Declare.
+ * tree.c (xvalue_p): Define.
+ * typeck.c (maybe_warn_about_useless_cast): Define.
+ (build_reinterpret_cast, build_const_cast,
+ build_static_cast, cp_build_c_cast): Use maybe_warn_about_useless_cast.
+ * rtti.c (build_dynamic_cast): Likewise.
+ * pt.c (tsubst_copy_and_build, case CAST_EXPR): Increment/decrement
+ c_inhibit_evaluation_warnings before/after the build_* calls.
+
+2012-03-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/52582
+ * method.c (implicitly_declare_fn): Set DECL_EXTERNAL.
+
+2012-03-15 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c++/44783
+ * error.c (print_instantiation_partial_context): Use
+ template_backtrace_limit.
+
+2012-03-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * Make-lang.in (doc/g++.1): Remove IRIX 6.5 reference.
+
+2012-03-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/52521
+ * parser.c (lookup_literal_operator): Return fn only if
+ processed all arguments from args vector and argtypes is
+ void_list_node.
+
+2012-01-30 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51641
+ * cp-tree.h (template_type_parameter_p): Declare new function.
+ (parameter_of_template_p): Remove.
+ * pt.c (template_type_parameter_p): Define new function.
+ (parameter_of_template_p): Remove.
+ * name-lookup.c (binding_to_template_parms_of_scope_p): Don't rely
+ on parameter_of_template_p anymore. Compare the level of the
+ template parameter to the depth of the template.
+
+2011-12-15 Dodji Seketeli <dodji@redhat.com>
+
+ * call.c (standard_conversion, build_integral_nontype_arg_conv)
+ (build_new_op_1, convert_like_real, is_subseq)
+ (maybe_handle_implicit_object, maybe_handle_ref_bind, compare_ics)
+ (joust): Use next_conversion instead of accessing fields of struct
+ conversion directly.
+
+2012-03-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52299
+ * pt.c (tsubst_copy_and_build, case COND_EXPR): Avoid bogus
+ division by zero warnings.
+
+2012-03-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * typeck.c (build_array_ref, cp_build_addr_expr_1, convert_ptrmem,
+ build_ptrmemfunc): Consistently forward the tsubst_flags_t
+ parameter.
+ * call.c (resolve_args): Likewise.
+
+2012-03-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/52521
+ * mangle.c (write_literal_operator_name): The length comes after the
+ operator prefix.
+
+2012-03-05 Jakub Jelinek <jakub@redhat.com>
+
+ * pt.c (local_specializations): Change from htab_t into
+ struct pointer_map_t *.
+ (retrieve_local_specializations, register_local_specialization,
+ tsubst_pack_expansion, instantiate_decl): Adjust users.
+ (eq_local_specializations, hash_local_specialization): Remove.
+
+2012-03-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/51930
+ * decl2.c (determine_visibility): Correct calculation of class
+ args depth.
+ * decl.c (check_tag_decl): Adjust warning.
+
+ * method.c (synthesized_method_walk): Cleanups don't affect the EH
+ spec either.
+
+2012-03-03 Jason Merrill <jason@redhat.com>
+
+ * init.c (perform_member_init): Cope with uninstantiated NSDMI.
+
+ Core 1270
+ * call.c (build_aggr_conv): Call reshape_init.
+ (convert_like_real): Likewise.
+ * typeck2.c (process_init_constructor): Clear TREE_CONSTANT if
+ not all constant.
+
+ * mangle.c (write_nested_name): Use decl_mangling_context.
+ (write_prefix, write_template_prefix): Likewise.
+
+ PR c++/36797
+ * mangle.c (write_expression): Improve diagnostic for TRAIT_EXPR.
+
+ * class.c (add_method): Always build an OVERLOAD for using-decls.
+ * search.c (lookup_member): Handle getting an OVERLOAD for a
+ single function.
+
+2012-03-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51989
+ * typeck2.c (build_x_arrow): Take a tsubst_flags_t argument and
+ propagate it.
+ * cp-tree.h (build_x_arrow): Adjust prototype.
+ * pt.c (tsubst_copy_and_build): Adjust call.
+ * parser.c (cp_parser_postfix_dot_deref_expression): Likewise.
+
+2012-03-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * name-lookup.c (binding_to_template_parms_of_scope_p): Clean up.
+
+2012-02-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/51930
+ * decl.c (check_tag_decl): Move warning for misplaced attributes here.
+ (shadow_tag): From here.
+ * parser.c (cp_parser_explicit_instantiation): Don't warn here.
+
+2012-02-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/52312
+ * typeck.c (check_literal_operator_args): Initialize *long_double_p
+ and *long_long_unsigned_p even if processing_template_decl.
+
+2012-02-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/52248
+ * decl.c (define_label): Use timevar_cond_start/stop.
+
+2012-02-16 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/52126
+ * decl.c (xref_basetypes): call dependent_scope_p instead of
+ dependent_type_p.
+
+2012-02-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/51415
+ * error.c (dump_expr): Handle lambda closures specifically.
+
+2012-02-14 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_explicit_instantiation): Give a warning
+ for ignored attributes on explicit class instantiation.
+
+2012-02-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/52247
+ * pt.c (tsubst_copy_asm_operands): For LABEL_DECL values call
+ lookup_label on label's name and set TREE_USED.
+
+2012-02-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/39055
+ * decl.c (local_variable_p_walkfn): Don't check DECL_ARTIFICIAL.
+
+2012-02-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/52181
+ * decl.c (duplicate_decls): If olddecl has bigger DECL_ALIGN than
+ newdecl, copy DECL_ALIGN to newdecl and or DECL_USER_ALIGN bits.
+
+2012-02-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/51675
+ * semantics.c (cx_check_missing_mem_inits): Handle unions.
+ Fix constexpr default constructor logic.
+
+ PR c++/52035
+ * pt.c (tsubst): Strip uninstantiated typedef.
+
+2012-02-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/52088
+ * cvt.c (build_expr_type_conversion): Check for template conversion.
+
+2012-01-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/52043
+ * cp-tree.h (PACK_EXPANSION_LOCAL_P): New.
+ * pt.c (make_pack_expansion, tsubst_initializer_list): Set it.
+ (tsubst_pack_expansion): Check it.
+
+2012-01-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51327
+ * class.c (explain_non_literal_class): Correctly handle implicitly
+ deleted constructors.
+
+2012-01-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/51852
+ * pt.c (tsubst_pack_expansion): Delete and restore
+ local_specialization whenever need_local_specialization, not just
+ when saved_local_specializations is non-NULL.
+
+2012-01-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51370
+ * error.c (dump_decl, [TEMPLATE_ID_EXPR]): Handle error_mark_node
+ as TREE_OPERAND (t, 1).
+
+2012-01-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/51917
+ * decl.c (xref_basetypes): Check VEC_length instead of VEC_space.
+
+ PR c++/51973
+ * tree.c (called_fns_equal): Check template args.
+ (cp_tree_equal): Call it.
+
+2012-01-24 Aldy Hernandez <aldyh@redhat.com>
+ Patrick Marlier <patrick.marlier@gmail.com>
+
+ PR c++/51928
+ * class.c (set_method_tm_attributes): Use TARGET_THUNK instead of
+ thunk for set_one_vmethod_tm_attributes.
+
+2012-01-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51223
+ * call.c (build_over_call): Check for error_mark_node as
+ TREE_VALUE when default arguments are processed.
+
+2012-01-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/51930
+ * decl2.c (determine_visibility): Check for visibility attribute
+ on template specialization.
+
+2012-01-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51398
+ * pt.c (parameter_of_template_p): Skip error_mark_node parameters.
+
+2012-01-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/51925
+ * class.c (add_method): Set OVL_USED for using-decls.
+ * tree.c (ovl_scope): New.
+ * cp-tree.h: Declare it.
+ * parser.c (cp_parser_template_name): Use it.
+ * semantics.c (baselink_for_fns): Likewise.
+ * name-lookup.c (set_inherited_value_binding_p): Likewise.
+
+2012-01-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51402
+ * pt.c (lookup_template_class_1): Check context returned by
+ tsubst for error_mark_node.
+
+2012-01-19 Kai Tietz <ktietz@redhat.com>
+
+ PR c++/51344
+ * decl2.c (save_template_attributes): Use merge_attributes
+ instead of chaining up via TREE_CHAIN.
+
+2012-01-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/51889
+ * class.c (finish_struct): Call add_method here for function usings.
+ * semantics.c (finish_member_declaration): Not here.
+
+2012-01-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51225
+ * typeck2.c (store_init_value): Within a template guard
+ cxx_constant_value with require_potential_constant_expression.
+ * pt.c (convert_nontype_argument): Likewise.
+
+2012-01-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/51854
+ * mangle.c (write_template_arg_literal): Handle complex.
+
+2012-01-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/51827
+ * mangle.c (mangle_decl): Don't mangle uninstantiated templates.
+
+ PR c++/51868
+ * typeck.c (build_static_cast_1): Handle bit-fields properly.
+
+2012-01-13 Ian Lance Taylor <iant@google.com>
+
+ PR c++/50012
+ * typeck.c (enum_cast_to_int): New static function.
+ (cp_build_binary_op): When handling warn_sign_compare, don't test
+ for TREE_NO_WARNING. Do call enum_cast_to_int.
+ * call.c (avoid_sign_compare_warnings): Remove static function.
+ (build_new_op_1): Don't call avoid_sign_compare_warnings.
+
+2012-01-13 Steven Bosscher <steven@gcc.gnu.org>
+
+ * decl2.c: Do not include tree-mudflap.h
+ * semantics.c: Likewise.
+
+2012-01-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/20681
+ * semantics.c (finish_break_stmt): Avoid adding an unreachable
+ BREAK_STMT.
+
+ PR c++/51813
+ * decl2.c (constrain_visibility): Clear DECL_VISIBILITY_SPECIFIED
+ when reducing the visibility.
+
+ PR c++/51620
+ * class.c (build_vtbl_initializer): Use __cxa_deleted_virtual.
+
+2012-01-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/51714
+ * pt.c (value_dependent_expression_p): Treat STMT_EXPR as
+ value-dependent.
+
+2012-01-13 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51633
+ * semantics.c (cp_parser_ctor_initializer_opt_and_function_body):
+ Set the pointer to the last block of the constructor to the
+ current statement.
+ (build_constexpr_constructor_member_initializers): Get
+ build_data_member_initialization a chance to deal with more
+ statements before we choke.
+
+2012-01-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/48051
+ * mangle.c (write_expression): Mangle BASELINK scope if
+ BASELINK_QUALIFIED_P.
+ * search.c (adjust_result_of_qualified_name_lookup): Set
+ BASELINK_QUALIFIED_P.
+ * tree.c (cp_tree_equal) [BASELINK]: Compare BASELINK_QUALIFIED_P.
+ * parser.c (cp_parser_postfix_dot_deref_expression): Don't call
+ adjust_result_of_qualified_name_lookup for non-qualified names.
+
+ PR c++/51403
+ * pt.c (unify): Handle error_mark_node.
+
+2012-01-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/51565
+ * call.c (standard_conversion): For ptrmemfuncs, compare the
+ static_fn_types.
+
+ PR c++/51818
+ * mangle.c (find_substitution): A type is only a substitution
+ match if we're looking for a type.
+ (write_nested_name): Use decl_mangling_context.
+
+ * decl.c (decls_match): Assert that the arguments are decls.
+
+ PR c++/51613
+ * pt.c (resolve_overloaded_unification): Compare types with
+ same_type_p, not decls_match.
+
+2012-01-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/51614
+ * class.c (build_base_path): Diagnose ambiguous base.
+
+ PR c++/51433
+ * semantics.c (cxx_eval_call_expression): Always retry previously
+ non-constant expressions.
+
+2012-01-06 Jason Merrill <jason@redhat.com>
+
+ DR 686
+ PR c++/47450
+ * parser.c (cp_parser_new_expression): Set
+ type_definition_forbidden_message.
+
+ PR c++/6057
+ PR c++/48051
+ PR c++/50855
+ PR c++/51322
+ * mangle.c (write_expression): Support NEW_EXPR, DELETE_EXPR,
+ THROW_EXPR, CONSTRUCTOR, OVERLOAD. Fix PREINCREMENT_EXPR and
+ PREDECREMENT_EXPR.
+ (write_template_arg): Fix mangling of class-scope functions and
+ argument packs.
+ (mangle_decl): Update suggested -fabi-version argument.
+ * operators.def: Add DOTSTAR_EXPR, REINTERPRET_CAST_EXPR,
+ DYNAMIC_CAST_EXPR; correct CONST_CAST_EXPR, STATIC_CAST_EXPR.
+ * tree.c (dependent_name): No longer static.
+ * cp-tree.h: Declare it.
+ * pt.c (unify): Defer handling of unconverted functions.
+
+ * mangle.c (mangle_decl): Don't generate mangling aliases
+ for maybe-in-charge [cd]tors.
+
+ * error.c (dump_expr): Print type of CONSTRUCTOR.
+
+2012-01-05 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51541
+ * parser.c (cp_parser_alias_declaration): Get out early upon
+ errors in the identifier or the attributes.
+
+2012-01-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51064
+ * pt.c (tsubst_copy_and_build): Maybe set TREE_NO_WARNING on
+ the tree returned by build_x_binary_op.
+
+2012-01-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51738
+ * parser.c (cp_parser_postfix_open_square_expression): Handle
+ postfix-expression [ braced-init-list ].
+
+2012-01-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/29273
+ * rtti.c (build_dynamic_cast_1): In case of T a pointer type,
+ call decay_conversion on v.
+
+2012-01-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/15867
+ * decl.c (duplicate_decls): With -Wredundant-decls don't warn for
+ declaration followed by specialization.
+
+2012-01-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/51669
+ * semantics.c (finish_omp_clauses): Call fold_build_cleanup_point_expr
+ on OMP_CLAUSE_{IF,FINAL,NUM_THREADS,SCHEDULE_CHUNK}_EXPR.
+
+2012-01-02 Jason Merrill <jason@redhat.com>
+
+ DR 1359
+ PR c++/51675
+ * method.c (walk_field_subobs): Don't check for uninitialized
+ fields in a union.
+ (synthesized_method_walk): Check here.
+
+ DR 325
+ PR c++/51666
+ * parser.c (cp_parser_cache_defarg): Split out...
+ (cp_parser_parameter_declaration): ...from here.
+ (cp_parser_save_nsdmi): Use it.
+ (cp_parser_cache_group): Remove CPP_COMMA support.
+
+2012-01-02 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51462
+ * semantics.c (cx_check_missing_mem_inits): Don't assert in case
+ of error.
+
+2012-01-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/20140
+ * typeck2.c (digest_init_r): Use copy_init when initializing
+ an array of chars.
+
+2012-01-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/16603
+ * decl.c (build_enumerator): Don't call perform_integral_promotions
+ on the value.
+
+2012-01-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51379
+ * typeck.c (build_reinterpret_cast_1): Implement resolution of
+ DR 799.
+
+2012-01-01 Fabien Chêne <fabien@gcc.gnu.org>
+
+ * parser.c (cp_parser_using_declaration): Add a warning about
+ deprecated access declarations when no errors were encountered
+ while parsing the access declaration. Save the first token in
+ order to emit the warning at the right place.
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog-2013 b/gcc-4.9/gcc/cp/ChangeLog-2013
new file mode 100644
index 000000000..146e67c58
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog-2013
@@ -0,0 +1,4295 @@
+2013-12-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/59271
+ * lambda.c (build_capture_proxy): Use build_cplus_array_type.
+
+ PR c++/59349
+ * parser.c (cp_parser_lambda_introducer): Handle empty init.
+
+2013-12-23 Stuart Hastings <stuart@apple.com>
+ Bill Maddox <maddox@google.com>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/41090
+ * optimize.c (can_alias_cdtor, populate_clone_array): Split out
+ from maybe_clone_body.
+ (maybe_thunk_body): New function.
+ (maybe_clone_body): Call it.
+ * mangle.c (write_mangled_name): Remove code to suppress
+ writing of mangled name for cloned constructor or destructor.
+ (write_special_name_constructor): Handle decloned constructor.
+ (write_special_name_destructor): Handle decloned destructor.
+ * method.c (trivial_fn_p): Handle decloning.
+ * semantics.c (expand_or_defer_fn_1): Clone after setting linkage.
+
+2013-12-23 Marek Polacek <polacek@redhat.com>
+
+ PR c++/59111
+ * search.c (lookup_conversions): Return NULL_TREE if !CLASS_TYPE_P.
+
+2013-12-20 Trevor saunders <tsaunders@mozilla.com>
+
+ * semantics.c (build_anon_member_initialization): Replace
+ stack_vec<T, N> with auto_vec<T, N>.
+
+2013-12-18 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * parser.c (cp_parser_cilk_simd_clause_name): Changed cilk_clause_name
+ to omp_clause_name.
+
+2013-12-17 Thomas Schwinge <thomas@codesourcery.com>
+
+ * parser.c (cp_parser_omp_parallel): Fix description.
+
+2013-12-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/58954
+ * pt.c (resolve_overloaded_unification): Use instantiate_template.
+
+2013-12-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/58627
+ * class.c (resolve_address_of_overloaded_function): Don't call ggc_free
+ on targs.
+
+2013-12-11 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * cp-tree.h (cilk_valid_spawn): New prototype.
+ (gimplify_cilk_spawn): Likewise.
+ (create_try_catch_expr): Likewise.
+ * decl.c (finish_function): Insert Cilk function-calls when a
+ _Cilk_spawn is used in a function.
+ * parser.c (cp_parser_postfix_expression): Added RID_CILK_SPAWN and
+ RID_CILK_SYNC cases.
+ * cp-cilkplus.c (set_cilk_except_flag): New function.
+ (set_cilk_except_data): Likewise.
+ (cilk_install_body_with_frame_cleanup): Likewise.
+ * except.c (create_try_catch_expr): Likewise.
+ * parser.h (IN_CILK_SPAWN): New #define.
+ * pt.c (tsubst_expr): Added CILK_SPAWN_STMT and CILK_SYNC_STMT cases.
+ * semantics.c (potential_constant_expression_1): Likewise.
+ * typeck.c (cp_build_compound_expr): Reject a spawned function in a
+ compound expression.
+ (check_return_expr): Reject a spawned function in a return expression.
+ * cp-gimplify.c (cp_gimplify_expr): Added a CILK_SPAWN_STMT and
+ CALL_EXPR case. Added handling of spawned function in MODIFY_EXPR
+ and INIT_EXPR.
+
+2013-12-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59435
+ * parser.c (cp_parser_cache_defarg): sizeof ... ( p ) can
+ occur in a default argument too.
+
+2013-12-06 Caroline Tice <cmtice@google.com>
+
+ Submitting patch from Stephen Checkoway, s@cs.jhu.edu
+ * vtable-class-hierarchy.c (init_functions): Make the libvtv
+ function decls externally visible.
+
+2013-12-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * decl2.c: Remove struct tags when referring to class varpool_node.
+
+2013-12-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/59044
+ PR c++/59052
+ * pt.c (most_specialized_class): Use the partially instantiated
+ template for deduction. Drop the TMPL parameter.
+
+2013-12-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (duplicate_decls): Replace pairs of errors and permerrors
+ with error + inform (permerror + inform, respectively).
+
+2013-12-04 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/52023
+ * typeck.c (cxx_sizeof_or_alignof_type): Update call to
+ c_sizeof_or_alignof_type.
+
+2013-12-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/59268
+ * pt.c (tsubst_copy_and_build): Handle POINTER_PLUS_EXPR.
+
+2013-11-29 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/59331
+ * decl.c (compute_array_index_type): Don't build COMPOUND_EXPR for
+ instrumentation.
+
+2013-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/59297
+ * semantics.c (finish_omp_atomic): Call finish_expr_stmt
+ rather than add_stmt.
+
+2013-11-28 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * g++spec.c (TIMELIB): Define.
+ (WITHLIBC, SKIPOPT): Adjust values.
+ (lang_specific_driver): Add TIME_LIBRARY if not passed explicitly.
+
+2013-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/59310
+ * parser.c (cp_parser_omp_target): Call keep_next_level only
+ if flag_openmp.
+
+2013-11-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58647
+ * semantics.c (cxx_eval_constant_expression, [COMPONENT_REF]):
+ Handle function COMPONENT_REFs.
+
+2013-11-27 Aldy Hernandez <aldyh@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (finish_omp_clauses): For #pragma omp declare simd
+ linear clause step call maybe_constant_value.
+
+2013-11-27 Tom de Vries <tom@codesourcery.com>
+ Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/59032
+ * typeck.c (cp_build_unary_op): Allow vector increment and decrement.
+
+2013-11-27 Tom de Vries <tom@codesourcery.com>
+ Marc Glisse <marc.glisse@inria.fr>
+
+ PR middle-end/59037
+ * semantics.c (cxx_fold_indirect_ref): Don't create out-of-bounds
+ BIT_FIELD_REF.
+
+2013-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/58874
+ * parser.c (cp_parser_late_parsing_for_member): For OpenMP UDRs
+ pass 2 instead of 0 to finish_function.
+
+2013-11-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58700
+ * decl.c (grokdeclarator): Don't try to pass declarator->id_loc
+ to build_lang_decl_loc when declarator is null.
+
+2013-11-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cvt.c (cp_convert_and_check): Avoid calling cp_convert
+ unnecessarily.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54485
+ * decl.c (duplicate_decls): Enforce 8.3.6/6 about default arguments
+ for member functions of class templates.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58607
+ * semantics.c (check_constexpr_ctor_body): Check for BIND_EXPR_VARS.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58810
+ * decl.c (grokdeclarator): Don't handle qualified free functions here,
+ leave the diagnostic to grokfndecl.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59080
+ * pt.c (unify): Don't call unify_array_domain with a NULL_TREE
+ third argument.
+
+ PR c++/59096
+ * pt.c (apply_late_template_attributes): Check that TREE_VALUE
+ isn't NULL_TREE in the attribute_takes_identifier_p case.
+
+2013-11-25 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/59112
+ PR c++/59113
+ * parser.c (cp_parser_parameter_declaration_clause): Disallow implicit
+ function templates in local functions unless defining a lambda.
+
+2013-11-23 Easwaran Raman <eraman@google.com>
+
+ PR c++/59031
+ * call.c (build_new_method_call_1): Comnpare function context
+ with BASELINK_BINFO type rather than instance type before
+ marking the call with LOOKUP_NONVIRTUAL.
+
+2013-11-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/58868
+ * init.c (build_aggr_init): Don't clobber the type of init
+ if we got an INIT_EXPR back from build_vec_init.
+ (build_vec_init): Do digest_init on trivial initialization.
+
+2013-11-23 Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+ PR c++/58525
+ * call.c (build_operator_new_call): Add flag_exceptions check.
+ * decl.c (compute_array_index_type): Ditto.
+ * init.c (build_new_1): Ditto.
+ (build_vec_init): Ditto.
+
+2013-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c: Include target.h and c-family/c-ubsan.h.
+ (cp_ubsan_maybe_instrument_return): New function.
+ (cp_genericize): Call it if -fsanitize=return.
+
+ * decl2.c: Include asan.h.
+ (one_static_initialization_or_destruction): If -fsanitize=address,
+ init is non-NULL and guard is NULL, set
+ vnode->dynamically_initialized.
+ (do_static_initialization_or_destruction): Call
+ __asan_{before,after}_dynamic_init around the static initialization.
+
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * class.c: Add required include files from gimple.h.
+ * cp-gimplify.c: Likewise
+ * decl2.c: Likewise
+ * init.c: Likewise
+ * optimize.c: Likewise
+ * pt.c: Likewise
+ * semantics.c: Likewise
+ * tree.c: Likewise
+ * typeck.c: Likewise
+ * vtable-class-hierarchy.c: Likewise
+
+2013-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ * call.c (build_integral_nontype_arg_conv): Remove use of
+ EXPR_LOC_OR_HERE macro.
+ (convert_like_real): Likewise.
+ (convert_arg_to_ellipsis): Likewise.
+ (build_cxx_call): Likewise.
+ (perform_implicit_conversion_flags): Likewise.
+ (initialize_reference): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_reference): Likewise.
+ (ocp_convert): Likewise.
+ (convert_to_void): Likewise.
+ * decl.c (pop_label): Update comment.
+ (pop_switch): Remove use of EXPR_LOC_OR_HERE macro.
+ (check_tag_decl): Remove use of in_system_header macro.
+ (make_rtl_for_nonlocal_decl): Remove use of input_filename
+ macro.
+ (compute_array_index_type): Remove use of in_system_header
+ macro.
+ (grokdeclarator): Likewise.
+ * error.c (dump_global_iord): Remove use of input_filename
+ macro.
+ (location_of): Remove use of EXPR_LOC_OR_HERE macro.
+ (maybe_warn_cpp0x): Remove use of in_system_header macro.
+ * init.c (build_new_1): Remove use of EXPR_LOC_OR_HERE macro.
+ * lex.c (handle_pragma_interface): Remove use of input_filename
+ macro.
+ (handle_pragma_implementation): Likewise.
+ (cxx_make_type): Likewise.
+ (in_main_input_context): Likewise.
+ * name-lookup.c (push_binding_level): Remove use of
+ input_line macro.
+ (leave_scope): Likewise.
+ (resume_scope): Likewise.
+ * parser.c (cp_parser_unqualified_id): Remove use of
+ in_system_header macro.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_declaration_seq_opt): Likewise.
+ (cp_parser_enumerator_list): Likewise.
+ (cp_parser_parameter_declaration_clause): Likewise.
+ (cp_parser_exception_specification_opt): Likewise.
+ * pt.c (unify_arg_conversion): Remove use of EXPR_LOC_OR_HERE
+ macro.
+ (convert_nontype_argument): Likewise.
+ (push_tinst_level): Remove use of in_system_header macro.
+ (tsubst_copy_and_build): Remove use of EXPR_LOC_OR_HERE
+ macros.
+ (do_decl_instantiation): Remove use of in_system_header macro.
+ (do_type_instantiation): Likewise.
+ * semantics.c (finish_call_expr): Remove use of EXPR_LOC_OR_HERE
+ macro.
+ (begin_class_definition): Remove use of input_filename macro.
+ (cxx_eval_call_expression): Remove use of EXPR_LOC_OR_HERE
+ macro.
+ (cxx_eval_constant_expression): Likewise.
+ (potential_constant_expression_1): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+ (rationalize_conditional_expr): Likewise.
+ (build_x_compound_expr_from_list): Likewise.
+ (convert_for_assignment): Likewise.
+ * typeck2.c (check_narrowing): Likewise.
+
+2013-11-22 Trevor Saunders <tsaunders@mozilla.com>
+
+ * parser.c, semantics.c: Change some local variables from vec to
+ auto_vec or stack_vec.
+
+2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * decl.c (reshape_init_array_1): Use tree_to_uhwi rather than
+ tree_low_cst.
+ (grokdeclarator): Update comment to refer to tree_to_[su]hwi rather
+ than tree_low_cst.
+
+2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * call.c, class.c, decl.c, error.c: Replace tree_low_cst (..., 1) with
+ tree_to_uhwi throughout.
+
+2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * class.c, dump.c, error.c, init.c, method.c, parser.c, semantics.c:
+ Replace tree_low_cst (..., 0) with tree_to_shwi throughout.
+
+2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * decl.c: Replace host_integerp (..., 1) with tree_fits_uhwi_p
+ throughout.
+
+2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * error.c, init.c, parser.c, semantics.c: Replace
+ host_integerp (..., 0) with tree_fits_shwi_p throughout.
+
+2013-11-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59123
+ * decl.c (validate_constexpr_redeclaration): Redeclarations of
+ variables can differ in constexpr.
+
+2013-11-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/29143
+ * semantics.c (finish_call_expr): Ensure that for OVERLOADs too
+ '(&f)(...)' is the same as '(f)(...)', per 13.3.1.1.
+
+2013-11-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * Make-lang.in (CXX_AND_OBJCXX_OBJS): Depend on cp/cp-cilkplus.o.
+ * cp-cilkplus.c: New file.
+ * cp-tree.h (cpp_validate_cilk_plus_loop): Protoize.
+ * parser.c (cp_parser_cilk_simd): New.
+ (cp_debug_parser): Add case for IN_CILK_SIMD_FOR.
+ (cp_parser_jump_statement): Same.
+ (cp_parser_omp_for_cond): Add new argument.
+ Add case for NE_EXPR.
+ (cp_parser_omp_for_loop): Pass new argument to
+ cp_parser_omp_for_cond.
+ Handle CILK_SIMD nodes.
+ Abstract initilization code to..
+ (cp_parser_omp_for_loop_init): ...here.
+ (cp_parser_pragma): Add case for PRAGMA_CILK_SIMD.
+ (cp_parser_cilk_simd_vectorlength): New.
+ (cp_parser_cilk_simd_linear): New.
+ (cp_parser_cilk_simd_clause_name): New.
+ (cp_parser_cilk_simd_all_clauses): New.
+ (cp_parser_cilk_simd): New.
+ * parser.h (IN_CILK_SIMD_FOR): New macro.
+ * pt.c (tsubst_expr): Add case for CILK_SIMD.
+ * typeck2.c (cxx_readonly_error): Pass location argument to
+ readonly_error.
+
+2013-11-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57887
+ * parser.c (cp_parser_late_parsing_nsdmi): Call
+ maybe_begin_member_template_processing.
+ * pt.c (maybe_begin_member_template_processing): Handle NSDMIs.
+ (inline_needs_template_parms): Adjust.
+
+2013-11-14 Andrew MacLeod <amacleod@redhat.com>
+
+ * class.c: Include only gimplify.h and gimple.h as needed.
+ * cp-gimplify.c: Likewise.
+ * error.c: Likewise.
+ * init.c: Likewise.
+ * optimize.c: Likewise.
+ * pt.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * vtable-class-hierarchy.c: Likewise.
+
+2013-11-14 Diego Novillo <dnovillo@google.com>
+
+ * call.c: Include stor-layout.h.
+ Include trans-mem.h.
+ Include stringpool.h.
+ * class.c: Include stringpool.h.
+ Include stor-layout.h.
+ Include attribs.h.
+ * cp-gimplify.c: Include stor-layout.h.
+ * cvt.c: Include stor-layout.h.
+ * decl.c: Include stringpool.h.
+ Include stor-layout.h.
+ Include varasm.h.
+ Include attribs.h.
+ Include calls.h.
+ * decl2.c: Include stringpool.h.
+ Include varasm.h.
+ Include attribs.h.
+ Include stor-layout.h.
+ Include calls.h.
+ * error.c: Include stringpool.h.
+ * except.c: Include stringpool.h.
+ Include trans-mem.h.
+ Include attribs.h.
+ * init.c: Include stringpool.h.
+ Include varasm.h.
+ * lambda.c: Include stringpool.h.
+ * lex.c: Include stringpool.h.
+ * mangle.c: Include stor-layout.h.
+ Include stringpool.h.
+ * method.c: Include stringpool.h.
+ Include varasm.h.
+ * name-lookup.c: Include stringpool.h.
+ Include print-tree.h.
+ Include attribs.h.
+ * optimize.c: Include stringpool.h.
+ * parser.c: Include print-tree.h.
+ Include stringpool.h.
+ Include attribs.h.
+ Include trans-mem.h.
+ * pt.c: Include stringpool.h.
+ Include varasm.h.
+ Include attribs.h.
+ Include stor-layout.h.
+ * ptree.c: Include print-tree.h.
+ * repo.c: Include stringpool.h.
+ * rtti.c: Include stringpool.h.
+ Include stor-layout.h.
+ * semantics.c: Include stmt.h.
+ Include varasm.h.
+ Include stor-layout.h.
+ Include stringpool.h.
+ * tree.c: Include stor-layout.h.
+ Include print-tree.h.
+ Include tree-iterator.h.
+ * typeck.c: Include stor-layout.h.
+ Include varasm.h.
+ * typeck2.c: Include stor-layout.h.
+ Include varasm.h.
+ * vtable-class-hierarchy.c: Include stringpool.h.
+ Include stor-layout.h.
+
+2013-11-12 Andrew MacLeod <amacleod@redhat.com>
+
+ * class.c: Include gimplify.h.
+ * cp-gimplify.c: Likewise.
+ * error.c: Likewise.
+ * init.c: Likewise.
+ * optimize.c: Likewise.
+ * pt.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * vtable-class-hierarchy.c: Likewise.
+ * decl2.c: Don't include gimple.h.
+ * except.c: Likewise.
+ * method.c: Include pointer-set.h instead of gimple.h.
+
+2013-11-12 Adam Butcher <adam@jessamine.co.uk>
+
+ * pt.c (convert_generic_types_to_packs): New function to transform
+ a range of implicitly introduced non-pack template parms to be parameter
+ packs.
+ * cp-tree.h (convert_generic_types_to_packs): Declare.
+ * parser.c (cp_parser_parameter_declaration_list): If a function
+ parameter pack contains generic types, convert them to packs prior to
+ grokdeclarator.
+
+2013-11-12 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/58534
+ PR c++/58536
+ PR c++/58548
+ PR c++/58549
+ PR c++/58637
+ * parser.h (struct cp_parser): New members implicit_template_parms,
+ implicit_template_scope and auto_is_implicit_function_template_parm_p.
+ * parser.c (add_implicit_template_parms): Refactor as ...
+ (synthesize_implicit_template_parm): ... this to append a new template
+ type parm to the current template parameter list (introducing a new list
+ if necessary). Removed push_deferring_access_checks.
+ (finish_fully_implicit_template): Removed pop_deferring_access_checks.
+ (cp_parser_new): Initialize new cp_parser members.
+ (cp_parser_parameter_declaration_clause): Consider auto as implicit
+ template parm when parsing a parameter declaration (unless parsing an
+ explicit specialization).
+ (cp_parser_parameter_declaration_list): Remove local
+ implicit_template_parms counter and reset cp_parser implicit template
+ state when complete.
+ (cp_parser_lambda_expression): Reset implicit template cp_parser members
+ whilst generating lambda class.
+ (cp_parser_function_definition_after_declarator): Reset implicit
+ template cp_parser members whilst parsing function definition.
+ (make_generic_type_name): Respell '<autoN>' as 'auto:N' which works
+ better with template diagnostics.
+ (cp_parser_simple_type_specifier): Synthesize implicit template parm on
+ parsing 'auto' if auto_is_implicit_function_template_parm_p and provide
+ diagnostics ...
+ * decl.c (grokdeclarator): ... that were previously done here.
+
+2013-11-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57734
+ * pt.c (lookup_template_class_1): Handle alias template declarations
+ of enumeration types.
+
+2013-11-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cvt.c (cp_convert_to_pointer): Call build_ptrmemfunc before
+ maybe_warn_zero_as_null_pointer_constant to avoid duplicate
+ -Wzero-as-null-pointer-constant diagnostics.
+
+ * typeck.c (build_ptrmemfunc): Use cp_build_c_cast.
+
+2013-11-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/11006
+ * init.c (build_new_1): Don't call build_java_class_ref on non-class
+ types.
+
+2013-11-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/58868
+ * decl.c (check_initializer): Don't use build_vec_init for arrays
+ of trivial type.
+
+2013-11-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58724
+ * name-lookup.c (handle_namespace_attrs): Use get_attribute_name.
+
+2013-11-05 Tobias Burnus <burnus@net-b.de>
+
+ * parser.c (cp_parser_omp_for, cp_parser_omp_parallel,
+ cp_parser_omp_distribute, cp_parser_omp_teams, cp_parser_omp_target,
+ cp_parser_omp_declare): Handle -fopenmp-simd.
+
+2013-11-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * decl2.c (cpp_check): Change type of first parameter and deal with
+ IS_TRIVIAL.
+
+2013-11-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/38313
+ * parser.c (cp_parser_constructor_declarator_p): Check that the
+ class-name matches current_class_type.
+
+2013-11-03 Marek Polacek <polacek@redhat.com>
+
+ * decl.c (cp_finish_decl): Move C++1y bounds checking...
+ (compute_array_index_type): ...here. Add VLA instrumentation.
+ Call stabilize_vla_size.
+ (grokdeclarator): Don't call stabilize_vla_size here.
+
+2013-11-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/29234
+ PR c++/56037
+ * parser.c (cp_parser_cast_expression): If we aren't looking at
+ a cast-expression don't call cp_parser_type_id.
+ (cp_parser_postfix_expression): Likewise for compound-literal.
+ (cp_parser_tokens_start_cast_expression): Adjust.
+
+2013-11-01 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/58708
+ * parser.c (make_string_pack): Discover non-const type and size
+ of character and build parm pack with correct type and chars.
+
+2013-11-01 Trevor Saunders <tsaunders@mozilla.com>
+
+ * semantics.c (build_anon_member_initialization): Convert fields to be
+ a stack_vec.
+
+2013-11-01 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/58834
+ * pt.c (type_dependent_expression_p): Handle null argument.
+
+2013-11-01 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (finish_omp_clauses) <case OMP_CLAUSE_UNIFORM>: Go to
+ check_dup_generic at the end, unless remove is true.
+ (finish_omp_clauses) <case OMP_CLAUSE_LINEAR>: Add break; after
+ remove = true;.
+
+2013-10-31 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (finish_omp_clauses): Diagnose aligned clause
+ with decl that is not pointer nor array nor reference to those.
+
+2013-10-31 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (cxx_eval_call_expression): Handle trivial
+ value-initialization.
+ * typeck2.c (store_init_value): Call maybe_constant_init after
+ cxx_constant_value.
+
+ * decl.c (cxx_maybe_build_cleanup): Always set LOOKUP_NONVIRTUAL.
+ * decl2.c (build_cleanup): Just call cxx_maybe_build_cleanup.
+
+ PR c++/58162
+ * parser.c (cp_parser_late_parse_one_default_arg): Set
+ TARGET_EXPR_DIRECT_INIT_P.
+
+ * class.c (type_build_ctor_call): Return early in C++98 mode.
+ (type_build_dtor_call): Likewise.
+
+2013-10-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58932
+ Revert:
+ 2013-10-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58466
+ * pt.c (most_specialized_class): Bump processing_template_decl for
+ get_class_bindings.
+
+2013-10-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58581
+ * call.c (build_over_call): Check return value of mark_used.
+
+2013-10-30 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (finish_compound_literal): Don't create a static variable
+ inside cp_unevaluated_operand.
+
+ * init.c (push_base_cleanups): Check ANON_AGGR_TYPE_P.
+
+2013-10-30 Tobias Burnus <burnus@net-b.de>
+
+ PR other/33426
+ * cp-tree.h (RANGE_FOR_IVDEP): Define.
+ (cp_convert_range_for, finish_while_stmt_cond, finish_do_stmt,
+ finish_for_cond): Take 'bool ivdep' parameter.
+ * cp-array-notation.c (create_an_loop): Update call.
+ * init.c (build_vec_init): Ditto.
+ * pt.c (tsubst_expr): Ditto.
+ * parser.c (cp_parser_iteration_statement, cp_parser_for,
+ cp_parser_range_for, cp_convert_range_for): Update calls.
+ (cp_parser_pragma): Accept GCC ivdep for 'while' and 'do'.
+ * semantics.c (finish_while_stmt_cond, finish_do_stmt,
+ finish_for_cond): Optionally build ivdep annotation.
+
+2013-10-30 Jason Merrill <jason@redhat.com>
+
+ * decl.c (cp_finish_decl): Never throw for VLA bound == 0.
+
+2013-10-29 David Malcolm <dmalcolm@redhat.com>
+
+ Patch autogenerated by refactor_symtab.py from
+ https://github.com/davidmalcolm/gcc-refactoring-scripts
+ revision 58bb219cc090b2f4516a9297d868c245495ee622
+
+ * call.c (mark_versions_used): Update for conversion of symtab types
+ to a true class hierarchy.
+ * decl2.c (cp_write_global_declarations): Likewise.
+ (clear_decl_external): Likewise.
+ (build_java_method_aliases): Likewise.
+ (collect_candidates_for_java_method_aliases): Likewise.
+ (mark_needed): Likewise.
+ (var_finalized_p): Likewise.
+ (maybe_make_one_only): Likewise.
+ (maybe_emit_vtables): Likewise.
+ * lambda.c (maybe_add_lambda_conv_op): Likewise.
+ * method.c (use_thunk): Likewise.
+ * optimize.c (maybe_clone_body): Likewise.
+ * tree.c (cp_fix_function_decl_p): Likewise.
+
+2013-10-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58888
+ * decl2.c (grokfield): Handle auto like NSDMI.
+
+2013-10-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58878
+ * pt.c (check_template_shadow): Don't skip declarations in inline
+ member templates.
+
+2013-10-25 Tobias Burnus <burnus@net-b.de>
+
+ PR other/33426
+ * parser.c (cp_parser_iteration_statement,
+ cp_parser_for, cp_parser_c_for, cp_parser_pragma): Handle
+ IVDEP pragma.
+
+2013-10-24 Marek Polacek <polacek@redhat.com>
+
+ PR c++/58705
+ * typeck2.c (check_narrowing): Don't check narrowing when the scalar
+ initializer is empty.
+
+2013-10-23 Jason Merrill <jason@redhat.com>
+
+ LWG 2165
+ * method.c (defaulted_late_check): Delete on eh-spec mismatch.
+ (maybe_explain_implicit_delete): Explain it.
+
+ * error.c (eh_spec_to_string): New.
+ (cp_printer): Use it for %X.
+
+ In C++11 a trivial [cd]tor might not be callable.
+ * class.c (user_provided_p): A function deleted on its declation
+ in the class is not user-provided.
+ (type_build_ctor_call): Also force a ctor call if we
+ might have a deleted or private trivial ctor.
+ (type_build_dtor_call): New.
+ (deduce_noexcept_on_destructors): Remove obsolete code.
+ * cp-tree.h: Declare type_build_dtor_call.
+ * decl.c (expand_static_init): Make sure trivial dtors are callable.
+ (cxx_maybe_build_cleanup): Likewise.
+ * except.c (build_throw): Likewise.
+ * init.c (build_value_init): Handle trivial but not callable ctors.
+ (perform_target_ctor): Make sure trivial dtor is callable.
+ (perform_member_init): Likewise.
+ (expand_cleanup_for_base): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_delete): Likewise.
+ (push_base_cleanups): Likewise.
+ (build_new_1): Avoid redundant error.
+ * method.c (synthesized_method_walk): Can't ever exit early in C++11.
+ Always process the subobject destructor.
+ * semantics.c (finish_compound_literal): Make sure trivial dtor is
+ callable.
+ * typeck2.c (split_nonconstant_init): Likewise.
+
+2013-10-23 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ Implement C++14 [[deprecated]] modulo [[gnu::deprecated]] bugs.
+ * parser.c (cp_parser_std_attribute): Interpret [[deprecated]]
+ as [[gnu::deprecated]].
+
+2013-10-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58816
+ * pt.c (apply_late_template_attributes): Use get_attribute_name,
+ not TREE_PURPOSE.
+
+2013-10-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58466
+ * pt.c (most_specialized_class): Bump processing_template_decl for
+ get_class_bindings.
+
+2013-10-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * parser.c (cp_parser_lookup_name): Tidy.
+
+2013-10-17 Andrew MacLeod <amacleod@redhat.com>
+
+ * parser.c: Include omp-low.h.
+ * semantics.c: Likewise.
+
+2013-10-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58596
+ * lambda.c (lambda_expr_this_capture): Handle NSDMIs in the
+ cp_unevaluated_operand case.
+
+2013-10-16 Jason Merrill <jason@redhat.com>
+
+ * pt.c (apply_late_template_attributes): Use
+ attribute_takes_identifier_p.
+
+ * error.c (dump_exception_spec): Print "noexcept" rather than
+ "noexcept (true)".
+
+ Core 1591
+ * pt.c (unify_array_domain): Split out from unify.
+ (unify): Use it for list deduction, too.
+
+ PR c++/57850
+ * decl2.c (dump_tu): Split out from...
+ (cp_write_global_declarations): ...here. Call it in PCH mode.
+
+2013-10-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * pt.c (tsubst): Fix typo in last commit.
+
+2013-10-16 Paulo Matos <pmatos@broadcom.com>
+
+ * error.c (code_to_string): Use new wrapper get_tree_code_name.
+ * cxx-pretty-print.c (pp_cxx_assignment_operator): Likewise.
+ * pt.c (tsubst): Likewise.
+ * semantics.c (cxx_eval_constant_expression,
+ potential_constant_expression_1): Likewise.
+ * mangle.c (MANGLE_TRACE_TREE, dump_substitution_candidates,
+ add_substitution, find_substitution): Likewise.
+
+2013-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58707
+ * parser.c (cp_parser_postfix_open_square_expression): Set
+ parser->greater_than_is_operator_p for the argument.
+
+2013-10-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58633
+ * parser.c (cp_parser_commit_to_topmost_tentative_parse): New.
+ (cp_parser_pseudo_destructor_name): Use it.
+
+2013-10-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/31671
+ * pt.c (convert_nontype_argument): Set expr_type to
+ TREE_TYPE (probe_type).
+
+2013-10-11 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (duplicate_decls): Error out for redeclaration of UDRs.
+ (declare_simd_adjust_this): New function.
+ (grokfndecl): If "omp declare simd" attribute is present,
+ call declare_simd_adjust_this if needed and
+ c_omp_declare_simd_clauses_to_numbers.
+ * cp-array-notation.c (expand_array_notation_exprs): Handle
+ OMP_TASKGROUP.
+ * cp-gimplify.c (cp_gimplify_expr): Handle OMP_SIMD and
+ OMP_DISTRIBUTE. Handle is_invisiref_parm decls in
+ OMP_CLAUSE_REDUCTION.
+ (cp_genericize_r): Handle OMP_SIMD and OMP_DISTRIBUTE like
+ OMP_FOR.
+ (cxx_omp_privatize_by_reference): Return true for
+ is_invisiref_parm decls.
+ (cxx_omp_finish_clause): Adjust cxx_omp_create_clause_info
+ caller.
+ * pt.c (apply_late_template_attributes): For "omp declare simd"
+ attribute call tsubst_omp_clauses,
+ c_omp_declare_simd_clauses_to_decls, finish_omp_clauses
+ and c_omp_declare_simd_clauses_to_numbers.
+ (instantiate_class_template_1): Call cp_check_omp_declare_reduction
+ for UDRs.
+ (tsubst_decl): Handle UDRs.
+ (tsubst_omp_clauses): Add declare_simd argument, if true don't
+ call finish_omp_clauses. Handle new OpenMP 4.0 clauses.
+ Handle non-NULL OMP_CLAUSE_REDUCTION_PLACEHOLDER on
+ OMP_CLAUSE_REDUCTION.
+ (tsubst_expr): For UDRs call pushdecl and
+ cp_check_omp_declare_reduction. Adjust tsubst_omp_clauses
+ callers. Handle OMP_SIMD, OMP_DISTRIBUTE, OMP_TEAMS,
+ OMP_TARGET_DATA, OMP_TARGET_UPDATE, OMP_TARGET, OMP_TASKGROUP.
+ Adjust finish_omp_atomic caller.
+ (tsubst_omp_udr): New function.
+ (instantiate_decl): For UDRs at block scope, don't call
+ start_preparsed_function/finish_function. Call tsubst_omp_udr.
+ * semantics.c (cxx_omp_create_clause_info): Add need_dtor argument,
+ use it instead of need_default_ctor || need_copy_ctor.
+ (struct cp_check_omp_declare_reduction_data): New type.
+ (handle_omp_array_sections_1, handle_omp_array_sections,
+ omp_reduction_id, omp_reduction_lookup,
+ cp_remove_omp_priv_cleanup_stmt, cp_check_omp_declare_reduction_r,
+ cp_check_omp_declare_reduction, clone_omp_udr,
+ find_omp_placeholder_r, finish_omp_reduction_clause): New functions.
+ (finish_omp_clauses): Handle new OpenMP 4.0 clauses and user defined
+ reductions.
+ (finish_omp_for): Add CODE argument, use it instead of hardcoded
+ OMP_FOR. Adjust c_finish_omp_for caller.
+ (finish_omp_atomic): Add seq_cst argument, adjust
+ c_finish_omp_atomic callers, handle seq_cst and new OpenMP 4.0
+ atomic variants.
+ (finish_omp_cancel, finish_omp_cancellation_point): New functions.
+ * decl2.c (mark_used): Force immediate instantiation of
+ DECL_OMP_DECLARE_REDUCTION_P decls.
+ (is_late_template_attribute): Return true for "omp declare simd"
+ attribute.
+ (cp_omp_mappable_type): New function.
+ (cplus_decl_attributes): Add implicit "omp declare target" attribute
+ if requested.
+ * parser.c (cp_debug_parser): Print
+ parser->colon_doesnt_start_class_def_p.
+ (cp_ensure_no_omp_declare_simd, cp_finalize_omp_declare_simd): New
+ functions.
+ (enum pragma_context): Add pragma_member and pragma_objc_icode.
+ (cp_parser_binary_expression): Handle no_toplevel_fold_p
+ even for binary operations other than comparison.
+ (cp_parser_linkage_specification): Call
+ cp_ensure_no_omp_declare_simd if needed.
+ (cp_parser_namespace_definition): Likewise.
+ (cp_parser_init_declarator): Call cp_finalize_omp_declare_simd.
+ (cp_parser_direct_declarator): Pass declarator to
+ cp_parser_late_return_type_opt.
+ (cp_parser_late_return_type_opt): Add declarator argument,
+ call cp_parser_late_parsing_omp_declare_simd for declare simd.
+ (cp_parser_class_specifier_1): Call cp_ensure_no_omp_declare_simd.
+ Parse UDRs before all other methods.
+ (cp_parser_member_specification_opt): Use pragma_member instead of
+ pragma_external.
+ (cp_parser_member_declaration): Call cp_finalize_omp_declare_simd.
+ (cp_parser_function_definition_from_specifiers_and_declarator,
+ cp_parser_save_member_function_body): Likewise.
+ (cp_parser_late_parsing_for_member): Handle UDRs specially.
+ (cp_parser_next_token_starts_class_definition_p): Don't allow
+ CPP_COLON if colon_doesnt_start_class_def_p flag is true.
+ (cp_parser_objc_interstitial_code): Use pragma_objc_icode
+ instead of pragma_external.
+ (cp_parser_omp_clause_name): Parse new OpenMP 4.0 clause names.
+ (cp_parser_omp_var_list_no_open): Parse array sections for
+ OMP_CLAUSE_{DEPEND,MAP,TO,FROM} clauses. Add COLON argument,
+ if non-NULL, allow parsing to end with a colon rather than close
+ paren.
+ (cp_parser_omp_var_list): Adjust cp_parser_omp_var_list_no_open
+ caller.
+ (cp_parser_omp_clause_reduction): Handle user defined reductions.
+ (cp_parser_omp_clause_branch, cp_parser_omp_clause_cancelkind,
+ cp_parser_omp_clause_num_teams, cp_parser_omp_clause_thread_limit,
+ cp_parser_omp_clause_aligned, cp_parser_omp_clause_linear,
+ cp_parser_omp_clause_safelen, cp_parser_omp_clause_simdlen,
+ cp_parser_omp_clause_depend, cp_parser_omp_clause_map,
+ cp_parser_omp_clause_device, cp_parser_omp_clause_dist_schedule,
+ cp_parser_omp_clause_proc_bind, cp_parser_omp_clause_to,
+ cp_parser_omp_clause_from, cp_parser_omp_clause_uniform): New
+ functions.
+ (cp_parser_omp_all_clauses): Add finish_p argument. Don't call
+ finish_omp_clauses if it is false. Handle new OpenMP 4.0 clauses.
+ (cp_parser_omp_atomic): Parse seq_cst clause, pass
+ true if it is present to finish_omp_atomic. Handle new OpenMP 4.0
+ atomic forms.
+ (cp_parser_omp_for_loop): Add CODE argument, pass it through
+ to finish_omp_for. Change last argument to cclauses,
+ and adjust uses to grab parallel clauses from the array of all
+ the split clauses.
+ (cp_omp_split_clauses): New function.
+ (cp_parser_omp_simd): New function.
+ (cp_parser_omp_for): Add p_name, mask and cclauses arguments.
+ Allow the function to be called also when parsing combined constructs,
+ and call c_parser_omp_simd when parsing for simd.
+ (cp_parser_omp_sections_scope): If section-sequence doesn't start with
+ #pragma omp section, require exactly one structured-block instead of
+ sequence of statements.
+ (cp_parser_omp_sections): Add p_name, mask and cclauses arguments.
+ Allow the function to be called also when parsing combined constructs.
+ (cp_parser_omp_parallel): Add p_name, mask and cclauses arguments.
+ Allow the function to be called also when parsing combined
+ constructs.
+ (cp_parser_omp_taskgroup, cp_parser_omp_cancel,
+ cp_parser_omp_cancellation_point, cp_parser_omp_distribute,
+ cp_parser_omp_teams, cp_parser_omp_target_data,
+ cp_parser_omp_target_update, cp_parser_omp_target,
+ cp_parser_omp_declare_simd, cp_parser_late_parsing_omp_declare_simd,
+ cp_parser_omp_declare_target, cp_parser_omp_end_declare_target,
+ cp_parser_omp_declare_reduction_exprs, cp_parser_omp_declare_reduction,
+ cp_parser_omp_declare): New functions.
+ (cp_parser_omp_construct): Add p_name and mask vars. Handle
+ PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_SIMD, PRAGMA_OMP_TASKGROUP,
+ PRAGMA_OMP_TEAMS. Adjust cp_parser_omp_for, cp_parser_omp_parallel
+ and cp_parser_omp_sections callers.
+ (cp_parser_pragma): Handle PRAGMA_OMP_CANCEL,
+ PRAGMA_OMP_CANCELLATION_POINT, PRAGMA_OMP_DECLARE_REDUCTION,
+ PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_SIMD, PRAGMA_OMP_TASKGROUP,
+ PRAGMA_OMP_TEAMS, PRAGMA_OMP_TARGET, PRAGMA_OMP_END_DECLARE_TARGET.
+ Handle pragma_member and pragma_objc_icode like pragma_external.
+ (OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK,
+ OMP_SINGLE_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1.
+ (OMP_PARALLEL_CLAUSE_MASK): Likewise. Add OMP_CLAUSE_PROC_BIND.
+ (OMP_TASK_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1. Add
+ OMP_CLAUSE_DEPEND.
+ (OMP_SIMD_CLAUSE_MASK, OMP_CANCEL_CLAUSE_MASK,
+ OMP_CANCELLATION_POINT_CLAUSE_MASK, OMP_DISTRIBUTE_CLAUSE_MASK,
+ OMP_TEAMS_CLAUSE_MASK, OMP_TARGET_DATA_CLAUSE_MASK,
+ OMP_TARGET_UPDATE_CLAUSE_MASK, OMP_TARGET_CLAUSE_MASK,
+ OMP_DECLARE_SIMD_CLAUSE_MASK): Define.
+ * parser.h (struct cp_omp_declare_simd_data): New type.
+ (struct cp_parser): Add colon_doesnt_start_class_def_p and
+ omp_declare_simd fields.
+ * cp-objcp-common.h (LANG_HOOKS_OMP_MAPPABLE_TYPE): Define.
+ * cp-tree.h (struct lang_decl_fn): Add omp_declare_reduction_p
+ bit.
+ (DECL_OMP_DECLARE_REDUCTION_P): Define.
+ (OMP_FOR_GIMPLIFYING_P): Use OMP_LOOP_CHECK macro.
+ (struct saved_scope): Add omp_declare_target_attribute field.
+ (cp_omp_mappable_type, omp_reduction_id,
+ cp_remove_omp_priv_cleanup_stmt, cp_check_omp_declare_reduction,
+ finish_omp_cancel, finish_omp_cancellation_point): New prototypes.
+ (finish_omp_for): Add CODE argument.
+ (finish_omp_atomic): Add seq_cst argument.
+ (cxx_omp_create_clause_info): Add need_dtor argument.
+
+2013-10-09 Marek Polacek <polacek@redhat.com>
+
+ PR c++/58635
+ * semantics.c (finish_return_stmt): Return error_mark_node
+ when error_operand_p of the expr is true.
+ (build_transaction_expr): Check for EXPR_P before setting the
+ expr location.
+
+2013-10-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58568
+ * lambda.c (begin_lambda_type): Check return value of xref_tag
+ for error_mark_node; tidy.
+ * decl.c (grokdeclarator): Tweak error message.
+
+2013-10-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58665
+ Revert:
+ 2013-10-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58448
+ * pt.c (tsubst): Use error_operand_p on parameter t.
+
+2013-10-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58126
+ * class.c (check_bases): Propagate CLASSTYPE_READONLY_FIELDS_NEED_INIT
+ and CLASSTYPE_REF_FIELDS_NEED_INIT from bases to derived.
+ * init.c (diagnose_uninitialized_cst_or_ref_member_1): Extend error
+ messages about uninitialized const and references members to mention
+ the base class.
+
+2013-10-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56060
+ * pt.c (type_dependent_expression_p): Handle EXPR_PACK_EXPANSION.
+
+2013-10-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58560
+ * typeck2.c (build_functional_cast): Use error_operand_p on exp.
+
+2013-10-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58503
+ * parser.c (cp_parser_perform_range_for_lookup): If eventually
+ either *begin or *end is type-dependent, return NULL_TREE.
+ (do_range_for_auto_deduction): If cp_parser_perform_range_for_lookup
+ returns NULL_TREE, don't actually do_auto_deduction.
+
+2013-10-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58448
+ * pt.c (tsubst): Use error_operand_p on parameter t.
+
+2013-10-04 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/19476
+ * decl.c (cxx_init_decl_processing): Set operator_new_flag.
+
+2013-10-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58584
+ * decl2.c (save_template_attributes): Handle error_mark_node as
+ *attr_p argument.
+ (cp_check_const_attributes): Likewise for attributes.
+ * parser.c (cp_parser_std_attribute_spec): When alignas_expr is an
+ error_mark_node call cp_parser_skip_to_end_of_statement.
+
+2013-10-03 Easwaran Raman <eraman@google.com>
+
+ PR c++/33911
+ * parser.c (cp_parser_init_declarator): Do not drop attributes
+ of template member functions.
+
+2013-10-03 Marek Polacek <polacek@redhat.com>
+
+ PR c++/58510
+ * init.c (sort_mem_initializers): Splice when giving an error.
+
+2013-10-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58535
+ * parser.c (cp_parser_function_specifier_opt): Upon error about
+ virtual templates don't set ds_virtual.
+ (finish_fully_implicit_template): Reject virtual implicit templates.
+
+2013-10-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58565
+ * semantics.c (potential_constant_expression_1): Handle LABEL_EXPR.
+
+2013-10-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58563
+ * parser.c (cp_parser_lookup_name): Check make_typename_type return
+ value for error_mark_node.
+
+2013-09-25 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in (CXX_TREE_H, CXX_PARSER_H, CXX_PRETTY_PRINT_H):
+ Remove.
+
+2013-09-25 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in (g++spec.o): Remove.
+ (CFLAGS-cp/g++spec.o): New variable.
+ (GXX_OBJS): Reference cp/g++spec.o.
+ (cc1plus-checksum.o, cp/lex.o, cp/cp-array-notation.o)
+ (cp/cp-lang.o, cp/decl.o, cp/decl2.o, cp/cp-objcp-common.o)
+ (cp/typeck2.o, cp/typeck.o, cp/class.o, cp/call.o)
+ (cp/friend.o, cp/init.o, cp/method.o, cp/cvt.o, cp/search.o)
+ (cp/tree.o, cp/ptree.o, cp/rtti.o, cp/except.o, cp/expr.o)
+ (cp/pt.o, cp/error.o, cp/repo.o, cp/semantics.o, cp/dump.o)
+ (cp/optimize.o, cp/mangle.o, cp/parser.o, cp/cp-gimplify.o)
+ (cp/name-lookup.o, cp/cxx-pretty-print.o): Remove.
+
+2013-09-25 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in (g++spec.o): Don't use subshell.
+
+2013-09-25 Marek Polacek <polacek@redhat.com>
+
+ PR c++/58516
+ * semantics.c (finish_transaction_stmt): Check for EXPR_P before
+ setting the expr location.
+
+2013-09-23 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/58500
+ * type-utils.h (find_type_usage): Only traverse one type level into
+ member function pointers.
+
+2013-09-23 Adam Butcher <adam@jessamine.co.uk>
+
+ * parser.c (cp_parser_init_declarator): Defer calling
+ finish_fully_implicit_template for forward declarations until after
+ other decl processing is complete. Cleanup for clarity: Extract 'else'
+ case after 'if' containing unconditional return.
+
+2013-09-23 Adam Butcher <adam@jessamine.co.uk>
+
+ * parser.c (make_generic_type_name): Spell generic type names '<autoN>'
+ rather than '__GenN'.
+
+2013-09-23 Adam Butcher <adam@jessamine.co.uk>
+
+ * lambda.c (maybe_add_lambda_conv_op): Don't check for instantiated
+ callop in the case of generic lambdas.
+
+2013-09-23 Adam Butcher <adam@jessamine.co.uk>
+
+ * parser.c (make_generic_type_name): Use global count rather than
+ parameter and ...
+ (add_implicit_template_parms): ... propagate interface change here.
+
+2013-09-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58481
+ * pt.c (tsubst_copy): Use current_nonlambda_class_type to
+ call tsubst_baselink.
+
+2013-09-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58457
+ * class.c (instantiate_type): Loosen a bit the gcc_assert.
+
+2013-09-18 Marek Polacek <polacek@redhat.com>
+
+ PR sanitize/58443
+ * typeck.c (cp_build_binary_op): Properly honor -fsanitize options.
+ Remove unnecessary check.
+
+2013-09-18 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/58411
+ * typeck.c (cp_build_binary_op): Don't sanitize function if it has the
+ no_sanitize_undefined attribute.
+
+2013-09-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58435
+ * pt.c (tsubst, [BOUND_TEMPLATE_TEMPLATE_PARM]): Take into account
+ the cp_type_quals (r) too.
+
+2013-09-16 Adam Butcher <adam@jessamine.co.uk>
+
+ * cp-tree.h (type_uses_auto_or_concept): Declare.
+ (is_auto_or_concept): Declare.
+ * decl.c (grokdeclarator): Allow 'auto' parameters in lambdas with
+ -std=gnu++1y or -std=c++1y or, as a GNU extension, in plain functions.
+ * type-utils.h: New header defining ...
+ (find_type_usage): ... this new function based on pt.c (type_uses_auto)
+ for searching a type tree given a predicate.
+ * pt.c (type_uses_auto): Reimplement via type-utils.h (find_type_usage).
+ (is_auto_or_concept): New function.
+ (type_uses_auto_or_concept): New function.
+ * parser.h (struct cp_parser): Add fully_implicit_function_template_p.
+ * parser.c (cp_parser_new): Initialize
+ fully_implicit_function_template_p.
+ (cp_parser_new): Initialize fully_implicit_function_template_p.
+ (cp_parser_lambda_expression): Copy and restore value of
+ fully_implicit_function_template_p as per other parser fields.
+ (cp_parser_parameter_declaration_list): Count generic
+ parameters and call ...
+ (add_implicit_template_parms): ... this new function to synthesize them
+ with help from type-utils.h (find_type_usage), ...
+ (tree_type_is_auto_or_concept): ... this new static function and ...
+ (make_generic_type_name): ... this new static function.
+ (cp_parser_direct_declarator): Account for implicit template parameters.
+ (cp_parser_lambda_declarator_opt): Finish fully implicit template if
+ necessary by calling ...
+ (finish_fully_implicit_template): ... this new function.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_function_definition_after_declarator): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ * Make-lang.in (cp/pt.o): Add dependency on type-utils.h.
+ (cp/parser.o): Likewise.
+
+2013-09-16 Adam Butcher <adam@jessamine.co.uk>
+
+ * parser.c (cp_parser_lambda_declarator_opt): Accept template parameter
+ list with std=c++1y or std=gnu++1y.
+ (cp_parser_lambda_body): Don't call 'expand_or_defer_fn' for lambda call
+ operator template to avoid adding template result to symbol table.
+ * lambda.c (lambda_function): Return template result if call operator is
+ a template.
+ (maybe_add_lambda_conv_op): Move declarations to point of use. Refactor
+ operator call building in order to support conversion of a non-capturing
+ lambda template to a function pointer with help from ...
+ (prepare_op_call): ... this new function.
+ * decl2.c (check_member_template): Don't reject lambda call operator
+ template in local [lambda] class.
+ * pt.c (instantiate_class_template_1): Don't instantiate lambda call
+ operator template when instantiating lambda class.
+
+2013-09-16 Adam Butcher <adam@jessamine.co.uk>
+
+ * pt.c (make_auto_1): Use input_location rather than BUILTINS_LOCATION.
+
+2013-09-15 Jason Merrill <jason@redhat.com>
+
+ Core DR 904
+ PR c++/41933
+ * parser.c (cp_parser_lambda_introducer): Handle variadic capture.
+ * lambda.c (add_capture): Handle variadic capture.
+ (add_default_capture, lambda_capture_field_type): Likewise.
+ (build_capture_proxy, register_capture_members): Likewise.
+ * pt.c (register_specialization): Allow FIELD_DECL.
+ (retrieve_specialization): Likewise.
+ (find_parameter_packs_r): Handle FIELD_DECL and VAR_DECL.
+ (tsubst_pack_expansion): Handle FIELD_DECL packs.
+ (gen_elem_of_pack_expansion_instantiation): Likewise.
+ (instantiate_class_template_1): Likewise.
+ (tsubst_decl, tsubst_copy): Likewise.
+ (tsubst_expr) [DECL_EXPR]: Handle capture proxy packs.
+ (tsubst_copy_and_build) [VAR_DECL]: Likewise.
+ * semantics.c (finish_non_static_data_member): Don't try to represent
+ the type of a COMPOUND_REF of a FIELD_DECL pack.
+
+ PR c++/41933
+ * cp-tree.h (DECL_PACK_P): Replace FUNCTION_PARAMETER_PACK_P.
+ * cxx-pretty-print.c (direct_declarator): Adjust.
+ * decl2.c (cp_build_parm_decl): Adjust.
+ * pt.c (function_parameter_pack_p): Adjust.
+ (find_parameter_packs_r, push_template_decl_real): Adjust.
+ (tsubst_pack_expansion, tsubst_decl): Adjust.
+ (regenerate_decl_from_template, instantiate_decl): Adjust.
+
+ * lambda.c (add_capture): Don't add DECL_LANG_SPECIFIC.
+
+2013-09-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/58273
+ * pt.c (any_type_dependent_elements_p): Actually check for
+ type-dependence, not value-dependence.
+
+2013-09-13 Jacek Caban <jacek@codeweavers.com>
+
+ * decl.c: Use new cxx_implicit_extern_c hook
+
+2013-09-12 Brooks Moses <bmoses@google.com>
+
+ PR driver/42955
+ * Make-lang.in: Do not install driver binaries in $(target)/bin.
+
+2013-09-12 Adam Butcher <adam@jessamine.co.uk>
+
+ * pt.c (instantiate_decl): Save/restore cp_unevaluated_operand and
+ c_inhibit_evaluation_warnings. Reset if instantiating within a
+ function-local template.
+
+2013-09-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * semantics.c (finish_pseudo_destructor_expr): Add location_t
+ parameter.
+ * pt.c (unify_arg_conversion): Use EXPR_LOC_OR_HERE.
+ (tsubst_copy_and_build): Adjust finish_pseudo_destructor_expr
+ calls.
+ * parser.c (cp_parser_postfix_dot_deref_expression): Likewise.
+ (cp_parser_postfix_expression): Pass the proper location to
+ cp_parser_postfix_dot_deref_expression.
+ * cp-tree.h (finish_pseudo_destructor_expr): Update declaration.
+
+2013-09-10 Jan Hubicka <jh@suse.cz>
+ Paolo Carlini <paolo.carlini@oracle.com>
+
+ * error.c (print_instantiation_partial_context_line): If
+ loc == UNKNOWN_LOCATION return immediately.
+
+2013-09-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/58325
+ * init.c (build_vec_delete): Call mark_rvalue_use on base.
+
+2013-09-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/43452
+ * init.c (build_vec_delete_1): When the type is incomplete emit a
+ warning, enabled by default (not an error).
+ (build_delete): Adjust to use OPT_Wdelete_incomplete.
+
+2013-09-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58362
+ * error.c (location_of): Don't handle PARM_DECLs specially.
+
+2013-09-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * error.c (dump_expr, [PSEUDO_DTOR_EXPR]): Fix.
+ * cxx-pretty-print.c (cxx_pretty_printer::postfix_expression):
+ Tweak, TREE_OPERAND (t, 1) may be null.
+
+2013-09-08 Caroline Tice <cmtice@google.com>
+
+ PR c++/58300
+ * vtable-class-hierarchy.c (vtv_generate_init_routine): In
+ preinit case, move call to assemble_vtv_preinit_initializer to
+ after call to cgraph_process_new_functions.
+
+2013-09-08 Tom de Vries <tom@codesourcery.com>
+
+ PR c++/58282
+ * except.c (build_must_not_throw_expr): Handle
+ flag_exceptions.
+
+2013-09-08 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * typeck.c (cp_build_binary_op): Use vector_types_compatible_elements_p.
+
+2013-09-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/24926
+ * class.c (finish_struct_anon_r): New.
+ (finish_struct_anon): Use it.
+
+2013-09-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::simple_type_specifier):
+ Declare as overrider.
+ * cxx-pretty-print.c (cxx_pretty_printer::simple_type_specifier):
+ Rename from pp_cxx_simple_type_specifier.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to
+ simple_type_specifier.
+
+2013-09-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58305
+ * typeck2.c (build_functional_cast): Maybe warn_deprecated_use.
+
+2013-09-03 Mike Stump <mikestump@comcast.net>
+
+ * Make-lang.in (cp/lambda.o): Add dependencies.
+
+2013-09-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::type_id): Declare as
+ overrider.
+ * cxx-pretty-print.c (pp_cxx_storage_class_specifier): Remove.
+ (pp_cxx_userdef_literal): Tidy.
+ (pp_cxx_template_argument_list): Likewise.
+ (pp_cxx_typeid_expression): Likewise.
+ (pp_cxx_offsetof_expression_1): Likewise.
+ (cxx_pretty_printer::postfix_expression): Likewise.
+ (cxx_pretty_printer::unary_expression): Likewise.
+ (cxx_pretty_printer::statement): Likewise.
+ (cxx_pretty_printer::type_id): Rename from pp_cxx_type_id.
+ (c_pretty_printer::cxx_pretty_printer): Do not assign to type_id.
+ * error.c (dump_decl): Tidy.
+ (dump_expr): Likewise.
+
+2013-09-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/21682, implement DR 565
+ * name-lookup.c (compparms_for_decl_and_using_decl): New.
+ (push_overloaded_decl_1, do_nonmember_using_decl): Use it.
+
+2013-08-30 Marek Polacek <polacek@redhat.com>
+
+ * typeck.c (cp_build_binary_op): Add division by zero and shift
+ instrumentation.
+ * error.c (dump_expr): Special-case ubsan builtins.
+
+2013-08-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51424
+ * cp-tree.h (LOOKUP_DELEGATING_CONS): Add.
+ * init.c (perform_target_ctor): Use it.
+ * call.c (build_special_member_call): Diagnose self-delegating
+ constructors.
+
+2013-08-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::declaration): Declare as
+ overrider.
+ (cxx_pretty_printer::declaration_specifiers): Likewise.
+ (cxx_pretty_printer::function_specifier): Likewise.
+ (cxx_pretty_printer::declarator): Likewise.
+ (cxx_pretty_printer::direct_declarator): Likewise.
+ (cxx_pretty_printer::abstract_declarator): Likewise.
+ (cxx_pretty_printer::direct_abstract_declarator): Likewise.
+ (pp_cxx_declaration): Remove.
+ * cxx-pretty-print.c (cxx_pretty_printer::function_specifier):
+ Rename from pp_cxx_function_specifier. Adjust.
+ (cxx_pretty_printer::declaration_specifiers): Rename from
+ pp_cxx_decl_specifier_seq. Adjust.
+ (cxx_pretty_printer::direct_declarator): Rename from
+ pp_cxx_direct_declarator. Adjust.
+ (cxx_pretty_printer::declarator): Rename from pp_cxx_declarator.
+ Adjust.
+ (cxx_pretty_printer::abstract_declarator): Rename from
+ pp_cxx_abstract_declarator. Adjust.
+ (cxx_pretty_printer::direct_abstract_declarator): Rename from
+ pp_cxx_direct_abstract_declarator. Adjust.
+ (cxx_pretty_printer::declaration): Rename from
+ pp_cxx_declaration. Adjust.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to
+ declaration, declaration_specifiers, function_specifier,
+ declarator, direct_declarator, abstract_declarator,
+ direct_abstract_declarator.
+ * error.c (dump_decl): Adjust.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ Correct previous patch to not mark terminate as LEAF.
+ * class.c (build_vtbl_initializer): Drop LEAF
+ * decl.c (cxx_init_decl_processing): Likewise.
+ (push_throw_library_fn): Likewise.
+ * except.c (init_exception_processing): Likewise.
+ (do_begin_catch): Likewise.
+ (do_end_catch): Likewise.
+ (do_allocate_exception): Likewise.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * class.c (build_vtbl_initializer): Make __cxa_deleted_virtual
+ ECF_NORETURN | ECF_LEAF
+ * cp-tree.h (build_library_fn_ptr, build_cp_library_fn_ptr,
+ push_library_fn, push_void_library_fn): Update prototype.
+ * decl.c (build_library_fn_1): Remove.
+ (push_cp_library_fn, build_cp_library_fn): Update to take ECF flags.
+ (cxx_init_decl_processing): Update; global_delete_fndecl is ECF_NOTROW;
+ __cxa_pure_virtual is ECF_NORETURN | ECF_NORETURN | ECF_LEAF.
+ (build_library_fn_1): Add ecf_flags argument; rename to ...
+ (build_library_fn): ... this one.
+ (build_cp_library_fn): Take ecf_flags; do not copy NOTHROW flag.
+ (build_library_fn_ptr): Take ecf_flags.
+ (build_cp_library_fn_ptr): Likewise.
+ (push_library_fn): Likewise.
+ (push_cp_library_fn): Likewise.
+ (push_void_library_fn): Likewise.
+ (push_throw_library_fn): All throws are ECF_NORETURN.
+ (__cxa_atexit, __cxa_thread_atexit): Add ECF_LEAF | ECF_NOTHROW attributes.
+ (expand_static_init): __cxa_guard_acquire, __cxa_guard_release,
+ __cxa_guard_abort are ECF_NOTHROW | ECF_LEAF.
+ * except.c (init_exception_processing): terminate is
+ ECF_NOTHROW | ECF_NORETURN | ECF_LEAF.
+ (declare_nothrow_library_fn): Add ecf_flags parameter.
+ (__cxa_get_exception_ptr): Is ECF_NOTHROW | ECF_PURE | ECF_LEAF |
+ ECF_TM_PURE.
+ (do_begin_catch): cxa_begin_catch and _ITM_cxa_begin_catch
+ are ECF_NOTHROW | ECF_LEAF.
+ (do_end_catch): __cxa_end_catch and _ITM_cxa_end_catch is
+ ECF_LEAF.
+ (do_allocate_exception): _cxa_allocate_exception
+ and _ITM_cxa_allocate_exception are ECF_NOTHROW | ECF_MALLOC
+ | ECF_LEAF
+ (do_free_exception): __cxa_free_exception is
+ ECF_NOTHROW | ECF_LEAF.
+ * rtti.c (build_dynamic_cast_1): __dynamic_cast
+ is ECF_LEAF | ECF_PURE | ECF_NOTHROW.
+
+2013-08-29 Adam Butcher <adam@jessamine.co.uk>
+
+ * error.c (dump_lambda_function): New function, dependent on ...
+ (dump_substitution): ... this new function, factored out of ...
+ (subst_to_string): ... here and ...
+ (dump_function_decl): ... here. Updated to early-out with call to
+ dump_lambda_function after determining template bindings.
+
+2013-08-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58255
+ * init.c (build_aggr_init): When init == void_type_node do not
+ set LOOKUP_ONLYCONVERTING.
+
+2013-08-27 Caroline Tice <cmtice@google.com>
+
+ * vtable-class-hierarchy.c: Remove unnecessary include statements.
+ (MAX_SET_SIZE): Remove unnecessary constant.
+ (register_construction_vtables): Make vtable_ptr_array parameter
+ into a vector; remove num_args parameter. Change array accesses to
+ vector accesses.
+ (register_other_binfo_vtables): Ditto.
+ (insert_call_to_register_set): Ditto.
+ (insert_call_to_register_pair): Ditto.
+ (output_set_info): Ditto. Also change warning calls to warning_at
+ calls, and fix format of warning messages.
+ (register_all_pairs): Change vtbl_ptr_array from an array into a
+ vector. Remove num_vtable_args (replace with calls to vector length).
+ Change array stores & accesses to vector functions. Change calls to
+ register_construction_vtables, register_other_binfo_vtables,
+ insert_call_to_register_set, insert_call_to_register_pair and
+ output_set_info to match their new signatures. Change warning to
+ warning_at and fix the format of the warning message.
+
+2013-08-27 Jakub Jelinek <jakub@redhat.com>
+ Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-tree.h (CP_OMP_CLAUSE_INFO): Adjust range for new clauses.
+
+2013-08-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (grokfndecl): Remove old bison hack.
+
+2013-08-26 Jan Hubicka <jh@suse.cz>
+
+ * cp-tree.h (DECL_CONSTRUCTOR_P, DECL_DESTRUCTOR_P): Use
+ middle-end flag.
+
+2013-08-26 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::unary_expression):
+ Declare as overrider.
+ (cxx_pretty_printer::multiplicative_expression): Likewise.
+ (cxx_pretty_printer::conditional_expression): Likewise.
+ (cxx_pretty_printer::assignment_expression): Likewise.
+ (cxx_pretty_printer::expression): Likewise.
+ * cxx-pretty-print.c (cxx_pretty_printer::unary_expression):
+ Rename from pp_cxx_unary_expression. Adjust.
+ (cxx_pretty_printer::multiplicative_expression): Rename from
+ pp_cxx_multiplicative_expression. Adjust.
+ (cxx_pretty_printer::conditional_expression): Rename from
+ pp_cxx_conditional_expression. Adjust.
+ (cxx_pretty_printer::assignment_expression): Rename from
+ pp_cxx_assignment_expression. Adjust.
+ (cxx_pretty_printer::expression): Rename from pp_cxx_expression.
+ Adjust.
+ (cxx_pretty_printer::cxx_pretty_printer): Dot not assign to
+ unary_expression, multiplicative_expression,
+ conditional_expression, assignment_expression, expression.
+
+2013-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::postfix_expression):
+ Declare as overrider.
+ * cxx-pretty-print.c (cxx_pretty_printer::postfix_expression):
+ Rename from pp_cxx_postfix_expression. Adjust.
+ (pp_cxx_expression): Use pp_postfix_expression.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to
+ postfix_expression.
+
+2013-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::primary_expression): Now
+ an overrider of c_pretty_printer::primary_expression.
+ * cxx-pretty-print.c (cxx_pretty_printer::primary_expression):
+ Rename from pp_cxx_primary_expression. Adjust.
+ (pp_cxx_postfix_expression): Use pp_primary_expression.
+ (pp_cxx_ctor_initializer): Likewise.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to
+ primary_expression.
+
+2013-08-23 Jan Hubicka <jh@suse.cz>
+
+ * cp-tree.h (struct lang_type_class): Free is_final bit.
+ (CLASSTYPE_FINAL): Define using TYPE_FINAL_P.
+ (DECL_FINAL_P): Remove.
+ * pt.c (instantiate_class_template_1): Guard that CLASSTYPE_FINAL
+ is called on CLASS_TYPE_P.
+
+2013-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.c (M_): Remove.
+ (pp_cxx_unqualified_id): Use translate_string instead of M_.
+ (pp_cxx_canonical_template_parameter): Likewise.
+
+2013-08-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::id_expression): Declare.
+ * cxx-pretty-print.c (cxx_pretty_printer::id_expression): Rename
+ from pp_cxx_id_expression. Adjust.
+ (pp_cxx_userdef_literal): Use pp_id_expression.
+ (pp_cxx_primary_expression): Likewise.
+ (pp_cxx_direct_declarator): Likewise.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to
+ id_expression.
+
+2013-08-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::constant): Now a member
+ function, overriding c_pretty_printer::constant.
+ * cxx-pretty-print.c (cxx_pretty_printer::constant): Rename from
+ pp_cxx_constant. Adjust.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to constant.
+
+2013-08-23 Gabriel Dos Reis <gdr@integrable-solutiobs.net>
+
+ * cp-objcp-common.c (cxx_initialize_diagnostics): Call a
+ destructor for the early printer.
+ * error.c (type_to_string): Use pp_buffer.
+
+2013-08-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56380
+ * class.c (check_field_decls): Check for const mutable and const
+ reference data members.
+
+2013-08-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (init_error): Remove calls to pp_construct and
+ pp_cxx_pretty_printer_init. Initialize cxx_pp with placement-new.
+ * cxx-pretty-print.h (cxx_pretty_printer::cxx_pretty_printer): Declare.
+ (cxx_pretty_printer_init): Remove.
+ * cxx-pretty-print.c (cxx_pretty_printer::cxx_pretty_printer):
+ Rename from cxx_pretty_printer_init. Adjust.
+ * cp-objcp-common.c (cxx_initialize_diagnostics): Simplify
+ initialization of C++ diagnostics pretty printer.
+
+2013-08-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * call.c (build_new_method_call_1): Use INDIRECT_REF_P.
+ * cp-tree.h (REFERENCE_REF_P): Likewise.
+ * semantics.c (finish_offsetof): Likewise.
+
+2013-08-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56130
+ * semantics.c (finish_id_expression): Handle deprecated references.
+
+2013-08-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/58119
+ * cvt.c (build_expr_type_conversion): Don't complain about a
+ template that can't match the desired type category.
+
+2013-08-20 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (pp_ggc_formatted_text): New.
+ (type_as_string): Use it in lieu of pp_formatted_text.
+ (type_as_string_translate): Likewise.
+ (expr_as_string): Likewise.
+ (decl_as_string): Likewise.
+ (decl_as_string_translate): Likewise.
+ (lang_decl_name): Likewise.
+ (decl_to_string): Likewise.
+ (expr_to_string): Likewise.
+ (fndecl_to_string): Likewise.
+ (parm_to_string): Likewise.
+ (type_to_string): Likewise.
+ (args_to_string): Likewise.
+ (subst_to_string): Likewise.
+
+2013-08-19 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR c/57490
+ * cp-array-notation.c (cp_expand_cond_array_notations): Added a
+ check for truth values.
+ (expand_array_notation_exprs): Added truth values case. Removed an
+ unwanted else. Added for-loop to walk through subtrees in default
+ case.
+ * call.c (build_cxx_call): Inherited the type of the array notation for
+ certain built-in array notation functions.
+
+2013-08-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * parser.c (cp_parser_lambda_introducer, cp_parser_decltype_expr):
+ Use cp_parser_lookup_name_simple.
+
+2013-08-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * name-lookup.h (pop_bindings_and_leave_scope): Declare.
+ * name-lookup.c (pop_bindings_and_leave_scope): Define.
+ * parser.c (cp_parser_lambda_declarator_opt,
+ cp_parser_direct_declarator, cp_parser_cache_defarg): Use it.
+
+2013-08-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/58083
+ * name-lookup.c (push_class_level_binding_1): It's OK to push a
+ lambda type after the enclosing type is complete.
+
+2013-08-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_scope): Add a cxx_pretty_printer parameter.
+ Adjust callers.
+ (dump_template_argument): Likewise.
+ (dump_template_argument_list): Likewise.
+ (dump_template_parameter): Likewise.
+ (dump_template_bindings): Likewise.
+ (dump_alias_template_specialization): Likewise.
+ (dump_type): Likewise.
+ (dump_typename): Likewise.
+ (dump_aggr_type): Likewise.
+ (dump_type_prefix): Likewise.
+ (dump_type_suffix): Likewise.
+ (dump_global_iord): Likewise.
+ (dump_simple_decl): Likewise.
+ (dump_decl): Likewise.
+ (dump_template_decl): Likewise.
+ (dump_function_decl): Likewise.
+ (dump_parameters): Likewise.
+ (dump_ref_qualifier): Likewise.
+ (dump_exception_spec): Likewise.
+ (dump_function_name): Likewise.
+ (dump_template_parms): Likewise.
+ (dump_call_expr_args): Likewise.
+ (dump_aggr_init_expr_args): Likewise.
+ (dump_expr_list): Likewise.
+ (dump_expr_init_vec): Likewise.
+ (dump_expr): Likewise.
+ (dump_binary_op): Likewise.
+ (dump_unary_op): Likewise.
+
+2013-08-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51912
+ * cp-tree.h (LOOKUP_NO_NON_INTEGRAL): Add.
+ * decl.c (case_conversion): Use it.
+ * call.c (standard_conversion): Likewise.
+ (implicit_conversion): Adjust.
+
+2013-08-13 Adam Butcher <adam@jessamine.co.uk>
+
+ * pt.c: Grammar fix in comments ("it's" to "its").
+
+2013-08-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (warn_extern_redeclared_static, duplicate_decls,
+ check_elaborated_type_specifier): Use error + inform.
+ * friend.c (make_friend_class): Likewise.
+ * semantics.c (finish_id_expression): Likewise.
+
+2013-08-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ Revert:
+ 2013-08-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/46206
+ * name-lookup.c (lookup_name_real_1): Handle iter->type before
+ iter->value.
+
+2013-08-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/46206
+ * name-lookup.c (lookup_name_real_1): Handle iter->type before
+ iter->value.
+
+2013-08-06 Caroline Tice <cmtice@google.com>
+
+ * Make-lang.in (*CXX_AND_OBJCXX_OBJS): Add vtable-class-hierarchy.o to
+ list.
+ (vtable-class-hierarchy.o): Add build rule.
+ * cp-tree.h (vtv_start_verification_constructor_init_function): New
+ extern function decl.
+ (vtv_finish_verification_constructor_init_function): New extern
+ function decl.
+ (build_vtbl_address): New extern function decl.
+ (get_mangled_vtable_map_var_name): New extern function decl.
+ (vtv_compute_class_hierarchy_transitive_closure): New extern function
+ decl.
+ (vtv_generate_init_routine): New extern function decl.
+ (vtv_save_class_info): New extern function decl.
+ (vtv_recover_class_info): New extern function decl.
+ (vtv_build_vtable_verify_fndecl): New extern function decl.
+ * class.c (finish_struct_1): Add call to vtv_save_class_info if
+ flag_vtable_verify is true.
+ * config-lang.in: Add vtable-class-hierarchy.c to gtfiles list.
+ * vtable-class-hierarchy.c: New file.
+ * mangle.c (get_mangled_vtable_map_var_name): New function.
+ * decl2.c (start_objects): Update function comment.
+ (cp_write_global_declarations): Call vtv_recover_class_info,
+ vtv_compute_class_hierarchy_transitive_closure and
+ vtv_build_vtable_verify_fndecl, before calling
+ finalize_compilation_unit, and call vtv_generate_init_rount after, IFF
+ flag_vtable_verify is true.
+ (vtv_start_verification_constructor_init_function): New function.
+ (vtv_finish_verification_constructor_init_function): New function.
+ * init.c (build_vtbl_address): Remove static qualifier from function.
+
+2013-08-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/57825
+ * tree.c (strip_typedefs) [METHOD_TYPE]: Preserve ref-qualifier.
+
+2013-08-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58080
+ * typeck.c (cp_pointer_int_sum): Add tsubst_flags_t parameter.
+ (cp_build_binary_op): Adjust.
+
+2013-08-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (pp_c_base): Remove.
+ (cxx_pretty_printer): Derive from c_pretty_printer.
+ Adjust macros using pp_c_base.
+ * cp-objcp-common.c (cxx_initialize_diagnostics): Do not call pp_base.
+ * cxx-pretty-print.c (pp_cxx_nonconsecutive_character): Likewise.
+ (pp_cxx_colon_colon): Likewise.
+ (pp_cxx_separate_with): Likewise.
+ (pp_cxx_storage_class_specifier): Do not call pp_c_base.
+ (pp_cxx_expression_list): Likewise.
+ (pp_cxx_space_for_pointer_operator): Likewise.
+ (pp_cxx_init_declarator): Likewise.
+ (pp_cxx_call_argument_list): Likewise.
+ (pp_cxx_constant): Likewise.
+ (pp_cxx_postfix_expression): Likewise.
+ (pp_cxx_new_expression): Likewise.
+ (pp_cxx_unary_expression): Likewise.
+ (pp_cxx_cast_expression): Likewise.
+ (pp_cxx_conditional_expression): Likewise.
+ (pp_cxx_assignment_expression): Likewise.
+ (pp_cxx_expression): Likewise.
+ (pp_cxx_function_specifier): Likewise.
+ (pp_cxx_decl_specifier_seq): Likewise.
+ (pp_cxx_simple_type_specifier): Likewise.
+ (pp_cxx_type_specifier_seq): Likewise.
+ (pp_cxx_ptr_operator): Likewise.
+ (pp_cxx_parameter_declaration_clause): Likewise.
+ (pp_cxx_direct_declarator): Likewise.
+ (pp_cxx_direct_abstract_declarator): Likewise.
+ (pp_cxx_type_id): Likewise.
+ (pp_cxx_statement): Likewise.
+ (pp_cxx_pretty_printer_init): Tidy.
+ * error.c (init_error): Do not use pp_base.
+ (dump_aggr_type): Likewise.
+ (dump_type_prefix): Likewise.
+ (dump_type_suffix): Likewise.
+ (dump_global_iord): Likewise.
+ (dump_decl): Likewise.
+ (dump_function_decl): Likewise.
+ (dump_ref_qualifier): Likewise.
+ (reinit_cxx_pp): Likewise.
+ (decl_as_dwarf_string): Likewise.
+ (lang_decl_dwarf_name): Likewise.
+ (type_to_string): Likewise.
+ (cv_to_string): Likewise.
+ (cxx_print_error_function): Likewise.
+ (cp_diagnostic_starter): Likewise.
+ (cp_diagnostic_finalizer): Likewise.
+ (cp_print_error_function): Likewise.
+ (print_instantiation_context): Likewise.
+ (cp_printer): Likewise.
+
+2013-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_type_prefix): Use specialized pretty printer
+ functions instead of pp_string or operators and punctuators.
+ (dump_decl): Likewise.
+ (dump_expr): Likewise.
+
+2013-08-03 Jason Merrill <jason@redhat.com>
+
+ DR 1286
+ * pt.c (get_underlying_template): New.
+ (convert_template_argument, lookup_template_class_1): Use it.
+
+ DR 1430
+ PR c++/51239
+ * pt.c (pack_expansion_args_count): Rename from
+ any_pack_expanson_args_p.
+ (coerce_template_parms): Reject pack expansion to
+ non-pack template parameter of alias template.
+
+2013-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_aggr_type): Use specialized pretty printer
+ functions instead of pp_character.
+ (dump_type_prefix): Likewise.
+ (dump_simple_decl): Likewise.
+ (type_to_string): Likewise.
+
+2013-08-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cp-tree.h (finish_stmt): Do not declare.
+ * decl.c (finish_stmt): Do not define.
+ * parser.c (cp_parser_expression_statement,
+ cp_parser_declaration_statement,
+ cp_parser_transaction_cancel): Don't call finish_stmt.
+ * semantics.c (finish_expr_stmt, finish_if_stmt,
+ finish_while_stmt, finish_do_stmt, finish_return_stmt,
+ finish_for_stmt, finish_switch_stmt, finish_compound_stmt,
+ finish_transaction_stmt): Likewise.
+
+2013-08-01 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/54537
+ * cp-tree.h: Check OVL_USED with OVERLOAD_CHECK.
+ * name-lookup.c (do_nonmember_using_decl): Make sure we have an
+ OVERLOAD before calling OVL_USED. Call diagnose_name_conflict
+ instead of issuing an error without mentioning the conflicting
+ declaration.
+
+2013-07-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * parser.c (cp_parser_sizeof_pack): Check cp_parser_identifier
+ return value for error_mark_node.
+
+2013-07-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57673
+ * parser.c (cp_parser_cache_defarg): In an NSDMI don't stop when
+ token->type == CPP_ELLIPSIS.
+
+2013-07-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57947
+ * call.c (is_std_init_list): Return false if cxx_dialect == cxx98.
+
+2013-07-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/57901
+ * semantics.c (build_data_member_initialization, constexpr_fn_retval):
+ Use break_out_target_exprs instead of unshare_expr.
+
+2013-07-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57948
+ * call.c (initialize_reference): Don't crash when reference_binding
+ returns a conv with conv->kind == ck_ambig.
+
+2013-07-29 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_name): Check for null context.
+ (write_unscoped_name): Allow PARM_DECL context.
+
+2013-07-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57981
+ * decl.c (check_default_argument): Take a tsubst_flags_t parameter.
+ (grokparms): Adjust.
+ * parser.c (cp_parser_late_parse_one_default_arg): Likewise.
+ * pt.c (tsubst_default_argument, tsubst_default_arguments): Take
+ a tsubst_flags_t parameter.
+ (tsubst_decl): Adjust.
+ * call.c (convert_default_arg): Likewise.
+ * cp-tree.h (check_default_argument, tsubst_default_argument):
+ Update declarations.
+
+2013-07-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57880
+ * parser.c (cp_parser_operator, case CPP_WSTRING, CPP_STRING16,
+ CPP_STRING32, CPP_UTF8STRING, CPP_WSTRING_USERDEF,
+ CPP_STRING16_USERDEF, CPP_STRING32_USERDEF, CPP_UTF8STRING_USERDEF):
+ Fix string_len management, tidy.
+
+2013-07-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57942
+ * typeck.c (ptr_reasonably_similar): Use COMPARE_STRICT if either
+ target type is incomplete; return a bool, not an int.
+ * cp-tree.h (ptr_reasonably_similar): Adjust declaration.
+
+2013-07-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cp-tree.h (DERIVED_FROM_P): Pass tf_none to lookup_base, not
+ tf_warning_or_error.
+
+2013-07-21 Ondřej Bílka <neleai@seznam.cz>
+
+ * class.c: Fix typos.
+ * cp-array-notation.c: Likewise.
+ * cp-objcp-common.c: Likewise.
+ * decl.c: Likewise.
+ * init.c: Likewise.
+ * mangle.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * semantics.c: Likewise.
+
+2013-07-14 Adam Butcher <adam@jessamine.co.uk>
+
+ * semantics.c (build_lambda_expr),
+ (build_lambda_object), (begin_lambda_type), (lambda_return_type),
+ (lambda_function), (lambda_capture_field_type), (is_capture_proxy),
+ (is_normal_capture_proxy), (insert_capture_proxy),
+ (insert_pending_capture_proxies), (lambda_proxy_type),
+ (build_capture_proxy), (vla_capture_type),
+ (register_capture_members), (add_default_capture),
+ (lambda_expr_this_capture), (maybe_resolve_dummy),
+ (nonlambda_method_basetype), (maybe_add_lambda_conv_op) and
+ (is_lambda_ignored_entity): Moved definitions into ...
+ * lambda.c: ... this new file.
+
+2013-07-14 Marc Glisse <marc.glisse@inria.fr>
+
+ * call.c (build_conditional_expr_1): Handle the case with 1 vector
+ and 2 scalars. Call save_expr before building a vector.
+ * typeck.c (cp_build_binary_op): Check complain before complaining.
+
+2013-07-13 Lubos Lunak <l.lunak@suse.cz>
+
+ PR c++/55203
+ * init.c (build_aggr_init): Check for warn_unused attribute.
+ * decl.c (poplevel): Likewise.
+
+2013-07-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/57402
+ * init.c (build_vec_init): Use {} for arrays of class type.
+ (build_vec_delete): Don't take the address of the array.
+
+ PR c++/57793
+ * class.c (layout_class_type): Check for too-large class.
+
+ * call.c (can_convert): Allow user-defined conversions.
+ (can_convert_standard): New.
+ * cp-tree.h: Declare it.
+ * cvt.c (convert_to_reference): Use it.
+ * pt.c (convert_nontype_argument): Likewise.
+ * search.c (check_final_overrider): Likewise.
+ Don't worry about user-defined conversions.
+
+2013-07-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57869
+ * typeck.c (build_reinterpret_cast_1): With -Wconditionally-supported
+ warn about casting between pointer-to-function and pointer-to-object.
+
+2013-07-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/57402
+ * init.c (build_vec_init): Don't take shortcuts when initializing
+ a VLA.
+
+ PR c++/57471
+ * parser.c (cp_parser_sizeof_pack): Clear parser scopes.
+
+ PR c++/57658
+ * semantics.c (finish_id_expression): Return the id for an
+ unevaluated outer variable.
+
+ PR c++/57526
+ * semantics.c (lambda_capture_field_type): Build a DECLTYPE_TYPE
+ if the variable type uses 'auto'.
+
+ PR c++/57437
+ * typeck.c (check_return_expr): Lambda proxies aren't eligible
+ for nrv or return by move.
+
+ PR c++/57532
+ * parser.c (cp_parser_ref_qualifier_opt): Don't tentatively parse
+ a ref-qualifier in C++98 mode.
+
+ PR c++/57545
+ * pt.c (convert_nontype_argument) [INTEGER_CST]: Force the
+ argument to have the exact type of the parameter.
+
+ PR c++/57551
+ * semantics.c (cxx_eval_indirect_ref): Don't try to look through
+ a POINTER_PLUS_EXPR for type punning diagnostic.
+
+ PR c++/57831
+ * pt.c (tsubst_copy): Handle USING_DECL.
+
+2013-07-09 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53094
+ * semantics.c (cxx_eval_bit_field_ref): Handle VECTOR_CST.
+
+2013-07-09 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53000
+ * call.c (build_conditional_expr_1): Preserve xvalues.
+
+2013-07-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51786
+ * parser.c (cp_parser_simple_declaration): Before calling shadow_tag
+ also check declares_class_or_enum.
+
+2013-07-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/57550
+ * pt.c (fn_type_unification): Only defer during substitution.
+ (type_unification_real): Defer during defarg substitution,
+ add checks parm to pass back deferred checks.
+ (unify, do_auto_deduction): Adjust.
+ * semantics.c (reopen_deferring_access_checks): New.
+ * cp-tree.h: Declare it.
+
+2013-07-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/28262
+ * parser.c (cp_parser_init_declarator): If we are parsing a typedef
+ set parser->default_arg_ok_p to false before cp_parser_declarator.
+
+2013-07-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/14263
+ * class.c (build_base_path): Improve diagnostic.
+
+2013-07-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/38634
+ * decl.c (start_preparsed_function): Return a bool, false if
+ push_template_decl fails.
+ (start_function): Adjust.
+ * cp-tree.h: Update.
+
+2013-07-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/57771
+ * parser.c (cp_parser_postfix_expression) <case RID_STATCAST>
+ Temporarily set parser->greater_than_is_operator_p for
+ cp_parser_expression and restore from saved value afterwards.
+
+2013-06-28 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ * cp-tree.h (UDLIT_OP_ANSI_PREFIX): Remove space.
+ * parser.c (cp_parser_operator()): Parse user-defined string
+ literal as literal operator.
+
+2013-06-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57645
+ * class.c (deduce_noexcept_on_destructors): Save, set, and restore
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) around the main loop over the
+ destructors.
+
+2013-06-28 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * parser.c (cp_parser_array_notation): Removed rejection array notation
+ of type function pointers. Added handling of array expressions when
+ Cilk Plus is enabled. Took out type-checking.
+ (cp_parser_postfix_open_square_expression): Moved normal array expr.
+ parsing into cp_parser_array_notation when cilkplus is enabled.
+ (cp_parser_compound_statement): Removed expansion of array notations.
+ (cp_parser_ctor_initializer_opt_and_function_body): Likewise.
+ (cp_parser_function_definition_after_declarator): Likewise.
+ (cp_parser_selection_statement): Removed error reporting.
+ (cp_parser_iteration_statement): Likewise.
+ (cp_parser_direct_declarator): Removed error checking/reporting if
+ array notations are used in the declarator.
+ * pt.c (instantiate_decl): Likewise.
+ (type_unification_real): Removed a check for ARRAY_NOTATION_REF.
+ (cxx_eval_constant_expression): Removed ARRAY_NOTATION_REF case.
+ (potential_constant_expression_1): Returned false for
+ ARRAY_NOTATION_REF case.
+ * cp-gimplify.c (cp_genericize): Added expansion of array notation
+ expressions here.
+ * cp-array-notation.c (make_triplet_val_inv): Removed loc and cry
+ parameters. Replaced build_decls with get_temp_regvar with type as
+ ptrdiff.
+ (create_array_refs): Made the type-casting to ptrdiff_type.
+ (replace_invariant_var): Added a check for void return type before
+ creating new var. Replaced build_decl and build_min_nt_loc with
+ get_temp_regvar.
+ (expand_an_in_modify_expr): Ditto. Replaced body of redundant else
+ with gcc_unreachable. Removed few unwanted checks. Made induction
+ variable type as ptrdiff_type. Removed loc and complain arguments
+ passed into make_triplet_val_inv. Replaced all modify expression's
+ code from NOP EXPR to INIT EXPR. Replaced all forceful appending
+ into stmt. list with the non-forceful one. Replaced some integer
+ conversion and equality-checking to using tree_int_cst_equal.
+ (expand_sec_reduce_builtin): All changes mentioned in above function
+ expand_an_in_modify_expr. Made the new variable type of
+ SEC_REDUCE_ANY/ALL_{NON}ZERO intrinsic functions as bool.
+ (expand_array_notation_exprs): Removed SWITCH_EXPR case. Moved all
+ the error reporting from parser to this function. Removed unwanted
+ statements and checks from SWITCH_STMT, WHILE_STMT, and DO_STMT cases.
+ (cilkplus_an_triplet_types_ok_p): Removed rejection of array notation
+ in function pointers.
+ (cp_expand_cond_array_notations): Added a new if statements to check
+ if condition has a zero rank. If so, then just return.
+ (expand_return_expr): Added a check for return expressions with a rank.
+ Replaced get_tmp_regvar with a create_temporary_var.
+ (build_array_notation_ref): Simplified and removed unwanted if-stmts.
+ Moved common code outside if-statements. Moved type-checking from
+ parser to here.
+ * semantics.c (finish_return_stmt): Removed a check for return exprs.
+ with a rank.
+ * call.c (convert_like_real): Removed a check for array notation
+ expression in a function.
+ (build_over_call): Likewise.
+ (magic_varargs_p): Added a check for builtin array notation function.
+ Made this function non-static and removed its prototype.
+ * cp-tree.h (magic_varargs_p): New prototype.
+ * typeck.c (cp_build_function_call_vec): Removed automatic setting of
+ nargs to the param->length when builtin reduction function is used.
+ (convert_arguments): Replaced check for a constant_p function with
+ margic_varargs_p function call.
+ (cp_build_binary_op): Removed calling of the function
+ find_correct_array_notation_type.
+ (cp_build_addr_expr_1): Removed an unwanted if-statement.
+ (convert_for_assignment): Removed automatic return of rhs when array
+ notation builtin function is used.
+
+2013-06-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57682
+ * parser.c (cp_parser_save_member_function_body): Handle correctly
+ curly braces in function-try-block mem-initializers.
+
+2013-06-27 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/57509
+ * typeck.c (cp_build_vec_perm_expr): New function.
+ * cp-tree.h: Declare it.
+ * parser.c (cp_parser_postfix_expression): Call it.
+ * pt.c (tsubst_copy): Handle VEC_PERM_EXPR.
+ (tsubst_copy_and_build): Likewise.
+
+2013-06-27 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/57172
+ * pt.c (more_specialized_fn): If both arguments are references,
+ give priority to an lvalue.
+
+2013-06-26 Jason Merrill <jason@redhat.com>
+
+ * typeck2.c (store_init_value): Diagnose a non-constant
+ initializer for in-class static.
+
+ PR c++/57408
+ * semantics.c (add_capture): Set type to error_mark_node after
+ error.
+
+2013-06-25 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/57640
+ * parser.c (cp_parser_unqualified_id): Add declarator_p to checks
+ to trigger warning, (cp_literal_operator_id): Remove bogus TODO comment.
+
+2013-06-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * call.c (null_ptr_cst_p): Use cxx11 in lieu of cxx0x.
+ * class.c (add_implicitly_declared_members): Likewise.
+ (check_field_decl): Likewise.
+ (finalize_literal_type_property): Likewise.
+ (check_bases_and_members): Likewise.
+ * decl.c (poplevel): Likewise.
+ (case_conversion): Likewise.
+ (check_initializer): Likewise.
+ (grokfndecl): Likewise.
+ (check_static_variable_definition): Likewise.
+ (compute_array_index_type): Likewise.
+ (grokdeclarator): Likewise.
+ (build_enumerator): Likewise.
+ * friend.c (make_friend_class): Likewise.
+ * lex.c (init_reswords): Likewise.
+ * method.c (synthesized_method_walk): Likewise.
+ (implicitly_declare_fn): Likewise.
+ * parser.c (cp_parser_diagnose_invalid_type_name): Likewise.
+ (cp_parser_constant_expression): Likewise.
+ (cp_parser_for_init_statement): Likewise.
+ (cp_parser_block_declaration): Likewise.
+ (cp_parser_type_name): Likewise.
+ (cp_parser_enum_specifier): Likewise.
+ (cp_parser_enumerator_list): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ (cp_nth_tokens_can_be_std_attribute_p): Likewise.
+ (cp_parser_template_declaration_after_export): Likewise.
+ * pt.c (convert_nontype_argument_function): Likewise.
+ (convert_nontype_argument): Likewise.
+ (convert_template_argument): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ (build_non_dependent_expr): Likewise.
+ * semantics.c (non_const_var_error): Likewise.
+ (potential_constant_expression_1): Likewise.
+ * tree.c (lvalue_kind): Likewise.
+ (build_vec_init_expr): Likewise.
+ (cast_valid_in_integral_constant_expression_p): Likewise.
+ * typeck.c (build_x_conditional_expr): Likewise.
+ * typeck2.c (check_narrowing): Likewise.
+
+2013-06-21 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * cp-array-notation.c (cp_length_mismatch_in_expr_p): Remove.
+ (expand_an_in_modify_expr): Changed a function call from the above
+ removed function to length_mismatch_in_expr_p.
+
+2013-06-21 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * call.c (convert_like_real): Added a check if array notation is present
+ in expression. If so, then no conversion of arguments is necessary.
+ (build_over_call): Likewise.
+ * typeck.c (cp_build_function_call_vec): Likewise.
+ (convert_for_assignment): Likewise.
+ (cp_build_array_ref): Reject array notations with a rank greater than 1
+ as an array's index.
+ (cp_build_binary_op): If array notations are preent in op, then call
+ find_correct_array_notation_type.
+ (cp_build_addr_expr_1): Handle ARRAY_NOTATION_REF similar to ARRAY_REF.
+ * cp-array-notation.c: New file.
+ * cp-objcp-common.c (cp_common_init_ts): Marked ARRAY_NOTATION_REF tree
+ as typed.
+ * cp-tree.h (fix_array_notation_exprs): New prototype.
+ * semantics.c (finish_return_stmt): Reject array notations as
+ return value.
+ (cxx_eval_constant_expression): Added ARRAY_NOTATION_REF case.
+ (potential_constant_expression_1): Likewise.
+ * tree.c (lvalue_kind): Likewise.
+ * error.c (dump_decl): Likewise.
+ (dump_expr): Likewise.
+ * pt.c (ARRAY_NOTATION_REF): Likewise.
+ (type_unification_real): Do not unify any arguments if array notations
+ are found in arg.
+ (instantiate_decl): Added a check for array notaitons inside the
+ function body. If so, then expand them.
+ * parser.c (cp_parser_array_notation): New function.
+ (cp_parser_postfix_open_square_expression): Added a check for colons
+ inside square braces. If found, then handle the array access as an
+ array notation access. Also, disable auto-correction from a single
+ colon to scope when Cilk Plus is enabled.
+ (cp_parser_compound_statement): Added a check for array notations
+ inside the statement. If found, then expand them.
+ (cp_parser_ctor_initializer_opt_and_function_body): Likewise.
+ (cp_parser_function_definition_after_declarator): Likewise.
+ (cp_parser_selection_statement): Searched for array notations inside
+ condition. If so, then emit an error.
+ (cp_parser_iteration_statement): Likewise.
+ (cp_parser_direct_declarator): Reject array notations inside a
+ variable or array declaration.
+ * Make-lang.in (CXX_AND_OBJCXX_OBJS): Added cp/cp-array-notation.o.
+
+2013-06-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/55149
+ * decl.c (compute_array_index_type): Don't reject VLAs in SFINAE
+ context if we're in C++14 mode.
+ * tree.c (array_of_runtime_bound_p): Return true for a dependent
+ bound that is not potentually constant.
+ * cp-tree.h (DECL_VLA_CAPTURE_P, REFERENCE_VLA_OK): New.
+ * pt.c (tsubst) [REFERENCE_TYPE]: Check REFERENCE_VLA_OK.
+ * semantics.c (build_lambda_object): Don't rvalue a VLA capture.
+ (build_capture_proxy): Set REFERENCE_VLA_OK.
+ (vla_capture_type): Make it a proper C++ class.
+ (add_capture): Set DECL_VLA_CAPTURE_P. Don't pre-digest the
+ initializer.
+
+ * decl.c (compute_array_index_type): Use size_one_node.
+
+ * pt.c (process_partial_specialization): Build a TEMPLATE_DECL for
+ a partial specialization.
+ (tsubst_decl): Don't clobber CLASSTYPE_TI_TEMPLATE of a partial
+ specialization.
+ (most_specialized_class): Adjust.
+
+ * cp-tree.h (DECL_TEMPLATE_PARMS, DECL_TEMPLATE_RESULT)
+ (DECL_TEMPLATE_INSTANTIATIONS, DECL_TEMPLATE_SPECIALIZATIONS): Use
+ TEMPLATE_DECL_CHECK.
+
+2013-06-19 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/57638
+ * pt.c (unify, [TEMPLATE_PARM_INDEX]): Pass to unify_type_mismatch
+ TREE_TYPE (arg), not arg itself.
+
+2013-06-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53211
+ * pt.c (type_dependent_expression_p): Handle an array of unknown
+ bound depending on a variadic parameter.
+ * parser.c (cp_parser_range_for): Revert PR56794 changes.
+
+2013-06-17 Richard Biener <rguenther@suse.de>
+
+ * cp-tree.h (ANON_AGGRNAME_FORMAT, ANON_AGGRNAME_P): Move to tree.h.
+
+2013-06-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/16128
+ * parser.c (cp_parser_expression_statement): Check whether
+ cp_parser_expression returns error_mark_node.
+
+2013-06-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51413
+ * semantics.c (finish_offsetof): Handle INDIRECT_REF as expr.
+
+2013-06-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57599
+ * rtti.c (build_dynamic_cast_1): In case of cast to an unambiguous
+ accessible base simply forward to build_static_cast.
+
+2013-06-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/38958
+ * decl.c (poplevel): For the benefit of -Wunused-variable see
+ through references.
+
+2013-06-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * parser.c (cp_parser_nested_name_specifier_opt): Fix typo in comment.
+
+2013-06-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/42021
+ * parser.c (cp_parser_nested_name_specifier_opt): Avoid emitting
+ again diagnostic already emitted by cp_parser_lookup_name.
+
+2013-06-11 Jan Hubicka <jh@suse.cz>
+
+ PR c++/57551
+ * cp/pt.c (mark_decl_instantiated): Do not export explicit
+ instantiations of anonymous namespace templates.
+
+2013-06-10 Jason Merrill <jason@redhat.com>
+
+ * name-lookup.c (add_decl_to_level): Add decls in an anonymous
+ namespace to static_decls.
+
+2013-06-07 Sriraman Tallam <tmsriram@google.com>
+
+ PR c++/57548
+ * call.c (build_over_call): Check if current_function_decl is
+ NULL.
+
+2013-06-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53658
+ * pt.c (lookup_template_class_1): Consistently use TYPE_MAIN_DECL,
+ not TYPE_STUB_DECL, to access the _DECL for a _TYPE.
+
+2013-06-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/55520
+ * semantics.c (add_capture): Diagnose capture of variable-size
+ type that is not a C++1y array of runtime bound.
+
+ * decl.c (grokdeclarator): Keep a decl with error type.
+ (grokfield, grokbitfield): Likewise.
+ * pt.c (instantiate_class_template_1): Likewise.
+ (tsubst_decl): Drop redundant error.
+ * class.c (walk_subobject_offsets): Handle erroneous fields.
+ * typeck2.c (process_init_constructor_record): Likewise.
+
+2013-06-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51908
+ * parser.c (cp_parser_postfix_expression [RID_*CAST]): Set
+ parser->in_type_id_in_expr_p before calling cp_parser_type_id.
+
+2013-06-03 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (maybe_make_one_only): Use forced_by_abi instead of
+ mark_decl_referenced.
+ (mark_needed): Likewise.
+
+2013-06-03 Jason Merrill <jason@redhat.com>
+
+ * class.c (mark_type_abi_tags): New.
+ (check_abi_tags): Use it.
+
+2013-06-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57419
+ * decl2.c (mark_used): Add overload taking a tsubst_flags_t too.
+ * semantics.c (finish_qualified_id_expr): Use it.
+ * cp-tree.h: Update.
+
+2013-06-01 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (cp_write_global_declarations): Replace same_body_alias
+ by symbol.cpp_implicit_alias.
+
+2013-05-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/57404
+ * cp-lang.c (cp_classify_record): Handle structs without
+ TYPE_LANG_SPECIFIC.
+
+ PR c++/52377
+ * class.c (common_enclosing_class): New.
+ * cp-tree.h: Declare it.
+ * init.c (sort_mem_initializers): Don't splice out a union member
+ with an NSDMI.
+
+2013-05-29 Jan Hubicka <jh@suse.cz>
+
+ * tree.c (cp_fix_function_decl_p): Update for new symtab flags.
+ * decl2.c )var_finalized_p, cp_write_global_declarations): Likewise.
+
+2013-05-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/25666
+ * decl2.c (check_classfn): Check for destructors declared as member
+ templates.
+
+2013-05-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/56971
+ * pt.c (any_template_arguments_need_structural_equality_p): A
+ TEMPLATE_TEMPLATE_PARM can require structural type comparison.
+
+2013-05-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/19618
+ * class.c (check_bitfield_decl): Warn for bool and enum bitfields
+ with width exceeding the type.
+
+2013-05-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/57391
+ * semantics.c (cxx_eval_constant_expression): Handle FMA_EXPR.
+ (cxx_eval_trinary_expression): Rename from cxx_eval_vec_perm_expr.
+
+2013-05-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/57388
+ * tree.c (build_ref_qualified_type): Clear
+ FUNCTION_RVALUE_QUALIFIED for lvalue ref-qualifier.
+
+2013-05-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/56930
+ * call.c (convert_like_real): Use cp_convert_and_check.
+ * cvt.c (cp_convert_and_check): Use maybe_constant_value.
+ * semantics.c (cxx_eval_constant_expression): Handle LTGT_EXPR.
+ (potential_constant_expression_1): Handle OMP_ATOMIC*.
+
+ PR c++/56915
+ * semantics.c (maybe_add_lambda_conv_op): Give up if the call op
+ isn't defined.
+
+2013-05-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57352
+ * parser.c (cp_parser_conversion_type_id): Set up
+ parser->type_definition_forbidden_message before calling
+ cp_parser_type_specifier_seq.
+
+2013-05-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57211
+ * method.c (defaultable_fn_check): Avoid do_warn_unused_parameter
+ warnings about defaulted functions.
+
+2013-05-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * call.c (build_conditional_expr_1): Add location_t parameter.
+ (build_conditional_expr): Likewise.
+ * typeck.c (rationalize_conditional_expr, cp_build_array_ref,
+ get_member_function_from_ptrfunc, build_x_conditional_expr,
+ cp_build_modify_expr): Update.
+ * init.c (build_new_1): Likewise.
+ * cp-tree.h: Update declaration.
+
+2013-05-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/57016
+ * pt.c (instantiation_dependent_r) [TRAIT_EXPR]: Only check type2
+ if there is one.
+
+ PR c++/57102
+ * decl.c (fndecl_declared_return_type): Also look in
+ DECL_SAVED_FUNCTION_DATA.
+
+2013-05-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/12288
+ * parser.c (cp_parser_parameter_declaration): Check return value
+ of cp_parser_parse_and_diagnose_invalid_type_name.
+
+2013-05-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/57319
+ * class.c (vbase_has_user_provided_move_assign): New.
+ * method.c (synthesized_method_walk): Check it.
+ * cp-tree.h: Declare it.
+
+ PR c++/57325
+ * tree.c (build_cplus_array_type): Copy layout info if element
+ type is complete.
+
+2013-05-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/23608
+ * call.c (build_new_op_1): Propagate loc to cp_build_binary_op.
+
+2013-05-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/57317
+ * decl2.c (determine_visibility): Use PRIMARY_TEMPLATE_P to decide
+ whether a template has its own args.
+
+2013-05-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57327
+ * pt.c (unify_no_common_base): Swap arg and parm arguments to inform.
+
+2013-05-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/10207
+ * parser.c (cp_parser_postfix_expression): Use cp_parser_braced_list
+ instead of cp_parser_initializer_list for compound-literals.
+
+2013-05-20 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/57175
+ * typeck.c (check_return_expr): Reverse the alignment comparison.
+
+2013-05-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/18126
+ * parser.c (cp_parser_sizeof_operand): As a GNU Extension, parse
+ correctly sizeof compound-literal; update comments.
+
+2013-05-16 Marc Glisse <marc.glisse@inria.fr>
+
+ * call.c (build_conditional_expr_1): Use cp_build_binary_op
+ instead of directly calling fold_build2.
+
+2013-05-16 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (cc1plus$(exeext)): Use link mutex.
+
+ PR c++/57279
+ * decl.c (grokdeclarator): Allow member function qualifiers in
+ TYPENAME context in C++11 mode.
+
+2013-05-16 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/56782 - Regression with empty pack expansions
+ * pt.c (use_pack_expansion_extra_args_p): When at least a
+ parameter pack has an empty argument pack, and another parameter
+ pack has no argument pack at all, use the PACK_EXPANSION_EXTRA
+ mechanism.
+
+2013-05-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * name-lookup.c (pushdecl_maybe_friend_1): Replace pairs of
+ warning_at and permerror with warning_at/inform and permerror/
+ inform, respectively.
+
+2013-05-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/31952
+ * name-lookup.c (pushdecl_maybe_friend_1): Diagnose illegal
+ redeclarations.
+
+2013-05-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/57243
+ * parser.c (cp_parser_range_for): Call complete_type.
+
+ PR c++/57041
+ * pt.c (tsubst_copy_and_build): Don't recur into a designator.
+
+2013-05-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53903
+ * method.c (defaulted_late_check): Check for compatible exception
+ specification out of class explicitly defaulted functions too.
+
+2013-05-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/56998
+ * semantics.c (potential_constant_expression_1): Make sure the
+ called function is potentially constant.
+ * call.c (null_ptr_cst_p): Revert earlier change.
+
+2013-05-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/56998
+ * call.c (null_ptr_cst_p): An expression with side-effects can't
+ be a C++03 null pointer constant.
+
+ PR c++/57041
+ * decl.c (reshape_init_class): Handle error_mark_node.
+
+ PR c++/57254
+ * typeck.c (merge_types): Propagate ref-qualifier
+ in METHOD_TYPE case.
+
+ PR c++/57253
+ * decl.c (grokdeclarator): Apply ref-qualifier
+ in the TYPENAME case.
+
+ PR c++/57252
+ * decl.c (decls_match): Compare ref-qualifiers.
+
+2013-05-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/57196
+ * pt.c (convert_template_argument): Use dependent_template_arg_p,
+ not uses_template_parms.
+
+ PR c++/57047
+ * semantics.c (cxx_fold_indirect_ref): Fix thinko.
+
+ PR c++/55149
+ * semantics.c (add_capture): Error rather than abort on copy
+ capture of VLA.
+ * typeck.c (maybe_warn_about_returning_address_of_local): Don't
+ warn about capture proxy.
+
+2013-05-09 Jason Merrill <jason@redhat.com>
+
+ * decl.c (cp_finish_decl): Only check VLA bound in C++1y mode.
+
+ PR c++/57222
+ * pt.c (lookup_template_class_1): Handle getting a template
+ template parameter as D1.
+
+ N3639 C++1y VLA diagnostics
+ * decl.c (grokdeclarator): Complain about reference, pointer, or
+ typedef to VLA.
+ (create_array_type_for_decl): Complain about array of VLA.
+ * pt.c (tsubst): Likewise.
+ * rtti.c (get_tinfo_decl): Talk about "array of runtime bound".
+ * semantics.c (finish_decltype_type): Complain about decltype of VLA.
+ * typeck.c (cp_build_addr_expr_1): Complain about VLA.
+ (cxx_sizeof_or_alignof_type): Likewise.
+
+ N3639 C++1y VLA support
+ * decl.c (compute_array_index_type): Allow VLAs in C++1y mode.
+ (check_array_initializer): Allow VLA init.
+ (reshape_init_array_1): Adjust.
+ (cp_finish_decl): Check for invalid VLA length.
+ * typeck2.c (process_init_constructor_array): Adjust.
+ (store_init_value): Use build_vec_init for VLAs.
+ * semantics.c (add_capture): Capture VLA as ptr+len.
+ (vla_capture_type): New.
+ (build_capture_proxy): Rebuild the VLA.
+ * typeck.c (build_simple_component_ref): Split out from...
+ (build_ptrmemfunc_access_expr): ...here.
+ * tree.c (array_of_runtime_bound_p): New.
+ * init.c (throw_bad_array_length): New.
+ (build_vec_init): Use it.
+ * parser.c (cp_convert_range_for): When iterating over a VLA,
+ use it directly rather than bind a reference.
+ * cp-tree.h: Declare new functions.
+
+2013-05-08 Jason Merrill <jason@redhat.com>
+
+ * except.c (is_admissible_throw_operand_or_catch_parameter): Check
+ variably_modified_type_p.
+ (expand_start_catch_block): Mark the typeinfo used here.
+ * semantics.c (finish_handler_parms): Not here.
+
+ * error.c (dump_type_suffix): Try harder on VLA length.
+
+ Core 624/N2932
+ * init.c (throw_bad_array_new_length): New.
+ (build_new_1): Use it. Don't warn about braced-init-list.
+ (build_vec_init): Use it.
+ * call.c (build_operator_new_call): Use it.
+
+ PR c++/57068
+ * decl.c (grokdeclarator): Warn about ref-qualifiers here.
+ * parser.c (cp_parser_ref_qualifier_seq_opt): Not here.
+ * error.c (maybe_warn_cpp0x): s/0x/11/.
+
+2013-05-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51226
+ * parser.c (cp_parser_enum_specifier): Handle nested_name_specifier
+ == error_mark_node.
+
+2013-05-06 Marc Glisse <marc.glisse@inria.fr>
+
+ * typeck.c (cp_build_binary_op): Call save_expr before
+ build_vector_from_val.
+
+2013-05-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57183
+ * decl.c (cp_finish_decl): After do_auto_deduction copy the
+ qualifers with cp_apply_type_quals_to_decl.
+
+2013-05-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * pt.c (convert_nontype_argument): Add missing whitespace in
+ error message.
+
+2013-05-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53745
+ * decl.c (build_enumerator): Improve error message.
+
+2013-05-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/14283
+ * parser.c (cp_parser_diagnose_invalid_type_name): Improve error
+ messages for template types and fix column numbers.
+
+2013-05-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57132
+ * pt.c (tsubst_copy_and_build, MODOP_EXPR): Increase / decrease
+ c_inhibit_evaluation_warnings around build_x_modify_expr call.
+
+2013-05-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57092
+ * semantics.c (finish_decltype_type): Handle instantiated template
+ non-type arguments.
+
+2013-04-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56450
+ * semantics.c (finish_decltype_type): Handle COMPOUND_EXPR.
+
+2013-04-26 Jakub Jelinek <jakub@redhat.com>
+
+ * error.c (cp_print_error_function): Adjust file_name_as_prefix
+ caller.
+
+2013-04-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/56859
+ * typeck.c (cxx_alignas_expr): Handle value-dependence properly.
+
+ PR c++/50261
+ * init.c (perform_member_init): Call reshape_init.
+
+2013-04-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/53721
+ * parser.c (cp_parser_postfix_dot_deref_expression): Fix thinko.
+
+2013-04-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * typeck.c (cxx_sizeof_or_alignof_type): Change -Wpointer-arith
+ pedwarn to simply use OPT_Wpointer_arith.
+ (cp_build_unary_op): Likewise.
+
+2013-04-24 Jason Merrill <jason@redhat.com>
+
+ N3648: init-captures are named.
+ * semantics.c (add_capture): Don't prepend "__" to init-captures.
+ (build_capture_proxy): Adjust.
+ * error.c (dump_simple_decl): Check DECL_NORMAL_CAPTURE_P.
+
+ N3648: Allow braced and parenthesized initializers.
+ * parser.c (cp_parser_lambda_introducer): Use cp_parser_initializer.
+ * pt.c (tsubst) [DECLTYPE_TYPE]: Handle DECLTYPE_FOR_INIT_CAPTURE.
+ * semantics.c (lambda_capture_field_type): Use do_auto_deduction.
+ (add_capture): Collapse a parenthesized initializer into a single
+ expression.
+ * cp-tree.h (DECLTYPE_FOR_INIT_CAPTURE): New.
+
+2013-04-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56970
+ * init.c (build_offset_ref): Add tsubst_flags_t parameter.
+ * semantics.c (finish_qualified_id_expr): Likewise.
+ (finish_id_expression): Update.
+ * typeck.c (cp_build_addr_expr_1): Likewise.
+ * pt.c (tsubst_qualified_id, resolve_nondeduced_context): Likewise.
+ * cp-tree.h: Update declarations.
+
+2013-04-22 Jason Merrill <jason@redhat.com>
+
+ Core 1586
+ * parser.c (cp_parser_unqualified_id): Handle ~auto.
+ (cp_parser_pseudo_destructor_name): Likewise.
+ (cp_parser_postfix_dot_deref_expression): Adjust.
+ (cp_lexer_nth_token_is_keyword): New.
+ * semantics.c (finish_pseudo_destructor_expr): Handle ~auto.
+ * typeck.c (lookup_destructor): Handle ~auto.
+
+ * pt.c (fn_type_unification): Push tinst level around
+ type_unification_real if we aren't explaining.
+ * cp-tree.h (TFF_NO_TEMPLATE_BINDINGS): New.
+ * error.c (dump_function_decl): Respect it.
+ (subst_to_string): Pass it.
+
+ PR c++/48665
+ * rtti.c (get_typeid): Diagnose qualified function type.
+ * pt.c (tsubst) [POINTER_TYPE]: Likewise.
+
+ * error.c (dump_aggr_type): Fix lambda detection.
+ (dump_simple_decl): Pretty-print capture field.
+
+ N3323
+ * cvt.c (build_expr_type_conversion): Two conversions that return
+ the same type aren't necessarily ambiguous.
+
+ N3648
+ * parser.c (cp_parser_lambda_introducer): Make lambda capture init
+ pedwarn unconditional except in C++1y mode.
+
+ * semantics.c (potential_constant_expression_1): Don't crash on
+ 'this' in NSDMI.
+
+ Core 1612
+ * semantics.c (finish_id_expression): Reject capture of anonymous
+ union member.
+
+ Core 1609
+ * decl2.c (check_default_args): Check for pack expansion.
+
+ * mangle.c (write_type): Mangle decltype(auto).
+
+2013-04-19 Jason Merrill <jason@redhat.com>
+
+ N3638 changes to return type deduction
+ * decl.c (undeduced_auto_decl): New.
+ (require_deduced_type): New.
+ (fndecl_declared_return_type): New.
+ (decls_match): Use it.
+ (duplicate_decls): Don't check for auto return.
+ (grokdeclarator): Reject virtual auto.
+ * class.c (resolve_address_of_overloaded_function): Handle
+ auto function templates.
+ * decl2.c (mark_used): Use undeduced_auto_decl, require_deduced_type.
+ * cp-tree.h: Declare new fns.
+ * error.c (dump_function_decl): Use fndecl_declared_return_type.
+ * search.c (check_final_overrider): Likewise.
+ * pt.c (make_decltype_auto): New.
+ (do_auto_deduction): Require plain decltype(auto).
+ (is_auto): Adjust.
+
+ DR 941
+ * decl.c (duplicate_decls): Don't propagate DECL_DELETED_FN to
+ template specializations.
+
+2013-04-16 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ Implement n3599 - Literal operator templates for strings.
+ * parser.c (make_string_pack (tree value)): New function.
+ (cp_parser_userdef_string_literal (cp_token *)): Use it
+ to construct calls to character string literal operator templates.
+ (cp_parser_template_declaration_after_export): Check for new string
+ literal operator template parameter form.
+
+2013-04-15 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst) [DECLTYPE_TYPE]: Use tsubst_copy_and_build.
+
+ PR c++/52748
+ * pt.c (tsubst) [DECLTYPE_TYPE]: If ~id is an expression
+ rather than a destructor name, it isn't an unqualified-name.
+ (tsubst_copy_and_build): Pass down decltype_flag to operator
+ handling code, too.
+
+ PR c++/56388
+ * semantics.c (insert_capture_proxy): Just use index 1 in the
+ stmt_list_stack.
+
+2013-04-12 Jakub Jelinek <jakub@redhat.com>
+
+ * error.c (cp_print_error_function,
+ print_instantiation_partial_context_line,
+ maybe_print_constexpr_context): Colorize locus strings.
+
+2013-04-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/52748
+ * parser.c (complain_flags): New.
+ (cp_parser_postfix_expression): Use it.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_binary_expression): Likewise.
+ (cp_parser_assignment_expression): Likewise.
+ (cp_parser_expression): Likewise.
+ (cp_parser_postfix_open_square_expression): Take decltype_p.
+ (cp_parser_builtin_offsetof): Adjust.
+ (cp_convert_range_for): Pass complain to finish_unary_op_expr.
+ * decl2.c (grok_array_decl): Add decltype_p parm.
+ * cp-tree.h: Adjust prototype.
+ * semantics.c (finish_unary_op_expr): Add complain parm.
+
+2013-04-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/56895
+ * call.c (null_ptr_cst_p): Call fold_non_dependent_expr_sfinae before
+ calling maybe_constant_value for C++98.
+
+2013-04-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/56901
+ * semantics.c (lambda_capture_field_type, lambda_proxy_type):
+ Strip references before checking WILDCARD_TYPE_P.
+
+2013-04-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * call.c (build_conditional_expr_1, build_over_call): Protect
+ error calls with complain & tf_error.
+ * typeck.c (finish_class_member_access_expr, cp_build_binary_op,
+ build_x_unary_op, cp_build_unary_op, cp_build_compound_expr,
+ build_ptrmemfunc): Likewise.
+ (lookup_destructor): Take tsubst_flags_t parameter, adjust.
+
+ * cvt.c (warn_ref_binding): Rename to diagnose_ref_binding.
+ (convert_to_reference): Adjust.
+
+2013-04-11 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_copy) [VAR_DECL]: Don't call tsubst for
+ local variables, look them up instead.
+ (tsubst_decl) [VAR_DECL]: Remove handling for anonymous union
+ proxies and substitution in unevaluated context.
+ (tsubst_expr) [OMP_FOR]: Instantiate OMP_FOR_PRE_BODY
+ before the iterators.
+
+ PR c++/23055
+ * pt.c (uses_deducible_template_parms): New.
+ (deducible_array_bound, deducible_expression): New.
+ (deducible_template_args): New.
+ (unify_one_argument): Call uses_deducible_template_parms.
+
+2013-04-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56913
+ * typeck2.c (build_m_component_ref): Protect error calls with
+ (complain & tf_error).
+
+2013-04-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54216
+ * parser.c (cp_parser_enum_specifier): Check for empty
+ anonymous enums and anonymous scoped enums.
+
+2013-04-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/56895
+ * typeck.c (cp_build_binary_op): Call fold_non_dependent_expr_sfinae
+ first before calling maybe_constant_value for warn_for_div_by_zero
+ or invalid shift count warning purposes.
+
+2013-04-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/25466
+ * rtti.c (build_typeid): Check the address of the argument
+ rather than looking for an INDIRECT_REF.
+
+2013-04-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/56838
+ PR c++/17232
+ * typeck2.c (abstract_virtuals_error_sfinae): Disable
+ complete_type again.
+
+2013-04-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56871
+ * decl.c (validate_constexpr_redeclaration): Allow an explicit
+ specialization to be different wrt the constexpr specifier.
+
+2013-04-06 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_std_attribute): Treat [[noreturn]] like GNU
+ noreturn attribute.
+
+2013-04-05 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ * parser.c (cp_parser_ref_qualifier_seq_opt): Move to
+ cp_parser_ref_qualifier_opt. Error if more than one ref-qual found.
+
+2013-04-03 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (FUNCTION_OR_METHOD_TYPE_CHECK): Remove.
+ (TYPE_RAISES_EXCEPTIONS): Use FUNC_OR_METHOD_CHECK instead.
+ (FUNCTION_REF_QUALIFIED, FUNCTION_RVALUE_QUALIFIED): Likewise.
+
+ * mangle.c (write_type): When writing a function type with
+ function-cv-quals, don't add the unqualified type as a
+ substitution candidate.
+
+2013-04-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56815
+ * typeck.c (cp_build_unary_op): Change -Wpointer-arith permerror to
+ pedwarn.
+
+2013-04-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/56819
+ * tree.c (strip_typedefs): Copy NON_DEFAULT_TEMPLATE_ARGS_COUNT
+ from args to new_args.
+ (strip_typedefs_expr): Copy NON_DEFAULT_TEMPLATE_ARGS_COUNT from t to
+ r instead of doing {S,G}ET_NON_DEFAULT_TEMPLATE_ARGS_COUNT.
+
+2013-04-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/56821
+ * mangle.c (write_function_type): Mangle ref-qualifier.
+ (write_nested_name): Likewise.
+ (canonicalize_for_substitution): Preserve ref-qualifier.
+ (write_type): Likewise.
+
+ PR c++/34949
+ * decl.c (begin_destructor_body): Clobber the object in a cleanup.
+
+2013-04-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * friend.c (do_friend): Use COMPLETE_OR_OPEN_TYPE_P.
+ * pt.c (find_parameter_packs_r): Use TYPE_ALIAS_P and TYPE_TI_ARGS.
+ (for_each_template_parm_r): Use TYPE_TI_ARGS.
+
+2013-04-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cp-tree.h (TAGGED_TYPE_P): Remove.
+ (IS_OVERLOAD_TYPE): Rename to OVERLOAD_TYPE_P, adjust.
+ (TYPE_ANONYMOUS_P): Adjust.
+ * call.c (build_new_op_1): Likewise.
+ * class.c (find_abi_tags_r): Likewise.
+ * decl.c (warn_misplaced_attr_for_class_type, start_decl,
+ type_is_deprecated): Likewise.
+ * decl2.c (grokfield, min_vis_r): Likewise.
+ * pt.c (get_template_info): Likewise.
+ * tree.c (handle_abi_tag_attribute): Likewise.
+
+2013-04-01 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (maybe_constant_value): Check
+ instantiation_dependent_expression_p.
+ * pt.c (build_non_dependent_expr): Don't check it here.
+
+ PR c++/56772
+ * init.c (build_new): Don't try to process an array initializer
+ at template definition time.
+
+ PR c++/56793
+ * typeck.c (finish_class_member_access_expr): Handle enum scope.
+
+ PR c++/56794
+ * parser.c (cp_parser_range_for): Don't try to do auto deduction
+ in a template if the type of the range is incomplete.
+
+ * call.c (add_function_candidate): Take the address of 'this' here.
+ (build_over_call): And here.
+ (build_new_method_call_1, build_op_call_1): Not here.
+ (build_user_type_conversion_1): Or here.
+ (add_candidates): Adjust.
+
+ * cxx-pretty-print.h (pp_cxx_cv_qualifiers): New.
+ * class.c (same_signature_p): Use type_memfn_quals.
+ * cp-tree.h (TYPE_RAISES_EXCEPTIONS): Use
+ FUNCTION_OR_METHOD_TYPE_CHECK.
+ * error.c (dump_type_suffix): Add padding before cv-qualifiers.
+ * pt.c (unify): Use static_fn_type.
+
+2013-04-01 Bronek Kozicki <b.kozicki@gmail.com>
+ Jason Merrill <jason@redhat.com>
+
+ Implement N2439 (ref-qualifiers for 'this')
+ * cp-tree.h (FUNCTION_REF_QUALIFIED): New.
+ (FUNCTION_RVALUE_QUALIFIED): New.
+ (FUNCTION_OR_METHOD_TYPE_CHECK): New.
+ (cpp0x_warn_str): Add CPP0X_REF_QUALIFIER.
+ (cp_ref_qualifier): New enum.
+ (cp_declarator): Add ref_qualifier.
+ * parser.c (cp_parser_ref_qualifier_seq_opt): New.
+ (cp_parser_direct_declarator): Use it.
+ (make_call_declarator): Adjust.
+ (cp_parser_lambda_declarator_opt): Adjust.
+ * call.c (add_function_candidate): Handle ref-qualifier overload
+ resolution semantics.
+ (standard_conversion): Adjust.
+ * class.c (add_method, same_signature_p): Compare ref-qualifiers.
+ * decl.c (grokdeclarator): Handle ref-qualifiers.
+ (grokfndecl): Check for invalid ref-qualifiers.
+ (static_fn_type, revert_static_member_fn): Adjust.
+ * decl2.c (build_memfn_type): Handle ref-qualifiers.
+ (check_classfn): Check them.
+ (cp_reconstruct_complex_type): Retain them.
+ * error.c (dump_ref_qualifier): New.
+ (dump_type_suffix, dump_function_decl): Use it.
+ (maybe_warn_cpp0x): Handle CPP0X_REF_QUALIFIER.
+ * pt.c (tsubst, tsubst_function_type): Instantiate ref-quals.
+ (unify): Retain them.
+ * tree.c (cp_check_qualified_type): New.
+ (cp_build_qualified_type_real): Keep exception spec and ref-qual.
+ (build_ref_qualified_type): New.
+ (strip_typedefs, build_exception_variant): Keep ref-qualifier.
+ (cp_build_type_attribute_variant): Keep ref-qualifier.
+ * typeck.c (merge_types): Keep ref-qualifier.
+ (structural_comptypes): Compare ref-qualifier.
+ (type_memfn_rqual): New.
+ (apply_memfn_quals): Take ref-qual argument.
+ * typeck2.c (build_m_component_ref): Check ref-qualifier.
+
+2013-04-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cp-tree.h (DECL_UNBOUND_CLASS_TEMPLATE_P): Remove.
+ (DECL_FUNCTION_TEMPLATE_P): Adjust.
+
+ * cxx-pretty-print.c (pp_cxx_nested_name_specifier,
+ pp_cxx_qualified_id): Use get_containing_scope.
+ * parser.c (cp_parser_class_head): Likewise.
+ * pt.c (push_template_decl_real): Likewise.
+
+ * decl2.c (import_export_decl): Use DECL_TEMPLOID_INSTANTIATION.
+ * pt.c (unify): Use CP_INTEGRAL_TYPE_P.
+
+2013-03-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl2.c (collect_candidates_for_java_method_aliases): Use
+ DECL_CLASS_SCOPE_P.
+ * name-lookup.c (pushtag_1) Use TYPE_FUNCTION_SCOPE_P.
+ (pushdecl_maybe_friend_1): Use DECL_DECLARES_FUNCTION_P.
+ * decl.c (duplicate_decls): Likewise.
+ * parser.c (cp_parser_template_declaration_after_export): Likewise,
+ also DECL_DECLARES_TYPE_P.
+ * pt.c (instantiate_class_template_1): Likewise.
+ * search.c (lookup_field_1): Use DECL_DECLARES_TYPE_P.
+ (lookup_field_r): Likewise.
+ (friend_accessible_p): Use DECL_DECLARES_FUNCTION_P.
+ (lookup_fnfields_slot_nolazy): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+ * typeck.c (convert_for_initialization): Use TYPE_REFFN_P.
+
+2013-03-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pt.c (template_parms_to_args): Fix typo in comment.
+
+2013-03-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * call.c (build_op_call_1): Use TYPE_PTRFN_P and TYPE_REFFN_P.
+
+2013-03-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * call.c (add_builtin_candidate): Use TYPE_PTR_P and VOID_TYPE_P.
+ (build_op_call_1): Likewise.
+ (build_over_call): Likewise.
+ (compare_ics): Likewise.
+ * class.c (build_base_path): Likewise.
+ (resolve_address_of_overloaded_function): Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_reference): Likewise.
+ (ocp_convert): Likewise.
+ (convert_force): Likewise, tidy.
+ * cxx-pretty-print.c (pp_cxx_postfix_expression): Likewise.
+ (pp_cxx_ptr_operator): Likewise.
+ * decl.c (duplicate_decls): Likewise.
+ (start_decl): Likewise.
+ (grok_op_properties): Likewise.
+ (start_preparsed_function): Likewise.
+ (store_parm_decls): Likewise.
+ (finish_function): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+ (acceptable_java_type): Likewise.
+ (grokbitfield): Likewise.
+ (cp_reconstruct_complex_type): Likewise.
+ * error.c (dump_type_prefix): Likewise.
+ (dump_expr): Likewise.
+ * except.c (push_eh_cleanup): Likewise.
+ (complete_ptr_ref_or_void_ptr_p): Likewise.
+ (can_convert_eh): Likewise.
+ * init.c (build_new_1): Likewise.
+ (build_delete): Likewise.
+ (build_vec_delete): Likewise.
+ * mangle.c (write_type): Likewise.
+ * parser.c (lookup_literal_operator): Likewise.
+ * pt.c (convert_nontype_argument_function): Likewise.
+ (convert_nontype_argument): Likewise.
+ (tsubst): Likewise.
+ (unify): Likewise.
+ (dependent_type_p_r): Likewise.
+ * rtti.c (build_headof): Likewise.
+ (build_typeid): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ (target_incomplete_p): Likewise.
+ (typeinfo_in_lib_p): Likewise.
+ * semantics.c (finish_omp_for): Likewise.
+ (cxx_eval_call_expression): Likewise.
+ (maybe_resolve_dummy): Likewise.
+ * tree.c (build_target_expr): Likewise.
+ (cp_build_qualified_type_real): Likewise.
+ * typeck.c (composite_pointer_type_r): Likewise.
+ (composite_pointer_type): Likewise.
+ (comp_except_types): Likewise.
+ (cxx_sizeof_nowarn): Likewise.
+ (string_conv_p): Likewise.
+ (cp_build_array_ref): Likewise.
+ (cp_build_function_call_vec): Likewise, also use TYPE_PTRFN_P.
+ (pointer_diff): Likewise.
+ (cp_build_addr_expr_1): Likewise.
+ (cp_build_unary_op): Likewise.
+ (build_static_cast_1): Likewise.
+ (cp_build_c_cast): Likewise.
+ (comp_ptr_ttypes_real): Likewise.
+ (ptr_reasonably_similar): Likewise.
+ (comp_ptr_ttypes_const): Likewise.
+ (casts_away_constness): Likewise.
+ (check_literal_operator_args): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+ (add_exception_specifier): Likewise.
+
+2013-03-29 Jason Merrill <jason@redhat.com>
+
+ N3582
+ * cp-tree.h (AUTO_IS_DECLTYPE): New.
+ * parser.c (cp_parser_decltype): Handle decltype(auto).
+ (cp_parser_type_id_1): Allow auto without a late-specified
+ return in C++1y.
+ (cp_parser_primary_expression): Use the return value of
+ finish_parenthesized_expr.
+ (cp_parser_transaction_expression): Likewise.
+ * semantics.c (force_paren_expr): New.
+ (finish_parenthesized_expr): Use it.
+ * call.c (build_conditional_expr_1): Likewise.
+ * pt.c (do_auto_deduction): Handle decltype(auto).
+ (tsubst_copy): Handle PAREN_EXPR.
+ (tsubst_copy_and_build): Likewise.
+ * error.c (dump_expr): Handle PAREN_EXPR.
+ * cxx-pretty-print.c (pp_cxx_expression): Likewise.
+ * mangle.c (write_expression): Ignore PAREN_EXPR.
+
+ * parser.c (cp_parser_decltype_expr): Split out...
+ (cp_parser_decltype): ...from here.
+
+ PR c++/56774
+ PR c++/35722
+ * pt.c (unify_pack_expansion): Fix indexing.
+
+2013-03-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * call.c (build_java_interface_fn_ref): Likewise.
+ (make_temporary_var_for_ref_to_temp): Likewise.
+ * class.c (check_field_decls): Likewise.
+ (layout_class_type): Likewise.
+ (finish_struct_1): Likewise.
+ (fixed_type_or_null): Likewise.
+ (get_vtbl_decl_for_binfo): Likewise.
+ * cp-gimplify.c (omp_var_to_track): Likewise.
+ (cp_genericize_r): Likewise.
+ * cp-objcp-common.c (cxx_warn_unused_global_decl): Likewise.
+ * cp-tree.h (LANG_DECL_HAS_MIN): Likewise.
+ (DECL_DISCRIMINATOR_P): Likewise.
+ * decl.c (poplevel): Likewise.
+ (decls_match): Likewise.
+ (duplicate_decls): Likewise.
+ (decl_jump_unsafe): Likewise.
+ (start_decl): Likewise.
+ (check_for_uninitialized_const_var): Likewise.
+ (make_rtl_for_nonlocal_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (expand_static_init): Likewise.
+ (local_variable_p): Likewise.
+ (maybe_register_incomplete_var): Likewise.
+ * decl2.c (grokfield): Likewise.
+ (comdat_linkage): Likewise.
+ (determine_visibility): Likewise.
+ (import_export_decl): Likewise.
+ (prune_vars_needing_no_initialization): Likewise.
+ (decl_maybe_constant_var_p): Likewise.
+ * error.c (dump_simple_decl): Likewise.
+ (dump_template_decl): Likewise.
+ (cp_printer): Likewise.
+ * except.c (build_throw): Likewise.
+ * init.c (build_vtbl_address): Likewise.
+ (member_init_ok_or_else): Likewise.
+ (build_aggr_init): Likewise.
+ (expand_aggr_init_1): Likewise.
+ (build_offset_ref): Likewise.
+ (constant_value_1): Likewise.
+ * mangle.c (write_mangled_name): Likewise.
+ (write_prefix): Likewise.
+ * name-lookup.c (supplement_binding_1): Likewise.
+ (add_decl_to_level): Likewise.
+ (pushdecl_maybe_friend_1): Likewise.
+ (check_for_out_of_scope_variable): Likewise.
+ (validate_nonmember_using_decl): Likewise.
+ (lookup_name_innermost_nonclass_level_1): Likewise.
+ (lookup_arg_dependent_1): Likewise.
+ * parser.c (cp_parser_lambda_introducer): Likewise.
+ (cp_parser_template_argument): Likewise.
+ (cp_parser_single_declaration): Likewise.
+ * pt.c (convert_nontype_argument): Likewise.
+ (instantiate_class_template_1): Likewise.
+ (tsubst_decl): Likewise.
+ (tsubst_expr): Likewise.
+ (do_decl_instantiation): Likewise.
+ (do_type_instantiation): Likewise.
+ (regenerate_decl_from_template): Likewise.
+ (always_instantiate_p): Likewise.
+ (instantiate_decl): Likewise.
+ (type_dependent_expression_p): Likewise.
+ (build_non_dependent_expr): Likewise.
+ * repo.c (repo_emit_p): Likewise.
+ * rtti.c (build_dynamic_cast_1): Likewise.
+ * search.c (shared_member_p): Likewise.
+ * semantics.c (outer_var_p): Likewise.
+ (finish_id_expression): Likewise.
+ (finish_omp_clauses): Likewise.
+ (finish_decltype_type): Likewise.
+ (ensure_literal_type_for_constexpr_object): Likewise.
+ * tree.c (lvalue_kind): Likewise.
+ (bot_replace): Likewise.
+ (cp_tree_equal): Likewise.
+ (handle_init_priority_attribute): Likewise.
+ (decl_storage_duration): Likewise.
+ * typeck.c (cxx_sizeof_expr): Likewise.
+ (cxx_alignof_expr): Likewise.
+ (decay_conversion): Likewise.
+ (build_class_member_access_expr): Likewise.
+ (cp_build_array_ref): Likewise.
+ (cxx_mark_addressable): Likewise.
+ (maybe_warn_about_returning_address_of_local): Likewise.
+ (check_return_expr): Likewise.
+ * typeck2.c (cxx_readonly_error): Likewise.
+ (abstract_virtuals_error_sfinae): Likewise.
+ (cxx_incomplete_type_diagnostic): Likewise.
+
+2013-03-28 Lawrence Crowl <crowl@google.com>
+
+ * Make-lang.in
+ (CXX_PARSER_H): Add header dependence.
+ * cp-tree.h
+ (extern debug (cp_binding_level &)): New.
+ (extern debug (cp_binding_level *)): New.
+ * name-lookup.h
+ (debug (cp_binding_level &)): New.
+ (debug (cp_binding_level *)): New.
+ * parser.c
+ (debug (cp_parser &)): New.
+ (debug (cp_parser *)): New.
+ (debug (cp_token &)): New.
+ (debug (cp_token *)): New.
+ (debug (vec<cp_token, va_gc> &)): New.
+ (debug (vec<cp_token, va_gc> *)): New.
+ * parser.c: Add header dependence.
+ (extern debug (cp_parser &)): New.
+ (extern debug (cp_parser *)): New.
+ (extern debug (cp_token &)): New.
+ (extern debug (cp_token *)): New.
+ (extern debug (vec<cp_token, va_gc> &)): New.
+ (extern debug (vec<cp_token, va_gc> *)): New.
+
+2013-03-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/17232
+ PR c++/52748
+ * typeck2.c (abstract_virtuals_error_sfinae): Don't complete
+ the type if tf_decltype is set.
+ * pt.c (fn_type_unification): Add decltype_p parm.
+ (get_bindings): Adjust.
+ * cp-tree.h: Adjust.
+ * class.c (resolve_address_of_overloaded_function): Adjust.
+ * call.c (add_template_candidate_real, print_z_candidate): Adjust.
+
+ PR c++/56679
+ * parser.c (cp_parser_sizeof_pack): Split out from...
+ (cp_parser_sizeof_operand): ...here. Require (id).
+
+ PR c++/56701
+ * semantics.c (finish_this_expr): 'this' is an rvalue.
+ * typeck.c (cp_build_indirect_ref): Handle NOP_EXPR of 'this'.
+
+ PR c++/56710
+ * semantics.c (finish_member_declaration): Don't push closure
+ members.
+
+ * name-lookup.c (pushdecl_maybe_friend_1): Use
+ nonlambda_method_basetype and current_nonlambda_class_type.
+
+ PR c++/56728
+ * semantics.c (potential_constant_expression_1) [NOP_EXPR]: Reject
+ conversion from integer to pointer.
+ (cxx_eval_constant_expression): Likewise.
+ (cxx_eval_indirect_ref): Use the folded operand if we still think
+ this might be constant.
+
+2013-03-28 Paolo Carlini <paolo.carlini@oracle.com>
+ Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c++/56725
+ * call.c (convert_like_real): Change series of two permerrors
+ to permerror + inform (and likewise for two errors).
+ (build_new_method_call_1): Likewise.
+ * typeck.c (convert_for_initialization): Change additional
+ warning or error to inform.
+
+2013-03-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (next_aggr_init_expr_arg): Remove static specifier.
+ (first_aggr_init_expr): Likewise.
+ (more_aggr_init_expr_args_p): Likewise.
+ (type_of_this_parm): Likewise.
+ (class_of_this_parm): Likewise.
+ * name-lookup.h (get_global_value_if_present): Likewise.
+ (is_typename_at_global_scope): Likewise.
+
+2013-03-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * call.c (joust): Don't call inform for a permerror returning false.
+ * parser.c (cp_parser_check_class_key): Likewise.
+ * pt.c (tsubst_copy_and_build): Likewise.
+
+2013-03-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/56749
+ * semantics.c (finish_qualified_id_expr): Return early
+ for enum scope.
+
+2013-03-26 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * call.c (build_new_method_call_1): Use INDIRECT_REF_P.
+ * cvt.c (convert_to_void): Likewise.
+ * error.c (dump_expr): Likewise.
+ * mangle.c (write_expression): Likewise.
+ * parser.c (cp_parser_template_argument): Likewise.
+ * pt.c (convert_nontype_argument): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ * rtti.c (build_typeid): Likewise.
+ * semantics.c (finish_call_expr): Likewise.
+ (finish_decltype_type): Likewise.
+ (build_data_member_initialization): Likewise.
+ * tree.c (is_dummy_object): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+ (build_class_member_access_expr): Likewise.
+ (cp_build_addr_expr_1): Likewise.
+ (unary_complex_lvalue): Likewise.
+ (check_return_expr): Likewise.
+ * typeck2.c (cxx_readonly_error): Likewise.
+
+2013-03-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/52597
+ * typeck.c (invalid_nonstatic_memfn_p): Use get_first_fn. Take tree.
+ * semantics.c (finish_decltype_type): Check it before type_unknown_p.
+ * cp-tree.h: Adjust prototype.
+
+ PR c++/45282
+ * typeck2.c (build_m_component_ref): Handle prvalue object.
+
+2013-03-26 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-gimplify.c (cp_genericize_r): Use VAR_OR_FUNCTION_DECL_P.
+ * decl.c (duplicate_decls): Likewise.
+ (cp_finish_decl): Likewise.
+ (check_class_member_definition_namespace): Likewise.
+ * decl2.c (grokfield): Likewise.
+ (decl_needed_p): Likewise.
+ (import_export_decl): Likewise.
+ (mark_used): Likewise.
+ * name-lookup.c (pushdecl_maybe_friend_1): Likewise.
+ * pt.c (push_access_scope): Likewise.
+ (instantiate_decl): Likewise.
+ * ptree.c (cxx_print_decl): Likewise.
+ * repo.c (repo_emit_p): Likewise.
+ * semantics.c (note_decl_for_pch): Likewise.
+ * tree.c (decl_linkage): Likewise.
+
+2013-03-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/55951
+ * decl.c (check_array_designated_initializer): Handle CONST_DECL
+ as ce->index.
+
+2013-03-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (grokfndecl): Handle separately <inline> and <constexpr>
+ error messages.
+
+ * decl.c (grokdeclarator): Declare typedef_p and use it everywhere.
+
+2013-03-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/56699
+ * semantics.c (maybe_resolve_dummy): Make sure that the enclosing
+ class is derived from the type of the object.
+
+ PR c++/52014
+ * semantics.c (lambda_expr_this_capture): Don't capture 'this' in
+ unevaluated context.
+
+2013-03-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56722
+ * decl.c (cp_finish_decl): Check DECL_LANG_SPECIFIC before
+ DECL_TEMPLATE_INSTANTIATION.
+
+2013-03-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/56684
+ * pt.c (instantiation_dependent_r): Check DECL_INITIAL of VAR_DECL
+ and CONST_DECL.
+
+2013-03-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (identifier_p): New.
+ * call.c: Throughout, call identifier_p insstead of direct
+ comparaison of TREE_CODE against IDENTIFIER_NODE.
+ * decl.c: Likewisse.
+ * decl2.c: Likewise.
+ * init.c: Likewise.
+ * mangle.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2013-03-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/48087
+ * pt.c (convert_nontype_argument): Count werrorcount as warnings.
+ * call.c (build_temp): Likewise.
+ * method.c (synthesize_method): Likewise.
+ * typeck.c (convert_for_initialization): Likewise.
+
+2013-03-21 Marc Glisse <marc.glisse@inria.fr>
+
+ * call.c (build_conditional_expr_1): Fold VEC_COND_EXPR.
+
+2013-03-21 Richard Biener <rguenther@suse.de>
+
+ * error.c (cp_printer): Use DECL_HAS_DEBUG_EXPR_P instead of
+ DECL_DEBUG_EXPR_IS_FROM. Guard properly.
+
+2013-03-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/56646
+ * parser.c (cp_parser_late_return_type_opt): Save and restore
+ current_class_ptr/ref.
+
+ PR c++/54532
+ * expr.c (cplus_expand_constant): Do nothing if the class is
+ incomplete.
+ * semantics.c (reduced_constant_expression_p): Allow PTRMEM_CST.
+ * typeck2.c (store_init_value): Use reduced_constant_expression_p.
+ * decl.c (maybe_register_incomplete_var): Handle PTRMEM_CST.
+ (complete_vars): Likewise.
+
+ * name-lookup.c (get_anonymous_namespace_name): Never use
+ get_file_function_name.
+
+ * pt.c (retrieve_specialization): Handle null tmpl argument.
+
+ PR c++/17232
+ PR c++/56642
+ * pt.c (tsubst_decl): Check return value of register_specialization.
+ * typeck2.c (abstract_virtuals_error_sfinae): Re-apply complete_type
+ change.
+
+2013-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/54359
+ PR c++/56639
+ * parser.c (cp_parser_direct_declarator): Bail if we see a
+ qualified-id not at namespace scope.
+
+ PR c++/17232
+ PR c++/56642
+ * typeck2.c (abstract_virtuals_error_sfinae): Revert complete_type
+ change for now.
+
+2013-03-16 Jason Merrill <jason@redhat.com>
+
+ * decl.c (grokdeclarator): Assert that we won't see a pointer to
+ METHOD_TYPE.
+
+ PR c++/54277
+ * cp-tree.h (WILDCARD_TYPE_P): Split out from...
+ (MAYBE_CLASS_TYPE_P): ...here.
+ * semantics.c (lambda_capture_field_type): Only build a
+ magic decltype for wildcard types.
+ (lambda_proxy_type): Likewise.
+ (finish_non_static_data_member): Get the quals from
+ the object.
+
+ PR c++/55931
+ * parser.c (cp_parser_template_argument): Don't
+ fold_non_dependent_expr.
+
+ * parser.c (cp_parser_lambda_declarator_opt): Use
+ cp_parser_trailing_type_id.
+
+ PR c++/45917
+ * parser.c (cp_parser_template_id): Don't forget access checks.
+
+ PR c++/52374
+ * pt.c (tsubst_qualified_id): Use current_nonlambda_class_type.
+
+ PR c++/54764
+ PR c++/55972
+ * name-lookup.h (tag_scope): Add ts_lambda.
+ * semantics.c (begin_lambda_type): Use it.
+ * decl.c (xref_tag_1): Set CLASSTYPE_LAMBDA_EXPR.
+ * pt.c (check_default_tmpl_args): Ignore lambdas.
+ (push_template_decl_real): Handle lambdas.
+ * tree.c (no_linkage_check): Adjust lambda check.
+
+ PR c++/56039
+ * tree.c (strip_typedefs_expr): Complain about lambda, don't abort.
+
+ PR c++/54359
+ * parser.c (cp_parser_direct_declarator): Fix late return
+ for out-of-class defn of member function.
+
+ PR c++/55357
+ * semantics.c (maybe_add_lambda_conv_op): Clear DECL_NAME of copied
+ parms to avoid duplicate -Wshadow warnings.
+
+ * search.c (lookup_base): Handle NULL_TREE.
+
+ PR c++/56481
+ * semantics.c (potential_constant_expression_1): Use of 'this' in
+ a non-constexpr function makes the expression not potentially
+ constant.
+
+ N3276
+ PR c++/52748
+ * cp-tree.h (tsubst_flags): Add tf_decltype.
+ * call.c (build_cxx_call): Don't build a temporary if it's set.
+ (build_over_call): Make sure it's only passed to build_cxx_call.
+ * parser.c (cp_parser_primary_expression): Add decltype_p parm.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_binary_expression): Likewise.
+ (cp_parser_assignment_expression): Likewise.
+ (cp_parser_postfix_expression): Likewise. Pass tf_decltype.
+ (cp_parser_expression): Add decltype_p. Force a
+ temporary for a call on the LHS of a comma.
+ (cp_parser_decltype): Pass true to decltype_p parms.
+ * pt.c (tsubst) [DECLTYPE_TYPE]: Pass tf_decltype.
+ (tsubst_copy_and_build): Pass tf_decltype down only for
+ CALL_EXPR and the RHS of COMPOUND_EXPR.
+ * tree.c (build_cplus_new): Call complete_type_or_maybe_complain.
+
+ * cp-tree.h (abstract_class_use): New enum.
+ * typeck2.c (pending_abstract_type): Add use field.
+ (abstract_virtuals_error_sfinae): Add overloads taking
+ abstract_class_use instead of tree.
+ * typeck.c (build_static_cast_1): Call it.
+ * except.c (is_admissible_throw_operand_or_catch_parameter): Call it.
+ * pt.c: Adjust calls.
+ * decl.c (cp_finish_decl): Don't handle functions specially.
+ (grokdeclarator): Always check return type.
+ * init.c (build_new_1): Adjust call.
+
+ DR 337
+ PR c++/17232
+ * pt.c (tsubst) [ARRAY_TYPE]: Use abstract_virtuals_error_sfinae.
+ * typeck2.c (abstract_virtuals_error_sfinae): Call complete_type.
+
+ DR 657
+ * pt.c (tsubst_function_type): Call abstract_virtuals_error_sfinae.
+ (tsubst_arg_types): Likewise.
+
+ DR 1518
+ PR c++/54835
+ * call.c (convert_like_real): Check for explicit constructors
+ even for value-initialization.
+
+ PR c++/54946
+ * pt.c (convert_nontype_argument): Handle invalid pointer.
+
+ * parser.c (cp_parser_lambda_expression): Use nreverse.
+
+ PR c++/56447
+ PR c++/55532
+ * pt.c (instantiate_class_template_1): Instantiate lambda capture
+ list here.
+ (tsubst_copy_and_build): Not here.
+
+ PR c++/55017
+ * method.c (walk_field_subobs): Disallow copy of rvalue ref.
+
+ PR c++/55240
+ * parser.c (parsing_nsdmi): New.
+ * semantics.c (outer_automatic_var_p): Check it.
+ (finish_id_expression): Likewise.
+ * cp-tree.h: Declare it.
+
+ PR c++/55241
+ * error.c (dump_expr) [SIZEOF_EXPR]: Print sizeof... properly.
+
+ * parser.c (lookup_literal_operator): Correct parm/arg naming
+ mixup.
+
+ PR c++/56238
+ * pt.c (fold_non_dependent_expr_sfinae): Check
+ instantiation_dependent_expression_p.
+
+ PR c++/56095
+ * class.c (resolve_address_of_overloaded_function): Accept a
+ reference to function for target_type.
+ (instantiate_type): Likewise.
+ * pt.c (convert_nontype_argument): Pass it to
+ convert_nontype_argument_function.
+
+2013-03-16 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.c (cp_tree_equal): Fix a pasto.
+
+ PR c++/56607
+ * typeck.c (cp_build_binary_op): When calling warn_for_div_by_zero,
+ pass op1 through maybe_constant_value first.
+
+2013-03-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56582
+ * semantics.c (cxx_eval_array_reference): Check for negative index.
+
+2013-03-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/56614
+ * decl.c (local_variable_p_walkfn): Check DECL_ARTIFICIAL again.
+
+ PR c++/56346
+ * decl.c (register_dtor_fn): Pass null to __cxa_thread_atexit
+ dso_handle parm on targets without __cxa_atexit.
+
+2013-03-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/56567
+ * typeck.c (check_return_expr): Disallow returning init list here.
+ * semantics.c (apply_deduced_return_type): Not here.
+
+2013-03-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51412
+ * cxx-pretty-print.c (pp_cxx_expression): Handle LAMBDA_EXPR.
+ * error.c (dump_expr): Likewise.
+
+2013-03-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/51884
+ * class.c (modify_all_vtables): Mangle the vtable name before
+ entering dfs_walk.
+
+ * semantics.c (lambda_expr_this_capture): In unevaluated context,
+ just return the nearest 'this'.
+
+ PR c++/51494
+ PR c++/52183
+ PR c++/56222
+ * tree.c (maybe_dummy_object): Don't capture 'this'.
+ * semantics.c (maybe_resolve_dummy): New.
+ (finish_non_static_data_member): Use it.
+ (finish_qualified_id_expr): Don't test is_dummy_object.
+ * cp-tree.h: Declare maybe_resolve_dummy.
+ * call.c (build_new_method_call_1): Use it.
+
+ PR c++/56567
+ * semantics.c (apply_deduced_return_type): Don't allow returning
+ std::initializer_list.
+
+2013-03-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56534
+ * parser.c (cp_parser_elaborated_type_specifier): Don't call
+ check_elaborated_type_specifier when TREE_CODE (decl) != TYPE_DECL.
+ * decl.c (check_elaborated_type_specifier): Tidy.
+
+2013-03-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/56543
+ * tree.c (strip_typedefs): Don't copy args if they are NULL.
+
+2013-03-05 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_braced_list): For {} initialize
+ *non_constant_p to false.
+
+2013-03-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/56464
+ PR c++/54383
+ * semantics.c (lambda_expr_this_capture): Handle NSDMI
+ and non-class scopes.
+
+2013-03-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (grokdeclarator): Remove dead code.
+
+2013-02-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/56481
+ * semantics.c (potential_constant_expression_1): Use
+ cxx_eval_outermost_constant_expr rather than maybe_constant_value.
+
+ PR c++/56243
+ * call.c (build_over_call): Avoid virtual lookup in a template.
+
+2013-02-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/56358
+ PR c++/56323
+ * name-lookup.c (do_class_using_decl): Use ctor_identifier instead
+ of the base name for inheriting ctors.
+ (push_class_level_binding_1): Remove inheriting ctor handling.
+ * pt.c (tsubst_decl) [USING_DECL]: Likewise.
+ * class.c (add_implicitly_declared_members): Adjust.
+
+2013-02-26 David Binderman <dcb314@hotmail.com>
+
+ PR c++/55632
+ * decl.c (grokdeclarator): Tidy publicp assignment.
+
+2013-02-25 Aldy Hernandez <aldyh@redhat.com>
+
+ PR c++/56419
+ * semantics.c (begin_transaction_stmt): Set TREE_SIDE_EFFECTS.
+ (build_transaction_expr): Same.
+
+2013-02-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/56377
+ * pt.c (fn_type_unification): Wait to call push_tinst_level until
+ we know what args we're looking at.
+
+ PR c++/56438
+ * semantics.c (potential_constant_expression_1): In C++98, a cast
+ to non-integral type can't be a constant expression.
+
+2013-02-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/56403
+ * init.c (build_zero_init_1): Use RECORD_OR_UNION_CODE_P instead
+ of CLASS_TYPE_P.
+
+2013-02-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/40405
+ * pt.c (push_template_decl_real): Set DECL_INTERFACE_KNOWN
+ if we got the wrong number of template parms.
+
+ PR c++/56377
+ * pt.c (fn_type_unification): Use explicit args in template
+ instantiation context.
+
+ PR c++/56359
+ * call.c (can_convert_arg): Discard access checks.
+
+ PR c++/56395
+ * tree.c (strip_typedefs): Strip typedefs from TYPENAME_TYPE template
+ args.
+
+2013-02-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56373
+ * tree.c (maybe_warn_zero_as_null_pointer_constant): Add.
+ * cvt.c (ocp_convert): Use the latter.
+ (cp_convert_to_pointer): Likewise.
+ * decl.c (check_default_argument): Likewise.
+ * typeck.c (cp_build_binary_op): Likewise.
+ * cp-tree.h (maybe_warn_zero_as_null_pointer_constant): Declare.
+
+2013-02-15 Jonathan Wakely <jwakely.gcc@gmail.com>
+ Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51242
+ * decl2.c (grokbitfield): Allow scoped enumeration types.
+
+2013-02-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/54276
+ * semantics.c (finish_id_expression): Also return the identifier
+ for an outer local static.
+
+ PR c++/56343
+ * class.c (check_bases_and_members): Deduce noexcept after
+ checking bases.
+
+ PR c++/52026
+ * semantics.c (finish_id_expression): In a template, return
+ the identifier for a constant variable.
+
+2013-02-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/54922
+ * semantics.c (build_anon_member_initialization): New.
+ (build_data_member_initialization): Use it.
+
+ PR c++/55003
+ * decl.c (cp_finish_decl): Force instantiation of an
+ auto static data member.
+
+ PR c++/55220
+ * pt.c (unify): A pack expansion that is not the last template
+ argument makes the entire template argument list non-deduced.
+
+ PR c++/56323
+ * name-lookup.c (do_class_using_decl): Handle typedefs with
+ inheriting constructors.
+ (push_class_level_binding_1): Allow inheriting from template
+ template parameter, too.
+ * pt.c (tsubst_decl) [USING_DECL]: Likewise.
+
+ PR c++/55223
+ * pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Fix handling of
+ default argument scope.
+ * mangle.c (write_name): Likewise.
+
+ PR c++/55232
+ * error.c (find_typenames_r): Don't walk into a pack expansion.
+
+2013-02-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/55670
+ * parser.c (cp_parser_member_declaration): Check the declarator
+ form when detecting a function declaration via typedef.
+
+ PR c++/55680
+ * pt.c (maybe_process_partial_specialization): A lambda
+ isn't what's being specialized.
+
+ PR c++/55710
+ * semantics.c (maybe_add_lambda_conv_op): Mark static thunk
+ TREE_USED.
+
+ PR c++/55879
+ * semantics.c (cxx_bind_parameters_in_call): Undo DECL_BY_REFERENCE.
+
+ PR c++/55993
+ * semantics.c (cxx_fold_indirect_ref): Handle empty bases at
+ non-zero offsets, too.
+
+ PR c++/56155
+ * decl.c (build_enumerator): Always convert the value to a
+ fixed underlying type.
+
+ PR c++/56135
+ * pt.c (tsubst_copy_and_build): Don't forget any new
+ captures that arose from use of dependent names.
+
+2013-02-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/56302
+ * semantics.c (finish_asm_stmt): If input constraints allow
+ neither register nor memory, try maybe_constant_value to get
+ a constant if possible.
+
+2013-02-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/56285
+ * method.c (add_one_base_init): Handle base constructor
+ taking rvalue reference parm.
+
+ PR c++/56291
+ * semantics.c (sort_constexpr_mem_initializers): Handle
+ vptr out of order.
+
+2013-02-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/56268
+ * semantics.c (classtype_has_nothrow_assign_or_copy_p): Call
+ maybe_instantiate_noexcept.
+
+ PR c++/56247
+ * pt.c (eq_specializations): Set comparing_specializations.
+ * tree.c (cp_tree_equal): Check it.
+ * cp-tree.h: Declare it.
+
+ * decl.c (decls_match): Check versions later.
+
+ PR c++/56238
+ * pt.c (build_non_dependent_expr): Don't try to fold
+ instantiation-dependent expressions.
+ (instantiation_dependent_r) [TRAIT_EXPR]: Split out.
+ [BIND_EXPR]: Treat as dependent.
+
+2013-02-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/56241
+ * init.c (build_vec_init): Don't append NULL values into new_vec.
+ (build_zero_init_1): Don't push anything into v if recursive call
+ returned NULL_TREE.
+ (build_value_init_noctor): Don't push anything into v if
+ build_value_init call returned NULL_TREE.
+
+ PR c++/56239
+ * parser.c (cp_parser_token_starts_cast_expression): Renamed to...
+ (cp_parser_tokens_start_cast_expression): ... this. Change parameter
+ to cp_parser *, call cp_lexer_peek_token first. For CPP_OPEN_PAREN,
+ return true only if 2nd token isn't CPP_CLOSE_PAREN.
+ (cp_parser_cast_expression): Adjust caller.
+
+ PR c++/56237
+ * decl.c (push_local_name): Look at DECL_DISCRIMINATOR (t)
+ only if DECL_DISCRIMINATOR_SET_P (t) rather than just
+ DECL_LANG_SPECIFIC (t).
+
+2013-02-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/56235
+ * method.c (do_build_copy_constructor): Don't bother turning
+ scalars from lvalues to xvalues.
+ (do_build_copy_assign): Likewise.
+
+2013-02-06 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_enum_specifier): Check for error_mark_node.
+
+2013-02-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/54122
+ * tree.c (lvalue_kind) [INDIRECT_REF]: Don't check for
+ METHOD_TYPE.
+
+ PR c++/56177
+ * decl.c (start_preparsed_function): Update restype if we change
+ decl1.
+
+ PR c++/56208
+ * pt.c (fn_type_unification): Discard any access checks from
+ substituting explicit args.
+
+2013-01-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/56162
+ PR c++/56104
+ * typeck.c (get_member_function_from_ptrfunc): Fix
+ ptrmemfunc_vbit_in_delta case.
+
+2013-01-29 Jason Merrill <jason@redhat.com>
+
+ PR libstdc++/54314
+ * class.c (build_ctor_vtbl_group): Give construction vtables
+ hidden visibility.
+
+2013-01-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/56095
+ * pt.c (convert_nontype_argument_function): Handle invalid input.
+ (convert_nontype_argument): Likewise.
+
+ PR c++/56104
+ * typeck.c (get_member_function_from_ptrfunc): Optimize if the
+ dynamic type has no virtual functions.
+
+2013-01-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/55944
+ * decl.c (check_initializer): Use TARGET_EXPR_DIRECT_INIT_P only
+ on TARGET_EXPR nodes.
+
+2013-01-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/56071
+ * pt.c (maybe_instantiate_noexcept): Don't defer access checks.
+
+2013-01-22 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/53609
+ * pt.c (argument_pack_element_is_expansion_p)
+ (make_argument_pack_select, use_pack_expansion_extra_args_p)
+ (gen_elem_of_pack_expansion_instantiation): New static functions.
+ (tsubst): When looking through an ARGUMENT_PACK_SELECT tree node,
+ look through the possibly resulting pack expansion as well.
+ (tsubst_pack_expansion): Use use_pack_expansion_extra_p to
+ generalize when to use the PACK_EXPANSION_EXTRA_ARGS mechanism.
+ Use gen_elem_of_pack_expansion_instantiation to build the
+ instantiation piece-wise. Don't use arg_from_parm_pack_p anymore,
+ as gen_elem_of_pack_expansion_instantiation and the change in
+ tsubst above generalize this particular case.
+ (arg_from_parm_pack_p): Remove this for it's not used by
+ tsubst_pack_expansion anymore.
+
+2013-01-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/56059
+ * tree.c (strip_typedefs_expr) [TREE_VEC]: Preserve non-default
+ template args count.
+
+2013-01-18 Jason Merrill <jason@redhat.com>
+
+ PR target/54908
+ * decl2.c (get_local_tls_init_fn): New.
+ (get_tls_init_fn): Handle flag_extern_tls_init. Don't bother
+ with aliases for internal variables. Don't use weakrefs if
+ the variable needs destruction.
+ (generate_tls_wrapper): Mark the wrapper as const if no
+ initialization is needed.
+ (handle_tls_init): Don't require aliases.
+
+2013-01-15 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/55663
+ * pt.c (coerce_innermost_template_parms): New static function.
+ (instantiate_alias_template): Use it here.
+
+2013-01-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/55878
+ * rtti.c (build_typeid, get_typeid): Add complain parm.
+ (get_tinfo_decl_dynamic): Likewise.
+ * cp-tree.h, parser.c, pt.c: Adjust.
+
+ PR c++/55893
+ * decl.c (cp_finish_decl): Clear TREE_READONLY if the variable
+ needs destruction.
+
+2013-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/48418
+ * typeck.c (cp_build_binary_op): For LSHIFT_EXPR and RSHIFT_EXPR,
+ call maybe_constant_value for the negative or too big shift
+ count warnings.
+
+2013-01-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/55801
+ * decl2.c (var_needs_tls_wrapper): Return false when error_operand_p
+ of the argument is true.
+
+2013-01-08 Joel Brobecker <brobecker@adacore.com>
+
+ * parser.c (cp_parser_initializer_list): Move declaration
+ of variable non_const to start of lexical block.
+
+2013-01-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/55753
+ * tree.c (build_aggr_init_expr): Do nothing in a template.
+ * pt.c (tsubst_copy_and_build) [CALL_EXPR]: Strip an ADDR_EXPR off
+ a FUNCTION_DECL before tsubsting.
+
+2013-01-04 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/52343
+ * pt.c (check_instantiated_arg): Allow type template arguments.
+
+2013-01-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/55877
+ * decl.c (reset_type_linkage, bt_reset_linkage): New.
+ (grokdeclarator): Use reset_type_linkage.
+ * name-lookup.c (binding_table_foreach): Handle null table.
+ * tree.c (decl_anon_ns_mem_p): Check TYPE_MAIN_DECL, not TYPE_NAME.
+
+2013-01-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54526 (again)
+ * parser.c (cp_parser_template_id): Revert core of previous change
+ (keep adjusted inform message).
+
+2013-01-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/55419
+ PR c++/55753
+ * pt.c (tsubst_copy_and_build) [TARGET_EXPR]: Don't touch
+ TREE_CONSTANT.
+
+ PR c++/55842
+ * semantics.c (trait_expr_value): Call maybe_instantiate_noexcept.
+
+ PR c++/55856
+ * semantics.c (build_data_member_initialization): Handle DECL_EXPR.
+
+ PR c++/53650
+ * call.c (type_has_extended_temps): New.
+ * cp-tree.h: Declare it.
+ * decl.c (check_initializer): Use build_aggr_init for arrays
+ if it is false.
+ * init.c (build_vec_init): Avoid mixed signed/unsigned arithmetic.
+
+2013-01-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/54325
+ * call.c (build_new_method_call_1): Don't use build_value_init for
+ user-provided default constructors.
+
+ * decl.c (check_default_argument): Use LOOKUP_IMPLICIT.
+
+ PR c++/55032
+ PR c++/55245
+ * tree.c (build_cplus_array_type): Copy layout information
+ to main variant if necessary.
+
+Copyright (C) 2013 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog.ptr b/gcc-4.9/gcc/cp/ChangeLog.ptr
new file mode 100644
index 000000000..d2d095499
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog.ptr
@@ -0,0 +1,75 @@
+2007-06-14 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * init.c (build_new_1): Use fold_build1 instead
+ of build1 for NEGATE_EXPR.
+ (build_vec_delete_1): Likewise.
+ * class.c (build_base_path): Likewise.
+ * except.c (expand_start_catch_block): Likewise.
+
+2007-05-28 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * typeck.c (build_binary_op): Add a comment on why creating
+ the tree in pieces while processing templates.
+
+2007-05-12 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * except.c (expand_start_catch_block): Do a
+ NEGATIVE and then a POINTER_PLUS_EXPR instead
+ of a MINUS_EXPR.
+
+2007-05-06 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Convert
+ PLUS_EXPR on pointer types over to use
+ POINTER_PLUS_EXPR and remove the conversion
+ to the pointer types.
+
+2007-05-06 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * typeck.c (build_unary_op): Remove code that used to
+ handle non lvalue increments/decrements as we now error
+ out all ways.
+
+2007-05-06 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * typeck.c (get_member_function_from_ptrfunc):
+ Change over to using POINTER_PLUS_EXPR and convert
+ the second operand to sizetype.
+ * typeck2.c (build_m_component_ref): Likewise.
+ * rtti.c (build_headof): Use sizetype instead of
+ ptrdiff_type_node.
+
+2007-05-06 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * method.c (thunk_adjust): Use POINTER_PLUS_EXPR for
+ adding to a pointer type. Use size_int instead of
+ ssize_int. Convert the index to sizetype before
+ adding it to the pointer.
+
+2006-11-23 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * typeck.c (build_binary_op): For templates build the
+ expression in pieces to avoid the assert in build2_stat.
+ * init.c (expand_virtual_init): Create a POINTER_PLUS_EXPR
+ instead of PLUS_EXPR for pointers.
+ (build_new_1): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_vec_delete): Likewise.
+ * class.c (build_base_path): Likewise.
+ (build_base_path): Likewise.
+ (convert_to_base_statically): Likewise.
+ (fixed_type_or_null): Handle POINTER_PLUS_EXPR.
+ (get_vtbl_decl_for_binfo): Handle POINTER_PLUS_EXPR
+ instead of PLUS_EXPR.
+ (dfs_accumulate_vtbl_inits): Create a POINTER_PLUS_EXPR
+ instead of PLUS_EXPR for pointers.
+ * call.c (build_special_member_call): Likewise.
+ * rtti.c (build_headof): Likewise.
+ (tinfo_base_init): Likewise.
+
+
+Copyright (C) 2006-2007 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/ChangeLog.tree-ssa b/gcc-4.9/gcc/cp/ChangeLog.tree-ssa
new file mode 100644
index 000000000..1a52ac399
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ChangeLog.tree-ssa
@@ -0,0 +1,573 @@
+2004-04-19 Richard Henderson <rth@redhat.com>
+
+ * except.c (check_handlers_1): Use locus stored in master for warning.
+ * tree.c (cp_walk_subtrees): Save and restore input_location.
+
+2004-04-12 Diego Novillo <dnovillo@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_RTL_EXPAND_START): Remove.
+ (LANG_HOOKS_RTL_EXPAND_STMT): Remove.
+ * semantics.c (cxx_expand_function_start): Remove.
+
+2004-04-12 Richard Henderson <rth@redhat.com>
+
+ * except.c (check_handlers_1): Use EXPR_LOCUS instead of STMT_LINENO.
+ * semantics.c (finalize_nrv_r): Likewise.
+ * tree.c (cp_walk_subtrees): Likewise.
+ * parser.c (cp_parser_statement): Save and restore entire locus;
+ set EXPR_LOCUS.
+ * pt.c (tsubst_expr): Don't special-case LABEL_STMT.
+
+2004-04-01 Diego Novillo <dnovillo@redhat.com>
+
+ * name-lookup.c (innermost_nonclass_level): Check for
+ error_mark_node.
+
+2004-03-25 Diego Novillo <dnovillo@redhat.com>
+
+ * parser.c (cp_parser_class_specifier): Initialize
+ variable 'attributes'.
+
+2004-03-17 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c (cxx_types_compatible_p): Use
+ same_type_ignoring_top_level_qualifiers_p.
+
+2004-03-16 Dale Johannesen <dalej@apple.com>
+
+ * cp-lang.c (cxx_types_compatible_p): New.
+ LANG_HOOKS_TYPES_COMPATIBLE_P: New.
+
+2004-03-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/14452
+ * tree.c (stabilize_init): Return whether or not it worked.
+ * init.c (build_new_1): If not, use a sentry.
+ * cp-tree.h: Adjust prototype.
+
+2004-03-01 Jeff Law <law@redhat.com>
+
+ * init.c (build_vec_delete_1): Convert 2nd argument to NE_EXPR to
+ the proper type.
+
+2004-02-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/13944
+ * except.c (do_free_exception): Remove #if 0 wrapper.
+ (build_throw): Use it if we elide a copy into the exception object.
+
+ * tree.c (stabilize_call): Fix thinko.
+
+2004-02-19 Steven Bosscher <stevenb@suse.de>
+
+ * decl.c (poplevel): Don't output nested inline functions.
+
+2004-02-16 Richard Henderson <rth@redhat.com>
+
+ * call.c (build_call, build_over_call, build_new_method_call): Add
+ static chain operand to call_expr.
+ * decl.c (build_offset_ref_call_from_tree): Likewise.
+ * parser.c (cp_parser_postfix_expression): Likewise.
+ * semantics.c (finish_call_expr): Likewise.
+ * cp-lang.c (cp_expand_decl): Don't declare_nonlocal_label.
+
+2004-02-09 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P): New.
+ * cp-tree.h (cp_missing_noreturn_ok_p): Declare.
+ * decl.c (cp_missing_noreturn_ok_p): Export.
+ (cxx_init_decl_processing): Don't set lang_missing_noreturn_ok_p.
+
+2004-02-06 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/13863
+ * cp-lang.c (LANG_HOOKS_DECL_UNINIT): Remove.
+
+2004-02-03 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/13325
+ * call.c, cvt.c, init.c, typeck.c: Use TREE_NO_WARNING instead
+ of TREE_NO_UNUSED_WARNING.
+ * cvt.c (convert_to_void): Also use it for "has no effect" warning.
+
+2004-01-30 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mflang_flush_calls): Mark static ctor as TREE_USED.
+
+2004-01-12 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (ok_to_generate_alias_set_for_type): Remove.
+ (cxx_get_alias_set): Allow all types.
+
+2004-01-08 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mflang_flush_calls): mf_mark synthetic function.
+
+2004-01-04 Richard Henderson <rth@redhat.com>
+
+ * call.c (build_over_call): Don't create a save_expr of an
+ aggregate, but rather its address.
+
+2004-01-01 Richard Henderson <rth@redhat.com>
+
+ * expr.c (cxx_expand_expr): Don't handle THROW_EXPR, or
+ MUST_NOT_THROW_EXPR.
+ * semantics.c (genrtl_try_block, genrtl_eh_spec_block,
+ genrtl_handler, cp_expand_stmt): Remove.
+ (init_cp_semantics): Don't set lang_expand_stmt.
+
+2003-12-31 Richard Henderson <rth@redhat.com>
+
+ * cp-mudflap.c (mflang_register_call): Remove.
+
+2003-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/12453
+ * cp-simplify.c (cp_gimplify_init_expr): Look inside STMT_EXPRs
+ and COMPOUND_EXPRs to find an AGGR_INIT_EXPR.
+
+2003-12-16 Jason Merrill <jason@redhat.com>
+
+ PR middle-end/12920
+ * decl.c (grokdeclarator): Immediately layout an
+ ARRAY_TYPE used in a pointer-to-array declarator.
+
+2003-12-16 Jan Hubicka <jh@suse.cz>
+
+ Revert until initializers are made language independent:
+ * cp-lang.c (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): Kill.
+ * cp-tree.h (cxx_callgraph_analyze_expr): Kill.
+ * decl2.c (cxx_callgraph_analyze_expr): Kill.
+
+2003-12-14 Jan Hubicka <jh@suse.cz>
+
+ * cp-lang.c (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): Kill.
+ * cp-tree.h (cxx_callgraph_analyze_expr): Kill.
+ * decl2.c (cxx_callgraph_analyze_expr): Kill.
+
+2003-11-24 Richard Henderson <rth@redhat.com>
+
+ * Make-lang.in (tree.o, typeck.o): Remove -Wno-error.
+
+2003-11-20 Richard Henderson <rth@redhat.com>
+
+ * call.c (build_java_interface_fn_ref): Use build_address+convert.
+ * except.c (build_eh_type_type): Likewise.
+ * class.c (build_base_path): Use convert+build_indirect_ref.
+ * init.c (expand_virtual_init): Likewise.
+ * rtti.c (get_tinfo_decl_dynamic): Use convert.
+
+2003-11-20 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mflang_flush_calls): Adapt to direct expansion of
+ synthetic function, bypassing callgraph code.
+ * cp-decl2.c (finish_file): Call mudflap after callgraph-based
+ expansion.
+
+2003-11-17 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Preevaluate initializer. Simplify EH code.
+ (build_init): Call a constructor rather than call build_aggr_init
+ for classes.
+ * except.c (stabilize_throw_expr): Remove.
+ (build_throw): Use stabilize_init instead of stabilize_throw_expr.
+ * tree.c (stabilize_call, stabilize_init): New fns.
+ * call.c (build_over_call): A constructor no longer returns the
+ address of the object.
+
+2003-11-16 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (pointer_diff): Remove unused variable.
+
+2003-11-16 Jason Merrill <jason@redhat.com>
+
+ PR optimization/11269
+ * semantics.c (finalize_nrv_r): Rename from nullify_returns_r.
+ Also replace uses of the nrv with our RESULT_DECL.
+ (cxx_expand_function_start): Don't mess with the nrv.
+ (finalize_nrv): New fn.
+ * cp-tree.h: Declare it.
+ * decl.c (finish_function): Call it.
+ * tree.c (cp_copy_res_decl_for_inlining): Don't mess with the nrv.
+
+2003-11-10 Richard Henderson <rth@redhat.com>
+
+ * cp-simplify.c (gimplify_must_not_throw_expr): Replace add_tree
+ with append_to_statement_list.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * decl.c (pop_switch): Call c_do_switch_warnings.
+
+2003-10-23 Richard Henderson <rth@redhat.com>
+
+ * cp-simplify.c (cp_gimplify_expr): Return gimplify_status.
+
+2003-10-16 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_function): Don't check flag_disable_gimple.
+
+2003-10-14 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_function): Always gimplify; call c_warn_unused_result.
+
+2003-10-13 Richard Henderson <rth@redhat.com>
+
+ * pt.c (push_tinst_level): Use annotate_with_locus.
+
+2003-10-12 Richard Henderson <rth@redhat.com>
+
+ * call.c (call_builtin_trap): Use implicit_built_in_decls.
+ * class.c (build_base_path): Set TREE_INVARIANT.
+ (build_vtbl_ref_1, build_vtbl_initializer): Likewise.
+ * decl.c (build_enumerator): Likewise.
+ * init.c (build_zero_init): Likewise.
+ * pt.c (push_inline_template_parms_recursive): Likewise.
+ (build_template_parm_index, reduce_template_parm_level): Likewise.
+ (process_template_parm): Likewise.
+ * rtti.c (tinfo_base_init, generic_initializer): Likewise.
+ (ptr_initializer, ptm_initializer, class_initializer): Likewise.
+ * typeck.c (build_ptrmemfunc1): Likewise.
+ * typeck2.c (process_init_constructor): Likewise.
+
+ * calls.c (dfs_accumulate_vtbl_inits): Rely on build to set
+ TREE_CONSTANT.
+ (build_vtbl_initializer): Likewise.
+ * init.c (build_vtbl_address): Likewise.
+ * rtti.c (tinfo_base_init): Likewise.
+ * tree.c (make_ptrmem_cst): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+ (get_member_function_from_ptrfunc, build_binary_op): Likewise.
+ (pointer_diff, build_address, build_nop, build_unary_op): Likewise.
+
+2003-09-30 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_function): Set cfun->function_end_locus.
+
+2003-09-24 Jason Merrill <jason@redhat.com>
+
+ * class.c, decl.c, decl2.c, error.c, init.c, lex.c, method.c,
+ pt.c, semantics.c, tree.c: Revert from TREE_LOCUS to
+ DECL_SOURCE_LOCATION.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * decl.c (cxx_init_decl_processing): Don't using_eh_for_cleanups
+ if exceptions are disabled.
+
+2003-09-03 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_RTL_EXPAND_STMT): Use expand_stmt_toplev.
+
+2003-09-03 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_function): Fix misapplied patch. Don't
+ free_after_parsing or free_after_compilation. For real this time.
+
+2003-08-22 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (cp_gimplify_init_expr): Update use of predicates.
+
+2003-08-21 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (cp_gimplify_expr): Use simplify_aggr_init_expr.
+ (cp_gimplify_init_expr): Don't call it here.
+ (gimplify_aggr_init_expr): Remove.
+
+2003-08-19 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_array_ref): Also build ARRAY_REFs from
+ INDIRECT_REFs of ARRAY_TYPE.
+
+ * semantics.c (finish_id_expression): Unshare aliases.
+
+2003-08-12 Diego Novillo <dnovillo@redhat.com>
+
+ * optimize.c (optimize_function): Do not call dump_function.
+
+2003-08-08 Jason Merrill <jason@redhat.com>
+
+ * optimize.c (optimize_function): Restore support for
+ !keep_function_tree_in_gimple_form.
+
+2003-07-27 Andreas Jaeger <aj@suse.de>
+
+ * cp-lang.c: Convert K&R prototypes to ISO C90.
+ * cp-simplify.c: Likewise.
+ * cp-mudflap.c: Likewise.
+
+2003-06-13 Frank Ch. Eigler <fche@redhat.com>
+
+ * semantics.c (expand_body): Call mudflap_c_function just before
+ rtl expansion of function body; don't interfere with inlining.
+ * optimize.c (optimize_function): Remove mudflap call.
+
+2003-06-13 Diego Novillo <dnovillo@redhat.com>
+
+ * cp-lang.c, cp-simplify.c, cp-tree.h, decl.c, optimize.c,
+ semantics.c, tree.c: Rename SIMPLE to GIMPLE everywhere.
+
+2003-06-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mflang_register_call): Give the synthetic decl
+ undefined (not zero) size.
+
+2003-06-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mx_flag): Remove. Update callers to use mf_mark.
+
+2003-05-24 Diego Novillo <dnovillo@redhat.com>
+
+ * Make-lang.in (optimize.o): Add dependency on tree-simple.h
+ * decl.c (grokdeclarator): Don't abort when the declarator is
+ ERROR_MARK_NODE.
+ * optimize.c (optimize_function): Unshare all trees after
+ optimizing inline calls.
+
+2003-05-12 Diego Novillo <dnovillo@redhat.com>
+
+ * class.c (dump_array): Call CONSTRUCTOR_ELTS to access
+ the operand of a CONSTRUCTOR node.
+
+2003-05-07 Diego Novillo <dnovillo@redhat.com>
+
+ * decl.c (grokdeclarator): Fix thinko in handling
+ ERROR_MARK declarators.
+
+2003-05-07 Diego Novillo <dnovillo@redhat.com>
+
+ * decl.c (grokdeclarator): Handle ERROR_MARK declarators.
+
+2003-05-07 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (expand_body): Call expand_stmt when
+ -fdisable-simple is given.
+
+2003-04-21 Jeff Law <law@redhat.com>
+
+ * optimize.c (optimize_function_tree): Do run the tree-ssa
+ optimizers.
+
+2003-04-16 Jeff Law <law@redhat.com>
+
+ * optimize.c (optimize_function): No longer check
+ flag_disable_simple.
+
+2003-04-15 Jeff Law <law@redhat.com>
+
+ * pt.c (instantiate_decl): If CFUN is null, then we will
+ need to push to the toplevel.
+
+ * Makefile.in (decl.o): Depends on tree-flow.h.
+ * decl.c (finish_function): Call set_has_hidden_use when
+ nullifying returns for named value return optimization.
+
+2003-04-02 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (cp_simplify_expr) <case EMPTY_CLASS_EXPR>:
+ Change type of constant to RECORD_TYPE.
+
+2003-03-10 Jeff Law <law@redhat.com>
+
+ * optimize.c (optimize_function): Avoid unnecessary
+ simplification of the function tree.
+
+2003-03-02 Diego Novillo <dnovillo@redhat.com>
+
+ * decl.c: Replace DECL_SOURCE_LOCATION with TREE_LOCUS
+ everywhere.
+
+2003-02-28 Frank Ch. Eigler <fche@redhat.com>
+
+ * decl2.c (finish_file): Adjust timing of mudflap_finish_file call
+ to account for unit-at-a-time compilation.
+
+2003-02-07 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (cp_simplify_expr): Handle BASELINK.
+
+ * parser.c (cp_parser_primary_expression): Unshare a COMPONENT_REF
+ from an ALIAS_DECL.
+
+2003-02-05 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (genericize_try_block): Do genericize catch blocks.
+
+2003-02-03 Diego Novillo <dnovillo@redhat.com>
+
+ * parser.c (cp_parser_asm_definition): Call finish_asm_stmt with
+ 'volatile_p' directly.
+ * typeck.c (build_binary_op): Initialize variable 'type'.
+ * Make-lang.in (cp/tree.o-warn): Add -Wno-error.
+
+2003-01-29 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mflang_register_call): Adapt to mf-runtime.h API
+ change.
+
+2003-01-15 Jeff Law <law@redhat.com>
+
+ * class.c: Use TREE_FILENAME and TREE_LINENO to extract
+ file/line information from tree nodes. Remove EXPR_WITH_FILE_LOCATION
+ nodes. Use annotate_with_file_line to attach file/line information
+ to tree nodes. Use TREE_LOCUS to copy file/line information
+ from one node to another.
+ * decl2.c, error.c, init.c, lex.c, method.c: Likewise.
+ * optimize.c: Likewise.
+ * cp-tree.def (TINST_LEVEL): New tree node.
+ * cp-tree.h (TINST_DECL): Update now that we no longer use
+ EXPR_WITH_FILE_LOCATION to represent the TINST_DECL information.
+ (TINST_FILE, TINST_LINE): Kill.
+ * decl.c: Use TREE_FILENAME and TREE_LINENO to extract
+ file/line information from tree nodes. Use annotate_witH_file_line
+ to add file/line information to tree nodes. Use TREE_LOCUS
+ to copy file/line information from one node to another.
+ (duplicate_decls): Make sure to copy TREE_LOCUS information
+ from the old decl to the new decl.
+ (finish_function): Save and restore file/line information
+ around genericizing the function tree.
+ * pt.c (lookup_template_class): Use TREE_LOCUS to copy file/line
+ information from one node to another.
+ (push_tinst_level): Generate a TINST_LEVEL node rather than
+ using EXPR_WITH_FILE_LOCATION nodes. Use annotate_with_file_line
+ to annotate the new node with file/line information.
+ (pop_tinst_level): Use TREE_LINENO and TREE_FILENAME to extract
+ file/line information from nodes.
+ (tsubst_friend_function, instantiate_class_template): Likewise.
+ (tsubst_decl, instantiate_decl, tsubst_enum): Likewise.
+ * semantics.c: Use annotate_with_file_line to annotate tree
+ nodes with file/line information. Use TREE_FILENAME and TREE_LINENO
+ to extract file/line information from tree nodes.
+ (expand_body): Restore file/line information slightly earlier.
+ tree.c (cp_walk_subtrees): Set lineno appropriately.
+ (cp_copy_res_decl_for_inlining): Use TREE_LOCUS to copy file/line
+ information from one node to another.
+
+2003-01-13 Frank Ch. Eigler <fche@redhat.com>
+
+ Prototype C++ mudflap support.
+ * Make-lang.in (CXX_OBJS): Add cp/cp-mudflap.o and dependencies.
+ * cp-mudflap.c: New file with C++ front-end mflang_* routines.
+ * decl2.c (finish_file): Divert to mudflap if appropriate.
+ * optimize.c (optimize_function): Ditto.
+
+2003-01-02 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (CXX_C_OBJS): Replace old-tree-inline.o with
+ tree-inline.o.
+
+ * optimize.c (dump_function): Move to ../tree-dump.c.
+
+ * cp-simplify.c (cp_simplify_expr): Handle PTRMEM_CST, INIT_EXPR,
+ MODIFY_EXPR and EMPTY_CLASS_EXPR.
+ (cp_simplify_stmt): Handle USING_STMT.
+ (cp_simplify_init_expr): New fn.
+ * cvt.c (build_up_reference): Don't push the decl.
+ * class.c (build_vtable_entry_ref, build_vtbl_ref_1): Unshare the
+ vtable address.
+ * init.c (build_vtbl_address): Likewise.
+ * cp-lang.c (LANG_HOOKS_UNSAVE_EXPR_NOW): Remove.
+ * decl.c (lookup_name_real): Unshare the expansion of an ALIAS_DECL.
+ (finish_function): Don't genericize templates.
+ * parse.y (parse_asm_stmt): Fix prototype.
+ * semantics.c (expand_body): Don't expand if we saw errors.
+ Drop support for expanding non-GENERIC code.
+
+ * cp-simplify.c (cp_simplify_stmt): Handle HANDLER and EH_SPEC_BLOCK.
+ (genericize_try_block): Always build a TRY_CATCH_EXPR.
+ (genericize_catch_block): New fn.
+ (genericize_eh_spec_block): New fn.
+ (cp_simplify_expr): Handle THROW_EXPR and MUST_NOT_THROW_EXPR.
+ (simplify_must_not_throw_expr): New fn.
+ * except.c (wrap_cleanups_r): Make the MUST_NOT_THROW_EXPR void.
+ (build_throw): Likewise.
+
+2002-12-14 Jason Merrill <jason@redhat.com>
+
+ * optimize.c (dump_function): Use pretty dumpers.
+ (optimize_function): Don't do .original dump here.
+
+2002-12-03 Diego Novillo <dnovillo@redhat.com>
+
+ * cp-simplify.c: Include coretypes.h and tm.h.
+
+2002-11-24 Jason Merrill <jason@redhat.com>
+
+ Gimplify C++ cleanups.
+ * decl.c (finish_function): Call c_genericize.
+ * cp-simplify.c (cp_simplify_stmt): New fn.
+ (genericize_try_block): New fn.
+ (cp_simplify_expr): Move INIT_EXPR/TARGET_EXPR code
+ to ../gimplify.c. Handle AGGR_INIT_EXPR.
+ (simplify_target_expr): Move to ../gimplify.c.
+ (maybe_fixup_loop_cond): Remove.
+ (simplify_aggr_init_expr): Split out from...
+ * semantics.c (simplify_aggr_init_exprs_r): ...here.
+ (expand_body): Don't simplify AGGR_INIT_EXPRs here
+ if we're gimplifying. Handle expanding generic trees.
+ * tree.c (init_tree): Set lang_simplify_stmt.
+ * cp-tree.h: Declare the new fns.
+
+ * optimize.c (optimize_function): Do pretty dumps.
+
+2002-10-04 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (CXX_C_OBJS): Add gimplify.o.
+
+2002-09-24 Jason Merrill <jason@redhat.com>
+
+ * parse.y (parse_asm_stmt): New fn.
+ (simple_stmt): Use it.
+ * semantics.c (finish_asm_stmt): Change cv_qualifier parm to
+ volatile_p.
+ * cp-tree.h: Adjust prototype.
+ * pt.c (tsubst_expr): Adjust call.
+
+2002-08-23 Diego Novillo <dnovillo@redhat.com>
+
+ * Make-lang.in (CXX_C_OBJS): Add tree-dchain.o
+
+2002-08-11 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (maybe_fixup_loop_cond): Move here.
+ (cp_simplify_expr): Call it.
+ (simplify_target_expr): Remove pre_p parm.
+
+2002-08-09 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (cp_simplify_expr): New fn.
+ (simplify_target_expr): New fn.
+ (cp_simplify_function_tree): Remove.
+ * cp-lang.c (LANG_HOOKS_SIMPLIFY_FUNCTION_TREE): Don't define.
+ (LANG_HOOKS_SIMPLIFY_EXPR): Define.
+ * optimize.c (optimize_function): De-hook simplify_function_tree.
+ * cp-tree.h: Declare cp_simplify_expr.
+
+2002-07-17 Daniel Berlin <dberlin@dberlin.org>
+
+ * Make-lang.in (CXX_C_OBJS): Add tree-alias-ecr.c,
+ tree-alias-type.o, tree-alias-steen.o, disjoint-set.o.
+
+2002-06-21 Andreas Jaeger <aj@suse.de>
+
+ * Make-lang.in (cp-simplify.o): New.
+
+2002-06-18 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c: New file.
+ * Make-lang.in: Add it.
+ * cp-tree.h: Declare cp_simplify_function_tree.
+ * cp-lang.c (LANG_HOOKS_SIMPLIFY_FUNCTION_TREE): Define.
+ * optimize.c (optimize_function): Call tree optimizers (but not yet).
+
+Local Variables:
+mode: change-log
+change-log-default-name: "ChangeLog.tree-ssa"
+End:
+
+
+Copyright (C) 2002-2004 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/Make-lang.in b/gcc-4.9/gcc/cp/Make-lang.in
new file mode 100644
index 000000000..5480c4eae
--- /dev/null
+++ b/gcc-4.9/gcc/cp/Make-lang.in
@@ -0,0 +1,246 @@
+# Top level -*- makefile -*- fragment for GNU C++.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+#This file is part of GCC.
+
+#GCC is free software; you can redistribute it and/or modify
+#it under the terms of the GNU General Public License as published by
+#the Free Software Foundation; either version 3, or (at your option)
+#any later version.
+
+#GCC is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# This file provides the language dependent support in the main Makefile.
+# Each language makefile fragment must provide the following targets:
+#
+# foo.all.cross, foo.start.encap, foo.rest.encap,
+# foo.install-common, foo.install-man, foo.install-info, foo.install-pdf,
+# foo.install-html, foo.info, foo.dvi, foo.pdf, foo.html, foo.uninstall,
+# foo.mostlyclean, foo.clean, foo.distclean,
+# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4
+#
+# where `foo' is the name of the language.
+#
+# It should also provide rules for:
+#
+# - making any compiler driver (eg: g++)
+# - the compiler proper (eg: cc1plus)
+# - define the names for selecting the language in LANGUAGES.
+
+# Actual names to use when installing a native compiler.
+CXX_INSTALL_NAME := $(shell echo c++|sed '$(program_transform_name)')
+GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)')
+CXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo c++|sed '$(program_transform_name)')
+GXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo g++|sed '$(program_transform_name)')
+CP_PLUGIN_HEADERS := cp-tree.h cxx-pretty-print.h name-lookup.h
+
+#
+# Define the names for selecting c++ in LANGUAGES.
+# Note that it would be nice to move the dependency on g++
+# into the C++ rule, but that needs a little bit of work
+# to do the right thing within all.cross.
+c++: cc1plus$(exeext)
+
+# Tell GNU make to ignore these if they exist.
+.PHONY: c++
+
+CFLAGS-cp/g++spec.o += $(DRIVER_DEFINES)
+
+# Create the compiler driver for g++.
+GXX_OBJS = $(GCC_OBJS) cp/g++spec.o
+xg++$(exeext): $(GXX_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS)
+ +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+ $(GXX_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \
+ $(EXTRA_GCC_LIBS) $(LIBS)
+
+# Create a version of the g++ driver which calls the cross-compiler.
+g++-cross$(exeext): xg++$(exeext)
+ -rm -f g++-cross$(exeext)
+ cp xg++$(exeext) g++-cross$(exeext)
+
+# The compiler itself.
+# Shared with C front end:
+CXX_C_OBJS = attribs.o incpath.o \
+ $(C_COMMON_OBJS) $(CXX_TARGET_OBJS)
+
+# Language-specific object files for C++ and Objective C++.
+CXX_AND_OBJCXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
+ cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parser.o cp/ptree.o cp/rtti.o \
+ cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \
+ cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o cp/optimize.o \
+ cp/mangle.o cp/cp-objcp-common.o cp/name-lookup.o cp/cxx-pretty-print.o \
+ cp/cp-cilkplus.o \
+ cp/cp-gimplify.o cp/cp-array-notation.o cp/lambda.o \
+ cp/vtable-class-hierarchy.o $(CXX_C_OBJS)
+
+# Language-specific object files for C++.
+CXX_OBJS = cp/cp-lang.o c-family/stub-objc.o $(CXX_AND_OBJCXX_OBJS)
+
+c++_OBJS = $(CXX_OBJS) cc1plus-checksum.o cp/g++spec.o
+
+# Use strict warnings for this front end.
+cp-warn = $(STRICT_WARN)
+
+# compute checksum over all object files and the options
+cc1plus-checksum.c : build/genchecksum$(build_exeext) checksum-options \
+ $(CXX_OBJS) $(BACKEND) $(LIBDEPS)
+ build/genchecksum$(build_exeext) $(CXX_OBJS) $(BACKEND) $(LIBDEPS) \
+ checksum-options > cc1plus-checksum.c.tmp && \
+ $(srcdir)/../move-if-change cc1plus-checksum.c.tmp cc1plus-checksum.c
+
+cc1plus$(exeext): $(CXX_OBJS) cc1plus-checksum.o $(BACKEND) $(LIBDEPS)
+ +$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+ $(CXX_OBJS) cc1plus-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
+
+ifeq ($(ENABLE_MAINTAINER_RULES), true)
+# Special build rule. This is a maintainer rule, that is only
+# available when GCC is configured with --enable-maintainer-mode. In
+# other cases, it is not available to avoid triggering rebuilds if a
+# user has the source checked out with unusual timestamps.
+$(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.gperf
+else
+# We keep the rule so that you can still force a rebuild, even if you
+# didn't configure GCC with --enable-maintainer-mode, by manually
+# deleting the $(srcdir)/cp/cfns.h file.
+$(srcdir)/cp/cfns.h:
+endif
+ gperf -o -C -E -k '1-6,$$' -j1 -D -N 'libc_name_p' -L ANSI-C \
+ $(srcdir)/cp/cfns.gperf --output-file $(srcdir)/cp/cfns.h
+
+#
+# Build hooks:
+
+c++.all.cross: g++-cross$(exeext)
+c++.start.encap: xg++$(exeext)
+c++.rest.encap:
+c++.info:
+c++.install-info:
+c++.dvi:
+c++.pdf:
+c++.install-pdf:
+c++.install-html:
+c++.html:
+c++.srcinfo:
+c++.srcextra:
+
+c++.tags: force
+ cd $(srcdir)/cp; etags -o TAGS.sub *.c *.h --language=none \
+ --regex='/DEFTREECODE [(]\([A-Z_]+\)/\1/' cp-tree.def; \
+ etags --include TAGS.sub --include ../TAGS.sub
+
+c++.man: doc/g++.1
+
+c++.srcman: doc/g++.1
+ -cp -p $^ $(srcdir)/doc
+
+# 'make check' in gcc/ looks for check-c++, as do all toplevel C++-related
+# check targets. However, our DejaGNU framework requires 'check-g++' as its
+# entry point. We feed the former to the latter here.
+check-c++ : check-g++
+# Run the testsute in C++0x mode.
+check-c++0x:
+ @echo Normal 'make check' now runs the testsuite in C++11 mode as well as C++98.
+# Run the testsuite with garbage collection at every opportunity.
+check-g++-strict-gc:
+ $(MAKE) RUNTESTFLAGS="$(RUNTESTFLAGS) --extra_opts,--param,ggc-min-heapsize=0,--param,ggc-min-expand=0" \
+ TESTSUITEDIR="$(TESTSUITEDIR).gc" check-g++
+check-c++-subtargets : check-g++-subtargets
+# List of targets that can use the generic check- rule and its // variant.
+lang_checks += check-g++
+lang_checks_parallelized += check-g++
+# For description see comment above check_gcc_parallelize in gcc/Makefile.in.
+check_g++_parallelize = old-deja.exp \
+ dg.exp=g++.dg/[0-9A-Za-bd-su-z]* \
+ dg.exp=g++.dg/[ct]* \
+ dg.exp=c-c++-common/*,dg-torture.exp
+
+#
+# Install hooks:
+# cc1plus is installed elsewhere as part of $(COMPILERS).
+
+# Install the driver program as $(target)-g++ and $(target)-c++, and
+# also as g++ and c++ if native.
+c++.install-common: installdirs
+ -rm -f $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext)
+ -$(INSTALL_PROGRAM) xg++$(exeext) $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext)
+ -chmod a+x $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext)
+ -rm -f $(DESTDIR)$(bindir)/$(CXX_INSTALL_NAME)$(exeext)
+ -( cd $(DESTDIR)$(bindir) && \
+ $(LN) $(GXX_INSTALL_NAME)$(exeext) $(CXX_INSTALL_NAME)$(exeext) )
+ -if [ -f cc1plus$(exeext) ] ; then \
+ if [ ! -f g++-cross$(exeext) ] ; then \
+ rm -f $(DESTDIR)$(bindir)/$(GXX_TARGET_INSTALL_NAME)$(exeext); \
+ ( cd $(DESTDIR)$(bindir) && \
+ $(LN) $(GXX_INSTALL_NAME)$(exeext) $(GXX_TARGET_INSTALL_NAME)$(exeext) ); \
+ rm -f $(DESTDIR)$(bindir)/$(CXX_TARGET_INSTALL_NAME)$(exeext); \
+ ( cd $(DESTDIR)$(bindir) && \
+ $(LN) $(CXX_INSTALL_NAME)$(exeext) $(CXX_TARGET_INSTALL_NAME)$(exeext) ); \
+ fi ; \
+ fi
+
+# We can't use links because not everyone supports them. So just copy the
+# manpage.
+doc/g++.1: doc/gcc.1
+ cp $< doc/g++.1
+
+c++.install-man: $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext)
+
+$(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext): doc/g++.1 installdirs
+ -rm -f $@
+ -$(INSTALL_DATA) $< $@
+ -chmod a-x $@
+
+c++.install-plugin: installdirs
+# We keep the directory structure for files in config and .def files. All
+# other files are flattened to a single directory.
+ headers="$(CP_PLUGIN_HEADERS)"; \
+ for file in $$headers; do \
+ path=$(srcdir)/cp/$$file; \
+ dest=$(plugin_includedir)/cp/$$file; \
+ echo $(INSTALL_DATA) $$path $(DESTDIR)$$dest; \
+ dir=`dirname $$dest`; \
+ $(mkinstalldirs) $(DESTDIR)$$dir; \
+ $(INSTALL_DATA) $$path $(DESTDIR)$$dest; \
+ done
+
+c++.uninstall:
+ -rm -rf $(DESTDIR)$(bindir)/$(CXX_INSTALL_NAME)$(exeext)
+ -rm -rf $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext)
+ -rm -rf $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext)
+#
+# Clean hooks:
+# A lot of the ancillary files are deleted by the main makefile.
+# We just have to delete files specific to us.
+
+c++.mostlyclean:
+ -rm -f doc/g++.1
+ -rm -f cp/*$(objext)
+ -rm -f cp/*$(coverageexts)
+c++.clean:
+c++.distclean:
+ -rm -f cp/config.status cp/Makefile
+ -rm -f cxxmain.c
+c++.maintainer-clean:
+#
+# Stage hooks:
+# The main makefile has already created stage?/cp.
+
+c++.stage1: stage1-start
+ -mv cp/*$(objext) stage1/cp
+c++.stage2: stage2-start
+ -mv cp/*$(objext) stage2/cp
+c++.stage3: stage3-start
+ -mv cp/*$(objext) stage3/cp
+c++.stage4: stage4-start
+ -mv cp/*$(objext) stage4/cp
+c++.stageprofile: stageprofile-start
+ -mv cp/*$(objext) stageprofile/cp
+c++.stagefeedback: stagefeedback-start
+ -mv cp/*$(objext) stagefeedback/cp
diff --git a/gcc-4.9/gcc/cp/NEWS b/gcc-4.9/gcc/cp/NEWS
new file mode 100644
index 000000000..d5d3d2fa6
--- /dev/null
+++ b/gcc-4.9/gcc/cp/NEWS
@@ -0,0 +1,408 @@
+*** Changes in GCC 3.4:
+
+* Changes in GCC 3.4 are described in 'gcc-3.4/changes.html'
+
+*** Changes in GCC 3.3:
+
+* The "new X = 3" extension has been removed; you must now use "new X(3)".
+
+* G++ no longer allows in-class initializations of static data members
+ that do not have arithmetic or enumeration type. For example:
+
+ struct S {
+ static const char* const p = "abc";
+ };
+
+ is no longer accepted.
+
+ Use the standards-conformant form:
+
+ struct S {
+ static const char* const p;
+ };
+
+ const char* const S::p = "abc";
+
+ instead.
+
+ (ISO C++ is even stricter; it does not allow in-class
+ initializations of floating-point types.)
+
+*** Changes in GCC 3.1:
+
+* -fhonor-std and -fno-honor-std have been removed. -fno-honor-std was
+ a workaround to allow std compliant code to work with the non-std
+ compliant libstdc++-v2. libstdc++-v3 is std compliant.
+
+* The C++ ABI has been fixed so that `void (A::*)() const' is mangled as
+ "M1AKFvvE", rather than "MK1AFvvE" as before. This change only affects
+ pointer to cv-qualified member function types.
+
+* The C++ ABI has been changed to correctly handle this code:
+
+ struct A {
+ void operator delete[] (void *, size_t);
+ };
+
+ struct B : public A {
+ };
+
+ new B[10];
+
+ The amount of storage allocated for the array will be greater than
+ it was in 3.0, in order to store the number of elements in the
+ array, so that the correct size can be passed to `operator delete[]'
+ when the array is deleted. Previously, the value passed to
+ `operator delete[]' was unpredictable.
+
+ This change will only affect code that declares a two-argument
+ `operator delete[]' with a second parameter of type `size_t'
+ in a base class, and does not override that definition in a
+ derived class.
+
+* The C++ ABI has been changed so that:
+
+ struct A {
+ void operator delete[] (void *, size_t);
+ void operator delete[] (void *);
+ };
+
+ does not cause unnecessary storage to be allocated when an array of
+ `A' objects is allocated.
+
+ This change will only affect code that declares both of these
+ forms of `operator delete[]', and declared the two-argument form
+ before the one-argument form.
+
+* The C++ ABI has been changed so that when a parameter is passed by value,
+ any cleanup for that parameter is performed in the caller, as specified
+ by the ia64 C++ ABI, rather than the called function as before. As a
+ result, classes with a non-trivial destructor but a trivial copy
+ constructor will be passed and returned by invisible reference, rather
+ than by bitwise copy as before.
+
+* G++ now supports the "named return value optimization": for code like
+
+ A f () {
+ A a;
+ ...
+ return a;
+ }
+
+ G++ will allocate 'a' in the return value slot, so that the return
+ becomes a no-op. For this to work, all return statements in the function
+ must return the same variable.
+
+*** Changes in GCC 3.0:
+
+* Support for guiding declarations has been removed.
+
+* G++ now supports importing member functions from base classes with a
+ using-declaration.
+
+* G++ now enforces access control for nested types.
+
+* In some obscure cases, functions with the same type could have the
+ same mangled name. This bug caused compiler crashes, link-time clashes,
+ and debugger crashes. Fixing this bug required breaking ABI
+ compatibility for the functions involved. The functions in questions
+ are those whose types involve non-type template arguments whose
+ mangled representations require more than one digit.
+
+* Support for assignment to `this' has been removed. This idiom
+ was used in the very early days of C++, before users were allowed
+ to overload `operator new'; it is no longer allowed by the C++
+ standard.
+
+* Support for signatures, a G++ extension, have been removed.
+
+* Certain invalid conversions that were previously accepted will now
+ be rejected. For example, assigning function pointers of one type
+ to function pointers of another type now requires a cast, whereas
+ previously g++ would sometimes accept the code even without the
+ cast.
+
+* G++ previously allowed `sizeof (X::Y)' where Y was a non-static
+ member of X, even if the `sizeof' expression occurred outside
+ of a non-static member function of X (or one of its derived classes,
+ or a member-initializer for X or one of its derived classes.) This
+ extension has been removed.
+
+* G++ no longer allows you to overload the conditional operator (i.e.,
+ the `?:' operator.)
+
+* The "named return value" extension:
+
+ int f () return r { r = 3; }
+
+ has been deprecated, and will be removed in a future version of G++.
+
+*** Changes in GCC 2.95:
+
+* Messages about non-conformant code that we can still handle ("pedwarns")
+ are now errors by default, rather than warnings. This can be reverted
+ with -fpermissive, and is overridden by -pedantic or -pedantic-errors.
+
+* String constants are now of type `const char[n]', rather than `char[n]'.
+ This can be reverted with -fno-const-strings.
+
+* References to functions are now supported.
+
+* Lookup of class members during class definition now works in all cases.
+
+* In overload resolution, type conversion operators are now properly
+ treated as always coming from the most derived class.
+
+* C9x-style restricted pointers are supported, using the `__restrict'
+ keyword.
+
+* You can now use -fno-implicit-inline-templates to suppress writing out
+ implicit instantiations of inline templates. Normally we do write them
+ out, even with -fno-implicit-templates, so that optimization doesn't
+ affect which instantiations are needed.
+
+* -fstrict-prototype now also suppresses implicit declarations.
+
+* Many obsolete options have been removed: -fall-virtual, -fmemoize-lookups,
+ -fsave-memoized, +e?, -fenum-int-equivalence, -fno-nonnull-objects.
+
+* Unused virtual functions can be discarded on some targets by specifying
+ -ffunction-sections -fvtable-gc to the compiler and --gc-sections to the
+ linker. Unfortunately, this only works on GNU/Linux if you're linking
+ statically.
+
+* Lots of bugs stomped.
+
+*** Changes in EGCS 1.1:
+
+* Namespaces are fully supported. The library has not yet been converted
+ to use namespace std, however, and the old std-faking code is still on by
+ default. To turn it off, you can use -fhonor-std.
+
+* Massive template improvements:
+ + member template classes are supported.
+ + template friends are supported.
+ + template template parameters are supported.
+ + local classes in templates are supported.
+ + lots of bugs fixed.
+
+* operator new now throws bad_alloc where appropriate.
+
+* Exception handling is now thread safe, and supports nested exceptions and
+ placement delete. Exception handling overhead on x86 is much lower with
+ GNU as 2.9.
+
+* protected virtual inheritance is now supported.
+
+* Loops are optimized better; we now move the test to the end in most
+ cases, like the C frontend does.
+
+* For class D derived from B which has a member 'int i', &D::i is now of
+ type 'int B::*' instead of 'int D::*'.
+
+* An _experimental_ new ABI for g++ can be turned on with -fnew-abi. The
+ current features of this are more efficient allocation of base classes
+ (including the empty base optimization), and more compact mangling of C++
+ symbol names (which can be turned on separately with -fsquangle). This
+ ABI is subject to change without notice, so don't use it for anything
+ that you don't want to rebuild with every release of the compiler.
+
+ As with all ABI-changing flags, this flag is for experts only, as all
+ code (including the library code in libgcc and libstdc++) must be
+ compiled with the same ABI.
+
+*** Changes in EGCS 1.0:
+
+* A public review copy of the December 1996 Draft of the ISO/ANSI C++
+ standard is now available. See
+
+ http://www.cygnus.com/misc/wp/
+
+ for more information.
+
+* g++ now uses a new implementation of templates. The basic idea is that
+ now templates are minimally parsed when seen and then expanded later.
+ This allows conformant early name binding and instantiation controls,
+ since instantiations no longer have to go through the parser.
+
+ What you get:
+
+ + Inlining of template functions works without any extra effort or
+ modifications.
+ + Instantiations of class templates and methods defined in the class
+ body are deferred until they are actually needed (unless
+ -fexternal-templates is specified).
+ + Nested types in class templates work.
+ + Static data member templates work.
+ + Member function templates are now supported.
+ + Partial specialization of class templates is now supported.
+ + Explicit specification of template parameters to function templates
+ is now supported.
+
+ Things you may need to fix in your code:
+
+ + Syntax errors in templates that are never instantiated will now be
+ diagnosed.
+ + Types and class templates used in templates must be declared
+ first, or the compiler will assume they are not types, and fail.
+ + Similarly, nested types of template type parameters must be tagged
+ with the 'typename' keyword, except in base lists. In many cases,
+ but not all, the compiler will tell you where you need to add
+ 'typename'. For more information, see
+
+ http://www.cygnus.com/misc/wp/dec96pub/template.html#temp.res
+
+ + Guiding declarations are no longer supported. Function declarations,
+ including friend declarations, do not refer to template instantiations.
+ You can restore the old behavior with -fguiding-decls until you fix
+ your code.
+
+ Other features:
+
+ + Default function arguments in templates will not be evaluated (or
+ checked for semantic validity) unless they are needed. Default
+ arguments in class bodies will not be parsed until the class
+ definition is complete.
+ + The -ftemplate-depth-NN flag can be used to increase the maximum
+ recursive template instantiation depth, which defaults to 17. If you
+ need to use this flag, the compiler will tell you.
+ + Explicit instantiation of template constructors and destructors is
+ now supported. For instance:
+
+ template A<int>::A(const A&);
+
+ Still not supported:
+
+ + Member class templates.
+ + Template friends.
+
+* Exception handling support has been significantly improved and is on by
+ default. The compiler supports two mechanisms for walking back up the
+ call stack; one relies on static information about how registers are
+ saved, and causes no runtime overhead for code that does not throw
+ exceptions. The other mechanism uses setjmp and longjmp equivalents, and
+ can result in quite a bit of runtime overhead. You can determine which
+ mechanism is the default for your target by compiling a testcase that
+ uses exceptions and doing an 'nm' on the object file; if it uses __throw,
+ it's using the first mechanism. If it uses __sjthrow, it's using the
+ second.
+
+ You can turn EH support off with -fno-exceptions.
+
+* RTTI support has been rewritten to work properly and is now on by default.
+ This means code that uses virtual functions will have a modest space
+ overhead. You can use the -fno-rtti flag to disable RTTI support.
+
+* On ELF systems, duplicate copies of symbols with 'initialized common'
+ linkage (such as template instantiations, vtables, and extern inlines)
+ will now be discarded by the GNU linker, so you don't need to use -frepo.
+ This support requires GNU ld from binutils 2.8 or later.
+
+* The overload resolution code has been rewritten to conform to the latest
+ C++ Working Paper. Built-in operators are now considered as candidates
+ in operator overload resolution. Function template overloading chooses
+ the more specialized template, and handles base classes in type deduction
+ and guiding declarations properly. In this release the old code can
+ still be selected with -fno-ansi-overloading, although this is not
+ supported and will be removed in a future release.
+
+* Standard usage syntax for the std namespace is supported; std is treated
+ as an alias for global scope. General namespaces are still not supported.
+
+* New flags:
+
+ + New warning -Wno-pmf-conversion (don't warn about
+ converting from a bound member function pointer to function
+ pointer).
+
+ + A flag -Weffc++ has been added for violations of some of the style
+ guidelines in Scott Meyers' _Effective C++_ books.
+
+ + -Woverloaded-virtual now warns if a virtual function in a base
+ class is hidden in a derived class, rather than warning about
+ virtual functions being overloaded (even if all of the inherited
+ signatures are overridden) as it did before.
+
+ + -Wall no longer implies -W. The new warning flag, -Wsign-compare,
+ included in -Wall, warns about dangerous comparisons of signed and
+ unsigned values. Only the flag is new; it was previously part of
+ -W.
+
+ + The new flag, -fno-weak, disables the use of weak symbols.
+
+* Synthesized methods are now emitted in any translation units that need
+ an out-of-line copy. They are no longer affected by #pragma interface
+ or #pragma implementation.
+
+* __FUNCTION__ and __PRETTY_FUNCTION__ are now treated as variables by the
+ parser; previously they were treated as string constants. So code like
+ `printf (__FUNCTION__ ": foo")' must be rewritten to
+ `printf ("%s: foo", __FUNCTION__)'. This is necessary for templates.
+
+* local static variables in extern inline functions will be shared between
+ translation units.
+
+* -fvtable-thunks is supported for all targets, and is the default for
+ GNU/Linux with glibc 2.x (also called libc 6.x).
+
+* bool is now always the same size as another built-in type. Previously,
+ a 64-bit RISC target using a 32-bit ABI would have 32-bit pointers and a
+ 64-bit bool. This should only affect Irix 6, which was not supported in
+ 2.7.2.
+
+* new (nothrow) is now supported.
+
+* Synthesized destructors are no longer made virtual just because the class
+ already has virtual functions, only if they override a virtual destructor
+ in a base class. The compiler will warn if this affects your code.
+
+* The g++ driver now only links against libstdc++, not libg++; it is
+ functionally identical to the c++ driver.
+
+* (void *)0 is no longer considered a null pointer constant; NULL in
+ <stddef.h> is now defined as __null, a magic constant of type (void *)
+ normally, or (size_t) with -ansi.
+
+* The name of a class is now implicitly declared in its own scope; A::A
+ refers to A.
+
+* Local classes are now supported.
+
+* __attribute__ can now be attached to types as well as declarations.
+
+* The compiler no longer emits a warning if an ellipsis is used as a
+ function's argument list.
+
+* Definition of nested types outside of their containing class is now
+ supported. For instance:
+
+ struct A {
+ struct B;
+ B* bp;
+ };
+
+ struct A::B {
+ int member;
+ };
+
+* On the HPPA, some classes that do not define a copy constructor
+ will be passed and returned in memory again so that functions
+ returning those types can be inlined.
+
+*** The g++ team thanks everyone that contributed to this release,
+ but especially:
+
+* Joe Buck <jbuck@synopsys.com>, the maintainer of the g++ FAQ.
+* Brendan Kehoe <brendan@cygnus.com>, who coordinates testing of g++.
+* Jason Merrill <jason@cygnus.com>, the g++ maintainer.
+* Mark Mitchell <mmitchell@usa.net>, who implemented member function
+ templates and explicit qualification of function templates.
+* Mike Stump <mrs@wrs.com>, the previous g++ maintainer, who did most of
+ the exception handling work.
+
+
+Copyright (C) 1997-2014 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc-4.9/gcc/cp/call.c b/gcc-4.9/gcc/cp/call.c
new file mode 100644
index 000000000..877f6d9cf
--- /dev/null
+++ b/gcc-4.9/gcc/cp/call.c
@@ -0,0 +1,9544 @@
+/* Functions related to invoking methods and overloaded functions.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Contributed by Michael Tiemann (tiemann@cygnus.com) and
+ modified by Brendan Kehoe (brendan@cygnus.com).
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* High-level class interface. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stor-layout.h"
+#include "trans-mem.h"
+#include "stringpool.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "toplev.h"
+#include "diagnostic-core.h"
+#include "intl.h"
+#include "target.h"
+#include "convert.h"
+#include "langhooks.h"
+#include "c-family/c-objc.h"
+#include "timevar.h"
+#include "cgraph.h"
+
+/* The various kinds of conversion. */
+
+typedef enum conversion_kind {
+ ck_identity,
+ ck_lvalue,
+ ck_qual,
+ ck_std,
+ ck_ptr,
+ ck_pmem,
+ ck_base,
+ ck_ref_bind,
+ ck_user,
+ ck_ambig,
+ ck_list,
+ ck_aggr,
+ ck_rvalue
+} conversion_kind;
+
+/* The rank of the conversion. Order of the enumerals matters; better
+ conversions should come earlier in the list. */
+
+typedef enum conversion_rank {
+ cr_identity,
+ cr_exact,
+ cr_promotion,
+ cr_std,
+ cr_pbool,
+ cr_user,
+ cr_ellipsis,
+ cr_bad
+} conversion_rank;
+
+/* An implicit conversion sequence, in the sense of [over.best.ics].
+ The first conversion to be performed is at the end of the chain.
+ That conversion is always a cr_identity conversion. */
+
+typedef struct conversion conversion;
+struct conversion {
+ /* The kind of conversion represented by this step. */
+ conversion_kind kind;
+ /* The rank of this conversion. */
+ conversion_rank rank;
+ BOOL_BITFIELD user_conv_p : 1;
+ BOOL_BITFIELD ellipsis_p : 1;
+ BOOL_BITFIELD this_p : 1;
+ /* True if this conversion would be permitted with a bending of
+ language standards, e.g. disregarding pointer qualifiers or
+ converting integers to pointers. */
+ BOOL_BITFIELD bad_p : 1;
+ /* If KIND is ck_ref_bind ck_base_conv, true to indicate that a
+ temporary should be created to hold the result of the
+ conversion. */
+ BOOL_BITFIELD need_temporary_p : 1;
+ /* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion
+ from a pointer-to-derived to pointer-to-base is being performed. */
+ BOOL_BITFIELD base_p : 1;
+ /* If KIND is ck_ref_bind, true when either an lvalue reference is
+ being bound to an lvalue expression or an rvalue reference is
+ being bound to an rvalue expression. If KIND is ck_rvalue,
+ true when we should treat an lvalue as an rvalue (12.8p33). If
+ KIND is ck_base, always false. */
+ BOOL_BITFIELD rvaluedness_matches_p: 1;
+ BOOL_BITFIELD check_narrowing: 1;
+ /* The type of the expression resulting from the conversion. */
+ tree type;
+ union {
+ /* The next conversion in the chain. Since the conversions are
+ arranged from outermost to innermost, the NEXT conversion will
+ actually be performed before this conversion. This variant is
+ used only when KIND is neither ck_identity, ck_ambig nor
+ ck_list. Please use the next_conversion function instead
+ of using this field directly. */
+ conversion *next;
+ /* The expression at the beginning of the conversion chain. This
+ variant is used only if KIND is ck_identity or ck_ambig. */
+ tree expr;
+ /* The array of conversions for an initializer_list, so this
+ variant is used only when KIN D is ck_list. */
+ conversion **list;
+ } u;
+ /* The function candidate corresponding to this conversion
+ sequence. This field is only used if KIND is ck_user. */
+ struct z_candidate *cand;
+};
+
+#define CONVERSION_RANK(NODE) \
+ ((NODE)->bad_p ? cr_bad \
+ : (NODE)->ellipsis_p ? cr_ellipsis \
+ : (NODE)->user_conv_p ? cr_user \
+ : (NODE)->rank)
+
+#define BAD_CONVERSION_RANK(NODE) \
+ ((NODE)->ellipsis_p ? cr_ellipsis \
+ : (NODE)->user_conv_p ? cr_user \
+ : (NODE)->rank)
+
+static struct obstack conversion_obstack;
+static bool conversion_obstack_initialized;
+struct rejection_reason;
+
+static struct z_candidate * tourney (struct z_candidate *, tsubst_flags_t);
+static int equal_functions (tree, tree);
+static int joust (struct z_candidate *, struct z_candidate *, bool,
+ tsubst_flags_t);
+static int compare_ics (conversion *, conversion *);
+static tree build_over_call (struct z_candidate *, int, tsubst_flags_t);
+static tree build_java_interface_fn_ref (tree, tree);
+#define convert_like(CONV, EXPR, COMPLAIN) \
+ convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0, \
+ /*issue_conversion_warnings=*/true, \
+ /*c_cast_p=*/false, (COMPLAIN))
+#define convert_like_with_context(CONV, EXPR, FN, ARGNO, COMPLAIN ) \
+ convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0, \
+ /*issue_conversion_warnings=*/true, \
+ /*c_cast_p=*/false, (COMPLAIN))
+static tree convert_like_real (conversion *, tree, tree, int, int, bool,
+ bool, tsubst_flags_t);
+static void op_error (location_t, enum tree_code, enum tree_code, tree,
+ tree, tree, bool);
+static struct z_candidate *build_user_type_conversion_1 (tree, tree, int,
+ tsubst_flags_t);
+static void print_z_candidate (location_t, const char *, struct z_candidate *);
+static void print_z_candidates (location_t, struct z_candidate *);
+static tree build_this (tree);
+static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
+static bool any_strictly_viable (struct z_candidate *);
+static struct z_candidate *add_template_candidate
+ (struct z_candidate **, tree, tree, tree, tree, const vec<tree, va_gc> *,
+ tree, tree, tree, int, unification_kind_t, tsubst_flags_t);
+static struct z_candidate *add_template_candidate_real
+ (struct z_candidate **, tree, tree, tree, tree, const vec<tree, va_gc> *,
+ tree, tree, tree, int, tree, unification_kind_t, tsubst_flags_t);
+static struct z_candidate *add_template_conv_candidate
+ (struct z_candidate **, tree, tree, tree, const vec<tree, va_gc> *,
+ tree, tree, tree, tsubst_flags_t);
+static void add_builtin_candidates
+ (struct z_candidate **, enum tree_code, enum tree_code,
+ tree, tree *, int, tsubst_flags_t);
+static void add_builtin_candidate
+ (struct z_candidate **, enum tree_code, enum tree_code,
+ tree, tree, tree, tree *, tree *, int, tsubst_flags_t);
+static bool is_complete (tree);
+static void build_builtin_candidate
+ (struct z_candidate **, tree, tree, tree, tree *, tree *,
+ int, tsubst_flags_t);
+static struct z_candidate *add_conv_candidate
+ (struct z_candidate **, tree, tree, tree, const vec<tree, va_gc> *, tree,
+ tree, tsubst_flags_t);
+static struct z_candidate *add_function_candidate
+ (struct z_candidate **, tree, tree, tree, const vec<tree, va_gc> *, tree,
+ tree, int, tsubst_flags_t);
+static conversion *implicit_conversion (tree, tree, tree, bool, int,
+ tsubst_flags_t);
+static conversion *standard_conversion (tree, tree, tree, bool, int);
+static conversion *reference_binding (tree, tree, tree, bool, int,
+ tsubst_flags_t);
+static conversion *build_conv (conversion_kind, tree, conversion *);
+static conversion *build_list_conv (tree, tree, int, tsubst_flags_t);
+static conversion *next_conversion (conversion *);
+static bool is_subseq (conversion *, conversion *);
+static conversion *maybe_handle_ref_bind (conversion **);
+static void maybe_handle_implicit_object (conversion **);
+static struct z_candidate *add_candidate
+ (struct z_candidate **, tree, tree, const vec<tree, va_gc> *, size_t,
+ conversion **, tree, tree, int, struct rejection_reason *);
+static tree source_type (conversion *);
+static void add_warning (struct z_candidate *, struct z_candidate *);
+static bool reference_compatible_p (tree, tree);
+static conversion *direct_reference_binding (tree, conversion *);
+static bool promoted_arithmetic_type_p (tree);
+static conversion *conditional_conversion (tree, tree, tsubst_flags_t);
+static char *name_as_c_string (tree, tree, bool *);
+static tree prep_operand (tree);
+static void add_candidates (tree, tree, const vec<tree, va_gc> *, tree, tree,
+ bool, tree, tree, int, struct z_candidate **,
+ tsubst_flags_t);
+static conversion *merge_conversion_sequences (conversion *, conversion *);
+static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t);
+
+/* Returns nonzero iff the destructor name specified in NAME matches BASETYPE.
+ NAME can take many forms... */
+
+bool
+check_dtor_name (tree basetype, tree name)
+{
+ /* Just accept something we've already complained about. */
+ if (name == error_mark_node)
+ return true;
+
+ if (TREE_CODE (name) == TYPE_DECL)
+ name = TREE_TYPE (name);
+ else if (TYPE_P (name))
+ /* OK */;
+ else if (identifier_p (name))
+ {
+ if ((MAYBE_CLASS_TYPE_P (basetype)
+ && name == constructor_name (basetype))
+ || (TREE_CODE (basetype) == ENUMERAL_TYPE
+ && name == TYPE_IDENTIFIER (basetype)))
+ return true;
+ else
+ name = get_type_value (name);
+ }
+ else
+ {
+ /* In the case of:
+
+ template <class T> struct S { ~S(); };
+ int i;
+ i.~S();
+
+ NAME will be a class template. */
+ gcc_assert (DECL_CLASS_TEMPLATE_P (name));
+ return false;
+ }
+
+ if (!name || name == error_mark_node)
+ return false;
+ return same_type_p (TYPE_MAIN_VARIANT (basetype), TYPE_MAIN_VARIANT (name));
+}
+
+/* We want the address of a function or method. We avoid creating a
+ pointer-to-member function. */
+
+tree
+build_addr_func (tree function, tsubst_flags_t complain)
+{
+ tree type = TREE_TYPE (function);
+
+ /* We have to do these by hand to avoid real pointer to member
+ functions. */
+ if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ if (TREE_CODE (function) == OFFSET_REF)
+ {
+ tree object = build_address (TREE_OPERAND (function, 0));
+ return get_member_function_from_ptrfunc (&object,
+ TREE_OPERAND (function, 1),
+ complain);
+ }
+ function = build_address (function);
+ }
+ else
+ function = decay_conversion (function, complain);
+
+ return function;
+}
+
+/* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or
+ POINTER_TYPE to those. Note, pointer to member function types
+ (TYPE_PTRMEMFUNC_P) must be handled by our callers. There are
+ two variants. build_call_a is the primitive taking an array of
+ arguments, while build_call_n is a wrapper that handles varargs. */
+
+tree
+build_call_n (tree function, int n, ...)
+{
+ if (n == 0)
+ return build_call_a (function, 0, NULL);
+ else
+ {
+ tree *argarray = XALLOCAVEC (tree, n);
+ va_list ap;
+ int i;
+
+ va_start (ap, n);
+ for (i = 0; i < n; i++)
+ argarray[i] = va_arg (ap, tree);
+ va_end (ap);
+ return build_call_a (function, n, argarray);
+ }
+}
+
+/* Update various flags in cfun and the call itself based on what is being
+ called. Split out of build_call_a so that bot_manip can use it too. */
+
+void
+set_flags_from_callee (tree call)
+{
+ int nothrow;
+ tree decl = get_callee_fndecl (call);
+
+ /* We check both the decl and the type; a function may be known not to
+ throw without being declared throw(). */
+ nothrow = ((decl && TREE_NOTHROW (decl))
+ || TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (call)))));
+
+ if (!nothrow && at_function_scope_p () && cfun && cp_function_chain)
+ cp_function_chain->can_throw = 1;
+
+ if (decl && TREE_THIS_VOLATILE (decl) && cfun && cp_function_chain)
+ current_function_returns_abnormally = 1;
+
+ TREE_NOTHROW (call) = nothrow;
+}
+
+tree
+build_call_a (tree function, int n, tree *argarray)
+{
+ tree decl;
+ tree result_type;
+ tree fntype;
+ int i;
+
+ function = build_addr_func (function, tf_warning_or_error);
+
+ gcc_assert (TYPE_PTR_P (TREE_TYPE (function)));
+ fntype = TREE_TYPE (TREE_TYPE (function));
+ gcc_assert (TREE_CODE (fntype) == FUNCTION_TYPE
+ || TREE_CODE (fntype) == METHOD_TYPE);
+ result_type = TREE_TYPE (fntype);
+ /* An rvalue has no cv-qualifiers. */
+ if (SCALAR_TYPE_P (result_type) || VOID_TYPE_P (result_type))
+ result_type = cv_unqualified (result_type);
+
+ function = build_call_array_loc (input_location,
+ result_type, function, n, argarray);
+ set_flags_from_callee (function);
+
+ decl = get_callee_fndecl (function);
+
+ if (decl && !TREE_USED (decl))
+ {
+ /* We invoke build_call directly for several library
+ functions. These may have been declared normally if
+ we're building libgcc, so we can't just check
+ DECL_ARTIFICIAL. */
+ gcc_assert (DECL_ARTIFICIAL (decl)
+ || !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)),
+ "__", 2));
+ mark_used (decl);
+ }
+
+ if (decl && TREE_DEPRECATED (decl))
+ warn_deprecated_use (decl, NULL_TREE);
+ require_complete_eh_spec_types (fntype, decl);
+
+ TREE_HAS_CONSTRUCTOR (function) = (decl && DECL_CONSTRUCTOR_P (decl));
+
+ /* Don't pass empty class objects by value. This is useful
+ for tags in STL, which are used to control overload resolution.
+ We don't need to handle other cases of copying empty classes. */
+ if (! decl || ! DECL_BUILT_IN (decl))
+ for (i = 0; i < n; i++)
+ {
+ tree arg = CALL_EXPR_ARG (function, i);
+ if (is_empty_class (TREE_TYPE (arg))
+ && ! TREE_ADDRESSABLE (TREE_TYPE (arg)))
+ {
+ tree t = build0 (EMPTY_CLASS_EXPR, TREE_TYPE (arg));
+ arg = build2 (COMPOUND_EXPR, TREE_TYPE (t), arg, t);
+ CALL_EXPR_ARG (function, i) = arg;
+ }
+ }
+
+ return function;
+}
+
+/* Build something of the form ptr->method (args)
+ or object.method (args). This can also build
+ calls to constructors, and find friends.
+
+ Member functions always take their class variable
+ as a pointer.
+
+ INSTANCE is a class instance.
+
+ NAME is the name of the method desired, usually an IDENTIFIER_NODE.
+
+ PARMS help to figure out what that NAME really refers to.
+
+ BASETYPE_PATH, if non-NULL, contains a chain from the type of INSTANCE
+ down to the real instance type to use for access checking. We need this
+ information to get protected accesses correct.
+
+ FLAGS is the logical disjunction of zero or more LOOKUP_
+ flags. See cp-tree.h for more info.
+
+ If this is all OK, calls build_function_call with the resolved
+ member function.
+
+ This function must also handle being called to perform
+ initialization, promotion/coercion of arguments, and
+ instantiation of default parameters.
+
+ Note that NAME may refer to an instance variable name. If
+ `operator()()' is defined for the type of that field, then we return
+ that result. */
+
+/* New overloading code. */
+
+typedef struct z_candidate z_candidate;
+
+typedef struct candidate_warning candidate_warning;
+struct candidate_warning {
+ z_candidate *loser;
+ candidate_warning *next;
+};
+
+/* Information for providing diagnostics about why overloading failed. */
+
+enum rejection_reason_code {
+ rr_none,
+ rr_arity,
+ rr_explicit_conversion,
+ rr_template_conversion,
+ rr_arg_conversion,
+ rr_bad_arg_conversion,
+ rr_template_unification,
+ rr_invalid_copy
+};
+
+struct conversion_info {
+ /* The index of the argument, 0-based. */
+ int n_arg;
+ /* The type of the actual argument. */
+ tree from_type;
+ /* The type of the formal argument. */
+ tree to_type;
+};
+
+struct rejection_reason {
+ enum rejection_reason_code code;
+ union {
+ /* Information about an arity mismatch. */
+ struct {
+ /* The expected number of arguments. */
+ int expected;
+ /* The actual number of arguments in the call. */
+ int actual;
+ /* Whether the call was a varargs call. */
+ bool call_varargs_p;
+ } arity;
+ /* Information about an argument conversion mismatch. */
+ struct conversion_info conversion;
+ /* Same, but for bad argument conversions. */
+ struct conversion_info bad_conversion;
+ /* Information about template unification failures. These are the
+ parameters passed to fn_type_unification. */
+ struct {
+ tree tmpl;
+ tree explicit_targs;
+ int num_targs;
+ const tree *args;
+ unsigned int nargs;
+ tree return_type;
+ unification_kind_t strict;
+ int flags;
+ } template_unification;
+ /* Information about template instantiation failures. These are the
+ parameters passed to instantiate_template. */
+ struct {
+ tree tmpl;
+ tree targs;
+ } template_instantiation;
+ } u;
+};
+
+struct z_candidate {
+ /* The FUNCTION_DECL that will be called if this candidate is
+ selected by overload resolution. */
+ tree fn;
+ /* If not NULL_TREE, the first argument to use when calling this
+ function. */
+ tree first_arg;
+ /* The rest of the arguments to use when calling this function. If
+ there are no further arguments this may be NULL or it may be an
+ empty vector. */
+ const vec<tree, va_gc> *args;
+ /* The implicit conversion sequences for each of the arguments to
+ FN. */
+ conversion **convs;
+ /* The number of implicit conversion sequences. */
+ size_t num_convs;
+ /* If FN is a user-defined conversion, the standard conversion
+ sequence from the type returned by FN to the desired destination
+ type. */
+ conversion *second_conv;
+ int viable;
+ struct rejection_reason *reason;
+ /* If FN is a member function, the binfo indicating the path used to
+ qualify the name of FN at the call site. This path is used to
+ determine whether or not FN is accessible if it is selected by
+ overload resolution. The DECL_CONTEXT of FN will always be a
+ (possibly improper) base of this binfo. */
+ tree access_path;
+ /* If FN is a non-static member function, the binfo indicating the
+ subobject to which the `this' pointer should be converted if FN
+ is selected by overload resolution. The type pointed to by
+ the `this' pointer must correspond to the most derived class
+ indicated by the CONVERSION_PATH. */
+ tree conversion_path;
+ tree template_decl;
+ tree explicit_targs;
+ candidate_warning *warnings;
+ z_candidate *next;
+};
+
+/* Returns true iff T is a null pointer constant in the sense of
+ [conv.ptr]. */
+
+bool
+null_ptr_cst_p (tree t)
+{
+ /* [conv.ptr]
+
+ A null pointer constant is an integral constant expression
+ (_expr.const_) rvalue of integer type that evaluates to zero or
+ an rvalue of type std::nullptr_t. */
+ if (NULLPTR_TYPE_P (TREE_TYPE (t)))
+ return true;
+ if (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ /* Core issue 903 says only literal 0 is a null pointer constant. */
+ if (cxx_dialect < cxx11)
+ t = maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none));
+ STRIP_NOPS (t);
+ if (integer_zerop (t) && !TREE_OVERFLOW (t))
+ return true;
+ }
+ return false;
+}
+
+/* Returns true iff T is a null member pointer value (4.11). */
+
+bool
+null_member_pointer_value_p (tree t)
+{
+ tree type = TREE_TYPE (t);
+ if (!type)
+ return false;
+ else if (TYPE_PTRMEMFUNC_P (type))
+ return (TREE_CODE (t) == CONSTRUCTOR
+ && integer_zerop (CONSTRUCTOR_ELT (t, 0)->value));
+ else if (TYPE_PTRDATAMEM_P (type))
+ return integer_all_onesp (t);
+ else
+ return false;
+}
+
+/* Returns nonzero if PARMLIST consists of only default parms,
+ ellipsis, and/or undeduced parameter packs. */
+
+bool
+sufficient_parms_p (const_tree parmlist)
+{
+ for (; parmlist && parmlist != void_list_node;
+ parmlist = TREE_CHAIN (parmlist))
+ if (!TREE_PURPOSE (parmlist)
+ && !PACK_EXPANSION_P (TREE_VALUE (parmlist)))
+ return false;
+ return true;
+}
+
+/* Allocate N bytes of memory from the conversion obstack. The memory
+ is zeroed before being returned. */
+
+static void *
+conversion_obstack_alloc (size_t n)
+{
+ void *p;
+ if (!conversion_obstack_initialized)
+ {
+ gcc_obstack_init (&conversion_obstack);
+ conversion_obstack_initialized = true;
+ }
+ p = obstack_alloc (&conversion_obstack, n);
+ memset (p, 0, n);
+ return p;
+}
+
+/* Allocate rejection reasons. */
+
+static struct rejection_reason *
+alloc_rejection (enum rejection_reason_code code)
+{
+ struct rejection_reason *p;
+ p = (struct rejection_reason *) conversion_obstack_alloc (sizeof *p);
+ p->code = code;
+ return p;
+}
+
+static struct rejection_reason *
+arity_rejection (tree first_arg, int expected, int actual)
+{
+ struct rejection_reason *r = alloc_rejection (rr_arity);
+ int adjust = first_arg != NULL_TREE;
+ r->u.arity.expected = expected - adjust;
+ r->u.arity.actual = actual - adjust;
+ return r;
+}
+
+static struct rejection_reason *
+arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to)
+{
+ struct rejection_reason *r = alloc_rejection (rr_arg_conversion);
+ int adjust = first_arg != NULL_TREE;
+ r->u.conversion.n_arg = n_arg - adjust;
+ r->u.conversion.from_type = from;
+ r->u.conversion.to_type = to;
+ return r;
+}
+
+static struct rejection_reason *
+bad_arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to)
+{
+ struct rejection_reason *r = alloc_rejection (rr_bad_arg_conversion);
+ int adjust = first_arg != NULL_TREE;
+ r->u.bad_conversion.n_arg = n_arg - adjust;
+ r->u.bad_conversion.from_type = from;
+ r->u.bad_conversion.to_type = to;
+ return r;
+}
+
+static struct rejection_reason *
+explicit_conversion_rejection (tree from, tree to)
+{
+ struct rejection_reason *r = alloc_rejection (rr_explicit_conversion);
+ r->u.conversion.n_arg = 0;
+ r->u.conversion.from_type = from;
+ r->u.conversion.to_type = to;
+ return r;
+}
+
+static struct rejection_reason *
+template_conversion_rejection (tree from, tree to)
+{
+ struct rejection_reason *r = alloc_rejection (rr_template_conversion);
+ r->u.conversion.n_arg = 0;
+ r->u.conversion.from_type = from;
+ r->u.conversion.to_type = to;
+ return r;
+}
+
+static struct rejection_reason *
+template_unification_rejection (tree tmpl, tree explicit_targs, tree targs,
+ const tree *args, unsigned int nargs,
+ tree return_type, unification_kind_t strict,
+ int flags)
+{
+ size_t args_n_bytes = sizeof (*args) * nargs;
+ tree *args1 = (tree *) conversion_obstack_alloc (args_n_bytes);
+ struct rejection_reason *r = alloc_rejection (rr_template_unification);
+ r->u.template_unification.tmpl = tmpl;
+ r->u.template_unification.explicit_targs = explicit_targs;
+ r->u.template_unification.num_targs = TREE_VEC_LENGTH (targs);
+ /* Copy args to our own storage. */
+ memcpy (args1, args, args_n_bytes);
+ r->u.template_unification.args = args1;
+ r->u.template_unification.nargs = nargs;
+ r->u.template_unification.return_type = return_type;
+ r->u.template_unification.strict = strict;
+ r->u.template_unification.flags = flags;
+ return r;
+}
+
+static struct rejection_reason *
+template_unification_error_rejection (void)
+{
+ return alloc_rejection (rr_template_unification);
+}
+
+static struct rejection_reason *
+invalid_copy_with_fn_template_rejection (void)
+{
+ struct rejection_reason *r = alloc_rejection (rr_invalid_copy);
+ return r;
+}
+
+/* Dynamically allocate a conversion. */
+
+static conversion *
+alloc_conversion (conversion_kind kind)
+{
+ conversion *c;
+ c = (conversion *) conversion_obstack_alloc (sizeof (conversion));
+ c->kind = kind;
+ return c;
+}
+
+#ifdef ENABLE_CHECKING
+
+/* Make sure that all memory on the conversion obstack has been
+ freed. */
+
+void
+validate_conversion_obstack (void)
+{
+ if (conversion_obstack_initialized)
+ gcc_assert ((obstack_next_free (&conversion_obstack)
+ == obstack_base (&conversion_obstack)));
+}
+
+#endif /* ENABLE_CHECKING */
+
+/* Dynamically allocate an array of N conversions. */
+
+static conversion **
+alloc_conversions (size_t n)
+{
+ return (conversion **) conversion_obstack_alloc (n * sizeof (conversion *));
+}
+
+static conversion *
+build_conv (conversion_kind code, tree type, conversion *from)
+{
+ conversion *t;
+ conversion_rank rank = CONVERSION_RANK (from);
+
+ /* Note that the caller is responsible for filling in t->cand for
+ user-defined conversions. */
+ t = alloc_conversion (code);
+ t->type = type;
+ t->u.next = from;
+
+ switch (code)
+ {
+ case ck_ptr:
+ case ck_pmem:
+ case ck_base:
+ case ck_std:
+ if (rank < cr_std)
+ rank = cr_std;
+ break;
+
+ case ck_qual:
+ if (rank < cr_exact)
+ rank = cr_exact;
+ break;
+
+ default:
+ break;
+ }
+ t->rank = rank;
+ t->user_conv_p = (code == ck_user || from->user_conv_p);
+ t->bad_p = from->bad_p;
+ t->base_p = false;
+ return t;
+}
+
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, a
+ specialization of std::initializer_list<T>, if such a conversion is
+ possible. */
+
+static conversion *
+build_list_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
+{
+ tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (type), 0);
+ unsigned len = CONSTRUCTOR_NELTS (ctor);
+ conversion **subconvs = alloc_conversions (len);
+ conversion *t;
+ unsigned i;
+ tree val;
+
+ /* Within a list-initialization we can have more user-defined
+ conversions. */
+ flags &= ~LOOKUP_NO_CONVERSION;
+ /* But no narrowing conversions. */
+ flags |= LOOKUP_NO_NARROWING;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val)
+ {
+ conversion *sub
+ = implicit_conversion (elttype, TREE_TYPE (val), val,
+ false, flags, complain);
+ if (sub == NULL)
+ return NULL;
+
+ subconvs[i] = sub;
+ }
+
+ t = alloc_conversion (ck_list);
+ t->type = type;
+ t->u.list = subconvs;
+ t->rank = cr_exact;
+
+ for (i = 0; i < len; ++i)
+ {
+ conversion *sub = subconvs[i];
+ if (sub->rank > t->rank)
+ t->rank = sub->rank;
+ if (sub->user_conv_p)
+ t->user_conv_p = true;
+ if (sub->bad_p)
+ t->bad_p = true;
+ }
+
+ return t;
+}
+
+/* Return the next conversion of the conversion chain (if applicable),
+ or NULL otherwise. Please use this function instead of directly
+ accessing fields of struct conversion. */
+
+static conversion *
+next_conversion (conversion *conv)
+{
+ if (conv == NULL
+ || conv->kind == ck_identity
+ || conv->kind == ck_ambig
+ || conv->kind == ck_list)
+ return NULL;
+ return conv->u.next;
+}
+
+/* Subroutine of build_aggr_conv: check whether CTOR, a braced-init-list,
+ is a valid aggregate initializer for array type ATYPE. */
+
+static bool
+can_convert_array (tree atype, tree ctor, int flags, tsubst_flags_t complain)
+{
+ unsigned i;
+ tree elttype = TREE_TYPE (atype);
+ for (i = 0; i < CONSTRUCTOR_NELTS (ctor); ++i)
+ {
+ tree val = CONSTRUCTOR_ELT (ctor, i)->value;
+ bool ok;
+ if (TREE_CODE (elttype) == ARRAY_TYPE
+ && TREE_CODE (val) == CONSTRUCTOR)
+ ok = can_convert_array (elttype, val, flags, complain);
+ else
+ ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags,
+ complain);
+ if (!ok)
+ return false;
+ }
+ return true;
+}
+
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, an
+ aggregate class, if such a conversion is possible. */
+
+static conversion *
+build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
+{
+ unsigned HOST_WIDE_INT i = 0;
+ conversion *c;
+ tree field = next_initializable_field (TYPE_FIELDS (type));
+ tree empty_ctor = NULL_TREE;
+
+ ctor = reshape_init (type, ctor, tf_none);
+ if (ctor == error_mark_node)
+ return NULL;
+
+ flags |= LOOKUP_NO_NARROWING;
+
+ for (; field; field = next_initializable_field (DECL_CHAIN (field)))
+ {
+ tree ftype = TREE_TYPE (field);
+ tree val;
+ bool ok;
+
+ if (i < CONSTRUCTOR_NELTS (ctor))
+ val = CONSTRUCTOR_ELT (ctor, i)->value;
+ else if (TREE_CODE (ftype) == REFERENCE_TYPE)
+ /* Value-initialization of reference is ill-formed. */
+ return NULL;
+ else
+ {
+ if (empty_ctor == NULL_TREE)
+ empty_ctor = build_constructor (init_list_type_node, NULL);
+ val = empty_ctor;
+ }
+ ++i;
+
+ if (TREE_CODE (ftype) == ARRAY_TYPE
+ && TREE_CODE (val) == CONSTRUCTOR)
+ ok = can_convert_array (ftype, val, flags, complain);
+ else
+ ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags,
+ complain);
+
+ if (!ok)
+ return NULL;
+
+ if (TREE_CODE (type) == UNION_TYPE)
+ break;
+ }
+
+ if (i < CONSTRUCTOR_NELTS (ctor))
+ return NULL;
+
+ c = alloc_conversion (ck_aggr);
+ c->type = type;
+ c->rank = cr_exact;
+ c->user_conv_p = true;
+ c->check_narrowing = true;
+ c->u.next = NULL;
+ return c;
+}
+
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, an
+ array type, if such a conversion is possible. */
+
+static conversion *
+build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
+{
+ conversion *c;
+ unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor);
+ tree elttype = TREE_TYPE (type);
+ unsigned i;
+ tree val;
+ bool bad = false;
+ bool user = false;
+ enum conversion_rank rank = cr_exact;
+
+ if (TYPE_DOMAIN (type)
+ && !variably_modified_type_p (TYPE_DOMAIN (type), NULL_TREE))
+ {
+ unsigned HOST_WIDE_INT alen = tree_to_uhwi (array_type_nelts_top (type));
+ if (alen < len)
+ return NULL;
+ }
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val)
+ {
+ conversion *sub
+ = implicit_conversion (elttype, TREE_TYPE (val), val,
+ false, flags, complain);
+ if (sub == NULL)
+ return NULL;
+
+ if (sub->rank > rank)
+ rank = sub->rank;
+ if (sub->user_conv_p)
+ user = true;
+ if (sub->bad_p)
+ bad = true;
+ }
+
+ c = alloc_conversion (ck_aggr);
+ c->type = type;
+ c->rank = rank;
+ c->user_conv_p = user;
+ c->bad_p = bad;
+ c->u.next = NULL;
+ return c;
+}
+
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, a
+ complex type, if such a conversion is possible. */
+
+static conversion *
+build_complex_conv (tree type, tree ctor, int flags,
+ tsubst_flags_t complain)
+{
+ conversion *c;
+ unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor);
+ tree elttype = TREE_TYPE (type);
+ unsigned i;
+ tree val;
+ bool bad = false;
+ bool user = false;
+ enum conversion_rank rank = cr_exact;
+
+ if (len != 2)
+ return NULL;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val)
+ {
+ conversion *sub
+ = implicit_conversion (elttype, TREE_TYPE (val), val,
+ false, flags, complain);
+ if (sub == NULL)
+ return NULL;
+
+ if (sub->rank > rank)
+ rank = sub->rank;
+ if (sub->user_conv_p)
+ user = true;
+ if (sub->bad_p)
+ bad = true;
+ }
+
+ c = alloc_conversion (ck_aggr);
+ c->type = type;
+ c->rank = rank;
+ c->user_conv_p = user;
+ c->bad_p = bad;
+ c->u.next = NULL;
+ return c;
+}
+
+/* Build a representation of the identity conversion from EXPR to
+ itself. The TYPE should match the type of EXPR, if EXPR is non-NULL. */
+
+static conversion *
+build_identity_conv (tree type, tree expr)
+{
+ conversion *c;
+
+ c = alloc_conversion (ck_identity);
+ c->type = type;
+ c->u.expr = expr;
+
+ return c;
+}
+
+/* Converting from EXPR to TYPE was ambiguous in the sense that there
+ were multiple user-defined conversions to accomplish the job.
+ Build a conversion that indicates that ambiguity. */
+
+static conversion *
+build_ambiguous_conv (tree type, tree expr)
+{
+ conversion *c;
+
+ c = alloc_conversion (ck_ambig);
+ c->type = type;
+ c->u.expr = expr;
+
+ return c;
+}
+
+tree
+strip_top_quals (tree t)
+{
+ if (TREE_CODE (t) == ARRAY_TYPE)
+ return t;
+ return cp_build_qualified_type (t, 0);
+}
+
+/* Returns the standard conversion path (see [conv]) from type FROM to type
+ TO, if any. For proper handling of null pointer constants, you must
+ also pass the expression EXPR to convert from. If C_CAST_P is true,
+ this conversion is coming from a C-style cast. */
+
+static conversion *
+standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
+ int flags)
+{
+ enum tree_code fcode, tcode;
+ conversion *conv;
+ bool fromref = false;
+ tree qualified_to;
+
+ to = non_reference (to);
+ if (TREE_CODE (from) == REFERENCE_TYPE)
+ {
+ fromref = true;
+ from = TREE_TYPE (from);
+ }
+ qualified_to = to;
+ to = strip_top_quals (to);
+ from = strip_top_quals (from);
+
+ if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
+ && expr && type_unknown_p (expr))
+ {
+ tsubst_flags_t tflags = tf_conv;
+ expr = instantiate_type (to, expr, tflags);
+ if (expr == error_mark_node)
+ return NULL;
+ from = TREE_TYPE (expr);
+ }
+
+ fcode = TREE_CODE (from);
+ tcode = TREE_CODE (to);
+
+ conv = build_identity_conv (from, expr);
+ if (fcode == FUNCTION_TYPE || fcode == ARRAY_TYPE)
+ {
+ from = type_decays_to (from);
+ fcode = TREE_CODE (from);
+ conv = build_conv (ck_lvalue, from, conv);
+ }
+ else if (fromref || (expr && lvalue_p (expr)))
+ {
+ if (expr)
+ {
+ tree bitfield_type;
+ bitfield_type = is_bitfield_expr_with_lowered_type (expr);
+ if (bitfield_type)
+ {
+ from = strip_top_quals (bitfield_type);
+ fcode = TREE_CODE (from);
+ }
+ }
+ conv = build_conv (ck_rvalue, from, conv);
+ if (flags & LOOKUP_PREFER_RVALUE)
+ conv->rvaluedness_matches_p = true;
+ }
+
+ /* Allow conversion between `__complex__' data types. */
+ if (tcode == COMPLEX_TYPE && fcode == COMPLEX_TYPE)
+ {
+ /* The standard conversion sequence to convert FROM to TO is
+ the standard conversion sequence to perform componentwise
+ conversion. */
+ conversion *part_conv = standard_conversion
+ (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags);
+
+ if (part_conv)
+ {
+ conv = build_conv (part_conv->kind, to, conv);
+ conv->rank = part_conv->rank;
+ }
+ else
+ conv = NULL;
+
+ return conv;
+ }
+
+ if (same_type_p (from, to))
+ {
+ if (CLASS_TYPE_P (to) && conv->kind == ck_rvalue)
+ conv->type = qualified_to;
+ return conv;
+ }
+
+ /* [conv.ptr]
+ A null pointer constant can be converted to a pointer type; ... A
+ null pointer constant of integral type can be converted to an
+ rvalue of type std::nullptr_t. */
+ if ((tcode == POINTER_TYPE || TYPE_PTRMEM_P (to)
+ || NULLPTR_TYPE_P (to))
+ && expr && null_ptr_cst_p (expr))
+ conv = build_conv (ck_std, to, conv);
+ else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
+ || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
+ {
+ /* For backwards brain damage compatibility, allow interconversion of
+ pointers and integers with a pedwarn. */
+ conv = build_conv (ck_std, to, conv);
+ conv->bad_p = true;
+ }
+ else if (UNSCOPED_ENUM_P (to) && fcode == INTEGER_TYPE)
+ {
+ /* For backwards brain damage compatibility, allow interconversion of
+ enums and integers with a pedwarn. */
+ conv = build_conv (ck_std, to, conv);
+ conv->bad_p = true;
+ }
+ else if ((tcode == POINTER_TYPE && fcode == POINTER_TYPE)
+ || (TYPE_PTRDATAMEM_P (to) && TYPE_PTRDATAMEM_P (from)))
+ {
+ tree to_pointee;
+ tree from_pointee;
+
+ if (tcode == POINTER_TYPE
+ && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (from),
+ TREE_TYPE (to)))
+ ;
+ else if (VOID_TYPE_P (TREE_TYPE (to))
+ && !TYPE_PTRDATAMEM_P (from)
+ && TREE_CODE (TREE_TYPE (from)) != FUNCTION_TYPE)
+ {
+ tree nfrom = TREE_TYPE (from);
+ from = build_pointer_type
+ (cp_build_qualified_type (void_type_node,
+ cp_type_quals (nfrom)));
+ conv = build_conv (ck_ptr, from, conv);
+ }
+ else if (TYPE_PTRDATAMEM_P (from))
+ {
+ tree fbase = TYPE_PTRMEM_CLASS_TYPE (from);
+ tree tbase = TYPE_PTRMEM_CLASS_TYPE (to);
+
+ if (DERIVED_FROM_P (fbase, tbase)
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TYPE_PTRMEM_POINTED_TO_TYPE (from),
+ TYPE_PTRMEM_POINTED_TO_TYPE (to))))
+ {
+ from = build_ptrmem_type (tbase,
+ TYPE_PTRMEM_POINTED_TO_TYPE (from));
+ conv = build_conv (ck_pmem, from, conv);
+ }
+ else if (!same_type_p (fbase, tbase))
+ return NULL;
+ }
+ else if (CLASS_TYPE_P (TREE_TYPE (from))
+ && CLASS_TYPE_P (TREE_TYPE (to))
+ /* [conv.ptr]
+
+ An rvalue of type "pointer to cv D," where D is a
+ class type, can be converted to an rvalue of type
+ "pointer to cv B," where B is a base class (clause
+ _class.derived_) of D. If B is an inaccessible
+ (clause _class.access_) or ambiguous
+ (_class.member.lookup_) base class of D, a program
+ that necessitates this conversion is ill-formed.
+ Therefore, we use DERIVED_FROM_P, and do not check
+ access or uniqueness. */
+ && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
+ {
+ from =
+ cp_build_qualified_type (TREE_TYPE (to),
+ cp_type_quals (TREE_TYPE (from)));
+ from = build_pointer_type (from);
+ conv = build_conv (ck_ptr, from, conv);
+ conv->base_p = true;
+ }
+
+ if (tcode == POINTER_TYPE)
+ {
+ to_pointee = TREE_TYPE (to);
+ from_pointee = TREE_TYPE (from);
+ }
+ else
+ {
+ to_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (to);
+ from_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (from);
+ }
+
+ if (same_type_p (from, to))
+ /* OK */;
+ else if (c_cast_p && comp_ptr_ttypes_const (to, from))
+ /* In a C-style cast, we ignore CV-qualification because we
+ are allowed to perform a static_cast followed by a
+ const_cast. */
+ conv = build_conv (ck_qual, to, conv);
+ else if (!c_cast_p && comp_ptr_ttypes (to_pointee, from_pointee))
+ conv = build_conv (ck_qual, to, conv);
+ else if (expr && string_conv_p (to, expr, 0))
+ /* converting from string constant to char *. */
+ conv = build_conv (ck_qual, to, conv);
+ /* Allow conversions among compatible ObjC pointer types (base
+ conversions have been already handled above). */
+ else if (c_dialect_objc ()
+ && objc_compare_types (to, from, -4, NULL_TREE))
+ conv = build_conv (ck_ptr, to, conv);
+ else if (ptr_reasonably_similar (to_pointee, from_pointee))
+ {
+ conv = build_conv (ck_ptr, to, conv);
+ conv->bad_p = true;
+ }
+ else
+ return NULL;
+
+ from = to;
+ }
+ else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from))
+ {
+ tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from));
+ tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
+ tree fbase = class_of_this_parm (fromfn);
+ tree tbase = class_of_this_parm (tofn);
+
+ if (!DERIVED_FROM_P (fbase, tbase)
+ || !same_type_p (static_fn_type (fromfn),
+ static_fn_type (tofn)))
+ return NULL;
+
+ from = build_memfn_type (fromfn,
+ tbase,
+ cp_type_quals (tbase),
+ type_memfn_rqual (tofn));
+ from = build_ptrmemfunc_type (build_pointer_type (from));
+ conv = build_conv (ck_pmem, from, conv);
+ conv->base_p = true;
+ }
+ else if (tcode == BOOLEAN_TYPE)
+ {
+ /* [conv.bool]
+
+ An rvalue of arithmetic, unscoped enumeration, pointer, or
+ pointer to member type can be converted to an rvalue of type
+ bool. ... An rvalue of type std::nullptr_t can be converted
+ to an rvalue of type bool; */
+ if (ARITHMETIC_TYPE_P (from)
+ || UNSCOPED_ENUM_P (from)
+ || fcode == POINTER_TYPE
+ || TYPE_PTRMEM_P (from)
+ || NULLPTR_TYPE_P (from))
+ {
+ conv = build_conv (ck_std, to, conv);
+ if (fcode == POINTER_TYPE
+ || TYPE_PTRDATAMEM_P (from)
+ || (TYPE_PTRMEMFUNC_P (from)
+ && conv->rank < cr_pbool)
+ || NULLPTR_TYPE_P (from))
+ conv->rank = cr_pbool;
+ return conv;
+ }
+
+ return NULL;
+ }
+ /* We don't check for ENUMERAL_TYPE here because there are no standard
+ conversions to enum type. */
+ /* As an extension, allow conversion to complex type. */
+ else if (ARITHMETIC_TYPE_P (to))
+ {
+ if (! (INTEGRAL_CODE_P (fcode)
+ || (fcode == REAL_TYPE && !(flags & LOOKUP_NO_NON_INTEGRAL)))
+ || SCOPED_ENUM_P (from))
+ return NULL;
+ conv = build_conv (ck_std, to, conv);
+
+ /* Give this a better rank if it's a promotion. */
+ if (same_type_p (to, type_promotes_to (from))
+ && next_conversion (conv)->rank <= cr_promotion)
+ conv->rank = cr_promotion;
+ }
+ else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
+ && vector_types_convertible_p (from, to, false))
+ return build_conv (ck_std, to, conv);
+ else if (MAYBE_CLASS_TYPE_P (to) && MAYBE_CLASS_TYPE_P (from)
+ && is_properly_derived_from (from, to))
+ {
+ if (conv->kind == ck_rvalue)
+ conv = next_conversion (conv);
+ conv = build_conv (ck_base, to, conv);
+ /* The derived-to-base conversion indicates the initialization
+ of a parameter with base type from an object of a derived
+ type. A temporary object is created to hold the result of
+ the conversion unless we're binding directly to a reference. */
+ conv->need_temporary_p = !(flags & LOOKUP_NO_TEMP_BIND);
+ }
+ else
+ return NULL;
+
+ if (flags & LOOKUP_NO_NARROWING)
+ conv->check_narrowing = true;
+
+ return conv;
+}
+
+/* Returns nonzero if T1 is reference-related to T2. */
+
+bool
+reference_related_p (tree t1, tree t2)
+{
+ if (t1 == error_mark_node || t2 == error_mark_node)
+ return false;
+
+ t1 = TYPE_MAIN_VARIANT (t1);
+ t2 = TYPE_MAIN_VARIANT (t2);
+
+ /* [dcl.init.ref]
+
+ Given types "cv1 T1" and "cv2 T2," "cv1 T1" is reference-related
+ to "cv2 T2" if T1 is the same type as T2, or T1 is a base class
+ of T2. */
+ return (same_type_p (t1, t2)
+ || (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2)
+ && DERIVED_FROM_P (t1, t2)));
+}
+
+/* Returns nonzero if T1 is reference-compatible with T2. */
+
+static bool
+reference_compatible_p (tree t1, tree t2)
+{
+ /* [dcl.init.ref]
+
+ "cv1 T1" is reference compatible with "cv2 T2" if T1 is
+ reference-related to T2 and cv1 is the same cv-qualification as,
+ or greater cv-qualification than, cv2. */
+ return (reference_related_p (t1, t2)
+ && at_least_as_qualified_p (t1, t2));
+}
+
+/* A reference of the indicated TYPE is being bound directly to the
+ expression represented by the implicit conversion sequence CONV.
+ Return a conversion sequence for this binding. */
+
+static conversion *
+direct_reference_binding (tree type, conversion *conv)
+{
+ tree t;
+
+ gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
+ gcc_assert (TREE_CODE (conv->type) != REFERENCE_TYPE);
+
+ t = TREE_TYPE (type);
+
+ /* [over.ics.rank]
+
+ When a parameter of reference type binds directly
+ (_dcl.init.ref_) to an argument expression, the implicit
+ conversion sequence is the identity conversion, unless the
+ argument expression has a type that is a derived class of the
+ parameter type, in which case the implicit conversion sequence is
+ a derived-to-base Conversion.
+
+ If the parameter binds directly to the result of applying a
+ conversion function to the argument expression, the implicit
+ conversion sequence is a user-defined conversion sequence
+ (_over.ics.user_), with the second standard conversion sequence
+ either an identity conversion or, if the conversion function
+ returns an entity of a type that is a derived class of the
+ parameter type, a derived-to-base conversion. */
+ if (!same_type_ignoring_top_level_qualifiers_p (t, conv->type))
+ {
+ /* Represent the derived-to-base conversion. */
+ conv = build_conv (ck_base, t, conv);
+ /* We will actually be binding to the base-class subobject in
+ the derived class, so we mark this conversion appropriately.
+ That way, convert_like knows not to generate a temporary. */
+ conv->need_temporary_p = false;
+ }
+ return build_conv (ck_ref_bind, type, conv);
+}
+
+/* Returns the conversion path from type FROM to reference type TO for
+ purposes of reference binding. For lvalue binding, either pass a
+ reference type to FROM or an lvalue expression to EXPR. If the
+ reference will be bound to a temporary, NEED_TEMPORARY_P is set for
+ the conversion returned. If C_CAST_P is true, this
+ conversion is coming from a C-style cast. */
+
+static conversion *
+reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
+ tsubst_flags_t complain)
+{
+ conversion *conv = NULL;
+ tree to = TREE_TYPE (rto);
+ tree from = rfrom;
+ tree tfrom;
+ bool related_p;
+ bool compatible_p;
+ cp_lvalue_kind gl_kind;
+ bool is_lvalue;
+
+ if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
+ {
+ expr = instantiate_type (to, expr, tf_none);
+ if (expr == error_mark_node)
+ return NULL;
+ from = TREE_TYPE (expr);
+ }
+
+ if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ /* DR 1288: Otherwise, if the initializer list has a single element
+ of type E and ... [T's] referenced type is reference-related to E,
+ the object or reference is initialized from that element... */
+ if (CONSTRUCTOR_NELTS (expr) == 1)
+ {
+ tree elt = CONSTRUCTOR_ELT (expr, 0)->value;
+ if (error_operand_p (elt))
+ return NULL;
+ tree etype = TREE_TYPE (elt);
+ if (reference_related_p (to, etype))
+ {
+ expr = elt;
+ from = etype;
+ goto skip;
+ }
+ }
+ /* Otherwise, if T is a reference type, a prvalue temporary of the
+ type referenced by T is copy-list-initialized or
+ direct-list-initialized, depending on the kind of initialization
+ for the reference, and the reference is bound to that temporary. */
+ conv = implicit_conversion (to, from, expr, c_cast_p,
+ flags|LOOKUP_NO_TEMP_BIND, complain);
+ skip:;
+ }
+
+ if (TREE_CODE (from) == REFERENCE_TYPE)
+ {
+ from = TREE_TYPE (from);
+ if (!TYPE_REF_IS_RVALUE (rfrom)
+ || TREE_CODE (from) == FUNCTION_TYPE)
+ gl_kind = clk_ordinary;
+ else
+ gl_kind = clk_rvalueref;
+ }
+ else if (expr)
+ {
+ gl_kind = lvalue_kind (expr);
+ if (gl_kind & clk_class)
+ /* A class prvalue is not a glvalue. */
+ gl_kind = clk_none;
+ }
+ else
+ gl_kind = clk_none;
+ is_lvalue = gl_kind && !(gl_kind & clk_rvalueref);
+
+ tfrom = from;
+ if ((gl_kind & clk_bitfield) != 0)
+ tfrom = unlowered_expr_type (expr);
+
+ /* Figure out whether or not the types are reference-related and
+ reference compatible. We have do do this after stripping
+ references from FROM. */
+ related_p = reference_related_p (to, tfrom);
+ /* If this is a C cast, first convert to an appropriately qualified
+ type, so that we can later do a const_cast to the desired type. */
+ if (related_p && c_cast_p
+ && !at_least_as_qualified_p (to, tfrom))
+ to = cp_build_qualified_type (to, cp_type_quals (tfrom));
+ compatible_p = reference_compatible_p (to, tfrom);
+
+ /* Directly bind reference when target expression's type is compatible with
+ the reference and expression is an lvalue. In DR391, the wording in
+ [8.5.3/5 dcl.init.ref] is changed to also require direct bindings for
+ const and rvalue references to rvalues of compatible class type.
+ We should also do direct bindings for non-class xvalues. */
+ if (compatible_p
+ && (is_lvalue
+ || (((CP_TYPE_CONST_NON_VOLATILE_P (to)
+ && !(flags & LOOKUP_NO_RVAL_BIND))
+ || TYPE_REF_IS_RVALUE (rto))
+ && (gl_kind
+ || (!(flags & LOOKUP_NO_TEMP_BIND)
+ && (CLASS_TYPE_P (from)
+ || TREE_CODE (from) == ARRAY_TYPE))))))
+ {
+ /* [dcl.init.ref]
+
+ If the initializer expression
+
+ -- is an lvalue (but not an lvalue for a bit-field), and "cv1 T1"
+ is reference-compatible with "cv2 T2,"
+
+ the reference is bound directly to the initializer expression
+ lvalue.
+
+ [...]
+ If the initializer expression is an rvalue, with T2 a class type,
+ and "cv1 T1" is reference-compatible with "cv2 T2", the reference
+ is bound to the object represented by the rvalue or to a sub-object
+ within that object. */
+
+ conv = build_identity_conv (tfrom, expr);
+ conv = direct_reference_binding (rto, conv);
+
+ if (flags & LOOKUP_PREFER_RVALUE)
+ /* The top-level caller requested that we pretend that the lvalue
+ be treated as an rvalue. */
+ conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
+ else if (TREE_CODE (rfrom) == REFERENCE_TYPE)
+ /* Handle rvalue reference to function properly. */
+ conv->rvaluedness_matches_p
+ = (TYPE_REF_IS_RVALUE (rto) == TYPE_REF_IS_RVALUE (rfrom));
+ else
+ conv->rvaluedness_matches_p
+ = (TYPE_REF_IS_RVALUE (rto) == !is_lvalue);
+
+ if ((gl_kind & clk_bitfield) != 0
+ || ((gl_kind & clk_packed) != 0 && !TYPE_PACKED (to)))
+ /* For the purposes of overload resolution, we ignore the fact
+ this expression is a bitfield or packed field. (In particular,
+ [over.ics.ref] says specifically that a function with a
+ non-const reference parameter is viable even if the
+ argument is a bitfield.)
+
+ However, when we actually call the function we must create
+ a temporary to which to bind the reference. If the
+ reference is volatile, or isn't const, then we cannot make
+ a temporary, so we just issue an error when the conversion
+ actually occurs. */
+ conv->need_temporary_p = true;
+
+ /* Don't allow binding of lvalues (other than function lvalues) to
+ rvalue references. */
+ if (is_lvalue && TYPE_REF_IS_RVALUE (rto)
+ && TREE_CODE (to) != FUNCTION_TYPE
+ && !(flags & LOOKUP_PREFER_RVALUE))
+ conv->bad_p = true;
+
+ return conv;
+ }
+ /* [class.conv.fct] A conversion function is never used to convert a
+ (possibly cv-qualified) object to the (possibly cv-qualified) same
+ object type (or a reference to it), to a (possibly cv-qualified) base
+ class of that type (or a reference to it).... */
+ else if (CLASS_TYPE_P (from) && !related_p
+ && !(flags & LOOKUP_NO_CONVERSION))
+ {
+ /* [dcl.init.ref]
+
+ If the initializer expression
+
+ -- has a class type (i.e., T2 is a class type) can be
+ implicitly converted to an lvalue of type "cv3 T3," where
+ "cv1 T1" is reference-compatible with "cv3 T3". (this
+ conversion is selected by enumerating the applicable
+ conversion functions (_over.match.ref_) and choosing the
+ best one through overload resolution. (_over.match_).
+
+ the reference is bound to the lvalue result of the conversion
+ in the second case. */
+ z_candidate *cand = build_user_type_conversion_1 (rto, expr, flags,
+ complain);
+ if (cand)
+ return cand->second_conv;
+ }
+
+ /* From this point on, we conceptually need temporaries, even if we
+ elide them. Only the cases above are "direct bindings". */
+ if (flags & LOOKUP_NO_TEMP_BIND)
+ return NULL;
+
+ /* [over.ics.rank]
+
+ When a parameter of reference type is not bound directly to an
+ argument expression, the conversion sequence is the one required
+ to convert the argument expression to the underlying type of the
+ reference according to _over.best.ics_. Conceptually, this
+ conversion sequence corresponds to copy-initializing a temporary
+ of the underlying type with the argument expression. Any
+ difference in top-level cv-qualification is subsumed by the
+ initialization itself and does not constitute a conversion. */
+
+ /* [dcl.init.ref]
+
+ Otherwise, the reference shall be an lvalue reference to a
+ non-volatile const type, or the reference shall be an rvalue
+ reference. */
+ if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !TYPE_REF_IS_RVALUE (rto))
+ return NULL;
+
+ /* [dcl.init.ref]
+
+ Otherwise, a temporary of type "cv1 T1" is created and
+ initialized from the initializer expression using the rules for a
+ non-reference copy initialization. If T1 is reference-related to
+ T2, cv1 must be the same cv-qualification as, or greater
+ cv-qualification than, cv2; otherwise, the program is ill-formed. */
+ if (related_p && !at_least_as_qualified_p (to, from))
+ return NULL;
+
+ /* We're generating a temporary now, but don't bind any more in the
+ conversion (specifically, don't slice the temporary returned by a
+ conversion operator). */
+ flags |= LOOKUP_NO_TEMP_BIND;
+
+ /* Core issue 899: When [copy-]initializing a temporary to be bound
+ to the first parameter of a copy constructor (12.8) called with
+ a single argument in the context of direct-initialization,
+ explicit conversion functions are also considered.
+
+ So don't set LOOKUP_ONLYCONVERTING in that case. */
+ if (!(flags & LOOKUP_COPY_PARM))
+ flags |= LOOKUP_ONLYCONVERTING;
+
+ if (!conv)
+ conv = implicit_conversion (to, from, expr, c_cast_p,
+ flags, complain);
+ if (!conv)
+ return NULL;
+
+ conv = build_conv (ck_ref_bind, rto, conv);
+ /* This reference binding, unlike those above, requires the
+ creation of a temporary. */
+ conv->need_temporary_p = true;
+ if (TYPE_REF_IS_RVALUE (rto))
+ {
+ conv->rvaluedness_matches_p = 1;
+ /* In the second case, if the reference is an rvalue reference and
+ the second standard conversion sequence of the user-defined
+ conversion sequence includes an lvalue-to-rvalue conversion, the
+ program is ill-formed. */
+ if (conv->user_conv_p && next_conversion (conv)->kind == ck_rvalue)
+ conv->bad_p = 1;
+ }
+
+ return conv;
+}
+
+/* Returns the implicit conversion sequence (see [over.ics]) from type
+ FROM to type TO. The optional expression EXPR may affect the
+ conversion. FLAGS are the usual overloading flags. If C_CAST_P is
+ true, this conversion is coming from a C-style cast. */
+
+static conversion *
+implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
+ int flags, tsubst_flags_t complain)
+{
+ conversion *conv;
+
+ if (from == error_mark_node || to == error_mark_node
+ || expr == error_mark_node)
+ return NULL;
+
+ /* Other flags only apply to the primary function in overload
+ resolution, or after we've chosen one. */
+ flags &= (LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION|LOOKUP_COPY_PARM
+ |LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_PREFER_RVALUE
+ |LOOKUP_NO_NARROWING|LOOKUP_PROTECT|LOOKUP_NO_NON_INTEGRAL);
+
+ /* FIXME: actually we don't want warnings either, but we can't just
+ have 'complain &= ~(tf_warning|tf_error)' because it would cause
+ the regression of, eg, g++.old-deja/g++.benjamin/16077.C.
+ We really ought not to issue that warning until we've committed
+ to that conversion. */
+ complain &= ~tf_error;
+
+ if (TREE_CODE (to) == REFERENCE_TYPE)
+ conv = reference_binding (to, from, expr, c_cast_p, flags, complain);
+ else
+ conv = standard_conversion (to, from, expr, c_cast_p, flags);
+
+ if (conv)
+ return conv;
+
+ if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ if (is_std_init_list (to))
+ return build_list_conv (to, expr, flags, complain);
+
+ /* As an extension, allow list-initialization of _Complex. */
+ if (TREE_CODE (to) == COMPLEX_TYPE)
+ {
+ conv = build_complex_conv (to, expr, flags, complain);
+ if (conv)
+ return conv;
+ }
+
+ /* Allow conversion from an initializer-list with one element to a
+ scalar type. */
+ if (SCALAR_TYPE_P (to))
+ {
+ int nelts = CONSTRUCTOR_NELTS (expr);
+ tree elt;
+
+ if (nelts == 0)
+ elt = build_value_init (to, tf_none);
+ else if (nelts == 1)
+ elt = CONSTRUCTOR_ELT (expr, 0)->value;
+ else
+ elt = error_mark_node;
+
+ conv = implicit_conversion (to, TREE_TYPE (elt), elt,
+ c_cast_p, flags, complain);
+ if (conv)
+ {
+ conv->check_narrowing = true;
+ if (BRACE_ENCLOSED_INITIALIZER_P (elt))
+ /* Too many levels of braces, i.e. '{{1}}'. */
+ conv->bad_p = true;
+ return conv;
+ }
+ }
+ else if (TREE_CODE (to) == ARRAY_TYPE)
+ return build_array_conv (to, expr, flags, complain);
+ }
+
+ if (expr != NULL_TREE
+ && (MAYBE_CLASS_TYPE_P (from)
+ || MAYBE_CLASS_TYPE_P (to))
+ && (flags & LOOKUP_NO_CONVERSION) == 0)
+ {
+ struct z_candidate *cand;
+
+ if (CLASS_TYPE_P (to)
+ && BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && !CLASSTYPE_NON_AGGREGATE (complete_type (to)))
+ return build_aggr_conv (to, expr, flags, complain);
+
+ cand = build_user_type_conversion_1 (to, expr, flags, complain);
+ if (cand)
+ conv = cand->second_conv;
+
+ /* We used to try to bind a reference to a temporary here, but that
+ is now handled after the recursive call to this function at the end
+ of reference_binding. */
+ return conv;
+ }
+
+ return NULL;
+}
+
+/* Add a new entry to the list of candidates. Used by the add_*_candidate
+ functions. ARGS will not be changed until a single candidate is
+ selected. */
+
+static struct z_candidate *
+add_candidate (struct z_candidate **candidates,
+ tree fn, tree first_arg, const vec<tree, va_gc> *args,
+ size_t num_convs, conversion **convs,
+ tree access_path, tree conversion_path,
+ int viable, struct rejection_reason *reason)
+{
+ struct z_candidate *cand = (struct z_candidate *)
+ conversion_obstack_alloc (sizeof (struct z_candidate));
+
+ cand->fn = fn;
+ cand->first_arg = first_arg;
+ cand->args = args;
+ cand->convs = convs;
+ cand->num_convs = num_convs;
+ cand->access_path = access_path;
+ cand->conversion_path = conversion_path;
+ cand->viable = viable;
+ cand->reason = reason;
+ cand->next = *candidates;
+ *candidates = cand;
+
+ return cand;
+}
+
+/* Return the number of remaining arguments in the parameter list
+ beginning with ARG. */
+
+static int
+remaining_arguments (tree arg)
+{
+ int n;
+
+ for (n = 0; arg != NULL_TREE && arg != void_list_node;
+ arg = TREE_CHAIN (arg))
+ n++;
+
+ return n;
+}
+
+/* Create an overload candidate for the function or method FN called
+ with the argument list FIRST_ARG/ARGS and add it to CANDIDATES.
+ FLAGS is passed on to implicit_conversion.
+
+ This does not change ARGS.
+
+ CTYPE, if non-NULL, is the type we want to pretend this function
+ comes from for purposes of overload resolution. */
+
+static struct z_candidate *
+add_function_candidate (struct z_candidate **candidates,
+ tree fn, tree ctype, tree first_arg,
+ const vec<tree, va_gc> *args, tree access_path,
+ tree conversion_path, int flags,
+ tsubst_flags_t complain)
+{
+ tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ int i, len;
+ conversion **convs;
+ tree parmnode;
+ tree orig_first_arg = first_arg;
+ int skip;
+ int viable = 1;
+ struct rejection_reason *reason = NULL;
+
+ /* At this point we should not see any functions which haven't been
+ explicitly declared, except for friend functions which will have
+ been found using argument dependent lookup. */
+ gcc_assert (!DECL_ANTICIPATED (fn) || DECL_HIDDEN_FRIEND_P (fn));
+
+ /* The `this', `in_chrg' and VTT arguments to constructors are not
+ considered in overload resolution. */
+ if (DECL_CONSTRUCTOR_P (fn))
+ {
+ parmlist = skip_artificial_parms_for (fn, parmlist);
+ skip = num_artificial_parms_for (fn);
+ if (skip > 0 && first_arg != NULL_TREE)
+ {
+ --skip;
+ first_arg = NULL_TREE;
+ }
+ }
+ else
+ skip = 0;
+
+ len = vec_safe_length (args) - skip + (first_arg != NULL_TREE ? 1 : 0);
+ convs = alloc_conversions (len);
+
+ /* 13.3.2 - Viable functions [over.match.viable]
+ First, to be a viable function, a candidate function shall have enough
+ parameters to agree in number with the arguments in the list.
+
+ We need to check this first; otherwise, checking the ICSes might cause
+ us to produce an ill-formed template instantiation. */
+
+ parmnode = parmlist;
+ for (i = 0; i < len; ++i)
+ {
+ if (parmnode == NULL_TREE || parmnode == void_list_node)
+ break;
+ parmnode = TREE_CHAIN (parmnode);
+ }
+
+ if ((i < len && parmnode)
+ || !sufficient_parms_p (parmnode))
+ {
+ int remaining = remaining_arguments (parmnode);
+ viable = 0;
+ reason = arity_rejection (first_arg, i + remaining, len);
+ }
+ /* When looking for a function from a subobject from an implicit
+ copy/move constructor/operator=, don't consider anything that takes (a
+ reference to) an unrelated type. See c++/44909 and core 1092. */
+ else if (parmlist && (flags & LOOKUP_DEFAULTED))
+ {
+ if (DECL_CONSTRUCTOR_P (fn))
+ i = 1;
+ else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
+ && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR)
+ i = 2;
+ else
+ i = 0;
+ if (i && len == i)
+ {
+ parmnode = chain_index (i-1, parmlist);
+ if (!reference_related_p (non_reference (TREE_VALUE (parmnode)),
+ ctype))
+ viable = 0;
+ }
+
+ /* This only applies at the top level. */
+ flags &= ~LOOKUP_DEFAULTED;
+ }
+
+ if (! viable)
+ goto out;
+
+ /* Second, for F to be a viable function, there shall exist for each
+ argument an implicit conversion sequence that converts that argument
+ to the corresponding parameter of F. */
+
+ parmnode = parmlist;
+
+ for (i = 0; i < len; ++i)
+ {
+ tree argtype, to_type;
+ tree arg;
+ conversion *t;
+ int is_this;
+
+ if (parmnode == void_list_node)
+ break;
+
+ if (i == 0 && first_arg != NULL_TREE)
+ arg = first_arg;
+ else
+ arg = CONST_CAST_TREE (
+ (*args)[i + skip - (first_arg != NULL_TREE ? 1 : 0)]);
+ argtype = lvalue_type (arg);
+
+ is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && ! DECL_CONSTRUCTOR_P (fn));
+
+ if (parmnode)
+ {
+ tree parmtype = TREE_VALUE (parmnode);
+ int lflags = flags;
+
+ parmnode = TREE_CHAIN (parmnode);
+
+ /* The type of the implicit object parameter ('this') for
+ overload resolution is not always the same as for the
+ function itself; conversion functions are considered to
+ be members of the class being converted, and functions
+ introduced by a using-declaration are considered to be
+ members of the class that uses them.
+
+ Since build_over_call ignores the ICS for the `this'
+ parameter, we can just change the parm type. */
+ if (ctype && is_this)
+ {
+ parmtype = cp_build_qualified_type
+ (ctype, cp_type_quals (TREE_TYPE (parmtype)));
+ if (FUNCTION_REF_QUALIFIED (TREE_TYPE (fn)))
+ {
+ /* If the function has a ref-qualifier, the implicit
+ object parameter has reference type. */
+ bool rv = FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (fn));
+ parmtype = cp_build_reference_type (parmtype, rv);
+ }
+ else
+ {
+ parmtype = build_pointer_type (parmtype);
+ arg = build_this (arg);
+ argtype = lvalue_type (arg);
+ }
+ }
+
+ /* Core issue 899: When [copy-]initializing a temporary to be bound
+ to the first parameter of a copy constructor (12.8) called with
+ a single argument in the context of direct-initialization,
+ explicit conversion functions are also considered.
+
+ So set LOOKUP_COPY_PARM to let reference_binding know that
+ it's being called in that context. We generalize the above
+ to handle move constructors and template constructors as well;
+ the standardese should soon be updated similarly. */
+ if (ctype && i == 0 && (len-skip == 1)
+ && DECL_CONSTRUCTOR_P (fn)
+ && parmtype != error_mark_node
+ && (same_type_ignoring_top_level_qualifiers_p
+ (non_reference (parmtype), ctype)))
+ {
+ if (!(flags & LOOKUP_ONLYCONVERTING))
+ lflags |= LOOKUP_COPY_PARM;
+ /* We allow user-defined conversions within init-lists, but
+ don't list-initialize the copy parm, as that would mean
+ using two levels of braces for the same type. */
+ if ((flags & LOOKUP_LIST_INIT_CTOR)
+ && BRACE_ENCLOSED_INITIALIZER_P (arg))
+ lflags |= LOOKUP_NO_CONVERSION;
+ }
+ else
+ lflags |= LOOKUP_ONLYCONVERTING;
+
+ t = implicit_conversion (parmtype, argtype, arg,
+ /*c_cast_p=*/false, lflags, complain);
+ to_type = parmtype;
+ }
+ else
+ {
+ t = build_identity_conv (argtype, arg);
+ t->ellipsis_p = true;
+ to_type = argtype;
+ }
+
+ if (t && is_this)
+ t->this_p = true;
+
+ convs[i] = t;
+ if (! t)
+ {
+ viable = 0;
+ reason = arg_conversion_rejection (first_arg, i, argtype, to_type);
+ break;
+ }
+
+ if (t->bad_p)
+ {
+ viable = -1;
+ reason = bad_arg_conversion_rejection (first_arg, i, argtype, to_type);
+ }
+ }
+
+ out:
+ return add_candidate (candidates, fn, orig_first_arg, args, len, convs,
+ access_path, conversion_path, viable, reason);
+}
+
+/* Create an overload candidate for the conversion function FN which will
+ be invoked for expression OBJ, producing a pointer-to-function which
+ will in turn be called with the argument list FIRST_ARG/ARGLIST,
+ and add it to CANDIDATES. This does not change ARGLIST. FLAGS is
+ passed on to implicit_conversion.
+
+ Actually, we don't really care about FN; we care about the type it
+ converts to. There may be multiple conversion functions that will
+ convert to that type, and we rely on build_user_type_conversion_1 to
+ choose the best one; so when we create our candidate, we record the type
+ instead of the function. */
+
+static struct z_candidate *
+add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
+ tree first_arg, const vec<tree, va_gc> *arglist,
+ tree access_path, tree conversion_path,
+ tsubst_flags_t complain)
+{
+ tree totype = TREE_TYPE (TREE_TYPE (fn));
+ int i, len, viable, flags;
+ tree parmlist, parmnode;
+ conversion **convs;
+ struct rejection_reason *reason;
+
+ for (parmlist = totype; TREE_CODE (parmlist) != FUNCTION_TYPE; )
+ parmlist = TREE_TYPE (parmlist);
+ parmlist = TYPE_ARG_TYPES (parmlist);
+
+ len = vec_safe_length (arglist) + (first_arg != NULL_TREE ? 1 : 0) + 1;
+ convs = alloc_conversions (len);
+ parmnode = parmlist;
+ viable = 1;
+ flags = LOOKUP_IMPLICIT;
+ reason = NULL;
+
+ /* Don't bother looking up the same type twice. */
+ if (*candidates && (*candidates)->fn == totype)
+ return NULL;
+
+ for (i = 0; i < len; ++i)
+ {
+ tree arg, argtype, convert_type = NULL_TREE;
+ conversion *t;
+
+ if (i == 0)
+ arg = obj;
+ else if (i == 1 && first_arg != NULL_TREE)
+ arg = first_arg;
+ else
+ arg = (*arglist)[i - (first_arg != NULL_TREE ? 1 : 0) - 1];
+ argtype = lvalue_type (arg);
+
+ if (i == 0)
+ {
+ t = implicit_conversion (totype, argtype, arg, /*c_cast_p=*/false,
+ flags, complain);
+ convert_type = totype;
+ }
+ else if (parmnode == void_list_node)
+ break;
+ else if (parmnode)
+ {
+ t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg,
+ /*c_cast_p=*/false, flags, complain);
+ convert_type = TREE_VALUE (parmnode);
+ }
+ else
+ {
+ t = build_identity_conv (argtype, arg);
+ t->ellipsis_p = true;
+ convert_type = argtype;
+ }
+
+ convs[i] = t;
+ if (! t)
+ break;
+
+ if (t->bad_p)
+ {
+ viable = -1;
+ reason = bad_arg_conversion_rejection (NULL_TREE, i, argtype, convert_type);
+ }
+
+ if (i == 0)
+ continue;
+
+ if (parmnode)
+ parmnode = TREE_CHAIN (parmnode);
+ }
+
+ if (i < len
+ || ! sufficient_parms_p (parmnode))
+ {
+ int remaining = remaining_arguments (parmnode);
+ viable = 0;
+ reason = arity_rejection (NULL_TREE, i + remaining, len);
+ }
+
+ return add_candidate (candidates, totype, first_arg, arglist, len, convs,
+ access_path, conversion_path, viable, reason);
+}
+
+static void
+build_builtin_candidate (struct z_candidate **candidates, tree fnname,
+ tree type1, tree type2, tree *args, tree *argtypes,
+ int flags, tsubst_flags_t complain)
+{
+ conversion *t;
+ conversion **convs;
+ size_t num_convs;
+ int viable = 1, i;
+ tree types[2];
+ struct rejection_reason *reason = NULL;
+
+ types[0] = type1;
+ types[1] = type2;
+
+ num_convs = args[2] ? 3 : (args[1] ? 2 : 1);
+ convs = alloc_conversions (num_convs);
+
+ /* TRUTH_*_EXPR do "contextual conversion to bool", which means explicit
+ conversion ops are allowed. We handle that here by just checking for
+ boolean_type_node because other operators don't ask for it. COND_EXPR
+ also does contextual conversion to bool for the first operand, but we
+ handle that in build_conditional_expr, and type1 here is operand 2. */
+ if (type1 != boolean_type_node)
+ flags |= LOOKUP_ONLYCONVERTING;
+
+ for (i = 0; i < 2; ++i)
+ {
+ if (! args[i])
+ break;
+
+ t = implicit_conversion (types[i], argtypes[i], args[i],
+ /*c_cast_p=*/false, flags, complain);
+ if (! t)
+ {
+ viable = 0;
+ /* We need something for printing the candidate. */
+ t = build_identity_conv (types[i], NULL_TREE);
+ reason = arg_conversion_rejection (NULL_TREE, i, argtypes[i],
+ types[i]);
+ }
+ else if (t->bad_p)
+ {
+ viable = 0;
+ reason = bad_arg_conversion_rejection (NULL_TREE, i, argtypes[i],
+ types[i]);
+ }
+ convs[i] = t;
+ }
+
+ /* For COND_EXPR we rearranged the arguments; undo that now. */
+ if (args[2])
+ {
+ convs[2] = convs[1];
+ convs[1] = convs[0];
+ t = implicit_conversion (boolean_type_node, argtypes[2], args[2],
+ /*c_cast_p=*/false, flags,
+ complain);
+ if (t)
+ convs[0] = t;
+ else
+ {
+ viable = 0;
+ reason = arg_conversion_rejection (NULL_TREE, 0, argtypes[2],
+ boolean_type_node);
+ }
+ }
+
+ add_candidate (candidates, fnname, /*first_arg=*/NULL_TREE, /*args=*/NULL,
+ num_convs, convs,
+ /*access_path=*/NULL_TREE,
+ /*conversion_path=*/NULL_TREE,
+ viable, reason);
+}
+
+static bool
+is_complete (tree t)
+{
+ return COMPLETE_TYPE_P (complete_type (t));
+}
+
+/* Returns nonzero if TYPE is a promoted arithmetic type. */
+
+static bool
+promoted_arithmetic_type_p (tree type)
+{
+ /* [over.built]
+
+ In this section, the term promoted integral type is used to refer
+ to those integral types which are preserved by integral promotion
+ (including e.g. int and long but excluding e.g. char).
+ Similarly, the term promoted arithmetic type refers to promoted
+ integral types plus floating types. */
+ return ((CP_INTEGRAL_TYPE_P (type)
+ && same_type_p (type_promotes_to (type), type))
+ || TREE_CODE (type) == REAL_TYPE);
+}
+
+/* Create any builtin operator overload candidates for the operator in
+ question given the converted operand types TYPE1 and TYPE2. The other
+ args are passed through from add_builtin_candidates to
+ build_builtin_candidate.
+
+ TYPE1 and TYPE2 may not be permissible, and we must filter them.
+ If CODE is requires candidates operands of the same type of the kind
+ of which TYPE1 and TYPE2 are, we add both candidates
+ CODE (TYPE1, TYPE1) and CODE (TYPE2, TYPE2). */
+
+static void
+add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
+ enum tree_code code2, tree fnname, tree type1,
+ tree type2, tree *args, tree *argtypes, int flags,
+ tsubst_flags_t complain)
+{
+ switch (code)
+ {
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ args[1] = integer_zero_node;
+ type2 = integer_type_node;
+ break;
+ default:
+ break;
+ }
+
+ switch (code)
+ {
+
+/* 4 For every pair T, VQ), where T is an arithmetic or enumeration type,
+ and VQ is either volatile or empty, there exist candidate operator
+ functions of the form
+ VQ T& operator++(VQ T&);
+ T operator++(VQ T&, int);
+ 5 For every pair T, VQ), where T is an enumeration type or an arithmetic
+ type other than bool, and VQ is either volatile or empty, there exist
+ candidate operator functions of the form
+ VQ T& operator--(VQ T&);
+ T operator--(VQ T&, int);
+ 6 For every pair T, VQ), where T is a cv-qualified or cv-unqualified
+ complete object type, and VQ is either volatile or empty, there exist
+ candidate operator functions of the form
+ T*VQ& operator++(T*VQ&);
+ T*VQ& operator--(T*VQ&);
+ T* operator++(T*VQ&, int);
+ T* operator--(T*VQ&, int); */
+
+ case POSTDECREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ if (TREE_CODE (type1) == BOOLEAN_TYPE)
+ return;
+ case POSTINCREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1))
+ {
+ type1 = build_reference_type (type1);
+ break;
+ }
+ return;
+
+/* 7 For every cv-qualified or cv-unqualified object type T, there
+ exist candidate operator functions of the form
+
+ T& operator*(T*);
+
+ 8 For every function type T, there exist candidate operator functions of
+ the form
+ T& operator*(T*); */
+
+ case INDIRECT_REF:
+ if (TYPE_PTR_P (type1)
+ && (TYPE_PTROB_P (type1)
+ || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE))
+ break;
+ return;
+
+/* 9 For every type T, there exist candidate operator functions of the form
+ T* operator+(T*);
+
+ 10For every promoted arithmetic type T, there exist candidate operator
+ functions of the form
+ T operator+(T);
+ T operator-(T); */
+
+ case UNARY_PLUS_EXPR: /* unary + */
+ if (TYPE_PTR_P (type1))
+ break;
+ case NEGATE_EXPR:
+ if (ARITHMETIC_TYPE_P (type1))
+ break;
+ return;
+
+/* 11For every promoted integral type T, there exist candidate operator
+ functions of the form
+ T operator~(T); */
+
+ case BIT_NOT_EXPR:
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1))
+ break;
+ return;
+
+/* 12For every quintuple C1, C2, T, CV1, CV2), where C2 is a class type, C1
+ is the same type as C2 or is a derived class of C2, T is a complete
+ object type or a function type, and CV1 and CV2 are cv-qualifier-seqs,
+ there exist candidate operator functions of the form
+ CV12 T& operator->*(CV1 C1*, CV2 T C2::*);
+ where CV12 is the union of CV1 and CV2. */
+
+ case MEMBER_REF:
+ if (TYPE_PTR_P (type1) && TYPE_PTRMEM_P (type2))
+ {
+ tree c1 = TREE_TYPE (type1);
+ tree c2 = TYPE_PTRMEM_CLASS_TYPE (type2);
+
+ if (MAYBE_CLASS_TYPE_P (c1) && DERIVED_FROM_P (c2, c1)
+ && (TYPE_PTRMEMFUNC_P (type2)
+ || is_complete (TYPE_PTRMEM_POINTED_TO_TYPE (type2))))
+ break;
+ }
+ return;
+
+/* 13For every pair of promoted arithmetic types L and R, there exist can-
+ didate operator functions of the form
+ LR operator*(L, R);
+ LR operator/(L, R);
+ LR operator+(L, R);
+ LR operator-(L, R);
+ bool operator<(L, R);
+ bool operator>(L, R);
+ bool operator<=(L, R);
+ bool operator>=(L, R);
+ bool operator==(L, R);
+ bool operator!=(L, R);
+ where LR is the result of the usual arithmetic conversions between
+ types L and R.
+
+ 14For every pair of types T and I, where T is a cv-qualified or cv-
+ unqualified complete object type and I is a promoted integral type,
+ there exist candidate operator functions of the form
+ T* operator+(T*, I);
+ T& operator[](T*, I);
+ T* operator-(T*, I);
+ T* operator+(I, T*);
+ T& operator[](I, T*);
+
+ 15For every T, where T is a pointer to complete object type, there exist
+ candidate operator functions of the form112)
+ ptrdiff_t operator-(T, T);
+
+ 16For every pointer or enumeration type T, there exist candidate operator
+ functions of the form
+ bool operator<(T, T);
+ bool operator>(T, T);
+ bool operator<=(T, T);
+ bool operator>=(T, T);
+ bool operator==(T, T);
+ bool operator!=(T, T);
+
+ 17For every pointer to member type T, there exist candidate operator
+ functions of the form
+ bool operator==(T, T);
+ bool operator!=(T, T); */
+
+ case MINUS_EXPR:
+ if (TYPE_PTROB_P (type1) && TYPE_PTROB_P (type2))
+ break;
+ if (TYPE_PTROB_P (type1)
+ && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
+ {
+ type2 = ptrdiff_type_node;
+ break;
+ }
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
+ break;
+ return;
+
+ case EQ_EXPR:
+ case NE_EXPR:
+ if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2))
+ || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2)))
+ break;
+ if (TYPE_PTRMEM_P (type1) && null_ptr_cst_p (args[1]))
+ {
+ type2 = type1;
+ break;
+ }
+ if (TYPE_PTRMEM_P (type2) && null_ptr_cst_p (args[0]))
+ {
+ type1 = type2;
+ break;
+ }
+ /* Fall through. */
+ case LT_EXPR:
+ case GT_EXPR:
+ case LE_EXPR:
+ case GE_EXPR:
+ case MAX_EXPR:
+ case MIN_EXPR:
+ if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
+ break;
+ if (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
+ break;
+ if (TREE_CODE (type1) == ENUMERAL_TYPE
+ && TREE_CODE (type2) == ENUMERAL_TYPE)
+ break;
+ if (TYPE_PTR_P (type1)
+ && null_ptr_cst_p (args[1]))
+ {
+ type2 = type1;
+ break;
+ }
+ if (null_ptr_cst_p (args[0])
+ && TYPE_PTR_P (type2))
+ {
+ type1 = type2;
+ break;
+ }
+ return;
+
+ case PLUS_EXPR:
+ if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
+ break;
+ case ARRAY_REF:
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && TYPE_PTROB_P (type2))
+ {
+ type1 = ptrdiff_type_node;
+ break;
+ }
+ if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
+ {
+ type2 = ptrdiff_type_node;
+ break;
+ }
+ return;
+
+/* 18For every pair of promoted integral types L and R, there exist candi-
+ date operator functions of the form
+ LR operator%(L, R);
+ LR operator&(L, R);
+ LR operator^(L, R);
+ LR operator|(L, R);
+ L operator<<(L, R);
+ L operator>>(L, R);
+ where LR is the result of the usual arithmetic conversions between
+ types L and R. */
+
+ case TRUNC_MOD_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
+ break;
+ return;
+
+/* 19For every triple L, VQ, R), where L is an arithmetic or enumeration
+ type, VQ is either volatile or empty, and R is a promoted arithmetic
+ type, there exist candidate operator functions of the form
+ VQ L& operator=(VQ L&, R);
+ VQ L& operator*=(VQ L&, R);
+ VQ L& operator/=(VQ L&, R);
+ VQ L& operator+=(VQ L&, R);
+ VQ L& operator-=(VQ L&, R);
+
+ 20For every pair T, VQ), where T is any type and VQ is either volatile
+ or empty, there exist candidate operator functions of the form
+ T*VQ& operator=(T*VQ&, T*);
+
+ 21For every pair T, VQ), where T is a pointer to member type and VQ is
+ either volatile or empty, there exist candidate operator functions of
+ the form
+ VQ T& operator=(VQ T&, T);
+
+ 22For every triple T, VQ, I), where T is a cv-qualified or cv-
+ unqualified complete object type, VQ is either volatile or empty, and
+ I is a promoted integral type, there exist candidate operator func-
+ tions of the form
+ T*VQ& operator+=(T*VQ&, I);
+ T*VQ& operator-=(T*VQ&, I);
+
+ 23For every triple L, VQ, R), where L is an integral or enumeration
+ type, VQ is either volatile or empty, and R is a promoted integral
+ type, there exist candidate operator functions of the form
+
+ VQ L& operator%=(VQ L&, R);
+ VQ L& operator<<=(VQ L&, R);
+ VQ L& operator>>=(VQ L&, R);
+ VQ L& operator&=(VQ L&, R);
+ VQ L& operator^=(VQ L&, R);
+ VQ L& operator|=(VQ L&, R); */
+
+ case MODIFY_EXPR:
+ switch (code2)
+ {
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
+ {
+ type2 = ptrdiff_type_node;
+ break;
+ }
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
+ break;
+ return;
+
+ case TRUNC_MOD_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
+ break;
+ return;
+
+ case NOP_EXPR:
+ if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
+ break;
+ if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2))
+ || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
+ || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2))
+ || ((TYPE_PTRMEMFUNC_P (type1)
+ || TYPE_PTR_P (type1))
+ && null_ptr_cst_p (args[1])))
+ {
+ type2 = type1;
+ break;
+ }
+ return;
+
+ default:
+ gcc_unreachable ();
+ }
+ type1 = build_reference_type (type1);
+ break;
+
+ case COND_EXPR:
+ /* [over.built]
+
+ For every pair of promoted arithmetic types L and R, there
+ exist candidate operator functions of the form
+
+ LR operator?(bool, L, R);
+
+ where LR is the result of the usual arithmetic conversions
+ between types L and R.
+
+ For every type T, where T is a pointer or pointer-to-member
+ type, there exist candidate operator functions of the form T
+ operator?(bool, T, T); */
+
+ if (promoted_arithmetic_type_p (type1)
+ && promoted_arithmetic_type_p (type2))
+ /* That's OK. */
+ break;
+
+ /* Otherwise, the types should be pointers. */
+ if (!TYPE_PTR_OR_PTRMEM_P (type1) || !TYPE_PTR_OR_PTRMEM_P (type2))
+ return;
+
+ /* We don't check that the two types are the same; the logic
+ below will actually create two candidates; one in which both
+ parameter types are TYPE1, and one in which both parameter
+ types are TYPE2. */
+ break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ if (ARITHMETIC_TYPE_P (type1))
+ break;
+ return;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ /* Make sure we don't create builtin candidates with dependent types. */
+ bool u1 = uses_template_parms (type1);
+ bool u2 = type2 ? uses_template_parms (type2) : false;
+ if (u1 || u2)
+ {
+ /* Try to recover if one of the types is non-dependent. But if
+ there's only one type, there's nothing we can do. */
+ if (!type2)
+ return;
+ /* And we lose if both are dependent. */
+ if (u1 && u2)
+ return;
+ /* Or if they have different forms. */
+ if (TREE_CODE (type1) != TREE_CODE (type2))
+ return;
+
+ if (u1 && !u2)
+ type1 = type2;
+ else if (u2 && !u1)
+ type2 = type1;
+ }
+
+ /* If we're dealing with two pointer types or two enumeral types,
+ we need candidates for both of them. */
+ if (type2 && !same_type_p (type1, type2)
+ && TREE_CODE (type1) == TREE_CODE (type2)
+ && (TREE_CODE (type1) == REFERENCE_TYPE
+ || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
+ || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2))
+ || TYPE_PTRMEMFUNC_P (type1)
+ || MAYBE_CLASS_TYPE_P (type1)
+ || TREE_CODE (type1) == ENUMERAL_TYPE))
+ {
+ if (TYPE_PTR_OR_PTRMEM_P (type1))
+ {
+ tree cptype = composite_pointer_type (type1, type2,
+ error_mark_node,
+ error_mark_node,
+ CPO_CONVERSION,
+ tf_none);
+ if (cptype != error_mark_node)
+ {
+ build_builtin_candidate
+ (candidates, fnname, cptype, cptype, args, argtypes,
+ flags, complain);
+ return;
+ }
+ }
+
+ build_builtin_candidate
+ (candidates, fnname, type1, type1, args, argtypes, flags, complain);
+ build_builtin_candidate
+ (candidates, fnname, type2, type2, args, argtypes, flags, complain);
+ return;
+ }
+
+ build_builtin_candidate
+ (candidates, fnname, type1, type2, args, argtypes, flags, complain);
+}
+
+tree
+type_decays_to (tree type)
+{
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ return build_pointer_type (TREE_TYPE (type));
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ return build_pointer_type (type);
+ return type;
+}
+
+/* There are three conditions of builtin candidates:
+
+ 1) bool-taking candidates. These are the same regardless of the input.
+ 2) pointer-pair taking candidates. These are generated for each type
+ one of the input types converts to.
+ 3) arithmetic candidates. According to the standard, we should generate
+ all of these, but I'm trying not to...
+
+ Here we generate a superset of the possible candidates for this particular
+ case. That is a subset of the full set the standard defines, plus some
+ other cases which the standard disallows. add_builtin_candidate will
+ filter out the invalid set. */
+
+static void
+add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
+ enum tree_code code2, tree fnname, tree *args,
+ int flags, tsubst_flags_t complain)
+{
+ int ref1, i;
+ int enum_p = 0;
+ tree type, argtypes[3], t;
+ /* TYPES[i] is the set of possible builtin-operator parameter types
+ we will consider for the Ith argument. */
+ vec<tree, va_gc> *types[2];
+ unsigned ix;
+
+ for (i = 0; i < 3; ++i)
+ {
+ if (args[i])
+ argtypes[i] = unlowered_expr_type (args[i]);
+ else
+ argtypes[i] = NULL_TREE;
+ }
+
+ switch (code)
+ {
+/* 4 For every pair T, VQ), where T is an arithmetic or enumeration type,
+ and VQ is either volatile or empty, there exist candidate operator
+ functions of the form
+ VQ T& operator++(VQ T&); */
+
+ case POSTINCREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case MODIFY_EXPR:
+ ref1 = 1;
+ break;
+
+/* 24There also exist candidate operator functions of the form
+ bool operator!(bool);
+ bool operator&&(bool, bool);
+ bool operator||(bool, bool); */
+
+ case TRUTH_NOT_EXPR:
+ build_builtin_candidate
+ (candidates, fnname, boolean_type_node,
+ NULL_TREE, args, argtypes, flags, complain);
+ return;
+
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ build_builtin_candidate
+ (candidates, fnname, boolean_type_node,
+ boolean_type_node, args, argtypes, flags, complain);
+ return;
+
+ case ADDR_EXPR:
+ case COMPOUND_EXPR:
+ case COMPONENT_REF:
+ return;
+
+ case COND_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ enum_p = 1;
+ /* Fall through. */
+
+ default:
+ ref1 = 0;
+ }
+
+ types[0] = make_tree_vector ();
+ types[1] = make_tree_vector ();
+
+ for (i = 0; i < 2; ++i)
+ {
+ if (! args[i])
+ ;
+ else if (MAYBE_CLASS_TYPE_P (argtypes[i]))
+ {
+ tree convs;
+
+ if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR)
+ return;
+
+ convs = lookup_conversions (argtypes[i]);
+
+ if (code == COND_EXPR)
+ {
+ if (real_lvalue_p (args[i]))
+ vec_safe_push (types[i], build_reference_type (argtypes[i]));
+
+ vec_safe_push (types[i], TYPE_MAIN_VARIANT (argtypes[i]));
+ }
+
+ else if (! convs)
+ return;
+
+ for (; convs; convs = TREE_CHAIN (convs))
+ {
+ type = TREE_TYPE (convs);
+
+ if (i == 0 && ref1
+ && (TREE_CODE (type) != REFERENCE_TYPE
+ || CP_TYPE_CONST_P (TREE_TYPE (type))))
+ continue;
+
+ if (code == COND_EXPR && TREE_CODE (type) == REFERENCE_TYPE)
+ vec_safe_push (types[i], type);
+
+ type = non_reference (type);
+ if (i != 0 || ! ref1)
+ {
+ type = cv_unqualified (type_decays_to (type));
+ if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE)
+ vec_safe_push (types[i], type);
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+ type = type_promotes_to (type);
+ }
+
+ if (! vec_member (type, types[i]))
+ vec_safe_push (types[i], type);
+ }
+ }
+ else
+ {
+ if (code == COND_EXPR && real_lvalue_p (args[i]))
+ vec_safe_push (types[i], build_reference_type (argtypes[i]));
+ type = non_reference (argtypes[i]);
+ if (i != 0 || ! ref1)
+ {
+ type = cv_unqualified (type_decays_to (type));
+ if (enum_p && UNSCOPED_ENUM_P (type))
+ vec_safe_push (types[i], type);
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+ type = type_promotes_to (type);
+ }
+ vec_safe_push (types[i], type);
+ }
+ }
+
+ /* Run through the possible parameter types of both arguments,
+ creating candidates with those parameter types. */
+ FOR_EACH_VEC_ELT_REVERSE (*(types[0]), ix, t)
+ {
+ unsigned jx;
+ tree u;
+
+ if (!types[1]->is_empty ())
+ FOR_EACH_VEC_ELT_REVERSE (*(types[1]), jx, u)
+ add_builtin_candidate
+ (candidates, code, code2, fnname, t,
+ u, args, argtypes, flags, complain);
+ else
+ add_builtin_candidate
+ (candidates, code, code2, fnname, t,
+ NULL_TREE, args, argtypes, flags, complain);
+ }
+
+ release_tree_vector (types[0]);
+ release_tree_vector (types[1]);
+}
+
+
+/* If TMPL can be successfully instantiated as indicated by
+ EXPLICIT_TARGS and ARGLIST, adds the instantiation to CANDIDATES.
+
+ TMPL is the template. EXPLICIT_TARGS are any explicit template
+ arguments. ARGLIST is the arguments provided at the call-site.
+ This does not change ARGLIST. The RETURN_TYPE is the desired type
+ for conversion operators. If OBJ is NULL_TREE, FLAGS and CTYPE are
+ as for add_function_candidate. If an OBJ is supplied, FLAGS and
+ CTYPE are ignored, and OBJ is as for add_conv_candidate. */
+
+static struct z_candidate*
+add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
+ tree ctype, tree explicit_targs, tree first_arg,
+ const vec<tree, va_gc> *arglist, tree return_type,
+ tree access_path, tree conversion_path,
+ int flags, tree obj, unification_kind_t strict,
+ tsubst_flags_t complain)
+{
+ int ntparms = DECL_NTPARMS (tmpl);
+ tree targs = make_tree_vec (ntparms);
+ unsigned int len = vec_safe_length (arglist);
+ unsigned int nargs = (first_arg == NULL_TREE ? 0 : 1) + len;
+ unsigned int skip_without_in_chrg = 0;
+ tree first_arg_without_in_chrg = first_arg;
+ tree *args_without_in_chrg;
+ unsigned int nargs_without_in_chrg;
+ unsigned int ia, ix;
+ tree arg;
+ struct z_candidate *cand;
+ tree fn;
+ struct rejection_reason *reason = NULL;
+ int errs;
+
+ /* We don't do deduction on the in-charge parameter, the VTT
+ parameter or 'this'. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl))
+ {
+ if (first_arg_without_in_chrg != NULL_TREE)
+ first_arg_without_in_chrg = NULL_TREE;
+ else
+ ++skip_without_in_chrg;
+ }
+
+ if ((DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (tmpl)
+ || DECL_BASE_CONSTRUCTOR_P (tmpl))
+ && CLASSTYPE_VBASECLASSES (DECL_CONTEXT (tmpl)))
+ {
+ if (first_arg_without_in_chrg != NULL_TREE)
+ first_arg_without_in_chrg = NULL_TREE;
+ else
+ ++skip_without_in_chrg;
+ }
+
+ if (len < skip_without_in_chrg)
+ return NULL;
+
+ nargs_without_in_chrg = ((first_arg_without_in_chrg != NULL_TREE ? 1 : 0)
+ + (len - skip_without_in_chrg));
+ args_without_in_chrg = XALLOCAVEC (tree, nargs_without_in_chrg);
+ ia = 0;
+ if (first_arg_without_in_chrg != NULL_TREE)
+ {
+ args_without_in_chrg[ia] = first_arg_without_in_chrg;
+ ++ia;
+ }
+ for (ix = skip_without_in_chrg;
+ vec_safe_iterate (arglist, ix, &arg);
+ ++ix)
+ {
+ args_without_in_chrg[ia] = arg;
+ ++ia;
+ }
+ gcc_assert (ia == nargs_without_in_chrg);
+
+ errs = errorcount+sorrycount;
+ fn = fn_type_unification (tmpl, explicit_targs, targs,
+ args_without_in_chrg,
+ nargs_without_in_chrg,
+ return_type, strict, flags, false,
+ complain & tf_decltype);
+
+ if (fn == error_mark_node)
+ {
+ /* Don't repeat unification later if it already resulted in errors. */
+ if (errorcount+sorrycount == errs)
+ reason = template_unification_rejection (tmpl, explicit_targs,
+ targs, args_without_in_chrg,
+ nargs_without_in_chrg,
+ return_type, strict, flags);
+ else
+ reason = template_unification_error_rejection ();
+ goto fail;
+ }
+
+ /* In [class.copy]:
+
+ A member function template is never instantiated to perform the
+ copy of a class object to an object of its class type.
+
+ It's a little unclear what this means; the standard explicitly
+ does allow a template to be used to copy a class. For example,
+ in:
+
+ struct A {
+ A(A&);
+ template <class T> A(const T&);
+ };
+ const A f ();
+ void g () { A a (f ()); }
+
+ the member template will be used to make the copy. The section
+ quoted above appears in the paragraph that forbids constructors
+ whose only parameter is (a possibly cv-qualified variant of) the
+ class type, and a logical interpretation is that the intent was
+ to forbid the instantiation of member templates which would then
+ have that form. */
+ if (DECL_CONSTRUCTOR_P (fn) && nargs == 2)
+ {
+ tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
+ ctype))
+ {
+ reason = invalid_copy_with_fn_template_rejection ();
+ goto fail;
+ }
+ }
+
+ if (obj != NULL_TREE)
+ /* Aha, this is a conversion function. */
+ cand = add_conv_candidate (candidates, fn, obj, first_arg, arglist,
+ access_path, conversion_path, complain);
+ else
+ cand = add_function_candidate (candidates, fn, ctype,
+ first_arg, arglist, access_path,
+ conversion_path, flags, complain);
+ if (DECL_TI_TEMPLATE (fn) != tmpl)
+ /* This situation can occur if a member template of a template
+ class is specialized. Then, instantiate_template might return
+ an instantiation of the specialization, in which case the
+ DECL_TI_TEMPLATE field will point at the original
+ specialization. For example:
+
+ template <class T> struct S { template <class U> void f(U);
+ template <> void f(int) {}; };
+ S<double> sd;
+ sd.f(3);
+
+ Here, TMPL will be template <class U> S<double>::f(U).
+ And, instantiate template will give us the specialization
+ template <> S<double>::f(int). But, the DECL_TI_TEMPLATE field
+ for this will point at template <class T> template <> S<T>::f(int),
+ so that we can find the definition. For the purposes of
+ overload resolution, however, we want the original TMPL. */
+ cand->template_decl = build_template_info (tmpl, targs);
+ else
+ cand->template_decl = DECL_TEMPLATE_INFO (fn);
+ cand->explicit_targs = explicit_targs;
+
+ return cand;
+ fail:
+ return add_candidate (candidates, tmpl, first_arg, arglist, nargs, NULL,
+ access_path, conversion_path, 0, reason);
+}
+
+
+static struct z_candidate *
+add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype,
+ tree explicit_targs, tree first_arg,
+ const vec<tree, va_gc> *arglist, tree return_type,
+ tree access_path, tree conversion_path, int flags,
+ unification_kind_t strict, tsubst_flags_t complain)
+{
+ return
+ add_template_candidate_real (candidates, tmpl, ctype,
+ explicit_targs, first_arg, arglist,
+ return_type, access_path, conversion_path,
+ flags, NULL_TREE, strict, complain);
+}
+
+
+static struct z_candidate *
+add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
+ tree obj, tree first_arg,
+ const vec<tree, va_gc> *arglist,
+ tree return_type, tree access_path,
+ tree conversion_path, tsubst_flags_t complain)
+{
+ return
+ add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
+ first_arg, arglist, return_type, access_path,
+ conversion_path, 0, obj, DEDUCE_CONV,
+ complain);
+}
+
+/* The CANDS are the set of candidates that were considered for
+ overload resolution. Return the set of viable candidates, or CANDS
+ if none are viable. If any of the candidates were viable, set
+ *ANY_VIABLE_P to true. STRICT_P is true if a candidate should be
+ considered viable only if it is strictly viable. */
+
+static struct z_candidate*
+splice_viable (struct z_candidate *cands,
+ bool strict_p,
+ bool *any_viable_p)
+{
+ struct z_candidate *viable;
+ struct z_candidate **last_viable;
+ struct z_candidate **cand;
+
+ /* Be strict inside templates, since build_over_call won't actually
+ do the conversions to get pedwarns. */
+ if (processing_template_decl)
+ strict_p = true;
+
+ viable = NULL;
+ last_viable = &viable;
+ *any_viable_p = false;
+
+ cand = &cands;
+ while (*cand)
+ {
+ struct z_candidate *c = *cand;
+ if (strict_p ? c->viable == 1 : c->viable)
+ {
+ *last_viable = c;
+ *cand = c->next;
+ c->next = NULL;
+ last_viable = &c->next;
+ *any_viable_p = true;
+ }
+ else
+ cand = &c->next;
+ }
+
+ return viable ? viable : cands;
+}
+
+static bool
+any_strictly_viable (struct z_candidate *cands)
+{
+ for (; cands; cands = cands->next)
+ if (cands->viable == 1)
+ return true;
+ return false;
+}
+
+/* OBJ is being used in an expression like "OBJ.f (...)". In other
+ words, it is about to become the "this" pointer for a member
+ function call. Take the address of the object. */
+
+static tree
+build_this (tree obj)
+{
+ /* In a template, we are only concerned about the type of the
+ expression, so we can take a shortcut. */
+ if (processing_template_decl)
+ return build_address (obj);
+
+ return cp_build_addr_expr (obj, tf_warning_or_error);
+}
+
+/* Returns true iff functions are equivalent. Equivalent functions are
+ not '==' only if one is a function-local extern function or if
+ both are extern "C". */
+
+static inline int
+equal_functions (tree fn1, tree fn2)
+{
+ if (TREE_CODE (fn1) != TREE_CODE (fn2))
+ return 0;
+ if (TREE_CODE (fn1) == TEMPLATE_DECL)
+ return fn1 == fn2;
+ if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
+ || DECL_EXTERN_C_FUNCTION_P (fn1))
+ return decls_match (fn1, fn2);
+ return fn1 == fn2;
+}
+
+/* Print information about a candidate being rejected due to INFO. */
+
+static void
+print_conversion_rejection (location_t loc, struct conversion_info *info)
+{
+ if (info->n_arg == -1)
+ /* Conversion of implicit `this' argument failed. */
+ inform (loc, " no known conversion for implicit "
+ "%<this%> parameter from %qT to %qT",
+ info->from_type, info->to_type);
+ else if (info->n_arg == -2)
+ /* Conversion of conversion function return value failed. */
+ inform (loc, " no known conversion from %qT to %qT",
+ info->from_type, info->to_type);
+ else
+ inform (loc, " no known conversion for argument %d from %qT to %qT",
+ info->n_arg+1, info->from_type, info->to_type);
+}
+
+/* Print information about a candidate with WANT parameters and we found
+ HAVE. */
+
+static void
+print_arity_information (location_t loc, unsigned int have, unsigned int want)
+{
+ inform_n (loc, want,
+ " candidate expects %d argument, %d provided",
+ " candidate expects %d arguments, %d provided",
+ want, have);
+}
+
+/* Print information about one overload candidate CANDIDATE. MSGSTR
+ is the text to print before the candidate itself.
+
+ NOTE: Unlike most diagnostic functions in GCC, MSGSTR is expected
+ to have been run through gettext by the caller. This wart makes
+ life simpler in print_z_candidates and for the translators. */
+
+static void
+print_z_candidate (location_t loc, const char *msgstr,
+ struct z_candidate *candidate)
+{
+ const char *msg = (msgstr == NULL
+ ? ""
+ : ACONCAT ((msgstr, " ", NULL)));
+ location_t cloc = location_of (candidate->fn);
+
+ if (identifier_p (candidate->fn))
+ {
+ cloc = loc;
+ if (candidate->num_convs == 3)
+ inform (cloc, "%s%D(%T, %T, %T) <built-in>", msg, candidate->fn,
+ candidate->convs[0]->type,
+ candidate->convs[1]->type,
+ candidate->convs[2]->type);
+ else if (candidate->num_convs == 2)
+ inform (cloc, "%s%D(%T, %T) <built-in>", msg, candidate->fn,
+ candidate->convs[0]->type,
+ candidate->convs[1]->type);
+ else
+ inform (cloc, "%s%D(%T) <built-in>", msg, candidate->fn,
+ candidate->convs[0]->type);
+ }
+ else if (TYPE_P (candidate->fn))
+ inform (cloc, "%s%T <conversion>", msg, candidate->fn);
+ else if (candidate->viable == -1)
+ inform (cloc, "%s%#D <near match>", msg, candidate->fn);
+ else if (DECL_DELETED_FN (candidate->fn))
+ inform (cloc, "%s%#D <deleted>", msg, candidate->fn);
+ else
+ inform (cloc, "%s%#D", msg, candidate->fn);
+ /* Give the user some information about why this candidate failed. */
+ if (candidate->reason != NULL)
+ {
+ struct rejection_reason *r = candidate->reason;
+
+ switch (r->code)
+ {
+ case rr_arity:
+ print_arity_information (cloc, r->u.arity.actual,
+ r->u.arity.expected);
+ break;
+ case rr_arg_conversion:
+ print_conversion_rejection (cloc, &r->u.conversion);
+ break;
+ case rr_bad_arg_conversion:
+ print_conversion_rejection (cloc, &r->u.bad_conversion);
+ break;
+ case rr_explicit_conversion:
+ inform (cloc, " return type %qT of explicit conversion function "
+ "cannot be converted to %qT with a qualification "
+ "conversion", r->u.conversion.from_type,
+ r->u.conversion.to_type);
+ break;
+ case rr_template_conversion:
+ inform (cloc, " conversion from return type %qT of template "
+ "conversion function specialization to %qT is not an "
+ "exact match", r->u.conversion.from_type,
+ r->u.conversion.to_type);
+ break;
+ case rr_template_unification:
+ /* We use template_unification_error_rejection if unification caused
+ actual non-SFINAE errors, in which case we don't need to repeat
+ them here. */
+ if (r->u.template_unification.tmpl == NULL_TREE)
+ {
+ inform (cloc, " substitution of deduced template arguments "
+ "resulted in errors seen above");
+ break;
+ }
+ /* Re-run template unification with diagnostics. */
+ inform (cloc, " template argument deduction/substitution failed:");
+ fn_type_unification (r->u.template_unification.tmpl,
+ r->u.template_unification.explicit_targs,
+ (make_tree_vec
+ (r->u.template_unification.num_targs)),
+ r->u.template_unification.args,
+ r->u.template_unification.nargs,
+ r->u.template_unification.return_type,
+ r->u.template_unification.strict,
+ r->u.template_unification.flags,
+ true, false);
+ break;
+ case rr_invalid_copy:
+ inform (cloc,
+ " a constructor taking a single argument of its own "
+ "class type is invalid");
+ break;
+ case rr_none:
+ default:
+ /* This candidate didn't have any issues or we failed to
+ handle a particular code. Either way... */
+ gcc_unreachable ();
+ }
+ }
+}
+
+static void
+print_z_candidates (location_t loc, struct z_candidate *candidates)
+{
+ struct z_candidate *cand1;
+ struct z_candidate **cand2;
+ int n_candidates;
+
+ if (!candidates)
+ return;
+
+ /* Remove non-viable deleted candidates. */
+ cand1 = candidates;
+ for (cand2 = &cand1; *cand2; )
+ {
+ if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL
+ && !(*cand2)->viable
+ && DECL_DELETED_FN ((*cand2)->fn))
+ *cand2 = (*cand2)->next;
+ else
+ cand2 = &(*cand2)->next;
+ }
+ /* ...if there are any non-deleted ones. */
+ if (cand1)
+ candidates = cand1;
+
+ /* There may be duplicates in the set of candidates. We put off
+ checking this condition as long as possible, since we have no way
+ to eliminate duplicates from a set of functions in less than n^2
+ time. Now we are about to emit an error message, so it is more
+ permissible to go slowly. */
+ for (cand1 = candidates; cand1; cand1 = cand1->next)
+ {
+ tree fn = cand1->fn;
+ /* Skip builtin candidates and conversion functions. */
+ if (!DECL_P (fn))
+ continue;
+ cand2 = &cand1->next;
+ while (*cand2)
+ {
+ if (DECL_P ((*cand2)->fn)
+ && equal_functions (fn, (*cand2)->fn))
+ *cand2 = (*cand2)->next;
+ else
+ cand2 = &(*cand2)->next;
+ }
+ }
+
+ for (n_candidates = 0, cand1 = candidates; cand1; cand1 = cand1->next)
+ n_candidates++;
+
+ inform_n (loc, n_candidates, "candidate is:", "candidates are:");
+ for (; candidates; candidates = candidates->next)
+ print_z_candidate (loc, NULL, candidates);
+}
+
+/* USER_SEQ is a user-defined conversion sequence, beginning with a
+ USER_CONV. STD_SEQ is the standard conversion sequence applied to
+ the result of the conversion function to convert it to the final
+ desired type. Merge the two sequences into a single sequence,
+ and return the merged sequence. */
+
+static conversion *
+merge_conversion_sequences (conversion *user_seq, conversion *std_seq)
+{
+ conversion **t;
+ bool bad = user_seq->bad_p;
+
+ gcc_assert (user_seq->kind == ck_user);
+
+ /* Find the end of the second conversion sequence. */
+ for (t = &std_seq; (*t)->kind != ck_identity; t = &((*t)->u.next))
+ {
+ /* The entire sequence is a user-conversion sequence. */
+ (*t)->user_conv_p = true;
+ if (bad)
+ (*t)->bad_p = true;
+ }
+
+ /* Replace the identity conversion with the user conversion
+ sequence. */
+ *t = user_seq;
+
+ return std_seq;
+}
+
+/* Handle overload resolution for initializing an object of class type from
+ an initializer list. First we look for a suitable constructor that
+ takes a std::initializer_list; if we don't find one, we then look for a
+ non-list constructor.
+
+ Parameters are as for add_candidates, except that the arguments are in
+ the form of a CONSTRUCTOR (the initializer list) rather than a vector, and
+ the RETURN_TYPE parameter is replaced by TOTYPE, the desired type. */
+
+static void
+add_list_candidates (tree fns, tree first_arg,
+ tree init_list, tree totype,
+ tree explicit_targs, bool template_only,
+ tree conversion_path, tree access_path,
+ int flags,
+ struct z_candidate **candidates,
+ tsubst_flags_t complain)
+{
+ vec<tree, va_gc> *args;
+
+ gcc_assert (*candidates == NULL);
+
+ /* We're looking for a ctor for list-initialization. */
+ flags |= LOOKUP_LIST_INIT_CTOR;
+ /* And we don't allow narrowing conversions. We also use this flag to
+ avoid the copy constructor call for copy-list-initialization. */
+ flags |= LOOKUP_NO_NARROWING;
+
+ /* Always use the default constructor if the list is empty (DR 990). */
+ if (CONSTRUCTOR_NELTS (init_list) == 0
+ && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
+ ;
+ /* If the class has a list ctor, try passing the list as a single
+ argument first, but only consider list ctors. */
+ else if (TYPE_HAS_LIST_CTOR (totype))
+ {
+ flags |= LOOKUP_LIST_ONLY;
+ args = make_tree_vector_single (init_list);
+ add_candidates (fns, first_arg, args, NULL_TREE,
+ explicit_targs, template_only, conversion_path,
+ access_path, flags, candidates, complain);
+ if (any_strictly_viable (*candidates))
+ return;
+ }
+
+ args = ctor_to_vec (init_list);
+
+ /* We aren't looking for list-ctors anymore. */
+ flags &= ~LOOKUP_LIST_ONLY;
+ /* We allow more user-defined conversions within an init-list. */
+ flags &= ~LOOKUP_NO_CONVERSION;
+
+ add_candidates (fns, first_arg, args, NULL_TREE,
+ explicit_targs, template_only, conversion_path,
+ access_path, flags, candidates, complain);
+}
+
+/* Returns the best overload candidate to perform the requested
+ conversion. This function is used for three the overloading situations
+ described in [over.match.copy], [over.match.conv], and [over.match.ref].
+ If TOTYPE is a REFERENCE_TYPE, we're trying to find a direct binding as
+ per [dcl.init.ref], so we ignore temporary bindings. */
+
+static struct z_candidate *
+build_user_type_conversion_1 (tree totype, tree expr, int flags,
+ tsubst_flags_t complain)
+{
+ struct z_candidate *candidates, *cand;
+ tree fromtype;
+ tree ctors = NULL_TREE;
+ tree conv_fns = NULL_TREE;
+ conversion *conv = NULL;
+ tree first_arg = NULL_TREE;
+ vec<tree, va_gc> *args = NULL;
+ bool any_viable_p;
+ int convflags;
+
+ if (!expr)
+ return NULL;
+
+ fromtype = TREE_TYPE (expr);
+
+ /* We represent conversion within a hierarchy using RVALUE_CONV and
+ BASE_CONV, as specified by [over.best.ics]; these become plain
+ constructor calls, as specified in [dcl.init]. */
+ gcc_assert (!MAYBE_CLASS_TYPE_P (fromtype) || !MAYBE_CLASS_TYPE_P (totype)
+ || !DERIVED_FROM_P (totype, fromtype));
+
+ if (MAYBE_CLASS_TYPE_P (totype))
+ /* Use lookup_fnfields_slot instead of lookup_fnfields to avoid
+ creating a garbage BASELINK; constructors can't be inherited. */
+ ctors = lookup_fnfields_slot (totype, complete_ctor_identifier);
+
+ if (MAYBE_CLASS_TYPE_P (fromtype))
+ {
+ tree to_nonref = non_reference (totype);
+ if (same_type_ignoring_top_level_qualifiers_p (to_nonref, fromtype) ||
+ (CLASS_TYPE_P (to_nonref) && CLASS_TYPE_P (fromtype)
+ && DERIVED_FROM_P (to_nonref, fromtype)))
+ {
+ /* [class.conv.fct] A conversion function is never used to
+ convert a (possibly cv-qualified) object to the (possibly
+ cv-qualified) same object type (or a reference to it), to a
+ (possibly cv-qualified) base class of that type (or a
+ reference to it)... */
+ }
+ else
+ conv_fns = lookup_conversions (fromtype);
+ }
+
+ candidates = 0;
+ flags |= LOOKUP_NO_CONVERSION;
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+ flags |= LOOKUP_NO_NARROWING;
+
+ /* It's OK to bind a temporary for converting constructor arguments, but
+ not in converting the return value of a conversion operator. */
+ convflags = ((flags & LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION);
+ flags &= ~LOOKUP_NO_TEMP_BIND;
+
+ if (ctors)
+ {
+ int ctorflags = flags;
+
+ first_arg = build_int_cst (build_pointer_type (totype), 0);
+ first_arg = build_fold_indirect_ref (first_arg);
+
+ /* We should never try to call the abstract or base constructor
+ from here. */
+ gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))
+ && !DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors)));
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ /* List-initialization. */
+ add_list_candidates (ctors, first_arg, expr, totype, NULL_TREE,
+ false, TYPE_BINFO (totype), TYPE_BINFO (totype),
+ ctorflags, &candidates, complain);
+ }
+ else
+ {
+ args = make_tree_vector_single (expr);
+ add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false,
+ TYPE_BINFO (totype), TYPE_BINFO (totype),
+ ctorflags, &candidates, complain);
+ }
+
+ for (cand = candidates; cand; cand = cand->next)
+ {
+ cand->second_conv = build_identity_conv (totype, NULL_TREE);
+
+ /* If totype isn't a reference, and LOOKUP_NO_TEMP_BIND isn't
+ set, then this is copy-initialization. In that case, "The
+ result of the call is then used to direct-initialize the
+ object that is the destination of the copy-initialization."
+ [dcl.init]
+
+ We represent this in the conversion sequence with an
+ rvalue conversion, which means a constructor call. */
+ if (TREE_CODE (totype) != REFERENCE_TYPE
+ && !(convflags & LOOKUP_NO_TEMP_BIND))
+ cand->second_conv
+ = build_conv (ck_rvalue, totype, cand->second_conv);
+ }
+ }
+
+ if (conv_fns)
+ first_arg = expr;
+
+ for (; conv_fns; conv_fns = TREE_CHAIN (conv_fns))
+ {
+ tree conversion_path = TREE_PURPOSE (conv_fns);
+ struct z_candidate *old_candidates;
+
+ /* If we are called to convert to a reference type, we are trying to
+ find a direct binding, so don't even consider temporaries. If
+ we don't find a direct binding, the caller will try again to
+ look for a temporary binding. */
+ if (TREE_CODE (totype) == REFERENCE_TYPE)
+ convflags |= LOOKUP_NO_TEMP_BIND;
+
+ old_candidates = candidates;
+ add_candidates (TREE_VALUE (conv_fns), first_arg, NULL, totype,
+ NULL_TREE, false,
+ conversion_path, TYPE_BINFO (fromtype),
+ flags, &candidates, complain);
+
+ for (cand = candidates; cand != old_candidates; cand = cand->next)
+ {
+ tree rettype = TREE_TYPE (TREE_TYPE (cand->fn));
+ conversion *ics
+ = implicit_conversion (totype,
+ rettype,
+ 0,
+ /*c_cast_p=*/false, convflags,
+ complain);
+
+ /* If LOOKUP_NO_TEMP_BIND isn't set, then this is
+ copy-initialization. In that case, "The result of the
+ call is then used to direct-initialize the object that is
+ the destination of the copy-initialization." [dcl.init]
+
+ We represent this in the conversion sequence with an
+ rvalue conversion, which means a constructor call. But
+ don't add a second rvalue conversion if there's already
+ one there. Which there really shouldn't be, but it's
+ harmless since we'd add it here anyway. */
+ if (ics && MAYBE_CLASS_TYPE_P (totype) && ics->kind != ck_rvalue
+ && !(convflags & LOOKUP_NO_TEMP_BIND))
+ ics = build_conv (ck_rvalue, totype, ics);
+
+ cand->second_conv = ics;
+
+ if (!ics)
+ {
+ cand->viable = 0;
+ cand->reason = arg_conversion_rejection (NULL_TREE, -2,
+ rettype, totype);
+ }
+ else if (DECL_NONCONVERTING_P (cand->fn)
+ && ics->rank > cr_exact)
+ {
+ /* 13.3.1.5: For direct-initialization, those explicit
+ conversion functions that are not hidden within S and
+ yield type T or a type that can be converted to type T
+ with a qualification conversion (4.4) are also candidate
+ functions. */
+ /* 13.3.1.6 doesn't have a parallel restriction, but it should;
+ I've raised this issue with the committee. --jason 9/2011 */
+ cand->viable = -1;
+ cand->reason = explicit_conversion_rejection (rettype, totype);
+ }
+ else if (cand->viable == 1 && ics->bad_p)
+ {
+ cand->viable = -1;
+ cand->reason
+ = bad_arg_conversion_rejection (NULL_TREE, -2,
+ rettype, totype);
+ }
+ else if (primary_template_instantiation_p (cand->fn)
+ && ics->rank > cr_exact)
+ {
+ /* 13.3.3.1.2: If the user-defined conversion is specified by
+ a specialization of a conversion function template, the
+ second standard conversion sequence shall have exact match
+ rank. */
+ cand->viable = -1;
+ cand->reason = template_conversion_rejection (rettype, totype);
+ }
+ }
+ }
+
+ candidates = splice_viable (candidates, pedantic, &any_viable_p);
+ if (!any_viable_p)
+ {
+ if (args)
+ release_tree_vector (args);
+ return NULL;
+ }
+
+ cand = tourney (candidates, complain);
+ if (cand == 0)
+ {
+ if (complain & tf_error)
+ {
+ error ("conversion from %qT to %qT is ambiguous",
+ fromtype, totype);
+ print_z_candidates (location_of (expr), candidates);
+ }
+
+ cand = candidates; /* any one will do */
+ cand->second_conv = build_ambiguous_conv (totype, expr);
+ cand->second_conv->user_conv_p = true;
+ if (!any_strictly_viable (candidates))
+ cand->second_conv->bad_p = true;
+ /* If there are viable candidates, don't set ICS_BAD_FLAG; an
+ ambiguous conversion is no worse than another user-defined
+ conversion. */
+
+ return cand;
+ }
+
+ /* Build the user conversion sequence. */
+ conv = build_conv
+ (ck_user,
+ (DECL_CONSTRUCTOR_P (cand->fn)
+ ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))),
+ build_identity_conv (TREE_TYPE (expr), expr));
+ conv->cand = cand;
+ if (cand->viable == -1)
+ conv->bad_p = true;
+
+ /* Remember that this was a list-initialization. */
+ if (flags & LOOKUP_NO_NARROWING)
+ conv->check_narrowing = true;
+
+ /* Combine it with the second conversion sequence. */
+ cand->second_conv = merge_conversion_sequences (conv,
+ cand->second_conv);
+
+ return cand;
+}
+
+/* Wrapper for above. */
+
+tree
+build_user_type_conversion (tree totype, tree expr, int flags,
+ tsubst_flags_t complain)
+{
+ struct z_candidate *cand;
+ tree ret;
+
+ bool subtime = timevar_cond_start (TV_OVERLOAD);
+ cand = build_user_type_conversion_1 (totype, expr, flags, complain);
+
+ if (cand)
+ {
+ if (cand->second_conv->kind == ck_ambig)
+ ret = error_mark_node;
+ else
+ {
+ expr = convert_like (cand->second_conv, expr, complain);
+ ret = convert_from_reference (expr);
+ }
+ }
+ else
+ ret = NULL_TREE;
+
+ timevar_cond_stop (TV_OVERLOAD, subtime);
+ return ret;
+}
+
+/* Subroutine of convert_nontype_argument.
+
+ EXPR is an argument for a template non-type parameter of integral or
+ enumeration type. Do any necessary conversions (that are permitted for
+ non-type arguments) to convert it to the parameter type.
+
+ If conversion is successful, returns the converted expression;
+ otherwise, returns error_mark_node. */
+
+tree
+build_integral_nontype_arg_conv (tree type, tree expr, tsubst_flags_t complain)
+{
+ conversion *conv;
+ void *p;
+ tree t;
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+
+ if (error_operand_p (expr))
+ return error_mark_node;
+
+ gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ conv = implicit_conversion (type, TREE_TYPE (expr), expr,
+ /*c_cast_p=*/false,
+ LOOKUP_IMPLICIT, complain);
+
+ /* for a non-type template-parameter of integral or
+ enumeration type, integral promotions (4.5) and integral
+ conversions (4.7) are applied. */
+ /* It should be sufficient to check the outermost conversion step, since
+ there are no qualification conversions to integer type. */
+ if (conv)
+ switch (conv->kind)
+ {
+ /* A conversion function is OK. If it isn't constexpr, we'll
+ complain later that the argument isn't constant. */
+ case ck_user:
+ /* The lvalue-to-rvalue conversion is OK. */
+ case ck_rvalue:
+ case ck_identity:
+ break;
+
+ case ck_std:
+ t = next_conversion (conv)->type;
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (t))
+ break;
+
+ if (complain & tf_error)
+ error_at (loc, "conversion from %qT to %qT not considered for "
+ "non-type template argument", t, type);
+ /* and fall through. */
+
+ default:
+ conv = NULL;
+ break;
+ }
+
+ if (conv)
+ expr = convert_like (conv, expr, complain);
+ else
+ expr = error_mark_node;
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return expr;
+}
+
+/* Do any initial processing on the arguments to a function call. */
+
+static vec<tree, va_gc> *
+resolve_args (vec<tree, va_gc> *args, tsubst_flags_t complain)
+{
+ unsigned int ix;
+ tree arg;
+
+ FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
+ {
+ if (error_operand_p (arg))
+ return NULL;
+ else if (VOID_TYPE_P (TREE_TYPE (arg)))
+ {
+ if (complain & tf_error)
+ error ("invalid use of void expression");
+ return NULL;
+ }
+ else if (invalid_nonstatic_memfn_p (arg, complain))
+ return NULL;
+ }
+ return args;
+}
+
+/* Perform overload resolution on FN, which is called with the ARGS.
+
+ Return the candidate function selected by overload resolution, or
+ NULL if the event that overload resolution failed. In the case
+ that overload resolution fails, *CANDIDATES will be the set of
+ candidates considered, and ANY_VIABLE_P will be set to true or
+ false to indicate whether or not any of the candidates were
+ viable.
+
+ The ARGS should already have gone through RESOLVE_ARGS before this
+ function is called. */
+
+static struct z_candidate *
+perform_overload_resolution (tree fn,
+ const vec<tree, va_gc> *args,
+ struct z_candidate **candidates,
+ bool *any_viable_p, tsubst_flags_t complain)
+{
+ struct z_candidate *cand;
+ tree explicit_targs;
+ int template_only;
+
+ bool subtime = timevar_cond_start (TV_OVERLOAD);
+
+ explicit_targs = NULL_TREE;
+ template_only = 0;
+
+ *candidates = NULL;
+ *any_viable_p = true;
+
+ /* Check FN. */
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
+ || TREE_CODE (fn) == TEMPLATE_DECL
+ || TREE_CODE (fn) == OVERLOAD
+ || TREE_CODE (fn) == TEMPLATE_ID_EXPR);
+
+ if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+ {
+ explicit_targs = TREE_OPERAND (fn, 1);
+ fn = TREE_OPERAND (fn, 0);
+ template_only = 1;
+ }
+
+ /* Add the various candidate functions. */
+ add_candidates (fn, NULL_TREE, args, NULL_TREE,
+ explicit_targs, template_only,
+ /*conversion_path=*/NULL_TREE,
+ /*access_path=*/NULL_TREE,
+ LOOKUP_NORMAL,
+ candidates, complain);
+
+ *candidates = splice_viable (*candidates, pedantic, any_viable_p);
+ if (*any_viable_p)
+ cand = tourney (*candidates, complain);
+ else
+ cand = NULL;
+
+ timevar_cond_stop (TV_OVERLOAD, subtime);
+ return cand;
+}
+
+/* Print an error message about being unable to build a call to FN with
+ ARGS. ANY_VIABLE_P indicates whether any candidate functions could
+ be located; CANDIDATES is a possibly empty list of such
+ functions. */
+
+static void
+print_error_for_call_failure (tree fn, vec<tree, va_gc> *args, bool any_viable_p,
+ struct z_candidate *candidates)
+{
+ tree name = DECL_NAME (OVL_CURRENT (fn));
+ location_t loc = location_of (name);
+
+ if (!any_viable_p)
+ error_at (loc, "no matching function for call to %<%D(%A)%>",
+ name, build_tree_list_vec (args));
+ else
+ error_at (loc, "call of overloaded %<%D(%A)%> is ambiguous",
+ name, build_tree_list_vec (args));
+ if (candidates)
+ print_z_candidates (loc, candidates);
+}
+
+/* Return an expression for a call to FN (a namespace-scope function,
+ or a static member function) with the ARGS. This may change
+ ARGS. */
+
+tree
+build_new_function_call (tree fn, vec<tree, va_gc> **args, bool koenig_p,
+ tsubst_flags_t complain)
+{
+ struct z_candidate *candidates, *cand;
+ bool any_viable_p;
+ void *p;
+ tree result;
+
+ if (args != NULL && *args != NULL)
+ {
+ *args = resolve_args (*args, complain);
+ if (*args == NULL)
+ return error_mark_node;
+ }
+
+ if (flag_tm)
+ tm_malloc_replacement (fn);
+
+ /* If this function was found without using argument dependent
+ lookup, then we want to ignore any undeclared friend
+ functions. */
+ if (!koenig_p)
+ {
+ tree orig_fn = fn;
+
+ fn = remove_hidden_names (fn);
+ if (!fn)
+ {
+ if (complain & tf_error)
+ print_error_for_call_failure (orig_fn, *args, false, NULL);
+ return error_mark_node;
+ }
+ }
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ cand = perform_overload_resolution (fn, *args, &candidates, &any_viable_p,
+ complain);
+
+ if (!cand)
+ {
+ if (complain & tf_error)
+ {
+ if (!any_viable_p && candidates && ! candidates->next
+ && (TREE_CODE (candidates->fn) == FUNCTION_DECL))
+ return cp_build_function_call_vec (candidates->fn, args, complain);
+ if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+ fn = TREE_OPERAND (fn, 0);
+ print_error_for_call_failure (fn, *args, any_viable_p, candidates);
+ }
+ result = error_mark_node;
+ }
+ else
+ {
+ int flags = LOOKUP_NORMAL;
+ /* If fn is template_id_expr, the call has explicit template arguments
+ (e.g. func<int>(5)), communicate this info to build_over_call
+ through flags so that later we can use it to decide whether to warn
+ about peculiar null pointer conversion. */
+ if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+ flags |= LOOKUP_EXPLICIT_TMPL_ARGS;
+ result = build_over_call (cand, flags, complain);
+ }
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return result;
+}
+
+/* Build a call to a global operator new. FNNAME is the name of the
+ operator (either "operator new" or "operator new[]") and ARGS are
+ the arguments provided. This may change ARGS. *SIZE points to the
+ total number of bytes required by the allocation, and is updated if
+ that is changed here. *COOKIE_SIZE is non-NULL if a cookie should
+ be used. If this function determines that no cookie should be
+ used, after all, *COOKIE_SIZE is set to NULL_TREE. If SIZE_CHECK
+ is not NULL_TREE, it is evaluated before calculating the final
+ array size, and if it fails, the array size is replaced with
+ (size_t)-1 (usually triggering a std::bad_alloc exception). If FN
+ is non-NULL, it will be set, upon return, to the allocation
+ function called. */
+
+tree
+build_operator_new_call (tree fnname, vec<tree, va_gc> **args,
+ tree *size, tree *cookie_size, tree size_check,
+ tree *fn, tsubst_flags_t complain)
+{
+ tree original_size = *size;
+ tree fns;
+ struct z_candidate *candidates;
+ struct z_candidate *cand;
+ bool any_viable_p;
+
+ if (fn)
+ *fn = NULL_TREE;
+ /* Set to (size_t)-1 if the size check fails. */
+ if (size_check != NULL_TREE)
+ {
+ tree errval = TYPE_MAX_VALUE (sizetype);
+ if (cxx_dialect >= cxx11 && flag_exceptions)
+ errval = throw_bad_array_new_length ();
+ *size = fold_build3 (COND_EXPR, sizetype, size_check,
+ original_size, errval);
+ }
+ vec_safe_insert (*args, 0, *size);
+ *args = resolve_args (*args, complain);
+ if (*args == NULL)
+ return error_mark_node;
+
+ /* Based on:
+
+ [expr.new]
+
+ If this lookup fails to find the name, or if the allocated type
+ is not a class type, the allocation function's name is looked
+ up in the global scope.
+
+ we disregard block-scope declarations of "operator new". */
+ fns = lookup_function_nonclass (fnname, *args, /*block_p=*/false);
+
+ /* Figure out what function is being called. */
+ cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p,
+ complain);
+
+ /* If no suitable function could be found, issue an error message
+ and give up. */
+ if (!cand)
+ {
+ if (complain & tf_error)
+ print_error_for_call_failure (fns, *args, any_viable_p, candidates);
+ return error_mark_node;
+ }
+
+ /* If a cookie is required, add some extra space. Whether
+ or not a cookie is required cannot be determined until
+ after we know which function was called. */
+ if (*cookie_size)
+ {
+ bool use_cookie = true;
+ if (!abi_version_at_least (2))
+ {
+ /* In G++ 3.2, the check was implemented incorrectly; it
+ looked at the placement expression, rather than the
+ type of the function. */
+ if ((*args)->length () == 2
+ && same_type_p (TREE_TYPE ((**args)[1]), ptr_type_node))
+ use_cookie = false;
+ }
+ else
+ {
+ tree arg_types;
+
+ arg_types = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
+ /* Skip the size_t parameter. */
+ arg_types = TREE_CHAIN (arg_types);
+ /* Check the remaining parameters (if any). */
+ if (arg_types
+ && TREE_CHAIN (arg_types) == void_list_node
+ && same_type_p (TREE_VALUE (arg_types),
+ ptr_type_node))
+ use_cookie = false;
+ }
+ /* If we need a cookie, adjust the number of bytes allocated. */
+ if (use_cookie)
+ {
+ /* Update the total size. */
+ *size = size_binop (PLUS_EXPR, original_size, *cookie_size);
+ /* Set to (size_t)-1 if the size check fails. */
+ gcc_assert (size_check != NULL_TREE);
+ *size = fold_build3 (COND_EXPR, sizetype, size_check,
+ *size, TYPE_MAX_VALUE (sizetype));
+ /* Update the argument list to reflect the adjusted size. */
+ (**args)[0] = *size;
+ }
+ else
+ *cookie_size = NULL_TREE;
+ }
+
+ /* Tell our caller which function we decided to call. */
+ if (fn)
+ *fn = cand->fn;
+
+ /* Build the CALL_EXPR. */
+ return build_over_call (cand, LOOKUP_NORMAL, complain);
+}
+
+/* Build a new call to operator(). This may change ARGS. */
+
+static tree
+build_op_call_1 (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain)
+{
+ struct z_candidate *candidates = 0, *cand;
+ tree fns, convs, first_mem_arg = NULL_TREE;
+ tree type = TREE_TYPE (obj);
+ bool any_viable_p;
+ tree result = NULL_TREE;
+ void *p;
+
+ if (error_operand_p (obj))
+ return error_mark_node;
+
+ obj = prep_operand (obj);
+
+ if (TYPE_PTRMEMFUNC_P (type))
+ {
+ if (complain & tf_error)
+ /* It's no good looking for an overloaded operator() on a
+ pointer-to-member-function. */
+ error ("pointer-to-member function %E cannot be called without an object; consider using .* or ->*", obj);
+ return error_mark_node;
+ }
+
+ if (TYPE_BINFO (type))
+ {
+ fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname (CALL_EXPR), 1);
+ if (fns == error_mark_node)
+ return error_mark_node;
+ }
+ else
+ fns = NULL_TREE;
+
+ if (args != NULL && *args != NULL)
+ {
+ *args = resolve_args (*args, complain);
+ if (*args == NULL)
+ return error_mark_node;
+ }
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ if (fns)
+ {
+ first_mem_arg = obj;
+
+ add_candidates (BASELINK_FUNCTIONS (fns),
+ first_mem_arg, *args, NULL_TREE,
+ NULL_TREE, false,
+ BASELINK_BINFO (fns), BASELINK_ACCESS_BINFO (fns),
+ LOOKUP_NORMAL, &candidates, complain);
+ }
+
+ convs = lookup_conversions (type);
+
+ for (; convs; convs = TREE_CHAIN (convs))
+ {
+ tree fns = TREE_VALUE (convs);
+ tree totype = TREE_TYPE (convs);
+
+ if (TYPE_PTRFN_P (totype)
+ || TYPE_REFFN_P (totype)
+ || (TREE_CODE (totype) == REFERENCE_TYPE
+ && TYPE_PTRFN_P (TREE_TYPE (totype))))
+ for (; fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ if (DECL_NONCONVERTING_P (fn))
+ continue;
+
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ add_template_conv_candidate
+ (&candidates, fn, obj, NULL_TREE, *args, totype,
+ /*access_path=*/NULL_TREE,
+ /*conversion_path=*/NULL_TREE, complain);
+ else
+ add_conv_candidate (&candidates, fn, obj, NULL_TREE,
+ *args, /*conversion_path=*/NULL_TREE,
+ /*access_path=*/NULL_TREE, complain);
+ }
+ }
+
+ candidates = splice_viable (candidates, pedantic, &any_viable_p);
+ if (!any_viable_p)
+ {
+ if (complain & tf_error)
+ {
+ error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj),
+ build_tree_list_vec (*args));
+ print_z_candidates (location_of (TREE_TYPE (obj)), candidates);
+ }
+ result = error_mark_node;
+ }
+ else
+ {
+ cand = tourney (candidates, complain);
+ if (cand == 0)
+ {
+ if (complain & tf_error)
+ {
+ error ("call of %<(%T) (%A)%> is ambiguous",
+ TREE_TYPE (obj), build_tree_list_vec (*args));
+ print_z_candidates (location_of (TREE_TYPE (obj)), candidates);
+ }
+ result = error_mark_node;
+ }
+ /* Since cand->fn will be a type, not a function, for a conversion
+ function, we must be careful not to unconditionally look at
+ DECL_NAME here. */
+ else if (TREE_CODE (cand->fn) == FUNCTION_DECL
+ && DECL_OVERLOADED_OPERATOR_P (cand->fn) == CALL_EXPR)
+ result = build_over_call (cand, LOOKUP_NORMAL, complain);
+ else
+ {
+ obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1,
+ complain);
+ obj = convert_from_reference (obj);
+ result = cp_build_function_call_vec (obj, args, complain);
+ }
+ }
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return result;
+}
+
+/* Wrapper for above. */
+
+tree
+build_op_call (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_OVERLOAD);
+ ret = build_op_call_1 (obj, args, complain);
+ timevar_cond_stop (TV_OVERLOAD, subtime);
+ return ret;
+}
+
+/* Called by op_error to prepare format strings suitable for the error
+ function. It concatenates a prefix (controlled by MATCH), ERRMSG,
+ and a suffix (controlled by NTYPES). */
+
+static const char *
+op_error_string (const char *errmsg, int ntypes, bool match)
+{
+ const char *msg;
+
+ const char *msgp = concat (match ? G_("ambiguous overload for ")
+ : G_("no match for "), errmsg, NULL);
+
+ if (ntypes == 3)
+ msg = concat (msgp, G_(" (operand types are %qT, %qT, and %qT)"), NULL);
+ else if (ntypes == 2)
+ msg = concat (msgp, G_(" (operand types are %qT and %qT)"), NULL);
+ else
+ msg = concat (msgp, G_(" (operand type is %qT)"), NULL);
+
+ return msg;
+}
+
+static void
+op_error (location_t loc, enum tree_code code, enum tree_code code2,
+ tree arg1, tree arg2, tree arg3, bool match)
+{
+ const char *opname;
+
+ if (code == MODIFY_EXPR)
+ opname = assignment_operator_name_info[code2].name;
+ else
+ opname = operator_name_info[code].name;
+
+ switch (code)
+ {
+ case COND_EXPR:
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("ternary %<operator?:%>"),
+ 3, match),
+ TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
+ else
+ error_at (loc, op_error_string (G_("ternary %<operator?:%> "
+ "in %<%E ? %E : %E%>"), 3, match),
+ arg1, arg2, arg3,
+ TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
+ break;
+
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("%<operator%s%>"), 1, match),
+ opname, TREE_TYPE (arg1));
+ else
+ error_at (loc, op_error_string (G_("%<operator%s%> in %<%E%s%>"),
+ 1, match),
+ opname, arg1, opname, TREE_TYPE (arg1));
+ break;
+
+ case ARRAY_REF:
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("%<operator[]%>"), 2, match),
+ TREE_TYPE (arg1), TREE_TYPE (arg2));
+ else
+ error_at (loc, op_error_string (G_("%<operator[]%> in %<%E[%E]%>"),
+ 2, match),
+ arg1, arg2, TREE_TYPE (arg1), TREE_TYPE (arg2));
+ break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("%qs"), 1, match),
+ opname, TREE_TYPE (arg1));
+ else
+ error_at (loc, op_error_string (G_("%qs in %<%s %E%>"), 1, match),
+ opname, opname, arg1, TREE_TYPE (arg1));
+ break;
+
+ default:
+ if (arg2)
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("%<operator%s%>"), 2, match),
+ opname, TREE_TYPE (arg1), TREE_TYPE (arg2));
+ else
+ error_at (loc, op_error_string (G_("%<operator%s%> in %<%E %s %E%>"),
+ 2, match),
+ opname, arg1, opname, arg2,
+ TREE_TYPE (arg1), TREE_TYPE (arg2));
+ else
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("%<operator%s%>"), 1, match),
+ opname, TREE_TYPE (arg1));
+ else
+ error_at (loc, op_error_string (G_("%<operator%s%> in %<%s%E%>"),
+ 1, match),
+ opname, opname, arg1, TREE_TYPE (arg1));
+ break;
+ }
+}
+
+/* Return the implicit conversion sequence that could be used to
+ convert E1 to E2 in [expr.cond]. */
+
+static conversion *
+conditional_conversion (tree e1, tree e2, tsubst_flags_t complain)
+{
+ tree t1 = non_reference (TREE_TYPE (e1));
+ tree t2 = non_reference (TREE_TYPE (e2));
+ conversion *conv;
+ bool good_base;
+
+ /* [expr.cond]
+
+ If E2 is an lvalue: E1 can be converted to match E2 if E1 can be
+ implicitly converted (clause _conv_) to the type "lvalue reference to
+ T2", subject to the constraint that in the conversion the
+ reference must bind directly (_dcl.init.ref_) to an lvalue. */
+ if (real_lvalue_p (e2))
+ {
+ conv = implicit_conversion (build_reference_type (t2),
+ t1,
+ e1,
+ /*c_cast_p=*/false,
+ LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND
+ |LOOKUP_ONLYCONVERTING,
+ complain);
+ if (conv)
+ return conv;
+ }
+
+ /* [expr.cond]
+
+ If E1 and E2 have class type, and the underlying class types are
+ the same or one is a base class of the other: E1 can be converted
+ to match E2 if the class of T2 is the same type as, or a base
+ class of, the class of T1, and the cv-qualification of T2 is the
+ same cv-qualification as, or a greater cv-qualification than, the
+ cv-qualification of T1. If the conversion is applied, E1 is
+ changed to an rvalue of type T2 that still refers to the original
+ source class object (or the appropriate subobject thereof). */
+ if (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2)
+ && ((good_base = DERIVED_FROM_P (t2, t1)) || DERIVED_FROM_P (t1, t2)))
+ {
+ if (good_base && at_least_as_qualified_p (t2, t1))
+ {
+ conv = build_identity_conv (t1, e1);
+ if (!same_type_p (TYPE_MAIN_VARIANT (t1),
+ TYPE_MAIN_VARIANT (t2)))
+ conv = build_conv (ck_base, t2, conv);
+ else
+ conv = build_conv (ck_rvalue, t2, conv);
+ return conv;
+ }
+ else
+ return NULL;
+ }
+ else
+ /* [expr.cond]
+
+ Otherwise: E1 can be converted to match E2 if E1 can be implicitly
+ converted to the type that expression E2 would have if E2 were
+ converted to an rvalue (or the type it has, if E2 is an rvalue). */
+ return implicit_conversion (t2, t1, e1, /*c_cast_p=*/false,
+ LOOKUP_IMPLICIT, complain);
+}
+
+/* Implement [expr.cond]. ARG1, ARG2, and ARG3 are the three
+ arguments to the conditional expression. */
+
+static tree
+build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
+ tsubst_flags_t complain)
+{
+ tree arg2_type;
+ tree arg3_type;
+ tree result = NULL_TREE;
+ tree result_type = NULL_TREE;
+ bool lvalue_p = true;
+ struct z_candidate *candidates = 0;
+ struct z_candidate *cand;
+ void *p;
+ tree orig_arg2, orig_arg3;
+
+ /* As a G++ extension, the second argument to the conditional can be
+ omitted. (So that `a ? : c' is roughly equivalent to `a ? a :
+ c'.) If the second operand is omitted, make sure it is
+ calculated only once. */
+ if (!arg2)
+ {
+ if (complain & tf_error)
+ pedwarn (loc, OPT_Wpedantic,
+ "ISO C++ forbids omitting the middle term of a ?: expression");
+
+ /* Make sure that lvalues remain lvalues. See g++.oliva/ext1.C. */
+ if (real_lvalue_p (arg1))
+ arg2 = arg1 = stabilize_reference (arg1);
+ else
+ arg2 = arg1 = save_expr (arg1);
+ }
+
+ /* If something has already gone wrong, just pass that fact up the
+ tree. */
+ if (error_operand_p (arg1)
+ || error_operand_p (arg2)
+ || error_operand_p (arg3))
+ return error_mark_node;
+
+ orig_arg2 = arg2;
+ orig_arg3 = arg3;
+
+ if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (arg1)))
+ {
+ arg1 = force_rvalue (arg1, complain);
+ arg2 = force_rvalue (arg2, complain);
+ arg3 = force_rvalue (arg3, complain);
+
+ /* force_rvalue can return error_mark on valid arguments. */
+ if (error_operand_p (arg1)
+ || error_operand_p (arg2)
+ || error_operand_p (arg3))
+ return error_mark_node;
+
+ tree arg1_type = TREE_TYPE (arg1);
+ arg2_type = TREE_TYPE (arg2);
+ arg3_type = TREE_TYPE (arg3);
+
+ if (TREE_CODE (arg2_type) != VECTOR_TYPE
+ && TREE_CODE (arg3_type) != VECTOR_TYPE)
+ {
+ /* Rely on the error messages of the scalar version. */
+ tree scal = build_conditional_expr_1 (loc, integer_one_node,
+ orig_arg2, orig_arg3, complain);
+ if (scal == error_mark_node)
+ return error_mark_node;
+ tree stype = TREE_TYPE (scal);
+ tree ctype = TREE_TYPE (arg1_type);
+ if (TYPE_SIZE (stype) != TYPE_SIZE (ctype)
+ || (!INTEGRAL_TYPE_P (stype) && !SCALAR_FLOAT_TYPE_P (stype)))
+ {
+ if (complain & tf_error)
+ error_at (loc, "inferred scalar type %qT is not an integer or "
+ "floating point type of the same size as %qT", stype,
+ COMPARISON_CLASS_P (arg1)
+ ? TREE_TYPE (TREE_TYPE (TREE_OPERAND (arg1, 0)))
+ : ctype);
+ return error_mark_node;
+ }
+
+ tree vtype = build_opaque_vector_type (stype,
+ TYPE_VECTOR_SUBPARTS (arg1_type));
+ /* We could pass complain & tf_warning to unsafe_conversion_p,
+ but the warnings (like Wsign-conversion) have already been
+ given by the scalar build_conditional_expr_1. We still check
+ unsafe_conversion_p to forbid truncating long long -> float. */
+ if (unsafe_conversion_p (loc, stype, arg2, false))
+ {
+ if (complain & tf_error)
+ error_at (loc, "conversion of scalar %qT to vector %qT "
+ "involves truncation", arg2_type, vtype);
+ return error_mark_node;
+ }
+ if (unsafe_conversion_p (loc, stype, arg3, false))
+ {
+ if (complain & tf_error)
+ error_at (loc, "conversion of scalar %qT to vector %qT "
+ "involves truncation", arg3_type, vtype);
+ return error_mark_node;
+ }
+
+ arg2 = cp_convert (stype, arg2, complain);
+ arg2 = save_expr (arg2);
+ arg2 = build_vector_from_val (vtype, arg2);
+ arg2_type = vtype;
+ arg3 = cp_convert (stype, arg3, complain);
+ arg3 = save_expr (arg3);
+ arg3 = build_vector_from_val (vtype, arg3);
+ arg3_type = vtype;
+ }
+
+ if ((TREE_CODE (arg2_type) == VECTOR_TYPE)
+ != (TREE_CODE (arg3_type) == VECTOR_TYPE))
+ {
+ enum stv_conv convert_flag =
+ scalar_to_vector (loc, VEC_COND_EXPR, arg2, arg3,
+ complain & tf_error);
+
+ switch (convert_flag)
+ {
+ case stv_error:
+ return error_mark_node;
+ case stv_firstarg:
+ {
+ arg2 = save_expr (arg2);
+ arg2 = convert (TREE_TYPE (arg3_type), arg2);
+ arg2 = build_vector_from_val (arg3_type, arg2);
+ arg2_type = TREE_TYPE (arg2);
+ break;
+ }
+ case stv_secondarg:
+ {
+ arg3 = save_expr (arg3);
+ arg3 = convert (TREE_TYPE (arg2_type), arg3);
+ arg3 = build_vector_from_val (arg2_type, arg3);
+ arg3_type = TREE_TYPE (arg3);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (!same_type_p (arg2_type, arg3_type)
+ || TYPE_VECTOR_SUBPARTS (arg1_type)
+ != TYPE_VECTOR_SUBPARTS (arg2_type)
+ || TYPE_SIZE (arg1_type) != TYPE_SIZE (arg2_type))
+ {
+ if (complain & tf_error)
+ error_at (loc,
+ "incompatible vector types in conditional expression: "
+ "%qT, %qT and %qT", TREE_TYPE (arg1),
+ TREE_TYPE (orig_arg2), TREE_TYPE (orig_arg3));
+ return error_mark_node;
+ }
+
+ if (!COMPARISON_CLASS_P (arg1))
+ arg1 = cp_build_binary_op (loc, NE_EXPR, arg1,
+ build_zero_cst (arg1_type), complain);
+ return fold_build3 (VEC_COND_EXPR, arg2_type, arg1, arg2, arg3);
+ }
+
+ /* [expr.cond]
+
+ The first expression is implicitly converted to bool (clause
+ _conv_). */
+ arg1 = perform_implicit_conversion_flags (boolean_type_node, arg1, complain,
+ LOOKUP_NORMAL);
+ if (error_operand_p (arg1))
+ return error_mark_node;
+
+ /* [expr.cond]
+
+ If either the second or the third operand has type (possibly
+ cv-qualified) void, then the lvalue-to-rvalue (_conv.lval_),
+ array-to-pointer (_conv.array_), and function-to-pointer
+ (_conv.func_) standard conversions are performed on the second
+ and third operands. */
+ arg2_type = unlowered_expr_type (arg2);
+ arg3_type = unlowered_expr_type (arg3);
+ if (VOID_TYPE_P (arg2_type) || VOID_TYPE_P (arg3_type))
+ {
+ /* Do the conversions. We don't these for `void' type arguments
+ since it can't have any effect and since decay_conversion
+ does not handle that case gracefully. */
+ if (!VOID_TYPE_P (arg2_type))
+ arg2 = decay_conversion (arg2, complain);
+ if (!VOID_TYPE_P (arg3_type))
+ arg3 = decay_conversion (arg3, complain);
+ arg2_type = TREE_TYPE (arg2);
+ arg3_type = TREE_TYPE (arg3);
+
+ /* [expr.cond]
+
+ One of the following shall hold:
+
+ --The second or the third operand (but not both) is a
+ throw-expression (_except.throw_); the result is of the
+ type of the other and is an rvalue.
+
+ --Both the second and the third operands have type void; the
+ result is of type void and is an rvalue.
+
+ We must avoid calling force_rvalue for expressions of type
+ "void" because it will complain that their value is being
+ used. */
+ if (TREE_CODE (arg2) == THROW_EXPR
+ && TREE_CODE (arg3) != THROW_EXPR)
+ {
+ if (!VOID_TYPE_P (arg3_type))
+ {
+ arg3 = force_rvalue (arg3, complain);
+ if (arg3 == error_mark_node)
+ return error_mark_node;
+ }
+ arg3_type = TREE_TYPE (arg3);
+ result_type = arg3_type;
+ }
+ else if (TREE_CODE (arg2) != THROW_EXPR
+ && TREE_CODE (arg3) == THROW_EXPR)
+ {
+ if (!VOID_TYPE_P (arg2_type))
+ {
+ arg2 = force_rvalue (arg2, complain);
+ if (arg2 == error_mark_node)
+ return error_mark_node;
+ }
+ arg2_type = TREE_TYPE (arg2);
+ result_type = arg2_type;
+ }
+ else if (VOID_TYPE_P (arg2_type) && VOID_TYPE_P (arg3_type))
+ result_type = void_type_node;
+ else
+ {
+ if (complain & tf_error)
+ {
+ if (VOID_TYPE_P (arg2_type))
+ error_at (EXPR_LOC_OR_LOC (arg3, loc),
+ "second operand to the conditional operator "
+ "is of type %<void%>, but the third operand is "
+ "neither a throw-expression nor of type %<void%>");
+ else
+ error_at (EXPR_LOC_OR_LOC (arg2, loc),
+ "third operand to the conditional operator "
+ "is of type %<void%>, but the second operand is "
+ "neither a throw-expression nor of type %<void%>");
+ }
+ return error_mark_node;
+ }
+
+ lvalue_p = false;
+ goto valid_operands;
+ }
+ /* [expr.cond]
+
+ Otherwise, if the second and third operand have different types,
+ and either has (possibly cv-qualified) class type, an attempt is
+ made to convert each of those operands to the type of the other. */
+ else if (!same_type_p (arg2_type, arg3_type)
+ && (CLASS_TYPE_P (arg2_type) || CLASS_TYPE_P (arg3_type)))
+ {
+ conversion *conv2;
+ conversion *conv3;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ conv2 = conditional_conversion (arg2, arg3, complain);
+ conv3 = conditional_conversion (arg3, arg2, complain);
+
+ /* [expr.cond]
+
+ If both can be converted, or one can be converted but the
+ conversion is ambiguous, the program is ill-formed. If
+ neither can be converted, the operands are left unchanged and
+ further checking is performed as described below. If exactly
+ one conversion is possible, that conversion is applied to the
+ chosen operand and the converted operand is used in place of
+ the original operand for the remainder of this section. */
+ if ((conv2 && !conv2->bad_p
+ && conv3 && !conv3->bad_p)
+ || (conv2 && conv2->kind == ck_ambig)
+ || (conv3 && conv3->kind == ck_ambig))
+ {
+ if (complain & tf_error)
+ error_at (loc, "operands to ?: have different types %qT and %qT",
+ arg2_type, arg3_type);
+ result = error_mark_node;
+ }
+ else if (conv2 && (!conv2->bad_p || !conv3))
+ {
+ arg2 = convert_like (conv2, arg2, complain);
+ arg2 = convert_from_reference (arg2);
+ arg2_type = TREE_TYPE (arg2);
+ /* Even if CONV2 is a valid conversion, the result of the
+ conversion may be invalid. For example, if ARG3 has type
+ "volatile X", and X does not have a copy constructor
+ accepting a "volatile X&", then even if ARG2 can be
+ converted to X, the conversion will fail. */
+ if (error_operand_p (arg2))
+ result = error_mark_node;
+ }
+ else if (conv3 && (!conv3->bad_p || !conv2))
+ {
+ arg3 = convert_like (conv3, arg3, complain);
+ arg3 = convert_from_reference (arg3);
+ arg3_type = TREE_TYPE (arg3);
+ if (error_operand_p (arg3))
+ result = error_mark_node;
+ }
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ if (result)
+ return result;
+
+ /* If, after the conversion, both operands have class type,
+ treat the cv-qualification of both operands as if it were the
+ union of the cv-qualification of the operands.
+
+ The standard is not clear about what to do in this
+ circumstance. For example, if the first operand has type
+ "const X" and the second operand has a user-defined
+ conversion to "volatile X", what is the type of the second
+ operand after this step? Making it be "const X" (matching
+ the first operand) seems wrong, as that discards the
+ qualification without actually performing a copy. Leaving it
+ as "volatile X" seems wrong as that will result in the
+ conditional expression failing altogether, even though,
+ according to this step, the one operand could be converted to
+ the type of the other. */
+ if ((conv2 || conv3)
+ && CLASS_TYPE_P (arg2_type)
+ && cp_type_quals (arg2_type) != cp_type_quals (arg3_type))
+ arg2_type = arg3_type =
+ cp_build_qualified_type (arg2_type,
+ cp_type_quals (arg2_type)
+ | cp_type_quals (arg3_type));
+ }
+
+ /* [expr.cond]
+
+ If the second and third operands are glvalues of the same value
+ category and have the same type, the result is of that type and
+ value category. */
+ if (((real_lvalue_p (arg2) && real_lvalue_p (arg3))
+ || (xvalue_p (arg2) && xvalue_p (arg3)))
+ && same_type_p (arg2_type, arg3_type))
+ {
+ result_type = arg2_type;
+ arg2 = mark_lvalue_use (arg2);
+ arg3 = mark_lvalue_use (arg3);
+ goto valid_operands;
+ }
+
+ /* [expr.cond]
+
+ Otherwise, the result is an rvalue. If the second and third
+ operand do not have the same type, and either has (possibly
+ cv-qualified) class type, overload resolution is used to
+ determine the conversions (if any) to be applied to the operands
+ (_over.match.oper_, _over.built_). */
+ lvalue_p = false;
+ if (!same_type_p (arg2_type, arg3_type)
+ && (CLASS_TYPE_P (arg2_type) || CLASS_TYPE_P (arg3_type)))
+ {
+ tree args[3];
+ conversion *conv;
+ bool any_viable_p;
+
+ /* Rearrange the arguments so that add_builtin_candidate only has
+ to know about two args. In build_builtin_candidate, the
+ arguments are unscrambled. */
+ args[0] = arg2;
+ args[1] = arg3;
+ args[2] = arg1;
+ add_builtin_candidates (&candidates,
+ COND_EXPR,
+ NOP_EXPR,
+ ansi_opname (COND_EXPR),
+ args,
+ LOOKUP_NORMAL, complain);
+
+ /* [expr.cond]
+
+ If the overload resolution fails, the program is
+ ill-formed. */
+ candidates = splice_viable (candidates, pedantic, &any_viable_p);
+ if (!any_viable_p)
+ {
+ if (complain & tf_error)
+ {
+ op_error (loc, COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
+ print_z_candidates (loc, candidates);
+ }
+ return error_mark_node;
+ }
+ cand = tourney (candidates, complain);
+ if (!cand)
+ {
+ if (complain & tf_error)
+ {
+ op_error (loc, COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
+ print_z_candidates (loc, candidates);
+ }
+ return error_mark_node;
+ }
+
+ /* [expr.cond]
+
+ Otherwise, the conversions thus determined are applied, and
+ the converted operands are used in place of the original
+ operands for the remainder of this section. */
+ conv = cand->convs[0];
+ arg1 = convert_like (conv, arg1, complain);
+ conv = cand->convs[1];
+ arg2 = convert_like (conv, arg2, complain);
+ arg2_type = TREE_TYPE (arg2);
+ conv = cand->convs[2];
+ arg3 = convert_like (conv, arg3, complain);
+ arg3_type = TREE_TYPE (arg3);
+ }
+
+ /* [expr.cond]
+
+ Lvalue-to-rvalue (_conv.lval_), array-to-pointer (_conv.array_),
+ and function-to-pointer (_conv.func_) standard conversions are
+ performed on the second and third operands.
+
+ We need to force the lvalue-to-rvalue conversion here for class types,
+ so we get TARGET_EXPRs; trying to deal with a COND_EXPR of class rvalues
+ that isn't wrapped with a TARGET_EXPR plays havoc with exception
+ regions. */
+
+ arg2 = force_rvalue (arg2, complain);
+ if (!CLASS_TYPE_P (arg2_type))
+ arg2_type = TREE_TYPE (arg2);
+
+ arg3 = force_rvalue (arg3, complain);
+ if (!CLASS_TYPE_P (arg3_type))
+ arg3_type = TREE_TYPE (arg3);
+
+ if (arg2 == error_mark_node || arg3 == error_mark_node)
+ return error_mark_node;
+
+ /* [expr.cond]
+
+ After those conversions, one of the following shall hold:
+
+ --The second and third operands have the same type; the result is of
+ that type. */
+ if (same_type_p (arg2_type, arg3_type))
+ result_type = arg2_type;
+ /* [expr.cond]
+
+ --The second and third operands have arithmetic or enumeration
+ type; the usual arithmetic conversions are performed to bring
+ them to a common type, and the result is of that type. */
+ else if ((ARITHMETIC_TYPE_P (arg2_type)
+ || UNSCOPED_ENUM_P (arg2_type))
+ && (ARITHMETIC_TYPE_P (arg3_type)
+ || UNSCOPED_ENUM_P (arg3_type)))
+ {
+ /* In this case, there is always a common type. */
+ result_type = type_after_usual_arithmetic_conversions (arg2_type,
+ arg3_type);
+ if (complain & tf_warning)
+ do_warn_double_promotion (result_type, arg2_type, arg3_type,
+ "implicit conversion from %qT to %qT to "
+ "match other result of conditional",
+ loc);
+
+ if (TREE_CODE (arg2_type) == ENUMERAL_TYPE
+ && TREE_CODE (arg3_type) == ENUMERAL_TYPE)
+ {
+ if (TREE_CODE (orig_arg2) == CONST_DECL
+ && TREE_CODE (orig_arg3) == CONST_DECL
+ && DECL_CONTEXT (orig_arg2) == DECL_CONTEXT (orig_arg3))
+ /* Two enumerators from the same enumeration can have different
+ types when the enumeration is still being defined. */;
+ else if (complain & tf_warning)
+ warning_at (loc, OPT_Wenum_compare, "enumeral mismatch in "
+ "conditional expression: %qT vs %qT",
+ arg2_type, arg3_type);
+ }
+ else if (extra_warnings
+ && ((TREE_CODE (arg2_type) == ENUMERAL_TYPE
+ && !same_type_p (arg3_type, type_promotes_to (arg2_type)))
+ || (TREE_CODE (arg3_type) == ENUMERAL_TYPE
+ && !same_type_p (arg2_type,
+ type_promotes_to (arg3_type)))))
+ {
+ if (complain & tf_warning)
+ warning_at (loc, 0, "enumeral and non-enumeral type in "
+ "conditional expression");
+ }
+
+ arg2 = perform_implicit_conversion (result_type, arg2, complain);
+ arg3 = perform_implicit_conversion (result_type, arg3, complain);
+ }
+ /* [expr.cond]
+
+ --The second and third operands have pointer type, or one has
+ pointer type and the other is a null pointer constant; pointer
+ conversions (_conv.ptr_) and qualification conversions
+ (_conv.qual_) are performed to bring them to their composite
+ pointer type (_expr.rel_). The result is of the composite
+ pointer type.
+
+ --The second and third operands have pointer to member type, or
+ one has pointer to member type and the other is a null pointer
+ constant; pointer to member conversions (_conv.mem_) and
+ qualification conversions (_conv.qual_) are performed to bring
+ them to a common type, whose cv-qualification shall match the
+ cv-qualification of either the second or the third operand.
+ The result is of the common type. */
+ else if ((null_ptr_cst_p (arg2)
+ && TYPE_PTR_OR_PTRMEM_P (arg3_type))
+ || (null_ptr_cst_p (arg3)
+ && TYPE_PTR_OR_PTRMEM_P (arg2_type))
+ || (TYPE_PTR_P (arg2_type) && TYPE_PTR_P (arg3_type))
+ || (TYPE_PTRDATAMEM_P (arg2_type) && TYPE_PTRDATAMEM_P (arg3_type))
+ || (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type)))
+ {
+ result_type = composite_pointer_type (arg2_type, arg3_type, arg2,
+ arg3, CPO_CONDITIONAL_EXPR,
+ complain);
+ if (result_type == error_mark_node)
+ return error_mark_node;
+ arg2 = perform_implicit_conversion (result_type, arg2, complain);
+ arg3 = perform_implicit_conversion (result_type, arg3, complain);
+ }
+
+ if (!result_type)
+ {
+ if (complain & tf_error)
+ error_at (loc, "operands to ?: have different types %qT and %qT",
+ arg2_type, arg3_type);
+ return error_mark_node;
+ }
+
+ if (arg2 == error_mark_node || arg3 == error_mark_node)
+ return error_mark_node;
+
+ valid_operands:
+ result = build3 (COND_EXPR, result_type, arg1, arg2, arg3);
+ if (!cp_unevaluated_operand)
+ /* Avoid folding within decltype (c++/42013) and noexcept. */
+ result = fold_if_not_in_template (result);
+
+ /* We can't use result_type below, as fold might have returned a
+ throw_expr. */
+
+ if (!lvalue_p)
+ {
+ /* Expand both sides into the same slot, hopefully the target of
+ the ?: expression. We used to check for TARGET_EXPRs here,
+ but now we sometimes wrap them in NOP_EXPRs so the test would
+ fail. */
+ if (CLASS_TYPE_P (TREE_TYPE (result)))
+ result = get_target_expr_sfinae (result, complain);
+ /* If this expression is an rvalue, but might be mistaken for an
+ lvalue, we must add a NON_LVALUE_EXPR. */
+ result = rvalue (result);
+ }
+ else
+ result = force_paren_expr (result);
+
+ return result;
+}
+
+/* Wrapper for above. */
+
+tree
+build_conditional_expr (location_t loc, tree arg1, tree arg2, tree arg3,
+ tsubst_flags_t complain)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_OVERLOAD);
+ ret = build_conditional_expr_1 (loc, arg1, arg2, arg3, complain);
+ timevar_cond_stop (TV_OVERLOAD, subtime);
+ return ret;
+}
+
+/* OPERAND is an operand to an expression. Perform necessary steps
+ required before using it. If OPERAND is NULL_TREE, NULL_TREE is
+ returned. */
+
+static tree
+prep_operand (tree operand)
+{
+ if (operand)
+ {
+ if (CLASS_TYPE_P (TREE_TYPE (operand))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (operand)))
+ /* Make sure the template type is instantiated now. */
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (operand)));
+ }
+
+ return operand;
+}
+
+/* Add each of the viable functions in FNS (a FUNCTION_DECL or
+ OVERLOAD) to the CANDIDATES, returning an updated list of
+ CANDIDATES. The ARGS are the arguments provided to the call;
+ if FIRST_ARG is non-null it is the implicit object argument,
+ otherwise the first element of ARGS is used if needed. The
+ EXPLICIT_TARGS are explicit template arguments provided.
+ TEMPLATE_ONLY is true if only template functions should be
+ considered. CONVERSION_PATH, ACCESS_PATH, and FLAGS are as for
+ add_function_candidate. */
+
+static void
+add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
+ tree return_type,
+ tree explicit_targs, bool template_only,
+ tree conversion_path, tree access_path,
+ int flags,
+ struct z_candidate **candidates,
+ tsubst_flags_t complain)
+{
+ tree ctype;
+ const vec<tree, va_gc> *non_static_args;
+ bool check_list_ctor;
+ bool check_converting;
+ unification_kind_t strict;
+ tree fn;
+
+ if (!fns)
+ return;
+
+ /* Precalculate special handling of constructors and conversion ops. */
+ fn = OVL_CURRENT (fns);
+ if (DECL_CONV_FN_P (fn))
+ {
+ check_list_ctor = false;
+ check_converting = !!(flags & LOOKUP_ONLYCONVERTING);
+ if (flags & LOOKUP_NO_CONVERSION)
+ /* We're doing return_type(x). */
+ strict = DEDUCE_CONV;
+ else
+ /* We're doing x.operator return_type(). */
+ strict = DEDUCE_EXACT;
+ /* [over.match.funcs] For conversion functions, the function
+ is considered to be a member of the class of the implicit
+ object argument for the purpose of defining the type of
+ the implicit object parameter. */
+ ctype = TYPE_MAIN_VARIANT (TREE_TYPE (first_arg));
+ }
+ else
+ {
+ if (DECL_CONSTRUCTOR_P (fn))
+ {
+ check_list_ctor = !!(flags & LOOKUP_LIST_ONLY);
+ /* For list-initialization we consider explicit constructors
+ and complain if one is chosen. */
+ check_converting
+ = ((flags & (LOOKUP_ONLYCONVERTING|LOOKUP_LIST_INIT_CTOR))
+ == LOOKUP_ONLYCONVERTING);
+ }
+ else
+ {
+ check_list_ctor = false;
+ check_converting = false;
+ }
+ strict = DEDUCE_CALL;
+ ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
+ }
+
+ if (first_arg)
+ non_static_args = args;
+ else
+ /* Delay creating the implicit this parameter until it is needed. */
+ non_static_args = NULL;
+
+ for (; fns; fns = OVL_NEXT (fns))
+ {
+ tree fn_first_arg;
+ const vec<tree, va_gc> *fn_args;
+
+ fn = OVL_CURRENT (fns);
+
+ if (check_converting && DECL_NONCONVERTING_P (fn))
+ continue;
+ if (check_list_ctor && !is_list_ctor (fn))
+ continue;
+
+ /* Figure out which set of arguments to use. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+ {
+ /* If this function is a non-static member and we didn't get an
+ implicit object argument, move it out of args. */
+ if (first_arg == NULL_TREE)
+ {
+ unsigned int ix;
+ tree arg;
+ vec<tree, va_gc> *tempvec;
+ vec_alloc (tempvec, args->length () - 1);
+ for (ix = 1; args->iterate (ix, &arg); ++ix)
+ tempvec->quick_push (arg);
+ non_static_args = tempvec;
+ first_arg = (*args)[0];
+ }
+
+ fn_first_arg = first_arg;
+ fn_args = non_static_args;
+ }
+ else
+ {
+ /* Otherwise, just use the list of arguments provided. */
+ fn_first_arg = NULL_TREE;
+ fn_args = args;
+ }
+
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ add_template_candidate (candidates,
+ fn,
+ ctype,
+ explicit_targs,
+ fn_first_arg,
+ fn_args,
+ return_type,
+ access_path,
+ conversion_path,
+ flags,
+ strict,
+ complain);
+ else if (!template_only)
+ add_function_candidate (candidates,
+ fn,
+ ctype,
+ fn_first_arg,
+ fn_args,
+ access_path,
+ conversion_path,
+ flags,
+ complain);
+ }
+}
+
+static tree
+build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
+ tree arg2, tree arg3, tree *overload, tsubst_flags_t complain)
+{
+ struct z_candidate *candidates = 0, *cand;
+ vec<tree, va_gc> *arglist;
+ tree fnname;
+ tree args[3];
+ tree result = NULL_TREE;
+ bool result_valid_p = false;
+ enum tree_code code2 = NOP_EXPR;
+ enum tree_code code_orig_arg1 = ERROR_MARK;
+ enum tree_code code_orig_arg2 = ERROR_MARK;
+ conversion *conv;
+ void *p;
+ bool strict_p;
+ bool any_viable_p;
+
+ if (error_operand_p (arg1)
+ || error_operand_p (arg2)
+ || error_operand_p (arg3))
+ return error_mark_node;
+
+ if (code == MODIFY_EXPR)
+ {
+ code2 = TREE_CODE (arg3);
+ arg3 = NULL_TREE;
+ fnname = ansi_assopname (code2);
+ }
+ else
+ fnname = ansi_opname (code);
+
+ arg1 = prep_operand (arg1);
+
+ switch (code)
+ {
+ case NEW_EXPR:
+ case VEC_NEW_EXPR:
+ case VEC_DELETE_EXPR:
+ case DELETE_EXPR:
+ /* Use build_op_new_call and build_op_delete_call instead. */
+ gcc_unreachable ();
+
+ case CALL_EXPR:
+ /* Use build_op_call instead. */
+ gcc_unreachable ();
+
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ /* These are saved for the sake of warn_logical_operator. */
+ code_orig_arg1 = TREE_CODE (arg1);
+ code_orig_arg2 = TREE_CODE (arg2);
+
+ default:
+ break;
+ }
+
+ arg2 = prep_operand (arg2);
+ arg3 = prep_operand (arg3);
+
+ if (code == COND_EXPR)
+ /* Use build_conditional_expr instead. */
+ gcc_unreachable ();
+ else if (! OVERLOAD_TYPE_P (TREE_TYPE (arg1))
+ && (! arg2 || ! OVERLOAD_TYPE_P (TREE_TYPE (arg2))))
+ goto builtin;
+
+ if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
+ arg2 = integer_zero_node;
+
+ vec_alloc (arglist, 3);
+ arglist->quick_push (arg1);
+ if (arg2 != NULL_TREE)
+ arglist->quick_push (arg2);
+ if (arg3 != NULL_TREE)
+ arglist->quick_push (arg3);
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ /* Add namespace-scope operators to the list of functions to
+ consider. */
+ add_candidates (lookup_function_nonclass (fnname, arglist, /*block_p=*/true),
+ NULL_TREE, arglist, NULL_TREE,
+ NULL_TREE, false, NULL_TREE, NULL_TREE,
+ flags, &candidates, complain);
+
+ args[0] = arg1;
+ args[1] = arg2;
+ args[2] = NULL_TREE;
+
+ /* Add class-member operators to the candidate set. */
+ if (CLASS_TYPE_P (TREE_TYPE (arg1)))
+ {
+ tree fns;
+
+ fns = lookup_fnfields (TREE_TYPE (arg1), fnname, 1);
+ if (fns == error_mark_node)
+ {
+ result = error_mark_node;
+ goto user_defined_result_ready;
+ }
+ if (fns)
+ add_candidates (BASELINK_FUNCTIONS (fns),
+ NULL_TREE, arglist, NULL_TREE,
+ NULL_TREE, false,
+ BASELINK_BINFO (fns),
+ BASELINK_ACCESS_BINFO (fns),
+ flags, &candidates, complain);
+ }
+ /* Per 13.3.1.2/3, 2nd bullet, if no operand has a class type, then
+ only non-member functions that have type T1 or reference to
+ cv-qualified-opt T1 for the first argument, if the first argument
+ has an enumeration type, or T2 or reference to cv-qualified-opt
+ T2 for the second argument, if the the second argument has an
+ enumeration type. Filter out those that don't match. */
+ else if (! arg2 || ! CLASS_TYPE_P (TREE_TYPE (arg2)))
+ {
+ struct z_candidate **candp, **next;
+
+ for (candp = &candidates; *candp; candp = next)
+ {
+ tree parmlist, parmtype;
+ int i, nargs = (arg2 ? 2 : 1);
+
+ cand = *candp;
+ next = &cand->next;
+
+ parmlist = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
+
+ for (i = 0; i < nargs; ++i)
+ {
+ parmtype = TREE_VALUE (parmlist);
+
+ if (TREE_CODE (parmtype) == REFERENCE_TYPE)
+ parmtype = TREE_TYPE (parmtype);
+ if (TREE_CODE (TREE_TYPE (args[i])) == ENUMERAL_TYPE
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (args[i]), parmtype)))
+ break;
+
+ parmlist = TREE_CHAIN (parmlist);
+ }
+
+ /* No argument has an appropriate type, so remove this
+ candidate function from the list. */
+ if (i == nargs)
+ {
+ *candp = cand->next;
+ next = candp;
+ }
+ }
+ }
+
+ add_builtin_candidates (&candidates, code, code2, fnname, args,
+ flags, complain);
+
+ switch (code)
+ {
+ case COMPOUND_EXPR:
+ case ADDR_EXPR:
+ /* For these, the built-in candidates set is empty
+ [over.match.oper]/3. We don't want non-strict matches
+ because exact matches are always possible with built-in
+ operators. The built-in candidate set for COMPONENT_REF
+ would be empty too, but since there are no such built-in
+ operators, we accept non-strict matches for them. */
+ strict_p = true;
+ break;
+
+ default:
+ strict_p = pedantic;
+ break;
+ }
+
+ candidates = splice_viable (candidates, strict_p, &any_viable_p);
+ if (!any_viable_p)
+ {
+ switch (code)
+ {
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ /* Don't try anything fancy if we're not allowed to produce
+ errors. */
+ if (!(complain & tf_error))
+ return error_mark_node;
+
+ /* Look for an `operator++ (int)'. Pre-1985 C++ didn't
+ distinguish between prefix and postfix ++ and
+ operator++() was used for both, so we allow this with
+ -fpermissive. */
+ else
+ {
+ const char *msg = (flag_permissive)
+ ? G_("no %<%D(int)%> declared for postfix %qs,"
+ " trying prefix operator instead")
+ : G_("no %<%D(int)%> declared for postfix %qs");
+ permerror (loc, msg, fnname, operator_name_info[code].name);
+ }
+
+ if (!flag_permissive)
+ return error_mark_node;
+
+ if (code == POSTINCREMENT_EXPR)
+ code = PREINCREMENT_EXPR;
+ else
+ code = PREDECREMENT_EXPR;
+ result = build_new_op_1 (loc, code, flags, arg1, NULL_TREE,
+ NULL_TREE, overload, complain);
+ break;
+
+ /* The caller will deal with these. */
+ case ADDR_EXPR:
+ case COMPOUND_EXPR:
+ case COMPONENT_REF:
+ result = NULL_TREE;
+ result_valid_p = true;
+ break;
+
+ default:
+ if (complain & tf_error)
+ {
+ /* If one of the arguments of the operator represents
+ an invalid use of member function pointer, try to report
+ a meaningful error ... */
+ if (invalid_nonstatic_memfn_p (arg1, tf_error)
+ || invalid_nonstatic_memfn_p (arg2, tf_error)
+ || invalid_nonstatic_memfn_p (arg3, tf_error))
+ /* We displayed the error message. */;
+ else
+ {
+ /* ... Otherwise, report the more generic
+ "no matching operator found" error */
+ op_error (loc, code, code2, arg1, arg2, arg3, FALSE);
+ print_z_candidates (loc, candidates);
+ }
+ }
+ result = error_mark_node;
+ break;
+ }
+ }
+ else
+ {
+ cand = tourney (candidates, complain);
+ if (cand == 0)
+ {
+ if (complain & tf_error)
+ {
+ op_error (loc, code, code2, arg1, arg2, arg3, TRUE);
+ print_z_candidates (loc, candidates);
+ }
+ result = error_mark_node;
+ }
+ else if (TREE_CODE (cand->fn) == FUNCTION_DECL)
+ {
+ if (overload)
+ *overload = cand->fn;
+
+ if (resolve_args (arglist, complain) == NULL)
+ result = error_mark_node;
+ else
+ result = build_over_call (cand, LOOKUP_NORMAL, complain);
+ }
+ else
+ {
+ /* Give any warnings we noticed during overload resolution. */
+ if (cand->warnings && (complain & tf_warning))
+ {
+ struct candidate_warning *w;
+ for (w = cand->warnings; w; w = w->next)
+ joust (cand, w->loser, 1, complain);
+ }
+
+ /* Check for comparison of different enum types. */
+ switch (code)
+ {
+ case GT_EXPR:
+ case LT_EXPR:
+ case GE_EXPR:
+ case LE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE
+ && TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE
+ && (TYPE_MAIN_VARIANT (TREE_TYPE (arg1))
+ != TYPE_MAIN_VARIANT (TREE_TYPE (arg2)))
+ && (complain & tf_warning))
+ {
+ warning (OPT_Wenum_compare,
+ "comparison between %q#T and %q#T",
+ TREE_TYPE (arg1), TREE_TYPE (arg2));
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* We need to strip any leading REF_BIND so that bitfields
+ don't cause errors. This should not remove any important
+ conversions, because builtins don't apply to class
+ objects directly. */
+ conv = cand->convs[0];
+ if (conv->kind == ck_ref_bind)
+ conv = next_conversion (conv);
+ arg1 = convert_like (conv, arg1, complain);
+
+ if (arg2)
+ {
+ conv = cand->convs[1];
+ if (conv->kind == ck_ref_bind)
+ conv = next_conversion (conv);
+ else
+ arg2 = decay_conversion (arg2, complain);
+
+ /* We need to call warn_logical_operator before
+ converting arg2 to a boolean_type, but after
+ decaying an enumerator to its value. */
+ if (complain & tf_warning)
+ warn_logical_operator (loc, code, boolean_type_node,
+ code_orig_arg1, arg1,
+ code_orig_arg2, arg2);
+
+ arg2 = convert_like (conv, arg2, complain);
+ }
+ if (arg3)
+ {
+ conv = cand->convs[2];
+ if (conv->kind == ck_ref_bind)
+ conv = next_conversion (conv);
+ arg3 = convert_like (conv, arg3, complain);
+ }
+
+ }
+ }
+
+ user_defined_result_ready:
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ if (result || result_valid_p)
+ return result;
+
+ builtin:
+ switch (code)
+ {
+ case MODIFY_EXPR:
+ return cp_build_modify_expr (arg1, code2, arg2, complain);
+
+ case INDIRECT_REF:
+ return cp_build_indirect_ref (arg1, RO_UNARY_STAR, complain);
+
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ warn_logical_operator (loc, code, boolean_type_node,
+ code_orig_arg1, arg1, code_orig_arg2, arg2);
+ /* Fall through. */
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case GT_EXPR:
+ case LT_EXPR:
+ case GE_EXPR:
+ case LE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case MAX_EXPR:
+ case MIN_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case TRUNC_MOD_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ return cp_build_binary_op (loc, code, arg1, arg2, complain);
+
+ case UNARY_PLUS_EXPR:
+ case NEGATE_EXPR:
+ case BIT_NOT_EXPR:
+ case TRUTH_NOT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case ABS_EXPR:
+ return cp_build_unary_op (code, arg1, candidates != 0, complain);
+
+ case ARRAY_REF:
+ return cp_build_array_ref (input_location, arg1, arg2, complain);
+
+ case MEMBER_REF:
+ return build_m_component_ref (cp_build_indirect_ref (arg1, RO_ARROW_STAR,
+ complain),
+ arg2, complain);
+
+ /* The caller will deal with these. */
+ case ADDR_EXPR:
+ case COMPONENT_REF:
+ case COMPOUND_EXPR:
+ return NULL_TREE;
+
+ default:
+ gcc_unreachable ();
+ }
+ return NULL_TREE;
+}
+
+/* Wrapper for above. */
+
+tree
+build_new_op (location_t loc, enum tree_code code, int flags,
+ tree arg1, tree arg2, tree arg3,
+ tree *overload, tsubst_flags_t complain)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_OVERLOAD);
+ ret = build_new_op_1 (loc, code, flags, arg1, arg2, arg3,
+ overload, complain);
+ timevar_cond_stop (TV_OVERLOAD, subtime);
+ return ret;
+}
+
+/* Returns true iff T, an element of an OVERLOAD chain, is a usual
+ deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]). */
+
+static bool
+non_placement_deallocation_fn_p (tree t)
+{
+ /* A template instance is never a usual deallocation function,
+ regardless of its signature. */
+ if (TREE_CODE (t) == TEMPLATE_DECL
+ || primary_template_instantiation_p (t))
+ return false;
+
+ /* If a class T has a member deallocation function named operator delete
+ with exactly one parameter, then that function is a usual
+ (non-placement) deallocation function. If class T does not declare
+ such an operator delete but does declare a member deallocation
+ function named operator delete with exactly two parameters, the second
+ of which has type std::size_t (18.2), then this function is a usual
+ deallocation function. */
+ t = FUNCTION_ARG_CHAIN (t);
+ if (t == void_list_node
+ || (t && same_type_p (TREE_VALUE (t), size_type_node)
+ && TREE_CHAIN (t) == void_list_node))
+ return true;
+ return false;
+}
+
+/* Build a call to operator delete. This has to be handled very specially,
+ because the restrictions on what signatures match are different from all
+ other call instances. For a normal delete, only a delete taking (void *)
+ or (void *, size_t) is accepted. For a placement delete, only an exact
+ match with the placement new is accepted.
+
+ CODE is either DELETE_EXPR or VEC_DELETE_EXPR.
+ ADDR is the pointer to be deleted.
+ SIZE is the size of the memory block to be deleted.
+ GLOBAL_P is true if the delete-expression should not consider
+ class-specific delete operators.
+ PLACEMENT is the corresponding placement new call, or NULL_TREE.
+
+ If this call to "operator delete" is being generated as part to
+ deallocate memory allocated via a new-expression (as per [expr.new]
+ which requires that if the initialization throws an exception then
+ we call a deallocation function), then ALLOC_FN is the allocation
+ function. */
+
+tree
+build_op_delete_call (enum tree_code code, tree addr, tree size,
+ bool global_p, tree placement,
+ tree alloc_fn, tsubst_flags_t complain)
+{
+ tree fn = NULL_TREE;
+ tree fns, fnname, type, t;
+
+ if (addr == error_mark_node)
+ return error_mark_node;
+
+ type = strip_array_types (TREE_TYPE (TREE_TYPE (addr)));
+
+ fnname = ansi_opname (code);
+
+ if (CLASS_TYPE_P (type)
+ && COMPLETE_TYPE_P (complete_type (type))
+ && !global_p)
+ /* In [class.free]
+
+ If the result of the lookup is ambiguous or inaccessible, or if
+ the lookup selects a placement deallocation function, the
+ program is ill-formed.
+
+ Therefore, we ask lookup_fnfields to complain about ambiguity. */
+ {
+ fns = lookup_fnfields (TYPE_BINFO (type), fnname, 1);
+ if (fns == error_mark_node)
+ return error_mark_node;
+ }
+ else
+ fns = NULL_TREE;
+
+ if (fns == NULL_TREE)
+ fns = lookup_name_nonclass (fnname);
+
+ /* Strip const and volatile from addr. */
+ addr = cp_convert (ptr_type_node, addr, complain);
+
+ if (placement)
+ {
+ /* "A declaration of a placement deallocation function matches the
+ declaration of a placement allocation function if it has the same
+ number of parameters and, after parameter transformations (8.3.5),
+ all parameter types except the first are identical."
+
+ So we build up the function type we want and ask instantiate_type
+ to get it for us. */
+ t = FUNCTION_ARG_CHAIN (alloc_fn);
+ t = tree_cons (NULL_TREE, ptr_type_node, t);
+ t = build_function_type (void_type_node, t);
+
+ fn = instantiate_type (t, fns, tf_none);
+ if (fn == error_mark_node)
+ return NULL_TREE;
+
+ if (BASELINK_P (fn))
+ fn = BASELINK_FUNCTIONS (fn);
+
+ /* "If the lookup finds the two-parameter form of a usual deallocation
+ function (3.7.4.2) and that function, considered as a placement
+ deallocation function, would have been selected as a match for the
+ allocation function, the program is ill-formed." */
+ if (non_placement_deallocation_fn_p (fn))
+ {
+ /* But if the class has an operator delete (void *), then that is
+ the usual deallocation function, so we shouldn't complain
+ about using the operator delete (void *, size_t). */
+ for (t = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
+ t; t = OVL_NEXT (t))
+ {
+ tree elt = OVL_CURRENT (t);
+ if (non_placement_deallocation_fn_p (elt)
+ && FUNCTION_ARG_CHAIN (elt) == void_list_node)
+ goto ok;
+ }
+ if (complain & tf_error)
+ {
+ permerror (0, "non-placement deallocation function %q+D", fn);
+ permerror (input_location, "selected for placement delete");
+ }
+ else
+ return error_mark_node;
+ ok:;
+ }
+ }
+ else
+ /* "Any non-placement deallocation function matches a non-placement
+ allocation function. If the lookup finds a single matching
+ deallocation function, that function will be called; otherwise, no
+ deallocation function will be called." */
+ for (t = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
+ t; t = OVL_NEXT (t))
+ {
+ tree elt = OVL_CURRENT (t);
+ if (non_placement_deallocation_fn_p (elt))
+ {
+ fn = elt;
+ /* "If a class T has a member deallocation function named
+ operator delete with exactly one parameter, then that
+ function is a usual (non-placement) deallocation
+ function. If class T does not declare such an operator
+ delete but does declare a member deallocation function named
+ operator delete with exactly two parameters, the second of
+ which has type std::size_t (18.2), then this function is a
+ usual deallocation function."
+
+ So (void*) beats (void*, size_t). */
+ if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
+ break;
+ }
+ }
+
+ /* If we have a matching function, call it. */
+ if (fn)
+ {
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
+
+ /* If the FN is a member function, make sure that it is
+ accessible. */
+ if (BASELINK_P (fns))
+ perform_or_defer_access_check (BASELINK_BINFO (fns), fn, fn,
+ complain);
+
+ /* Core issue 901: It's ok to new a type with deleted delete. */
+ if (DECL_DELETED_FN (fn) && alloc_fn)
+ return NULL_TREE;
+
+ if (placement)
+ {
+ /* The placement args might not be suitable for overload
+ resolution at this point, so build the call directly. */
+ int nargs = call_expr_nargs (placement);
+ tree *argarray = XALLOCAVEC (tree, nargs);
+ int i;
+ argarray[0] = addr;
+ for (i = 1; i < nargs; i++)
+ argarray[i] = CALL_EXPR_ARG (placement, i);
+ mark_used (fn);
+ return build_cxx_call (fn, nargs, argarray, complain);
+ }
+ else
+ {
+ tree ret;
+ vec<tree, va_gc> *args = make_tree_vector ();
+ args->quick_push (addr);
+ if (FUNCTION_ARG_CHAIN (fn) != void_list_node)
+ args->quick_push (size);
+ ret = cp_build_function_call_vec (fn, &args, complain);
+ release_tree_vector (args);
+ return ret;
+ }
+ }
+
+ /* [expr.new]
+
+ If no unambiguous matching deallocation function can be found,
+ propagating the exception does not cause the object's memory to
+ be freed. */
+ if (alloc_fn)
+ {
+ if ((complain & tf_warning)
+ && !placement)
+ warning (0, "no corresponding deallocation function for %qD",
+ alloc_fn);
+ return NULL_TREE;
+ }
+
+ if (complain & tf_error)
+ error ("no suitable %<operator %s%> for %qT",
+ operator_name_info[(int)code].name, type);
+ return error_mark_node;
+}
+
+/* If the current scope isn't allowed to access DECL along
+ BASETYPE_PATH, give an error. The most derived class in
+ BASETYPE_PATH is the one used to qualify DECL. DIAG_DECL is
+ the declaration to use in the error diagnostic. */
+
+bool
+enforce_access (tree basetype_path, tree decl, tree diag_decl,
+ tsubst_flags_t complain)
+{
+ gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
+
+ if (!accessible_p (basetype_path, decl, true))
+ {
+ if (complain & tf_error)
+ {
+ if (TREE_PRIVATE (decl))
+ error ("%q+#D is private", diag_decl);
+ else if (TREE_PROTECTED (decl))
+ error ("%q+#D is protected", diag_decl);
+ else
+ error ("%q+#D is inaccessible", diag_decl);
+ error ("within this context");
+ }
+ return false;
+ }
+
+ return true;
+}
+
+/* Initialize a temporary of type TYPE with EXPR. The FLAGS are a
+ bitwise or of LOOKUP_* values. If any errors are warnings are
+ generated, set *DIAGNOSTIC_FN to "error" or "warning",
+ respectively. If no diagnostics are generated, set *DIAGNOSTIC_FN
+ to NULL. */
+
+static tree
+build_temp (tree expr, tree type, int flags,
+ diagnostic_t *diagnostic_kind, tsubst_flags_t complain)
+{
+ int savew, savee;
+ vec<tree, va_gc> *args;
+
+ savew = warningcount + werrorcount, savee = errorcount;
+ args = make_tree_vector_single (expr);
+ expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ &args, type, flags, complain);
+ release_tree_vector (args);
+ if (warningcount + werrorcount > savew)
+ *diagnostic_kind = DK_WARNING;
+ else if (errorcount > savee)
+ *diagnostic_kind = DK_ERROR;
+ else
+ *diagnostic_kind = DK_UNSPECIFIED;
+ return expr;
+}
+
+/* Perform warnings about peculiar, but valid, conversions from/to NULL.
+ EXPR is implicitly converted to type TOTYPE.
+ FN and ARGNUM are used for diagnostics. */
+
+static void
+conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
+{
+ /* Issue warnings about peculiar, but valid, uses of NULL. */
+ if (expr == null_node && TREE_CODE (totype) != BOOLEAN_TYPE
+ && ARITHMETIC_TYPE_P (totype))
+ {
+ source_location loc =
+ expansion_point_location_if_in_system_header (input_location);
+
+ if (fn)
+ warning_at (loc, OPT_Wconversion_null,
+ "passing NULL to non-pointer argument %P of %qD",
+ argnum, fn);
+ else
+ warning_at (loc, OPT_Wconversion_null,
+ "converting to non-pointer type %qT from NULL", totype);
+ }
+
+ /* Issue warnings if "false" is converted to a NULL pointer */
+ else if (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE
+ && TYPE_PTR_P (totype))
+ {
+ if (fn)
+ warning_at (input_location, OPT_Wconversion_null,
+ "converting %<false%> to pointer type for argument %P "
+ "of %qD", argnum, fn);
+ else
+ warning_at (input_location, OPT_Wconversion_null,
+ "converting %<false%> to pointer type %qT", totype);
+ }
+}
+
+/* Perform the conversions in CONVS on the expression EXPR. FN and
+ ARGNUM are used for diagnostics. ARGNUM is zero based, -1
+ indicates the `this' argument of a method. INNER is nonzero when
+ being called to continue a conversion chain. It is negative when a
+ reference binding will be applied, positive otherwise. If
+ ISSUE_CONVERSION_WARNINGS is true, warnings about suspicious
+ conversions will be emitted if appropriate. If C_CAST_P is true,
+ this conversion is coming from a C-style cast; in that case,
+ conversions to inaccessible bases are permitted. */
+
+static tree
+convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
+ int inner, bool issue_conversion_warnings,
+ bool c_cast_p, tsubst_flags_t complain)
+{
+ tree totype = convs->type;
+ diagnostic_t diag_kind;
+ int flags;
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+
+ if (convs->bad_p && !(complain & tf_error))
+ return error_mark_node;
+
+ if (convs->bad_p
+ && convs->kind != ck_user
+ && convs->kind != ck_list
+ && convs->kind != ck_ambig
+ && (convs->kind != ck_ref_bind
+ || (convs->user_conv_p && next_conversion (convs)->bad_p))
+ && (convs->kind != ck_rvalue
+ || SCALAR_TYPE_P (totype))
+ && convs->kind != ck_base)
+ {
+ bool complained = false;
+ conversion *t = convs;
+
+ /* Give a helpful error if this is bad because of excess braces. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && SCALAR_TYPE_P (totype)
+ && CONSTRUCTOR_NELTS (expr) > 0
+ && BRACE_ENCLOSED_INITIALIZER_P (CONSTRUCTOR_ELT (expr, 0)->value))
+ {
+ complained = permerror (loc, "too many braces around initializer "
+ "for %qT", totype);
+ while (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && CONSTRUCTOR_NELTS (expr) == 1)
+ expr = CONSTRUCTOR_ELT (expr, 0)->value;
+ }
+
+ for (; t ; t = next_conversion (t))
+ {
+ if (t->kind == ck_user && t->cand->reason)
+ {
+ permerror (loc, "invalid user-defined conversion "
+ "from %qT to %qT", TREE_TYPE (expr), totype);
+ print_z_candidate (loc, "candidate is:", t->cand);
+ expr = convert_like_real (t, expr, fn, argnum, 1,
+ /*issue_conversion_warnings=*/false,
+ /*c_cast_p=*/false,
+ complain);
+ if (convs->kind == ck_ref_bind)
+ return convert_to_reference (totype, expr, CONV_IMPLICIT,
+ LOOKUP_NORMAL, NULL_TREE,
+ complain);
+ else
+ return cp_convert (totype, expr, complain);
+ }
+ else if (t->kind == ck_user || !t->bad_p)
+ {
+ expr = convert_like_real (t, expr, fn, argnum, 1,
+ /*issue_conversion_warnings=*/false,
+ /*c_cast_p=*/false,
+ complain);
+ break;
+ }
+ else if (t->kind == ck_ambig)
+ return convert_like_real (t, expr, fn, argnum, 1,
+ /*issue_conversion_warnings=*/false,
+ /*c_cast_p=*/false,
+ complain);
+ else if (t->kind == ck_identity)
+ break;
+ }
+ if (!complained)
+ complained = permerror (loc, "invalid conversion from %qT to %qT",
+ TREE_TYPE (expr), totype);
+ if (complained && fn)
+ inform (DECL_SOURCE_LOCATION (fn),
+ "initializing argument %P of %qD", argnum, fn);
+
+ return cp_convert (totype, expr, complain);
+ }
+
+ if (issue_conversion_warnings && (complain & tf_warning))
+ conversion_null_warnings (totype, expr, fn, argnum);
+
+ switch (convs->kind)
+ {
+ case ck_user:
+ {
+ struct z_candidate *cand = convs->cand;
+ tree convfn = cand->fn;
+ unsigned i;
+
+ /* When converting from an init list we consider explicit
+ constructors, but actually trying to call one is an error. */
+ if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
+ /* Unless this is for direct-list-initialization. */
+ && !(BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && CONSTRUCTOR_IS_DIRECT_INIT (expr)))
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+ error ("converting to %qT from initializer list would use "
+ "explicit constructor %qD", totype, convfn);
+ }
+
+ /* If we're initializing from {}, it's value-initialization. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && CONSTRUCTOR_NELTS (expr) == 0
+ && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
+ {
+ bool direct = CONSTRUCTOR_IS_DIRECT_INIT (expr);
+ expr = build_value_init (totype, complain);
+ expr = get_target_expr_sfinae (expr, complain);
+ if (expr != error_mark_node)
+ {
+ TARGET_EXPR_LIST_INIT_P (expr) = true;
+ TARGET_EXPR_DIRECT_INIT_P (expr) = direct;
+ }
+ return expr;
+ }
+
+ expr = mark_rvalue_use (expr);
+
+ /* Set user_conv_p on the argument conversions, so rvalue/base
+ handling knows not to allow any more UDCs. */
+ for (i = 0; i < cand->num_convs; ++i)
+ cand->convs[i]->user_conv_p = true;
+
+ expr = build_over_call (cand, LOOKUP_NORMAL, complain);
+
+ /* If this is a constructor or a function returning an aggr type,
+ we need to build up a TARGET_EXPR. */
+ if (DECL_CONSTRUCTOR_P (convfn))
+ {
+ expr = build_cplus_new (totype, expr, complain);
+
+ /* Remember that this was list-initialization. */
+ if (convs->check_narrowing && expr != error_mark_node)
+ TARGET_EXPR_LIST_INIT_P (expr) = true;
+ }
+
+ return expr;
+ }
+ case ck_identity:
+ expr = mark_rvalue_use (expr);
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ int nelts = CONSTRUCTOR_NELTS (expr);
+ if (nelts == 0)
+ expr = build_value_init (totype, complain);
+ else if (nelts == 1)
+ expr = CONSTRUCTOR_ELT (expr, 0)->value;
+ else
+ gcc_unreachable ();
+ }
+
+ if (type_unknown_p (expr))
+ expr = instantiate_type (totype, expr, complain);
+ /* Convert a constant to its underlying value, unless we are
+ about to bind it to a reference, in which case we need to
+ leave it as an lvalue. */
+ if (inner >= 0)
+ {
+ expr = decl_constant_value_safe (expr);
+ if (expr == null_node && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (totype))
+ /* If __null has been converted to an integer type, we do not
+ want to warn about uses of EXPR as an integer, rather than
+ as a pointer. */
+ expr = build_int_cst (totype, 0);
+ }
+ return expr;
+ case ck_ambig:
+ /* We leave bad_p off ck_ambig because overload resolution considers
+ it valid, it just fails when we try to perform it. So we need to
+ check complain here, too. */
+ if (complain & tf_error)
+ {
+ /* Call build_user_type_conversion again for the error. */
+ build_user_type_conversion (totype, convs->u.expr, LOOKUP_NORMAL,
+ complain);
+ if (fn)
+ inform (input_location, "initializing argument %P of %q+D",
+ argnum, fn);
+ }
+ return error_mark_node;
+
+ case ck_list:
+ {
+ /* Conversion to std::initializer_list<T>. */
+ tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (totype), 0);
+ tree new_ctor = build_constructor (init_list_type_node, NULL);
+ unsigned len = CONSTRUCTOR_NELTS (expr);
+ tree array, val, field;
+ vec<constructor_elt, va_gc> *vec = NULL;
+ unsigned ix;
+
+ /* Convert all the elements. */
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val)
+ {
+ tree sub = convert_like_real (convs->u.list[ix], val, fn, argnum,
+ 1, false, false, complain);
+ if (sub == error_mark_node)
+ return sub;
+ if (!BRACE_ENCLOSED_INITIALIZER_P (val))
+ check_narrowing (TREE_TYPE (sub), val);
+ CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), NULL_TREE, sub);
+ if (!TREE_CONSTANT (sub))
+ TREE_CONSTANT (new_ctor) = false;
+ }
+ /* Build up the array. */
+ elttype = cp_build_qualified_type
+ (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST);
+ array = build_array_of_n_type (elttype, len);
+ array = finish_compound_literal (array, new_ctor, complain);
+ /* Take the address explicitly rather than via decay_conversion
+ to avoid the error about taking the address of a temporary. */
+ array = cp_build_addr_expr (array, complain);
+ array = cp_convert (build_pointer_type (elttype), array, complain);
+ if (array == error_mark_node)
+ return error_mark_node;
+
+ /* Build up the initializer_list object. */
+ totype = complete_type (totype);
+ field = next_initializable_field (TYPE_FIELDS (totype));
+ CONSTRUCTOR_APPEND_ELT (vec, field, array);
+ field = next_initializable_field (DECL_CHAIN (field));
+ CONSTRUCTOR_APPEND_ELT (vec, field, size_int (len));
+ new_ctor = build_constructor (totype, vec);
+ return get_target_expr_sfinae (new_ctor, complain);
+ }
+
+ case ck_aggr:
+ if (TREE_CODE (totype) == COMPLEX_TYPE)
+ {
+ tree real = CONSTRUCTOR_ELT (expr, 0)->value;
+ tree imag = CONSTRUCTOR_ELT (expr, 1)->value;
+ real = perform_implicit_conversion (TREE_TYPE (totype),
+ real, complain);
+ imag = perform_implicit_conversion (TREE_TYPE (totype),
+ imag, complain);
+ expr = build2 (COMPLEX_EXPR, totype, real, imag);
+ return fold_if_not_in_template (expr);
+ }
+ expr = reshape_init (totype, expr, complain);
+ expr = get_target_expr_sfinae (digest_init (totype, expr, complain),
+ complain);
+ if (expr != error_mark_node)
+ TARGET_EXPR_LIST_INIT_P (expr) = true;
+ return expr;
+
+ default:
+ break;
+ };
+
+ expr = convert_like_real (next_conversion (convs), expr, fn, argnum,
+ convs->kind == ck_ref_bind ? -1 : 1,
+ convs->kind == ck_ref_bind ? issue_conversion_warnings : false,
+ c_cast_p,
+ complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ switch (convs->kind)
+ {
+ case ck_rvalue:
+ expr = decay_conversion (expr, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ if (! MAYBE_CLASS_TYPE_P (totype))
+ return expr;
+ /* Else fall through. */
+ case ck_base:
+ if (convs->kind == ck_base && !convs->need_temporary_p)
+ {
+ /* We are going to bind a reference directly to a base-class
+ subobject of EXPR. */
+ /* Build an expression for `*((base*) &expr)'. */
+ expr = cp_build_addr_expr (expr, complain);
+ expr = convert_to_base (expr, build_pointer_type (totype),
+ !c_cast_p, /*nonnull=*/true, complain);
+ expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain);
+ return expr;
+ }
+
+ /* Copy-initialization where the cv-unqualified version of the source
+ type is the same class as, or a derived class of, the class of the
+ destination [is treated as direct-initialization]. [dcl.init] */
+ flags = LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING;
+ if (convs->user_conv_p)
+ /* This conversion is being done in the context of a user-defined
+ conversion (i.e. the second step of copy-initialization), so
+ don't allow any more. */
+ flags |= LOOKUP_NO_CONVERSION;
+ if (convs->rvaluedness_matches_p)
+ flags |= LOOKUP_PREFER_RVALUE;
+ if (TREE_CODE (expr) == TARGET_EXPR
+ && TARGET_EXPR_LIST_INIT_P (expr))
+ /* Copy-list-initialization doesn't actually involve a copy. */
+ return expr;
+ expr = build_temp (expr, totype, flags, &diag_kind, complain);
+ if (diag_kind && fn && complain)
+ emit_diagnostic (diag_kind, DECL_SOURCE_LOCATION (fn), 0,
+ " initializing argument %P of %qD", argnum, fn);
+ return build_cplus_new (totype, expr, complain);
+
+ case ck_ref_bind:
+ {
+ tree ref_type = totype;
+
+ if (convs->bad_p && !next_conversion (convs)->bad_p)
+ {
+ gcc_assert (TYPE_REF_IS_RVALUE (ref_type)
+ && (real_lvalue_p (expr)
+ || next_conversion(convs)->kind == ck_rvalue));
+
+ error_at (loc, "cannot bind %qT lvalue to %qT",
+ TREE_TYPE (expr), totype);
+ if (fn)
+ inform (input_location,
+ "initializing argument %P of %q+D", argnum, fn);
+ return error_mark_node;
+ }
+
+ /* If necessary, create a temporary.
+
+ VA_ARG_EXPR and CONSTRUCTOR expressions are special cases
+ that need temporaries, even when their types are reference
+ compatible with the type of reference being bound, so the
+ upcoming call to cp_build_addr_expr doesn't fail. */
+ if (convs->need_temporary_p
+ || TREE_CODE (expr) == CONSTRUCTOR
+ || TREE_CODE (expr) == VA_ARG_EXPR)
+ {
+ /* Otherwise, a temporary of type "cv1 T1" is created and
+ initialized from the initializer expression using the rules
+ for a non-reference copy-initialization (8.5). */
+
+ tree type = TREE_TYPE (ref_type);
+ cp_lvalue_kind lvalue = real_lvalue_p (expr);
+
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ (type, next_conversion (convs)->type));
+ if (!CP_TYPE_CONST_NON_VOLATILE_P (type)
+ && !TYPE_REF_IS_RVALUE (ref_type))
+ {
+ /* If the reference is volatile or non-const, we
+ cannot create a temporary. */
+ if (lvalue & clk_bitfield)
+ error_at (loc, "cannot bind bitfield %qE to %qT",
+ expr, ref_type);
+ else if (lvalue & clk_packed)
+ error_at (loc, "cannot bind packed field %qE to %qT",
+ expr, ref_type);
+ else
+ error_at (loc, "cannot bind rvalue %qE to %qT",
+ expr, ref_type);
+ return error_mark_node;
+ }
+ /* If the source is a packed field, and we must use a copy
+ constructor, then building the target expr will require
+ binding the field to the reference parameter to the
+ copy constructor, and we'll end up with an infinite
+ loop. If we can use a bitwise copy, then we'll be
+ OK. */
+ if ((lvalue & clk_packed)
+ && CLASS_TYPE_P (type)
+ && type_has_nontrivial_copy_init (type))
+ {
+ error_at (loc, "cannot bind packed field %qE to %qT",
+ expr, ref_type);
+ return error_mark_node;
+ }
+ if (lvalue & clk_bitfield)
+ {
+ expr = convert_bitfield_to_declared_type (expr);
+ expr = fold_convert (type, expr);
+ }
+ expr = build_target_expr_with_type (expr, type, complain);
+ }
+
+ /* Take the address of the thing to which we will bind the
+ reference. */
+ expr = cp_build_addr_expr (expr, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ /* Convert it to a pointer to the type referred to by the
+ reference. This will adjust the pointer if a derived to
+ base conversion is being performed. */
+ expr = cp_convert (build_pointer_type (TREE_TYPE (ref_type)),
+ expr, complain);
+ /* Convert the pointer to the desired reference type. */
+ return build_nop (ref_type, expr);
+ }
+
+ case ck_lvalue:
+ return decay_conversion (expr, complain);
+
+ case ck_qual:
+ /* Warn about deprecated conversion if appropriate. */
+ string_conv_p (totype, expr, 1);
+ break;
+
+ case ck_ptr:
+ if (convs->base_p)
+ expr = convert_to_base (expr, totype, !c_cast_p,
+ /*nonnull=*/false, complain);
+ return build_nop (totype, expr);
+
+ case ck_pmem:
+ return convert_ptrmem (totype, expr, /*allow_inverse_p=*/false,
+ c_cast_p, complain);
+
+ default:
+ break;
+ }
+
+ if (convs->check_narrowing)
+ check_narrowing (totype, expr);
+
+ if (issue_conversion_warnings)
+ expr = cp_convert_and_check (totype, expr, complain);
+ else
+ expr = cp_convert (totype, expr, complain);
+
+ return expr;
+}
+
+/* ARG is being passed to a varargs function. Perform any conversions
+ required. Return the converted value. */
+
+tree
+convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
+{
+ tree arg_type;
+ location_t loc = EXPR_LOC_OR_LOC (arg, input_location);
+
+ /* [expr.call]
+
+ The lvalue-to-rvalue, array-to-pointer, and function-to-pointer
+ standard conversions are performed. */
+ arg = decay_conversion (arg, complain);
+ arg_type = TREE_TYPE (arg);
+ /* [expr.call]
+
+ If the argument has integral or enumeration type that is subject
+ to the integral promotions (_conv.prom_), or a floating point
+ type that is subject to the floating point promotion
+ (_conv.fpprom_), the value of the argument is converted to the
+ promoted type before the call. */
+ if (TREE_CODE (arg_type) == REAL_TYPE
+ && (TYPE_PRECISION (arg_type)
+ < TYPE_PRECISION (double_type_node))
+ && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (arg_type)))
+ {
+ if ((complain & tf_warning)
+ && warn_double_promotion && !c_inhibit_evaluation_warnings)
+ warning_at (loc, OPT_Wdouble_promotion,
+ "implicit conversion from %qT to %qT when passing "
+ "argument to function",
+ arg_type, double_type_node);
+ arg = convert_to_real (double_type_node, arg);
+ }
+ else if (NULLPTR_TYPE_P (arg_type))
+ arg = null_pointer_node;
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (arg_type))
+ {
+ if (SCOPED_ENUM_P (arg_type) && !abi_version_at_least (6))
+ {
+ if (complain & tf_warning)
+ warning_at (loc, OPT_Wabi, "scoped enum %qT will not promote to an "
+ "integral type in a future version of GCC", arg_type);
+ arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg, complain);
+ }
+ arg = cp_perform_integral_promotions (arg, complain);
+ }
+
+ arg = require_complete_type_sfinae (arg, complain);
+ arg_type = TREE_TYPE (arg);
+
+ if (arg != error_mark_node
+ /* In a template (or ill-formed code), we can have an incomplete type
+ even after require_complete_type_sfinae, in which case we don't know
+ whether it has trivial copy or not. */
+ && COMPLETE_TYPE_P (arg_type))
+ {
+ /* Build up a real lvalue-to-rvalue conversion in case the
+ copy constructor is trivial but not callable. */
+ if (!cp_unevaluated_operand && CLASS_TYPE_P (arg_type))
+ force_rvalue (arg, complain);
+
+ /* [expr.call] 5.2.2/7:
+ Passing a potentially-evaluated argument of class type (Clause 9)
+ with a non-trivial copy constructor or a non-trivial destructor
+ with no corresponding parameter is conditionally-supported, with
+ implementation-defined semantics.
+
+ We used to just warn here and do a bitwise copy, but now
+ cp_expr_size will abort if we try to do that.
+
+ If the call appears in the context of a sizeof expression,
+ it is not potentially-evaluated. */
+ if (cp_unevaluated_operand == 0
+ && (type_has_nontrivial_copy_init (arg_type)
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (arg_type)))
+ {
+ if (complain & tf_error)
+ error_at (loc, "cannot pass objects of non-trivially-copyable "
+ "type %q#T through %<...%>", arg_type);
+ return error_mark_node;
+ }
+ }
+
+ return arg;
+}
+
+/* va_arg (EXPR, TYPE) is a builtin. Make sure it is not abused. */
+
+tree
+build_x_va_arg (source_location loc, tree expr, tree type)
+{
+ if (processing_template_decl)
+ return build_min (VA_ARG_EXPR, type, expr);
+
+ type = complete_type_or_else (type, NULL_TREE);
+
+ if (expr == error_mark_node || !type)
+ return error_mark_node;
+
+ expr = mark_lvalue_use (expr);
+
+ if (type_has_nontrivial_copy_init (type)
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ || TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ /* Remove reference types so we don't ICE later on. */
+ tree type1 = non_reference (type);
+ /* conditionally-supported behavior [expr.call] 5.2.2/7. */
+ error ("cannot receive objects of non-trivially-copyable type %q#T "
+ "through %<...%>; ", type);
+ expr = convert (build_pointer_type (type1), null_node);
+ expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
+ return expr;
+ }
+
+ return build_va_arg (loc, expr, type);
+}
+
+/* TYPE has been given to va_arg. Apply the default conversions which
+ would have happened when passed via ellipsis. Return the promoted
+ type, or the passed type if there is no change. */
+
+tree
+cxx_type_promotes_to (tree type)
+{
+ tree promote;
+
+ /* Perform the array-to-pointer and function-to-pointer
+ conversions. */
+ type = type_decays_to (type);
+
+ promote = type_promotes_to (type);
+ if (same_type_p (type, promote))
+ promote = type;
+
+ return promote;
+}
+
+/* ARG is a default argument expression being passed to a parameter of
+ the indicated TYPE, which is a parameter to FN. PARMNUM is the
+ zero-based argument number. Do any required conversions. Return
+ the converted value. */
+
+static GTY(()) vec<tree, va_gc> *default_arg_context;
+void
+push_defarg_context (tree fn)
+{ vec_safe_push (default_arg_context, fn); }
+
+void
+pop_defarg_context (void)
+{ default_arg_context->pop (); }
+
+tree
+convert_default_arg (tree type, tree arg, tree fn, int parmnum,
+ tsubst_flags_t complain)
+{
+ int i;
+ tree t;
+
+ /* See through clones. */
+ fn = DECL_ORIGIN (fn);
+
+ /* Detect recursion. */
+ FOR_EACH_VEC_SAFE_ELT (default_arg_context, i, t)
+ if (t == fn)
+ {
+ if (complain & tf_error)
+ error ("recursive evaluation of default argument for %q#D", fn);
+ return error_mark_node;
+ }
+
+ /* If the ARG is an unparsed default argument expression, the
+ conversion cannot be performed. */
+ if (TREE_CODE (arg) == DEFAULT_ARG)
+ {
+ if (complain & tf_error)
+ error ("call to %qD uses the default argument for parameter %P, which "
+ "is not yet defined", fn, parmnum);
+ return error_mark_node;
+ }
+
+ push_defarg_context (fn);
+
+ if (fn && DECL_TEMPLATE_INFO (fn))
+ arg = tsubst_default_argument (fn, type, arg, complain);
+
+ /* Due to:
+
+ [dcl.fct.default]
+
+ The names in the expression are bound, and the semantic
+ constraints are checked, at the point where the default
+ expressions appears.
+
+ we must not perform access checks here. */
+ push_deferring_access_checks (dk_no_check);
+ /* We must make a copy of ARG, in case subsequent processing
+ alters any part of it. */
+ arg = break_out_target_exprs (arg);
+ arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
+ ICR_DEFAULT_ARGUMENT, fn, parmnum,
+ complain);
+ arg = convert_for_arg_passing (type, arg, complain);
+ pop_deferring_access_checks();
+
+ pop_defarg_context ();
+
+ return arg;
+}
+
+/* Returns the type which will really be used for passing an argument of
+ type TYPE. */
+
+tree
+type_passed_as (tree type)
+{
+ /* Pass classes with copy ctors by invisible reference. */
+ if (TREE_ADDRESSABLE (type))
+ {
+ type = build_reference_type (type);
+ /* There are no other pointers to this temporary. */
+ type = cp_build_qualified_type (type, TYPE_QUAL_RESTRICT);
+ }
+ else if (targetm.calls.promote_prototypes (type)
+ && INTEGRAL_TYPE_P (type)
+ && COMPLETE_TYPE_P (type)
+ && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
+ TYPE_SIZE (integer_type_node)))
+ type = integer_type_node;
+
+ return type;
+}
+
+/* Actually perform the appropriate conversion. */
+
+tree
+convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
+{
+ tree bitfield_type;
+
+ /* If VAL is a bitfield, then -- since it has already been converted
+ to TYPE -- it cannot have a precision greater than TYPE.
+
+ If it has a smaller precision, we must widen it here. For
+ example, passing "int f:3;" to a function expecting an "int" will
+ not result in any conversion before this point.
+
+ If the precision is the same we must not risk widening. For
+ example, the COMPONENT_REF for a 32-bit "long long" bitfield will
+ often have type "int", even though the C++ type for the field is
+ "long long". If the value is being passed to a function
+ expecting an "int", then no conversions will be required. But,
+ if we call convert_bitfield_to_declared_type, the bitfield will
+ be converted to "long long". */
+ bitfield_type = is_bitfield_expr_with_lowered_type (val);
+ if (bitfield_type
+ && TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type))
+ val = convert_to_integer (TYPE_MAIN_VARIANT (bitfield_type), val);
+
+ if (val == error_mark_node)
+ ;
+ /* Pass classes with copy ctors by invisible reference. */
+ else if (TREE_ADDRESSABLE (type))
+ val = build1 (ADDR_EXPR, build_reference_type (type), val);
+ else if (targetm.calls.promote_prototypes (type)
+ && INTEGRAL_TYPE_P (type)
+ && COMPLETE_TYPE_P (type)
+ && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
+ TYPE_SIZE (integer_type_node)))
+ val = cp_perform_integral_promotions (val, complain);
+ if ((complain & tf_warning)
+ && warn_suggest_attribute_format)
+ {
+ tree rhstype = TREE_TYPE (val);
+ const enum tree_code coder = TREE_CODE (rhstype);
+ const enum tree_code codel = TREE_CODE (type);
+ if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
+ && coder == codel
+ && check_missing_format_attribute (type, rhstype))
+ warning (OPT_Wsuggest_attribute_format,
+ "argument of function call might be a candidate for a format attribute");
+ }
+ return val;
+}
+
+/* Returns true iff FN is a function with magic varargs, i.e. ones for
+ which no conversions at all should be done. This is true for some
+ builtins which don't act like normal functions. */
+
+bool
+magic_varargs_p (tree fn)
+{
+ if (flag_cilkplus && is_cilkplus_reduce_builtin (fn) != BUILT_IN_NONE)
+ return true;
+
+ if (DECL_BUILT_IN (fn))
+ switch (DECL_FUNCTION_CODE (fn))
+ {
+ case BUILT_IN_CLASSIFY_TYPE:
+ case BUILT_IN_CONSTANT_P:
+ case BUILT_IN_NEXT_ARG:
+ case BUILT_IN_VA_START:
+ return true;
+
+ default:;
+ return lookup_attribute ("type generic",
+ TYPE_ATTRIBUTES (TREE_TYPE (fn))) != 0;
+ }
+
+ return false;
+}
+
+/* Returns the decl of the dispatcher function if FN is a function version. */
+
+tree
+get_function_version_dispatcher (tree fn)
+{
+ tree dispatcher_decl = NULL;
+
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (fn));
+
+ gcc_assert (targetm.get_function_versions_dispatcher);
+ dispatcher_decl = targetm.get_function_versions_dispatcher (fn);
+
+ if (dispatcher_decl == NULL)
+ {
+ error_at (input_location, "use of multiversioned function "
+ "without a default");
+ return NULL;
+ }
+
+ retrofit_lang_decl (dispatcher_decl);
+ gcc_assert (dispatcher_decl != NULL);
+ return dispatcher_decl;
+}
+
+/* fn is a function version dispatcher that is marked used. Mark all the
+ semantically identical function versions it will dispatch as used. */
+
+void
+mark_versions_used (tree fn)
+{
+ struct cgraph_node *node;
+ struct cgraph_function_version_info *node_v;
+ struct cgraph_function_version_info *it_v;
+
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
+
+ node = cgraph_get_node (fn);
+ if (node == NULL)
+ return;
+
+ gcc_assert (node->dispatcher_function);
+
+ node_v = get_cgraph_node_version (node);
+ if (node_v == NULL)
+ return;
+
+ /* All semantically identical versions are chained. Traverse and mark each
+ one of them as used. */
+ it_v = node_v->next;
+ while (it_v != NULL)
+ {
+ mark_used (it_v->this_node->decl);
+ it_v = it_v->next;
+ }
+}
+
+/* Subroutine of the various build_*_call functions. Overload resolution
+ has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
+ ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a
+ bitmask of various LOOKUP_* flags which apply to the call itself. */
+
+static tree
+build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
+{
+ tree fn = cand->fn;
+ const vec<tree, va_gc> *args = cand->args;
+ tree first_arg = cand->first_arg;
+ conversion **convs = cand->convs;
+ conversion *conv;
+ tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ int parmlen;
+ tree val;
+ int i = 0;
+ int j = 0;
+ unsigned int arg_index = 0;
+ int is_method = 0;
+ int nargs;
+ tree *argarray;
+ bool already_used = false;
+
+ /* In a template, there is no need to perform all of the work that
+ is normally done. We are only interested in the type of the call
+ expression, i.e., the return type of the function. Any semantic
+ errors will be deferred until the template is instantiated. */
+ if (processing_template_decl)
+ {
+ tree expr, addr;
+ tree return_type;
+ const tree *argarray;
+ unsigned int nargs;
+
+ return_type = TREE_TYPE (TREE_TYPE (fn));
+ nargs = vec_safe_length (args);
+ if (first_arg == NULL_TREE)
+ argarray = args->address ();
+ else
+ {
+ tree *alcarray;
+ unsigned int ix;
+ tree arg;
+
+ ++nargs;
+ alcarray = XALLOCAVEC (tree, nargs);
+ alcarray[0] = first_arg;
+ FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
+ alcarray[ix + 1] = arg;
+ argarray = alcarray;
+ }
+
+ addr = build_addr_func (fn, complain);
+ if (addr == error_mark_node)
+ return error_mark_node;
+ expr = build_call_array_loc (input_location, return_type,
+ addr, nargs, argarray);
+ if (TREE_THIS_VOLATILE (fn) && cfun)
+ current_function_returns_abnormally = 1;
+ return convert_from_reference (expr);
+ }
+
+ /* Give any warnings we noticed during overload resolution. */
+ if (cand->warnings && (complain & tf_warning))
+ {
+ struct candidate_warning *w;
+ for (w = cand->warnings; w; w = w->next)
+ joust (cand, w->loser, 1, complain);
+ }
+
+ /* Make =delete work with SFINAE. */
+ if (DECL_DELETED_FN (fn) && !(complain & tf_error))
+ return error_mark_node;
+
+ if (DECL_FUNCTION_MEMBER_P (fn))
+ {
+ tree access_fn;
+ /* If FN is a template function, two cases must be considered.
+ For example:
+
+ struct A {
+ protected:
+ template <class T> void f();
+ };
+ template <class T> struct B {
+ protected:
+ void g();
+ };
+ struct C : A, B<int> {
+ using A::f; // #1
+ using B<int>::g; // #2
+ };
+
+ In case #1 where `A::f' is a member template, DECL_ACCESS is
+ recorded in the primary template but not in its specialization.
+ We check access of FN using its primary template.
+
+ In case #2, where `B<int>::g' has a DECL_TEMPLATE_INFO simply
+ because it is a member of class template B, DECL_ACCESS is
+ recorded in the specialization `B<int>::g'. We cannot use its
+ primary template because `B<T>::g' and `B<int>::g' may have
+ different access. */
+ if (DECL_TEMPLATE_INFO (fn)
+ && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (fn)))
+ access_fn = DECL_TI_TEMPLATE (fn);
+ else
+ access_fn = fn;
+ if (!perform_or_defer_access_check (cand->access_path, access_fn,
+ fn, complain))
+ return error_mark_node;
+ }
+
+ /* If we're checking for implicit delete, don't bother with argument
+ conversions. */
+ if (flags & LOOKUP_SPECULATIVE)
+ {
+ if (DECL_DELETED_FN (fn))
+ {
+ if (complain & tf_error)
+ mark_used (fn);
+ return error_mark_node;
+ }
+ if (cand->viable == 1)
+ return fn;
+ else if (!(complain & tf_error))
+ /* Reject bad conversions now. */
+ return error_mark_node;
+ /* else continue to get conversion error. */
+ }
+
+ /* N3276 magic doesn't apply to nested calls. */
+ int decltype_flag = (complain & tf_decltype);
+ complain &= ~tf_decltype;
+
+ /* Find maximum size of vector to hold converted arguments. */
+ parmlen = list_length (parm);
+ nargs = vec_safe_length (args) + (first_arg != NULL_TREE ? 1 : 0);
+ if (parmlen > nargs)
+ nargs = parmlen;
+ argarray = XALLOCAVEC (tree, nargs);
+
+ /* The implicit parameters to a constructor are not considered by overload
+ resolution, and must be of the proper type. */
+ if (DECL_CONSTRUCTOR_P (fn))
+ {
+ tree object_arg;
+ if (first_arg != NULL_TREE)
+ {
+ object_arg = first_arg;
+ first_arg = NULL_TREE;
+ }
+ else
+ {
+ object_arg = (*args)[arg_index];
+ ++arg_index;
+ }
+ argarray[j++] = build_this (object_arg);
+ parm = TREE_CHAIN (parm);
+ /* We should never try to call the abstract constructor. */
+ gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (fn));
+
+ if (DECL_HAS_VTT_PARM_P (fn))
+ {
+ argarray[j++] = (*args)[arg_index];
+ ++arg_index;
+ parm = TREE_CHAIN (parm);
+ }
+ }
+ /* Bypass access control for 'this' parameter. */
+ else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+ {
+ tree parmtype = TREE_VALUE (parm);
+ tree arg = build_this (first_arg != NULL_TREE
+ ? first_arg
+ : (*args)[arg_index]);
+ tree argtype = TREE_TYPE (arg);
+ tree converted_arg;
+ tree base_binfo;
+
+ if (convs[i]->bad_p)
+ {
+ if (complain & tf_error)
+ permerror (input_location, "passing %qT as %<this%> argument of %q#D discards qualifiers",
+ TREE_TYPE (argtype), fn);
+ else
+ return error_mark_node;
+ }
+
+ /* See if the function member or the whole class type is declared
+ final and the call can be devirtualized. */
+ if (DECL_FINAL_P (fn)
+ || CLASSTYPE_FINAL (TYPE_METHOD_BASETYPE (TREE_TYPE (fn))))
+ flags |= LOOKUP_NONVIRTUAL;
+
+ /* [class.mfct.nonstatic]: If a nonstatic member function of a class
+ X is called for an object that is not of type X, or of a type
+ derived from X, the behavior is undefined.
+
+ So we can assume that anything passed as 'this' is non-null, and
+ optimize accordingly. */
+ gcc_assert (TYPE_PTR_P (parmtype));
+ /* Convert to the base in which the function was declared. */
+ gcc_assert (cand->conversion_path != NULL_TREE);
+ converted_arg = build_base_path (PLUS_EXPR,
+ arg,
+ cand->conversion_path,
+ 1, complain);
+ /* Check that the base class is accessible. */
+ if (!accessible_base_p (TREE_TYPE (argtype),
+ BINFO_TYPE (cand->conversion_path), true))
+ {
+ if (complain & tf_error)
+ error ("%qT is not an accessible base of %qT",
+ BINFO_TYPE (cand->conversion_path),
+ TREE_TYPE (argtype));
+ else
+ return error_mark_node;
+ }
+ /* If fn was found by a using declaration, the conversion path
+ will be to the derived class, not the base declaring fn. We
+ must convert from derived to base. */
+ base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)),
+ TREE_TYPE (parmtype), ba_unique,
+ NULL, complain);
+ converted_arg = build_base_path (PLUS_EXPR, converted_arg,
+ base_binfo, 1, complain);
+
+ argarray[j++] = converted_arg;
+ parm = TREE_CHAIN (parm);
+ if (first_arg != NULL_TREE)
+ first_arg = NULL_TREE;
+ else
+ ++arg_index;
+ ++i;
+ is_method = 1;
+ }
+
+ gcc_assert (first_arg == NULL_TREE);
+ for (; arg_index < vec_safe_length (args) && parm;
+ parm = TREE_CHAIN (parm), ++arg_index, ++i)
+ {
+ tree type = TREE_VALUE (parm);
+ tree arg = (*args)[arg_index];
+ bool conversion_warning = true;
+
+ conv = convs[i];
+
+ /* If the argument is NULL and used to (implicitly) instantiate a
+ template function (and bind one of the template arguments to
+ the type of 'long int'), we don't want to warn about passing NULL
+ to non-pointer argument.
+ For example, if we have this template function:
+
+ template<typename T> void func(T x) {}
+
+ we want to warn (when -Wconversion is enabled) in this case:
+
+ void foo() {
+ func<int>(NULL);
+ }
+
+ but not in this case:
+
+ void foo() {
+ func(NULL);
+ }
+ */
+ if (arg == null_node
+ && DECL_TEMPLATE_INFO (fn)
+ && cand->template_decl
+ && !(flags & LOOKUP_EXPLICIT_TMPL_ARGS))
+ conversion_warning = false;
+
+ /* Warn about initializer_list deduction that isn't currently in the
+ working draft. */
+ if (cxx_dialect > cxx98
+ && flag_deduce_init_list
+ && cand->template_decl
+ && is_std_init_list (non_reference (type))
+ && BRACE_ENCLOSED_INITIALIZER_P (arg))
+ {
+ tree tmpl = TI_TEMPLATE (cand->template_decl);
+ tree realparm = chain_index (j, DECL_ARGUMENTS (cand->fn));
+ tree patparm = get_pattern_parm (realparm, tmpl);
+ tree pattype = TREE_TYPE (patparm);
+ if (PACK_EXPANSION_P (pattype))
+ pattype = PACK_EXPANSION_PATTERN (pattype);
+ pattype = non_reference (pattype);
+
+ if (TREE_CODE (pattype) == TEMPLATE_TYPE_PARM
+ && (cand->explicit_targs == NULL_TREE
+ || (TREE_VEC_LENGTH (cand->explicit_targs)
+ <= TEMPLATE_TYPE_IDX (pattype))))
+ {
+ pedwarn (input_location, 0, "deducing %qT as %qT",
+ non_reference (TREE_TYPE (patparm)),
+ non_reference (type));
+ pedwarn (input_location, 0, " in call to %q+D", cand->fn);
+ pedwarn (input_location, 0,
+ " (you can disable this with -fno-deduce-init-list)");
+ }
+ }
+ val = convert_like_with_context (conv, arg, fn, i - is_method,
+ conversion_warning
+ ? complain
+ : complain & (~tf_warning));
+
+ val = convert_for_arg_passing (type, val, complain);
+
+ if (val == error_mark_node)
+ return error_mark_node;
+ else
+ argarray[j++] = val;
+ }
+
+ /* Default arguments */
+ for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++)
+ {
+ if (TREE_VALUE (parm) == error_mark_node)
+ return error_mark_node;
+ argarray[j++] = convert_default_arg (TREE_VALUE (parm),
+ TREE_PURPOSE (parm),
+ fn, i - is_method,
+ complain);
+ }
+
+ /* Ellipsis */
+ for (; arg_index < vec_safe_length (args); ++arg_index)
+ {
+ tree a = (*args)[arg_index];
+ if (magic_varargs_p (fn))
+ /* Do no conversions for magic varargs. */
+ a = mark_type_use (a);
+ else
+ a = convert_arg_to_ellipsis (a, complain);
+ argarray[j++] = a;
+ }
+
+ gcc_assert (j <= nargs);
+ nargs = j;
+
+ check_function_arguments (TREE_TYPE (fn), nargs, argarray);
+
+ /* Avoid actually calling copy constructors and copy assignment operators,
+ if possible. */
+
+ if (! flag_elide_constructors)
+ /* Do things the hard way. */;
+ else if (cand->num_convs == 1
+ && (DECL_COPY_CONSTRUCTOR_P (fn)
+ || DECL_MOVE_CONSTRUCTOR_P (fn)))
+ {
+ tree targ;
+ tree arg = argarray[num_artificial_parms_for (fn)];
+ tree fa;
+ bool trivial = trivial_fn_p (fn);
+
+ /* Pull out the real argument, disregarding const-correctness. */
+ targ = arg;
+ while (CONVERT_EXPR_P (targ)
+ || TREE_CODE (targ) == NON_LVALUE_EXPR)
+ targ = TREE_OPERAND (targ, 0);
+ if (TREE_CODE (targ) == ADDR_EXPR)
+ {
+ targ = TREE_OPERAND (targ, 0);
+ if (!same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (TREE_TYPE (arg)), TREE_TYPE (targ)))
+ targ = NULL_TREE;
+ }
+ else
+ targ = NULL_TREE;
+
+ if (targ)
+ arg = targ;
+ else
+ arg = cp_build_indirect_ref (arg, RO_NULL, complain);
+
+ /* [class.copy]: the copy constructor is implicitly defined even if
+ the implementation elided its use. */
+ if (!trivial || DECL_DELETED_FN (fn))
+ {
+ mark_used (fn);
+ already_used = true;
+ }
+
+ /* If we're creating a temp and we already have one, don't create a
+ new one. If we're not creating a temp but we get one, use
+ INIT_EXPR to collapse the temp into our target. Otherwise, if the
+ ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
+ temp or an INIT_EXPR otherwise. */
+ fa = argarray[0];
+ if (integer_zerop (fa))
+ {
+ if (TREE_CODE (arg) == TARGET_EXPR)
+ return arg;
+ else if (trivial)
+ return force_target_expr (DECL_CONTEXT (fn), arg, complain);
+ }
+ else if (TREE_CODE (arg) == TARGET_EXPR || trivial)
+ {
+ tree to = stabilize_reference (cp_build_indirect_ref (fa, RO_NULL,
+ complain));
+
+ val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
+ return val;
+ }
+ }
+ else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
+ && trivial_fn_p (fn)
+ && !DECL_DELETED_FN (fn))
+ {
+ tree to = stabilize_reference
+ (cp_build_indirect_ref (argarray[0], RO_NULL, complain));
+ tree type = TREE_TYPE (to);
+ tree as_base = CLASSTYPE_AS_BASE (type);
+ tree arg = argarray[1];
+
+ if (is_really_empty_class (type))
+ {
+ /* Avoid copying empty classes. */
+ val = build2 (COMPOUND_EXPR, void_type_node, to, arg);
+ TREE_NO_WARNING (val) = 1;
+ val = build2 (COMPOUND_EXPR, type, val, to);
+ TREE_NO_WARNING (val) = 1;
+ }
+ else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
+ {
+ arg = cp_build_indirect_ref (arg, RO_NULL, complain);
+ val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
+ }
+ else
+ {
+ /* We must only copy the non-tail padding parts. */
+ tree arg0, arg2, t;
+ tree array_type, alias_set;
+
+ arg2 = TYPE_SIZE_UNIT (as_base);
+ arg0 = cp_build_addr_expr (to, complain);
+
+ array_type = build_array_type (char_type_node,
+ build_index_type
+ (size_binop (MINUS_EXPR,
+ arg2, size_int (1))));
+ alias_set = build_int_cst (build_pointer_type (type), 0);
+ t = build2 (MODIFY_EXPR, void_type_node,
+ build2 (MEM_REF, array_type, arg0, alias_set),
+ build2 (MEM_REF, array_type, arg, alias_set));
+ val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to);
+ TREE_NO_WARNING (val) = 1;
+ }
+
+ return val;
+ }
+ else if (DECL_DESTRUCTOR_P (fn)
+ && trivial_fn_p (fn)
+ && !DECL_DELETED_FN (fn))
+ return fold_convert (void_type_node, argarray[0]);
+ /* FIXME handle trivial default constructor, too. */
+
+ /* For calls to a multi-versioned function, overload resolution
+ returns the function with the highest target priority, that is,
+ the version that will checked for dispatching first. If this
+ version is inlinable, a direct call to this version can be made
+ otherwise the call should go through the dispatcher. */
+
+ if (DECL_FUNCTION_VERSIONED (fn)
+ && (current_function_decl == NULL
+ || !targetm.target_option.can_inline_p (current_function_decl, fn)))
+ {
+ fn = get_function_version_dispatcher (fn);
+ if (fn == NULL)
+ return NULL;
+ if (!already_used)
+ mark_versions_used (fn);
+ }
+
+ if (!already_used
+ && !mark_used (fn))
+ return error_mark_node;
+
+ if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
+ /* Don't mess with virtual lookup in fold_non_dependent_expr; virtual
+ functions can't be constexpr. */
+ && !in_template_function ())
+ {
+ tree t;
+ tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (argarray[0])),
+ DECL_CONTEXT (fn),
+ ba_any, NULL, complain);
+ gcc_assert (binfo && binfo != error_mark_node);
+
+ /* Warn about deprecated virtual functions now, since we're about
+ to throw away the decl. */
+ if (TREE_DEPRECATED (fn))
+ warn_deprecated_use (fn, NULL_TREE);
+
+ argarray[0] = build_base_path (PLUS_EXPR, argarray[0], binfo, 1,
+ complain);
+ if (TREE_SIDE_EFFECTS (argarray[0]))
+ argarray[0] = save_expr (argarray[0]);
+ t = build_pointer_type (TREE_TYPE (fn));
+ if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn)))
+ fn = build_java_interface_fn_ref (fn, argarray[0]);
+ else
+ fn = build_vfn_ref (argarray[0], DECL_VINDEX (fn));
+ TREE_TYPE (fn) = t;
+ }
+ else
+ {
+ fn = build_addr_func (fn, complain);
+ if (fn == error_mark_node)
+ return error_mark_node;
+ }
+
+ return build_cxx_call (fn, nargs, argarray, complain|decltype_flag);
+}
+
+/* Build and return a call to FN, using NARGS arguments in ARGARRAY.
+ This function performs no overload resolution, conversion, or other
+ high-level operations. */
+
+tree
+build_cxx_call (tree fn, int nargs, tree *argarray,
+ tsubst_flags_t complain)
+{
+ tree fndecl;
+ int optimize_sav;
+
+ /* Remember roughly where this call is. */
+ location_t loc = EXPR_LOC_OR_LOC (fn, input_location);
+ fn = build_call_a (fn, nargs, argarray);
+ SET_EXPR_LOCATION (fn, loc);
+
+ fndecl = get_callee_fndecl (fn);
+
+ /* Check that arguments to builtin functions match the expectations. */
+ if (fndecl
+ && DECL_BUILT_IN (fndecl)
+ && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && !check_builtin_function_arguments (fndecl, nargs, argarray))
+ return error_mark_node;
+
+ /* If it is a built-in array notation function, then the return type of
+ the function is the element type of the array passed in as array
+ notation (i.e. the first parameter of the function). */
+ if (flag_cilkplus && TREE_CODE (fn) == CALL_EXPR)
+ {
+ enum built_in_function bif =
+ is_cilkplus_reduce_builtin (CALL_EXPR_FN (fn));
+ if (bif == BUILT_IN_CILKPLUS_SEC_REDUCE_ADD
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MUL
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
+ {
+ /* for bif == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
+ The pre-defined return-type is the correct one. */
+ tree array_ntn = CALL_EXPR_ARG (fn, 0);
+ TREE_TYPE (fn) = TREE_TYPE (array_ntn);
+ return fn;
+ }
+ }
+
+ /* Some built-in function calls will be evaluated at compile-time in
+ fold (). Set optimize to 1 when folding __builtin_constant_p inside
+ a constexpr function so that fold_builtin_1 doesn't fold it to 0. */
+ optimize_sav = optimize;
+ if (!optimize && fndecl && DECL_IS_BUILTIN_CONSTANT_P (fndecl)
+ && current_function_decl
+ && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
+ optimize = 1;
+ fn = fold_if_not_in_template (fn);
+ optimize = optimize_sav;
+
+ if (VOID_TYPE_P (TREE_TYPE (fn)))
+ return fn;
+
+ /* 5.2.2/11: If a function call is a prvalue of object type: if the
+ function call is either the operand of a decltype-specifier or the
+ right operand of a comma operator that is the operand of a
+ decltype-specifier, a temporary object is not introduced for the
+ prvalue. The type of the prvalue may be incomplete. */
+ if (!(complain & tf_decltype))
+ {
+ fn = require_complete_type_sfinae (fn, complain);
+ if (fn == error_mark_node)
+ return error_mark_node;
+
+ if (MAYBE_CLASS_TYPE_P (TREE_TYPE (fn)))
+ fn = build_cplus_new (TREE_TYPE (fn), fn, complain);
+ }
+ return convert_from_reference (fn);
+}
+
+static GTY(()) tree java_iface_lookup_fn;
+
+/* Make an expression which yields the address of the Java interface
+ method FN. This is achieved by generating a call to libjava's
+ _Jv_LookupInterfaceMethodIdx(). */
+
+static tree
+build_java_interface_fn_ref (tree fn, tree instance)
+{
+ tree lookup_fn, method, idx;
+ tree klass_ref, iface, iface_ref;
+ int i;
+
+ if (!java_iface_lookup_fn)
+ {
+ tree ftype = build_function_type_list (ptr_type_node,
+ ptr_type_node, ptr_type_node,
+ java_int_type_node, NULL_TREE);
+ java_iface_lookup_fn
+ = add_builtin_function ("_Jv_LookupInterfaceMethodIdx", ftype,
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ }
+
+ /* Look up the pointer to the runtime java.lang.Class object for `instance'.
+ This is the first entry in the vtable. */
+ klass_ref = build_vtbl_ref (cp_build_indirect_ref (instance, RO_NULL,
+ tf_warning_or_error),
+ integer_zero_node);
+
+ /* Get the java.lang.Class pointer for the interface being called. */
+ iface = DECL_CONTEXT (fn);
+ iface_ref = lookup_field (iface, get_identifier ("class$"), 0, false);
+ if (!iface_ref || !VAR_P (iface_ref)
+ || DECL_CONTEXT (iface_ref) != iface)
+ {
+ error ("could not find class$ field in java interface type %qT",
+ iface);
+ return error_mark_node;
+ }
+ iface_ref = build_address (iface_ref);
+ iface_ref = convert (build_pointer_type (iface), iface_ref);
+
+ /* Determine the itable index of FN. */
+ i = 1;
+ for (method = TYPE_METHODS (iface); method; method = DECL_CHAIN (method))
+ {
+ if (!DECL_VIRTUAL_P (method))
+ continue;
+ if (fn == method)
+ break;
+ i++;
+ }
+ idx = build_int_cst (NULL_TREE, i);
+
+ lookup_fn = build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (java_iface_lookup_fn)),
+ java_iface_lookup_fn);
+ return build_call_nary (ptr_type_node, lookup_fn,
+ 3, klass_ref, iface_ref, idx);
+}
+
+/* Returns the value to use for the in-charge parameter when making a
+ call to a function with the indicated NAME.
+
+ FIXME:Can't we find a neater way to do this mapping? */
+
+tree
+in_charge_arg_for_name (tree name)
+{
+ if (name == base_ctor_identifier
+ || name == base_dtor_identifier)
+ return integer_zero_node;
+ else if (name == complete_ctor_identifier)
+ return integer_one_node;
+ else if (name == complete_dtor_identifier)
+ return integer_two_node;
+ else if (name == deleting_dtor_identifier)
+ return integer_three_node;
+
+ /* This function should only be called with one of the names listed
+ above. */
+ gcc_unreachable ();
+ return NULL_TREE;
+}
+
+/* Build a call to a constructor, destructor, or an assignment
+ operator for INSTANCE, an expression with class type. NAME
+ indicates the special member function to call; *ARGS are the
+ arguments. ARGS may be NULL. This may change ARGS. BINFO
+ indicates the base of INSTANCE that is to be passed as the `this'
+ parameter to the member function called.
+
+ FLAGS are the LOOKUP_* flags to use when processing the call.
+
+ If NAME indicates a complete object constructor, INSTANCE may be
+ NULL_TREE. In this case, the caller will call build_cplus_new to
+ store the newly constructed object into a VAR_DECL. */
+
+tree
+build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
+ tree binfo, int flags, tsubst_flags_t complain)
+{
+ tree fns;
+ /* The type of the subobject to be constructed or destroyed. */
+ tree class_type;
+ vec<tree, va_gc> *allocated = NULL;
+ tree ret;
+
+ gcc_assert (name == complete_ctor_identifier
+ || name == base_ctor_identifier
+ || name == complete_dtor_identifier
+ || name == base_dtor_identifier
+ || name == deleting_dtor_identifier
+ || name == ansi_assopname (NOP_EXPR));
+ if (TYPE_P (binfo))
+ {
+ /* Resolve the name. */
+ if (!complete_type_or_maybe_complain (binfo, NULL_TREE, complain))
+ return error_mark_node;
+
+ binfo = TYPE_BINFO (binfo);
+ }
+
+ gcc_assert (binfo != NULL_TREE);
+
+ class_type = BINFO_TYPE (binfo);
+
+ /* Handle the special case where INSTANCE is NULL_TREE. */
+ if (name == complete_ctor_identifier && !instance)
+ {
+ instance = build_int_cst (build_pointer_type (class_type), 0);
+ instance = build1 (INDIRECT_REF, class_type, instance);
+ }
+ else
+ {
+ if (name == complete_dtor_identifier
+ || name == base_dtor_identifier
+ || name == deleting_dtor_identifier)
+ gcc_assert (args == NULL || vec_safe_is_empty (*args));
+
+ /* Convert to the base class, if necessary. */
+ if (!same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (instance), BINFO_TYPE (binfo)))
+ {
+ if (name != ansi_assopname (NOP_EXPR))
+ /* For constructors and destructors, either the base is
+ non-virtual, or it is virtual but we are doing the
+ conversion from a constructor or destructor for the
+ complete object. In either case, we can convert
+ statically. */
+ instance = convert_to_base_statically (instance, binfo);
+ else
+ /* However, for assignment operators, we must convert
+ dynamically if the base is virtual. */
+ instance = build_base_path (PLUS_EXPR, instance,
+ binfo, /*nonnull=*/1, complain);
+ }
+ }
+
+ gcc_assert (instance != NULL_TREE);
+
+ fns = lookup_fnfields (binfo, name, 1);
+
+ /* When making a call to a constructor or destructor for a subobject
+ that uses virtual base classes, pass down a pointer to a VTT for
+ the subobject. */
+ if ((name == base_ctor_identifier
+ || name == base_dtor_identifier)
+ && CLASSTYPE_VBASECLASSES (class_type))
+ {
+ tree vtt;
+ tree sub_vtt;
+
+ /* If the current function is a complete object constructor
+ or destructor, then we fetch the VTT directly.
+ Otherwise, we look it up using the VTT we were given. */
+ vtt = DECL_CHAIN (CLASSTYPE_VTABLES (current_class_type));
+ vtt = decay_conversion (vtt, complain);
+ if (vtt == error_mark_node)
+ return error_mark_node;
+ vtt = build3 (COND_EXPR, TREE_TYPE (vtt),
+ build2 (EQ_EXPR, boolean_type_node,
+ current_in_charge_parm, integer_zero_node),
+ current_vtt_parm,
+ vtt);
+ if (BINFO_SUBVTT_INDEX (binfo))
+ sub_vtt = fold_build_pointer_plus (vtt, BINFO_SUBVTT_INDEX (binfo));
+ else
+ sub_vtt = vtt;
+
+ if (args == NULL)
+ {
+ allocated = make_tree_vector ();
+ args = &allocated;
+ }
+
+ vec_safe_insert (*args, 0, sub_vtt);
+ }
+
+ ret = build_new_method_call (instance, fns, args,
+ TYPE_BINFO (BINFO_TYPE (binfo)),
+ flags, /*fn=*/NULL,
+ complain);
+
+ if (allocated != NULL)
+ release_tree_vector (allocated);
+
+ if ((complain & tf_error)
+ && (flags & LOOKUP_DELEGATING_CONS)
+ && name == complete_ctor_identifier
+ && TREE_CODE (ret) == CALL_EXPR
+ && (DECL_ABSTRACT_ORIGIN (TREE_OPERAND (CALL_EXPR_FN (ret), 0))
+ == current_function_decl))
+ error ("constructor delegates to itself");
+
+ return ret;
+}
+
+/* Return the NAME, as a C string. The NAME indicates a function that
+ is a member of TYPE. *FREE_P is set to true if the caller must
+ free the memory returned.
+
+ Rather than go through all of this, we should simply set the names
+ of constructors and destructors appropriately, and dispense with
+ ctor_identifier, dtor_identifier, etc. */
+
+static char *
+name_as_c_string (tree name, tree type, bool *free_p)
+{
+ char *pretty_name;
+
+ /* Assume that we will not allocate memory. */
+ *free_p = false;
+ /* Constructors and destructors are special. */
+ if (IDENTIFIER_CTOR_OR_DTOR_P (name))
+ {
+ pretty_name
+ = CONST_CAST (char *, identifier_to_locale (IDENTIFIER_POINTER (constructor_name (type))));
+ /* For a destructor, add the '~'. */
+ if (name == complete_dtor_identifier
+ || name == base_dtor_identifier
+ || name == deleting_dtor_identifier)
+ {
+ pretty_name = concat ("~", pretty_name, NULL);
+ /* Remember that we need to free the memory allocated. */
+ *free_p = true;
+ }
+ }
+ else if (IDENTIFIER_TYPENAME_P (name))
+ {
+ pretty_name = concat ("operator ",
+ type_as_string_translate (TREE_TYPE (name),
+ TFF_PLAIN_IDENTIFIER),
+ NULL);
+ /* Remember that we need to free the memory allocated. */
+ *free_p = true;
+ }
+ else
+ pretty_name = CONST_CAST (char *, identifier_to_locale (IDENTIFIER_POINTER (name)));
+
+ return pretty_name;
+}
+
+/* Build a call to "INSTANCE.FN (ARGS)". If FN_P is non-NULL, it will
+ be set, upon return, to the function called. ARGS may be NULL.
+ This may change ARGS. */
+
+static tree
+build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
+ tree conversion_path, int flags,
+ tree *fn_p, tsubst_flags_t complain)
+{
+ struct z_candidate *candidates = 0, *cand;
+ tree explicit_targs = NULL_TREE;
+ tree basetype = NULL_TREE;
+ tree access_binfo, binfo;
+ tree optype;
+ tree first_mem_arg = NULL_TREE;
+ tree name;
+ bool skip_first_for_error;
+ vec<tree, va_gc> *user_args;
+ tree call;
+ tree fn;
+ int template_only = 0;
+ bool any_viable_p;
+ tree orig_instance;
+ tree orig_fns;
+ vec<tree, va_gc> *orig_args = NULL;
+ void *p;
+
+ gcc_assert (instance != NULL_TREE);
+
+ /* We don't know what function we're going to call, yet. */
+ if (fn_p)
+ *fn_p = NULL_TREE;
+
+ if (error_operand_p (instance)
+ || !fns || error_operand_p (fns))
+ return error_mark_node;
+
+ if (!BASELINK_P (fns))
+ {
+ if (complain & tf_error)
+ error ("call to non-function %qD", fns);
+ return error_mark_node;
+ }
+
+ orig_instance = instance;
+ orig_fns = fns;
+
+ /* Dismantle the baselink to collect all the information we need. */
+ if (!conversion_path)
+ conversion_path = BASELINK_BINFO (fns);
+ access_binfo = BASELINK_ACCESS_BINFO (fns);
+ binfo = BASELINK_BINFO (fns);
+ optype = BASELINK_OPTYPE (fns);
+ fns = BASELINK_FUNCTIONS (fns);
+ if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
+ {
+ explicit_targs = TREE_OPERAND (fns, 1);
+ fns = TREE_OPERAND (fns, 0);
+ template_only = 1;
+ }
+ gcc_assert (TREE_CODE (fns) == FUNCTION_DECL
+ || TREE_CODE (fns) == TEMPLATE_DECL
+ || TREE_CODE (fns) == OVERLOAD);
+ fn = get_first_fn (fns);
+ name = DECL_NAME (fn);
+
+ basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance));
+ gcc_assert (CLASS_TYPE_P (basetype));
+
+ if (processing_template_decl)
+ {
+ orig_args = args == NULL ? NULL : make_tree_vector_copy (*args);
+ instance = build_non_dependent_expr (instance);
+ if (args != NULL)
+ make_args_non_dependent (*args);
+ }
+
+ user_args = args == NULL ? NULL : *args;
+ /* Under DR 147 A::A() is an invalid constructor call,
+ not a functional cast. */
+ if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
+ {
+ if (! (complain & tf_error))
+ return error_mark_node;
+
+ if (permerror (input_location,
+ "cannot call constructor %<%T::%D%> directly",
+ basetype, name))
+ inform (input_location, "for a function-style cast, remove the "
+ "redundant %<::%D%>", name);
+ call = build_functional_cast (basetype, build_tree_list_vec (user_args),
+ complain);
+ return call;
+ }
+
+ /* Figure out whether to skip the first argument for the error
+ message we will display to users if an error occurs. We don't
+ want to display any compiler-generated arguments. The "this"
+ pointer hasn't been added yet. However, we must remove the VTT
+ pointer if this is a call to a base-class constructor or
+ destructor. */
+ skip_first_for_error = false;
+ if (IDENTIFIER_CTOR_OR_DTOR_P (name))
+ {
+ /* Callers should explicitly indicate whether they want to construct
+ the complete object or just the part without virtual bases. */
+ gcc_assert (name != ctor_identifier);
+ /* Similarly for destructors. */
+ gcc_assert (name != dtor_identifier);
+ /* Remove the VTT pointer, if present. */
+ if ((name == base_ctor_identifier || name == base_dtor_identifier)
+ && CLASSTYPE_VBASECLASSES (basetype))
+ skip_first_for_error = true;
+ }
+
+ /* Process the argument list. */
+ if (args != NULL && *args != NULL)
+ {
+ *args = resolve_args (*args, complain);
+ if (*args == NULL)
+ return error_mark_node;
+ }
+
+ /* Consider the object argument to be used even if we end up selecting a
+ static member function. */
+ instance = mark_type_use (instance);
+
+ /* It's OK to call destructors and constructors on cv-qualified objects.
+ Therefore, convert the INSTANCE to the unqualified type, if
+ necessary. */
+ if (DECL_DESTRUCTOR_P (fn)
+ || DECL_CONSTRUCTOR_P (fn))
+ {
+ if (!same_type_p (basetype, TREE_TYPE (instance)))
+ {
+ instance = build_this (instance);
+ instance = build_nop (build_pointer_type (basetype), instance);
+ instance = build_fold_indirect_ref (instance);
+ }
+ }
+ if (DECL_DESTRUCTOR_P (fn))
+ name = complete_dtor_identifier;
+
+ first_mem_arg = instance;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ /* If CONSTRUCTOR_IS_DIRECT_INIT is set, this was a T{ } form
+ initializer, not T({ }). */
+ if (DECL_CONSTRUCTOR_P (fn) && args != NULL && !vec_safe_is_empty (*args)
+ && BRACE_ENCLOSED_INITIALIZER_P ((**args)[0])
+ && CONSTRUCTOR_IS_DIRECT_INIT ((**args)[0]))
+ {
+ tree init_list = (**args)[0];
+ tree init = NULL_TREE;
+
+ gcc_assert ((*args)->length () == 1
+ && !(flags & LOOKUP_ONLYCONVERTING));
+
+ /* If the initializer list has no elements and T is a class type with
+ a default constructor, the object is value-initialized. Handle
+ this here so we don't need to handle it wherever we use
+ build_special_member_call. */
+ if (CONSTRUCTOR_NELTS (init_list) == 0
+ && TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
+ /* For a user-provided default constructor, use the normal
+ mechanisms so that protected access works. */
+ && !type_has_user_provided_default_constructor (basetype)
+ && !processing_template_decl)
+ init = build_value_init (basetype, complain);
+
+ /* If BASETYPE is an aggregate, we need to do aggregate
+ initialization. */
+ else if (CP_AGGREGATE_TYPE_P (basetype))
+ init = digest_init (basetype, init_list, complain);
+
+ if (init)
+ {
+ if (INDIRECT_REF_P (instance)
+ && integer_zerop (TREE_OPERAND (instance, 0)))
+ return get_target_expr_sfinae (init, complain);
+ init = build2 (INIT_EXPR, TREE_TYPE (instance), instance, init);
+ TREE_SIDE_EFFECTS (init) = true;
+ return init;
+ }
+
+ /* Otherwise go ahead with overload resolution. */
+ add_list_candidates (fns, first_mem_arg, init_list,
+ basetype, explicit_targs, template_only,
+ conversion_path, access_binfo, flags,
+ &candidates, complain);
+ }
+ else
+ {
+ add_candidates (fns, first_mem_arg, user_args, optype,
+ explicit_targs, template_only, conversion_path,
+ access_binfo, flags, &candidates, complain);
+ }
+ any_viable_p = false;
+ candidates = splice_viable (candidates, pedantic, &any_viable_p);
+
+ if (!any_viable_p)
+ {
+ if (complain & tf_error)
+ {
+ if (!COMPLETE_OR_OPEN_TYPE_P (basetype))
+ cxx_incomplete_type_error (instance, basetype);
+ else if (optype)
+ error ("no matching function for call to %<%T::operator %T(%A)%#V%>",
+ basetype, optype, build_tree_list_vec (user_args),
+ TREE_TYPE (instance));
+ else
+ {
+ char *pretty_name;
+ bool free_p;
+ tree arglist;
+
+ pretty_name = name_as_c_string (name, basetype, &free_p);
+ arglist = build_tree_list_vec (user_args);
+ if (skip_first_for_error)
+ arglist = TREE_CHAIN (arglist);
+ error ("no matching function for call to %<%T::%s(%A)%#V%>",
+ basetype, pretty_name, arglist,
+ TREE_TYPE (instance));
+ if (free_p)
+ free (pretty_name);
+ }
+ print_z_candidates (location_of (name), candidates);
+ }
+ call = error_mark_node;
+ }
+ else
+ {
+ cand = tourney (candidates, complain);
+ if (cand == 0)
+ {
+ char *pretty_name;
+ bool free_p;
+ tree arglist;
+
+ if (complain & tf_error)
+ {
+ pretty_name = name_as_c_string (name, basetype, &free_p);
+ arglist = build_tree_list_vec (user_args);
+ if (skip_first_for_error)
+ arglist = TREE_CHAIN (arglist);
+ error ("call of overloaded %<%s(%A)%> is ambiguous", pretty_name,
+ arglist);
+ print_z_candidates (location_of (name), candidates);
+ if (free_p)
+ free (pretty_name);
+ }
+ call = error_mark_node;
+ }
+ else
+ {
+ fn = cand->fn;
+ call = NULL_TREE;
+
+ if (!(flags & LOOKUP_NONVIRTUAL)
+ && DECL_PURE_VIRTUAL_P (fn)
+ && instance == current_class_ref
+ && (complain & tf_warning))
+ {
+ /* This is not an error, it is runtime undefined
+ behavior. */
+ if (!current_function_decl)
+ warning (0, "pure virtual %q#D called from "
+ "non-static data member initializer", fn);
+ else if (DECL_CONSTRUCTOR_P (current_function_decl)
+ || DECL_DESTRUCTOR_P (current_function_decl))
+ warning (0, (DECL_CONSTRUCTOR_P (current_function_decl)
+ ? "pure virtual %q#D called from constructor"
+ : "pure virtual %q#D called from destructor"),
+ fn);
+ }
+
+ if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
+ && is_dummy_object (instance))
+ {
+ instance = maybe_resolve_dummy (instance);
+ if (instance == error_mark_node)
+ call = error_mark_node;
+ else if (!is_dummy_object (instance))
+ {
+ /* We captured 'this' in the current lambda now that
+ we know we really need it. */
+ cand->first_arg = instance;
+ }
+ else
+ {
+ if (complain & tf_error)
+ error ("cannot call member function %qD without object",
+ fn);
+ call = error_mark_node;
+ }
+ }
+
+ if (call != error_mark_node)
+ {
+ /* Optimize away vtable lookup if we know that this
+ function can't be overridden. We need to check if
+ the context and the type where we found fn are the same,
+ actually FN might be defined in a different class
+ type because of a using-declaration. In this case, we
+ do not want to perform a non-virtual call. */
+ if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL)
+ && same_type_ignoring_top_level_qualifiers_p
+ (DECL_CONTEXT (fn), BINFO_TYPE (binfo))
+ && resolves_to_fixed_type_p (instance, 0))
+ flags |= LOOKUP_NONVIRTUAL;
+ if (explicit_targs)
+ flags |= LOOKUP_EXPLICIT_TMPL_ARGS;
+ /* Now we know what function is being called. */
+ if (fn_p)
+ *fn_p = fn;
+ /* Build the actual CALL_EXPR. */
+ call = build_over_call (cand, flags, complain);
+ /* In an expression of the form `a->f()' where `f' turns
+ out to be a static member function, `a' is
+ none-the-less evaluated. */
+ if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
+ && !is_dummy_object (instance)
+ && TREE_SIDE_EFFECTS (instance))
+ call = build2 (COMPOUND_EXPR, TREE_TYPE (call),
+ instance, call);
+ else if (call != error_mark_node
+ && DECL_DESTRUCTOR_P (cand->fn)
+ && !VOID_TYPE_P (TREE_TYPE (call)))
+ /* An explicit call of the form "x->~X()" has type
+ "void". However, on platforms where destructors
+ return "this" (i.e., those where
+ targetm.cxx.cdtor_returns_this is true), such calls
+ will appear to have a return value of pointer type
+ to the low-level call machinery. We do not want to
+ change the low-level machinery, since we want to be
+ able to optimize "delete f()" on such platforms as
+ "operator delete(~X(f()))" (rather than generating
+ "t = f(), ~X(t), operator delete (t)"). */
+ call = build_nop (void_type_node, call);
+ }
+ }
+ }
+
+ if (processing_template_decl && call != error_mark_node)
+ {
+ bool cast_to_void = false;
+
+ if (TREE_CODE (call) == COMPOUND_EXPR)
+ call = TREE_OPERAND (call, 1);
+ else if (TREE_CODE (call) == NOP_EXPR)
+ {
+ cast_to_void = true;
+ call = TREE_OPERAND (call, 0);
+ }
+ if (INDIRECT_REF_P (call))
+ call = TREE_OPERAND (call, 0);
+ call = (build_min_non_dep_call_vec
+ (call,
+ build_min (COMPONENT_REF, TREE_TYPE (CALL_EXPR_FN (call)),
+ orig_instance, orig_fns, NULL_TREE),
+ orig_args));
+ SET_EXPR_LOCATION (call, input_location);
+ call = convert_from_reference (call);
+ if (cast_to_void)
+ call = build_nop (void_type_node, call);
+ }
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ if (orig_args != NULL)
+ release_tree_vector (orig_args);
+
+ return call;
+}
+
+/* Wrapper for above. */
+
+tree
+build_new_method_call (tree instance, tree fns, vec<tree, va_gc> **args,
+ tree conversion_path, int flags,
+ tree *fn_p, tsubst_flags_t complain)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_OVERLOAD);
+ ret = build_new_method_call_1 (instance, fns, args, conversion_path, flags,
+ fn_p, complain);
+ timevar_cond_stop (TV_OVERLOAD, subtime);
+ return ret;
+}
+
+/* Returns true iff standard conversion sequence ICS1 is a proper
+ subsequence of ICS2. */
+
+static bool
+is_subseq (conversion *ics1, conversion *ics2)
+{
+ /* We can assume that a conversion of the same code
+ between the same types indicates a subsequence since we only get
+ here if the types we are converting from are the same. */
+
+ while (ics1->kind == ck_rvalue
+ || ics1->kind == ck_lvalue)
+ ics1 = next_conversion (ics1);
+
+ while (1)
+ {
+ while (ics2->kind == ck_rvalue
+ || ics2->kind == ck_lvalue)
+ ics2 = next_conversion (ics2);
+
+ if (ics2->kind == ck_user
+ || ics2->kind == ck_ambig
+ || ics2->kind == ck_aggr
+ || ics2->kind == ck_list
+ || ics2->kind == ck_identity)
+ /* At this point, ICS1 cannot be a proper subsequence of
+ ICS2. We can get a USER_CONV when we are comparing the
+ second standard conversion sequence of two user conversion
+ sequences. */
+ return false;
+
+ ics2 = next_conversion (ics2);
+
+ if (ics2->kind == ics1->kind
+ && same_type_p (ics2->type, ics1->type)
+ && same_type_p (next_conversion (ics2)->type,
+ next_conversion (ics1)->type))
+ return true;
+ }
+}
+
+/* Returns nonzero iff DERIVED is derived from BASE. The inputs may
+ be any _TYPE nodes. */
+
+bool
+is_properly_derived_from (tree derived, tree base)
+{
+ if (!CLASS_TYPE_P (derived) || !CLASS_TYPE_P (base))
+ return false;
+
+ /* We only allow proper derivation here. The DERIVED_FROM_P macro
+ considers every class derived from itself. */
+ return (!same_type_ignoring_top_level_qualifiers_p (derived, base)
+ && DERIVED_FROM_P (base, derived));
+}
+
+/* We build the ICS for an implicit object parameter as a pointer
+ conversion sequence. However, such a sequence should be compared
+ as if it were a reference conversion sequence. If ICS is the
+ implicit conversion sequence for an implicit object parameter,
+ modify it accordingly. */
+
+static void
+maybe_handle_implicit_object (conversion **ics)
+{
+ if ((*ics)->this_p)
+ {
+ /* [over.match.funcs]
+
+ For non-static member functions, the type of the
+ implicit object parameter is "reference to cv X"
+ where X is the class of which the function is a
+ member and cv is the cv-qualification on the member
+ function declaration. */
+ conversion *t = *ics;
+ tree reference_type;
+
+ /* The `this' parameter is a pointer to a class type. Make the
+ implicit conversion talk about a reference to that same class
+ type. */
+ reference_type = TREE_TYPE (t->type);
+ reference_type = build_reference_type (reference_type);
+
+ if (t->kind == ck_qual)
+ t = next_conversion (t);
+ if (t->kind == ck_ptr)
+ t = next_conversion (t);
+ t = build_identity_conv (TREE_TYPE (t->type), NULL_TREE);
+ t = direct_reference_binding (reference_type, t);
+ t->this_p = 1;
+ t->rvaluedness_matches_p = 0;
+ *ics = t;
+ }
+}
+
+/* If *ICS is a REF_BIND set *ICS to the remainder of the conversion,
+ and return the initial reference binding conversion. Otherwise,
+ leave *ICS unchanged and return NULL. */
+
+static conversion *
+maybe_handle_ref_bind (conversion **ics)
+{
+ if ((*ics)->kind == ck_ref_bind)
+ {
+ conversion *old_ics = *ics;
+ *ics = next_conversion (old_ics);
+ (*ics)->user_conv_p = old_ics->user_conv_p;
+ return old_ics;
+ }
+
+ return NULL;
+}
+
+/* Compare two implicit conversion sequences according to the rules set out in
+ [over.ics.rank]. Return values:
+
+ 1: ics1 is better than ics2
+ -1: ics2 is better than ics1
+ 0: ics1 and ics2 are indistinguishable */
+
+static int
+compare_ics (conversion *ics1, conversion *ics2)
+{
+ tree from_type1;
+ tree from_type2;
+ tree to_type1;
+ tree to_type2;
+ tree deref_from_type1 = NULL_TREE;
+ tree deref_from_type2 = NULL_TREE;
+ tree deref_to_type1 = NULL_TREE;
+ tree deref_to_type2 = NULL_TREE;
+ conversion_rank rank1, rank2;
+
+ /* REF_BINDING is nonzero if the result of the conversion sequence
+ is a reference type. In that case REF_CONV is the reference
+ binding conversion. */
+ conversion *ref_conv1;
+ conversion *ref_conv2;
+
+ /* Handle implicit object parameters. */
+ maybe_handle_implicit_object (&ics1);
+ maybe_handle_implicit_object (&ics2);
+
+ /* Handle reference parameters. */
+ ref_conv1 = maybe_handle_ref_bind (&ics1);
+ ref_conv2 = maybe_handle_ref_bind (&ics2);
+
+ /* List-initialization sequence L1 is a better conversion sequence than
+ list-initialization sequence L2 if L1 converts to
+ std::initializer_list<X> for some X and L2 does not. */
+ if (ics1->kind == ck_list && ics2->kind != ck_list)
+ return 1;
+ if (ics2->kind == ck_list && ics1->kind != ck_list)
+ return -1;
+
+ /* [over.ics.rank]
+
+ When comparing the basic forms of implicit conversion sequences (as
+ defined in _over.best.ics_)
+
+ --a standard conversion sequence (_over.ics.scs_) is a better
+ conversion sequence than a user-defined conversion sequence
+ or an ellipsis conversion sequence, and
+
+ --a user-defined conversion sequence (_over.ics.user_) is a
+ better conversion sequence than an ellipsis conversion sequence
+ (_over.ics.ellipsis_). */
+ rank1 = CONVERSION_RANK (ics1);
+ rank2 = CONVERSION_RANK (ics2);
+
+ if (rank1 > rank2)
+ return -1;
+ else if (rank1 < rank2)
+ return 1;
+
+ if (rank1 == cr_bad)
+ {
+ /* Both ICS are bad. We try to make a decision based on what would
+ have happened if they'd been good. This is not an extension,
+ we'll still give an error when we build up the call; this just
+ helps us give a more helpful error message. */
+ rank1 = BAD_CONVERSION_RANK (ics1);
+ rank2 = BAD_CONVERSION_RANK (ics2);
+
+ if (rank1 > rank2)
+ return -1;
+ else if (rank1 < rank2)
+ return 1;
+
+ /* We couldn't make up our minds; try to figure it out below. */
+ }
+
+ if (ics1->ellipsis_p)
+ /* Both conversions are ellipsis conversions. */
+ return 0;
+
+ /* User-defined conversion sequence U1 is a better conversion sequence
+ than another user-defined conversion sequence U2 if they contain the
+ same user-defined conversion operator or constructor and if the sec-
+ ond standard conversion sequence of U1 is better than the second
+ standard conversion sequence of U2. */
+
+ /* Handle list-conversion with the same code even though it isn't always
+ ranked as a user-defined conversion and it doesn't have a second
+ standard conversion sequence; it will still have the desired effect.
+ Specifically, we need to do the reference binding comparison at the
+ end of this function. */
+
+ if (ics1->user_conv_p || ics1->kind == ck_list || ics1->kind == ck_aggr)
+ {
+ conversion *t1;
+ conversion *t2;
+
+ for (t1 = ics1; t1->kind != ck_user; t1 = next_conversion (t1))
+ if (t1->kind == ck_ambig || t1->kind == ck_aggr
+ || t1->kind == ck_list)
+ break;
+ for (t2 = ics2; t2->kind != ck_user; t2 = next_conversion (t2))
+ if (t2->kind == ck_ambig || t2->kind == ck_aggr
+ || t2->kind == ck_list)
+ break;
+
+ if (t1->kind != t2->kind)
+ return 0;
+ else if (t1->kind == ck_user)
+ {
+ if (t1->cand->fn != t2->cand->fn)
+ return 0;
+ }
+ else
+ {
+ /* For ambiguous or aggregate conversions, use the target type as
+ a proxy for the conversion function. */
+ if (!same_type_ignoring_top_level_qualifiers_p (t1->type, t2->type))
+ return 0;
+ }
+
+ /* We can just fall through here, after setting up
+ FROM_TYPE1 and FROM_TYPE2. */
+ from_type1 = t1->type;
+ from_type2 = t2->type;
+ }
+ else
+ {
+ conversion *t1;
+ conversion *t2;
+
+ /* We're dealing with two standard conversion sequences.
+
+ [over.ics.rank]
+
+ Standard conversion sequence S1 is a better conversion
+ sequence than standard conversion sequence S2 if
+
+ --S1 is a proper subsequence of S2 (comparing the conversion
+ sequences in the canonical form defined by _over.ics.scs_,
+ excluding any Lvalue Transformation; the identity
+ conversion sequence is considered to be a subsequence of
+ any non-identity conversion sequence */
+
+ t1 = ics1;
+ while (t1->kind != ck_identity)
+ t1 = next_conversion (t1);
+ from_type1 = t1->type;
+
+ t2 = ics2;
+ while (t2->kind != ck_identity)
+ t2 = next_conversion (t2);
+ from_type2 = t2->type;
+ }
+
+ /* One sequence can only be a subsequence of the other if they start with
+ the same type. They can start with different types when comparing the
+ second standard conversion sequence in two user-defined conversion
+ sequences. */
+ if (same_type_p (from_type1, from_type2))
+ {
+ if (is_subseq (ics1, ics2))
+ return 1;
+ if (is_subseq (ics2, ics1))
+ return -1;
+ }
+
+ /* [over.ics.rank]
+
+ Or, if not that,
+
+ --the rank of S1 is better than the rank of S2 (by the rules
+ defined below):
+
+ Standard conversion sequences are ordered by their ranks: an Exact
+ Match is a better conversion than a Promotion, which is a better
+ conversion than a Conversion.
+
+ Two conversion sequences with the same rank are indistinguishable
+ unless one of the following rules applies:
+
+ --A conversion that does not a convert a pointer, pointer to member,
+ or std::nullptr_t to bool is better than one that does.
+
+ The ICS_STD_RANK automatically handles the pointer-to-bool rule,
+ so that we do not have to check it explicitly. */
+ if (ics1->rank < ics2->rank)
+ return 1;
+ else if (ics2->rank < ics1->rank)
+ return -1;
+
+ to_type1 = ics1->type;
+ to_type2 = ics2->type;
+
+ /* A conversion from scalar arithmetic type to complex is worse than a
+ conversion between scalar arithmetic types. */
+ if (same_type_p (from_type1, from_type2)
+ && ARITHMETIC_TYPE_P (from_type1)
+ && ARITHMETIC_TYPE_P (to_type1)
+ && ARITHMETIC_TYPE_P (to_type2)
+ && ((TREE_CODE (to_type1) == COMPLEX_TYPE)
+ != (TREE_CODE (to_type2) == COMPLEX_TYPE)))
+ {
+ if (TREE_CODE (to_type1) == COMPLEX_TYPE)
+ return -1;
+ else
+ return 1;
+ }
+
+ if (TYPE_PTR_P (from_type1)
+ && TYPE_PTR_P (from_type2)
+ && TYPE_PTR_P (to_type1)
+ && TYPE_PTR_P (to_type2))
+ {
+ deref_from_type1 = TREE_TYPE (from_type1);
+ deref_from_type2 = TREE_TYPE (from_type2);
+ deref_to_type1 = TREE_TYPE (to_type1);
+ deref_to_type2 = TREE_TYPE (to_type2);
+ }
+ /* The rules for pointers to members A::* are just like the rules
+ for pointers A*, except opposite: if B is derived from A then
+ A::* converts to B::*, not vice versa. For that reason, we
+ switch the from_ and to_ variables here. */
+ else if ((TYPE_PTRDATAMEM_P (from_type1) && TYPE_PTRDATAMEM_P (from_type2)
+ && TYPE_PTRDATAMEM_P (to_type1) && TYPE_PTRDATAMEM_P (to_type2))
+ || (TYPE_PTRMEMFUNC_P (from_type1)
+ && TYPE_PTRMEMFUNC_P (from_type2)
+ && TYPE_PTRMEMFUNC_P (to_type1)
+ && TYPE_PTRMEMFUNC_P (to_type2)))
+ {
+ deref_to_type1 = TYPE_PTRMEM_CLASS_TYPE (from_type1);
+ deref_to_type2 = TYPE_PTRMEM_CLASS_TYPE (from_type2);
+ deref_from_type1 = TYPE_PTRMEM_CLASS_TYPE (to_type1);
+ deref_from_type2 = TYPE_PTRMEM_CLASS_TYPE (to_type2);
+ }
+
+ if (deref_from_type1 != NULL_TREE
+ && RECORD_OR_UNION_CODE_P (TREE_CODE (deref_from_type1))
+ && RECORD_OR_UNION_CODE_P (TREE_CODE (deref_from_type2)))
+ {
+ /* This was one of the pointer or pointer-like conversions.
+
+ [over.ics.rank]
+
+ --If class B is derived directly or indirectly from class A,
+ conversion of B* to A* is better than conversion of B* to
+ void*, and conversion of A* to void* is better than
+ conversion of B* to void*. */
+ if (VOID_TYPE_P (deref_to_type1)
+ && VOID_TYPE_P (deref_to_type2))
+ {
+ if (is_properly_derived_from (deref_from_type1,
+ deref_from_type2))
+ return -1;
+ else if (is_properly_derived_from (deref_from_type2,
+ deref_from_type1))
+ return 1;
+ }
+ else if (VOID_TYPE_P (deref_to_type1)
+ || VOID_TYPE_P (deref_to_type2))
+ {
+ if (same_type_p (deref_from_type1, deref_from_type2))
+ {
+ if (VOID_TYPE_P (deref_to_type2))
+ {
+ if (is_properly_derived_from (deref_from_type1,
+ deref_to_type1))
+ return 1;
+ }
+ /* We know that DEREF_TO_TYPE1 is `void' here. */
+ else if (is_properly_derived_from (deref_from_type1,
+ deref_to_type2))
+ return -1;
+ }
+ }
+ else if (RECORD_OR_UNION_CODE_P (TREE_CODE (deref_to_type1))
+ && RECORD_OR_UNION_CODE_P (TREE_CODE (deref_to_type2)))
+ {
+ /* [over.ics.rank]
+
+ --If class B is derived directly or indirectly from class A
+ and class C is derived directly or indirectly from B,
+
+ --conversion of C* to B* is better than conversion of C* to
+ A*,
+
+ --conversion of B* to A* is better than conversion of C* to
+ A* */
+ if (same_type_p (deref_from_type1, deref_from_type2))
+ {
+ if (is_properly_derived_from (deref_to_type1,
+ deref_to_type2))
+ return 1;
+ else if (is_properly_derived_from (deref_to_type2,
+ deref_to_type1))
+ return -1;
+ }
+ else if (same_type_p (deref_to_type1, deref_to_type2))
+ {
+ if (is_properly_derived_from (deref_from_type2,
+ deref_from_type1))
+ return 1;
+ else if (is_properly_derived_from (deref_from_type1,
+ deref_from_type2))
+ return -1;
+ }
+ }
+ }
+ else if (CLASS_TYPE_P (non_reference (from_type1))
+ && same_type_p (from_type1, from_type2))
+ {
+ tree from = non_reference (from_type1);
+
+ /* [over.ics.rank]
+
+ --binding of an expression of type C to a reference of type
+ B& is better than binding an expression of type C to a
+ reference of type A&
+
+ --conversion of C to B is better than conversion of C to A, */
+ if (is_properly_derived_from (from, to_type1)
+ && is_properly_derived_from (from, to_type2))
+ {
+ if (is_properly_derived_from (to_type1, to_type2))
+ return 1;
+ else if (is_properly_derived_from (to_type2, to_type1))
+ return -1;
+ }
+ }
+ else if (CLASS_TYPE_P (non_reference (to_type1))
+ && same_type_p (to_type1, to_type2))
+ {
+ tree to = non_reference (to_type1);
+
+ /* [over.ics.rank]
+
+ --binding of an expression of type B to a reference of type
+ A& is better than binding an expression of type C to a
+ reference of type A&,
+
+ --conversion of B to A is better than conversion of C to A */
+ if (is_properly_derived_from (from_type1, to)
+ && is_properly_derived_from (from_type2, to))
+ {
+ if (is_properly_derived_from (from_type2, from_type1))
+ return 1;
+ else if (is_properly_derived_from (from_type1, from_type2))
+ return -1;
+ }
+ }
+
+ /* [over.ics.rank]
+
+ --S1 and S2 differ only in their qualification conversion and yield
+ similar types T1 and T2 (_conv.qual_), respectively, and the cv-
+ qualification signature of type T1 is a proper subset of the cv-
+ qualification signature of type T2 */
+ if (ics1->kind == ck_qual
+ && ics2->kind == ck_qual
+ && same_type_p (from_type1, from_type2))
+ {
+ int result = comp_cv_qual_signature (to_type1, to_type2);
+ if (result != 0)
+ return result;
+ }
+
+ /* [over.ics.rank]
+
+ --S1 and S2 are reference bindings (_dcl.init.ref_) and neither refers
+ to an implicit object parameter, and either S1 binds an lvalue reference
+ to an lvalue and S2 binds an rvalue reference or S1 binds an rvalue
+ reference to an rvalue and S2 binds an lvalue reference
+ (C++0x draft standard, 13.3.3.2)
+
+ --S1 and S2 are reference bindings (_dcl.init.ref_), and the
+ types to which the references refer are the same type except for
+ top-level cv-qualifiers, and the type to which the reference
+ initialized by S2 refers is more cv-qualified than the type to
+ which the reference initialized by S1 refers.
+
+ DR 1328 [over.match.best]: the context is an initialization by
+ conversion function for direct reference binding (13.3.1.6) of a
+ reference to function type, the return type of F1 is the same kind of
+ reference (i.e. lvalue or rvalue) as the reference being initialized,
+ and the return type of F2 is not. */
+
+ if (ref_conv1 && ref_conv2)
+ {
+ if (!ref_conv1->this_p && !ref_conv2->this_p
+ && (ref_conv1->rvaluedness_matches_p
+ != ref_conv2->rvaluedness_matches_p)
+ && (same_type_p (ref_conv1->type, ref_conv2->type)
+ || (TYPE_REF_IS_RVALUE (ref_conv1->type)
+ != TYPE_REF_IS_RVALUE (ref_conv2->type))))
+ {
+ return (ref_conv1->rvaluedness_matches_p
+ - ref_conv2->rvaluedness_matches_p);
+ }
+
+ if (same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2))
+ return comp_cv_qualification (TREE_TYPE (ref_conv2->type),
+ TREE_TYPE (ref_conv1->type));
+ }
+
+ /* Neither conversion sequence is better than the other. */
+ return 0;
+}
+
+/* The source type for this standard conversion sequence. */
+
+static tree
+source_type (conversion *t)
+{
+ for (;; t = next_conversion (t))
+ {
+ if (t->kind == ck_user
+ || t->kind == ck_ambig
+ || t->kind == ck_identity)
+ return t->type;
+ }
+ gcc_unreachable ();
+}
+
+/* Note a warning about preferring WINNER to LOSER. We do this by storing
+ a pointer to LOSER and re-running joust to produce the warning if WINNER
+ is actually used. */
+
+static void
+add_warning (struct z_candidate *winner, struct z_candidate *loser)
+{
+ candidate_warning *cw = (candidate_warning *)
+ conversion_obstack_alloc (sizeof (candidate_warning));
+ cw->loser = loser;
+ cw->next = winner->warnings;
+ winner->warnings = cw;
+}
+
+/* Compare two candidates for overloading as described in
+ [over.match.best]. Return values:
+
+ 1: cand1 is better than cand2
+ -1: cand2 is better than cand1
+ 0: cand1 and cand2 are indistinguishable */
+
+static int
+joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
+ tsubst_flags_t complain)
+{
+ int winner = 0;
+ int off1 = 0, off2 = 0;
+ size_t i;
+ size_t len;
+
+ /* Candidates that involve bad conversions are always worse than those
+ that don't. */
+ if (cand1->viable > cand2->viable)
+ return 1;
+ if (cand1->viable < cand2->viable)
+ return -1;
+
+ /* If we have two pseudo-candidates for conversions to the same type,
+ or two candidates for the same function, arbitrarily pick one. */
+ if (cand1->fn == cand2->fn
+ && (IS_TYPE_OR_DECL_P (cand1->fn)))
+ return 1;
+
+ /* Prefer a non-deleted function over an implicitly deleted move
+ constructor or assignment operator. This differs slightly from the
+ wording for issue 1402 (which says the move op is ignored by overload
+ resolution), but this way produces better error messages. */
+ if (TREE_CODE (cand1->fn) == FUNCTION_DECL
+ && TREE_CODE (cand2->fn) == FUNCTION_DECL
+ && DECL_DELETED_FN (cand1->fn) != DECL_DELETED_FN (cand2->fn))
+ {
+ if (DECL_DELETED_FN (cand1->fn) && DECL_DEFAULTED_FN (cand1->fn)
+ && move_fn_p (cand1->fn))
+ return -1;
+ if (DECL_DELETED_FN (cand2->fn) && DECL_DEFAULTED_FN (cand2->fn)
+ && move_fn_p (cand2->fn))
+ return 1;
+ }
+
+ /* a viable function F1
+ is defined to be a better function than another viable function F2 if
+ for all arguments i, ICSi(F1) is not a worse conversion sequence than
+ ICSi(F2), and then */
+
+ /* for some argument j, ICSj(F1) is a better conversion sequence than
+ ICSj(F2) */
+
+ /* For comparing static and non-static member functions, we ignore
+ the implicit object parameter of the non-static function. The
+ standard says to pretend that the static function has an object
+ parm, but that won't work with operator overloading. */
+ len = cand1->num_convs;
+ if (len != cand2->num_convs)
+ {
+ int static_1 = DECL_STATIC_FUNCTION_P (cand1->fn);
+ int static_2 = DECL_STATIC_FUNCTION_P (cand2->fn);
+
+ if (DECL_CONSTRUCTOR_P (cand1->fn)
+ && is_list_ctor (cand1->fn) != is_list_ctor (cand2->fn))
+ /* We're comparing a near-match list constructor and a near-match
+ non-list constructor. Just treat them as unordered. */
+ return 0;
+
+ gcc_assert (static_1 != static_2);
+
+ if (static_1)
+ off2 = 1;
+ else
+ {
+ off1 = 1;
+ --len;
+ }
+ }
+
+ for (i = 0; i < len; ++i)
+ {
+ conversion *t1 = cand1->convs[i + off1];
+ conversion *t2 = cand2->convs[i + off2];
+ int comp = compare_ics (t1, t2);
+
+ if (comp != 0)
+ {
+ if ((complain & tf_warning)
+ && warn_sign_promo
+ && (CONVERSION_RANK (t1) + CONVERSION_RANK (t2)
+ == cr_std + cr_promotion)
+ && t1->kind == ck_std
+ && t2->kind == ck_std
+ && TREE_CODE (t1->type) == INTEGER_TYPE
+ && TREE_CODE (t2->type) == INTEGER_TYPE
+ && (TYPE_PRECISION (t1->type)
+ == TYPE_PRECISION (t2->type))
+ && (TYPE_UNSIGNED (next_conversion (t1)->type)
+ || (TREE_CODE (next_conversion (t1)->type)
+ == ENUMERAL_TYPE)))
+ {
+ tree type = next_conversion (t1)->type;
+ tree type1, type2;
+ struct z_candidate *w, *l;
+ if (comp > 0)
+ type1 = t1->type, type2 = t2->type,
+ w = cand1, l = cand2;
+ else
+ type1 = t2->type, type2 = t1->type,
+ w = cand2, l = cand1;
+
+ if (warn)
+ {
+ warning (OPT_Wsign_promo, "passing %qT chooses %qT over %qT",
+ type, type1, type2);
+ warning (OPT_Wsign_promo, " in call to %qD", w->fn);
+ }
+ else
+ add_warning (w, l);
+ }
+
+ if (winner && comp != winner)
+ {
+ winner = 0;
+ goto tweak;
+ }
+ winner = comp;
+ }
+ }
+
+ /* warn about confusing overload resolution for user-defined conversions,
+ either between a constructor and a conversion op, or between two
+ conversion ops. */
+ if ((complain & tf_warning)
+ && winner && warn_conversion && cand1->second_conv
+ && (!DECL_CONSTRUCTOR_P (cand1->fn) || !DECL_CONSTRUCTOR_P (cand2->fn))
+ && winner != compare_ics (cand1->second_conv, cand2->second_conv))
+ {
+ struct z_candidate *w, *l;
+ bool give_warning = false;
+
+ if (winner == 1)
+ w = cand1, l = cand2;
+ else
+ w = cand2, l = cand1;
+
+ /* We don't want to complain about `X::operator T1 ()'
+ beating `X::operator T2 () const', when T2 is a no less
+ cv-qualified version of T1. */
+ if (DECL_CONTEXT (w->fn) == DECL_CONTEXT (l->fn)
+ && !DECL_CONSTRUCTOR_P (w->fn) && !DECL_CONSTRUCTOR_P (l->fn))
+ {
+ tree t = TREE_TYPE (TREE_TYPE (l->fn));
+ tree f = TREE_TYPE (TREE_TYPE (w->fn));
+
+ if (TREE_CODE (t) == TREE_CODE (f) && POINTER_TYPE_P (t))
+ {
+ t = TREE_TYPE (t);
+ f = TREE_TYPE (f);
+ }
+ if (!comp_ptr_ttypes (t, f))
+ give_warning = true;
+ }
+ else
+ give_warning = true;
+
+ if (!give_warning)
+ /*NOP*/;
+ else if (warn)
+ {
+ tree source = source_type (w->convs[0]);
+ if (! DECL_CONSTRUCTOR_P (w->fn))
+ source = TREE_TYPE (source);
+ if (warning (OPT_Wconversion, "choosing %qD over %qD", w->fn, l->fn)
+ && warning (OPT_Wconversion, " for conversion from %qT to %qT",
+ source, w->second_conv->type))
+ {
+ inform (input_location, " because conversion sequence for the argument is better");
+ }
+ }
+ else
+ add_warning (w, l);
+ }
+
+ if (winner)
+ return winner;
+
+ /* DR 495 moved this tiebreaker above the template ones. */
+ /* or, if not that,
+ the context is an initialization by user-defined conversion (see
+ _dcl.init_ and _over.match.user_) and the standard conversion
+ sequence from the return type of F1 to the destination type (i.e.,
+ the type of the entity being initialized) is a better conversion
+ sequence than the standard conversion sequence from the return type
+ of F2 to the destination type. */
+
+ if (cand1->second_conv)
+ {
+ winner = compare_ics (cand1->second_conv, cand2->second_conv);
+ if (winner)
+ return winner;
+ }
+
+ /* or, if not that,
+ F1 is a non-template function and F2 is a template function
+ specialization. */
+
+ if (!cand1->template_decl && cand2->template_decl)
+ return 1;
+ else if (cand1->template_decl && !cand2->template_decl)
+ return -1;
+
+ /* or, if not that,
+ F1 and F2 are template functions and the function template for F1 is
+ more specialized than the template for F2 according to the partial
+ ordering rules. */
+
+ if (cand1->template_decl && cand2->template_decl)
+ {
+ winner = more_specialized_fn
+ (TI_TEMPLATE (cand1->template_decl),
+ TI_TEMPLATE (cand2->template_decl),
+ /* [temp.func.order]: The presence of unused ellipsis and default
+ arguments has no effect on the partial ordering of function
+ templates. add_function_candidate() will not have
+ counted the "this" argument for constructors. */
+ cand1->num_convs + DECL_CONSTRUCTOR_P (cand1->fn));
+ if (winner)
+ return winner;
+ }
+
+ /* Check whether we can discard a builtin candidate, either because we
+ have two identical ones or matching builtin and non-builtin candidates.
+
+ (Pedantically in the latter case the builtin which matched the user
+ function should not be added to the overload set, but we spot it here.
+
+ [over.match.oper]
+ ... the builtin candidates include ...
+ - do not have the same parameter type list as any non-template
+ non-member candidate. */
+
+ if (identifier_p (cand1->fn) || identifier_p (cand2->fn))
+ {
+ for (i = 0; i < len; ++i)
+ if (!same_type_p (cand1->convs[i]->type,
+ cand2->convs[i]->type))
+ break;
+ if (i == cand1->num_convs)
+ {
+ if (cand1->fn == cand2->fn)
+ /* Two built-in candidates; arbitrarily pick one. */
+ return 1;
+ else if (identifier_p (cand1->fn))
+ /* cand1 is built-in; prefer cand2. */
+ return -1;
+ else
+ /* cand2 is built-in; prefer cand1. */
+ return 1;
+ }
+ }
+
+ /* For candidates of a multi-versioned function, make the version with
+ the highest priority win. This version will be checked for dispatching
+ first. If this version can be inlined into the caller, the front-end
+ will simply make a direct call to this function. */
+
+ if (TREE_CODE (cand1->fn) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (cand1->fn)
+ && TREE_CODE (cand2->fn) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (cand2->fn))
+ {
+ tree f1 = TREE_TYPE (cand1->fn);
+ tree f2 = TREE_TYPE (cand2->fn);
+ tree p1 = TYPE_ARG_TYPES (f1);
+ tree p2 = TYPE_ARG_TYPES (f2);
+
+ /* Check if cand1->fn and cand2->fn are versions of the same function. It
+ is possible that cand1->fn and cand2->fn are function versions but of
+ different functions. Check types to see if they are versions of the same
+ function. */
+ if (compparms (p1, p2)
+ && same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
+ {
+ /* Always make the version with the higher priority, more
+ specialized, win. */
+ gcc_assert (targetm.compare_version_priority);
+ if (targetm.compare_version_priority (cand1->fn, cand2->fn) >= 0)
+ return 1;
+ else
+ return -1;
+ }
+ }
+
+ /* If the two function declarations represent the same function (this can
+ happen with declarations in multiple scopes and arg-dependent lookup),
+ arbitrarily choose one. But first make sure the default args we're
+ using match. */
+ if (DECL_P (cand1->fn) && DECL_P (cand2->fn)
+ && equal_functions (cand1->fn, cand2->fn))
+ {
+ tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (cand1->fn));
+ tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (cand2->fn));
+
+ gcc_assert (!DECL_CONSTRUCTOR_P (cand1->fn));
+
+ for (i = 0; i < len; ++i)
+ {
+ /* Don't crash if the fn is variadic. */
+ if (!parms1)
+ break;
+ parms1 = TREE_CHAIN (parms1);
+ parms2 = TREE_CHAIN (parms2);
+ }
+
+ if (off1)
+ parms1 = TREE_CHAIN (parms1);
+ else if (off2)
+ parms2 = TREE_CHAIN (parms2);
+
+ for (; parms1; ++i)
+ {
+ if (!cp_tree_equal (TREE_PURPOSE (parms1),
+ TREE_PURPOSE (parms2)))
+ {
+ if (warn)
+ {
+ if (complain & tf_error)
+ {
+ if (permerror (input_location,
+ "default argument mismatch in "
+ "overload resolution"))
+ {
+ inform (input_location,
+ " candidate 1: %q+#F", cand1->fn);
+ inform (input_location,
+ " candidate 2: %q+#F", cand2->fn);
+ }
+ }
+ else
+ return 0;
+ }
+ else
+ add_warning (cand1, cand2);
+ break;
+ }
+ parms1 = TREE_CHAIN (parms1);
+ parms2 = TREE_CHAIN (parms2);
+ }
+
+ return 1;
+ }
+
+tweak:
+
+ /* Extension: If the worst conversion for one candidate is worse than the
+ worst conversion for the other, take the first. */
+ if (!pedantic && (complain & tf_warning_or_error))
+ {
+ conversion_rank rank1 = cr_identity, rank2 = cr_identity;
+ struct z_candidate *w = 0, *l = 0;
+
+ for (i = 0; i < len; ++i)
+ {
+ if (CONVERSION_RANK (cand1->convs[i+off1]) > rank1)
+ rank1 = CONVERSION_RANK (cand1->convs[i+off1]);
+ if (CONVERSION_RANK (cand2->convs[i + off2]) > rank2)
+ rank2 = CONVERSION_RANK (cand2->convs[i + off2]);
+ }
+ if (rank1 < rank2)
+ winner = 1, w = cand1, l = cand2;
+ if (rank1 > rank2)
+ winner = -1, w = cand2, l = cand1;
+ if (winner)
+ {
+ /* Don't choose a deleted function over ambiguity. */
+ if (DECL_P (w->fn) && DECL_DELETED_FN (w->fn))
+ return 0;
+ if (warn)
+ {
+ pedwarn (input_location, 0,
+ "ISO C++ says that these are ambiguous, even "
+ "though the worst conversion for the first is better than "
+ "the worst conversion for the second:");
+ print_z_candidate (input_location, _("candidate 1:"), w);
+ print_z_candidate (input_location, _("candidate 2:"), l);
+ }
+ else
+ add_warning (w, l);
+ return winner;
+ }
+ }
+
+ gcc_assert (!winner);
+ return 0;
+}
+
+/* Given a list of candidates for overloading, find the best one, if any.
+ This algorithm has a worst case of O(2n) (winner is last), and a best
+ case of O(n/2) (totally ambiguous); much better than a sorting
+ algorithm. */
+
+static struct z_candidate *
+tourney (struct z_candidate *candidates, tsubst_flags_t complain)
+{
+ struct z_candidate *champ = candidates, *challenger;
+ int fate;
+ int champ_compared_to_predecessor = 0;
+
+ /* Walk through the list once, comparing each current champ to the next
+ candidate, knocking out a candidate or two with each comparison. */
+
+ for (challenger = champ->next; challenger; )
+ {
+ fate = joust (champ, challenger, 0, complain);
+ if (fate == 1)
+ challenger = challenger->next;
+ else
+ {
+ if (fate == 0)
+ {
+ champ = challenger->next;
+ if (champ == 0)
+ return NULL;
+ champ_compared_to_predecessor = 0;
+ }
+ else
+ {
+ champ = challenger;
+ champ_compared_to_predecessor = 1;
+ }
+
+ challenger = champ->next;
+ }
+ }
+
+ /* Make sure the champ is better than all the candidates it hasn't yet
+ been compared to. */
+
+ for (challenger = candidates;
+ challenger != champ
+ && !(champ_compared_to_predecessor && challenger->next == champ);
+ challenger = challenger->next)
+ {
+ fate = joust (champ, challenger, 0, complain);
+ if (fate != 1)
+ return NULL;
+ }
+
+ return champ;
+}
+
+/* Returns nonzero if things of type FROM can be converted to TO. */
+
+bool
+can_convert (tree to, tree from, tsubst_flags_t complain)
+{
+ tree arg = NULL_TREE;
+ /* implicit_conversion only considers user-defined conversions
+ if it has an expression for the call argument list. */
+ if (CLASS_TYPE_P (from) || CLASS_TYPE_P (to))
+ arg = build1 (CAST_EXPR, from, NULL_TREE);
+ return can_convert_arg (to, from, arg, LOOKUP_IMPLICIT, complain);
+}
+
+/* Returns nonzero if things of type FROM can be converted to TO with a
+ standard conversion. */
+
+bool
+can_convert_standard (tree to, tree from, tsubst_flags_t complain)
+{
+ return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT, complain);
+}
+
+/* Returns nonzero if ARG (of type FROM) can be converted to TO. */
+
+bool
+can_convert_arg (tree to, tree from, tree arg, int flags,
+ tsubst_flags_t complain)
+{
+ conversion *t;
+ void *p;
+ bool ok_p;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+ /* We want to discard any access checks done for this test,
+ as we might not be in the appropriate access context and
+ we'll do the check again when we actually perform the
+ conversion. */
+ push_deferring_access_checks (dk_deferred);
+
+ t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
+ flags, complain);
+ ok_p = (t && !t->bad_p);
+
+ /* Discard the access checks now. */
+ pop_deferring_access_checks ();
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return ok_p;
+}
+
+/* Like can_convert_arg, but allows dubious conversions as well. */
+
+bool
+can_convert_arg_bad (tree to, tree from, tree arg, int flags,
+ tsubst_flags_t complain)
+{
+ conversion *t;
+ void *p;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+ /* Try to perform the conversion. */
+ t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
+ flags, complain);
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return t != NULL;
+}
+
+/* Convert EXPR to TYPE. Return the converted expression.
+
+ Note that we allow bad conversions here because by the time we get to
+ this point we are committed to doing the conversion. If we end up
+ doing a bad conversion, convert_like will complain. */
+
+tree
+perform_implicit_conversion_flags (tree type, tree expr,
+ tsubst_flags_t complain, int flags)
+{
+ conversion *conv;
+ void *p;
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+
+ if (error_operand_p (expr))
+ return error_mark_node;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ conv = implicit_conversion (type, TREE_TYPE (expr), expr,
+ /*c_cast_p=*/false,
+ flags, complain);
+
+ if (!conv)
+ {
+ if (complain & tf_error)
+ {
+ /* If expr has unknown type, then it is an overloaded function.
+ Call instantiate_type to get good error messages. */
+ if (TREE_TYPE (expr) == unknown_type_node)
+ instantiate_type (type, expr, complain);
+ else if (invalid_nonstatic_memfn_p (expr, complain))
+ /* We gave an error. */;
+ else
+ error_at (loc, "could not convert %qE from %qT to %qT", expr,
+ TREE_TYPE (expr), type);
+ }
+ expr = error_mark_node;
+ }
+ else if (processing_template_decl && conv->kind != ck_identity)
+ {
+ /* In a template, we are only concerned about determining the
+ type of non-dependent expressions, so we do not have to
+ perform the actual conversion. But for initializers, we
+ need to be able to perform it at instantiation
+ (or fold_non_dependent_expr) time. */
+ expr = build1 (IMPLICIT_CONV_EXPR, type, expr);
+ if (!(flags & LOOKUP_ONLYCONVERTING))
+ IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true;
+ }
+ else
+ expr = convert_like (conv, expr, complain);
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return expr;
+}
+
+tree
+perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain)
+{
+ return perform_implicit_conversion_flags (type, expr, complain,
+ LOOKUP_IMPLICIT);
+}
+
+/* Convert EXPR to TYPE (as a direct-initialization) if that is
+ permitted. If the conversion is valid, the converted expression is
+ returned. Otherwise, NULL_TREE is returned, except in the case
+ that TYPE is a class type; in that case, an error is issued. If
+ C_CAST_P is true, then this direct-initialization is taking
+ place as part of a static_cast being attempted as part of a C-style
+ cast. */
+
+tree
+perform_direct_initialization_if_possible (tree type,
+ tree expr,
+ bool c_cast_p,
+ tsubst_flags_t complain)
+{
+ conversion *conv;
+ void *p;
+
+ if (type == error_mark_node || error_operand_p (expr))
+ return error_mark_node;
+ /* [dcl.init]
+
+ If the destination type is a (possibly cv-qualified) class type:
+
+ -- If the initialization is direct-initialization ...,
+ constructors are considered. ... If no constructor applies, or
+ the overload resolution is ambiguous, the initialization is
+ ill-formed. */
+ if (CLASS_TYPE_P (type))
+ {
+ vec<tree, va_gc> *args = make_tree_vector_single (expr);
+ expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ &args, type, LOOKUP_NORMAL, complain);
+ release_tree_vector (args);
+ return build_cplus_new (type, expr, complain);
+ }
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ conv = implicit_conversion (type, TREE_TYPE (expr), expr,
+ c_cast_p,
+ LOOKUP_NORMAL, complain);
+ if (!conv || conv->bad_p)
+ expr = NULL_TREE;
+ else
+ expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
+ /*issue_conversion_warnings=*/false,
+ c_cast_p,
+ complain);
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return expr;
+}
+
+/* When initializing a reference that lasts longer than a full-expression,
+ this special rule applies:
+
+ [class.temporary]
+
+ The temporary to which the reference is bound or the temporary
+ that is the complete object to which the reference is bound
+ persists for the lifetime of the reference.
+
+ The temporaries created during the evaluation of the expression
+ initializing the reference, except the temporary to which the
+ reference is bound, are destroyed at the end of the
+ full-expression in which they are created.
+
+ In that case, we store the converted expression into a new
+ VAR_DECL in a new scope.
+
+ However, we want to be careful not to create temporaries when
+ they are not required. For example, given:
+
+ struct B {};
+ struct D : public B {};
+ D f();
+ const B& b = f();
+
+ there is no need to copy the return value from "f"; we can just
+ extend its lifetime. Similarly, given:
+
+ struct S {};
+ struct T { operator S(); };
+ T t;
+ const S& s = t;
+
+ we can extend the lifetime of the return value of the conversion
+ operator.
+
+ The next several functions are involved in this lifetime extension. */
+
+/* DECL is a VAR_DECL or FIELD_DECL whose type is a REFERENCE_TYPE. The
+ reference is being bound to a temporary. Create and return a new
+ VAR_DECL with the indicated TYPE; this variable will store the value to
+ which the reference is bound. */
+
+tree
+make_temporary_var_for_ref_to_temp (tree decl, tree type)
+{
+ tree var;
+
+ /* Create the variable. */
+ var = create_temporary_var (type);
+
+ /* Register the variable. */
+ if (VAR_P (decl)
+ && (TREE_STATIC (decl) || DECL_THREAD_LOCAL_P (decl)))
+ {
+ /* Namespace-scope or local static; give it a mangled name. */
+ /* FIXME share comdat with decl? */
+ tree name;
+
+ TREE_STATIC (var) = TREE_STATIC (decl);
+ DECL_TLS_MODEL (var) = DECL_TLS_MODEL (decl);
+ name = mangle_ref_init_variable (decl);
+ DECL_NAME (var) = name;
+ SET_DECL_ASSEMBLER_NAME (var, name);
+ var = pushdecl_top_level (var);
+ }
+ else
+ /* Create a new cleanup level if necessary. */
+ maybe_push_cleanup_level (type);
+
+ return var;
+}
+
+/* EXPR is the initializer for a variable DECL of reference or
+ std::initializer_list type. Create, push and return a new VAR_DECL
+ for the initializer so that it will live as long as DECL. Any
+ cleanup for the new variable is returned through CLEANUP, and the
+ code to initialize the new variable is returned through INITP. */
+
+static tree
+set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
+ tree *initp)
+{
+ tree init;
+ tree type;
+ tree var;
+
+ /* Create the temporary variable. */
+ type = TREE_TYPE (expr);
+ var = make_temporary_var_for_ref_to_temp (decl, type);
+ layout_decl (var, 0);
+ /* If the rvalue is the result of a function call it will be
+ a TARGET_EXPR. If it is some other construct (such as a
+ member access expression where the underlying object is
+ itself the result of a function call), turn it into a
+ TARGET_EXPR here. It is important that EXPR be a
+ TARGET_EXPR below since otherwise the INIT_EXPR will
+ attempt to make a bitwise copy of EXPR to initialize
+ VAR. */
+ if (TREE_CODE (expr) != TARGET_EXPR)
+ expr = get_target_expr (expr);
+
+ if (TREE_CODE (decl) == FIELD_DECL
+ && extra_warnings && !TREE_NO_WARNING (decl))
+ {
+ warning (OPT_Wextra, "a temporary bound to %qD only persists "
+ "until the constructor exits", decl);
+ TREE_NO_WARNING (decl) = true;
+ }
+
+ /* Recursively extend temps in this initializer. */
+ TARGET_EXPR_INITIAL (expr)
+ = extend_ref_init_temps (decl, TARGET_EXPR_INITIAL (expr), cleanups);
+
+ /* Any reference temp has a non-trivial initializer. */
+ DECL_NONTRIVIALLY_INITIALIZED_P (var) = true;
+
+ /* If the initializer is constant, put it in DECL_INITIAL so we get
+ static initialization and use in constant expressions. */
+ init = maybe_constant_init (expr);
+ if (TREE_CONSTANT (init))
+ {
+ if (literal_type_p (type) && CP_TYPE_CONST_NON_VOLATILE_P (type))
+ {
+ /* 5.19 says that a constant expression can include an
+ lvalue-rvalue conversion applied to "a glvalue of literal type
+ that refers to a non-volatile temporary object initialized
+ with a constant expression". Rather than try to communicate
+ that this VAR_DECL is a temporary, just mark it constexpr.
+
+ Currently this is only useful for initializer_list temporaries,
+ since reference vars can't appear in constant expressions. */
+ DECL_DECLARED_CONSTEXPR_P (var) = true;
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = true;
+ TREE_CONSTANT (var) = true;
+ }
+ DECL_INITIAL (var) = init;
+ init = NULL_TREE;
+ }
+ else
+ /* Create the INIT_EXPR that will initialize the temporary
+ variable. */
+ init = build2 (INIT_EXPR, type, var, expr);
+ if (at_function_scope_p ())
+ {
+ add_decl_expr (var);
+
+ if (TREE_STATIC (var))
+ init = add_stmt_to_compound (init, register_dtor_fn (var));
+ else
+ {
+ tree cleanup = cxx_maybe_build_cleanup (var, tf_warning_or_error);
+ if (cleanup)
+ vec_safe_push (*cleanups, cleanup);
+ }
+
+ /* We must be careful to destroy the temporary only
+ after its initialization has taken place. If the
+ initialization throws an exception, then the
+ destructor should not be run. We cannot simply
+ transform INIT into something like:
+
+ (INIT, ({ CLEANUP_STMT; }))
+
+ because emit_local_var always treats the
+ initializer as a full-expression. Thus, the
+ destructor would run too early; it would run at the
+ end of initializing the reference variable, rather
+ than at the end of the block enclosing the
+ reference variable.
+
+ The solution is to pass back a cleanup expression
+ which the caller is responsible for attaching to
+ the statement tree. */
+ }
+ else
+ {
+ rest_of_decl_compilation (var, /*toplev=*/1, at_eof);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ {
+ if (DECL_THREAD_LOCAL_P (var))
+ tls_aggregates = tree_cons (NULL_TREE, var,
+ tls_aggregates);
+ else
+ static_aggregates = tree_cons (NULL_TREE, var,
+ static_aggregates);
+ }
+ else
+ /* Check whether the dtor is callable. */
+ cxx_maybe_build_cleanup (var, tf_warning_or_error);
+ }
+
+ *initp = init;
+ return var;
+}
+
+/* Convert EXPR to the indicated reference TYPE, in a way suitable for
+ initializing a variable of that TYPE. */
+
+tree
+initialize_reference (tree type, tree expr,
+ int flags, tsubst_flags_t complain)
+{
+ conversion *conv;
+ void *p;
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+
+ if (type == error_mark_node || error_operand_p (expr))
+ return error_mark_node;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ conv = reference_binding (type, TREE_TYPE (expr), expr, /*c_cast_p=*/false,
+ flags, complain);
+ if (!conv || conv->bad_p)
+ {
+ if (complain & tf_error)
+ {
+ if (conv)
+ convert_like (conv, expr, complain);
+ else if (!CP_TYPE_CONST_P (TREE_TYPE (type))
+ && !TYPE_REF_IS_RVALUE (type)
+ && !real_lvalue_p (expr))
+ error_at (loc, "invalid initialization of non-const reference of "
+ "type %qT from an rvalue of type %qT",
+ type, TREE_TYPE (expr));
+ else
+ error_at (loc, "invalid initialization of reference of type "
+ "%qT from expression of type %qT", type,
+ TREE_TYPE (expr));
+ }
+ return error_mark_node;
+ }
+
+ if (conv->kind == ck_ref_bind)
+ /* Perform the conversion. */
+ expr = convert_like (conv, expr, complain);
+ else if (conv->kind == ck_ambig)
+ /* We gave an error in build_user_type_conversion_1. */
+ expr = error_mark_node;
+ else
+ gcc_unreachable ();
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return expr;
+}
+
+/* Subroutine of extend_ref_init_temps. Possibly extend one initializer,
+ which is bound either to a reference or a std::initializer_list. */
+
+static tree
+extend_ref_init_temps_1 (tree decl, tree init, vec<tree, va_gc> **cleanups)
+{
+ tree sub = init;
+ tree *p;
+ STRIP_NOPS (sub);
+ if (TREE_CODE (sub) == COMPOUND_EXPR)
+ {
+ TREE_OPERAND (sub, 1)
+ = extend_ref_init_temps_1 (decl, TREE_OPERAND (sub, 1), cleanups);
+ return init;
+ }
+ if (TREE_CODE (sub) != ADDR_EXPR)
+ return init;
+ /* Deal with binding to a subobject. */
+ for (p = &TREE_OPERAND (sub, 0); TREE_CODE (*p) == COMPONENT_REF; )
+ p = &TREE_OPERAND (*p, 0);
+ if (TREE_CODE (*p) == TARGET_EXPR)
+ {
+ tree subinit = NULL_TREE;
+ *p = set_up_extended_ref_temp (decl, *p, cleanups, &subinit);
+ if (subinit)
+ init = build2 (COMPOUND_EXPR, TREE_TYPE (init), subinit, init);
+ recompute_tree_invariant_for_addr_expr (sub);
+ }
+ return init;
+}
+
+/* INIT is part of the initializer for DECL. If there are any
+ reference or initializer lists being initialized, extend their
+ lifetime to match that of DECL. */
+
+tree
+extend_ref_init_temps (tree decl, tree init, vec<tree, va_gc> **cleanups)
+{
+ tree type = TREE_TYPE (init);
+ if (processing_template_decl)
+ return init;
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ init = extend_ref_init_temps_1 (decl, init, cleanups);
+ else if (is_std_init_list (type))
+ {
+ /* The temporary array underlying a std::initializer_list
+ is handled like a reference temporary. */
+ tree ctor = init;
+ if (TREE_CODE (ctor) == TARGET_EXPR)
+ ctor = TARGET_EXPR_INITIAL (ctor);
+ if (TREE_CODE (ctor) == CONSTRUCTOR)
+ {
+ tree array = CONSTRUCTOR_ELT (ctor, 0)->value;
+ array = extend_ref_init_temps_1 (decl, array, cleanups);
+ CONSTRUCTOR_ELT (ctor, 0)->value = array;
+ }
+ }
+ else if (TREE_CODE (init) == CONSTRUCTOR)
+ {
+ unsigned i;
+ constructor_elt *p;
+ vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (init);
+ FOR_EACH_VEC_SAFE_ELT (elts, i, p)
+ p->value = extend_ref_init_temps (decl, p->value, cleanups);
+ }
+
+ return init;
+}
+
+/* Returns true iff an initializer for TYPE could contain temporaries that
+ need to be extended because they are bound to references or
+ std::initializer_list. */
+
+bool
+type_has_extended_temps (tree type)
+{
+ type = strip_array_types (type);
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ return true;
+ if (CLASS_TYPE_P (type))
+ {
+ if (is_std_init_list (type))
+ return true;
+ for (tree f = next_initializable_field (TYPE_FIELDS (type));
+ f; f = next_initializable_field (DECL_CHAIN (f)))
+ if (type_has_extended_temps (TREE_TYPE (f)))
+ return true;
+ }
+ return false;
+}
+
+/* Returns true iff TYPE is some variant of std::initializer_list. */
+
+bool
+is_std_init_list (tree type)
+{
+ /* Look through typedefs. */
+ if (!TYPE_P (type))
+ return false;
+ if (cxx_dialect == cxx98)
+ return false;
+ type = TYPE_MAIN_VARIANT (type);
+ return (CLASS_TYPE_P (type)
+ && CP_TYPE_CONTEXT (type) == std_node
+ && strcmp (TYPE_NAME_STRING (type), "initializer_list") == 0);
+}
+
+/* Returns true iff DECL is a list constructor: i.e. a constructor which
+ will accept an argument list of a single std::initializer_list<T>. */
+
+bool
+is_list_ctor (tree decl)
+{
+ tree args = FUNCTION_FIRST_USER_PARMTYPE (decl);
+ tree arg;
+
+ if (!args || args == void_list_node)
+ return false;
+
+ arg = non_reference (TREE_VALUE (args));
+ if (!is_std_init_list (arg))
+ return false;
+
+ args = TREE_CHAIN (args);
+
+ if (args && args != void_list_node && !TREE_PURPOSE (args))
+ /* There are more non-defaulted parms. */
+ return false;
+
+ return true;
+}
+
+#include "gt-cp-call.h"
diff --git a/gcc-4.9/gcc/cp/cfns.gperf b/gcc-4.9/gcc/cp/cfns.gperf
new file mode 100644
index 000000000..05ca75392
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cfns.gperf
@@ -0,0 +1,247 @@
+%{
+/* Copyright (C) 2000-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+#ifdef __GNUC__
+__inline
+#endif
+static unsigned int hash (const char *, unsigned int);
+#ifdef __GNUC__
+__inline
+#endif
+const char * libc_name_p (const char *, unsigned int);
+%}
+%%
+# The standard C library functions, for feeding to gperf; the result is used
+# by nothrow_libfn_p.
+#
+# [lib.res.on.exception.handling]: None of the functions from the
+# Standard C library shall report an error by throwing an
+# exception, unless it calls a program-supplied function that
+# throws an exception.
+#
+# Specific functions are commented out for the reason noted in each case.
+#
+# abort -- synchronous exception from SIGABRT handler
+abs
+acos
+asctime
+asin
+atan
+atan2
+atexit
+atof
+atoi
+atol
+#bsearch -- calls user function which may throw exception
+btowc
+calloc
+ceil
+clearerr
+clock
+cos
+cosh
+ctime
+difftime
+div
+exit
+exp
+fabs
+#fclose -- POSIX thread cancellation point
+feof
+ferror
+#fflush -- POSIX thread cancellation point
+#fgetc -- POSIX thread cancellation point
+#fgetpos -- POSIX thread cancellation point
+#fgets -- POSIX thread cancellation point
+#fgetwc -- POSIX thread cancellation point
+#fgetws -- POSIX thread cancellation point
+floor
+fmod
+#fopen -- POSIX thread cancellation point
+#fprintf -- POSIX thread cancellation point
+#fputc -- POSIX thread cancellation point
+#fputs -- POSIX thread cancellation point
+#fputwc -- POSIX thread cancellation point
+#fputws -- POSIX thread cancellation point
+#fread -- POSIX thread cancellation point
+free
+#freopen -- POSIX thread cancellation point
+frexp
+#fscanf -- POSIX thread cancellation point
+fseek
+#fsetpos -- POSIX thread cancellation point
+#ftell -- POSIX thread cancellation point
+fwide
+#fwprintf -- POSIX thread cancellation point
+#fwrite -- POSIX thread cancellation point
+#fwscanf -- POSIX thread cancellation point
+#getc -- POSIX thread cancellation point
+#getchar -- POSIX thread cancellation point
+getenv
+#gets -- POSIX thread cancellation point
+#getwc -- POSIX thread cancellation point
+#getwchar -- POSIX thread cancellation point
+gmtime
+isalnum
+isalpha
+iscntrl
+isdigit
+isgraph
+islower
+isprint
+ispunct
+isspace
+isupper
+iswalnum
+iswalpha
+iswcntrl
+iswctype
+iswdigit
+iswgraph
+iswlower
+iswprint
+iswpunct
+iswspace
+iswupper
+iswxdigit
+isxdigit
+labs
+ldexp
+ldiv
+localeconv
+localtime
+log
+log10
+longjmp
+malloc
+mblen
+mbrlen
+mbrtowc
+mbsinit
+mbsrtowcs
+mbstowcs
+mbtowc
+memchr
+memcmp
+memcpy
+memmove
+memset
+mktime
+modf
+#perror -- POSIX thread cancellation point
+pow
+#printf -- POSIX thread cancellation point
+#putc -- POSIX thread cancellation point
+#putchar -- POSIX thread cancellation point
+#puts -- POSIX thread cancellation point
+#putwc -- POSIX thread cancellation point
+#putwchar -- POSIX thread cancellation point
+#qsort -- calls user function which may throw exception
+#raise -- synchronous exception from signal handler
+rand
+realloc
+#remove -- POSIX thread cancellation point
+#rename -- POSIX thread cancellation point
+#rewind -- POSIX thread cancellation point
+#scanf -- POSIX thread cancellation point
+setbuf
+setlocale
+setvbuf
+signal
+sin
+sinh
+sprintf
+sqrt
+srand
+sscanf
+strcat
+strchr
+strcmp
+strcoll
+strcpy
+strcspn
+#strerror -- POSIX thread cancellation point
+strftime
+strlen
+strncat
+strncmp
+strncpy
+strpbrk
+strrchr
+strspn
+strstr
+strtod
+strtok
+strtol
+strtoul
+strxfrm
+swprintf
+swscanf
+#system -- POSIX thread cancellation point
+tan
+tanh
+time
+#tmpfile -- POSIX thread cancellation point
+#tmpnam -- POSIX thread cancellation point
+tolower
+toupper
+towctrans
+towlower
+towupper
+#ungetc -- POSIX thread cancellation point
+#ungetwc -- POSIX thread cancellation point
+#vfprintf -- POSIX thread cancellation point
+#vfwprintf -- POSIX thread cancellation point
+#vprintf -- POSIX thread cancellation point
+vsprintf
+vswprintf
+#vwprintf -- POSIX thread cancellation point
+wcrtomb
+wcscat
+wcschr
+wcscmp
+wcscoll
+wcscpy
+wcscspn
+wcsftime
+wcslen
+wcsncat
+wcsncmp
+wcsncpy
+wcspbrk
+wcsrchr
+wcsrtombs
+wcsspn
+wcsstr
+wcstod
+wcstok
+wcstol
+wcstombs
+wcstoul
+wcsxfrm
+wctob
+wctomb
+wctrans
+wctype
+wmemchr
+wmemcmp
+wmemcpy
+wmemmove
+wmemset
+#wprintf -- POSIX thread cancellation point
+#wscanf -- POSIX thread cancellation point
diff --git a/gcc-4.9/gcc/cp/cfns.h b/gcc-4.9/gcc/cp/cfns.h
new file mode 100644
index 000000000..c845ddf08
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cfns.h
@@ -0,0 +1,365 @@
+/* ANSI-C code produced by gperf version 3.0.3 */
+/* Command-line: gperf -o -C -E -k '1-6,$' -j1 -D -N libc_name_p -L ANSI-C cfns.gperf */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646. */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+#line 1 "cfns.gperf"
+
+/* Copyright (C) 2000-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+#ifdef __GNUC__
+__inline
+#endif
+static unsigned int hash (const char *, unsigned int);
+#ifdef __GNUC__
+__inline
+#endif
+const char * libc_name_p (const char *, unsigned int);
+/* maximum key range = 391, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+hash (register const char *str, register unsigned int len)
+{
+ static const unsigned short asso_values[] =
+ {
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 0, 0,
+ 1, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 28, 90, 0,
+ 95, 0, 51, 93, 114, 26, 109, 124, 5, 1,
+ 6, 13, 37, 128, 3, 0, 0, 49, 38, 0,
+ 104, 45, 0, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 400, 400, 400, 400
+ };
+ register int hval = len;
+
+ switch (hval)
+ {
+ default:
+ hval += asso_values[(unsigned char)str[5]+1];
+ /*FALLTHROUGH*/
+ case 5:
+ hval += asso_values[(unsigned char)str[4]];
+ /*FALLTHROUGH*/
+ case 4:
+ hval += asso_values[(unsigned char)str[3]];
+ /*FALLTHROUGH*/
+ case 3:
+ hval += asso_values[(unsigned char)str[2]];
+ /*FALLTHROUGH*/
+ case 2:
+ hval += asso_values[(unsigned char)str[1]];
+ /*FALLTHROUGH*/
+ case 1:
+ hval += asso_values[(unsigned char)str[0]];
+ break;
+ }
+ return hval + asso_values[(unsigned char)str[len - 1]];
+}
+
+#ifdef __GNUC__
+__inline
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
+#endif
+const char *
+libc_name_p (register const char *str, register unsigned int len)
+{
+ enum
+ {
+ TOTAL_KEYWORDS = 156,
+ MIN_WORD_LENGTH = 3,
+ MAX_WORD_LENGTH = 10,
+ MIN_HASH_VALUE = 9,
+ MAX_HASH_VALUE = 399
+ };
+
+ static const char * const wordlist[] =
+ {
+ "wcsstr",
+ "strstr",
+ "cos",
+ "towctrans",
+ "memmove",
+ "wcstol",
+ "wcscoll",
+ "wcstombs",
+ "strtol",
+ "strcoll",
+ "wcslen",
+ "time",
+ "ctime",
+ "strlen",
+ "iswctype",
+ "wmemchr",
+ "wcsrchr",
+ "ceil",
+ "sin",
+ "strrchr",
+ "tan",
+ "iscntrl",
+ "acos",
+ "wmemmove",
+ "wcsrtombs",
+ "wctrans",
+ "wmemcmp",
+ "pow",
+ "atol",
+ "wcsncmp",
+ "memset",
+ "free",
+ "strncmp",
+ "wmemset",
+ "wcsspn",
+ "wcstoul",
+ "strspn",
+ "strtoul",
+ "asctime",
+ "atan2",
+ "asin",
+ "atan",
+ "ferror",
+ "iswalnum",
+ "wcscat",
+ "realloc",
+ "strcat",
+ "wcscpy",
+ "memcpy",
+ "strcpy",
+ "tolower",
+ "floor",
+ "iswcntrl",
+ "atoi",
+ "clearerr",
+ "swscanf",
+ "wcsncat",
+ "islower",
+ "strncat",
+ "btowc",
+ "localtime",
+ "wctomb",
+ "isalnum",
+ "isprint",
+ "mblen",
+ "wcstod",
+ "log10",
+ "strtod",
+ "wcrtomb",
+ "abs",
+ "setlocale",
+ "wcschr",
+ "mbrlen",
+ "memchr",
+ "strchr",
+ "labs",
+ "iswpunct",
+ "exit",
+ "sqrt",
+ "swprintf",
+ "wctype",
+ "mbsrtowcs",
+ "wcscspn",
+ "getenv",
+ "strcspn",
+ "towlower",
+ "atof",
+ "wcstok",
+ "localeconv",
+ "strtok",
+ "calloc",
+ "malloc",
+ "isalpha",
+ "iswlower",
+ "iswspace",
+ "wcsxfrm",
+ "signal",
+ "strxfrm",
+ "wcsftime",
+ "feof",
+ "strftime",
+ "wcscmp",
+ "fabs",
+ "memcmp",
+ "strcmp",
+ "vsprintf",
+ "fwide",
+ "gmtime",
+ "sprintf",
+ "exp",
+ "wmemcpy",
+ "iswprint",
+ "sscanf",
+ "wcsncpy",
+ "strncpy",
+ "isspace",
+ "toupper",
+ "wctob",
+ "div",
+ "mbtowc",
+ "ldiv",
+ "log",
+ "mktime",
+ "isupper",
+ "atexit",
+ "modf",
+ "mbstowcs",
+ "mbrtowc",
+ "ispunct",
+ "iswalpha",
+ "setvbuf",
+ "rand",
+ "srand",
+ "frexp",
+ "towupper",
+ "mbsinit",
+ "cosh",
+ "vswprintf",
+ "iswupper",
+ "wcspbrk",
+ "fmod",
+ "strpbrk",
+ "sinh",
+ "tanh",
+ "iswdigit",
+ "clock",
+ "longjmp",
+ "ldexp",
+ "setbuf",
+ "fseek",
+ "iswgraph",
+ "difftime",
+ "iswxdigit",
+ "isdigit",
+ "isxdigit",
+ "isgraph"
+ };
+
+ static const short lookup[] =
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 0,
+ -1, -1, 1, -1, -1, -1, 2, -1, -1, -1,
+ -1, -1, 3, 4, -1, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, -1, -1, 15, 16,
+ 17, 18, 19, 20, 21, 22, -1, -1, 23, 24,
+ -1, 25, 26, 27, -1, 28, 29, 30, 31, 32,
+ 33, -1, 34, 35, -1, 36, 37, 38, -1, 39,
+ 40, -1, 41, -1, -1, -1, -1, -1, -1, 42,
+ -1, 43, -1, 44, -1, 45, 46, -1, 47, -1,
+ 48, 49, 50, 51, 52, -1, -1, 53, 54, 55,
+ -1, -1, -1, 56, -1, 57, 58, -1, 59, 60,
+ 61, 62, 63, 64, 65, -1, 66, 67, -1, 68,
+ -1, 69, 70, 71, 72, 73, 74, 75, -1, -1,
+ -1, -1, -1, 76, 77, 78, -1, -1, 79, 80,
+ 81, 82, -1, 83, 84, -1, 85, 86, 87, -1,
+ 88, 89, 90, 91, -1, -1, -1, 92, -1, 93,
+ -1, 94, -1, 95, -1, 96, 97, -1, 98, -1,
+ 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ -1, 109, 110, 111, 112, -1, 113, -1, -1, 114,
+ -1, -1, -1, 115, -1, -1, -1, 116, 117, -1,
+ 118, -1, -1, -1, -1, 119, 120, 121, -1, 122,
+ 123, -1, -1, 124, -1, 125, 126, -1, 127, -1,
+ 128, -1, -1, 129, 130, -1, -1, -1, -1, -1,
+ -1, 131, 132, -1, -1, -1, -1, 133, 134, 135,
+ -1, -1, -1, -1, -1, 136, -1, 137, -1, -1,
+ -1, 138, -1, -1, -1, -1, -1, -1, 139, 140,
+ -1, 141, -1, -1, 142, -1, 143, -1, -1, 144,
+ -1, 145, -1, -1, -1, -1, 146, -1, -1, -1,
+ -1, -1, -1, 147, -1, -1, -1, -1, -1, 148,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 149, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 150, -1, -1, -1, -1, -1,
+ 151, -1, -1, 152, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 153, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 154, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 155
+ };
+
+ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+ {
+ register int key = hash (str, len);
+
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ {
+ register int index = lookup[key];
+
+ if (index >= 0)
+ {
+ register const char *s = wordlist[index];
+
+ if (*str == *s && !strcmp (str + 1, s + 1))
+ return s;
+ }
+ }
+ }
+ return 0;
+}
diff --git a/gcc-4.9/gcc/cp/class.c b/gcc-4.9/gcc/cp/class.c
new file mode 100644
index 000000000..b46391be1
--- /dev/null
+++ b/gcc-4.9/gcc/cp/class.c
@@ -0,0 +1,9484 @@
+/* Functions related to building classes and their related objects.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Contributed by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* High-level class interface. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "stor-layout.h"
+#include "attribs.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "toplev.h"
+#include "target.h"
+#include "convert.h"
+#include "cgraph.h"
+#include "dumpfile.h"
+#include "splay-tree.h"
+#include "gimplify.h"
+
+/* The number of nested classes being processed. If we are not in the
+ scope of any class, this is zero. */
+
+int current_class_depth;
+
+/* In order to deal with nested classes, we keep a stack of classes.
+ The topmost entry is the innermost class, and is the entry at index
+ CURRENT_CLASS_DEPTH */
+
+typedef struct class_stack_node {
+ /* The name of the class. */
+ tree name;
+
+ /* The _TYPE node for the class. */
+ tree type;
+
+ /* The access specifier pending for new declarations in the scope of
+ this class. */
+ tree access;
+
+ /* If were defining TYPE, the names used in this class. */
+ splay_tree names_used;
+
+ /* Nonzero if this class is no longer open, because of a call to
+ push_to_top_level. */
+ size_t hidden;
+}* class_stack_node_t;
+
+typedef struct vtbl_init_data_s
+{
+ /* The base for which we're building initializers. */
+ tree binfo;
+ /* The type of the most-derived type. */
+ tree derived;
+ /* The binfo for the dynamic type. This will be TYPE_BINFO (derived),
+ unless ctor_vtbl_p is true. */
+ tree rtti_binfo;
+ /* The negative-index vtable initializers built up so far. These
+ are in order from least negative index to most negative index. */
+ vec<constructor_elt, va_gc> *inits;
+ /* The binfo for the virtual base for which we're building
+ vcall offset initializers. */
+ tree vbase;
+ /* The functions in vbase for which we have already provided vcall
+ offsets. */
+ vec<tree, va_gc> *fns;
+ /* The vtable index of the next vcall or vbase offset. */
+ tree index;
+ /* Nonzero if we are building the initializer for the primary
+ vtable. */
+ int primary_vtbl_p;
+ /* Nonzero if we are building the initializer for a construction
+ vtable. */
+ int ctor_vtbl_p;
+ /* True when adding vcall offset entries to the vtable. False when
+ merely computing the indices. */
+ bool generate_vcall_entries;
+} vtbl_init_data;
+
+/* The type of a function passed to walk_subobject_offsets. */
+typedef int (*subobject_offset_fn) (tree, tree, splay_tree);
+
+/* The stack itself. This is a dynamically resized array. The
+ number of elements allocated is CURRENT_CLASS_STACK_SIZE. */
+static int current_class_stack_size;
+static class_stack_node_t current_class_stack;
+
+/* The size of the largest empty class seen in this translation unit. */
+static GTY (()) tree sizeof_biggest_empty_class;
+
+/* An array of all local classes present in this translation unit, in
+ declaration order. */
+vec<tree, va_gc> *local_classes;
+
+static tree get_vfield_name (tree);
+static void finish_struct_anon (tree);
+static tree get_vtable_name (tree);
+static tree get_basefndecls (tree, tree);
+static int build_primary_vtable (tree, tree);
+static int build_secondary_vtable (tree);
+static void finish_vtbls (tree);
+static void modify_vtable_entry (tree, tree, tree, tree, tree *);
+static void finish_struct_bits (tree);
+static int alter_access (tree, tree, tree);
+static void handle_using_decl (tree, tree);
+static tree dfs_modify_vtables (tree, void *);
+static tree modify_all_vtables (tree, tree);
+static void determine_primary_bases (tree);
+static void finish_struct_methods (tree);
+static void maybe_warn_about_overly_private_class (tree);
+static int method_name_cmp (const void *, const void *);
+static int resort_method_name_cmp (const void *, const void *);
+static void add_implicitly_declared_members (tree, tree*, int, int);
+static tree fixed_type_or_null (tree, int *, int *);
+static tree build_simple_base_path (tree expr, tree binfo);
+static tree build_vtbl_ref_1 (tree, tree);
+static void build_vtbl_initializer (tree, tree, tree, tree, int *,
+ vec<constructor_elt, va_gc> **);
+static int count_fields (tree);
+static int add_fields_to_record_type (tree, struct sorted_fields_type*, int);
+static void insert_into_classtype_sorted_fields (tree, tree, int);
+static bool check_bitfield_decl (tree);
+static void check_field_decl (tree, tree, int *, int *, int *);
+static void check_field_decls (tree, tree *, int *, int *);
+static tree *build_base_field (record_layout_info, tree, splay_tree, tree *);
+static void build_base_fields (record_layout_info, splay_tree, tree *);
+static void check_methods (tree);
+static void remove_zero_width_bit_fields (tree);
+static void check_bases (tree, int *, int *);
+static void check_bases_and_members (tree);
+static tree create_vtable_ptr (tree, tree *);
+static void include_empty_classes (record_layout_info);
+static void layout_class_type (tree, tree *);
+static void propagate_binfo_offsets (tree, tree);
+static void layout_virtual_bases (record_layout_info, splay_tree);
+static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *);
+static void add_vcall_offset_vtbl_entries_r (tree, vtbl_init_data *);
+static void add_vcall_offset_vtbl_entries_1 (tree, vtbl_init_data *);
+static void build_vcall_offset_vtbl_entries (tree, vtbl_init_data *);
+static void add_vcall_offset (tree, tree, vtbl_init_data *);
+static void layout_vtable_decl (tree, int);
+static tree dfs_find_final_overrider_pre (tree, void *);
+static tree dfs_find_final_overrider_post (tree, void *);
+static tree find_final_overrider (tree, tree, tree);
+static int make_new_vtable (tree, tree);
+static tree get_primary_binfo (tree);
+static int maybe_indent_hierarchy (FILE *, int, int);
+static tree dump_class_hierarchy_r (FILE *, int, tree, tree, int);
+static void dump_class_hierarchy (tree);
+static void dump_class_hierarchy_1 (FILE *, int, tree);
+static void dump_array (FILE *, tree);
+static void dump_vtable (tree, tree, tree);
+static void dump_vtt (tree, tree);
+static void dump_thunk (FILE *, int, tree);
+static tree build_vtable (tree, tree, tree);
+static void initialize_vtable (tree, vec<constructor_elt, va_gc> *);
+static void layout_nonempty_base_or_field (record_layout_info,
+ tree, tree, splay_tree);
+static tree end_of_class (tree, int);
+static bool layout_empty_base (record_layout_info, tree, tree, splay_tree);
+static void accumulate_vtbl_inits (tree, tree, tree, tree, tree,
+ vec<constructor_elt, va_gc> **);
+static void dfs_accumulate_vtbl_inits (tree, tree, tree, tree, tree,
+ vec<constructor_elt, va_gc> **);
+static void build_rtti_vtbl_entries (tree, vtbl_init_data *);
+static void build_vcall_and_vbase_vtbl_entries (tree, vtbl_init_data *);
+static void clone_constructors_and_destructors (tree);
+static tree build_clone (tree, tree);
+static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned);
+static void build_ctor_vtbl_group (tree, tree);
+static void build_vtt (tree);
+static tree binfo_ctor_vtable (tree);
+static void build_vtt_inits (tree, tree, vec<constructor_elt, va_gc> **,
+ tree *);
+static tree dfs_build_secondary_vptr_vtt_inits (tree, void *);
+static tree dfs_fixup_binfo_vtbls (tree, void *);
+static int record_subobject_offset (tree, tree, splay_tree);
+static int check_subobject_offset (tree, tree, splay_tree);
+static int walk_subobject_offsets (tree, subobject_offset_fn,
+ tree, splay_tree, tree, int);
+static void record_subobject_offsets (tree, tree, splay_tree, bool);
+static int layout_conflict_p (tree, tree, splay_tree, int);
+static int splay_tree_compare_integer_csts (splay_tree_key k1,
+ splay_tree_key k2);
+static void warn_about_ambiguous_bases (tree);
+static bool type_requires_array_cookie (tree);
+static bool contains_empty_class_p (tree);
+static bool base_derived_from (tree, tree);
+static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree);
+static tree end_of_base (tree);
+static tree get_vcall_index (tree, tree);
+
+/* Variables shared between class.c and call.c. */
+
+int n_vtables = 0;
+int n_vtable_entries = 0;
+int n_vtable_searches = 0;
+int n_vtable_elems = 0;
+int n_convert_harshness = 0;
+int n_compute_conversion_costs = 0;
+int n_inner_fields_searched = 0;
+
+/* Convert to or from a base subobject. EXPR is an expression of type
+ `A' or `A*', an expression of type `B' or `B*' is returned. To
+ convert A to a base B, CODE is PLUS_EXPR and BINFO is the binfo for
+ the B base instance within A. To convert base A to derived B, CODE
+ is MINUS_EXPR and BINFO is the binfo for the A instance within B.
+ In this latter case, A must not be a morally virtual base of B.
+ NONNULL is true if EXPR is known to be non-NULL (this is only
+ needed when EXPR is of pointer type). CV qualifiers are preserved
+ from EXPR. */
+
+tree
+build_base_path (enum tree_code code,
+ tree expr,
+ tree binfo,
+ int nonnull,
+ tsubst_flags_t complain)
+{
+ tree v_binfo = NULL_TREE;
+ tree d_binfo = NULL_TREE;
+ tree probe;
+ tree offset;
+ tree target_type;
+ tree null_test = NULL;
+ tree ptr_target_type;
+ int fixed_type_p;
+ int want_pointer = TYPE_PTR_P (TREE_TYPE (expr));
+ bool has_empty = false;
+ bool virtual_access;
+
+ if (expr == error_mark_node || binfo == error_mark_node || !binfo)
+ return error_mark_node;
+
+ for (probe = binfo; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
+ {
+ d_binfo = probe;
+ if (is_empty_class (BINFO_TYPE (probe)))
+ has_empty = true;
+ if (!v_binfo && BINFO_VIRTUAL_P (probe))
+ v_binfo = probe;
+ }
+
+ probe = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
+ if (want_pointer)
+ probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
+
+ if (code == PLUS_EXPR
+ && !SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe))
+ {
+ /* This can happen when adjust_result_of_qualified_name_lookup can't
+ find a unique base binfo in a call to a member function. We
+ couldn't give the diagnostic then since we might have been calling
+ a static member function, so we do it now. */
+ if (complain & tf_error)
+ {
+ tree base = lookup_base (probe, BINFO_TYPE (d_binfo),
+ ba_unique, NULL, complain);
+ gcc_assert (base == error_mark_node);
+ }
+ return error_mark_node;
+ }
+
+ gcc_assert ((code == MINUS_EXPR
+ && SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), probe))
+ || code == PLUS_EXPR);
+
+ if (binfo == d_binfo)
+ /* Nothing to do. */
+ return expr;
+
+ if (code == MINUS_EXPR && v_binfo)
+ {
+ if (complain & tf_error)
+ {
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (v_binfo)))
+ {
+ if (want_pointer)
+ error ("cannot convert from pointer to base class %qT to "
+ "pointer to derived class %qT because the base is "
+ "virtual", BINFO_TYPE (binfo), BINFO_TYPE (d_binfo));
+ else
+ error ("cannot convert from base class %qT to derived "
+ "class %qT because the base is virtual",
+ BINFO_TYPE (binfo), BINFO_TYPE (d_binfo));
+ }
+ else
+ {
+ if (want_pointer)
+ error ("cannot convert from pointer to base class %qT to "
+ "pointer to derived class %qT via virtual base %qT",
+ BINFO_TYPE (binfo), BINFO_TYPE (d_binfo),
+ BINFO_TYPE (v_binfo));
+ else
+ error ("cannot convert from base class %qT to derived "
+ "class %qT via virtual base %qT", BINFO_TYPE (binfo),
+ BINFO_TYPE (d_binfo), BINFO_TYPE (v_binfo));
+ }
+ }
+ return error_mark_node;
+ }
+
+ if (!want_pointer)
+ /* This must happen before the call to save_expr. */
+ expr = cp_build_addr_expr (expr, complain);
+ else
+ expr = mark_rvalue_use (expr);
+
+ offset = BINFO_OFFSET (binfo);
+ fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
+ target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
+ /* TARGET_TYPE has been extracted from BINFO, and, is therefore always
+ cv-unqualified. Extract the cv-qualifiers from EXPR so that the
+ expression returned matches the input. */
+ target_type = cp_build_qualified_type
+ (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
+ ptr_target_type = build_pointer_type (target_type);
+
+ /* Do we need to look in the vtable for the real offset? */
+ virtual_access = (v_binfo && fixed_type_p <= 0);
+
+ /* Don't bother with the calculations inside sizeof; they'll ICE if the
+ source type is incomplete and the pointer value doesn't matter. In a
+ template (even in fold_non_dependent_expr), we don't have vtables set
+ up properly yet, and the value doesn't matter there either; we're just
+ interested in the result of overload resolution. */
+ if (cp_unevaluated_operand != 0
+ || in_template_function ())
+ {
+ expr = build_nop (ptr_target_type, expr);
+ if (!want_pointer)
+ expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
+ return expr;
+ }
+
+ /* If we're in an NSDMI, we don't have the full constructor context yet
+ that we need for converting to a virtual base, so just build a stub
+ CONVERT_EXPR and expand it later in bot_replace. */
+ if (virtual_access && fixed_type_p < 0
+ && current_scope () != current_function_decl)
+ {
+ expr = build1 (CONVERT_EXPR, ptr_target_type, expr);
+ CONVERT_EXPR_VBASE_PATH (expr) = true;
+ if (!want_pointer)
+ expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
+ return expr;
+ }
+
+ /* Do we need to check for a null pointer? */
+ if (want_pointer && !nonnull)
+ {
+ /* If we know the conversion will not actually change the value
+ of EXPR, then we can avoid testing the expression for NULL.
+ We have to avoid generating a COMPONENT_REF for a base class
+ field, because other parts of the compiler know that such
+ expressions are always non-NULL. */
+ if (!virtual_access && integer_zerop (offset))
+ return build_nop (ptr_target_type, expr);
+ null_test = error_mark_node;
+ }
+
+ /* Protect against multiple evaluation if necessary. */
+ if (TREE_SIDE_EFFECTS (expr) && (null_test || virtual_access))
+ expr = save_expr (expr);
+
+ /* Now that we've saved expr, build the real null test. */
+ if (null_test)
+ {
+ tree zero = cp_convert (TREE_TYPE (expr), nullptr_node, complain);
+ null_test = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
+ expr, zero);
+ }
+
+ /* If this is a simple base reference, express it as a COMPONENT_REF. */
+ if (code == PLUS_EXPR && !virtual_access
+ /* We don't build base fields for empty bases, and they aren't very
+ interesting to the optimizers anyway. */
+ && !has_empty)
+ {
+ expr = cp_build_indirect_ref (expr, RO_NULL, complain);
+ expr = build_simple_base_path (expr, binfo);
+ if (want_pointer)
+ expr = build_address (expr);
+ target_type = TREE_TYPE (expr);
+ goto out;
+ }
+
+ if (virtual_access)
+ {
+ /* Going via virtual base V_BINFO. We need the static offset
+ from V_BINFO to BINFO, and the dynamic offset from D_BINFO to
+ V_BINFO. That offset is an entry in D_BINFO's vtable. */
+ tree v_offset;
+
+ if (fixed_type_p < 0 && in_base_initializer)
+ {
+ /* In a base member initializer, we cannot rely on the
+ vtable being set up. We have to indirect via the
+ vtt_parm. */
+ tree t;
+
+ t = TREE_TYPE (TYPE_VFIELD (current_class_type));
+ t = build_pointer_type (t);
+ v_offset = convert (t, current_vtt_parm);
+ v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
+ }
+ else
+ v_offset = build_vfield_ref (cp_build_indirect_ref (expr, RO_NULL,
+ complain),
+ TREE_TYPE (TREE_TYPE (expr)));
+
+ if (v_offset == error_mark_node)
+ return error_mark_node;
+
+ v_offset = fold_build_pointer_plus (v_offset, BINFO_VPTR_FIELD (v_binfo));
+ v_offset = build1 (NOP_EXPR,
+ build_pointer_type (ptrdiff_type_node),
+ v_offset);
+ v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
+ TREE_CONSTANT (v_offset) = 1;
+
+ offset = convert_to_integer (ptrdiff_type_node,
+ size_diffop_loc (input_location, offset,
+ BINFO_OFFSET (v_binfo)));
+
+ if (!integer_zerop (offset))
+ v_offset = build2 (code, ptrdiff_type_node, v_offset, offset);
+
+ if (fixed_type_p < 0)
+ /* Negative fixed_type_p means this is a constructor or destructor;
+ virtual base layout is fixed in in-charge [cd]tors, but not in
+ base [cd]tors. */
+ offset = build3 (COND_EXPR, ptrdiff_type_node,
+ build2 (EQ_EXPR, boolean_type_node,
+ current_in_charge_parm, integer_zero_node),
+ v_offset,
+ convert_to_integer (ptrdiff_type_node,
+ BINFO_OFFSET (binfo)));
+ else
+ offset = v_offset;
+ }
+
+ if (want_pointer)
+ target_type = ptr_target_type;
+
+ expr = build1 (NOP_EXPR, ptr_target_type, expr);
+
+ if (!integer_zerop (offset))
+ {
+ offset = fold_convert (sizetype, offset);
+ if (code == MINUS_EXPR)
+ offset = fold_build1_loc (input_location, NEGATE_EXPR, sizetype, offset);
+ expr = fold_build_pointer_plus (expr, offset);
+ }
+ else
+ null_test = NULL;
+
+ if (!want_pointer)
+ expr = cp_build_indirect_ref (expr, RO_NULL, complain);
+
+ out:
+ if (null_test)
+ expr = fold_build3_loc (input_location, COND_EXPR, target_type, null_test, expr,
+ build_zero_cst (target_type));
+
+ return expr;
+}
+
+/* Subroutine of build_base_path; EXPR and BINFO are as in that function.
+ Perform a derived-to-base conversion by recursively building up a
+ sequence of COMPONENT_REFs to the appropriate base fields. */
+
+static tree
+build_simple_base_path (tree expr, tree binfo)
+{
+ tree type = BINFO_TYPE (binfo);
+ tree d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
+ tree field;
+
+ if (d_binfo == NULL_TREE)
+ {
+ tree temp;
+
+ gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type);
+
+ /* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x'
+ into `(*(a ? &b : &c)).x', and so on. A COND_EXPR is only
+ an lvalue in the front end; only _DECLs and _REFs are lvalues
+ in the back end. */
+ temp = unary_complex_lvalue (ADDR_EXPR, expr);
+ if (temp)
+ expr = cp_build_indirect_ref (temp, RO_NULL, tf_warning_or_error);
+
+ return expr;
+ }
+
+ /* Recurse. */
+ expr = build_simple_base_path (expr, d_binfo);
+
+ for (field = TYPE_FIELDS (BINFO_TYPE (d_binfo));
+ field; field = DECL_CHAIN (field))
+ /* Is this the base field created by build_base_field? */
+ if (TREE_CODE (field) == FIELD_DECL
+ && DECL_FIELD_IS_BASE (field)
+ && TREE_TYPE (field) == type
+ /* If we're looking for a field in the most-derived class,
+ also check the field offset; we can have two base fields
+ of the same type if one is an indirect virtual base and one
+ is a direct non-virtual base. */
+ && (BINFO_INHERITANCE_CHAIN (d_binfo)
+ || tree_int_cst_equal (byte_position (field),
+ BINFO_OFFSET (binfo))))
+ {
+ /* We don't use build_class_member_access_expr here, as that
+ has unnecessary checks, and more importantly results in
+ recursive calls to dfs_walk_once. */
+ int type_quals = cp_type_quals (TREE_TYPE (expr));
+
+ expr = build3 (COMPONENT_REF,
+ cp_build_qualified_type (type, type_quals),
+ expr, field, NULL_TREE);
+ expr = fold_if_not_in_template (expr);
+
+ /* Mark the expression const or volatile, as appropriate.
+ Even though we've dealt with the type above, we still have
+ to mark the expression itself. */
+ if (type_quals & TYPE_QUAL_CONST)
+ TREE_READONLY (expr) = 1;
+ if (type_quals & TYPE_QUAL_VOLATILE)
+ TREE_THIS_VOLATILE (expr) = 1;
+
+ return expr;
+ }
+
+ /* Didn't find the base field?!? */
+ gcc_unreachable ();
+}
+
+/* Convert OBJECT to the base TYPE. OBJECT is an expression whose
+ type is a class type or a pointer to a class type. In the former
+ case, TYPE is also a class type; in the latter it is another
+ pointer type. If CHECK_ACCESS is true, an error message is emitted
+ if TYPE is inaccessible. If OBJECT has pointer type, the value is
+ assumed to be non-NULL. */
+
+tree
+convert_to_base (tree object, tree type, bool check_access, bool nonnull,
+ tsubst_flags_t complain)
+{
+ tree binfo;
+ tree object_type;
+
+ if (TYPE_PTR_P (TREE_TYPE (object)))
+ {
+ object_type = TREE_TYPE (TREE_TYPE (object));
+ type = TREE_TYPE (type);
+ }
+ else
+ object_type = TREE_TYPE (object);
+
+ binfo = lookup_base (object_type, type, check_access ? ba_check : ba_unique,
+ NULL, complain);
+ if (!binfo || binfo == error_mark_node)
+ return error_mark_node;
+
+ return build_base_path (PLUS_EXPR, object, binfo, nonnull, complain);
+}
+
+/* EXPR is an expression with unqualified class type. BASE is a base
+ binfo of that class type. Returns EXPR, converted to the BASE
+ type. This function assumes that EXPR is the most derived class;
+ therefore virtual bases can be found at their static offsets. */
+
+tree
+convert_to_base_statically (tree expr, tree base)
+{
+ tree expr_type;
+
+ expr_type = TREE_TYPE (expr);
+ if (!SAME_BINFO_TYPE_P (BINFO_TYPE (base), expr_type))
+ {
+ /* If this is a non-empty base, use a COMPONENT_REF. */
+ if (!is_empty_class (BINFO_TYPE (base)))
+ return build_simple_base_path (expr, base);
+
+ /* We use fold_build2 and fold_convert below to simplify the trees
+ provided to the optimizers. It is not safe to call these functions
+ when processing a template because they do not handle C++-specific
+ trees. */
+ gcc_assert (!processing_template_decl);
+ expr = cp_build_addr_expr (expr, tf_warning_or_error);
+ if (!integer_zerop (BINFO_OFFSET (base)))
+ expr = fold_build_pointer_plus_loc (input_location,
+ expr, BINFO_OFFSET (base));
+ expr = fold_convert (build_pointer_type (BINFO_TYPE (base)), expr);
+ expr = build_fold_indirect_ref_loc (input_location, expr);
+ }
+
+ return expr;
+}
+
+
+tree
+build_vfield_ref (tree datum, tree type)
+{
+ tree vfield, vcontext;
+
+ if (datum == error_mark_node
+ /* Can happen in case of duplicate base types (c++/59082). */
+ || !TYPE_VFIELD (type))
+ return error_mark_node;
+
+ /* First, convert to the requested type. */
+ if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
+ datum = convert_to_base (datum, type, /*check_access=*/false,
+ /*nonnull=*/true, tf_warning_or_error);
+
+ /* Second, the requested type may not be the owner of its own vptr.
+ If not, convert to the base class that owns it. We cannot use
+ convert_to_base here, because VCONTEXT may appear more than once
+ in the inheritance hierarchy of TYPE, and thus direct conversion
+ between the types may be ambiguous. Following the path back up
+ one step at a time via primary bases avoids the problem. */
+ vfield = TYPE_VFIELD (type);
+ vcontext = DECL_CONTEXT (vfield);
+ while (!same_type_ignoring_top_level_qualifiers_p (vcontext, type))
+ {
+ datum = build_simple_base_path (datum, CLASSTYPE_PRIMARY_BINFO (type));
+ type = TREE_TYPE (datum);
+ }
+
+ return build3 (COMPONENT_REF, TREE_TYPE (vfield), datum, vfield, NULL_TREE);
+}
+
+/* Given an object INSTANCE, return an expression which yields the
+ vtable element corresponding to INDEX. There are many special
+ cases for INSTANCE which we take care of here, mainly to avoid
+ creating extra tree nodes when we don't have to. */
+
+static tree
+build_vtbl_ref_1 (tree instance, tree idx)
+{
+ tree aref;
+ tree vtbl = NULL_TREE;
+
+ /* Try to figure out what a reference refers to, and
+ access its virtual function table directly. */
+
+ int cdtorp = 0;
+ tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
+
+ tree basetype = non_reference (TREE_TYPE (instance));
+
+ if (fixed_type && !cdtorp)
+ {
+ tree binfo = lookup_base (fixed_type, basetype,
+ ba_unique, NULL, tf_none);
+ if (binfo && binfo != error_mark_node)
+ vtbl = unshare_expr (BINFO_VTABLE (binfo));
+ }
+
+ if (!vtbl)
+ vtbl = build_vfield_ref (instance, basetype);
+
+ aref = build_array_ref (input_location, vtbl, idx);
+ TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx);
+
+ return aref;
+}
+
+tree
+build_vtbl_ref (tree instance, tree idx)
+{
+ tree aref = build_vtbl_ref_1 (instance, idx);
+
+ return aref;
+}
+
+/* Given a stable object pointer INSTANCE_PTR, return an expression which
+ yields a function pointer corresponding to vtable element INDEX. */
+
+tree
+build_vfn_ref (tree instance_ptr, tree idx)
+{
+ tree aref;
+
+ aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, RO_NULL,
+ tf_warning_or_error),
+ idx);
+
+ /* When using function descriptors, the address of the
+ vtable entry is treated as a function pointer. */
+ if (TARGET_VTABLE_USES_DESCRIPTORS)
+ aref = build1 (NOP_EXPR, TREE_TYPE (aref),
+ cp_build_addr_expr (aref, tf_warning_or_error));
+
+ /* Remember this as a method reference, for later devirtualization. */
+ aref = build3 (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx);
+
+ return aref;
+}
+
+/* Return the name of the virtual function table (as an IDENTIFIER_NODE)
+ for the given TYPE. */
+
+static tree
+get_vtable_name (tree type)
+{
+ return mangle_vtbl_for_type (type);
+}
+
+/* DECL is an entity associated with TYPE, like a virtual table or an
+ implicitly generated constructor. Determine whether or not DECL
+ should have external or internal linkage at the object file
+ level. This routine does not deal with COMDAT linkage and other
+ similar complexities; it simply sets TREE_PUBLIC if it possible for
+ entities in other translation units to contain copies of DECL, in
+ the abstract. */
+
+void
+set_linkage_according_to_type (tree /*type*/, tree decl)
+{
+ TREE_PUBLIC (decl) = 1;
+ determine_visibility (decl);
+}
+
+/* Create a VAR_DECL for a primary or secondary vtable for CLASS_TYPE.
+ (For a secondary vtable for B-in-D, CLASS_TYPE should be D, not B.)
+ Use NAME for the name of the vtable, and VTABLE_TYPE for its type. */
+
+static tree
+build_vtable (tree class_type, tree name, tree vtable_type)
+{
+ tree decl;
+
+ decl = build_lang_decl (VAR_DECL, name, vtable_type);
+ /* vtable names are already mangled; give them their DECL_ASSEMBLER_NAME
+ now to avoid confusion in mangle_decl. */
+ SET_DECL_ASSEMBLER_NAME (decl, name);
+ DECL_CONTEXT (decl) = class_type;
+ DECL_ARTIFICIAL (decl) = 1;
+ TREE_STATIC (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ DECL_VIRTUAL_P (decl) = 1;
+ DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
+ DECL_VTABLE_OR_VTT_P (decl) = 1;
+ /* At one time the vtable info was grabbed 2 words at a time. This
+ fails on sparc unless you have 8-byte alignment. (tiemann) */
+ DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
+ DECL_ALIGN (decl));
+ set_linkage_according_to_type (class_type, decl);
+ /* The vtable has not been defined -- yet. */
+ DECL_EXTERNAL (decl) = 1;
+ DECL_NOT_REALLY_EXTERN (decl) = 1;
+
+ /* Mark the VAR_DECL node representing the vtable itself as a
+ "gratuitous" one, thereby forcing dwarfout.c to ignore it. It
+ is rather important that such things be ignored because any
+ effort to actually generate DWARF for them will run into
+ trouble when/if we encounter code like:
+
+ #pragma interface
+ struct S { virtual void member (); };
+
+ because the artificial declaration of the vtable itself (as
+ manufactured by the g++ front end) will say that the vtable is
+ a static member of `S' but only *after* the debug output for
+ the definition of `S' has already been output. This causes
+ grief because the DWARF entry for the definition of the vtable
+ will try to refer back to an earlier *declaration* of the
+ vtable as a static member of `S' and there won't be one. We
+ might be able to arrange to have the "vtable static member"
+ attached to the member list for `S' before the debug info for
+ `S' get written (which would solve the problem) but that would
+ require more intrusive changes to the g++ front end. */
+ DECL_IGNORED_P (decl) = 1;
+
+ return decl;
+}
+
+/* Get the VAR_DECL of the vtable for TYPE. TYPE need not be polymorphic,
+ or even complete. If this does not exist, create it. If COMPLETE is
+ nonzero, then complete the definition of it -- that will render it
+ impossible to actually build the vtable, but is useful to get at those
+ which are known to exist in the runtime. */
+
+tree
+get_vtable_decl (tree type, int complete)
+{
+ tree decl;
+
+ if (CLASSTYPE_VTABLES (type))
+ return CLASSTYPE_VTABLES (type);
+
+ decl = build_vtable (type, get_vtable_name (type), vtbl_type_node);
+ CLASSTYPE_VTABLES (type) = decl;
+
+ if (complete)
+ {
+ DECL_EXTERNAL (decl) = 1;
+ cp_finish_decl (decl, NULL_TREE, false, NULL_TREE, 0);
+ }
+
+ return decl;
+}
+
+/* Build the primary virtual function table for TYPE. If BINFO is
+ non-NULL, build the vtable starting with the initial approximation
+ that it is the same as the one which is the head of the association
+ list. Returns a nonzero value if a new vtable is actually
+ created. */
+
+static int
+build_primary_vtable (tree binfo, tree type)
+{
+ tree decl;
+ tree virtuals;
+
+ decl = get_vtable_decl (type, /*complete=*/0);
+
+ if (binfo)
+ {
+ if (BINFO_NEW_VTABLE_MARKED (binfo))
+ /* We have already created a vtable for this base, so there's
+ no need to do it again. */
+ return 0;
+
+ virtuals = copy_list (BINFO_VIRTUALS (binfo));
+ TREE_TYPE (decl) = TREE_TYPE (get_vtbl_decl_for_binfo (binfo));
+ DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (decl));
+ DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
+ }
+ else
+ {
+ gcc_assert (TREE_TYPE (decl) == vtbl_type_node);
+ virtuals = NULL_TREE;
+ }
+
+ if (GATHER_STATISTICS)
+ {
+ n_vtables += 1;
+ n_vtable_elems += list_length (virtuals);
+ }
+
+ /* Initialize the association list for this type, based
+ on our first approximation. */
+ BINFO_VTABLE (TYPE_BINFO (type)) = decl;
+ BINFO_VIRTUALS (TYPE_BINFO (type)) = virtuals;
+ SET_BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (type));
+ return 1;
+}
+
+/* Give BINFO a new virtual function table which is initialized
+ with a skeleton-copy of its original initialization. The only
+ entry that changes is the `delta' entry, so we can really
+ share a lot of structure.
+
+ FOR_TYPE is the most derived type which caused this table to
+ be needed.
+
+ Returns nonzero if we haven't met BINFO before.
+
+ The order in which vtables are built (by calling this function) for
+ an object must remain the same, otherwise a binary incompatibility
+ can result. */
+
+static int
+build_secondary_vtable (tree binfo)
+{
+ if (BINFO_NEW_VTABLE_MARKED (binfo))
+ /* We already created a vtable for this base. There's no need to
+ do it again. */
+ return 0;
+
+ /* Remember that we've created a vtable for this BINFO, so that we
+ don't try to do so again. */
+ SET_BINFO_NEW_VTABLE_MARKED (binfo);
+
+ /* Make fresh virtual list, so we can smash it later. */
+ BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
+
+ /* Secondary vtables are laid out as part of the same structure as
+ the primary vtable. */
+ BINFO_VTABLE (binfo) = NULL_TREE;
+ return 1;
+}
+
+/* Create a new vtable for BINFO which is the hierarchy dominated by
+ T. Return nonzero if we actually created a new vtable. */
+
+static int
+make_new_vtable (tree t, tree binfo)
+{
+ if (binfo == TYPE_BINFO (t))
+ /* In this case, it is *type*'s vtable we are modifying. We start
+ with the approximation that its vtable is that of the
+ immediate base class. */
+ return build_primary_vtable (binfo, t);
+ else
+ /* This is our very own copy of `basetype' to play with. Later,
+ we will fill in all the virtual functions that override the
+ virtual functions in these base classes which are not defined
+ by the current type. */
+ return build_secondary_vtable (binfo);
+}
+
+/* Make *VIRTUALS, an entry on the BINFO_VIRTUALS list for BINFO
+ (which is in the hierarchy dominated by T) list FNDECL as its
+ BV_FN. DELTA is the required constant adjustment from the `this'
+ pointer where the vtable entry appears to the `this' required when
+ the function is actually called. */
+
+static void
+modify_vtable_entry (tree t,
+ tree binfo,
+ tree fndecl,
+ tree delta,
+ tree *virtuals)
+{
+ tree v;
+
+ v = *virtuals;
+
+ if (fndecl != BV_FN (v)
+ || !tree_int_cst_equal (delta, BV_DELTA (v)))
+ {
+ /* We need a new vtable for BINFO. */
+ if (make_new_vtable (t, binfo))
+ {
+ /* If we really did make a new vtable, we also made a copy
+ of the BINFO_VIRTUALS list. Now, we have to find the
+ corresponding entry in that list. */
+ *virtuals = BINFO_VIRTUALS (binfo);
+ while (BV_FN (*virtuals) != BV_FN (v))
+ *virtuals = TREE_CHAIN (*virtuals);
+ v = *virtuals;
+ }
+
+ BV_DELTA (v) = delta;
+ BV_VCALL_INDEX (v) = NULL_TREE;
+ BV_FN (v) = fndecl;
+ }
+}
+
+
+/* Add method METHOD to class TYPE. If USING_DECL is non-null, it is
+ the USING_DECL naming METHOD. Returns true if the method could be
+ added to the method vec. */
+
+bool
+add_method (tree type, tree method, tree using_decl)
+{
+ unsigned slot;
+ tree overload;
+ bool template_conv_p = false;
+ bool conv_p;
+ vec<tree, va_gc> *method_vec;
+ bool complete_p;
+ bool insert_p = false;
+ tree current_fns;
+ tree fns;
+
+ if (method == error_mark_node)
+ return false;
+
+ complete_p = COMPLETE_TYPE_P (type);
+ conv_p = DECL_CONV_FN_P (method);
+ if (conv_p)
+ template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
+ && DECL_TEMPLATE_CONV_FN_P (method));
+
+ method_vec = CLASSTYPE_METHOD_VEC (type);
+ if (!method_vec)
+ {
+ /* Make a new method vector. We start with 8 entries. We must
+ allocate at least two (for constructors and destructors), and
+ we're going to end up with an assignment operator at some
+ point as well. */
+ vec_alloc (method_vec, 8);
+ /* Create slots for constructors and destructors. */
+ method_vec->quick_push (NULL_TREE);
+ method_vec->quick_push (NULL_TREE);
+ CLASSTYPE_METHOD_VEC (type) = method_vec;
+ }
+
+ /* Maintain TYPE_HAS_USER_CONSTRUCTOR, etc. */
+ grok_special_member_properties (method);
+
+ /* Constructors and destructors go in special slots. */
+ if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (method))
+ slot = CLASSTYPE_CONSTRUCTOR_SLOT;
+ else if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
+ {
+ slot = CLASSTYPE_DESTRUCTOR_SLOT;
+
+ if (TYPE_FOR_JAVA (type))
+ {
+ if (!DECL_ARTIFICIAL (method))
+ error ("Java class %qT cannot have a destructor", type);
+ else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ error ("Java class %qT cannot have an implicit non-trivial "
+ "destructor",
+ type);
+ }
+ }
+ else
+ {
+ tree m;
+
+ insert_p = true;
+ /* See if we already have an entry with this name. */
+ for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ vec_safe_iterate (method_vec, slot, &m);
+ ++slot)
+ {
+ m = OVL_CURRENT (m);
+ if (template_conv_p)
+ {
+ if (TREE_CODE (m) == TEMPLATE_DECL
+ && DECL_TEMPLATE_CONV_FN_P (m))
+ insert_p = false;
+ break;
+ }
+ if (conv_p && !DECL_CONV_FN_P (m))
+ break;
+ if (DECL_NAME (m) == DECL_NAME (method))
+ {
+ insert_p = false;
+ break;
+ }
+ if (complete_p
+ && !DECL_CONV_FN_P (m)
+ && DECL_NAME (m) > DECL_NAME (method))
+ break;
+ }
+ }
+ current_fns = insert_p ? NULL_TREE : (*method_vec)[slot];
+
+ /* Check to see if we've already got this method. */
+ for (fns = current_fns; fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ tree fn_type;
+ tree method_type;
+ tree parms1;
+ tree parms2;
+
+ if (TREE_CODE (fn) != TREE_CODE (method))
+ continue;
+
+ /* [over.load] Member function declarations with the
+ same name and the same parameter types cannot be
+ overloaded if any of them is a static member
+ function declaration.
+
+ [over.load] Member function declarations with the same name and
+ the same parameter-type-list as well as member function template
+ declarations with the same name, the same parameter-type-list, and
+ the same template parameter lists cannot be overloaded if any of
+ them, but not all, have a ref-qualifier.
+
+ [namespace.udecl] When a using-declaration brings names
+ from a base class into a derived class scope, member
+ functions in the derived class override and/or hide member
+ functions with the same name and parameter types in a base
+ class (rather than conflicting). */
+ fn_type = TREE_TYPE (fn);
+ method_type = TREE_TYPE (method);
+ parms1 = TYPE_ARG_TYPES (fn_type);
+ parms2 = TYPE_ARG_TYPES (method_type);
+
+ /* Compare the quals on the 'this' parm. Don't compare
+ the whole types, as used functions are treated as
+ coming from the using class in overload resolution. */
+ if (! DECL_STATIC_FUNCTION_P (fn)
+ && ! DECL_STATIC_FUNCTION_P (method)
+ /* Either both or neither need to be ref-qualified for
+ differing quals to allow overloading. */
+ && (FUNCTION_REF_QUALIFIED (fn_type)
+ == FUNCTION_REF_QUALIFIED (method_type))
+ && (type_memfn_quals (fn_type) != type_memfn_quals (method_type)
+ || type_memfn_rqual (fn_type) != type_memfn_rqual (method_type)))
+ continue;
+
+ /* For templates, the return type and template parameters
+ must be identical. */
+ if (TREE_CODE (fn) == TEMPLATE_DECL
+ && (!same_type_p (TREE_TYPE (fn_type),
+ TREE_TYPE (method_type))
+ || !comp_template_parms (DECL_TEMPLATE_PARMS (fn),
+ DECL_TEMPLATE_PARMS (method))))
+ continue;
+
+ if (! DECL_STATIC_FUNCTION_P (fn))
+ parms1 = TREE_CHAIN (parms1);
+ if (! DECL_STATIC_FUNCTION_P (method))
+ parms2 = TREE_CHAIN (parms2);
+
+ if (compparms (parms1, parms2)
+ && (!DECL_CONV_FN_P (fn)
+ || same_type_p (TREE_TYPE (fn_type),
+ TREE_TYPE (method_type))))
+ {
+ /* For function versions, their parms and types match
+ but they are not duplicates. Record function versions
+ as and when they are found. extern "C" functions are
+ not treated as versions. */
+ if (TREE_CODE (fn) == FUNCTION_DECL
+ && TREE_CODE (method) == FUNCTION_DECL
+ && !DECL_EXTERN_C_P (fn)
+ && !DECL_EXTERN_C_P (method)
+ && targetm.target_option.function_versions (fn, method))
+ {
+ /* Mark functions as versions if necessary. Modify the mangled
+ decl name if necessary. */
+ if (!DECL_FUNCTION_VERSIONED (fn))
+ {
+ DECL_FUNCTION_VERSIONED (fn) = 1;
+ if (DECL_ASSEMBLER_NAME_SET_P (fn))
+ mangle_decl (fn);
+ }
+ if (!DECL_FUNCTION_VERSIONED (method))
+ {
+ DECL_FUNCTION_VERSIONED (method) = 1;
+ if (DECL_ASSEMBLER_NAME_SET_P (method))
+ mangle_decl (method);
+ }
+ record_function_versions (fn, method);
+ continue;
+ }
+ if (DECL_INHERITED_CTOR_BASE (method))
+ {
+ if (DECL_INHERITED_CTOR_BASE (fn))
+ {
+ error_at (DECL_SOURCE_LOCATION (method),
+ "%q#D inherited from %qT", method,
+ DECL_INHERITED_CTOR_BASE (method));
+ error_at (DECL_SOURCE_LOCATION (fn),
+ "conflicts with version inherited from %qT",
+ DECL_INHERITED_CTOR_BASE (fn));
+ }
+ /* Otherwise defer to the other function. */
+ return false;
+ }
+ if (using_decl)
+ {
+ if (DECL_CONTEXT (fn) == type)
+ /* Defer to the local function. */
+ return false;
+ }
+ else
+ {
+ error ("%q+#D cannot be overloaded", method);
+ error ("with %q+#D", fn);
+ }
+
+ /* We don't call duplicate_decls here to merge the
+ declarations because that will confuse things if the
+ methods have inline definitions. In particular, we
+ will crash while processing the definitions. */
+ return false;
+ }
+ }
+
+ /* A class should never have more than one destructor. */
+ if (current_fns && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
+ return false;
+
+ /* Add the new binding. */
+ if (using_decl)
+ {
+ overload = ovl_cons (method, current_fns);
+ OVL_USED (overload) = true;
+ }
+ else
+ overload = build_overload (method, current_fns);
+
+ if (conv_p)
+ TYPE_HAS_CONVERSION (type) = 1;
+ else if (slot >= CLASSTYPE_FIRST_CONVERSION_SLOT && !complete_p)
+ push_class_level_binding (DECL_NAME (method), overload);
+
+ if (insert_p)
+ {
+ bool reallocated;
+
+ /* We only expect to add few methods in the COMPLETE_P case, so
+ just make room for one more method in that case. */
+ if (complete_p)
+ reallocated = vec_safe_reserve_exact (method_vec, 1);
+ else
+ reallocated = vec_safe_reserve (method_vec, 1);
+ if (reallocated)
+ CLASSTYPE_METHOD_VEC (type) = method_vec;
+ if (slot == method_vec->length ())
+ method_vec->quick_push (overload);
+ else
+ method_vec->quick_insert (slot, overload);
+ }
+ else
+ /* Replace the current slot. */
+ (*method_vec)[slot] = overload;
+ return true;
+}
+
+/* Subroutines of finish_struct. */
+
+/* Change the access of FDECL to ACCESS in T. Return 1 if change was
+ legit, otherwise return 0. */
+
+static int
+alter_access (tree t, tree fdecl, tree access)
+{
+ tree elem;
+
+ if (!DECL_LANG_SPECIFIC (fdecl))
+ retrofit_lang_decl (fdecl);
+
+ gcc_assert (!DECL_DISCRIMINATOR_P (fdecl));
+
+ elem = purpose_member (t, DECL_ACCESS (fdecl));
+ if (elem)
+ {
+ if (TREE_VALUE (elem) != access)
+ {
+ if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
+ error ("conflicting access specifications for method"
+ " %q+D, ignored", TREE_TYPE (fdecl));
+ else
+ error ("conflicting access specifications for field %qE, ignored",
+ DECL_NAME (fdecl));
+ }
+ else
+ {
+ /* They're changing the access to the same thing they changed
+ it to before. That's OK. */
+ ;
+ }
+ }
+ else
+ {
+ perform_or_defer_access_check (TYPE_BINFO (t), fdecl, fdecl,
+ tf_warning_or_error);
+ DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
+ return 1;
+ }
+ return 0;
+}
+
+/* Process the USING_DECL, which is a member of T. */
+
+static void
+handle_using_decl (tree using_decl, tree t)
+{
+ tree decl = USING_DECL_DECLS (using_decl);
+ tree name = DECL_NAME (using_decl);
+ tree access
+ = TREE_PRIVATE (using_decl) ? access_private_node
+ : TREE_PROTECTED (using_decl) ? access_protected_node
+ : access_public_node;
+ tree flist = NULL_TREE;
+ tree old_value;
+
+ gcc_assert (!processing_template_decl && decl);
+
+ old_value = lookup_member (t, name, /*protect=*/0, /*want_type=*/false,
+ tf_warning_or_error);
+ if (old_value)
+ {
+ if (is_overloaded_fn (old_value))
+ old_value = OVL_CURRENT (old_value);
+
+ if (DECL_P (old_value) && DECL_CONTEXT (old_value) == t)
+ /* OK */;
+ else
+ old_value = NULL_TREE;
+ }
+
+ cp_emit_debug_info_for_using (decl, USING_DECL_SCOPE (using_decl));
+
+ if (is_overloaded_fn (decl))
+ flist = decl;
+
+ if (! old_value)
+ ;
+ else if (is_overloaded_fn (old_value))
+ {
+ if (flist)
+ /* It's OK to use functions from a base when there are functions with
+ the same name already present in the current class. */;
+ else
+ {
+ error ("%q+D invalid in %q#T", using_decl, t);
+ error (" because of local method %q+#D with same name",
+ OVL_CURRENT (old_value));
+ return;
+ }
+ }
+ else if (!DECL_ARTIFICIAL (old_value))
+ {
+ error ("%q+D invalid in %q#T", using_decl, t);
+ error (" because of local member %q+#D with same name", old_value);
+ return;
+ }
+
+ /* Make type T see field decl FDECL with access ACCESS. */
+ if (flist)
+ for (; flist; flist = OVL_NEXT (flist))
+ {
+ add_method (t, OVL_CURRENT (flist), using_decl);
+ alter_access (t, OVL_CURRENT (flist), access);
+ }
+ else
+ alter_access (t, decl, access);
+}
+
+/* walk_tree callback for check_abi_tags: if the type at *TP involves any
+ types with abi tags, add the corresponding identifiers to the VEC in
+ *DATA and set IDENTIFIER_MARKED. */
+
+struct abi_tag_data
+{
+ tree t;
+ tree subob;
+ // error_mark_node to get diagnostics; otherwise collect missing tags here
+ tree tags;
+};
+
+static tree
+find_abi_tags_r (tree *tp, int *walk_subtrees, void *data)
+{
+ if (!OVERLOAD_TYPE_P (*tp))
+ return NULL_TREE;
+
+ /* walk_tree shouldn't be walking into any subtrees of a RECORD_TYPE
+ anyway, but let's make sure of it. */
+ *walk_subtrees = false;
+
+ if (tree attributes = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (*tp)))
+ {
+ struct abi_tag_data *p = static_cast<struct abi_tag_data*>(data);
+ for (tree list = TREE_VALUE (attributes); list;
+ list = TREE_CHAIN (list))
+ {
+ tree tag = TREE_VALUE (list);
+ tree id = get_identifier (TREE_STRING_POINTER (tag));
+ if (!IDENTIFIER_MARKED (id))
+ {
+ if (p->tags != error_mark_node)
+ {
+ /* We're collecting tags from template arguments. */
+ tree str = build_string (IDENTIFIER_LENGTH (id),
+ IDENTIFIER_POINTER (id));
+ p->tags = tree_cons (NULL_TREE, str, p->tags);
+ ABI_TAG_IMPLICIT (p->tags) = true;
+
+ /* Don't inherit this tag multiple times. */
+ IDENTIFIER_MARKED (id) = true;
+ }
+
+ /* Otherwise we're diagnosing missing tags. */
+ else if (TYPE_P (p->subob))
+ {
+ warning (OPT_Wabi_tag, "%qT does not have the %E abi tag "
+ "that base %qT has", p->t, tag, p->subob);
+ inform (location_of (p->subob), "%qT declared here",
+ p->subob);
+ }
+ else
+ {
+ warning (OPT_Wabi_tag, "%qT does not have the %E abi tag "
+ "that %qT (used in the type of %qD) has",
+ p->t, tag, *tp, p->subob);
+ inform (location_of (p->subob), "%qD declared here",
+ p->subob);
+ inform (location_of (*tp), "%qT declared here", *tp);
+ }
+ }
+ }
+ }
+ return NULL_TREE;
+}
+
+/* Set IDENTIFIER_MARKED on all the ABI tags on T and its (transitively
+ complete) template arguments. */
+
+static void
+mark_type_abi_tags (tree t, bool val)
+{
+ tree attributes = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t));
+ if (attributes)
+ {
+ for (tree list = TREE_VALUE (attributes); list;
+ list = TREE_CHAIN (list))
+ {
+ tree tag = TREE_VALUE (list);
+ tree id = get_identifier (TREE_STRING_POINTER (tag));
+ IDENTIFIER_MARKED (id) = val;
+ }
+ }
+}
+
+/* Check that class T has all the abi tags that subobject SUBOB has, or
+ warn if not. */
+
+static void
+check_abi_tags (tree t, tree subob)
+{
+ mark_type_abi_tags (t, true);
+
+ tree subtype = TYPE_P (subob) ? subob : TREE_TYPE (subob);
+ struct abi_tag_data data = { t, subob, error_mark_node };
+
+ cp_walk_tree_without_duplicates (&subtype, find_abi_tags_r, &data);
+
+ mark_type_abi_tags (t, false);
+}
+
+void
+inherit_targ_abi_tags (tree t)
+{
+ if (CLASSTYPE_TEMPLATE_INFO (t) == NULL_TREE)
+ return;
+
+ mark_type_abi_tags (t, true);
+
+ tree args = CLASSTYPE_TI_ARGS (t);
+ struct abi_tag_data data = { t, NULL_TREE, NULL_TREE };
+ for (int i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
+ {
+ tree level = TMPL_ARGS_LEVEL (args, i+1);
+ for (int j = 0; j < TREE_VEC_LENGTH (level); ++j)
+ {
+ tree arg = TREE_VEC_ELT (level, j);
+ data.subob = arg;
+ cp_walk_tree_without_duplicates (&arg, find_abi_tags_r, &data);
+ }
+ }
+
+ // If we found some tags on our template arguments, add them to our
+ // abi_tag attribute.
+ if (data.tags)
+ {
+ tree attr = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t));
+ if (attr)
+ TREE_VALUE (attr) = chainon (data.tags, TREE_VALUE (attr));
+ else
+ TYPE_ATTRIBUTES (t)
+ = tree_cons (get_identifier ("abi_tag"), data.tags,
+ TYPE_ATTRIBUTES (t));
+ }
+
+ mark_type_abi_tags (t, false);
+}
+
+/* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P,
+ and NO_CONST_ASN_REF_P. Also set flag bits in T based on
+ properties of the bases. */
+
+static void
+check_bases (tree t,
+ int* cant_have_const_ctor_p,
+ int* no_const_asn_ref_p)
+{
+ int i;
+ bool seen_non_virtual_nearly_empty_base_p = 0;
+ int seen_tm_mask = 0;
+ tree base_binfo;
+ tree binfo;
+ tree field = NULL_TREE;
+
+ if (!CLASSTYPE_NON_STD_LAYOUT (t))
+ for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL)
+ break;
+
+ for (binfo = TYPE_BINFO (t), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ {
+ tree basetype = TREE_TYPE (base_binfo);
+
+ gcc_assert (COMPLETE_TYPE_P (basetype));
+
+ if (CLASSTYPE_FINAL (basetype))
+ error ("cannot derive from %<final%> base %qT in derived type %qT",
+ basetype, t);
+
+ /* If any base class is non-literal, so is the derived class. */
+ if (!CLASSTYPE_LITERAL_P (basetype))
+ CLASSTYPE_LITERAL_P (t) = false;
+
+ /* Effective C++ rule 14. We only need to check TYPE_POLYMORPHIC_P
+ here because the case of virtual functions but non-virtual
+ dtor is handled in finish_struct_1. */
+ if (!TYPE_POLYMORPHIC_P (basetype))
+ warning (OPT_Weffc__,
+ "base class %q#T has a non-virtual destructor", basetype);
+
+ /* If the base class doesn't have copy constructors or
+ assignment operators that take const references, then the
+ derived class cannot have such a member automatically
+ generated. */
+ if (TYPE_HAS_COPY_CTOR (basetype)
+ && ! TYPE_HAS_CONST_COPY_CTOR (basetype))
+ *cant_have_const_ctor_p = 1;
+ if (TYPE_HAS_COPY_ASSIGN (basetype)
+ && !TYPE_HAS_CONST_COPY_ASSIGN (basetype))
+ *no_const_asn_ref_p = 1;
+
+ if (BINFO_VIRTUAL_P (base_binfo))
+ /* A virtual base does not effect nearly emptiness. */
+ ;
+ else if (CLASSTYPE_NEARLY_EMPTY_P (basetype))
+ {
+ if (seen_non_virtual_nearly_empty_base_p)
+ /* And if there is more than one nearly empty base, then the
+ derived class is not nearly empty either. */
+ CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+ else
+ /* Remember we've seen one. */
+ seen_non_virtual_nearly_empty_base_p = 1;
+ }
+ else if (!is_empty_class (basetype))
+ /* If the base class is not empty or nearly empty, then this
+ class cannot be nearly empty. */
+ CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+
+ /* A lot of properties from the bases also apply to the derived
+ class. */
+ TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
+ |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype);
+ TYPE_HAS_COMPLEX_COPY_ASSIGN (t)
+ |= (TYPE_HAS_COMPLEX_COPY_ASSIGN (basetype)
+ || !TYPE_HAS_COPY_ASSIGN (basetype));
+ TYPE_HAS_COMPLEX_COPY_CTOR (t) |= (TYPE_HAS_COMPLEX_COPY_CTOR (basetype)
+ || !TYPE_HAS_COPY_CTOR (basetype));
+ TYPE_HAS_COMPLEX_MOVE_ASSIGN (t)
+ |= TYPE_HAS_COMPLEX_MOVE_ASSIGN (basetype);
+ TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_HAS_COMPLEX_MOVE_CTOR (basetype);
+ TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
+ |= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
+ TYPE_HAS_COMPLEX_DFLT (t) |= (!TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
+ || TYPE_HAS_COMPLEX_DFLT (basetype));
+ SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT
+ (t, CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)
+ | CLASSTYPE_READONLY_FIELDS_NEED_INIT (basetype));
+ SET_CLASSTYPE_REF_FIELDS_NEED_INIT
+ (t, CLASSTYPE_REF_FIELDS_NEED_INIT (t)
+ | CLASSTYPE_REF_FIELDS_NEED_INIT (basetype));
+
+ /* A standard-layout class is a class that:
+ ...
+ * has no non-standard-layout base classes, */
+ CLASSTYPE_NON_STD_LAYOUT (t) |= CLASSTYPE_NON_STD_LAYOUT (basetype);
+ if (!CLASSTYPE_NON_STD_LAYOUT (t))
+ {
+ tree basefield;
+ /* ...has no base classes of the same type as the first non-static
+ data member... */
+ if (field && DECL_CONTEXT (field) == t
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (field), basetype)))
+ CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+ else
+ /* ...either has no non-static data members in the most-derived
+ class and at most one base class with non-static data
+ members, or has no base classes with non-static data
+ members */
+ for (basefield = TYPE_FIELDS (basetype); basefield;
+ basefield = DECL_CHAIN (basefield))
+ if (TREE_CODE (basefield) == FIELD_DECL)
+ {
+ if (field)
+ CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+ else
+ field = basefield;
+ break;
+ }
+ }
+
+ /* Don't bother collecting tm attributes if transactional memory
+ support is not enabled. */
+ if (flag_tm)
+ {
+ tree tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (basetype));
+ if (tm_attr)
+ seen_tm_mask |= tm_attr_to_mask (tm_attr);
+ }
+
+ check_abi_tags (t, basetype);
+ }
+
+ /* If one of the base classes had TM attributes, and the current class
+ doesn't define its own, then the current class inherits one. */
+ if (seen_tm_mask && !find_tm_attribute (TYPE_ATTRIBUTES (t)))
+ {
+ tree tm_attr = tm_mask_to_attr (seen_tm_mask & -seen_tm_mask);
+ TYPE_ATTRIBUTES (t) = tree_cons (tm_attr, NULL, TYPE_ATTRIBUTES (t));
+ }
+}
+
+/* Determine all the primary bases within T. Sets BINFO_PRIMARY_BASE_P for
+ those that are primaries. Sets BINFO_LOST_PRIMARY_P for those
+ that have had a nearly-empty virtual primary base stolen by some
+ other base in the hierarchy. Determines CLASSTYPE_PRIMARY_BASE for
+ T. */
+
+static void
+determine_primary_bases (tree t)
+{
+ unsigned i;
+ tree primary = NULL_TREE;
+ tree type_binfo = TYPE_BINFO (t);
+ tree base_binfo;
+
+ /* Determine the primary bases of our bases. */
+ for (base_binfo = TREE_CHAIN (type_binfo); base_binfo;
+ base_binfo = TREE_CHAIN (base_binfo))
+ {
+ tree primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (base_binfo));
+
+ /* See if we're the non-virtual primary of our inheritance
+ chain. */
+ if (!BINFO_VIRTUAL_P (base_binfo))
+ {
+ tree parent = BINFO_INHERITANCE_CHAIN (base_binfo);
+ tree parent_primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (parent));
+
+ if (parent_primary
+ && SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo),
+ BINFO_TYPE (parent_primary)))
+ /* We are the primary binfo. */
+ BINFO_PRIMARY_P (base_binfo) = 1;
+ }
+ /* Determine if we have a virtual primary base, and mark it so.
+ */
+ if (primary && BINFO_VIRTUAL_P (primary))
+ {
+ tree this_primary = copied_binfo (primary, base_binfo);
+
+ if (BINFO_PRIMARY_P (this_primary))
+ /* Someone already claimed this base. */
+ BINFO_LOST_PRIMARY_P (base_binfo) = 1;
+ else
+ {
+ tree delta;
+
+ BINFO_PRIMARY_P (this_primary) = 1;
+ BINFO_INHERITANCE_CHAIN (this_primary) = base_binfo;
+
+ /* A virtual binfo might have been copied from within
+ another hierarchy. As we're about to use it as a
+ primary base, make sure the offsets match. */
+ delta = size_diffop_loc (input_location,
+ convert (ssizetype,
+ BINFO_OFFSET (base_binfo)),
+ convert (ssizetype,
+ BINFO_OFFSET (this_primary)));
+
+ propagate_binfo_offsets (this_primary, delta);
+ }
+ }
+ }
+
+ /* First look for a dynamic direct non-virtual base. */
+ for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, base_binfo); i++)
+ {
+ tree basetype = BINFO_TYPE (base_binfo);
+
+ if (TYPE_CONTAINS_VPTR_P (basetype) && !BINFO_VIRTUAL_P (base_binfo))
+ {
+ primary = base_binfo;
+ goto found;
+ }
+ }
+
+ /* A "nearly-empty" virtual base class can be the primary base
+ class, if no non-virtual polymorphic base can be found. Look for
+ a nearly-empty virtual dynamic base that is not already a primary
+ base of something in the hierarchy. If there is no such base,
+ just pick the first nearly-empty virtual base. */
+
+ for (base_binfo = TREE_CHAIN (type_binfo); base_binfo;
+ base_binfo = TREE_CHAIN (base_binfo))
+ if (BINFO_VIRTUAL_P (base_binfo)
+ && CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (base_binfo)))
+ {
+ if (!BINFO_PRIMARY_P (base_binfo))
+ {
+ /* Found one that is not primary. */
+ primary = base_binfo;
+ goto found;
+ }
+ else if (!primary)
+ /* Remember the first candidate. */
+ primary = base_binfo;
+ }
+
+ found:
+ /* If we've got a primary base, use it. */
+ if (primary)
+ {
+ tree basetype = BINFO_TYPE (primary);
+
+ CLASSTYPE_PRIMARY_BINFO (t) = primary;
+ if (BINFO_PRIMARY_P (primary))
+ /* We are stealing a primary base. */
+ BINFO_LOST_PRIMARY_P (BINFO_INHERITANCE_CHAIN (primary)) = 1;
+ BINFO_PRIMARY_P (primary) = 1;
+ if (BINFO_VIRTUAL_P (primary))
+ {
+ tree delta;
+
+ BINFO_INHERITANCE_CHAIN (primary) = type_binfo;
+ /* A virtual binfo might have been copied from within
+ another hierarchy. As we're about to use it as a primary
+ base, make sure the offsets match. */
+ delta = size_diffop_loc (input_location, ssize_int (0),
+ convert (ssizetype, BINFO_OFFSET (primary)));
+
+ propagate_binfo_offsets (primary, delta);
+ }
+
+ primary = TYPE_BINFO (basetype);
+
+ TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
+ BINFO_VTABLE (type_binfo) = BINFO_VTABLE (primary);
+ BINFO_VIRTUALS (type_binfo) = BINFO_VIRTUALS (primary);
+ }
+}
+
+/* Update the variant types of T. */
+
+void
+fixup_type_variants (tree t)
+{
+ tree variants;
+
+ if (!t)
+ return;
+
+ for (variants = TYPE_NEXT_VARIANT (t);
+ variants;
+ variants = TYPE_NEXT_VARIANT (variants))
+ {
+ /* These fields are in the _TYPE part of the node, not in
+ the TYPE_LANG_SPECIFIC component, so they are not shared. */
+ TYPE_HAS_USER_CONSTRUCTOR (variants) = TYPE_HAS_USER_CONSTRUCTOR (t);
+ TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t);
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (variants)
+ = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
+
+ TYPE_POLYMORPHIC_P (variants) = TYPE_POLYMORPHIC_P (t);
+
+ TYPE_BINFO (variants) = TYPE_BINFO (t);
+
+ /* Copy whatever these are holding today. */
+ TYPE_VFIELD (variants) = TYPE_VFIELD (t);
+ TYPE_METHODS (variants) = TYPE_METHODS (t);
+ TYPE_FIELDS (variants) = TYPE_FIELDS (t);
+ }
+}
+
+/* Early variant fixups: we apply attributes at the beginning of the class
+ definition, and we need to fix up any variants that have already been
+ made via elaborated-type-specifier so that check_qualified_type works. */
+
+void
+fixup_attribute_variants (tree t)
+{
+ tree variants;
+
+ if (!t)
+ return;
+
+ for (variants = TYPE_NEXT_VARIANT (t);
+ variants;
+ variants = TYPE_NEXT_VARIANT (variants))
+ {
+ /* These are the two fields that check_qualified_type looks at and
+ are affected by attributes. */
+ TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (t);
+ TYPE_ALIGN (variants) = TYPE_ALIGN (t);
+ }
+}
+
+/* Set memoizing fields and bits of T (and its variants) for later
+ use. */
+
+static void
+finish_struct_bits (tree t)
+{
+ /* Fix up variants (if any). */
+ fixup_type_variants (t);
+
+ if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
+ /* For a class w/o baseclasses, 'finish_struct' has set
+ CLASSTYPE_PURE_VIRTUALS correctly (by definition).
+ Similarly for a class whose base classes do not have vtables.
+ When neither of these is true, we might have removed abstract
+ virtuals (by providing a definition), added some (by declaring
+ new ones), or redeclared ones from a base class. We need to
+ recalculate what's really an abstract virtual at this point (by
+ looking in the vtables). */
+ get_pure_virtuals (t);
+
+ /* If this type has a copy constructor or a destructor, force its
+ mode to be BLKmode, and force its TREE_ADDRESSABLE bit to be
+ nonzero. This will cause it to be passed by invisible reference
+ and prevent it from being returned in a register. */
+ if (type_has_nontrivial_copy_init (t)
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
+ {
+ tree variants;
+ DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;
+ for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))
+ {
+ SET_TYPE_MODE (variants, BLKmode);
+ TREE_ADDRESSABLE (variants) = 1;
+ }
+ }
+}
+
+/* Issue warnings about T having private constructors, but no friends,
+ and so forth.
+
+ HAS_NONPRIVATE_METHOD is nonzero if T has any non-private methods or
+ static members. HAS_NONPRIVATE_STATIC_FN is nonzero if T has any
+ non-private static member functions. */
+
+static void
+maybe_warn_about_overly_private_class (tree t)
+{
+ int has_member_fn = 0;
+ int has_nonprivate_method = 0;
+ tree fn;
+
+ if (!warn_ctor_dtor_privacy
+ /* If the class has friends, those entities might create and
+ access instances, so we should not warn. */
+ || (CLASSTYPE_FRIEND_CLASSES (t)
+ || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
+ /* We will have warned when the template was declared; there's
+ no need to warn on every instantiation. */
+ || CLASSTYPE_TEMPLATE_INSTANTIATION (t))
+ /* There's no reason to even consider warning about this
+ class. */
+ return;
+
+ /* We only issue one warning, if more than one applies, because
+ otherwise, on code like:
+
+ class A {
+ // Oops - forgot `public:'
+ A();
+ A(const A&);
+ ~A();
+ };
+
+ we warn several times about essentially the same problem. */
+
+ /* Check to see if all (non-constructor, non-destructor) member
+ functions are private. (Since there are no friends or
+ non-private statics, we can't ever call any of the private member
+ functions.) */
+ for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
+ /* We're not interested in compiler-generated methods; they don't
+ provide any way to call private members. */
+ if (!DECL_ARTIFICIAL (fn))
+ {
+ if (!TREE_PRIVATE (fn))
+ {
+ if (DECL_STATIC_FUNCTION_P (fn))
+ /* A non-private static member function is just like a
+ friend; it can create and invoke private member
+ functions, and be accessed without a class
+ instance. */
+ return;
+
+ has_nonprivate_method = 1;
+ /* Keep searching for a static member function. */
+ }
+ else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
+ has_member_fn = 1;
+ }
+
+ if (!has_nonprivate_method && has_member_fn)
+ {
+ /* There are no non-private methods, and there's at least one
+ private member function that isn't a constructor or
+ destructor. (If all the private members are
+ constructors/destructors we want to use the code below that
+ issues error messages specifically referring to
+ constructors/destructors.) */
+ unsigned i;
+ tree binfo = TYPE_BINFO (t);
+
+ for (i = 0; i != BINFO_N_BASE_BINFOS (binfo); i++)
+ if (BINFO_BASE_ACCESS (binfo, i) != access_private_node)
+ {
+ has_nonprivate_method = 1;
+ break;
+ }
+ if (!has_nonprivate_method)
+ {
+ warning (OPT_Wctor_dtor_privacy,
+ "all member functions in class %qT are private", t);
+ return;
+ }
+ }
+
+ /* Even if some of the member functions are non-private, the class
+ won't be useful for much if all the constructors or destructors
+ are private: such an object can never be created or destroyed. */
+ fn = CLASSTYPE_DESTRUCTORS (t);
+ if (fn && TREE_PRIVATE (fn))
+ {
+ warning (OPT_Wctor_dtor_privacy,
+ "%q#T only defines a private destructor and has no friends",
+ t);
+ return;
+ }
+
+ /* Warn about classes that have private constructors and no friends. */
+ if (TYPE_HAS_USER_CONSTRUCTOR (t)
+ /* Implicitly generated constructors are always public. */
+ && (!CLASSTYPE_LAZY_DEFAULT_CTOR (t)
+ || !CLASSTYPE_LAZY_COPY_CTOR (t)))
+ {
+ int nonprivate_ctor = 0;
+
+ /* If a non-template class does not define a copy
+ constructor, one is defined for it, enabling it to avoid
+ this warning. For a template class, this does not
+ happen, and so we would normally get a warning on:
+
+ template <class T> class C { private: C(); };
+
+ To avoid this asymmetry, we check TYPE_HAS_COPY_CTOR. All
+ complete non-template or fully instantiated classes have this
+ flag set. */
+ if (!TYPE_HAS_COPY_CTOR (t))
+ nonprivate_ctor = 1;
+ else
+ for (fn = CLASSTYPE_CONSTRUCTORS (t); fn; fn = OVL_NEXT (fn))
+ {
+ tree ctor = OVL_CURRENT (fn);
+ /* Ideally, we wouldn't count copy constructors (or, in
+ fact, any constructor that takes an argument of the
+ class type as a parameter) because such things cannot
+ be used to construct an instance of the class unless
+ you already have one. But, for now at least, we're
+ more generous. */
+ if (! TREE_PRIVATE (ctor))
+ {
+ nonprivate_ctor = 1;
+ break;
+ }
+ }
+
+ if (nonprivate_ctor == 0)
+ {
+ warning (OPT_Wctor_dtor_privacy,
+ "%q#T only defines private constructors and has no friends",
+ t);
+ return;
+ }
+ }
+}
+
+static struct {
+ gt_pointer_operator new_value;
+ void *cookie;
+} resort_data;
+
+/* Comparison function to compare two TYPE_METHOD_VEC entries by name. */
+
+static int
+method_name_cmp (const void* m1_p, const void* m2_p)
+{
+ const tree *const m1 = (const tree *) m1_p;
+ const tree *const m2 = (const tree *) m2_p;
+
+ if (*m1 == NULL_TREE && *m2 == NULL_TREE)
+ return 0;
+ if (*m1 == NULL_TREE)
+ return -1;
+ if (*m2 == NULL_TREE)
+ return 1;
+ if (DECL_NAME (OVL_CURRENT (*m1)) < DECL_NAME (OVL_CURRENT (*m2)))
+ return -1;
+ return 1;
+}
+
+/* This routine compares two fields like method_name_cmp but using the
+ pointer operator in resort_field_decl_data. */
+
+static int
+resort_method_name_cmp (const void* m1_p, const void* m2_p)
+{
+ const tree *const m1 = (const tree *) m1_p;
+ const tree *const m2 = (const tree *) m2_p;
+ if (*m1 == NULL_TREE && *m2 == NULL_TREE)
+ return 0;
+ if (*m1 == NULL_TREE)
+ return -1;
+ if (*m2 == NULL_TREE)
+ return 1;
+ {
+ tree d1 = DECL_NAME (OVL_CURRENT (*m1));
+ tree d2 = DECL_NAME (OVL_CURRENT (*m2));
+ resort_data.new_value (&d1, resort_data.cookie);
+ resort_data.new_value (&d2, resort_data.cookie);
+ if (d1 < d2)
+ return -1;
+ }
+ return 1;
+}
+
+/* Resort TYPE_METHOD_VEC because pointers have been reordered. */
+
+void
+resort_type_method_vec (void* obj,
+ void* /*orig_obj*/,
+ gt_pointer_operator new_value,
+ void* cookie)
+{
+ vec<tree, va_gc> *method_vec = (vec<tree, va_gc> *) obj;
+ int len = vec_safe_length (method_vec);
+ size_t slot;
+ tree fn;
+
+ /* The type conversion ops have to live at the front of the vec, so we
+ can't sort them. */
+ for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ vec_safe_iterate (method_vec, slot, &fn);
+ ++slot)
+ if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
+ break;
+
+ if (len - slot > 1)
+ {
+ resort_data.new_value = new_value;
+ resort_data.cookie = cookie;
+ qsort (method_vec->address () + slot, len - slot, sizeof (tree),
+ resort_method_name_cmp);
+ }
+}
+
+/* Warn about duplicate methods in fn_fields.
+
+ Sort methods that are not special (i.e., constructors, destructors,
+ and type conversion operators) so that we can find them faster in
+ search. */
+
+static void
+finish_struct_methods (tree t)
+{
+ tree fn_fields;
+ vec<tree, va_gc> *method_vec;
+ int slot, len;
+
+ method_vec = CLASSTYPE_METHOD_VEC (t);
+ if (!method_vec)
+ return;
+
+ len = method_vec->length ();
+
+ /* Clear DECL_IN_AGGR_P for all functions. */
+ for (fn_fields = TYPE_METHODS (t); fn_fields;
+ fn_fields = DECL_CHAIN (fn_fields))
+ DECL_IN_AGGR_P (fn_fields) = 0;
+
+ /* Issue warnings about private constructors and such. If there are
+ no methods, then some public defaults are generated. */
+ maybe_warn_about_overly_private_class (t);
+
+ /* The type conversion ops have to live at the front of the vec, so we
+ can't sort them. */
+ for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ method_vec->iterate (slot, &fn_fields);
+ ++slot)
+ if (!DECL_CONV_FN_P (OVL_CURRENT (fn_fields)))
+ break;
+ if (len - slot > 1)
+ qsort (method_vec->address () + slot,
+ len-slot, sizeof (tree), method_name_cmp);
+}
+
+/* Make BINFO's vtable have N entries, including RTTI entries,
+ vbase and vcall offsets, etc. Set its type and call the back end
+ to lay it out. */
+
+static void
+layout_vtable_decl (tree binfo, int n)
+{
+ tree atype;
+ tree vtable;
+
+ atype = build_array_of_n_type (vtable_entry_type, n);
+ layout_type (atype);
+
+ /* We may have to grow the vtable. */
+ vtable = get_vtbl_decl_for_binfo (binfo);
+ if (!same_type_p (TREE_TYPE (vtable), atype))
+ {
+ TREE_TYPE (vtable) = atype;
+ DECL_SIZE (vtable) = DECL_SIZE_UNIT (vtable) = NULL_TREE;
+ layout_decl (vtable, 0);
+ }
+}
+
+/* True iff FNDECL and BASE_FNDECL (both non-static member functions)
+ have the same signature. */
+
+int
+same_signature_p (const_tree fndecl, const_tree base_fndecl)
+{
+ /* One destructor overrides another if they are the same kind of
+ destructor. */
+ if (DECL_DESTRUCTOR_P (base_fndecl) && DECL_DESTRUCTOR_P (fndecl)
+ && special_function_p (base_fndecl) == special_function_p (fndecl))
+ return 1;
+ /* But a non-destructor never overrides a destructor, nor vice
+ versa, nor do different kinds of destructors override
+ one-another. For example, a complete object destructor does not
+ override a deleting destructor. */
+ if (DECL_DESTRUCTOR_P (base_fndecl) || DECL_DESTRUCTOR_P (fndecl))
+ return 0;
+
+ if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl)
+ || (DECL_CONV_FN_P (fndecl)
+ && DECL_CONV_FN_P (base_fndecl)
+ && same_type_p (DECL_CONV_FN_TYPE (fndecl),
+ DECL_CONV_FN_TYPE (base_fndecl))))
+ {
+ tree fntype = TREE_TYPE (fndecl);
+ tree base_fntype = TREE_TYPE (base_fndecl);
+ if (type_memfn_quals (fntype) == type_memfn_quals (base_fntype)
+ && type_memfn_rqual (fntype) == type_memfn_rqual (base_fntype)
+ && compparms (FUNCTION_FIRST_USER_PARMTYPE (fndecl),
+ FUNCTION_FIRST_USER_PARMTYPE (base_fndecl)))
+ return 1;
+ }
+ return 0;
+}
+
+/* Returns TRUE if DERIVED is a binfo containing the binfo BASE as a
+ subobject. */
+
+static bool
+base_derived_from (tree derived, tree base)
+{
+ tree probe;
+
+ for (probe = base; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
+ {
+ if (probe == derived)
+ return true;
+ else if (BINFO_VIRTUAL_P (probe))
+ /* If we meet a virtual base, we can't follow the inheritance
+ any more. See if the complete type of DERIVED contains
+ such a virtual base. */
+ return (binfo_for_vbase (BINFO_TYPE (probe), BINFO_TYPE (derived))
+ != NULL_TREE);
+ }
+ return false;
+}
+
+typedef struct find_final_overrider_data_s {
+ /* The function for which we are trying to find a final overrider. */
+ tree fn;
+ /* The base class in which the function was declared. */
+ tree declaring_base;
+ /* The candidate overriders. */
+ tree candidates;
+ /* Path to most derived. */
+ vec<tree> path;
+} find_final_overrider_data;
+
+/* Add the overrider along the current path to FFOD->CANDIDATES.
+ Returns true if an overrider was found; false otherwise. */
+
+static bool
+dfs_find_final_overrider_1 (tree binfo,
+ find_final_overrider_data *ffod,
+ unsigned depth)
+{
+ tree method;
+
+ /* If BINFO is not the most derived type, try a more derived class.
+ A definition there will overrider a definition here. */
+ if (depth)
+ {
+ depth--;
+ if (dfs_find_final_overrider_1
+ (ffod->path[depth], ffod, depth))
+ return true;
+ }
+
+ method = look_for_overrides_here (BINFO_TYPE (binfo), ffod->fn);
+ if (method)
+ {
+ tree *candidate = &ffod->candidates;
+
+ /* Remove any candidates overridden by this new function. */
+ while (*candidate)
+ {
+ /* If *CANDIDATE overrides METHOD, then METHOD
+ cannot override anything else on the list. */
+ if (base_derived_from (TREE_VALUE (*candidate), binfo))
+ return true;
+ /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */
+ if (base_derived_from (binfo, TREE_VALUE (*candidate)))
+ *candidate = TREE_CHAIN (*candidate);
+ else
+ candidate = &TREE_CHAIN (*candidate);
+ }
+
+ /* Add the new function. */
+ ffod->candidates = tree_cons (method, binfo, ffod->candidates);
+ return true;
+ }
+
+ return false;
+}
+
+/* Called from find_final_overrider via dfs_walk. */
+
+static tree
+dfs_find_final_overrider_pre (tree binfo, void *data)
+{
+ find_final_overrider_data *ffod = (find_final_overrider_data *) data;
+
+ if (binfo == ffod->declaring_base)
+ dfs_find_final_overrider_1 (binfo, ffod, ffod->path.length ());
+ ffod->path.safe_push (binfo);
+
+ return NULL_TREE;
+}
+
+static tree
+dfs_find_final_overrider_post (tree /*binfo*/, void *data)
+{
+ find_final_overrider_data *ffod = (find_final_overrider_data *) data;
+ ffod->path.pop ();
+
+ return NULL_TREE;
+}
+
+/* Returns a TREE_LIST whose TREE_PURPOSE is the final overrider for
+ FN and whose TREE_VALUE is the binfo for the base where the
+ overriding occurs. BINFO (in the hierarchy dominated by the binfo
+ DERIVED) is the base object in which FN is declared. */
+
+static tree
+find_final_overrider (tree derived, tree binfo, tree fn)
+{
+ find_final_overrider_data ffod;
+
+ /* Getting this right is a little tricky. This is valid:
+
+ struct S { virtual void f (); };
+ struct T { virtual void f (); };
+ struct U : public S, public T { };
+
+ even though calling `f' in `U' is ambiguous. But,
+
+ struct R { virtual void f(); };
+ struct S : virtual public R { virtual void f (); };
+ struct T : virtual public R { virtual void f (); };
+ struct U : public S, public T { };
+
+ is not -- there's no way to decide whether to put `S::f' or
+ `T::f' in the vtable for `R'.
+
+ The solution is to look at all paths to BINFO. If we find
+ different overriders along any two, then there is a problem. */
+ if (DECL_THUNK_P (fn))
+ fn = THUNK_TARGET (fn);
+
+ /* Determine the depth of the hierarchy. */
+ ffod.fn = fn;
+ ffod.declaring_base = binfo;
+ ffod.candidates = NULL_TREE;
+ ffod.path.create (30);
+
+ dfs_walk_all (derived, dfs_find_final_overrider_pre,
+ dfs_find_final_overrider_post, &ffod);
+
+ ffod.path.release ();
+
+ /* If there was no winner, issue an error message. */
+ if (!ffod.candidates || TREE_CHAIN (ffod.candidates))
+ return error_mark_node;
+
+ return ffod.candidates;
+}
+
+/* Return the index of the vcall offset for FN when TYPE is used as a
+ virtual base. */
+
+static tree
+get_vcall_index (tree fn, tree type)
+{
+ vec<tree_pair_s, va_gc> *indices = CLASSTYPE_VCALL_INDICES (type);
+ tree_pair_p p;
+ unsigned ix;
+
+ FOR_EACH_VEC_SAFE_ELT (indices, ix, p)
+ if ((DECL_DESTRUCTOR_P (fn) && DECL_DESTRUCTOR_P (p->purpose))
+ || same_signature_p (fn, p->purpose))
+ return p->value;
+
+ /* There should always be an appropriate index. */
+ gcc_unreachable ();
+}
+
+/* Update an entry in the vtable for BINFO, which is in the hierarchy
+ dominated by T. FN is the old function; VIRTUALS points to the
+ corresponding position in the new BINFO_VIRTUALS list. IX is the index
+ of that entry in the list. */
+
+static void
+update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
+ unsigned ix)
+{
+ tree b;
+ tree overrider;
+ tree delta;
+ tree virtual_base;
+ tree first_defn;
+ tree overrider_fn, overrider_target;
+ tree target_fn = DECL_THUNK_P (fn) ? THUNK_TARGET (fn) : fn;
+ tree over_return, base_return;
+ bool lost = false;
+
+ /* Find the nearest primary base (possibly binfo itself) which defines
+ this function; this is the class the caller will convert to when
+ calling FN through BINFO. */
+ for (b = binfo; ; b = get_primary_binfo (b))
+ {
+ gcc_assert (b);
+ if (look_for_overrides_here (BINFO_TYPE (b), target_fn))
+ break;
+
+ /* The nearest definition is from a lost primary. */
+ if (BINFO_LOST_PRIMARY_P (b))
+ lost = true;
+ }
+ first_defn = b;
+
+ /* Find the final overrider. */
+ overrider = find_final_overrider (TYPE_BINFO (t), b, target_fn);
+ if (overrider == error_mark_node)
+ {
+ error ("no unique final overrider for %qD in %qT", target_fn, t);
+ return;
+ }
+ overrider_target = overrider_fn = TREE_PURPOSE (overrider);
+
+ /* Check for adjusting covariant return types. */
+ over_return = TREE_TYPE (TREE_TYPE (overrider_target));
+ base_return = TREE_TYPE (TREE_TYPE (target_fn));
+
+ if (POINTER_TYPE_P (over_return)
+ && TREE_CODE (over_return) == TREE_CODE (base_return)
+ && CLASS_TYPE_P (TREE_TYPE (over_return))
+ && CLASS_TYPE_P (TREE_TYPE (base_return))
+ /* If the overrider is invalid, don't even try. */
+ && !DECL_INVALID_OVERRIDER_P (overrider_target))
+ {
+ /* If FN is a covariant thunk, we must figure out the adjustment
+ to the final base FN was converting to. As OVERRIDER_TARGET might
+ also be converting to the return type of FN, we have to
+ combine the two conversions here. */
+ tree fixed_offset, virtual_offset;
+
+ over_return = TREE_TYPE (over_return);
+ base_return = TREE_TYPE (base_return);
+
+ if (DECL_THUNK_P (fn))
+ {
+ gcc_assert (DECL_RESULT_THUNK_P (fn));
+ fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn));
+ virtual_offset = THUNK_VIRTUAL_OFFSET (fn);
+ }
+ else
+ fixed_offset = virtual_offset = NULL_TREE;
+
+ if (virtual_offset)
+ /* Find the equivalent binfo within the return type of the
+ overriding function. We will want the vbase offset from
+ there. */
+ virtual_offset = binfo_for_vbase (BINFO_TYPE (virtual_offset),
+ over_return);
+ else if (!same_type_ignoring_top_level_qualifiers_p
+ (over_return, base_return))
+ {
+ /* There was no existing virtual thunk (which takes
+ precedence). So find the binfo of the base function's
+ return type within the overriding function's return type.
+ We cannot call lookup base here, because we're inside a
+ dfs_walk, and will therefore clobber the BINFO_MARKED
+ flags. Fortunately we know the covariancy is valid (it
+ has already been checked), so we can just iterate along
+ the binfos, which have been chained in inheritance graph
+ order. Of course it is lame that we have to repeat the
+ search here anyway -- we should really be caching pieces
+ of the vtable and avoiding this repeated work. */
+ tree thunk_binfo, base_binfo;
+
+ /* Find the base binfo within the overriding function's
+ return type. We will always find a thunk_binfo, except
+ when the covariancy is invalid (which we will have
+ already diagnosed). */
+ for (base_binfo = TYPE_BINFO (base_return),
+ thunk_binfo = TYPE_BINFO (over_return);
+ thunk_binfo;
+ thunk_binfo = TREE_CHAIN (thunk_binfo))
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo),
+ BINFO_TYPE (base_binfo)))
+ break;
+
+ /* See if virtual inheritance is involved. */
+ for (virtual_offset = thunk_binfo;
+ virtual_offset;
+ virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset))
+ if (BINFO_VIRTUAL_P (virtual_offset))
+ break;
+
+ if (virtual_offset
+ || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo)))
+ {
+ tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
+
+ if (virtual_offset)
+ {
+ /* We convert via virtual base. Adjust the fixed
+ offset to be from there. */
+ offset =
+ size_diffop (offset,
+ convert (ssizetype,
+ BINFO_OFFSET (virtual_offset)));
+ }
+ if (fixed_offset)
+ /* There was an existing fixed offset, this must be
+ from the base just converted to, and the base the
+ FN was thunking to. */
+ fixed_offset = size_binop (PLUS_EXPR, fixed_offset, offset);
+ else
+ fixed_offset = offset;
+ }
+ }
+
+ if (fixed_offset || virtual_offset)
+ /* Replace the overriding function with a covariant thunk. We
+ will emit the overriding function in its own slot as
+ well. */
+ overrider_fn = make_thunk (overrider_target, /*this_adjusting=*/0,
+ fixed_offset, virtual_offset);
+ }
+ else
+ gcc_assert (DECL_INVALID_OVERRIDER_P (overrider_target) ||
+ !DECL_THUNK_P (fn));
+
+ /* If we need a covariant thunk, then we may need to adjust first_defn.
+ The ABI specifies that the thunks emitted with a function are
+ determined by which bases the function overrides, so we need to be
+ sure that we're using a thunk for some overridden base; even if we
+ know that the necessary this adjustment is zero, there may not be an
+ appropriate zero-this-adjusment thunk for us to use since thunks for
+ overriding virtual bases always use the vcall offset.
+
+ Furthermore, just choosing any base that overrides this function isn't
+ quite right, as this slot won't be used for calls through a type that
+ puts a covariant thunk here. Calling the function through such a type
+ will use a different slot, and that slot is the one that determines
+ the thunk emitted for that base.
+
+ So, keep looking until we find the base that we're really overriding
+ in this slot: the nearest primary base that doesn't use a covariant
+ thunk in this slot. */
+ if (overrider_target != overrider_fn)
+ {
+ if (BINFO_TYPE (b) == DECL_CONTEXT (overrider_target))
+ /* We already know that the overrider needs a covariant thunk. */
+ b = get_primary_binfo (b);
+ for (; ; b = get_primary_binfo (b))
+ {
+ tree main_binfo = TYPE_BINFO (BINFO_TYPE (b));
+ tree bv = chain_index (ix, BINFO_VIRTUALS (main_binfo));
+ if (!DECL_THUNK_P (TREE_VALUE (bv)))
+ break;
+ if (BINFO_LOST_PRIMARY_P (b))
+ lost = true;
+ }
+ first_defn = b;
+ }
+
+ /* Assume that we will produce a thunk that convert all the way to
+ the final overrider, and not to an intermediate virtual base. */
+ virtual_base = NULL_TREE;
+
+ /* See if we can convert to an intermediate virtual base first, and then
+ use the vcall offset located there to finish the conversion. */
+ for (; b; b = BINFO_INHERITANCE_CHAIN (b))
+ {
+ /* If we find the final overrider, then we can stop
+ walking. */
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (b),
+ BINFO_TYPE (TREE_VALUE (overrider))))
+ break;
+
+ /* If we find a virtual base, and we haven't yet found the
+ overrider, then there is a virtual base between the
+ declaring base (first_defn) and the final overrider. */
+ if (BINFO_VIRTUAL_P (b))
+ {
+ virtual_base = b;
+ break;
+ }
+ }
+
+ /* Compute the constant adjustment to the `this' pointer. The
+ `this' pointer, when this function is called, will point at BINFO
+ (or one of its primary bases, which are at the same offset). */
+ if (virtual_base)
+ /* The `this' pointer needs to be adjusted from the declaration to
+ the nearest virtual base. */
+ delta = size_diffop_loc (input_location,
+ convert (ssizetype, BINFO_OFFSET (virtual_base)),
+ convert (ssizetype, BINFO_OFFSET (first_defn)));
+ else if (lost)
+ /* If the nearest definition is in a lost primary, we don't need an
+ entry in our vtable. Except possibly in a constructor vtable,
+ if we happen to get our primary back. In that case, the offset
+ will be zero, as it will be a primary base. */
+ delta = size_zero_node;
+ else
+ /* The `this' pointer needs to be adjusted from pointing to
+ BINFO to pointing at the base where the final overrider
+ appears. */
+ delta = size_diffop_loc (input_location,
+ convert (ssizetype,
+ BINFO_OFFSET (TREE_VALUE (overrider))),
+ convert (ssizetype, BINFO_OFFSET (binfo)));
+
+ modify_vtable_entry (t, binfo, overrider_fn, delta, virtuals);
+
+ if (virtual_base)
+ BV_VCALL_INDEX (*virtuals)
+ = get_vcall_index (overrider_target, BINFO_TYPE (virtual_base));
+ else
+ BV_VCALL_INDEX (*virtuals) = NULL_TREE;
+
+ BV_LOST_PRIMARY (*virtuals) = lost;
+}
+
+/* Called from modify_all_vtables via dfs_walk. */
+
+static tree
+dfs_modify_vtables (tree binfo, void* data)
+{
+ tree t = (tree) data;
+ tree virtuals;
+ tree old_virtuals;
+ unsigned ix;
+
+ if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
+ /* A base without a vtable needs no modification, and its bases
+ are uninteresting. */
+ return dfs_skip_bases;
+
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t)
+ && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
+ /* Don't do the primary vtable, if it's new. */
+ return NULL_TREE;
+
+ if (BINFO_PRIMARY_P (binfo) && !BINFO_VIRTUAL_P (binfo))
+ /* There's no need to modify the vtable for a non-virtual primary
+ base; we're not going to use that vtable anyhow. We do still
+ need to do this for virtual primary bases, as they could become
+ non-primary in a construction vtable. */
+ return NULL_TREE;
+
+ make_new_vtable (t, binfo);
+
+ /* Now, go through each of the virtual functions in the virtual
+ function table for BINFO. Find the final overrider, and update
+ the BINFO_VIRTUALS list appropriately. */
+ for (ix = 0, virtuals = BINFO_VIRTUALS (binfo),
+ old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
+ virtuals;
+ ix++, virtuals = TREE_CHAIN (virtuals),
+ old_virtuals = TREE_CHAIN (old_virtuals))
+ update_vtable_entry_for_fn (t,
+ binfo,
+ BV_FN (old_virtuals),
+ &virtuals, ix);
+
+ return NULL_TREE;
+}
+
+/* Update all of the primary and secondary vtables for T. Create new
+ vtables as required, and initialize their RTTI information. Each
+ of the functions in VIRTUALS is declared in T and may override a
+ virtual function from a base class; find and modify the appropriate
+ entries to point to the overriding functions. Returns a list, in
+ declaration order, of the virtual functions that are declared in T,
+ but do not appear in the primary base class vtable, and which
+ should therefore be appended to the end of the vtable for T. */
+
+static tree
+modify_all_vtables (tree t, tree virtuals)
+{
+ tree binfo = TYPE_BINFO (t);
+ tree *fnsp;
+
+ /* Mangle the vtable name before entering dfs_walk (c++/51884). */
+ if (TYPE_CONTAINS_VPTR_P (t))
+ get_vtable_decl (t, false);
+
+ /* Update all of the vtables. */
+ dfs_walk_once (binfo, dfs_modify_vtables, NULL, t);
+
+ /* Add virtual functions not already in our primary vtable. These
+ will be both those introduced by this class, and those overridden
+ from secondary bases. It does not include virtuals merely
+ inherited from secondary bases. */
+ for (fnsp = &virtuals; *fnsp; )
+ {
+ tree fn = TREE_VALUE (*fnsp);
+
+ if (!value_member (fn, BINFO_VIRTUALS (binfo))
+ || DECL_VINDEX (fn) == error_mark_node)
+ {
+ /* We don't need to adjust the `this' pointer when
+ calling this function. */
+ BV_DELTA (*fnsp) = integer_zero_node;
+ BV_VCALL_INDEX (*fnsp) = NULL_TREE;
+
+ /* This is a function not already in our vtable. Keep it. */
+ fnsp = &TREE_CHAIN (*fnsp);
+ }
+ else
+ /* We've already got an entry for this function. Skip it. */
+ *fnsp = TREE_CHAIN (*fnsp);
+ }
+
+ return virtuals;
+}
+
+/* Get the base virtual function declarations in T that have the
+ indicated NAME. */
+
+static tree
+get_basefndecls (tree name, tree t)
+{
+ tree methods;
+ tree base_fndecls = NULL_TREE;
+ int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
+ int i;
+
+ /* Find virtual functions in T with the indicated NAME. */
+ i = lookup_fnfields_1 (t, name);
+ if (i != -1)
+ for (methods = (*CLASSTYPE_METHOD_VEC (t))[i];
+ methods;
+ methods = OVL_NEXT (methods))
+ {
+ tree method = OVL_CURRENT (methods);
+
+ if (TREE_CODE (method) == FUNCTION_DECL
+ && DECL_VINDEX (method))
+ base_fndecls = tree_cons (NULL_TREE, method, base_fndecls);
+ }
+
+ if (base_fndecls)
+ return base_fndecls;
+
+ for (i = 0; i < n_baseclasses; i++)
+ {
+ tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), i));
+ base_fndecls = chainon (get_basefndecls (name, basetype),
+ base_fndecls);
+ }
+
+ return base_fndecls;
+}
+
+/* If this declaration supersedes the declaration of
+ a method declared virtual in the base class, then
+ mark this field as being virtual as well. */
+
+void
+check_for_override (tree decl, tree ctype)
+{
+ bool overrides_found = false;
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ /* In [temp.mem] we have:
+
+ A specialization of a member function template does not
+ override a virtual function from a base class. */
+ return;
+ if ((DECL_DESTRUCTOR_P (decl)
+ || IDENTIFIER_VIRTUAL_P (DECL_NAME (decl))
+ || DECL_CONV_FN_P (decl))
+ && look_for_overrides (ctype, decl)
+ && !DECL_STATIC_FUNCTION_P (decl))
+ /* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
+ the error_mark_node so that we know it is an overriding
+ function. */
+ {
+ DECL_VINDEX (decl) = decl;
+ overrides_found = true;
+ }
+
+ if (DECL_VIRTUAL_P (decl))
+ {
+ if (!DECL_VINDEX (decl))
+ DECL_VINDEX (decl) = error_mark_node;
+ IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
+ if (DECL_DESTRUCTOR_P (decl))
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
+ }
+ else if (DECL_FINAL_P (decl))
+ error ("%q+#D marked final, but is not virtual", decl);
+ if (DECL_OVERRIDE_P (decl) && !overrides_found)
+ error ("%q+#D marked override, but does not override", decl);
+}
+
+/* Warn about hidden virtual functions that are not overridden in t.
+ We know that constructors and destructors don't apply. */
+
+static void
+warn_hidden (tree t)
+{
+ vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (t);
+ tree fns;
+ size_t i;
+
+ /* We go through each separately named virtual function. */
+ for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ vec_safe_iterate (method_vec, i, &fns);
+ ++i)
+ {
+ tree fn;
+ tree name;
+ tree fndecl;
+ tree base_fndecls;
+ tree base_binfo;
+ tree binfo;
+ int j;
+
+ /* All functions in this slot in the CLASSTYPE_METHOD_VEC will
+ have the same name. Figure out what name that is. */
+ name = DECL_NAME (OVL_CURRENT (fns));
+ /* There are no possibly hidden functions yet. */
+ base_fndecls = NULL_TREE;
+ /* Iterate through all of the base classes looking for possibly
+ hidden functions. */
+ for (binfo = TYPE_BINFO (t), j = 0;
+ BINFO_BASE_ITERATE (binfo, j, base_binfo); j++)
+ {
+ tree basetype = BINFO_TYPE (base_binfo);
+ base_fndecls = chainon (get_basefndecls (name, basetype),
+ base_fndecls);
+ }
+
+ /* If there are no functions to hide, continue. */
+ if (!base_fndecls)
+ continue;
+
+ /* Remove any overridden functions. */
+ for (fn = fns; fn; fn = OVL_NEXT (fn))
+ {
+ fndecl = OVL_CURRENT (fn);
+ if (DECL_VINDEX (fndecl))
+ {
+ tree *prev = &base_fndecls;
+
+ while (*prev)
+ /* If the method from the base class has the same
+ signature as the method from the derived class, it
+ has been overridden. */
+ if (same_signature_p (fndecl, TREE_VALUE (*prev)))
+ *prev = TREE_CHAIN (*prev);
+ else
+ prev = &TREE_CHAIN (*prev);
+ }
+ }
+
+ /* Now give a warning for all base functions without overriders,
+ as they are hidden. */
+ while (base_fndecls)
+ {
+ /* Here we know it is a hider, and no overrider exists. */
+ warning (OPT_Woverloaded_virtual, "%q+D was hidden", TREE_VALUE (base_fndecls));
+ warning (OPT_Woverloaded_virtual, " by %q+D", fns);
+ base_fndecls = TREE_CHAIN (base_fndecls);
+ }
+ }
+}
+
+/* Recursive helper for finish_struct_anon. */
+
+static void
+finish_struct_anon_r (tree field, bool complain)
+{
+ bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE;
+ tree elt = TYPE_FIELDS (TREE_TYPE (field));
+ for (; elt; elt = DECL_CHAIN (elt))
+ {
+ /* We're generally only interested in entities the user
+ declared, but we also find nested classes by noticing
+ the TYPE_DECL that we create implicitly. You're
+ allowed to put one anonymous union inside another,
+ though, so we explicitly tolerate that. We use
+ TYPE_ANONYMOUS_P rather than ANON_AGGR_TYPE_P so that
+ we also allow unnamed types used for defining fields. */
+ if (DECL_ARTIFICIAL (elt)
+ && (!DECL_IMPLICIT_TYPEDEF_P (elt)
+ || TYPE_ANONYMOUS_P (TREE_TYPE (elt))))
+ continue;
+
+ if (TREE_CODE (elt) != FIELD_DECL)
+ {
+ /* We already complained about static data members in
+ finish_static_data_member_decl. */
+ if (complain && TREE_CODE (elt) != VAR_DECL)
+ {
+ if (is_union)
+ permerror (input_location,
+ "%q+#D invalid; an anonymous union can "
+ "only have non-static data members", elt);
+ else
+ permerror (input_location,
+ "%q+#D invalid; an anonymous struct can "
+ "only have non-static data members", elt);
+ }
+ continue;
+ }
+
+ if (complain)
+ {
+ if (TREE_PRIVATE (elt))
+ {
+ if (is_union)
+ permerror (input_location,
+ "private member %q+#D in anonymous union", elt);
+ else
+ permerror (input_location,
+ "private member %q+#D in anonymous struct", elt);
+ }
+ else if (TREE_PROTECTED (elt))
+ {
+ if (is_union)
+ permerror (input_location,
+ "protected member %q+#D in anonymous union", elt);
+ else
+ permerror (input_location,
+ "protected member %q+#D in anonymous struct", elt);
+ }
+ }
+
+ TREE_PRIVATE (elt) = TREE_PRIVATE (field);
+ TREE_PROTECTED (elt) = TREE_PROTECTED (field);
+
+ /* Recurse into the anonymous aggregates to handle correctly
+ access control (c++/24926):
+
+ class A {
+ union {
+ union {
+ int i;
+ };
+ };
+ };
+
+ int j=A().i; */
+ if (DECL_NAME (elt) == NULL_TREE
+ && ANON_AGGR_TYPE_P (TREE_TYPE (elt)))
+ finish_struct_anon_r (elt, /*complain=*/false);
+ }
+}
+
+/* Check for things that are invalid. There are probably plenty of other
+ things we should check for also. */
+
+static void
+finish_struct_anon (tree t)
+{
+ for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
+ {
+ if (TREE_STATIC (field))
+ continue;
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ if (DECL_NAME (field) == NULL_TREE
+ && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
+ finish_struct_anon_r (field, /*complain=*/true);
+ }
+}
+
+/* Add T to CLASSTYPE_DECL_LIST of current_class_type which
+ will be used later during class template instantiation.
+ When FRIEND_P is zero, T can be a static member data (VAR_DECL),
+ a non-static member data (FIELD_DECL), a member function
+ (FUNCTION_DECL), a nested type (RECORD_TYPE, ENUM_TYPE),
+ a typedef (TYPE_DECL) or a member class template (TEMPLATE_DECL)
+ When FRIEND_P is nonzero, T is either a friend class
+ (RECORD_TYPE, TEMPLATE_DECL) or a friend function
+ (FUNCTION_DECL, TEMPLATE_DECL). */
+
+void
+maybe_add_class_template_decl_list (tree type, tree t, int friend_p)
+{
+ /* Save some memory by not creating TREE_LIST if TYPE is not template. */
+ if (CLASSTYPE_TEMPLATE_INFO (type))
+ CLASSTYPE_DECL_LIST (type)
+ = tree_cons (friend_p ? NULL_TREE : type,
+ t, CLASSTYPE_DECL_LIST (type));
+}
+
+/* This function is called from declare_virt_assop_and_dtor via
+ dfs_walk_all.
+
+ DATA is a type that direcly or indirectly inherits the base
+ represented by BINFO. If BINFO contains a virtual assignment [copy
+ assignment or move assigment] operator or a virtual constructor,
+ declare that function in DATA if it hasn't been already declared. */
+
+static tree
+dfs_declare_virt_assop_and_dtor (tree binfo, void *data)
+{
+ tree bv, fn, t = (tree)data;
+ tree opname = ansi_assopname (NOP_EXPR);
+
+ gcc_assert (t && CLASS_TYPE_P (t));
+ gcc_assert (binfo && TREE_CODE (binfo) == TREE_BINFO);
+
+ if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
+ /* A base without a vtable needs no modification, and its bases
+ are uninteresting. */
+ return dfs_skip_bases;
+
+ if (BINFO_PRIMARY_P (binfo))
+ /* If this is a primary base, then we have already looked at the
+ virtual functions of its vtable. */
+ return NULL_TREE;
+
+ for (bv = BINFO_VIRTUALS (binfo); bv; bv = TREE_CHAIN (bv))
+ {
+ fn = BV_FN (bv);
+
+ if (DECL_NAME (fn) == opname)
+ {
+ if (CLASSTYPE_LAZY_COPY_ASSIGN (t))
+ lazily_declare_fn (sfk_copy_assignment, t);
+ if (CLASSTYPE_LAZY_MOVE_ASSIGN (t))
+ lazily_declare_fn (sfk_move_assignment, t);
+ }
+ else if (DECL_DESTRUCTOR_P (fn)
+ && CLASSTYPE_LAZY_DESTRUCTOR (t))
+ lazily_declare_fn (sfk_destructor, t);
+ }
+
+ return NULL_TREE;
+}
+
+/* If the class type T has a direct or indirect base that contains a
+ virtual assignment operator or a virtual destructor, declare that
+ function in T if it hasn't been already declared. */
+
+static void
+declare_virt_assop_and_dtor (tree t)
+{
+ if (!(TYPE_POLYMORPHIC_P (t)
+ && (CLASSTYPE_LAZY_COPY_ASSIGN (t)
+ || CLASSTYPE_LAZY_MOVE_ASSIGN (t)
+ || CLASSTYPE_LAZY_DESTRUCTOR (t))))
+ return;
+
+ dfs_walk_all (TYPE_BINFO (t),
+ dfs_declare_virt_assop_and_dtor,
+ NULL, t);
+}
+
+/* Declare the inheriting constructor for class T inherited from base
+ constructor CTOR with the parameter array PARMS of size NPARMS. */
+
+static void
+one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
+{
+ /* We don't declare an inheriting ctor that would be a default,
+ copy or move ctor for derived or base. */
+ if (nparms == 0)
+ return;
+ if (nparms == 1
+ && TREE_CODE (parms[0]) == REFERENCE_TYPE)
+ {
+ tree parm = TYPE_MAIN_VARIANT (TREE_TYPE (parms[0]));
+ if (parm == t || parm == DECL_CONTEXT (ctor))
+ return;
+ }
+
+ tree parmlist = void_list_node;
+ for (int i = nparms - 1; i >= 0; i--)
+ parmlist = tree_cons (NULL_TREE, parms[i], parmlist);
+ tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
+ t, false, ctor, parmlist);
+ if (add_method (t, fn, NULL_TREE))
+ {
+ DECL_CHAIN (fn) = TYPE_METHODS (t);
+ TYPE_METHODS (t) = fn;
+ }
+}
+
+/* Declare all the inheriting constructors for class T inherited from base
+ constructor CTOR. */
+
+static void
+one_inherited_ctor (tree ctor, tree t)
+{
+ tree parms = FUNCTION_FIRST_USER_PARMTYPE (ctor);
+
+ tree *new_parms = XALLOCAVEC (tree, list_length (parms));
+ int i = 0;
+ for (; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
+ {
+ if (TREE_PURPOSE (parms))
+ one_inheriting_sig (t, ctor, new_parms, i);
+ new_parms[i++] = TREE_VALUE (parms);
+ }
+ one_inheriting_sig (t, ctor, new_parms, i);
+ if (parms == NULL_TREE)
+ {
+ warning (OPT_Winherited_variadic_ctor,
+ "the ellipsis in %qD is not inherited", ctor);
+ inform (DECL_SOURCE_LOCATION (ctor), "%qD declared here", ctor);
+ }
+}
+
+/* Create default constructors, assignment operators, and so forth for
+ the type indicated by T, if they are needed. CANT_HAVE_CONST_CTOR,
+ and CANT_HAVE_CONST_ASSIGNMENT are nonzero if, for whatever reason,
+ the class cannot have a default constructor, copy constructor
+ taking a const reference argument, or an assignment operator taking
+ a const reference, respectively. */
+
+static void
+add_implicitly_declared_members (tree t, tree* access_decls,
+ int cant_have_const_cctor,
+ int cant_have_const_assignment)
+{
+ bool move_ok = false;
+
+ if (cxx_dialect >= cxx11 && !CLASSTYPE_DESTRUCTORS (t)
+ && !TYPE_HAS_COPY_CTOR (t) && !TYPE_HAS_COPY_ASSIGN (t)
+ && !type_has_move_constructor (t) && !type_has_move_assign (t))
+ move_ok = true;
+
+ /* Destructor. */
+ if (!CLASSTYPE_DESTRUCTORS (t))
+ {
+ /* In general, we create destructors lazily. */
+ CLASSTYPE_LAZY_DESTRUCTOR (t) = 1;
+
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
+ && TYPE_FOR_JAVA (t))
+ /* But if this is a Java class, any non-trivial destructor is
+ invalid, even if compiler-generated. Therefore, if the
+ destructor is non-trivial we create it now. */
+ lazily_declare_fn (sfk_destructor, t);
+ }
+
+ /* [class.ctor]
+
+ If there is no user-declared constructor for a class, a default
+ constructor is implicitly declared. */
+ if (! TYPE_HAS_USER_CONSTRUCTOR (t))
+ {
+ TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
+ CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
+ if (cxx_dialect >= cxx11)
+ TYPE_HAS_CONSTEXPR_CTOR (t)
+ /* This might force the declaration. */
+ = type_has_constexpr_default_constructor (t);
+ }
+
+ /* [class.ctor]
+
+ If a class definition does not explicitly declare a copy
+ constructor, one is declared implicitly. */
+ if (! TYPE_HAS_COPY_CTOR (t) && ! TYPE_FOR_JAVA (t))
+ {
+ TYPE_HAS_COPY_CTOR (t) = 1;
+ TYPE_HAS_CONST_COPY_CTOR (t) = !cant_have_const_cctor;
+ CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
+ if (move_ok)
+ CLASSTYPE_LAZY_MOVE_CTOR (t) = 1;
+ }
+
+ /* If there is no assignment operator, one will be created if and
+ when it is needed. For now, just record whether or not the type
+ of the parameter to the assignment operator will be a const or
+ non-const reference. */
+ if (!TYPE_HAS_COPY_ASSIGN (t) && !TYPE_FOR_JAVA (t))
+ {
+ TYPE_HAS_COPY_ASSIGN (t) = 1;
+ TYPE_HAS_CONST_COPY_ASSIGN (t) = !cant_have_const_assignment;
+ CLASSTYPE_LAZY_COPY_ASSIGN (t) = 1;
+ if (move_ok)
+ CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 1;
+ }
+
+ /* We can't be lazy about declaring functions that might override
+ a virtual function from a base class. */
+ declare_virt_assop_and_dtor (t);
+
+ while (*access_decls)
+ {
+ tree using_decl = TREE_VALUE (*access_decls);
+ tree decl = USING_DECL_DECLS (using_decl);
+ if (DECL_NAME (using_decl) == ctor_identifier)
+ {
+ /* declare, then remove the decl */
+ tree ctor_list = decl;
+ location_t loc = input_location;
+ input_location = DECL_SOURCE_LOCATION (using_decl);
+ if (ctor_list)
+ for (; ctor_list; ctor_list = OVL_NEXT (ctor_list))
+ one_inherited_ctor (OVL_CURRENT (ctor_list), t);
+ *access_decls = TREE_CHAIN (*access_decls);
+ input_location = loc;
+ }
+ else
+ access_decls = &TREE_CHAIN (*access_decls);
+ }
+}
+
+/* Subroutine of insert_into_classtype_sorted_fields. Recursively
+ count the number of fields in TYPE, including anonymous union
+ members. */
+
+static int
+count_fields (tree fields)
+{
+ tree x;
+ int n_fields = 0;
+ for (x = fields; x; x = DECL_CHAIN (x))
+ {
+ if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
+ n_fields += count_fields (TYPE_FIELDS (TREE_TYPE (x)));
+ else
+ n_fields += 1;
+ }
+ return n_fields;
+}
+
+/* Subroutine of insert_into_classtype_sorted_fields. Recursively add
+ all the fields in the TREE_LIST FIELDS to the SORTED_FIELDS_TYPE
+ elts, starting at offset IDX. */
+
+static int
+add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, int idx)
+{
+ tree x;
+ for (x = fields; x; x = DECL_CHAIN (x))
+ {
+ if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
+ idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx);
+ else
+ field_vec->elts[idx++] = x;
+ }
+ return idx;
+}
+
+/* Add all of the enum values of ENUMTYPE, to the FIELD_VEC elts,
+ starting at offset IDX. */
+
+static int
+add_enum_fields_to_record_type (tree enumtype,
+ struct sorted_fields_type *field_vec,
+ int idx)
+{
+ tree values;
+ for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
+ field_vec->elts[idx++] = TREE_VALUE (values);
+ return idx;
+}
+
+/* FIELD is a bit-field. We are finishing the processing for its
+ enclosing type. Issue any appropriate messages and set appropriate
+ flags. Returns false if an error has been diagnosed. */
+
+static bool
+check_bitfield_decl (tree field)
+{
+ tree type = TREE_TYPE (field);
+ tree w;
+
+ /* Extract the declared width of the bitfield, which has been
+ temporarily stashed in DECL_INITIAL. */
+ w = DECL_INITIAL (field);
+ gcc_assert (w != NULL_TREE);
+ /* Remove the bit-field width indicator so that the rest of the
+ compiler does not treat that value as an initializer. */
+ DECL_INITIAL (field) = NULL_TREE;
+
+ /* Detect invalid bit-field type. */
+ if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ {
+ error ("bit-field %q+#D with non-integral type", field);
+ w = error_mark_node;
+ }
+ else
+ {
+ location_t loc = input_location;
+ /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */
+ STRIP_NOPS (w);
+
+ /* detect invalid field size. */
+ input_location = DECL_SOURCE_LOCATION (field);
+ w = cxx_constant_value (w);
+ input_location = loc;
+
+ if (TREE_CODE (w) != INTEGER_CST)
+ {
+ error ("bit-field %q+D width not an integer constant", field);
+ w = error_mark_node;
+ }
+ else if (tree_int_cst_sgn (w) < 0)
+ {
+ error ("negative width in bit-field %q+D", field);
+ w = error_mark_node;
+ }
+ else if (integer_zerop (w) && DECL_NAME (field) != 0)
+ {
+ error ("zero width for bit-field %q+D", field);
+ w = error_mark_node;
+ }
+ else if ((TREE_CODE (type) != ENUMERAL_TYPE
+ && TREE_CODE (type) != BOOLEAN_TYPE
+ && compare_tree_int (w, TYPE_PRECISION (type)) > 0)
+ || ((TREE_CODE (type) == ENUMERAL_TYPE
+ || TREE_CODE (type) == BOOLEAN_TYPE)
+ && tree_int_cst_lt (TYPE_SIZE (type), w)))
+ warning (0, "width of %q+D exceeds its type", field);
+ else if (TREE_CODE (type) == ENUMERAL_TYPE
+ && (0 > (compare_tree_int
+ (w, TYPE_PRECISION (ENUM_UNDERLYING_TYPE (type))))))
+ warning (0, "%q+D is too small to hold all values of %q#T", field, type);
+ }
+
+ if (w != error_mark_node)
+ {
+ DECL_SIZE (field) = convert (bitsizetype, w);
+ DECL_BIT_FIELD (field) = 1;
+ return true;
+ }
+ else
+ {
+ /* Non-bit-fields are aligned for their type. */
+ DECL_BIT_FIELD (field) = 0;
+ CLEAR_DECL_C_BIT_FIELD (field);
+ return false;
+ }
+}
+
+/* FIELD is a non bit-field. We are finishing the processing for its
+ enclosing type T. Issue any appropriate messages and set appropriate
+ flags. */
+
+static void
+check_field_decl (tree field,
+ tree t,
+ int* cant_have_const_ctor,
+ int* no_const_asn_ref,
+ int* any_default_members)
+{
+ tree type = strip_array_types (TREE_TYPE (field));
+
+ /* In C++98 an anonymous union cannot contain any fields which would change
+ the settings of CANT_HAVE_CONST_CTOR and friends. */
+ if (ANON_UNION_TYPE_P (type) && cxx_dialect < cxx11)
+ ;
+ /* And, we don't set TYPE_HAS_CONST_COPY_CTOR, etc., for anonymous
+ structs. So, we recurse through their fields here. */
+ else if (ANON_AGGR_TYPE_P (type))
+ {
+ tree fields;
+
+ for (fields = TYPE_FIELDS (type); fields; fields = DECL_CHAIN (fields))
+ if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field))
+ check_field_decl (fields, t, cant_have_const_ctor,
+ no_const_asn_ref, any_default_members);
+ }
+ /* Check members with class type for constructors, destructors,
+ etc. */
+ else if (CLASS_TYPE_P (type))
+ {
+ /* Never let anything with uninheritable virtuals
+ make it through without complaint. */
+ abstract_virtuals_error (field, type);
+
+ if (TREE_CODE (t) == UNION_TYPE && cxx_dialect < cxx11)
+ {
+ static bool warned;
+ int oldcount = errorcount;
+ if (TYPE_NEEDS_CONSTRUCTING (type))
+ error ("member %q+#D with constructor not allowed in union",
+ field);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ error ("member %q+#D with destructor not allowed in union", field);
+ if (TYPE_HAS_COMPLEX_COPY_ASSIGN (type))
+ error ("member %q+#D with copy assignment operator not allowed in union",
+ field);
+ if (!warned && errorcount > oldcount)
+ {
+ inform (DECL_SOURCE_LOCATION (field), "unrestricted unions "
+ "only available with -std=c++11 or -std=gnu++11");
+ warned = true;
+ }
+ }
+ else
+ {
+ TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type);
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
+ |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type);
+ TYPE_HAS_COMPLEX_COPY_ASSIGN (t)
+ |= (TYPE_HAS_COMPLEX_COPY_ASSIGN (type)
+ || !TYPE_HAS_COPY_ASSIGN (type));
+ TYPE_HAS_COMPLEX_COPY_CTOR (t) |= (TYPE_HAS_COMPLEX_COPY_CTOR (type)
+ || !TYPE_HAS_COPY_CTOR (type));
+ TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_HAS_COMPLEX_MOVE_ASSIGN (type);
+ TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_HAS_COMPLEX_MOVE_CTOR (type);
+ TYPE_HAS_COMPLEX_DFLT (t) |= (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type)
+ || TYPE_HAS_COMPLEX_DFLT (type));
+ }
+
+ if (TYPE_HAS_COPY_CTOR (type)
+ && !TYPE_HAS_CONST_COPY_CTOR (type))
+ *cant_have_const_ctor = 1;
+
+ if (TYPE_HAS_COPY_ASSIGN (type)
+ && !TYPE_HAS_CONST_COPY_ASSIGN (type))
+ *no_const_asn_ref = 1;
+ }
+
+ check_abi_tags (t, field);
+
+ if (DECL_INITIAL (field) != NULL_TREE)
+ {
+ /* `build_class_init_list' does not recognize
+ non-FIELD_DECLs. */
+ if (TREE_CODE (t) == UNION_TYPE && *any_default_members != 0)
+ error ("multiple fields in union %qT initialized", t);
+ *any_default_members = 1;
+ }
+}
+
+/* Check the data members (both static and non-static), class-scoped
+ typedefs, etc., appearing in the declaration of T. Issue
+ appropriate diagnostics. Sets ACCESS_DECLS to a list (in
+ declaration order) of access declarations; each TREE_VALUE in this
+ list is a USING_DECL.
+
+ In addition, set the following flags:
+
+ EMPTY_P
+ The class is empty, i.e., contains no non-static data members.
+
+ CANT_HAVE_CONST_CTOR_P
+ This class cannot have an implicitly generated copy constructor
+ taking a const reference.
+
+ CANT_HAVE_CONST_ASN_REF
+ This class cannot have an implicitly generated assignment
+ operator taking a const reference.
+
+ All of these flags should be initialized before calling this
+ function.
+
+ Returns a pointer to the end of the TYPE_FIELDs chain; additional
+ fields can be added by adding to this chain. */
+
+static void
+check_field_decls (tree t, tree *access_decls,
+ int *cant_have_const_ctor_p,
+ int *no_const_asn_ref_p)
+{
+ tree *field;
+ tree *next;
+ bool has_pointers;
+ int any_default_members;
+ int cant_pack = 0;
+ int field_access = -1;
+
+ /* Assume there are no access declarations. */
+ *access_decls = NULL_TREE;
+ /* Assume this class has no pointer members. */
+ has_pointers = false;
+ /* Assume none of the members of this class have default
+ initializations. */
+ any_default_members = 0;
+
+ for (field = &TYPE_FIELDS (t); *field; field = next)
+ {
+ tree x = *field;
+ tree type = TREE_TYPE (x);
+ int this_field_access;
+
+ next = &DECL_CHAIN (x);
+
+ if (TREE_CODE (x) == USING_DECL)
+ {
+ /* Save the access declarations for our caller. */
+ *access_decls = tree_cons (NULL_TREE, x, *access_decls);
+ continue;
+ }
+
+ if (TREE_CODE (x) == TYPE_DECL
+ || TREE_CODE (x) == TEMPLATE_DECL)
+ continue;
+
+ /* If we've gotten this far, it's a data member, possibly static,
+ or an enumerator. */
+ if (TREE_CODE (x) != CONST_DECL)
+ DECL_CONTEXT (x) = t;
+
+ /* When this goes into scope, it will be a non-local reference. */
+ DECL_NONLOCAL (x) = 1;
+
+ if (TREE_CODE (t) == UNION_TYPE)
+ {
+ /* [class.union]
+
+ If a union contains a static data member, or a member of
+ reference type, the program is ill-formed. */
+ if (VAR_P (x))
+ {
+ error ("%q+D may not be static because it is a member of a union", x);
+ continue;
+ }
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ error ("%q+D may not have reference type %qT because"
+ " it is a member of a union",
+ x, type);
+ continue;
+ }
+ }
+
+ /* Perform error checking that did not get done in
+ grokdeclarator. */
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ error ("field %q+D invalidly declared function type", x);
+ type = build_pointer_type (type);
+ TREE_TYPE (x) = type;
+ }
+ else if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ error ("field %q+D invalidly declared method type", x);
+ type = build_pointer_type (type);
+ TREE_TYPE (x) = type;
+ }
+
+ if (type == error_mark_node)
+ continue;
+
+ if (TREE_CODE (x) == CONST_DECL || VAR_P (x))
+ continue;
+
+ /* Now it can only be a FIELD_DECL. */
+
+ if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
+ CLASSTYPE_NON_AGGREGATE (t) = 1;
+
+ /* If at least one non-static data member is non-literal, the whole
+ class becomes non-literal. Note: if the type is incomplete we
+ will complain later on. */
+ if (COMPLETE_TYPE_P (type) && !literal_type_p (type))
+ CLASSTYPE_LITERAL_P (t) = false;
+
+ /* A standard-layout class is a class that:
+ ...
+ has the same access control (Clause 11) for all non-static data members,
+ ... */
+ this_field_access = TREE_PROTECTED (x) ? 1 : TREE_PRIVATE (x) ? 2 : 0;
+ if (field_access == -1)
+ field_access = this_field_access;
+ else if (this_field_access != field_access)
+ CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+
+ /* If this is of reference type, check if it needs an init. */
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;
+ CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+ if (DECL_INITIAL (x) == NULL_TREE)
+ SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
+
+ /* ARM $12.6.2: [A member initializer list] (or, for an
+ aggregate, initialization by a brace-enclosed list) is the
+ only way to initialize nonstatic const and reference
+ members. */
+ TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
+ TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
+ }
+
+ type = strip_array_types (type);
+
+ if (TYPE_PACKED (t))
+ {
+ if (!layout_pod_type_p (type) && !TYPE_PACKED (type))
+ {
+ warning
+ (0,
+ "ignoring packed attribute because of unpacked non-POD field %q+#D",
+ x);
+ cant_pack = 1;
+ }
+ else if (DECL_C_BIT_FIELD (x)
+ || TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
+ DECL_PACKED (x) = 1;
+ }
+
+ if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
+ /* We don't treat zero-width bitfields as making a class
+ non-empty. */
+ ;
+ else
+ {
+ /* The class is non-empty. */
+ CLASSTYPE_EMPTY_P (t) = 0;
+ /* The class is not even nearly empty. */
+ CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+ /* If one of the data members contains an empty class,
+ so does T. */
+ if (CLASS_TYPE_P (type)
+ && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
+ }
+
+ /* This is used by -Weffc++ (see below). Warn only for pointers
+ to members which might hold dynamic memory. So do not warn
+ for pointers to functions or pointers to members. */
+ if (TYPE_PTR_P (type)
+ && !TYPE_PTRFN_P (type))
+ has_pointers = true;
+
+ if (CLASS_TYPE_P (type))
+ {
+ if (CLASSTYPE_REF_FIELDS_NEED_INIT (type))
+ SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
+ if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
+ SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
+ }
+
+ if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
+ CLASSTYPE_HAS_MUTABLE (t) = 1;
+
+ if (DECL_MUTABLE_P (x))
+ {
+ if (CP_TYPE_CONST_P (type))
+ {
+ error ("member %q+D cannot be declared both %<const%> "
+ "and %<mutable%>", x);
+ continue;
+ }
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ error ("member %q+D cannot be declared as a %<mutable%> "
+ "reference", x);
+ continue;
+ }
+ }
+
+ if (! layout_pod_type_p (type))
+ /* DR 148 now allows pointers to members (which are POD themselves),
+ to be allowed in POD structs. */
+ CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;
+
+ if (!std_layout_type_p (type))
+ CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+
+ if (! zero_init_p (type))
+ CLASSTYPE_NON_ZERO_INIT_P (t) = 1;
+
+ /* We set DECL_C_BIT_FIELD in grokbitfield.
+ If the type and width are valid, we'll also set DECL_BIT_FIELD. */
+ if (! DECL_C_BIT_FIELD (x) || ! check_bitfield_decl (x))
+ check_field_decl (x, t,
+ cant_have_const_ctor_p,
+ no_const_asn_ref_p,
+ &any_default_members);
+
+ /* Now that we've removed bit-field widths from DECL_INITIAL,
+ anything left in DECL_INITIAL is an NSDMI that makes the class
+ non-aggregate. */
+ if (DECL_INITIAL (x))
+ CLASSTYPE_NON_AGGREGATE (t) = true;
+
+ /* If any field is const, the structure type is pseudo-const. */
+ if (CP_TYPE_CONST_P (type))
+ {
+ C_TYPE_FIELDS_READONLY (t) = 1;
+ if (DECL_INITIAL (x) == NULL_TREE)
+ SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
+
+ /* ARM $12.6.2: [A member initializer list] (or, for an
+ aggregate, initialization by a brace-enclosed list) is the
+ only way to initialize nonstatic const and reference
+ members. */
+ TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
+ TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
+ }
+ /* A field that is pseudo-const makes the structure likewise. */
+ else if (CLASS_TYPE_P (type))
+ {
+ C_TYPE_FIELDS_READONLY (t) |= C_TYPE_FIELDS_READONLY (type);
+ SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t,
+ CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)
+ | CLASSTYPE_READONLY_FIELDS_NEED_INIT (type));
+ }
+
+ /* Core issue 80: A nonstatic data member is required to have a
+ different name from the class iff the class has a
+ user-declared constructor. */
+ if (constructor_name_p (DECL_NAME (x), t)
+ && TYPE_HAS_USER_CONSTRUCTOR (t))
+ permerror (input_location, "field %q+#D with same name as class", x);
+ }
+
+ /* Effective C++ rule 11: if a class has dynamic memory held by pointers,
+ it should also define a copy constructor and an assignment operator to
+ implement the correct copy semantic (deep vs shallow, etc.). As it is
+ not feasible to check whether the constructors do allocate dynamic memory
+ and store it within members, we approximate the warning like this:
+
+ -- Warn only if there are members which are pointers
+ -- Warn only if there is a non-trivial constructor (otherwise,
+ there cannot be memory allocated).
+ -- Warn only if there is a non-trivial destructor. We assume that the
+ user at least implemented the cleanup correctly, and a destructor
+ is needed to free dynamic memory.
+
+ This seems enough for practical purposes. */
+ if (warn_ecpp
+ && has_pointers
+ && TYPE_HAS_USER_CONSTRUCTOR (t)
+ && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
+ && !(TYPE_HAS_COPY_CTOR (t) && TYPE_HAS_COPY_ASSIGN (t)))
+ {
+ warning (OPT_Weffc__, "%q#T has pointer data members", t);
+
+ if (! TYPE_HAS_COPY_CTOR (t))
+ {
+ warning (OPT_Weffc__,
+ " but does not override %<%T(const %T&)%>", t, t);
+ if (!TYPE_HAS_COPY_ASSIGN (t))
+ warning (OPT_Weffc__, " or %<operator=(const %T&)%>", t);
+ }
+ else if (! TYPE_HAS_COPY_ASSIGN (t))
+ warning (OPT_Weffc__,
+ " but does not override %<operator=(const %T&)%>", t);
+ }
+
+ /* Non-static data member initializers make the default constructor
+ non-trivial. */
+ if (any_default_members)
+ {
+ TYPE_NEEDS_CONSTRUCTING (t) = true;
+ TYPE_HAS_COMPLEX_DFLT (t) = true;
+ }
+
+ /* If any of the fields couldn't be packed, unset TYPE_PACKED. */
+ if (cant_pack)
+ TYPE_PACKED (t) = 0;
+
+ /* Check anonymous struct/anonymous union fields. */
+ finish_struct_anon (t);
+
+ /* We've built up the list of access declarations in reverse order.
+ Fix that now. */
+ *access_decls = nreverse (*access_decls);
+}
+
+/* If TYPE is an empty class type, records its OFFSET in the table of
+ OFFSETS. */
+
+static int
+record_subobject_offset (tree type, tree offset, splay_tree offsets)
+{
+ splay_tree_node n;
+
+ if (!is_empty_class (type))
+ return 0;
+
+ /* Record the location of this empty object in OFFSETS. */
+ n = splay_tree_lookup (offsets, (splay_tree_key) offset);
+ if (!n)
+ n = splay_tree_insert (offsets,
+ (splay_tree_key) offset,
+ (splay_tree_value) NULL_TREE);
+ n->value = ((splay_tree_value)
+ tree_cons (NULL_TREE,
+ type,
+ (tree) n->value));
+
+ return 0;
+}
+
+/* Returns nonzero if TYPE is an empty class type and there is
+ already an entry in OFFSETS for the same TYPE as the same OFFSET. */
+
+static int
+check_subobject_offset (tree type, tree offset, splay_tree offsets)
+{
+ splay_tree_node n;
+ tree t;
+
+ if (!is_empty_class (type))
+ return 0;
+
+ /* Record the location of this empty object in OFFSETS. */
+ n = splay_tree_lookup (offsets, (splay_tree_key) offset);
+ if (!n)
+ return 0;
+
+ for (t = (tree) n->value; t; t = TREE_CHAIN (t))
+ if (same_type_p (TREE_VALUE (t), type))
+ return 1;
+
+ return 0;
+}
+
+/* Walk through all the subobjects of TYPE (located at OFFSET). Call
+ F for every subobject, passing it the type, offset, and table of
+ OFFSETS. If VBASES_P is one, then virtual non-primary bases should
+ be traversed.
+
+ If MAX_OFFSET is non-NULL, then subobjects with an offset greater
+ than MAX_OFFSET will not be walked.
+
+ If F returns a nonzero value, the traversal ceases, and that value
+ is returned. Otherwise, returns zero. */
+
+static int
+walk_subobject_offsets (tree type,
+ subobject_offset_fn f,
+ tree offset,
+ splay_tree offsets,
+ tree max_offset,
+ int vbases_p)
+{
+ int r = 0;
+ tree type_binfo = NULL_TREE;
+
+ /* If this OFFSET is bigger than the MAX_OFFSET, then we should
+ stop. */
+ if (max_offset && INT_CST_LT (max_offset, offset))
+ return 0;
+
+ if (type == error_mark_node)
+ return 0;
+
+ if (!TYPE_P (type))
+ {
+ if (abi_version_at_least (2))
+ type_binfo = type;
+ type = BINFO_TYPE (type);
+ }
+
+ if (CLASS_TYPE_P (type))
+ {
+ tree field;
+ tree binfo;
+ int i;
+
+ /* Avoid recursing into objects that are not interesting. */
+ if (!CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
+ return 0;
+
+ /* Record the location of TYPE. */
+ r = (*f) (type, offset, offsets);
+ if (r)
+ return r;
+
+ /* Iterate through the direct base classes of TYPE. */
+ if (!type_binfo)
+ type_binfo = TYPE_BINFO (type);
+ for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, binfo); i++)
+ {
+ tree binfo_offset;
+
+ if (abi_version_at_least (2)
+ && BINFO_VIRTUAL_P (binfo))
+ continue;
+
+ if (!vbases_p
+ && BINFO_VIRTUAL_P (binfo)
+ && !BINFO_PRIMARY_P (binfo))
+ continue;
+
+ if (!abi_version_at_least (2))
+ binfo_offset = size_binop (PLUS_EXPR,
+ offset,
+ BINFO_OFFSET (binfo));
+ else
+ {
+ tree orig_binfo;
+ /* We cannot rely on BINFO_OFFSET being set for the base
+ class yet, but the offsets for direct non-virtual
+ bases can be calculated by going back to the TYPE. */
+ orig_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
+ binfo_offset = size_binop (PLUS_EXPR,
+ offset,
+ BINFO_OFFSET (orig_binfo));
+ }
+
+ r = walk_subobject_offsets (binfo,
+ f,
+ binfo_offset,
+ offsets,
+ max_offset,
+ (abi_version_at_least (2)
+ ? /*vbases_p=*/0 : vbases_p));
+ if (r)
+ return r;
+ }
+
+ if (abi_version_at_least (2) && CLASSTYPE_VBASECLASSES (type))
+ {
+ unsigned ix;
+ vec<tree, va_gc> *vbases;
+
+ /* Iterate through the virtual base classes of TYPE. In G++
+ 3.2, we included virtual bases in the direct base class
+ loop above, which results in incorrect results; the
+ correct offsets for virtual bases are only known when
+ working with the most derived type. */
+ if (vbases_p)
+ for (vbases = CLASSTYPE_VBASECLASSES (type), ix = 0;
+ vec_safe_iterate (vbases, ix, &binfo); ix++)
+ {
+ r = walk_subobject_offsets (binfo,
+ f,
+ size_binop (PLUS_EXPR,
+ offset,
+ BINFO_OFFSET (binfo)),
+ offsets,
+ max_offset,
+ /*vbases_p=*/0);
+ if (r)
+ return r;
+ }
+ else
+ {
+ /* We still have to walk the primary base, if it is
+ virtual. (If it is non-virtual, then it was walked
+ above.) */
+ tree vbase = get_primary_binfo (type_binfo);
+
+ if (vbase && BINFO_VIRTUAL_P (vbase)
+ && BINFO_PRIMARY_P (vbase)
+ && BINFO_INHERITANCE_CHAIN (vbase) == type_binfo)
+ {
+ r = (walk_subobject_offsets
+ (vbase, f, offset,
+ offsets, max_offset, /*vbases_p=*/0));
+ if (r)
+ return r;
+ }
+ }
+ }
+
+ /* Iterate through the fields of TYPE. */
+ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL
+ && TREE_TYPE (field) != error_mark_node
+ && !DECL_ARTIFICIAL (field))
+ {
+ tree field_offset;
+
+ if (abi_version_at_least (2))
+ field_offset = byte_position (field);
+ else
+ /* In G++ 3.2, DECL_FIELD_OFFSET was used. */
+ field_offset = DECL_FIELD_OFFSET (field);
+
+ r = walk_subobject_offsets (TREE_TYPE (field),
+ f,
+ size_binop (PLUS_EXPR,
+ offset,
+ field_offset),
+ offsets,
+ max_offset,
+ /*vbases_p=*/1);
+ if (r)
+ return r;
+ }
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree element_type = strip_array_types (type);
+ tree domain = TYPE_DOMAIN (type);
+ tree index;
+
+ /* Avoid recursing into objects that are not interesting. */
+ if (!CLASS_TYPE_P (element_type)
+ || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
+ return 0;
+
+ /* Step through each of the elements in the array. */
+ for (index = size_zero_node;
+ /* G++ 3.2 had an off-by-one error here. */
+ (abi_version_at_least (2)
+ ? !INT_CST_LT (TYPE_MAX_VALUE (domain), index)
+ : INT_CST_LT (index, TYPE_MAX_VALUE (domain)));
+ index = size_binop (PLUS_EXPR, index, size_one_node))
+ {
+ r = walk_subobject_offsets (TREE_TYPE (type),
+ f,
+ offset,
+ offsets,
+ max_offset,
+ /*vbases_p=*/1);
+ if (r)
+ return r;
+ offset = size_binop (PLUS_EXPR, offset,
+ TYPE_SIZE_UNIT (TREE_TYPE (type)));
+ /* If this new OFFSET is bigger than the MAX_OFFSET, then
+ there's no point in iterating through the remaining
+ elements of the array. */
+ if (max_offset && INT_CST_LT (max_offset, offset))
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/* Record all of the empty subobjects of TYPE (either a type or a
+ binfo). If IS_DATA_MEMBER is true, then a non-static data member
+ is being placed at OFFSET; otherwise, it is a base class that is
+ being placed at OFFSET. */
+
+static void
+record_subobject_offsets (tree type,
+ tree offset,
+ splay_tree offsets,
+ bool is_data_member)
+{
+ tree max_offset;
+ /* If recording subobjects for a non-static data member or a
+ non-empty base class , we do not need to record offsets beyond
+ the size of the biggest empty class. Additional data members
+ will go at the end of the class. Additional base classes will go
+ either at offset zero (if empty, in which case they cannot
+ overlap with offsets past the size of the biggest empty class) or
+ at the end of the class.
+
+ However, if we are placing an empty base class, then we must record
+ all offsets, as either the empty class is at offset zero (where
+ other empty classes might later be placed) or at the end of the
+ class (where other objects might then be placed, so other empty
+ subobjects might later overlap). */
+ if (is_data_member
+ || !is_empty_class (BINFO_TYPE (type)))
+ max_offset = sizeof_biggest_empty_class;
+ else
+ max_offset = NULL_TREE;
+ walk_subobject_offsets (type, record_subobject_offset, offset,
+ offsets, max_offset, is_data_member);
+}
+
+/* Returns nonzero if any of the empty subobjects of TYPE (located at
+ OFFSET) conflict with entries in OFFSETS. If VBASES_P is nonzero,
+ virtual bases of TYPE are examined. */
+
+static int
+layout_conflict_p (tree type,
+ tree offset,
+ splay_tree offsets,
+ int vbases_p)
+{
+ splay_tree_node max_node;
+
+ /* Get the node in OFFSETS that indicates the maximum offset where
+ an empty subobject is located. */
+ max_node = splay_tree_max (offsets);
+ /* If there aren't any empty subobjects, then there's no point in
+ performing this check. */
+ if (!max_node)
+ return 0;
+
+ return walk_subobject_offsets (type, check_subobject_offset, offset,
+ offsets, (tree) (max_node->key),
+ vbases_p);
+}
+
+/* DECL is a FIELD_DECL corresponding either to a base subobject of a
+ non-static data member of the type indicated by RLI. BINFO is the
+ binfo corresponding to the base subobject, OFFSETS maps offsets to
+ types already located at those offsets. This function determines
+ the position of the DECL. */
+
+static void
+layout_nonempty_base_or_field (record_layout_info rli,
+ tree decl,
+ tree binfo,
+ splay_tree offsets)
+{
+ tree offset = NULL_TREE;
+ bool field_p;
+ tree type;
+
+ if (binfo)
+ {
+ /* For the purposes of determining layout conflicts, we want to
+ use the class type of BINFO; TREE_TYPE (DECL) will be the
+ CLASSTYPE_AS_BASE version, which does not contain entries for
+ zero-sized bases. */
+ type = TREE_TYPE (binfo);
+ field_p = false;
+ }
+ else
+ {
+ type = TREE_TYPE (decl);
+ field_p = true;
+ }
+
+ /* Try to place the field. It may take more than one try if we have
+ a hard time placing the field without putting two objects of the
+ same type at the same address. */
+ while (1)
+ {
+ struct record_layout_info_s old_rli = *rli;
+
+ /* Place this field. */
+ place_field (rli, decl);
+ offset = byte_position (decl);
+
+ /* We have to check to see whether or not there is already
+ something of the same type at the offset we're about to use.
+ For example, consider:
+
+ struct S {};
+ struct T : public S { int i; };
+ struct U : public S, public T {};
+
+ Here, we put S at offset zero in U. Then, we can't put T at
+ offset zero -- its S component would be at the same address
+ as the S we already allocated. So, we have to skip ahead.
+ Since all data members, including those whose type is an
+ empty class, have nonzero size, any overlap can happen only
+ with a direct or indirect base-class -- it can't happen with
+ a data member. */
+ /* In a union, overlap is permitted; all members are placed at
+ offset zero. */
+ if (TREE_CODE (rli->t) == UNION_TYPE)
+ break;
+ /* G++ 3.2 did not check for overlaps when placing a non-empty
+ virtual base. */
+ if (!abi_version_at_least (2) && binfo && BINFO_VIRTUAL_P (binfo))
+ break;
+ if (layout_conflict_p (field_p ? type : binfo, offset,
+ offsets, field_p))
+ {
+ /* Strip off the size allocated to this field. That puts us
+ at the first place we could have put the field with
+ proper alignment. */
+ *rli = old_rli;
+
+ /* Bump up by the alignment required for the type. */
+ rli->bitpos
+ = size_binop (PLUS_EXPR, rli->bitpos,
+ bitsize_int (binfo
+ ? CLASSTYPE_ALIGN (type)
+ : TYPE_ALIGN (type)));
+ normalize_rli (rli);
+ }
+ else
+ /* There was no conflict. We're done laying out this field. */
+ break;
+ }
+
+ /* Now that we know where it will be placed, update its
+ BINFO_OFFSET. */
+ if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo)))
+ /* Indirect virtual bases may have a nonzero BINFO_OFFSET at
+ this point because their BINFO_OFFSET is copied from another
+ hierarchy. Therefore, we may not need to add the entire
+ OFFSET. */
+ propagate_binfo_offsets (binfo,
+ size_diffop_loc (input_location,
+ convert (ssizetype, offset),
+ convert (ssizetype,
+ BINFO_OFFSET (binfo))));
+}
+
+/* Returns true if TYPE is empty and OFFSET is nonzero. */
+
+static int
+empty_base_at_nonzero_offset_p (tree type,
+ tree offset,
+ splay_tree /*offsets*/)
+{
+ return is_empty_class (type) && !integer_zerop (offset);
+}
+
+/* Layout the empty base BINFO. EOC indicates the byte currently just
+ past the end of the class, and should be correctly aligned for a
+ class of the type indicated by BINFO; OFFSETS gives the offsets of
+ the empty bases allocated so far. T is the most derived
+ type. Return nonzero iff we added it at the end. */
+
+static bool
+layout_empty_base (record_layout_info rli, tree binfo,
+ tree eoc, splay_tree offsets)
+{
+ tree alignment;
+ tree basetype = BINFO_TYPE (binfo);
+ bool atend = false;
+
+ /* This routine should only be used for empty classes. */
+ gcc_assert (is_empty_class (basetype));
+ alignment = ssize_int (CLASSTYPE_ALIGN_UNIT (basetype));
+
+ if (!integer_zerop (BINFO_OFFSET (binfo)))
+ {
+ if (abi_version_at_least (2))
+ propagate_binfo_offsets
+ (binfo, size_diffop_loc (input_location,
+ size_zero_node, BINFO_OFFSET (binfo)));
+ else
+ warning (OPT_Wabi,
+ "offset of empty base %qT may not be ABI-compliant and may"
+ "change in a future version of GCC",
+ BINFO_TYPE (binfo));
+ }
+
+ /* This is an empty base class. We first try to put it at offset
+ zero. */
+ if (layout_conflict_p (binfo,
+ BINFO_OFFSET (binfo),
+ offsets,
+ /*vbases_p=*/0))
+ {
+ /* That didn't work. Now, we move forward from the next
+ available spot in the class. */
+ atend = true;
+ propagate_binfo_offsets (binfo, convert (ssizetype, eoc));
+ while (1)
+ {
+ if (!layout_conflict_p (binfo,
+ BINFO_OFFSET (binfo),
+ offsets,
+ /*vbases_p=*/0))
+ /* We finally found a spot where there's no overlap. */
+ break;
+
+ /* There's overlap here, too. Bump along to the next spot. */
+ propagate_binfo_offsets (binfo, alignment);
+ }
+ }
+
+ if (CLASSTYPE_USER_ALIGN (basetype))
+ {
+ rli->record_align = MAX (rli->record_align, CLASSTYPE_ALIGN (basetype));
+ if (warn_packed)
+ rli->unpacked_align = MAX (rli->unpacked_align, CLASSTYPE_ALIGN (basetype));
+ TYPE_USER_ALIGN (rli->t) = 1;
+ }
+
+ return atend;
+}
+
+/* Layout the base given by BINFO in the class indicated by RLI.
+ *BASE_ALIGN is a running maximum of the alignments of
+ any base class. OFFSETS gives the location of empty base
+ subobjects. T is the most derived type. Return nonzero if the new
+ object cannot be nearly-empty. A new FIELD_DECL is inserted at
+ *NEXT_FIELD, unless BINFO is for an empty base class.
+
+ Returns the location at which the next field should be inserted. */
+
+static tree *
+build_base_field (record_layout_info rli, tree binfo,
+ splay_tree offsets, tree *next_field)
+{
+ tree t = rli->t;
+ tree basetype = BINFO_TYPE (binfo);
+
+ if (!COMPLETE_TYPE_P (basetype))
+ /* This error is now reported in xref_tag, thus giving better
+ location information. */
+ return next_field;
+
+ /* Place the base class. */
+ if (!is_empty_class (basetype))
+ {
+ tree decl;
+
+ /* The containing class is non-empty because it has a non-empty
+ base class. */
+ CLASSTYPE_EMPTY_P (t) = 0;
+
+ /* Create the FIELD_DECL. */
+ decl = build_decl (input_location,
+ FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ DECL_FIELD_CONTEXT (decl) = t;
+ if (CLASSTYPE_AS_BASE (basetype))
+ {
+ DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
+ DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
+ DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
+ DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
+ DECL_MODE (decl) = TYPE_MODE (basetype);
+ DECL_FIELD_IS_BASE (decl) = 1;
+
+ /* Try to place the field. It may take more than one try if we
+ have a hard time placing the field without putting two
+ objects of the same type at the same address. */
+ layout_nonempty_base_or_field (rli, decl, binfo, offsets);
+ /* Add the new FIELD_DECL to the list of fields for T. */
+ DECL_CHAIN (decl) = *next_field;
+ *next_field = decl;
+ next_field = &DECL_CHAIN (decl);
+ }
+ }
+ else
+ {
+ tree eoc;
+ bool atend;
+
+ /* On some platforms (ARM), even empty classes will not be
+ byte-aligned. */
+ eoc = round_up_loc (input_location,
+ rli_size_unit_so_far (rli),
+ CLASSTYPE_ALIGN_UNIT (basetype));
+ atend = layout_empty_base (rli, binfo, eoc, offsets);
+ /* A nearly-empty class "has no proper base class that is empty,
+ not morally virtual, and at an offset other than zero." */
+ if (!BINFO_VIRTUAL_P (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))
+ {
+ if (atend)
+ CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+ /* The check above (used in G++ 3.2) is insufficient because
+ an empty class placed at offset zero might itself have an
+ empty base at a nonzero offset. */
+ else if (walk_subobject_offsets (basetype,
+ empty_base_at_nonzero_offset_p,
+ size_zero_node,
+ /*offsets=*/NULL,
+ /*max_offset=*/NULL_TREE,
+ /*vbases_p=*/true))
+ {
+ if (abi_version_at_least (2))
+ CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+ else
+ warning (OPT_Wabi,
+ "class %qT will be considered nearly empty in a "
+ "future version of GCC", t);
+ }
+ }
+
+ /* We do not create a FIELD_DECL for empty base classes because
+ it might overlap some other field. We want to be able to
+ create CONSTRUCTORs for the class by iterating over the
+ FIELD_DECLs, and the back end does not handle overlapping
+ FIELD_DECLs. */
+
+ /* An empty virtual base causes a class to be non-empty
+ -- but in that case we do not need to clear CLASSTYPE_EMPTY_P
+ here because that was already done when the virtual table
+ pointer was created. */
+ }
+
+ /* Record the offsets of BINFO and its base subobjects. */
+ record_subobject_offsets (binfo,
+ BINFO_OFFSET (binfo),
+ offsets,
+ /*is_data_member=*/false);
+
+ return next_field;
+}
+
+/* Layout all of the non-virtual base classes. Record empty
+ subobjects in OFFSETS. T is the most derived type. Return nonzero
+ if the type cannot be nearly empty. The fields created
+ corresponding to the base classes will be inserted at
+ *NEXT_FIELD. */
+
+static void
+build_base_fields (record_layout_info rli,
+ splay_tree offsets, tree *next_field)
+{
+ /* Chain to hold all the new FIELD_DECLs which stand in for base class
+ subobjects. */
+ tree t = rli->t;
+ int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
+ int i;
+
+ /* The primary base class is always allocated first. */
+ if (CLASSTYPE_HAS_PRIMARY_BASE_P (t))
+ next_field = build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (t),
+ offsets, next_field);
+
+ /* Now allocate the rest of the bases. */
+ for (i = 0; i < n_baseclasses; ++i)
+ {
+ tree base_binfo;
+
+ base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (t), i);
+
+ /* The primary base was already allocated above, so we don't
+ need to allocate it again here. */
+ if (base_binfo == CLASSTYPE_PRIMARY_BINFO (t))
+ continue;
+
+ /* Virtual bases are added at the end (a primary virtual base
+ will have already been added). */
+ if (BINFO_VIRTUAL_P (base_binfo))
+ continue;
+
+ next_field = build_base_field (rli, base_binfo,
+ offsets, next_field);
+ }
+}
+
+/* Go through the TYPE_METHODS of T issuing any appropriate
+ diagnostics, figuring out which methods override which other
+ methods, and so forth. */
+
+static void
+check_methods (tree t)
+{
+ tree x;
+
+ for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x))
+ {
+ check_for_override (x, t);
+ if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x))
+ error ("initializer specified for non-virtual method %q+D", x);
+ /* The name of the field is the original field name
+ Save this in auxiliary field for later overloading. */
+ if (DECL_VINDEX (x))
+ {
+ TYPE_POLYMORPHIC_P (t) = 1;
+ if (DECL_PURE_VIRTUAL_P (x))
+ vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
+ }
+ /* All user-provided destructors are non-trivial.
+ Constructors and assignment ops are handled in
+ grok_special_member_properties. */
+ if (DECL_DESTRUCTOR_P (x) && user_provided_p (x))
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
+ }
+}
+
+/* FN is a constructor or destructor. Clone the declaration to create
+ a specialized in-charge or not-in-charge version, as indicated by
+ NAME. */
+
+static tree
+build_clone (tree fn, tree name)
+{
+ tree parms;
+ tree clone;
+
+ /* Copy the function. */
+ clone = copy_decl (fn);
+ /* Reset the function name. */
+ DECL_NAME (clone) = name;
+ SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
+ /* Remember where this function came from. */
+ DECL_ABSTRACT_ORIGIN (clone) = fn;
+ /* Make it easy to find the CLONE given the FN. */
+ DECL_CHAIN (clone) = DECL_CHAIN (fn);
+ DECL_CHAIN (fn) = clone;
+
+ /* If this is a template, do the rest on the DECL_TEMPLATE_RESULT. */
+ if (TREE_CODE (clone) == TEMPLATE_DECL)
+ {
+ tree result = build_clone (DECL_TEMPLATE_RESULT (clone), name);
+ DECL_TEMPLATE_RESULT (clone) = result;
+ DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
+ DECL_TI_TEMPLATE (result) = clone;
+ TREE_TYPE (clone) = TREE_TYPE (result);
+ return clone;
+ }
+
+ DECL_CLONED_FUNCTION (clone) = fn;
+ /* There's no pending inline data for this function. */
+ DECL_PENDING_INLINE_INFO (clone) = NULL;
+ DECL_PENDING_INLINE_P (clone) = 0;
+
+ /* The base-class destructor is not virtual. */
+ if (name == base_dtor_identifier)
+ {
+ DECL_VIRTUAL_P (clone) = 0;
+ if (TREE_CODE (clone) != TEMPLATE_DECL)
+ DECL_VINDEX (clone) = NULL_TREE;
+ }
+
+ /* If there was an in-charge parameter, drop it from the function
+ type. */
+ if (DECL_HAS_IN_CHARGE_PARM_P (clone))
+ {
+ tree basetype;
+ tree parmtypes;
+ tree exceptions;
+
+ exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
+ basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
+ parmtypes = TYPE_ARG_TYPES (TREE_TYPE (clone));
+ /* Skip the `this' parameter. */
+ parmtypes = TREE_CHAIN (parmtypes);
+ /* Skip the in-charge parameter. */
+ parmtypes = TREE_CHAIN (parmtypes);
+ /* And the VTT parm, in a complete [cd]tor. */
+ if (DECL_HAS_VTT_PARM_P (fn)
+ && ! DECL_NEEDS_VTT_PARM_P (clone))
+ parmtypes = TREE_CHAIN (parmtypes);
+ /* If this is subobject constructor or destructor, add the vtt
+ parameter. */
+ TREE_TYPE (clone)
+ = build_method_type_directly (basetype,
+ TREE_TYPE (TREE_TYPE (clone)),
+ parmtypes);
+ if (exceptions)
+ TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone),
+ exceptions);
+ TREE_TYPE (clone)
+ = cp_build_type_attribute_variant (TREE_TYPE (clone),
+ TYPE_ATTRIBUTES (TREE_TYPE (fn)));
+ }
+
+ /* Copy the function parameters. */
+ DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
+ /* Remove the in-charge parameter. */
+ if (DECL_HAS_IN_CHARGE_PARM_P (clone))
+ {
+ DECL_CHAIN (DECL_ARGUMENTS (clone))
+ = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone)));
+ DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
+ }
+ /* And the VTT parm, in a complete [cd]tor. */
+ if (DECL_HAS_VTT_PARM_P (fn))
+ {
+ if (DECL_NEEDS_VTT_PARM_P (clone))
+ DECL_HAS_VTT_PARM_P (clone) = 1;
+ else
+ {
+ DECL_CHAIN (DECL_ARGUMENTS (clone))
+ = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone)));
+ DECL_HAS_VTT_PARM_P (clone) = 0;
+ }
+ }
+
+ for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms))
+ {
+ DECL_CONTEXT (parms) = clone;
+ cxx_dup_lang_specific_decl (parms);
+ }
+
+ /* Create the RTL for this function. */
+ SET_DECL_RTL (clone, NULL);
+ rest_of_decl_compilation (clone, /*top_level=*/1, at_eof);
+
+ if (pch_file)
+ note_decl_for_pch (clone);
+
+ return clone;
+}
+
+/* Implementation of DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P, do
+ not invoke this function directly.
+
+ For a non-thunk function, returns the address of the slot for storing
+ the function it is a clone of. Otherwise returns NULL_TREE.
+
+ If JUST_TESTING, looks through TEMPLATE_DECL and returns NULL if
+ cloned_function is unset. This is to support the separate
+ DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P modes; using the latter
+ on a template makes sense, but not the former. */
+
+tree *
+decl_cloned_function_p (const_tree decl, bool just_testing)
+{
+ tree *ptr;
+ if (just_testing)
+ decl = STRIP_TEMPLATE (decl);
+
+ if (TREE_CODE (decl) != FUNCTION_DECL
+ || !DECL_LANG_SPECIFIC (decl)
+ || DECL_LANG_SPECIFIC (decl)->u.fn.thunk_p)
+ {
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+ if (!just_testing)
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__);
+ else
+#endif
+ return NULL;
+ }
+
+ ptr = &DECL_LANG_SPECIFIC (decl)->u.fn.u5.cloned_function;
+ if (just_testing && *ptr == NULL_TREE)
+ return NULL;
+ else
+ return ptr;
+}
+
+/* Produce declarations for all appropriate clones of FN. If
+ UPDATE_METHOD_VEC_P is nonzero, the clones are added to the
+ CLASTYPE_METHOD_VEC as well. */
+
+void
+clone_function_decl (tree fn, int update_method_vec_p)
+{
+ tree clone;
+
+ /* Avoid inappropriate cloning. */
+ if (DECL_CHAIN (fn)
+ && DECL_CLONED_FUNCTION_P (DECL_CHAIN (fn)))
+ return;
+
+ if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
+ {
+ /* For each constructor, we need two variants: an in-charge version
+ and a not-in-charge version. */
+ clone = build_clone (fn, complete_ctor_identifier);
+ if (update_method_vec_p)
+ add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
+ clone = build_clone (fn, base_ctor_identifier);
+ if (update_method_vec_p)
+ add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
+ }
+ else
+ {
+ gcc_assert (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn));
+
+ /* For each destructor, we need three variants: an in-charge
+ version, a not-in-charge version, and an in-charge deleting
+ version. We clone the deleting version first because that
+ means it will go second on the TYPE_METHODS list -- and that
+ corresponds to the correct layout order in the virtual
+ function table.
+
+ For a non-virtual destructor, we do not build a deleting
+ destructor. */
+ if (DECL_VIRTUAL_P (fn))
+ {
+ clone = build_clone (fn, deleting_dtor_identifier);
+ if (update_method_vec_p)
+ add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
+ }
+ clone = build_clone (fn, complete_dtor_identifier);
+ if (update_method_vec_p)
+ add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
+ clone = build_clone (fn, base_dtor_identifier);
+ if (update_method_vec_p)
+ add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
+ }
+
+ /* Note that this is an abstract function that is never emitted. */
+ DECL_ABSTRACT (fn) = 1;
+}
+
+/* DECL is an in charge constructor, which is being defined. This will
+ have had an in class declaration, from whence clones were
+ declared. An out-of-class definition can specify additional default
+ arguments. As it is the clones that are involved in overload
+ resolution, we must propagate the information from the DECL to its
+ clones. */
+
+void
+adjust_clone_args (tree decl)
+{
+ tree clone;
+
+ for (clone = DECL_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone);
+ clone = DECL_CHAIN (clone))
+ {
+ tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone));
+ tree orig_decl_parms = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ tree decl_parms, clone_parms;
+
+ clone_parms = orig_clone_parms;
+
+ /* Skip the 'this' parameter. */
+ orig_clone_parms = TREE_CHAIN (orig_clone_parms);
+ orig_decl_parms = TREE_CHAIN (orig_decl_parms);
+
+ if (DECL_HAS_IN_CHARGE_PARM_P (decl))
+ orig_decl_parms = TREE_CHAIN (orig_decl_parms);
+ if (DECL_HAS_VTT_PARM_P (decl))
+ orig_decl_parms = TREE_CHAIN (orig_decl_parms);
+
+ clone_parms = orig_clone_parms;
+ if (DECL_HAS_VTT_PARM_P (clone))
+ clone_parms = TREE_CHAIN (clone_parms);
+
+ for (decl_parms = orig_decl_parms; decl_parms;
+ decl_parms = TREE_CHAIN (decl_parms),
+ clone_parms = TREE_CHAIN (clone_parms))
+ {
+ gcc_assert (same_type_p (TREE_TYPE (decl_parms),
+ TREE_TYPE (clone_parms)));
+
+ if (TREE_PURPOSE (decl_parms) && !TREE_PURPOSE (clone_parms))
+ {
+ /* A default parameter has been added. Adjust the
+ clone's parameters. */
+ tree exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
+ tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (clone));
+ tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
+ tree type;
+
+ clone_parms = orig_decl_parms;
+
+ if (DECL_HAS_VTT_PARM_P (clone))
+ {
+ clone_parms = tree_cons (TREE_PURPOSE (orig_clone_parms),
+ TREE_VALUE (orig_clone_parms),
+ clone_parms);
+ TREE_TYPE (clone_parms) = TREE_TYPE (orig_clone_parms);
+ }
+ type = build_method_type_directly (basetype,
+ TREE_TYPE (TREE_TYPE (clone)),
+ clone_parms);
+ if (exceptions)
+ type = build_exception_variant (type, exceptions);
+ if (attrs)
+ type = cp_build_type_attribute_variant (type, attrs);
+ TREE_TYPE (clone) = type;
+
+ clone_parms = NULL_TREE;
+ break;
+ }
+ }
+ gcc_assert (!clone_parms);
+ }
+}
+
+/* For each of the constructors and destructors in T, create an
+ in-charge and not-in-charge variant. */
+
+static void
+clone_constructors_and_destructors (tree t)
+{
+ tree fns;
+
+ /* If for some reason we don't have a CLASSTYPE_METHOD_VEC, we bail
+ out now. */
+ if (!CLASSTYPE_METHOD_VEC (t))
+ return;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1);
+ for (fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1);
+}
+
+/* Deduce noexcept for a destructor DTOR. */
+
+void
+deduce_noexcept_on_destructor (tree dtor)
+{
+ if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (dtor)))
+ {
+ tree ctx = DECL_CONTEXT (dtor);
+ tree implicit_fn = implicitly_declare_fn (sfk_destructor, ctx,
+ /*const_p=*/false,
+ NULL, NULL);
+ tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
+ TREE_TYPE (dtor) = build_exception_variant (TREE_TYPE (dtor), eh_spec);
+ }
+}
+
+/* For each destructor in T, deduce noexcept:
+
+ 12.4/3: A declaration of a destructor that does not have an
+ exception-specification is implicitly considered to have the
+ same exception-specification as an implicit declaration (15.4). */
+
+static void
+deduce_noexcept_on_destructors (tree t)
+{
+ /* If for some reason we don't have a CLASSTYPE_METHOD_VEC, we bail
+ out now. */
+ if (!CLASSTYPE_METHOD_VEC (t))
+ return;
+
+ for (tree fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ deduce_noexcept_on_destructor (OVL_CURRENT (fns));
+}
+
+/* Subroutine of set_one_vmethod_tm_attributes. Search base classes
+ of TYPE for virtual functions which FNDECL overrides. Return a
+ mask of the tm attributes found therein. */
+
+static int
+look_for_tm_attr_overrides (tree type, tree fndecl)
+{
+ tree binfo = TYPE_BINFO (type);
+ tree base_binfo;
+ int ix, found = 0;
+
+ for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ++ix)
+ {
+ tree o, basetype = BINFO_TYPE (base_binfo);
+
+ if (!TYPE_POLYMORPHIC_P (basetype))
+ continue;
+
+ o = look_for_overrides_here (basetype, fndecl);
+ if (o)
+ found |= tm_attr_to_mask (find_tm_attribute
+ (TYPE_ATTRIBUTES (TREE_TYPE (o))));
+ else
+ found |= look_for_tm_attr_overrides (basetype, fndecl);
+ }
+
+ return found;
+}
+
+/* Subroutine of set_method_tm_attributes. Handle the checks and
+ inheritance for one virtual method FNDECL. */
+
+static void
+set_one_vmethod_tm_attributes (tree type, tree fndecl)
+{
+ tree tm_attr;
+ int found, have;
+
+ found = look_for_tm_attr_overrides (type, fndecl);
+
+ /* If FNDECL doesn't actually override anything (i.e. T is the
+ class that first declares FNDECL virtual), then we're done. */
+ if (found == 0)
+ return;
+
+ tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl)));
+ have = tm_attr_to_mask (tm_attr);
+
+ /* Intel STM Language Extension 3.0, Section 4.2 table 4:
+ tm_pure must match exactly, otherwise no weakening of
+ tm_safe > tm_callable > nothing. */
+ /* ??? The tm_pure attribute didn't make the transition to the
+ multivendor language spec. */
+ if (have == TM_ATTR_PURE)
+ {
+ if (found != TM_ATTR_PURE)
+ {
+ found &= -found;
+ goto err_override;
+ }
+ }
+ /* If the overridden function is tm_pure, then FNDECL must be. */
+ else if (found == TM_ATTR_PURE && tm_attr)
+ goto err_override;
+ /* Look for base class combinations that cannot be satisfied. */
+ else if (found != TM_ATTR_PURE && (found & TM_ATTR_PURE))
+ {
+ found &= ~TM_ATTR_PURE;
+ found &= -found;
+ error_at (DECL_SOURCE_LOCATION (fndecl),
+ "method overrides both %<transaction_pure%> and %qE methods",
+ tm_mask_to_attr (found));
+ }
+ /* If FNDECL did not declare an attribute, then inherit the most
+ restrictive one. */
+ else if (tm_attr == NULL)
+ {
+ apply_tm_attr (fndecl, tm_mask_to_attr (found & -found));
+ }
+ /* Otherwise validate that we're not weaker than a function
+ that is being overridden. */
+ else
+ {
+ found &= -found;
+ if (found <= TM_ATTR_CALLABLE && have > found)
+ goto err_override;
+ }
+ return;
+
+ err_override:
+ error_at (DECL_SOURCE_LOCATION (fndecl),
+ "method declared %qE overriding %qE method",
+ tm_attr, tm_mask_to_attr (found));
+}
+
+/* For each of the methods in T, propagate a class-level tm attribute. */
+
+static void
+set_method_tm_attributes (tree t)
+{
+ tree class_tm_attr, fndecl;
+
+ /* Don't bother collecting tm attributes if transactional memory
+ support is not enabled. */
+ if (!flag_tm)
+ return;
+
+ /* Process virtual methods first, as they inherit directly from the
+ base virtual function and also require validation of new attributes. */
+ if (TYPE_CONTAINS_VPTR_P (t))
+ {
+ tree vchain;
+ for (vchain = BINFO_VIRTUALS (TYPE_BINFO (t)); vchain;
+ vchain = TREE_CHAIN (vchain))
+ {
+ fndecl = BV_FN (vchain);
+ if (DECL_THUNK_P (fndecl))
+ fndecl = THUNK_TARGET (fndecl);
+ set_one_vmethod_tm_attributes (t, fndecl);
+ }
+ }
+
+ /* If the class doesn't have an attribute, nothing more to do. */
+ class_tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (t));
+ if (class_tm_attr == NULL)
+ return;
+
+ /* Any method that does not yet have a tm attribute inherits
+ the one from the class. */
+ for (fndecl = TYPE_METHODS (t); fndecl; fndecl = TREE_CHAIN (fndecl))
+ {
+ if (!find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+ apply_tm_attr (fndecl, class_tm_attr);
+ }
+}
+
+/* Returns true iff class T has a user-defined constructor other than
+ the default constructor. */
+
+bool
+type_has_user_nondefault_constructor (tree t)
+{
+ tree fns;
+
+ if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+ return false;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (!DECL_ARTIFICIAL (fn)
+ && (TREE_CODE (fn) == TEMPLATE_DECL
+ || (skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn))
+ != NULL_TREE)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Returns the defaulted constructor if T has one. Otherwise, returns
+ NULL_TREE. */
+
+tree
+in_class_defaulted_default_constructor (tree t)
+{
+ tree fns, args;
+
+ if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+ return NULL_TREE;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ if (DECL_DEFAULTED_IN_CLASS_P (fn))
+ {
+ args = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ while (args && TREE_PURPOSE (args))
+ args = TREE_CHAIN (args);
+ if (!args || args == void_list_node)
+ return fn;
+ }
+ }
+
+ return NULL_TREE;
+}
+
+/* Returns true iff FN is a user-provided function, i.e. user-declared
+ and not defaulted at its first declaration; or explicit, private,
+ protected, or non-const. */
+
+bool
+user_provided_p (tree fn)
+{
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ return true;
+ else
+ return (!DECL_ARTIFICIAL (fn)
+ && !(DECL_INITIALIZED_IN_CLASS_P (fn)
+ && (DECL_DEFAULTED_FN (fn) || DECL_DELETED_FN (fn))));
+}
+
+/* Returns true iff class T has a user-provided constructor. */
+
+bool
+type_has_user_provided_constructor (tree t)
+{
+ tree fns;
+
+ if (!CLASS_TYPE_P (t))
+ return false;
+
+ if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+ return false;
+
+ /* This can happen in error cases; avoid crashing. */
+ if (!CLASSTYPE_METHOD_VEC (t))
+ return false;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ if (user_provided_p (OVL_CURRENT (fns)))
+ return true;
+
+ return false;
+}
+
+/* Returns true iff class T has a user-provided default constructor. */
+
+bool
+type_has_user_provided_default_constructor (tree t)
+{
+ tree fns;
+
+ if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+ return false;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (TREE_CODE (fn) == FUNCTION_DECL
+ && user_provided_p (fn)
+ && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)))
+ return true;
+ }
+
+ return false;
+}
+
+/* TYPE is being used as a virtual base, and has a non-trivial move
+ assignment. Return true if this is due to there being a user-provided
+ move assignment in TYPE or one of its subobjects; if there isn't, then
+ multiple move assignment can't cause any harm. */
+
+bool
+vbase_has_user_provided_move_assign (tree type)
+{
+ /* Does the type itself have a user-provided move assignment operator? */
+ for (tree fns
+ = lookup_fnfields_slot_nolazy (type, ansi_assopname (NOP_EXPR));
+ fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (move_fn_p (fn) && user_provided_p (fn))
+ return true;
+ }
+
+ /* Do any of its bases? */
+ tree binfo = TYPE_BINFO (type);
+ tree base_binfo;
+ for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ if (vbase_has_user_provided_move_assign (BINFO_TYPE (base_binfo)))
+ return true;
+
+ /* Or non-static data members? */
+ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL
+ && CLASS_TYPE_P (TREE_TYPE (field))
+ && vbase_has_user_provided_move_assign (TREE_TYPE (field)))
+ return true;
+ }
+
+ /* Seems not. */
+ return false;
+}
+
+/* If default-initialization leaves part of TYPE uninitialized, returns
+ a DECL for the field or TYPE itself (DR 253). */
+
+tree
+default_init_uninitialized_part (tree type)
+{
+ tree t, r, binfo;
+ int i;
+
+ type = strip_array_types (type);
+ if (!CLASS_TYPE_P (type))
+ return type;
+ if (type_has_user_provided_default_constructor (type))
+ return NULL_TREE;
+ for (binfo = TYPE_BINFO (type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, t); ++i)
+ {
+ r = default_init_uninitialized_part (BINFO_TYPE (t));
+ if (r)
+ return r;
+ }
+ for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
+ if (TREE_CODE (t) == FIELD_DECL
+ && !DECL_ARTIFICIAL (t)
+ && !DECL_INITIAL (t))
+ {
+ r = default_init_uninitialized_part (TREE_TYPE (t));
+ if (r)
+ return DECL_P (r) ? r : t;
+ }
+
+ return NULL_TREE;
+}
+
+/* Returns true iff for class T, a trivial synthesized default constructor
+ would be constexpr. */
+
+bool
+trivial_default_constructor_is_constexpr (tree t)
+{
+ /* A defaulted trivial default constructor is constexpr
+ if there is nothing to initialize. */
+ gcc_assert (!TYPE_HAS_COMPLEX_DFLT (t));
+ return is_really_empty_class (t);
+}
+
+/* Returns true iff class T has a constexpr default constructor. */
+
+bool
+type_has_constexpr_default_constructor (tree t)
+{
+ tree fns;
+
+ if (!CLASS_TYPE_P (t))
+ {
+ /* The caller should have stripped an enclosing array. */
+ gcc_assert (TREE_CODE (t) != ARRAY_TYPE);
+ return false;
+ }
+ if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
+ {
+ if (!TYPE_HAS_COMPLEX_DFLT (t))
+ return trivial_default_constructor_is_constexpr (t);
+ /* Non-trivial, we need to check subobject constructors. */
+ lazily_declare_fn (sfk_constructor, t);
+ }
+ fns = locate_ctor (t);
+ return (fns && DECL_DECLARED_CONSTEXPR_P (fns));
+}
+
+/* Returns true iff class TYPE has a virtual destructor. */
+
+bool
+type_has_virtual_destructor (tree type)
+{
+ tree dtor;
+
+ if (!CLASS_TYPE_P (type))
+ return false;
+
+ gcc_assert (COMPLETE_TYPE_P (type));
+ dtor = CLASSTYPE_DESTRUCTORS (type);
+ return (dtor && DECL_VIRTUAL_P (dtor));
+}
+
+/* Returns true iff class T has a move constructor. */
+
+bool
+type_has_move_constructor (tree t)
+{
+ tree fns;
+
+ if (CLASSTYPE_LAZY_MOVE_CTOR (t))
+ {
+ gcc_assert (COMPLETE_TYPE_P (t));
+ lazily_declare_fn (sfk_move_constructor, t);
+ }
+
+ if (!CLASSTYPE_METHOD_VEC (t))
+ return false;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ if (move_fn_p (OVL_CURRENT (fns)))
+ return true;
+
+ return false;
+}
+
+/* Returns true iff class T has a move assignment operator. */
+
+bool
+type_has_move_assign (tree t)
+{
+ tree fns;
+
+ if (CLASSTYPE_LAZY_MOVE_ASSIGN (t))
+ {
+ gcc_assert (COMPLETE_TYPE_P (t));
+ lazily_declare_fn (sfk_move_assignment, t);
+ }
+
+ for (fns = lookup_fnfields_slot_nolazy (t, ansi_assopname (NOP_EXPR));
+ fns; fns = OVL_NEXT (fns))
+ if (move_fn_p (OVL_CURRENT (fns)))
+ return true;
+
+ return false;
+}
+
+/* Returns true iff class T has a move constructor that was explicitly
+ declared in the class body. Note that this is different from
+ "user-provided", which doesn't include functions that are defaulted in
+ the class. */
+
+bool
+type_has_user_declared_move_constructor (tree t)
+{
+ tree fns;
+
+ if (CLASSTYPE_LAZY_MOVE_CTOR (t))
+ return false;
+
+ if (!CLASSTYPE_METHOD_VEC (t))
+ return false;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (move_fn_p (fn) && !DECL_ARTIFICIAL (fn))
+ return true;
+ }
+
+ return false;
+}
+
+/* Returns true iff class T has a move assignment operator that was
+ explicitly declared in the class body. */
+
+bool
+type_has_user_declared_move_assign (tree t)
+{
+ tree fns;
+
+ if (CLASSTYPE_LAZY_MOVE_ASSIGN (t))
+ return false;
+
+ for (fns = lookup_fnfields_slot_nolazy (t, ansi_assopname (NOP_EXPR));
+ fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (move_fn_p (fn) && !DECL_ARTIFICIAL (fn))
+ return true;
+ }
+
+ return false;
+}
+
+/* Nonzero if we need to build up a constructor call when initializing an
+ object of this class, either because it has a user-declared constructor
+ or because it doesn't have a default constructor (so we need to give an
+ error if no initializer is provided). Use TYPE_NEEDS_CONSTRUCTING when
+ what you care about is whether or not an object can be produced by a
+ constructor (e.g. so we don't set TREE_READONLY on const variables of
+ such type); use this function when what you care about is whether or not
+ to try to call a constructor to create an object. The latter case is
+ the former plus some cases of constructors that cannot be called. */
+
+bool
+type_build_ctor_call (tree t)
+{
+ tree inner;
+ if (TYPE_NEEDS_CONSTRUCTING (t))
+ return true;
+ inner = strip_array_types (t);
+ if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner))
+ return false;
+ if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (inner))
+ return true;
+ if (cxx_dialect < cxx11)
+ return false;
+ /* A user-declared constructor might be private, and a constructor might
+ be trivial but deleted. */
+ for (tree fns = lookup_fnfields_slot (inner, complete_ctor_identifier);
+ fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (!DECL_ARTIFICIAL (fn)
+ || DECL_DELETED_FN (fn))
+ return true;
+ }
+ return false;
+}
+
+/* Like type_build_ctor_call, but for destructors. */
+
+bool
+type_build_dtor_call (tree t)
+{
+ tree inner;
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
+ return true;
+ inner = strip_array_types (t);
+ if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner)
+ || !COMPLETE_TYPE_P (inner))
+ return false;
+ if (cxx_dialect < cxx11)
+ return false;
+ /* A user-declared destructor might be private, and a destructor might
+ be trivial but deleted. */
+ for (tree fns = lookup_fnfields_slot (inner, complete_dtor_identifier);
+ fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (!DECL_ARTIFICIAL (fn)
+ || DECL_DELETED_FN (fn))
+ return true;
+ }
+ return false;
+}
+
+/* Remove all zero-width bit-fields from T. */
+
+static void
+remove_zero_width_bit_fields (tree t)
+{
+ tree *fieldsp;
+
+ fieldsp = &TYPE_FIELDS (t);
+ while (*fieldsp)
+ {
+ if (TREE_CODE (*fieldsp) == FIELD_DECL
+ && DECL_C_BIT_FIELD (*fieldsp)
+ /* We should not be confused by the fact that grokbitfield
+ temporarily sets the width of the bit field into
+ DECL_INITIAL (*fieldsp).
+ check_bitfield_decl eventually sets DECL_SIZE (*fieldsp)
+ to that width. */
+ && integer_zerop (DECL_SIZE (*fieldsp)))
+ *fieldsp = DECL_CHAIN (*fieldsp);
+ else
+ fieldsp = &DECL_CHAIN (*fieldsp);
+ }
+}
+
+/* Returns TRUE iff we need a cookie when dynamically allocating an
+ array whose elements have the indicated class TYPE. */
+
+static bool
+type_requires_array_cookie (tree type)
+{
+ tree fns;
+ bool has_two_argument_delete_p = false;
+
+ gcc_assert (CLASS_TYPE_P (type));
+
+ /* If there's a non-trivial destructor, we need a cookie. In order
+ to iterate through the array calling the destructor for each
+ element, we'll have to know how many elements there are. */
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ return true;
+
+ /* If the usual deallocation function is a two-argument whose second
+ argument is of type `size_t', then we have to pass the size of
+ the array to the deallocation function, so we will need to store
+ a cookie. */
+ fns = lookup_fnfields (TYPE_BINFO (type),
+ ansi_opname (VEC_DELETE_EXPR),
+ /*protect=*/0);
+ /* If there are no `operator []' members, or the lookup is
+ ambiguous, then we don't need a cookie. */
+ if (!fns || fns == error_mark_node)
+ return false;
+ /* Loop through all of the functions. */
+ for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
+ {
+ tree fn;
+ tree second_parm;
+
+ /* Select the current function. */
+ fn = OVL_CURRENT (fns);
+ /* See if this function is a one-argument delete function. If
+ it is, then it will be the usual deallocation function. */
+ second_parm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
+ if (second_parm == void_list_node)
+ return false;
+ /* Do not consider this function if its second argument is an
+ ellipsis. */
+ if (!second_parm)
+ continue;
+ /* Otherwise, if we have a two-argument function and the second
+ argument is `size_t', it will be the usual deallocation
+ function -- unless there is one-argument function, too. */
+ if (TREE_CHAIN (second_parm) == void_list_node
+ && same_type_p (TREE_VALUE (second_parm), size_type_node))
+ has_two_argument_delete_p = true;
+ }
+
+ return has_two_argument_delete_p;
+}
+
+/* Finish computing the `literal type' property of class type T.
+
+ At this point, we have already processed base classes and
+ non-static data members. We need to check whether the copy
+ constructor is trivial, the destructor is trivial, and there
+ is a trivial default constructor or at least one constexpr
+ constructor other than the copy constructor. */
+
+static void
+finalize_literal_type_property (tree t)
+{
+ tree fn;
+
+ if (cxx_dialect < cxx11
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
+ CLASSTYPE_LITERAL_P (t) = false;
+ else if (CLASSTYPE_LITERAL_P (t) && !TYPE_HAS_TRIVIAL_DFLT (t)
+ && CLASSTYPE_NON_AGGREGATE (t)
+ && !TYPE_HAS_CONSTEXPR_CTOR (t))
+ CLASSTYPE_LITERAL_P (t) = false;
+
+ if (!CLASSTYPE_LITERAL_P (t))
+ for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
+ if (DECL_DECLARED_CONSTEXPR_P (fn)
+ && TREE_CODE (fn) != TEMPLATE_DECL
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !DECL_CONSTRUCTOR_P (fn))
+ {
+ DECL_DECLARED_CONSTEXPR_P (fn) = false;
+ if (!DECL_GENERATED_P (fn))
+ {
+ error ("enclosing class of constexpr non-static member "
+ "function %q+#D is not a literal type", fn);
+ explain_non_literal_class (t);
+ }
+ }
+}
+
+/* T is a non-literal type used in a context which requires a constant
+ expression. Explain why it isn't literal. */
+
+void
+explain_non_literal_class (tree t)
+{
+ static struct pointer_set_t *diagnosed;
+
+ if (!CLASS_TYPE_P (t))
+ return;
+ t = TYPE_MAIN_VARIANT (t);
+
+ if (diagnosed == NULL)
+ diagnosed = pointer_set_create ();
+ if (pointer_set_insert (diagnosed, t) != 0)
+ /* Already explained. */
+ return;
+
+ inform (0, "%q+T is not literal because:", t);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
+ inform (0, " %q+T has a non-trivial destructor", t);
+ else if (CLASSTYPE_NON_AGGREGATE (t)
+ && !TYPE_HAS_TRIVIAL_DFLT (t)
+ && !TYPE_HAS_CONSTEXPR_CTOR (t))
+ {
+ inform (0, " %q+T is not an aggregate, does not have a trivial "
+ "default constructor, and has no constexpr constructor that "
+ "is not a copy or move constructor", t);
+ if (TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
+ && !type_has_user_provided_default_constructor (t))
+ {
+ /* Note that we can't simply call locate_ctor because when the
+ constructor is deleted it just returns NULL_TREE. */
+ tree fns;
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
+
+ parms = skip_artificial_parms_for (fn, parms);
+
+ if (sufficient_parms_p (parms))
+ {
+ if (DECL_DELETED_FN (fn))
+ maybe_explain_implicit_delete (fn);
+ else
+ explain_invalid_constexpr_fn (fn);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ tree binfo, base_binfo, field; int i;
+ for (binfo = TYPE_BINFO (t), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ {
+ tree basetype = TREE_TYPE (base_binfo);
+ if (!CLASSTYPE_LITERAL_P (basetype))
+ {
+ inform (0, " base class %qT of %q+T is non-literal",
+ basetype, t);
+ explain_non_literal_class (basetype);
+ return;
+ }
+ }
+ for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+ {
+ tree ftype;
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+ ftype = TREE_TYPE (field);
+ if (!literal_type_p (ftype))
+ {
+ inform (0, " non-static data member %q+D has "
+ "non-literal type", field);
+ if (CLASS_TYPE_P (ftype))
+ explain_non_literal_class (ftype);
+ }
+ }
+ }
+}
+
+/* Check the validity of the bases and members declared in T. Add any
+ implicitly-generated functions (like copy-constructors and
+ assignment operators). Compute various flag bits (like
+ CLASSTYPE_NON_LAYOUT_POD_T) for T. This routine works purely at the C++
+ level: i.e., independently of the ABI in use. */
+
+static void
+check_bases_and_members (tree t)
+{
+ /* Nonzero if the implicitly generated copy constructor should take
+ a non-const reference argument. */
+ int cant_have_const_ctor;
+ /* Nonzero if the implicitly generated assignment operator
+ should take a non-const reference argument. */
+ int no_const_asn_ref;
+ tree access_decls;
+ bool saved_complex_asn_ref;
+ bool saved_nontrivial_dtor;
+ tree fn;
+
+ /* Pick up any abi_tags from our template arguments before checking. */
+ inherit_targ_abi_tags (t);
+
+ /* By default, we use const reference arguments and generate default
+ constructors. */
+ cant_have_const_ctor = 0;
+ no_const_asn_ref = 0;
+
+ /* Check all the base-classes. */
+ check_bases (t, &cant_have_const_ctor,
+ &no_const_asn_ref);
+
+ /* Deduce noexcept on destructors. This needs to happen after we've set
+ triviality flags appropriately for our bases. */
+ if (cxx_dialect >= cxx11)
+ deduce_noexcept_on_destructors (t);
+
+ /* Check all the method declarations. */
+ check_methods (t);
+
+ /* Save the initial values of these flags which only indicate whether
+ or not the class has user-provided functions. As we analyze the
+ bases and members we can set these flags for other reasons. */
+ saved_complex_asn_ref = TYPE_HAS_COMPLEX_COPY_ASSIGN (t);
+ saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
+
+ /* Check all the data member declarations. We cannot call
+ check_field_decls until we have called check_bases check_methods,
+ as check_field_decls depends on TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+ being set appropriately. */
+ check_field_decls (t, &access_decls,
+ &cant_have_const_ctor,
+ &no_const_asn_ref);
+
+ /* A nearly-empty class has to be vptr-containing; a nearly empty
+ class contains just a vptr. */
+ if (!TYPE_CONTAINS_VPTR_P (t))
+ CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+
+ /* Do some bookkeeping that will guide the generation of implicitly
+ declared member functions. */
+ TYPE_HAS_COMPLEX_COPY_CTOR (t) |= TYPE_CONTAINS_VPTR_P (t);
+ TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_CONTAINS_VPTR_P (t);
+ /* We need to call a constructor for this class if it has a
+ user-provided constructor, or if the default constructor is going
+ to initialize the vptr. (This is not an if-and-only-if;
+ TYPE_NEEDS_CONSTRUCTING is set elsewhere if bases or members
+ themselves need constructing.) */
+ TYPE_NEEDS_CONSTRUCTING (t)
+ |= (type_has_user_provided_constructor (t) || TYPE_CONTAINS_VPTR_P (t));
+ /* [dcl.init.aggr]
+
+ An aggregate is an array or a class with no user-provided
+ constructors ... and no virtual functions.
+
+ Again, other conditions for being an aggregate are checked
+ elsewhere. */
+ CLASSTYPE_NON_AGGREGATE (t)
+ |= (type_has_user_provided_constructor (t) || TYPE_POLYMORPHIC_P (t));
+ /* This is the C++98/03 definition of POD; it changed in C++0x, but we
+ retain the old definition internally for ABI reasons. */
+ CLASSTYPE_NON_LAYOUT_POD_P (t)
+ |= (CLASSTYPE_NON_AGGREGATE (t)
+ || saved_nontrivial_dtor || saved_complex_asn_ref);
+ CLASSTYPE_NON_STD_LAYOUT (t) |= TYPE_CONTAINS_VPTR_P (t);
+ TYPE_HAS_COMPLEX_COPY_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
+ TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
+ TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t);
+
+ /* If the class has no user-declared constructor, but does have
+ non-static const or reference data members that can never be
+ initialized, issue a warning. */
+ if (warn_uninitialized
+ /* Classes with user-declared constructors are presumed to
+ initialize these members. */
+ && !TYPE_HAS_USER_CONSTRUCTOR (t)
+ /* Aggregates can be initialized with brace-enclosed
+ initializers. */
+ && CLASSTYPE_NON_AGGREGATE (t))
+ {
+ tree field;
+
+ for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
+ {
+ tree type;
+
+ if (TREE_CODE (field) != FIELD_DECL
+ || DECL_INITIAL (field) != NULL_TREE)
+ continue;
+
+ type = TREE_TYPE (field);
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ warning (OPT_Wuninitialized, "non-static reference %q+#D "
+ "in class without a constructor", field);
+ else if (CP_TYPE_CONST_P (type)
+ && (!CLASS_TYPE_P (type)
+ || !TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
+ warning (OPT_Wuninitialized, "non-static const member %q+#D "
+ "in class without a constructor", field);
+ }
+ }
+
+ /* Synthesize any needed methods. */
+ add_implicitly_declared_members (t, &access_decls,
+ cant_have_const_ctor,
+ no_const_asn_ref);
+
+ /* Check defaulted declarations here so we have cant_have_const_ctor
+ and don't need to worry about clones. */
+ for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
+ if (!DECL_ARTIFICIAL (fn) && DECL_DEFAULTED_IN_CLASS_P (fn))
+ {
+ int copy = copy_fn_p (fn);
+ if (copy > 0)
+ {
+ bool imp_const_p
+ = (DECL_CONSTRUCTOR_P (fn) ? !cant_have_const_ctor
+ : !no_const_asn_ref);
+ bool fn_const_p = (copy == 2);
+
+ if (fn_const_p && !imp_const_p)
+ /* If the function is defaulted outside the class, we just
+ give the synthesis error. */
+ error ("%q+D declared to take const reference, but implicit "
+ "declaration would take non-const", fn);
+ }
+ defaulted_late_check (fn);
+ }
+
+ if (LAMBDA_TYPE_P (t))
+ {
+ /* "The closure type associated with a lambda-expression has a deleted
+ default constructor and a deleted copy assignment operator." */
+ TYPE_NEEDS_CONSTRUCTING (t) = 1;
+ TYPE_HAS_COMPLEX_DFLT (t) = 1;
+ TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
+ CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 0;
+
+ /* "This class type is not an aggregate." */
+ CLASSTYPE_NON_AGGREGATE (t) = 1;
+ }
+
+ /* Compute the 'literal type' property before we
+ do anything with non-static member functions. */
+ finalize_literal_type_property (t);
+
+ /* Create the in-charge and not-in-charge variants of constructors
+ and destructors. */
+ clone_constructors_and_destructors (t);
+
+ /* Process the using-declarations. */
+ for (; access_decls; access_decls = TREE_CHAIN (access_decls))
+ handle_using_decl (TREE_VALUE (access_decls), t);
+
+ /* Build and sort the CLASSTYPE_METHOD_VEC. */
+ finish_struct_methods (t);
+
+ /* Figure out whether or not we will need a cookie when dynamically
+ allocating an array of this type. */
+ TYPE_LANG_SPECIFIC (t)->u.c.vec_new_uses_cookie
+ = type_requires_array_cookie (t);
+}
+
+/* If T needs a pointer to its virtual function table, set TYPE_VFIELD
+ accordingly. If a new vfield was created (because T doesn't have a
+ primary base class), then the newly created field is returned. It
+ is not added to the TYPE_FIELDS list; it is the caller's
+ responsibility to do that. Accumulate declared virtual functions
+ on VIRTUALS_P. */
+
+static tree
+create_vtable_ptr (tree t, tree* virtuals_p)
+{
+ tree fn;
+
+ /* Collect the virtual functions declared in T. */
+ for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
+ if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
+ && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
+ {
+ tree new_virtual = make_node (TREE_LIST);
+
+ BV_FN (new_virtual) = fn;
+ BV_DELTA (new_virtual) = integer_zero_node;
+ BV_VCALL_INDEX (new_virtual) = NULL_TREE;
+
+ TREE_CHAIN (new_virtual) = *virtuals_p;
+ *virtuals_p = new_virtual;
+ }
+
+ /* If we couldn't find an appropriate base class, create a new field
+ here. Even if there weren't any new virtual functions, we might need a
+ new virtual function table if we're supposed to include vptrs in
+ all classes that need them. */
+ if (!TYPE_VFIELD (t) && (*virtuals_p || TYPE_CONTAINS_VPTR_P (t)))
+ {
+ /* We build this decl with vtbl_ptr_type_node, which is a
+ `vtable_entry_type*'. It might seem more precise to use
+ `vtable_entry_type (*)[N]' where N is the number of virtual
+ functions. However, that would require the vtable pointer in
+ base classes to have a different type than the vtable pointer
+ in derived classes. We could make that happen, but that
+ still wouldn't solve all the problems. In particular, the
+ type-based alias analysis code would decide that assignments
+ to the base class vtable pointer can't alias assignments to
+ the derived class vtable pointer, since they have different
+ types. Thus, in a derived class destructor, where the base
+ class constructor was inlined, we could generate bad code for
+ setting up the vtable pointer.
+
+ Therefore, we use one type for all vtable pointers. We still
+ use a type-correct type; it's just doesn't indicate the array
+ bounds. That's better than using `void*' or some such; it's
+ cleaner, and it let's the alias analysis code know that these
+ stores cannot alias stores to void*! */
+ tree field;
+
+ field = build_decl (input_location,
+ FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node);
+ DECL_VIRTUAL_P (field) = 1;
+ DECL_ARTIFICIAL (field) = 1;
+ DECL_FIELD_CONTEXT (field) = t;
+ DECL_FCONTEXT (field) = t;
+ if (TYPE_PACKED (t))
+ DECL_PACKED (field) = 1;
+
+ TYPE_VFIELD (t) = field;
+
+ /* This class is non-empty. */
+ CLASSTYPE_EMPTY_P (t) = 0;
+
+ return field;
+ }
+
+ return NULL_TREE;
+}
+
+/* Add OFFSET to all base types of BINFO which is a base in the
+ hierarchy dominated by T.
+
+ OFFSET, which is a type offset, is number of bytes. */
+
+static void
+propagate_binfo_offsets (tree binfo, tree offset)
+{
+ int i;
+ tree primary_binfo;
+ tree base_binfo;
+
+ /* Update BINFO's offset. */
+ BINFO_OFFSET (binfo)
+ = convert (sizetype,
+ size_binop (PLUS_EXPR,
+ convert (ssizetype, BINFO_OFFSET (binfo)),
+ offset));
+
+ /* Find the primary base class. */
+ primary_binfo = get_primary_binfo (binfo);
+
+ if (primary_binfo && BINFO_INHERITANCE_CHAIN (primary_binfo) == binfo)
+ propagate_binfo_offsets (primary_binfo, offset);
+
+ /* Scan all of the bases, pushing the BINFO_OFFSET adjust
+ downwards. */
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ {
+ /* Don't do the primary base twice. */
+ if (base_binfo == primary_binfo)
+ continue;
+
+ if (BINFO_VIRTUAL_P (base_binfo))
+ continue;
+
+ propagate_binfo_offsets (base_binfo, offset);
+ }
+}
+
+/* Set BINFO_OFFSET for all of the virtual bases for RLI->T. Update
+ TYPE_ALIGN and TYPE_SIZE for T. OFFSETS gives the location of
+ empty subobjects of T. */
+
+static void
+layout_virtual_bases (record_layout_info rli, splay_tree offsets)
+{
+ tree vbase;
+ tree t = rli->t;
+ bool first_vbase = true;
+ tree *next_field;
+
+ if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) == 0)
+ return;
+
+ if (!abi_version_at_least(2))
+ {
+ /* In G++ 3.2, we incorrectly rounded the size before laying out
+ the virtual bases. */
+ finish_record_layout (rli, /*free_p=*/false);
+#ifdef STRUCTURE_SIZE_BOUNDARY
+ /* Packed structures don't need to have minimum size. */
+ if (! TYPE_PACKED (t))
+ TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), (unsigned) STRUCTURE_SIZE_BOUNDARY);
+#endif
+ rli->offset = TYPE_SIZE_UNIT (t);
+ rli->bitpos = bitsize_zero_node;
+ rli->record_align = TYPE_ALIGN (t);
+ }
+
+ /* Find the last field. The artificial fields created for virtual
+ bases will go after the last extant field to date. */
+ next_field = &TYPE_FIELDS (t);
+ while (*next_field)
+ next_field = &DECL_CHAIN (*next_field);
+
+ /* Go through the virtual bases, allocating space for each virtual
+ base that is not already a primary base class. These are
+ allocated in inheritance graph order. */
+ for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
+ {
+ if (!BINFO_VIRTUAL_P (vbase))
+ continue;
+
+ if (!BINFO_PRIMARY_P (vbase))
+ {
+ tree basetype = TREE_TYPE (vbase);
+
+ /* This virtual base is not a primary base of any class in the
+ hierarchy, so we have to add space for it. */
+ next_field = build_base_field (rli, vbase,
+ offsets, next_field);
+
+ /* If the first virtual base might have been placed at a
+ lower address, had we started from CLASSTYPE_SIZE, rather
+ than TYPE_SIZE, issue a warning. There can be both false
+ positives and false negatives from this warning in rare
+ cases; to deal with all the possibilities would probably
+ require performing both layout algorithms and comparing
+ the results which is not particularly tractable. */
+ if (warn_abi
+ && first_vbase
+ && (tree_int_cst_lt
+ (size_binop (CEIL_DIV_EXPR,
+ round_up_loc (input_location,
+ CLASSTYPE_SIZE (t),
+ CLASSTYPE_ALIGN (basetype)),
+ bitsize_unit_node),
+ BINFO_OFFSET (vbase))))
+ warning (OPT_Wabi,
+ "offset of virtual base %qT is not ABI-compliant and "
+ "may change in a future version of GCC",
+ basetype);
+
+ first_vbase = false;
+ }
+ }
+}
+
+/* Returns the offset of the byte just past the end of the base class
+ BINFO. */
+
+static tree
+end_of_base (tree binfo)
+{
+ tree size;
+
+ if (!CLASSTYPE_AS_BASE (BINFO_TYPE (binfo)))
+ size = TYPE_SIZE_UNIT (char_type_node);
+ else if (is_empty_class (BINFO_TYPE (binfo)))
+ /* An empty class has zero CLASSTYPE_SIZE_UNIT, but we need to
+ allocate some space for it. It cannot have virtual bases, so
+ TYPE_SIZE_UNIT is fine. */
+ size = TYPE_SIZE_UNIT (BINFO_TYPE (binfo));
+ else
+ size = CLASSTYPE_SIZE_UNIT (BINFO_TYPE (binfo));
+
+ return size_binop (PLUS_EXPR, BINFO_OFFSET (binfo), size);
+}
+
+/* Returns the offset of the byte just past the end of the base class
+ with the highest offset in T. If INCLUDE_VIRTUALS_P is zero, then
+ only non-virtual bases are included. */
+
+static tree
+end_of_class (tree t, int include_virtuals_p)
+{
+ tree result = size_zero_node;
+ vec<tree, va_gc> *vbases;
+ tree binfo;
+ tree base_binfo;
+ tree offset;
+ int i;
+
+ for (binfo = TYPE_BINFO (t), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ {
+ if (!include_virtuals_p
+ && BINFO_VIRTUAL_P (base_binfo)
+ && (!BINFO_PRIMARY_P (base_binfo)
+ || BINFO_INHERITANCE_CHAIN (base_binfo) != TYPE_BINFO (t)))
+ continue;
+
+ offset = end_of_base (base_binfo);
+ if (INT_CST_LT_UNSIGNED (result, offset))
+ result = offset;
+ }
+
+ /* G++ 3.2 did not check indirect virtual bases. */
+ if (abi_version_at_least (2) && include_virtuals_p)
+ for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
+ vec_safe_iterate (vbases, i, &base_binfo); i++)
+ {
+ offset = end_of_base (base_binfo);
+ if (INT_CST_LT_UNSIGNED (result, offset))
+ result = offset;
+ }
+
+ return result;
+}
+
+/* Warn about bases of T that are inaccessible because they are
+ ambiguous. For example:
+
+ struct S {};
+ struct T : public S {};
+ struct U : public S, public T {};
+
+ Here, `(S*) new U' is not allowed because there are two `S'
+ subobjects of U. */
+
+static void
+warn_about_ambiguous_bases (tree t)
+{
+ int i;
+ vec<tree, va_gc> *vbases;
+ tree basetype;
+ tree binfo;
+ tree base_binfo;
+
+ /* If there are no repeated bases, nothing can be ambiguous. */
+ if (!CLASSTYPE_REPEATED_BASE_P (t))
+ return;
+
+ /* Check direct bases. */
+ for (binfo = TYPE_BINFO (t), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ {
+ basetype = BINFO_TYPE (base_binfo);
+
+ if (!uniquely_derived_from_p (basetype, t))
+ warning (0, "direct base %qT inaccessible in %qT due to ambiguity",
+ basetype, t);
+ }
+
+ /* Check for ambiguous virtual bases. */
+ if (extra_warnings)
+ for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
+ vec_safe_iterate (vbases, i, &binfo); i++)
+ {
+ basetype = BINFO_TYPE (binfo);
+
+ if (!uniquely_derived_from_p (basetype, t))
+ warning (OPT_Wextra, "virtual base %qT inaccessible in %qT due "
+ "to ambiguity", basetype, t);
+ }
+}
+
+/* Compare two INTEGER_CSTs K1 and K2. */
+
+static int
+splay_tree_compare_integer_csts (splay_tree_key k1, splay_tree_key k2)
+{
+ return tree_int_cst_compare ((tree) k1, (tree) k2);
+}
+
+/* Increase the size indicated in RLI to account for empty classes
+ that are "off the end" of the class. */
+
+static void
+include_empty_classes (record_layout_info rli)
+{
+ tree eoc;
+ tree rli_size;
+
+ /* It might be the case that we grew the class to allocate a
+ zero-sized base class. That won't be reflected in RLI, yet,
+ because we are willing to overlay multiple bases at the same
+ offset. However, now we need to make sure that RLI is big enough
+ to reflect the entire class. */
+ eoc = end_of_class (rli->t,
+ CLASSTYPE_AS_BASE (rli->t) != NULL_TREE);
+ rli_size = rli_size_unit_so_far (rli);
+ if (TREE_CODE (rli_size) == INTEGER_CST
+ && INT_CST_LT_UNSIGNED (rli_size, eoc))
+ {
+ if (!abi_version_at_least (2))
+ /* In version 1 of the ABI, the size of a class that ends with
+ a bitfield was not rounded up to a whole multiple of a
+ byte. Because rli_size_unit_so_far returns only the number
+ of fully allocated bytes, any extra bits were not included
+ in the size. */
+ rli->bitpos = round_down (rli->bitpos, BITS_PER_UNIT);
+ else
+ /* The size should have been rounded to a whole byte. */
+ gcc_assert (tree_int_cst_equal
+ (rli->bitpos, round_down (rli->bitpos, BITS_PER_UNIT)));
+ rli->bitpos
+ = size_binop (PLUS_EXPR,
+ rli->bitpos,
+ size_binop (MULT_EXPR,
+ convert (bitsizetype,
+ size_binop (MINUS_EXPR,
+ eoc, rli_size)),
+ bitsize_int (BITS_PER_UNIT)));
+ normalize_rli (rli);
+ }
+}
+
+/* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T. Calculate
+ BINFO_OFFSETs for all of the base-classes. Position the vtable
+ pointer. Accumulate declared virtual functions on VIRTUALS_P. */
+
+static void
+layout_class_type (tree t, tree *virtuals_p)
+{
+ tree non_static_data_members;
+ tree field;
+ tree vptr;
+ record_layout_info rli;
+ /* Maps offsets (represented as INTEGER_CSTs) to a TREE_LIST of
+ types that appear at that offset. */
+ splay_tree empty_base_offsets;
+ /* True if the last field laid out was a bit-field. */
+ bool last_field_was_bitfield = false;
+ /* The location at which the next field should be inserted. */
+ tree *next_field;
+ /* T, as a base class. */
+ tree base_t;
+
+ /* Keep track of the first non-static data member. */
+ non_static_data_members = TYPE_FIELDS (t);
+
+ /* Start laying out the record. */
+ rli = start_record_layout (t);
+
+ /* Mark all the primary bases in the hierarchy. */
+ determine_primary_bases (t);
+
+ /* Create a pointer to our virtual function table. */
+ vptr = create_vtable_ptr (t, virtuals_p);
+
+ /* The vptr is always the first thing in the class. */
+ if (vptr)
+ {
+ DECL_CHAIN (vptr) = TYPE_FIELDS (t);
+ TYPE_FIELDS (t) = vptr;
+ next_field = &DECL_CHAIN (vptr);
+ place_field (rli, vptr);
+ }
+ else
+ next_field = &TYPE_FIELDS (t);
+
+ /* Build FIELD_DECLs for all of the non-virtual base-types. */
+ empty_base_offsets = splay_tree_new (splay_tree_compare_integer_csts,
+ NULL, NULL);
+ build_base_fields (rli, empty_base_offsets, next_field);
+
+ /* Layout the non-static data members. */
+ for (field = non_static_data_members; field; field = DECL_CHAIN (field))
+ {
+ tree type;
+ tree padding;
+
+ /* We still pass things that aren't non-static data members to
+ the back end, in case it wants to do something with them. */
+ if (TREE_CODE (field) != FIELD_DECL)
+ {
+ place_field (rli, field);
+ /* If the static data member has incomplete type, keep track
+ of it so that it can be completed later. (The handling
+ of pending statics in finish_record_layout is
+ insufficient; consider:
+
+ struct S1;
+ struct S2 { static S1 s1; };
+
+ At this point, finish_record_layout will be called, but
+ S1 is still incomplete.) */
+ if (VAR_P (field))
+ {
+ maybe_register_incomplete_var (field);
+ /* The visibility of static data members is determined
+ at their point of declaration, not their point of
+ definition. */
+ determine_visibility (field);
+ }
+ continue;
+ }
+
+ type = TREE_TYPE (field);
+ if (type == error_mark_node)
+ continue;
+
+ padding = NULL_TREE;
+
+ /* If this field is a bit-field whose width is greater than its
+ type, then there are some special rules for allocating
+ it. */
+ if (DECL_C_BIT_FIELD (field)
+ && INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
+ {
+ unsigned int itk;
+ tree integer_type;
+ bool was_unnamed_p = false;
+ /* We must allocate the bits as if suitably aligned for the
+ longest integer type that fits in this many bits. type
+ of the field. Then, we are supposed to use the left over
+ bits as additional padding. */
+ for (itk = itk_char; itk != itk_none; ++itk)
+ if (integer_types[itk] != NULL_TREE
+ && (INT_CST_LT (size_int (MAX_FIXED_MODE_SIZE),
+ TYPE_SIZE (integer_types[itk]))
+ || INT_CST_LT (DECL_SIZE (field),
+ TYPE_SIZE (integer_types[itk]))))
+ break;
+
+ /* ITK now indicates a type that is too large for the
+ field. We have to back up by one to find the largest
+ type that fits. */
+ do
+ {
+ --itk;
+ integer_type = integer_types[itk];
+ } while (itk > 0 && integer_type == NULL_TREE);
+
+ /* Figure out how much additional padding is required. GCC
+ 3.2 always created a padding field, even if it had zero
+ width. */
+ if (!abi_version_at_least (2)
+ || INT_CST_LT (TYPE_SIZE (integer_type), DECL_SIZE (field)))
+ {
+ if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
+ /* In a union, the padding field must have the full width
+ of the bit-field; all fields start at offset zero. */
+ padding = DECL_SIZE (field);
+ else
+ {
+ if (TREE_CODE (t) == UNION_TYPE)
+ warning (OPT_Wabi, "size assigned to %qT may not be "
+ "ABI-compliant and may change in a future "
+ "version of GCC",
+ t);
+ padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
+ TYPE_SIZE (integer_type));
+ }
+ }
+#ifdef PCC_BITFIELD_TYPE_MATTERS
+ /* An unnamed bitfield does not normally affect the
+ alignment of the containing class on a target where
+ PCC_BITFIELD_TYPE_MATTERS. But, the C++ ABI does not
+ make any exceptions for unnamed bitfields when the
+ bitfields are longer than their types. Therefore, we
+ temporarily give the field a name. */
+ if (PCC_BITFIELD_TYPE_MATTERS && !DECL_NAME (field))
+ {
+ was_unnamed_p = true;
+ DECL_NAME (field) = make_anon_name ();
+ }
+#endif
+ DECL_SIZE (field) = TYPE_SIZE (integer_type);
+ DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
+ DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
+ layout_nonempty_base_or_field (rli, field, NULL_TREE,
+ empty_base_offsets);
+ if (was_unnamed_p)
+ DECL_NAME (field) = NULL_TREE;
+ /* Now that layout has been performed, set the size of the
+ field to the size of its declared type; the rest of the
+ field is effectively invisible. */
+ DECL_SIZE (field) = TYPE_SIZE (type);
+ /* We must also reset the DECL_MODE of the field. */
+ if (abi_version_at_least (2))
+ DECL_MODE (field) = TYPE_MODE (type);
+ else if (warn_abi
+ && DECL_MODE (field) != TYPE_MODE (type))
+ /* Versions of G++ before G++ 3.4 did not reset the
+ DECL_MODE. */
+ warning (OPT_Wabi,
+ "the offset of %qD may not be ABI-compliant and may "
+ "change in a future version of GCC", field);
+ }
+ else
+ layout_nonempty_base_or_field (rli, field, NULL_TREE,
+ empty_base_offsets);
+
+ /* Remember the location of any empty classes in FIELD. */
+ if (abi_version_at_least (2))
+ record_subobject_offsets (TREE_TYPE (field),
+ byte_position(field),
+ empty_base_offsets,
+ /*is_data_member=*/true);
+
+ /* If a bit-field does not immediately follow another bit-field,
+ and yet it starts in the middle of a byte, we have failed to
+ comply with the ABI. */
+ if (warn_abi
+ && DECL_C_BIT_FIELD (field)
+ /* The TREE_NO_WARNING flag gets set by Objective-C when
+ laying out an Objective-C class. The ObjC ABI differs
+ from the C++ ABI, and so we do not want a warning
+ here. */
+ && !TREE_NO_WARNING (field)
+ && !last_field_was_bitfield
+ && !integer_zerop (size_binop (TRUNC_MOD_EXPR,
+ DECL_FIELD_BIT_OFFSET (field),
+ bitsize_unit_node)))
+ warning (OPT_Wabi, "offset of %q+D is not ABI-compliant and may "
+ "change in a future version of GCC", field);
+
+ /* G++ used to use DECL_FIELD_OFFSET as if it were the byte
+ offset of the field. */
+ if (warn_abi
+ && !abi_version_at_least (2)
+ && !tree_int_cst_equal (DECL_FIELD_OFFSET (field),
+ byte_position (field))
+ && contains_empty_class_p (TREE_TYPE (field)))
+ warning (OPT_Wabi, "%q+D contains empty classes which may cause base "
+ "classes to be placed at different locations in a "
+ "future version of GCC", field);
+
+ /* The middle end uses the type of expressions to determine the
+ possible range of expression values. In order to optimize
+ "x.i > 7" to "false" for a 2-bit bitfield "i", the middle end
+ must be made aware of the width of "i", via its type.
+
+ Because C++ does not have integer types of arbitrary width,
+ we must (for the purposes of the front end) convert from the
+ type assigned here to the declared type of the bitfield
+ whenever a bitfield expression is used as an rvalue.
+ Similarly, when assigning a value to a bitfield, the value
+ must be converted to the type given the bitfield here. */
+ if (DECL_C_BIT_FIELD (field))
+ {
+ unsigned HOST_WIDE_INT width;
+ tree ftype = TREE_TYPE (field);
+ width = tree_to_uhwi (DECL_SIZE (field));
+ if (width != TYPE_PRECISION (ftype))
+ {
+ TREE_TYPE (field)
+ = c_build_bitfield_integer_type (width,
+ TYPE_UNSIGNED (ftype));
+ TREE_TYPE (field)
+ = cp_build_qualified_type (TREE_TYPE (field),
+ cp_type_quals (ftype));
+ }
+ }
+
+ /* If we needed additional padding after this field, add it
+ now. */
+ if (padding)
+ {
+ tree padding_field;
+
+ padding_field = build_decl (input_location,
+ FIELD_DECL,
+ NULL_TREE,
+ char_type_node);
+ DECL_BIT_FIELD (padding_field) = 1;
+ DECL_SIZE (padding_field) = padding;
+ DECL_CONTEXT (padding_field) = t;
+ DECL_ARTIFICIAL (padding_field) = 1;
+ DECL_IGNORED_P (padding_field) = 1;
+ layout_nonempty_base_or_field (rli, padding_field,
+ NULL_TREE,
+ empty_base_offsets);
+ }
+
+ last_field_was_bitfield = DECL_C_BIT_FIELD (field);
+ }
+
+ if (abi_version_at_least (2) && !integer_zerop (rli->bitpos))
+ {
+ /* Make sure that we are on a byte boundary so that the size of
+ the class without virtual bases will always be a round number
+ of bytes. */
+ rli->bitpos = round_up_loc (input_location, rli->bitpos, BITS_PER_UNIT);
+ normalize_rli (rli);
+ }
+
+ /* G++ 3.2 does not allow virtual bases to be overlaid with tail
+ padding. */
+ if (!abi_version_at_least (2))
+ include_empty_classes(rli);
+
+ /* Delete all zero-width bit-fields from the list of fields. Now
+ that the type is laid out they are no longer important. */
+ remove_zero_width_bit_fields (t);
+
+ /* Create the version of T used for virtual bases. We do not use
+ make_class_type for this version; this is an artificial type. For
+ a POD type, we just reuse T. */
+ if (CLASSTYPE_NON_LAYOUT_POD_P (t) || CLASSTYPE_EMPTY_P (t))
+ {
+ base_t = make_node (TREE_CODE (t));
+
+ /* Set the size and alignment for the new type. In G++ 3.2, all
+ empty classes were considered to have size zero when used as
+ base classes. */
+ if (!abi_version_at_least (2) && CLASSTYPE_EMPTY_P (t))
+ {
+ TYPE_SIZE (base_t) = bitsize_zero_node;
+ TYPE_SIZE_UNIT (base_t) = size_zero_node;
+ if (warn_abi && !integer_zerop (rli_size_unit_so_far (rli)))
+ warning (OPT_Wabi,
+ "layout of classes derived from empty class %qT "
+ "may change in a future version of GCC",
+ t);
+ }
+ else
+ {
+ tree eoc;
+
+ /* If the ABI version is not at least two, and the last
+ field was a bit-field, RLI may not be on a byte
+ boundary. In particular, rli_size_unit_so_far might
+ indicate the last complete byte, while rli_size_so_far
+ indicates the total number of bits used. Therefore,
+ rli_size_so_far, rather than rli_size_unit_so_far, is
+ used to compute TYPE_SIZE_UNIT. */
+ eoc = end_of_class (t, /*include_virtuals_p=*/0);
+ TYPE_SIZE_UNIT (base_t)
+ = size_binop (MAX_EXPR,
+ convert (sizetype,
+ size_binop (CEIL_DIV_EXPR,
+ rli_size_so_far (rli),
+ bitsize_int (BITS_PER_UNIT))),
+ eoc);
+ TYPE_SIZE (base_t)
+ = size_binop (MAX_EXPR,
+ rli_size_so_far (rli),
+ size_binop (MULT_EXPR,
+ convert (bitsizetype, eoc),
+ bitsize_int (BITS_PER_UNIT)));
+ }
+ TYPE_ALIGN (base_t) = rli->record_align;
+ TYPE_USER_ALIGN (base_t) = TYPE_USER_ALIGN (t);
+
+ /* Copy the fields from T. */
+ next_field = &TYPE_FIELDS (base_t);
+ for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL)
+ {
+ *next_field = build_decl (input_location,
+ FIELD_DECL,
+ DECL_NAME (field),
+ TREE_TYPE (field));
+ DECL_CONTEXT (*next_field) = base_t;
+ DECL_FIELD_OFFSET (*next_field) = DECL_FIELD_OFFSET (field);
+ DECL_FIELD_BIT_OFFSET (*next_field)
+ = DECL_FIELD_BIT_OFFSET (field);
+ DECL_SIZE (*next_field) = DECL_SIZE (field);
+ DECL_MODE (*next_field) = DECL_MODE (field);
+ next_field = &DECL_CHAIN (*next_field);
+ }
+
+ /* Record the base version of the type. */
+ CLASSTYPE_AS_BASE (t) = base_t;
+ TYPE_CONTEXT (base_t) = t;
+ }
+ else
+ CLASSTYPE_AS_BASE (t) = t;
+
+ /* Every empty class contains an empty class. */
+ if (CLASSTYPE_EMPTY_P (t))
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
+
+ /* Set the TYPE_DECL for this type to contain the right
+ value for DECL_OFFSET, so that we can use it as part
+ of a COMPONENT_REF for multiple inheritance. */
+ layout_decl (TYPE_MAIN_DECL (t), 0);
+
+ /* Now fix up any virtual base class types that we left lying
+ around. We must get these done before we try to lay out the
+ virtual function table. As a side-effect, this will remove the
+ base subobject fields. */
+ layout_virtual_bases (rli, empty_base_offsets);
+
+ /* Make sure that empty classes are reflected in RLI at this
+ point. */
+ include_empty_classes(rli);
+
+ /* Make sure not to create any structures with zero size. */
+ if (integer_zerop (rli_size_unit_so_far (rli)) && CLASSTYPE_EMPTY_P (t))
+ place_field (rli,
+ build_decl (input_location,
+ FIELD_DECL, NULL_TREE, char_type_node));
+
+ /* If this is a non-POD, declaring it packed makes a difference to how it
+ can be used as a field; don't let finalize_record_size undo it. */
+ if (TYPE_PACKED (t) && !layout_pod_type_p (t))
+ rli->packed_maybe_necessary = true;
+
+ /* Let the back end lay out the type. */
+ finish_record_layout (rli, /*free_p=*/true);
+
+ if (TYPE_SIZE_UNIT (t)
+ && TREE_CODE (TYPE_SIZE_UNIT (t)) == INTEGER_CST
+ && !TREE_OVERFLOW (TYPE_SIZE_UNIT (t))
+ && !valid_constant_size_p (TYPE_SIZE_UNIT (t)))
+ error ("type %qT is too large", t);
+
+ /* Warn about bases that can't be talked about due to ambiguity. */
+ warn_about_ambiguous_bases (t);
+
+ /* Now that we're done with layout, give the base fields the real types. */
+ for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
+ if (DECL_ARTIFICIAL (field) && IS_FAKE_BASE_TYPE (TREE_TYPE (field)))
+ TREE_TYPE (field) = TYPE_CONTEXT (TREE_TYPE (field));
+
+ /* Clean up. */
+ splay_tree_delete (empty_base_offsets);
+
+ if (CLASSTYPE_EMPTY_P (t)
+ && tree_int_cst_lt (sizeof_biggest_empty_class,
+ TYPE_SIZE_UNIT (t)))
+ sizeof_biggest_empty_class = TYPE_SIZE_UNIT (t);
+}
+
+/* Determine the "key method" for the class type indicated by TYPE,
+ and set CLASSTYPE_KEY_METHOD accordingly. */
+
+void
+determine_key_method (tree type)
+{
+ tree method;
+
+ if (TYPE_FOR_JAVA (type)
+ || processing_template_decl
+ || CLASSTYPE_TEMPLATE_INSTANTIATION (type)
+ || CLASSTYPE_INTERFACE_KNOWN (type))
+ return;
+
+ /* The key method is the first non-pure virtual function that is not
+ inline at the point of class definition. On some targets the
+ key function may not be inline; those targets should not call
+ this function until the end of the translation unit. */
+ for (method = TYPE_METHODS (type); method != NULL_TREE;
+ method = DECL_CHAIN (method))
+ if (DECL_VINDEX (method) != NULL_TREE
+ && ! DECL_DECLARED_INLINE_P (method)
+ && ! DECL_PURE_VIRTUAL_P (method))
+ {
+ CLASSTYPE_KEY_METHOD (type) = method;
+ break;
+ }
+
+ return;
+}
+
+
+/* Allocate and return an instance of struct sorted_fields_type with
+ N fields. */
+
+static struct sorted_fields_type *
+sorted_fields_type_new (int n)
+{
+ struct sorted_fields_type *sft;
+ sft = ggc_alloc_sorted_fields_type (sizeof (struct sorted_fields_type)
+ + n * sizeof (tree));
+ sft->len = n;
+
+ return sft;
+}
+
+
+/* Perform processing required when the definition of T (a class type)
+ is complete. */
+
+void
+finish_struct_1 (tree t)
+{
+ tree x;
+ /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */
+ tree virtuals = NULL_TREE;
+
+ if (COMPLETE_TYPE_P (t))
+ {
+ gcc_assert (MAYBE_CLASS_TYPE_P (t));
+ error ("redefinition of %q#T", t);
+ popclass ();
+ return;
+ }
+
+ /* If this type was previously laid out as a forward reference,
+ make sure we lay it out again. */
+ TYPE_SIZE (t) = NULL_TREE;
+ CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
+
+ /* Make assumptions about the class; we'll reset the flags if
+ necessary. */
+ CLASSTYPE_EMPTY_P (t) = 1;
+ CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
+ CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
+ CLASSTYPE_LITERAL_P (t) = true;
+
+ /* Do end-of-class semantic processing: checking the validity of the
+ bases and members and add implicitly generated methods. */
+ check_bases_and_members (t);
+
+ /* Find the key method. */
+ if (TYPE_CONTAINS_VPTR_P (t))
+ {
+ /* The Itanium C++ ABI permits the key method to be chosen when
+ the class is defined -- even though the key method so
+ selected may later turn out to be an inline function. On
+ some systems (such as ARM Symbian OS) the key method cannot
+ be determined until the end of the translation unit. On such
+ systems, we leave CLASSTYPE_KEY_METHOD set to NULL, which
+ will cause the class to be added to KEYED_CLASSES. Then, in
+ finish_file we will determine the key method. */
+ if (targetm.cxx.key_method_may_be_inline ())
+ determine_key_method (t);
+
+ /* If a polymorphic class has no key method, we may emit the vtable
+ in every translation unit where the class definition appears. */
+ if (CLASSTYPE_KEY_METHOD (t) == NULL_TREE)
+ keyed_classes = tree_cons (NULL_TREE, t, keyed_classes);
+ }
+
+ /* Layout the class itself. */
+ layout_class_type (t, &virtuals);
+ if (CLASSTYPE_AS_BASE (t) != t)
+ /* We use the base type for trivial assignments, and hence it
+ needs a mode. */
+ compute_record_mode (CLASSTYPE_AS_BASE (t));
+
+ virtuals = modify_all_vtables (t, nreverse (virtuals));
+
+ /* If necessary, create the primary vtable for this class. */
+ if (virtuals || TYPE_CONTAINS_VPTR_P (t))
+ {
+ /* We must enter these virtuals into the table. */
+ if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
+ build_primary_vtable (NULL_TREE, t);
+ else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
+ /* Here we know enough to change the type of our virtual
+ function table, but we will wait until later this function. */
+ build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
+
+ /* If we're warning about ABI tags, check the types of the new
+ virtual functions. */
+ if (warn_abi_tag)
+ for (tree v = virtuals; v; v = TREE_CHAIN (v))
+ check_abi_tags (t, TREE_VALUE (v));
+ }
+
+ if (TYPE_CONTAINS_VPTR_P (t))
+ {
+ int vindex;
+ tree fn;
+
+ if (BINFO_VTABLE (TYPE_BINFO (t)))
+ gcc_assert (DECL_VIRTUAL_P (BINFO_VTABLE (TYPE_BINFO (t))));
+ if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
+ gcc_assert (BINFO_VIRTUALS (TYPE_BINFO (t)) == NULL_TREE);
+
+ /* Add entries for virtual functions introduced by this class. */
+ BINFO_VIRTUALS (TYPE_BINFO (t))
+ = chainon (BINFO_VIRTUALS (TYPE_BINFO (t)), virtuals);
+
+ /* Set DECL_VINDEX for all functions declared in this class. */
+ for (vindex = 0, fn = BINFO_VIRTUALS (TYPE_BINFO (t));
+ fn;
+ fn = TREE_CHAIN (fn),
+ vindex += (TARGET_VTABLE_USES_DESCRIPTORS
+ ? TARGET_VTABLE_USES_DESCRIPTORS : 1))
+ {
+ tree fndecl = BV_FN (fn);
+
+ if (DECL_THUNK_P (fndecl))
+ /* A thunk. We should never be calling this entry directly
+ from this vtable -- we'd use the entry for the non
+ thunk base function. */
+ DECL_VINDEX (fndecl) = NULL_TREE;
+ else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
+ DECL_VINDEX (fndecl) = build_int_cst (NULL_TREE, vindex);
+ }
+ }
+
+ finish_struct_bits (t);
+ set_method_tm_attributes (t);
+
+ /* Complete the rtl for any static member objects of the type we're
+ working on. */
+ for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
+ if (VAR_P (x) && TREE_STATIC (x)
+ && TREE_TYPE (x) != error_mark_node
+ && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))
+ DECL_MODE (x) = TYPE_MODE (t);
+
+ /* Done with FIELDS...now decide whether to sort these for
+ faster lookups later.
+
+ We use a small number because most searches fail (succeeding
+ ultimately as the search bores through the inheritance
+ hierarchy), and we want this failure to occur quickly. */
+
+ insert_into_classtype_sorted_fields (TYPE_FIELDS (t), t, 8);
+
+ /* Complain if one of the field types requires lower visibility. */
+ constrain_class_visibility (t);
+
+ /* Make the rtl for any new vtables we have created, and unmark
+ the base types we marked. */
+ finish_vtbls (t);
+
+ /* Build the VTT for T. */
+ build_vtt (t);
+
+ /* This warning does not make sense for Java classes, since they
+ cannot have destructors. */
+ if (!TYPE_FOR_JAVA (t) && warn_nonvdtor && TYPE_POLYMORPHIC_P (t))
+ {
+ tree dtor;
+
+ dtor = CLASSTYPE_DESTRUCTORS (t);
+ if (/* An implicitly declared destructor is always public. And,
+ if it were virtual, we would have created it by now. */
+ !dtor
+ || (!DECL_VINDEX (dtor)
+ && (/* public non-virtual */
+ (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor))
+ || (/* non-public non-virtual with friends */
+ (TREE_PRIVATE (dtor) || TREE_PROTECTED (dtor))
+ && (CLASSTYPE_FRIEND_CLASSES (t)
+ || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))))))
+ warning (OPT_Wnon_virtual_dtor,
+ "%q#T has virtual functions and accessible"
+ " non-virtual destructor", t);
+ }
+
+ complete_vars (t);
+
+ if (warn_overloaded_virtual)
+ warn_hidden (t);
+
+ /* Class layout, assignment of virtual table slots, etc., is now
+ complete. Give the back end a chance to tweak the visibility of
+ the class or perform any other required target modifications. */
+ targetm.cxx.adjust_class_at_definition (t);
+
+ maybe_suppress_debug_info (t);
+
+ if (flag_vtable_verify)
+ vtv_save_class_info (t);
+
+ dump_class_hierarchy (t);
+
+ /* Finish debugging output for this type. */
+ rest_of_type_compilation (t, ! LOCAL_CLASS_P (t));
+
+ if (TYPE_TRANSPARENT_AGGR (t))
+ {
+ tree field = first_field (t);
+ if (field == NULL_TREE || error_operand_p (field))
+ {
+ error ("type transparent %q#T does not have any fields", t);
+ TYPE_TRANSPARENT_AGGR (t) = 0;
+ }
+ else if (DECL_ARTIFICIAL (field))
+ {
+ if (DECL_FIELD_IS_BASE (field))
+ error ("type transparent class %qT has base classes", t);
+ else
+ {
+ gcc_checking_assert (DECL_VIRTUAL_P (field));
+ error ("type transparent class %qT has virtual functions", t);
+ }
+ TYPE_TRANSPARENT_AGGR (t) = 0;
+ }
+ else if (TYPE_MODE (t) != DECL_MODE (field))
+ {
+ error ("type transparent %q#T cannot be made transparent because "
+ "the type of the first field has a different ABI from the "
+ "class overall", t);
+ TYPE_TRANSPARENT_AGGR (t) = 0;
+ }
+ }
+}
+
+/* Insert FIELDS into T for the sorted case if the FIELDS count is
+ equal to THRESHOLD or greater than THRESHOLD. */
+
+static void
+insert_into_classtype_sorted_fields (tree fields, tree t, int threshold)
+{
+ int n_fields = count_fields (fields);
+ if (n_fields >= threshold)
+ {
+ struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields);
+ add_fields_to_record_type (fields, field_vec, 0);
+ qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp);
+ CLASSTYPE_SORTED_FIELDS (t) = field_vec;
+ }
+}
+
+/* Insert lately defined enum ENUMTYPE into T for the sorted case. */
+
+void
+insert_late_enum_def_into_classtype_sorted_fields (tree enumtype, tree t)
+{
+ struct sorted_fields_type *sorted_fields = CLASSTYPE_SORTED_FIELDS (t);
+ if (sorted_fields)
+ {
+ int i;
+ int n_fields
+ = list_length (TYPE_VALUES (enumtype)) + sorted_fields->len;
+ struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields);
+
+ for (i = 0; i < sorted_fields->len; ++i)
+ field_vec->elts[i] = sorted_fields->elts[i];
+
+ add_enum_fields_to_record_type (enumtype, field_vec,
+ sorted_fields->len);
+ qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp);
+ CLASSTYPE_SORTED_FIELDS (t) = field_vec;
+ }
+}
+
+/* When T was built up, the member declarations were added in reverse
+ order. Rearrange them to declaration order. */
+
+void
+unreverse_member_declarations (tree t)
+{
+ tree next;
+ tree prev;
+ tree x;
+
+ /* The following lists are all in reverse order. Put them in
+ declaration order now. */
+ TYPE_METHODS (t) = nreverse (TYPE_METHODS (t));
+ CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t));
+
+ /* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in
+ reverse order, so we can't just use nreverse. */
+ prev = NULL_TREE;
+ for (x = TYPE_FIELDS (t);
+ x && TREE_CODE (x) != TYPE_DECL;
+ x = next)
+ {
+ next = DECL_CHAIN (x);
+ DECL_CHAIN (x) = prev;
+ prev = x;
+ }
+ if (prev)
+ {
+ DECL_CHAIN (TYPE_FIELDS (t)) = x;
+ if (prev)
+ TYPE_FIELDS (t) = prev;
+ }
+}
+
+tree
+finish_struct (tree t, tree attributes)
+{
+ location_t saved_loc = input_location;
+
+ /* Now that we've got all the field declarations, reverse everything
+ as necessary. */
+ unreverse_member_declarations (t);
+
+ cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
+
+ /* Nadger the current location so that diagnostics point to the start of
+ the struct, not the end. */
+ input_location = DECL_SOURCE_LOCATION (TYPE_NAME (t));
+
+ if (processing_template_decl)
+ {
+ tree x;
+
+ finish_struct_methods (t);
+ TYPE_SIZE (t) = bitsize_zero_node;
+ TYPE_SIZE_UNIT (t) = size_zero_node;
+
+ /* We need to emit an error message if this type was used as a parameter
+ and it is an abstract type, even if it is a template. We construct
+ a simple CLASSTYPE_PURE_VIRTUALS list without taking bases into
+ account and we call complete_vars with this type, which will check
+ the PARM_DECLS. Note that while the type is being defined,
+ CLASSTYPE_PURE_VIRTUALS contains the list of the inline friends
+ (see CLASSTYPE_INLINE_FRIENDS) so we need to clear it. */
+ CLASSTYPE_PURE_VIRTUALS (t) = NULL;
+ for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x))
+ if (DECL_PURE_VIRTUAL_P (x))
+ vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
+ complete_vars (t);
+ /* We need to add the target functions to the CLASSTYPE_METHOD_VEC if
+ an enclosing scope is a template class, so that this function be
+ found by lookup_fnfields_1 when the using declaration is not
+ instantiated yet. */
+ for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
+ if (TREE_CODE (x) == USING_DECL)
+ {
+ tree fn = strip_using_decl (x);
+ if (is_overloaded_fn (fn))
+ for (; fn; fn = OVL_NEXT (fn))
+ add_method (t, OVL_CURRENT (fn), x);
+ }
+
+ /* Remember current #pragma pack value. */
+ TYPE_PRECISION (t) = maximum_field_alignment;
+
+ /* Fix up any variants we've already built. */
+ for (x = TYPE_NEXT_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
+ {
+ TYPE_SIZE (x) = TYPE_SIZE (t);
+ TYPE_SIZE_UNIT (x) = TYPE_SIZE_UNIT (t);
+ TYPE_FIELDS (x) = TYPE_FIELDS (t);
+ TYPE_METHODS (x) = TYPE_METHODS (t);
+ }
+ }
+ else
+ finish_struct_1 (t);
+
+ input_location = saved_loc;
+
+ TYPE_BEING_DEFINED (t) = 0;
+
+ if (current_class_type)
+ popclass ();
+ else
+ error ("trying to finish struct, but kicked out due to previous parse errors");
+
+ if (processing_template_decl && at_function_scope_p ()
+ /* Lambdas are defined by the LAMBDA_EXPR. */
+ && !LAMBDA_TYPE_P (t))
+ add_stmt (build_min (TAG_DEFN, t));
+
+ return t;
+}
+
+/* Hash table to avoid endless recursion when handling references. */
+static hash_table <pointer_hash <tree_node> > fixed_type_or_null_ref_ht;
+
+/* Return the dynamic type of INSTANCE, if known.
+ Used to determine whether the virtual function table is needed
+ or not.
+
+ *NONNULL is set iff INSTANCE can be known to be nonnull, regardless
+ of our knowledge of its type. *NONNULL should be initialized
+ before this function is called. */
+
+static tree
+fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
+{
+#define RECUR(T) fixed_type_or_null((T), nonnull, cdtorp)
+
+ switch (TREE_CODE (instance))
+ {
+ case INDIRECT_REF:
+ if (POINTER_TYPE_P (TREE_TYPE (instance)))
+ return NULL_TREE;
+ else
+ return RECUR (TREE_OPERAND (instance, 0));
+
+ case CALL_EXPR:
+ /* This is a call to a constructor, hence it's never zero. */
+ if (TREE_HAS_CONSTRUCTOR (instance))
+ {
+ if (nonnull)
+ *nonnull = 1;
+ return TREE_TYPE (instance);
+ }
+ return NULL_TREE;
+
+ case SAVE_EXPR:
+ /* This is a call to a constructor, hence it's never zero. */
+ if (TREE_HAS_CONSTRUCTOR (instance))
+ {
+ if (nonnull)
+ *nonnull = 1;
+ return TREE_TYPE (instance);
+ }
+ return RECUR (TREE_OPERAND (instance, 0));
+
+ case POINTER_PLUS_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
+ return RECUR (TREE_OPERAND (instance, 0));
+ if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
+ /* Propagate nonnull. */
+ return RECUR (TREE_OPERAND (instance, 0));
+
+ return NULL_TREE;
+
+ CASE_CONVERT:
+ return RECUR (TREE_OPERAND (instance, 0));
+
+ case ADDR_EXPR:
+ instance = TREE_OPERAND (instance, 0);
+ if (nonnull)
+ {
+ /* Just because we see an ADDR_EXPR doesn't mean we're dealing
+ with a real object -- given &p->f, p can still be null. */
+ tree t = get_base_address (instance);
+ /* ??? Probably should check DECL_WEAK here. */
+ if (t && DECL_P (t))
+ *nonnull = 1;
+ }
+ return RECUR (instance);
+
+ case COMPONENT_REF:
+ /* If this component is really a base class reference, then the field
+ itself isn't definitive. */
+ if (DECL_FIELD_IS_BASE (TREE_OPERAND (instance, 1)))
+ return RECUR (TREE_OPERAND (instance, 0));
+ return RECUR (TREE_OPERAND (instance, 1));
+
+ case VAR_DECL:
+ case FIELD_DECL:
+ if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE
+ && MAYBE_CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (instance))))
+ {
+ if (nonnull)
+ *nonnull = 1;
+ return TREE_TYPE (TREE_TYPE (instance));
+ }
+ /* fall through... */
+ case TARGET_EXPR:
+ case PARM_DECL:
+ case RESULT_DECL:
+ if (MAYBE_CLASS_TYPE_P (TREE_TYPE (instance)))
+ {
+ if (nonnull)
+ *nonnull = 1;
+ return TREE_TYPE (instance);
+ }
+ else if (instance == current_class_ptr)
+ {
+ if (nonnull)
+ *nonnull = 1;
+
+ /* if we're in a ctor or dtor, we know our type. If
+ current_class_ptr is set but we aren't in a function, we're in
+ an NSDMI (and therefore a constructor). */
+ if (current_scope () != current_function_decl
+ || (DECL_LANG_SPECIFIC (current_function_decl)
+ && (DECL_CONSTRUCTOR_P (current_function_decl)
+ || DECL_DESTRUCTOR_P (current_function_decl))))
+ {
+ if (cdtorp)
+ *cdtorp = 1;
+ return TREE_TYPE (TREE_TYPE (instance));
+ }
+ }
+ else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
+ {
+ /* We only need one hash table because it is always left empty. */
+ if (!fixed_type_or_null_ref_ht.is_created ())
+ fixed_type_or_null_ref_ht.create (37);
+
+ /* Reference variables should be references to objects. */
+ if (nonnull)
+ *nonnull = 1;
+
+ /* Enter the INSTANCE in a table to prevent recursion; a
+ variable's initializer may refer to the variable
+ itself. */
+ if (VAR_P (instance)
+ && DECL_INITIAL (instance)
+ && !type_dependent_expression_p_push (DECL_INITIAL (instance))
+ && !fixed_type_or_null_ref_ht.find (instance))
+ {
+ tree type;
+ tree_node **slot;
+
+ slot = fixed_type_or_null_ref_ht.find_slot (instance, INSERT);
+ *slot = instance;
+ type = RECUR (DECL_INITIAL (instance));
+ fixed_type_or_null_ref_ht.remove_elt (instance);
+
+ return type;
+ }
+ }
+ return NULL_TREE;
+
+ default:
+ return NULL_TREE;
+ }
+#undef RECUR
+}
+
+/* Return nonzero if the dynamic type of INSTANCE is known, and
+ equivalent to the static type. We also handle the case where
+ INSTANCE is really a pointer. Return negative if this is a
+ ctor/dtor. There the dynamic type is known, but this might not be
+ the most derived base of the original object, and hence virtual
+ bases may not be laid out according to this type.
+
+ Used to determine whether the virtual function table is needed
+ or not.
+
+ *NONNULL is set iff INSTANCE can be known to be nonnull, regardless
+ of our knowledge of its type. *NONNULL should be initialized
+ before this function is called. */
+
+int
+resolves_to_fixed_type_p (tree instance, int* nonnull)
+{
+ tree t = TREE_TYPE (instance);
+ int cdtorp = 0;
+ tree fixed;
+
+ /* processing_template_decl can be false in a template if we're in
+ fold_non_dependent_expr, but we still want to suppress this check. */
+ if (in_template_function ())
+ {
+ /* In a template we only care about the type of the result. */
+ if (nonnull)
+ *nonnull = true;
+ return true;
+ }
+
+ fixed = fixed_type_or_null (instance, nonnull, &cdtorp);
+ if (fixed == NULL_TREE)
+ return 0;
+ if (POINTER_TYPE_P (t))
+ t = TREE_TYPE (t);
+ if (!same_type_ignoring_top_level_qualifiers_p (t, fixed))
+ return 0;
+ return cdtorp ? -1 : 1;
+}
+
+
+void
+init_class_processing (void)
+{
+ current_class_depth = 0;
+ current_class_stack_size = 10;
+ current_class_stack
+ = XNEWVEC (struct class_stack_node, current_class_stack_size);
+ vec_alloc (local_classes, 8);
+ sizeof_biggest_empty_class = size_zero_node;
+
+ ridpointers[(int) RID_PUBLIC] = access_public_node;
+ ridpointers[(int) RID_PRIVATE] = access_private_node;
+ ridpointers[(int) RID_PROTECTED] = access_protected_node;
+}
+
+/* Restore the cached PREVIOUS_CLASS_LEVEL. */
+
+static void
+restore_class_cache (void)
+{
+ tree type;
+
+ /* We are re-entering the same class we just left, so we don't
+ have to search the whole inheritance matrix to find all the
+ decls to bind again. Instead, we install the cached
+ class_shadowed list and walk through it binding names. */
+ push_binding_level (previous_class_level);
+ class_binding_level = previous_class_level;
+ /* Restore IDENTIFIER_TYPE_VALUE. */
+ for (type = class_binding_level->type_shadowed;
+ type;
+ type = TREE_CHAIN (type))
+ SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (type), TREE_TYPE (type));
+}
+
+/* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE as
+ appropriate for TYPE.
+
+ So that we may avoid calls to lookup_name, we cache the _TYPE
+ nodes of local TYPE_DECLs in the TREE_TYPE field of the name.
+
+ For multiple inheritance, we perform a two-pass depth-first search
+ of the type lattice. */
+
+void
+pushclass (tree type)
+{
+ class_stack_node_t csn;
+
+ type = TYPE_MAIN_VARIANT (type);
+
+ /* Make sure there is enough room for the new entry on the stack. */
+ if (current_class_depth + 1 >= current_class_stack_size)
+ {
+ current_class_stack_size *= 2;
+ current_class_stack
+ = XRESIZEVEC (struct class_stack_node, current_class_stack,
+ current_class_stack_size);
+ }
+
+ /* Insert a new entry on the class stack. */
+ csn = current_class_stack + current_class_depth;
+ csn->name = current_class_name;
+ csn->type = current_class_type;
+ csn->access = current_access_specifier;
+ csn->names_used = 0;
+ csn->hidden = 0;
+ current_class_depth++;
+
+ /* Now set up the new type. */
+ current_class_name = TYPE_NAME (type);
+ if (TREE_CODE (current_class_name) == TYPE_DECL)
+ current_class_name = DECL_NAME (current_class_name);
+ current_class_type = type;
+
+ /* By default, things in classes are private, while things in
+ structures or unions are public. */
+ current_access_specifier = (CLASSTYPE_DECLARED_CLASS (type)
+ ? access_private_node
+ : access_public_node);
+
+ if (previous_class_level
+ && type != previous_class_level->this_entity
+ && current_class_depth == 1)
+ {
+ /* Forcibly remove any old class remnants. */
+ invalidate_class_lookup_cache ();
+ }
+
+ if (!previous_class_level
+ || type != previous_class_level->this_entity
+ || current_class_depth > 1)
+ pushlevel_class ();
+ else
+ restore_class_cache ();
+}
+
+/* When we exit a toplevel class scope, we save its binding level so
+ that we can restore it quickly. Here, we've entered some other
+ class, so we must invalidate our cache. */
+
+void
+invalidate_class_lookup_cache (void)
+{
+ previous_class_level = NULL;
+}
+
+/* Get out of the current class scope. If we were in a class scope
+ previously, that is the one popped to. */
+
+void
+popclass (void)
+{
+ poplevel_class ();
+
+ current_class_depth--;
+ current_class_name = current_class_stack[current_class_depth].name;
+ current_class_type = current_class_stack[current_class_depth].type;
+ current_access_specifier = current_class_stack[current_class_depth].access;
+ if (current_class_stack[current_class_depth].names_used)
+ splay_tree_delete (current_class_stack[current_class_depth].names_used);
+}
+
+/* Mark the top of the class stack as hidden. */
+
+void
+push_class_stack (void)
+{
+ if (current_class_depth)
+ ++current_class_stack[current_class_depth - 1].hidden;
+}
+
+/* Mark the top of the class stack as un-hidden. */
+
+void
+pop_class_stack (void)
+{
+ if (current_class_depth)
+ --current_class_stack[current_class_depth - 1].hidden;
+}
+
+/* Returns 1 if the class type currently being defined is either T or
+ a nested type of T. */
+
+bool
+currently_open_class (tree t)
+{
+ int i;
+
+ if (!CLASS_TYPE_P (t))
+ return false;
+
+ t = TYPE_MAIN_VARIANT (t);
+
+ /* We start looking from 1 because entry 0 is from global scope,
+ and has no type. */
+ for (i = current_class_depth; i > 0; --i)
+ {
+ tree c;
+ if (i == current_class_depth)
+ c = current_class_type;
+ else
+ {
+ if (current_class_stack[i].hidden)
+ break;
+ c = current_class_stack[i].type;
+ }
+ if (!c)
+ continue;
+ if (same_type_p (c, t))
+ return true;
+ }
+ return false;
+}
+
+/* If either current_class_type or one of its enclosing classes are derived
+ from T, return the appropriate type. Used to determine how we found
+ something via unqualified lookup. */
+
+tree
+currently_open_derived_class (tree t)
+{
+ int i;
+
+ /* The bases of a dependent type are unknown. */
+ if (dependent_type_p (t))
+ return NULL_TREE;
+
+ if (!current_class_type)
+ return NULL_TREE;
+
+ if (DERIVED_FROM_P (t, current_class_type))
+ return current_class_type;
+
+ for (i = current_class_depth - 1; i > 0; --i)
+ {
+ if (current_class_stack[i].hidden)
+ break;
+ if (DERIVED_FROM_P (t, current_class_stack[i].type))
+ return current_class_stack[i].type;
+ }
+
+ return NULL_TREE;
+}
+
+/* Returns the innermost class type which is not a lambda closure type. */
+
+tree
+current_nonlambda_class_type (void)
+{
+ int i;
+
+ /* We start looking from 1 because entry 0 is from global scope,
+ and has no type. */
+ for (i = current_class_depth; i > 0; --i)
+ {
+ tree c;
+ if (i == current_class_depth)
+ c = current_class_type;
+ else
+ {
+ if (current_class_stack[i].hidden)
+ break;
+ c = current_class_stack[i].type;
+ }
+ if (!c)
+ continue;
+ if (!LAMBDA_TYPE_P (c))
+ return c;
+ }
+ return NULL_TREE;
+}
+
+/* When entering a class scope, all enclosing class scopes' names with
+ static meaning (static variables, static functions, types and
+ enumerators) have to be visible. This recursive function calls
+ pushclass for all enclosing class contexts until global or a local
+ scope is reached. TYPE is the enclosed class. */
+
+void
+push_nested_class (tree type)
+{
+ /* A namespace might be passed in error cases, like A::B:C. */
+ if (type == NULL_TREE
+ || !CLASS_TYPE_P (type))
+ return;
+
+ push_nested_class (DECL_CONTEXT (TYPE_MAIN_DECL (type)));
+
+ pushclass (type);
+}
+
+/* Undoes a push_nested_class call. */
+
+void
+pop_nested_class (void)
+{
+ tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));
+
+ popclass ();
+ if (context && CLASS_TYPE_P (context))
+ pop_nested_class ();
+}
+
+/* Returns the number of extern "LANG" blocks we are nested within. */
+
+int
+current_lang_depth (void)
+{
+ return vec_safe_length (current_lang_base);
+}
+
+/* Set global variables CURRENT_LANG_NAME to appropriate value
+ so that behavior of name-mangling machinery is correct. */
+
+void
+push_lang_context (tree name)
+{
+ vec_safe_push (current_lang_base, current_lang_name);
+
+ if (name == lang_name_cplusplus)
+ {
+ current_lang_name = name;
+ }
+ else if (name == lang_name_java)
+ {
+ current_lang_name = name;
+ /* DECL_IGNORED_P is initially set for these types, to avoid clutter.
+ (See record_builtin_java_type in decl.c.) However, that causes
+ incorrect debug entries if these types are actually used.
+ So we re-enable debug output after extern "Java". */
+ DECL_IGNORED_P (TYPE_NAME (java_byte_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_short_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_int_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_long_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_float_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_double_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_char_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_boolean_type_node)) = 0;
+ }
+ else if (name == lang_name_c)
+ {
+ current_lang_name = name;
+ }
+ else
+ error ("language string %<\"%E\"%> not recognized", name);
+}
+
+/* Get out of the current language scope. */
+
+void
+pop_lang_context (void)
+{
+ current_lang_name = current_lang_base->pop ();
+}
+
+/* Type instantiation routines. */
+
+/* Given an OVERLOAD and a TARGET_TYPE, return the function that
+ matches the TARGET_TYPE. If there is no satisfactory match, return
+ error_mark_node, and issue an error & warning messages under
+ control of FLAGS. Permit pointers to member function if FLAGS
+ permits. If TEMPLATE_ONLY, the name of the overloaded function was
+ a template-id, and EXPLICIT_TARGS are the explicitly provided
+ template arguments.
+
+ If OVERLOAD is for one or more member functions, then ACCESS_PATH
+ is the base path used to reference those member functions. If
+ the address is resolved to a member function, access checks will be
+ performed and errors issued if appropriate. */
+
+static tree
+resolve_address_of_overloaded_function (tree target_type,
+ tree overload,
+ tsubst_flags_t flags,
+ bool template_only,
+ tree explicit_targs,
+ tree access_path)
+{
+ /* Here's what the standard says:
+
+ [over.over]
+
+ If the name is a function template, template argument deduction
+ is done, and if the argument deduction succeeds, the deduced
+ arguments are used to generate a single template function, which
+ is added to the set of overloaded functions considered.
+
+ Non-member functions and static member functions match targets of
+ type "pointer-to-function" or "reference-to-function." Nonstatic
+ member functions match targets of type "pointer-to-member
+ function;" the function type of the pointer to member is used to
+ select the member function from the set of overloaded member
+ functions. If a nonstatic member function is selected, the
+ reference to the overloaded function name is required to have the
+ form of a pointer to member as described in 5.3.1.
+
+ If more than one function is selected, any template functions in
+ the set are eliminated if the set also contains a non-template
+ function, and any given template function is eliminated if the
+ set contains a second template function that is more specialized
+ than the first according to the partial ordering rules 14.5.5.2.
+ After such eliminations, if any, there shall remain exactly one
+ selected function. */
+
+ int is_ptrmem = 0;
+ /* We store the matches in a TREE_LIST rooted here. The functions
+ are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
+ interoperability with most_specialized_instantiation. */
+ tree matches = NULL_TREE;
+ tree fn;
+ tree target_fn_type;
+
+ /* By the time we get here, we should be seeing only real
+ pointer-to-member types, not the internal POINTER_TYPE to
+ METHOD_TYPE representation. */
+ gcc_assert (!TYPE_PTR_P (target_type)
+ || TREE_CODE (TREE_TYPE (target_type)) != METHOD_TYPE);
+
+ gcc_assert (is_overloaded_fn (overload));
+
+ /* Check that the TARGET_TYPE is reasonable. */
+ if (TYPE_PTRFN_P (target_type)
+ || TYPE_REFFN_P (target_type))
+ /* This is OK. */;
+ else if (TYPE_PTRMEMFUNC_P (target_type))
+ /* This is OK, too. */
+ is_ptrmem = 1;
+ else if (TREE_CODE (target_type) == FUNCTION_TYPE)
+ /* This is OK, too. This comes from a conversion to reference
+ type. */
+ target_type = build_reference_type (target_type);
+ else
+ {
+ if (flags & tf_error)
+ error ("cannot resolve overloaded function %qD based on"
+ " conversion to type %qT",
+ DECL_NAME (OVL_FUNCTION (overload)), target_type);
+ return error_mark_node;
+ }
+
+ /* Non-member functions and static member functions match targets of type
+ "pointer-to-function" or "reference-to-function." Nonstatic member
+ functions match targets of type "pointer-to-member-function;" the
+ function type of the pointer to member is used to select the member
+ function from the set of overloaded member functions.
+
+ So figure out the FUNCTION_TYPE that we want to match against. */
+ target_fn_type = static_fn_type (target_type);
+
+ /* If we can find a non-template function that matches, we can just
+ use it. There's no point in generating template instantiations
+ if we're just going to throw them out anyhow. But, of course, we
+ can only do this when we don't *need* a template function. */
+ if (!template_only)
+ {
+ tree fns;
+
+ for (fns = overload; fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ /* We're not looking for templates just yet. */
+ continue;
+
+ if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+ != is_ptrmem)
+ /* We're looking for a non-static member, and this isn't
+ one, or vice versa. */
+ continue;
+
+ /* Ignore functions which haven't been explicitly
+ declared. */
+ if (DECL_ANTICIPATED (fn))
+ continue;
+
+ /* See if there's a match. */
+ if (same_type_p (target_fn_type, static_fn_type (fn)))
+ matches = tree_cons (fn, NULL_TREE, matches);
+ }
+ }
+
+ /* Now, if we've already got a match (or matches), there's no need
+ to proceed to the template functions. But, if we don't have a
+ match we need to look at them, too. */
+ if (!matches)
+ {
+ tree target_arg_types;
+ tree target_ret_type;
+ tree fns;
+ tree *args;
+ unsigned int nargs, ia;
+ tree arg;
+
+ target_arg_types = TYPE_ARG_TYPES (target_fn_type);
+ target_ret_type = TREE_TYPE (target_fn_type);
+
+ nargs = list_length (target_arg_types);
+ args = XALLOCAVEC (tree, nargs);
+ for (arg = target_arg_types, ia = 0;
+ arg != NULL_TREE && arg != void_list_node;
+ arg = TREE_CHAIN (arg), ++ia)
+ args[ia] = TREE_VALUE (arg);
+ nargs = ia;
+
+ for (fns = overload; fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ tree instantiation;
+ tree targs;
+
+ if (TREE_CODE (fn) != TEMPLATE_DECL)
+ /* We're only looking for templates. */
+ continue;
+
+ if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+ != is_ptrmem)
+ /* We're not looking for a non-static member, and this is
+ one, or vice versa. */
+ continue;
+
+ tree ret = target_ret_type;
+
+ /* If the template has a deduced return type, don't expose it to
+ template argument deduction. */
+ if (undeduced_auto_decl (fn))
+ ret = NULL_TREE;
+
+ /* Try to do argument deduction. */
+ targs = make_tree_vec (DECL_NTPARMS (fn));
+ instantiation = fn_type_unification (fn, explicit_targs, targs, args,
+ nargs, ret,
+ DEDUCE_EXACT, LOOKUP_NORMAL,
+ false, false);
+ if (instantiation == error_mark_node)
+ /* Instantiation failed. */
+ continue;
+
+ /* And now force instantiation to do return type deduction. */
+ if (undeduced_auto_decl (instantiation))
+ {
+ ++function_depth;
+ instantiate_decl (instantiation, /*defer*/false, /*class*/false);
+ --function_depth;
+
+ require_deduced_type (instantiation);
+ }
+
+ /* See if there's a match. */
+ if (same_type_p (target_fn_type, static_fn_type (instantiation)))
+ matches = tree_cons (instantiation, fn, matches);
+ }
+
+ /* Now, remove all but the most specialized of the matches. */
+ if (matches)
+ {
+ tree match = most_specialized_instantiation (matches);
+
+ if (match != error_mark_node)
+ matches = tree_cons (TREE_PURPOSE (match),
+ NULL_TREE,
+ NULL_TREE);
+ }
+ }
+
+ /* Now we should have exactly one function in MATCHES. */
+ if (matches == NULL_TREE)
+ {
+ /* There were *no* matches. */
+ if (flags & tf_error)
+ {
+ error ("no matches converting function %qD to type %q#T",
+ DECL_NAME (OVL_CURRENT (overload)),
+ target_type);
+
+ print_candidates (overload);
+ }
+ return error_mark_node;
+ }
+ else if (TREE_CHAIN (matches))
+ {
+ /* There were too many matches. First check if they're all
+ the same function. */
+ tree match = NULL_TREE;
+
+ fn = TREE_PURPOSE (matches);
+
+ /* For multi-versioned functions, more than one match is just fine and
+ decls_match will return false as they are different. */
+ for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
+ if (!decls_match (fn, TREE_PURPOSE (match))
+ && !targetm.target_option.function_versions
+ (fn, TREE_PURPOSE (match)))
+ break;
+
+ if (match)
+ {
+ if (flags & tf_error)
+ {
+ error ("converting overloaded function %qD to type %q#T is ambiguous",
+ DECL_NAME (OVL_FUNCTION (overload)),
+ target_type);
+
+ /* Since print_candidates expects the functions in the
+ TREE_VALUE slot, we flip them here. */
+ for (match = matches; match; match = TREE_CHAIN (match))
+ TREE_VALUE (match) = TREE_PURPOSE (match);
+
+ print_candidates (matches);
+ }
+
+ return error_mark_node;
+ }
+ }
+
+ /* Good, exactly one match. Now, convert it to the correct type. */
+ fn = TREE_PURPOSE (matches);
+
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !(flags & tf_ptrmem_ok) && !flag_ms_extensions)
+ {
+ static int explained;
+
+ if (!(flags & tf_error))
+ return error_mark_node;
+
+ permerror (input_location, "assuming pointer to member %qD", fn);
+ if (!explained)
+ {
+ inform (input_location, "(a pointer to member can only be formed with %<&%E%>)", fn);
+ explained = 1;
+ }
+ }
+
+ /* If a pointer to a function that is multi-versioned is requested, the
+ pointer to the dispatcher function is returned instead. This works
+ well because indirectly calling the function will dispatch the right
+ function version at run-time. */
+ if (DECL_FUNCTION_VERSIONED (fn))
+ {
+ fn = get_function_version_dispatcher (fn);
+ if (fn == NULL)
+ return error_mark_node;
+ /* Mark all the versions corresponding to the dispatcher as used. */
+ if (!(flags & tf_conv))
+ mark_versions_used (fn);
+ }
+
+ /* If we're doing overload resolution purely for the purpose of
+ determining conversion sequences, we should not consider the
+ function used. If this conversion sequence is selected, the
+ function will be marked as used at this point. */
+ if (!(flags & tf_conv))
+ {
+ /* Make =delete work with SFINAE. */
+ if (DECL_DELETED_FN (fn) && !(flags & tf_error))
+ return error_mark_node;
+
+ mark_used (fn);
+ }
+
+ /* We could not check access to member functions when this
+ expression was originally created since we did not know at that
+ time to which function the expression referred. */
+ if (DECL_FUNCTION_MEMBER_P (fn))
+ {
+ gcc_assert (access_path);
+ perform_or_defer_access_check (access_path, fn, fn, flags);
+ }
+
+ if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
+ return cp_build_addr_expr (fn, flags);
+ else
+ {
+ /* The target must be a REFERENCE_TYPE. Above, cp_build_unary_op
+ will mark the function as addressed, but here we must do it
+ explicitly. */
+ cxx_mark_addressable (fn);
+
+ return fn;
+ }
+}
+
+/* This function will instantiate the type of the expression given in
+ RHS to match the type of LHSTYPE. If errors exist, then return
+ error_mark_node. FLAGS is a bit mask. If TF_ERROR is set, then
+ we complain on errors. If we are not complaining, never modify rhs,
+ as overload resolution wants to try many possible instantiations, in
+ the hope that at least one will work.
+
+ For non-recursive calls, LHSTYPE should be a function, pointer to
+ function, or a pointer to member function. */
+
+tree
+instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
+{
+ tsubst_flags_t flags_in = flags;
+ tree access_path = NULL_TREE;
+
+ flags &= ~tf_ptrmem_ok;
+
+ if (lhstype == unknown_type_node)
+ {
+ if (flags & tf_error)
+ error ("not enough type information");
+ return error_mark_node;
+ }
+
+ if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
+ {
+ tree fntype = non_reference (lhstype);
+ if (same_type_p (fntype, TREE_TYPE (rhs)))
+ return rhs;
+ if (flag_ms_extensions
+ && TYPE_PTRMEMFUNC_P (fntype)
+ && !TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))
+ /* Microsoft allows `A::f' to be resolved to a
+ pointer-to-member. */
+ ;
+ else
+ {
+ if (flags & tf_error)
+ error ("cannot convert %qE from type %qT to type %qT",
+ rhs, TREE_TYPE (rhs), fntype);
+ return error_mark_node;
+ }
+ }
+
+ if (BASELINK_P (rhs))
+ {
+ access_path = BASELINK_ACCESS_BINFO (rhs);
+ rhs = BASELINK_FUNCTIONS (rhs);
+ }
+
+ /* If we are in a template, and have a NON_DEPENDENT_EXPR, we cannot
+ deduce any type information. */
+ if (TREE_CODE (rhs) == NON_DEPENDENT_EXPR)
+ {
+ if (flags & tf_error)
+ error ("not enough type information");
+ return error_mark_node;
+ }
+
+ /* There only a few kinds of expressions that may have a type
+ dependent on overload resolution. */
+ gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
+ || TREE_CODE (rhs) == COMPONENT_REF
+ || is_overloaded_fn (rhs)
+ || (flag_ms_extensions && TREE_CODE (rhs) == FUNCTION_DECL));
+
+ /* This should really only be used when attempting to distinguish
+ what sort of a pointer to function we have. For now, any
+ arithmetic operation which is not supported on pointers
+ is rejected as an error. */
+
+ switch (TREE_CODE (rhs))
+ {
+ case COMPONENT_REF:
+ {
+ tree member = TREE_OPERAND (rhs, 1);
+
+ member = instantiate_type (lhstype, member, flags);
+ if (member != error_mark_node
+ && TREE_SIDE_EFFECTS (TREE_OPERAND (rhs, 0)))
+ /* Do not lose object's side effects. */
+ return build2 (COMPOUND_EXPR, TREE_TYPE (member),
+ TREE_OPERAND (rhs, 0), member);
+ return member;
+ }
+
+ case OFFSET_REF:
+ rhs = TREE_OPERAND (rhs, 1);
+ if (BASELINK_P (rhs))
+ return instantiate_type (lhstype, rhs, flags_in);
+
+ /* This can happen if we are forming a pointer-to-member for a
+ member template. */
+ gcc_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR);
+
+ /* Fall through. */
+
+ case TEMPLATE_ID_EXPR:
+ {
+ tree fns = TREE_OPERAND (rhs, 0);
+ tree args = TREE_OPERAND (rhs, 1);
+
+ return
+ resolve_address_of_overloaded_function (lhstype, fns, flags_in,
+ /*template_only=*/true,
+ args, access_path);
+ }
+
+ case OVERLOAD:
+ case FUNCTION_DECL:
+ return
+ resolve_address_of_overloaded_function (lhstype, rhs, flags_in,
+ /*template_only=*/false,
+ /*explicit_targs=*/NULL_TREE,
+ access_path);
+
+ case ADDR_EXPR:
+ {
+ if (PTRMEM_OK_P (rhs))
+ flags |= tf_ptrmem_ok;
+
+ return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
+ }
+
+ case ERROR_MARK:
+ return error_mark_node;
+
+ default:
+ gcc_unreachable ();
+ }
+ return error_mark_node;
+}
+
+/* Return the name of the virtual function pointer field
+ (as an IDENTIFIER_NODE) for the given TYPE. Note that
+ this may have to look back through base types to find the
+ ultimate field name. (For single inheritance, these could
+ all be the same name. Who knows for multiple inheritance). */
+
+static tree
+get_vfield_name (tree type)
+{
+ tree binfo, base_binfo;
+ char *buf;
+
+ for (binfo = TYPE_BINFO (type);
+ BINFO_N_BASE_BINFOS (binfo);
+ binfo = base_binfo)
+ {
+ base_binfo = BINFO_BASE_BINFO (binfo, 0);
+
+ if (BINFO_VIRTUAL_P (base_binfo)
+ || !TYPE_CONTAINS_VPTR_P (BINFO_TYPE (base_binfo)))
+ break;
+ }
+
+ type = BINFO_TYPE (binfo);
+ buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
+ + TYPE_NAME_LENGTH (type) + 2);
+ sprintf (buf, VFIELD_NAME_FORMAT,
+ IDENTIFIER_POINTER (constructor_name (type)));
+ return get_identifier (buf);
+}
+
+void
+print_class_statistics (void)
+{
+ if (! GATHER_STATISTICS)
+ return;
+
+ fprintf (stderr, "convert_harshness = %d\n", n_convert_harshness);
+ fprintf (stderr, "compute_conversion_costs = %d\n", n_compute_conversion_costs);
+ if (n_vtables)
+ {
+ fprintf (stderr, "vtables = %d; vtable searches = %d\n",
+ n_vtables, n_vtable_searches);
+ fprintf (stderr, "vtable entries = %d; vtable elems = %d\n",
+ n_vtable_entries, n_vtable_elems);
+ }
+}
+
+/* Build a dummy reference to ourselves so Derived::Base (and A::A) works,
+ according to [class]:
+ The class-name is also inserted
+ into the scope of the class itself. For purposes of access checking,
+ the inserted class name is treated as if it were a public member name. */
+
+void
+build_self_reference (void)
+{
+ tree name = constructor_name (current_class_type);
+ tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
+ tree saved_cas;
+
+ DECL_NONLOCAL (value) = 1;
+ DECL_CONTEXT (value) = current_class_type;
+ DECL_ARTIFICIAL (value) = 1;
+ SET_DECL_SELF_REFERENCE_P (value);
+ set_underlying_type (value);
+
+ if (processing_template_decl)
+ value = push_template_decl (value);
+
+ saved_cas = current_access_specifier;
+ current_access_specifier = access_public_node;
+ finish_member_declaration (value);
+ current_access_specifier = saved_cas;
+}
+
+/* Returns 1 if TYPE contains only padding bytes. */
+
+int
+is_empty_class (tree type)
+{
+ if (type == error_mark_node)
+ return 0;
+
+ if (! CLASS_TYPE_P (type))
+ return 0;
+
+ /* In G++ 3.2, whether or not a class was empty was determined by
+ looking at its size. */
+ if (abi_version_at_least (2))
+ return CLASSTYPE_EMPTY_P (type);
+ else
+ return integer_zerop (CLASSTYPE_SIZE (type));
+}
+
+/* Returns true if TYPE contains an empty class. */
+
+static bool
+contains_empty_class_p (tree type)
+{
+ if (is_empty_class (type))
+ return true;
+ if (CLASS_TYPE_P (type))
+ {
+ tree field;
+ tree binfo;
+ tree base_binfo;
+ int i;
+
+ for (binfo = TYPE_BINFO (type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ if (contains_empty_class_p (BINFO_TYPE (base_binfo)))
+ return true;
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL
+ && !DECL_ARTIFICIAL (field)
+ && is_empty_class (TREE_TYPE (field)))
+ return true;
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ return contains_empty_class_p (TREE_TYPE (type));
+ return false;
+}
+
+/* Returns true if TYPE contains no actual data, just various
+ possible combinations of empty classes and possibly a vptr. */
+
+bool
+is_really_empty_class (tree type)
+{
+ if (CLASS_TYPE_P (type))
+ {
+ tree field;
+ tree binfo;
+ tree base_binfo;
+ int i;
+
+ /* CLASSTYPE_EMPTY_P isn't set properly until the class is actually laid
+ out, but we'd like to be able to check this before then. */
+ if (COMPLETE_TYPE_P (type) && is_empty_class (type))
+ return true;
+
+ for (binfo = TYPE_BINFO (type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ if (!is_really_empty_class (BINFO_TYPE (base_binfo)))
+ return false;
+ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL
+ && !DECL_ARTIFICIAL (field)
+ && !is_really_empty_class (TREE_TYPE (field)))
+ return false;
+ return true;
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ return is_really_empty_class (TREE_TYPE (type));
+ return false;
+}
+
+/* Note that NAME was looked up while the current class was being
+ defined and that the result of that lookup was DECL. */
+
+void
+maybe_note_name_used_in_class (tree name, tree decl)
+{
+ splay_tree names_used;
+
+ /* If we're not defining a class, there's nothing to do. */
+ if (!(innermost_scope_kind() == sk_class
+ && TYPE_BEING_DEFINED (current_class_type)
+ && !LAMBDA_TYPE_P (current_class_type)))
+ return;
+
+ /* If there's already a binding for this NAME, then we don't have
+ anything to worry about. */
+ if (lookup_member (current_class_type, name,
+ /*protect=*/0, /*want_type=*/false, tf_warning_or_error))
+ return;
+
+ if (!current_class_stack[current_class_depth - 1].names_used)
+ current_class_stack[current_class_depth - 1].names_used
+ = splay_tree_new (splay_tree_compare_pointers, 0, 0);
+ names_used = current_class_stack[current_class_depth - 1].names_used;
+
+ splay_tree_insert (names_used,
+ (splay_tree_key) name,
+ (splay_tree_value) decl);
+}
+
+/* Note that NAME was declared (as DECL) in the current class. Check
+ to see that the declaration is valid. */
+
+void
+note_name_declared_in_class (tree name, tree decl)
+{
+ splay_tree names_used;
+ splay_tree_node n;
+
+ /* Look to see if we ever used this name. */
+ names_used
+ = current_class_stack[current_class_depth - 1].names_used;
+ if (!names_used)
+ return;
+ /* The C language allows members to be declared with a type of the same
+ name, and the C++ standard says this diagnostic is not required. So
+ allow it in extern "C" blocks unless predantic is specified.
+ Allow it in all cases if -ms-extensions is specified. */
+ if ((!pedantic && current_lang_name == lang_name_c)
+ || flag_ms_extensions)
+ return;
+ n = splay_tree_lookup (names_used, (splay_tree_key) name);
+ if (n)
+ {
+ /* [basic.scope.class]
+
+ A name N used in a class S shall refer to the same declaration
+ in its context and when re-evaluated in the completed scope of
+ S. */
+ permerror (input_location, "declaration of %q#D", decl);
+ permerror (input_location, "changes meaning of %qD from %q+#D",
+ DECL_NAME (OVL_CURRENT (decl)), (tree) n->value);
+ }
+}
+
+/* Returns the VAR_DECL for the complete vtable associated with BINFO.
+ Secondary vtables are merged with primary vtables; this function
+ will return the VAR_DECL for the primary vtable. */
+
+tree
+get_vtbl_decl_for_binfo (tree binfo)
+{
+ tree decl;
+
+ decl = BINFO_VTABLE (binfo);
+ if (decl && TREE_CODE (decl) == POINTER_PLUS_EXPR)
+ {
+ gcc_assert (TREE_CODE (TREE_OPERAND (decl, 0)) == ADDR_EXPR);
+ decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
+ }
+ if (decl)
+ gcc_assert (VAR_P (decl));
+ return decl;
+}
+
+
+/* Returns the binfo for the primary base of BINFO. If the resulting
+ BINFO is a virtual base, and it is inherited elsewhere in the
+ hierarchy, then the returned binfo might not be the primary base of
+ BINFO in the complete object. Check BINFO_PRIMARY_P or
+ BINFO_LOST_PRIMARY_P to be sure. */
+
+static tree
+get_primary_binfo (tree binfo)
+{
+ tree primary_base;
+
+ primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo));
+ if (!primary_base)
+ return NULL_TREE;
+
+ return copied_binfo (primary_base, binfo);
+}
+
+/* If INDENTED_P is zero, indent to INDENT. Return nonzero. */
+
+static int
+maybe_indent_hierarchy (FILE * stream, int indent, int indented_p)
+{
+ if (!indented_p)
+ fprintf (stream, "%*s", indent, "");
+ return 1;
+}
+
+/* Dump the offsets of all the bases rooted at BINFO to STREAM.
+ INDENT should be zero when called from the top level; it is
+ incremented recursively. IGO indicates the next expected BINFO in
+ inheritance graph ordering. */
+
+static tree
+dump_class_hierarchy_r (FILE *stream,
+ int flags,
+ tree binfo,
+ tree igo,
+ int indent)
+{
+ int indented = 0;
+ tree base_binfo;
+ int i;
+
+ indented = maybe_indent_hierarchy (stream, indent, 0);
+ fprintf (stream, "%s (0x" HOST_WIDE_INT_PRINT_HEX ") ",
+ type_as_string (BINFO_TYPE (binfo), TFF_PLAIN_IDENTIFIER),
+ (HOST_WIDE_INT) (uintptr_t) binfo);
+ if (binfo != igo)
+ {
+ fprintf (stream, "alternative-path\n");
+ return igo;
+ }
+ igo = TREE_CHAIN (binfo);
+
+ fprintf (stream, HOST_WIDE_INT_PRINT_DEC,
+ tree_to_shwi (BINFO_OFFSET (binfo)));
+ if (is_empty_class (BINFO_TYPE (binfo)))
+ fprintf (stream, " empty");
+ else if (CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (binfo)))
+ fprintf (stream, " nearly-empty");
+ if (BINFO_VIRTUAL_P (binfo))
+ fprintf (stream, " virtual");
+ fprintf (stream, "\n");
+
+ indented = 0;
+ if (BINFO_PRIMARY_P (binfo))
+ {
+ indented = maybe_indent_hierarchy (stream, indent + 3, indented);
+ fprintf (stream, " primary-for %s (0x" HOST_WIDE_INT_PRINT_HEX ")",
+ type_as_string (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)),
+ TFF_PLAIN_IDENTIFIER),
+ (HOST_WIDE_INT) (uintptr_t) BINFO_INHERITANCE_CHAIN (binfo));
+ }
+ if (BINFO_LOST_PRIMARY_P (binfo))
+ {
+ indented = maybe_indent_hierarchy (stream, indent + 3, indented);
+ fprintf (stream, " lost-primary");
+ }
+ if (indented)
+ fprintf (stream, "\n");
+
+ if (!(flags & TDF_SLIM))
+ {
+ int indented = 0;
+
+ if (BINFO_SUBVTT_INDEX (binfo))
+ {
+ indented = maybe_indent_hierarchy (stream, indent + 3, indented);
+ fprintf (stream, " subvttidx=%s",
+ expr_as_string (BINFO_SUBVTT_INDEX (binfo),
+ TFF_PLAIN_IDENTIFIER));
+ }
+ if (BINFO_VPTR_INDEX (binfo))
+ {
+ indented = maybe_indent_hierarchy (stream, indent + 3, indented);
+ fprintf (stream, " vptridx=%s",
+ expr_as_string (BINFO_VPTR_INDEX (binfo),
+ TFF_PLAIN_IDENTIFIER));
+ }
+ if (BINFO_VPTR_FIELD (binfo))
+ {
+ indented = maybe_indent_hierarchy (stream, indent + 3, indented);
+ fprintf (stream, " vbaseoffset=%s",
+ expr_as_string (BINFO_VPTR_FIELD (binfo),
+ TFF_PLAIN_IDENTIFIER));
+ }
+ if (BINFO_VTABLE (binfo))
+ {
+ indented = maybe_indent_hierarchy (stream, indent + 3, indented);
+ fprintf (stream, " vptr=%s",
+ expr_as_string (BINFO_VTABLE (binfo),
+ TFF_PLAIN_IDENTIFIER));
+ }
+
+ if (indented)
+ fprintf (stream, "\n");
+ }
+
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ igo = dump_class_hierarchy_r (stream, flags, base_binfo, igo, indent + 2);
+
+ return igo;
+}
+
+/* Dump the BINFO hierarchy for T. */
+
+static void
+dump_class_hierarchy_1 (FILE *stream, int flags, tree t)
+{
+ fprintf (stream, "Class %s\n", type_as_string (t, TFF_PLAIN_IDENTIFIER));
+ fprintf (stream, " size=%lu align=%lu\n",
+ (unsigned long)(tree_to_shwi (TYPE_SIZE (t)) / BITS_PER_UNIT),
+ (unsigned long)(TYPE_ALIGN (t) / BITS_PER_UNIT));
+ fprintf (stream, " base size=%lu base align=%lu\n",
+ (unsigned long)(tree_to_shwi (TYPE_SIZE (CLASSTYPE_AS_BASE (t)))
+ / BITS_PER_UNIT),
+ (unsigned long)(TYPE_ALIGN (CLASSTYPE_AS_BASE (t))
+ / BITS_PER_UNIT));
+ dump_class_hierarchy_r (stream, flags, TYPE_BINFO (t), TYPE_BINFO (t), 0);
+ fprintf (stream, "\n");
+}
+
+/* Debug interface to hierarchy dumping. */
+
+void
+debug_class (tree t)
+{
+ dump_class_hierarchy_1 (stderr, TDF_SLIM, t);
+}
+
+static void
+dump_class_hierarchy (tree t)
+{
+ int flags;
+ FILE *stream = dump_begin (TDI_class, &flags);
+
+ if (stream)
+ {
+ dump_class_hierarchy_1 (stream, flags, t);
+ dump_end (TDI_class, stream);
+ }
+}
+
+static void
+dump_array (FILE * stream, tree decl)
+{
+ tree value;
+ unsigned HOST_WIDE_INT ix;
+ HOST_WIDE_INT elt;
+ tree size = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (decl)));
+
+ elt = (tree_to_shwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl))))
+ / BITS_PER_UNIT);
+ fprintf (stream, "%s:", decl_as_string (decl, TFF_PLAIN_IDENTIFIER));
+ fprintf (stream, " %s entries",
+ expr_as_string (size_binop (PLUS_EXPR, size, size_one_node),
+ TFF_PLAIN_IDENTIFIER));
+ fprintf (stream, "\n");
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)),
+ ix, value)
+ fprintf (stream, "%-4ld %s\n", (long)(ix * elt),
+ expr_as_string (value, TFF_PLAIN_IDENTIFIER));
+}
+
+static void
+dump_vtable (tree t, tree binfo, tree vtable)
+{
+ int flags;
+ FILE *stream = dump_begin (TDI_class, &flags);
+
+ if (!stream)
+ return;
+
+ if (!(flags & TDF_SLIM))
+ {
+ int ctor_vtbl_p = TYPE_BINFO (t) != binfo;
+
+ fprintf (stream, "%s for %s",
+ ctor_vtbl_p ? "Construction vtable" : "Vtable",
+ type_as_string (BINFO_TYPE (binfo), TFF_PLAIN_IDENTIFIER));
+ if (ctor_vtbl_p)
+ {
+ if (!BINFO_VIRTUAL_P (binfo))
+ fprintf (stream, " (0x" HOST_WIDE_INT_PRINT_HEX " instance)",
+ (HOST_WIDE_INT) (uintptr_t) binfo);
+ fprintf (stream, " in %s", type_as_string (t, TFF_PLAIN_IDENTIFIER));
+ }
+ fprintf (stream, "\n");
+ dump_array (stream, vtable);
+ fprintf (stream, "\n");
+ }
+
+ dump_end (TDI_class, stream);
+}
+
+static void
+dump_vtt (tree t, tree vtt)
+{
+ int flags;
+ FILE *stream = dump_begin (TDI_class, &flags);
+
+ if (!stream)
+ return;
+
+ if (!(flags & TDF_SLIM))
+ {
+ fprintf (stream, "VTT for %s\n",
+ type_as_string (t, TFF_PLAIN_IDENTIFIER));
+ dump_array (stream, vtt);
+ fprintf (stream, "\n");
+ }
+
+ dump_end (TDI_class, stream);
+}
+
+/* Dump a function or thunk and its thunkees. */
+
+static void
+dump_thunk (FILE *stream, int indent, tree thunk)
+{
+ static const char spaces[] = " ";
+ tree name = DECL_NAME (thunk);
+ tree thunks;
+
+ fprintf (stream, "%.*s%p %s %s", indent, spaces,
+ (void *)thunk,
+ !DECL_THUNK_P (thunk) ? "function"
+ : DECL_THIS_THUNK_P (thunk) ? "this-thunk" : "covariant-thunk",
+ name ? IDENTIFIER_POINTER (name) : "<unset>");
+ if (DECL_THUNK_P (thunk))
+ {
+ HOST_WIDE_INT fixed_adjust = THUNK_FIXED_OFFSET (thunk);
+ tree virtual_adjust = THUNK_VIRTUAL_OFFSET (thunk);
+
+ fprintf (stream, " fixed=" HOST_WIDE_INT_PRINT_DEC, fixed_adjust);
+ if (!virtual_adjust)
+ /*NOP*/;
+ else if (DECL_THIS_THUNK_P (thunk))
+ fprintf (stream, " vcall=" HOST_WIDE_INT_PRINT_DEC,
+ tree_to_shwi (virtual_adjust));
+ else
+ fprintf (stream, " vbase=" HOST_WIDE_INT_PRINT_DEC "(%s)",
+ tree_to_shwi (BINFO_VPTR_FIELD (virtual_adjust)),
+ type_as_string (BINFO_TYPE (virtual_adjust), TFF_SCOPE));
+ if (THUNK_ALIAS (thunk))
+ fprintf (stream, " alias to %p", (void *)THUNK_ALIAS (thunk));
+ }
+ fprintf (stream, "\n");
+ for (thunks = DECL_THUNKS (thunk); thunks; thunks = TREE_CHAIN (thunks))
+ dump_thunk (stream, indent + 2, thunks);
+}
+
+/* Dump the thunks for FN. */
+
+void
+debug_thunks (tree fn)
+{
+ dump_thunk (stderr, 0, fn);
+}
+
+/* Virtual function table initialization. */
+
+/* Create all the necessary vtables for T and its base classes. */
+
+static void
+finish_vtbls (tree t)
+{
+ tree vbase;
+ vec<constructor_elt, va_gc> *v = NULL;
+ tree vtable = BINFO_VTABLE (TYPE_BINFO (t));
+
+ /* We lay out the primary and secondary vtables in one contiguous
+ vtable. The primary vtable is first, followed by the non-virtual
+ secondary vtables in inheritance graph order. */
+ accumulate_vtbl_inits (TYPE_BINFO (t), TYPE_BINFO (t), TYPE_BINFO (t),
+ vtable, t, &v);
+
+ /* Then come the virtual bases, also in inheritance graph order. */
+ for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
+ {
+ if (!BINFO_VIRTUAL_P (vbase))
+ continue;
+ accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), vtable, t, &v);
+ }
+
+ if (BINFO_VTABLE (TYPE_BINFO (t)))
+ initialize_vtable (TYPE_BINFO (t), v);
+}
+
+/* Initialize the vtable for BINFO with the INITS. */
+
+static void
+initialize_vtable (tree binfo, vec<constructor_elt, va_gc> *inits)
+{
+ tree decl;
+
+ layout_vtable_decl (binfo, vec_safe_length (inits));
+ decl = get_vtbl_decl_for_binfo (binfo);
+ initialize_artificial_var (decl, inits);
+ dump_vtable (BINFO_TYPE (binfo), binfo, decl);
+}
+
+/* Build the VTT (virtual table table) for T.
+ A class requires a VTT if it has virtual bases.
+
+ This holds
+ 1 - primary virtual pointer for complete object T
+ 2 - secondary VTTs for each direct non-virtual base of T which requires a
+ VTT
+ 3 - secondary virtual pointers for each direct or indirect base of T which
+ has virtual bases or is reachable via a virtual path from T.
+ 4 - secondary VTTs for each direct or indirect virtual base of T.
+
+ Secondary VTTs look like complete object VTTs without part 4. */
+
+static void
+build_vtt (tree t)
+{
+ tree type;
+ tree vtt;
+ tree index;
+ vec<constructor_elt, va_gc> *inits;
+
+ /* Build up the initializers for the VTT. */
+ inits = NULL;
+ index = size_zero_node;
+ build_vtt_inits (TYPE_BINFO (t), t, &inits, &index);
+
+ /* If we didn't need a VTT, we're done. */
+ if (!inits)
+ return;
+
+ /* Figure out the type of the VTT. */
+ type = build_array_of_n_type (const_ptr_type_node,
+ inits->length ());
+
+ /* Now, build the VTT object itself. */
+ vtt = build_vtable (t, mangle_vtt_for_type (t), type);
+ initialize_artificial_var (vtt, inits);
+ /* Add the VTT to the vtables list. */
+ DECL_CHAIN (vtt) = DECL_CHAIN (CLASSTYPE_VTABLES (t));
+ DECL_CHAIN (CLASSTYPE_VTABLES (t)) = vtt;
+
+ dump_vtt (t, vtt);
+}
+
+/* When building a secondary VTT, BINFO_VTABLE is set to a TREE_LIST with
+ PURPOSE the RTTI_BINFO, VALUE the real vtable pointer for this binfo,
+ and CHAIN the vtable pointer for this binfo after construction is
+ complete. VALUE can also be another BINFO, in which case we recurse. */
+
+static tree
+binfo_ctor_vtable (tree binfo)
+{
+ tree vt;
+
+ while (1)
+ {
+ vt = BINFO_VTABLE (binfo);
+ if (TREE_CODE (vt) == TREE_LIST)
+ vt = TREE_VALUE (vt);
+ if (TREE_CODE (vt) == TREE_BINFO)
+ binfo = vt;
+ else
+ break;
+ }
+
+ return vt;
+}
+
+/* Data for secondary VTT initialization. */
+typedef struct secondary_vptr_vtt_init_data_s
+{
+ /* Is this the primary VTT? */
+ bool top_level_p;
+
+ /* Current index into the VTT. */
+ tree index;
+
+ /* Vector of initializers built up. */
+ vec<constructor_elt, va_gc> *inits;
+
+ /* The type being constructed by this secondary VTT. */
+ tree type_being_constructed;
+} secondary_vptr_vtt_init_data;
+
+/* Recursively build the VTT-initializer for BINFO (which is in the
+ hierarchy dominated by T). INITS points to the end of the initializer
+ list to date. INDEX is the VTT index where the next element will be
+ replaced. Iff BINFO is the binfo for T, this is the top level VTT (i.e.
+ not a subvtt for some base of T). When that is so, we emit the sub-VTTs
+ for virtual bases of T. When it is not so, we build the constructor
+ vtables for the BINFO-in-T variant. */
+
+static void
+build_vtt_inits (tree binfo, tree t, vec<constructor_elt, va_gc> **inits,
+ tree *index)
+{
+ int i;
+ tree b;
+ tree init;
+ secondary_vptr_vtt_init_data data;
+ int top_level_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
+
+ /* We only need VTTs for subobjects with virtual bases. */
+ if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
+ return;
+
+ /* We need to use a construction vtable if this is not the primary
+ VTT. */
+ if (!top_level_p)
+ {
+ build_ctor_vtbl_group (binfo, t);
+
+ /* Record the offset in the VTT where this sub-VTT can be found. */
+ BINFO_SUBVTT_INDEX (binfo) = *index;
+ }
+
+ /* Add the address of the primary vtable for the complete object. */
+ init = binfo_ctor_vtable (binfo);
+ CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
+ if (top_level_p)
+ {
+ gcc_assert (!BINFO_VPTR_INDEX (binfo));
+ BINFO_VPTR_INDEX (binfo) = *index;
+ }
+ *index = size_binop (PLUS_EXPR, *index, TYPE_SIZE_UNIT (ptr_type_node));
+
+ /* Recursively add the secondary VTTs for non-virtual bases. */
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, b); ++i)
+ if (!BINFO_VIRTUAL_P (b))
+ build_vtt_inits (b, t, inits, index);
+
+ /* Add secondary virtual pointers for all subobjects of BINFO with
+ either virtual bases or reachable along a virtual path, except
+ subobjects that are non-virtual primary bases. */
+ data.top_level_p = top_level_p;
+ data.index = *index;
+ data.inits = *inits;
+ data.type_being_constructed = BINFO_TYPE (binfo);
+
+ dfs_walk_once (binfo, dfs_build_secondary_vptr_vtt_inits, NULL, &data);
+
+ *index = data.index;
+
+ /* data.inits might have grown as we added secondary virtual pointers.
+ Make sure our caller knows about the new vector. */
+ *inits = data.inits;
+
+ if (top_level_p)
+ /* Add the secondary VTTs for virtual bases in inheritance graph
+ order. */
+ for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
+ {
+ if (!BINFO_VIRTUAL_P (b))
+ continue;
+
+ build_vtt_inits (b, t, inits, index);
+ }
+ else
+ /* Remove the ctor vtables we created. */
+ dfs_walk_all (binfo, dfs_fixup_binfo_vtbls, NULL, binfo);
+}
+
+/* Called from build_vtt_inits via dfs_walk. BINFO is the binfo for the base
+ in most derived. DATA is a SECONDARY_VPTR_VTT_INIT_DATA structure. */
+
+static tree
+dfs_build_secondary_vptr_vtt_inits (tree binfo, void *data_)
+{
+ secondary_vptr_vtt_init_data *data = (secondary_vptr_vtt_init_data *)data_;
+
+ /* We don't care about bases that don't have vtables. */
+ if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
+ return dfs_skip_bases;
+
+ /* We're only interested in proper subobjects of the type being
+ constructed. */
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->type_being_constructed))
+ return NULL_TREE;
+
+ /* We're only interested in bases with virtual bases or reachable
+ via a virtual path from the type being constructed. */
+ if (!(CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))
+ || binfo_via_virtual (binfo, data->type_being_constructed)))
+ return dfs_skip_bases;
+
+ /* We're not interested in non-virtual primary bases. */
+ if (!BINFO_VIRTUAL_P (binfo) && BINFO_PRIMARY_P (binfo))
+ return NULL_TREE;
+
+ /* Record the index where this secondary vptr can be found. */
+ if (data->top_level_p)
+ {
+ gcc_assert (!BINFO_VPTR_INDEX (binfo));
+ BINFO_VPTR_INDEX (binfo) = data->index;
+
+ if (BINFO_VIRTUAL_P (binfo))
+ {
+ /* It's a primary virtual base, and this is not a
+ construction vtable. Find the base this is primary of in
+ the inheritance graph, and use that base's vtable
+ now. */
+ while (BINFO_PRIMARY_P (binfo))
+ binfo = BINFO_INHERITANCE_CHAIN (binfo);
+ }
+ }
+
+ /* Add the initializer for the secondary vptr itself. */
+ CONSTRUCTOR_APPEND_ELT (data->inits, NULL_TREE, binfo_ctor_vtable (binfo));
+
+ /* Advance the vtt index. */
+ data->index = size_binop (PLUS_EXPR, data->index,
+ TYPE_SIZE_UNIT (ptr_type_node));
+
+ return NULL_TREE;
+}
+
+/* Called from build_vtt_inits via dfs_walk. After building
+ constructor vtables and generating the sub-vtt from them, we need
+ to restore the BINFO_VTABLES that were scribbled on. DATA is the
+ binfo of the base whose sub vtt was generated. */
+
+static tree
+dfs_fixup_binfo_vtbls (tree binfo, void* data)
+{
+ tree vtable = BINFO_VTABLE (binfo);
+
+ if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
+ /* If this class has no vtable, none of its bases do. */
+ return dfs_skip_bases;
+
+ if (!vtable)
+ /* This might be a primary base, so have no vtable in this
+ hierarchy. */
+ return NULL_TREE;
+
+ /* If we scribbled the construction vtable vptr into BINFO, clear it
+ out now. */
+ if (TREE_CODE (vtable) == TREE_LIST
+ && (TREE_PURPOSE (vtable) == (tree) data))
+ BINFO_VTABLE (binfo) = TREE_CHAIN (vtable);
+
+ return NULL_TREE;
+}
+
+/* Build the construction vtable group for BINFO which is in the
+ hierarchy dominated by T. */
+
+static void
+build_ctor_vtbl_group (tree binfo, tree t)
+{
+ tree type;
+ tree vtbl;
+ tree id;
+ tree vbase;
+ vec<constructor_elt, va_gc> *v;
+
+ /* See if we've already created this construction vtable group. */
+ id = mangle_ctor_vtbl_for_type (t, binfo);
+ if (IDENTIFIER_GLOBAL_VALUE (id))
+ return;
+
+ gcc_assert (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t));
+ /* Build a version of VTBL (with the wrong type) for use in
+ constructing the addresses of secondary vtables in the
+ construction vtable group. */
+ vtbl = build_vtable (t, id, ptr_type_node);
+ DECL_CONSTRUCTION_VTABLE_P (vtbl) = 1;
+ /* Don't export construction vtables from shared libraries. Even on
+ targets that don't support hidden visibility, this tells
+ can_refer_decl_in_current_unit_p not to assume that it's safe to
+ access from a different compilation unit (bz 54314). */
+ DECL_VISIBILITY (vtbl) = VISIBILITY_HIDDEN;
+ DECL_VISIBILITY_SPECIFIED (vtbl) = true;
+
+ v = NULL;
+ accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
+ binfo, vtbl, t, &v);
+
+ /* Add the vtables for each of our virtual bases using the vbase in T
+ binfo. */
+ for (vbase = TYPE_BINFO (BINFO_TYPE (binfo));
+ vbase;
+ vbase = TREE_CHAIN (vbase))
+ {
+ tree b;
+
+ if (!BINFO_VIRTUAL_P (vbase))
+ continue;
+ b = copied_binfo (vbase, binfo);
+
+ accumulate_vtbl_inits (b, vbase, binfo, vtbl, t, &v);
+ }
+
+ /* Figure out the type of the construction vtable. */
+ type = build_array_of_n_type (vtable_entry_type, v->length ());
+ layout_type (type);
+ TREE_TYPE (vtbl) = type;
+ DECL_SIZE (vtbl) = DECL_SIZE_UNIT (vtbl) = NULL_TREE;
+ layout_decl (vtbl, 0);
+
+ /* Initialize the construction vtable. */
+ CLASSTYPE_VTABLES (t) = chainon (CLASSTYPE_VTABLES (t), vtbl);
+ initialize_artificial_var (vtbl, v);
+ dump_vtable (t, binfo, vtbl);
+}
+
+/* Add the vtbl initializers for BINFO (and its bases other than
+ non-virtual primaries) to the list of INITS. BINFO is in the
+ hierarchy dominated by T. RTTI_BINFO is the binfo within T of
+ the constructor the vtbl inits should be accumulated for. (If this
+ is the complete object vtbl then RTTI_BINFO will be TYPE_BINFO (T).)
+ ORIG_BINFO is the binfo for this object within BINFO_TYPE (RTTI_BINFO).
+ BINFO is the active base equivalent of ORIG_BINFO in the inheritance
+ graph of T. Both BINFO and ORIG_BINFO will have the same BINFO_TYPE,
+ but are not necessarily the same in terms of layout. */
+
+static void
+accumulate_vtbl_inits (tree binfo,
+ tree orig_binfo,
+ tree rtti_binfo,
+ tree vtbl,
+ tree t,
+ vec<constructor_elt, va_gc> **inits)
+{
+ int i;
+ tree base_binfo;
+ int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
+
+ gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (orig_binfo)));
+
+ /* If it doesn't have a vptr, we don't do anything. */
+ if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
+ return;
+
+ /* If we're building a construction vtable, we're not interested in
+ subobjects that don't require construction vtables. */
+ if (ctor_vtbl_p
+ && !CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))
+ && !binfo_via_virtual (orig_binfo, BINFO_TYPE (rtti_binfo)))
+ return;
+
+ /* Build the initializers for the BINFO-in-T vtable. */
+ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, vtbl, t, inits);
+
+ /* Walk the BINFO and its bases. We walk in preorder so that as we
+ initialize each vtable we can figure out at what offset the
+ secondary vtable lies from the primary vtable. We can't use
+ dfs_walk here because we need to iterate through bases of BINFO
+ and RTTI_BINFO simultaneously. */
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ {
+ /* Skip virtual bases. */
+ if (BINFO_VIRTUAL_P (base_binfo))
+ continue;
+ accumulate_vtbl_inits (base_binfo,
+ BINFO_BASE_BINFO (orig_binfo, i),
+ rtti_binfo, vtbl, t,
+ inits);
+ }
+}
+
+/* Called from accumulate_vtbl_inits. Adds the initializers for the
+ BINFO vtable to L. */
+
+static void
+dfs_accumulate_vtbl_inits (tree binfo,
+ tree orig_binfo,
+ tree rtti_binfo,
+ tree orig_vtbl,
+ tree t,
+ vec<constructor_elt, va_gc> **l)
+{
+ tree vtbl = NULL_TREE;
+ int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
+ int n_inits;
+
+ if (ctor_vtbl_p
+ && BINFO_VIRTUAL_P (orig_binfo) && BINFO_PRIMARY_P (orig_binfo))
+ {
+ /* In the hierarchy of BINFO_TYPE (RTTI_BINFO), this is a
+ primary virtual base. If it is not the same primary in
+ the hierarchy of T, we'll need to generate a ctor vtable
+ for it, to place at its location in T. If it is the same
+ primary, we still need a VTT entry for the vtable, but it
+ should point to the ctor vtable for the base it is a
+ primary for within the sub-hierarchy of RTTI_BINFO.
+
+ There are three possible cases:
+
+ 1) We are in the same place.
+ 2) We are a primary base within a lost primary virtual base of
+ RTTI_BINFO.
+ 3) We are primary to something not a base of RTTI_BINFO. */
+
+ tree b;
+ tree last = NULL_TREE;
+
+ /* First, look through the bases we are primary to for RTTI_BINFO
+ or a virtual base. */
+ b = binfo;
+ while (BINFO_PRIMARY_P (b))
+ {
+ b = BINFO_INHERITANCE_CHAIN (b);
+ last = b;
+ if (BINFO_VIRTUAL_P (b) || b == rtti_binfo)
+ goto found;
+ }
+ /* If we run out of primary links, keep looking down our
+ inheritance chain; we might be an indirect primary. */
+ for (b = last; b; b = BINFO_INHERITANCE_CHAIN (b))
+ if (BINFO_VIRTUAL_P (b) || b == rtti_binfo)
+ break;
+ found:
+
+ /* If we found RTTI_BINFO, this is case 1. If we found a virtual
+ base B and it is a base of RTTI_BINFO, this is case 2. In
+ either case, we share our vtable with LAST, i.e. the
+ derived-most base within B of which we are a primary. */
+ if (b == rtti_binfo
+ || (b && binfo_for_vbase (BINFO_TYPE (b), BINFO_TYPE (rtti_binfo))))
+ /* Just set our BINFO_VTABLE to point to LAST, as we may not have
+ set LAST's BINFO_VTABLE yet. We'll extract the actual vptr in
+ binfo_ctor_vtable after everything's been set up. */
+ vtbl = last;
+
+ /* Otherwise, this is case 3 and we get our own. */
+ }
+ else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo))
+ return;
+
+ n_inits = vec_safe_length (*l);
+
+ if (!vtbl)
+ {
+ tree index;
+ int non_fn_entries;
+
+ /* Add the initializer for this vtable. */
+ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo,
+ &non_fn_entries, l);
+
+ /* Figure out the position to which the VPTR should point. */
+ vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, orig_vtbl);
+ index = size_binop (MULT_EXPR,
+ TYPE_SIZE_UNIT (vtable_entry_type),
+ size_int (non_fn_entries + n_inits));
+ vtbl = fold_build_pointer_plus (vtbl, index);
+ }
+
+ if (ctor_vtbl_p)
+ /* For a construction vtable, we can't overwrite BINFO_VTABLE.
+ So, we make a TREE_LIST. Later, dfs_fixup_binfo_vtbls will
+ straighten this out. */
+ BINFO_VTABLE (binfo) = tree_cons (rtti_binfo, vtbl, BINFO_VTABLE (binfo));
+ else if (BINFO_PRIMARY_P (binfo) && BINFO_VIRTUAL_P (binfo))
+ /* Throw away any unneeded intializers. */
+ (*l)->truncate (n_inits);
+ else
+ /* For an ordinary vtable, set BINFO_VTABLE. */
+ BINFO_VTABLE (binfo) = vtbl;
+}
+
+static GTY(()) tree abort_fndecl_addr;
+
+/* Construct the initializer for BINFO's virtual function table. BINFO
+ is part of the hierarchy dominated by T. If we're building a
+ construction vtable, the ORIG_BINFO is the binfo we should use to
+ find the actual function pointers to put in the vtable - but they
+ can be overridden on the path to most-derived in the graph that
+ ORIG_BINFO belongs. Otherwise,
+ ORIG_BINFO should be the same as BINFO. The RTTI_BINFO is the
+ BINFO that should be indicated by the RTTI information in the
+ vtable; it will be a base class of T, rather than T itself, if we
+ are building a construction vtable.
+
+ The value returned is a TREE_LIST suitable for wrapping in a
+ CONSTRUCTOR to use as the DECL_INITIAL for a vtable. If
+ NON_FN_ENTRIES_P is not NULL, *NON_FN_ENTRIES_P is set to the
+ number of non-function entries in the vtable.
+
+ It might seem that this function should never be called with a
+ BINFO for which BINFO_PRIMARY_P holds, the vtable for such a
+ base is always subsumed by a derived class vtable. However, when
+ we are building construction vtables, we do build vtables for
+ primary bases; we need these while the primary base is being
+ constructed. */
+
+static void
+build_vtbl_initializer (tree binfo,
+ tree orig_binfo,
+ tree t,
+ tree rtti_binfo,
+ int* non_fn_entries_p,
+ vec<constructor_elt, va_gc> **inits)
+{
+ tree v;
+ vtbl_init_data vid;
+ unsigned ix, jx;
+ tree vbinfo;
+ vec<tree, va_gc> *vbases;
+ constructor_elt *e;
+
+ /* Initialize VID. */
+ memset (&vid, 0, sizeof (vid));
+ vid.binfo = binfo;
+ vid.derived = t;
+ vid.rtti_binfo = rtti_binfo;
+ vid.primary_vtbl_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
+ vid.ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
+ vid.generate_vcall_entries = true;
+ /* The first vbase or vcall offset is at index -3 in the vtable. */
+ vid.index = ssize_int(-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
+
+ /* Add entries to the vtable for RTTI. */
+ build_rtti_vtbl_entries (binfo, &vid);
+
+ /* Create an array for keeping track of the functions we've
+ processed. When we see multiple functions with the same
+ signature, we share the vcall offsets. */
+ vec_alloc (vid.fns, 32);
+ /* Add the vcall and vbase offset entries. */
+ build_vcall_and_vbase_vtbl_entries (binfo, &vid);
+
+ /* Clear BINFO_VTABLE_PATH_MARKED; it's set by
+ build_vbase_offset_vtbl_entries. */
+ for (vbases = CLASSTYPE_VBASECLASSES (t), ix = 0;
+ vec_safe_iterate (vbases, ix, &vbinfo); ix++)
+ BINFO_VTABLE_PATH_MARKED (vbinfo) = 0;
+
+ /* If the target requires padding between data entries, add that now. */
+ if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1)
+ {
+ int n_entries = vec_safe_length (vid.inits);
+
+ vec_safe_grow (vid.inits, TARGET_VTABLE_DATA_ENTRY_DISTANCE * n_entries);
+
+ /* Move data entries into their new positions and add padding
+ after the new positions. Iterate backwards so we don't
+ overwrite entries that we would need to process later. */
+ for (ix = n_entries - 1;
+ vid.inits->iterate (ix, &e);
+ ix--)
+ {
+ int j;
+ int new_position = (TARGET_VTABLE_DATA_ENTRY_DISTANCE * ix
+ + (TARGET_VTABLE_DATA_ENTRY_DISTANCE - 1));
+
+ (*vid.inits)[new_position] = *e;
+
+ for (j = 1; j < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++j)
+ {
+ constructor_elt *f = &(*vid.inits)[new_position - j];
+ f->index = NULL_TREE;
+ f->value = build1 (NOP_EXPR, vtable_entry_type,
+ null_pointer_node);
+ }
+ }
+ }
+
+ if (non_fn_entries_p)
+ *non_fn_entries_p = vec_safe_length (vid.inits);
+
+ /* The initializers for virtual functions were built up in reverse
+ order. Straighten them out and add them to the running list in one
+ step. */
+ jx = vec_safe_length (*inits);
+ vec_safe_grow (*inits, jx + vid.inits->length ());
+
+ for (ix = vid.inits->length () - 1;
+ vid.inits->iterate (ix, &e);
+ ix--, jx++)
+ (**inits)[jx] = *e;
+
+ /* Go through all the ordinary virtual functions, building up
+ initializers. */
+ for (v = BINFO_VIRTUALS (orig_binfo); v; v = TREE_CHAIN (v))
+ {
+ tree delta;
+ tree vcall_index;
+ tree fn, fn_original;
+ tree init = NULL_TREE;
+
+ fn = BV_FN (v);
+ fn_original = fn;
+ if (DECL_THUNK_P (fn))
+ {
+ if (!DECL_NAME (fn))
+ finish_thunk (fn);
+ if (THUNK_ALIAS (fn))
+ {
+ fn = THUNK_ALIAS (fn);
+ BV_FN (v) = fn;
+ }
+ fn_original = THUNK_TARGET (fn);
+ }
+
+ /* If the only definition of this function signature along our
+ primary base chain is from a lost primary, this vtable slot will
+ never be used, so just zero it out. This is important to avoid
+ requiring extra thunks which cannot be generated with the function.
+
+ We first check this in update_vtable_entry_for_fn, so we handle
+ restored primary bases properly; we also need to do it here so we
+ zero out unused slots in ctor vtables, rather than filling them
+ with erroneous values (though harmless, apart from relocation
+ costs). */
+ if (BV_LOST_PRIMARY (v))
+ init = size_zero_node;
+
+ if (! init)
+ {
+ /* Pull the offset for `this', and the function to call, out of
+ the list. */
+ delta = BV_DELTA (v);
+ vcall_index = BV_VCALL_INDEX (v);
+
+ gcc_assert (TREE_CODE (delta) == INTEGER_CST);
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
+
+ /* You can't call an abstract virtual function; it's abstract.
+ So, we replace these functions with __pure_virtual. */
+ if (DECL_PURE_VIRTUAL_P (fn_original))
+ {
+ fn = abort_fndecl;
+ if (!TARGET_VTABLE_USES_DESCRIPTORS)
+ {
+ if (abort_fndecl_addr == NULL)
+ abort_fndecl_addr
+ = fold_convert (vfunc_ptr_type_node,
+ build_fold_addr_expr (fn));
+ init = abort_fndecl_addr;
+ }
+ }
+ /* Likewise for deleted virtuals. */
+ else if (DECL_DELETED_FN (fn_original))
+ {
+ fn = get_identifier ("__cxa_deleted_virtual");
+ if (!get_global_value_if_present (fn, &fn))
+ fn = push_library_fn (fn, (build_function_type_list
+ (void_type_node, NULL_TREE)),
+ NULL_TREE, ECF_NORETURN);
+ if (!TARGET_VTABLE_USES_DESCRIPTORS)
+ init = fold_convert (vfunc_ptr_type_node,
+ build_fold_addr_expr (fn));
+ }
+ else
+ {
+ if (!integer_zerop (delta) || vcall_index)
+ {
+ fn = make_thunk (fn, /*this_adjusting=*/1, delta, vcall_index);
+ if (!DECL_NAME (fn))
+ finish_thunk (fn);
+ }
+ /* Take the address of the function, considering it to be of an
+ appropriate generic type. */
+ if (!TARGET_VTABLE_USES_DESCRIPTORS)
+ init = fold_convert (vfunc_ptr_type_node,
+ build_fold_addr_expr (fn));
+ }
+ }
+
+ /* And add it to the chain of initializers. */
+ if (TARGET_VTABLE_USES_DESCRIPTORS)
+ {
+ int i;
+ if (init == size_zero_node)
+ for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
+ CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
+ else
+ for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
+ {
+ tree fdesc = build2 (FDESC_EXPR, vfunc_ptr_type_node,
+ fn, build_int_cst (NULL_TREE, i));
+ TREE_CONSTANT (fdesc) = 1;
+
+ CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, fdesc);
+ }
+ }
+ else
+ CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
+ }
+}
+
+/* Adds to vid->inits the initializers for the vbase and vcall
+ offsets in BINFO, which is in the hierarchy dominated by T. */
+
+static void
+build_vcall_and_vbase_vtbl_entries (tree binfo, vtbl_init_data* vid)
+{
+ tree b;
+
+ /* If this is a derived class, we must first create entries
+ corresponding to the primary base class. */
+ b = get_primary_binfo (binfo);
+ if (b)
+ build_vcall_and_vbase_vtbl_entries (b, vid);
+
+ /* Add the vbase entries for this base. */
+ build_vbase_offset_vtbl_entries (binfo, vid);
+ /* Add the vcall entries for this base. */
+ build_vcall_offset_vtbl_entries (binfo, vid);
+}
+
+/* Returns the initializers for the vbase offset entries in the vtable
+ for BINFO (which is part of the class hierarchy dominated by T), in
+ reverse order. VBASE_OFFSET_INDEX gives the vtable index
+ where the next vbase offset will go. */
+
+static void
+build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
+{
+ tree vbase;
+ tree t;
+ tree non_primary_binfo;
+
+ /* If there are no virtual baseclasses, then there is nothing to
+ do. */
+ if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
+ return;
+
+ t = vid->derived;
+
+ /* We might be a primary base class. Go up the inheritance hierarchy
+ until we find the most derived class of which we are a primary base:
+ it is the offset of that which we need to use. */
+ non_primary_binfo = binfo;
+ while (BINFO_INHERITANCE_CHAIN (non_primary_binfo))
+ {
+ tree b;
+
+ /* If we have reached a virtual base, then it must be a primary
+ base (possibly multi-level) of vid->binfo, or we wouldn't
+ have called build_vcall_and_vbase_vtbl_entries for it. But it
+ might be a lost primary, so just skip down to vid->binfo. */
+ if (BINFO_VIRTUAL_P (non_primary_binfo))
+ {
+ non_primary_binfo = vid->binfo;
+ break;
+ }
+
+ b = BINFO_INHERITANCE_CHAIN (non_primary_binfo);
+ if (get_primary_binfo (b) != non_primary_binfo)
+ break;
+ non_primary_binfo = b;
+ }
+
+ /* Go through the virtual bases, adding the offsets. */
+ for (vbase = TYPE_BINFO (BINFO_TYPE (binfo));
+ vbase;
+ vbase = TREE_CHAIN (vbase))
+ {
+ tree b;
+ tree delta;
+
+ if (!BINFO_VIRTUAL_P (vbase))
+ continue;
+
+ /* Find the instance of this virtual base in the complete
+ object. */
+ b = copied_binfo (vbase, binfo);
+
+ /* If we've already got an offset for this virtual base, we
+ don't need another one. */
+ if (BINFO_VTABLE_PATH_MARKED (b))
+ continue;
+ BINFO_VTABLE_PATH_MARKED (b) = 1;
+
+ /* Figure out where we can find this vbase offset. */
+ delta = size_binop (MULT_EXPR,
+ vid->index,
+ convert (ssizetype,
+ TYPE_SIZE_UNIT (vtable_entry_type)));
+ if (vid->primary_vtbl_p)
+ BINFO_VPTR_FIELD (b) = delta;
+
+ if (binfo != TYPE_BINFO (t))
+ /* The vbase offset had better be the same. */
+ gcc_assert (tree_int_cst_equal (delta, BINFO_VPTR_FIELD (vbase)));
+
+ /* The next vbase will come at a more negative offset. */
+ vid->index = size_binop (MINUS_EXPR, vid->index,
+ ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));
+
+ /* The initializer is the delta from BINFO to this virtual base.
+ The vbase offsets go in reverse inheritance-graph order, and
+ we are walking in inheritance graph order so these end up in
+ the right order. */
+ delta = size_diffop_loc (input_location,
+ BINFO_OFFSET (b), BINFO_OFFSET (non_primary_binfo));
+
+ CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE,
+ fold_build1_loc (input_location, NOP_EXPR,
+ vtable_entry_type, delta));
+ }
+}
+
+/* Adds the initializers for the vcall offset entries in the vtable
+ for BINFO (which is part of the class hierarchy dominated by VID->DERIVED)
+ to VID->INITS. */
+
+static void
+build_vcall_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
+{
+ /* We only need these entries if this base is a virtual base. We
+ compute the indices -- but do not add to the vtable -- when
+ building the main vtable for a class. */
+ if (binfo == TYPE_BINFO (vid->derived)
+ || (BINFO_VIRTUAL_P (binfo)
+ /* If BINFO is RTTI_BINFO, then (since BINFO does not
+ correspond to VID->DERIVED), we are building a primary
+ construction virtual table. Since this is a primary
+ virtual table, we do not need the vcall offsets for
+ BINFO. */
+ && binfo != vid->rtti_binfo))
+ {
+ /* We need a vcall offset for each of the virtual functions in this
+ vtable. For example:
+
+ class A { virtual void f (); };
+ class B1 : virtual public A { virtual void f (); };
+ class B2 : virtual public A { virtual void f (); };
+ class C: public B1, public B2 { virtual void f (); };
+
+ A C object has a primary base of B1, which has a primary base of A. A
+ C also has a secondary base of B2, which no longer has a primary base
+ of A. So the B2-in-C construction vtable needs a secondary vtable for
+ A, which will adjust the A* to a B2* to call f. We have no way of
+ knowing what (or even whether) this offset will be when we define B2,
+ so we store this "vcall offset" in the A sub-vtable and look it up in
+ a "virtual thunk" for B2::f.
+
+ We need entries for all the functions in our primary vtable and
+ in our non-virtual bases' secondary vtables. */
+ vid->vbase = binfo;
+ /* If we are just computing the vcall indices -- but do not need
+ the actual entries -- not that. */
+ if (!BINFO_VIRTUAL_P (binfo))
+ vid->generate_vcall_entries = false;
+ /* Now, walk through the non-virtual bases, adding vcall offsets. */
+ add_vcall_offset_vtbl_entries_r (binfo, vid);
+ }
+}
+
+/* Build vcall offsets, starting with those for BINFO. */
+
+static void
+add_vcall_offset_vtbl_entries_r (tree binfo, vtbl_init_data* vid)
+{
+ int i;
+ tree primary_binfo;
+ tree base_binfo;
+
+ /* Don't walk into virtual bases -- except, of course, for the
+ virtual base for which we are building vcall offsets. Any
+ primary virtual base will have already had its offsets generated
+ through the recursion in build_vcall_and_vbase_vtbl_entries. */
+ if (BINFO_VIRTUAL_P (binfo) && vid->vbase != binfo)
+ return;
+
+ /* If BINFO has a primary base, process it first. */
+ primary_binfo = get_primary_binfo (binfo);
+ if (primary_binfo)
+ add_vcall_offset_vtbl_entries_r (primary_binfo, vid);
+
+ /* Add BINFO itself to the list. */
+ add_vcall_offset_vtbl_entries_1 (binfo, vid);
+
+ /* Scan the non-primary bases of BINFO. */
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ if (base_binfo != primary_binfo)
+ add_vcall_offset_vtbl_entries_r (base_binfo, vid);
+}
+
+/* Called from build_vcall_offset_vtbl_entries_r. */
+
+static void
+add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid)
+{
+ /* Make entries for the rest of the virtuals. */
+ if (abi_version_at_least (2))
+ {
+ tree orig_fn;
+
+ /* The ABI requires that the methods be processed in declaration
+ order. G++ 3.2 used the order in the vtable. */
+ for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo));
+ orig_fn;
+ orig_fn = DECL_CHAIN (orig_fn))
+ if (DECL_VINDEX (orig_fn))
+ add_vcall_offset (orig_fn, binfo, vid);
+ }
+ else
+ {
+ tree derived_virtuals;
+ tree base_virtuals;
+ tree orig_virtuals;
+ /* If BINFO is a primary base, the most derived class which has
+ BINFO as a primary base; otherwise, just BINFO. */
+ tree non_primary_binfo;
+
+ /* We might be a primary base class. Go up the inheritance hierarchy
+ until we find the most derived class of which we are a primary base:
+ it is the BINFO_VIRTUALS there that we need to consider. */
+ non_primary_binfo = binfo;
+ while (BINFO_INHERITANCE_CHAIN (non_primary_binfo))
+ {
+ tree b;
+
+ /* If we have reached a virtual base, then it must be vid->vbase,
+ because we ignore other virtual bases in
+ add_vcall_offset_vtbl_entries_r. In turn, it must be a primary
+ base (possibly multi-level) of vid->binfo, or we wouldn't
+ have called build_vcall_and_vbase_vtbl_entries for it. But it
+ might be a lost primary, so just skip down to vid->binfo. */
+ if (BINFO_VIRTUAL_P (non_primary_binfo))
+ {
+ gcc_assert (non_primary_binfo == vid->vbase);
+ non_primary_binfo = vid->binfo;
+ break;
+ }
+
+ b = BINFO_INHERITANCE_CHAIN (non_primary_binfo);
+ if (get_primary_binfo (b) != non_primary_binfo)
+ break;
+ non_primary_binfo = b;
+ }
+
+ if (vid->ctor_vtbl_p)
+ /* For a ctor vtable we need the equivalent binfo within the hierarchy
+ where rtti_binfo is the most derived type. */
+ non_primary_binfo
+ = original_binfo (non_primary_binfo, vid->rtti_binfo);
+
+ for (base_virtuals = BINFO_VIRTUALS (binfo),
+ derived_virtuals = BINFO_VIRTUALS (non_primary_binfo),
+ orig_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
+ base_virtuals;
+ base_virtuals = TREE_CHAIN (base_virtuals),
+ derived_virtuals = TREE_CHAIN (derived_virtuals),
+ orig_virtuals = TREE_CHAIN (orig_virtuals))
+ {
+ tree orig_fn;
+
+ /* Find the declaration that originally caused this function to
+ be present in BINFO_TYPE (binfo). */
+ orig_fn = BV_FN (orig_virtuals);
+
+ /* When processing BINFO, we only want to generate vcall slots for
+ function slots introduced in BINFO. So don't try to generate
+ one if the function isn't even defined in BINFO. */
+ if (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), DECL_CONTEXT (orig_fn)))
+ continue;
+
+ add_vcall_offset (orig_fn, binfo, vid);
+ }
+ }
+}
+
+/* Add a vcall offset entry for ORIG_FN to the vtable. */
+
+static void
+add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid)
+{
+ size_t i;
+ tree vcall_offset;
+ tree derived_entry;
+
+ /* If there is already an entry for a function with the same
+ signature as FN, then we do not need a second vcall offset.
+ Check the list of functions already present in the derived
+ class vtable. */
+ FOR_EACH_VEC_SAFE_ELT (vid->fns, i, derived_entry)
+ {
+ if (same_signature_p (derived_entry, orig_fn)
+ /* We only use one vcall offset for virtual destructors,
+ even though there are two virtual table entries. */
+ || (DECL_DESTRUCTOR_P (derived_entry)
+ && DECL_DESTRUCTOR_P (orig_fn)))
+ return;
+ }
+
+ /* If we are building these vcall offsets as part of building
+ the vtable for the most derived class, remember the vcall
+ offset. */
+ if (vid->binfo == TYPE_BINFO (vid->derived))
+ {
+ tree_pair_s elt = {orig_fn, vid->index};
+ vec_safe_push (CLASSTYPE_VCALL_INDICES (vid->derived), elt);
+ }
+
+ /* The next vcall offset will be found at a more negative
+ offset. */
+ vid->index = size_binop (MINUS_EXPR, vid->index,
+ ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));
+
+ /* Keep track of this function. */
+ vec_safe_push (vid->fns, orig_fn);
+
+ if (vid->generate_vcall_entries)
+ {
+ tree base;
+ tree fn;
+
+ /* Find the overriding function. */
+ fn = find_final_overrider (vid->rtti_binfo, binfo, orig_fn);
+ if (fn == error_mark_node)
+ vcall_offset = build_zero_cst (vtable_entry_type);
+ else
+ {
+ base = TREE_VALUE (fn);
+
+ /* The vbase we're working on is a primary base of
+ vid->binfo. But it might be a lost primary, so its
+ BINFO_OFFSET might be wrong, so we just use the
+ BINFO_OFFSET from vid->binfo. */
+ vcall_offset = size_diffop_loc (input_location,
+ BINFO_OFFSET (base),
+ BINFO_OFFSET (vid->binfo));
+ vcall_offset = fold_build1_loc (input_location,
+ NOP_EXPR, vtable_entry_type,
+ vcall_offset);
+ }
+ /* Add the initializer to the vtable. */
+ CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, vcall_offset);
+ }
+}
+
+/* Return vtbl initializers for the RTTI entries corresponding to the
+ BINFO's vtable. The RTTI entries should indicate the object given
+ by VID->rtti_binfo. */
+
+static void
+build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
+{
+ tree b;
+ tree t;
+ tree offset;
+ tree decl;
+ tree init;
+
+ t = BINFO_TYPE (vid->rtti_binfo);
+
+ /* To find the complete object, we will first convert to our most
+ primary base, and then add the offset in the vtbl to that value. */
+ b = binfo;
+ while (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (b))
+ && !BINFO_LOST_PRIMARY_P (b))
+ {
+ tree primary_base;
+
+ primary_base = get_primary_binfo (b);
+ gcc_assert (BINFO_PRIMARY_P (primary_base)
+ && BINFO_INHERITANCE_CHAIN (primary_base) == b);
+ b = primary_base;
+ }
+ offset = size_diffop_loc (input_location,
+ BINFO_OFFSET (vid->rtti_binfo), BINFO_OFFSET (b));
+
+ /* The second entry is the address of the typeinfo object. */
+ if (flag_rtti)
+ decl = build_address (get_tinfo_decl (t));
+ else
+ decl = integer_zero_node;
+
+ /* Convert the declaration to a type that can be stored in the
+ vtable. */
+ init = build_nop (vfunc_ptr_type_node, decl);
+ CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init);
+
+ /* Add the offset-to-top entry. It comes earlier in the vtable than
+ the typeinfo entry. Convert the offset to look like a
+ function pointer, so that we can put it in the vtable. */
+ init = build_nop (vfunc_ptr_type_node, offset);
+ CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init);
+}
+
+/* TRUE iff TYPE is uniquely derived from PARENT. Ignores
+ accessibility. */
+
+bool
+uniquely_derived_from_p (tree parent, tree type)
+{
+ tree base = lookup_base (type, parent, ba_unique, NULL, tf_none);
+ return base && base != error_mark_node;
+}
+
+/* TRUE iff TYPE is publicly & uniquely derived from PARENT. */
+
+bool
+publicly_uniquely_derived_p (tree parent, tree type)
+{
+ tree base = lookup_base (type, parent, ba_ignore_scope | ba_check,
+ NULL, tf_none);
+ return base && base != error_mark_node;
+}
+
+/* CTX1 and CTX2 are declaration contexts. Return the innermost common
+ class between them, if any. */
+
+tree
+common_enclosing_class (tree ctx1, tree ctx2)
+{
+ if (!TYPE_P (ctx1) || !TYPE_P (ctx2))
+ return NULL_TREE;
+ gcc_assert (ctx1 == TYPE_MAIN_VARIANT (ctx1)
+ && ctx2 == TYPE_MAIN_VARIANT (ctx2));
+ if (ctx1 == ctx2)
+ return ctx1;
+ for (tree t = ctx1; TYPE_P (t); t = TYPE_CONTEXT (t))
+ TYPE_MARKED_P (t) = true;
+ tree found = NULL_TREE;
+ for (tree t = ctx2; TYPE_P (t); t = TYPE_CONTEXT (t))
+ if (TYPE_MARKED_P (t))
+ {
+ found = t;
+ break;
+ }
+ for (tree t = ctx1; TYPE_P (t); t = TYPE_CONTEXT (t))
+ TYPE_MARKED_P (t) = false;
+ return found;
+}
+
+#include "gt-cp-class.h"
diff --git a/gcc-4.9/gcc/cp/config-lang.in b/gcc-4.9/gcc/cp/config-lang.in
new file mode 100644
index 000000000..1d0b0c44d
--- /dev/null
+++ b/gcc-4.9/gcc/cp/config-lang.in
@@ -0,0 +1,32 @@
+# Top level configure fragment for GNU C++.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+#This file is part of GCC.
+
+#GCC is free software; you can redistribute it and/or modify
+#it under the terms of the GNU General Public License as published by
+#the Free Software Foundation; either version 3, or (at your option)
+#any later version.
+
+#GCC is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Configure looks for the existence of this file to auto-config each language.
+# We define several parameters used by configure:
+#
+# language - name of language as it would appear in $(LANGUAGES)
+# compilers - value to add to $(COMPILERS)
+
+language="c++"
+
+compilers="cc1plus\$(exeext)"
+
+target_libs="target-libstdc++-v3"
+
+gtfiles="\$(srcdir)/cp/rtti.c \$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.h \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/cp/typeck2.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/c-family/c-lex.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/cp/class.c \$(srcdir)/cp/cp-objcp-common.c \$(srcdir)/cp/cp-lang.c \$(srcdir)/cp/except.c \$(srcdir)/cp/vtable-class-hierarchy.c"
diff --git a/gcc-4.9/gcc/cp/cp-array-notation.c b/gcc-4.9/gcc/cp/cp-array-notation.c
new file mode 100644
index 000000000..65b8bcb81
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cp-array-notation.c
@@ -0,0 +1,1447 @@
+/* This file is part of the Intel(R) Cilk(TM) Plus support
+ It contains routines to handle Array Notation expression
+ handling routines in the C++ Compiler.
+ Copyright (C) 2013-2014 Free Software Foundation, Inc.
+ Contributed by Balaji V. Iyer <balaji.v.iyer@intel.com>,
+ Intel Corporation
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+/* The Array Notation Transformation Technique:
+
+ An array notation expression has 4 major components:
+ 1. The array name
+ 2. Start Index
+ 3. Number of elements we need to acess (we call it length)
+ 4. Stride
+
+ So, if we have something like A[0:5:2], we are accessing A[0], A[2], A[4],
+ A[6] and A[8]. The user is responsible to make sure the access length does
+ not step outside the array's size.
+
+ In this section, I highlight the overall method on how array notations are
+ broken up into C/C++ code. Almost all the functions follows this step:
+
+ Let's say the user has used the array notation in a statement like this:
+
+ A[St1:Ln:Str1] = B[St2:Ln:Str2] + <NON ARRAY_NOT STMT>
+
+ where St{1,2} = Starting index, Ln = Number of elements we need to access,
+ and Str{1,2} = the stride.
+ Note: The length of both the array notation expressions must be the same.
+
+ The above expression is broken into the following:
+
+ for (Tmp_Var = 0; Tmp_Var < Ln; Tmp_Var++)
+ A[St1 + Tmp_Var * Str1] = B[St1 + Tmp_Var * Str2] + <NON_ARRAY_NOT_STMT>;
+*/
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "cp-tree.h"
+#include "c-family/c-common.h"
+#include "diagnostic.h"
+#include "tree-iterator.h"
+#include "vec.h"
+
+/* Creates a FOR_STMT with INIT, COND, INCR and BODY as the initializer,
+ condition, increment expression and the loop-body, respectively. */
+
+static void
+create_an_loop (tree init, tree cond, tree incr, tree body)
+{
+ tree for_stmt;
+
+ finish_expr_stmt (init);
+ for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
+ finish_for_init_stmt (for_stmt);
+ finish_for_cond (cond, for_stmt, false);
+ finish_for_expr (incr, for_stmt);
+ finish_expr_stmt (body);
+ finish_for_stmt (for_stmt);
+}
+
+/* If *VALUE is not a constant integer, then this function replaces it with
+ a variable to make it loop invariant for array notations. */
+
+static inline void
+make_triplet_val_inv (tree *value)
+{
+ if (TREE_CODE (*value) != INTEGER_CST
+ && TREE_CODE (*value) != PARM_DECL
+ && TREE_CODE (*value) != VAR_DECL)
+ *value = get_temp_regvar (ptrdiff_type_node, *value);
+}
+
+/* Returns a vector of size RANK that contains an ARRAY_REF. This vector is
+ created using array notation-triplet information stored in AN_INFO. The
+ induction var is taken from AN_LOOP_INFO.
+
+ For example: For an array notation A[5:10:2], the vector start will be
+ of size 1 holding '5', stride of same size as start but holding the value of
+ as 2, and is_vector as true. Let's assume VAR is 'x'
+ This function returns a vector of size 1 with the following data:
+ A[5 + (x * 2)] .
+*/
+
+static vec<tree, va_gc> *
+create_array_refs (location_t loc, vec<vec<an_parts> > an_info,
+ vec<an_loop_parts> an_loop_info, size_t size, size_t rank)
+{
+ tree ind_mult, ind_incr;
+ vec<tree, va_gc> *array_operand = NULL;
+
+ for (size_t ii = 0; ii < size; ii++)
+ if (an_info[ii][0].is_vector)
+ {
+ tree array_opr = an_info[ii][rank - 1].value;
+ for (int s_jj = rank -1; s_jj >= 0; s_jj--)
+ {
+ tree start = cp_fold_convert (ptrdiff_type_node,
+ an_info[ii][s_jj].start);
+ tree stride = cp_fold_convert (ptrdiff_type_node,
+ an_info[ii][s_jj].stride);
+ tree var = cp_fold_convert (ptrdiff_type_node,
+ an_loop_info[s_jj].var);
+
+ ind_mult = build2 (MULT_EXPR, TREE_TYPE (var), var, stride);
+ ind_incr = build2 (PLUS_EXPR, TREE_TYPE (var), start, ind_mult);
+ /* Array [ start_index + (induction_var * stride)] */
+ array_opr = grok_array_decl (loc, array_opr, ind_incr, false);
+ }
+ vec_safe_push (array_operand, array_opr);
+ }
+ else
+ vec_safe_push (array_operand, integer_one_node);
+ return array_operand;
+}
+
+/* Populates the INCR and CMP fields in *NODE with the increment
+ (of type POSTINCREMENT) and comparison (of TYPE LT_EXPR) expressions, using
+ data from AN_INFO. */
+
+void
+create_cmp_incr (location_t loc, vec <an_loop_parts> *node, size_t rank,
+ vec<vec<an_parts> > an_info, tsubst_flags_t complain)
+{
+ for (size_t ii = 0; ii < rank; ii++)
+ {
+ (*node)[ii].incr = build_x_unary_op (loc, POSTINCREMENT_EXPR,
+ (*node)[ii].var, complain);
+ (*node)[ii].cmp = build_x_binary_op (loc, LT_EXPR, (*node)[ii].var,
+ TREE_CODE ((*node)[ii].var),
+ an_info[0][ii].length,
+ TREE_CODE (an_info[0][ii].length),
+ NULL, complain);
+ }
+}
+
+/* Replaces all the scalar expressions in *NODE. Returns a STATEMENT LIST that
+ holds the NODE along with the variables that hold the results of the
+ invariant expressions. */
+
+static tree
+replace_invariant_exprs (tree *node)
+{
+ size_t ix = 0;
+ tree node_list = NULL_TREE;
+ tree t = NULL_TREE, new_var = NULL_TREE;
+ struct inv_list data;
+
+ data.list_values = NULL;
+ data.replacement = NULL;
+ data.additional_tcodes = NULL;
+ cp_walk_tree (node, find_inv_trees, (void *) &data, NULL);
+
+ if (vec_safe_length (data.list_values))
+ {
+ node_list = push_stmt_list ();
+ for (ix = 0; vec_safe_iterate (data.list_values, ix, &t); ix++)
+ {
+ /* Sometimes, when comma_expr has a function call in it, it will
+ typecast it to void. Find_inv_trees finds those nodes and so
+ if it void type, then don't bother creating a new var to hold
+ the return value. */
+ if (VOID_TYPE_P (TREE_TYPE (t)))
+ {
+ finish_expr_stmt (t);
+ new_var = void_zero_node;
+ }
+ else
+ new_var = get_temp_regvar (TREE_TYPE (t), t);
+ vec_safe_push (data.replacement, new_var);
+ }
+ cp_walk_tree (node, replace_inv_trees, (void *) &data, NULL);
+ node_list = pop_stmt_list (node_list);
+ }
+ return node_list;
+}
+
+/* Replace array notation's built-in function passed in AN_BUILTIN_FN with
+ the appropriate loop and computation (all stored in variable LOOP of type
+ tree node). The output of the function function is always a scalar and that
+ result is returned in *NEW_VAR. *NEW_VAR is NULL_TREE if the function is
+ __sec_reduce_mutating. */
+
+static tree
+expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
+{
+ tree new_var_type = NULL_TREE, func_parm, new_yes_expr, new_no_expr;
+ tree array_ind_value = NULL_TREE, new_no_ind, new_yes_ind, new_no_list;
+ tree new_yes_list, new_cond_expr, new_expr = NULL_TREE;
+ vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
+ size_t list_size = 0, rank = 0, ii = 0;
+ tree body, an_init, loop_with_init = alloc_stmt_list ();
+ tree array_op0, comp_node = NULL_TREE;
+ tree call_fn = NULL_TREE, identity_value = NULL_TREE;
+ tree init = NULL_TREE, cond_init = NULL_TREE;
+ enum tree_code code = NOP_EXPR;
+ location_t location = UNKNOWN_LOCATION;
+ vec<vec<an_parts> > an_info = vNULL;
+ vec<an_loop_parts> an_loop_info = vNULL;
+ enum built_in_function an_type =
+ is_cilkplus_reduce_builtin (CALL_EXPR_FN (an_builtin_fn));
+ vec <tree, va_gc> *func_args;
+
+ if (an_type == BUILT_IN_NONE)
+ return NULL_TREE;
+
+ if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE
+ && an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
+ func_parm = CALL_EXPR_ARG (an_builtin_fn, 0);
+ else
+ {
+ call_fn = CALL_EXPR_ARG (an_builtin_fn, 2);
+
+ /* We need to do this because we are "faking" the builtin function types,
+ so the compiler does a bunch of typecasts and this will get rid of
+ all that! */
+ STRIP_NOPS (call_fn);
+ if (TREE_CODE (call_fn) != OVERLOAD
+ && TREE_CODE (call_fn) != FUNCTION_DECL)
+ call_fn = TREE_OPERAND (call_fn, 0);
+ identity_value = CALL_EXPR_ARG (an_builtin_fn, 0);
+ func_parm = CALL_EXPR_ARG (an_builtin_fn, 1);
+ STRIP_NOPS (identity_value);
+ }
+ STRIP_NOPS (func_parm);
+
+ location = EXPR_LOCATION (an_builtin_fn);
+
+ /* Note about using find_rank (): If find_rank returns false, then it must
+ have already reported an error, thus we just return an error_mark_node
+ without any doing any error emission. */
+ if (!find_rank (location, an_builtin_fn, an_builtin_fn, true, &rank))
+ return error_mark_node;
+ if (rank == 0)
+ return an_builtin_fn;
+ else if (rank > 1
+ && (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
+ || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND))
+ {
+ error_at (location, "__sec_reduce_min_ind or __sec_reduce_max_ind cannot "
+ "have arrays with dimension greater than 1");
+ return error_mark_node;
+ }
+
+ extract_array_notation_exprs (func_parm, true, &array_list);
+ list_size = vec_safe_length (array_list);
+ switch (an_type)
+ {
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUL:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN:
+ new_var_type = TREE_TYPE ((*array_list)[0]);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
+ new_var_type = boolean_type_node;
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
+ new_var_type = size_type_node;
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE:
+ if (call_fn && identity_value)
+ new_var_type = TREE_TYPE ((*array_list)[0]);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING:
+ new_var_type = NULL_TREE;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (new_var_type && TREE_CODE (new_var_type) == ARRAY_TYPE)
+ new_var_type = TREE_TYPE (new_var_type);
+ an_loop_info.safe_grow_cleared (rank);
+
+ an_init = push_stmt_list ();
+
+ /* Assign the array notation components to variable so that they can satisfy
+ the exec-once rule. */
+ for (ii = 0; ii < list_size; ii++)
+ if (TREE_CODE ((*array_list)[ii]) == ARRAY_NOTATION_REF)
+ {
+ tree anode = (*array_list)[ii];
+ make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
+ }
+ cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
+ for (ii = 0; ii < rank; ii++)
+ {
+ tree typ = ptrdiff_type_node;
+
+ /* In this place, we are using get_temp_regvar instead of
+ create_temporary_var if an_type is SEC_REDUCE_MAX/MIN_IND because
+ the array_ind_value depends on this value being initalized to 0. */
+ if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
+ || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
+ an_loop_info[ii].var = get_temp_regvar (typ, build_zero_cst (typ));
+ else
+ {
+ an_loop_info[ii].var = create_temporary_var (typ);
+ add_decl_expr (an_loop_info[ii].var);
+ }
+ an_loop_info[ii].ind_init =
+ build_x_modify_expr (location, an_loop_info[ii].var, INIT_EXPR,
+ build_zero_cst (typ), tf_warning_or_error);
+ }
+ array_operand = create_array_refs (location, an_info, an_loop_info,
+ list_size, rank);
+ replace_array_notations (&func_parm, true, array_list, array_operand);
+
+ if (!TREE_TYPE (func_parm))
+ TREE_TYPE (func_parm) = TREE_TYPE ((*array_list)[0]);
+
+ create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
+ if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
+ || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
+ array_ind_value = get_temp_regvar (TREE_TYPE (func_parm), func_parm);
+
+ array_op0 = (*array_operand)[0];
+ switch (an_type)
+ {
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD:
+ code = PLUS_EXPR;
+ init = build_zero_cst (new_var_type);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUL:
+ code = MULT_EXPR;
+ init = build_one_cst (new_var_type);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
+ code = ((an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO) ? EQ_EXPR
+ : NE_EXPR);
+ init = build_zero_cst (new_var_type);
+ cond_init = build_one_cst (new_var_type);
+ comp_node = build_zero_cst (TREE_TYPE (func_parm));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
+ code = ((an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO) ? NE_EXPR
+ : EQ_EXPR);
+ init = build_one_cst (new_var_type);
+ cond_init = build_zero_cst (new_var_type);
+ comp_node = build_zero_cst (TREE_TYPE (func_parm));
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX:
+ code = MAX_EXPR;
+ init = (TYPE_MIN_VALUE (new_var_type) ? TYPE_MIN_VALUE (new_var_type)
+ : func_parm);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN:
+ code = MIN_EXPR;
+ init = (TYPE_MAX_VALUE (new_var_type) ? TYPE_MAX_VALUE (new_var_type)
+ : func_parm);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
+ code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND ? LE_EXPR
+ : GE_EXPR);
+ init = an_loop_info[0].var;
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE:
+ init = identity_value;
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING:
+ init = NULL_TREE;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
+ *new_var = get_temp_regvar (new_var_type, init);
+ else
+ *new_var = NULL_TREE;
+
+ switch (an_type)
+ {
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUL:
+ new_expr = build_x_modify_expr (location, *new_var, code, func_parm,
+ tf_warning_or_error);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
+ /* In all these cases, assume the false case is true and as soon as
+ we find a true case, set the true flag on and latch it in. */
+ new_yes_expr = build_x_modify_expr (location, *new_var, NOP_EXPR,
+ cond_init, tf_warning_or_error);
+ new_no_expr = build_x_modify_expr (location, *new_var, NOP_EXPR,
+ *new_var, tf_warning_or_error);
+ new_cond_expr = build_x_binary_op
+ (location, code, func_parm, TREE_CODE (func_parm), comp_node,
+ TREE_CODE (comp_node), NULL, tf_warning_or_error);
+ new_expr = build_x_conditional_expr (location, new_cond_expr,
+ new_yes_expr, new_no_expr,
+ tf_warning_or_error);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN:
+ new_cond_expr = build_x_binary_op
+ (location, code, *new_var, TREE_CODE (*new_var), func_parm,
+ TREE_CODE (func_parm), NULL, tf_warning_or_error);
+ new_expr = build_x_modify_expr (location, *new_var, NOP_EXPR, func_parm,
+ tf_warning_or_error);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
+ new_yes_expr = build_x_modify_expr (location, array_ind_value, NOP_EXPR,
+ func_parm, tf_warning_or_error);
+ new_no_expr = build_x_modify_expr (location, array_ind_value, NOP_EXPR,
+ array_ind_value, tf_warning_or_error);
+ if (list_size > 1)
+ new_yes_ind = build_x_modify_expr (location, *new_var, NOP_EXPR,
+ an_loop_info[0].var,
+ tf_warning_or_error);
+ else
+ new_yes_ind = build_x_modify_expr (location, *new_var, NOP_EXPR,
+ TREE_OPERAND (array_op0, 1),
+ tf_warning_or_error);
+ new_no_ind = build_x_modify_expr (location, *new_var, NOP_EXPR, *new_var,
+ tf_warning_or_error);
+ new_yes_list = alloc_stmt_list ();
+ append_to_statement_list (new_yes_ind, &new_yes_list);
+ append_to_statement_list (new_yes_expr, &new_yes_list);
+
+ new_no_list = alloc_stmt_list ();
+ append_to_statement_list (new_no_ind, &new_no_list);
+ append_to_statement_list (new_no_expr, &new_no_list);
+
+ new_cond_expr = build_x_binary_op (location, code, array_ind_value,
+ TREE_CODE (array_ind_value), func_parm,
+ TREE_CODE (func_parm), NULL,
+ tf_warning_or_error);
+ new_expr = build_x_conditional_expr (location, new_cond_expr,
+ new_yes_list, new_no_list,
+ tf_warning_or_error);
+ break;
+ case BUILT_IN_CILKPLUS_SEC_REDUCE:
+ case BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING:
+ func_args = make_tree_vector ();
+ if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE)
+ vec_safe_push (func_args, *new_var);
+ else
+ vec_safe_push (func_args, identity_value);
+ vec_safe_push (func_args, func_parm);
+
+ new_expr = finish_call_expr (call_fn, &func_args, false, true,
+ tf_warning_or_error);
+ if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE)
+ new_expr = build_x_modify_expr (location, *new_var, NOP_EXPR, new_expr,
+ tf_warning_or_error);
+ release_tree_vector (func_args);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ an_init = pop_stmt_list (an_init);
+ append_to_statement_list (an_init, &loop_with_init);
+ body = new_expr;
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ tree new_loop = push_stmt_list ();
+ create_an_loop (an_loop_info[ii].ind_init, an_loop_info[ii].cmp,
+ an_loop_info[ii].incr, body);
+ body = pop_stmt_list (new_loop);
+ }
+ append_to_statement_list (body, &loop_with_init);
+
+ an_info.release ();
+ an_loop_info.release ();
+
+ return loop_with_init;
+}
+
+/* Returns a loop with ARRAY_REF inside it with an appropriate modify expr.
+ The LHS and/or RHS will be array notation expressions that have a
+ MODIFYCODE. The location of the variable is specified by LOCATION. */
+
+static tree
+expand_an_in_modify_expr (location_t location, tree lhs,
+ enum tree_code modifycode, tree rhs,
+ tsubst_flags_t complain)
+{
+ tree array_expr_lhs = NULL_TREE, array_expr_rhs = NULL_TREE;
+ tree array_expr = NULL_TREE;
+ tree body = NULL_TREE;
+ vec<tree> cond_expr = vNULL;
+ vec<tree, va_gc> *lhs_array_operand = NULL, *rhs_array_operand = NULL;
+ size_t lhs_rank = 0, rhs_rank = 0, ii = 0;
+ vec<tree, va_gc> *rhs_list = NULL, *lhs_list = NULL;
+ size_t rhs_list_size = 0, lhs_list_size = 0;
+ tree new_modify_expr, new_var = NULL_TREE, builtin_loop, scalar_mods;
+ bool found_builtin_fn = false;
+ tree an_init, loop_with_init = alloc_stmt_list ();
+ vec<vec<an_parts> > lhs_an_info = vNULL, rhs_an_info = vNULL;
+ vec<an_loop_parts> lhs_an_loop_info = vNULL, rhs_an_loop_info = vNULL;
+
+ if (!find_rank (location, rhs, rhs, false, &rhs_rank))
+ return error_mark_node;
+ extract_array_notation_exprs (rhs, false, &rhs_list);
+ rhs_list_size = vec_safe_length (rhs_list);
+ an_init = push_stmt_list ();
+ if (rhs_rank)
+ {
+ scalar_mods = replace_invariant_exprs (&rhs);
+ if (scalar_mods)
+ finish_expr_stmt (scalar_mods);
+ }
+ for (ii = 0; ii < rhs_list_size; ii++)
+ {
+ tree rhs_node = (*rhs_list)[ii];
+ if (TREE_CODE (rhs_node) == CALL_EXPR)
+ {
+ builtin_loop = expand_sec_reduce_builtin (rhs_node, &new_var);
+ if (builtin_loop == error_mark_node)
+ return error_mark_node;
+ else if (builtin_loop)
+ {
+ finish_expr_stmt (builtin_loop);
+ found_builtin_fn = true;
+ if (new_var)
+ {
+ vec <tree, va_gc> *rhs_sub_list = NULL, *new_var_list = NULL;
+ vec_safe_push (rhs_sub_list, rhs_node);
+ vec_safe_push (new_var_list, new_var);
+ replace_array_notations (&rhs, false, rhs_sub_list,
+ new_var_list);
+ }
+ }
+ }
+ }
+ lhs_rank = 0;
+ rhs_rank = 0;
+ if (!find_rank (location, lhs, lhs, true, &lhs_rank)
+ || !find_rank (location, rhs, rhs, true, &rhs_rank))
+ {
+ pop_stmt_list (an_init);
+ return error_mark_node;
+ }
+
+ /* If both are scalar, then the only reason why we will get this far is if
+ there is some array notations inside it and was using a builtin array
+ notation functions. If so, we have already broken those guys up and now
+ a simple build_x_modify_expr would do. */
+ if (lhs_rank == 0 && rhs_rank == 0)
+ {
+ if (found_builtin_fn)
+ {
+ new_modify_expr = build_x_modify_expr (location, lhs,
+ modifycode, rhs, complain);
+ finish_expr_stmt (new_modify_expr);
+ pop_stmt_list (an_init);
+ return an_init;
+ }
+ else
+ gcc_unreachable ();
+ }
+
+ /* If for some reason location is not set, then find if LHS or RHS has
+ location info. If so, then use that so we atleast have an idea. */
+ if (location == UNKNOWN_LOCATION)
+ {
+ if (EXPR_LOCATION (lhs) != UNKNOWN_LOCATION)
+ location = EXPR_LOCATION (lhs);
+ else if (EXPR_LOCATION (rhs) != UNKNOWN_LOCATION)
+ location = EXPR_LOCATION (rhs);
+ }
+
+ /* We need this when we have a scatter issue. */
+ extract_array_notation_exprs (lhs, true, &lhs_list);
+ rhs_list = NULL;
+ extract_array_notation_exprs (rhs, true, &rhs_list);
+ rhs_list_size = vec_safe_length (rhs_list);
+ lhs_list_size = vec_safe_length (lhs_list);
+
+ if (lhs_rank == 0 && rhs_rank != 0)
+ {
+ error_at (location, "%qD cannot be scalar when %qD is not", lhs, rhs);
+ return error_mark_node;
+ }
+ if (lhs_rank != 0 && rhs_rank != 0 && lhs_rank != rhs_rank)
+ {
+ error_at (location, "rank mismatch between %qE and %qE", lhs, rhs);
+ return error_mark_node;
+ }
+
+ /* Assign the array notation components to variable so that they can satisfy
+ the execute-once rule. */
+ for (ii = 0; ii < lhs_list_size; ii++)
+ {
+ tree anode = (*lhs_list)[ii];
+ make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
+ }
+ for (ii = 0; ii < rhs_list_size; ii++)
+ if ((*rhs_list)[ii] && TREE_CODE ((*rhs_list)[ii]) == ARRAY_NOTATION_REF)
+ {
+ tree aa = (*rhs_list)[ii];
+ make_triplet_val_inv (&ARRAY_NOTATION_START (aa));
+ make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (aa));
+ make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (aa));
+ }
+ lhs_an_loop_info.safe_grow_cleared (lhs_rank);
+
+ if (rhs_rank)
+ rhs_an_loop_info.safe_grow_cleared (rhs_rank);
+
+ cond_expr.safe_grow_cleared (MAX (lhs_rank, rhs_rank));
+ cilkplus_extract_an_triplets (lhs_list, lhs_list_size, lhs_rank,
+ &lhs_an_info);
+ if (rhs_list)
+ cilkplus_extract_an_triplets (rhs_list, rhs_list_size, rhs_rank,
+ &rhs_an_info);
+ if (length_mismatch_in_expr_p (EXPR_LOCATION (lhs), lhs_an_info)
+ || (rhs_list && length_mismatch_in_expr_p (EXPR_LOCATION (rhs),
+ rhs_an_info)))
+ {
+ pop_stmt_list (an_init);
+ return error_mark_node;
+ }
+ tree rhs_len = ((rhs_list_size > 0 && rhs_rank > 0) ?
+ rhs_an_info[0][0].length : NULL_TREE);
+ tree lhs_len = ((lhs_list_size > 0 && lhs_rank > 0) ?
+ lhs_an_info[0][0].length : NULL_TREE);
+ if (lhs_list_size > 0 && rhs_list_size > 0 && lhs_rank > 0 && rhs_rank > 0
+ && TREE_CODE (lhs_len) == INTEGER_CST && rhs_len
+ && TREE_CODE (rhs_len) == INTEGER_CST
+ && !tree_int_cst_equal (rhs_len, lhs_len))
+ {
+ error_at (location, "length mismatch between LHS and RHS");
+ pop_stmt_list (an_init);
+ return error_mark_node;
+ }
+ for (ii = 0; ii < lhs_rank; ii++)
+ {
+ tree typ = ptrdiff_type_node;
+ lhs_an_loop_info[ii].var = create_temporary_var (typ);
+ add_decl_expr (lhs_an_loop_info[ii].var);
+ lhs_an_loop_info[ii].ind_init = build_x_modify_expr
+ (location, lhs_an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ),
+ complain);
+ }
+
+ if (rhs_list_size > 0)
+ {
+ rhs_array_operand = fix_sec_implicit_args (location, rhs_list,
+ lhs_an_loop_info, lhs_rank,
+ lhs);
+ if (!rhs_array_operand)
+ return error_mark_node;
+ }
+ replace_array_notations (&rhs, true, rhs_list, rhs_array_operand);
+ rhs_list_size = 0;
+ rhs_list = NULL;
+ extract_array_notation_exprs (rhs, true, &rhs_list);
+ rhs_list_size = vec_safe_length (rhs_list);
+
+ for (ii = 0; ii < rhs_rank; ii++)
+ {
+ tree typ = ptrdiff_type_node;
+ rhs_an_loop_info[ii].var = create_temporary_var (typ);
+ add_decl_expr (rhs_an_loop_info[ii].var);
+ rhs_an_loop_info[ii].ind_init = build_x_modify_expr
+ (location, rhs_an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ),
+ complain);
+ }
+
+ if (lhs_rank)
+ {
+ lhs_array_operand =
+ create_array_refs (location, lhs_an_info, lhs_an_loop_info,
+ lhs_list_size, lhs_rank);
+ replace_array_notations (&lhs, true, lhs_list, lhs_array_operand);
+ }
+
+ if (rhs_array_operand)
+ vec_safe_truncate (rhs_array_operand, 0);
+ if (rhs_rank)
+ {
+ rhs_array_operand = create_array_refs (location, rhs_an_info,
+ rhs_an_loop_info, rhs_list_size,
+ rhs_rank);
+ /* Replace all the array refs created by the above function because this
+ variable is blown away by the fix_sec_implicit_args function below. */
+ replace_array_notations (&rhs, true, rhs_list, rhs_array_operand);
+ vec_safe_truncate (rhs_array_operand , 0);
+ rhs_array_operand = fix_sec_implicit_args (location, rhs_list,
+ rhs_an_loop_info, rhs_rank,
+ rhs);
+ if (!rhs_array_operand)
+ return error_mark_node;
+ replace_array_notations (&rhs, true, rhs_list, rhs_array_operand);
+ }
+
+ array_expr_rhs = rhs;
+ array_expr_lhs = lhs;
+
+ array_expr = build_x_modify_expr (location, array_expr_lhs, modifycode,
+ array_expr_rhs, complain);
+ create_cmp_incr (location, &lhs_an_loop_info, lhs_rank, lhs_an_info,
+ complain);
+ if (rhs_rank)
+ create_cmp_incr (location, &rhs_an_loop_info, rhs_rank, rhs_an_info,
+ complain);
+ for (ii = 0; ii < MAX (rhs_rank, lhs_rank); ii++)
+ if (ii < lhs_rank && ii < rhs_rank)
+ cond_expr[ii] = build_x_binary_op
+ (location, TRUTH_ANDIF_EXPR, lhs_an_loop_info[ii].cmp,
+ TREE_CODE (lhs_an_loop_info[ii].cmp), rhs_an_loop_info[ii].cmp,
+ TREE_CODE (rhs_an_loop_info[ii].cmp), NULL, complain);
+ else if (ii < lhs_rank && ii >= rhs_rank)
+ cond_expr[ii] = lhs_an_loop_info[ii].cmp;
+ else
+ /* No need to compare ii < rhs_rank && ii >= lhs_rank because in a valid
+ Array notation expression, rank of RHS cannot be greater than LHS. */
+ gcc_unreachable ();
+
+ an_init = pop_stmt_list (an_init);
+ append_to_statement_list (an_init, &loop_with_init);
+ body = array_expr;
+ for (ii = 0; ii < MAX (lhs_rank, rhs_rank); ii++)
+ {
+ tree incr_list = alloc_stmt_list ();
+ tree init_list = alloc_stmt_list ();
+ tree new_loop = push_stmt_list ();
+
+ if (lhs_rank)
+ {
+ append_to_statement_list (lhs_an_loop_info[ii].ind_init, &init_list);
+ append_to_statement_list (lhs_an_loop_info[ii].incr, &incr_list);
+ }
+ if (rhs_rank)
+ {
+ append_to_statement_list (rhs_an_loop_info[ii].ind_init, &init_list);
+ append_to_statement_list (rhs_an_loop_info[ii].incr, &incr_list);
+ }
+ create_an_loop (init_list, cond_expr[ii], incr_list, body);
+ body = pop_stmt_list (new_loop);
+ }
+ append_to_statement_list (body, &loop_with_init);
+
+ lhs_an_info.release ();
+ lhs_an_loop_info.release ();
+ if (rhs_rank)
+ {
+ rhs_an_info.release ();
+ rhs_an_loop_info.release ();
+ }
+ cond_expr.release ();
+
+ return loop_with_init;
+}
+
+/* Helper function for expand_conditonal_array_notations. Encloses the
+ conditional statement passed in ORIG_STMT with a loop around it and
+ replaces the condition in STMT with a ARRAY_REF tree-node to the array.
+ The condition must have a ARRAY_NOTATION_REF tree. */
+
+static tree
+cp_expand_cond_array_notations (tree orig_stmt)
+{
+ vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
+ size_t list_size = 0;
+ size_t rank = 0, ii = 0;
+ tree an_init, body, stmt = NULL_TREE;
+ tree builtin_loop, new_var = NULL_TREE;
+ tree loop_with_init = alloc_stmt_list ();
+ location_t location = UNKNOWN_LOCATION;
+ vec<vec<an_parts> > an_info = vNULL;
+ vec<an_loop_parts> an_loop_info = vNULL;
+
+ if (TREE_CODE (orig_stmt) == COND_EXPR)
+ {
+ size_t cond_rank = 0, yes_rank = 0, no_rank = 0;
+ tree yes_expr = COND_EXPR_THEN (orig_stmt);
+ tree no_expr = COND_EXPR_ELSE (orig_stmt);
+ tree cond = COND_EXPR_COND (orig_stmt);
+ if (!find_rank (EXPR_LOCATION (cond), cond, cond, true, &cond_rank)
+ || !find_rank (EXPR_LOCATION (yes_expr), yes_expr, yes_expr, true,
+ &yes_rank)
+ || find_rank (EXPR_LOCATION (no_expr), no_expr, no_expr, true,
+ &no_rank))
+ return error_mark_node;
+ /* If the condition has a zero rank, then handle array notations in body
+ separately. */
+ if (cond_rank == 0)
+ return orig_stmt;
+ if (cond_rank != yes_rank && yes_rank != 0)
+ {
+ error_at (EXPR_LOCATION (yes_expr), "rank mismatch with controlling"
+ " expression of parent if-statement");
+ return error_mark_node;
+ }
+ else if (cond_rank != no_rank && no_rank != 0)
+ {
+ error_at (EXPR_LOCATION (no_expr), "rank mismatch with controlling "
+ "expression of parent if-statement");
+ return error_mark_node;
+ }
+ }
+ else if (TREE_CODE (orig_stmt) == IF_STMT)
+ {
+ size_t cond_rank = 0, yes_rank = 0, no_rank = 0;
+ tree yes_expr = THEN_CLAUSE (orig_stmt);
+ tree no_expr = ELSE_CLAUSE (orig_stmt);
+ tree cond = IF_COND (orig_stmt);
+ if (!find_rank (EXPR_LOCATION (cond), cond, cond, true, &cond_rank)
+ || (yes_expr
+ && !find_rank (EXPR_LOCATION (yes_expr), yes_expr, yes_expr, true,
+ &yes_rank))
+ || (no_expr
+ && !find_rank (EXPR_LOCATION (no_expr), no_expr, no_expr, true,
+ &no_rank)))
+ return error_mark_node;
+
+ /* Same reasoning as for COND_EXPR. */
+ if (cond_rank == 0)
+ return orig_stmt;
+ else if (cond_rank != yes_rank && yes_rank != 0)
+ {
+ error_at (EXPR_LOCATION (yes_expr), "rank mismatch with controlling"
+ " expression of parent if-statement");
+ return error_mark_node;
+ }
+ else if (cond_rank != no_rank && no_rank != 0)
+ {
+ error_at (EXPR_LOCATION (no_expr), "rank mismatch with controlling "
+ "expression of parent if-statement");
+ return error_mark_node;
+ }
+ }
+ else if (truth_value_p (TREE_CODE (orig_stmt)))
+ {
+ size_t left_rank = 0, right_rank = 0;
+ tree left_expr = TREE_OPERAND (orig_stmt, 0);
+ tree right_expr = TREE_OPERAND (orig_stmt, 1);
+ if (!find_rank (EXPR_LOCATION (left_expr), left_expr, left_expr, true,
+ &left_rank)
+ || !find_rank (EXPR_LOCATION (right_expr), right_expr, right_expr,
+ true, &right_rank))
+ return error_mark_node;
+ if (right_rank == 0 && left_rank == 0)
+ return orig_stmt;
+ }
+
+ if (!find_rank (EXPR_LOCATION (orig_stmt), orig_stmt, orig_stmt, true,
+ &rank))
+ return error_mark_node;
+ if (rank == 0)
+ return orig_stmt;
+
+ extract_array_notation_exprs (orig_stmt, false, &array_list);
+ stmt = alloc_stmt_list ();
+ for (ii = 0; ii < vec_safe_length (array_list); ii++)
+ {
+ tree array_node = (*array_list)[ii];
+ if (TREE_CODE (array_node) == CALL_EXPR
+ || TREE_CODE (array_node) == AGGR_INIT_EXPR)
+ {
+ builtin_loop = expand_sec_reduce_builtin (array_node, &new_var);
+ if (builtin_loop == error_mark_node)
+ finish_expr_stmt (error_mark_node);
+ else if (new_var)
+ {
+ vec<tree, va_gc> *sub_list = NULL, *new_var_list = NULL;
+ vec_safe_push (sub_list, array_node);
+ vec_safe_push (new_var_list, new_var);
+ replace_array_notations (&orig_stmt, false, sub_list,
+ new_var_list);
+ append_to_statement_list (builtin_loop, &stmt);
+ }
+ }
+ }
+ append_to_statement_list (orig_stmt, &stmt);
+ rank = 0;
+ array_list = NULL;
+ if (!find_rank (EXPR_LOCATION (stmt), stmt, stmt, true, &rank))
+ return error_mark_node;
+ if (rank == 0)
+ return stmt;
+
+ extract_array_notation_exprs (stmt, true, &array_list);
+ list_size = vec_safe_length (array_list);
+ if (list_size == 0)
+ return stmt;
+
+ location = EXPR_LOCATION (orig_stmt);
+ list_size = vec_safe_length (array_list);
+ an_loop_info.safe_grow_cleared (rank);
+
+ an_init = push_stmt_list ();
+
+ /* Assign the array notation components to variable so that they can
+ satisfy the exec-once rule. */
+ for (ii = 0; ii < list_size; ii++)
+ {
+ tree anode = (*array_list)[ii];
+ make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
+ make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
+ }
+ cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ tree typ = ptrdiff_type_node;
+ an_loop_info[ii].var = create_temporary_var (typ);
+ add_decl_expr (an_loop_info[ii].var);
+ an_loop_info[ii].ind_init =
+ build_x_modify_expr (location, an_loop_info[ii].var, INIT_EXPR,
+ build_zero_cst (typ), tf_warning_or_error);
+ }
+ array_operand = create_array_refs (location, an_info, an_loop_info,
+ list_size, rank);
+ replace_array_notations (&stmt, true, array_list, array_operand);
+ create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
+
+ an_init = pop_stmt_list (an_init);
+ append_to_statement_list (an_init, &loop_with_init);
+ body = stmt;
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ tree new_loop = push_stmt_list ();
+ create_an_loop (an_loop_info[ii].ind_init, an_loop_info[ii].cmp,
+ an_loop_info[ii].incr, body);
+ body = pop_stmt_list (new_loop);
+ }
+ append_to_statement_list (body, &loop_with_init);
+
+ an_info.release ();
+ an_loop_info.release ();
+
+ return loop_with_init;
+}
+
+/* Transforms array notations inside unary expression ORIG_STMT with an
+ appropriate loop and ARRAY_REF (and returns all this as a super-tree called
+ LOOP). */
+
+static tree
+expand_unary_array_notation_exprs (tree orig_stmt)
+{
+ vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
+ size_t list_size = 0, rank = 0, ii = 0;
+ tree body;
+ tree builtin_loop, stmt = NULL_TREE, new_var = NULL_TREE;
+ location_t location = EXPR_LOCATION (orig_stmt);
+ tree an_init, loop_with_init = alloc_stmt_list ();
+ vec<vec<an_parts> > an_info = vNULL;
+ vec<an_loop_parts> an_loop_info = vNULL;
+
+ if (!find_rank (location, orig_stmt, orig_stmt, true, &rank))
+ return error_mark_node;
+ if (rank == 0)
+ return orig_stmt;
+
+ extract_array_notation_exprs (orig_stmt, false, &array_list);
+ list_size = vec_safe_length (array_list);
+ location = EXPR_LOCATION (orig_stmt);
+ stmt = NULL_TREE;
+ for (ii = 0; ii < list_size; ii++)
+ if (TREE_CODE ((*array_list)[ii]) == CALL_EXPR
+ || TREE_CODE ((*array_list)[ii]) == AGGR_INIT_EXPR)
+ {
+ tree list_node = (*array_list)[ii];
+ builtin_loop = expand_sec_reduce_builtin (list_node, &new_var);
+ if (builtin_loop == error_mark_node)
+ return error_mark_node;
+ else if (builtin_loop)
+ {
+ vec<tree, va_gc> *sub_list = NULL, *new_var_list = NULL;
+ stmt = alloc_stmt_list ();
+ append_to_statement_list (builtin_loop, &stmt);
+ vec_safe_push (sub_list, list_node);
+ vec_safe_push (new_var_list, new_var);
+ replace_array_notations (&orig_stmt, false, sub_list, new_var_list);
+ }
+ }
+ if (stmt != NULL_TREE)
+ append_to_statement_list (finish_expr_stmt (orig_stmt), &stmt);
+ else
+ stmt = orig_stmt;
+ rank = 0;
+ list_size = 0;
+ array_list = NULL;
+ extract_array_notation_exprs (stmt, true, &array_list);
+ list_size = vec_safe_length (array_list);
+
+ if (!find_rank (EXPR_LOCATION (stmt), stmt, stmt, true, &rank))
+ return error_mark_node;
+ if (rank == 0 || list_size == 0)
+ return stmt;
+ an_loop_info.safe_grow_cleared (rank);
+ an_init = push_stmt_list ();
+ /* Assign the array notation components to variable so that they can satisfy
+ the exec-once rule. */
+ for (ii = 0; ii < list_size; ii++)
+ {
+ tree array_node = (*array_list)[ii];
+ make_triplet_val_inv (&ARRAY_NOTATION_START (array_node));
+ make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (array_node));
+ make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (array_node));
+ }
+ cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ tree typ = ptrdiff_type_node;
+ an_loop_info[ii].var = create_temporary_var (typ);
+ add_decl_expr (an_loop_info[ii].var);
+ an_loop_info[ii].ind_init = build_x_modify_expr
+ (location, an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ),
+ tf_warning_or_error);
+ }
+ array_operand = create_array_refs (location, an_info, an_loop_info,
+ list_size, rank);
+ replace_array_notations (&stmt, true, array_list, array_operand);
+ create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
+
+ an_init = pop_stmt_list (an_init);
+ append_to_statement_list (an_init, &loop_with_init);
+ body = stmt;
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ tree new_loop = push_stmt_list ();
+ create_an_loop (an_loop_info[ii].ind_init, an_loop_info[ii].cmp,
+ an_loop_info[ii].incr, body);
+ body = pop_stmt_list (new_loop);
+ }
+ append_to_statement_list (body, &loop_with_init);
+
+ an_info.release ();
+ an_loop_info.release ();
+
+ return loop_with_init;
+}
+
+/* Expands the array notation's builtin reduction function in EXPR
+ (of type RETURN_EXPR) and returns a STATEMENT_LIST that contains a loop
+ with the builtin function expansion and a return statement at the end. */
+
+static tree
+expand_return_expr (tree expr)
+{
+ tree new_mod_list, new_var, new_mod, retval_expr;
+ size_t rank = 0;
+ location_t loc = EXPR_LOCATION (expr);
+ if (TREE_CODE (expr) != RETURN_EXPR)
+ return expr;
+
+ if (!find_rank (loc, expr, expr, false, &rank))
+ return error_mark_node;
+
+ /* If the return expression contains array notations, then flag it as
+ error. */
+ if (rank >= 1)
+ {
+ error_at (loc, "array notation expression cannot be used as a return "
+ "value");
+ return error_mark_node;
+ }
+
+ new_mod_list = push_stmt_list ();
+ retval_expr = TREE_OPERAND (expr, 0);
+ new_var = create_temporary_var (TREE_TYPE (retval_expr));
+ add_decl_expr (new_var);
+ new_mod = expand_an_in_modify_expr (loc, new_var, NOP_EXPR,
+ TREE_OPERAND (retval_expr, 1),
+ tf_warning_or_error);
+ TREE_OPERAND (retval_expr, 1) = new_var;
+ TREE_OPERAND (expr, 0) = retval_expr;
+ add_stmt (new_mod);
+ add_stmt (expr);
+ new_mod_list = pop_stmt_list (new_mod_list);
+ return new_mod_list;
+}
+
+/* Expands ARRAY_NOTATION_REF and builtin functions in a compound statement,
+ STMT. Returns the STMT with expanded array notations. */
+
+tree
+expand_array_notation_exprs (tree t)
+{
+ enum tree_code code;
+ bool is_expr;
+ location_t loc = UNKNOWN_LOCATION;
+
+ if (!t)
+ return t;
+
+ loc = EXPR_LOCATION (t);
+
+ code = TREE_CODE (t);
+ is_expr = IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code));
+ switch (code)
+ {
+ case ERROR_MARK:
+ case IDENTIFIER_NODE:
+ case INTEGER_CST:
+ case REAL_CST:
+ case FIXED_CST:
+ case STRING_CST:
+ case BLOCK:
+ case PLACEHOLDER_EXPR:
+ case FIELD_DECL:
+ case VOID_TYPE:
+ case REAL_TYPE:
+ case SSA_NAME:
+ case LABEL_DECL:
+ case RESULT_DECL:
+ case VAR_DECL:
+ case PARM_DECL:
+ case NON_LVALUE_EXPR:
+ case NOP_EXPR:
+ case INIT_EXPR:
+ case ADDR_EXPR:
+ case ARRAY_REF:
+ case BIT_FIELD_REF:
+ case VECTOR_CST:
+ case COMPLEX_CST:
+ return t;
+ case MODIFY_EXPR:
+ if (contains_array_notation_expr (t))
+ t = expand_an_in_modify_expr (loc, TREE_OPERAND (t, 0), NOP_EXPR,
+ TREE_OPERAND (t, 1),
+ tf_warning_or_error);
+ return t;
+ case MODOP_EXPR:
+ if (contains_array_notation_expr (t) && !processing_template_decl)
+ t = expand_an_in_modify_expr
+ (loc, TREE_OPERAND (t, 0), TREE_CODE (TREE_OPERAND (t, 1)),
+ TREE_OPERAND (t, 2), tf_warning_or_error);
+ return t;
+ case CONSTRUCTOR:
+ return t;
+ case BIND_EXPR:
+ {
+ BIND_EXPR_BODY (t) =
+ expand_array_notation_exprs (BIND_EXPR_BODY (t));
+ return t;
+ }
+ case DECL_EXPR:
+ {
+ tree x = DECL_EXPR_DECL (t);
+ if (t && TREE_CODE (x) != FUNCTION_DECL)
+ if (DECL_INITIAL (x))
+ t = expand_unary_array_notation_exprs (t);
+ return t;
+ }
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
+ *tsi_stmt_ptr (i) =
+ expand_array_notation_exprs (*tsi_stmt_ptr (i));
+ return t;
+ }
+
+ case OMP_PARALLEL:
+ case OMP_TASK:
+ case OMP_FOR:
+ case OMP_SINGLE:
+ case OMP_SECTION:
+ case OMP_SECTIONS:
+ case OMP_MASTER:
+ case OMP_TASKGROUP:
+ case OMP_ORDERED:
+ case OMP_CRITICAL:
+ case OMP_ATOMIC:
+ case OMP_CLAUSE:
+ case TARGET_EXPR:
+ case INTEGER_TYPE:
+ case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
+ case POINTER_TYPE:
+ case ARRAY_TYPE:
+ case RECORD_TYPE:
+ case METHOD_TYPE:
+ return t;
+ case RETURN_EXPR:
+ if (contains_array_notation_expr (t))
+ t = expand_return_expr (t);
+ return t;
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case AGGR_INIT_EXPR:
+ case CALL_EXPR:
+ t = expand_unary_array_notation_exprs (t);
+ return t;
+ case CONVERT_EXPR:
+ case CLEANUP_POINT_EXPR:
+ case EXPR_STMT:
+ TREE_OPERAND (t, 0) = expand_array_notation_exprs (TREE_OPERAND (t, 0));
+ /* It is not necessary to wrap error_mark_node in EXPR_STMT. */
+ if (TREE_OPERAND (t, 0) == error_mark_node)
+ return TREE_OPERAND (t, 0);
+ return t;
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case TRUTH_XOR_EXPR:
+ case TRUTH_NOT_EXPR:
+ case COND_EXPR:
+ t = cp_expand_cond_array_notations (t);
+ if (TREE_CODE (t) == COND_EXPR)
+ {
+ COND_EXPR_THEN (t) =
+ expand_array_notation_exprs (COND_EXPR_THEN (t));
+ COND_EXPR_ELSE (t) =
+ expand_array_notation_exprs (COND_EXPR_ELSE (t));
+ }
+ return t;
+ case FOR_STMT:
+ if (contains_array_notation_expr (FOR_COND (t)))
+ {
+ error_at (EXPR_LOCATION (FOR_COND (t)),
+ "array notation cannot be used in a condition for "
+ "a for-loop");
+ return error_mark_node;
+ }
+ /* FIXME: Add a check for CILK_FOR_STMT here when we add Cilk tasking
+ keywords. */
+ if (TREE_CODE (t) == FOR_STMT)
+ {
+ FOR_BODY (t) = expand_array_notation_exprs (FOR_BODY (t));
+ FOR_EXPR (t) = expand_array_notation_exprs (FOR_EXPR (t));
+ }
+ else
+ t = expand_array_notation_exprs (t);
+ return t;
+ case IF_STMT:
+ t = cp_expand_cond_array_notations (t);
+ /* If the above function added some extra instructions above the original
+ if statement, then we can't assume it is still IF_STMT so we have to
+ check again. */
+ if (TREE_CODE (t) == IF_STMT)
+ {
+ if (THEN_CLAUSE (t))
+ THEN_CLAUSE (t) = expand_array_notation_exprs (THEN_CLAUSE (t));
+ if (ELSE_CLAUSE (t))
+ ELSE_CLAUSE (t) = expand_array_notation_exprs (ELSE_CLAUSE (t));
+ }
+ else
+ t = expand_array_notation_exprs (t);
+ return t;
+ case SWITCH_STMT:
+ if (contains_array_notation_expr (SWITCH_STMT_COND (t)))
+ {
+ error_at (EXPR_LOCATION (SWITCH_STMT_COND (t)),
+ "array notation cannot be used as a condition for "
+ "switch statement");
+ return error_mark_node;
+ }
+ if (SWITCH_STMT_BODY (t))
+ SWITCH_STMT_BODY (t) =
+ expand_array_notation_exprs (SWITCH_STMT_BODY (t));
+ return t;
+ case WHILE_STMT:
+ if (contains_array_notation_expr (WHILE_COND (t)))
+ {
+ if (EXPR_LOCATION (WHILE_COND (t)) != UNKNOWN_LOCATION)
+ loc = EXPR_LOCATION (WHILE_COND (t));
+ error_at (loc, "array notation cannot be used as a condition for "
+ "while statement");
+ return error_mark_node;
+ }
+ if (WHILE_BODY (t))
+ WHILE_BODY (t) = expand_array_notation_exprs (WHILE_BODY (t));
+ return t;
+ case DO_STMT:
+ if (contains_array_notation_expr (DO_COND (t)))
+ {
+ error_at (EXPR_LOCATION (DO_COND (t)),
+ "array notation cannot be used as a condition for a "
+ "do-while statement");
+ return error_mark_node;
+ }
+ if (DO_BODY (t))
+ DO_BODY (t) = expand_array_notation_exprs (DO_BODY (t));
+ return t;
+ default:
+ if (is_expr)
+ {
+ int i, len;
+
+ /* Walk over all the sub-trees of this operand. */
+ len = TREE_CODE_LENGTH (code);
+
+ /* Go through the subtrees. We need to do this in forward order so
+ that the scope of a FOR_EXPR is handled properly. */
+ for (i = 0; i < len; ++i)
+ TREE_OPERAND (t, i) =
+ expand_array_notation_exprs (TREE_OPERAND (t, i));
+ }
+ return t;
+ }
+ return t;
+}
+
+/* Given the base of an array (ARRAY), the START (start_index), the number of
+ elements to be accessed (LENGTH) and the STRIDE, construct an
+ ARRAY_NOTATION_REF tree of type TYPE and return it. Restrictions on START,
+ LENGTH and STRIDE are the same as that of index field passed into ARRAY_REF.
+ The only additional restriction is that, unlike index in ARRAY_REF, stride,
+ length and start_index cannot contain array notations. */
+
+tree
+build_array_notation_ref (location_t loc, tree array, tree start, tree length,
+ tree stride, tree type)
+{
+ tree array_ntn_expr = NULL_TREE;
+
+ /* If we enter the then-case of the if-statement below, we have hit a case
+ like this: ARRAY [:]. */
+ if (!start && !length)
+ {
+ if (TREE_CODE (type) != ARRAY_TYPE)
+ {
+ error_at (loc, "start-index and length fields necessary for "
+ "using array notation in pointers or records");
+ return error_mark_node;
+ }
+ tree domain = TYPE_DOMAIN (type);
+ if (!domain)
+ {
+ error_at (loc, "start-index and length fields necessary for "
+ "using array notation with array of unknown bound");
+ return error_mark_node;
+ }
+ start = cp_fold_convert (ptrdiff_type_node, TYPE_MINVAL (domain));
+ length = size_binop (PLUS_EXPR, TYPE_MAXVAL (domain), size_one_node);
+ length = cp_fold_convert (ptrdiff_type_node, length);
+ }
+
+ if (!stride)
+ stride = build_one_cst (ptrdiff_type_node);
+
+ /* When dealing with templates, triplet type-checking will be done in pt.c
+ after type substitution. */
+ if (processing_template_decl
+ && (type_dependent_expression_p (array)
+ || type_dependent_expression_p (length)
+ || type_dependent_expression_p (start)
+ || type_dependent_expression_p (stride)))
+ array_ntn_expr = build_min_nt_loc (loc, ARRAY_NOTATION_REF, array, start,
+ length, stride, NULL_TREE);
+ else
+ {
+ if (!cilkplus_an_triplet_types_ok_p (loc, start, length, stride, type))
+ return error_mark_node;
+ array_ntn_expr = build4 (ARRAY_NOTATION_REF, NULL_TREE, array, start,
+ length, stride);
+ }
+ if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == POINTER_TYPE)
+ TREE_TYPE (array_ntn_expr) = TREE_TYPE (type);
+ else
+ gcc_unreachable ();
+
+ SET_EXPR_LOCATION (array_ntn_expr, loc);
+ return array_ntn_expr;
+}
+
+/* Returns false if any of the Array notation triplet values: START_INDEX,
+ LENGTH and STRIDE, are not of integral type and have a rank greater than
+ zero. */
+
+bool
+cilkplus_an_triplet_types_ok_p (location_t loc, tree start_index, tree length,
+ tree stride, tree type)
+{
+ size_t stride_rank = 0, length_rank = 0, start_rank = 0;
+ if (!TREE_TYPE (start_index) || !INTEGRAL_TYPE_P (TREE_TYPE (start_index)))
+ {
+ error_at (loc, "start-index of array notation triplet is not an integer");
+ return false;
+ }
+ if (!TREE_TYPE (length) || !INTEGRAL_TYPE_P (TREE_TYPE (length)))
+ {
+ error_at (loc, "length of array notation triplet is not an integer");
+ return false;
+ }
+ if (!TREE_TYPE (stride) || !INTEGRAL_TYPE_P (TREE_TYPE (stride)))
+ {
+ error_at (loc, "stride of array notation triplet is not an integer");
+ return false;
+ }
+ if (!TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ error_at (loc, "array notation cannot be used with function type");
+ return false;
+ }
+ if (!find_rank (loc, start_index, start_index, false, &start_rank)
+ || !find_rank (loc, length, length, false, &length_rank)
+ || !find_rank (loc, stride, stride, false, &stride_rank))
+ return false;
+
+ if (start_rank != 0)
+ {
+ error_at (loc, "rank of an array notation triplet%'s start-index is not "
+ "zero");
+ return false;
+ }
+ if (length_rank != 0)
+ {
+ error_at (loc, "rank of an array notation triplet%'s length is not zero");
+ return false;
+ }
+ if (stride_rank != 0)
+ {
+ error_at (loc, "rank of array notation triplet%'s stride is not zero");
+ return false;
+ }
+ return true;
+}
diff --git a/gcc-4.9/gcc/cp/cp-cilkplus.c b/gcc-4.9/gcc/cp/cp-cilkplus.c
new file mode 100644
index 000000000..f3a2aff04
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cp-cilkplus.c
@@ -0,0 +1,145 @@
+/* This file is part of the Intel(R) Cilk(TM) Plus support
+ This file contains routines to handle Cilk Plus specific
+ routines for the C++ Compiler.
+ Copyright (C) 2013-2014 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com>.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "cp-tree.h"
+#include "diagnostic-core.h"
+#include "tree-iterator.h"
+#include "tree-inline.h" /* for copy_tree_body_r. */
+#include "ggc.h"
+#include "cilk.h"
+
+/* Callback for cp_walk_tree to validate the body of a pragma simd loop
+ or _cilk_for loop.
+
+ This function is passed in as a function pointer to walk_tree. *TP is
+ the current tree pointer, *WALK_SUBTREES is set to 0 by this function if
+ recursing into TP's subtrees is unnecessary. *DATA is a bool variable that
+ is set to false if an error has occured. */
+
+static tree
+cpp_validate_cilk_plus_loop_aux (tree *tp, int *walk_subtrees, void *data)
+{
+ bool *valid = (bool *) data;
+ location_t loc = EXPR_HAS_LOCATION (*tp) ? EXPR_LOCATION (*tp) :
+ UNKNOWN_LOCATION;
+
+ if (!tp || !*tp)
+ return NULL_TREE;
+
+ if (TREE_CODE (*tp) == THROW_EXPR)
+ {
+ error_at (loc, "throw expressions are not allowed inside loops "
+ "marked with pragma simd");
+ *walk_subtrees = 0;
+ *valid = false;
+ }
+ else if (TREE_CODE (*tp) == TRY_BLOCK)
+ {
+ error_at (loc, "try statements are not allowed inside loops marked "
+ "with #pragma simd");
+ *valid = false;
+ *walk_subtrees = 0;
+ }
+ return NULL_TREE;
+}
+
+
+/* Walks through all the subtrees of BODY using walk_tree to make sure
+ invalid statements/expressions are not found inside BODY. Returns
+ false if any invalid statements are found. */
+
+bool
+cpp_validate_cilk_plus_loop (tree body)
+{
+ bool valid = true;
+ cp_walk_tree (&body, cpp_validate_cilk_plus_loop_aux,
+ (void *) &valid, NULL);
+ return valid;
+}
+
+/* Sets the EXCEPTION bit (0x10) in the FRAME.flags field. */
+
+static tree
+set_cilk_except_flag (tree frame)
+{
+ tree flags = cilk_dot (frame, CILK_TI_FRAME_FLAGS, 0);
+
+ flags = build2 (MODIFY_EXPR, void_type_node, flags,
+ build2 (BIT_IOR_EXPR, TREE_TYPE (flags), flags,
+ build_int_cst (TREE_TYPE (flags),
+ CILK_FRAME_EXCEPTING)));
+ return flags;
+}
+
+/* Sets the frame.EXCEPT_DATA field to the head of the exception pointer. */
+
+static tree
+set_cilk_except_data (tree frame)
+{
+ tree except_data = cilk_dot (frame, CILK_TI_FRAME_EXCEPTION, 0);
+ tree uresume_fn = builtin_decl_implicit (BUILT_IN_EH_POINTER);
+ tree ret_expr;
+ uresume_fn = build_call_expr (uresume_fn, 1,
+ build_int_cst (integer_type_node, 0));
+ ret_expr = build2 (MODIFY_EXPR, void_type_node, except_data, uresume_fn);
+ return ret_expr;
+}
+
+/* Installs BODY into function FNDECL with appropriate exception handling
+ code. WD holds information of wrapper function used to pass into the
+ outlining function, cilk_outline. */
+
+void
+cilk_install_body_with_frame_cleanup (tree fndecl, tree orig_body, void *wd)
+{
+ tree frame = make_cilk_frame (fndecl);
+ tree dtor = create_cilk_function_exit (frame, false, false);
+ add_local_decl (cfun, frame);
+
+ cfun->language = ggc_alloc_cleared_language_function ();
+
+ location_t loc = EXPR_LOCATION (orig_body);
+ tree list = alloc_stmt_list ();
+ DECL_SAVED_TREE (fndecl) = list;
+ tree fptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (frame)), frame);
+ tree body = cilk_install_body_pedigree_operations (fptr);
+ gcc_assert (TREE_CODE (body) == STATEMENT_LIST);
+ tree detach_expr = build_call_expr (cilk_detach_fndecl, 1, fptr);
+ append_to_statement_list (detach_expr, &body);
+ cilk_outline (fndecl, &orig_body, (struct wrapper_data *) wd);
+ append_to_statement_list (orig_body, &body);
+ if (flag_exceptions)
+ {
+ tree except_flag = set_cilk_except_flag (frame);
+ tree except_data = set_cilk_except_data (frame);
+ tree catch_list = alloc_stmt_list ();
+ append_to_statement_list (except_flag, &catch_list);
+ append_to_statement_list (except_data, &catch_list);
+ body = create_try_catch_expr (body, catch_list);
+ }
+ append_to_statement_list (build_stmt (loc, TRY_FINALLY_EXPR, body, dtor),
+ &list);
+}
+
diff --git a/gcc-4.9/gcc/cp/cp-gimplify.c b/gcc-4.9/gcc/cp/cp-gimplify.c
new file mode 100644
index 000000000..ef4b04372
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cp-gimplify.c
@@ -0,0 +1,1620 @@
+/* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
+
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ Contributed by Jason Merrill <jason@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stor-layout.h"
+#include "cp-tree.h"
+#include "c-family/c-common.h"
+#include "tree-iterator.h"
+#include "pointer-set.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "gimple.h"
+#include "gimplify.h"
+#include "hashtab.h"
+#include "flags.h"
+#include "splay-tree.h"
+#include "target.h"
+#include "c-family/c-ubsan.h"
+#include "cilk.h"
+
+/* Forward declarations. */
+
+static tree cp_genericize_r (tree *, int *, void *);
+static void cp_genericize_tree (tree*);
+
+/* Local declarations. */
+
+enum bc_t { bc_break = 0, bc_continue = 1 };
+
+/* Stack of labels which are targets for "break" or "continue",
+ linked through TREE_CHAIN. */
+static tree bc_label[2];
+
+/* Begin a scope which can be exited by a break or continue statement. BC
+ indicates which.
+
+ Just creates a label with location LOCATION and pushes it into the current
+ context. */
+
+static tree
+begin_bc_block (enum bc_t bc, location_t location)
+{
+ tree label = create_artificial_label (location);
+ DECL_CHAIN (label) = bc_label[bc];
+ bc_label[bc] = label;
+ return label;
+}
+
+/* Finish a scope which can be exited by a break or continue statement.
+ LABEL was returned from the most recent call to begin_bc_block. BLOCK is
+ an expression for the contents of the scope.
+
+ If we saw a break (or continue) in the scope, append a LABEL_EXPR to
+ BLOCK. Otherwise, just forget the label. */
+
+static void
+finish_bc_block (tree *block, enum bc_t bc, tree label)
+{
+ gcc_assert (label == bc_label[bc]);
+
+ if (TREE_USED (label))
+ append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
+ block);
+
+ bc_label[bc] = DECL_CHAIN (label);
+ DECL_CHAIN (label) = NULL_TREE;
+}
+
+/* Get the LABEL_EXPR to represent a break or continue statement
+ in the current block scope. BC indicates which. */
+
+static tree
+get_bc_label (enum bc_t bc)
+{
+ tree label = bc_label[bc];
+
+ /* Mark the label used for finish_bc_block. */
+ TREE_USED (label) = 1;
+ return label;
+}
+
+/* Genericize a TRY_BLOCK. */
+
+static void
+genericize_try_block (tree *stmt_p)
+{
+ tree body = TRY_STMTS (*stmt_p);
+ tree cleanup = TRY_HANDLERS (*stmt_p);
+
+ *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
+}
+
+/* Genericize a HANDLER by converting to a CATCH_EXPR. */
+
+static void
+genericize_catch_block (tree *stmt_p)
+{
+ tree type = HANDLER_TYPE (*stmt_p);
+ tree body = HANDLER_BODY (*stmt_p);
+
+ /* FIXME should the caught type go in TREE_TYPE? */
+ *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
+}
+
+/* A terser interface for building a representation of an exception
+ specification. */
+
+static tree
+build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
+{
+ tree t;
+
+ /* FIXME should the allowed types go in TREE_TYPE? */
+ t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
+ append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
+
+ t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
+ append_to_statement_list (body, &TREE_OPERAND (t, 0));
+
+ return t;
+}
+
+/* Genericize an EH_SPEC_BLOCK by converting it to a
+ TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
+
+static void
+genericize_eh_spec_block (tree *stmt_p)
+{
+ tree body = EH_SPEC_STMTS (*stmt_p);
+ tree allowed = EH_SPEC_RAISES (*stmt_p);
+ tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
+
+ *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
+ TREE_NO_WARNING (*stmt_p) = true;
+ TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true;
+}
+
+/* Genericize an IF_STMT by turning it into a COND_EXPR. */
+
+static void
+genericize_if_stmt (tree *stmt_p)
+{
+ tree stmt, cond, then_, else_;
+ location_t locus = EXPR_LOCATION (*stmt_p);
+
+ stmt = *stmt_p;
+ cond = IF_COND (stmt);
+ then_ = THEN_CLAUSE (stmt);
+ else_ = ELSE_CLAUSE (stmt);
+
+ if (!then_)
+ then_ = build_empty_stmt (locus);
+ if (!else_)
+ else_ = build_empty_stmt (locus);
+
+ if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
+ stmt = then_;
+ else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
+ stmt = else_;
+ else
+ stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
+ if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
+ SET_EXPR_LOCATION (stmt, locus);
+ *stmt_p = stmt;
+}
+
+/* Build a generic representation of one of the C loop forms. COND is the
+ loop condition or NULL_TREE. BODY is the (possibly compound) statement
+ controlled by the loop. INCR is the increment expression of a for-loop,
+ or NULL_TREE. COND_IS_FIRST indicates whether the condition is
+ evaluated before the loop body as in while and for loops, or after the
+ loop body as in do-while loops. */
+
+static void
+genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
+ tree incr, bool cond_is_first, int *walk_subtrees,
+ void *data)
+{
+ tree blab, clab;
+ tree entry = NULL, exit = NULL, t;
+ tree stmt_list = NULL;
+
+ blab = begin_bc_block (bc_break, start_locus);
+ clab = begin_bc_block (bc_continue, start_locus);
+
+ if (incr && EXPR_P (incr))
+ SET_EXPR_LOCATION (incr, start_locus);
+
+ cp_walk_tree (&cond, cp_genericize_r, data, NULL);
+ cp_walk_tree (&body, cp_genericize_r, data, NULL);
+ cp_walk_tree (&incr, cp_genericize_r, data, NULL);
+ *walk_subtrees = 0;
+
+ /* If condition is zero don't generate a loop construct. */
+ if (cond && integer_zerop (cond))
+ {
+ if (cond_is_first)
+ {
+ t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
+ get_bc_label (bc_break));
+ append_to_statement_list (t, &stmt_list);
+ }
+ }
+ else
+ {
+ /* Expand to gotos, just like c_finish_loop. TODO: Use LOOP_EXPR. */
+ tree top = build1 (LABEL_EXPR, void_type_node,
+ create_artificial_label (start_locus));
+
+ /* If we have an exit condition, then we build an IF with gotos either
+ out of the loop, or to the top of it. If there's no exit condition,
+ then we just build a jump back to the top. */
+ exit = build1 (GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL (top));
+
+ if (cond && !integer_nonzerop (cond))
+ {
+ /* Canonicalize the loop condition to the end. This means
+ generating a branch to the loop condition. Reuse the
+ continue label, if possible. */
+ if (cond_is_first)
+ {
+ if (incr)
+ {
+ entry = build1 (LABEL_EXPR, void_type_node,
+ create_artificial_label (start_locus));
+ t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
+ LABEL_EXPR_LABEL (entry));
+ }
+ else
+ t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
+ get_bc_label (bc_continue));
+ append_to_statement_list (t, &stmt_list);
+ }
+
+ t = build1 (GOTO_EXPR, void_type_node, get_bc_label (bc_break));
+ exit = fold_build3_loc (start_locus,
+ COND_EXPR, void_type_node, cond, exit, t);
+ }
+
+ append_to_statement_list (top, &stmt_list);
+ }
+
+ append_to_statement_list (body, &stmt_list);
+ finish_bc_block (&stmt_list, bc_continue, clab);
+ append_to_statement_list (incr, &stmt_list);
+ append_to_statement_list (entry, &stmt_list);
+ append_to_statement_list (exit, &stmt_list);
+ finish_bc_block (&stmt_list, bc_break, blab);
+
+ if (stmt_list == NULL_TREE)
+ stmt_list = build1 (NOP_EXPR, void_type_node, integer_zero_node);
+
+ *stmt_p = stmt_list;
+}
+
+/* Genericize a FOR_STMT node *STMT_P. */
+
+static void
+genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
+{
+ tree stmt = *stmt_p;
+ tree expr = NULL;
+ tree loop;
+ tree init = FOR_INIT_STMT (stmt);
+
+ if (init)
+ {
+ cp_walk_tree (&init, cp_genericize_r, data, NULL);
+ append_to_statement_list (init, &expr);
+ }
+
+ genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
+ FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data);
+ append_to_statement_list (loop, &expr);
+ *stmt_p = expr;
+}
+
+/* Genericize a WHILE_STMT node *STMT_P. */
+
+static void
+genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data)
+{
+ tree stmt = *stmt_p;
+ genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
+ WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees, data);
+}
+
+/* Genericize a DO_STMT node *STMT_P. */
+
+static void
+genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data)
+{
+ tree stmt = *stmt_p;
+ genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
+ DO_BODY (stmt), NULL_TREE, 0, walk_subtrees, data);
+}
+
+/* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR. */
+
+static void
+genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data)
+{
+ tree stmt = *stmt_p;
+ tree break_block, body, cond, type;
+ location_t stmt_locus = EXPR_LOCATION (stmt);
+
+ break_block = begin_bc_block (bc_break, stmt_locus);
+
+ body = SWITCH_STMT_BODY (stmt);
+ if (!body)
+ body = build_empty_stmt (stmt_locus);
+ cond = SWITCH_STMT_COND (stmt);
+ type = SWITCH_STMT_TYPE (stmt);
+
+ cp_walk_tree (&body, cp_genericize_r, data, NULL);
+ cp_walk_tree (&cond, cp_genericize_r, data, NULL);
+ cp_walk_tree (&type, cp_genericize_r, data, NULL);
+ *walk_subtrees = 0;
+
+ *stmt_p = build3_loc (stmt_locus, SWITCH_EXPR, type, cond, body, NULL_TREE);
+ finish_bc_block (stmt_p, bc_break, break_block);
+}
+
+/* Genericize a CONTINUE_STMT node *STMT_P. */
+
+static void
+genericize_continue_stmt (tree *stmt_p)
+{
+ tree stmt_list = NULL;
+ tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
+ tree label = get_bc_label (bc_continue);
+ location_t location = EXPR_LOCATION (*stmt_p);
+ tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
+ append_to_statement_list (pred, &stmt_list);
+ append_to_statement_list (jump, &stmt_list);
+ *stmt_p = stmt_list;
+}
+
+/* Genericize a BREAK_STMT node *STMT_P. */
+
+static void
+genericize_break_stmt (tree *stmt_p)
+{
+ tree label = get_bc_label (bc_break);
+ location_t location = EXPR_LOCATION (*stmt_p);
+ *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
+}
+
+/* Genericize a OMP_FOR node *STMT_P. */
+
+static void
+genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
+{
+ tree stmt = *stmt_p;
+ location_t locus = EXPR_LOCATION (stmt);
+ tree clab = begin_bc_block (bc_continue, locus);
+
+ cp_walk_tree (&OMP_FOR_BODY (stmt), cp_genericize_r, data, NULL);
+ cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_genericize_r, data, NULL);
+ cp_walk_tree (&OMP_FOR_INIT (stmt), cp_genericize_r, data, NULL);
+ cp_walk_tree (&OMP_FOR_COND (stmt), cp_genericize_r, data, NULL);
+ cp_walk_tree (&OMP_FOR_INCR (stmt), cp_genericize_r, data, NULL);
+ cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_genericize_r, data, NULL);
+ *walk_subtrees = 0;
+
+ finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
+}
+
+/* Hook into the middle of gimplifying an OMP_FOR node. */
+
+static enum gimplify_status
+cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
+{
+ tree for_stmt = *expr_p;
+ gimple_seq seq = NULL;
+
+ /* Protect ourselves from recursion. */
+ if (OMP_FOR_GIMPLIFYING_P (for_stmt))
+ return GS_UNHANDLED;
+ OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
+
+ gimplify_and_add (for_stmt, &seq);
+ gimple_seq_add_seq (pre_p, seq);
+
+ OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
+
+ return GS_ALL_DONE;
+}
+
+/* Gimplify an EXPR_STMT node. */
+
+static void
+gimplify_expr_stmt (tree *stmt_p)
+{
+ tree stmt = EXPR_STMT_EXPR (*stmt_p);
+
+ if (stmt == error_mark_node)
+ stmt = NULL;
+
+ /* Gimplification of a statement expression will nullify the
+ statement if all its side effects are moved to *PRE_P and *POST_P.
+
+ In this case we will not want to emit the gimplified statement.
+ However, we may still want to emit a warning, so we do that before
+ gimplification. */
+ if (stmt && warn_unused_value)
+ {
+ if (!TREE_SIDE_EFFECTS (stmt))
+ {
+ if (!IS_EMPTY_STMT (stmt)
+ && !VOID_TYPE_P (TREE_TYPE (stmt))
+ && !TREE_NO_WARNING (stmt))
+ warning (OPT_Wunused_value, "statement with no effect");
+ }
+ else
+ warn_if_unused_value (stmt, input_location);
+ }
+
+ if (stmt == NULL_TREE)
+ stmt = alloc_stmt_list ();
+
+ *stmt_p = stmt;
+}
+
+/* Gimplify initialization from an AGGR_INIT_EXPR. */
+
+static void
+cp_gimplify_init_expr (tree *expr_p)
+{
+ tree from = TREE_OPERAND (*expr_p, 1);
+ tree to = TREE_OPERAND (*expr_p, 0);
+ tree t;
+
+ /* What about code that pulls out the temp and uses it elsewhere? I
+ think that such code never uses the TARGET_EXPR as an initializer. If
+ I'm wrong, we'll abort because the temp won't have any RTL. In that
+ case, I guess we'll need to replace references somehow. */
+ if (TREE_CODE (from) == TARGET_EXPR)
+ from = TARGET_EXPR_INITIAL (from);
+
+ /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
+ inside the TARGET_EXPR. */
+ for (t = from; t; )
+ {
+ tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
+
+ /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
+ replace the slot operand with our target.
+
+ Should we add a target parm to gimplify_expr instead? No, as in this
+ case we want to replace the INIT_EXPR. */
+ if (TREE_CODE (sub) == AGGR_INIT_EXPR
+ || TREE_CODE (sub) == VEC_INIT_EXPR)
+ {
+ if (TREE_CODE (sub) == AGGR_INIT_EXPR)
+ AGGR_INIT_EXPR_SLOT (sub) = to;
+ else
+ VEC_INIT_EXPR_SLOT (sub) = to;
+ *expr_p = from;
+
+ /* The initialization is now a side-effect, so the container can
+ become void. */
+ if (from != sub)
+ TREE_TYPE (from) = void_type_node;
+ }
+
+ if (t == sub)
+ break;
+ else
+ t = TREE_OPERAND (t, 1);
+ }
+
+}
+
+/* Gimplify a MUST_NOT_THROW_EXPR. */
+
+static enum gimplify_status
+gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
+{
+ tree stmt = *expr_p;
+ tree temp = voidify_wrapper_expr (stmt, NULL);
+ tree body = TREE_OPERAND (stmt, 0);
+ gimple_seq try_ = NULL;
+ gimple_seq catch_ = NULL;
+ gimple mnt;
+
+ gimplify_and_add (body, &try_);
+ mnt = gimple_build_eh_must_not_throw (terminate_node);
+ gimple_seq_add_stmt_without_update (&catch_, mnt);
+ mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
+
+ gimple_seq_add_stmt_without_update (pre_p, mnt);
+ if (temp)
+ {
+ *expr_p = temp;
+ return GS_OK;
+ }
+
+ *expr_p = NULL;
+ return GS_ALL_DONE;
+}
+
+/* Do C++-specific gimplification. Args are as for gimplify_expr. */
+
+int
+cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
+{
+ int saved_stmts_are_full_exprs_p = 0;
+ enum tree_code code = TREE_CODE (*expr_p);
+ enum gimplify_status ret;
+
+ if (STATEMENT_CODE_P (code))
+ {
+ saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
+ current_stmt_tree ()->stmts_are_full_exprs_p
+ = STMT_IS_FULL_EXPR_P (*expr_p);
+ }
+
+ switch (code)
+ {
+ case PTRMEM_CST:
+ *expr_p = cplus_expand_constant (*expr_p);
+ ret = GS_OK;
+ break;
+
+ case AGGR_INIT_EXPR:
+ simplify_aggr_init_expr (expr_p);
+ ret = GS_OK;
+ break;
+
+ case VEC_INIT_EXPR:
+ {
+ location_t loc = input_location;
+ tree init = VEC_INIT_EXPR_INIT (*expr_p);
+ int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
+ gcc_assert (EXPR_HAS_LOCATION (*expr_p));
+ input_location = EXPR_LOCATION (*expr_p);
+ *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
+ init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
+ from_array,
+ tf_warning_or_error);
+ cp_genericize_tree (expr_p);
+ ret = GS_OK;
+ input_location = loc;
+ }
+ break;
+
+ case THROW_EXPR:
+ /* FIXME communicate throw type to back end, probably by moving
+ THROW_EXPR into ../tree.def. */
+ *expr_p = TREE_OPERAND (*expr_p, 0);
+ ret = GS_OK;
+ break;
+
+ case MUST_NOT_THROW_EXPR:
+ ret = gimplify_must_not_throw_expr (expr_p, pre_p);
+ break;
+
+ /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
+ LHS of an assignment might also be involved in the RHS, as in bug
+ 25979. */
+ case INIT_EXPR:
+ if (fn_contains_cilk_spawn_p (cfun)
+ && cilk_detect_spawn_and_unwrap (expr_p)
+ && !seen_error ())
+ return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+ cp_gimplify_init_expr (expr_p);
+ if (TREE_CODE (*expr_p) != INIT_EXPR)
+ return GS_OK;
+ /* Otherwise fall through. */
+ case MODIFY_EXPR:
+ {
+ if (fn_contains_cilk_spawn_p (cfun)
+ && cilk_detect_spawn_and_unwrap (expr_p)
+ && !seen_error ())
+ return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+
+ /* If the back end isn't clever enough to know that the lhs and rhs
+ types are the same, add an explicit conversion. */
+ tree op0 = TREE_OPERAND (*expr_p, 0);
+ tree op1 = TREE_OPERAND (*expr_p, 1);
+
+ if (!error_operand_p (op0)
+ && !error_operand_p (op1)
+ && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
+ || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
+ && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
+ TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
+ TREE_TYPE (op0), op1);
+
+ else if ((is_gimple_lvalue (op1) || INDIRECT_REF_P (op1)
+ || (TREE_CODE (op1) == CONSTRUCTOR
+ && CONSTRUCTOR_NELTS (op1) == 0
+ && !TREE_CLOBBER_P (op1))
+ || (TREE_CODE (op1) == CALL_EXPR
+ && !CALL_EXPR_RETURN_SLOT_OPT (op1)))
+ && is_really_empty_class (TREE_TYPE (op0)))
+ {
+ /* Remove any copies of empty classes. We check that the RHS
+ has a simple form so that TARGET_EXPRs and non-empty
+ CONSTRUCTORs get reduced properly, and we leave the return
+ slot optimization alone because it isn't a copy (FIXME so it
+ shouldn't be represented as one).
+
+ Also drop volatile variables on the RHS to avoid infinite
+ recursion from gimplify_expr trying to load the value. */
+ if (!TREE_SIDE_EFFECTS (op1)
+ || (DECL_P (op1) && TREE_THIS_VOLATILE (op1)))
+ *expr_p = op0;
+ else if (TREE_CODE (op1) == MEM_REF
+ && TREE_THIS_VOLATILE (op1))
+ {
+ /* Similarly for volatile MEM_REFs on the RHS. */
+ if (!TREE_SIDE_EFFECTS (TREE_OPERAND (op1, 0)))
+ *expr_p = op0;
+ else
+ *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
+ TREE_OPERAND (op1, 0), op0);
+ }
+ else
+ *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
+ op0, op1);
+ }
+ }
+ ret = GS_OK;
+ break;
+
+ case EMPTY_CLASS_EXPR:
+ /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
+ *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
+ ret = GS_OK;
+ break;
+
+ case BASELINK:
+ *expr_p = BASELINK_FUNCTIONS (*expr_p);
+ ret = GS_OK;
+ break;
+
+ case TRY_BLOCK:
+ genericize_try_block (expr_p);
+ ret = GS_OK;
+ break;
+
+ case HANDLER:
+ genericize_catch_block (expr_p);
+ ret = GS_OK;
+ break;
+
+ case EH_SPEC_BLOCK:
+ genericize_eh_spec_block (expr_p);
+ ret = GS_OK;
+ break;
+
+ case USING_STMT:
+ gcc_unreachable ();
+
+ case FOR_STMT:
+ case WHILE_STMT:
+ case DO_STMT:
+ case SWITCH_STMT:
+ case CONTINUE_STMT:
+ case BREAK_STMT:
+ gcc_unreachable ();
+
+ case OMP_FOR:
+ case OMP_SIMD:
+ case OMP_DISTRIBUTE:
+ ret = cp_gimplify_omp_for (expr_p, pre_p);
+ break;
+
+ case EXPR_STMT:
+ gimplify_expr_stmt (expr_p);
+ ret = GS_OK;
+ break;
+
+ case UNARY_PLUS_EXPR:
+ {
+ tree arg = TREE_OPERAND (*expr_p, 0);
+ tree type = TREE_TYPE (*expr_p);
+ *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
+ : arg;
+ ret = GS_OK;
+ }
+ break;
+
+ case CILK_SPAWN_STMT:
+ gcc_assert
+ (fn_contains_cilk_spawn_p (cfun)
+ && cilk_detect_spawn_and_unwrap (expr_p));
+
+ /* If errors are seen, then just process it as a CALL_EXPR. */
+ if (!seen_error ())
+ return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+
+ case CALL_EXPR:
+ if (fn_contains_cilk_spawn_p (cfun)
+ && cilk_detect_spawn_and_unwrap (expr_p)
+ && !seen_error ())
+ return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+
+ default:
+ ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
+ break;
+ }
+
+ /* Restore saved state. */
+ if (STATEMENT_CODE_P (code))
+ current_stmt_tree ()->stmts_are_full_exprs_p
+ = saved_stmts_are_full_exprs_p;
+
+ return ret;
+}
+
+static inline bool
+is_invisiref_parm (const_tree t)
+{
+ return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
+ && DECL_BY_REFERENCE (t));
+}
+
+/* Return true if the uid in both int tree maps are equal. */
+
+int
+cxx_int_tree_map_eq (const void *va, const void *vb)
+{
+ const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
+ const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
+ return (a->uid == b->uid);
+}
+
+/* Hash a UID in a cxx_int_tree_map. */
+
+unsigned int
+cxx_int_tree_map_hash (const void *item)
+{
+ return ((const struct cxx_int_tree_map *)item)->uid;
+}
+
+/* A stable comparison routine for use with splay trees and DECLs. */
+
+static int
+splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
+{
+ tree a = (tree) xa;
+ tree b = (tree) xb;
+
+ return DECL_UID (a) - DECL_UID (b);
+}
+
+/* OpenMP context during genericization. */
+
+struct cp_genericize_omp_taskreg
+{
+ bool is_parallel;
+ bool default_shared;
+ struct cp_genericize_omp_taskreg *outer;
+ splay_tree variables;
+};
+
+/* Return true if genericization should try to determine if
+ DECL is firstprivate or shared within task regions. */
+
+static bool
+omp_var_to_track (tree decl)
+{
+ tree type = TREE_TYPE (decl);
+ if (is_invisiref_parm (decl))
+ type = TREE_TYPE (type);
+ while (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+ if (type == error_mark_node || !CLASS_TYPE_P (type))
+ return false;
+ if (VAR_P (decl) && DECL_THREAD_LOCAL_P (decl))
+ return false;
+ if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
+ return false;
+ return true;
+}
+
+/* Note DECL use in OpenMP region OMP_CTX during genericization. */
+
+static void
+omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
+{
+ splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
+ (splay_tree_key) decl);
+ if (n == NULL)
+ {
+ int flags = OMP_CLAUSE_DEFAULT_SHARED;
+ if (omp_ctx->outer)
+ omp_cxx_notice_variable (omp_ctx->outer, decl);
+ if (!omp_ctx->default_shared)
+ {
+ struct cp_genericize_omp_taskreg *octx;
+
+ for (octx = omp_ctx->outer; octx; octx = octx->outer)
+ {
+ n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
+ if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
+ {
+ flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
+ break;
+ }
+ if (octx->is_parallel)
+ break;
+ }
+ if (octx == NULL
+ && (TREE_CODE (decl) == PARM_DECL
+ || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
+ && DECL_CONTEXT (decl) == current_function_decl)))
+ flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
+ if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
+ {
+ /* DECL is implicitly determined firstprivate in
+ the current task construct. Ensure copy ctor and
+ dtor are instantiated, because during gimplification
+ it will be already too late. */
+ tree type = TREE_TYPE (decl);
+ if (is_invisiref_parm (decl))
+ type = TREE_TYPE (type);
+ while (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+ get_copy_ctor (type, tf_none);
+ get_dtor (type, tf_none);
+ }
+ }
+ splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
+ }
+}
+
+/* Genericization context. */
+
+struct cp_genericize_data
+{
+ struct pointer_set_t *p_set;
+ vec<tree> bind_expr_stack;
+ struct cp_genericize_omp_taskreg *omp_ctx;
+};
+
+/* Perform any pre-gimplification lowering of C++ front end trees to
+ GENERIC. */
+
+static tree
+cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
+{
+ tree stmt = *stmt_p;
+ struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
+ struct pointer_set_t *p_set = wtd->p_set;
+
+ /* If in an OpenMP context, note var uses. */
+ if (__builtin_expect (wtd->omp_ctx != NULL, 0)
+ && (VAR_P (stmt)
+ || TREE_CODE (stmt) == PARM_DECL
+ || TREE_CODE (stmt) == RESULT_DECL)
+ && omp_var_to_track (stmt))
+ omp_cxx_notice_variable (wtd->omp_ctx, stmt);
+
+ if (is_invisiref_parm (stmt)
+ /* Don't dereference parms in a thunk, pass the references through. */
+ && !(DECL_THUNK_P (current_function_decl)
+ && TREE_CODE (stmt) == PARM_DECL))
+ {
+ *stmt_p = convert_from_reference (stmt);
+ *walk_subtrees = 0;
+ return NULL;
+ }
+
+ /* Map block scope extern declarations to visible declarations with the
+ same name and type in outer scopes if any. */
+ if (cp_function_chain->extern_decl_map
+ && VAR_OR_FUNCTION_DECL_P (stmt)
+ && DECL_EXTERNAL (stmt))
+ {
+ struct cxx_int_tree_map *h, in;
+ in.uid = DECL_UID (stmt);
+ h = (struct cxx_int_tree_map *)
+ htab_find_with_hash (cp_function_chain->extern_decl_map,
+ &in, in.uid);
+ if (h)
+ {
+ *stmt_p = h->to;
+ *walk_subtrees = 0;
+ return NULL;
+ }
+ }
+
+ /* Other than invisiref parms, don't walk the same tree twice. */
+ if (pointer_set_contains (p_set, stmt))
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (stmt) == ADDR_EXPR
+ && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
+ {
+ /* If in an OpenMP context, note var uses. */
+ if (__builtin_expect (wtd->omp_ctx != NULL, 0)
+ && omp_var_to_track (TREE_OPERAND (stmt, 0)))
+ omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
+ *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
+ *walk_subtrees = 0;
+ }
+ else if (TREE_CODE (stmt) == RETURN_EXPR
+ && TREE_OPERAND (stmt, 0)
+ && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
+ /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
+ *walk_subtrees = 0;
+ else if (TREE_CODE (stmt) == OMP_CLAUSE)
+ switch (OMP_CLAUSE_CODE (stmt))
+ {
+ case OMP_CLAUSE_LASTPRIVATE:
+ /* Don't dereference an invisiref in OpenMP clauses. */
+ if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
+ {
+ *walk_subtrees = 0;
+ if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
+ cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
+ cp_genericize_r, data, NULL);
+ }
+ break;
+ case OMP_CLAUSE_PRIVATE:
+ /* Don't dereference an invisiref in OpenMP clauses. */
+ if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
+ *walk_subtrees = 0;
+ else if (wtd->omp_ctx != NULL)
+ {
+ /* Private clause doesn't cause any references to the
+ var in outer contexts, avoid calling
+ omp_cxx_notice_variable for it. */
+ struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
+ wtd->omp_ctx = NULL;
+ cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
+ data, NULL);
+ wtd->omp_ctx = old;
+ *walk_subtrees = 0;
+ }
+ break;
+ case OMP_CLAUSE_SHARED:
+ case OMP_CLAUSE_FIRSTPRIVATE:
+ case OMP_CLAUSE_COPYIN:
+ case OMP_CLAUSE_COPYPRIVATE:
+ /* Don't dereference an invisiref in OpenMP clauses. */
+ if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
+ *walk_subtrees = 0;
+ break;
+ case OMP_CLAUSE_REDUCTION:
+ /* Don't dereference an invisiref in reduction clause's
+ OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE}
+ still needs to be genericized. */
+ if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
+ {
+ *walk_subtrees = 0;
+ if (OMP_CLAUSE_REDUCTION_INIT (stmt))
+ cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
+ cp_genericize_r, data, NULL);
+ if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
+ cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
+ cp_genericize_r, data, NULL);
+ }
+ break;
+ default:
+ break;
+ }
+ else if (IS_TYPE_OR_DECL_P (stmt))
+ *walk_subtrees = 0;
+
+ /* Due to the way voidify_wrapper_expr is written, we don't get a chance
+ to lower this construct before scanning it, so we need to lower these
+ before doing anything else. */
+ else if (TREE_CODE (stmt) == CLEANUP_STMT)
+ *stmt_p = build2_loc (EXPR_LOCATION (stmt),
+ CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
+ : TRY_FINALLY_EXPR,
+ void_type_node,
+ CLEANUP_BODY (stmt),
+ CLEANUP_EXPR (stmt));
+
+ else if (TREE_CODE (stmt) == IF_STMT)
+ {
+ genericize_if_stmt (stmt_p);
+ /* *stmt_p has changed, tail recurse to handle it again. */
+ return cp_genericize_r (stmt_p, walk_subtrees, data);
+ }
+
+ /* COND_EXPR might have incompatible types in branches if one or both
+ arms are bitfields. Fix it up now. */
+ else if (TREE_CODE (stmt) == COND_EXPR)
+ {
+ tree type_left
+ = (TREE_OPERAND (stmt, 1)
+ ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
+ : NULL_TREE);
+ tree type_right
+ = (TREE_OPERAND (stmt, 2)
+ ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
+ : NULL_TREE);
+ if (type_left
+ && !useless_type_conversion_p (TREE_TYPE (stmt),
+ TREE_TYPE (TREE_OPERAND (stmt, 1))))
+ {
+ TREE_OPERAND (stmt, 1)
+ = fold_convert (type_left, TREE_OPERAND (stmt, 1));
+ gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
+ type_left));
+ }
+ if (type_right
+ && !useless_type_conversion_p (TREE_TYPE (stmt),
+ TREE_TYPE (TREE_OPERAND (stmt, 2))))
+ {
+ TREE_OPERAND (stmt, 2)
+ = fold_convert (type_right, TREE_OPERAND (stmt, 2));
+ gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
+ type_right));
+ }
+ }
+
+ else if (TREE_CODE (stmt) == BIND_EXPR)
+ {
+ if (__builtin_expect (wtd->omp_ctx != NULL, 0))
+ {
+ tree decl;
+ for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
+ if (VAR_P (decl)
+ && !DECL_EXTERNAL (decl)
+ && omp_var_to_track (decl))
+ {
+ splay_tree_node n
+ = splay_tree_lookup (wtd->omp_ctx->variables,
+ (splay_tree_key) decl);
+ if (n == NULL)
+ splay_tree_insert (wtd->omp_ctx->variables,
+ (splay_tree_key) decl,
+ TREE_STATIC (decl)
+ ? OMP_CLAUSE_DEFAULT_SHARED
+ : OMP_CLAUSE_DEFAULT_PRIVATE);
+ }
+ }
+ wtd->bind_expr_stack.safe_push (stmt);
+ cp_walk_tree (&BIND_EXPR_BODY (stmt),
+ cp_genericize_r, data, NULL);
+ wtd->bind_expr_stack.pop ();
+ }
+
+ else if (TREE_CODE (stmt) == USING_STMT)
+ {
+ tree block = NULL_TREE;
+
+ /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
+ BLOCK, and append an IMPORTED_DECL to its
+ BLOCK_VARS chained list. */
+ if (wtd->bind_expr_stack.exists ())
+ {
+ int i;
+ for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
+ if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
+ break;
+ }
+ if (block)
+ {
+ tree using_directive;
+ gcc_assert (TREE_OPERAND (stmt, 0));
+
+ using_directive = make_node (IMPORTED_DECL);
+ TREE_TYPE (using_directive) = void_type_node;
+
+ IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
+ = TREE_OPERAND (stmt, 0);
+ DECL_CHAIN (using_directive) = BLOCK_VARS (block);
+ BLOCK_VARS (block) = using_directive;
+ }
+ /* The USING_STMT won't appear in GENERIC. */
+ *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
+ *walk_subtrees = 0;
+ }
+
+ else if (TREE_CODE (stmt) == DECL_EXPR
+ && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
+ {
+ /* Using decls inside DECL_EXPRs are just dropped on the floor. */
+ *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
+ *walk_subtrees = 0;
+ }
+ else if (TREE_CODE (stmt) == OMP_PARALLEL || TREE_CODE (stmt) == OMP_TASK)
+ {
+ struct cp_genericize_omp_taskreg omp_ctx;
+ tree c, decl;
+ splay_tree_node n;
+
+ *walk_subtrees = 0;
+ cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
+ omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
+ omp_ctx.default_shared = omp_ctx.is_parallel;
+ omp_ctx.outer = wtd->omp_ctx;
+ omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
+ wtd->omp_ctx = &omp_ctx;
+ for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_SHARED:
+ case OMP_CLAUSE_PRIVATE:
+ case OMP_CLAUSE_FIRSTPRIVATE:
+ case OMP_CLAUSE_LASTPRIVATE:
+ decl = OMP_CLAUSE_DECL (c);
+ if (decl == error_mark_node || !omp_var_to_track (decl))
+ break;
+ n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
+ if (n != NULL)
+ break;
+ splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
+ OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
+ ? OMP_CLAUSE_DEFAULT_SHARED
+ : OMP_CLAUSE_DEFAULT_PRIVATE);
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
+ && omp_ctx.outer)
+ omp_cxx_notice_variable (omp_ctx.outer, decl);
+ break;
+ case OMP_CLAUSE_DEFAULT:
+ if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
+ omp_ctx.default_shared = true;
+ default:
+ break;
+ }
+ cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
+ wtd->omp_ctx = omp_ctx.outer;
+ splay_tree_delete (omp_ctx.variables);
+ }
+ else if (TREE_CODE (stmt) == CONVERT_EXPR)
+ gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
+ else if (TREE_CODE (stmt) == FOR_STMT)
+ genericize_for_stmt (stmt_p, walk_subtrees, data);
+ else if (TREE_CODE (stmt) == WHILE_STMT)
+ genericize_while_stmt (stmt_p, walk_subtrees, data);
+ else if (TREE_CODE (stmt) == DO_STMT)
+ genericize_do_stmt (stmt_p, walk_subtrees, data);
+ else if (TREE_CODE (stmt) == SWITCH_STMT)
+ genericize_switch_stmt (stmt_p, walk_subtrees, data);
+ else if (TREE_CODE (stmt) == CONTINUE_STMT)
+ genericize_continue_stmt (stmt_p);
+ else if (TREE_CODE (stmt) == BREAK_STMT)
+ genericize_break_stmt (stmt_p);
+ else if (TREE_CODE (stmt) == OMP_FOR
+ || TREE_CODE (stmt) == OMP_SIMD
+ || TREE_CODE (stmt) == OMP_DISTRIBUTE)
+ genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
+ else if (TREE_CODE (stmt) == SIZEOF_EXPR)
+ {
+ if (SIZEOF_EXPR_TYPE_P (stmt))
+ *stmt_p
+ = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (stmt, 0)),
+ SIZEOF_EXPR, false);
+ else if (TYPE_P (TREE_OPERAND (stmt, 0)))
+ *stmt_p = cxx_sizeof_or_alignof_type (TREE_OPERAND (stmt, 0),
+ SIZEOF_EXPR, false);
+ else
+ *stmt_p = cxx_sizeof_or_alignof_expr (TREE_OPERAND (stmt, 0),
+ SIZEOF_EXPR, false);
+ if (*stmt_p == error_mark_node)
+ *stmt_p = size_one_node;
+ return NULL;
+ }
+
+ pointer_set_insert (p_set, *stmt_p);
+
+ return NULL;
+}
+
+/* Lower C++ front end trees to GENERIC in T_P. */
+
+static void
+cp_genericize_tree (tree* t_p)
+{
+ struct cp_genericize_data wtd;
+
+ wtd.p_set = pointer_set_create ();
+ wtd.bind_expr_stack.create (0);
+ wtd.omp_ctx = NULL;
+ cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
+ pointer_set_destroy (wtd.p_set);
+ wtd.bind_expr_stack.release ();
+}
+
+/* If a function that should end with a return in non-void
+ function doesn't obviously end with return, add ubsan
+ instrmentation code to verify it at runtime. */
+
+static void
+cp_ubsan_maybe_instrument_return (tree fndecl)
+{
+ if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
+ || DECL_CONSTRUCTOR_P (fndecl)
+ || DECL_DESTRUCTOR_P (fndecl)
+ || !targetm.warn_func_return (fndecl))
+ return;
+
+ tree t = DECL_SAVED_TREE (fndecl);
+ while (t)
+ {
+ switch (TREE_CODE (t))
+ {
+ case BIND_EXPR:
+ t = BIND_EXPR_BODY (t);
+ continue;
+ case TRY_FINALLY_EXPR:
+ t = TREE_OPERAND (t, 0);
+ continue;
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i = tsi_last (t);
+ if (!tsi_end_p (i))
+ {
+ t = tsi_stmt (i);
+ continue;
+ }
+ }
+ break;
+ case RETURN_EXPR:
+ return;
+ default:
+ break;
+ }
+ break;
+ }
+ if (t == NULL_TREE)
+ return;
+ t = DECL_SAVED_TREE (fndecl);
+ if (TREE_CODE (t) == BIND_EXPR
+ && TREE_CODE (BIND_EXPR_BODY (t)) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator i = tsi_last (BIND_EXPR_BODY (t));
+ t = ubsan_instrument_return (DECL_SOURCE_LOCATION (fndecl));
+ tsi_link_after (&i, t, TSI_NEW_STMT);
+ }
+}
+
+void
+cp_genericize (tree fndecl)
+{
+ tree t;
+
+ /* Fix up the types of parms passed by invisible reference. */
+ for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
+ if (TREE_ADDRESSABLE (TREE_TYPE (t)))
+ {
+ /* If a function's arguments are copied to create a thunk,
+ then DECL_BY_REFERENCE will be set -- but the type of the
+ argument will be a pointer type, so we will never get
+ here. */
+ gcc_assert (!DECL_BY_REFERENCE (t));
+ gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
+ TREE_TYPE (t) = DECL_ARG_TYPE (t);
+ DECL_BY_REFERENCE (t) = 1;
+ TREE_ADDRESSABLE (t) = 0;
+ relayout_decl (t);
+ }
+
+ /* Do the same for the return value. */
+ if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
+ {
+ t = DECL_RESULT (fndecl);
+ TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
+ DECL_BY_REFERENCE (t) = 1;
+ TREE_ADDRESSABLE (t) = 0;
+ relayout_decl (t);
+ if (DECL_NAME (t))
+ {
+ /* Adjust DECL_VALUE_EXPR of the original var. */
+ tree outer = outer_curly_brace_block (current_function_decl);
+ tree var;
+
+ if (outer)
+ for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
+ if (DECL_NAME (t) == DECL_NAME (var)
+ && DECL_HAS_VALUE_EXPR_P (var)
+ && DECL_VALUE_EXPR (var) == t)
+ {
+ tree val = convert_from_reference (t);
+ SET_DECL_VALUE_EXPR (var, val);
+ break;
+ }
+ }
+ }
+
+ /* If we're a clone, the body is already GIMPLE. */
+ if (DECL_CLONED_FUNCTION_P (fndecl))
+ return;
+
+ /* Expand all the array notations here. */
+ if (flag_cilkplus
+ && contains_array_notation_expr (DECL_SAVED_TREE (fndecl)))
+ DECL_SAVED_TREE (fndecl) =
+ expand_array_notation_exprs (DECL_SAVED_TREE (fndecl));
+
+ /* We do want to see every occurrence of the parms, so we can't just use
+ walk_tree's hash functionality. */
+ cp_genericize_tree (&DECL_SAVED_TREE (fndecl));
+
+ if (flag_sanitize & SANITIZE_RETURN)
+ cp_ubsan_maybe_instrument_return (fndecl);
+
+ /* Do everything else. */
+ c_genericize (fndecl);
+
+ gcc_assert (bc_label[bc_break] == NULL);
+ gcc_assert (bc_label[bc_continue] == NULL);
+}
+
+/* Build code to apply FN to each member of ARG1 and ARG2. FN may be
+ NULL if there is in fact nothing to do. ARG2 may be null if FN
+ actually only takes one argument. */
+
+static tree
+cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
+{
+ tree defparm, parm, t;
+ int i = 0;
+ int nargs;
+ tree *argarray;
+
+ if (fn == NULL)
+ return NULL;
+
+ nargs = list_length (DECL_ARGUMENTS (fn));
+ argarray = XALLOCAVEC (tree, nargs);
+
+ defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
+ if (arg2)
+ defparm = TREE_CHAIN (defparm);
+
+ if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
+ {
+ tree inner_type = TREE_TYPE (arg1);
+ tree start1, end1, p1;
+ tree start2 = NULL, p2 = NULL;
+ tree ret = NULL, lab;
+
+ start1 = arg1;
+ start2 = arg2;
+ do
+ {
+ inner_type = TREE_TYPE (inner_type);
+ start1 = build4 (ARRAY_REF, inner_type, start1,
+ size_zero_node, NULL, NULL);
+ if (arg2)
+ start2 = build4 (ARRAY_REF, inner_type, start2,
+ size_zero_node, NULL, NULL);
+ }
+ while (TREE_CODE (inner_type) == ARRAY_TYPE);
+ start1 = build_fold_addr_expr_loc (input_location, start1);
+ if (arg2)
+ start2 = build_fold_addr_expr_loc (input_location, start2);
+
+ end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
+ end1 = fold_build_pointer_plus (start1, end1);
+
+ p1 = create_tmp_var (TREE_TYPE (start1), NULL);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
+ append_to_statement_list (t, &ret);
+
+ if (arg2)
+ {
+ p2 = create_tmp_var (TREE_TYPE (start2), NULL);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
+ append_to_statement_list (t, &ret);
+ }
+
+ lab = create_artificial_label (input_location);
+ t = build1 (LABEL_EXPR, void_type_node, lab);
+ append_to_statement_list (t, &ret);
+
+ argarray[i++] = p1;
+ if (arg2)
+ argarray[i++] = p2;
+ /* Handle default arguments. */
+ for (parm = defparm; parm && parm != void_list_node;
+ parm = TREE_CHAIN (parm), i++)
+ argarray[i] = convert_default_arg (TREE_VALUE (parm),
+ TREE_PURPOSE (parm), fn, i,
+ tf_warning_or_error);
+ t = build_call_a (fn, i, argarray);
+ t = fold_convert (void_type_node, t);
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ append_to_statement_list (t, &ret);
+
+ t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
+ append_to_statement_list (t, &ret);
+
+ if (arg2)
+ {
+ t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
+ append_to_statement_list (t, &ret);
+ }
+
+ t = build2 (NE_EXPR, boolean_type_node, p1, end1);
+ t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
+ append_to_statement_list (t, &ret);
+
+ return ret;
+ }
+ else
+ {
+ argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
+ if (arg2)
+ argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
+ /* Handle default arguments. */
+ for (parm = defparm; parm && parm != void_list_node;
+ parm = TREE_CHAIN (parm), i++)
+ argarray[i] = convert_default_arg (TREE_VALUE (parm),
+ TREE_PURPOSE (parm),
+ fn, i, tf_warning_or_error);
+ t = build_call_a (fn, i, argarray);
+ t = fold_convert (void_type_node, t);
+ return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
+}
+
+/* Return code to initialize DECL with its default constructor, or
+ NULL if there's nothing to do. */
+
+tree
+cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
+{
+ tree info = CP_OMP_CLAUSE_INFO (clause);
+ tree ret = NULL;
+
+ if (info)
+ ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
+
+ return ret;
+}
+
+/* Return code to initialize DST with a copy constructor from SRC. */
+
+tree
+cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
+{
+ tree info = CP_OMP_CLAUSE_INFO (clause);
+ tree ret = NULL;
+
+ if (info)
+ ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
+ if (ret == NULL)
+ ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
+
+ return ret;
+}
+
+/* Similarly, except use an assignment operator instead. */
+
+tree
+cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
+{
+ tree info = CP_OMP_CLAUSE_INFO (clause);
+ tree ret = NULL;
+
+ if (info)
+ ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
+ if (ret == NULL)
+ ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
+
+ return ret;
+}
+
+/* Return code to destroy DECL. */
+
+tree
+cxx_omp_clause_dtor (tree clause, tree decl)
+{
+ tree info = CP_OMP_CLAUSE_INFO (clause);
+ tree ret = NULL;
+
+ if (info)
+ ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
+
+ return ret;
+}
+
+/* True if OpenMP should privatize what this DECL points to rather
+ than the DECL itself. */
+
+bool
+cxx_omp_privatize_by_reference (const_tree decl)
+{
+ return (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
+ || is_invisiref_parm (decl));
+}
+
+/* Return true if DECL is const qualified var having no mutable member. */
+bool
+cxx_omp_const_qual_no_mutable (tree decl)
+{
+ tree type = TREE_TYPE (decl);
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (!is_invisiref_parm (decl))
+ return false;
+ type = TREE_TYPE (type);
+
+ if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
+ {
+ /* NVR doesn't preserve const qualification of the
+ variable's type. */
+ tree outer = outer_curly_brace_block (current_function_decl);
+ tree var;
+
+ if (outer)
+ for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
+ if (DECL_NAME (decl) == DECL_NAME (var)
+ && (TYPE_MAIN_VARIANT (type)
+ == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
+ {
+ if (TYPE_READONLY (TREE_TYPE (var)))
+ type = TREE_TYPE (var);
+ break;
+ }
+ }
+ }
+
+ if (type == error_mark_node)
+ return false;
+
+ /* Variables with const-qualified type having no mutable member
+ are predetermined shared. */
+ if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
+ return true;
+
+ return false;
+}
+
+/* True if OpenMP sharing attribute of DECL is predetermined. */
+
+enum omp_clause_default_kind
+cxx_omp_predetermined_sharing (tree decl)
+{
+ /* Static data members are predetermined shared. */
+ if (TREE_STATIC (decl))
+ {
+ tree ctx = CP_DECL_CONTEXT (decl);
+ if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
+ return OMP_CLAUSE_DEFAULT_SHARED;
+ }
+
+ /* Const qualified vars having no mutable member are predetermined
+ shared. */
+ if (cxx_omp_const_qual_no_mutable (decl))
+ return OMP_CLAUSE_DEFAULT_SHARED;
+
+ return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
+}
+
+/* Finalize an implicitly determined clause. */
+
+void
+cxx_omp_finish_clause (tree c)
+{
+ tree decl, inner_type;
+ bool make_shared = false;
+
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
+ return;
+
+ decl = OMP_CLAUSE_DECL (c);
+ decl = require_complete_type (decl);
+ inner_type = TREE_TYPE (decl);
+ if (decl == error_mark_node)
+ make_shared = true;
+ else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
+ {
+ if (is_invisiref_parm (decl))
+ inner_type = TREE_TYPE (inner_type);
+ else
+ {
+ error ("%qE implicitly determined as %<firstprivate%> has reference type",
+ decl);
+ make_shared = true;
+ }
+ }
+
+ /* We're interested in the base element, not arrays. */
+ while (TREE_CODE (inner_type) == ARRAY_TYPE)
+ inner_type = TREE_TYPE (inner_type);
+
+ /* Check for special function availability by building a call to one.
+ Save the results, because later we won't be in the right context
+ for making these queries. */
+ if (!make_shared
+ && CLASS_TYPE_P (inner_type)
+ && cxx_omp_create_clause_info (c, inner_type, false, true, false, true))
+ make_shared = true;
+
+ if (make_shared)
+ OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
+}
diff --git a/gcc-4.9/gcc/cp/cp-lang.c b/gcc-4.9/gcc/cp/cp-lang.c
new file mode 100644
index 000000000..c28c07a9d
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cp-lang.c
@@ -0,0 +1,223 @@
+/* Language-dependent hooks for C++.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Contributed by Alexandre Oliva <aoliva@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "cp-tree.h"
+#include "c-family/c-common.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+#include "debug.h"
+#include "cp-objcp-common.h"
+#include "hashtab.h"
+#include "target.h"
+#include "parser.h"
+
+enum c_language_kind c_language = clk_cxx;
+static void cp_init_ts (void);
+static const char * cxx_dwarf_name (tree t, int verbosity);
+static enum classify_record cp_classify_record (tree type);
+static tree cp_eh_personality (void);
+static tree get_template_innermost_arguments_folded (const_tree);
+static tree get_template_argument_pack_elems_folded (const_tree);
+
+/* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h;
+ consequently, there should be very few hooks below. */
+
+#undef LANG_HOOKS_NAME
+#define LANG_HOOKS_NAME "GNU C++"
+#undef LANG_HOOKS_INIT
+#define LANG_HOOKS_INIT cxx_init
+#undef LANG_HOOKS_CLASSIFY_RECORD
+#define LANG_HOOKS_CLASSIFY_RECORD cp_classify_record
+#undef LANG_HOOKS_GENERIC_TYPE_P
+#define LANG_HOOKS_GENERIC_TYPE_P class_tmpl_impl_spec_p
+
+#undef LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS
+#define LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS \
+ get_primary_template_innermost_parameters
+#undef LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS
+#define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS \
+ get_template_innermost_arguments_folded
+#undef LANG_HOOKS_FUNCTION_PARAMETER_PACK_P
+#define LANG_HOOKS_FUNCTION_PARAMETER_PACK_P \
+ function_parameter_pack_p
+#undef LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS
+#define LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS \
+ get_template_argument_pack_elems_folded
+#undef LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P
+#define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P \
+ template_template_parameter_p
+#undef LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P
+#define LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P \
+ function_parameter_expanded_from_pack_p
+#undef LANG_HOOKS_GET_GENERIC_FUNCTION_DECL
+#define LANG_HOOKS_GET_GENERIC_FUNCTION_DECL get_function_template_decl
+#undef LANG_HOOKS_DWARF_NAME
+#define LANG_HOOKS_DWARF_NAME cxx_dwarf_name
+#undef LANG_HOOKS_INIT_TS
+#define LANG_HOOKS_INIT_TS cp_init_ts
+#undef LANG_HOOKS_EH_PERSONALITY
+#define LANG_HOOKS_EH_PERSONALITY cp_eh_personality
+#undef LANG_HOOKS_EH_RUNTIME_TYPE
+#define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
+
+/* Each front end provides its own lang hook initializer. */
+struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
+
+/* Lang hook routines common to C++ and ObjC++ appear in cp/cp-objcp-common.c;
+ there should be very few routines below. */
+
+/* The following function does something real, but only in Objective-C++. */
+
+tree
+objcp_tsubst_copy_and_build (tree /*t*/,
+ tree /*args*/,
+ tsubst_flags_t /*complain*/,
+ tree /*in_decl*/,
+ bool /*function_p*/)
+{
+ return NULL_TREE;
+}
+
+static void
+cp_init_ts (void)
+{
+ cp_common_init_ts ();
+
+ init_shadowed_var_for_decl ();
+}
+
+static const char *
+cxx_dwarf_name (tree t, int verbosity)
+{
+ gcc_assert (DECL_P (t));
+
+ if (DECL_NAME (t)
+ && (ANON_AGGRNAME_P (DECL_NAME (t)) || LAMBDA_TYPE_P (t)))
+ return NULL;
+ if (verbosity >= 2)
+ return decl_as_dwarf_string (t,
+ TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME
+ | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
+
+ return lang_decl_dwarf_name (t, verbosity, false);
+}
+
+static enum classify_record
+cp_classify_record (tree type)
+{
+ if (TYPE_LANG_SPECIFIC (type)
+ && CLASSTYPE_DECLARED_CLASS (type))
+ return RECORD_IS_CLASS;
+
+ return RECORD_IS_STRUCT;
+}
+
+static GTY(()) tree cp_eh_personality_decl;
+
+static tree
+cp_eh_personality (void)
+{
+ if (!cp_eh_personality_decl)
+ {
+ const char *lang = (pragma_java_exceptions ? "gcj" : "gxx");
+ cp_eh_personality_decl = build_personality_function (lang);
+ }
+
+ return cp_eh_personality_decl;
+}
+
+/* This is a subroutine of fold_cplus_constants. It returns TRUE if T
+ is a C++ specific constant that needs to be folded further before
+ being passed to the debug info emitter. */
+
+static bool
+template_arg_needs_folding (const_tree t)
+{
+ /* For now only PTRMEM_CST nodes are to be folded further. */
+ if (TREE_CODE (t) == PTRMEM_CST)
+ return true;
+ return false;
+}
+
+/* Fold the elements of the TREE_VEC C which are C++ specific nodes
+ that would need folding so that they can be processed by the debug
+ info emitter. This is a subroutine of
+ get_template_innermost_arguments_folded and
+ get_template_argument_pack_elems_folded. */
+
+static tree
+fold_cplus_constants (const_tree c)
+{
+ tree folded_elems, elems = CONST_CAST_TREE (c);
+ int vec_len, i;
+
+ if (elems == NULL_TREE || elems == error_mark_node)
+ return elems;
+
+ vec_len = TREE_VEC_LENGTH (elems);
+
+ /* First check if there is at least one element that needs
+ folding. If there is none, we just return ELEMS. Otherwise create
+ and return a new tree vector that contains the folded versions of
+ ELEMS. This is to avoid allocating memory if we don't need
+ to. */
+ for (i = 0; i < vec_len; ++i)
+ {
+ if (template_arg_needs_folding (TREE_VEC_ELT (elems, i)))
+ break;
+ }
+ if (i == vec_len)
+ return elems;
+
+ folded_elems = make_tree_vec (vec_len);
+ for (i = 0; i < vec_len; ++i)
+ {
+ tree elem = TREE_VEC_ELT (elems, i);
+ TREE_VEC_ELT (folded_elems, i) =
+ (elem && !TYPE_P (elem)) ? cplus_expand_constant (elem) : elem;
+
+ }
+ return folded_elems;
+}
+
+/* The C++ implementation of the LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS
+ hook. It returns the innermost template arguments of type T, and
+ makes sure those arguments are folded enough for the debug info
+ emitter. */
+
+static tree
+get_template_innermost_arguments_folded (const_tree t)
+{
+ return fold_cplus_constants (get_template_innermost_arguments (t));
+}
+
+static tree
+get_template_argument_pack_elems_folded (const_tree t)
+{
+ return fold_cplus_constants (get_template_argument_pack_elems (t));
+}
+
+#include "gt-cp-cp-lang.h"
+#include "gtype-cp.h"
diff --git a/gcc-4.9/gcc/cp/cp-objcp-common.c b/gcc-4.9/gcc/cp/cp-objcp-common.c
new file mode 100644
index 000000000..aa0ff839c
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cp-objcp-common.c
@@ -0,0 +1,324 @@
+/* Some code common to C++ and ObjC++ front ends.
+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
+ Contributed by Ziemowit Laski <zlaski@apple.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "cp-tree.h"
+#include "c-family/c-common.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+#include "diagnostic.h"
+#include "debug.h"
+#include "cxx-pretty-print.h"
+#include "cp-objcp-common.h"
+
+#include <new> // For placement new.
+
+/* Special routine to get the alias set for C++. */
+
+alias_set_type
+cxx_get_alias_set (tree t)
+{
+ if (IS_FAKE_BASE_TYPE (t))
+ /* The base variant of a type must be in the same alias set as the
+ complete type. */
+ return get_alias_set (TYPE_CONTEXT (t));
+
+ /* Punt on PMFs until we canonicalize functions properly. */
+ if (TYPE_PTRMEMFUNC_P (t)
+ || (POINTER_TYPE_P (t)
+ && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))))
+ return 0;
+
+ return c_common_get_alias_set (t);
+}
+
+/* Called from check_global_declarations. */
+
+bool
+cxx_warn_unused_global_decl (const_tree decl)
+{
+ if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
+ return false;
+ if (DECL_IN_SYSTEM_HEADER (decl))
+ return false;
+
+ /* Const variables take the place of #defines in C++. */
+ if (VAR_P (decl) && TREE_READONLY (decl))
+ return false;
+
+ return true;
+}
+
+/* Langhook for tree_size: determine size of our 'x' and 'c' nodes. */
+size_t
+cp_tree_size (enum tree_code code)
+{
+ switch (code)
+ {
+ case PTRMEM_CST: return sizeof (struct ptrmem_cst);
+ case BASELINK: return sizeof (struct tree_baselink);
+ case TEMPLATE_PARM_INDEX: return sizeof (template_parm_index);
+ case DEFAULT_ARG: return sizeof (struct tree_default_arg);
+ case DEFERRED_NOEXCEPT: return sizeof (struct tree_deferred_noexcept);
+ case OVERLOAD: return sizeof (struct tree_overload);
+ case STATIC_ASSERT: return sizeof (struct tree_static_assert);
+ case TYPE_ARGUMENT_PACK:
+ case TYPE_PACK_EXPANSION:
+ return sizeof (struct tree_common);
+
+ case NONTYPE_ARGUMENT_PACK:
+ case EXPR_PACK_EXPANSION:
+ return sizeof (struct tree_exp);
+
+ case ARGUMENT_PACK_SELECT:
+ return sizeof (struct tree_argument_pack_select);
+
+ case TRAIT_EXPR:
+ return sizeof (struct tree_trait_expr);
+
+ case LAMBDA_EXPR: return sizeof (struct tree_lambda_expr);
+
+ case TEMPLATE_INFO: return sizeof (struct tree_template_info);
+
+ case USERDEF_LITERAL: return sizeof (struct tree_userdef_literal);
+
+ default:
+ gcc_unreachable ();
+ }
+ /* NOTREACHED */
+}
+
+/* Returns true if T is a variably modified type, in the sense of C99.
+ FN is as passed to variably_modified_p.
+ This routine needs only check cases that cannot be handled by the
+ language-independent logic in tree.c. */
+
+bool
+cp_var_mod_type_p (tree type, tree fn)
+{
+ /* If TYPE is a pointer-to-member, it is variably modified if either
+ the class or the member are variably modified. */
+ if (TYPE_PTRMEM_P (type))
+ return (variably_modified_type_p (TYPE_PTRMEM_CLASS_TYPE (type), fn)
+ || variably_modified_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type),
+ fn));
+
+ /* All other types are not variably modified. */
+ return false;
+}
+
+/* Construct a C++-aware pretty-printer for CONTEXT. It is assumed
+ that CONTEXT->printer is an already constructed basic pretty_printer. */
+void
+cxx_initialize_diagnostics (diagnostic_context *context)
+{
+ c_common_initialize_diagnostics (context);
+
+ pretty_printer *base = context->printer;
+ cxx_pretty_printer *pp = XNEW (cxx_pretty_printer);
+ context->printer = new (pp) cxx_pretty_printer ();
+
+ /* It is safe to free this object because it was previously XNEW()'d. */
+ base->~pretty_printer ();
+ XDELETE (base);
+}
+
+/* This compares two types for equivalence ("compatible" in C-based languages).
+ This routine should only return 1 if it is sure. It should not be used
+ in contexts where erroneously returning 0 causes problems. */
+
+int
+cxx_types_compatible_p (tree x, tree y)
+{
+ return same_type_ignoring_top_level_qualifiers_p (x, y);
+}
+
+/* Return true if DECL is explicit member function. */
+
+bool
+cp_function_decl_explicit_p (tree decl)
+{
+ return (decl
+ && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl))
+ && DECL_NONCONVERTING_P (decl));
+}
+
+/* Stubs to keep c-opts.c happy. */
+void
+push_file_scope (void)
+{
+}
+
+void
+pop_file_scope (void)
+{
+}
+
+/* c-pragma.c needs to query whether a decl has extern "C" linkage. */
+bool
+has_c_linkage (const_tree decl)
+{
+ return DECL_EXTERN_C_P (decl);
+}
+
+static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_map)))
+ htab_t shadowed_var_for_decl;
+
+/* Lookup a shadowed var for FROM, and return it if we find one. */
+
+tree
+decl_shadowed_for_var_lookup (tree from)
+{
+ struct tree_decl_map *h, in;
+ in.base.from = from;
+
+ h = (struct tree_decl_map *)
+ htab_find_with_hash (shadowed_var_for_decl, &in, DECL_UID (from));
+ if (h)
+ return h->to;
+ return NULL_TREE;
+}
+
+/* Insert a mapping FROM->TO in the shadowed var hashtable. */
+
+void
+decl_shadowed_for_var_insert (tree from, tree to)
+{
+ struct tree_decl_map *h;
+ void **loc;
+
+ h = ggc_alloc_tree_decl_map ();
+ h->base.from = from;
+ h->to = to;
+ loc = htab_find_slot_with_hash (shadowed_var_for_decl, h, DECL_UID (from),
+ INSERT);
+ *(struct tree_decl_map **) loc = h;
+}
+
+void
+init_shadowed_var_for_decl (void)
+{
+ shadowed_var_for_decl = htab_create_ggc (512, tree_decl_map_hash,
+ tree_decl_map_eq, 0);
+}
+
+/* Return true if stmt can fall through. Used by block_may_fallthru
+ default case. */
+
+bool
+cxx_block_may_fallthru (const_tree stmt)
+{
+ switch (TREE_CODE (stmt))
+ {
+ case EXPR_STMT:
+ return block_may_fallthru (EXPR_STMT_EXPR (stmt));
+
+ case THROW_EXPR:
+ return false;
+
+ default:
+ return true;
+ }
+}
+
+void
+cp_common_init_ts (void)
+{
+ MARK_TS_DECL_NON_COMMON (NAMESPACE_DECL);
+ MARK_TS_DECL_NON_COMMON (USING_DECL);
+ MARK_TS_DECL_NON_COMMON (TEMPLATE_DECL);
+
+ MARK_TS_COMMON (TEMPLATE_TEMPLATE_PARM);
+ MARK_TS_COMMON (TEMPLATE_TYPE_PARM);
+ MARK_TS_COMMON (TEMPLATE_PARM_INDEX);
+ MARK_TS_COMMON (OVERLOAD);
+ MARK_TS_COMMON (TEMPLATE_INFO);
+ MARK_TS_COMMON (TYPENAME_TYPE);
+ MARK_TS_COMMON (TYPEOF_TYPE);
+ MARK_TS_COMMON (UNDERLYING_TYPE);
+ MARK_TS_COMMON (BASELINK);
+ MARK_TS_COMMON (TYPE_PACK_EXPANSION);
+ MARK_TS_COMMON (TYPE_ARGUMENT_PACK);
+ MARK_TS_COMMON (DECLTYPE_TYPE);
+ MARK_TS_COMMON (BOUND_TEMPLATE_TEMPLATE_PARM);
+ MARK_TS_COMMON (UNBOUND_CLASS_TEMPLATE);
+
+ MARK_TS_TYPED (EXPR_PACK_EXPANSION);
+ MARK_TS_TYPED (SWITCH_STMT);
+ MARK_TS_TYPED (IF_STMT);
+ MARK_TS_TYPED (FOR_STMT);
+ MARK_TS_TYPED (RANGE_FOR_STMT);
+ MARK_TS_TYPED (AGGR_INIT_EXPR);
+ MARK_TS_TYPED (EXPR_STMT);
+ MARK_TS_TYPED (EH_SPEC_BLOCK);
+ MARK_TS_TYPED (CLEANUP_STMT);
+ MARK_TS_TYPED (SCOPE_REF);
+ MARK_TS_TYPED (CAST_EXPR);
+ MARK_TS_TYPED (NON_DEPENDENT_EXPR);
+ MARK_TS_TYPED (MODOP_EXPR);
+ MARK_TS_TYPED (TRY_BLOCK);
+ MARK_TS_TYPED (THROW_EXPR);
+ MARK_TS_TYPED (HANDLER);
+ MARK_TS_TYPED (REINTERPRET_CAST_EXPR);
+ MARK_TS_TYPED (CONST_CAST_EXPR);
+ MARK_TS_TYPED (STATIC_CAST_EXPR);
+ MARK_TS_TYPED (DYNAMIC_CAST_EXPR);
+ MARK_TS_TYPED (IMPLICIT_CONV_EXPR);
+ MARK_TS_TYPED (TEMPLATE_ID_EXPR);
+ MARK_TS_TYPED (ARROW_EXPR);
+ MARK_TS_TYPED (SIZEOF_EXPR);
+ MARK_TS_TYPED (ALIGNOF_EXPR);
+ MARK_TS_TYPED (AT_ENCODE_EXPR);
+ MARK_TS_TYPED (UNARY_PLUS_EXPR);
+ MARK_TS_TYPED (TRAIT_EXPR);
+ MARK_TS_TYPED (TYPE_ARGUMENT_PACK);
+ MARK_TS_TYPED (NOEXCEPT_EXPR);
+ MARK_TS_TYPED (NONTYPE_ARGUMENT_PACK);
+ MARK_TS_TYPED (WHILE_STMT);
+ MARK_TS_TYPED (NEW_EXPR);
+ MARK_TS_TYPED (VEC_NEW_EXPR);
+ MARK_TS_TYPED (BREAK_STMT);
+ MARK_TS_TYPED (MEMBER_REF);
+ MARK_TS_TYPED (DOTSTAR_EXPR);
+ MARK_TS_TYPED (DO_STMT);
+ MARK_TS_TYPED (DELETE_EXPR);
+ MARK_TS_TYPED (VEC_DELETE_EXPR);
+ MARK_TS_TYPED (CONTINUE_STMT);
+ MARK_TS_TYPED (TAG_DEFN);
+ MARK_TS_TYPED (PSEUDO_DTOR_EXPR);
+ MARK_TS_TYPED (TYPEID_EXPR);
+ MARK_TS_TYPED (MUST_NOT_THROW_EXPR);
+ MARK_TS_TYPED (STMT_EXPR);
+ MARK_TS_TYPED (OFFSET_REF);
+ MARK_TS_TYPED (OFFSETOF_EXPR);
+ MARK_TS_TYPED (PTRMEM_CST);
+ MARK_TS_TYPED (EMPTY_CLASS_EXPR);
+ MARK_TS_TYPED (VEC_INIT_EXPR);
+ MARK_TS_TYPED (USING_STMT);
+ MARK_TS_TYPED (LAMBDA_EXPR);
+ MARK_TS_TYPED (CTOR_INITIALIZER);
+ MARK_TS_TYPED (ARRAY_NOTATION_REF);
+}
+
+#include "gt-cp-cp-objcp-common.h"
diff --git a/gcc-4.9/gcc/cp/cp-objcp-common.h b/gcc-4.9/gcc/cp/cp-objcp-common.h
new file mode 100644
index 000000000..246800eef
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cp-objcp-common.h
@@ -0,0 +1,156 @@
+/* Language hooks common to C++ and ObjC++ front ends.
+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
+ Contributed by Ziemowit Laski <zlaski@apple.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_CP_OBJCP_COMMON
+#define GCC_CP_OBJCP_COMMON
+
+/* In cp/cp-lang.c and objcp/objcp-lang.c. */
+
+extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
+ tree, bool);
+
+extern bool cp_function_decl_explicit_p (tree decl);
+extern void cp_common_init_ts (void);
+
+/* Lang hooks that are shared between C++ and ObjC++ are defined here. Hooks
+ specific to C++ or ObjC++ go in cp/cp-lang.c and objcp/objcp-lang.c,
+ respectively. */
+
+#undef LANG_HOOKS_FREE_LANG_DATA
+#define LANG_HOOKS_FREE_LANG_DATA cp_free_lang_data
+#undef LANG_HOOKS_TREE_SIZE
+#define LANG_HOOKS_TREE_SIZE cp_tree_size
+#undef LANG_HOOKS_FINISH
+#define LANG_HOOKS_FINISH cxx_finish
+#undef LANG_HOOKS_CLEAR_BINDING_STACK
+#define LANG_HOOKS_CLEAR_BINDING_STACK pop_everything
+#undef LANG_HOOKS_OPTION_LANG_MASK
+#define LANG_HOOKS_OPTION_LANG_MASK c_common_option_lang_mask
+#undef LANG_HOOKS_COMPLAIN_WRONG_LANG_P
+#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P c_common_complain_wrong_lang_p
+#undef LANG_HOOKS_INIT_OPTIONS_STRUCT
+#define LANG_HOOKS_INIT_OPTIONS_STRUCT c_common_init_options_struct
+#undef LANG_HOOKS_INIT_OPTIONS
+#define LANG_HOOKS_INIT_OPTIONS c_common_init_options
+#undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS
+#define LANG_HOOKS_INITIALIZE_DIAGNOSTICS cxx_initialize_diagnostics
+#undef LANG_HOOKS_HANDLE_OPTION
+#define LANG_HOOKS_HANDLE_OPTION c_common_handle_option
+#undef LANG_HOOKS_HANDLE_FILENAME
+#define LANG_HOOKS_HANDLE_FILENAME c_common_handle_filename
+#undef LANG_HOOKS_POST_OPTIONS
+#define LANG_HOOKS_POST_OPTIONS c_common_post_options
+#undef LANG_HOOKS_GET_ALIAS_SET
+#define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set
+#undef LANG_HOOKS_PARSE_FILE
+#define LANG_HOOKS_PARSE_FILE c_common_parse_file
+#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
+#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl
+#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
+#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME mangle_decl
+#undef LANG_HOOKS_PRINT_STATISTICS
+#define LANG_HOOKS_PRINT_STATISTICS cxx_print_statistics
+#undef LANG_HOOKS_PRINT_XNODE
+#define LANG_HOOKS_PRINT_XNODE cxx_print_xnode
+#undef LANG_HOOKS_DECL_PRINTABLE_NAME
+#define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name
+#undef LANG_HOOKS_PRINT_DECL
+#define LANG_HOOKS_PRINT_DECL cxx_print_decl
+#undef LANG_HOOKS_PRINT_TYPE
+#define LANG_HOOKS_PRINT_TYPE cxx_print_type
+#undef LANG_HOOKS_PRINT_IDENTIFIER
+#define LANG_HOOKS_PRINT_IDENTIFIER cxx_print_identifier
+#undef LANG_HOOKS_TYPES_COMPATIBLE_P
+#define LANG_HOOKS_TYPES_COMPATIBLE_P cxx_types_compatible_p
+#undef LANG_HOOKS_PRINT_ERROR_FUNCTION
+#define LANG_HOOKS_PRINT_ERROR_FUNCTION cxx_print_error_function
+#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
+#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl
+#undef LANG_HOOKS_WRITE_GLOBALS
+#define LANG_HOOKS_WRITE_GLOBALS cp_write_global_declarations
+#undef LANG_HOOKS_BUILTIN_FUNCTION
+#define LANG_HOOKS_BUILTIN_FUNCTION cxx_builtin_function
+#undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
+#define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE cxx_builtin_function_ext_scope
+#undef LANG_HOOKS_TYPE_HASH_EQ
+#define LANG_HOOKS_TYPE_HASH_EQ cxx_type_hash_eq
+#undef LANG_HOOKS_MISSING_NORETURN_OK_P
+#define LANG_HOOKS_MISSING_NORETURN_OK_P cp_missing_noreturn_ok_p
+#undef LANG_HOOKS_BLOCK_MAY_FALLTHRU
+#define LANG_HOOKS_BLOCK_MAY_FALLTHRU cxx_block_may_fallthru
+
+/* Attribute hooks. */
+#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
+#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table
+#undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
+#define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE c_common_format_attribute_table
+#undef LANG_HOOKS_ATTRIBUTE_TABLE
+#define LANG_HOOKS_ATTRIBUTE_TABLE cxx_attribute_table
+
+#undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P
+#define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P cp_var_mod_type_p
+#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
+#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree
+#undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN
+#define LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN cp_type_quals
+
+#undef LANG_HOOKS_MAKE_TYPE
+#define LANG_HOOKS_MAKE_TYPE cxx_make_type
+#undef LANG_HOOKS_TYPE_FOR_MODE
+#define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode
+#undef LANG_HOOKS_TYPE_FOR_SIZE
+#define LANG_HOOKS_TYPE_FOR_SIZE c_common_type_for_size
+#undef LANG_HOOKS_INCOMPLETE_TYPE_ERROR
+#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR cxx_incomplete_type_error
+#undef LANG_HOOKS_TYPE_PROMOTES_TO
+#define LANG_HOOKS_TYPE_PROMOTES_TO cxx_type_promotes_to
+#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
+#define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
+#undef LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE
+#define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE cp_reconstruct_complex_type
+#undef LANG_HOOKS_TO_TARGET_CHARSET
+#define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset
+#undef LANG_HOOKS_GIMPLIFY_EXPR
+#define LANG_HOOKS_GIMPLIFY_EXPR cp_gimplify_expr
+#undef LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P
+#define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P cp_function_decl_explicit_p
+#undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
+#define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
+#undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
+#define LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR cxx_omp_clause_default_ctor
+#undef LANG_HOOKS_OMP_CLAUSE_COPY_CTOR
+#define LANG_HOOKS_OMP_CLAUSE_COPY_CTOR cxx_omp_clause_copy_ctor
+#undef LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP
+#define LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP cxx_omp_clause_assign_op
+#undef LANG_HOOKS_OMP_CLAUSE_DTOR
+#define LANG_HOOKS_OMP_CLAUSE_DTOR cxx_omp_clause_dtor
+#undef LANG_HOOKS_OMP_FINISH_CLAUSE
+#define LANG_HOOKS_OMP_FINISH_CLAUSE cxx_omp_finish_clause
+#undef LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE
+#define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE cxx_omp_privatize_by_reference
+#undef LANG_HOOKS_OMP_MAPPABLE_TYPE
+#define LANG_HOOKS_OMP_MAPPABLE_TYPE cp_omp_mappable_type
+
+#undef LANG_HOOKS_EH_USE_CXA_END_CLEANUP
+#define LANG_HOOKS_EH_USE_CXA_END_CLEANUP true
+
+#undef LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS
+#define LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS cp_protect_cleanup_actions
+#endif /* GCC_CP_OBJCP_COMMON */
diff --git a/gcc-4.9/gcc/cp/cp-tree.def b/gcc-4.9/gcc/cp/cp-tree.def
new file mode 100644
index 000000000..057e7ea5e
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cp-tree.def
@@ -0,0 +1,479 @@
+/* This file contains the definitions and documentation for the
+ additional tree codes used in the GNU C++ compiler (see tree.def
+ for the standard codes).
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Hacked by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* An OFFSET_REF is used in two situations:
+
+ 1. An expression of the form `A::m' where `A' is a class and `m' is
+ a non-static member. In this case, operand 0 will be a TYPE
+ (corresponding to `A') and operand 1 will be a FIELD_DECL,
+ BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m').
+
+ The expression is a pointer-to-member if its address is taken,
+ but simply denotes a member of the object if its address is not
+ taken.
+
+ This form is only used during the parsing phase; once semantic
+ analysis has taken place they are eliminated.
+
+ 2. An expression of the form `x.*p'. In this case, operand 0 will
+ be an expression corresponding to `x' and operand 1 will be an
+ expression with pointer-to-member type. */
+DEFTREECODE (OFFSET_REF, "offset_ref", tcc_reference, 2)
+
+/* A pointer-to-member constant. For a pointer-to-member constant
+ `X::Y' The PTRMEM_CST_CLASS is the RECORD_TYPE for `X' and the
+ PTRMEM_CST_MEMBER is the _DECL for `Y'. */
+DEFTREECODE (PTRMEM_CST, "ptrmem_cst", tcc_constant, 0)
+
+/* For NEW_EXPR, operand 0 is the placement list.
+ Operand 1 is the new-declarator.
+ Operand 2 is the number of elements in the array.
+ Operand 3 is the initializer. */
+DEFTREECODE (NEW_EXPR, "nw_expr", tcc_expression, 4)
+DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", tcc_expression, 3)
+
+/* For DELETE_EXPR, operand 0 is the store to be destroyed.
+ Operand 1 is the value to pass to the destroying function
+ saying whether the store should be deallocated as well. */
+DEFTREECODE (DELETE_EXPR, "dl_expr", tcc_expression, 2)
+DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", tcc_expression, 2)
+
+/* Value is reference to particular overloaded class method.
+ Operand 0 is the class, operand 1 is the field
+ The COMPLEXITY field holds the class level (usually 0). */
+DEFTREECODE (SCOPE_REF, "scope_ref", tcc_reference, 2)
+
+/* When composing an object with a member, this is the result.
+ Operand 0 is the object. Operand 1 is the member (usually
+ a dereferenced pointer to member). */
+DEFTREECODE (MEMBER_REF, "member_ref", tcc_reference, 2)
+
+/* Type conversion operator in C++. TREE_TYPE is type that this
+ operator converts to. Operand is expression to be converted. */
+DEFTREECODE (TYPE_EXPR, "type_expr", tcc_expression, 1)
+
+/* AGGR_INIT_EXPRs have a variably-sized representation similar to
+ that of CALL_EXPRs. Operand 0 is an INTEGER_CST node containing the
+ operand count, operand 1 is the function which performs initialization,
+ operand 2 is the slot which was allocated for this expression, and
+ the remaining operands are the arguments to the initialization function. */
+DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", tcc_vl_exp, 3)
+
+/* Initialization of an array from another array, expressed at a high level
+ so that it works with TARGET_EXPR. Operand 0 is the target, operand 1
+ is the initializer. */
+DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", tcc_expression, 2)
+
+/* A throw expression. operand 0 is the expression, if there was one,
+ else it is NULL_TREE. */
+DEFTREECODE (THROW_EXPR, "throw_expr", tcc_expression, 1)
+
+/* An empty class object. The TREE_TYPE gives the class type. We use
+ these to avoid actually creating instances of the empty classes. */
+DEFTREECODE (EMPTY_CLASS_EXPR, "empty_class_expr", tcc_expression, 0)
+
+/* A reference to a member function or member functions from a base
+ class. BASELINK_FUNCTIONS gives the FUNCTION_DECL,
+ TEMPLATE_DECL, OVERLOAD, or TEMPLATE_ID_EXPR corresponding to the
+ functions. BASELINK_BINFO gives the base from which the functions
+ come, i.e., the base to which the `this' pointer must be converted
+ before the functions are called. BASELINK_ACCESS_BINFO gives the
+ base used to name the functions.
+
+ A BASELINK is an expression; the TREE_TYPE of the BASELINK gives
+ the type of the expression. This type is either a FUNCTION_TYPE,
+ METHOD_TYPE, or `unknown_type_node' indicating that the function is
+ overloaded. */
+DEFTREECODE (BASELINK, "baselink", tcc_exceptional, 0)
+
+/* Template definition. The following fields have the specified uses,
+ although there are other macros in cp-tree.h that should be used for
+ accessing this data.
+ DECL_ARGUMENTS template parm vector
+ DECL_TEMPLATE_INFO template text &c
+ DECL_VINDEX list of instantiations already produced;
+ only done for functions so far
+ For class template:
+ DECL_INITIAL associated templates (methods &c)
+ DECL_TEMPLATE_RESULT null
+ For non-class templates:
+ TREE_TYPE type of object to be constructed
+ DECL_TEMPLATE_RESULT decl for object to be created
+ (e.g., FUNCTION_DECL with tmpl parms used)
+ */
+DEFTREECODE (TEMPLATE_DECL, "template_decl", tcc_declaration, 0)
+
+/* Index into a template parameter list. The TEMPLATE_PARM_IDX gives
+ the index (from 0) of the parameter, while the TEMPLATE_PARM_LEVEL
+ gives the level (from 1) of the parameter.
+
+ Here's an example:
+
+ template <class T> // Index 0, Level 1.
+ struct S
+ {
+ template <class U, // Index 0, Level 2.
+ class V> // Index 1, Level 2.
+ void f();
+ };
+
+ The DESCENDANTS will be a chain of TEMPLATE_PARM_INDEXs descended
+ from this one. The first descendant will have the same IDX, but
+ its LEVEL will be one less. The TREE_CHAIN field is used to chain
+ together the descendants. The TEMPLATE_PARM_DECL is the
+ declaration of this parameter, either a TYPE_DECL or CONST_DECL.
+ The TEMPLATE_PARM_ORIG_LEVEL is the LEVEL of the most distant
+ parent, i.e., the LEVEL that the parameter originally had when it
+ was declared. For example, if we instantiate S<int>, we will have:
+
+ struct S<int>
+ {
+ template <class U, // Index 0, Level 1, Orig Level 2
+ class V> // Index 1, Level 1, Orig Level 2
+ void f();
+ };
+
+ The LEVEL is the level of the parameter when we are worrying about
+ the types of things; the ORIG_LEVEL is the level when we are
+ worrying about instantiating things. */
+DEFTREECODE (TEMPLATE_PARM_INDEX, "template_parm_index", tcc_exceptional, 0)
+
+/* Index into a template parameter list for template template parameters.
+ This parameter must be a type. The TYPE_FIELDS value will be a
+ TEMPLATE_PARM_INDEX.
+
+ It is used without template arguments like TT in C<TT>,
+ TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO is NULL_TREE
+ and TYPE_NAME is a TEMPLATE_DECL. */
+DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", tcc_type, 0)
+
+/* The ordering of the following codes is optimized for the checking
+ macros in tree.h. Changing the order will degrade the speed of the
+ compiler. TEMPLATE_TYPE_PARM, TYPENAME_TYPE, TYPEOF_TYPE,
+ BOUND_TEMPLATE_TEMPLATE_PARM. */
+
+/* Index into a template parameter list. This parameter must be a type.
+ The type.values field will be a TEMPLATE_PARM_INDEX. */
+DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", tcc_type, 0)
+
+/* A type designated by `typename T::t'. TYPE_CONTEXT is `T',
+ TYPE_NAME is an IDENTIFIER_NODE for `t'. If the type was named via
+ template-id, TYPENAME_TYPE_FULLNAME will hold the TEMPLATE_ID_EXPR.
+ TREE_TYPE is always NULL. */
+DEFTREECODE (TYPENAME_TYPE, "typename_type", tcc_type, 0)
+
+/* A type designated by `__typeof (expr)'. TYPEOF_TYPE_EXPR is the
+ expression in question. */
+DEFTREECODE (TYPEOF_TYPE, "typeof_type", tcc_type, 0)
+
+/* Like TEMPLATE_TEMPLATE_PARM it is used with bound template arguments
+ like TT<int>.
+ In this case, TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO contains the
+ template name and its bound arguments. TYPE_NAME is a TYPE_DECL. */
+DEFTREECODE (BOUND_TEMPLATE_TEMPLATE_PARM, "bound_template_template_parm",
+ tcc_type, 0)
+
+/* For template template argument of the form `T::template C'.
+ TYPE_CONTEXT is `T', the template parameter dependent object.
+ TYPE_NAME is an IDENTIFIER_NODE for `C', the member class template. */
+DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", tcc_type, 0)
+
+/* A using declaration. USING_DECL_SCOPE contains the specified
+ scope. In a member using decl, unless DECL_DEPENDENT_P is true,
+ USING_DECL_DECLS contains the _DECL or OVERLOAD so named. This is
+ not an alias, but is later expanded into multiple aliases. */
+DEFTREECODE (USING_DECL, "using_decl", tcc_declaration, 0)
+
+/* A using directive. The operand is USING_STMT_NAMESPACE. */
+DEFTREECODE (USING_STMT, "using_stmt", tcc_statement, 1)
+
+/* An un-parsed default argument. Holds a vector of input tokens and
+ a vector of places where the argument was instantiated before
+ parsing had occurred. */
+DEFTREECODE (DEFAULT_ARG, "default_arg", tcc_exceptional, 0)
+
+/* An uninstantiated noexcept-specification. DEFERRED_NOEXCEPT_PATTERN is
+ the pattern from the template, and DEFERRED_NOEXCEPT_ARGS are the
+ template arguments to substitute into the pattern when needed. */
+DEFTREECODE (DEFERRED_NOEXCEPT, "deferred_noexcept", tcc_exceptional, 0)
+
+/* A template-id, like foo<int>. The first operand is the template.
+ The second is NULL if there are no explicit arguments, or a
+ TREE_VEC of arguments. The template will be a FUNCTION_DECL,
+ TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a
+ member template, the template may be an IDENTIFIER_NODE. */
+DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", tcc_expression, 2)
+
+/* A list-like node for chaining overloading candidates. TREE_TYPE is
+ the original name, and the parameter is the FUNCTION_DECL. */
+DEFTREECODE (OVERLOAD, "overload", tcc_exceptional, 0)
+
+/* A pseudo-destructor, of the form "OBJECT.~DESTRUCTOR" or
+ "OBJECT.SCOPE::~DESTRUCTOR. The first operand is the OBJECT. The
+ second operand (if non-NULL) is the SCOPE. The third operand is
+ the TYPE node corresponding to the DESTRUCTOR. The type of the
+ first operand will always be a scalar type.
+
+ The type of a PSEUDO_DTOR_EXPR is always "void", even though it can
+ be used as if it were a zero-argument function. We handle the
+ function-call case specially, and giving it "void" type prevents it
+ being used in expressions in ways that are not permitted. */
+DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", tcc_expression, 3)
+
+/* A whole bunch of tree codes for the initial, superficial parsing of
+ templates. */
+DEFTREECODE (MODOP_EXPR, "modop_expr", tcc_expression, 3)
+DEFTREECODE (CAST_EXPR, "cast_expr", tcc_unary, 1)
+DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", tcc_unary, 1)
+DEFTREECODE (CONST_CAST_EXPR, "const_cast_expr", tcc_unary, 1)
+DEFTREECODE (STATIC_CAST_EXPR, "static_cast_expr", tcc_unary, 1)
+DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", tcc_unary, 1)
+DEFTREECODE (IMPLICIT_CONV_EXPR, "implicit_conv_expr", tcc_unary, 1)
+DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", tcc_expression, 2)
+DEFTREECODE (TYPEID_EXPR, "typeid_expr", tcc_expression, 1)
+DEFTREECODE (NOEXCEPT_EXPR, "noexcept_expr", tcc_unary, 1)
+
+/* A placeholder for an expression that is not type-dependent, but
+ does occur in a template. When an expression that is not
+ type-dependent appears in a larger expression, we must compute the
+ type of that larger expression. That computation would normally
+ modify the original expression, which would change the mangling of
+ that expression if it appeared in a template argument list. In
+ that situation, we create a NON_DEPENDENT_EXPR to take the place of
+ the original expression. The expression is the only operand -- it
+ is only needed for diagnostics. */
+DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", tcc_expression, 1)
+
+/* CTOR_INITIALIZER is a placeholder in template code for a call to
+ setup_vtbl_pointer (and appears in all functions, not just ctors). */
+DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", tcc_expression, 1)
+
+DEFTREECODE (TRY_BLOCK, "try_block", tcc_statement, 2)
+
+DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", tcc_statement, 2)
+
+/* A HANDLER wraps a catch handler for the HANDLER_TYPE. If this is
+ CATCH_ALL_TYPE, then the handler catches all types. The declaration of
+ the catch variable is in HANDLER_PARMS, and the body block in
+ HANDLER_BODY. */
+DEFTREECODE (HANDLER, "handler", tcc_statement, 2)
+
+/* A MUST_NOT_THROW_EXPR wraps an expression that may not
+ throw, and must call terminate if it does. The second argument
+ is a condition, used in templates to express noexcept (condition). */
+DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", tcc_expression, 2)
+
+/* A CLEANUP_STMT marks the point at which a declaration is fully
+ constructed. The CLEANUP_EXPR is run on behalf of CLEANUP_DECL
+ when CLEANUP_BODY completes. */
+DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", tcc_statement, 3)
+
+/* Represents an 'if' statement. The operands are IF_COND,
+ THEN_CLAUSE, and ELSE_CLAUSE, and the current scope, respectively. */
+/* ??? It is currently still necessary to distinguish between IF_STMT
+ and COND_EXPR for the benefit of templates. */
+DEFTREECODE (IF_STMT, "if_stmt", tcc_statement, 4)
+
+/* Used to represent a `for' statement. The operands are
+ FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */
+DEFTREECODE (FOR_STMT, "for_stmt", tcc_statement, 5)
+
+/* Used to represent a range-based `for' statement. The operands are
+ RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY, and RANGE_FOR_SCOPE,
+ respectively. Only used in templates. */
+DEFTREECODE (RANGE_FOR_STMT, "range_for_stmt", tcc_statement, 4)
+
+/* Used to represent a 'while' statement. The operands are WHILE_COND
+ and WHILE_BODY, respectively. */
+DEFTREECODE (WHILE_STMT, "while_stmt", tcc_statement, 2)
+
+/* Used to represent a 'do' statement. The operands are DO_BODY and
+ DO_COND, respectively. */
+DEFTREECODE (DO_STMT, "do_stmt", tcc_statement, 2)
+
+/* Used to represent a 'break' statement. */
+DEFTREECODE (BREAK_STMT, "break_stmt", tcc_statement, 0)
+
+/* Used to represent a 'continue' statement. */
+DEFTREECODE (CONTINUE_STMT, "continue_stmt", tcc_statement, 0)
+
+/* Used to represent a 'switch' statement. The operands are
+ SWITCH_STMT_COND, SWITCH_STMT_BODY, SWITCH_STMT_TYPE, and
+ SWITCH_STMT_SCOPE, respectively. */
+DEFTREECODE (SWITCH_STMT, "switch_stmt", tcc_statement, 4)
+
+/* Used to represent an expression statement. Use `EXPR_STMT_EXPR' to
+ obtain the expression. */
+DEFTREECODE (EXPR_STMT, "expr_stmt", tcc_expression, 1)
+
+DEFTREECODE (TAG_DEFN, "tag_defn", tcc_expression, 0)
+
+/* Represents an 'offsetof' expression during template expansion. */
+DEFTREECODE (OFFSETOF_EXPR, "offsetof_expr", tcc_expression, 1)
+
+/* Represents the -> operator during template expansion. */
+DEFTREECODE (ARROW_EXPR, "arrow_expr", tcc_expression, 1)
+
+/* Represents an '__alignof__' expression during template
+ expansion. */
+DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", tcc_expression, 1)
+
+/* Represents an Objective-C++ '@encode' expression during template
+ expansion. */
+DEFTREECODE (AT_ENCODE_EXPR, "at_encode_expr", tcc_expression, 1)
+
+/* A STMT_EXPR represents a statement-expression during template
+ expansion. This is the GCC extension { ( ... ) }. The
+ STMT_EXPR_STMT is the statement given by the expression. */
+DEFTREECODE (STMT_EXPR, "stmt_expr", tcc_expression, 1)
+
+/* Unary plus. Operand 0 is the expression to which the unary plus
+ is applied. */
+DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", tcc_unary, 1)
+
+/** C++0x extensions. */
+
+/* A static assertion. This is a C++0x extension.
+ STATIC_ASSERT_CONDITION contains the condition that is being
+ checked. STATIC_ASSERT_MESSAGE contains the message (a string
+ literal) to be displayed if the condition fails to hold. */
+DEFTREECODE (STATIC_ASSERT, "static_assert", tcc_exceptional, 0)
+
+/* Represents an argument pack of types (or templates). An argument
+ pack stores zero or more arguments that will be used to instantiate
+ a parameter pack.
+
+ ARGUMENT_PACK_ARGS retrieves the arguments stored in the argument
+ pack.
+
+ Example:
+ template<typename... Values>
+ class tuple { ... };
+
+ tuple<int, float, double> t;
+
+ Values is a (template) parameter pack. When tuple<int, float,
+ double> is instantiated, the Values parameter pack is instantiated
+ with the argument pack <int, float, double>. ARGUMENT_PACK_ARGS will
+ be a TREE_VEC containing int, float, and double. */
+DEFTREECODE (TYPE_ARGUMENT_PACK, "type_argument_pack", tcc_type, 0)
+
+/* Represents an argument pack of values, which can be used either for
+ non-type template arguments or function call arguments.
+
+ NONTYPE_ARGUMENT_PACK plays precisely the same role as
+ TYPE_ARGUMENT_PACK, but will be used for packing non-type template
+ arguments (e.g., "int... Dimensions") or function arguments ("const
+ Args&... args"). */
+DEFTREECODE (NONTYPE_ARGUMENT_PACK, "nontype_argument_pack", tcc_expression, 1)
+
+/* Represents a type expression that will be expanded into a list of
+ types when instantiated with one or more argument packs.
+
+ PACK_EXPANSION_PATTERN retrieves the expansion pattern. This is
+ the type or expression that we will substitute into with each
+ argument in an argument pack.
+
+ SET_PACK_EXPANSION_PATTERN sets the expansion pattern.
+
+ PACK_EXPANSION_PARAMETER_PACKS contains a TREE_LIST of the parameter
+ packs that are used in this pack expansion.
+
+ Example:
+ template<typename... Values>
+ struct tied : tuple<Values&...> {
+ // ...
+ };
+
+ The derivation from tuple contains a TYPE_PACK_EXPANSION for the
+ template arguments. Its PACK_EXPANSION_PATTERN is "Values&" and its
+ PACK_EXPANSION_PARAMETER_PACKS will contain "Values". */
+DEFTREECODE (TYPE_PACK_EXPANSION, "type_pack_expansion", tcc_type, 0)
+
+/* Represents an expression that will be expanded into a list of
+ expressions when instantiated with one or more argument packs.
+
+ EXPR_PACK_EXPANSION plays precisely the same role as TYPE_PACK_EXPANSION,
+ but will be used for expressions. */
+DEFTREECODE (EXPR_PACK_EXPANSION, "expr_pack_expansion", tcc_expression, 3)
+
+/* Selects the Ith parameter out of an argument pack. This node will
+ be used when instantiating pack expansions; see
+ tsubst_pack_expansion.
+
+ ARGUMENT_PACK_SELECT_FROM_PACK contains the *_ARGUMENT_PACK node
+ from which the argument will be selected.
+
+ ARGUMENT_PACK_SELECT_INDEX contains the index into the argument
+ pack that will be returned by this ARGUMENT_PACK_SELECT node. The
+ index is a machine integer. */
+DEFTREECODE (ARGUMENT_PACK_SELECT, "argument_pack_select", tcc_exceptional, 0)
+
+/** C++ extensions. */
+
+/* Represents a trait expression during template expansion. */
+DEFTREECODE (TRAIT_EXPR, "trait_expr", tcc_exceptional, 0)
+
+/* A lambda expression. This is a C++0x extension.
+ LAMBDA_EXPR_DEFAULT_CAPTURE_MODE is an enum for the default, which may be
+ none.
+ LAMBDA_EXPR_CAPTURE_LIST holds the capture-list, including `this'.
+ LAMBDA_EXPR_THIS_CAPTURE goes straight to the capture of `this', if it exists.
+ LAMBDA_EXPR_PENDING_PROXIES is a vector of capture proxies which need to
+ be pushed once scope returns to the lambda.
+ LAMBDA_EXPR_MUTABLE_P signals whether this lambda was declared mutable.
+ LAMBDA_EXPR_RETURN_TYPE holds the return type, if it was specified. */
+DEFTREECODE (LAMBDA_EXPR, "lambda_expr", tcc_exceptional, 0)
+
+/* The declared type of an expression. This is a C++0x extension.
+ DECLTYPE_TYPE_EXPR is the expression whose type we are computing.
+ DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P states whether the
+ expression was parsed as an id-expression or a member access
+ expression. When false, it was parsed as a full expression.
+ DECLTYPE_FOR_LAMBDA_CAPTURE is set if we want lambda capture semantics.
+ DECLTYPE_FOR_LAMBDA_RETURN is set if we want lambda return deduction. */
+DEFTREECODE (DECLTYPE_TYPE, "decltype_type", tcc_type, 0)
+
+/* A type designated by `__underlying_type (type)'.
+ UNDERLYING_TYPE_TYPE is the type in question. */
+DEFTREECODE (UNDERLYING_TYPE, "underlying_type", tcc_type, 0)
+
+/* A type designated by one of the bases type traits.
+ BASES_TYPE is the type in question. */
+DEFTREECODE (BASES, "bases", tcc_type, 0)
+
+/* Used to represent the template information stored by template
+ specializations.
+ The accessors are:
+ TI_TEMPLATE the template declaration associated to the specialization
+ TI_ARGS the arguments of the template specialization
+ TI_TYPEDEFS_NEEDING_ACCESS_CHECKING the vector of typedefs used in
+ the pattern of the template for which access check is needed at template
+ instantiation time. */
+DEFTREECODE (TEMPLATE_INFO, "template_info", tcc_exceptional, 0)
+
+/*
+Local variables:
+mode:c
+End:
+*/
diff --git a/gcc-4.9/gcc/cp/cp-tree.h b/gcc-4.9/gcc/cp/cp-tree.h
new file mode 100644
index 000000000..e9fe86ee4
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cp-tree.h
@@ -0,0 +1,6230 @@
+/* Definitions for C++ parsing and type checking.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Contributed by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_CP_TREE_H
+#define GCC_CP_TREE_H
+
+#include "ggc.h"
+#include "function.h"
+#include "hashtab.h"
+#include "vec.h"
+
+/* In order for the format checking to accept the C++ front end
+ diagnostic framework extensions, you must include this file before
+ diagnostic-core.h, not after. We override the definition of GCC_DIAG_STYLE
+ in c-common.h. */
+#undef GCC_DIAG_STYLE
+#define GCC_DIAG_STYLE __gcc_cxxdiag__
+#if defined(GCC_DIAGNOSTIC_CORE_H) || defined (GCC_C_COMMON_H)
+#error \
+In order for the format checking to accept the C++ front end diagnostic \
+framework extensions, you must include this file before diagnostic-core.h and \
+c-common.h, not after.
+#endif
+#include "c-family/c-common.h"
+#include "diagnostic.h"
+
+#include "name-lookup.h"
+
+/* Usage of TREE_LANG_FLAG_?:
+ 0: IDENTIFIER_MARKED (IDENTIFIER_NODEs)
+ NEW_EXPR_USE_GLOBAL (in NEW_EXPR).
+ DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR).
+ COMPOUND_EXPR_OVERLOADED (in COMPOUND_EXPR).
+ TREE_INDIRECT_USING (in NAMESPACE_DECL).
+ CLEANUP_P (in TRY_BLOCK)
+ AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
+ PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF, SCOPE_REF)
+ PAREN_STRING_LITERAL (in STRING_CST)
+ DECL_GNU_TLS_P (in VAR_DECL)
+ KOENIG_LOOKUP_P (in CALL_EXPR)
+ STATEMENT_LIST_NO_SCOPE (in STATEMENT_LIST).
+ EXPR_STMT_STMT_EXPR_RESULT (in EXPR_STMT)
+ STMT_EXPR_NO_SCOPE (in STMT_EXPR)
+ BIND_EXPR_TRY_BLOCK (in BIND_EXPR)
+ TYPENAME_IS_ENUM_P (in TYPENAME_TYPE)
+ OMP_FOR_GIMPLIFYING_P (in OMP_FOR, OMP_SIMD and OMP_DISTRIBUTE)
+ BASELINK_QUALIFIED_P (in BASELINK)
+ TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR)
+ TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX)
+ ATTR_IS_DEPENDENT (in the TREE_LIST for an attribute)
+ ABI_TAG_IMPLICIT (in the TREE_LIST for the argument of abi_tag)
+ CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR)
+ LAMBDA_EXPR_CAPTURES_THIS_P (in LAMBDA_EXPR)
+ DECLTYPE_FOR_LAMBDA_CAPTURE (in DECLTYPE_TYPE)
+ VEC_INIT_EXPR_IS_CONSTEXPR (in VEC_INIT_EXPR)
+ DECL_OVERRIDE_P (in FUNCTION_DECL)
+ IMPLICIT_CONV_EXPR_DIRECT_INIT (in IMPLICIT_CONV_EXPR)
+ TRANSACTION_EXPR_IS_STMT (in TRANSACTION_EXPR)
+ CONVERT_EXPR_VBASE_PATH (in CONVERT_EXPR)
+ OVL_ARG_DEPENDENT (in OVERLOAD)
+ PACK_EXPANSION_LOCAL_P (in *_PACK_EXPANSION)
+ TINFO_RECHECK_ACCESS_P (in TEMPLATE_INFO)
+ SIZEOF_EXPR_TYPE_P (in SIZEOF_EXPR)
+ 1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
+ TI_PENDING_TEMPLATE_FLAG.
+ TEMPLATE_PARMS_FOR_INLINE.
+ DELETE_EXPR_USE_VEC (in DELETE_EXPR).
+ (TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out).
+ ICS_ELLIPSIS_FLAG (in _CONV)
+ DECL_INITIALIZED_P (in VAR_DECL)
+ TYPENAME_IS_CLASS_P (in TYPENAME_TYPE)
+ STMT_IS_FULL_EXPR_P (in _STMT)
+ TARGET_EXPR_LIST_INIT_P (in TARGET_EXPR)
+ LAMBDA_EXPR_MUTABLE_P (in LAMBDA_EXPR)
+ DECL_FINAL_P (in FUNCTION_DECL)
+ QUALIFIED_NAME_IS_TEMPLATE (in SCOPE_REF)
+ DECLTYPE_FOR_INIT_CAPTURE (in DECLTYPE_TYPE)
+ 2: IDENTIFIER_OPNAME_P (in IDENTIFIER_NODE)
+ ICS_THIS_FLAG (in _CONV)
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL)
+ STATEMENT_LIST_TRY_BLOCK (in STATEMENT_LIST)
+ TYPENAME_IS_RESOLVING_P (in TYPE_NAME_TYPE)
+ TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR)
+ FNDECL_USED_AUTO (in FUNCTION_DECL)
+ DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE)
+ REF_PARENTHESIZED_P (in COMPONENT_REF, SCOPE_REF)
+ 3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
+ ICS_BAD_FLAG (in _CONV)
+ FN_TRY_BLOCK_P (in TRY_BLOCK)
+ IDENTIFIER_CTOR_OR_DTOR_P (in IDENTIFIER_NODE)
+ BIND_EXPR_BODY_BLOCK (in BIND_EXPR)
+ DECL_NON_TRIVIALLY_INITIALIZED_P (in VAR_DECL)
+ 4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
+ or FIELD_DECL).
+ IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE)
+ DECL_TINFO_P (in VAR_DECL)
+ FUNCTION_REF_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE)
+ 5: C_IS_RESERVED_WORD (in IDENTIFIER_NODE)
+ DECL_VTABLE_OR_VTT_P (in VAR_DECL)
+ FUNCTION_RVALUE_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE)
+ 6: IDENTIFIER_REPO_CHOSEN (in IDENTIFIER_NODE)
+ DECL_CONSTRUCTION_VTABLE_P (in VAR_DECL)
+ TYPE_MARKED_P (in _TYPE)
+ RANGE_FOR_IVDEP (in RANGE_FOR_STMT)
+
+ Usage of TYPE_LANG_FLAG_?:
+ 0: TYPE_DEPENDENT_P
+ 1: TYPE_HAS_USER_CONSTRUCTOR.
+ 2: unused
+ 3: TYPE_FOR_JAVA.
+ 4: TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+ 5: CLASS_TYPE_P (in RECORD_TYPE and UNION_TYPE)
+ ENUM_FIXED_UNDERLYING_TYPE_P (in ENUMERAL_TYPE)
+ AUTO_IS_DECLTYPE (in TEMPLATE_TYPE_PARM)
+ REFERENCE_VLA_OK (in REFERENCE_TYPE)
+ 6: TYPE_DEPENDENT_P_VALID
+
+ Usage of DECL_LANG_FLAG_?:
+ 0: DECL_ERROR_REPORTED (in VAR_DECL).
+ DECL_TEMPLATE_PARM_P (in PARM_DECL, CONST_DECL, TYPE_DECL, or TEMPLATE_DECL)
+ DECL_LOCAL_FUNCTION_P (in FUNCTION_DECL)
+ DECL_MUTABLE_P (in FIELD_DECL)
+ DECL_DEPENDENT_P (in USING_DECL)
+ 1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL).
+ DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
+ DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL)
+ USING_DECL_TYPENAME_P (in USING_DECL)
+ DECL_VLA_CAPTURE_P (in FIELD_DECL)
+ 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
+ DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL)
+ 3: DECL_IN_AGGR_P.
+ 4: DECL_C_BIT_FIELD (in a FIELD_DECL)
+ DECL_ANON_UNION_VAR_P (in a VAR_DECL)
+ DECL_SELF_REFERENCE_P (in a TYPE_DECL)
+ DECL_INVALID_OVERRIDER_P (in a FUNCTION_DECL)
+ 5: DECL_INTERFACE_KNOWN.
+ 6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL).
+ DECL_FIELD_IS_BASE (in FIELD_DECL)
+ TYPE_DECL_ALIAS_P (in TYPE_DECL)
+ 7: DECL_DEAD_FOR_LOCAL (in VAR_DECL).
+ DECL_THUNK_P (in a member FUNCTION_DECL)
+ DECL_NORMAL_CAPTURE_P (in FIELD_DECL)
+ 8: DECL_DECLARED_CONSTEXPR_P (in VAR_DECL, FUNCTION_DECL)
+
+ Usage of language-independent fields in a language-dependent manner:
+
+ TYPE_ALIAS_SET
+ This field is used by TYPENAME_TYPEs, TEMPLATE_TYPE_PARMs, and so
+ forth as a substitute for the mark bits provided in `lang_type'.
+ At present, only the six low-order bits are used.
+
+ TYPE_LANG_SLOT_1
+ For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO.
+ For a FUNCTION_TYPE or METHOD_TYPE, this is TYPE_RAISES_EXCEPTIONS
+
+ BINFO_VIRTUALS
+ For a binfo, this is a TREE_LIST. There is an entry for each
+ virtual function declared either in BINFO or its direct and
+ indirect primary bases.
+
+ The BV_DELTA of each node gives the amount by which to adjust the
+ `this' pointer when calling the function. If the method is an
+ overridden version of a base class method, then it is assumed
+ that, prior to adjustment, the this pointer points to an object
+ of the base class.
+
+ The BV_VCALL_INDEX of each node, if non-NULL, gives the vtable
+ index of the vcall offset for this entry.
+
+ The BV_FN is the declaration for the virtual function itself.
+
+ If BV_LOST_PRIMARY is set, it means that this entry is for a lost
+ primary virtual base and can be left null in the vtable.
+
+ BINFO_VTABLE
+ This is an expression with POINTER_TYPE that gives the value
+ to which the vptr should be initialized. Use get_vtbl_decl_for_binfo
+ to extract the VAR_DECL for the complete vtable.
+
+ DECL_VINDEX
+ This field is NULL for a non-virtual function. For a virtual
+ function, it is eventually set to an INTEGER_CST indicating the
+ index in the vtable at which this function can be found. When
+ a virtual function is declared, but before it is known what
+ function is overridden, this field is the error_mark_node.
+
+ Temporarily, it may be set to a TREE_LIST whose TREE_VALUE is
+ the virtual function this one overrides, and whose TREE_CHAIN is
+ the old DECL_VINDEX. */
+
+/* Language-specific tree checkers. */
+
+#define VAR_OR_FUNCTION_DECL_CHECK(NODE) \
+ TREE_CHECK2(NODE,VAR_DECL,FUNCTION_DECL)
+
+#define TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK(NODE) \
+ TREE_CHECK3(NODE,TYPE_DECL,TEMPLATE_DECL,FUNCTION_DECL)
+
+#define TYPE_FUNCTION_OR_TEMPLATE_DECL_P(NODE) \
+ (TREE_CODE (NODE) == TYPE_DECL || TREE_CODE (NODE) == TEMPLATE_DECL \
+ || TREE_CODE (NODE) == FUNCTION_DECL)
+
+#define VAR_FUNCTION_OR_PARM_DECL_CHECK(NODE) \
+ TREE_CHECK3(NODE,VAR_DECL,FUNCTION_DECL,PARM_DECL)
+
+#define VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK(NODE) \
+ TREE_CHECK4(NODE,VAR_DECL,FUNCTION_DECL,TYPE_DECL,TEMPLATE_DECL)
+
+#define VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK(NODE) \
+ TREE_CHECK5(NODE,VAR_DECL,FIELD_DECL,FUNCTION_DECL,TYPE_DECL,TEMPLATE_DECL)
+
+#define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) \
+ TREE_CHECK(NODE,BOUND_TEMPLATE_TEMPLATE_PARM)
+
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+#define THUNK_FUNCTION_CHECK(NODE) __extension__ \
+({ __typeof (NODE) const __t = (NODE); \
+ if (TREE_CODE (__t) != FUNCTION_DECL || !__t->decl_common.lang_specific \
+ || !__t->decl_common.lang_specific->u.fn.thunk_p) \
+ tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, 0); \
+ __t; })
+#else
+#define THUNK_FUNCTION_CHECK(NODE) (NODE)
+#endif
+
+/* Language-dependent contents of an identifier. */
+
+struct GTY(()) lang_identifier {
+ struct c_common_identifier c_common;
+ cxx_binding *namespace_bindings;
+ cxx_binding *bindings;
+ tree class_template_info;
+ tree label_value;
+};
+
+/* Return a typed pointer version of T if it designates a
+ C++ front-end identifier. */
+inline lang_identifier*
+identifier_p (tree t)
+{
+ if (TREE_CODE (t) == IDENTIFIER_NODE)
+ return (lang_identifier*) t;
+ return NULL;
+}
+
+/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
+ keyword. C_RID_CODE (node) is then the RID_* value of the keyword,
+ and C_RID_YYCODE is the token number wanted by Yacc. */
+
+#define C_IS_RESERVED_WORD(ID) TREE_LANG_FLAG_5 (ID)
+
+#define LANG_IDENTIFIER_CAST(NODE) \
+ ((struct lang_identifier*)IDENTIFIER_NODE_CHECK (NODE))
+
+struct GTY(()) template_parm_index_s {
+ struct tree_common common;
+ int index;
+ int level;
+ int orig_level;
+ tree decl;
+};
+typedef struct template_parm_index_s template_parm_index;
+
+struct GTY(()) ptrmem_cst {
+ struct tree_common common;
+ tree member;
+};
+typedef struct ptrmem_cst * ptrmem_cst_t;
+
+#define IDENTIFIER_GLOBAL_VALUE(NODE) \
+ namespace_binding ((NODE), global_namespace)
+#define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \
+ set_namespace_binding ((NODE), global_namespace, (VAL))
+#define IDENTIFIER_NAMESPACE_VALUE(NODE) \
+ namespace_binding ((NODE), current_namespace)
+#define SET_IDENTIFIER_NAMESPACE_VALUE(NODE, VAL) \
+ set_namespace_binding ((NODE), current_namespace, (VAL))
+
+#define CLEANUP_P(NODE) TREE_LANG_FLAG_0 (TRY_BLOCK_CHECK (NODE))
+
+#define BIND_EXPR_TRY_BLOCK(NODE) \
+ TREE_LANG_FLAG_0 (BIND_EXPR_CHECK (NODE))
+
+/* Used to mark the block around the member initializers and cleanups. */
+#define BIND_EXPR_BODY_BLOCK(NODE) \
+ TREE_LANG_FLAG_3 (BIND_EXPR_CHECK (NODE))
+#define FUNCTION_NEEDS_BODY_BLOCK(NODE) \
+ (DECL_CONSTRUCTOR_P (NODE) || DECL_DESTRUCTOR_P (NODE) \
+ || LAMBDA_FUNCTION_P (NODE))
+
+#define STATEMENT_LIST_NO_SCOPE(NODE) \
+ TREE_LANG_FLAG_0 (STATEMENT_LIST_CHECK (NODE))
+#define STATEMENT_LIST_TRY_BLOCK(NODE) \
+ TREE_LANG_FLAG_2 (STATEMENT_LIST_CHECK (NODE))
+
+/* Nonzero if this statement should be considered a full-expression,
+ i.e., if temporaries created during this statement should have
+ their destructors run at the end of this statement. */
+#define STMT_IS_FULL_EXPR_P(NODE) TREE_LANG_FLAG_1 ((NODE))
+
+/* Marks the result of a statement expression. */
+#define EXPR_STMT_STMT_EXPR_RESULT(NODE) \
+ TREE_LANG_FLAG_0 (EXPR_STMT_CHECK (NODE))
+
+/* Nonzero if this statement-expression does not have an associated scope. */
+#define STMT_EXPR_NO_SCOPE(NODE) \
+ TREE_LANG_FLAG_0 (STMT_EXPR_CHECK (NODE))
+
+/* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual
+ sense of `same'. */
+#define same_type_p(TYPE1, TYPE2) \
+ comptypes ((TYPE1), (TYPE2), COMPARE_STRICT)
+
+/* Returns nonzero iff NODE is a declaration for the global function
+ `main'. */
+#define DECL_MAIN_P(NODE) \
+ (DECL_EXTERN_C_FUNCTION_P (NODE) \
+ && DECL_NAME (NODE) != NULL_TREE \
+ && MAIN_NAME_P (DECL_NAME (NODE)) \
+ && flag_hosted)
+
+/* The overloaded FUNCTION_DECL. */
+#define OVL_FUNCTION(NODE) \
+ (((struct tree_overload*)OVERLOAD_CHECK (NODE))->function)
+#define OVL_CHAIN(NODE) TREE_CHAIN (NODE)
+/* Polymorphic access to FUNCTION and CHAIN. */
+#define OVL_CURRENT(NODE) \
+ ((TREE_CODE (NODE) == OVERLOAD) ? OVL_FUNCTION (NODE) : (NODE))
+#define OVL_NEXT(NODE) \
+ ((TREE_CODE (NODE) == OVERLOAD) ? TREE_CHAIN (NODE) : NULL_TREE)
+/* If set, this was imported in a using declaration.
+ This is not to confuse with being used somewhere, which
+ is not important for this node. */
+#define OVL_USED(NODE) TREE_USED (OVERLOAD_CHECK (NODE))
+/* If set, this OVERLOAD was created for argument-dependent lookup
+ and can be freed afterward. */
+#define OVL_ARG_DEPENDENT(NODE) TREE_LANG_FLAG_0 (OVERLOAD_CHECK (NODE))
+
+struct GTY(()) tree_overload {
+ struct tree_common common;
+ tree function;
+};
+
+/* Returns true iff NODE is a BASELINK. */
+#define BASELINK_P(NODE) \
+ (TREE_CODE (NODE) == BASELINK)
+/* The BINFO indicating the base in which lookup found the
+ BASELINK_FUNCTIONS. */
+#define BASELINK_BINFO(NODE) \
+ (((struct tree_baselink*) BASELINK_CHECK (NODE))->binfo)
+/* The functions referred to by the BASELINK; either a FUNCTION_DECL,
+ a TEMPLATE_DECL, an OVERLOAD, or a TEMPLATE_ID_EXPR. */
+#define BASELINK_FUNCTIONS(NODE) \
+ (((struct tree_baselink*) BASELINK_CHECK (NODE))->functions)
+/* The BINFO in which the search for the functions indicated by this baselink
+ began. This base is used to determine the accessibility of functions
+ selected by overload resolution. */
+#define BASELINK_ACCESS_BINFO(NODE) \
+ (((struct tree_baselink*) BASELINK_CHECK (NODE))->access_binfo)
+/* For a type-conversion operator, the BASELINK_OPTYPE indicates the type
+ to which the conversion should occur. This value is important if
+ the BASELINK_FUNCTIONS include a template conversion operator --
+ the BASELINK_OPTYPE can be used to determine what type the user
+ requested. */
+#define BASELINK_OPTYPE(NODE) \
+ (TREE_CHAIN (BASELINK_CHECK (NODE)))
+/* Nonzero if this baselink was from a qualified lookup. */
+#define BASELINK_QUALIFIED_P(NODE) \
+ TREE_LANG_FLAG_0 (BASELINK_CHECK (NODE))
+
+struct GTY(()) tree_baselink {
+ struct tree_common common;
+ tree binfo;
+ tree functions;
+ tree access_binfo;
+};
+
+/* The different kinds of ids that we encounter. */
+
+typedef enum cp_id_kind
+{
+ /* Not an id at all. */
+ CP_ID_KIND_NONE,
+ /* An unqualified-id that is not a template-id. */
+ CP_ID_KIND_UNQUALIFIED,
+ /* An unqualified-id that is a dependent name. */
+ CP_ID_KIND_UNQUALIFIED_DEPENDENT,
+ /* An unqualified template-id. */
+ CP_ID_KIND_TEMPLATE_ID,
+ /* A qualified-id. */
+ CP_ID_KIND_QUALIFIED
+} cp_id_kind;
+
+
+/* The various kinds of C++0x warnings we encounter. */
+
+typedef enum cpp0x_warn_str
+{
+ /* extended initializer lists */
+ CPP0X_INITIALIZER_LISTS,
+ /* explicit conversion operators */
+ CPP0X_EXPLICIT_CONVERSION,
+ /* variadic templates */
+ CPP0X_VARIADIC_TEMPLATES,
+ /* lambda expressions */
+ CPP0X_LAMBDA_EXPR,
+ /* C++0x auto */
+ CPP0X_AUTO,
+ /* scoped enums */
+ CPP0X_SCOPED_ENUMS,
+ /* defaulted and deleted functions */
+ CPP0X_DEFAULTED_DELETED,
+ /* inline namespaces */
+ CPP0X_INLINE_NAMESPACES,
+ /* override controls, override/final */
+ CPP0X_OVERRIDE_CONTROLS,
+ /* non-static data member initializers */
+ CPP0X_NSDMI,
+ /* user defined literals */
+ CPP0X_USER_DEFINED_LITERALS,
+ /* delegating constructors */
+ CPP0X_DELEGATING_CTORS,
+ /* inheriting constructors */
+ CPP0X_INHERITING_CTORS,
+ /* C++11 attributes */
+ CPP0X_ATTRIBUTES,
+ /* ref-qualified member functions */
+ CPP0X_REF_QUALIFIER
+} cpp0x_warn_str;
+
+/* The various kinds of operation used by composite_pointer_type. */
+
+typedef enum composite_pointer_operation
+{
+ /* comparison */
+ CPO_COMPARISON,
+ /* conversion */
+ CPO_CONVERSION,
+ /* conditional expression */
+ CPO_CONDITIONAL_EXPR
+} composite_pointer_operation;
+
+/* Possible cases of expression list used by build_x_compound_expr_from_list. */
+typedef enum expr_list_kind {
+ ELK_INIT, /* initializer */
+ ELK_MEM_INIT, /* member initializer */
+ ELK_FUNC_CAST /* functional cast */
+} expr_list_kind;
+
+/* Possible cases of implicit bad rhs conversions. */
+typedef enum impl_conv_rhs {
+ ICR_DEFAULT_ARGUMENT, /* default argument */
+ ICR_CONVERTING, /* converting */
+ ICR_INIT, /* initialization */
+ ICR_ARGPASS, /* argument passing */
+ ICR_RETURN, /* return */
+ ICR_ASSIGN /* assignment */
+} impl_conv_rhs;
+
+/* Possible cases of implicit or explicit bad conversions to void. */
+typedef enum impl_conv_void {
+ ICV_CAST, /* (explicit) conversion to void */
+ ICV_SECOND_OF_COND, /* second operand of conditional expression */
+ ICV_THIRD_OF_COND, /* third operand of conditional expression */
+ ICV_RIGHT_OF_COMMA, /* right operand of comma operator */
+ ICV_LEFT_OF_COMMA, /* left operand of comma operator */
+ ICV_STATEMENT, /* statement */
+ ICV_THIRD_IN_FOR /* for increment expression */
+} impl_conv_void;
+
+/* Possible invalid uses of an abstract class that might not have a
+ specific associated declaration. */
+typedef enum abstract_class_use {
+ ACU_UNKNOWN, /* unknown or decl provided */
+ ACU_CAST, /* cast to abstract class */
+ ACU_NEW, /* new-expression of abstract class */
+ ACU_THROW, /* throw-expression of abstract class */
+ ACU_CATCH, /* catch-parameter of abstract class */
+ ACU_ARRAY, /* array of abstract class */
+ ACU_RETURN, /* return type of abstract class */
+ ACU_PARM /* parameter type of abstract class */
+} abstract_class_use;
+
+/* Macros for access to language-specific slots in an identifier. */
+
+#define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \
+ (LANG_IDENTIFIER_CAST (NODE)->namespace_bindings)
+#define IDENTIFIER_TEMPLATE(NODE) \
+ (LANG_IDENTIFIER_CAST (NODE)->class_template_info)
+
+/* The IDENTIFIER_BINDING is the innermost cxx_binding for the
+ identifier. It's PREVIOUS is the next outermost binding. Each
+ VALUE field is a DECL for the associated declaration. Thus,
+ name lookup consists simply of pulling off the node at the front
+ of the list (modulo oddities for looking up the names of types,
+ and such.) You can use SCOPE field to determine the scope
+ that bound the name. */
+#define IDENTIFIER_BINDING(NODE) \
+ (LANG_IDENTIFIER_CAST (NODE)->bindings)
+
+/* TREE_TYPE only indicates on local and class scope the current
+ type. For namespace scope, the presence of a type in any namespace
+ is indicated with global_type_node, and the real type behind must
+ be found through lookup. */
+#define IDENTIFIER_TYPE_VALUE(NODE) identifier_type_value (NODE)
+#define REAL_IDENTIFIER_TYPE_VALUE(NODE) TREE_TYPE (NODE)
+#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = (TYPE))
+#define IDENTIFIER_HAS_TYPE_VALUE(NODE) (IDENTIFIER_TYPE_VALUE (NODE) ? 1 : 0)
+
+#define IDENTIFIER_LABEL_VALUE(NODE) \
+ (LANG_IDENTIFIER_CAST (NODE)->label_value)
+#define SET_IDENTIFIER_LABEL_VALUE(NODE, VALUE) \
+ IDENTIFIER_LABEL_VALUE (NODE) = (VALUE)
+
+/* Nonzero if this identifier is used as a virtual function name somewhere
+ (optimizes searches). */
+#define IDENTIFIER_VIRTUAL_P(NODE) TREE_LANG_FLAG_1 (NODE)
+
+/* Nonzero if this identifier is the prefix for a mangled C++ operator
+ name. */
+#define IDENTIFIER_OPNAME_P(NODE) TREE_LANG_FLAG_2 (NODE)
+
+/* Nonzero if this identifier is the name of a type-conversion
+ operator. */
+#define IDENTIFIER_TYPENAME_P(NODE) \
+ TREE_LANG_FLAG_4 (NODE)
+
+/* Nonzero if this identifier is the name of a constructor or
+ destructor. */
+#define IDENTIFIER_CTOR_OR_DTOR_P(NODE) \
+ TREE_LANG_FLAG_3 (NODE)
+
+/* True iff NAME is the DECL_ASSEMBLER_NAME for an entity with vague
+ linkage which the prelinker has assigned to this translation
+ unit. */
+#define IDENTIFIER_REPO_CHOSEN(NAME) \
+ (TREE_LANG_FLAG_6 (NAME))
+
+/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */
+#define C_TYPE_FIELDS_READONLY(TYPE) \
+ (LANG_TYPE_CLASS_CHECK (TYPE)->fields_readonly)
+
+/* The tokens stored in the default argument. */
+
+#define DEFARG_TOKENS(NODE) \
+ (((struct tree_default_arg *)DEFAULT_ARG_CHECK (NODE))->tokens)
+#define DEFARG_INSTANTIATIONS(NODE) \
+ (((struct tree_default_arg *)DEFAULT_ARG_CHECK (NODE))->instantiations)
+
+struct GTY (()) tree_default_arg {
+ struct tree_common common;
+ struct cp_token_cache *tokens;
+ vec<tree, va_gc> *instantiations;
+};
+
+
+#define DEFERRED_NOEXCEPT_PATTERN(NODE) \
+ (((struct tree_deferred_noexcept *)DEFERRED_NOEXCEPT_CHECK (NODE))->pattern)
+#define DEFERRED_NOEXCEPT_ARGS(NODE) \
+ (((struct tree_deferred_noexcept *)DEFERRED_NOEXCEPT_CHECK (NODE))->args)
+#define DEFERRED_NOEXCEPT_SPEC_P(NODE) \
+ ((NODE) && (TREE_PURPOSE (NODE)) \
+ && (TREE_CODE (TREE_PURPOSE (NODE)) == DEFERRED_NOEXCEPT \
+ || is_overloaded_fn (TREE_PURPOSE (NODE))))
+
+struct GTY (()) tree_deferred_noexcept {
+ struct tree_base base;
+ tree pattern;
+ tree args;
+};
+
+
+/* The condition associated with the static assertion. This must be
+ an integral constant expression. */
+#define STATIC_ASSERT_CONDITION(NODE) \
+ (((struct tree_static_assert *)STATIC_ASSERT_CHECK (NODE))->condition)
+
+/* The message associated with the static assertion. This must be a
+ string constant, which will be emitted as an error message when the
+ static assert condition is false. */
+#define STATIC_ASSERT_MESSAGE(NODE) \
+ (((struct tree_static_assert *)STATIC_ASSERT_CHECK (NODE))->message)
+
+/* Source location information for a static assertion. */
+#define STATIC_ASSERT_SOURCE_LOCATION(NODE) \
+ (((struct tree_static_assert *)STATIC_ASSERT_CHECK (NODE))->location)
+
+struct GTY (()) tree_static_assert {
+ struct tree_common common;
+ tree condition;
+ tree message;
+ location_t location;
+};
+
+struct GTY (()) tree_argument_pack_select {
+ struct tree_common common;
+ tree argument_pack;
+ int index;
+};
+
+/* The different kinds of traits that we encounter. */
+
+typedef enum cp_trait_kind
+{
+ CPTK_BASES,
+ CPTK_DIRECT_BASES,
+ CPTK_HAS_NOTHROW_ASSIGN,
+ CPTK_HAS_NOTHROW_CONSTRUCTOR,
+ CPTK_HAS_NOTHROW_COPY,
+ CPTK_HAS_TRIVIAL_ASSIGN,
+ CPTK_HAS_TRIVIAL_CONSTRUCTOR,
+ CPTK_HAS_TRIVIAL_COPY,
+ CPTK_HAS_TRIVIAL_DESTRUCTOR,
+ CPTK_HAS_VIRTUAL_DESTRUCTOR,
+ CPTK_IS_ABSTRACT,
+ CPTK_IS_BASE_OF,
+ CPTK_IS_CLASS,
+ CPTK_IS_CONVERTIBLE_TO,
+ CPTK_IS_EMPTY,
+ CPTK_IS_ENUM,
+ CPTK_IS_FINAL,
+ CPTK_IS_LITERAL_TYPE,
+ CPTK_IS_POD,
+ CPTK_IS_POLYMORPHIC,
+ CPTK_IS_STD_LAYOUT,
+ CPTK_IS_TRIVIAL,
+ CPTK_IS_UNION,
+ CPTK_UNDERLYING_TYPE
+} cp_trait_kind;
+
+/* The types that we are processing. */
+#define TRAIT_EXPR_TYPE1(NODE) \
+ (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->type1)
+
+#define TRAIT_EXPR_TYPE2(NODE) \
+ (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->type2)
+
+/* The specific trait that we are processing. */
+#define TRAIT_EXPR_KIND(NODE) \
+ (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->kind)
+
+struct GTY (()) tree_trait_expr {
+ struct tree_common common;
+ tree type1;
+ tree type2;
+ enum cp_trait_kind kind;
+};
+
+/* Based off of TYPE_ANONYMOUS_P. */
+#define LAMBDA_TYPE_P(NODE) \
+ (CLASS_TYPE_P (NODE) && CLASSTYPE_LAMBDA_EXPR (NODE))
+
+/* Test if FUNCTION_DECL is a lambda function. */
+#define LAMBDA_FUNCTION_P(FNDECL) \
+ (DECL_OVERLOADED_OPERATOR_P (FNDECL) == CALL_EXPR \
+ && LAMBDA_TYPE_P (CP_DECL_CONTEXT (FNDECL)))
+
+enum cp_lambda_default_capture_mode_type {
+ CPLD_NONE,
+ CPLD_COPY,
+ CPLD_REFERENCE
+};
+
+/* The method of default capture, if any. */
+#define LAMBDA_EXPR_DEFAULT_CAPTURE_MODE(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->default_capture_mode)
+
+/* The capture-list, including `this'. Each capture is stored as a FIELD_DECL
+ * so that the name, type, and field are all together, whether or not it has
+ * been added to the lambda's class type.
+ TREE_LIST:
+ TREE_PURPOSE: The FIELD_DECL for this capture.
+ TREE_VALUE: The initializer. This is part of a GNU extension. */
+#define LAMBDA_EXPR_CAPTURE_LIST(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->capture_list)
+
+/* During parsing of the lambda-introducer, the node in the capture-list
+ that holds the 'this' capture. During parsing of the body, the
+ capture proxy for that node. */
+#define LAMBDA_EXPR_THIS_CAPTURE(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->this_capture)
+
+/* Predicate tracking whether `this' is in the effective capture set. */
+#define LAMBDA_EXPR_CAPTURES_THIS_P(NODE) \
+ LAMBDA_EXPR_THIS_CAPTURE(NODE)
+
+/* Predicate tracking whether the lambda was declared 'mutable'. */
+#define LAMBDA_EXPR_MUTABLE_P(NODE) \
+ TREE_LANG_FLAG_1 (LAMBDA_EXPR_CHECK (NODE))
+
+/* The return type in the expression.
+ * NULL_TREE indicates that none was specified. */
+#define LAMBDA_EXPR_RETURN_TYPE(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->return_type)
+
+/* The source location of the lambda. */
+#define LAMBDA_EXPR_LOCATION(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->locus)
+
+/* The mangling scope for the lambda: FUNCTION_DECL, PARM_DECL, VAR_DECL,
+ FIELD_DECL or NULL_TREE. If this is NULL_TREE, we have no linkage. */
+#define LAMBDA_EXPR_EXTRA_SCOPE(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->extra_scope)
+
+/* If EXTRA_SCOPE, this is the number of the lambda within that scope. */
+#define LAMBDA_EXPR_DISCRIMINATOR(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator)
+
+/* During parsing of the lambda, a vector of capture proxies which need
+ to be pushed once we're done processing a nested lambda. */
+#define LAMBDA_EXPR_PENDING_PROXIES(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->pending_proxies)
+
+/* The closure type of the lambda. Note that the TREE_TYPE of a
+ LAMBDA_EXPR is always NULL_TREE, because we need to instantiate the
+ LAMBDA_EXPR in order to instantiate the type. */
+#define LAMBDA_EXPR_CLOSURE(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->closure)
+
+struct GTY (()) tree_lambda_expr
+{
+ struct tree_typed typed;
+ tree capture_list;
+ tree this_capture;
+ tree return_type;
+ tree extra_scope;
+ tree closure;
+ vec<tree, va_gc> *pending_proxies;
+ location_t locus;
+ enum cp_lambda_default_capture_mode_type default_capture_mode;
+ int discriminator;
+};
+
+/* A (typedef,context,usage location) triplet.
+ It represents a typedef used through a
+ context at a given source location.
+ e.g.
+ struct foo {
+ typedef int myint;
+ };
+
+ struct bar {
+ foo::myint v; // #1<-- this location.
+ };
+
+ In bar, the triplet will be (myint, foo, #1).
+ */
+struct GTY(()) qualified_typedef_usage_s {
+ tree typedef_decl;
+ tree context;
+ location_t locus;
+};
+typedef struct qualified_typedef_usage_s qualified_typedef_usage_t;
+
+/* Non-zero if this template specialization has access violations that
+ should be rechecked when the function is instantiated outside argument
+ deduction. */
+#define TINFO_HAS_ACCESS_ERRORS(NODE) \
+ (TREE_LANG_FLAG_0 (TEMPLATE_INFO_CHECK (NODE)))
+#define FNDECL_HAS_ACCESS_ERRORS(NODE) \
+ (TINFO_HAS_ACCESS_ERRORS (DECL_TEMPLATE_INFO (NODE)))
+
+struct GTY(()) tree_template_info {
+ struct tree_common common;
+ vec<qualified_typedef_usage_t, va_gc> *typedefs_needing_access_checking;
+};
+
+enum cp_tree_node_structure_enum {
+ TS_CP_GENERIC,
+ TS_CP_IDENTIFIER,
+ TS_CP_TPI,
+ TS_CP_PTRMEM,
+ TS_CP_BINDING,
+ TS_CP_OVERLOAD,
+ TS_CP_BASELINK,
+ TS_CP_WRAPPER,
+ TS_CP_DEFAULT_ARG,
+ TS_CP_DEFERRED_NOEXCEPT,
+ TS_CP_STATIC_ASSERT,
+ TS_CP_ARGUMENT_PACK_SELECT,
+ TS_CP_TRAIT_EXPR,
+ TS_CP_LAMBDA_EXPR,
+ TS_CP_TEMPLATE_INFO,
+ TS_CP_USERDEF_LITERAL,
+ LAST_TS_CP_ENUM
+};
+
+/* The resulting tree type. */
+union GTY((desc ("cp_tree_node_structure (&%h)"),
+ chain_next ("(union lang_tree_node *) c_tree_chain_next (&%h.generic)"))) lang_tree_node {
+ union tree_node GTY ((tag ("TS_CP_GENERIC"),
+ desc ("tree_node_structure (&%h)"))) generic;
+ struct template_parm_index_s GTY ((tag ("TS_CP_TPI"))) tpi;
+ struct ptrmem_cst GTY ((tag ("TS_CP_PTRMEM"))) ptrmem;
+ struct tree_overload GTY ((tag ("TS_CP_OVERLOAD"))) overload;
+ struct tree_baselink GTY ((tag ("TS_CP_BASELINK"))) baselink;
+ struct tree_default_arg GTY ((tag ("TS_CP_DEFAULT_ARG"))) default_arg;
+ struct tree_deferred_noexcept GTY ((tag ("TS_CP_DEFERRED_NOEXCEPT"))) deferred_noexcept;
+ struct lang_identifier GTY ((tag ("TS_CP_IDENTIFIER"))) identifier;
+ struct tree_static_assert GTY ((tag ("TS_CP_STATIC_ASSERT")))
+ static_assertion;
+ struct tree_argument_pack_select GTY ((tag ("TS_CP_ARGUMENT_PACK_SELECT")))
+ argument_pack_select;
+ struct tree_trait_expr GTY ((tag ("TS_CP_TRAIT_EXPR")))
+ trait_expression;
+ struct tree_lambda_expr GTY ((tag ("TS_CP_LAMBDA_EXPR")))
+ lambda_expression;
+ struct tree_template_info GTY ((tag ("TS_CP_TEMPLATE_INFO")))
+ template_info;
+ struct tree_userdef_literal GTY ((tag ("TS_CP_USERDEF_LITERAL")))
+ userdef_literal;
+};
+
+
+enum cp_tree_index
+{
+ CPTI_JAVA_BYTE_TYPE,
+ CPTI_JAVA_SHORT_TYPE,
+ CPTI_JAVA_INT_TYPE,
+ CPTI_JAVA_LONG_TYPE,
+ CPTI_JAVA_FLOAT_TYPE,
+ CPTI_JAVA_DOUBLE_TYPE,
+ CPTI_JAVA_CHAR_TYPE,
+ CPTI_JAVA_BOOLEAN_TYPE,
+
+ CPTI_WCHAR_DECL,
+ CPTI_VTABLE_ENTRY_TYPE,
+ CPTI_DELTA_TYPE,
+ CPTI_VTABLE_INDEX_TYPE,
+ CPTI_CLEANUP_TYPE,
+ CPTI_VTT_PARM_TYPE,
+
+ CPTI_CLASS_TYPE,
+ CPTI_UNKNOWN_TYPE,
+ CPTI_INIT_LIST_TYPE,
+ CPTI_VTBL_TYPE,
+ CPTI_VTBL_PTR_TYPE,
+ CPTI_STD,
+ CPTI_ABI,
+ CPTI_CONST_TYPE_INFO_TYPE,
+ CPTI_TYPE_INFO_PTR_TYPE,
+ CPTI_ABORT_FNDECL,
+ CPTI_GLOBAL_DELETE_FNDECL,
+ CPTI_AGGR_TAG,
+
+ CPTI_CTOR_IDENTIFIER,
+ CPTI_COMPLETE_CTOR_IDENTIFIER,
+ CPTI_BASE_CTOR_IDENTIFIER,
+ CPTI_DTOR_IDENTIFIER,
+ CPTI_COMPLETE_DTOR_IDENTIFIER,
+ CPTI_BASE_DTOR_IDENTIFIER,
+ CPTI_DELETING_DTOR_IDENTIFIER,
+ CPTI_DELTA_IDENTIFIER,
+ CPTI_IN_CHARGE_IDENTIFIER,
+ CPTI_VTT_PARM_IDENTIFIER,
+ CPTI_NELTS_IDENTIFIER,
+ CPTI_THIS_IDENTIFIER,
+ CPTI_PFN_IDENTIFIER,
+ CPTI_VPTR_IDENTIFIER,
+ CPTI_STD_IDENTIFIER,
+
+ CPTI_LANG_NAME_C,
+ CPTI_LANG_NAME_CPLUSPLUS,
+ CPTI_LANG_NAME_JAVA,
+
+ CPTI_EMPTY_EXCEPT_SPEC,
+ CPTI_NOEXCEPT_TRUE_SPEC,
+ CPTI_NOEXCEPT_FALSE_SPEC,
+ CPTI_JCLASS,
+ CPTI_TERMINATE,
+ CPTI_CALL_UNEXPECTED,
+ CPTI_ATEXIT_FN_PTR_TYPE,
+ CPTI_ATEXIT,
+ CPTI_DSO_HANDLE,
+ CPTI_DCAST,
+
+ CPTI_KEYED_CLASSES,
+
+ CPTI_NULLPTR,
+ CPTI_NULLPTR_TYPE,
+
+ CPTI_MAX
+};
+
+extern GTY(()) tree cp_global_trees[CPTI_MAX];
+
+#define java_byte_type_node cp_global_trees[CPTI_JAVA_BYTE_TYPE]
+#define java_short_type_node cp_global_trees[CPTI_JAVA_SHORT_TYPE]
+#define java_int_type_node cp_global_trees[CPTI_JAVA_INT_TYPE]
+#define java_long_type_node cp_global_trees[CPTI_JAVA_LONG_TYPE]
+#define java_float_type_node cp_global_trees[CPTI_JAVA_FLOAT_TYPE]
+#define java_double_type_node cp_global_trees[CPTI_JAVA_DOUBLE_TYPE]
+#define java_char_type_node cp_global_trees[CPTI_JAVA_CHAR_TYPE]
+#define java_boolean_type_node cp_global_trees[CPTI_JAVA_BOOLEAN_TYPE]
+
+#define wchar_decl_node cp_global_trees[CPTI_WCHAR_DECL]
+#define vtable_entry_type cp_global_trees[CPTI_VTABLE_ENTRY_TYPE]
+/* The type used to represent an offset by which to adjust the `this'
+ pointer in pointer-to-member types. */
+#define delta_type_node cp_global_trees[CPTI_DELTA_TYPE]
+/* The type used to represent an index into the vtable. */
+#define vtable_index_type cp_global_trees[CPTI_VTABLE_INDEX_TYPE]
+
+#define class_type_node cp_global_trees[CPTI_CLASS_TYPE]
+#define unknown_type_node cp_global_trees[CPTI_UNKNOWN_TYPE]
+#define init_list_type_node cp_global_trees[CPTI_INIT_LIST_TYPE]
+#define vtbl_type_node cp_global_trees[CPTI_VTBL_TYPE]
+#define vtbl_ptr_type_node cp_global_trees[CPTI_VTBL_PTR_TYPE]
+#define std_node cp_global_trees[CPTI_STD]
+#define abi_node cp_global_trees[CPTI_ABI]
+#define const_type_info_type_node cp_global_trees[CPTI_CONST_TYPE_INFO_TYPE]
+#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
+#define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL]
+#define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL]
+#define current_aggr cp_global_trees[CPTI_AGGR_TAG]
+#define nullptr_node cp_global_trees[CPTI_NULLPTR]
+#define nullptr_type_node cp_global_trees[CPTI_NULLPTR_TYPE]
+
+/* We cache these tree nodes so as to call get_identifier less
+ frequently. */
+
+/* The name of a constructor that takes an in-charge parameter to
+ decide whether or not to construct virtual base classes. */
+#define ctor_identifier cp_global_trees[CPTI_CTOR_IDENTIFIER]
+/* The name of a constructor that constructs virtual base classes. */
+#define complete_ctor_identifier cp_global_trees[CPTI_COMPLETE_CTOR_IDENTIFIER]
+/* The name of a constructor that does not construct virtual base classes. */
+#define base_ctor_identifier cp_global_trees[CPTI_BASE_CTOR_IDENTIFIER]
+/* The name of a destructor that takes an in-charge parameter to
+ decide whether or not to destroy virtual base classes and whether
+ or not to delete the object. */
+#define dtor_identifier cp_global_trees[CPTI_DTOR_IDENTIFIER]
+/* The name of a destructor that destroys virtual base classes. */
+#define complete_dtor_identifier cp_global_trees[CPTI_COMPLETE_DTOR_IDENTIFIER]
+/* The name of a destructor that does not destroy virtual base
+ classes. */
+#define base_dtor_identifier cp_global_trees[CPTI_BASE_DTOR_IDENTIFIER]
+/* The name of a destructor that destroys virtual base classes, and
+ then deletes the entire object. */
+#define deleting_dtor_identifier cp_global_trees[CPTI_DELETING_DTOR_IDENTIFIER]
+#define delta_identifier cp_global_trees[CPTI_DELTA_IDENTIFIER]
+#define in_charge_identifier cp_global_trees[CPTI_IN_CHARGE_IDENTIFIER]
+/* The name of the parameter that contains a pointer to the VTT to use
+ for this subobject constructor or destructor. */
+#define vtt_parm_identifier cp_global_trees[CPTI_VTT_PARM_IDENTIFIER]
+#define nelts_identifier cp_global_trees[CPTI_NELTS_IDENTIFIER]
+#define this_identifier cp_global_trees[CPTI_THIS_IDENTIFIER]
+#define pfn_identifier cp_global_trees[CPTI_PFN_IDENTIFIER]
+#define vptr_identifier cp_global_trees[CPTI_VPTR_IDENTIFIER]
+/* The name of the std namespace. */
+#define std_identifier cp_global_trees[CPTI_STD_IDENTIFIER]
+#define lang_name_c cp_global_trees[CPTI_LANG_NAME_C]
+#define lang_name_cplusplus cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS]
+#define lang_name_java cp_global_trees[CPTI_LANG_NAME_JAVA]
+
+/* Exception specifier used for throw(). */
+#define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC]
+#define noexcept_true_spec cp_global_trees[CPTI_NOEXCEPT_TRUE_SPEC]
+#define noexcept_false_spec cp_global_trees[CPTI_NOEXCEPT_FALSE_SPEC]
+
+/* If non-NULL, a POINTER_TYPE equivalent to (java::lang::Class*). */
+#define jclass_node cp_global_trees[CPTI_JCLASS]
+
+/* The declaration for `std::terminate'. */
+#define terminate_node cp_global_trees[CPTI_TERMINATE]
+
+/* The declaration for "__cxa_call_unexpected". */
+#define call_unexpected_node cp_global_trees[CPTI_CALL_UNEXPECTED]
+
+/* The type of the function-pointer argument to "__cxa_atexit" (or
+ "std::atexit", if "__cxa_atexit" is not being used). */
+#define atexit_fn_ptr_type_node cp_global_trees[CPTI_ATEXIT_FN_PTR_TYPE]
+
+/* A pointer to `std::atexit'. */
+#define atexit_node cp_global_trees[CPTI_ATEXIT]
+
+/* A pointer to `__dso_handle'. */
+#define dso_handle_node cp_global_trees[CPTI_DSO_HANDLE]
+
+/* The declaration of the dynamic_cast runtime. */
+#define dynamic_cast_node cp_global_trees[CPTI_DCAST]
+
+/* The type of a destructor. */
+#define cleanup_type cp_global_trees[CPTI_CLEANUP_TYPE]
+
+/* The type of the vtt parameter passed to subobject constructors and
+ destructors. */
+#define vtt_parm_type cp_global_trees[CPTI_VTT_PARM_TYPE]
+
+/* A TREE_LIST of the dynamic classes whose vtables may have to be
+ emitted in this translation unit. */
+
+#define keyed_classes cp_global_trees[CPTI_KEYED_CLASSES]
+
+/* Node to indicate default access. This must be distinct from the
+ access nodes in tree.h. */
+
+#define access_default_node null_node
+
+/* Global state. */
+
+struct GTY(()) saved_scope {
+ vec<cxx_saved_binding, va_gc> *old_bindings;
+ tree old_namespace;
+ vec<tree, va_gc> *decl_ns_list;
+ tree class_name;
+ tree class_type;
+ tree access_specifier;
+ tree function_decl;
+ vec<tree, va_gc> *lang_base;
+ tree lang_name;
+ tree template_parms;
+ cp_binding_level *x_previous_class_level;
+ tree x_saved_tree;
+
+ /* Only used for uses of this in trailing return type. */
+ tree x_current_class_ptr;
+ tree x_current_class_ref;
+
+ int x_processing_template_decl;
+ int x_processing_specialization;
+ BOOL_BITFIELD x_processing_explicit_instantiation : 1;
+ BOOL_BITFIELD need_pop_function_context : 1;
+
+ int unevaluated_operand;
+ int inhibit_evaluation_warnings;
+ /* If non-zero, implicit "omp declare target" attribute is added into the
+ attribute lists. */
+ int omp_declare_target_attribute;
+
+ struct stmt_tree_s x_stmt_tree;
+
+ cp_binding_level *class_bindings;
+ cp_binding_level *bindings;
+
+ struct pointer_map_t *x_local_specializations;
+
+ struct saved_scope *prev;
+};
+
+/* The current open namespace. */
+
+#define current_namespace scope_chain->old_namespace
+
+/* The stack for namespaces of current declarations. */
+
+#define decl_namespace_list scope_chain->decl_ns_list
+
+/* IDENTIFIER_NODE: name of current class */
+
+#define current_class_name scope_chain->class_name
+
+/* _TYPE: the type of the current class */
+
+#define current_class_type scope_chain->class_type
+
+/* When parsing a class definition, the access specifier most recently
+ given by the user, or, if no access specifier was given, the
+ default value appropriate for the kind of class (i.e., struct,
+ class, or union). */
+
+#define current_access_specifier scope_chain->access_specifier
+
+/* Pointer to the top of the language name stack. */
+
+#define current_lang_base scope_chain->lang_base
+#define current_lang_name scope_chain->lang_name
+
+/* When parsing a template declaration, a TREE_LIST represents the
+ active template parameters. Each node in the list represents one
+ level of template parameters. The innermost level is first in the
+ list. The depth of each level is stored as an INTEGER_CST in the
+ TREE_PURPOSE of each node. The parameters for that level are
+ stored in the TREE_VALUE. */
+
+#define current_template_parms scope_chain->template_parms
+
+#define processing_template_decl scope_chain->x_processing_template_decl
+#define processing_specialization scope_chain->x_processing_specialization
+#define processing_explicit_instantiation scope_chain->x_processing_explicit_instantiation
+
+/* The cached class binding level, from the most recently exited
+ class, or NULL if none. */
+
+#define previous_class_level scope_chain->x_previous_class_level
+
+/* A map from local variable declarations in the body of the template
+ presently being instantiated to the corresponding instantiated
+ local variables. */
+
+#define local_specializations scope_chain->x_local_specializations
+
+/* A list of private types mentioned, for deferred access checking. */
+
+extern GTY(()) struct saved_scope *scope_chain;
+
+struct GTY(()) cxx_int_tree_map {
+ unsigned int uid;
+ tree to;
+};
+
+extern unsigned int cxx_int_tree_map_hash (const void *);
+extern int cxx_int_tree_map_eq (const void *, const void *);
+
+/* Global state pertinent to the current function. */
+
+struct GTY(()) language_function {
+ struct c_language_function base;
+
+ tree x_cdtor_label;
+ tree x_current_class_ptr;
+ tree x_current_class_ref;
+ tree x_eh_spec_block;
+ tree x_in_charge_parm;
+ tree x_vtt_parm;
+ tree x_return_value;
+ tree x_auto_return_pattern;
+
+ BOOL_BITFIELD returns_value : 1;
+ BOOL_BITFIELD returns_null : 1;
+ BOOL_BITFIELD returns_abnormally : 1;
+ BOOL_BITFIELD infinite_loop: 1;
+ BOOL_BITFIELD x_in_function_try_handler : 1;
+ BOOL_BITFIELD x_in_base_initializer : 1;
+
+ /* True if this function can throw an exception. */
+ BOOL_BITFIELD can_throw : 1;
+
+ htab_t GTY((param_is(struct named_label_entry))) x_named_labels;
+ cp_binding_level *bindings;
+ vec<tree, va_gc> *x_local_names;
+ /* Tracking possibly infinite loops. This is a vec<tree> only because
+ vec<bool> doesn't work with gtype. */
+ vec<tree, va_gc> *infinite_loops;
+ htab_t GTY((param_is (struct cxx_int_tree_map))) extern_decl_map;
+};
+
+/* The current C++-specific per-function global variables. */
+
+#define cp_function_chain (cfun->language)
+
+/* In a constructor destructor, the point at which all derived class
+ destroying/construction has been done. I.e., just before a
+ constructor returns, or before any base class destroying will be done
+ in a destructor. */
+
+#define cdtor_label cp_function_chain->x_cdtor_label
+
+/* When we're processing a member function, current_class_ptr is the
+ PARM_DECL for the `this' pointer. The current_class_ref is an
+ expression for `*this'. */
+
+#define current_class_ptr \
+ (*(cfun && cp_function_chain \
+ ? &cp_function_chain->x_current_class_ptr \
+ : &scope_chain->x_current_class_ptr))
+#define current_class_ref \
+ (*(cfun && cp_function_chain \
+ ? &cp_function_chain->x_current_class_ref \
+ : &scope_chain->x_current_class_ref))
+
+/* The EH_SPEC_BLOCK for the exception-specifiers for the current
+ function, if any. */
+
+#define current_eh_spec_block cp_function_chain->x_eh_spec_block
+
+/* The `__in_chrg' parameter for the current function. Only used for
+ constructors and destructors. */
+
+#define current_in_charge_parm cp_function_chain->x_in_charge_parm
+
+/* The `__vtt_parm' parameter for the current function. Only used for
+ constructors and destructors. */
+
+#define current_vtt_parm cp_function_chain->x_vtt_parm
+
+/* Set to 0 at beginning of a function definition, set to 1 if
+ a return statement that specifies a return value is seen. */
+
+#define current_function_returns_value cp_function_chain->returns_value
+
+/* Set to 0 at beginning of a function definition, set to 1 if
+ a return statement with no argument is seen. */
+
+#define current_function_returns_null cp_function_chain->returns_null
+
+/* Set to 0 at beginning of a function definition, set to 1 if
+ a call to a noreturn function is seen. */
+
+#define current_function_returns_abnormally \
+ cp_function_chain->returns_abnormally
+
+/* Set to 0 at beginning of a function definition, set to 1 if we see an
+ obvious infinite loop. This can have false positives and false
+ negatives, so it should only be used as a heuristic. */
+
+#define current_function_infinite_loop cp_function_chain->infinite_loop
+
+/* Nonzero if we are processing a base initializer. Zero elsewhere. */
+#define in_base_initializer cp_function_chain->x_in_base_initializer
+
+#define in_function_try_handler cp_function_chain->x_in_function_try_handler
+
+/* Expression always returned from function, or error_mark_node
+ otherwise, for use by the automatic named return value optimization. */
+
+#define current_function_return_value \
+ (cp_function_chain->x_return_value)
+
+/* A type involving 'auto' to be used for return type deduction. */
+
+#define current_function_auto_return_pattern \
+ (cp_function_chain->x_auto_return_pattern)
+
+/* True if NAME is the IDENTIFIER_NODE for an overloaded "operator
+ new" or "operator delete". */
+#define NEW_DELETE_OPNAME_P(NAME) \
+ ((NAME) == ansi_opname (NEW_EXPR) \
+ || (NAME) == ansi_opname (VEC_NEW_EXPR) \
+ || (NAME) == ansi_opname (DELETE_EXPR) \
+ || (NAME) == ansi_opname (VEC_DELETE_EXPR))
+
+#define ansi_opname(CODE) \
+ (operator_name_info[(int) (CODE)].identifier)
+#define ansi_assopname(CODE) \
+ (assignment_operator_name_info[(int) (CODE)].identifier)
+
+/* TRUE if a tree code represents a statement. */
+extern bool statement_code_p[MAX_TREE_CODES];
+
+#define STATEMENT_CODE_P(CODE) statement_code_p[(int) (CODE)]
+
+enum languages { lang_c, lang_cplusplus, lang_java };
+
+/* Macros to make error reporting functions' lives easier. */
+#define TYPE_IDENTIFIER(NODE) (DECL_NAME (TYPE_NAME (NODE)))
+#define TYPE_LINKAGE_IDENTIFIER(NODE) \
+ (TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (NODE)))
+#define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE)))
+#define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE)))
+
+/* Nonzero if NODE has no name for linkage purposes. */
+#define TYPE_ANONYMOUS_P(NODE) \
+ (OVERLOAD_TYPE_P (NODE) && ANON_AGGRNAME_P (TYPE_LINKAGE_IDENTIFIER (NODE)))
+
+/* The _DECL for this _TYPE. */
+#define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE)))
+
+/* Nonzero if T is a type that could resolve to any kind of concrete type
+ at instantiation time. */
+#define WILDCARD_TYPE_P(T) \
+ (TREE_CODE (T) == TEMPLATE_TYPE_PARM \
+ || TREE_CODE (T) == TYPENAME_TYPE \
+ || TREE_CODE (T) == TYPEOF_TYPE \
+ || TREE_CODE (T) == BOUND_TEMPLATE_TEMPLATE_PARM \
+ || TREE_CODE (T) == DECLTYPE_TYPE)
+
+/* Nonzero if T is a class (or struct or union) type. Also nonzero
+ for template type parameters, typename types, and instantiated
+ template template parameters. Keep these checks in ascending code
+ order. */
+#define MAYBE_CLASS_TYPE_P(T) (WILDCARD_TYPE_P (T) || CLASS_TYPE_P (T))
+
+/* Set CLASS_TYPE_P for T to VAL. T must be a class, struct, or
+ union type. */
+#define SET_CLASS_TYPE_P(T, VAL) \
+ (TYPE_LANG_FLAG_5 (T) = (VAL))
+
+/* Nonzero if T is a class type. Zero for template type parameters,
+ typename types, and so forth. */
+#define CLASS_TYPE_P(T) \
+ (RECORD_OR_UNION_CODE_P (TREE_CODE (T)) && TYPE_LANG_FLAG_5 (T))
+
+/* Nonzero if T is a class type but not an union. */
+#define NON_UNION_CLASS_TYPE_P(T) \
+ (CLASS_TYPE_P (T) && TREE_CODE (T) != UNION_TYPE)
+
+/* Keep these checks in ascending code order. */
+#define RECORD_OR_UNION_CODE_P(T) \
+ ((T) == RECORD_TYPE || (T) == UNION_TYPE)
+#define OVERLOAD_TYPE_P(T) \
+ (CLASS_TYPE_P (T) || TREE_CODE (T) == ENUMERAL_TYPE)
+
+/* True if this a "Java" type, defined in 'extern "Java"'. */
+#define TYPE_FOR_JAVA(NODE) TYPE_LANG_FLAG_3 (NODE)
+
+/* True if this type is dependent. This predicate is only valid if
+ TYPE_DEPENDENT_P_VALID is true. */
+#define TYPE_DEPENDENT_P(NODE) TYPE_LANG_FLAG_0 (NODE)
+
+/* True if dependent_type_p has been called for this type, with the
+ result that TYPE_DEPENDENT_P is valid. */
+#define TYPE_DEPENDENT_P_VALID(NODE) TYPE_LANG_FLAG_6(NODE)
+
+/* Nonzero if this type is const-qualified. */
+#define CP_TYPE_CONST_P(NODE) \
+ ((cp_type_quals (NODE) & TYPE_QUAL_CONST) != 0)
+
+/* Nonzero if this type is volatile-qualified. */
+#define CP_TYPE_VOLATILE_P(NODE) \
+ ((cp_type_quals (NODE) & TYPE_QUAL_VOLATILE) != 0)
+
+/* Nonzero if this type is restrict-qualified. */
+#define CP_TYPE_RESTRICT_P(NODE) \
+ ((cp_type_quals (NODE) & TYPE_QUAL_RESTRICT) != 0)
+
+/* Nonzero if this type is const-qualified, but not
+ volatile-qualified. Other qualifiers are ignored. This macro is
+ used to test whether or not it is OK to bind an rvalue to a
+ reference. */
+#define CP_TYPE_CONST_NON_VOLATILE_P(NODE) \
+ ((cp_type_quals (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) \
+ == TYPE_QUAL_CONST)
+
+#define FUNCTION_ARG_CHAIN(NODE) \
+ TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE)))
+
+/* Given a FUNCTION_DECL, returns the first TREE_LIST out of TYPE_ARG_TYPES
+ which refers to a user-written parameter. */
+#define FUNCTION_FIRST_USER_PARMTYPE(NODE) \
+ skip_artificial_parms_for ((NODE), TYPE_ARG_TYPES (TREE_TYPE (NODE)))
+
+/* Similarly, but for DECL_ARGUMENTS. */
+#define FUNCTION_FIRST_USER_PARM(NODE) \
+ skip_artificial_parms_for ((NODE), DECL_ARGUMENTS (NODE))
+
+/* Nonzero iff TYPE is derived from PARENT. Ignores accessibility and
+ ambiguity issues. */
+#define DERIVED_FROM_P(PARENT, TYPE) \
+ (lookup_base ((TYPE), (PARENT), ba_any, NULL, tf_none) != NULL_TREE)
+
+/* Gives the visibility specification for a class type. */
+#define CLASSTYPE_VISIBILITY(TYPE) \
+ DECL_VISIBILITY (TYPE_MAIN_DECL (TYPE))
+#define CLASSTYPE_VISIBILITY_SPECIFIED(TYPE) \
+ DECL_VISIBILITY_SPECIFIED (TYPE_MAIN_DECL (TYPE))
+
+typedef struct GTY (()) tree_pair_s {
+ tree purpose;
+ tree value;
+} tree_pair_s;
+typedef tree_pair_s *tree_pair_p;
+
+/* This is a few header flags for 'struct lang_type'. Actually,
+ all but the first are used only for lang_type_class; they
+ are put in this structure to save space. */
+struct GTY(()) lang_type_header {
+ BOOL_BITFIELD is_lang_type_class : 1;
+
+ BOOL_BITFIELD has_type_conversion : 1;
+ BOOL_BITFIELD has_copy_ctor : 1;
+ BOOL_BITFIELD has_default_ctor : 1;
+ BOOL_BITFIELD const_needs_init : 1;
+ BOOL_BITFIELD ref_needs_init : 1;
+ BOOL_BITFIELD has_const_copy_assign : 1;
+
+ BOOL_BITFIELD spare : 1;
+};
+
+/* This structure provides additional information above and beyond
+ what is provide in the ordinary tree_type. In the past, we used it
+ for the types of class types, template parameters types, typename
+ types, and so forth. However, there can be many (tens to hundreds
+ of thousands) of template parameter types in a compilation, and
+ there's no need for this additional information in that case.
+ Therefore, we now use this data structure only for class types.
+
+ In the past, it was thought that there would be relatively few
+ class types. However, in the presence of heavy use of templates,
+ many (i.e., thousands) of classes can easily be generated.
+ Therefore, we should endeavor to keep the size of this structure to
+ a minimum. */
+struct GTY(()) lang_type_class {
+ struct lang_type_header h;
+
+ unsigned char align;
+
+ unsigned has_mutable : 1;
+ unsigned com_interface : 1;
+ unsigned non_pod_class : 1;
+ unsigned nearly_empty_p : 1;
+ unsigned user_align : 1;
+ unsigned has_copy_assign : 1;
+ unsigned has_new : 1;
+ unsigned has_array_new : 1;
+
+ unsigned gets_delete : 2;
+ unsigned interface_only : 1;
+ unsigned interface_unknown : 1;
+ unsigned contains_empty_class_p : 1;
+ unsigned anon_aggr : 1;
+ unsigned non_zero_init : 1;
+ unsigned empty_p : 1;
+
+ unsigned vec_new_uses_cookie : 1;
+ unsigned declared_class : 1;
+ unsigned diamond_shaped : 1;
+ unsigned repeated_base : 1;
+ unsigned being_defined : 1;
+ unsigned java_interface : 1;
+ unsigned debug_requested : 1;
+ unsigned fields_readonly : 1;
+
+ unsigned use_template : 2;
+ unsigned ptrmemfunc_flag : 1;
+ unsigned was_anonymous : 1;
+ unsigned lazy_default_ctor : 1;
+ unsigned lazy_copy_ctor : 1;
+ unsigned lazy_copy_assign : 1;
+ unsigned lazy_destructor : 1;
+
+ unsigned has_const_copy_ctor : 1;
+ unsigned has_complex_copy_ctor : 1;
+ unsigned has_complex_copy_assign : 1;
+ unsigned non_aggregate : 1;
+ unsigned has_complex_dflt : 1;
+ unsigned has_list_ctor : 1;
+ unsigned non_std_layout : 1;
+ unsigned is_literal : 1;
+
+ unsigned lazy_move_ctor : 1;
+ unsigned lazy_move_assign : 1;
+ unsigned has_complex_move_ctor : 1;
+ unsigned has_complex_move_assign : 1;
+ unsigned has_constexpr_ctor : 1;
+
+ /* When adding a flag here, consider whether or not it ought to
+ apply to a template instance if it applies to the template. If
+ so, make sure to copy it in instantiate_class_template! */
+
+ /* There are some bits left to fill out a 32-bit word. Keep track
+ of this by updating the size of this bitfield whenever you add or
+ remove a flag. */
+ unsigned dummy : 3;
+
+ tree primary_base;
+ vec<tree_pair_s, va_gc> *vcall_indices;
+ tree vtables;
+ tree typeinfo_var;
+ vec<tree, va_gc> *vbases;
+ binding_table nested_udts;
+ tree as_base;
+ vec<tree, va_gc> *pure_virtuals;
+ tree friend_classes;
+ vec<tree, va_gc> * GTY((reorder ("resort_type_method_vec"))) methods;
+ tree key_method;
+ tree decl_list;
+ tree template_info;
+ tree befriending_classes;
+ /* In a RECORD_TYPE, information specific to Objective-C++, such
+ as a list of adopted protocols or a pointer to a corresponding
+ @interface. See objc/objc-act.h for details. */
+ tree objc_info;
+ /* sorted_fields is sorted based on a pointer, so we need to be able
+ to resort it if pointers get rearranged. */
+ struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields")))
+ sorted_fields;
+ /* FIXME reuse another field? */
+ tree lambda_expr;
+};
+
+struct GTY(()) lang_type_ptrmem {
+ struct lang_type_header h;
+ tree record;
+};
+
+struct GTY((variable_size)) lang_type {
+ union lang_type_u
+ {
+ struct lang_type_header GTY((skip (""))) h;
+ struct lang_type_class GTY((tag ("1"))) c;
+ struct lang_type_ptrmem GTY((tag ("0"))) ptrmem;
+ } GTY((desc ("%h.h.is_lang_type_class"))) u;
+};
+
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+
+#define LANG_TYPE_CLASS_CHECK(NODE) __extension__ \
+({ struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE); \
+ if (! lt->u.h.is_lang_type_class) \
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
+ &lt->u.c; })
+
+#define LANG_TYPE_PTRMEM_CHECK(NODE) __extension__ \
+({ struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE); \
+ if (lt->u.h.is_lang_type_class) \
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
+ &lt->u.ptrmem; })
+
+#else
+
+#define LANG_TYPE_CLASS_CHECK(NODE) (&TYPE_LANG_SPECIFIC (NODE)->u.c)
+#define LANG_TYPE_PTRMEM_CHECK(NODE) (&TYPE_LANG_SPECIFIC (NODE)->u.ptrmem)
+
+#endif /* ENABLE_TREE_CHECKING */
+
+/* Nonzero for _CLASSTYPE means that operator delete is defined. */
+#define TYPE_GETS_DELETE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->gets_delete)
+#define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1)
+
+/* Nonzero if `new NODE[x]' should cause the allocation of extra
+ storage to indicate how many array elements are in use. */
+#define TYPE_VEC_NEW_USES_COOKIE(NODE) \
+ (CLASS_TYPE_P (NODE) \
+ && LANG_TYPE_CLASS_CHECK (NODE)->vec_new_uses_cookie)
+
+/* Nonzero means that this _CLASSTYPE node defines ways of converting
+ itself to other types. */
+#define TYPE_HAS_CONVERSION(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->h.has_type_conversion)
+
+/* Nonzero means that NODE (a class type) has a default constructor --
+ but that it has not yet been declared. */
+#define CLASSTYPE_LAZY_DEFAULT_CTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->lazy_default_ctor)
+
+/* Nonzero means that NODE (a class type) has a copy constructor --
+ but that it has not yet been declared. */
+#define CLASSTYPE_LAZY_COPY_CTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->lazy_copy_ctor)
+
+/* Nonzero means that NODE (a class type) has a move constructor --
+ but that it has not yet been declared. */
+#define CLASSTYPE_LAZY_MOVE_CTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->lazy_move_ctor)
+
+/* Nonzero means that NODE (a class type) has an assignment operator
+ -- but that it has not yet been declared. */
+#define CLASSTYPE_LAZY_COPY_ASSIGN(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->lazy_copy_assign)
+
+/* Nonzero means that NODE (a class type) has an assignment operator
+ -- but that it has not yet been declared. */
+#define CLASSTYPE_LAZY_MOVE_ASSIGN(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->lazy_move_assign)
+
+/* Nonzero means that NODE (a class type) has a destructor -- but that
+ it has not yet been declared. */
+#define CLASSTYPE_LAZY_DESTRUCTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->lazy_destructor)
+
+/* Nonzero means that NODE (a class type) is final */
+#define CLASSTYPE_FINAL(NODE) \
+ TYPE_FINAL_P (NODE)
+
+
+/* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */
+#define TYPE_HAS_COPY_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_copy_assign)
+
+/* True iff the class type NODE has an "operator =" whose parameter
+ has a parameter of type "const X&". */
+#define TYPE_HAS_CONST_COPY_ASSIGN(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->h.has_const_copy_assign)
+
+/* Nonzero means that this _CLASSTYPE node has an X(X&) constructor. */
+#define TYPE_HAS_COPY_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->h.has_copy_ctor)
+#define TYPE_HAS_CONST_COPY_CTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->has_const_copy_ctor)
+
+/* Nonzero if this class has an X(initializer_list<T>) constructor. */
+#define TYPE_HAS_LIST_CTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->has_list_ctor)
+
+/* Nonzero if this class has a constexpr constructor other than a copy/move
+ constructor. Note that a class can have constexpr constructors for
+ static initialization even if it isn't a literal class. */
+#define TYPE_HAS_CONSTEXPR_CTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->has_constexpr_ctor)
+
+/* Nonzero if this class defines an overloaded operator new. (An
+ operator new [] doesn't count.) */
+#define TYPE_HAS_NEW_OPERATOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->has_new)
+
+/* Nonzero if this class defines an overloaded operator new[]. */
+#define TYPE_HAS_ARRAY_NEW_OPERATOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->has_array_new)
+
+/* Nonzero means that this type is being defined. I.e., the left brace
+ starting the definition of this type has been seen. */
+#define TYPE_BEING_DEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->being_defined)
+
+/* Nonzero means that this type is either complete or being defined, so we
+ can do lookup in it. */
+#define COMPLETE_OR_OPEN_TYPE_P(NODE) \
+ (COMPLETE_TYPE_P (NODE) || (CLASS_TYPE_P (NODE) && TYPE_BEING_DEFINED (NODE)))
+
+/* Mark bits for repeated base checks. */
+#define TYPE_MARKED_P(NODE) TREE_LANG_FLAG_6 (TYPE_CHECK (NODE))
+
+/* Nonzero if the class NODE has multiple paths to the same (virtual)
+ base object. */
+#define CLASSTYPE_DIAMOND_SHAPED_P(NODE) \
+ (LANG_TYPE_CLASS_CHECK(NODE)->diamond_shaped)
+
+/* Nonzero if the class NODE has multiple instances of the same base
+ type. */
+#define CLASSTYPE_REPEATED_BASE_P(NODE) \
+ (LANG_TYPE_CLASS_CHECK(NODE)->repeated_base)
+
+/* The member function with which the vtable will be emitted:
+ the first noninline non-pure-virtual member function. NULL_TREE
+ if there is no key function or if this is a class template */
+#define CLASSTYPE_KEY_METHOD(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->key_method)
+
+/* Vector member functions defined in this class. Each element is
+ either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD. All
+ functions with the same name end up in the same slot. The first
+ two elements are for constructors, and destructors, respectively.
+ All template conversion operators to innermost template dependent
+ types are overloaded on the next slot, if they exist. Note, the
+ names for these functions will not all be the same. The
+ non-template conversion operators & templated conversions to
+ non-innermost template types are next, followed by ordinary member
+ functions. There may be empty entries at the end of the vector.
+ The conversion operators are unsorted. The ordinary member
+ functions are sorted, once the class is complete. */
+#define CLASSTYPE_METHOD_VEC(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->methods)
+
+/* For class templates, this is a TREE_LIST of all member data,
+ functions, types, and friends in the order of declaration.
+ The TREE_PURPOSE of each TREE_LIST is NULL_TREE for a friend,
+ and the RECORD_TYPE for the class template otherwise. */
+#define CLASSTYPE_DECL_LIST(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->decl_list)
+
+/* The slot in the CLASSTYPE_METHOD_VEC where constructors go. */
+#define CLASSTYPE_CONSTRUCTOR_SLOT 0
+
+/* The slot in the CLASSTYPE_METHOD_VEC where destructors go. */
+#define CLASSTYPE_DESTRUCTOR_SLOT 1
+
+/* The first slot in the CLASSTYPE_METHOD_VEC where conversion
+ operators can appear. */
+#define CLASSTYPE_FIRST_CONVERSION_SLOT 2
+
+/* A FUNCTION_DECL or OVERLOAD for the constructors for NODE. These
+ are the constructors that take an in-charge parameter. */
+#define CLASSTYPE_CONSTRUCTORS(NODE) \
+ ((*CLASSTYPE_METHOD_VEC (NODE))[CLASSTYPE_CONSTRUCTOR_SLOT])
+
+/* A FUNCTION_DECL for the destructor for NODE. These are the
+ destructors that take an in-charge parameter. If
+ CLASSTYPE_LAZY_DESTRUCTOR is true, then this entry will be NULL
+ until the destructor is created with lazily_declare_fn. */
+#define CLASSTYPE_DESTRUCTORS(NODE) \
+ (CLASSTYPE_METHOD_VEC (NODE) \
+ ? (*CLASSTYPE_METHOD_VEC (NODE))[CLASSTYPE_DESTRUCTOR_SLOT] \
+ : NULL_TREE)
+
+/* A dictionary of the nested user-defined-types (class-types, or enums)
+ found within this class. This table includes nested member class
+ templates. */
+#define CLASSTYPE_NESTED_UTDS(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->nested_udts)
+
+/* Nonzero if NODE has a primary base class, i.e., a base class with
+ which it shares the virtual function table pointer. */
+#define CLASSTYPE_HAS_PRIMARY_BASE_P(NODE) \
+ (CLASSTYPE_PRIMARY_BINFO (NODE) != NULL_TREE)
+
+/* If non-NULL, this is the binfo for the primary base class, i.e.,
+ the base class which contains the virtual function table pointer
+ for this class. */
+#define CLASSTYPE_PRIMARY_BINFO(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->primary_base)
+
+/* A vector of BINFOs for the direct and indirect virtual base classes
+ that this type uses in a post-order depth-first left-to-right
+ order. (In other words, these bases appear in the order that they
+ should be initialized.) */
+#define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases)
+
+/* The type corresponding to NODE when NODE is used as a base class,
+ i.e., NODE without virtual base classes. */
+
+#define CLASSTYPE_AS_BASE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->as_base)
+
+/* True iff NODE is the CLASSTYPE_AS_BASE version of some type. */
+
+#define IS_FAKE_BASE_TYPE(NODE) \
+ (TREE_CODE (NODE) == RECORD_TYPE \
+ && TYPE_CONTEXT (NODE) && CLASS_TYPE_P (TYPE_CONTEXT (NODE)) \
+ && CLASSTYPE_AS_BASE (TYPE_CONTEXT (NODE)) == (NODE))
+
+/* These are the size and alignment of the type without its virtual
+ base classes, for when we use this type as a base itself. */
+#define CLASSTYPE_SIZE(NODE) TYPE_SIZE (CLASSTYPE_AS_BASE (NODE))
+#define CLASSTYPE_SIZE_UNIT(NODE) TYPE_SIZE_UNIT (CLASSTYPE_AS_BASE (NODE))
+#define CLASSTYPE_ALIGN(NODE) TYPE_ALIGN (CLASSTYPE_AS_BASE (NODE))
+#define CLASSTYPE_USER_ALIGN(NODE) TYPE_USER_ALIGN (CLASSTYPE_AS_BASE (NODE))
+
+/* The alignment of NODE, without its virtual bases, in bytes. */
+#define CLASSTYPE_ALIGN_UNIT(NODE) \
+ (CLASSTYPE_ALIGN (NODE) / BITS_PER_UNIT)
+
+/* True if this a Java interface type, declared with
+ '__attribute__ ((java_interface))'. */
+#define TYPE_JAVA_INTERFACE(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->java_interface)
+
+/* A vec<tree> of virtual functions which cannot be inherited by
+ derived classes. When deriving from this type, the derived
+ class must provide its own definition for each of these functions. */
+#define CLASSTYPE_PURE_VIRTUALS(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->pure_virtuals)
+
+/* Nonzero means that this type is an abstract class type. */
+#define ABSTRACT_CLASS_TYPE_P(NODE) \
+ (CLASS_TYPE_P (NODE) && CLASSTYPE_PURE_VIRTUALS(NODE))
+
+/* Nonzero means that this type has an X() constructor. */
+#define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->h.has_default_ctor)
+
+/* Nonzero means that this type contains a mutable member. */
+#define CLASSTYPE_HAS_MUTABLE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_mutable)
+#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
+
+/* Nonzero means that this class type is not POD for the purpose of layout
+ (as defined in the ABI). This is different from the language's POD. */
+#define CLASSTYPE_NON_LAYOUT_POD_P(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->non_pod_class)
+
+/* Nonzero means that this class type is a non-standard-layout class. */
+#define CLASSTYPE_NON_STD_LAYOUT(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->non_std_layout)
+
+/* Nonzero means that this class contains pod types whose default
+ initialization is not a zero initialization (namely, pointers to
+ data members). */
+#define CLASSTYPE_NON_ZERO_INIT_P(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->non_zero_init)
+
+/* Nonzero if this class is "empty" in the sense of the C++ ABI. */
+#define CLASSTYPE_EMPTY_P(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->empty_p)
+
+/* Nonzero if this class is "nearly empty", i.e., contains only a
+ virtual function table pointer. */
+#define CLASSTYPE_NEARLY_EMPTY_P(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->nearly_empty_p)
+
+/* Nonzero if this class contains an empty subobject. */
+#define CLASSTYPE_CONTAINS_EMPTY_CLASS_P(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->contains_empty_class_p)
+
+/* A list of class types of which this type is a friend. The
+ TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the
+ case of a template friend. */
+#define CLASSTYPE_FRIEND_CLASSES(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->friend_classes)
+
+/* A list of the classes which grant friendship to this class. */
+#define CLASSTYPE_BEFRIENDING_CLASSES(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->befriending_classes)
+
+/* The associated LAMBDA_EXPR that made this class. */
+#define CLASSTYPE_LAMBDA_EXPR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->lambda_expr)
+/* The extra mangling scope for this closure type. */
+#define LAMBDA_TYPE_EXTRA_SCOPE(NODE) \
+ (LAMBDA_EXPR_EXTRA_SCOPE (CLASSTYPE_LAMBDA_EXPR (NODE)))
+
+/* Say whether this node was declared as a "class" or a "struct". */
+#define CLASSTYPE_DECLARED_CLASS(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->declared_class)
+
+/* Nonzero if this class has const members
+ which have no specified initialization. */
+#define CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE) \
+ (TYPE_LANG_SPECIFIC (NODE) \
+ ? LANG_TYPE_CLASS_CHECK (NODE)->h.const_needs_init : 0)
+#define SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE, VALUE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->h.const_needs_init = (VALUE))
+
+/* Nonzero if this class has ref members
+ which have no specified initialization. */
+#define CLASSTYPE_REF_FIELDS_NEED_INIT(NODE) \
+ (TYPE_LANG_SPECIFIC (NODE) \
+ ? LANG_TYPE_CLASS_CHECK (NODE)->h.ref_needs_init : 0)
+#define SET_CLASSTYPE_REF_FIELDS_NEED_INIT(NODE, VALUE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->h.ref_needs_init = (VALUE))
+
+/* Nonzero if this class is included from a header file which employs
+ `#pragma interface', and it is not included in its implementation file. */
+#define CLASSTYPE_INTERFACE_ONLY(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->interface_only)
+
+/* True if we have already determined whether or not vtables, VTTs,
+ typeinfo, and other similar per-class data should be emitted in
+ this translation unit. This flag does not indicate whether or not
+ these items should be emitted; it only indicates that we know one
+ way or the other. */
+#define CLASSTYPE_INTERFACE_KNOWN(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown == 0)
+/* The opposite of CLASSTYPE_INTERFACE_KNOWN. */
+#define CLASSTYPE_INTERFACE_UNKNOWN(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown)
+
+#define SET_CLASSTYPE_INTERFACE_UNKNOWN_X(NODE,X) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = !!(X))
+#define SET_CLASSTYPE_INTERFACE_UNKNOWN(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = 1)
+#define SET_CLASSTYPE_INTERFACE_KNOWN(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = 0)
+
+/* Nonzero if a _DECL node requires us to output debug info for this class. */
+#define CLASSTYPE_DEBUG_REQUESTED(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->debug_requested)
+
+/* Additional macros for inheritance information. */
+
+/* Nonzero means that this class is on a path leading to a new vtable. */
+#define BINFO_VTABLE_PATH_MARKED(NODE) BINFO_FLAG_1 (NODE)
+
+/* Nonzero means B (a BINFO) has its own vtable. Any copies will not
+ have this flag set. */
+#define BINFO_NEW_VTABLE_MARKED(B) (BINFO_FLAG_2 (B))
+
+/* Compare a BINFO_TYPE with another type for equality. For a binfo,
+ this is functionally equivalent to using same_type_p, but
+ measurably faster. At least one of the arguments must be a
+ BINFO_TYPE. The other can be a BINFO_TYPE or a regular type. If
+ BINFO_TYPE(T) ever stops being the main variant of the class the
+ binfo is for, this macro must change. */
+#define SAME_BINFO_TYPE_P(A, B) ((A) == (B))
+
+/* Any subobject that needs a new vtable must have a vptr and must not
+ be a non-virtual primary base (since it would then use the vtable from a
+ derived class and never become non-primary.) */
+#define SET_BINFO_NEW_VTABLE_MARKED(B) \
+ (BINFO_NEW_VTABLE_MARKED (B) = 1, \
+ gcc_assert (!BINFO_PRIMARY_P (B) || BINFO_VIRTUAL_P (B)), \
+ gcc_assert (TYPE_VFIELD (BINFO_TYPE (B))))
+
+/* Nonzero if this binfo is for a dependent base - one that should not
+ be searched. */
+#define BINFO_DEPENDENT_BASE_P(NODE) BINFO_FLAG_3 (NODE)
+
+/* Nonzero if this binfo has lost its primary base binfo (because that
+ is a nearly-empty virtual base that has been taken by some other
+ base in the complete hierarchy. */
+#define BINFO_LOST_PRIMARY_P(NODE) BINFO_FLAG_4 (NODE)
+
+/* Nonzero if this BINFO is a primary base class. */
+#define BINFO_PRIMARY_P(NODE) BINFO_FLAG_5(NODE)
+
+/* Used by various search routines. */
+#define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE)
+
+/* A vec<tree_pair_s> of the vcall indices associated with the class
+ NODE. The PURPOSE of each element is a FUNCTION_DECL for a virtual
+ function. The VALUE is the index into the virtual table where the
+ vcall offset for that function is stored, when NODE is a virtual
+ base. */
+#define CLASSTYPE_VCALL_INDICES(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->vcall_indices)
+
+/* The various vtables for the class NODE. The primary vtable will be
+ first, followed by the construction vtables and VTT, if any. */
+#define CLASSTYPE_VTABLES(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->vtables)
+
+/* The std::type_info variable representing this class, or NULL if no
+ such variable has been created. This field is only set for the
+ TYPE_MAIN_VARIANT of the class. */
+#define CLASSTYPE_TYPEINFO_VAR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->typeinfo_var)
+
+/* Accessor macros for the BINFO_VIRTUALS list. */
+
+/* The number of bytes by which to adjust the `this' pointer when
+ calling this virtual function. Subtract this value from the this
+ pointer. Always non-NULL, might be constant zero though. */
+#define BV_DELTA(NODE) (TREE_PURPOSE (NODE))
+
+/* If non-NULL, the vtable index at which to find the vcall offset
+ when calling this virtual function. Add the value at that vtable
+ index to the this pointer. */
+#define BV_VCALL_INDEX(NODE) (TREE_TYPE (NODE))
+
+/* The function to call. */
+#define BV_FN(NODE) (TREE_VALUE (NODE))
+
+/* Whether or not this entry is for a lost primary virtual base. */
+#define BV_LOST_PRIMARY(NODE) (TREE_LANG_FLAG_0 (NODE))
+
+/* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that
+ this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE
+ will be NULL_TREE to indicate a throw specification of `()', or
+ no exceptions allowed. For a noexcept specification, TREE_VALUE
+ is NULL_TREE and TREE_PURPOSE is the constant-expression. For
+ a deferred noexcept-specification, TREE_PURPOSE is a DEFERRED_NOEXCEPT
+ (for templates) or an OVERLOAD list of functions (for implicitly
+ declared functions). */
+#define TYPE_RAISES_EXCEPTIONS(NODE) \
+ TYPE_LANG_SLOT_1 (FUNC_OR_METHOD_CHECK (NODE))
+
+/* For FUNCTION_TYPE or METHOD_TYPE, return 1 iff it is declared `throw()'
+ or noexcept(true). */
+#define TYPE_NOTHROW_P(NODE) nothrow_spec_p (TYPE_RAISES_EXCEPTIONS (NODE))
+
+/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE is noexcept. This is the
+ case for things declared noexcept(true) and, with -fnothrow-opt, for
+ throw() functions. */
+#define TYPE_NOEXCEPT_P(NODE) type_noexcept_p (NODE)
+
+/* The binding level associated with the namespace. */
+#define NAMESPACE_LEVEL(NODE) \
+ (LANG_DECL_NS_CHECK (NODE)->level)
+
+/* Flags shared by all forms of DECL_LANG_SPECIFIC.
+
+ Some of the flags live here only to make lang_decl_min/fn smaller. Do
+ not make this struct larger than 32 bits; instead, make sel smaller. */
+
+struct GTY(()) lang_decl_base {
+ unsigned selector : 16; /* Larger than necessary for faster access. */
+ ENUM_BITFIELD(languages) language : 4;
+ unsigned use_template : 2;
+ unsigned not_really_extern : 1; /* var or fn */
+ unsigned initialized_in_class : 1; /* var or fn */
+ unsigned repo_available_p : 1; /* var or fn */
+ unsigned threadprivate_or_deleted_p : 1; /* var or fn */
+ unsigned anticipated_p : 1; /* fn, type or template */
+ unsigned friend_attr : 1; /* fn, type or template */
+ unsigned template_conv_p : 1; /* var or template */
+ unsigned odr_used : 1; /* var or fn */
+ unsigned u2sel : 1;
+ /* 1 spare bit */
+};
+
+/* True for DECL codes which have template info and access. */
+#define LANG_DECL_HAS_MIN(NODE) \
+ (VAR_OR_FUNCTION_DECL_P (NODE) \
+ || TREE_CODE (NODE) == FIELD_DECL \
+ || TREE_CODE (NODE) == CONST_DECL \
+ || TREE_CODE (NODE) == TYPE_DECL \
+ || TREE_CODE (NODE) == TEMPLATE_DECL \
+ || TREE_CODE (NODE) == USING_DECL)
+
+/* DECL_LANG_SPECIFIC for the above codes. */
+
+struct GTY(()) lang_decl_min {
+ struct lang_decl_base base;
+
+ /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
+ THUNK_ALIAS.
+ In a FUNCTION_DECL for which DECL_THUNK_P does not hold,
+ VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this is
+ DECL_TEMPLATE_INFO. */
+ tree template_info;
+
+ union lang_decl_u2 {
+ /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
+ THUNK_VIRTUAL_OFFSET.
+ Otherwise this is DECL_ACCESS. */
+ tree GTY ((tag ("0"))) access;
+
+ /* For VAR_DECL in function, this is DECL_DISCRIMINATOR. */
+ int GTY ((tag ("1"))) discriminator;
+ } GTY ((desc ("%0.u.base.u2sel"))) u2;
+};
+
+/* Additional DECL_LANG_SPECIFIC information for functions. */
+
+struct GTY(()) lang_decl_fn {
+ struct lang_decl_min min;
+
+ /* In an overloaded operator, this is the value of
+ DECL_OVERLOADED_OPERATOR_P. */
+ ENUM_BITFIELD (tree_code) operator_code : 16;
+
+ unsigned global_ctor_p : 1;
+ unsigned global_dtor_p : 1;
+ unsigned constructor_attr : 1;
+ unsigned destructor_attr : 1;
+ unsigned assignment_operator_p : 1;
+ unsigned static_function : 1;
+ unsigned pure_virtual : 1;
+ unsigned defaulted_p : 1;
+
+ unsigned has_in_charge_parm_p : 1;
+ unsigned has_vtt_parm_p : 1;
+ unsigned pending_inline_p : 1;
+ unsigned nonconverting : 1;
+ unsigned thunk_p : 1;
+ unsigned this_thunk_p : 1;
+ unsigned hidden_friend_p : 1;
+ unsigned omp_declare_reduction_p : 1;
+ /* No spare bits on 32-bit hosts, 32 on 64-bit hosts. */
+
+ /* For a non-thunk function decl, this is a tree list of
+ friendly classes. For a thunk function decl, it is the
+ thunked to function decl. */
+ tree befriending_classes;
+
+ /* For a non-virtual FUNCTION_DECL, this is
+ DECL_FRIEND_CONTEXT. For a virtual FUNCTION_DECL for which
+ DECL_THIS_THUNK_P does not hold, this is DECL_THUNKS. Both
+ this pointer and result pointer adjusting thunks are
+ chained here. This pointer thunks to return pointer thunks
+ will be chained on the return pointer thunk. */
+ tree context;
+
+ union lang_decl_u5
+ {
+ /* In a non-thunk FUNCTION_DECL or TEMPLATE_DECL, this is
+ DECL_CLONED_FUNCTION. */
+ tree GTY ((tag ("0"))) cloned_function;
+
+ /* In a FUNCTION_DECL for which THUNK_P holds this is the
+ THUNK_FIXED_OFFSET. */
+ HOST_WIDE_INT GTY ((tag ("1"))) fixed_offset;
+ } GTY ((desc ("%1.thunk_p"))) u5;
+
+ union lang_decl_u3
+ {
+ struct cp_token_cache * GTY ((tag ("1"))) pending_inline_info;
+ struct language_function * GTY ((tag ("0")))
+ saved_language_function;
+ } GTY ((desc ("%1.pending_inline_p"))) u;
+
+};
+
+/* DECL_LANG_SPECIFIC for namespaces. */
+
+struct GTY(()) lang_decl_ns {
+ struct lang_decl_base base;
+ cp_binding_level *level;
+};
+
+/* DECL_LANG_SPECIFIC for parameters. */
+
+struct GTY(()) lang_decl_parm {
+ struct lang_decl_base base;
+ int level;
+ int index;
+};
+
+/* DECL_LANG_SPECIFIC for all types. It would be nice to just make this a
+ union rather than a struct containing a union as its only field, but
+ tree.h declares it as a struct. */
+
+struct GTY((variable_size)) lang_decl {
+ union GTY((desc ("%h.base.selector"))) lang_decl_u {
+ struct lang_decl_base GTY ((default)) base;
+ struct lang_decl_min GTY((tag ("0"))) min;
+ struct lang_decl_fn GTY ((tag ("1"))) fn;
+ struct lang_decl_ns GTY((tag ("2"))) ns;
+ struct lang_decl_parm GTY((tag ("3"))) parm;
+ } u;
+};
+
+/* Looks through a template (if present) to find what it declares. */
+#define STRIP_TEMPLATE(NODE) \
+ (TREE_CODE (NODE) == TEMPLATE_DECL ? DECL_TEMPLATE_RESULT (NODE) : NODE)
+
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+
+#define LANG_DECL_MIN_CHECK(NODE) __extension__ \
+({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
+ if (!LANG_DECL_HAS_MIN (NODE)) \
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
+ &lt->u.min; })
+
+/* We want to be able to check DECL_CONSTRUCTOR_P and such on a function
+ template, not just on a FUNCTION_DECL. So when looking for things in
+ lang_decl_fn, look down through a TEMPLATE_DECL into its result. */
+#define LANG_DECL_FN_CHECK(NODE) __extension__ \
+({ struct lang_decl *lt = DECL_LANG_SPECIFIC (STRIP_TEMPLATE (NODE)); \
+ if (!DECL_DECLARES_FUNCTION_P (NODE) || lt->u.base.selector != 1) \
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
+ &lt->u.fn; })
+
+#define LANG_DECL_NS_CHECK(NODE) __extension__ \
+({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
+ if (TREE_CODE (NODE) != NAMESPACE_DECL || lt->u.base.selector != 2) \
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
+ &lt->u.ns; })
+
+#define LANG_DECL_PARM_CHECK(NODE) __extension__ \
+({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
+ if (TREE_CODE (NODE) != PARM_DECL) \
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
+ &lt->u.parm; })
+
+#define LANG_DECL_U2_CHECK(NODE, TF) __extension__ \
+({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
+ if (!LANG_DECL_HAS_MIN (NODE) || lt->u.base.u2sel != TF) \
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
+ &lt->u.min.u2; })
+
+#else
+
+#define LANG_DECL_MIN_CHECK(NODE) \
+ (&DECL_LANG_SPECIFIC (NODE)->u.min)
+
+#define LANG_DECL_FN_CHECK(NODE) \
+ (&DECL_LANG_SPECIFIC (STRIP_TEMPLATE (NODE))->u.fn)
+
+#define LANG_DECL_NS_CHECK(NODE) \
+ (&DECL_LANG_SPECIFIC (NODE)->u.ns)
+
+#define LANG_DECL_PARM_CHECK(NODE) \
+ (&DECL_LANG_SPECIFIC (NODE)->u.parm)
+
+#define LANG_DECL_U2_CHECK(NODE, TF) \
+ (&DECL_LANG_SPECIFIC (NODE)->u.min.u2)
+
+#endif /* ENABLE_TREE_CHECKING */
+
+/* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the
+ declaration. Some entities (like a member function in a local
+ class, or a local variable) do not have linkage at all, and this
+ macro should not be used in those cases.
+
+ Implementation note: A FUNCTION_DECL without DECL_LANG_SPECIFIC was
+ created by language-independent code, and has C linkage. Most
+ VAR_DECLs have C++ linkage, and do not have DECL_LANG_SPECIFIC, but
+ we do create DECL_LANG_SPECIFIC for variables with non-C++ linkage. */
+#define DECL_LANGUAGE(NODE) \
+ (DECL_LANG_SPECIFIC (NODE) \
+ ? DECL_LANG_SPECIFIC (NODE)->u.base.language \
+ : (TREE_CODE (NODE) == FUNCTION_DECL \
+ ? lang_c : lang_cplusplus))
+
+/* Set the language linkage for NODE to LANGUAGE. */
+#define SET_DECL_LANGUAGE(NODE, LANGUAGE) \
+ (DECL_LANG_SPECIFIC (NODE)->u.base.language = (LANGUAGE))
+
+/* For FUNCTION_DECLs and TEMPLATE_DECLs: nonzero means that this function
+ is a constructor. */
+#define DECL_CONSTRUCTOR_P(NODE) \
+ DECL_CXX_CONSTRUCTOR_P (STRIP_TEMPLATE (NODE))
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a constructor for a complete
+ object. */
+#define DECL_COMPLETE_CONSTRUCTOR_P(NODE) \
+ (DECL_CONSTRUCTOR_P (NODE) \
+ && DECL_NAME (NODE) == complete_ctor_identifier)
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a constructor for a base
+ object. */
+#define DECL_BASE_CONSTRUCTOR_P(NODE) \
+ (DECL_CONSTRUCTOR_P (NODE) \
+ && DECL_NAME (NODE) == base_ctor_identifier)
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a constructor, but not either the
+ specialized in-charge constructor or the specialized not-in-charge
+ constructor. */
+#define DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P(NODE) \
+ (DECL_DECLARES_FUNCTION_P (NODE) && DECL_CONSTRUCTOR_P (NODE) \
+ && !DECL_CLONED_FUNCTION_P (NODE))
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a copy constructor. */
+#define DECL_COPY_CONSTRUCTOR_P(NODE) \
+ (DECL_CONSTRUCTOR_P (NODE) && copy_fn_p (NODE) > 0)
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a move constructor. */
+#define DECL_MOVE_CONSTRUCTOR_P(NODE) \
+ (DECL_CONSTRUCTOR_P (NODE) && move_fn_p (NODE))
+
+/* Nonzero if NODE (a FUNCTION_DECL or TEMPLATE_DECL)
+ is a destructor. */
+#define DECL_DESTRUCTOR_P(NODE) \
+ DECL_CXX_DESTRUCTOR_P (STRIP_TEMPLATE (NODE))
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a destructor, but not the
+ specialized in-charge constructor, in-charge deleting constructor,
+ or the base destructor. */
+#define DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P(NODE) \
+ (DECL_DECLARES_FUNCTION_P (NODE) && DECL_DESTRUCTOR_P (NODE) \
+ && !DECL_CLONED_FUNCTION_P (NODE))
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a complete
+ object. */
+#define DECL_COMPLETE_DESTRUCTOR_P(NODE) \
+ (DECL_DESTRUCTOR_P (NODE) \
+ && DECL_NAME (NODE) == complete_dtor_identifier)
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a base
+ object. */
+#define DECL_BASE_DESTRUCTOR_P(NODE) \
+ (DECL_DESTRUCTOR_P (NODE) \
+ && DECL_NAME (NODE) == base_dtor_identifier)
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a complete
+ object that deletes the object after it has been destroyed. */
+#define DECL_DELETING_DESTRUCTOR_P(NODE) \
+ (DECL_DESTRUCTOR_P (NODE) \
+ && DECL_NAME (NODE) == deleting_dtor_identifier)
+
+/* Nonzero if NODE (a FUNCTION_DECL) is a cloned constructor or
+ destructor. */
+#define DECL_CLONED_FUNCTION_P(NODE) (!!decl_cloned_function_p (NODE, true))
+
+/* If DECL_CLONED_FUNCTION_P holds, this is the function that was
+ cloned. */
+#define DECL_CLONED_FUNCTION(NODE) (*decl_cloned_function_p (NODE, false))
+
+/* Perform an action for each clone of FN, if FN is a function with
+ clones. This macro should be used like:
+
+ FOR_EACH_CLONE (clone, fn)
+ { ... }
+
+ */
+#define FOR_EACH_CLONE(CLONE, FN) \
+ if (TREE_CODE (FN) == FUNCTION_DECL \
+ && (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (FN) \
+ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (FN))) \
+ for (CLONE = DECL_CHAIN (FN); \
+ CLONE && DECL_CLONED_FUNCTION_P (CLONE); \
+ CLONE = DECL_CHAIN (CLONE))
+
+/* Nonzero if NODE has DECL_DISCRIMINATOR and not DECL_ACCESS. */
+#define DECL_DISCRIMINATOR_P(NODE) \
+ (VAR_P (NODE) && DECL_FUNCTION_SCOPE_P (NODE))
+
+/* Discriminator for name mangling. */
+#define DECL_DISCRIMINATOR(NODE) (LANG_DECL_U2_CHECK (NODE, 1)->discriminator)
+
+/* True iff DECL_DISCRIMINATOR is set for a DECL_DISCRIMINATOR_P decl. */
+#define DECL_DISCRIMINATOR_SET_P(NODE) \
+ (DECL_LANG_SPECIFIC (NODE) && DECL_LANG_SPECIFIC (NODE)->u.base.u2sel == 1)
+
+/* The index of a user-declared parameter in its function, starting at 1.
+ All artificial parameters will have index 0. */
+#define DECL_PARM_INDEX(NODE) \
+ (LANG_DECL_PARM_CHECK (NODE)->index)
+
+/* The level of a user-declared parameter in its function, starting at 1.
+ A parameter of the function will have level 1; a parameter of the first
+ nested function declarator (i.e. t in void f (void (*p)(T t))) will have
+ level 2. */
+#define DECL_PARM_LEVEL(NODE) \
+ (LANG_DECL_PARM_CHECK (NODE)->level)
+
+/* Nonzero if the VTT parm has been added to NODE. */
+#define DECL_HAS_VTT_PARM_P(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p)
+
+/* Nonzero if NODE is a FUNCTION_DECL for which a VTT parameter is
+ required. */
+#define DECL_NEEDS_VTT_PARM_P(NODE) \
+ (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (NODE)) \
+ && (DECL_BASE_CONSTRUCTOR_P (NODE) \
+ || DECL_BASE_DESTRUCTOR_P (NODE)))
+
+/* Nonzero if NODE is a user-defined conversion operator. */
+#define DECL_CONV_FN_P(NODE) \
+ (DECL_NAME (NODE) && IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)))
+
+/* If FN is a conversion operator, the type to which it converts.
+ Otherwise, NULL_TREE. */
+#define DECL_CONV_FN_TYPE(FN) \
+ (DECL_CONV_FN_P (FN) ? TREE_TYPE (DECL_NAME (FN)) : NULL_TREE)
+
+/* Nonzero if NODE, which is a TEMPLATE_DECL, is a template
+ conversion operator to a type dependent on the innermost template
+ args. */
+#define DECL_TEMPLATE_CONV_FN_P(NODE) \
+ (DECL_LANG_SPECIFIC (TEMPLATE_DECL_CHECK (NODE))->u.base.template_conv_p)
+
+/* Nonzero if NODE, a static data member, was declared in its class as an
+ array of unknown bound. */
+#define VAR_HAD_UNKNOWN_BOUND(NODE) \
+ (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE)) \
+ ? DECL_LANG_SPECIFIC (NODE)->u.base.template_conv_p \
+ : false)
+#define SET_VAR_HAD_UNKNOWN_BOUND(NODE) \
+ (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.template_conv_p = true)
+
+/* Set the overloaded operator code for NODE to CODE. */
+#define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \
+ (LANG_DECL_FN_CHECK (NODE)->operator_code = (CODE))
+
+/* If NODE is an overloaded operator, then this returns the TREE_CODE
+ associated with the overloaded operator.
+ DECL_ASSIGNMENT_OPERATOR_P must also be checked to determine
+ whether or not NODE is an assignment operator. If NODE is not an
+ overloaded operator, ERROR_MARK is returned. Since the numerical
+ value of ERROR_MARK is zero, this macro can be used as a predicate
+ to test whether or not NODE is an overloaded operator. */
+#define DECL_OVERLOADED_OPERATOR_P(NODE) \
+ (IDENTIFIER_OPNAME_P (DECL_NAME (NODE)) \
+ ? LANG_DECL_FN_CHECK (NODE)->operator_code : ERROR_MARK)
+
+/* Nonzero if NODE is an assignment operator (including += and such). */
+#define DECL_ASSIGNMENT_OPERATOR_P(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->assignment_operator_p)
+
+/* For FUNCTION_DECLs: nonzero means that this function is a
+ constructor or a destructor with an extra in-charge parameter to
+ control whether or not virtual bases are constructed. */
+#define DECL_HAS_IN_CHARGE_PARM_P(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->has_in_charge_parm_p)
+
+/* Nonzero if DECL is a declaration of __builtin_constant_p. */
+#define DECL_IS_BUILTIN_CONSTANT_P(NODE) \
+ (TREE_CODE (NODE) == FUNCTION_DECL \
+ && DECL_BUILT_IN_CLASS (NODE) == BUILT_IN_NORMAL \
+ && DECL_FUNCTION_CODE (NODE) == BUILT_IN_CONSTANT_P)
+
+/* Nonzero for _DECL means that this decl appears in (or will appear
+ in) as a member in a RECORD_TYPE or UNION_TYPE node. It is also for
+ detecting circularity in case members are multiply defined. In the
+ case of a VAR_DECL, it is also used to determine how program storage
+ should be allocated. */
+#define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3 (NODE))
+
+/* Nonzero for a VAR_DECL means that the variable's initialization (if
+ any) has been processed. (In general, DECL_INITIALIZED_P is
+ !DECL_EXTERNAL, but static data members may be initialized even if
+ not defined.) */
+#define DECL_INITIALIZED_P(NODE) \
+ (TREE_LANG_FLAG_1 (VAR_DECL_CHECK (NODE)))
+
+/* Nonzero for a VAR_DECL iff an explicit initializer was provided
+ or a non-trivial constructor is called. */
+#define DECL_NONTRIVIALLY_INITIALIZED_P(NODE) \
+ (TREE_LANG_FLAG_3 (VAR_DECL_CHECK (NODE)))
+
+/* Nonzero for a VAR_DECL that was initialized with a
+ constant-expression. */
+#define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \
+ (TREE_LANG_FLAG_2 (VAR_DECL_CHECK (NODE)))
+
+/* Nonzero if the DECL was initialized in the class definition itself,
+ rather than outside the class. This is used for both static member
+ VAR_DECLS, and FUNCTION_DECLS that are defined in the class. */
+#define DECL_INITIALIZED_IN_CLASS_P(DECL) \
+ (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL)) \
+ ->u.base.initialized_in_class)
+
+/* Nonzero if the DECL is used in the sense of 3.2 [basic.def.odr].
+ Only available for decls with DECL_LANG_SPECIFIC. */
+#define DECL_ODR_USED(DECL) \
+ (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL)) \
+ ->u.base.odr_used)
+
+/* Nonzero for DECL means that this decl is just a friend declaration,
+ and should not be added to the list of members for this class. */
+#define DECL_FRIEND_P(NODE) \
+ (DECL_LANG_SPECIFIC (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK (NODE)) \
+ ->u.base.friend_attr)
+
+/* A TREE_LIST of the types which have befriended this FUNCTION_DECL. */
+#define DECL_BEFRIENDING_CLASSES(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->befriending_classes)
+
+/* Nonzero for FUNCTION_DECL means that this decl is a static
+ member function. */
+#define DECL_STATIC_FUNCTION_P(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->static_function)
+
+/* Nonzero for FUNCTION_DECL means that this decl is a non-static
+ member function. */
+#define DECL_NONSTATIC_MEMBER_FUNCTION_P(NODE) \
+ (TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE)
+
+/* Nonzero for FUNCTION_DECL means that this decl is a member function
+ (static or non-static). */
+#define DECL_FUNCTION_MEMBER_P(NODE) \
+ (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE))
+
+/* Nonzero for FUNCTION_DECL means that this member function
+ has `this' as const X *const. */
+#define DECL_CONST_MEMFUNC_P(NODE) \
+ (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \
+ && CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE \
+ (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))
+
+/* Nonzero for FUNCTION_DECL means that this member function
+ has `this' as volatile X *const. */
+#define DECL_VOLATILE_MEMFUNC_P(NODE) \
+ (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \
+ && CP_TYPE_VOLATILE_P (TREE_TYPE (TREE_VALUE \
+ (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))
+
+/* Nonzero for a DECL means that this member is a non-static member. */
+#define DECL_NONSTATIC_MEMBER_P(NODE) \
+ (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \
+ || TREE_CODE (NODE) == FIELD_DECL)
+
+/* Nonzero for _DECL means that this member object type
+ is mutable. */
+#define DECL_MUTABLE_P(NODE) (DECL_LANG_FLAG_0 (NODE))
+
+/* Nonzero for _DECL means that this constructor or conversion function is
+ non-converting. */
+#define DECL_NONCONVERTING_P(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->nonconverting)
+
+/* Nonzero for FUNCTION_DECL means that this member function is a pure
+ virtual function. */
+#define DECL_PURE_VIRTUAL_P(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->pure_virtual)
+
+/* True (in a FUNCTION_DECL) if NODE is a virtual function that is an
+ invalid overrider for a function from a base class. Once we have
+ complained about an invalid overrider we avoid complaining about it
+ again. */
+#define DECL_INVALID_OVERRIDER_P(NODE) \
+ (DECL_LANG_FLAG_4 (NODE))
+
+/* True (in a FUNCTION_DECL) if NODE is a function declared with
+ an override virt-specifier */
+#define DECL_OVERRIDE_P(NODE) (TREE_LANG_FLAG_0 (NODE))
+
+/* The thunks associated with NODE, a FUNCTION_DECL. */
+#define DECL_THUNKS(NODE) \
+ (DECL_VIRTUAL_P (NODE) ? LANG_DECL_FN_CHECK (NODE)->context : NULL_TREE)
+
+/* Set DECL_THUNKS. */
+#define SET_DECL_THUNKS(NODE,THUNKS) \
+ (LANG_DECL_FN_CHECK (NODE)->context = (THUNKS))
+
+/* If NODE, a FUNCTION_DECL, is a C++11 inheriting constructor, then this
+ is the base it inherits from. */
+#define DECL_INHERITED_CTOR_BASE(NODE) \
+ (DECL_CONSTRUCTOR_P (NODE) ? LANG_DECL_FN_CHECK (NODE)->context : NULL_TREE)
+
+/* Set the inherited base. */
+#define SET_DECL_INHERITED_CTOR_BASE(NODE,INH) \
+ (LANG_DECL_FN_CHECK (NODE)->context = (INH))
+
+/* Nonzero if NODE is a thunk, rather than an ordinary function. */
+#define DECL_THUNK_P(NODE) \
+ (TREE_CODE (NODE) == FUNCTION_DECL \
+ && DECL_LANG_SPECIFIC (NODE) \
+ && LANG_DECL_FN_CHECK (NODE)->thunk_p)
+
+/* Set DECL_THUNK_P for node. */
+#define SET_DECL_THUNK_P(NODE, THIS_ADJUSTING) \
+ (LANG_DECL_FN_CHECK (NODE)->thunk_p = 1, \
+ LANG_DECL_FN_CHECK (NODE)->this_thunk_p = (THIS_ADJUSTING))
+
+/* Nonzero if NODE is a this pointer adjusting thunk. */
+#define DECL_THIS_THUNK_P(NODE) \
+ (DECL_THUNK_P (NODE) && LANG_DECL_FN_CHECK (NODE)->this_thunk_p)
+
+/* Nonzero if NODE is a result pointer adjusting thunk. */
+#define DECL_RESULT_THUNK_P(NODE) \
+ (DECL_THUNK_P (NODE) && !LANG_DECL_FN_CHECK (NODE)->this_thunk_p)
+
+/* Nonzero if NODE is a FUNCTION_DECL, but not a thunk. */
+#define DECL_NON_THUNK_FUNCTION_P(NODE) \
+ (TREE_CODE (NODE) == FUNCTION_DECL && !DECL_THUNK_P (NODE))
+
+/* Nonzero if NODE is `extern "C"'. */
+#define DECL_EXTERN_C_P(NODE) \
+ (DECL_LANGUAGE (NODE) == lang_c)
+
+/* Nonzero if NODE is an `extern "C"' function. */
+#define DECL_EXTERN_C_FUNCTION_P(NODE) \
+ (DECL_NON_THUNK_FUNCTION_P (NODE) && DECL_EXTERN_C_P (NODE))
+
+/* True iff DECL is an entity with vague linkage whose definition is
+ available in this translation unit. */
+#define DECL_REPO_AVAILABLE_P(NODE) \
+ (DECL_LANG_SPECIFIC (NODE)->u.base.repo_available_p)
+
+/* True if DECL is declared 'constexpr'. */
+#define DECL_DECLARED_CONSTEXPR_P(DECL) \
+ DECL_LANG_FLAG_8 (VAR_OR_FUNCTION_DECL_CHECK (STRIP_TEMPLATE (DECL)))
+
+/* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
+ template function. */
+#define DECL_PRETTY_FUNCTION_P(NODE) \
+ (DECL_NAME (NODE) \
+ && !strcmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__PRETTY_FUNCTION__"))
+
+/* Nonzero if the thread-local variable was declared with __thread
+ as opposed to thread_local. */
+#define DECL_GNU_TLS_P(NODE) \
+ (TREE_LANG_FLAG_0 (VAR_DECL_CHECK (NODE)))
+
+/* The _TYPE context in which this _DECL appears. This field holds the
+ class where a virtual function instance is actually defined. */
+#define DECL_CLASS_CONTEXT(NODE) \
+ (DECL_CLASS_SCOPE_P (NODE) ? DECL_CONTEXT (NODE) : NULL_TREE)
+
+/* For a non-member friend function, the class (if any) in which this
+ friend was defined. For example, given:
+
+ struct S { friend void f (); };
+
+ the DECL_FRIEND_CONTEXT for `f' will be `S'. */
+#define DECL_FRIEND_CONTEXT(NODE) \
+ ((DECL_DECLARES_FUNCTION_P (NODE) \
+ && DECL_FRIEND_P (NODE) && !DECL_FUNCTION_MEMBER_P (NODE)) \
+ ? LANG_DECL_FN_CHECK (NODE)->context \
+ : NULL_TREE)
+
+/* Set the DECL_FRIEND_CONTEXT for NODE to CONTEXT. */
+#define SET_DECL_FRIEND_CONTEXT(NODE, CONTEXT) \
+ (LANG_DECL_FN_CHECK (NODE)->context = (CONTEXT))
+
+#define CP_DECL_CONTEXT(NODE) \
+ (!DECL_FILE_SCOPE_P (NODE) ? DECL_CONTEXT (NODE) : global_namespace)
+#define CP_TYPE_CONTEXT(NODE) \
+ (!TYPE_FILE_SCOPE_P (NODE) ? TYPE_CONTEXT (NODE) : global_namespace)
+#define FROB_CONTEXT(NODE) \
+ ((NODE) == global_namespace ? DECL_CONTEXT (NODE) : (NODE))
+
+/* 1 iff NODE has namespace scope, including the global namespace. */
+#define DECL_NAMESPACE_SCOPE_P(NODE) \
+ (!DECL_TEMPLATE_PARM_P (NODE) \
+ && TREE_CODE (CP_DECL_CONTEXT (NODE)) == NAMESPACE_DECL)
+
+#define TYPE_NAMESPACE_SCOPE_P(NODE) \
+ (TREE_CODE (CP_TYPE_CONTEXT (NODE)) == NAMESPACE_DECL)
+
+#define NAMESPACE_SCOPE_P(NODE) \
+ ((DECL_P (NODE) && DECL_NAMESPACE_SCOPE_P (NODE)) \
+ || (TYPE_P (NODE) && TYPE_NAMESPACE_SCOPE_P (NODE)))
+
+/* 1 iff NODE is a class member. */
+#define DECL_CLASS_SCOPE_P(NODE) \
+ (DECL_CONTEXT (NODE) && TYPE_P (DECL_CONTEXT (NODE)))
+
+#define TYPE_CLASS_SCOPE_P(NODE) \
+ (TYPE_CONTEXT (NODE) && TYPE_P (TYPE_CONTEXT (NODE)))
+
+/* 1 iff NODE is function-local. */
+#define DECL_FUNCTION_SCOPE_P(NODE) \
+ (DECL_CONTEXT (NODE) \
+ && TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL)
+
+#define TYPE_FUNCTION_SCOPE_P(NODE) \
+ (TYPE_CONTEXT (NODE) && TREE_CODE (TYPE_CONTEXT (NODE)) == FUNCTION_DECL)
+
+/* 1 iff VAR_DECL node NODE is a type-info decl. This flag is set for
+ both the primary typeinfo object and the associated NTBS name. */
+#define DECL_TINFO_P(NODE) TREE_LANG_FLAG_4 (VAR_DECL_CHECK (NODE))
+
+/* 1 iff VAR_DECL node NODE is virtual table or VTT. */
+#define DECL_VTABLE_OR_VTT_P(NODE) TREE_LANG_FLAG_5 (VAR_DECL_CHECK (NODE))
+
+/* 1 iff FUNCTION_TYPE or METHOD_TYPE has a ref-qualifier (either & or &&). */
+#define FUNCTION_REF_QUALIFIED(NODE) \
+ TREE_LANG_FLAG_4 (FUNC_OR_METHOD_CHECK (NODE))
+
+/* 1 iff FUNCTION_TYPE or METHOD_TYPE has &&-ref-qualifier. */
+#define FUNCTION_RVALUE_QUALIFIED(NODE) \
+ TREE_LANG_FLAG_5 (FUNC_OR_METHOD_CHECK (NODE))
+
+/* Returns 1 iff VAR_DECL is a construction virtual table.
+ DECL_VTABLE_OR_VTT_P will be true in this case and must be checked
+ before using this macro. */
+#define DECL_CONSTRUCTION_VTABLE_P(NODE) \
+ TREE_LANG_FLAG_6 (VAR_DECL_CHECK (NODE))
+
+/* 1 iff NODE is function-local, but for types. */
+#define LOCAL_CLASS_P(NODE) \
+ (decl_function_context (TYPE_MAIN_DECL (NODE)) != NULL_TREE)
+
+/* For a NAMESPACE_DECL: the list of using namespace directives
+ The PURPOSE is the used namespace, the value is the namespace
+ that is the common ancestor. */
+#define DECL_NAMESPACE_USING(NODE) DECL_VINDEX (NAMESPACE_DECL_CHECK (NODE))
+
+/* In a NAMESPACE_DECL, the DECL_INITIAL is used to record all users
+ of a namespace, to record the transitive closure of using namespace. */
+#define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NAMESPACE_DECL_CHECK (NODE))
+
+/* In a NAMESPACE_DECL, the list of namespaces which have associated
+ themselves with this one. */
+#define DECL_NAMESPACE_ASSOCIATIONS(NODE) \
+ (NAMESPACE_DECL_CHECK (NODE)->decl_non_common.saved_tree)
+
+/* In a NAMESPACE_DECL, points to the original namespace if this is
+ a namespace alias. */
+#define DECL_NAMESPACE_ALIAS(NODE) \
+ DECL_ABSTRACT_ORIGIN (NAMESPACE_DECL_CHECK (NODE))
+#define ORIGINAL_NAMESPACE(NODE) \
+ (DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE))
+
+/* Nonzero if NODE is the std namespace. */
+#define DECL_NAMESPACE_STD_P(NODE) \
+ (TREE_CODE (NODE) == NAMESPACE_DECL \
+ && CP_DECL_CONTEXT (NODE) == global_namespace \
+ && DECL_NAME (NODE) == std_identifier)
+
+/* In a TREE_LIST concatenating using directives, indicate indirect
+ directives */
+#define TREE_INDIRECT_USING(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
+
+/* In a TREE_LIST in an attribute list, indicates that the attribute
+ must be applied at instantiation time. */
+#define ATTR_IS_DEPENDENT(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
+
+/* In a TREE_LIST in the argument of attribute abi_tag, indicates that the tag
+ was inherited from a template parameter, not explicitly indicated. */
+#define ABI_TAG_IMPLICIT(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
+
+extern tree decl_shadowed_for_var_lookup (tree);
+extern void decl_shadowed_for_var_insert (tree, tree);
+
+/* Non zero if this is a using decl for a dependent scope. */
+#define DECL_DEPENDENT_P(NODE) DECL_LANG_FLAG_0 (USING_DECL_CHECK (NODE))
+
+/* The scope named in a using decl. */
+#define USING_DECL_SCOPE(NODE) TREE_TYPE (USING_DECL_CHECK (NODE))
+
+/* The decls named by a using decl. */
+#define USING_DECL_DECLS(NODE) DECL_INITIAL (USING_DECL_CHECK (NODE))
+
+/* Non zero if the using decl refers to a dependent type. */
+#define USING_DECL_TYPENAME_P(NODE) DECL_LANG_FLAG_1 (USING_DECL_CHECK (NODE))
+
+/* In a VAR_DECL, true if we have a shadowed local variable
+ in the shadowed var table for this VAR_DECL. */
+#define DECL_HAS_SHADOWED_FOR_VAR_P(NODE) \
+ (VAR_DECL_CHECK (NODE)->decl_with_vis.shadowed_for_var_p)
+
+/* In a VAR_DECL for a variable declared in a for statement,
+ this is the shadowed (local) variable. */
+#define DECL_SHADOWED_FOR_VAR(NODE) \
+ (DECL_HAS_SHADOWED_FOR_VAR_P(NODE) ? decl_shadowed_for_var_lookup (NODE) : NULL)
+
+#define SET_DECL_SHADOWED_FOR_VAR(NODE, VAL) \
+ (decl_shadowed_for_var_insert (NODE, VAL))
+
+/* In a FUNCTION_DECL, this is nonzero if this function was defined in
+ the class definition. We have saved away the text of the function,
+ but have not yet processed it. */
+#define DECL_PENDING_INLINE_P(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->pending_inline_p)
+
+/* If DECL_PENDING_INLINE_P holds, this is the saved text of the
+ function. */
+#define DECL_PENDING_INLINE_INFO(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->u.pending_inline_info)
+
+/* Nonzero for TYPE_DECL means that it was written 'using name = type'. */
+#define TYPE_DECL_ALIAS_P(NODE) \
+ DECL_LANG_FLAG_6 (TYPE_DECL_CHECK (NODE))
+
+/* Nonzero for a type which is an alias for another type; i.e, a type
+ which declaration was written 'using name-of-type =
+ another-type'. */
+#define TYPE_ALIAS_P(NODE) \
+ (TYPE_P (NODE) \
+ && TYPE_NAME (NODE) \
+ && TREE_CODE (TYPE_NAME (NODE)) == TYPE_DECL \
+ && TYPE_DECL_ALIAS_P (TYPE_NAME (NODE)))
+
+/* For a class type: if this structure has many fields, we'll sort them
+ and put them into a TREE_VEC. */
+#define CLASSTYPE_SORTED_FIELDS(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->sorted_fields)
+
+/* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or
+ TEMPLATE_DECL, the entity is either a template specialization (if
+ DECL_USE_TEMPLATE is nonzero) or the abstract instance of the
+ template itself.
+
+ In either case, DECL_TEMPLATE_INFO is a TREE_LIST, whose
+ TREE_PURPOSE is the TEMPLATE_DECL of which this entity is a
+ specialization or abstract instance. The TREE_VALUE is the
+ template arguments used to specialize the template.
+
+ Consider:
+
+ template <typename T> struct S { friend void f(T) {} };
+
+ In this case, S<int>::f is, from the point of view of the compiler,
+ an instantiation of a template -- but, from the point of view of
+ the language, each instantiation of S results in a wholly unrelated
+ global function f. In this case, DECL_TEMPLATE_INFO for S<int>::f
+ will be non-NULL, but DECL_USE_TEMPLATE will be zero. */
+#define DECL_TEMPLATE_INFO(NODE) \
+ (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK (NODE)) \
+ ->u.min.template_info)
+
+/* For a VAR_DECL, indicates that the variable is actually a
+ non-static data member of anonymous union that has been promoted to
+ variable status. */
+#define DECL_ANON_UNION_VAR_P(NODE) \
+ (DECL_LANG_FLAG_4 (VAR_DECL_CHECK (NODE)))
+
+/* Template information for a RECORD_TYPE or UNION_TYPE. */
+#define CLASSTYPE_TEMPLATE_INFO(NODE) \
+ (LANG_TYPE_CLASS_CHECK (RECORD_OR_UNION_CHECK (NODE))->template_info)
+
+/* Template information for an ENUMERAL_TYPE. Although an enumeration may
+ not be a primary template, it may be declared within the scope of a
+ primary template and the enumeration constants may depend on
+ non-type template parameters. */
+#define ENUM_TEMPLATE_INFO(NODE) \
+ (TYPE_LANG_SLOT_1 (ENUMERAL_TYPE_CHECK (NODE)))
+
+/* Template information for a template template parameter. */
+#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) \
+ (LANG_TYPE_CLASS_CHECK (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \
+ ->template_info)
+
+/* Template information for an ENUMERAL_, RECORD_, UNION_TYPE, or
+ BOUND_TEMPLATE_TEMPLATE_PARM type. Note that if NODE is a
+ specialization of an alias template, this accessor returns the
+ template info for the alias template, not the one (if any) for the
+ template of the underlying type. */
+#define TYPE_TEMPLATE_INFO(NODE) \
+ ((TYPE_ALIAS_P (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE))) \
+ ? (DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \
+ ? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \
+ : NULL_TREE) \
+ : ((TREE_CODE (NODE) == ENUMERAL_TYPE) \
+ ? ENUM_TEMPLATE_INFO (NODE) \
+ : ((TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM) \
+ ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \
+ : (CLASS_TYPE_P (NODE) \
+ ? CLASSTYPE_TEMPLATE_INFO (NODE) \
+ : NULL_TREE))))
+
+
+/* Set the template information for an ENUMERAL_, RECORD_, or
+ UNION_TYPE to VAL. */
+#define SET_TYPE_TEMPLATE_INFO(NODE, VAL) \
+ (TREE_CODE (NODE) == ENUMERAL_TYPE \
+ ? (ENUM_TEMPLATE_INFO (NODE) = (VAL)) \
+ : ((CLASS_TYPE_P (NODE) && !TYPE_ALIAS_P (NODE)) \
+ ? (CLASSTYPE_TEMPLATE_INFO (NODE) = (VAL)) \
+ : (DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) = (VAL))))
+
+#define TI_TEMPLATE(NODE) TREE_TYPE (TEMPLATE_INFO_CHECK (NODE))
+#define TI_ARGS(NODE) TREE_CHAIN (TEMPLATE_INFO_CHECK (NODE))
+#define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
+/* For a given TREE_VEC containing a template argument list,
+ this property contains the number of arguments that are not
+ defaulted. */
+#define NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) TREE_CHAIN (TREE_VEC_CHECK (NODE))
+/* Below are the setter and getter of the NON_DEFAULT_TEMPLATE_ARGS_COUNT
+ property. */
+#define SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE, INT_VALUE) \
+ NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) = build_int_cst (NULL_TREE, INT_VALUE)
+#ifdef ENABLE_CHECKING
+#define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
+ int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE))
+#else
+#define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
+ NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE) \
+ ? int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE)) \
+ : TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (NODE))
+#endif
+/* The list of typedefs - used in the template - that need
+ access checking at template instantiation time.
+
+ FIXME this should be associated with the TEMPLATE_DECL, not the
+ TEMPLATE_INFO. */
+#define TI_TYPEDEFS_NEEDING_ACCESS_CHECKING(NODE) \
+ ((struct tree_template_info*)TEMPLATE_INFO_CHECK \
+ (NODE))->typedefs_needing_access_checking
+
+/* We use TREE_VECs to hold template arguments. If there is only one
+ level of template arguments, then the TREE_VEC contains the
+ arguments directly. If there is more than one level of template
+ arguments, then each entry in the TREE_VEC is itself a TREE_VEC,
+ containing the template arguments for a single level. The first
+ entry in the outer TREE_VEC is the outermost level of template
+ parameters; the last is the innermost.
+
+ It is incorrect to ever form a template argument vector containing
+ only one level of arguments, but which is a TREE_VEC containing as
+ its only entry the TREE_VEC for that level.
+
+ For each TREE_VEC containing the template arguments for a single
+ level, it's possible to get or set the number of non defaulted
+ template arguments by using the accessor macros
+ GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT or
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT. */
+
+/* Nonzero if the template arguments is actually a vector of vectors,
+ rather than just a vector. */
+#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \
+ (NODE && TREE_VEC_LENGTH (NODE) && TREE_VEC_ELT (NODE, 0) \
+ && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC)
+
+/* The depth of a template argument vector. When called directly by
+ the parser, we use a TREE_LIST rather than a TREE_VEC to represent
+ template arguments. In fact, we may even see NULL_TREE if there
+ are no template arguments. In both of those cases, there is only
+ one level of template arguments. */
+#define TMPL_ARGS_DEPTH(NODE) \
+ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (NODE) ? TREE_VEC_LENGTH (NODE) : 1)
+
+/* The LEVELth level of the template ARGS. The outermost level of
+ args is level 1, not level 0. */
+#define TMPL_ARGS_LEVEL(ARGS, LEVEL) \
+ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (ARGS) \
+ ? TREE_VEC_ELT (ARGS, (LEVEL) - 1) : (ARGS))
+
+/* Set the LEVELth level of the template ARGS to VAL. This macro does
+ not work with single-level argument vectors. */
+#define SET_TMPL_ARGS_LEVEL(ARGS, LEVEL, VAL) \
+ (TREE_VEC_ELT (ARGS, (LEVEL) - 1) = (VAL))
+
+/* Accesses the IDXth parameter in the LEVELth level of the ARGS. */
+#define TMPL_ARG(ARGS, LEVEL, IDX) \
+ (TREE_VEC_ELT (TMPL_ARGS_LEVEL (ARGS, LEVEL), IDX))
+
+/* Given a single level of template arguments in NODE, return the
+ number of arguments. */
+#define NUM_TMPL_ARGS(NODE) \
+ (TREE_VEC_LENGTH (NODE))
+
+/* Returns the innermost level of template arguments in ARGS. */
+#define INNERMOST_TEMPLATE_ARGS(NODE) \
+ (get_innermost_template_args ((NODE), 1))
+
+/* The number of levels of template parameters given by NODE. */
+#define TMPL_PARMS_DEPTH(NODE) \
+ ((HOST_WIDE_INT) TREE_INT_CST_LOW (TREE_PURPOSE (NODE)))
+
+/* The TEMPLATE_DECL instantiated or specialized by NODE. This
+ TEMPLATE_DECL will be the immediate parent, not the most general
+ template. For example, in:
+
+ template <class T> struct S { template <class U> void f(U); }
+
+ the FUNCTION_DECL for S<int>::f<double> will have, as its
+ DECL_TI_TEMPLATE, `template <class U> S<int>::f<U>'.
+
+ As a special case, for a member friend template of a template
+ class, this value will not be a TEMPLATE_DECL, but rather an
+ IDENTIFIER_NODE or OVERLOAD indicating the name of the template and
+ any explicit template arguments provided. For example, in:
+
+ template <class T> struct S { friend void f<int>(int, double); }
+
+ the DECL_TI_TEMPLATE will be an IDENTIFIER_NODE for `f' and the
+ DECL_TI_ARGS will be {int}.
+
+ For a FIELD_DECL with a non-static data member initializer, this value
+ is the FIELD_DECL it was instantiated from. */
+#define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE))
+
+/* The template arguments used to obtain this decl from the most
+ general form of DECL_TI_TEMPLATE. For the example given for
+ DECL_TI_TEMPLATE, the DECL_TI_ARGS will be {int, double}. These
+ are always the full set of arguments required to instantiate this
+ declaration from the most general template specialized here. */
+#define DECL_TI_ARGS(NODE) TI_ARGS (DECL_TEMPLATE_INFO (NODE))
+
+/* The TEMPLATE_DECL associated with NODE, a class type. Even if NODE
+ will be generated from a partial specialization, the TEMPLATE_DECL
+ referred to here will be the original template. For example,
+ given:
+
+ template <typename T> struct S {};
+ template <typename T> struct S<T*> {};
+
+ the CLASSTPYE_TI_TEMPLATE for S<int*> will be S, not the S<T*>. */
+#define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE))
+#define CLASSTYPE_TI_ARGS(NODE) TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE))
+
+/* For a template instantiation TYPE, returns the TYPE corresponding
+ to the primary template. Otherwise returns TYPE itself. */
+#define CLASSTYPE_PRIMARY_TEMPLATE_TYPE(TYPE) \
+ ((CLASSTYPE_USE_TEMPLATE ((TYPE)) \
+ && !CLASSTYPE_TEMPLATE_SPECIALIZATION ((TYPE))) \
+ ? TREE_TYPE (DECL_TEMPLATE_RESULT (DECL_PRIMARY_TEMPLATE \
+ (CLASSTYPE_TI_TEMPLATE ((TYPE))))) \
+ : (TYPE))
+
+/* Like CLASS_TI_TEMPLATE, but also works for ENUMERAL_TYPEs. */
+#define TYPE_TI_TEMPLATE(NODE) \
+ (TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE)))
+
+/* Like DECL_TI_ARGS, but for an ENUMERAL_, RECORD_, or UNION_TYPE. */
+#define TYPE_TI_ARGS(NODE) \
+ (TI_ARGS (TYPE_TEMPLATE_INFO (NODE)))
+
+#define INNERMOST_TEMPLATE_PARMS(NODE) TREE_VALUE (NODE)
+
+/* Nonzero if NODE (a TEMPLATE_DECL) is a member template, in the
+ sense of [temp.mem]. */
+#define DECL_MEMBER_TEMPLATE_P(NODE) \
+ (DECL_LANG_FLAG_1 (TEMPLATE_DECL_CHECK (NODE)))
+
+/* Nonzero if the NODE corresponds to the template parameters for a
+ member template, whose inline definition is being processed after
+ the class definition is complete. */
+#define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE)
+
+/* Determine if a declaration (PARM_DECL or FIELD_DECL) is a pack. */
+#define DECL_PACK_P(NODE) \
+ (DECL_P (NODE) && PACK_EXPANSION_P (TREE_TYPE (NODE)))
+
+/* Determines if NODE is an expansion of one or more parameter packs,
+ e.g., a TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION. */
+#define PACK_EXPANSION_P(NODE) \
+ (TREE_CODE (NODE) == TYPE_PACK_EXPANSION \
+ || TREE_CODE (NODE) == EXPR_PACK_EXPANSION)
+
+/* Extracts the type or expression pattern from a TYPE_PACK_EXPANSION or
+ EXPR_PACK_EXPANSION. */
+#define PACK_EXPANSION_PATTERN(NODE) \
+ (TREE_CODE (NODE) == TYPE_PACK_EXPANSION? TREE_TYPE (NODE) \
+ : TREE_OPERAND (NODE, 0))
+
+/* Sets the type or expression pattern for a TYPE_PACK_EXPANSION or
+ EXPR_PACK_EXPANSION. */
+#define SET_PACK_EXPANSION_PATTERN(NODE,VALUE) \
+ if (TREE_CODE (NODE) == TYPE_PACK_EXPANSION) \
+ TREE_TYPE (NODE) = VALUE; \
+ else \
+ TREE_OPERAND (NODE, 0) = VALUE
+
+/* The list of parameter packs used in the PACK_EXPANSION_* node. The
+ TREE_VALUE of each TREE_LIST contains the parameter packs. */
+#define PACK_EXPANSION_PARAMETER_PACKS(NODE) \
+ *(TREE_CODE (NODE) == EXPR_PACK_EXPANSION \
+ ? &TREE_OPERAND (NODE, 1) \
+ : &TYPE_MINVAL (TYPE_PACK_EXPANSION_CHECK (NODE)))
+
+/* Any additional template args to be applied when substituting into
+ the pattern, set by tsubst_pack_expansion for partial instantiations. */
+#define PACK_EXPANSION_EXTRA_ARGS(NODE) \
+ *(TREE_CODE (NODE) == TYPE_PACK_EXPANSION \
+ ? &TYPE_MAXVAL (NODE) \
+ : &TREE_OPERAND ((NODE), 2))
+
+/* True iff this pack expansion is within a function context. */
+#define PACK_EXPANSION_LOCAL_P(NODE) TREE_LANG_FLAG_0 (NODE)
+
+/* Determine if this is an argument pack. */
+#define ARGUMENT_PACK_P(NODE) \
+ (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK \
+ || TREE_CODE (NODE) == NONTYPE_ARGUMENT_PACK)
+
+/* The arguments stored in an argument pack. Arguments are stored in a
+ TREE_VEC, which may have length zero. */
+#define ARGUMENT_PACK_ARGS(NODE) \
+ (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK? TREE_TYPE (NODE) \
+ : TREE_OPERAND (NODE, 0))
+
+/* Set the arguments stored in an argument pack. VALUE must be a
+ TREE_VEC. */
+#define SET_ARGUMENT_PACK_ARGS(NODE,VALUE) \
+ if (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK) \
+ TREE_TYPE (NODE) = VALUE; \
+ else \
+ TREE_OPERAND (NODE, 0) = VALUE
+
+/* Whether the argument pack is "incomplete", meaning that more
+ arguments can still be deduced. Incomplete argument packs are only
+ used when the user has provided an explicit template argument list
+ for a variadic function template. Some of the explicit template
+ arguments will be placed into the beginning of the argument pack,
+ but additional arguments might still be deduced. */
+#define ARGUMENT_PACK_INCOMPLETE_P(NODE) \
+ TREE_ADDRESSABLE (ARGUMENT_PACK_ARGS (NODE))
+
+/* When ARGUMENT_PACK_INCOMPLETE_P, stores the explicit template
+ arguments used to fill this pack. */
+#define ARGUMENT_PACK_EXPLICIT_ARGS(NODE) \
+ TREE_TYPE (ARGUMENT_PACK_ARGS (NODE))
+
+/* In an ARGUMENT_PACK_SELECT, the argument pack from which an
+ argument will be selected. */
+#define ARGUMENT_PACK_SELECT_FROM_PACK(NODE) \
+ (((struct tree_argument_pack_select *)ARGUMENT_PACK_SELECT_CHECK (NODE))->argument_pack)
+
+/* In an ARGUMENT_PACK_SELECT, the index of the argument we want to
+ select. */
+#define ARGUMENT_PACK_SELECT_INDEX(NODE) \
+ (((struct tree_argument_pack_select *)ARGUMENT_PACK_SELECT_CHECK (NODE))->index)
+
+/* In an ARGUMENT_PACK_SELECT, the actual underlying argument that the
+ ARGUMENT_PACK_SELECT represents. */
+#define ARGUMENT_PACK_SELECT_ARG(NODE) \
+ TREE_VEC_ELT (ARGUMENT_PACK_ARGS (ARGUMENT_PACK_SELECT_FROM_PACK (NODE)), \
+ ARGUMENT_PACK_SELECT_INDEX (NODE));
+
+/* In a FUNCTION_DECL, the saved language-specific per-function data. */
+#define DECL_SAVED_FUNCTION_DATA(NODE) \
+ (LANG_DECL_FN_CHECK (FUNCTION_DECL_CHECK (NODE)) \
+ ->u.saved_language_function)
+
+/* True if NODE is an implicit INDIRECT_EXPR from convert_from_reference. */
+#define REFERENCE_REF_P(NODE) \
+ (INDIRECT_REF_P (NODE) \
+ && TREE_TYPE (TREE_OPERAND (NODE, 0)) \
+ && (TREE_CODE (TREE_TYPE (TREE_OPERAND ((NODE), 0))) \
+ == REFERENCE_TYPE))
+
+/* True if NODE is a REFERENCE_TYPE which is OK to instantiate to be a
+ reference to VLA type, because it's used for VLA capture. */
+#define REFERENCE_VLA_OK(NODE) \
+ (TYPE_LANG_FLAG_5 (REFERENCE_TYPE_CHECK (NODE)))
+
+#define NEW_EXPR_USE_GLOBAL(NODE) \
+ TREE_LANG_FLAG_0 (NEW_EXPR_CHECK (NODE))
+#define DELETE_EXPR_USE_GLOBAL(NODE) \
+ TREE_LANG_FLAG_0 (DELETE_EXPR_CHECK (NODE))
+#define DELETE_EXPR_USE_VEC(NODE) \
+ TREE_LANG_FLAG_1 (DELETE_EXPR_CHECK (NODE))
+
+/* Indicates that this is a non-dependent COMPOUND_EXPR which will
+ resolve to a function call. */
+#define COMPOUND_EXPR_OVERLOADED(NODE) \
+ TREE_LANG_FLAG_0 (COMPOUND_EXPR_CHECK (NODE))
+
+/* In a CALL_EXPR appearing in a template, true if Koenig lookup
+ should be performed at instantiation time. */
+#define KOENIG_LOOKUP_P(NODE) TREE_LANG_FLAG_0 (CALL_EXPR_CHECK (NODE))
+
+/* Indicates whether a string literal has been parenthesized. Such
+ usages are disallowed in certain circumstances. */
+
+#define PAREN_STRING_LITERAL_P(NODE) \
+ TREE_LANG_FLAG_0 (STRING_CST_CHECK (NODE))
+
+/* Indicates whether a COMPONENT_REF has been parenthesized. Currently
+ only set some of the time in C++14 mode. */
+
+#define REF_PARENTHESIZED_P(NODE) \
+ TREE_LANG_FLAG_2 (COMPONENT_REF_CHECK (NODE))
+
+/* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
+ constructor call, rather than an ordinary function call. */
+#define AGGR_INIT_VIA_CTOR_P(NODE) \
+ TREE_LANG_FLAG_0 (AGGR_INIT_EXPR_CHECK (NODE))
+
+/* Nonzero if expanding this AGGR_INIT_EXPR should first zero-initialize
+ the object. */
+#define AGGR_INIT_ZERO_FIRST(NODE) \
+ TREE_LANG_FLAG_2 (AGGR_INIT_EXPR_CHECK (NODE))
+
+/* AGGR_INIT_EXPR accessors. These are equivalent to the CALL_EXPR
+ accessors, except for AGGR_INIT_EXPR_SLOT (which takes the place of
+ CALL_EXPR_STATIC_CHAIN). */
+
+#define AGGR_INIT_EXPR_FN(NODE) TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 1)
+#define AGGR_INIT_EXPR_SLOT(NODE) \
+ TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 2)
+#define AGGR_INIT_EXPR_ARG(NODE, I) \
+ TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), (I) + 3)
+#define aggr_init_expr_nargs(NODE) (VL_EXP_OPERAND_LENGTH(NODE) - 3)
+
+/* AGGR_INIT_EXPR_ARGP returns a pointer to the argument vector for NODE.
+ We can't use &AGGR_INIT_EXPR_ARG (NODE, 0) because that will complain if
+ the argument count is zero when checking is enabled. Instead, do
+ the pointer arithmetic to advance past the 3 fixed operands in a
+ AGGR_INIT_EXPR. That produces a valid pointer to just past the end of
+ the operand array, even if it's not valid to dereference it. */
+#define AGGR_INIT_EXPR_ARGP(NODE) \
+ (&(TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 0)) + 3)
+
+/* Abstract iterators for AGGR_INIT_EXPRs. */
+
+/* Structure containing iterator state. */
+typedef struct aggr_init_expr_arg_iterator_d {
+ tree t; /* the aggr_init_expr */
+ int n; /* argument count */
+ int i; /* next argument index */
+} aggr_init_expr_arg_iterator;
+
+/* Initialize the abstract argument list iterator object ITER with the
+ arguments from AGGR_INIT_EXPR node EXP. */
+inline void
+init_aggr_init_expr_arg_iterator (tree exp,
+ aggr_init_expr_arg_iterator *iter)
+{
+ iter->t = exp;
+ iter->n = aggr_init_expr_nargs (exp);
+ iter->i = 0;
+}
+
+/* Return the next argument from abstract argument list iterator object ITER,
+ and advance its state. Return NULL_TREE if there are no more arguments. */
+inline tree
+next_aggr_init_expr_arg (aggr_init_expr_arg_iterator *iter)
+{
+ tree result;
+ if (iter->i >= iter->n)
+ return NULL_TREE;
+ result = AGGR_INIT_EXPR_ARG (iter->t, iter->i);
+ iter->i++;
+ return result;
+}
+
+/* Initialize the abstract argument list iterator object ITER, then advance
+ past and return the first argument. Useful in for expressions, e.g.
+ for (arg = first_aggr_init_expr_arg (exp, &iter); arg;
+ arg = next_aggr_init_expr_arg (&iter)) */
+inline tree
+first_aggr_init_expr_arg (tree exp, aggr_init_expr_arg_iterator *iter)
+{
+ init_aggr_init_expr_arg_iterator (exp, iter);
+ return next_aggr_init_expr_arg (iter);
+}
+
+/* Test whether there are more arguments in abstract argument list iterator
+ ITER, without changing its state. */
+inline bool
+more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
+{
+ return (iter->i < iter->n);
+}
+
+/* Iterate through each argument ARG of AGGR_INIT_EXPR CALL, using variable
+ ITER (of type aggr_init_expr_arg_iterator) to hold the iteration state. */
+#define FOR_EACH_AGGR_INIT_EXPR_ARG(arg, iter, call) \
+ for ((arg) = first_aggr_init_expr_arg ((call), &(iter)); (arg); \
+ (arg) = next_aggr_init_expr_arg (&(iter)))
+
+/* VEC_INIT_EXPR accessors. */
+#define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 0)
+#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 1)
+
+/* Indicates that a VEC_INIT_EXPR is a potential constant expression.
+ Only set when the current function is constexpr. */
+#define VEC_INIT_EXPR_IS_CONSTEXPR(NODE) \
+ TREE_LANG_FLAG_0 (VEC_INIT_EXPR_CHECK (NODE))
+
+/* Indicates that a VEC_INIT_EXPR is expressing value-initialization. */
+#define VEC_INIT_EXPR_VALUE_INIT(NODE) \
+ TREE_LANG_FLAG_1 (VEC_INIT_EXPR_CHECK (NODE))
+
+/* The condition under which this MUST_NOT_THROW_EXPR actually blocks
+ exceptions. NULL_TREE means 'true'. */
+#define MUST_NOT_THROW_COND(NODE) \
+ TREE_OPERAND (MUST_NOT_THROW_EXPR_CHECK (NODE), 1)
+
+/* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a
+ TEMPLATE_DECL. This macro determines whether or not a given class
+ type is really a template type, as opposed to an instantiation or
+ specialization of one. */
+#define CLASSTYPE_IS_TEMPLATE(NODE) \
+ (CLASSTYPE_TEMPLATE_INFO (NODE) \
+ && !CLASSTYPE_USE_TEMPLATE (NODE) \
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))
+
+/* The name used by the user to name the typename type. Typically,
+ this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the
+ corresponding TYPE_DECL. However, this may also be a
+ TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'. */
+#define TYPENAME_TYPE_FULLNAME(NODE) \
+ (TYPE_VALUES_RAW (TYPENAME_TYPE_CHECK (NODE)))
+
+/* True if a TYPENAME_TYPE was declared as an "enum". */
+#define TYPENAME_IS_ENUM_P(NODE) \
+ (TREE_LANG_FLAG_0 (TYPENAME_TYPE_CHECK (NODE)))
+
+/* True if a TYPENAME_TYPE was declared as a "class", "struct", or
+ "union". */
+#define TYPENAME_IS_CLASS_P(NODE) \
+ (TREE_LANG_FLAG_1 (TYPENAME_TYPE_CHECK (NODE)))
+
+/* True if a TYPENAME_TYPE is in the process of being resolved. */
+#define TYPENAME_IS_RESOLVING_P(NODE) \
+ (TREE_LANG_FLAG_2 (TYPENAME_TYPE_CHECK (NODE)))
+
+/* [class.virtual]
+
+ A class that declares or inherits a virtual function is called a
+ polymorphic class. */
+#define TYPE_POLYMORPHIC_P(NODE) (TREE_LANG_FLAG_2 (NODE))
+
+/* Nonzero if this class has a virtual function table pointer. */
+#define TYPE_CONTAINS_VPTR_P(NODE) \
+ (TYPE_POLYMORPHIC_P (NODE) || CLASSTYPE_VBASECLASSES (NODE))
+
+/* This flag is true of a local VAR_DECL if it was declared in a for
+ statement, but we are no longer in the scope of the for. */
+#define DECL_DEAD_FOR_LOCAL(NODE) DECL_LANG_FLAG_7 (VAR_DECL_CHECK (NODE))
+
+/* This flag is set on a VAR_DECL that is a DECL_DEAD_FOR_LOCAL
+ if we already emitted a warning about using it. */
+#define DECL_ERROR_REPORTED(NODE) DECL_LANG_FLAG_0 (VAR_DECL_CHECK (NODE))
+
+/* Nonzero if NODE is a FUNCTION_DECL (for a function with global
+ scope) declared in a local scope. */
+#define DECL_LOCAL_FUNCTION_P(NODE) \
+ DECL_LANG_FLAG_0 (FUNCTION_DECL_CHECK (NODE))
+
+/* True if NODE was declared with auto in its return type, but it has
+ started compilation and so the return type might have been changed by
+ return type deduction; its declared return type should be found in
+ DECL_STRUCT_FUNCTION(NODE)->language->x_auto_return_pattern. */
+#define FNDECL_USED_AUTO(NODE) \
+ TREE_LANG_FLAG_2 (FUNCTION_DECL_CHECK (NODE))
+
+/* Nonzero if NODE is a DECL which we know about but which has not
+ been explicitly declared, such as a built-in function or a friend
+ declared inside a class. In the latter case DECL_HIDDEN_FRIEND_P
+ will be set. */
+#define DECL_ANTICIPATED(NODE) \
+ (DECL_LANG_SPECIFIC (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK (NODE)) \
+ ->u.base.anticipated_p)
+
+/* Nonzero if NODE is a FUNCTION_DECL which was declared as a friend
+ within a class but has not been declared in the surrounding scope.
+ The function is invisible except via argument dependent lookup. */
+#define DECL_HIDDEN_FRIEND_P(NODE) \
+ (LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->hidden_friend_p)
+
+/* Nonzero if NODE is an artificial FUNCTION_DECL for
+ #pragma omp declare reduction. */
+#define DECL_OMP_DECLARE_REDUCTION_P(NODE) \
+ (LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->omp_declare_reduction_p)
+
+/* Nonzero if DECL has been declared threadprivate by
+ #pragma omp threadprivate. */
+#define CP_DECL_THREADPRIVATE_P(DECL) \
+ (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (DECL))->u.base.threadprivate_or_deleted_p)
+
+/* Nonzero if DECL was declared with '= delete'. */
+#define DECL_DELETED_FN(DECL) \
+ (LANG_DECL_FN_CHECK (DECL)->min.base.threadprivate_or_deleted_p)
+
+/* Nonzero if DECL was declared with '= default' (maybe implicitly). */
+#define DECL_DEFAULTED_FN(DECL) \
+ (LANG_DECL_FN_CHECK (DECL)->defaulted_p)
+
+/* Nonzero if DECL is explicitly defaulted in the class body. */
+#define DECL_DEFAULTED_IN_CLASS_P(DECL) \
+ (DECL_DEFAULTED_FN (DECL) && DECL_INITIALIZED_IN_CLASS_P (DECL))
+/* Nonzero if DECL was defaulted outside the class body. */
+#define DECL_DEFAULTED_OUTSIDE_CLASS_P(DECL) \
+ (DECL_DEFAULTED_FN (DECL) \
+ && !(DECL_ARTIFICIAL (DECL) || DECL_INITIALIZED_IN_CLASS_P (DECL)))
+
+/* Record whether a typedef for type `int' was actually `signed int'. */
+#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
+
+/* Returns nonzero if DECL has external linkage, as specified by the
+ language standard. (This predicate may hold even when the
+ corresponding entity is not actually given external linkage in the
+ object file; see decl_linkage for details.) */
+#define DECL_EXTERNAL_LINKAGE_P(DECL) \
+ (decl_linkage (DECL) == lk_external)
+
+/* Keep these codes in ascending code order. */
+
+#define INTEGRAL_CODE_P(CODE) \
+ ((CODE) == ENUMERAL_TYPE \
+ || (CODE) == BOOLEAN_TYPE \
+ || (CODE) == INTEGER_TYPE)
+
+/* [basic.fundamental]
+
+ Types bool, char, wchar_t, and the signed and unsigned integer types
+ are collectively called integral types.
+
+ Note that INTEGRAL_TYPE_P, as defined in tree.h, allows enumeration
+ types as well, which is incorrect in C++. Keep these checks in
+ ascending code order. */
+#define CP_INTEGRAL_TYPE_P(TYPE) \
+ (TREE_CODE (TYPE) == BOOLEAN_TYPE \
+ || TREE_CODE (TYPE) == INTEGER_TYPE)
+
+/* Returns true if TYPE is an integral or enumeration name. Keep
+ these checks in ascending code order. */
+#define INTEGRAL_OR_ENUMERATION_TYPE_P(TYPE) \
+ (TREE_CODE (TYPE) == ENUMERAL_TYPE || CP_INTEGRAL_TYPE_P (TYPE))
+
+/* Returns true if TYPE is an integral or unscoped enumeration type. */
+#define INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P(TYPE) \
+ (UNSCOPED_ENUM_P (TYPE) || CP_INTEGRAL_TYPE_P (TYPE))
+
+/* True if the class type TYPE is a literal type. */
+#define CLASSTYPE_LITERAL_P(TYPE) \
+ (LANG_TYPE_CLASS_CHECK (TYPE)->is_literal)
+
+/* [basic.fundamental]
+
+ Integral and floating types are collectively called arithmetic
+ types.
+
+ As a GNU extension, we also accept complex types.
+
+ Keep these checks in ascending code order. */
+#define ARITHMETIC_TYPE_P(TYPE) \
+ (CP_INTEGRAL_TYPE_P (TYPE) \
+ || TREE_CODE (TYPE) == REAL_TYPE \
+ || TREE_CODE (TYPE) == COMPLEX_TYPE)
+
+/* True iff TYPE is cv decltype(nullptr). */
+#define NULLPTR_TYPE_P(TYPE) (TREE_CODE (TYPE) == NULLPTR_TYPE)
+
+/* [basic.types]
+
+ Arithmetic types, enumeration types, pointer types,
+ pointer-to-member types, and std::nullptr_t are collectively called
+ scalar types.
+
+ Keep these checks in ascending code order. */
+#define SCALAR_TYPE_P(TYPE) \
+ (TYPE_PTRDATAMEM_P (TYPE) \
+ || TREE_CODE (TYPE) == ENUMERAL_TYPE \
+ || ARITHMETIC_TYPE_P (TYPE) \
+ || TYPE_PTR_P (TYPE) \
+ || TYPE_PTRMEMFUNC_P (TYPE) \
+ || NULLPTR_TYPE_P (TYPE))
+
+/* Determines whether this type is a C++0x scoped enumeration
+ type. Scoped enumerations types are introduced via "enum class" or
+ "enum struct", e.g.,
+
+ enum class Color {
+ Red, Green, Blue
+ };
+
+ Scoped enumeration types are different from normal (unscoped)
+ enumeration types in several ways:
+
+ - The enumerators of a scoped enumeration type are only available
+ within the scope of the enumeration type and not in the
+ enclosing scope. For example, the Red color can be referred to
+ with "Color::Red" but not "Red".
+
+ - Scoped enumerators and enumerations do not implicitly convert
+ to integers or 'bool'.
+
+ - The underlying type of the enum is well-defined. */
+#define SCOPED_ENUM_P(TYPE) \
+ (TREE_CODE (TYPE) == ENUMERAL_TYPE && ENUM_IS_SCOPED (TYPE))
+
+/* Determine whether this is an unscoped enumeration type. */
+#define UNSCOPED_ENUM_P(TYPE) \
+ (TREE_CODE (TYPE) == ENUMERAL_TYPE && !ENUM_IS_SCOPED (TYPE))
+
+/* Set the flag indicating whether an ENUMERAL_TYPE is a C++0x scoped
+ enumeration type (1) or a normal (unscoped) enumeration type
+ (0). */
+#define SET_SCOPED_ENUM_P(TYPE, VAL) \
+ (ENUM_IS_SCOPED (TYPE) = (VAL))
+
+#define SET_OPAQUE_ENUM_P(TYPE, VAL) \
+ (ENUM_IS_OPAQUE (TYPE) = (VAL))
+
+#define OPAQUE_ENUM_P(TYPE) \
+ (TREE_CODE (TYPE) == ENUMERAL_TYPE && ENUM_IS_OPAQUE (TYPE))
+
+/* Determines whether an ENUMERAL_TYPE has an explicit
+ underlying type. */
+#define ENUM_FIXED_UNDERLYING_TYPE_P(NODE) (TYPE_LANG_FLAG_5 (NODE))
+
+/* Returns the underlying type of the given enumeration type. The
+ underlying type is determined in different ways, depending on the
+ properties of the enum:
+
+ - In C++0x, the underlying type can be explicitly specified, e.g.,
+
+ enum E1 : char { ... } // underlying type is char
+
+ - In a C++0x scoped enumeration, the underlying type is int
+ unless otherwises specified:
+
+ enum class E2 { ... } // underlying type is int
+
+ - Otherwise, the underlying type is determined based on the
+ values of the enumerators. In this case, the
+ ENUM_UNDERLYING_TYPE will not be set until after the definition
+ of the enumeration is completed by finish_enum. */
+#define ENUM_UNDERLYING_TYPE(TYPE) \
+ TREE_TYPE (ENUMERAL_TYPE_CHECK (TYPE))
+
+/* [dcl.init.aggr]
+
+ An aggregate is an array or a class with no user-provided
+ constructors, no brace-or-equal-initializers for non-static data
+ members, no private or protected non-static data members, no
+ base classes, and no virtual functions.
+
+ As an extension, we also treat vectors as aggregates. Keep these
+ checks in ascending code order. */
+#define CP_AGGREGATE_TYPE_P(TYPE) \
+ (TREE_CODE (TYPE) == VECTOR_TYPE \
+ ||TREE_CODE (TYPE) == ARRAY_TYPE \
+ || (CLASS_TYPE_P (TYPE) && !CLASSTYPE_NON_AGGREGATE (TYPE)))
+
+/* Nonzero for a class type means that the class type has a
+ user-declared constructor. */
+#define TYPE_HAS_USER_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1 (NODE))
+
+/* When appearing in an INDIRECT_REF, it means that the tree structure
+ underneath is actually a call to a constructor. This is needed
+ when the constructor must initialize local storage (which can
+ be automatically destroyed), rather than allowing it to allocate
+ space from the heap.
+
+ When appearing in a SAVE_EXPR, it means that underneath
+ is a call to a constructor.
+
+ When appearing in a CONSTRUCTOR, the expression is a
+ compound literal.
+
+ When appearing in a FIELD_DECL, it means that this field
+ has been duly initialized in its constructor. */
+#define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4 (NODE))
+
+/* True if NODE is a brace-enclosed initializer. */
+#define BRACE_ENCLOSED_INITIALIZER_P(NODE) \
+ (TREE_CODE (NODE) == CONSTRUCTOR && TREE_TYPE (NODE) == init_list_type_node)
+
+/* True if NODE is a compound-literal, i.e., a brace-enclosed
+ initializer cast to a particular type. */
+#define COMPOUND_LITERAL_P(NODE) \
+ (TREE_CODE (NODE) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (NODE))
+
+#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \
+ && vec_safe_is_empty(CONSTRUCTOR_ELTS(NODE))\
+ && !TREE_HAS_CONSTRUCTOR (NODE))
+
+/* True if NODE is a init-list used as a direct-initializer, i.e.
+ B b{1,2}, not B b({1,2}) or B b = {1,2}. */
+#define CONSTRUCTOR_IS_DIRECT_INIT(NODE) (TREE_LANG_FLAG_0 (CONSTRUCTOR_CHECK (NODE)))
+
+/* True if NODE represents a conversion for direct-initialization in a
+ template. Set by perform_implicit_conversion_flags. */
+#define IMPLICIT_CONV_EXPR_DIRECT_INIT(NODE) \
+ (TREE_LANG_FLAG_0 (IMPLICIT_CONV_EXPR_CHECK (NODE)))
+
+/* Nonzero means that an object of this type can not be initialized using
+ an initializer list. */
+#define CLASSTYPE_NON_AGGREGATE(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->non_aggregate)
+#define TYPE_NON_AGGREGATE_CLASS(NODE) \
+ (CLASS_TYPE_P (NODE) && CLASSTYPE_NON_AGGREGATE (NODE))
+
+/* Nonzero if there is a non-trivial X::op=(cv X&) for this class. */
+#define TYPE_HAS_COMPLEX_COPY_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_copy_assign)
+
+/* Nonzero if there is a non-trivial X::X(cv X&) for this class. */
+#define TYPE_HAS_COMPLEX_COPY_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_copy_ctor)
+
+/* Nonzero if there is a non-trivial X::op=(X&&) for this class. */
+#define TYPE_HAS_COMPLEX_MOVE_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_move_assign)
+
+/* Nonzero if there is a non-trivial X::X(X&&) for this class. */
+#define TYPE_HAS_COMPLEX_MOVE_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_move_ctor)
+
+/* Nonzero if there is a non-trivial default constructor for this class. */
+#define TYPE_HAS_COMPLEX_DFLT(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_dflt)
+
+/* Nonzero if TYPE has a trivial destructor. From [class.dtor]:
+
+ A destructor is trivial if it is an implicitly declared
+ destructor and if:
+
+ - all of the direct base classes of its class have trivial
+ destructors,
+
+ - for all of the non-static data members of its class that are
+ of class type (or array thereof), each such class has a
+ trivial destructor. */
+#define TYPE_HAS_TRIVIAL_DESTRUCTOR(NODE) \
+ (!TYPE_HAS_NONTRIVIAL_DESTRUCTOR (NODE))
+
+/* Nonzero for _TYPE node means that this type does not have a trivial
+ destructor. Therefore, destroying an object of this type will
+ involve a call to a destructor. This can apply to objects of
+ ARRAY_TYPE is the type of the elements needs a destructor. */
+#define TYPE_HAS_NONTRIVIAL_DESTRUCTOR(NODE) \
+ (TYPE_LANG_FLAG_4 (NODE))
+
+/* Nonzero for class type means that the default constructor is trivial. */
+#define TYPE_HAS_TRIVIAL_DFLT(NODE) \
+ (TYPE_HAS_DEFAULT_CONSTRUCTOR (NODE) && ! TYPE_HAS_COMPLEX_DFLT (NODE))
+
+/* Nonzero for class type means that copy initialization of this type can use
+ a bitwise copy. */
+#define TYPE_HAS_TRIVIAL_COPY_CTOR(NODE) \
+ (TYPE_HAS_COPY_CTOR (NODE) && ! TYPE_HAS_COMPLEX_COPY_CTOR (NODE))
+
+/* Nonzero for class type means that assignment of this type can use
+ a bitwise copy. */
+#define TYPE_HAS_TRIVIAL_COPY_ASSIGN(NODE) \
+ (TYPE_HAS_COPY_ASSIGN (NODE) && ! TYPE_HAS_COMPLEX_COPY_ASSIGN (NODE))
+
+/* Returns true if NODE is a pointer-to-data-member. */
+#define TYPE_PTRDATAMEM_P(NODE) \
+ (TREE_CODE (NODE) == OFFSET_TYPE)
+/* Returns true if NODE is a pointer. */
+#define TYPE_PTR_P(NODE) \
+ (TREE_CODE (NODE) == POINTER_TYPE)
+
+/* Returns true if NODE is an object type:
+
+ [basic.types]
+
+ An object type is a (possibly cv-qualified) type that is not a
+ function type, not a reference type, and not a void type.
+
+ Keep these checks in ascending order, for speed. */
+#define TYPE_OBJ_P(NODE) \
+ (TREE_CODE (NODE) != REFERENCE_TYPE \
+ && !VOID_TYPE_P (NODE) \
+ && TREE_CODE (NODE) != FUNCTION_TYPE \
+ && TREE_CODE (NODE) != METHOD_TYPE)
+
+/* Returns true if NODE is a pointer to an object. Keep these checks
+ in ascending tree code order. */
+#define TYPE_PTROB_P(NODE) \
+ (TYPE_PTR_P (NODE) && TYPE_OBJ_P (TREE_TYPE (NODE)))
+
+/* Returns true if NODE is a reference to an object. Keep these checks
+ in ascending tree code order. */
+#define TYPE_REF_OBJ_P(NODE) \
+ (TREE_CODE (NODE) == REFERENCE_TYPE && TYPE_OBJ_P (TREE_TYPE (NODE)))
+
+/* Returns true if NODE is a pointer to an object, or a pointer to
+ void. Keep these checks in ascending tree code order. */
+#define TYPE_PTROBV_P(NODE) \
+ (TYPE_PTR_P (NODE) \
+ && !(TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE \
+ || TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
+
+/* Returns true if NODE is a pointer to function. */
+#define TYPE_PTRFN_P(NODE) \
+ (TYPE_PTR_P (NODE) \
+ && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
+
+/* Returns true if NODE is a reference to function. */
+#define TYPE_REFFN_P(NODE) \
+ (TREE_CODE (NODE) == REFERENCE_TYPE \
+ && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
+
+/* Nonzero for _TYPE node means that this type is a pointer to member
+ function type. */
+#define TYPE_PTRMEMFUNC_P(NODE) \
+ (TREE_CODE (NODE) == RECORD_TYPE \
+ && TYPE_LANG_SPECIFIC (NODE) \
+ && TYPE_PTRMEMFUNC_FLAG (NODE))
+
+#define TYPE_PTRMEMFUNC_FLAG(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->ptrmemfunc_flag)
+
+/* Returns true if NODE is a pointer-to-member. */
+#define TYPE_PTRMEM_P(NODE) \
+ (TYPE_PTRDATAMEM_P (NODE) || TYPE_PTRMEMFUNC_P (NODE))
+
+/* Returns true if NODE is a pointer or a pointer-to-member. */
+#define TYPE_PTR_OR_PTRMEM_P(NODE) \
+ (TYPE_PTR_P (NODE) || TYPE_PTRMEM_P (NODE))
+
+/* Indicates when overload resolution may resolve to a pointer to
+ member function. [expr.unary.op]/3 */
+#define PTRMEM_OK_P(NODE) \
+ TREE_LANG_FLAG_0 (TREE_CHECK3 ((NODE), ADDR_EXPR, OFFSET_REF, SCOPE_REF))
+
+/* Get the POINTER_TYPE to the METHOD_TYPE associated with this
+ pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true,
+ before using this macro. */
+#define TYPE_PTRMEMFUNC_FN_TYPE(NODE) \
+ (TREE_TYPE (TYPE_FIELDS (NODE)))
+
+/* Returns `A' for a type like `int (A::*)(double)' */
+#define TYPE_PTRMEMFUNC_OBJECT_TYPE(NODE) \
+ TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (NODE)))
+
+/* These are use to manipulate the canonical RECORD_TYPE from the
+ hashed POINTER_TYPE, and can only be used on the POINTER_TYPE. */
+#define TYPE_GET_PTRMEMFUNC_TYPE(NODE) \
+ (TYPE_LANG_SPECIFIC (NODE) ? LANG_TYPE_PTRMEM_CHECK (NODE)->record : NULL)
+#define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE) \
+ do { \
+ if (TYPE_LANG_SPECIFIC (NODE) == NULL) \
+ { \
+ TYPE_LANG_SPECIFIC (NODE) = ggc_alloc_cleared_lang_type \
+ (sizeof (struct lang_type_ptrmem)); \
+ TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.h.is_lang_type_class = 0; \
+ } \
+ TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.record = (VALUE); \
+ } while (0)
+
+/* For a pointer-to-member type of the form `T X::*', this is `X'.
+ For a type like `void (X::*)() const', this type is `X', not `const
+ X'. To get at the `const X' you have to look at the
+ TYPE_PTRMEM_POINTED_TO_TYPE; there, the first parameter will have
+ type `const X*'. */
+#define TYPE_PTRMEM_CLASS_TYPE(NODE) \
+ (TYPE_PTRDATAMEM_P (NODE) \
+ ? TYPE_OFFSET_BASETYPE (NODE) \
+ : TYPE_PTRMEMFUNC_OBJECT_TYPE (NODE))
+
+/* For a pointer-to-member type of the form `T X::*', this is `T'. */
+#define TYPE_PTRMEM_POINTED_TO_TYPE(NODE) \
+ (TYPE_PTRDATAMEM_P (NODE) \
+ ? TREE_TYPE (NODE) \
+ : TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (NODE)))
+
+/* For a pointer-to-member constant `X::Y' this is the RECORD_TYPE for
+ `X'. */
+#define PTRMEM_CST_CLASS(NODE) \
+ TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (PTRMEM_CST_CHECK (NODE)))
+
+/* For a pointer-to-member constant `X::Y' this is the _DECL for
+ `Y'. */
+#define PTRMEM_CST_MEMBER(NODE) (((ptrmem_cst_t)PTRMEM_CST_CHECK (NODE))->member)
+
+/* The expression in question for a TYPEOF_TYPE. */
+#define TYPEOF_TYPE_EXPR(NODE) (TYPE_VALUES_RAW (TYPEOF_TYPE_CHECK (NODE)))
+
+/* The type in question for an UNDERLYING_TYPE. */
+#define UNDERLYING_TYPE_TYPE(NODE) \
+ (TYPE_VALUES_RAW (UNDERLYING_TYPE_CHECK (NODE)))
+
+/* The type in question for BASES. */
+#define BASES_TYPE(NODE) \
+ (TYPE_VALUES_RAW (BASES_CHECK (NODE)))
+
+#define BASES_DIRECT(NODE) \
+ TREE_LANG_FLAG_0 (BASES_CHECK (NODE))
+
+/* The expression in question for a DECLTYPE_TYPE. */
+#define DECLTYPE_TYPE_EXPR(NODE) (TYPE_VALUES_RAW (DECLTYPE_TYPE_CHECK (NODE)))
+
+/* Whether the DECLTYPE_TYPE_EXPR of NODE was originally parsed as an
+ id-expression or a member-access expression. When false, it was
+ parsed as a full expression. */
+#define DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P(NODE) \
+ (DECLTYPE_TYPE_CHECK (NODE))->type_common.string_flag
+
+/* These flags indicate that we want different semantics from normal
+ decltype: lambda capture just drops references, init capture
+ uses auto semantics, lambda proxies look through implicit dereference. */
+#define DECLTYPE_FOR_LAMBDA_CAPTURE(NODE) \
+ TREE_LANG_FLAG_0 (DECLTYPE_TYPE_CHECK (NODE))
+#define DECLTYPE_FOR_INIT_CAPTURE(NODE) \
+ TREE_LANG_FLAG_1 (DECLTYPE_TYPE_CHECK (NODE))
+#define DECLTYPE_FOR_LAMBDA_PROXY(NODE) \
+ TREE_LANG_FLAG_2 (DECLTYPE_TYPE_CHECK (NODE))
+
+/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern' was
+ specified in its declaration. This can also be set for an
+ erroneously declared PARM_DECL. */
+#define DECL_THIS_EXTERN(NODE) \
+ DECL_LANG_FLAG_2 (VAR_FUNCTION_OR_PARM_DECL_CHECK (NODE))
+
+/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `static' was
+ specified in its declaration. This can also be set for an
+ erroneously declared PARM_DECL. */
+#define DECL_THIS_STATIC(NODE) \
+ DECL_LANG_FLAG_6 (VAR_FUNCTION_OR_PARM_DECL_CHECK (NODE))
+
+/* Nonzero for FIELD_DECL node means that this field is a lambda capture
+ field for an array of runtime bound. */
+#define DECL_VLA_CAPTURE_P(NODE) \
+ DECL_LANG_FLAG_1 (FIELD_DECL_CHECK (NODE))
+
+/* Nonzero for FIELD_DECL node means that this field is a base class
+ of the parent object, as opposed to a member field. */
+#define DECL_FIELD_IS_BASE(NODE) \
+ DECL_LANG_FLAG_6 (FIELD_DECL_CHECK (NODE))
+
+/* Nonzero for FIELD_DECL node means that this field is a simple (no
+ explicit initializer) lambda capture field, making it invisible to
+ name lookup in unevaluated contexts. */
+#define DECL_NORMAL_CAPTURE_P(NODE) \
+ DECL_LANG_FLAG_7 (FIELD_DECL_CHECK (NODE))
+
+/* Nonzero if TYPE is an anonymous union or struct type. We have to use a
+ flag for this because "A union for which objects or pointers are
+ declared is not an anonymous union" [class.union]. */
+#define ANON_AGGR_TYPE_P(NODE) \
+ (CLASS_TYPE_P (NODE) && LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr)
+#define SET_ANON_AGGR_TYPE_P(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr = 1)
+
+/* Nonzero if TYPE is an anonymous union type. */
+#define ANON_UNION_TYPE_P(NODE) \
+ (TREE_CODE (NODE) == UNION_TYPE && ANON_AGGR_TYPE_P (NODE))
+
+/* Define fields and accessors for nodes representing declared names. */
+
+#define TYPE_WAS_ANONYMOUS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->was_anonymous)
+
+/* C++: all of these are overloaded! These apply only to TYPE_DECLs. */
+
+/* The format of each node in the DECL_FRIENDLIST is as follows:
+
+ The TREE_PURPOSE will be the name of a function, i.e., an
+ IDENTIFIER_NODE. The TREE_VALUE will be itself a TREE_LIST, whose
+ TREE_VALUEs are friends with the given name. */
+#define DECL_FRIENDLIST(NODE) (DECL_INITIAL (NODE))
+#define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST))
+#define FRIEND_DECLS(LIST) (TREE_VALUE (LIST))
+
+/* The DECL_ACCESS, if non-NULL, is a TREE_LIST. The TREE_PURPOSE of
+ each node is a type; the TREE_VALUE is the access granted for this
+ DECL in that type. The DECL_ACCESS is set by access declarations.
+ For example, if a member that would normally be public in a
+ derived class is made protected, then the derived class and the
+ protected_access_node will appear in the DECL_ACCESS for the node. */
+#define DECL_ACCESS(NODE) (LANG_DECL_U2_CHECK (NODE, 0)->access)
+
+/* Nonzero if the FUNCTION_DECL is a global constructor. */
+#define DECL_GLOBAL_CTOR_P(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->global_ctor_p)
+
+/* Nonzero if the FUNCTION_DECL is a global destructor. */
+#define DECL_GLOBAL_DTOR_P(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->global_dtor_p)
+
+/* Accessor macros for C++ template decl nodes. */
+
+/* The DECL_TEMPLATE_PARMS are a list. The TREE_PURPOSE of each node
+ is a INT_CST whose TREE_INT_CST_LOW indicates the level of the
+ template parameters, with 1 being the outermost set of template
+ parameters. The TREE_VALUE is a vector, whose elements are the
+ template parameters at each level. Each element in the vector is a
+ TREE_LIST, whose TREE_VALUE is a PARM_DECL (if the parameter is a
+ non-type parameter), or a TYPE_DECL (if the parameter is a type
+ parameter). The TREE_PURPOSE is the default value, if any. The
+ TEMPLATE_PARM_INDEX for the parameter is available as the
+ DECL_INITIAL (for a PARM_DECL) or as the TREE_TYPE (for a
+ TYPE_DECL). */
+#define DECL_TEMPLATE_PARMS(NODE) \
+ TEMPLATE_DECL_CHECK (NODE)->decl_non_common.arguments
+#define DECL_INNERMOST_TEMPLATE_PARMS(NODE) \
+ INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (NODE))
+#define DECL_NTPARMS(NODE) \
+ TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (NODE))
+/* For function, method, class-data templates. */
+#define DECL_TEMPLATE_RESULT(NODE) \
+ DECL_RESULT_FLD (TEMPLATE_DECL_CHECK (NODE))
+/* For a function template at namespace scope, DECL_TEMPLATE_INSTANTIATIONS
+ lists all instantiations and specializations of the function so that
+ tsubst_friend_function can reassign them to another template if we find
+ that the namespace-scope template is really a partial instantiation of a
+ friend template.
+
+ For a class template the DECL_TEMPLATE_INSTANTIATIONS lists holds
+ all instantiations and specializations of the class type, including
+ partial instantiations and partial specializations, so that if we
+ explicitly specialize a partial instantiation we can walk the list
+ in maybe_process_partial_specialization and reassign them or complain
+ as appropriate.
+
+ In both cases, the TREE_PURPOSE of each node contains the arguments
+ used; the TREE_VALUE contains the generated variable. The template
+ arguments are always complete. For example, given:
+
+ template <class T> struct S1 {
+ template <class U> struct S2 {};
+ template <class U> struct S2<U*> {};
+ };
+
+ the record for the partial specialization will contain, as its
+ argument list, { {T}, {U*} }, and will be on the
+ DECL_TEMPLATE_INSTANTIATIONS list for `template <class T> template
+ <class U> struct S1<T>::S2'.
+
+ This list is not used for other templates. */
+#define DECL_TEMPLATE_INSTANTIATIONS(NODE) \
+ DECL_VINDEX (TEMPLATE_DECL_CHECK (NODE))
+
+/* For a class template, this list contains the partial
+ specializations of this template. (Full specializations are not
+ recorded on this list.) The TREE_PURPOSE holds the arguments used
+ in the partial specialization (e.g., for `template <class T> struct
+ S<T*, int>' this will be `T*, int'.) The arguments will also include
+ any outer template arguments. The TREE_VALUE holds the TEMPLATE_DECL
+ for the partial specialization. The TREE_TYPE is the _TYPE node for
+ the partial specialization.
+
+ This list is not used for other templates. */
+#define DECL_TEMPLATE_SPECIALIZATIONS(NODE) \
+ DECL_SIZE (TEMPLATE_DECL_CHECK (NODE))
+
+/* Nonzero for a DECL which is actually a template parameter. Keep
+ these checks in ascending tree code order. */
+#define DECL_TEMPLATE_PARM_P(NODE) \
+ (DECL_LANG_FLAG_0 (NODE) \
+ && (TREE_CODE (NODE) == CONST_DECL \
+ || TREE_CODE (NODE) == PARM_DECL \
+ || TREE_CODE (NODE) == TYPE_DECL \
+ || TREE_CODE (NODE) == TEMPLATE_DECL))
+
+/* Mark NODE as a template parameter. */
+#define SET_DECL_TEMPLATE_PARM_P(NODE) \
+ (DECL_LANG_FLAG_0 (NODE) = 1)
+
+/* Nonzero if NODE is a template template parameter. */
+#define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \
+ (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE))
+
+/* Nonzero for a DECL that represents a function template. */
+#define DECL_FUNCTION_TEMPLATE_P(NODE) \
+ (TREE_CODE (NODE) == TEMPLATE_DECL \
+ && DECL_TEMPLATE_RESULT (NODE) != NULL_TREE \
+ && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL)
+
+/* Nonzero for a DECL that represents a class template or alias
+ template. */
+#define DECL_TYPE_TEMPLATE_P(NODE) \
+ (TREE_CODE (NODE) == TEMPLATE_DECL \
+ && DECL_TEMPLATE_RESULT (NODE) != NULL_TREE \
+ && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == TYPE_DECL)
+
+/* Nonzero for a DECL that represents a class template. */
+#define DECL_CLASS_TEMPLATE_P(NODE) \
+ (DECL_TYPE_TEMPLATE_P (NODE) \
+ && DECL_IMPLICIT_TYPEDEF_P (DECL_TEMPLATE_RESULT (NODE)))
+
+/* Nonzero for a TEMPLATE_DECL that represents an alias template. */
+#define DECL_ALIAS_TEMPLATE_P(NODE) \
+ (DECL_TYPE_TEMPLATE_P (NODE) \
+ && !DECL_ARTIFICIAL (DECL_TEMPLATE_RESULT (NODE)))
+
+/* Nonzero for a NODE which declares a type. */
+#define DECL_DECLARES_TYPE_P(NODE) \
+ (TREE_CODE (NODE) == TYPE_DECL || DECL_TYPE_TEMPLATE_P (NODE))
+
+/* Nonzero if NODE declares a function. */
+#define DECL_DECLARES_FUNCTION_P(NODE) \
+ (TREE_CODE (NODE) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (NODE))
+
+/* Nonzero if NODE is the typedef implicitly generated for a type when
+ the type is declared. In C++, `struct S {};' is roughly
+ equivalent to `struct S {}; typedef struct S S;' in C.
+ DECL_IMPLICIT_TYPEDEF_P will hold for the typedef indicated in this
+ example. In C++, there is a second implicit typedef for each
+ class, in the scope of `S' itself, so that you can say `S::S'.
+ DECL_SELF_REFERENCE_P will hold for that second typedef. */
+#define DECL_IMPLICIT_TYPEDEF_P(NODE) \
+ (TREE_CODE (NODE) == TYPE_DECL && DECL_LANG_FLAG_2 (NODE))
+#define SET_DECL_IMPLICIT_TYPEDEF_P(NODE) \
+ (DECL_LANG_FLAG_2 (NODE) = 1)
+#define DECL_SELF_REFERENCE_P(NODE) \
+ (TREE_CODE (NODE) == TYPE_DECL && DECL_LANG_FLAG_4 (NODE))
+#define SET_DECL_SELF_REFERENCE_P(NODE) \
+ (DECL_LANG_FLAG_4 (NODE) = 1)
+
+/* A `primary' template is one that has its own template header and is not
+ a partial specialization. A member function of a class template is a
+ template, but not primary. A member template is primary. Friend
+ templates are primary, too. */
+
+/* Returns the primary template corresponding to these parameters. */
+#define DECL_PRIMARY_TEMPLATE(NODE) \
+ (TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (NODE)))
+
+/* Returns nonzero if NODE is a primary template. */
+#define PRIMARY_TEMPLATE_P(NODE) (DECL_PRIMARY_TEMPLATE (NODE) == (NODE))
+
+/* Nonzero iff NODE is a specialization of a template. The value
+ indicates the type of specializations:
+
+ 1=implicit instantiation
+
+ 2=partial or explicit specialization, e.g.:
+
+ template <> int min<int> (int, int),
+
+ 3=explicit instantiation, e.g.:
+
+ template int min<int> (int, int);
+
+ Note that NODE will be marked as a specialization even if the
+ template it is instantiating is not a primary template. For
+ example, given:
+
+ template <typename T> struct O {
+ void f();
+ struct I {};
+ };
+
+ both O<int>::f and O<int>::I will be marked as instantiations.
+
+ If DECL_USE_TEMPLATE is nonzero, then DECL_TEMPLATE_INFO will also
+ be non-NULL. */
+#define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->u.base.use_template)
+
+/* Like DECL_USE_TEMPLATE, but for class types. */
+#define CLASSTYPE_USE_TEMPLATE(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->use_template)
+
+/* True if NODE is a specialization of a primary template. */
+#define CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P(NODE) \
+ (CLASS_TYPE_P (NODE) \
+ && CLASSTYPE_USE_TEMPLATE (NODE) \
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))
+
+#define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1)
+#define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \
+ (CLASSTYPE_USE_TEMPLATE (NODE) & 1)
+
+#define DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) == 2)
+#define SET_DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) = 2)
+
+/* Returns true for an explicit or partial specialization of a class
+ template. */
+#define CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \
+ (CLASSTYPE_USE_TEMPLATE (NODE) == 2)
+#define SET_CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \
+ (CLASSTYPE_USE_TEMPLATE (NODE) = 2)
+
+#define DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 1)
+#define SET_DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 1)
+#define CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \
+ (CLASSTYPE_USE_TEMPLATE (NODE) == 1)
+#define SET_CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \
+ (CLASSTYPE_USE_TEMPLATE (NODE) = 1)
+
+#define DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 3)
+#define SET_DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 3)
+#define CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \
+ (CLASSTYPE_USE_TEMPLATE (NODE) == 3)
+#define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \
+ (CLASSTYPE_USE_TEMPLATE (NODE) = 3)
+
+/* Nonzero if DECL is a friend function which is an instantiation
+ from the point of view of the compiler, but not from the point of
+ view of the language. For example given:
+ template <class T> struct S { friend void f(T) {}; };
+ the declaration of `void f(int)' generated when S<int> is
+ instantiated will not be a DECL_TEMPLATE_INSTANTIATION, but will be
+ a DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION. */
+#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \
+ (DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL))
+
+/* Nonzero if DECL is a function generated from a function 'temploid',
+ i.e. template, member of class template, or dependent friend. */
+#define DECL_TEMPLOID_INSTANTIATION(DECL) \
+ (DECL_TEMPLATE_INSTANTIATION (DECL) \
+ || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (DECL))
+
+/* Nonzero if DECL is either defined implicitly by the compiler or
+ generated from a temploid. */
+#define DECL_GENERATED_P(DECL) \
+ (DECL_TEMPLOID_INSTANTIATION (DECL) || DECL_DEFAULTED_FN (DECL))
+
+/* Nonzero iff we are currently processing a declaration for an
+ entity with its own template parameter list, and which is not a
+ full specialization. */
+#define PROCESSING_REAL_TEMPLATE_DECL_P() \
+ (processing_template_decl > template_class_depth (current_scope ()))
+
+/* Nonzero if this VAR_DECL or FUNCTION_DECL has already been
+ instantiated, i.e. its definition has been generated from the
+ pattern given in the template. */
+#define DECL_TEMPLATE_INSTANTIATED(NODE) \
+ DECL_LANG_FLAG_1 (VAR_OR_FUNCTION_DECL_CHECK (NODE))
+
+/* We know what we're doing with this decl now. */
+#define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE)
+
+/* DECL_EXTERNAL must be set on a decl until the decl is actually emitted,
+ so that assemble_external will work properly. So we have this flag to
+ tell us whether the decl is really not external.
+
+ This flag does not indicate whether or not the decl is defined in the
+ current translation unit; it indicates whether or not we should emit the
+ decl at the end of compilation if it is defined and needed. */
+#define DECL_NOT_REALLY_EXTERN(NODE) \
+ (DECL_LANG_SPECIFIC (NODE)->u.base.not_really_extern)
+
+#define DECL_REALLY_EXTERN(NODE) \
+ (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE))
+
+/* A thunk is a stub function.
+
+ A thunk is an alternate entry point for an ordinary FUNCTION_DECL.
+ The address of the ordinary FUNCTION_DECL is given by the
+ DECL_INITIAL, which is always an ADDR_EXPR whose operand is a
+ FUNCTION_DECL. The job of the thunk is to either adjust the this
+ pointer before transferring control to the FUNCTION_DECL, or call
+ FUNCTION_DECL and then adjust the result value. Note, the result
+ pointer adjusting thunk must perform a call to the thunked
+ function, (or be implemented via passing some invisible parameter
+ to the thunked function, which is modified to perform the
+ adjustment just before returning).
+
+ A thunk may perform either, or both, of the following operations:
+
+ o Adjust the this or result pointer by a constant offset.
+ o Adjust the this or result pointer by looking up a vcall or vbase offset
+ in the vtable.
+
+ A this pointer adjusting thunk converts from a base to a derived
+ class, and hence adds the offsets. A result pointer adjusting thunk
+ converts from a derived class to a base, and hence subtracts the
+ offsets. If both operations are performed, then the constant
+ adjustment is performed first for this pointer adjustment and last
+ for the result pointer adjustment.
+
+ The constant adjustment is given by THUNK_FIXED_OFFSET. If the
+ vcall or vbase offset is required, THUNK_VIRTUAL_OFFSET is
+ used. For this pointer adjusting thunks, it is the vcall offset
+ into the vtable. For result pointer adjusting thunks it is the
+ binfo of the virtual base to convert to. Use that binfo's vbase
+ offset.
+
+ It is possible to have equivalent covariant thunks. These are
+ distinct virtual covariant thunks whose vbase offsets happen to
+ have the same value. THUNK_ALIAS is used to pick one as the
+ canonical thunk, which will get all the this pointer adjusting
+ thunks attached to it. */
+
+/* An integer indicating how many bytes should be subtracted from the
+ this or result pointer when this function is called. */
+#define THUNK_FIXED_OFFSET(DECL) \
+ (DECL_LANG_SPECIFIC (THUNK_FUNCTION_CHECK (DECL))->u.fn.u5.fixed_offset)
+
+/* A tree indicating how to perform the virtual adjustment. For a this
+ adjusting thunk it is the number of bytes to be added to the vtable
+ to find the vcall offset. For a result adjusting thunk, it is the
+ binfo of the relevant virtual base. If NULL, then there is no
+ virtual adjust. (The vptr is always located at offset zero from
+ the this or result pointer.) (If the covariant type is within the
+ class hierarchy being laid out, the vbase index is not yet known
+ at the point we need to create the thunks, hence the need to use
+ binfos.) */
+
+#define THUNK_VIRTUAL_OFFSET(DECL) \
+ (LANG_DECL_U2_CHECK (FUNCTION_DECL_CHECK (DECL), 0)->access)
+
+/* A thunk which is equivalent to another thunk. */
+#define THUNK_ALIAS(DECL) \
+ (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->u.min.template_info)
+
+/* For thunk NODE, this is the FUNCTION_DECL thunked to. It is
+ possible for the target to be a thunk too. */
+#define THUNK_TARGET(NODE) \
+ (LANG_DECL_FN_CHECK (NODE)->befriending_classes)
+
+/* True for a SCOPE_REF iff the "template" keyword was used to
+ indicate that the qualified name denotes a template. */
+#define QUALIFIED_NAME_IS_TEMPLATE(NODE) \
+ (TREE_LANG_FLAG_1 (SCOPE_REF_CHECK (NODE)))
+
+/* True for an OMP_ATOMIC that has dependent parameters. These are stored
+ as an expr in operand 1, and integer_zero_node in operand 0. */
+#define OMP_ATOMIC_DEPENDENT_P(NODE) \
+ (TREE_CODE (TREE_OPERAND (OMP_ATOMIC_CHECK (NODE), 0)) == INTEGER_CST)
+
+/* Used while gimplifying continue statements bound to OMP_FOR nodes. */
+#define OMP_FOR_GIMPLIFYING_P(NODE) \
+ (TREE_LANG_FLAG_0 (OMP_LOOP_CHECK (NODE)))
+
+/* A language-specific token attached to the OpenMP data clauses to
+ hold code (or code fragments) related to ctors, dtors, and op=.
+ See semantics.c for details. */
+#define CP_OMP_CLAUSE_INFO(NODE) \
+ TREE_TYPE (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_PRIVATE, \
+ OMP_CLAUSE_LINEAR))
+
+/* Nonzero if this transaction expression's body contains statements. */
+#define TRANSACTION_EXPR_IS_STMT(NODE) \
+ TREE_LANG_FLAG_0 (TRANSACTION_EXPR_CHECK (NODE))
+
+/* These macros provide convenient access to the various _STMT nodes
+ created when parsing template declarations. */
+#define TRY_STMTS(NODE) TREE_OPERAND (TRY_BLOCK_CHECK (NODE), 0)
+#define TRY_HANDLERS(NODE) TREE_OPERAND (TRY_BLOCK_CHECK (NODE), 1)
+
+#define EH_SPEC_STMTS(NODE) TREE_OPERAND (EH_SPEC_BLOCK_CHECK (NODE), 0)
+#define EH_SPEC_RAISES(NODE) TREE_OPERAND (EH_SPEC_BLOCK_CHECK (NODE), 1)
+
+#define USING_STMT_NAMESPACE(NODE) TREE_OPERAND (USING_STMT_CHECK (NODE), 0)
+
+/* Nonzero if this try block is a function try block. */
+#define FN_TRY_BLOCK_P(NODE) TREE_LANG_FLAG_3 (TRY_BLOCK_CHECK (NODE))
+#define HANDLER_PARMS(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 0)
+#define HANDLER_BODY(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 1)
+#define HANDLER_TYPE(NODE) TREE_TYPE (HANDLER_CHECK (NODE))
+
+/* CLEANUP_STMT accessors. The statement(s) covered, the cleanup to run
+ and the VAR_DECL for which this cleanup exists. */
+#define CLEANUP_BODY(NODE) TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 0)
+#define CLEANUP_EXPR(NODE) TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 1)
+#define CLEANUP_DECL(NODE) TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 2)
+
+/* IF_STMT accessors. These give access to the condition of the if
+ statement, the then block of the if statement, and the else block
+ of the if statement if it exists. */
+#define IF_COND(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 0)
+#define THEN_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 1)
+#define ELSE_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 2)
+#define IF_SCOPE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 3)
+
+/* WHILE_STMT accessors. These give access to the condition of the
+ while statement and the body of the while statement, respectively. */
+#define WHILE_COND(NODE) TREE_OPERAND (WHILE_STMT_CHECK (NODE), 0)
+#define WHILE_BODY(NODE) TREE_OPERAND (WHILE_STMT_CHECK (NODE), 1)
+
+/* DO_STMT accessors. These give access to the condition of the do
+ statement and the body of the do statement, respectively. */
+#define DO_COND(NODE) TREE_OPERAND (DO_STMT_CHECK (NODE), 0)
+#define DO_BODY(NODE) TREE_OPERAND (DO_STMT_CHECK (NODE), 1)
+
+/* FOR_STMT accessors. These give access to the init statement,
+ condition, update expression, and body of the for statement,
+ respectively. */
+#define FOR_INIT_STMT(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 0)
+#define FOR_COND(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 1)
+#define FOR_EXPR(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 2)
+#define FOR_BODY(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 3)
+#define FOR_SCOPE(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 4)
+
+/* RANGE_FOR_STMT accessors. These give access to the declarator,
+ expression, body, and scope of the statement, respectively. */
+#define RANGE_FOR_DECL(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 0)
+#define RANGE_FOR_EXPR(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 1)
+#define RANGE_FOR_BODY(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 2)
+#define RANGE_FOR_SCOPE(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 3)
+#define RANGE_FOR_IVDEP(NODE) TREE_LANG_FLAG_6 (RANGE_FOR_STMT_CHECK (NODE))
+
+#define SWITCH_STMT_COND(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0)
+#define SWITCH_STMT_BODY(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1)
+#define SWITCH_STMT_TYPE(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 2)
+#define SWITCH_STMT_SCOPE(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 3)
+
+/* STMT_EXPR accessor. */
+#define STMT_EXPR_STMT(NODE) TREE_OPERAND (STMT_EXPR_CHECK (NODE), 0)
+
+/* EXPR_STMT accessor. This gives the expression associated with an
+ expression statement. */
+#define EXPR_STMT_EXPR(NODE) TREE_OPERAND (EXPR_STMT_CHECK (NODE), 0)
+
+/* True if this TARGET_EXPR was created by build_cplus_new, and so we can
+ discard it if it isn't useful. */
+#define TARGET_EXPR_IMPLICIT_P(NODE) \
+ TREE_LANG_FLAG_0 (TARGET_EXPR_CHECK (NODE))
+
+/* True if this TARGET_EXPR is the result of list-initialization of a
+ temporary. */
+#define TARGET_EXPR_LIST_INIT_P(NODE) \
+ TREE_LANG_FLAG_1 (TARGET_EXPR_CHECK (NODE))
+
+/* True if this TARGET_EXPR expresses direct-initialization of an object
+ to be named later. */
+#define TARGET_EXPR_DIRECT_INIT_P(NODE) \
+ TREE_LANG_FLAG_2 (TARGET_EXPR_CHECK (NODE))
+
+/* True if EXPR expresses direct-initialization of a TYPE. */
+#define DIRECT_INIT_EXPR_P(TYPE,EXPR) \
+ (TREE_CODE (EXPR) == TARGET_EXPR && TREE_LANG_FLAG_2 (EXPR) \
+ && same_type_ignoring_top_level_qualifiers_p (TYPE, TREE_TYPE (EXPR)))
+
+/* True if this CONVERT_EXPR is for a conversion to virtual base in
+ an NSDMI, and should be re-evaluated when used in a constructor. */
+#define CONVERT_EXPR_VBASE_PATH(NODE) \
+ TREE_LANG_FLAG_0 (CONVERT_EXPR_CHECK (NODE))
+
+/* True if SIZEOF_EXPR argument is type. */
+#define SIZEOF_EXPR_TYPE_P(NODE) \
+ TREE_LANG_FLAG_0 (SIZEOF_EXPR_CHECK (NODE))
+
+/* An enumeration of the kind of tags that C++ accepts. */
+enum tag_types {
+ none_type = 0, /* Not a tag type. */
+ record_type, /* "struct" types. */
+ class_type, /* "class" types. */
+ union_type, /* "union" types. */
+ enum_type, /* "enum" types. */
+ typename_type /* "typename" types. */
+};
+
+/* The various kinds of lvalues we distinguish. */
+enum cp_lvalue_kind_flags {
+ clk_none = 0, /* Things that are not an lvalue. */
+ clk_ordinary = 1, /* An ordinary lvalue. */
+ clk_rvalueref = 2,/* An xvalue (rvalue formed using an rvalue reference) */
+ clk_class = 4, /* A prvalue of class-type. */
+ clk_bitfield = 8, /* An lvalue for a bit-field. */
+ clk_packed = 16 /* An lvalue for a packed field. */
+};
+
+/* This type is used for parameters and variables which hold
+ combinations of the flags in enum cp_lvalue_kind_flags. */
+typedef int cp_lvalue_kind;
+
+/* Various kinds of template specialization, instantiation, etc. */
+typedef enum tmpl_spec_kind {
+ tsk_none, /* Not a template at all. */
+ tsk_invalid_member_spec, /* An explicit member template
+ specialization, but the enclosing
+ classes have not all been explicitly
+ specialized. */
+ tsk_invalid_expl_inst, /* An explicit instantiation containing
+ template parameter lists. */
+ tsk_excessive_parms, /* A template declaration with too many
+ template parameter lists. */
+ tsk_insufficient_parms, /* A template declaration with too few
+ parameter lists. */
+ tsk_template, /* A template declaration. */
+ tsk_expl_spec, /* An explicit specialization. */
+ tsk_expl_inst /* An explicit instantiation. */
+} tmpl_spec_kind;
+
+/* The various kinds of access. BINFO_ACCESS depends on these being
+ two bit quantities. The numerical values are important; they are
+ used to initialize RTTI data structures, so changing them changes
+ the ABI. */
+typedef enum access_kind {
+ ak_none = 0, /* Inaccessible. */
+ ak_public = 1, /* Accessible, as a `public' thing. */
+ ak_protected = 2, /* Accessible, as a `protected' thing. */
+ ak_private = 3 /* Accessible, as a `private' thing. */
+} access_kind;
+
+/* The various kinds of special functions. If you add to this list,
+ you should update special_function_p as well. */
+typedef enum special_function_kind {
+ sfk_none = 0, /* Not a special function. This enumeral
+ must have value zero; see
+ special_function_p. */
+ sfk_constructor, /* A constructor. */
+ sfk_copy_constructor, /* A copy constructor. */
+ sfk_move_constructor, /* A move constructor. */
+ sfk_copy_assignment, /* A copy assignment operator. */
+ sfk_move_assignment, /* A move assignment operator. */
+ sfk_destructor, /* A destructor. */
+ sfk_complete_destructor, /* A destructor for complete objects. */
+ sfk_base_destructor, /* A destructor for base subobjects. */
+ sfk_deleting_destructor, /* A destructor for complete objects that
+ deletes the object after it has been
+ destroyed. */
+ sfk_conversion, /* A conversion operator. */
+ sfk_inheriting_constructor /* An inheriting constructor */
+} special_function_kind;
+
+/* The various kinds of linkage. From [basic.link],
+
+ A name is said to have linkage when it might denote the same
+ object, reference, function, type, template, namespace or value
+ as a name introduced in another scope:
+
+ -- When a name has external linkage, the entity it denotes can
+ be referred to from scopes of other translation units or from
+ other scopes of the same translation unit.
+
+ -- When a name has internal linkage, the entity it denotes can
+ be referred to by names from other scopes in the same
+ translation unit.
+
+ -- When a name has no linkage, the entity it denotes cannot be
+ referred to by names from other scopes. */
+
+typedef enum linkage_kind {
+ lk_none, /* No linkage. */
+ lk_internal, /* Internal linkage. */
+ lk_external /* External linkage. */
+} linkage_kind;
+
+typedef enum duration_kind {
+ dk_static,
+ dk_thread,
+ dk_auto,
+ dk_dynamic
+} duration_kind;
+
+/* Bitmask flags to control type substitution. */
+enum tsubst_flags {
+ tf_none = 0, /* nothing special */
+ tf_error = 1 << 0, /* give error messages */
+ tf_warning = 1 << 1, /* give warnings too */
+ tf_ignore_bad_quals = 1 << 2, /* ignore bad cvr qualifiers */
+ tf_keep_type_decl = 1 << 3, /* retain typedef type decls
+ (make_typename_type use) */
+ tf_ptrmem_ok = 1 << 4, /* pointers to member ok (internal
+ instantiate_type use) */
+ tf_user = 1 << 5, /* found template must be a user template
+ (lookup_template_class use) */
+ tf_conv = 1 << 6, /* We are determining what kind of
+ conversion might be permissible,
+ not actually performing the
+ conversion. */
+ tf_decltype = 1 << 7, /* We are the operand of decltype.
+ Used to implement the special rules
+ for calls in decltype (5.2.2/11). */
+ tf_partial = 1 << 8, /* Doing initial explicit argument
+ substitution in fn_type_unification. */
+ /* Convenient substitution flags combinations. */
+ tf_warning_or_error = tf_warning | tf_error
+};
+
+/* This type is used for parameters and variables which hold
+ combinations of the flags in enum tsubst_flags. */
+typedef int tsubst_flags_t;
+
+/* The kind of checking we can do looking in a class hierarchy. */
+enum base_access_flags {
+ ba_any = 0, /* Do not check access, allow an ambiguous base,
+ prefer a non-virtual base */
+ ba_unique = 1 << 0, /* Must be a unique base. */
+ ba_check_bit = 1 << 1, /* Check access. */
+ ba_check = ba_unique | ba_check_bit,
+ ba_ignore_scope = 1 << 2 /* Ignore access allowed by local scope. */
+};
+
+/* This type is used for parameters and variables which hold
+ combinations of the flags in enum base_access_flags. */
+typedef int base_access;
+
+/* The various kinds of access check during parsing. */
+typedef enum deferring_kind {
+ dk_no_deferred = 0, /* Check access immediately */
+ dk_deferred = 1, /* Deferred check */
+ dk_no_check = 2 /* No access check */
+} deferring_kind;
+
+/* The kind of base we can find, looking in a class hierarchy.
+ Values <0 indicate we failed. */
+typedef enum base_kind {
+ bk_inaccessible = -3, /* The base is inaccessible */
+ bk_ambig = -2, /* The base is ambiguous */
+ bk_not_base = -1, /* It is not a base */
+ bk_same_type = 0, /* It is the same type */
+ bk_proper_base = 1, /* It is a proper base */
+ bk_via_virtual = 2 /* It is a proper base, but via a virtual
+ path. This might not be the canonical
+ binfo. */
+} base_kind;
+
+/* Node for "pointer to (virtual) function".
+ This may be distinct from ptr_type_node so gdb can distinguish them. */
+#define vfunc_ptr_type_node vtable_entry_type
+
+
+/* For building calls to `delete'. */
+extern GTY(()) tree integer_two_node;
+
+/* The number of function bodies which we are currently processing.
+ (Zero if we are at namespace scope, one inside the body of a
+ function, two inside the body of a function in a local class, etc.) */
+extern int function_depth;
+
+/* Nonzero if we are inside eq_specializations, which affects comparison of
+ PARM_DECLs in cp_tree_equal. */
+extern int comparing_specializations;
+
+/* In parser.c. */
+
+/* Nonzero if we are parsing an unevaluated operand: an operand to
+ sizeof, typeof, or alignof. This is a count since operands to
+ sizeof can be nested. */
+
+extern int cp_unevaluated_operand;
+extern tree cp_convert_range_for (tree, tree, tree, bool);
+extern bool parsing_nsdmi (void);
+
+/* in pt.c */
+
+/* These values are used for the `STRICT' parameter to type_unification and
+ fn_type_unification. Their meanings are described with the
+ documentation for fn_type_unification. */
+
+typedef enum unification_kind_t {
+ DEDUCE_CALL,
+ DEDUCE_CONV,
+ DEDUCE_EXACT
+} unification_kind_t;
+
+/* in class.c */
+
+extern int current_class_depth;
+
+/* An array of all local classes present in this translation unit, in
+ declaration order. */
+extern GTY(()) vec<tree, va_gc> *local_classes;
+
+/* Here's where we control how name mangling takes place. */
+
+/* Cannot use '$' up front, because this confuses gdb
+ (names beginning with '$' are gdb-local identifiers).
+
+ Note that all forms in which the '$' is significant are long enough
+ for direct indexing (meaning that if we know there is a '$'
+ at a particular location, we can index into the string at
+ any other location that provides distinguishing characters). */
+
+/* Define NO_DOT_IN_LABEL in your favorite tm file if your assembler
+ doesn't allow '.' in symbol names. */
+#ifndef NO_DOT_IN_LABEL
+
+#define JOINER '.'
+
+#define AUTO_TEMP_NAME "_.tmp_"
+#define VFIELD_BASE ".vf"
+#define VFIELD_NAME "_vptr."
+#define VFIELD_NAME_FORMAT "_vptr.%s"
+
+#else /* NO_DOT_IN_LABEL */
+
+#ifndef NO_DOLLAR_IN_LABEL
+
+#define JOINER '$'
+
+#define AUTO_TEMP_NAME "_$tmp_"
+#define VFIELD_BASE "$vf"
+#define VFIELD_NAME "_vptr$"
+#define VFIELD_NAME_FORMAT "_vptr$%s"
+
+#else /* NO_DOLLAR_IN_LABEL */
+
+#define AUTO_TEMP_NAME "__tmp_"
+#define TEMP_NAME_P(ID_NODE) \
+ (!strncmp (IDENTIFIER_POINTER (ID_NODE), AUTO_TEMP_NAME, \
+ sizeof (AUTO_TEMP_NAME) - 1))
+#define VTABLE_NAME "__vt_"
+#define VTABLE_NAME_P(ID_NODE) \
+ (!strncmp (IDENTIFIER_POINTER (ID_NODE), VTABLE_NAME, \
+ sizeof (VTABLE_NAME) - 1))
+#define VFIELD_BASE "__vfb"
+#define VFIELD_NAME "__vptr_"
+#define VFIELD_NAME_P(ID_NODE) \
+ (!strncmp (IDENTIFIER_POINTER (ID_NODE), VFIELD_NAME, \
+ sizeof (VFIELD_NAME) - 1))
+#define VFIELD_NAME_FORMAT "__vptr_%s"
+
+#endif /* NO_DOLLAR_IN_LABEL */
+#endif /* NO_DOT_IN_LABEL */
+
+#define THIS_NAME "this"
+
+#define IN_CHARGE_NAME "__in_chrg"
+
+#define VTBL_PTR_TYPE "__vtbl_ptr_type"
+#define VTABLE_DELTA_NAME "__delta"
+#define VTABLE_PFN_NAME "__pfn"
+
+#define LAMBDANAME_PREFIX "__lambda"
+#define LAMBDANAME_FORMAT LAMBDANAME_PREFIX "%d"
+
+#define UDLIT_OP_ANSI_PREFIX "operator\"\""
+#define UDLIT_OP_ANSI_FORMAT UDLIT_OP_ANSI_PREFIX "%s"
+#define UDLIT_OP_MANGLED_PREFIX "li"
+#define UDLIT_OP_MANGLED_FORMAT UDLIT_OP_MANGLED_PREFIX "%s"
+#define UDLIT_OPER_P(ID_NODE) \
+ (!strncmp (IDENTIFIER_POINTER (ID_NODE), \
+ UDLIT_OP_ANSI_PREFIX, \
+ sizeof (UDLIT_OP_ANSI_PREFIX) - 1))
+#define UDLIT_OP_SUFFIX(ID_NODE) \
+ (IDENTIFIER_POINTER (ID_NODE) + sizeof (UDLIT_OP_ANSI_PREFIX) - 1)
+
+#if !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL)
+
+#define VTABLE_NAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[1] == 'v' \
+ && IDENTIFIER_POINTER (ID_NODE)[2] == 't' \
+ && IDENTIFIER_POINTER (ID_NODE)[3] == JOINER)
+
+#define TEMP_NAME_P(ID_NODE) \
+ (!strncmp (IDENTIFIER_POINTER (ID_NODE), AUTO_TEMP_NAME, sizeof (AUTO_TEMP_NAME)-1))
+#define VFIELD_NAME_P(ID_NODE) \
+ (!strncmp (IDENTIFIER_POINTER (ID_NODE), VFIELD_NAME, sizeof(VFIELD_NAME)-1))
+
+#endif /* !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) */
+
+
+/* Nonzero if we're done parsing and into end-of-file activities. */
+
+extern int at_eof;
+
+/* A list of namespace-scope objects which have constructors or
+ destructors which reside in the global scope. The decl is stored
+ in the TREE_VALUE slot and the initializer is stored in the
+ TREE_PURPOSE slot. */
+extern GTY(()) tree static_aggregates;
+/* Likewise, for thread local storage. */
+extern GTY(()) tree tls_aggregates;
+
+enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
+
+/* These are uses as bits in flags passed to various functions to
+ control their behavior. Despite the LOOKUP_ prefix, many of these
+ do not control name lookup. ??? Functions using these flags should
+ probably be modified to accept explicit boolean flags for the
+ behaviors relevant to them. */
+/* Check for access violations. */
+#define LOOKUP_PROTECT (1 << 0)
+#define LOOKUP_NORMAL (LOOKUP_PROTECT)
+/* Even if the function found by lookup is a virtual function, it
+ should be called directly. */
+#define LOOKUP_NONVIRTUAL (1 << 1)
+/* Non-converting (i.e., "explicit") constructors are not tried. This flag
+ indicates that we are not performing direct-initialization. */
+#define LOOKUP_ONLYCONVERTING (1 << 2)
+#define LOOKUP_IMPLICIT (LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING)
+/* If a temporary is created, it should be created so that it lives
+ as long as the current variable bindings; otherwise it only lives
+ until the end of the complete-expression. It also forces
+ direct-initialization in cases where other parts of the compiler
+ have already generated a temporary, such as reference
+ initialization and the catch parameter. */
+#define DIRECT_BIND (1 << 3)
+/* We're performing a user-defined conversion, so more user-defined
+ conversions are not permitted (only built-in conversions). */
+#define LOOKUP_NO_CONVERSION (1 << 4)
+/* The user has explicitly called a destructor. (Therefore, we do
+ not need to check that the object is non-NULL before calling the
+ destructor.) */
+#define LOOKUP_DESTRUCTOR (1 << 5)
+/* Do not permit references to bind to temporaries. */
+#define LOOKUP_NO_TEMP_BIND (1 << 6)
+/* Do not accept objects, and possibly namespaces. */
+#define LOOKUP_PREFER_TYPES (1 << 7)
+/* Do not accept objects, and possibly types. */
+#define LOOKUP_PREFER_NAMESPACES (1 << 8)
+/* Accept types or namespaces. */
+#define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
+/* Return friend declarations and un-declared builtin functions.
+ (Normally, these entities are registered in the symbol table, but
+ not found by lookup.) */
+#define LOOKUP_HIDDEN (LOOKUP_PREFER_NAMESPACES << 1)
+/* Prefer that the lvalue be treated as an rvalue. */
+#define LOOKUP_PREFER_RVALUE (LOOKUP_HIDDEN << 1)
+/* We're inside an init-list, so narrowing conversions are ill-formed. */
+#define LOOKUP_NO_NARROWING (LOOKUP_PREFER_RVALUE << 1)
+/* We're looking up a constructor for list-initialization. */
+#define LOOKUP_LIST_INIT_CTOR (LOOKUP_NO_NARROWING << 1)
+/* This is the first parameter of a copy constructor. */
+#define LOOKUP_COPY_PARM (LOOKUP_LIST_INIT_CTOR << 1)
+/* We only want to consider list constructors. */
+#define LOOKUP_LIST_ONLY (LOOKUP_COPY_PARM << 1)
+/* Return after determining which function to call and checking access.
+ Used by sythesized_method_walk to determine which functions will
+ be called to initialize subobjects, in order to determine exception
+ specification and possible implicit delete.
+ This is kind of a hack, but exiting early avoids problems with trying
+ to perform argument conversions when the class isn't complete yet. */
+#define LOOKUP_SPECULATIVE (LOOKUP_LIST_ONLY << 1)
+/* Used by calls from defaulted functions to limit the overload set to avoid
+ cycles trying to declare them (core issue 1092). */
+#define LOOKUP_DEFAULTED (LOOKUP_SPECULATIVE << 1)
+/* Used in calls to store_init_value to suppress its usual call to
+ digest_init. */
+#define LOOKUP_ALREADY_DIGESTED (LOOKUP_DEFAULTED << 1)
+/* An instantiation with explicit template arguments. */
+#define LOOKUP_EXPLICIT_TMPL_ARGS (LOOKUP_ALREADY_DIGESTED << 1)
+/* Like LOOKUP_NO_TEMP_BIND, but also prevent binding to xvalues. */
+#define LOOKUP_NO_RVAL_BIND (LOOKUP_EXPLICIT_TMPL_ARGS << 1)
+/* Used by case_conversion to disregard non-integral conversions. */
+#define LOOKUP_NO_NON_INTEGRAL (LOOKUP_NO_RVAL_BIND << 1)
+/* Used for delegating constructors in order to diagnose self-delegation. */
+#define LOOKUP_DELEGATING_CONS (LOOKUP_NO_NON_INTEGRAL << 1)
+
+#define LOOKUP_NAMESPACES_ONLY(F) \
+ (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
+#define LOOKUP_TYPES_ONLY(F) \
+ (!((F) & LOOKUP_PREFER_NAMESPACES) && ((F) & LOOKUP_PREFER_TYPES))
+#define LOOKUP_QUALIFIERS_ONLY(F) ((F) & LOOKUP_PREFER_BOTH)
+
+
+/* These flags are used by the conversion code.
+ CONV_IMPLICIT : Perform implicit conversions (standard and user-defined).
+ CONV_STATIC : Perform the explicit conversions for static_cast.
+ CONV_CONST : Perform the explicit conversions for const_cast.
+ CONV_REINTERPRET: Perform the explicit conversions for reinterpret_cast.
+ CONV_PRIVATE : Perform upcasts to private bases.
+ CONV_FORCE_TEMP : Require a new temporary when converting to the same
+ aggregate type. */
+
+#define CONV_IMPLICIT 1
+#define CONV_STATIC 2
+#define CONV_CONST 4
+#define CONV_REINTERPRET 8
+#define CONV_PRIVATE 16
+/* #define CONV_NONCONVERTING 32 */
+#define CONV_FORCE_TEMP 64
+#define CONV_OLD_CONVERT (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \
+ | CONV_REINTERPRET)
+#define CONV_C_CAST (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \
+ | CONV_REINTERPRET | CONV_PRIVATE | CONV_FORCE_TEMP)
+
+/* Used by build_expr_type_conversion to indicate which types are
+ acceptable as arguments to the expression under consideration. */
+
+#define WANT_INT 1 /* integer types, including bool */
+#define WANT_FLOAT 2 /* floating point types */
+#define WANT_ENUM 4 /* enumerated types */
+#define WANT_POINTER 8 /* pointer types */
+#define WANT_NULL 16 /* null pointer constant */
+#define WANT_VECTOR_OR_COMPLEX 32 /* vector or complex types */
+#define WANT_ARITH (WANT_INT | WANT_FLOAT | WANT_VECTOR_OR_COMPLEX)
+
+/* Used with comptypes, and related functions, to guide type
+ comparison. */
+
+#define COMPARE_STRICT 0 /* Just check if the types are the
+ same. */
+#define COMPARE_BASE 1 /* Check to see if the second type is
+ derived from the first. */
+#define COMPARE_DERIVED 2 /* Like COMPARE_BASE, but in
+ reverse. */
+#define COMPARE_REDECLARATION 4 /* The comparison is being done when
+ another declaration of an existing
+ entity is seen. */
+#define COMPARE_STRUCTURAL 8 /* The comparison is intended to be
+ structural. The actual comparison
+ will be identical to
+ COMPARE_STRICT. */
+
+/* Used with push_overloaded_decl. */
+#define PUSH_GLOBAL 0 /* Push the DECL into namespace scope,
+ regardless of the current scope. */
+#define PUSH_LOCAL 1 /* Push the DECL into the current
+ scope. */
+#define PUSH_USING 2 /* We are pushing this DECL as the
+ result of a using declaration. */
+
+/* Used with start function. */
+#define SF_DEFAULT 0 /* No flags. */
+#define SF_PRE_PARSED 1 /* The function declaration has
+ already been parsed. */
+#define SF_INCLASS_INLINE 2 /* The function is an inline, defined
+ in the class body. */
+
+/* Used with start_decl's initialized parameter. */
+#define SD_UNINITIALIZED 0
+#define SD_INITIALIZED 1
+#define SD_DEFAULTED 2
+#define SD_DELETED 3
+
+/* Returns nonzero iff TYPE1 and TYPE2 are the same type, or if TYPE2
+ is derived from TYPE1, or if TYPE2 is a pointer (reference) to a
+ class derived from the type pointed to (referred to) by TYPE1. */
+#define same_or_base_type_p(TYPE1, TYPE2) \
+ comptypes ((TYPE1), (TYPE2), COMPARE_BASE)
+
+/* These macros are used to access a TEMPLATE_PARM_INDEX. */
+#define TEMPLATE_PARM_INDEX_CAST(NODE) \
+ ((template_parm_index*)TEMPLATE_PARM_INDEX_CHECK (NODE))
+#define TEMPLATE_PARM_IDX(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->index)
+#define TEMPLATE_PARM_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->level)
+#define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (NODE))
+#define TEMPLATE_PARM_ORIG_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->orig_level)
+#define TEMPLATE_PARM_DECL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->decl)
+#define TEMPLATE_PARM_PARAMETER_PACK(NODE) \
+ (TREE_LANG_FLAG_0 (TEMPLATE_PARM_INDEX_CHECK (NODE)))
+
+/* These macros are for accessing the fields of TEMPLATE_TYPE_PARM,
+ TEMPLATE_TEMPLATE_PARM and BOUND_TEMPLATE_TEMPLATE_PARM nodes. */
+#define TEMPLATE_TYPE_PARM_INDEX(NODE) \
+ (TYPE_VALUES_RAW (TREE_CHECK3 ((NODE), TEMPLATE_TYPE_PARM, \
+ TEMPLATE_TEMPLATE_PARM, \
+ BOUND_TEMPLATE_TEMPLATE_PARM)))
+#define TEMPLATE_TYPE_IDX(NODE) \
+ (TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (NODE)))
+#define TEMPLATE_TYPE_LEVEL(NODE) \
+ (TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
+#define TEMPLATE_TYPE_ORIG_LEVEL(NODE) \
+ (TEMPLATE_PARM_ORIG_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
+#define TEMPLATE_TYPE_DECL(NODE) \
+ (TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
+#define TEMPLATE_TYPE_PARAMETER_PACK(NODE) \
+ (TEMPLATE_PARM_PARAMETER_PACK (TEMPLATE_TYPE_PARM_INDEX (NODE)))
+
+/* True iff this TEMPLATE_TYPE_PARM represents decltype(auto). */
+#define AUTO_IS_DECLTYPE(NODE) \
+ (TYPE_LANG_FLAG_5 (TEMPLATE_TYPE_PARM_CHECK (NODE)))
+
+/* These constants can used as bit flags in the process of tree formatting.
+
+ TFF_PLAIN_IDENTIFIER: unqualified part of a name.
+ TFF_SCOPE: include the class and namespace scope of the name.
+ TFF_CHASE_TYPEDEF: print the original type-id instead of the typedef-name.
+ TFF_DECL_SPECIFIERS: print decl-specifiers.
+ TFF_CLASS_KEY_OR_ENUM: precede a class-type name (resp. enum name) with
+ a class-key (resp. `enum').
+ TFF_RETURN_TYPE: include function return type.
+ TFF_FUNCTION_DEFAULT_ARGUMENTS: include function default parameter values.
+ TFF_EXCEPTION_SPECIFICATION: show function exception specification.
+ TFF_TEMPLATE_HEADER: show the template<...> header in a
+ template-declaration.
+ TFF_TEMPLATE_NAME: show only template-name.
+ TFF_EXPR_IN_PARENS: parenthesize expressions.
+ TFF_NO_FUNCTION_ARGUMENTS: don't show function arguments.
+ TFF_UNQUALIFIED_NAME: do not print the qualifying scope of the
+ top-level entity.
+ TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS: do not omit template arguments
+ identical to their defaults.
+ TFF_NO_TEMPLATE_BINDINGS: do not print information about the template
+ arguments for a function template specialization. */
+
+#define TFF_PLAIN_IDENTIFIER (0)
+#define TFF_SCOPE (1)
+#define TFF_CHASE_TYPEDEF (1 << 1)
+#define TFF_DECL_SPECIFIERS (1 << 2)
+#define TFF_CLASS_KEY_OR_ENUM (1 << 3)
+#define TFF_RETURN_TYPE (1 << 4)
+#define TFF_FUNCTION_DEFAULT_ARGUMENTS (1 << 5)
+#define TFF_EXCEPTION_SPECIFICATION (1 << 6)
+#define TFF_TEMPLATE_HEADER (1 << 7)
+#define TFF_TEMPLATE_NAME (1 << 8)
+#define TFF_EXPR_IN_PARENS (1 << 9)
+#define TFF_NO_FUNCTION_ARGUMENTS (1 << 10)
+#define TFF_UNQUALIFIED_NAME (1 << 11)
+#define TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS (1 << 12)
+#define TFF_NO_TEMPLATE_BINDINGS (1 << 13)
+
+/* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
+ node. */
+#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL(NODE) \
+ ((TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM) \
+ ? TYPE_TI_TEMPLATE (NODE) \
+ : TYPE_NAME (NODE))
+
+/* in lex.c */
+
+extern void init_reswords (void);
+
+typedef struct GTY(()) operator_name_info_t {
+ /* The IDENTIFIER_NODE for the operator. */
+ tree identifier;
+ /* The name of the operator. */
+ const char *name;
+ /* The mangled name of the operator. */
+ const char *mangled_name;
+ /* The arity of the operator. */
+ int arity;
+} operator_name_info_t;
+
+/* A mapping from tree codes to operator name information. */
+extern GTY(()) operator_name_info_t operator_name_info
+ [(int) MAX_TREE_CODES];
+/* Similar, but for assignment operators. */
+extern GTY(()) operator_name_info_t assignment_operator_name_info
+ [(int) MAX_TREE_CODES];
+
+/* A type-qualifier, or bitmask therefore, using the TYPE_QUAL
+ constants. */
+
+typedef int cp_cv_quals;
+
+/* Non-static member functions have an optional virt-specifier-seq.
+ There is a VIRT_SPEC value for each virt-specifier.
+ They can be combined by bitwise-or to form the complete set of
+ virt-specifiers for a member function. */
+enum virt_specifier
+ {
+ VIRT_SPEC_UNSPECIFIED = 0x0,
+ VIRT_SPEC_FINAL = 0x1,
+ VIRT_SPEC_OVERRIDE = 0x2
+ };
+
+/* A type-qualifier, or bitmask therefore, using the VIRT_SPEC
+ constants. */
+
+typedef int cp_virt_specifiers;
+
+/* Wherever there is a function-cv-qual, there could also be a ref-qualifier:
+
+ [dcl.fct]
+ The return type, the parameter-type-list, the ref-qualifier, and
+ the cv-qualifier-seq, but not the default arguments or the exception
+ specification, are part of the function type.
+
+ REF_QUAL_NONE Ordinary member function with no ref-qualifier
+ REF_QUAL_LVALUE Member function with the &-ref-qualifier
+ REF_QUAL_RVALUE Member function with the &&-ref-qualifier */
+
+enum cp_ref_qualifier {
+ REF_QUAL_NONE = 0,
+ REF_QUAL_LVALUE = 1,
+ REF_QUAL_RVALUE = 2
+};
+
+/* A storage class. */
+
+typedef enum cp_storage_class {
+ /* sc_none must be zero so that zeroing a cp_decl_specifier_seq
+ sets the storage_class field to sc_none. */
+ sc_none = 0,
+ sc_auto,
+ sc_register,
+ sc_static,
+ sc_extern,
+ sc_mutable
+} cp_storage_class;
+
+/* An individual decl-specifier. This is used to index the array of
+ locations for the declspecs in struct cp_decl_specifier_seq
+ below. */
+
+typedef enum cp_decl_spec {
+ ds_first,
+ ds_signed = ds_first,
+ ds_unsigned,
+ ds_short,
+ ds_long,
+ ds_const,
+ ds_volatile,
+ ds_restrict,
+ ds_inline,
+ ds_virtual,
+ ds_explicit,
+ ds_friend,
+ ds_typedef,
+ ds_alias,
+ ds_constexpr,
+ ds_complex,
+ ds_thread,
+ ds_type_spec,
+ ds_redefined_builtin_type_spec,
+ ds_attribute,
+ ds_std_attribute,
+ ds_storage_class,
+ ds_long_long,
+ ds_last /* This enumerator must always be the last one. */
+} cp_decl_spec;
+
+/* A decl-specifier-seq. */
+
+typedef struct cp_decl_specifier_seq {
+ /* An array of locations for the declaration sepecifiers, indexed by
+ enum cp_decl_spec_word. */
+ source_location locations[ds_last];
+ /* The primary type, if any, given by the decl-specifier-seq.
+ Modifiers, like "short", "const", and "unsigned" are not
+ reflected here. This field will be a TYPE, unless a typedef-name
+ was used, in which case it will be a TYPE_DECL. */
+ tree type;
+ /* The attributes, if any, provided with the specifier sequence. */
+ tree attributes;
+ /* The c++11 attributes that follows the type specifier. */
+ tree std_attributes;
+ /* If non-NULL, a built-in type that the user attempted to redefine
+ to some other type. */
+ tree redefined_builtin_type;
+ /* The storage class specified -- or sc_none if no storage class was
+ explicitly specified. */
+ cp_storage_class storage_class;
+ /* True iff TYPE_SPEC defines a class or enum. */
+ BOOL_BITFIELD type_definition_p : 1;
+ /* True iff multiple types were (erroneously) specified for this
+ decl-specifier-seq. */
+ BOOL_BITFIELD multiple_types_p : 1;
+ /* True iff multiple storage classes were (erroneously) specified
+ for this decl-specifier-seq or a combination of a storage class
+ with a typedef specifier. */
+ BOOL_BITFIELD conflicting_specifiers_p : 1;
+ /* True iff at least one decl-specifier was found. */
+ BOOL_BITFIELD any_specifiers_p : 1;
+ /* True iff at least one type-specifier was found. */
+ BOOL_BITFIELD any_type_specifiers_p : 1;
+ /* True iff "int" was explicitly provided. */
+ BOOL_BITFIELD explicit_int_p : 1;
+ /* True iff "__int128" was explicitly provided. */
+ BOOL_BITFIELD explicit_int128_p : 1;
+ /* True iff "char" was explicitly provided. */
+ BOOL_BITFIELD explicit_char_p : 1;
+ /* True iff ds_thread is set for __thread, not thread_local. */
+ BOOL_BITFIELD gnu_thread_keyword_p : 1;
+} cp_decl_specifier_seq;
+
+/* The various kinds of declarators. */
+
+typedef enum cp_declarator_kind {
+ cdk_id,
+ cdk_function,
+ cdk_array,
+ cdk_pointer,
+ cdk_reference,
+ cdk_ptrmem,
+ cdk_error
+} cp_declarator_kind;
+
+/* A declarator. */
+
+typedef struct cp_declarator cp_declarator;
+
+typedef struct cp_parameter_declarator cp_parameter_declarator;
+
+/* A parameter, before it has been semantically analyzed. */
+struct cp_parameter_declarator {
+ /* The next parameter, or NULL_TREE if none. */
+ cp_parameter_declarator *next;
+ /* The decl-specifiers-seq for the parameter. */
+ cp_decl_specifier_seq decl_specifiers;
+ /* The declarator for the parameter. */
+ cp_declarator *declarator;
+ /* The default-argument expression, or NULL_TREE, if none. */
+ tree default_argument;
+ /* True iff this is the first parameter in the list and the
+ parameter sequence ends with an ellipsis. */
+ bool ellipsis_p;
+};
+
+/* A declarator. */
+struct cp_declarator {
+ /* The kind of declarator. */
+ ENUM_BITFIELD (cp_declarator_kind) kind : 4;
+ /* Whether we parsed an ellipsis (`...') just before the declarator,
+ to indicate this is a parameter pack. */
+ BOOL_BITFIELD parameter_pack_p : 1;
+ location_t id_loc; /* Currently only set for cdk_id and cdk_function. */
+ /* GNU Attributes that apply to this declarator. If the declarator
+ is a pointer or a reference, these attribute apply to the type
+ pointed to. */
+ tree attributes;
+ /* Standard C++11 attributes that apply to this declarator. If the
+ declarator is a pointer or a reference, these attributes apply
+ to the pointer, rather than to the type pointed to. */
+ tree std_attributes;
+ /* For all but cdk_id and cdk_error, the contained declarator. For
+ cdk_id and cdk_error, guaranteed to be NULL. */
+ cp_declarator *declarator;
+ union {
+ /* For identifiers. */
+ struct {
+ /* If non-NULL, the qualifying scope (a NAMESPACE_DECL or
+ *_TYPE) for this identifier. */
+ tree qualifying_scope;
+ /* The unqualified name of the entity -- an IDENTIFIER_NODE,
+ BIT_NOT_EXPR, or TEMPLATE_ID_EXPR. */
+ tree unqualified_name;
+ /* If this is the name of a function, what kind of special
+ function (if any). */
+ special_function_kind sfk;
+ } id;
+ /* For functions. */
+ struct {
+ /* The parameters to the function as a TREE_LIST of decl/default. */
+ tree parameters;
+ /* The cv-qualifiers for the function. */
+ cp_cv_quals qualifiers;
+ /* The virt-specifiers for the function. */
+ cp_virt_specifiers virt_specifiers;
+ /* The ref-qualifier for the function. */
+ cp_ref_qualifier ref_qualifier;
+ /* The exception-specification for the function. */
+ tree exception_specification;
+ /* The late-specified return type, if any. */
+ tree late_return_type;
+ } function;
+ /* For arrays. */
+ struct {
+ /* The bounds to the array. */
+ tree bounds;
+ } array;
+ /* For cdk_pointer and cdk_ptrmem. */
+ struct {
+ /* The cv-qualifiers for the pointer. */
+ cp_cv_quals qualifiers;
+ /* For cdk_ptrmem, the class type containing the member. */
+ tree class_type;
+ } pointer;
+ /* For cdk_reference */
+ struct {
+ /* The cv-qualifiers for the reference. These qualifiers are
+ only used to diagnose ill-formed code. */
+ cp_cv_quals qualifiers;
+ /* Whether this is an rvalue reference */
+ bool rvalue_ref;
+ } reference;
+ } u;
+};
+
+/* A level of template instantiation. */
+struct GTY((chain_next ("%h.next"))) tinst_level {
+ /* The immediately deeper level in the chain. */
+ struct tinst_level *next;
+
+ /* The original node. Can be either a DECL (for a function or static
+ data member) or a TYPE (for a class), depending on what we were
+ asked to instantiate. */
+ tree decl;
+
+ /* The location where the template is instantiated. */
+ location_t locus;
+
+ /* errorcount+sorrycount when we pushed this level. */
+ int errors;
+
+ /* True if the location is in a system header. */
+ bool in_system_header_p;
+};
+
+bool decl_spec_seq_has_spec_p (const cp_decl_specifier_seq *, cp_decl_spec);
+
+/* Return the type of the `this' parameter of FNTYPE. */
+
+inline tree
+type_of_this_parm (const_tree fntype)
+{
+ function_args_iterator iter;
+ gcc_assert (TREE_CODE (fntype) == METHOD_TYPE);
+ function_args_iter_init (&iter, fntype);
+ return function_args_iter_cond (&iter);
+}
+
+/* Return the class of the `this' parameter of FNTYPE. */
+
+inline tree
+class_of_this_parm (const_tree fntype)
+{
+ return TREE_TYPE (type_of_this_parm (fntype));
+}
+
+/* A parameter list indicating for a function with no parameters,
+ e.g "int f(void)". */
+extern cp_parameter_declarator *no_parameters;
+
+/* True if we saw "#pragma GCC java_exceptions". */
+extern bool pragma_java_exceptions;
+
+/* in call.c */
+extern bool check_dtor_name (tree, tree);
+bool magic_varargs_p (tree);
+
+extern tree build_conditional_expr (location_t, tree, tree, tree,
+ tsubst_flags_t);
+extern tree build_addr_func (tree, tsubst_flags_t);
+extern void set_flags_from_callee (tree);
+extern tree build_call_a (tree, int, tree*);
+extern tree build_call_n (tree, int, ...);
+extern bool null_ptr_cst_p (tree);
+extern bool null_member_pointer_value_p (tree);
+extern bool sufficient_parms_p (const_tree);
+extern tree type_decays_to (tree);
+extern tree build_user_type_conversion (tree, tree, int,
+ tsubst_flags_t);
+extern tree build_new_function_call (tree, vec<tree, va_gc> **, bool,
+ tsubst_flags_t);
+extern tree build_operator_new_call (tree, vec<tree, va_gc> **, tree *,
+ tree *, tree, tree *,
+ tsubst_flags_t);
+extern tree build_new_method_call (tree, tree, vec<tree, va_gc> **,
+ tree, int, tree *,
+ tsubst_flags_t);
+extern tree build_special_member_call (tree, tree, vec<tree, va_gc> **,
+ tree, int, tsubst_flags_t);
+extern tree build_new_op (location_t, enum tree_code,
+ int, tree, tree, tree, tree *,
+ tsubst_flags_t);
+extern tree build_op_call (tree, vec<tree, va_gc> **,
+ tsubst_flags_t);
+extern tree build_op_delete_call (enum tree_code, tree, tree,
+ bool, tree, tree,
+ tsubst_flags_t);
+extern bool can_convert (tree, tree, tsubst_flags_t);
+extern bool can_convert_standard (tree, tree, tsubst_flags_t);
+extern bool can_convert_arg (tree, tree, tree, int,
+ tsubst_flags_t);
+extern bool can_convert_arg_bad (tree, tree, tree, int,
+ tsubst_flags_t);
+extern bool enforce_access (tree, tree, tree,
+ tsubst_flags_t);
+extern void push_defarg_context (tree);
+extern void pop_defarg_context (void);
+extern tree convert_default_arg (tree, tree, tree, int,
+ tsubst_flags_t);
+extern tree convert_arg_to_ellipsis (tree, tsubst_flags_t);
+extern tree build_x_va_arg (source_location, tree, tree);
+extern tree cxx_type_promotes_to (tree);
+extern tree type_passed_as (tree);
+extern tree convert_for_arg_passing (tree, tree, tsubst_flags_t);
+extern bool is_properly_derived_from (tree, tree);
+extern tree initialize_reference (tree, tree, int,
+ tsubst_flags_t);
+extern tree extend_ref_init_temps (tree, tree, vec<tree, va_gc>**);
+extern tree make_temporary_var_for_ref_to_temp (tree, tree);
+extern bool type_has_extended_temps (tree);
+extern tree strip_top_quals (tree);
+extern bool reference_related_p (tree, tree);
+extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t);
+extern tree perform_implicit_conversion_flags (tree, tree, tsubst_flags_t, int);
+extern tree build_integral_nontype_arg_conv (tree, tree, tsubst_flags_t);
+extern tree perform_direct_initialization_if_possible (tree, tree, bool,
+ tsubst_flags_t);
+extern tree in_charge_arg_for_name (tree);
+extern tree build_cxx_call (tree, int, tree *,
+ tsubst_flags_t);
+extern bool is_std_init_list (tree);
+extern bool is_list_ctor (tree);
+#ifdef ENABLE_CHECKING
+extern void validate_conversion_obstack (void);
+#endif /* ENABLE_CHECKING */
+extern void mark_versions_used (tree);
+extern tree get_function_version_dispatcher (tree);
+
+/* in class.c */
+extern tree build_vfield_ref (tree, tree);
+extern tree build_base_path (enum tree_code, tree,
+ tree, int, tsubst_flags_t);
+extern tree convert_to_base (tree, tree, bool, bool,
+ tsubst_flags_t);
+extern tree convert_to_base_statically (tree, tree);
+extern tree build_vtbl_ref (tree, tree);
+extern tree build_vfn_ref (tree, tree);
+extern tree get_vtable_decl (tree, int);
+extern void resort_type_method_vec (void *, void *,
+ gt_pointer_operator, void *);
+extern bool add_method (tree, tree, tree);
+extern bool currently_open_class (tree);
+extern tree currently_open_derived_class (tree);
+extern tree current_nonlambda_class_type (void);
+extern tree finish_struct (tree, tree);
+extern void finish_struct_1 (tree);
+extern int resolves_to_fixed_type_p (tree, int *);
+extern void init_class_processing (void);
+extern int is_empty_class (tree);
+extern bool is_really_empty_class (tree);
+extern void pushclass (tree);
+extern void popclass (void);
+extern void push_nested_class (tree);
+extern void pop_nested_class (void);
+extern int current_lang_depth (void);
+extern void push_lang_context (tree);
+extern void pop_lang_context (void);
+extern tree instantiate_type (tree, tree, tsubst_flags_t);
+extern void print_class_statistics (void);
+extern void build_self_reference (void);
+extern int same_signature_p (const_tree, const_tree);
+extern void maybe_add_class_template_decl_list (tree, tree, int);
+extern void unreverse_member_declarations (tree);
+extern void invalidate_class_lookup_cache (void);
+extern void maybe_note_name_used_in_class (tree, tree);
+extern void note_name_declared_in_class (tree, tree);
+extern tree get_vtbl_decl_for_binfo (tree);
+extern void debug_class (tree);
+extern void debug_thunks (tree);
+extern void set_linkage_according_to_type (tree, tree);
+extern void determine_key_method (tree);
+extern void check_for_override (tree, tree);
+extern void push_class_stack (void);
+extern void pop_class_stack (void);
+extern bool type_has_user_nondefault_constructor (tree);
+extern tree in_class_defaulted_default_constructor (tree);
+extern bool user_provided_p (tree);
+extern bool type_has_user_provided_constructor (tree);
+extern bool type_has_user_provided_default_constructor (tree);
+extern bool vbase_has_user_provided_move_assign (tree);
+extern tree default_init_uninitialized_part (tree);
+extern bool trivial_default_constructor_is_constexpr (tree);
+extern bool type_has_constexpr_default_constructor (tree);
+extern bool type_has_virtual_destructor (tree);
+extern bool type_has_move_constructor (tree);
+extern bool type_has_move_assign (tree);
+extern bool type_has_user_declared_move_constructor (tree);
+extern bool type_has_user_declared_move_assign(tree);
+extern bool type_build_ctor_call (tree);
+extern bool type_build_dtor_call (tree);
+extern void explain_non_literal_class (tree);
+extern void defaulted_late_check (tree);
+extern bool defaultable_fn_check (tree);
+extern void fixup_type_variants (tree);
+extern void fixup_attribute_variants (tree);
+extern tree* decl_cloned_function_p (const_tree, bool);
+extern void clone_function_decl (tree, int);
+extern void adjust_clone_args (tree);
+extern void deduce_noexcept_on_destructor (tree);
+extern void insert_late_enum_def_into_classtype_sorted_fields (tree, tree);
+extern bool uniquely_derived_from_p (tree, tree);
+extern bool publicly_uniquely_derived_p (tree, tree);
+extern tree common_enclosing_class (tree, tree);
+
+/* in cvt.c */
+extern tree convert_to_reference (tree, tree, int, int, tree,
+ tsubst_flags_t);
+extern tree convert_from_reference (tree);
+extern tree force_rvalue (tree, tsubst_flags_t);
+extern tree ocp_convert (tree, tree, int, int,
+ tsubst_flags_t);
+extern tree cp_convert (tree, tree, tsubst_flags_t);
+extern tree cp_convert_and_check (tree, tree, tsubst_flags_t);
+extern tree cp_fold_convert (tree, tree);
+extern tree convert_to_void (tree, impl_conv_void,
+ tsubst_flags_t);
+extern tree convert_force (tree, tree, int,
+ tsubst_flags_t);
+extern tree build_expr_type_conversion (int, tree, bool);
+extern tree type_promotes_to (tree);
+extern tree perform_qualification_conversions (tree, tree);
+
+/* in name-lookup.c */
+extern tree pushdecl (tree);
+extern tree pushdecl_maybe_friend (tree, bool);
+extern void maybe_push_cleanup_level (tree);
+extern tree pushtag (tree, tree, tag_scope);
+extern tree make_anon_name (void);
+extern tree pushdecl_top_level_maybe_friend (tree, bool);
+extern tree pushdecl_top_level_and_finish (tree, tree);
+extern tree check_for_out_of_scope_variable (tree);
+extern void dump (cp_binding_level &ref);
+extern void dump (cp_binding_level *ptr);
+extern void print_other_binding_stack (cp_binding_level *);
+extern tree maybe_push_decl (tree);
+extern tree current_decl_namespace (void);
+
+/* decl.c */
+extern tree poplevel (int, int, int);
+extern void cxx_init_decl_processing (void);
+enum cp_tree_node_structure_enum cp_tree_node_structure
+ (union lang_tree_node *);
+extern void finish_scope (void);
+extern void push_switch (tree);
+extern void pop_switch (void);
+extern tree make_lambda_name (void);
+extern int decls_match (tree, tree);
+extern tree duplicate_decls (tree, tree, bool);
+extern tree declare_local_label (tree);
+extern tree define_label (location_t, tree);
+extern void check_goto (tree);
+extern bool check_omp_return (void);
+extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t);
+extern tree make_unbound_class_template (tree, tree, tree, tsubst_flags_t);
+extern tree build_library_fn_ptr (const char *, tree, int);
+extern tree build_cp_library_fn_ptr (const char *, tree, int);
+extern tree push_library_fn (tree, tree, tree, int);
+extern tree push_void_library_fn (tree, tree, int);
+extern tree push_throw_library_fn (tree, tree);
+extern void warn_misplaced_attr_for_class_type (source_location location,
+ tree class_type);
+extern tree check_tag_decl (cp_decl_specifier_seq *, bool);
+extern tree shadow_tag (cp_decl_specifier_seq *);
+extern tree groktypename (cp_decl_specifier_seq *, const cp_declarator *, bool);
+extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int, tree, tree, tree *);
+extern void start_decl_1 (tree, bool);
+extern bool check_array_initializer (tree, tree, tree);
+extern void cp_finish_decl (tree, tree, bool, tree, int);
+extern int cp_complete_array_type (tree *, tree, bool);
+extern int cp_complete_array_type_or_error (tree *, tree, bool, tsubst_flags_t);
+extern tree build_ptrmemfunc_type (tree);
+extern tree build_ptrmem_type (tree, tree);
+/* the grokdeclarator prototype is in decl.h */
+extern tree build_this_parm (tree, cp_cv_quals);
+extern int copy_fn_p (const_tree);
+extern bool move_fn_p (const_tree);
+extern bool move_signature_fn_p (const_tree);
+extern tree get_scope_of_declarator (const cp_declarator *);
+extern void grok_special_member_properties (tree);
+extern int grok_ctor_properties (const_tree, const_tree);
+extern bool grok_op_properties (tree, bool);
+extern tree xref_tag (enum tag_types, tree, tag_scope, bool);
+extern tree xref_tag_from_type (tree, tree, tag_scope);
+extern bool xref_basetypes (tree, tree);
+extern tree start_enum (tree, tree, tree, bool, bool *);
+extern void finish_enum_value_list (tree);
+extern void finish_enum (tree);
+extern void build_enumerator (tree, tree, tree, location_t);
+extern tree lookup_enumerator (tree, tree);
+extern bool start_preparsed_function (tree, tree, int);
+extern bool start_function (cp_decl_specifier_seq *,
+ const cp_declarator *, tree);
+extern tree begin_function_body (void);
+extern void finish_function_body (tree);
+extern tree outer_curly_brace_block (tree);
+extern tree finish_function (int);
+extern tree grokmethod (cp_decl_specifier_seq *, const cp_declarator *, tree);
+extern void maybe_register_incomplete_var (tree);
+extern void maybe_commonize_var (tree);
+extern void complete_vars (tree);
+extern tree static_fn_type (tree);
+extern void revert_static_member_fn (tree);
+extern void fixup_anonymous_aggr (tree);
+extern tree compute_array_index_type (tree, tree, tsubst_flags_t);
+extern tree check_default_argument (tree, tree, tsubst_flags_t);
+typedef int (*walk_namespaces_fn) (tree, void *);
+extern int walk_namespaces (walk_namespaces_fn,
+ void *);
+extern int wrapup_globals_for_namespace (tree, void *);
+extern tree create_implicit_typedef (tree, tree);
+extern int local_variable_p (const_tree);
+extern tree register_dtor_fn (tree);
+extern tmpl_spec_kind current_tmpl_spec_kind (int);
+extern tree cp_fname_init (const char *, tree *);
+extern tree cxx_builtin_function (tree decl);
+extern tree cxx_builtin_function_ext_scope (tree decl);
+extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
+extern void warn_extern_redeclared_static (tree, tree);
+extern tree cxx_comdat_group (tree);
+extern bool cp_missing_noreturn_ok_p (tree);
+extern void initialize_artificial_var (tree, vec<constructor_elt, va_gc> *);
+extern tree check_var_type (tree, tree);
+extern tree reshape_init (tree, tree, tsubst_flags_t);
+extern tree next_initializable_field (tree);
+extern tree fndecl_declared_return_type (tree);
+extern bool undeduced_auto_decl (tree);
+extern void require_deduced_type (tree);
+
+extern bool defer_mark_used_calls;
+extern GTY(()) vec<tree, va_gc> *deferred_mark_used_calls;
+extern tree finish_case_label (location_t, tree, tree);
+extern tree cxx_maybe_build_cleanup (tree, tsubst_flags_t);
+
+/* in decl2.c */
+extern bool check_java_method (tree);
+extern tree build_memfn_type (tree, tree, cp_cv_quals, cp_ref_qualifier);
+extern tree build_pointer_ptrmemfn_type (tree);
+extern tree change_return_type (tree, tree);
+extern void maybe_retrofit_in_chrg (tree);
+extern void maybe_make_one_only (tree);
+extern bool vague_linkage_p (tree);
+extern void grokclassfn (tree, tree,
+ enum overload_flags);
+extern tree grok_array_decl (location_t, tree, tree, bool);
+extern tree delete_sanity (tree, tree, bool, int, tsubst_flags_t);
+extern tree check_classfn (tree, tree, tree);
+extern void check_member_template (tree);
+extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *,
+ tree, bool, tree, tree);
+extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *,
+ tree, tree);
+extern tree cp_reconstruct_complex_type (tree, tree);
+extern bool attributes_naming_typedef_ok (tree);
+extern void cplus_decl_attributes (tree *, tree, int);
+extern void finish_anon_union (tree);
+extern void cp_write_global_declarations (void);
+extern tree coerce_new_type (tree);
+extern tree coerce_delete_type (tree);
+extern void comdat_linkage (tree);
+extern void determine_visibility (tree);
+extern void constrain_class_visibility (tree);
+extern void reset_type_linkage (tree);
+extern void tentative_decl_linkage (tree);
+extern void import_export_decl (tree);
+extern tree build_cleanup (tree);
+extern tree build_offset_ref_call_from_tree (tree, vec<tree, va_gc> **,
+ tsubst_flags_t);
+extern bool decl_constant_var_p (tree);
+extern bool decl_maybe_constant_var_p (tree);
+extern void no_linkage_error (tree);
+extern void check_default_args (tree);
+extern bool mark_used (tree);
+extern bool mark_used (tree, tsubst_flags_t);
+extern void finish_static_data_member_decl (tree, tree, bool, tree, int);
+extern tree cp_build_parm_decl (tree, tree);
+extern tree get_guard (tree);
+extern tree get_guard_cond (tree);
+extern tree set_guard (tree);
+extern tree get_tls_wrapper_fn (tree);
+extern void mark_needed (tree);
+extern bool decl_needed_p (tree);
+extern void note_vague_linkage_fn (tree);
+extern tree build_artificial_parm (tree, tree);
+extern bool possibly_inlined_p (tree);
+extern int parm_index (tree);
+extern tree vtv_start_verification_constructor_init_function (void);
+extern tree vtv_finish_verification_constructor_init_function (tree);
+extern bool cp_omp_mappable_type (tree);
+
+/* in error.c */
+extern void init_error (void);
+extern const char *type_as_string (tree, int);
+extern const char *type_as_string_translate (tree, int);
+extern const char *decl_as_string (tree, int);
+extern const char *decl_as_string_translate (tree, int);
+extern const char *decl_as_dwarf_string (tree, int);
+extern const char *expr_as_string (tree, int);
+extern const char *lang_decl_name (tree, int, bool);
+extern const char *lang_decl_dwarf_name (tree, int, bool);
+extern const char *language_to_string (enum languages);
+extern const char *class_key_or_enum_as_string (tree);
+extern void print_instantiation_context (void);
+extern void maybe_warn_variadic_templates (void);
+extern void maybe_warn_cpp0x (cpp0x_warn_str str);
+extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
+extern location_t location_of (tree);
+extern void qualified_name_lookup_error (tree, tree, tree,
+ location_t);
+
+/* in except.c */
+extern void init_exception_processing (void);
+extern tree expand_start_catch_block (tree);
+extern void expand_end_catch_block (void);
+extern tree build_exc_ptr (void);
+extern tree build_throw (tree);
+extern int nothrow_libfn_p (const_tree);
+extern void check_handlers (tree);
+extern tree finish_noexcept_expr (tree, tsubst_flags_t);
+extern bool expr_noexcept_p (tree, tsubst_flags_t);
+extern void perform_deferred_noexcept_checks (void);
+extern bool nothrow_spec_p (const_tree);
+extern bool type_noexcept_p (const_tree);
+extern bool type_throw_all_p (const_tree);
+extern tree build_noexcept_spec (tree, int);
+extern void choose_personality_routine (enum languages);
+extern tree build_must_not_throw_expr (tree,tree);
+extern tree eh_type_info (tree);
+extern tree begin_eh_spec_block (void);
+extern void finish_eh_spec_block (tree, tree);
+extern tree build_eh_type_type (tree);
+extern tree cp_protect_cleanup_actions (void);
+extern tree create_try_catch_expr (tree, tree);
+
+/* in expr.c */
+extern tree cplus_expand_constant (tree);
+extern tree mark_rvalue_use (tree);
+extern tree mark_lvalue_use (tree);
+extern tree mark_type_use (tree);
+extern void mark_exp_read (tree);
+
+/* friend.c */
+extern int is_friend (tree, tree);
+extern void make_friend_class (tree, tree, bool);
+extern void add_friend (tree, tree, bool);
+extern tree do_friend (tree, tree, tree, tree, enum overload_flags, bool);
+
+/* in init.c */
+extern tree expand_member_init (tree);
+extern void emit_mem_initializers (tree);
+extern tree build_aggr_init (tree, tree, int,
+ tsubst_flags_t);
+extern int is_class_type (tree, int);
+extern tree get_type_value (tree);
+extern tree build_zero_init (tree, tree, bool);
+extern tree build_value_init (tree, tsubst_flags_t);
+extern tree build_value_init_noctor (tree, tsubst_flags_t);
+extern tree build_offset_ref (tree, tree, bool,
+ tsubst_flags_t);
+extern tree throw_bad_array_new_length (void);
+extern tree throw_bad_array_length (void);
+extern tree build_new (vec<tree, va_gc> **, tree, tree,
+ vec<tree, va_gc> **, int,
+ tsubst_flags_t);
+extern tree get_temp_regvar (tree, tree);
+extern tree build_vec_init (tree, tree, tree, bool, int,
+ tsubst_flags_t);
+extern tree build_delete (tree, tree,
+ special_function_kind,
+ int, int, tsubst_flags_t);
+extern void push_base_cleanups (void);
+extern tree build_vec_delete (tree, tree,
+ special_function_kind, int,
+ tsubst_flags_t);
+extern tree create_temporary_var (tree);
+extern void initialize_vtbl_ptrs (tree);
+extern tree build_java_class_ref (tree);
+extern tree integral_constant_value (tree);
+extern tree decl_constant_value_safe (tree);
+extern int diagnose_uninitialized_cst_or_ref_member (tree, bool, bool);
+extern tree build_vtbl_address (tree);
+
+/* in lex.c */
+extern void cxx_dup_lang_specific_decl (tree);
+extern void yyungetc (int, int);
+
+extern tree unqualified_name_lookup_error (tree);
+extern tree unqualified_fn_lookup_error (tree);
+extern tree build_lang_decl (enum tree_code, tree, tree);
+extern tree build_lang_decl_loc (location_t, enum tree_code, tree, tree);
+extern void retrofit_lang_decl (tree);
+extern tree copy_decl (tree);
+extern tree copy_type (tree);
+extern tree cxx_make_type (enum tree_code);
+extern tree make_class_type (enum tree_code);
+extern bool cxx_init (void);
+extern void cxx_finish (void);
+extern bool in_main_input_context (void);
+
+/* in method.c */
+extern void init_method (void);
+extern tree make_thunk (tree, bool, tree, tree);
+extern void finish_thunk (tree);
+extern void use_thunk (tree, bool);
+extern bool trivial_fn_p (tree);
+extern bool maybe_explain_implicit_delete (tree);
+extern void explain_implicit_non_constexpr (tree);
+extern void deduce_inheriting_ctor (tree);
+extern void synthesize_method (tree);
+extern tree lazily_declare_fn (special_function_kind,
+ tree);
+extern tree skip_artificial_parms_for (const_tree, tree);
+extern int num_artificial_parms_for (const_tree);
+extern tree make_alias_for (tree, tree);
+extern tree get_copy_ctor (tree, tsubst_flags_t);
+extern tree get_copy_assign (tree);
+extern tree get_default_ctor (tree);
+extern tree get_dtor (tree, tsubst_flags_t);
+extern tree get_inherited_ctor (tree);
+extern tree locate_ctor (tree);
+extern tree implicitly_declare_fn (special_function_kind, tree,
+ bool, tree, tree);
+
+/* In optimize.c */
+extern bool maybe_clone_body (tree);
+
+/* in pt.c */
+extern bool check_template_shadow (tree);
+extern tree get_innermost_template_args (tree, int);
+extern void maybe_begin_member_template_processing (tree);
+extern void maybe_end_member_template_processing (void);
+extern tree finish_member_template_decl (tree);
+extern void begin_template_parm_list (void);
+extern bool begin_specialization (void);
+extern void reset_specialization (void);
+extern void end_specialization (void);
+extern void begin_explicit_instantiation (void);
+extern void end_explicit_instantiation (void);
+extern tree check_explicit_specialization (tree, tree, int, int);
+extern int num_template_headers_for_class (tree);
+extern void check_template_variable (tree);
+extern tree make_auto (void);
+extern tree make_decltype_auto (void);
+extern tree do_auto_deduction (tree, tree, tree);
+extern tree type_uses_auto (tree);
+extern tree type_uses_auto_or_concept (tree);
+extern void append_type_to_template_for_access_check (tree, tree, tree,
+ location_t);
+extern tree convert_generic_types_to_packs (tree, int, int);
+extern tree splice_late_return_type (tree, tree);
+extern bool is_auto (const_tree);
+extern bool is_auto_or_concept (const_tree);
+extern tree process_template_parm (tree, location_t, tree,
+ bool, bool);
+extern tree end_template_parm_list (tree);
+extern void end_template_decl (void);
+extern tree maybe_update_decl_type (tree, tree);
+extern bool check_default_tmpl_args (tree, tree, bool, bool, int);
+extern tree push_template_decl (tree);
+extern tree push_template_decl_real (tree, bool);
+extern tree add_inherited_template_parms (tree, tree);
+extern bool redeclare_class_template (tree, tree);
+extern tree lookup_template_class (tree, tree, tree, tree,
+ int, tsubst_flags_t);
+extern tree lookup_template_function (tree, tree);
+extern int uses_template_parms (tree);
+extern int uses_template_parms_level (tree, int);
+extern bool in_template_function (void);
+extern tree instantiate_class_template (tree);
+extern tree instantiate_template (tree, tree, tsubst_flags_t);
+extern tree fn_type_unification (tree, tree, tree,
+ const tree *, unsigned int,
+ tree, unification_kind_t, int,
+ bool, bool);
+extern void mark_decl_instantiated (tree, int);
+extern int more_specialized_fn (tree, tree, int);
+extern void do_decl_instantiation (tree, tree);
+extern void do_type_instantiation (tree, tree, tsubst_flags_t);
+extern bool always_instantiate_p (tree);
+extern void maybe_instantiate_noexcept (tree);
+extern tree instantiate_decl (tree, int, bool);
+extern int comp_template_parms (const_tree, const_tree);
+extern bool uses_parameter_packs (tree);
+extern bool template_parameter_pack_p (const_tree);
+extern bool function_parameter_pack_p (const_tree);
+extern bool function_parameter_expanded_from_pack_p (tree, tree);
+extern tree make_pack_expansion (tree);
+extern bool check_for_bare_parameter_packs (tree);
+extern tree build_template_info (tree, tree);
+extern tree get_template_info (const_tree);
+extern vec<qualified_typedef_usage_t, va_gc> *get_types_needing_access_check (tree);
+extern int template_class_depth (tree);
+extern int is_specialization_of (tree, tree);
+extern bool is_specialization_of_friend (tree, tree);
+extern tree get_pattern_parm (tree, tree);
+extern int comp_template_args (tree, tree);
+extern tree maybe_process_partial_specialization (tree);
+extern tree most_specialized_instantiation (tree);
+extern void print_candidates (tree);
+extern void instantiate_pending_templates (int);
+extern tree tsubst_default_argument (tree, tree, tree,
+ tsubst_flags_t);
+extern tree tsubst (tree, tree, tsubst_flags_t, tree);
+extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t,
+ tree, bool, bool);
+extern tree most_general_template (tree);
+extern tree get_mostly_instantiated_function_type (tree);
+extern int problematic_instantiation_changed (void);
+extern void record_last_problematic_instantiation (void);
+extern struct tinst_level *current_instantiation(void);
+extern tree maybe_get_template_decl_from_type_decl (tree);
+extern int processing_template_parmlist;
+extern bool dependent_type_p (tree);
+extern bool dependent_scope_p (tree);
+extern bool any_dependent_template_arguments_p (const_tree);
+extern bool dependent_template_p (tree);
+extern bool dependent_template_id_p (tree, tree);
+extern bool type_dependent_expression_p (tree);
+extern bool any_type_dependent_arguments_p (const vec<tree, va_gc> *);
+extern bool any_type_dependent_elements_p (const_tree);
+extern bool type_dependent_expression_p_push (tree);
+extern bool value_dependent_expression_p (tree);
+extern bool instantiation_dependent_expression_p (tree);
+extern bool any_value_dependent_elements_p (const_tree);
+extern bool dependent_omp_for_p (tree, tree, tree, tree);
+extern tree resolve_typename_type (tree, bool);
+extern tree template_for_substitution (tree);
+extern tree build_non_dependent_expr (tree);
+extern void make_args_non_dependent (vec<tree, va_gc> *);
+extern bool reregister_specialization (tree, tree, tree);
+extern tree fold_non_dependent_expr (tree);
+extern tree fold_non_dependent_expr_sfinae (tree, tsubst_flags_t);
+extern bool alias_type_or_template_p (tree);
+extern bool alias_template_specialization_p (const_tree);
+extern bool explicit_class_specialization_p (tree);
+extern int push_tinst_level (tree);
+extern void pop_tinst_level (void);
+extern struct tinst_level *outermost_tinst_level(void);
+extern void init_template_processing (void);
+extern void print_template_statistics (void);
+bool template_template_parameter_p (const_tree);
+bool template_type_parameter_p (const_tree);
+extern bool primary_template_instantiation_p (const_tree);
+extern tree get_primary_template_innermost_parameters (const_tree);
+extern tree get_template_parms_at_level (tree, int);
+extern tree get_template_innermost_arguments (const_tree);
+extern tree get_template_argument_pack_elems (const_tree);
+extern tree get_function_template_decl (const_tree);
+extern tree resolve_nondeduced_context (tree);
+extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
+
+/* in repo.c */
+extern void init_repo (void);
+extern int repo_emit_p (tree);
+extern bool repo_export_class_p (const_tree);
+extern void finish_repo (void);
+
+/* in rtti.c */
+/* A vector of all tinfo decls that haven't been emitted yet. */
+extern GTY(()) vec<tree, va_gc> *unemitted_tinfo_decls;
+
+extern void init_rtti_processing (void);
+extern tree build_typeid (tree, tsubst_flags_t);
+extern tree get_tinfo_decl (tree);
+extern tree get_typeid (tree, tsubst_flags_t);
+extern tree build_headof (tree);
+extern tree build_dynamic_cast (tree, tree, tsubst_flags_t);
+extern void emit_support_tinfos (void);
+extern bool emit_tinfo_decl (tree);
+
+/* in search.c */
+extern bool accessible_base_p (tree, tree, bool);
+extern tree lookup_base (tree, tree, base_access,
+ base_kind *, tsubst_flags_t);
+extern tree dcast_base_hint (tree, tree);
+extern int accessible_p (tree, tree, bool);
+extern int accessible_in_template_p (tree, tree);
+extern tree lookup_field_1 (tree, tree, bool);
+extern tree lookup_field (tree, tree, int, bool);
+extern int lookup_fnfields_1 (tree, tree);
+extern tree lookup_fnfields_slot (tree, tree);
+extern tree lookup_fnfields_slot_nolazy (tree, tree);
+extern int class_method_index_for_fn (tree, tree);
+extern tree lookup_fnfields (tree, tree, int);
+extern tree lookup_member (tree, tree, int, bool,
+ tsubst_flags_t);
+extern int look_for_overrides (tree, tree);
+extern void get_pure_virtuals (tree);
+extern void maybe_suppress_debug_info (tree);
+extern void note_debug_info_needed (tree);
+extern void print_search_statistics (void);
+extern void reinit_search_statistics (void);
+extern tree current_scope (void);
+extern int at_function_scope_p (void);
+extern bool at_class_scope_p (void);
+extern bool at_namespace_scope_p (void);
+extern tree context_for_name_lookup (tree);
+extern tree lookup_conversions (tree);
+extern tree binfo_from_vbase (tree);
+extern tree binfo_for_vbase (tree, tree);
+extern tree look_for_overrides_here (tree, tree);
+#define dfs_skip_bases ((tree)1)
+extern tree dfs_walk_all (tree, tree (*) (tree, void *),
+ tree (*) (tree, void *), void *);
+extern tree dfs_walk_once (tree, tree (*) (tree, void *),
+ tree (*) (tree, void *), void *);
+extern tree binfo_via_virtual (tree, tree);
+extern tree build_baselink (tree, tree, tree, tree);
+extern tree adjust_result_of_qualified_name_lookup
+ (tree, tree, tree);
+extern tree copied_binfo (tree, tree);
+extern tree original_binfo (tree, tree);
+extern int shared_member_p (tree);
+
+/* The representation of a deferred access check. */
+
+typedef struct GTY(()) deferred_access_check {
+ /* The base class in which the declaration is referenced. */
+ tree binfo;
+ /* The declaration whose access must be checked. */
+ tree decl;
+ /* The declaration that should be used in the error message. */
+ tree diag_decl;
+ /* The location of this access. */
+ location_t loc;
+} deferred_access_check;
+
+/* in semantics.c */
+extern void push_deferring_access_checks (deferring_kind);
+extern void resume_deferring_access_checks (void);
+extern void stop_deferring_access_checks (void);
+extern void pop_deferring_access_checks (void);
+extern vec<deferred_access_check, va_gc> *get_deferred_access_checks (void);
+extern void reopen_deferring_access_checks (vec<deferred_access_check, va_gc> *);
+extern void pop_to_parent_deferring_access_checks (void);
+extern bool perform_access_checks (vec<deferred_access_check, va_gc> *,
+ tsubst_flags_t);
+extern bool perform_deferred_access_checks (tsubst_flags_t);
+extern bool perform_or_defer_access_check (tree, tree, tree,
+ tsubst_flags_t);
+extern int stmts_are_full_exprs_p (void);
+extern void init_cp_semantics (void);
+extern tree do_poplevel (tree);
+extern void break_maybe_infinite_loop (void);
+extern void add_decl_expr (tree);
+extern tree maybe_cleanup_point_expr_void (tree);
+extern tree finish_expr_stmt (tree);
+extern tree begin_if_stmt (void);
+extern void finish_if_stmt_cond (tree, tree);
+extern tree finish_then_clause (tree);
+extern void begin_else_clause (tree);
+extern void finish_else_clause (tree);
+extern void finish_if_stmt (tree);
+extern tree begin_while_stmt (void);
+extern void finish_while_stmt_cond (tree, tree, bool);
+extern void finish_while_stmt (tree);
+extern tree begin_do_stmt (void);
+extern void finish_do_body (tree);
+extern void finish_do_stmt (tree, tree, bool);
+extern tree finish_return_stmt (tree);
+extern tree begin_for_scope (tree *);
+extern tree begin_for_stmt (tree, tree);
+extern void finish_for_init_stmt (tree);
+extern void finish_for_cond (tree, tree, bool);
+extern void finish_for_expr (tree, tree);
+extern void finish_for_stmt (tree);
+extern tree begin_range_for_stmt (tree, tree);
+extern void finish_range_for_decl (tree, tree, tree);
+extern void finish_range_for_stmt (tree);
+extern tree finish_break_stmt (void);
+extern tree finish_continue_stmt (void);
+extern tree begin_switch_stmt (void);
+extern void finish_switch_cond (tree, tree);
+extern void finish_switch_stmt (tree);
+extern tree finish_goto_stmt (tree);
+extern tree begin_try_block (void);
+extern void finish_try_block (tree);
+extern void finish_handler_sequence (tree);
+extern tree begin_function_try_block (tree *);
+extern void finish_function_try_block (tree);
+extern void finish_function_handler_sequence (tree, tree);
+extern void finish_cleanup_try_block (tree);
+extern tree begin_handler (void);
+extern void finish_handler_parms (tree, tree);
+extern void finish_handler (tree);
+extern void finish_cleanup (tree, tree);
+extern bool literal_type_p (tree);
+extern tree register_constexpr_fundef (tree, tree);
+extern bool check_constexpr_ctor_body (tree, tree);
+extern tree ensure_literal_type_for_constexpr_object (tree);
+extern bool potential_constant_expression (tree);
+extern bool potential_rvalue_constant_expression (tree);
+extern bool require_potential_constant_expression (tree);
+extern bool require_potential_rvalue_constant_expression (tree);
+extern tree cxx_constant_value (tree);
+extern tree maybe_constant_value (tree);
+extern tree maybe_constant_init (tree);
+extern bool is_sub_constant_expr (tree);
+extern bool reduced_constant_expression_p (tree);
+extern void explain_invalid_constexpr_fn (tree);
+extern vec<tree> cx_error_context (void);
+
+enum {
+ BCS_NO_SCOPE = 1,
+ BCS_TRY_BLOCK = 2,
+ BCS_FN_BODY = 4
+};
+extern tree begin_compound_stmt (unsigned int);
+
+extern void finish_compound_stmt (tree);
+extern tree finish_asm_stmt (int, tree, tree, tree, tree,
+ tree);
+extern tree finish_label_stmt (tree);
+extern void finish_label_decl (tree);
+extern tree finish_parenthesized_expr (tree);
+extern tree force_paren_expr (tree);
+extern tree finish_non_static_data_member (tree, tree, tree);
+extern tree begin_stmt_expr (void);
+extern tree finish_stmt_expr_expr (tree, tree);
+extern tree finish_stmt_expr (tree, bool);
+extern tree stmt_expr_value_expr (tree);
+bool empty_expr_stmt_p (tree);
+extern tree perform_koenig_lookup (tree, vec<tree, va_gc> *,
+ tsubst_flags_t);
+extern tree finish_call_expr (tree, vec<tree, va_gc> **, bool,
+ bool, tsubst_flags_t);
+extern tree finish_increment_expr (tree, enum tree_code);
+extern tree finish_this_expr (void);
+extern tree finish_pseudo_destructor_expr (tree, tree, tree, location_t);
+extern tree finish_unary_op_expr (location_t, enum tree_code, tree,
+ tsubst_flags_t);
+extern tree finish_compound_literal (tree, tree, tsubst_flags_t);
+extern tree finish_fname (tree);
+extern void finish_translation_unit (void);
+extern tree finish_template_type_parm (tree, tree);
+extern tree finish_template_template_parm (tree, tree);
+extern tree begin_class_definition (tree);
+extern void finish_template_decl (tree);
+extern tree finish_template_type (tree, tree, int);
+extern tree finish_base_specifier (tree, tree, bool);
+extern void finish_member_declaration (tree);
+extern tree finish_id_expression (tree, tree, tree,
+ cp_id_kind *,
+ bool, bool, bool *,
+ bool, bool, bool, bool,
+ const char **,
+ location_t);
+extern tree finish_typeof (tree);
+extern tree finish_underlying_type (tree);
+extern tree calculate_bases (tree);
+extern tree finish_bases (tree, bool);
+extern tree calculate_direct_bases (tree);
+extern tree finish_offsetof (tree);
+extern void finish_decl_cleanup (tree, tree);
+extern void finish_eh_cleanup (tree);
+extern void emit_associated_thunks (tree);
+extern void finish_mem_initializers (tree);
+extern tree check_template_template_default_arg (tree);
+extern bool expand_or_defer_fn_1 (tree);
+extern void expand_or_defer_fn (tree);
+extern void add_typedef_to_current_template_for_access_check (tree, tree,
+ location_t);
+extern void check_accessibility_of_qualified_id (tree, tree, tree);
+extern tree finish_qualified_id_expr (tree, tree, bool, bool,
+ bool, bool, tsubst_flags_t);
+extern void simplify_aggr_init_expr (tree *);
+extern void finalize_nrv (tree *, tree, tree);
+extern void note_decl_for_pch (tree);
+extern tree omp_reduction_id (enum tree_code, tree, tree);
+extern tree cp_remove_omp_priv_cleanup_stmt (tree *, int *, void *);
+extern void cp_check_omp_declare_reduction (tree);
+extern tree finish_omp_clauses (tree);
+extern void finish_omp_threadprivate (tree);
+extern tree begin_omp_structured_block (void);
+extern tree finish_omp_structured_block (tree);
+extern tree begin_omp_parallel (void);
+extern tree finish_omp_parallel (tree, tree);
+extern tree begin_omp_task (void);
+extern tree finish_omp_task (tree, tree);
+extern tree finish_omp_for (location_t, enum tree_code,
+ tree, tree, tree, tree, tree,
+ tree, tree);
+extern void finish_omp_atomic (enum tree_code, enum tree_code,
+ tree, tree, tree, tree, tree,
+ bool);
+extern void finish_omp_barrier (void);
+extern void finish_omp_flush (void);
+extern void finish_omp_taskwait (void);
+extern void finish_omp_taskyield (void);
+extern void finish_omp_cancel (tree);
+extern void finish_omp_cancellation_point (tree);
+extern tree begin_transaction_stmt (location_t, tree *, int);
+extern void finish_transaction_stmt (tree, tree, int, tree);
+extern tree build_transaction_expr (location_t, tree, int, tree);
+extern bool cxx_omp_create_clause_info (tree, tree, bool, bool,
+ bool, bool);
+extern tree baselink_for_fns (tree);
+extern void finish_static_assert (tree, tree, location_t,
+ bool);
+extern tree finish_decltype_type (tree, bool, tsubst_flags_t);
+extern tree finish_trait_expr (enum cp_trait_kind, tree, tree);
+extern tree build_lambda_expr (void);
+extern tree build_lambda_object (tree);
+extern tree begin_lambda_type (tree);
+extern tree lambda_capture_field_type (tree, bool);
+extern tree lambda_return_type (tree);
+extern tree lambda_proxy_type (tree);
+extern tree lambda_function (tree);
+extern void apply_deduced_return_type (tree, tree);
+extern tree add_capture (tree, tree, tree, bool, bool);
+extern tree add_default_capture (tree, tree, tree);
+extern tree build_capture_proxy (tree);
+extern void insert_capture_proxy (tree);
+extern void insert_pending_capture_proxies (void);
+extern bool is_capture_proxy (tree);
+extern bool is_normal_capture_proxy (tree);
+extern void register_capture_members (tree);
+extern tree lambda_expr_this_capture (tree);
+extern tree maybe_resolve_dummy (tree);
+extern tree nonlambda_method_basetype (void);
+extern void maybe_add_lambda_conv_op (tree);
+extern bool is_lambda_ignored_entity (tree);
+
+/* in tree.c */
+extern int cp_tree_operand_length (const_tree);
+void cp_free_lang_data (tree t);
+extern tree force_target_expr (tree, tree, tsubst_flags_t);
+extern tree build_target_expr_with_type (tree, tree, tsubst_flags_t);
+extern void lang_check_failed (const char *, int,
+ const char *) ATTRIBUTE_NORETURN;
+extern tree stabilize_expr (tree, tree *);
+extern void stabilize_call (tree, tree *);
+extern bool stabilize_init (tree, tree *);
+extern tree add_stmt_to_compound (tree, tree);
+extern void init_tree (void);
+extern bool pod_type_p (const_tree);
+extern bool layout_pod_type_p (const_tree);
+extern bool std_layout_type_p (const_tree);
+extern bool trivial_type_p (const_tree);
+extern bool trivially_copyable_p (const_tree);
+extern bool scalarish_type_p (const_tree);
+extern bool type_has_nontrivial_default_init (const_tree);
+extern bool type_has_nontrivial_copy_init (const_tree);
+extern bool class_tmpl_impl_spec_p (const_tree);
+extern int zero_init_p (const_tree);
+extern bool check_abi_tag_redeclaration (const_tree, const_tree, const_tree);
+extern tree strip_typedefs (tree);
+extern tree strip_typedefs_expr (tree);
+extern tree copy_binfo (tree, tree, tree,
+ tree *, int);
+extern int member_p (const_tree);
+extern cp_lvalue_kind real_lvalue_p (const_tree);
+extern cp_lvalue_kind lvalue_kind (const_tree);
+extern bool lvalue_or_rvalue_with_address_p (const_tree);
+extern bool xvalue_p (const_tree);
+extern bool builtin_valid_in_constant_expr_p (const_tree);
+extern tree build_min (enum tree_code, tree, ...);
+extern tree build_min_nt_loc (location_t, enum tree_code,
+ ...);
+extern tree build_min_non_dep (enum tree_code, tree, ...);
+extern tree build_min_non_dep_call_vec (tree, tree, vec<tree, va_gc> *);
+extern tree build_cplus_new (tree, tree, tsubst_flags_t);
+extern tree build_aggr_init_expr (tree, tree);
+extern tree get_target_expr (tree);
+extern tree get_target_expr_sfinae (tree, tsubst_flags_t);
+extern tree build_cplus_array_type (tree, tree);
+extern tree build_array_of_n_type (tree, int);
+extern bool array_of_runtime_bound_p (tree);
+extern tree build_array_copy (tree);
+extern tree build_vec_init_expr (tree, tree, tsubst_flags_t);
+extern void diagnose_non_constexpr_vec_init (tree);
+extern tree hash_tree_cons (tree, tree, tree);
+extern tree hash_tree_chain (tree, tree);
+extern tree build_qualified_name (tree, tree, tree, bool);
+extern tree build_ref_qualified_type (tree, cp_ref_qualifier);
+extern int is_overloaded_fn (tree);
+extern tree dependent_name (tree);
+extern tree get_fns (tree);
+extern tree get_first_fn (tree);
+extern tree ovl_cons (tree, tree);
+extern tree build_overload (tree, tree);
+extern tree ovl_scope (tree);
+extern bool non_static_member_function_p (tree);
+extern const char *cxx_printable_name (tree, int);
+extern const char *cxx_printable_name_translate (tree, int);
+extern tree build_exception_variant (tree, tree);
+extern tree bind_template_template_parm (tree, tree);
+extern tree array_type_nelts_total (tree);
+extern tree array_type_nelts_top (tree);
+extern tree break_out_target_exprs (tree);
+extern tree get_type_decl (tree);
+extern tree decl_namespace_context (tree);
+extern bool decl_anon_ns_mem_p (const_tree);
+extern tree lvalue_type (tree);
+extern tree error_type (tree);
+extern int varargs_function_p (const_tree);
+extern bool really_overloaded_fn (tree);
+extern bool cp_tree_equal (tree, tree);
+extern tree no_linkage_check (tree, bool);
+extern void debug_binfo (tree);
+extern tree build_dummy_object (tree);
+extern tree maybe_dummy_object (tree, tree *);
+extern int is_dummy_object (const_tree);
+extern const struct attribute_spec cxx_attribute_table[];
+extern tree make_ptrmem_cst (tree, tree);
+extern tree cp_build_type_attribute_variant (tree, tree);
+extern tree cp_build_reference_type (tree, bool);
+extern tree move (tree);
+extern tree cp_build_qualified_type_real (tree, int, tsubst_flags_t);
+#define cp_build_qualified_type(TYPE, QUALS) \
+ cp_build_qualified_type_real ((TYPE), (QUALS), tf_warning_or_error)
+extern bool cv_qualified_p (const_tree);
+extern tree cv_unqualified (tree);
+extern special_function_kind special_function_p (const_tree);
+extern int count_trees (tree);
+extern int char_type_p (tree);
+extern void verify_stmt_tree (tree);
+extern linkage_kind decl_linkage (tree);
+extern duration_kind decl_storage_duration (tree);
+extern tree cp_walk_subtrees (tree*, int*, walk_tree_fn,
+ void*, struct pointer_set_t*);
+#define cp_walk_tree(tp,func,data,pset) \
+ walk_tree_1 (tp, func, data, pset, cp_walk_subtrees)
+#define cp_walk_tree_without_duplicates(tp,func,data) \
+ walk_tree_without_duplicates_1 (tp, func, data, cp_walk_subtrees)
+extern tree fold_if_not_in_template (tree);
+extern tree rvalue (tree);
+extern tree convert_bitfield_to_declared_type (tree);
+extern tree cp_save_expr (tree);
+extern bool cast_valid_in_integral_constant_expression_p (tree);
+extern bool cxx_type_hash_eq (const_tree, const_tree);
+
+extern void cxx_print_statistics (void);
+extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t);
+
+/* in ptree.c */
+extern void cxx_print_xnode (FILE *, tree, int);
+extern void cxx_print_decl (FILE *, tree, int);
+extern void cxx_print_type (FILE *, tree, int);
+extern void cxx_print_identifier (FILE *, tree, int);
+extern void cxx_print_error_function (diagnostic_context *,
+ const char *,
+ struct diagnostic_info *);
+
+/* in typeck.c */
+extern bool cxx_mark_addressable (tree);
+extern int string_conv_p (const_tree, const_tree, int);
+extern tree cp_truthvalue_conversion (tree);
+extern tree condition_conversion (tree);
+extern tree require_complete_type (tree);
+extern tree require_complete_type_sfinae (tree, tsubst_flags_t);
+extern tree complete_type (tree);
+extern tree complete_type_or_else (tree, tree);
+extern tree complete_type_or_maybe_complain (tree, tree, tsubst_flags_t);
+extern int type_unknown_p (const_tree);
+enum { ce_derived, ce_normal, ce_exact };
+extern bool comp_except_specs (const_tree, const_tree, int);
+extern bool comptypes (tree, tree, int);
+extern bool same_type_ignoring_top_level_qualifiers_p (tree, tree);
+extern bool compparms (const_tree, const_tree);
+extern int comp_cv_qualification (const_tree, const_tree);
+extern int comp_cv_qual_signature (tree, tree);
+extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code, bool);
+extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool);
+extern tree cxx_alignas_expr (tree);
+extern tree cxx_sizeof_nowarn (tree);
+extern tree is_bitfield_expr_with_lowered_type (const_tree);
+extern tree unlowered_expr_type (const_tree);
+extern tree decay_conversion (tree, tsubst_flags_t);
+extern tree build_class_member_access_expr (tree, tree, tree, bool,
+ tsubst_flags_t);
+extern tree finish_class_member_access_expr (tree, tree, bool,
+ tsubst_flags_t);
+extern tree build_x_indirect_ref (location_t, tree,
+ ref_operator, tsubst_flags_t);
+extern tree cp_build_indirect_ref (tree, ref_operator,
+ tsubst_flags_t);
+extern tree build_array_ref (location_t, tree, tree);
+extern tree cp_build_array_ref (location_t, tree, tree,
+ tsubst_flags_t);
+extern tree get_member_function_from_ptrfunc (tree *, tree, tsubst_flags_t);
+extern tree cp_build_function_call (tree, tree, tsubst_flags_t);
+extern tree cp_build_function_call_nary (tree, tsubst_flags_t, ...)
+ ATTRIBUTE_SENTINEL;
+extern tree cp_build_function_call_vec (tree, vec<tree, va_gc> **,
+ tsubst_flags_t);
+extern tree build_x_binary_op (location_t,
+ enum tree_code, tree,
+ enum tree_code, tree,
+ enum tree_code, tree *,
+ tsubst_flags_t);
+extern tree build_x_array_ref (location_t, tree, tree,
+ tsubst_flags_t);
+extern tree build_x_unary_op (location_t,
+ enum tree_code, tree,
+ tsubst_flags_t);
+extern tree cp_build_addr_expr (tree, tsubst_flags_t);
+extern tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
+extern tree cp_build_unary_op (enum tree_code, tree, int,
+ tsubst_flags_t);
+extern tree unary_complex_lvalue (enum tree_code, tree);
+extern tree build_x_conditional_expr (location_t, tree, tree, tree,
+ tsubst_flags_t);
+extern tree build_x_compound_expr_from_list (tree, expr_list_kind,
+ tsubst_flags_t);
+extern tree build_x_compound_expr_from_vec (vec<tree, va_gc> *,
+ const char *, tsubst_flags_t);
+extern tree build_x_compound_expr (location_t, tree, tree,
+ tsubst_flags_t);
+extern tree build_compound_expr (location_t, tree, tree);
+extern tree cp_build_compound_expr (tree, tree, tsubst_flags_t);
+extern tree build_static_cast (tree, tree, tsubst_flags_t);
+extern tree build_reinterpret_cast (tree, tree, tsubst_flags_t);
+extern tree build_const_cast (tree, tree, tsubst_flags_t);
+extern tree build_c_cast (location_t, tree, tree);
+extern tree cp_build_c_cast (tree, tree, tsubst_flags_t);
+extern tree build_x_modify_expr (location_t, tree,
+ enum tree_code, tree,
+ tsubst_flags_t);
+extern tree cp_build_modify_expr (tree, enum tree_code, tree,
+ tsubst_flags_t);
+extern tree convert_for_initialization (tree, tree, tree, int,
+ impl_conv_rhs, tree, int,
+ tsubst_flags_t);
+extern int comp_ptr_ttypes (tree, tree);
+extern bool comp_ptr_ttypes_const (tree, tree);
+extern bool error_type_p (const_tree);
+extern bool ptr_reasonably_similar (const_tree, const_tree);
+extern tree build_ptrmemfunc (tree, tree, int, bool,
+ tsubst_flags_t);
+extern int cp_type_quals (const_tree);
+extern int type_memfn_quals (const_tree);
+extern cp_ref_qualifier type_memfn_rqual (const_tree);
+extern tree apply_memfn_quals (tree, cp_cv_quals, cp_ref_qualifier);
+extern bool cp_has_mutable_p (const_tree);
+extern bool at_least_as_qualified_p (const_tree, const_tree);
+extern void cp_apply_type_quals_to_decl (int, tree);
+extern tree build_ptrmemfunc1 (tree, tree, tree);
+extern void expand_ptrmemfunc_cst (tree, tree *, tree *);
+extern tree type_after_usual_arithmetic_conversions (tree, tree);
+extern tree common_pointer_type (tree, tree);
+extern tree composite_pointer_type (tree, tree, tree, tree,
+ composite_pointer_operation,
+ tsubst_flags_t);
+extern tree merge_types (tree, tree);
+extern tree strip_array_domain (tree);
+extern tree check_return_expr (tree, bool *);
+extern tree cp_build_binary_op (location_t,
+ enum tree_code, tree, tree,
+ tsubst_flags_t);
+extern tree build_x_vec_perm_expr (location_t,
+ tree, tree, tree,
+ tsubst_flags_t);
+#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true)
+extern tree build_simple_component_ref (tree, tree);
+extern tree build_ptrmemfunc_access_expr (tree, tree);
+extern tree build_address (tree);
+extern tree build_typed_address (tree, tree);
+extern tree build_nop (tree, tree);
+extern tree non_reference (tree);
+extern tree lookup_anon_field (tree, tree);
+extern bool invalid_nonstatic_memfn_p (tree, tsubst_flags_t);
+extern tree convert_member_func_to_ptr (tree, tree, tsubst_flags_t);
+extern tree convert_ptrmem (tree, tree, bool, bool,
+ tsubst_flags_t);
+extern int lvalue_or_else (tree, enum lvalue_use,
+ tsubst_flags_t);
+extern void check_template_keyword (tree);
+extern bool check_raw_literal_operator (const_tree decl);
+extern bool check_literal_operator_args (const_tree, bool *, bool *);
+extern void maybe_warn_about_useless_cast (tree, tree, tsubst_flags_t);
+extern tree cp_perform_integral_promotions (tree, tsubst_flags_t);
+
+/* in typeck2.c */
+extern void require_complete_eh_spec_types (tree, tree);
+extern void cxx_incomplete_type_diagnostic (const_tree, const_tree, diagnostic_t);
+#undef cxx_incomplete_type_error
+extern void cxx_incomplete_type_error (const_tree, const_tree);
+#define cxx_incomplete_type_error(V,T) \
+ (cxx_incomplete_type_diagnostic ((V), (T), DK_ERROR))
+extern tree error_not_base_type (tree, tree);
+extern tree binfo_or_else (tree, tree);
+extern void cxx_readonly_error (tree, enum lvalue_use);
+extern void complete_type_check_abstract (tree);
+extern int abstract_virtuals_error (tree, tree);
+extern int abstract_virtuals_error (abstract_class_use, tree);
+extern int abstract_virtuals_error_sfinae (tree, tree, tsubst_flags_t);
+extern int abstract_virtuals_error_sfinae (abstract_class_use, tree, tsubst_flags_t);
+
+extern tree store_init_value (tree, tree, vec<tree, va_gc>**, int);
+extern void check_narrowing (tree, tree);
+extern tree digest_init (tree, tree, tsubst_flags_t);
+extern tree digest_init_flags (tree, tree, int);
+extern tree build_scoped_ref (tree, tree, tree *);
+extern tree build_x_arrow (location_t, tree,
+ tsubst_flags_t);
+extern tree build_m_component_ref (tree, tree, tsubst_flags_t);
+extern tree build_functional_cast (tree, tree, tsubst_flags_t);
+extern tree add_exception_specifier (tree, tree, int);
+extern tree merge_exception_specifiers (tree, tree, tree);
+
+/* in mangle.c */
+extern void init_mangle (void);
+extern void mangle_decl (tree);
+extern const char *mangle_type_string (tree);
+extern tree mangle_typeinfo_for_type (tree);
+extern tree mangle_typeinfo_string_for_type (tree);
+extern tree mangle_vtbl_for_type (tree);
+extern tree mangle_vtt_for_type (tree);
+extern tree mangle_ctor_vtbl_for_type (tree, tree);
+extern tree mangle_thunk (tree, int, tree, tree);
+extern tree mangle_conv_op_name_for_type (tree);
+extern tree mangle_guard_variable (tree);
+extern tree mangle_tls_init_fn (tree);
+extern tree mangle_tls_wrapper_fn (tree);
+extern bool decl_tls_wrapper_p (tree);
+extern tree mangle_ref_init_variable (tree);
+extern char * get_mangled_vtable_map_var_name (tree);
+
+/* in dump.c */
+extern bool cp_dump_tree (void *, tree);
+
+/* In cp/cp-objcp-common.c. */
+
+extern alias_set_type cxx_get_alias_set (tree);
+extern bool cxx_warn_unused_global_decl (const_tree);
+extern size_t cp_tree_size (enum tree_code);
+extern bool cp_var_mod_type_p (tree, tree);
+extern void cxx_initialize_diagnostics (diagnostic_context *);
+extern int cxx_types_compatible_p (tree, tree);
+extern void init_shadowed_var_for_decl (void);
+extern bool cxx_block_may_fallthru (const_tree);
+
+/* in cp-gimplify.c */
+extern int cp_gimplify_expr (tree *, gimple_seq *,
+ gimple_seq *);
+extern void cp_genericize (tree);
+extern bool cxx_omp_const_qual_no_mutable (tree);
+extern enum omp_clause_default_kind cxx_omp_predetermined_sharing (tree);
+extern tree cxx_omp_clause_default_ctor (tree, tree, tree);
+extern tree cxx_omp_clause_copy_ctor (tree, tree, tree);
+extern tree cxx_omp_clause_assign_op (tree, tree, tree);
+extern tree cxx_omp_clause_dtor (tree, tree);
+extern void cxx_omp_finish_clause (tree);
+extern bool cxx_omp_privatize_by_reference (const_tree);
+
+/* in name-lookup.c */
+extern void suggest_alternatives_for (location_t, tree);
+extern tree strip_using_decl (tree);
+
+/* in vtable-class-hierarchy.c */
+extern void vtv_compute_class_hierarchy_transitive_closure (void);
+extern void vtv_generate_init_routine (void);
+extern void vtv_save_class_info (tree);
+extern void vtv_recover_class_info (void);
+extern void vtv_build_vtable_verify_fndecl (void);
+
+/* In cp-cilkplus.c. */
+extern bool cpp_validate_cilk_plus_loop (tree);
+
+/* In cp/cp-array-notations.c */
+extern tree expand_array_notation_exprs (tree);
+bool cilkplus_an_triplet_types_ok_p (location_t, tree, tree, tree,
+ tree);
+/* In c-family/cilk.c */
+extern bool cilk_valid_spawn (tree);
+
+/* -- end of C++ */
+
+#endif /* ! GCC_CP_TREE_H */
diff --git a/gcc-4.9/gcc/cp/cvt.c b/gcc-4.9/gcc/cp/cvt.c
new file mode 100644
index 000000000..e8ece0e0b
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cvt.c
@@ -0,0 +1,1774 @@
+/* Language-level data type conversion for GNU C++.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Hacked by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* This file contains the functions for converting C++ expressions
+ to different data types. The only entry point is `convert'.
+ Every language front end must have a `convert' function
+ but what kind of conversions it does will depend on the language. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stor-layout.h"
+#include "flags.h"
+#include "cp-tree.h"
+#include "intl.h"
+#include "convert.h"
+#include "decl.h"
+#include "target.h"
+
+static tree cp_convert_to_pointer (tree, tree, tsubst_flags_t);
+static tree convert_to_pointer_force (tree, tree, tsubst_flags_t);
+static tree build_type_conversion (tree, tree);
+static tree build_up_reference (tree, tree, int, tree, tsubst_flags_t);
+static void diagnose_ref_binding (location_t, tree, tree, tree);
+
+/* Change of width--truncation and extension of integers or reals--
+ is represented with NOP_EXPR. Proper functioning of many things
+ assumes that no other conversions can be NOP_EXPRs.
+
+ Conversion between integer and pointer is represented with CONVERT_EXPR.
+ Converting integer to real uses FLOAT_EXPR
+ and real to integer uses FIX_TRUNC_EXPR.
+
+ Here is a list of all the functions that assume that widening and
+ narrowing is always done with a NOP_EXPR:
+ In convert.c, convert_to_integer.
+ In c-typeck.c, build_binary_op_nodefault (boolean ops),
+ and c_common_truthvalue_conversion.
+ In expr.c: expand_expr, for operands of a MULT_EXPR.
+ In fold-const.c: fold.
+ In tree.c: get_narrower and get_unwidened.
+
+ C++: in multiple-inheritance, converting between pointers may involve
+ adjusting them by a delta stored within the class definition. */
+
+/* Subroutines of `convert'. */
+
+/* if converting pointer to pointer
+ if dealing with classes, check for derived->base or vice versa
+ else if dealing with method pointers, delegate
+ else convert blindly
+ else if converting class, pass off to build_type_conversion
+ else try C-style pointer conversion. */
+
+static tree
+cp_convert_to_pointer (tree type, tree expr, tsubst_flags_t complain)
+{
+ tree intype = TREE_TYPE (expr);
+ enum tree_code form;
+ tree rval;
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+
+ if (intype == error_mark_node)
+ return error_mark_node;
+
+ if (MAYBE_CLASS_TYPE_P (intype))
+ {
+ intype = complete_type (intype);
+ if (!COMPLETE_TYPE_P (intype))
+ {
+ if (complain & tf_error)
+ error_at (loc, "can%'t convert from incomplete type %qT to %qT",
+ intype, type);
+ return error_mark_node;
+ }
+
+ rval = build_type_conversion (type, expr);
+ if (rval)
+ {
+ if ((complain & tf_error)
+ && rval == error_mark_node)
+ error_at (loc, "conversion of %qE from %qT to %qT is ambiguous",
+ expr, intype, type);
+ return rval;
+ }
+ }
+
+ /* Handle anachronistic conversions from (::*)() to cv void* or (*)(). */
+ if (TYPE_PTR_P (type)
+ && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
+ || VOID_TYPE_P (TREE_TYPE (type))))
+ {
+ if (TYPE_PTRMEMFUNC_P (intype)
+ || TREE_CODE (intype) == METHOD_TYPE)
+ return convert_member_func_to_ptr (type, expr, complain);
+ if (TYPE_PTR_P (TREE_TYPE (expr)))
+ return build_nop (type, expr);
+ intype = TREE_TYPE (expr);
+ }
+
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ form = TREE_CODE (intype);
+
+ if (POINTER_TYPE_P (intype))
+ {
+ intype = TYPE_MAIN_VARIANT (intype);
+
+ if (TYPE_MAIN_VARIANT (type) != intype
+ && TYPE_PTR_P (type)
+ && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
+ && MAYBE_CLASS_TYPE_P (TREE_TYPE (type))
+ && MAYBE_CLASS_TYPE_P (TREE_TYPE (intype))
+ && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE)
+ {
+ enum tree_code code = PLUS_EXPR;
+ tree binfo;
+ tree intype_class;
+ tree type_class;
+ bool same_p;
+
+ intype_class = TREE_TYPE (intype);
+ type_class = TREE_TYPE (type);
+
+ same_p = same_type_p (TYPE_MAIN_VARIANT (intype_class),
+ TYPE_MAIN_VARIANT (type_class));
+ binfo = NULL_TREE;
+ /* Try derived to base conversion. */
+ if (!same_p)
+ binfo = lookup_base (intype_class, type_class, ba_check,
+ NULL, complain);
+ if (!same_p && !binfo)
+ {
+ /* Try base to derived conversion. */
+ binfo = lookup_base (type_class, intype_class, ba_check,
+ NULL, complain);
+ code = MINUS_EXPR;
+ }
+ if (binfo == error_mark_node)
+ return error_mark_node;
+ if (binfo || same_p)
+ {
+ if (binfo)
+ expr = build_base_path (code, expr, binfo, 0, complain);
+ /* Add any qualifier conversions. */
+ return build_nop (type, expr);
+ }
+ }
+
+ if (TYPE_PTRMEMFUNC_P (type))
+ {
+ if (complain & tf_error)
+ error_at (loc, "cannot convert %qE from type %qT to type %qT",
+ expr, intype, type);
+ return error_mark_node;
+ }
+
+ return build_nop (type, expr);
+ }
+ else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
+ || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
+ return convert_ptrmem (type, expr, /*allow_inverse_p=*/false,
+ /*c_cast_p=*/false, complain);
+ else if (TYPE_PTRMEMFUNC_P (intype))
+ {
+ if (!warn_pmf2ptr)
+ {
+ if (TREE_CODE (expr) == PTRMEM_CST)
+ return cp_convert_to_pointer (type, PTRMEM_CST_MEMBER (expr),
+ complain);
+ else if (TREE_CODE (expr) == OFFSET_REF)
+ {
+ tree object = TREE_OPERAND (expr, 0);
+ return get_member_function_from_ptrfunc (&object,
+ TREE_OPERAND (expr, 1),
+ complain);
+ }
+ }
+ error_at (loc, "cannot convert %qE from type %qT to type %qT",
+ expr, intype, type);
+ return error_mark_node;
+ }
+
+ if (null_ptr_cst_p (expr))
+ {
+ if (TYPE_PTRMEMFUNC_P (type))
+ return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
+ /*c_cast_p=*/false, complain);
+
+ if (complain & tf_warning)
+ maybe_warn_zero_as_null_pointer_constant (expr, loc);
+
+ /* A NULL pointer-to-data-member is represented by -1, not by
+ zero. */
+ tree val = (TYPE_PTRDATAMEM_P (type)
+ ? build_int_cst_type (type, -1)
+ : build_int_cst (type, 0));
+
+ return (TREE_SIDE_EFFECTS (expr)
+ ? build2 (COMPOUND_EXPR, type, expr, val) : val);
+ }
+ else if (TYPE_PTRMEM_P (type) && INTEGRAL_CODE_P (form))
+ {
+ if (complain & tf_error)
+ error_at (loc, "invalid conversion from %qT to %qT", intype, type);
+ return error_mark_node;
+ }
+
+ if (INTEGRAL_CODE_P (form))
+ {
+ if (TYPE_PRECISION (intype) == POINTER_SIZE)
+ return build1 (CONVERT_EXPR, type, expr);
+ expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr,
+ complain);
+ /* Modes may be different but sizes should be the same. There
+ is supposed to be some integral type that is the same width
+ as a pointer. */
+ gcc_assert (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr)))
+ == GET_MODE_SIZE (TYPE_MODE (type)));
+
+ return convert_to_pointer (type, expr);
+ }
+
+ if (type_unknown_p (expr))
+ return instantiate_type (type, expr, complain);
+
+ if (complain & tf_error)
+ error_at (loc, "cannot convert %qE from type %qT to type %qT",
+ expr, intype, type);
+ return error_mark_node;
+}
+
+/* Like convert, except permit conversions to take place which
+ are not normally allowed due to access restrictions
+ (such as conversion from sub-type to private super-type). */
+
+static tree
+convert_to_pointer_force (tree type, tree expr, tsubst_flags_t complain)
+{
+ tree intype = TREE_TYPE (expr);
+ enum tree_code form = TREE_CODE (intype);
+
+ if (form == POINTER_TYPE)
+ {
+ intype = TYPE_MAIN_VARIANT (intype);
+
+ if (TYPE_MAIN_VARIANT (type) != intype
+ && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
+ && MAYBE_CLASS_TYPE_P (TREE_TYPE (type))
+ && MAYBE_CLASS_TYPE_P (TREE_TYPE (intype))
+ && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE)
+ {
+ enum tree_code code = PLUS_EXPR;
+ tree binfo;
+
+ binfo = lookup_base (TREE_TYPE (intype), TREE_TYPE (type),
+ ba_unique, NULL, complain);
+ if (!binfo)
+ {
+ binfo = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
+ ba_unique, NULL, complain);
+ code = MINUS_EXPR;
+ }
+ if (binfo == error_mark_node)
+ return error_mark_node;
+ if (binfo)
+ {
+ expr = build_base_path (code, expr, binfo, 0, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+ /* Add any qualifier conversions. */
+ if (!same_type_p (TREE_TYPE (TREE_TYPE (expr)),
+ TREE_TYPE (type)))
+ expr = build_nop (type, expr);
+ return expr;
+ }
+ }
+ }
+
+ return cp_convert_to_pointer (type, expr, complain);
+}
+
+/* We are passing something to a function which requires a reference.
+ The type we are interested in is in TYPE. The initial
+ value we have to begin with is in ARG.
+
+ FLAGS controls how we manage access checking.
+ DIRECT_BIND in FLAGS controls how any temporaries are generated.
+ If DIRECT_BIND is set, DECL is the reference we're binding to. */
+
+static tree
+build_up_reference (tree type, tree arg, int flags, tree decl,
+ tsubst_flags_t complain)
+{
+ tree rval;
+ tree argtype = TREE_TYPE (arg);
+ tree target_type = TREE_TYPE (type);
+
+ gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
+
+ if ((flags & DIRECT_BIND) && ! real_lvalue_p (arg))
+ {
+ /* Create a new temporary variable. We can't just use a TARGET_EXPR
+ here because it needs to live as long as DECL. */
+ tree targ = arg;
+
+ arg = make_temporary_var_for_ref_to_temp (decl, target_type);
+
+ /* Process the initializer for the declaration. */
+ DECL_INITIAL (arg) = targ;
+ cp_finish_decl (arg, targ, /*init_const_expr_p=*/false, NULL_TREE,
+ LOOKUP_ONLYCONVERTING|DIRECT_BIND);
+ }
+ else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg))
+ return get_target_expr_sfinae (arg, complain);
+
+ /* If we had a way to wrap this up, and say, if we ever needed its
+ address, transform all occurrences of the register, into a memory
+ reference we could win better. */
+ rval = cp_build_addr_expr (arg, complain);
+ if (rval == error_mark_node)
+ return error_mark_node;
+
+ if ((flags & LOOKUP_PROTECT)
+ && TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type)
+ && MAYBE_CLASS_TYPE_P (argtype)
+ && MAYBE_CLASS_TYPE_P (target_type))
+ {
+ /* We go through lookup_base for the access control. */
+ tree binfo = lookup_base (argtype, target_type, ba_check,
+ NULL, complain);
+ if (binfo == error_mark_node)
+ return error_mark_node;
+ if (binfo == NULL_TREE)
+ return error_not_base_type (target_type, argtype);
+ rval = build_base_path (PLUS_EXPR, rval, binfo, 1, complain);
+ }
+ else
+ rval
+ = convert_to_pointer_force (build_pointer_type (target_type),
+ rval, complain);
+ return build_nop (type, rval);
+}
+
+/* Subroutine of convert_to_reference. REFTYPE is the target reference type.
+ INTYPE is the original rvalue type and DECL is an optional _DECL node
+ for diagnostics.
+
+ [dcl.init.ref] says that if an rvalue is used to
+ initialize a reference, then the reference must be to a
+ non-volatile const type. */
+
+static void
+diagnose_ref_binding (location_t loc, tree reftype, tree intype, tree decl)
+{
+ tree ttl = TREE_TYPE (reftype);
+
+ if (!CP_TYPE_CONST_NON_VOLATILE_P (ttl))
+ {
+ const char *msg;
+
+ if (CP_TYPE_VOLATILE_P (ttl) && decl)
+ msg = G_("initialization of volatile reference type %q#T from "
+ "rvalue of type %qT");
+ else if (CP_TYPE_VOLATILE_P (ttl))
+ msg = G_("conversion to volatile reference type %q#T "
+ "from rvalue of type %qT");
+ else if (decl)
+ msg = G_("initialization of non-const reference type %q#T from "
+ "rvalue of type %qT");
+ else
+ msg = G_("conversion to non-const reference type %q#T from "
+ "rvalue of type %qT");
+
+ permerror (loc, msg, reftype, intype);
+ }
+}
+
+/* For C++: Only need to do one-level references, but cannot
+ get tripped up on signed/unsigned differences.
+
+ DECL is either NULL_TREE or the _DECL node for a reference that is being
+ initialized. It can be error_mark_node if we don't know the _DECL but
+ we know it's an initialization. */
+
+tree
+convert_to_reference (tree reftype, tree expr, int convtype,
+ int flags, tree decl, tsubst_flags_t complain)
+{
+ tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));
+ tree intype;
+ tree rval = NULL_TREE;
+ tree rval_as_conversion = NULL_TREE;
+ bool can_convert_intype_to_type;
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+
+ if (TREE_CODE (type) == FUNCTION_TYPE
+ && TREE_TYPE (expr) == unknown_type_node)
+ expr = instantiate_type (type, expr, complain);
+
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ intype = TREE_TYPE (expr);
+
+ gcc_assert (TREE_CODE (intype) != REFERENCE_TYPE);
+ gcc_assert (TREE_CODE (reftype) == REFERENCE_TYPE);
+
+ intype = TYPE_MAIN_VARIANT (intype);
+
+ can_convert_intype_to_type = can_convert_standard (type, intype, complain);
+
+ if (!can_convert_intype_to_type
+ && (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype)
+ && ! (flags & LOOKUP_NO_CONVERSION))
+ {
+ /* Look for a user-defined conversion to lvalue that we can use. */
+
+ rval_as_conversion
+ = build_type_conversion (reftype, expr);
+
+ if (rval_as_conversion && rval_as_conversion != error_mark_node
+ && real_lvalue_p (rval_as_conversion))
+ {
+ expr = rval_as_conversion;
+ rval_as_conversion = NULL_TREE;
+ intype = type;
+ can_convert_intype_to_type = 1;
+ }
+ }
+
+ if (((convtype & CONV_STATIC)
+ && can_convert_standard (intype, type, complain))
+ || ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type))
+ {
+ {
+ tree ttl = TREE_TYPE (reftype);
+ tree ttr = lvalue_type (expr);
+
+ if ((complain & tf_error)
+ && ! real_lvalue_p (expr))
+ diagnose_ref_binding (loc, reftype, intype, decl);
+
+ if (! (convtype & CONV_CONST)
+ && !at_least_as_qualified_p (ttl, ttr))
+ {
+ if (complain & tf_error)
+ permerror (loc, "conversion from %qT to %qT discards qualifiers",
+ ttr, reftype);
+ else
+ return error_mark_node;
+ }
+ }
+
+ return build_up_reference (reftype, expr, flags, decl, complain);
+ }
+ else if ((convtype & CONV_REINTERPRET) && lvalue_p (expr))
+ {
+ /* When casting an lvalue to a reference type, just convert into
+ a pointer to the new type and deference it. This is allowed
+ by San Diego WP section 5.2.9 paragraph 12, though perhaps it
+ should be done directly (jason). (int &)ri ---> *(int*)&ri */
+
+ /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they
+ meant. */
+ if ((complain & tf_warning)
+ && TYPE_PTR_P (intype)
+ && (comptypes (TREE_TYPE (intype), type,
+ COMPARE_BASE | COMPARE_DERIVED)))
+ warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
+ intype, reftype);
+
+ rval = cp_build_addr_expr (expr, complain);
+ if (rval != error_mark_node)
+ rval = convert_force (build_pointer_type (TREE_TYPE (reftype)),
+ rval, 0, complain);
+ if (rval != error_mark_node)
+ rval = build1 (NOP_EXPR, reftype, rval);
+ }
+ else
+ {
+ rval = convert_for_initialization (NULL_TREE, type, expr, flags,
+ ICR_CONVERTING, 0, 0, complain);
+ if (rval == NULL_TREE || rval == error_mark_node)
+ return rval;
+ if (complain & tf_error)
+ diagnose_ref_binding (loc, reftype, intype, decl);
+ rval = build_up_reference (reftype, rval, flags, decl, complain);
+ }
+
+ if (rval)
+ {
+ /* If we found a way to convert earlier, then use it. */
+ return rval;
+ }
+
+ if (complain & tf_error)
+ error_at (loc, "cannot convert type %qT to type %qT", intype, reftype);
+
+ return error_mark_node;
+}
+
+/* We are using a reference VAL for its value. Bash that reference all the
+ way down to its lowest form. */
+
+tree
+convert_from_reference (tree val)
+{
+ if (TREE_TYPE (val)
+ && TREE_CODE (TREE_TYPE (val)) == REFERENCE_TYPE)
+ {
+ tree t = TREE_TYPE (TREE_TYPE (val));
+ tree ref = build1 (INDIRECT_REF, t, val);
+
+ mark_exp_read (val);
+ /* We *must* set TREE_READONLY when dereferencing a pointer to const,
+ so that we get the proper error message if the result is used
+ to assign to. Also, &* is supposed to be a no-op. */
+ TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
+ TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
+ TREE_SIDE_EFFECTS (ref)
+ = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (val));
+ val = ref;
+ }
+
+ return val;
+}
+
+/* Really perform an lvalue-to-rvalue conversion, including copying an
+ argument of class type into a temporary. */
+
+tree
+force_rvalue (tree expr, tsubst_flags_t complain)
+{
+ tree type = TREE_TYPE (expr);
+ if (MAYBE_CLASS_TYPE_P (type) && TREE_CODE (expr) != TARGET_EXPR)
+ {
+ vec<tree, va_gc> *args = make_tree_vector_single (expr);
+ expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ &args, type, LOOKUP_NORMAL, complain);
+ release_tree_vector (args);
+ expr = build_cplus_new (type, expr, complain);
+ }
+ else
+ expr = decay_conversion (expr, complain);
+
+ return expr;
+}
+
+
+/* If EXPR and ORIG are INTEGER_CSTs, return a version of EXPR that has
+ TREE_OVERFLOW set only if it is set in ORIG. Otherwise, return EXPR
+ unchanged. */
+
+static tree
+ignore_overflows (tree expr, tree orig)
+{
+ if (TREE_CODE (expr) == INTEGER_CST
+ && TREE_CODE (orig) == INTEGER_CST
+ && TREE_OVERFLOW (expr) != TREE_OVERFLOW (orig))
+ {
+ gcc_assert (!TREE_OVERFLOW (orig));
+ /* Ensure constant sharing. */
+ expr = build_int_cst_wide (TREE_TYPE (expr),
+ TREE_INT_CST_LOW (expr),
+ TREE_INT_CST_HIGH (expr));
+ }
+ return expr;
+}
+
+/* Fold away simple conversions, but make sure TREE_OVERFLOW is set
+ properly. */
+
+tree
+cp_fold_convert (tree type, tree expr)
+{
+ tree conv = fold_convert (type, expr);
+ conv = ignore_overflows (conv, expr);
+ return conv;
+}
+
+/* C++ conversions, preference to static cast conversions. */
+
+tree
+cp_convert (tree type, tree expr, tsubst_flags_t complain)
+{
+ return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL, complain);
+}
+
+/* C++ equivalent of convert_and_check but using cp_convert as the
+ conversion function.
+
+ Convert EXPR to TYPE, warning about conversion problems with constants.
+ Invoke this function on every expression that is converted implicitly,
+ i.e. because of language rules and not because of an explicit cast. */
+
+tree
+cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain)
+{
+ tree result;
+
+ if (TREE_TYPE (expr) == type)
+ return expr;
+
+ result = cp_convert (type, expr, complain);
+
+ if ((complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
+ {
+ tree folded = maybe_constant_value (expr);
+ tree stripped = folded;
+ tree folded_result
+ = folded != expr ? cp_convert (type, folded, complain) : result;
+
+ /* maybe_constant_value wraps an INTEGER_CST with TREE_OVERFLOW in a
+ NOP_EXPR so that it isn't TREE_CONSTANT anymore. */
+ STRIP_NOPS (stripped);
+
+ if (!TREE_OVERFLOW_P (stripped)
+ && folded_result != error_mark_node)
+ warnings_for_convert_and_check (input_location, type, folded,
+ folded_result);
+ }
+
+ return result;
+}
+
+/* Conversion...
+
+ FLAGS indicates how we should behave. */
+
+tree
+ocp_convert (tree type, tree expr, int convtype, int flags,
+ tsubst_flags_t complain)
+{
+ tree e = expr;
+ enum tree_code code = TREE_CODE (type);
+ const char *invalid_conv_diag;
+ tree e1;
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+
+ if (error_operand_p (e) || type == error_mark_node)
+ return error_mark_node;
+
+ complete_type (type);
+ complete_type (TREE_TYPE (expr));
+
+ if ((invalid_conv_diag
+ = targetm.invalid_conversion (TREE_TYPE (expr), type)))
+ {
+ if (complain & tf_error)
+ error (invalid_conv_diag);
+ return error_mark_node;
+ }
+
+ /* FIXME remove when moving to c_fully_fold model. */
+ /* FIXME do we still need this test? */
+ if (!CLASS_TYPE_P (type))
+ e = integral_constant_value (e);
+ if (error_operand_p (e))
+ return error_mark_node;
+
+ if (MAYBE_CLASS_TYPE_P (type) && (convtype & CONV_FORCE_TEMP))
+ /* We need a new temporary; don't take this shortcut. */;
+ else if (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (e)))
+ {
+ if (same_type_p (type, TREE_TYPE (e)))
+ /* The call to fold will not always remove the NOP_EXPR as
+ might be expected, since if one of the types is a typedef;
+ the comparison in fold is just equality of pointers, not a
+ call to comptypes. We don't call fold in this case because
+ that can result in infinite recursion; fold will call
+ convert, which will call ocp_convert, etc. */
+ return e;
+ /* For complex data types, we need to perform componentwise
+ conversion. */
+ else if (TREE_CODE (type) == COMPLEX_TYPE)
+ return fold_if_not_in_template (convert_to_complex (type, e));
+ else if (TREE_CODE (type) == VECTOR_TYPE)
+ return fold_if_not_in_template (convert_to_vector (type, e));
+ else if (TREE_CODE (e) == TARGET_EXPR)
+ {
+ /* Don't build a NOP_EXPR of class type. Instead, change the
+ type of the temporary. */
+ TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
+ return e;
+ }
+ else
+ {
+ /* We shouldn't be treating objects of ADDRESSABLE type as
+ rvalues. */
+ gcc_assert (!TREE_ADDRESSABLE (type));
+ return fold_if_not_in_template (build_nop (type, e));
+ }
+ }
+
+ e1 = targetm.convert_to_type (type, e);
+ if (e1)
+ return e1;
+
+ if (code == VOID_TYPE && (convtype & CONV_STATIC))
+ {
+ e = convert_to_void (e, ICV_CAST, complain);
+ return e;
+ }
+
+ if (INTEGRAL_CODE_P (code))
+ {
+ tree intype = TREE_TYPE (e);
+ tree converted;
+
+ if (TREE_CODE (type) == ENUMERAL_TYPE)
+ {
+ /* enum = enum, enum = int, enum = float, (enum)pointer are all
+ errors. */
+ if (((INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
+ || TREE_CODE (intype) == REAL_TYPE)
+ && ! (convtype & CONV_STATIC))
+ || TYPE_PTR_P (intype))
+ {
+ if (complain & tf_error)
+ permerror (loc, "conversion from %q#T to %q#T", intype, type);
+ else
+ return error_mark_node;
+ }
+
+ /* [expr.static.cast]
+
+ 8. A value of integral or enumeration type can be explicitly
+ converted to an enumeration type. The value is unchanged if
+ the original value is within the range of the enumeration
+ values. Otherwise, the resulting enumeration value is
+ unspecified. */
+ if ((complain & tf_warning)
+ && TREE_CODE (e) == INTEGER_CST
+ && ENUM_UNDERLYING_TYPE (type)
+ && !int_fits_type_p (e, ENUM_UNDERLYING_TYPE (type)))
+ warning_at (loc, OPT_Wconversion,
+ "the result of the conversion is unspecified because "
+ "%qE is outside the range of type %qT",
+ expr, type);
+ }
+ if (MAYBE_CLASS_TYPE_P (intype))
+ {
+ tree rval;
+ rval = build_type_conversion (type, e);
+ if (rval)
+ return rval;
+ if (complain & tf_error)
+ error_at (loc, "%q#T used where a %qT was expected", intype, type);
+ return error_mark_node;
+ }
+ if (code == BOOLEAN_TYPE)
+ {
+ if (VOID_TYPE_P (intype))
+ {
+ if (complain & tf_error)
+ error_at (loc,
+ "could not convert %qE from %<void%> to %<bool%>",
+ expr);
+ return error_mark_node;
+ }
+
+ /* We can't implicitly convert a scoped enum to bool, so convert
+ to the underlying type first. */
+ if (SCOPED_ENUM_P (intype) && (convtype & CONV_STATIC))
+ e = build_nop (ENUM_UNDERLYING_TYPE (intype), e);
+ return cp_truthvalue_conversion (e);
+ }
+
+ converted = fold_if_not_in_template (convert_to_integer (type, e));
+
+ /* Ignore any integer overflow caused by the conversion. */
+ return ignore_overflows (converted, e);
+ }
+ if (NULLPTR_TYPE_P (type) && e && null_ptr_cst_p (e))
+ {
+ if (complain & tf_warning)
+ maybe_warn_zero_as_null_pointer_constant (e, loc);
+ return nullptr_node;
+ }
+ if (POINTER_TYPE_P (type) || TYPE_PTRMEM_P (type))
+ return fold_if_not_in_template (cp_convert_to_pointer (type, e, complain));
+ if (code == VECTOR_TYPE)
+ {
+ tree in_vtype = TREE_TYPE (e);
+ if (MAYBE_CLASS_TYPE_P (in_vtype))
+ {
+ tree ret_val;
+ ret_val = build_type_conversion (type, e);
+ if (ret_val)
+ return ret_val;
+ if (complain & tf_error)
+ error_at (loc, "%q#T used where a %qT was expected",
+ in_vtype, type);
+ return error_mark_node;
+ }
+ return fold_if_not_in_template (convert_to_vector (type, e));
+ }
+ if (code == REAL_TYPE || code == COMPLEX_TYPE)
+ {
+ if (MAYBE_CLASS_TYPE_P (TREE_TYPE (e)))
+ {
+ tree rval;
+ rval = build_type_conversion (type, e);
+ if (rval)
+ return rval;
+ else if (complain & tf_error)
+ error_at (loc,
+ "%q#T used where a floating point value was expected",
+ TREE_TYPE (e));
+ }
+ if (code == REAL_TYPE)
+ return fold_if_not_in_template (convert_to_real (type, e));
+ else if (code == COMPLEX_TYPE)
+ return fold_if_not_in_template (convert_to_complex (type, e));
+ }
+
+ /* New C++ semantics: since assignment is now based on
+ memberwise copying, if the rhs type is derived from the
+ lhs type, then we may still do a conversion. */
+ if (RECORD_OR_UNION_CODE_P (code))
+ {
+ tree dtype = TREE_TYPE (e);
+ tree ctor = NULL_TREE;
+
+ dtype = TYPE_MAIN_VARIANT (dtype);
+
+ /* Conversion between aggregate types. New C++ semantics allow
+ objects of derived type to be cast to objects of base type.
+ Old semantics only allowed this between pointers.
+
+ There may be some ambiguity between using a constructor
+ vs. using a type conversion operator when both apply. */
+
+ ctor = e;
+
+ if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain))
+ return error_mark_node;
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (ctor))
+ ctor = perform_implicit_conversion (type, ctor, complain);
+ else if ((flags & LOOKUP_ONLYCONVERTING)
+ && ! (CLASS_TYPE_P (dtype) && DERIVED_FROM_P (type, dtype)))
+ /* For copy-initialization, first we create a temp of the proper type
+ with a user-defined conversion sequence, then we direct-initialize
+ the target with the temp (see [dcl.init]). */
+ ctor = build_user_type_conversion (type, ctor, flags, complain);
+ else
+ {
+ vec<tree, va_gc> *ctor_vec = make_tree_vector_single (ctor);
+ ctor = build_special_member_call (NULL_TREE,
+ complete_ctor_identifier,
+ &ctor_vec,
+ type, flags, complain);
+ release_tree_vector (ctor_vec);
+ }
+ if (ctor)
+ return build_cplus_new (type, ctor, complain);
+ }
+
+ if (complain & tf_error)
+ {
+ /* If the conversion failed and expr was an invalid use of pointer to
+ member function, try to report a meaningful error. */
+ if (invalid_nonstatic_memfn_p (expr, complain))
+ /* We displayed the error message. */;
+ else
+ error_at (loc, "conversion from %qT to non-scalar type %qT requested",
+ TREE_TYPE (expr), type);
+ }
+ return error_mark_node;
+}
+
+/* When an expression is used in a void context, its value is discarded and
+ no lvalue-rvalue and similar conversions happen [expr.static.cast/4,
+ stmt.expr/1, expr.comma/1]. This permits dereferencing an incomplete type
+ in a void context. The C++ standard does not define what an `access' to an
+ object is, but there is reason to believe that it is the lvalue to rvalue
+ conversion -- if it were not, `*&*p = 1' would violate [expr]/4 in that it
+ accesses `*p' not to calculate the value to be stored. But, dcl.type.cv/8
+ indicates that volatile semantics should be the same between C and C++
+ where ever possible. C leaves it implementation defined as to what
+ constitutes an access to a volatile. So, we interpret `*vp' as a read of
+ the volatile object `vp' points to, unless that is an incomplete type. For
+ volatile references we do not do this interpretation, because that would
+ make it impossible to ignore the reference return value from functions. We
+ issue warnings in the confusing cases.
+
+ The IMPLICIT is ICV_CAST when the user is explicitly converting an expression
+ to void via a cast. If an expression is being implicitly converted, IMPLICIT
+ indicates the context of the implicit conversion. */
+
+tree
+convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
+{
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+
+ if (expr == error_mark_node
+ || TREE_TYPE (expr) == error_mark_node)
+ return error_mark_node;
+
+ if (implicit == ICV_CAST)
+ mark_exp_read (expr);
+ else
+ {
+ tree exprv = expr;
+
+ while (TREE_CODE (exprv) == COMPOUND_EXPR)
+ exprv = TREE_OPERAND (exprv, 1);
+ if (DECL_P (exprv)
+ || handled_component_p (exprv)
+ || INDIRECT_REF_P (exprv))
+ /* Expr is not being 'used' here, otherwise we whould have
+ called mark_{rl}value_use use here, which would have in turn
+ called mark_exp_read. Rather, we call mark_exp_read directly
+ to avoid some warnings when
+ -Wunused-but-set-{variable,parameter} is in effect. */
+ mark_exp_read (exprv);
+ }
+
+ if (!TREE_TYPE (expr))
+ return expr;
+ if (invalid_nonstatic_memfn_p (expr, complain))
+ return error_mark_node;
+ if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
+ {
+ if (complain & tf_error)
+ error_at (loc, "pseudo-destructor is not called");
+ return error_mark_node;
+ }
+ if (VOID_TYPE_P (TREE_TYPE (expr)))
+ return expr;
+ switch (TREE_CODE (expr))
+ {
+ case COND_EXPR:
+ {
+ /* The two parts of a cond expr might be separate lvalues. */
+ tree op1 = TREE_OPERAND (expr,1);
+ tree op2 = TREE_OPERAND (expr,2);
+ bool side_effects = ((op1 && TREE_SIDE_EFFECTS (op1))
+ || TREE_SIDE_EFFECTS (op2));
+ tree new_op1, new_op2;
+ new_op1 = NULL_TREE;
+ if (implicit != ICV_CAST && !side_effects)
+ {
+ if (op1)
+ new_op1 = convert_to_void (op1, ICV_SECOND_OF_COND, complain);
+ new_op2 = convert_to_void (op2, ICV_THIRD_OF_COND, complain);
+ }
+ else
+ {
+ if (op1)
+ new_op1 = convert_to_void (op1, ICV_CAST, complain);
+ new_op2 = convert_to_void (op2, ICV_CAST, complain);
+ }
+
+ expr = build3 (COND_EXPR, TREE_TYPE (new_op2),
+ TREE_OPERAND (expr, 0), new_op1, new_op2);
+ break;
+ }
+
+ case COMPOUND_EXPR:
+ {
+ /* The second part of a compound expr contains the value. */
+ tree op1 = TREE_OPERAND (expr,1);
+ tree new_op1;
+ if (implicit != ICV_CAST && !TREE_NO_WARNING (expr))
+ new_op1 = convert_to_void (op1, ICV_RIGHT_OF_COMMA, complain);
+ else
+ new_op1 = convert_to_void (op1, ICV_CAST, complain);
+
+ if (new_op1 != op1)
+ {
+ tree t = build2 (COMPOUND_EXPR, TREE_TYPE (new_op1),
+ TREE_OPERAND (expr, 0), new_op1);
+ expr = t;
+ }
+
+ break;
+ }
+
+ case NON_LVALUE_EXPR:
+ case NOP_EXPR:
+ /* These have already decayed to rvalue. */
+ break;
+
+ case CALL_EXPR: /* We have a special meaning for volatile void fn(). */
+ break;
+
+ case INDIRECT_REF:
+ {
+ tree type = TREE_TYPE (expr);
+ int is_reference = TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0)))
+ == REFERENCE_TYPE;
+ int is_volatile = TYPE_VOLATILE (type);
+ int is_complete = COMPLETE_TYPE_P (complete_type (type));
+
+ /* Can't load the value if we don't know the type. */
+ if (is_volatile && !is_complete)
+ {
+ if (complain & tf_warning)
+ switch (implicit)
+ {
+ case ICV_CAST:
+ warning_at (loc, 0, "conversion to void will not access "
+ "object of incomplete type %qT", type);
+ break;
+ case ICV_SECOND_OF_COND:
+ warning_at (loc, 0, "indirection will not access object of "
+ "incomplete type %qT in second operand "
+ "of conditional expression", type);
+ break;
+ case ICV_THIRD_OF_COND:
+ warning_at (loc, 0, "indirection will not access object of "
+ "incomplete type %qT in third operand "
+ "of conditional expression", type);
+ break;
+ case ICV_RIGHT_OF_COMMA:
+ warning_at (loc, 0, "indirection will not access object of "
+ "incomplete type %qT in right operand of "
+ "comma operator", type);
+ break;
+ case ICV_LEFT_OF_COMMA:
+ warning_at (loc, 0, "indirection will not access object of "
+ "incomplete type %qT in left operand of "
+ "comma operator", type);
+ break;
+ case ICV_STATEMENT:
+ warning_at (loc, 0, "indirection will not access object of "
+ "incomplete type %qT in statement", type);
+ break;
+ case ICV_THIRD_IN_FOR:
+ warning_at (loc, 0, "indirection will not access object of "
+ "incomplete type %qT in for increment "
+ "expression", type);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ /* Don't load the value if this is an implicit dereference, or if
+ the type needs to be handled by ctors/dtors. */
+ else if (is_volatile && is_reference)
+ {
+ if (complain & tf_warning)
+ switch (implicit)
+ {
+ case ICV_CAST:
+ warning_at (loc, 0, "conversion to void will not access "
+ "object of type %qT", type);
+ break;
+ case ICV_SECOND_OF_COND:
+ warning_at (loc, 0, "implicit dereference will not access "
+ "object of type %qT in second operand of "
+ "conditional expression", type);
+ break;
+ case ICV_THIRD_OF_COND:
+ warning_at (loc, 0, "implicit dereference will not access "
+ "object of type %qT in third operand of "
+ "conditional expression", type);
+ break;
+ case ICV_RIGHT_OF_COMMA:
+ warning_at (loc, 0, "implicit dereference will not access "
+ "object of type %qT in right operand of "
+ "comma operator", type);
+ break;
+ case ICV_LEFT_OF_COMMA:
+ warning_at (loc, 0, "implicit dereference will not access "
+ "object of type %qT in left operand of comma "
+ "operator", type);
+ break;
+ case ICV_STATEMENT:
+ warning_at (loc, 0, "implicit dereference will not access "
+ "object of type %qT in statement", type);
+ break;
+ case ICV_THIRD_IN_FOR:
+ warning_at (loc, 0, "implicit dereference will not access "
+ "object of type %qT in for increment expression",
+ type);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else if (is_volatile && TREE_ADDRESSABLE (type))
+ {
+ if (complain & tf_warning)
+ switch (implicit)
+ {
+ case ICV_CAST:
+ warning_at (loc, 0, "conversion to void will not access "
+ "object of non-trivially-copyable type %qT",
+ type);
+ break;
+ case ICV_SECOND_OF_COND:
+ warning_at (loc, 0, "indirection will not access object of "
+ "non-trivially-copyable type %qT in second "
+ "operand of conditional expression", type);
+ break;
+ case ICV_THIRD_OF_COND:
+ warning_at (loc, 0, "indirection will not access object of "
+ "non-trivially-copyable type %qT in third "
+ "operand of conditional expression", type);
+ break;
+ case ICV_RIGHT_OF_COMMA:
+ warning_at (loc, 0, "indirection will not access object of "
+ "non-trivially-copyable type %qT in right "
+ "operand of comma operator", type);
+ break;
+ case ICV_LEFT_OF_COMMA:
+ warning_at (loc, 0, "indirection will not access object of "
+ "non-trivially-copyable type %qT in left "
+ "operand of comma operator", type);
+ break;
+ case ICV_STATEMENT:
+ warning_at (loc, 0, "indirection will not access object of "
+ "non-trivially-copyable type %qT in statement",
+ type);
+ break;
+ case ICV_THIRD_IN_FOR:
+ warning_at (loc, 0, "indirection will not access object of "
+ "non-trivially-copyable type %qT in for "
+ "increment expression", type);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ if (is_reference || !is_volatile || !is_complete || TREE_ADDRESSABLE (type))
+ {
+ /* Emit a warning (if enabled) when the "effect-less" INDIRECT_REF
+ operation is stripped off. Note that we don't warn about
+ - an expression with TREE_NO_WARNING set. (For an example of
+ such expressions, see build_over_call in call.c.)
+ - automatic dereferencing of references, since the user cannot
+ control it. (See also warn_if_unused_value() in c-common.c.) */
+ if (warn_unused_value
+ && implicit != ICV_CAST
+ && (complain & tf_warning)
+ && !TREE_NO_WARNING (expr)
+ && !is_reference)
+ warning_at (loc, OPT_Wunused_value, "value computed is not used");
+ expr = TREE_OPERAND (expr, 0);
+ }
+
+ break;
+ }
+
+ case VAR_DECL:
+ {
+ /* External variables might be incomplete. */
+ tree type = TREE_TYPE (expr);
+ int is_complete = COMPLETE_TYPE_P (complete_type (type));
+
+ if (TYPE_VOLATILE (type) && !is_complete && (complain & tf_warning))
+ switch (implicit)
+ {
+ case ICV_CAST:
+ warning_at (loc, 0, "conversion to void will not access "
+ "object %qE of incomplete type %qT", expr, type);
+ break;
+ case ICV_SECOND_OF_COND:
+ warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+ "not be accessed in second operand of "
+ "conditional expression", expr, type);
+ break;
+ case ICV_THIRD_OF_COND:
+ warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+ "not be accessed in third operand of "
+ "conditional expression", expr, type);
+ break;
+ case ICV_RIGHT_OF_COMMA:
+ warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+ "not be accessed in right operand of comma operator",
+ expr, type);
+ break;
+ case ICV_LEFT_OF_COMMA:
+ warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+ "not be accessed in left operand of comma operator",
+ expr, type);
+ break;
+ case ICV_STATEMENT:
+ warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+ "not be accessed in statement", expr, type);
+ break;
+ case ICV_THIRD_IN_FOR:
+ warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+ "not be accessed in for increment expression",
+ expr, type);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ break;
+ }
+
+ case TARGET_EXPR:
+ /* Don't bother with the temporary object returned from a function if
+ we don't use it and don't need to destroy it. We'll still
+ allocate space for it in expand_call or declare_return_variable,
+ but we don't need to track it through all the tree phases. */
+ if (TARGET_EXPR_IMPLICIT_P (expr)
+ && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (expr)))
+ {
+ tree init = TARGET_EXPR_INITIAL (expr);
+ if (TREE_CODE (init) == AGGR_INIT_EXPR
+ && !AGGR_INIT_VIA_CTOR_P (init))
+ {
+ tree fn = AGGR_INIT_EXPR_FN (init);
+ expr = build_call_array_loc (input_location,
+ TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
+ fn,
+ aggr_init_expr_nargs (init),
+ AGGR_INIT_EXPR_ARGP (init));
+ }
+ }
+ break;
+
+ default:;
+ }
+ expr = resolve_nondeduced_context (expr);
+ {
+ tree probe = expr;
+
+ if (TREE_CODE (probe) == ADDR_EXPR)
+ probe = TREE_OPERAND (expr, 0);
+ if (type_unknown_p (probe))
+ {
+ /* [over.over] enumerates the places where we can take the address
+ of an overloaded function, and this is not one of them. */
+ if (complain & tf_error)
+ switch (implicit)
+ {
+ case ICV_CAST:
+ error_at (loc, "conversion to void "
+ "cannot resolve address of overloaded function");
+ break;
+ case ICV_SECOND_OF_COND:
+ error_at (loc, "second operand of conditional expression "
+ "cannot resolve address of overloaded function");
+ break;
+ case ICV_THIRD_OF_COND:
+ error_at (loc, "third operand of conditional expression "
+ "cannot resolve address of overloaded function");
+ break;
+ case ICV_RIGHT_OF_COMMA:
+ error_at (loc, "right operand of comma operator "
+ "cannot resolve address of overloaded function");
+ break;
+ case ICV_LEFT_OF_COMMA:
+ error_at (loc, "left operand of comma operator "
+ "cannot resolve address of overloaded function");
+ break;
+ case ICV_STATEMENT:
+ error_at (loc, "statement "
+ "cannot resolve address of overloaded function");
+ break;
+ case ICV_THIRD_IN_FOR:
+ error_at (loc, "for increment expression "
+ "cannot resolve address of overloaded function");
+ break;
+ }
+ else
+ return error_mark_node;
+ expr = void_zero_node;
+ }
+ else if (implicit != ICV_CAST && probe == expr && is_overloaded_fn (probe))
+ {
+ /* Only warn when there is no &. */
+ if (complain & tf_warning)
+ switch (implicit)
+ {
+ case ICV_SECOND_OF_COND:
+ warning_at (loc, OPT_Waddress,
+ "second operand of conditional expression "
+ "is a reference, not call, to function %qE", expr);
+ break;
+ case ICV_THIRD_OF_COND:
+ warning_at (loc, OPT_Waddress,
+ "third operand of conditional expression "
+ "is a reference, not call, to function %qE", expr);
+ break;
+ case ICV_RIGHT_OF_COMMA:
+ warning_at (loc, OPT_Waddress,
+ "right operand of comma operator "
+ "is a reference, not call, to function %qE", expr);
+ break;
+ case ICV_LEFT_OF_COMMA:
+ warning_at (loc, OPT_Waddress,
+ "left operand of comma operator "
+ "is a reference, not call, to function %qE", expr);
+ break;
+ case ICV_STATEMENT:
+ warning_at (loc, OPT_Waddress,
+ "statement is a reference, not call, to function %qE",
+ expr);
+ break;
+ case ICV_THIRD_IN_FOR:
+ warning_at (loc, OPT_Waddress,
+ "for increment expression "
+ "is a reference, not call, to function %qE", expr);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (TREE_CODE (expr) == COMPONENT_REF)
+ expr = TREE_OPERAND (expr, 0);
+ }
+ }
+
+ if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
+ {
+ if (implicit != ICV_CAST
+ && warn_unused_value
+ && !TREE_NO_WARNING (expr)
+ && !processing_template_decl)
+ {
+ /* The middle end does not warn about expressions that have
+ been explicitly cast to void, so we must do so here. */
+ if (!TREE_SIDE_EFFECTS (expr)) {
+ if (complain & tf_warning)
+ switch (implicit)
+ {
+ case ICV_SECOND_OF_COND:
+ warning_at (loc, OPT_Wunused_value,
+ "second operand of conditional expression "
+ "has no effect");
+ break;
+ case ICV_THIRD_OF_COND:
+ warning_at (loc, OPT_Wunused_value,
+ "third operand of conditional expression "
+ "has no effect");
+ break;
+ case ICV_RIGHT_OF_COMMA:
+ warning_at (loc, OPT_Wunused_value,
+ "right operand of comma operator has no effect");
+ break;
+ case ICV_LEFT_OF_COMMA:
+ warning_at (loc, OPT_Wunused_value,
+ "left operand of comma operator has no effect");
+ break;
+ case ICV_STATEMENT:
+ warning_at (loc, OPT_Wunused_value,
+ "statement has no effect");
+ break;
+ case ICV_THIRD_IN_FOR:
+ warning_at (loc, OPT_Wunused_value,
+ "for increment expression has no effect");
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else
+ {
+ tree e;
+ enum tree_code code;
+ enum tree_code_class tclass;
+
+ e = expr;
+ /* We might like to warn about (say) "(int) f()", as the
+ cast has no effect, but the compiler itself will
+ generate implicit conversions under some
+ circumstances. (For example a block copy will be
+ turned into a call to "__builtin_memcpy", with a
+ conversion of the return value to an appropriate
+ type.) So, to avoid false positives, we strip
+ conversions. Do not use STRIP_NOPs because it will
+ not strip conversions to "void", as that is not a
+ mode-preserving conversion. */
+ while (TREE_CODE (e) == NOP_EXPR)
+ e = TREE_OPERAND (e, 0);
+
+ code = TREE_CODE (e);
+ tclass = TREE_CODE_CLASS (code);
+ if ((tclass == tcc_comparison
+ || tclass == tcc_unary
+ || (tclass == tcc_binary
+ && !(code == MODIFY_EXPR
+ || code == INIT_EXPR
+ || code == PREDECREMENT_EXPR
+ || code == PREINCREMENT_EXPR
+ || code == POSTDECREMENT_EXPR
+ || code == POSTINCREMENT_EXPR))
+ || code == VEC_PERM_EXPR
+ || code == VEC_COND_EXPR)
+ && (complain & tf_warning))
+ warning_at (loc, OPT_Wunused_value, "value computed is not used");
+ }
+ }
+ expr = build1 (CONVERT_EXPR, void_type_node, expr);
+ }
+ if (! TREE_SIDE_EFFECTS (expr))
+ expr = void_zero_node;
+ return expr;
+}
+
+/* Create an expression whose value is that of EXPR,
+ converted to type TYPE. The TREE_TYPE of the value
+ is always TYPE. This function implements all reasonable
+ conversions; callers should filter out those that are
+ not permitted by the language being compiled.
+
+ Most of this routine is from build_reinterpret_cast.
+
+ The back end cannot call cp_convert (what was convert) because
+ conversions to/from basetypes may involve memory references
+ (vbases) and adding or subtracting small values (multiple
+ inheritance), but it calls convert from the constant folding code
+ on subtrees of already built trees after it has ripped them apart.
+
+ Also, if we ever support range variables, we'll probably also have to
+ do a little bit more work. */
+
+tree
+convert (tree type, tree expr)
+{
+ tree intype;
+
+ if (type == error_mark_node || expr == error_mark_node)
+ return error_mark_node;
+
+ intype = TREE_TYPE (expr);
+
+ if (POINTER_TYPE_P (type) && POINTER_TYPE_P (intype))
+ return fold_if_not_in_template (build_nop (type, expr));
+
+ return ocp_convert (type, expr, CONV_OLD_CONVERT,
+ LOOKUP_NORMAL|LOOKUP_NO_CONVERSION,
+ tf_warning_or_error);
+}
+
+/* Like cp_convert, except permit conversions to take place which
+ are not normally allowed due to access restrictions
+ (such as conversion from sub-type to private super-type). */
+
+tree
+convert_force (tree type, tree expr, int convtype, tsubst_flags_t complain)
+{
+ tree e = expr;
+ enum tree_code code = TREE_CODE (type);
+
+ if (code == REFERENCE_TYPE)
+ return (fold_if_not_in_template
+ (convert_to_reference (type, e, CONV_C_CAST, 0,
+ NULL_TREE, complain)));
+
+ if (code == POINTER_TYPE)
+ return fold_if_not_in_template (convert_to_pointer_force (type, e,
+ complain));
+
+ /* From typeck.c convert_for_assignment */
+ if (((TYPE_PTR_P (TREE_TYPE (e)) && TREE_CODE (e) == ADDR_EXPR
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (e))) == METHOD_TYPE)
+ || integer_zerop (e)
+ || TYPE_PTRMEMFUNC_P (TREE_TYPE (e)))
+ && TYPE_PTRMEMFUNC_P (type))
+ /* compatible pointer to member functions. */
+ return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1,
+ /*c_cast_p=*/1, complain);
+
+ return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL, complain);
+}
+
+/* Convert an aggregate EXPR to type XTYPE. If a conversion
+ exists, return the attempted conversion. This may
+ return ERROR_MARK_NODE if the conversion is not
+ allowed (references private members, etc).
+ If no conversion exists, NULL_TREE is returned.
+
+ FIXME: Ambiguity checking is wrong. Should choose one by the implicit
+ object parameter, or by the second standard conversion sequence if
+ that doesn't do it. This will probably wait for an overloading rewrite.
+ (jason 8/9/95) */
+
+static tree
+build_type_conversion (tree xtype, tree expr)
+{
+ /* C++: check to see if we can convert this aggregate type
+ into the required type. */
+ return build_user_type_conversion (xtype, expr, LOOKUP_NORMAL,
+ tf_warning_or_error);
+}
+
+/* Convert the given EXPR to one of a group of types suitable for use in an
+ expression. DESIRES is a combination of various WANT_* flags (q.v.)
+ which indicates which types are suitable. If COMPLAIN is true, complain
+ about ambiguity; otherwise, the caller will deal with it. */
+
+tree
+build_expr_type_conversion (int desires, tree expr, bool complain)
+{
+ tree basetype = TREE_TYPE (expr);
+ tree conv = NULL_TREE;
+ tree winner = NULL_TREE;
+
+ if (expr == null_node
+ && (desires & WANT_INT)
+ && !(desires & WANT_NULL))
+ {
+ source_location loc =
+ expansion_point_location_if_in_system_header (input_location);
+
+ warning_at (loc, OPT_Wconversion_null,
+ "converting NULL to non-pointer type");
+ }
+
+ if (basetype == error_mark_node)
+ return error_mark_node;
+
+ if (! MAYBE_CLASS_TYPE_P (basetype))
+ switch (TREE_CODE (basetype))
+ {
+ case INTEGER_TYPE:
+ if ((desires & WANT_NULL) && null_ptr_cst_p (expr))
+ return expr;
+ /* else fall through... */
+
+ case BOOLEAN_TYPE:
+ return (desires & WANT_INT) ? expr : NULL_TREE;
+ case ENUMERAL_TYPE:
+ return (desires & WANT_ENUM) ? expr : NULL_TREE;
+ case REAL_TYPE:
+ return (desires & WANT_FLOAT) ? expr : NULL_TREE;
+ case POINTER_TYPE:
+ return (desires & WANT_POINTER) ? expr : NULL_TREE;
+
+ case FUNCTION_TYPE:
+ case ARRAY_TYPE:
+ return (desires & WANT_POINTER) ? decay_conversion (expr,
+ tf_warning_or_error)
+ : NULL_TREE;
+
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ if ((desires & WANT_VECTOR_OR_COMPLEX) == 0)
+ return NULL_TREE;
+ switch (TREE_CODE (TREE_TYPE (basetype)))
+ {
+ case INTEGER_TYPE:
+ case BOOLEAN_TYPE:
+ return (desires & WANT_INT) ? expr : NULL_TREE;
+ case ENUMERAL_TYPE:
+ return (desires & WANT_ENUM) ? expr : NULL_TREE;
+ case REAL_TYPE:
+ return (desires & WANT_FLOAT) ? expr : NULL_TREE;
+ default:
+ return NULL_TREE;
+ }
+
+ default:
+ return NULL_TREE;
+ }
+
+ /* The code for conversions from class type is currently only used for
+ delete expressions. Other expressions are handled by build_new_op. */
+ if (!complete_type_or_maybe_complain (basetype, expr, complain))
+ return error_mark_node;
+ if (!TYPE_HAS_CONVERSION (basetype))
+ return NULL_TREE;
+
+ for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
+ {
+ int win = 0;
+ tree candidate;
+ tree cand = TREE_VALUE (conv);
+ cand = OVL_CURRENT (cand);
+
+ if (winner && winner == cand)
+ continue;
+
+ if (DECL_NONCONVERTING_P (cand))
+ continue;
+
+ candidate = non_reference (TREE_TYPE (TREE_TYPE (cand)));
+
+ switch (TREE_CODE (candidate))
+ {
+ case BOOLEAN_TYPE:
+ case INTEGER_TYPE:
+ win = (desires & WANT_INT); break;
+ case ENUMERAL_TYPE:
+ win = (desires & WANT_ENUM); break;
+ case REAL_TYPE:
+ win = (desires & WANT_FLOAT); break;
+ case POINTER_TYPE:
+ win = (desires & WANT_POINTER); break;
+
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ if ((desires & WANT_VECTOR_OR_COMPLEX) == 0)
+ break;
+ switch (TREE_CODE (TREE_TYPE (candidate)))
+ {
+ case BOOLEAN_TYPE:
+ case INTEGER_TYPE:
+ win = (desires & WANT_INT); break;
+ case ENUMERAL_TYPE:
+ win = (desires & WANT_ENUM); break;
+ case REAL_TYPE:
+ win = (desires & WANT_FLOAT); break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ /* A wildcard could be instantiated to match any desired
+ type, but we can't deduce the template argument. */
+ if (WILDCARD_TYPE_P (candidate))
+ win = true;
+ break;
+ }
+
+ if (win)
+ {
+ if (TREE_CODE (cand) == TEMPLATE_DECL)
+ {
+ if (complain)
+ error ("default type conversion can't deduce template"
+ " argument for %qD", cand);
+ return error_mark_node;
+ }
+
+ if (winner)
+ {
+ tree winner_type
+ = non_reference (TREE_TYPE (TREE_TYPE (winner)));
+
+ if (!same_type_ignoring_top_level_qualifiers_p (winner_type,
+ candidate))
+ {
+ if (complain)
+ {
+ error ("ambiguous default type conversion from %qT",
+ basetype);
+ error (" candidate conversions include %qD and %qD",
+ winner, cand);
+ }
+ return error_mark_node;
+ }
+ }
+
+ winner = cand;
+ }
+ }
+
+ if (winner)
+ {
+ tree type = non_reference (TREE_TYPE (TREE_TYPE (winner)));
+ return build_user_type_conversion (type, expr, LOOKUP_NORMAL,
+ tf_warning_or_error);
+ }
+
+ return NULL_TREE;
+}
+
+/* Implements integral promotion (4.1) and float->double promotion. */
+
+tree
+type_promotes_to (tree type)
+{
+ tree promoted_type;
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ type = TYPE_MAIN_VARIANT (type);
+
+ /* Check for promotions of target-defined types first. */
+ promoted_type = targetm.promoted_type (type);
+ if (promoted_type)
+ return promoted_type;
+
+ /* bool always promotes to int (not unsigned), even if it's the same
+ size. */
+ if (TREE_CODE (type) == BOOLEAN_TYPE)
+ type = integer_type_node;
+
+ /* Scoped enums don't promote, but pretend they do for backward ABI bug
+ compatibility wrt varargs. */
+ else if (SCOPED_ENUM_P (type) && abi_version_at_least (6))
+ ;
+
+ /* Normally convert enums to int, but convert wide enums to something
+ wider. */
+ else if (TREE_CODE (type) == ENUMERAL_TYPE
+ || type == char16_type_node
+ || type == char32_type_node
+ || type == wchar_type_node)
+ {
+ int precision = MAX (TYPE_PRECISION (type),
+ TYPE_PRECISION (integer_type_node));
+ tree totype = c_common_type_for_size (precision, 0);
+ if (SCOPED_ENUM_P (type))
+ warning (OPT_Wabi, "scoped enum %qT will not promote to an integral "
+ "type in a future version of GCC", type);
+ if (TREE_CODE (type) == ENUMERAL_TYPE)
+ type = ENUM_UNDERLYING_TYPE (type);
+ if (TYPE_UNSIGNED (type)
+ && ! int_fits_type_p (TYPE_MAX_VALUE (type), totype))
+ type = c_common_type_for_size (precision, 1);
+ else
+ type = totype;
+ }
+ else if (c_promoting_integer_type_p (type))
+ {
+ /* Retain unsignedness if really not getting bigger. */
+ if (TYPE_UNSIGNED (type)
+ && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
+ type = unsigned_type_node;
+ else
+ type = integer_type_node;
+ }
+ else if (type == float_type_node)
+ type = double_type_node;
+
+ return type;
+}
+
+/* The routines below this point are carefully written to conform to
+ the standard. They use the same terminology, and follow the rules
+ closely. Although they are used only in pt.c at the moment, they
+ should presumably be used everywhere in the future. */
+
+/* Attempt to perform qualification conversions on EXPR to convert it
+ to TYPE. Return the resulting expression, or error_mark_node if
+ the conversion was impossible. */
+
+tree
+perform_qualification_conversions (tree type, tree expr)
+{
+ tree expr_type;
+
+ expr_type = TREE_TYPE (expr);
+
+ if (same_type_p (type, expr_type))
+ return expr;
+ else if (TYPE_PTR_P (type) && TYPE_PTR_P (expr_type)
+ && comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (expr_type)))
+ return build_nop (type, expr);
+ else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (expr_type)
+ && same_type_p (TYPE_PTRMEM_CLASS_TYPE (type),
+ TYPE_PTRMEM_CLASS_TYPE (expr_type))
+ && comp_ptr_ttypes (TYPE_PTRMEM_POINTED_TO_TYPE (type),
+ TYPE_PTRMEM_POINTED_TO_TYPE (expr_type)))
+ return build_nop (type, expr);
+ else
+ return error_mark_node;
+}
diff --git a/gcc-4.9/gcc/cp/cxx-pretty-print.c b/gcc-4.9/gcc/cp/cxx-pretty-print.c
new file mode 100644
index 000000000..c39fb7d71
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cxx-pretty-print.c
@@ -0,0 +1,2433 @@
+/* Implementation of subroutines for the GNU C++ pretty-printer.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "intl.h"
+#include "cp-tree.h"
+#include "cxx-pretty-print.h"
+#include "tree-pretty-print.h"
+
+static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
+static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
+static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
+static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
+static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
+static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
+static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
+static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
+static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
+static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
+
+
+static inline void
+pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
+{
+ const char *p = pp_last_position_in_text (pp);
+
+ if (p != NULL && *p == c)
+ pp_cxx_whitespace (pp);
+ pp_character (pp, c);
+ pp->padding = pp_none;
+}
+
+#define pp_cxx_expression_list(PP, T) \
+ pp_c_expression_list (PP, T)
+#define pp_cxx_space_for_pointer_operator(PP, T) \
+ pp_c_space_for_pointer_operator (PP, T)
+#define pp_cxx_init_declarator(PP, T) \
+ pp_c_init_declarator (PP, T)
+#define pp_cxx_call_argument_list(PP, T) \
+ pp_c_call_argument_list (PP, T)
+
+void
+pp_cxx_colon_colon (cxx_pretty_printer *pp)
+{
+ pp_colon_colon (pp);
+ pp->padding = pp_none;
+}
+
+void
+pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
+{
+ pp_cxx_nonconsecutive_character (pp, '<');
+}
+
+void
+pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
+{
+ pp_cxx_nonconsecutive_character (pp, '>');
+}
+
+void
+pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
+{
+ pp_separate_with (pp, c);
+ pp->padding = pp_none;
+}
+
+/* Expressions. */
+
+static inline bool
+is_destructor_name (tree name)
+{
+ return name == complete_dtor_identifier
+ || name == base_dtor_identifier
+ || name == deleting_dtor_identifier;
+}
+
+/* conversion-function-id:
+ operator conversion-type-id
+
+ conversion-type-id:
+ type-specifier-seq conversion-declarator(opt)
+
+ conversion-declarator:
+ ptr-operator conversion-declarator(opt) */
+
+static inline void
+pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_ws_string (pp, "operator");
+ pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
+}
+
+static inline void
+pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
+ pp_cxx_begin_template_argument_list (pp);
+ pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
+ pp_cxx_end_template_argument_list (pp);
+}
+
+/* Prints the unqualified part of the id-expression T.
+
+ unqualified-id:
+ identifier
+ operator-function-id
+ conversion-function-id
+ ~ class-name
+ template-id */
+
+static void
+pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+ switch (code)
+ {
+ case RESULT_DECL:
+ pp->translate_string ("<return-value>");
+ break;
+
+ case OVERLOAD:
+ t = OVL_CURRENT (t);
+ case VAR_DECL:
+ case PARM_DECL:
+ case CONST_DECL:
+ case TYPE_DECL:
+ case FUNCTION_DECL:
+ case NAMESPACE_DECL:
+ case FIELD_DECL:
+ case LABEL_DECL:
+ case USING_DECL:
+ case TEMPLATE_DECL:
+ t = DECL_NAME (t);
+
+ case IDENTIFIER_NODE:
+ if (t == NULL)
+ pp->translate_string ("<unnamed>");
+ else if (IDENTIFIER_TYPENAME_P (t))
+ pp_cxx_conversion_function_id (pp, t);
+ else
+ {
+ if (is_destructor_name (t))
+ {
+ pp_complement (pp);
+ /* FIXME: Why is this necessary? */
+ if (TREE_TYPE (t))
+ t = constructor_name (TREE_TYPE (t));
+ }
+ pp_cxx_tree_identifier (pp, t);
+ }
+ break;
+
+ case TEMPLATE_ID_EXPR:
+ pp_cxx_template_id (pp, t);
+ break;
+
+ case BASELINK:
+ pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ case TYPENAME_TYPE:
+ case UNBOUND_CLASS_TEMPLATE:
+ pp_cxx_unqualified_id (pp, TYPE_NAME (t));
+ if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
+ {
+ pp_cxx_begin_template_argument_list (pp);
+ pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
+ (CLASSTYPE_TI_ARGS (t)));
+ pp_cxx_end_template_argument_list (pp);
+ }
+ break;
+
+ case BIT_NOT_EXPR:
+ pp_cxx_complement (pp);
+ pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ if (TYPE_IDENTIFIER (t))
+ pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
+ else
+ pp_cxx_canonical_template_parameter (pp, t);
+ break;
+
+ case TEMPLATE_PARM_INDEX:
+ pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
+ break;
+
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
+ pp_cxx_begin_template_argument_list (pp);
+ pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
+ pp_cxx_end_template_argument_list (pp);
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ break;
+ }
+}
+
+/* Pretty-print out the token sequence ":: template" in template codes
+ where it is needed to "inline declare" the (following) member as
+ a template. This situation arises when SCOPE of T is dependent
+ on template parameters. */
+
+static inline void
+pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
+{
+ if (TREE_CODE (t) == TEMPLATE_ID_EXPR
+ && TYPE_P (scope) && dependent_type_p (scope))
+ pp_cxx_ws_string (pp, "template");
+}
+
+/* nested-name-specifier:
+ class-or-namespace-name :: nested-name-specifier(opt)
+ class-or-namespace-name :: template nested-name-specifier */
+
+static void
+pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
+{
+ if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
+ {
+ tree scope = get_containing_scope (t);
+ pp_cxx_nested_name_specifier (pp, scope);
+ pp_cxx_template_keyword_if_needed (pp, scope, t);
+ pp_cxx_unqualified_id (pp, t);
+ pp_cxx_colon_colon (pp);
+ }
+}
+
+/* qualified-id:
+ nested-name-specifier template(opt) unqualified-id */
+
+static void
+pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ /* A pointer-to-member is always qualified. */
+ case PTRMEM_CST:
+ pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
+ pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
+ break;
+
+ /* In Standard C++, functions cannot possibly be used as
+ nested-name-specifiers. However, there are situations where
+ is "makes sense" to output the surrounding function name for the
+ purpose of emphasizing on the scope kind. Just printing the
+ function name might not be sufficient as it may be overloaded; so,
+ we decorate the function with its signature too.
+ FIXME: This is probably the wrong pretty-printing for conversion
+ functions and some function templates. */
+ case OVERLOAD:
+ t = OVL_CURRENT (t);
+ case FUNCTION_DECL:
+ if (DECL_FUNCTION_MEMBER_P (t))
+ pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
+ pp_cxx_unqualified_id
+ (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
+ pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
+ break;
+
+ case OFFSET_REF:
+ case SCOPE_REF:
+ pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
+ pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
+ break;
+
+ default:
+ {
+ tree scope = get_containing_scope (t);
+ if (scope != pp->enclosing_scope)
+ {
+ pp_cxx_nested_name_specifier (pp, scope);
+ pp_cxx_template_keyword_if_needed (pp, scope, t);
+ }
+ pp_cxx_unqualified_id (pp, t);
+ }
+ break;
+ }
+}
+
+
+void
+cxx_pretty_printer::constant (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case STRING_CST:
+ {
+ const bool in_parens = PAREN_STRING_LITERAL_P (t);
+ if (in_parens)
+ pp_cxx_left_paren (this);
+ c_pretty_printer::constant (t);
+ if (in_parens)
+ pp_cxx_right_paren (this);
+ }
+ break;
+
+ case INTEGER_CST:
+ if (NULLPTR_TYPE_P (TREE_TYPE (t)))
+ {
+ pp_string (this, "nullptr");
+ break;
+ }
+ /* else fall through. */
+
+ default:
+ c_pretty_printer::constant (t);
+ break;
+ }
+}
+
+/* id-expression:
+ unqualified-id
+ qualified-id */
+
+void
+cxx_pretty_printer::id_expression (tree t)
+{
+ if (TREE_CODE (t) == OVERLOAD)
+ t = OVL_CURRENT (t);
+ if (DECL_P (t) && DECL_CONTEXT (t))
+ pp_cxx_qualified_id (this, t);
+ else
+ pp_cxx_unqualified_id (this, t);
+}
+
+/* user-defined literal:
+ literal ud-suffix */
+
+void
+pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
+{
+ pp->constant (USERDEF_LITERAL_VALUE (t));
+ pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
+}
+
+
+/* primary-expression:
+ literal
+ this
+ :: identifier
+ :: operator-function-id
+ :: qualifier-id
+ ( expression )
+ id-expression
+
+ GNU Extensions:
+ __builtin_va_arg ( assignment-expression , type-id )
+ __builtin_offsetof ( type-id, offsetof-expression )
+
+ __has_nothrow_assign ( type-id )
+ __has_nothrow_constructor ( type-id )
+ __has_nothrow_copy ( type-id )
+ __has_trivial_assign ( type-id )
+ __has_trivial_constructor ( type-id )
+ __has_trivial_copy ( type-id )
+ __has_trivial_destructor ( type-id )
+ __has_virtual_destructor ( type-id )
+ __is_abstract ( type-id )
+ __is_base_of ( type-id , type-id )
+ __is_class ( type-id )
+ __is_convertible_to ( type-id , type-id )
+ __is_empty ( type-id )
+ __is_enum ( type-id )
+ __is_literal_type ( type-id )
+ __is_pod ( type-id )
+ __is_polymorphic ( type-id )
+ __is_std_layout ( type-id )
+ __is_trivial ( type-id )
+ __is_union ( type-id ) */
+
+void
+cxx_pretty_printer::primary_expression (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case INTEGER_CST:
+ case REAL_CST:
+ case COMPLEX_CST:
+ case STRING_CST:
+ constant (t);
+ break;
+
+ case USERDEF_LITERAL:
+ pp_cxx_userdef_literal (this, t);
+ break;
+
+ case BASELINK:
+ t = BASELINK_FUNCTIONS (t);
+ case VAR_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ case FUNCTION_DECL:
+ case OVERLOAD:
+ case CONST_DECL:
+ case TEMPLATE_DECL:
+ id_expression (t);
+ break;
+
+ case RESULT_DECL:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ pp_cxx_unqualified_id (this, t);
+ break;
+
+ case STMT_EXPR:
+ pp_cxx_left_paren (this);
+ statement (STMT_EXPR_STMT (t));
+ pp_cxx_right_paren (this);
+ break;
+
+ case TRAIT_EXPR:
+ pp_cxx_trait_expression (this, t);
+ break;
+
+ case VA_ARG_EXPR:
+ pp_cxx_va_arg_expression (this, t);
+ break;
+
+ case OFFSETOF_EXPR:
+ pp_cxx_offsetof_expression (this, t);
+ break;
+
+ default:
+ c_pretty_printer::primary_expression (t);
+ break;
+ }
+}
+
+/* postfix-expression:
+ primary-expression
+ postfix-expression [ expression ]
+ postfix-expression ( expression-list(opt) )
+ simple-type-specifier ( expression-list(opt) )
+ typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
+ typename ::(opt) nested-name-specifier template(opt)
+ template-id ( expression-list(opt) )
+ postfix-expression . template(opt) ::(opt) id-expression
+ postfix-expression -> template(opt) ::(opt) id-expression
+ postfix-expression . pseudo-destructor-name
+ postfix-expression -> pseudo-destructor-name
+ postfix-expression ++
+ postfix-expression --
+ dynamic_cast < type-id > ( expression )
+ static_cast < type-id > ( expression )
+ reinterpret_cast < type-id > ( expression )
+ const_cast < type-id > ( expression )
+ typeid ( expression )
+ typeid ( type-id ) */
+
+void
+cxx_pretty_printer::postfix_expression (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+
+ switch (code)
+ {
+ case AGGR_INIT_EXPR:
+ case CALL_EXPR:
+ {
+ tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
+ : CALL_EXPR_FN (t));
+ tree saved_scope = enclosing_scope;
+ bool skipfirst = false;
+ tree arg;
+
+ if (TREE_CODE (fun) == ADDR_EXPR)
+ fun = TREE_OPERAND (fun, 0);
+
+ /* In templates, where there is no way to tell whether a given
+ call uses an actual member function. So the parser builds
+ FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
+ instantiation time. */
+ if (TREE_CODE (fun) != FUNCTION_DECL)
+ ;
+ else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
+ {
+ tree object = (code == AGGR_INIT_EXPR
+ ? (AGGR_INIT_VIA_CTOR_P (t)
+ ? AGGR_INIT_EXPR_SLOT (t)
+ : AGGR_INIT_EXPR_ARG (t, 0))
+ : CALL_EXPR_ARG (t, 0));
+
+ while (TREE_CODE (object) == NOP_EXPR)
+ object = TREE_OPERAND (object, 0);
+
+ if (TREE_CODE (object) == ADDR_EXPR)
+ object = TREE_OPERAND (object, 0);
+
+ if (!TYPE_PTR_P (TREE_TYPE (object)))
+ {
+ postfix_expression (object);
+ pp_cxx_dot (this);
+ }
+ else
+ {
+ postfix_expression (object);
+ pp_cxx_arrow (this);
+ }
+ skipfirst = true;
+ enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
+ }
+
+ postfix_expression (fun);
+ enclosing_scope = saved_scope;
+ pp_cxx_left_paren (this);
+ if (code == AGGR_INIT_EXPR)
+ {
+ aggr_init_expr_arg_iterator iter;
+ FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
+ {
+ if (skipfirst)
+ skipfirst = false;
+ else
+ {
+ expression (arg);
+ if (more_aggr_init_expr_args_p (&iter))
+ pp_cxx_separate_with (this, ',');
+ }
+ }
+ }
+ else
+ {
+ call_expr_arg_iterator iter;
+ FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
+ {
+ if (skipfirst)
+ skipfirst = false;
+ else
+ {
+ expression (arg);
+ if (more_call_expr_args_p (&iter))
+ pp_cxx_separate_with (this, ',');
+ }
+ }
+ }
+ pp_cxx_right_paren (this);
+ }
+ if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
+ {
+ pp_cxx_separate_with (this, ',');
+ postfix_expression (AGGR_INIT_EXPR_SLOT (t));
+ }
+ break;
+
+ case BASELINK:
+ case VAR_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ case FUNCTION_DECL:
+ case OVERLOAD:
+ case CONST_DECL:
+ case TEMPLATE_DECL:
+ case RESULT_DECL:
+ primary_expression (t);
+ break;
+
+ case DYNAMIC_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ if (code == DYNAMIC_CAST_EXPR)
+ pp_cxx_ws_string (this, "dynamic_cast");
+ else if (code == STATIC_CAST_EXPR)
+ pp_cxx_ws_string (this, "static_cast");
+ else if (code == REINTERPRET_CAST_EXPR)
+ pp_cxx_ws_string (this, "reinterpret_cast");
+ else
+ pp_cxx_ws_string (this, "const_cast");
+ pp_cxx_begin_template_argument_list (this);
+ type_id (TREE_TYPE (t));
+ pp_cxx_end_template_argument_list (this);
+ pp_left_paren (this);
+ expression (TREE_OPERAND (t, 0));
+ pp_right_paren (this);
+ break;
+
+ case EMPTY_CLASS_EXPR:
+ type_id (TREE_TYPE (t));
+ pp_left_paren (this);
+ pp_right_paren (this);
+ break;
+
+ case TYPEID_EXPR:
+ pp_cxx_typeid_expression (this, t);
+ break;
+
+ case PSEUDO_DTOR_EXPR:
+ postfix_expression (TREE_OPERAND (t, 0));
+ pp_cxx_dot (this);
+ if (TREE_OPERAND (t, 1))
+ {
+ pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
+ pp_cxx_colon_colon (this);
+ }
+ pp_complement (this);
+ pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
+ break;
+
+ case ARROW_EXPR:
+ postfix_expression (TREE_OPERAND (t, 0));
+ pp_cxx_arrow (this);
+ break;
+
+ default:
+ c_pretty_printer::postfix_expression (t);
+ break;
+ }
+}
+
+/* new-expression:
+ ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
+ ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
+
+ new-placement:
+ ( expression-list )
+
+ new-type-id:
+ type-specifier-seq new-declarator(opt)
+
+ new-declarator:
+ ptr-operator new-declarator(opt)
+ direct-new-declarator
+
+ direct-new-declarator
+ [ expression ]
+ direct-new-declarator [ constant-expression ]
+
+ new-initializer:
+ ( expression-list(opt) ) */
+
+static void
+pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+ tree type = TREE_OPERAND (t, 1);
+ tree init = TREE_OPERAND (t, 2);
+ switch (code)
+ {
+ case NEW_EXPR:
+ case VEC_NEW_EXPR:
+ if (NEW_EXPR_USE_GLOBAL (t))
+ pp_cxx_colon_colon (pp);
+ pp_cxx_ws_string (pp, "new");
+ if (TREE_OPERAND (t, 0))
+ {
+ pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
+ pp_space (pp);
+ }
+ if (TREE_CODE (type) == ARRAY_REF)
+ type = build_cplus_array_type
+ (TREE_OPERAND (type, 0),
+ build_index_type (fold_build2_loc (input_location,
+ MINUS_EXPR, integer_type_node,
+ TREE_OPERAND (type, 1),
+ integer_one_node)));
+ pp->type_id (type);
+ if (init)
+ {
+ pp_left_paren (pp);
+ if (TREE_CODE (init) == TREE_LIST)
+ pp_c_expression_list (pp, init);
+ else if (init == void_zero_node)
+ ; /* OK, empty initializer list. */
+ else
+ pp->expression (init);
+ pp_right_paren (pp);
+ }
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ }
+}
+
+/* delete-expression:
+ ::(opt) delete cast-expression
+ ::(opt) delete [ ] cast-expression */
+
+static void
+pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+ switch (code)
+ {
+ case DELETE_EXPR:
+ case VEC_DELETE_EXPR:
+ if (DELETE_EXPR_USE_GLOBAL (t))
+ pp_cxx_colon_colon (pp);
+ pp_cxx_ws_string (pp, "delete");
+ pp_space (pp);
+ if (code == VEC_DELETE_EXPR
+ || DELETE_EXPR_USE_VEC (t))
+ {
+ pp_left_bracket (pp);
+ pp_right_bracket (pp);
+ pp_space (pp);
+ }
+ pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ }
+}
+
+/* unary-expression:
+ postfix-expression
+ ++ cast-expression
+ -- cast-expression
+ unary-operator cast-expression
+ sizeof unary-expression
+ sizeof ( type-id )
+ sizeof ... ( identifier )
+ new-expression
+ delete-expression
+
+ unary-operator: one of
+ * & + - !
+
+ GNU extensions:
+ __alignof__ unary-expression
+ __alignof__ ( type-id ) */
+
+void
+cxx_pretty_printer::unary_expression (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+ switch (code)
+ {
+ case NEW_EXPR:
+ case VEC_NEW_EXPR:
+ pp_cxx_new_expression (this, t);
+ break;
+
+ case DELETE_EXPR:
+ case VEC_DELETE_EXPR:
+ pp_cxx_delete_expression (this, t);
+ break;
+
+ case SIZEOF_EXPR:
+ if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
+ {
+ pp_cxx_ws_string (this, "sizeof");
+ pp_cxx_ws_string (this, "...");
+ pp_cxx_whitespace (this);
+ pp_cxx_left_paren (this);
+ if (TYPE_P (TREE_OPERAND (t, 0)))
+ type_id (TREE_OPERAND (t, 0));
+ else
+ unary_expression (TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (this);
+ break;
+ }
+ /* Fall through */
+
+ case ALIGNOF_EXPR:
+ pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
+ pp_cxx_whitespace (this);
+ if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
+ {
+ pp_cxx_left_paren (this);
+ type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
+ pp_cxx_right_paren (this);
+ }
+ else if (TYPE_P (TREE_OPERAND (t, 0)))
+ {
+ pp_cxx_left_paren (this);
+ type_id (TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (this);
+ }
+ else
+ unary_expression (TREE_OPERAND (t, 0));
+ break;
+
+ case AT_ENCODE_EXPR:
+ pp_cxx_ws_string (this, "@encode");
+ pp_cxx_whitespace (this);
+ pp_cxx_left_paren (this);
+ type_id (TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (this);
+ break;
+
+ case NOEXCEPT_EXPR:
+ pp_cxx_ws_string (this, "noexcept");
+ pp_cxx_whitespace (this);
+ pp_cxx_left_paren (this);
+ expression (TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (this);
+ break;
+
+ case UNARY_PLUS_EXPR:
+ pp_plus (this);
+ pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
+ break;
+
+ default:
+ c_pretty_printer::unary_expression (t);
+ break;
+ }
+}
+
+/* cast-expression:
+ unary-expression
+ ( type-id ) cast-expression */
+
+static void
+pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
+ pp->type_id (TREE_TYPE (t));
+ pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
+ break;
+
+ default:
+ pp_c_cast_expression (pp, t);
+ break;
+ }
+}
+
+/* pm-expression:
+ cast-expression
+ pm-expression .* cast-expression
+ pm-expression ->* cast-expression */
+
+static void
+pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ /* Handle unfortunate OFFSET_REF overloading here. */
+ case OFFSET_REF:
+ if (TYPE_P (TREE_OPERAND (t, 0)))
+ {
+ pp_cxx_qualified_id (pp, t);
+ break;
+ }
+ /* Else fall through. */
+ case MEMBER_REF:
+ case DOTSTAR_EXPR:
+ pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
+ if (TREE_CODE (t) == MEMBER_REF)
+ pp_cxx_arrow (pp);
+ else
+ pp_cxx_dot (pp);
+ pp_star(pp);
+ pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
+ break;
+
+
+ default:
+ pp_cxx_cast_expression (pp, t);
+ break;
+ }
+}
+
+/* multiplicative-expression:
+ pm-expression
+ multiplicative-expression * pm-expression
+ multiplicative-expression / pm-expression
+ multiplicative-expression % pm-expression */
+
+void
+cxx_pretty_printer::multiplicative_expression (tree e)
+{
+ enum tree_code code = TREE_CODE (e);
+ switch (code)
+ {
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ multiplicative_expression (TREE_OPERAND (e, 0));
+ pp_space (this);
+ if (code == MULT_EXPR)
+ pp_star (this);
+ else if (code == TRUNC_DIV_EXPR)
+ pp_slash (this);
+ else
+ pp_modulo (this);
+ pp_space (this);
+ pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
+ break;
+
+ default:
+ pp_cxx_pm_expression (this, e);
+ break;
+ }
+}
+
+/* conditional-expression:
+ logical-or-expression
+ logical-or-expression ? expression : assignment-expression */
+
+void
+cxx_pretty_printer::conditional_expression (tree e)
+{
+ if (TREE_CODE (e) == COND_EXPR)
+ {
+ pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
+ pp_space (this);
+ pp_question (this);
+ pp_space (this);
+ expression (TREE_OPERAND (e, 1));
+ pp_space (this);
+ assignment_expression (TREE_OPERAND (e, 2));
+ }
+ else
+ pp_c_logical_or_expression (this, e);
+}
+
+/* Pretty-print a compound assignment operator token as indicated by T. */
+
+static void
+pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
+{
+ const char *op;
+
+ switch (TREE_CODE (t))
+ {
+ case NOP_EXPR:
+ op = "=";
+ break;
+
+ case PLUS_EXPR:
+ op = "+=";
+ break;
+
+ case MINUS_EXPR:
+ op = "-=";
+ break;
+
+ case TRUNC_DIV_EXPR:
+ op = "/=";
+ break;
+
+ case TRUNC_MOD_EXPR:
+ op = "%=";
+ break;
+
+ default:
+ op = get_tree_code_name (TREE_CODE (t));
+ break;
+ }
+
+ pp_cxx_ws_string (pp, op);
+}
+
+
+/* assignment-expression:
+ conditional-expression
+ logical-or-expression assignment-operator assignment-expression
+ throw-expression
+
+ throw-expression:
+ throw assignment-expression(opt)
+
+ assignment-operator: one of
+ = *= /= %= += -= >>= <<= &= ^= |= */
+
+void
+cxx_pretty_printer::assignment_expression (tree e)
+{
+ switch (TREE_CODE (e))
+ {
+ case MODIFY_EXPR:
+ case INIT_EXPR:
+ pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
+ pp_space (this);
+ pp_equal (this);
+ pp_space (this);
+ assignment_expression (TREE_OPERAND (e, 1));
+ break;
+
+ case THROW_EXPR:
+ pp_cxx_ws_string (this, "throw");
+ if (TREE_OPERAND (e, 0))
+ assignment_expression (TREE_OPERAND (e, 0));
+ break;
+
+ case MODOP_EXPR:
+ pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
+ pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
+ assignment_expression (TREE_OPERAND (e, 2));
+ break;
+
+ default:
+ conditional_expression (e);
+ break;
+ }
+}
+
+void
+cxx_pretty_printer::expression (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case STRING_CST:
+ case INTEGER_CST:
+ case REAL_CST:
+ case COMPLEX_CST:
+ constant (t);
+ break;
+
+ case USERDEF_LITERAL:
+ pp_cxx_userdef_literal (this, t);
+ break;
+
+ case RESULT_DECL:
+ pp_cxx_unqualified_id (this, t);
+ break;
+
+#if 0
+ case OFFSET_REF:
+#endif
+ case SCOPE_REF:
+ case PTRMEM_CST:
+ pp_cxx_qualified_id (this, t);
+ break;
+
+ case OVERLOAD:
+ t = OVL_CURRENT (t);
+ case VAR_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ case CONST_DECL:
+ case FUNCTION_DECL:
+ case BASELINK:
+ case TEMPLATE_DECL:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ case TEMPLATE_TEMPLATE_PARM:
+ case STMT_EXPR:
+ primary_expression (t);
+ break;
+
+ case CALL_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+#if 0
+ case MEMBER_REF:
+#endif
+ case EMPTY_CLASS_EXPR:
+ case TYPEID_EXPR:
+ case PSEUDO_DTOR_EXPR:
+ case AGGR_INIT_EXPR:
+ case ARROW_EXPR:
+ postfix_expression (t);
+ break;
+
+ case NEW_EXPR:
+ case VEC_NEW_EXPR:
+ pp_cxx_new_expression (this, t);
+ break;
+
+ case DELETE_EXPR:
+ case VEC_DELETE_EXPR:
+ pp_cxx_delete_expression (this, t);
+ break;
+
+ case SIZEOF_EXPR:
+ case ALIGNOF_EXPR:
+ case NOEXCEPT_EXPR:
+ unary_expression (t);
+ break;
+
+ case CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
+ pp_cxx_cast_expression (this, t);
+ break;
+
+ case OFFSET_REF:
+ case MEMBER_REF:
+ case DOTSTAR_EXPR:
+ pp_cxx_pm_expression (this, t);
+ break;
+
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ multiplicative_expression (t);
+ break;
+
+ case COND_EXPR:
+ conditional_expression (t);
+ break;
+
+ case MODIFY_EXPR:
+ case INIT_EXPR:
+ case THROW_EXPR:
+ case MODOP_EXPR:
+ assignment_expression (t);
+ break;
+
+ case NON_DEPENDENT_EXPR:
+ case MUST_NOT_THROW_EXPR:
+ expression (TREE_OPERAND (t, 0));
+ break;
+
+ case EXPR_PACK_EXPANSION:
+ expression (PACK_EXPANSION_PATTERN (t));
+ pp_cxx_ws_string (this, "...");
+ break;
+
+ case TEMPLATE_ID_EXPR:
+ pp_cxx_template_id (this, t);
+ break;
+
+ case NONTYPE_ARGUMENT_PACK:
+ {
+ tree args = ARGUMENT_PACK_ARGS (t);
+ int i, len = TREE_VEC_LENGTH (args);
+ for (i = 0; i < len; ++i)
+ {
+ if (i > 0)
+ pp_cxx_separate_with (this, ',');
+ expression (TREE_VEC_ELT (args, i));
+ }
+ }
+ break;
+
+ case LAMBDA_EXPR:
+ pp_cxx_ws_string (this, "<lambda>");
+ break;
+
+ case PAREN_EXPR:
+ pp_cxx_left_paren (this);
+ expression (TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (this);
+ break;
+
+ default:
+ c_pretty_printer::expression (t);
+ break;
+ }
+}
+
+
+/* Declarations. */
+
+/* function-specifier:
+ inline
+ virtual
+ explicit */
+
+void
+cxx_pretty_printer::function_specifier (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case FUNCTION_DECL:
+ if (DECL_VIRTUAL_P (t))
+ pp_cxx_ws_string (this, "virtual");
+ else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
+ pp_cxx_ws_string (this, "explicit");
+ else
+ c_pretty_printer::function_specifier (t);
+
+ default:
+ break;
+ }
+}
+
+/* decl-specifier-seq:
+ decl-specifier-seq(opt) decl-specifier
+
+ decl-specifier:
+ storage-class-specifier
+ type-specifier
+ function-specifier
+ friend
+ typedef */
+
+void
+cxx_pretty_printer::declaration_specifiers (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case CONST_DECL:
+ case FIELD_DECL:
+ storage_class_specifier (t);
+ declaration_specifiers (TREE_TYPE (t));
+ break;
+
+ case TYPE_DECL:
+ pp_cxx_ws_string (this, "typedef");
+ declaration_specifiers (TREE_TYPE (t));
+ break;
+
+ case FUNCTION_DECL:
+ /* Constructors don't have return types. And conversion functions
+ do not have a type-specifier in their return types. */
+ if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
+ function_specifier (t);
+ else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
+ declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
+ else
+ default:
+ c_pretty_printer::declaration_specifiers (t);
+ break;
+ }
+}
+
+/* simple-type-specifier:
+ ::(opt) nested-name-specifier(opt) type-name
+ ::(opt) nested-name-specifier(opt) template(opt) template-id
+ char
+ wchar_t
+ bool
+ short
+ int
+ long
+ signed
+ unsigned
+ float
+ double
+ void */
+
+void
+cxx_pretty_printer::simple_type_specifier (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ pp_cxx_qualified_id (this, t);
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ pp_cxx_unqualified_id (this, t);
+ break;
+
+ case TYPENAME_TYPE:
+ pp_cxx_ws_string (this, "typename");
+ pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
+ pp_cxx_unqualified_id (this, TYPE_NAME (t));
+ break;
+
+ default:
+ c_pretty_printer::simple_type_specifier (t);
+ break;
+ }
+}
+
+/* type-specifier-seq:
+ type-specifier type-specifier-seq(opt)
+
+ type-specifier:
+ simple-type-specifier
+ class-specifier
+ enum-specifier
+ elaborated-type-specifier
+ cv-qualifier */
+
+static void
+pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case TEMPLATE_DECL:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case TYPE_DECL:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp->simple_type_specifier (t);
+ break;
+
+ case METHOD_TYPE:
+ pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
+ pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
+ pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
+ break;
+
+ case DECLTYPE_TYPE:
+ pp_cxx_ws_string (pp, "decltype");
+ pp_cxx_left_paren (pp);
+ pp->expression (DECLTYPE_TYPE_EXPR (t));
+ pp_cxx_right_paren (pp);
+ break;
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ {
+ tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
+ pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
+ pp_cxx_whitespace (pp);
+ pp_cxx_ptr_operator (pp, t);
+ break;
+ }
+ /* else fall through */
+
+ default:
+ if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
+ pp_c_specifier_qualifier_list (pp, t);
+ }
+}
+
+/* ptr-operator:
+ * cv-qualifier-seq(opt)
+ &
+ ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
+
+static void
+pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
+{
+ if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
+ t = TREE_TYPE (t);
+ switch (TREE_CODE (t))
+ {
+ case REFERENCE_TYPE:
+ case POINTER_TYPE:
+ if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
+ pp_cxx_ptr_operator (pp, TREE_TYPE (t));
+ pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
+ if (TYPE_PTR_P (t))
+ {
+ pp_star (pp);
+ pp_cxx_cv_qualifier_seq (pp, t);
+ }
+ else
+ pp_ampersand (pp);
+ break;
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ {
+ pp_cxx_left_paren (pp);
+ pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
+ pp_star (pp);
+ break;
+ }
+ case OFFSET_TYPE:
+ if (TYPE_PTRMEM_P (t))
+ {
+ if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
+ pp_cxx_left_paren (pp);
+ pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
+ pp_star (pp);
+ pp_cxx_cv_qualifier_seq (pp, t);
+ break;
+ }
+ /* else fall through. */
+
+ default:
+ pp_unsupported_tree (pp, t);
+ break;
+ }
+}
+
+static inline tree
+pp_cxx_implicit_parameter_type (tree mf)
+{
+ return class_of_this_parm (TREE_TYPE (mf));
+}
+
+/*
+ parameter-declaration:
+ decl-specifier-seq declarator
+ decl-specifier-seq declarator = assignment-expression
+ decl-specifier-seq abstract-declarator(opt)
+ decl-specifier-seq abstract-declarator(opt) assignment-expression */
+
+static inline void
+pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
+{
+ pp->declaration_specifiers (t);
+ if (TYPE_P (t))
+ pp->abstract_declarator (t);
+ else
+ pp->declarator (t);
+}
+
+/* parameter-declaration-clause:
+ parameter-declaration-list(opt) ...(opt)
+ parameter-declaration-list , ...
+
+ parameter-declaration-list:
+ parameter-declaration
+ parameter-declaration-list , parameter-declaration */
+
+static void
+pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
+{
+ tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
+ tree types =
+ TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
+ const bool abstract = args == NULL || pp->flags & pp_c_flag_abstract;
+ bool first = true;
+
+ /* Skip artificial parameter for nonstatic member functions. */
+ if (TREE_CODE (t) == METHOD_TYPE)
+ types = TREE_CHAIN (types);
+
+ pp_cxx_left_paren (pp);
+ for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
+ {
+ if (!first)
+ pp_cxx_separate_with (pp, ',');
+ first = false;
+ pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
+ if (!abstract && pp->flags & pp_cxx_flag_default_argument)
+ {
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
+ pp->assignment_expression (TREE_PURPOSE (types));
+ }
+ }
+ pp_cxx_right_paren (pp);
+}
+
+/* exception-specification:
+ throw ( type-id-list(opt) )
+
+ type-id-list
+ type-id
+ type-id-list , type-id */
+
+static void
+pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
+{
+ tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
+ bool need_comma = false;
+
+ if (ex_spec == NULL)
+ return;
+ if (TREE_PURPOSE (ex_spec))
+ {
+ pp_cxx_ws_string (pp, "noexcept");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
+ pp_cxx_ws_string (pp, "<uninstantiated>");
+ else
+ pp->expression (TREE_PURPOSE (ex_spec));
+ pp_cxx_right_paren (pp);
+ return;
+ }
+ pp_cxx_ws_string (pp, "throw");
+ pp_cxx_left_paren (pp);
+ for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
+ {
+ tree type = TREE_VALUE (ex_spec);
+ tree argpack = NULL_TREE;
+ int i, len = 1;
+
+ if (ARGUMENT_PACK_P (type))
+ {
+ argpack = ARGUMENT_PACK_ARGS (type);
+ len = TREE_VEC_LENGTH (argpack);
+ }
+
+ for (i = 0; i < len; ++i)
+ {
+ if (argpack)
+ type = TREE_VEC_ELT (argpack, i);
+
+ if (need_comma)
+ pp_cxx_separate_with (pp, ',');
+ else
+ need_comma = true;
+
+ pp->type_id (type);
+ }
+ }
+ pp_cxx_right_paren (pp);
+}
+
+/* direct-declarator:
+ declarator-id
+ direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
+ exception-specification(opt)
+ direct-declaration [ constant-expression(opt) ]
+ ( declarator ) */
+
+void
+cxx_pretty_printer::direct_declarator (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case CONST_DECL:
+ case FIELD_DECL:
+ if (DECL_NAME (t))
+ {
+ pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
+
+ if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
+ || template_parameter_pack_p (t))
+ /* A function parameter pack or non-type template
+ parameter pack. */
+ pp_cxx_ws_string (this, "...");
+
+ id_expression (DECL_NAME (t));
+ }
+ abstract_declarator (TREE_TYPE (t));
+ break;
+
+ case FUNCTION_DECL:
+ pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
+ expression (t);
+ pp_cxx_parameter_declaration_clause (this, t);
+
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
+ {
+ padding = pp_before;
+ pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
+ }
+
+ pp_cxx_exception_specification (this, TREE_TYPE (t));
+ break;
+
+ case TYPENAME_TYPE:
+ case TEMPLATE_DECL:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ case TEMPLATE_TEMPLATE_PARM:
+ break;
+
+ default:
+ c_pretty_printer::direct_declarator (t);
+ break;
+ }
+}
+
+/* declarator:
+ direct-declarator
+ ptr-operator declarator */
+
+void
+cxx_pretty_printer::declarator (tree t)
+{
+ direct_declarator (t);
+}
+
+/* ctor-initializer:
+ : mem-initializer-list
+
+ mem-initializer-list:
+ mem-initializer
+ mem-initializer , mem-initializer-list
+
+ mem-initializer:
+ mem-initializer-id ( expression-list(opt) )
+
+ mem-initializer-id:
+ ::(opt) nested-name-specifier(opt) class-name
+ identifier */
+
+static void
+pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
+{
+ t = TREE_OPERAND (t, 0);
+ pp_cxx_whitespace (pp);
+ pp_colon (pp);
+ pp_cxx_whitespace (pp);
+ for (; t; t = TREE_CHAIN (t))
+ {
+ tree purpose = TREE_PURPOSE (t);
+ bool is_pack = PACK_EXPANSION_P (purpose);
+
+ if (is_pack)
+ pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
+ else
+ pp->primary_expression (purpose);
+ pp_cxx_call_argument_list (pp, TREE_VALUE (t));
+ if (is_pack)
+ pp_cxx_ws_string (pp, "...");
+ if (TREE_CHAIN (t))
+ pp_cxx_separate_with (pp, ',');
+ }
+}
+
+/* function-definition:
+ decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
+ decl-specifier-seq(opt) declarator function-try-block */
+
+static void
+pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
+{
+ tree saved_scope = pp->enclosing_scope;
+ pp->declaration_specifiers (t);
+ pp->declarator (t);
+ pp_needs_newline (pp) = true;
+ pp->enclosing_scope = DECL_CONTEXT (t);
+ if (DECL_SAVED_TREE (t))
+ pp->statement (DECL_SAVED_TREE (t));
+ else
+ pp_cxx_semicolon (pp);
+ pp_newline_and_flush (pp);
+ pp->enclosing_scope = saved_scope;
+}
+
+/* abstract-declarator:
+ ptr-operator abstract-declarator(opt)
+ direct-abstract-declarator */
+
+void
+cxx_pretty_printer::abstract_declarator (tree t)
+{
+ if (TYPE_PTRMEM_P (t))
+ pp_cxx_right_paren (this);
+ else if (POINTER_TYPE_P (t))
+ {
+ if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
+ || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
+ pp_cxx_right_paren (this);
+ t = TREE_TYPE (t);
+ }
+ direct_abstract_declarator (t);
+}
+
+/* direct-abstract-declarator:
+ direct-abstract-declarator(opt) ( parameter-declaration-clause )
+ cv-qualifier-seq(opt) exception-specification(opt)
+ direct-abstract-declarator(opt) [ constant-expression(opt) ]
+ ( abstract-declarator ) */
+
+void
+cxx_pretty_printer::direct_abstract_declarator (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case REFERENCE_TYPE:
+ abstract_declarator (t);
+ break;
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
+ break;
+
+ case METHOD_TYPE:
+ case FUNCTION_TYPE:
+ pp_cxx_parameter_declaration_clause (this, t);
+ direct_abstract_declarator (TREE_TYPE (t));
+ if (TREE_CODE (t) == METHOD_TYPE)
+ {
+ padding = pp_before;
+ pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
+ }
+ pp_cxx_exception_specification (this, t);
+ break;
+
+ case TYPENAME_TYPE:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ case UNBOUND_CLASS_TEMPLATE:
+ break;
+
+ default:
+ c_pretty_printer::direct_abstract_declarator (t);
+ break;
+ }
+}
+
+/* type-id:
+ type-specifier-seq abstract-declarator(opt) */
+
+void
+cxx_pretty_printer::type_id (tree t)
+{
+ pp_flags saved_flags = flags;
+ flags |= pp_c_flag_abstract;
+
+ switch (TREE_CODE (t))
+ {
+ case TYPE_DECL:
+ case UNION_TYPE:
+ case RECORD_TYPE:
+ case ENUMERAL_TYPE:
+ case TYPENAME_TYPE:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ case UNBOUND_CLASS_TEMPLATE:
+ case TEMPLATE_TEMPLATE_PARM:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ case TEMPLATE_DECL:
+ case TYPEOF_TYPE:
+ case UNDERLYING_TYPE:
+ case DECLTYPE_TYPE:
+ case TEMPLATE_ID_EXPR:
+ pp_cxx_type_specifier_seq (this, t);
+ break;
+
+ case TYPE_PACK_EXPANSION:
+ type_id (PACK_EXPANSION_PATTERN (t));
+ pp_cxx_ws_string (this, "...");
+ break;
+
+ default:
+ c_pretty_printer::type_id (t);
+ break;
+ }
+
+ flags = saved_flags;
+}
+
+/* template-argument-list:
+ template-argument ...(opt)
+ template-argument-list, template-argument ...(opt)
+
+ template-argument:
+ assignment-expression
+ type-id
+ template-name */
+
+static void
+pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
+{
+ int i;
+ bool need_comma = false;
+
+ if (t == NULL)
+ return;
+ for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
+ {
+ tree arg = TREE_VEC_ELT (t, i);
+ tree argpack = NULL_TREE;
+ int idx, len = 1;
+
+ if (ARGUMENT_PACK_P (arg))
+ {
+ argpack = ARGUMENT_PACK_ARGS (arg);
+ len = TREE_VEC_LENGTH (argpack);
+ }
+
+ for (idx = 0; idx < len; idx++)
+ {
+ if (argpack)
+ arg = TREE_VEC_ELT (argpack, idx);
+
+ if (need_comma)
+ pp_cxx_separate_with (pp, ',');
+ else
+ need_comma = true;
+
+ if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
+ && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
+ pp->type_id (arg);
+ else
+ pp->expression (arg);
+ }
+ }
+}
+
+
+static void
+pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
+{
+ t = DECL_EXPR_DECL (t);
+ pp_cxx_type_specifier_seq (pp, t);
+ if (TYPE_P (t))
+ pp->abstract_declarator (t);
+ else
+ pp->declarator (t);
+}
+
+/* Statements. */
+
+void
+cxx_pretty_printer::statement (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case CTOR_INITIALIZER:
+ pp_cxx_ctor_initializer (this, t);
+ break;
+
+ case USING_STMT:
+ pp_cxx_ws_string (this, "using");
+ pp_cxx_ws_string (this, "namespace");
+ if (DECL_CONTEXT (t))
+ pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
+ pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
+ break;
+
+ case USING_DECL:
+ pp_cxx_ws_string (this, "using");
+ pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
+ pp_cxx_unqualified_id (this, DECL_NAME (t));
+ break;
+
+ case EH_SPEC_BLOCK:
+ break;
+
+ /* try-block:
+ try compound-statement handler-seq */
+ case TRY_BLOCK:
+ pp_maybe_newline_and_indent (this, 0);
+ pp_cxx_ws_string (this, "try");
+ pp_newline_and_indent (this, 3);
+ statement (TRY_STMTS (t));
+ pp_newline_and_indent (this, -3);
+ if (CLEANUP_P (t))
+ ;
+ else
+ statement (TRY_HANDLERS (t));
+ break;
+
+ /*
+ handler-seq:
+ handler handler-seq(opt)
+
+ handler:
+ catch ( exception-declaration ) compound-statement
+
+ exception-declaration:
+ type-specifier-seq declarator
+ type-specifier-seq abstract-declarator
+ ... */
+ case HANDLER:
+ pp_cxx_ws_string (this, "catch");
+ pp_cxx_left_paren (this);
+ pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
+ pp_cxx_right_paren (this);
+ pp_indentation (this) += 3;
+ pp_needs_newline (this) = true;
+ statement (HANDLER_BODY (t));
+ pp_indentation (this) -= 3;
+ pp_needs_newline (this) = true;
+ break;
+
+ /* selection-statement:
+ if ( expression ) statement
+ if ( expression ) statement else statement */
+ case IF_STMT:
+ pp_cxx_ws_string (this, "if");
+ pp_cxx_whitespace (this);
+ pp_cxx_left_paren (this);
+ expression (IF_COND (t));
+ pp_cxx_right_paren (this);
+ pp_newline_and_indent (this, 2);
+ statement (THEN_CLAUSE (t));
+ pp_newline_and_indent (this, -2);
+ if (ELSE_CLAUSE (t))
+ {
+ tree else_clause = ELSE_CLAUSE (t);
+ pp_cxx_ws_string (this, "else");
+ if (TREE_CODE (else_clause) == IF_STMT)
+ pp_cxx_whitespace (this);
+ else
+ pp_newline_and_indent (this, 2);
+ statement (else_clause);
+ if (TREE_CODE (else_clause) != IF_STMT)
+ pp_newline_and_indent (this, -2);
+ }
+ break;
+
+ case SWITCH_STMT:
+ pp_cxx_ws_string (this, "switch");
+ pp_space (this);
+ pp_cxx_left_paren (this);
+ expression (SWITCH_STMT_COND (t));
+ pp_cxx_right_paren (this);
+ pp_indentation (this) += 3;
+ pp_needs_newline (this) = true;
+ statement (SWITCH_STMT_BODY (t));
+ pp_newline_and_indent (this, -3);
+ break;
+
+ /* iteration-statement:
+ while ( expression ) statement
+ do statement while ( expression ) ;
+ for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
+ for ( declaration expression(opt) ; expression(opt) ) statement */
+ case WHILE_STMT:
+ pp_cxx_ws_string (this, "while");
+ pp_space (this);
+ pp_cxx_left_paren (this);
+ expression (WHILE_COND (t));
+ pp_cxx_right_paren (this);
+ pp_newline_and_indent (this, 3);
+ statement (WHILE_BODY (t));
+ pp_indentation (this) -= 3;
+ pp_needs_newline (this) = true;
+ break;
+
+ case DO_STMT:
+ pp_cxx_ws_string (this, "do");
+ pp_newline_and_indent (this, 3);
+ statement (DO_BODY (t));
+ pp_newline_and_indent (this, -3);
+ pp_cxx_ws_string (this, "while");
+ pp_space (this);
+ pp_cxx_left_paren (this);
+ expression (DO_COND (t));
+ pp_cxx_right_paren (this);
+ pp_cxx_semicolon (this);
+ pp_needs_newline (this) = true;
+ break;
+
+ case FOR_STMT:
+ pp_cxx_ws_string (this, "for");
+ pp_space (this);
+ pp_cxx_left_paren (this);
+ if (FOR_INIT_STMT (t))
+ statement (FOR_INIT_STMT (t));
+ else
+ pp_cxx_semicolon (this);
+ pp_needs_newline (this) = false;
+ pp_cxx_whitespace (this);
+ if (FOR_COND (t))
+ expression (FOR_COND (t));
+ pp_cxx_semicolon (this);
+ pp_needs_newline (this) = false;
+ pp_cxx_whitespace (this);
+ if (FOR_EXPR (t))
+ expression (FOR_EXPR (t));
+ pp_cxx_right_paren (this);
+ pp_newline_and_indent (this, 3);
+ statement (FOR_BODY (t));
+ pp_indentation (this) -= 3;
+ pp_needs_newline (this) = true;
+ break;
+
+ case RANGE_FOR_STMT:
+ pp_cxx_ws_string (this, "for");
+ pp_space (this);
+ pp_cxx_left_paren (this);
+ statement (RANGE_FOR_DECL (t));
+ pp_space (this);
+ pp_needs_newline (this) = false;
+ pp_colon (this);
+ pp_space (this);
+ statement (RANGE_FOR_EXPR (t));
+ pp_cxx_right_paren (this);
+ pp_newline_and_indent (this, 3);
+ statement (FOR_BODY (t));
+ pp_indentation (this) -= 3;
+ pp_needs_newline (this) = true;
+ break;
+
+ /* jump-statement:
+ goto identifier;
+ continue ;
+ return expression(opt) ; */
+ case BREAK_STMT:
+ case CONTINUE_STMT:
+ pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
+ pp_cxx_semicolon (this);
+ pp_needs_newline (this) = true;
+ break;
+
+ /* expression-statement:
+ expression(opt) ; */
+ case EXPR_STMT:
+ expression (EXPR_STMT_EXPR (t));
+ pp_cxx_semicolon (this);
+ pp_needs_newline (this) = true;
+ break;
+
+ case CLEANUP_STMT:
+ pp_cxx_ws_string (this, "try");
+ pp_newline_and_indent (this, 2);
+ statement (CLEANUP_BODY (t));
+ pp_newline_and_indent (this, -2);
+ pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
+ pp_newline_and_indent (this, 2);
+ statement (CLEANUP_EXPR (t));
+ pp_newline_and_indent (this, -2);
+ break;
+
+ case STATIC_ASSERT:
+ declaration (t);
+ break;
+
+ default:
+ c_pretty_printer::statement (t);
+ break;
+ }
+}
+
+/* original-namespace-definition:
+ namespace identifier { namespace-body }
+
+ As an edge case, we also handle unnamed namespace definition here. */
+
+static void
+pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_ws_string (pp, "namespace");
+ if (DECL_CONTEXT (t))
+ pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
+ if (DECL_NAME (t))
+ pp_cxx_unqualified_id (pp, t);
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_brace (pp);
+ /* We do not print the namespace-body. */
+ pp_cxx_whitespace (pp);
+ pp_cxx_right_brace (pp);
+}
+
+/* namespace-alias:
+ identifier
+
+ namespace-alias-definition:
+ namespace identifier = qualified-namespace-specifier ;
+
+ qualified-namespace-specifier:
+ ::(opt) nested-name-specifier(opt) namespace-name */
+
+static void
+pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_ws_string (pp, "namespace");
+ if (DECL_CONTEXT (t))
+ pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
+ pp_cxx_unqualified_id (pp, t);
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
+ if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
+ pp_cxx_nested_name_specifier (pp,
+ DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
+ pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
+ pp_cxx_semicolon (pp);
+}
+
+/* simple-declaration:
+ decl-specifier-seq(opt) init-declarator-list(opt) */
+
+static void
+pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
+{
+ pp->declaration_specifiers (t);
+ pp_cxx_init_declarator (pp, t);
+ pp_cxx_semicolon (pp);
+ pp_needs_newline (pp) = true;
+}
+
+/*
+ template-parameter-list:
+ template-parameter
+ template-parameter-list , template-parameter */
+
+static inline void
+pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
+{
+ const int n = TREE_VEC_LENGTH (t);
+ int i;
+ for (i = 0; i < n; ++i)
+ {
+ if (i)
+ pp_cxx_separate_with (pp, ',');
+ pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
+ }
+}
+
+/* template-parameter:
+ type-parameter
+ parameter-declaration
+
+ type-parameter:
+ class ...(opt) identifier(opt)
+ class identifier(opt) = type-id
+ typename identifier(opt)
+ typename ...(opt) identifier(opt) = type-id
+ template < template-parameter-list > class ...(opt) identifier(opt)
+ template < template-parameter-list > class identifier(opt) = template-name */
+
+static void
+pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
+{
+ tree parameter = TREE_VALUE (t);
+ switch (TREE_CODE (parameter))
+ {
+ case TYPE_DECL:
+ pp_cxx_ws_string (pp, "class");
+ if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+ pp_cxx_ws_string (pp, "...");
+ if (DECL_NAME (parameter))
+ pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
+ /* FIXME: Check if we should print also default argument. */
+ break;
+
+ case PARM_DECL:
+ pp_cxx_parameter_declaration (pp, parameter);
+ break;
+
+ case TEMPLATE_DECL:
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ break;
+ }
+}
+
+/* Pretty-print a template parameter in the canonical form
+ "template-parameter-<level>-<position in parameter list>". */
+
+void
+pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
+{
+ const enum tree_code code = TREE_CODE (parm);
+
+ /* Brings type template parameters to the canonical forms. */
+ if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
+ || code == BOUND_TEMPLATE_TEMPLATE_PARM)
+ parm = TEMPLATE_TYPE_PARM_INDEX (parm);
+
+ pp_cxx_begin_template_argument_list (pp);
+ pp->translate_string ("template-parameter-");
+ pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
+ pp_minus (pp);
+ pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
+ pp_cxx_end_template_argument_list (pp);
+}
+
+/*
+ template-declaration:
+ export(opt) template < template-parameter-list > declaration */
+
+static void
+pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
+{
+ tree tmpl = most_general_template (t);
+ tree level;
+
+ pp_maybe_newline_and_indent (pp, 0);
+ for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
+ {
+ pp_cxx_ws_string (pp, "template");
+ pp_cxx_begin_template_argument_list (pp);
+ pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
+ pp_cxx_end_template_argument_list (pp);
+ pp_newline_and_indent (pp, 3);
+ }
+ if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
+ pp_cxx_function_definition (pp, t);
+ else
+ pp_cxx_simple_declaration (pp, t);
+}
+
+static void
+pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
+{
+ pp_unsupported_tree (pp, t);
+}
+
+static void
+pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
+{
+ pp_unsupported_tree (pp, t);
+}
+
+/*
+ declaration:
+ block-declaration
+ function-definition
+ template-declaration
+ explicit-instantiation
+ explicit-specialization
+ linkage-specification
+ namespace-definition
+
+ block-declaration:
+ simple-declaration
+ asm-definition
+ namespace-alias-definition
+ using-declaration
+ using-directive
+ static_assert-declaration */
+void
+cxx_pretty_printer::declaration (tree t)
+{
+ if (TREE_CODE (t) == STATIC_ASSERT)
+ {
+ pp_cxx_ws_string (this, "static_assert");
+ pp_cxx_left_paren (this);
+ expression (STATIC_ASSERT_CONDITION (t));
+ pp_cxx_separate_with (this, ',');
+ expression (STATIC_ASSERT_MESSAGE (t));
+ pp_cxx_right_paren (this);
+ }
+ else if (!DECL_LANG_SPECIFIC (t))
+ pp_cxx_simple_declaration (this, t);
+ else if (DECL_USE_TEMPLATE (t))
+ switch (DECL_USE_TEMPLATE (t))
+ {
+ case 1:
+ pp_cxx_template_declaration (this, t);
+ break;
+
+ case 2:
+ pp_cxx_explicit_specialization (this, t);
+ break;
+
+ case 3:
+ pp_cxx_explicit_instantiation (this, t);
+ break;
+
+ default:
+ break;
+ }
+ else switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ case TYPE_DECL:
+ pp_cxx_simple_declaration (this, t);
+ break;
+
+ case FUNCTION_DECL:
+ if (DECL_SAVED_TREE (t))
+ pp_cxx_function_definition (this, t);
+ else
+ pp_cxx_simple_declaration (this, t);
+ break;
+
+ case NAMESPACE_DECL:
+ if (DECL_NAMESPACE_ALIAS (t))
+ pp_cxx_namespace_alias_definition (this, t);
+ else
+ pp_cxx_original_namespace_definition (this, t);
+ break;
+
+ default:
+ pp_unsupported_tree (this, t);
+ break;
+ }
+}
+
+static void
+pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
+{
+ t = TREE_OPERAND (t, 0);
+ pp_cxx_ws_string (pp, "typeid");
+ pp_cxx_left_paren (pp);
+ if (TYPE_P (t))
+ pp->type_id (t);
+ else
+ pp->expression (t);
+ pp_cxx_right_paren (pp);
+}
+
+void
+pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_ws_string (pp, "va_arg");
+ pp_cxx_left_paren (pp);
+ pp->assignment_expression (TREE_OPERAND (t, 0));
+ pp_cxx_separate_with (pp, ',');
+ pp->type_id (TREE_TYPE (t));
+ pp_cxx_right_paren (pp);
+}
+
+static bool
+pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case ARROW_EXPR:
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
+ && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
+ {
+ pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
+ pp_cxx_separate_with (pp, ',');
+ return true;
+ }
+ return false;
+ case COMPONENT_REF:
+ if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
+ return false;
+ if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
+ pp_cxx_dot (pp);
+ pp->expression (TREE_OPERAND (t, 1));
+ return true;
+ case ARRAY_REF:
+ if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
+ return false;
+ pp_left_bracket (pp);
+ pp->expression (TREE_OPERAND (t, 1));
+ pp_right_bracket (pp);
+ return true;
+ default:
+ return false;
+ }
+}
+
+void
+pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_ws_string (pp, "offsetof");
+ pp_cxx_left_paren (pp);
+ if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
+ pp->expression (TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (pp);
+}
+
+void
+pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
+{
+ cp_trait_kind kind = TRAIT_EXPR_KIND (t);
+
+ switch (kind)
+ {
+ case CPTK_HAS_NOTHROW_ASSIGN:
+ pp_cxx_ws_string (pp, "__has_nothrow_assign");
+ break;
+ case CPTK_HAS_TRIVIAL_ASSIGN:
+ pp_cxx_ws_string (pp, "__has_trivial_assign");
+ break;
+ case CPTK_HAS_NOTHROW_CONSTRUCTOR:
+ pp_cxx_ws_string (pp, "__has_nothrow_constructor");
+ break;
+ case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
+ pp_cxx_ws_string (pp, "__has_trivial_constructor");
+ break;
+ case CPTK_HAS_NOTHROW_COPY:
+ pp_cxx_ws_string (pp, "__has_nothrow_copy");
+ break;
+ case CPTK_HAS_TRIVIAL_COPY:
+ pp_cxx_ws_string (pp, "__has_trivial_copy");
+ break;
+ case CPTK_HAS_TRIVIAL_DESTRUCTOR:
+ pp_cxx_ws_string (pp, "__has_trivial_destructor");
+ break;
+ case CPTK_HAS_VIRTUAL_DESTRUCTOR:
+ pp_cxx_ws_string (pp, "__has_virtual_destructor");
+ break;
+ case CPTK_IS_ABSTRACT:
+ pp_cxx_ws_string (pp, "__is_abstract");
+ break;
+ case CPTK_IS_BASE_OF:
+ pp_cxx_ws_string (pp, "__is_base_of");
+ break;
+ case CPTK_IS_CLASS:
+ pp_cxx_ws_string (pp, "__is_class");
+ break;
+ case CPTK_IS_CONVERTIBLE_TO:
+ pp_cxx_ws_string (pp, "__is_convertible_to");
+ break;
+ case CPTK_IS_EMPTY:
+ pp_cxx_ws_string (pp, "__is_empty");
+ break;
+ case CPTK_IS_ENUM:
+ pp_cxx_ws_string (pp, "__is_enum");
+ break;
+ case CPTK_IS_FINAL:
+ pp_cxx_ws_string (pp, "__is_final");
+ break;
+ case CPTK_IS_POD:
+ pp_cxx_ws_string (pp, "__is_pod");
+ break;
+ case CPTK_IS_POLYMORPHIC:
+ pp_cxx_ws_string (pp, "__is_polymorphic");
+ break;
+ case CPTK_IS_STD_LAYOUT:
+ pp_cxx_ws_string (pp, "__is_std_layout");
+ break;
+ case CPTK_IS_TRIVIAL:
+ pp_cxx_ws_string (pp, "__is_trivial");
+ break;
+ case CPTK_IS_UNION:
+ pp_cxx_ws_string (pp, "__is_union");
+ break;
+ case CPTK_IS_LITERAL_TYPE:
+ pp_cxx_ws_string (pp, "__is_literal_type");
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ pp_cxx_left_paren (pp);
+ pp->type_id (TRAIT_EXPR_TYPE1 (t));
+
+ if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
+ {
+ pp_cxx_separate_with (pp, ',');
+ pp->type_id (TRAIT_EXPR_TYPE2 (t));
+ }
+
+ pp_cxx_right_paren (pp);
+}
+
+typedef c_pretty_print_fn pp_fun;
+
+/* Initialization of a C++ pretty-printer object. */
+
+cxx_pretty_printer::cxx_pretty_printer ()
+ : c_pretty_printer (),
+ enclosing_scope (global_namespace)
+{
+ pp_set_line_maximum_length (this, 0);
+
+ type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
+ parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
+}
diff --git a/gcc-4.9/gcc/cp/cxx-pretty-print.h b/gcc-4.9/gcc/cp/cxx-pretty-print.h
new file mode 100644
index 000000000..2dc3f95b2
--- /dev/null
+++ b/gcc-4.9/gcc/cp/cxx-pretty-print.h
@@ -0,0 +1,96 @@
+/* Interface for the GNU C++ pretty-printer.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_CXX_PRETTY_PRINT_H
+#define GCC_CXX_PRETTY_PRINT_H
+
+#include "c-family/c-pretty-print.h"
+
+enum cxx_pretty_printer_flags
+{
+ /* Ask for a qualified-id. */
+ pp_cxx_flag_default_argument = 1 << pp_c_flag_last_bit
+};
+
+struct cxx_pretty_printer : c_pretty_printer
+{
+ cxx_pretty_printer ();
+
+ void constant (tree);
+ void id_expression (tree);
+ void primary_expression (tree);
+ void postfix_expression (tree);
+ void unary_expression (tree);
+ void multiplicative_expression (tree);
+ void conditional_expression (tree);
+ void assignment_expression (tree);
+ void expression (tree);
+ void type_id (tree);
+ void statement (tree);
+ void declaration (tree);
+ void declaration_specifiers (tree);
+ void simple_type_specifier (tree);
+ void function_specifier (tree);
+ void declarator (tree);
+ void direct_declarator (tree);
+ void abstract_declarator (tree);
+ void direct_abstract_declarator (tree);
+
+ /* This is the enclosing scope of the entity being pretty-printed. */
+ tree enclosing_scope;
+};
+
+#define pp_cxx_cv_qualifier_seq(PP, T) \
+ pp_c_type_qualifier_list (PP, T)
+#define pp_cxx_cv_qualifiers(PP, CV) \
+ pp_c_cv_qualifiers (PP, CV, false)
+
+#define pp_cxx_whitespace(PP) pp_c_whitespace (PP)
+#define pp_cxx_left_paren(PP) pp_c_left_paren (PP)
+#define pp_cxx_right_paren(PP) pp_c_right_paren (PP)
+#define pp_cxx_left_brace(PP) pp_c_left_brace (PP)
+#define pp_cxx_right_brace(PP) pp_c_right_brace (PP)
+#define pp_cxx_left_bracket(PP) pp_c_left_bracket (PP)
+#define pp_cxx_right_bracket(PP) pp_c_right_bracket (PP)
+#define pp_cxx_dot(PP) pp_c_dot (PP)
+#define pp_cxx_ampersand(PP) pp_c_ampersand (PP)
+#define pp_cxx_star(PP) pp_c_star (PP)
+#define pp_cxx_arrow(PP) pp_c_arrow (PP)
+#define pp_cxx_semicolon(PP) pp_c_semicolon (PP)
+#define pp_cxx_complement(PP) pp_c_complement (PP)
+
+#define pp_cxx_ws_string(PP, I) pp_c_ws_string (PP, I)
+#define pp_cxx_identifier(PP, I) pp_c_identifier (PP, I)
+#define pp_cxx_tree_identifier(PP, T) \
+ pp_c_tree_identifier (PP, T)
+
+void pp_cxx_begin_template_argument_list (cxx_pretty_printer *);
+void pp_cxx_end_template_argument_list (cxx_pretty_printer *);
+void pp_cxx_colon_colon (cxx_pretty_printer *);
+void pp_cxx_separate_with (cxx_pretty_printer *, int);
+
+void pp_cxx_canonical_template_parameter (cxx_pretty_printer *, tree);
+void pp_cxx_trait_expression (cxx_pretty_printer *, tree);
+void pp_cxx_va_arg_expression (cxx_pretty_printer *, tree);
+void pp_cxx_offsetof_expression (cxx_pretty_printer *, tree);
+void pp_cxx_userdef_literal (cxx_pretty_printer *, tree);
+
+
+#endif /* GCC_CXX_PRETTY_PRINT_H */
diff --git a/gcc-4.9/gcc/cp/decl.c b/gcc-4.9/gcc/cp/decl.c
new file mode 100644
index 000000000..c912ffcb5
--- /dev/null
+++ b/gcc-4.9/gcc/cp/decl.c
@@ -0,0 +1,14476 @@
+/* Process declarations and variables for C++ compiler.
+ Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Contributed by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* Process declarations and symbol lookup for C++ front end.
+ Also constructs types; the standard scalar types at initialization,
+ and structure, union, array and enum types when they are declared. */
+
+/* ??? not all decl nodes are given the most useful possible
+ line numbers. For example, the CONST_DECLs for enum values. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "stor-layout.h"
+#include "varasm.h"
+#include "attribs.h"
+#include "calls.h"
+#include "flags.h"
+#include "cp-tree.h"
+#include "tree-iterator.h"
+#include "tree-inline.h"
+#include "decl.h"
+#include "intl.h"
+#include "toplev.h"
+#include "hashtab.h"
+#include "tm_p.h"
+#include "target.h"
+#include "c-family/c-common.h"
+#include "c-family/c-objc.h"
+#include "c-family/c-pragma.h"
+#include "c-family/c-target.h"
+#include "c-family/c-ubsan.h"
+#include "diagnostic.h"
+#include "intl.h"
+#include "debug.h"
+#include "timevar.h"
+#include "pointer-set.h"
+#include "splay-tree.h"
+#include "plugin.h"
+#include "cgraph.h"
+#include "cilk.h"
+
+/* Possible cases of bad specifiers type used by bad_specifiers. */
+enum bad_spec_place {
+ BSP_VAR, /* variable */
+ BSP_PARM, /* parameter */
+ BSP_TYPE, /* type */
+ BSP_FIELD /* field */
+};
+
+static tree grokparms (tree parmlist, tree *);
+static const char *redeclaration_error_message (tree, tree);
+
+static int decl_jump_unsafe (tree);
+static void require_complete_types_for_parms (tree);
+static int ambi_op_p (enum tree_code);
+static int unary_op_p (enum tree_code);
+static void push_local_name (tree);
+static tree grok_reference_init (tree, tree, tree, int);
+static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
+ int, int, tree);
+static int check_static_variable_definition (tree, tree);
+static void record_unknown_type (tree, const char *);
+static tree builtin_function_1 (tree, tree, bool);
+static int member_function_or_else (tree, tree, enum overload_flags);
+static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
+ int);
+static void check_for_uninitialized_const_var (tree);
+static hashval_t typename_hash (const void *);
+static int typename_compare (const void *, const void *);
+static tree local_variable_p_walkfn (tree *, int *, void *);
+static tree record_builtin_java_type (const char *, int);
+static const char *tag_name (enum tag_types);
+static tree lookup_and_check_tag (enum tag_types, tree, tag_scope, bool);
+static int walk_namespaces_r (tree, walk_namespaces_fn, void *);
+static void maybe_deduce_size_from_array_init (tree, tree);
+static void layout_var_decl (tree);
+static tree check_initializer (tree, tree, int, vec<tree, va_gc> **);
+static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
+static void save_function_data (tree);
+static void copy_type_enum (tree , tree);
+static void check_function_type (tree, tree);
+static void finish_constructor_body (void);
+static void begin_destructor_body (void);
+static void finish_destructor_body (void);
+static void record_key_method_defined (tree);
+static tree create_array_type_for_decl (tree, tree, tree);
+static tree get_atexit_node (void);
+static tree get_dso_handle_node (void);
+static tree start_cleanup_fn (void);
+static void end_cleanup_fn (void);
+static tree cp_make_fname_decl (location_t, tree, int);
+static void initialize_predefined_identifiers (void);
+static tree check_special_function_return_type
+ (special_function_kind, tree, tree);
+static tree push_cp_library_fn (enum tree_code, tree, int);
+static tree build_cp_library_fn (tree, enum tree_code, tree, int);
+static void store_parm_decls (tree);
+static void initialize_local_var (tree, tree);
+static void expand_static_init (tree, tree);
+
+/* The following symbols are subsumed in the cp_global_trees array, and
+ listed here individually for documentation purposes.
+
+ C++ extensions
+ tree wchar_decl_node;
+
+ tree vtable_entry_type;
+ tree delta_type_node;
+ tree __t_desc_type_node;
+
+ tree class_type_node;
+ tree unknown_type_node;
+
+ Array type `vtable_entry_type[]'
+
+ tree vtbl_type_node;
+ tree vtbl_ptr_type_node;
+
+ Namespaces,
+
+ tree std_node;
+ tree abi_node;
+
+ A FUNCTION_DECL which can call `abort'. Not necessarily the
+ one that the user will declare, but sufficient to be called
+ by routines that want to abort the program.
+
+ tree abort_fndecl;
+
+ The FUNCTION_DECL for the default `::operator delete'.
+
+ tree global_delete_fndecl;
+
+ Used by RTTI
+ tree type_info_type_node, tinfo_decl_id, tinfo_decl_type;
+ tree tinfo_var_id; */
+
+tree cp_global_trees[CPTI_MAX];
+
+/* Indicates that there is a type value in some namespace, although
+ that is not necessarily in scope at the moment. */
+
+tree global_type_node;
+
+/* The node that holds the "name" of the global scope. */
+tree global_scope_name;
+
+#define local_names cp_function_chain->x_local_names
+
+/* A list of objects which have constructors or destructors
+ which reside in the global scope. The decl is stored in
+ the TREE_VALUE slot and the initializer is stored
+ in the TREE_PURPOSE slot. */
+tree static_aggregates;
+
+/* Like static_aggregates, but for thread_local variables. */
+tree tls_aggregates;
+
+/* -- end of C++ */
+
+/* A node for the integer constant 2. */
+
+tree integer_two_node;
+
+/* Used only for jumps to as-yet undefined labels, since jumps to
+ defined labels can have their validity checked immediately. */
+
+struct GTY((chain_next ("%h.next"))) named_label_use_entry {
+ struct named_label_use_entry *next;
+ /* The binding level to which this entry is *currently* attached.
+ This is initially the binding level in which the goto appeared,
+ but is modified as scopes are closed. */
+ cp_binding_level *binding_level;
+ /* The head of the names list that was current when the goto appeared,
+ or the inner scope popped. These are the decls that will *not* be
+ skipped when jumping to the label. */
+ tree names_in_scope;
+ /* The location of the goto, for error reporting. */
+ location_t o_goto_locus;
+ /* True if an OpenMP structured block scope has been closed since
+ the goto appeared. This means that the branch from the label will
+ illegally exit an OpenMP scope. */
+ bool in_omp_scope;
+};
+
+/* A list of all LABEL_DECLs in the function that have names. Here so
+ we can clear out their names' definitions at the end of the
+ function, and so we can check the validity of jumps to these labels. */
+
+struct GTY(()) named_label_entry {
+ /* The decl itself. */
+ tree label_decl;
+
+ /* The binding level to which the label is *currently* attached.
+ This is initially set to the binding level in which the label
+ is defined, but is modified as scopes are closed. */
+ cp_binding_level *binding_level;
+ /* The head of the names list that was current when the label was
+ defined, or the inner scope popped. These are the decls that will
+ be skipped when jumping to the label. */
+ tree names_in_scope;
+ /* A vector of all decls from all binding levels that would be
+ crossed by a backward branch to the label. */
+ vec<tree, va_gc> *bad_decls;
+
+ /* A list of uses of the label, before the label is defined. */
+ struct named_label_use_entry *uses;
+
+ /* The following bits are set after the label is defined, and are
+ updated as scopes are popped. They indicate that a backward jump
+ to the label will illegally enter a scope of the given flavor. */
+ bool in_try_scope;
+ bool in_catch_scope;
+ bool in_omp_scope;
+};
+
+#define named_labels cp_function_chain->x_named_labels
+
+/* The number of function bodies which we are currently processing.
+ (Zero if we are at namespace scope, one inside the body of a
+ function, two inside the body of a function in a local class, etc.) */
+int function_depth;
+
+/* To avoid unwanted recursion, finish_function defers all mark_used calls
+ encountered during its execution until it finishes. */
+bool defer_mark_used_calls;
+vec<tree, va_gc> *deferred_mark_used_calls;
+
+/* States indicating how grokdeclarator() should handle declspecs marked
+ with __attribute__((deprecated)). An object declared as
+ __attribute__((deprecated)) suppresses warnings of uses of other
+ deprecated items. */
+enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
+
+
+/* A list of VAR_DECLs whose type was incomplete at the time the
+ variable was declared. */
+
+typedef struct GTY(()) incomplete_var_d {
+ tree decl;
+ tree incomplete_type;
+} incomplete_var;
+
+
+static GTY(()) vec<incomplete_var, va_gc> *incomplete_vars;
+
+/* Returns the kind of template specialization we are currently
+ processing, given that it's declaration contained N_CLASS_SCOPES
+ explicit scope qualifications. */
+
+tmpl_spec_kind
+current_tmpl_spec_kind (int n_class_scopes)
+{
+ int n_template_parm_scopes = 0;
+ int seen_specialization_p = 0;
+ int innermost_specialization_p = 0;
+ cp_binding_level *b;
+
+ /* Scan through the template parameter scopes. */
+ for (b = current_binding_level;
+ b->kind == sk_template_parms;
+ b = b->level_chain)
+ {
+ /* If we see a specialization scope inside a parameter scope,
+ then something is wrong. That corresponds to a declaration
+ like:
+
+ template <class T> template <> ...
+
+ which is always invalid since [temp.expl.spec] forbids the
+ specialization of a class member template if the enclosing
+ class templates are not explicitly specialized as well. */
+ if (b->explicit_spec_p)
+ {
+ if (n_template_parm_scopes == 0)
+ innermost_specialization_p = 1;
+ else
+ seen_specialization_p = 1;
+ }
+ else if (seen_specialization_p == 1)
+ return tsk_invalid_member_spec;
+
+ ++n_template_parm_scopes;
+ }
+
+ /* Handle explicit instantiations. */
+ if (processing_explicit_instantiation)
+ {
+ if (n_template_parm_scopes != 0)
+ /* We've seen a template parameter list during an explicit
+ instantiation. For example:
+
+ template <class T> template void f(int);
+
+ This is erroneous. */
+ return tsk_invalid_expl_inst;
+ else
+ return tsk_expl_inst;
+ }
+
+ if (n_template_parm_scopes < n_class_scopes)
+ /* We've not seen enough template headers to match all the
+ specialized classes present. For example:
+
+ template <class T> void R<T>::S<T>::f(int);
+
+ This is invalid; there needs to be one set of template
+ parameters for each class. */
+ return tsk_insufficient_parms;
+ else if (n_template_parm_scopes == n_class_scopes)
+ /* We're processing a non-template declaration (even though it may
+ be a member of a template class.) For example:
+
+ template <class T> void S<T>::f(int);
+
+ The `class T' matches the `S<T>', leaving no template headers
+ corresponding to the `f'. */
+ return tsk_none;
+ else if (n_template_parm_scopes > n_class_scopes + 1)
+ /* We've got too many template headers. For example:
+
+ template <> template <class T> void f (T);
+
+ There need to be more enclosing classes. */
+ return tsk_excessive_parms;
+ else
+ /* This must be a template. It's of the form:
+
+ template <class T> template <class U> void S<T>::f(U);
+
+ This is a specialization if the innermost level was a
+ specialization; otherwise it's just a definition of the
+ template. */
+ return innermost_specialization_p ? tsk_expl_spec : tsk_template;
+}
+
+/* Exit the current scope. */
+
+void
+finish_scope (void)
+{
+ poplevel (0, 0, 0);
+}
+
+/* When a label goes out of scope, check to see if that label was used
+ in a valid manner, and issue any appropriate warnings or errors. */
+
+static void
+pop_label (tree label, tree old_value)
+{
+ if (!processing_template_decl)
+ {
+ if (DECL_INITIAL (label) == NULL_TREE)
+ {
+ location_t location;
+
+ error ("label %q+D used but not defined", label);
+ location = input_location;
+ /* FIXME want (LOCATION_FILE (input_location), (line)0) */
+ /* Avoid crashing later. */
+ define_label (location, DECL_NAME (label));
+ }
+ else
+ warn_for_unused_label (label);
+ }
+
+ SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), old_value);
+}
+
+/* At the end of a function, all labels declared within the function
+ go out of scope. BLOCK is the top-level block for the
+ function. */
+
+static int
+pop_labels_1 (void **slot, void *data)
+{
+ struct named_label_entry *ent = (struct named_label_entry *) *slot;
+ tree block = (tree) data;
+
+ pop_label (ent->label_decl, NULL_TREE);
+
+ /* Put the labels into the "variables" of the top-level block,
+ so debugger can see them. */
+ DECL_CHAIN (ent->label_decl) = BLOCK_VARS (block);
+ BLOCK_VARS (block) = ent->label_decl;
+
+ htab_clear_slot (named_labels, slot);
+
+ return 1;
+}
+
+static void
+pop_labels (tree block)
+{
+ if (named_labels)
+ {
+ htab_traverse (named_labels, pop_labels_1, block);
+ named_labels = NULL;
+ }
+}
+
+/* At the end of a block with local labels, restore the outer definition. */
+
+static void
+pop_local_label (tree label, tree old_value)
+{
+ struct named_label_entry dummy;
+ void **slot;
+
+ pop_label (label, old_value);
+
+ dummy.label_decl = label;
+ slot = htab_find_slot (named_labels, &dummy, NO_INSERT);
+ htab_clear_slot (named_labels, slot);
+}
+
+/* The following two routines are used to interface to Objective-C++.
+ The binding level is purposely treated as an opaque type. */
+
+void *
+objc_get_current_scope (void)
+{
+ return current_binding_level;
+}
+
+/* The following routine is used by the NeXT-style SJLJ exceptions;
+ variables get marked 'volatile' so as to not be clobbered by
+ _setjmp()/_longjmp() calls. All variables in the current scope,
+ as well as parent scopes up to (but not including) ENCLOSING_BLK
+ shall be thusly marked. */
+
+void
+objc_mark_locals_volatile (void *enclosing_blk)
+{
+ cp_binding_level *scope;
+
+ for (scope = current_binding_level;
+ scope && scope != enclosing_blk;
+ scope = scope->level_chain)
+ {
+ tree decl;
+
+ for (decl = scope->names; decl; decl = TREE_CHAIN (decl))
+ objc_volatilize_decl (decl);
+
+ /* Do not climb up past the current function. */
+ if (scope->kind == sk_function_parms)
+ break;
+ }
+}
+
+/* Update data for defined and undefined labels when leaving a scope. */
+
+static int
+poplevel_named_label_1 (void **slot, void *data)
+{
+ struct named_label_entry *ent = (struct named_label_entry *) *slot;
+ cp_binding_level *bl = (cp_binding_level *) data;
+ cp_binding_level *obl = bl->level_chain;
+
+ if (ent->binding_level == bl)
+ {
+ tree decl;
+
+ /* ENT->NAMES_IN_SCOPE may contain a mixture of DECLs and
+ TREE_LISTs representing OVERLOADs, so be careful. */
+ for (decl = ent->names_in_scope; decl; decl = (DECL_P (decl)
+ ? DECL_CHAIN (decl)
+ : TREE_CHAIN (decl)))
+ if (decl_jump_unsafe (decl))
+ vec_safe_push (ent->bad_decls, decl);
+
+ ent->binding_level = obl;
+ ent->names_in_scope = obl->names;
+ switch (bl->kind)
+ {
+ case sk_try:
+ ent->in_try_scope = true;
+ break;
+ case sk_catch:
+ ent->in_catch_scope = true;
+ break;
+ case sk_omp:
+ ent->in_omp_scope = true;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (ent->uses)
+ {
+ struct named_label_use_entry *use;
+
+ for (use = ent->uses; use ; use = use->next)
+ if (use->binding_level == bl)
+ {
+ use->binding_level = obl;
+ use->names_in_scope = obl->names;
+ if (bl->kind == sk_omp)
+ use->in_omp_scope = true;
+ }
+ }
+
+ return 1;
+}
+
+/* Saved errorcount to avoid -Wunused-but-set-{parameter,variable} warnings
+ when errors were reported, except for -Werror-unused-but-set-*. */
+static int unused_but_set_errorcount;
+
+/* Exit a binding level.
+ Pop the level off, and restore the state of the identifier-decl mappings
+ that were in effect when this level was entered.
+
+ If KEEP == 1, this level had explicit declarations, so
+ and create a "block" (a BLOCK node) for the level
+ to record its declarations and subblocks for symbol table output.
+
+ If FUNCTIONBODY is nonzero, this level is the body of a function,
+ so create a block as if KEEP were set and also clear out all
+ label names.
+
+ If REVERSE is nonzero, reverse the order of decls before putting
+ them into the BLOCK. */
+
+tree
+poplevel (int keep, int reverse, int functionbody)
+{
+ tree link;
+ /* The chain of decls was accumulated in reverse order.
+ Put it into forward order, just for cleanliness. */
+ tree decls;
+ tree subblocks;
+ tree block;
+ tree decl;
+ int leaving_for_scope;
+ scope_kind kind;
+ unsigned ix;
+ cp_label_binding *label_bind;
+
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ restart:
+
+ block = NULL_TREE;
+
+ gcc_assert (current_binding_level->kind != sk_class);
+
+ if (current_binding_level->kind == sk_cleanup)
+ functionbody = 0;
+ subblocks = functionbody >= 0 ? current_binding_level->blocks : 0;
+
+ gcc_assert (!vec_safe_length (current_binding_level->class_shadowed));
+
+ /* We used to use KEEP == 2 to indicate that the new block should go
+ at the beginning of the list of blocks at this binding level,
+ rather than the end. This hack is no longer used. */
+ gcc_assert (keep == 0 || keep == 1);
+
+ if (current_binding_level->keep)
+ keep = 1;
+
+ /* Any uses of undefined labels, and any defined labels, now operate
+ under constraints of next binding contour. */
+ if (cfun && !functionbody && named_labels)
+ htab_traverse (named_labels, poplevel_named_label_1,
+ current_binding_level);
+
+ /* Get the decls in the order they were written.
+ Usually current_binding_level->names is in reverse order.
+ But parameter decls were previously put in forward order. */
+
+ if (reverse)
+ current_binding_level->names
+ = decls = nreverse (current_binding_level->names);
+ else
+ decls = current_binding_level->names;
+
+ /* If there were any declarations or structure tags in that level,
+ or if this level is a function body,
+ create a BLOCK to record them for the life of this function. */
+ block = NULL_TREE;
+ if (keep == 1 || functionbody)
+ block = make_node (BLOCK);
+ if (block != NULL_TREE)
+ {
+ BLOCK_VARS (block) = decls;
+ BLOCK_SUBBLOCKS (block) = subblocks;
+ }
+
+ /* In each subblock, record that this is its superior. */
+ if (keep >= 0)
+ for (link = subblocks; link; link = BLOCK_CHAIN (link))
+ BLOCK_SUPERCONTEXT (link) = block;
+
+ /* We still support the old for-scope rules, whereby the variables
+ in a for-init statement were in scope after the for-statement
+ ended. We only use the new rules if flag_new_for_scope is
+ nonzero. */
+ leaving_for_scope
+ = current_binding_level->kind == sk_for && flag_new_for_scope == 1;
+
+ /* Before we remove the declarations first check for unused variables. */
+ if ((warn_unused_variable || warn_unused_but_set_variable)
+ && !processing_template_decl)
+ for (tree d = getdecls (); d; d = TREE_CHAIN (d))
+ {
+ /* There are cases where D itself is a TREE_LIST. See in
+ push_local_binding where the list of decls returned by
+ getdecls is built. */
+ decl = TREE_CODE (d) == TREE_LIST ? TREE_VALUE (d) : d;
+ // See through references for improved -Wunused-variable (PR 38958).
+ tree type = non_reference (TREE_TYPE (decl));
+ if (VAR_P (decl)
+ && (! TREE_USED (decl) || !DECL_READ_P (decl))
+ && ! DECL_IN_SYSTEM_HEADER (decl)
+ && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)
+ && type != error_mark_node
+ && (!CLASS_TYPE_P (type)
+ || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ || lookup_attribute ("warn_unused",
+ TYPE_ATTRIBUTES (TREE_TYPE (decl)))))
+ {
+ if (! TREE_USED (decl))
+ warning (OPT_Wunused_variable, "unused variable %q+D", decl);
+ else if (DECL_CONTEXT (decl) == current_function_decl
+ // For -Wunused-but-set-variable leave references alone.
+ && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
+ && errorcount == unused_but_set_errorcount)
+ {
+ warning (OPT_Wunused_but_set_variable,
+ "variable %q+D set but not used", decl);
+ unused_but_set_errorcount = errorcount;
+ }
+ }
+ }
+
+ /* Remove declarations for all the DECLs in this level. */
+ for (link = decls; link; link = TREE_CHAIN (link))
+ {
+ if (leaving_for_scope && VAR_P (link)
+ /* It's hard to make this ARM compatibility hack play nicely with
+ lambdas, and it really isn't necessary in C++11 mode. */
+ && cxx_dialect < cxx11
+ && DECL_NAME (link))
+ {
+ tree name = DECL_NAME (link);
+ cxx_binding *ob;
+ tree ns_binding;
+
+ ob = outer_binding (name,
+ IDENTIFIER_BINDING (name),
+ /*class_p=*/true);
+ if (!ob)
+ ns_binding = IDENTIFIER_NAMESPACE_VALUE (name);
+ else
+ ns_binding = NULL_TREE;
+
+ if (ob && ob->scope == current_binding_level->level_chain)
+ /* We have something like:
+
+ int i;
+ for (int i; ;);
+
+ and we are leaving the `for' scope. There's no reason to
+ keep the binding of the inner `i' in this case. */
+ pop_binding (name, link);
+ else if ((ob && (TREE_CODE (ob->value) == TYPE_DECL))
+ || (ns_binding && TREE_CODE (ns_binding) == TYPE_DECL))
+ /* Here, we have something like:
+
+ typedef int I;
+
+ void f () {
+ for (int I; ;);
+ }
+
+ We must pop the for-scope binding so we know what's a
+ type and what isn't. */
+ pop_binding (name, link);
+ else
+ {
+ /* Mark this VAR_DECL as dead so that we can tell we left it
+ there only for backward compatibility. */
+ DECL_DEAD_FOR_LOCAL (link) = 1;
+
+ /* Keep track of what should have happened when we
+ popped the binding. */
+ if (ob && ob->value)
+ {
+ SET_DECL_SHADOWED_FOR_VAR (link, ob->value);
+ DECL_HAS_SHADOWED_FOR_VAR_P (link) = 1;
+ }
+
+ /* Add it to the list of dead variables in the next
+ outermost binding to that we can remove these when we
+ leave that binding. */
+ vec_safe_push (
+ current_binding_level->level_chain->dead_vars_from_for,
+ link);
+
+ /* Although we don't pop the cxx_binding, we do clear
+ its SCOPE since the scope is going away now. */
+ IDENTIFIER_BINDING (name)->scope
+ = current_binding_level->level_chain;
+ }
+ }
+ else
+ {
+ tree name;
+
+ /* Remove the binding. */
+ decl = link;
+
+ if (TREE_CODE (decl) == TREE_LIST)
+ decl = TREE_VALUE (decl);
+ name = decl;
+
+ if (TREE_CODE (name) == OVERLOAD)
+ name = OVL_FUNCTION (name);
+
+ gcc_assert (DECL_P (name));
+ pop_binding (DECL_NAME (name), decl);
+ }
+ }
+
+ /* Remove declarations for any `for' variables from inner scopes
+ that we kept around. */
+ FOR_EACH_VEC_SAFE_ELT_REVERSE (current_binding_level->dead_vars_from_for,
+ ix, decl)
+ pop_binding (DECL_NAME (decl), decl);
+
+ /* Restore the IDENTIFIER_TYPE_VALUEs. */
+ for (link = current_binding_level->type_shadowed;
+ link; link = TREE_CHAIN (link))
+ SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));
+
+ /* Restore the IDENTIFIER_LABEL_VALUEs for local labels. */
+ FOR_EACH_VEC_SAFE_ELT_REVERSE (current_binding_level->shadowed_labels,
+ ix, label_bind)
+ pop_local_label (label_bind->label, label_bind->prev_value);
+
+ /* There may be OVERLOADs (wrapped in TREE_LISTs) on the BLOCK_VARs
+ list if a `using' declaration put them there. The debugging
+ back ends won't understand OVERLOAD, so we remove them here.
+ Because the BLOCK_VARS are (temporarily) shared with
+ CURRENT_BINDING_LEVEL->NAMES we must do this fixup after we have
+ popped all the bindings. */
+ if (block)
+ {
+ tree* d;
+
+ for (d = &BLOCK_VARS (block); *d; )
+ {
+ if (TREE_CODE (*d) == TREE_LIST)
+ *d = TREE_CHAIN (*d);
+ else
+ d = &DECL_CHAIN (*d);
+ }
+ }
+
+ /* If the level being exited is the top level of a function,
+ check over all the labels. */
+ if (functionbody)
+ {
+ /* Since this is the top level block of a function, the vars are
+ the function's parameters. Don't leave them in the BLOCK
+ because they are found in the FUNCTION_DECL instead. */
+ BLOCK_VARS (block) = 0;
+ pop_labels (block);
+ }
+
+ kind = current_binding_level->kind;
+ if (kind == sk_cleanup)
+ {
+ tree stmt;
+
+ /* If this is a temporary binding created for a cleanup, then we'll
+ have pushed a statement list level. Pop that, create a new
+ BIND_EXPR for the block, and insert it into the stream. */
+ stmt = pop_stmt_list (current_binding_level->statement_list);
+ stmt = c_build_bind_expr (input_location, block, stmt);
+ add_stmt (stmt);
+ }
+
+ leave_scope ();
+ if (functionbody)
+ {
+ /* The current function is being defined, so its DECL_INITIAL
+ should be error_mark_node. */
+ gcc_assert (DECL_INITIAL (current_function_decl) == error_mark_node);
+ DECL_INITIAL (current_function_decl) = block;
+ }
+ else if (block)
+ current_binding_level->blocks
+ = block_chainon (current_binding_level->blocks, block);
+
+ /* If we did not make a block for the level just exited,
+ any blocks made for inner levels
+ (since they cannot be recorded as subblocks in that level)
+ must be carried forward so they will later become subblocks
+ of something else. */
+ else if (subblocks)
+ current_binding_level->blocks
+ = block_chainon (current_binding_level->blocks, subblocks);
+
+ /* Each and every BLOCK node created here in `poplevel' is important
+ (e.g. for proper debugging information) so if we created one
+ earlier, mark it as "used". */
+ if (block)
+ TREE_USED (block) = 1;
+
+ /* All temporary bindings created for cleanups are popped silently. */
+ if (kind == sk_cleanup)
+ goto restart;
+
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return block;
+}
+
+/* Walk all the namespaces contained NAMESPACE, including NAMESPACE
+ itself, calling F for each. The DATA is passed to F as well. */
+
+static int
+walk_namespaces_r (tree name_space, walk_namespaces_fn f, void* data)
+{
+ int result = 0;
+ tree current = NAMESPACE_LEVEL (name_space)->namespaces;
+
+ result |= (*f) (name_space, data);
+
+ for (; current; current = DECL_CHAIN (current))
+ result |= walk_namespaces_r (current, f, data);
+
+ return result;
+}
+
+/* Walk all the namespaces, calling F for each. The DATA is passed to
+ F as well. */
+
+int
+walk_namespaces (walk_namespaces_fn f, void* data)
+{
+ return walk_namespaces_r (global_namespace, f, data);
+}
+
+/* Call wrapup_globals_declarations for the globals in NAMESPACE. If
+ DATA is non-NULL, this is the last time we will call
+ wrapup_global_declarations for this NAMESPACE. */
+
+int
+wrapup_globals_for_namespace (tree name_space, void* data)
+{
+ cp_binding_level *level = NAMESPACE_LEVEL (name_space);
+ vec<tree, va_gc> *statics = level->static_decls;
+ tree *vec = statics->address ();
+ int len = statics->length ();
+ int last_time = (data != 0);
+
+ if (last_time)
+ {
+ check_global_declarations (vec, len);
+ emit_debug_global_declarations (vec, len);
+ return 0;
+ }
+
+ /* Write out any globals that need to be output. */
+ return wrapup_global_declarations (vec, len);
+}
+
+
+/* In C++, you don't have to write `struct S' to refer to `S'; you
+ can just use `S'. We accomplish this by creating a TYPE_DECL as
+ if the user had written `typedef struct S S'. Create and return
+ the TYPE_DECL for TYPE. */
+
+tree
+create_implicit_typedef (tree name, tree type)
+{
+ tree decl;
+
+ decl = build_decl (input_location, TYPE_DECL, name, type);
+ DECL_ARTIFICIAL (decl) = 1;
+ /* There are other implicit type declarations, like the one *within*
+ a class that allows you to write `S::S'. We must distinguish
+ amongst these. */
+ SET_DECL_IMPLICIT_TYPEDEF_P (decl);
+ TYPE_NAME (type) = decl;
+ TYPE_STUB_DECL (type) = decl;
+
+ return decl;
+}
+
+/* Remember a local name for name-mangling purposes. */
+
+static void
+push_local_name (tree decl)
+{
+ size_t i, nelts;
+ tree t, name;
+
+ timevar_start (TV_NAME_LOOKUP);
+
+ name = DECL_NAME (decl);
+
+ nelts = vec_safe_length (local_names);
+ for (i = 0; i < nelts; i++)
+ {
+ t = (*local_names)[i];
+ if (DECL_NAME (t) == name)
+ {
+ if (!DECL_LANG_SPECIFIC (decl))
+ retrofit_lang_decl (decl);
+ DECL_LANG_SPECIFIC (decl)->u.base.u2sel = 1;
+ if (DECL_DISCRIMINATOR_SET_P (t))
+ DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1;
+ else
+ DECL_DISCRIMINATOR (decl) = 1;
+
+ (*local_names)[i] = decl;
+ timevar_stop (TV_NAME_LOOKUP);
+ return;
+ }
+ }
+
+ vec_safe_push (local_names, decl);
+ timevar_stop (TV_NAME_LOOKUP);
+}
+
+/* Subroutine of duplicate_decls: return truthvalue of whether
+ or not types of these decls match.
+
+ For C++, we must compare the parameter list so that `int' can match
+ `int&' in a parameter position, but `int&' is not confused with
+ `const int&'. */
+
+int
+decls_match (tree newdecl, tree olddecl)
+{
+ int types_match;
+
+ if (newdecl == olddecl)
+ return 1;
+
+ if (TREE_CODE (newdecl) != TREE_CODE (olddecl))
+ /* If the two DECLs are not even the same kind of thing, we're not
+ interested in their types. */
+ return 0;
+
+ gcc_assert (DECL_P (newdecl));
+
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ tree f1 = TREE_TYPE (newdecl);
+ tree f2 = TREE_TYPE (olddecl);
+ tree p1 = TYPE_ARG_TYPES (f1);
+ tree p2 = TYPE_ARG_TYPES (f2);
+ tree r2;
+
+ /* Specializations of different templates are different functions
+ even if they have the same type. */
+ tree t1 = (DECL_USE_TEMPLATE (newdecl)
+ ? DECL_TI_TEMPLATE (newdecl)
+ : NULL_TREE);
+ tree t2 = (DECL_USE_TEMPLATE (olddecl)
+ ? DECL_TI_TEMPLATE (olddecl)
+ : NULL_TREE);
+ if (t1 != t2)
+ return 0;
+
+ if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
+ && ! (DECL_EXTERN_C_P (newdecl)
+ && DECL_EXTERN_C_P (olddecl)))
+ return 0;
+
+ /* A new declaration doesn't match a built-in one unless it
+ is also extern "C". */
+ if (DECL_IS_BUILTIN (olddecl)
+ && DECL_EXTERN_C_P (olddecl) && !DECL_EXTERN_C_P (newdecl))
+ return 0;
+
+ if (TREE_CODE (f1) != TREE_CODE (f2))
+ return 0;
+
+ /* A declaration with deduced return type should use its pre-deduction
+ type for declaration matching. */
+ r2 = fndecl_declared_return_type (olddecl);
+
+ if (same_type_p (TREE_TYPE (f1), r2))
+ {
+ if (!prototype_p (f2) && DECL_EXTERN_C_P (olddecl)
+ && (DECL_BUILT_IN (olddecl)
+#ifndef NO_IMPLICIT_EXTERN_C
+ || (DECL_IN_SYSTEM_HEADER (newdecl) && !DECL_CLASS_SCOPE_P (newdecl))
+ || (DECL_IN_SYSTEM_HEADER (olddecl) && !DECL_CLASS_SCOPE_P (olddecl))
+#endif
+ ))
+ {
+ types_match = self_promoting_args_p (p1);
+ if (p1 == void_list_node)
+ TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
+ }
+#ifndef NO_IMPLICIT_EXTERN_C
+ else if (!prototype_p (f1)
+ && (DECL_EXTERN_C_P (olddecl)
+ && DECL_IN_SYSTEM_HEADER (olddecl)
+ && !DECL_CLASS_SCOPE_P (olddecl))
+ && (DECL_EXTERN_C_P (newdecl)
+ && DECL_IN_SYSTEM_HEADER (newdecl)
+ && !DECL_CLASS_SCOPE_P (newdecl)))
+ {
+ types_match = self_promoting_args_p (p2);
+ TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
+ }
+#endif
+ else
+ types_match =
+ compparms (p1, p2)
+ && type_memfn_rqual (f1) == type_memfn_rqual (f2)
+ && (TYPE_ATTRIBUTES (TREE_TYPE (newdecl)) == NULL_TREE
+ || comp_type_attributes (TREE_TYPE (newdecl),
+ TREE_TYPE (olddecl)) != 0);
+ }
+ else
+ types_match = 0;
+
+ /* The decls dont match if they correspond to two different versions
+ of the same function. Disallow extern "C" functions to be
+ versions for now. */
+ if (types_match
+ && !DECL_EXTERN_C_P (newdecl)
+ && !DECL_EXTERN_C_P (olddecl)
+ && targetm.target_option.function_versions (newdecl, olddecl))
+ {
+ /* Mark functions as versions if necessary. Modify the mangled decl
+ name if necessary. */
+ if (DECL_FUNCTION_VERSIONED (newdecl)
+ && DECL_FUNCTION_VERSIONED (olddecl))
+ return 0;
+ if (!DECL_FUNCTION_VERSIONED (newdecl))
+ {
+ DECL_FUNCTION_VERSIONED (newdecl) = 1;
+ if (DECL_ASSEMBLER_NAME_SET_P (newdecl))
+ mangle_decl (newdecl);
+ }
+ if (!DECL_FUNCTION_VERSIONED (olddecl))
+ {
+ DECL_FUNCTION_VERSIONED (olddecl) = 1;
+ if (DECL_ASSEMBLER_NAME_SET_P (olddecl))
+ mangle_decl (olddecl);
+ }
+ record_function_versions (olddecl, newdecl);
+ return 0;
+ }
+ }
+ else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
+ {
+ if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl))
+ != TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)))
+ return 0;
+
+ if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
+ DECL_TEMPLATE_PARMS (olddecl)))
+ return 0;
+
+ if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
+ types_match = same_type_p (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl)),
+ TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl)));
+ else
+ types_match = decls_match (DECL_TEMPLATE_RESULT (olddecl),
+ DECL_TEMPLATE_RESULT (newdecl));
+ }
+ else
+ {
+ /* Need to check scope for variable declaration (VAR_DECL).
+ For typedef (TYPE_DECL), scope is ignored. */
+ if (VAR_P (newdecl)
+ && CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
+ /* [dcl.link]
+ Two declarations for an object with C language linkage
+ with the same name (ignoring the namespace that qualify
+ it) that appear in different namespace scopes refer to
+ the same object. */
+ && !(DECL_EXTERN_C_P (olddecl) && DECL_EXTERN_C_P (newdecl)))
+ return 0;
+
+ if (TREE_TYPE (newdecl) == error_mark_node)
+ types_match = TREE_TYPE (olddecl) == error_mark_node;
+ else if (TREE_TYPE (olddecl) == NULL_TREE)
+ types_match = TREE_TYPE (newdecl) == NULL_TREE;
+ else if (TREE_TYPE (newdecl) == NULL_TREE)
+ types_match = 0;
+ else
+ types_match = comptypes (TREE_TYPE (newdecl),
+ TREE_TYPE (olddecl),
+ COMPARE_REDECLARATION);
+ }
+
+ return types_match;
+}
+
+/* If NEWDECL is `static' and an `extern' was seen previously,
+ warn about it. OLDDECL is the previous declaration.
+
+ Note that this does not apply to the C++ case of declaring
+ a variable `extern const' and then later `const'.
+
+ Don't complain about built-in functions, since they are beyond
+ the user's control. */
+
+void
+warn_extern_redeclared_static (tree newdecl, tree olddecl)
+{
+ if (TREE_CODE (newdecl) == TYPE_DECL
+ || TREE_CODE (newdecl) == TEMPLATE_DECL
+ || TREE_CODE (newdecl) == CONST_DECL
+ || TREE_CODE (newdecl) == NAMESPACE_DECL)
+ return;
+
+ /* Don't get confused by static member functions; that's a different
+ use of `static'. */
+ if (TREE_CODE (newdecl) == FUNCTION_DECL
+ && DECL_STATIC_FUNCTION_P (newdecl))
+ return;
+
+ /* If the old declaration was `static', or the new one isn't, then
+ everything is OK. */
+ if (DECL_THIS_STATIC (olddecl) || !DECL_THIS_STATIC (newdecl))
+ return;
+
+ /* It's OK to declare a builtin function as `static'. */
+ if (TREE_CODE (olddecl) == FUNCTION_DECL
+ && DECL_ARTIFICIAL (olddecl))
+ return;
+
+ if (permerror (input_location,
+ "%qD was declared %<extern%> and later %<static%>", newdecl))
+ inform (input_location, "previous declaration of %q+D", olddecl);
+}
+
+/* NEW_DECL is a redeclaration of OLD_DECL; both are functions or
+ function templates. If their exception specifications do not
+ match, issue a diagnostic. */
+
+static void
+check_redeclaration_exception_specification (tree new_decl,
+ tree old_decl)
+{
+ tree new_type;
+ tree old_type;
+ tree new_exceptions;
+ tree old_exceptions;
+
+ new_type = TREE_TYPE (new_decl);
+ new_exceptions = TYPE_RAISES_EXCEPTIONS (new_type);
+ old_type = TREE_TYPE (old_decl);
+ old_exceptions = TYPE_RAISES_EXCEPTIONS (old_type);
+
+ /* [except.spec]
+
+ If any declaration of a function has an exception-specification,
+ all declarations, including the definition and an explicit
+ specialization, of that function shall have an
+ exception-specification with the same set of type-ids. */
+ if ((pedantic || ! DECL_IN_SYSTEM_HEADER (old_decl))
+ && ! DECL_IS_BUILTIN (old_decl)
+ && flag_exceptions
+ && !comp_except_specs (new_exceptions, old_exceptions, ce_normal))
+ {
+ error ("declaration of %qF has a different exception specifier",
+ new_decl);
+ error ("from previous declaration %q+F", old_decl);
+ }
+}
+
+/* Return true if OLD_DECL and NEW_DECL agree on constexprness.
+ Otherwise issue diagnostics. */
+
+static bool
+validate_constexpr_redeclaration (tree old_decl, tree new_decl)
+{
+ old_decl = STRIP_TEMPLATE (old_decl);
+ new_decl = STRIP_TEMPLATE (new_decl);
+ if (!VAR_OR_FUNCTION_DECL_P (old_decl)
+ || !VAR_OR_FUNCTION_DECL_P (new_decl))
+ return true;
+ if (DECL_DECLARED_CONSTEXPR_P (old_decl)
+ == DECL_DECLARED_CONSTEXPR_P (new_decl))
+ return true;
+ if (TREE_CODE (old_decl) == FUNCTION_DECL)
+ {
+ if (DECL_BUILT_IN (old_decl))
+ {
+ /* Hide a built-in declaration. */
+ DECL_DECLARED_CONSTEXPR_P (old_decl)
+ = DECL_DECLARED_CONSTEXPR_P (new_decl);
+ return true;
+ }
+ /* 7.1.5 [dcl.constexpr]
+ Note: An explicit specialization can differ from the template
+ declaration with respect to the constexpr specifier. */
+ if (! DECL_TEMPLATE_SPECIALIZATION (old_decl)
+ && DECL_TEMPLATE_SPECIALIZATION (new_decl))
+ return true;
+
+ error ("redeclaration %qD differs in %<constexpr%>", new_decl);
+ error ("from previous declaration %q+D", old_decl);
+ return false;
+ }
+ return true;
+}
+
+#define GNU_INLINE_P(fn) (DECL_DECLARED_INLINE_P (fn) \
+ && lookup_attribute ("gnu_inline", \
+ DECL_ATTRIBUTES (fn)))
+
+/* If NEWDECL is a redeclaration of OLDDECL, merge the declarations.
+ If the redeclaration is invalid, a diagnostic is issued, and the
+ error_mark_node is returned. Otherwise, OLDDECL is returned.
+
+ If NEWDECL is not a redeclaration of OLDDECL, NULL_TREE is
+ returned.
+
+ NEWDECL_IS_FRIEND is true if NEWDECL was declared as a friend. */
+
+tree
+duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
+{
+ unsigned olddecl_uid = DECL_UID (olddecl);
+ int olddecl_friend = 0, types_match = 0, hidden_friend = 0;
+ int new_defines_function = 0;
+ tree new_template_info;
+
+ if (newdecl == olddecl)
+ return olddecl;
+
+ types_match = decls_match (newdecl, olddecl);
+
+ /* If either the type of the new decl or the type of the old decl is an
+ error_mark_node, then that implies that we have already issued an
+ error (earlier) for some bogus type specification, and in that case,
+ it is rather pointless to harass the user with yet more error message
+ about the same declaration, so just pretend the types match here. */
+ if (TREE_TYPE (newdecl) == error_mark_node
+ || TREE_TYPE (olddecl) == error_mark_node)
+ return error_mark_node;
+
+ if (UDLIT_OPER_P (DECL_NAME (newdecl))
+ && UDLIT_OPER_P (DECL_NAME (olddecl)))
+ {
+ if (TREE_CODE (newdecl) == TEMPLATE_DECL
+ && TREE_CODE (olddecl) != TEMPLATE_DECL
+ && check_raw_literal_operator (olddecl))
+ error ("literal operator template %q+D conflicts with"
+ " raw literal operator %qD", newdecl, olddecl);
+ else if (TREE_CODE (newdecl) != TEMPLATE_DECL
+ && TREE_CODE (olddecl) == TEMPLATE_DECL
+ && check_raw_literal_operator (newdecl))
+ error ("raw literal operator %q+D conflicts with"
+ " literal operator template %qD", newdecl, olddecl);
+ }
+
+ if (DECL_P (olddecl)
+ && TREE_CODE (newdecl) == FUNCTION_DECL
+ && TREE_CODE (olddecl) == FUNCTION_DECL
+ && (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)))
+ {
+ if (DECL_DECLARED_INLINE_P (newdecl)
+ && DECL_UNINLINABLE (newdecl)
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
+ /* Already warned elsewhere. */;
+ else if (DECL_DECLARED_INLINE_P (olddecl)
+ && DECL_UNINLINABLE (olddecl)
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
+ /* Already warned. */;
+ else if (DECL_DECLARED_INLINE_P (newdecl)
+ && DECL_UNINLINABLE (olddecl)
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
+ {
+ if (warning (OPT_Wattributes, "function %q+D redeclared as inline",
+ newdecl))
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous declaration of %qD with attribute noinline",
+ olddecl);
+ }
+ else if (DECL_DECLARED_INLINE_P (olddecl)
+ && DECL_UNINLINABLE (newdecl)
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
+ {
+ if (warning (OPT_Wattributes, "function %q+D redeclared with "
+ "attribute noinline", newdecl))
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous declaration of %qD was inline",
+ olddecl);
+ }
+ }
+
+ /* Check for redeclaration and other discrepancies. */
+ if (TREE_CODE (olddecl) == FUNCTION_DECL
+ && DECL_ARTIFICIAL (olddecl))
+ {
+ gcc_assert (!DECL_HIDDEN_FRIEND_P (olddecl));
+ if (TREE_CODE (newdecl) != FUNCTION_DECL)
+ {
+ /* Avoid warnings redeclaring built-ins which have not been
+ explicitly declared. */
+ if (DECL_ANTICIPATED (olddecl))
+ return NULL_TREE;
+
+ /* If you declare a built-in or predefined function name as static,
+ the old definition is overridden, but optionally warn this was a
+ bad choice of name. */
+ if (! TREE_PUBLIC (newdecl))
+ {
+ warning (OPT_Wshadow,
+ DECL_BUILT_IN (olddecl)
+ ? G_("shadowing built-in function %q#D")
+ : G_("shadowing library function %q#D"), olddecl);
+ /* Discard the old built-in function. */
+ return NULL_TREE;
+ }
+ /* If the built-in is not ansi, then programs can override
+ it even globally without an error. */
+ else if (! DECL_BUILT_IN (olddecl))
+ warning (0, "library function %q#D redeclared as non-function %q#D",
+ olddecl, newdecl);
+ else
+ error ("declaration of %q#D conflicts with built-in "
+ "declaration %q#D", newdecl, olddecl);
+ return NULL_TREE;
+ }
+ else if (DECL_OMP_DECLARE_REDUCTION_P (olddecl))
+ {
+ gcc_assert (DECL_OMP_DECLARE_REDUCTION_P (newdecl));
+ error_at (DECL_SOURCE_LOCATION (newdecl),
+ "redeclaration of %<pragma omp declare reduction%>");
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous %<pragma omp declare reduction%> declaration");
+ return error_mark_node;
+ }
+ else if (!types_match)
+ {
+ /* Avoid warnings redeclaring built-ins which have not been
+ explicitly declared. */
+ if (DECL_ANTICIPATED (olddecl))
+ {
+ /* Deal with fileptr_type_node. FILE type is not known
+ at the time we create the builtins. */
+ tree t1, t2;
+
+ for (t1 = TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
+ t2 = TYPE_ARG_TYPES (TREE_TYPE (olddecl));
+ t1 || t2;
+ t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
+ if (!t1 || !t2)
+ break;
+ else if (TREE_VALUE (t2) == fileptr_type_node)
+ {
+ tree t = TREE_VALUE (t1);
+
+ if (TYPE_PTR_P (t)
+ && TYPE_NAME (TREE_TYPE (t))
+ && TYPE_IDENTIFIER (TREE_TYPE (t))
+ == get_identifier ("FILE")
+ && compparms (TREE_CHAIN (t1), TREE_CHAIN (t2)))
+ {
+ tree oldargs = TYPE_ARG_TYPES (TREE_TYPE (olddecl));
+
+ TYPE_ARG_TYPES (TREE_TYPE (olddecl))
+ = TYPE_ARG_TYPES (TREE_TYPE (newdecl));
+ types_match = decls_match (newdecl, olddecl);
+ if (types_match)
+ return duplicate_decls (newdecl, olddecl,
+ newdecl_is_friend);
+ TYPE_ARG_TYPES (TREE_TYPE (olddecl)) = oldargs;
+ }
+ }
+ else if (! same_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
+ break;
+ }
+ else if ((DECL_EXTERN_C_P (newdecl)
+ && DECL_EXTERN_C_P (olddecl))
+ || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
+ TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
+ {
+ /* A near match; override the builtin. */
+
+ if (TREE_PUBLIC (newdecl))
+ warning (0, "new declaration %q#D ambiguates built-in "
+ "declaration %q#D", newdecl, olddecl);
+ else
+ warning (OPT_Wshadow,
+ DECL_BUILT_IN (olddecl)
+ ? G_("shadowing built-in function %q#D")
+ : G_("shadowing library function %q#D"), olddecl);
+ }
+ else
+ /* Discard the old built-in function. */
+ return NULL_TREE;
+
+ /* Replace the old RTL to avoid problems with inlining. */
+ COPY_DECL_RTL (newdecl, olddecl);
+ }
+ /* Even if the types match, prefer the new declarations type for
+ built-ins which have not been explicitly declared, for
+ exception lists, etc... */
+ else if (DECL_IS_BUILTIN (olddecl))
+ {
+ tree type = TREE_TYPE (newdecl);
+ tree attribs = (*targetm.merge_type_attributes)
+ (TREE_TYPE (olddecl), type);
+
+ type = cp_build_type_attribute_variant (type, attribs);
+ TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = type;
+ }
+
+ /* If a function is explicitly declared "throw ()", propagate that to
+ the corresponding builtin. */
+ if (DECL_BUILT_IN_CLASS (olddecl) == BUILT_IN_NORMAL
+ && DECL_ANTICIPATED (olddecl)
+ && TREE_NOTHROW (newdecl)
+ && !TREE_NOTHROW (olddecl))
+ {
+ enum built_in_function fncode = DECL_FUNCTION_CODE (olddecl);
+ tree tmpdecl = builtin_decl_explicit (fncode);
+ if (tmpdecl && tmpdecl != olddecl && types_match)
+ TREE_NOTHROW (tmpdecl) = 1;
+ }
+
+ /* Whether or not the builtin can throw exceptions has no
+ bearing on this declarator. */
+ TREE_NOTHROW (olddecl) = 0;
+
+ if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl))
+ {
+ /* If a builtin function is redeclared as `static', merge
+ the declarations, but make the original one static. */
+ DECL_THIS_STATIC (olddecl) = 1;
+ TREE_PUBLIC (olddecl) = 0;
+
+ /* Make the old declaration consistent with the new one so
+ that all remnants of the builtin-ness of this function
+ will be banished. */
+ SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
+ COPY_DECL_RTL (newdecl, olddecl);
+ }
+ }
+ else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
+ {
+ /* C++ Standard, 3.3, clause 4:
+ "[Note: a namespace name or a class template name must be unique
+ in its declarative region (7.3.2, clause 14). ]" */
+ if (TREE_CODE (olddecl) != NAMESPACE_DECL
+ && TREE_CODE (newdecl) != NAMESPACE_DECL
+ && (TREE_CODE (olddecl) != TEMPLATE_DECL
+ || TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) != TYPE_DECL)
+ && (TREE_CODE (newdecl) != TEMPLATE_DECL
+ || TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) != TYPE_DECL))
+ {
+ if ((TREE_CODE (olddecl) == TYPE_DECL && DECL_ARTIFICIAL (olddecl)
+ && TREE_CODE (newdecl) != TYPE_DECL)
+ || (TREE_CODE (newdecl) == TYPE_DECL && DECL_ARTIFICIAL (newdecl)
+ && TREE_CODE (olddecl) != TYPE_DECL))
+ {
+ /* We do nothing special here, because C++ does such nasty
+ things with TYPE_DECLs. Instead, just let the TYPE_DECL
+ get shadowed, and know that if we need to find a TYPE_DECL
+ for a given name, we can look in the IDENTIFIER_TYPE_VALUE
+ slot of the identifier. */
+ return NULL_TREE;
+ }
+
+ if ((TREE_CODE (newdecl) == FUNCTION_DECL
+ && DECL_FUNCTION_TEMPLATE_P (olddecl))
+ || (TREE_CODE (olddecl) == FUNCTION_DECL
+ && DECL_FUNCTION_TEMPLATE_P (newdecl)))
+ return NULL_TREE;
+ }
+
+ error ("%q#D redeclared as different kind of symbol", newdecl);
+ if (TREE_CODE (olddecl) == TREE_LIST)
+ olddecl = TREE_VALUE (olddecl);
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous declaration %q#D", olddecl);
+
+ return error_mark_node;
+ }
+ else if (!types_match)
+ {
+ if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl))
+ /* These are certainly not duplicate declarations; they're
+ from different scopes. */
+ return NULL_TREE;
+
+ if (TREE_CODE (newdecl) == TEMPLATE_DECL)
+ {
+ /* The name of a class template may not be declared to refer to
+ any other template, class, function, object, namespace, value,
+ or type in the same scope. */
+ if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == TYPE_DECL
+ || TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
+ {
+ error ("conflicting declaration of template %q#D", newdecl);
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous declaration %q#D", olddecl);
+ return error_mark_node;
+ }
+ else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL
+ && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
+ && compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))),
+ TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))))
+ && comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
+ DECL_TEMPLATE_PARMS (olddecl))
+ /* Template functions can be disambiguated by
+ return type. */
+ && same_type_p (TREE_TYPE (TREE_TYPE (newdecl)),
+ TREE_TYPE (TREE_TYPE (olddecl))))
+ {
+ error ("ambiguating new declaration %q#D", newdecl);
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "old declaration %q#D", olddecl);
+ }
+ return NULL_TREE;
+ }
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ if (DECL_EXTERN_C_P (newdecl) && DECL_EXTERN_C_P (olddecl))
+ {
+ error ("conflicting declaration of C function %q#D",
+ newdecl);
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous declaration %q#D", olddecl);
+ return NULL_TREE;
+ }
+ /* For function versions, params and types match, but they
+ are not ambiguous. */
+ else if ((!DECL_FUNCTION_VERSIONED (newdecl)
+ && !DECL_FUNCTION_VERSIONED (olddecl))
+ && compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
+ TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
+ {
+ error ("ambiguating new declaration of %q#D", newdecl);
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "old declaration %q#D", olddecl);
+ return error_mark_node;
+ }
+ else
+ return NULL_TREE;
+ }
+ else
+ {
+ error ("conflicting declaration %q#D", newdecl);
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous declaration as %q#D", olddecl);
+ return error_mark_node;
+ }
+ }
+ else if (TREE_CODE (newdecl) == FUNCTION_DECL
+ && ((DECL_TEMPLATE_SPECIALIZATION (olddecl)
+ && (!DECL_TEMPLATE_INFO (newdecl)
+ || (DECL_TI_TEMPLATE (newdecl)
+ != DECL_TI_TEMPLATE (olddecl))))
+ || (DECL_TEMPLATE_SPECIALIZATION (newdecl)
+ && (!DECL_TEMPLATE_INFO (olddecl)
+ || (DECL_TI_TEMPLATE (olddecl)
+ != DECL_TI_TEMPLATE (newdecl))))))
+ /* It's OK to have a template specialization and a non-template
+ with the same type, or to have specializations of two
+ different templates with the same type. Note that if one is a
+ specialization, and the other is an instantiation of the same
+ template, that we do not exit at this point. That situation
+ can occur if we instantiate a template class, and then
+ specialize one of its methods. This situation is valid, but
+ the declarations must be merged in the usual way. */
+ return NULL_TREE;
+ else if (TREE_CODE (newdecl) == FUNCTION_DECL
+ && ((DECL_TEMPLATE_INSTANTIATION (olddecl)
+ && !DECL_USE_TEMPLATE (newdecl))
+ || (DECL_TEMPLATE_INSTANTIATION (newdecl)
+ && !DECL_USE_TEMPLATE (olddecl))))
+ /* One of the declarations is a template instantiation, and the
+ other is not a template at all. That's OK. */
+ return NULL_TREE;
+ else if (TREE_CODE (newdecl) == NAMESPACE_DECL)
+ {
+ /* In [namespace.alias] we have:
+
+ In a declarative region, a namespace-alias-definition can be
+ used to redefine a namespace-alias declared in that declarative
+ region to refer only to the namespace to which it already
+ refers.
+
+ Therefore, if we encounter a second alias directive for the same
+ alias, we can just ignore the second directive. */
+ if (DECL_NAMESPACE_ALIAS (newdecl)
+ && (DECL_NAMESPACE_ALIAS (newdecl)
+ == DECL_NAMESPACE_ALIAS (olddecl)))
+ return olddecl;
+ /* [namespace.alias]
+
+ A namespace-name or namespace-alias shall not be declared as
+ the name of any other entity in the same declarative region.
+ A namespace-name defined at global scope shall not be
+ declared as the name of any other entity in any global scope
+ of the program. */
+ error ("conflicting declaration of namespace %qD", newdecl);
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous declaration of namespace %qD here", olddecl);
+ return error_mark_node;
+ }
+ else
+ {
+ const char *errmsg = redeclaration_error_message (newdecl, olddecl);
+ if (errmsg)
+ {
+ error_at (DECL_SOURCE_LOCATION (newdecl), errmsg, newdecl);
+ if (DECL_NAME (olddecl) != NULL_TREE)
+ inform (input_location,
+ (DECL_INITIAL (olddecl) && namespace_bindings_p ())
+ ? G_("%q+#D previously defined here")
+ : G_("%q+#D previously declared here"), olddecl);
+ return error_mark_node;
+ }
+ else if (TREE_CODE (olddecl) == FUNCTION_DECL
+ && DECL_INITIAL (olddecl) != NULL_TREE
+ && !prototype_p (TREE_TYPE (olddecl))
+ && prototype_p (TREE_TYPE (newdecl)))
+ {
+ /* Prototype decl follows defn w/o prototype. */
+ warning_at (DECL_SOURCE_LOCATION (newdecl), 0,
+ "prototype specified for %q#D", newdecl);
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous non-prototype definition here");
+ }
+ else if (VAR_OR_FUNCTION_DECL_P (olddecl)
+ && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))
+ {
+ /* [dcl.link]
+ If two declarations of the same function or object
+ specify different linkage-specifications ..., the program
+ is ill-formed.... Except for functions with C++ linkage,
+ a function declaration without a linkage specification
+ shall not precede the first linkage specification for
+ that function. A function can be declared without a
+ linkage specification after an explicit linkage
+ specification has been seen; the linkage explicitly
+ specified in the earlier declaration is not affected by
+ such a function declaration.
+
+ DR 563 raises the question why the restrictions on
+ functions should not also apply to objects. Older
+ versions of G++ silently ignore the linkage-specification
+ for this example:
+
+ namespace N {
+ extern int i;
+ extern "C" int i;
+ }
+
+ which is clearly wrong. Therefore, we now treat objects
+ like functions. */
+ if (current_lang_depth () == 0)
+ {
+ /* There is no explicit linkage-specification, so we use
+ the linkage from the previous declaration. */
+ if (!DECL_LANG_SPECIFIC (newdecl))
+ retrofit_lang_decl (newdecl);
+ SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
+ }
+ else
+ {
+ error ("conflicting declaration of %q#D with %qL linkage",
+ newdecl, DECL_LANGUAGE (newdecl));
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous declaration with %qL linkage",
+ DECL_LANGUAGE (olddecl));
+ }
+ }
+
+ if (DECL_LANG_SPECIFIC (olddecl) && DECL_USE_TEMPLATE (olddecl))
+ ;
+ else if (TREE_CODE (olddecl) == FUNCTION_DECL)
+ {
+ tree t1 = TYPE_ARG_TYPES (TREE_TYPE (olddecl));
+ tree t2 = TYPE_ARG_TYPES (TREE_TYPE (newdecl));
+ int i = 1;
+
+ if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE)
+ t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2);
+
+ if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE
+ && CLASSTYPE_TEMPLATE_INFO (CP_DECL_CONTEXT (newdecl)))
+ {
+ /* C++11 8.3.6/6.
+ Default arguments for a member function of a class template
+ shall be specified on the initial declaration of the member
+ function within the class template. */
+ for (; t2 && t2 != void_list_node; t2 = TREE_CHAIN (t2))
+ if (TREE_PURPOSE (t2))
+ {
+ permerror (input_location,
+ "redeclaration of %q#D may not have default "
+ "arguments", newdecl);
+ break;
+ }
+ }
+ else
+ {
+ for (; t1 && t1 != void_list_node;
+ t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++)
+ if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
+ {
+ if (1 == simple_cst_equal (TREE_PURPOSE (t1),
+ TREE_PURPOSE (t2)))
+ {
+ if (permerror (input_location,
+ "default argument given for parameter "
+ "%d of %q#D", i, newdecl))
+ permerror (DECL_SOURCE_LOCATION (olddecl),
+ "previous specification in %q#D here",
+ olddecl);
+ }
+ else
+ {
+ error ("default argument given for parameter %d "
+ "of %q#D", i, newdecl);
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous specification in %q#D here",
+ olddecl);
+ }
+ }
+ }
+ }
+ }
+
+ /* Do not merge an implicit typedef with an explicit one. In:
+
+ class A;
+ ...
+ typedef class A A __attribute__ ((foo));
+
+ the attribute should apply only to the typedef. */
+ if (TREE_CODE (olddecl) == TYPE_DECL
+ && (DECL_IMPLICIT_TYPEDEF_P (olddecl)
+ || DECL_IMPLICIT_TYPEDEF_P (newdecl)))
+ return NULL_TREE;
+
+ /* If new decl is `static' and an `extern' was seen previously,
+ warn about it. */
+ warn_extern_redeclared_static (newdecl, olddecl);
+
+ if (!validate_constexpr_redeclaration (olddecl, newdecl))
+ return error_mark_node;
+
+ /* We have committed to returning 1 at this point. */
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ /* Now that functions must hold information normally held
+ by field decls, there is extra work to do so that
+ declaration information does not get destroyed during
+ definition. */
+ if (DECL_VINDEX (olddecl))
+ DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl);
+ if (DECL_CONTEXT (olddecl))
+ DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
+ DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl);
+ DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
+ DECL_PURE_VIRTUAL_P (newdecl) |= DECL_PURE_VIRTUAL_P (olddecl);
+ DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
+ DECL_INVALID_OVERRIDER_P (newdecl) |= DECL_INVALID_OVERRIDER_P (olddecl);
+ DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
+ if (DECL_OVERLOADED_OPERATOR_P (olddecl) != ERROR_MARK)
+ SET_OVERLOADED_OPERATOR_CODE
+ (newdecl, DECL_OVERLOADED_OPERATOR_P (olddecl));
+ new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
+
+ /* Optionally warn about more than one declaration for the same
+ name, but don't warn about a function declaration followed by a
+ definition. */
+ if (warn_redundant_decls && ! DECL_ARTIFICIAL (olddecl)
+ && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)
+ /* Don't warn about extern decl followed by definition. */
+ && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl))
+ /* Don't warn about friends, let add_friend take care of it. */
+ && ! (newdecl_is_friend || DECL_FRIEND_P (olddecl))
+ /* Don't warn about declaration followed by specialization. */
+ && (! DECL_TEMPLATE_SPECIALIZATION (newdecl)
+ || DECL_TEMPLATE_SPECIALIZATION (olddecl)))
+ {
+ if (warning (OPT_Wredundant_decls,
+ "redundant redeclaration of %qD in same scope",
+ newdecl))
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous declaration of %qD", olddecl);
+ }
+
+ if (!(DECL_TEMPLATE_INSTANTIATION (olddecl)
+ && DECL_TEMPLATE_SPECIALIZATION (newdecl)))
+ {
+ if (DECL_DELETED_FN (newdecl))
+ {
+ error ("deleted definition of %qD", newdecl);
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous declaration of %qD", olddecl);
+ }
+ DECL_DELETED_FN (newdecl) |= DECL_DELETED_FN (olddecl);
+ }
+ }
+
+ /* Deal with C++: must preserve virtual function table size. */
+ if (TREE_CODE (olddecl) == TYPE_DECL)
+ {
+ tree newtype = TREE_TYPE (newdecl);
+ tree oldtype = TREE_TYPE (olddecl);
+
+ if (newtype != error_mark_node && oldtype != error_mark_node
+ && TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype))
+ CLASSTYPE_FRIEND_CLASSES (newtype)
+ = CLASSTYPE_FRIEND_CLASSES (oldtype);
+
+ DECL_ORIGINAL_TYPE (newdecl) = DECL_ORIGINAL_TYPE (olddecl);
+ }
+
+ /* Copy all the DECL_... slots specified in the new decl
+ except for any that we copy here from the old type. */
+ DECL_ATTRIBUTES (newdecl)
+ = (*targetm.merge_decl_attributes) (olddecl, newdecl);
+
+ if (TREE_CODE (newdecl) == TEMPLATE_DECL)
+ {
+ tree old_result;
+ tree new_result;
+ old_result = DECL_TEMPLATE_RESULT (olddecl);
+ new_result = DECL_TEMPLATE_RESULT (newdecl);
+ TREE_TYPE (olddecl) = TREE_TYPE (old_result);
+ DECL_TEMPLATE_SPECIALIZATIONS (olddecl)
+ = chainon (DECL_TEMPLATE_SPECIALIZATIONS (olddecl),
+ DECL_TEMPLATE_SPECIALIZATIONS (newdecl));
+
+ DECL_ATTRIBUTES (old_result)
+ = (*targetm.merge_decl_attributes) (old_result, new_result);
+
+ if (DECL_FUNCTION_TEMPLATE_P (newdecl))
+ {
+ if (GNU_INLINE_P (old_result) != GNU_INLINE_P (new_result)
+ && DECL_INITIAL (new_result))
+ {
+ if (DECL_INITIAL (old_result))
+ DECL_UNINLINABLE (old_result) = 1;
+ else
+ DECL_UNINLINABLE (old_result) = DECL_UNINLINABLE (new_result);
+ DECL_EXTERNAL (old_result) = DECL_EXTERNAL (new_result);
+ DECL_NOT_REALLY_EXTERN (old_result)
+ = DECL_NOT_REALLY_EXTERN (new_result);
+ DECL_INTERFACE_KNOWN (old_result)
+ = DECL_INTERFACE_KNOWN (new_result);
+ DECL_DECLARED_INLINE_P (old_result)
+ = DECL_DECLARED_INLINE_P (new_result);
+ DECL_DISREGARD_INLINE_LIMITS (old_result)
+ |= DECL_DISREGARD_INLINE_LIMITS (new_result);
+
+ }
+ else
+ {
+ DECL_DECLARED_INLINE_P (old_result)
+ |= DECL_DECLARED_INLINE_P (new_result);
+ DECL_DISREGARD_INLINE_LIMITS (old_result)
+ |= DECL_DISREGARD_INLINE_LIMITS (new_result);
+ check_redeclaration_exception_specification (newdecl, olddecl);
+ }
+ }
+
+ /* If the new declaration is a definition, update the file and
+ line information on the declaration, and also make
+ the old declaration the same definition. */
+ if (DECL_INITIAL (new_result) != NULL_TREE)
+ {
+ DECL_SOURCE_LOCATION (olddecl)
+ = DECL_SOURCE_LOCATION (old_result)
+ = DECL_SOURCE_LOCATION (newdecl);
+ DECL_INITIAL (old_result) = DECL_INITIAL (new_result);
+ if (DECL_FUNCTION_TEMPLATE_P (newdecl))
+ {
+ tree parm;
+ DECL_ARGUMENTS (old_result)
+ = DECL_ARGUMENTS (new_result);
+ for (parm = DECL_ARGUMENTS (old_result); parm;
+ parm = DECL_CHAIN (parm))
+ DECL_CONTEXT (parm) = old_result;
+ }
+ }
+
+ return olddecl;
+ }
+
+ if (types_match)
+ {
+ /* Automatically handles default parameters. */
+ tree oldtype = TREE_TYPE (olddecl);
+ tree newtype;
+
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ maybe_instantiate_noexcept (olddecl);
+
+ /* For typedefs use the old type, as the new type's DECL_NAME points
+ at newdecl, which will be ggc_freed. */
+ if (TREE_CODE (newdecl) == TYPE_DECL)
+ newtype = oldtype;
+ else
+ /* Merge the data types specified in the two decls. */
+ newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
+
+ if (VAR_P (newdecl))
+ {
+ DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
+ DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl);
+ DECL_NONTRIVIALLY_INITIALIZED_P (newdecl)
+ |= DECL_NONTRIVIALLY_INITIALIZED_P (olddecl);
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl)
+ |= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl);
+
+ /* Merge the threadprivate attribute from OLDDECL into NEWDECL. */
+ if (DECL_LANG_SPECIFIC (olddecl)
+ && CP_DECL_THREADPRIVATE_P (olddecl))
+ {
+ /* Allocate a LANG_SPECIFIC structure for NEWDECL, if needed. */
+ if (!DECL_LANG_SPECIFIC (newdecl))
+ retrofit_lang_decl (newdecl);
+
+ DECL_TLS_MODEL (newdecl) = DECL_TLS_MODEL (olddecl);
+ CP_DECL_THREADPRIVATE_P (newdecl) = 1;
+ }
+ }
+
+ /* Do this after calling `merge_types' so that default
+ parameters don't confuse us. */
+ else if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ check_redeclaration_exception_specification (newdecl, olddecl);
+ TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype;
+
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ check_default_args (newdecl);
+
+ /* Lay the type out, unless already done. */
+ if (! same_type_p (newtype, oldtype)
+ && TREE_TYPE (newdecl) != error_mark_node
+ && !(processing_template_decl && uses_template_parms (newdecl)))
+ layout_type (TREE_TYPE (newdecl));
+
+ if ((VAR_P (newdecl)
+ || TREE_CODE (newdecl) == PARM_DECL
+ || TREE_CODE (newdecl) == RESULT_DECL
+ || TREE_CODE (newdecl) == FIELD_DECL
+ || TREE_CODE (newdecl) == TYPE_DECL)
+ && !(processing_template_decl && uses_template_parms (newdecl)))
+ layout_decl (newdecl, 0);
+
+ /* Merge the type qualifiers. */
+ if (TREE_READONLY (newdecl))
+ TREE_READONLY (olddecl) = 1;
+ if (TREE_THIS_VOLATILE (newdecl))
+ TREE_THIS_VOLATILE (olddecl) = 1;
+ if (TREE_NOTHROW (newdecl))
+ TREE_NOTHROW (olddecl) = 1;
+
+ /* Merge deprecatedness. */
+ if (TREE_DEPRECATED (newdecl))
+ TREE_DEPRECATED (olddecl) = 1;
+
+ /* Preserve function specific target and optimization options */
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ if (DECL_FUNCTION_SPECIFIC_TARGET (olddecl)
+ && !DECL_FUNCTION_SPECIFIC_TARGET (newdecl))
+ DECL_FUNCTION_SPECIFIC_TARGET (newdecl)
+ = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
+
+ if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl)
+ && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl))
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl)
+ = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl);
+ }
+
+ /* Merge the initialization information. */
+ if (DECL_INITIAL (newdecl) == NULL_TREE
+ && DECL_INITIAL (olddecl) != NULL_TREE)
+ {
+ DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
+ DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
+ DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
+ }
+ }
+
+ /* Merge the section attribute.
+ We want to issue an error if the sections conflict but that must be
+ done later in decl_attributes since we are called before attributes
+ are assigned. */
+ if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
+ DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
+
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
+ |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
+ DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
+ TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
+ TREE_NOTHROW (newdecl) |= TREE_NOTHROW (olddecl);
+ DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
+ DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl);
+ DECL_PURE_P (newdecl) |= DECL_PURE_P (olddecl);
+ TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
+ DECL_LOOPING_CONST_OR_PURE_P (newdecl)
+ |= DECL_LOOPING_CONST_OR_PURE_P (olddecl);
+ /* Keep the old RTL. */
+ COPY_DECL_RTL (olddecl, newdecl);
+ }
+ else if (VAR_P (newdecl)
+ && (DECL_SIZE (olddecl) || !DECL_SIZE (newdecl)))
+ {
+ /* Keep the old RTL. We cannot keep the old RTL if the old
+ declaration was for an incomplete object and the new
+ declaration is not since many attributes of the RTL will
+ change. */
+ COPY_DECL_RTL (olddecl, newdecl);
+ }
+ }
+ /* If cannot merge, then use the new type and qualifiers,
+ and don't preserve the old rtl. */
+ else
+ {
+ /* Clean out any memory we had of the old declaration. */
+ tree oldstatic = value_member (olddecl, static_aggregates);
+ if (oldstatic)
+ TREE_VALUE (oldstatic) = error_mark_node;
+
+ TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
+ TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
+ TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
+ TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
+ }
+
+ /* Merge the storage class information. */
+ merge_weak (newdecl, olddecl);
+
+ if (DECL_ONE_ONLY (olddecl))
+ DECL_COMDAT_GROUP (newdecl) = DECL_COMDAT_GROUP (olddecl);
+
+ DECL_DEFER_OUTPUT (newdecl) |= DECL_DEFER_OUTPUT (olddecl);
+ TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
+ TREE_STATIC (olddecl) = TREE_STATIC (newdecl) |= TREE_STATIC (olddecl);
+ if (! DECL_EXTERNAL (olddecl))
+ DECL_EXTERNAL (newdecl) = 0;
+
+ new_template_info = NULL_TREE;
+ if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl))
+ {
+ bool new_redefines_gnu_inline = false;
+
+ if (new_defines_function
+ && ((DECL_INTERFACE_KNOWN (olddecl)
+ && TREE_CODE (olddecl) == FUNCTION_DECL)
+ || (TREE_CODE (olddecl) == TEMPLATE_DECL
+ && (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl))
+ == FUNCTION_DECL))))
+ {
+ tree fn = olddecl;
+
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ fn = DECL_TEMPLATE_RESULT (olddecl);
+
+ new_redefines_gnu_inline = GNU_INLINE_P (fn) && DECL_INITIAL (fn);
+ }
+
+ if (!new_redefines_gnu_inline)
+ {
+ DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
+ DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
+ DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
+ }
+ DECL_TEMPLATE_INSTANTIATED (newdecl)
+ |= DECL_TEMPLATE_INSTANTIATED (olddecl);
+ DECL_ODR_USED (newdecl) |= DECL_ODR_USED (olddecl);
+
+ /* If the OLDDECL is an instantiation and/or specialization,
+ then the NEWDECL must be too. But, it may not yet be marked
+ as such if the caller has created NEWDECL, but has not yet
+ figured out that it is a redeclaration. */
+ if (!DECL_USE_TEMPLATE (newdecl))
+ DECL_USE_TEMPLATE (newdecl) = DECL_USE_TEMPLATE (olddecl);
+
+ /* Don't really know how much of the language-specific
+ values we should copy from old to new. */
+ DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
+ DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl);
+ DECL_INITIALIZED_IN_CLASS_P (newdecl)
+ |= DECL_INITIALIZED_IN_CLASS_P (olddecl);
+
+ if (LANG_DECL_HAS_MIN (newdecl))
+ {
+ DECL_LANG_SPECIFIC (newdecl)->u.min.u2 =
+ DECL_LANG_SPECIFIC (olddecl)->u.min.u2;
+ if (DECL_TEMPLATE_INFO (newdecl))
+ new_template_info = DECL_TEMPLATE_INFO (newdecl);
+ DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
+ }
+ /* Only functions have these fields. */
+ if (DECL_DECLARES_FUNCTION_P (newdecl))
+ {
+ DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
+ olddecl_friend = DECL_FRIEND_P (olddecl);
+ hidden_friend = (DECL_ANTICIPATED (olddecl)
+ && DECL_HIDDEN_FRIEND_P (olddecl)
+ && newdecl_is_friend);
+ DECL_BEFRIENDING_CLASSES (newdecl)
+ = chainon (DECL_BEFRIENDING_CLASSES (newdecl),
+ DECL_BEFRIENDING_CLASSES (olddecl));
+ /* DECL_THUNKS is only valid for virtual functions,
+ otherwise it is a DECL_FRIEND_CONTEXT. */
+ if (DECL_VIRTUAL_P (newdecl))
+ SET_DECL_THUNKS (newdecl, DECL_THUNKS (olddecl));
+ }
+ /* Only variables have this field. */
+ else if (VAR_P (newdecl)
+ && VAR_HAD_UNKNOWN_BOUND (olddecl))
+ SET_VAR_HAD_UNKNOWN_BOUND (newdecl);
+ }
+
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ tree parm;
+
+ /* Merge parameter attributes. */
+ tree oldarg, newarg;
+ for (oldarg = DECL_ARGUMENTS(olddecl),
+ newarg = DECL_ARGUMENTS(newdecl);
+ oldarg && newarg;
+ oldarg = DECL_CHAIN(oldarg), newarg = DECL_CHAIN(newarg)) {
+ DECL_ATTRIBUTES (newarg)
+ = (*targetm.merge_decl_attributes) (oldarg, newarg);
+ DECL_ATTRIBUTES (oldarg) = DECL_ATTRIBUTES (newarg);
+ }
+
+ if (DECL_TEMPLATE_INSTANTIATION (olddecl)
+ && !DECL_TEMPLATE_INSTANTIATION (newdecl))
+ {
+ /* If newdecl is not a specialization, then it is not a
+ template-related function at all. And that means that we
+ should have exited above, returning 0. */
+ gcc_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl));
+
+ if (DECL_ODR_USED (olddecl))
+ /* From [temp.expl.spec]:
+
+ If a template, a member template or the member of a class
+ template is explicitly specialized then that
+ specialization shall be declared before the first use of
+ that specialization that would cause an implicit
+ instantiation to take place, in every translation unit in
+ which such a use occurs. */
+ error ("explicit specialization of %qD after first use",
+ olddecl);
+
+ SET_DECL_TEMPLATE_SPECIALIZATION (olddecl);
+
+ /* Don't propagate visibility from the template to the
+ specialization here. We'll do that in determine_visibility if
+ appropriate. */
+ DECL_VISIBILITY_SPECIFIED (olddecl) = 0;
+
+ /* [temp.expl.spec/14] We don't inline explicit specialization
+ just because the primary template says so. */
+
+ /* But still keep DECL_DISREGARD_INLINE_LIMITS in sync with
+ the always_inline attribute. */
+ if (DECL_DISREGARD_INLINE_LIMITS (olddecl)
+ && !DECL_DISREGARD_INLINE_LIMITS (newdecl))
+ {
+ if (DECL_DECLARED_INLINE_P (newdecl))
+ DECL_DISREGARD_INLINE_LIMITS (newdecl) = true;
+ else
+ DECL_ATTRIBUTES (newdecl)
+ = remove_attribute ("always_inline",
+ DECL_ATTRIBUTES (newdecl));
+ }
+ }
+ else if (new_defines_function && DECL_INITIAL (olddecl))
+ {
+ /* Never inline re-defined extern inline functions.
+ FIXME: this could be better handled by keeping both
+ function as separate declarations. */
+ DECL_UNINLINABLE (newdecl) = 1;
+ }
+ else
+ {
+ if (DECL_PENDING_INLINE_INFO (newdecl) == 0)
+ DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl);
+
+ DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl);
+
+ DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
+ = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
+
+ DECL_DISREGARD_INLINE_LIMITS (newdecl)
+ = DECL_DISREGARD_INLINE_LIMITS (olddecl)
+ = (DECL_DISREGARD_INLINE_LIMITS (newdecl)
+ || DECL_DISREGARD_INLINE_LIMITS (olddecl));
+ }
+
+ /* Preserve abstractness on cloned [cd]tors. */
+ DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl);
+
+ /* Update newdecl's parms to point at olddecl. */
+ for (parm = DECL_ARGUMENTS (newdecl); parm;
+ parm = DECL_CHAIN (parm))
+ DECL_CONTEXT (parm) = olddecl;
+
+ if (! types_match)
+ {
+ SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
+ COPY_DECL_ASSEMBLER_NAME (newdecl, olddecl);
+ COPY_DECL_RTL (newdecl, olddecl);
+ }
+ if (! types_match || new_defines_function)
+ {
+ /* These need to be copied so that the names are available.
+ Note that if the types do match, we'll preserve inline
+ info and other bits, but if not, we won't. */
+ DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl);
+ DECL_RESULT (olddecl) = DECL_RESULT (newdecl);
+ }
+ /* If redeclaring a builtin function, it stays built in
+ if newdecl is a gnu_inline definition, or if newdecl is just
+ a declaration. */
+ if (DECL_BUILT_IN (olddecl)
+ && (new_defines_function ? GNU_INLINE_P (newdecl) : types_match))
+ {
+ DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
+ DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
+ /* If we're keeping the built-in definition, keep the rtl,
+ regardless of declaration matches. */
+ COPY_DECL_RTL (olddecl, newdecl);
+ if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
+ {
+ enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
+ switch (fncode)
+ {
+ /* If a compatible prototype of these builtin functions
+ is seen, assume the runtime implements it with the
+ expected semantics. */
+ case BUILT_IN_STPCPY:
+ if (builtin_decl_explicit_p (fncode))
+ set_builtin_decl_implicit_p (fncode, true);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (new_defines_function)
+ /* If defining a function declared with other language
+ linkage, use the previously declared language linkage. */
+ SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
+ else if (types_match)
+ {
+ DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
+ /* Don't clear out the arguments if we're just redeclaring a
+ function. */
+ if (DECL_ARGUMENTS (olddecl))
+ DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
+ }
+ }
+ else if (TREE_CODE (newdecl) == NAMESPACE_DECL)
+ NAMESPACE_LEVEL (newdecl) = NAMESPACE_LEVEL (olddecl);
+
+ /* Now preserve various other info from the definition. */
+ TREE_ADDRESSABLE (newdecl) = TREE_ADDRESSABLE (olddecl);
+ TREE_ASM_WRITTEN (newdecl) = TREE_ASM_WRITTEN (olddecl);
+ DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
+ COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
+
+ /* Warn about conflicting visibility specifications. */
+ if (DECL_VISIBILITY_SPECIFIED (olddecl)
+ && DECL_VISIBILITY_SPECIFIED (newdecl)
+ && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
+ {
+ warning_at (input_location, OPT_Wattributes,
+ "%q+D: visibility attribute ignored because it", newdecl);
+ warning_at (DECL_SOURCE_LOCATION (olddecl), OPT_Wattributes,
+ "conflicts with previous declaration here");
+ }
+ /* Choose the declaration which specified visibility. */
+ if (DECL_VISIBILITY_SPECIFIED (olddecl))
+ {
+ DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
+ DECL_VISIBILITY_SPECIFIED (newdecl) = 1;
+ }
+ /* Init priority used to be merged from newdecl to olddecl by the memcpy,
+ so keep this behavior. */
+ if (VAR_P (newdecl) && DECL_HAS_INIT_PRIORITY_P (newdecl))
+ {
+ SET_DECL_INIT_PRIORITY (olddecl, DECL_INIT_PRIORITY (newdecl));
+ DECL_HAS_INIT_PRIORITY_P (olddecl) = 1;
+ }
+ /* Likewise for DECL_ALIGN, DECL_USER_ALIGN and DECL_PACKED. */
+ if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
+ {
+ DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
+ DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
+ }
+ DECL_USER_ALIGN (olddecl) = DECL_USER_ALIGN (newdecl);
+ if (TREE_CODE (newdecl) == FIELD_DECL)
+ DECL_PACKED (olddecl) = DECL_PACKED (newdecl);
+
+ /* The DECL_LANG_SPECIFIC information in OLDDECL will be replaced
+ with that from NEWDECL below. */
+ if (DECL_LANG_SPECIFIC (olddecl))
+ {
+ gcc_assert (DECL_LANG_SPECIFIC (olddecl)
+ != DECL_LANG_SPECIFIC (newdecl));
+ ggc_free (DECL_LANG_SPECIFIC (olddecl));
+ }
+
+ /* Merge the USED information. */
+ if (TREE_USED (olddecl))
+ TREE_USED (newdecl) = 1;
+ else if (TREE_USED (newdecl))
+ TREE_USED (olddecl) = 1;
+ if (VAR_P (newdecl))
+ {
+ if (DECL_READ_P (olddecl))
+ DECL_READ_P (newdecl) = 1;
+ else if (DECL_READ_P (newdecl))
+ DECL_READ_P (olddecl) = 1;
+ }
+ if (DECL_PRESERVE_P (olddecl))
+ DECL_PRESERVE_P (newdecl) = 1;
+ else if (DECL_PRESERVE_P (newdecl))
+ DECL_PRESERVE_P (olddecl) = 1;
+
+ /* Merge the DECL_FUNCTION_VERSIONED information. newdecl will be copied
+ to olddecl and deleted. */
+ if (TREE_CODE (newdecl) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (olddecl))
+ {
+ /* Set the flag for newdecl so that it gets copied to olddecl. */
+ DECL_FUNCTION_VERSIONED (newdecl) = 1;
+ /* newdecl will be purged after copying to olddecl and is no longer
+ a version. */
+ delete_function_version (newdecl);
+ }
+
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ int function_size;
+
+ function_size = sizeof (struct tree_decl_common);
+
+ memcpy ((char *) olddecl + sizeof (struct tree_common),
+ (char *) newdecl + sizeof (struct tree_common),
+ function_size - sizeof (struct tree_common));
+
+ memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
+ (char *) newdecl + sizeof (struct tree_decl_common),
+ sizeof (struct tree_function_decl) - sizeof (struct tree_decl_common));
+ if (new_template_info)
+ /* If newdecl is a template instantiation, it is possible that
+ the following sequence of events has occurred:
+
+ o A friend function was declared in a class template. The
+ class template was instantiated.
+
+ o The instantiation of the friend declaration was
+ recorded on the instantiation list, and is newdecl.
+
+ o Later, however, instantiate_class_template called pushdecl
+ on the newdecl to perform name injection. But, pushdecl in
+ turn called duplicate_decls when it discovered that another
+ declaration of a global function with the same name already
+ existed.
+
+ o Here, in duplicate_decls, we decided to clobber newdecl.
+
+ If we're going to do that, we'd better make sure that
+ olddecl, and not newdecl, is on the list of
+ instantiations so that if we try to do the instantiation
+ again we won't get the clobbered declaration. */
+ reregister_specialization (newdecl,
+ new_template_info,
+ olddecl);
+ }
+ else
+ {
+ size_t size = tree_code_size (TREE_CODE (olddecl));
+ memcpy ((char *) olddecl + sizeof (struct tree_common),
+ (char *) newdecl + sizeof (struct tree_common),
+ sizeof (struct tree_decl_common) - sizeof (struct tree_common));
+ switch (TREE_CODE (olddecl))
+ {
+ case LABEL_DECL:
+ case VAR_DECL:
+ case RESULT_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ case TYPE_DECL:
+ case CONST_DECL:
+ {
+ memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
+ (char *) newdecl + sizeof (struct tree_decl_common),
+ size - sizeof (struct tree_decl_common)
+ + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *));
+ }
+ break;
+ default:
+ memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
+ (char *) newdecl + sizeof (struct tree_decl_common),
+ sizeof (struct tree_decl_non_common) - sizeof (struct tree_decl_common)
+ + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *));
+ break;
+ }
+ }
+ DECL_UID (olddecl) = olddecl_uid;
+ if (olddecl_friend)
+ DECL_FRIEND_P (olddecl) = 1;
+ if (hidden_friend)
+ {
+ DECL_ANTICIPATED (olddecl) = 1;
+ DECL_HIDDEN_FRIEND_P (olddecl) = 1;
+ }
+
+ /* NEWDECL contains the merged attribute lists.
+ Update OLDDECL to be the same. */
+ DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
+
+ /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
+ so that encode_section_info has a chance to look at the new decl
+ flags and attributes. */
+ if (DECL_RTL_SET_P (olddecl)
+ && (TREE_CODE (olddecl) == FUNCTION_DECL
+ || (VAR_P (olddecl)
+ && TREE_STATIC (olddecl))))
+ make_decl_rtl (olddecl);
+
+ /* The NEWDECL will no longer be needed. Because every out-of-class
+ declaration of a member results in a call to duplicate_decls,
+ freeing these nodes represents in a significant savings. */
+ ggc_free (newdecl);
+
+ return olddecl;
+}
+
+/* Return zero if the declaration NEWDECL is valid
+ when the declaration OLDDECL (assumed to be for the same name)
+ has already been seen.
+ Otherwise return an error message format string with a %s
+ where the identifier should go. */
+
+static const char *
+redeclaration_error_message (tree newdecl, tree olddecl)
+{
+ if (TREE_CODE (newdecl) == TYPE_DECL)
+ {
+ /* Because C++ can put things into name space for free,
+ constructs like "typedef struct foo { ... } foo"
+ would look like an erroneous redeclaration. */
+ if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl)))
+ return NULL;
+ else
+ return G_("redefinition of %q#D");
+ }
+ else if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ /* If this is a pure function, its olddecl will actually be
+ the original initialization to `0' (which we force to call
+ abort()). Don't complain about redefinition in this case. */
+ if (DECL_LANG_SPECIFIC (olddecl) && DECL_PURE_VIRTUAL_P (olddecl)
+ && DECL_INITIAL (olddecl) == NULL_TREE)
+ return NULL;
+
+ /* If both functions come from different namespaces, this is not
+ a redeclaration - this is a conflict with a used function. */
+ if (DECL_NAMESPACE_SCOPE_P (olddecl)
+ && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)
+ && ! decls_match (olddecl, newdecl))
+ return G_("%qD conflicts with used function");
+
+ /* We'll complain about linkage mismatches in
+ warn_extern_redeclared_static. */
+
+ /* Defining the same name twice is no good. */
+ if (DECL_INITIAL (olddecl) != NULL_TREE
+ && DECL_INITIAL (newdecl) != NULL_TREE)
+ {
+ if (DECL_NAME (olddecl) == NULL_TREE)
+ return G_("%q#D not declared in class");
+ else if (!GNU_INLINE_P (olddecl)
+ || GNU_INLINE_P (newdecl))
+ return G_("redefinition of %q#D");
+ }
+
+ if (DECL_DECLARED_INLINE_P (olddecl) && DECL_DECLARED_INLINE_P (newdecl))
+ {
+ bool olda = GNU_INLINE_P (olddecl);
+ bool newa = GNU_INLINE_P (newdecl);
+
+ if (olda != newa)
+ {
+ if (newa)
+ return G_("%q+D redeclared inline with "
+ "%<gnu_inline%> attribute");
+ else
+ return G_("%q+D redeclared inline without "
+ "%<gnu_inline%> attribute");
+ }
+ }
+
+ check_abi_tag_redeclaration
+ (olddecl, lookup_attribute ("abi_tag", DECL_ATTRIBUTES (olddecl)),
+ lookup_attribute ("abi_tag", DECL_ATTRIBUTES (newdecl)));
+
+ return NULL;
+ }
+ else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
+ {
+ tree nt, ot;
+
+ if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
+ {
+ if (COMPLETE_TYPE_P (TREE_TYPE (newdecl))
+ && COMPLETE_TYPE_P (TREE_TYPE (olddecl)))
+ return G_("redefinition of %q#D");
+ return NULL;
+ }
+
+ if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) != FUNCTION_DECL
+ || (DECL_TEMPLATE_RESULT (newdecl)
+ == DECL_TEMPLATE_RESULT (olddecl)))
+ return NULL;
+
+ nt = DECL_TEMPLATE_RESULT (newdecl);
+ if (DECL_TEMPLATE_INFO (nt))
+ nt = DECL_TEMPLATE_RESULT (template_for_substitution (nt));
+ ot = DECL_TEMPLATE_RESULT (olddecl);
+ if (DECL_TEMPLATE_INFO (ot))
+ ot = DECL_TEMPLATE_RESULT (template_for_substitution (ot));
+ if (DECL_INITIAL (nt) && DECL_INITIAL (ot)
+ && (!GNU_INLINE_P (ot) || GNU_INLINE_P (nt)))
+ return G_("redefinition of %q#D");
+
+ if (DECL_DECLARED_INLINE_P (ot) && DECL_DECLARED_INLINE_P (nt))
+ {
+ bool olda = GNU_INLINE_P (ot);
+ bool newa = GNU_INLINE_P (nt);
+
+ if (olda != newa)
+ {
+ if (newa)
+ return G_("%q+D redeclared inline with "
+ "%<gnu_inline%> attribute");
+ else
+ return G_("%q+D redeclared inline without "
+ "%<gnu_inline%> attribute");
+ }
+ }
+
+ /* Core issue #226 (C++0x):
+
+ If a friend function template declaration specifies a
+ default template-argument, that declaration shall be a
+ definition and shall be the only declaration of the
+ function template in the translation unit. */
+ if ((cxx_dialect != cxx98)
+ && TREE_CODE (ot) == FUNCTION_DECL && DECL_FRIEND_P (ot)
+ && !check_default_tmpl_args (nt, DECL_TEMPLATE_PARMS (newdecl),
+ /*is_primary=*/true,
+ /*is_partial=*/false,
+ /*is_friend_decl=*/2))
+ return G_("redeclaration of friend %q#D "
+ "may not have default template arguments");
+
+ return NULL;
+ }
+ else if (VAR_P (newdecl)
+ && DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl)
+ && (! DECL_LANG_SPECIFIC (olddecl)
+ || ! CP_DECL_THREADPRIVATE_P (olddecl)
+ || DECL_THREAD_LOCAL_P (newdecl)))
+ {
+ /* Only variables can be thread-local, and all declarations must
+ agree on this property. */
+ if (DECL_THREAD_LOCAL_P (newdecl))
+ return G_("thread-local declaration of %q#D follows "
+ "non-thread-local declaration");
+ else
+ return G_("non-thread-local declaration of %q#D follows "
+ "thread-local declaration");
+ }
+ else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl))
+ {
+ /* The objects have been declared at namespace scope. If either
+ is a member of an anonymous union, then this is an invalid
+ redeclaration. For example:
+
+ int i;
+ union { int i; };
+
+ is invalid. */
+ if ((VAR_P (newdecl) && DECL_ANON_UNION_VAR_P (newdecl))
+ || (VAR_P (olddecl) && DECL_ANON_UNION_VAR_P (olddecl)))
+ return G_("redeclaration of %q#D");
+ /* If at least one declaration is a reference, there is no
+ conflict. For example:
+
+ int i = 3;
+ extern int i;
+
+ is valid. */
+ if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
+ return NULL;
+ /* Reject two definitions. */
+ return G_("redefinition of %q#D");
+ }
+ else
+ {
+ /* Objects declared with block scope: */
+ /* Reject two definitions, and reject a definition
+ together with an external reference. */
+ if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl)))
+ return G_("redeclaration of %q#D");
+ return NULL;
+ }
+}
+
+/* Hash and equality functions for the named_label table. */
+
+static hashval_t
+named_label_entry_hash (const void *data)
+{
+ const struct named_label_entry *ent = (const struct named_label_entry *) data;
+ return DECL_UID (ent->label_decl);
+}
+
+static int
+named_label_entry_eq (const void *a, const void *b)
+{
+ const struct named_label_entry *ent_a = (const struct named_label_entry *) a;
+ const struct named_label_entry *ent_b = (const struct named_label_entry *) b;
+ return ent_a->label_decl == ent_b->label_decl;
+}
+
+/* Create a new label, named ID. */
+
+static tree
+make_label_decl (tree id, int local_p)
+{
+ struct named_label_entry *ent;
+ void **slot;
+ tree decl;
+
+ decl = build_decl (input_location, LABEL_DECL, id, void_type_node);
+
+ DECL_CONTEXT (decl) = current_function_decl;
+ DECL_MODE (decl) = VOIDmode;
+ C_DECLARED_LABEL_FLAG (decl) = local_p;
+
+ /* Say where one reference is to the label, for the sake of the
+ error if it is not defined. */
+ DECL_SOURCE_LOCATION (decl) = input_location;
+
+ /* Record the fact that this identifier is bound to this label. */
+ SET_IDENTIFIER_LABEL_VALUE (id, decl);
+
+ /* Create the label htab for the function on demand. */
+ if (!named_labels)
+ named_labels = htab_create_ggc (13, named_label_entry_hash,
+ named_label_entry_eq, NULL);
+
+ /* Record this label on the list of labels used in this function.
+ We do this before calling make_label_decl so that we get the
+ IDENTIFIER_LABEL_VALUE before the new label is declared. */
+ ent = ggc_alloc_cleared_named_label_entry ();
+ ent->label_decl = decl;
+
+ slot = htab_find_slot (named_labels, ent, INSERT);
+ gcc_assert (*slot == NULL);
+ *slot = ent;
+
+ return decl;
+}
+
+/* Look for a label named ID in the current function. If one cannot
+ be found, create one. (We keep track of used, but undefined,
+ labels, and complain about them at the end of a function.) */
+
+static tree
+lookup_label_1 (tree id)
+{
+ tree decl;
+
+ /* You can't use labels at global scope. */
+ if (current_function_decl == NULL_TREE)
+ {
+ error ("label %qE referenced outside of any function", id);
+ return NULL_TREE;
+ }
+
+ /* See if we've already got this label. */
+ decl = IDENTIFIER_LABEL_VALUE (id);
+ if (decl != NULL_TREE && DECL_CONTEXT (decl) == current_function_decl)
+ return decl;
+
+ decl = make_label_decl (id, /*local_p=*/0);
+ return decl;
+}
+
+/* Wrapper for lookup_label_1. */
+
+tree
+lookup_label (tree id)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = lookup_label_1 (id);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+/* Declare a local label named ID. */
+
+tree
+declare_local_label (tree id)
+{
+ tree decl;
+ cp_label_binding bind;
+
+ /* Add a new entry to the SHADOWED_LABELS list so that when we leave
+ this scope we can restore the old value of IDENTIFIER_TYPE_VALUE. */
+ bind.prev_value = IDENTIFIER_LABEL_VALUE (id);
+
+ decl = make_label_decl (id, /*local_p=*/1);
+ bind.label = decl;
+ vec_safe_push (current_binding_level->shadowed_labels, bind);
+
+ return decl;
+}
+
+/* Returns nonzero if it is ill-formed to jump past the declaration of
+ DECL. Returns 2 if it's also a real problem. */
+
+static int
+decl_jump_unsafe (tree decl)
+{
+ /* [stmt.dcl]/3: A program that jumps from a point where a local variable
+ with automatic storage duration is not in scope to a point where it is
+ in scope is ill-formed unless the variable has scalar type, class type
+ with a trivial default constructor and a trivial destructor, a
+ cv-qualified version of one of these types, or an array of one of the
+ preceding types and is declared without an initializer (8.5). */
+ tree type = TREE_TYPE (decl);
+
+ if (!VAR_P (decl) || TREE_STATIC (decl)
+ || type == error_mark_node)
+ return 0;
+
+ type = strip_array_types (type);
+
+ if (DECL_NONTRIVIALLY_INITIALIZED_P (decl))
+ return 2;
+
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+ return 1;
+
+ return 0;
+}
+
+/* A subroutine of check_previous_goto_1 to identify a branch to the user. */
+
+static void
+identify_goto (tree decl, const location_t *locus)
+{
+ if (decl)
+ permerror (input_location, "jump to label %qD", decl);
+ else
+ permerror (input_location, "jump to case label");
+ if (locus)
+ permerror (*locus, " from here");
+}
+
+/* Check that a single previously seen jump to a newly defined label
+ is OK. DECL is the LABEL_DECL or 0; LEVEL is the binding_level for
+ the jump context; NAMES are the names in scope in LEVEL at the jump
+ context; LOCUS is the source position of the jump or 0. Returns
+ true if all is well. */
+
+static bool
+check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
+ bool exited_omp, const location_t *locus)
+{
+ cp_binding_level *b;
+ bool identified = false, saw_eh = false, saw_omp = false;
+
+ if (exited_omp)
+ {
+ identify_goto (decl, locus);
+ error (" exits OpenMP structured block");
+ identified = saw_omp = true;
+ }
+
+ for (b = current_binding_level; b ; b = b->level_chain)
+ {
+ tree new_decls, old_decls = (b == level ? names : NULL_TREE);
+
+ for (new_decls = b->names; new_decls != old_decls;
+ new_decls = (DECL_P (new_decls) ? DECL_CHAIN (new_decls)
+ : TREE_CHAIN (new_decls)))
+ {
+ int problem = decl_jump_unsafe (new_decls);
+ if (! problem)
+ continue;
+
+ if (!identified)
+ {
+ identify_goto (decl, locus);
+ identified = true;
+ }
+ if (problem > 1)
+ error (" crosses initialization of %q+#D", new_decls);
+ else
+ permerror (input_location, " enters scope of %q+#D which has "
+ "non-trivial destructor", new_decls);
+ }
+
+ if (b == level)
+ break;
+ if ((b->kind == sk_try || b->kind == sk_catch) && !saw_eh)
+ {
+ if (!identified)
+ {
+ identify_goto (decl, locus);
+ identified = true;
+ }
+ if (b->kind == sk_try)
+ error (" enters try block");
+ else
+ error (" enters catch block");
+ saw_eh = true;
+ }
+ if (b->kind == sk_omp && !saw_omp)
+ {
+ if (!identified)
+ {
+ identify_goto (decl, locus);
+ identified = true;
+ }
+ error (" enters OpenMP structured block");
+ saw_omp = true;
+ }
+ }
+
+ return !identified;
+}
+
+static void
+check_previous_goto (tree decl, struct named_label_use_entry *use)
+{
+ check_previous_goto_1 (decl, use->binding_level,
+ use->names_in_scope, use->in_omp_scope,
+ &use->o_goto_locus);
+}
+
+static bool
+check_switch_goto (cp_binding_level* level)
+{
+ return check_previous_goto_1 (NULL_TREE, level, level->names, false, NULL);
+}
+
+/* Check that a new jump to a label DECL is OK. Called by
+ finish_goto_stmt. */
+
+void
+check_goto (tree decl)
+{
+ struct named_label_entry *ent, dummy;
+ bool saw_catch = false, identified = false;
+ tree bad;
+ unsigned ix;
+
+ /* We can't know where a computed goto is jumping.
+ So we assume that it's OK. */
+ if (TREE_CODE (decl) != LABEL_DECL)
+ return;
+
+ /* We didn't record any information about this label when we created it,
+ and there's not much point since it's trivial to analyze as a return. */
+ if (decl == cdtor_label)
+ return;
+
+ dummy.label_decl = decl;
+ ent = (struct named_label_entry *) htab_find (named_labels, &dummy);
+ gcc_assert (ent != NULL);
+
+ /* If the label hasn't been defined yet, defer checking. */
+ if (! DECL_INITIAL (decl))
+ {
+ struct named_label_use_entry *new_use;
+
+ /* Don't bother creating another use if the last goto had the
+ same data, and will therefore create the same set of errors. */
+ if (ent->uses
+ && ent->uses->names_in_scope == current_binding_level->names)
+ return;
+
+ new_use = ggc_alloc_named_label_use_entry ();
+ new_use->binding_level = current_binding_level;
+ new_use->names_in_scope = current_binding_level->names;
+ new_use->o_goto_locus = input_location;
+ new_use->in_omp_scope = false;
+
+ new_use->next = ent->uses;
+ ent->uses = new_use;
+ return;
+ }
+
+ if (ent->in_try_scope || ent->in_catch_scope
+ || ent->in_omp_scope || !vec_safe_is_empty (ent->bad_decls))
+ {
+ permerror (input_location, "jump to label %q+D", decl);
+ permerror (input_location, " from here");
+ identified = true;
+ }
+
+ FOR_EACH_VEC_SAFE_ELT (ent->bad_decls, ix, bad)
+ {
+ int u = decl_jump_unsafe (bad);
+
+ if (u > 1 && DECL_ARTIFICIAL (bad))
+ {
+ /* Can't skip init of __exception_info. */
+ error_at (DECL_SOURCE_LOCATION (bad), " enters catch block");
+ saw_catch = true;
+ }
+ else if (u > 1)
+ error (" skips initialization of %q+#D", bad);
+ else
+ permerror (input_location, " enters scope of %q+#D which has "
+ "non-trivial destructor", bad);
+ }
+
+ if (ent->in_try_scope)
+ error (" enters try block");
+ else if (ent->in_catch_scope && !saw_catch)
+ error (" enters catch block");
+
+ if (ent->in_omp_scope)
+ error (" enters OpenMP structured block");
+ else if (flag_openmp)
+ {
+ cp_binding_level *b;
+ for (b = current_binding_level; b ; b = b->level_chain)
+ {
+ if (b == ent->binding_level)
+ break;
+ if (b->kind == sk_omp)
+ {
+ if (!identified)
+ {
+ permerror (input_location, "jump to label %q+D", decl);
+ permerror (input_location, " from here");
+ identified = true;
+ }
+ error (" exits OpenMP structured block");
+ break;
+ }
+ }
+ }
+}
+
+/* Check that a return is ok wrt OpenMP structured blocks.
+ Called by finish_return_stmt. Returns true if all is well. */
+
+bool
+check_omp_return (void)
+{
+ cp_binding_level *b;
+ for (b = current_binding_level; b ; b = b->level_chain)
+ if (b->kind == sk_omp)
+ {
+ error ("invalid exit from OpenMP structured block");
+ return false;
+ }
+ else if (b->kind == sk_function_parms)
+ break;
+ return true;
+}
+
+/* Define a label, specifying the location in the source file.
+ Return the LABEL_DECL node for the label. */
+
+static tree
+define_label_1 (location_t location, tree name)
+{
+ struct named_label_entry *ent, dummy;
+ cp_binding_level *p;
+ tree decl;
+
+ decl = lookup_label (name);
+
+ dummy.label_decl = decl;
+ ent = (struct named_label_entry *) htab_find (named_labels, &dummy);
+ gcc_assert (ent != NULL);
+
+ /* After labels, make any new cleanups in the function go into their
+ own new (temporary) binding contour. */
+ for (p = current_binding_level;
+ p->kind != sk_function_parms;
+ p = p->level_chain)
+ p->more_cleanups_ok = 0;
+
+ if (name == get_identifier ("wchar_t"))
+ permerror (input_location, "label named wchar_t");
+
+ if (DECL_INITIAL (decl) != NULL_TREE)
+ {
+ error ("duplicate label %qD", decl);
+ return error_mark_node;
+ }
+ else
+ {
+ struct named_label_use_entry *use;
+
+ /* Mark label as having been defined. */
+ DECL_INITIAL (decl) = error_mark_node;
+ /* Say where in the source. */
+ DECL_SOURCE_LOCATION (decl) = location;
+
+ ent->binding_level = current_binding_level;
+ ent->names_in_scope = current_binding_level->names;
+
+ for (use = ent->uses; use ; use = use->next)
+ check_previous_goto (decl, use);
+ ent->uses = NULL;
+ }
+
+ return decl;
+}
+
+/* Wrapper for define_label_1. */
+
+tree
+define_label (location_t location, tree name)
+{
+ tree ret;
+ bool running = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = define_label_1 (location, name);
+ timevar_cond_stop (TV_NAME_LOOKUP, running);
+ return ret;
+}
+
+
+struct cp_switch
+{
+ cp_binding_level *level;
+ struct cp_switch *next;
+ /* The SWITCH_STMT being built. */
+ tree switch_stmt;
+ /* A splay-tree mapping the low element of a case range to the high
+ element, or NULL_TREE if there is no high element. Used to
+ determine whether or not a new case label duplicates an old case
+ label. We need a tree, rather than simply a hash table, because
+ of the GNU case range extension. */
+ splay_tree cases;
+};
+
+/* A stack of the currently active switch statements. The innermost
+ switch statement is on the top of the stack. There is no need to
+ mark the stack for garbage collection because it is only active
+ during the processing of the body of a function, and we never
+ collect at that point. */
+
+static struct cp_switch *switch_stack;
+
+/* Called right after a switch-statement condition is parsed.
+ SWITCH_STMT is the switch statement being parsed. */
+
+void
+push_switch (tree switch_stmt)
+{
+ struct cp_switch *p = XNEW (struct cp_switch);
+ p->level = current_binding_level;
+ p->next = switch_stack;
+ p->switch_stmt = switch_stmt;
+ p->cases = splay_tree_new (case_compare, NULL, NULL);
+ switch_stack = p;
+}
+
+void
+pop_switch (void)
+{
+ struct cp_switch *cs = switch_stack;
+ location_t switch_location;
+
+ /* Emit warnings as needed. */
+ switch_location = EXPR_LOC_OR_LOC (cs->switch_stmt, input_location);
+ if (!processing_template_decl)
+ c_do_switch_warnings (cs->cases, switch_location,
+ SWITCH_STMT_TYPE (cs->switch_stmt),
+ SWITCH_STMT_COND (cs->switch_stmt));
+
+ splay_tree_delete (cs->cases);
+ switch_stack = switch_stack->next;
+ free (cs);
+}
+
+/* Convert a case constant VALUE in a switch to the type TYPE of the switch
+ condition. Note that if TYPE and VALUE are already integral we don't
+ really do the conversion because the language-independent
+ warning/optimization code will work better that way. */
+
+static tree
+case_conversion (tree type, tree value)
+{
+ if (value == NULL_TREE)
+ return value;
+
+ if (cxx_dialect >= cxx11
+ && (SCOPED_ENUM_P (type)
+ || !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value))))
+ {
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+ type = type_promotes_to (type);
+ value = (perform_implicit_conversion_flags
+ (type, value, tf_warning_or_error,
+ LOOKUP_IMPLICIT | LOOKUP_NO_NON_INTEGRAL));
+ }
+ return cxx_constant_value (value);
+}
+
+/* Note that we've seen a definition of a case label, and complain if this
+ is a bad place for one. */
+
+tree
+finish_case_label (location_t loc, tree low_value, tree high_value)
+{
+ tree cond, r;
+ cp_binding_level *p;
+ tree type;
+
+ if (processing_template_decl)
+ {
+ tree label;
+
+ /* For templates, just add the case label; we'll do semantic
+ analysis at instantiation-time. */
+ label = build_decl (loc, LABEL_DECL, NULL_TREE, NULL_TREE);
+ return add_stmt (build_case_label (low_value, high_value, label));
+ }
+
+ /* Find the condition on which this switch statement depends. */
+ cond = SWITCH_STMT_COND (switch_stack->switch_stmt);
+ if (cond && TREE_CODE (cond) == TREE_LIST)
+ cond = TREE_VALUE (cond);
+
+ if (!check_switch_goto (switch_stack->level))
+ return error_mark_node;
+
+ type = SWITCH_STMT_TYPE (switch_stack->switch_stmt);
+
+ low_value = case_conversion (type, low_value);
+ high_value = case_conversion (type, high_value);
+
+ r = c_add_case_label (loc, switch_stack->cases, cond, type,
+ low_value, high_value);
+
+ /* After labels, make any new cleanups in the function go into their
+ own new (temporary) binding contour. */
+ for (p = current_binding_level;
+ p->kind != sk_function_parms;
+ p = p->level_chain)
+ p->more_cleanups_ok = 0;
+
+ return r;
+}
+
+/* Hash a TYPENAME_TYPE. K is really of type `tree'. */
+
+static hashval_t
+typename_hash (const void* k)
+{
+ hashval_t hash;
+ const_tree const t = (const_tree) k;
+
+ hash = (htab_hash_pointer (TYPE_CONTEXT (t))
+ ^ htab_hash_pointer (TYPE_IDENTIFIER (t)));
+
+ return hash;
+}
+
+typedef struct typename_info {
+ tree scope;
+ tree name;
+ tree template_id;
+ bool enum_p;
+ bool class_p;
+} typename_info;
+
+/* Compare two TYPENAME_TYPEs. K1 is really of type `tree', K2 is
+ really of type `typename_info*' */
+
+static int
+typename_compare (const void * k1, const void * k2)
+{
+ const_tree const t1 = (const_tree) k1;
+ const typename_info *const t2 = (const typename_info *) k2;
+
+ return (TYPE_IDENTIFIER (t1) == t2->name
+ && TYPE_CONTEXT (t1) == t2->scope
+ && TYPENAME_TYPE_FULLNAME (t1) == t2->template_id
+ && TYPENAME_IS_ENUM_P (t1) == t2->enum_p
+ && TYPENAME_IS_CLASS_P (t1) == t2->class_p);
+}
+
+/* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is
+ the type of `T', NAME is the IDENTIFIER_NODE for `t'.
+
+ Returns the new TYPENAME_TYPE. */
+
+static GTY ((param_is (union tree_node))) htab_t typename_htab;
+
+static tree
+build_typename_type (tree context, tree name, tree fullname,
+ enum tag_types tag_type)
+{
+ tree t;
+ tree d;
+ typename_info ti;
+ void **e;
+ hashval_t hash;
+
+ if (typename_htab == NULL)
+ typename_htab = htab_create_ggc (61, &typename_hash,
+ &typename_compare, NULL);
+
+ ti.scope = FROB_CONTEXT (context);
+ ti.name = name;
+ ti.template_id = fullname;
+ ti.enum_p = tag_type == enum_type;
+ ti.class_p = (tag_type == class_type
+ || tag_type == record_type
+ || tag_type == union_type);
+ hash = (htab_hash_pointer (ti.scope)
+ ^ htab_hash_pointer (ti.name));
+
+ /* See if we already have this type. */
+ e = htab_find_slot_with_hash (typename_htab, &ti, hash, INSERT);
+ if (*e)
+ t = (tree) *e;
+ else
+ {
+ /* Build the TYPENAME_TYPE. */
+ t = cxx_make_type (TYPENAME_TYPE);
+ TYPE_CONTEXT (t) = ti.scope;
+ TYPENAME_TYPE_FULLNAME (t) = ti.template_id;
+ TYPENAME_IS_ENUM_P (t) = ti.enum_p;
+ TYPENAME_IS_CLASS_P (t) = ti.class_p;
+
+ /* Build the corresponding TYPE_DECL. */
+ d = build_decl (input_location, TYPE_DECL, name, t);
+ TYPE_NAME (TREE_TYPE (d)) = d;
+ TYPE_STUB_DECL (TREE_TYPE (d)) = d;
+ DECL_CONTEXT (d) = FROB_CONTEXT (context);
+ DECL_ARTIFICIAL (d) = 1;
+
+ /* Store it in the hash table. */
+ *e = t;
+
+ /* TYPENAME_TYPEs must always be compared structurally, because
+ they may or may not resolve down to another type depending on
+ the currently open classes. */
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ }
+
+ return t;
+}
+
+/* Resolve `typename CONTEXT::NAME'. TAG_TYPE indicates the tag
+ provided to name the type. Returns an appropriate type, unless an
+ error occurs, in which case error_mark_node is returned. If we
+ locate a non-artificial TYPE_DECL and TF_KEEP_TYPE_DECL is set, we
+ return that, rather than the _TYPE it corresponds to, in other
+ cases we look through the type decl. If TF_ERROR is set, complain
+ about errors, otherwise be quiet. */
+
+tree
+make_typename_type (tree context, tree name, enum tag_types tag_type,
+ tsubst_flags_t complain)
+{
+ tree fullname;
+ tree t;
+ bool want_template;
+
+ if (name == error_mark_node
+ || context == NULL_TREE
+ || context == error_mark_node)
+ return error_mark_node;
+
+ if (TYPE_P (name))
+ {
+ if (!(TYPE_LANG_SPECIFIC (name)
+ && (CLASSTYPE_IS_TEMPLATE (name)
+ || CLASSTYPE_USE_TEMPLATE (name))))
+ name = TYPE_IDENTIFIER (name);
+ else
+ /* Create a TEMPLATE_ID_EXPR for the type. */
+ name = build_nt (TEMPLATE_ID_EXPR,
+ CLASSTYPE_TI_TEMPLATE (name),
+ CLASSTYPE_TI_ARGS (name));
+ }
+ else if (TREE_CODE (name) == TYPE_DECL)
+ name = DECL_NAME (name);
+
+ fullname = name;
+
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ name = TREE_OPERAND (name, 0);
+ if (TREE_CODE (name) == TEMPLATE_DECL)
+ name = TREE_OPERAND (fullname, 0) = DECL_NAME (name);
+ else if (TREE_CODE (name) == OVERLOAD)
+ {
+ if (complain & tf_error)
+ error ("%qD is not a type", name);
+ return error_mark_node;
+ }
+ }
+ if (TREE_CODE (name) == TEMPLATE_DECL)
+ {
+ if (complain & tf_error)
+ error ("%qD used without template parameters", name);
+ return error_mark_node;
+ }
+ gcc_assert (identifier_p (name));
+ gcc_assert (TYPE_P (context));
+
+ if (!MAYBE_CLASS_TYPE_P (context))
+ {
+ if (complain & tf_error)
+ error ("%q#T is not a class", context);
+ return error_mark_node;
+ }
+
+ /* When the CONTEXT is a dependent type, NAME could refer to a
+ dependent base class of CONTEXT. But look inside it anyway
+ if CONTEXT is a currently open scope, in case it refers to a
+ member of the current instantiation or a non-dependent base;
+ lookup will stop when we hit a dependent base. */
+ if (!dependent_scope_p (context))
+ /* We should only set WANT_TYPE when we're a nested typename type.
+ Then we can give better diagnostics if we find a non-type. */
+ t = lookup_field (context, name, 2, /*want_type=*/true);
+ else
+ t = NULL_TREE;
+
+ if ((!t || TREE_CODE (t) == TREE_LIST) && dependent_type_p (context))
+ return build_typename_type (context, name, fullname, tag_type);
+
+ want_template = TREE_CODE (fullname) == TEMPLATE_ID_EXPR;
+
+ if (!t)
+ {
+ if (complain & tf_error)
+ error (want_template ? G_("no class template named %q#T in %q#T")
+ : G_("no type named %q#T in %q#T"), name, context);
+ return error_mark_node;
+ }
+
+ /* Pull out the template from an injected-class-name (or multiple). */
+ if (want_template)
+ t = maybe_get_template_decl_from_type_decl (t);
+
+ if (TREE_CODE (t) == TREE_LIST)
+ {
+ if (complain & tf_error)
+ {
+ error ("lookup of %qT in %qT is ambiguous", name, context);
+ print_candidates (t);
+ }
+ return error_mark_node;
+ }
+
+ if (want_template && !DECL_TYPE_TEMPLATE_P (t))
+ {
+ if (complain & tf_error)
+ error ("%<typename %T::%D%> names %q#T, which is not a class template",
+ context, name, t);
+ return error_mark_node;
+ }
+ if (!want_template && TREE_CODE (t) != TYPE_DECL)
+ {
+ if (complain & tf_error)
+ error ("%<typename %T::%D%> names %q#T, which is not a type",
+ context, name, t);
+ return error_mark_node;
+ }
+
+ if (!perform_or_defer_access_check (TYPE_BINFO (context), t, t, complain))
+ return error_mark_node;
+
+ /* If we are currently parsing a template and if T is a typedef accessed
+ through CONTEXT then we need to remember and check access of T at
+ template instantiation time. */
+ add_typedef_to_current_template_for_access_check (t, context, input_location);
+
+ if (want_template)
+ return lookup_template_class (t, TREE_OPERAND (fullname, 1),
+ NULL_TREE, context,
+ /*entering_scope=*/0,
+ tf_warning_or_error | tf_user);
+
+ if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
+ t = TREE_TYPE (t);
+
+ maybe_record_typedef_use (t);
+
+ return t;
+}
+
+/* Resolve `CONTEXT::template NAME'. Returns a TEMPLATE_DECL if the name
+ can be resolved or an UNBOUND_CLASS_TEMPLATE, unless an error occurs,
+ in which case error_mark_node is returned.
+
+ If PARM_LIST is non-NULL, also make sure that the template parameter
+ list of TEMPLATE_DECL matches.
+
+ If COMPLAIN zero, don't complain about any errors that occur. */
+
+tree
+make_unbound_class_template (tree context, tree name, tree parm_list,
+ tsubst_flags_t complain)
+{
+ tree t;
+ tree d;
+
+ if (TYPE_P (name))
+ name = TYPE_IDENTIFIER (name);
+ else if (DECL_P (name))
+ name = DECL_NAME (name);
+ gcc_assert (identifier_p (name));
+
+ if (!dependent_type_p (context)
+ || currently_open_class (context))
+ {
+ tree tmpl = NULL_TREE;
+
+ if (MAYBE_CLASS_TYPE_P (context))
+ tmpl = lookup_field (context, name, 0, false);
+
+ if (tmpl && TREE_CODE (tmpl) == TYPE_DECL)
+ tmpl = maybe_get_template_decl_from_type_decl (tmpl);
+
+ if (!tmpl || !DECL_TYPE_TEMPLATE_P (tmpl))
+ {
+ if (complain & tf_error)
+ error ("no class template named %q#T in %q#T", name, context);
+ return error_mark_node;
+ }
+
+ if (parm_list
+ && !comp_template_parms (DECL_TEMPLATE_PARMS (tmpl), parm_list))
+ {
+ if (complain & tf_error)
+ {
+ error ("template parameters do not match template");
+ error ("%q+D declared here", tmpl);
+ }
+ return error_mark_node;
+ }
+
+ if (!perform_or_defer_access_check (TYPE_BINFO (context), tmpl, tmpl,
+ complain))
+ return error_mark_node;
+
+ return tmpl;
+ }
+
+ /* Build the UNBOUND_CLASS_TEMPLATE. */
+ t = cxx_make_type (UNBOUND_CLASS_TEMPLATE);
+ TYPE_CONTEXT (t) = FROB_CONTEXT (context);
+ TREE_TYPE (t) = NULL_TREE;
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+
+ /* Build the corresponding TEMPLATE_DECL. */
+ d = build_decl (input_location, TEMPLATE_DECL, name, t);
+ TYPE_NAME (TREE_TYPE (d)) = d;
+ TYPE_STUB_DECL (TREE_TYPE (d)) = d;
+ DECL_CONTEXT (d) = FROB_CONTEXT (context);
+ DECL_ARTIFICIAL (d) = 1;
+ DECL_TEMPLATE_PARMS (d) = parm_list;
+
+ return t;
+}
+
+
+
+/* Push the declarations of builtin types into the namespace.
+ RID_INDEX is the index of the builtin type in the array
+ RID_POINTERS. NAME is the name used when looking up the builtin
+ type. TYPE is the _TYPE node for the builtin type. */
+
+void
+record_builtin_type (enum rid rid_index,
+ const char* name,
+ tree type)
+{
+ tree rname = NULL_TREE, tname = NULL_TREE;
+ tree tdecl = NULL_TREE;
+
+ if ((int) rid_index < (int) RID_MAX)
+ rname = ridpointers[(int) rid_index];
+ if (name)
+ tname = get_identifier (name);
+
+ /* The calls to SET_IDENTIFIER_GLOBAL_VALUE below should be
+ eliminated. Built-in types should not be looked up name; their
+ names are keywords that the parser can recognize. However, there
+ is code in c-common.c that uses identifier_global_value to look
+ up built-in types by name. */
+ if (tname)
+ {
+ tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, tname, type);
+ DECL_ARTIFICIAL (tdecl) = 1;
+ SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl);
+ }
+ if (rname)
+ {
+ if (!tdecl)
+ {
+ tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, rname, type);
+ DECL_ARTIFICIAL (tdecl) = 1;
+ }
+ SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl);
+ }
+
+ if (!TYPE_NAME (type))
+ TYPE_NAME (type) = tdecl;
+
+ if (tdecl)
+ debug_hooks->type_decl (tdecl, 0);
+}
+
+/* Record one of the standard Java types.
+ * Declare it as having the given NAME.
+ * If SIZE > 0, it is the size of one of the integral types;
+ * otherwise it is the negative of the size of one of the other types. */
+
+static tree
+record_builtin_java_type (const char* name, int size)
+{
+ tree type, decl;
+ if (size > 0)
+ {
+ type = build_nonstandard_integer_type (size, 0);
+ type = build_distinct_type_copy (type);
+ }
+ else if (size > -32)
+ {
+ tree stype;
+ /* "__java_char" or ""__java_boolean". */
+ type = build_nonstandard_integer_type (-size, 1);
+ type = build_distinct_type_copy (type);
+ /* Get the signed type cached and attached to the unsigned type,
+ so it doesn't get garbage-collected at "random" times,
+ causing potential codegen differences out of different UIDs
+ and different alias set numbers. */
+ stype = build_nonstandard_integer_type (-size, 0);
+ stype = build_distinct_type_copy (stype);
+ TREE_CHAIN (type) = stype;
+ /*if (size == -1) TREE_SET_CODE (type, BOOLEAN_TYPE);*/
+ }
+ else
+ { /* "__java_float" or ""__java_double". */
+ type = make_node (REAL_TYPE);
+ TYPE_PRECISION (type) = - size;
+ layout_type (type);
+ }
+ record_builtin_type (RID_MAX, name, type);
+ decl = TYPE_NAME (type);
+
+ /* Suppress generate debug symbol entries for these types,
+ since for normal C++ they are just clutter.
+ However, push_lang_context undoes this if extern "Java" is seen. */
+ DECL_IGNORED_P (decl) = 1;
+
+ TYPE_FOR_JAVA (type) = 1;
+ return type;
+}
+
+/* Push a type into the namespace so that the back ends ignore it. */
+
+static void
+record_unknown_type (tree type, const char* name)
+{
+ tree decl = pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, get_identifier (name), type));
+ /* Make sure the "unknown type" typedecl gets ignored for debug info. */
+ DECL_IGNORED_P (decl) = 1;
+ TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
+ TYPE_SIZE (type) = TYPE_SIZE (void_type_node);
+ TYPE_ALIGN (type) = 1;
+ TYPE_USER_ALIGN (type) = 0;
+ SET_TYPE_MODE (type, TYPE_MODE (void_type_node));
+}
+
+/* A string for which we should create an IDENTIFIER_NODE at
+ startup. */
+
+typedef struct predefined_identifier
+{
+ /* The name of the identifier. */
+ const char *const name;
+ /* The place where the IDENTIFIER_NODE should be stored. */
+ tree *const node;
+ /* Nonzero if this is the name of a constructor or destructor. */
+ const int ctor_or_dtor_p;
+} predefined_identifier;
+
+/* Create all the predefined identifiers. */
+
+static void
+initialize_predefined_identifiers (void)
+{
+ const predefined_identifier *pid;
+
+ /* A table of identifiers to create at startup. */
+ static const predefined_identifier predefined_identifiers[] = {
+ { "C++", &lang_name_cplusplus, 0 },
+ { "C", &lang_name_c, 0 },
+ { "Java", &lang_name_java, 0 },
+ /* Some of these names have a trailing space so that it is
+ impossible for them to conflict with names written by users. */
+ { "__ct ", &ctor_identifier, 1 },
+ { "__base_ctor ", &base_ctor_identifier, 1 },
+ { "__comp_ctor ", &complete_ctor_identifier, 1 },
+ { "__dt ", &dtor_identifier, 1 },
+ { "__comp_dtor ", &complete_dtor_identifier, 1 },
+ { "__base_dtor ", &base_dtor_identifier, 1 },
+ { "__deleting_dtor ", &deleting_dtor_identifier, 1 },
+ { IN_CHARGE_NAME, &in_charge_identifier, 0 },
+ { "nelts", &nelts_identifier, 0 },
+ { THIS_NAME, &this_identifier, 0 },
+ { VTABLE_DELTA_NAME, &delta_identifier, 0 },
+ { VTABLE_PFN_NAME, &pfn_identifier, 0 },
+ { "_vptr", &vptr_identifier, 0 },
+ { "__vtt_parm", &vtt_parm_identifier, 0 },
+ { "::", &global_scope_name, 0 },
+ { "std", &std_identifier, 0 },
+ { NULL, NULL, 0 }
+ };
+
+ for (pid = predefined_identifiers; pid->name; ++pid)
+ {
+ *pid->node = get_identifier (pid->name);
+ if (pid->ctor_or_dtor_p)
+ IDENTIFIER_CTOR_OR_DTOR_P (*pid->node) = 1;
+ }
+}
+
+/* Create the predefined scalar types of C,
+ and some nodes representing standard constants (0, 1, (void *)0).
+ Initialize the global binding level.
+ Make definitions for built-in primitive functions. */
+
+void
+cxx_init_decl_processing (void)
+{
+ tree void_ftype;
+ tree void_ftype_ptr;
+
+ /* Create all the identifiers we need. */
+ initialize_predefined_identifiers ();
+
+ /* Create the global variables. */
+ push_to_top_level ();
+
+ current_function_decl = NULL_TREE;
+ current_binding_level = NULL;
+ /* Enter the global namespace. */
+ gcc_assert (global_namespace == NULL_TREE);
+ global_namespace = build_lang_decl (NAMESPACE_DECL, global_scope_name,
+ void_type_node);
+ DECL_CONTEXT (global_namespace) = build_translation_unit_decl (NULL_TREE);
+ TREE_PUBLIC (global_namespace) = 1;
+ begin_scope (sk_namespace, global_namespace);
+
+ if (flag_visibility_ms_compat)
+ default_visibility = VISIBILITY_HIDDEN;
+
+ /* Initially, C. */
+ current_lang_name = lang_name_c;
+
+ /* Create the `std' namespace. */
+ push_namespace (std_identifier);
+ std_node = current_namespace;
+ pop_namespace ();
+
+ c_common_nodes_and_builtins ();
+
+ java_byte_type_node = record_builtin_java_type ("__java_byte", 8);
+ java_short_type_node = record_builtin_java_type ("__java_short", 16);
+ java_int_type_node = record_builtin_java_type ("__java_int", 32);
+ java_long_type_node = record_builtin_java_type ("__java_long", 64);
+ java_float_type_node = record_builtin_java_type ("__java_float", -32);
+ java_double_type_node = record_builtin_java_type ("__java_double", -64);
+ java_char_type_node = record_builtin_java_type ("__java_char", -16);
+ java_boolean_type_node = record_builtin_java_type ("__java_boolean", -1);
+
+ integer_two_node = build_int_cst (NULL_TREE, 2);
+
+ record_builtin_type (RID_BOOL, "bool", boolean_type_node);
+ truthvalue_type_node = boolean_type_node;
+ truthvalue_false_node = boolean_false_node;
+ truthvalue_true_node = boolean_true_node;
+
+ empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
+ noexcept_true_spec = build_tree_list (boolean_true_node, NULL_TREE);
+ noexcept_false_spec = build_tree_list (boolean_false_node, NULL_TREE);
+
+#if 0
+ record_builtin_type (RID_MAX, NULL, string_type_node);
+#endif
+
+ delta_type_node = ptrdiff_type_node;
+ vtable_index_type = ptrdiff_type_node;
+
+ vtt_parm_type = build_pointer_type (const_ptr_type_node);
+ void_ftype = build_function_type_list (void_type_node, NULL_TREE);
+ void_ftype_ptr = build_function_type_list (void_type_node,
+ ptr_type_node, NULL_TREE);
+ void_ftype_ptr
+ = build_exception_variant (void_ftype_ptr, empty_except_spec);
+
+ /* C++ extensions */
+
+ unknown_type_node = make_node (LANG_TYPE);
+ record_unknown_type (unknown_type_node, "unknown type");
+
+ /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node. */
+ TREE_TYPE (unknown_type_node) = unknown_type_node;
+
+ /* Looking up TYPE_POINTER_TO and TYPE_REFERENCE_TO yield the same
+ result. */
+ TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
+ TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
+
+ init_list_type_node = make_node (LANG_TYPE);
+ record_unknown_type (init_list_type_node, "init list");
+
+ {
+ /* Make sure we get a unique function type, so we can give
+ its pointer type a name. (This wins for gdb.) */
+ tree vfunc_type = make_node (FUNCTION_TYPE);
+ TREE_TYPE (vfunc_type) = integer_type_node;
+ TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
+ layout_type (vfunc_type);
+
+ vtable_entry_type = build_pointer_type (vfunc_type);
+ }
+ record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
+
+ vtbl_type_node
+ = build_cplus_array_type (vtable_entry_type, NULL_TREE);
+ layout_type (vtbl_type_node);
+ vtbl_type_node = cp_build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST);
+ record_builtin_type (RID_MAX, NULL, vtbl_type_node);
+ vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
+ layout_type (vtbl_ptr_type_node);
+ record_builtin_type (RID_MAX, NULL, vtbl_ptr_type_node);
+
+ push_namespace (get_identifier ("__cxxabiv1"));
+ abi_node = current_namespace;
+ pop_namespace ();
+
+ global_type_node = make_node (LANG_TYPE);
+ record_unknown_type (global_type_node, "global type");
+
+ /* Now, C++. */
+ current_lang_name = lang_name_cplusplus;
+
+ {
+ tree newattrs, extvisattr;
+ tree newtype, deltype;
+ tree ptr_ftype_sizetype;
+ tree new_eh_spec;
+
+ ptr_ftype_sizetype
+ = build_function_type_list (ptr_type_node, size_type_node, NULL_TREE);
+ if (cxx_dialect == cxx98)
+ {
+ tree bad_alloc_id;
+ tree bad_alloc_type_node;
+ tree bad_alloc_decl;
+
+ push_namespace (std_identifier);
+ bad_alloc_id = get_identifier ("bad_alloc");
+ bad_alloc_type_node = make_class_type (RECORD_TYPE);
+ TYPE_CONTEXT (bad_alloc_type_node) = current_namespace;
+ bad_alloc_decl
+ = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node);
+ DECL_CONTEXT (bad_alloc_decl) = current_namespace;
+ pop_namespace ();
+
+ new_eh_spec
+ = add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1);
+ }
+ else
+ new_eh_spec = noexcept_false_spec;
+
+ /* Ensure attribs.c is initialized. */
+ init_attributes ();
+ extvisattr = build_tree_list (get_identifier ("externally_visible"),
+ NULL_TREE);
+ newattrs = tree_cons (get_identifier ("alloc_size"),
+ build_tree_list (NULL_TREE, integer_one_node),
+ extvisattr);
+ newtype = cp_build_type_attribute_variant (ptr_ftype_sizetype, newattrs);
+ newtype = build_exception_variant (newtype, new_eh_spec);
+ deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
+ deltype = build_exception_variant (deltype, empty_except_spec);
+ DECL_IS_OPERATOR_NEW (push_cp_library_fn (NEW_EXPR, newtype, 0)) = 1;
+ DECL_IS_OPERATOR_NEW (push_cp_library_fn (VEC_NEW_EXPR, newtype, 0)) = 1;
+ global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
+ push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
+
+ nullptr_type_node = make_node (NULLPTR_TYPE);
+ TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
+ TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
+ TYPE_UNSIGNED (nullptr_type_node) = 1;
+ TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode);
+ SET_TYPE_MODE (nullptr_type_node, ptr_mode);
+ record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node);
+ nullptr_node = build_int_cst (nullptr_type_node, 0);
+ }
+
+ abort_fndecl
+ = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype,
+ ECF_NORETURN | ECF_NOTHROW);
+
+ /* Perform other language dependent initializations. */
+ init_class_processing ();
+ init_rtti_processing ();
+ init_template_processing ();
+
+ if (flag_exceptions)
+ init_exception_processing ();
+
+ if (! supports_one_only ())
+ flag_weak = 0;
+
+ make_fname_decl = cp_make_fname_decl;
+ start_fname_decls ();
+
+ /* Show we use EH for cleanups. */
+ if (flag_exceptions)
+ using_eh_for_cleanups ();
+}
+
+/* Generate an initializer for a function naming variable from
+ NAME. NAME may be NULL, to indicate a dependent name. TYPE_P is
+ filled in with the type of the init. */
+
+tree
+cp_fname_init (const char* name, tree *type_p)
+{
+ tree domain = NULL_TREE;
+ tree type;
+ tree init = NULL_TREE;
+ size_t length = 0;
+
+ if (name)
+ {
+ length = strlen (name);
+ domain = build_index_type (size_int (length));
+ init = build_string (length + 1, name);
+ }
+
+ type = cp_build_qualified_type (char_type_node, TYPE_QUAL_CONST);
+ type = build_cplus_array_type (type, domain);
+
+ *type_p = type;
+
+ if (init)
+ TREE_TYPE (init) = type;
+ else
+ init = error_mark_node;
+
+ return init;
+}
+
+/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give
+ the decl, LOC is the location to give the decl, NAME is the
+ initialization string and TYPE_DEP indicates whether NAME depended
+ on the type of the function. We make use of that to detect
+ __PRETTY_FUNCTION__ inside a template fn. This is being done lazily
+ at the point of first use, so we mustn't push the decl now. */
+
+static tree
+cp_make_fname_decl (location_t loc, tree id, int type_dep)
+{
+ const char *const name = (type_dep && processing_template_decl
+ ? NULL : fname_as_string (type_dep));
+ tree type;
+ tree init = cp_fname_init (name, &type);
+ tree decl = build_decl (loc, VAR_DECL, id, type);
+
+ if (name)
+ free (CONST_CAST (char *, name));
+
+ /* As we're using pushdecl_with_scope, we must set the context. */
+ DECL_CONTEXT (decl) = current_function_decl;
+
+ TREE_STATIC (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+
+ TREE_USED (decl) = 1;
+
+ if (current_function_decl)
+ {
+ cp_binding_level *b = current_binding_level;
+ if (b->kind == sk_function_parms)
+ return error_mark_node;
+ while (b->level_chain->kind != sk_function_parms)
+ b = b->level_chain;
+ pushdecl_with_scope (decl, b, /*is_friend=*/false);
+ cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
+ LOOKUP_ONLYCONVERTING);
+ }
+ else
+ {
+ DECL_THIS_STATIC (decl) = true;
+ pushdecl_top_level_and_finish (decl, init);
+ }
+
+ return decl;
+}
+
+static tree
+builtin_function_1 (tree decl, tree context, bool is_global)
+{
+ tree id = DECL_NAME (decl);
+ const char *name = IDENTIFIER_POINTER (id);
+
+ retrofit_lang_decl (decl);
+
+ DECL_ARTIFICIAL (decl) = 1;
+ SET_OVERLOADED_OPERATOR_CODE (decl, ERROR_MARK);
+ SET_DECL_LANGUAGE (decl, lang_c);
+ /* Runtime library routines are, by definition, available in an
+ external shared object. */
+ DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+ DECL_VISIBILITY_SPECIFIED (decl) = 1;
+
+ DECL_CONTEXT (decl) = context;
+
+ if (is_global)
+ pushdecl_top_level (decl);
+ else
+ pushdecl (decl);
+
+ /* A function in the user's namespace should have an explicit
+ declaration before it is used. Mark the built-in function as
+ anticipated but not actually declared. */
+ if (name[0] != '_' || name[1] != '_')
+ DECL_ANTICIPATED (decl) = 1;
+ else if (strncmp (name + 2, "builtin_", strlen ("builtin_")) != 0)
+ {
+ size_t len = strlen (name);
+
+ /* Treat __*_chk fortification functions as anticipated as well,
+ unless they are __builtin_*. */
+ if (len > strlen ("___chk")
+ && memcmp (name + len - strlen ("_chk"),
+ "_chk", strlen ("_chk") + 1) == 0)
+ DECL_ANTICIPATED (decl) = 1;
+ }
+
+ return decl;
+}
+
+tree
+cxx_builtin_function (tree decl)
+{
+ tree id = DECL_NAME (decl);
+ const char *name = IDENTIFIER_POINTER (id);
+ /* All builtins that don't begin with an '_' should additionally
+ go in the 'std' namespace. */
+ if (name[0] != '_')
+ {
+ tree decl2 = copy_node(decl);
+ push_namespace (std_identifier);
+ builtin_function_1 (decl2, std_node, false);
+ pop_namespace ();
+ }
+
+ return builtin_function_1 (decl, NULL_TREE, false);
+}
+
+/* Like cxx_builtin_function, but guarantee the function is added to the global
+ scope. This is to allow function specific options to add new machine
+ dependent builtins when the target ISA changes via attribute((target(...)))
+ which saves space on program startup if the program does not use non-generic
+ ISAs. */
+
+tree
+cxx_builtin_function_ext_scope (tree decl)
+{
+
+ tree id = DECL_NAME (decl);
+ const char *name = IDENTIFIER_POINTER (id);
+ /* All builtins that don't begin with an '_' should additionally
+ go in the 'std' namespace. */
+ if (name[0] != '_')
+ {
+ tree decl2 = copy_node(decl);
+ push_namespace (std_identifier);
+ builtin_function_1 (decl2, std_node, true);
+ pop_namespace ();
+ }
+
+ return builtin_function_1 (decl, NULL_TREE, true);
+}
+
+/* Generate a FUNCTION_DECL with the typical flags for a runtime library
+ function. Not called directly. */
+
+static tree
+build_library_fn (tree name, enum tree_code operator_code, tree type,
+ int ecf_flags)
+{
+ tree fn = build_lang_decl (FUNCTION_DECL, name, type);
+ DECL_EXTERNAL (fn) = 1;
+ TREE_PUBLIC (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ SET_OVERLOADED_OPERATOR_CODE (fn, operator_code);
+ SET_DECL_LANGUAGE (fn, lang_c);
+ /* Runtime library routines are, by definition, available in an
+ external shared object. */
+ DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
+ DECL_VISIBILITY_SPECIFIED (fn) = 1;
+ set_call_expr_flags (fn, ecf_flags);
+ return fn;
+}
+
+/* Returns the _DECL for a library function with C++ linkage. */
+
+static tree
+build_cp_library_fn (tree name, enum tree_code operator_code, tree type,
+ int ecf_flags)
+{
+ tree fn = build_library_fn (name, operator_code, type, ecf_flags);
+ DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
+ SET_DECL_LANGUAGE (fn, lang_cplusplus);
+ return fn;
+}
+
+/* Like build_library_fn, but takes a C string instead of an
+ IDENTIFIER_NODE. */
+
+tree
+build_library_fn_ptr (const char* name, tree type, int ecf_flags)
+{
+ return build_library_fn (get_identifier (name), ERROR_MARK, type, ecf_flags);
+}
+
+/* Like build_cp_library_fn, but takes a C string instead of an
+ IDENTIFIER_NODE. */
+
+tree
+build_cp_library_fn_ptr (const char* name, tree type, int ecf_flags)
+{
+ return build_cp_library_fn (get_identifier (name), ERROR_MARK, type,
+ ecf_flags);
+}
+
+/* Like build_library_fn, but also pushes the function so that we will
+ be able to find it via IDENTIFIER_GLOBAL_VALUE. Also, the function
+ may throw exceptions listed in RAISES. */
+
+tree
+push_library_fn (tree name, tree type, tree raises, int ecf_flags)
+{
+ tree fn;
+
+ if (raises)
+ type = build_exception_variant (type, raises);
+
+ fn = build_library_fn (name, ERROR_MARK, type, ecf_flags);
+ pushdecl_top_level (fn);
+ return fn;
+}
+
+/* Like build_cp_library_fn, but also pushes the function so that it
+ will be found by normal lookup. */
+
+static tree
+push_cp_library_fn (enum tree_code operator_code, tree type,
+ int ecf_flags)
+{
+ tree fn = build_cp_library_fn (ansi_opname (operator_code),
+ operator_code,
+ type, ecf_flags);
+ pushdecl (fn);
+ if (flag_tm)
+ apply_tm_attr (fn, get_identifier ("transaction_safe"));
+ return fn;
+}
+
+/* Like push_library_fn, but takes a TREE_LIST of parm types rather than
+ a FUNCTION_TYPE. */
+
+tree
+push_void_library_fn (tree name, tree parmtypes, int ecf_flags)
+{
+ tree type = build_function_type (void_type_node, parmtypes);
+ return push_library_fn (name, type, NULL_TREE, ecf_flags);
+}
+
+/* Like push_library_fn, but also note that this function throws
+ and does not return. Used for __throw_foo and the like. */
+
+tree
+push_throw_library_fn (tree name, tree type)
+{
+ tree fn = push_library_fn (name, type, NULL_TREE, ECF_NORETURN);
+ return fn;
+}
+
+/* When we call finish_struct for an anonymous union, we create
+ default copy constructors and such. But, an anonymous union
+ shouldn't have such things; this function undoes the damage to the
+ anonymous union type T.
+
+ (The reason that we create the synthesized methods is that we don't
+ distinguish `union { int i; }' from `typedef union { int i; } U'.
+ The first is an anonymous union; the second is just an ordinary
+ union type.) */
+
+void
+fixup_anonymous_aggr (tree t)
+{
+ tree *q;
+
+ /* Wipe out memory of synthesized methods. */
+ TYPE_HAS_USER_CONSTRUCTOR (t) = 0;
+ TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0;
+ TYPE_HAS_COPY_CTOR (t) = 0;
+ TYPE_HAS_CONST_COPY_CTOR (t) = 0;
+ TYPE_HAS_COPY_ASSIGN (t) = 0;
+ TYPE_HAS_CONST_COPY_ASSIGN (t) = 0;
+
+ /* Splice the implicitly generated functions out of the TYPE_METHODS
+ list. */
+ q = &TYPE_METHODS (t);
+ while (*q)
+ {
+ if (DECL_ARTIFICIAL (*q))
+ *q = TREE_CHAIN (*q);
+ else
+ q = &DECL_CHAIN (*q);
+ }
+
+ /* ISO C++ 9.5.3. Anonymous unions may not have function members. */
+ if (TYPE_METHODS (t))
+ {
+ tree decl = TYPE_MAIN_DECL (t);
+
+ if (TREE_CODE (t) != UNION_TYPE)
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "an anonymous struct cannot have function members");
+ else
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "an anonymous union cannot have function members");
+ }
+
+ /* Anonymous aggregates cannot have fields with ctors, dtors or complex
+ assignment operators (because they cannot have these methods themselves).
+ For anonymous unions this is already checked because they are not allowed
+ in any union, otherwise we have to check it. */
+ if (TREE_CODE (t) != UNION_TYPE)
+ {
+ tree field, type;
+
+ for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL)
+ {
+ type = TREE_TYPE (field);
+ if (CLASS_TYPE_P (type))
+ {
+ if (TYPE_NEEDS_CONSTRUCTING (type))
+ error ("member %q+#D with constructor not allowed "
+ "in anonymous aggregate", field);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ error ("member %q+#D with destructor not allowed "
+ "in anonymous aggregate", field);
+ if (TYPE_HAS_COMPLEX_COPY_ASSIGN (type))
+ error ("member %q+#D with copy assignment operator "
+ "not allowed in anonymous aggregate", field);
+ }
+ }
+ }
+}
+
+/* Warn for an attribute located at LOCATION that appertains to the
+ class type CLASS_TYPE that has not been properly placed after its
+ class-key, in it class-specifier. */
+
+void
+warn_misplaced_attr_for_class_type (source_location location,
+ tree class_type)
+{
+ gcc_assert (OVERLOAD_TYPE_P (class_type));
+
+ warning_at (location, OPT_Wattributes,
+ "attribute ignored in declaration "
+ "of %q#T", class_type);
+ inform (location,
+ "attribute for %q#T must follow the %qs keyword",
+ class_type, class_key_or_enum_as_string (class_type));
+}
+
+/* Make sure that a declaration with no declarator is well-formed, i.e.
+ just declares a tagged type or anonymous union.
+
+ Returns the type declared; or NULL_TREE if none. */
+
+tree
+check_tag_decl (cp_decl_specifier_seq *declspecs,
+ bool explicit_type_instantiation_p)
+{
+ int saw_friend = decl_spec_seq_has_spec_p (declspecs, ds_friend);
+ int saw_typedef = decl_spec_seq_has_spec_p (declspecs, ds_typedef);
+ /* If a class, struct, or enum type is declared by the DECLSPECS
+ (i.e, if a class-specifier, enum-specifier, or non-typename
+ elaborated-type-specifier appears in the DECLSPECS),
+ DECLARED_TYPE is set to the corresponding type. */
+ tree declared_type = NULL_TREE;
+ bool error_p = false;
+
+ if (declspecs->multiple_types_p)
+ error ("multiple types in one declaration");
+ else if (declspecs->redefined_builtin_type)
+ {
+ if (!in_system_header_at (input_location))
+ permerror (declspecs->locations[ds_redefined_builtin_type_spec],
+ "redeclaration of C++ built-in type %qT",
+ declspecs->redefined_builtin_type);
+ return NULL_TREE;
+ }
+
+ if (declspecs->type
+ && TYPE_P (declspecs->type)
+ && ((TREE_CODE (declspecs->type) != TYPENAME_TYPE
+ && MAYBE_CLASS_TYPE_P (declspecs->type))
+ || TREE_CODE (declspecs->type) == ENUMERAL_TYPE))
+ declared_type = declspecs->type;
+ else if (declspecs->type == error_mark_node)
+ error_p = true;
+ if (declared_type == NULL_TREE && ! saw_friend && !error_p)
+ permerror (input_location, "declaration does not declare anything");
+ else if (declared_type != NULL_TREE && type_uses_auto (declared_type))
+ {
+ error ("%<auto%> can only be specified for variables "
+ "or function declarations");
+ return error_mark_node;
+ }
+ /* Check for an anonymous union. */
+ else if (declared_type && RECORD_OR_UNION_CODE_P (TREE_CODE (declared_type))
+ && TYPE_ANONYMOUS_P (declared_type))
+ {
+ /* 7/3 In a simple-declaration, the optional init-declarator-list
+ can be omitted only when declaring a class (clause 9) or
+ enumeration (7.2), that is, when the decl-specifier-seq contains
+ either a class-specifier, an elaborated-type-specifier with
+ a class-key (9.1), or an enum-specifier. In these cases and
+ whenever a class-specifier or enum-specifier is present in the
+ decl-specifier-seq, the identifiers in these specifiers are among
+ the names being declared by the declaration (as class-name,
+ enum-names, or enumerators, depending on the syntax). In such
+ cases, and except for the declaration of an unnamed bit-field (9.6),
+ the decl-specifier-seq shall introduce one or more names into the
+ program, or shall redeclare a name introduced by a previous
+ declaration. [Example:
+ enum { }; // ill-formed
+ typedef class { }; // ill-formed
+ --end example] */
+ if (saw_typedef)
+ {
+ error ("missing type-name in typedef-declaration");
+ return NULL_TREE;
+ }
+ /* Anonymous unions are objects, so they can have specifiers. */;
+ SET_ANON_AGGR_TYPE_P (declared_type);
+
+ if (TREE_CODE (declared_type) != UNION_TYPE
+ && !in_system_header_at (input_location))
+ pedwarn (input_location, OPT_Wpedantic, "ISO C++ prohibits anonymous structs");
+ }
+
+ else
+ {
+ if (decl_spec_seq_has_spec_p (declspecs, ds_inline)
+ || decl_spec_seq_has_spec_p (declspecs, ds_virtual))
+ error ("%qs can only be specified for functions",
+ decl_spec_seq_has_spec_p (declspecs, ds_inline)
+ ? "inline" : "virtual");
+ else if (saw_friend
+ && (!current_class_type
+ || current_scope () != current_class_type))
+ error ("%<friend%> can only be specified inside a class");
+ else if (decl_spec_seq_has_spec_p (declspecs, ds_explicit))
+ error ("%<explicit%> can only be specified for constructors");
+ else if (declspecs->storage_class)
+ error ("a storage class can only be specified for objects "
+ "and functions");
+ else if (decl_spec_seq_has_spec_p (declspecs, ds_const)
+ || decl_spec_seq_has_spec_p (declspecs, ds_volatile)
+ || decl_spec_seq_has_spec_p (declspecs, ds_restrict)
+ || decl_spec_seq_has_spec_p (declspecs, ds_thread))
+ error ("qualifiers can only be specified for objects "
+ "and functions");
+ else if (saw_typedef)
+ warning (0, "%<typedef%> was ignored in this declaration");
+ else if (decl_spec_seq_has_spec_p (declspecs, ds_constexpr))
+ error ("%<constexpr%> cannot be used for type declarations");
+ }
+
+ if (declspecs->attributes && warn_attributes && declared_type)
+ {
+ location_t loc;
+ if (!CLASS_TYPE_P (declared_type)
+ || !CLASSTYPE_TEMPLATE_INSTANTIATION (declared_type))
+ /* For a non-template class, use the name location. */
+ loc = location_of (declared_type);
+ else
+ /* For a template class (an explicit instantiation), use the
+ current location. */
+ loc = input_location;
+
+ if (explicit_type_instantiation_p)
+ /* [dcl.attr.grammar]/4:
+
+ No attribute-specifier-seq shall appertain to an explicit
+ instantiation. */
+ {
+ warning_at (loc, OPT_Wattributes,
+ "attribute ignored in explicit instantiation %q#T",
+ declared_type);
+ inform (loc,
+ "no attribute can be applied to "
+ "an explicit instantiation");
+ }
+ else
+ warn_misplaced_attr_for_class_type (loc, declared_type);
+ }
+
+ return declared_type;
+}
+
+/* Called when a declaration is seen that contains no names to declare.
+ If its type is a reference to a structure, union or enum inherited
+ from a containing scope, shadow that tag name for the current scope
+ with a forward reference.
+ If its type defines a new named structure or union
+ or defines an enum, it is valid but we need not do anything here.
+ Otherwise, it is an error.
+
+ C++: may have to grok the declspecs to learn about static,
+ complain for anonymous unions.
+
+ Returns the TYPE declared -- or NULL_TREE if none. */
+
+tree
+shadow_tag (cp_decl_specifier_seq *declspecs)
+{
+ tree t = check_tag_decl (declspecs,
+ /*explicit_type_instantiation_p=*/false);
+
+ if (!t)
+ return NULL_TREE;
+
+ if (maybe_process_partial_specialization (t) == error_mark_node)
+ return NULL_TREE;
+
+ /* This is where the variables in an anonymous union are
+ declared. An anonymous union declaration looks like:
+ union { ... } ;
+ because there is no declarator after the union, the parser
+ sends that declaration here. */
+ if (ANON_AGGR_TYPE_P (t))
+ {
+ fixup_anonymous_aggr (t);
+
+ if (TYPE_FIELDS (t))
+ {
+ tree decl = grokdeclarator (/*declarator=*/NULL,
+ declspecs, NORMAL, 0, NULL);
+ finish_anon_union (decl);
+ }
+ }
+
+ return t;
+}
+
+/* Decode a "typename", such as "int **", returning a ..._TYPE node. */
+
+tree
+groktypename (cp_decl_specifier_seq *type_specifiers,
+ const cp_declarator *declarator,
+ bool is_template_arg)
+{
+ tree attrs;
+ tree type;
+ enum decl_context context
+ = is_template_arg ? TEMPLATE_TYPE_ARG : TYPENAME;
+ attrs = type_specifiers->attributes;
+ type_specifiers->attributes = NULL_TREE;
+ type = grokdeclarator (declarator, type_specifiers, context, 0, &attrs);
+ if (attrs && type != error_mark_node)
+ {
+ if (CLASS_TYPE_P (type))
+ warning (OPT_Wattributes, "ignoring attributes applied to class type %qT "
+ "outside of definition", type);
+ else if (MAYBE_CLASS_TYPE_P (type))
+ /* A template type parameter or other dependent type. */
+ warning (OPT_Wattributes, "ignoring attributes applied to dependent "
+ "type %qT without an associated declaration", type);
+ else
+ cplus_decl_attributes (&type, attrs, 0);
+ }
+ return type;
+}
+
+/* Process a DECLARATOR for a function-scope variable declaration,
+ namespace-scope variable declaration, or function declaration.
+ (Function definitions go through start_function; class member
+ declarations appearing in the body of the class go through
+ grokfield.) The DECL corresponding to the DECLARATOR is returned.
+ If an error occurs, the error_mark_node is returned instead.
+
+ DECLSPECS are the decl-specifiers for the declaration. INITIALIZED is
+ SD_INITIALIZED if an explicit initializer is present, or SD_DEFAULTED
+ for an explicitly defaulted function, or SD_DELETED for an explicitly
+ deleted function, but 0 (SD_UNINITIALIZED) if this is a variable
+ implicitly initialized via a default constructor. ATTRIBUTES and
+ PREFIX_ATTRIBUTES are GNU attributes associated with this declaration.
+
+ The scope represented by the context of the returned DECL is pushed
+ (if it is not the global namespace) and is assigned to
+ *PUSHED_SCOPE_P. The caller is then responsible for calling
+ pop_scope on *PUSHED_SCOPE_P if it is set. */
+
+tree
+start_decl (const cp_declarator *declarator,
+ cp_decl_specifier_seq *declspecs,
+ int initialized,
+ tree attributes,
+ tree prefix_attributes,
+ tree *pushed_scope_p)
+{
+ tree decl;
+ tree context;
+ bool was_public;
+ int flags;
+ bool alias;
+
+ *pushed_scope_p = NULL_TREE;
+
+ /* An object declared as __attribute__((deprecated)) suppresses
+ warnings of uses of other deprecated items. */
+ if (lookup_attribute ("deprecated", attributes))
+ deprecated_state = DEPRECATED_SUPPRESS;
+
+ attributes = chainon (attributes, prefix_attributes);
+
+ decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
+ &attributes);
+
+ deprecated_state = DEPRECATED_NORMAL;
+
+ if (decl == NULL_TREE || VOID_TYPE_P (decl)
+ || decl == error_mark_node)
+ return error_mark_node;
+
+ context = CP_DECL_CONTEXT (decl);
+ if (context != global_namespace)
+ *pushed_scope_p = push_scope (context);
+
+ if (initialized)
+ /* Is it valid for this decl to have an initializer at all?
+ If not, set INITIALIZED to zero, which will indirectly
+ tell `cp_finish_decl' to ignore the initializer once it is parsed. */
+ switch (TREE_CODE (decl))
+ {
+ case TYPE_DECL:
+ error ("typedef %qD is initialized (use decltype instead)", decl);
+ return error_mark_node;
+
+ case FUNCTION_DECL:
+ if (initialized == SD_DELETED)
+ /* We'll handle the rest of the semantics later, but we need to
+ set this now so it's visible to duplicate_decls. */
+ DECL_DELETED_FN (decl) = 1;
+ break;
+
+ default:
+ break;
+ }
+
+ if (initialized)
+ {
+ if (! toplevel_bindings_p ()
+ && DECL_EXTERNAL (decl))
+ warning (0, "declaration of %q#D has %<extern%> and is initialized",
+ decl);
+ DECL_EXTERNAL (decl) = 0;
+ if (toplevel_bindings_p ())
+ TREE_STATIC (decl) = 1;
+ }
+ alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)) != 0;
+
+ if (alias && TREE_CODE (decl) == FUNCTION_DECL)
+ record_key_method_defined (decl);
+
+ /* If this is a typedef that names the class for linkage purposes
+ (7.1.3p8), apply any attributes directly to the type. */
+ if (TREE_CODE (decl) == TYPE_DECL
+ && OVERLOAD_TYPE_P (TREE_TYPE (decl))
+ && decl == TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl))))
+ flags = ATTR_FLAG_TYPE_IN_PLACE;
+ else
+ flags = 0;
+
+ /* Set attributes here so if duplicate decl, will have proper attributes. */
+ cplus_decl_attributes (&decl, attributes, flags);
+
+ /* Dllimported symbols cannot be defined. Static data members (which
+ can be initialized in-class and dllimported) go through grokfield,
+ not here, so we don't need to exclude those decls when checking for
+ a definition. */
+ if (initialized && DECL_DLLIMPORT_P (decl))
+ {
+ error ("definition of %q#D is marked %<dllimport%>", decl);
+ DECL_DLLIMPORT_P (decl) = 0;
+ }
+
+ /* If #pragma weak was used, mark the decl weak now. */
+ if (!processing_template_decl)
+ maybe_apply_pragma_weak (decl);
+
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (decl)
+ && DECL_UNINLINABLE (decl)
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
+ warning (0, "inline function %q+D given attribute noinline", decl);
+
+ if (TYPE_P (context) && COMPLETE_TYPE_P (complete_type (context)))
+ {
+ if (VAR_P (decl))
+ {
+ tree field = lookup_field (context, DECL_NAME (decl), 0, false);
+ if (field == NULL_TREE || !VAR_P (field))
+ error ("%q#D is not a static member of %q#T", decl, context);
+ else
+ {
+ if (DECL_CONTEXT (field) != context)
+ {
+ if (!same_type_p (DECL_CONTEXT (field), context))
+ permerror (input_location, "ISO C++ does not permit %<%T::%D%> "
+ "to be defined as %<%T::%D%>",
+ DECL_CONTEXT (field), DECL_NAME (decl),
+ context, DECL_NAME (decl));
+ DECL_CONTEXT (decl) = DECL_CONTEXT (field);
+ }
+ /* Static data member are tricky; an in-class initialization
+ still doesn't provide a definition, so the in-class
+ declaration will have DECL_EXTERNAL set, but will have an
+ initialization. Thus, duplicate_decls won't warn
+ about this situation, and so we check here. */
+ if (initialized && DECL_INITIALIZED_IN_CLASS_P (field))
+ error ("duplicate initialization of %qD", decl);
+ if (duplicate_decls (decl, field, /*newdecl_is_friend=*/false))
+ decl = field;
+ if (decl_spec_seq_has_spec_p (declspecs, ds_constexpr)
+ && !DECL_DECLARED_CONSTEXPR_P (field))
+ error ("%qD declared %<constexpr%> outside its class", field);
+ }
+ }
+ else
+ {
+ tree field = check_classfn (context, decl,
+ (processing_template_decl
+ > template_class_depth (context))
+ ? current_template_parms
+ : NULL_TREE);
+ if (field && field != error_mark_node
+ && duplicate_decls (decl, field,
+ /*newdecl_is_friend=*/false))
+ decl = field;
+ }
+
+ /* cp_finish_decl sets DECL_EXTERNAL if DECL_IN_AGGR_P is set. */
+ DECL_IN_AGGR_P (decl) = 0;
+ /* Do not mark DECL as an explicit specialization if it was not
+ already marked as an instantiation; a declaration should
+ never be marked as a specialization unless we know what
+ template is being specialized. */
+ if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
+ {
+ SET_DECL_TEMPLATE_SPECIALIZATION (decl);
+
+ /* [temp.expl.spec] An explicit specialization of a static data
+ member of a template is a definition if the declaration
+ includes an initializer; otherwise, it is a declaration.
+
+ We check for processing_specialization so this only applies
+ to the new specialization syntax. */
+ if (!initialized && processing_specialization)
+ DECL_EXTERNAL (decl) = 1;
+ }
+
+ if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)
+ /* Aliases are definitions. */
+ && !alias)
+ permerror (input_location, "declaration of %q#D outside of class is not definition",
+ decl);
+ }
+
+ was_public = TREE_PUBLIC (decl);
+
+ /* Enter this declaration into the symbol table. */
+ decl = maybe_push_decl (decl);
+
+ if (processing_template_decl)
+ decl = push_template_decl (decl);
+ if (decl == error_mark_node)
+ return error_mark_node;
+
+ if (VAR_P (decl)
+ && DECL_NAMESPACE_SCOPE_P (decl) && !TREE_PUBLIC (decl) && !was_public
+ && !DECL_THIS_STATIC (decl) && !DECL_ARTIFICIAL (decl))
+ {
+ /* This is a const variable with implicit 'static'. Set
+ DECL_THIS_STATIC so we can tell it from variables that are
+ !TREE_PUBLIC because of the anonymous namespace. */
+ gcc_assert (CP_TYPE_CONST_P (TREE_TYPE (decl)) || errorcount);
+ DECL_THIS_STATIC (decl) = 1;
+ }
+
+ if (!processing_template_decl && VAR_P (decl))
+ start_decl_1 (decl, initialized);
+
+ return decl;
+}
+
+/* Process the declaration of a variable DECL. INITIALIZED is true
+ iff DECL is explicitly initialized. (INITIALIZED is false if the
+ variable is initialized via an implicitly-called constructor.)
+ This function must be called for ordinary variables (including, for
+ example, implicit instantiations of templates), but must not be
+ called for template declarations. */
+
+void
+start_decl_1 (tree decl, bool initialized)
+{
+ tree type;
+ bool complete_p;
+ bool aggregate_definition_p;
+
+ gcc_assert (!processing_template_decl);
+
+ if (error_operand_p (decl))
+ return;
+
+ gcc_assert (VAR_P (decl));
+
+ type = TREE_TYPE (decl);
+ complete_p = COMPLETE_TYPE_P (type);
+ aggregate_definition_p = MAYBE_CLASS_TYPE_P (type) && !DECL_EXTERNAL (decl);
+
+ /* If an explicit initializer is present, or if this is a definition
+ of an aggregate, then we need a complete type at this point.
+ (Scalars are always complete types, so there is nothing to
+ check.) This code just sets COMPLETE_P; errors (if necessary)
+ are issued below. */
+ if ((initialized || aggregate_definition_p)
+ && !complete_p
+ && COMPLETE_TYPE_P (complete_type (type)))
+ {
+ complete_p = true;
+ /* We will not yet have set TREE_READONLY on DECL if the type
+ was "const", but incomplete, before this point. But, now, we
+ have a complete type, so we can try again. */
+ cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
+ }
+
+ if (initialized)
+ /* Is it valid for this decl to have an initializer at all? */
+ {
+ /* Don't allow initializations for incomplete types except for
+ arrays which might be completed by the initialization. */
+ if (complete_p)
+ ; /* A complete type is ok. */
+ else if (type_uses_auto (type))
+ ; /* An auto type is ok. */
+ else if (TREE_CODE (type) != ARRAY_TYPE)
+ {
+ error ("variable %q#D has initializer but incomplete type", decl);
+ type = TREE_TYPE (decl) = error_mark_node;
+ }
+ else if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
+ {
+ if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))
+ error ("elements of array %q#D have incomplete type", decl);
+ /* else we already gave an error in start_decl. */
+ }
+ }
+ else if (aggregate_definition_p && !complete_p)
+ {
+ if (type_uses_auto (type))
+ error ("declaration of %q#D has no initializer", decl);
+ else
+ error ("aggregate %q#D has incomplete type and cannot be defined",
+ decl);
+ /* Change the type so that assemble_variable will give
+ DECL an rtl we can live with: (mem (const_int 0)). */
+ type = TREE_TYPE (decl) = error_mark_node;
+ }
+
+ /* Create a new scope to hold this declaration if necessary.
+ Whether or not a new scope is necessary cannot be determined
+ until after the type has been completed; if the type is a
+ specialization of a class template it is not until after
+ instantiation has occurred that TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+ will be set correctly. */
+ maybe_push_cleanup_level (type);
+}
+
+/* Handle initialization of references. DECL, TYPE, and INIT have the
+ same meaning as in cp_finish_decl. *CLEANUP must be NULL on entry,
+ but will be set to a new CLEANUP_STMT if a temporary is created
+ that must be destroyed subsequently.
+
+ Returns an initializer expression to use to initialize DECL, or
+ NULL if the initialization can be performed statically.
+
+ Quotes on semantics can be found in ARM 8.4.3. */
+
+static tree
+grok_reference_init (tree decl, tree type, tree init, int flags)
+{
+ if (init == NULL_TREE)
+ {
+ if ((DECL_LANG_SPECIFIC (decl) == 0
+ || DECL_IN_AGGR_P (decl) == 0)
+ && ! DECL_THIS_EXTERN (decl))
+ error ("%qD declared as reference but not initialized", decl);
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (init) == TREE_LIST)
+ init = build_x_compound_expr_from_list (init, ELK_INIT,
+ tf_warning_or_error);
+
+ if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE
+ && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
+ /* Note: default conversion is only called in very special cases. */
+ init = decay_conversion (init, tf_warning_or_error);
+
+ /* Convert INIT to the reference type TYPE. This may involve the
+ creation of a temporary, whose lifetime must be the same as that
+ of the reference. If so, a DECL_EXPR for the temporary will be
+ added just after the DECL_EXPR for DECL. That's why we don't set
+ DECL_INITIAL for local references (instead assigning to them
+ explicitly); we need to allow the temporary to be initialized
+ first. */
+ return initialize_reference (type, init, flags,
+ tf_warning_or_error);
+}
+
+/* Designated initializers in arrays are not supported in GNU C++.
+ The parser cannot detect this error since it does not know whether
+ a given brace-enclosed initializer is for a class type or for an
+ array. This function checks that CE does not use a designated
+ initializer. If it does, an error is issued. Returns true if CE
+ is valid, i.e., does not have a designated initializer. */
+
+static bool
+check_array_designated_initializer (constructor_elt *ce,
+ unsigned HOST_WIDE_INT index)
+{
+ /* Designated initializers for array elements are not supported. */
+ if (ce->index)
+ {
+ /* The parser only allows identifiers as designated
+ initializers. */
+ if (ce->index == error_mark_node)
+ {
+ error ("name used in a GNU-style designated "
+ "initializer for an array");
+ return false;
+ }
+ else if (identifier_p (ce->index))
+ {
+ error ("name %qD used in a GNU-style designated "
+ "initializer for an array", ce->index);
+ return false;
+ }
+
+ ce->index = cxx_constant_value (ce->index);
+
+ if (TREE_CODE (ce->index) == INTEGER_CST)
+ {
+ /* A C99 designator is OK if it matches the current index. */
+ if (TREE_INT_CST_LOW (ce->index) == index)
+ return true;
+ else
+ sorry ("non-trivial designated initializers not supported");
+ }
+ else
+ gcc_unreachable ();
+
+ return false;
+ }
+
+ return true;
+}
+
+/* When parsing `int a[] = {1, 2};' we don't know the size of the
+ array until we finish parsing the initializer. If that's the
+ situation we're in, update DECL accordingly. */
+
+static void
+maybe_deduce_size_from_array_init (tree decl, tree init)
+{
+ tree type = TREE_TYPE (decl);
+
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_DOMAIN (type) == NULL_TREE
+ && TREE_CODE (decl) != TYPE_DECL)
+ {
+ /* do_default is really a C-ism to deal with tentative definitions.
+ But let's leave it here to ease the eventual merge. */
+ int do_default = !DECL_EXTERNAL (decl);
+ tree initializer = init ? init : DECL_INITIAL (decl);
+ int failure = 0;
+
+ /* Check that there are no designated initializers in INIT, as
+ those are not supported in GNU C++, and as the middle-end
+ will crash if presented with a non-numeric designated
+ initializer. */
+ if (initializer && BRACE_ENCLOSED_INITIALIZER_P (initializer))
+ {
+ vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (initializer);
+ constructor_elt *ce;
+ HOST_WIDE_INT i;
+ FOR_EACH_VEC_SAFE_ELT (v, i, ce)
+ if (!check_array_designated_initializer (ce, i))
+ failure = 1;
+ }
+
+ if (!failure)
+ {
+ failure = cp_complete_array_type (&TREE_TYPE (decl), initializer,
+ do_default);
+ if (failure == 1)
+ {
+ error ("initializer fails to determine size of %qD", decl);
+ }
+ else if (failure == 2)
+ {
+ if (do_default)
+ {
+ error ("array size missing in %qD", decl);
+ }
+ /* If a `static' var's size isn't known, make it extern as
+ well as static, so it does not get allocated. If it's not
+ `static', then don't mark it extern; finish_incomplete_decl
+ will give it a default size and it will get allocated. */
+ else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
+ DECL_EXTERNAL (decl) = 1;
+ }
+ else if (failure == 3)
+ {
+ error ("zero-size array %qD", decl);
+ }
+ }
+
+ cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);
+
+ relayout_decl (decl);
+ }
+}
+
+/* Set DECL_SIZE, DECL_ALIGN, etc. for DECL (a VAR_DECL), and issue
+ any appropriate error messages regarding the layout. */
+
+static void
+layout_var_decl (tree decl)
+{
+ tree type;
+
+ type = TREE_TYPE (decl);
+ if (type == error_mark_node)
+ return;
+
+ /* If we haven't already laid out this declaration, do so now.
+ Note that we must not call complete type for an external object
+ because it's type might involve templates that we are not
+ supposed to instantiate yet. (And it's perfectly valid to say
+ `extern X x' for some incomplete type `X'.) */
+ if (!DECL_EXTERNAL (decl))
+ complete_type (type);
+ if (!DECL_SIZE (decl)
+ && TREE_TYPE (decl) != error_mark_node
+ && (COMPLETE_TYPE_P (type)
+ || (TREE_CODE (type) == ARRAY_TYPE
+ && !TYPE_DOMAIN (type)
+ && COMPLETE_TYPE_P (TREE_TYPE (type)))))
+ layout_decl (decl, 0);
+
+ if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE)
+ {
+ /* An automatic variable with an incomplete type: that is an error.
+ Don't talk about array types here, since we took care of that
+ message in grokdeclarator. */
+ error ("storage size of %qD isn%'t known", decl);
+ TREE_TYPE (decl) = error_mark_node;
+ }
+#if 0
+ /* Keep this code around in case we later want to control debug info
+ based on whether a type is "used". (jason 1999-11-11) */
+
+ else if (!DECL_EXTERNAL (decl) && MAYBE_CLASS_TYPE_P (ttype))
+ /* Let debugger know it should output info for this type. */
+ note_debug_info_needed (ttype);
+
+ if (TREE_STATIC (decl) && DECL_CLASS_SCOPE_P (decl))
+ note_debug_info_needed (DECL_CONTEXT (decl));
+#endif
+
+ if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
+ && DECL_SIZE (decl) != NULL_TREE
+ && ! TREE_CONSTANT (DECL_SIZE (decl)))
+ {
+ if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
+ constant_expression_warning (DECL_SIZE (decl));
+ else
+ {
+ error ("storage size of %qD isn%'t constant", decl);
+ TREE_TYPE (decl) = error_mark_node;
+ }
+ }
+}
+
+/* If a local static variable is declared in an inline function, or if
+ we have a weak definition, we must endeavor to create only one
+ instance of the variable at link-time. */
+
+void
+maybe_commonize_var (tree decl)
+{
+ /* Static data in a function with comdat linkage also has comdat
+ linkage. */
+ if (TREE_STATIC (decl)
+ /* Don't mess with __FUNCTION__. */
+ && ! DECL_ARTIFICIAL (decl)
+ && DECL_FUNCTION_SCOPE_P (decl)
+ && vague_linkage_p (DECL_CONTEXT (decl)))
+ {
+ if (flag_weak)
+ {
+ /* With weak symbols, we simply make the variable COMDAT;
+ that will cause copies in multiple translations units to
+ be merged. */
+ comdat_linkage (decl);
+ }
+ else
+ {
+ if (DECL_INITIAL (decl) == NULL_TREE
+ || DECL_INITIAL (decl) == error_mark_node)
+ {
+ /* Without weak symbols, we can use COMMON to merge
+ uninitialized variables. */
+ TREE_PUBLIC (decl) = 1;
+ DECL_COMMON (decl) = 1;
+ }
+ else
+ {
+ /* While for initialized variables, we must use internal
+ linkage -- which means that multiple copies will not
+ be merged. */
+ TREE_PUBLIC (decl) = 0;
+ DECL_COMMON (decl) = 0;
+ warning_at (input_location, 0,
+ "sorry: semantics of inline function static "
+ "data %q+#D are wrong (you%'ll wind up "
+ "with multiple copies)", decl);
+ warning_at (DECL_SOURCE_LOCATION (decl), 0,
+ " you can work around this by removing "
+ "the initializer");
+ }
+ }
+ }
+ else if (DECL_LANG_SPECIFIC (decl) && DECL_COMDAT (decl))
+ /* Set it up again; we might have set DECL_INITIAL since the last
+ time. */
+ comdat_linkage (decl);
+}
+
+/* Issue an error message if DECL is an uninitialized const variable. */
+
+static void
+check_for_uninitialized_const_var (tree decl)
+{
+ tree type = strip_array_types (TREE_TYPE (decl));
+
+ /* ``Unless explicitly declared extern, a const object does not have
+ external linkage and must be initialized. ($8.4; $12.1)'' ARM
+ 7.1.6 */
+ if (VAR_P (decl)
+ && TREE_CODE (type) != REFERENCE_TYPE
+ && CP_TYPE_CONST_P (type)
+ && !DECL_INITIAL (decl))
+ {
+ tree field = default_init_uninitialized_part (type);
+ if (!field)
+ return;
+
+ permerror (DECL_SOURCE_LOCATION (decl),
+ "uninitialized const %qD", decl);
+
+ if (CLASS_TYPE_P (type))
+ {
+ tree defaulted_ctor;
+
+ inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
+ "%q#T has no user-provided default constructor", type);
+ defaulted_ctor = in_class_defaulted_default_constructor (type);
+ if (defaulted_ctor)
+ inform (DECL_SOURCE_LOCATION (defaulted_ctor),
+ "constructor is not user-provided because it is "
+ "explicitly defaulted in the class body");
+ inform (0, "and the implicitly-defined constructor does not "
+ "initialize %q+#D", field);
+ }
+ }
+}
+
+/* Structure holding the current initializer being processed by reshape_init.
+ CUR is a pointer to the current element being processed, END is a pointer
+ after the last element present in the initializer. */
+typedef struct reshape_iterator_t
+{
+ constructor_elt *cur;
+ constructor_elt *end;
+} reshape_iter;
+
+static tree reshape_init_r (tree, reshape_iter *, bool, tsubst_flags_t);
+
+/* FIELD is a FIELD_DECL or NULL. In the former case, the value
+ returned is the next FIELD_DECL (possibly FIELD itself) that can be
+ initialized. If there are no more such fields, the return value
+ will be NULL. */
+
+tree
+next_initializable_field (tree field)
+{
+ while (field
+ && (TREE_CODE (field) != FIELD_DECL
+ || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))
+ || DECL_ARTIFICIAL (field)))
+ field = DECL_CHAIN (field);
+
+ return field;
+}
+
+/* Subroutine of reshape_init_array and reshape_init_vector, which does
+ the actual work. ELT_TYPE is the element type of the array. MAX_INDEX is an
+ INTEGER_CST representing the size of the array minus one (the maximum index),
+ or NULL_TREE if the array was declared without specifying the size. D is
+ the iterator within the constructor. */
+
+static tree
+reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
+ tsubst_flags_t complain)
+{
+ tree new_init;
+ bool sized_array_p = (max_index && TREE_CONSTANT (max_index));
+ unsigned HOST_WIDE_INT max_index_cst = 0;
+ unsigned HOST_WIDE_INT index;
+
+ /* The initializer for an array is always a CONSTRUCTOR. */
+ new_init = build_constructor (init_list_type_node, NULL);
+
+ if (sized_array_p)
+ {
+ /* Minus 1 is used for zero sized arrays. */
+ if (integer_all_onesp (max_index))
+ return new_init;
+
+ if (tree_fits_uhwi_p (max_index))
+ max_index_cst = tree_to_uhwi (max_index);
+ /* sizetype is sign extended, not zero extended. */
+ else
+ max_index_cst = tree_to_uhwi (fold_convert (size_type_node, max_index));
+ }
+
+ /* Loop until there are no more initializers. */
+ for (index = 0;
+ d->cur != d->end && (!sized_array_p || index <= max_index_cst);
+ ++index)
+ {
+ tree elt_init;
+ constructor_elt *old_cur = d->cur;
+
+ check_array_designated_initializer (d->cur, index);
+ elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
+ complain);
+ if (elt_init == error_mark_node)
+ return error_mark_node;
+ CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init),
+ size_int (index), elt_init);
+ if (!TREE_CONSTANT (elt_init))
+ TREE_CONSTANT (new_init) = false;
+
+ /* This can happen with an invalid initializer (c++/54501). */
+ if (d->cur == old_cur && !sized_array_p)
+ break;
+ }
+
+ return new_init;
+}
+
+/* Subroutine of reshape_init_r, processes the initializers for arrays.
+ Parameters are the same of reshape_init_r. */
+
+static tree
+reshape_init_array (tree type, reshape_iter *d, tsubst_flags_t complain)
+{
+ tree max_index = NULL_TREE;
+
+ gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
+
+ if (TYPE_DOMAIN (type))
+ max_index = array_type_nelts (type);
+
+ return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain);
+}
+
+/* Subroutine of reshape_init_r, processes the initializers for vectors.
+ Parameters are the same of reshape_init_r. */
+
+static tree
+reshape_init_vector (tree type, reshape_iter *d, tsubst_flags_t complain)
+{
+ tree max_index = NULL_TREE;
+
+ gcc_assert (TREE_CODE (type) == VECTOR_TYPE);
+
+ if (COMPOUND_LITERAL_P (d->cur->value))
+ {
+ tree value = d->cur->value;
+ if (!same_type_p (TREE_TYPE (value), type))
+ {
+ if (complain & tf_error)
+ error ("invalid type %qT as initializer for a vector of type %qT",
+ TREE_TYPE (d->cur->value), type);
+ value = error_mark_node;
+ }
+ ++d->cur;
+ return value;
+ }
+
+ /* For a vector, we initialize it as an array of the appropriate size. */
+ if (TREE_CODE (type) == VECTOR_TYPE)
+ max_index = size_int (TYPE_VECTOR_SUBPARTS (type) - 1);
+
+ return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain);
+}
+
+/* Subroutine of reshape_init_r, processes the initializers for classes
+ or union. Parameters are the same of reshape_init_r. */
+
+static tree
+reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
+ tsubst_flags_t complain)
+{
+ tree field;
+ tree new_init;
+
+ gcc_assert (CLASS_TYPE_P (type));
+
+ /* The initializer for a class is always a CONSTRUCTOR. */
+ new_init = build_constructor (init_list_type_node, NULL);
+ field = next_initializable_field (TYPE_FIELDS (type));
+
+ if (!field)
+ {
+ /* [dcl.init.aggr]
+
+ An initializer for an aggregate member that is an
+ empty class shall have the form of an empty
+ initializer-list {}. */
+ if (!first_initializer_p)
+ {
+ if (complain & tf_error)
+ error ("initializer for %qT must be brace-enclosed", type);
+ return error_mark_node;
+ }
+ return new_init;
+ }
+
+ /* Loop through the initializable fields, gathering initializers. */
+ while (d->cur != d->end)
+ {
+ tree field_init;
+ constructor_elt *old_cur = d->cur;
+
+ /* Handle designated initializers, as an extension. */
+ if (d->cur->index)
+ {
+ if (d->cur->index == error_mark_node)
+ return error_mark_node;
+
+ if (TREE_CODE (d->cur->index) == INTEGER_CST)
+ {
+ if (complain & tf_error)
+ error ("%<[%E] =%> used in a GNU-style designated initializer"
+ " for class %qT", d->cur->index, type);
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (d->cur->index) == FIELD_DECL)
+ /* We already reshaped this. */
+ gcc_assert (d->cur->index == field);
+ else
+ field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);
+
+ if (!field || TREE_CODE (field) != FIELD_DECL)
+ {
+ if (complain & tf_error)
+ error ("%qT has no non-static data member named %qD", type,
+ d->cur->index);
+ return error_mark_node;
+ }
+ }
+
+ /* If we processed all the member of the class, we are done. */
+ if (!field)
+ break;
+
+ field_init = reshape_init_r (TREE_TYPE (field), d,
+ /*first_initializer_p=*/false, complain);
+ if (field_init == error_mark_node)
+ return error_mark_node;
+
+ if (d->cur == old_cur && d->cur->index)
+ {
+ /* This can happen with an invalid initializer for a flexible
+ array member (c++/54441). */
+ if (complain & tf_error)
+ error ("invalid initializer for %q#D", field);
+ return error_mark_node;
+ }
+
+ CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), field, field_init);
+
+ /* [dcl.init.aggr]
+
+ When a union is initialized with a brace-enclosed
+ initializer, the braces shall only contain an
+ initializer for the first member of the union. */
+ if (TREE_CODE (type) == UNION_TYPE)
+ break;
+
+ field = next_initializable_field (DECL_CHAIN (field));
+ }
+
+ return new_init;
+}
+
+/* Subroutine of reshape_init_r. We're in a context where C99 initializer
+ designators are not valid; either complain or return true to indicate
+ that reshape_init_r should return error_mark_node. */
+
+static bool
+has_designator_problem (reshape_iter *d, tsubst_flags_t complain)
+{
+ if (d->cur->index)
+ {
+ if (complain & tf_error)
+ error ("C99 designator %qE outside aggregate initializer",
+ d->cur->index);
+ else
+ return true;
+ }
+ return false;
+}
+
+/* Subroutine of reshape_init, which processes a single initializer (part of
+ a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the
+ iterator within the CONSTRUCTOR which points to the initializer to process.
+ FIRST_INITIALIZER_P is true if this is the first initializer of the
+ outermost CONSTRUCTOR node. */
+
+static tree
+reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
+ tsubst_flags_t complain)
+{
+ tree init = d->cur->value;
+
+ if (error_operand_p (init))
+ return error_mark_node;
+
+ if (first_initializer_p && !CP_AGGREGATE_TYPE_P (type)
+ && has_designator_problem (d, complain))
+ return error_mark_node;
+
+ if (TREE_CODE (type) == COMPLEX_TYPE)
+ {
+ /* A complex type can be initialized from one or two initializers,
+ but braces are not elided. */
+ d->cur++;
+ if (BRACE_ENCLOSED_INITIALIZER_P (init))
+ {
+ if (CONSTRUCTOR_NELTS (init) > 2)
+ {
+ if (complain & tf_error)
+ error ("too many initializers for %qT", type);
+ else
+ return error_mark_node;
+ }
+ }
+ else if (first_initializer_p && d->cur != d->end)
+ {
+ vec<constructor_elt, va_gc> *v = 0;
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, d->cur->value);
+ if (has_designator_problem (d, complain))
+ return error_mark_node;
+ d->cur++;
+ init = build_constructor (init_list_type_node, v);
+ }
+ return init;
+ }
+
+ /* A non-aggregate type is always initialized with a single
+ initializer. */
+ if (!CP_AGGREGATE_TYPE_P (type))
+ {
+ /* It is invalid to initialize a non-aggregate type with a
+ brace-enclosed initializer before C++0x.
+ We need to check for BRACE_ENCLOSED_INITIALIZER_P here because
+ of g++.old-deja/g++.mike/p7626.C: a pointer-to-member constant is
+ a CONSTRUCTOR (with a record type). */
+ if (TREE_CODE (init) == CONSTRUCTOR
+ && BRACE_ENCLOSED_INITIALIZER_P (init)) /* p7626.C */
+ {
+ if (SCALAR_TYPE_P (type))
+ {
+ if (complain & tf_error)
+ error ("braces around scalar initializer for type %qT", type);
+ init = error_mark_node;
+ }
+ else
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ }
+
+ d->cur++;
+ return init;
+ }
+
+ /* [dcl.init.aggr]
+
+ All implicit type conversions (clause _conv_) are considered when
+ initializing the aggregate member with an initializer from an
+ initializer-list. If the initializer can initialize a member,
+ the member is initialized. Otherwise, if the member is itself a
+ non-empty subaggregate, brace elision is assumed and the
+ initializer is considered for the initialization of the first
+ member of the subaggregate. */
+ if (TREE_CODE (init) != CONSTRUCTOR
+ /* But don't try this for the first initializer, since that would be
+ looking through the outermost braces; A a2 = { a1 }; is not a
+ valid aggregate initialization. */
+ && !first_initializer_p
+ && (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init))
+ || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL,
+ complain)))
+ {
+ d->cur++;
+ return init;
+ }
+
+ /* [dcl.init.string]
+
+ A char array (whether plain char, signed char, or unsigned char)
+ can be initialized by a string-literal (optionally enclosed in
+ braces); a wchar_t array can be initialized by a wide
+ string-literal (optionally enclosed in braces). */
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))))
+ {
+ tree str_init = init;
+
+ /* Strip one level of braces if and only if they enclose a single
+ element (as allowed by [dcl.init.string]). */
+ if (!first_initializer_p
+ && TREE_CODE (str_init) == CONSTRUCTOR
+ && vec_safe_length (CONSTRUCTOR_ELTS (str_init)) == 1)
+ {
+ str_init = (*CONSTRUCTOR_ELTS (str_init))[0].value;
+ }
+
+ /* If it's a string literal, then it's the initializer for the array
+ as a whole. Otherwise, continue with normal initialization for
+ array types (one value per array element). */
+ if (TREE_CODE (str_init) == STRING_CST)
+ {
+ if (has_designator_problem (d, complain))
+ return error_mark_node;
+ d->cur++;
+ return str_init;
+ }
+ }
+
+ /* The following cases are about aggregates. If we are not within a full
+ initializer already, and there is not a CONSTRUCTOR, it means that there
+ is a missing set of braces (that is, we are processing the case for
+ which reshape_init exists). */
+ if (!first_initializer_p)
+ {
+ if (TREE_CODE (init) == CONSTRUCTOR)
+ {
+ if (TREE_TYPE (init) && TYPE_PTRMEMFUNC_P (TREE_TYPE (init)))
+ /* There is no need to reshape pointer-to-member function
+ initializers, as they are always constructed correctly
+ by the front end. */
+ ;
+ else if (COMPOUND_LITERAL_P (init))
+ /* For a nested compound literal, there is no need to reshape since
+ brace elision is not allowed. Even if we decided to allow it,
+ we should add a call to reshape_init in finish_compound_literal,
+ before calling digest_init, so changing this code would still
+ not be necessary. */
+ gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (init));
+ else
+ {
+ ++d->cur;
+ gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
+ return reshape_init (type, init, complain);
+ }
+ }
+
+ warning (OPT_Wmissing_braces, "missing braces around initializer for %qT",
+ type);
+ }
+
+ /* Dispatch to specialized routines. */
+ if (CLASS_TYPE_P (type))
+ return reshape_init_class (type, d, first_initializer_p, complain);
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ return reshape_init_array (type, d, complain);
+ else if (TREE_CODE (type) == VECTOR_TYPE)
+ return reshape_init_vector (type, d, complain);
+ else
+ gcc_unreachable();
+}
+
+/* Undo the brace-elision allowed by [dcl.init.aggr] in a
+ brace-enclosed aggregate initializer.
+
+ INIT is the CONSTRUCTOR containing the list of initializers describing
+ a brace-enclosed initializer for an entity of the indicated aggregate TYPE.
+ It may not presently match the shape of the TYPE; for example:
+
+ struct S { int a; int b; };
+ struct S a[] = { 1, 2, 3, 4 };
+
+ Here INIT will hold a vector of four elements, rather than a
+ vector of two elements, each itself a vector of two elements. This
+ routine transforms INIT from the former form into the latter. The
+ revised CONSTRUCTOR node is returned. */
+
+tree
+reshape_init (tree type, tree init, tsubst_flags_t complain)
+{
+ vec<constructor_elt, va_gc> *v;
+ reshape_iter d;
+ tree new_init;
+
+ gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
+
+ v = CONSTRUCTOR_ELTS (init);
+
+ /* An empty constructor does not need reshaping, and it is always a valid
+ initializer. */
+ if (vec_safe_is_empty (v))
+ return init;
+
+ /* Recurse on this CONSTRUCTOR. */
+ d.cur = &(*v)[0];
+ d.end = d.cur + v->length ();
+
+ new_init = reshape_init_r (type, &d, true, complain);
+ if (new_init == error_mark_node)
+ return error_mark_node;
+
+ /* Make sure all the element of the constructor were used. Otherwise,
+ issue an error about exceeding initializers. */
+ if (d.cur != d.end)
+ {
+ if (complain & tf_error)
+ error ("too many initializers for %qT", type);
+ else
+ return error_mark_node;
+ }
+
+ return new_init;
+}
+
+/* Verify array initializer. Returns true if errors have been reported. */
+
+bool
+check_array_initializer (tree decl, tree type, tree init)
+{
+ tree element_type = TREE_TYPE (type);
+
+ /* The array type itself need not be complete, because the
+ initializer may tell us how many elements are in the array.
+ But, the elements of the array must be complete. */
+ if (!COMPLETE_TYPE_P (complete_type (element_type)))
+ {
+ if (decl)
+ error ("elements of array %q#D have incomplete type", decl);
+ else
+ error ("elements of array %q#T have incomplete type", type);
+ return true;
+ }
+ /* A compound literal can't have variable size. */
+ if (init && !decl
+ && ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type)))
+ || !TREE_CONSTANT (TYPE_SIZE (element_type))))
+ {
+ error ("variable-sized compound literal");
+ return true;
+ }
+ return false;
+}
+
+/* Subroutine of check_initializer; args are passed down from that function.
+ Set stmts_are_full_exprs_p to 1 across a call to build_aggr_init. */
+
+static tree
+build_aggr_init_full_exprs (tree decl, tree init, int flags)
+
+{
+ gcc_assert (stmts_are_full_exprs_p ());
+ return build_aggr_init (decl, init, flags, tf_warning_or_error);
+}
+
+/* Verify INIT (the initializer for DECL), and record the
+ initialization in DECL_INITIAL, if appropriate. CLEANUP is as for
+ grok_reference_init.
+
+ If the return value is non-NULL, it is an expression that must be
+ evaluated dynamically to initialize DECL. */
+
+static tree
+check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups)
+{
+ tree type = TREE_TYPE (decl);
+ tree init_code = NULL;
+ tree core_type;
+
+ /* Things that are going to be initialized need to have complete
+ type. */
+ TREE_TYPE (decl) = type = complete_type (TREE_TYPE (decl));
+
+ if (DECL_HAS_VALUE_EXPR_P (decl))
+ {
+ /* A variable with DECL_HAS_VALUE_EXPR_P set is just a placeholder,
+ it doesn't have storage to be initialized. */
+ gcc_assert (init == NULL_TREE);
+ return NULL_TREE;
+ }
+
+ if (type == error_mark_node)
+ /* We will have already complained. */
+ return NULL_TREE;
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (check_array_initializer (decl, type, init))
+ return NULL_TREE;
+ }
+ else if (!COMPLETE_TYPE_P (type))
+ {
+ error ("%q#D has incomplete type", decl);
+ TREE_TYPE (decl) = error_mark_node;
+ return NULL_TREE;
+ }
+ else
+ /* There is no way to make a variable-sized class type in GNU C++. */
+ gcc_assert (TREE_CONSTANT (TYPE_SIZE (type)));
+
+ if (init && BRACE_ENCLOSED_INITIALIZER_P (init))
+ {
+ int init_len = vec_safe_length (CONSTRUCTOR_ELTS (init));
+ if (SCALAR_TYPE_P (type))
+ {
+ if (init_len == 0)
+ {
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ init = build_zero_init (type, NULL_TREE, false);
+ }
+ else if (init_len != 1 && TREE_CODE (type) != COMPLEX_TYPE)
+ {
+ error ("scalar object %qD requires one element in initializer",
+ decl);
+ TREE_TYPE (decl) = error_mark_node;
+ return NULL_TREE;
+ }
+ }
+ }
+
+ if (TREE_CODE (decl) == CONST_DECL)
+ {
+ gcc_assert (TREE_CODE (type) != REFERENCE_TYPE);
+
+ DECL_INITIAL (decl) = init;
+
+ gcc_assert (init != NULL_TREE);
+ init = NULL_TREE;
+ }
+ else if (!init && DECL_REALLY_EXTERN (decl))
+ ;
+ else if (init || type_build_ctor_call (type)
+ || TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ init = grok_reference_init (decl, type, init, flags);
+ flags |= LOOKUP_ALREADY_DIGESTED;
+ }
+ else if (!init)
+ check_for_uninitialized_const_var (decl);
+ /* Do not reshape constructors of vectors (they don't need to be
+ reshaped. */
+ else if (BRACE_ENCLOSED_INITIALIZER_P (init))
+ {
+ if (is_std_init_list (type))
+ {
+ init = perform_implicit_conversion (type, init,
+ tf_warning_or_error);
+ flags |= LOOKUP_ALREADY_DIGESTED;
+ }
+ else if (TYPE_NON_AGGREGATE_CLASS (type))
+ {
+ /* Don't reshape if the class has constructors. */
+ if (cxx_dialect == cxx98)
+ error ("in C++98 %qD must be initialized by constructor, "
+ "not by %<{...}%>",
+ decl);
+ }
+ else if (TREE_CODE (type) == VECTOR_TYPE && TYPE_VECTOR_OPAQUE (type))
+ {
+ error ("opaque vector types cannot be initialized");
+ init = error_mark_node;
+ }
+ else
+ {
+ init = reshape_init (type, init, tf_warning_or_error);
+ if (SCALAR_TYPE_P (type))
+ check_narrowing (type, init);
+ }
+ }
+
+ /* If DECL has an array type without a specific bound, deduce the
+ array size from the initializer. */
+ maybe_deduce_size_from_array_init (decl, init);
+ type = TREE_TYPE (decl);
+ if (type == error_mark_node)
+ return NULL_TREE;
+
+ if ((type_build_ctor_call (type) || CLASS_TYPE_P (type))
+ && !(flags & LOOKUP_ALREADY_DIGESTED)
+ && !(init && BRACE_ENCLOSED_INITIALIZER_P (init)
+ && CP_AGGREGATE_TYPE_P (type)
+ && (CLASS_TYPE_P (type)
+ || !TYPE_NEEDS_CONSTRUCTING (type)
+ || type_has_extended_temps (type))))
+ {
+ init_code = build_aggr_init_full_exprs (decl, init, flags);
+
+ /* A constructor call is a non-trivial initializer even if
+ it isn't explicitly written. */
+ if (TREE_SIDE_EFFECTS (init_code))
+ DECL_NONTRIVIALLY_INITIALIZED_P (decl) = true;
+
+ /* If this is a constexpr initializer, expand_default_init will
+ have returned an INIT_EXPR rather than a CALL_EXPR. In that
+ case, pull the initializer back out and pass it down into
+ store_init_value. */
+ while (TREE_CODE (init_code) == EXPR_STMT
+ || TREE_CODE (init_code) == CONVERT_EXPR)
+ init_code = TREE_OPERAND (init_code, 0);
+ if (TREE_CODE (init_code) == INIT_EXPR)
+ {
+ init = TREE_OPERAND (init_code, 1);
+ init_code = NULL_TREE;
+ /* Don't call digest_init; it's unnecessary and will complain
+ about aggregate initialization of non-aggregate classes. */
+ flags |= LOOKUP_ALREADY_DIGESTED;
+ }
+ else if (DECL_DECLARED_CONSTEXPR_P (decl))
+ {
+ /* Declared constexpr, but no suitable initializer; massage
+ init appropriately so we can pass it into store_init_value
+ for the error. */
+ if (init && BRACE_ENCLOSED_INITIALIZER_P (init))
+ init = finish_compound_literal (type, init,
+ tf_warning_or_error);
+ else if (CLASS_TYPE_P (type)
+ && (!init || TREE_CODE (init) == TREE_LIST))
+ {
+ init = build_functional_cast (type, init, tf_none);
+ if (TREE_CODE (init) == TARGET_EXPR)
+ TARGET_EXPR_DIRECT_INIT_P (init) = true;
+ }
+ init_code = NULL_TREE;
+ }
+ else
+ init = NULL_TREE;
+ }
+
+ if (init && TREE_CODE (init) != TREE_VEC)
+ {
+ /* In aggregate initialization of a variable, each element
+ initialization is a full-expression because there is no
+ enclosing expression. */
+ gcc_assert (stmts_are_full_exprs_p ());
+
+ init_code = store_init_value (decl, init, cleanups, flags);
+
+ if (pedantic && TREE_CODE (type) == ARRAY_TYPE
+ && DECL_INITIAL (decl)
+ && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
+ && PAREN_STRING_LITERAL_P (DECL_INITIAL (decl)))
+ warning (0, "array %qD initialized by parenthesized string literal %qE",
+ decl, DECL_INITIAL (decl));
+ init = NULL;
+ }
+ }
+ else
+ {
+ if (CLASS_TYPE_P (core_type = strip_array_types (type))
+ && (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)
+ || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)))
+ diagnose_uninitialized_cst_or_ref_member (core_type, /*using_new=*/false,
+ /*complain=*/true);
+
+ check_for_uninitialized_const_var (decl);
+ }
+
+ if (init && init != error_mark_node)
+ init_code = build2 (INIT_EXPR, type, decl, init);
+
+ if (init_code && DECL_IN_AGGR_P (decl))
+ {
+ static int explained = 0;
+
+ if (cxx_dialect < cxx11)
+ error ("initializer invalid for static member with constructor");
+ else
+ error ("non-constant in-class initialization invalid for static "
+ "member %qD", decl);
+ if (!explained)
+ {
+ inform (input_location,
+ "(an out of class initialization is required)");
+ explained = 1;
+ }
+ return NULL_TREE;
+ }
+
+ return init_code;
+}
+
+/* If DECL is not a local variable, give it RTL. */
+
+static void
+make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
+{
+ int toplev = toplevel_bindings_p ();
+ int defer_p;
+ const char *filename;
+
+ /* Set the DECL_ASSEMBLER_NAME for the object. */
+ if (asmspec)
+ {
+ /* The `register' keyword, when used together with an
+ asm-specification, indicates that the variable should be
+ placed in a particular register. */
+ if (VAR_P (decl) && DECL_REGISTER (decl))
+ {
+ set_user_assembler_name (decl, asmspec);
+ DECL_HARD_REGISTER (decl) = 1;
+ }
+ else
+ {
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+ set_builtin_user_assembler_name (decl, asmspec);
+ set_user_assembler_name (decl, asmspec);
+ }
+ }
+
+ /* Handle non-variables up front. */
+ if (!VAR_P (decl))
+ {
+ rest_of_decl_compilation (decl, toplev, at_eof);
+ return;
+ }
+
+ /* If we see a class member here, it should be a static data
+ member. */
+ if (DECL_LANG_SPECIFIC (decl) && DECL_IN_AGGR_P (decl))
+ {
+ gcc_assert (TREE_STATIC (decl));
+ /* An in-class declaration of a static data member should be
+ external; it is only a declaration, and not a definition. */
+ if (init == NULL_TREE)
+ gcc_assert (DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl));
+ }
+
+ /* We don't create any RTL for local variables. */
+ if (DECL_FUNCTION_SCOPE_P (decl) && !TREE_STATIC (decl))
+ return;
+
+ /* We defer emission of local statics until the corresponding
+ DECL_EXPR is expanded. */
+ defer_p = DECL_FUNCTION_SCOPE_P (decl) || DECL_VIRTUAL_P (decl);
+
+ /* We try to defer namespace-scope static constants so that they are
+ not emitted into the object file unnecessarily. */
+ filename = LOCATION_FILE (input_location);
+ if (!DECL_VIRTUAL_P (decl)
+ && TREE_READONLY (decl)
+ && DECL_INITIAL (decl) != NULL_TREE
+ && DECL_INITIAL (decl) != error_mark_node
+ && filename != NULL
+ && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))
+ && toplev
+ && !TREE_PUBLIC (decl))
+ {
+ /* Fool with the linkage of static consts according to #pragma
+ interface. */
+ struct c_fileinfo *finfo = get_fileinfo (filename);
+ if (!finfo->interface_unknown && !TREE_PUBLIC (decl))
+ {
+ TREE_PUBLIC (decl) = 1;
+ DECL_EXTERNAL (decl) = finfo->interface_only;
+ }
+
+ defer_p = 1;
+ }
+ /* Likewise for template instantiations. */
+ else if (DECL_LANG_SPECIFIC (decl)
+ && DECL_IMPLICIT_INSTANTIATION (decl))
+ defer_p = 1;
+
+ /* If we're not deferring, go ahead and assemble the variable. */
+ if (!defer_p)
+ rest_of_decl_compilation (decl, toplev, at_eof);
+}
+
+/* walk_tree helper for wrap_temporary_cleanups, below. */
+
+static tree
+wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data)
+{
+ /* Stop at types or full-expression boundaries. */
+ if (TYPE_P (*stmt_p)
+ || TREE_CODE (*stmt_p) == CLEANUP_POINT_EXPR)
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (*stmt_p) == TARGET_EXPR)
+ {
+ tree guard = (tree)data;
+ tree tcleanup = TARGET_EXPR_CLEANUP (*stmt_p);
+
+ tcleanup = build2 (TRY_CATCH_EXPR, void_type_node, tcleanup, guard);
+ /* Tell honor_protect_cleanup_actions to handle this as a separate
+ cleanup. */
+ TRY_CATCH_IS_CLEANUP (tcleanup) = 1;
+
+ TARGET_EXPR_CLEANUP (*stmt_p) = tcleanup;
+ }
+
+ return NULL_TREE;
+}
+
+/* We're initializing a local variable which has a cleanup GUARD. If there
+ are any temporaries used in the initializer INIT of this variable, we
+ need to wrap their cleanups with TRY_CATCH_EXPR (, GUARD) so that the
+ variable will be cleaned up properly if one of them throws.
+
+ Unfortunately, there's no way to express this properly in terms of
+ nesting, as the regions for the temporaries overlap the region for the
+ variable itself; if there are two temporaries, the variable needs to be
+ the first thing destroyed if either of them throws. However, we only
+ want to run the variable's cleanup if it actually got constructed. So
+ we need to guard the temporary cleanups with the variable's cleanup if
+ they are run on the normal path, but not if they are run on the
+ exceptional path. We implement this by telling
+ honor_protect_cleanup_actions to strip the variable cleanup from the
+ exceptional path. */
+
+static void
+wrap_temporary_cleanups (tree init, tree guard)
+{
+ cp_walk_tree_without_duplicates (&init, wrap_cleanups_r, (void *)guard);
+}
+
+/* Generate code to initialize DECL (a local variable). */
+
+static void
+initialize_local_var (tree decl, tree init)
+{
+ tree type = TREE_TYPE (decl);
+ tree cleanup;
+ int already_used;
+
+ gcc_assert (VAR_P (decl)
+ || TREE_CODE (decl) == RESULT_DECL);
+ gcc_assert (!TREE_STATIC (decl));
+
+ if (DECL_SIZE (decl) == NULL_TREE)
+ {
+ /* If we used it already as memory, it must stay in memory. */
+ DECL_INITIAL (decl) = NULL_TREE;
+ TREE_ADDRESSABLE (decl) = TREE_USED (decl);
+ return;
+ }
+
+ if (type == error_mark_node)
+ return;
+
+ /* Compute and store the initial value. */
+ already_used = TREE_USED (decl) || TREE_USED (type);
+ if (TREE_USED (type))
+ DECL_READ_P (decl) = 1;
+
+ /* Generate a cleanup, if necessary. */
+ cleanup = cxx_maybe_build_cleanup (decl, tf_warning_or_error);
+
+ /* Perform the initialization. */
+ if (init)
+ {
+ if (TREE_CODE (init) == INIT_EXPR
+ && !TREE_SIDE_EFFECTS (TREE_OPERAND (init, 1)))
+ {
+ /* Stick simple initializers in DECL_INITIAL so that
+ -Wno-init-self works (c++/34772). */
+ gcc_assert (TREE_OPERAND (init, 0) == decl);
+ DECL_INITIAL (decl) = TREE_OPERAND (init, 1);
+ }
+ else
+ {
+ int saved_stmts_are_full_exprs_p;
+
+ /* If we're only initializing a single object, guard the
+ destructors of any temporaries used in its initializer with
+ its destructor. This isn't right for arrays because each
+ element initialization is a full-expression. */
+ if (cleanup && TREE_CODE (type) != ARRAY_TYPE)
+ wrap_temporary_cleanups (init, cleanup);
+
+ gcc_assert (building_stmt_list_p ());
+ saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
+ current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+ finish_expr_stmt (init);
+ current_stmt_tree ()->stmts_are_full_exprs_p =
+ saved_stmts_are_full_exprs_p;
+ }
+ }
+
+ /* Set this to 0 so we can tell whether an aggregate which was
+ initialized was ever used. Don't do this if it has a
+ destructor, so we don't complain about the 'resource
+ allocation is initialization' idiom. Now set
+ attribute((unused)) on types so decls of that type will be
+ marked used. (see TREE_USED, above.) */
+ if (TYPE_NEEDS_CONSTRUCTING (type)
+ && ! already_used
+ && TYPE_HAS_TRIVIAL_DESTRUCTOR (type)
+ && DECL_NAME (decl))
+ TREE_USED (decl) = 0;
+ else if (already_used)
+ TREE_USED (decl) = 1;
+
+ if (cleanup)
+ finish_decl_cleanup (decl, cleanup);
+}
+
+/* DECL is a VAR_DECL for a compiler-generated variable with static
+ storage duration (like a virtual table) whose initializer is a
+ compile-time constant. Initialize the variable and provide it to the
+ back end. */
+
+void
+initialize_artificial_var (tree decl, vec<constructor_elt, va_gc> *v)
+{
+ tree init;
+ gcc_assert (DECL_ARTIFICIAL (decl));
+ init = build_constructor (TREE_TYPE (decl), v);
+ gcc_assert (TREE_CODE (init) == CONSTRUCTOR);
+ DECL_INITIAL (decl) = init;
+ DECL_INITIALIZED_P (decl) = 1;
+ determine_visibility (decl);
+ layout_var_decl (decl);
+ maybe_commonize_var (decl);
+ make_rtl_for_nonlocal_decl (decl, init, /*asmspec=*/NULL);
+}
+
+/* INIT is the initializer for a variable, as represented by the
+ parser. Returns true iff INIT is type-dependent. */
+
+static bool
+type_dependent_init_p (tree init)
+{
+ if (TREE_CODE (init) == TREE_LIST)
+ /* A parenthesized initializer, e.g.: int i (3, 2); ? */
+ return any_type_dependent_elements_p (init);
+ else if (TREE_CODE (init) == CONSTRUCTOR)
+ /* A brace-enclosed initializer, e.g.: int i = { 3 }; ? */
+ {
+ vec<constructor_elt, va_gc> *elts;
+ size_t nelts;
+ size_t i;
+
+ elts = CONSTRUCTOR_ELTS (init);
+ nelts = vec_safe_length (elts);
+ for (i = 0; i < nelts; ++i)
+ if (type_dependent_init_p ((*elts)[i].value))
+ return true;
+ }
+ else
+ /* It must be a simple expression, e.g., int i = 3; */
+ return type_dependent_expression_p (init);
+
+ return false;
+}
+
+/* INIT is the initializer for a variable, as represented by the
+ parser. Returns true iff INIT is value-dependent. */
+
+static bool
+value_dependent_init_p (tree init)
+{
+ if (TREE_CODE (init) == TREE_LIST)
+ /* A parenthesized initializer, e.g.: int i (3, 2); ? */
+ return any_value_dependent_elements_p (init);
+ else if (TREE_CODE (init) == CONSTRUCTOR)
+ /* A brace-enclosed initializer, e.g.: int i = { 3 }; ? */
+ {
+ vec<constructor_elt, va_gc> *elts;
+ size_t nelts;
+ size_t i;
+
+ elts = CONSTRUCTOR_ELTS (init);
+ nelts = vec_safe_length (elts);
+ for (i = 0; i < nelts; ++i)
+ if (value_dependent_init_p ((*elts)[i].value))
+ return true;
+ }
+ else
+ /* It must be a simple expression, e.g., int i = 3; */
+ return value_dependent_expression_p (init);
+
+ return false;
+}
+
+/* Finish processing of a declaration;
+ install its line number and initial value.
+ If the length of an array type is not known before,
+ it must be determined now, from the initial value, or it is an error.
+
+ INIT is the initializer (if any) for DECL. If INIT_CONST_EXPR_P is
+ true, then INIT is an integral constant expression.
+
+ FLAGS is LOOKUP_ONLYCONVERTING if the = init syntax was used, else 0
+ if the (init) syntax was used. */
+
+void
+cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
+ tree asmspec_tree, int flags)
+{
+ tree type;
+ vec<tree, va_gc> *cleanups = NULL;
+ const char *asmspec = NULL;
+ int was_readonly = 0;
+ bool var_definition_p = false;
+ tree auto_node;
+
+ if (decl == error_mark_node)
+ return;
+ else if (! decl)
+ {
+ if (init)
+ error ("assignment (not initialization) in declaration");
+ return;
+ }
+
+ gcc_assert (TREE_CODE (decl) != RESULT_DECL);
+ /* Parameters are handled by store_parm_decls, not cp_finish_decl. */
+ gcc_assert (TREE_CODE (decl) != PARM_DECL);
+
+ type = TREE_TYPE (decl);
+ if (type == error_mark_node)
+ return;
+
+ /* If a name was specified, get the string. */
+ if (at_namespace_scope_p ())
+ asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
+ if (asmspec_tree && asmspec_tree != error_mark_node)
+ asmspec = TREE_STRING_POINTER (asmspec_tree);
+
+ if (current_class_type
+ && CP_DECL_CONTEXT (decl) == current_class_type
+ && TYPE_BEING_DEFINED (current_class_type)
+ && !CLASSTYPE_TEMPLATE_INSTANTIATION (current_class_type)
+ && (DECL_INITIAL (decl) || init))
+ DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
+
+ if (TREE_CODE (decl) != FUNCTION_DECL
+ && (auto_node = type_uses_auto (type)))
+ {
+ tree d_init;
+ if (init == NULL_TREE)
+ {
+ if (DECL_LANG_SPECIFIC (decl)
+ && DECL_TEMPLATE_INSTANTIATION (decl)
+ && !DECL_TEMPLATE_INSTANTIATED (decl))
+ {
+ /* init is null because we're deferring instantiating the
+ initializer until we need it. Well, we need it now. */
+ instantiate_decl (decl, /*defer_ok*/true, /*expl*/false);
+ return;
+ }
+
+ error ("declaration of %q#D has no initializer", decl);
+ TREE_TYPE (decl) = error_mark_node;
+ return;
+ }
+ d_init = init;
+ if (TREE_CODE (d_init) == TREE_LIST)
+ d_init = build_x_compound_expr_from_list (d_init, ELK_INIT,
+ tf_warning_or_error);
+ d_init = resolve_nondeduced_context (d_init);
+ type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
+ auto_node);
+ if (type == error_mark_node)
+ return;
+ cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
+ }
+
+ if (!ensure_literal_type_for_constexpr_object (decl))
+ DECL_DECLARED_CONSTEXPR_P (decl) = 0;
+
+ if (VAR_P (decl)
+ && DECL_CLASS_SCOPE_P (decl)
+ && DECL_INITIALIZED_IN_CLASS_P (decl))
+ check_static_variable_definition (decl, type);
+
+ if (init && TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ tree clone;
+ if (init == ridpointers[(int)RID_DELETE])
+ {
+ /* FIXME check this is 1st decl. */
+ DECL_DELETED_FN (decl) = 1;
+ DECL_DECLARED_INLINE_P (decl) = 1;
+ DECL_INITIAL (decl) = error_mark_node;
+ FOR_EACH_CLONE (clone, decl)
+ {
+ DECL_DELETED_FN (clone) = 1;
+ DECL_DECLARED_INLINE_P (clone) = 1;
+ DECL_INITIAL (clone) = error_mark_node;
+ }
+ init = NULL_TREE;
+ }
+ else if (init == ridpointers[(int)RID_DEFAULT])
+ {
+ if (defaultable_fn_check (decl))
+ DECL_DEFAULTED_FN (decl) = 1;
+ else
+ DECL_INITIAL (decl) = NULL_TREE;
+ }
+ }
+
+ if (init && VAR_P (decl))
+ {
+ DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
+ /* If DECL is a reference, then we want to know whether init is a
+ reference constant; init_const_expr_p as passed tells us whether
+ it's an rvalue constant. */
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ init_const_expr_p = potential_constant_expression (init);
+ if (init_const_expr_p)
+ {
+ /* Set these flags now for templates. We'll update the flags in
+ store_init_value for instantiations. */
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
+ if (decl_maybe_constant_var_p (decl))
+ TREE_CONSTANT (decl) = 1;
+ }
+ }
+
+ if (processing_template_decl)
+ {
+ bool type_dependent_p;
+
+ /* Add this declaration to the statement-tree. */
+ if (at_function_scope_p ())
+ add_decl_expr (decl);
+
+ type_dependent_p = dependent_type_p (type);
+
+ if (check_for_bare_parameter_packs (init))
+ {
+ init = NULL_TREE;
+ DECL_INITIAL (decl) = NULL_TREE;
+ }
+
+ /* Generally, initializers in templates are expanded when the
+ template is instantiated. But, if DECL is a variable constant
+ then it can be used in future constant expressions, so its value
+ must be available. */
+
+ if (!VAR_P (decl) || dependent_type_p (type))
+ /* We can't do anything if the decl has dependent type. */;
+ else if (init
+ && init_const_expr_p
+ && !type_dependent_p
+ && decl_maybe_constant_var_p (decl)
+ && !type_dependent_init_p (init)
+ && !value_dependent_init_p (init))
+ {
+ /* This variable seems to be a non-dependent constant, so process
+ its initializer. If check_initializer returns non-null the
+ initialization wasn't constant after all. */
+ tree init_code;
+ cleanups = make_tree_vector ();
+ init_code = check_initializer (decl, init, flags, &cleanups);
+ if (init_code == NULL_TREE)
+ init = NULL_TREE;
+ release_tree_vector (cleanups);
+ }
+ else if (!DECL_PRETTY_FUNCTION_P (decl))
+ {
+ /* Deduce array size even if the initializer is dependent. */
+ maybe_deduce_size_from_array_init (decl, init);
+ /* And complain about multiple initializers. */
+ if (init && TREE_CODE (init) == TREE_LIST && TREE_CHAIN (init)
+ && !MAYBE_CLASS_TYPE_P (type))
+ init = build_x_compound_expr_from_list (init, ELK_INIT,
+ tf_warning_or_error);
+ }
+
+ if (init)
+ DECL_INITIAL (decl) = init;
+ return;
+ }
+
+ /* Just store non-static data member initializers for later. */
+ if (init && TREE_CODE (decl) == FIELD_DECL)
+ DECL_INITIAL (decl) = init;
+
+ /* Take care of TYPE_DECLs up front. */
+ if (TREE_CODE (decl) == TYPE_DECL)
+ {
+ if (type != error_mark_node
+ && MAYBE_CLASS_TYPE_P (type) && DECL_NAME (decl))
+ {
+ if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type)
+ warning (0, "shadowing previous type declaration of %q#D", decl);
+ set_identifier_type_value (DECL_NAME (decl), decl);
+ }
+
+ /* If we have installed this as the canonical typedef for this
+ type, and that type has not been defined yet, delay emitting
+ the debug information for it, as we will emit it later. */
+ if (TYPE_MAIN_DECL (TREE_TYPE (decl)) == decl
+ && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
+ TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
+
+ rest_of_decl_compilation (decl, DECL_FILE_SCOPE_P (decl),
+ at_eof);
+ return;
+ }
+
+ /* A reference will be modified here, as it is initialized. */
+ if (! DECL_EXTERNAL (decl)
+ && TREE_READONLY (decl)
+ && TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ was_readonly = 1;
+ TREE_READONLY (decl) = 0;
+ }
+
+ if (VAR_P (decl))
+ {
+ /* If this is a local variable that will need a mangled name,
+ register it now. We must do this before processing the
+ initializer for the variable, since the initialization might
+ require a guard variable, and since the mangled name of the
+ guard variable will depend on the mangled name of this
+ variable. */
+ if (DECL_FUNCTION_SCOPE_P (decl)
+ && TREE_STATIC (decl)
+ && !DECL_ARTIFICIAL (decl))
+ {
+ push_local_name (decl);
+ if (DECL_CONSTRUCTOR_P (current_function_decl)
+ || DECL_DESTRUCTOR_P (current_function_decl))
+ /* Normally local_decls is populated during GIMPLE lowering,
+ but [cd]tors are never actually compiled directly. We need
+ to put statics on the list so we can deal with the label
+ address extension. FIXME. */
+ add_local_decl (cfun, decl);
+ }
+
+ /* Convert the initializer to the type of DECL, if we have not
+ already initialized DECL. */
+ if (!DECL_INITIALIZED_P (decl)
+ /* If !DECL_EXTERNAL then DECL is being defined. In the
+ case of a static data member initialized inside the
+ class-specifier, there can be an initializer even if DECL
+ is *not* defined. */
+ && (!DECL_EXTERNAL (decl) || init))
+ {
+ if (TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type))
+ {
+ tree jclass
+ = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jclass"));
+ /* Allow libjava/prims.cc define primitive classes. */
+ if (init != NULL_TREE
+ || jclass == NULL_TREE
+ || TREE_CODE (jclass) != TYPE_DECL
+ || !POINTER_TYPE_P (TREE_TYPE (jclass))
+ || !same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (TREE_TYPE (jclass))))
+ error ("Java object %qD not allocated with %<new%>", decl);
+ init = NULL_TREE;
+ }
+ cleanups = make_tree_vector ();
+ init = check_initializer (decl, init, flags, &cleanups);
+
+ /* Handle:
+
+ [dcl.init]
+
+ The memory occupied by any object of static storage
+ duration is zero-initialized at program startup before
+ any other initialization takes place.
+
+ We cannot create an appropriate initializer until after
+ the type of DECL is finalized. If DECL_INITIAL is set,
+ then the DECL is statically initialized, and any
+ necessary zero-initialization has already been performed. */
+ if (TREE_STATIC (decl) && !DECL_INITIAL (decl))
+ DECL_INITIAL (decl) = build_zero_init (TREE_TYPE (decl),
+ /*nelts=*/NULL_TREE,
+ /*static_storage_p=*/true);
+ /* Remember that the initialization for this variable has
+ taken place. */
+ DECL_INITIALIZED_P (decl) = 1;
+ /* This declaration is the definition of this variable,
+ unless we are initializing a static data member within
+ the class specifier. */
+ if (!DECL_EXTERNAL (decl))
+ var_definition_p = true;
+ }
+ /* If the variable has an array type, lay out the type, even if
+ there is no initializer. It is valid to index through the
+ array, and we must get TYPE_ALIGN set correctly on the array
+ type. */
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ layout_type (type);
+
+ if (TREE_STATIC (decl)
+ && !at_function_scope_p ()
+ && current_function_decl == NULL)
+ /* So decl is a global variable or a static member of a
+ non local class. Record the types it uses
+ so that we can decide later to emit debug info for them. */
+ record_types_used_by_current_var_decl (decl);
+ }
+ else if (TREE_CODE (decl) == FIELD_DECL
+ && TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type))
+ error ("non-static data member %qD has Java class type", decl);
+
+ /* Add this declaration to the statement-tree. This needs to happen
+ after the call to check_initializer so that the DECL_EXPR for a
+ reference temp is added before the DECL_EXPR for the reference itself. */
+ if (DECL_FUNCTION_SCOPE_P (decl))
+ add_decl_expr (decl);
+
+ /* Let the middle end know about variables and functions -- but not
+ static data members in uninstantiated class templates. */
+ if (VAR_OR_FUNCTION_DECL_P (decl))
+ {
+ if (VAR_P (decl))
+ {
+ layout_var_decl (decl);
+ maybe_commonize_var (decl);
+ }
+
+ /* This needs to happen after the linkage is set. */
+ determine_visibility (decl);
+
+ if (var_definition_p && TREE_STATIC (decl))
+ {
+ /* If a TREE_READONLY variable needs initialization
+ at runtime, it is no longer readonly and we need to
+ avoid MEM_READONLY_P being set on RTL created for it. */
+ if (init)
+ {
+ if (TREE_READONLY (decl))
+ TREE_READONLY (decl) = 0;
+ was_readonly = 0;
+ }
+ else if (was_readonly)
+ TREE_READONLY (decl) = 1;
+
+ /* Likewise if it needs destruction. */
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ TREE_READONLY (decl) = 0;
+ }
+
+ make_rtl_for_nonlocal_decl (decl, init, asmspec);
+
+ /* Check for abstractness of the type. Notice that there is no
+ need to strip array types here since the check for those types
+ is already done within create_array_type_for_decl. */
+ abstract_virtuals_error (decl, type);
+
+ if (TREE_TYPE (decl) == error_mark_node)
+ /* No initialization required. */
+ ;
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (init)
+ {
+ if (init == ridpointers[(int)RID_DEFAULT])
+ {
+ /* An out-of-class default definition is defined at
+ the point where it is explicitly defaulted. */
+ if (DECL_DELETED_FN (decl))
+ maybe_explain_implicit_delete (decl);
+ else if (DECL_INITIAL (decl) == error_mark_node)
+ synthesize_method (decl);
+ }
+ else
+ error ("function %q#D is initialized like a variable", decl);
+ }
+ /* else no initialization required. */
+ }
+ else if (DECL_EXTERNAL (decl)
+ && ! (DECL_LANG_SPECIFIC (decl)
+ && DECL_NOT_REALLY_EXTERN (decl)))
+ {
+ if (init)
+ DECL_INITIAL (decl) = init;
+ }
+ /* A variable definition. */
+ else if (DECL_FUNCTION_SCOPE_P (decl) && !TREE_STATIC (decl))
+ /* Initialize the local variable. */
+ initialize_local_var (decl, init);
+
+ /* If a variable is defined, and then a subsequent
+ definition with external linkage is encountered, we will
+ get here twice for the same variable. We want to avoid
+ calling expand_static_init more than once. For variables
+ that are not static data members, we can call
+ expand_static_init only when we actually process the
+ initializer. It is not legal to redeclare a static data
+ member, so this issue does not arise in that case. */
+ else if (var_definition_p && TREE_STATIC (decl))
+ expand_static_init (decl, init);
+ }
+
+ /* If a CLEANUP_STMT was created to destroy a temporary bound to a
+ reference, insert it in the statement-tree now. */
+ if (cleanups)
+ {
+ unsigned i; tree t;
+ FOR_EACH_VEC_ELT (*cleanups, i, t)
+ push_cleanup (decl, t, false);
+ release_tree_vector (cleanups);
+ }
+
+ if (was_readonly)
+ TREE_READONLY (decl) = 1;
+
+ invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
+}
+
+/* Returns a declaration for a VAR_DECL as if:
+
+ extern "C" TYPE NAME;
+
+ had been seen. Used to create compiler-generated global
+ variables. */
+
+static tree
+declare_global_var (tree name, tree type)
+{
+ tree decl;
+
+ push_to_top_level ();
+ decl = build_decl (input_location, VAR_DECL, name, type);
+ TREE_PUBLIC (decl) = 1;
+ DECL_EXTERNAL (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ /* If the user has explicitly declared this variable (perhaps
+ because the code we are compiling is part of a low-level runtime
+ library), then it is possible that our declaration will be merged
+ with theirs by pushdecl. */
+ decl = pushdecl (decl);
+ cp_finish_decl (decl, NULL_TREE, false, NULL_TREE, 0);
+ pop_from_top_level ();
+
+ return decl;
+}
+
+/* Returns the type for the argument to "__cxa_atexit" (or "atexit",
+ if "__cxa_atexit" is not being used) corresponding to the function
+ to be called when the program exits. */
+
+static tree
+get_atexit_fn_ptr_type (void)
+{
+ tree fn_type;
+
+ if (!atexit_fn_ptr_type_node)
+ {
+ tree arg_type;
+ if (flag_use_cxa_atexit
+ && !targetm.cxx.use_atexit_for_cxa_atexit ())
+ /* The parameter to "__cxa_atexit" is "void (*)(void *)". */
+ arg_type = ptr_type_node;
+ else
+ /* The parameter to "atexit" is "void (*)(void)". */
+ arg_type = NULL_TREE;
+
+ fn_type = build_function_type_list (void_type_node,
+ arg_type, NULL_TREE);
+ atexit_fn_ptr_type_node = build_pointer_type (fn_type);
+ }
+
+ return atexit_fn_ptr_type_node;
+}
+
+/* Returns a pointer to the `atexit' function. Note that if
+ FLAG_USE_CXA_ATEXIT is nonzero, then this will actually be the new
+ `__cxa_atexit' function specified in the IA64 C++ ABI. */
+
+static tree
+get_atexit_node (void)
+{
+ tree atexit_fndecl;
+ tree fn_type;
+ tree fn_ptr_type;
+ const char *name;
+ bool use_aeabi_atexit;
+
+ if (atexit_node)
+ return atexit_node;
+
+ if (flag_use_cxa_atexit && !targetm.cxx.use_atexit_for_cxa_atexit ())
+ {
+ /* The declaration for `__cxa_atexit' is:
+
+ int __cxa_atexit (void (*)(void *), void *, void *)
+
+ We build up the argument types and then the function type
+ itself. */
+ tree argtype0, argtype1, argtype2;
+
+ use_aeabi_atexit = targetm.cxx.use_aeabi_atexit ();
+ /* First, build the pointer-to-function type for the first
+ argument. */
+ fn_ptr_type = get_atexit_fn_ptr_type ();
+ /* Then, build the rest of the argument types. */
+ argtype2 = ptr_type_node;
+ if (use_aeabi_atexit)
+ {
+ argtype1 = fn_ptr_type;
+ argtype0 = ptr_type_node;
+ }
+ else
+ {
+ argtype1 = ptr_type_node;
+ argtype0 = fn_ptr_type;
+ }
+ /* And the final __cxa_atexit type. */
+ fn_type = build_function_type_list (integer_type_node,
+ argtype0, argtype1, argtype2,
+ NULL_TREE);
+ if (use_aeabi_atexit)
+ name = "__aeabi_atexit";
+ else
+ name = "__cxa_atexit";
+ }
+ else
+ {
+ /* The declaration for `atexit' is:
+
+ int atexit (void (*)());
+
+ We build up the argument types and then the function type
+ itself. */
+ fn_ptr_type = get_atexit_fn_ptr_type ();
+ /* Build the final atexit type. */
+ fn_type = build_function_type_list (integer_type_node,
+ fn_ptr_type, NULL_TREE);
+ name = "atexit";
+ }
+
+ /* Now, build the function declaration. */
+ push_lang_context (lang_name_c);
+ atexit_fndecl = build_library_fn_ptr (name, fn_type, ECF_LEAF | ECF_NOTHROW);
+ mark_used (atexit_fndecl);
+ pop_lang_context ();
+ atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error);
+
+ return atexit_node;
+}
+
+/* Like get_atexit_node, but for thread-local cleanups. */
+
+static tree
+get_thread_atexit_node (void)
+{
+ /* The declaration for `__cxa_thread_atexit' is:
+
+ int __cxa_thread_atexit (void (*)(void *), void *, void *) */
+ tree fn_type = build_function_type_list (integer_type_node,
+ get_atexit_fn_ptr_type (),
+ ptr_type_node, ptr_type_node,
+ NULL_TREE);
+
+ /* Now, build the function declaration. */
+ tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type,
+ ECF_LEAF | ECF_NOTHROW);
+ return decay_conversion (atexit_fndecl, tf_warning_or_error);
+}
+
+/* Returns the __dso_handle VAR_DECL. */
+
+static tree
+get_dso_handle_node (void)
+{
+ if (dso_handle_node)
+ return dso_handle_node;
+
+ /* Declare the variable. */
+ dso_handle_node = declare_global_var (get_identifier ("__dso_handle"),
+ ptr_type_node);
+
+#ifdef HAVE_GAS_HIDDEN
+ if (dso_handle_node != error_mark_node)
+ {
+ DECL_VISIBILITY (dso_handle_node) = VISIBILITY_HIDDEN;
+ DECL_VISIBILITY_SPECIFIED (dso_handle_node) = 1;
+ }
+#endif
+
+ return dso_handle_node;
+}
+
+/* Begin a new function with internal linkage whose job will be simply
+ to destroy some particular variable. */
+
+static GTY(()) int start_cleanup_cnt;
+
+static tree
+start_cleanup_fn (void)
+{
+ char name[32];
+ tree fntype;
+ tree fndecl;
+ bool use_cxa_atexit = flag_use_cxa_atexit
+ && !targetm.cxx.use_atexit_for_cxa_atexit ();
+
+ push_to_top_level ();
+
+ /* No need to mangle this. */
+ push_lang_context (lang_name_c);
+
+ /* Build the name of the function. */
+ sprintf (name, "__tcf_%d", start_cleanup_cnt++);
+ /* Build the function declaration. */
+ fntype = TREE_TYPE (get_atexit_fn_ptr_type ());
+ fndecl = build_lang_decl (FUNCTION_DECL, get_identifier (name), fntype);
+ /* It's a function with internal linkage, generated by the
+ compiler. */
+ TREE_PUBLIC (fndecl) = 0;
+ DECL_ARTIFICIAL (fndecl) = 1;
+ /* Make the function `inline' so that it is only emitted if it is
+ actually needed. It is unlikely that it will be inlined, since
+ it is only called via a function pointer, but we avoid unnecessary
+ emissions this way. */
+ DECL_DECLARED_INLINE_P (fndecl) = 1;
+ DECL_INTERFACE_KNOWN (fndecl) = 1;
+ /* Build the parameter. */
+ if (use_cxa_atexit)
+ {
+ tree parmdecl;
+
+ parmdecl = cp_build_parm_decl (NULL_TREE, ptr_type_node);
+ DECL_CONTEXT (parmdecl) = fndecl;
+ TREE_USED (parmdecl) = 1;
+ DECL_READ_P (parmdecl) = 1;
+ DECL_ARGUMENTS (fndecl) = parmdecl;
+ }
+
+ pushdecl (fndecl);
+ start_preparsed_function (fndecl, NULL_TREE, SF_PRE_PARSED);
+
+ pop_lang_context ();
+
+ return current_function_decl;
+}
+
+/* Finish the cleanup function begun by start_cleanup_fn. */
+
+static void
+end_cleanup_fn (void)
+{
+ expand_or_defer_fn (finish_function (0));
+
+ pop_from_top_level ();
+}
+
+/* Generate code to handle the destruction of DECL, an object with
+ static storage duration. */
+
+tree
+register_dtor_fn (tree decl)
+{
+ tree cleanup;
+ tree addr;
+ tree compound_stmt;
+ tree fcall;
+ tree type;
+ bool ob_parm, dso_parm, use_dtor;
+ tree arg0, arg1, arg2;
+ tree atex_node;
+
+ type = TREE_TYPE (decl);
+ if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+ return void_zero_node;
+
+ /* If we're using "__cxa_atexit" (or "__cxa_thread_atexit" or
+ "__aeabi_atexit"), and DECL is a class object, we can just pass the
+ destructor to "__cxa_atexit"; we don't have to build a temporary
+ function to do the cleanup. */
+ dso_parm = (flag_use_cxa_atexit
+ && !targetm.cxx.use_atexit_for_cxa_atexit ());
+ ob_parm = (DECL_THREAD_LOCAL_P (decl) || dso_parm);
+ use_dtor = ob_parm && CLASS_TYPE_P (type);
+ if (use_dtor)
+ {
+ int idx;
+
+ /* Find the destructor. */
+ idx = lookup_fnfields_1 (type, complete_dtor_identifier);
+ gcc_assert (idx >= 0);
+ cleanup = (*CLASSTYPE_METHOD_VEC (type))[idx];
+ /* Make sure it is accessible. */
+ perform_or_defer_access_check (TYPE_BINFO (type), cleanup, cleanup,
+ tf_warning_or_error);
+ }
+ else
+ {
+ /* Call build_cleanup before we enter the anonymous function so
+ that any access checks will be done relative to the current
+ scope, rather than the scope of the anonymous function. */
+ build_cleanup (decl);
+
+ /* Now start the function. */
+ cleanup = start_cleanup_fn ();
+
+ /* Now, recompute the cleanup. It may contain SAVE_EXPRs that refer
+ to the original function, rather than the anonymous one. That
+ will make the back end think that nested functions are in use,
+ which causes confusion. */
+ push_deferring_access_checks (dk_no_check);
+ fcall = build_cleanup (decl);
+ pop_deferring_access_checks ();
+
+ /* Create the body of the anonymous function. */
+ compound_stmt = begin_compound_stmt (BCS_FN_BODY);
+ finish_expr_stmt (fcall);
+ finish_compound_stmt (compound_stmt);
+ end_cleanup_fn ();
+ }
+
+ /* Call atexit with the cleanup function. */
+ mark_used (cleanup);
+ cleanup = build_address (cleanup);
+
+ if (DECL_THREAD_LOCAL_P (decl))
+ atex_node = get_thread_atexit_node ();
+ else
+ atex_node = get_atexit_node ();
+
+ if (use_dtor)
+ {
+ /* We must convert CLEANUP to the type that "__cxa_atexit"
+ expects. */
+ cleanup = build_nop (get_atexit_fn_ptr_type (), cleanup);
+ /* "__cxa_atexit" will pass the address of DECL to the
+ cleanup function. */
+ mark_used (decl);
+ addr = build_address (decl);
+ /* The declared type of the parameter to "__cxa_atexit" is
+ "void *". For plain "T*", we could just let the
+ machinery in cp_build_function_call convert it -- but if the
+ type is "cv-qualified T *", then we need to convert it
+ before passing it in, to avoid spurious errors. */
+ addr = build_nop (ptr_type_node, addr);
+ }
+ else
+ /* Since the cleanup functions we build ignore the address
+ they're given, there's no reason to pass the actual address
+ in, and, in general, it's cheaper to pass NULL than any
+ other value. */
+ addr = null_pointer_node;
+
+ if (dso_parm)
+ arg2 = cp_build_addr_expr (get_dso_handle_node (),
+ tf_warning_or_error);
+ else if (ob_parm)
+ /* Just pass NULL to the dso handle parm if we don't actually
+ have a DSO handle on this target. */
+ arg2 = null_pointer_node;
+ else
+ arg2 = NULL_TREE;
+
+ if (ob_parm)
+ {
+ if (!DECL_THREAD_LOCAL_P (decl)
+ && targetm.cxx.use_aeabi_atexit ())
+ {
+ arg1 = cleanup;
+ arg0 = addr;
+ }
+ else
+ {
+ arg1 = addr;
+ arg0 = cleanup;
+ }
+ }
+ else
+ {
+ arg0 = cleanup;
+ arg1 = NULL_TREE;
+ }
+ return cp_build_function_call_nary (atex_node, tf_warning_or_error,
+ arg0, arg1, arg2, NULL_TREE);
+}
+
+/* DECL is a VAR_DECL with static storage duration. INIT, if present,
+ is its initializer. Generate code to handle the construction
+ and destruction of DECL. */
+
+static void
+expand_static_init (tree decl, tree init)
+{
+ gcc_assert (VAR_P (decl));
+ gcc_assert (TREE_STATIC (decl));
+
+ /* Some variables require no dynamic initialization. */
+ if (!init
+ && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+ {
+ /* Make sure the destructor is callable. */
+ cxx_maybe_build_cleanup (decl, tf_warning_or_error);
+ return;
+ }
+
+ if (DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl)
+ && !DECL_FUNCTION_SCOPE_P (decl))
+ {
+ if (init)
+ error ("non-local variable %qD declared %<__thread%> "
+ "needs dynamic initialization", decl);
+ else
+ error ("non-local variable %qD declared %<__thread%> "
+ "has a non-trivial destructor", decl);
+ static bool informed;
+ if (!informed)
+ {
+ inform (DECL_SOURCE_LOCATION (decl),
+ "C++11 %<thread_local%> allows dynamic initialization "
+ "and destruction");
+ informed = true;
+ }
+ return;
+ }
+
+ if (DECL_FUNCTION_SCOPE_P (decl))
+ {
+ /* Emit code to perform this initialization but once. */
+ tree if_stmt = NULL_TREE, inner_if_stmt = NULL_TREE;
+ tree then_clause = NULL_TREE, inner_then_clause = NULL_TREE;
+ tree guard, guard_addr;
+ tree flag, begin;
+ /* We don't need thread-safety code for thread-local vars. */
+ bool thread_guard = (flag_threadsafe_statics
+ && !DECL_THREAD_LOCAL_P (decl));
+
+ /* Emit code to perform this initialization but once. This code
+ looks like:
+
+ static <type> guard;
+ if (!guard.first_byte) {
+ if (__cxa_guard_acquire (&guard)) {
+ bool flag = false;
+ try {
+ // Do initialization.
+ flag = true; __cxa_guard_release (&guard);
+ // Register variable for destruction at end of program.
+ } catch {
+ if (!flag) __cxa_guard_abort (&guard);
+ }
+ }
+
+ Note that the `flag' variable is only set to 1 *after* the
+ initialization is complete. This ensures that an exception,
+ thrown during the construction, will cause the variable to
+ reinitialized when we pass through this code again, as per:
+
+ [stmt.dcl]
+
+ If the initialization exits by throwing an exception, the
+ initialization is not complete, so it will be tried again
+ the next time control enters the declaration.
+
+ This process should be thread-safe, too; multiple threads
+ should not be able to initialize the variable more than
+ once. */
+
+ /* Create the guard variable. */
+ guard = get_guard (decl);
+
+ /* This optimization isn't safe on targets with relaxed memory
+ consistency. On such targets we force synchronization in
+ __cxa_guard_acquire. */
+ if (!targetm.relaxed_ordering || !thread_guard)
+ {
+ /* Begin the conditional initialization. */
+ if_stmt = begin_if_stmt ();
+ finish_if_stmt_cond (get_guard_cond (guard), if_stmt);
+ then_clause = begin_compound_stmt (BCS_NO_SCOPE);
+ }
+
+ if (thread_guard)
+ {
+ tree vfntype = NULL_TREE;
+ tree acquire_name, release_name, abort_name;
+ tree acquire_fn, release_fn, abort_fn;
+ guard_addr = build_address (guard);
+
+ acquire_name = get_identifier ("__cxa_guard_acquire");
+ release_name = get_identifier ("__cxa_guard_release");
+ abort_name = get_identifier ("__cxa_guard_abort");
+ acquire_fn = identifier_global_value (acquire_name);
+ release_fn = identifier_global_value (release_name);
+ abort_fn = identifier_global_value (abort_name);
+ if (!acquire_fn)
+ acquire_fn = push_library_fn
+ (acquire_name, build_function_type_list (integer_type_node,
+ TREE_TYPE (guard_addr),
+ NULL_TREE),
+ NULL_TREE, ECF_NOTHROW | ECF_LEAF);
+ if (!release_fn || !abort_fn)
+ vfntype = build_function_type_list (void_type_node,
+ TREE_TYPE (guard_addr),
+ NULL_TREE);
+ if (!release_fn)
+ release_fn = push_library_fn (release_name, vfntype, NULL_TREE,
+ ECF_NOTHROW | ECF_LEAF);
+ if (!abort_fn)
+ abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE,
+ ECF_NOTHROW | ECF_LEAF);
+
+ inner_if_stmt = begin_if_stmt ();
+ finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
+ inner_if_stmt);
+
+ inner_then_clause = begin_compound_stmt (BCS_NO_SCOPE);
+ begin = get_target_expr (boolean_false_node);
+ flag = TARGET_EXPR_SLOT (begin);
+
+ TARGET_EXPR_CLEANUP (begin)
+ = build3 (COND_EXPR, void_type_node, flag,
+ void_zero_node,
+ build_call_n (abort_fn, 1, guard_addr));
+ CLEANUP_EH_ONLY (begin) = 1;
+
+ /* Do the initialization itself. */
+ init = add_stmt_to_compound (begin, init);
+ init = add_stmt_to_compound
+ (init, build2 (MODIFY_EXPR, void_type_node, flag, boolean_true_node));
+ init = add_stmt_to_compound
+ (init, build_call_n (release_fn, 1, guard_addr));
+ }
+ else
+ init = add_stmt_to_compound (init, set_guard (guard));
+
+ /* Use atexit to register a function for destroying this static
+ variable. */
+ init = add_stmt_to_compound (init, register_dtor_fn (decl));
+
+ finish_expr_stmt (init);
+
+ if (thread_guard)
+ {
+ finish_compound_stmt (inner_then_clause);
+ finish_then_clause (inner_if_stmt);
+ finish_if_stmt (inner_if_stmt);
+ }
+
+ if (!targetm.relaxed_ordering || !thread_guard)
+ {
+ finish_compound_stmt (then_clause);
+ finish_then_clause (if_stmt);
+ finish_if_stmt (if_stmt);
+ }
+ }
+ else if (DECL_THREAD_LOCAL_P (decl))
+ tls_aggregates = tree_cons (init, decl, tls_aggregates);
+ else
+ static_aggregates = tree_cons (init, decl, static_aggregates);
+}
+
+
+/* Make TYPE a complete type based on INITIAL_VALUE.
+ Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
+ 2 if there was no information (in which case assume 0 if DO_DEFAULT),
+ 3 if the initializer list is empty (in pedantic mode). */
+
+int
+cp_complete_array_type (tree *ptype, tree initial_value, bool do_default)
+{
+ int failure;
+ tree type, elt_type;
+
+ /* Don't get confused by a CONSTRUCTOR for some other type. */
+ if (initial_value && TREE_CODE (initial_value) == CONSTRUCTOR
+ && !BRACE_ENCLOSED_INITIALIZER_P (initial_value))
+ return 1;
+
+ if (initial_value)
+ {
+ unsigned HOST_WIDE_INT i;
+ tree value;
+
+ /* An array of character type can be initialized from a
+ brace-enclosed string constant.
+
+ FIXME: this code is duplicated from reshape_init. Probably
+ we should just call reshape_init here? */
+ if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype)))
+ && TREE_CODE (initial_value) == CONSTRUCTOR
+ && !vec_safe_is_empty (CONSTRUCTOR_ELTS (initial_value)))
+ {
+ vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (initial_value);
+ tree value = (*v)[0].value;
+
+ if (TREE_CODE (value) == STRING_CST
+ && v->length () == 1)
+ initial_value = value;
+ }
+
+ /* If any of the elements are parameter packs, we can't actually
+ complete this type now because the array size is dependent. */
+ if (TREE_CODE (initial_value) == CONSTRUCTOR)
+ {
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (initial_value),
+ i, value)
+ {
+ if (PACK_EXPANSION_P (value))
+ return 0;
+ }
+ }
+ }
+
+ failure = complete_array_type (ptype, initial_value, do_default);
+
+ /* We can create the array before the element type is complete, which
+ means that we didn't have these two bits set in the original type
+ either. In completing the type, we are expected to propagate these
+ bits. See also complete_type which does the same thing for arrays
+ of fixed size. */
+ type = *ptype;
+ if (TYPE_DOMAIN (type))
+ {
+ elt_type = TREE_TYPE (type);
+ TYPE_NEEDS_CONSTRUCTING (type) = TYPE_NEEDS_CONSTRUCTING (elt_type);
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (elt_type);
+ }
+
+ return failure;
+}
+
+/* As above, but either give an error or reject zero-size arrays, depending
+ on COMPLAIN. */
+
+int
+cp_complete_array_type_or_error (tree *ptype, tree initial_value,
+ bool do_default, tsubst_flags_t complain)
+{
+ int failure;
+ bool sfinae = !(complain & tf_error);
+ /* In SFINAE context we can't be lenient about zero-size arrays. */
+ if (sfinae)
+ ++pedantic;
+ failure = cp_complete_array_type (ptype, initial_value, do_default);
+ if (sfinae)
+ --pedantic;
+ if (failure)
+ {
+ if (sfinae)
+ /* Not an error. */;
+ else if (failure == 1)
+ error ("initializer fails to determine size of %qT", *ptype);
+ else if (failure == 2)
+ {
+ if (do_default)
+ error ("array size missing in %qT", *ptype);
+ }
+ else if (failure == 3)
+ error ("zero-size array %qT", *ptype);
+ *ptype = error_mark_node;
+ }
+ return failure;
+}
+
+/* Return zero if something is declared to be a member of type
+ CTYPE when in the context of CUR_TYPE. STRING is the error
+ message to print in that case. Otherwise, quietly return 1. */
+
+static int
+member_function_or_else (tree ctype, tree cur_type, enum overload_flags flags)
+{
+ if (ctype && ctype != cur_type)
+ {
+ if (flags == DTOR_FLAG)
+ error ("destructor for alien class %qT cannot be a member", ctype);
+ else
+ error ("constructor for alien class %qT cannot be a member", ctype);
+ return 0;
+ }
+ return 1;
+}
+
+/* Subroutine of `grokdeclarator'. */
+
+/* Generate errors possibly applicable for a given set of specifiers.
+ This is for ARM $7.1.2. */
+
+static void
+bad_specifiers (tree object,
+ enum bad_spec_place type,
+ int virtualp,
+ int quals,
+ int inlinep,
+ int friendp,
+ int raises)
+{
+ switch (type)
+ {
+ case BSP_VAR:
+ if (virtualp)
+ error ("%qD declared as a %<virtual%> variable", object);
+ if (inlinep)
+ error ("%qD declared as an %<inline%> variable", object);
+ if (quals)
+ error ("%<const%> and %<volatile%> function specifiers on "
+ "%qD invalid in variable declaration", object);
+ break;
+ case BSP_PARM:
+ if (virtualp)
+ error ("%qD declared as a %<virtual%> parameter", object);
+ if (inlinep)
+ error ("%qD declared as an %<inline%> parameter", object);
+ if (quals)
+ error ("%<const%> and %<volatile%> function specifiers on "
+ "%qD invalid in parameter declaration", object);
+ break;
+ case BSP_TYPE:
+ if (virtualp)
+ error ("%qD declared as a %<virtual%> type", object);
+ if (inlinep)
+ error ("%qD declared as an %<inline%> type", object);
+ if (quals)
+ error ("%<const%> and %<volatile%> function specifiers on "
+ "%qD invalid in type declaration", object);
+ break;
+ case BSP_FIELD:
+ if (virtualp)
+ error ("%qD declared as a %<virtual%> field", object);
+ if (inlinep)
+ error ("%qD declared as an %<inline%> field", object);
+ if (quals)
+ error ("%<const%> and %<volatile%> function specifiers on "
+ "%qD invalid in field declaration", object);
+ break;
+ default:
+ gcc_unreachable();
+ }
+ if (friendp)
+ error ("%q+D declared as a friend", object);
+ if (raises
+ && (TREE_CODE (object) == TYPE_DECL
+ || (!TYPE_PTRFN_P (TREE_TYPE (object))
+ && !TYPE_REFFN_P (TREE_TYPE (object))
+ && !TYPE_PTRMEMFUNC_P (TREE_TYPE (object)))))
+ error ("%q+D declared with an exception specification", object);
+}
+
+/* DECL is a member function or static data member and is presently
+ being defined. Check that the definition is taking place in a
+ valid namespace. */
+
+static void
+check_class_member_definition_namespace (tree decl)
+{
+ /* These checks only apply to member functions and static data
+ members. */
+ gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
+ /* We check for problems with specializations in pt.c in
+ check_specialization_namespace, where we can issue better
+ diagnostics. */
+ if (processing_specialization)
+ return;
+ /* There are no restrictions on the placement of
+ explicit instantiations. */
+ if (processing_explicit_instantiation)
+ return;
+ /* [class.mfct]
+
+ A member function definition that appears outside of the
+ class definition shall appear in a namespace scope enclosing
+ the class definition.
+
+ [class.static.data]
+
+ The definition for a static data member shall appear in a
+ namespace scope enclosing the member's class definition. */
+ if (!is_ancestor (current_namespace, DECL_CONTEXT (decl)))
+ permerror (input_location, "definition of %qD is not in namespace enclosing %qT",
+ decl, DECL_CONTEXT (decl));
+}
+
+/* Build a PARM_DECL for the "this" parameter. TYPE is the
+ METHOD_TYPE for a non-static member function; QUALS are the
+ cv-qualifiers that apply to the function. */
+
+tree
+build_this_parm (tree type, cp_cv_quals quals)
+{
+ tree this_type;
+ tree qual_type;
+ tree parm;
+ cp_cv_quals this_quals;
+
+ if (CLASS_TYPE_P (type))
+ {
+ this_type
+ = cp_build_qualified_type (type, quals & ~TYPE_QUAL_RESTRICT);
+ this_type = build_pointer_type (this_type);
+ }
+ else
+ this_type = type_of_this_parm (type);
+ /* The `this' parameter is implicitly `const'; it cannot be
+ assigned to. */
+ this_quals = (quals & TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST;
+ qual_type = cp_build_qualified_type (this_type, this_quals);
+ parm = build_artificial_parm (this_identifier, qual_type);
+ cp_apply_type_quals_to_decl (this_quals, parm);
+ return parm;
+}
+
+/* DECL is a static member function. Complain if it was declared
+ with function-cv-quals. */
+
+static void
+check_static_quals (tree decl, cp_cv_quals quals)
+{
+ if (quals != TYPE_UNQUALIFIED)
+ error ("static member function %q#D declared with type qualifiers",
+ decl);
+}
+
+/* Helper function. Replace the temporary this parameter injected
+ during cp_finish_omp_declare_simd with the real this parameter. */
+
+static tree
+declare_simd_adjust_this (tree *tp, int *walk_subtrees, void *data)
+{
+ tree this_parm = (tree) data;
+ if (TREE_CODE (*tp) == PARM_DECL
+ && DECL_NAME (*tp) == this_identifier
+ && *tp != this_parm)
+ *tp = this_parm;
+ else if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ return NULL_TREE;
+}
+
+/* CTYPE is class type, or null if non-class.
+ TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
+ or METHOD_TYPE.
+ DECLARATOR is the function's name.
+ PARMS is a chain of PARM_DECLs for the function.
+ VIRTUALP is truthvalue of whether the function is virtual or not.
+ FLAGS are to be passed through to `grokclassfn'.
+ QUALS are qualifiers indicating whether the function is `const'
+ or `volatile'.
+ RAISES is a list of exceptions that this function can raise.
+ CHECK is 1 if we must find this method in CTYPE, 0 if we should
+ not look, and -1 if we should not call `grokclassfn' at all.
+
+ SFK is the kind of special function (if any) for the new function.
+
+ Returns `NULL_TREE' if something goes wrong, after issuing
+ applicable error messages. */
+
+static tree
+grokfndecl (tree ctype,
+ tree type,
+ tree declarator,
+ tree parms,
+ tree orig_declarator,
+ int virtualp,
+ enum overload_flags flags,
+ cp_cv_quals quals,
+ cp_ref_qualifier rqual,
+ tree raises,
+ int check,
+ int friendp,
+ int publicp,
+ int inlinep,
+ special_function_kind sfk,
+ bool funcdef_flag,
+ int template_count,
+ tree in_namespace,
+ tree* attrlist,
+ location_t location)
+{
+ tree decl;
+ int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
+ tree t;
+
+ if (rqual)
+ type = build_ref_qualified_type (type, rqual);
+ if (raises)
+ type = build_exception_variant (type, raises);
+
+ decl = build_lang_decl (FUNCTION_DECL, declarator, type);
+
+ /* If we have an explicit location, use it, otherwise use whatever
+ build_lang_decl used (probably input_location). */
+ if (location != UNKNOWN_LOCATION)
+ DECL_SOURCE_LOCATION (decl) = location;
+
+ if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ tree parm;
+ parm = build_this_parm (type, quals);
+ DECL_CHAIN (parm) = parms;
+ parms = parm;
+ }
+ DECL_ARGUMENTS (decl) = parms;
+ for (t = parms; t; t = DECL_CHAIN (t))
+ DECL_CONTEXT (t) = decl;
+ /* Propagate volatile out from type to decl. */
+ if (TYPE_VOLATILE (type))
+ TREE_THIS_VOLATILE (decl) = 1;
+
+ /* Setup decl according to sfk. */
+ switch (sfk)
+ {
+ case sfk_constructor:
+ case sfk_copy_constructor:
+ case sfk_move_constructor:
+ DECL_CONSTRUCTOR_P (decl) = 1;
+ break;
+ case sfk_destructor:
+ DECL_DESTRUCTOR_P (decl) = 1;
+ break;
+ default:
+ break;
+ }
+
+ /* If pointers to member functions use the least significant bit to
+ indicate whether a function is virtual, ensure a pointer
+ to this function will have that bit clear. */
+ if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+ && TREE_CODE (type) == METHOD_TYPE
+ && DECL_ALIGN (decl) < 2 * BITS_PER_UNIT)
+ DECL_ALIGN (decl) = 2 * BITS_PER_UNIT;
+
+ if (friendp
+ && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
+ {
+ if (funcdef_flag)
+ error
+ ("defining explicit specialization %qD in friend declaration",
+ orig_declarator);
+ else
+ {
+ tree fns = TREE_OPERAND (orig_declarator, 0);
+ tree args = TREE_OPERAND (orig_declarator, 1);
+
+ if (PROCESSING_REAL_TEMPLATE_DECL_P ())
+ {
+ /* Something like `template <class T> friend void f<T>()'. */
+ error ("invalid use of template-id %qD in declaration "
+ "of primary template",
+ orig_declarator);
+ return NULL_TREE;
+ }
+
+
+ /* A friend declaration of the form friend void f<>(). Record
+ the information in the TEMPLATE_ID_EXPR. */
+ SET_DECL_IMPLICIT_INSTANTIATION (decl);
+
+ gcc_assert (identifier_p (fns) || TREE_CODE (fns) == OVERLOAD);
+ DECL_TEMPLATE_INFO (decl) = build_template_info (fns, args);
+
+ for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
+ if (TREE_PURPOSE (t)
+ && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
+ {
+ error ("default arguments are not allowed in declaration "
+ "of friend template specialization %qD",
+ decl);
+ return NULL_TREE;
+ }
+
+ if (inlinep & 1)
+ error ("%<inline%> is not allowed in declaration of friend "
+ "template specialization %qD",
+ decl);
+ if (inlinep & 2)
+ error ("%<constexpr%> is not allowed in declaration of friend "
+ "template specialization %qD",
+ decl);
+ if (inlinep)
+ return NULL_TREE;
+ }
+ }
+
+ /* If this decl has namespace scope, set that up. */
+ if (in_namespace)
+ set_decl_namespace (decl, in_namespace, friendp);
+ else if (!ctype)
+ DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ());
+
+ /* `main' and builtins have implicit 'C' linkage. */
+ if ((MAIN_NAME_P (declarator)
+ || (IDENTIFIER_LENGTH (declarator) > 10
+ && IDENTIFIER_POINTER (declarator)[0] == '_'
+ && IDENTIFIER_POINTER (declarator)[1] == '_'
+ && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0)
+ || (targetcm.cxx_implicit_extern_c
+ && targetcm.cxx_implicit_extern_c(IDENTIFIER_POINTER (declarator))))
+ && current_lang_name == lang_name_cplusplus
+ && ctype == NULL_TREE
+ && DECL_FILE_SCOPE_P (decl))
+ SET_DECL_LANGUAGE (decl, lang_c);
+
+ /* Should probably propagate const out from type to decl I bet (mrs). */
+ if (staticp)
+ {
+ DECL_STATIC_FUNCTION_P (decl) = 1;
+ DECL_CONTEXT (decl) = ctype;
+ }
+
+ if (ctype)
+ {
+ DECL_CONTEXT (decl) = ctype;
+ if (funcdef_flag)
+ check_class_member_definition_namespace (decl);
+ }
+
+ if (ctype == NULL_TREE && DECL_MAIN_P (decl))
+ {
+ if (PROCESSING_REAL_TEMPLATE_DECL_P())
+ error ("cannot declare %<::main%> to be a template");
+ if (inlinep & 1)
+ error ("cannot declare %<::main%> to be inline");
+ if (inlinep & 2)
+ error ("cannot declare %<::main%> to be constexpr");
+ if (!publicp)
+ error ("cannot declare %<::main%> to be static");
+ inlinep = 0;
+ publicp = 1;
+ }
+
+ /* Members of anonymous types and local classes have no linkage; make
+ them internal. If a typedef is made later, this will be changed. */
+ if (ctype && (TYPE_ANONYMOUS_P (ctype)
+ || decl_function_context (TYPE_MAIN_DECL (ctype))))
+ publicp = 0;
+
+ if (publicp && cxx_dialect == cxx98)
+ {
+ /* [basic.link]: A name with no linkage (notably, the name of a class
+ or enumeration declared in a local scope) shall not be used to
+ declare an entity with linkage.
+
+ DR 757 relaxes this restriction for C++0x. */
+ no_linkage_error (decl);
+ }
+
+ TREE_PUBLIC (decl) = publicp;
+ if (! publicp)
+ {
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ DECL_NOT_REALLY_EXTERN (decl) = 1;
+ }
+
+ /* If the declaration was declared inline, mark it as such. */
+ if (inlinep)
+ DECL_DECLARED_INLINE_P (decl) = 1;
+ if (inlinep & 2)
+ DECL_DECLARED_CONSTEXPR_P (decl) = true;
+
+ DECL_EXTERNAL (decl) = 1;
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ if (quals)
+ {
+ error (ctype
+ ? G_("static member function %qD cannot have cv-qualifier")
+ : G_("non-member function %qD cannot have cv-qualifier"),
+ decl);
+ quals = TYPE_UNQUALIFIED;
+ }
+
+ if (rqual)
+ {
+ error (ctype
+ ? G_("static member function %qD cannot have ref-qualifier")
+ : G_("non-member function %qD cannot have ref-qualifier"),
+ decl);
+ rqual = REF_QUAL_NONE;
+ }
+ }
+
+ if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))
+ && !grok_op_properties (decl, /*complain=*/true))
+ return NULL_TREE;
+ else if (UDLIT_OPER_P (DECL_NAME (decl)))
+ {
+ bool long_long_unsigned_p;
+ bool long_double_p;
+ const char *suffix = NULL;
+ /* [over.literal]/6: Literal operators shall not have C linkage. */
+ if (DECL_LANGUAGE (decl) == lang_c)
+ {
+ error ("literal operator with C linkage");
+ return NULL_TREE;
+ }
+
+ if (DECL_NAMESPACE_SCOPE_P (decl))
+ {
+ if (!check_literal_operator_args (decl, &long_long_unsigned_p,
+ &long_double_p))
+ {
+ error ("%qD has invalid argument list", decl);
+ return NULL_TREE;
+ }
+
+ suffix = UDLIT_OP_SUFFIX (DECL_NAME (decl));
+ if (long_long_unsigned_p)
+ {
+ if (cpp_interpret_int_suffix (parse_in, suffix, strlen (suffix)))
+ warning (0, "integer suffix %<%s%>"
+ " shadowed by implementation", suffix);
+ }
+ else if (long_double_p)
+ {
+ if (cpp_interpret_float_suffix (parse_in, suffix, strlen (suffix)))
+ warning (0, "floating point suffix %<%s%>"
+ " shadowed by implementation", suffix);
+ }
+ }
+ else
+ {
+ error ("%qD must be a non-member function", decl);
+ return NULL_TREE;
+ }
+ }
+
+ if (funcdef_flag)
+ /* Make the init_value nonzero so pushdecl knows this is not
+ tentative. error_mark_node is replaced later with the BLOCK. */
+ DECL_INITIAL (decl) = error_mark_node;
+
+ if (TYPE_NOTHROW_P (type) || nothrow_libfn_p (decl))
+ TREE_NOTHROW (decl) = 1;
+
+ if (flag_openmp || flag_cilkplus)
+ {
+ /* Adjust "omp declare simd" attributes. */
+ tree ods = lookup_attribute ("omp declare simd", *attrlist);
+ if (ods)
+ {
+ tree attr;
+ for (attr = ods; attr;
+ attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr)))
+ {
+ if (TREE_CODE (type) == METHOD_TYPE)
+ walk_tree (&TREE_VALUE (attr), declare_simd_adjust_this,
+ DECL_ARGUMENTS (decl), NULL);
+ if (TREE_VALUE (attr) != NULL_TREE)
+ {
+ tree cl = TREE_VALUE (TREE_VALUE (attr));
+ cl = c_omp_declare_simd_clauses_to_numbers
+ (DECL_ARGUMENTS (decl), cl);
+ if (cl)
+ TREE_VALUE (TREE_VALUE (attr)) = cl;
+ else
+ TREE_VALUE (attr) = NULL_TREE;
+ }
+ }
+ }
+ }
+
+ /* Caller will do the rest of this. */
+ if (check < 0)
+ return decl;
+
+ if (ctype != NULL_TREE)
+ grokclassfn (ctype, decl, flags);
+
+ /* 12.4/3 */
+ if (cxx_dialect >= cxx11
+ && DECL_DESTRUCTOR_P (decl)
+ && !TYPE_BEING_DEFINED (DECL_CONTEXT (decl))
+ && !processing_template_decl)
+ deduce_noexcept_on_destructor (decl);
+
+ decl = check_explicit_specialization (orig_declarator, decl,
+ template_count,
+ 2 * funcdef_flag +
+ 4 * (friendp != 0));
+ if (decl == error_mark_node)
+ return NULL_TREE;
+
+ if (DECL_STATIC_FUNCTION_P (decl))
+ check_static_quals (decl, quals);
+
+ if (attrlist)
+ {
+ cplus_decl_attributes (&decl, *attrlist, 0);
+ *attrlist = NULL_TREE;
+ }
+
+ /* Check main's type after attributes have been applied. */
+ if (ctype == NULL_TREE && DECL_MAIN_P (decl))
+ {
+ if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),
+ integer_type_node))
+ {
+ tree oldtypeargs = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ tree newtype;
+ error ("%<::main%> must return %<int%>");
+ newtype = build_function_type (integer_type_node, oldtypeargs);
+ TREE_TYPE (decl) = newtype;
+ }
+ if (warn_main)
+ check_main_parameter_types (decl);
+ }
+
+ if (ctype != NULL_TREE
+ && (! TYPE_FOR_JAVA (ctype) || check_java_method (decl))
+ && check)
+ {
+ tree old_decl = check_classfn (ctype, decl,
+ (processing_template_decl
+ > template_class_depth (ctype))
+ ? current_template_parms
+ : NULL_TREE);
+
+ if (old_decl == error_mark_node)
+ return NULL_TREE;
+
+ if (old_decl)
+ {
+ tree ok;
+ tree pushed_scope;
+
+ if (TREE_CODE (old_decl) == TEMPLATE_DECL)
+ /* Because grokfndecl is always supposed to return a
+ FUNCTION_DECL, we pull out the DECL_TEMPLATE_RESULT
+ here. We depend on our callers to figure out that its
+ really a template that's being returned. */
+ old_decl = DECL_TEMPLATE_RESULT (old_decl);
+
+ if (DECL_STATIC_FUNCTION_P (old_decl)
+ && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
+ {
+ /* Remove the `this' parm added by grokclassfn. */
+ revert_static_member_fn (decl);
+ check_static_quals (decl, quals);
+ }
+ if (DECL_ARTIFICIAL (old_decl))
+ {
+ error ("definition of implicitly-declared %qD", old_decl);
+ return NULL_TREE;
+ }
+ else if (DECL_DEFAULTED_FN (old_decl))
+ {
+ error ("definition of explicitly-defaulted %q+D", decl);
+ error ("%q+#D explicitly defaulted here", old_decl);
+ return NULL_TREE;
+ }
+
+ /* Since we've smashed OLD_DECL to its
+ DECL_TEMPLATE_RESULT, we must do the same to DECL. */
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ decl = DECL_TEMPLATE_RESULT (decl);
+
+ /* Attempt to merge the declarations. This can fail, in
+ the case of some invalid specialization declarations. */
+ pushed_scope = push_scope (ctype);
+ ok = duplicate_decls (decl, old_decl, friendp);
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ if (!ok)
+ {
+ error ("no %q#D member function declared in class %qT",
+ decl, ctype);
+ return NULL_TREE;
+ }
+ return old_decl;
+ }
+ }
+
+ if (DECL_CONSTRUCTOR_P (decl) && !grok_ctor_properties (ctype, decl))
+ return NULL_TREE;
+
+ if (ctype == NULL_TREE || check)
+ return decl;
+
+ if (virtualp)
+ DECL_VIRTUAL_P (decl) = 1;
+
+ return decl;
+}
+
+/* decl is a FUNCTION_DECL.
+ specifiers are the parsed virt-specifiers.
+
+ Set flags to reflect the virt-specifiers.
+
+ Returns decl. */
+
+static tree
+set_virt_specifiers (tree decl, cp_virt_specifiers specifiers)
+{
+ if (decl == NULL_TREE)
+ return decl;
+ if (specifiers & VIRT_SPEC_OVERRIDE)
+ DECL_OVERRIDE_P (decl) = 1;
+ if (specifiers & VIRT_SPEC_FINAL)
+ DECL_FINAL_P (decl) = 1;
+ return decl;
+}
+
+/* DECL is a VAR_DECL for a static data member. Set flags to reflect
+ the linkage that DECL will receive in the object file. */
+
+static void
+set_linkage_for_static_data_member (tree decl)
+{
+ /* A static data member always has static storage duration and
+ external linkage. Note that static data members are forbidden in
+ local classes -- the only situation in which a class has
+ non-external linkage. */
+ TREE_PUBLIC (decl) = 1;
+ TREE_STATIC (decl) = 1;
+ /* For non-template classes, static data members are always put
+ out in exactly those files where they are defined, just as
+ with ordinary namespace-scope variables. */
+ if (!processing_template_decl)
+ DECL_INTERFACE_KNOWN (decl) = 1;
+}
+
+/* Create a VAR_DECL named NAME with the indicated TYPE.
+
+ If SCOPE is non-NULL, it is the class type or namespace containing
+ the variable. If SCOPE is NULL, the variable should is created in
+ the innermost enclosing scope. */
+
+static tree
+grokvardecl (tree type,
+ tree name,
+ const cp_decl_specifier_seq *declspecs,
+ int initialized,
+ int constp,
+ tree scope)
+{
+ tree decl;
+ tree explicit_scope;
+
+ gcc_assert (!name || identifier_p (name));
+
+ /* Compute the scope in which to place the variable, but remember
+ whether or not that scope was explicitly specified by the user. */
+ explicit_scope = scope;
+ if (!scope)
+ {
+ /* An explicit "extern" specifier indicates a namespace-scope
+ variable. */
+ if (declspecs->storage_class == sc_extern)
+ scope = current_decl_namespace ();
+ else if (!at_function_scope_p ())
+ scope = current_scope ();
+ }
+
+ if (scope
+ && (/* If the variable is a namespace-scope variable declared in a
+ template, we need DECL_LANG_SPECIFIC. */
+ (TREE_CODE (scope) == NAMESPACE_DECL && processing_template_decl)
+ /* Similarly for namespace-scope variables with language linkage
+ other than C++. */
+ || (TREE_CODE (scope) == NAMESPACE_DECL
+ && current_lang_name != lang_name_cplusplus)
+ /* Similarly for static data members. */
+ || TYPE_P (scope)))
+ decl = build_lang_decl (VAR_DECL, name, type);
+ else
+ decl = build_decl (input_location, VAR_DECL, name, type);
+
+ if (explicit_scope && TREE_CODE (explicit_scope) == NAMESPACE_DECL)
+ set_decl_namespace (decl, explicit_scope, 0);
+ else
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
+
+ if (declspecs->storage_class == sc_extern)
+ {
+ DECL_THIS_EXTERN (decl) = 1;
+ DECL_EXTERNAL (decl) = !initialized;
+ }
+
+ if (DECL_CLASS_SCOPE_P (decl))
+ {
+ set_linkage_for_static_data_member (decl);
+ /* This function is only called with out-of-class definitions. */
+ DECL_EXTERNAL (decl) = 0;
+ check_class_member_definition_namespace (decl);
+ }
+ /* At top level, either `static' or no s.c. makes a definition
+ (perhaps tentative), and absence of `static' makes it public. */
+ else if (toplevel_bindings_p ())
+ {
+ TREE_PUBLIC (decl) = (declspecs->storage_class != sc_static
+ && (DECL_THIS_EXTERN (decl) || ! constp));
+ TREE_STATIC (decl) = ! DECL_EXTERNAL (decl);
+ }
+ /* Not at top level, only `static' makes a static definition. */
+ else
+ {
+ TREE_STATIC (decl) = declspecs->storage_class == sc_static;
+ TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
+ }
+
+ if (decl_spec_seq_has_spec_p (declspecs, ds_thread))
+ {
+ DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+ if (declspecs->gnu_thread_keyword_p)
+ DECL_GNU_TLS_P (decl) = true;
+ }
+
+ /* If the type of the decl has no linkage, make sure that we'll
+ notice that in mark_used. */
+ if (cxx_dialect > cxx98
+ && decl_linkage (decl) != lk_none
+ && DECL_LANG_SPECIFIC (decl) == NULL
+ && !DECL_EXTERN_C_P (decl)
+ && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false))
+ retrofit_lang_decl (decl);
+
+ if (TREE_PUBLIC (decl))
+ {
+ /* [basic.link]: A name with no linkage (notably, the name of a class
+ or enumeration declared in a local scope) shall not be used to
+ declare an entity with linkage.
+
+ DR 757 relaxes this restriction for C++0x. */
+ if (cxx_dialect < cxx11)
+ no_linkage_error (decl);
+ }
+ else
+ DECL_INTERFACE_KNOWN (decl) = 1;
+
+ return decl;
+}
+
+/* Create and return a canonical pointer to member function type, for
+ TYPE, which is a POINTER_TYPE to a METHOD_TYPE. */
+
+tree
+build_ptrmemfunc_type (tree type)
+{
+ tree field, fields;
+ tree t;
+ tree unqualified_variant = NULL_TREE;
+
+ if (type == error_mark_node)
+ return type;
+
+ /* If a canonical type already exists for this type, use it. We use
+ this method instead of type_hash_canon, because it only does a
+ simple equality check on the list of field members. */
+
+ if ((t = TYPE_GET_PTRMEMFUNC_TYPE (type)))
+ return t;
+
+ /* Make sure that we always have the unqualified pointer-to-member
+ type first. */
+ if (cp_type_quals (type) != TYPE_UNQUALIFIED)
+ unqualified_variant
+ = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type));
+
+ t = make_class_type (RECORD_TYPE);
+ xref_basetypes (t, NULL_TREE);
+
+ /* Let the front end know this is a pointer to member function... */
+ TYPE_PTRMEMFUNC_FLAG (t) = 1;
+ /* ... and not really a class type. */
+ SET_CLASS_TYPE_P (t, 0);
+
+ field = build_decl (input_location, FIELD_DECL, pfn_identifier, type);
+ fields = field;
+
+ field = build_decl (input_location, FIELD_DECL, delta_identifier,
+ delta_type_node);
+ DECL_CHAIN (field) = fields;
+ fields = field;
+
+ finish_builtin_struct (t, "__ptrmemfunc_type", fields, ptr_type_node);
+
+ /* Zap out the name so that the back end will give us the debugging
+ information for this anonymous RECORD_TYPE. */
+ TYPE_NAME (t) = NULL_TREE;
+
+ /* If this is not the unqualified form of this pointer-to-member
+ type, set the TYPE_MAIN_VARIANT for this type to be the
+ unqualified type. Since they are actually RECORD_TYPEs that are
+ not variants of each other, we must do this manually.
+ As we just built a new type there is no need to do yet another copy. */
+ if (cp_type_quals (type) != TYPE_UNQUALIFIED)
+ {
+ int type_quals = cp_type_quals (type);
+ TYPE_READONLY (t) = (type_quals & TYPE_QUAL_CONST) != 0;
+ TYPE_VOLATILE (t) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
+ TYPE_RESTRICT (t) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
+ TYPE_MAIN_VARIANT (t) = unqualified_variant;
+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (unqualified_variant);
+ TYPE_NEXT_VARIANT (unqualified_variant) = t;
+ TREE_TYPE (TYPE_BINFO (t)) = t;
+ }
+
+ /* Cache this pointer-to-member type so that we can find it again
+ later. */
+ TYPE_SET_PTRMEMFUNC_TYPE (type, t);
+
+ if (TYPE_STRUCTURAL_EQUALITY_P (type))
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else if (TYPE_CANONICAL (type) != type)
+ TYPE_CANONICAL (t) = build_ptrmemfunc_type (TYPE_CANONICAL (type));
+
+ return t;
+}
+
+/* Create and return a pointer to data member type. */
+
+tree
+build_ptrmem_type (tree class_type, tree member_type)
+{
+ if (TREE_CODE (member_type) == METHOD_TYPE)
+ {
+ cp_cv_quals quals = type_memfn_quals (member_type);
+ cp_ref_qualifier rqual = type_memfn_rqual (member_type);
+ member_type = build_memfn_type (member_type, class_type, quals, rqual);
+ return build_ptrmemfunc_type (build_pointer_type (member_type));
+ }
+ else
+ {
+ gcc_assert (TREE_CODE (member_type) != FUNCTION_TYPE);
+ return build_offset_type (class_type, member_type);
+ }
+}
+
+/* DECL is a VAR_DECL defined in-class, whose TYPE is also given.
+ Check to see that the definition is valid. Issue appropriate error
+ messages. Return 1 if the definition is particularly bad, or 0
+ otherwise. */
+
+static int
+check_static_variable_definition (tree decl, tree type)
+{
+ /* Can't check yet if we don't know the type. */
+ if (dependent_type_p (type))
+ return 0;
+ /* If DECL is declared constexpr, we'll do the appropriate checks
+ in check_initializer. */
+ if (DECL_P (decl) && DECL_DECLARED_CONSTEXPR_P (decl))
+ return 0;
+ else if (cxx_dialect >= cxx11 && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ {
+ if (!COMPLETE_TYPE_P (type))
+ error ("in-class initialization of static data member %q#D of "
+ "incomplete type", decl);
+ else if (literal_type_p (type))
+ permerror (input_location,
+ "%<constexpr%> needed for in-class initialization of "
+ "static data member %q#D of non-integral type", decl);
+ else
+ error ("in-class initialization of static data member %q#D of "
+ "non-literal type", decl);
+ return 1;
+ }
+
+ /* Motion 10 at San Diego: If a static const integral data member is
+ initialized with an integral constant expression, the initializer
+ may appear either in the declaration (within the class), or in
+ the definition, but not both. If it appears in the class, the
+ member is a member constant. The file-scope definition is always
+ required. */
+ if (!ARITHMETIC_TYPE_P (type) && TREE_CODE (type) != ENUMERAL_TYPE)
+ {
+ error ("invalid in-class initialization of static data member "
+ "of non-integral type %qT",
+ type);
+ return 1;
+ }
+ else if (!CP_TYPE_CONST_P (type))
+ error ("ISO C++ forbids in-class initialization of non-const "
+ "static member %qD",
+ decl);
+ else if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids initialization of member constant "
+ "%qD of non-integral type %qT", decl, type);
+
+ return 0;
+}
+
+/* *expr_p is part of the TYPE_SIZE of a variably-sized array. If any
+ SAVE_EXPRs in *expr_p wrap expressions with side-effects, break those
+ expressions out into temporary variables so that walk_tree doesn't
+ step into them (c++/15764). */
+
+static tree
+stabilize_save_expr_r (tree *expr_p, int *walk_subtrees, void *data)
+{
+ struct pointer_set_t *pset = (struct pointer_set_t *)data;
+ tree expr = *expr_p;
+ if (TREE_CODE (expr) == SAVE_EXPR)
+ {
+ tree op = TREE_OPERAND (expr, 0);
+ cp_walk_tree (&op, stabilize_save_expr_r, data, pset);
+ if (TREE_SIDE_EFFECTS (op))
+ TREE_OPERAND (expr, 0) = get_temp_regvar (TREE_TYPE (op), op);
+ *walk_subtrees = 0;
+ }
+ else if (!EXPR_P (expr) || !TREE_SIDE_EFFECTS (expr))
+ *walk_subtrees = 0;
+ return NULL;
+}
+
+/* Entry point for the above. */
+
+static void
+stabilize_vla_size (tree size)
+{
+ struct pointer_set_t *pset = pointer_set_create ();
+ /* Break out any function calls into temporary variables. */
+ cp_walk_tree (&size, stabilize_save_expr_r, pset, pset);
+ pointer_set_destroy (pset);
+}
+
+/* Helper function for compute_array_index_type. Look for SIZEOF_EXPR
+ not inside of SAVE_EXPR and fold them. */
+
+static tree
+fold_sizeof_expr_r (tree *expr_p, int *walk_subtrees, void *data)
+{
+ tree expr = *expr_p;
+ if (TREE_CODE (expr) == SAVE_EXPR || TYPE_P (expr))
+ *walk_subtrees = 0;
+ else if (TREE_CODE (expr) == SIZEOF_EXPR)
+ {
+ *(bool *)data = true;
+ if (SIZEOF_EXPR_TYPE_P (expr))
+ expr = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (expr, 0)),
+ SIZEOF_EXPR, false);
+ else if (TYPE_P (TREE_OPERAND (expr, 0)))
+ expr = cxx_sizeof_or_alignof_type (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
+ false);
+ else
+ expr = cxx_sizeof_or_alignof_expr (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
+ false);
+ if (expr == error_mark_node)
+ expr = size_one_node;
+ *expr_p = expr;
+ *walk_subtrees = 0;
+ }
+ return NULL;
+}
+
+/* Given the SIZE (i.e., number of elements) in an array, compute an
+ appropriate index type for the array. If non-NULL, NAME is the
+ name of the thing being declared. */
+
+tree
+compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
+{
+ tree itype;
+ tree osize = size;
+ tree abi_1_itype = NULL_TREE;
+
+ if (error_operand_p (size))
+ return error_mark_node;
+
+ if (!type_dependent_expression_p (size))
+ {
+ tree type = TREE_TYPE (size);
+
+ mark_rvalue_use (size);
+
+ if (cxx_dialect < cxx11 && TREE_CODE (size) == NOP_EXPR
+ && TREE_SIDE_EFFECTS (size))
+ /* In C++98, we mark a non-constant array bound with a magic
+ NOP_EXPR with TREE_SIDE_EFFECTS; don't fold in that case. */;
+ else
+ {
+ size = fold_non_dependent_expr_sfinae (size, complain);
+
+ if (CLASS_TYPE_P (type)
+ && CLASSTYPE_LITERAL_P (type))
+ {
+ size = build_expr_type_conversion (WANT_INT, size, true);
+ if (!size)
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+ if (name)
+ error ("size of array %qD has non-integral type %qT",
+ name, type);
+ else
+ error ("size of array has non-integral type %qT", type);
+ size = integer_one_node;
+ }
+ if (size == error_mark_node)
+ return error_mark_node;
+ type = TREE_TYPE (size);
+ /* We didn't support this case in GCC 3.2, so don't bother
+ trying to model it now in ABI v1. */
+ abi_1_itype = error_mark_node;
+ }
+
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+ size = maybe_constant_value (size);
+
+ if (!TREE_CONSTANT (size))
+ size = osize;
+ }
+
+ if (error_operand_p (size))
+ return error_mark_node;
+
+ /* The array bound must be an integer type. */
+ if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+ if (name)
+ error ("size of array %qD has non-integral type %qT", name, type);
+ else
+ error ("size of array has non-integral type %qT", type);
+ size = integer_one_node;
+ type = TREE_TYPE (size);
+ }
+ }
+
+ /* A type is dependent if it is...an array type constructed from any
+ dependent type or whose size is specified by a constant expression
+ that is value-dependent. */
+ /* We can only call value_dependent_expression_p on integral constant
+ expressions; treat non-constant expressions as dependent, too. */
+ if (processing_template_decl
+ && (type_dependent_expression_p (size)
+ || !TREE_CONSTANT (size) || value_dependent_expression_p (size)))
+ {
+ /* We cannot do any checking for a SIZE that isn't known to be
+ constant. Just build the index type and mark that it requires
+ structural equality checks. */
+ itype = build_index_type (build_min (MINUS_EXPR, sizetype,
+ size, size_one_node));
+ TYPE_DEPENDENT_P (itype) = 1;
+ TYPE_DEPENDENT_P_VALID (itype) = 1;
+ SET_TYPE_STRUCTURAL_EQUALITY (itype);
+ return itype;
+ }
+
+ if (!abi_version_at_least (2) && processing_template_decl
+ && abi_1_itype == NULL_TREE)
+ /* For abi-1, we handled all instances in templates the same way,
+ even when they were non-dependent. This affects the manglings
+ produced. So, we do the normal checking for non-dependent
+ sizes, but at the end we'll return the same type that abi-1
+ would have, but with TYPE_CANONICAL set to the "right"
+ value that the current ABI would provide. */
+ abi_1_itype = build_index_type (build_min (MINUS_EXPR, sizetype,
+ osize, integer_one_node));
+
+ /* Normally, the array-bound will be a constant. */
+ if (TREE_CODE (size) == INTEGER_CST)
+ {
+ /* Check to see if the array bound overflowed. Make that an
+ error, no matter how generous we're being. */
+ constant_expression_error (size);
+
+ /* An array must have a positive number of elements. */
+ if (INT_CST_LT (size, integer_zero_node))
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+ if (name)
+ error ("size of array %qD is negative", name);
+ else
+ error ("size of array is negative");
+ size = integer_one_node;
+ }
+ /* As an extension we allow zero-sized arrays. */
+ else if (integer_zerop (size))
+ {
+ if (!(complain & tf_error))
+ /* We must fail if performing argument deduction (as
+ indicated by the state of complain), so that
+ another substitution can be found. */
+ return error_mark_node;
+ else if (in_system_header_at (input_location))
+ /* Allow them in system headers because glibc uses them. */;
+ else if (name)
+ pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array %qD", name);
+ else
+ pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array");
+ }
+ }
+ else if (TREE_CONSTANT (size)
+ /* We don't allow VLAs at non-function scopes, or during
+ tentative template substitution. */
+ || !at_function_scope_p ()
+ || (cxx_dialect < cxx1y && !(complain & tf_error)))
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+ /* `(int) &fn' is not a valid array bound. */
+ if (name)
+ error ("size of array %qD is not an integral constant-expression",
+ name);
+ else
+ error ("size of array is not an integral constant-expression");
+ size = integer_one_node;
+ }
+ else if (cxx_dialect < cxx1y && pedantic && warn_vla != 0)
+ {
+ if (name)
+ pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
+ else
+ pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array");
+ }
+ else if (warn_vla > 0)
+ {
+ if (name)
+ warning (OPT_Wvla,
+ "variable length array %qD is used", name);
+ else
+ warning (OPT_Wvla,
+ "variable length array is used");
+ }
+
+ if (processing_template_decl && !TREE_CONSTANT (size))
+ /* A variable sized array. */
+ itype = build_min (MINUS_EXPR, sizetype, size, integer_one_node);
+ else
+ {
+ HOST_WIDE_INT saved_processing_template_decl;
+
+ /* Compute the index of the largest element in the array. It is
+ one less than the number of elements in the array. We save
+ and restore PROCESSING_TEMPLATE_DECL so that computations in
+ cp_build_binary_op will be appropriately folded. */
+ saved_processing_template_decl = processing_template_decl;
+ processing_template_decl = 0;
+ itype = cp_build_binary_op (input_location,
+ MINUS_EXPR,
+ cp_convert (ssizetype, size, complain),
+ cp_convert (ssizetype, integer_one_node,
+ complain),
+ complain);
+ itype = fold (itype);
+ processing_template_decl = saved_processing_template_decl;
+
+ if (!TREE_CONSTANT (itype))
+ {
+ /* A variable sized array. */
+ itype = variable_size (itype);
+
+ if (TREE_CODE (itype) != SAVE_EXPR)
+ {
+ /* Look for SIZEOF_EXPRs in itype and fold them, otherwise
+ they might survive till gimplification. */
+ tree newitype = itype;
+ bool found = false;
+ cp_walk_tree_without_duplicates (&newitype,
+ fold_sizeof_expr_r, &found);
+ if (found)
+ itype = variable_size (fold (newitype));
+ }
+
+ stabilize_vla_size (itype);
+
+ if (cxx_dialect >= cxx1y && flag_exceptions)
+ {
+ /* If the VLA bound is larger than half the address space,
+ or less than zero, throw std::bad_array_length. */
+ tree comp = build2 (LT_EXPR, boolean_type_node, itype,
+ ssize_int (-1));
+ comp = build3 (COND_EXPR, void_type_node, comp,
+ throw_bad_array_length (), void_zero_node);
+ finish_expr_stmt (comp);
+ }
+ else if (flag_sanitize & SANITIZE_VLA)
+ {
+ /* From C++1y onwards, we throw an exception on a negative
+ length size of an array; see above. */
+
+ /* We have to add 1 -- in the ubsan routine we generate
+ LE_EXPR rather than LT_EXPR. */
+ tree t = fold_build2 (PLUS_EXPR, TREE_TYPE (itype), itype,
+ build_one_cst (TREE_TYPE (itype)));
+ t = ubsan_instrument_vla (input_location, t);
+ finish_expr_stmt (t);
+ }
+ }
+ /* Make sure that there was no overflow when creating to a signed
+ index type. (For example, on a 32-bit machine, an array with
+ size 2^32 - 1 is too big.) */
+ else if (TREE_CODE (itype) == INTEGER_CST
+ && TREE_OVERFLOW (itype))
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+ error ("overflow in array dimension");
+ TREE_OVERFLOW (itype) = 0;
+ }
+ }
+
+ /* Create and return the appropriate index type. */
+ if (abi_1_itype && abi_1_itype != error_mark_node)
+ {
+ tree t = build_index_type (itype);
+ TYPE_CANONICAL (abi_1_itype) = TYPE_CANONICAL (t);
+ itype = abi_1_itype;
+ }
+ else
+ itype = build_index_type (itype);
+
+ /* If the index type were dependent, we would have returned early, so
+ remember that it isn't. */
+ TYPE_DEPENDENT_P (itype) = 0;
+ TYPE_DEPENDENT_P_VALID (itype) = 1;
+ return itype;
+}
+
+/* Returns the scope (if any) in which the entity declared by
+ DECLARATOR will be located. If the entity was declared with an
+ unqualified name, NULL_TREE is returned. */
+
+tree
+get_scope_of_declarator (const cp_declarator *declarator)
+{
+ while (declarator && declarator->kind != cdk_id)
+ declarator = declarator->declarator;
+
+ /* If the declarator-id is a SCOPE_REF, the scope in which the
+ declaration occurs is the first operand. */
+ if (declarator
+ && declarator->u.id.qualifying_scope)
+ return declarator->u.id.qualifying_scope;
+
+ /* Otherwise, the declarator is not a qualified name; the entity will
+ be declared in the current scope. */
+ return NULL_TREE;
+}
+
+/* Returns an ARRAY_TYPE for an array with SIZE elements of the
+ indicated TYPE. If non-NULL, NAME is the NAME of the declaration
+ with this type. */
+
+static tree
+create_array_type_for_decl (tree name, tree type, tree size)
+{
+ tree itype = NULL_TREE;
+
+ /* If things have already gone awry, bail now. */
+ if (type == error_mark_node || size == error_mark_node)
+ return error_mark_node;
+
+ /* 8.3.4/1: If the type of the identifier of D contains the auto
+ type-specifier, the program is ill-formed. */
+ if (pedantic && type_uses_auto (type))
+ pedwarn (input_location, OPT_Wpedantic,
+ "declaration of %qD as array of %<auto%>", name);
+
+ /* If there are some types which cannot be array elements,
+ issue an error-message and return. */
+ switch (TREE_CODE (type))
+ {
+ case VOID_TYPE:
+ if (name)
+ error ("declaration of %qD as array of void", name);
+ else
+ error ("creating array of void");
+ return error_mark_node;
+
+ case FUNCTION_TYPE:
+ if (name)
+ error ("declaration of %qD as array of functions", name);
+ else
+ error ("creating array of functions");
+ return error_mark_node;
+
+ case REFERENCE_TYPE:
+ if (name)
+ error ("declaration of %qD as array of references", name);
+ else
+ error ("creating array of references");
+ return error_mark_node;
+
+ case METHOD_TYPE:
+ if (name)
+ error ("declaration of %qD as array of function members", name);
+ else
+ error ("creating array of function members");
+ return error_mark_node;
+
+ default:
+ break;
+ }
+
+ /* [dcl.array]
+
+ The constant expressions that specify the bounds of the arrays
+ can be omitted only for the first member of the sequence. */
+ if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
+ {
+ if (name)
+ error ("declaration of %qD as multidimensional array must "
+ "have bounds for all dimensions except the first",
+ name);
+ else
+ error ("multidimensional array must have bounds for all "
+ "dimensions except the first");
+
+ return error_mark_node;
+ }
+
+ if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type)
+ && (flag_iso || warn_vla > 0))
+ pedwarn (input_location, OPT_Wvla, "array of array of runtime bound");
+
+ /* Figure out the index type for the array. */
+ if (size)
+ itype = compute_array_index_type (name, size, tf_warning_or_error);
+
+ /* [dcl.array]
+ T is called the array element type; this type shall not be [...] an
+ abstract class type. */
+ abstract_virtuals_error (name, type);
+
+ return build_cplus_array_type (type, itype);
+}
+
+/* Check that it's OK to declare a function with the indicated TYPE.
+ SFK indicates the kind of special function (if any) that this
+ function is. OPTYPE is the type given in a conversion operator
+ declaration, or the class type for a constructor/destructor.
+ Returns the actual return type of the function; that
+ may be different than TYPE if an error occurs, or for certain
+ special functions. */
+
+static tree
+check_special_function_return_type (special_function_kind sfk,
+ tree type,
+ tree optype)
+{
+ switch (sfk)
+ {
+ case sfk_constructor:
+ if (type)
+ error ("return type specification for constructor invalid");
+
+ if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (optype))
+ type = build_pointer_type (optype);
+ else
+ type = void_type_node;
+ break;
+
+ case sfk_destructor:
+ if (type)
+ error ("return type specification for destructor invalid");
+ /* We can't use the proper return type here because we run into
+ problems with ambiguous bases and covariant returns.
+ Java classes are left unchanged because (void *) isn't a valid
+ Java type, and we don't want to change the Java ABI. */
+ if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (optype))
+ type = build_pointer_type (void_type_node);
+ else
+ type = void_type_node;
+ break;
+
+ case sfk_conversion:
+ if (type)
+ error ("return type specified for %<operator %T%>", optype);
+ type = optype;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return type;
+}
+
+/* A variable or data member (whose unqualified name is IDENTIFIER)
+ has been declared with the indicated TYPE. If the TYPE is not
+ acceptable, issue an error message and return a type to use for
+ error-recovery purposes. */
+
+tree
+check_var_type (tree identifier, tree type)
+{
+ if (VOID_TYPE_P (type))
+ {
+ if (!identifier)
+ error ("unnamed variable or field declared void");
+ else if (identifier_p (identifier))
+ {
+ gcc_assert (!IDENTIFIER_OPNAME_P (identifier));
+ error ("variable or field %qE declared void", identifier);
+ }
+ else
+ error ("variable or field declared void");
+ type = error_mark_node;
+ }
+
+ return type;
+}
+
+/* Given declspecs and a declarator (abstract or otherwise), determine
+ the name and type of the object declared and construct a DECL node
+ for it.
+
+ DECLSPECS points to the representation of declaration-specifier
+ sequence that precedes declarator.
+
+ DECL_CONTEXT says which syntactic context this declaration is in:
+ NORMAL for most contexts. Make a VAR_DECL or FUNCTION_DECL or TYPE_DECL.
+ FUNCDEF for a function definition. Like NORMAL but a few different
+ error messages in each case. Return value may be zero meaning
+ this definition is too screwy to try to parse.
+ MEMFUNCDEF for a function definition. Like FUNCDEF but prepares to
+ handle member functions (which have FIELD context).
+ Return value may be zero meaning this definition is too screwy to
+ try to parse.
+ PARM for a parameter declaration (either within a function prototype
+ or before a function body). Make a PARM_DECL, or return void_type_node.
+ TPARM for a template parameter declaration.
+ CATCHPARM for a parameter declaration before a catch clause.
+ TYPENAME if for a typename (in a cast or sizeof).
+ Don't make a DECL node; just return the ..._TYPE node.
+ FIELD for a struct or union field; make a FIELD_DECL.
+ BITFIELD for a field with specified width.
+
+ INITIALIZED is as for start_decl.
+
+ ATTRLIST is a pointer to the list of attributes, which may be NULL
+ if there are none; *ATTRLIST may be modified if attributes from inside
+ the declarator should be applied to the declaration.
+
+ When this function is called, scoping variables (such as
+ CURRENT_CLASS_TYPE) should reflect the scope in which the
+ declaration occurs, not the scope in which the new declaration will
+ be placed. For example, on:
+
+ void S::f() { ... }
+
+ when grokdeclarator is called for `S::f', the CURRENT_CLASS_TYPE
+ should not be `S'.
+
+ Returns a DECL (if a declarator is present), a TYPE (if there is no
+ declarator, in cases like "struct S;"), or the ERROR_MARK_NODE if an
+ error occurs. */
+
+tree
+grokdeclarator (const cp_declarator *declarator,
+ cp_decl_specifier_seq *declspecs,
+ enum decl_context decl_context,
+ int initialized,
+ tree* attrlist)
+{
+ tree type = NULL_TREE;
+ int longlong = 0;
+ int explicit_int128 = 0;
+ int virtualp, explicitp, friendp, inlinep, staticp;
+ int explicit_int = 0;
+ int explicit_char = 0;
+ int defaulted_int = 0;
+
+ tree typedef_decl = NULL_TREE;
+ const char *name = NULL;
+ tree typedef_type = NULL_TREE;
+ /* True if this declarator is a function definition. */
+ bool funcdef_flag = false;
+ cp_declarator_kind innermost_code = cdk_error;
+ int bitfield = 0;
+#if 0
+ /* See the code below that used this. */
+ tree decl_attr = NULL_TREE;
+#endif
+
+ /* Keep track of what sort of function is being processed
+ so that we can warn about default return values, or explicit
+ return values which do not match prescribed defaults. */
+ special_function_kind sfk = sfk_none;
+
+ tree dname = NULL_TREE;
+ tree ctor_return_type = NULL_TREE;
+ enum overload_flags flags = NO_SPECIAL;
+ /* cv-qualifiers that apply to the declarator, for a declaration of
+ a member function. */
+ cp_cv_quals memfn_quals = TYPE_UNQUALIFIED;
+ /* virt-specifiers that apply to the declarator, for a declaration of
+ a member function. */
+ cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
+ /* ref-qualifier that applies to the declarator, for a declaration of
+ a member function. */
+ cp_ref_qualifier rqual = REF_QUAL_NONE;
+ /* cv-qualifiers that apply to the type specified by the DECLSPECS. */
+ int type_quals;
+ tree raises = NULL_TREE;
+ int template_count = 0;
+ tree returned_attrs = NULL_TREE;
+ tree parms = NULL_TREE;
+ const cp_declarator *id_declarator;
+ /* The unqualified name of the declarator; either an
+ IDENTIFIER_NODE, BIT_NOT_EXPR, or TEMPLATE_ID_EXPR. */
+ tree unqualified_id;
+ /* The class type, if any, in which this entity is located,
+ or NULL_TREE if none. Note that this value may be different from
+ the current class type; for example if an attempt is made to declare
+ "A::f" inside "B", this value will be "A". */
+ tree ctype = current_class_type;
+ /* The NAMESPACE_DECL for the namespace in which this entity is
+ located. If an unqualified name is used to declare the entity,
+ this value will be NULL_TREE, even if the entity is located at
+ namespace scope. */
+ tree in_namespace = NULL_TREE;
+ cp_storage_class storage_class;
+ bool unsigned_p, signed_p, short_p, long_p, thread_p;
+ bool type_was_error_mark_node = false;
+ bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
+ bool template_type_arg = false;
+ bool template_parm_flag = false;
+ bool typedef_p = decl_spec_seq_has_spec_p (declspecs, ds_typedef);
+ bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
+ source_location saved_loc = input_location;
+ const char *errmsg;
+
+ signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed);
+ unsigned_p = decl_spec_seq_has_spec_p (declspecs, ds_unsigned);
+ short_p = decl_spec_seq_has_spec_p (declspecs, ds_short);
+ long_p = decl_spec_seq_has_spec_p (declspecs, ds_long);
+ longlong = decl_spec_seq_has_spec_p (declspecs, ds_long_long);
+ explicit_int128 = declspecs->explicit_int128_p;
+ thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread);
+
+ if (decl_context == FUNCDEF)
+ funcdef_flag = true, decl_context = NORMAL;
+ else if (decl_context == MEMFUNCDEF)
+ funcdef_flag = true, decl_context = FIELD;
+ else if (decl_context == BITFIELD)
+ bitfield = 1, decl_context = FIELD;
+ else if (decl_context == TEMPLATE_TYPE_ARG)
+ template_type_arg = true, decl_context = TYPENAME;
+ else if (decl_context == TPARM)
+ template_parm_flag = true, decl_context = PARM;
+
+ if (initialized > 1)
+ funcdef_flag = true;
+
+ /* Look inside a declarator for the name being declared
+ and get it as a string, for an error message. */
+ for (id_declarator = declarator;
+ id_declarator;
+ id_declarator = id_declarator->declarator)
+ {
+ if (id_declarator->kind != cdk_id)
+ innermost_code = id_declarator->kind;
+
+ switch (id_declarator->kind)
+ {
+ case cdk_function:
+ if (id_declarator->declarator
+ && id_declarator->declarator->kind == cdk_id)
+ {
+ sfk = id_declarator->declarator->u.id.sfk;
+ if (sfk == sfk_destructor)
+ flags = DTOR_FLAG;
+ }
+ break;
+
+ case cdk_id:
+ {
+ tree qualifying_scope = id_declarator->u.id.qualifying_scope;
+ tree decl = id_declarator->u.id.unqualified_name;
+ if (!decl)
+ break;
+ if (qualifying_scope)
+ {
+ if (at_function_scope_p ())
+ {
+ /* [dcl.meaning]
+
+ A declarator-id shall not be qualified except
+ for ...
+
+ None of the cases are permitted in block
+ scope. */
+ if (qualifying_scope == global_namespace)
+ error ("invalid use of qualified-name %<::%D%>",
+ decl);
+ else if (TYPE_P (qualifying_scope))
+ error ("invalid use of qualified-name %<%T::%D%>",
+ qualifying_scope, decl);
+ else
+ error ("invalid use of qualified-name %<%D::%D%>",
+ qualifying_scope, decl);
+ return error_mark_node;
+ }
+ else if (TYPE_P (qualifying_scope))
+ {
+ ctype = qualifying_scope;
+ if (!MAYBE_CLASS_TYPE_P (ctype))
+ {
+ error ("%q#T is not a class or a namespace", ctype);
+ ctype = NULL_TREE;
+ }
+ else if (innermost_code != cdk_function
+ && current_class_type
+ && !uniquely_derived_from_p (ctype,
+ current_class_type))
+ {
+ error ("invalid use of qualified-name %<%T::%D%>",
+ qualifying_scope, decl);
+ return error_mark_node;
+ }
+ }
+ else if (TREE_CODE (qualifying_scope) == NAMESPACE_DECL)
+ in_namespace = qualifying_scope;
+ }
+ switch (TREE_CODE (decl))
+ {
+ case BIT_NOT_EXPR:
+ {
+ tree type;
+
+ if (innermost_code != cdk_function)
+ {
+ error ("declaration of %qD as non-function", decl);
+ return error_mark_node;
+ }
+ else if (!qualifying_scope
+ && !(current_class_type && at_class_scope_p ()))
+ {
+ error ("declaration of %qD as non-member", decl);
+ return error_mark_node;
+ }
+
+ type = TREE_OPERAND (decl, 0);
+ if (TYPE_P (type))
+ type = constructor_name (type);
+ name = identifier_to_locale (IDENTIFIER_POINTER (type));
+ dname = decl;
+ }
+ break;
+
+ case TEMPLATE_ID_EXPR:
+ {
+ tree fns = TREE_OPERAND (decl, 0);
+
+ dname = fns;
+ if (!identifier_p (dname))
+ {
+ gcc_assert (is_overloaded_fn (dname));
+ dname = DECL_NAME (get_first_fn (dname));
+ }
+ }
+ /* Fall through. */
+
+ case IDENTIFIER_NODE:
+ if (identifier_p (decl))
+ dname = decl;
+
+ if (C_IS_RESERVED_WORD (dname))
+ {
+ error ("declarator-id missing; using reserved word %qD",
+ dname);
+ name = identifier_to_locale (IDENTIFIER_POINTER (dname));
+ }
+ else if (!IDENTIFIER_TYPENAME_P (dname))
+ name = identifier_to_locale (IDENTIFIER_POINTER (dname));
+ else
+ {
+ gcc_assert (flags == NO_SPECIAL);
+ flags = TYPENAME_FLAG;
+ ctor_return_type = TREE_TYPE (dname);
+ sfk = sfk_conversion;
+ if (is_typename_at_global_scope (dname))
+ name = identifier_to_locale (IDENTIFIER_POINTER (dname));
+ else
+ name = "<invalid operator>";
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ break;
+ }
+
+ case cdk_array:
+ case cdk_pointer:
+ case cdk_reference:
+ case cdk_ptrmem:
+ break;
+
+ case cdk_error:
+ return error_mark_node;
+
+ default:
+ gcc_unreachable ();
+ }
+ if (id_declarator->kind == cdk_id)
+ break;
+ }
+
+ /* [dcl.fct.edf]
+
+ The declarator in a function-definition shall have the form
+ D1 ( parameter-declaration-clause) ... */
+ if (funcdef_flag && innermost_code != cdk_function)
+ {
+ error ("function definition does not declare parameters");
+ return error_mark_node;
+ }
+
+ if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG)
+ && innermost_code != cdk_function
+ && ! (ctype && !declspecs->any_specifiers_p))
+ {
+ error ("declaration of %qD as non-function", dname);
+ return error_mark_node;
+ }
+
+ if (dname
+ && identifier_p (dname)
+ && UDLIT_OPER_P (dname)
+ && innermost_code != cdk_function)
+ {
+ error ("declaration of %qD as non-function", dname);
+ return error_mark_node;
+ }
+
+ if (dname && IDENTIFIER_OPNAME_P (dname))
+ {
+ if (typedef_p)
+ {
+ error ("declaration of %qD as %<typedef%>", dname);
+ return error_mark_node;
+ }
+ else if (decl_context == PARM || decl_context == CATCHPARM)
+ {
+ error ("declaration of %qD as parameter", dname);
+ return error_mark_node;
+ }
+ }
+
+ /* Anything declared one level down from the top level
+ must be one of the parameters of a function
+ (because the body is at least two levels down). */
+
+ /* This heuristic cannot be applied to C++ nodes! Fixed, however,
+ by not allowing C++ class definitions to specify their parameters
+ with xdecls (must be spec.d in the parmlist).
+
+ Since we now wait to push a class scope until we are sure that
+ we are in a legitimate method context, we must set oldcname
+ explicitly (since current_class_name is not yet alive).
+
+ We also want to avoid calling this a PARM if it is in a namespace. */
+
+ if (decl_context == NORMAL && !toplevel_bindings_p ())
+ {
+ cp_binding_level *b = current_binding_level;
+ current_binding_level = b->level_chain;
+ if (current_binding_level != 0 && toplevel_bindings_p ())
+ decl_context = PARM;
+ current_binding_level = b;
+ }
+
+ if (name == NULL)
+ name = decl_context == PARM ? "parameter" : "type name";
+
+ if (constexpr_p && typedef_p)
+ {
+ error ("%<constexpr%> cannot appear in a typedef declaration");
+ return error_mark_node;
+ }
+
+ /* If there were multiple types specified in the decl-specifier-seq,
+ issue an error message. */
+ if (declspecs->multiple_types_p)
+ {
+ error ("two or more data types in declaration of %qs", name);
+ return error_mark_node;
+ }
+
+ if (declspecs->conflicting_specifiers_p)
+ {
+ error ("conflicting specifiers in declaration of %qs", name);
+ return error_mark_node;
+ }
+
+ /* Extract the basic type from the decl-specifier-seq. */
+ type = declspecs->type;
+ if (type == error_mark_node)
+ {
+ type = NULL_TREE;
+ type_was_error_mark_node = true;
+ }
+ /* If the entire declaration is itself tagged as deprecated then
+ suppress reports of deprecated items. */
+ if (type && TREE_DEPRECATED (type)
+ && deprecated_state != DEPRECATED_SUPPRESS)
+ warn_deprecated_use (type, NULL_TREE);
+ if (type && TREE_CODE (type) == TYPE_DECL)
+ {
+ typedef_decl = type;
+ type = TREE_TYPE (typedef_decl);
+ if (TREE_DEPRECATED (type)
+ && DECL_ARTIFICIAL (typedef_decl)
+ && deprecated_state != DEPRECATED_SUPPRESS)
+ warn_deprecated_use (type, NULL_TREE);
+ }
+ /* No type at all: default to `int', and set DEFAULTED_INT
+ because it was not a user-defined typedef. */
+ if (type == NULL_TREE && (signed_p || unsigned_p || long_p || short_p))
+ {
+ /* These imply 'int'. */
+ type = integer_type_node;
+ defaulted_int = 1;
+ }
+ /* Gather flags. */
+ explicit_int = declspecs->explicit_int_p;
+ explicit_char = declspecs->explicit_char_p;
+
+#if 0
+ /* See the code below that used this. */
+ if (typedef_decl)
+ decl_attr = DECL_ATTRIBUTES (typedef_decl);
+#endif
+ typedef_type = type;
+
+
+ if (sfk != sfk_conversion)
+ ctor_return_type = ctype;
+
+ if (sfk != sfk_none)
+ type = check_special_function_return_type (sfk, type,
+ ctor_return_type);
+ else if (type == NULL_TREE)
+ {
+ int is_main;
+
+ explicit_int = -1;
+
+ /* We handle `main' specially here, because 'main () { }' is so
+ common. With no options, it is allowed. With -Wreturn-type,
+ it is a warning. It is only an error with -pedantic-errors. */
+ is_main = (funcdef_flag
+ && dname && identifier_p (dname)
+ && MAIN_NAME_P (dname)
+ && ctype == NULL_TREE
+ && in_namespace == NULL_TREE
+ && current_namespace == global_namespace);
+
+ if (type_was_error_mark_node)
+ /* We've already issued an error, don't complain more. */;
+ else if (in_system_header_at (input_location) || flag_ms_extensions)
+ /* Allow it, sigh. */;
+ else if (! is_main)
+ permerror (input_location, "ISO C++ forbids declaration of %qs with no type", name);
+ else if (pedantic)
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ forbids declaration of %qs with no type", name);
+ else
+ warning (OPT_Wreturn_type,
+ "ISO C++ forbids declaration of %qs with no type", name);
+
+ type = integer_type_node;
+ }
+
+ ctype = NULL_TREE;
+
+ if (explicit_int128)
+ {
+ if (int128_integer_type_node == NULL_TREE)
+ {
+ error ("%<__int128%> is not supported by this target");
+ explicit_int128 = false;
+ }
+ else if (pedantic && ! in_system_header_at (input_location))
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ does not support %<__int128%> for %qs", name);
+ }
+
+ /* Now process the modifiers that were specified
+ and check for invalid combinations. */
+
+ /* Long double is a special combination. */
+ if (long_p && !longlong && TYPE_MAIN_VARIANT (type) == double_type_node)
+ {
+ long_p = false;
+ type = cp_build_qualified_type (long_double_type_node,
+ cp_type_quals (type));
+ }
+
+ /* Check all other uses of type modifiers. */
+
+ if (unsigned_p || signed_p || long_p || short_p)
+ {
+ int ok = 0;
+
+ if ((signed_p || unsigned_p) && TREE_CODE (type) != INTEGER_TYPE)
+ error ("%<signed%> or %<unsigned%> invalid for %qs", name);
+ else if (signed_p && unsigned_p)
+ error ("%<signed%> and %<unsigned%> specified together for %qs", name);
+ else if (longlong && TREE_CODE (type) != INTEGER_TYPE)
+ error ("%<long long%> invalid for %qs", name);
+ else if (long_p && TREE_CODE (type) == REAL_TYPE)
+ error ("%<long%> invalid for %qs", name);
+ else if (short_p && TREE_CODE (type) == REAL_TYPE)
+ error ("%<short%> invalid for %qs", name);
+ else if ((long_p || short_p) && TREE_CODE (type) != INTEGER_TYPE)
+ error ("%<long%> or %<short%> invalid for %qs", name);
+ else if ((long_p || short_p || explicit_char || explicit_int) && explicit_int128)
+ error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs", name);
+ else if ((long_p || short_p) && explicit_char)
+ error ("%<long%> or %<short%> specified with char for %qs", name);
+ else if (long_p && short_p)
+ error ("%<long%> and %<short%> specified together for %qs", name);
+ else if (type == char16_type_node || type == char32_type_node)
+ {
+ if (signed_p || unsigned_p)
+ error ("%<signed%> or %<unsigned%> invalid for %qs", name);
+ else if (short_p || long_p)
+ error ("%<short%> or %<long%> invalid for %qs", name);
+ }
+ else
+ {
+ ok = 1;
+ if (!explicit_int && !defaulted_int && !explicit_char && !explicit_int128 && pedantic)
+ {
+ pedwarn (input_location, OPT_Wpedantic,
+ "long, short, signed or unsigned used invalidly for %qs",
+ name);
+ if (flag_pedantic_errors)
+ ok = 0;
+ }
+ }
+
+ /* Discard the type modifiers if they are invalid. */
+ if (! ok)
+ {
+ unsigned_p = false;
+ signed_p = false;
+ long_p = false;
+ short_p = false;
+ longlong = 0;
+ }
+ }
+
+ /* Decide whether an integer type is signed or not.
+ Optionally treat bitfields as signed by default. */
+ if (unsigned_p
+ /* [class.bit]
+
+ It is implementation-defined whether a plain (neither
+ explicitly signed or unsigned) char, short, int, or long
+ bit-field is signed or unsigned.
+
+ Naturally, we extend this to long long as well. Note that
+ this does not include wchar_t. */
+ || (bitfield && !flag_signed_bitfields
+ && !signed_p
+ /* A typedef for plain `int' without `signed' can be
+ controlled just like plain `int', but a typedef for
+ `signed int' cannot be so controlled. */
+ && !(typedef_decl
+ && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))
+ && TREE_CODE (type) == INTEGER_TYPE
+ && !same_type_p (TYPE_MAIN_VARIANT (type), wchar_type_node)))
+ {
+ if (explicit_int128)
+ type = int128_unsigned_type_node;
+ else if (longlong)
+ type = long_long_unsigned_type_node;
+ else if (long_p)
+ type = long_unsigned_type_node;
+ else if (short_p)
+ type = short_unsigned_type_node;
+ else if (type == char_type_node)
+ type = unsigned_char_type_node;
+ else if (typedef_decl)
+ type = unsigned_type_for (type);
+ else
+ type = unsigned_type_node;
+ }
+ else if (signed_p && type == char_type_node)
+ type = signed_char_type_node;
+ else if (explicit_int128)
+ type = int128_integer_type_node;
+ else if (longlong)
+ type = long_long_integer_type_node;
+ else if (long_p)
+ type = long_integer_type_node;
+ else if (short_p)
+ type = short_integer_type_node;
+
+ if (decl_spec_seq_has_spec_p (declspecs, ds_complex))
+ {
+ if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
+ error ("complex invalid for %qs", name);
+ /* If we just have "complex", it is equivalent to
+ "complex double", but if any modifiers at all are specified it is
+ the complex form of TYPE. E.g, "complex short" is
+ "complex short int". */
+ else if (defaulted_int && ! longlong && ! explicit_int128
+ && ! (long_p || short_p || signed_p || unsigned_p))
+ type = complex_double_type_node;
+ else if (type == integer_type_node)
+ type = complex_integer_type_node;
+ else if (type == float_type_node)
+ type = complex_float_type_node;
+ else if (type == double_type_node)
+ type = complex_double_type_node;
+ else if (type == long_double_type_node)
+ type = complex_long_double_type_node;
+ else
+ type = build_complex_type (type);
+ }
+
+ type_quals = TYPE_UNQUALIFIED;
+ if (decl_spec_seq_has_spec_p (declspecs, ds_const))
+ type_quals |= TYPE_QUAL_CONST;
+ if (decl_spec_seq_has_spec_p (declspecs, ds_volatile))
+ type_quals |= TYPE_QUAL_VOLATILE;
+ if (decl_spec_seq_has_spec_p (declspecs, ds_restrict))
+ type_quals |= TYPE_QUAL_RESTRICT;
+ if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED)
+ error ("qualifiers are not allowed on declaration of %<operator %T%>",
+ ctor_return_type);
+
+ /* If we're using the injected-class-name to form a compound type or a
+ declaration, replace it with the underlying class so we don't get
+ redundant typedefs in the debug output. But if we are returning the
+ type unchanged, leave it alone so that it's available to
+ maybe_get_template_decl_from_type_decl. */
+ if (CLASS_TYPE_P (type)
+ && DECL_SELF_REFERENCE_P (TYPE_NAME (type))
+ && type == TREE_TYPE (TYPE_NAME (type))
+ && (declarator || type_quals))
+ type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
+
+ type_quals |= cp_type_quals (type);
+ type = cp_build_qualified_type_real
+ (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
+ ? tf_ignore_bad_quals : 0) | tf_warning_or_error));
+ /* We might have ignored or rejected some of the qualifiers. */
+ type_quals = cp_type_quals (type);
+
+ staticp = 0;
+ inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline);
+ virtualp = decl_spec_seq_has_spec_p (declspecs, ds_virtual);
+ explicitp = decl_spec_seq_has_spec_p (declspecs, ds_explicit);
+
+ storage_class = declspecs->storage_class;
+ if (storage_class == sc_static)
+ staticp = 1 + (decl_context == FIELD);
+
+ if (virtualp && staticp == 2)
+ {
+ error ("member %qD cannot be declared both virtual and static", dname);
+ storage_class = sc_none;
+ staticp = 0;
+ }
+ friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);
+
+ /* Issue errors about use of storage classes for parameters. */
+ if (decl_context == PARM)
+ {
+ if (typedef_p)
+ {
+ error ("typedef declaration invalid in parameter declaration");
+ return error_mark_node;
+ }
+ else if (template_parm_flag && storage_class != sc_none)
+ {
+ error ("storage class specified for template parameter %qs", name);
+ return error_mark_node;
+ }
+ else if (storage_class == sc_static
+ || storage_class == sc_extern
+ || thread_p)
+ error ("storage class specifiers invalid in parameter declarations");
+
+ /* Function parameters cannot be constexpr. If we saw one, moan
+ and pretend it wasn't there. */
+ if (constexpr_p)
+ {
+ error ("a parameter cannot be declared %<constexpr%>");
+ constexpr_p = 0;
+ }
+ }
+
+ /* Give error if `virtual' is used outside of class declaration. */
+ if (virtualp
+ && (current_class_name == NULL_TREE || decl_context != FIELD))
+ {
+ error ("%<virtual%> outside class declaration");
+ virtualp = 0;
+ }
+
+ /* Static anonymous unions are dealt with here. */
+ if (staticp && decl_context == TYPENAME
+ && declspecs->type
+ && ANON_AGGR_TYPE_P (declspecs->type))
+ decl_context = FIELD;
+
+ /* Warn about storage classes that are invalid for certain
+ kinds of declarations (parameters, typenames, etc.). */
+ if (thread_p
+ && ((storage_class
+ && storage_class != sc_extern
+ && storage_class != sc_static)
+ || typedef_p))
+ {
+ error ("multiple storage classes in declaration of %qs", name);
+ thread_p = false;
+ }
+ if (decl_context != NORMAL
+ && ((storage_class != sc_none
+ && storage_class != sc_mutable)
+ || thread_p))
+ {
+ if ((decl_context == PARM || decl_context == CATCHPARM)
+ && (storage_class == sc_register
+ || storage_class == sc_auto))
+ ;
+ else if (typedef_p)
+ ;
+ else if (decl_context == FIELD
+ /* C++ allows static class elements. */
+ && storage_class == sc_static)
+ /* C++ also allows inlines and signed and unsigned elements,
+ but in those cases we don't come in here. */
+ ;
+ else
+ {
+ if (decl_context == FIELD)
+ error ("storage class specified for %qs", name);
+ else
+ {
+ if (decl_context == PARM || decl_context == CATCHPARM)
+ error ("storage class specified for parameter %qs", name);
+ else
+ error ("storage class specified for typename");
+ }
+ if (storage_class == sc_register
+ || storage_class == sc_auto
+ || storage_class == sc_extern
+ || thread_p)
+ storage_class = sc_none;
+ }
+ }
+ else if (storage_class == sc_extern && funcdef_flag
+ && ! toplevel_bindings_p ())
+ error ("nested function %qs declared %<extern%>", name);
+ else if (toplevel_bindings_p ())
+ {
+ if (storage_class == sc_auto)
+ error ("top-level declaration of %qs specifies %<auto%>", name);
+ }
+ else if (thread_p
+ && storage_class != sc_extern
+ && storage_class != sc_static)
+ {
+ if (declspecs->gnu_thread_keyword_p)
+ pedwarn (input_location, 0, "function-scope %qs implicitly auto and "
+ "declared %<__thread%>", name);
+
+ /* When thread_local is applied to a variable of block scope the
+ storage-class-specifier static is implied if it does not appear
+ explicitly. */
+ storage_class = declspecs->storage_class = sc_static;
+ staticp = 1;
+ }
+
+ if (storage_class && friendp)
+ {
+ error ("storage class specifiers invalid in friend function declarations");
+ storage_class = sc_none;
+ staticp = 0;
+ }
+
+ if (!id_declarator)
+ unqualified_id = NULL_TREE;
+ else
+ {
+ unqualified_id = id_declarator->u.id.unqualified_name;
+ switch (TREE_CODE (unqualified_id))
+ {
+ case BIT_NOT_EXPR:
+ unqualified_id = TREE_OPERAND (unqualified_id, 0);
+ if (TYPE_P (unqualified_id))
+ unqualified_id = constructor_name (unqualified_id);
+ break;
+
+ case IDENTIFIER_NODE:
+ case TEMPLATE_ID_EXPR:
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+
+ if (declspecs->std_attributes)
+ {
+ /* Apply the c++11 attributes to the type preceding them. */
+ input_location = declspecs->locations[ds_std_attribute];
+ decl_attributes (&type, declspecs->std_attributes, 0);
+ input_location = saved_loc;
+ }
+
+ /* Determine the type of the entity declared by recurring on the
+ declarator. */
+ for (; declarator; declarator = declarator->declarator)
+ {
+ const cp_declarator *inner_declarator;
+ tree attrs;
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ attrs = declarator->attributes;
+ if (attrs)
+ {
+ int attr_flags;
+
+ attr_flags = 0;
+ if (declarator == NULL || declarator->kind == cdk_id)
+ attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
+ if (declarator->kind == cdk_function)
+ attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
+ if (declarator->kind == cdk_array)
+ attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
+ returned_attrs = decl_attributes (&type,
+ chainon (returned_attrs, attrs),
+ attr_flags);
+ }
+
+ if (declarator->kind == cdk_id)
+ break;
+
+ inner_declarator = declarator->declarator;
+
+ switch (declarator->kind)
+ {
+ case cdk_array:
+ type = create_array_type_for_decl (dname, type,
+ declarator->u.array.bounds);
+ if (declarator->std_attributes)
+ /* [dcl.array]/1:
+
+ The optional attribute-specifier-seq appertains to the
+ array. */
+ returned_attrs = chainon (returned_attrs,
+ declarator->std_attributes);
+ break;
+
+ case cdk_function:
+ {
+ tree arg_types;
+ int funcdecl_p;
+
+ /* Declaring a function type.
+ Make sure we have a valid type for the function to return. */
+
+ if (type_quals != TYPE_UNQUALIFIED)
+ {
+ if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type))
+ warning (OPT_Wignored_qualifiers,
+ "type qualifiers ignored on function return type");
+ /* We now know that the TYPE_QUALS don't apply to the
+ decl, but to its return type. */
+ type_quals = TYPE_UNQUALIFIED;
+ }
+ errmsg = targetm.invalid_return_type (type);
+ if (errmsg)
+ {
+ error (errmsg);
+ type = integer_type_node;
+ }
+
+ /* Error about some types functions can't return. */
+
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ error ("%qs declared as function returning a function", name);
+ return error_mark_node;
+ }
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ error ("%qs declared as function returning an array", name);
+ return error_mark_node;
+ }
+
+ input_location = declspecs->locations[ds_type_spec];
+ abstract_virtuals_error (ACU_RETURN, type);
+ input_location = saved_loc;
+
+ /* Pick up type qualifiers which should be applied to `this'. */
+ memfn_quals = declarator->u.function.qualifiers;
+ /* Pick up virt-specifiers. */
+ virt_specifiers = declarator->u.function.virt_specifiers;
+ /* And ref-qualifier, too */
+ rqual = declarator->u.function.ref_qualifier;
+ /* Pick up the exception specifications. */
+ raises = declarator->u.function.exception_specification;
+ /* If the exception-specification is ill-formed, let's pretend
+ there wasn't one. */
+ if (raises == error_mark_node)
+ raises = NULL_TREE;
+
+ /* Say it's a definition only for the CALL_EXPR
+ closest to the identifier. */
+ funcdecl_p = inner_declarator && inner_declarator->kind == cdk_id;
+
+ /* Handle a late-specified return type. */
+ if (funcdecl_p)
+ {
+ if (type_uses_auto (type))
+ {
+ if (!declarator->u.function.late_return_type)
+ {
+ if (current_class_type
+ && LAMBDA_TYPE_P (current_class_type))
+ /* OK for C++11 lambdas. */;
+ else if (cxx_dialect < cxx1y)
+ {
+ error ("%qs function uses "
+ "%<auto%> type specifier without trailing "
+ "return type", name);
+ inform (input_location, "deduced return type "
+ "only available with -std=c++1y or "
+ "-std=gnu++1y");
+ }
+ else if (virtualp)
+ error ("virtual function cannot "
+ "have deduced return type");
+ }
+ else if (!is_auto (type))
+ {
+ error ("%qs function with trailing return type has"
+ " %qT as its type rather than plain %<auto%>",
+ name, type);
+ return error_mark_node;
+ }
+ }
+ else if (declarator->u.function.late_return_type)
+ {
+ if (cxx_dialect < cxx11)
+ /* Not using maybe_warn_cpp0x because this should
+ always be an error. */
+ error ("trailing return type only available with "
+ "-std=c++11 or -std=gnu++11");
+ else
+ error ("%qs function with trailing return type not "
+ "declared with %<auto%> type specifier", name);
+ return error_mark_node;
+ }
+ }
+ type = splice_late_return_type
+ (type, declarator->u.function.late_return_type);
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ if (ctype == NULL_TREE
+ && decl_context == FIELD
+ && funcdecl_p
+ && (friendp == 0 || dname == current_class_name))
+ ctype = current_class_type;
+
+ if (ctype && (sfk == sfk_constructor
+ || sfk == sfk_destructor))
+ {
+ /* We are within a class's scope. If our declarator name
+ is the same as the class name, and we are defining
+ a function, then it is a constructor/destructor, and
+ therefore returns a void type. */
+
+ /* ISO C++ 12.4/2. A destructor may not be declared
+ const or volatile. A destructor may not be static.
+ A destructor may not be declared with ref-qualifier.
+
+ ISO C++ 12.1. A constructor may not be declared
+ const or volatile. A constructor may not be
+ virtual. A constructor may not be static.
+ A constructor may not be declared with ref-qualifier. */
+ if (staticp == 2)
+ error ((flags == DTOR_FLAG)
+ ? G_("destructor cannot be static member function")
+ : G_("constructor cannot be static member function"));
+ if (memfn_quals)
+ {
+ error ((flags == DTOR_FLAG)
+ ? G_("destructors may not be cv-qualified")
+ : G_("constructors may not be cv-qualified"));
+ memfn_quals = TYPE_UNQUALIFIED;
+ }
+
+ if (rqual)
+ {
+ maybe_warn_cpp0x (CPP0X_REF_QUALIFIER);
+ error ((flags == DTOR_FLAG)
+ ? "destructors may not be ref-qualified"
+ : "constructors may not be ref-qualified");
+ rqual = REF_QUAL_NONE;
+ }
+
+ if (decl_context == FIELD
+ && !member_function_or_else (ctype,
+ current_class_type,
+ flags))
+ return error_mark_node;
+
+ if (flags != DTOR_FLAG)
+ {
+ /* It's a constructor. */
+ if (explicitp == 1)
+ explicitp = 2;
+ if (virtualp)
+ {
+ permerror (input_location, "constructors cannot be declared virtual");
+ virtualp = 0;
+ }
+ if (decl_context == FIELD
+ && sfk != sfk_constructor)
+ return error_mark_node;
+ }
+ if (decl_context == FIELD)
+ staticp = 0;
+ }
+ else if (friendp)
+ {
+ if (initialized)
+ error ("can%'t initialize friend function %qs", name);
+ if (virtualp)
+ {
+ /* Cannot be both friend and virtual. */
+ error ("virtual functions cannot be friends");
+ friendp = 0;
+ }
+ if (decl_context == NORMAL)
+ error ("friend declaration not in class definition");
+ if (current_function_decl && funcdef_flag)
+ error ("can%'t define friend function %qs in a local "
+ "class definition",
+ name);
+ }
+ else if (ctype && sfk == sfk_conversion)
+ {
+ if (explicitp == 1)
+ {
+ maybe_warn_cpp0x (CPP0X_EXPLICIT_CONVERSION);
+ explicitp = 2;
+ }
+ }
+
+ arg_types = grokparms (declarator->u.function.parameters,
+ &parms);
+
+ if (inner_declarator
+ && inner_declarator->kind == cdk_id
+ && inner_declarator->u.id.sfk == sfk_destructor
+ && arg_types != void_list_node)
+ {
+ error ("destructors may not have parameters");
+ arg_types = void_list_node;
+ parms = NULL_TREE;
+ }
+
+ type = build_function_type (type, arg_types);
+ if (declarator->std_attributes)
+ /* [dcl.fct]/2:
+
+ The optional attribute-specifier-seq appertains to
+ the function type. */
+ decl_attributes (&type, declarator->std_attributes,
+ 0);
+ }
+ break;
+
+ case cdk_pointer:
+ case cdk_reference:
+ case cdk_ptrmem:
+ /* Filter out pointers-to-references and references-to-references.
+ We can get these if a TYPE_DECL is used. */
+
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (declarator->kind != cdk_reference)
+ {
+ error ("cannot declare pointer to %q#T", type);
+ type = TREE_TYPE (type);
+ }
+
+ /* In C++0x, we allow reference to reference declarations
+ that occur indirectly through typedefs [7.1.3/8 dcl.typedef]
+ and template type arguments [14.3.1/4 temp.arg.type]. The
+ check for direct reference to reference declarations, which
+ are still forbidden, occurs below. Reasoning behind the change
+ can be found in DR106, DR540, and the rvalue reference
+ proposals. */
+ else if (cxx_dialect == cxx98)
+ {
+ error ("cannot declare reference to %q#T", type);
+ type = TREE_TYPE (type);
+ }
+ }
+ else if (VOID_TYPE_P (type))
+ {
+ if (declarator->kind == cdk_reference)
+ error ("cannot declare reference to %q#T", type);
+ else if (declarator->kind == cdk_ptrmem)
+ error ("cannot declare pointer to %q#T member", type);
+ }
+
+ /* We now know that the TYPE_QUALS don't apply to the decl,
+ but to the target of the pointer. */
+ type_quals = TYPE_UNQUALIFIED;
+
+ /* This code used to handle METHOD_TYPE, but I don't think it's
+ possible to get it here anymore. */
+ gcc_assert (TREE_CODE (type) != METHOD_TYPE);
+ if (declarator->kind == cdk_ptrmem
+ && TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ memfn_quals |= type_memfn_quals (type);
+ type = build_memfn_type (type,
+ declarator->u.pointer.class_type,
+ memfn_quals,
+ rqual);
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ rqual = REF_QUAL_NONE;
+ memfn_quals = TYPE_UNQUALIFIED;
+ }
+
+ if (TREE_CODE (type) == FUNCTION_TYPE
+ && (type_memfn_quals (type) != TYPE_UNQUALIFIED
+ || type_memfn_rqual (type) != REF_QUAL_NONE))
+ error (declarator->kind == cdk_reference
+ ? G_("cannot declare reference to qualified function type %qT")
+ : G_("cannot declare pointer to qualified function type %qT"),
+ type);
+
+ if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type)
+ && (flag_iso || warn_vla > 0))
+ pedwarn (input_location, OPT_Wvla,
+ declarator->kind == cdk_reference
+ ? G_("reference to array of runtime bound")
+ : G_("pointer to array of runtime bound"));
+
+ /* When the pointed-to type involves components of variable size,
+ care must be taken to ensure that the size evaluation code is
+ emitted early enough to dominate all the possible later uses
+ and late enough for the variables on which it depends to have
+ been assigned.
+
+ This is expected to happen automatically when the pointed-to
+ type has a name/declaration of it's own, but special attention
+ is required if the type is anonymous.
+
+ We handle the NORMAL and FIELD contexts here by inserting a
+ dummy statement that just evaluates the size at a safe point
+ and ensures it is not deferred until e.g. within a deeper
+ conditional context (c++/43555).
+
+ We expect nothing to be needed here for PARM or TYPENAME.
+ Evaluating the size at this point for TYPENAME would
+ actually be incorrect, as we might be in the middle of an
+ expression with side effects on the pointed-to type size
+ "arguments" prior to the pointer declaration point and the
+ size evaluation could end up prior to the side effects. */
+
+ if (!TYPE_NAME (type)
+ && (decl_context == NORMAL || decl_context == FIELD)
+ && at_function_scope_p ()
+ && variably_modified_type_p (type, NULL_TREE))
+ /* Force evaluation of the SAVE_EXPR. */
+ finish_expr_stmt (TYPE_SIZE (type));
+
+ if (declarator->kind == cdk_reference)
+ {
+ /* In C++0x, the type we are creating a reference to might be
+ a typedef which is itself a reference type. In that case,
+ we follow the reference collapsing rules in
+ [7.1.3/8 dcl.typedef] to create the final reference type:
+
+ "If a typedef TD names a type that is a reference to a type
+ T, an attempt to create the type 'lvalue reference to cv TD'
+ creates the type 'lvalue reference to T,' while an attempt
+ to create the type "rvalue reference to cv TD' creates the
+ type TD."
+ */
+ if (VOID_TYPE_P (type))
+ /* We already gave an error. */;
+ else if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (declarator->u.reference.rvalue_ref)
+ /* Leave type alone. */;
+ else
+ type = cp_build_reference_type (TREE_TYPE (type), false);
+ }
+ else
+ type = cp_build_reference_type
+ (type, declarator->u.reference.rvalue_ref);
+
+ /* In C++0x, we need this check for direct reference to
+ reference declarations, which are forbidden by
+ [8.3.2/5 dcl.ref]. Reference to reference declarations
+ are only allowed indirectly through typedefs and template
+ type arguments. Example:
+
+ void foo(int & &); // invalid ref-to-ref decl
+
+ typedef int & int_ref;
+ void foo(int_ref &); // valid ref-to-ref decl
+ */
+ if (inner_declarator && inner_declarator->kind == cdk_reference)
+ error ("cannot declare reference to %q#T, which is not "
+ "a typedef or a template type argument", type);
+ }
+ else if (TREE_CODE (type) == METHOD_TYPE)
+ type = build_ptrmemfunc_type (build_pointer_type (type));
+ else if (declarator->kind == cdk_ptrmem)
+ {
+ gcc_assert (TREE_CODE (declarator->u.pointer.class_type)
+ != NAMESPACE_DECL);
+ if (declarator->u.pointer.class_type == error_mark_node)
+ /* We will already have complained. */
+ type = error_mark_node;
+ else
+ type = build_ptrmem_type (declarator->u.pointer.class_type,
+ type);
+ }
+ else
+ type = build_pointer_type (type);
+
+ /* Process a list of type modifier keywords (such as
+ const or volatile) that were given inside the `*' or `&'. */
+
+ if (declarator->u.pointer.qualifiers)
+ {
+ type
+ = cp_build_qualified_type (type,
+ declarator->u.pointer.qualifiers);
+ type_quals = cp_type_quals (type);
+ }
+
+ /* Apply C++11 attributes to the pointer, and not to the
+ type pointed to. This is unlike what is done for GNU
+ attributes above. It is to comply with [dcl.ptr]/1:
+
+ [the optional attribute-specifier-seq (7.6.1) appertains
+ to the pointer and not to the object pointed to]. */
+ if (declarator->std_attributes)
+ decl_attributes (&type, declarator->std_attributes,
+ 0);
+
+ ctype = NULL_TREE;
+ break;
+
+ case cdk_error:
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+
+ /* A `constexpr' specifier used in an object declaration declares
+ the object as `const'. */
+ if (constexpr_p && innermost_code != cdk_function)
+ {
+ if (type_quals & TYPE_QUAL_VOLATILE)
+ error ("both %<volatile%> and %<constexpr%> cannot be used here");
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ {
+ type_quals |= TYPE_QUAL_CONST;
+ type = cp_build_qualified_type (type, type_quals);
+ }
+ }
+
+ if (unqualified_id && TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR
+ && TREE_CODE (type) != FUNCTION_TYPE
+ && TREE_CODE (type) != METHOD_TYPE)
+ {
+ error ("template-id %qD used as a declarator",
+ unqualified_id);
+ unqualified_id = dname;
+ }
+
+ /* If TYPE is a FUNCTION_TYPE, but the function name was explicitly
+ qualified with a class-name, turn it into a METHOD_TYPE, unless
+ we know that the function is static. We take advantage of this
+ opportunity to do other processing that pertains to entities
+ explicitly declared to be class members. Note that if DECLARATOR
+ is non-NULL, we know it is a cdk_id declarator; otherwise, we
+ would not have exited the loop above. */
+ if (declarator
+ && declarator->u.id.qualifying_scope
+ && MAYBE_CLASS_TYPE_P (declarator->u.id.qualifying_scope))
+ {
+ ctype = declarator->u.id.qualifying_scope;
+ ctype = TYPE_MAIN_VARIANT (ctype);
+ template_count = num_template_headers_for_class (ctype);
+
+ if (ctype == current_class_type)
+ {
+ if (friendp)
+ {
+ permerror (input_location, "member functions are implicitly friends of their class");
+ friendp = 0;
+ }
+ else
+ permerror (declarator->id_loc,
+ "extra qualification %<%T::%> on member %qs",
+ ctype, name);
+ }
+ else if (/* If the qualifying type is already complete, then we
+ can skip the following checks. */
+ !COMPLETE_TYPE_P (ctype)
+ && (/* If the function is being defined, then
+ qualifying type must certainly be complete. */
+ funcdef_flag
+ /* A friend declaration of "T::f" is OK, even if
+ "T" is a template parameter. But, if this
+ function is not a friend, the qualifying type
+ must be a class. */
+ || (!friendp && !CLASS_TYPE_P (ctype))
+ /* For a declaration, the type need not be
+ complete, if either it is dependent (since there
+ is no meaningful definition of complete in that
+ case) or the qualifying class is currently being
+ defined. */
+ || !(dependent_type_p (ctype)
+ || currently_open_class (ctype)))
+ /* Check that the qualifying type is complete. */
+ && !complete_type_or_else (ctype, NULL_TREE))
+ return error_mark_node;
+ else if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ if (current_class_type
+ && (!friendp || funcdef_flag))
+ {
+ error (funcdef_flag
+ ? G_("cannot define member function %<%T::%s%> "
+ "within %<%T%>")
+ : G_("cannot declare member function %<%T::%s%> "
+ "within %<%T%>"),
+ ctype, name, current_class_type);
+ return error_mark_node;
+ }
+ }
+ else if (typedef_p && current_class_type)
+ {
+ error ("cannot declare member %<%T::%s%> within %qT",
+ ctype, name, current_class_type);
+ return error_mark_node;
+ }
+ }
+
+ if (ctype == NULL_TREE && decl_context == FIELD && friendp == 0)
+ ctype = current_class_type;
+
+ /* Now TYPE has the actual type. */
+
+ if (returned_attrs)
+ {
+ if (attrlist)
+ *attrlist = chainon (returned_attrs, *attrlist);
+ else
+ attrlist = &returned_attrs;
+ }
+
+ if (declarator
+ && declarator->kind == cdk_id
+ && declarator->std_attributes)
+ /* [dcl.meaning]/1: The optional attribute-specifier-seq following
+ a declarator-id appertains to the entity that is declared. */
+ *attrlist = chainon (*attrlist, declarator->std_attributes);
+
+ /* Handle parameter packs. */
+ if (parameter_pack_p)
+ {
+ if (decl_context == PARM)
+ /* Turn the type into a pack expansion.*/
+ type = make_pack_expansion (type);
+ else
+ error ("non-parameter %qs cannot be a parameter pack", name);
+ }
+
+ /* Did array size calculations overflow or does the array cover more
+ than half of the address-space? */
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && COMPLETE_TYPE_P (type)
+ && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
+ && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
+ {
+ error ("size of array %qs is too large", name);
+ /* If we proceed with the array type as it is, we'll eventually
+ crash in tree_to_[su]hwi(). */
+ type = error_mark_node;
+ }
+
+ if ((decl_context == FIELD || decl_context == PARM)
+ && !processing_template_decl
+ && variably_modified_type_p (type, NULL_TREE))
+ {
+ if (decl_context == FIELD)
+ error ("data member may not have variably modified type %qT", type);
+ else
+ error ("parameter may not have variably modified type %qT", type);
+ type = error_mark_node;
+ }
+
+ if (explicitp == 1 || (explicitp && friendp))
+ {
+ /* [dcl.fct.spec] The explicit specifier shall only be used in
+ declarations of constructors within a class definition. */
+ error ("only declarations of constructors can be %<explicit%>");
+ explicitp = 0;
+ }
+
+ if (storage_class == sc_mutable)
+ {
+ if (decl_context != FIELD || friendp)
+ {
+ error ("non-member %qs cannot be declared %<mutable%>", name);
+ storage_class = sc_none;
+ }
+ else if (decl_context == TYPENAME || typedef_p)
+ {
+ error ("non-object member %qs cannot be declared %<mutable%>", name);
+ storage_class = sc_none;
+ }
+ else if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
+ {
+ error ("function %qs cannot be declared %<mutable%>", name);
+ storage_class = sc_none;
+ }
+ else if (staticp)
+ {
+ error ("static %qs cannot be declared %<mutable%>", name);
+ storage_class = sc_none;
+ }
+ else if (type_quals & TYPE_QUAL_CONST)
+ {
+ error ("const %qs cannot be declared %<mutable%>", name);
+ storage_class = sc_none;
+ }
+ else if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ permerror (input_location, "reference %qs cannot be declared "
+ "%<mutable%>", name);
+ storage_class = sc_none;
+ }
+ }
+
+ /* If this is declaring a typedef name, return a TYPE_DECL. */
+ if (typedef_p && decl_context != TYPENAME)
+ {
+ tree decl;
+
+ /* Note that the grammar rejects storage classes
+ in typenames, fields or parameters. */
+ if (current_lang_name == lang_name_java)
+ TYPE_FOR_JAVA (type) = 1;
+
+ /* This declaration:
+
+ typedef void f(int) const;
+
+ declares a function type which is not a member of any
+ particular class, but which is cv-qualified; for
+ example "f S::*" declares a pointer to a const-qualified
+ member function of S. We record the cv-qualification in the
+ function type. */
+ if ((rqual || memfn_quals) && TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ type = apply_memfn_quals (type, memfn_quals, rqual);
+
+ /* We have now dealt with these qualifiers. */
+ memfn_quals = TYPE_UNQUALIFIED;
+ rqual = REF_QUAL_NONE;
+ }
+
+ if (type_uses_auto (type))
+ {
+ error ("typedef declared %<auto%>");
+ type = error_mark_node;
+ }
+
+ if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type)
+ && (flag_iso || warn_vla > 0))
+ pedwarn (input_location, OPT_Wvla,
+ "typedef naming array of runtime bound");
+
+ if (decl_context == FIELD)
+ decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
+ else
+ decl = build_decl (input_location, TYPE_DECL, unqualified_id, type);
+ if (id_declarator && declarator->u.id.qualifying_scope) {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "typedef name may not be a nested-name-specifier");
+ TREE_TYPE (decl) = error_mark_node;
+ }
+
+ if (decl_context != FIELD)
+ {
+ if (!current_function_decl)
+ DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
+ else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (current_function_decl)
+ || (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P
+ (current_function_decl)))
+ /* The TYPE_DECL is "abstract" because there will be
+ clones of this constructor/destructor, and there will
+ be copies of this TYPE_DECL generated in those
+ clones. The decloning optimization (for space) may
+ revert this subsequently if it determines that
+ the clones should share a common implementation. */
+ DECL_ABSTRACT (decl) = 1;
+ }
+ else if (current_class_type
+ && constructor_name_p (unqualified_id, current_class_type))
+ permerror (input_location, "ISO C++ forbids nested type %qD with same name "
+ "as enclosing class",
+ unqualified_id);
+
+ /* If the user declares "typedef struct {...} foo" then the
+ struct will have an anonymous name. Fill that name in now.
+ Nothing can refer to it, so nothing needs know about the name
+ change. */
+ if (type != error_mark_node
+ && unqualified_id
+ && TYPE_NAME (type)
+ && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
+ && TYPE_ANONYMOUS_P (type)
+ && declspecs->type_definition_p
+ && attributes_naming_typedef_ok (*attrlist)
+ && cp_type_quals (type) == TYPE_UNQUALIFIED)
+ {
+ tree t;
+
+ /* Replace the anonymous name with the real name everywhere. */
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ {
+ if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
+ /* We do not rename the debug info representing the
+ anonymous tagged type because the standard says in
+ [dcl.typedef] that the naming applies only for
+ linkage purposes. */
+ /*debug_hooks->set_name (t, decl);*/
+ TYPE_NAME (t) = decl;
+ }
+
+ if (TYPE_LANG_SPECIFIC (type))
+ TYPE_WAS_ANONYMOUS (type) = 1;
+
+ /* If this is a typedef within a template class, the nested
+ type is a (non-primary) template. The name for the
+ template needs updating as well. */
+ if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type))
+ DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
+ = TYPE_IDENTIFIER (type);
+
+ /* Adjust linkage now that we aren't anonymous anymore. */
+ reset_type_linkage (type);
+
+ /* FIXME remangle member functions; member functions of a
+ type with external linkage have external linkage. */
+ }
+
+ if (signed_p
+ || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
+ C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
+
+ bad_specifiers (decl, BSP_TYPE, virtualp,
+ memfn_quals != TYPE_UNQUALIFIED,
+ inlinep, friendp, raises != NULL_TREE);
+
+ if (decl_spec_seq_has_spec_p (declspecs, ds_alias))
+ /* Acknowledge that this was written:
+ `using analias = atype;'. */
+ TYPE_DECL_ALIAS_P (decl) = 1;
+
+ return decl;
+ }
+
+ /* Detect the case of an array type of unspecified size
+ which came, as such, direct from a typedef name.
+ We must copy the type, so that the array's domain can be
+ individually set by the object's initializer. */
+
+ if (type && typedef_type
+ && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)
+ && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type))
+ type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
+
+ /* Detect where we're using a typedef of function type to declare a
+ function. PARMS will not be set, so we must create it now. */
+
+ if (type == typedef_type && TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ tree decls = NULL_TREE;
+ tree args;
+
+ for (args = TYPE_ARG_TYPES (type);
+ args && args != void_list_node;
+ args = TREE_CHAIN (args))
+ {
+ tree decl = cp_build_parm_decl (NULL_TREE, TREE_VALUE (args));
+
+ DECL_CHAIN (decl) = decls;
+ decls = decl;
+ }
+
+ parms = nreverse (decls);
+
+ if (decl_context != TYPENAME)
+ {
+ /* The qualifiers on the function type become the qualifiers on
+ the non-static member function. */
+ memfn_quals |= type_memfn_quals (type);
+ rqual = type_memfn_rqual (type);
+ type_quals = TYPE_UNQUALIFIED;
+ }
+ }
+
+ /* If this is a type name (such as, in a cast or sizeof),
+ compute the type and return it now. */
+
+ if (decl_context == TYPENAME)
+ {
+ /* Note that the grammar rejects storage classes
+ in typenames, fields or parameters. */
+ if (type_quals != TYPE_UNQUALIFIED)
+ type_quals = TYPE_UNQUALIFIED;
+
+ /* Special case: "friend class foo" looks like a TYPENAME context. */
+ if (friendp)
+ {
+ if (type_quals != TYPE_UNQUALIFIED)
+ {
+ error ("type qualifiers specified for friend class declaration");
+ type_quals = TYPE_UNQUALIFIED;
+ }
+ if (inlinep)
+ {
+ error ("%<inline%> specified for friend class declaration");
+ inlinep = 0;
+ }
+
+ if (!current_aggr)
+ {
+ /* Don't allow friend declaration without a class-key. */
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+ permerror (input_location, "template parameters cannot be friends");
+ else if (TREE_CODE (type) == TYPENAME_TYPE)
+ permerror (input_location, "friend declaration requires class-key, "
+ "i.e. %<friend class %T::%D%>",
+ TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
+ else
+ permerror (input_location, "friend declaration requires class-key, "
+ "i.e. %<friend %#T%>",
+ type);
+ }
+
+ /* Only try to do this stuff if we didn't already give up. */
+ if (type != integer_type_node)
+ {
+ /* A friendly class? */
+ if (current_class_type)
+ make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type),
+ /*complain=*/true);
+ else
+ error ("trying to make class %qT a friend of global scope",
+ type);
+
+ type = void_type_node;
+ }
+ }
+ else if (memfn_quals || rqual)
+ {
+ if (ctype == NULL_TREE
+ && TREE_CODE (type) == METHOD_TYPE)
+ ctype = TYPE_METHOD_BASETYPE (type);
+
+ if (ctype)
+ type = build_memfn_type (type, ctype, memfn_quals, rqual);
+ /* Core issue #547: need to allow this in template type args.
+ Allow it in general in C++11 for alias-declarations. */
+ else if ((template_type_arg || cxx_dialect >= cxx11)
+ && TREE_CODE (type) == FUNCTION_TYPE)
+ type = apply_memfn_quals (type, memfn_quals, rqual);
+ else
+ error ("invalid qualifiers on non-member function type");
+ }
+
+ return type;
+ }
+ else if (unqualified_id == NULL_TREE && decl_context != PARM
+ && decl_context != CATCHPARM
+ && TREE_CODE (type) != UNION_TYPE
+ && ! bitfield)
+ {
+ error ("abstract declarator %qT used as declaration", type);
+ return error_mark_node;
+ }
+
+ /* Only functions may be declared using an operator-function-id. */
+ if (unqualified_id
+ && IDENTIFIER_OPNAME_P (unqualified_id)
+ && TREE_CODE (type) != FUNCTION_TYPE
+ && TREE_CODE (type) != METHOD_TYPE)
+ {
+ error ("declaration of %qD as non-function", unqualified_id);
+ return error_mark_node;
+ }
+
+ /* We don't check parameter types here because we can emit a better
+ error message later. */
+ if (decl_context != PARM)
+ {
+ type = check_var_type (unqualified_id, type);
+ if (type == error_mark_node)
+ return error_mark_node;
+ }
+
+ /* Now create the decl, which may be a VAR_DECL, a PARM_DECL
+ or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE. */
+
+ if (decl_context == PARM || decl_context == CATCHPARM)
+ {
+ if (ctype || in_namespace)
+ error ("cannot use %<::%> in parameter declaration");
+
+ if (type_uses_auto (type))
+ {
+ if (cxx_dialect >= cxx1y)
+ error ("%<auto%> parameter not permitted in this context");
+ else
+ error ("parameter declared %<auto%>");
+ type = error_mark_node;
+ }
+
+ /* A parameter declared as an array of T is really a pointer to T.
+ One declared as a function is really a pointer to a function.
+ One declared as a member is really a pointer to member. */
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ /* Transfer const-ness of array into that of type pointed to. */
+ type = build_pointer_type (TREE_TYPE (type));
+ type_quals = TYPE_UNQUALIFIED;
+ }
+ else if (TREE_CODE (type) == FUNCTION_TYPE)
+ type = build_pointer_type (type);
+ }
+
+ if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
+ && !NEW_DELETE_OPNAME_P (unqualified_id))
+ {
+ cp_cv_quals real_quals = memfn_quals;
+ if (constexpr_p && sfk != sfk_constructor && sfk != sfk_destructor)
+ real_quals |= TYPE_QUAL_CONST;
+ type = build_memfn_type (type, ctype, real_quals, rqual);
+ }
+
+ {
+ tree decl;
+
+ if (decl_context == PARM)
+ {
+ decl = cp_build_parm_decl (unqualified_id, type);
+
+ bad_specifiers (decl, BSP_PARM, virtualp,
+ memfn_quals != TYPE_UNQUALIFIED,
+ inlinep, friendp, raises != NULL_TREE);
+ }
+ else if (decl_context == FIELD)
+ {
+ if (!staticp && TREE_CODE (type) != METHOD_TYPE
+ && type_uses_auto (type))
+ {
+ error ("non-static data member declared %<auto%>");
+ type = error_mark_node;
+ }
+
+ /* The C99 flexible array extension. */
+ if (!staticp && TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_DOMAIN (type) == NULL_TREE)
+ {
+ tree itype = compute_array_index_type (dname, integer_zero_node,
+ tf_warning_or_error);
+ type = build_cplus_array_type (TREE_TYPE (type), itype);
+ }
+
+ if (type == error_mark_node)
+ {
+ /* Happens when declaring arrays of sizes which
+ are error_mark_node, for example. */
+ decl = NULL_TREE;
+ }
+ else if (in_namespace && !friendp)
+ {
+ /* Something like struct S { int N::j; }; */
+ error ("invalid use of %<::%>");
+ return error_mark_node;
+ }
+ else if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
+ {
+ int publicp = 0;
+ tree function_context;
+
+ if (friendp == 0)
+ {
+ /* This should never happen in pure C++ (the check
+ could be an assert). It could happen in
+ Objective-C++ if someone writes invalid code that
+ uses a function declaration for an instance
+ variable or property (instance variables and
+ properties are parsed as FIELD_DECLs, but they are
+ part of an Objective-C class, not a C++ class).
+ That code is invalid and is caught by this
+ check. */
+ if (!ctype)
+ {
+ error ("declaration of function %qD in invalid context",
+ unqualified_id);
+ return error_mark_node;
+ }
+
+ /* ``A union may [ ... ] not [ have ] virtual functions.''
+ ARM 9.5 */
+ if (virtualp && TREE_CODE (ctype) == UNION_TYPE)
+ {
+ error ("function %qD declared virtual inside a union",
+ unqualified_id);
+ return error_mark_node;
+ }
+
+ if (NEW_DELETE_OPNAME_P (unqualified_id))
+ {
+ if (virtualp)
+ {
+ error ("%qD cannot be declared virtual, since it "
+ "is always static",
+ unqualified_id);
+ virtualp = 0;
+ }
+ }
+ }
+
+ /* Check that the name used for a destructor makes sense. */
+ if (sfk == sfk_destructor)
+ {
+ tree uqname = id_declarator->u.id.unqualified_name;
+
+ if (!ctype)
+ {
+ gcc_assert (friendp);
+ error ("expected qualified name in friend declaration "
+ "for destructor %qD", uqname);
+ return error_mark_node;
+ }
+
+ if (!check_dtor_name (ctype, TREE_OPERAND (uqname, 0)))
+ {
+ error ("declaration of %qD as member of %qT",
+ uqname, ctype);
+ return error_mark_node;
+ }
+ if (constexpr_p)
+ {
+ error ("a destructor cannot be %<constexpr%>");
+ return error_mark_node;
+ }
+ }
+ else if (sfk == sfk_constructor && friendp && !ctype)
+ {
+ error ("expected qualified name in friend declaration "
+ "for constructor %qD",
+ id_declarator->u.id.unqualified_name);
+ return error_mark_node;
+ }
+
+ /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */
+ function_context = (ctype != NULL_TREE) ?
+ decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
+ publicp = (! friendp || ! staticp)
+ && function_context == NULL_TREE;
+ decl = grokfndecl (ctype, type,
+ TREE_CODE (unqualified_id) != TEMPLATE_ID_EXPR
+ ? unqualified_id : dname,
+ parms,
+ unqualified_id,
+ virtualp, flags, memfn_quals, rqual, raises,
+ friendp ? -1 : 0, friendp, publicp,
+ inlinep | (2 * constexpr_p),
+ sfk,
+ funcdef_flag, template_count, in_namespace,
+ attrlist, declarator->id_loc);
+ decl = set_virt_specifiers (decl, virt_specifiers);
+ if (decl == NULL_TREE)
+ return error_mark_node;
+#if 0
+ /* This clobbers the attrs stored in `decl' from `attrlist'. */
+ /* The decl and setting of decl_attr is also turned off. */
+ decl = build_decl_attribute_variant (decl, decl_attr);
+#endif
+
+ /* [class.conv.ctor]
+
+ A constructor declared without the function-specifier
+ explicit that can be called with a single parameter
+ specifies a conversion from the type of its first
+ parameter to the type of its class. Such a constructor
+ is called a converting constructor. */
+ if (explicitp == 2)
+ DECL_NONCONVERTING_P (decl) = 1;
+ }
+ else if (!staticp && !dependent_type_p (type)
+ && !COMPLETE_TYPE_P (complete_type (type))
+ && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
+ {
+ if (unqualified_id)
+ error ("field %qD has incomplete type %qT",
+ unqualified_id, type);
+ else
+ error ("name %qT has incomplete type", type);
+
+ type = error_mark_node;
+ decl = NULL_TREE;
+ }
+ else
+ {
+ if (friendp)
+ {
+ error ("%qE is neither function nor member function; "
+ "cannot be declared friend", unqualified_id);
+ friendp = 0;
+ }
+ decl = NULL_TREE;
+ }
+
+ if (friendp)
+ {
+ /* Friends are treated specially. */
+ if (ctype == current_class_type)
+ ; /* We already issued a permerror. */
+ else if (decl && DECL_NAME (decl))
+ {
+ if (template_class_depth (current_class_type) == 0)
+ {
+ decl = check_explicit_specialization
+ (unqualified_id, decl, template_count,
+ 2 * funcdef_flag + 4);
+ if (decl == error_mark_node)
+ return error_mark_node;
+ }
+
+ decl = do_friend (ctype, unqualified_id, decl,
+ *attrlist, flags,
+ funcdef_flag);
+ return decl;
+ }
+ else
+ return error_mark_node;
+ }
+
+ /* Structure field. It may not be a function, except for C++. */
+
+ if (decl == NULL_TREE)
+ {
+ if (staticp)
+ {
+ /* C++ allows static class members. All other work
+ for this is done by grokfield. */
+ decl = build_lang_decl_loc (declarator
+ ? declarator->id_loc
+ : input_location,
+ VAR_DECL, unqualified_id, type);
+ set_linkage_for_static_data_member (decl);
+ /* Even if there is an in-class initialization, DECL
+ is considered undefined until an out-of-class
+ definition is provided. */
+ DECL_EXTERNAL (decl) = 1;
+
+ if (thread_p)
+ {
+ DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+ if (declspecs->gnu_thread_keyword_p)
+ DECL_GNU_TLS_P (decl) = true;
+ }
+
+ if (constexpr_p && !initialized)
+ {
+ error ("constexpr static data member %qD must have an "
+ "initializer", decl);
+ constexpr_p = false;
+ }
+ }
+ else
+ {
+ if (constexpr_p)
+ {
+ error ("non-static data member %qE declared %<constexpr%>",
+ unqualified_id);
+ constexpr_p = false;
+ }
+ decl = build_decl (input_location,
+ FIELD_DECL, unqualified_id, type);
+ DECL_NONADDRESSABLE_P (decl) = bitfield;
+ if (bitfield && !unqualified_id)
+ TREE_NO_WARNING (decl) = 1;
+
+ if (storage_class == sc_mutable)
+ {
+ DECL_MUTABLE_P (decl) = 1;
+ storage_class = sc_none;
+ }
+
+ if (initialized)
+ {
+ /* An attempt is being made to initialize a non-static
+ member. This is new in C++11. */
+ maybe_warn_cpp0x (CPP0X_NSDMI);
+
+ /* If this has been parsed with static storage class, but
+ errors forced staticp to be cleared, ensure NSDMI is
+ not present. */
+ if (declspecs->storage_class == sc_static)
+ DECL_INITIAL (decl) = error_mark_node;
+ }
+ }
+
+ bad_specifiers (decl, BSP_FIELD, virtualp,
+ memfn_quals != TYPE_UNQUALIFIED,
+ inlinep, friendp, raises != NULL_TREE);
+ }
+ }
+ else if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
+ {
+ tree original_name;
+ int publicp = 0;
+
+ if (!unqualified_id)
+ return error_mark_node;
+
+ if (TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR)
+ original_name = dname;
+ else
+ original_name = unqualified_id;
+
+ if (storage_class == sc_auto)
+ error ("storage class %<auto%> invalid for function %qs", name);
+ else if (storage_class == sc_register)
+ error ("storage class %<register%> invalid for function %qs", name);
+ else if (thread_p)
+ {
+ if (declspecs->gnu_thread_keyword_p)
+ error ("storage class %<__thread%> invalid for function %qs",
+ name);
+ else
+ error ("storage class %<thread_local%> invalid for function %qs",
+ name);
+ }
+
+ if (virt_specifiers)
+ error ("virt-specifiers in %qs not allowed outside a class definition", name);
+ /* Function declaration not at top level.
+ Storage classes other than `extern' are not allowed
+ and `extern' makes no difference. */
+ if (! toplevel_bindings_p ()
+ && (storage_class == sc_static
+ || decl_spec_seq_has_spec_p (declspecs, ds_inline))
+ && pedantic)
+ {
+ if (storage_class == sc_static)
+ pedwarn (input_location, OPT_Wpedantic,
+ "%<static%> specified invalid for function %qs "
+ "declared out of global scope", name);
+ else
+ pedwarn (input_location, OPT_Wpedantic,
+ "%<inline%> specifier invalid for function %qs "
+ "declared out of global scope", name);
+ }
+
+ if (ctype == NULL_TREE)
+ {
+ if (virtualp)
+ {
+ error ("virtual non-class function %qs", name);
+ virtualp = 0;
+ }
+ else if (sfk == sfk_constructor
+ || sfk == sfk_destructor)
+ {
+ error (funcdef_flag
+ ? G_("%qs defined in a non-class scope")
+ : G_("%qs declared in a non-class scope"), name);
+ sfk = sfk_none;
+ }
+ }
+
+ /* Record whether the function is public. */
+ publicp = (ctype != NULL_TREE
+ || storage_class != sc_static);
+
+ decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
+ virtualp, flags, memfn_quals, rqual, raises,
+ 1, friendp,
+ publicp, inlinep | (2 * constexpr_p), sfk,
+ funcdef_flag,
+ template_count, in_namespace, attrlist,
+ declarator->id_loc);
+ if (decl == NULL_TREE)
+ return error_mark_node;
+
+ if (staticp == 1)
+ {
+ int invalid_static = 0;
+
+ /* Don't allow a static member function in a class, and forbid
+ declaring main to be static. */
+ if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ permerror (input_location, "cannot declare member function %qD to have "
+ "static linkage", decl);
+ invalid_static = 1;
+ }
+ else if (current_function_decl)
+ {
+ /* FIXME need arm citation */
+ error ("cannot declare static function inside another function");
+ invalid_static = 1;
+ }
+
+ if (invalid_static)
+ {
+ staticp = 0;
+ storage_class = sc_none;
+ }
+ }
+ }
+ else
+ {
+ /* It's a variable. */
+
+ /* An uninitialized decl with `extern' is a reference. */
+ decl = grokvardecl (type, unqualified_id,
+ declspecs,
+ initialized,
+ (type_quals & TYPE_QUAL_CONST) != 0,
+ ctype ? ctype : in_namespace);
+ bad_specifiers (decl, BSP_VAR, virtualp,
+ memfn_quals != TYPE_UNQUALIFIED,
+ inlinep, friendp, raises != NULL_TREE);
+
+ if (ctype)
+ {
+ DECL_CONTEXT (decl) = ctype;
+ if (staticp == 1)
+ {
+ permerror (input_location, "%<static%> may not be used when defining "
+ "(as opposed to declaring) a static data member");
+ staticp = 0;
+ storage_class = sc_none;
+ }
+ if (storage_class == sc_register && TREE_STATIC (decl))
+ {
+ error ("static member %qD declared %<register%>", decl);
+ storage_class = sc_none;
+ }
+ if (storage_class == sc_extern && pedantic)
+ {
+ pedwarn (input_location, OPT_Wpedantic,
+ "cannot explicitly declare member %q#D to have "
+ "extern linkage", decl);
+ storage_class = sc_none;
+ }
+ }
+ else if (constexpr_p && DECL_EXTERNAL (decl))
+ {
+ error ("declaration of constexpr variable %qD is not a definition",
+ decl);
+ constexpr_p = false;
+ }
+ }
+
+ if (storage_class == sc_extern && initialized && !funcdef_flag)
+ {
+ if (toplevel_bindings_p ())
+ {
+ /* It's common practice (and completely valid) to have a const
+ be initialized and declared extern. */
+ if (!(type_quals & TYPE_QUAL_CONST))
+ warning (0, "%qs initialized and declared %<extern%>", name);
+ }
+ else
+ {
+ error ("%qs has both %<extern%> and initializer", name);
+ return error_mark_node;
+ }
+ }
+
+ /* Record `register' declaration for warnings on &
+ and in case doing stupid register allocation. */
+
+ if (storage_class == sc_register)
+ DECL_REGISTER (decl) = 1;
+ else if (storage_class == sc_extern)
+ DECL_THIS_EXTERN (decl) = 1;
+ else if (storage_class == sc_static)
+ DECL_THIS_STATIC (decl) = 1;
+
+ /* Set constexpr flag on vars (functions got it in grokfndecl). */
+ if (constexpr_p && VAR_P (decl))
+ DECL_DECLARED_CONSTEXPR_P (decl) = true;
+
+ /* Record constancy and volatility on the DECL itself . There's
+ no need to do this when processing a template; we'll do this
+ for the instantiated declaration based on the type of DECL. */
+ if (!processing_template_decl)
+ cp_apply_type_quals_to_decl (type_quals, decl);
+
+ return decl;
+ }
+}
+
+/* Subroutine of start_function. Ensure that each of the parameter
+ types (as listed in PARMS) is complete, as is required for a
+ function definition. */
+
+static void
+require_complete_types_for_parms (tree parms)
+{
+ for (; parms; parms = DECL_CHAIN (parms))
+ {
+ if (dependent_type_p (TREE_TYPE (parms)))
+ continue;
+ if (!VOID_TYPE_P (TREE_TYPE (parms))
+ && complete_type_or_else (TREE_TYPE (parms), parms))
+ {
+ relayout_decl (parms);
+ DECL_ARG_TYPE (parms) = type_passed_as (TREE_TYPE (parms));
+ }
+ else
+ /* grokparms or complete_type_or_else will have already issued
+ an error. */
+ TREE_TYPE (parms) = error_mark_node;
+ }
+}
+
+/* Returns nonzero if T is a local variable. */
+
+int
+local_variable_p (const_tree t)
+{
+ if ((VAR_P (t)
+ /* A VAR_DECL with a context that is a _TYPE is a static data
+ member. */
+ && !TYPE_P (CP_DECL_CONTEXT (t))
+ /* Any other non-local variable must be at namespace scope. */
+ && !DECL_NAMESPACE_SCOPE_P (t))
+ || (TREE_CODE (t) == PARM_DECL))
+ return 1;
+
+ return 0;
+}
+
+/* Like local_variable_p, but suitable for use as a tree-walking
+ function. */
+
+static tree
+local_variable_p_walkfn (tree *tp, int *walk_subtrees,
+ void * /*data*/)
+{
+ if (local_variable_p (*tp)
+ && (!DECL_ARTIFICIAL (*tp) || DECL_NAME (*tp) == this_identifier))
+ return *tp;
+ else if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+
+ return NULL_TREE;
+}
+
+/* Check that ARG, which is a default-argument expression for a
+ parameter DECL, is valid. Returns ARG, or ERROR_MARK_NODE, if
+ something goes wrong. DECL may also be a _TYPE node, rather than a
+ DECL, if there is no DECL available. */
+
+tree
+check_default_argument (tree decl, tree arg, tsubst_flags_t complain)
+{
+ tree var;
+ tree decl_type;
+
+ if (TREE_CODE (arg) == DEFAULT_ARG)
+ /* We get a DEFAULT_ARG when looking at an in-class declaration
+ with a default argument. Ignore the argument for now; we'll
+ deal with it after the class is complete. */
+ return arg;
+
+ if (TYPE_P (decl))
+ {
+ decl_type = decl;
+ decl = NULL_TREE;
+ }
+ else
+ decl_type = TREE_TYPE (decl);
+
+ if (arg == error_mark_node
+ || decl == error_mark_node
+ || TREE_TYPE (arg) == error_mark_node
+ || decl_type == error_mark_node)
+ /* Something already went wrong. There's no need to check
+ further. */
+ return error_mark_node;
+
+ /* [dcl.fct.default]
+
+ A default argument expression is implicitly converted to the
+ parameter type. */
+ ++cp_unevaluated_operand;
+ perform_implicit_conversion_flags (decl_type, arg, complain,
+ LOOKUP_IMPLICIT);
+ --cp_unevaluated_operand;
+
+ if (warn_zero_as_null_pointer_constant
+ && TYPE_PTR_OR_PTRMEM_P (decl_type)
+ && null_ptr_cst_p (arg)
+ && (complain & tf_warning)
+ && maybe_warn_zero_as_null_pointer_constant (arg, input_location))
+ return nullptr_node;
+
+ /* [dcl.fct.default]
+
+ Local variables shall not be used in default argument
+ expressions.
+
+ The keyword `this' shall not be used in a default argument of a
+ member function. */
+ var = cp_walk_tree_without_duplicates (&arg, local_variable_p_walkfn, NULL);
+ if (var)
+ {
+ if (complain & tf_warning_or_error)
+ {
+ if (DECL_NAME (var) == this_identifier)
+ permerror (input_location, "default argument %qE uses %qD",
+ arg, var);
+ else
+ error ("default argument %qE uses local variable %qD", arg, var);
+ }
+ return error_mark_node;
+ }
+
+ /* All is well. */
+ return arg;
+}
+
+/* Returns a deprecated type used within TYPE, or NULL_TREE if none. */
+
+static tree
+type_is_deprecated (tree type)
+{
+ enum tree_code code;
+ if (TREE_DEPRECATED (type))
+ return type;
+ if (TYPE_NAME (type)
+ && TREE_DEPRECATED (TYPE_NAME (type)))
+ return type;
+
+ /* Do warn about using typedefs to a deprecated class. */
+ if (OVERLOAD_TYPE_P (type) && type != TYPE_MAIN_VARIANT (type))
+ return type_is_deprecated (TYPE_MAIN_VARIANT (type));
+
+ code = TREE_CODE (type);
+
+ if (code == POINTER_TYPE || code == REFERENCE_TYPE
+ || code == OFFSET_TYPE || code == FUNCTION_TYPE
+ || code == METHOD_TYPE || code == ARRAY_TYPE)
+ return type_is_deprecated (TREE_TYPE (type));
+
+ if (TYPE_PTRMEMFUNC_P (type))
+ return type_is_deprecated
+ (TREE_TYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type))));
+
+ return NULL_TREE;
+}
+
+/* Decode the list of parameter types for a function type.
+ Given the list of things declared inside the parens,
+ return a list of types.
+
+ If this parameter does not end with an ellipsis, we append
+ void_list_node.
+
+ *PARMS is set to the chain of PARM_DECLs created. */
+
+static tree
+grokparms (tree parmlist, tree *parms)
+{
+ tree result = NULL_TREE;
+ tree decls = NULL_TREE;
+ tree parm;
+ int any_error = 0;
+
+ for (parm = parmlist; parm != NULL_TREE; parm = TREE_CHAIN (parm))
+ {
+ tree type = NULL_TREE;
+ tree init = TREE_PURPOSE (parm);
+ tree decl = TREE_VALUE (parm);
+ const char *errmsg;
+
+ if (parm == void_list_node)
+ break;
+
+ if (! decl || TREE_TYPE (decl) == error_mark_node)
+ continue;
+
+ type = TREE_TYPE (decl);
+ if (VOID_TYPE_P (type))
+ {
+ if (same_type_p (type, void_type_node)
+ && DECL_SELF_REFERENCE_P (type)
+ && !DECL_NAME (decl) && !result && TREE_CHAIN (parm) == void_list_node)
+ /* this is a parmlist of `(void)', which is ok. */
+ break;
+ cxx_incomplete_type_error (decl, type);
+ /* It's not a good idea to actually create parameters of
+ type `void'; other parts of the compiler assume that a
+ void type terminates the parameter list. */
+ type = error_mark_node;
+ TREE_TYPE (decl) = error_mark_node;
+ }
+
+ if (type != error_mark_node
+ && TYPE_FOR_JAVA (type)
+ && MAYBE_CLASS_TYPE_P (type))
+ {
+ error ("parameter %qD has Java class type", decl);
+ type = error_mark_node;
+ TREE_TYPE (decl) = error_mark_node;
+ init = NULL_TREE;
+ }
+
+ if (type != error_mark_node
+ && (errmsg = targetm.invalid_parameter_type (type)))
+ {
+ error (errmsg);
+ type = error_mark_node;
+ TREE_TYPE (decl) = error_mark_node;
+ }
+
+ if (type != error_mark_node)
+ {
+ if (deprecated_state != DEPRECATED_SUPPRESS)
+ {
+ tree deptype = type_is_deprecated (type);
+ if (deptype)
+ warn_deprecated_use (deptype, NULL_TREE);
+ }
+
+ /* Top-level qualifiers on the parameters are
+ ignored for function types. */
+ type = cp_build_qualified_type (type, 0);
+ if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ error ("parameter %qD invalidly declared method type", decl);
+ type = build_pointer_type (type);
+ TREE_TYPE (decl) = type;
+ }
+ else if (abstract_virtuals_error (decl, type))
+ any_error = 1; /* Seems like a good idea. */
+ else if (POINTER_TYPE_P (type))
+ {
+ /* [dcl.fct]/6, parameter types cannot contain pointers
+ (references) to arrays of unknown bound. */
+ tree t = TREE_TYPE (type);
+ int ptr = TYPE_PTR_P (type);
+
+ while (1)
+ {
+ if (TYPE_PTR_P (t))
+ ptr = 1;
+ else if (TREE_CODE (t) != ARRAY_TYPE)
+ break;
+ else if (!TYPE_DOMAIN (t))
+ break;
+ t = TREE_TYPE (t);
+ }
+ if (TREE_CODE (t) == ARRAY_TYPE)
+ error (ptr
+ ? G_("parameter %qD includes pointer to array of "
+ "unknown bound %qT")
+ : G_("parameter %qD includes reference to array of "
+ "unknown bound %qT"),
+ decl, t);
+ }
+
+ if (any_error)
+ init = NULL_TREE;
+ else if (init && !processing_template_decl)
+ init = check_default_argument (decl, init, tf_warning_or_error);
+ }
+
+ DECL_CHAIN (decl) = decls;
+ decls = decl;
+ result = tree_cons (init, type, result);
+ }
+ decls = nreverse (decls);
+ result = nreverse (result);
+ if (parm)
+ result = chainon (result, void_list_node);
+ *parms = decls;
+
+ return result;
+}
+
+
+/* D is a constructor or overloaded `operator='.
+
+ Let T be the class in which D is declared. Then, this function
+ returns:
+
+ -1 if D's is an ill-formed constructor or copy assignment operator
+ whose first parameter is of type `T'.
+ 0 if D is not a copy constructor or copy assignment
+ operator.
+ 1 if D is a copy constructor or copy assignment operator whose
+ first parameter is a reference to non-const qualified T.
+ 2 if D is a copy constructor or copy assignment operator whose
+ first parameter is a reference to const qualified T.
+
+ This function can be used as a predicate. Positive values indicate
+ a copy constructor and nonzero values indicate a copy assignment
+ operator. */
+
+int
+copy_fn_p (const_tree d)
+{
+ tree args;
+ tree arg_type;
+ int result = 1;
+
+ gcc_assert (DECL_FUNCTION_MEMBER_P (d));
+
+ if (TREE_CODE (d) == TEMPLATE_DECL
+ || (DECL_TEMPLATE_INFO (d)
+ && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))))
+ /* Instantiations of template member functions are never copy
+ functions. Note that member functions of templated classes are
+ represented as template functions internally, and we must
+ accept those as copy functions. */
+ return 0;
+
+ args = FUNCTION_FIRST_USER_PARMTYPE (d);
+ if (!args)
+ return 0;
+
+ arg_type = TREE_VALUE (args);
+ if (arg_type == error_mark_node)
+ return 0;
+
+ if (TYPE_MAIN_VARIANT (arg_type) == DECL_CONTEXT (d))
+ {
+ /* Pass by value copy assignment operator. */
+ result = -1;
+ }
+ else if (TREE_CODE (arg_type) == REFERENCE_TYPE
+ && !TYPE_REF_IS_RVALUE (arg_type)
+ && TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)) == DECL_CONTEXT (d))
+ {
+ if (CP_TYPE_CONST_P (TREE_TYPE (arg_type)))
+ result = 2;
+ }
+ else
+ return 0;
+
+ args = TREE_CHAIN (args);
+
+ if (args && args != void_list_node && !TREE_PURPOSE (args))
+ /* There are more non-optional args. */
+ return 0;
+
+ return result;
+}
+
+/* D is a constructor or overloaded `operator='.
+
+ Let T be the class in which D is declared. Then, this function
+ returns true when D is a move constructor or move assignment
+ operator, false otherwise. */
+
+bool
+move_fn_p (const_tree d)
+{
+ gcc_assert (DECL_FUNCTION_MEMBER_P (d));
+
+ if (cxx_dialect == cxx98)
+ /* There are no move constructors if we are in C++98 mode. */
+ return false;
+
+ if (TREE_CODE (d) == TEMPLATE_DECL
+ || (DECL_TEMPLATE_INFO (d)
+ && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))))
+ /* Instantiations of template member functions are never move
+ functions. Note that member functions of templated classes are
+ represented as template functions internally, and we must
+ accept those as move functions. */
+ return 0;
+
+ return move_signature_fn_p (d);
+}
+
+/* D is a constructor or overloaded `operator='.
+
+ Then, this function returns true when D has the same signature as a move
+ constructor or move assignment operator (because either it is such a
+ ctor/op= or it is a template specialization with the same signature),
+ false otherwise. */
+
+bool
+move_signature_fn_p (const_tree d)
+{
+ tree args;
+ tree arg_type;
+ bool result = false;
+
+ args = FUNCTION_FIRST_USER_PARMTYPE (d);
+ if (!args)
+ return 0;
+
+ arg_type = TREE_VALUE (args);
+ if (arg_type == error_mark_node)
+ return 0;
+
+ if (TREE_CODE (arg_type) == REFERENCE_TYPE
+ && TYPE_REF_IS_RVALUE (arg_type)
+ && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)),
+ DECL_CONTEXT (d)))
+ result = true;
+
+ args = TREE_CHAIN (args);
+
+ if (args && args != void_list_node && !TREE_PURPOSE (args))
+ /* There are more non-optional args. */
+ return false;
+
+ return result;
+}
+
+/* Remember any special properties of member function DECL. */
+
+void
+grok_special_member_properties (tree decl)
+{
+ tree class_type;
+
+ if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ return;
+
+ class_type = DECL_CONTEXT (decl);
+ if (DECL_CONSTRUCTOR_P (decl))
+ {
+ int ctor = copy_fn_p (decl);
+
+ if (!DECL_ARTIFICIAL (decl))
+ TYPE_HAS_USER_CONSTRUCTOR (class_type) = 1;
+
+ if (ctor > 0)
+ {
+ /* [class.copy]
+
+ A non-template constructor for class X is a copy
+ constructor if its first parameter is of type X&, const
+ X&, volatile X& or const volatile X&, and either there
+ are no other parameters or else all other parameters have
+ default arguments. */
+ TYPE_HAS_COPY_CTOR (class_type) = 1;
+ if (user_provided_p (decl))
+ TYPE_HAS_COMPLEX_COPY_CTOR (class_type) = 1;
+ if (ctor > 1)
+ TYPE_HAS_CONST_COPY_CTOR (class_type) = 1;
+ }
+ else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
+ {
+ TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
+ if (user_provided_p (decl))
+ TYPE_HAS_COMPLEX_DFLT (class_type) = 1;
+ }
+ else if (move_fn_p (decl) && user_provided_p (decl))
+ TYPE_HAS_COMPLEX_MOVE_CTOR (class_type) = 1;
+ else if (is_list_ctor (decl))
+ TYPE_HAS_LIST_CTOR (class_type) = 1;
+
+ if (DECL_DECLARED_CONSTEXPR_P (decl)
+ && !copy_fn_p (decl) && !move_fn_p (decl))
+ TYPE_HAS_CONSTEXPR_CTOR (class_type) = 1;
+ }
+ else if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
+ {
+ /* [class.copy]
+
+ A non-template assignment operator for class X is a copy
+ assignment operator if its parameter is of type X, X&, const
+ X&, volatile X& or const volatile X&. */
+
+ int assop = copy_fn_p (decl);
+
+ if (assop)
+ {
+ TYPE_HAS_COPY_ASSIGN (class_type) = 1;
+ if (user_provided_p (decl))
+ TYPE_HAS_COMPLEX_COPY_ASSIGN (class_type) = 1;
+ if (assop != 1)
+ TYPE_HAS_CONST_COPY_ASSIGN (class_type) = 1;
+ }
+ else if (move_fn_p (decl) && user_provided_p (decl))
+ TYPE_HAS_COMPLEX_MOVE_ASSIGN (class_type) = 1;
+ }
+ /* Destructors are handled in check_methods. */
+}
+
+/* Check a constructor DECL has the correct form. Complains
+ if the class has a constructor of the form X(X). */
+
+int
+grok_ctor_properties (const_tree ctype, const_tree decl)
+{
+ int ctor_parm = copy_fn_p (decl);
+
+ if (ctor_parm < 0)
+ {
+ /* [class.copy]
+
+ A declaration of a constructor for a class X is ill-formed if
+ its first parameter is of type (optionally cv-qualified) X
+ and either there are no other parameters or else all other
+ parameters have default arguments.
+
+ We *don't* complain about member template instantiations that
+ have this form, though; they can occur as we try to decide
+ what constructor to use during overload resolution. Since
+ overload resolution will never prefer such a constructor to
+ the non-template copy constructor (which is either explicitly
+ or implicitly defined), there's no need to worry about their
+ existence. Theoretically, they should never even be
+ instantiated, but that's hard to forestall. */
+ error ("invalid constructor; you probably meant %<%T (const %T&)%>",
+ ctype, ctype);
+ return 0;
+ }
+
+ return 1;
+}
+
+/* An operator with this code is unary, but can also be binary. */
+
+static int
+ambi_op_p (enum tree_code code)
+{
+ return (code == INDIRECT_REF
+ || code == ADDR_EXPR
+ || code == UNARY_PLUS_EXPR
+ || code == NEGATE_EXPR
+ || code == PREINCREMENT_EXPR
+ || code == PREDECREMENT_EXPR);
+}
+
+/* An operator with this name can only be unary. */
+
+static int
+unary_op_p (enum tree_code code)
+{
+ return (code == TRUTH_NOT_EXPR
+ || code == BIT_NOT_EXPR
+ || code == COMPONENT_REF
+ || code == TYPE_EXPR);
+}
+
+/* DECL is a declaration for an overloaded operator. If COMPLAIN is true,
+ errors are issued for invalid declarations. */
+
+bool
+grok_op_properties (tree decl, bool complain)
+{
+ tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ tree argtype;
+ int methodp = (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
+ tree name = DECL_NAME (decl);
+ enum tree_code operator_code;
+ int arity;
+ bool ellipsis_p;
+ tree class_type;
+
+ /* Count the number of arguments and check for ellipsis. */
+ for (argtype = argtypes, arity = 0;
+ argtype && argtype != void_list_node;
+ argtype = TREE_CHAIN (argtype))
+ ++arity;
+ ellipsis_p = !argtype;
+
+ class_type = DECL_CONTEXT (decl);
+ if (class_type && !CLASS_TYPE_P (class_type))
+ class_type = NULL_TREE;
+
+ if (DECL_CONV_FN_P (decl))
+ operator_code = TYPE_EXPR;
+ else
+ do
+ {
+#define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, ASSN_P) \
+ if (ansi_opname (CODE) == name) \
+ { \
+ operator_code = (CODE); \
+ break; \
+ } \
+ else if (ansi_assopname (CODE) == name) \
+ { \
+ operator_code = (CODE); \
+ DECL_ASSIGNMENT_OPERATOR_P (decl) = 1; \
+ break; \
+ }
+
+#include "operators.def"
+#undef DEF_OPERATOR
+
+ gcc_unreachable ();
+ }
+ while (0);
+ gcc_assert (operator_code != MAX_TREE_CODES);
+ SET_OVERLOADED_OPERATOR_CODE (decl, operator_code);
+
+ if (class_type)
+ switch (operator_code)
+ {
+ case NEW_EXPR:
+ TYPE_HAS_NEW_OPERATOR (class_type) = 1;
+ break;
+
+ case DELETE_EXPR:
+ TYPE_GETS_DELETE (class_type) |= 1;
+ break;
+
+ case VEC_NEW_EXPR:
+ TYPE_HAS_ARRAY_NEW_OPERATOR (class_type) = 1;
+ break;
+
+ case VEC_DELETE_EXPR:
+ TYPE_GETS_DELETE (class_type) |= 2;
+ break;
+
+ default:
+ break;
+ }
+
+ /* [basic.std.dynamic.allocation]/1:
+
+ A program is ill-formed if an allocation function is declared
+ in a namespace scope other than global scope or declared static
+ in global scope.
+
+ The same also holds true for deallocation functions. */
+ if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR
+ || operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
+ {
+ if (DECL_NAMESPACE_SCOPE_P (decl))
+ {
+ if (CP_DECL_CONTEXT (decl) != global_namespace)
+ {
+ error ("%qD may not be declared within a namespace", decl);
+ return false;
+ }
+ else if (!TREE_PUBLIC (decl))
+ {
+ error ("%qD may not be declared as static", decl);
+ return false;
+ }
+ }
+ }
+
+ if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR)
+ {
+ TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
+ DECL_IS_OPERATOR_NEW (decl) = 1;
+ }
+ else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
+ TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
+ else
+ {
+ /* An operator function must either be a non-static member function
+ or have at least one parameter of a class, a reference to a class,
+ an enumeration, or a reference to an enumeration. 13.4.0.6 */
+ if (! methodp || DECL_STATIC_FUNCTION_P (decl))
+ {
+ if (operator_code == TYPE_EXPR
+ || operator_code == CALL_EXPR
+ || operator_code == COMPONENT_REF
+ || operator_code == ARRAY_REF
+ || operator_code == NOP_EXPR)
+ {
+ error ("%qD must be a nonstatic member function", decl);
+ return false;
+ }
+ else
+ {
+ tree p;
+
+ if (DECL_STATIC_FUNCTION_P (decl))
+ {
+ error ("%qD must be either a non-static member "
+ "function or a non-member function", decl);
+ return false;
+ }
+
+ for (p = argtypes; p && p != void_list_node; p = TREE_CHAIN (p))
+ {
+ tree arg = non_reference (TREE_VALUE (p));
+ if (arg == error_mark_node)
+ return false;
+
+ /* MAYBE_CLASS_TYPE_P, rather than CLASS_TYPE_P, is used
+ because these checks are performed even on
+ template functions. */
+ if (MAYBE_CLASS_TYPE_P (arg)
+ || TREE_CODE (arg) == ENUMERAL_TYPE)
+ break;
+ }
+
+ if (!p || p == void_list_node)
+ {
+ if (complain)
+ error ("%qD must have an argument of class or "
+ "enumerated type", decl);
+ return false;
+ }
+ }
+ }
+
+ /* There are no restrictions on the arguments to an overloaded
+ "operator ()". */
+ if (operator_code == CALL_EXPR)
+ return true;
+
+ /* Warn about conversion operators that will never be used. */
+ if (IDENTIFIER_TYPENAME_P (name)
+ && ! DECL_TEMPLATE_INFO (decl)
+ && warn_conversion
+ /* Warn only declaring the function; there is no need to
+ warn again about out-of-class definitions. */
+ && class_type == current_class_type)
+ {
+ tree t = TREE_TYPE (name);
+ int ref = (TREE_CODE (t) == REFERENCE_TYPE);
+
+ if (ref)
+ t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
+
+ if (VOID_TYPE_P (t))
+ warning (OPT_Wconversion,
+ ref
+ ? G_("conversion to a reference to void "
+ "will never use a type conversion operator")
+ : G_("conversion to void "
+ "will never use a type conversion operator"));
+ else if (class_type)
+ {
+ if (t == class_type)
+ warning (OPT_Wconversion,
+ ref
+ ? G_("conversion to a reference to the same type "
+ "will never use a type conversion operator")
+ : G_("conversion to the same type "
+ "will never use a type conversion operator"));
+ /* Don't force t to be complete here. */
+ else if (MAYBE_CLASS_TYPE_P (t)
+ && COMPLETE_TYPE_P (t)
+ && DERIVED_FROM_P (t, class_type))
+ warning (OPT_Wconversion,
+ ref
+ ? G_("conversion to a reference to a base class "
+ "will never use a type conversion operator")
+ : G_("conversion to a base class "
+ "will never use a type conversion operator"));
+ }
+
+ }
+
+ if (operator_code == COND_EXPR)
+ {
+ /* 13.4.0.3 */
+ error ("ISO C++ prohibits overloading operator ?:");
+ return false;
+ }
+ else if (ellipsis_p)
+ {
+ error ("%qD must not have variable number of arguments", decl);
+ return false;
+ }
+ else if (ambi_op_p (operator_code))
+ {
+ if (arity == 1)
+ /* We pick the one-argument operator codes by default, so
+ we don't have to change anything. */
+ ;
+ else if (arity == 2)
+ {
+ /* If we thought this was a unary operator, we now know
+ it to be a binary operator. */
+ switch (operator_code)
+ {
+ case INDIRECT_REF:
+ operator_code = MULT_EXPR;
+ break;
+
+ case ADDR_EXPR:
+ operator_code = BIT_AND_EXPR;
+ break;
+
+ case UNARY_PLUS_EXPR:
+ operator_code = PLUS_EXPR;
+ break;
+
+ case NEGATE_EXPR:
+ operator_code = MINUS_EXPR;
+ break;
+
+ case PREINCREMENT_EXPR:
+ operator_code = POSTINCREMENT_EXPR;
+ break;
+
+ case PREDECREMENT_EXPR:
+ operator_code = POSTDECREMENT_EXPR;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ SET_OVERLOADED_OPERATOR_CODE (decl, operator_code);
+
+ if ((operator_code == POSTINCREMENT_EXPR
+ || operator_code == POSTDECREMENT_EXPR)
+ && ! processing_template_decl
+ && ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)), integer_type_node))
+ {
+ if (methodp)
+ error ("postfix %qD must take %<int%> as its argument",
+ decl);
+ else
+ error ("postfix %qD must take %<int%> as its second "
+ "argument", decl);
+ return false;
+ }
+ }
+ else
+ {
+ if (methodp)
+ error ("%qD must take either zero or one argument", decl);
+ else
+ error ("%qD must take either one or two arguments", decl);
+ return false;
+ }
+
+ /* More Effective C++ rule 6. */
+ if (warn_ecpp
+ && (operator_code == POSTINCREMENT_EXPR
+ || operator_code == POSTDECREMENT_EXPR
+ || operator_code == PREINCREMENT_EXPR
+ || operator_code == PREDECREMENT_EXPR))
+ {
+ tree arg = TREE_VALUE (argtypes);
+ tree ret = TREE_TYPE (TREE_TYPE (decl));
+ if (methodp || TREE_CODE (arg) == REFERENCE_TYPE)
+ arg = TREE_TYPE (arg);
+ arg = TYPE_MAIN_VARIANT (arg);
+ if (operator_code == PREINCREMENT_EXPR
+ || operator_code == PREDECREMENT_EXPR)
+ {
+ if (TREE_CODE (ret) != REFERENCE_TYPE
+ || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)),
+ arg))
+ warning (OPT_Weffc__, "prefix %qD should return %qT", decl,
+ build_reference_type (arg));
+ }
+ else
+ {
+ if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg))
+ warning (OPT_Weffc__, "postfix %qD should return %qT", decl, arg);
+ }
+ }
+ }
+ else if (unary_op_p (operator_code))
+ {
+ if (arity != 1)
+ {
+ if (methodp)
+ error ("%qD must take %<void%>", decl);
+ else
+ error ("%qD must take exactly one argument", decl);
+ return false;
+ }
+ }
+ else /* if (binary_op_p (operator_code)) */
+ {
+ if (arity != 2)
+ {
+ if (methodp)
+ error ("%qD must take exactly one argument", decl);
+ else
+ error ("%qD must take exactly two arguments", decl);
+ return false;
+ }
+
+ /* More Effective C++ rule 7. */
+ if (warn_ecpp
+ && (operator_code == TRUTH_ANDIF_EXPR
+ || operator_code == TRUTH_ORIF_EXPR
+ || operator_code == COMPOUND_EXPR))
+ warning (OPT_Weffc__, "user-defined %qD always evaluates both arguments",
+ decl);
+ }
+
+ /* Effective C++ rule 23. */
+ if (warn_ecpp
+ && arity == 2
+ && !DECL_ASSIGNMENT_OPERATOR_P (decl)
+ && (operator_code == PLUS_EXPR
+ || operator_code == MINUS_EXPR
+ || operator_code == TRUNC_DIV_EXPR
+ || operator_code == MULT_EXPR
+ || operator_code == TRUNC_MOD_EXPR)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == REFERENCE_TYPE)
+ warning (OPT_Weffc__, "%qD should return by value", decl);
+
+ /* [over.oper]/8 */
+ for (; argtypes && argtypes != void_list_node;
+ argtypes = TREE_CHAIN (argtypes))
+ if (TREE_PURPOSE (argtypes))
+ {
+ TREE_PURPOSE (argtypes) = NULL_TREE;
+ if (operator_code == POSTINCREMENT_EXPR
+ || operator_code == POSTDECREMENT_EXPR)
+ {
+ pedwarn (input_location, OPT_Wpedantic, "%qD cannot have default arguments",
+ decl);
+ }
+ else
+ {
+ error ("%qD cannot have default arguments", decl);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/* Return a string giving the keyword associate with CODE. */
+
+static const char *
+tag_name (enum tag_types code)
+{
+ switch (code)
+ {
+ case record_type:
+ return "struct";
+ case class_type:
+ return "class";
+ case union_type:
+ return "union";
+ case enum_type:
+ return "enum";
+ case typename_type:
+ return "typename";
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Name lookup in an elaborated-type-specifier (after the keyword
+ indicated by TAG_CODE) has found the TYPE_DECL DECL. If the
+ elaborated-type-specifier is invalid, issue a diagnostic and return
+ error_mark_node; otherwise, return the *_TYPE to which it referred.
+ If ALLOW_TEMPLATE_P is true, TYPE may be a class template. */
+
+tree
+check_elaborated_type_specifier (enum tag_types tag_code,
+ tree decl,
+ bool allow_template_p)
+{
+ tree type;
+
+ /* In the case of:
+
+ struct S { struct S *p; };
+
+ name lookup will find the TYPE_DECL for the implicit "S::S"
+ typedef. Adjust for that here. */
+ if (DECL_SELF_REFERENCE_P (decl))
+ decl = TYPE_NAME (TREE_TYPE (decl));
+
+ type = TREE_TYPE (decl);
+
+ /* Check TEMPLATE_TYPE_PARM first because DECL_IMPLICIT_TYPEDEF_P
+ is false for this case as well. */
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+ {
+ error ("using template type parameter %qT after %qs",
+ type, tag_name (tag_code));
+ return error_mark_node;
+ }
+ /* Accept template template parameters. */
+ else if (allow_template_p
+ && (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM))
+ ;
+ /* [dcl.type.elab]
+
+ If the identifier resolves to a typedef-name or the
+ simple-template-id resolves to an alias template
+ specialization, the elaborated-type-specifier is ill-formed.
+
+ In other words, the only legitimate declaration to use in the
+ elaborated type specifier is the implicit typedef created when
+ the type is declared. */
+ else if (!DECL_IMPLICIT_TYPEDEF_P (decl)
+ && !DECL_SELF_REFERENCE_P (decl)
+ && tag_code != typename_type)
+ {
+ if (alias_template_specialization_p (type))
+ error ("using alias template specialization %qT after %qs",
+ type, tag_name (tag_code));
+ else
+ error ("using typedef-name %qD after %qs", decl, tag_name (tag_code));
+ inform (DECL_SOURCE_LOCATION (decl),
+ "%qD has a previous declaration here", decl);
+ return error_mark_node;
+ }
+ else if (TREE_CODE (type) != RECORD_TYPE
+ && TREE_CODE (type) != UNION_TYPE
+ && tag_code != enum_type
+ && tag_code != typename_type)
+ {
+ error ("%qT referred to as %qs", type, tag_name (tag_code));
+ inform (input_location, "%q+T has a previous declaration here", type);
+ return error_mark_node;
+ }
+ else if (TREE_CODE (type) != ENUMERAL_TYPE
+ && tag_code == enum_type)
+ {
+ error ("%qT referred to as enum", type);
+ inform (input_location, "%q+T has a previous declaration here", type);
+ return error_mark_node;
+ }
+ else if (!allow_template_p
+ && TREE_CODE (type) == RECORD_TYPE
+ && CLASSTYPE_IS_TEMPLATE (type))
+ {
+ /* If a class template appears as elaborated type specifier
+ without a template header such as:
+
+ template <class T> class C {};
+ void f(class C); // No template header here
+
+ then the required template argument is missing. */
+ error ("template argument required for %<%s %T%>",
+ tag_name (tag_code),
+ DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)));
+ return error_mark_node;
+ }
+
+ return type;
+}
+
+/* Lookup NAME in elaborate type specifier in scope according to
+ SCOPE and issue diagnostics if necessary.
+ Return *_TYPE node upon success, NULL_TREE when the NAME is not
+ found, and ERROR_MARK_NODE for type error. */
+
+static tree
+lookup_and_check_tag (enum tag_types tag_code, tree name,
+ tag_scope scope, bool template_header_p)
+{
+ tree t;
+ tree decl;
+ if (scope == ts_global)
+ {
+ /* First try ordinary name lookup, ignoring hidden class name
+ injected via friend declaration. */
+ decl = lookup_name_prefer_type (name, 2);
+ /* If that fails, the name will be placed in the smallest
+ non-class, non-function-prototype scope according to 3.3.1/5.
+ We may already have a hidden name declared as friend in this
+ scope. So lookup again but not ignoring hidden names.
+ If we find one, that name will be made visible rather than
+ creating a new tag. */
+ if (!decl)
+ decl = lookup_type_scope (name, ts_within_enclosing_non_class);
+ }
+ else
+ decl = lookup_type_scope (name, scope);
+
+ if (decl
+ && (DECL_CLASS_TEMPLATE_P (decl)
+ /* If scope is ts_current we're defining a class, so ignore a
+ template template parameter. */
+ || (scope != ts_current
+ && DECL_TEMPLATE_TEMPLATE_PARM_P (decl))))
+ decl = DECL_TEMPLATE_RESULT (decl);
+
+ if (decl && TREE_CODE (decl) == TYPE_DECL)
+ {
+ /* Look for invalid nested type:
+ class C {
+ class C {};
+ }; */
+ if (scope == ts_current && DECL_SELF_REFERENCE_P (decl))
+ {
+ error ("%qD has the same name as the class in which it is "
+ "declared",
+ decl);
+ return error_mark_node;
+ }
+
+ /* Two cases we need to consider when deciding if a class
+ template is allowed as an elaborated type specifier:
+ 1. It is a self reference to its own class.
+ 2. It comes with a template header.
+
+ For example:
+
+ template <class T> class C {
+ class C *c1; // DECL_SELF_REFERENCE_P is true
+ class D;
+ };
+ template <class U> class C; // template_header_p is true
+ template <class T> class C<T>::D {
+ class C *c2; // DECL_SELF_REFERENCE_P is true
+ }; */
+
+ t = check_elaborated_type_specifier (tag_code,
+ decl,
+ template_header_p
+ | DECL_SELF_REFERENCE_P (decl));
+ return t;
+ }
+ else if (decl && TREE_CODE (decl) == TREE_LIST)
+ {
+ error ("reference to %qD is ambiguous", name);
+ print_candidates (decl);
+ return error_mark_node;
+ }
+ else
+ return NULL_TREE;
+}
+
+/* Get the struct, enum or union (TAG_CODE says which) with tag NAME.
+ Define the tag as a forward-reference if it is not defined.
+
+ If a declaration is given, process it here, and report an error if
+ multiple declarations are not identical.
+
+ SCOPE is TS_CURRENT when this is also a definition. Only look in
+ the current frame for the name (since C++ allows new names in any
+ scope.) It is TS_WITHIN_ENCLOSING_NON_CLASS if this is a friend
+ declaration. Only look beginning from the current scope outward up
+ till the nearest non-class scope. Otherwise it is TS_GLOBAL.
+
+ TEMPLATE_HEADER_P is true when this declaration is preceded by
+ a set of template parameters. */
+
+static tree
+xref_tag_1 (enum tag_types tag_code, tree name,
+ tag_scope orig_scope, bool template_header_p)
+{
+ enum tree_code code;
+ tree t;
+ tree context = NULL_TREE;
+ tag_scope scope;
+
+ gcc_assert (identifier_p (name));
+
+ switch (tag_code)
+ {
+ case record_type:
+ case class_type:
+ code = RECORD_TYPE;
+ break;
+ case union_type:
+ code = UNION_TYPE;
+ break;
+ case enum_type:
+ code = ENUMERAL_TYPE;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (orig_scope == ts_lambda)
+ scope = ts_current;
+ else
+ scope = orig_scope;
+
+ /* In case of anonymous name, xref_tag is only called to
+ make type node and push name. Name lookup is not required. */
+ if (ANON_AGGRNAME_P (name))
+ t = NULL_TREE;
+ else
+ t = lookup_and_check_tag (tag_code, name,
+ scope, template_header_p);
+
+ if (t == error_mark_node)
+ return error_mark_node;
+
+ if (scope != ts_current && t && current_class_type
+ && template_class_depth (current_class_type)
+ && template_header_p)
+ {
+ if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
+ return t;
+
+ /* Since SCOPE is not TS_CURRENT, we are not looking at a
+ definition of this tag. Since, in addition, we are currently
+ processing a (member) template declaration of a template
+ class, we must be very careful; consider:
+
+ template <class X>
+ struct S1
+
+ template <class U>
+ struct S2
+ { template <class V>
+ friend struct S1; };
+
+ Here, the S2::S1 declaration should not be confused with the
+ outer declaration. In particular, the inner version should
+ have a template parameter of level 2, not level 1. This
+ would be particularly important if the member declaration
+ were instead:
+
+ template <class V = U> friend struct S1;
+
+ say, when we should tsubst into `U' when instantiating
+ S2. On the other hand, when presented with:
+
+ template <class T>
+ struct S1 {
+ template <class U>
+ struct S2 {};
+ template <class U>
+ friend struct S2;
+ };
+
+ we must find the inner binding eventually. We
+ accomplish this by making sure that the new type we
+ create to represent this declaration has the right
+ TYPE_CONTEXT. */
+ context = TYPE_CONTEXT (t);
+ t = NULL_TREE;
+ }
+
+ if (! t)
+ {
+ /* If no such tag is yet defined, create a forward-reference node
+ and record it as the "definition".
+ When a real declaration of this type is found,
+ the forward-reference will be altered into a real type. */
+ if (code == ENUMERAL_TYPE)
+ {
+ error ("use of enum %q#D without previous declaration", name);
+ return error_mark_node;
+ }
+ else
+ {
+ t = make_class_type (code);
+ TYPE_CONTEXT (t) = context;
+ if (orig_scope == ts_lambda)
+ /* Remember that we're declaring a lambda to avoid bogus errors
+ in push_template_decl. */
+ CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
+ t = pushtag (name, t, scope);
+ }
+ }
+ else
+ {
+ if (template_header_p && MAYBE_CLASS_TYPE_P (t))
+ {
+ if (!redeclare_class_template (t, current_template_parms))
+ return error_mark_node;
+ }
+ else if (!processing_template_decl
+ && CLASS_TYPE_P (t)
+ && CLASSTYPE_IS_TEMPLATE (t))
+ {
+ error ("redeclaration of %qT as a non-template", t);
+ error ("previous declaration %q+D", t);
+ return error_mark_node;
+ }
+
+ /* Make injected friend class visible. */
+ if (scope != ts_within_enclosing_non_class
+ && hidden_name_p (TYPE_NAME (t)))
+ {
+ DECL_ANTICIPATED (TYPE_NAME (t)) = 0;
+ DECL_FRIEND_P (TYPE_NAME (t)) = 0;
+
+ if (TYPE_TEMPLATE_INFO (t))
+ {
+ DECL_ANTICIPATED (TYPE_TI_TEMPLATE (t)) = 0;
+ DECL_FRIEND_P (TYPE_TI_TEMPLATE (t)) = 0;
+ }
+ }
+ }
+
+ return t;
+}
+
+/* Wrapper for xref_tag_1. */
+
+tree
+xref_tag (enum tag_types tag_code, tree name,
+ tag_scope scope, bool template_header_p)
+{
+ tree ret;
+ bool subtime;
+ subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = xref_tag_1 (tag_code, name, scope, template_header_p);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+
+tree
+xref_tag_from_type (tree old, tree id, tag_scope scope)
+{
+ enum tag_types tag_kind;
+
+ if (TREE_CODE (old) == RECORD_TYPE)
+ tag_kind = (CLASSTYPE_DECLARED_CLASS (old) ? class_type : record_type);
+ else
+ tag_kind = union_type;
+
+ if (id == NULL_TREE)
+ id = TYPE_IDENTIFIER (old);
+
+ return xref_tag (tag_kind, id, scope, false);
+}
+
+/* Create the binfo hierarchy for REF with (possibly NULL) base list
+ BASE_LIST. For each element on BASE_LIST the TREE_PURPOSE is an
+ access_* node, and the TREE_VALUE is the type of the base-class.
+ Non-NULL TREE_TYPE indicates virtual inheritance.
+
+ Returns true if the binfo hierarchy was successfully created,
+ false if an error was detected. */
+
+bool
+xref_basetypes (tree ref, tree base_list)
+{
+ tree *basep;
+ tree binfo, base_binfo;
+ unsigned max_vbases = 0; /* Maximum direct & indirect virtual bases. */
+ unsigned max_bases = 0; /* Maximum direct bases. */
+ int i;
+ tree default_access;
+ tree igo_prev; /* Track Inheritance Graph Order. */
+
+ if (ref == error_mark_node)
+ return false;
+
+ /* The base of a derived class is private by default, all others are
+ public. */
+ default_access = (TREE_CODE (ref) == RECORD_TYPE
+ && CLASSTYPE_DECLARED_CLASS (ref)
+ ? access_private_node : access_public_node);
+
+ /* First, make sure that any templates in base-classes are
+ instantiated. This ensures that if we call ourselves recursively
+ we do not get confused about which classes are marked and which
+ are not. */
+ basep = &base_list;
+ while (*basep)
+ {
+ tree basetype = TREE_VALUE (*basep);
+
+ /* The dependent_type_p call below should really be dependent_scope_p
+ so that we give a hard error about using an incomplete type as a
+ base, but we allow it with a pedwarn for backward
+ compatibility. */
+ if (processing_template_decl
+ && CLASS_TYPE_P (basetype) && TYPE_BEING_DEFINED (basetype))
+ cxx_incomplete_type_diagnostic (NULL_TREE, basetype, DK_PEDWARN);
+ if (!dependent_type_p (basetype)
+ && !complete_type_or_else (basetype, NULL))
+ /* An incomplete type. Remove it from the list. */
+ *basep = TREE_CHAIN (*basep);
+ else
+ {
+ max_bases++;
+ if (TREE_TYPE (*basep))
+ max_vbases++;
+ if (CLASS_TYPE_P (basetype))
+ max_vbases += vec_safe_length (CLASSTYPE_VBASECLASSES (basetype));
+ basep = &TREE_CHAIN (*basep);
+ }
+ }
+
+ TYPE_MARKED_P (ref) = 1;
+
+ /* The binfo slot should be empty, unless this is an (ill-formed)
+ redefinition. */
+ if (TYPE_BINFO (ref) && !TYPE_SIZE (ref))
+ {
+ error ("redefinition of %q#T", ref);
+ return false;
+ }
+
+ gcc_assert (TYPE_MAIN_VARIANT (ref) == ref);
+
+ binfo = make_tree_binfo (max_bases);
+
+ TYPE_BINFO (ref) = binfo;
+ BINFO_OFFSET (binfo) = size_zero_node;
+ BINFO_TYPE (binfo) = ref;
+
+ /* Apply base-class info set up to the variants of this type. */
+ fixup_type_variants (ref);
+
+ if (max_bases)
+ {
+ vec_alloc (BINFO_BASE_ACCESSES (binfo), max_bases);
+ /* An aggregate cannot have baseclasses. */
+ CLASSTYPE_NON_AGGREGATE (ref) = 1;
+
+ if (TREE_CODE (ref) == UNION_TYPE)
+ {
+ error ("derived union %qT invalid", ref);
+ return false;
+ }
+ }
+
+ if (max_bases > 1)
+ {
+ if (TYPE_FOR_JAVA (ref))
+ {
+ error ("Java class %qT cannot have multiple bases", ref);
+ return false;
+ }
+ }
+
+ if (max_vbases)
+ {
+ vec_alloc (CLASSTYPE_VBASECLASSES (ref), max_vbases);
+
+ if (TYPE_FOR_JAVA (ref))
+ {
+ error ("Java class %qT cannot have virtual bases", ref);
+ return false;
+ }
+ }
+
+ for (igo_prev = binfo; base_list; base_list = TREE_CHAIN (base_list))
+ {
+ tree access = TREE_PURPOSE (base_list);
+ int via_virtual = TREE_TYPE (base_list) != NULL_TREE;
+ tree basetype = TREE_VALUE (base_list);
+
+ if (access == access_default_node)
+ access = default_access;
+
+ if (PACK_EXPANSION_P (basetype))
+ basetype = PACK_EXPANSION_PATTERN (basetype);
+ if (TREE_CODE (basetype) == TYPE_DECL)
+ basetype = TREE_TYPE (basetype);
+ if (!MAYBE_CLASS_TYPE_P (basetype) || TREE_CODE (basetype) == UNION_TYPE)
+ {
+ error ("base type %qT fails to be a struct or class type",
+ basetype);
+ return false;
+ }
+
+ if (TYPE_FOR_JAVA (basetype) && (current_lang_depth () == 0))
+ TYPE_FOR_JAVA (ref) = 1;
+
+ base_binfo = NULL_TREE;
+ if (CLASS_TYPE_P (basetype) && !dependent_scope_p (basetype))
+ {
+ base_binfo = TYPE_BINFO (basetype);
+ /* The original basetype could have been a typedef'd type. */
+ basetype = BINFO_TYPE (base_binfo);
+
+ /* Inherit flags from the base. */
+ TYPE_HAS_NEW_OPERATOR (ref)
+ |= TYPE_HAS_NEW_OPERATOR (basetype);
+ TYPE_HAS_ARRAY_NEW_OPERATOR (ref)
+ |= TYPE_HAS_ARRAY_NEW_OPERATOR (basetype);
+ TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
+ TYPE_HAS_CONVERSION (ref) |= TYPE_HAS_CONVERSION (basetype);
+ CLASSTYPE_DIAMOND_SHAPED_P (ref)
+ |= CLASSTYPE_DIAMOND_SHAPED_P (basetype);
+ CLASSTYPE_REPEATED_BASE_P (ref)
+ |= CLASSTYPE_REPEATED_BASE_P (basetype);
+ }
+
+ /* We must do this test after we've seen through a typedef
+ type. */
+ if (TYPE_MARKED_P (basetype))
+ {
+ if (basetype == ref)
+ error ("recursive type %qT undefined", basetype);
+ else
+ error ("duplicate base type %qT invalid", basetype);
+ return false;
+ }
+
+ if (PACK_EXPANSION_P (TREE_VALUE (base_list)))
+ /* Regenerate the pack expansion for the bases. */
+ basetype = make_pack_expansion (basetype);
+
+ TYPE_MARKED_P (basetype) = 1;
+
+ base_binfo = copy_binfo (base_binfo, basetype, ref,
+ &igo_prev, via_virtual);
+ if (!BINFO_INHERITANCE_CHAIN (base_binfo))
+ BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
+
+ BINFO_BASE_APPEND (binfo, base_binfo);
+ BINFO_BASE_ACCESS_APPEND (binfo, access);
+ }
+
+ if (vec_safe_length (CLASSTYPE_VBASECLASSES (ref)) < max_vbases)
+ /* If we didn't get max_vbases vbases, we must have shared at
+ least one of them, and are therefore diamond shaped. */
+ CLASSTYPE_DIAMOND_SHAPED_P (ref) = 1;
+
+ /* Unmark all the types. */
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 0;
+ TYPE_MARKED_P (ref) = 0;
+
+ /* Now see if we have a repeated base type. */
+ if (!CLASSTYPE_REPEATED_BASE_P (ref))
+ {
+ for (base_binfo = binfo; base_binfo;
+ base_binfo = TREE_CHAIN (base_binfo))
+ {
+ if (TYPE_MARKED_P (BINFO_TYPE (base_binfo)))
+ {
+ CLASSTYPE_REPEATED_BASE_P (ref) = 1;
+ break;
+ }
+ TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 1;
+ }
+ for (base_binfo = binfo; base_binfo;
+ base_binfo = TREE_CHAIN (base_binfo))
+ if (TYPE_MARKED_P (BINFO_TYPE (base_binfo)))
+ TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 0;
+ else
+ break;
+ }
+
+ return true;
+}
+
+
+/* Copies the enum-related properties from type SRC to type DST.
+ Used with the underlying type of an enum and the enum itself. */
+static void
+copy_type_enum (tree dst, tree src)
+{
+ tree t;
+ for (t = dst; t; t = TYPE_NEXT_VARIANT (t))
+ {
+ TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (src);
+ TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (src);
+ TYPE_SIZE (t) = TYPE_SIZE (src);
+ TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (src);
+ SET_TYPE_MODE (dst, TYPE_MODE (src));
+ TYPE_PRECISION (t) = TYPE_PRECISION (src);
+ TYPE_ALIGN (t) = TYPE_ALIGN (src);
+ TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (src);
+ TYPE_UNSIGNED (t) = TYPE_UNSIGNED (src);
+ }
+}
+
+/* Begin compiling the definition of an enumeration type.
+ NAME is its name,
+
+ if ENUMTYPE is not NULL_TREE then the type has alredy been found.
+
+ UNDERLYING_TYPE is the type that will be used as the storage for
+ the enumeration type. This should be NULL_TREE if no storage type
+ was specified.
+
+ SCOPED_ENUM_P is true if this is a scoped enumeration type.
+
+ if IS_NEW is not NULL, gets TRUE iff a new type is created.
+
+ Returns the type object, as yet incomplete.
+ Also records info about it so that build_enumerator
+ may be used to declare the individual values as they are read. */
+
+tree
+start_enum (tree name, tree enumtype, tree underlying_type,
+ bool scoped_enum_p, bool *is_new)
+{
+ tree prevtype = NULL_TREE;
+ gcc_assert (identifier_p (name));
+
+ if (is_new)
+ *is_new = false;
+ /* [C++0x dcl.enum]p5:
+
+ If not explicitly specified, the underlying type of a scoped
+ enumeration type is int. */
+ if (!underlying_type && scoped_enum_p)
+ underlying_type = integer_type_node;
+
+ if (underlying_type)
+ underlying_type = cv_unqualified (underlying_type);
+
+ /* If this is the real definition for a previous forward reference,
+ fill in the contents in the same object that used to be the
+ forward reference. */
+ if (!enumtype)
+ enumtype = lookup_and_check_tag (enum_type, name,
+ /*tag_scope=*/ts_current,
+ /*template_header_p=*/false);
+
+ /* In case of a template_decl, the only check that should be deferred
+ to instantiation time is the comparison of underlying types. */
+ if (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
+ {
+ if (scoped_enum_p != SCOPED_ENUM_P (enumtype))
+ {
+ error_at (input_location, "scoped/unscoped mismatch "
+ "in enum %q#T", enumtype);
+ error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
+ "previous definition here");
+ enumtype = error_mark_node;
+ }
+ else if (ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) != !! underlying_type)
+ {
+ error_at (input_location, "underlying type mismatch "
+ "in enum %q#T", enumtype);
+ error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
+ "previous definition here");
+ enumtype = error_mark_node;
+ }
+ else if (underlying_type && ENUM_UNDERLYING_TYPE (enumtype)
+ && !dependent_type_p (underlying_type)
+ && !dependent_type_p (ENUM_UNDERLYING_TYPE (enumtype))
+ && !same_type_p (underlying_type,
+ ENUM_UNDERLYING_TYPE (enumtype)))
+ {
+ error_at (input_location, "different underlying type "
+ "in enum %q#T", enumtype);
+ error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
+ "previous definition here");
+ underlying_type = NULL_TREE;
+ }
+ }
+
+ if (!enumtype || TREE_CODE (enumtype) != ENUMERAL_TYPE
+ || processing_template_decl)
+ {
+ /* In case of error, make a dummy enum to allow parsing to
+ continue. */
+ if (enumtype == error_mark_node)
+ {
+ name = make_anon_name ();
+ enumtype = NULL_TREE;
+ }
+
+ /* enumtype may be an ENUMERAL_TYPE if this is a redefinition
+ of an opaque enum, or an opaque enum of an already defined
+ enumeration (C++0x only).
+ In any other case, it'll be NULL_TREE. */
+ if (!enumtype)
+ {
+ if (is_new)
+ *is_new = true;
+ }
+ prevtype = enumtype;
+
+ /* Do not push the decl more than once, unless we need to
+ compare underlying types at instantiation time */
+ if (!enumtype
+ || TREE_CODE (enumtype) != ENUMERAL_TYPE
+ || (underlying_type
+ && dependent_type_p (underlying_type))
+ || (ENUM_UNDERLYING_TYPE (enumtype)
+ && dependent_type_p (ENUM_UNDERLYING_TYPE (enumtype))))
+ {
+ enumtype = cxx_make_type (ENUMERAL_TYPE);
+ enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
+ }
+ else
+ enumtype = xref_tag (enum_type, name, /*tag_scope=*/ts_current,
+ false);
+
+ if (enumtype == error_mark_node)
+ return error_mark_node;
+
+ /* The enum is considered opaque until the opening '{' of the
+ enumerator list. */
+ SET_OPAQUE_ENUM_P (enumtype, true);
+ ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) = !! underlying_type;
+ }
+
+ SET_SCOPED_ENUM_P (enumtype, scoped_enum_p);
+
+ if (underlying_type)
+ {
+ if (CP_INTEGRAL_TYPE_P (underlying_type))
+ {
+ copy_type_enum (enumtype, underlying_type);
+ ENUM_UNDERLYING_TYPE (enumtype) = underlying_type;
+ }
+ else if (dependent_type_p (underlying_type))
+ ENUM_UNDERLYING_TYPE (enumtype) = underlying_type;
+ else
+ error ("underlying type %<%T%> of %<%T%> must be an integral type",
+ underlying_type, enumtype);
+ }
+
+ /* If into a template class, the returned enum is always the first
+ declaration (opaque or not) seen. This way all the references to
+ this type will be to the same declaration. The following ones are used
+ only to check for definition errors. */
+ if (prevtype && processing_template_decl)
+ return prevtype;
+ else
+ return enumtype;
+}
+
+/* After processing and defining all the values of an enumeration type,
+ install their decls in the enumeration type.
+ ENUMTYPE is the type object. */
+
+void
+finish_enum_value_list (tree enumtype)
+{
+ tree values;
+ tree underlying_type;
+ tree decl;
+ tree value;
+ tree minnode, maxnode;
+ tree t;
+
+ bool fixed_underlying_type_p
+ = ENUM_UNDERLYING_TYPE (enumtype) != NULL_TREE;
+
+ /* We built up the VALUES in reverse order. */
+ TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
+
+ /* For an enum defined in a template, just set the type of the values;
+ all further processing is postponed until the template is
+ instantiated. We need to set the type so that tsubst of a CONST_DECL
+ works. */
+ if (processing_template_decl)
+ {
+ for (values = TYPE_VALUES (enumtype);
+ values;
+ values = TREE_CHAIN (values))
+ TREE_TYPE (TREE_VALUE (values)) = enumtype;
+ return;
+ }
+
+ /* Determine the minimum and maximum values of the enumerators. */
+ if (TYPE_VALUES (enumtype))
+ {
+ minnode = maxnode = NULL_TREE;
+
+ for (values = TYPE_VALUES (enumtype);
+ values;
+ values = TREE_CHAIN (values))
+ {
+ decl = TREE_VALUE (values);
+
+ /* [dcl.enum]: Following the closing brace of an enum-specifier,
+ each enumerator has the type of its enumeration. Prior to the
+ closing brace, the type of each enumerator is the type of its
+ initializing value. */
+ TREE_TYPE (decl) = enumtype;
+
+ /* Update the minimum and maximum values, if appropriate. */
+ value = DECL_INITIAL (decl);
+ if (value == error_mark_node)
+ value = integer_zero_node;
+ /* Figure out what the minimum and maximum values of the
+ enumerators are. */
+ if (!minnode)
+ minnode = maxnode = value;
+ else if (tree_int_cst_lt (maxnode, value))
+ maxnode = value;
+ else if (tree_int_cst_lt (value, minnode))
+ minnode = value;
+ }
+ }
+ else
+ /* [dcl.enum]
+
+ If the enumerator-list is empty, the underlying type is as if
+ the enumeration had a single enumerator with value 0. */
+ minnode = maxnode = integer_zero_node;
+
+ if (!fixed_underlying_type_p)
+ {
+ /* Compute the number of bits require to represent all values of the
+ enumeration. We must do this before the type of MINNODE and
+ MAXNODE are transformed, since tree_int_cst_min_precision relies
+ on the TREE_TYPE of the value it is passed. */
+ bool unsignedp = tree_int_cst_sgn (minnode) >= 0;
+ int lowprec = tree_int_cst_min_precision (minnode, unsignedp);
+ int highprec = tree_int_cst_min_precision (maxnode, unsignedp);
+ int precision = MAX (lowprec, highprec);
+ unsigned int itk;
+ bool use_short_enum;
+
+ /* Determine the underlying type of the enumeration.
+
+ [dcl.enum]
+
+ The underlying type of an enumeration is an integral type that
+ can represent all the enumerator values defined in the
+ enumeration. It is implementation-defined which integral type is
+ used as the underlying type for an enumeration except that the
+ underlying type shall not be larger than int unless the value of
+ an enumerator cannot fit in an int or unsigned int.
+
+ We use "int" or an "unsigned int" as the underlying type, even if
+ a smaller integral type would work, unless the user has
+ explicitly requested that we use the smallest possible type. The
+ user can request that for all enumerations with a command line
+ flag, or for just one enumeration with an attribute. */
+
+ use_short_enum = flag_short_enums
+ || lookup_attribute ("packed", TYPE_ATTRIBUTES (enumtype));
+
+ for (itk = (use_short_enum ? itk_char : itk_int);
+ itk != itk_none;
+ itk++)
+ {
+ underlying_type = integer_types[itk];
+ if (underlying_type != NULL_TREE
+ && TYPE_PRECISION (underlying_type) >= precision
+ && TYPE_UNSIGNED (underlying_type) == unsignedp)
+ break;
+ }
+ if (itk == itk_none)
+ {
+ /* DR 377
+
+ IF no integral type can represent all the enumerator values, the
+ enumeration is ill-formed. */
+ error ("no integral type can represent all of the enumerator values "
+ "for %qT", enumtype);
+ precision = TYPE_PRECISION (long_long_integer_type_node);
+ underlying_type = integer_types[itk_unsigned_long_long];
+ }
+
+ /* [dcl.enum]
+
+ The value of sizeof() applied to an enumeration type, an object
+ of an enumeration type, or an enumerator, is the value of sizeof()
+ applied to the underlying type. */
+ copy_type_enum (enumtype, underlying_type);
+
+ /* Compute the minimum and maximum values for the type.
+
+ [dcl.enum]
+
+ For an enumeration where emin is the smallest enumerator and emax
+ is the largest, the values of the enumeration are the values of the
+ underlying type in the range bmin to bmax, where bmin and bmax are,
+ respectively, the smallest and largest values of the smallest bit-
+ field that can store emin and emax. */
+
+ /* The middle-end currently assumes that types with TYPE_PRECISION
+ narrower than their underlying type are suitably zero or sign
+ extended to fill their mode. Similarly, it assumes that the front
+ end assures that a value of a particular type must be within
+ TYPE_MIN_VALUE and TYPE_MAX_VALUE.
+
+ We used to set these fields based on bmin and bmax, but that led
+ to invalid assumptions like optimizing away bounds checking. So
+ now we just set the TYPE_PRECISION, TYPE_MIN_VALUE, and
+ TYPE_MAX_VALUE to the values for the mode above and only restrict
+ the ENUM_UNDERLYING_TYPE for the benefit of diagnostics. */
+ ENUM_UNDERLYING_TYPE (enumtype)
+ = build_distinct_type_copy (underlying_type);
+ TYPE_PRECISION (ENUM_UNDERLYING_TYPE (enumtype)) = precision;
+ set_min_and_max_values_for_integral_type
+ (ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp);
+
+ /* If -fstrict-enums, still constrain TYPE_MIN/MAX_VALUE. */
+ if (flag_strict_enums)
+ set_min_and_max_values_for_integral_type (enumtype, precision,
+ unsignedp);
+ }
+ else
+ underlying_type = ENUM_UNDERLYING_TYPE (enumtype);
+
+ /* Convert each of the enumerators to the type of the underlying
+ type of the enumeration. */
+ for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
+ {
+ location_t saved_location;
+
+ decl = TREE_VALUE (values);
+ saved_location = input_location;
+ input_location = DECL_SOURCE_LOCATION (decl);
+ if (fixed_underlying_type_p)
+ /* If the enumeration type has a fixed underlying type, we
+ already checked all of the enumerator values. */
+ value = DECL_INITIAL (decl);
+ else
+ value = perform_implicit_conversion (underlying_type,
+ DECL_INITIAL (decl),
+ tf_warning_or_error);
+ input_location = saved_location;
+
+ /* Do not clobber shared ints. */
+ value = copy_node (value);
+
+ TREE_TYPE (value) = enumtype;
+ DECL_INITIAL (decl) = value;
+ }
+
+ /* Fix up all variant types of this enum type. */
+ for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t))
+ TYPE_VALUES (t) = TYPE_VALUES (enumtype);
+
+ if (at_class_scope_p ()
+ && COMPLETE_TYPE_P (current_class_type)
+ && UNSCOPED_ENUM_P (enumtype))
+ insert_late_enum_def_into_classtype_sorted_fields (enumtype,
+ current_class_type);
+
+ /* Finish debugging output for this type. */
+ rest_of_type_compilation (enumtype, namespace_bindings_p ());
+}
+
+/* Finishes the enum type. This is called only the first time an
+ enumeration is seen, be it opaque or odinary.
+ ENUMTYPE is the type object. */
+
+void
+finish_enum (tree enumtype)
+{
+ if (processing_template_decl)
+ {
+ if (at_function_scope_p ())
+ add_stmt (build_min (TAG_DEFN, enumtype));
+ return;
+ }
+
+ /* If this is a forward declaration, there should not be any variants,
+ though we can get a variant in the middle of an enum-specifier with
+ wacky code like 'enum E { e = sizeof(const E*) };' */
+ gcc_assert (enumtype == TYPE_MAIN_VARIANT (enumtype)
+ && (TYPE_VALUES (enumtype)
+ || !TYPE_NEXT_VARIANT (enumtype)));
+}
+
+/* Build and install a CONST_DECL for an enumeration constant of the
+ enumeration type ENUMTYPE whose NAME and VALUE (if any) are provided.
+ LOC is the location of NAME.
+ Assignment of sequential values by default is handled here. */
+
+void
+build_enumerator (tree name, tree value, tree enumtype, location_t loc)
+{
+ tree decl;
+ tree context;
+ tree type;
+
+ /* If the VALUE was erroneous, pretend it wasn't there; that will
+ result in the enum being assigned the next value in sequence. */
+ if (value == error_mark_node)
+ value = NULL_TREE;
+
+ /* Remove no-op casts from the value. */
+ if (value)
+ STRIP_TYPE_NOPS (value);
+
+ if (! processing_template_decl)
+ {
+ /* Validate and default VALUE. */
+ if (value != NULL_TREE)
+ {
+ value = cxx_constant_value (value);
+
+ if (TREE_CODE (value) != INTEGER_CST
+ || ! INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (value)))
+ {
+ error ("enumerator value for %qD is not an integer constant",
+ name);
+ value = NULL_TREE;
+ }
+ }
+
+ /* Default based on previous value. */
+ if (value == NULL_TREE)
+ {
+ if (TYPE_VALUES (enumtype))
+ {
+ tree prev_value;
+ bool overflowed;
+
+ /* C++03 7.2/4: If no initializer is specified for the first
+ enumerator, the type is an unspecified integral
+ type. Otherwise the type is the same as the type of the
+ initializing value of the preceding enumerator unless the
+ incremented value is not representable in that type, in
+ which case the type is an unspecified integral type
+ sufficient to contain the incremented value. */
+ prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
+ if (error_operand_p (prev_value))
+ value = error_mark_node;
+ else
+ {
+ double_int di = TREE_INT_CST (prev_value)
+ .add_with_sign (double_int_one,
+ false, &overflowed);
+ if (!overflowed)
+ {
+ tree type = TREE_TYPE (prev_value);
+ bool pos = TYPE_UNSIGNED (type) || !di.is_negative ();
+ if (!double_int_fits_to_tree_p (type, di))
+ {
+ unsigned int itk;
+ for (itk = itk_int; itk != itk_none; itk++)
+ {
+ type = integer_types[itk];
+ if (type != NULL_TREE
+ && (pos || !TYPE_UNSIGNED (type))
+ && double_int_fits_to_tree_p (type, di))
+ break;
+ }
+ if (type && cxx_dialect < cxx11
+ && itk > itk_unsigned_long)
+ pedwarn (input_location, OPT_Wlong_long, pos ? "\
+incremented enumerator value is too large for %<unsigned long%>" : "\
+incremented enumerator value is too large for %<long%>");
+ }
+ if (type == NULL_TREE)
+ overflowed = true;
+ else
+ value = double_int_to_tree (type, di);
+ }
+
+ if (overflowed)
+ {
+ error ("overflow in enumeration values at %qD", name);
+ value = error_mark_node;
+ }
+ }
+ }
+ else
+ value = integer_zero_node;
+ }
+
+ /* Remove no-op casts from the value. */
+ STRIP_TYPE_NOPS (value);
+
+ /* If the underlying type of the enum is fixed, check whether
+ the enumerator values fits in the underlying type. If it
+ does not fit, the program is ill-formed [C++0x dcl.enum]. */
+ if (ENUM_UNDERLYING_TYPE (enumtype)
+ && value
+ && TREE_CODE (value) == INTEGER_CST)
+ {
+ if (!int_fits_type_p (value, ENUM_UNDERLYING_TYPE (enumtype)))
+ error ("enumerator value %E is outside the range of underlying "
+ "type %<%T%>", value, ENUM_UNDERLYING_TYPE (enumtype));
+
+ /* Convert the value to the appropriate type. */
+ value = convert (ENUM_UNDERLYING_TYPE (enumtype), value);
+ }
+ }
+
+ /* C++ associates enums with global, function, or class declarations. */
+ context = current_scope ();
+
+ /* Build the actual enumeration constant. Note that the enumeration
+ constants have the underlying type of the enum (if it is fixed)
+ or the type of their initializer (if the underlying type of the
+ enum is not fixed):
+
+ [ C++0x dcl.enum ]
+
+ If the underlying type is fixed, the type of each enumerator
+ prior to the closing brace is the underlying type; if the
+ initializing value of an enumerator cannot be represented by
+ the underlying type, the program is ill-formed. If the
+ underlying type is not fixed, the type of each enumerator is
+ the type of its initializing value.
+
+ If the underlying type is not fixed, it will be computed by
+ finish_enum and we will reset the type of this enumerator. Of
+ course, if we're processing a template, there may be no value. */
+ type = value ? TREE_TYPE (value) : NULL_TREE;
+
+ decl = build_decl (loc, CONST_DECL, name, type);
+
+ DECL_CONTEXT (decl) = enumtype;
+ TREE_CONSTANT (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ DECL_INITIAL (decl) = value;
+
+ if (context && context == current_class_type && !SCOPED_ENUM_P (enumtype))
+ /* In something like `struct S { enum E { i = 7 }; };' we put `i'
+ on the TYPE_FIELDS list for `S'. (That's so that you can say
+ things like `S::i' later.) */
+ finish_member_declaration (decl);
+ else
+ pushdecl (decl);
+
+ /* Add this enumeration constant to the list for this type. */
+ TYPE_VALUES (enumtype) = tree_cons (name, decl, TYPE_VALUES (enumtype));
+}
+
+/* Look for an enumerator with the given NAME within the enumeration
+ type ENUMTYPE. This routine is used primarily for qualified name
+ lookup into an enumerator in C++0x, e.g.,
+
+ enum class Color { Red, Green, Blue };
+
+ Color color = Color::Red;
+
+ Returns the value corresponding to the enumerator, or
+ NULL_TREE if no such enumerator was found. */
+tree
+lookup_enumerator (tree enumtype, tree name)
+{
+ tree e;
+ gcc_assert (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE);
+
+ e = purpose_member (name, TYPE_VALUES (enumtype));
+ return e? TREE_VALUE (e) : NULL_TREE;
+}
+
+
+/* We're defining DECL. Make sure that its type is OK. */
+
+static void
+check_function_type (tree decl, tree current_function_parms)
+{
+ tree fntype = TREE_TYPE (decl);
+ tree return_type = complete_type (TREE_TYPE (fntype));
+
+ /* In a function definition, arg types must be complete. */
+ require_complete_types_for_parms (current_function_parms);
+
+ if (dependent_type_p (return_type)
+ || type_uses_auto (return_type))
+ return;
+ if (!COMPLETE_OR_VOID_TYPE_P (return_type)
+ || (TYPE_FOR_JAVA (return_type) && MAYBE_CLASS_TYPE_P (return_type)))
+ {
+ tree args = TYPE_ARG_TYPES (fntype);
+
+ if (!COMPLETE_OR_VOID_TYPE_P (return_type))
+ error ("return type %q#T is incomplete", return_type);
+ else
+ error ("return type has Java class type %q#T", return_type);
+
+ /* Make it return void instead. */
+ if (TREE_CODE (fntype) == METHOD_TYPE)
+ fntype = build_method_type_directly (TREE_TYPE (TREE_VALUE (args)),
+ void_type_node,
+ TREE_CHAIN (args));
+ else
+ fntype = build_function_type (void_type_node, args);
+ fntype
+ = build_exception_variant (fntype,
+ TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)));
+ fntype = (cp_build_type_attribute_variant
+ (fntype, TYPE_ATTRIBUTES (TREE_TYPE (decl))));
+ TREE_TYPE (decl) = fntype;
+ }
+ else
+ abstract_virtuals_error (decl, TREE_TYPE (fntype));
+}
+
+/* Create the FUNCTION_DECL for a function definition.
+ DECLSPECS and DECLARATOR are the parts of the declaration;
+ they describe the function's name and the type it returns,
+ but twisted together in a fashion that parallels the syntax of C.
+
+ FLAGS is a bitwise or of SF_PRE_PARSED (indicating that the
+ DECLARATOR is really the DECL for the function we are about to
+ process and that DECLSPECS should be ignored), SF_INCLASS_INLINE
+ indicating that the function is an inline defined in-class.
+
+ This function creates a binding context for the function body
+ as well as setting up the FUNCTION_DECL in current_function_decl.
+
+ For C++, we must first check whether that datum makes any sense.
+ For example, "class A local_a(1,2);" means that variable local_a
+ is an aggregate of type A, which should have a constructor
+ applied to it with the argument list [1, 2].
+
+ On entry, DECL_INITIAL (decl1) should be NULL_TREE or error_mark_node,
+ or may be a BLOCK if the function has been defined previously
+ in this translation unit. On exit, DECL_INITIAL (decl1) will be
+ error_mark_node if the function has never been defined, or
+ a BLOCK if the function has been defined somewhere. */
+
+bool
+start_preparsed_function (tree decl1, tree attrs, int flags)
+{
+ tree ctype = NULL_TREE;
+ tree fntype;
+ tree restype;
+ int doing_friend = 0;
+ cp_binding_level *bl;
+ tree current_function_parms;
+ struct c_fileinfo *finfo
+ = get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)));
+ bool honor_interface;
+
+ /* Sanity check. */
+ gcc_assert (VOID_TYPE_P (TREE_VALUE (void_list_node)));
+ gcc_assert (TREE_CHAIN (void_list_node) == NULL_TREE);
+
+ fntype = TREE_TYPE (decl1);
+ if (TREE_CODE (fntype) == METHOD_TYPE)
+ ctype = TYPE_METHOD_BASETYPE (fntype);
+
+ /* ISO C++ 11.4/5. A friend function defined in a class is in
+ the (lexical) scope of the class in which it is defined. */
+ if (!ctype && DECL_FRIEND_P (decl1))
+ {
+ ctype = DECL_FRIEND_CONTEXT (decl1);
+
+ /* CTYPE could be null here if we're dealing with a template;
+ for example, `inline friend float foo()' inside a template
+ will have no CTYPE set. */
+ if (ctype && TREE_CODE (ctype) != RECORD_TYPE)
+ ctype = NULL_TREE;
+ else
+ doing_friend = 1;
+ }
+
+ if (DECL_DECLARED_INLINE_P (decl1)
+ && lookup_attribute ("noinline", attrs))
+ warning (0, "inline function %q+D given attribute noinline", decl1);
+
+ /* Handle gnu_inline attribute. */
+ if (GNU_INLINE_P (decl1))
+ {
+ DECL_EXTERNAL (decl1) = 1;
+ DECL_NOT_REALLY_EXTERN (decl1) = 0;
+ DECL_INTERFACE_KNOWN (decl1) = 1;
+ DECL_DISREGARD_INLINE_LIMITS (decl1) = 1;
+ }
+
+ if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1))
+ /* This is a constructor, we must ensure that any default args
+ introduced by this definition are propagated to the clones
+ now. The clones are used directly in overload resolution. */
+ adjust_clone_args (decl1);
+
+ /* Sometimes we don't notice that a function is a static member, and
+ build a METHOD_TYPE for it. Fix that up now. */
+ gcc_assert (!(ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
+ && TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE));
+
+ /* Set up current_class_type, and enter the scope of the class, if
+ appropriate. */
+ if (ctype)
+ push_nested_class (ctype);
+ else if (DECL_STATIC_FUNCTION_P (decl1))
+ push_nested_class (DECL_CONTEXT (decl1));
+
+ /* Now that we have entered the scope of the class, we must restore
+ the bindings for any template parameters surrounding DECL1, if it
+ is an inline member template. (Order is important; consider the
+ case where a template parameter has the same name as a field of
+ the class.) It is not until after this point that
+ PROCESSING_TEMPLATE_DECL is guaranteed to be set up correctly. */
+ if (flags & SF_INCLASS_INLINE)
+ maybe_begin_member_template_processing (decl1);
+
+ /* Effective C++ rule 15. */
+ if (warn_ecpp
+ && DECL_OVERLOADED_OPERATOR_P (decl1) == NOP_EXPR
+ && VOID_TYPE_P (TREE_TYPE (fntype)))
+ warning (OPT_Weffc__, "%<operator=%> should return a reference to %<*this%>");
+
+ /* Make the init_value nonzero so pushdecl knows this is not tentative.
+ error_mark_node is replaced below (in poplevel) with the BLOCK. */
+ if (!DECL_INITIAL (decl1))
+ DECL_INITIAL (decl1) = error_mark_node;
+
+ /* This function exists in static storage.
+ (This does not mean `static' in the C sense!) */
+ TREE_STATIC (decl1) = 1;
+
+ /* We must call push_template_decl after current_class_type is set
+ up. (If we are processing inline definitions after exiting a
+ class scope, current_class_type will be NULL_TREE until set above
+ by push_nested_class.) */
+ if (processing_template_decl)
+ {
+ tree newdecl1 = push_template_decl (decl1);
+ if (newdecl1 == error_mark_node)
+ {
+ if (ctype || DECL_STATIC_FUNCTION_P (decl1))
+ pop_nested_class ();
+ return false;
+ }
+ decl1 = newdecl1;
+ }
+
+ /* We are now in the scope of the function being defined. */
+ current_function_decl = decl1;
+
+ /* Save the parm names or decls from this function's declarator
+ where store_parm_decls will find them. */
+ current_function_parms = DECL_ARGUMENTS (decl1);
+
+ /* Make sure the parameter and return types are reasonable. When
+ you declare a function, these types can be incomplete, but they
+ must be complete when you define the function. */
+ check_function_type (decl1, current_function_parms);
+
+ /* Build the return declaration for the function. */
+ restype = TREE_TYPE (fntype);
+
+ if (DECL_RESULT (decl1) == NULL_TREE)
+ {
+ tree resdecl;
+
+ resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
+ DECL_ARTIFICIAL (resdecl) = 1;
+ DECL_IGNORED_P (resdecl) = 1;
+ DECL_RESULT (decl1) = resdecl;
+
+ cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
+ }
+
+ /* Let the user know we're compiling this function. */
+ announce_function (decl1);
+
+ /* Record the decl so that the function name is defined.
+ If we already have a decl for this name, and it is a FUNCTION_DECL,
+ use the old decl. */
+ if (!processing_template_decl && !(flags & SF_PRE_PARSED))
+ {
+ /* A specialization is not used to guide overload resolution. */
+ if (!DECL_FUNCTION_MEMBER_P (decl1)
+ && !(DECL_USE_TEMPLATE (decl1) &&
+ PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl1))))
+ {
+ tree olddecl = pushdecl (decl1);
+
+ if (olddecl == error_mark_node)
+ /* If something went wrong when registering the declaration,
+ use DECL1; we have to have a FUNCTION_DECL to use when
+ parsing the body of the function. */
+ ;
+ else
+ {
+ /* Otherwise, OLDDECL is either a previous declaration
+ of the same function or DECL1 itself. */
+
+ if (warn_missing_declarations
+ && olddecl == decl1
+ && !DECL_MAIN_P (decl1)
+ && TREE_PUBLIC (decl1)
+ && !DECL_DECLARED_INLINE_P (decl1))
+ {
+ tree context;
+
+ /* Check whether DECL1 is in an anonymous
+ namespace. */
+ for (context = DECL_CONTEXT (decl1);
+ context;
+ context = DECL_CONTEXT (context))
+ {
+ if (TREE_CODE (context) == NAMESPACE_DECL
+ && DECL_NAME (context) == NULL_TREE)
+ break;
+ }
+
+ if (context == NULL)
+ warning (OPT_Wmissing_declarations,
+ "no previous declaration for %q+D", decl1);
+ }
+
+ decl1 = olddecl;
+ }
+ }
+ else
+ {
+ /* We need to set the DECL_CONTEXT. */
+ if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1))
+ DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1));
+ }
+ fntype = TREE_TYPE (decl1);
+ restype = TREE_TYPE (fntype);
+
+ /* If #pragma weak applies, mark the decl appropriately now.
+ The pragma only applies to global functions. Because
+ determining whether or not the #pragma applies involves
+ computing the mangled name for the declaration, we cannot
+ apply the pragma until after we have merged this declaration
+ with any previous declarations; if the original declaration
+ has a linkage specification, that specification applies to
+ the definition as well, and may affect the mangled name. */
+ if (DECL_FILE_SCOPE_P (decl1))
+ maybe_apply_pragma_weak (decl1);
+ }
+
+ /* Reset this in case the call to pushdecl changed it. */
+ current_function_decl = decl1;
+
+ gcc_assert (DECL_INITIAL (decl1));
+
+ /* This function may already have been parsed, in which case just
+ return; our caller will skip over the body without parsing. */
+ if (DECL_INITIAL (decl1) != error_mark_node)
+ return true;
+
+ /* Initialize RTL machinery. We cannot do this until
+ CURRENT_FUNCTION_DECL and DECL_RESULT are set up. We do this
+ even when processing a template; this is how we get
+ CFUN set up, and our per-function variables initialized.
+ FIXME factor out the non-RTL stuff. */
+ bl = current_binding_level;
+ allocate_struct_function (decl1, processing_template_decl);
+
+ /* Initialize the language data structures. Whenever we start
+ a new function, we destroy temporaries in the usual way. */
+ cfun->language = ggc_alloc_cleared_language_function ();
+ current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+ current_binding_level = bl;
+
+ if (!processing_template_decl && type_uses_auto (restype))
+ {
+ FNDECL_USED_AUTO (decl1) = true;
+ current_function_auto_return_pattern = restype;
+ }
+
+ /* Start the statement-tree, start the tree now. */
+ DECL_SAVED_TREE (decl1) = push_stmt_list ();
+
+ /* If we are (erroneously) defining a function that we have already
+ defined before, wipe out what we knew before. */
+ if (!DECL_PENDING_INLINE_P (decl1))
+ DECL_SAVED_FUNCTION_DATA (decl1) = NULL;
+
+ if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1))
+ {
+ /* We know that this was set up by `grokclassfn'. We do not
+ wait until `store_parm_decls', since evil parse errors may
+ never get us to that point. Here we keep the consistency
+ between `current_class_type' and `current_class_ptr'. */
+ tree t = DECL_ARGUMENTS (decl1);
+
+ gcc_assert (t != NULL_TREE && TREE_CODE (t) == PARM_DECL);
+ gcc_assert (TYPE_PTR_P (TREE_TYPE (t)));
+
+ cp_function_chain->x_current_class_ref
+ = cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
+ /* Set this second to avoid shortcut in cp_build_indirect_ref. */
+ cp_function_chain->x_current_class_ptr = t;
+
+ /* Constructors and destructors need to know whether they're "in
+ charge" of initializing virtual base classes. */
+ t = DECL_CHAIN (t);
+ if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
+ {
+ current_in_charge_parm = t;
+ t = DECL_CHAIN (t);
+ }
+ if (DECL_HAS_VTT_PARM_P (decl1))
+ {
+ gcc_assert (DECL_NAME (t) == vtt_parm_identifier);
+ current_vtt_parm = t;
+ }
+ }
+
+ honor_interface = (!DECL_TEMPLATE_INSTANTIATION (decl1)
+ /* Implicitly-defined methods (like the
+ destructor for a class in which no destructor
+ is explicitly declared) must not be defined
+ until their definition is needed. So, we
+ ignore interface specifications for
+ compiler-generated functions. */
+ && !DECL_ARTIFICIAL (decl1));
+
+ if (processing_template_decl)
+ /* Don't mess with interface flags. */;
+ else if (DECL_INTERFACE_KNOWN (decl1))
+ {
+ tree ctx = decl_function_context (decl1);
+
+ if (DECL_NOT_REALLY_EXTERN (decl1))
+ DECL_EXTERNAL (decl1) = 0;
+
+ if (ctx != NULL_TREE && vague_linkage_p (ctx))
+ /* This is a function in a local class in an extern inline
+ or template function. */
+ comdat_linkage (decl1);
+ }
+ /* If this function belongs to an interface, it is public.
+ If it belongs to someone else's interface, it is also external.
+ This only affects inlines and template instantiations. */
+ else if (!finfo->interface_unknown && honor_interface)
+ {
+ if (DECL_DECLARED_INLINE_P (decl1)
+ || DECL_TEMPLATE_INSTANTIATION (decl1))
+ {
+ DECL_EXTERNAL (decl1)
+ = (finfo->interface_only
+ || (DECL_DECLARED_INLINE_P (decl1)
+ && ! flag_implement_inlines
+ && !DECL_VINDEX (decl1)));
+
+ /* For WIN32 we also want to put these in linkonce sections. */
+ maybe_make_one_only (decl1);
+ }
+ else
+ DECL_EXTERNAL (decl1) = 0;
+ DECL_INTERFACE_KNOWN (decl1) = 1;
+ /* If this function is in an interface implemented in this file,
+ make sure that the back end knows to emit this function
+ here. */
+ if (!DECL_EXTERNAL (decl1))
+ mark_needed (decl1);
+ }
+ else if (finfo->interface_unknown && finfo->interface_only
+ && honor_interface)
+ {
+ /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma
+ interface, we will have both finfo->interface_unknown and
+ finfo->interface_only set. In that case, we don't want to
+ use the normal heuristics because someone will supply a
+ #pragma implementation elsewhere, and deducing it here would
+ produce a conflict. */
+ comdat_linkage (decl1);
+ DECL_EXTERNAL (decl1) = 0;
+ DECL_INTERFACE_KNOWN (decl1) = 1;
+ DECL_DEFER_OUTPUT (decl1) = 1;
+ }
+ else
+ {
+ /* This is a definition, not a reference.
+ So clear DECL_EXTERNAL, unless this is a GNU extern inline. */
+ if (!GNU_INLINE_P (decl1))
+ DECL_EXTERNAL (decl1) = 0;
+
+ if ((DECL_DECLARED_INLINE_P (decl1)
+ || DECL_TEMPLATE_INSTANTIATION (decl1))
+ && ! DECL_INTERFACE_KNOWN (decl1))
+ DECL_DEFER_OUTPUT (decl1) = 1;
+ else
+ DECL_INTERFACE_KNOWN (decl1) = 1;
+ }
+
+ /* Determine the ELF visibility attribute for the function. We must not
+ do this before calling "pushdecl", as we must allow "duplicate_decls"
+ to merge any attributes appropriately. We also need to wait until
+ linkage is set. */
+ if (!DECL_CLONED_FUNCTION_P (decl1))
+ determine_visibility (decl1);
+
+ begin_scope (sk_function_parms, decl1);
+
+ ++function_depth;
+
+ if (DECL_DESTRUCTOR_P (decl1)
+ || (DECL_CONSTRUCTOR_P (decl1)
+ && targetm.cxx.cdtor_returns_this ()))
+ {
+ cdtor_label = build_decl (input_location,
+ LABEL_DECL, NULL_TREE, NULL_TREE);
+ DECL_CONTEXT (cdtor_label) = current_function_decl;
+ }
+
+ start_fname_decls ();
+
+ store_parm_decls (current_function_parms);
+
+ return true;
+}
+
+
+/* Like start_preparsed_function, except that instead of a
+ FUNCTION_DECL, this function takes DECLSPECS and DECLARATOR.
+
+ Returns true on success. If the DECLARATOR is not suitable
+ for a function, we return false, which tells the parser to
+ skip the entire function. */
+
+bool
+start_function (cp_decl_specifier_seq *declspecs,
+ const cp_declarator *declarator,
+ tree attrs)
+{
+ tree decl1;
+
+ decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
+ if (decl1 == error_mark_node)
+ return false;
+ /* If the declarator is not suitable for a function definition,
+ cause a syntax error. */
+ if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
+ {
+ error ("invalid function declaration");
+ return false;
+ }
+
+ if (DECL_MAIN_P (decl1))
+ /* main must return int. grokfndecl should have corrected it
+ (and issued a diagnostic) if the user got it wrong. */
+ gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
+ integer_type_node));
+
+ return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
+}
+
+/* Returns true iff an EH_SPEC_BLOCK should be created in the body of
+ FN. */
+
+static bool
+use_eh_spec_block (tree fn)
+{
+ return (flag_exceptions && flag_enforce_eh_specs
+ && !processing_template_decl
+ && !type_throw_all_p (TREE_TYPE (fn))
+ /* We insert the EH_SPEC_BLOCK only in the original
+ function; then, it is copied automatically to the
+ clones. */
+ && !DECL_CLONED_FUNCTION_P (fn)
+ /* Implicitly-generated constructors and destructors have
+ exception specifications. However, those specifications
+ are the union of the possible exceptions specified by the
+ constructors/destructors for bases and members, so no
+ unallowed exception will ever reach this function. By
+ not creating the EH_SPEC_BLOCK we save a little memory,
+ and we avoid spurious warnings about unreachable
+ code. */
+ && !DECL_DEFAULTED_FN (fn));
+}
+
+/* Store the parameter declarations into the current function declaration.
+ This is called after parsing the parameter declarations, before
+ digesting the body of the function.
+
+ Also install to binding contour return value identifier, if any. */
+
+static void
+store_parm_decls (tree current_function_parms)
+{
+ tree fndecl = current_function_decl;
+ tree parm;
+
+ /* This is a chain of any other decls that came in among the parm
+ declarations. If a parm is declared with enum {foo, bar} x;
+ then CONST_DECLs for foo and bar are put here. */
+ tree nonparms = NULL_TREE;
+
+ if (current_function_parms)
+ {
+ /* This case is when the function was defined with an ANSI prototype.
+ The parms already have decls, so we need not do anything here
+ except record them as in effect
+ and complain if any redundant old-style parm decls were written. */
+
+ tree specparms = current_function_parms;
+ tree next;
+
+ /* Must clear this because it might contain TYPE_DECLs declared
+ at class level. */
+ current_binding_level->names = NULL;
+
+ /* If we're doing semantic analysis, then we'll call pushdecl
+ for each of these. We must do them in reverse order so that
+ they end in the correct forward order. */
+ specparms = nreverse (specparms);
+
+ for (parm = specparms; parm; parm = next)
+ {
+ next = DECL_CHAIN (parm);
+ if (TREE_CODE (parm) == PARM_DECL)
+ {
+ if (DECL_NAME (parm) == NULL_TREE
+ || !VOID_TYPE_P (parm))
+ pushdecl (parm);
+ else
+ error ("parameter %qD declared void", parm);
+ }
+ else
+ {
+ /* If we find an enum constant or a type tag,
+ put it aside for the moment. */
+ TREE_CHAIN (parm) = NULL_TREE;
+ nonparms = chainon (nonparms, parm);
+ }
+ }
+
+ /* Get the decls in their original chain order and record in the
+ function. This is all and only the PARM_DECLs that were
+ pushed into scope by the loop above. */
+ DECL_ARGUMENTS (fndecl) = getdecls ();
+ }
+ else
+ DECL_ARGUMENTS (fndecl) = NULL_TREE;
+
+ /* Now store the final chain of decls for the arguments
+ as the decl-chain of the current lexical scope.
+ Put the enumerators in as well, at the front so that
+ DECL_ARGUMENTS is not modified. */
+ current_binding_level->names = chainon (nonparms, DECL_ARGUMENTS (fndecl));
+
+ if (use_eh_spec_block (current_function_decl))
+ current_eh_spec_block = begin_eh_spec_block ();
+}
+
+
+/* We have finished doing semantic analysis on DECL, but have not yet
+ generated RTL for its body. Save away our current state, so that
+ when we want to generate RTL later we know what to do. */
+
+static void
+save_function_data (tree decl)
+{
+ struct language_function *f;
+
+ /* Save the language-specific per-function data so that we can
+ get it back when we really expand this function. */
+ gcc_assert (!DECL_PENDING_INLINE_P (decl));
+
+ /* Make a copy. */
+ f = ggc_alloc_language_function ();
+ memcpy (f, cp_function_chain, sizeof (struct language_function));
+ DECL_SAVED_FUNCTION_DATA (decl) = f;
+
+ /* Clear out the bits we don't need. */
+ f->base.x_stmt_tree.x_cur_stmt_list = NULL;
+ f->bindings = NULL;
+ f->x_local_names = NULL;
+ f->base.local_typedefs = NULL;
+}
+
+
+/* Set the return value of the constructor (if present). */
+
+static void
+finish_constructor_body (void)
+{
+ tree val;
+ tree exprstmt;
+
+ if (targetm.cxx.cdtor_returns_this ()
+ && (! TYPE_FOR_JAVA (current_class_type)))
+ {
+ /* Any return from a constructor will end up here. */
+ add_stmt (build_stmt (input_location, LABEL_EXPR, cdtor_label));
+
+ val = DECL_ARGUMENTS (current_function_decl);
+ val = build2 (MODIFY_EXPR, TREE_TYPE (val),
+ DECL_RESULT (current_function_decl), val);
+ /* Return the address of the object. */
+ exprstmt = build_stmt (input_location, RETURN_EXPR, val);
+ add_stmt (exprstmt);
+ }
+}
+
+/* Do all the processing for the beginning of a destructor; set up the
+ vtable pointers and cleanups for bases and members. */
+
+static void
+begin_destructor_body (void)
+{
+ tree compound_stmt;
+
+ /* If the CURRENT_CLASS_TYPE is incomplete, we will have already
+ issued an error message. We still want to try to process the
+ body of the function, but initialize_vtbl_ptrs will crash if
+ TYPE_BINFO is NULL. */
+ if (COMPLETE_TYPE_P (current_class_type))
+ {
+ compound_stmt = begin_compound_stmt (0);
+ /* Make all virtual function table pointers in non-virtual base
+ classes point to CURRENT_CLASS_TYPE's virtual function
+ tables. */
+ initialize_vtbl_ptrs (current_class_ptr);
+ finish_compound_stmt (compound_stmt);
+
+ /* Insert a cleanup to let the back end know that the object is dead
+ when we exit the destructor, either normally or via exception. */
+ tree clobber = build_constructor (current_class_type, NULL);
+ TREE_THIS_VOLATILE (clobber) = true;
+ tree exprstmt = build2 (MODIFY_EXPR, current_class_type,
+ current_class_ref, clobber);
+ finish_decl_cleanup (NULL_TREE, exprstmt);
+
+ /* And insert cleanups for our bases and members so that they
+ will be properly destroyed if we throw. */
+ push_base_cleanups ();
+ }
+}
+
+/* At the end of every destructor we generate code to delete the object if
+ necessary. Do that now. */
+
+static void
+finish_destructor_body (void)
+{
+ tree exprstmt;
+
+ /* Any return from a destructor will end up here; that way all base
+ and member cleanups will be run when the function returns. */
+ add_stmt (build_stmt (input_location, LABEL_EXPR, cdtor_label));
+
+ /* In a virtual destructor, we must call delete. */
+ if (DECL_VIRTUAL_P (current_function_decl))
+ {
+ tree if_stmt;
+ tree virtual_size = cxx_sizeof (current_class_type);
+
+ /* [class.dtor]
+
+ At the point of definition of a virtual destructor (including
+ an implicit definition), non-placement operator delete shall
+ be looked up in the scope of the destructor's class and if
+ found shall be accessible and unambiguous. */
+ exprstmt = build_op_delete_call (DELETE_EXPR, current_class_ptr,
+ virtual_size,
+ /*global_p=*/false,
+ /*placement=*/NULL_TREE,
+ /*alloc_fn=*/NULL_TREE,
+ tf_warning_or_error);
+
+ if_stmt = begin_if_stmt ();
+ finish_if_stmt_cond (build2 (BIT_AND_EXPR, integer_type_node,
+ current_in_charge_parm,
+ integer_one_node),
+ if_stmt);
+ finish_expr_stmt (exprstmt);
+ finish_then_clause (if_stmt);
+ finish_if_stmt (if_stmt);
+ }
+
+ if (targetm.cxx.cdtor_returns_this ())
+ {
+ tree val;
+
+ val = DECL_ARGUMENTS (current_function_decl);
+ val = build2 (MODIFY_EXPR, TREE_TYPE (val),
+ DECL_RESULT (current_function_decl), val);
+ /* Return the address of the object. */
+ exprstmt = build_stmt (input_location, RETURN_EXPR, val);
+ add_stmt (exprstmt);
+ }
+}
+
+/* Do the necessary processing for the beginning of a function body, which
+ in this case includes member-initializers, but not the catch clauses of
+ a function-try-block. Currently, this means opening a binding level
+ for the member-initializers (in a ctor), member cleanups (in a dtor),
+ and capture proxies (in a lambda operator()). */
+
+tree
+begin_function_body (void)
+{
+ tree stmt;
+
+ if (! FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
+ return NULL_TREE;
+
+ if (processing_template_decl)
+ /* Do nothing now. */;
+ else
+ /* Always keep the BLOCK node associated with the outermost pair of
+ curly braces of a function. These are needed for correct
+ operation of dwarfout.c. */
+ keep_next_level (true);
+
+ stmt = begin_compound_stmt (BCS_FN_BODY);
+
+ if (processing_template_decl)
+ /* Do nothing now. */;
+ else if (DECL_DESTRUCTOR_P (current_function_decl))
+ begin_destructor_body ();
+
+ return stmt;
+}
+
+/* Do the processing for the end of a function body. Currently, this means
+ closing out the cleanups for fully-constructed bases and members, and in
+ the case of the destructor, deleting the object if desired. Again, this
+ is only meaningful for [cd]tors, since they are the only functions where
+ there is a significant distinction between the main body and any
+ function catch clauses. Handling, say, main() return semantics here
+ would be wrong, as flowing off the end of a function catch clause for
+ main() would also need to return 0. */
+
+void
+finish_function_body (tree compstmt)
+{
+ if (compstmt == NULL_TREE)
+ return;
+
+ /* Close the block. */
+ finish_compound_stmt (compstmt);
+
+ if (processing_template_decl)
+ /* Do nothing now. */;
+ else if (DECL_CONSTRUCTOR_P (current_function_decl))
+ finish_constructor_body ();
+ else if (DECL_DESTRUCTOR_P (current_function_decl))
+ finish_destructor_body ();
+}
+
+/* Given a function, returns the BLOCK corresponding to the outermost level
+ of curly braces, skipping the artificial block created for constructor
+ initializers. */
+
+tree
+outer_curly_brace_block (tree fndecl)
+{
+ tree block = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl));
+ if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
+ /* Skip the artificial function body block. */
+ block = BLOCK_SUBBLOCKS (block);
+ return block;
+}
+
+/* If FNDECL is a class's key method, add the class to the list of
+ keyed classes that should be emitted. */
+
+static void
+record_key_method_defined (tree fndecl)
+{
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
+ && DECL_VIRTUAL_P (fndecl)
+ && !processing_template_decl)
+ {
+ tree fnclass = DECL_CONTEXT (fndecl);
+ if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
+ keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes);
+ }
+}
+
+/* Subroutine of finish_function.
+ Save the body of constexpr functions for possible
+ future compile time evaluation. */
+
+static void
+maybe_save_function_definition (tree fun)
+{
+ if (!processing_template_decl
+ && DECL_DECLARED_CONSTEXPR_P (fun)
+ && !DECL_CLONED_FUNCTION_P (fun))
+ register_constexpr_fundef (fun, DECL_SAVED_TREE (fun));
+}
+
+/* Finish up a function declaration and compile that function
+ all the way to assembler language output. The free the storage
+ for the function definition.
+
+ FLAGS is a bitwise or of the following values:
+ 2 - INCLASS_INLINE
+ We just finished processing the body of an in-class inline
+ function definition. (This processing will have taken place
+ after the class definition is complete.) */
+
+tree
+finish_function (int flags)
+{
+ tree fndecl = current_function_decl;
+ tree fntype, ctype = NULL_TREE;
+ int inclass_inline = (flags & 2) != 0;
+
+ /* When we get some parse errors, we can end up without a
+ current_function_decl, so cope. */
+ if (fndecl == NULL_TREE)
+ return error_mark_node;
+
+ if (c_dialect_objc ())
+ objc_finish_function ();
+
+ gcc_assert (!defer_mark_used_calls);
+ defer_mark_used_calls = true;
+
+ record_key_method_defined (fndecl);
+
+ fntype = TREE_TYPE (fndecl);
+
+ /* TREE_READONLY (fndecl) = 1;
+ This caused &foo to be of type ptr-to-const-function
+ which then got a warning when stored in a ptr-to-function variable. */
+
+ gcc_assert (building_stmt_list_p ());
+ /* The current function is being defined, so its DECL_INITIAL should
+ be set, and unless there's a multiple definition, it should be
+ error_mark_node. */
+ gcc_assert (DECL_INITIAL (fndecl) == error_mark_node);
+
+ /* For a cloned function, we've already got all the code we need;
+ there's no need to add any extra bits. */
+ if (!DECL_CLONED_FUNCTION_P (fndecl))
+ {
+ /* Make it so that `main' always returns 0 by default. */
+ if (DECL_MAIN_P (current_function_decl))
+ finish_return_stmt (integer_zero_node);
+
+ if (use_eh_spec_block (current_function_decl))
+ finish_eh_spec_block (TYPE_RAISES_EXCEPTIONS
+ (TREE_TYPE (current_function_decl)),
+ current_eh_spec_block);
+ }
+
+ /* If we're saving up tree structure, tie off the function now. */
+ DECL_SAVED_TREE (fndecl) = pop_stmt_list (DECL_SAVED_TREE (fndecl));
+
+ if (fn_contains_cilk_spawn_p (cfun) && !processing_template_decl)
+ cfun->cilk_frame_decl = insert_cilk_frame (fndecl);
+
+ finish_fname_decls ();
+
+ /* If this function can't throw any exceptions, remember that. */
+ if (!processing_template_decl
+ && !cp_function_chain->can_throw
+ && !flag_non_call_exceptions
+ && !decl_replaceable_p (fndecl))
+ TREE_NOTHROW (fndecl) = 1;
+
+ /* This must come after expand_function_end because cleanups might
+ have declarations (from inline functions) that need to go into
+ this function's blocks. */
+
+ /* If the current binding level isn't the outermost binding level
+ for this function, either there is a bug, or we have experienced
+ syntax errors and the statement tree is malformed. */
+ if (current_binding_level->kind != sk_function_parms)
+ {
+ /* Make sure we have already experienced errors. */
+ gcc_assert (errorcount);
+
+ /* Throw away the broken statement tree and extra binding
+ levels. */
+ DECL_SAVED_TREE (fndecl) = alloc_stmt_list ();
+
+ while (current_binding_level->kind != sk_function_parms)
+ {
+ if (current_binding_level->kind == sk_class)
+ pop_nested_class ();
+ else
+ poplevel (0, 0, 0);
+ }
+ }
+ poplevel (1, 0, 1);
+
+ /* Statements should always be full-expressions at the outermost set
+ of curly braces for a function. */
+ gcc_assert (stmts_are_full_exprs_p ());
+
+ /* If there are no return statements in a function with auto return type,
+ the return type is void. But if the declared type is something like
+ auto*, this is an error. */
+ if (!processing_template_decl && FNDECL_USED_AUTO (fndecl)
+ && TREE_TYPE (fntype) == current_function_auto_return_pattern)
+ {
+ if (!is_auto (current_function_auto_return_pattern)
+ && !current_function_returns_value && !current_function_returns_null)
+ {
+ error ("no return statements in function returning %qT",
+ current_function_auto_return_pattern);
+ inform (input_location, "only plain %<auto%> return type can be "
+ "deduced to %<void%>");
+ }
+ apply_deduced_return_type (fndecl, void_type_node);
+ fntype = TREE_TYPE (fndecl);
+ }
+
+ /* Save constexpr function body before it gets munged by
+ the NRV transformation. */
+ maybe_save_function_definition (fndecl);
+
+ /* Set up the named return value optimization, if we can. Candidate
+ variables are selected in check_return_expr. */
+ if (current_function_return_value)
+ {
+ tree r = current_function_return_value;
+ tree outer;
+
+ if (r != error_mark_node
+ /* This is only worth doing for fns that return in memory--and
+ simpler, since we don't have to worry about promoted modes. */
+ && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)), fndecl)
+ /* Only allow this for variables declared in the outer scope of
+ the function so we know that their lifetime always ends with a
+ return; see g++.dg/opt/nrv6.C. We could be more flexible if
+ we were to do this optimization in tree-ssa. */
+ && (outer = outer_curly_brace_block (fndecl))
+ && chain_member (r, BLOCK_VARS (outer)))
+ finalize_nrv (&DECL_SAVED_TREE (fndecl), r, DECL_RESULT (fndecl));
+
+ current_function_return_value = NULL_TREE;
+ }
+
+ /* Remember that we were in class scope. */
+ if (current_class_name)
+ ctype = current_class_type;
+
+ /* Must mark the RESULT_DECL as being in this function. */
+ DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
+
+ /* Set the BLOCK_SUPERCONTEXT of the outermost function scope to point
+ to the FUNCTION_DECL node itself. */
+ BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
+
+ /* Save away current state, if appropriate. */
+ if (!processing_template_decl)
+ save_function_data (fndecl);
+
+ /* Complain if there's just no return statement. */
+ if (warn_return_type
+ && !VOID_TYPE_P (TREE_TYPE (fntype))
+ && !dependent_type_p (TREE_TYPE (fntype))
+ && !current_function_returns_value && !current_function_returns_null
+ /* Don't complain if we abort or throw. */
+ && !current_function_returns_abnormally
+ /* Don't complain if there's an infinite loop. */
+ && !current_function_infinite_loop
+ /* Don't complain if we are declared noreturn. */
+ && !TREE_THIS_VOLATILE (fndecl)
+ && !DECL_NAME (DECL_RESULT (fndecl))
+ && !TREE_NO_WARNING (fndecl)
+ /* Structor return values (if any) are set by the compiler. */
+ && !DECL_CONSTRUCTOR_P (fndecl)
+ && !DECL_DESTRUCTOR_P (fndecl)
+ && targetm.warn_func_return (fndecl))
+ {
+ warning (OPT_Wreturn_type,
+ "no return statement in function returning non-void");
+ TREE_NO_WARNING (fndecl) = 1;
+ }
+
+ /* Store the end of the function, so that we get good line number
+ info for the epilogue. */
+ cfun->function_end_locus = input_location;
+
+ /* Complain about parameters that are only set, but never otherwise used. */
+ if (warn_unused_but_set_parameter
+ && !processing_template_decl
+ && errorcount == unused_but_set_errorcount
+ && !DECL_CLONED_FUNCTION_P (fndecl))
+ {
+ tree decl;
+
+ for (decl = DECL_ARGUMENTS (fndecl);
+ decl;
+ decl = DECL_CHAIN (decl))
+ if (TREE_USED (decl)
+ && TREE_CODE (decl) == PARM_DECL
+ && !DECL_READ_P (decl)
+ && DECL_NAME (decl)
+ && !DECL_ARTIFICIAL (decl)
+ && !TREE_NO_WARNING (decl)
+ && !DECL_IN_SYSTEM_HEADER (decl)
+ && TREE_TYPE (decl) != error_mark_node
+ && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
+ && (!CLASS_TYPE_P (TREE_TYPE (decl))
+ || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
+ warning (OPT_Wunused_but_set_parameter,
+ "parameter %q+D set but not used", decl);
+ unused_but_set_errorcount = errorcount;
+ }
+
+ /* Complain about locally defined typedefs that are not used in this
+ function. */
+ maybe_warn_unused_local_typedefs ();
+
+ /* Genericize before inlining. */
+ if (!processing_template_decl)
+ {
+ struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl);
+ invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
+ cp_genericize (fndecl);
+ /* Clear out the bits we don't need. */
+ f->x_current_class_ptr = NULL;
+ f->x_current_class_ref = NULL;
+ f->x_eh_spec_block = NULL;
+ f->x_in_charge_parm = NULL;
+ f->x_vtt_parm = NULL;
+ f->x_return_value = NULL;
+ f->bindings = NULL;
+ f->extern_decl_map = NULL;
+ f->infinite_loops = NULL;
+ }
+ /* Clear out the bits we don't need. */
+ local_names = NULL;
+
+ /* We're leaving the context of this function, so zap cfun. It's still in
+ DECL_STRUCT_FUNCTION, and we'll restore it in tree_rest_of_compilation. */
+ set_cfun (NULL);
+ current_function_decl = NULL;
+
+ /* If this is an in-class inline definition, we may have to pop the
+ bindings for the template parameters that we added in
+ maybe_begin_member_template_processing when start_function was
+ called. */
+ if (inclass_inline)
+ maybe_end_member_template_processing ();
+
+ /* Leave the scope of the class. */
+ if (ctype)
+ pop_nested_class ();
+
+ --function_depth;
+
+ /* Clean up. */
+ current_function_decl = NULL_TREE;
+
+ defer_mark_used_calls = false;
+ if (deferred_mark_used_calls)
+ {
+ unsigned int i;
+ tree decl;
+
+ FOR_EACH_VEC_SAFE_ELT (deferred_mark_used_calls, i, decl)
+ mark_used (decl);
+ vec_free (deferred_mark_used_calls);
+ }
+
+ return fndecl;
+}
+
+/* Create the FUNCTION_DECL for a function definition.
+ DECLSPECS and DECLARATOR are the parts of the declaration;
+ they describe the return type and the name of the function,
+ but twisted together in a fashion that parallels the syntax of C.
+
+ This function creates a binding context for the function body
+ as well as setting up the FUNCTION_DECL in current_function_decl.
+
+ Returns a FUNCTION_DECL on success.
+
+ If the DECLARATOR is not suitable for a function (it defines a datum
+ instead), we return 0, which tells yyparse to report a parse error.
+
+ May return void_type_node indicating that this method is actually
+ a friend. See grokfield for more details.
+
+ Came here with a `.pushlevel' .
+
+ DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING
+ CHANGES TO CODE IN `grokfield'. */
+
+tree
+grokmethod (cp_decl_specifier_seq *declspecs,
+ const cp_declarator *declarator, tree attrlist)
+{
+ tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
+ &attrlist);
+
+ if (fndecl == error_mark_node)
+ return error_mark_node;
+
+ if (fndecl == NULL || TREE_CODE (fndecl) != FUNCTION_DECL)
+ {
+ error ("invalid member function declaration");
+ return error_mark_node;
+ }
+
+ if (attrlist)
+ cplus_decl_attributes (&fndecl, attrlist, 0);
+
+ /* Pass friends other than inline friend functions back. */
+ if (fndecl == void_type_node)
+ return fndecl;
+
+ if (DECL_IN_AGGR_P (fndecl))
+ {
+ if (DECL_CLASS_SCOPE_P (fndecl))
+ error ("%qD is already defined in class %qT", fndecl,
+ DECL_CONTEXT (fndecl));
+ return error_mark_node;
+ }
+
+ check_template_shadow (fndecl);
+
+ DECL_DECLARED_INLINE_P (fndecl) = 1;
+ DECL_NO_INLINE_WARNING_P (fndecl) = 1;
+
+ /* We process method specializations in finish_struct_1. */
+ if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl))
+ {
+ fndecl = push_template_decl (fndecl);
+ if (fndecl == error_mark_node)
+ return fndecl;
+ }
+
+ if (! DECL_FRIEND_P (fndecl))
+ {
+ if (DECL_CHAIN (fndecl))
+ {
+ fndecl = copy_node (fndecl);
+ TREE_CHAIN (fndecl) = NULL_TREE;
+ }
+ }
+
+ cp_finish_decl (fndecl, NULL_TREE, false, NULL_TREE, 0);
+
+ DECL_IN_AGGR_P (fndecl) = 1;
+ return fndecl;
+}
+
+
+/* VAR is a VAR_DECL. If its type is incomplete, remember VAR so that
+ we can lay it out later, when and if its type becomes complete.
+
+ Also handle constexpr pointer to member variables where the initializer
+ is an unlowered PTRMEM_CST because the class isn't complete yet. */
+
+void
+maybe_register_incomplete_var (tree var)
+{
+ gcc_assert (VAR_P (var));
+
+ /* Keep track of variables with incomplete types. */
+ if (!processing_template_decl && TREE_TYPE (var) != error_mark_node
+ && DECL_EXTERNAL (var))
+ {
+ tree inner_type = TREE_TYPE (var);
+
+ while (TREE_CODE (inner_type) == ARRAY_TYPE)
+ inner_type = TREE_TYPE (inner_type);
+ inner_type = TYPE_MAIN_VARIANT (inner_type);
+
+ if ((!COMPLETE_TYPE_P (inner_type) && CLASS_TYPE_P (inner_type))
+ /* RTTI TD entries are created while defining the type_info. */
+ || (TYPE_LANG_SPECIFIC (inner_type)
+ && TYPE_BEING_DEFINED (inner_type)))
+ {
+ incomplete_var iv = {var, inner_type};
+ vec_safe_push (incomplete_vars, iv);
+ }
+ else if (TYPE_PTRMEM_P (inner_type)
+ && DECL_INITIAL (var)
+ && TREE_CODE (DECL_INITIAL (var)) == PTRMEM_CST)
+ {
+ tree context = TYPE_PTRMEM_CLASS_TYPE (inner_type);
+ gcc_assert (TYPE_BEING_DEFINED (context));
+ incomplete_var iv = {var, context};
+ vec_safe_push (incomplete_vars, iv);
+ }
+ }
+}
+
+/* Called when a class type (given by TYPE) is defined. If there are
+ any existing VAR_DECLs whose type has been completed by this
+ declaration, update them now. */
+
+void
+complete_vars (tree type)
+{
+ unsigned ix;
+ incomplete_var *iv;
+
+ for (ix = 0; vec_safe_iterate (incomplete_vars, ix, &iv); )
+ {
+ if (same_type_p (type, iv->incomplete_type))
+ {
+ tree var = iv->decl;
+ tree type = TREE_TYPE (var);
+
+ if (TYPE_PTRMEM_P (type))
+ DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var));
+ else
+ {
+ /* Complete the type of the variable. The VAR_DECL itself
+ will be laid out in expand_expr. */
+ complete_type (type);
+ cp_apply_type_quals_to_decl (cp_type_quals (type), var);
+ }
+
+ /* Remove this entry from the list. */
+ incomplete_vars->unordered_remove (ix);
+ }
+ else
+ ix++;
+ }
+
+ /* Check for pending declarations which may have abstract type. */
+ complete_type_check_abstract (type);
+}
+
+/* If DECL is of a type which needs a cleanup, build and return an
+ expression to perform that cleanup here. Return NULL_TREE if no
+ cleanup need be done. */
+
+tree
+cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
+{
+ tree type;
+ tree attr;
+ tree cleanup;
+
+ /* Assume no cleanup is required. */
+ cleanup = NULL_TREE;
+
+ if (error_operand_p (decl))
+ return cleanup;
+
+ /* Handle "__attribute__((cleanup))". We run the cleanup function
+ before the destructor since the destructor is what actually
+ terminates the lifetime of the object. */
+ attr = lookup_attribute ("cleanup", DECL_ATTRIBUTES (decl));
+ if (attr)
+ {
+ tree id;
+ tree fn;
+ tree arg;
+
+ /* Get the name specified by the user for the cleanup function. */
+ id = TREE_VALUE (TREE_VALUE (attr));
+ /* Look up the name to find the cleanup function to call. It is
+ important to use lookup_name here because that is what is
+ used in c-common.c:handle_cleanup_attribute when performing
+ initial checks on the attribute. Note that those checks
+ include ensuring that the function found is not an overloaded
+ function, or an object with an overloaded call operator,
+ etc.; we can rely on the fact that the function found is an
+ ordinary FUNCTION_DECL. */
+ fn = lookup_name (id);
+ arg = build_address (decl);
+ mark_used (decl);
+ cleanup = cp_build_function_call_nary (fn, complain, arg, NULL_TREE);
+ if (cleanup == error_mark_node)
+ return error_mark_node;
+ }
+ /* Handle ordinary C++ destructors. */
+ type = TREE_TYPE (decl);
+ if (type_build_dtor_call (type))
+ {
+ int flags = LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR;
+ tree addr;
+ tree call;
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ addr = decl;
+ else
+ addr = build_address (decl);
+
+ call = build_delete (TREE_TYPE (addr), addr,
+ sfk_complete_destructor, flags, 0, complain);
+ if (call == error_mark_node)
+ cleanup = error_mark_node;
+ else if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+ /* Discard the call. */;
+ else if (cleanup)
+ cleanup = cp_build_compound_expr (cleanup, call, complain);
+ else
+ cleanup = call;
+ }
+
+ /* build_delete sets the location of the destructor call to the
+ current location, even though the destructor is going to be
+ called later, at the end of the current scope. This can lead to
+ a "jumpy" behaviour for users of debuggers when they step around
+ the end of the block. So let's unset the location of the
+ destructor call instead. */
+ if (cleanup != NULL && EXPR_P (cleanup))
+ SET_EXPR_LOCATION (cleanup, UNKNOWN_LOCATION);
+
+ if (cleanup
+ && !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
+ /* Treat objects with destructors as used; the destructor may do
+ something substantive. */
+ mark_used (decl);
+
+ return cleanup;
+}
+
+
+/* Return the FUNCTION_TYPE that corresponds to MEMFNTYPE, which can be a
+ FUNCTION_DECL, METHOD_TYPE, FUNCTION_TYPE, pointer or reference to
+ METHOD_TYPE or FUNCTION_TYPE, or pointer to member function. */
+
+tree
+static_fn_type (tree memfntype)
+{
+ tree fntype;
+ tree args;
+
+ if (TYPE_PTRMEMFUNC_P (memfntype))
+ memfntype = TYPE_PTRMEMFUNC_FN_TYPE (memfntype);
+ if (POINTER_TYPE_P (memfntype)
+ || TREE_CODE (memfntype) == FUNCTION_DECL)
+ memfntype = TREE_TYPE (memfntype);
+ if (TREE_CODE (memfntype) == FUNCTION_TYPE)
+ return memfntype;
+ gcc_assert (TREE_CODE (memfntype) == METHOD_TYPE);
+ args = TYPE_ARG_TYPES (memfntype);
+ cp_ref_qualifier rqual = type_memfn_rqual (memfntype);
+ fntype = build_function_type (TREE_TYPE (memfntype), TREE_CHAIN (args));
+ fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype), rqual);
+ fntype = (cp_build_type_attribute_variant
+ (fntype, TYPE_ATTRIBUTES (memfntype)));
+ fntype = (build_exception_variant
+ (fntype, TYPE_RAISES_EXCEPTIONS (memfntype)));
+ return fntype;
+}
+
+/* DECL was originally constructed as a non-static member function,
+ but turned out to be static. Update it accordingly. */
+
+void
+revert_static_member_fn (tree decl)
+{
+ tree stype = static_fn_type (decl);
+ cp_cv_quals quals = type_memfn_quals (stype);
+ cp_ref_qualifier rqual = type_memfn_rqual (stype);
+
+ if (quals != TYPE_UNQUALIFIED || rqual != REF_QUAL_NONE)
+ stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED, REF_QUAL_NONE);
+
+ TREE_TYPE (decl) = stype;
+
+ if (DECL_ARGUMENTS (decl))
+ DECL_ARGUMENTS (decl) = DECL_CHAIN (DECL_ARGUMENTS (decl));
+ DECL_STATIC_FUNCTION_P (decl) = 1;
+}
+
+/* Return which tree structure is used by T, or TS_CP_GENERIC if T is
+ one of the language-independent trees. */
+
+enum cp_tree_node_structure_enum
+cp_tree_node_structure (union lang_tree_node * t)
+{
+ switch (TREE_CODE (&t->generic))
+ {
+ case DEFAULT_ARG: return TS_CP_DEFAULT_ARG;
+ case DEFERRED_NOEXCEPT: return TS_CP_DEFERRED_NOEXCEPT;
+ case IDENTIFIER_NODE: return TS_CP_IDENTIFIER;
+ case OVERLOAD: return TS_CP_OVERLOAD;
+ case TEMPLATE_PARM_INDEX: return TS_CP_TPI;
+ case PTRMEM_CST: return TS_CP_PTRMEM;
+ case BASELINK: return TS_CP_BASELINK;
+ case STATIC_ASSERT: return TS_CP_STATIC_ASSERT;
+ case ARGUMENT_PACK_SELECT: return TS_CP_ARGUMENT_PACK_SELECT;
+ case TRAIT_EXPR: return TS_CP_TRAIT_EXPR;
+ case LAMBDA_EXPR: return TS_CP_LAMBDA_EXPR;
+ case TEMPLATE_INFO: return TS_CP_TEMPLATE_INFO;
+ case USERDEF_LITERAL: return TS_CP_USERDEF_LITERAL;
+ default: return TS_CP_GENERIC;
+ }
+}
+
+/* Build the void_list_node (void_type_node having been created). */
+tree
+build_void_list_node (void)
+{
+ tree t = build_tree_list (NULL_TREE, void_type_node);
+ return t;
+}
+
+bool
+cp_missing_noreturn_ok_p (tree decl)
+{
+ /* A missing noreturn is ok for the `main' function. */
+ return DECL_MAIN_P (decl);
+}
+
+/* Return the COMDAT group into which DECL should be placed. */
+
+tree
+cxx_comdat_group (tree decl)
+{
+ tree name;
+
+ /* Virtual tables, construction virtual tables, and virtual table
+ tables all go in a single COMDAT group, named after the primary
+ virtual table. */
+ if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl))
+ name = DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (DECL_CONTEXT (decl)));
+ /* For all other DECLs, the COMDAT group is the mangled name of the
+ declaration itself. */
+ else
+ {
+ while (DECL_THUNK_P (decl))
+ {
+ /* If TARGET_USE_LOCAL_THUNK_ALIAS_P, use_thunk puts the thunk
+ into the same section as the target function. In that case
+ we must return target's name. */
+ tree target = THUNK_TARGET (decl);
+ if (TARGET_USE_LOCAL_THUNK_ALIAS_P (target)
+ && DECL_SECTION_NAME (target) != NULL
+ && DECL_ONE_ONLY (target))
+ decl = target;
+ else
+ break;
+ }
+ name = DECL_ASSEMBLER_NAME (decl);
+ }
+
+ return name;
+}
+
+/* Returns the return type for FN as written by the user, which may include
+ a placeholder for a deduced return type. */
+
+tree
+fndecl_declared_return_type (tree fn)
+{
+ fn = STRIP_TEMPLATE (fn);
+ if (FNDECL_USED_AUTO (fn))
+ {
+ struct language_function *f = NULL;
+ if (DECL_STRUCT_FUNCTION (fn))
+ f = DECL_STRUCT_FUNCTION (fn)->language;
+ if (f == NULL)
+ f = DECL_SAVED_FUNCTION_DATA (fn);
+ return f->x_auto_return_pattern;
+ }
+ return TREE_TYPE (TREE_TYPE (fn));
+}
+
+/* Returns true iff DECL was declared with an auto return type and it has
+ not yet been deduced to a real type. */
+
+bool
+undeduced_auto_decl (tree decl)
+{
+ if (cxx_dialect < cxx1y)
+ return false;
+ return type_uses_auto (TREE_TYPE (decl));
+}
+
+/* Complain if DECL has an undeduced return type. */
+
+void
+require_deduced_type (tree decl)
+{
+ if (undeduced_auto_decl (decl))
+ error ("use of %qD before deduction of %<auto%>", decl);
+}
+
+#include "gt-cp-decl.h"
diff --git a/gcc-4.9/gcc/cp/decl.h b/gcc-4.9/gcc/cp/decl.h
new file mode 100644
index 000000000..bb36271ba
--- /dev/null
+++ b/gcc-4.9/gcc/cp/decl.h
@@ -0,0 +1,50 @@
+/* Variables and structures for declaration processing.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* In grokdeclarator, distinguish syntactic contexts of declarators. */
+enum decl_context
+{ NORMAL, /* Ordinary declaration */
+ FUNCDEF, /* Function definition */
+ PARM, /* Declaration of parm before function body */
+ TPARM, /* Declaration of template parm */
+ CATCHPARM, /* Declaration of catch parm */
+ FIELD, /* Declaration inside struct or union */
+ BITFIELD, /* Likewise but with specified width */
+ TYPENAME, /* Typename (inside cast or sizeof) */
+ TEMPLATE_TYPE_ARG, /* Almost the same as TYPENAME */
+ MEMFUNCDEF /* Member function definition */
+};
+
+/* We need this in here to get the decl_context definition. */
+extern tree grokdeclarator (const cp_declarator *,
+ cp_decl_specifier_seq *,
+ enum decl_context, int, tree*);
+
+/* States indicating how grokdeclarator() should handle declspecs marked
+ with __attribute__((deprecated)). An object declared as
+ __attribute__((deprecated)) suppresses warnings of uses of other
+ deprecated items. */
+
+enum deprecated_states {
+ DEPRECATED_NORMAL,
+ DEPRECATED_SUPPRESS
+};
+
+extern enum deprecated_states deprecated_state;
+
diff --git a/gcc-4.9/gcc/cp/decl2.c b/gcc-4.9/gcc/cp/decl2.c
new file mode 100644
index 000000000..dfc532d5b
--- /dev/null
+++ b/gcc-4.9/gcc/cp/decl2.c
@@ -0,0 +1,5011 @@
+/* Process declarations and variables for C++ compiler.
+ Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Hacked by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* Process declarations and symbol lookup for C++ front end.
+ Also constructs types; the standard scalar types at initialization,
+ and structure, union, array and enum types when they are declared. */
+
+/* ??? not all decl nodes are given the most useful possible
+ line numbers. For example, the CONST_DECLs for enum values. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "varasm.h"
+#include "attribs.h"
+#include "stor-layout.h"
+#include "calls.h"
+#include "pointer-set.h"
+#include "flags.h"
+#include "cp-tree.h"
+#include "decl.h"
+#include "toplev.h"
+#include "timevar.h"
+#include "cpplib.h"
+#include "target.h"
+#include "c-family/c-common.h"
+#include "c-family/c-objc.h"
+#include "cgraph.h"
+#include "tree-inline.h"
+#include "c-family/c-pragma.h"
+#include "dumpfile.h"
+#include "intl.h"
+#include "splay-tree.h"
+#include "langhooks.h"
+#include "c-family/c-ada-spec.h"
+#include "asan.h"
+
+extern cpp_reader *parse_in;
+
+/* This structure contains information about the initializations
+ and/or destructions required for a particular priority level. */
+typedef struct priority_info_s {
+ /* Nonzero if there have been any initializations at this priority
+ throughout the translation unit. */
+ int initializations_p;
+ /* Nonzero if there have been any destructions at this priority
+ throughout the translation unit. */
+ int destructions_p;
+} *priority_info;
+
+static void mark_vtable_entries (tree);
+static bool maybe_emit_vtables (tree);
+static bool acceptable_java_type (tree);
+static tree start_objects (int, int);
+static void finish_objects (int, int, tree);
+static tree start_static_storage_duration_function (unsigned);
+static void finish_static_storage_duration_function (tree);
+static priority_info get_priority_info (int);
+static void do_static_initialization_or_destruction (tree, bool);
+static void one_static_initialization_or_destruction (tree, tree, bool);
+static void generate_ctor_or_dtor_function (bool, int, location_t *);
+static int generate_ctor_and_dtor_functions_for_priority (splay_tree_node,
+ void *);
+static tree prune_vars_needing_no_initialization (tree *);
+static void write_out_vars (tree);
+static void import_export_class (tree);
+static tree get_guard_bits (tree);
+static void determine_visibility_from_class (tree, tree);
+static bool determine_hidden_inline (tree);
+static bool decl_defined_p (tree);
+
+/* A list of static class variables. This is needed, because a
+ static class variable can be declared inside the class without
+ an initializer, and then initialized, statically, outside the class. */
+static GTY(()) vec<tree, va_gc> *pending_statics;
+
+/* A list of functions which were declared inline, but which we
+ may need to emit outline anyway. */
+static GTY(()) vec<tree, va_gc> *deferred_fns;
+
+/* A list of decls that use types with no linkage, which we need to make
+ sure are defined. */
+static GTY(()) vec<tree, va_gc> *no_linkage_decls;
+
+/* Nonzero if we're done parsing and into end-of-file activities. */
+
+int at_eof;
+
+
+/* Return a member function type (a METHOD_TYPE), given FNTYPE (a
+ FUNCTION_TYPE), CTYPE (class type), and QUALS (the cv-qualifiers
+ that apply to the function). */
+
+tree
+build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals,
+ cp_ref_qualifier rqual)
+{
+ tree raises;
+ tree attrs;
+ int type_quals;
+
+ if (fntype == error_mark_node || ctype == error_mark_node)
+ return error_mark_node;
+
+ gcc_assert (TREE_CODE (fntype) == FUNCTION_TYPE
+ || TREE_CODE (fntype) == METHOD_TYPE);
+
+ type_quals = quals & ~TYPE_QUAL_RESTRICT;
+ ctype = cp_build_qualified_type (ctype, type_quals);
+ raises = TYPE_RAISES_EXCEPTIONS (fntype);
+ attrs = TYPE_ATTRIBUTES (fntype);
+ fntype = build_method_type_directly (ctype, TREE_TYPE (fntype),
+ (TREE_CODE (fntype) == METHOD_TYPE
+ ? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
+ : TYPE_ARG_TYPES (fntype)));
+ if (attrs)
+ fntype = cp_build_type_attribute_variant (fntype, attrs);
+ if (rqual)
+ fntype = build_ref_qualified_type (fntype, rqual);
+ if (raises)
+ fntype = build_exception_variant (fntype, raises);
+
+ return fntype;
+}
+
+/* Return a variant of FNTYPE, a FUNCTION_TYPE or METHOD_TYPE, with its
+ return type changed to NEW_RET. */
+
+tree
+change_return_type (tree new_ret, tree fntype)
+{
+ tree newtype;
+ tree args = TYPE_ARG_TYPES (fntype);
+ tree raises = TYPE_RAISES_EXCEPTIONS (fntype);
+ tree attrs = TYPE_ATTRIBUTES (fntype);
+
+ if (new_ret == error_mark_node)
+ return fntype;
+
+ if (same_type_p (new_ret, TREE_TYPE (fntype)))
+ return fntype;
+
+ if (TREE_CODE (fntype) == FUNCTION_TYPE)
+ {
+ newtype = build_function_type (new_ret, args);
+ newtype = apply_memfn_quals (newtype,
+ type_memfn_quals (fntype),
+ type_memfn_rqual (fntype));
+ }
+ else
+ newtype = build_method_type_directly
+ (class_of_this_parm (fntype), new_ret, TREE_CHAIN (args));
+ if (raises)
+ newtype = build_exception_variant (newtype, raises);
+ if (attrs)
+ newtype = cp_build_type_attribute_variant (newtype, attrs);
+
+ return newtype;
+}
+
+/* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE
+ appropriately. */
+
+tree
+cp_build_parm_decl (tree name, tree type)
+{
+ tree parm = build_decl (input_location,
+ PARM_DECL, name, type);
+ /* DECL_ARG_TYPE is only used by the back end and the back end never
+ sees templates. */
+ if (!processing_template_decl)
+ DECL_ARG_TYPE (parm) = type_passed_as (type);
+
+ return parm;
+}
+
+/* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
+ indicated NAME. */
+
+tree
+build_artificial_parm (tree name, tree type)
+{
+ tree parm = cp_build_parm_decl (name, type);
+ DECL_ARTIFICIAL (parm) = 1;
+ /* All our artificial parms are implicitly `const'; they cannot be
+ assigned to. */
+ TREE_READONLY (parm) = 1;
+ return parm;
+}
+
+/* Constructors for types with virtual baseclasses need an "in-charge" flag
+ saying whether this constructor is responsible for initialization of
+ virtual baseclasses or not. All destructors also need this "in-charge"
+ flag, which additionally determines whether or not the destructor should
+ free the memory for the object.
+
+ This function adds the "in-charge" flag to member function FN if
+ appropriate. It is called from grokclassfn and tsubst.
+ FN must be either a constructor or destructor.
+
+ The in-charge flag follows the 'this' parameter, and is followed by the
+ VTT parm (if any), then the user-written parms. */
+
+void
+maybe_retrofit_in_chrg (tree fn)
+{
+ tree basetype, arg_types, parms, parm, fntype;
+
+ /* If we've already add the in-charge parameter don't do it again. */
+ if (DECL_HAS_IN_CHARGE_PARM_P (fn))
+ return;
+
+ /* When processing templates we can't know, in general, whether or
+ not we're going to have virtual baseclasses. */
+ if (processing_template_decl)
+ return;
+
+ /* We don't need an in-charge parameter for constructors that don't
+ have virtual bases. */
+ if (DECL_CONSTRUCTOR_P (fn)
+ && !CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
+ return;
+
+ arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ basetype = TREE_TYPE (TREE_VALUE (arg_types));
+ arg_types = TREE_CHAIN (arg_types);
+
+ parms = DECL_CHAIN (DECL_ARGUMENTS (fn));
+
+ /* If this is a subobject constructor or destructor, our caller will
+ pass us a pointer to our VTT. */
+ if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
+ {
+ parm = build_artificial_parm (vtt_parm_identifier, vtt_parm_type);
+
+ /* First add it to DECL_ARGUMENTS between 'this' and the real args... */
+ DECL_CHAIN (parm) = parms;
+ parms = parm;
+
+ /* ...and then to TYPE_ARG_TYPES. */
+ arg_types = hash_tree_chain (vtt_parm_type, arg_types);
+
+ DECL_HAS_VTT_PARM_P (fn) = 1;
+ }
+
+ /* Then add the in-charge parm (before the VTT parm). */
+ parm = build_artificial_parm (in_charge_identifier, integer_type_node);
+ DECL_CHAIN (parm) = parms;
+ parms = parm;
+ arg_types = hash_tree_chain (integer_type_node, arg_types);
+
+ /* Insert our new parameter(s) into the list. */
+ DECL_CHAIN (DECL_ARGUMENTS (fn)) = parms;
+
+ /* And rebuild the function type. */
+ fntype = build_method_type_directly (basetype, TREE_TYPE (TREE_TYPE (fn)),
+ arg_types);
+ if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
+ fntype = build_exception_variant (fntype,
+ TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)));
+ if (TYPE_ATTRIBUTES (TREE_TYPE (fn)))
+ fntype = (cp_build_type_attribute_variant
+ (fntype, TYPE_ATTRIBUTES (TREE_TYPE (fn))));
+ TREE_TYPE (fn) = fntype;
+
+ /* Now we've got the in-charge parameter. */
+ DECL_HAS_IN_CHARGE_PARM_P (fn) = 1;
+}
+
+/* Classes overload their constituent function names automatically.
+ When a function name is declared in a record structure,
+ its name is changed to it overloaded name. Since names for
+ constructors and destructors can conflict, we place a leading
+ '$' for destructors.
+
+ CNAME is the name of the class we are grokking for.
+
+ FUNCTION is a FUNCTION_DECL. It was created by `grokdeclarator'.
+
+ FLAGS contains bits saying what's special about today's
+ arguments. DTOR_FLAG == DESTRUCTOR.
+
+ If FUNCTION is a destructor, then we must add the `auto-delete' field
+ as a second parameter. There is some hair associated with the fact
+ that we must "declare" this variable in the manner consistent with the
+ way the rest of the arguments were declared.
+
+ QUALS are the qualifiers for the this pointer. */
+
+void
+grokclassfn (tree ctype, tree function, enum overload_flags flags)
+{
+ tree fn_name = DECL_NAME (function);
+
+ /* Even within an `extern "C"' block, members get C++ linkage. See
+ [dcl.link] for details. */
+ SET_DECL_LANGUAGE (function, lang_cplusplus);
+
+ if (fn_name == NULL_TREE)
+ {
+ error ("name missing for member function");
+ fn_name = get_identifier ("<anonymous>");
+ DECL_NAME (function) = fn_name;
+ }
+
+ DECL_CONTEXT (function) = ctype;
+
+ if (flags == DTOR_FLAG)
+ DECL_DESTRUCTOR_P (function) = 1;
+
+ if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))
+ maybe_retrofit_in_chrg (function);
+}
+
+/* Create an ARRAY_REF, checking for the user doing things backwards
+ along the way. DECLTYPE_P is for N3276, as in the parser. */
+
+tree
+grok_array_decl (location_t loc, tree array_expr, tree index_exp,
+ bool decltype_p)
+{
+ tree type;
+ tree expr;
+ tree orig_array_expr = array_expr;
+ tree orig_index_exp = index_exp;
+
+ if (error_operand_p (array_expr) || error_operand_p (index_exp))
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (array_expr)
+ || type_dependent_expression_p (index_exp))
+ return build_min_nt_loc (loc, ARRAY_REF, array_expr, index_exp,
+ NULL_TREE, NULL_TREE);
+ array_expr = build_non_dependent_expr (array_expr);
+ index_exp = build_non_dependent_expr (index_exp);
+ }
+
+ type = TREE_TYPE (array_expr);
+ gcc_assert (type);
+ type = non_reference (type);
+
+ /* If they have an `operator[]', use that. */
+ if (MAYBE_CLASS_TYPE_P (type) || MAYBE_CLASS_TYPE_P (TREE_TYPE (index_exp)))
+ {
+ tsubst_flags_t complain = tf_warning_or_error;
+ if (decltype_p)
+ complain |= tf_decltype;
+ expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, array_expr,
+ index_exp, NULL_TREE, /*overload=*/NULL, complain);
+ }
+ else
+ {
+ tree p1, p2, i1, i2;
+
+ /* Otherwise, create an ARRAY_REF for a pointer or array type.
+ It is a little-known fact that, if `a' is an array and `i' is
+ an int, you can write `i[a]', which means the same thing as
+ `a[i]'. */
+ if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
+ p1 = array_expr;
+ else
+ p1 = build_expr_type_conversion (WANT_POINTER, array_expr, false);
+
+ if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE)
+ p2 = index_exp;
+ else
+ p2 = build_expr_type_conversion (WANT_POINTER, index_exp, false);
+
+ i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr,
+ false);
+ i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp,
+ false);
+
+ if ((p1 && i2) && (i1 && p2))
+ error ("ambiguous conversion for array subscript");
+
+ if (p1 && i2)
+ array_expr = p1, index_exp = i2;
+ else if (i1 && p2)
+ array_expr = p2, index_exp = i1;
+ else
+ {
+ error ("invalid types %<%T[%T]%> for array subscript",
+ type, TREE_TYPE (index_exp));
+ return error_mark_node;
+ }
+
+ if (array_expr == error_mark_node || index_exp == error_mark_node)
+ error ("ambiguous conversion for array subscript");
+
+ expr = build_array_ref (input_location, array_expr, index_exp);
+ }
+ if (processing_template_decl && expr != error_mark_node)
+ return build_min_non_dep (ARRAY_REF, expr, orig_array_expr, orig_index_exp,
+ NULL_TREE, NULL_TREE);
+ return expr;
+}
+
+/* Given the cast expression EXP, checking out its validity. Either return
+ an error_mark_node if there was an unavoidable error, return a cast to
+ void for trying to delete a pointer w/ the value 0, or return the
+ call to delete. If DOING_VEC is true, we handle things differently
+ for doing an array delete.
+ Implements ARM $5.3.4. This is called from the parser. */
+
+tree
+delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete,
+ tsubst_flags_t complain)
+{
+ tree t, type;
+
+ if (exp == error_mark_node)
+ return exp;
+
+ if (processing_template_decl)
+ {
+ t = build_min (DELETE_EXPR, void_type_node, exp, size);
+ DELETE_EXPR_USE_GLOBAL (t) = use_global_delete;
+ DELETE_EXPR_USE_VEC (t) = doing_vec;
+ TREE_SIDE_EFFECTS (t) = 1;
+ return t;
+ }
+
+ /* An array can't have been allocated by new, so complain. */
+ if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+ warning (0, "deleting array %q#E", exp);
+
+ t = build_expr_type_conversion (WANT_POINTER, exp, true);
+
+ if (t == NULL_TREE || t == error_mark_node)
+ {
+ error ("type %q#T argument given to %<delete%>, expected pointer",
+ TREE_TYPE (exp));
+ return error_mark_node;
+ }
+
+ type = TREE_TYPE (t);
+
+ /* As of Valley Forge, you can delete a pointer to const. */
+
+ /* You can't delete functions. */
+ if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
+ {
+ error ("cannot delete a function. Only pointer-to-objects are "
+ "valid arguments to %<delete%>");
+ return error_mark_node;
+ }
+
+ /* Deleting ptr to void is undefined behavior [expr.delete/3]. */
+ if (VOID_TYPE_P (TREE_TYPE (type)))
+ {
+ warning (0, "deleting %qT is undefined", type);
+ doing_vec = 0;
+ }
+
+ /* Deleting a pointer with the value zero is valid and has no effect. */
+ if (integer_zerop (t))
+ return build1 (NOP_EXPR, void_type_node, t);
+
+ if (doing_vec)
+ return build_vec_delete (t, /*maxindex=*/NULL_TREE,
+ sfk_deleting_destructor,
+ use_global_delete, complain);
+ else
+ return build_delete (type, t, sfk_deleting_destructor,
+ LOOKUP_NORMAL, use_global_delete,
+ complain);
+}
+
+/* Report an error if the indicated template declaration is not the
+ sort of thing that should be a member template. */
+
+void
+check_member_template (tree tmpl)
+{
+ tree decl;
+
+ gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
+ decl = DECL_TEMPLATE_RESULT (tmpl);
+
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ || DECL_ALIAS_TEMPLATE_P (tmpl)
+ || (TREE_CODE (decl) == TYPE_DECL
+ && MAYBE_CLASS_TYPE_P (TREE_TYPE (decl))))
+ {
+ /* The parser rejects template declarations in local classes
+ (with the exception of generic lambdas). */
+ gcc_assert (!current_function_decl || LAMBDA_FUNCTION_P (decl));
+ /* The parser rejects any use of virtual in a function template. */
+ gcc_assert (!(TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_VIRTUAL_P (decl)));
+
+ /* The debug-information generating code doesn't know what to do
+ with member templates. */
+ DECL_IGNORED_P (tmpl) = 1;
+ }
+ else
+ error ("template declaration of %q#D", decl);
+}
+
+/* Return true iff TYPE is a valid Java parameter or return type. */
+
+static bool
+acceptable_java_type (tree type)
+{
+ if (type == error_mark_node)
+ return false;
+
+ if (VOID_TYPE_P (type) || TYPE_FOR_JAVA (type))
+ return true;
+ if (TYPE_PTR_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ type = TREE_TYPE (type);
+ if (TREE_CODE (type) == RECORD_TYPE)
+ {
+ tree args; int i;
+ if (! TYPE_FOR_JAVA (type))
+ return false;
+ if (! CLASSTYPE_TEMPLATE_INFO (type))
+ return true;
+ args = CLASSTYPE_TI_ARGS (type);
+ i = TREE_VEC_LENGTH (args);
+ while (--i >= 0)
+ {
+ type = TREE_VEC_ELT (args, i);
+ if (TYPE_PTR_P (type))
+ type = TREE_TYPE (type);
+ if (! TYPE_FOR_JAVA (type))
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+/* For a METHOD in a Java class CTYPE, return true if
+ the parameter and return types are valid Java types.
+ Otherwise, print appropriate error messages, and return false. */
+
+bool
+check_java_method (tree method)
+{
+ bool jerr = false;
+ tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
+ tree ret_type = TREE_TYPE (TREE_TYPE (method));
+
+ if (!acceptable_java_type (ret_type))
+ {
+ error ("Java method %qD has non-Java return type %qT",
+ method, ret_type);
+ jerr = true;
+ }
+
+ arg_types = TREE_CHAIN (arg_types);
+ if (DECL_HAS_IN_CHARGE_PARM_P (method))
+ arg_types = TREE_CHAIN (arg_types);
+ if (DECL_HAS_VTT_PARM_P (method))
+ arg_types = TREE_CHAIN (arg_types);
+
+ for (; arg_types != NULL_TREE; arg_types = TREE_CHAIN (arg_types))
+ {
+ tree type = TREE_VALUE (arg_types);
+ if (!acceptable_java_type (type))
+ {
+ if (type != error_mark_node)
+ error ("Java method %qD has non-Java parameter type %qT",
+ method, type);
+ jerr = true;
+ }
+ }
+ return !jerr;
+}
+
+/* Sanity check: report error if this function FUNCTION is not
+ really a member of the class (CTYPE) it is supposed to belong to.
+ TEMPLATE_PARMS is used to specify the template parameters of a member
+ template passed as FUNCTION_DECL. If the member template is passed as a
+ TEMPLATE_DECL, it can be NULL since the parameters can be extracted
+ from the declaration. If the function is not a function template, it
+ must be NULL.
+ It returns the original declaration for the function, NULL_TREE if
+ no declaration was found, error_mark_node if an error was emitted. */
+
+tree
+check_classfn (tree ctype, tree function, tree template_parms)
+{
+ int ix;
+ bool is_template;
+ tree pushed_scope;
+
+ if (DECL_USE_TEMPLATE (function)
+ && !(TREE_CODE (function) == TEMPLATE_DECL
+ && DECL_TEMPLATE_SPECIALIZATION (function))
+ && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (function)))
+ /* Since this is a specialization of a member template,
+ we're not going to find the declaration in the class.
+ For example, in:
+
+ struct S { template <typename T> void f(T); };
+ template <> void S::f(int);
+
+ we're not going to find `S::f(int)', but there's no
+ reason we should, either. We let our callers know we didn't
+ find the method, but we don't complain. */
+ return NULL_TREE;
+
+ /* Basic sanity check: for a template function, the template parameters
+ either were not passed, or they are the same of DECL_TEMPLATE_PARMS. */
+ if (TREE_CODE (function) == TEMPLATE_DECL)
+ {
+ if (template_parms
+ && !comp_template_parms (template_parms,
+ DECL_TEMPLATE_PARMS (function)))
+ {
+ error ("template parameter lists provided don%'t match the "
+ "template parameters of %qD", function);
+ return error_mark_node;
+ }
+ template_parms = DECL_TEMPLATE_PARMS (function);
+ }
+
+ /* OK, is this a definition of a member template? */
+ is_template = (template_parms != NULL_TREE);
+
+ /* [temp.mem]
+
+ A destructor shall not be a member template. */
+ if (DECL_DESTRUCTOR_P (function) && is_template)
+ {
+ error ("destructor %qD declared as member template", function);
+ return error_mark_node;
+ }
+
+ /* We must enter the scope here, because conversion operators are
+ named by target type, and type equivalence relies on typenames
+ resolving within the scope of CTYPE. */
+ pushed_scope = push_scope (ctype);
+ ix = class_method_index_for_fn (complete_type (ctype), function);
+ if (ix >= 0)
+ {
+ vec<tree, va_gc> *methods = CLASSTYPE_METHOD_VEC (ctype);
+ tree fndecls, fndecl = 0;
+ bool is_conv_op;
+ const char *format = NULL;
+
+ for (fndecls = (*methods)[ix];
+ fndecls; fndecls = OVL_NEXT (fndecls))
+ {
+ tree p1, p2;
+
+ fndecl = OVL_CURRENT (fndecls);
+ p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
+ p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+
+ /* We cannot simply call decls_match because this doesn't
+ work for static member functions that are pretending to
+ be methods, and because the name may have been changed by
+ asm("new_name"). */
+
+ /* Get rid of the this parameter on functions that become
+ static. */
+ if (DECL_STATIC_FUNCTION_P (fndecl)
+ && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
+ p1 = TREE_CHAIN (p1);
+
+ /* A member template definition only matches a member template
+ declaration. */
+ if (is_template != (TREE_CODE (fndecl) == TEMPLATE_DECL))
+ continue;
+
+ /* ref-qualifier or absence of same must match. */
+ if (type_memfn_rqual (TREE_TYPE (function))
+ != type_memfn_rqual (TREE_TYPE (fndecl)))
+ continue;
+
+ /* While finding a match, same types and params are not enough
+ if the function is versioned. Also check version ("target")
+ attributes. */
+ if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
+ TREE_TYPE (TREE_TYPE (fndecl)))
+ && compparms (p1, p2)
+ && !targetm.target_option.function_versions (function, fndecl)
+ && (!is_template
+ || comp_template_parms (template_parms,
+ DECL_TEMPLATE_PARMS (fndecl)))
+ && (DECL_TEMPLATE_SPECIALIZATION (function)
+ == DECL_TEMPLATE_SPECIALIZATION (fndecl))
+ && (!DECL_TEMPLATE_SPECIALIZATION (function)
+ || (DECL_TI_TEMPLATE (function)
+ == DECL_TI_TEMPLATE (fndecl))))
+ break;
+ }
+ if (fndecls)
+ {
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ return OVL_CURRENT (fndecls);
+ }
+
+ error_at (DECL_SOURCE_LOCATION (function),
+ "prototype for %q#D does not match any in class %qT",
+ function, ctype);
+ is_conv_op = DECL_CONV_FN_P (fndecl);
+
+ if (is_conv_op)
+ ix = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ fndecls = (*methods)[ix];
+ while (fndecls)
+ {
+ fndecl = OVL_CURRENT (fndecls);
+ fndecls = OVL_NEXT (fndecls);
+
+ if (!fndecls && is_conv_op)
+ {
+ if (methods->length () > (size_t) ++ix)
+ {
+ fndecls = (*methods)[ix];
+ if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls)))
+ {
+ fndecls = NULL_TREE;
+ is_conv_op = false;
+ }
+ }
+ else
+ is_conv_op = false;
+ }
+ if (format)
+ format = " %+#D";
+ else if (fndecls)
+ format = N_("candidates are: %+#D");
+ else
+ format = N_("candidate is: %+#D");
+ error (format, fndecl);
+ }
+ }
+ else if (!COMPLETE_TYPE_P (ctype))
+ cxx_incomplete_type_error (function, ctype);
+ else
+ error ("no %q#D member function declared in class %qT",
+ function, ctype);
+
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ return error_mark_node;
+}
+
+/* DECL is a function with vague linkage. Remember it so that at the
+ end of the translation unit we can decide whether or not to emit
+ it. */
+
+void
+note_vague_linkage_fn (tree decl)
+{
+ DECL_DEFER_OUTPUT (decl) = 1;
+ vec_safe_push (deferred_fns, decl);
+}
+
+/* We have just processed the DECL, which is a static data member.
+ The other parameters are as for cp_finish_decl. */
+
+void
+finish_static_data_member_decl (tree decl,
+ tree init, bool init_const_expr_p,
+ tree asmspec_tree,
+ int flags)
+{
+ DECL_CONTEXT (decl) = current_class_type;
+
+ /* We cannot call pushdecl here, because that would fill in the
+ TREE_CHAIN of our decl. Instead, we modify cp_finish_decl to do
+ the right thing, namely, to put this decl out straight away. */
+
+ if (! processing_template_decl)
+ vec_safe_push (pending_statics, decl);
+
+ if (LOCAL_CLASS_P (current_class_type)
+ /* We already complained about the template definition. */
+ && !DECL_TEMPLATE_INSTANTIATION (decl))
+ permerror (input_location, "local class %q#T shall not have static data member %q#D",
+ current_class_type, decl);
+ else
+ for (tree t = current_class_type; TYPE_P (t);
+ t = CP_TYPE_CONTEXT (t))
+ if (TYPE_ANONYMOUS_P (t))
+ {
+ if (permerror (DECL_SOURCE_LOCATION (decl),
+ "static data member %qD in unnamed class", decl))
+ inform (DECL_SOURCE_LOCATION (TYPE_NAME (t)),
+ "unnamed class defined here");
+ break;
+ }
+
+ DECL_IN_AGGR_P (decl) = 1;
+
+ if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
+ && TYPE_DOMAIN (TREE_TYPE (decl)) == NULL_TREE)
+ SET_VAR_HAD_UNKNOWN_BOUND (decl);
+
+ cp_finish_decl (decl, init, init_const_expr_p, asmspec_tree, flags);
+}
+
+/* DECLARATOR and DECLSPECS correspond to a class member. The other
+ parameters are as for cp_finish_decl. Return the DECL for the
+ class member declared. */
+
+tree
+grokfield (const cp_declarator *declarator,
+ cp_decl_specifier_seq *declspecs,
+ tree init, bool init_const_expr_p,
+ tree asmspec_tree,
+ tree attrlist)
+{
+ tree value;
+ const char *asmspec = 0;
+ int flags;
+ tree name;
+
+ if (init
+ && TREE_CODE (init) == TREE_LIST
+ && TREE_VALUE (init) == error_mark_node
+ && TREE_CHAIN (init) == NULL_TREE)
+ init = NULL_TREE;
+
+ value = grokdeclarator (declarator, declspecs, FIELD, init != 0, &attrlist);
+ if (! value || value == error_mark_node)
+ /* friend or constructor went bad. */
+ return error_mark_node;
+ if (TREE_TYPE (value) == error_mark_node)
+ return value;
+
+ if (TREE_CODE (value) == TYPE_DECL && init)
+ {
+ error ("typedef %qD is initialized (use decltype instead)", value);
+ init = NULL_TREE;
+ }
+
+ /* Pass friendly classes back. */
+ if (value == void_type_node)
+ return value;
+
+ /* Pass friend decls back. */
+ if ((TREE_CODE (value) == FUNCTION_DECL
+ || TREE_CODE (value) == TEMPLATE_DECL)
+ && DECL_CONTEXT (value) != current_class_type)
+ return value;
+
+ name = DECL_NAME (value);
+
+ if (name != NULL_TREE)
+ {
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ error ("explicit template argument list not allowed");
+ return error_mark_node;
+ }
+
+ if (IDENTIFIER_POINTER (name)[0] == '_'
+ && ! strcmp (IDENTIFIER_POINTER (name), "_vptr"))
+ error ("member %qD conflicts with virtual function table field name",
+ value);
+ }
+
+ /* Stash away type declarations. */
+ if (TREE_CODE (value) == TYPE_DECL)
+ {
+ DECL_NONLOCAL (value) = 1;
+ DECL_CONTEXT (value) = current_class_type;
+
+ if (attrlist)
+ {
+ int attrflags = 0;
+
+ /* If this is a typedef that names the class for linkage purposes
+ (7.1.3p8), apply any attributes directly to the type. */
+ if (OVERLOAD_TYPE_P (TREE_TYPE (value))
+ && value == TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (value))))
+ attrflags = ATTR_FLAG_TYPE_IN_PLACE;
+
+ cplus_decl_attributes (&value, attrlist, attrflags);
+ }
+
+ if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)
+ && TREE_TYPE (value) != error_mark_node
+ && TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (value))) != value)
+ set_underlying_type (value);
+
+ /* It's important that push_template_decl below follows
+ set_underlying_type above so that the created template
+ carries the properly set type of VALUE. */
+ if (processing_template_decl)
+ value = push_template_decl (value);
+
+ record_locally_defined_typedef (value);
+ return value;
+ }
+
+ if (DECL_IN_AGGR_P (value))
+ {
+ error ("%qD is already defined in %qT", value, DECL_CONTEXT (value));
+ return void_type_node;
+ }
+
+ if (asmspec_tree && asmspec_tree != error_mark_node)
+ asmspec = TREE_STRING_POINTER (asmspec_tree);
+
+ if (init)
+ {
+ if (TREE_CODE (value) == FUNCTION_DECL)
+ {
+ /* Initializers for functions are rejected early in the parser.
+ If we get here, it must be a pure specifier for a method. */
+ if (init == ridpointers[(int)RID_DELETE])
+ {
+ DECL_DELETED_FN (value) = 1;
+ DECL_DECLARED_INLINE_P (value) = 1;
+ DECL_INITIAL (value) = error_mark_node;
+ }
+ else if (init == ridpointers[(int)RID_DEFAULT])
+ {
+ if (defaultable_fn_check (value))
+ {
+ DECL_DEFAULTED_FN (value) = 1;
+ DECL_INITIALIZED_IN_CLASS_P (value) = 1;
+ DECL_DECLARED_INLINE_P (value) = 1;
+ }
+ }
+ else if (TREE_CODE (init) == DEFAULT_ARG)
+ error ("invalid initializer for member function %qD", value);
+ else if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE)
+ {
+ if (integer_zerop (init))
+ DECL_PURE_VIRTUAL_P (value) = 1;
+ else if (error_operand_p (init))
+ ; /* An error has already been reported. */
+ else
+ error ("invalid initializer for member function %qD",
+ value);
+ }
+ else
+ {
+ gcc_assert (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE);
+ error ("initializer specified for static member function %qD",
+ value);
+ }
+ }
+ else if (TREE_CODE (value) == FIELD_DECL)
+ /* C++11 NSDMI, keep going. */;
+ else if (!VAR_P (value))
+ gcc_unreachable ();
+ }
+
+ if (processing_template_decl && VAR_OR_FUNCTION_DECL_P (value))
+ {
+ value = push_template_decl (value);
+ if (error_operand_p (value))
+ return error_mark_node;
+ }
+
+ if (attrlist)
+ cplus_decl_attributes (&value, attrlist, 0);
+
+ if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
+ && CONSTRUCTOR_IS_DIRECT_INIT (init))
+ flags = LOOKUP_NORMAL;
+ else
+ flags = LOOKUP_IMPLICIT;
+
+ switch (TREE_CODE (value))
+ {
+ case VAR_DECL:
+ finish_static_data_member_decl (value, init, init_const_expr_p,
+ asmspec_tree, flags);
+ return value;
+
+ case FIELD_DECL:
+ if (asmspec)
+ error ("%<asm%> specifiers are not permitted on non-static data members");
+ if (DECL_INITIAL (value) == error_mark_node)
+ init = error_mark_node;
+ cp_finish_decl (value, init, /*init_const_expr_p=*/false,
+ NULL_TREE, flags);
+ DECL_IN_AGGR_P (value) = 1;
+ return value;
+
+ case FUNCTION_DECL:
+ if (asmspec)
+ set_user_assembler_name (value, asmspec);
+
+ cp_finish_decl (value,
+ /*init=*/NULL_TREE,
+ /*init_const_expr_p=*/false,
+ asmspec_tree, flags);
+
+ /* Pass friends back this way. */
+ if (DECL_FRIEND_P (value))
+ return void_type_node;
+
+ DECL_IN_AGGR_P (value) = 1;
+ return value;
+
+ default:
+ gcc_unreachable ();
+ }
+ return NULL_TREE;
+}
+
+/* Like `grokfield', but for bitfields.
+ WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. */
+
+tree
+grokbitfield (const cp_declarator *declarator,
+ cp_decl_specifier_seq *declspecs, tree width,
+ tree attrlist)
+{
+ tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, &attrlist);
+
+ if (value == error_mark_node)
+ return NULL_TREE; /* friends went bad. */
+ if (TREE_TYPE (value) == error_mark_node)
+ return value;
+
+ /* Pass friendly classes back. */
+ if (VOID_TYPE_P (value))
+ return void_type_node;
+
+ if (!INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (value))
+ && (POINTER_TYPE_P (value)
+ || !dependent_type_p (TREE_TYPE (value))))
+ {
+ error ("bit-field %qD with non-integral type", value);
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (value) == TYPE_DECL)
+ {
+ error ("cannot declare %qD to be a bit-field type", value);
+ return NULL_TREE;
+ }
+
+ /* Usually, finish_struct_1 catches bitfields with invalid types.
+ But, in the case of bitfields with function type, we confuse
+ ourselves into thinking they are member functions, so we must
+ check here. */
+ if (TREE_CODE (value) == FUNCTION_DECL)
+ {
+ error ("cannot declare bit-field %qD with function type",
+ DECL_NAME (value));
+ return NULL_TREE;
+ }
+
+ if (DECL_IN_AGGR_P (value))
+ {
+ error ("%qD is already defined in the class %qT", value,
+ DECL_CONTEXT (value));
+ return void_type_node;
+ }
+
+ if (TREE_STATIC (value))
+ {
+ error ("static member %qD cannot be a bit-field", value);
+ return NULL_TREE;
+ }
+ cp_finish_decl (value, NULL_TREE, false, NULL_TREE, 0);
+
+ if (width != error_mark_node)
+ {
+ /* The width must be an integer type. */
+ if (!type_dependent_expression_p (width)
+ && !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (width)))
+ error ("width of bit-field %qD has non-integral type %qT", value,
+ TREE_TYPE (width));
+ DECL_INITIAL (value) = width;
+ SET_DECL_C_BIT_FIELD (value);
+ }
+
+ DECL_IN_AGGR_P (value) = 1;
+
+ if (attrlist)
+ cplus_decl_attributes (&value, attrlist, /*flags=*/0);
+
+ return value;
+}
+
+
+/* Returns true iff ATTR is an attribute which needs to be applied at
+ instantiation time rather than template definition time. */
+
+static bool
+is_late_template_attribute (tree attr, tree decl)
+{
+ tree name = get_attribute_name (attr);
+ tree args = TREE_VALUE (attr);
+ const struct attribute_spec *spec = lookup_attribute_spec (name);
+ tree arg;
+
+ if (!spec)
+ /* Unknown attribute. */
+ return false;
+
+ /* Attribute weak handling wants to write out assembly right away. */
+ if (is_attribute_p ("weak", name))
+ return true;
+
+ /* Attribute unused is applied directly, as it appertains to
+ decls. */
+ if (is_attribute_p ("unused", name))
+ return false;
+
+ /* #pragma omp declare simd attribute needs to be always deferred. */
+ if (flag_openmp
+ && is_attribute_p ("omp declare simd", name))
+ return true;
+
+ /* If any of the arguments are dependent expressions, we can't evaluate
+ the attribute until instantiation time. */
+ for (arg = args; arg; arg = TREE_CHAIN (arg))
+ {
+ tree t = TREE_VALUE (arg);
+
+ /* If the first attribute argument is an identifier, only consider
+ second and following arguments. Attributes like mode, format,
+ cleanup and several target specific attributes aren't late
+ just because they have an IDENTIFIER_NODE as first argument. */
+ if (arg == args && identifier_p (t))
+ continue;
+
+ if (value_dependent_expression_p (t)
+ || type_dependent_expression_p (t))
+ return true;
+ }
+
+ if (TREE_CODE (decl) == TYPE_DECL
+ || TYPE_P (decl)
+ || spec->type_required)
+ {
+ tree type = TYPE_P (decl) ? decl : TREE_TYPE (decl);
+
+ /* We can't apply any attributes to a completely unknown type until
+ instantiation time. */
+ enum tree_code code = TREE_CODE (type);
+ if (code == TEMPLATE_TYPE_PARM
+ || code == BOUND_TEMPLATE_TEMPLATE_PARM
+ || code == TYPENAME_TYPE)
+ return true;
+ /* Also defer most attributes on dependent types. This is not
+ necessary in all cases, but is the better default. */
+ else if (dependent_type_p (type)
+ /* But attribute visibility specifically works on
+ templates. */
+ && !is_attribute_p ("visibility", name))
+ return true;
+ else
+ return false;
+ }
+ else
+ return false;
+}
+
+/* ATTR_P is a list of attributes. Remove any attributes which need to be
+ applied at instantiation time and return them. If IS_DEPENDENT is true,
+ the declaration itself is dependent, so all attributes should be applied
+ at instantiation time. */
+
+static tree
+splice_template_attributes (tree *attr_p, tree decl)
+{
+ tree *p = attr_p;
+ tree late_attrs = NULL_TREE;
+ tree *q = &late_attrs;
+
+ if (!p)
+ return NULL_TREE;
+
+ for (; *p; )
+ {
+ if (is_late_template_attribute (*p, decl))
+ {
+ ATTR_IS_DEPENDENT (*p) = 1;
+ *q = *p;
+ *p = TREE_CHAIN (*p);
+ q = &TREE_CHAIN (*q);
+ *q = NULL_TREE;
+ }
+ else
+ p = &TREE_CHAIN (*p);
+ }
+
+ return late_attrs;
+}
+
+/* Remove any late attributes from the list in ATTR_P and attach them to
+ DECL_P. */
+
+static void
+save_template_attributes (tree *attr_p, tree *decl_p)
+{
+ tree *q;
+
+ if (attr_p && *attr_p == error_mark_node)
+ return;
+
+ tree late_attrs = splice_template_attributes (attr_p, *decl_p);
+ if (!late_attrs)
+ return;
+
+ if (DECL_P (*decl_p))
+ q = &DECL_ATTRIBUTES (*decl_p);
+ else
+ q = &TYPE_ATTRIBUTES (*decl_p);
+
+ tree old_attrs = *q;
+
+ /* Merge the late attributes at the beginning with the attribute
+ list. */
+ late_attrs = merge_attributes (late_attrs, *q);
+ *q = late_attrs;
+
+ if (!DECL_P (*decl_p) && *decl_p == TYPE_MAIN_VARIANT (*decl_p))
+ {
+ /* We've added new attributes directly to the main variant, so
+ now we need to update all of the other variants to include
+ these new attributes. */
+ tree variant;
+ for (variant = TYPE_NEXT_VARIANT (*decl_p); variant;
+ variant = TYPE_NEXT_VARIANT (variant))
+ {
+ gcc_assert (TYPE_ATTRIBUTES (variant) == old_attrs);
+ TYPE_ATTRIBUTES (variant) = TYPE_ATTRIBUTES (*decl_p);
+ }
+ }
+}
+
+/* Return true iff ATTRS are acceptable attributes to be applied in-place
+ to a typedef which gives a previously anonymous class or enum a name for
+ linkage purposes. */
+
+bool
+attributes_naming_typedef_ok (tree attrs)
+{
+ for (; attrs; attrs = TREE_CHAIN (attrs))
+ {
+ tree name = get_attribute_name (attrs);
+ if (is_attribute_p ("vector_size", name))
+ return false;
+ }
+ return true;
+}
+
+/* Like reconstruct_complex_type, but handle also template trees. */
+
+tree
+cp_reconstruct_complex_type (tree type, tree bottom)
+{
+ tree inner, outer;
+
+ if (TYPE_PTR_P (type))
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ outer = build_pointer_type_for_mode (inner, TYPE_MODE (type),
+ TYPE_REF_CAN_ALIAS_ALL (type));
+ }
+ else if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ outer = build_reference_type_for_mode (inner, TYPE_MODE (type),
+ TYPE_REF_CAN_ALIAS_ALL (type));
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ outer = build_cplus_array_type (inner, TYPE_DOMAIN (type));
+ /* Don't call cp_build_qualified_type on ARRAY_TYPEs, the
+ element type qualification will be handled by the recursive
+ cp_reconstruct_complex_type call and cp_build_qualified_type
+ for ARRAY_TYPEs changes the element type. */
+ return outer;
+ }
+ else if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ outer = build_function_type (inner, TYPE_ARG_TYPES (type));
+ outer = apply_memfn_quals (outer,
+ type_memfn_quals (type),
+ type_memfn_rqual (type));
+ }
+ else if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ /* The build_method_type_directly() routine prepends 'this' to argument list,
+ so we must compensate by getting rid of it. */
+ outer
+ = build_method_type_directly
+ (class_of_this_parm (type), inner,
+ TREE_CHAIN (TYPE_ARG_TYPES (type)));
+ }
+ else if (TREE_CODE (type) == OFFSET_TYPE)
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ outer = build_offset_type (TYPE_OFFSET_BASETYPE (type), inner);
+ }
+ else
+ return bottom;
+
+ if (TYPE_ATTRIBUTES (type))
+ outer = cp_build_type_attribute_variant (outer, TYPE_ATTRIBUTES (type));
+ return cp_build_qualified_type (outer, cp_type_quals (type));
+}
+
+/* Replaces any constexpr expression that may be into the attributes
+ arguments with their reduced value. */
+
+static void
+cp_check_const_attributes (tree attributes)
+{
+ if (attributes == error_mark_node)
+ return;
+
+ tree attr;
+ for (attr = attributes; attr; attr = TREE_CHAIN (attr))
+ {
+ tree arg;
+ for (arg = TREE_VALUE (attr); arg; arg = TREE_CHAIN (arg))
+ {
+ tree expr = TREE_VALUE (arg);
+ if (EXPR_P (expr))
+ TREE_VALUE (arg) = maybe_constant_value (expr);
+ }
+ }
+}
+
+/* Return true if TYPE is an OpenMP mappable type. */
+bool
+cp_omp_mappable_type (tree type)
+{
+ /* Mappable type has to be complete. */
+ if (type == error_mark_node || !COMPLETE_TYPE_P (type))
+ return false;
+ /* Arrays have mappable type if the elements have mappable type. */
+ while (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+ /* A mappable type cannot contain virtual members. */
+ if (CLASS_TYPE_P (type) && CLASSTYPE_VTABLES (type))
+ return false;
+ /* All data members must be non-static. */
+ if (CLASS_TYPE_P (type))
+ {
+ tree field;
+ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == VAR_DECL)
+ return false;
+ /* All fields must have mappable types. */
+ else if (TREE_CODE (field) == FIELD_DECL
+ && !cp_omp_mappable_type (TREE_TYPE (field)))
+ return false;
+ }
+ return true;
+}
+
+/* Like decl_attributes, but handle C++ complexity. */
+
+void
+cplus_decl_attributes (tree *decl, tree attributes, int flags)
+{
+ if (*decl == NULL_TREE || *decl == void_type_node
+ || *decl == error_mark_node)
+ return;
+
+ /* Add implicit "omp declare target" attribute if requested. */
+ if (scope_chain->omp_declare_target_attribute
+ && ((TREE_CODE (*decl) == VAR_DECL && TREE_STATIC (*decl))
+ || TREE_CODE (*decl) == FUNCTION_DECL))
+ {
+ if (TREE_CODE (*decl) == VAR_DECL
+ && DECL_CLASS_SCOPE_P (*decl))
+ error ("%q+D static data member inside of declare target directive",
+ *decl);
+ else if (TREE_CODE (*decl) == VAR_DECL
+ && (DECL_FUNCTION_SCOPE_P (*decl)
+ || (current_function_decl && !DECL_EXTERNAL (*decl))))
+ error ("%q+D in block scope inside of declare target directive",
+ *decl);
+ else if (!processing_template_decl
+ && TREE_CODE (*decl) == VAR_DECL
+ && !cp_omp_mappable_type (TREE_TYPE (*decl)))
+ error ("%q+D in declare target directive does not have mappable type",
+ *decl);
+ else
+ attributes = tree_cons (get_identifier ("omp declare target"),
+ NULL_TREE, attributes);
+ }
+
+ if (processing_template_decl)
+ {
+ if (check_for_bare_parameter_packs (attributes))
+ return;
+
+ save_template_attributes (&attributes, decl);
+ }
+
+ cp_check_const_attributes (attributes);
+
+ if (TREE_CODE (*decl) == TEMPLATE_DECL)
+ decl = &DECL_TEMPLATE_RESULT (*decl);
+
+ decl_attributes (decl, attributes, flags);
+
+ if (TREE_CODE (*decl) == TYPE_DECL)
+ SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
+}
+
+/* Walks through the namespace- or function-scope anonymous union
+ OBJECT, with the indicated TYPE, building appropriate VAR_DECLs.
+ Returns one of the fields for use in the mangled name. */
+
+static tree
+build_anon_union_vars (tree type, tree object)
+{
+ tree main_decl = NULL_TREE;
+ tree field;
+
+ /* Rather than write the code to handle the non-union case,
+ just give an error. */
+ if (TREE_CODE (type) != UNION_TYPE)
+ {
+ error ("anonymous struct not inside named type");
+ return error_mark_node;
+ }
+
+ for (field = TYPE_FIELDS (type);
+ field != NULL_TREE;
+ field = DECL_CHAIN (field))
+ {
+ tree decl;
+ tree ref;
+
+ if (DECL_ARTIFICIAL (field))
+ continue;
+ if (TREE_CODE (field) != FIELD_DECL)
+ {
+ permerror (input_location, "%q+#D invalid; an anonymous union can only "
+ "have non-static data members", field);
+ continue;
+ }
+
+ if (TREE_PRIVATE (field))
+ permerror (input_location, "private member %q+#D in anonymous union", field);
+ else if (TREE_PROTECTED (field))
+ permerror (input_location, "protected member %q+#D in anonymous union", field);
+
+ if (processing_template_decl)
+ ref = build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF, object,
+ DECL_NAME (field), NULL_TREE);
+ else
+ ref = build_class_member_access_expr (object, field, NULL_TREE,
+ false, tf_warning_or_error);
+
+ if (DECL_NAME (field))
+ {
+ tree base;
+
+ decl = build_decl (input_location,
+ VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
+ DECL_ANON_UNION_VAR_P (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+
+ base = get_base_address (object);
+ TREE_PUBLIC (decl) = TREE_PUBLIC (base);
+ TREE_STATIC (decl) = TREE_STATIC (base);
+ DECL_EXTERNAL (decl) = DECL_EXTERNAL (base);
+
+ SET_DECL_VALUE_EXPR (decl, ref);
+ DECL_HAS_VALUE_EXPR_P (decl) = 1;
+
+ decl = pushdecl (decl);
+ }
+ else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
+ decl = build_anon_union_vars (TREE_TYPE (field), ref);
+ else
+ decl = 0;
+
+ if (main_decl == NULL_TREE)
+ main_decl = decl;
+ }
+
+ return main_decl;
+}
+
+/* Finish off the processing of a UNION_TYPE structure. If the union is an
+ anonymous union, then all members must be laid out together. PUBLIC_P
+ is nonzero if this union is not declared static. */
+
+void
+finish_anon_union (tree anon_union_decl)
+{
+ tree type;
+ tree main_decl;
+ bool public_p;
+
+ if (anon_union_decl == error_mark_node)
+ return;
+
+ type = TREE_TYPE (anon_union_decl);
+ public_p = TREE_PUBLIC (anon_union_decl);
+
+ /* The VAR_DECL's context is the same as the TYPE's context. */
+ DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type));
+
+ if (TYPE_FIELDS (type) == NULL_TREE)
+ return;
+
+ if (public_p)
+ {
+ error ("namespace-scope anonymous aggregates must be static");
+ return;
+ }
+
+ main_decl = build_anon_union_vars (type, anon_union_decl);
+ if (main_decl == error_mark_node)
+ return;
+ if (main_decl == NULL_TREE)
+ {
+ warning (0, "anonymous union with no members");
+ return;
+ }
+
+ if (!processing_template_decl)
+ {
+ /* Use main_decl to set the mangled name. */
+ DECL_NAME (anon_union_decl) = DECL_NAME (main_decl);
+ maybe_commonize_var (anon_union_decl);
+ if (TREE_STATIC (anon_union_decl) || DECL_EXTERNAL (anon_union_decl))
+ mangle_decl (anon_union_decl);
+ DECL_NAME (anon_union_decl) = NULL_TREE;
+ }
+
+ pushdecl (anon_union_decl);
+ cp_finish_decl (anon_union_decl, NULL_TREE, false, NULL_TREE, 0);
+}
+
+/* Auxiliary functions to make type signatures for
+ `operator new' and `operator delete' correspond to
+ what compiler will be expecting. */
+
+tree
+coerce_new_type (tree type)
+{
+ int e = 0;
+ tree args = TYPE_ARG_TYPES (type);
+
+ gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
+
+ if (!same_type_p (TREE_TYPE (type), ptr_type_node))
+ {
+ e = 1;
+ error ("%<operator new%> must return type %qT", ptr_type_node);
+ }
+
+ if (args && args != void_list_node)
+ {
+ if (TREE_PURPOSE (args))
+ {
+ /* [basic.stc.dynamic.allocation]
+
+ The first parameter shall not have an associated default
+ argument. */
+ error ("the first parameter of %<operator new%> cannot "
+ "have a default argument");
+ /* Throw away the default argument. */
+ TREE_PURPOSE (args) = NULL_TREE;
+ }
+
+ if (!same_type_p (TREE_VALUE (args), size_type_node))
+ {
+ e = 2;
+ args = TREE_CHAIN (args);
+ }
+ }
+ else
+ e = 2;
+
+ if (e == 2)
+ permerror (input_location, "%<operator new%> takes type %<size_t%> (%qT) "
+ "as first parameter", size_type_node);
+
+ switch (e)
+ {
+ case 2:
+ args = tree_cons (NULL_TREE, size_type_node, args);
+ /* Fall through. */
+ case 1:
+ type = build_exception_variant
+ (build_function_type (ptr_type_node, args),
+ TYPE_RAISES_EXCEPTIONS (type));
+ /* Fall through. */
+ default:;
+ }
+ return type;
+}
+
+tree
+coerce_delete_type (tree type)
+{
+ int e = 0;
+ tree args = TYPE_ARG_TYPES (type);
+
+ gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
+
+ if (!same_type_p (TREE_TYPE (type), void_type_node))
+ {
+ e = 1;
+ error ("%<operator delete%> must return type %qT", void_type_node);
+ }
+
+ if (!args || args == void_list_node
+ || !same_type_p (TREE_VALUE (args), ptr_type_node))
+ {
+ e = 2;
+ if (args && args != void_list_node)
+ args = TREE_CHAIN (args);
+ error ("%<operator delete%> takes type %qT as first parameter",
+ ptr_type_node);
+ }
+ switch (e)
+ {
+ case 2:
+ args = tree_cons (NULL_TREE, ptr_type_node, args);
+ /* Fall through. */
+ case 1:
+ type = build_exception_variant
+ (build_function_type (void_type_node, args),
+ TYPE_RAISES_EXCEPTIONS (type));
+ /* Fall through. */
+ default:;
+ }
+
+ return type;
+}
+
+/* DECL is a VAR_DECL for a vtable: walk through the entries in the vtable
+ and mark them as needed. */
+
+static void
+mark_vtable_entries (tree decl)
+{
+ tree fnaddr;
+ unsigned HOST_WIDE_INT idx;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)),
+ idx, fnaddr)
+ {
+ tree fn;
+
+ STRIP_NOPS (fnaddr);
+
+ if (TREE_CODE (fnaddr) != ADDR_EXPR
+ && TREE_CODE (fnaddr) != FDESC_EXPR)
+ /* This entry is an offset: a virtual base class offset, a
+ virtual call offset, an RTTI offset, etc. */
+ continue;
+
+ fn = TREE_OPERAND (fnaddr, 0);
+ TREE_ADDRESSABLE (fn) = 1;
+ /* When we don't have vcall offsets, we output thunks whenever
+ we output the vtables that contain them. With vcall offsets,
+ we know all the thunks we'll need when we emit a virtual
+ function, so we emit the thunks there instead. */
+ if (DECL_THUNK_P (fn))
+ use_thunk (fn, /*emit_p=*/0);
+ mark_used (fn);
+ }
+}
+
+/* Set DECL up to have the closest approximation of "initialized common"
+ linkage available. */
+
+void
+comdat_linkage (tree decl)
+{
+ if (flag_weak)
+ make_decl_one_only (decl, cxx_comdat_group (decl));
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ || (VAR_P (decl) && DECL_ARTIFICIAL (decl)))
+ /* We can just emit function and compiler-generated variables
+ statically; having multiple copies is (for the most part) only
+ a waste of space.
+
+ There are two correctness issues, however: the address of a
+ template instantiation with external linkage should be the
+ same, independent of what translation unit asks for the
+ address, and this will not hold when we emit multiple copies of
+ the function. However, there's little else we can do.
+
+ Also, by default, the typeinfo implementation assumes that
+ there will be only one copy of the string used as the name for
+ each type. Therefore, if weak symbols are unavailable, the
+ run-time library should perform a more conservative check; it
+ should perform a string comparison, rather than an address
+ comparison. */
+ TREE_PUBLIC (decl) = 0;
+ else
+ {
+ /* Static data member template instantiations, however, cannot
+ have multiple copies. */
+ if (DECL_INITIAL (decl) == 0
+ || DECL_INITIAL (decl) == error_mark_node)
+ DECL_COMMON (decl) = 1;
+ else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
+ {
+ DECL_COMMON (decl) = 1;
+ DECL_INITIAL (decl) = error_mark_node;
+ }
+ else if (!DECL_EXPLICIT_INSTANTIATION (decl))
+ {
+ /* We can't do anything useful; leave vars for explicit
+ instantiation. */
+ DECL_EXTERNAL (decl) = 1;
+ DECL_NOT_REALLY_EXTERN (decl) = 0;
+ }
+ }
+
+ DECL_COMDAT (decl) = 1;
+}
+
+/* For win32 we also want to put explicit instantiations in
+ linkonce sections, so that they will be merged with implicit
+ instantiations; otherwise we get duplicate symbol errors.
+ For Darwin we do not want explicit instantiations to be
+ linkonce. */
+
+void
+maybe_make_one_only (tree decl)
+{
+ /* We used to say that this was not necessary on targets that support weak
+ symbols, because the implicit instantiations will defer to the explicit
+ one. However, that's not actually the case in SVR4; a strong definition
+ after a weak one is an error. Also, not making explicit
+ instantiations one_only means that we can end up with two copies of
+ some template instantiations. */
+ if (! flag_weak)
+ return;
+
+ /* We can't set DECL_COMDAT on functions, or cp_finish_file will think
+ we can get away with not emitting them if they aren't used. We need
+ to for variables so that cp_finish_decl will update their linkage,
+ because their DECL_INITIAL may not have been set properly yet. */
+
+ if (!TARGET_WEAK_NOT_IN_ARCHIVE_TOC
+ || (! DECL_EXPLICIT_INSTANTIATION (decl)
+ && ! DECL_TEMPLATE_SPECIALIZATION (decl)))
+ {
+ make_decl_one_only (decl, cxx_comdat_group (decl));
+
+ if (VAR_P (decl))
+ {
+ varpool_node *node = varpool_node_for_decl (decl);
+ DECL_COMDAT (decl) = 1;
+ /* Mark it needed so we don't forget to emit it. */
+ node->forced_by_abi = true;
+ TREE_USED (decl) = 1;
+ }
+ }
+}
+
+/* Returns true iff DECL, a FUNCTION_DECL or VAR_DECL, has vague linkage.
+ This predicate will give the right answer during parsing of the
+ function, which other tests may not. */
+
+bool
+vague_linkage_p (tree decl)
+{
+ /* Unfortunately, import_export_decl has not always been called
+ before the function is processed, so we cannot simply check
+ DECL_COMDAT. */
+ return (DECL_COMDAT (decl)
+ || (((TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (decl))
+ || (DECL_LANG_SPECIFIC (decl)
+ && DECL_TEMPLATE_INSTANTIATION (decl)))
+ && TREE_PUBLIC (decl)));
+}
+
+/* Determine whether or not we want to specifically import or export CTYPE,
+ using various heuristics. */
+
+static void
+import_export_class (tree ctype)
+{
+ /* -1 for imported, 1 for exported. */
+ int import_export = 0;
+
+ /* It only makes sense to call this function at EOF. The reason is
+ that this function looks at whether or not the first non-inline
+ non-abstract virtual member function has been defined in this
+ translation unit. But, we can't possibly know that until we've
+ seen the entire translation unit. */
+ gcc_assert (at_eof);
+
+ if (CLASSTYPE_INTERFACE_KNOWN (ctype))
+ return;
+
+ /* If MULTIPLE_SYMBOL_SPACES is set and we saw a #pragma interface,
+ we will have CLASSTYPE_INTERFACE_ONLY set but not
+ CLASSTYPE_INTERFACE_KNOWN. In that case, we don't want to use this
+ heuristic because someone will supply a #pragma implementation
+ elsewhere, and deducing it here would produce a conflict. */
+ if (CLASSTYPE_INTERFACE_ONLY (ctype))
+ return;
+
+ if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype)))
+ import_export = -1;
+ else if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype)))
+ import_export = 1;
+ else if (CLASSTYPE_IMPLICIT_INSTANTIATION (ctype)
+ && !flag_implicit_templates)
+ /* For a template class, without -fimplicit-templates, check the
+ repository. If the virtual table is assigned to this
+ translation unit, then export the class; otherwise, import
+ it. */
+ import_export = repo_export_class_p (ctype) ? 1 : -1;
+ else if (TYPE_POLYMORPHIC_P (ctype))
+ {
+ /* The ABI specifies that the virtual table and associated
+ information are emitted with the key method, if any. */
+ tree method = CLASSTYPE_KEY_METHOD (ctype);
+ /* If weak symbol support is not available, then we must be
+ careful not to emit the vtable when the key function is
+ inline. An inline function can be defined in multiple
+ translation units. If we were to emit the vtable in each
+ translation unit containing a definition, we would get
+ multiple definition errors at link-time. */
+ if (method && (flag_weak || ! DECL_DECLARED_INLINE_P (method)))
+ import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1);
+ }
+
+ /* When MULTIPLE_SYMBOL_SPACES is set, we cannot count on seeing
+ a definition anywhere else. */
+ if (MULTIPLE_SYMBOL_SPACES && import_export == -1)
+ import_export = 0;
+
+ /* Allow back ends the chance to overrule the decision. */
+ if (targetm.cxx.import_export_class)
+ import_export = targetm.cxx.import_export_class (ctype, import_export);
+
+ if (import_export)
+ {
+ SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
+ CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0);
+ }
+}
+
+/* Return true if VAR has already been provided to the back end; in that
+ case VAR should not be modified further by the front end. */
+static bool
+var_finalized_p (tree var)
+{
+ return varpool_node_for_decl (var)->definition;
+}
+
+/* DECL is a VAR_DECL or FUNCTION_DECL which, for whatever reason,
+ must be emitted in this translation unit. Mark it as such. */
+
+void
+mark_needed (tree decl)
+{
+ TREE_USED (decl) = 1;
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ /* Extern inline functions don't become needed when referenced.
+ If we know a method will be emitted in other TU and no new
+ functions can be marked reachable, just use the external
+ definition. */
+ struct cgraph_node *node = cgraph_get_create_node (decl);
+ node->forced_by_abi = true;
+ }
+ else if (TREE_CODE (decl) == VAR_DECL)
+ {
+ varpool_node *node = varpool_node_for_decl (decl);
+ /* C++ frontend use mark_decl_references to force COMDAT variables
+ to be output that might appear dead otherwise. */
+ node->forced_by_abi = true;
+ }
+}
+
+/* DECL is either a FUNCTION_DECL or a VAR_DECL. This function
+ returns true if a definition of this entity should be provided in
+ this object file. Callers use this function to determine whether
+ or not to let the back end know that a definition of DECL is
+ available in this translation unit. */
+
+bool
+decl_needed_p (tree decl)
+{
+ gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
+ /* This function should only be called at the end of the translation
+ unit. We cannot be sure of whether or not something will be
+ COMDAT until that point. */
+ gcc_assert (at_eof);
+
+ /* All entities with external linkage that are not COMDAT should be
+ emitted; they may be referred to from other object files. */
+ if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
+ return true;
+ /* If this entity was used, let the back end see it; it will decide
+ whether or not to emit it into the object file. */
+ if (TREE_USED (decl))
+ return true;
+ /* Functions marked "dllexport" must be emitted so that they are
+ visible to other DLLs. */
+ if (flag_keep_inline_dllexport
+ && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
+ return true;
+ /* Otherwise, DECL does not need to be emitted -- yet. A subsequent
+ reference to DECL might cause it to be emitted later. */
+ return false;
+}
+
+/* If necessary, write out the vtables for the dynamic class CTYPE.
+ Returns true if any vtables were emitted. */
+
+static bool
+maybe_emit_vtables (tree ctype)
+{
+ tree vtbl;
+ tree primary_vtbl;
+ int needed = 0;
+ varpool_node *current = NULL, *last = NULL;
+
+ /* If the vtables for this class have already been emitted there is
+ nothing more to do. */
+ primary_vtbl = CLASSTYPE_VTABLES (ctype);
+ if (var_finalized_p (primary_vtbl))
+ return false;
+ /* Ignore dummy vtables made by get_vtable_decl. */
+ if (TREE_TYPE (primary_vtbl) == void_type_node)
+ return false;
+
+ /* On some targets, we cannot determine the key method until the end
+ of the translation unit -- which is when this function is
+ called. */
+ if (!targetm.cxx.key_method_may_be_inline ())
+ determine_key_method (ctype);
+
+ /* See if any of the vtables are needed. */
+ for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl))
+ {
+ import_export_decl (vtbl);
+ if (DECL_NOT_REALLY_EXTERN (vtbl) && decl_needed_p (vtbl))
+ needed = 1;
+ }
+ if (!needed)
+ {
+ /* If the references to this class' vtables are optimized away,
+ still emit the appropriate debugging information. See
+ dfs_debug_mark. */
+ if (DECL_COMDAT (primary_vtbl)
+ && CLASSTYPE_DEBUG_REQUESTED (ctype))
+ note_debug_info_needed (ctype);
+ return false;
+ }
+
+ /* The ABI requires that we emit all of the vtables if we emit any
+ of them. */
+ for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl))
+ {
+ /* Mark entities references from the virtual table as used. */
+ mark_vtable_entries (vtbl);
+
+ if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
+ {
+ vec<tree, va_gc> *cleanups = NULL;
+ tree expr = store_init_value (vtbl, DECL_INITIAL (vtbl), &cleanups,
+ LOOKUP_NORMAL);
+
+ /* It had better be all done at compile-time. */
+ gcc_assert (!expr && !cleanups);
+ }
+
+ /* Write it out. */
+ DECL_EXTERNAL (vtbl) = 0;
+ rest_of_decl_compilation (vtbl, 1, 1);
+
+ /* Because we're only doing syntax-checking, we'll never end up
+ actually marking the variable as written. */
+ if (flag_syntax_only)
+ TREE_ASM_WRITTEN (vtbl) = 1;
+ else if (DECL_ONE_ONLY (vtbl))
+ {
+ current = varpool_node_for_decl (vtbl);
+ if (last)
+ symtab_add_to_same_comdat_group (current, last);
+ last = current;
+ }
+ }
+
+ /* Since we're writing out the vtable here, also write the debug
+ info. */
+ note_debug_info_needed (ctype);
+
+ return true;
+}
+
+/* A special return value from type_visibility meaning internal
+ linkage. */
+
+enum { VISIBILITY_ANON = VISIBILITY_INTERNAL+1 };
+
+/* walk_tree helper function for type_visibility. */
+
+static tree
+min_vis_r (tree *tp, int *walk_subtrees, void *data)
+{
+ int *vis_p = (int *)data;
+ if (! TYPE_P (*tp))
+ {
+ *walk_subtrees = 0;
+ }
+ else if (OVERLOAD_TYPE_P (*tp)
+ && !TREE_PUBLIC (TYPE_MAIN_DECL (*tp)))
+ {
+ *vis_p = VISIBILITY_ANON;
+ return *tp;
+ }
+ else if (CLASS_TYPE_P (*tp)
+ && CLASSTYPE_VISIBILITY (*tp) > *vis_p)
+ *vis_p = CLASSTYPE_VISIBILITY (*tp);
+ return NULL;
+}
+
+/* Returns the visibility of TYPE, which is the minimum visibility of its
+ component types. */
+
+static int
+type_visibility (tree type)
+{
+ int vis = VISIBILITY_DEFAULT;
+ cp_walk_tree_without_duplicates (&type, min_vis_r, &vis);
+ return vis;
+}
+
+/* Limit the visibility of DECL to VISIBILITY, if not explicitly
+ specified (or if VISIBILITY is static). If TMPL is true, this
+ constraint is for a template argument, and takes precedence
+ over explicitly-specified visibility on the template. */
+
+static void
+constrain_visibility (tree decl, int visibility, bool tmpl)
+{
+ if (visibility == VISIBILITY_ANON)
+ {
+ /* extern "C" declarations aren't affected by the anonymous
+ namespace. */
+ if (!DECL_EXTERN_C_P (decl))
+ {
+ TREE_PUBLIC (decl) = 0;
+ DECL_WEAK (decl) = 0;
+ DECL_COMMON (decl) = 0;
+ DECL_COMDAT_GROUP (decl) = NULL_TREE;
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ if (DECL_LANG_SPECIFIC (decl))
+ DECL_NOT_REALLY_EXTERN (decl) = 1;
+ }
+ }
+ else if (visibility > DECL_VISIBILITY (decl)
+ && (tmpl || !DECL_VISIBILITY_SPECIFIED (decl)))
+ {
+ DECL_VISIBILITY (decl) = (enum symbol_visibility) visibility;
+ /* This visibility was not specified. */
+ DECL_VISIBILITY_SPECIFIED (decl) = false;
+ }
+}
+
+/* Constrain the visibility of DECL based on the visibility of its template
+ arguments. */
+
+static void
+constrain_visibility_for_template (tree decl, tree targs)
+{
+ /* If this is a template instantiation, check the innermost
+ template args for visibility constraints. The outer template
+ args are covered by the class check. */
+ tree args = INNERMOST_TEMPLATE_ARGS (targs);
+ int i;
+ for (i = TREE_VEC_LENGTH (args); i > 0; --i)
+ {
+ int vis = 0;
+
+ tree arg = TREE_VEC_ELT (args, i-1);
+ if (TYPE_P (arg))
+ vis = type_visibility (arg);
+ else if (TREE_TYPE (arg) && POINTER_TYPE_P (TREE_TYPE (arg)))
+ {
+ STRIP_NOPS (arg);
+ if (TREE_CODE (arg) == ADDR_EXPR)
+ arg = TREE_OPERAND (arg, 0);
+ if (VAR_OR_FUNCTION_DECL_P (arg))
+ {
+ if (! TREE_PUBLIC (arg))
+ vis = VISIBILITY_ANON;
+ else
+ vis = DECL_VISIBILITY (arg);
+ }
+ }
+ if (vis)
+ constrain_visibility (decl, vis, true);
+ }
+}
+
+/* Like c_determine_visibility, but with additional C++-specific
+ behavior.
+
+ Function-scope entities can rely on the function's visibility because
+ it is set in start_preparsed_function.
+
+ Class-scope entities cannot rely on the class's visibility until the end
+ of the enclosing class definition.
+
+ Note that because namespaces have multiple independent definitions,
+ namespace visibility is handled elsewhere using the #pragma visibility
+ machinery rather than by decorating the namespace declaration.
+
+ The goal is for constraints from the type to give a diagnostic, and
+ other constraints to be applied silently. */
+
+void
+determine_visibility (tree decl)
+{
+ tree class_type = NULL_TREE;
+ bool use_template;
+ bool orig_visibility_specified;
+ enum symbol_visibility orig_visibility;
+
+ /* Remember that all decls get VISIBILITY_DEFAULT when built. */
+
+ /* Only relevant for names with external linkage. */
+ if (!TREE_PUBLIC (decl))
+ return;
+
+ /* Cloned constructors and destructors get the same visibility as
+ the underlying function. That should be set up in
+ maybe_clone_body. */
+ gcc_assert (!DECL_CLONED_FUNCTION_P (decl));
+
+ orig_visibility_specified = DECL_VISIBILITY_SPECIFIED (decl);
+ orig_visibility = DECL_VISIBILITY (decl);
+
+ if (TREE_CODE (decl) == TYPE_DECL)
+ {
+ if (CLASS_TYPE_P (TREE_TYPE (decl)))
+ use_template = CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl));
+ else if (TYPE_TEMPLATE_INFO (TREE_TYPE (decl)))
+ use_template = 1;
+ else
+ use_template = 0;
+ }
+ else if (DECL_LANG_SPECIFIC (decl))
+ use_template = DECL_USE_TEMPLATE (decl);
+ else
+ use_template = 0;
+
+ /* If DECL is a member of a class, visibility specifiers on the
+ class can influence the visibility of the DECL. */
+ if (DECL_CLASS_SCOPE_P (decl))
+ class_type = DECL_CONTEXT (decl);
+ else
+ {
+ /* Not a class member. */
+
+ /* Virtual tables have DECL_CONTEXT set to their associated class,
+ so they are automatically handled above. */
+ gcc_assert (!VAR_P (decl)
+ || !DECL_VTABLE_OR_VTT_P (decl));
+
+ if (DECL_FUNCTION_SCOPE_P (decl) && ! DECL_VISIBILITY_SPECIFIED (decl))
+ {
+ /* Local statics and classes get the visibility of their
+ containing function by default, except that
+ -fvisibility-inlines-hidden doesn't affect them. */
+ tree fn = DECL_CONTEXT (decl);
+ if (DECL_VISIBILITY_SPECIFIED (fn))
+ {
+ DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
+ DECL_VISIBILITY_SPECIFIED (decl) =
+ DECL_VISIBILITY_SPECIFIED (fn);
+ }
+ else
+ {
+ if (DECL_CLASS_SCOPE_P (fn))
+ determine_visibility_from_class (decl, DECL_CONTEXT (fn));
+ else if (determine_hidden_inline (fn))
+ {
+ DECL_VISIBILITY (decl) = default_visibility;
+ DECL_VISIBILITY_SPECIFIED (decl) =
+ visibility_options.inpragma;
+ }
+ else
+ {
+ DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
+ DECL_VISIBILITY_SPECIFIED (decl) =
+ DECL_VISIBILITY_SPECIFIED (fn);
+ }
+ }
+
+ /* Local classes in templates have CLASSTYPE_USE_TEMPLATE set,
+ but have no TEMPLATE_INFO, so don't try to check it. */
+ use_template = 0;
+ }
+ else if (VAR_P (decl) && DECL_TINFO_P (decl)
+ && flag_visibility_ms_compat)
+ {
+ /* Under -fvisibility-ms-compat, types are visible by default,
+ even though their contents aren't. */
+ tree underlying_type = TREE_TYPE (DECL_NAME (decl));
+ int underlying_vis = type_visibility (underlying_type);
+ if (underlying_vis == VISIBILITY_ANON
+ || (CLASS_TYPE_P (underlying_type)
+ && CLASSTYPE_VISIBILITY_SPECIFIED (underlying_type)))
+ constrain_visibility (decl, underlying_vis, false);
+ else
+ DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+ }
+ else if (VAR_P (decl) && DECL_TINFO_P (decl))
+ {
+ /* tinfo visibility is based on the type it's for. */
+ constrain_visibility
+ (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))), false);
+
+ /* Give the target a chance to override the visibility associated
+ with DECL. */
+ if (TREE_PUBLIC (decl)
+ && !DECL_REALLY_EXTERN (decl)
+ && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl)))
+ && !CLASSTYPE_VISIBILITY_SPECIFIED (TREE_TYPE (DECL_NAME (decl))))
+ targetm.cxx.determine_class_data_visibility (decl);
+ }
+ else if (use_template)
+ /* Template instantiations and specializations get visibility based
+ on their template unless they override it with an attribute. */;
+ else if (! DECL_VISIBILITY_SPECIFIED (decl))
+ {
+ if (determine_hidden_inline (decl))
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ else
+ {
+ /* Set default visibility to whatever the user supplied with
+ #pragma GCC visibility or a namespace visibility attribute. */
+ DECL_VISIBILITY (decl) = default_visibility;
+ DECL_VISIBILITY_SPECIFIED (decl) = visibility_options.inpragma;
+ }
+ }
+ }
+
+ if (use_template)
+ {
+ /* If the specialization doesn't specify visibility, use the
+ visibility from the template. */
+ tree tinfo = (TREE_CODE (decl) == TYPE_DECL
+ ? TYPE_TEMPLATE_INFO (TREE_TYPE (decl))
+ : DECL_TEMPLATE_INFO (decl));
+ tree args = TI_ARGS (tinfo);
+ tree attribs = (TREE_CODE (decl) == TYPE_DECL
+ ? TYPE_ATTRIBUTES (TREE_TYPE (decl))
+ : DECL_ATTRIBUTES (decl));
+
+ if (args != error_mark_node)
+ {
+ tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo));
+
+ if (!DECL_VISIBILITY_SPECIFIED (decl))
+ {
+ if (!DECL_VISIBILITY_SPECIFIED (pattern)
+ && determine_hidden_inline (decl))
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ else
+ {
+ DECL_VISIBILITY (decl) = DECL_VISIBILITY (pattern);
+ DECL_VISIBILITY_SPECIFIED (decl)
+ = DECL_VISIBILITY_SPECIFIED (pattern);
+ }
+ }
+
+ if (args
+ /* Template argument visibility outweighs #pragma or namespace
+ visibility, but not an explicit attribute. */
+ && !lookup_attribute ("visibility", attribs))
+ {
+ int depth = TMPL_ARGS_DEPTH (args);
+ if (DECL_VISIBILITY_SPECIFIED (decl))
+ {
+ /* A class template member with explicit visibility
+ overrides the class visibility, so we need to apply
+ all the levels of template args directly. */
+ int i;
+ for (i = 1; i <= depth; ++i)
+ {
+ tree lev = TMPL_ARGS_LEVEL (args, i);
+ constrain_visibility_for_template (decl, lev);
+ }
+ }
+ else if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)))
+ /* Limit visibility based on its template arguments. */
+ constrain_visibility_for_template (decl, args);
+ }
+ }
+ }
+
+ if (class_type)
+ determine_visibility_from_class (decl, class_type);
+
+ if (decl_anon_ns_mem_p (decl))
+ /* Names in an anonymous namespace get internal linkage.
+ This might change once we implement export. */
+ constrain_visibility (decl, VISIBILITY_ANON, false);
+ else if (TREE_CODE (decl) != TYPE_DECL)
+ {
+ /* Propagate anonymity from type to decl. */
+ int tvis = type_visibility (TREE_TYPE (decl));
+ if (tvis == VISIBILITY_ANON
+ || ! DECL_VISIBILITY_SPECIFIED (decl))
+ constrain_visibility (decl, tvis, false);
+ }
+ else if (no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/true))
+ /* DR 757: A type without linkage shall not be used as the type of a
+ variable or function with linkage, unless
+ o the variable or function has extern "C" linkage (7.5 [dcl.link]), or
+ o the variable or function is not used (3.2 [basic.def.odr]) or is
+ defined in the same translation unit.
+
+ Since non-extern "C" decls need to be defined in the same
+ translation unit, we can make the type internal. */
+ constrain_visibility (decl, VISIBILITY_ANON, false);
+
+ /* If visibility changed and DECL already has DECL_RTL, ensure
+ symbol flags are updated. */
+ if ((DECL_VISIBILITY (decl) != orig_visibility
+ || DECL_VISIBILITY_SPECIFIED (decl) != orig_visibility_specified)
+ && ((VAR_P (decl) && TREE_STATIC (decl))
+ || TREE_CODE (decl) == FUNCTION_DECL)
+ && DECL_RTL_SET_P (decl))
+ make_decl_rtl (decl);
+}
+
+/* By default, static data members and function members receive
+ the visibility of their containing class. */
+
+static void
+determine_visibility_from_class (tree decl, tree class_type)
+{
+ if (DECL_VISIBILITY_SPECIFIED (decl))
+ return;
+
+ if (determine_hidden_inline (decl))
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ else
+ {
+ /* Default to the class visibility. */
+ DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
+ DECL_VISIBILITY_SPECIFIED (decl)
+ = CLASSTYPE_VISIBILITY_SPECIFIED (class_type);
+ }
+
+ /* Give the target a chance to override the visibility associated
+ with DECL. */
+ if (VAR_P (decl)
+ && (DECL_TINFO_P (decl)
+ || (DECL_VTABLE_OR_VTT_P (decl)
+ /* Construction virtual tables are not exported because
+ they cannot be referred to from other object files;
+ their name is not standardized by the ABI. */
+ && !DECL_CONSTRUCTION_VTABLE_P (decl)))
+ && TREE_PUBLIC (decl)
+ && !DECL_REALLY_EXTERN (decl)
+ && !CLASSTYPE_VISIBILITY_SPECIFIED (class_type))
+ targetm.cxx.determine_class_data_visibility (decl);
+}
+
+/* Returns true iff DECL is an inline that should get hidden visibility
+ because of -fvisibility-inlines-hidden. */
+
+static bool
+determine_hidden_inline (tree decl)
+{
+ return (visibility_options.inlines_hidden
+ /* Don't do this for inline templates; specializations might not be
+ inline, and we don't want them to inherit the hidden
+ visibility. We'll set it here for all inline instantiations. */
+ && !processing_template_decl
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (decl)
+ && (! DECL_LANG_SPECIFIC (decl)
+ || ! DECL_EXPLICIT_INSTANTIATION (decl)));
+}
+
+/* Constrain the visibility of a class TYPE based on the visibility of its
+ field types. Warn if any fields require lesser visibility. */
+
+void
+constrain_class_visibility (tree type)
+{
+ tree binfo;
+ tree t;
+ int i;
+
+ int vis = type_visibility (type);
+
+ if (vis == VISIBILITY_ANON
+ || DECL_IN_SYSTEM_HEADER (TYPE_MAIN_DECL (type)))
+ return;
+
+ /* Don't warn about visibility if the class has explicit visibility. */
+ if (CLASSTYPE_VISIBILITY_SPECIFIED (type))
+ vis = VISIBILITY_INTERNAL;
+
+ for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
+ if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node)
+ {
+ tree ftype = strip_pointer_or_array_types (TREE_TYPE (t));
+ int subvis = type_visibility (ftype);
+
+ if (subvis == VISIBILITY_ANON)
+ {
+ if (!in_main_input_context ())
+ warning (0, "\
+%qT has a field %qD whose type uses the anonymous namespace",
+ type, t);
+ }
+ else if (MAYBE_CLASS_TYPE_P (ftype)
+ && vis < VISIBILITY_HIDDEN
+ && subvis >= VISIBILITY_HIDDEN)
+ warning (OPT_Wattributes, "\
+%qT declared with greater visibility than the type of its field %qD",
+ type, t);
+ }
+
+ binfo = TYPE_BINFO (type);
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, t); ++i)
+ {
+ int subvis = type_visibility (TREE_TYPE (t));
+
+ if (subvis == VISIBILITY_ANON)
+ {
+ if (!in_main_input_context())
+ warning (0, "\
+%qT has a base %qT whose type uses the anonymous namespace",
+ type, TREE_TYPE (t));
+ }
+ else if (vis < VISIBILITY_HIDDEN
+ && subvis >= VISIBILITY_HIDDEN)
+ warning (OPT_Wattributes, "\
+%qT declared with greater visibility than its base %qT",
+ type, TREE_TYPE (t));
+ }
+}
+
+/* Functions for adjusting the visibility of a tagged type and its nested
+ types and declarations when it gets a name for linkage purposes from a
+ typedef. */
+
+static void bt_reset_linkage_1 (binding_entry, void *);
+static void bt_reset_linkage_2 (binding_entry, void *);
+
+/* First reset the visibility of all the types. */
+
+static void
+reset_type_linkage_1 (tree type)
+{
+ set_linkage_according_to_type (type, TYPE_MAIN_DECL (type));
+ if (CLASS_TYPE_P (type))
+ binding_table_foreach (CLASSTYPE_NESTED_UTDS (type),
+ bt_reset_linkage_1, NULL);
+}
+static void
+bt_reset_linkage_1 (binding_entry b, void */*data*/)
+{
+ reset_type_linkage_1 (b->type);
+}
+
+/* Then reset the visibility of any static data members or member
+ functions that use those types. */
+
+static void
+reset_decl_linkage (tree decl)
+{
+ if (TREE_PUBLIC (decl))
+ return;
+ if (DECL_CLONED_FUNCTION_P (decl))
+ return;
+ TREE_PUBLIC (decl) = true;
+ DECL_INTERFACE_KNOWN (decl) = false;
+ determine_visibility (decl);
+ tentative_decl_linkage (decl);
+}
+static void
+reset_type_linkage_2 (tree type)
+{
+ if (CLASS_TYPE_P (type))
+ {
+ if (tree vt = CLASSTYPE_VTABLES (type))
+ {
+ tree name = mangle_vtbl_for_type (type);
+ DECL_NAME (vt) = name;
+ SET_DECL_ASSEMBLER_NAME (vt, name);
+ reset_decl_linkage (vt);
+ }
+ if (tree ti = CLASSTYPE_TYPEINFO_VAR (type))
+ {
+ tree name = mangle_typeinfo_for_type (type);
+ DECL_NAME (ti) = name;
+ SET_DECL_ASSEMBLER_NAME (ti, name);
+ TREE_TYPE (name) = type;
+ reset_decl_linkage (ti);
+ }
+ for (tree m = TYPE_FIELDS (type); m; m = DECL_CHAIN (m))
+ if (TREE_CODE (m) == VAR_DECL)
+ reset_decl_linkage (m);
+ for (tree m = TYPE_METHODS (type); m; m = DECL_CHAIN (m))
+ reset_decl_linkage (m);
+ binding_table_foreach (CLASSTYPE_NESTED_UTDS (type),
+ bt_reset_linkage_2, NULL);
+ }
+}
+static void
+bt_reset_linkage_2 (binding_entry b, void */*data*/)
+{
+ reset_type_linkage_2 (b->type);
+}
+void
+reset_type_linkage (tree type)
+{
+ reset_type_linkage_1 (type);
+ reset_type_linkage_2 (type);
+}
+
+/* Set up our initial idea of what the linkage of DECL should be. */
+
+void
+tentative_decl_linkage (tree decl)
+{
+ if (DECL_INTERFACE_KNOWN (decl))
+ /* We've already made a decision as to how this function will
+ be handled. */;
+ else if (vague_linkage_p (decl))
+ {
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && decl_defined_p (decl))
+ {
+ DECL_EXTERNAL (decl) = 1;
+ DECL_NOT_REALLY_EXTERN (decl) = 1;
+ note_vague_linkage_fn (decl);
+ /* A non-template inline function with external linkage will
+ always be COMDAT. As we must eventually determine the
+ linkage of all functions, and as that causes writes to
+ the data mapped in from the PCH file, it's advantageous
+ to mark the functions at this point. */
+ if (DECL_DECLARED_INLINE_P (decl)
+ && (!DECL_IMPLICIT_INSTANTIATION (decl)
+ || DECL_DEFAULTED_FN (decl)))
+ {
+ /* This function must have external linkage, as
+ otherwise DECL_INTERFACE_KNOWN would have been
+ set. */
+ gcc_assert (TREE_PUBLIC (decl));
+ comdat_linkage (decl);
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ }
+ }
+ else if (TREE_CODE (decl) == VAR_DECL)
+ maybe_commonize_var (decl);
+ }
+}
+
+/* DECL is a FUNCTION_DECL or VAR_DECL. If the object file linkage
+ for DECL has not already been determined, do so now by setting
+ DECL_EXTERNAL, DECL_COMDAT and other related flags. Until this
+ function is called entities with vague linkage whose definitions
+ are available must have TREE_PUBLIC set.
+
+ If this function decides to place DECL in COMDAT, it will set
+ appropriate flags -- but will not clear DECL_EXTERNAL. It is up to
+ the caller to decide whether or not to clear DECL_EXTERNAL. Some
+ callers defer that decision until it is clear that DECL is actually
+ required. */
+
+void
+import_export_decl (tree decl)
+{
+ int emit_p;
+ bool comdat_p;
+ bool import_p;
+ tree class_type = NULL_TREE;
+
+ if (DECL_INTERFACE_KNOWN (decl))
+ return;
+
+ /* We cannot determine what linkage to give to an entity with vague
+ linkage until the end of the file. For example, a virtual table
+ for a class will be defined if and only if the key method is
+ defined in this translation unit. As a further example, consider
+ that when compiling a translation unit that uses PCH file with
+ "-frepo" it would be incorrect to make decisions about what
+ entities to emit when building the PCH; those decisions must be
+ delayed until the repository information has been processed. */
+ gcc_assert (at_eof);
+ /* Object file linkage for explicit instantiations is handled in
+ mark_decl_instantiated. For static variables in functions with
+ vague linkage, maybe_commonize_var is used.
+
+ Therefore, the only declarations that should be provided to this
+ function are those with external linkage that are:
+
+ * implicit instantiations of function templates
+
+ * inline function
+
+ * implicit instantiations of static data members of class
+ templates
+
+ * virtual tables
+
+ * typeinfo objects
+
+ Furthermore, all entities that reach this point must have a
+ definition available in this translation unit.
+
+ The following assertions check these conditions. */
+ gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
+ /* Any code that creates entities with TREE_PUBLIC cleared should
+ also set DECL_INTERFACE_KNOWN. */
+ gcc_assert (TREE_PUBLIC (decl));
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ gcc_assert (DECL_IMPLICIT_INSTANTIATION (decl)
+ || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)
+ || DECL_DECLARED_INLINE_P (decl));
+ else
+ gcc_assert (DECL_IMPLICIT_INSTANTIATION (decl)
+ || DECL_VTABLE_OR_VTT_P (decl)
+ || DECL_TINFO_P (decl));
+ /* Check that a definition of DECL is available in this translation
+ unit. */
+ gcc_assert (!DECL_REALLY_EXTERN (decl));
+
+ /* Assume that DECL will not have COMDAT linkage. */
+ comdat_p = false;
+ /* Assume that DECL will not be imported into this translation
+ unit. */
+ import_p = false;
+
+ /* See if the repository tells us whether or not to emit DECL in
+ this translation unit. */
+ emit_p = repo_emit_p (decl);
+ if (emit_p == 0)
+ import_p = true;
+ else if (emit_p == 1)
+ {
+ /* The repository indicates that this entity should be defined
+ here. Make sure the back end honors that request. */
+ if (VAR_P (decl))
+ mark_needed (decl);
+ else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
+ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
+ {
+ tree clone;
+ FOR_EACH_CLONE (clone, decl)
+ mark_needed (clone);
+ }
+ else
+ mark_needed (decl);
+ /* Output the definition as an ordinary strong definition. */
+ DECL_EXTERNAL (decl) = 0;
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ return;
+ }
+
+ if (import_p)
+ /* We have already decided what to do with this DECL; there is no
+ need to check anything further. */
+ ;
+ else if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl))
+ {
+ class_type = DECL_CONTEXT (decl);
+ import_export_class (class_type);
+ if (TYPE_FOR_JAVA (class_type))
+ import_p = true;
+ else if (CLASSTYPE_INTERFACE_KNOWN (class_type)
+ && CLASSTYPE_INTERFACE_ONLY (class_type))
+ import_p = true;
+ else if ((!flag_weak || TARGET_WEAK_NOT_IN_ARCHIVE_TOC)
+ && !CLASSTYPE_USE_TEMPLATE (class_type)
+ && CLASSTYPE_KEY_METHOD (class_type)
+ && !DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (class_type)))
+ /* The ABI requires that all virtual tables be emitted with
+ COMDAT linkage. However, on systems where COMDAT symbols
+ don't show up in the table of contents for a static
+ archive, or on systems without weak symbols (where we
+ approximate COMDAT linkage by using internal linkage), the
+ linker will report errors about undefined symbols because
+ it will not see the virtual table definition. Therefore,
+ in the case that we know that the virtual table will be
+ emitted in only one translation unit, we make the virtual
+ table an ordinary definition with external linkage. */
+ DECL_EXTERNAL (decl) = 0;
+ else if (CLASSTYPE_INTERFACE_KNOWN (class_type))
+ {
+ /* CLASS_TYPE is being exported from this translation unit,
+ so DECL should be defined here. */
+ if (!flag_weak && CLASSTYPE_EXPLICIT_INSTANTIATION (class_type))
+ /* If a class is declared in a header with the "extern
+ template" extension, then it will not be instantiated,
+ even in translation units that would normally require
+ it. Often such classes are explicitly instantiated in
+ one translation unit. Therefore, the explicit
+ instantiation must be made visible to other translation
+ units. */
+ DECL_EXTERNAL (decl) = 0;
+ else
+ {
+ /* The generic C++ ABI says that class data is always
+ COMDAT, even if there is a key function. Some
+ variants (e.g., the ARM EABI) says that class data
+ only has COMDAT linkage if the class data might be
+ emitted in more than one translation unit. When the
+ key method can be inline and is inline, we still have
+ to arrange for comdat even though
+ class_data_always_comdat is false. */
+ if (!CLASSTYPE_KEY_METHOD (class_type)
+ || DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (class_type))
+ || targetm.cxx.class_data_always_comdat ())
+ {
+ /* The ABI requires COMDAT linkage. Normally, we
+ only emit COMDAT things when they are needed;
+ make sure that we realize that this entity is
+ indeed needed. */
+ comdat_p = true;
+ mark_needed (decl);
+ }
+ }
+ }
+ else if (!flag_implicit_templates
+ && CLASSTYPE_IMPLICIT_INSTANTIATION (class_type))
+ import_p = true;
+ else
+ comdat_p = true;
+ }
+ else if (VAR_P (decl) && DECL_TINFO_P (decl))
+ {
+ tree type = TREE_TYPE (DECL_NAME (decl));
+ if (CLASS_TYPE_P (type))
+ {
+ class_type = type;
+ import_export_class (type);
+ if (CLASSTYPE_INTERFACE_KNOWN (type)
+ && TYPE_POLYMORPHIC_P (type)
+ && CLASSTYPE_INTERFACE_ONLY (type)
+ /* If -fno-rtti was specified, then we cannot be sure
+ that RTTI information will be emitted with the
+ virtual table of the class, so we must emit it
+ wherever it is used. */
+ && flag_rtti)
+ import_p = true;
+ else
+ {
+ if (CLASSTYPE_INTERFACE_KNOWN (type)
+ && !CLASSTYPE_INTERFACE_ONLY (type))
+ {
+ comdat_p = (targetm.cxx.class_data_always_comdat ()
+ || (CLASSTYPE_KEY_METHOD (type)
+ && DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (type))));
+ mark_needed (decl);
+ if (!flag_weak)
+ {
+ comdat_p = false;
+ DECL_EXTERNAL (decl) = 0;
+ }
+ }
+ else
+ comdat_p = true;
+ }
+ }
+ else
+ comdat_p = true;
+ }
+ else if (DECL_TEMPLOID_INSTANTIATION (decl))
+ {
+ /* DECL is an implicit instantiation of a function or static
+ data member. */
+ if ((flag_implicit_templates
+ && !flag_use_repository)
+ || (flag_implicit_inline_templates
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (decl)))
+ comdat_p = true;
+ else
+ /* If we are not implicitly generating templates, then mark
+ this entity as undefined in this translation unit. */
+ import_p = true;
+ }
+ else if (DECL_FUNCTION_MEMBER_P (decl))
+ {
+ if (!DECL_DECLARED_INLINE_P (decl))
+ {
+ tree ctype = DECL_CONTEXT (decl);
+ import_export_class (ctype);
+ if (CLASSTYPE_INTERFACE_KNOWN (ctype))
+ {
+ DECL_NOT_REALLY_EXTERN (decl)
+ = ! (CLASSTYPE_INTERFACE_ONLY (ctype)
+ || (DECL_DECLARED_INLINE_P (decl)
+ && ! flag_implement_inlines
+ && !DECL_VINDEX (decl)));
+
+ if (!DECL_NOT_REALLY_EXTERN (decl))
+ DECL_EXTERNAL (decl) = 1;
+
+ /* Always make artificials weak. */
+ if (DECL_ARTIFICIAL (decl) && flag_weak)
+ comdat_p = true;
+ else
+ maybe_make_one_only (decl);
+ }
+ }
+ else
+ comdat_p = true;
+ }
+ else
+ comdat_p = true;
+
+ if (import_p)
+ {
+ /* If we are importing DECL into this translation unit, mark is
+ an undefined here. */
+ DECL_EXTERNAL (decl) = 1;
+ DECL_NOT_REALLY_EXTERN (decl) = 0;
+ }
+ else if (comdat_p)
+ {
+ /* If we decided to put DECL in COMDAT, mark it accordingly at
+ this point. */
+ comdat_linkage (decl);
+ }
+
+ DECL_INTERFACE_KNOWN (decl) = 1;
+}
+
+/* Return an expression that performs the destruction of DECL, which
+ must be a VAR_DECL whose type has a non-trivial destructor, or is
+ an array whose (innermost) elements have a non-trivial destructor. */
+
+tree
+build_cleanup (tree decl)
+{
+ tree clean = cxx_maybe_build_cleanup (decl, tf_warning_or_error);
+ gcc_assert (clean != NULL_TREE);
+ return clean;
+}
+
+/* Returns the initialization guard variable for the variable DECL,
+ which has static storage duration. */
+
+tree
+get_guard (tree decl)
+{
+ tree sname;
+ tree guard;
+
+ sname = mangle_guard_variable (decl);
+ guard = IDENTIFIER_GLOBAL_VALUE (sname);
+ if (! guard)
+ {
+ tree guard_type;
+
+ /* We use a type that is big enough to contain a mutex as well
+ as an integer counter. */
+ guard_type = targetm.cxx.guard_type ();
+ guard = build_decl (DECL_SOURCE_LOCATION (decl),
+ VAR_DECL, sname, guard_type);
+
+ /* The guard should have the same linkage as what it guards. */
+ TREE_PUBLIC (guard) = TREE_PUBLIC (decl);
+ TREE_STATIC (guard) = TREE_STATIC (decl);
+ DECL_COMMON (guard) = DECL_COMMON (decl);
+ DECL_COMDAT (guard) = DECL_COMDAT (decl);
+ DECL_TLS_MODEL (guard) = DECL_TLS_MODEL (decl);
+ if (DECL_ONE_ONLY (decl))
+ make_decl_one_only (guard, cxx_comdat_group (guard));
+ if (TREE_PUBLIC (decl))
+ DECL_WEAK (guard) = DECL_WEAK (decl);
+ DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl);
+ DECL_VISIBILITY_SPECIFIED (guard) = DECL_VISIBILITY_SPECIFIED (decl);
+
+ DECL_ARTIFICIAL (guard) = 1;
+ DECL_IGNORED_P (guard) = 1;
+ TREE_USED (guard) = 1;
+ pushdecl_top_level_and_finish (guard, NULL_TREE);
+ }
+ return guard;
+}
+
+/* Return those bits of the GUARD variable that should be set when the
+ guarded entity is actually initialized. */
+
+static tree
+get_guard_bits (tree guard)
+{
+ if (!targetm.cxx.guard_mask_bit ())
+ {
+ /* We only set the first byte of the guard, in order to leave room
+ for a mutex in the high-order bits. */
+ guard = build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (guard)),
+ guard);
+ guard = build1 (NOP_EXPR,
+ build_pointer_type (char_type_node),
+ guard);
+ guard = build1 (INDIRECT_REF, char_type_node, guard);
+ }
+
+ return guard;
+}
+
+/* Return an expression which determines whether or not the GUARD
+ variable has already been initialized. */
+
+tree
+get_guard_cond (tree guard)
+{
+ tree guard_value;
+
+ /* Check to see if the GUARD is zero. */
+ guard = get_guard_bits (guard);
+
+ /* Mask off all but the low bit. */
+ if (targetm.cxx.guard_mask_bit ())
+ {
+ guard_value = integer_one_node;
+ if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
+ guard_value = convert (TREE_TYPE (guard), guard_value);
+ guard = cp_build_binary_op (input_location,
+ BIT_AND_EXPR, guard, guard_value,
+ tf_warning_or_error);
+ }
+
+ guard_value = integer_zero_node;
+ if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
+ guard_value = convert (TREE_TYPE (guard), guard_value);
+ return cp_build_binary_op (input_location,
+ EQ_EXPR, guard, guard_value,
+ tf_warning_or_error);
+}
+
+/* Return an expression which sets the GUARD variable, indicating that
+ the variable being guarded has been initialized. */
+
+tree
+set_guard (tree guard)
+{
+ tree guard_init;
+
+ /* Set the GUARD to one. */
+ guard = get_guard_bits (guard);
+ guard_init = integer_one_node;
+ if (!same_type_p (TREE_TYPE (guard_init), TREE_TYPE (guard)))
+ guard_init = convert (TREE_TYPE (guard), guard_init);
+ return cp_build_modify_expr (guard, NOP_EXPR, guard_init,
+ tf_warning_or_error);
+}
+
+/* Returns true iff we can tell that VAR does not have a dynamic
+ initializer. */
+
+static bool
+var_defined_without_dynamic_init (tree var)
+{
+ /* If it's defined in another TU, we can't tell. */
+ if (DECL_EXTERNAL (var))
+ return false;
+ /* If it has a non-trivial destructor, registering the destructor
+ counts as dynamic initialization. */
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var)))
+ return false;
+ /* If it's in this TU, its initializer has been processed. */
+ gcc_assert (DECL_INITIALIZED_P (var));
+ /* If it has no initializer or a constant one, it's not dynamic. */
+ return (!DECL_NONTRIVIALLY_INITIALIZED_P (var)
+ || DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var));
+}
+
+/* Returns true iff VAR is a variable that needs uses to be
+ wrapped for possible dynamic initialization. */
+
+static bool
+var_needs_tls_wrapper (tree var)
+{
+ return (!error_operand_p (var)
+ && DECL_THREAD_LOCAL_P (var)
+ && !DECL_GNU_TLS_P (var)
+ && !DECL_FUNCTION_SCOPE_P (var)
+ && !var_defined_without_dynamic_init (var));
+}
+
+/* Get the FUNCTION_DECL for the shared TLS init function for this
+ translation unit. */
+
+static tree
+get_local_tls_init_fn (void)
+{
+ tree sname = get_identifier ("__tls_init");
+ tree fn = IDENTIFIER_GLOBAL_VALUE (sname);
+ if (!fn)
+ {
+ fn = build_lang_decl (FUNCTION_DECL, sname,
+ build_function_type (void_type_node,
+ void_list_node));
+ SET_DECL_LANGUAGE (fn, lang_c);
+ TREE_PUBLIC (fn) = false;
+ DECL_ARTIFICIAL (fn) = true;
+ mark_used (fn);
+ SET_IDENTIFIER_GLOBAL_VALUE (sname, fn);
+ }
+ return fn;
+}
+
+/* Get a FUNCTION_DECL for the init function for the thread_local
+ variable VAR. The init function will be an alias to the function
+ that initializes all the non-local TLS variables in the translation
+ unit. The init function is only used by the wrapper function. */
+
+static tree
+get_tls_init_fn (tree var)
+{
+ /* Only C++11 TLS vars need this init fn. */
+ if (!var_needs_tls_wrapper (var))
+ return NULL_TREE;
+
+ /* If -fno-extern-tls-init, assume that we don't need to call
+ a tls init function for a variable defined in another TU. */
+ if (!flag_extern_tls_init && DECL_EXTERNAL (var))
+ return NULL_TREE;
+
+#ifdef ASM_OUTPUT_DEF
+ /* If the variable is internal, or if we can't generate aliases,
+ call the local init function directly. */
+ if (!TREE_PUBLIC (var))
+#endif
+ return get_local_tls_init_fn ();
+
+ tree sname = mangle_tls_init_fn (var);
+ tree fn = IDENTIFIER_GLOBAL_VALUE (sname);
+ if (!fn)
+ {
+ fn = build_lang_decl (FUNCTION_DECL, sname,
+ build_function_type (void_type_node,
+ void_list_node));
+ SET_DECL_LANGUAGE (fn, lang_c);
+ TREE_PUBLIC (fn) = TREE_PUBLIC (var);
+ DECL_ARTIFICIAL (fn) = true;
+ DECL_COMDAT (fn) = DECL_COMDAT (var);
+ DECL_EXTERNAL (fn) = DECL_EXTERNAL (var);
+ if (DECL_ONE_ONLY (var))
+ make_decl_one_only (fn, cxx_comdat_group (fn));
+ if (TREE_PUBLIC (var))
+ {
+ tree obtype = strip_array_types (non_reference (TREE_TYPE (var)));
+ /* If the variable is defined somewhere else and might have static
+ initialization, make the init function a weak reference. */
+ if ((!TYPE_NEEDS_CONSTRUCTING (obtype)
+ || TYPE_HAS_CONSTEXPR_CTOR (obtype))
+ && TYPE_HAS_TRIVIAL_DESTRUCTOR (obtype)
+ && DECL_EXTERNAL (var))
+ declare_weak (fn);
+ else
+ DECL_WEAK (fn) = DECL_WEAK (var);
+ }
+ DECL_VISIBILITY (fn) = DECL_VISIBILITY (var);
+ DECL_VISIBILITY_SPECIFIED (fn) = DECL_VISIBILITY_SPECIFIED (var);
+ DECL_DLLIMPORT_P (fn) = DECL_DLLIMPORT_P (var);
+ DECL_IGNORED_P (fn) = 1;
+ mark_used (fn);
+
+ DECL_BEFRIENDING_CLASSES (fn) = var;
+
+ SET_IDENTIFIER_GLOBAL_VALUE (sname, fn);
+ }
+ return fn;
+}
+
+/* Get a FUNCTION_DECL for the init wrapper function for the thread_local
+ variable VAR. The wrapper function calls the init function (if any) for
+ VAR and then returns a reference to VAR. The wrapper function is used
+ in place of VAR everywhere VAR is mentioned. */
+
+tree
+get_tls_wrapper_fn (tree var)
+{
+ /* Only C++11 TLS vars need this wrapper fn. */
+ if (!var_needs_tls_wrapper (var))
+ return NULL_TREE;
+
+ tree sname = mangle_tls_wrapper_fn (var);
+ tree fn = IDENTIFIER_GLOBAL_VALUE (sname);
+ if (!fn)
+ {
+ /* A named rvalue reference is an lvalue, so the wrapper should
+ always return an lvalue reference. */
+ tree type = non_reference (TREE_TYPE (var));
+ type = build_reference_type (type);
+ tree fntype = build_function_type (type, void_list_node);
+ fn = build_lang_decl (FUNCTION_DECL, sname, fntype);
+ SET_DECL_LANGUAGE (fn, lang_c);
+ TREE_PUBLIC (fn) = TREE_PUBLIC (var);
+ DECL_ARTIFICIAL (fn) = true;
+ DECL_IGNORED_P (fn) = 1;
+ /* The wrapper is inline and emitted everywhere var is used. */
+ DECL_DECLARED_INLINE_P (fn) = true;
+ if (TREE_PUBLIC (var))
+ {
+ comdat_linkage (fn);
+#ifdef HAVE_GAS_HIDDEN
+ /* Make the wrapper bind locally; there's no reason to share
+ the wrapper between multiple shared objects. */
+ DECL_VISIBILITY (fn) = VISIBILITY_INTERNAL;
+ DECL_VISIBILITY_SPECIFIED (fn) = true;
+#endif
+ }
+ if (!TREE_PUBLIC (fn))
+ DECL_INTERFACE_KNOWN (fn) = true;
+ mark_used (fn);
+ note_vague_linkage_fn (fn);
+
+#if 0
+ /* We want CSE to commonize calls to the wrapper, but marking it as
+ pure is unsafe since it has side-effects. I guess we need a new
+ ECF flag even weaker than ECF_PURE. FIXME! */
+ DECL_PURE_P (fn) = true;
+#endif
+
+ DECL_BEFRIENDING_CLASSES (fn) = var;
+
+ SET_IDENTIFIER_GLOBAL_VALUE (sname, fn);
+ }
+ return fn;
+}
+
+/* At EOF, generate the definition for the TLS wrapper function FN:
+
+ T& var_wrapper() {
+ if (init_fn) init_fn();
+ return var;
+ } */
+
+static void
+generate_tls_wrapper (tree fn)
+{
+ tree var = DECL_BEFRIENDING_CLASSES (fn);
+
+ start_preparsed_function (fn, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
+ tree body = begin_function_body ();
+ /* Only call the init fn if there might be one. */
+ if (tree init_fn = get_tls_init_fn (var))
+ {
+ tree if_stmt = NULL_TREE;
+ /* If init_fn is a weakref, make sure it exists before calling. */
+ if (lookup_attribute ("weak", DECL_ATTRIBUTES (init_fn)))
+ {
+ if_stmt = begin_if_stmt ();
+ tree addr = cp_build_addr_expr (init_fn, tf_warning_or_error);
+ tree cond = cp_build_binary_op (DECL_SOURCE_LOCATION (var),
+ NE_EXPR, addr, nullptr_node,
+ tf_warning_or_error);
+ finish_if_stmt_cond (cond, if_stmt);
+ }
+ finish_expr_stmt (build_cxx_call
+ (init_fn, 0, NULL, tf_warning_or_error));
+ if (if_stmt)
+ {
+ finish_then_clause (if_stmt);
+ finish_if_stmt (if_stmt);
+ }
+ }
+ else
+ /* If there's no initialization, the wrapper is a constant function. */
+ TREE_READONLY (fn) = true;
+ finish_return_stmt (convert_from_reference (var));
+ finish_function_body (body);
+ expand_or_defer_fn (finish_function (0));
+}
+
+/* Start the process of running a particular set of global constructors
+ or destructors. Subroutine of do_[cd]tors. Also called from
+ vtv_start_verification_constructor_init_function. */
+
+static tree
+start_objects (int method_type, int initp)
+{
+ tree body;
+ tree fndecl;
+ char type[14];
+
+ /* Make ctor or dtor function. METHOD_TYPE may be 'I' or 'D'. */
+
+ if (initp != DEFAULT_INIT_PRIORITY)
+ {
+ char joiner;
+
+#ifdef JOINER
+ joiner = JOINER;
+#else
+ joiner = '_';
+#endif
+
+ sprintf (type, "sub_%c%c%.5u", method_type, joiner, initp);
+ }
+ else
+ sprintf (type, "sub_%c", method_type);
+
+ fndecl = build_lang_decl (FUNCTION_DECL,
+ get_file_function_name (type),
+ build_function_type_list (void_type_node,
+ NULL_TREE));
+ start_preparsed_function (fndecl, /*attrs=*/NULL_TREE, SF_PRE_PARSED);
+
+ TREE_PUBLIC (current_function_decl) = 0;
+
+ /* Mark as artificial because it's not explicitly in the user's
+ source code. */
+ DECL_ARTIFICIAL (current_function_decl) = 1;
+
+ /* Mark this declaration as used to avoid spurious warnings. */
+ TREE_USED (current_function_decl) = 1;
+
+ /* Mark this function as a global constructor or destructor. */
+ if (method_type == 'I')
+ DECL_GLOBAL_CTOR_P (current_function_decl) = 1;
+ else
+ DECL_GLOBAL_DTOR_P (current_function_decl) = 1;
+
+ body = begin_compound_stmt (BCS_FN_BODY);
+
+ return body;
+}
+
+/* Finish the process of running a particular set of global constructors
+ or destructors. Subroutine of do_[cd]tors. */
+
+static void
+finish_objects (int method_type, int initp, tree body)
+{
+ tree fn;
+
+ /* Finish up. */
+ finish_compound_stmt (body);
+ fn = finish_function (0);
+
+ if (method_type == 'I')
+ {
+ DECL_STATIC_CONSTRUCTOR (fn) = 1;
+ decl_init_priority_insert (fn, initp);
+ }
+ else
+ {
+ DECL_STATIC_DESTRUCTOR (fn) = 1;
+ decl_fini_priority_insert (fn, initp);
+ }
+
+ expand_or_defer_fn (fn);
+}
+
+/* The names of the parameters to the function created to handle
+ initializations and destructions for objects with static storage
+ duration. */
+#define INITIALIZE_P_IDENTIFIER "__initialize_p"
+#define PRIORITY_IDENTIFIER "__priority"
+
+/* The name of the function we create to handle initializations and
+ destructions for objects with static storage duration. */
+#define SSDF_IDENTIFIER "__static_initialization_and_destruction"
+
+/* The declaration for the __INITIALIZE_P argument. */
+static GTY(()) tree initialize_p_decl;
+
+/* The declaration for the __PRIORITY argument. */
+static GTY(()) tree priority_decl;
+
+/* The declaration for the static storage duration function. */
+static GTY(()) tree ssdf_decl;
+
+/* All the static storage duration functions created in this
+ translation unit. */
+static GTY(()) vec<tree, va_gc> *ssdf_decls;
+
+/* A map from priority levels to information about that priority
+ level. There may be many such levels, so efficient lookup is
+ important. */
+static splay_tree priority_info_map;
+
+/* Begins the generation of the function that will handle all
+ initialization and destruction of objects with static storage
+ duration. The function generated takes two parameters of type
+ `int': __INITIALIZE_P and __PRIORITY. If __INITIALIZE_P is
+ nonzero, it performs initializations. Otherwise, it performs
+ destructions. It only performs those initializations or
+ destructions with the indicated __PRIORITY. The generated function
+ returns no value.
+
+ It is assumed that this function will only be called once per
+ translation unit. */
+
+static tree
+start_static_storage_duration_function (unsigned count)
+{
+ tree type;
+ tree body;
+ char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 32];
+
+ /* Create the identifier for this function. It will be of the form
+ SSDF_IDENTIFIER_<number>. */
+ sprintf (id, "%s_%u", SSDF_IDENTIFIER, count);
+
+ type = build_function_type_list (void_type_node,
+ integer_type_node, integer_type_node,
+ NULL_TREE);
+
+ /* Create the FUNCTION_DECL itself. */
+ ssdf_decl = build_lang_decl (FUNCTION_DECL,
+ get_identifier (id),
+ type);
+ TREE_PUBLIC (ssdf_decl) = 0;
+ DECL_ARTIFICIAL (ssdf_decl) = 1;
+
+ /* Put this function in the list of functions to be called from the
+ static constructors and destructors. */
+ if (!ssdf_decls)
+ {
+ vec_alloc (ssdf_decls, 32);
+
+ /* Take this opportunity to initialize the map from priority
+ numbers to information about that priority level. */
+ priority_info_map = splay_tree_new (splay_tree_compare_ints,
+ /*delete_key_fn=*/0,
+ /*delete_value_fn=*/
+ (splay_tree_delete_value_fn) &free);
+
+ /* We always need to generate functions for the
+ DEFAULT_INIT_PRIORITY so enter it now. That way when we walk
+ priorities later, we'll be sure to find the
+ DEFAULT_INIT_PRIORITY. */
+ get_priority_info (DEFAULT_INIT_PRIORITY);
+ }
+
+ vec_safe_push (ssdf_decls, ssdf_decl);
+
+ /* Create the argument list. */
+ initialize_p_decl = cp_build_parm_decl
+ (get_identifier (INITIALIZE_P_IDENTIFIER), integer_type_node);
+ DECL_CONTEXT (initialize_p_decl) = ssdf_decl;
+ TREE_USED (initialize_p_decl) = 1;
+ priority_decl = cp_build_parm_decl
+ (get_identifier (PRIORITY_IDENTIFIER), integer_type_node);
+ DECL_CONTEXT (priority_decl) = ssdf_decl;
+ TREE_USED (priority_decl) = 1;
+
+ DECL_CHAIN (initialize_p_decl) = priority_decl;
+ DECL_ARGUMENTS (ssdf_decl) = initialize_p_decl;
+
+ /* Put the function in the global scope. */
+ pushdecl (ssdf_decl);
+
+ /* Start the function itself. This is equivalent to declaring the
+ function as:
+
+ static void __ssdf (int __initialize_p, init __priority_p);
+
+ It is static because we only need to call this function from the
+ various constructor and destructor functions for this module. */
+ start_preparsed_function (ssdf_decl,
+ /*attrs=*/NULL_TREE,
+ SF_PRE_PARSED);
+
+ /* Set up the scope of the outermost block in the function. */
+ body = begin_compound_stmt (BCS_FN_BODY);
+
+ return body;
+}
+
+/* Finish the generation of the function which performs initialization
+ and destruction of objects with static storage duration. After
+ this point, no more such objects can be created. */
+
+static void
+finish_static_storage_duration_function (tree body)
+{
+ /* Close out the function. */
+ finish_compound_stmt (body);
+ expand_or_defer_fn (finish_function (0));
+}
+
+/* Return the information about the indicated PRIORITY level. If no
+ code to handle this level has yet been generated, generate the
+ appropriate prologue. */
+
+static priority_info
+get_priority_info (int priority)
+{
+ priority_info pi;
+ splay_tree_node n;
+
+ n = splay_tree_lookup (priority_info_map,
+ (splay_tree_key) priority);
+ if (!n)
+ {
+ /* Create a new priority information structure, and insert it
+ into the map. */
+ pi = XNEW (struct priority_info_s);
+ pi->initializations_p = 0;
+ pi->destructions_p = 0;
+ splay_tree_insert (priority_info_map,
+ (splay_tree_key) priority,
+ (splay_tree_value) pi);
+ }
+ else
+ pi = (priority_info) n->value;
+
+ return pi;
+}
+
+/* The effective initialization priority of a DECL. */
+
+#define DECL_EFFECTIVE_INIT_PRIORITY(decl) \
+ ((!DECL_HAS_INIT_PRIORITY_P (decl) || DECL_INIT_PRIORITY (decl) == 0) \
+ ? DEFAULT_INIT_PRIORITY : DECL_INIT_PRIORITY (decl))
+
+/* Whether a DECL needs a guard to protect it against multiple
+ initialization. */
+
+#define NEEDS_GUARD_P(decl) (TREE_PUBLIC (decl) && (DECL_COMMON (decl) \
+ || DECL_ONE_ONLY (decl) \
+ || DECL_WEAK (decl)))
+
+/* Called from one_static_initialization_or_destruction(),
+ via walk_tree.
+ Walks the initializer list of a global variable and looks for
+ temporary variables (DECL_NAME() == NULL and DECL_ARTIFICIAL != 0)
+ and that have their DECL_CONTEXT() == NULL.
+ For each such temporary variable, set their DECL_CONTEXT() to
+ the current function. This is necessary because otherwise
+ some optimizers (enabled by -O2 -fprofile-arcs) might crash
+ when trying to refer to a temporary variable that does not have
+ it's DECL_CONTECT() properly set. */
+static tree
+fix_temporary_vars_context_r (tree *node,
+ int * /*unused*/,
+ void * /*unused1*/)
+{
+ gcc_assert (current_function_decl);
+
+ if (TREE_CODE (*node) == BIND_EXPR)
+ {
+ tree var;
+
+ for (var = BIND_EXPR_VARS (*node); var; var = DECL_CHAIN (var))
+ if (VAR_P (var)
+ && !DECL_NAME (var)
+ && DECL_ARTIFICIAL (var)
+ && !DECL_CONTEXT (var))
+ DECL_CONTEXT (var) = current_function_decl;
+ }
+
+ return NULL_TREE;
+}
+
+/* Set up to handle the initialization or destruction of DECL. If
+ INITP is nonzero, we are initializing the variable. Otherwise, we
+ are destroying it. */
+
+static void
+one_static_initialization_or_destruction (tree decl, tree init, bool initp)
+{
+ tree guard_if_stmt = NULL_TREE;
+ tree guard;
+
+ /* If we are supposed to destruct and there's a trivial destructor,
+ nothing has to be done. */
+ if (!initp
+ && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+ return;
+
+ /* Trick the compiler into thinking we are at the file and line
+ where DECL was declared so that error-messages make sense, and so
+ that the debugger will show somewhat sensible file and line
+ information. */
+ input_location = DECL_SOURCE_LOCATION (decl);
+
+ /* Make sure temporary variables in the initialiser all have
+ their DECL_CONTEXT() set to a value different from NULL_TREE.
+ This can happen when global variables initialisers are built.
+ In that case, the DECL_CONTEXT() of the global variables _AND_ of all
+ the temporary variables that might have been generated in the
+ accompagning initialisers is NULL_TREE, meaning the variables have been
+ declared in the global namespace.
+ What we want to do here is to fix that and make sure the DECL_CONTEXT()
+ of the temporaries are set to the current function decl. */
+ cp_walk_tree_without_duplicates (&init,
+ fix_temporary_vars_context_r,
+ NULL);
+
+ /* Because of:
+
+ [class.access.spec]
+
+ Access control for implicit calls to the constructors,
+ the conversion functions, or the destructor called to
+ create and destroy a static data member is performed as
+ if these calls appeared in the scope of the member's
+ class.
+
+ we pretend we are in a static member function of the class of
+ which the DECL is a member. */
+ if (member_p (decl))
+ {
+ DECL_CONTEXT (current_function_decl) = DECL_CONTEXT (decl);
+ DECL_STATIC_FUNCTION_P (current_function_decl) = 1;
+ }
+
+ /* Assume we don't need a guard. */
+ guard = NULL_TREE;
+ /* We need a guard if this is an object with external linkage that
+ might be initialized in more than one place. (For example, a
+ static data member of a template, when the data member requires
+ construction.) */
+ if (NEEDS_GUARD_P (decl))
+ {
+ tree guard_cond;
+
+ guard = get_guard (decl);
+
+ /* When using __cxa_atexit, we just check the GUARD as we would
+ for a local static. */
+ if (flag_use_cxa_atexit)
+ {
+ /* When using __cxa_atexit, we never try to destroy
+ anything from a static destructor. */
+ gcc_assert (initp);
+ guard_cond = get_guard_cond (guard);
+ }
+ /* If we don't have __cxa_atexit, then we will be running
+ destructors from .fini sections, or their equivalents. So,
+ we need to know how many times we've tried to initialize this
+ object. We do initializations only if the GUARD is zero,
+ i.e., if we are the first to initialize the variable. We do
+ destructions only if the GUARD is one, i.e., if we are the
+ last to destroy the variable. */
+ else if (initp)
+ guard_cond
+ = cp_build_binary_op (input_location,
+ EQ_EXPR,
+ cp_build_unary_op (PREINCREMENT_EXPR,
+ guard,
+ /*noconvert=*/1,
+ tf_warning_or_error),
+ integer_one_node,
+ tf_warning_or_error);
+ else
+ guard_cond
+ = cp_build_binary_op (input_location,
+ EQ_EXPR,
+ cp_build_unary_op (PREDECREMENT_EXPR,
+ guard,
+ /*noconvert=*/1,
+ tf_warning_or_error),
+ integer_zero_node,
+ tf_warning_or_error);
+
+ guard_if_stmt = begin_if_stmt ();
+ finish_if_stmt_cond (guard_cond, guard_if_stmt);
+ }
+
+
+ /* If we're using __cxa_atexit, we have not already set the GUARD,
+ so we must do so now. */
+ if (guard && initp && flag_use_cxa_atexit)
+ finish_expr_stmt (set_guard (guard));
+
+ /* Perform the initialization or destruction. */
+ if (initp)
+ {
+ if (init)
+ {
+ finish_expr_stmt (init);
+ if (flag_sanitize & SANITIZE_ADDRESS)
+ {
+ varpool_node *vnode = varpool_get_node (decl);
+ if (vnode)
+ vnode->dynamically_initialized = 1;
+ }
+ }
+
+ /* If we're using __cxa_atexit, register a function that calls the
+ destructor for the object. */
+ if (flag_use_cxa_atexit)
+ finish_expr_stmt (register_dtor_fn (decl));
+ }
+ else
+ finish_expr_stmt (build_cleanup (decl));
+
+ /* Finish the guard if-stmt, if necessary. */
+ if (guard)
+ {
+ finish_then_clause (guard_if_stmt);
+ finish_if_stmt (guard_if_stmt);
+ }
+
+ /* Now that we're done with DECL we don't need to pretend to be a
+ member of its class any longer. */
+ DECL_CONTEXT (current_function_decl) = NULL_TREE;
+ DECL_STATIC_FUNCTION_P (current_function_decl) = 0;
+}
+
+/* Generate code to do the initialization or destruction of the decls in VARS,
+ a TREE_LIST of VAR_DECL with static storage duration.
+ Whether initialization or destruction is performed is specified by INITP. */
+
+static void
+do_static_initialization_or_destruction (tree vars, bool initp)
+{
+ tree node, init_if_stmt, cond;
+
+ /* Build the outer if-stmt to check for initialization or destruction. */
+ init_if_stmt = begin_if_stmt ();
+ cond = initp ? integer_one_node : integer_zero_node;
+ cond = cp_build_binary_op (input_location,
+ EQ_EXPR,
+ initialize_p_decl,
+ cond,
+ tf_warning_or_error);
+ finish_if_stmt_cond (cond, init_if_stmt);
+
+ /* To make sure dynamic construction doesn't access globals from other
+ compilation units where they might not be yet constructed, for
+ -fsanitize=address insert __asan_before_dynamic_init call that
+ prevents access to either all global variables that need construction
+ in other compilation units, or at least those that haven't been
+ initialized yet. Variables that need dynamic construction in
+ the current compilation unit are kept accessible. */
+ if (flag_sanitize & SANITIZE_ADDRESS)
+ finish_expr_stmt (asan_dynamic_init_call (/*after_p=*/false));
+
+ node = vars;
+ do {
+ tree decl = TREE_VALUE (node);
+ tree priority_if_stmt;
+ int priority;
+ priority_info pi;
+
+ /* If we don't need a destructor, there's nothing to do. Avoid
+ creating a possibly empty if-stmt. */
+ if (!initp && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+ {
+ node = TREE_CHAIN (node);
+ continue;
+ }
+
+ /* Remember that we had an initialization or finalization at this
+ priority. */
+ priority = DECL_EFFECTIVE_INIT_PRIORITY (decl);
+ pi = get_priority_info (priority);
+ if (initp)
+ pi->initializations_p = 1;
+ else
+ pi->destructions_p = 1;
+
+ /* Conditionalize this initialization on being in the right priority
+ and being initializing/finalizing appropriately. */
+ priority_if_stmt = begin_if_stmt ();
+ cond = cp_build_binary_op (input_location,
+ EQ_EXPR,
+ priority_decl,
+ build_int_cst (NULL_TREE, priority),
+ tf_warning_or_error);
+ finish_if_stmt_cond (cond, priority_if_stmt);
+
+ /* Process initializers with same priority. */
+ for (; node
+ && DECL_EFFECTIVE_INIT_PRIORITY (TREE_VALUE (node)) == priority;
+ node = TREE_CHAIN (node))
+ /* Do one initialization or destruction. */
+ one_static_initialization_or_destruction (TREE_VALUE (node),
+ TREE_PURPOSE (node), initp);
+
+ /* Finish up the priority if-stmt body. */
+ finish_then_clause (priority_if_stmt);
+ finish_if_stmt (priority_if_stmt);
+
+ } while (node);
+
+ /* Revert what __asan_before_dynamic_init did by calling
+ __asan_after_dynamic_init. */
+ if (flag_sanitize & SANITIZE_ADDRESS)
+ finish_expr_stmt (asan_dynamic_init_call (/*after_p=*/true));
+
+ /* Finish up the init/destruct if-stmt body. */
+ finish_then_clause (init_if_stmt);
+ finish_if_stmt (init_if_stmt);
+}
+
+/* VARS is a list of variables with static storage duration which may
+ need initialization and/or finalization. Remove those variables
+ that don't really need to be initialized or finalized, and return
+ the resulting list. The order in which the variables appear in
+ VARS is in reverse order of the order in which they should actually
+ be initialized. The list we return is in the unreversed order;
+ i.e., the first variable should be initialized first. */
+
+static tree
+prune_vars_needing_no_initialization (tree *vars)
+{
+ tree *var = vars;
+ tree result = NULL_TREE;
+
+ while (*var)
+ {
+ tree t = *var;
+ tree decl = TREE_VALUE (t);
+ tree init = TREE_PURPOSE (t);
+
+ /* Deal gracefully with error. */
+ if (decl == error_mark_node)
+ {
+ var = &TREE_CHAIN (t);
+ continue;
+ }
+
+ /* The only things that can be initialized are variables. */
+ gcc_assert (VAR_P (decl));
+
+ /* If this object is not defined, we don't need to do anything
+ here. */
+ if (DECL_EXTERNAL (decl))
+ {
+ var = &TREE_CHAIN (t);
+ continue;
+ }
+
+ /* Also, if the initializer already contains errors, we can bail
+ out now. */
+ if (init && TREE_CODE (init) == TREE_LIST
+ && value_member (error_mark_node, init))
+ {
+ var = &TREE_CHAIN (t);
+ continue;
+ }
+
+ /* This variable is going to need initialization and/or
+ finalization, so we add it to the list. */
+ *var = TREE_CHAIN (t);
+ TREE_CHAIN (t) = result;
+ result = t;
+ }
+
+ return result;
+}
+
+/* Make sure we have told the back end about all the variables in
+ VARS. */
+
+static void
+write_out_vars (tree vars)
+{
+ tree v;
+
+ for (v = vars; v; v = TREE_CHAIN (v))
+ {
+ tree var = TREE_VALUE (v);
+ if (!var_finalized_p (var))
+ {
+ import_export_decl (var);
+ rest_of_decl_compilation (var, 1, 1);
+ }
+ }
+}
+
+/* Generate a static constructor (if CONSTRUCTOR_P) or destructor
+ (otherwise) that will initialize all global objects with static
+ storage duration having the indicated PRIORITY. */
+
+static void
+generate_ctor_or_dtor_function (bool constructor_p, int priority,
+ location_t *locus)
+{
+ char function_key;
+ tree fndecl;
+ tree body;
+ size_t i;
+
+ input_location = *locus;
+ /* ??? */
+ /* Was: locus->line++; */
+
+ /* We use `I' to indicate initialization and `D' to indicate
+ destruction. */
+ function_key = constructor_p ? 'I' : 'D';
+
+ /* We emit the function lazily, to avoid generating empty
+ global constructors and destructors. */
+ body = NULL_TREE;
+
+ /* For Objective-C++, we may need to initialize metadata found in this module.
+ This must be done _before_ any other static initializations. */
+ if (c_dialect_objc () && (priority == DEFAULT_INIT_PRIORITY)
+ && constructor_p && objc_static_init_needed_p ())
+ {
+ body = start_objects (function_key, priority);
+ objc_generate_static_init_call (NULL_TREE);
+ }
+
+ /* Call the static storage duration function with appropriate
+ arguments. */
+ FOR_EACH_VEC_SAFE_ELT (ssdf_decls, i, fndecl)
+ {
+ /* Calls to pure or const functions will expand to nothing. */
+ if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
+ {
+ tree call;
+
+ if (! body)
+ body = start_objects (function_key, priority);
+
+ call = cp_build_function_call_nary (fndecl, tf_warning_or_error,
+ build_int_cst (NULL_TREE,
+ constructor_p),
+ build_int_cst (NULL_TREE,
+ priority),
+ NULL_TREE);
+ finish_expr_stmt (call);
+ }
+ }
+
+ /* Close out the function. */
+ if (body)
+ finish_objects (function_key, priority, body);
+}
+
+/* Generate constructor and destructor functions for the priority
+ indicated by N. */
+
+static int
+generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
+{
+ location_t *locus = (location_t *) data;
+ int priority = (int) n->key;
+ priority_info pi = (priority_info) n->value;
+
+ /* Generate the functions themselves, but only if they are really
+ needed. */
+ if (pi->initializations_p)
+ generate_ctor_or_dtor_function (/*constructor_p=*/true, priority, locus);
+ if (pi->destructions_p)
+ generate_ctor_or_dtor_function (/*constructor_p=*/false, priority, locus);
+
+ /* Keep iterating. */
+ return 0;
+}
+
+/* Java requires that we be able to reference a local address for a
+ method, and not be confused by PLT entries. If hidden aliases are
+ supported, collect and return all the functions for which we should
+ emit a hidden alias. */
+
+static struct pointer_set_t *
+collect_candidates_for_java_method_aliases (void)
+{
+ struct cgraph_node *node;
+ struct pointer_set_t *candidates = NULL;
+
+#ifndef HAVE_GAS_HIDDEN
+ return candidates;
+#endif
+
+ FOR_EACH_FUNCTION (node)
+ {
+ tree fndecl = node->decl;
+
+ if (DECL_CLASS_SCOPE_P (fndecl)
+ && TYPE_FOR_JAVA (DECL_CONTEXT (fndecl))
+ && TARGET_USE_LOCAL_THUNK_ALIAS_P (fndecl))
+ {
+ if (candidates == NULL)
+ candidates = pointer_set_create ();
+ pointer_set_insert (candidates, fndecl);
+ }
+ }
+
+ return candidates;
+}
+
+
+/* Java requires that we be able to reference a local address for a
+ method, and not be confused by PLT entries. If hidden aliases are
+ supported, emit one for each java function that we've emitted.
+ CANDIDATES is the set of FUNCTION_DECLs that were gathered
+ by collect_candidates_for_java_method_aliases. */
+
+static void
+build_java_method_aliases (struct pointer_set_t *candidates)
+{
+ struct cgraph_node *node;
+
+#ifndef HAVE_GAS_HIDDEN
+ return;
+#endif
+
+ FOR_EACH_FUNCTION (node)
+ {
+ tree fndecl = node->decl;
+
+ if (TREE_ASM_WRITTEN (fndecl)
+ && pointer_set_contains (candidates, fndecl))
+ {
+ /* Mangle the name in a predictable way; we need to reference
+ this from a java compiled object file. */
+ tree oid, nid, alias;
+ const char *oname;
+ char *nname;
+
+ oid = DECL_ASSEMBLER_NAME (fndecl);
+ oname = IDENTIFIER_POINTER (oid);
+ gcc_assert (oname[0] == '_' && oname[1] == 'Z');
+ nname = ACONCAT (("_ZGA", oname+2, NULL));
+ nid = get_identifier (nname);
+
+ alias = make_alias_for (fndecl, nid);
+ TREE_PUBLIC (alias) = 1;
+ DECL_VISIBILITY (alias) = VISIBILITY_HIDDEN;
+
+ assemble_alias (alias, oid);
+ }
+ }
+}
+
+/* Return C++ property of T, based on given operation OP. */
+
+static int
+cpp_check (tree t, cpp_operation op)
+{
+ switch (op)
+ {
+ case IS_ABSTRACT:
+ return DECL_PURE_VIRTUAL_P (t);
+ case IS_CONSTRUCTOR:
+ return DECL_CONSTRUCTOR_P (t);
+ case IS_DESTRUCTOR:
+ return DECL_DESTRUCTOR_P (t);
+ case IS_COPY_CONSTRUCTOR:
+ return DECL_COPY_CONSTRUCTOR_P (t);
+ case IS_TEMPLATE:
+ return TREE_CODE (t) == TEMPLATE_DECL;
+ case IS_TRIVIAL:
+ return trivial_type_p (t);
+ default:
+ return 0;
+ }
+}
+
+/* Collect source file references recursively, starting from NAMESPC. */
+
+static void
+collect_source_refs (tree namespc)
+{
+ tree t;
+
+ if (!namespc)
+ return;
+
+ /* Iterate over names in this name space. */
+ for (t = NAMESPACE_LEVEL (namespc)->names; t; t = TREE_CHAIN (t))
+ if (!DECL_IS_BUILTIN (t) )
+ collect_source_ref (DECL_SOURCE_FILE (t));
+
+ /* Dump siblings, if any */
+ collect_source_refs (TREE_CHAIN (namespc));
+
+ /* Dump children, if any */
+ collect_source_refs (NAMESPACE_LEVEL (namespc)->namespaces);
+}
+
+/* Collect decls relevant to SOURCE_FILE from all namespaces recursively,
+ starting from NAMESPC. */
+
+static void
+collect_ada_namespace (tree namespc, const char *source_file)
+{
+ if (!namespc)
+ return;
+
+ /* Collect decls from this namespace */
+ collect_ada_nodes (NAMESPACE_LEVEL (namespc)->names, source_file);
+
+ /* Collect siblings, if any */
+ collect_ada_namespace (TREE_CHAIN (namespc), source_file);
+
+ /* Collect children, if any */
+ collect_ada_namespace (NAMESPACE_LEVEL (namespc)->namespaces, source_file);
+}
+
+/* Returns true iff there is a definition available for variable or
+ function DECL. */
+
+static bool
+decl_defined_p (tree decl)
+{
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ return (DECL_INITIAL (decl) != NULL_TREE);
+ else
+ {
+ gcc_assert (VAR_P (decl));
+ return !DECL_EXTERNAL (decl);
+ }
+}
+
+/* Nonzero for a VAR_DECL whose value can be used in a constant expression.
+
+ [expr.const]
+
+ An integral constant-expression can only involve ... const
+ variables of integral or enumeration types initialized with
+ constant expressions ...
+
+ C++0x also allows constexpr variables and temporaries initialized
+ with constant expressions. We handle the former here, but the latter
+ are just folded away in cxx_eval_constant_expression.
+
+ The standard does not require that the expression be non-volatile.
+ G++ implements the proposed correction in DR 457. */
+
+bool
+decl_constant_var_p (tree decl)
+{
+ if (!decl_maybe_constant_var_p (decl))
+ return false;
+
+ /* We don't know if a template static data member is initialized with
+ a constant expression until we instantiate its initializer. Even
+ in the case of a constexpr variable, we can't treat it as a
+ constant until its initializer is complete in case it's used in
+ its own initializer. */
+ mark_used (decl);
+ return DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl);
+}
+
+/* Returns true if DECL could be a symbolic constant variable, depending on
+ its initializer. */
+
+bool
+decl_maybe_constant_var_p (tree decl)
+{
+ tree type = TREE_TYPE (decl);
+ if (!VAR_P (decl))
+ return false;
+ if (DECL_DECLARED_CONSTEXPR_P (decl))
+ return true;
+ return (CP_TYPE_CONST_NON_VOLATILE_P (type)
+ && INTEGRAL_OR_ENUMERATION_TYPE_P (type));
+}
+
+/* Complain that DECL uses a type with no linkage. In C++98 mode this is
+ called from grokfndecl and grokvardecl; in all modes it is called from
+ cp_write_global_declarations. */
+
+void
+no_linkage_error (tree decl)
+{
+ if (cxx_dialect >= cxx11 && decl_defined_p (decl))
+ /* In C++11 it's ok if the decl is defined. */
+ return;
+ tree t = no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false);
+ if (t == NULL_TREE)
+ /* The type that got us on no_linkage_decls must have gotten a name for
+ linkage purposes. */;
+ else if (CLASS_TYPE_P (t) && TYPE_BEING_DEFINED (t))
+ /* The type might end up having a typedef name for linkage purposes. */
+ vec_safe_push (no_linkage_decls, decl);
+ else if (TYPE_ANONYMOUS_P (t))
+ {
+ bool d = false;
+ if (cxx_dialect >= cxx11)
+ d = permerror (DECL_SOURCE_LOCATION (decl), "%q#D, declared using "
+ "anonymous type, is used but never defined", decl);
+ else if (DECL_EXTERN_C_P (decl))
+ /* Allow this; it's pretty common in C. */;
+ else if (TREE_CODE (decl) == VAR_DECL)
+ /* DRs 132, 319 and 389 seem to indicate types with
+ no linkage can only be used to declare extern "C"
+ entities. Since it's not always an error in the
+ ISO C++ 90 Standard, we only issue a warning. */
+ d = warning_at (DECL_SOURCE_LOCATION (decl), 0, "anonymous type "
+ "with no linkage used to declare variable %q#D with "
+ "linkage", decl);
+ else
+ d = permerror (DECL_SOURCE_LOCATION (decl), "anonymous type with no "
+ "linkage used to declare function %q#D with linkage",
+ decl);
+ if (d && is_typedef_decl (TYPE_NAME (t)))
+ inform (DECL_SOURCE_LOCATION (TYPE_NAME (t)), "%q#D does not refer "
+ "to the unqualified type, so it is not used for linkage",
+ TYPE_NAME (t));
+ }
+ else if (cxx_dialect >= cxx11)
+ permerror (DECL_SOURCE_LOCATION (decl), "%q#D, declared using local type "
+ "%qT, is used but never defined", decl, t);
+ else if (TREE_CODE (decl) == VAR_DECL)
+ warning_at (DECL_SOURCE_LOCATION (decl), 0, "type %qT with no linkage "
+ "used to declare variable %q#D with linkage", t, decl);
+ else
+ permerror (DECL_SOURCE_LOCATION (decl), "type %qT with no linkage used "
+ "to declare function %q#D with linkage", t, decl);
+}
+
+/* Collect declarations from all namespaces relevant to SOURCE_FILE. */
+
+static void
+collect_all_refs (const char *source_file)
+{
+ collect_ada_namespace (global_namespace, source_file);
+}
+
+/* Clear DECL_EXTERNAL for NODE. */
+
+static bool
+clear_decl_external (struct cgraph_node *node, void * /*data*/)
+{
+ DECL_EXTERNAL (node->decl) = 0;
+ return false;
+}
+
+/* Build up the function to run dynamic initializers for thread_local
+ variables in this translation unit and alias the init functions for the
+ individual variables to it. */
+
+static void
+handle_tls_init (void)
+{
+ tree vars = prune_vars_needing_no_initialization (&tls_aggregates);
+ if (vars == NULL_TREE)
+ return;
+
+ location_t loc = DECL_SOURCE_LOCATION (TREE_VALUE (vars));
+
+ write_out_vars (vars);
+
+ tree guard = build_decl (loc, VAR_DECL, get_identifier ("__tls_guard"),
+ boolean_type_node);
+ TREE_PUBLIC (guard) = false;
+ TREE_STATIC (guard) = true;
+ DECL_ARTIFICIAL (guard) = true;
+ DECL_IGNORED_P (guard) = true;
+ TREE_USED (guard) = true;
+ DECL_TLS_MODEL (guard) = decl_default_tls_model (guard);
+ pushdecl_top_level_and_finish (guard, NULL_TREE);
+
+ tree fn = get_local_tls_init_fn ();
+ start_preparsed_function (fn, NULL_TREE, SF_PRE_PARSED);
+ tree body = begin_function_body ();
+ tree if_stmt = begin_if_stmt ();
+ tree cond = cp_build_unary_op (TRUTH_NOT_EXPR, guard, false,
+ tf_warning_or_error);
+ finish_if_stmt_cond (cond, if_stmt);
+ finish_expr_stmt (cp_build_modify_expr (guard, NOP_EXPR, boolean_true_node,
+ tf_warning_or_error));
+ for (; vars; vars = TREE_CHAIN (vars))
+ {
+ tree var = TREE_VALUE (vars);
+ tree init = TREE_PURPOSE (vars);
+ one_static_initialization_or_destruction (var, init, true);
+
+#ifdef ASM_OUTPUT_DEF
+ /* Output init aliases even with -fno-extern-tls-init. */
+ if (TREE_PUBLIC (var))
+ {
+ tree single_init_fn = get_tls_init_fn (var);
+ if (single_init_fn == NULL_TREE)
+ continue;
+ cgraph_node *alias
+ = cgraph_same_body_alias (cgraph_get_create_node (fn),
+ single_init_fn, fn);
+ gcc_assert (alias != NULL);
+ }
+#endif
+ }
+
+ finish_then_clause (if_stmt);
+ finish_if_stmt (if_stmt);
+ finish_function_body (body);
+ expand_or_defer_fn (finish_function (0));
+}
+
+/* The entire file is now complete. If requested, dump everything
+ to a file. */
+
+static void
+dump_tu (void)
+{
+ int flags;
+ FILE *stream = dump_begin (TDI_tu, &flags);
+
+ if (stream)
+ {
+ dump_node (global_namespace, flags & ~TDF_SLIM, stream);
+ dump_end (TDI_tu, stream);
+ }
+}
+
+/* This routine is called at the end of compilation.
+ Its job is to create all the code needed to initialize and
+ destroy the global aggregates. We do the destruction
+ first, since that way we only need to reverse the decls once. */
+
+void
+cp_write_global_declarations (void)
+{
+ tree vars;
+ bool reconsider;
+ size_t i;
+ location_t locus;
+ unsigned ssdf_count = 0;
+ int retries = 0;
+ tree decl;
+ struct pointer_set_t *candidates;
+
+ locus = input_location;
+ at_eof = 1;
+
+ /* Bad parse errors. Just forget about it. */
+ if (! global_bindings_p () || current_class_type
+ || !vec_safe_is_empty (decl_namespace_list))
+ return;
+
+ /* This is the point to write out a PCH if we're doing that.
+ In that case we do not want to do anything else. */
+ if (pch_file)
+ {
+ c_common_write_pch ();
+ dump_tu ();
+ return;
+ }
+
+ cgraph_process_same_body_aliases ();
+
+ /* Handle -fdump-ada-spec[-slim] */
+ if (flag_dump_ada_spec || flag_dump_ada_spec_slim)
+ {
+ if (flag_dump_ada_spec_slim)
+ collect_source_ref (main_input_filename);
+ else
+ collect_source_refs (global_namespace);
+
+ dump_ada_specs (collect_all_refs, cpp_check);
+ }
+
+ /* FIXME - huh? was input_line -= 1;*/
+
+ timevar_start (TV_PHASE_DEFERRED);
+
+ /* We now have to write out all the stuff we put off writing out.
+ These include:
+
+ o Template specializations that we have not yet instantiated,
+ but which are needed.
+ o Initialization and destruction for non-local objects with
+ static storage duration. (Local objects with static storage
+ duration are initialized when their scope is first entered,
+ and are cleaned up via atexit.)
+ o Virtual function tables.
+
+ All of these may cause others to be needed. For example,
+ instantiating one function may cause another to be needed, and
+ generating the initializer for an object may cause templates to be
+ instantiated, etc., etc. */
+
+ emit_support_tinfos ();
+
+ do
+ {
+ tree t;
+ tree decl;
+
+ reconsider = false;
+
+ /* If there are templates that we've put off instantiating, do
+ them now. */
+ instantiate_pending_templates (retries);
+ ggc_collect ();
+
+ /* Write out virtual tables as required. Note that writing out
+ the virtual table for a template class may cause the
+ instantiation of members of that class. If we write out
+ vtables then we remove the class from our list so we don't
+ have to look at it again. */
+
+ while (keyed_classes != NULL_TREE
+ && maybe_emit_vtables (TREE_VALUE (keyed_classes)))
+ {
+ reconsider = true;
+ keyed_classes = TREE_CHAIN (keyed_classes);
+ }
+
+ t = keyed_classes;
+ if (t != NULL_TREE)
+ {
+ tree next = TREE_CHAIN (t);
+
+ while (next)
+ {
+ if (maybe_emit_vtables (TREE_VALUE (next)))
+ {
+ reconsider = true;
+ TREE_CHAIN (t) = TREE_CHAIN (next);
+ }
+ else
+ t = next;
+
+ next = TREE_CHAIN (t);
+ }
+ }
+
+ /* Write out needed type info variables. We have to be careful
+ looping through unemitted decls, because emit_tinfo_decl may
+ cause other variables to be needed. New elements will be
+ appended, and we remove from the vector those that actually
+ get emitted. */
+ for (i = unemitted_tinfo_decls->length ();
+ unemitted_tinfo_decls->iterate (--i, &t);)
+ if (emit_tinfo_decl (t))
+ {
+ reconsider = true;
+ unemitted_tinfo_decls->unordered_remove (i);
+ }
+
+ /* The list of objects with static storage duration is built up
+ in reverse order. We clear STATIC_AGGREGATES so that any new
+ aggregates added during the initialization of these will be
+ initialized in the correct order when we next come around the
+ loop. */
+ vars = prune_vars_needing_no_initialization (&static_aggregates);
+
+ if (vars)
+ {
+ /* We need to start a new initialization function each time
+ through the loop. That's because we need to know which
+ vtables have been referenced, and TREE_SYMBOL_REFERENCED
+ isn't computed until a function is finished, and written
+ out. That's a deficiency in the back end. When this is
+ fixed, these initialization functions could all become
+ inline, with resulting performance improvements. */
+ tree ssdf_body;
+
+ /* Set the line and file, so that it is obviously not from
+ the source file. */
+ input_location = locus;
+ ssdf_body = start_static_storage_duration_function (ssdf_count);
+
+ /* Make sure the back end knows about all the variables. */
+ write_out_vars (vars);
+
+ /* First generate code to do all the initializations. */
+ if (vars)
+ do_static_initialization_or_destruction (vars, /*initp=*/true);
+
+ /* Then, generate code to do all the destructions. Do these
+ in reverse order so that the most recently constructed
+ variable is the first destroyed. If we're using
+ __cxa_atexit, then we don't need to do this; functions
+ were registered at initialization time to destroy the
+ local statics. */
+ if (!flag_use_cxa_atexit && vars)
+ {
+ vars = nreverse (vars);
+ do_static_initialization_or_destruction (vars, /*initp=*/false);
+ }
+ else
+ vars = NULL_TREE;
+
+ /* Finish up the static storage duration function for this
+ round. */
+ input_location = locus;
+ finish_static_storage_duration_function (ssdf_body);
+
+ /* All those initializations and finalizations might cause
+ us to need more inline functions, more template
+ instantiations, etc. */
+ reconsider = true;
+ ssdf_count++;
+ /* ??? was: locus.line++; */
+ }
+
+ /* Now do the same for thread_local variables. */
+ handle_tls_init ();
+
+ /* Go through the set of inline functions whose bodies have not
+ been emitted yet. If out-of-line copies of these functions
+ are required, emit them. */
+ FOR_EACH_VEC_SAFE_ELT (deferred_fns, i, decl)
+ {
+ /* Does it need synthesizing? */
+ if (DECL_DEFAULTED_FN (decl) && ! DECL_INITIAL (decl)
+ && (! DECL_REALLY_EXTERN (decl) || possibly_inlined_p (decl)))
+ {
+ /* Even though we're already at the top-level, we push
+ there again. That way, when we pop back a few lines
+ hence, all of our state is restored. Otherwise,
+ finish_function doesn't clean things up, and we end
+ up with CURRENT_FUNCTION_DECL set. */
+ push_to_top_level ();
+ /* The decl's location will mark where it was first
+ needed. Save that so synthesize method can indicate
+ where it was needed from, in case of error */
+ input_location = DECL_SOURCE_LOCATION (decl);
+ synthesize_method (decl);
+ pop_from_top_level ();
+ reconsider = true;
+ }
+
+ if (!DECL_INITIAL (decl) && decl_tls_wrapper_p (decl))
+ generate_tls_wrapper (decl);
+
+ if (!DECL_SAVED_TREE (decl))
+ continue;
+
+ /* We lie to the back end, pretending that some functions
+ are not defined when they really are. This keeps these
+ functions from being put out unnecessarily. But, we must
+ stop lying when the functions are referenced, or if they
+ are not comdat since they need to be put out now. If
+ DECL_INTERFACE_KNOWN, then we have already set
+ DECL_EXTERNAL appropriately, so there's no need to check
+ again, and we do not want to clear DECL_EXTERNAL if a
+ previous call to import_export_decl set it.
+
+ This is done in a separate for cycle, because if some
+ deferred function is contained in another deferred
+ function later in deferred_fns varray,
+ rest_of_compilation would skip this function and we
+ really cannot expand the same function twice. */
+ import_export_decl (decl);
+ if (DECL_NOT_REALLY_EXTERN (decl)
+ && DECL_INITIAL (decl)
+ && decl_needed_p (decl))
+ {
+ struct cgraph_node *node, *next;
+
+ node = cgraph_get_node (decl);
+ if (node->cpp_implicit_alias)
+ node = cgraph_alias_target (node);
+
+ cgraph_for_node_and_aliases (node, clear_decl_external,
+ NULL, true);
+ /* If we mark !DECL_EXTERNAL one of the symbols in some comdat
+ group, we need to mark all symbols in the same comdat group
+ that way. */
+ if (node->same_comdat_group)
+ for (next = cgraph (node->same_comdat_group);
+ next != node;
+ next = cgraph (next->same_comdat_group))
+ cgraph_for_node_and_aliases (next, clear_decl_external,
+ NULL, true);
+ }
+
+ /* If we're going to need to write this function out, and
+ there's already a body for it, create RTL for it now.
+ (There might be no body if this is a method we haven't
+ gotten around to synthesizing yet.) */
+ if (!DECL_EXTERNAL (decl)
+ && decl_needed_p (decl)
+ && !TREE_ASM_WRITTEN (decl)
+ && !cgraph_get_node (decl)->definition)
+ {
+ /* We will output the function; no longer consider it in this
+ loop. */
+ DECL_DEFER_OUTPUT (decl) = 0;
+ /* Generate RTL for this function now that we know we
+ need it. */
+ expand_or_defer_fn (decl);
+ /* If we're compiling -fsyntax-only pretend that this
+ function has been written out so that we don't try to
+ expand it again. */
+ if (flag_syntax_only)
+ TREE_ASM_WRITTEN (decl) = 1;
+ reconsider = true;
+ }
+ }
+
+ if (walk_namespaces (wrapup_globals_for_namespace, /*data=*/0))
+ reconsider = true;
+
+ /* Static data members are just like namespace-scope globals. */
+ FOR_EACH_VEC_SAFE_ELT (pending_statics, i, decl)
+ {
+ if (var_finalized_p (decl) || DECL_REALLY_EXTERN (decl)
+ /* Don't write it out if we haven't seen a definition. */
+ || DECL_IN_AGGR_P (decl))
+ continue;
+ import_export_decl (decl);
+ /* If this static data member is needed, provide it to the
+ back end. */
+ if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl))
+ DECL_EXTERNAL (decl) = 0;
+ }
+ if (vec_safe_length (pending_statics) != 0
+ && wrapup_global_declarations (pending_statics->address (),
+ pending_statics->length ()))
+ reconsider = true;
+
+ retries++;
+ }
+ while (reconsider);
+
+ /* All used inline functions must have a definition at this point. */
+ FOR_EACH_VEC_SAFE_ELT (deferred_fns, i, decl)
+ {
+ if (/* Check online inline functions that were actually used. */
+ DECL_ODR_USED (decl) && DECL_DECLARED_INLINE_P (decl)
+ /* If the definition actually was available here, then the
+ fact that the function was not defined merely represents
+ that for some reason (use of a template repository,
+ #pragma interface, etc.) we decided not to emit the
+ definition here. */
+ && !DECL_INITIAL (decl)
+ /* Don't complain if the template was defined. */
+ && !(DECL_TEMPLATE_INSTANTIATION (decl)
+ && DECL_INITIAL (DECL_TEMPLATE_RESULT
+ (template_for_substitution (decl)))))
+ {
+ warning (0, "inline function %q+D used but never defined", decl);
+ /* Avoid a duplicate warning from check_global_declaration_1. */
+ TREE_NO_WARNING (decl) = 1;
+ }
+ }
+
+ /* So must decls that use a type with no linkage. */
+ FOR_EACH_VEC_SAFE_ELT (no_linkage_decls, i, decl)
+ no_linkage_error (decl);
+
+ /* Then, do the Objective-C stuff. This is where all the
+ Objective-C module stuff gets generated (symtab,
+ class/protocol/selector lists etc). This must be done after C++
+ templates, destructors etc. so that selectors used in C++
+ templates are properly allocated. */
+ if (c_dialect_objc ())
+ objc_write_global_declarations ();
+
+ /* We give C linkage to static constructors and destructors. */
+ push_lang_context (lang_name_c);
+
+ /* Generate initialization and destruction functions for all
+ priorities for which they are required. */
+ if (priority_info_map)
+ splay_tree_foreach (priority_info_map,
+ generate_ctor_and_dtor_functions_for_priority,
+ /*data=*/&locus);
+ else if (c_dialect_objc () && objc_static_init_needed_p ())
+ /* If this is obj-c++ and we need a static init, call
+ generate_ctor_or_dtor_function. */
+ generate_ctor_or_dtor_function (/*constructor_p=*/true,
+ DEFAULT_INIT_PRIORITY, &locus);
+
+ /* We're done with the splay-tree now. */
+ if (priority_info_map)
+ splay_tree_delete (priority_info_map);
+
+ /* Generate any missing aliases. */
+ maybe_apply_pending_pragma_weaks ();
+
+ /* We're done with static constructors, so we can go back to "C++"
+ linkage now. */
+ pop_lang_context ();
+
+ /* Collect candidates for Java hidden aliases. */
+ candidates = collect_candidates_for_java_method_aliases ();
+
+ timevar_stop (TV_PHASE_DEFERRED);
+ timevar_start (TV_PHASE_OPT_GEN);
+
+ if (flag_vtable_verify)
+ {
+ vtv_recover_class_info ();
+ vtv_compute_class_hierarchy_transitive_closure ();
+ vtv_build_vtable_verify_fndecl ();
+ }
+
+ finalize_compilation_unit ();
+
+ if (flag_vtable_verify)
+ {
+ /* Generate the special constructor initialization function that
+ calls __VLTRegisterPairs, and give it a very high
+ initialization priority. This must be done after
+ finalize_compilation_unit so that we have accurate
+ information about which vtable will actually be emitted. */
+ vtv_generate_init_routine ();
+ }
+
+ timevar_stop (TV_PHASE_OPT_GEN);
+ timevar_start (TV_PHASE_CHECK_DBGINFO);
+
+ /* Now, issue warnings about static, but not defined, functions,
+ etc., and emit debugging information. */
+ walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider);
+ if (vec_safe_length (pending_statics) != 0)
+ {
+ check_global_declarations (pending_statics->address (),
+ pending_statics->length ());
+ emit_debug_global_declarations (pending_statics->address (),
+ pending_statics->length ());
+ }
+
+ perform_deferred_noexcept_checks ();
+
+ /* Generate hidden aliases for Java. */
+ if (candidates)
+ {
+ build_java_method_aliases (candidates);
+ pointer_set_destroy (candidates);
+ }
+
+ finish_repo ();
+
+ /* The entire file is now complete. If requested, dump everything
+ to a file. */
+ dump_tu ();
+
+ if (flag_detailed_statistics)
+ {
+ dump_tree_statistics ();
+ dump_time_statistics ();
+ }
+ input_location = locus;
+
+#ifdef ENABLE_CHECKING
+ validate_conversion_obstack ();
+#endif /* ENABLE_CHECKING */
+
+ timevar_stop (TV_PHASE_CHECK_DBGINFO);
+}
+
+/* FN is an OFFSET_REF, DOTSTAR_EXPR or MEMBER_REF indicating the
+ function to call in parse-tree form; it has not yet been
+ semantically analyzed. ARGS are the arguments to the function.
+ They have already been semantically analyzed. This may change
+ ARGS. */
+
+tree
+build_offset_ref_call_from_tree (tree fn, vec<tree, va_gc> **args,
+ tsubst_flags_t complain)
+{
+ tree orig_fn;
+ vec<tree, va_gc> *orig_args = NULL;
+ tree expr;
+ tree object;
+
+ orig_fn = fn;
+ object = TREE_OPERAND (fn, 0);
+
+ if (processing_template_decl)
+ {
+ gcc_assert (TREE_CODE (fn) == DOTSTAR_EXPR
+ || TREE_CODE (fn) == MEMBER_REF);
+ if (type_dependent_expression_p (fn)
+ || any_type_dependent_arguments_p (*args))
+ return build_nt_call_vec (fn, *args);
+
+ orig_args = make_tree_vector_copy (*args);
+
+ /* Transform the arguments and add the implicit "this"
+ parameter. That must be done before the FN is transformed
+ because we depend on the form of FN. */
+ make_args_non_dependent (*args);
+ object = build_non_dependent_expr (object);
+ if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+ {
+ if (TREE_CODE (fn) == DOTSTAR_EXPR)
+ object = cp_build_addr_expr (object, complain);
+ vec_safe_insert (*args, 0, object);
+ }
+ /* Now that the arguments are done, transform FN. */
+ fn = build_non_dependent_expr (fn);
+ }
+
+ /* A qualified name corresponding to a bound pointer-to-member is
+ represented as an OFFSET_REF:
+
+ struct B { void g(); };
+ void (B::*p)();
+ void B::g() { (this->*p)(); } */
+ if (TREE_CODE (fn) == OFFSET_REF)
+ {
+ tree object_addr = cp_build_addr_expr (object, complain);
+ fn = TREE_OPERAND (fn, 1);
+ fn = get_member_function_from_ptrfunc (&object_addr, fn,
+ complain);
+ vec_safe_insert (*args, 0, object_addr);
+ }
+
+ if (CLASS_TYPE_P (TREE_TYPE (fn)))
+ expr = build_op_call (fn, args, complain);
+ else
+ expr = cp_build_function_call_vec (fn, args, complain);
+ if (processing_template_decl && expr != error_mark_node)
+ expr = build_min_non_dep_call_vec (expr, orig_fn, orig_args);
+
+ if (orig_args != NULL)
+ release_tree_vector (orig_args);
+
+ return expr;
+}
+
+
+void
+check_default_args (tree x)
+{
+ tree arg = TYPE_ARG_TYPES (TREE_TYPE (x));
+ bool saw_def = false;
+ int i = 0 - (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE);
+ for (; arg && arg != void_list_node; arg = TREE_CHAIN (arg), ++i)
+ {
+ if (TREE_PURPOSE (arg))
+ saw_def = true;
+ else if (saw_def && !PACK_EXPANSION_P (TREE_VALUE (arg)))
+ {
+ error ("default argument missing for parameter %P of %q+#D", i, x);
+ TREE_PURPOSE (arg) = error_mark_node;
+ }
+ }
+}
+
+/* Return true if function DECL can be inlined. This is used to force
+ instantiation of methods that might be interesting for inlining. */
+bool
+possibly_inlined_p (tree decl)
+{
+ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+ if (DECL_UNINLINABLE (decl))
+ return false;
+ if (!optimize || pragma_java_exceptions)
+ return DECL_DECLARED_INLINE_P (decl);
+ /* When optimizing, we might inline everything when flatten
+ attribute or heuristics inlining for size or autoinlining
+ is used. */
+ return true;
+}
+
+/* Mark DECL (either a _DECL or a BASELINK) as "used" in the program.
+ If DECL is a specialization or implicitly declared class member,
+ generate the actual definition. Return false if something goes
+ wrong, true otherwise. */
+
+bool
+mark_used (tree decl, tsubst_flags_t complain)
+{
+ /* If DECL is a BASELINK for a single function, then treat it just
+ like the DECL for the function. Otherwise, if the BASELINK is
+ for an overloaded function, we don't know which function was
+ actually used until after overload resolution. */
+ if (BASELINK_P (decl))
+ {
+ decl = BASELINK_FUNCTIONS (decl);
+ if (really_overloaded_fn (decl))
+ return true;
+ decl = OVL_CURRENT (decl);
+ }
+
+ /* Set TREE_USED for the benefit of -Wunused. */
+ TREE_USED (decl) = 1;
+ if (DECL_CLONED_FUNCTION_P (decl))
+ TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1;
+
+ /* Mark enumeration types as used. */
+ if (TREE_CODE (decl) == CONST_DECL)
+ used_types_insert (DECL_CONTEXT (decl));
+
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DELETED_FN (decl))
+ {
+ if (DECL_ARTIFICIAL (decl))
+ {
+ if (DECL_OVERLOADED_OPERATOR_P (decl) == TYPE_EXPR
+ && LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
+ {
+ /* We mark a lambda conversion op as deleted if we can't
+ generate it properly; see maybe_add_lambda_conv_op. */
+ sorry ("converting lambda which uses %<...%> to "
+ "function pointer");
+ return false;
+ }
+ }
+ if (complain & tf_error)
+ {
+ error ("use of deleted function %qD", decl);
+ if (!maybe_explain_implicit_delete (decl))
+ inform (DECL_SOURCE_LOCATION (decl), "declared here");
+ }
+ return false;
+ }
+
+ /* We can only check DECL_ODR_USED on variables or functions with
+ DECL_LANG_SPECIFIC set, and these are also the only decls that we
+ might need special handling for. */
+ if (!VAR_OR_FUNCTION_DECL_P (decl)
+ || DECL_LANG_SPECIFIC (decl) == NULL
+ || DECL_THUNK_P (decl))
+ {
+ if (!processing_template_decl && type_uses_auto (TREE_TYPE (decl)))
+ {
+ if (complain & tf_error)
+ error ("use of %qD before deduction of %<auto%>", decl);
+ return false;
+ }
+ return true;
+ }
+
+ /* We only want to do this processing once. We don't need to keep trying
+ to instantiate inline templates, because unit-at-a-time will make sure
+ we get them compiled before functions that want to inline them. */
+ if (DECL_ODR_USED (decl))
+ return true;
+
+ /* If within finish_function, defer the rest until that function
+ finishes, otherwise it might recurse. */
+ if (defer_mark_used_calls)
+ {
+ vec_safe_push (deferred_mark_used_calls, decl);
+ return true;
+ }
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ maybe_instantiate_noexcept (decl);
+
+ /* Normally, we can wait until instantiation-time to synthesize DECL.
+ However, if DECL is a static data member initialized with a constant
+ or a constexpr function, we need it right now because a reference to
+ such a data member or a call to such function is not value-dependent.
+ For a function that uses auto in the return type, we need to instantiate
+ it to find out its type. For OpenMP user defined reductions, we need
+ them instantiated for reduction clauses which inline them by hand
+ directly. */
+ if (DECL_LANG_SPECIFIC (decl)
+ && DECL_TEMPLATE_INFO (decl)
+ && (decl_maybe_constant_var_p (decl)
+ || (TREE_CODE (decl) == FUNCTION_DECL
+ && (DECL_DECLARED_CONSTEXPR_P (decl)
+ || DECL_OMP_DECLARE_REDUCTION_P (decl)))
+ || undeduced_auto_decl (decl))
+ && !uses_template_parms (DECL_TI_ARGS (decl)))
+ {
+ /* Instantiating a function will result in garbage collection. We
+ must treat this situation as if we were within the body of a
+ function so as to avoid collecting live data only referenced from
+ the stack (such as overload resolution candidates). */
+ ++function_depth;
+ instantiate_decl (decl, /*defer_ok=*/false,
+ /*expl_inst_class_mem_p=*/false);
+ --function_depth;
+ }
+
+ if (processing_template_decl)
+ return true;
+
+ /* Check this too in case we're within fold_non_dependent_expr. */
+ if (DECL_TEMPLATE_INFO (decl)
+ && uses_template_parms (DECL_TI_ARGS (decl)))
+ return true;
+
+ require_deduced_type (decl);
+
+ /* If we don't need a value, then we don't need to synthesize DECL. */
+ if (cp_unevaluated_operand != 0)
+ return true;
+
+ DECL_ODR_USED (decl) = 1;
+ if (DECL_CLONED_FUNCTION_P (decl))
+ DECL_ODR_USED (DECL_CLONED_FUNCTION (decl)) = 1;
+
+ /* DR 757: A type without linkage shall not be used as the type of a
+ variable or function with linkage, unless
+ o the variable or function has extern "C" linkage (7.5 [dcl.link]), or
+ o the variable or function is not used (3.2 [basic.def.odr]) or is
+ defined in the same translation unit. */
+ if (cxx_dialect > cxx98
+ && decl_linkage (decl) != lk_none
+ && !DECL_EXTERN_C_P (decl)
+ && !DECL_ARTIFICIAL (decl)
+ && !decl_defined_p (decl)
+ && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false))
+ {
+ if (is_local_extern (decl))
+ /* There's no way to define a local extern, and adding it to
+ the vector interferes with GC, so give an error now. */
+ no_linkage_error (decl);
+ else
+ vec_safe_push (no_linkage_decls, decl);
+ }
+
+ if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)
+ && !DECL_INITIAL (decl) && !DECL_ARTIFICIAL (decl))
+ /* Remember it, so we can check it was defined. */
+ note_vague_linkage_fn (decl);
+
+ /* Is it a synthesized method that needs to be synthesized? */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
+ && DECL_DEFAULTED_FN (decl)
+ /* A function defaulted outside the class is synthesized either by
+ cp_finish_decl or instantiate_decl. */
+ && !DECL_DEFAULTED_OUTSIDE_CLASS_P (decl)
+ && ! DECL_INITIAL (decl))
+ {
+ /* Defer virtual destructors so that thunks get the right
+ linkage. */
+ if (DECL_VIRTUAL_P (decl) && !at_eof)
+ {
+ note_vague_linkage_fn (decl);
+ return true;
+ }
+
+ /* Remember the current location for a function we will end up
+ synthesizing. Then we can inform the user where it was
+ required in the case of error. */
+ DECL_SOURCE_LOCATION (decl) = input_location;
+
+ /* Synthesizing an implicitly defined member function will result in
+ garbage collection. We must treat this situation as if we were
+ within the body of a function so as to avoid collecting live data
+ on the stack (such as overload resolution candidates).
+
+ We could just let cp_write_global_declarations handle synthesizing
+ this function by adding it to deferred_fns, but doing
+ it at the use site produces better error messages. */
+ ++function_depth;
+ synthesize_method (decl);
+ --function_depth;
+ /* If this is a synthesized method we don't need to
+ do the instantiation test below. */
+ }
+ else if (VAR_OR_FUNCTION_DECL_P (decl)
+ && DECL_TEMPLATE_INFO (decl)
+ && (!DECL_EXPLICIT_INSTANTIATION (decl)
+ || always_instantiate_p (decl)))
+ /* If this is a function or variable that is an instance of some
+ template, we now know that we will need to actually do the
+ instantiation. We check that DECL is not an explicit
+ instantiation because that is not checked in instantiate_decl.
+
+ We put off instantiating functions in order to improve compile
+ times. Maintaining a stack of active functions is expensive,
+ and the inliner knows to instantiate any functions it might
+ need. Therefore, we always try to defer instantiation. */
+ {
+ ++function_depth;
+ instantiate_decl (decl, /*defer_ok=*/true,
+ /*expl_inst_class_mem_p=*/false);
+ --function_depth;
+ }
+
+ return true;
+}
+
+bool
+mark_used (tree decl)
+{
+ return mark_used (decl, tf_warning_or_error);
+}
+
+tree
+vtv_start_verification_constructor_init_function (void)
+{
+ return start_objects ('I', MAX_RESERVED_INIT_PRIORITY - 1);
+}
+
+tree
+vtv_finish_verification_constructor_init_function (tree function_body)
+{
+ tree fn;
+
+ finish_compound_stmt (function_body);
+ fn = finish_function (0);
+ DECL_STATIC_CONSTRUCTOR (fn) = 1;
+ decl_init_priority_insert (fn, MAX_RESERVED_INIT_PRIORITY - 1);
+
+ return fn;
+}
+
+#include "gt-cp-decl2.h"
diff --git a/gcc-4.9/gcc/cp/dump.c b/gcc-4.9/gcc/cp/dump.c
new file mode 100644
index 000000000..70b047a90
--- /dev/null
+++ b/gcc-4.9/gcc/cp/dump.c
@@ -0,0 +1,498 @@
+/* Tree-dumping functionality for intermediate representation.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Written by Mark Mitchell <mark@codesourcery.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "cp-tree.h"
+#include "tree-dump.h"
+
+static void dump_access (dump_info_p, tree);
+
+static void dump_op (dump_info_p, tree);
+
+/* Dump a representation of the accessibility information associated
+ with T. */
+
+static void
+dump_access (dump_info_p di, tree t)
+{
+ if (TREE_PROTECTED(t))
+ dump_string_field (di, "accs", "prot");
+ else if (TREE_PRIVATE(t))
+ dump_string_field (di, "accs", "priv");
+ else
+ dump_string_field (di, "accs", "pub");
+}
+
+/* Dump a representation of the specific operator for an overloaded
+ operator associated with node t. */
+
+static void
+dump_op (dump_info_p di, tree t)
+{
+ switch (DECL_OVERLOADED_OPERATOR_P (t)) {
+ case NEW_EXPR:
+ dump_string (di, "new");
+ break;
+ case VEC_NEW_EXPR:
+ dump_string (di, "vecnew");
+ break;
+ case DELETE_EXPR:
+ dump_string (di, "delete");
+ break;
+ case VEC_DELETE_EXPR:
+ dump_string (di, "vecdelete");
+ break;
+ case UNARY_PLUS_EXPR:
+ dump_string (di, "pos");
+ break;
+ case NEGATE_EXPR:
+ dump_string (di, "neg");
+ break;
+ case ADDR_EXPR:
+ dump_string (di, "addr");
+ break;
+ case INDIRECT_REF:
+ dump_string(di, "deref");
+ break;
+ case BIT_NOT_EXPR:
+ dump_string(di, "not");
+ break;
+ case TRUTH_NOT_EXPR:
+ dump_string(di, "lnot");
+ break;
+ case PREINCREMENT_EXPR:
+ dump_string(di, "preinc");
+ break;
+ case PREDECREMENT_EXPR:
+ dump_string(di, "predec");
+ break;
+ case PLUS_EXPR:
+ if (DECL_ASSIGNMENT_OPERATOR_P (t))
+ dump_string (di, "plusassign");
+ else
+ dump_string(di, "plus");
+ break;
+ case MINUS_EXPR:
+ if (DECL_ASSIGNMENT_OPERATOR_P (t))
+ dump_string (di, "minusassign");
+ else
+ dump_string(di, "minus");
+ break;
+ case MULT_EXPR:
+ if (DECL_ASSIGNMENT_OPERATOR_P (t))
+ dump_string (di, "multassign");
+ else
+ dump_string (di, "mult");
+ break;
+ case TRUNC_DIV_EXPR:
+ if (DECL_ASSIGNMENT_OPERATOR_P (t))
+ dump_string (di, "divassign");
+ else
+ dump_string (di, "div");
+ break;
+ case TRUNC_MOD_EXPR:
+ if (DECL_ASSIGNMENT_OPERATOR_P (t))
+ dump_string (di, "modassign");
+ else
+ dump_string (di, "mod");
+ break;
+ case BIT_AND_EXPR:
+ if (DECL_ASSIGNMENT_OPERATOR_P (t))
+ dump_string (di, "andassign");
+ else
+ dump_string (di, "and");
+ break;
+ case BIT_IOR_EXPR:
+ if (DECL_ASSIGNMENT_OPERATOR_P (t))
+ dump_string (di, "orassign");
+ else
+ dump_string (di, "or");
+ break;
+ case BIT_XOR_EXPR:
+ if (DECL_ASSIGNMENT_OPERATOR_P (t))
+ dump_string (di, "xorassign");
+ else
+ dump_string (di, "xor");
+ break;
+ case LSHIFT_EXPR:
+ if (DECL_ASSIGNMENT_OPERATOR_P (t))
+ dump_string (di, "lshiftassign");
+ else
+ dump_string (di, "lshift");
+ break;
+ case RSHIFT_EXPR:
+ if (DECL_ASSIGNMENT_OPERATOR_P (t))
+ dump_string (di, "rshiftassign");
+ else
+ dump_string (di, "rshift");
+ break;
+ case EQ_EXPR:
+ dump_string (di, "eq");
+ break;
+ case NE_EXPR:
+ dump_string (di, "ne");
+ break;
+ case LT_EXPR:
+ dump_string (di, "lt");
+ break;
+ case GT_EXPR:
+ dump_string (di, "gt");
+ break;
+ case LE_EXPR:
+ dump_string (di, "le");
+ break;
+ case GE_EXPR:
+ dump_string (di, "ge");
+ break;
+ case TRUTH_ANDIF_EXPR:
+ dump_string (di, "land");
+ break;
+ case TRUTH_ORIF_EXPR:
+ dump_string (di, "lor");
+ break;
+ case COMPOUND_EXPR:
+ dump_string (di, "compound");
+ break;
+ case MEMBER_REF:
+ dump_string (di, "memref");
+ break;
+ case COMPONENT_REF:
+ dump_string (di, "ref");
+ break;
+ case ARRAY_REF:
+ dump_string (di, "subs");
+ break;
+ case POSTINCREMENT_EXPR:
+ dump_string (di, "postinc");
+ break;
+ case POSTDECREMENT_EXPR:
+ dump_string (di, "postdec");
+ break;
+ case CALL_EXPR:
+ dump_string (di, "call");
+ break;
+ case NOP_EXPR:
+ if (DECL_ASSIGNMENT_OPERATOR_P (t))
+ dump_string (di, "assign");
+ break;
+ default:
+ break;
+ }
+}
+
+/* Dump information common to statements from STMT. */
+
+static void
+dump_stmt (dump_info_p di, const_tree t)
+{
+ if (EXPR_HAS_LOCATION (t))
+ dump_int (di, "line", EXPR_LINENO (t));
+}
+
+bool
+cp_dump_tree (void* dump_info, tree t)
+{
+ enum tree_code code;
+ dump_info_p di = (dump_info_p) dump_info;
+
+ /* Figure out what kind of node this is. */
+ code = TREE_CODE (t);
+
+ if (DECL_P (t))
+ {
+ if (DECL_LANG_SPECIFIC (t) && DECL_LANGUAGE (t) != lang_cplusplus)
+ dump_string_field (di, "lang", language_to_string (DECL_LANGUAGE (t)));
+ }
+
+ switch (code)
+ {
+ case IDENTIFIER_NODE:
+ if (IDENTIFIER_OPNAME_P (t))
+ {
+ dump_string_field (di, "note", "operator");
+ return true;
+ }
+ else if (IDENTIFIER_TYPENAME_P (t))
+ {
+ dump_child ("tynm", TREE_TYPE (t));
+ return true;
+ }
+ break;
+
+ case OFFSET_TYPE:
+ dump_string_field (di, "note", "ptrmem");
+ dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
+ dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
+ return true;
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ {
+ dump_string_field (di, "note", "ptrmem");
+ dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
+ dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
+ return true;
+ }
+ /* Fall through. */
+
+ case UNION_TYPE:
+ /* Is it a type used as a base? */
+ if (TYPE_CONTEXT (t) && TREE_CODE (TYPE_CONTEXT (t)) == TREE_CODE (t)
+ && CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t)
+ {
+ dump_child ("bfld", TYPE_CONTEXT (t));
+ return true;
+ }
+
+ if (! MAYBE_CLASS_TYPE_P (t))
+ break;
+
+ dump_child ("vfld", TYPE_VFIELD (t));
+ if (CLASSTYPE_TEMPLATE_SPECIALIZATION(t))
+ dump_string(di, "spec");
+
+ if (!dump_flag (di, TDF_SLIM, t) && TYPE_BINFO (t))
+ {
+ int i;
+ tree binfo;
+ tree base_binfo;
+
+ for (binfo = TYPE_BINFO (t), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ {
+ dump_child ("base", BINFO_TYPE (base_binfo));
+ if (BINFO_VIRTUAL_P (base_binfo))
+ dump_string_field (di, "spec", "virt");
+ dump_access (di, base_binfo);
+ }
+ }
+ break;
+
+ case FIELD_DECL:
+ dump_access (di, t);
+ if (DECL_MUTABLE_P (t))
+ dump_string_field (di, "spec", "mutable");
+ break;
+
+ case VAR_DECL:
+ if (TREE_CODE (CP_DECL_CONTEXT (t)) == RECORD_TYPE)
+ dump_access (di, t);
+ if (TREE_STATIC (t) && !TREE_PUBLIC (t))
+ dump_string_field (di, "link", "static");
+ break;
+
+ case FUNCTION_DECL:
+ if (!DECL_THUNK_P (t))
+ {
+ if (DECL_OVERLOADED_OPERATOR_P (t)) {
+ dump_string_field (di, "note", "operator");
+ dump_op (di, t);
+ }
+ if (DECL_FUNCTION_MEMBER_P (t))
+ {
+ dump_string_field (di, "note", "member");
+ dump_access (di, t);
+ }
+ if (DECL_PURE_VIRTUAL_P (t))
+ dump_string_field (di, "spec", "pure");
+ if (DECL_VIRTUAL_P (t))
+ dump_string_field (di, "spec", "virt");
+ if (DECL_CONSTRUCTOR_P (t))
+ dump_string_field (di, "note", "constructor");
+ if (DECL_DESTRUCTOR_P (t))
+ dump_string_field (di, "note", "destructor");
+ if (DECL_CONV_FN_P (t))
+ dump_string_field (di, "note", "conversion");
+ if (DECL_GLOBAL_CTOR_P (t))
+ dump_string_field (di, "note", "global init");
+ if (DECL_GLOBAL_DTOR_P (t))
+ dump_string_field (di, "note", "global fini");
+ if (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t))
+ dump_string_field (di, "note", "pseudo tmpl");
+ }
+ else
+ {
+ tree virt = THUNK_VIRTUAL_OFFSET (t);
+
+ dump_string_field (di, "note", "thunk");
+ if (DECL_THIS_THUNK_P (t))
+ dump_string_field (di, "note", "this adjusting");
+ else
+ {
+ dump_string_field (di, "note", "result adjusting");
+ if (virt)
+ virt = BINFO_VPTR_FIELD (virt);
+ }
+ dump_int (di, "fixd", THUNK_FIXED_OFFSET (t));
+ if (virt)
+ dump_int (di, "virt", tree_to_shwi (virt));
+ dump_child ("fn", DECL_INITIAL (t));
+ }
+ break;
+
+ case NAMESPACE_DECL:
+ if (DECL_NAMESPACE_ALIAS (t))
+ dump_child ("alis", DECL_NAMESPACE_ALIAS (t));
+ else if (!dump_flag (di, TDF_SLIM, t))
+ dump_child ("dcls", cp_namespace_decls (t));
+ break;
+
+ case TEMPLATE_DECL:
+ dump_child ("rslt", DECL_TEMPLATE_RESULT (t));
+ dump_child ("inst", DECL_TEMPLATE_INSTANTIATIONS (t));
+ dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
+ dump_child ("prms", DECL_TEMPLATE_PARMS (t));
+ break;
+
+ case OVERLOAD:
+ dump_child ("crnt", OVL_CURRENT (t));
+ dump_child ("chan", OVL_CHAIN (t));
+ break;
+
+ case TRY_BLOCK:
+ dump_stmt (di, t);
+ if (CLEANUP_P (t))
+ dump_string_field (di, "note", "cleanup");
+ dump_child ("body", TRY_STMTS (t));
+ dump_child ("hdlr", TRY_HANDLERS (t));
+ break;
+
+ case EH_SPEC_BLOCK:
+ dump_stmt (di, t);
+ dump_child ("body", EH_SPEC_STMTS (t));
+ dump_child ("raises", EH_SPEC_RAISES (t));
+ break;
+
+ case PTRMEM_CST:
+ dump_child ("clas", PTRMEM_CST_CLASS (t));
+ dump_child ("mbr", PTRMEM_CST_MEMBER (t));
+ break;
+
+ case THROW_EXPR:
+ /* These nodes are unary, but do not have code class `1'. */
+ dump_child ("op 0", TREE_OPERAND (t, 0));
+ break;
+
+ case AGGR_INIT_EXPR:
+ {
+ int i = 0;
+ tree arg;
+ aggr_init_expr_arg_iterator iter;
+ dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
+ dump_child ("fn", AGGR_INIT_EXPR_FN (t));
+ FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
+ {
+ char buffer[32];
+ sprintf (buffer, "%u", i);
+ dump_child (buffer, arg);
+ i++;
+ }
+ dump_child ("decl", AGGR_INIT_EXPR_SLOT (t));
+ }
+ break;
+
+ case HANDLER:
+ dump_stmt (di, t);
+ dump_child ("parm", HANDLER_PARMS (t));
+ dump_child ("body", HANDLER_BODY (t));
+ break;
+
+ case MUST_NOT_THROW_EXPR:
+ dump_stmt (di, t);
+ dump_child ("body", TREE_OPERAND (t, 0));
+ dump_child ("cond", MUST_NOT_THROW_COND (t));
+ break;
+
+ case USING_STMT:
+ dump_stmt (di, t);
+ dump_child ("nmsp", USING_STMT_NAMESPACE (t));
+ break;
+
+ case CLEANUP_STMT:
+ dump_stmt (di, t);
+ dump_child ("decl", CLEANUP_DECL (t));
+ dump_child ("expr", CLEANUP_EXPR (t));
+ dump_child ("body", CLEANUP_BODY (t));
+ break;
+
+ case IF_STMT:
+ dump_stmt (di, t);
+ dump_child ("cond", IF_COND (t));
+ dump_child ("then", THEN_CLAUSE (t));
+ dump_child ("else", ELSE_CLAUSE (t));
+ break;
+
+ case BREAK_STMT:
+ case CONTINUE_STMT:
+ dump_stmt (di, t);
+ break;
+
+ case DO_STMT:
+ dump_stmt (di, t);
+ dump_child ("body", DO_BODY (t));
+ dump_child ("cond", DO_COND (t));
+ break;
+
+ case FOR_STMT:
+ dump_stmt (di, t);
+ dump_child ("init", FOR_INIT_STMT (t));
+ dump_child ("cond", FOR_COND (t));
+ dump_child ("expr", FOR_EXPR (t));
+ dump_child ("body", FOR_BODY (t));
+ break;
+
+ case RANGE_FOR_STMT:
+ dump_stmt (di, t);
+ dump_child ("decl", RANGE_FOR_DECL (t));
+ dump_child ("expr", RANGE_FOR_EXPR (t));
+ dump_child ("body", RANGE_FOR_BODY (t));
+ break;
+
+ case SWITCH_STMT:
+ dump_stmt (di, t);
+ dump_child ("cond", SWITCH_STMT_COND (t));
+ dump_child ("body", SWITCH_STMT_BODY (t));
+ break;
+
+ case WHILE_STMT:
+ dump_stmt (di, t);
+ dump_child ("cond", WHILE_COND (t));
+ dump_child ("body", WHILE_BODY (t));
+ break;
+
+ case STMT_EXPR:
+ dump_child ("stmt", STMT_EXPR_STMT (t));
+ break;
+
+ case EXPR_STMT:
+ dump_stmt (di, t);
+ dump_child ("expr", EXPR_STMT_EXPR (t));
+ break;
+
+ default:
+ break;
+ }
+
+ return c_dump_tree (di, t);
+}
diff --git a/gcc-4.9/gcc/cp/error.c b/gcc-4.9/gcc/cp/error.c
new file mode 100644
index 000000000..454feb519
--- /dev/null
+++ b/gcc-4.9/gcc/cp/error.c
@@ -0,0 +1,3612 @@
+/* Call-backs for C++ error reporting.
+ This code is non-reentrant.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
+ This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "diagnostic.h"
+#include "tree-diagnostic.h"
+#include "langhooks-def.h"
+#include "intl.h"
+#include "cxx-pretty-print.h"
+#include "tree-pretty-print.h"
+#include "pointer-set.h"
+#include "c-family/c-objc.h"
+#include "ubsan.h"
+
+#include <new> // For placement-new.
+
+#define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',')
+#define pp_separate_with_semicolon(PP) pp_cxx_separate_with (PP, ';')
+
+/* The global buffer where we dump everything. It is there only for
+ transitional purpose. It is expected, in the near future, to be
+ completely removed. */
+static cxx_pretty_printer scratch_pretty_printer;
+#define cxx_pp (&scratch_pretty_printer)
+
+/* Translate if being used for diagnostics, but not for dump files or
+ __PRETTY_FUNCTION. */
+#define M_(msgid) (pp_translate_identifiers (cxx_pp) ? _(msgid) : (msgid))
+
+# define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T)))
+
+static const char *args_to_string (tree, int);
+static const char *assop_to_string (enum tree_code);
+static const char *code_to_string (enum tree_code);
+static const char *cv_to_string (tree, int);
+static const char *decl_to_string (tree, int);
+static const char *expr_to_string (tree);
+static const char *fndecl_to_string (tree, int);
+static const char *op_to_string (enum tree_code);
+static const char *parm_to_string (int);
+static const char *type_to_string (tree, int);
+
+static void dump_alias_template_specialization (cxx_pretty_printer *, tree, int);
+static void dump_type (cxx_pretty_printer *, tree, int);
+static void dump_typename (cxx_pretty_printer *, tree, int);
+static void dump_simple_decl (cxx_pretty_printer *, tree, tree, int);
+static void dump_decl (cxx_pretty_printer *, tree, int);
+static void dump_template_decl (cxx_pretty_printer *, tree, int);
+static void dump_function_decl (cxx_pretty_printer *, tree, int);
+static void dump_expr (cxx_pretty_printer *, tree, int);
+static void dump_unary_op (cxx_pretty_printer *, const char *, tree, int);
+static void dump_binary_op (cxx_pretty_printer *, const char *, tree, int);
+static void dump_aggr_type (cxx_pretty_printer *, tree, int);
+static void dump_type_prefix (cxx_pretty_printer *, tree, int);
+static void dump_type_suffix (cxx_pretty_printer *, tree, int);
+static void dump_function_name (cxx_pretty_printer *, tree, int);
+static void dump_call_expr_args (cxx_pretty_printer *, tree, int, bool);
+static void dump_aggr_init_expr_args (cxx_pretty_printer *, tree, int, bool);
+static void dump_expr_list (cxx_pretty_printer *, tree, int);
+static void dump_global_iord (cxx_pretty_printer *, tree);
+static void dump_parameters (cxx_pretty_printer *, tree, int);
+static void dump_ref_qualifier (cxx_pretty_printer *, tree, int);
+static void dump_exception_spec (cxx_pretty_printer *, tree, int);
+static void dump_template_argument (cxx_pretty_printer *, tree, int);
+static void dump_template_argument_list (cxx_pretty_printer *, tree, int);
+static void dump_template_parameter (cxx_pretty_printer *, tree, int);
+static void dump_template_bindings (cxx_pretty_printer *, tree, tree,
+ vec<tree, va_gc> *);
+static void dump_scope (cxx_pretty_printer *, tree, int);
+static void dump_template_parms (cxx_pretty_printer *, tree, int, int);
+static int get_non_default_template_args_count (tree, int);
+static const char *function_category (tree);
+static void maybe_print_constexpr_context (diagnostic_context *);
+static void maybe_print_instantiation_context (diagnostic_context *);
+static void print_instantiation_full_context (diagnostic_context *);
+static void print_instantiation_partial_context (diagnostic_context *,
+ struct tinst_level *,
+ location_t);
+static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *);
+static void cp_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
+static void cp_print_error_function (diagnostic_context *, diagnostic_info *);
+
+static bool cp_printer (pretty_printer *, text_info *, const char *,
+ int, bool, bool, bool);
+
+void
+init_error (void)
+{
+ diagnostic_starter (global_dc) = cp_diagnostic_starter;
+ diagnostic_finalizer (global_dc) = cp_diagnostic_finalizer;
+ diagnostic_format_decoder (global_dc) = cp_printer;
+
+ new (cxx_pp) cxx_pretty_printer ();
+}
+
+/* Dump a scope, if deemed necessary. */
+
+static void
+dump_scope (cxx_pretty_printer *pp, tree scope, int flags)
+{
+ int f = flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF);
+
+ if (scope == NULL_TREE)
+ return;
+
+ if (TREE_CODE (scope) == NAMESPACE_DECL)
+ {
+ if (scope != global_namespace)
+ {
+ dump_decl (pp, scope, f);
+ pp_cxx_colon_colon (pp);
+ }
+ }
+ else if (AGGREGATE_TYPE_P (scope))
+ {
+ dump_type (pp, scope, f);
+ pp_cxx_colon_colon (pp);
+ }
+ else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL)
+ {
+ dump_function_decl (pp, scope, f);
+ pp_cxx_colon_colon (pp);
+ }
+}
+
+/* Dump the template ARGument under control of FLAGS. */
+
+static void
+dump_template_argument (cxx_pretty_printer *pp, tree arg, int flags)
+{
+ if (ARGUMENT_PACK_P (arg))
+ dump_template_argument_list (pp, ARGUMENT_PACK_ARGS (arg),
+ /* No default args in argument packs. */
+ flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
+ else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
+ dump_type (pp, arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
+ else
+ {
+ if (TREE_CODE (arg) == TREE_LIST)
+ arg = TREE_VALUE (arg);
+
+ dump_expr (pp, arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM);
+ }
+}
+
+/* Count the number of template arguments ARGS whose value does not
+ match the (optional) default template parameter in PARAMS */
+
+static int
+get_non_default_template_args_count (tree args, int flags)
+{
+ int n = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (args));
+
+ if (/* We use this flag when generating debug information. We don't
+ want to expand templates at this point, for this may generate
+ new decls, which gets decl counts out of sync, which may in
+ turn cause codegen differences between compilations with and
+ without -g. */
+ (flags & TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS) != 0
+ || !flag_pretty_templates)
+ return n;
+
+ return GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (INNERMOST_TEMPLATE_ARGS (args));
+}
+
+/* Dump a template-argument-list ARGS (always a TREE_VEC) under control
+ of FLAGS. */
+
+static void
+dump_template_argument_list (cxx_pretty_printer *pp, tree args, int flags)
+{
+ int n = get_non_default_template_args_count (args, flags);
+ int need_comma = 0;
+ int i;
+
+ for (i = 0; i < n; ++i)
+ {
+ tree arg = TREE_VEC_ELT (args, i);
+
+ /* Only print a comma if we know there is an argument coming. In
+ the case of an empty template argument pack, no actual
+ argument will be printed. */
+ if (need_comma
+ && (!ARGUMENT_PACK_P (arg)
+ || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
+ pp_separate_with_comma (pp);
+
+ dump_template_argument (pp, arg, flags);
+ need_comma = 1;
+ }
+}
+
+/* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS. */
+
+static void
+dump_template_parameter (cxx_pretty_printer *pp, tree parm, int flags)
+{
+ tree p;
+ tree a;
+
+ if (parm == error_mark_node)
+ return;
+
+ p = TREE_VALUE (parm);
+ a = TREE_PURPOSE (parm);
+
+ if (TREE_CODE (p) == TYPE_DECL)
+ {
+ if (flags & TFF_DECL_SPECIFIERS)
+ {
+ pp_cxx_ws_string (pp, "class");
+ if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (p)))
+ pp_cxx_ws_string (pp, "...");
+ if (DECL_NAME (p))
+ pp_cxx_tree_identifier (pp, DECL_NAME (p));
+ }
+ else if (DECL_NAME (p))
+ pp_cxx_tree_identifier (pp, DECL_NAME (p));
+ else
+ pp_cxx_canonical_template_parameter (pp, TREE_TYPE (p));
+ }
+ else
+ dump_decl (pp, p, flags | TFF_DECL_SPECIFIERS);
+
+ if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE)
+ {
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
+ if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
+ dump_type (pp, a, flags & ~TFF_CHASE_TYPEDEF);
+ else
+ dump_expr (pp, a, flags | TFF_EXPR_IN_PARENS);
+ }
+}
+
+/* Dump, under control of FLAGS, a template-parameter-list binding.
+ PARMS is a TREE_LIST of TREE_VEC of TREE_LIST and ARGS is a
+ TREE_VEC. */
+
+static void
+dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
+ vec<tree, va_gc> *typenames)
+{
+ bool need_semicolon = false;
+ int i;
+ tree t;
+
+ while (parms)
+ {
+ tree p = TREE_VALUE (parms);
+ int lvl = TMPL_PARMS_DEPTH (parms);
+ int arg_idx = 0;
+ int i;
+ tree lvl_args = NULL_TREE;
+
+ /* Don't crash if we had an invalid argument list. */
+ if (TMPL_ARGS_DEPTH (args) >= lvl)
+ lvl_args = TMPL_ARGS_LEVEL (args, lvl);
+
+ for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
+ {
+ tree arg = NULL_TREE;
+
+ /* Don't crash if we had an invalid argument list. */
+ if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx)
+ arg = TREE_VEC_ELT (lvl_args, arg_idx);
+
+ if (need_semicolon)
+ pp_separate_with_semicolon (pp);
+ dump_template_parameter (pp, TREE_VEC_ELT (p, i),
+ TFF_PLAIN_IDENTIFIER);
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
+ if (arg)
+ {
+ if (ARGUMENT_PACK_P (arg))
+ pp_cxx_left_brace (pp);
+ dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER);
+ if (ARGUMENT_PACK_P (arg))
+ pp_cxx_right_brace (pp);
+ }
+ else
+ pp_string (pp, M_("<missing>"));
+
+ ++arg_idx;
+ need_semicolon = true;
+ }
+
+ parms = TREE_CHAIN (parms);
+ }
+
+ /* Don't bother with typenames for a partial instantiation. */
+ if (vec_safe_is_empty (typenames) || uses_template_parms (args))
+ return;
+
+ FOR_EACH_VEC_SAFE_ELT (typenames, i, t)
+ {
+ if (need_semicolon)
+ pp_separate_with_semicolon (pp);
+ dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
+ push_deferring_access_checks (dk_no_check);
+ t = tsubst (t, args, tf_none, NULL_TREE);
+ pop_deferring_access_checks ();
+ /* Strip typedefs. We can't just use TFF_CHASE_TYPEDEF because
+ pp_simple_type_specifier doesn't know about it. */
+ t = strip_typedefs (t);
+ dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
+ }
+}
+
+/* Dump a human-readable equivalent of the alias template
+ specialization of T. */
+
+static void
+dump_alias_template_specialization (cxx_pretty_printer *pp, tree t, int flags)
+{
+ tree name;
+
+ gcc_assert (alias_template_specialization_p (t));
+
+ if (!(flags & TFF_UNQUALIFIED_NAME))
+ dump_scope (pp, CP_DECL_CONTEXT (TYPE_NAME (t)), flags);
+ name = TYPE_IDENTIFIER (t);
+ pp_cxx_tree_identifier (pp, name);
+ dump_template_parms (pp, TYPE_TEMPLATE_INFO (t),
+ /*primary=*/false,
+ flags & ~TFF_TEMPLATE_HEADER);
+}
+
+/* Dump a human-readable equivalent of TYPE. FLAGS controls the
+ format. */
+
+static void
+dump_type (cxx_pretty_printer *pp, tree t, int flags)
+{
+ if (t == NULL_TREE)
+ return;
+
+ /* Don't print e.g. "struct mytypedef". */
+ if (TYPE_P (t) && typedef_variant_p (t))
+ {
+ tree decl = TYPE_NAME (t);
+ if ((flags & TFF_CHASE_TYPEDEF)
+ || DECL_SELF_REFERENCE_P (decl)
+ || (!flag_pretty_templates
+ && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)))
+ t = strip_typedefs (t);
+ else if (alias_template_specialization_p (t))
+ {
+ dump_alias_template_specialization (pp, t, flags);
+ return;
+ }
+ else if (same_type_p (t, TREE_TYPE (decl)))
+ t = decl;
+ else
+ {
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
+ return;
+ }
+ }
+
+ if (TYPE_PTRMEMFUNC_P (t))
+ goto offset_type;
+
+ switch (TREE_CODE (t))
+ {
+ case LANG_TYPE:
+ if (t == init_list_type_node)
+ pp_string (pp, M_("<brace-enclosed initializer list>"));
+ else if (t == unknown_type_node)
+ pp_string (pp, M_("<unresolved overloaded function type>"));
+ else
+ {
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
+ }
+ break;
+
+ case TREE_LIST:
+ /* A list of function parms. */
+ dump_parameters (pp, t, flags);
+ break;
+
+ case IDENTIFIER_NODE:
+ pp_cxx_tree_identifier (pp, t);
+ break;
+
+ case TREE_BINFO:
+ dump_type (pp, BINFO_TYPE (t), flags);
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ dump_aggr_type (pp, t, flags);
+ break;
+
+ case TYPE_DECL:
+ if (flags & TFF_CHASE_TYPEDEF)
+ {
+ dump_type (pp, DECL_ORIGINAL_TYPE (t)
+ ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags);
+ break;
+ }
+ /* Else fall through. */
+
+ case TEMPLATE_DECL:
+ case NAMESPACE_DECL:
+ dump_decl (pp, t, flags & ~TFF_DECL_SPECIFIERS);
+ break;
+
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ case VOID_TYPE:
+ case BOOLEAN_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ case FIXED_POINT_TYPE:
+ pp_type_specifier_seq (pp, t);
+ break;
+
+ case TEMPLATE_TEMPLATE_PARM:
+ /* For parameters inside template signature. */
+ if (TYPE_IDENTIFIER (t))
+ pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
+ else
+ pp_cxx_canonical_template_parameter (pp, t);
+ break;
+
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ {
+ tree args = TYPE_TI_ARGS (t);
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
+ pp_cxx_begin_template_argument_list (pp);
+ dump_template_argument_list (pp, args, flags);
+ pp_cxx_end_template_argument_list (pp);
+ }
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ pp_cxx_cv_qualifier_seq (pp, t);
+ if (TYPE_IDENTIFIER (t))
+ pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
+ else
+ pp_cxx_canonical_template_parameter
+ (pp, TEMPLATE_TYPE_PARM_INDEX (t));
+ break;
+
+ /* This is not always necessary for pointers and such, but doing this
+ reduces code size. */
+ case ARRAY_TYPE:
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ case OFFSET_TYPE:
+ offset_type:
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ {
+ dump_type_prefix (pp, t, flags);
+ dump_type_suffix (pp, t, flags);
+ break;
+ }
+ case TYPENAME_TYPE:
+ if (! (flags & TFF_CHASE_TYPEDEF)
+ && DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
+ {
+ dump_decl (pp, TYPE_NAME (t), TFF_PLAIN_IDENTIFIER);
+ break;
+ }
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp_cxx_ws_string (pp,
+ TYPENAME_IS_ENUM_P (t) ? "enum"
+ : TYPENAME_IS_CLASS_P (t) ? "class"
+ : "typename");
+ dump_typename (pp, t, flags);
+ break;
+
+ case UNBOUND_CLASS_TEMPLATE:
+ if (! (flags & TFF_UNQUALIFIED_NAME))
+ {
+ dump_type (pp, TYPE_CONTEXT (t), flags);
+ pp_cxx_colon_colon (pp);
+ }
+ pp_cxx_ws_string (pp, "template");
+ dump_type (pp, TYPE_IDENTIFIER (t), flags);
+ break;
+
+ case TYPEOF_TYPE:
+ pp_cxx_ws_string (pp, "__typeof__");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
+ break;
+
+ case UNDERLYING_TYPE:
+ pp_cxx_ws_string (pp, "__underlying_type");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, UNDERLYING_TYPE_TYPE (t), flags & ~TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
+ break;
+
+ case TYPE_PACK_EXPANSION:
+ dump_type (pp, PACK_EXPANSION_PATTERN (t), flags);
+ pp_cxx_ws_string (pp, "...");
+ break;
+
+ case TYPE_ARGUMENT_PACK:
+ dump_template_argument (pp, t, flags);
+ break;
+
+ case DECLTYPE_TYPE:
+ pp_cxx_ws_string (pp, "decltype");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, DECLTYPE_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
+ break;
+
+ case NULLPTR_TYPE:
+ pp_string (pp, "std::nullptr_t");
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ /* Fall through to error. */
+
+ case ERROR_MARK:
+ pp_string (pp, M_("<type error>"));
+ break;
+ }
+}
+
+/* Dump a TYPENAME_TYPE. We need to notice when the context is itself
+ a TYPENAME_TYPE. */
+
+static void
+dump_typename (cxx_pretty_printer *pp, tree t, int flags)
+{
+ tree ctx = TYPE_CONTEXT (t);
+
+ if (TREE_CODE (ctx) == TYPENAME_TYPE)
+ dump_typename (pp, ctx, flags);
+ else
+ dump_type (pp, ctx, flags & ~TFF_CLASS_KEY_OR_ENUM);
+ pp_cxx_colon_colon (pp);
+ dump_decl (pp, TYPENAME_TYPE_FULLNAME (t), flags);
+}
+
+/* Return the name of the supplied aggregate, or enumeral type. */
+
+const char *
+class_key_or_enum_as_string (tree t)
+{
+ if (TREE_CODE (t) == ENUMERAL_TYPE)
+ {
+ if (SCOPED_ENUM_P (t))
+ return "enum class";
+ else
+ return "enum";
+ }
+ else if (TREE_CODE (t) == UNION_TYPE)
+ return "union";
+ else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
+ return "class";
+ else
+ return "struct";
+}
+
+/* Print out a class declaration T under the control of FLAGS,
+ in the form `class foo'. */
+
+static void
+dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
+{
+ tree name;
+ const char *variety = class_key_or_enum_as_string (t);
+ int typdef = 0;
+ int tmplate = 0;
+
+ pp_cxx_cv_qualifier_seq (pp, t);
+
+ if (flags & TFF_CLASS_KEY_OR_ENUM)
+ pp_cxx_ws_string (pp, variety);
+
+ name = TYPE_NAME (t);
+
+ if (name)
+ {
+ typdef = (!DECL_ARTIFICIAL (name)
+ /* An alias specialization is not considered to be a
+ typedef. */
+ && !alias_template_specialization_p (t));
+
+ if ((typdef
+ && ((flags & TFF_CHASE_TYPEDEF)
+ || (!flag_pretty_templates && DECL_LANG_SPECIFIC (name)
+ && DECL_TEMPLATE_INFO (name))))
+ || DECL_SELF_REFERENCE_P (name))
+ {
+ t = TYPE_MAIN_VARIANT (t);
+ name = TYPE_NAME (t);
+ typdef = 0;
+ }
+
+ tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
+ && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
+ && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
+ || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
+
+ if (! (flags & TFF_UNQUALIFIED_NAME))
+ dump_scope (pp, CP_DECL_CONTEXT (name), flags | TFF_SCOPE);
+ flags &= ~TFF_UNQUALIFIED_NAME;
+ if (tmplate)
+ {
+ /* Because the template names are mangled, we have to locate
+ the most general template, and use that name. */
+ tree tpl = TYPE_TI_TEMPLATE (t);
+
+ while (DECL_TEMPLATE_INFO (tpl))
+ tpl = DECL_TI_TEMPLATE (tpl);
+ name = tpl;
+ }
+ name = DECL_NAME (name);
+ }
+
+ if (name == 0 || ANON_AGGRNAME_P (name))
+ {
+ if (flags & TFF_CLASS_KEY_OR_ENUM)
+ pp_string (pp, M_("<anonymous>"));
+ else
+ pp_printf (pp, M_("<anonymous %s>"), variety);
+ }
+ else if (LAMBDA_TYPE_P (t))
+ {
+ /* A lambda's "type" is essentially its signature. */
+ pp_string (pp, M_("<lambda"));
+ if (lambda_function (t))
+ dump_parameters (pp,
+ FUNCTION_FIRST_USER_PARMTYPE (lambda_function (t)),
+ flags);
+ pp_greater (pp);
+ }
+ else
+ pp_cxx_tree_identifier (pp, name);
+ if (tmplate)
+ dump_template_parms (pp, TYPE_TEMPLATE_INFO (t),
+ !CLASSTYPE_USE_TEMPLATE (t),
+ flags & ~TFF_TEMPLATE_HEADER);
+}
+
+/* Dump into the obstack the initial part of the output for a given type.
+ This is necessary when dealing with things like functions returning
+ functions. Examples:
+
+ return type of `int (* fee ())()': pointer -> function -> int. Both
+ pointer (and reference and offset) and function (and member) types must
+ deal with prefix and suffix.
+
+ Arrays must also do this for DECL nodes, like int a[], and for things like
+ int *[]&. */
+
+static void
+dump_type_prefix (cxx_pretty_printer *pp, tree t, int flags)
+{
+ if (TYPE_PTRMEMFUNC_P (t))
+ {
+ t = TYPE_PTRMEMFUNC_FN_TYPE (t);
+ goto offset_type;
+ }
+
+ switch (TREE_CODE (t))
+ {
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ {
+ tree sub = TREE_TYPE (t);
+
+ dump_type_prefix (pp, sub, flags);
+ if (TREE_CODE (sub) == ARRAY_TYPE
+ || TREE_CODE (sub) == FUNCTION_TYPE)
+ {
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ pp_c_attributes_display (pp, TYPE_ATTRIBUTES (sub));
+ }
+ if (TYPE_PTR_P (t))
+ pp_star (pp);
+ else if (TREE_CODE (t) == REFERENCE_TYPE)
+ {
+ if (TYPE_REF_IS_RVALUE (t))
+ pp_ampersand_ampersand (pp);
+ else
+ pp_ampersand (pp);
+ }
+ pp->padding = pp_before;
+ pp_cxx_cv_qualifier_seq (pp, t);
+ }
+ break;
+
+ case OFFSET_TYPE:
+ offset_type:
+ dump_type_prefix (pp, TREE_TYPE (t), flags);
+ if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
+ {
+ pp_maybe_space (pp);
+ if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
+ pp_cxx_left_paren (pp);
+ dump_type (pp, TYPE_OFFSET_BASETYPE (t), flags);
+ pp_cxx_colon_colon (pp);
+ }
+ pp_cxx_star (pp);
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp->padding = pp_before;
+ break;
+
+ /* This can be reached without a pointer when dealing with
+ templates, e.g. std::is_function. */
+ case FUNCTION_TYPE:
+ dump_type_prefix (pp, TREE_TYPE (t), flags);
+ break;
+
+ case METHOD_TYPE:
+ dump_type_prefix (pp, TREE_TYPE (t), flags);
+ pp_maybe_space (pp);
+ pp_cxx_left_paren (pp);
+ dump_aggr_type (pp, TYPE_METHOD_BASETYPE (t), flags);
+ pp_cxx_colon_colon (pp);
+ break;
+
+ case ARRAY_TYPE:
+ dump_type_prefix (pp, TREE_TYPE (t), flags);
+ break;
+
+ case ENUMERAL_TYPE:
+ case IDENTIFIER_NODE:
+ case INTEGER_TYPE:
+ case BOOLEAN_TYPE:
+ case REAL_TYPE:
+ case RECORD_TYPE:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ case TREE_LIST:
+ case TYPE_DECL:
+ case TREE_VEC:
+ case UNION_TYPE:
+ case LANG_TYPE:
+ case VOID_TYPE:
+ case TYPENAME_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ case TYPEOF_TYPE:
+ case UNDERLYING_TYPE:
+ case DECLTYPE_TYPE:
+ case TYPE_PACK_EXPANSION:
+ case FIXED_POINT_TYPE:
+ case NULLPTR_TYPE:
+ dump_type (pp, t, flags);
+ pp->padding = pp_before;
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ /* fall through. */
+ case ERROR_MARK:
+ pp_string (pp, M_("<typeprefixerror>"));
+ break;
+ }
+}
+
+/* Dump the suffix of type T, under control of FLAGS. This is the part
+ which appears after the identifier (or function parms). */
+
+static void
+dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags)
+{
+ if (TYPE_PTRMEMFUNC_P (t))
+ t = TYPE_PTRMEMFUNC_FN_TYPE (t);
+
+ switch (TREE_CODE (t))
+ {
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ case OFFSET_TYPE:
+ if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
+ || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
+ pp_cxx_right_paren (pp);
+ dump_type_suffix (pp, TREE_TYPE (t), flags);
+ break;
+
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ {
+ tree arg;
+ if (TREE_CODE (t) == METHOD_TYPE)
+ /* Can only be reached through a pointer. */
+ pp_cxx_right_paren (pp);
+ arg = TYPE_ARG_TYPES (t);
+ if (TREE_CODE (t) == METHOD_TYPE)
+ arg = TREE_CHAIN (arg);
+
+ /* Function pointers don't have default args. Not in standard C++,
+ anyway; they may in g++, but we'll just pretend otherwise. */
+ dump_parameters (pp, arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
+
+ pp->padding = pp_before;
+ pp_cxx_cv_qualifiers (pp, type_memfn_quals (t));
+ dump_ref_qualifier (pp, t, flags);
+ dump_exception_spec (pp, TYPE_RAISES_EXCEPTIONS (t), flags);
+ dump_type_suffix (pp, TREE_TYPE (t), flags);
+ break;
+ }
+
+ case ARRAY_TYPE:
+ pp_maybe_space (pp);
+ pp_cxx_left_bracket (pp);
+ if (TYPE_DOMAIN (t))
+ {
+ tree dtype = TYPE_DOMAIN (t);
+ tree max = TYPE_MAX_VALUE (dtype);
+ if (integer_all_onesp (max))
+ pp_character (pp, '0');
+ else if (tree_fits_shwi_p (max))
+ pp_wide_integer (pp, tree_to_shwi (max) + 1);
+ else
+ {
+ STRIP_NOPS (max);
+ if (TREE_CODE (max) == SAVE_EXPR)
+ max = TREE_OPERAND (max, 0);
+ if (TREE_CODE (max) == MINUS_EXPR
+ || TREE_CODE (max) == PLUS_EXPR)
+ {
+ max = TREE_OPERAND (max, 0);
+ while (CONVERT_EXPR_P (max))
+ max = TREE_OPERAND (max, 0);
+ }
+ else
+ max = fold_build2_loc (input_location,
+ PLUS_EXPR, dtype, max,
+ build_int_cst (dtype, 1));
+ dump_expr (pp, max, flags & ~TFF_EXPR_IN_PARENS);
+ }
+ }
+ pp_cxx_right_bracket (pp);
+ dump_type_suffix (pp, TREE_TYPE (t), flags);
+ break;
+
+ case ENUMERAL_TYPE:
+ case IDENTIFIER_NODE:
+ case INTEGER_TYPE:
+ case BOOLEAN_TYPE:
+ case REAL_TYPE:
+ case RECORD_TYPE:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ case TREE_LIST:
+ case TYPE_DECL:
+ case TREE_VEC:
+ case UNION_TYPE:
+ case LANG_TYPE:
+ case VOID_TYPE:
+ case TYPENAME_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ case TYPEOF_TYPE:
+ case UNDERLYING_TYPE:
+ case DECLTYPE_TYPE:
+ case TYPE_PACK_EXPANSION:
+ case FIXED_POINT_TYPE:
+ case NULLPTR_TYPE:
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ case ERROR_MARK:
+ /* Don't mark it here, we should have already done in
+ dump_type_prefix. */
+ break;
+ }
+}
+
+static void
+dump_global_iord (cxx_pretty_printer *pp, tree t)
+{
+ const char *p = NULL;
+
+ if (DECL_GLOBAL_CTOR_P (t))
+ p = M_("(static initializers for %s)");
+ else if (DECL_GLOBAL_DTOR_P (t))
+ p = M_("(static destructors for %s)");
+ else
+ gcc_unreachable ();
+
+ pp_printf (pp, p, LOCATION_FILE (input_location));
+}
+
+static void
+dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags)
+{
+ if (flags & TFF_DECL_SPECIFIERS)
+ {
+ if (VAR_P (t)
+ && DECL_DECLARED_CONSTEXPR_P (t))
+ pp_cxx_ws_string (pp, "constexpr");
+ dump_type_prefix (pp, type, flags & ~TFF_UNQUALIFIED_NAME);
+ pp_maybe_space (pp);
+ }
+ if (! (flags & TFF_UNQUALIFIED_NAME)
+ && TREE_CODE (t) != PARM_DECL
+ && (!DECL_INITIAL (t)
+ || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX))
+ dump_scope (pp, CP_DECL_CONTEXT (t), flags);
+ flags &= ~TFF_UNQUALIFIED_NAME;
+ if ((flags & TFF_DECL_SPECIFIERS)
+ && DECL_TEMPLATE_PARM_P (t)
+ && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (t)))
+ pp_string (pp, "...");
+ if (DECL_NAME (t))
+ {
+ if (TREE_CODE (t) == FIELD_DECL && DECL_NORMAL_CAPTURE_P (t))
+ {
+ pp_less (pp);
+ pp_string (pp, IDENTIFIER_POINTER (DECL_NAME (t)) + 2);
+ pp_string (pp, " capture>");
+ }
+ else
+ dump_decl (pp, DECL_NAME (t), flags);
+ }
+ else
+ pp_string (pp, M_("<anonymous>"));
+ if (flags & TFF_DECL_SPECIFIERS)
+ dump_type_suffix (pp, type, flags);
+}
+
+/* Dump a human readable string for the decl T under control of FLAGS. */
+
+static void
+dump_decl (cxx_pretty_printer *pp, tree t, int flags)
+{
+ if (t == NULL_TREE)
+ return;
+
+ /* If doing Objective-C++, give Objective-C a chance to demangle
+ Objective-C method names. */
+ if (c_dialect_objc ())
+ {
+ const char *demangled = objc_maybe_printable_name (t, flags);
+ if (demangled)
+ {
+ pp_string (pp, demangled);
+ return;
+ }
+ }
+
+ switch (TREE_CODE (t))
+ {
+ case TYPE_DECL:
+ /* Don't say 'typedef class A' */
+ if (DECL_ARTIFICIAL (t) && !DECL_SELF_REFERENCE_P (t))
+ {
+ if ((flags & TFF_DECL_SPECIFIERS)
+ && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
+ {
+ /* Say `class T' not just `T'. */
+ pp_cxx_ws_string (pp, "class");
+
+ /* Emit the `...' for a parameter pack. */
+ if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+ pp_cxx_ws_string (pp, "...");
+ }
+
+ dump_type (pp, TREE_TYPE (t), flags);
+ break;
+ }
+ if (TYPE_DECL_ALIAS_P (t)
+ && (flags & TFF_DECL_SPECIFIERS
+ || flags & TFF_CLASS_KEY_OR_ENUM))
+ {
+ pp_cxx_ws_string (pp, "using");
+ dump_decl (pp, DECL_NAME (t), flags);
+ pp_cxx_whitespace (pp);
+ pp_cxx_ws_string (pp, "=");
+ pp_cxx_whitespace (pp);
+ dump_type (pp, DECL_ORIGINAL_TYPE (t), flags);
+ break;
+ }
+ if ((flags & TFF_DECL_SPECIFIERS)
+ && !DECL_SELF_REFERENCE_P (t))
+ pp_cxx_ws_string (pp, "typedef");
+ dump_simple_decl (pp, t, DECL_ORIGINAL_TYPE (t)
+ ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
+ flags);
+ break;
+
+ case VAR_DECL:
+ if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
+ {
+ pp_string (pp, M_("vtable for "));
+ gcc_assert (TYPE_P (DECL_CONTEXT (t)));
+ dump_type (pp, DECL_CONTEXT (t), flags);
+ break;
+ }
+ /* Else fall through. */
+ case FIELD_DECL:
+ case PARM_DECL:
+ dump_simple_decl (pp, t, TREE_TYPE (t), flags);
+ break;
+
+ case RESULT_DECL:
+ pp_string (pp, M_("<return value> "));
+ dump_simple_decl (pp, t, TREE_TYPE (t), flags);
+ break;
+
+ case NAMESPACE_DECL:
+ if (flags & TFF_DECL_SPECIFIERS)
+ pp->declaration (t);
+ else
+ {
+ if (! (flags & TFF_UNQUALIFIED_NAME))
+ dump_scope (pp, CP_DECL_CONTEXT (t), flags);
+ flags &= ~TFF_UNQUALIFIED_NAME;
+ if (DECL_NAME (t) == NULL_TREE)
+ {
+ if (!(pp->flags & pp_c_flag_gnu_v3))
+ pp_cxx_ws_string (pp, M_("{anonymous}"));
+ else
+ pp_cxx_ws_string (pp, M_("(anonymous namespace)"));
+ }
+ else
+ pp_cxx_tree_identifier (pp, DECL_NAME (t));
+ }
+ break;
+
+ case SCOPE_REF:
+ dump_type (pp, TREE_OPERAND (t, 0), flags);
+ pp_colon_colon (pp);
+ dump_decl (pp, TREE_OPERAND (t, 1), TFF_UNQUALIFIED_NAME);
+ break;
+
+ case ARRAY_REF:
+ dump_decl (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_left_bracket (pp);
+ dump_decl (pp, TREE_OPERAND (t, 1), flags);
+ pp_cxx_right_bracket (pp);
+ break;
+
+ case ARRAY_NOTATION_REF:
+ dump_decl (pp, ARRAY_NOTATION_ARRAY (t), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_left_bracket (pp);
+ dump_decl (pp, ARRAY_NOTATION_START (t), flags | TFF_EXPR_IN_PARENS);
+ pp_colon (pp);
+ dump_decl (pp, ARRAY_NOTATION_LENGTH (t), flags | TFF_EXPR_IN_PARENS);
+ pp_colon (pp);
+ dump_decl (pp, ARRAY_NOTATION_STRIDE (t), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_bracket (pp);
+ break;
+
+ /* So that we can do dump_decl on an aggr type. */
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ dump_type (pp, t, flags);
+ break;
+
+ case BIT_NOT_EXPR:
+ /* This is a pseudo destructor call which has not been folded into
+ a PSEUDO_DTOR_EXPR yet. */
+ pp_cxx_complement (pp);
+ dump_type (pp, TREE_OPERAND (t, 0), flags);
+ break;
+
+ case TYPE_EXPR:
+ gcc_unreachable ();
+ break;
+
+ /* These special cases are duplicated here so that other functions
+ can feed identifiers to error and get them demangled properly. */
+ case IDENTIFIER_NODE:
+ if (IDENTIFIER_TYPENAME_P (t))
+ {
+ pp_cxx_ws_string (pp, "operator");
+ /* Not exactly IDENTIFIER_TYPE_VALUE. */
+ dump_type (pp, TREE_TYPE (t), flags);
+ break;
+ }
+ else
+ pp_cxx_tree_identifier (pp, t);
+ break;
+
+ case OVERLOAD:
+ if (OVL_CHAIN (t))
+ {
+ t = OVL_CURRENT (t);
+ if (DECL_CLASS_SCOPE_P (t))
+ {
+ dump_type (pp, DECL_CONTEXT (t), flags);
+ pp_cxx_colon_colon (pp);
+ }
+ else if (!DECL_FILE_SCOPE_P (t))
+ {
+ dump_decl (pp, DECL_CONTEXT (t), flags);
+ pp_cxx_colon_colon (pp);
+ }
+ dump_decl (pp, DECL_NAME (t), flags);
+ break;
+ }
+
+ /* If there's only one function, just treat it like an ordinary
+ FUNCTION_DECL. */
+ t = OVL_CURRENT (t);
+ /* Fall through. */
+
+ case FUNCTION_DECL:
+ if (! DECL_LANG_SPECIFIC (t))
+ pp_string (pp, M_("<built-in>"));
+ else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
+ dump_global_iord (pp, t);
+ else
+ dump_function_decl (pp, t, flags);
+ break;
+
+ case TEMPLATE_DECL:
+ dump_template_decl (pp, t, flags);
+ break;
+
+ case TEMPLATE_ID_EXPR:
+ {
+ tree name = TREE_OPERAND (t, 0);
+ tree args = TREE_OPERAND (t, 1);
+
+ if (is_overloaded_fn (name))
+ name = DECL_NAME (get_first_fn (name));
+ dump_decl (pp, name, flags);
+ pp_cxx_begin_template_argument_list (pp);
+ if (args == error_mark_node)
+ pp_string (pp, M_("<template arguments error>"));
+ else if (args)
+ dump_template_argument_list (pp, args, flags);
+ pp_cxx_end_template_argument_list (pp);
+ }
+ break;
+
+ case LABEL_DECL:
+ pp_cxx_tree_identifier (pp, DECL_NAME (t));
+ break;
+
+ case CONST_DECL:
+ if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
+ || (DECL_INITIAL (t) &&
+ TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
+ dump_simple_decl (pp, t, TREE_TYPE (t), flags);
+ else if (DECL_NAME (t))
+ dump_decl (pp, DECL_NAME (t), flags);
+ else if (DECL_INITIAL (t))
+ dump_expr (pp, DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
+ else
+ pp_string (pp, M_("<enumerator>"));
+ break;
+
+ case USING_DECL:
+ pp_cxx_ws_string (pp, "using");
+ dump_type (pp, USING_DECL_SCOPE (t), flags);
+ pp_cxx_colon_colon (pp);
+ dump_decl (pp, DECL_NAME (t), flags);
+ break;
+
+ case STATIC_ASSERT:
+ pp->declaration (t);
+ break;
+
+ case BASELINK:
+ dump_decl (pp, BASELINK_FUNCTIONS (t), flags);
+ break;
+
+ case NON_DEPENDENT_EXPR:
+ dump_expr (pp, t, flags);
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ if (flags & TFF_DECL_SPECIFIERS)
+ pp->declaration (t);
+ else
+ pp->type_id (t);
+ break;
+
+ case UNBOUND_CLASS_TEMPLATE:
+ case TYPE_PACK_EXPANSION:
+ case TREE_BINFO:
+ dump_type (pp, t, flags);
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ /* Fall through to error. */
+
+ case ERROR_MARK:
+ pp_string (pp, M_("<declaration error>"));
+ break;
+ }
+}
+
+/* Dump a template declaration T under control of FLAGS. This means the
+ 'template <...> leaders plus the 'class X' or 'void fn(...)' part. */
+
+static void
+dump_template_decl (cxx_pretty_printer *pp, tree t, int flags)
+{
+ tree orig_parms = DECL_TEMPLATE_PARMS (t);
+ tree parms;
+ int i;
+
+ if (flags & TFF_TEMPLATE_HEADER)
+ {
+ for (parms = orig_parms = nreverse (orig_parms);
+ parms;
+ parms = TREE_CHAIN (parms))
+ {
+ tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
+ int len = TREE_VEC_LENGTH (inner_parms);
+
+ pp_cxx_ws_string (pp, "template");
+ pp_cxx_begin_template_argument_list (pp);
+
+ /* If we've shown the template prefix, we'd better show the
+ parameters' and decl's type too. */
+ flags |= TFF_DECL_SPECIFIERS;
+
+ for (i = 0; i < len; i++)
+ {
+ if (i)
+ pp_separate_with_comma (pp);
+ dump_template_parameter (pp, TREE_VEC_ELT (inner_parms, i),
+ flags);
+ }
+ pp_cxx_end_template_argument_list (pp);
+ pp_cxx_whitespace (pp);
+ }
+ nreverse(orig_parms);
+
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
+ {
+ /* Say `template<arg> class TT' not just `template<arg> TT'. */
+ pp_cxx_ws_string (pp, "class");
+
+ /* If this is a parameter pack, print the ellipsis. */
+ if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+ pp_cxx_ws_string (pp, "...");
+ }
+ }
+
+ if (DECL_CLASS_TEMPLATE_P (t))
+ dump_type (pp, TREE_TYPE (t),
+ ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
+ | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)));
+ else if (DECL_TEMPLATE_RESULT (t)
+ && (VAR_P (DECL_TEMPLATE_RESULT (t))
+ /* Alias template. */
+ || DECL_TYPE_TEMPLATE_P (t)))
+ dump_decl (pp, DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME);
+ else
+ {
+ gcc_assert (TREE_TYPE (t));
+ switch (NEXT_CODE (t))
+ {
+ case METHOD_TYPE:
+ case FUNCTION_TYPE:
+ dump_function_decl (pp, t, flags | TFF_TEMPLATE_NAME);
+ break;
+ default:
+ /* This case can occur with some invalid code. */
+ dump_type (pp, TREE_TYPE (t),
+ (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
+ | (flags & TFF_DECL_SPECIFIERS
+ ? TFF_CLASS_KEY_OR_ENUM : 0));
+ }
+ }
+}
+
+/* find_typenames looks through the type of the function template T
+ and returns a vec containing any typedefs, decltypes or TYPENAME_TYPEs
+ it finds. */
+
+struct find_typenames_t
+{
+ struct pointer_set_t *p_set;
+ vec<tree, va_gc> *typenames;
+};
+
+static tree
+find_typenames_r (tree *tp, int *walk_subtrees, void *data)
+{
+ struct find_typenames_t *d = (struct find_typenames_t *)data;
+ tree mv = NULL_TREE;
+
+ if (TYPE_P (*tp) && is_typedef_decl (TYPE_NAME (*tp)))
+ /* Add the type of the typedef without any additional cv-quals. */
+ mv = TREE_TYPE (TYPE_NAME (*tp));
+ else if (TREE_CODE (*tp) == TYPENAME_TYPE
+ || TREE_CODE (*tp) == DECLTYPE_TYPE)
+ /* Add the typename without any cv-qualifiers. */
+ mv = TYPE_MAIN_VARIANT (*tp);
+
+ if (TREE_CODE (*tp) == TYPE_PACK_EXPANSION)
+ {
+ /* Don't mess with parameter packs since we don't remember
+ the pack expansion context for a particular typename. */
+ *walk_subtrees = false;
+ return NULL_TREE;
+ }
+
+ if (mv && (mv == *tp || !pointer_set_insert (d->p_set, mv)))
+ vec_safe_push (d->typenames, mv);
+
+ /* Search into class template arguments, which cp_walk_subtrees
+ doesn't do. */
+ if (CLASS_TYPE_P (*tp) && CLASSTYPE_TEMPLATE_INFO (*tp))
+ cp_walk_tree (&CLASSTYPE_TI_ARGS (*tp), find_typenames_r,
+ data, d->p_set);
+
+ return NULL_TREE;
+}
+
+static vec<tree, va_gc> *
+find_typenames (tree t)
+{
+ struct find_typenames_t ft;
+ ft.p_set = pointer_set_create ();
+ ft.typenames = NULL;
+ cp_walk_tree (&TREE_TYPE (DECL_TEMPLATE_RESULT (t)),
+ find_typenames_r, &ft, ft.p_set);
+ pointer_set_destroy (ft.p_set);
+ return ft.typenames;
+}
+
+/* Output the "[with ...]" clause for a template instantiation T iff
+ TEMPLATE_PARMS, TEMPLATE_ARGS and FLAGS are suitable. T may be NULL if
+ formatting a deduction/substitution diagnostic rather than an
+ instantiation. */
+
+static void
+dump_substitution (cxx_pretty_printer *pp,
+ tree t, tree template_parms, tree template_args,
+ int flags)
+{
+ if (template_parms != NULL_TREE && template_args != NULL_TREE
+ && !(flags & TFF_NO_TEMPLATE_BINDINGS))
+ {
+ vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL;
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_bracket (pp);
+ pp->translate_string ("with");
+ pp_cxx_whitespace (pp);
+ dump_template_bindings (pp, template_parms, template_args, typenames);
+ pp_cxx_right_bracket (pp);
+ }
+}
+
+/* Dump the lambda function FN including its 'mutable' qualifier and any
+ template bindings. */
+
+static void
+dump_lambda_function (cxx_pretty_printer *pp,
+ tree fn, tree template_parms, tree template_args,
+ int flags)
+{
+ /* A lambda's signature is essentially its "type". */
+ dump_type (pp, DECL_CONTEXT (fn), flags);
+ if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn))) & TYPE_QUAL_CONST))
+ {
+ pp->padding = pp_before;
+ pp_c_ws_string (pp, "mutable");
+ }
+ dump_substitution (pp, fn, template_parms, template_args, flags);
+}
+
+/* Pretty print a function decl. There are several ways we want to print a
+ function declaration. The TFF_ bits in FLAGS tells us how to behave.
+ As error can only apply the '#' flag once to give 0 and 1 for V, there
+ is %D which doesn't print the throw specs, and %F which does. */
+
+static void
+dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
+{
+ tree fntype;
+ tree parmtypes;
+ tree cname = NULL_TREE;
+ tree template_args = NULL_TREE;
+ tree template_parms = NULL_TREE;
+ int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
+ int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME);
+ tree exceptions;
+
+ flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ t = DECL_TEMPLATE_RESULT (t);
+
+ /* Save the exceptions, in case t is a specialization and we are
+ emitting an error about incompatible specifications. */
+ exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t));
+
+ /* Pretty print template instantiations only. */
+ if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t)
+ && flag_pretty_templates)
+ {
+ tree tmpl;
+
+ template_args = DECL_TI_ARGS (t);
+ tmpl = most_general_template (t);
+ if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL)
+ {
+ template_parms = DECL_TEMPLATE_PARMS (tmpl);
+ t = tmpl;
+ }
+ }
+
+ if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t))
+ return dump_lambda_function (pp, t, template_parms, template_args, flags);
+
+ fntype = TREE_TYPE (t);
+ parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
+
+ if (DECL_CLASS_SCOPE_P (t))
+ cname = DECL_CONTEXT (t);
+ /* This is for partially instantiated template methods. */
+ else if (TREE_CODE (fntype) == METHOD_TYPE)
+ cname = TREE_TYPE (TREE_VALUE (parmtypes));
+
+ if (flags & TFF_DECL_SPECIFIERS)
+ {
+ if (DECL_STATIC_FUNCTION_P (t))
+ pp_cxx_ws_string (pp, "static");
+ else if (DECL_VIRTUAL_P (t))
+ pp_cxx_ws_string (pp, "virtual");
+
+ if (DECL_DECLARED_CONSTEXPR_P (t))
+ pp_cxx_ws_string (pp, "constexpr");
+ }
+
+ /* Print the return type? */
+ if (show_return)
+ show_return = !DECL_CONV_FN_P (t) && !DECL_CONSTRUCTOR_P (t)
+ && !DECL_DESTRUCTOR_P (t);
+ if (show_return)
+ {
+ tree ret = fndecl_declared_return_type (t);
+ dump_type_prefix (pp, ret, flags);
+ }
+
+ /* Print the function name. */
+ if (!do_outer_scope)
+ /* Nothing. */;
+ else if (cname)
+ {
+ dump_type (pp, cname, flags);
+ pp_cxx_colon_colon (pp);
+ }
+ else
+ dump_scope (pp, CP_DECL_CONTEXT (t), flags);
+
+ dump_function_name (pp, t, flags);
+
+ if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
+ {
+ dump_parameters (pp, parmtypes, flags);
+
+ if (TREE_CODE (fntype) == METHOD_TYPE)
+ {
+ pp->padding = pp_before;
+ pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (fntype));
+ dump_ref_qualifier (pp, fntype, flags);
+ }
+
+ if (flags & TFF_EXCEPTION_SPECIFICATION)
+ {
+ pp->padding = pp_before;
+ dump_exception_spec (pp, exceptions, flags);
+ }
+
+ if (show_return)
+ dump_type_suffix (pp, TREE_TYPE (fntype), flags);
+
+ dump_substitution (pp, t, template_parms, template_args, flags);
+ }
+ else if (template_args)
+ {
+ bool need_comma = false;
+ int i;
+ pp_cxx_begin_template_argument_list (pp);
+ template_args = INNERMOST_TEMPLATE_ARGS (template_args);
+ for (i = 0; i < TREE_VEC_LENGTH (template_args); ++i)
+ {
+ tree arg = TREE_VEC_ELT (template_args, i);
+ if (need_comma)
+ pp_separate_with_comma (pp);
+ if (ARGUMENT_PACK_P (arg))
+ pp_cxx_left_brace (pp);
+ dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER);
+ if (ARGUMENT_PACK_P (arg))
+ pp_cxx_right_brace (pp);
+ need_comma = true;
+ }
+ pp_cxx_end_template_argument_list (pp);
+ }
+}
+
+/* Print a parameter list. If this is for a member function, the
+ member object ptr (and any other hidden args) should have
+ already been removed. */
+
+static void
+dump_parameters (cxx_pretty_printer *pp, tree parmtypes, int flags)
+{
+ int first = 1;
+ flags &= ~TFF_SCOPE;
+ pp_cxx_left_paren (pp);
+
+ for (first = 1; parmtypes != void_list_node;
+ parmtypes = TREE_CHAIN (parmtypes))
+ {
+ if (!first)
+ pp_separate_with_comma (pp);
+ first = 0;
+ if (!parmtypes)
+ {
+ pp_cxx_ws_string (pp, "...");
+ break;
+ }
+
+ dump_type (pp, TREE_VALUE (parmtypes), flags);
+
+ if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes))
+ {
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
+ dump_expr (pp, TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS);
+ }
+ }
+
+ pp_cxx_right_paren (pp);
+}
+
+/* Print ref-qualifier of a FUNCTION_TYPE or METHOD_TYPE. FLAGS are ignored. */
+
+static void
+dump_ref_qualifier (cxx_pretty_printer *pp, tree t, int flags ATTRIBUTE_UNUSED)
+{
+ if (FUNCTION_REF_QUALIFIED (t))
+ {
+ pp->padding = pp_before;
+ if (FUNCTION_RVALUE_QUALIFIED (t))
+ pp_cxx_ws_string (pp, "&&");
+ else
+ pp_cxx_ws_string (pp, "&");
+ }
+}
+
+/* Print an exception specification. T is the exception specification. */
+
+static void
+dump_exception_spec (cxx_pretty_printer *pp, tree t, int flags)
+{
+ if (t && TREE_PURPOSE (t))
+ {
+ pp_cxx_ws_string (pp, "noexcept");
+ if (!integer_onep (TREE_PURPOSE (t)))
+ {
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ if (DEFERRED_NOEXCEPT_SPEC_P (t))
+ pp_cxx_ws_string (pp, "<uninstantiated>");
+ else
+ dump_expr (pp, TREE_PURPOSE (t), flags);
+ pp_cxx_right_paren (pp);
+ }
+ }
+ else if (t)
+ {
+ pp_cxx_ws_string (pp, "throw");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ if (TREE_VALUE (t) != NULL_TREE)
+ while (1)
+ {
+ dump_type (pp, TREE_VALUE (t), flags);
+ t = TREE_CHAIN (t);
+ if (!t)
+ break;
+ pp_separate_with_comma (pp);
+ }
+ pp_cxx_right_paren (pp);
+ }
+}
+
+/* Handle the function name for a FUNCTION_DECL node, grokking operators
+ and destructors properly. */
+
+static void
+dump_function_name (cxx_pretty_printer *pp, tree t, int flags)
+{
+ tree name = DECL_NAME (t);
+
+ /* We can get here with a decl that was synthesized by language-
+ independent machinery (e.g. coverage.c) in which case it won't
+ have a lang_specific structure attached and DECL_CONSTRUCTOR_P
+ will crash. In this case it is safe just to print out the
+ literal name. */
+ if (!DECL_LANG_SPECIFIC (t))
+ {
+ pp_cxx_tree_identifier (pp, name);
+ return;
+ }
+
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ t = DECL_TEMPLATE_RESULT (t);
+
+ /* Don't let the user see __comp_ctor et al. */
+ if (DECL_CONSTRUCTOR_P (t)
+ || DECL_DESTRUCTOR_P (t))
+ {
+ if (LAMBDA_TYPE_P (DECL_CONTEXT (t)))
+ name = get_identifier ("<lambda>");
+ else if (TYPE_ANONYMOUS_P (DECL_CONTEXT (t)))
+ name = get_identifier ("<constructor>");
+ else
+ name = constructor_name (DECL_CONTEXT (t));
+ }
+
+ if (DECL_DESTRUCTOR_P (t))
+ {
+ pp_cxx_complement (pp);
+ dump_decl (pp, name, TFF_PLAIN_IDENTIFIER);
+ }
+ else if (DECL_CONV_FN_P (t))
+ {
+ /* This cannot use the hack that the operator's return
+ type is stashed off of its name because it may be
+ used for error reporting. In the case of conflicting
+ declarations, both will have the same name, yet
+ the types will be different, hence the TREE_TYPE field
+ of the first name will be clobbered by the second. */
+ pp_cxx_ws_string (pp, "operator");
+ dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
+ }
+ else if (name && IDENTIFIER_OPNAME_P (name))
+ pp_cxx_tree_identifier (pp, name);
+ else if (name && UDLIT_OPER_P (name))
+ pp_cxx_tree_identifier (pp, name);
+ else
+ dump_decl (pp, name, flags);
+
+ if (DECL_TEMPLATE_INFO (t)
+ && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
+ && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
+ || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
+ dump_template_parms (pp, DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t),
+ flags);
+}
+
+/* Dump the template parameters from the template info INFO under control of
+ FLAGS. PRIMARY indicates whether this is a primary template decl, or
+ specialization (partial or complete). For partial specializations we show
+ the specialized parameter values. For a primary template we show no
+ decoration. */
+
+static void
+dump_template_parms (cxx_pretty_printer *pp, tree info,
+ int primary, int flags)
+{
+ tree args = info ? TI_ARGS (info) : NULL_TREE;
+
+ if (primary && flags & TFF_TEMPLATE_NAME)
+ return;
+ flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME);
+ pp_cxx_begin_template_argument_list (pp);
+
+ /* Be careful only to print things when we have them, so as not
+ to crash producing error messages. */
+ if (args && !primary)
+ {
+ int len, ix;
+ len = get_non_default_template_args_count (args, flags);
+
+ args = INNERMOST_TEMPLATE_ARGS (args);
+ for (ix = 0; ix != len; ix++)
+ {
+ tree arg = TREE_VEC_ELT (args, ix);
+
+ /* Only print a comma if we know there is an argument coming. In
+ the case of an empty template argument pack, no actual
+ argument will be printed. */
+ if (ix
+ && (!ARGUMENT_PACK_P (arg)
+ || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
+ pp_separate_with_comma (pp);
+
+ if (!arg)
+ pp_string (pp, M_("<template parameter error>"));
+ else
+ dump_template_argument (pp, arg, flags);
+ }
+ }
+ else if (primary)
+ {
+ tree tpl = TI_TEMPLATE (info);
+ tree parms = DECL_TEMPLATE_PARMS (tpl);
+ int len, ix;
+
+ parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE;
+ len = parms ? TREE_VEC_LENGTH (parms) : 0;
+
+ for (ix = 0; ix != len; ix++)
+ {
+ tree parm;
+
+ if (TREE_VEC_ELT (parms, ix) == error_mark_node)
+ {
+ pp_string (pp, M_("<template parameter error>"));
+ continue;
+ }
+
+ parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
+
+ if (ix)
+ pp_separate_with_comma (pp);
+
+ dump_decl (pp, parm, flags & ~TFF_DECL_SPECIFIERS);
+ }
+ }
+ pp_cxx_end_template_argument_list (pp);
+}
+
+/* Print out the arguments of CALL_EXPR T as a parenthesized list using
+ flags FLAGS. Skip over the first argument if SKIPFIRST is true. */
+
+static void
+dump_call_expr_args (cxx_pretty_printer *pp, tree t, int flags, bool skipfirst)
+{
+ tree arg;
+ call_expr_arg_iterator iter;
+
+ pp_cxx_left_paren (pp);
+ FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
+ {
+ if (skipfirst)
+ skipfirst = false;
+ else
+ {
+ dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS);
+ if (more_call_expr_args_p (&iter))
+ pp_separate_with_comma (pp);
+ }
+ }
+ pp_cxx_right_paren (pp);
+}
+
+/* Print out the arguments of AGGR_INIT_EXPR T as a parenthesized list
+ using flags FLAGS. Skip over the first argument if SKIPFIRST is
+ true. */
+
+static void
+dump_aggr_init_expr_args (cxx_pretty_printer *pp, tree t, int flags,
+ bool skipfirst)
+{
+ tree arg;
+ aggr_init_expr_arg_iterator iter;
+
+ pp_cxx_left_paren (pp);
+ FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
+ {
+ if (skipfirst)
+ skipfirst = false;
+ else
+ {
+ dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS);
+ if (more_aggr_init_expr_args_p (&iter))
+ pp_separate_with_comma (pp);
+ }
+ }
+ pp_cxx_right_paren (pp);
+}
+
+/* Print out a list of initializers (subr of dump_expr). */
+
+static void
+dump_expr_list (cxx_pretty_printer *pp, tree l, int flags)
+{
+ while (l)
+ {
+ dump_expr (pp, TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS);
+ l = TREE_CHAIN (l);
+ if (l)
+ pp_separate_with_comma (pp);
+ }
+}
+
+/* Print out a vector of initializers (subr of dump_expr). */
+
+static void
+dump_expr_init_vec (cxx_pretty_printer *pp, vec<constructor_elt, va_gc> *v,
+ int flags)
+{
+ unsigned HOST_WIDE_INT idx;
+ tree value;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
+ {
+ dump_expr (pp, value, flags | TFF_EXPR_IN_PARENS);
+ if (idx != v->length () - 1)
+ pp_separate_with_comma (pp);
+ }
+}
+
+
+/* We've gotten an indirect REFERENCE (an OBJ_TYPE_REF) to a virtual
+ function. Resolve it to a close relative -- in the sense of static
+ type -- variant being overridden. That is close to what was written in
+ the source code. Subroutine of dump_expr. */
+
+static tree
+resolve_virtual_fun_from_obj_type_ref (tree ref)
+{
+ tree obj_type = TREE_TYPE (OBJ_TYPE_REF_OBJECT (ref));
+ HOST_WIDE_INT index = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (ref));
+ tree fun = BINFO_VIRTUALS (TYPE_BINFO (TREE_TYPE (obj_type)));
+ while (index)
+ {
+ fun = TREE_CHAIN (fun);
+ index -= (TARGET_VTABLE_USES_DESCRIPTORS
+ ? TARGET_VTABLE_USES_DESCRIPTORS : 1);
+ }
+
+ return BV_FN (fun);
+}
+
+/* Print out an expression E under control of FLAGS. */
+
+static void
+dump_expr (cxx_pretty_printer *pp, tree t, int flags)
+{
+ tree op;
+
+ if (t == 0)
+ return;
+
+ if (STATEMENT_CLASS_P (t))
+ {
+ pp_cxx_ws_string (pp, M_("<statement>"));
+ return;
+ }
+
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ case CONST_DECL:
+ case FUNCTION_DECL:
+ case TEMPLATE_DECL:
+ case NAMESPACE_DECL:
+ case LABEL_DECL:
+ case OVERLOAD:
+ case TYPE_DECL:
+ case IDENTIFIER_NODE:
+ dump_decl (pp, t, ((flags & ~(TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE
+ |TFF_TEMPLATE_HEADER))
+ | TFF_NO_FUNCTION_ARGUMENTS));
+ break;
+
+ case SSA_NAME:
+ if (SSA_NAME_VAR (t)
+ && !DECL_ARTIFICIAL (SSA_NAME_VAR (t)))
+ dump_expr (pp, SSA_NAME_VAR (t), flags);
+ else
+ pp_cxx_ws_string (pp, M_("<unknown>"));
+ break;
+
+ case INTEGER_CST:
+ case REAL_CST:
+ case STRING_CST:
+ case COMPLEX_CST:
+ pp->constant (t);
+ break;
+
+ case USERDEF_LITERAL:
+ pp_cxx_userdef_literal (pp, t);
+ break;
+
+ case THROW_EXPR:
+ /* While waiting for caret diagnostics, avoid printing
+ __cxa_allocate_exception, __cxa_throw, and the like. */
+ pp_cxx_ws_string (pp, M_("<throw-expression>"));
+ break;
+
+ case PTRMEM_CST:
+ pp_ampersand (pp);
+ dump_type (pp, PTRMEM_CST_CLASS (t), flags);
+ pp_cxx_colon_colon (pp);
+ pp_cxx_tree_identifier (pp, DECL_NAME (PTRMEM_CST_MEMBER (t)));
+ break;
+
+ case COMPOUND_EXPR:
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_separate_with_comma (pp);
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
+ break;
+
+ case COND_EXPR:
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_string (pp, " ? ");
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ pp_string (pp, " : ");
+ dump_expr (pp, TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
+ break;
+
+ case SAVE_EXPR:
+ if (TREE_HAS_CONSTRUCTOR (t))
+ {
+ pp_cxx_ws_string (pp, "new");
+ pp_cxx_whitespace (pp);
+ dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
+ }
+ else
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ break;
+
+ case AGGR_INIT_EXPR:
+ {
+ tree fn = NULL_TREE;
+
+ if (TREE_CODE (AGGR_INIT_EXPR_FN (t)) == ADDR_EXPR)
+ fn = TREE_OPERAND (AGGR_INIT_EXPR_FN (t), 0);
+
+ if (fn && TREE_CODE (fn) == FUNCTION_DECL)
+ {
+ if (DECL_CONSTRUCTOR_P (fn))
+ dump_type (pp, DECL_CONTEXT (fn), flags);
+ else
+ dump_decl (pp, fn, 0);
+ }
+ else
+ dump_expr (pp, AGGR_INIT_EXPR_FN (t), 0);
+ }
+ dump_aggr_init_expr_args (pp, t, flags, true);
+ break;
+
+ case CALL_EXPR:
+ {
+ tree fn = CALL_EXPR_FN (t);
+ bool skipfirst = false;
+
+ if (TREE_CODE (fn) == ADDR_EXPR)
+ fn = TREE_OPERAND (fn, 0);
+
+ /* Nobody is interested in seeing the guts of vcalls. */
+ if (TREE_CODE (fn) == OBJ_TYPE_REF)
+ fn = resolve_virtual_fun_from_obj_type_ref (fn);
+
+ if (TREE_TYPE (fn) != NULL_TREE
+ && NEXT_CODE (fn) == METHOD_TYPE
+ && call_expr_nargs (t))
+ {
+ tree ob = CALL_EXPR_ARG (t, 0);
+ if (TREE_CODE (ob) == ADDR_EXPR)
+ {
+ dump_expr (pp, TREE_OPERAND (ob, 0),
+ flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_dot (pp);
+ }
+ else if (TREE_CODE (ob) != PARM_DECL
+ || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
+ {
+ dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_arrow (pp);
+ }
+ skipfirst = true;
+ }
+ if (flag_sanitize & SANITIZE_UNDEFINED
+ && is_ubsan_builtin_p (fn))
+ {
+ pp_string (cxx_pp, M_("<ubsan routine call>"));
+ break;
+ }
+ dump_expr (pp, fn, flags | TFF_EXPR_IN_PARENS);
+ dump_call_expr_args (pp, t, flags, skipfirst);
+ }
+ break;
+
+ case TARGET_EXPR:
+ /* Note that this only works for G++ target exprs. If somebody
+ builds a general TARGET_EXPR, there's no way to represent that
+ it initializes anything other that the parameter slot for the
+ default argument. Note we may have cleared out the first
+ operand in expand_expr, so don't go killing ourselves. */
+ if (TREE_OPERAND (t, 1))
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ break;
+
+ case POINTER_PLUS_EXPR:
+ dump_binary_op (pp, "+", t, flags);
+ break;
+
+ case INIT_EXPR:
+ case MODIFY_EXPR:
+ dump_binary_op (pp, assignment_operator_name_info[NOP_EXPR].name,
+ t, flags);
+ break;
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ case MIN_EXPR:
+ case MAX_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case BIT_AND_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case EXACT_DIV_EXPR:
+ dump_binary_op (pp, operator_name_info[TREE_CODE (t)].name, t, flags);
+ break;
+
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case RDIV_EXPR:
+ dump_binary_op (pp, "/", t, flags);
+ break;
+
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ dump_binary_op (pp, "%", t, flags);
+ break;
+
+ case COMPONENT_REF:
+ {
+ tree ob = TREE_OPERAND (t, 0);
+ if (INDIRECT_REF_P (ob))
+ {
+ ob = TREE_OPERAND (ob, 0);
+ if (TREE_CODE (ob) != PARM_DECL
+ || (DECL_NAME (ob)
+ && strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")))
+ {
+ dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
+ if (TREE_CODE (TREE_TYPE (ob)) == REFERENCE_TYPE)
+ pp_cxx_dot (pp);
+ else
+ pp_cxx_arrow (pp);
+ }
+ }
+ else
+ {
+ dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_dot (pp);
+ }
+ dump_expr (pp, TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
+ }
+ break;
+
+ case ARRAY_REF:
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_left_bracket (pp);
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_bracket (pp);
+ break;
+
+ case ARRAY_NOTATION_REF:
+ dump_expr (pp, ARRAY_NOTATION_ARRAY (t), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_left_bracket (pp);
+ dump_expr (pp, ARRAY_NOTATION_START (t), flags | TFF_EXPR_IN_PARENS);
+ pp_colon (pp);
+ dump_expr (pp, ARRAY_NOTATION_LENGTH (t), flags | TFF_EXPR_IN_PARENS);
+ pp_colon (pp);
+ dump_expr (pp, ARRAY_NOTATION_STRIDE (t), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_bracket (pp);
+ break;
+
+ case UNARY_PLUS_EXPR:
+ dump_unary_op (pp, "+", t, flags);
+ break;
+
+ case ADDR_EXPR:
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
+ || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST
+ /* An ADDR_EXPR can have reference type. In that case, we
+ shouldn't print the `&' doing so indicates to the user
+ that the expression has pointer type. */
+ || (TREE_TYPE (t)
+ && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE))
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL)
+ dump_unary_op (pp, "&&", t, flags);
+ else
+ dump_unary_op (pp, "&", t, flags);
+ break;
+
+ case INDIRECT_REF:
+ if (TREE_HAS_CONSTRUCTOR (t))
+ {
+ t = TREE_OPERAND (t, 0);
+ gcc_assert (TREE_CODE (t) == CALL_EXPR);
+ dump_expr (pp, CALL_EXPR_FN (t), flags | TFF_EXPR_IN_PARENS);
+ dump_call_expr_args (pp, t, flags, true);
+ }
+ else
+ {
+ if (TREE_OPERAND (t,0) != NULL_TREE
+ && TREE_TYPE (TREE_OPERAND (t, 0))
+ && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ else
+ dump_unary_op (pp, "*", t, flags);
+ }
+ break;
+
+ case MEM_REF:
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
+ && integer_zerop (TREE_OPERAND (t, 1)))
+ dump_expr (pp, TREE_OPERAND (TREE_OPERAND (t, 0), 0), flags);
+ else
+ {
+ pp_cxx_star (pp);
+ if (!integer_zerop (TREE_OPERAND (t, 1)))
+ {
+ pp_cxx_left_paren (pp);
+ if (!integer_onep (TYPE_SIZE_UNIT
+ (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))))))
+ {
+ pp_cxx_left_paren (pp);
+ dump_type (pp, ptr_type_node, flags);
+ pp_cxx_right_paren (pp);
+ }
+ }
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ if (!integer_zerop (TREE_OPERAND (t, 1)))
+ {
+ pp_cxx_ws_string (pp, "+");
+ dump_expr (pp, fold_convert (ssizetype, TREE_OPERAND (t, 1)),
+ flags);
+ pp_cxx_right_paren (pp);
+ }
+ }
+ break;
+
+ case NEGATE_EXPR:
+ case BIT_NOT_EXPR:
+ case TRUTH_NOT_EXPR:
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ dump_unary_op (pp, operator_name_info [TREE_CODE (t)].name, t, flags);
+ break;
+
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_ws_string (pp, operator_name_info[TREE_CODE (t)].name);
+ pp_cxx_right_paren (pp);
+ break;
+
+ case NON_LVALUE_EXPR:
+ /* FIXME: This is a KLUDGE workaround for a parsing problem. There
+ should be another level of INDIRECT_REF so that I don't have to do
+ this. */
+ if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)
+ {
+ tree next = TREE_TYPE (TREE_TYPE (t));
+
+ while (TYPE_PTR_P (next))
+ next = TREE_TYPE (next);
+
+ if (TREE_CODE (next) == FUNCTION_TYPE)
+ {
+ if (flags & TFF_EXPR_IN_PARENS)
+ pp_cxx_left_paren (pp);
+ pp_cxx_star (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ if (flags & TFF_EXPR_IN_PARENS)
+ pp_cxx_right_paren (pp);
+ break;
+ }
+ /* Else fall through. */
+ }
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ break;
+
+ CASE_CONVERT:
+ case IMPLICIT_CONV_EXPR:
+ case VIEW_CONVERT_EXPR:
+ {
+ tree op = TREE_OPERAND (t, 0);
+ tree ttype = TREE_TYPE (t);
+ tree optype = TREE_TYPE (op);
+
+ if (TREE_CODE (ttype) != TREE_CODE (optype)
+ && POINTER_TYPE_P (ttype)
+ && POINTER_TYPE_P (optype)
+ && same_type_p (TREE_TYPE (optype),
+ TREE_TYPE (ttype)))
+ {
+ if (TREE_CODE (ttype) == REFERENCE_TYPE)
+ dump_unary_op (pp, "*", t, flags);
+ else
+ dump_unary_op (pp, "&", t, flags);
+ }
+ else if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t)))
+ {
+ /* It is a cast, but we cannot tell whether it is a
+ reinterpret or static cast. Use the C style notation. */
+ if (flags & TFF_EXPR_IN_PARENS)
+ pp_cxx_left_paren (pp);
+ pp_cxx_left_paren (pp);
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_right_paren (pp);
+ dump_expr (pp, op, flags | TFF_EXPR_IN_PARENS);
+ if (flags & TFF_EXPR_IN_PARENS)
+ pp_cxx_right_paren (pp);
+ }
+ else
+ dump_expr (pp, op, flags);
+ break;
+ }
+
+ case CONSTRUCTOR:
+ if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
+ {
+ tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier);
+
+ if (integer_zerop (idx))
+ {
+ /* A NULL pointer-to-member constant. */
+ pp_cxx_left_paren (pp);
+ pp_cxx_left_paren (pp);
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_right_paren (pp);
+ pp_character (pp, '0');
+ pp_cxx_right_paren (pp);
+ break;
+ }
+ else if (tree_fits_shwi_p (idx))
+ {
+ tree virtuals;
+ unsigned HOST_WIDE_INT n;
+
+ t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
+ t = TYPE_METHOD_BASETYPE (t);
+ virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t)));
+
+ n = tree_to_shwi (idx);
+
+ /* Map vtable index back one, to allow for the null pointer to
+ member. */
+ --n;
+
+ while (n > 0 && virtuals)
+ {
+ --n;
+ virtuals = TREE_CHAIN (virtuals);
+ }
+ if (virtuals)
+ {
+ dump_expr (pp, BV_FN (virtuals),
+ flags | TFF_EXPR_IN_PARENS);
+ break;
+ }
+ }
+ }
+ if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t)))
+ pp_string (pp, "<lambda closure object>");
+ if (TREE_TYPE (t) && EMPTY_CONSTRUCTOR_P (t))
+ {
+ dump_type (pp, TREE_TYPE (t), 0);
+ pp_cxx_left_paren (pp);
+ pp_cxx_right_paren (pp);
+ }
+ else
+ {
+ if (!BRACE_ENCLOSED_INITIALIZER_P (t))
+ dump_type (pp, TREE_TYPE (t), 0);
+ pp_cxx_left_brace (pp);
+ dump_expr_init_vec (pp, CONSTRUCTOR_ELTS (t), flags);
+ pp_cxx_right_brace (pp);
+ }
+
+ break;
+
+ case OFFSET_REF:
+ {
+ tree ob = TREE_OPERAND (t, 0);
+ if (is_dummy_object (ob))
+ {
+ t = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ /* A::f */
+ dump_expr (pp, t, flags | TFF_EXPR_IN_PARENS);
+ else if (BASELINK_P (t))
+ dump_expr (pp, OVL_CURRENT (BASELINK_FUNCTIONS (t)),
+ flags | TFF_EXPR_IN_PARENS);
+ else
+ dump_decl (pp, t, flags);
+ }
+ else
+ {
+ if (INDIRECT_REF_P (ob))
+ {
+ dump_expr (pp, TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_arrow (pp);
+ pp_cxx_star (pp);
+ }
+ else
+ {
+ dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_dot (pp);
+ pp_cxx_star (pp);
+ }
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ }
+ break;
+ }
+
+ case TEMPLATE_PARM_INDEX:
+ dump_decl (pp, TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
+ break;
+
+ case CAST_EXPR:
+ if (TREE_OPERAND (t, 0) == NULL_TREE
+ || TREE_CHAIN (TREE_OPERAND (t, 0)))
+ {
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_left_paren (pp);
+ dump_expr_list (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (pp);
+ }
+ else
+ {
+ pp_cxx_left_paren (pp);
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_right_paren (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr_list (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (pp);
+ }
+ break;
+
+ case STATIC_CAST_EXPR:
+ pp_cxx_ws_string (pp, "static_cast");
+ goto cast;
+ case REINTERPRET_CAST_EXPR:
+ pp_cxx_ws_string (pp, "reinterpret_cast");
+ goto cast;
+ case CONST_CAST_EXPR:
+ pp_cxx_ws_string (pp, "const_cast");
+ goto cast;
+ case DYNAMIC_CAST_EXPR:
+ pp_cxx_ws_string (pp, "dynamic_cast");
+ cast:
+ pp_cxx_begin_template_argument_list (pp);
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_end_template_argument_list (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (pp);
+ break;
+
+ case ARROW_EXPR:
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_arrow (pp);
+ break;
+
+ case SIZEOF_EXPR:
+ case ALIGNOF_EXPR:
+ if (TREE_CODE (t) == SIZEOF_EXPR)
+ pp_cxx_ws_string (pp, "sizeof");
+ else
+ {
+ gcc_assert (TREE_CODE (t) == ALIGNOF_EXPR);
+ pp_cxx_ws_string (pp, "__alignof__");
+ }
+ op = TREE_OPERAND (t, 0);
+ if (PACK_EXPANSION_P (op))
+ {
+ pp_string (pp, "...");
+ op = PACK_EXPANSION_PATTERN (op);
+ }
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
+ dump_type (pp, TREE_TYPE (op), flags);
+ else if (TYPE_P (TREE_OPERAND (t, 0)))
+ dump_type (pp, op, flags);
+ else
+ dump_expr (pp, op, flags);
+ pp_cxx_right_paren (pp);
+ break;
+
+ case AT_ENCODE_EXPR:
+ pp_cxx_ws_string (pp, "@encode");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ dump_type (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (pp);
+ break;
+
+ case NOEXCEPT_EXPR:
+ pp_cxx_ws_string (pp, "noexcept");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (pp);
+ break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ pp_cxx_ws_string (pp, operator_name_info[TREE_CODE (t)].name);
+ pp_cxx_whitespace (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ break;
+
+ case DEFAULT_ARG:
+ pp_string (pp, M_("<unparsed>"));
+ break;
+
+ case TRY_CATCH_EXPR:
+ case WITH_CLEANUP_EXPR:
+ case CLEANUP_POINT_EXPR:
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ break;
+
+ case PSEUDO_DTOR_EXPR:
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_dot (pp);
+ if (TREE_OPERAND (t, 1))
+ {
+ dump_type (pp, TREE_OPERAND (t, 1), flags);
+ pp_cxx_colon_colon (pp);
+ }
+ pp_cxx_complement (pp);
+ dump_type (pp, TREE_OPERAND (t, 2), flags);
+ break;
+
+ case TEMPLATE_ID_EXPR:
+ dump_decl (pp, t, flags);
+ break;
+
+ case BIND_EXPR:
+ case STMT_EXPR:
+ case EXPR_STMT:
+ case STATEMENT_LIST:
+ /* We don't yet have a way of dumping statements in a
+ human-readable format. */
+ pp_string (pp, "({...})");
+ break;
+
+ case LOOP_EXPR:
+ pp_string (pp, "while (1) { ");
+ dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ pp_cxx_right_brace (pp);
+ break;
+
+ case EXIT_EXPR:
+ pp_string (pp, "if (");
+ dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ pp_string (pp, ") break; ");
+ break;
+
+ case BASELINK:
+ dump_expr (pp, BASELINK_FUNCTIONS (t), flags & ~TFF_EXPR_IN_PARENS);
+ break;
+
+ case EMPTY_CLASS_EXPR:
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_left_paren (pp);
+ pp_cxx_right_paren (pp);
+ break;
+
+ case NON_DEPENDENT_EXPR:
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ break;
+
+ case ARGUMENT_PACK_SELECT:
+ dump_template_argument (pp, ARGUMENT_PACK_SELECT_FROM_PACK (t), flags);
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ case REAL_TYPE:
+ case VOID_TYPE:
+ case BOOLEAN_TYPE:
+ case INTEGER_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ pp_type_specifier_seq (pp, t);
+ break;
+
+ case TYPENAME_TYPE:
+ /* We get here when we want to print a dependent type as an
+ id-expression, without any disambiguator decoration. */
+ pp->id_expression (t);
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ dump_type (pp, t, flags);
+ break;
+
+ case TRAIT_EXPR:
+ pp_cxx_trait_expression (pp, t);
+ break;
+
+ case VA_ARG_EXPR:
+ pp_cxx_va_arg_expression (pp, t);
+ break;
+
+ case OFFSETOF_EXPR:
+ pp_cxx_offsetof_expression (pp, t);
+ break;
+
+ case SCOPE_REF:
+ dump_decl (pp, t, flags);
+ break;
+
+ case EXPR_PACK_EXPANSION:
+ case TYPEID_EXPR:
+ case MEMBER_REF:
+ case DOTSTAR_EXPR:
+ case NEW_EXPR:
+ case VEC_NEW_EXPR:
+ case DELETE_EXPR:
+ case VEC_DELETE_EXPR:
+ case MODOP_EXPR:
+ case ABS_EXPR:
+ case CONJ_EXPR:
+ case VECTOR_CST:
+ case FIXED_CST:
+ case UNORDERED_EXPR:
+ case ORDERED_EXPR:
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ case LTGT_EXPR:
+ case COMPLEX_EXPR:
+ case BIT_FIELD_REF:
+ case FIX_TRUNC_EXPR:
+ case FLOAT_EXPR:
+ pp->expression (t);
+ break;
+
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case TRUTH_XOR_EXPR:
+ if (flags & TFF_EXPR_IN_PARENS)
+ pp_cxx_left_paren (pp);
+ pp->expression (t);
+ if (flags & TFF_EXPR_IN_PARENS)
+ pp_cxx_right_paren (pp);
+ break;
+
+ case OBJ_TYPE_REF:
+ dump_expr (pp, resolve_virtual_fun_from_obj_type_ref (t), flags);
+ break;
+
+ case LAMBDA_EXPR:
+ pp_string (pp, M_("<lambda>"));
+ break;
+
+ case PAREN_EXPR:
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
+ break;
+
+ /* This list is incomplete, but should suffice for now.
+ It is very important that `sorry' does not call
+ `report_error_function'. That could cause an infinite loop. */
+ default:
+ pp_unsupported_tree (pp, t);
+ /* fall through to ERROR_MARK... */
+ case ERROR_MARK:
+ pp_string (pp, M_("<expression error>"));
+ break;
+ }
+}
+
+static void
+dump_binary_op (cxx_pretty_printer *pp, const char *opstring, tree t,
+ int flags)
+{
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_whitespace (pp);
+ if (opstring)
+ pp_cxx_ws_string (pp, opstring);
+ else
+ pp_string (pp, M_("<unknown operator>"));
+ pp_cxx_whitespace (pp);
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
+}
+
+static void
+dump_unary_op (cxx_pretty_printer *pp, const char *opstring, tree t, int flags)
+{
+ if (flags & TFF_EXPR_IN_PARENS)
+ pp_cxx_left_paren (pp);
+ pp_cxx_ws_string (pp, opstring);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ if (flags & TFF_EXPR_IN_PARENS)
+ pp_cxx_right_paren (pp);
+}
+
+static void
+reinit_cxx_pp (void)
+{
+ pp_clear_output_area (cxx_pp);
+ cxx_pp->padding = pp_none;
+ pp_indentation (cxx_pp) = 0;
+ pp_needs_newline (cxx_pp) = false;
+ cxx_pp->enclosing_scope = current_function_decl;
+}
+
+/* Same as pp_formatted_text, except the return string is a separate
+ copy and has a GGC storage duration, e.g. an indefinite lifetime. */
+
+inline const char *
+pp_ggc_formatted_text (pretty_printer *pp)
+{
+ return ggc_strdup (pp_formatted_text (pp));
+}
+
+/* Exported interface to stringifying types, exprs and decls under TFF_*
+ control. */
+
+const char *
+type_as_string (tree typ, int flags)
+{
+ reinit_cxx_pp ();
+ pp_translate_identifiers (cxx_pp) = false;
+ dump_type (cxx_pp, typ, flags);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+const char *
+type_as_string_translate (tree typ, int flags)
+{
+ reinit_cxx_pp ();
+ dump_type (cxx_pp, typ, flags);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+const char *
+expr_as_string (tree decl, int flags)
+{
+ reinit_cxx_pp ();
+ pp_translate_identifiers (cxx_pp) = false;
+ dump_expr (cxx_pp, decl, flags);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+/* Wrap decl_as_string with options appropriate for dwarf. */
+
+const char *
+decl_as_dwarf_string (tree decl, int flags)
+{
+ const char *name;
+ /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag
+ here will be adequate to get the desired behaviour. */
+ cxx_pp->flags |= pp_c_flag_gnu_v3;
+ name = decl_as_string (decl, flags);
+ /* Subsequent calls to the pretty printer shouldn't use this style. */
+ cxx_pp->flags &= ~pp_c_flag_gnu_v3;
+ return name;
+}
+
+const char *
+decl_as_string (tree decl, int flags)
+{
+ reinit_cxx_pp ();
+ pp_translate_identifiers (cxx_pp) = false;
+ dump_decl (cxx_pp, decl, flags);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+const char *
+decl_as_string_translate (tree decl, int flags)
+{
+ reinit_cxx_pp ();
+ dump_decl (cxx_pp, decl, flags);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+/* Wrap lang_decl_name with options appropriate for dwarf. */
+
+const char *
+lang_decl_dwarf_name (tree decl, int v, bool translate)
+{
+ const char *name;
+ /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag
+ here will be adequate to get the desired behaviour. */
+ cxx_pp->flags |= pp_c_flag_gnu_v3;
+ name = lang_decl_name (decl, v, translate);
+ /* Subsequent calls to the pretty printer shouldn't use this style. */
+ cxx_pp->flags &= ~pp_c_flag_gnu_v3;
+ return name;
+}
+
+/* Generate the three forms of printable names for cxx_printable_name. */
+
+const char *
+lang_decl_name (tree decl, int v, bool translate)
+{
+ if (v >= 2)
+ return (translate
+ ? decl_as_string_translate (decl, TFF_DECL_SPECIFIERS)
+ : decl_as_string (decl, TFF_DECL_SPECIFIERS));
+
+ reinit_cxx_pp ();
+ pp_translate_identifiers (cxx_pp) = translate;
+ if (v == 1
+ && (DECL_CLASS_SCOPE_P (decl)
+ || (DECL_NAMESPACE_SCOPE_P (decl)
+ && CP_DECL_CONTEXT (decl) != global_namespace)))
+ {
+ dump_type (cxx_pp, CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER);
+ pp_cxx_colon_colon (cxx_pp);
+ }
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ dump_function_name (cxx_pp, decl, TFF_PLAIN_IDENTIFIER);
+ else if ((DECL_NAME (decl) == NULL_TREE)
+ && TREE_CODE (decl) == NAMESPACE_DECL)
+ dump_decl (cxx_pp, decl, TFF_PLAIN_IDENTIFIER | TFF_UNQUALIFIED_NAME);
+ else
+ dump_decl (cxx_pp, DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
+
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+/* Return the location of a tree passed to %+ formats. */
+
+location_t
+location_of (tree t)
+{
+ if (TYPE_P (t))
+ {
+ t = TYPE_MAIN_DECL (t);
+ if (t == NULL_TREE)
+ return input_location;
+ }
+ else if (TREE_CODE (t) == OVERLOAD)
+ t = OVL_FUNCTION (t);
+
+ if (DECL_P (t))
+ return DECL_SOURCE_LOCATION (t);
+ return EXPR_LOC_OR_LOC (t, input_location);
+}
+
+/* Now the interfaces from error et al to dump_type et al. Each takes an
+ on/off VERBOSE flag and supply the appropriate TFF_ flags to a dump_
+ function. */
+
+static const char *
+decl_to_string (tree decl, int verbose)
+{
+ int flags = 0;
+
+ if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE
+ || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE)
+ flags = TFF_CLASS_KEY_OR_ENUM;
+ if (verbose)
+ flags |= TFF_DECL_SPECIFIERS;
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE;
+ flags |= TFF_TEMPLATE_HEADER;
+
+ reinit_cxx_pp ();
+ dump_decl (cxx_pp, decl, flags);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+static const char *
+expr_to_string (tree decl)
+{
+ reinit_cxx_pp ();
+ dump_expr (cxx_pp, decl, 0);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+static const char *
+fndecl_to_string (tree fndecl, int verbose)
+{
+ int flags;
+
+ flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS
+ | TFF_TEMPLATE_HEADER;
+ if (verbose)
+ flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS;
+ reinit_cxx_pp ();
+ dump_decl (cxx_pp, fndecl, flags);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+
+static const char *
+code_to_string (enum tree_code c)
+{
+ return get_tree_code_name (c);
+}
+
+const char *
+language_to_string (enum languages c)
+{
+ switch (c)
+ {
+ case lang_c:
+ return "C";
+
+ case lang_cplusplus:
+ return "C++";
+
+ case lang_java:
+ return "Java";
+
+ default:
+ gcc_unreachable ();
+ }
+ return NULL;
+}
+
+/* Return the proper printed version of a parameter to a C++ function. */
+
+static const char *
+parm_to_string (int p)
+{
+ reinit_cxx_pp ();
+ if (p < 0)
+ pp_string (cxx_pp, "'this'");
+ else
+ pp_decimal_int (cxx_pp, p + 1);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+static const char *
+op_to_string (enum tree_code p)
+{
+ tree id = operator_name_info[p].identifier;
+ return id ? IDENTIFIER_POINTER (id) : M_("<unknown>");
+}
+
+static const char *
+type_to_string (tree typ, int verbose)
+{
+ int flags = 0;
+ if (verbose)
+ flags |= TFF_CLASS_KEY_OR_ENUM;
+ flags |= TFF_TEMPLATE_HEADER;
+
+ reinit_cxx_pp ();
+ dump_type (cxx_pp, typ, flags);
+ /* If we're printing a type that involves typedefs, also print the
+ stripped version. But sometimes the stripped version looks
+ exactly the same, so we don't want it after all. To avoid printing
+ it in that case, we play ugly obstack games. */
+ if (typ && TYPE_P (typ) && typ != TYPE_CANONICAL (typ)
+ && !uses_template_parms (typ))
+ {
+ int aka_start; char *p;
+ struct obstack *ob = pp_buffer (cxx_pp)->obstack;
+ /* Remember the end of the initial dump. */
+ int len = obstack_object_size (ob);
+ tree aka = strip_typedefs (typ);
+ pp_string (cxx_pp, " {aka");
+ pp_cxx_whitespace (cxx_pp);
+ /* And remember the start of the aka dump. */
+ aka_start = obstack_object_size (ob);
+ dump_type (cxx_pp, aka, flags);
+ pp_right_brace (cxx_pp);
+ p = (char*)obstack_base (ob);
+ /* If they are identical, cut off the aka with a NUL. */
+ if (memcmp (p, p+aka_start, len) == 0)
+ p[len] = '\0';
+ }
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+static const char *
+assop_to_string (enum tree_code p)
+{
+ tree id = assignment_operator_name_info[(int) p].identifier;
+ return id ? IDENTIFIER_POINTER (id) : M_("{unknown}");
+}
+
+static const char *
+args_to_string (tree p, int verbose)
+{
+ int flags = 0;
+ if (verbose)
+ flags |= TFF_CLASS_KEY_OR_ENUM;
+
+ if (p == NULL_TREE)
+ return "";
+
+ if (TYPE_P (TREE_VALUE (p)))
+ return type_as_string_translate (p, flags);
+
+ reinit_cxx_pp ();
+ for (; p; p = TREE_CHAIN (p))
+ {
+ if (TREE_VALUE (p) == null_node)
+ pp_cxx_ws_string (cxx_pp, "NULL");
+ else
+ dump_type (cxx_pp, error_type (TREE_VALUE (p)), flags);
+ if (TREE_CHAIN (p))
+ pp_separate_with_comma (cxx_pp);
+ }
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+/* Pretty-print a deduction substitution (from deduction_tsubst_fntype). P
+ is a TREE_LIST with purpose the TEMPLATE_DECL, value the template
+ arguments. */
+
+static const char *
+subst_to_string (tree p)
+{
+ tree decl = TREE_PURPOSE (p);
+ tree targs = TREE_VALUE (p);
+ tree tparms = DECL_TEMPLATE_PARMS (decl);
+ int flags = (TFF_DECL_SPECIFIERS|TFF_TEMPLATE_HEADER
+ |TFF_NO_TEMPLATE_BINDINGS);
+
+ if (p == NULL_TREE)
+ return "";
+
+ reinit_cxx_pp ();
+ dump_template_decl (cxx_pp, TREE_PURPOSE (p), flags);
+ dump_substitution (cxx_pp, NULL, tparms, targs, /*flags=*/0);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+static const char *
+cv_to_string (tree p, int v)
+{
+ reinit_cxx_pp ();
+ cxx_pp->padding = v ? pp_before : pp_none;
+ pp_cxx_cv_qualifier_seq (cxx_pp, p);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+static const char *
+eh_spec_to_string (tree p, int /*v*/)
+{
+ int flags = 0;
+ reinit_cxx_pp ();
+ dump_exception_spec (cxx_pp, p, flags);
+ return pp_ggc_formatted_text (cxx_pp);
+}
+
+/* Langhook for print_error_function. */
+void
+cxx_print_error_function (diagnostic_context *context, const char *file,
+ diagnostic_info *diagnostic)
+{
+ lhd_print_error_function (context, file, diagnostic);
+ pp_set_prefix (context->printer, file);
+ maybe_print_instantiation_context (context);
+}
+
+static void
+cp_diagnostic_starter (diagnostic_context *context,
+ diagnostic_info *diagnostic)
+{
+ diagnostic_report_current_module (context, diagnostic->location);
+ cp_print_error_function (context, diagnostic);
+ maybe_print_instantiation_context (context);
+ maybe_print_constexpr_context (context);
+ pp_set_prefix (context->printer, diagnostic_build_prefix (context,
+ diagnostic));
+}
+
+static void
+cp_diagnostic_finalizer (diagnostic_context *context,
+ diagnostic_info *diagnostic)
+{
+ virt_loc_aware_diagnostic_finalizer (context, diagnostic);
+ pp_destroy_prefix (context->printer);
+}
+
+/* Print current function onto BUFFER, in the process of reporting
+ a diagnostic message. Called from cp_diagnostic_starter. */
+static void
+cp_print_error_function (diagnostic_context *context,
+ diagnostic_info *diagnostic)
+{
+ /* If we are in an instantiation context, current_function_decl is likely
+ to be wrong, so just rely on print_instantiation_full_context. */
+ if (current_instantiation ())
+ return;
+ if (diagnostic_last_function_changed (context, diagnostic))
+ {
+ const char *old_prefix = context->printer->prefix;
+ const char *file = LOCATION_FILE (diagnostic->location);
+ tree abstract_origin = diagnostic_abstract_origin (diagnostic);
+ char *new_prefix = (file && abstract_origin == NULL)
+ ? file_name_as_prefix (context, file) : NULL;
+
+ pp_set_prefix (context->printer, new_prefix);
+
+ if (current_function_decl == NULL)
+ pp_string (context->printer, _("At global scope:"));
+ else
+ {
+ tree fndecl, ao;
+
+ if (abstract_origin)
+ {
+ ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin);
+ while (TREE_CODE (ao) == BLOCK
+ && BLOCK_ABSTRACT_ORIGIN (ao)
+ && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
+ ao = BLOCK_ABSTRACT_ORIGIN (ao);
+ gcc_assert (TREE_CODE (ao) == FUNCTION_DECL);
+ fndecl = ao;
+ }
+ else
+ fndecl = current_function_decl;
+
+ pp_printf (context->printer, function_category (fndecl),
+ cxx_printable_name_translate (fndecl, 2));
+
+ while (abstract_origin)
+ {
+ location_t *locus;
+ tree block = abstract_origin;
+
+ locus = &BLOCK_SOURCE_LOCATION (block);
+ fndecl = NULL;
+ block = BLOCK_SUPERCONTEXT (block);
+ while (block && TREE_CODE (block) == BLOCK
+ && BLOCK_ABSTRACT_ORIGIN (block))
+ {
+ ao = BLOCK_ABSTRACT_ORIGIN (block);
+
+ while (TREE_CODE (ao) == BLOCK
+ && BLOCK_ABSTRACT_ORIGIN (ao)
+ && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
+ ao = BLOCK_ABSTRACT_ORIGIN (ao);
+
+ if (TREE_CODE (ao) == FUNCTION_DECL)
+ {
+ fndecl = ao;
+ break;
+ }
+ else if (TREE_CODE (ao) != BLOCK)
+ break;
+
+ block = BLOCK_SUPERCONTEXT (block);
+ }
+ if (fndecl)
+ abstract_origin = block;
+ else
+ {
+ while (block && TREE_CODE (block) == BLOCK)
+ block = BLOCK_SUPERCONTEXT (block);
+
+ if (block && TREE_CODE (block) == FUNCTION_DECL)
+ fndecl = block;
+ abstract_origin = NULL;
+ }
+ if (fndecl)
+ {
+ expanded_location s = expand_location (*locus);
+ pp_character (context->printer, ',');
+ pp_newline (context->printer);
+ if (s.file != NULL)
+ {
+ if (context->show_column && s.column != 0)
+ pp_printf (context->printer,
+ _(" inlined from %qs at %r%s:%d:%d%R"),
+ cxx_printable_name_translate (fndecl, 2),
+ "locus", s.file, s.line, s.column);
+ else
+ pp_printf (context->printer,
+ _(" inlined from %qs at %r%s:%d%R"),
+ cxx_printable_name_translate (fndecl, 2),
+ "locus", s.file, s.line);
+
+ }
+ else
+ pp_printf (context->printer, _(" inlined from %qs"),
+ cxx_printable_name_translate (fndecl, 2));
+ }
+ }
+ pp_character (context->printer, ':');
+ }
+ pp_newline (context->printer);
+
+ diagnostic_set_last_function (context, diagnostic);
+ pp_destroy_prefix (context->printer);
+ context->printer->prefix = old_prefix;
+ }
+}
+
+/* Returns a description of FUNCTION using standard terminology. The
+ result is a format string of the form "In CATEGORY %qs". */
+static const char *
+function_category (tree fn)
+{
+ /* We can get called from the middle-end for diagnostics of function
+ clones. Make sure we have language specific information before
+ dereferencing it. */
+ if (DECL_LANG_SPECIFIC (STRIP_TEMPLATE (fn))
+ && DECL_FUNCTION_MEMBER_P (fn))
+ {
+ if (DECL_STATIC_FUNCTION_P (fn))
+ return _("In static member function %qs");
+ else if (DECL_COPY_CONSTRUCTOR_P (fn))
+ return _("In copy constructor %qs");
+ else if (DECL_CONSTRUCTOR_P (fn))
+ return _("In constructor %qs");
+ else if (DECL_DESTRUCTOR_P (fn))
+ return _("In destructor %qs");
+ else if (LAMBDA_FUNCTION_P (fn))
+ return _("In lambda function");
+ else
+ return _("In member function %qs");
+ }
+ else
+ return _("In function %qs");
+}
+
+/* Report the full context of a current template instantiation,
+ onto BUFFER. */
+static void
+print_instantiation_full_context (diagnostic_context *context)
+{
+ struct tinst_level *p = current_instantiation ();
+ location_t location = input_location;
+
+ if (p)
+ {
+ pp_verbatim (context->printer,
+ TREE_CODE (p->decl) == TREE_LIST
+ ? _("%s: In substitution of %qS:\n")
+ : _("%s: In instantiation of %q#D:\n"),
+ LOCATION_FILE (location),
+ p->decl);
+
+ location = p->locus;
+ p = p->next;
+ }
+
+ print_instantiation_partial_context (context, p, location);
+}
+
+/* Helper function of print_instantiation_partial_context() that
+ prints a single line of instantiation context. */
+
+static void
+print_instantiation_partial_context_line (diagnostic_context *context,
+ const struct tinst_level *t,
+ location_t loc, bool recursive_p)
+{
+ if (loc == UNKNOWN_LOCATION)
+ return;
+
+ expanded_location xloc = expand_location (loc);
+
+ if (context->show_column)
+ pp_verbatim (context->printer, _("%r%s:%d:%d:%R "),
+ "locus", xloc.file, xloc.line, xloc.column);
+ else
+ pp_verbatim (context->printer, _("%r%s:%d:%R "),
+ "locus", xloc.file, xloc.line);
+
+ if (t != NULL)
+ {
+ if (TREE_CODE (t->decl) == TREE_LIST)
+ pp_verbatim (context->printer,
+ recursive_p
+ ? _("recursively required by substitution of %qS\n")
+ : _("required by substitution of %qS\n"),
+ t->decl);
+ else
+ pp_verbatim (context->printer,
+ recursive_p
+ ? _("recursively required from %q#D\n")
+ : _("required from %q#D\n"),
+ t->decl);
+ }
+ else
+ {
+ pp_verbatim (context->printer,
+ recursive_p
+ ? _("recursively required from here")
+ : _("required from here"));
+ }
+}
+
+/* Same as print_instantiation_full_context but less verbose. */
+
+static void
+print_instantiation_partial_context (diagnostic_context *context,
+ struct tinst_level *t0, location_t loc)
+{
+ struct tinst_level *t;
+ int n_total = 0;
+ int n;
+ location_t prev_loc = loc;
+
+ for (t = t0; t != NULL; t = t->next)
+ if (prev_loc != t->locus)
+ {
+ prev_loc = t->locus;
+ n_total++;
+ }
+
+ t = t0;
+
+ if (template_backtrace_limit
+ && n_total > template_backtrace_limit)
+ {
+ int skip = n_total - template_backtrace_limit;
+ int head = template_backtrace_limit / 2;
+
+ /* Avoid skipping just 1. If so, skip 2. */
+ if (skip == 1)
+ {
+ skip = 2;
+ head = (template_backtrace_limit - 1) / 2;
+ }
+
+ for (n = 0; n < head; n++)
+ {
+ gcc_assert (t != NULL);
+ if (loc != t->locus)
+ print_instantiation_partial_context_line (context, t, loc,
+ /*recursive_p=*/false);
+ loc = t->locus;
+ t = t->next;
+ }
+ if (t != NULL && skip > 0)
+ {
+ expanded_location xloc;
+ xloc = expand_location (loc);
+ if (context->show_column)
+ pp_verbatim (context->printer,
+ _("%r%s:%d:%d:%R [ skipping %d instantiation "
+ "contexts, use -ftemplate-backtrace-limit=0 to "
+ "disable ]\n"),
+ "locus", xloc.file, xloc.line, xloc.column, skip);
+ else
+ pp_verbatim (context->printer,
+ _("%r%s:%d:%R [ skipping %d instantiation "
+ "contexts, use -ftemplate-backtrace-limit=0 to "
+ "disable ]\n"),
+ "locus", xloc.file, xloc.line, skip);
+
+ do {
+ loc = t->locus;
+ t = t->next;
+ } while (t != NULL && --skip > 0);
+ }
+ }
+
+ while (t != NULL)
+ {
+ while (t->next != NULL && t->locus == t->next->locus)
+ {
+ loc = t->locus;
+ t = t->next;
+ }
+ print_instantiation_partial_context_line (context, t, loc,
+ t->locus == loc);
+ loc = t->locus;
+ t = t->next;
+ }
+ print_instantiation_partial_context_line (context, NULL, loc,
+ /*recursive_p=*/false);
+ pp_newline (context->printer);
+}
+
+/* Called from cp_thing to print the template context for an error. */
+static void
+maybe_print_instantiation_context (diagnostic_context *context)
+{
+ if (!problematic_instantiation_changed () || current_instantiation () == 0)
+ return;
+
+ record_last_problematic_instantiation ();
+ print_instantiation_full_context (context);
+}
+
+/* Report the bare minimum context of a template instantiation. */
+void
+print_instantiation_context (void)
+{
+ print_instantiation_partial_context
+ (global_dc, current_instantiation (), input_location);
+ pp_newline (global_dc->printer);
+ diagnostic_flush_buffer (global_dc);
+}
+
+/* Report what constexpr call(s) we're trying to expand, if any. */
+
+void
+maybe_print_constexpr_context (diagnostic_context *context)
+{
+ vec<tree> call_stack = cx_error_context ();
+ unsigned ix;
+ tree t;
+
+ FOR_EACH_VEC_ELT (call_stack, ix, t)
+ {
+ expanded_location xloc = expand_location (EXPR_LOCATION (t));
+ const char *s = expr_as_string (t, 0);
+ if (context->show_column)
+ pp_verbatim (context->printer,
+ _("%r%s:%d:%d:%R in constexpr expansion of %qs"),
+ "locus", xloc.file, xloc.line, xloc.column, s);
+ else
+ pp_verbatim (context->printer,
+ _("%r%s:%d:%R in constexpr expansion of %qs"),
+ "locus", xloc.file, xloc.line, s);
+ pp_newline (context->printer);
+ }
+}
+
+/* Called from output_format -- during diagnostic message processing --
+ to handle C++ specific format specifier with the following meanings:
+ %A function argument-list.
+ %C tree code.
+ %D declaration.
+ %E expression.
+ %F function declaration.
+ %L language as used in extern "lang".
+ %O binary operator.
+ %P function parameter whose position is indicated by an integer.
+ %Q assignment operator.
+ %S substitution (template + args)
+ %T type.
+ %V cv-qualifier.
+ %X exception-specification. */
+static bool
+cp_printer (pretty_printer *pp, text_info *text, const char *spec,
+ int precision, bool wide, bool set_locus, bool verbose)
+{
+ const char *result;
+ tree t = NULL;
+#define next_tree (t = va_arg (*text->args_ptr, tree))
+#define next_tcode ((enum tree_code) va_arg (*text->args_ptr, int))
+#define next_lang ((enum languages) va_arg (*text->args_ptr, int))
+#define next_int va_arg (*text->args_ptr, int)
+
+ if (precision != 0 || wide)
+ return false;
+
+ if (text->locus == NULL)
+ set_locus = false;
+
+ switch (*spec)
+ {
+ case 'A': result = args_to_string (next_tree, verbose); break;
+ case 'C': result = code_to_string (next_tcode); break;
+ case 'D':
+ {
+ tree temp = next_tree;
+ if (VAR_P (temp)
+ && DECL_HAS_DEBUG_EXPR_P (temp))
+ {
+ temp = DECL_DEBUG_EXPR (temp);
+ if (!DECL_P (temp))
+ {
+ result = expr_to_string (temp);
+ break;
+ }
+ }
+ result = decl_to_string (temp, verbose);
+ }
+ break;
+ case 'E': result = expr_to_string (next_tree); break;
+ case 'F': result = fndecl_to_string (next_tree, verbose); break;
+ case 'L': result = language_to_string (next_lang); break;
+ case 'O': result = op_to_string (next_tcode); break;
+ case 'P': result = parm_to_string (next_int); break;
+ case 'Q': result = assop_to_string (next_tcode); break;
+ case 'S': result = subst_to_string (next_tree); break;
+ case 'T': result = type_to_string (next_tree, verbose); break;
+ case 'V': result = cv_to_string (next_tree, verbose); break;
+ case 'X': result = eh_spec_to_string (next_tree, verbose); break;
+
+ case 'K':
+ percent_K_format (text);
+ return true;
+
+ default:
+ return false;
+ }
+
+ pp_string (pp, result);
+ if (set_locus && t != NULL)
+ *text->locus = location_of (t);
+ return true;
+#undef next_tree
+#undef next_tcode
+#undef next_lang
+#undef next_int
+}
+
+/* Warn about the use of C++0x features when appropriate. */
+void
+maybe_warn_cpp0x (cpp0x_warn_str str)
+{
+ if ((cxx_dialect == cxx98) && !in_system_header_at (input_location))
+ /* We really want to suppress this warning in system headers,
+ because libstdc++ uses variadic templates even when we aren't
+ in C++0x mode. */
+ switch (str)
+ {
+ case CPP0X_INITIALIZER_LISTS:
+ pedwarn (input_location, 0,
+ "extended initializer lists "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_EXPLICIT_CONVERSION:
+ pedwarn (input_location, 0,
+ "explicit conversion operators "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_VARIADIC_TEMPLATES:
+ pedwarn (input_location, 0,
+ "variadic templates "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_LAMBDA_EXPR:
+ pedwarn (input_location, 0,
+ "lambda expressions "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_AUTO:
+ pedwarn (input_location, 0,
+ "C++11 auto only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_SCOPED_ENUMS:
+ pedwarn (input_location, 0,
+ "scoped enums only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_DEFAULTED_DELETED:
+ pedwarn (input_location, 0,
+ "defaulted and deleted functions "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_INLINE_NAMESPACES:
+ pedwarn (input_location, OPT_Wpedantic,
+ "inline namespaces "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_OVERRIDE_CONTROLS:
+ pedwarn (input_location, 0,
+ "override controls (override/final) "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_NSDMI:
+ pedwarn (input_location, 0,
+ "non-static data member initializers "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_USER_DEFINED_LITERALS:
+ pedwarn (input_location, 0,
+ "user-defined literals "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_DELEGATING_CTORS:
+ pedwarn (input_location, 0,
+ "delegating constructors "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_INHERITING_CTORS:
+ pedwarn (input_location, 0,
+ "inheriting constructors "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_ATTRIBUTES:
+ pedwarn (input_location, 0,
+ "c++11 attributes "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ case CPP0X_REF_QUALIFIER:
+ pedwarn (input_location, 0,
+ "ref-qualifiers "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Warn about the use of variadic templates when appropriate. */
+void
+maybe_warn_variadic_templates (void)
+{
+ maybe_warn_cpp0x (CPP0X_VARIADIC_TEMPLATES);
+}
+
+
+/* Issue an ISO C++98 pedantic warning at LOCATION, conditional on
+ option OPT with text GMSGID. Use this function to report
+ diagnostics for constructs that are invalid C++98, but valid
+ C++0x. */
+bool
+pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...)
+{
+ diagnostic_info diagnostic;
+ va_list ap;
+ bool ret;
+
+ va_start (ap, gmsgid);
+ diagnostic_set_info (&diagnostic, gmsgid, &ap, location,
+ (cxx_dialect == cxx98) ? DK_PEDWARN : DK_WARNING);
+ diagnostic.option_index = opt;
+ ret = report_diagnostic (&diagnostic);
+ va_end (ap);
+ return ret;
+}
+
+/* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is what
+ we found when we tried to do the lookup. LOCATION is the location of
+ the NAME identifier. */
+
+void
+qualified_name_lookup_error (tree scope, tree name,
+ tree decl, location_t location)
+{
+ if (scope == error_mark_node)
+ ; /* We already complained. */
+ else if (TYPE_P (scope))
+ {
+ if (!COMPLETE_TYPE_P (scope))
+ error_at (location, "incomplete type %qT used in nested name specifier",
+ scope);
+ else if (TREE_CODE (decl) == TREE_LIST)
+ {
+ error_at (location, "reference to %<%T::%D%> is ambiguous",
+ scope, name);
+ print_candidates (decl);
+ }
+ else
+ error_at (location, "%qD is not a member of %qT", name, scope);
+ }
+ else if (scope != global_namespace)
+ {
+ error_at (location, "%qD is not a member of %qD", name, scope);
+ suggest_alternatives_for (location, name);
+ }
+ else
+ {
+ error_at (location, "%<::%D%> has not been declared", name);
+ suggest_alternatives_for (location, name);
+ }
+}
diff --git a/gcc-4.9/gcc/cp/except.c b/gcc-4.9/gcc/cp/except.c
new file mode 100644
index 000000000..221971ac9
--- /dev/null
+++ b/gcc-4.9/gcc/cp/except.c
@@ -0,0 +1,1363 @@
+/* Handle exceptional things in C++.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Contributed by Michael Tiemann <tiemann@cygnus.com>
+ Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
+ initial re-implementation courtesy Tad Hunt.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "trans-mem.h"
+#include "attribs.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "tree-inline.h"
+#include "tree-iterator.h"
+#include "target.h"
+
+static void push_eh_cleanup (tree);
+static tree prepare_eh_type (tree);
+static tree do_begin_catch (void);
+static int dtor_nothrow (tree);
+static tree do_end_catch (tree);
+static bool decl_is_java_type (tree decl, int err);
+static void initialize_handler_parm (tree, tree);
+static tree do_allocate_exception (tree);
+static tree wrap_cleanups_r (tree *, int *, void *);
+static int complete_ptr_ref_or_void_ptr_p (tree, tree);
+static bool is_admissible_throw_operand_or_catch_parameter (tree, bool);
+static int can_convert_eh (tree, tree);
+
+/* Sets up all the global eh stuff that needs to be initialized at the
+ start of compilation. */
+
+void
+init_exception_processing (void)
+{
+ tree tmp;
+
+ /* void std::terminate (); */
+ push_namespace (std_identifier);
+ tmp = build_function_type_list (void_type_node, NULL_TREE);
+ terminate_node = build_cp_library_fn_ptr ("terminate", tmp,
+ ECF_NOTHROW | ECF_NORETURN);
+ TREE_THIS_VOLATILE (terminate_node) = 1;
+ TREE_NOTHROW (terminate_node) = 1;
+ pop_namespace ();
+
+ /* void __cxa_call_unexpected(void *); */
+ tmp = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
+ call_unexpected_node
+ = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
+}
+
+/* Returns an expression to be executed if an unhandled exception is
+ propagated out of a cleanup region. */
+
+tree
+cp_protect_cleanup_actions (void)
+{
+ /* [except.terminate]
+
+ When the destruction of an object during stack unwinding exits
+ using an exception ... void terminate(); is called. */
+ return terminate_node;
+}
+
+static tree
+prepare_eh_type (tree type)
+{
+ if (type == NULL_TREE)
+ return type;
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ /* peel back references, so they match. */
+ type = non_reference (type);
+
+ /* Peel off cv qualifiers. */
+ type = TYPE_MAIN_VARIANT (type);
+
+ /* Functions and arrays decay to pointers. */
+ type = type_decays_to (type);
+
+ return type;
+}
+
+/* Return the type info for TYPE as used by EH machinery. */
+tree
+eh_type_info (tree type)
+{
+ tree exp;
+
+ if (type == NULL_TREE || type == error_mark_node)
+ return type;
+
+ if (decl_is_java_type (type, 0))
+ exp = build_java_class_ref (TREE_TYPE (type));
+ else
+ exp = get_tinfo_decl (type);
+
+ return exp;
+}
+
+/* Build the address of a typeinfo decl for use in the runtime
+ matching field of the exception model. */
+
+tree
+build_eh_type_type (tree type)
+{
+ tree exp = eh_type_info (type);
+
+ if (!exp)
+ return NULL;
+
+ mark_used (exp);
+
+ return convert (ptr_type_node, build_address (exp));
+}
+
+tree
+build_exc_ptr (void)
+{
+ return build_call_n (builtin_decl_explicit (BUILT_IN_EH_POINTER),
+ 1, integer_zero_node);
+}
+
+/* Declare a function NAME, returning RETURN_TYPE, taking a single
+ parameter PARM_TYPE, with an empty exception specification.
+
+ Note that the C++ ABI document does not have a throw-specifier on
+ the routines declared below via this function. The declarations
+ are consistent with the actual implementations in libsupc++. */
+
+static tree
+declare_library_fn (tree name, tree return_type, tree parm_type, int ecf_flags)
+{
+ return push_library_fn (name, build_function_type_list (return_type,
+ parm_type,
+ NULL_TREE),
+ empty_except_spec,
+ ecf_flags);
+}
+
+/* Build up a call to __cxa_get_exception_ptr so that we can build a
+ copy constructor for the thrown object. */
+
+static tree
+do_get_exception_ptr (void)
+{
+ tree fn;
+
+ fn = get_identifier ("__cxa_get_exception_ptr");
+ if (!get_global_value_if_present (fn, &fn))
+ {
+ /* Declare void* __cxa_get_exception_ptr (void *) throw(). */
+ fn = declare_library_fn (fn, ptr_type_node, ptr_type_node,
+ ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE);
+ }
+
+ return cp_build_function_call_nary (fn, tf_warning_or_error,
+ build_exc_ptr (), NULL_TREE);
+}
+
+/* Build up a call to __cxa_begin_catch, to tell the runtime that the
+ exception has been handled. */
+
+static tree
+do_begin_catch (void)
+{
+ tree fn;
+
+ fn = get_identifier ("__cxa_begin_catch");
+ if (!get_global_value_if_present (fn, &fn))
+ {
+ /* Declare void* __cxa_begin_catch (void *) throw(). */
+ fn = declare_library_fn (fn, ptr_type_node, ptr_type_node, ECF_NOTHROW);
+
+ /* Create its transactional-memory equivalent. */
+ if (flag_tm)
+ {
+ tree fn2 = get_identifier ("_ITM_cxa_begin_catch");
+ if (!get_global_value_if_present (fn2, &fn2))
+ fn2 = declare_library_fn (fn2, ptr_type_node,
+ ptr_type_node, ECF_NOTHROW | ECF_TM_PURE);
+ record_tm_replacement (fn, fn2);
+ }
+ }
+
+ return cp_build_function_call_nary (fn, tf_warning_or_error,
+ build_exc_ptr (), NULL_TREE);
+}
+
+/* Returns nonzero if cleaning up an exception of type TYPE (which can be
+ NULL_TREE for a ... handler) will not throw an exception. */
+
+static int
+dtor_nothrow (tree type)
+{
+ if (type == NULL_TREE || type == error_mark_node)
+ return 0;
+
+ if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+ return 1;
+
+ if (CLASSTYPE_LAZY_DESTRUCTOR (type))
+ lazily_declare_fn (sfk_destructor, type);
+
+ return TREE_NOTHROW (CLASSTYPE_DESTRUCTORS (type));
+}
+
+/* Build up a call to __cxa_end_catch, to destroy the exception object
+ for the current catch block if no others are currently using it. */
+
+static tree
+do_end_catch (tree type)
+{
+ tree fn, cleanup;
+
+ fn = get_identifier ("__cxa_end_catch");
+ if (!get_global_value_if_present (fn, &fn))
+ {
+ /* Declare void __cxa_end_catch ().
+ This can throw if the destructor for the exception throws. */
+ fn = push_void_library_fn (fn, void_list_node, 0);
+
+ /* Create its transactional-memory equivalent. */
+ if (flag_tm)
+ {
+ tree fn2 = get_identifier ("_ITM_cxa_end_catch");
+ if (!get_global_value_if_present (fn2, &fn2))
+ fn2 = push_void_library_fn (fn2, void_list_node, ECF_TM_PURE);
+ record_tm_replacement (fn, fn2);
+ }
+ }
+
+ cleanup = cp_build_function_call_vec (fn, NULL, tf_warning_or_error);
+ TREE_NOTHROW (cleanup) = dtor_nothrow (type);
+
+ return cleanup;
+}
+
+/* This routine creates the cleanup for the current exception. */
+
+static void
+push_eh_cleanup (tree type)
+{
+ finish_decl_cleanup (NULL_TREE, do_end_catch (type));
+}
+
+/* Return nonzero value if DECL is a Java type suitable for catch or
+ throw. */
+
+static bool
+decl_is_java_type (tree decl, int err)
+{
+ bool r = (TYPE_PTR_P (decl)
+ && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
+ && TYPE_FOR_JAVA (TREE_TYPE (decl)));
+
+ if (err)
+ {
+ if (TREE_CODE (decl) == REFERENCE_TYPE
+ && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
+ && TYPE_FOR_JAVA (TREE_TYPE (decl)))
+ {
+ /* Can't throw a reference. */
+ error ("type %qT is disallowed in Java %<throw%> or %<catch%>",
+ decl);
+ }
+
+ if (r)
+ {
+ tree jthrow_node
+ = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jthrowable"));
+
+ if (jthrow_node == NULL_TREE)
+ fatal_error
+ ("call to Java %<catch%> or %<throw%> with %<jthrowable%> undefined");
+
+ jthrow_node = TREE_TYPE (TREE_TYPE (jthrow_node));
+
+ if (! DERIVED_FROM_P (jthrow_node, TREE_TYPE (decl)))
+ {
+ /* Thrown object must be a Throwable. */
+ error ("type %qT is not derived from %<java::lang::Throwable%>",
+ TREE_TYPE (decl));
+ }
+ }
+ }
+
+ return r;
+}
+
+/* Select the personality routine to be used for exception handling,
+ or issue an error if we need two different ones in the same
+ translation unit.
+ ??? At present DECL_FUNCTION_PERSONALITY is set via
+ LANG_HOOKS_EH_PERSONALITY. Should it be done here instead? */
+void
+choose_personality_routine (enum languages lang)
+{
+ static enum {
+ chose_none,
+ chose_cpp,
+ chose_java,
+ gave_error
+ } state;
+
+ switch (state)
+ {
+ case gave_error:
+ return;
+
+ case chose_cpp:
+ if (lang != lang_cplusplus)
+ goto give_error;
+ return;
+
+ case chose_java:
+ if (lang != lang_java)
+ goto give_error;
+ return;
+
+ case chose_none:
+ ; /* Proceed to language selection. */
+ }
+
+ switch (lang)
+ {
+ case lang_cplusplus:
+ state = chose_cpp;
+ break;
+
+ case lang_java:
+ state = chose_java;
+ terminate_node = builtin_decl_explicit (BUILT_IN_ABORT);
+ pragma_java_exceptions = true;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ return;
+
+ give_error:
+ error ("mixing C++ and Java catches in a single translation unit");
+ state = gave_error;
+}
+
+/* Wrap EXPR in a MUST_NOT_THROW_EXPR expressing that EXPR must
+ not throw any exceptions if COND is true. A condition of
+ NULL_TREE is treated as 'true'. */
+
+tree
+build_must_not_throw_expr (tree body, tree cond)
+{
+ tree type = body ? TREE_TYPE (body) : void_type_node;
+
+ if (!flag_exceptions)
+ return body;
+
+ if (cond && !value_dependent_expression_p (cond))
+ {
+ cond = cxx_constant_value (cond);
+ if (integer_zerop (cond))
+ return body;
+ else if (integer_onep (cond))
+ cond = NULL_TREE;
+ }
+
+ return build2 (MUST_NOT_THROW_EXPR, type, body, cond);
+}
+
+
+/* Initialize the catch parameter DECL. */
+
+static void
+initialize_handler_parm (tree decl, tree exp)
+{
+ tree init;
+ tree init_type;
+
+ /* Make sure we mark the catch param as used, otherwise we'll get a
+ warning about an unused ((anonymous)). */
+ TREE_USED (decl) = 1;
+ DECL_READ_P (decl) = 1;
+
+ /* Figure out the type that the initializer is. Pointers are returned
+ adjusted by value from __cxa_begin_catch. Others are returned by
+ reference. */
+ init_type = TREE_TYPE (decl);
+ if (!POINTER_TYPE_P (init_type))
+ init_type = build_reference_type (init_type);
+
+ choose_personality_routine (decl_is_java_type (init_type, 0)
+ ? lang_java : lang_cplusplus);
+
+ /* Since pointers are passed by value, initialize a reference to
+ pointer catch parm with the address of the temporary. */
+ if (TREE_CODE (init_type) == REFERENCE_TYPE
+ && TYPE_PTR_P (TREE_TYPE (init_type)))
+ exp = cp_build_addr_expr (exp, tf_warning_or_error);
+
+ exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0,
+ tf_warning_or_error);
+
+ init = convert_from_reference (exp);
+
+ /* If the constructor for the catch parm exits via an exception, we
+ must call terminate. See eh23.C. */
+ if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
+ {
+ /* Generate the copy constructor call directly so we can wrap it.
+ See also expand_default_init. */
+ init = ocp_convert (TREE_TYPE (decl), init,
+ CONV_IMPLICIT|CONV_FORCE_TEMP, 0,
+ tf_warning_or_error);
+ /* Force cleanups now to avoid nesting problems with the
+ MUST_NOT_THROW_EXPR. */
+ init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
+ init = build_must_not_throw_expr (init, NULL_TREE);
+ }
+
+ decl = pushdecl (decl);
+
+ start_decl_1 (decl, true);
+ cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
+ LOOKUP_ONLYCONVERTING|DIRECT_BIND);
+}
+
+
+/* Routine to see if exception handling is turned on.
+ DO_WARN is nonzero if we want to inform the user that exception
+ handling is turned off.
+
+ This is used to ensure that -fexceptions has been specified if the
+ compiler tries to use any exception-specific functions. */
+
+static inline int
+doing_eh (void)
+{
+ if (! flag_exceptions)
+ {
+ static int warned = 0;
+ if (! warned)
+ {
+ error ("exception handling disabled, use -fexceptions to enable");
+ warned = 1;
+ }
+ return 0;
+ }
+ return 1;
+}
+
+/* Call this to start a catch block. DECL is the catch parameter. */
+
+tree
+expand_start_catch_block (tree decl)
+{
+ tree exp;
+ tree type, init;
+
+ if (! doing_eh ())
+ return NULL_TREE;
+
+ if (decl)
+ {
+ if (!is_admissible_throw_operand_or_catch_parameter (decl, false))
+ decl = error_mark_node;
+
+ type = prepare_eh_type (TREE_TYPE (decl));
+ mark_used (eh_type_info (type));
+ }
+ else
+ type = NULL_TREE;
+
+ if (decl && decl_is_java_type (type, 1))
+ {
+ /* Java only passes object via pointer and doesn't require
+ adjusting. The java object is immediately before the
+ generic exception header. */
+ exp = build_exc_ptr ();
+ exp = build1 (NOP_EXPR, build_pointer_type (type), exp);
+ exp = fold_build_pointer_plus (exp,
+ fold_build1_loc (input_location,
+ NEGATE_EXPR, sizetype,
+ TYPE_SIZE_UNIT (TREE_TYPE (exp))));
+ exp = cp_build_indirect_ref (exp, RO_NULL, tf_warning_or_error);
+ initialize_handler_parm (decl, exp);
+ return type;
+ }
+
+ /* Call __cxa_end_catch at the end of processing the exception. */
+ push_eh_cleanup (type);
+
+ init = do_begin_catch ();
+
+ /* If there's no decl at all, then all we need to do is make sure
+ to tell the runtime that we've begun handling the exception. */
+ if (decl == NULL || decl == error_mark_node || init == error_mark_node)
+ finish_expr_stmt (init);
+
+ /* If the C++ object needs constructing, we need to do that before
+ calling __cxa_begin_catch, so that std::uncaught_exception gets
+ the right value during the copy constructor. */
+ else if (flag_use_cxa_get_exception_ptr
+ && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
+ {
+ exp = do_get_exception_ptr ();
+ initialize_handler_parm (decl, exp);
+ finish_expr_stmt (init);
+ }
+
+ /* Otherwise the type uses a bitwise copy, and we don't have to worry
+ about the value of std::uncaught_exception and therefore can do the
+ copy with the return value of __cxa_end_catch instead. */
+ else
+ {
+ tree init_type = type;
+
+ /* Pointers are passed by values, everything else by reference. */
+ if (!TYPE_PTR_P (type))
+ init_type = build_pointer_type (type);
+ if (init_type != TREE_TYPE (init))
+ init = build1 (NOP_EXPR, init_type, init);
+ exp = create_temporary_var (init_type);
+ DECL_REGISTER (exp) = 1;
+ cp_finish_decl (exp, init, /*init_const_expr=*/false,
+ NULL_TREE, LOOKUP_ONLYCONVERTING);
+ initialize_handler_parm (decl, exp);
+ }
+
+ return type;
+}
+
+
+/* Call this to end a catch block. Its responsible for emitting the
+ code to handle jumping back to the correct place, and for emitting
+ the label to jump to if this catch block didn't match. */
+
+void
+expand_end_catch_block (void)
+{
+ if (! doing_eh ())
+ return;
+
+ /* The exception being handled is rethrown if control reaches the end of
+ a handler of the function-try-block of a constructor or destructor. */
+ if (in_function_try_handler
+ && (DECL_CONSTRUCTOR_P (current_function_decl)
+ || DECL_DESTRUCTOR_P (current_function_decl)))
+ finish_expr_stmt (build_throw (NULL_TREE));
+}
+
+tree
+begin_eh_spec_block (void)
+{
+ tree r;
+ location_t spec_location = DECL_SOURCE_LOCATION (current_function_decl);
+
+ /* A noexcept specification (or throw() with -fnothrow-opt) is a
+ MUST_NOT_THROW_EXPR. */
+ if (TYPE_NOEXCEPT_P (TREE_TYPE (current_function_decl)))
+ {
+ r = build_stmt (spec_location, MUST_NOT_THROW_EXPR,
+ NULL_TREE, NULL_TREE);
+ TREE_SIDE_EFFECTS (r) = 1;
+ }
+ else
+ r = build_stmt (spec_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
+ add_stmt (r);
+ TREE_OPERAND (r, 0) = push_stmt_list ();
+ return r;
+}
+
+void
+finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
+{
+ tree raises;
+
+ TREE_OPERAND (eh_spec_block, 0)
+ = pop_stmt_list (TREE_OPERAND (eh_spec_block, 0));
+
+ if (TREE_CODE (eh_spec_block) == MUST_NOT_THROW_EXPR)
+ return;
+
+ /* Strip cv quals, etc, from the specification types. */
+ for (raises = NULL_TREE;
+ raw_raises && TREE_VALUE (raw_raises);
+ raw_raises = TREE_CHAIN (raw_raises))
+ {
+ tree type = prepare_eh_type (TREE_VALUE (raw_raises));
+ tree tinfo = eh_type_info (type);
+
+ mark_used (tinfo);
+ raises = tree_cons (NULL_TREE, type, raises);
+ }
+
+ EH_SPEC_RAISES (eh_spec_block) = raises;
+}
+
+/* Return a pointer to a buffer for an exception object of type TYPE. */
+
+static tree
+do_allocate_exception (tree type)
+{
+ tree fn;
+
+ fn = get_identifier ("__cxa_allocate_exception");
+ if (!get_global_value_if_present (fn, &fn))
+ {
+ /* Declare void *__cxa_allocate_exception(size_t) throw(). */
+ fn = declare_library_fn (fn, ptr_type_node, size_type_node,
+ ECF_NOTHROW | ECF_MALLOC);
+
+ if (flag_tm)
+ {
+ tree fn2 = get_identifier ("_ITM_cxa_allocate_exception");
+ if (!get_global_value_if_present (fn2, &fn2))
+ fn2 = declare_library_fn (fn2, ptr_type_node,
+ size_type_node,
+ ECF_NOTHROW | ECF_MALLOC | ECF_TM_PURE);
+ record_tm_replacement (fn, fn2);
+ }
+ }
+
+ return cp_build_function_call_nary (fn, tf_warning_or_error,
+ size_in_bytes (type), NULL_TREE);
+}
+
+/* Call __cxa_free_exception from a cleanup. This is never invoked
+ directly, but see the comment for stabilize_throw_expr. */
+
+static tree
+do_free_exception (tree ptr)
+{
+ tree fn;
+
+ fn = get_identifier ("__cxa_free_exception");
+ if (!get_global_value_if_present (fn, &fn))
+ {
+ /* Declare void __cxa_free_exception (void *) throw(). */
+ fn = declare_library_fn (fn, void_type_node, ptr_type_node,
+ ECF_NOTHROW | ECF_LEAF);
+ }
+
+ return cp_build_function_call_nary (fn, tf_warning_or_error, ptr, NULL_TREE);
+}
+
+/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
+ Called from build_throw via walk_tree_without_duplicates. */
+
+static tree
+wrap_cleanups_r (tree *tp, int *walk_subtrees, void * /*data*/)
+{
+ tree exp = *tp;
+ tree cleanup;
+
+ /* Don't walk into types. */
+ if (TYPE_P (exp))
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+ if (TREE_CODE (exp) != TARGET_EXPR)
+ return NULL_TREE;
+
+ cleanup = TARGET_EXPR_CLEANUP (exp);
+ if (cleanup)
+ {
+ cleanup = build2 (MUST_NOT_THROW_EXPR, void_type_node, cleanup,
+ NULL_TREE);
+ TARGET_EXPR_CLEANUP (exp) = cleanup;
+ }
+
+ /* Keep iterating. */
+ return NULL_TREE;
+}
+
+/* Build a throw expression. */
+
+tree
+build_throw (tree exp)
+{
+ tree fn;
+
+ if (exp == error_mark_node)
+ return exp;
+
+ if (processing_template_decl)
+ {
+ if (cfun)
+ current_function_returns_abnormally = 1;
+ exp = build_min (THROW_EXPR, void_type_node, exp);
+ SET_EXPR_LOCATION (exp, input_location);
+ return exp;
+ }
+
+ if (exp == null_node)
+ warning (0, "throwing NULL, which has integral, not pointer type");
+
+ if (exp != NULL_TREE)
+ {
+ if (!is_admissible_throw_operand_or_catch_parameter (exp, true))
+ return error_mark_node;
+ }
+
+ if (! doing_eh ())
+ return error_mark_node;
+
+ if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
+ {
+ tree fn = get_identifier ("_Jv_Throw");
+ if (!get_global_value_if_present (fn, &fn))
+ {
+ /* Declare void _Jv_Throw (void *). */
+ tree tmp;
+ tmp = build_function_type_list (ptr_type_node,
+ ptr_type_node, NULL_TREE);
+ fn = push_throw_library_fn (fn, tmp);
+ }
+ else if (really_overloaded_fn (fn))
+ {
+ error ("%qD should never be overloaded", fn);
+ return error_mark_node;
+ }
+ fn = OVL_CURRENT (fn);
+ exp = cp_build_function_call_nary (fn, tf_warning_or_error,
+ exp, NULL_TREE);
+ }
+ else if (exp)
+ {
+ tree throw_type;
+ tree temp_type;
+ tree cleanup;
+ tree object, ptr;
+ tree tmp;
+ tree allocate_expr;
+
+ /* The CLEANUP_TYPE is the internal type of a destructor. */
+ if (!cleanup_type)
+ {
+ tmp = build_function_type_list (void_type_node,
+ ptr_type_node, NULL_TREE);
+ cleanup_type = build_pointer_type (tmp);
+ }
+
+ fn = get_identifier ("__cxa_throw");
+ if (!get_global_value_if_present (fn, &fn))
+ {
+ /* Declare void __cxa_throw (void*, void*, void (*)(void*)). */
+ /* ??? Second argument is supposed to be "std::type_info*". */
+ tmp = build_function_type_list (void_type_node,
+ ptr_type_node, ptr_type_node,
+ cleanup_type, NULL_TREE);
+ fn = push_throw_library_fn (fn, tmp);
+
+ if (flag_tm)
+ {
+ tree fn2 = get_identifier ("_ITM_cxa_throw");
+ if (!get_global_value_if_present (fn2, &fn2))
+ fn2 = push_throw_library_fn (fn2, tmp);
+ apply_tm_attr (fn2, get_identifier ("transaction_pure"));
+ record_tm_replacement (fn, fn2);
+ }
+ }
+
+ /* [except.throw]
+
+ A throw-expression initializes a temporary object, the type
+ of which is determined by removing any top-level
+ cv-qualifiers from the static type of the operand of throw
+ and adjusting the type from "array of T" or "function return
+ T" to "pointer to T" or "pointer to function returning T"
+ respectively. */
+ temp_type = is_bitfield_expr_with_lowered_type (exp);
+ if (!temp_type)
+ temp_type = cv_unqualified (type_decays_to (TREE_TYPE (exp)));
+
+ /* OK, this is kind of wacky. The standard says that we call
+ terminate when the exception handling mechanism, after
+ completing evaluation of the expression to be thrown but
+ before the exception is caught (_except.throw_), calls a
+ user function that exits via an uncaught exception.
+
+ So we have to protect the actual initialization of the
+ exception object with terminate(), but evaluate the
+ expression first. Since there could be temps in the
+ expression, we need to handle that, too. We also expand
+ the call to __cxa_allocate_exception first (which doesn't
+ matter, since it can't throw). */
+
+ /* Allocate the space for the exception. */
+ allocate_expr = do_allocate_exception (temp_type);
+ allocate_expr = get_target_expr (allocate_expr);
+ ptr = TARGET_EXPR_SLOT (allocate_expr);
+ TARGET_EXPR_CLEANUP (allocate_expr) = do_free_exception (ptr);
+ CLEANUP_EH_ONLY (allocate_expr) = 1;
+
+ object = build_nop (build_pointer_type (temp_type), ptr);
+ object = cp_build_indirect_ref (object, RO_NULL, tf_warning_or_error);
+
+ /* And initialize the exception object. */
+ if (CLASS_TYPE_P (temp_type))
+ {
+ int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
+ vec<tree, va_gc> *exp_vec;
+
+ /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
+ treated as an rvalue for the purposes of overload resolution
+ to favor move constructors over copy constructors. */
+ if (/* Must be a local, automatic variable. */
+ VAR_P (exp)
+ && DECL_CONTEXT (exp) == current_function_decl
+ && ! TREE_STATIC (exp)
+ /* The variable must not have the `volatile' qualifier. */
+ && !(cp_type_quals (TREE_TYPE (exp)) & TYPE_QUAL_VOLATILE))
+ flags = flags | LOOKUP_PREFER_RVALUE;
+
+ /* Call the copy constructor. */
+ exp_vec = make_tree_vector_single (exp);
+ exp = (build_special_member_call
+ (object, complete_ctor_identifier, &exp_vec,
+ TREE_TYPE (object), flags, tf_warning_or_error));
+ release_tree_vector (exp_vec);
+ if (exp == error_mark_node)
+ {
+ error (" in thrown expression");
+ return error_mark_node;
+ }
+ }
+ else
+ {
+ tmp = decay_conversion (exp, tf_warning_or_error);
+ if (tmp == error_mark_node)
+ return error_mark_node;
+ exp = build2 (INIT_EXPR, temp_type, object, tmp);
+ }
+
+ /* Mark any cleanups from the initialization as MUST_NOT_THROW, since
+ they are run after the exception object is initialized. */
+ cp_walk_tree_without_duplicates (&exp, wrap_cleanups_r, 0);
+
+ /* Prepend the allocation. */
+ exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
+
+ /* Force all the cleanups to be evaluated here so that we don't have
+ to do them during unwinding. */
+ exp = build1 (CLEANUP_POINT_EXPR, void_type_node, exp);
+
+ throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
+
+ cleanup = NULL_TREE;
+ if (type_build_dtor_call (TREE_TYPE (object)))
+ {
+ tree fn = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
+ complete_dtor_identifier, 0);
+ fn = BASELINK_FUNCTIONS (fn);
+ mark_used (fn);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
+ {
+ cxx_mark_addressable (fn);
+ /* Pretend it's a normal function. */
+ cleanup = build1 (ADDR_EXPR, cleanup_type, fn);
+ }
+ }
+ if (cleanup == NULL_TREE)
+ cleanup = build_int_cst (cleanup_type, 0);
+
+ /* ??? Indicate that this function call throws throw_type. */
+ tmp = cp_build_function_call_nary (fn, tf_warning_or_error,
+ ptr, throw_type, cleanup, NULL_TREE);
+
+ /* Tack on the initialization stuff. */
+ exp = build2 (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
+ }
+ else
+ {
+ /* Rethrow current exception. */
+
+ tree fn = get_identifier ("__cxa_rethrow");
+ if (!get_global_value_if_present (fn, &fn))
+ {
+ /* Declare void __cxa_rethrow (void). */
+ fn = push_throw_library_fn
+ (fn, build_function_type_list (void_type_node, NULL_TREE));
+ }
+
+ if (flag_tm)
+ apply_tm_attr (fn, get_identifier ("transaction_pure"));
+
+ /* ??? Indicate that this function call allows exceptions of the type
+ of the enclosing catch block (if known). */
+ exp = cp_build_function_call_vec (fn, NULL, tf_warning_or_error);
+ }
+
+ exp = build1 (THROW_EXPR, void_type_node, exp);
+ SET_EXPR_LOCATION (exp, input_location);
+
+ return exp;
+}
+
+/* Make sure TYPE is complete, pointer to complete, reference to
+ complete, or pointer to cv void. Issue diagnostic on failure.
+ Return the zero on failure and nonzero on success. FROM can be
+ the expr or decl from whence TYPE came, if available. */
+
+static int
+complete_ptr_ref_or_void_ptr_p (tree type, tree from)
+{
+ int is_ptr;
+
+ /* Check complete. */
+ type = complete_type_or_else (type, from);
+ if (!type)
+ return 0;
+
+ /* Or a pointer or ref to one, or cv void *. */
+ is_ptr = TYPE_PTR_P (type);
+ if (is_ptr || TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ tree core = TREE_TYPE (type);
+
+ if (is_ptr && VOID_TYPE_P (core))
+ /* OK */;
+ else if (!complete_type_or_else (core, from))
+ return 0;
+ }
+ return 1;
+}
+
+/* If IS_THROW is true return truth-value if T is an expression admissible
+ in throw-expression, i.e. if it is not of incomplete type or a pointer/
+ reference to such a type or of an abstract class type.
+ If IS_THROW is false, likewise for a catch parameter, same requirements
+ for its type plus rvalue reference type is also not admissible. */
+
+static bool
+is_admissible_throw_operand_or_catch_parameter (tree t, bool is_throw)
+{
+ tree expr = is_throw ? t : NULL_TREE;
+ tree type = TREE_TYPE (t);
+
+ /* C++11 [except.handle] The exception-declaration shall not denote
+ an incomplete type, an abstract class type, or an rvalue reference
+ type. */
+
+ /* 15.1/4 [...] The type of the throw-expression shall not be an
+ incomplete type, or a pointer or a reference to an incomplete
+ type, other than void*, const void*, volatile void*, or
+ const volatile void*. Except for these restriction and the
+ restrictions on type matching mentioned in 15.3, the operand
+ of throw is treated exactly as a function argument in a call
+ (5.2.2) or the operand of a return statement. */
+ if (!complete_ptr_ref_or_void_ptr_p (type, expr))
+ return false;
+
+ /* 10.4/3 An abstract class shall not be used as a parameter type,
+ as a function return type or as type of an explicit
+ conversion. */
+ else if (abstract_virtuals_error (is_throw ? ACU_THROW : ACU_CATCH, type))
+ return false;
+ else if (!is_throw
+ && TREE_CODE (type) == REFERENCE_TYPE
+ && TYPE_REF_IS_RVALUE (type))
+ {
+ error ("cannot declare catch parameter to be of rvalue "
+ "reference type %qT", type);
+ return false;
+ }
+ else if (variably_modified_type_p (type, NULL_TREE))
+ {
+ if (is_throw)
+ error ("cannot throw expression of type %qT because it involves "
+ "types of variable size", type);
+ else
+ error ("cannot catch type %qT because it involves types of "
+ "variable size", type);
+ return false;
+ }
+
+ return true;
+}
+
+/* Returns nonzero if FN is a declaration of a standard C library
+ function which is known not to throw.
+
+ [lib.res.on.exception.handling]: None of the functions from the
+ Standard C library shall report an error by throwing an
+ exception, unless it calls a program-supplied function that
+ throws an exception. */
+
+#include "cfns.h"
+
+int
+nothrow_libfn_p (const_tree fn)
+{
+ tree id;
+
+ if (TREE_PUBLIC (fn)
+ && DECL_EXTERNAL (fn)
+ && DECL_NAMESPACE_SCOPE_P (fn)
+ && DECL_EXTERN_C_P (fn))
+ /* OK */;
+ else
+ /* Can't be a C library function. */
+ return 0;
+
+ /* Being a C library function, DECL_ASSEMBLER_NAME == DECL_NAME
+ unless the system headers are playing rename tricks, and if
+ they are, we don't want to be confused by them. */
+ id = DECL_NAME (fn);
+ return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
+}
+
+/* Returns nonzero if an exception of type FROM will be caught by a
+ handler for type TO, as per [except.handle]. */
+
+static int
+can_convert_eh (tree to, tree from)
+{
+ to = non_reference (to);
+ from = non_reference (from);
+
+ if (TYPE_PTR_P (to) && TYPE_PTR_P (from))
+ {
+ to = TREE_TYPE (to);
+ from = TREE_TYPE (from);
+
+ if (! at_least_as_qualified_p (to, from))
+ return 0;
+
+ if (VOID_TYPE_P (to))
+ return 1;
+
+ /* Else fall through. */
+ }
+
+ if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
+ && publicly_uniquely_derived_p (to, from))
+ return 1;
+
+ return 0;
+}
+
+/* Check whether any of the handlers in I are shadowed by another handler
+ accepting TYPE. Note that the shadowing may not be complete; even if
+ an exception of type B would be caught by a handler for A, there could
+ be a derived class C for which A is an ambiguous base but B is not, so
+ the handler for B would catch an exception of type C. */
+
+static void
+check_handlers_1 (tree master, tree_stmt_iterator i)
+{
+ tree type = TREE_TYPE (master);
+
+ for (; !tsi_end_p (i); tsi_next (&i))
+ {
+ tree handler = tsi_stmt (i);
+ if (TREE_TYPE (handler) && can_convert_eh (type, TREE_TYPE (handler)))
+ {
+ warning_at (EXPR_LOCATION (handler), 0,
+ "exception of type %qT will be caught",
+ TREE_TYPE (handler));
+ warning_at (EXPR_LOCATION (master), 0,
+ " by earlier handler for %qT", type);
+ break;
+ }
+ }
+}
+
+/* Given a STATEMENT_LIST of HANDLERs, make sure that they're OK. */
+
+void
+check_handlers (tree handlers)
+{
+ tree_stmt_iterator i;
+
+ /* If we don't have a STATEMENT_LIST, then we've just got one
+ handler, and thus nothing to warn about. */
+ if (TREE_CODE (handlers) != STATEMENT_LIST)
+ return;
+
+ i = tsi_start (handlers);
+ if (!tsi_end_p (i))
+ while (1)
+ {
+ tree handler = tsi_stmt (i);
+ tsi_next (&i);
+
+ /* No more handlers; nothing to shadow. */
+ if (tsi_end_p (i))
+ break;
+ if (TREE_TYPE (handler) == NULL_TREE)
+ permerror (EXPR_LOCATION (handler), "%<...%>"
+ " handler must be the last handler for its try block");
+ else
+ check_handlers_1 (handler, i);
+ }
+}
+
+/* walk_tree helper for finish_noexcept_expr. Returns non-null if the
+ expression *TP causes the noexcept operator to evaluate to false.
+
+ 5.3.7 [expr.noexcept]: The result of the noexcept operator is false if
+ in a potentially-evaluated context the expression would contain
+ * a potentially evaluated call to a function, member function,
+ function pointer, or member function pointer that does not have a
+ non-throwing exception-specification (15.4),
+ * a potentially evaluated throw-expression (15.1),
+ * a potentially evaluated dynamic_cast expression dynamic_cast<T>(v),
+ where T is a reference type, that requires a run-time check (5.2.7), or
+ * a potentially evaluated typeid expression (5.2.8) applied to a glvalue
+ expression whose type is a polymorphic class type (10.3). */
+
+static tree
+check_noexcept_r (tree *tp, int * /*walk_subtrees*/, void * /*data*/)
+{
+ tree t = *tp;
+ enum tree_code code = TREE_CODE (t);
+ if (code == CALL_EXPR
+ || code == AGGR_INIT_EXPR)
+ {
+ /* We can only use the exception specification of the called function
+ for determining the value of a noexcept expression; we can't use
+ TREE_NOTHROW, as it might have a different value in another
+ translation unit, creating ODR problems.
+
+ We could use TREE_NOTHROW (t) for !TREE_PUBLIC fns, though... */
+ tree fn = (code == AGGR_INIT_EXPR
+ ? AGGR_INIT_EXPR_FN (t) : CALL_EXPR_FN (t));
+ tree type = TREE_TYPE (TREE_TYPE (fn));
+
+ STRIP_NOPS (fn);
+ if (TREE_CODE (fn) == ADDR_EXPR)
+ fn = TREE_OPERAND (fn, 0);
+ if (TREE_CODE (fn) == FUNCTION_DECL)
+ {
+ /* We do use TREE_NOTHROW for ABI internals like __dynamic_cast,
+ and for C library functions known not to throw. */
+ if (DECL_EXTERN_C_P (fn)
+ && (DECL_ARTIFICIAL (fn)
+ || nothrow_libfn_p (fn)))
+ return TREE_NOTHROW (fn) ? NULL_TREE : fn;
+ /* A call to a constexpr function is noexcept if the call
+ is a constant expression. */
+ if (DECL_DECLARED_CONSTEXPR_P (fn)
+ && is_sub_constant_expr (t))
+ return NULL_TREE;
+ }
+ if (!TYPE_NOTHROW_P (type))
+ return fn;
+ }
+
+ return NULL_TREE;
+}
+
+/* If a function that causes a noexcept-expression to be false isn't
+ defined yet, remember it and check it for TREE_NOTHROW again at EOF. */
+
+typedef struct GTY(()) pending_noexcept {
+ tree fn;
+ location_t loc;
+} pending_noexcept;
+static GTY(()) vec<pending_noexcept, va_gc> *pending_noexcept_checks;
+
+/* FN is a FUNCTION_DECL that caused a noexcept-expr to be false. Warn if
+ it can't throw. */
+
+static void
+maybe_noexcept_warning (tree fn)
+{
+ if (TREE_NOTHROW (fn))
+ {
+ warning (OPT_Wnoexcept, "noexcept-expression evaluates to %<false%> "
+ "because of a call to %qD", fn);
+ warning (OPT_Wnoexcept, "but %q+D does not throw; perhaps "
+ "it should be declared %<noexcept%>", fn);
+ }
+}
+
+/* Check any functions that weren't defined earlier when they caused a
+ noexcept expression to evaluate to false. */
+
+void
+perform_deferred_noexcept_checks (void)
+{
+ int i;
+ pending_noexcept *p;
+ location_t saved_loc = input_location;
+ FOR_EACH_VEC_SAFE_ELT (pending_noexcept_checks, i, p)
+ {
+ input_location = p->loc;
+ maybe_noexcept_warning (p->fn);
+ }
+ input_location = saved_loc;
+}
+
+/* Evaluate noexcept ( EXPR ). */
+
+tree
+finish_noexcept_expr (tree expr, tsubst_flags_t complain)
+{
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl)
+ return build_min (NOEXCEPT_EXPR, boolean_type_node, expr);
+
+ return (expr_noexcept_p (expr, complain)
+ ? boolean_true_node : boolean_false_node);
+}
+
+/* Returns whether EXPR is noexcept, possibly warning if allowed by
+ COMPLAIN. */
+
+bool
+expr_noexcept_p (tree expr, tsubst_flags_t complain)
+{
+ tree fn;
+
+ if (expr == error_mark_node)
+ return false;
+
+ fn = cp_walk_tree_without_duplicates (&expr, check_noexcept_r, 0);
+ if (fn)
+ {
+ if ((complain & tf_warning) && warn_noexcept
+ && TREE_CODE (fn) == FUNCTION_DECL)
+ {
+ if (!DECL_INITIAL (fn))
+ {
+ /* Not defined yet; check again at EOF. */
+ pending_noexcept p = {fn, input_location};
+ vec_safe_push (pending_noexcept_checks, p);
+ }
+ else
+ maybe_noexcept_warning (fn);
+ }
+ return false;
+ }
+ else
+ return true;
+}
+
+/* Return true iff SPEC is throw() or noexcept(true). */
+
+bool
+nothrow_spec_p (const_tree spec)
+{
+ gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec));
+ if (spec == NULL_TREE
+ || TREE_VALUE (spec) != NULL_TREE
+ || spec == noexcept_false_spec)
+ return false;
+ if (TREE_PURPOSE (spec) == NULL_TREE
+ || spec == noexcept_true_spec)
+ return true;
+ gcc_assert (processing_template_decl
+ || TREE_PURPOSE (spec) == error_mark_node);
+ return false;
+}
+
+/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE is noexcept. This is the
+ case for things declared noexcept(true) and, with -fnothrow-opt, for
+ throw() functions. */
+
+bool
+type_noexcept_p (const_tree type)
+{
+ tree spec = TYPE_RAISES_EXCEPTIONS (type);
+ gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec));
+ if (flag_nothrow_opt)
+ return nothrow_spec_p (spec);
+ else
+ return spec == noexcept_true_spec;
+}
+
+/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE can throw any type,
+ i.e. no exception-specification or noexcept(false). */
+
+bool
+type_throw_all_p (const_tree type)
+{
+ tree spec = TYPE_RAISES_EXCEPTIONS (type);
+ gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec));
+ return spec == NULL_TREE || spec == noexcept_false_spec;
+}
+
+/* Create a representation of the noexcept-specification with
+ constant-expression of EXPR. COMPLAIN is as for tsubst. */
+
+tree
+build_noexcept_spec (tree expr, int complain)
+{
+ /* This isn't part of the signature, so don't bother trying to evaluate
+ it until instantiation. */
+ if (!processing_template_decl && TREE_CODE (expr) != DEFERRED_NOEXCEPT)
+ {
+ expr = perform_implicit_conversion_flags (boolean_type_node, expr,
+ complain,
+ LOOKUP_NORMAL);
+ expr = cxx_constant_value (expr);
+ }
+ if (TREE_CODE (expr) == INTEGER_CST)
+ {
+ if (operand_equal_p (expr, boolean_true_node, 0))
+ return noexcept_true_spec;
+ else
+ {
+ gcc_checking_assert (operand_equal_p (expr, boolean_false_node, 0));
+ return noexcept_false_spec;
+ }
+ }
+ else if (expr == error_mark_node)
+ return error_mark_node;
+ else
+ {
+ gcc_assert (processing_template_decl
+ || TREE_CODE (expr) == DEFERRED_NOEXCEPT);
+ return build_tree_list (expr, NULL_TREE);
+ }
+}
+
+/* Returns a TRY_CATCH_EXPR that will put TRY_LIST and CATCH_LIST in the
+ TRY and CATCH locations. CATCH_LIST must be a STATEMENT_LIST */
+
+tree
+create_try_catch_expr (tree try_expr, tree catch_list)
+{
+ location_t loc = EXPR_LOCATION (try_expr);
+
+ append_to_statement_list (do_begin_catch (), &catch_list);
+ append_to_statement_list (build_throw (NULL_TREE), &catch_list);
+ tree catch_tf_expr = build_stmt (loc, TRY_FINALLY_EXPR, catch_list,
+ do_end_catch (NULL_TREE));
+ catch_list = build2 (CATCH_EXPR, void_type_node, NULL_TREE,
+ catch_tf_expr);
+ tree try_catch_expr = build_stmt (loc, TRY_CATCH_EXPR, try_expr, catch_list);
+ return try_catch_expr;
+}
+
+#include "gt-cp-except.h"
diff --git a/gcc-4.9/gcc/cp/expr.c b/gcc-4.9/gcc/cp/expr.c
new file mode 100644
index 000000000..a62e0f9b5
--- /dev/null
+++ b/gcc-4.9/gcc/cp/expr.c
@@ -0,0 +1,153 @@
+/* Convert language-specific tree expression to rtl instructions,
+ for GNU compiler.
+ Copyright (C) 1988-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "flags.h"
+#include "cp-tree.h"
+#include "tm_p.h"
+
+/* Expand C++-specific constants. Currently, this means PTRMEM_CST. */
+
+tree
+cplus_expand_constant (tree cst)
+{
+ switch (TREE_CODE (cst))
+ {
+ case PTRMEM_CST:
+ {
+ tree type = TREE_TYPE (cst);
+ tree member;
+
+ /* Find the member. */
+ member = PTRMEM_CST_MEMBER (cst);
+
+ /* We can't lower this until the class is complete. */
+ if (!COMPLETE_TYPE_P (DECL_CONTEXT (member)))
+ return cst;
+
+ if (TREE_CODE (member) == FIELD_DECL)
+ {
+ /* Find the offset for the field. */
+ cst = byte_position (member);
+ while (!same_type_p (DECL_CONTEXT (member),
+ TYPE_PTRMEM_CLASS_TYPE (type)))
+ {
+ /* The MEMBER must have been nestled within an
+ anonymous aggregate contained in TYPE. Find the
+ anonymous aggregate. */
+ member = lookup_anon_field (TYPE_PTRMEM_CLASS_TYPE (type),
+ DECL_CONTEXT (member));
+ cst = size_binop (PLUS_EXPR, cst, byte_position (member));
+ }
+ cst = fold (build_nop (type, cst));
+ }
+ else
+ {
+ tree delta;
+ tree pfn;
+
+ expand_ptrmemfunc_cst (cst, &delta, &pfn);
+ cst = build_ptrmemfunc1 (type, delta, pfn);
+ }
+ }
+ break;
+
+ default:
+ /* There's nothing to do. */
+ break;
+ }
+
+ return cst;
+}
+
+/* Called whenever an expression is used
+ in a rvalue context. */
+
+tree
+mark_rvalue_use (tree expr)
+{
+ mark_exp_read (expr);
+ return expr;
+}
+
+/* Called whenever an expression is used
+ in a lvalue context. */
+
+tree
+mark_lvalue_use (tree expr)
+{
+ mark_exp_read (expr);
+ return expr;
+}
+
+/* Called whenever an expression is used in a type use context. */
+
+tree
+mark_type_use (tree expr)
+{
+ mark_exp_read (expr);
+ return expr;
+}
+
+/* Mark EXP as read, not just set, for set but not used -Wunused
+ warning purposes. */
+
+void
+mark_exp_read (tree exp)
+{
+ if (exp == NULL)
+ return;
+
+ switch (TREE_CODE (exp))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ DECL_READ_P (exp) = 1;
+ break;
+ case ARRAY_REF:
+ case COMPONENT_REF:
+ case MODIFY_EXPR:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ CASE_CONVERT:
+ case ADDR_EXPR:
+ case INDIRECT_REF:
+ case FLOAT_EXPR:
+ mark_exp_read (TREE_OPERAND (exp, 0));
+ break;
+ case COMPOUND_EXPR:
+ mark_exp_read (TREE_OPERAND (exp, 1));
+ break;
+ case COND_EXPR:
+ if (TREE_OPERAND (exp, 1))
+ mark_exp_read (TREE_OPERAND (exp, 1));
+ if (TREE_OPERAND (exp, 2))
+ mark_exp_read (TREE_OPERAND (exp, 2));
+ break;
+ default:
+ break;
+ }
+}
+
diff --git a/gcc-4.9/gcc/cp/friend.c b/gcc-4.9/gcc/cp/friend.c
new file mode 100644
index 000000000..150b392b6
--- /dev/null
+++ b/gcc-4.9/gcc/cp/friend.c
@@ -0,0 +1,611 @@
+/* Help friends in C++.
+ Copyright (C) 1997-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "cp-tree.h"
+#include "flags.h"
+
+/* Friend data structures are described in cp-tree.h. */
+
+/* Returns nonzero if SUPPLICANT is a friend of TYPE. */
+
+int
+is_friend (tree type, tree supplicant)
+{
+ int declp;
+ tree list;
+ tree context;
+
+ if (supplicant == NULL_TREE || type == NULL_TREE)
+ return 0;
+
+ declp = DECL_P (supplicant);
+
+ if (declp)
+ /* It's a function decl. */
+ {
+ tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type));
+ tree name = DECL_NAME (supplicant);
+
+ for (; list ; list = TREE_CHAIN (list))
+ {
+ if (name == FRIEND_NAME (list))
+ {
+ tree friends = FRIEND_DECLS (list);
+ for (; friends ; friends = TREE_CHAIN (friends))
+ {
+ tree this_friend = TREE_VALUE (friends);
+
+ if (this_friend == NULL_TREE)
+ continue;
+
+ if (supplicant == this_friend)
+ return 1;
+
+ if (is_specialization_of_friend (supplicant, this_friend))
+ return 1;
+ }
+ break;
+ }
+ }
+ }
+ else
+ /* It's a type. */
+ {
+ if (same_type_p (supplicant, type))
+ return 1;
+
+ list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
+ for (; list ; list = TREE_CHAIN (list))
+ {
+ tree t = TREE_VALUE (list);
+
+ if (TREE_CODE (t) == TEMPLATE_DECL ?
+ is_specialization_of_friend (TYPE_MAIN_DECL (supplicant), t) :
+ same_type_p (supplicant, t))
+ return 1;
+ }
+ }
+
+ if (declp)
+ {
+ if (DECL_FUNCTION_MEMBER_P (supplicant))
+ context = DECL_CONTEXT (supplicant);
+ else
+ context = NULL_TREE;
+ }
+ else
+ {
+ if (TYPE_CLASS_SCOPE_P (supplicant))
+ /* Nested classes get the same access as their enclosing types, as
+ per DR 45 (this is a change from the standard). */
+ context = TYPE_CONTEXT (supplicant);
+ else
+ /* Local classes have the same access as the enclosing function. */
+ context = decl_function_context (TYPE_MAIN_DECL (supplicant));
+ }
+
+ /* A namespace is not friend to anybody. */
+ if (context && TREE_CODE (context) == NAMESPACE_DECL)
+ context = NULL_TREE;
+
+ if (context)
+ return is_friend (type, context);
+
+ return 0;
+}
+
+/* Add a new friend to the friends of the aggregate type TYPE.
+ DECL is the FUNCTION_DECL of the friend being added.
+
+ If COMPLAIN is true, warning about duplicate friend is issued.
+ We want to have this diagnostics during parsing but not
+ when a template is being instantiated. */
+
+void
+add_friend (tree type, tree decl, bool complain)
+{
+ tree typedecl;
+ tree list;
+ tree name;
+ tree ctx;
+
+ if (decl == error_mark_node)
+ return;
+
+ typedecl = TYPE_MAIN_DECL (type);
+ list = DECL_FRIENDLIST (typedecl);
+ name = DECL_NAME (decl);
+ type = TREE_TYPE (typedecl);
+
+ while (list)
+ {
+ if (name == FRIEND_NAME (list))
+ {
+ tree friends = FRIEND_DECLS (list);
+ for (; friends ; friends = TREE_CHAIN (friends))
+ {
+ if (decl == TREE_VALUE (friends))
+ {
+ if (complain)
+ warning (0, "%qD is already a friend of class %qT",
+ decl, type);
+ return;
+ }
+ }
+
+ maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
+
+ TREE_VALUE (list) = tree_cons (NULL_TREE, decl,
+ TREE_VALUE (list));
+ return;
+ }
+ list = TREE_CHAIN (list);
+ }
+
+ ctx = DECL_CONTEXT (decl);
+ if (ctx && CLASS_TYPE_P (ctx) && !uses_template_parms (ctx))
+ perform_or_defer_access_check (TYPE_BINFO (ctx), decl, decl,
+ tf_warning_or_error);
+
+ maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
+
+ DECL_FRIENDLIST (typedecl)
+ = tree_cons (DECL_NAME (decl), build_tree_list (NULL_TREE, decl),
+ DECL_FRIENDLIST (typedecl));
+ if (!uses_template_parms (type))
+ DECL_BEFRIENDING_CLASSES (decl)
+ = tree_cons (NULL_TREE, type,
+ DECL_BEFRIENDING_CLASSES (decl));
+}
+
+/* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already
+ been defined, we make all of its member functions friends of
+ TYPE. If not, we make it a pending friend, which can later be added
+ when its definition is seen. If a type is defined, then its TYPE_DECL's
+ DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
+ classes that are not defined. If a type has not yet been defined,
+ then the DECL_WAITING_FRIENDS contains a list of types
+ waiting to make it their friend. Note that these two can both
+ be in use at the same time!
+
+ If COMPLAIN is true, warning about duplicate friend is issued.
+ We want to have this diagnostics during parsing but not
+ when a template is being instantiated. */
+
+void
+make_friend_class (tree type, tree friend_type, bool complain)
+{
+ tree classes;
+
+ /* CLASS_TEMPLATE_DEPTH counts the number of template headers for
+ the enclosing class. FRIEND_DEPTH counts the number of template
+ headers used for this friend declaration. TEMPLATE_MEMBER_P,
+ defined inside the `if' block for TYPENAME_TYPE case, is true if
+ a template header in FRIEND_DEPTH is intended for DECLARATOR.
+ For example, the code
+
+ template <class T> struct A {
+ template <class U> struct B {
+ template <class V> template <class W>
+ friend class C<V>::D;
+ };
+ };
+
+ will eventually give the following results
+
+ 1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U').
+ 2. FRIEND_DEPTH equals 2 (for `V' and `W').
+ 3. TEMPLATE_MEMBER_P is true (for `W').
+
+ The friend is a template friend iff FRIEND_DEPTH is nonzero. */
+
+ int class_template_depth = template_class_depth (type);
+ int friend_depth = processing_template_decl - class_template_depth;
+
+ if (! MAYBE_CLASS_TYPE_P (friend_type)
+ && TREE_CODE (friend_type) != TEMPLATE_TEMPLATE_PARM)
+ {
+ /* N1791: If the type specifier in a friend declaration designates a
+ (possibly cv-qualified) class type, that class is declared as a
+ friend; otherwise, the friend declaration is ignored.
+
+ So don't complain in C++11 mode. */
+ if (cxx_dialect < cxx11)
+ pedwarn (input_location, complain ? 0 : OPT_Wpedantic,
+ "invalid type %qT declared %<friend%>", friend_type);
+ return;
+ }
+
+ friend_type = cv_unqualified (friend_type);
+
+ if (check_for_bare_parameter_packs (friend_type))
+ return;
+
+ if (friend_depth)
+ /* If the TYPE is a template then it makes sense for it to be
+ friends with itself; this means that each instantiation is
+ friends with all other instantiations. */
+ {
+ if (CLASS_TYPE_P (friend_type)
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type)
+ && uses_template_parms (friend_type))
+ {
+ /* [temp.friend]
+ Friend declarations shall not declare partial
+ specializations. */
+ error ("partial specialization %qT declared %<friend%>",
+ friend_type);
+ return;
+ }
+ }
+ else if (same_type_p (type, friend_type))
+ {
+ if (complain)
+ warning (0, "class %qT is implicitly friends with itself",
+ type);
+ return;
+ }
+
+ /* [temp.friend]
+
+ A friend of a class or class template can be a function or
+ class template, a specialization of a function template or
+ class template, or an ordinary (nontemplate) function or
+ class. */
+ if (!friend_depth)
+ ;/* ok */
+ else if (TREE_CODE (friend_type) == TYPENAME_TYPE)
+ {
+ if (TREE_CODE (TYPENAME_TYPE_FULLNAME (friend_type))
+ == TEMPLATE_ID_EXPR)
+ {
+ /* template <class U> friend class T::X<U>; */
+ /* [temp.friend]
+ Friend declarations shall not declare partial
+ specializations. */
+ error ("partial specialization %qT declared %<friend%>",
+ friend_type);
+ return;
+ }
+ else
+ {
+ /* We will figure this out later. */
+ bool template_member_p = false;
+
+ tree ctype = TYPE_CONTEXT (friend_type);
+ tree name = TYPE_IDENTIFIER (friend_type);
+ tree decl;
+
+ if (!uses_template_parms_level (ctype, class_template_depth
+ + friend_depth))
+ template_member_p = true;
+
+ if (class_template_depth)
+ {
+ /* We rely on tsubst_friend_class to check the
+ validity of the declaration later. */
+ if (template_member_p)
+ friend_type
+ = make_unbound_class_template (ctype,
+ name,
+ current_template_parms,
+ tf_error);
+ else
+ friend_type
+ = make_typename_type (ctype, name, class_type, tf_error);
+ }
+ else
+ {
+ decl = lookup_member (ctype, name, 0, true, tf_warning_or_error);
+ if (!decl)
+ {
+ error ("%qT is not a member of %qT", name, ctype);
+ return;
+ }
+ if (template_member_p && !DECL_CLASS_TEMPLATE_P (decl))
+ {
+ error ("%qT is not a member class template of %qT",
+ name, ctype);
+ inform (input_location, "%q+D declared here", decl);
+ return;
+ }
+ if (!template_member_p && (TREE_CODE (decl) != TYPE_DECL
+ || !CLASS_TYPE_P (TREE_TYPE (decl))))
+ {
+ error ("%qT is not a nested class of %qT",
+ name, ctype);
+ inform (input_location, "%q+D declared here", decl);
+ return;
+ }
+
+ friend_type = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl));
+ }
+ }
+ }
+ else if (TREE_CODE (friend_type) == TEMPLATE_TYPE_PARM)
+ {
+ /* template <class T> friend class T; */
+ error ("template parameter type %qT declared %<friend%>", friend_type);
+ return;
+ }
+ else if (TREE_CODE (friend_type) == TEMPLATE_TEMPLATE_PARM)
+ friend_type = TYPE_NAME (friend_type);
+ else if (!CLASSTYPE_TEMPLATE_INFO (friend_type))
+ {
+ /* template <class T> friend class A; where A is not a template */
+ error ("%q#T is not a template", friend_type);
+ return;
+ }
+ else
+ /* template <class T> friend class A; where A is a template */
+ friend_type = CLASSTYPE_TI_TEMPLATE (friend_type);
+
+ if (friend_type == error_mark_node)
+ return;
+
+ /* See if it is already a friend. */
+ for (classes = CLASSTYPE_FRIEND_CLASSES (type);
+ classes;
+ classes = TREE_CHAIN (classes))
+ {
+ tree probe = TREE_VALUE (classes);
+
+ if (TREE_CODE (friend_type) == TEMPLATE_DECL)
+ {
+ if (friend_type == probe)
+ {
+ if (complain)
+ warning (0, "%qD is already a friend of %qT", probe, type);
+ break;
+ }
+ }
+ else if (TREE_CODE (probe) != TEMPLATE_DECL)
+ {
+ if (same_type_p (probe, friend_type))
+ {
+ if (complain)
+ warning (0, "%qT is already a friend of %qT", probe, type);
+ break;
+ }
+ }
+ }
+
+ if (!classes)
+ {
+ maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1);
+
+ CLASSTYPE_FRIEND_CLASSES (type)
+ = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
+ if (TREE_CODE (friend_type) == TEMPLATE_DECL)
+ friend_type = TREE_TYPE (friend_type);
+ if (!uses_template_parms (type))
+ CLASSTYPE_BEFRIENDING_CLASSES (friend_type)
+ = tree_cons (NULL_TREE, type,
+ CLASSTYPE_BEFRIENDING_CLASSES (friend_type));
+ }
+}
+
+/* Record DECL (a FUNCTION_DECL) as a friend of the
+ CURRENT_CLASS_TYPE. If DECL is a member function, CTYPE is the
+ class of which it is a member, as named in the friend declaration.
+ DECLARATOR is the name of the friend. FUNCDEF_FLAG is true if the
+ friend declaration is a definition of the function. FLAGS is as
+ for grokclass fn. */
+
+tree
+do_friend (tree ctype, tree declarator, tree decl,
+ tree attrlist, enum overload_flags flags,
+ bool funcdef_flag)
+{
+ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+ gcc_assert (!ctype || MAYBE_CLASS_TYPE_P (ctype));
+
+ /* Every decl that gets here is a friend of something. */
+ DECL_FRIEND_P (decl) = 1;
+
+ /* Unfortunately, we have to handle attributes here. Normally we would
+ handle them in start_decl_1, but since this is a friend decl start_decl_1
+ never gets to see it. */
+
+ /* Set attributes here so if duplicate decl, will have proper attributes. */
+ cplus_decl_attributes (&decl, attrlist, 0);
+
+ if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
+ {
+ declarator = TREE_OPERAND (declarator, 0);
+ if (is_overloaded_fn (declarator))
+ declarator = DECL_NAME (get_first_fn (declarator));
+ }
+
+ if (ctype)
+ {
+ /* CLASS_TEMPLATE_DEPTH counts the number of template headers for
+ the enclosing class. FRIEND_DEPTH counts the number of template
+ headers used for this friend declaration. TEMPLATE_MEMBER_P is
+ true if a template header in FRIEND_DEPTH is intended for
+ DECLARATOR. For example, the code
+
+ template <class T> struct A {
+ template <class U> struct B {
+ template <class V> template <class W>
+ friend void C<V>::f(W);
+ };
+ };
+
+ will eventually give the following results
+
+ 1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U').
+ 2. FRIEND_DEPTH equals 2 (for `V' and `W').
+ 3. TEMPLATE_MEMBER_P is true (for `W'). */
+
+ int class_template_depth = template_class_depth (current_class_type);
+ int friend_depth = processing_template_decl - class_template_depth;
+ /* We will figure this out later. */
+ bool template_member_p = false;
+
+ tree cname = TYPE_NAME (ctype);
+ if (TREE_CODE (cname) == TYPE_DECL)
+ cname = DECL_NAME (cname);
+
+ /* A method friend. */
+ if (flags == NO_SPECIAL && declarator == cname)
+ DECL_CONSTRUCTOR_P (decl) = 1;
+
+ grokclassfn (ctype, decl, flags);
+
+ if (friend_depth)
+ {
+ if (!uses_template_parms_level (ctype, class_template_depth
+ + friend_depth))
+ template_member_p = true;
+ }
+
+ /* A nested class may declare a member of an enclosing class
+ to be a friend, so we do lookup here even if CTYPE is in
+ the process of being defined. */
+ if (class_template_depth
+ || COMPLETE_OR_OPEN_TYPE_P (ctype))
+ {
+ if (DECL_TEMPLATE_INFO (decl))
+ /* DECL is a template specialization. No need to
+ build a new TEMPLATE_DECL. */
+ ;
+ else if (class_template_depth)
+ /* We rely on tsubst_friend_function to check the
+ validity of the declaration later. */
+ decl = push_template_decl_real (decl, /*is_friend=*/true);
+ else
+ decl = check_classfn (ctype, decl,
+ template_member_p
+ ? current_template_parms
+ : NULL_TREE);
+
+ if ((template_member_p
+ /* Always pull out the TEMPLATE_DECL if we have a friend
+ template in a class template so that it gets tsubsted
+ properly later on (59956). tsubst_friend_function knows
+ how to tell this apart from a member template. */
+ || (class_template_depth && friend_depth))
+ && decl && TREE_CODE (decl) == FUNCTION_DECL)
+ decl = DECL_TI_TEMPLATE (decl);
+
+ if (decl)
+ add_friend (current_class_type, decl, /*complain=*/true);
+ }
+ else
+ error ("member %qD declared as friend before type %qT defined",
+ decl, ctype);
+ }
+ /* A global friend.
+ @@ or possibly a friend from a base class ?!? */
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ int is_friend_template = PROCESSING_REAL_TEMPLATE_DECL_P ();
+
+ /* Friends must all go through the overload machinery,
+ even though they may not technically be overloaded.
+
+ Note that because classes all wind up being top-level
+ in their scope, their friend wind up in top-level scope as well. */
+ if (funcdef_flag)
+ SET_DECL_FRIEND_CONTEXT (decl, current_class_type);
+
+ if (! DECL_USE_TEMPLATE (decl))
+ {
+ /* We must check whether the decl refers to template
+ arguments before push_template_decl_real adds a
+ reference to the containing template class. */
+ int warn = (warn_nontemplate_friend
+ && ! funcdef_flag && ! is_friend_template
+ && current_template_parms
+ && uses_template_parms (decl));
+
+ if (is_friend_template
+ || template_class_depth (current_class_type) != 0)
+ /* We can't call pushdecl for a template class, since in
+ general, such a declaration depends on template
+ parameters. Instead, we call pushdecl when the class
+ is instantiated. */
+ decl = push_template_decl_real (decl, /*is_friend=*/true);
+ else if (current_function_decl)
+ {
+ /* This must be a local class. 11.5p11:
+
+ If a friend declaration appears in a local class (9.8) and
+ the name specified is an unqualified name, a prior
+ declaration is looked up without considering scopes that
+ are outside the innermost enclosing non-class scope. For a
+ friend function declaration, if there is no prior
+ declaration, the program is ill-formed. */
+ tree t = lookup_name_innermost_nonclass_level (DECL_NAME (decl));
+ if (t)
+ decl = pushdecl_maybe_friend (decl, /*is_friend=*/true);
+ else
+ {
+ error ("friend declaration %qD in local class without "
+ "prior declaration", decl);
+ return error_mark_node;
+ }
+ }
+ else
+ {
+ /* We can't use pushdecl, as we might be in a template
+ class specialization, and pushdecl will insert an
+ unqualified friend decl into the template parameter
+ scope, rather than the namespace containing it. */
+ tree ns = decl_namespace_context (decl);
+
+ push_nested_namespace (ns);
+ decl = pushdecl_namespace_level (decl, /*is_friend=*/true);
+ pop_nested_namespace (ns);
+ }
+
+ if (warn)
+ {
+ static int explained;
+ bool warned;
+
+ warned = warning (OPT_Wnon_template_friend, "friend declaration "
+ "%q#D declares a non-template function", decl);
+ if (! explained && warned)
+ {
+ inform (input_location, "(if this is not what you intended, make sure "
+ "the function template has already been declared "
+ "and add <> after the function name here) ");
+ explained = 1;
+ }
+ }
+ }
+
+ if (decl == error_mark_node)
+ return error_mark_node;
+
+ add_friend (current_class_type,
+ is_friend_template ? DECL_TI_TEMPLATE (decl) : decl,
+ /*complain=*/true);
+ DECL_FRIEND_P (decl) = 1;
+ }
+
+ return decl;
+}
diff --git a/gcc-4.9/gcc/cp/g++spec.c b/gcc-4.9/gcc/cp/g++spec.c
new file mode 100644
index 000000000..79117673b
--- /dev/null
+++ b/gcc-4.9/gcc/cp/g++spec.c
@@ -0,0 +1,405 @@
+/* Specific flags and argument handling of the C++ front end.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "gcc.h"
+#include "opts.h"
+
+/* This bit is set if we saw a `-xfoo' language specification. */
+#define LANGSPEC (1<<1)
+/* This bit is set if they did `-lm' or `-lmath'. */
+#define MATHLIB (1<<2)
+/* This bit is set if they did `-lrt' or equivalent. */
+#define TIMELIB (1<<3)
+/* This bit is set if they did `-lc'. */
+#define WITHLIBC (1<<4)
+/* Skip this option. */
+#define SKIPOPT (1<<5)
+
+#ifndef MATH_LIBRARY
+#define MATH_LIBRARY "m"
+#endif
+#ifndef MATH_LIBRARY_PROFILE
+#define MATH_LIBRARY_PROFILE MATH_LIBRARY
+#endif
+
+#ifndef TIME_LIBRARY
+#define TIME_LIBRARY ""
+#endif
+
+#ifndef LIBSTDCXX
+#define LIBSTDCXX "stdc++"
+#endif
+#ifndef LIBSTDCXX_PROFILE
+#define LIBSTDCXX_PROFILE LIBSTDCXX
+#endif
+#ifndef LIBSTDCXX_STATIC
+#define LIBSTDCXX_STATIC NULL
+#endif
+
+void
+lang_specific_driver (struct cl_decoded_option **in_decoded_options,
+ unsigned int *in_decoded_options_count,
+ int *in_added_libraries)
+{
+ unsigned int i, j;
+
+ /* If nonzero, the user gave us the `-p' or `-pg' flag. */
+ int saw_profile_flag = 0;
+
+ /* What do with libstdc++:
+ -1 means we should not link in libstdc++
+ 0 means we should link in libstdc++ if it is needed
+ 1 means libstdc++ is needed and should be linked in.
+ 2 means libstdc++ is needed and should be linked statically. */
+ int library = 0;
+
+ /* The number of arguments being added to what's in argv, other than
+ libraries. We use this to track the number of times we've inserted
+ -xc++/-xnone. */
+ int added = 0;
+
+ /* The new argument list will be contained in this. */
+ struct cl_decoded_option *new_decoded_options;
+
+ /* Nonzero if we saw a `-xfoo' language specification on the
+ command line. Used to avoid adding our own -xc++ if the user
+ already gave a language for the file. */
+ int saw_speclang = 0;
+
+ /* "-lm" or "-lmath" if it appears on the command line. */
+ const struct cl_decoded_option *saw_math = NULL;
+
+ /* "-lrt" or eqivalent if it appears on the command line. */
+ const struct cl_decoded_option *saw_time = NULL;
+
+ /* "-lc" if it appears on the command line. */
+ const struct cl_decoded_option *saw_libc = NULL;
+
+ /* An array used to flag each argument that needs a bit set for
+ LANGSPEC, MATHLIB, TIMELIB, or WITHLIBC. */
+ int *args;
+
+ /* By default, we throw on the math library if we have one. */
+ int need_math = (MATH_LIBRARY[0] != '\0');
+
+ /* By default, we throw on the time library if we have one. */
+ int need_time = (TIME_LIBRARY[0] != '\0');
+
+ /* True if we saw -static. */
+ int static_link = 0;
+
+ /* True if we should add -shared-libgcc to the command-line. */
+ int shared_libgcc = 1;
+
+ /* The total number of arguments with the new stuff. */
+ unsigned int argc;
+
+ /* The argument list. */
+ struct cl_decoded_option *decoded_options;
+
+ /* The number of libraries added in. */
+ int added_libraries;
+
+ /* The total number of arguments with the new stuff. */
+ unsigned int num_args = 1;
+
+ argc = *in_decoded_options_count;
+ decoded_options = *in_decoded_options;
+ added_libraries = *in_added_libraries;
+
+ args = XCNEWVEC (int, argc);
+
+ for (i = 1; i < argc; i++)
+ {
+ const char *arg = decoded_options[i].arg;
+ if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
+ continue; /* Avoid examining arguments of options missing them. */
+
+ switch (decoded_options[i].opt_index)
+ {
+ case OPT_nostdlib:
+ case OPT_nodefaultlibs:
+ library = -1;
+ break;
+
+ case OPT_l:
+ if (strcmp (arg, MATH_LIBRARY) == 0)
+ {
+ args[i] |= MATHLIB;
+ need_math = 0;
+ }
+ else if (strcmp (arg, TIME_LIBRARY) == 0)
+ {
+ args[i] |= TIMELIB;
+ need_time = 0;
+ }
+ else if (strcmp (arg, "c") == 0)
+ args[i] |= WITHLIBC;
+ else
+ /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */
+ library = (library == 0) ? 1 : library;
+ break;
+
+ case OPT_pg:
+ case OPT_p:
+ saw_profile_flag++;
+ break;
+
+ case OPT_x:
+ if (library == 0
+ && (strcmp (arg, "c++") == 0
+ || strcmp (arg, "c++-cpp-output") == 0
+ || strcmp (arg, "objective-c++") == 0
+ || strcmp (arg, "objective-c++-cpp-output") == 0))
+ library = 1;
+
+ saw_speclang = 1;
+ break;
+
+ case OPT_Xlinker:
+ case OPT_Wl_:
+ /* Arguments that go directly to the linker might be .o files,
+ or something, and so might cause libstdc++ to be needed. */
+ if (library == 0)
+ library = 1;
+ break;
+
+ case OPT_c:
+ case OPT_S:
+ case OPT_E:
+ case OPT_M:
+ case OPT_MM:
+ case OPT_fsyntax_only:
+ /* Don't specify libraries if we won't link, since that would
+ cause a warning. */
+ library = -1;
+ break;
+
+ case OPT_static:
+ static_link = 1;
+ break;
+
+ case OPT_static_libgcc:
+ shared_libgcc = 0;
+ break;
+
+ case OPT_static_libstdc__:
+ library = library >= 0 ? 2 : library;
+ args[i] |= SKIPOPT;
+ break;
+
+ case OPT_SPECIAL_input_file:
+ {
+ int len;
+
+ /* We don't do this anymore, since we don't get them with minus
+ signs on them. */
+ if (arg[0] == '\0' || arg[1] == '\0')
+ continue;
+
+ if (saw_speclang)
+ {
+ saw_speclang = 0;
+ continue;
+ }
+
+ /* If the filename ends in .[chi], put options around it.
+ But not if a specified -x option is currently active. */
+ len = strlen (arg);
+ if (len > 2
+ && (arg[len - 1] == 'c'
+ || arg[len - 1] == 'i'
+ || arg[len - 1] == 'h')
+ && arg[len - 2] == '.')
+ {
+ args[i] |= LANGSPEC;
+ added += 2;
+ }
+
+ /* If we don't know that this is a header file, we might
+ need to be linking in the libraries. */
+ if (library == 0)
+ {
+ if ((len <= 2 || strcmp (arg + (len - 2), ".H") != 0)
+ && (len <= 2 || strcmp (arg + (len - 2), ".h") != 0)
+ && (len <= 4 || strcmp (arg + (len - 4), ".hpp") != 0)
+ && (len <= 3 || strcmp (arg + (len - 3), ".hp") != 0)
+ && (len <= 4 || strcmp (arg + (len - 4), ".hxx") != 0)
+ && (len <= 4 || strcmp (arg + (len - 4), ".h++") != 0)
+ && (len <= 4 || strcmp (arg + (len - 4), ".HPP") != 0)
+ && (len <= 4 || strcmp (arg + (len - 4), ".tcc") != 0)
+ && (len <= 3 || strcmp (arg + (len - 3), ".hh") != 0))
+ library = 1;
+ }
+ }
+ break;
+ }
+ }
+
+ /* There's no point adding -shared-libgcc if we don't have a shared
+ libgcc. */
+#ifndef ENABLE_SHARED_LIBGCC
+ shared_libgcc = 0;
+#endif
+
+ /* Add one for shared_libgcc or extra static library. */
+ num_args = argc + added + need_math + (library > 0) * 4 + 1;
+ new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
+
+ i = 0;
+ j = 0;
+
+ /* Copy the 0th argument, i.e., the name of the program itself. */
+ new_decoded_options[j++] = decoded_options[i++];
+
+ /* NOTE: We start at 1 now, not 0. */
+ while (i < argc)
+ {
+ new_decoded_options[j] = decoded_options[i];
+
+ /* Make sure -lstdc++ is before the math library, since libstdc++
+ itself uses those math routines. */
+ if (!saw_math && (args[i] & MATHLIB) && library > 0)
+ {
+ --j;
+ saw_math = &decoded_options[i];
+ }
+
+ if (!saw_time && (args[i] & TIMELIB) && library > 0)
+ {
+ --j;
+ saw_time = &decoded_options[i];
+ }
+
+ if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
+ {
+ --j;
+ saw_libc = &decoded_options[i];
+ }
+
+ /* Wrap foo.[chi] files in a language specification to
+ force the gcc compiler driver to run cc1plus on them. */
+ if (args[i] & LANGSPEC)
+ {
+ const char *arg = decoded_options[i].arg;
+ int len = strlen (arg);
+ switch (arg[len - 1])
+ {
+ case 'c':
+ generate_option (OPT_x, "c++", 1, CL_DRIVER,
+ &new_decoded_options[j++]);
+ break;
+ case 'i':
+ generate_option (OPT_x, "c++-cpp-output", 1, CL_DRIVER,
+ &new_decoded_options[j++]);
+ break;
+ case 'h':
+ generate_option (OPT_x, "c++-header", 1, CL_DRIVER,
+ &new_decoded_options[j++]);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ new_decoded_options[j++] = decoded_options[i];
+ generate_option (OPT_x, "none", 1, CL_DRIVER,
+ &new_decoded_options[j]);
+ }
+
+ if ((args[i] & SKIPOPT) != 0)
+ --j;
+
+ i++;
+ j++;
+ }
+
+ /* Add `-lstdc++' if we haven't already done so. */
+ if (library > 0)
+ {
+#ifdef HAVE_LD_STATIC_DYNAMIC
+ if (library > 1 && !static_link)
+ {
+ generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
+ &new_decoded_options[j]);
+ j++;
+ }
+#endif
+ generate_option (OPT_l,
+ saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX, 1,
+ CL_DRIVER, &new_decoded_options[j]);
+ added_libraries++;
+ j++;
+ /* Add target-dependent static library, if necessary. */
+ if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
+ {
+ generate_option (OPT_l, LIBSTDCXX_STATIC, 1,
+ CL_DRIVER, &new_decoded_options[j]);
+ added_libraries++;
+ j++;
+ }
+#ifdef HAVE_LD_STATIC_DYNAMIC
+ if (library > 1 && !static_link)
+ {
+ generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
+ &new_decoded_options[j]);
+ j++;
+ }
+#endif
+ }
+ if (saw_math)
+ new_decoded_options[j++] = *saw_math;
+ else if (library > 0 && need_math)
+ {
+ generate_option (OPT_l,
+ saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY,
+ 1, CL_DRIVER, &new_decoded_options[j]);
+ added_libraries++;
+ j++;
+ }
+ if (saw_time)
+ new_decoded_options[j++] = *saw_time;
+ else if (library > 0 && need_time)
+ {
+ generate_option (OPT_l, TIME_LIBRARY, 1, CL_DRIVER,
+ &new_decoded_options[j]);
+ added_libraries++;
+ j++;
+ }
+ if (saw_libc)
+ new_decoded_options[j++] = *saw_libc;
+ if (shared_libgcc && !static_link)
+ generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
+ &new_decoded_options[j++]);
+
+ *in_decoded_options_count = j;
+ *in_decoded_options = new_decoded_options;
+ *in_added_libraries = added_libraries;
+}
+
+/* Called before linking. Returns 0 on success and -1 on failure. */
+int lang_specific_pre_link (void) /* Not used for C++. */
+{
+ return 0;
+}
+
+/* Number of extra output files that lang_specific_pre_link may generate. */
+int lang_specific_extra_outfiles = 0; /* Not used for C++. */
diff --git a/gcc-4.9/gcc/cp/init.c b/gcc-4.9/gcc/cp/init.c
new file mode 100644
index 000000000..2e1cddef4
--- /dev/null
+++ b/gcc-4.9/gcc/cp/init.c
@@ -0,0 +1,4263 @@
+/* Handle initialization things in C++.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Contributed by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* High-level class interface. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "varasm.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "target.h"
+#include "gimplify.h"
+
+static bool begin_init_stmts (tree *, tree *);
+static tree finish_init_stmts (bool, tree, tree);
+static void construct_virtual_base (tree, tree);
+static void expand_aggr_init_1 (tree, tree, tree, tree, int, tsubst_flags_t);
+static void expand_default_init (tree, tree, tree, tree, int, tsubst_flags_t);
+static void perform_member_init (tree, tree);
+static tree build_builtin_delete_call (tree);
+static int member_init_ok_or_else (tree, tree, tree);
+static void expand_virtual_init (tree, tree);
+static tree sort_mem_initializers (tree, tree);
+static tree initializing_context (tree);
+static void expand_cleanup_for_base (tree, tree);
+static tree dfs_initialize_vtbl_ptrs (tree, void *);
+static tree build_field_list (tree, tree, int *);
+static int diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool, bool);
+
+/* We are about to generate some complex initialization code.
+ Conceptually, it is all a single expression. However, we may want
+ to include conditionals, loops, and other such statement-level
+ constructs. Therefore, we build the initialization code inside a
+ statement-expression. This function starts such an expression.
+ STMT_EXPR_P and COMPOUND_STMT_P are filled in by this function;
+ pass them back to finish_init_stmts when the expression is
+ complete. */
+
+static bool
+begin_init_stmts (tree *stmt_expr_p, tree *compound_stmt_p)
+{
+ bool is_global = !building_stmt_list_p ();
+
+ *stmt_expr_p = begin_stmt_expr ();
+ *compound_stmt_p = begin_compound_stmt (BCS_NO_SCOPE);
+
+ return is_global;
+}
+
+/* Finish out the statement-expression begun by the previous call to
+ begin_init_stmts. Returns the statement-expression itself. */
+
+static tree
+finish_init_stmts (bool is_global, tree stmt_expr, tree compound_stmt)
+{
+ finish_compound_stmt (compound_stmt);
+
+ stmt_expr = finish_stmt_expr (stmt_expr, true);
+
+ gcc_assert (!building_stmt_list_p () == is_global);
+
+ return stmt_expr;
+}
+
+/* Constructors */
+
+/* Called from initialize_vtbl_ptrs via dfs_walk. BINFO is the base
+ which we want to initialize the vtable pointer for, DATA is
+ TREE_LIST whose TREE_VALUE is the this ptr expression. */
+
+static tree
+dfs_initialize_vtbl_ptrs (tree binfo, void *data)
+{
+ if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
+ return dfs_skip_bases;
+
+ if (!BINFO_PRIMARY_P (binfo) || BINFO_VIRTUAL_P (binfo))
+ {
+ tree base_ptr = TREE_VALUE ((tree) data);
+
+ base_ptr = build_base_path (PLUS_EXPR, base_ptr, binfo, /*nonnull=*/1,
+ tf_warning_or_error);
+
+ expand_virtual_init (binfo, base_ptr);
+ }
+
+ return NULL_TREE;
+}
+
+/* Initialize all the vtable pointers in the object pointed to by
+ ADDR. */
+
+void
+initialize_vtbl_ptrs (tree addr)
+{
+ tree list;
+ tree type;
+
+ type = TREE_TYPE (TREE_TYPE (addr));
+ list = build_tree_list (type, addr);
+
+ /* Walk through the hierarchy, initializing the vptr in each base
+ class. We do these in pre-order because we can't find the virtual
+ bases for a class until we've initialized the vtbl for that
+ class. */
+ dfs_walk_once (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs, NULL, list);
+}
+
+/* Return an expression for the zero-initialization of an object with
+ type T. This expression will either be a constant (in the case
+ that T is a scalar), or a CONSTRUCTOR (in the case that T is an
+ aggregate), or NULL (in the case that T does not require
+ initialization). In either case, the value can be used as
+ DECL_INITIAL for a decl of the indicated TYPE; it is a valid static
+ initializer. If NELTS is non-NULL, and TYPE is an ARRAY_TYPE, NELTS
+ is the number of elements in the array. If STATIC_STORAGE_P is
+ TRUE, initializers are only generated for entities for which
+ zero-initialization does not simply mean filling the storage with
+ zero bytes. FIELD_SIZE, if non-NULL, is the bit size of the field,
+ subfields with bit positions at or above that bit size shouldn't
+ be added. Note that this only works when the result is assigned
+ to a base COMPONENT_REF; if we only have a pointer to the base subobject,
+ expand_assignment will end up clearing the full size of TYPE. */
+
+static tree
+build_zero_init_1 (tree type, tree nelts, bool static_storage_p,
+ tree field_size)
+{
+ tree init = NULL_TREE;
+
+ /* [dcl.init]
+
+ To zero-initialize an object of type T means:
+
+ -- if T is a scalar type, the storage is set to the value of zero
+ converted to T.
+
+ -- if T is a non-union class type, the storage for each nonstatic
+ data member and each base-class subobject is zero-initialized.
+
+ -- if T is a union type, the storage for its first data member is
+ zero-initialized.
+
+ -- if T is an array type, the storage for each element is
+ zero-initialized.
+
+ -- if T is a reference type, no initialization is performed. */
+
+ gcc_assert (nelts == NULL_TREE || TREE_CODE (nelts) == INTEGER_CST);
+
+ if (type == error_mark_node)
+ ;
+ else if (static_storage_p && zero_init_p (type))
+ /* In order to save space, we do not explicitly build initializers
+ for items that do not need them. GCC's semantics are that
+ items with static storage duration that are not otherwise
+ initialized are initialized to zero. */
+ ;
+ else if (TYPE_PTR_OR_PTRMEM_P (type))
+ init = convert (type, nullptr_node);
+ else if (SCALAR_TYPE_P (type))
+ init = convert (type, integer_zero_node);
+ else if (RECORD_OR_UNION_CODE_P (TREE_CODE (type)))
+ {
+ tree field;
+ vec<constructor_elt, va_gc> *v = NULL;
+
+ /* Iterate over the fields, building initializations. */
+ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ if (TREE_TYPE (field) == error_mark_node)
+ continue;
+
+ /* Don't add virtual bases for base classes if they are beyond
+ the size of the current field, that means it is present
+ somewhere else in the object. */
+ if (field_size)
+ {
+ tree bitpos = bit_position (field);
+ if (TREE_CODE (bitpos) == INTEGER_CST
+ && !tree_int_cst_lt (bitpos, field_size))
+ continue;
+ }
+
+ /* Note that for class types there will be FIELD_DECLs
+ corresponding to base classes as well. Thus, iterating
+ over TYPE_FIELDs will result in correct initialization of
+ all of the subobjects. */
+ if (!static_storage_p || !zero_init_p (TREE_TYPE (field)))
+ {
+ tree new_field_size
+ = (DECL_FIELD_IS_BASE (field)
+ && DECL_SIZE (field)
+ && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST)
+ ? DECL_SIZE (field) : NULL_TREE;
+ tree value = build_zero_init_1 (TREE_TYPE (field),
+ /*nelts=*/NULL_TREE,
+ static_storage_p,
+ new_field_size);
+ if (value)
+ CONSTRUCTOR_APPEND_ELT(v, field, value);
+ }
+
+ /* For unions, only the first field is initialized. */
+ if (TREE_CODE (type) == UNION_TYPE)
+ break;
+ }
+
+ /* Build a constructor to contain the initializations. */
+ init = build_constructor (type, v);
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree max_index;
+ vec<constructor_elt, va_gc> *v = NULL;
+
+ /* Iterate over the array elements, building initializations. */
+ if (nelts)
+ max_index = fold_build2_loc (input_location,
+ MINUS_EXPR, TREE_TYPE (nelts),
+ nelts, integer_one_node);
+ else
+ max_index = array_type_nelts (type);
+
+ /* If we have an error_mark here, we should just return error mark
+ as we don't know the size of the array yet. */
+ if (max_index == error_mark_node)
+ return error_mark_node;
+ gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
+
+ /* A zero-sized array, which is accepted as an extension, will
+ have an upper bound of -1. */
+ if (!tree_int_cst_equal (max_index, integer_minus_one_node))
+ {
+ constructor_elt ce;
+
+ /* If this is a one element array, we just use a regular init. */
+ if (tree_int_cst_equal (size_zero_node, max_index))
+ ce.index = size_zero_node;
+ else
+ ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node,
+ max_index);
+
+ ce.value = build_zero_init_1 (TREE_TYPE (type),
+ /*nelts=*/NULL_TREE,
+ static_storage_p, NULL_TREE);
+ if (ce.value)
+ {
+ vec_alloc (v, 1);
+ v->quick_push (ce);
+ }
+ }
+
+ /* Build a constructor to contain the initializations. */
+ init = build_constructor (type, v);
+ }
+ else if (TREE_CODE (type) == VECTOR_TYPE)
+ init = build_zero_cst (type);
+ else
+ gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
+
+ /* In all cases, the initializer is a constant. */
+ if (init)
+ TREE_CONSTANT (init) = 1;
+
+ return init;
+}
+
+/* Return an expression for the zero-initialization of an object with
+ type T. This expression will either be a constant (in the case
+ that T is a scalar), or a CONSTRUCTOR (in the case that T is an
+ aggregate), or NULL (in the case that T does not require
+ initialization). In either case, the value can be used as
+ DECL_INITIAL for a decl of the indicated TYPE; it is a valid static
+ initializer. If NELTS is non-NULL, and TYPE is an ARRAY_TYPE, NELTS
+ is the number of elements in the array. If STATIC_STORAGE_P is
+ TRUE, initializers are only generated for entities for which
+ zero-initialization does not simply mean filling the storage with
+ zero bytes. */
+
+tree
+build_zero_init (tree type, tree nelts, bool static_storage_p)
+{
+ return build_zero_init_1 (type, nelts, static_storage_p, NULL_TREE);
+}
+
+/* Return a suitable initializer for value-initializing an object of type
+ TYPE, as described in [dcl.init]. */
+
+tree
+build_value_init (tree type, tsubst_flags_t complain)
+{
+ /* [dcl.init]
+
+ To value-initialize an object of type T means:
+
+ - if T is a class type (clause 9) with either no default constructor
+ (12.1) or a default constructor that is user-provided or deleted,
+ then then the object is default-initialized;
+
+ - if T is a (possibly cv-qualified) class type without a user-provided
+ or deleted default constructor, then the object is zero-initialized
+ and the semantic constraints for default-initialization are checked,
+ and if T has a non-trivial default constructor, the object is
+ default-initialized;
+
+ - if T is an array type, then each element is value-initialized;
+
+ - otherwise, the object is zero-initialized.
+
+ A program that calls for default-initialization or
+ value-initialization of an entity of reference type is ill-formed. */
+
+ /* The AGGR_INIT_EXPR tweaking below breaks in templates. */
+ gcc_assert (!processing_template_decl
+ || (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE));
+
+ if (type_build_ctor_call (type))
+ {
+ tree ctor = build_aggr_init_expr
+ (type,
+ build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ NULL, type, LOOKUP_NORMAL,
+ complain));
+ if (ctor == error_mark_node
+ || type_has_user_provided_default_constructor (type))
+ return ctor;
+ else if (TYPE_HAS_COMPLEX_DFLT (type))
+ {
+ /* This is a class that needs constructing, but doesn't have
+ a user-provided constructor. So we need to zero-initialize
+ the object and then call the implicitly defined ctor.
+ This will be handled in simplify_aggr_init_expr. */
+ AGGR_INIT_ZERO_FIRST (ctor) = 1;
+ return ctor;
+ }
+ }
+
+ /* Discard any access checking during subobject initialization;
+ the checks are implied by the call to the ctor which we have
+ verified is OK (cpp0x/defaulted46.C). */
+ push_deferring_access_checks (dk_deferred);
+ tree r = build_value_init_noctor (type, complain);
+ pop_deferring_access_checks ();
+ return r;
+}
+
+/* Like build_value_init, but don't call the constructor for TYPE. Used
+ for base initializers. */
+
+tree
+build_value_init_noctor (tree type, tsubst_flags_t complain)
+{
+ if (!COMPLETE_TYPE_P (type))
+ {
+ if (complain & tf_error)
+ error ("value-initialization of incomplete type %qT", type);
+ return error_mark_node;
+ }
+ /* FIXME the class and array cases should just use digest_init once it is
+ SFINAE-enabled. */
+ if (CLASS_TYPE_P (type))
+ {
+ gcc_assert (!TYPE_HAS_COMPLEX_DFLT (type)
+ || errorcount != 0);
+
+ if (TREE_CODE (type) != UNION_TYPE)
+ {
+ tree field;
+ vec<constructor_elt, va_gc> *v = NULL;
+
+ /* Iterate over the fields, building initializations. */
+ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ {
+ tree ftype, value;
+
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ ftype = TREE_TYPE (field);
+
+ if (ftype == error_mark_node)
+ continue;
+
+ /* We could skip vfields and fields of types with
+ user-defined constructors, but I think that won't improve
+ performance at all; it should be simpler in general just
+ to zero out the entire object than try to only zero the
+ bits that actually need it. */
+
+ /* Note that for class types there will be FIELD_DECLs
+ corresponding to base classes as well. Thus, iterating
+ over TYPE_FIELDs will result in correct initialization of
+ all of the subobjects. */
+ value = build_value_init (ftype, complain);
+
+ if (value == error_mark_node)
+ return error_mark_node;
+
+ if (value)
+ CONSTRUCTOR_APPEND_ELT(v, field, value);
+ }
+
+ /* Build a constructor to contain the zero- initializations. */
+ return build_constructor (type, v);
+ }
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ vec<constructor_elt, va_gc> *v = NULL;
+
+ /* Iterate over the array elements, building initializations. */
+ tree max_index = array_type_nelts (type);
+
+ /* If we have an error_mark here, we should just return error mark
+ as we don't know the size of the array yet. */
+ if (max_index == error_mark_node)
+ {
+ if (complain & tf_error)
+ error ("cannot value-initialize array of unknown bound %qT",
+ type);
+ return error_mark_node;
+ }
+ gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
+
+ /* A zero-sized array, which is accepted as an extension, will
+ have an upper bound of -1. */
+ if (!tree_int_cst_equal (max_index, integer_minus_one_node))
+ {
+ constructor_elt ce;
+
+ /* If this is a one element array, we just use a regular init. */
+ if (tree_int_cst_equal (size_zero_node, max_index))
+ ce.index = size_zero_node;
+ else
+ ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node, max_index);
+
+ ce.value = build_value_init (TREE_TYPE (type), complain);
+ if (ce.value)
+ {
+ if (ce.value == error_mark_node)
+ return error_mark_node;
+
+ vec_alloc (v, 1);
+ v->quick_push (ce);
+
+ /* We shouldn't have gotten here for anything that would need
+ non-trivial initialization, and gimplify_init_ctor_preeval
+ would need to be fixed to allow it. */
+ gcc_assert (TREE_CODE (ce.value) != TARGET_EXPR
+ && TREE_CODE (ce.value) != AGGR_INIT_EXPR);
+ }
+ }
+
+ /* Build a constructor to contain the initializations. */
+ return build_constructor (type, v);
+ }
+ else if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ if (complain & tf_error)
+ error ("value-initialization of function type %qT", type);
+ return error_mark_node;
+ }
+ else if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (complain & tf_error)
+ error ("value-initialization of reference type %qT", type);
+ return error_mark_node;
+ }
+
+ return build_zero_init (type, NULL_TREE, /*static_storage_p=*/false);
+}
+
+/* Initialize current class with INIT, a TREE_LIST of
+ arguments for a target constructor. If TREE_LIST is void_type_node,
+ an empty initializer list was given. */
+
+static void
+perform_target_ctor (tree init)
+{
+ tree decl = current_class_ref;
+ tree type = current_class_type;
+
+ finish_expr_stmt (build_aggr_init (decl, init,
+ LOOKUP_NORMAL|LOOKUP_DELEGATING_CONS,
+ tf_warning_or_error));
+ if (type_build_dtor_call (type))
+ {
+ tree expr = build_delete (type, decl, sfk_complete_destructor,
+ LOOKUP_NORMAL
+ |LOOKUP_NONVIRTUAL
+ |LOOKUP_DESTRUCTOR,
+ 0, tf_warning_or_error);
+ if (expr != error_mark_node
+ && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ finish_eh_cleanup (expr);
+ }
+}
+
+/* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
+ arguments. If TREE_LIST is void_type_node, an empty initializer
+ list was given; if NULL_TREE no initializer was given. */
+
+static void
+perform_member_init (tree member, tree init)
+{
+ tree decl;
+ tree type = TREE_TYPE (member);
+
+ /* Use the non-static data member initializer if there was no
+ mem-initializer for this field. */
+ if (init == NULL_TREE)
+ {
+ if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member))
+ /* Do deferred instantiation of the NSDMI. */
+ init = (tsubst_copy_and_build
+ (DECL_INITIAL (DECL_TI_TEMPLATE (member)),
+ DECL_TI_ARGS (member),
+ tf_warning_or_error, member, /*function_p=*/false,
+ /*integral_constant_expression_p=*/false));
+ else
+ {
+ init = DECL_INITIAL (member);
+ if (init && TREE_CODE (init) == DEFAULT_ARG)
+ {
+ error ("constructor required before non-static data member "
+ "for %qD has been parsed", member);
+ init = NULL_TREE;
+ }
+ /* Strip redundant TARGET_EXPR so we don't need to remap it, and
+ so the aggregate init code below will see a CONSTRUCTOR. */
+ if (init && TREE_CODE (init) == TARGET_EXPR
+ && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (init))))
+ init = TARGET_EXPR_INITIAL (init);
+ init = break_out_target_exprs (init);
+ }
+ }
+
+ if (init == error_mark_node)
+ return;
+
+ /* Effective C++ rule 12 requires that all data members be
+ initialized. */
+ if (warn_ecpp && init == NULL_TREE && TREE_CODE (type) != ARRAY_TYPE)
+ warning_at (DECL_SOURCE_LOCATION (current_function_decl), OPT_Weffc__,
+ "%qD should be initialized in the member initialization list",
+ member);
+
+ /* Get an lvalue for the data member. */
+ decl = build_class_member_access_expr (current_class_ref, member,
+ /*access_path=*/NULL_TREE,
+ /*preserve_reference=*/true,
+ tf_warning_or_error);
+ if (decl == error_mark_node)
+ return;
+
+ if (warn_init_self && init && TREE_CODE (init) == TREE_LIST
+ && TREE_CHAIN (init) == NULL_TREE)
+ {
+ tree val = TREE_VALUE (init);
+ if (TREE_CODE (val) == COMPONENT_REF && TREE_OPERAND (val, 1) == member
+ && TREE_OPERAND (val, 0) == current_class_ref)
+ warning_at (DECL_SOURCE_LOCATION (current_function_decl),
+ OPT_Winit_self, "%qD is initialized with itself",
+ member);
+ }
+
+ if (init == void_type_node)
+ {
+ /* mem() means value-initialization. */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ init = build_vec_init_expr (type, init, tf_warning_or_error);
+ init = build2 (INIT_EXPR, type, decl, init);
+ finish_expr_stmt (init);
+ }
+ else
+ {
+ tree value = build_value_init (type, tf_warning_or_error);
+ if (value == error_mark_node)
+ return;
+ init = build2 (INIT_EXPR, type, decl, value);
+ finish_expr_stmt (init);
+ }
+ }
+ /* Deal with this here, as we will get confused if we try to call the
+ assignment op for an anonymous union. This can happen in a
+ synthesized copy constructor. */
+ else if (ANON_AGGR_TYPE_P (type))
+ {
+ if (init)
+ {
+ init = build2 (INIT_EXPR, type, decl, TREE_VALUE (init));
+ finish_expr_stmt (init);
+ }
+ }
+ else if (init
+ && (TREE_CODE (type) == REFERENCE_TYPE
+ /* Pre-digested NSDMI. */
+ || (((TREE_CODE (init) == CONSTRUCTOR
+ && TREE_TYPE (init) == type)
+ /* { } mem-initializer. */
+ || (TREE_CODE (init) == TREE_LIST
+ && TREE_CODE (TREE_VALUE (init)) == CONSTRUCTOR
+ && CONSTRUCTOR_IS_DIRECT_INIT (TREE_VALUE (init))))
+ && (CP_AGGREGATE_TYPE_P (type)
+ || is_std_init_list (type)))))
+ {
+ /* With references and list-initialization, we need to deal with
+ extending temporary lifetimes. 12.2p5: "A temporary bound to a
+ reference member in a constructor’s ctor-initializer (12.6.2)
+ persists until the constructor exits." */
+ unsigned i; tree t;
+ vec<tree, va_gc> *cleanups = make_tree_vector ();
+ if (TREE_CODE (init) == TREE_LIST)
+ init = build_x_compound_expr_from_list (init, ELK_MEM_INIT,
+ tf_warning_or_error);
+ if (TREE_TYPE (init) != type)
+ {
+ if (BRACE_ENCLOSED_INITIALIZER_P (init)
+ && CP_AGGREGATE_TYPE_P (type))
+ init = reshape_init (type, init, tf_warning_or_error);
+ init = digest_init (type, init, tf_warning_or_error);
+ }
+ if (init == error_mark_node)
+ return;
+ /* A FIELD_DECL doesn't really have a suitable lifetime, but
+ make_temporary_var_for_ref_to_temp will treat it as automatic and
+ set_up_extended_ref_temp wants to use the decl in a warning. */
+ init = extend_ref_init_temps (member, init, &cleanups);
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (type)))
+ init = build_vec_init_expr (type, init, tf_warning_or_error);
+ init = build2 (INIT_EXPR, type, decl, init);
+ finish_expr_stmt (init);
+ FOR_EACH_VEC_ELT (*cleanups, i, t)
+ push_cleanup (decl, t, false);
+ release_tree_vector (cleanups);
+ }
+ else if (type_build_ctor_call (type)
+ || (init && CLASS_TYPE_P (strip_array_types (type))))
+ {
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (init)
+ {
+ if (TREE_CHAIN (init))
+ init = error_mark_node;
+ else
+ init = TREE_VALUE (init);
+ if (BRACE_ENCLOSED_INITIALIZER_P (init))
+ init = digest_init (type, init, tf_warning_or_error);
+ }
+ if (init == NULL_TREE
+ || same_type_ignoring_top_level_qualifiers_p (type,
+ TREE_TYPE (init)))
+ {
+ init = build_vec_init_expr (type, init, tf_warning_or_error);
+ init = build2 (INIT_EXPR, type, decl, init);
+ finish_expr_stmt (init);
+ }
+ else
+ error ("invalid initializer for array member %q#D", member);
+ }
+ else
+ {
+ int flags = LOOKUP_NORMAL;
+ if (DECL_DEFAULTED_FN (current_function_decl))
+ flags |= LOOKUP_DEFAULTED;
+ if (CP_TYPE_CONST_P (type)
+ && init == NULL_TREE
+ && default_init_uninitialized_part (type))
+ /* TYPE_NEEDS_CONSTRUCTING can be set just because we have a
+ vtable; still give this diagnostic. */
+ permerror (DECL_SOURCE_LOCATION (current_function_decl),
+ "uninitialized member %qD with %<const%> type %qT",
+ member, type);
+ finish_expr_stmt (build_aggr_init (decl, init, flags,
+ tf_warning_or_error));
+ }
+ }
+ else
+ {
+ if (init == NULL_TREE)
+ {
+ tree core_type;
+ /* member traversal: note it leaves init NULL */
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ permerror (DECL_SOURCE_LOCATION (current_function_decl),
+ "uninitialized reference member %qD",
+ member);
+ else if (CP_TYPE_CONST_P (type))
+ permerror (DECL_SOURCE_LOCATION (current_function_decl),
+ "uninitialized member %qD with %<const%> type %qT",
+ member, type);
+
+ core_type = strip_array_types (type);
+
+ if (CLASS_TYPE_P (core_type)
+ && (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)
+ || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)))
+ diagnose_uninitialized_cst_or_ref_member (core_type,
+ /*using_new=*/false,
+ /*complain=*/true);
+ }
+ else if (TREE_CODE (init) == TREE_LIST)
+ /* There was an explicit member initialization. Do some work
+ in that case. */
+ init = build_x_compound_expr_from_list (init, ELK_MEM_INIT,
+ tf_warning_or_error);
+
+ if (init)
+ finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
+ tf_warning_or_error));
+ }
+
+ if (type_build_dtor_call (type))
+ {
+ tree expr;
+
+ expr = build_class_member_access_expr (current_class_ref, member,
+ /*access_path=*/NULL_TREE,
+ /*preserve_reference=*/false,
+ tf_warning_or_error);
+ expr = build_delete (type, expr, sfk_complete_destructor,
+ LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0,
+ tf_warning_or_error);
+
+ if (expr != error_mark_node
+ && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ finish_eh_cleanup (expr);
+ }
+}
+
+/* Returns a TREE_LIST containing (as the TREE_PURPOSE of each node) all
+ the FIELD_DECLs on the TYPE_FIELDS list for T, in reverse order. */
+
+static tree
+build_field_list (tree t, tree list, int *uses_unions_p)
+{
+ tree fields;
+
+ /* Note whether or not T is a union. */
+ if (TREE_CODE (t) == UNION_TYPE)
+ *uses_unions_p = 1;
+
+ for (fields = TYPE_FIELDS (t); fields; fields = DECL_CHAIN (fields))
+ {
+ tree fieldtype;
+
+ /* Skip CONST_DECLs for enumeration constants and so forth. */
+ if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
+ continue;
+
+ fieldtype = TREE_TYPE (fields);
+ /* Keep track of whether or not any fields are unions. */
+ if (TREE_CODE (fieldtype) == UNION_TYPE)
+ *uses_unions_p = 1;
+
+ /* For an anonymous struct or union, we must recursively
+ consider the fields of the anonymous type. They can be
+ directly initialized from the constructor. */
+ if (ANON_AGGR_TYPE_P (fieldtype))
+ {
+ /* Add this field itself. Synthesized copy constructors
+ initialize the entire aggregate. */
+ list = tree_cons (fields, NULL_TREE, list);
+ /* And now add the fields in the anonymous aggregate. */
+ list = build_field_list (fieldtype, list, uses_unions_p);
+ }
+ /* Add this field. */
+ else if (DECL_NAME (fields))
+ list = tree_cons (fields, NULL_TREE, list);
+ }
+
+ return list;
+}
+
+/* The MEM_INITS are a TREE_LIST. The TREE_PURPOSE of each list gives
+ a FIELD_DECL or BINFO in T that needs initialization. The
+ TREE_VALUE gives the initializer, or list of initializer arguments.
+
+ Return a TREE_LIST containing all of the initializations required
+ for T, in the order in which they should be performed. The output
+ list has the same format as the input. */
+
+static tree
+sort_mem_initializers (tree t, tree mem_inits)
+{
+ tree init;
+ tree base, binfo, base_binfo;
+ tree sorted_inits;
+ tree next_subobject;
+ vec<tree, va_gc> *vbases;
+ int i;
+ int uses_unions_p = 0;
+
+ /* Build up a list of initializations. The TREE_PURPOSE of entry
+ will be the subobject (a FIELD_DECL or BINFO) to initialize. The
+ TREE_VALUE will be the constructor arguments, or NULL if no
+ explicit initialization was provided. */
+ sorted_inits = NULL_TREE;
+
+ /* Process the virtual bases. */
+ for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
+ vec_safe_iterate (vbases, i, &base); i++)
+ sorted_inits = tree_cons (base, NULL_TREE, sorted_inits);
+
+ /* Process the direct bases. */
+ for (binfo = TYPE_BINFO (t), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ if (!BINFO_VIRTUAL_P (base_binfo))
+ sorted_inits = tree_cons (base_binfo, NULL_TREE, sorted_inits);
+
+ /* Process the non-static data members. */
+ sorted_inits = build_field_list (t, sorted_inits, &uses_unions_p);
+ /* Reverse the entire list of initializations, so that they are in
+ the order that they will actually be performed. */
+ sorted_inits = nreverse (sorted_inits);
+
+ /* If the user presented the initializers in an order different from
+ that in which they will actually occur, we issue a warning. Keep
+ track of the next subobject which can be explicitly initialized
+ without issuing a warning. */
+ next_subobject = sorted_inits;
+
+ /* Go through the explicit initializers, filling in TREE_PURPOSE in
+ the SORTED_INITS. */
+ for (init = mem_inits; init; init = TREE_CHAIN (init))
+ {
+ tree subobject;
+ tree subobject_init;
+
+ subobject = TREE_PURPOSE (init);
+
+ /* If the explicit initializers are in sorted order, then
+ SUBOBJECT will be NEXT_SUBOBJECT, or something following
+ it. */
+ for (subobject_init = next_subobject;
+ subobject_init;
+ subobject_init = TREE_CHAIN (subobject_init))
+ if (TREE_PURPOSE (subobject_init) == subobject)
+ break;
+
+ /* Issue a warning if the explicit initializer order does not
+ match that which will actually occur.
+ ??? Are all these on the correct lines? */
+ if (warn_reorder && !subobject_init)
+ {
+ if (TREE_CODE (TREE_PURPOSE (next_subobject)) == FIELD_DECL)
+ warning (OPT_Wreorder, "%q+D will be initialized after",
+ TREE_PURPOSE (next_subobject));
+ else
+ warning (OPT_Wreorder, "base %qT will be initialized after",
+ TREE_PURPOSE (next_subobject));
+ if (TREE_CODE (subobject) == FIELD_DECL)
+ warning (OPT_Wreorder, " %q+#D", subobject);
+ else
+ warning (OPT_Wreorder, " base %qT", subobject);
+ warning_at (DECL_SOURCE_LOCATION (current_function_decl),
+ OPT_Wreorder, " when initialized here");
+ }
+
+ /* Look again, from the beginning of the list. */
+ if (!subobject_init)
+ {
+ subobject_init = sorted_inits;
+ while (TREE_PURPOSE (subobject_init) != subobject)
+ subobject_init = TREE_CHAIN (subobject_init);
+ }
+
+ /* It is invalid to initialize the same subobject more than
+ once. */
+ if (TREE_VALUE (subobject_init))
+ {
+ if (TREE_CODE (subobject) == FIELD_DECL)
+ error_at (DECL_SOURCE_LOCATION (current_function_decl),
+ "multiple initializations given for %qD",
+ subobject);
+ else
+ error_at (DECL_SOURCE_LOCATION (current_function_decl),
+ "multiple initializations given for base %qT",
+ subobject);
+ }
+
+ /* Record the initialization. */
+ TREE_VALUE (subobject_init) = TREE_VALUE (init);
+ next_subobject = subobject_init;
+ }
+
+ /* [class.base.init]
+
+ If a ctor-initializer specifies more than one mem-initializer for
+ multiple members of the same union (including members of
+ anonymous unions), the ctor-initializer is ill-formed.
+
+ Here we also splice out uninitialized union members. */
+ if (uses_unions_p)
+ {
+ tree *last_p = NULL;
+ tree *p;
+ for (p = &sorted_inits; *p; )
+ {
+ tree field;
+ tree ctx;
+
+ init = *p;
+
+ field = TREE_PURPOSE (init);
+
+ /* Skip base classes. */
+ if (TREE_CODE (field) != FIELD_DECL)
+ goto next;
+
+ /* If this is an anonymous union with no explicit initializer,
+ splice it out. */
+ if (!TREE_VALUE (init) && ANON_UNION_TYPE_P (TREE_TYPE (field)))
+ goto splice;
+
+ /* See if this field is a member of a union, or a member of a
+ structure contained in a union, etc. */
+ for (ctx = DECL_CONTEXT (field);
+ !same_type_p (ctx, t);
+ ctx = TYPE_CONTEXT (ctx))
+ if (TREE_CODE (ctx) == UNION_TYPE
+ || !ANON_AGGR_TYPE_P (ctx))
+ break;
+ /* If this field is not a member of a union, skip it. */
+ if (TREE_CODE (ctx) != UNION_TYPE)
+ goto next;
+
+ /* If this union member has no explicit initializer and no NSDMI,
+ splice it out. */
+ if (TREE_VALUE (init) || DECL_INITIAL (field))
+ /* OK. */;
+ else
+ goto splice;
+
+ /* It's only an error if we have two initializers for the same
+ union type. */
+ if (!last_p)
+ {
+ last_p = p;
+ goto next;
+ }
+
+ /* See if LAST_FIELD and the field initialized by INIT are
+ members of the same union. If so, there's a problem,
+ unless they're actually members of the same structure
+ which is itself a member of a union. For example, given:
+
+ union { struct { int i; int j; }; };
+
+ initializing both `i' and `j' makes sense. */
+ ctx = common_enclosing_class (DECL_CONTEXT (field),
+ DECL_CONTEXT (TREE_PURPOSE (*last_p)));
+
+ if (ctx && TREE_CODE (ctx) == UNION_TYPE)
+ {
+ /* A mem-initializer hides an NSDMI. */
+ if (TREE_VALUE (init) && !TREE_VALUE (*last_p))
+ *last_p = TREE_CHAIN (*last_p);
+ else if (TREE_VALUE (*last_p) && !TREE_VALUE (init))
+ goto splice;
+ else
+ {
+ error_at (DECL_SOURCE_LOCATION (current_function_decl),
+ "initializations for multiple members of %qT",
+ ctx);
+ goto splice;
+ }
+ }
+
+ last_p = p;
+
+ next:
+ p = &TREE_CHAIN (*p);
+ continue;
+ splice:
+ *p = TREE_CHAIN (*p);
+ continue;
+ }
+ }
+
+ return sorted_inits;
+}
+
+/* Initialize all bases and members of CURRENT_CLASS_TYPE. MEM_INITS
+ is a TREE_LIST giving the explicit mem-initializer-list for the
+ constructor. The TREE_PURPOSE of each entry is a subobject (a
+ FIELD_DECL or a BINFO) of the CURRENT_CLASS_TYPE. The TREE_VALUE
+ is a TREE_LIST giving the arguments to the constructor or
+ void_type_node for an empty list of arguments. */
+
+void
+emit_mem_initializers (tree mem_inits)
+{
+ int flags = LOOKUP_NORMAL;
+
+ /* We will already have issued an error message about the fact that
+ the type is incomplete. */
+ if (!COMPLETE_TYPE_P (current_class_type))
+ return;
+
+ if (mem_inits
+ && TYPE_P (TREE_PURPOSE (mem_inits))
+ && same_type_p (TREE_PURPOSE (mem_inits), current_class_type))
+ {
+ /* Delegating constructor. */
+ gcc_assert (TREE_CHAIN (mem_inits) == NULL_TREE);
+ perform_target_ctor (TREE_VALUE (mem_inits));
+ return;
+ }
+
+ if (DECL_DEFAULTED_FN (current_function_decl)
+ && ! DECL_INHERITED_CTOR_BASE (current_function_decl))
+ flags |= LOOKUP_DEFAULTED;
+
+ /* Sort the mem-initializers into the order in which the
+ initializations should be performed. */
+ mem_inits = sort_mem_initializers (current_class_type, mem_inits);
+
+ in_base_initializer = 1;
+
+ /* Initialize base classes. */
+ for (; (mem_inits
+ && TREE_CODE (TREE_PURPOSE (mem_inits)) != FIELD_DECL);
+ mem_inits = TREE_CHAIN (mem_inits))
+ {
+ tree subobject = TREE_PURPOSE (mem_inits);
+ tree arguments = TREE_VALUE (mem_inits);
+
+ /* We already have issued an error message. */
+ if (arguments == error_mark_node)
+ continue;
+
+ if (arguments == NULL_TREE)
+ {
+ /* If these initializations are taking place in a copy constructor,
+ the base class should probably be explicitly initialized if there
+ is a user-defined constructor in the base class (other than the
+ default constructor, which will be called anyway). */
+ if (extra_warnings
+ && DECL_COPY_CONSTRUCTOR_P (current_function_decl)
+ && type_has_user_nondefault_constructor (BINFO_TYPE (subobject)))
+ warning_at (DECL_SOURCE_LOCATION (current_function_decl),
+ OPT_Wextra, "base class %q#T should be explicitly "
+ "initialized in the copy constructor",
+ BINFO_TYPE (subobject));
+ }
+
+ /* Initialize the base. */
+ if (BINFO_VIRTUAL_P (subobject))
+ construct_virtual_base (subobject, arguments);
+ else
+ {
+ tree base_addr;
+
+ base_addr = build_base_path (PLUS_EXPR, current_class_ptr,
+ subobject, 1, tf_warning_or_error);
+ expand_aggr_init_1 (subobject, NULL_TREE,
+ cp_build_indirect_ref (base_addr, RO_NULL,
+ tf_warning_or_error),
+ arguments,
+ flags,
+ tf_warning_or_error);
+ expand_cleanup_for_base (subobject, NULL_TREE);
+ }
+ }
+ in_base_initializer = 0;
+
+ /* Initialize the vptrs. */
+ initialize_vtbl_ptrs (current_class_ptr);
+
+ /* Initialize the data members. */
+ while (mem_inits)
+ {
+ perform_member_init (TREE_PURPOSE (mem_inits),
+ TREE_VALUE (mem_inits));
+ mem_inits = TREE_CHAIN (mem_inits);
+ }
+}
+
+/* Returns the address of the vtable (i.e., the value that should be
+ assigned to the vptr) for BINFO. */
+
+tree
+build_vtbl_address (tree binfo)
+{
+ tree binfo_for = binfo;
+ tree vtbl;
+
+ if (BINFO_VPTR_INDEX (binfo) && BINFO_VIRTUAL_P (binfo))
+ /* If this is a virtual primary base, then the vtable we want to store
+ is that for the base this is being used as the primary base of. We
+ can't simply skip the initialization, because we may be expanding the
+ inits of a subobject constructor where the virtual base layout
+ can be different. */
+ while (BINFO_PRIMARY_P (binfo_for))
+ binfo_for = BINFO_INHERITANCE_CHAIN (binfo_for);
+
+ /* Figure out what vtable BINFO's vtable is based on, and mark it as
+ used. */
+ vtbl = get_vtbl_decl_for_binfo (binfo_for);
+ if (tree dtor = CLASSTYPE_DESTRUCTORS (DECL_CONTEXT (vtbl)))
+ if (!TREE_USED (vtbl) && DECL_VIRTUAL_P (dtor) && DECL_DEFAULTED_FN (dtor))
+ /* Make sure the destructor gets synthesized so that it can be
+ inlined after devirtualization even if the vtable is never
+ emitted. */
+ note_vague_linkage_fn (dtor);
+ TREE_USED (vtbl) = true;
+
+ /* Now compute the address to use when initializing the vptr. */
+ vtbl = unshare_expr (BINFO_VTABLE (binfo_for));
+ if (VAR_P (vtbl))
+ vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
+
+ return vtbl;
+}
+
+/* This code sets up the virtual function tables appropriate for
+ the pointer DECL. It is a one-ply initialization.
+
+ BINFO is the exact type that DECL is supposed to be. In
+ multiple inheritance, this might mean "C's A" if C : A, B. */
+
+static void
+expand_virtual_init (tree binfo, tree decl)
+{
+ tree vtbl, vtbl_ptr;
+ tree vtt_index;
+
+ /* Compute the initializer for vptr. */
+ vtbl = build_vtbl_address (binfo);
+
+ /* We may get this vptr from a VTT, if this is a subobject
+ constructor or subobject destructor. */
+ vtt_index = BINFO_VPTR_INDEX (binfo);
+ if (vtt_index)
+ {
+ tree vtbl2;
+ tree vtt_parm;
+
+ /* Compute the value to use, when there's a VTT. */
+ vtt_parm = current_vtt_parm;
+ vtbl2 = fold_build_pointer_plus (vtt_parm, vtt_index);
+ vtbl2 = cp_build_indirect_ref (vtbl2, RO_NULL, tf_warning_or_error);
+ vtbl2 = convert (TREE_TYPE (vtbl), vtbl2);
+
+ /* The actual initializer is the VTT value only in the subobject
+ constructor. In maybe_clone_body we'll substitute NULL for
+ the vtt_parm in the case of the non-subobject constructor. */
+ vtbl = build3 (COND_EXPR,
+ TREE_TYPE (vtbl),
+ build2 (EQ_EXPR, boolean_type_node,
+ current_in_charge_parm, integer_zero_node),
+ vtbl2,
+ vtbl);
+ }
+
+ /* Compute the location of the vtpr. */
+ vtbl_ptr = build_vfield_ref (cp_build_indirect_ref (decl, RO_NULL,
+ tf_warning_or_error),
+ TREE_TYPE (binfo));
+ gcc_assert (vtbl_ptr != error_mark_node);
+
+ /* Assign the vtable to the vptr. */
+ vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0, tf_warning_or_error);
+ finish_expr_stmt (cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl,
+ tf_warning_or_error));
+}
+
+/* If an exception is thrown in a constructor, those base classes already
+ constructed must be destroyed. This function creates the cleanup
+ for BINFO, which has just been constructed. If FLAG is non-NULL,
+ it is a DECL which is nonzero when this base needs to be
+ destroyed. */
+
+static void
+expand_cleanup_for_base (tree binfo, tree flag)
+{
+ tree expr;
+
+ if (!type_build_dtor_call (BINFO_TYPE (binfo)))
+ return;
+
+ /* Call the destructor. */
+ expr = build_special_member_call (current_class_ref,
+ base_dtor_identifier,
+ NULL,
+ binfo,
+ LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
+ tf_warning_or_error);
+
+ if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (binfo)))
+ return;
+
+ if (flag)
+ expr = fold_build3_loc (input_location,
+ COND_EXPR, void_type_node,
+ c_common_truthvalue_conversion (input_location, flag),
+ expr, integer_zero_node);
+
+ finish_eh_cleanup (expr);
+}
+
+/* Construct the virtual base-class VBASE passing the ARGUMENTS to its
+ constructor. */
+
+static void
+construct_virtual_base (tree vbase, tree arguments)
+{
+ tree inner_if_stmt;
+ tree exp;
+ tree flag;
+
+ /* If there are virtual base classes with destructors, we need to
+ emit cleanups to destroy them if an exception is thrown during
+ the construction process. These exception regions (i.e., the
+ period during which the cleanups must occur) begin from the time
+ the construction is complete to the end of the function. If we
+ create a conditional block in which to initialize the
+ base-classes, then the cleanup region for the virtual base begins
+ inside a block, and ends outside of that block. This situation
+ confuses the sjlj exception-handling code. Therefore, we do not
+ create a single conditional block, but one for each
+ initialization. (That way the cleanup regions always begin
+ in the outer block.) We trust the back end to figure out
+ that the FLAG will not change across initializations, and
+ avoid doing multiple tests. */
+ flag = DECL_CHAIN (DECL_ARGUMENTS (current_function_decl));
+ inner_if_stmt = begin_if_stmt ();
+ finish_if_stmt_cond (flag, inner_if_stmt);
+
+ /* Compute the location of the virtual base. If we're
+ constructing virtual bases, then we must be the most derived
+ class. Therefore, we don't have to look up the virtual base;
+ we already know where it is. */
+ exp = convert_to_base_statically (current_class_ref, vbase);
+
+ expand_aggr_init_1 (vbase, current_class_ref, exp, arguments,
+ 0, tf_warning_or_error);
+ finish_then_clause (inner_if_stmt);
+ finish_if_stmt (inner_if_stmt);
+
+ expand_cleanup_for_base (vbase, flag);
+}
+
+/* Find the context in which this FIELD can be initialized. */
+
+static tree
+initializing_context (tree field)
+{
+ tree t = DECL_CONTEXT (field);
+
+ /* Anonymous union members can be initialized in the first enclosing
+ non-anonymous union context. */
+ while (t && ANON_AGGR_TYPE_P (t))
+ t = TYPE_CONTEXT (t);
+ return t;
+}
+
+/* Function to give error message if member initialization specification
+ is erroneous. FIELD is the member we decided to initialize.
+ TYPE is the type for which the initialization is being performed.
+ FIELD must be a member of TYPE.
+
+ MEMBER_NAME is the name of the member. */
+
+static int
+member_init_ok_or_else (tree field, tree type, tree member_name)
+{
+ if (field == error_mark_node)
+ return 0;
+ if (!field)
+ {
+ error ("class %qT does not have any field named %qD", type,
+ member_name);
+ return 0;
+ }
+ if (VAR_P (field))
+ {
+ error ("%q#D is a static data member; it can only be "
+ "initialized at its definition",
+ field);
+ return 0;
+ }
+ if (TREE_CODE (field) != FIELD_DECL)
+ {
+ error ("%q#D is not a non-static data member of %qT",
+ field, type);
+ return 0;
+ }
+ if (initializing_context (field) != type)
+ {
+ error ("class %qT does not have any field named %qD", type,
+ member_name);
+ return 0;
+ }
+
+ return 1;
+}
+
+/* NAME is a FIELD_DECL, an IDENTIFIER_NODE which names a field, or it
+ is a _TYPE node or TYPE_DECL which names a base for that type.
+ Check the validity of NAME, and return either the base _TYPE, base
+ binfo, or the FIELD_DECL of the member. If NAME is invalid, return
+ NULL_TREE and issue a diagnostic.
+
+ An old style unnamed direct single base construction is permitted,
+ where NAME is NULL. */
+
+tree
+expand_member_init (tree name)
+{
+ tree basetype;
+ tree field;
+
+ if (!current_class_ref)
+ return NULL_TREE;
+
+ if (!name)
+ {
+ /* This is an obsolete unnamed base class initializer. The
+ parser will already have warned about its use. */
+ switch (BINFO_N_BASE_BINFOS (TYPE_BINFO (current_class_type)))
+ {
+ case 0:
+ error ("unnamed initializer for %qT, which has no base classes",
+ current_class_type);
+ return NULL_TREE;
+ case 1:
+ basetype = BINFO_TYPE
+ (BINFO_BASE_BINFO (TYPE_BINFO (current_class_type), 0));
+ break;
+ default:
+ error ("unnamed initializer for %qT, which uses multiple inheritance",
+ current_class_type);
+ return NULL_TREE;
+ }
+ }
+ else if (TYPE_P (name))
+ {
+ basetype = TYPE_MAIN_VARIANT (name);
+ name = TYPE_NAME (name);
+ }
+ else if (TREE_CODE (name) == TYPE_DECL)
+ basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name));
+ else
+ basetype = NULL_TREE;
+
+ if (basetype)
+ {
+ tree class_binfo;
+ tree direct_binfo;
+ tree virtual_binfo;
+ int i;
+
+ if (current_template_parms
+ || same_type_p (basetype, current_class_type))
+ return basetype;
+
+ class_binfo = TYPE_BINFO (current_class_type);
+ direct_binfo = NULL_TREE;
+ virtual_binfo = NULL_TREE;
+
+ /* Look for a direct base. */
+ for (i = 0; BINFO_BASE_ITERATE (class_binfo, i, direct_binfo); ++i)
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (direct_binfo), basetype))
+ break;
+
+ /* Look for a virtual base -- unless the direct base is itself
+ virtual. */
+ if (!direct_binfo || !BINFO_VIRTUAL_P (direct_binfo))
+ virtual_binfo = binfo_for_vbase (basetype, current_class_type);
+
+ /* [class.base.init]
+
+ If a mem-initializer-id is ambiguous because it designates
+ both a direct non-virtual base class and an inherited virtual
+ base class, the mem-initializer is ill-formed. */
+ if (direct_binfo && virtual_binfo)
+ {
+ error ("%qD is both a direct base and an indirect virtual base",
+ basetype);
+ return NULL_TREE;
+ }
+
+ if (!direct_binfo && !virtual_binfo)
+ {
+ if (CLASSTYPE_VBASECLASSES (current_class_type))
+ error ("type %qT is not a direct or virtual base of %qT",
+ basetype, current_class_type);
+ else
+ error ("type %qT is not a direct base of %qT",
+ basetype, current_class_type);
+ return NULL_TREE;
+ }
+
+ return direct_binfo ? direct_binfo : virtual_binfo;
+ }
+ else
+ {
+ if (identifier_p (name))
+ field = lookup_field (current_class_type, name, 1, false);
+ else
+ field = name;
+
+ if (member_init_ok_or_else (field, current_class_type, name))
+ return field;
+ }
+
+ return NULL_TREE;
+}
+
+/* This is like `expand_member_init', only it stores one aggregate
+ value into another.
+
+ INIT comes in two flavors: it is either a value which
+ is to be stored in EXP, or it is a parameter list
+ to go to a constructor, which will operate on EXP.
+ If INIT is not a parameter list for a constructor, then set
+ LOOKUP_ONLYCONVERTING.
+ If FLAGS is LOOKUP_ONLYCONVERTING then it is the = init form of
+ the initializer, if FLAGS is 0, then it is the (init) form.
+ If `init' is a CONSTRUCTOR, then we emit a warning message,
+ explaining that such initializations are invalid.
+
+ If INIT resolves to a CALL_EXPR which happens to return
+ something of the type we are looking for, then we know
+ that we can safely use that call to perform the
+ initialization.
+
+ The virtual function table pointer cannot be set up here, because
+ we do not really know its type.
+
+ This never calls operator=().
+
+ When initializing, nothing is CONST.
+
+ A default copy constructor may have to be used to perform the
+ initialization.
+
+ A constructor or a conversion operator may have to be used to
+ perform the initialization, but not both, as it would be ambiguous. */
+
+tree
+build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
+{
+ tree stmt_expr;
+ tree compound_stmt;
+ int destroy_temps;
+ tree type = TREE_TYPE (exp);
+ int was_const = TREE_READONLY (exp);
+ int was_volatile = TREE_THIS_VOLATILE (exp);
+ int is_global;
+
+ if (init == error_mark_node)
+ return error_mark_node;
+
+ TREE_READONLY (exp) = 0;
+ TREE_THIS_VOLATILE (exp) = 0;
+
+ if (init && init != void_type_node
+ && TREE_CODE (init) != TREE_LIST
+ && !(TREE_CODE (init) == TARGET_EXPR
+ && TARGET_EXPR_DIRECT_INIT_P (init))
+ && !(BRACE_ENCLOSED_INITIALIZER_P (init)
+ && CONSTRUCTOR_IS_DIRECT_INIT (init)))
+ flags |= LOOKUP_ONLYCONVERTING;
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree itype;
+
+ /* An array may not be initialized use the parenthesized
+ initialization form -- unless the initializer is "()". */
+ if (init && TREE_CODE (init) == TREE_LIST)
+ {
+ if (complain & tf_error)
+ error ("bad array initializer");
+ return error_mark_node;
+ }
+ /* Must arrange to initialize each element of EXP
+ from elements of INIT. */
+ itype = init ? TREE_TYPE (init) : NULL_TREE;
+ if (cv_qualified_p (type))
+ TREE_TYPE (exp) = cv_unqualified (type);
+ if (itype && cv_qualified_p (itype))
+ TREE_TYPE (init) = cv_unqualified (itype);
+ stmt_expr = build_vec_init (exp, NULL_TREE, init,
+ /*explicit_value_init_p=*/false,
+ itype && same_type_p (TREE_TYPE (init),
+ TREE_TYPE (exp)),
+ complain);
+ TREE_READONLY (exp) = was_const;
+ TREE_THIS_VOLATILE (exp) = was_volatile;
+ TREE_TYPE (exp) = type;
+ /* Restore the type of init unless it was used directly. */
+ if (init && TREE_CODE (stmt_expr) != INIT_EXPR)
+ TREE_TYPE (init) = itype;
+ return stmt_expr;
+ }
+
+ if ((VAR_P (exp) || TREE_CODE (exp) == PARM_DECL)
+ && !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (type)))
+ /* Just know that we've seen something for this node. */
+ TREE_USED (exp) = 1;
+
+ is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
+ destroy_temps = stmts_are_full_exprs_p ();
+ current_stmt_tree ()->stmts_are_full_exprs_p = 0;
+ expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
+ init, LOOKUP_NORMAL|flags, complain);
+ stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
+ current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
+ TREE_READONLY (exp) = was_const;
+ TREE_THIS_VOLATILE (exp) = was_volatile;
+
+ return stmt_expr;
+}
+
+static void
+expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
+ tsubst_flags_t complain)
+{
+ tree type = TREE_TYPE (exp);
+ tree ctor_name;
+
+ /* It fails because there may not be a constructor which takes
+ its own type as the first (or only parameter), but which does
+ take other types via a conversion. So, if the thing initializing
+ the expression is a unit element of type X, first try X(X&),
+ followed by initialization by X. If neither of these work
+ out, then look hard. */
+ tree rval;
+ vec<tree, va_gc> *parms;
+
+ /* If we have direct-initialization from an initializer list, pull
+ it out of the TREE_LIST so the code below can see it. */
+ if (init && TREE_CODE (init) == TREE_LIST
+ && BRACE_ENCLOSED_INITIALIZER_P (TREE_VALUE (init))
+ && CONSTRUCTOR_IS_DIRECT_INIT (TREE_VALUE (init)))
+ {
+ gcc_checking_assert ((flags & LOOKUP_ONLYCONVERTING) == 0
+ && TREE_CHAIN (init) == NULL_TREE);
+ init = TREE_VALUE (init);
+ }
+
+ if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
+ && CP_AGGREGATE_TYPE_P (type))
+ /* A brace-enclosed initializer for an aggregate. In C++0x this can
+ happen for direct-initialization, too. */
+ init = digest_init (type, init, complain);
+
+ /* A CONSTRUCTOR of the target's type is a previously digested
+ initializer, whether that happened just above or in
+ cp_parser_late_parsing_nsdmi.
+
+ A TARGET_EXPR with TARGET_EXPR_DIRECT_INIT_P or TARGET_EXPR_LIST_INIT_P
+ set represents the whole initialization, so we shouldn't build up
+ another ctor call. */
+ if (init
+ && (TREE_CODE (init) == CONSTRUCTOR
+ || (TREE_CODE (init) == TARGET_EXPR
+ && (TARGET_EXPR_DIRECT_INIT_P (init)
+ || TARGET_EXPR_LIST_INIT_P (init))))
+ && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init), type))
+ {
+ /* Early initialization via a TARGET_EXPR only works for
+ complete objects. */
+ gcc_assert (TREE_CODE (init) == CONSTRUCTOR || true_exp == exp);
+
+ init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
+ TREE_SIDE_EFFECTS (init) = 1;
+ finish_expr_stmt (init);
+ return;
+ }
+
+ if (init && TREE_CODE (init) != TREE_LIST
+ && (flags & LOOKUP_ONLYCONVERTING))
+ {
+ /* Base subobjects should only get direct-initialization. */
+ gcc_assert (true_exp == exp);
+
+ if (flags & DIRECT_BIND)
+ /* Do nothing. We hit this in two cases: Reference initialization,
+ where we aren't initializing a real variable, so we don't want
+ to run a new constructor; and catching an exception, where we
+ have already built up the constructor call so we could wrap it
+ in an exception region. */;
+ else
+ init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP,
+ flags, complain);
+
+ if (TREE_CODE (init) == MUST_NOT_THROW_EXPR)
+ /* We need to protect the initialization of a catch parm with a
+ call to terminate(), which shows up as a MUST_NOT_THROW_EXPR
+ around the TARGET_EXPR for the copy constructor. See
+ initialize_handler_parm. */
+ {
+ TREE_OPERAND (init, 0) = build2 (INIT_EXPR, TREE_TYPE (exp), exp,
+ TREE_OPERAND (init, 0));
+ TREE_TYPE (init) = void_type_node;
+ }
+ else
+ init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
+ TREE_SIDE_EFFECTS (init) = 1;
+ finish_expr_stmt (init);
+ return;
+ }
+
+ if (init == NULL_TREE)
+ parms = NULL;
+ else if (TREE_CODE (init) == TREE_LIST && !TREE_TYPE (init))
+ {
+ parms = make_tree_vector ();
+ for (; init != NULL_TREE; init = TREE_CHAIN (init))
+ vec_safe_push (parms, TREE_VALUE (init));
+ }
+ else
+ parms = make_tree_vector_single (init);
+
+ if (exp == current_class_ref && current_function_decl
+ && DECL_HAS_IN_CHARGE_PARM_P (current_function_decl))
+ {
+ /* Delegating constructor. */
+ tree complete;
+ tree base;
+ tree elt; unsigned i;
+
+ /* Unshare the arguments for the second call. */
+ vec<tree, va_gc> *parms2 = make_tree_vector ();
+ FOR_EACH_VEC_SAFE_ELT (parms, i, elt)
+ {
+ elt = break_out_target_exprs (elt);
+ vec_safe_push (parms2, elt);
+ }
+ complete = build_special_member_call (exp, complete_ctor_identifier,
+ &parms2, binfo, flags,
+ complain);
+ complete = fold_build_cleanup_point_expr (void_type_node, complete);
+ release_tree_vector (parms2);
+
+ base = build_special_member_call (exp, base_ctor_identifier,
+ &parms, binfo, flags,
+ complain);
+ base = fold_build_cleanup_point_expr (void_type_node, base);
+ rval = build3 (COND_EXPR, void_type_node,
+ build2 (EQ_EXPR, boolean_type_node,
+ current_in_charge_parm, integer_zero_node),
+ base,
+ complete);
+ }
+ else
+ {
+ if (true_exp == exp)
+ ctor_name = complete_ctor_identifier;
+ else
+ ctor_name = base_ctor_identifier;
+ rval = build_special_member_call (exp, ctor_name, &parms, binfo, flags,
+ complain);
+ }
+
+ if (parms != NULL)
+ release_tree_vector (parms);
+
+ if (exp == true_exp && TREE_CODE (rval) == CALL_EXPR)
+ {
+ tree fn = get_callee_fndecl (rval);
+ if (fn && DECL_DECLARED_CONSTEXPR_P (fn))
+ {
+ tree e = maybe_constant_init (rval);
+ if (TREE_CONSTANT (e))
+ rval = build2 (INIT_EXPR, type, exp, e);
+ }
+ }
+
+ /* FIXME put back convert_to_void? */
+ if (TREE_SIDE_EFFECTS (rval))
+ finish_expr_stmt (rval);
+}
+
+/* This function is responsible for initializing EXP with INIT
+ (if any).
+
+ BINFO is the binfo of the type for who we are performing the
+ initialization. For example, if W is a virtual base class of A and B,
+ and C : A, B.
+ If we are initializing B, then W must contain B's W vtable, whereas
+ were we initializing C, W must contain C's W vtable.
+
+ TRUE_EXP is nonzero if it is the true expression being initialized.
+ In this case, it may be EXP, or may just contain EXP. The reason we
+ need this is because if EXP is a base element of TRUE_EXP, we
+ don't necessarily know by looking at EXP where its virtual
+ baseclass fields should really be pointing. But we do know
+ from TRUE_EXP. In constructors, we don't know anything about
+ the value being initialized.
+
+ FLAGS is just passed to `build_new_method_call'. See that function
+ for its description. */
+
+static void
+expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
+ tsubst_flags_t complain)
+{
+ tree type = TREE_TYPE (exp);
+
+ gcc_assert (init != error_mark_node && type != error_mark_node);
+ gcc_assert (building_stmt_list_p ());
+
+ /* Use a function returning the desired type to initialize EXP for us.
+ If the function is a constructor, and its first argument is
+ NULL_TREE, know that it was meant for us--just slide exp on
+ in and expand the constructor. Constructors now come
+ as TARGET_EXPRs. */
+
+ if (init && VAR_P (exp)
+ && COMPOUND_LITERAL_P (init))
+ {
+ vec<tree, va_gc> *cleanups = NULL;
+ /* If store_init_value returns NULL_TREE, the INIT has been
+ recorded as the DECL_INITIAL for EXP. That means there's
+ nothing more we have to do. */
+ init = store_init_value (exp, init, &cleanups, flags);
+ if (init)
+ finish_expr_stmt (init);
+ gcc_assert (!cleanups);
+ return;
+ }
+
+ /* If an explicit -- but empty -- initializer list was present,
+ that's value-initialization. */
+ if (init == void_type_node)
+ {
+ /* If the type has data but no user-provided ctor, we need to zero
+ out the object. */
+ if (!type_has_user_provided_constructor (type)
+ && !is_really_empty_class (type))
+ {
+ tree field_size = NULL_TREE;
+ if (exp != true_exp && CLASSTYPE_AS_BASE (type) != type)
+ /* Don't clobber already initialized virtual bases. */
+ field_size = TYPE_SIZE (CLASSTYPE_AS_BASE (type));
+ init = build_zero_init_1 (type, NULL_TREE, /*static_storage_p=*/false,
+ field_size);
+ init = build2 (INIT_EXPR, type, exp, init);
+ finish_expr_stmt (init);
+ }
+
+ /* If we don't need to mess with the constructor at all,
+ then we're done. */
+ if (! type_build_ctor_call (type))
+ return;
+
+ /* Otherwise fall through and call the constructor. */
+ init = NULL_TREE;
+ }
+
+ /* We know that expand_default_init can handle everything we want
+ at this point. */
+ expand_default_init (binfo, true_exp, exp, init, flags, complain);
+}
+
+/* Report an error if TYPE is not a user-defined, class type. If
+ OR_ELSE is nonzero, give an error message. */
+
+int
+is_class_type (tree type, int or_else)
+{
+ if (type == error_mark_node)
+ return 0;
+
+ if (! CLASS_TYPE_P (type))
+ {
+ if (or_else)
+ error ("%qT is not a class type", type);
+ return 0;
+ }
+ return 1;
+}
+
+tree
+get_type_value (tree name)
+{
+ if (name == error_mark_node)
+ return NULL_TREE;
+
+ if (IDENTIFIER_HAS_TYPE_VALUE (name))
+ return IDENTIFIER_TYPE_VALUE (name);
+ else
+ return NULL_TREE;
+}
+
+/* Build a reference to a member of an aggregate. This is not a C++
+ `&', but really something which can have its address taken, and
+ then act as a pointer to member, for example TYPE :: FIELD can have
+ its address taken by saying & TYPE :: FIELD. ADDRESS_P is true if
+ this expression is the operand of "&".
+
+ @@ Prints out lousy diagnostics for operator <typename>
+ @@ fields.
+
+ @@ This function should be rewritten and placed in search.c. */
+
+tree
+build_offset_ref (tree type, tree member, bool address_p,
+ tsubst_flags_t complain)
+{
+ tree decl;
+ tree basebinfo = NULL_TREE;
+
+ /* class templates can come in as TEMPLATE_DECLs here. */
+ if (TREE_CODE (member) == TEMPLATE_DECL)
+ return member;
+
+ if (dependent_scope_p (type) || type_dependent_expression_p (member))
+ return build_qualified_name (NULL_TREE, type, member,
+ /*template_p=*/false);
+
+ gcc_assert (TYPE_P (type));
+ if (! is_class_type (type, 1))
+ return error_mark_node;
+
+ gcc_assert (DECL_P (member) || BASELINK_P (member));
+ /* Callers should call mark_used before this point. */
+ gcc_assert (!DECL_P (member) || TREE_USED (member));
+
+ type = TYPE_MAIN_VARIANT (type);
+ if (!COMPLETE_OR_OPEN_TYPE_P (complete_type (type)))
+ {
+ if (complain & tf_error)
+ error ("incomplete type %qT does not have member %qD", type, member);
+ return error_mark_node;
+ }
+
+ /* Entities other than non-static members need no further
+ processing. */
+ if (TREE_CODE (member) == TYPE_DECL)
+ return member;
+ if (VAR_P (member) || TREE_CODE (member) == CONST_DECL)
+ return convert_from_reference (member);
+
+ if (TREE_CODE (member) == FIELD_DECL && DECL_C_BIT_FIELD (member))
+ {
+ if (complain & tf_error)
+ error ("invalid pointer to bit-field %qD", member);
+ return error_mark_node;
+ }
+
+ /* Set up BASEBINFO for member lookup. */
+ decl = maybe_dummy_object (type, &basebinfo);
+
+ /* A lot of this logic is now handled in lookup_member. */
+ if (BASELINK_P (member))
+ {
+ /* Go from the TREE_BASELINK to the member function info. */
+ tree t = BASELINK_FUNCTIONS (member);
+
+ if (TREE_CODE (t) != TEMPLATE_ID_EXPR && !really_overloaded_fn (t))
+ {
+ /* Get rid of a potential OVERLOAD around it. */
+ t = OVL_CURRENT (t);
+
+ /* Unique functions are handled easily. */
+
+ /* For non-static member of base class, we need a special rule
+ for access checking [class.protected]:
+
+ If the access is to form a pointer to member, the
+ nested-name-specifier shall name the derived class
+ (or any class derived from that class). */
+ if (address_p && DECL_P (t)
+ && DECL_NONSTATIC_MEMBER_P (t))
+ perform_or_defer_access_check (TYPE_BINFO (type), t, t,
+ complain);
+ else
+ perform_or_defer_access_check (basebinfo, t, t,
+ complain);
+
+ if (DECL_STATIC_FUNCTION_P (t))
+ return t;
+ member = t;
+ }
+ else
+ TREE_TYPE (member) = unknown_type_node;
+ }
+ else if (address_p && TREE_CODE (member) == FIELD_DECL)
+ /* We need additional test besides the one in
+ check_accessibility_of_qualified_id in case it is
+ a pointer to non-static member. */
+ perform_or_defer_access_check (TYPE_BINFO (type), member, member,
+ complain);
+
+ if (!address_p)
+ {
+ /* If MEMBER is non-static, then the program has fallen afoul of
+ [expr.prim]:
+
+ An id-expression that denotes a nonstatic data member or
+ nonstatic member function of a class can only be used:
+
+ -- as part of a class member access (_expr.ref_) in which the
+ object-expression refers to the member's class or a class
+ derived from that class, or
+
+ -- to form a pointer to member (_expr.unary.op_), or
+
+ -- in the body of a nonstatic member function of that class or
+ of a class derived from that class (_class.mfct.nonstatic_), or
+
+ -- in a mem-initializer for a constructor for that class or for
+ a class derived from that class (_class.base.init_). */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (member))
+ {
+ /* Build a representation of the qualified name suitable
+ for use as the operand to "&" -- even though the "&" is
+ not actually present. */
+ member = build2 (OFFSET_REF, TREE_TYPE (member), decl, member);
+ /* In Microsoft mode, treat a non-static member function as if
+ it were a pointer-to-member. */
+ if (flag_ms_extensions)
+ {
+ PTRMEM_OK_P (member) = 1;
+ return cp_build_addr_expr (member, complain);
+ }
+ if (complain & tf_error)
+ error ("invalid use of non-static member function %qD",
+ TREE_OPERAND (member, 1));
+ return error_mark_node;
+ }
+ else if (TREE_CODE (member) == FIELD_DECL)
+ {
+ if (complain & tf_error)
+ error ("invalid use of non-static data member %qD", member);
+ return error_mark_node;
+ }
+ return member;
+ }
+
+ member = build2 (OFFSET_REF, TREE_TYPE (member), decl, member);
+ PTRMEM_OK_P (member) = 1;
+ return member;
+}
+
+/* If DECL is a scalar enumeration constant or variable with a
+ constant initializer, return the initializer (or, its initializers,
+ recursively); otherwise, return DECL. If INTEGRAL_P, the
+ initializer is only returned if DECL is an integral
+ constant-expression. If RETURN_AGGREGATE_CST_OK_P, it is ok to
+ return an aggregate constant. */
+
+static tree
+constant_value_1 (tree decl, bool integral_p, bool return_aggregate_cst_ok_p)
+{
+ while (TREE_CODE (decl) == CONST_DECL
+ || (integral_p
+ ? decl_constant_var_p (decl)
+ : (VAR_P (decl)
+ && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))))
+ {
+ tree init;
+ /* If DECL is a static data member in a template
+ specialization, we must instantiate it here. The
+ initializer for the static data member is not processed
+ until needed; we need it now. */
+ mark_used (decl);
+ mark_rvalue_use (decl);
+ init = DECL_INITIAL (decl);
+ if (init == error_mark_node)
+ {
+ if (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
+ /* Treat the error as a constant to avoid cascading errors on
+ excessively recursive template instantiation (c++/9335). */
+ return init;
+ else
+ return decl;
+ }
+ /* Initializers in templates are generally expanded during
+ instantiation, so before that for const int i(2)
+ INIT is a TREE_LIST with the actual initializer as
+ TREE_VALUE. */
+ if (processing_template_decl
+ && init
+ && TREE_CODE (init) == TREE_LIST
+ && TREE_CHAIN (init) == NULL_TREE)
+ init = TREE_VALUE (init);
+ if (!init
+ || !TREE_TYPE (init)
+ || !TREE_CONSTANT (init)
+ || (!integral_p && !return_aggregate_cst_ok_p
+ /* Unless RETURN_AGGREGATE_CST_OK_P is true, do not
+ return an aggregate constant (of which string
+ literals are a special case), as we do not want
+ to make inadvertent copies of such entities, and
+ we must be sure that their addresses are the
+ same everywhere. */
+ && (TREE_CODE (init) == CONSTRUCTOR
+ || TREE_CODE (init) == STRING_CST)))
+ break;
+ decl = unshare_expr (init);
+ }
+ return decl;
+}
+
+/* If DECL is a CONST_DECL, or a constant VAR_DECL initialized by
+ constant of integral or enumeration type, then return that value.
+ These are those variables permitted in constant expressions by
+ [5.19/1]. */
+
+tree
+integral_constant_value (tree decl)
+{
+ return constant_value_1 (decl, /*integral_p=*/true,
+ /*return_aggregate_cst_ok_p=*/false);
+}
+
+/* A more relaxed version of integral_constant_value, used by the
+ common C/C++ code. */
+
+tree
+decl_constant_value (tree decl)
+{
+ return constant_value_1 (decl, /*integral_p=*/processing_template_decl,
+ /*return_aggregate_cst_ok_p=*/true);
+}
+
+/* A version of integral_constant_value used by the C++ front end for
+ optimization purposes. */
+
+tree
+decl_constant_value_safe (tree decl)
+{
+ return constant_value_1 (decl, /*integral_p=*/processing_template_decl,
+ /*return_aggregate_cst_ok_p=*/false);
+}
+
+/* Common subroutines of build_new and build_vec_delete. */
+
+/* Call the global __builtin_delete to delete ADDR. */
+
+static tree
+build_builtin_delete_call (tree addr)
+{
+ mark_used (global_delete_fndecl);
+ return build_call_n (global_delete_fndecl, 1, addr);
+}
+
+/* Build and return a NEW_EXPR. If NELTS is non-NULL, TYPE[NELTS] is
+ the type of the object being allocated; otherwise, it's just TYPE.
+ INIT is the initializer, if any. USE_GLOBAL_NEW is true if the
+ user explicitly wrote "::operator new". PLACEMENT, if non-NULL, is
+ a vector of arguments to be provided as arguments to a placement
+ new operator. This routine performs no semantic checks; it just
+ creates and returns a NEW_EXPR. */
+
+static tree
+build_raw_new_expr (vec<tree, va_gc> *placement, tree type, tree nelts,
+ vec<tree, va_gc> *init, int use_global_new)
+{
+ tree init_list;
+ tree new_expr;
+
+ /* If INIT is NULL, the we want to store NULL_TREE in the NEW_EXPR.
+ If INIT is not NULL, then we want to store VOID_ZERO_NODE. This
+ permits us to distinguish the case of a missing initializer "new
+ int" from an empty initializer "new int()". */
+ if (init == NULL)
+ init_list = NULL_TREE;
+ else if (init->is_empty ())
+ init_list = void_zero_node;
+ else
+ init_list = build_tree_list_vec (init);
+
+ new_expr = build4 (NEW_EXPR, build_pointer_type (type),
+ build_tree_list_vec (placement), type, nelts,
+ init_list);
+ NEW_EXPR_USE_GLOBAL (new_expr) = use_global_new;
+ TREE_SIDE_EFFECTS (new_expr) = 1;
+
+ return new_expr;
+}
+
+/* Diagnose uninitialized const members or reference members of type
+ TYPE. USING_NEW is used to disambiguate the diagnostic between a
+ new expression without a new-initializer and a declaration. Returns
+ the error count. */
+
+static int
+diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin,
+ bool using_new, bool complain)
+{
+ tree field;
+ int error_count = 0;
+
+ if (type_has_user_provided_constructor (type))
+ return 0;
+
+ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ {
+ tree field_type;
+
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ field_type = strip_array_types (TREE_TYPE (field));
+
+ if (type_has_user_provided_constructor (field_type))
+ continue;
+
+ if (TREE_CODE (field_type) == REFERENCE_TYPE)
+ {
+ ++ error_count;
+ if (complain)
+ {
+ if (DECL_CONTEXT (field) == origin)
+ {
+ if (using_new)
+ error ("uninitialized reference member in %q#T "
+ "using %<new%> without new-initializer", origin);
+ else
+ error ("uninitialized reference member in %q#T", origin);
+ }
+ else
+ {
+ if (using_new)
+ error ("uninitialized reference member in base %q#T "
+ "of %q#T using %<new%> without new-initializer",
+ DECL_CONTEXT (field), origin);
+ else
+ error ("uninitialized reference member in base %q#T "
+ "of %q#T", DECL_CONTEXT (field), origin);
+ }
+ inform (DECL_SOURCE_LOCATION (field),
+ "%qD should be initialized", field);
+ }
+ }
+
+ if (CP_TYPE_CONST_P (field_type))
+ {
+ ++ error_count;
+ if (complain)
+ {
+ if (DECL_CONTEXT (field) == origin)
+ {
+ if (using_new)
+ error ("uninitialized const member in %q#T "
+ "using %<new%> without new-initializer", origin);
+ else
+ error ("uninitialized const member in %q#T", origin);
+ }
+ else
+ {
+ if (using_new)
+ error ("uninitialized const member in base %q#T "
+ "of %q#T using %<new%> without new-initializer",
+ DECL_CONTEXT (field), origin);
+ else
+ error ("uninitialized const member in base %q#T "
+ "of %q#T", DECL_CONTEXT (field), origin);
+ }
+ inform (DECL_SOURCE_LOCATION (field),
+ "%qD should be initialized", field);
+ }
+ }
+
+ if (CLASS_TYPE_P (field_type))
+ error_count
+ += diagnose_uninitialized_cst_or_ref_member_1 (field_type, origin,
+ using_new, complain);
+ }
+ return error_count;
+}
+
+int
+diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new, bool complain)
+{
+ return diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new, complain);
+}
+
+/* Call __cxa_bad_array_new_length to indicate that the size calculation
+ overflowed. Pretend it returns sizetype so that it plays nicely in the
+ COND_EXPR. */
+
+tree
+throw_bad_array_new_length (void)
+{
+ tree fn = get_identifier ("__cxa_throw_bad_array_new_length");
+ if (!get_global_value_if_present (fn, &fn))
+ fn = push_throw_library_fn (fn, build_function_type_list (sizetype,
+ NULL_TREE));
+
+ return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
+}
+
+/* Call __cxa_bad_array_length to indicate that there were too many
+ initializers. */
+
+tree
+throw_bad_array_length (void)
+{
+ tree fn = get_identifier ("__cxa_throw_bad_array_length");
+ if (!get_global_value_if_present (fn, &fn))
+ fn = push_throw_library_fn (fn, build_function_type_list (void_type_node,
+ NULL_TREE));
+
+ return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
+}
+
+/* Generate code for a new-expression, including calling the "operator
+ new" function, initializing the object, and, if an exception occurs
+ during construction, cleaning up. The arguments are as for
+ build_raw_new_expr. This may change PLACEMENT and INIT. */
+
+static tree
+build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
+ vec<tree, va_gc> **init, bool globally_qualified_p,
+ tsubst_flags_t complain)
+{
+ tree size, rval;
+ /* True iff this is a call to "operator new[]" instead of just
+ "operator new". */
+ bool array_p = false;
+ /* If ARRAY_P is true, the element type of the array. This is never
+ an ARRAY_TYPE; for something like "new int[3][4]", the
+ ELT_TYPE is "int". If ARRAY_P is false, this is the same type as
+ TYPE. */
+ tree elt_type;
+ /* The type of the new-expression. (This type is always a pointer
+ type.) */
+ tree pointer_type;
+ tree non_const_pointer_type;
+ tree outer_nelts = NULL_TREE;
+ /* For arrays, a bounds checks on the NELTS parameter. */
+ tree outer_nelts_check = NULL_TREE;
+ bool outer_nelts_from_type = false;
+ double_int inner_nelts_count = double_int_one;
+ tree alloc_call, alloc_expr;
+ /* Size of the inner array elements. */
+ double_int inner_size;
+ /* The address returned by the call to "operator new". This node is
+ a VAR_DECL and is therefore reusable. */
+ tree alloc_node;
+ tree alloc_fn;
+ tree cookie_expr, init_expr;
+ int nothrow, check_new;
+ int use_java_new = 0;
+ /* If non-NULL, the number of extra bytes to allocate at the
+ beginning of the storage allocated for an array-new expression in
+ order to store the number of elements. */
+ tree cookie_size = NULL_TREE;
+ tree placement_first;
+ tree placement_expr = NULL_TREE;
+ /* True if the function we are calling is a placement allocation
+ function. */
+ bool placement_allocation_fn_p;
+ /* True if the storage must be initialized, either by a constructor
+ or due to an explicit new-initializer. */
+ bool is_initialized;
+ /* The address of the thing allocated, not including any cookie. In
+ particular, if an array cookie is in use, DATA_ADDR is the
+ address of the first array element. This node is a VAR_DECL, and
+ is therefore reusable. */
+ tree data_addr;
+ tree init_preeval_expr = NULL_TREE;
+ tree orig_type = type;
+
+ if (nelts)
+ {
+ outer_nelts = nelts;
+ array_p = true;
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ /* Transforms new (T[N]) to new T[N]. The former is a GNU
+ extension for variable N. (This also covers new T where T is
+ a VLA typedef.) */
+ array_p = true;
+ nelts = array_type_nelts_top (type);
+ outer_nelts = nelts;
+ type = TREE_TYPE (type);
+ outer_nelts_from_type = true;
+ }
+
+ /* If our base type is an array, then make sure we know how many elements
+ it has. */
+ for (elt_type = type;
+ TREE_CODE (elt_type) == ARRAY_TYPE;
+ elt_type = TREE_TYPE (elt_type))
+ {
+ tree inner_nelts = array_type_nelts_top (elt_type);
+ tree inner_nelts_cst = maybe_constant_value (inner_nelts);
+ if (TREE_CODE (inner_nelts_cst) == INTEGER_CST)
+ {
+ bool overflow;
+ double_int result = TREE_INT_CST (inner_nelts_cst)
+ .mul_with_sign (inner_nelts_count,
+ false, &overflow);
+ if (overflow)
+ {
+ if (complain & tf_error)
+ error ("integer overflow in array size");
+ nelts = error_mark_node;
+ }
+ inner_nelts_count = result;
+ }
+ else
+ {
+ if (complain & tf_error)
+ {
+ error_at (EXPR_LOC_OR_LOC (inner_nelts, input_location),
+ "array size in new-expression must be constant");
+ cxx_constant_value(inner_nelts);
+ }
+ nelts = error_mark_node;
+ }
+ if (nelts != error_mark_node)
+ nelts = cp_build_binary_op (input_location,
+ MULT_EXPR, nelts,
+ inner_nelts_cst,
+ complain);
+ }
+
+ if (variably_modified_type_p (elt_type, NULL_TREE) && (complain & tf_error))
+ {
+ error ("variably modified type not allowed in new-expression");
+ return error_mark_node;
+ }
+
+ if (nelts == error_mark_node)
+ return error_mark_node;
+
+ /* Warn if we performed the (T[N]) to T[N] transformation and N is
+ variable. */
+ if (outer_nelts_from_type
+ && !TREE_CONSTANT (maybe_constant_value (outer_nelts)))
+ {
+ if (complain & tf_warning_or_error)
+ {
+ const char *msg;
+ if (typedef_variant_p (orig_type))
+ msg = ("non-constant array new length must be specified "
+ "directly, not by typedef");
+ else
+ msg = ("non-constant array new length must be specified "
+ "without parentheses around the type-id");
+ pedwarn (EXPR_LOC_OR_LOC (outer_nelts, input_location),
+ OPT_Wvla, msg);
+ }
+ else
+ return error_mark_node;
+ }
+
+ if (VOID_TYPE_P (elt_type))
+ {
+ if (complain & tf_error)
+ error ("invalid type %<void%> for new");
+ return error_mark_node;
+ }
+
+ if (abstract_virtuals_error_sfinae (ACU_NEW, elt_type, complain))
+ return error_mark_node;
+
+ is_initialized = (type_build_ctor_call (elt_type) || *init != NULL);
+
+ if (*init == NULL && cxx_dialect < cxx11)
+ {
+ bool maybe_uninitialized_error = false;
+ /* A program that calls for default-initialization [...] of an
+ entity of reference type is ill-formed. */
+ if (CLASSTYPE_REF_FIELDS_NEED_INIT (elt_type))
+ maybe_uninitialized_error = true;
+
+ /* A new-expression that creates an object of type T initializes
+ that object as follows:
+ - If the new-initializer is omitted:
+ -- If T is a (possibly cv-qualified) non-POD class type
+ (or array thereof), the object is default-initialized (8.5).
+ [...]
+ -- Otherwise, the object created has indeterminate
+ value. If T is a const-qualified type, or a (possibly
+ cv-qualified) POD class type (or array thereof)
+ containing (directly or indirectly) a member of
+ const-qualified type, the program is ill-formed; */
+
+ if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (elt_type))
+ maybe_uninitialized_error = true;
+
+ if (maybe_uninitialized_error
+ && diagnose_uninitialized_cst_or_ref_member (elt_type,
+ /*using_new=*/true,
+ complain & tf_error))
+ return error_mark_node;
+ }
+
+ if (CP_TYPE_CONST_P (elt_type) && *init == NULL
+ && default_init_uninitialized_part (elt_type))
+ {
+ if (complain & tf_error)
+ error ("uninitialized const in %<new%> of %q#T", elt_type);
+ return error_mark_node;
+ }
+
+ size = size_in_bytes (elt_type);
+ if (array_p)
+ {
+ /* Maximum available size in bytes. Half of the address space
+ minus the cookie size. */
+ double_int max_size
+ = double_int_one.llshift (TYPE_PRECISION (sizetype) - 1,
+ HOST_BITS_PER_DOUBLE_INT);
+ /* Maximum number of outer elements which can be allocated. */
+ double_int max_outer_nelts;
+ tree max_outer_nelts_tree;
+
+ gcc_assert (TREE_CODE (size) == INTEGER_CST);
+ cookie_size = targetm.cxx.get_cookie_size (elt_type);
+ gcc_assert (TREE_CODE (cookie_size) == INTEGER_CST);
+ gcc_checking_assert (TREE_INT_CST (cookie_size).ult (max_size));
+ /* Unconditionally subtract the cookie size. This decreases the
+ maximum object size and is safe even if we choose not to use
+ a cookie after all. */
+ max_size -= TREE_INT_CST (cookie_size);
+ bool overflow;
+ inner_size = TREE_INT_CST (size)
+ .mul_with_sign (inner_nelts_count, false, &overflow);
+ if (overflow || inner_size.ugt (max_size))
+ {
+ if (complain & tf_error)
+ error ("size of array is too large");
+ return error_mark_node;
+ }
+ max_outer_nelts = max_size.udiv (inner_size, TRUNC_DIV_EXPR);
+ /* Only keep the top-most seven bits, to simplify encoding the
+ constant in the instruction stream. */
+ {
+ unsigned shift = HOST_BITS_PER_DOUBLE_INT - 7
+ - (max_outer_nelts.high ? clz_hwi (max_outer_nelts.high)
+ : (HOST_BITS_PER_WIDE_INT + clz_hwi (max_outer_nelts.low)));
+ max_outer_nelts
+ = max_outer_nelts.lrshift (shift, HOST_BITS_PER_DOUBLE_INT)
+ .llshift (shift, HOST_BITS_PER_DOUBLE_INT);
+ }
+ max_outer_nelts_tree = double_int_to_tree (sizetype, max_outer_nelts);
+
+ size = size_binop (MULT_EXPR, size, convert (sizetype, nelts));
+ outer_nelts_check = fold_build2 (LE_EXPR, boolean_type_node,
+ outer_nelts,
+ max_outer_nelts_tree);
+ }
+
+ alloc_fn = NULL_TREE;
+
+ /* If PLACEMENT is a single simple pointer type not passed by
+ reference, prepare to capture it in a temporary variable. Do
+ this now, since PLACEMENT will change in the calls below. */
+ placement_first = NULL_TREE;
+ if (vec_safe_length (*placement) == 1
+ && (TYPE_PTR_P (TREE_TYPE ((**placement)[0]))))
+ placement_first = (**placement)[0];
+
+ /* Allocate the object. */
+ if (vec_safe_is_empty (*placement) && TYPE_FOR_JAVA (elt_type))
+ {
+ tree class_addr;
+ tree class_decl;
+ static const char alloc_name[] = "_Jv_AllocObject";
+
+ if (!MAYBE_CLASS_TYPE_P (elt_type))
+ {
+ error ("%qT isn%'t a valid Java class type", elt_type);
+ return error_mark_node;
+ }
+
+ class_decl = build_java_class_ref (elt_type);
+ if (class_decl == error_mark_node)
+ return error_mark_node;
+
+ use_java_new = 1;
+ if (!get_global_value_if_present (get_identifier (alloc_name),
+ &alloc_fn))
+ {
+ if (complain & tf_error)
+ error ("call to Java constructor with %qs undefined", alloc_name);
+ return error_mark_node;
+ }
+ else if (really_overloaded_fn (alloc_fn))
+ {
+ if (complain & tf_error)
+ error ("%qD should never be overloaded", alloc_fn);
+ return error_mark_node;
+ }
+ alloc_fn = OVL_CURRENT (alloc_fn);
+ class_addr = build1 (ADDR_EXPR, jclass_node, class_decl);
+ alloc_call = cp_build_function_call_nary (alloc_fn, complain,
+ class_addr, NULL_TREE);
+ }
+ else if (TYPE_FOR_JAVA (elt_type) && MAYBE_CLASS_TYPE_P (elt_type))
+ {
+ error ("Java class %q#T object allocated using placement new", elt_type);
+ return error_mark_node;
+ }
+ else
+ {
+ tree fnname;
+ tree fns;
+
+ fnname = ansi_opname (array_p ? VEC_NEW_EXPR : NEW_EXPR);
+
+ if (!globally_qualified_p
+ && CLASS_TYPE_P (elt_type)
+ && (array_p
+ ? TYPE_HAS_ARRAY_NEW_OPERATOR (elt_type)
+ : TYPE_HAS_NEW_OPERATOR (elt_type)))
+ {
+ /* Use a class-specific operator new. */
+ /* If a cookie is required, add some extra space. */
+ if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))
+ size = size_binop (PLUS_EXPR, size, cookie_size);
+ else
+ {
+ cookie_size = NULL_TREE;
+ /* No size arithmetic necessary, so the size check is
+ not needed. */
+ if (outer_nelts_check != NULL && inner_size.is_one ())
+ outer_nelts_check = NULL_TREE;
+ }
+ /* Perform the overflow check. */
+ tree errval = TYPE_MAX_VALUE (sizetype);
+ if (cxx_dialect >= cxx11 && flag_exceptions)
+ errval = throw_bad_array_new_length ();
+ if (outer_nelts_check != NULL_TREE)
+ size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check,
+ size, errval);
+ /* Create the argument list. */
+ vec_safe_insert (*placement, 0, size);
+ /* Do name-lookup to find the appropriate operator. */
+ fns = lookup_fnfields (elt_type, fnname, /*protect=*/2);
+ if (fns == NULL_TREE)
+ {
+ if (complain & tf_error)
+ error ("no suitable %qD found in class %qT", fnname, elt_type);
+ return error_mark_node;
+ }
+ if (TREE_CODE (fns) == TREE_LIST)
+ {
+ if (complain & tf_error)
+ {
+ error ("request for member %qD is ambiguous", fnname);
+ print_candidates (fns);
+ }
+ return error_mark_node;
+ }
+ alloc_call = build_new_method_call (build_dummy_object (elt_type),
+ fns, placement,
+ /*conversion_path=*/NULL_TREE,
+ LOOKUP_NORMAL,
+ &alloc_fn,
+ complain);
+ }
+ else
+ {
+ /* Use a global operator new. */
+ /* See if a cookie might be required. */
+ if (!(array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type)))
+ {
+ cookie_size = NULL_TREE;
+ /* No size arithmetic necessary, so the size check is
+ not needed. */
+ if (outer_nelts_check != NULL && inner_size.is_one ())
+ outer_nelts_check = NULL_TREE;
+ }
+
+ alloc_call = build_operator_new_call (fnname, placement,
+ &size, &cookie_size,
+ outer_nelts_check,
+ &alloc_fn, complain);
+ }
+ }
+
+ if (alloc_call == error_mark_node)
+ return error_mark_node;
+
+ gcc_assert (alloc_fn != NULL_TREE);
+
+ /* If we found a simple case of PLACEMENT_EXPR above, then copy it
+ into a temporary variable. */
+ if (!processing_template_decl
+ && placement_first != NULL_TREE
+ && TREE_CODE (alloc_call) == CALL_EXPR
+ && call_expr_nargs (alloc_call) == 2
+ && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 0))) == INTEGER_TYPE
+ && TYPE_PTR_P (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 1))))
+ {
+ tree placement_arg = CALL_EXPR_ARG (alloc_call, 1);
+
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg)))
+ || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg))))
+ {
+ placement_expr = get_target_expr (placement_first);
+ CALL_EXPR_ARG (alloc_call, 1)
+ = convert (TREE_TYPE (placement_arg), placement_expr);
+ }
+ }
+
+ /* In the simple case, we can stop now. */
+ pointer_type = build_pointer_type (type);
+ if (!cookie_size && !is_initialized)
+ return build_nop (pointer_type, alloc_call);
+
+ /* Store the result of the allocation call in a variable so that we can
+ use it more than once. */
+ alloc_expr = get_target_expr (alloc_call);
+ alloc_node = TARGET_EXPR_SLOT (alloc_expr);
+
+ /* Strip any COMPOUND_EXPRs from ALLOC_CALL. */
+ while (TREE_CODE (alloc_call) == COMPOUND_EXPR)
+ alloc_call = TREE_OPERAND (alloc_call, 1);
+
+ /* Now, check to see if this function is actually a placement
+ allocation function. This can happen even when PLACEMENT is NULL
+ because we might have something like:
+
+ struct S { void* operator new (size_t, int i = 0); };
+
+ A call to `new S' will get this allocation function, even though
+ there is no explicit placement argument. If there is more than
+ one argument, or there are variable arguments, then this is a
+ placement allocation function. */
+ placement_allocation_fn_p
+ = (type_num_arguments (TREE_TYPE (alloc_fn)) > 1
+ || varargs_function_p (alloc_fn));
+
+ /* Preevaluate the placement args so that we don't reevaluate them for a
+ placement delete. */
+ if (placement_allocation_fn_p)
+ {
+ tree inits;
+ stabilize_call (alloc_call, &inits);
+ if (inits)
+ alloc_expr = build2 (COMPOUND_EXPR, TREE_TYPE (alloc_expr), inits,
+ alloc_expr);
+ }
+
+ /* unless an allocation function is declared with an empty excep-
+ tion-specification (_except.spec_), throw(), it indicates failure to
+ allocate storage by throwing a bad_alloc exception (clause _except_,
+ _lib.bad.alloc_); it returns a non-null pointer otherwise If the allo-
+ cation function is declared with an empty exception-specification,
+ throw(), it returns null to indicate failure to allocate storage and a
+ non-null pointer otherwise.
+
+ So check for a null exception spec on the op new we just called. */
+
+ nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn));
+ check_new = (flag_check_new || nothrow) && ! use_java_new;
+
+ if (cookie_size)
+ {
+ tree cookie;
+ tree cookie_ptr;
+ tree size_ptr_type;
+
+ /* Adjust so we're pointing to the start of the object. */
+ data_addr = fold_build_pointer_plus (alloc_node, cookie_size);
+
+ /* Store the number of bytes allocated so that we can know how
+ many elements to destroy later. We use the last sizeof
+ (size_t) bytes to store the number of elements. */
+ cookie_ptr = size_binop (MINUS_EXPR, cookie_size, size_in_bytes (sizetype));
+ cookie_ptr = fold_build_pointer_plus_loc (input_location,
+ alloc_node, cookie_ptr);
+ size_ptr_type = build_pointer_type (sizetype);
+ cookie_ptr = fold_convert (size_ptr_type, cookie_ptr);
+ cookie = cp_build_indirect_ref (cookie_ptr, RO_NULL, complain);
+
+ cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
+
+ if (targetm.cxx.cookie_has_size ())
+ {
+ /* Also store the element size. */
+ cookie_ptr = fold_build_pointer_plus (cookie_ptr,
+ fold_build1_loc (input_location,
+ NEGATE_EXPR, sizetype,
+ size_in_bytes (sizetype)));
+
+ cookie = cp_build_indirect_ref (cookie_ptr, RO_NULL, complain);
+ cookie = build2 (MODIFY_EXPR, sizetype, cookie,
+ size_in_bytes (elt_type));
+ cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
+ cookie, cookie_expr);
+ }
+ }
+ else
+ {
+ cookie_expr = NULL_TREE;
+ data_addr = alloc_node;
+ }
+
+ /* Now use a pointer to the type we've actually allocated. */
+
+ /* But we want to operate on a non-const version to start with,
+ since we'll be modifying the elements. */
+ non_const_pointer_type = build_pointer_type
+ (cp_build_qualified_type (type, cp_type_quals (type) & ~TYPE_QUAL_CONST));
+
+ data_addr = fold_convert (non_const_pointer_type, data_addr);
+ /* Any further uses of alloc_node will want this type, too. */
+ alloc_node = fold_convert (non_const_pointer_type, alloc_node);
+
+ /* Now initialize the allocated object. Note that we preevaluate the
+ initialization expression, apart from the actual constructor call or
+ assignment--we do this because we want to delay the allocation as long
+ as possible in order to minimize the size of the exception region for
+ placement delete. */
+ if (is_initialized)
+ {
+ bool stable;
+ bool explicit_value_init_p = false;
+
+ if (*init != NULL && (*init)->is_empty ())
+ {
+ *init = NULL;
+ explicit_value_init_p = true;
+ }
+
+ if (processing_template_decl && explicit_value_init_p)
+ {
+ /* build_value_init doesn't work in templates, and we don't need
+ the initializer anyway since we're going to throw it away and
+ rebuild it at instantiation time, so just build up a single
+ constructor call to get any appropriate diagnostics. */
+ init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
+ if (type_build_ctor_call (elt_type))
+ init_expr = build_special_member_call (init_expr,
+ complete_ctor_identifier,
+ init, elt_type,
+ LOOKUP_NORMAL,
+ complain);
+ stable = stabilize_init (init_expr, &init_preeval_expr);
+ }
+ else if (array_p)
+ {
+ tree vecinit = NULL_TREE;
+ if (vec_safe_length (*init) == 1
+ && BRACE_ENCLOSED_INITIALIZER_P ((**init)[0])
+ && CONSTRUCTOR_IS_DIRECT_INIT ((**init)[0]))
+ {
+ vecinit = (**init)[0];
+ if (CONSTRUCTOR_NELTS (vecinit) == 0)
+ /* List-value-initialization, leave it alone. */;
+ else
+ {
+ tree arraytype, domain;
+ if (TREE_CONSTANT (nelts))
+ domain = compute_array_index_type (NULL_TREE, nelts,
+ complain);
+ else
+ /* We'll check the length at runtime. */
+ domain = NULL_TREE;
+ arraytype = build_cplus_array_type (type, domain);
+ vecinit = digest_init (arraytype, vecinit, complain);
+ }
+ }
+ else if (*init)
+ {
+ if (complain & tf_error)
+ permerror (input_location,
+ "parenthesized initializer in array new");
+ else
+ return error_mark_node;
+ vecinit = build_tree_list_vec (*init);
+ }
+ init_expr
+ = build_vec_init (data_addr,
+ cp_build_binary_op (input_location,
+ MINUS_EXPR, outer_nelts,
+ integer_one_node,
+ complain),
+ vecinit,
+ explicit_value_init_p,
+ /*from_array=*/0,
+ complain);
+
+ /* An array initialization is stable because the initialization
+ of each element is a full-expression, so the temporaries don't
+ leak out. */
+ stable = true;
+ }
+ else
+ {
+ init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
+
+ if (type_build_ctor_call (type) && !explicit_value_init_p)
+ {
+ init_expr = build_special_member_call (init_expr,
+ complete_ctor_identifier,
+ init, elt_type,
+ LOOKUP_NORMAL,
+ complain);
+ }
+ else if (explicit_value_init_p)
+ {
+ /* Something like `new int()'. */
+ tree val = build_value_init (type, complain);
+ if (val == error_mark_node)
+ return error_mark_node;
+ init_expr = build2 (INIT_EXPR, type, init_expr, val);
+ }
+ else
+ {
+ tree ie;
+
+ /* We are processing something like `new int (10)', which
+ means allocate an int, and initialize it with 10. */
+
+ ie = build_x_compound_expr_from_vec (*init, "new initializer",
+ complain);
+ init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, ie,
+ complain);
+ }
+ stable = stabilize_init (init_expr, &init_preeval_expr);
+ }
+
+ if (init_expr == error_mark_node)
+ return error_mark_node;
+
+ /* If any part of the object initialization terminates by throwing an
+ exception and a suitable deallocation function can be found, the
+ deallocation function is called to free the memory in which the
+ object was being constructed, after which the exception continues
+ to propagate in the context of the new-expression. If no
+ unambiguous matching deallocation function can be found,
+ propagating the exception does not cause the object's memory to be
+ freed. */
+ if (flag_exceptions && ! use_java_new)
+ {
+ enum tree_code dcode = array_p ? VEC_DELETE_EXPR : DELETE_EXPR;
+ tree cleanup;
+
+ /* The Standard is unclear here, but the right thing to do
+ is to use the same method for finding deallocation
+ functions that we use for finding allocation functions. */
+ cleanup = (build_op_delete_call
+ (dcode,
+ alloc_node,
+ size,
+ globally_qualified_p,
+ placement_allocation_fn_p ? alloc_call : NULL_TREE,
+ alloc_fn,
+ complain));
+
+ if (!cleanup)
+ /* We're done. */;
+ else if (stable)
+ /* This is much simpler if we were able to preevaluate all of
+ the arguments to the constructor call. */
+ {
+ /* CLEANUP is compiler-generated, so no diagnostics. */
+ TREE_NO_WARNING (cleanup) = true;
+ init_expr = build2 (TRY_CATCH_EXPR, void_type_node,
+ init_expr, cleanup);
+ /* Likewise, this try-catch is compiler-generated. */
+ TREE_NO_WARNING (init_expr) = true;
+ }
+ else
+ /* Ack! First we allocate the memory. Then we set our sentry
+ variable to true, and expand a cleanup that deletes the
+ memory if sentry is true. Then we run the constructor, and
+ finally clear the sentry.
+
+ We need to do this because we allocate the space first, so
+ if there are any temporaries with cleanups in the
+ constructor args and we weren't able to preevaluate them, we
+ need this EH region to extend until end of full-expression
+ to preserve nesting. */
+ {
+ tree end, sentry, begin;
+
+ begin = get_target_expr (boolean_true_node);
+ CLEANUP_EH_ONLY (begin) = 1;
+
+ sentry = TARGET_EXPR_SLOT (begin);
+
+ /* CLEANUP is compiler-generated, so no diagnostics. */
+ TREE_NO_WARNING (cleanup) = true;
+
+ TARGET_EXPR_CLEANUP (begin)
+ = build3 (COND_EXPR, void_type_node, sentry,
+ cleanup, void_zero_node);
+
+ end = build2 (MODIFY_EXPR, TREE_TYPE (sentry),
+ sentry, boolean_false_node);
+
+ init_expr
+ = build2 (COMPOUND_EXPR, void_type_node, begin,
+ build2 (COMPOUND_EXPR, void_type_node, init_expr,
+ end));
+ /* Likewise, this is compiler-generated. */
+ TREE_NO_WARNING (init_expr) = true;
+ }
+ }
+ }
+ else
+ init_expr = NULL_TREE;
+
+ /* Now build up the return value in reverse order. */
+
+ rval = data_addr;
+
+ if (init_expr)
+ rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_expr, rval);
+ if (cookie_expr)
+ rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), cookie_expr, rval);
+
+ if (rval == data_addr)
+ /* If we don't have an initializer or a cookie, strip the TARGET_EXPR
+ and return the call (which doesn't need to be adjusted). */
+ rval = TARGET_EXPR_INITIAL (alloc_expr);
+ else
+ {
+ if (check_new)
+ {
+ tree ifexp = cp_build_binary_op (input_location,
+ NE_EXPR, alloc_node,
+ nullptr_node,
+ complain);
+ rval = build_conditional_expr (input_location, ifexp, rval,
+ alloc_node, complain);
+ }
+
+ /* Perform the allocation before anything else, so that ALLOC_NODE
+ has been initialized before we start using it. */
+ rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
+ }
+
+ if (init_preeval_expr)
+ rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_preeval_expr, rval);
+
+ /* A new-expression is never an lvalue. */
+ gcc_assert (!lvalue_p (rval));
+
+ return convert (pointer_type, rval);
+}
+
+/* Generate a representation for a C++ "new" expression. *PLACEMENT
+ is a vector of placement-new arguments (or NULL if none). If NELTS
+ is NULL, TYPE is the type of the storage to be allocated. If NELTS
+ is not NULL, then this is an array-new allocation; TYPE is the type
+ of the elements in the array and NELTS is the number of elements in
+ the array. *INIT, if non-NULL, is the initializer for the new
+ object, or an empty vector to indicate an initializer of "()". If
+ USE_GLOBAL_NEW is true, then the user explicitly wrote "::new"
+ rather than just "new". This may change PLACEMENT and INIT. */
+
+tree
+build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
+ vec<tree, va_gc> **init, int use_global_new, tsubst_flags_t complain)
+{
+ tree rval;
+ vec<tree, va_gc> *orig_placement = NULL;
+ tree orig_nelts = NULL_TREE;
+ vec<tree, va_gc> *orig_init = NULL;
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ if (nelts == NULL_TREE && vec_safe_length (*init) == 1
+ /* Don't do auto deduction where it might affect mangling. */
+ && (!processing_template_decl || at_function_scope_p ()))
+ {
+ tree auto_node = type_uses_auto (type);
+ if (auto_node)
+ {
+ tree d_init = (**init)[0];
+ d_init = resolve_nondeduced_context (d_init);
+ type = do_auto_deduction (type, d_init, auto_node);
+ }
+ }
+
+ if (processing_template_decl)
+ {
+ if (dependent_type_p (type)
+ || any_type_dependent_arguments_p (*placement)
+ || (nelts && type_dependent_expression_p (nelts))
+ || (nelts && *init)
+ || any_type_dependent_arguments_p (*init))
+ return build_raw_new_expr (*placement, type, nelts, *init,
+ use_global_new);
+
+ orig_placement = make_tree_vector_copy (*placement);
+ orig_nelts = nelts;
+ if (*init)
+ orig_init = make_tree_vector_copy (*init);
+
+ make_args_non_dependent (*placement);
+ if (nelts)
+ nelts = build_non_dependent_expr (nelts);
+ make_args_non_dependent (*init);
+ }
+
+ if (nelts)
+ {
+ if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, nelts, false))
+ {
+ if (complain & tf_error)
+ permerror (input_location, "size in array new must have integral type");
+ else
+ return error_mark_node;
+ }
+ nelts = mark_rvalue_use (nelts);
+ nelts = cp_save_expr (cp_convert (sizetype, nelts, complain));
+ }
+
+ /* ``A reference cannot be created by the new operator. A reference
+ is not an object (8.2.2, 8.4.3), so a pointer to it could not be
+ returned by new.'' ARM 5.3.3 */
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (complain & tf_error)
+ error ("new cannot be applied to a reference type");
+ else
+ return error_mark_node;
+ type = TREE_TYPE (type);
+ }
+
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ if (complain & tf_error)
+ error ("new cannot be applied to a function type");
+ return error_mark_node;
+ }
+
+ /* The type allocated must be complete. If the new-type-id was
+ "T[N]" then we are just checking that "T" is complete here, but
+ that is equivalent, since the value of "N" doesn't matter. */
+ if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
+ return error_mark_node;
+
+ rval = build_new_1 (placement, type, nelts, init, use_global_new, complain);
+ if (rval == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ tree ret = build_raw_new_expr (orig_placement, type, orig_nelts,
+ orig_init, use_global_new);
+ release_tree_vector (orig_placement);
+ release_tree_vector (orig_init);
+ return ret;
+ }
+
+ /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain. */
+ rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
+ TREE_NO_WARNING (rval) = 1;
+
+ return rval;
+}
+
+/* Given a Java class, return a decl for the corresponding java.lang.Class. */
+
+tree
+build_java_class_ref (tree type)
+{
+ tree name = NULL_TREE, class_decl;
+ static tree CL_suffix = NULL_TREE;
+ if (CL_suffix == NULL_TREE)
+ CL_suffix = get_identifier("class$");
+ if (jclass_node == NULL_TREE)
+ {
+ jclass_node = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jclass"));
+ if (jclass_node == NULL_TREE)
+ {
+ error ("call to Java constructor, while %<jclass%> undefined");
+ return error_mark_node;
+ }
+ jclass_node = TREE_TYPE (jclass_node);
+ }
+
+ /* Mangle the class$ field. */
+ {
+ tree field;
+ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ if (DECL_NAME (field) == CL_suffix)
+ {
+ mangle_decl (field);
+ name = DECL_ASSEMBLER_NAME (field);
+ break;
+ }
+ if (!field)
+ {
+ error ("can%'t find %<class$%> in %qT", type);
+ return error_mark_node;
+ }
+ }
+
+ class_decl = IDENTIFIER_GLOBAL_VALUE (name);
+ if (class_decl == NULL_TREE)
+ {
+ class_decl = build_decl (input_location,
+ VAR_DECL, name, TREE_TYPE (jclass_node));
+ TREE_STATIC (class_decl) = 1;
+ DECL_EXTERNAL (class_decl) = 1;
+ TREE_PUBLIC (class_decl) = 1;
+ DECL_ARTIFICIAL (class_decl) = 1;
+ DECL_IGNORED_P (class_decl) = 1;
+ pushdecl_top_level (class_decl);
+ make_decl_rtl (class_decl);
+ }
+ return class_decl;
+}
+
+static tree
+build_vec_delete_1 (tree base, tree maxindex, tree type,
+ special_function_kind auto_delete_vec,
+ int use_global_delete, tsubst_flags_t complain)
+{
+ tree virtual_size;
+ tree ptype = build_pointer_type (type = complete_type (type));
+ tree size_exp;
+
+ /* Temporary variables used by the loop. */
+ tree tbase, tbase_init;
+
+ /* This is the body of the loop that implements the deletion of a
+ single element, and moves temp variables to next elements. */
+ tree body;
+
+ /* This is the LOOP_EXPR that governs the deletion of the elements. */
+ tree loop = 0;
+
+ /* This is the thing that governs what to do after the loop has run. */
+ tree deallocate_expr = 0;
+
+ /* This is the BIND_EXPR which holds the outermost iterator of the
+ loop. It is convenient to set this variable up and test it before
+ executing any other code in the loop.
+ This is also the containing expression returned by this function. */
+ tree controller = NULL_TREE;
+ tree tmp;
+
+ /* We should only have 1-D arrays here. */
+ gcc_assert (TREE_CODE (type) != ARRAY_TYPE);
+
+ if (base == error_mark_node || maxindex == error_mark_node)
+ return error_mark_node;
+
+ if (!COMPLETE_TYPE_P (type))
+ {
+ if ((complain & tf_warning)
+ && warning (OPT_Wdelete_incomplete,
+ "possible problem detected in invocation of "
+ "delete [] operator:"))
+ {
+ cxx_incomplete_type_diagnostic (base, type, DK_WARNING);
+ inform (input_location, "neither the destructor nor the "
+ "class-specific operator delete [] will be called, "
+ "even if they are declared when the class is defined");
+ }
+ return build_builtin_delete_call (base);
+ }
+
+ size_exp = size_in_bytes (type);
+
+ if (! MAYBE_CLASS_TYPE_P (type))
+ goto no_destructor;
+ else if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+ {
+ /* Make sure the destructor is callable. */
+ if (type_build_dtor_call (type))
+ {
+ tmp = build_delete (ptype, base, sfk_complete_destructor,
+ LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1,
+ complain);
+ if (tmp == error_mark_node)
+ return error_mark_node;
+ }
+ goto no_destructor;
+ }
+
+ /* The below is short by the cookie size. */
+ virtual_size = size_binop (MULT_EXPR, size_exp,
+ convert (sizetype, maxindex));
+
+ tbase = create_temporary_var (ptype);
+ tbase_init
+ = cp_build_modify_expr (tbase, NOP_EXPR,
+ fold_build_pointer_plus_loc (input_location,
+ fold_convert (ptype,
+ base),
+ virtual_size),
+ complain);
+ if (tbase_init == error_mark_node)
+ return error_mark_node;
+ controller = build3 (BIND_EXPR, void_type_node, tbase,
+ NULL_TREE, NULL_TREE);
+ TREE_SIDE_EFFECTS (controller) = 1;
+
+ body = build1 (EXIT_EXPR, void_type_node,
+ build2 (EQ_EXPR, boolean_type_node, tbase,
+ fold_convert (ptype, base)));
+ tmp = fold_build1_loc (input_location, NEGATE_EXPR, sizetype, size_exp);
+ tmp = fold_build_pointer_plus (tbase, tmp);
+ tmp = cp_build_modify_expr (tbase, NOP_EXPR, tmp, complain);
+ if (tmp == error_mark_node)
+ return error_mark_node;
+ body = build_compound_expr (input_location, body, tmp);
+ tmp = build_delete (ptype, tbase, sfk_complete_destructor,
+ LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1,
+ complain);
+ if (tmp == error_mark_node)
+ return error_mark_node;
+ body = build_compound_expr (input_location, body, tmp);
+
+ loop = build1 (LOOP_EXPR, void_type_node, body);
+ loop = build_compound_expr (input_location, tbase_init, loop);
+
+ no_destructor:
+ /* Delete the storage if appropriate. */
+ if (auto_delete_vec == sfk_deleting_destructor)
+ {
+ tree base_tbd;
+
+ /* The below is short by the cookie size. */
+ virtual_size = size_binop (MULT_EXPR, size_exp,
+ convert (sizetype, maxindex));
+
+ if (! TYPE_VEC_NEW_USES_COOKIE (type))
+ /* no header */
+ base_tbd = base;
+ else
+ {
+ tree cookie_size;
+
+ cookie_size = targetm.cxx.get_cookie_size (type);
+ base_tbd = cp_build_binary_op (input_location,
+ MINUS_EXPR,
+ cp_convert (string_type_node,
+ base, complain),
+ cookie_size,
+ complain);
+ if (base_tbd == error_mark_node)
+ return error_mark_node;
+ base_tbd = cp_convert (ptype, base_tbd, complain);
+ /* True size with header. */
+ virtual_size = size_binop (PLUS_EXPR, virtual_size, cookie_size);
+ }
+
+ deallocate_expr = build_op_delete_call (VEC_DELETE_EXPR,
+ base_tbd, virtual_size,
+ use_global_delete & 1,
+ /*placement=*/NULL_TREE,
+ /*alloc_fn=*/NULL_TREE,
+ complain);
+ }
+
+ body = loop;
+ if (!deallocate_expr)
+ ;
+ else if (!body)
+ body = deallocate_expr;
+ else
+ body = build_compound_expr (input_location, body, deallocate_expr);
+
+ if (!body)
+ body = integer_zero_node;
+
+ /* Outermost wrapper: If pointer is null, punt. */
+ body = fold_build3_loc (input_location, COND_EXPR, void_type_node,
+ fold_build2_loc (input_location,
+ NE_EXPR, boolean_type_node, base,
+ convert (TREE_TYPE (base),
+ nullptr_node)),
+ body, integer_zero_node);
+ body = build1 (NOP_EXPR, void_type_node, body);
+
+ if (controller)
+ {
+ TREE_OPERAND (controller, 1) = body;
+ body = controller;
+ }
+
+ if (TREE_CODE (base) == SAVE_EXPR)
+ /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR. */
+ body = build2 (COMPOUND_EXPR, void_type_node, base, body);
+
+ return convert_to_void (body, ICV_CAST, complain);
+}
+
+/* Create an unnamed variable of the indicated TYPE. */
+
+tree
+create_temporary_var (tree type)
+{
+ tree decl;
+
+ decl = build_decl (input_location,
+ VAR_DECL, NULL_TREE, type);
+ TREE_USED (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ DECL_CONTEXT (decl) = current_function_decl;
+
+ return decl;
+}
+
+/* Create a new temporary variable of the indicated TYPE, initialized
+ to INIT.
+
+ It is not entered into current_binding_level, because that breaks
+ things when it comes time to do final cleanups (which take place
+ "outside" the binding contour of the function). */
+
+tree
+get_temp_regvar (tree type, tree init)
+{
+ tree decl;
+
+ decl = create_temporary_var (type);
+ add_decl_expr (decl);
+
+ finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
+ tf_warning_or_error));
+
+ return decl;
+}
+
+/* `build_vec_init' returns tree structure that performs
+ initialization of a vector of aggregate types.
+
+ BASE is a reference to the vector, of ARRAY_TYPE, or a pointer
+ to the first element, of POINTER_TYPE.
+ MAXINDEX is the maximum index of the array (one less than the
+ number of elements). It is only used if BASE is a pointer or
+ TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE.
+
+ INIT is the (possibly NULL) initializer.
+
+ If EXPLICIT_VALUE_INIT_P is true, then INIT must be NULL. All
+ elements in the array are value-initialized.
+
+ FROM_ARRAY is 0 if we should init everything with INIT
+ (i.e., every element initialized from INIT).
+ FROM_ARRAY is 1 if we should index into INIT in parallel
+ with initialization of DECL.
+ FROM_ARRAY is 2 if we should index into INIT in parallel,
+ but use assignment instead of initialization. */
+
+tree
+build_vec_init (tree base, tree maxindex, tree init,
+ bool explicit_value_init_p,
+ int from_array, tsubst_flags_t complain)
+{
+ tree rval;
+ tree base2 = NULL_TREE;
+ tree itype = NULL_TREE;
+ tree iterator;
+ /* The type of BASE. */
+ tree atype = TREE_TYPE (base);
+ /* The type of an element in the array. */
+ tree type = TREE_TYPE (atype);
+ /* The element type reached after removing all outer array
+ types. */
+ tree inner_elt_type;
+ /* The type of a pointer to an element in the array. */
+ tree ptype;
+ tree stmt_expr;
+ tree compound_stmt;
+ int destroy_temps;
+ tree try_block = NULL_TREE;
+ int num_initialized_elts = 0;
+ bool is_global;
+ tree const_init = NULL_TREE;
+ tree obase = base;
+ bool xvalue = false;
+ bool errors = false;
+ tree length_check = NULL_TREE;
+
+ if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype))
+ maxindex = array_type_nelts (atype);
+
+ if (maxindex == NULL_TREE || maxindex == error_mark_node)
+ return error_mark_node;
+
+ if (explicit_value_init_p)
+ gcc_assert (!init);
+
+ inner_elt_type = strip_array_types (type);
+
+ /* Look through the TARGET_EXPR around a compound literal. */
+ if (init && TREE_CODE (init) == TARGET_EXPR
+ && TREE_CODE (TARGET_EXPR_INITIAL (init)) == CONSTRUCTOR
+ && from_array != 2)
+ init = TARGET_EXPR_INITIAL (init);
+
+ /* If we have a braced-init-list, make sure that the array
+ is big enough for all the initializers. */
+ if (init && TREE_CODE (init) == CONSTRUCTOR
+ && CONSTRUCTOR_NELTS (init) > 0
+ && !TREE_CONSTANT (maxindex)
+ && flag_exceptions)
+ length_check = fold_build2 (LT_EXPR, boolean_type_node, maxindex,
+ size_int (CONSTRUCTOR_NELTS (init) - 1));
+
+ if (init
+ && TREE_CODE (atype) == ARRAY_TYPE
+ && TREE_CONSTANT (maxindex)
+ && (from_array == 2
+ ? (!CLASS_TYPE_P (inner_elt_type)
+ || !TYPE_HAS_COMPLEX_COPY_ASSIGN (inner_elt_type))
+ : !TYPE_NEEDS_CONSTRUCTING (type))
+ && ((TREE_CODE (init) == CONSTRUCTOR
+ /* Don't do this if the CONSTRUCTOR might contain something
+ that might throw and require us to clean up. */
+ && (vec_safe_is_empty (CONSTRUCTOR_ELTS (init))
+ || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
+ || from_array))
+ {
+ /* Do non-default initialization of trivial arrays resulting from
+ brace-enclosed initializers. In this case, digest_init and
+ store_constructor will handle the semantics for us. */
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (init))
+ init = digest_init (atype, init, complain);
+ stmt_expr = build2 (INIT_EXPR, atype, base, init);
+ if (length_check)
+ stmt_expr = build3 (COND_EXPR, atype, length_check,
+ throw_bad_array_length (),
+ stmt_expr);
+ return stmt_expr;
+ }
+
+ maxindex = cp_convert (ptrdiff_type_node, maxindex, complain);
+ if (TREE_CODE (atype) == ARRAY_TYPE)
+ {
+ ptype = build_pointer_type (type);
+ base = decay_conversion (base, complain);
+ if (base == error_mark_node)
+ return error_mark_node;
+ base = cp_convert (ptype, base, complain);
+ }
+ else
+ ptype = atype;
+
+ /* The code we are generating looks like:
+ ({
+ T* t1 = (T*) base;
+ T* rval = t1;
+ ptrdiff_t iterator = maxindex;
+ try {
+ for (; iterator != -1; --iterator) {
+ ... initialize *t1 ...
+ ++t1;
+ }
+ } catch (...) {
+ ... destroy elements that were constructed ...
+ }
+ rval;
+ })
+
+ We can omit the try and catch blocks if we know that the
+ initialization will never throw an exception, or if the array
+ elements do not have destructors. We can omit the loop completely if
+ the elements of the array do not have constructors.
+
+ We actually wrap the entire body of the above in a STMT_EXPR, for
+ tidiness.
+
+ When copying from array to another, when the array elements have
+ only trivial copy constructors, we should use __builtin_memcpy
+ rather than generating a loop. That way, we could take advantage
+ of whatever cleverness the back end has for dealing with copies
+ of blocks of memory. */
+
+ is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
+ destroy_temps = stmts_are_full_exprs_p ();
+ current_stmt_tree ()->stmts_are_full_exprs_p = 0;
+ rval = get_temp_regvar (ptype, base);
+ base = get_temp_regvar (ptype, rval);
+ iterator = get_temp_regvar (ptrdiff_type_node, maxindex);
+
+ /* If initializing one array from another, initialize element by
+ element. We rely upon the below calls to do the argument
+ checking. Evaluate the initializer before entering the try block. */
+ if (from_array && init && TREE_CODE (init) != CONSTRUCTOR)
+ {
+ if (lvalue_kind (init) & clk_rvalueref)
+ xvalue = true;
+ base2 = decay_conversion (init, complain);
+ if (base2 == error_mark_node)
+ return error_mark_node;
+ itype = TREE_TYPE (base2);
+ base2 = get_temp_regvar (itype, base2);
+ itype = TREE_TYPE (itype);
+ }
+
+ /* Protect the entire array initialization so that we can destroy
+ the partially constructed array if an exception is thrown.
+ But don't do this if we're assigning. */
+ if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ && from_array != 2)
+ {
+ try_block = begin_try_block ();
+ }
+
+ /* If the initializer is {}, then all elements are initialized from {}.
+ But for non-classes, that's the same as value-initialization. */
+ if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
+ && CONSTRUCTOR_NELTS (init) == 0)
+ {
+ if (CLASS_TYPE_P (type))
+ /* Leave init alone. */;
+ else
+ {
+ init = NULL_TREE;
+ explicit_value_init_p = true;
+ }
+ }
+
+ /* Maybe pull out constant value when from_array? */
+
+ else if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR)
+ {
+ /* Do non-default initialization of non-trivial arrays resulting from
+ brace-enclosed initializers. */
+ unsigned HOST_WIDE_INT idx;
+ tree field, elt;
+ /* Should we try to create a constant initializer? */
+ bool try_const = (TREE_CODE (atype) == ARRAY_TYPE
+ && TREE_CONSTANT (maxindex)
+ && (literal_type_p (inner_elt_type)
+ || TYPE_HAS_CONSTEXPR_CTOR (inner_elt_type)));
+ /* If the constructor already has the array type, it's been through
+ digest_init, so we shouldn't try to do anything more. */
+ bool digested = same_type_p (atype, TREE_TYPE (init));
+ bool saw_non_const = false;
+ bool saw_const = false;
+ /* If we're initializing a static array, we want to do static
+ initialization of any elements with constant initializers even if
+ some are non-constant. */
+ bool do_static_init = (DECL_P (obase) && TREE_STATIC (obase));
+ vec<constructor_elt, va_gc> *new_vec;
+ from_array = 0;
+
+ if (length_check)
+ {
+ tree throw_call;
+ if (array_of_runtime_bound_p (atype))
+ throw_call = throw_bad_array_length ();
+ else
+ throw_call = throw_bad_array_new_length ();
+ length_check = build3 (COND_EXPR, void_type_node, length_check,
+ throw_call, void_zero_node);
+ finish_expr_stmt (length_check);
+ }
+
+ if (try_const)
+ vec_alloc (new_vec, CONSTRUCTOR_NELTS (init));
+ else
+ new_vec = NULL;
+
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, field, elt)
+ {
+ tree baseref = build1 (INDIRECT_REF, type, base);
+ tree one_init;
+
+ num_initialized_elts++;
+
+ current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+ if (digested)
+ one_init = build2 (INIT_EXPR, type, baseref, elt);
+ else if (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
+ one_init = build_aggr_init (baseref, elt, 0, complain);
+ else
+ one_init = cp_build_modify_expr (baseref, NOP_EXPR,
+ elt, complain);
+ if (one_init == error_mark_node)
+ errors = true;
+ if (try_const)
+ {
+ tree e = one_init;
+ if (TREE_CODE (e) == EXPR_STMT)
+ e = TREE_OPERAND (e, 0);
+ if (TREE_CODE (e) == CONVERT_EXPR
+ && VOID_TYPE_P (TREE_TYPE (e)))
+ e = TREE_OPERAND (e, 0);
+ e = maybe_constant_init (e);
+ if (reduced_constant_expression_p (e))
+ {
+ CONSTRUCTOR_APPEND_ELT (new_vec, field, e);
+ if (do_static_init)
+ one_init = NULL_TREE;
+ else
+ one_init = build2 (INIT_EXPR, type, baseref, e);
+ saw_const = true;
+ }
+ else
+ {
+ if (do_static_init)
+ {
+ tree value = build_zero_init (TREE_TYPE (e), NULL_TREE,
+ true);
+ if (value)
+ CONSTRUCTOR_APPEND_ELT (new_vec, field, value);
+ }
+ saw_non_const = true;
+ }
+ }
+
+ if (one_init)
+ finish_expr_stmt (one_init);
+ current_stmt_tree ()->stmts_are_full_exprs_p = 0;
+
+ one_init = cp_build_unary_op (PREINCREMENT_EXPR, base, 0, complain);
+ if (one_init == error_mark_node)
+ errors = true;
+ else
+ finish_expr_stmt (one_init);
+
+ one_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0,
+ complain);
+ if (one_init == error_mark_node)
+ errors = true;
+ else
+ finish_expr_stmt (one_init);
+ }
+
+ if (try_const)
+ {
+ if (!saw_non_const)
+ const_init = build_constructor (atype, new_vec);
+ else if (do_static_init && saw_const)
+ DECL_INITIAL (obase) = build_constructor (atype, new_vec);
+ else
+ vec_free (new_vec);
+ }
+
+ /* Any elements without explicit initializers get {}. */
+ if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
+ init = build_constructor (init_list_type_node, NULL);
+ else
+ {
+ init = NULL_TREE;
+ explicit_value_init_p = true;
+ }
+ }
+ else if (from_array)
+ {
+ if (init)
+ /* OK, we set base2 above. */;
+ else if (CLASS_TYPE_P (type)
+ && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
+ {
+ if (complain & tf_error)
+ error ("initializer ends prematurely");
+ errors = true;
+ }
+ }
+
+ /* Now, default-initialize any remaining elements. We don't need to
+ do that if a) the type does not need constructing, or b) we've
+ already initialized all the elements.
+
+ We do need to keep going if we're copying an array. */
+
+ if (from_array
+ || ((type_build_ctor_call (type) || init || explicit_value_init_p)
+ && ! (tree_fits_shwi_p (maxindex)
+ && (num_initialized_elts
+ == tree_to_shwi (maxindex) + 1))))
+ {
+ /* If the ITERATOR is equal to -1, then we don't have to loop;
+ we've already initialized all the elements. */
+ tree for_stmt;
+ tree elt_init;
+ tree to;
+
+ for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
+ finish_for_init_stmt (for_stmt);
+ finish_for_cond (build2 (NE_EXPR, boolean_type_node, iterator,
+ build_int_cst (TREE_TYPE (iterator), -1)),
+ for_stmt, false);
+ elt_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0,
+ complain);
+ if (elt_init == error_mark_node)
+ errors = true;
+ finish_for_expr (elt_init, for_stmt);
+
+ to = build1 (INDIRECT_REF, type, base);
+
+ if (from_array)
+ {
+ tree from;
+
+ if (base2)
+ {
+ from = build1 (INDIRECT_REF, itype, base2);
+ if (xvalue)
+ from = move (from);
+ }
+ else
+ from = NULL_TREE;
+
+ if (from_array == 2)
+ elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
+ complain);
+ else if (type_build_ctor_call (type))
+ elt_init = build_aggr_init (to, from, 0, complain);
+ else if (from)
+ elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
+ complain);
+ else
+ gcc_unreachable ();
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (init && !BRACE_ENCLOSED_INITIALIZER_P (init))
+ sorry
+ ("cannot initialize multi-dimensional array with initializer");
+ elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
+ 0, init,
+ explicit_value_init_p,
+ 0, complain);
+ }
+ else if (explicit_value_init_p)
+ {
+ elt_init = build_value_init (type, complain);
+ if (elt_init != error_mark_node)
+ elt_init = build2 (INIT_EXPR, type, to, elt_init);
+ }
+ else
+ {
+ gcc_assert (type_build_ctor_call (type) || init);
+ if (CLASS_TYPE_P (type))
+ elt_init = build_aggr_init (to, init, 0, complain);
+ else
+ {
+ if (TREE_CODE (init) == TREE_LIST)
+ init = build_x_compound_expr_from_list (init, ELK_INIT,
+ complain);
+ elt_init = build2 (INIT_EXPR, type, to, init);
+ }
+ }
+
+ if (elt_init == error_mark_node)
+ errors = true;
+
+ current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+ finish_expr_stmt (elt_init);
+ current_stmt_tree ()->stmts_are_full_exprs_p = 0;
+
+ finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base, 0,
+ complain));
+ if (base2)
+ finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base2, 0,
+ complain));
+
+ finish_for_stmt (for_stmt);
+ }
+
+ /* Make sure to cleanup any partially constructed elements. */
+ if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ && from_array != 2)
+ {
+ tree e;
+ tree m = cp_build_binary_op (input_location,
+ MINUS_EXPR, maxindex, iterator,
+ complain);
+
+ /* Flatten multi-dimensional array since build_vec_delete only
+ expects one-dimensional array. */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ m = cp_build_binary_op (input_location,
+ MULT_EXPR, m,
+ /* Avoid mixing signed and unsigned. */
+ convert (TREE_TYPE (m),
+ array_type_nelts_total (type)),
+ complain);
+
+ finish_cleanup_try_block (try_block);
+ e = build_vec_delete_1 (rval, m,
+ inner_elt_type, sfk_complete_destructor,
+ /*use_global_delete=*/0, complain);
+ if (e == error_mark_node)
+ errors = true;
+ finish_cleanup (e, try_block);
+ }
+
+ /* The value of the array initialization is the array itself, RVAL
+ is a pointer to the first element. */
+ finish_stmt_expr_expr (rval, stmt_expr);
+
+ stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
+
+ /* Now make the result have the correct type. */
+ if (TREE_CODE (atype) == ARRAY_TYPE)
+ {
+ atype = build_pointer_type (atype);
+ stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
+ stmt_expr = cp_build_indirect_ref (stmt_expr, RO_NULL, complain);
+ TREE_NO_WARNING (stmt_expr) = 1;
+ }
+
+ current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
+
+ if (const_init)
+ return build2 (INIT_EXPR, atype, obase, const_init);
+ if (errors)
+ return error_mark_node;
+ return stmt_expr;
+}
+
+/* Call the DTOR_KIND destructor for EXP. FLAGS are as for
+ build_delete. */
+
+static tree
+build_dtor_call (tree exp, special_function_kind dtor_kind, int flags,
+ tsubst_flags_t complain)
+{
+ tree name;
+ tree fn;
+ switch (dtor_kind)
+ {
+ case sfk_complete_destructor:
+ name = complete_dtor_identifier;
+ break;
+
+ case sfk_base_destructor:
+ name = base_dtor_identifier;
+ break;
+
+ case sfk_deleting_destructor:
+ name = deleting_dtor_identifier;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ fn = lookup_fnfields (TREE_TYPE (exp), name, /*protect=*/2);
+ return build_new_method_call (exp, fn,
+ /*args=*/NULL,
+ /*conversion_path=*/NULL_TREE,
+ flags,
+ /*fn_p=*/NULL,
+ complain);
+}
+
+/* Generate a call to a destructor. TYPE is the type to cast ADDR to.
+ ADDR is an expression which yields the store to be destroyed.
+ AUTO_DELETE is the name of the destructor to call, i.e., either
+ sfk_complete_destructor, sfk_base_destructor, or
+ sfk_deleting_destructor.
+
+ FLAGS is the logical disjunction of zero or more LOOKUP_
+ flags. See cp-tree.h for more info. */
+
+tree
+build_delete (tree otype, tree addr, special_function_kind auto_delete,
+ int flags, int use_global_delete, tsubst_flags_t complain)
+{
+ tree expr;
+
+ if (addr == error_mark_node)
+ return error_mark_node;
+
+ tree type = TYPE_MAIN_VARIANT (otype);
+
+ /* Can happen when CURRENT_EXCEPTION_OBJECT gets its type
+ set to `error_mark_node' before it gets properly cleaned up. */
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ if (TREE_CODE (type) == POINTER_TYPE)
+ type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (TYPE_DOMAIN (type) == NULL_TREE)
+ {
+ if (complain & tf_error)
+ error ("unknown array size in delete");
+ return error_mark_node;
+ }
+ return build_vec_delete (addr, array_type_nelts (type),
+ auto_delete, use_global_delete, complain);
+ }
+
+ if (TYPE_PTR_P (otype))
+ {
+ bool complete_p = true;
+
+ addr = mark_rvalue_use (addr);
+
+ /* We don't want to warn about delete of void*, only other
+ incomplete types. Deleting other incomplete types
+ invokes undefined behavior, but it is not ill-formed, so
+ compile to something that would even do The Right Thing
+ (TM) should the type have a trivial dtor and no delete
+ operator. */
+ if (!VOID_TYPE_P (type))
+ {
+ complete_type (type);
+ if (!COMPLETE_TYPE_P (type))
+ {
+ if ((complain & tf_warning)
+ && warning (OPT_Wdelete_incomplete,
+ "possible problem detected in invocation of "
+ "delete operator:"))
+ {
+ cxx_incomplete_type_diagnostic (addr, type, DK_WARNING);
+ inform (input_location,
+ "neither the destructor nor the class-specific "
+ "operator delete will be called, even if they are "
+ "declared when the class is defined");
+ }
+ complete_p = false;
+ }
+ else if (auto_delete == sfk_deleting_destructor && warn_delnonvdtor
+ && MAYBE_CLASS_TYPE_P (type) && !CLASSTYPE_FINAL (type)
+ && TYPE_POLYMORPHIC_P (type))
+ {
+ tree dtor;
+ dtor = CLASSTYPE_DESTRUCTORS (type);
+ if (!dtor || !DECL_VINDEX (dtor))
+ {
+ if (CLASSTYPE_PURE_VIRTUALS (type))
+ warning (OPT_Wdelete_non_virtual_dtor,
+ "deleting object of abstract class type %qT"
+ " which has non-virtual destructor"
+ " will cause undefined behaviour", type);
+ else
+ warning (OPT_Wdelete_non_virtual_dtor,
+ "deleting object of polymorphic class type %qT"
+ " which has non-virtual destructor"
+ " might cause undefined behaviour", type);
+ }
+ }
+ }
+ if (VOID_TYPE_P (type) || !complete_p || !MAYBE_CLASS_TYPE_P (type))
+ /* Call the builtin operator delete. */
+ return build_builtin_delete_call (addr);
+ if (TREE_SIDE_EFFECTS (addr))
+ addr = save_expr (addr);
+
+ /* Throw away const and volatile on target type of addr. */
+ addr = convert_force (build_pointer_type (type), addr, 0, complain);
+ }
+ else
+ {
+ /* Don't check PROTECT here; leave that decision to the
+ destructor. If the destructor is accessible, call it,
+ else report error. */
+ addr = cp_build_addr_expr (addr, complain);
+ if (addr == error_mark_node)
+ return error_mark_node;
+ if (TREE_SIDE_EFFECTS (addr))
+ addr = save_expr (addr);
+
+ addr = convert_force (build_pointer_type (type), addr, 0, complain);
+ }
+
+ if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+ {
+ /* Make sure the destructor is callable. */
+ if (type_build_dtor_call (type))
+ {
+ expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL,
+ complain),
+ sfk_complete_destructor, flags, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+ }
+
+ if (auto_delete != sfk_deleting_destructor)
+ return void_zero_node;
+
+ return build_op_delete_call (DELETE_EXPR, addr,
+ cxx_sizeof_nowarn (type),
+ use_global_delete,
+ /*placement=*/NULL_TREE,
+ /*alloc_fn=*/NULL_TREE,
+ complain);
+ }
+ else
+ {
+ tree head = NULL_TREE;
+ tree do_delete = NULL_TREE;
+ tree ifexp;
+
+ if (CLASSTYPE_LAZY_DESTRUCTOR (type))
+ lazily_declare_fn (sfk_destructor, type);
+
+ /* For `::delete x', we must not use the deleting destructor
+ since then we would not be sure to get the global `operator
+ delete'. */
+ if (use_global_delete && auto_delete == sfk_deleting_destructor)
+ {
+ /* We will use ADDR multiple times so we must save it. */
+ addr = save_expr (addr);
+ head = get_target_expr (build_headof (addr));
+ /* Delete the object. */
+ do_delete = build_builtin_delete_call (head);
+ /* Otherwise, treat this like a complete object destructor
+ call. */
+ auto_delete = sfk_complete_destructor;
+ }
+ /* If the destructor is non-virtual, there is no deleting
+ variant. Instead, we must explicitly call the appropriate
+ `operator delete' here. */
+ else if (!DECL_VIRTUAL_P (CLASSTYPE_DESTRUCTORS (type))
+ && auto_delete == sfk_deleting_destructor)
+ {
+ /* We will use ADDR multiple times so we must save it. */
+ addr = save_expr (addr);
+ /* Build the call. */
+ do_delete = build_op_delete_call (DELETE_EXPR,
+ addr,
+ cxx_sizeof_nowarn (type),
+ /*global_p=*/false,
+ /*placement=*/NULL_TREE,
+ /*alloc_fn=*/NULL_TREE,
+ complain);
+ /* Call the complete object destructor. */
+ auto_delete = sfk_complete_destructor;
+ }
+ else if (auto_delete == sfk_deleting_destructor
+ && TYPE_GETS_REG_DELETE (type))
+ {
+ /* Make sure we have access to the member op delete, even though
+ we'll actually be calling it from the destructor. */
+ build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type),
+ /*global_p=*/false,
+ /*placement=*/NULL_TREE,
+ /*alloc_fn=*/NULL_TREE,
+ complain);
+ }
+
+ expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL, complain),
+ auto_delete, flags, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+ if (do_delete)
+ expr = build2 (COMPOUND_EXPR, void_type_node, expr, do_delete);
+
+ /* We need to calculate this before the dtor changes the vptr. */
+ if (head)
+ expr = build2 (COMPOUND_EXPR, void_type_node, head, expr);
+
+ if (flags & LOOKUP_DESTRUCTOR)
+ /* Explicit destructor call; don't check for null pointer. */
+ ifexp = integer_one_node;
+ else
+ {
+ /* Handle deleting a null pointer. */
+ ifexp = fold (cp_build_binary_op (input_location,
+ NE_EXPR, addr, nullptr_node,
+ complain));
+ if (ifexp == error_mark_node)
+ return error_mark_node;
+ }
+
+ if (ifexp != integer_one_node)
+ expr = build3 (COND_EXPR, void_type_node,
+ ifexp, expr, void_zero_node);
+
+ return expr;
+ }
+}
+
+/* At the beginning of a destructor, push cleanups that will call the
+ destructors for our base classes and members.
+
+ Called from begin_destructor_body. */
+
+void
+push_base_cleanups (void)
+{
+ tree binfo, base_binfo;
+ int i;
+ tree member;
+ tree expr;
+ vec<tree, va_gc> *vbases;
+
+ /* Run destructors for all virtual baseclasses. */
+ if (CLASSTYPE_VBASECLASSES (current_class_type))
+ {
+ tree cond = (condition_conversion
+ (build2 (BIT_AND_EXPR, integer_type_node,
+ current_in_charge_parm,
+ integer_two_node)));
+
+ /* The CLASSTYPE_VBASECLASSES vector is in initialization
+ order, which is also the right order for pushing cleanups. */
+ for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
+ vec_safe_iterate (vbases, i, &base_binfo); i++)
+ {
+ if (type_build_dtor_call (BINFO_TYPE (base_binfo)))
+ {
+ expr = build_special_member_call (current_class_ref,
+ base_dtor_identifier,
+ NULL,
+ base_binfo,
+ (LOOKUP_NORMAL
+ | LOOKUP_NONVIRTUAL),
+ tf_warning_or_error);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
+ {
+ expr = build3 (COND_EXPR, void_type_node, cond,
+ expr, void_zero_node);
+ finish_decl_cleanup (NULL_TREE, expr);
+ }
+ }
+ }
+ }
+
+ /* Take care of the remaining baseclasses. */
+ for (binfo = TYPE_BINFO (current_class_type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ {
+ if (BINFO_VIRTUAL_P (base_binfo)
+ || !type_build_dtor_call (BINFO_TYPE (base_binfo)))
+ continue;
+
+ expr = build_special_member_call (current_class_ref,
+ base_dtor_identifier,
+ NULL, base_binfo,
+ LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
+ tf_warning_or_error);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
+ finish_decl_cleanup (NULL_TREE, expr);
+ }
+
+ /* Don't automatically destroy union members. */
+ if (TREE_CODE (current_class_type) == UNION_TYPE)
+ return;
+
+ for (member = TYPE_FIELDS (current_class_type); member;
+ member = DECL_CHAIN (member))
+ {
+ tree this_type = TREE_TYPE (member);
+ if (this_type == error_mark_node
+ || TREE_CODE (member) != FIELD_DECL
+ || DECL_ARTIFICIAL (member))
+ continue;
+ if (ANON_AGGR_TYPE_P (this_type))
+ continue;
+ if (type_build_dtor_call (this_type))
+ {
+ tree this_member = (build_class_member_access_expr
+ (current_class_ref, member,
+ /*access_path=*/NULL_TREE,
+ /*preserve_reference=*/false,
+ tf_warning_or_error));
+ expr = build_delete (this_type, this_member,
+ sfk_complete_destructor,
+ LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL,
+ 0, tf_warning_or_error);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (this_type))
+ finish_decl_cleanup (NULL_TREE, expr);
+ }
+ }
+}
+
+/* Build a C++ vector delete expression.
+ MAXINDEX is the number of elements to be deleted.
+ ELT_SIZE is the nominal size of each element in the vector.
+ BASE is the expression that should yield the store to be deleted.
+ This function expands (or synthesizes) these calls itself.
+ AUTO_DELETE_VEC says whether the container (vector) should be deallocated.
+
+ This also calls delete for virtual baseclasses of elements of the vector.
+
+ Update: MAXINDEX is no longer needed. The size can be extracted from the
+ start of the vector for pointers, and from the type for arrays. We still
+ use MAXINDEX for arrays because it happens to already have one of the
+ values we'd have to extract. (We could use MAXINDEX with pointers to
+ confirm the size, and trap if the numbers differ; not clear that it'd
+ be worth bothering.) */
+
+tree
+build_vec_delete (tree base, tree maxindex,
+ special_function_kind auto_delete_vec,
+ int use_global_delete, tsubst_flags_t complain)
+{
+ tree type;
+ tree rval;
+ tree base_init = NULL_TREE;
+
+ type = TREE_TYPE (base);
+
+ if (TYPE_PTR_P (type))
+ {
+ /* Step back one from start of vector, and read dimension. */
+ tree cookie_addr;
+ tree size_ptr_type = build_pointer_type (sizetype);
+
+ base = mark_rvalue_use (base);
+ if (TREE_SIDE_EFFECTS (base))
+ {
+ base_init = get_target_expr (base);
+ base = TARGET_EXPR_SLOT (base_init);
+ }
+ type = strip_array_types (TREE_TYPE (type));
+ cookie_addr = fold_build1_loc (input_location, NEGATE_EXPR,
+ sizetype, TYPE_SIZE_UNIT (sizetype));
+ cookie_addr = fold_build_pointer_plus (fold_convert (size_ptr_type, base),
+ cookie_addr);
+ maxindex = cp_build_indirect_ref (cookie_addr, RO_NULL, complain);
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ /* Get the total number of things in the array, maxindex is a
+ bad name. */
+ maxindex = array_type_nelts_total (type);
+ type = strip_array_types (type);
+ base = decay_conversion (base, complain);
+ if (base == error_mark_node)
+ return error_mark_node;
+ if (TREE_SIDE_EFFECTS (base))
+ {
+ base_init = get_target_expr (base);
+ base = TARGET_EXPR_SLOT (base_init);
+ }
+ }
+ else
+ {
+ if (base != error_mark_node && !(complain & tf_error))
+ error ("type to vector delete is neither pointer or array type");
+ return error_mark_node;
+ }
+
+ rval = build_vec_delete_1 (base, maxindex, type, auto_delete_vec,
+ use_global_delete, complain);
+ if (base_init && rval != error_mark_node)
+ rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), base_init, rval);
+
+ return rval;
+}
diff --git a/gcc-4.9/gcc/cp/lambda.c b/gcc-4.9/gcc/cp/lambda.c
new file mode 100644
index 000000000..0b8b46a81
--- /dev/null
+++ b/gcc-4.9/gcc/cp/lambda.c
@@ -0,0 +1,1095 @@
+/* Perform the semantic phase of lambda parsing, i.e., the process of
+ building tree structure, checking semantic consistency, and
+ building RTL. These routines are used both during actual parsing
+ and during the instantiation of template functions.
+
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "cgraph.h"
+#include "tree-iterator.h"
+#include "cp-tree.h"
+#include "toplev.h"
+#include "vec.h"
+
+/* Constructor for a lambda expression. */
+
+tree
+build_lambda_expr (void)
+{
+ tree lambda = make_node (LAMBDA_EXPR);
+ LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) = CPLD_NONE;
+ LAMBDA_EXPR_CAPTURE_LIST (lambda) = NULL_TREE;
+ LAMBDA_EXPR_THIS_CAPTURE (lambda) = NULL_TREE;
+ LAMBDA_EXPR_PENDING_PROXIES (lambda) = NULL;
+ LAMBDA_EXPR_RETURN_TYPE (lambda) = NULL_TREE;
+ LAMBDA_EXPR_MUTABLE_P (lambda) = false;
+ return lambda;
+}
+
+/* Create the closure object for a LAMBDA_EXPR. */
+
+tree
+build_lambda_object (tree lambda_expr)
+{
+ /* Build aggregate constructor call.
+ - cp_parser_braced_list
+ - cp_parser_functional_cast */
+ vec<constructor_elt, va_gc> *elts = NULL;
+ tree node, expr, type;
+ location_t saved_loc;
+
+ if (processing_template_decl)
+ return lambda_expr;
+
+ /* Make sure any error messages refer to the lambda-introducer. */
+ saved_loc = input_location;
+ input_location = LAMBDA_EXPR_LOCATION (lambda_expr);
+
+ for (node = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr);
+ node;
+ node = TREE_CHAIN (node))
+ {
+ tree field = TREE_PURPOSE (node);
+ tree val = TREE_VALUE (node);
+
+ if (field == error_mark_node)
+ {
+ expr = error_mark_node;
+ goto out;
+ }
+
+ if (DECL_P (val))
+ mark_used (val);
+
+ /* Mere mortals can't copy arrays with aggregate initialization, so
+ do some magic to make it work here. */
+ if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
+ val = build_array_copy (val);
+ else if (DECL_NORMAL_CAPTURE_P (field)
+ && !DECL_VLA_CAPTURE_P (field)
+ && TREE_CODE (TREE_TYPE (field)) != REFERENCE_TYPE)
+ {
+ /* "the entities that are captured by copy are used to
+ direct-initialize each corresponding non-static data
+ member of the resulting closure object."
+
+ There's normally no way to express direct-initialization
+ from an element of a CONSTRUCTOR, so we build up a special
+ TARGET_EXPR to bypass the usual copy-initialization. */
+ val = force_rvalue (val, tf_warning_or_error);
+ if (TREE_CODE (val) == TARGET_EXPR)
+ TARGET_EXPR_DIRECT_INIT_P (val) = true;
+ }
+
+ CONSTRUCTOR_APPEND_ELT (elts, DECL_NAME (field), val);
+ }
+
+ expr = build_constructor (init_list_type_node, elts);
+ CONSTRUCTOR_IS_DIRECT_INIT (expr) = 1;
+
+ /* N2927: "[The closure] class type is not an aggregate."
+ But we briefly treat it as an aggregate to make this simpler. */
+ type = LAMBDA_EXPR_CLOSURE (lambda_expr);
+ CLASSTYPE_NON_AGGREGATE (type) = 0;
+ expr = finish_compound_literal (type, expr, tf_warning_or_error);
+ CLASSTYPE_NON_AGGREGATE (type) = 1;
+
+ out:
+ input_location = saved_loc;
+ return expr;
+}
+
+/* Return an initialized RECORD_TYPE for LAMBDA.
+ LAMBDA must have its explicit captures already. */
+
+tree
+begin_lambda_type (tree lambda)
+{
+ tree type;
+
+ {
+ /* Unique name. This is just like an unnamed class, but we cannot use
+ make_anon_name because of certain checks against TYPE_ANONYMOUS_P. */
+ tree name;
+ name = make_lambda_name ();
+
+ /* Create the new RECORD_TYPE for this lambda. */
+ type = xref_tag (/*tag_code=*/record_type,
+ name,
+ /*scope=*/ts_lambda,
+ /*template_header_p=*/false);
+ if (type == error_mark_node)
+ return error_mark_node;
+ }
+
+ /* Designate it as a struct so that we can use aggregate initialization. */
+ CLASSTYPE_DECLARED_CLASS (type) = false;
+
+ /* Cross-reference the expression and the type. */
+ LAMBDA_EXPR_CLOSURE (lambda) = type;
+ CLASSTYPE_LAMBDA_EXPR (type) = lambda;
+
+ /* Clear base types. */
+ xref_basetypes (type, /*bases=*/NULL_TREE);
+
+ /* Start the class. */
+ type = begin_class_definition (type);
+
+ return type;
+}
+
+/* Returns the type to use for the return type of the operator() of a
+ closure class. */
+
+tree
+lambda_return_type (tree expr)
+{
+ if (expr == NULL_TREE)
+ return void_type_node;
+ if (type_unknown_p (expr)
+ || BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ cxx_incomplete_type_error (expr, TREE_TYPE (expr));
+ return void_type_node;
+ }
+ gcc_checking_assert (!type_dependent_expression_p (expr));
+ return cv_unqualified (type_decays_to (unlowered_expr_type (expr)));
+}
+
+/* Given a LAMBDA_EXPR or closure type LAMBDA, return the op() of the
+ closure type. */
+
+tree
+lambda_function (tree lambda)
+{
+ tree type;
+ if (TREE_CODE (lambda) == LAMBDA_EXPR)
+ type = LAMBDA_EXPR_CLOSURE (lambda);
+ else
+ type = lambda;
+ gcc_assert (LAMBDA_TYPE_P (type));
+ /* Don't let debug_tree cause instantiation. */
+ if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)
+ && !COMPLETE_OR_OPEN_TYPE_P (type))
+ return NULL_TREE;
+ lambda = lookup_member (type, ansi_opname (CALL_EXPR),
+ /*protect=*/0, /*want_type=*/false,
+ tf_warning_or_error);
+ if (lambda)
+ lambda = STRIP_TEMPLATE (get_first_fn (lambda));
+ return lambda;
+}
+
+/* Returns the type to use for the FIELD_DECL corresponding to the
+ capture of EXPR.
+ The caller should add REFERENCE_TYPE for capture by reference. */
+
+tree
+lambda_capture_field_type (tree expr, bool explicit_init_p)
+{
+ tree type;
+ if (explicit_init_p)
+ {
+ type = make_auto ();
+ type = do_auto_deduction (type, expr, type);
+ }
+ else
+ type = non_reference (unlowered_expr_type (expr));
+ if (!type || WILDCARD_TYPE_P (type) || type_uses_auto (type)
+ || DECL_PACK_P (expr))
+ {
+ type = cxx_make_type (DECLTYPE_TYPE);
+ DECLTYPE_TYPE_EXPR (type) = expr;
+ DECLTYPE_FOR_LAMBDA_CAPTURE (type) = true;
+ DECLTYPE_FOR_INIT_CAPTURE (type) = explicit_init_p;
+ SET_TYPE_STRUCTURAL_EQUALITY (type);
+ }
+ return type;
+}
+
+/* Returns true iff DECL is a lambda capture proxy variable created by
+ build_capture_proxy. */
+
+bool
+is_capture_proxy (tree decl)
+{
+ return (VAR_P (decl)
+ && DECL_HAS_VALUE_EXPR_P (decl)
+ && !DECL_ANON_UNION_VAR_P (decl)
+ && LAMBDA_FUNCTION_P (DECL_CONTEXT (decl)));
+}
+
+/* Returns true iff DECL is a capture proxy for a normal capture
+ (i.e. without explicit initializer). */
+
+bool
+is_normal_capture_proxy (tree decl)
+{
+ if (!is_capture_proxy (decl))
+ /* It's not a capture proxy. */
+ return false;
+
+ if (variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
+ /* VLA capture. */
+ return true;
+
+ /* It is a capture proxy, is it a normal capture? */
+ tree val = DECL_VALUE_EXPR (decl);
+ if (val == error_mark_node)
+ return true;
+
+ gcc_assert (TREE_CODE (val) == COMPONENT_REF);
+ val = TREE_OPERAND (val, 1);
+ return DECL_NORMAL_CAPTURE_P (val);
+}
+
+/* VAR is a capture proxy created by build_capture_proxy; add it to the
+ current function, which is the operator() for the appropriate lambda. */
+
+void
+insert_capture_proxy (tree var)
+{
+ cp_binding_level *b;
+ tree stmt_list;
+
+ /* Put the capture proxy in the extra body block so that it won't clash
+ with a later local variable. */
+ b = current_binding_level;
+ for (;;)
+ {
+ cp_binding_level *n = b->level_chain;
+ if (n->kind == sk_function_parms)
+ break;
+ b = n;
+ }
+ pushdecl_with_scope (var, b, false);
+
+ /* And put a DECL_EXPR in the STATEMENT_LIST for the same block. */
+ var = build_stmt (DECL_SOURCE_LOCATION (var), DECL_EXPR, var);
+ stmt_list = (*stmt_list_stack)[1];
+ gcc_assert (stmt_list);
+ append_to_statement_list_force (var, &stmt_list);
+}
+
+/* We've just finished processing a lambda; if the containing scope is also
+ a lambda, insert any capture proxies that were created while processing
+ the nested lambda. */
+
+void
+insert_pending_capture_proxies (void)
+{
+ tree lam;
+ vec<tree, va_gc> *proxies;
+ unsigned i;
+
+ if (!current_function_decl || !LAMBDA_FUNCTION_P (current_function_decl))
+ return;
+
+ lam = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (current_function_decl));
+ proxies = LAMBDA_EXPR_PENDING_PROXIES (lam);
+ for (i = 0; i < vec_safe_length (proxies); ++i)
+ {
+ tree var = (*proxies)[i];
+ insert_capture_proxy (var);
+ }
+ release_tree_vector (LAMBDA_EXPR_PENDING_PROXIES (lam));
+ LAMBDA_EXPR_PENDING_PROXIES (lam) = NULL;
+}
+
+/* Given REF, a COMPONENT_REF designating a field in the lambda closure,
+ return the type we want the proxy to have: the type of the field itself,
+ with added const-qualification if the lambda isn't mutable and the
+ capture is by value. */
+
+tree
+lambda_proxy_type (tree ref)
+{
+ tree type;
+ if (ref == error_mark_node)
+ return error_mark_node;
+ if (REFERENCE_REF_P (ref))
+ ref = TREE_OPERAND (ref, 0);
+ gcc_assert (TREE_CODE (ref) == COMPONENT_REF);
+ type = TREE_TYPE (ref);
+ if (!type || WILDCARD_TYPE_P (non_reference (type)))
+ {
+ type = cxx_make_type (DECLTYPE_TYPE);
+ DECLTYPE_TYPE_EXPR (type) = ref;
+ DECLTYPE_FOR_LAMBDA_PROXY (type) = true;
+ SET_TYPE_STRUCTURAL_EQUALITY (type);
+ }
+ if (DECL_PACK_P (TREE_OPERAND (ref, 1)))
+ type = make_pack_expansion (type);
+ return type;
+}
+
+/* MEMBER is a capture field in a lambda closure class. Now that we're
+ inside the operator(), build a placeholder var for future lookups and
+ debugging. */
+
+tree
+build_capture_proxy (tree member)
+{
+ tree var, object, fn, closure, name, lam, type;
+
+ if (PACK_EXPANSION_P (member))
+ member = PACK_EXPANSION_PATTERN (member);
+
+ closure = DECL_CONTEXT (member);
+ fn = lambda_function (closure);
+ lam = CLASSTYPE_LAMBDA_EXPR (closure);
+
+ /* The proxy variable forwards to the capture field. */
+ object = build_fold_indirect_ref (DECL_ARGUMENTS (fn));
+ object = finish_non_static_data_member (member, object, NULL_TREE);
+ if (REFERENCE_REF_P (object))
+ object = TREE_OPERAND (object, 0);
+
+ /* Remove the __ inserted by add_capture. */
+ if (DECL_NORMAL_CAPTURE_P (member))
+ name = get_identifier (IDENTIFIER_POINTER (DECL_NAME (member)) + 2);
+ else
+ name = DECL_NAME (member);
+
+ type = lambda_proxy_type (object);
+
+ if (DECL_VLA_CAPTURE_P (member))
+ {
+ /* Rebuild the VLA type from the pointer and maxindex. */
+ tree field = next_initializable_field (TYPE_FIELDS (type));
+ tree ptr = build_simple_component_ref (object, field);
+ field = next_initializable_field (DECL_CHAIN (field));
+ tree max = build_simple_component_ref (object, field);
+ type = build_cplus_array_type (TREE_TYPE (TREE_TYPE (ptr)),
+ build_index_type (max));
+ type = build_reference_type (type);
+ REFERENCE_VLA_OK (type) = true;
+ object = convert (type, ptr);
+ }
+
+ var = build_decl (input_location, VAR_DECL, name, type);
+ SET_DECL_VALUE_EXPR (var, object);
+ DECL_HAS_VALUE_EXPR_P (var) = 1;
+ DECL_ARTIFICIAL (var) = 1;
+ TREE_USED (var) = 1;
+ DECL_CONTEXT (var) = fn;
+
+ if (name == this_identifier)
+ {
+ gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (lam) == member);
+ LAMBDA_EXPR_THIS_CAPTURE (lam) = var;
+ }
+
+ if (fn == current_function_decl)
+ insert_capture_proxy (var);
+ else
+ vec_safe_push (LAMBDA_EXPR_PENDING_PROXIES (lam), var);
+
+ return var;
+}
+
+/* Return a struct containing a pointer and a length for lambda capture of
+ an array of runtime length. */
+
+static tree
+vla_capture_type (tree array_type)
+{
+ static tree ptr_id, max_id;
+ tree type = xref_tag (record_type, make_anon_name (), ts_current, false);
+ xref_basetypes (type, NULL_TREE);
+ type = begin_class_definition (type);
+ if (!ptr_id)
+ {
+ ptr_id = get_identifier ("ptr");
+ max_id = get_identifier ("max");
+ }
+ tree ptrtype = build_pointer_type (TREE_TYPE (array_type));
+ tree field = build_decl (input_location, FIELD_DECL, ptr_id, ptrtype);
+ finish_member_declaration (field);
+ field = build_decl (input_location, FIELD_DECL, max_id, sizetype);
+ finish_member_declaration (field);
+ return finish_struct (type, NULL_TREE);
+}
+
+/* From an ID and INITIALIZER, create a capture (by reference if
+ BY_REFERENCE_P is true), add it to the capture-list for LAMBDA,
+ and return it. */
+
+tree
+add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
+ bool explicit_init_p)
+{
+ char *buf;
+ tree type, member, name;
+ bool vla = false;
+ bool variadic = false;
+ tree initializer = orig_init;
+
+ if (PACK_EXPANSION_P (initializer))
+ {
+ initializer = PACK_EXPANSION_PATTERN (initializer);
+ variadic = true;
+ }
+
+ if (TREE_CODE (initializer) == TREE_LIST)
+ initializer = build_x_compound_expr_from_list (initializer, ELK_INIT,
+ tf_warning_or_error);
+ type = lambda_capture_field_type (initializer, explicit_init_p);
+ if (array_of_runtime_bound_p (type))
+ {
+ vla = true;
+ if (!by_reference_p)
+ error ("array of runtime bound cannot be captured by copy, "
+ "only by reference");
+
+ /* For a VLA, we capture the address of the first element and the
+ maximum index, and then reconstruct the VLA for the proxy. */
+ tree elt = cp_build_array_ref (input_location, initializer,
+ integer_zero_node, tf_warning_or_error);
+ initializer = build_constructor_va (init_list_type_node, 2,
+ NULL_TREE, build_address (elt),
+ NULL_TREE, array_type_nelts (type));
+ type = vla_capture_type (type);
+ }
+ else if (variably_modified_type_p (type, NULL_TREE))
+ {
+ error ("capture of variable-size type %qT that is not a C++1y array "
+ "of runtime bound", type);
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && variably_modified_type_p (TREE_TYPE (type), NULL_TREE))
+ inform (input_location, "because the array element type %qT has "
+ "variable size", TREE_TYPE (type));
+ type = error_mark_node;
+ }
+ else if (by_reference_p)
+ {
+ type = build_reference_type (type);
+ if (!real_lvalue_p (initializer))
+ error ("cannot capture %qE by reference", initializer);
+ }
+ else
+ /* Capture by copy requires a complete type. */
+ type = complete_type (type);
+
+ /* Add __ to the beginning of the field name so that user code
+ won't find the field with name lookup. We can't just leave the name
+ unset because template instantiation uses the name to find
+ instantiated fields. */
+ if (!explicit_init_p)
+ {
+ buf = (char *) alloca (IDENTIFIER_LENGTH (id) + 3);
+ buf[1] = buf[0] = '_';
+ memcpy (buf + 2, IDENTIFIER_POINTER (id),
+ IDENTIFIER_LENGTH (id) + 1);
+ name = get_identifier (buf);
+ }
+ else
+ /* But captures with explicit initializers are named. */
+ name = id;
+
+ /* If TREE_TYPE isn't set, we're still in the introducer, so check
+ for duplicates. */
+ if (!LAMBDA_EXPR_CLOSURE (lambda))
+ {
+ if (IDENTIFIER_MARKED (name))
+ {
+ pedwarn (input_location, 0,
+ "already captured %qD in lambda expression", id);
+ return NULL_TREE;
+ }
+ IDENTIFIER_MARKED (name) = true;
+ }
+
+ if (variadic)
+ type = make_pack_expansion (type);
+
+ /* Make member variable. */
+ member = build_decl (input_location, FIELD_DECL, name, type);
+ DECL_VLA_CAPTURE_P (member) = vla;
+
+ if (!explicit_init_p)
+ /* Normal captures are invisible to name lookup but uses are replaced
+ with references to the capture field; we implement this by only
+ really making them invisible in unevaluated context; see
+ qualify_lookup. For now, let's make explicitly initialized captures
+ always visible. */
+ DECL_NORMAL_CAPTURE_P (member) = true;
+
+ if (id == this_identifier)
+ LAMBDA_EXPR_THIS_CAPTURE (lambda) = member;
+
+ /* Add it to the appropriate closure class if we've started it. */
+ if (current_class_type
+ && current_class_type == LAMBDA_EXPR_CLOSURE (lambda))
+ finish_member_declaration (member);
+
+ tree listmem = member;
+ if (variadic)
+ {
+ listmem = make_pack_expansion (member);
+ initializer = orig_init;
+ }
+ LAMBDA_EXPR_CAPTURE_LIST (lambda)
+ = tree_cons (listmem, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda));
+
+ if (LAMBDA_EXPR_CLOSURE (lambda))
+ return build_capture_proxy (member);
+ /* For explicit captures we haven't started the function yet, so we wait
+ and build the proxy from cp_parser_lambda_body. */
+ return NULL_TREE;
+}
+
+/* Register all the capture members on the list CAPTURES, which is the
+ LAMBDA_EXPR_CAPTURE_LIST for the lambda after the introducer. */
+
+void
+register_capture_members (tree captures)
+{
+ if (captures == NULL_TREE)
+ return;
+
+ register_capture_members (TREE_CHAIN (captures));
+
+ tree field = TREE_PURPOSE (captures);
+ if (PACK_EXPANSION_P (field))
+ field = PACK_EXPANSION_PATTERN (field);
+
+ /* We set this in add_capture to avoid duplicates. */
+ IDENTIFIER_MARKED (DECL_NAME (field)) = false;
+ finish_member_declaration (field);
+}
+
+/* Similar to add_capture, except this works on a stack of nested lambdas.
+ BY_REFERENCE_P in this case is derived from the default capture mode.
+ Returns the capture for the lambda at the bottom of the stack. */
+
+tree
+add_default_capture (tree lambda_stack, tree id, tree initializer)
+{
+ bool this_capture_p = (id == this_identifier);
+
+ tree var = NULL_TREE;
+
+ tree saved_class_type = current_class_type;
+
+ tree node;
+
+ for (node = lambda_stack;
+ node;
+ node = TREE_CHAIN (node))
+ {
+ tree lambda = TREE_VALUE (node);
+
+ current_class_type = LAMBDA_EXPR_CLOSURE (lambda);
+ if (DECL_PACK_P (initializer))
+ initializer = make_pack_expansion (initializer);
+ var = add_capture (lambda,
+ id,
+ initializer,
+ /*by_reference_p=*/
+ (!this_capture_p
+ && (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda)
+ == CPLD_REFERENCE)),
+ /*explicit_init_p=*/false);
+ initializer = convert_from_reference (var);
+ }
+
+ current_class_type = saved_class_type;
+
+ return var;
+}
+
+/* Return the capture pertaining to a use of 'this' in LAMBDA, in the form of an
+ INDIRECT_REF, possibly adding it through default capturing. */
+
+tree
+lambda_expr_this_capture (tree lambda)
+{
+ tree result;
+
+ tree this_capture = LAMBDA_EXPR_THIS_CAPTURE (lambda);
+
+ /* In unevaluated context this isn't an odr-use, so just return the
+ nearest 'this'. */
+ if (cp_unevaluated_operand)
+ {
+ /* In an NSDMI the fake 'this' pointer that we're using for
+ parsing is in scope_chain. */
+ if (LAMBDA_EXPR_EXTRA_SCOPE (lambda)
+ && TREE_CODE (LAMBDA_EXPR_EXTRA_SCOPE (lambda)) == FIELD_DECL)
+ return scope_chain->x_current_class_ptr;
+ return lookup_name (this_identifier);
+ }
+
+ /* Try to default capture 'this' if we can. */
+ if (!this_capture
+ && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE)
+ {
+ tree lambda_stack = NULL_TREE;
+ tree init = NULL_TREE;
+
+ /* If we are in a lambda function, we can move out until we hit:
+ 1. a non-lambda function or NSDMI,
+ 2. a lambda function capturing 'this', or
+ 3. a non-default capturing lambda function. */
+ for (tree tlambda = lambda; ;)
+ {
+ lambda_stack = tree_cons (NULL_TREE,
+ tlambda,
+ lambda_stack);
+
+ if (LAMBDA_EXPR_EXTRA_SCOPE (tlambda)
+ && TREE_CODE (LAMBDA_EXPR_EXTRA_SCOPE (tlambda)) == FIELD_DECL)
+ {
+ /* In an NSDMI, we don't have a function to look up the decl in,
+ but the fake 'this' pointer that we're using for parsing is
+ in scope_chain. */
+ init = scope_chain->x_current_class_ptr;
+ gcc_checking_assert
+ (init && (TREE_TYPE (TREE_TYPE (init))
+ == current_nonlambda_class_type ()));
+ break;
+ }
+
+ tree closure_decl = TYPE_NAME (LAMBDA_EXPR_CLOSURE (tlambda));
+ tree containing_function = decl_function_context (closure_decl);
+
+ if (containing_function == NULL_TREE)
+ /* We ran out of scopes; there's no 'this' to capture. */
+ break;
+
+ if (!LAMBDA_FUNCTION_P (containing_function))
+ {
+ /* We found a non-lambda function. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (containing_function))
+ /* First parameter is 'this'. */
+ init = DECL_ARGUMENTS (containing_function);
+ break;
+ }
+
+ tlambda
+ = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (containing_function));
+
+ if (LAMBDA_EXPR_THIS_CAPTURE (tlambda))
+ {
+ /* An outer lambda has already captured 'this'. */
+ init = LAMBDA_EXPR_THIS_CAPTURE (tlambda);
+ break;
+ }
+
+ if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (tlambda) == CPLD_NONE)
+ /* An outer lambda won't let us capture 'this'. */
+ break;
+ }
+
+ if (init)
+ this_capture = add_default_capture (lambda_stack,
+ /*id=*/this_identifier,
+ init);
+ }
+
+ if (!this_capture)
+ {
+ error ("%<this%> was not captured for this lambda function");
+ result = error_mark_node;
+ }
+ else
+ {
+ /* To make sure that current_class_ref is for the lambda. */
+ gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref))
+ == LAMBDA_EXPR_CLOSURE (lambda));
+
+ result = this_capture;
+
+ /* If 'this' is captured, each use of 'this' is transformed into an
+ access to the corresponding unnamed data member of the closure
+ type cast (_expr.cast_ 5.4) to the type of 'this'. [ The cast
+ ensures that the transformed expression is an rvalue. ] */
+ result = rvalue (result);
+ }
+
+ return result;
+}
+
+/* We don't want to capture 'this' until we know we need it, i.e. after
+ overload resolution has chosen a non-static member function. At that
+ point we call this function to turn a dummy object into a use of the
+ 'this' capture. */
+
+tree
+maybe_resolve_dummy (tree object)
+{
+ if (!is_dummy_object (object))
+ return object;
+
+ tree type = TYPE_MAIN_VARIANT (TREE_TYPE (object));
+ gcc_assert (!TYPE_PTR_P (type));
+
+ if (type != current_class_type
+ && current_class_type
+ && LAMBDA_TYPE_P (current_class_type)
+ && lambda_function (current_class_type)
+ && DERIVED_FROM_P (type, current_nonlambda_class_type ()))
+ {
+ /* In a lambda, need to go through 'this' capture. */
+ tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
+ tree cap = lambda_expr_this_capture (lam);
+ object = build_x_indirect_ref (EXPR_LOCATION (object), cap,
+ RO_NULL, tf_warning_or_error);
+ }
+
+ return object;
+}
+
+/* Returns the method basetype of the innermost non-lambda function, or
+ NULL_TREE if none. */
+
+tree
+nonlambda_method_basetype (void)
+{
+ tree fn, type;
+ if (!current_class_ref)
+ return NULL_TREE;
+
+ type = current_class_type;
+ if (!LAMBDA_TYPE_P (type))
+ return type;
+
+ /* Find the nearest enclosing non-lambda function. */
+ fn = TYPE_NAME (type);
+ do
+ fn = decl_function_context (fn);
+ while (fn && LAMBDA_FUNCTION_P (fn));
+
+ if (!fn || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+ return NULL_TREE;
+
+ return TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
+}
+
+/* Helper function for maybe_add_lambda_conv_op; build a CALL_EXPR with
+ indicated FN and NARGS, but do not initialize the return type or any of the
+ argument slots. */
+
+static tree
+prepare_op_call (tree fn, int nargs)
+{
+ tree t;
+
+ t = build_vl_exp (CALL_EXPR, nargs + 3);
+ CALL_EXPR_FN (t) = fn;
+ CALL_EXPR_STATIC_CHAIN (t) = NULL;
+
+ return t;
+}
+
+/* If the closure TYPE has a static op(), also add a conversion to function
+ pointer. */
+
+void
+maybe_add_lambda_conv_op (tree type)
+{
+ bool nested = (current_function_decl != NULL_TREE);
+ tree callop = lambda_function (type);
+
+ if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE)
+ return;
+
+ if (processing_template_decl)
+ return;
+
+ bool const generic_lambda_p
+ = (DECL_TEMPLATE_INFO (callop)
+ && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (callop)) == callop);
+
+ if (!generic_lambda_p && DECL_INITIAL (callop) == NULL_TREE)
+ {
+ /* If the op() wasn't instantiated due to errors, give up. */
+ gcc_assert (errorcount || sorrycount);
+ return;
+ }
+
+ /* Non-template conversion operators are defined directly with build_call_a
+ and using DIRECT_ARGVEC for arguments (including 'this'). Templates are
+ deferred and the CALL is built in-place. In the case of a deduced return
+ call op, the decltype expression, DECLTYPE_CALL, used as a substitute for
+ the return type is also built in-place. The arguments of DECLTYPE_CALL in
+ the return expression may differ in flags from those in the body CALL. In
+ particular, parameter pack expansions are marked PACK_EXPANSION_LOCAL_P in
+ the body CALL, but not in DECLTYPE_CALL. */
+
+ vec<tree, va_gc> *direct_argvec = 0;
+ tree decltype_call = 0, call = 0;
+ tree fn_result = TREE_TYPE (TREE_TYPE (callop));
+
+ if (generic_lambda_p)
+ {
+ /* Prepare the dependent member call for the static member function
+ '_FUN' and, potentially, prepare another call to be used in a decltype
+ return expression for a deduced return call op to allow for simple
+ implementation of the conversion operator. */
+
+ tree instance = build_nop (type, null_pointer_node);
+ tree objfn = build_min (COMPONENT_REF, NULL_TREE,
+ instance, DECL_NAME (callop), NULL_TREE);
+ int nargs = list_length (DECL_ARGUMENTS (callop)) - 1;
+
+ call = prepare_op_call (objfn, nargs);
+ if (type_uses_auto (fn_result))
+ decltype_call = prepare_op_call (objfn, nargs);
+ }
+ else
+ {
+ direct_argvec = make_tree_vector ();
+ direct_argvec->quick_push (build1 (NOP_EXPR,
+ TREE_TYPE (DECL_ARGUMENTS (callop)),
+ null_pointer_node));
+ }
+
+ /* Copy CALLOP's argument list (as per 'copy_list') as FN_ARGS in order to
+ declare the static member function "_FUN" below. For each arg append to
+ DIRECT_ARGVEC (for the non-template case) or populate the pre-allocated
+ call args (for the template case). If a parameter pack is found, expand
+ it, flagging it as PACK_EXPANSION_LOCAL_P for the body call. */
+
+ tree fn_args = NULL_TREE;
+ {
+ int ix = 0;
+ tree src = DECL_CHAIN (DECL_ARGUMENTS (callop));
+ tree tgt;
+
+ while (src)
+ {
+ tree new_node = copy_node (src);
+
+ if (!fn_args)
+ fn_args = tgt = new_node;
+ else
+ {
+ TREE_CHAIN (tgt) = new_node;
+ tgt = new_node;
+ }
+
+ mark_exp_read (tgt);
+
+ if (generic_lambda_p)
+ {
+ if (DECL_PACK_P (tgt))
+ {
+ tree a = make_pack_expansion (tgt);
+ if (decltype_call)
+ CALL_EXPR_ARG (decltype_call, ix) = copy_node (a);
+ PACK_EXPANSION_LOCAL_P (a) = true;
+ CALL_EXPR_ARG (call, ix) = a;
+ }
+ else
+ {
+ tree a = convert_from_reference (tgt);
+ CALL_EXPR_ARG (call, ix) = a;
+ if (decltype_call)
+ CALL_EXPR_ARG (decltype_call, ix) = copy_node (a);
+ }
+ ++ix;
+ }
+ else
+ vec_safe_push (direct_argvec, tgt);
+
+ src = TREE_CHAIN (src);
+ }
+ }
+
+
+ if (generic_lambda_p)
+ {
+ if (decltype_call)
+ {
+ ++processing_template_decl;
+ fn_result = finish_decltype_type
+ (decltype_call, /*id_expression_or_member_access_p=*/false,
+ tf_warning_or_error);
+ --processing_template_decl;
+ }
+ }
+ else
+ call = build_call_a (callop,
+ direct_argvec->length (),
+ direct_argvec->address ());
+
+ CALL_FROM_THUNK_P (call) = 1;
+
+ tree stattype = build_function_type (fn_result, FUNCTION_ARG_CHAIN (callop));
+
+ /* First build up the conversion op. */
+
+ tree rettype = build_pointer_type (stattype);
+ tree name = mangle_conv_op_name_for_type (rettype);
+ tree thistype = cp_build_qualified_type (type, TYPE_QUAL_CONST);
+ tree fntype = build_method_type_directly (thistype, rettype, void_list_node);
+ tree convfn = build_lang_decl (FUNCTION_DECL, name, fntype);
+ tree fn = convfn;
+ DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
+
+ if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+ && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
+ DECL_ALIGN (fn) = 2 * BITS_PER_UNIT;
+
+ SET_OVERLOADED_OPERATOR_CODE (fn, TYPE_EXPR);
+ grokclassfn (type, fn, NO_SPECIAL);
+ set_linkage_according_to_type (type, fn);
+ rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
+ DECL_IN_AGGR_P (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ DECL_NOT_REALLY_EXTERN (fn) = 1;
+ DECL_DECLARED_INLINE_P (fn) = 1;
+ DECL_ARGUMENTS (fn) = build_this_parm (fntype, TYPE_QUAL_CONST);
+ if (nested)
+ DECL_INTERFACE_KNOWN (fn) = 1;
+
+ if (generic_lambda_p)
+ fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));
+
+ add_method (type, fn, NULL_TREE);
+
+ /* Generic thunk code fails for varargs; we'll complain in mark_used if
+ the conversion op is used. */
+ if (varargs_function_p (callop))
+ {
+ DECL_DELETED_FN (fn) = 1;
+ return;
+ }
+
+ /* Now build up the thunk to be returned. */
+
+ name = get_identifier ("_FUN");
+ tree statfn = build_lang_decl (FUNCTION_DECL, name, stattype);
+ fn = statfn;
+ DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
+ if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+ && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
+ DECL_ALIGN (fn) = 2 * BITS_PER_UNIT;
+ grokclassfn (type, fn, NO_SPECIAL);
+ set_linkage_according_to_type (type, fn);
+ rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
+ DECL_IN_AGGR_P (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ DECL_NOT_REALLY_EXTERN (fn) = 1;
+ DECL_DECLARED_INLINE_P (fn) = 1;
+ DECL_STATIC_FUNCTION_P (fn) = 1;
+ DECL_ARGUMENTS (fn) = fn_args;
+ for (tree arg = fn_args; arg; arg = DECL_CHAIN (arg))
+ {
+ /* Avoid duplicate -Wshadow warnings. */
+ DECL_NAME (arg) = NULL_TREE;
+ DECL_CONTEXT (arg) = fn;
+ }
+ if (nested)
+ DECL_INTERFACE_KNOWN (fn) = 1;
+
+ if (generic_lambda_p)
+ fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));
+
+ add_method (type, fn, NULL_TREE);
+
+ if (nested)
+ push_function_context ();
+ else
+ /* Still increment function_depth so that we don't GC in the
+ middle of an expression. */
+ ++function_depth;
+
+ /* Generate the body of the thunk. */
+
+ start_preparsed_function (statfn, NULL_TREE,
+ SF_PRE_PARSED | SF_INCLASS_INLINE);
+ if (DECL_ONE_ONLY (statfn))
+ {
+ /* Put the thunk in the same comdat group as the call op. */
+ symtab_add_to_same_comdat_group
+ (cgraph_get_create_node (statfn),
+ cgraph_get_create_node (callop));
+ }
+ tree body = begin_function_body ();
+ tree compound_stmt = begin_compound_stmt (0);
+ if (!generic_lambda_p)
+ {
+ set_flags_from_callee (call);
+ if (MAYBE_CLASS_TYPE_P (TREE_TYPE (call)))
+ call = build_cplus_new (TREE_TYPE (call), call, tf_warning_or_error);
+ }
+ call = convert_from_reference (call);
+ finish_return_stmt (call);
+
+ finish_compound_stmt (compound_stmt);
+ finish_function_body (body);
+
+ fn = finish_function (/*inline*/2);
+ if (!generic_lambda_p)
+ expand_or_defer_fn (fn);
+
+ /* Generate the body of the conversion op. */
+
+ start_preparsed_function (convfn, NULL_TREE,
+ SF_PRE_PARSED | SF_INCLASS_INLINE);
+ body = begin_function_body ();
+ compound_stmt = begin_compound_stmt (0);
+
+ /* decl_needed_p needs to see that it's used. */
+ TREE_USED (statfn) = 1;
+ finish_return_stmt (decay_conversion (statfn, tf_warning_or_error));
+
+ finish_compound_stmt (compound_stmt);
+ finish_function_body (body);
+
+ fn = finish_function (/*inline*/2);
+ if (!generic_lambda_p)
+ expand_or_defer_fn (fn);
+
+ if (nested)
+ pop_function_context ();
+ else
+ --function_depth;
+}
+
+/* Returns true iff VAL is a lambda-related declaration which should
+ be ignored by unqualified lookup. */
+
+bool
+is_lambda_ignored_entity (tree val)
+{
+ /* In unevaluated context, look past normal capture proxies. */
+ if (cp_unevaluated_operand && is_normal_capture_proxy (val))
+ return true;
+
+ /* Always ignore lambda fields, their names are only for debugging. */
+ if (TREE_CODE (val) == FIELD_DECL
+ && CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (val)))
+ return true;
+
+ /* None of the lookups that use qualify_lookup want the op() from the
+ lambda; they want the one from the enclosing class. */
+ if (TREE_CODE (val) == FUNCTION_DECL && LAMBDA_FUNCTION_P (val))
+ return true;
+
+ return false;
+}
diff --git a/gcc-4.9/gcc/cp/lang-specs.h b/gcc-4.9/gcc/cp/lang-specs.h
new file mode 100644
index 000000000..79c9222b3
--- /dev/null
+++ b/gcc-4.9/gcc/cp/lang-specs.h
@@ -0,0 +1,67 @@
+/* Definitions for specs for C++.
+ Copyright (C) 1995-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* This is the contribution to the `default_compilers' array in gcc.c for
+ g++. */
+
+#ifndef CPLUSPLUS_CPP_SPEC
+#define CPLUSPLUS_CPP_SPEC 0
+#endif
+
+ {".cc", "@c++", 0, 0, 0},
+ {".cp", "@c++", 0, 0, 0},
+ {".cxx", "@c++", 0, 0, 0},
+ {".cpp", "@c++", 0, 0, 0},
+ {".c++", "@c++", 0, 0, 0},
+ {".C", "@c++", 0, 0, 0},
+ {".CPP", "@c++", 0, 0, 0},
+ {".H", "@c++-header", 0, 0, 0},
+ {".hpp", "@c++-header", 0, 0, 0},
+ {".hp", "@c++-header", 0, 0, 0},
+ {".hxx", "@c++-header", 0, 0, 0},
+ {".h++", "@c++-header", 0, 0, 0},
+ {".HPP", "@c++-header", 0, 0, 0},
+ {".tcc", "@c++-header", 0, 0, 0},
+ {".hh", "@c++-header", 0, 0, 0},
+ {"@c++-header",
+ "%{E|M|MM:cc1plus -E %(cpp_options) %2 %(cpp_debug_options)}\
+ %{!E:%{!M:%{!MM:\
+ %{save-temps*|no-integrated-cpp:cc1plus -E\
+ %(cpp_options) %2 -o %{save-temps*:%b.ii} %{!save-temps*:%g.ii} \n}\
+ cc1plus %{save-temps*|no-integrated-cpp:-fpreprocessed %{save-temps*:%b.ii} %{!save-temps*:%g.ii}}\
+ %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}\
+ %(cc1_options) %2\
+ %{!fsyntax-only:%{!fdump-ada-spec*:-o %g.s %{!o*:--output-pch=%i.gch}\
+ %W{o*:--output-pch=%*}}%V}}}}",
+ CPLUSPLUS_CPP_SPEC, 0, 0},
+ {"@c++",
+ "%{E|M|MM:cc1plus -E %(cpp_options) %2 %(cpp_debug_options)}\
+ %{!E:%{!M:%{!MM:\
+ %{save-temps*|no-integrated-cpp:cc1plus -E\
+ %(cpp_options) %2 -o %{save-temps*:%b.ii} %{!save-temps*:%g.ii} \n}\
+ cc1plus %{save-temps*|no-integrated-cpp:-fpreprocessed %{save-temps*:%b.ii} %{!save-temps*:%g.ii}}\
+ %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}\
+ %(cc1_options) %2\
+ %{!fsyntax-only:%(invoke_as)}}}}",
+ CPLUSPLUS_CPP_SPEC, 0, 0},
+ {".ii", "@c++-cpp-output", 0, 0, 0},
+ {"@c++-cpp-output",
+ "%{!M:%{!MM:%{!E:\
+ cc1plus -fpreprocessed %i %(cc1_options) %2\
+ %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
diff --git a/gcc-4.9/gcc/cp/lex.c b/gcc-4.9/gcc/cp/lex.c
new file mode 100644
index 000000000..3fe275e49
--- /dev/null
+++ b/gcc-4.9/gcc/cp/lex.c
@@ -0,0 +1,716 @@
+/* Separate lexical analyzer for GNU C++.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Hacked by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* This file is the lexical analyzer for GNU C++. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "input.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "cp-tree.h"
+#include "cpplib.h"
+#include "flags.h"
+#include "c-family/c-pragma.h"
+#include "c-family/c-objc.h"
+#include "tm_p.h"
+#include "timevar.h"
+
+static int interface_strcmp (const char *);
+static void init_cp_pragma (void);
+
+static tree parse_strconst_pragma (const char *, int);
+static void handle_pragma_vtable (cpp_reader *);
+static void handle_pragma_unit (cpp_reader *);
+static void handle_pragma_interface (cpp_reader *);
+static void handle_pragma_implementation (cpp_reader *);
+static void handle_pragma_java_exceptions (cpp_reader *);
+
+static void init_operators (void);
+static void copy_lang_type (tree);
+
+/* A constraint that can be tested at compile time. */
+#define CONSTRAINT(name, expr) extern int constraint_##name [(expr) ? 1 : -1]
+
+/* Functions and data structures for #pragma interface.
+
+ `#pragma implementation' means that the main file being compiled
+ is considered to implement (provide) the classes that appear in
+ its main body. I.e., if this is file "foo.cc", and class `bar'
+ is defined in "foo.cc", then we say that "foo.cc implements bar".
+
+ All main input files "implement" themselves automagically.
+
+ `#pragma interface' means that unless this file (of the form "foo.h"
+ is not presently being included by file "foo.cc", the
+ CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none
+ of the vtables nor any of the inline functions defined in foo.h
+ will ever be output.
+
+ There are cases when we want to link files such as "defs.h" and
+ "main.cc". In this case, we give "defs.h" a `#pragma interface',
+ and "main.cc" has `#pragma implementation "defs.h"'. */
+
+struct impl_files
+{
+ const char *filename;
+ struct impl_files *next;
+};
+
+static struct impl_files *impl_file_chain;
+
+/* True if we saw "#pragma GCC java_exceptions". */
+bool pragma_java_exceptions;
+
+void
+cxx_finish (void)
+{
+ c_common_finish ();
+}
+
+/* A mapping from tree codes to operator name information. */
+operator_name_info_t operator_name_info[(int) MAX_TREE_CODES];
+/* Similar, but for assignment operators. */
+operator_name_info_t assignment_operator_name_info[(int) MAX_TREE_CODES];
+
+/* Initialize data structures that keep track of operator names. */
+
+#define DEF_OPERATOR(NAME, C, M, AR, AP) \
+ CONSTRAINT (C, sizeof "operator " + sizeof NAME <= 256);
+#include "operators.def"
+#undef DEF_OPERATOR
+
+static void
+init_operators (void)
+{
+ tree identifier;
+ char buffer[256];
+ struct operator_name_info_t *oni;
+
+#define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, ASSN_P) \
+ sprintf (buffer, ISALPHA (NAME[0]) ? "operator %s" : "operator%s", NAME); \
+ identifier = get_identifier (buffer); \
+ IDENTIFIER_OPNAME_P (identifier) = 1; \
+ \
+ oni = (ASSN_P \
+ ? &assignment_operator_name_info[(int) CODE] \
+ : &operator_name_info[(int) CODE]); \
+ oni->identifier = identifier; \
+ oni->name = NAME; \
+ oni->mangled_name = MANGLING; \
+ oni->arity = ARITY;
+
+#include "operators.def"
+#undef DEF_OPERATOR
+
+ operator_name_info[(int) ERROR_MARK].identifier
+ = get_identifier ("<invalid operator>");
+
+ /* Handle some special cases. These operators are not defined in
+ the language, but can be produced internally. We may need them
+ for error-reporting. (Eventually, we should ensure that this
+ does not happen. Error messages involving these operators will
+ be confusing to users.) */
+
+ operator_name_info [(int) INIT_EXPR].name
+ = operator_name_info [(int) MODIFY_EXPR].name;
+ operator_name_info [(int) EXACT_DIV_EXPR].name = "(ceiling /)";
+ operator_name_info [(int) CEIL_DIV_EXPR].name = "(ceiling /)";
+ operator_name_info [(int) FLOOR_DIV_EXPR].name = "(floor /)";
+ operator_name_info [(int) ROUND_DIV_EXPR].name = "(round /)";
+ operator_name_info [(int) CEIL_MOD_EXPR].name = "(ceiling %)";
+ operator_name_info [(int) FLOOR_MOD_EXPR].name = "(floor %)";
+ operator_name_info [(int) ROUND_MOD_EXPR].name = "(round %)";
+ operator_name_info [(int) ABS_EXPR].name = "abs";
+ operator_name_info [(int) TRUTH_AND_EXPR].name = "strict &&";
+ operator_name_info [(int) TRUTH_OR_EXPR].name = "strict ||";
+ operator_name_info [(int) RANGE_EXPR].name = "...";
+ operator_name_info [(int) UNARY_PLUS_EXPR].name = "+";
+
+ assignment_operator_name_info [(int) EXACT_DIV_EXPR].name
+ = "(exact /=)";
+ assignment_operator_name_info [(int) CEIL_DIV_EXPR].name
+ = "(ceiling /=)";
+ assignment_operator_name_info [(int) FLOOR_DIV_EXPR].name
+ = "(floor /=)";
+ assignment_operator_name_info [(int) ROUND_DIV_EXPR].name
+ = "(round /=)";
+ assignment_operator_name_info [(int) CEIL_MOD_EXPR].name
+ = "(ceiling %=)";
+ assignment_operator_name_info [(int) FLOOR_MOD_EXPR].name
+ = "(floor %=)";
+ assignment_operator_name_info [(int) ROUND_MOD_EXPR].name
+ = "(round %=)";
+}
+
+/* Initialize the reserved words. */
+
+void
+init_reswords (void)
+{
+ unsigned int i;
+ tree id;
+ int mask = 0;
+
+ if (cxx_dialect < cxx11)
+ mask |= D_CXX0X;
+ if (flag_no_asm)
+ mask |= D_ASM | D_EXT;
+ if (flag_no_gnu_keywords)
+ mask |= D_EXT;
+
+ /* The Objective-C keywords are all context-dependent. */
+ mask |= D_OBJC;
+
+ ridpointers = ggc_alloc_cleared_vec_tree ((int) RID_MAX);
+ for (i = 0; i < num_c_common_reswords; i++)
+ {
+ if (c_common_reswords[i].disable & D_CONLY)
+ continue;
+ id = get_identifier (c_common_reswords[i].word);
+ C_SET_RID_CODE (id, c_common_reswords[i].rid);
+ ridpointers [(int) c_common_reswords[i].rid] = id;
+ if (! (c_common_reswords[i].disable & mask))
+ C_IS_RESERVED_WORD (id) = 1;
+ }
+}
+
+static void
+init_cp_pragma (void)
+{
+ c_register_pragma (0, "vtable", handle_pragma_vtable);
+ c_register_pragma (0, "unit", handle_pragma_unit);
+ c_register_pragma (0, "interface", handle_pragma_interface);
+ c_register_pragma (0, "implementation", handle_pragma_implementation);
+ c_register_pragma ("GCC", "interface", handle_pragma_interface);
+ c_register_pragma ("GCC", "implementation", handle_pragma_implementation);
+ c_register_pragma ("GCC", "java_exceptions", handle_pragma_java_exceptions);
+}
+
+/* TRUE if a code represents a statement. */
+
+bool statement_code_p[MAX_TREE_CODES];
+
+/* Initialize the C++ front end. This function is very sensitive to
+ the exact order that things are done here. It would be nice if the
+ initialization done by this routine were moved to its subroutines,
+ and the ordering dependencies clarified and reduced. */
+bool
+cxx_init (void)
+{
+ location_t saved_loc;
+ unsigned int i;
+ static const enum tree_code stmt_codes[] = {
+ CTOR_INITIALIZER, TRY_BLOCK, HANDLER,
+ EH_SPEC_BLOCK, USING_STMT, TAG_DEFN,
+ IF_STMT, CLEANUP_STMT, FOR_STMT,
+ RANGE_FOR_STMT, WHILE_STMT, DO_STMT,
+ BREAK_STMT, CONTINUE_STMT, SWITCH_STMT,
+ EXPR_STMT
+ };
+
+ memset (&statement_code_p, 0, sizeof (statement_code_p));
+ for (i = 0; i < ARRAY_SIZE (stmt_codes); i++)
+ statement_code_p[stmt_codes[i]] = true;
+
+ saved_loc = input_location;
+ input_location = BUILTINS_LOCATION;
+
+ init_reswords ();
+ init_tree ();
+ init_cp_semantics ();
+ init_operators ();
+ init_method ();
+ init_error ();
+
+ current_function_decl = NULL;
+
+ class_type_node = ridpointers[(int) RID_CLASS];
+
+ cxx_init_decl_processing ();
+
+ if (c_common_init () == false)
+ {
+ input_location = saved_loc;
+ return false;
+ }
+
+ init_cp_pragma ();
+
+ init_repo ();
+
+ input_location = saved_loc;
+ return true;
+}
+
+/* Return nonzero if S is not considered part of an
+ INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */
+
+static int
+interface_strcmp (const char* s)
+{
+ /* Set the interface/implementation bits for this scope. */
+ struct impl_files *ifiles;
+ const char *s1;
+
+ for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
+ {
+ const char *t1 = ifiles->filename;
+ s1 = s;
+
+ if (*s1 == 0 || filename_ncmp (s1, t1, 1) != 0)
+ continue;
+
+ while (*s1 != 0 && filename_ncmp (s1, t1, 1) == 0)
+ s1++, t1++;
+
+ /* A match. */
+ if (*s1 == *t1)
+ return 0;
+
+ /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */
+ if (strchr (s1, '.') || strchr (t1, '.'))
+ continue;
+
+ if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
+ continue;
+
+ /* A match. */
+ return 0;
+ }
+
+ /* No matches. */
+ return 1;
+}
+
+
+
+/* Parse a #pragma whose sole argument is a string constant.
+ If OPT is true, the argument is optional. */
+static tree
+parse_strconst_pragma (const char* name, int opt)
+{
+ tree result, x;
+ enum cpp_ttype t;
+
+ t = pragma_lex (&result);
+ if (t == CPP_STRING)
+ {
+ if (pragma_lex (&x) != CPP_EOF)
+ warning (0, "junk at end of #pragma %s", name);
+ return result;
+ }
+
+ if (t == CPP_EOF && opt)
+ return NULL_TREE;
+
+ error ("invalid #pragma %s", name);
+ return error_mark_node;
+}
+
+static void
+handle_pragma_vtable (cpp_reader* /*dfile*/)
+{
+ parse_strconst_pragma ("vtable", 0);
+ sorry ("#pragma vtable no longer supported");
+}
+
+static void
+handle_pragma_unit (cpp_reader* /*dfile*/)
+{
+ /* Validate syntax, but don't do anything. */
+ parse_strconst_pragma ("unit", 0);
+}
+
+static void
+handle_pragma_interface (cpp_reader* /*dfile*/)
+{
+ tree fname = parse_strconst_pragma ("interface", 1);
+ struct c_fileinfo *finfo;
+ const char *filename;
+
+ if (fname == error_mark_node)
+ return;
+ else if (fname == 0)
+ filename = lbasename (LOCATION_FILE (input_location));
+ else
+ filename = TREE_STRING_POINTER (fname);
+
+ finfo = get_fileinfo (LOCATION_FILE (input_location));
+
+ if (impl_file_chain == 0)
+ {
+ /* If this is zero at this point, then we are
+ auto-implementing. */
+ if (main_input_filename == 0)
+ main_input_filename = LOCATION_FILE (input_location);
+ }
+
+ finfo->interface_only = interface_strcmp (filename);
+ /* If MULTIPLE_SYMBOL_SPACES is set, we cannot assume that we can see
+ a definition in another file. */
+ if (!MULTIPLE_SYMBOL_SPACES || !finfo->interface_only)
+ finfo->interface_unknown = 0;
+}
+
+/* Note that we have seen a #pragma implementation for the key MAIN_FILENAME.
+ We used to only allow this at toplevel, but that restriction was buggy
+ in older compilers and it seems reasonable to allow it in the headers
+ themselves, too. It only needs to precede the matching #p interface.
+
+ We don't touch finfo->interface_only or finfo->interface_unknown;
+ the user must specify a matching #p interface for this to have
+ any effect. */
+
+static void
+handle_pragma_implementation (cpp_reader* /*dfile*/)
+{
+ tree fname = parse_strconst_pragma ("implementation", 1);
+ const char *filename;
+ struct impl_files *ifiles = impl_file_chain;
+
+ if (fname == error_mark_node)
+ return;
+
+ if (fname == 0)
+ {
+ if (main_input_filename)
+ filename = main_input_filename;
+ else
+ filename = LOCATION_FILE (input_location);
+ filename = lbasename (filename);
+ }
+ else
+ {
+ filename = TREE_STRING_POINTER (fname);
+ if (cpp_included_before (parse_in, filename, input_location))
+ warning (0, "#pragma implementation for %qs appears after "
+ "file is included", filename);
+ }
+
+ for (; ifiles; ifiles = ifiles->next)
+ {
+ if (! filename_cmp (ifiles->filename, filename))
+ break;
+ }
+ if (ifiles == 0)
+ {
+ ifiles = XNEW (struct impl_files);
+ ifiles->filename = xstrdup (filename);
+ ifiles->next = impl_file_chain;
+ impl_file_chain = ifiles;
+ }
+}
+
+/* Indicate that this file uses Java-personality exception handling. */
+static void
+handle_pragma_java_exceptions (cpp_reader* /*dfile*/)
+{
+ tree x;
+ if (pragma_lex (&x) != CPP_EOF)
+ warning (0, "junk at end of #pragma GCC java_exceptions");
+
+ choose_personality_routine (lang_java);
+ pragma_java_exceptions = true;
+}
+
+/* Issue an error message indicating that the lookup of NAME (an
+ IDENTIFIER_NODE) failed. Returns the ERROR_MARK_NODE. */
+
+tree
+unqualified_name_lookup_error (tree name)
+{
+ if (IDENTIFIER_OPNAME_P (name))
+ {
+ if (name != ansi_opname (ERROR_MARK))
+ error ("%qD not defined", name);
+ }
+ else
+ {
+ if (!objc_diagnose_private_ivar (name))
+ {
+ error ("%qD was not declared in this scope", name);
+ suggest_alternatives_for (location_of (name), name);
+ }
+ /* Prevent repeated error messages by creating a VAR_DECL with
+ this NAME in the innermost block scope. */
+ if (local_bindings_p ())
+ {
+ tree decl;
+ decl = build_decl (input_location,
+ VAR_DECL, name, error_mark_node);
+ DECL_CONTEXT (decl) = current_function_decl;
+ push_local_binding (name, decl, 0);
+ /* Mark the variable as used so that we do not get warnings
+ about it being unused later. */
+ TREE_USED (decl) = 1;
+ }
+ }
+
+ return error_mark_node;
+}
+
+/* Like unqualified_name_lookup_error, but NAME is an unqualified-id
+ used as a function. Returns an appropriate expression for
+ NAME. */
+
+tree
+unqualified_fn_lookup_error (tree name)
+{
+ if (processing_template_decl)
+ {
+ /* In a template, it is invalid to write "f()" or "f(3)" if no
+ declaration of "f" is available. Historically, G++ and most
+ other compilers accepted that usage since they deferred all name
+ lookup until instantiation time rather than doing unqualified
+ name lookup at template definition time; explain to the user what
+ is going wrong.
+
+ Note that we have the exact wording of the following message in
+ the manual (trouble.texi, node "Name lookup"), so they need to
+ be kept in synch. */
+ permerror (input_location, "there are no arguments to %qD that depend on a template "
+ "parameter, so a declaration of %qD must be available",
+ name, name);
+
+ if (!flag_permissive)
+ {
+ static bool hint;
+ if (!hint)
+ {
+ inform (input_location, "(if you use %<-fpermissive%>, G++ will accept your "
+ "code, but allowing the use of an undeclared name is "
+ "deprecated)");
+ hint = true;
+ }
+ }
+ return name;
+ }
+
+ return unqualified_name_lookup_error (name);
+}
+
+/* Wrapper around build_lang_decl_loc(). Should gradually move to
+ build_lang_decl_loc() and then rename build_lang_decl_loc() back to
+ build_lang_decl(). */
+
+tree
+build_lang_decl (enum tree_code code, tree name, tree type)
+{
+ return build_lang_decl_loc (input_location, code, name, type);
+}
+
+/* Build a decl from CODE, NAME, TYPE declared at LOC, and then add
+ DECL_LANG_SPECIFIC info to the result. */
+
+tree
+build_lang_decl_loc (location_t loc, enum tree_code code, tree name, tree type)
+{
+ tree t;
+
+ t = build_decl (loc, code, name, type);
+ retrofit_lang_decl (t);
+
+ return t;
+}
+
+/* Add DECL_LANG_SPECIFIC info to T. Called from build_lang_decl
+ and pushdecl (for functions generated by the back end). */
+
+void
+retrofit_lang_decl (tree t)
+{
+ struct lang_decl *ld;
+ size_t size;
+ int sel;
+
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ sel = 1, size = sizeof (struct lang_decl_fn);
+ else if (TREE_CODE (t) == NAMESPACE_DECL)
+ sel = 2, size = sizeof (struct lang_decl_ns);
+ else if (TREE_CODE (t) == PARM_DECL)
+ sel = 3, size = sizeof (struct lang_decl_parm);
+ else if (LANG_DECL_HAS_MIN (t))
+ sel = 0, size = sizeof (struct lang_decl_min);
+ else
+ gcc_unreachable ();
+
+ ld = ggc_alloc_cleared_lang_decl (size);
+
+ ld->u.base.selector = sel;
+
+ DECL_LANG_SPECIFIC (t) = ld;
+ if (current_lang_name == lang_name_cplusplus
+ || decl_linkage (t) == lk_none)
+ SET_DECL_LANGUAGE (t, lang_cplusplus);
+ else if (current_lang_name == lang_name_c)
+ SET_DECL_LANGUAGE (t, lang_c);
+ else if (current_lang_name == lang_name_java)
+ SET_DECL_LANGUAGE (t, lang_java);
+ else
+ gcc_unreachable ();
+
+ if (GATHER_STATISTICS)
+ {
+ tree_node_counts[(int)lang_decl] += 1;
+ tree_node_sizes[(int)lang_decl] += size;
+ }
+}
+
+void
+cxx_dup_lang_specific_decl (tree node)
+{
+ int size;
+ struct lang_decl *ld;
+
+ if (! DECL_LANG_SPECIFIC (node))
+ return;
+
+ if (TREE_CODE (node) == FUNCTION_DECL)
+ size = sizeof (struct lang_decl_fn);
+ else if (TREE_CODE (node) == NAMESPACE_DECL)
+ size = sizeof (struct lang_decl_ns);
+ else if (TREE_CODE (node) == PARM_DECL)
+ size = sizeof (struct lang_decl_parm);
+ else if (LANG_DECL_HAS_MIN (node))
+ size = sizeof (struct lang_decl_min);
+ else
+ gcc_unreachable ();
+
+ ld = ggc_alloc_lang_decl (size);
+ memcpy (ld, DECL_LANG_SPECIFIC (node), size);
+ DECL_LANG_SPECIFIC (node) = ld;
+
+ if (GATHER_STATISTICS)
+ {
+ tree_node_counts[(int)lang_decl] += 1;
+ tree_node_sizes[(int)lang_decl] += size;
+ }
+}
+
+/* Copy DECL, including any language-specific parts. */
+
+tree
+copy_decl (tree decl)
+{
+ tree copy;
+
+ copy = copy_node (decl);
+ cxx_dup_lang_specific_decl (copy);
+ return copy;
+}
+
+/* Replace the shared language-specific parts of NODE with a new copy. */
+
+static void
+copy_lang_type (tree node)
+{
+ int size;
+ struct lang_type *lt;
+
+ if (! TYPE_LANG_SPECIFIC (node))
+ return;
+
+ if (TYPE_LANG_SPECIFIC (node)->u.h.is_lang_type_class)
+ size = sizeof (struct lang_type);
+ else
+ size = sizeof (struct lang_type_ptrmem);
+ lt = ggc_alloc_lang_type (size);
+ memcpy (lt, TYPE_LANG_SPECIFIC (node), size);
+ TYPE_LANG_SPECIFIC (node) = lt;
+
+ if (GATHER_STATISTICS)
+ {
+ tree_node_counts[(int)lang_type] += 1;
+ tree_node_sizes[(int)lang_type] += size;
+ }
+}
+
+/* Copy TYPE, including any language-specific parts. */
+
+tree
+copy_type (tree type)
+{
+ tree copy;
+
+ copy = copy_node (type);
+ copy_lang_type (copy);
+ return copy;
+}
+
+tree
+cxx_make_type (enum tree_code code)
+{
+ tree t = make_node (code);
+
+ /* Create lang_type structure. */
+ if (RECORD_OR_UNION_CODE_P (code)
+ || code == BOUND_TEMPLATE_TEMPLATE_PARM)
+ {
+ struct lang_type *pi
+ = ggc_alloc_cleared_lang_type (sizeof (struct lang_type));
+
+ TYPE_LANG_SPECIFIC (t) = pi;
+ pi->u.c.h.is_lang_type_class = 1;
+
+ if (GATHER_STATISTICS)
+ {
+ tree_node_counts[(int)lang_type] += 1;
+ tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
+ }
+ }
+
+ /* Set up some flags that give proper default behavior. */
+ if (RECORD_OR_UNION_CODE_P (code))
+ {
+ struct c_fileinfo *finfo = \
+ get_fileinfo (LOCATION_FILE (input_location));
+ SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
+ CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
+ }
+
+ return t;
+}
+
+tree
+make_class_type (enum tree_code code)
+{
+ tree t = cxx_make_type (code);
+ SET_CLASS_TYPE_P (t, 1);
+ return t;
+}
+
+/* Returns true if we are currently in the main source file, or in a
+ template instantiation started from the main source file. */
+
+bool
+in_main_input_context (void)
+{
+ struct tinst_level *tl = outermost_tinst_level();
+
+ if (tl)
+ return filename_cmp (main_input_filename,
+ LOCATION_FILE (tl->locus)) == 0;
+ else
+ return filename_cmp (main_input_filename, LOCATION_FILE (input_location)) == 0;
+}
diff --git a/gcc-4.9/gcc/cp/mangle.c b/gcc-4.9/gcc/cp/mangle.c
new file mode 100644
index 000000000..251edb14d
--- /dev/null
+++ b/gcc-4.9/gcc/cp/mangle.c
@@ -0,0 +1,3915 @@
+/* Name mangling for the 3.0 C++ ABI.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Written by Alex Samuel <samuel@codesourcery.com>
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* This file implements mangling of C++ names according to the IA64
+ C++ ABI specification. A mangled name encodes a function or
+ variable's name, scope, type, and/or template arguments into a text
+ identifier. This identifier is used as the function's or
+ variable's linkage name, to preserve compatibility between C++'s
+ language features (templates, scoping, and overloading) and C
+ linkers.
+
+ Additionally, g++ uses mangled names internally. To support this,
+ mangling of types is allowed, even though the mangled name of a
+ type should not appear by itself as an exported name. Ditto for
+ uninstantiated templates.
+
+ The primary entry point for this module is mangle_decl, which
+ returns an identifier containing the mangled name for a decl.
+ Additional entry points are provided to build mangled names of
+ particular constructs when the appropriate decl for that construct
+ is not available. These are:
+
+ mangle_typeinfo_for_type: typeinfo data
+ mangle_typeinfo_string_for_type: typeinfo type name
+ mangle_vtbl_for_type: virtual table data
+ mangle_vtt_for_type: VTT data
+ mangle_ctor_vtbl_for_type: `C-in-B' constructor virtual table data
+ mangle_thunk: thunk function or entry */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stor-layout.h"
+#include "stringpool.h"
+#include "tm_p.h"
+#include "cp-tree.h"
+#include "obstack.h"
+#include "flags.h"
+#include "target.h"
+#include "cgraph.h"
+
+/* Debugging support. */
+
+/* Define DEBUG_MANGLE to enable very verbose trace messages. */
+#ifndef DEBUG_MANGLE
+#define DEBUG_MANGLE 0
+#endif
+
+/* Macros for tracing the write_* functions. */
+#if DEBUG_MANGLE
+# define MANGLE_TRACE(FN, INPUT) \
+ fprintf (stderr, " %-24s: %-24s\n", (FN), (INPUT))
+# define MANGLE_TRACE_TREE(FN, NODE) \
+ fprintf (stderr, " %-24s: %-24s (%p)\n", \
+ (FN), get_tree_code_name (TREE_CODE (NODE)), (void *) (NODE))
+#else
+# define MANGLE_TRACE(FN, INPUT)
+# define MANGLE_TRACE_TREE(FN, NODE)
+#endif
+
+/* Nonzero if NODE is a class template-id. We can't rely on
+ CLASSTYPE_USE_TEMPLATE here because of tricky bugs in the parser
+ that hard to distinguish A<T> from A, where A<T> is the type as
+ instantiated outside of the template, and A is the type used
+ without parameters inside the template. */
+#define CLASSTYPE_TEMPLATE_ID_P(NODE) \
+ (TYPE_LANG_SPECIFIC (NODE) != NULL \
+ && (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \
+ || (CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \
+ && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))))))
+
+/* Things we only need one of. This module is not reentrant. */
+typedef struct GTY(()) globals {
+ /* An array of the current substitution candidates, in the order
+ we've seen them. */
+ vec<tree, va_gc> *substitutions;
+
+ /* The entity that is being mangled. */
+ tree GTY ((skip)) entity;
+
+ /* How many parameter scopes we are inside. */
+ int parm_depth;
+
+ /* True if the mangling will be different in a future version of the
+ ABI. */
+ bool need_abi_warning;
+} globals;
+
+static GTY (()) globals G;
+
+/* The obstack on which we build mangled names. */
+static struct obstack *mangle_obstack;
+
+/* The obstack on which we build mangled names that are not going to
+ be IDENTIFIER_NODEs. */
+static struct obstack name_obstack;
+
+/* The first object on the name_obstack; we use this to free memory
+ allocated on the name_obstack. */
+static void *name_base;
+
+/* Indices into subst_identifiers. These are identifiers used in
+ special substitution rules. */
+typedef enum
+{
+ SUBID_ALLOCATOR,
+ SUBID_BASIC_STRING,
+ SUBID_CHAR_TRAITS,
+ SUBID_BASIC_ISTREAM,
+ SUBID_BASIC_OSTREAM,
+ SUBID_BASIC_IOSTREAM,
+ SUBID_MAX
+}
+substitution_identifier_index_t;
+
+/* For quick substitution checks, look up these common identifiers
+ once only. */
+static GTY(()) tree subst_identifiers[SUBID_MAX];
+
+/* Single-letter codes for builtin integer types, defined in
+ <builtin-type>. These are indexed by integer_type_kind values. */
+static const char
+integer_type_codes[itk_none] =
+{
+ 'c', /* itk_char */
+ 'a', /* itk_signed_char */
+ 'h', /* itk_unsigned_char */
+ 's', /* itk_short */
+ 't', /* itk_unsigned_short */
+ 'i', /* itk_int */
+ 'j', /* itk_unsigned_int */
+ 'l', /* itk_long */
+ 'm', /* itk_unsigned_long */
+ 'x', /* itk_long_long */
+ 'y', /* itk_unsigned_long_long */
+ 'n', /* itk_int128 */
+ 'o', /* itk_unsigned_int128 */
+};
+
+static int decl_is_template_id (const tree, tree* const);
+
+/* Functions for handling substitutions. */
+
+static inline tree canonicalize_for_substitution (tree);
+static void add_substitution (tree);
+static inline int is_std_substitution (const tree,
+ const substitution_identifier_index_t);
+static inline int is_std_substitution_char (const tree,
+ const substitution_identifier_index_t);
+static int find_substitution (tree);
+static void mangle_call_offset (const tree, const tree);
+
+/* Functions for emitting mangled representations of things. */
+
+static void write_mangled_name (const tree, bool);
+static void write_encoding (const tree);
+static void write_name (tree, const int);
+static void write_abi_tags (tree);
+static void write_unscoped_name (const tree);
+static void write_unscoped_template_name (const tree);
+static void write_nested_name (const tree);
+static void write_prefix (const tree);
+static void write_template_prefix (const tree);
+static void write_unqualified_name (const tree);
+static void write_conversion_operator_name (const tree);
+static void write_source_name (tree);
+static void write_literal_operator_name (tree);
+static void write_unnamed_type_name (const tree);
+static void write_closure_type_name (const tree);
+static int hwint_to_ascii (unsigned HOST_WIDE_INT, const unsigned int, char *,
+ const unsigned int);
+static void write_number (unsigned HOST_WIDE_INT, const int,
+ const unsigned int);
+static void write_compact_number (int num);
+static void write_integer_cst (const tree);
+static void write_real_cst (const tree);
+static void write_identifier (const char *);
+static void write_special_name_constructor (const tree);
+static void write_special_name_destructor (const tree);
+static void write_type (tree);
+static int write_CV_qualifiers_for_type (const tree);
+static void write_builtin_type (tree);
+static void write_function_type (const tree);
+static void write_bare_function_type (const tree, const int, const tree);
+static void write_method_parms (tree, const int, const tree);
+static void write_class_enum_type (const tree);
+static void write_template_args (tree);
+static void write_expression (tree);
+static void write_template_arg_literal (const tree);
+static void write_template_arg (tree);
+static void write_template_template_arg (const tree);
+static void write_array_type (const tree);
+static void write_pointer_to_member_type (const tree);
+static void write_template_param (const tree);
+static void write_template_template_param (const tree);
+static void write_substitution (const int);
+static int discriminator_for_local_entity (tree);
+static int discriminator_for_string_literal (tree, tree);
+static void write_discriminator (const int);
+static void write_local_name (tree, const tree, const tree);
+static void dump_substitution_candidates (void);
+static tree mangle_decl_string (const tree);
+static int local_class_index (tree);
+
+/* Control functions. */
+
+static inline void start_mangling (const tree);
+static inline const char *finish_mangling (const bool);
+static tree mangle_special_for_type (const tree, const char *);
+
+/* Foreign language functions. */
+
+static void write_java_integer_type_codes (const tree);
+
+/* Append a single character to the end of the mangled
+ representation. */
+#define write_char(CHAR) \
+ obstack_1grow (mangle_obstack, (CHAR))
+
+/* Append a sized buffer to the end of the mangled representation. */
+#define write_chars(CHAR, LEN) \
+ obstack_grow (mangle_obstack, (CHAR), (LEN))
+
+/* Append a NUL-terminated string to the end of the mangled
+ representation. */
+#define write_string(STRING) \
+ obstack_grow (mangle_obstack, (STRING), strlen (STRING))
+
+/* Nonzero if NODE1 and NODE2 are both TREE_LIST nodes and have the
+ same purpose (context, which may be a type) and value (template
+ decl). See write_template_prefix for more information on what this
+ is used for. */
+#define NESTED_TEMPLATE_MATCH(NODE1, NODE2) \
+ (TREE_CODE (NODE1) == TREE_LIST \
+ && TREE_CODE (NODE2) == TREE_LIST \
+ && ((TYPE_P (TREE_PURPOSE (NODE1)) \
+ && same_type_p (TREE_PURPOSE (NODE1), TREE_PURPOSE (NODE2))) \
+ || TREE_PURPOSE (NODE1) == TREE_PURPOSE (NODE2)) \
+ && TREE_VALUE (NODE1) == TREE_VALUE (NODE2))
+
+/* Write out an unsigned quantity in base 10. */
+#define write_unsigned_number(NUMBER) \
+ write_number ((NUMBER), /*unsigned_p=*/1, 10)
+
+/* If DECL is a template instance, return nonzero and, if
+ TEMPLATE_INFO is non-NULL, set *TEMPLATE_INFO to its template info.
+ Otherwise return zero. */
+
+static int
+decl_is_template_id (const tree decl, tree* const template_info)
+{
+ if (TREE_CODE (decl) == TYPE_DECL)
+ {
+ /* TYPE_DECLs are handled specially. Look at its type to decide
+ if this is a template instantiation. */
+ const tree type = TREE_TYPE (decl);
+
+ if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_ID_P (type))
+ {
+ if (template_info != NULL)
+ /* For a templated TYPE_DECL, the template info is hanging
+ off the type. */
+ *template_info = TYPE_TEMPLATE_INFO (type);
+ return 1;
+ }
+ }
+ else
+ {
+ /* Check if this is a primary template. */
+ if (DECL_LANG_SPECIFIC (decl) != NULL
+ && DECL_USE_TEMPLATE (decl)
+ && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl))
+ && TREE_CODE (decl) != TEMPLATE_DECL)
+ {
+ if (template_info != NULL)
+ /* For most templated decls, the template info is hanging
+ off the decl. */
+ *template_info = DECL_TEMPLATE_INFO (decl);
+ return 1;
+ }
+ }
+
+ /* It's not a template id. */
+ return 0;
+}
+
+/* Produce debugging output of current substitution candidates. */
+
+static void
+dump_substitution_candidates (void)
+{
+ unsigned i;
+ tree el;
+
+ fprintf (stderr, " ++ substitutions ");
+ FOR_EACH_VEC_ELT (*G.substitutions, i, el)
+ {
+ const char *name = "???";
+
+ if (i > 0)
+ fprintf (stderr, " ");
+ if (DECL_P (el))
+ name = IDENTIFIER_POINTER (DECL_NAME (el));
+ else if (TREE_CODE (el) == TREE_LIST)
+ name = IDENTIFIER_POINTER (DECL_NAME (TREE_VALUE (el)));
+ else if (TYPE_NAME (el))
+ name = IDENTIFIER_POINTER (TYPE_IDENTIFIER (el));
+ fprintf (stderr, " S%d_ = ", i - 1);
+ if (TYPE_P (el) &&
+ (CP_TYPE_RESTRICT_P (el)
+ || CP_TYPE_VOLATILE_P (el)
+ || CP_TYPE_CONST_P (el)))
+ fprintf (stderr, "CV-");
+ fprintf (stderr, "%s (%s at %p)\n",
+ name, get_tree_code_name (TREE_CODE (el)), (void *) el);
+ }
+}
+
+/* Both decls and types can be substitution candidates, but sometimes
+ they refer to the same thing. For instance, a TYPE_DECL and
+ RECORD_TYPE for the same class refer to the same thing, and should
+ be treated accordingly in substitutions. This function returns a
+ canonicalized tree node representing NODE that is used when adding
+ and substitution candidates and finding matches. */
+
+static inline tree
+canonicalize_for_substitution (tree node)
+{
+ /* For a TYPE_DECL, use the type instead. */
+ if (TREE_CODE (node) == TYPE_DECL)
+ node = TREE_TYPE (node);
+ if (TYPE_P (node)
+ && TYPE_CANONICAL (node) != node
+ && TYPE_MAIN_VARIANT (node) != node)
+ {
+ tree orig = node;
+ /* Here we want to strip the topmost typedef only.
+ We need to do that so is_std_substitution can do proper
+ name matching. */
+ if (TREE_CODE (node) == FUNCTION_TYPE)
+ /* Use build_qualified_type and TYPE_QUALS here to preserve
+ the old buggy mangling of attribute noreturn with abi<5. */
+ node = build_qualified_type (TYPE_MAIN_VARIANT (node),
+ TYPE_QUALS (node));
+ else
+ node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node),
+ cp_type_quals (node));
+ if (TREE_CODE (node) == FUNCTION_TYPE
+ || TREE_CODE (node) == METHOD_TYPE)
+ node = build_ref_qualified_type (node, type_memfn_rqual (orig));
+ }
+ return node;
+}
+
+/* Add NODE as a substitution candidate. NODE must not already be on
+ the list of candidates. */
+
+static void
+add_substitution (tree node)
+{
+ tree c;
+
+ if (DEBUG_MANGLE)
+ fprintf (stderr, " ++ add_substitution (%s at %10p)\n",
+ get_tree_code_name (TREE_CODE (node)), (void *) node);
+
+ /* Get the canonicalized substitution candidate for NODE. */
+ c = canonicalize_for_substitution (node);
+ if (DEBUG_MANGLE && c != node)
+ fprintf (stderr, " ++ using candidate (%s at %10p)\n",
+ get_tree_code_name (TREE_CODE (node)), (void *) node);
+ node = c;
+
+#if ENABLE_CHECKING
+ /* Make sure NODE isn't already a candidate. */
+ {
+ int i;
+ tree candidate;
+
+ FOR_EACH_VEC_SAFE_ELT (G.substitutions, i, candidate)
+ {
+ gcc_assert (!(DECL_P (node) && node == candidate));
+ gcc_assert (!(TYPE_P (node) && TYPE_P (candidate)
+ && same_type_p (node, candidate)));
+ }
+ }
+#endif /* ENABLE_CHECKING */
+
+ /* Put the decl onto the varray of substitution candidates. */
+ vec_safe_push (G.substitutions, node);
+
+ if (DEBUG_MANGLE)
+ dump_substitution_candidates ();
+}
+
+/* Helper function for find_substitution. Returns nonzero if NODE,
+ which may be a decl or a CLASS_TYPE, is a template-id with template
+ name of substitution_index[INDEX] in the ::std namespace. */
+
+static inline int
+is_std_substitution (const tree node,
+ const substitution_identifier_index_t index)
+{
+ tree type = NULL;
+ tree decl = NULL;
+
+ if (DECL_P (node))
+ {
+ type = TREE_TYPE (node);
+ decl = node;
+ }
+ else if (CLASS_TYPE_P (node))
+ {
+ type = node;
+ decl = TYPE_NAME (node);
+ }
+ else
+ /* These are not the droids you're looking for. */
+ return 0;
+
+ return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl))
+ && TYPE_LANG_SPECIFIC (type)
+ && TYPE_TEMPLATE_INFO (type)
+ && (DECL_NAME (TYPE_TI_TEMPLATE (type))
+ == subst_identifiers[index]));
+}
+
+/* Helper function for find_substitution. Returns nonzero if NODE,
+ which may be a decl or a CLASS_TYPE, is the template-id
+ ::std::identifier<char>, where identifier is
+ substitution_index[INDEX]. */
+
+static inline int
+is_std_substitution_char (const tree node,
+ const substitution_identifier_index_t index)
+{
+ tree args;
+ /* Check NODE's name is ::std::identifier. */
+ if (!is_std_substitution (node, index))
+ return 0;
+ /* Figure out its template args. */
+ if (DECL_P (node))
+ args = DECL_TI_ARGS (node);
+ else if (CLASS_TYPE_P (node))
+ args = CLASSTYPE_TI_ARGS (node);
+ else
+ /* Oops, not a template. */
+ return 0;
+ /* NODE's template arg list should be <char>. */
+ return
+ TREE_VEC_LENGTH (args) == 1
+ && TREE_VEC_ELT (args, 0) == char_type_node;
+}
+
+/* Check whether a substitution should be used to represent NODE in
+ the mangling.
+
+ First, check standard special-case substitutions.
+
+ <substitution> ::= St
+ # ::std
+
+ ::= Sa
+ # ::std::allocator
+
+ ::= Sb
+ # ::std::basic_string
+
+ ::= Ss
+ # ::std::basic_string<char,
+ ::std::char_traits<char>,
+ ::std::allocator<char> >
+
+ ::= Si
+ # ::std::basic_istream<char, ::std::char_traits<char> >
+
+ ::= So
+ # ::std::basic_ostream<char, ::std::char_traits<char> >
+
+ ::= Sd
+ # ::std::basic_iostream<char, ::std::char_traits<char> >
+
+ Then examine the stack of currently available substitution
+ candidates for entities appearing earlier in the same mangling
+
+ If a substitution is found, write its mangled representation and
+ return nonzero. If none is found, just return zero. */
+
+static int
+find_substitution (tree node)
+{
+ int i;
+ const int size = vec_safe_length (G.substitutions);
+ tree decl;
+ tree type;
+
+ if (DEBUG_MANGLE)
+ fprintf (stderr, " ++ find_substitution (%s at %p)\n",
+ get_tree_code_name (TREE_CODE (node)), (void *) node);
+
+ /* Obtain the canonicalized substitution representation for NODE.
+ This is what we'll compare against. */
+ node = canonicalize_for_substitution (node);
+
+ /* Check for builtin substitutions. */
+
+ decl = TYPE_P (node) ? TYPE_NAME (node) : node;
+ type = TYPE_P (node) ? node : TREE_TYPE (node);
+
+ /* Check for std::allocator. */
+ if (decl
+ && is_std_substitution (decl, SUBID_ALLOCATOR)
+ && !CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)))
+ {
+ write_string ("Sa");
+ return 1;
+ }
+
+ /* Check for std::basic_string. */
+ if (decl && is_std_substitution (decl, SUBID_BASIC_STRING))
+ {
+ if (TYPE_P (node))
+ {
+ /* If this is a type (i.e. a fully-qualified template-id),
+ check for
+ std::basic_string <char,
+ std::char_traits<char>,
+ std::allocator<char> > . */
+ if (cp_type_quals (type) == TYPE_UNQUALIFIED
+ && CLASSTYPE_USE_TEMPLATE (type))
+ {
+ tree args = CLASSTYPE_TI_ARGS (type);
+ if (TREE_VEC_LENGTH (args) == 3
+ && same_type_p (TREE_VEC_ELT (args, 0), char_type_node)
+ && is_std_substitution_char (TREE_VEC_ELT (args, 1),
+ SUBID_CHAR_TRAITS)
+ && is_std_substitution_char (TREE_VEC_ELT (args, 2),
+ SUBID_ALLOCATOR))
+ {
+ write_string ("Ss");
+ return 1;
+ }
+ }
+ }
+ else
+ /* Substitute for the template name only if this isn't a type. */
+ {
+ write_string ("Sb");
+ return 1;
+ }
+ }
+
+ /* Check for basic_{i,o,io}stream. */
+ if (TYPE_P (node)
+ && cp_type_quals (type) == TYPE_UNQUALIFIED
+ && CLASS_TYPE_P (type)
+ && CLASSTYPE_USE_TEMPLATE (type)
+ && CLASSTYPE_TEMPLATE_INFO (type) != NULL)
+ {
+ /* First, check for the template
+ args <char, std::char_traits<char> > . */
+ tree args = CLASSTYPE_TI_ARGS (type);
+ if (TREE_VEC_LENGTH (args) == 2
+ && TYPE_P (TREE_VEC_ELT (args, 0))
+ && same_type_p (TREE_VEC_ELT (args, 0), char_type_node)
+ && is_std_substitution_char (TREE_VEC_ELT (args, 1),
+ SUBID_CHAR_TRAITS))
+ {
+ /* Got them. Is this basic_istream? */
+ if (is_std_substitution (decl, SUBID_BASIC_ISTREAM))
+ {
+ write_string ("Si");
+ return 1;
+ }
+ /* Or basic_ostream? */
+ else if (is_std_substitution (decl, SUBID_BASIC_OSTREAM))
+ {
+ write_string ("So");
+ return 1;
+ }
+ /* Or basic_iostream? */
+ else if (is_std_substitution (decl, SUBID_BASIC_IOSTREAM))
+ {
+ write_string ("Sd");
+ return 1;
+ }
+ }
+ }
+
+ /* Check for namespace std. */
+ if (decl && DECL_NAMESPACE_STD_P (decl))
+ {
+ write_string ("St");
+ return 1;
+ }
+
+ /* Now check the list of available substitutions for this mangling
+ operation. */
+ for (i = 0; i < size; ++i)
+ {
+ tree candidate = (*G.substitutions)[i];
+ /* NODE is a matched to a candidate if it's the same decl node or
+ if it's the same type. */
+ if (decl == candidate
+ || (TYPE_P (candidate) && type && TYPE_P (node)
+ && same_type_p (type, candidate))
+ || NESTED_TEMPLATE_MATCH (node, candidate))
+ {
+ write_substitution (i);
+ return 1;
+ }
+ }
+
+ /* No substitution found. */
+ return 0;
+}
+
+
+/* TOP_LEVEL is true, if this is being called at outermost level of
+ mangling. It should be false when mangling a decl appearing in an
+ expression within some other mangling.
+
+ <mangled-name> ::= _Z <encoding> */
+
+static void
+write_mangled_name (const tree decl, bool top_level)
+{
+ MANGLE_TRACE_TREE ("mangled-name", decl);
+
+ if (/* The names of `extern "C"' functions are not mangled. */
+ DECL_EXTERN_C_FUNCTION_P (decl)
+ /* But overloaded operator names *are* mangled. */
+ && !DECL_OVERLOADED_OPERATOR_P (decl))
+ {
+ unmangled_name:;
+
+ if (top_level)
+ write_string (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ else
+ {
+ /* The standard notes: "The <encoding> of an extern "C"
+ function is treated like global-scope data, i.e. as its
+ <source-name> without a type." We cannot write
+ overloaded operators that way though, because it contains
+ characters invalid in assembler. */
+ if (abi_version_at_least (2))
+ write_string ("_Z");
+ else
+ G.need_abi_warning = true;
+ write_source_name (DECL_NAME (decl));
+ }
+ }
+ else if (VAR_P (decl)
+ /* The names of non-static global variables aren't mangled. */
+ && DECL_EXTERNAL_LINKAGE_P (decl)
+ && (CP_DECL_CONTEXT (decl) == global_namespace
+ /* And neither are `extern "C"' variables. */
+ || DECL_EXTERN_C_P (decl)))
+ {
+ if (top_level || abi_version_at_least (2))
+ goto unmangled_name;
+ else
+ {
+ G.need_abi_warning = true;
+ goto mangled_name;
+ }
+ }
+ else
+ {
+ mangled_name:;
+ write_string ("_Z");
+ write_encoding (decl);
+ }
+}
+
+/* <encoding> ::= <function name> <bare-function-type>
+ ::= <data name> */
+
+static void
+write_encoding (const tree decl)
+{
+ MANGLE_TRACE_TREE ("encoding", decl);
+
+ if (DECL_LANG_SPECIFIC (decl) && DECL_EXTERN_C_FUNCTION_P (decl))
+ {
+ /* For overloaded operators write just the mangled name
+ without arguments. */
+ if (DECL_OVERLOADED_OPERATOR_P (decl))
+ write_name (decl, /*ignore_local_scope=*/0);
+ else
+ write_source_name (DECL_NAME (decl));
+ return;
+ }
+
+ write_name (decl, /*ignore_local_scope=*/0);
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ tree fn_type;
+ tree d;
+
+ if (decl_is_template_id (decl, NULL))
+ {
+ fn_type = get_mostly_instantiated_function_type (decl);
+ /* FN_TYPE will not have parameter types for in-charge or
+ VTT parameters. Therefore, we pass NULL_TREE to
+ write_bare_function_type -- otherwise, it will get
+ confused about which artificial parameters to skip. */
+ d = NULL_TREE;
+ }
+ else
+ {
+ fn_type = TREE_TYPE (decl);
+ d = decl;
+ }
+
+ write_bare_function_type (fn_type,
+ (!DECL_CONSTRUCTOR_P (decl)
+ && !DECL_DESTRUCTOR_P (decl)
+ && !DECL_CONV_FN_P (decl)
+ && decl_is_template_id (decl, NULL)),
+ d);
+ }
+}
+
+/* Lambdas can have a bit more context for mangling, specifically VAR_DECL
+ or PARM_DECL context, which doesn't belong in DECL_CONTEXT. */
+
+static tree
+decl_mangling_context (tree decl)
+{
+ tree tcontext = targetm.cxx.decl_mangling_context (decl);
+
+ if (tcontext != NULL_TREE)
+ return tcontext;
+
+ if (TREE_CODE (decl) == TYPE_DECL
+ && LAMBDA_TYPE_P (TREE_TYPE (decl)))
+ {
+ tree extra = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl));
+ if (extra)
+ return extra;
+ }
+ else if (TREE_CODE (decl) == TYPE_DECL
+ && TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TYPE_PARM)
+ /* template type parms have no mangling context. */
+ return NULL_TREE;
+ return CP_DECL_CONTEXT (decl);
+}
+
+/* <name> ::= <unscoped-name>
+ ::= <unscoped-template-name> <template-args>
+ ::= <nested-name>
+ ::= <local-name>
+
+ If IGNORE_LOCAL_SCOPE is nonzero, this production of <name> is
+ called from <local-name>, which mangles the enclosing scope
+ elsewhere and then uses this function to mangle just the part
+ underneath the function scope. So don't use the <local-name>
+ production, to avoid an infinite recursion. */
+
+static void
+write_name (tree decl, const int ignore_local_scope)
+{
+ tree context;
+
+ MANGLE_TRACE_TREE ("name", decl);
+
+ if (TREE_CODE (decl) == TYPE_DECL)
+ {
+ /* In case this is a typedef, fish out the corresponding
+ TYPE_DECL for the main variant. */
+ decl = TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl)));
+ }
+
+ context = decl_mangling_context (decl);
+
+ gcc_assert (context != NULL_TREE);
+
+ /* A decl in :: or ::std scope is treated specially. The former is
+ mangled using <unscoped-name> or <unscoped-template-name>, the
+ latter with a special substitution. Also, a name that is
+ directly in a local function scope is also mangled with
+ <unscoped-name> rather than a full <nested-name>. */
+ if (context == global_namespace
+ || DECL_NAMESPACE_STD_P (context)
+ || (ignore_local_scope
+ && (TREE_CODE (context) == FUNCTION_DECL
+ || (abi_version_at_least (7)
+ && TREE_CODE (context) == PARM_DECL))))
+ {
+ tree template_info;
+ /* Is this a template instance? */
+ if (decl_is_template_id (decl, &template_info))
+ {
+ /* Yes: use <unscoped-template-name>. */
+ write_unscoped_template_name (TI_TEMPLATE (template_info));
+ write_template_args (TI_ARGS (template_info));
+ }
+ else
+ /* Everything else gets an <unqualified-name>. */
+ write_unscoped_name (decl);
+ }
+ else
+ {
+ /* Handle local names, unless we asked not to (that is, invoked
+ under <local-name>, to handle only the part of the name under
+ the local scope). */
+ if (!ignore_local_scope)
+ {
+ /* Scan up the list of scope context, looking for a
+ function. If we find one, this entity is in local
+ function scope. local_entity tracks context one scope
+ level down, so it will contain the element that's
+ directly in that function's scope, either decl or one of
+ its enclosing scopes. */
+ tree local_entity = decl;
+ while (context != global_namespace)
+ {
+ /* Make sure we're always dealing with decls. */
+ if (TYPE_P (context))
+ context = TYPE_NAME (context);
+ /* Is this a function? */
+ if (TREE_CODE (context) == FUNCTION_DECL
+ || TREE_CODE (context) == PARM_DECL)
+ {
+ /* Yes, we have local scope. Use the <local-name>
+ production for the innermost function scope. */
+ write_local_name (context, local_entity, decl);
+ return;
+ }
+ /* Up one scope level. */
+ local_entity = context;
+ context = decl_mangling_context (context);
+ }
+
+ /* No local scope found? Fall through to <nested-name>. */
+ }
+
+ /* Other decls get a <nested-name> to encode their scope. */
+ write_nested_name (decl);
+ }
+}
+
+/* <unscoped-name> ::= <unqualified-name>
+ ::= St <unqualified-name> # ::std:: */
+
+static void
+write_unscoped_name (const tree decl)
+{
+ tree context = decl_mangling_context (decl);
+
+ MANGLE_TRACE_TREE ("unscoped-name", decl);
+
+ /* Is DECL in ::std? */
+ if (DECL_NAMESPACE_STD_P (context))
+ {
+ write_string ("St");
+ write_unqualified_name (decl);
+ }
+ else
+ {
+ /* If not, it should be either in the global namespace, or directly
+ in a local function scope. A lambda can also be mangled in the
+ scope of a default argument. */
+ gcc_assert (context == global_namespace
+ || TREE_CODE (context) == PARM_DECL
+ || TREE_CODE (context) == FUNCTION_DECL);
+
+ write_unqualified_name (decl);
+ }
+}
+
+/* <unscoped-template-name> ::= <unscoped-name>
+ ::= <substitution> */
+
+static void
+write_unscoped_template_name (const tree decl)
+{
+ MANGLE_TRACE_TREE ("unscoped-template-name", decl);
+
+ if (find_substitution (decl))
+ return;
+ write_unscoped_name (decl);
+ add_substitution (decl);
+}
+
+/* Write the nested name, including CV-qualifiers, of DECL.
+
+ <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
+ ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
+
+ <ref-qualifier> ::= R # & ref-qualifier
+ ::= O # && ref-qualifier
+ <CV-qualifiers> ::= [r] [V] [K] */
+
+static void
+write_nested_name (const tree decl)
+{
+ tree template_info;
+
+ MANGLE_TRACE_TREE ("nested-name", decl);
+
+ write_char ('N');
+
+ /* Write CV-qualifiers, if this is a member function. */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ {
+ if (DECL_VOLATILE_MEMFUNC_P (decl))
+ write_char ('V');
+ if (DECL_CONST_MEMFUNC_P (decl))
+ write_char ('K');
+ if (FUNCTION_REF_QUALIFIED (TREE_TYPE (decl)))
+ {
+ if (FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl)))
+ write_char ('O');
+ else
+ write_char ('R');
+ }
+ }
+
+ /* Is this a template instance? */
+ if (decl_is_template_id (decl, &template_info))
+ {
+ /* Yes, use <template-prefix>. */
+ write_template_prefix (decl);
+ write_template_args (TI_ARGS (template_info));
+ }
+ else if (TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE)
+ {
+ tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl));
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ write_template_prefix (decl);
+ write_template_args (TREE_OPERAND (name, 1));
+ }
+ else
+ {
+ write_prefix (decl_mangling_context (decl));
+ write_unqualified_name (decl);
+ }
+ }
+ else
+ {
+ /* No, just use <prefix> */
+ write_prefix (decl_mangling_context (decl));
+ write_unqualified_name (decl);
+ }
+ write_char ('E');
+}
+
+/* <prefix> ::= <prefix> <unqualified-name>
+ ::= <template-param>
+ ::= <template-prefix> <template-args>
+ ::= <decltype>
+ ::= # empty
+ ::= <substitution> */
+
+static void
+write_prefix (const tree node)
+{
+ tree decl;
+ /* Non-NULL if NODE represents a template-id. */
+ tree template_info = NULL;
+
+ if (node == NULL
+ || node == global_namespace)
+ return;
+
+ MANGLE_TRACE_TREE ("prefix", node);
+
+ if (TREE_CODE (node) == DECLTYPE_TYPE)
+ {
+ write_type (node);
+ return;
+ }
+
+ if (find_substitution (node))
+ return;
+
+ if (DECL_P (node))
+ {
+ /* If this is a function or parm decl, that means we've hit function
+ scope, so this prefix must be for a local name. In this
+ case, we're under the <local-name> production, which encodes
+ the enclosing function scope elsewhere. So don't continue
+ here. */
+ if (TREE_CODE (node) == FUNCTION_DECL
+ || TREE_CODE (node) == PARM_DECL)
+ return;
+
+ decl = node;
+ decl_is_template_id (decl, &template_info);
+ }
+ else
+ {
+ /* Node is a type. */
+ decl = TYPE_NAME (node);
+ if (CLASSTYPE_TEMPLATE_ID_P (node))
+ template_info = TYPE_TEMPLATE_INFO (node);
+ }
+
+ /* In G++ 3.2, the name of the template parameter was used. */
+ if (TREE_CODE (node) == TEMPLATE_TYPE_PARM
+ && !abi_version_at_least (2))
+ G.need_abi_warning = true;
+
+ if (TREE_CODE (node) == TEMPLATE_TYPE_PARM
+ && abi_version_at_least (2))
+ write_template_param (node);
+ else if (template_info != NULL)
+ /* Templated. */
+ {
+ write_template_prefix (decl);
+ write_template_args (TI_ARGS (template_info));
+ }
+ else if (TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE)
+ {
+ tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl));
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ write_template_prefix (decl);
+ write_template_args (TREE_OPERAND (name, 1));
+ }
+ else
+ {
+ write_prefix (decl_mangling_context (decl));
+ write_unqualified_name (decl);
+ }
+ }
+ else
+ /* Not templated. */
+ {
+ write_prefix (decl_mangling_context (decl));
+ write_unqualified_name (decl);
+ if (VAR_P (decl)
+ || TREE_CODE (decl) == FIELD_DECL)
+ {
+ /* <data-member-prefix> := <member source-name> M */
+ write_char ('M');
+ return;
+ }
+ }
+
+ add_substitution (node);
+}
+
+/* <template-prefix> ::= <prefix> <template component>
+ ::= <template-param>
+ ::= <substitution> */
+
+static void
+write_template_prefix (const tree node)
+{
+ tree decl = DECL_P (node) ? node : TYPE_NAME (node);
+ tree type = DECL_P (node) ? TREE_TYPE (node) : node;
+ tree context = decl_mangling_context (decl);
+ tree template_info;
+ tree templ;
+ tree substitution;
+
+ MANGLE_TRACE_TREE ("template-prefix", node);
+
+ /* Find the template decl. */
+ if (decl_is_template_id (decl, &template_info))
+ templ = TI_TEMPLATE (template_info);
+ else if (TREE_CODE (type) == TYPENAME_TYPE)
+ /* For a typename type, all we have is the name. */
+ templ = DECL_NAME (decl);
+ else
+ {
+ gcc_assert (CLASSTYPE_TEMPLATE_ID_P (type));
+
+ templ = TYPE_TI_TEMPLATE (type);
+ }
+
+ /* For a member template, though, the template name for the
+ innermost name must have all the outer template levels
+ instantiated. For instance, consider
+
+ template<typename T> struct Outer {
+ template<typename U> struct Inner {};
+ };
+
+ The template name for `Inner' in `Outer<int>::Inner<float>' is
+ `Outer<int>::Inner<U>'. In g++, we don't instantiate the template
+ levels separately, so there's no TEMPLATE_DECL available for this
+ (there's only `Outer<T>::Inner<U>').
+
+ In order to get the substitutions right, we create a special
+ TREE_LIST to represent the substitution candidate for a nested
+ template. The TREE_PURPOSE is the template's context, fully
+ instantiated, and the TREE_VALUE is the TEMPLATE_DECL for the inner
+ template.
+
+ So, for the example above, `Outer<int>::Inner' is represented as a
+ substitution candidate by a TREE_LIST whose purpose is `Outer<int>'
+ and whose value is `Outer<T>::Inner<U>'. */
+ if (TYPE_P (context))
+ substitution = build_tree_list (context, templ);
+ else
+ substitution = templ;
+
+ if (find_substitution (substitution))
+ return;
+
+ /* In G++ 3.2, the name of the template template parameter was used. */
+ if (TREE_TYPE (templ)
+ && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
+ && !abi_version_at_least (2))
+ G.need_abi_warning = true;
+
+ if (TREE_TYPE (templ)
+ && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
+ && abi_version_at_least (2))
+ write_template_param (TREE_TYPE (templ));
+ else
+ {
+ write_prefix (context);
+ write_unqualified_name (decl);
+ }
+
+ add_substitution (substitution);
+}
+
+/* We don't need to handle thunks, vtables, or VTTs here. Those are
+ mangled through special entry points.
+
+ <unqualified-name> ::= <operator-name>
+ ::= <special-name>
+ ::= <source-name>
+ ::= <unnamed-type-name>
+ ::= <local-source-name>
+
+ <local-source-name> ::= L <source-name> <discriminator> */
+
+static void
+write_unqualified_id (tree identifier)
+{
+ if (IDENTIFIER_TYPENAME_P (identifier))
+ write_conversion_operator_name (TREE_TYPE (identifier));
+ else if (IDENTIFIER_OPNAME_P (identifier))
+ {
+ int i;
+ const char *mangled_name = NULL;
+
+ /* Unfortunately, there is no easy way to go from the
+ name of the operator back to the corresponding tree
+ code. */
+ for (i = 0; i < MAX_TREE_CODES; ++i)
+ if (operator_name_info[i].identifier == identifier)
+ {
+ /* The ABI says that we prefer binary operator
+ names to unary operator names. */
+ if (operator_name_info[i].arity == 2)
+ {
+ mangled_name = operator_name_info[i].mangled_name;
+ break;
+ }
+ else if (!mangled_name)
+ mangled_name = operator_name_info[i].mangled_name;
+ }
+ else if (assignment_operator_name_info[i].identifier
+ == identifier)
+ {
+ mangled_name
+ = assignment_operator_name_info[i].mangled_name;
+ break;
+ }
+ write_string (mangled_name);
+ }
+ else if (UDLIT_OPER_P (identifier))
+ write_literal_operator_name (identifier);
+ else
+ write_source_name (identifier);
+}
+
+static void
+write_unqualified_name (const tree decl)
+{
+ MANGLE_TRACE_TREE ("unqualified-name", decl);
+
+ if (identifier_p (decl))
+ {
+ write_unqualified_id (decl);
+ return;
+ }
+
+ bool found = false;
+
+ if (DECL_NAME (decl) == NULL_TREE)
+ {
+ found = true;
+ gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
+ write_source_name (DECL_ASSEMBLER_NAME (decl));
+ }
+ else if (DECL_DECLARES_FUNCTION_P (decl))
+ {
+ found = true;
+ if (DECL_CONSTRUCTOR_P (decl))
+ write_special_name_constructor (decl);
+ else if (DECL_DESTRUCTOR_P (decl))
+ write_special_name_destructor (decl);
+ else if (DECL_CONV_FN_P (decl))
+ {
+ /* Conversion operator. Handle it right here.
+ <operator> ::= cv <type> */
+ tree type;
+ if (decl_is_template_id (decl, NULL))
+ {
+ tree fn_type;
+ fn_type = get_mostly_instantiated_function_type (decl);
+ type = TREE_TYPE (fn_type);
+ }
+ else if (FNDECL_USED_AUTO (decl))
+ type = (DECL_STRUCT_FUNCTION (decl)->language
+ ->x_auto_return_pattern);
+ else
+ type = DECL_CONV_FN_TYPE (decl);
+ write_conversion_operator_name (type);
+ }
+ else if (DECL_OVERLOADED_OPERATOR_P (decl))
+ {
+ operator_name_info_t *oni;
+ if (DECL_ASSIGNMENT_OPERATOR_P (decl))
+ oni = assignment_operator_name_info;
+ else
+ oni = operator_name_info;
+
+ write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name);
+ }
+ else if (UDLIT_OPER_P (DECL_NAME (decl)))
+ write_literal_operator_name (DECL_NAME (decl));
+ else
+ found = false;
+ }
+
+ if (found)
+ /* OK */;
+ else if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
+ && DECL_NAMESPACE_SCOPE_P (decl)
+ && decl_linkage (decl) == lk_internal)
+ {
+ MANGLE_TRACE_TREE ("local-source-name", decl);
+ write_char ('L');
+ write_source_name (DECL_NAME (decl));
+ /* The default discriminator is 1, and that's all we ever use,
+ so there's no code to output one here. */
+ }
+ else
+ {
+ tree type = TREE_TYPE (decl);
+
+ if (TREE_CODE (decl) == TYPE_DECL
+ && TYPE_ANONYMOUS_P (type))
+ write_unnamed_type_name (type);
+ else if (TREE_CODE (decl) == TYPE_DECL
+ && LAMBDA_TYPE_P (type))
+ write_closure_type_name (type);
+ else
+ write_source_name (DECL_NAME (decl));
+ }
+
+ tree attrs = (TREE_CODE (decl) == TYPE_DECL
+ ? TYPE_ATTRIBUTES (TREE_TYPE (decl))
+ : DECL_ATTRIBUTES (decl));
+ write_abi_tags (lookup_attribute ("abi_tag", attrs));
+}
+
+/* Write the unqualified-name for a conversion operator to TYPE. */
+
+static void
+write_conversion_operator_name (const tree type)
+{
+ write_string ("cv");
+ write_type (type);
+}
+
+/* Non-terminal <source-name>. IDENTIFIER is an IDENTIFIER_NODE.
+
+ <source-name> ::= </length/ number> <identifier> */
+
+static void
+write_source_name (tree identifier)
+{
+ MANGLE_TRACE_TREE ("source-name", identifier);
+
+ /* Never write the whole template-id name including the template
+ arguments; we only want the template name. */
+ if (IDENTIFIER_TEMPLATE (identifier))
+ identifier = IDENTIFIER_TEMPLATE (identifier);
+
+ write_unsigned_number (IDENTIFIER_LENGTH (identifier));
+ write_identifier (IDENTIFIER_POINTER (identifier));
+}
+
+/* Compare two TREE_STRINGs like strcmp. */
+
+int
+tree_string_cmp (const void *p1, const void *p2)
+{
+ if (p1 == p2)
+ return 0;
+ tree s1 = *(const tree*)p1;
+ tree s2 = *(const tree*)p2;
+ return strcmp (TREE_STRING_POINTER (s1),
+ TREE_STRING_POINTER (s2));
+}
+
+/* ID is the name of a function or type with abi_tags attribute TAGS.
+ Write out the name, suitably decorated. */
+
+static void
+write_abi_tags (tree tags)
+{
+ if (tags == NULL_TREE)
+ return;
+
+ tags = TREE_VALUE (tags);
+
+ vec<tree, va_gc> * vec = make_tree_vector();
+
+ for (tree t = tags; t; t = TREE_CHAIN (t))
+ {
+ if (ABI_TAG_IMPLICIT (t))
+ continue;
+ tree str = TREE_VALUE (t);
+ vec_safe_push (vec, str);
+ }
+
+ vec->qsort (tree_string_cmp);
+
+ unsigned i; tree str;
+ FOR_EACH_VEC_ELT (*vec, i, str)
+ {
+ write_string ("B");
+ write_unsigned_number (TREE_STRING_LENGTH (str) - 1);
+ write_identifier (TREE_STRING_POINTER (str));
+ }
+
+ release_tree_vector (vec);
+}
+
+/* Write a user-defined literal operator.
+ ::= li <source-name> # "" <source-name>
+ IDENTIFIER is an LITERAL_IDENTIFIER_NODE. */
+
+static void
+write_literal_operator_name (tree identifier)
+{
+ const char* suffix = UDLIT_OP_SUFFIX (identifier);
+ write_identifier (UDLIT_OP_MANGLED_PREFIX);
+ write_unsigned_number (strlen (suffix));
+ write_identifier (suffix);
+}
+
+/* Encode 0 as _, and 1+ as n-1_. */
+
+static void
+write_compact_number (int num)
+{
+ if (num > 0)
+ write_unsigned_number (num - 1);
+ write_char ('_');
+}
+
+/* Return how many unnamed types precede TYPE in its enclosing class. */
+
+static int
+nested_anon_class_index (tree type)
+{
+ int index = 0;
+ tree member = TYPE_FIELDS (TYPE_CONTEXT (type));
+ for (; member; member = DECL_CHAIN (member))
+ if (DECL_IMPLICIT_TYPEDEF_P (member))
+ {
+ tree memtype = TREE_TYPE (member);
+ if (memtype == type)
+ return index;
+ else if (TYPE_ANONYMOUS_P (memtype))
+ ++index;
+ }
+
+ gcc_unreachable ();
+}
+
+/* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */
+
+static void
+write_unnamed_type_name (const tree type)
+{
+ int discriminator;
+ MANGLE_TRACE_TREE ("unnamed-type-name", type);
+
+ if (TYPE_FUNCTION_SCOPE_P (type))
+ discriminator = local_class_index (type);
+ else if (TYPE_CLASS_SCOPE_P (type))
+ discriminator = nested_anon_class_index (type);
+ else
+ {
+ gcc_assert (no_linkage_check (type, /*relaxed_p=*/true));
+ /* Just use the old mangling at namespace scope. */
+ write_source_name (TYPE_IDENTIFIER (type));
+ return;
+ }
+
+ write_string ("Ut");
+ write_compact_number (discriminator);
+}
+
+/* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
+ <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters */
+
+static void
+write_closure_type_name (const tree type)
+{
+ tree fn = lambda_function (type);
+ tree lambda = CLASSTYPE_LAMBDA_EXPR (type);
+ tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
+
+ MANGLE_TRACE_TREE ("closure-type-name", type);
+
+ write_string ("Ul");
+ write_method_parms (parms, /*method_p=*/1, fn);
+ write_char ('E');
+ write_compact_number (LAMBDA_EXPR_DISCRIMINATOR (lambda));
+}
+
+/* Convert NUMBER to ascii using base BASE and generating at least
+ MIN_DIGITS characters. BUFFER points to the _end_ of the buffer
+ into which to store the characters. Returns the number of
+ characters generated (these will be laid out in advance of where
+ BUFFER points). */
+
+static int
+hwint_to_ascii (unsigned HOST_WIDE_INT number, const unsigned int base,
+ char *buffer, const unsigned int min_digits)
+{
+ static const char base_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ unsigned digits = 0;
+
+ while (number)
+ {
+ unsigned HOST_WIDE_INT d = number / base;
+
+ *--buffer = base_digits[number - d * base];
+ digits++;
+ number = d;
+ }
+ while (digits < min_digits)
+ {
+ *--buffer = base_digits[0];
+ digits++;
+ }
+ return digits;
+}
+
+/* Non-terminal <number>.
+
+ <number> ::= [n] </decimal integer/> */
+
+static void
+write_number (unsigned HOST_WIDE_INT number, const int unsigned_p,
+ const unsigned int base)
+{
+ char buffer[sizeof (HOST_WIDE_INT) * 8];
+ unsigned count = 0;
+
+ if (!unsigned_p && (HOST_WIDE_INT) number < 0)
+ {
+ write_char ('n');
+ number = -((HOST_WIDE_INT) number);
+ }
+ count = hwint_to_ascii (number, base, buffer + sizeof (buffer), 1);
+ write_chars (buffer + sizeof (buffer) - count, count);
+}
+
+/* Write out an integral CST in decimal. Most numbers are small, and
+ representable in a HOST_WIDE_INT. Occasionally we'll have numbers
+ bigger than that, which we must deal with. */
+
+static inline void
+write_integer_cst (const tree cst)
+{
+ int sign = tree_int_cst_sgn (cst);
+
+ if (TREE_INT_CST_HIGH (cst) + (sign < 0))
+ {
+ /* A bignum. We do this in chunks, each of which fits in a
+ HOST_WIDE_INT. */
+ char buffer[sizeof (HOST_WIDE_INT) * 8 * 2];
+ unsigned HOST_WIDE_INT chunk;
+ unsigned chunk_digits;
+ char *ptr = buffer + sizeof (buffer);
+ unsigned count = 0;
+ tree n, base, type;
+ int done;
+
+ /* HOST_WIDE_INT must be at least 32 bits, so 10^9 is
+ representable. */
+ chunk = 1000000000;
+ chunk_digits = 9;
+
+ if (sizeof (HOST_WIDE_INT) >= 8)
+ {
+ /* It is at least 64 bits, so 10^18 is representable. */
+ chunk_digits = 18;
+ chunk *= chunk;
+ }
+
+ type = c_common_signed_or_unsigned_type (1, TREE_TYPE (cst));
+ base = build_int_cstu (type, chunk);
+ n = build_int_cst_wide (type,
+ TREE_INT_CST_LOW (cst), TREE_INT_CST_HIGH (cst));
+
+ if (sign < 0)
+ {
+ write_char ('n');
+ n = fold_build1_loc (input_location, NEGATE_EXPR, type, n);
+ }
+ do
+ {
+ tree d = fold_build2_loc (input_location, FLOOR_DIV_EXPR, type, n, base);
+ tree tmp = fold_build2_loc (input_location, MULT_EXPR, type, d, base);
+ unsigned c;
+
+ done = integer_zerop (d);
+ tmp = fold_build2_loc (input_location, MINUS_EXPR, type, n, tmp);
+ c = hwint_to_ascii (TREE_INT_CST_LOW (tmp), 10, ptr,
+ done ? 1 : chunk_digits);
+ ptr -= c;
+ count += c;
+ n = d;
+ }
+ while (!done);
+ write_chars (ptr, count);
+ }
+ else
+ {
+ /* A small num. */
+ unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (cst);
+
+ if (sign < 0)
+ {
+ write_char ('n');
+ low = -low;
+ }
+ write_unsigned_number (low);
+ }
+}
+
+/* Write out a floating-point literal.
+
+ "Floating-point literals are encoded using the bit pattern of the
+ target processor's internal representation of that number, as a
+ fixed-length lowercase hexadecimal string, high-order bytes first
+ (even if the target processor would store low-order bytes first).
+ The "n" prefix is not used for floating-point literals; the sign
+ bit is encoded with the rest of the number.
+
+ Here are some examples, assuming the IEEE standard representation
+ for floating point numbers. (Spaces are for readability, not
+ part of the encoding.)
+
+ 1.0f Lf 3f80 0000 E
+ -1.0f Lf bf80 0000 E
+ 1.17549435e-38f Lf 0080 0000 E
+ 1.40129846e-45f Lf 0000 0001 E
+ 0.0f Lf 0000 0000 E"
+
+ Caller is responsible for the Lx and the E. */
+static void
+write_real_cst (const tree value)
+{
+ if (abi_version_at_least (2))
+ {
+ long target_real[4]; /* largest supported float */
+ char buffer[9]; /* eight hex digits in a 32-bit number */
+ int i, limit, dir;
+
+ tree type = TREE_TYPE (value);
+ int words = GET_MODE_BITSIZE (TYPE_MODE (type)) / 32;
+
+ real_to_target (target_real, &TREE_REAL_CST (value),
+ TYPE_MODE (type));
+
+ /* The value in target_real is in the target word order,
+ so we must write it out backward if that happens to be
+ little-endian. write_number cannot be used, it will
+ produce uppercase. */
+ if (FLOAT_WORDS_BIG_ENDIAN)
+ i = 0, limit = words, dir = 1;
+ else
+ i = words - 1, limit = -1, dir = -1;
+
+ for (; i != limit; i += dir)
+ {
+ sprintf (buffer, "%08lx", (unsigned long) target_real[i]);
+ write_chars (buffer, 8);
+ }
+ }
+ else
+ {
+ /* In G++ 3.3 and before the REAL_VALUE_TYPE was written out
+ literally. Note that compatibility with 3.2 is impossible,
+ because the old floating-point emulator used a different
+ format for REAL_VALUE_TYPE. */
+ size_t i;
+ for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i)
+ write_number (((unsigned char *) &TREE_REAL_CST (value))[i],
+ /*unsigned_p*/ 1,
+ /*base*/ 16);
+ G.need_abi_warning = 1;
+ }
+}
+
+/* Non-terminal <identifier>.
+
+ <identifier> ::= </unqualified source code identifier> */
+
+static void
+write_identifier (const char *identifier)
+{
+ MANGLE_TRACE ("identifier", identifier);
+ write_string (identifier);
+}
+
+/* Handle constructor productions of non-terminal <special-name>.
+ CTOR is a constructor FUNCTION_DECL.
+
+ <special-name> ::= C1 # complete object constructor
+ ::= C2 # base object constructor
+ ::= C3 # complete object allocating constructor
+
+ Currently, allocating constructors are never used. */
+
+static void
+write_special_name_constructor (const tree ctor)
+{
+ if (DECL_BASE_CONSTRUCTOR_P (ctor))
+ write_string ("C2");
+ /* This is the old-style "[unified]" constructor.
+ In some cases, we may emit this function and call
+ it from the clones in order to share code and save space. */
+ else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (ctor))
+ write_string ("C4");
+ else
+ {
+ gcc_assert (DECL_COMPLETE_CONSTRUCTOR_P (ctor));
+ write_string ("C1");
+ }
+}
+
+/* Handle destructor productions of non-terminal <special-name>.
+ DTOR is a destructor FUNCTION_DECL.
+
+ <special-name> ::= D0 # deleting (in-charge) destructor
+ ::= D1 # complete object (in-charge) destructor
+ ::= D2 # base object (not-in-charge) destructor */
+
+static void
+write_special_name_destructor (const tree dtor)
+{
+ if (DECL_DELETING_DESTRUCTOR_P (dtor))
+ write_string ("D0");
+ else if (DECL_BASE_DESTRUCTOR_P (dtor))
+ write_string ("D2");
+ else if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (dtor))
+ /* This is the old-style "[unified]" destructor.
+ In some cases, we may emit this function and call
+ it from the clones in order to share code and save space. */
+ write_string ("D4");
+ else
+ {
+ gcc_assert (DECL_COMPLETE_DESTRUCTOR_P (dtor));
+ write_string ("D1");
+ }
+}
+
+/* Scan the vector of local classes and return how many others with the
+ same name (or same no name) and context precede ENTITY. */
+
+static int
+local_class_index (tree entity)
+{
+ int ix, discriminator = 0;
+ tree name = (TYPE_ANONYMOUS_P (entity) ? NULL_TREE
+ : TYPE_IDENTIFIER (entity));
+ tree ctx = TYPE_CONTEXT (entity);
+ for (ix = 0; ; ix++)
+ {
+ tree type = (*local_classes)[ix];
+ if (type == entity)
+ return discriminator;
+ if (TYPE_CONTEXT (type) == ctx
+ && (name ? TYPE_IDENTIFIER (type) == name
+ : TYPE_ANONYMOUS_P (type)))
+ ++discriminator;
+ }
+ gcc_unreachable ();
+}
+
+/* Return the discriminator for ENTITY appearing inside
+ FUNCTION. The discriminator is the lexical ordinal of VAR among
+ entities with the same name in the same FUNCTION. */
+
+static int
+discriminator_for_local_entity (tree entity)
+{
+ if (DECL_DISCRIMINATOR_P (entity))
+ {
+ if (DECL_DISCRIMINATOR_SET_P (entity))
+ return DECL_DISCRIMINATOR (entity);
+ else
+ /* The first entity with a particular name doesn't get
+ DECL_DISCRIMINATOR set up. */
+ return 0;
+ }
+ else if (TREE_CODE (entity) == TYPE_DECL)
+ {
+ /* Scan the list of local classes. */
+ entity = TREE_TYPE (entity);
+
+ /* Lambdas and unnamed types have their own discriminators. */
+ if (LAMBDA_TYPE_P (entity) || TYPE_ANONYMOUS_P (entity))
+ return 0;
+
+ return local_class_index (entity);
+ }
+ else
+ gcc_unreachable ();
+}
+
+/* Return the discriminator for STRING, a string literal used inside
+ FUNCTION. The discriminator is the lexical ordinal of STRING among
+ string literals used in FUNCTION. */
+
+static int
+discriminator_for_string_literal (tree /*function*/,
+ tree /*string*/)
+{
+ /* For now, we don't discriminate amongst string literals. */
+ return 0;
+}
+
+/* <discriminator> := _ <number>
+
+ The discriminator is used only for the second and later occurrences
+ of the same name within a single function. In this case <number> is
+ n - 2, if this is the nth occurrence, in lexical order. */
+
+static void
+write_discriminator (const int discriminator)
+{
+ /* If discriminator is zero, don't write anything. Otherwise... */
+ if (discriminator > 0)
+ {
+ write_char ('_');
+ write_unsigned_number (discriminator - 1);
+ }
+}
+
+/* Mangle the name of a function-scope entity. FUNCTION is the
+ FUNCTION_DECL for the enclosing function, or a PARM_DECL for lambdas in
+ default argument scope. ENTITY is the decl for the entity itself.
+ LOCAL_ENTITY is the entity that's directly scoped in FUNCTION_DECL,
+ either ENTITY itself or an enclosing scope of ENTITY.
+
+ <local-name> := Z <function encoding> E <entity name> [<discriminator>]
+ := Z <function encoding> E s [<discriminator>]
+ := Z <function encoding> Ed [ <parameter number> ] _ <entity name> */
+
+static void
+write_local_name (tree function, const tree local_entity,
+ const tree entity)
+{
+ tree parm = NULL_TREE;
+
+ MANGLE_TRACE_TREE ("local-name", entity);
+
+ if (TREE_CODE (function) == PARM_DECL)
+ {
+ parm = function;
+ function = DECL_CONTEXT (parm);
+ }
+
+ write_char ('Z');
+ write_encoding (function);
+ write_char ('E');
+
+ /* For this purpose, parameters are numbered from right-to-left. */
+ if (parm)
+ {
+ tree t;
+ int i = 0;
+ for (t = DECL_ARGUMENTS (function); t; t = DECL_CHAIN (t))
+ {
+ if (t == parm)
+ i = 1;
+ else if (i)
+ ++i;
+ }
+ write_char ('d');
+ write_compact_number (i - 1);
+ }
+
+ if (TREE_CODE (entity) == STRING_CST)
+ {
+ write_char ('s');
+ write_discriminator (discriminator_for_string_literal (function,
+ entity));
+ }
+ else
+ {
+ /* Now the <entity name>. Let write_name know its being called
+ from <local-name>, so it doesn't try to process the enclosing
+ function scope again. */
+ write_name (entity, /*ignore_local_scope=*/1);
+ write_discriminator (discriminator_for_local_entity (local_entity));
+ }
+}
+
+/* Non-terminals <type> and <CV-qualifier>.
+
+ <type> ::= <builtin-type>
+ ::= <function-type>
+ ::= <class-enum-type>
+ ::= <array-type>
+ ::= <pointer-to-member-type>
+ ::= <template-param>
+ ::= <substitution>
+ ::= <CV-qualifier>
+ ::= P <type> # pointer-to
+ ::= R <type> # reference-to
+ ::= C <type> # complex pair (C 2000)
+ ::= G <type> # imaginary (C 2000) [not supported]
+ ::= U <source-name> <type> # vendor extended type qualifier
+
+ C++0x extensions
+
+ <type> ::= RR <type> # rvalue reference-to
+ <type> ::= Dt <expression> # decltype of an id-expression or
+ # class member access
+ <type> ::= DT <expression> # decltype of an expression
+ <type> ::= Dn # decltype of nullptr
+
+ TYPE is a type node. */
+
+static void
+write_type (tree type)
+{
+ /* This gets set to nonzero if TYPE turns out to be a (possibly
+ CV-qualified) builtin type. */
+ int is_builtin_type = 0;
+
+ MANGLE_TRACE_TREE ("type", type);
+
+ if (type == error_mark_node)
+ return;
+
+ type = canonicalize_for_substitution (type);
+ if (find_substitution (type))
+ return;
+
+
+ if (write_CV_qualifiers_for_type (type) > 0)
+ /* If TYPE was CV-qualified, we just wrote the qualifiers; now
+ mangle the unqualified type. The recursive call is needed here
+ since both the qualified and unqualified types are substitution
+ candidates. */
+ {
+ tree t = TYPE_MAIN_VARIANT (type);
+ if (TREE_CODE (t) == FUNCTION_TYPE
+ || TREE_CODE (t) == METHOD_TYPE)
+ {
+ t = build_ref_qualified_type (t, type_memfn_rqual (type));
+ if (abi_version_at_least (8))
+ /* Avoid adding the unqualified function type as a substitution. */
+ write_function_type (t);
+ else
+ write_type (t);
+ }
+ else
+ write_type (t);
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ /* It is important not to use the TYPE_MAIN_VARIANT of TYPE here
+ so that the cv-qualification of the element type is available
+ in write_array_type. */
+ write_array_type (type);
+ else
+ {
+ tree type_orig = type;
+
+ /* See through any typedefs. */
+ type = TYPE_MAIN_VARIANT (type);
+ if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
+ type = build_ref_qualified_type (type, type_memfn_rqual (type_orig));
+
+ /* According to the C++ ABI, some library classes are passed the
+ same as the scalar type of their single member and use the same
+ mangling. */
+ if (TREE_CODE (type) == RECORD_TYPE && TYPE_TRANSPARENT_AGGR (type))
+ type = TREE_TYPE (first_field (type));
+
+ if (TYPE_PTRDATAMEM_P (type))
+ write_pointer_to_member_type (type);
+ else
+ {
+ /* Handle any target-specific fundamental types. */
+ const char *target_mangling
+ = targetm.mangle_type (type_orig);
+
+ if (target_mangling)
+ {
+ write_string (target_mangling);
+ /* Add substitutions for types other than fundamental
+ types. */
+ if (!VOID_TYPE_P (type)
+ && TREE_CODE (type) != INTEGER_TYPE
+ && TREE_CODE (type) != REAL_TYPE
+ && TREE_CODE (type) != BOOLEAN_TYPE)
+ add_substitution (type);
+ return;
+ }
+
+ switch (TREE_CODE (type))
+ {
+ case VOID_TYPE:
+ case BOOLEAN_TYPE:
+ case INTEGER_TYPE: /* Includes wchar_t. */
+ case REAL_TYPE:
+ case FIXED_POINT_TYPE:
+ {
+ /* If this is a typedef, TYPE may not be one of
+ the standard builtin type nodes, but an alias of one. Use
+ TYPE_MAIN_VARIANT to get to the underlying builtin type. */
+ write_builtin_type (TYPE_MAIN_VARIANT (type));
+ ++is_builtin_type;
+ }
+ break;
+
+ case COMPLEX_TYPE:
+ write_char ('C');
+ write_type (TREE_TYPE (type));
+ break;
+
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ write_function_type (type);
+ break;
+
+ case UNION_TYPE:
+ case RECORD_TYPE:
+ case ENUMERAL_TYPE:
+ /* A pointer-to-member function is represented as a special
+ RECORD_TYPE, so check for this first. */
+ if (TYPE_PTRMEMFUNC_P (type))
+ write_pointer_to_member_type (type);
+ else
+ write_class_enum_type (type);
+ break;
+
+ case TYPENAME_TYPE:
+ case UNBOUND_CLASS_TEMPLATE:
+ /* We handle TYPENAME_TYPEs and UNBOUND_CLASS_TEMPLATEs like
+ ordinary nested names. */
+ write_nested_name (TYPE_STUB_DECL (type));
+ break;
+
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ if (TYPE_PTR_P (type))
+ write_char ('P');
+ else if (TYPE_REF_IS_RVALUE (type))
+ write_char ('O');
+ else
+ write_char ('R');
+ {
+ tree target = TREE_TYPE (type);
+ /* Attribute const/noreturn are not reflected in mangling.
+ We strip them here rather than at a lower level because
+ a typedef or template argument can have function type
+ with function-cv-quals (that use the same representation),
+ but you can't have a pointer/reference to such a type. */
+ if (abi_version_at_least (5)
+ && TREE_CODE (target) == FUNCTION_TYPE)
+ target = build_qualified_type (target, TYPE_UNQUALIFIED);
+ write_type (target);
+ }
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ if (is_auto (type))
+ {
+ if (AUTO_IS_DECLTYPE (type))
+ write_identifier ("Dc");
+ else
+ write_identifier ("Da");
+ ++is_builtin_type;
+ break;
+ }
+ /* else fall through. */
+ case TEMPLATE_PARM_INDEX:
+ write_template_param (type);
+ break;
+
+ case TEMPLATE_TEMPLATE_PARM:
+ write_template_template_param (type);
+ break;
+
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ write_template_template_param (type);
+ write_template_args
+ (TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
+ break;
+
+ case VECTOR_TYPE:
+ if (abi_version_at_least (4))
+ {
+ write_string ("Dv");
+ /* Non-constant vector size would be encoded with
+ _ expression, but we don't support that yet. */
+ write_unsigned_number (TYPE_VECTOR_SUBPARTS (type));
+ write_char ('_');
+ }
+ else
+ {
+ G.need_abi_warning = 1;
+ write_string ("U8__vector");
+ }
+ write_type (TREE_TYPE (type));
+ break;
+
+ case TYPE_PACK_EXPANSION:
+ write_string ("Dp");
+ write_type (PACK_EXPANSION_PATTERN (type));
+ break;
+
+ case DECLTYPE_TYPE:
+ /* These shouldn't make it into mangling. */
+ gcc_assert (!DECLTYPE_FOR_LAMBDA_CAPTURE (type)
+ && !DECLTYPE_FOR_LAMBDA_PROXY (type));
+
+ /* In ABI <5, we stripped decltype of a plain decl. */
+ if (!abi_version_at_least (5)
+ && DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type))
+ {
+ tree expr = DECLTYPE_TYPE_EXPR (type);
+ tree etype = NULL_TREE;
+ switch (TREE_CODE (expr))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ case FUNCTION_DECL:
+ case CONST_DECL:
+ case TEMPLATE_PARM_INDEX:
+ etype = TREE_TYPE (expr);
+ break;
+
+ default:
+ break;
+ }
+
+ if (etype && !type_uses_auto (etype))
+ {
+ G.need_abi_warning = 1;
+ write_type (etype);
+ return;
+ }
+ }
+
+ write_char ('D');
+ if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type))
+ write_char ('t');
+ else
+ write_char ('T');
+ ++cp_unevaluated_operand;
+ write_expression (DECLTYPE_TYPE_EXPR (type));
+ --cp_unevaluated_operand;
+ write_char ('E');
+ break;
+
+ case NULLPTR_TYPE:
+ write_string ("Dn");
+ if (abi_version_at_least (7))
+ ++is_builtin_type;
+ break;
+
+ case TYPEOF_TYPE:
+ sorry ("mangling typeof, use decltype instead");
+ break;
+
+ case UNDERLYING_TYPE:
+ sorry ("mangling __underlying_type");
+ break;
+
+ case LANG_TYPE:
+ /* fall through. */
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+ }
+
+ /* Types other than builtin types are substitution candidates. */
+ if (!is_builtin_type)
+ add_substitution (type);
+}
+
+/* Non-terminal <CV-qualifiers> for type nodes. Returns the number of
+ CV-qualifiers written for TYPE.
+
+ <CV-qualifiers> ::= [r] [V] [K] */
+
+static int
+write_CV_qualifiers_for_type (const tree type)
+{
+ int num_qualifiers = 0;
+
+ /* The order is specified by:
+
+ "In cases where multiple order-insensitive qualifiers are
+ present, they should be ordered 'K' (closest to the base type),
+ 'V', 'r', and 'U' (farthest from the base type) ..."
+
+ Note that we do not use cp_type_quals below; given "const
+ int[3]", the "const" is emitted with the "int", not with the
+ array. */
+ cp_cv_quals quals = TYPE_QUALS (type);
+
+ if (quals & TYPE_QUAL_RESTRICT)
+ {
+ write_char ('r');
+ ++num_qualifiers;
+ }
+ if (quals & TYPE_QUAL_VOLATILE)
+ {
+ write_char ('V');
+ ++num_qualifiers;
+ }
+ if (quals & TYPE_QUAL_CONST)
+ {
+ write_char ('K');
+ ++num_qualifiers;
+ }
+
+ return num_qualifiers;
+}
+
+/* Non-terminal <builtin-type>.
+
+ <builtin-type> ::= v # void
+ ::= b # bool
+ ::= w # wchar_t
+ ::= c # char
+ ::= a # signed char
+ ::= h # unsigned char
+ ::= s # short
+ ::= t # unsigned short
+ ::= i # int
+ ::= j # unsigned int
+ ::= l # long
+ ::= m # unsigned long
+ ::= x # long long, __int64
+ ::= y # unsigned long long, __int64
+ ::= n # __int128
+ ::= o # unsigned __int128
+ ::= f # float
+ ::= d # double
+ ::= e # long double, __float80
+ ::= g # __float128 [not supported]
+ ::= u <source-name> # vendor extended type */
+
+static void
+write_builtin_type (tree type)
+{
+ if (TYPE_CANONICAL (type))
+ type = TYPE_CANONICAL (type);
+
+ switch (TREE_CODE (type))
+ {
+ case VOID_TYPE:
+ write_char ('v');
+ break;
+
+ case BOOLEAN_TYPE:
+ write_char ('b');
+ break;
+
+ case INTEGER_TYPE:
+ /* TYPE may still be wchar_t, char16_t, or char32_t, since that
+ isn't in integer_type_nodes. */
+ if (type == wchar_type_node)
+ write_char ('w');
+ else if (type == char16_type_node)
+ write_string ("Ds");
+ else if (type == char32_type_node)
+ write_string ("Di");
+ else if (TYPE_FOR_JAVA (type))
+ write_java_integer_type_codes (type);
+ else
+ {
+ size_t itk;
+ /* Assume TYPE is one of the shared integer type nodes. Find
+ it in the array of these nodes. */
+ iagain:
+ for (itk = 0; itk < itk_none; ++itk)
+ if (integer_types[itk] != NULL_TREE
+ && type == integer_types[itk])
+ {
+ /* Print the corresponding single-letter code. */
+ write_char (integer_type_codes[itk]);
+ break;
+ }
+
+ if (itk == itk_none)
+ {
+ tree t = c_common_type_for_mode (TYPE_MODE (type),
+ TYPE_UNSIGNED (type));
+ if (type != t)
+ {
+ type = t;
+ goto iagain;
+ }
+
+ if (TYPE_PRECISION (type) == 128)
+ write_char (TYPE_UNSIGNED (type) ? 'o' : 'n');
+ else
+ {
+ /* Allow for cases where TYPE is not one of the shared
+ integer type nodes and write a "vendor extended builtin
+ type" with a name the form intN or uintN, respectively.
+ Situations like this can happen if you have an
+ __attribute__((__mode__(__SI__))) type and use exotic
+ switches like '-mint8' on AVR. Of course, this is
+ undefined by the C++ ABI (and '-mint8' is not even
+ Standard C conforming), but when using such special
+ options you're pretty much in nowhere land anyway. */
+ const char *prefix;
+ char prec[11]; /* up to ten digits for an unsigned */
+
+ prefix = TYPE_UNSIGNED (type) ? "uint" : "int";
+ sprintf (prec, "%u", (unsigned) TYPE_PRECISION (type));
+ write_char ('u'); /* "vendor extended builtin type" */
+ write_unsigned_number (strlen (prefix) + strlen (prec));
+ write_string (prefix);
+ write_string (prec);
+ }
+ }
+ }
+ break;
+
+ case REAL_TYPE:
+ if (type == float_type_node
+ || type == java_float_type_node)
+ write_char ('f');
+ else if (type == double_type_node
+ || type == java_double_type_node)
+ write_char ('d');
+ else if (type == long_double_type_node)
+ write_char ('e');
+ else if (type == dfloat32_type_node)
+ write_string ("Df");
+ else if (type == dfloat64_type_node)
+ write_string ("Dd");
+ else if (type == dfloat128_type_node)
+ write_string ("De");
+ else
+ gcc_unreachable ();
+ break;
+
+ case FIXED_POINT_TYPE:
+ write_string ("DF");
+ if (GET_MODE_IBIT (TYPE_MODE (type)) > 0)
+ write_unsigned_number (GET_MODE_IBIT (TYPE_MODE (type)));
+ if (type == fract_type_node
+ || type == sat_fract_type_node
+ || type == accum_type_node
+ || type == sat_accum_type_node)
+ write_char ('i');
+ else if (type == unsigned_fract_type_node
+ || type == sat_unsigned_fract_type_node
+ || type == unsigned_accum_type_node
+ || type == sat_unsigned_accum_type_node)
+ write_char ('j');
+ else if (type == short_fract_type_node
+ || type == sat_short_fract_type_node
+ || type == short_accum_type_node
+ || type == sat_short_accum_type_node)
+ write_char ('s');
+ else if (type == unsigned_short_fract_type_node
+ || type == sat_unsigned_short_fract_type_node
+ || type == unsigned_short_accum_type_node
+ || type == sat_unsigned_short_accum_type_node)
+ write_char ('t');
+ else if (type == long_fract_type_node
+ || type == sat_long_fract_type_node
+ || type == long_accum_type_node
+ || type == sat_long_accum_type_node)
+ write_char ('l');
+ else if (type == unsigned_long_fract_type_node
+ || type == sat_unsigned_long_fract_type_node
+ || type == unsigned_long_accum_type_node
+ || type == sat_unsigned_long_accum_type_node)
+ write_char ('m');
+ else if (type == long_long_fract_type_node
+ || type == sat_long_long_fract_type_node
+ || type == long_long_accum_type_node
+ || type == sat_long_long_accum_type_node)
+ write_char ('x');
+ else if (type == unsigned_long_long_fract_type_node
+ || type == sat_unsigned_long_long_fract_type_node
+ || type == unsigned_long_long_accum_type_node
+ || type == sat_unsigned_long_long_accum_type_node)
+ write_char ('y');
+ else
+ sorry ("mangling unknown fixed point type");
+ write_unsigned_number (GET_MODE_FBIT (TYPE_MODE (type)));
+ if (TYPE_SATURATING (type))
+ write_char ('s');
+ else
+ write_char ('n');
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Non-terminal <function-type>. NODE is a FUNCTION_TYPE or
+ METHOD_TYPE. The return type is mangled before the parameter
+ types.
+
+ <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E */
+
+static void
+write_function_type (const tree type)
+{
+ MANGLE_TRACE_TREE ("function-type", type);
+
+ /* For a pointer to member function, the function type may have
+ cv-qualifiers, indicating the quals for the artificial 'this'
+ parameter. */
+ if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ /* The first parameter must be a POINTER_TYPE pointing to the
+ `this' parameter. */
+ tree this_type = class_of_this_parm (type);
+ write_CV_qualifiers_for_type (this_type);
+ }
+
+ write_char ('F');
+ /* We don't track whether or not a type is `extern "C"'. Note that
+ you can have an `extern "C"' function that does not have
+ `extern "C"' type, and vice versa:
+
+ extern "C" typedef void function_t();
+ function_t f; // f has C++ linkage, but its type is
+ // `extern "C"'
+
+ typedef void function_t();
+ extern "C" function_t f; // Vice versa.
+
+ See [dcl.link]. */
+ write_bare_function_type (type, /*include_return_type_p=*/1,
+ /*decl=*/NULL);
+ if (FUNCTION_REF_QUALIFIED (type))
+ {
+ if (FUNCTION_RVALUE_QUALIFIED (type))
+ write_char ('O');
+ else
+ write_char ('R');
+ }
+ write_char ('E');
+}
+
+/* Non-terminal <bare-function-type>. TYPE is a FUNCTION_TYPE or
+ METHOD_TYPE. If INCLUDE_RETURN_TYPE is nonzero, the return value
+ is mangled before the parameter types. If non-NULL, DECL is
+ FUNCTION_DECL for the function whose type is being emitted.
+
+ If DECL is a member of a Java type, then a literal 'J'
+ is output and the return type is mangled as if INCLUDE_RETURN_TYPE
+ were nonzero.
+
+ <bare-function-type> ::= [J]</signature/ type>+ */
+
+static void
+write_bare_function_type (const tree type, const int include_return_type_p,
+ const tree decl)
+{
+ int java_method_p;
+
+ MANGLE_TRACE_TREE ("bare-function-type", type);
+
+ /* Detect Java methods and emit special encoding. */
+ if (decl != NULL
+ && DECL_FUNCTION_MEMBER_P (decl)
+ && TYPE_FOR_JAVA (DECL_CONTEXT (decl))
+ && !DECL_CONSTRUCTOR_P (decl)
+ && !DECL_DESTRUCTOR_P (decl)
+ && !DECL_CONV_FN_P (decl))
+ {
+ java_method_p = 1;
+ write_char ('J');
+ }
+ else
+ {
+ java_method_p = 0;
+ }
+
+ /* Mangle the return type, if requested. */
+ if (include_return_type_p || java_method_p)
+ write_type (TREE_TYPE (type));
+
+ /* Now mangle the types of the arguments. */
+ ++G.parm_depth;
+ write_method_parms (TYPE_ARG_TYPES (type),
+ TREE_CODE (type) == METHOD_TYPE,
+ decl);
+ --G.parm_depth;
+}
+
+/* Write the mangled representation of a method parameter list of
+ types given in PARM_TYPES. If METHOD_P is nonzero, the function is
+ considered a non-static method, and the this parameter is omitted.
+ If non-NULL, DECL is the FUNCTION_DECL for the function whose
+ parameters are being emitted. */
+
+static void
+write_method_parms (tree parm_types, const int method_p, const tree decl)
+{
+ tree first_parm_type;
+ tree parm_decl = decl ? DECL_ARGUMENTS (decl) : NULL_TREE;
+
+ /* Assume this parameter type list is variable-length. If it ends
+ with a void type, then it's not. */
+ int varargs_p = 1;
+
+ /* If this is a member function, skip the first arg, which is the
+ this pointer.
+ "Member functions do not encode the type of their implicit this
+ parameter."
+
+ Similarly, there's no need to mangle artificial parameters, like
+ the VTT parameters for constructors and destructors. */
+ if (method_p)
+ {
+ parm_types = TREE_CHAIN (parm_types);
+ parm_decl = parm_decl ? DECL_CHAIN (parm_decl) : NULL_TREE;
+
+ while (parm_decl && DECL_ARTIFICIAL (parm_decl))
+ {
+ parm_types = TREE_CHAIN (parm_types);
+ parm_decl = DECL_CHAIN (parm_decl);
+ }
+ }
+
+ for (first_parm_type = parm_types;
+ parm_types;
+ parm_types = TREE_CHAIN (parm_types))
+ {
+ tree parm = TREE_VALUE (parm_types);
+ if (parm == void_type_node)
+ {
+ /* "Empty parameter lists, whether declared as () or
+ conventionally as (void), are encoded with a void parameter
+ (v)." */
+ if (parm_types == first_parm_type)
+ write_type (parm);
+ /* If the parm list is terminated with a void type, it's
+ fixed-length. */
+ varargs_p = 0;
+ /* A void type better be the last one. */
+ gcc_assert (TREE_CHAIN (parm_types) == NULL);
+ }
+ else
+ write_type (parm);
+ }
+
+ if (varargs_p)
+ /* <builtin-type> ::= z # ellipsis */
+ write_char ('z');
+}
+
+/* <class-enum-type> ::= <name> */
+
+static void
+write_class_enum_type (const tree type)
+{
+ write_name (TYPE_NAME (type), /*ignore_local_scope=*/0);
+}
+
+/* Non-terminal <template-args>. ARGS is a TREE_VEC of template
+ arguments.
+
+ <template-args> ::= I <template-arg>* E */
+
+static void
+write_template_args (tree args)
+{
+ int i;
+ int length = 0;
+
+ MANGLE_TRACE_TREE ("template-args", args);
+
+ write_char ('I');
+
+ if (args)
+ length = TREE_VEC_LENGTH (args);
+
+ if (args && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
+ {
+ /* We have nested template args. We want the innermost template
+ argument list. */
+ args = TREE_VEC_ELT (args, length - 1);
+ length = TREE_VEC_LENGTH (args);
+ }
+ for (i = 0; i < length; ++i)
+ write_template_arg (TREE_VEC_ELT (args, i));
+
+ write_char ('E');
+}
+
+/* Write out the
+ <unqualified-name>
+ <unqualified-name> <template-args>
+ part of SCOPE_REF or COMPONENT_REF mangling. */
+
+static void
+write_member_name (tree member)
+{
+ if (identifier_p (member))
+ write_unqualified_id (member);
+ else if (DECL_P (member))
+ write_unqualified_name (member);
+ else if (TREE_CODE (member) == TEMPLATE_ID_EXPR)
+ {
+ tree name = TREE_OPERAND (member, 0);
+ if (TREE_CODE (name) == OVERLOAD)
+ name = OVL_FUNCTION (name);
+ write_member_name (name);
+ write_template_args (TREE_OPERAND (member, 1));
+ }
+ else
+ write_expression (member);
+}
+
+/* <expression> ::= <unary operator-name> <expression>
+ ::= <binary operator-name> <expression> <expression>
+ ::= <expr-primary>
+
+ <expr-primary> ::= <template-param>
+ ::= L <type> <value number> E # literal
+ ::= L <mangled-name> E # external name
+ ::= st <type> # sizeof
+ ::= sr <type> <unqualified-name> # dependent name
+ ::= sr <type> <unqualified-name> <template-args> */
+
+static void
+write_expression (tree expr)
+{
+ enum tree_code code = TREE_CODE (expr);
+
+ /* Skip NOP_EXPRs. They can occur when (say) a pointer argument
+ is converted (via qualification conversions) to another
+ type. */
+ while (TREE_CODE (expr) == NOP_EXPR
+ /* Parentheses aren't mangled. */
+ || code == PAREN_EXPR
+ || TREE_CODE (expr) == NON_LVALUE_EXPR)
+ {
+ expr = TREE_OPERAND (expr, 0);
+ code = TREE_CODE (expr);
+ }
+
+ if (code == BASELINK
+ && (!type_unknown_p (expr)
+ || !BASELINK_QUALIFIED_P (expr)))
+ {
+ expr = BASELINK_FUNCTIONS (expr);
+ code = TREE_CODE (expr);
+ }
+
+ /* Handle pointers-to-members by making them look like expression
+ nodes. */
+ if (code == PTRMEM_CST)
+ {
+ expr = build_nt (ADDR_EXPR,
+ build_qualified_name (/*type=*/NULL_TREE,
+ PTRMEM_CST_CLASS (expr),
+ PTRMEM_CST_MEMBER (expr),
+ /*template_p=*/false));
+ code = TREE_CODE (expr);
+ }
+
+ /* Handle template parameters. */
+ if (code == TEMPLATE_TYPE_PARM
+ || code == TEMPLATE_TEMPLATE_PARM
+ || code == BOUND_TEMPLATE_TEMPLATE_PARM
+ || code == TEMPLATE_PARM_INDEX)
+ write_template_param (expr);
+ /* Handle literals. */
+ else if (TREE_CODE_CLASS (code) == tcc_constant
+ || (abi_version_at_least (2) && code == CONST_DECL))
+ write_template_arg_literal (expr);
+ else if (code == PARM_DECL && DECL_ARTIFICIAL (expr))
+ {
+ gcc_assert (!strcmp ("this", IDENTIFIER_POINTER (DECL_NAME (expr))));
+ write_string ("fpT");
+ }
+ else if (code == PARM_DECL)
+ {
+ /* A function parameter used in a late-specified return type. */
+ int index = DECL_PARM_INDEX (expr);
+ int level = DECL_PARM_LEVEL (expr);
+ int delta = G.parm_depth - level + 1;
+ gcc_assert (index >= 1);
+ write_char ('f');
+ if (delta != 0)
+ {
+ if (abi_version_at_least (5))
+ {
+ /* Let L be the number of function prototype scopes from the
+ innermost one (in which the parameter reference occurs) up
+ to (and including) the one containing the declaration of
+ the referenced parameter. If the parameter declaration
+ clause of the innermost function prototype scope has been
+ completely seen, it is not counted (in that case -- which
+ is perhaps the most common -- L can be zero). */
+ write_char ('L');
+ write_unsigned_number (delta - 1);
+ }
+ else
+ G.need_abi_warning = true;
+ }
+ write_char ('p');
+ write_compact_number (index - 1);
+ }
+ else if (DECL_P (expr))
+ {
+ /* G++ 3.2 incorrectly mangled non-type template arguments of
+ enumeration type using their names. */
+ if (code == CONST_DECL)
+ G.need_abi_warning = 1;
+ write_char ('L');
+ write_mangled_name (expr, false);
+ write_char ('E');
+ }
+ else if (TREE_CODE (expr) == SIZEOF_EXPR
+ && SIZEOF_EXPR_TYPE_P (expr))
+ {
+ write_string ("st");
+ write_type (TREE_TYPE (TREE_OPERAND (expr, 0)));
+ }
+ else if (TREE_CODE (expr) == SIZEOF_EXPR
+ && TYPE_P (TREE_OPERAND (expr, 0)))
+ {
+ write_string ("st");
+ write_type (TREE_OPERAND (expr, 0));
+ }
+ else if (TREE_CODE (expr) == ALIGNOF_EXPR
+ && TYPE_P (TREE_OPERAND (expr, 0)))
+ {
+ write_string ("at");
+ write_type (TREE_OPERAND (expr, 0));
+ }
+ else if (code == SCOPE_REF
+ || code == BASELINK)
+ {
+ tree scope, member;
+ if (code == SCOPE_REF)
+ {
+ scope = TREE_OPERAND (expr, 0);
+ member = TREE_OPERAND (expr, 1);
+ }
+ else
+ {
+ scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (expr));
+ member = BASELINK_FUNCTIONS (expr);
+ }
+
+ if (!abi_version_at_least (2) && DECL_P (member))
+ {
+ write_string ("sr");
+ write_type (scope);
+ /* G++ 3.2 incorrectly put out both the "sr" code and
+ the nested name of the qualified name. */
+ G.need_abi_warning = 1;
+ write_encoding (member);
+ }
+
+ /* If the MEMBER is a real declaration, then the qualifying
+ scope was not dependent. Ideally, we would not have a
+ SCOPE_REF in those cases, but sometimes we do. If the second
+ argument is a DECL, then the name must not have been
+ dependent. */
+ else if (DECL_P (member))
+ write_expression (member);
+ else
+ {
+ write_string ("sr");
+ write_type (scope);
+ write_member_name (member);
+ }
+ }
+ else if (INDIRECT_REF_P (expr)
+ && TREE_TYPE (TREE_OPERAND (expr, 0))
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
+ {
+ write_expression (TREE_OPERAND (expr, 0));
+ }
+ else if (identifier_p (expr))
+ {
+ /* An operator name appearing as a dependent name needs to be
+ specially marked to disambiguate between a use of the operator
+ name and a use of the operator in an expression. */
+ if (IDENTIFIER_OPNAME_P (expr))
+ write_string ("on");
+ write_unqualified_id (expr);
+ }
+ else if (TREE_CODE (expr) == TEMPLATE_ID_EXPR)
+ {
+ tree fn = TREE_OPERAND (expr, 0);
+ if (is_overloaded_fn (fn))
+ fn = DECL_NAME (get_first_fn (fn));
+ if (IDENTIFIER_OPNAME_P (fn))
+ write_string ("on");
+ write_unqualified_id (fn);
+ write_template_args (TREE_OPERAND (expr, 1));
+ }
+ else if (TREE_CODE (expr) == MODOP_EXPR)
+ {
+ enum tree_code subop = TREE_CODE (TREE_OPERAND (expr, 1));
+ const char *name = (assignment_operator_name_info[(int) subop]
+ .mangled_name);
+ write_string (name);
+ write_expression (TREE_OPERAND (expr, 0));
+ write_expression (TREE_OPERAND (expr, 2));
+ }
+ else if (code == NEW_EXPR || code == VEC_NEW_EXPR)
+ {
+ /* ::= [gs] nw <expression>* _ <type> E
+ ::= [gs] nw <expression>* _ <type> <initializer>
+ ::= [gs] na <expression>* _ <type> E
+ ::= [gs] na <expression>* _ <type> <initializer>
+ <initializer> ::= pi <expression>* E */
+ tree placement = TREE_OPERAND (expr, 0);
+ tree type = TREE_OPERAND (expr, 1);
+ tree nelts = TREE_OPERAND (expr, 2);
+ tree init = TREE_OPERAND (expr, 3);
+ tree t;
+
+ gcc_assert (code == NEW_EXPR);
+ if (TREE_OPERAND (expr, 2))
+ code = VEC_NEW_EXPR;
+
+ if (NEW_EXPR_USE_GLOBAL (expr))
+ write_string ("gs");
+
+ write_string (operator_name_info[(int) code].mangled_name);
+
+ for (t = placement; t; t = TREE_CHAIN (t))
+ write_expression (TREE_VALUE (t));
+
+ write_char ('_');
+
+ if (nelts)
+ {
+ tree domain;
+ ++processing_template_decl;
+ domain = compute_array_index_type (NULL_TREE, nelts,
+ tf_warning_or_error);
+ type = build_cplus_array_type (type, domain);
+ --processing_template_decl;
+ }
+ write_type (type);
+
+ if (init && TREE_CODE (init) == TREE_LIST
+ && TREE_CODE (TREE_VALUE (init)) == CONSTRUCTOR
+ && CONSTRUCTOR_IS_DIRECT_INIT (TREE_VALUE (init)))
+ write_expression (TREE_VALUE (init));
+ else
+ {
+ if (init)
+ write_string ("pi");
+ if (init && init != void_zero_node)
+ for (t = init; t; t = TREE_CHAIN (t))
+ write_expression (TREE_VALUE (t));
+ write_char ('E');
+ }
+ }
+ else if (code == DELETE_EXPR || code == VEC_DELETE_EXPR)
+ {
+ gcc_assert (code == DELETE_EXPR);
+ if (DELETE_EXPR_USE_VEC (expr))
+ code = VEC_DELETE_EXPR;
+
+ if (DELETE_EXPR_USE_GLOBAL (expr))
+ write_string ("gs");
+
+ write_string (operator_name_info[(int) code].mangled_name);
+
+ write_expression (TREE_OPERAND (expr, 0));
+ }
+ else if (code == THROW_EXPR)
+ {
+ tree op = TREE_OPERAND (expr, 0);
+ if (op)
+ {
+ write_string ("tw");
+ write_expression (op);
+ }
+ else
+ write_string ("tr");
+ }
+ else if (code == CONSTRUCTOR)
+ {
+ vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (expr);
+ unsigned i; tree val;
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+ write_string ("il");
+ else
+ {
+ write_string ("tl");
+ write_type (TREE_TYPE (expr));
+ }
+ FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val)
+ write_expression (val);
+ write_char ('E');
+ }
+ else if (dependent_name (expr))
+ {
+ write_unqualified_id (dependent_name (expr));
+ }
+ else
+ {
+ int i, len;
+ const char *name;
+
+ /* When we bind a variable or function to a non-type template
+ argument with reference type, we create an ADDR_EXPR to show
+ the fact that the entity's address has been taken. But, we
+ don't actually want to output a mangling code for the `&'. */
+ if (TREE_CODE (expr) == ADDR_EXPR
+ && TREE_TYPE (expr)
+ && TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE)
+ {
+ expr = TREE_OPERAND (expr, 0);
+ if (DECL_P (expr))
+ {
+ write_expression (expr);
+ return;
+ }
+
+ code = TREE_CODE (expr);
+ }
+
+ if (code == COMPONENT_REF)
+ {
+ tree ob = TREE_OPERAND (expr, 0);
+
+ if (TREE_CODE (ob) == ARROW_EXPR)
+ {
+ write_string (operator_name_info[(int)code].mangled_name);
+ ob = TREE_OPERAND (ob, 0);
+ }
+ else
+ write_string ("dt");
+
+ write_expression (ob);
+ write_member_name (TREE_OPERAND (expr, 1));
+ return;
+ }
+
+ /* If it wasn't any of those, recursively expand the expression. */
+ name = operator_name_info[(int) code].mangled_name;
+
+ /* We used to mangle const_cast and static_cast like a C cast. */
+ if (!abi_version_at_least (6)
+ && (code == CONST_CAST_EXPR
+ || code == STATIC_CAST_EXPR))
+ {
+ name = operator_name_info[CAST_EXPR].mangled_name;
+ G.need_abi_warning = 1;
+ }
+
+ if (name == NULL)
+ {
+ switch (code)
+ {
+ case TRAIT_EXPR:
+ error ("use of built-in trait %qE in function signature; "
+ "use library traits instead", expr);
+ break;
+
+ default:
+ sorry ("mangling %C", code);
+ break;
+ }
+ return;
+ }
+ else
+ write_string (name);
+
+ switch (code)
+ {
+ case CALL_EXPR:
+ {
+ tree fn = CALL_EXPR_FN (expr);
+
+ if (TREE_CODE (fn) == ADDR_EXPR)
+ fn = TREE_OPERAND (fn, 0);
+
+ /* Mangle a dependent name as the name, not whatever happens to
+ be the first function in the overload set. */
+ if ((TREE_CODE (fn) == FUNCTION_DECL
+ || TREE_CODE (fn) == OVERLOAD)
+ && type_dependent_expression_p_push (expr))
+ fn = DECL_NAME (get_first_fn (fn));
+
+ write_expression (fn);
+ }
+
+ for (i = 0; i < call_expr_nargs (expr); ++i)
+ write_expression (CALL_EXPR_ARG (expr, i));
+ write_char ('E');
+ break;
+
+ case CAST_EXPR:
+ write_type (TREE_TYPE (expr));
+ if (list_length (TREE_OPERAND (expr, 0)) == 1)
+ write_expression (TREE_VALUE (TREE_OPERAND (expr, 0)));
+ else
+ {
+ tree args = TREE_OPERAND (expr, 0);
+ write_char ('_');
+ for (; args; args = TREE_CHAIN (args))
+ write_expression (TREE_VALUE (args));
+ write_char ('E');
+ }
+ break;
+
+ case DYNAMIC_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ write_type (TREE_TYPE (expr));
+ write_expression (TREE_OPERAND (expr, 0));
+ break;
+
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ if (abi_version_at_least (6))
+ write_char ('_');
+ else
+ G.need_abi_warning = 1;
+ /* Fall through. */
+
+ default:
+ /* In the middle-end, some expressions have more operands than
+ they do in templates (and mangling). */
+ len = cp_tree_operand_length (expr);
+
+ for (i = 0; i < len; ++i)
+ {
+ tree operand = TREE_OPERAND (expr, i);
+ /* As a GNU extension, the middle operand of a
+ conditional may be omitted. Since expression
+ manglings are supposed to represent the input token
+ stream, there's no good way to mangle such an
+ expression without extending the C++ ABI. */
+ if (code == COND_EXPR && i == 1 && !operand)
+ {
+ error ("omitted middle operand to %<?:%> operand "
+ "cannot be mangled");
+ continue;
+ }
+ write_expression (operand);
+ }
+ }
+ }
+}
+
+/* Literal subcase of non-terminal <template-arg>.
+
+ "Literal arguments, e.g. "A<42L>", are encoded with their type
+ and value. Negative integer values are preceded with "n"; for
+ example, "A<-42L>" becomes "1AILln42EE". The bool value false is
+ encoded as 0, true as 1." */
+
+static void
+write_template_arg_literal (const tree value)
+{
+ write_char ('L');
+ write_type (TREE_TYPE (value));
+
+ /* Write a null member pointer value as (type)0, regardless of its
+ real representation. */
+ if (null_member_pointer_value_p (value))
+ write_integer_cst (integer_zero_node);
+ else
+ switch (TREE_CODE (value))
+ {
+ case CONST_DECL:
+ write_integer_cst (DECL_INITIAL (value));
+ break;
+
+ case INTEGER_CST:
+ gcc_assert (!same_type_p (TREE_TYPE (value), boolean_type_node)
+ || integer_zerop (value) || integer_onep (value));
+ write_integer_cst (value);
+ break;
+
+ case REAL_CST:
+ write_real_cst (value);
+ break;
+
+ case COMPLEX_CST:
+ if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST
+ && TREE_CODE (TREE_IMAGPART (value)) == INTEGER_CST)
+ {
+ write_integer_cst (TREE_REALPART (value));
+ write_char ('_');
+ write_integer_cst (TREE_IMAGPART (value));
+ }
+ else if (TREE_CODE (TREE_REALPART (value)) == REAL_CST
+ && TREE_CODE (TREE_IMAGPART (value)) == REAL_CST)
+ {
+ write_real_cst (TREE_REALPART (value));
+ write_char ('_');
+ write_real_cst (TREE_IMAGPART (value));
+ }
+ else
+ gcc_unreachable ();
+ break;
+
+ case STRING_CST:
+ sorry ("string literal in function template signature");
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ write_char ('E');
+}
+
+/* Non-terminal <template-arg>.
+
+ <template-arg> ::= <type> # type
+ ::= L <type> </value/ number> E # literal
+ ::= LZ <name> E # external name
+ ::= X <expression> E # expression */
+
+static void
+write_template_arg (tree node)
+{
+ enum tree_code code = TREE_CODE (node);
+
+ MANGLE_TRACE_TREE ("template-arg", node);
+
+ /* A template template parameter's argument list contains TREE_LIST
+ nodes of which the value field is the actual argument. */
+ if (code == TREE_LIST)
+ {
+ node = TREE_VALUE (node);
+ /* If it's a decl, deal with its type instead. */
+ if (DECL_P (node))
+ {
+ node = TREE_TYPE (node);
+ code = TREE_CODE (node);
+ }
+ }
+
+ if (TREE_CODE (node) == NOP_EXPR
+ && TREE_CODE (TREE_TYPE (node)) == REFERENCE_TYPE)
+ {
+ /* Template parameters can be of reference type. To maintain
+ internal consistency, such arguments use a conversion from
+ address of object to reference type. */
+ gcc_assert (TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR);
+ if (abi_version_at_least (2))
+ node = TREE_OPERAND (TREE_OPERAND (node, 0), 0);
+ else
+ G.need_abi_warning = 1;
+ }
+
+ if (TREE_CODE (node) == BASELINK
+ && !type_unknown_p (node))
+ {
+ if (abi_version_at_least (6))
+ node = BASELINK_FUNCTIONS (node);
+ else
+ /* We wrongly wrapped a class-scope function in X/E. */
+ G.need_abi_warning = 1;
+ }
+
+ if (ARGUMENT_PACK_P (node))
+ {
+ /* Expand the template argument pack. */
+ tree args = ARGUMENT_PACK_ARGS (node);
+ int i, length = TREE_VEC_LENGTH (args);
+ if (abi_version_at_least (6))
+ write_char ('J');
+ else
+ {
+ write_char ('I');
+ G.need_abi_warning = 1;
+ }
+ for (i = 0; i < length; ++i)
+ write_template_arg (TREE_VEC_ELT (args, i));
+ write_char ('E');
+ }
+ else if (TYPE_P (node))
+ write_type (node);
+ else if (code == TEMPLATE_DECL)
+ /* A template appearing as a template arg is a template template arg. */
+ write_template_template_arg (node);
+ else if ((TREE_CODE_CLASS (code) == tcc_constant && code != PTRMEM_CST)
+ || (abi_version_at_least (2) && code == CONST_DECL)
+ || null_member_pointer_value_p (node))
+ write_template_arg_literal (node);
+ else if (DECL_P (node))
+ {
+ /* Until ABI version 2, non-type template arguments of
+ enumeration type were mangled using their names. */
+ if (code == CONST_DECL && !abi_version_at_least (2))
+ G.need_abi_warning = 1;
+ write_char ('L');
+ /* Until ABI version 3, the underscore before the mangled name
+ was incorrectly omitted. */
+ if (!abi_version_at_least (3))
+ {
+ G.need_abi_warning = 1;
+ write_char ('Z');
+ }
+ else
+ write_string ("_Z");
+ write_encoding (node);
+ write_char ('E');
+ }
+ else
+ {
+ /* Template arguments may be expressions. */
+ write_char ('X');
+ write_expression (node);
+ write_char ('E');
+ }
+}
+
+/* <template-template-arg>
+ ::= <name>
+ ::= <substitution> */
+
+static void
+write_template_template_arg (const tree decl)
+{
+ MANGLE_TRACE_TREE ("template-template-arg", decl);
+
+ if (find_substitution (decl))
+ return;
+ write_name (decl, /*ignore_local_scope=*/0);
+ add_substitution (decl);
+}
+
+
+/* Non-terminal <array-type>. TYPE is an ARRAY_TYPE.
+
+ <array-type> ::= A [</dimension/ number>] _ </element/ type>
+ ::= A <expression> _ </element/ type>
+
+ "Array types encode the dimension (number of elements) and the
+ element type. For variable length arrays, the dimension (but not
+ the '_' separator) is omitted." */
+
+static void
+write_array_type (const tree type)
+{
+ write_char ('A');
+ if (TYPE_DOMAIN (type))
+ {
+ tree index_type;
+ tree max;
+
+ index_type = TYPE_DOMAIN (type);
+ /* The INDEX_TYPE gives the upper and lower bounds of the
+ array. */
+ max = TYPE_MAX_VALUE (index_type);
+ if (TREE_CODE (max) == INTEGER_CST)
+ {
+ /* The ABI specifies that we should mangle the number of
+ elements in the array, not the largest allowed index. */
+ double_int dmax = tree_to_double_int (max) + double_int_one;
+ /* Truncate the result - this will mangle [0, SIZE_INT_MAX]
+ number of elements as zero. */
+ dmax = dmax.zext (TYPE_PRECISION (TREE_TYPE (max)));
+ gcc_assert (dmax.fits_uhwi ());
+ write_unsigned_number (dmax.low);
+ }
+ else
+ {
+ max = TREE_OPERAND (max, 0);
+ if (!abi_version_at_least (2))
+ {
+ /* value_dependent_expression_p presumes nothing is
+ dependent when PROCESSING_TEMPLATE_DECL is zero. */
+ ++processing_template_decl;
+ if (!value_dependent_expression_p (max))
+ G.need_abi_warning = 1;
+ --processing_template_decl;
+ }
+ write_expression (max);
+ }
+
+ }
+ write_char ('_');
+ write_type (TREE_TYPE (type));
+}
+
+/* Non-terminal <pointer-to-member-type> for pointer-to-member
+ variables. TYPE is a pointer-to-member POINTER_TYPE.
+
+ <pointer-to-member-type> ::= M </class/ type> </member/ type> */
+
+static void
+write_pointer_to_member_type (const tree type)
+{
+ write_char ('M');
+ write_type (TYPE_PTRMEM_CLASS_TYPE (type));
+ write_type (TYPE_PTRMEM_POINTED_TO_TYPE (type));
+}
+
+/* Non-terminal <template-param>. PARM is a TEMPLATE_TYPE_PARM,
+ TEMPLATE_TEMPLATE_PARM, BOUND_TEMPLATE_TEMPLATE_PARM or a
+ TEMPLATE_PARM_INDEX.
+
+ <template-param> ::= T </parameter/ number> _ */
+
+static void
+write_template_param (const tree parm)
+{
+ int parm_index;
+
+ MANGLE_TRACE_TREE ("template-parm", parm);
+
+ switch (TREE_CODE (parm))
+ {
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ parm_index = TEMPLATE_TYPE_IDX (parm);
+ break;
+
+ case TEMPLATE_PARM_INDEX:
+ parm_index = TEMPLATE_PARM_IDX (parm);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ write_char ('T');
+ /* NUMBER as it appears in the mangling is (-1)-indexed, with the
+ earliest template param denoted by `_'. */
+ write_compact_number (parm_index);
+}
+
+/* <template-template-param>
+ ::= <template-param>
+ ::= <substitution> */
+
+static void
+write_template_template_param (const tree parm)
+{
+ tree templ = NULL_TREE;
+
+ /* PARM, a TEMPLATE_TEMPLATE_PARM, is an instantiation of the
+ template template parameter. The substitution candidate here is
+ only the template. */
+ if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ {
+ templ
+ = TI_TEMPLATE (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm));
+ if (find_substitution (templ))
+ return;
+ }
+
+ /* <template-param> encodes only the template parameter position,
+ not its template arguments, which is fine here. */
+ write_template_param (parm);
+ if (templ)
+ add_substitution (templ);
+}
+
+/* Non-terminal <substitution>.
+
+ <substitution> ::= S <seq-id> _
+ ::= S_ */
+
+static void
+write_substitution (const int seq_id)
+{
+ MANGLE_TRACE ("substitution", "");
+
+ write_char ('S');
+ if (seq_id > 0)
+ write_number (seq_id - 1, /*unsigned=*/1, 36);
+ write_char ('_');
+}
+
+/* Start mangling ENTITY. */
+
+static inline void
+start_mangling (const tree entity)
+{
+ G.entity = entity;
+ G.need_abi_warning = false;
+ obstack_free (&name_obstack, name_base);
+ mangle_obstack = &name_obstack;
+ name_base = obstack_alloc (&name_obstack, 0);
+}
+
+/* Done with mangling. If WARN is true, and the name of G.entity will
+ be mangled differently in a future version of the ABI, issue a
+ warning. */
+
+static void
+finish_mangling_internal (const bool warn)
+{
+ if (warn_abi && warn && G.need_abi_warning)
+ warning (OPT_Wabi, "the mangled name of %qD will change in a future "
+ "version of GCC",
+ G.entity);
+
+ /* Clear all the substitutions. */
+ vec_safe_truncate (G.substitutions, 0);
+
+ /* Null-terminate the string. */
+ write_char ('\0');
+}
+
+
+/* Like finish_mangling_internal, but return the mangled string. */
+
+static inline const char *
+finish_mangling (const bool warn)
+{
+ finish_mangling_internal (warn);
+ return (const char *) obstack_finish (mangle_obstack);
+}
+
+/* Like finish_mangling_internal, but return an identifier. */
+
+static tree
+finish_mangling_get_identifier (const bool warn)
+{
+ finish_mangling_internal (warn);
+ /* Don't obstack_finish here, and the next start_mangling will
+ remove the identifier. */
+ return get_identifier ((const char *) obstack_base (mangle_obstack));
+}
+
+/* Initialize data structures for mangling. */
+
+void
+init_mangle (void)
+{
+ gcc_obstack_init (&name_obstack);
+ name_base = obstack_alloc (&name_obstack, 0);
+ vec_alloc (G.substitutions, 0);
+
+ /* Cache these identifiers for quick comparison when checking for
+ standard substitutions. */
+ subst_identifiers[SUBID_ALLOCATOR] = get_identifier ("allocator");
+ subst_identifiers[SUBID_BASIC_STRING] = get_identifier ("basic_string");
+ subst_identifiers[SUBID_CHAR_TRAITS] = get_identifier ("char_traits");
+ subst_identifiers[SUBID_BASIC_ISTREAM] = get_identifier ("basic_istream");
+ subst_identifiers[SUBID_BASIC_OSTREAM] = get_identifier ("basic_ostream");
+ subst_identifiers[SUBID_BASIC_IOSTREAM] = get_identifier ("basic_iostream");
+}
+
+/* Generate the mangled name of DECL. */
+
+static tree
+mangle_decl_string (const tree decl)
+{
+ tree result;
+ location_t saved_loc = input_location;
+ tree saved_fn = NULL_TREE;
+ bool template_p = false;
+
+ /* We shouldn't be trying to mangle an uninstantiated template. */
+ gcc_assert (!type_dependent_expression_p (decl));
+
+ if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
+ {
+ struct tinst_level *tl = current_instantiation ();
+ if ((!tl || tl->decl != decl)
+ && push_tinst_level (decl))
+ {
+ template_p = true;
+ saved_fn = current_function_decl;
+ current_function_decl = NULL_TREE;
+ }
+ }
+ input_location = DECL_SOURCE_LOCATION (decl);
+
+ start_mangling (decl);
+
+ if (TREE_CODE (decl) == TYPE_DECL)
+ write_type (TREE_TYPE (decl));
+ else
+ write_mangled_name (decl, true);
+
+ result = finish_mangling_get_identifier (/*warn=*/true);
+ if (DEBUG_MANGLE)
+ fprintf (stderr, "mangle_decl_string = '%s'\n\n",
+ IDENTIFIER_POINTER (result));
+
+ if (template_p)
+ {
+ pop_tinst_level ();
+ current_function_decl = saved_fn;
+ }
+ input_location = saved_loc;
+
+ return result;
+}
+
+/* Return an identifier for the external mangled name of DECL. */
+
+static tree
+get_mangled_id (tree decl)
+{
+ tree id = mangle_decl_string (decl);
+ return targetm.mangle_decl_assembler_name (decl, id);
+}
+
+/* Create an identifier for the external mangled name of DECL. */
+
+void
+mangle_decl (const tree decl)
+{
+ tree id;
+ bool dep;
+
+ /* Don't bother mangling uninstantiated templates. */
+ ++processing_template_decl;
+ if (TREE_CODE (decl) == TYPE_DECL)
+ dep = dependent_type_p (TREE_TYPE (decl));
+ else
+ dep = (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
+ && any_dependent_template_arguments_p (DECL_TI_ARGS (decl)));
+ --processing_template_decl;
+ if (dep)
+ return;
+
+ id = get_mangled_id (decl);
+ SET_DECL_ASSEMBLER_NAME (decl, id);
+
+ if (G.need_abi_warning
+ /* Don't do this for a fake symbol we aren't going to emit anyway. */
+ && TREE_CODE (decl) != TYPE_DECL
+ && !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
+ && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
+ {
+#ifdef ASM_OUTPUT_DEF
+ /* If the mangling will change in the future, emit an alias with the
+ future mangled name for forward-compatibility. */
+ int save_ver;
+ tree id2, alias;
+#endif
+
+ SET_IDENTIFIER_GLOBAL_VALUE (id, decl);
+ if (IDENTIFIER_GLOBAL_VALUE (id) != decl)
+ inform (DECL_SOURCE_LOCATION (decl), "-fabi-version=6 (or =0) "
+ "avoids this error with a change in mangling");
+
+#ifdef ASM_OUTPUT_DEF
+ save_ver = flag_abi_version;
+ flag_abi_version = 0;
+ id2 = mangle_decl_string (decl);
+ id2 = targetm.mangle_decl_assembler_name (decl, id2);
+ flag_abi_version = save_ver;
+
+ alias = make_alias_for (decl, id2);
+ DECL_IGNORED_P (alias) = 1;
+ TREE_PUBLIC (alias) = TREE_PUBLIC (decl);
+ DECL_VISIBILITY (alias) = DECL_VISIBILITY (decl);
+ if (vague_linkage_p (decl))
+ DECL_WEAK (alias) = 1;
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ cgraph_same_body_alias (cgraph_get_create_node (decl), alias, decl);
+ else
+ varpool_extra_name_alias (alias, decl);
+#endif
+ }
+}
+
+/* Generate the mangled representation of TYPE. */
+
+const char *
+mangle_type_string (const tree type)
+{
+ const char *result;
+
+ start_mangling (type);
+ write_type (type);
+ result = finish_mangling (/*warn=*/false);
+ if (DEBUG_MANGLE)
+ fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
+ return result;
+}
+
+/* Create an identifier for the mangled name of a special component
+ for belonging to TYPE. CODE is the ABI-specified code for this
+ component. */
+
+static tree
+mangle_special_for_type (const tree type, const char *code)
+{
+ tree result;
+
+ /* We don't have an actual decl here for the special component, so
+ we can't just process the <encoded-name>. Instead, fake it. */
+ start_mangling (type);
+
+ /* Start the mangling. */
+ write_string ("_Z");
+ write_string (code);
+
+ /* Add the type. */
+ write_type (type);
+ result = finish_mangling_get_identifier (/*warn=*/false);
+
+ if (DEBUG_MANGLE)
+ fprintf (stderr, "mangle_special_for_type = %s\n\n",
+ IDENTIFIER_POINTER (result));
+
+ return result;
+}
+
+/* Create an identifier for the mangled representation of the typeinfo
+ structure for TYPE. */
+
+tree
+mangle_typeinfo_for_type (const tree type)
+{
+ return mangle_special_for_type (type, "TI");
+}
+
+/* Create an identifier for the mangled name of the NTBS containing
+ the mangled name of TYPE. */
+
+tree
+mangle_typeinfo_string_for_type (const tree type)
+{
+ return mangle_special_for_type (type, "TS");
+}
+
+/* Create an identifier for the mangled name of the vtable for TYPE. */
+
+tree
+mangle_vtbl_for_type (const tree type)
+{
+ return mangle_special_for_type (type, "TV");
+}
+
+/* Returns an identifier for the mangled name of the VTT for TYPE. */
+
+tree
+mangle_vtt_for_type (const tree type)
+{
+ return mangle_special_for_type (type, "TT");
+}
+
+/* Return an identifier for a construction vtable group. TYPE is
+ the most derived class in the hierarchy; BINFO is the base
+ subobject for which this construction vtable group will be used.
+
+ This mangling isn't part of the ABI specification; in the ABI
+ specification, the vtable group is dumped in the same COMDAT as the
+ main vtable, and is referenced only from that vtable, so it doesn't
+ need an external name. For binary formats without COMDAT sections,
+ though, we need external names for the vtable groups.
+
+ We use the production
+
+ <special-name> ::= CT <type> <offset number> _ <base type> */
+
+tree
+mangle_ctor_vtbl_for_type (const tree type, const tree binfo)
+{
+ tree result;
+
+ start_mangling (type);
+
+ write_string ("_Z");
+ write_string ("TC");
+ write_type (type);
+ write_integer_cst (BINFO_OFFSET (binfo));
+ write_char ('_');
+ write_type (BINFO_TYPE (binfo));
+
+ result = finish_mangling_get_identifier (/*warn=*/false);
+ if (DEBUG_MANGLE)
+ fprintf (stderr, "mangle_ctor_vtbl_for_type = %s\n\n",
+ IDENTIFIER_POINTER (result));
+ return result;
+}
+
+/* Mangle a this pointer or result pointer adjustment.
+
+ <call-offset> ::= h <fixed offset number> _
+ ::= v <fixed offset number> _ <virtual offset number> _ */
+
+static void
+mangle_call_offset (const tree fixed_offset, const tree virtual_offset)
+{
+ write_char (virtual_offset ? 'v' : 'h');
+
+ /* For either flavor, write the fixed offset. */
+ write_integer_cst (fixed_offset);
+ write_char ('_');
+
+ /* For a virtual thunk, add the virtual offset. */
+ if (virtual_offset)
+ {
+ write_integer_cst (virtual_offset);
+ write_char ('_');
+ }
+}
+
+/* Return an identifier for the mangled name of a this-adjusting or
+ covariant thunk to FN_DECL. FIXED_OFFSET is the initial adjustment
+ to this used to find the vptr. If VIRTUAL_OFFSET is non-NULL, this
+ is a virtual thunk, and it is the vtbl offset in
+ bytes. THIS_ADJUSTING is nonzero for a this adjusting thunk and
+ zero for a covariant thunk. Note, that FN_DECL might be a covariant
+ thunk itself. A covariant thunk name always includes the adjustment
+ for the this pointer, even if there is none.
+
+ <special-name> ::= T <call-offset> <base encoding>
+ ::= Tc <this_adjust call-offset> <result_adjust call-offset>
+ <base encoding> */
+
+tree
+mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset,
+ tree virtual_offset)
+{
+ tree result;
+
+ start_mangling (fn_decl);
+
+ write_string ("_Z");
+ write_char ('T');
+
+ if (!this_adjusting)
+ {
+ /* Covariant thunk with no this adjustment */
+ write_char ('c');
+ mangle_call_offset (integer_zero_node, NULL_TREE);
+ mangle_call_offset (fixed_offset, virtual_offset);
+ }
+ else if (!DECL_THUNK_P (fn_decl))
+ /* Plain this adjusting thunk. */
+ mangle_call_offset (fixed_offset, virtual_offset);
+ else
+ {
+ /* This adjusting thunk to covariant thunk. */
+ write_char ('c');
+ mangle_call_offset (fixed_offset, virtual_offset);
+ fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn_decl));
+ virtual_offset = THUNK_VIRTUAL_OFFSET (fn_decl);
+ if (virtual_offset)
+ virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
+ mangle_call_offset (fixed_offset, virtual_offset);
+ fn_decl = THUNK_TARGET (fn_decl);
+ }
+
+ /* Scoped name. */
+ write_encoding (fn_decl);
+
+ result = finish_mangling_get_identifier (/*warn=*/false);
+ if (DEBUG_MANGLE)
+ fprintf (stderr, "mangle_thunk = %s\n\n", IDENTIFIER_POINTER (result));
+ return result;
+}
+
+/* This hash table maps TYPEs to the IDENTIFIER for a conversion
+ operator to TYPE. The nodes are IDENTIFIERs whose TREE_TYPE is the
+ TYPE. */
+
+static GTY ((param_is (union tree_node))) htab_t conv_type_names;
+
+/* Hash a node (VAL1) in the table. */
+
+static hashval_t
+hash_type (const void *val)
+{
+ return (hashval_t) TYPE_UID (TREE_TYPE ((const_tree) val));
+}
+
+/* Compare VAL1 (a node in the table) with VAL2 (a TYPE). */
+
+static int
+compare_type (const void *val1, const void *val2)
+{
+ return TREE_TYPE ((const_tree) val1) == (const_tree) val2;
+}
+
+/* Return an identifier for the mangled unqualified name for a
+ conversion operator to TYPE. This mangling is not specified by the
+ ABI spec; it is only used internally. */
+
+tree
+mangle_conv_op_name_for_type (const tree type)
+{
+ void **slot;
+ tree identifier;
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ if (conv_type_names == NULL)
+ conv_type_names = htab_create_ggc (31, &hash_type, &compare_type, NULL);
+
+ slot = htab_find_slot_with_hash (conv_type_names, type,
+ (hashval_t) TYPE_UID (type), INSERT);
+ identifier = (tree)*slot;
+ if (!identifier)
+ {
+ char buffer[64];
+
+ /* Create a unique name corresponding to TYPE. */
+ sprintf (buffer, "operator %lu",
+ (unsigned long) htab_elements (conv_type_names));
+ identifier = get_identifier (buffer);
+ *slot = identifier;
+
+ /* Hang TYPE off the identifier so it can be found easily later
+ when performing conversions. */
+ TREE_TYPE (identifier) = type;
+
+ /* Set bits on the identifier so we know later it's a conversion. */
+ IDENTIFIER_OPNAME_P (identifier) = 1;
+ IDENTIFIER_TYPENAME_P (identifier) = 1;
+ }
+
+ return identifier;
+}
+
+/* Write out the appropriate string for this variable when generating
+ another mangled name based on this one. */
+
+static void
+write_guarded_var_name (const tree variable)
+{
+ if (DECL_NAME (variable)
+ && strncmp (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR", 4) == 0)
+ /* The name of a guard variable for a reference temporary should refer
+ to the reference, not the temporary. */
+ write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
+ else
+ write_name (variable, /*ignore_local_scope=*/0);
+}
+
+/* Return an identifier for the name of an initialization guard
+ variable for indicated VARIABLE. */
+
+tree
+mangle_guard_variable (const tree variable)
+{
+ start_mangling (variable);
+ write_string ("_ZGV");
+ write_guarded_var_name (variable);
+ return finish_mangling_get_identifier (/*warn=*/false);
+}
+
+/* Return an identifier for the name of a thread_local initialization
+ function for VARIABLE. */
+
+tree
+mangle_tls_init_fn (const tree variable)
+{
+ start_mangling (variable);
+ write_string ("_ZTH");
+ write_guarded_var_name (variable);
+ return finish_mangling_get_identifier (/*warn=*/false);
+}
+
+/* Return an identifier for the name of a thread_local wrapper
+ function for VARIABLE. */
+
+#define TLS_WRAPPER_PREFIX "_ZTW"
+
+tree
+mangle_tls_wrapper_fn (const tree variable)
+{
+ start_mangling (variable);
+ write_string (TLS_WRAPPER_PREFIX);
+ write_guarded_var_name (variable);
+ return finish_mangling_get_identifier (/*warn=*/false);
+}
+
+/* Return true iff FN is a thread_local wrapper function. */
+
+bool
+decl_tls_wrapper_p (const tree fn)
+{
+ if (TREE_CODE (fn) != FUNCTION_DECL)
+ return false;
+ tree name = DECL_NAME (fn);
+ return strncmp (IDENTIFIER_POINTER (name), TLS_WRAPPER_PREFIX,
+ strlen (TLS_WRAPPER_PREFIX)) == 0;
+}
+
+/* Return an identifier for the name of a temporary variable used to
+ initialize a static reference. This isn't part of the ABI, but we might
+ as well call them something readable. */
+
+static GTY(()) int temp_count;
+
+tree
+mangle_ref_init_variable (const tree variable)
+{
+ start_mangling (variable);
+ write_string ("_ZGR");
+ write_name (variable, /*ignore_local_scope=*/0);
+ /* Avoid name clashes with aggregate initialization of multiple
+ references at once. */
+ write_unsigned_number (temp_count++);
+ return finish_mangling_get_identifier (/*warn=*/false);
+}
+
+
+/* Foreign language type mangling section. */
+
+/* How to write the type codes for the integer Java type. */
+
+static void
+write_java_integer_type_codes (const tree type)
+{
+ if (type == java_int_type_node)
+ write_char ('i');
+ else if (type == java_short_type_node)
+ write_char ('s');
+ else if (type == java_byte_type_node)
+ write_char ('c');
+ else if (type == java_char_type_node)
+ write_char ('w');
+ else if (type == java_long_type_node)
+ write_char ('x');
+ else if (type == java_boolean_type_node)
+ write_char ('b');
+ else
+ gcc_unreachable ();
+}
+
+/* Given a CLASS_TYPE, such as a record for std::bad_exception this
+ function generates a mangled name for the vtable map variable of
+ the class type. For example, if the class type is
+ "std::bad_exception", the mangled name for the class is
+ "St13bad_exception". This function would generate the name
+ "_ZN4_VTVISt13bad_exceptionE12__vtable_mapE", which unmangles as:
+ "_VTV<std::bad_exception>::__vtable_map". */
+
+
+char *
+get_mangled_vtable_map_var_name (tree class_type)
+{
+ char *var_name = NULL;
+ const char *prefix = "_ZN4_VTVI";
+ const char *postfix = "E12__vtable_mapE";
+
+ gcc_assert (TREE_CODE (class_type) == RECORD_TYPE);
+
+ tree class_id = DECL_ASSEMBLER_NAME (TYPE_NAME (class_type));
+ unsigned int len = strlen (IDENTIFIER_POINTER (class_id)) +
+ strlen (prefix) +
+ strlen (postfix) + 1;
+
+ var_name = (char *) xmalloc (len);
+
+ sprintf (var_name, "%s%s%s", prefix, IDENTIFIER_POINTER (class_id), postfix);
+
+ return var_name;
+}
+
+#include "gt-cp-mangle.h"
diff --git a/gcc-4.9/gcc/cp/method.c b/gcc-4.9/gcc/cp/method.c
new file mode 100644
index 000000000..d72b564a4
--- /dev/null
+++ b/gcc-4.9/gcc/cp/method.c
@@ -0,0 +1,2058 @@
+/* Handle the hair of processing (but not expanding) inline functions.
+ Also manage function and variable name overloading.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Contributed by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* Handle method declarations. */
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "varasm.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "toplev.h"
+#include "tm_p.h"
+#include "target.h"
+#include "common/common-target.h"
+#include "diagnostic.h"
+#include "cgraph.h"
+#include "pointer-set.h"
+
+/* Various flags to control the mangling process. */
+
+enum mangling_flags
+{
+ /* No flags. */
+ mf_none = 0,
+ /* The thing we are presently mangling is part of a template type,
+ rather than a fully instantiated type. Therefore, we may see
+ complex expressions where we would normally expect to see a
+ simple integer constant. */
+ mf_maybe_uninstantiated = 1,
+ /* When mangling a numeric value, use the form `_XX_' (instead of
+ just `XX') if the value has more than one digit. */
+ mf_use_underscores_around_value = 2
+};
+
+typedef enum mangling_flags mangling_flags;
+
+static void do_build_copy_assign (tree);
+static void do_build_copy_constructor (tree);
+static tree make_alias_for_thunk (tree);
+
+/* Called once to initialize method.c. */
+
+void
+init_method (void)
+{
+ init_mangle ();
+}
+
+/* Return a this or result adjusting thunk to FUNCTION. THIS_ADJUSTING
+ indicates whether it is a this or result adjusting thunk.
+ FIXED_OFFSET and VIRTUAL_OFFSET indicate how to do the adjustment
+ (see thunk_adjust). VIRTUAL_OFFSET can be NULL, but FIXED_OFFSET
+ never is. VIRTUAL_OFFSET is the /index/ into the vtable for this
+ adjusting thunks, we scale it to a byte offset. For covariant
+ thunks VIRTUAL_OFFSET is the virtual binfo. You must post process
+ the returned thunk with finish_thunk. */
+
+tree
+make_thunk (tree function, bool this_adjusting,
+ tree fixed_offset, tree virtual_offset)
+{
+ HOST_WIDE_INT d;
+ tree thunk;
+
+ gcc_assert (TREE_CODE (function) == FUNCTION_DECL);
+ /* We can have this thunks to covariant thunks, but not vice versa. */
+ gcc_assert (!DECL_THIS_THUNK_P (function));
+ gcc_assert (!DECL_RESULT_THUNK_P (function) || this_adjusting);
+
+ /* Scale the VIRTUAL_OFFSET to be in terms of bytes. */
+ if (this_adjusting && virtual_offset)
+ virtual_offset
+ = size_binop (MULT_EXPR,
+ virtual_offset,
+ convert (ssizetype,
+ TYPE_SIZE_UNIT (vtable_entry_type)));
+
+ d = tree_to_shwi (fixed_offset);
+
+ /* See if we already have the thunk in question. For this_adjusting
+ thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it
+ will be a BINFO. */
+ for (thunk = DECL_THUNKS (function); thunk; thunk = DECL_CHAIN (thunk))
+ if (DECL_THIS_THUNK_P (thunk) == this_adjusting
+ && THUNK_FIXED_OFFSET (thunk) == d
+ && !virtual_offset == !THUNK_VIRTUAL_OFFSET (thunk)
+ && (!virtual_offset
+ || (this_adjusting
+ ? tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk),
+ virtual_offset)
+ : THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset)))
+ return thunk;
+
+ /* All thunks must be created before FUNCTION is actually emitted;
+ the ABI requires that all thunks be emitted together with the
+ function to which they transfer control. */
+ gcc_assert (!TREE_ASM_WRITTEN (function));
+ /* Likewise, we can only be adding thunks to a function declared in
+ the class currently being laid out. */
+ gcc_assert (TYPE_SIZE (DECL_CONTEXT (function))
+ && TYPE_BEING_DEFINED (DECL_CONTEXT (function)));
+
+ thunk = build_decl (DECL_SOURCE_LOCATION (function),
+ FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
+ DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
+ cxx_dup_lang_specific_decl (thunk);
+ DECL_VIRTUAL_P (thunk) = true;
+ SET_DECL_THUNKS (thunk, NULL_TREE);
+
+ DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
+ TREE_READONLY (thunk) = TREE_READONLY (function);
+ TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
+ TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
+ SET_DECL_THUNK_P (thunk, this_adjusting);
+ THUNK_TARGET (thunk) = function;
+ THUNK_FIXED_OFFSET (thunk) = d;
+ THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
+ THUNK_ALIAS (thunk) = NULL_TREE;
+
+ DECL_INTERFACE_KNOWN (thunk) = 1;
+ DECL_NOT_REALLY_EXTERN (thunk) = 1;
+ DECL_COMDAT (thunk) = DECL_COMDAT (function);
+ DECL_SAVED_FUNCTION_DATA (thunk) = NULL;
+ /* The thunk itself is not a constructor or destructor, even if
+ the thing it is thunking to is. */
+ DECL_DESTRUCTOR_P (thunk) = 0;
+ DECL_CONSTRUCTOR_P (thunk) = 0;
+ DECL_EXTERNAL (thunk) = 1;
+ DECL_ARTIFICIAL (thunk) = 1;
+ /* The THUNK is not a pending inline, even if the FUNCTION is. */
+ DECL_PENDING_INLINE_P (thunk) = 0;
+ DECL_DECLARED_INLINE_P (thunk) = 0;
+ /* Nor is it a template instantiation. */
+ DECL_USE_TEMPLATE (thunk) = 0;
+ DECL_TEMPLATE_INFO (thunk) = NULL;
+
+ /* Add it to the list of thunks associated with FUNCTION. */
+ DECL_CHAIN (thunk) = DECL_THUNKS (function);
+ SET_DECL_THUNKS (function, thunk);
+
+ return thunk;
+}
+
+/* Finish THUNK, a thunk decl. */
+
+void
+finish_thunk (tree thunk)
+{
+ tree function, name;
+ tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk));
+ tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk);
+
+ gcc_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk));
+ if (virtual_offset && DECL_RESULT_THUNK_P (thunk))
+ virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
+ function = THUNK_TARGET (thunk);
+ name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
+ fixed_offset, virtual_offset);
+
+ /* We can end up with declarations of (logically) different
+ covariant thunks, that do identical adjustments. The two thunks
+ will be adjusting between within different hierarchies, which
+ happen to have the same layout. We must nullify one of them to
+ refer to the other. */
+ if (DECL_RESULT_THUNK_P (thunk))
+ {
+ tree cov_probe;
+
+ for (cov_probe = DECL_THUNKS (function);
+ cov_probe; cov_probe = DECL_CHAIN (cov_probe))
+ if (DECL_NAME (cov_probe) == name)
+ {
+ gcc_assert (!DECL_THUNKS (thunk));
+ THUNK_ALIAS (thunk) = (THUNK_ALIAS (cov_probe)
+ ? THUNK_ALIAS (cov_probe) : cov_probe);
+ break;
+ }
+ }
+
+ DECL_NAME (thunk) = name;
+ SET_DECL_ASSEMBLER_NAME (thunk, name);
+}
+
+static GTY (()) int thunk_labelno;
+
+/* Create a static alias to target. */
+
+tree
+make_alias_for (tree target, tree newid)
+{
+ tree alias = build_decl (DECL_SOURCE_LOCATION (target),
+ TREE_CODE (target), newid, TREE_TYPE (target));
+ DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (target);
+ cxx_dup_lang_specific_decl (alias);
+ DECL_CONTEXT (alias) = NULL;
+ TREE_READONLY (alias) = TREE_READONLY (target);
+ TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (target);
+ TREE_PUBLIC (alias) = 0;
+ DECL_INTERFACE_KNOWN (alias) = 1;
+ if (DECL_LANG_SPECIFIC (alias))
+ {
+ DECL_NOT_REALLY_EXTERN (alias) = 1;
+ DECL_USE_TEMPLATE (alias) = 0;
+ DECL_TEMPLATE_INFO (alias) = NULL;
+ }
+ DECL_EXTERNAL (alias) = 0;
+ DECL_ARTIFICIAL (alias) = 1;
+ DECL_TEMPLATE_INSTANTIATED (alias) = 0;
+ if (TREE_CODE (alias) == FUNCTION_DECL)
+ {
+ DECL_SAVED_FUNCTION_DATA (alias) = NULL;
+ DECL_DESTRUCTOR_P (alias) = 0;
+ DECL_CONSTRUCTOR_P (alias) = 0;
+ DECL_PENDING_INLINE_P (alias) = 0;
+ DECL_DECLARED_INLINE_P (alias) = 0;
+ DECL_INITIAL (alias) = error_mark_node;
+ DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (target));
+ }
+ else
+ TREE_STATIC (alias) = 1;
+ TREE_ADDRESSABLE (alias) = 1;
+ TREE_USED (alias) = 1;
+ SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
+ return alias;
+}
+
+static tree
+make_alias_for_thunk (tree function)
+{
+ tree alias;
+ char buf[256];
+
+ targetm.asm_out.generate_internal_label (buf, "LTHUNK", thunk_labelno);
+ thunk_labelno++;
+
+ alias = make_alias_for (function, get_identifier (buf));
+
+ if (!flag_syntax_only)
+ {
+ struct cgraph_node *funcn, *aliasn;
+ funcn = cgraph_get_node (function);
+ gcc_checking_assert (funcn);
+ aliasn = cgraph_same_body_alias (funcn, alias, function);
+ DECL_ASSEMBLER_NAME (function);
+ gcc_assert (aliasn != NULL);
+ }
+
+ return alias;
+}
+
+/* Emit the definition of a C++ multiple inheritance or covariant
+ return vtable thunk. If EMIT_P is nonzero, the thunk is emitted
+ immediately. */
+
+void
+use_thunk (tree thunk_fndecl, bool emit_p)
+{
+ tree a, t, function, alias;
+ tree virtual_offset;
+ HOST_WIDE_INT fixed_offset, virtual_value;
+ bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
+ struct cgraph_node *funcn, *thunk_node;
+
+ /* We should have called finish_thunk to give it a name. */
+ gcc_assert (DECL_NAME (thunk_fndecl));
+
+ /* We should never be using an alias, always refer to the
+ aliased thunk. */
+ gcc_assert (!THUNK_ALIAS (thunk_fndecl));
+
+ if (TREE_ASM_WRITTEN (thunk_fndecl))
+ return;
+
+ function = THUNK_TARGET (thunk_fndecl);
+ if (DECL_RESULT (thunk_fndecl))
+ /* We already turned this thunk into an ordinary function.
+ There's no need to process this thunk again. */
+ return;
+
+ if (DECL_THUNK_P (function))
+ /* The target is itself a thunk, process it now. */
+ use_thunk (function, emit_p);
+
+ /* Thunks are always addressable; they only appear in vtables. */
+ TREE_ADDRESSABLE (thunk_fndecl) = 1;
+
+ /* Figure out what function is being thunked to. It's referenced in
+ this translation unit. */
+ TREE_ADDRESSABLE (function) = 1;
+ mark_used (function);
+ if (!emit_p)
+ return;
+
+ if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
+ alias = make_alias_for_thunk (function);
+ else
+ alias = function;
+
+ fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
+ virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
+
+ if (virtual_offset)
+ {
+ if (!this_adjusting)
+ virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
+ virtual_value = tree_to_shwi (virtual_offset);
+ gcc_assert (virtual_value);
+ }
+ else
+ virtual_value = 0;
+
+ /* And, if we need to emit the thunk, it's used. */
+ mark_used (thunk_fndecl);
+ /* This thunk is actually defined. */
+ DECL_EXTERNAL (thunk_fndecl) = 0;
+ /* The linkage of the function may have changed. FIXME in linkage
+ rewrite. */
+ gcc_assert (DECL_INTERFACE_KNOWN (function));
+ TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
+ DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
+ DECL_VISIBILITY_SPECIFIED (thunk_fndecl)
+ = DECL_VISIBILITY_SPECIFIED (function);
+ DECL_COMDAT (thunk_fndecl) = DECL_COMDAT (function);
+ DECL_WEAK (thunk_fndecl) = DECL_WEAK (function);
+
+ if (flag_syntax_only)
+ {
+ TREE_ASM_WRITTEN (thunk_fndecl) = 1;
+ return;
+ }
+
+ push_to_top_level ();
+
+ if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function)
+ && targetm_common.have_named_sections)
+ {
+ resolve_unique_section (function, 0, flag_function_sections);
+
+ if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function))
+ {
+ resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
+
+ /* Output the thunk into the same section as function. */
+ DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function);
+ }
+ }
+
+ /* Set up cloned argument trees for the thunk. */
+ t = NULL_TREE;
+ for (a = DECL_ARGUMENTS (function); a; a = DECL_CHAIN (a))
+ {
+ tree x = copy_node (a);
+ DECL_CHAIN (x) = t;
+ DECL_CONTEXT (x) = thunk_fndecl;
+ SET_DECL_RTL (x, NULL);
+ DECL_HAS_VALUE_EXPR_P (x) = 0;
+ TREE_ADDRESSABLE (x) = 0;
+ t = x;
+ }
+ a = nreverse (t);
+ DECL_ARGUMENTS (thunk_fndecl) = a;
+ TREE_ASM_WRITTEN (thunk_fndecl) = 1;
+ funcn = cgraph_get_node (function);
+ gcc_checking_assert (funcn);
+ thunk_node = cgraph_add_thunk (funcn, thunk_fndecl, function,
+ this_adjusting, fixed_offset, virtual_value,
+ virtual_offset, alias);
+ if (DECL_ONE_ONLY (function))
+ symtab_add_to_same_comdat_group (thunk_node,
+ funcn);
+
+ if (!this_adjusting
+ || !targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
+ virtual_value, alias))
+ {
+ /* If this is a covariant thunk, or we don't have the necessary
+ code for efficient thunks, generate a thunk function that
+ just makes a call to the real function. Unfortunately, this
+ doesn't work for varargs. */
+
+ if (varargs_function_p (function))
+ error ("generic thunk code fails for method %q#D which uses %<...%>",
+ function);
+ }
+
+ pop_from_top_level ();
+}
+
+/* Code for synthesizing methods which have default semantics defined. */
+
+/* True iff CTYPE has a trivial SFK. */
+
+static bool
+type_has_trivial_fn (tree ctype, special_function_kind sfk)
+{
+ switch (sfk)
+ {
+ case sfk_constructor:
+ return !TYPE_HAS_COMPLEX_DFLT (ctype);
+ case sfk_copy_constructor:
+ return !TYPE_HAS_COMPLEX_COPY_CTOR (ctype);
+ case sfk_move_constructor:
+ return !TYPE_HAS_COMPLEX_MOVE_CTOR (ctype);
+ case sfk_copy_assignment:
+ return !TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype);
+ case sfk_move_assignment:
+ return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype);
+ case sfk_destructor:
+ return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype);
+ case sfk_inheriting_constructor:
+ return false;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Note that CTYPE has a non-trivial SFK even though we previously thought
+ it was trivial. */
+
+static void
+type_set_nontrivial_flag (tree ctype, special_function_kind sfk)
+{
+ switch (sfk)
+ {
+ case sfk_constructor:
+ TYPE_HAS_COMPLEX_DFLT (ctype) = true;
+ return;
+ case sfk_copy_constructor:
+ TYPE_HAS_COMPLEX_COPY_CTOR (ctype) = true;
+ return;
+ case sfk_move_constructor:
+ TYPE_HAS_COMPLEX_MOVE_CTOR (ctype) = true;
+ return;
+ case sfk_copy_assignment:
+ TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype) = true;
+ return;
+ case sfk_move_assignment:
+ TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype) = true;
+ return;
+ case sfk_destructor:
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
+ return;
+ case sfk_inheriting_constructor:
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* True iff FN is a trivial defaulted member function ([cd]tor, op=). */
+
+bool
+trivial_fn_p (tree fn)
+{
+ if (!DECL_DEFAULTED_FN (fn))
+ return false;
+
+ /* If fn is a clone, get the primary variant. */
+ if (tree prim = DECL_CLONED_FUNCTION (fn))
+ fn = prim;
+ return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn));
+}
+
+/* Subroutine of do_build_copy_constructor: Add a mem-initializer for BINFO
+ given the parameter or parameters PARM, possibly inherited constructor
+ base INH, or move flag MOVE_P. */
+
+static tree
+add_one_base_init (tree binfo, tree parm, bool move_p, tree inh,
+ tree member_init_list)
+{
+ tree init;
+ if (inh)
+ {
+ /* An inheriting constructor only has a mem-initializer for
+ the base it inherits from. */
+ if (BINFO_TYPE (binfo) != inh)
+ return member_init_list;
+
+ tree *p = &init;
+ init = NULL_TREE;
+ for (; parm; parm = DECL_CHAIN (parm))
+ {
+ tree exp = convert_from_reference (parm);
+ if (TREE_CODE (TREE_TYPE (parm)) != REFERENCE_TYPE
+ || TYPE_REF_IS_RVALUE (TREE_TYPE (parm)))
+ exp = move (exp);
+ *p = build_tree_list (NULL_TREE, exp);
+ p = &TREE_CHAIN (*p);
+ }
+ }
+ else
+ {
+ init = build_base_path (PLUS_EXPR, parm, binfo, 1,
+ tf_warning_or_error);
+ if (move_p)
+ init = move (init);
+ init = build_tree_list (NULL_TREE, init);
+ }
+ return tree_cons (binfo, init, member_init_list);
+}
+
+/* Generate code for default X(X&) or X(X&&) constructor or an inheriting
+ constructor. */
+
+static void
+do_build_copy_constructor (tree fndecl)
+{
+ tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
+ bool move_p = DECL_MOVE_CONSTRUCTOR_P (fndecl);
+ bool trivial = trivial_fn_p (fndecl);
+ tree inh = DECL_INHERITED_CTOR_BASE (fndecl);
+
+ if (!inh)
+ parm = convert_from_reference (parm);
+
+ if (trivial
+ && is_empty_class (current_class_type))
+ /* Don't copy the padding byte; it might not have been allocated
+ if *this is a base subobject. */;
+ else if (trivial)
+ {
+ tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm);
+ finish_expr_stmt (t);
+ }
+ else
+ {
+ tree fields = TYPE_FIELDS (current_class_type);
+ tree member_init_list = NULL_TREE;
+ int cvquals = cp_type_quals (TREE_TYPE (parm));
+ int i;
+ tree binfo, base_binfo;
+ tree init;
+ vec<tree, va_gc> *vbases;
+
+ /* Initialize all the base-classes with the parameter converted
+ to their type so that we get their copy constructor and not
+ another constructor that takes current_class_type. We must
+ deal with the binfo's directly as a direct base might be
+ inaccessible due to ambiguity. */
+ for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
+ vec_safe_iterate (vbases, i, &binfo); i++)
+ {
+ member_init_list = add_one_base_init (binfo, parm, move_p, inh,
+ member_init_list);
+ }
+
+ for (binfo = TYPE_BINFO (current_class_type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ {
+ if (BINFO_VIRTUAL_P (base_binfo))
+ continue;
+ member_init_list = add_one_base_init (base_binfo, parm, move_p,
+ inh, member_init_list);
+ }
+
+ for (; fields; fields = DECL_CHAIN (fields))
+ {
+ tree field = fields;
+ tree expr_type;
+
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+ if (inh)
+ continue;
+
+ expr_type = TREE_TYPE (field);
+ if (DECL_NAME (field))
+ {
+ if (VFIELD_NAME_P (DECL_NAME (field)))
+ continue;
+ }
+ else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
+ /* Just use the field; anonymous types can't have
+ nontrivial copy ctors or assignment ops or this
+ function would be deleted. */;
+ else
+ continue;
+
+ /* Compute the type of "init->field". If the copy-constructor
+ parameter is, for example, "const S&", and the type of
+ the field is "T", then the type will usually be "const
+ T". (There are no cv-qualified variants of reference
+ types.) */
+ if (TREE_CODE (expr_type) != REFERENCE_TYPE)
+ {
+ int quals = cvquals;
+
+ if (DECL_MUTABLE_P (field))
+ quals &= ~TYPE_QUAL_CONST;
+ quals |= cp_type_quals (expr_type);
+ expr_type = cp_build_qualified_type (expr_type, quals);
+ }
+
+ init = build3 (COMPONENT_REF, expr_type, parm, field, NULL_TREE);
+ if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE
+ /* 'move' breaks bit-fields, and has no effect for scalars. */
+ && !scalarish_type_p (expr_type))
+ init = move (init);
+ init = build_tree_list (NULL_TREE, init);
+
+ member_init_list = tree_cons (field, init, member_init_list);
+ }
+ finish_mem_initializers (member_init_list);
+ }
+}
+
+static void
+do_build_copy_assign (tree fndecl)
+{
+ tree parm = DECL_CHAIN (DECL_ARGUMENTS (fndecl));
+ tree compound_stmt;
+ bool move_p = move_fn_p (fndecl);
+ bool trivial = trivial_fn_p (fndecl);
+ int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED;
+
+ compound_stmt = begin_compound_stmt (0);
+ parm = convert_from_reference (parm);
+
+ if (trivial
+ && is_empty_class (current_class_type))
+ /* Don't copy the padding byte; it might not have been allocated
+ if *this is a base subobject. */;
+ else if (trivial)
+ {
+ tree t = build2 (MODIFY_EXPR, void_type_node, current_class_ref, parm);
+ finish_expr_stmt (t);
+ }
+ else
+ {
+ tree fields;
+ int cvquals = cp_type_quals (TREE_TYPE (parm));
+ int i;
+ tree binfo, base_binfo;
+
+ /* Assign to each of the direct base classes. */
+ for (binfo = TYPE_BINFO (current_class_type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ {
+ tree converted_parm;
+ vec<tree, va_gc> *parmvec;
+
+ /* We must convert PARM directly to the base class
+ explicitly since the base class may be ambiguous. */
+ converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1,
+ tf_warning_or_error);
+ if (move_p)
+ converted_parm = move (converted_parm);
+ /* Call the base class assignment operator. */
+ parmvec = make_tree_vector_single (converted_parm);
+ finish_expr_stmt
+ (build_special_member_call (current_class_ref,
+ ansi_assopname (NOP_EXPR),
+ &parmvec,
+ base_binfo,
+ flags,
+ tf_warning_or_error));
+ release_tree_vector (parmvec);
+ }
+
+ /* Assign to each of the non-static data members. */
+ for (fields = TYPE_FIELDS (current_class_type);
+ fields;
+ fields = DECL_CHAIN (fields))
+ {
+ tree comp = current_class_ref;
+ tree init = parm;
+ tree field = fields;
+ tree expr_type;
+ int quals;
+
+ if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
+ continue;
+
+ expr_type = TREE_TYPE (field);
+
+ if (CP_TYPE_CONST_P (expr_type))
+ {
+ error ("non-static const member %q#D, can%'t use default "
+ "assignment operator", field);
+ continue;
+ }
+ else if (TREE_CODE (expr_type) == REFERENCE_TYPE)
+ {
+ error ("non-static reference member %q#D, can%'t use "
+ "default assignment operator", field);
+ continue;
+ }
+
+ if (DECL_NAME (field))
+ {
+ if (VFIELD_NAME_P (DECL_NAME (field)))
+ continue;
+ }
+ else if (ANON_AGGR_TYPE_P (expr_type)
+ && TYPE_FIELDS (expr_type) != NULL_TREE)
+ /* Just use the field; anonymous types can't have
+ nontrivial copy ctors or assignment ops or this
+ function would be deleted. */;
+ else
+ continue;
+
+ comp = build3 (COMPONENT_REF, expr_type, comp, field, NULL_TREE);
+
+ /* Compute the type of init->field */
+ quals = cvquals;
+ if (DECL_MUTABLE_P (field))
+ quals &= ~TYPE_QUAL_CONST;
+ expr_type = cp_build_qualified_type (expr_type, quals);
+
+ init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
+ if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE
+ /* 'move' breaks bit-fields, and has no effect for scalars. */
+ && !scalarish_type_p (expr_type))
+ init = move (init);
+
+ if (DECL_NAME (field))
+ init = cp_build_modify_expr (comp, NOP_EXPR, init,
+ tf_warning_or_error);
+ else
+ init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
+ finish_expr_stmt (init);
+ }
+ }
+ finish_return_stmt (current_class_ref);
+ finish_compound_stmt (compound_stmt);
+}
+
+/* Synthesize FNDECL, a non-static member function. */
+
+void
+synthesize_method (tree fndecl)
+{
+ bool nested = (current_function_decl != NULL_TREE);
+ tree context = decl_function_context (fndecl);
+ bool need_body = true;
+ tree stmt;
+ location_t save_input_location = input_location;
+ int error_count = errorcount;
+ int warning_count = warningcount + werrorcount;
+
+ /* Reset the source location, we might have been previously
+ deferred, and thus have saved where we were first needed. */
+ DECL_SOURCE_LOCATION (fndecl)
+ = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl)));
+
+ /* If we've been asked to synthesize a clone, just synthesize the
+ cloned function instead. Doing so will automatically fill in the
+ body for the clone. */
+ if (DECL_CLONED_FUNCTION_P (fndecl))
+ fndecl = DECL_CLONED_FUNCTION (fndecl);
+
+ /* We may be in the middle of deferred access check. Disable
+ it now. */
+ push_deferring_access_checks (dk_no_deferred);
+
+ if (! context)
+ push_to_top_level ();
+ else if (nested)
+ push_function_context ();
+
+ input_location = DECL_SOURCE_LOCATION (fndecl);
+
+ start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
+ stmt = begin_function_body ();
+
+ if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
+ {
+ do_build_copy_assign (fndecl);
+ need_body = false;
+ }
+ else if (DECL_CONSTRUCTOR_P (fndecl))
+ {
+ tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
+ if (arg_chain != void_list_node)
+ do_build_copy_constructor (fndecl);
+ else
+ finish_mem_initializers (NULL_TREE);
+ }
+
+ /* If we haven't yet generated the body of the function, just
+ generate an empty compound statement. */
+ if (need_body)
+ {
+ tree compound_stmt;
+ compound_stmt = begin_compound_stmt (BCS_FN_BODY);
+ finish_compound_stmt (compound_stmt);
+ }
+
+ finish_function_body (stmt);
+ expand_or_defer_fn (finish_function (0));
+
+ input_location = save_input_location;
+
+ if (! context)
+ pop_from_top_level ();
+ else if (nested)
+ pop_function_context ();
+
+ pop_deferring_access_checks ();
+
+ if (error_count != errorcount || warning_count != warningcount + werrorcount)
+ inform (input_location, "synthesized method %qD first required here ",
+ fndecl);
+}
+
+/* Build a reference to type TYPE with cv-quals QUALS, which is an
+ rvalue if RVALUE is true. */
+
+static tree
+build_stub_type (tree type, int quals, bool rvalue)
+{
+ tree argtype = cp_build_qualified_type (type, quals);
+ return cp_build_reference_type (argtype, rvalue);
+}
+
+/* Build a dummy glvalue from dereferencing a dummy reference of type
+ REFTYPE. */
+
+static tree
+build_stub_object (tree reftype)
+{
+ tree stub = build1 (NOP_EXPR, reftype, integer_one_node);
+ return convert_from_reference (stub);
+}
+
+/* Determine which function will be called when looking up NAME in TYPE,
+ called with a single ARGTYPE argument, or no argument if ARGTYPE is
+ null. FLAGS and COMPLAIN are as for build_new_method_call.
+
+ Returns a FUNCTION_DECL if all is well.
+ Returns NULL_TREE if overload resolution failed.
+ Returns error_mark_node if the chosen function cannot be called. */
+
+static tree
+locate_fn_flags (tree type, tree name, tree argtype, int flags,
+ tsubst_flags_t complain)
+{
+ tree ob, fn, fns, binfo, rval;
+ vec<tree, va_gc> *args;
+
+ if (TYPE_P (type))
+ binfo = TYPE_BINFO (type);
+ else
+ {
+ binfo = type;
+ type = BINFO_TYPE (binfo);
+ }
+
+ ob = build_stub_object (cp_build_reference_type (type, false));
+ args = make_tree_vector ();
+ if (argtype)
+ {
+ if (TREE_CODE (argtype) == TREE_LIST)
+ {
+ for (tree elt = argtype; elt != void_list_node;
+ elt = TREE_CHAIN (elt))
+ {
+ tree type = TREE_VALUE (elt);
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ type = cp_build_reference_type (type, /*rval*/true);
+ tree arg = build_stub_object (type);
+ vec_safe_push (args, arg);
+ }
+ }
+ else
+ {
+ tree arg = build_stub_object (argtype);
+ args->quick_push (arg);
+ }
+ }
+
+ fns = lookup_fnfields (binfo, name, 0);
+ rval = build_new_method_call (ob, fns, &args, binfo, flags, &fn, complain);
+
+ release_tree_vector (args);
+ if (fn && rval == error_mark_node)
+ return rval;
+ else
+ return fn;
+}
+
+/* Locate the dtor of TYPE. */
+
+tree
+get_dtor (tree type, tsubst_flags_t complain)
+{
+ tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE,
+ LOOKUP_NORMAL, complain);
+ if (fn == error_mark_node)
+ return NULL_TREE;
+ return fn;
+}
+
+/* Locate the default ctor of TYPE. */
+
+tree
+locate_ctor (tree type)
+{
+ tree fn;
+
+ push_deferring_access_checks (dk_no_check);
+ fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
+ LOOKUP_SPECULATIVE, tf_none);
+ pop_deferring_access_checks ();
+ if (fn == error_mark_node)
+ return NULL_TREE;
+ return fn;
+}
+
+/* Likewise, but give any appropriate errors. */
+
+tree
+get_default_ctor (tree type)
+{
+ tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
+ LOOKUP_NORMAL, tf_warning_or_error);
+ if (fn == error_mark_node)
+ return NULL_TREE;
+ return fn;
+}
+
+/* Locate the copy ctor of TYPE. */
+
+tree
+get_copy_ctor (tree type, tsubst_flags_t complain)
+{
+ int quals = (TYPE_HAS_CONST_COPY_CTOR (type)
+ ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
+ tree argtype = build_stub_type (type, quals, false);
+ tree fn = locate_fn_flags (type, complete_ctor_identifier, argtype,
+ LOOKUP_NORMAL, complain);
+ if (fn == error_mark_node)
+ return NULL_TREE;
+ return fn;
+}
+
+/* Locate the copy assignment operator of TYPE. */
+
+tree
+get_copy_assign (tree type)
+{
+ int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type)
+ ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
+ tree argtype = build_stub_type (type, quals, false);
+ tree fn = locate_fn_flags (type, ansi_assopname (NOP_EXPR), argtype,
+ LOOKUP_NORMAL, tf_warning_or_error);
+ if (fn == error_mark_node)
+ return NULL_TREE;
+ return fn;
+}
+
+/* Locate the inherited constructor of constructor CTOR. */
+
+tree
+get_inherited_ctor (tree ctor)
+{
+ gcc_assert (DECL_INHERITED_CTOR_BASE (ctor));
+
+ push_deferring_access_checks (dk_no_check);
+ tree fn = locate_fn_flags (DECL_INHERITED_CTOR_BASE (ctor),
+ complete_ctor_identifier,
+ FUNCTION_FIRST_USER_PARMTYPE (ctor),
+ LOOKUP_NORMAL|LOOKUP_SPECULATIVE,
+ tf_none);
+ pop_deferring_access_checks ();
+ if (fn == error_mark_node)
+ return NULL_TREE;
+ return fn;
+}
+
+/* Subroutine of synthesized_method_walk. Update SPEC_P, TRIVIAL_P and
+ DELETED_P or give an error message MSG with argument ARG. */
+
+static void
+process_subob_fn (tree fn, tree *spec_p, bool *trivial_p,
+ bool *deleted_p, bool *constexpr_p,
+ bool diag, tree arg)
+{
+ if (!fn || fn == error_mark_node)
+ goto bad;
+
+ if (spec_p)
+ {
+ tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
+ *spec_p = merge_exception_specifiers (*spec_p, raises, fn);
+ }
+
+ if (!trivial_fn_p (fn))
+ {
+ if (trivial_p)
+ *trivial_p = false;
+ if (TREE_CODE (arg) == FIELD_DECL
+ && TREE_CODE (DECL_CONTEXT (arg)) == UNION_TYPE)
+ {
+ if (deleted_p)
+ *deleted_p = true;
+ if (diag)
+ error ("union member %q+D with non-trivial %qD", arg, fn);
+ }
+ }
+
+ if (constexpr_p && !DECL_DECLARED_CONSTEXPR_P (fn))
+ {
+ *constexpr_p = false;
+ if (diag)
+ {
+ inform (0, "defaulted constructor calls non-constexpr "
+ "%q+D", fn);
+ explain_invalid_constexpr_fn (fn);
+ }
+ }
+
+ return;
+
+ bad:
+ if (deleted_p)
+ *deleted_p = true;
+}
+
+/* Subroutine of synthesized_method_walk to allow recursion into anonymous
+ aggregates. */
+
+static void
+walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
+ int quals, bool copy_arg_p, bool move_p,
+ bool assign_p, tree *spec_p, bool *trivial_p,
+ bool *deleted_p, bool *constexpr_p,
+ bool diag, int flags, tsubst_flags_t complain)
+{
+ tree field;
+ for (field = fields; field; field = DECL_CHAIN (field))
+ {
+ tree mem_type, argtype, rval;
+
+ if (TREE_CODE (field) != FIELD_DECL
+ || DECL_ARTIFICIAL (field))
+ continue;
+
+ mem_type = strip_array_types (TREE_TYPE (field));
+ if (assign_p)
+ {
+ bool bad = true;
+ if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type))
+ {
+ if (diag)
+ error ("non-static const member %q#D, can%'t use default "
+ "assignment operator", field);
+ }
+ else if (TREE_CODE (mem_type) == REFERENCE_TYPE)
+ {
+ if (diag)
+ error ("non-static reference member %q#D, can%'t use "
+ "default assignment operator", field);
+ }
+ else
+ bad = false;
+
+ if (bad && deleted_p)
+ *deleted_p = true;
+ }
+ else if (sfk == sfk_constructor)
+ {
+ bool bad;
+
+ if (DECL_INITIAL (field))
+ {
+ if (diag && DECL_INITIAL (field) == error_mark_node)
+ inform (0, "initializer for %q+#D is invalid", field);
+ if (trivial_p)
+ *trivial_p = false;
+#if 0
+ /* Core 1351: If the field has an NSDMI that could throw, the
+ default constructor is noexcept(false). FIXME this is
+ broken by deferred parsing and 1360 saying we can't lazily
+ declare a non-trivial default constructor. Also this
+ needs to do deferred instantiation. Disable until the
+ conflict between 1351 and 1360 is resolved. */
+ if (spec_p && !expr_noexcept_p (DECL_INITIAL (field), complain))
+ *spec_p = noexcept_false_spec;
+#endif
+
+ /* Don't do the normal processing. */
+ continue;
+ }
+
+ bad = false;
+ if (CP_TYPE_CONST_P (mem_type)
+ && default_init_uninitialized_part (mem_type))
+ {
+ if (diag)
+ error ("uninitialized non-static const member %q#D",
+ field);
+ bad = true;
+ }
+ else if (TREE_CODE (mem_type) == REFERENCE_TYPE)
+ {
+ if (diag)
+ error ("uninitialized non-static reference member %q#D",
+ field);
+ bad = true;
+ }
+
+ if (bad && deleted_p)
+ *deleted_p = true;
+
+ /* For an implicitly-defined default constructor to be constexpr,
+ every member must have a user-provided default constructor or
+ an explicit initializer. */
+ if (constexpr_p && !CLASS_TYPE_P (mem_type)
+ && TREE_CODE (DECL_CONTEXT (field)) != UNION_TYPE)
+ {
+ *constexpr_p = false;
+ if (diag)
+ inform (0, "defaulted default constructor does not "
+ "initialize %q+#D", field);
+ }
+ }
+ else if (sfk == sfk_copy_constructor)
+ {
+ /* 12.8p11b5 */
+ if (TREE_CODE (mem_type) == REFERENCE_TYPE
+ && TYPE_REF_IS_RVALUE (mem_type))
+ {
+ if (diag)
+ error ("copying non-static data member %q#D of rvalue "
+ "reference type", field);
+ if (deleted_p)
+ *deleted_p = true;
+ }
+ }
+
+ if (!CLASS_TYPE_P (mem_type))
+ continue;
+
+ if (ANON_AGGR_TYPE_P (mem_type))
+ {
+ walk_field_subobs (TYPE_FIELDS (mem_type), fnname, sfk, quals,
+ copy_arg_p, move_p, assign_p, spec_p, trivial_p,
+ deleted_p, constexpr_p,
+ diag, flags, complain);
+ continue;
+ }
+
+ if (copy_arg_p)
+ {
+ int mem_quals = cp_type_quals (mem_type) | quals;
+ if (DECL_MUTABLE_P (field))
+ mem_quals &= ~TYPE_QUAL_CONST;
+ argtype = build_stub_type (mem_type, mem_quals, move_p);
+ }
+ else
+ argtype = NULL_TREE;
+
+ rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain);
+
+ process_subob_fn (rval, spec_p, trivial_p, deleted_p,
+ constexpr_p, diag, field);
+ }
+}
+
+/* The caller wants to generate an implicit declaration of SFK for CTYPE
+ which is const if relevant and CONST_P is set. If spec_p, trivial_p and
+ deleted_p are non-null, set their referent appropriately. If diag is
+ true, we're either being called from maybe_explain_implicit_delete to
+ give errors, or if constexpr_p is non-null, from
+ explain_invalid_constexpr_fn. */
+
+static void
+synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
+ tree *spec_p, bool *trivial_p, bool *deleted_p,
+ bool *constexpr_p, bool diag,
+ tree inherited_base, tree inherited_parms)
+{
+ tree binfo, base_binfo, scope, fnname, rval, argtype;
+ bool move_p, copy_arg_p, assign_p, expected_trivial, check_vdtor;
+ vec<tree, va_gc> *vbases;
+ int i, quals, flags;
+ tsubst_flags_t complain;
+ bool ctor_p;
+
+ if (spec_p)
+ *spec_p = (cxx_dialect >= cxx11 ? noexcept_true_spec : empty_except_spec);
+
+ if (deleted_p)
+ {
+ /* "The closure type associated with a lambda-expression has a deleted
+ default constructor and a deleted copy assignment operator."
+ This is diagnosed in maybe_explain_implicit_delete. */
+ if (LAMBDA_TYPE_P (ctype)
+ && (sfk == sfk_constructor
+ || sfk == sfk_copy_assignment))
+ {
+ *deleted_p = true;
+ return;
+ }
+
+ *deleted_p = false;
+ }
+
+ ctor_p = false;
+ assign_p = false;
+ check_vdtor = false;
+ switch (sfk)
+ {
+ case sfk_move_assignment:
+ case sfk_copy_assignment:
+ assign_p = true;
+ fnname = ansi_assopname (NOP_EXPR);
+ break;
+
+ case sfk_destructor:
+ check_vdtor = true;
+ /* The synthesized method will call base dtors, but check complete
+ here to avoid having to deal with VTT. */
+ fnname = complete_dtor_identifier;
+ break;
+
+ case sfk_constructor:
+ case sfk_move_constructor:
+ case sfk_copy_constructor:
+ case sfk_inheriting_constructor:
+ ctor_p = true;
+ fnname = complete_ctor_identifier;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ gcc_assert ((sfk == sfk_inheriting_constructor)
+ == (inherited_base != NULL_TREE));
+
+ /* If that user-written default constructor would satisfy the
+ requirements of a constexpr constructor (7.1.5), the
+ implicitly-defined default constructor is constexpr. */
+ if (constexpr_p)
+ *constexpr_p = ctor_p;
+
+ move_p = false;
+ switch (sfk)
+ {
+ case sfk_constructor:
+ case sfk_destructor:
+ case sfk_inheriting_constructor:
+ copy_arg_p = false;
+ break;
+
+ case sfk_move_constructor:
+ case sfk_move_assignment:
+ move_p = true;
+ case sfk_copy_constructor:
+ case sfk_copy_assignment:
+ copy_arg_p = true;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ expected_trivial = type_has_trivial_fn (ctype, sfk);
+ if (trivial_p)
+ *trivial_p = expected_trivial;
+
+ /* The TYPE_HAS_COMPLEX_* flags tell us about constraints from base
+ class versions and other properties of the type. But a subobject
+ class can be trivially copyable and yet have overload resolution
+ choose a template constructor for initialization, depending on
+ rvalueness and cv-quals. And furthermore, a member in a base might
+ be trivial but deleted or otherwise not callable. So we can't exit
+ early in C++0x. The same considerations apply in C++98/03, but
+ there the definition of triviality does not consider overload
+ resolution, so a constructor can be trivial even if it would otherwise
+ call a non-trivial constructor. */
+ if (expected_trivial
+ && (!copy_arg_p || cxx_dialect < cxx11))
+ {
+ if (constexpr_p && sfk == sfk_constructor)
+ {
+ bool cx = trivial_default_constructor_is_constexpr (ctype);
+ *constexpr_p = cx;
+ if (diag && !cx && TREE_CODE (ctype) == UNION_TYPE)
+ /* A trivial constructor doesn't have any NSDMI. */
+ inform (input_location, "defaulted default constructor does "
+ "not initialize any non-static data member");
+ }
+ if (!diag && cxx_dialect < cxx11)
+ return;
+ }
+
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
+ push_deferring_access_checks (dk_no_deferred);
+
+ scope = push_scope (ctype);
+
+ flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE;
+ if (!inherited_base)
+ flags |= LOOKUP_DEFAULTED;
+
+ complain = diag ? tf_warning_or_error : tf_none;
+
+ if (const_p)
+ quals = TYPE_QUAL_CONST;
+ else
+ quals = TYPE_UNQUALIFIED;
+ argtype = NULL_TREE;
+
+ for (binfo = TYPE_BINFO (ctype), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ {
+ tree basetype = BINFO_TYPE (base_binfo);
+
+ if (!assign_p && BINFO_VIRTUAL_P (base_binfo))
+ /* We'll handle virtual bases below. */
+ continue;
+
+ if (copy_arg_p)
+ argtype = build_stub_type (basetype, quals, move_p);
+ else if (basetype == inherited_base)
+ argtype = inherited_parms;
+ rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain);
+ if (inherited_base)
+ argtype = NULL_TREE;
+
+ process_subob_fn (rval, spec_p, trivial_p, deleted_p,
+ constexpr_p, diag, basetype);
+ if (ctor_p)
+ {
+ /* In a constructor we also need to check the subobject
+ destructors for cleanup of partially constructed objects. */
+ rval = locate_fn_flags (base_binfo, complete_dtor_identifier,
+ NULL_TREE, flags, complain);
+ /* Note that we don't pass down trivial_p; the subobject
+ destructors don't affect triviality of the constructor. Nor
+ do they affect constexpr-ness (a constant expression doesn't
+ throw) or exception-specification (a throw from one of the
+ dtors would be a double-fault). */
+ process_subob_fn (rval, NULL, NULL,
+ deleted_p, NULL, false,
+ basetype);
+ }
+
+ if (check_vdtor && type_has_virtual_destructor (basetype))
+ {
+ rval = locate_fn_flags (ctype, ansi_opname (DELETE_EXPR),
+ ptr_type_node, flags, complain);
+ /* Unlike for base ctor/op=/dtor, for operator delete it's fine
+ to have a null rval (no class-specific op delete). */
+ if (rval && rval == error_mark_node && deleted_p)
+ *deleted_p = true;
+ check_vdtor = false;
+ }
+
+ if (diag && assign_p && move_p
+ && BINFO_VIRTUAL_P (base_binfo)
+ && rval && TREE_CODE (rval) == FUNCTION_DECL
+ && move_fn_p (rval) && !trivial_fn_p (rval)
+ && vbase_has_user_provided_move_assign (basetype))
+ warning (OPT_Wvirtual_move_assign,
+ "defaulted move assignment for %qT calls a non-trivial "
+ "move assignment operator for virtual base %qT",
+ ctype, basetype);
+ }
+
+ vbases = CLASSTYPE_VBASECLASSES (ctype);
+ if (vec_safe_is_empty (vbases))
+ /* No virtual bases to worry about. */;
+ else if (!assign_p)
+ {
+ if (constexpr_p)
+ *constexpr_p = false;
+ FOR_EACH_VEC_ELT (*vbases, i, base_binfo)
+ {
+ tree basetype = BINFO_TYPE (base_binfo);
+ if (copy_arg_p)
+ argtype = build_stub_type (basetype, quals, move_p);
+ rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain);
+
+ process_subob_fn (rval, spec_p, trivial_p, deleted_p,
+ constexpr_p, diag, basetype);
+ if (ctor_p && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype))
+ {
+ rval = locate_fn_flags (base_binfo, complete_dtor_identifier,
+ NULL_TREE, flags, complain);
+ process_subob_fn (rval, NULL, NULL,
+ deleted_p, NULL, false,
+ basetype);
+ }
+ }
+ }
+
+ /* Now handle the non-static data members. */
+ walk_field_subobs (TYPE_FIELDS (ctype), fnname, sfk, quals,
+ copy_arg_p, move_p, assign_p, spec_p, trivial_p,
+ deleted_p, constexpr_p,
+ diag, flags, complain);
+ if (ctor_p)
+ walk_field_subobs (TYPE_FIELDS (ctype), complete_dtor_identifier,
+ sfk_destructor, TYPE_UNQUALIFIED, false,
+ false, false, NULL, NULL,
+ deleted_p, NULL,
+ false, flags, complain);
+
+ pop_scope (scope);
+
+ pop_deferring_access_checks ();
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+}
+
+/* DECL is a deleted function. If it's implicitly deleted, explain why and
+ return true; else return false. */
+
+bool
+maybe_explain_implicit_delete (tree decl)
+{
+ /* If decl is a clone, get the primary variant. */
+ decl = DECL_ORIGIN (decl);
+ gcc_assert (DECL_DELETED_FN (decl));
+ if (DECL_DEFAULTED_FN (decl))
+ {
+ /* Not marked GTY; it doesn't need to be GC'd or written to PCH. */
+ static struct pointer_set_t *explained;
+
+ special_function_kind sfk;
+ location_t loc;
+ bool informed;
+ tree ctype;
+
+ if (!explained)
+ explained = pointer_set_create ();
+ if (pointer_set_insert (explained, decl))
+ return true;
+
+ sfk = special_function_p (decl);
+ ctype = DECL_CONTEXT (decl);
+ loc = input_location;
+ input_location = DECL_SOURCE_LOCATION (decl);
+
+ informed = false;
+ if (LAMBDA_TYPE_P (ctype))
+ {
+ informed = true;
+ if (sfk == sfk_constructor)
+ inform (DECL_SOURCE_LOCATION (decl),
+ "a lambda closure type has a deleted default constructor");
+ else if (sfk == sfk_copy_assignment)
+ inform (DECL_SOURCE_LOCATION (decl),
+ "a lambda closure type has a deleted copy assignment operator");
+ else
+ informed = false;
+ }
+ else if (DECL_ARTIFICIAL (decl)
+ && (sfk == sfk_copy_assignment
+ || sfk == sfk_copy_constructor)
+ && (type_has_user_declared_move_constructor (ctype)
+ || type_has_user_declared_move_assign (ctype)))
+ {
+ inform (0, "%q+#D is implicitly declared as deleted because %qT "
+ "declares a move constructor or move assignment operator",
+ decl, ctype);
+ informed = true;
+ }
+ if (!informed)
+ {
+ tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
+ tree parm_type = TREE_VALUE (parms);
+ bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
+ tree raises = NULL_TREE;
+ bool deleted_p = false;
+ tree scope = push_scope (ctype);
+
+ synthesized_method_walk (ctype, sfk, const_p,
+ &raises, NULL, &deleted_p, NULL, false,
+ DECL_INHERITED_CTOR_BASE (decl), parms);
+ if (deleted_p)
+ {
+ inform (0, "%q+#D is implicitly deleted because the default "
+ "definition would be ill-formed:", decl);
+ synthesized_method_walk (ctype, sfk, const_p,
+ NULL, NULL, NULL, NULL, true,
+ DECL_INHERITED_CTOR_BASE (decl), parms);
+ }
+ else if (!comp_except_specs
+ (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)),
+ raises, ce_normal))
+ inform (DECL_SOURCE_LOCATION (decl), "%q#F is implicitly "
+ "deleted because its exception-specification does not "
+ "match the implicit exception-specification %qX",
+ decl, raises);
+#ifdef ENABLE_CHECKING
+ else
+ gcc_unreachable ();
+#endif
+
+ pop_scope (scope);
+ }
+
+ input_location = loc;
+ return true;
+ }
+ return false;
+}
+
+/* DECL is a defaulted function which was declared constexpr. Explain why
+ it can't be constexpr. */
+
+void
+explain_implicit_non_constexpr (tree decl)
+{
+ tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl));
+ bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
+ bool dummy;
+ synthesized_method_walk (DECL_CLASS_CONTEXT (decl),
+ special_function_p (decl), const_p,
+ NULL, NULL, NULL, &dummy, true,
+ NULL_TREE, NULL_TREE);
+}
+
+/* DECL is an instantiation of an inheriting constructor template. Deduce
+ the correct exception-specification and deletedness for this particular
+ specialization. */
+
+void
+deduce_inheriting_ctor (tree decl)
+{
+ gcc_assert (DECL_INHERITED_CTOR_BASE (decl));
+ tree spec;
+ bool trivial, constexpr_, deleted;
+ synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor,
+ false, &spec, &trivial, &deleted, &constexpr_,
+ /*diag*/false,
+ DECL_INHERITED_CTOR_BASE (decl),
+ FUNCTION_FIRST_USER_PARMTYPE (decl));
+ DECL_DELETED_FN (decl) = deleted;
+ TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
+}
+
+/* Implicitly declare the special function indicated by KIND, as a
+ member of TYPE. For copy constructors and assignment operators,
+ CONST_P indicates whether these functions should take a const
+ reference argument or a non-const reference. Returns the
+ FUNCTION_DECL for the implicitly declared function. */
+
+tree
+implicitly_declare_fn (special_function_kind kind, tree type,
+ bool const_p, tree inherited_ctor,
+ tree inherited_parms)
+{
+ tree fn;
+ tree parameter_types = void_list_node;
+ tree return_type;
+ tree fn_type;
+ tree raises = empty_except_spec;
+ tree rhs_parm_type = NULL_TREE;
+ tree this_parm;
+ tree name;
+ HOST_WIDE_INT saved_processing_template_decl;
+ bool deleted_p;
+ bool constexpr_p;
+
+ /* Because we create declarations for implicitly declared functions
+ lazily, we may be creating the declaration for a member of TYPE
+ while in some completely different context. However, TYPE will
+ never be a dependent class (because we never want to do lookups
+ for implicitly defined functions in a dependent class).
+ Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here
+ because we only create clones for constructors and destructors
+ when not in a template. */
+ gcc_assert (!dependent_type_p (type));
+ saved_processing_template_decl = processing_template_decl;
+ processing_template_decl = 0;
+
+ type = TYPE_MAIN_VARIANT (type);
+
+ if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (type))
+ {
+ if (kind == sfk_destructor)
+ /* See comment in check_special_function_return_type. */
+ return_type = build_pointer_type (void_type_node);
+ else
+ return_type = build_pointer_type (type);
+ }
+ else
+ return_type = void_type_node;
+
+ switch (kind)
+ {
+ case sfk_destructor:
+ /* Destructor. */
+ name = constructor_name (type);
+ break;
+
+ case sfk_constructor:
+ /* Default constructor. */
+ name = constructor_name (type);
+ break;
+
+ case sfk_copy_constructor:
+ case sfk_copy_assignment:
+ case sfk_move_constructor:
+ case sfk_move_assignment:
+ case sfk_inheriting_constructor:
+ {
+ bool move_p;
+ if (kind == sfk_copy_assignment
+ || kind == sfk_move_assignment)
+ {
+ return_type = build_reference_type (type);
+ name = ansi_assopname (NOP_EXPR);
+ }
+ else
+ name = constructor_name (type);
+
+ if (kind == sfk_inheriting_constructor)
+ parameter_types = inherited_parms;
+ else
+ {
+ if (const_p)
+ rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
+ else
+ rhs_parm_type = type;
+ move_p = (kind == sfk_move_assignment
+ || kind == sfk_move_constructor);
+ rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p);
+
+ parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
+ }
+ break;
+ }
+ default:
+ gcc_unreachable ();
+ }
+
+ tree inherited_base = (inherited_ctor
+ ? DECL_CONTEXT (inherited_ctor)
+ : NULL_TREE);
+ bool trivial_p = false;
+
+ if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
+ {
+ /* For an inheriting constructor template, just copy these flags from
+ the inherited constructor template for now. */
+ raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor));
+ deleted_p = DECL_DELETED_FN (inherited_ctor);
+ constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
+ }
+ else
+ synthesized_method_walk (type, kind, const_p, &raises, &trivial_p,
+ &deleted_p, &constexpr_p, false,
+ inherited_base, inherited_parms);
+ /* Don't bother marking a deleted constructor as constexpr. */
+ if (deleted_p)
+ constexpr_p = false;
+ /* A trivial copy/move constructor is also a constexpr constructor,
+ unless the class has virtual bases (7.1.5p4). */
+ else if (trivial_p && cxx_dialect >= cxx11
+ && (kind == sfk_copy_constructor
+ || kind == sfk_move_constructor)
+ && !CLASSTYPE_VBASECLASSES (type))
+ gcc_assert (constexpr_p);
+
+ if (!trivial_p && type_has_trivial_fn (type, kind))
+ type_set_nontrivial_flag (type, kind);
+
+ /* Create the function. */
+ fn_type = build_method_type_directly (type, return_type, parameter_types);
+ if (raises)
+ fn_type = build_exception_variant (fn_type, raises);
+ fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
+ if (kind != sfk_inheriting_constructor)
+ DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
+ if (kind == sfk_constructor || kind == sfk_copy_constructor
+ || kind == sfk_move_constructor || kind == sfk_inheriting_constructor)
+ DECL_CONSTRUCTOR_P (fn) = 1;
+ else if (kind == sfk_destructor)
+ DECL_DESTRUCTOR_P (fn) = 1;
+ else
+ {
+ DECL_ASSIGNMENT_OPERATOR_P (fn) = 1;
+ SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
+ }
+
+ /* If pointers to member functions use the least significant bit to
+ indicate whether a function is virtual, ensure a pointer
+ to this function will have that bit clear. */
+ if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+ && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
+ DECL_ALIGN (fn) = 2 * BITS_PER_UNIT;
+
+ /* Create the explicit arguments. */
+ if (rhs_parm_type)
+ {
+ /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
+ want its type to be included in the mangled function
+ name. */
+ tree decl = cp_build_parm_decl (NULL_TREE, rhs_parm_type);
+ TREE_READONLY (decl) = 1;
+ retrofit_lang_decl (decl);
+ DECL_PARM_INDEX (decl) = DECL_PARM_LEVEL (decl) = 1;
+ DECL_ARGUMENTS (fn) = decl;
+ }
+ else if (kind == sfk_inheriting_constructor)
+ {
+ tree *p = &DECL_ARGUMENTS (fn);
+ int index = 1;
+ for (tree parm = inherited_parms; parm != void_list_node;
+ parm = TREE_CHAIN (parm))
+ {
+ *p = cp_build_parm_decl (NULL_TREE, TREE_VALUE (parm));
+ retrofit_lang_decl (*p);
+ DECL_PARM_LEVEL (*p) = 1;
+ DECL_PARM_INDEX (*p) = index++;
+ DECL_CONTEXT (*p) = fn;
+ p = &DECL_CHAIN (*p);
+ }
+ SET_DECL_INHERITED_CTOR_BASE (fn, inherited_base);
+ DECL_NONCONVERTING_P (fn) = DECL_NONCONVERTING_P (inherited_ctor);
+ /* A constructor so declared has the same access as the corresponding
+ constructor in X. */
+ TREE_PRIVATE (fn) = TREE_PRIVATE (inherited_ctor);
+ TREE_PROTECTED (fn) = TREE_PROTECTED (inherited_ctor);
+ /* Copy constexpr from the inherited constructor even if the
+ inheriting constructor doesn't satisfy the requirements. */
+ constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
+ }
+ /* Add the "this" parameter. */
+ this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED);
+ DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
+ DECL_ARGUMENTS (fn) = this_parm;
+
+ grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);
+ set_linkage_according_to_type (type, fn);
+ rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
+ DECL_IN_AGGR_P (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ DECL_DEFAULTED_FN (fn) = 1;
+ if (cxx_dialect >= cxx11)
+ {
+ DECL_DELETED_FN (fn) = deleted_p;
+ DECL_DECLARED_CONSTEXPR_P (fn) = constexpr_p;
+ }
+ DECL_EXTERNAL (fn) = true;
+ DECL_NOT_REALLY_EXTERN (fn) = 1;
+ DECL_DECLARED_INLINE_P (fn) = 1;
+ gcc_assert (!TREE_USED (fn));
+
+ /* Restore PROCESSING_TEMPLATE_DECL. */
+ processing_template_decl = saved_processing_template_decl;
+
+ if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
+ fn = add_inherited_template_parms (fn, inherited_ctor);
+
+ /* Warn about calling a non-trivial move assignment in a virtual base. */
+ if (kind == sfk_move_assignment && !deleted_p && !trivial_p
+ && CLASSTYPE_VBASECLASSES (type))
+ {
+ location_t loc = input_location;
+ input_location = DECL_SOURCE_LOCATION (fn);
+ synthesized_method_walk (type, kind, const_p,
+ NULL, NULL, NULL, NULL, true,
+ NULL_TREE, NULL_TREE);
+ input_location = loc;
+ }
+
+ return fn;
+}
+
+/* Gives any errors about defaulted functions which need to be deferred
+ until the containing class is complete. */
+
+void
+defaulted_late_check (tree fn)
+{
+ /* Complain about invalid signature for defaulted fn. */
+ tree ctx = DECL_CONTEXT (fn);
+ special_function_kind kind = special_function_p (fn);
+ bool fn_const_p = (copy_fn_p (fn) == 2);
+ tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p,
+ NULL, NULL);
+ tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
+
+ if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)),
+ TREE_TYPE (TREE_TYPE (implicit_fn)))
+ || !compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
+ TYPE_ARG_TYPES (TREE_TYPE (implicit_fn))))
+ {
+ error ("defaulted declaration %q+D", fn);
+ error_at (DECL_SOURCE_LOCATION (fn),
+ "does not match expected signature %qD", implicit_fn);
+ }
+
+ /* 8.4.2/2: An explicitly-defaulted function (...) may have an explicit
+ exception-specification only if it is compatible (15.4) with the
+ exception-specification on the implicit declaration. If a function
+ is explicitly defaulted on its first declaration, (...) it is
+ implicitly considered to have the same exception-specification as if
+ it had been implicitly declared. */
+ if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
+ {
+ maybe_instantiate_noexcept (fn);
+ if (!comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)),
+ eh_spec, ce_normal))
+ {
+ if (DECL_DEFAULTED_IN_CLASS_P (fn))
+ {
+ DECL_DELETED_FN (fn) = true;
+ eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
+ }
+ else
+ error ("function %q+D defaulted on its redeclaration "
+ "with an exception-specification that differs from "
+ "the implicit declaration %q#D", fn, implicit_fn);
+ }
+ }
+ if (DECL_DEFAULTED_IN_CLASS_P (fn))
+ TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec);
+
+ if (DECL_DEFAULTED_IN_CLASS_P (fn)
+ && DECL_DECLARED_CONSTEXPR_P (implicit_fn))
+ {
+ /* Hmm...should we do this for out-of-class too? Should it be OK to
+ add constexpr later like inline, rather than requiring
+ declarations to match? */
+ DECL_DECLARED_CONSTEXPR_P (fn) = true;
+ if (kind == sfk_constructor)
+ TYPE_HAS_CONSTEXPR_CTOR (ctx) = true;
+ }
+
+ if (!DECL_DECLARED_CONSTEXPR_P (implicit_fn)
+ && DECL_DECLARED_CONSTEXPR_P (fn))
+ {
+ if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
+ {
+ error ("explicitly defaulted function %q+D cannot be declared "
+ "as constexpr because the implicit declaration is not "
+ "constexpr:", fn);
+ explain_implicit_non_constexpr (fn);
+ }
+ DECL_DECLARED_CONSTEXPR_P (fn) = false;
+ }
+
+ if (DECL_DELETED_FN (implicit_fn))
+ DECL_DELETED_FN (fn) = 1;
+}
+
+/* Returns true iff FN can be explicitly defaulted, and gives any
+ errors if defaulting FN is ill-formed. */
+
+bool
+defaultable_fn_check (tree fn)
+{
+ special_function_kind kind = sfk_none;
+
+ if (template_parm_scope_p ())
+ {
+ error ("a template cannot be defaulted");
+ return false;
+ }
+
+ if (DECL_CONSTRUCTOR_P (fn))
+ {
+ if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node)
+ kind = sfk_constructor;
+ else if (copy_fn_p (fn) > 0
+ && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn))
+ == void_list_node))
+ kind = sfk_copy_constructor;
+ else if (move_fn_p (fn))
+ kind = sfk_move_constructor;
+ }
+ else if (DECL_DESTRUCTOR_P (fn))
+ kind = sfk_destructor;
+ else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
+ && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR)
+ {
+ if (copy_fn_p (fn))
+ kind = sfk_copy_assignment;
+ else if (move_fn_p (fn))
+ kind = sfk_move_assignment;
+ }
+
+ if (kind == sfk_none)
+ {
+ error ("%qD cannot be defaulted", fn);
+ return false;
+ }
+ else
+ {
+ for (tree t = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ t && t != void_list_node; t = TREE_CHAIN (t))
+ if (TREE_PURPOSE (t))
+ {
+ error ("defaulted function %q+D with default argument", fn);
+ break;
+ }
+
+ /* Avoid do_warn_unused_parameter warnings. */
+ for (tree p = FUNCTION_FIRST_USER_PARM (fn); p; p = DECL_CHAIN (p))
+ if (DECL_NAME (p))
+ TREE_NO_WARNING (p) = 1;
+
+ if (TYPE_BEING_DEFINED (DECL_CONTEXT (fn)))
+ /* Defer checking. */;
+ else if (!processing_template_decl)
+ defaulted_late_check (fn);
+
+ return true;
+ }
+}
+
+/* Add an implicit declaration to TYPE for the kind of function
+ indicated by SFK. Return the FUNCTION_DECL for the new implicit
+ declaration. */
+
+tree
+lazily_declare_fn (special_function_kind sfk, tree type)
+{
+ tree fn;
+ /* Whether or not the argument has a const reference type. */
+ bool const_p = false;
+
+ switch (sfk)
+ {
+ case sfk_constructor:
+ CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0;
+ break;
+ case sfk_copy_constructor:
+ const_p = TYPE_HAS_CONST_COPY_CTOR (type);
+ CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
+ break;
+ case sfk_move_constructor:
+ CLASSTYPE_LAZY_MOVE_CTOR (type) = 0;
+ break;
+ case sfk_copy_assignment:
+ const_p = TYPE_HAS_CONST_COPY_ASSIGN (type);
+ CLASSTYPE_LAZY_COPY_ASSIGN (type) = 0;
+ break;
+ case sfk_move_assignment:
+ CLASSTYPE_LAZY_MOVE_ASSIGN (type) = 0;
+ break;
+ case sfk_destructor:
+ CLASSTYPE_LAZY_DESTRUCTOR (type) = 0;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ /* Declare the function. */
+ fn = implicitly_declare_fn (sfk, type, const_p, NULL, NULL);
+
+ /* [class.copy]/8 If the class definition declares a move constructor or
+ move assignment operator, the implicitly declared copy constructor is
+ defined as deleted.... */
+ if ((sfk == sfk_copy_assignment
+ || sfk == sfk_copy_constructor)
+ && (type_has_user_declared_move_constructor (type)
+ || type_has_user_declared_move_assign (type)))
+ DECL_DELETED_FN (fn) = true;
+
+ /* A destructor may be virtual. */
+ if (sfk == sfk_destructor
+ || sfk == sfk_move_assignment
+ || sfk == sfk_copy_assignment)
+ check_for_override (fn, type);
+ /* Add it to CLASSTYPE_METHOD_VEC. */
+ add_method (type, fn, NULL_TREE);
+ /* Add it to TYPE_METHODS. */
+ if (sfk == sfk_destructor
+ && DECL_VIRTUAL_P (fn)
+ && abi_version_at_least (2))
+ /* The ABI requires that a virtual destructor go at the end of the
+ vtable. */
+ TYPE_METHODS (type) = chainon (TYPE_METHODS (type), fn);
+ else
+ {
+ /* G++ 3.2 put the implicit destructor at the *beginning* of the
+ TYPE_METHODS list, which cause the destructor to be emitted
+ in an incorrect location in the vtable. */
+ if (warn_abi && sfk == sfk_destructor && DECL_VIRTUAL_P (fn))
+ warning (OPT_Wabi, "vtable layout for class %qT may not be ABI-compliant"
+ "and may change in a future version of GCC due to "
+ "implicit virtual destructor",
+ type);
+ DECL_CHAIN (fn) = TYPE_METHODS (type);
+ TYPE_METHODS (type) = fn;
+ }
+ maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
+ if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
+ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
+ /* Create appropriate clones. */
+ clone_function_decl (fn, /*update_method_vec=*/true);
+
+ return fn;
+}
+
+/* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
+ as there are artificial parms in FN. */
+
+tree
+skip_artificial_parms_for (const_tree fn, tree list)
+{
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+ list = TREE_CHAIN (list);
+ else
+ return list;
+
+ if (DECL_HAS_IN_CHARGE_PARM_P (fn))
+ list = TREE_CHAIN (list);
+ if (DECL_HAS_VTT_PARM_P (fn))
+ list = TREE_CHAIN (list);
+ return list;
+}
+
+/* Given a FUNCTION_DECL FN and a chain LIST, return the number of
+ artificial parms in FN. */
+
+int
+num_artificial_parms_for (const_tree fn)
+{
+ int count = 0;
+
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+ count++;
+ else
+ return 0;
+
+ if (DECL_HAS_IN_CHARGE_PARM_P (fn))
+ count++;
+ if (DECL_HAS_VTT_PARM_P (fn))
+ count++;
+ return count;
+}
+
+
+#include "gt-cp-method.h"
diff --git a/gcc-4.9/gcc/cp/name-lookup.c b/gcc-4.9/gcc/cp/name-lookup.c
new file mode 100644
index 000000000..53f14f3ee
--- /dev/null
+++ b/gcc-4.9/gcc/cp/name-lookup.c
@@ -0,0 +1,6236 @@
+/* Definitions for C++ name lookup routines.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "flags.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "print-tree.h"
+#include "attribs.h"
+#include "cp-tree.h"
+#include "name-lookup.h"
+#include "timevar.h"
+#include "diagnostic-core.h"
+#include "intl.h"
+#include "debug.h"
+#include "c-family/c-pragma.h"
+#include "params.h"
+#include "pointer-set.h"
+
+/* The bindings for a particular name in a particular scope. */
+
+struct scope_binding {
+ tree value;
+ tree type;
+};
+#define EMPTY_SCOPE_BINDING { NULL_TREE, NULL_TREE }
+
+static cp_binding_level *innermost_nonclass_level (void);
+static cxx_binding *binding_for_name (cp_binding_level *, tree);
+static tree push_overloaded_decl (tree, int, bool);
+static bool lookup_using_namespace (tree, struct scope_binding *, tree,
+ tree, int);
+static bool qualified_lookup_using_namespace (tree, tree,
+ struct scope_binding *, int);
+static tree lookup_type_current_level (tree);
+static tree push_using_directive (tree);
+static tree lookup_extern_c_fun_in_all_ns (tree);
+static void diagnose_name_conflict (tree, tree);
+
+/* The :: namespace. */
+
+tree global_namespace;
+
+/* The name of the anonymous namespace, throughout this translation
+ unit. */
+static GTY(()) tree anonymous_namespace_name;
+
+/* Initialize anonymous_namespace_name if necessary, and return it. */
+
+static tree
+get_anonymous_namespace_name (void)
+{
+ if (!anonymous_namespace_name)
+ {
+ /* We used to use get_file_function_name here, but that isn't
+ necessary now that anonymous namespace typeinfos
+ are !TREE_PUBLIC, and thus compared by address. */
+ /* The demangler expects anonymous namespaces to be called
+ something starting with '_GLOBAL__N_'. */
+ anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
+ }
+ return anonymous_namespace_name;
+}
+
+/* Compute the chain index of a binding_entry given the HASH value of its
+ name and the total COUNT of chains. COUNT is assumed to be a power
+ of 2. */
+
+#define ENTRY_INDEX(HASH, COUNT) (((HASH) >> 3) & ((COUNT) - 1))
+
+/* A free list of "binding_entry"s awaiting for re-use. */
+
+static GTY((deletable)) binding_entry free_binding_entry = NULL;
+
+/* Create a binding_entry object for (NAME, TYPE). */
+
+static inline binding_entry
+binding_entry_make (tree name, tree type)
+{
+ binding_entry entry;
+
+ if (free_binding_entry)
+ {
+ entry = free_binding_entry;
+ free_binding_entry = entry->chain;
+ }
+ else
+ entry = ggc_alloc_binding_entry_s ();
+
+ entry->name = name;
+ entry->type = type;
+ entry->chain = NULL;
+
+ return entry;
+}
+
+/* Put ENTRY back on the free list. */
+#if 0
+static inline void
+binding_entry_free (binding_entry entry)
+{
+ entry->name = NULL;
+ entry->type = NULL;
+ entry->chain = free_binding_entry;
+ free_binding_entry = entry;
+}
+#endif
+
+/* The datatype used to implement the mapping from names to types at
+ a given scope. */
+struct GTY(()) binding_table_s {
+ /* Array of chains of "binding_entry"s */
+ binding_entry * GTY((length ("%h.chain_count"))) chain;
+
+ /* The number of chains in this table. This is the length of the
+ member "chain" considered as an array. */
+ size_t chain_count;
+
+ /* Number of "binding_entry"s in this table. */
+ size_t entry_count;
+};
+
+/* Construct TABLE with an initial CHAIN_COUNT. */
+
+static inline void
+binding_table_construct (binding_table table, size_t chain_count)
+{
+ table->chain_count = chain_count;
+ table->entry_count = 0;
+ table->chain = ggc_alloc_cleared_vec_binding_entry (table->chain_count);
+}
+
+/* Make TABLE's entries ready for reuse. */
+#if 0
+static void
+binding_table_free (binding_table table)
+{
+ size_t i;
+ size_t count;
+
+ if (table == NULL)
+ return;
+
+ for (i = 0, count = table->chain_count; i < count; ++i)
+ {
+ binding_entry temp = table->chain[i];
+ while (temp != NULL)
+ {
+ binding_entry entry = temp;
+ temp = entry->chain;
+ binding_entry_free (entry);
+ }
+ table->chain[i] = NULL;
+ }
+ table->entry_count = 0;
+}
+#endif
+
+/* Allocate a table with CHAIN_COUNT, assumed to be a power of two. */
+
+static inline binding_table
+binding_table_new (size_t chain_count)
+{
+ binding_table table = ggc_alloc_binding_table_s ();
+ table->chain = NULL;
+ binding_table_construct (table, chain_count);
+ return table;
+}
+
+/* Expand TABLE to twice its current chain_count. */
+
+static void
+binding_table_expand (binding_table table)
+{
+ const size_t old_chain_count = table->chain_count;
+ const size_t old_entry_count = table->entry_count;
+ const size_t new_chain_count = 2 * old_chain_count;
+ binding_entry *old_chains = table->chain;
+ size_t i;
+
+ binding_table_construct (table, new_chain_count);
+ for (i = 0; i < old_chain_count; ++i)
+ {
+ binding_entry entry = old_chains[i];
+ for (; entry != NULL; entry = old_chains[i])
+ {
+ const unsigned int hash = IDENTIFIER_HASH_VALUE (entry->name);
+ const size_t j = ENTRY_INDEX (hash, new_chain_count);
+
+ old_chains[i] = entry->chain;
+ entry->chain = table->chain[j];
+ table->chain[j] = entry;
+ }
+ }
+ table->entry_count = old_entry_count;
+}
+
+/* Insert a binding for NAME to TYPE into TABLE. */
+
+static void
+binding_table_insert (binding_table table, tree name, tree type)
+{
+ const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
+ const size_t i = ENTRY_INDEX (hash, table->chain_count);
+ binding_entry entry = binding_entry_make (name, type);
+
+ entry->chain = table->chain[i];
+ table->chain[i] = entry;
+ ++table->entry_count;
+
+ if (3 * table->chain_count < 5 * table->entry_count)
+ binding_table_expand (table);
+}
+
+/* Return the binding_entry, if any, that maps NAME. */
+
+binding_entry
+binding_table_find (binding_table table, tree name)
+{
+ const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
+ binding_entry entry = table->chain[ENTRY_INDEX (hash, table->chain_count)];
+
+ while (entry != NULL && entry->name != name)
+ entry = entry->chain;
+
+ return entry;
+}
+
+/* Apply PROC -- with DATA -- to all entries in TABLE. */
+
+void
+binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
+{
+ size_t chain_count;
+ size_t i;
+
+ if (!table)
+ return;
+
+ chain_count = table->chain_count;
+ for (i = 0; i < chain_count; ++i)
+ {
+ binding_entry entry = table->chain[i];
+ for (; entry != NULL; entry = entry->chain)
+ proc (entry, data);
+ }
+}
+
+#ifndef ENABLE_SCOPE_CHECKING
+# define ENABLE_SCOPE_CHECKING 0
+#else
+# define ENABLE_SCOPE_CHECKING 1
+#endif
+
+/* A free list of "cxx_binding"s, connected by their PREVIOUS. */
+
+static GTY((deletable)) cxx_binding *free_bindings;
+
+/* Initialize VALUE and TYPE field for BINDING, and set the PREVIOUS
+ field to NULL. */
+
+static inline void
+cxx_binding_init (cxx_binding *binding, tree value, tree type)
+{
+ binding->value = value;
+ binding->type = type;
+ binding->previous = NULL;
+}
+
+/* (GC)-allocate a binding object with VALUE and TYPE member initialized. */
+
+static cxx_binding *
+cxx_binding_make (tree value, tree type)
+{
+ cxx_binding *binding;
+ if (free_bindings)
+ {
+ binding = free_bindings;
+ free_bindings = binding->previous;
+ }
+ else
+ binding = ggc_alloc_cxx_binding ();
+
+ cxx_binding_init (binding, value, type);
+
+ return binding;
+}
+
+/* Put BINDING back on the free list. */
+
+static inline void
+cxx_binding_free (cxx_binding *binding)
+{
+ binding->scope = NULL;
+ binding->previous = free_bindings;
+ free_bindings = binding;
+}
+
+/* Create a new binding for NAME (with the indicated VALUE and TYPE
+ bindings) in the class scope indicated by SCOPE. */
+
+static cxx_binding *
+new_class_binding (tree name, tree value, tree type, cp_binding_level *scope)
+{
+ cp_class_binding cb = {cxx_binding_make (value, type), name};
+ cxx_binding *binding = cb.base;
+ vec_safe_push (scope->class_shadowed, cb);
+ binding->scope = scope;
+ return binding;
+}
+
+/* Make DECL the innermost binding for ID. The LEVEL is the binding
+ level at which this declaration is being bound. */
+
+static void
+push_binding (tree id, tree decl, cp_binding_level* level)
+{
+ cxx_binding *binding;
+
+ if (level != class_binding_level)
+ {
+ binding = cxx_binding_make (decl, NULL_TREE);
+ binding->scope = level;
+ }
+ else
+ binding = new_class_binding (id, decl, /*type=*/NULL_TREE, level);
+
+ /* Now, fill in the binding information. */
+ binding->previous = IDENTIFIER_BINDING (id);
+ INHERITED_VALUE_BINDING_P (binding) = 0;
+ LOCAL_BINDING_P (binding) = (level != class_binding_level);
+
+ /* And put it on the front of the list of bindings for ID. */
+ IDENTIFIER_BINDING (id) = binding;
+}
+
+/* Remove the binding for DECL which should be the innermost binding
+ for ID. */
+
+void
+pop_binding (tree id, tree decl)
+{
+ cxx_binding *binding;
+
+ if (id == NULL_TREE)
+ /* It's easiest to write the loops that call this function without
+ checking whether or not the entities involved have names. We
+ get here for such an entity. */
+ return;
+
+ /* Get the innermost binding for ID. */
+ binding = IDENTIFIER_BINDING (id);
+
+ /* The name should be bound. */
+ gcc_assert (binding != NULL);
+
+ /* The DECL will be either the ordinary binding or the type
+ binding for this identifier. Remove that binding. */
+ if (binding->value == decl)
+ binding->value = NULL_TREE;
+ else
+ {
+ gcc_assert (binding->type == decl);
+ binding->type = NULL_TREE;
+ }
+
+ if (!binding->value && !binding->type)
+ {
+ /* We're completely done with the innermost binding for this
+ identifier. Unhook it from the list of bindings. */
+ IDENTIFIER_BINDING (id) = binding->previous;
+
+ /* Add it to the free list. */
+ cxx_binding_free (binding);
+ }
+}
+
+/* Remove the bindings for the decls of the current level and leave
+ the current scope. */
+
+void
+pop_bindings_and_leave_scope (void)
+{
+ for (tree t = getdecls (); t; t = DECL_CHAIN (t))
+ pop_binding (DECL_NAME (t), t);
+ leave_scope ();
+}
+
+/* Strip non dependent using declarations. If DECL is dependent,
+ surreptitiously create a typename_type and return it. */
+
+tree
+strip_using_decl (tree decl)
+{
+ if (decl == NULL_TREE)
+ return NULL_TREE;
+
+ while (TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
+ decl = USING_DECL_DECLS (decl);
+
+ if (TREE_CODE (decl) == USING_DECL && DECL_DEPENDENT_P (decl)
+ && USING_DECL_TYPENAME_P (decl))
+ {
+ /* We have found a type introduced by a using
+ declaration at class scope that refers to a dependent
+ type.
+
+ using typename :: [opt] nested-name-specifier unqualified-id ;
+ */
+ decl = make_typename_type (TREE_TYPE (decl),
+ DECL_NAME (decl),
+ typename_type, tf_error);
+ if (decl != error_mark_node)
+ decl = TYPE_NAME (decl);
+ }
+
+ return decl;
+}
+
+/* BINDING records an existing declaration for a name in the current scope.
+ But, DECL is another declaration for that same identifier in the
+ same scope. This is the `struct stat' hack whereby a non-typedef
+ class name or enum-name can be bound at the same level as some other
+ kind of entity.
+ 3.3.7/1
+
+ A class name (9.1) or enumeration name (7.2) can be hidden by the
+ name of an object, function, or enumerator declared in the same scope.
+ If a class or enumeration name and an object, function, or enumerator
+ are declared in the same scope (in any order) with the same name, the
+ class or enumeration name is hidden wherever the object, function, or
+ enumerator name is visible.
+
+ It's the responsibility of the caller to check that
+ inserting this name is valid here. Returns nonzero if the new binding
+ was successful. */
+
+static bool
+supplement_binding_1 (cxx_binding *binding, tree decl)
+{
+ tree bval = binding->value;
+ bool ok = true;
+ tree target_bval = strip_using_decl (bval);
+ tree target_decl = strip_using_decl (decl);
+
+ if (TREE_CODE (target_decl) == TYPE_DECL && DECL_ARTIFICIAL (target_decl)
+ && target_decl != target_bval
+ && (TREE_CODE (target_bval) != TYPE_DECL
+ /* We allow pushing an enum multiple times in a class
+ template in order to handle late matching of underlying
+ type on an opaque-enum-declaration followed by an
+ enum-specifier. */
+ || (processing_template_decl
+ && TREE_CODE (TREE_TYPE (target_decl)) == ENUMERAL_TYPE
+ && TREE_CODE (TREE_TYPE (target_bval)) == ENUMERAL_TYPE
+ && (dependent_type_p (ENUM_UNDERLYING_TYPE
+ (TREE_TYPE (target_decl)))
+ || dependent_type_p (ENUM_UNDERLYING_TYPE
+ (TREE_TYPE (target_bval)))))))
+ /* The new name is the type name. */
+ binding->type = decl;
+ else if (/* TARGET_BVAL is null when push_class_level_binding moves
+ an inherited type-binding out of the way to make room
+ for a new value binding. */
+ !target_bval
+ /* TARGET_BVAL is error_mark_node when TARGET_DECL's name
+ has been used in a non-class scope prior declaration.
+ In that case, we should have already issued a
+ diagnostic; for graceful error recovery purpose, pretend
+ this was the intended declaration for that name. */
+ || target_bval == error_mark_node
+ /* If TARGET_BVAL is anticipated but has not yet been
+ declared, pretend it is not there at all. */
+ || (TREE_CODE (target_bval) == FUNCTION_DECL
+ && DECL_ANTICIPATED (target_bval)
+ && !DECL_HIDDEN_FRIEND_P (target_bval)))
+ binding->value = decl;
+ else if (TREE_CODE (target_bval) == TYPE_DECL
+ && DECL_ARTIFICIAL (target_bval)
+ && target_decl != target_bval
+ && (TREE_CODE (target_decl) != TYPE_DECL
+ || same_type_p (TREE_TYPE (target_decl),
+ TREE_TYPE (target_bval))))
+ {
+ /* The old binding was a type name. It was placed in
+ VALUE field because it was thought, at the point it was
+ declared, to be the only entity with such a name. Move the
+ type name into the type slot; it is now hidden by the new
+ binding. */
+ binding->type = bval;
+ binding->value = decl;
+ binding->value_is_inherited = false;
+ }
+ else if (TREE_CODE (target_bval) == TYPE_DECL
+ && TREE_CODE (target_decl) == TYPE_DECL
+ && DECL_NAME (target_decl) == DECL_NAME (target_bval)
+ && binding->scope->kind != sk_class
+ && (same_type_p (TREE_TYPE (target_decl), TREE_TYPE (target_bval))
+ /* If either type involves template parameters, we must
+ wait until instantiation. */
+ || uses_template_parms (TREE_TYPE (target_decl))
+ || uses_template_parms (TREE_TYPE (target_bval))))
+ /* We have two typedef-names, both naming the same type to have
+ the same name. In general, this is OK because of:
+
+ [dcl.typedef]
+
+ In a given scope, a typedef specifier can be used to redefine
+ the name of any type declared in that scope to refer to the
+ type to which it already refers.
+
+ However, in class scopes, this rule does not apply due to the
+ stricter language in [class.mem] prohibiting redeclarations of
+ members. */
+ ok = false;
+ /* There can be two block-scope declarations of the same variable,
+ so long as they are `extern' declarations. However, there cannot
+ be two declarations of the same static data member:
+
+ [class.mem]
+
+ A member shall not be declared twice in the
+ member-specification. */
+ else if (VAR_P (target_decl)
+ && VAR_P (target_bval)
+ && DECL_EXTERNAL (target_decl) && DECL_EXTERNAL (target_bval)
+ && !DECL_CLASS_SCOPE_P (target_decl))
+ {
+ duplicate_decls (decl, binding->value, /*newdecl_is_friend=*/false);
+ ok = false;
+ }
+ else if (TREE_CODE (decl) == NAMESPACE_DECL
+ && TREE_CODE (bval) == NAMESPACE_DECL
+ && DECL_NAMESPACE_ALIAS (decl)
+ && DECL_NAMESPACE_ALIAS (bval)
+ && ORIGINAL_NAMESPACE (bval) == ORIGINAL_NAMESPACE (decl))
+ /* [namespace.alias]
+
+ In a declarative region, a namespace-alias-definition can be
+ used to redefine a namespace-alias declared in that declarative
+ region to refer only to the namespace to which it already
+ refers. */
+ ok = false;
+ else
+ {
+ diagnose_name_conflict (decl, bval);
+ ok = false;
+ }
+
+ return ok;
+}
+
+/* Diagnose a name conflict between DECL and BVAL. */
+
+static void
+diagnose_name_conflict (tree decl, tree bval)
+{
+ if (TREE_CODE (decl) == TREE_CODE (bval)
+ && (TREE_CODE (decl) != TYPE_DECL
+ || (DECL_ARTIFICIAL (decl) && DECL_ARTIFICIAL (bval))
+ || (!DECL_ARTIFICIAL (decl) && !DECL_ARTIFICIAL (bval)))
+ && !is_overloaded_fn (decl))
+ error ("redeclaration of %q#D", decl);
+ else
+ error ("%q#D conflicts with a previous declaration", decl);
+
+ inform (input_location, "previous declaration %q+#D", bval);
+}
+
+/* Wrapper for supplement_binding_1. */
+
+static bool
+supplement_binding (cxx_binding *binding, tree decl)
+{
+ bool ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = supplement_binding_1 (binding, decl);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+/* Add DECL to the list of things declared in B. */
+
+static void
+add_decl_to_level (tree decl, cp_binding_level *b)
+{
+ /* We used to record virtual tables as if they were ordinary
+ variables, but no longer do so. */
+ gcc_assert (!(VAR_P (decl) && DECL_VIRTUAL_P (decl)));
+
+ if (TREE_CODE (decl) == NAMESPACE_DECL
+ && !DECL_NAMESPACE_ALIAS (decl))
+ {
+ DECL_CHAIN (decl) = b->namespaces;
+ b->namespaces = decl;
+ }
+ else
+ {
+ /* We build up the list in reverse order, and reverse it later if
+ necessary. */
+ TREE_CHAIN (decl) = b->names;
+ b->names = decl;
+
+ /* If appropriate, add decl to separate list of statics. We
+ include extern variables because they might turn out to be
+ static later. It's OK for this list to contain a few false
+ positives. */
+ if (b->kind == sk_namespace)
+ if ((VAR_P (decl)
+ && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
+ || (TREE_CODE (decl) == FUNCTION_DECL
+ && (!TREE_PUBLIC (decl)
+ || decl_anon_ns_mem_p (decl)
+ || DECL_DECLARED_INLINE_P (decl))))
+ vec_safe_push (b->static_decls, decl);
+ }
+}
+
+/* Record a decl-node X as belonging to the current lexical scope.
+ Check for errors (such as an incompatible declaration for the same
+ name already seen in the same scope). IS_FRIEND is true if X is
+ declared as a friend.
+
+ Returns either X or an old decl for the same name.
+ If an old decl is returned, it may have been smashed
+ to agree with what X says. */
+
+static tree
+pushdecl_maybe_friend_1 (tree x, bool is_friend)
+{
+ tree t;
+ tree name;
+ int need_new_binding;
+
+ if (x == error_mark_node)
+ return error_mark_node;
+
+ need_new_binding = 1;
+
+ if (DECL_TEMPLATE_PARM_P (x))
+ /* Template parameters have no context; they are not X::T even
+ when declared within a class or namespace. */
+ ;
+ else
+ {
+ if (current_function_decl && x != current_function_decl
+ /* A local declaration for a function doesn't constitute
+ nesting. */
+ && TREE_CODE (x) != FUNCTION_DECL
+ /* A local declaration for an `extern' variable is in the
+ scope of the current namespace, not the current
+ function. */
+ && !(VAR_P (x) && DECL_EXTERNAL (x))
+ /* When parsing the parameter list of a function declarator,
+ don't set DECL_CONTEXT to an enclosing function. When we
+ push the PARM_DECLs in order to process the function body,
+ current_binding_level->this_entity will be set. */
+ && !(TREE_CODE (x) == PARM_DECL
+ && current_binding_level->kind == sk_function_parms
+ && current_binding_level->this_entity == NULL)
+ && !DECL_CONTEXT (x))
+ DECL_CONTEXT (x) = current_function_decl;
+
+ /* If this is the declaration for a namespace-scope function,
+ but the declaration itself is in a local scope, mark the
+ declaration. */
+ if (TREE_CODE (x) == FUNCTION_DECL
+ && DECL_NAMESPACE_SCOPE_P (x)
+ && current_function_decl
+ && x != current_function_decl)
+ DECL_LOCAL_FUNCTION_P (x) = 1;
+ }
+
+ name = DECL_NAME (x);
+ if (name)
+ {
+ int different_binding_level = 0;
+
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ name = TREE_OPERAND (name, 0);
+
+ /* In case this decl was explicitly namespace-qualified, look it
+ up in its namespace context. */
+ if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())
+ t = namespace_binding (name, DECL_CONTEXT (x));
+ else
+ t = lookup_name_innermost_nonclass_level (name);
+
+ /* [basic.link] If there is a visible declaration of an entity
+ with linkage having the same name and type, ignoring entities
+ declared outside the innermost enclosing namespace scope, the
+ block scope declaration declares that same entity and
+ receives the linkage of the previous declaration. */
+ if (! t && current_function_decl && x != current_function_decl
+ && VAR_OR_FUNCTION_DECL_P (x)
+ && DECL_EXTERNAL (x))
+ {
+ /* Look in block scope. */
+ t = innermost_non_namespace_value (name);
+ /* Or in the innermost namespace. */
+ if (! t)
+ t = namespace_binding (name, DECL_CONTEXT (x));
+ /* Does it have linkage? Note that if this isn't a DECL, it's an
+ OVERLOAD, which is OK. */
+ if (t && DECL_P (t) && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
+ t = NULL_TREE;
+ if (t)
+ different_binding_level = 1;
+ }
+
+ /* If we are declaring a function, and the result of name-lookup
+ was an OVERLOAD, look for an overloaded instance that is
+ actually the same as the function we are declaring. (If
+ there is one, we have to merge our declaration with the
+ previous declaration.) */
+ if (t && TREE_CODE (t) == OVERLOAD)
+ {
+ tree match;
+
+ if (TREE_CODE (x) == FUNCTION_DECL)
+ for (match = t; match; match = OVL_NEXT (match))
+ {
+ if (decls_match (OVL_CURRENT (match), x))
+ break;
+ }
+ else
+ /* Just choose one. */
+ match = t;
+
+ if (match)
+ t = OVL_CURRENT (match);
+ else
+ t = NULL_TREE;
+ }
+
+ if (t && t != error_mark_node)
+ {
+ if (different_binding_level)
+ {
+ if (decls_match (x, t))
+ /* The standard only says that the local extern
+ inherits linkage from the previous decl; in
+ particular, default args are not shared. Add
+ the decl into a hash table to make sure only
+ the previous decl in this case is seen by the
+ middle end. */
+ {
+ struct cxx_int_tree_map *h;
+ void **loc;
+
+ TREE_PUBLIC (x) = TREE_PUBLIC (t);
+
+ if (cp_function_chain->extern_decl_map == NULL)
+ cp_function_chain->extern_decl_map
+ = htab_create_ggc (20, cxx_int_tree_map_hash,
+ cxx_int_tree_map_eq, NULL);
+
+ h = ggc_alloc_cxx_int_tree_map ();
+ h->uid = DECL_UID (x);
+ h->to = t;
+ loc = htab_find_slot_with_hash
+ (cp_function_chain->extern_decl_map, h,
+ h->uid, INSERT);
+ *(struct cxx_int_tree_map **) loc = h;
+ }
+ }
+ else if (TREE_CODE (t) == PARM_DECL)
+ {
+ /* Check for duplicate params. */
+ tree d = duplicate_decls (x, t, is_friend);
+ if (d)
+ return d;
+ }
+ else if ((DECL_EXTERN_C_FUNCTION_P (x)
+ || DECL_FUNCTION_TEMPLATE_P (x))
+ && is_overloaded_fn (t))
+ /* Don't do anything just yet. */;
+ else if (t == wchar_decl_node)
+ {
+ if (! DECL_IN_SYSTEM_HEADER (x))
+ pedwarn (input_location, OPT_Wpedantic, "redeclaration of %<wchar_t%> as %qT",
+ TREE_TYPE (x));
+
+ /* Throw away the redeclaration. */
+ return t;
+ }
+ else
+ {
+ tree olddecl = duplicate_decls (x, t, is_friend);
+
+ /* If the redeclaration failed, we can stop at this
+ point. */
+ if (olddecl == error_mark_node)
+ return error_mark_node;
+
+ if (olddecl)
+ {
+ if (TREE_CODE (t) == TYPE_DECL)
+ SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
+
+ return t;
+ }
+ else if (DECL_MAIN_P (x) && TREE_CODE (t) == FUNCTION_DECL)
+ {
+ /* A redeclaration of main, but not a duplicate of the
+ previous one.
+
+ [basic.start.main]
+
+ This function shall not be overloaded. */
+ error ("invalid redeclaration of %q+D", t);
+ error ("as %qD", x);
+ /* We don't try to push this declaration since that
+ causes a crash. */
+ return x;
+ }
+ }
+ }
+
+ /* If x has C linkage-specification, (extern "C"),
+ lookup its binding, in case it's already bound to an object.
+ The lookup is done in all namespaces.
+ If we find an existing binding, make sure it has the same
+ exception specification as x, otherwise, bail in error [7.5, 7.6]. */
+ if ((TREE_CODE (x) == FUNCTION_DECL)
+ && DECL_EXTERN_C_P (x)
+ /* We should ignore declarations happening in system headers. */
+ && !DECL_ARTIFICIAL (x)
+ && !DECL_IN_SYSTEM_HEADER (x))
+ {
+ tree previous = lookup_extern_c_fun_in_all_ns (x);
+ if (previous
+ && !DECL_ARTIFICIAL (previous)
+ && !DECL_IN_SYSTEM_HEADER (previous)
+ && DECL_CONTEXT (previous) != DECL_CONTEXT (x))
+ {
+ /* In case either x or previous is declared to throw an exception,
+ make sure both exception specifications are equal. */
+ if (decls_match (x, previous))
+ {
+ tree x_exception_spec = NULL_TREE;
+ tree previous_exception_spec = NULL_TREE;
+
+ x_exception_spec =
+ TYPE_RAISES_EXCEPTIONS (TREE_TYPE (x));
+ previous_exception_spec =
+ TYPE_RAISES_EXCEPTIONS (TREE_TYPE (previous));
+ if (!comp_except_specs (previous_exception_spec,
+ x_exception_spec,
+ ce_normal))
+ {
+ pedwarn (input_location, 0,
+ "declaration of %q#D with C language linkage",
+ x);
+ pedwarn (input_location, 0,
+ "conflicts with previous declaration %q+#D",
+ previous);
+ pedwarn (input_location, 0,
+ "due to different exception specifications");
+ return error_mark_node;
+ }
+ if (DECL_ASSEMBLER_NAME_SET_P (previous))
+ SET_DECL_ASSEMBLER_NAME (x,
+ DECL_ASSEMBLER_NAME (previous));
+ }
+ else
+ {
+ pedwarn (input_location, 0,
+ "declaration of %q#D with C language linkage", x);
+ pedwarn (input_location, 0,
+ "conflicts with previous declaration %q+#D",
+ previous);
+ }
+ }
+ }
+
+ check_template_shadow (x);
+
+ /* If this is a function conjured up by the back end, massage it
+ so it looks friendly. */
+ if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_LANG_SPECIFIC (x))
+ {
+ retrofit_lang_decl (x);
+ SET_DECL_LANGUAGE (x, lang_c);
+ }
+
+ t = x;
+ if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_FUNCTION_MEMBER_P (x))
+ {
+ t = push_overloaded_decl (x, PUSH_LOCAL, is_friend);
+ if (!namespace_bindings_p ())
+ /* We do not need to create a binding for this name;
+ push_overloaded_decl will have already done so if
+ necessary. */
+ need_new_binding = 0;
+ }
+ else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
+ {
+ t = push_overloaded_decl (x, PUSH_GLOBAL, is_friend);
+ if (t == x)
+ add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
+ }
+
+ if (DECL_DECLARES_FUNCTION_P (t))
+ check_default_args (t);
+
+ if (t != x || DECL_FUNCTION_TEMPLATE_P (t))
+ return t;
+
+ /* If declaring a type as a typedef, copy the type (unless we're
+ at line 0), and install this TYPE_DECL as the new type's typedef
+ name. See the extensive comment of set_underlying_type (). */
+ if (TREE_CODE (x) == TYPE_DECL)
+ {
+ tree type = TREE_TYPE (x);
+
+ if (DECL_IS_BUILTIN (x)
+ || (TREE_TYPE (x) != error_mark_node
+ && TYPE_NAME (type) != x
+ /* We don't want to copy the type when all we're
+ doing is making a TYPE_DECL for the purposes of
+ inlining. */
+ && (!TYPE_NAME (type)
+ || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x))))
+ set_underlying_type (x);
+
+ if (type != error_mark_node
+ && TYPE_NAME (type)
+ && TYPE_IDENTIFIER (type))
+ set_identifier_type_value (DECL_NAME (x), x);
+
+ /* If this is a locally defined typedef in a function that
+ is not a template instantation, record it to implement
+ -Wunused-local-typedefs. */
+ if (current_instantiation () == NULL
+ || (current_instantiation ()->decl != current_function_decl))
+ record_locally_defined_typedef (x);
+ }
+
+ /* Multiple external decls of the same identifier ought to match.
+
+ We get warnings about inline functions where they are defined.
+ We get warnings about other functions from push_overloaded_decl.
+
+ Avoid duplicate warnings where they are used. */
+ if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL)
+ {
+ tree decl;
+
+ decl = IDENTIFIER_NAMESPACE_VALUE (name);
+ if (decl && TREE_CODE (decl) == OVERLOAD)
+ decl = OVL_FUNCTION (decl);
+
+ if (decl && decl != error_mark_node
+ && (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl))
+ /* If different sort of thing, we already gave an error. */
+ && TREE_CODE (decl) == TREE_CODE (x)
+ && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl)))
+ {
+ if (permerror (input_location, "type mismatch with previous "
+ "external decl of %q#D", x))
+ inform (input_location, "previous external decl of %q+#D",
+ decl);
+ }
+ }
+
+ if (TREE_CODE (x) == FUNCTION_DECL
+ && is_friend
+ && !flag_friend_injection)
+ {
+ /* This is a new declaration of a friend function, so hide
+ it from ordinary function lookup. */
+ DECL_ANTICIPATED (x) = 1;
+ DECL_HIDDEN_FRIEND_P (x) = 1;
+ }
+
+ /* This name is new in its binding level.
+ Install the new declaration and return it. */
+ if (namespace_bindings_p ())
+ {
+ /* Install a global value. */
+
+ /* If the first global decl has external linkage,
+ warn if we later see static one. */
+ if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
+ TREE_PUBLIC (name) = 1;
+
+ /* Bind the name for the entity. */
+ if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
+ && t != NULL_TREE)
+ && (TREE_CODE (x) == TYPE_DECL
+ || VAR_P (x)
+ || TREE_CODE (x) == NAMESPACE_DECL
+ || TREE_CODE (x) == CONST_DECL
+ || TREE_CODE (x) == TEMPLATE_DECL))
+ SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
+
+ /* If new decl is `static' and an `extern' was seen previously,
+ warn about it. */
+ if (x != NULL_TREE && t != NULL_TREE && decls_match (x, t))
+ warn_extern_redeclared_static (x, t);
+ }
+ else
+ {
+ /* Here to install a non-global value. */
+ tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
+ tree oldlocal = NULL_TREE;
+ cp_binding_level *oldscope = NULL;
+ cxx_binding *oldbinding = outer_binding (name, NULL, true);
+ if (oldbinding)
+ {
+ oldlocal = oldbinding->value;
+ oldscope = oldbinding->scope;
+ }
+
+ if (need_new_binding)
+ {
+ push_local_binding (name, x, 0);
+ /* Because push_local_binding will hook X on to the
+ current_binding_level's name list, we don't want to
+ do that again below. */
+ need_new_binding = 0;
+ }
+
+ /* If this is a TYPE_DECL, push it into the type value slot. */
+ if (TREE_CODE (x) == TYPE_DECL)
+ set_identifier_type_value (name, x);
+
+ /* Clear out any TYPE_DECL shadowed by a namespace so that
+ we won't think this is a type. The C struct hack doesn't
+ go through namespaces. */
+ if (TREE_CODE (x) == NAMESPACE_DECL)
+ set_identifier_type_value (name, NULL_TREE);
+
+ if (oldlocal)
+ {
+ tree d = oldlocal;
+
+ while (oldlocal
+ && VAR_P (oldlocal)
+ && DECL_DEAD_FOR_LOCAL (oldlocal))
+ oldlocal = DECL_SHADOWED_FOR_VAR (oldlocal);
+
+ if (oldlocal == NULL_TREE)
+ oldlocal = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (d));
+ }
+
+ /* If this is an extern function declaration, see if we
+ have a global definition or declaration for the function. */
+ if (oldlocal == NULL_TREE
+ && DECL_EXTERNAL (x)
+ && oldglobal != NULL_TREE
+ && TREE_CODE (x) == FUNCTION_DECL
+ && TREE_CODE (oldglobal) == FUNCTION_DECL)
+ {
+ /* We have one. Their types must agree. */
+ if (decls_match (x, oldglobal))
+ /* OK */;
+ else
+ {
+ warning (0, "extern declaration of %q#D doesn%'t match", x);
+ warning (0, "global declaration %q+#D", oldglobal);
+ }
+ }
+ /* If we have a local external declaration,
+ and no file-scope declaration has yet been seen,
+ then if we later have a file-scope decl it must not be static. */
+ if (oldlocal == NULL_TREE
+ && oldglobal == NULL_TREE
+ && DECL_EXTERNAL (x)
+ && TREE_PUBLIC (x))
+ TREE_PUBLIC (name) = 1;
+
+ /* Don't complain about the parms we push and then pop
+ while tentatively parsing a function declarator. */
+ if (TREE_CODE (x) == PARM_DECL && DECL_CONTEXT (x) == NULL_TREE)
+ /* Ignore. */;
+
+ /* Warn if shadowing an argument at the top level of the body. */
+ else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
+ /* Inline decls shadow nothing. */
+ && !DECL_FROM_INLINE (x)
+ && (TREE_CODE (oldlocal) == PARM_DECL
+ || VAR_P (oldlocal)
+ /* If the old decl is a type decl, only warn if the
+ old decl is an explicit typedef or if both the old
+ and new decls are type decls. */
+ || (TREE_CODE (oldlocal) == TYPE_DECL
+ && (!DECL_ARTIFICIAL (oldlocal)
+ || TREE_CODE (x) == TYPE_DECL)))
+ /* Don't check for internally generated vars unless
+ it's an implicit typedef (see create_implicit_typedef
+ in decl.c). */
+ && (!DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x)))
+ {
+ bool nowarn = false;
+
+ /* Don't complain if it's from an enclosing function. */
+ if (DECL_CONTEXT (oldlocal) == current_function_decl
+ && TREE_CODE (x) != PARM_DECL
+ && TREE_CODE (oldlocal) == PARM_DECL)
+ {
+ /* Go to where the parms should be and see if we find
+ them there. */
+ cp_binding_level *b = current_binding_level->level_chain;
+
+ if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
+ /* Skip the ctor/dtor cleanup level. */
+ b = b->level_chain;
+
+ /* ARM $8.3 */
+ if (b->kind == sk_function_parms)
+ {
+ error ("declaration of %q#D shadows a parameter", x);
+ nowarn = true;
+ }
+ }
+
+ /* The local structure or class can't use parameters of
+ the containing function anyway. */
+ if (DECL_CONTEXT (oldlocal) != current_function_decl)
+ {
+ cp_binding_level *scope = current_binding_level;
+ tree context = DECL_CONTEXT (oldlocal);
+ for (; scope; scope = scope->level_chain)
+ {
+ if (scope->kind == sk_function_parms
+ && scope->this_entity == context)
+ break;
+ if (scope->kind == sk_class
+ && !LAMBDA_TYPE_P (scope->this_entity))
+ {
+ nowarn = true;
+ break;
+ }
+ }
+ }
+ /* Error if redeclaring a local declared in a
+ for-init-statement or in the condition of an if or
+ switch statement when the new declaration is in the
+ outermost block of the controlled statement.
+ Redeclaring a variable from a for or while condition is
+ detected elsewhere. */
+ else if (VAR_P (oldlocal)
+ && oldscope == current_binding_level->level_chain
+ && (oldscope->kind == sk_cond
+ || oldscope->kind == sk_for))
+ {
+ error ("redeclaration of %q#D", x);
+ inform (input_location, "%q+#D previously declared here",
+ oldlocal);
+ nowarn = true;
+ }
+ /* C++11:
+ 3.3.3/3: The name declared in an exception-declaration (...)
+ shall not be redeclared in the outermost block of the handler.
+ 3.3.3/2: A parameter name shall not be redeclared (...) in
+ the outermost block of any handler associated with a
+ function-try-block.
+ 3.4.1/15: The function parameter names shall not be redeclared
+ in the exception-declaration nor in the outermost block of a
+ handler for the function-try-block. */
+ else if ((VAR_P (oldlocal)
+ && oldscope == current_binding_level->level_chain
+ && oldscope->kind == sk_catch)
+ || (TREE_CODE (oldlocal) == PARM_DECL
+ && (current_binding_level->kind == sk_catch
+ || (current_binding_level->level_chain->kind
+ == sk_catch))
+ && in_function_try_handler))
+ {
+ if (permerror (input_location, "redeclaration of %q#D", x))
+ inform (input_location, "%q+#D previously declared here",
+ oldlocal);
+ nowarn = true;
+ }
+
+ if (warn_shadow && !nowarn)
+ {
+ bool warned;
+
+ if (TREE_CODE (oldlocal) == PARM_DECL)
+ warned = warning_at (input_location, OPT_Wshadow,
+ "declaration of %q#D shadows a parameter", x);
+ else if (is_capture_proxy (oldlocal))
+ warned = warning_at (input_location, OPT_Wshadow,
+ "declaration of %qD shadows a lambda capture",
+ x);
+ else
+ warned = warning_at (input_location, OPT_Wshadow,
+ "declaration of %qD shadows a previous local",
+ x);
+
+ if (warned)
+ inform (DECL_SOURCE_LOCATION (oldlocal),
+ "shadowed declaration is here");
+ }
+ }
+
+ /* Maybe warn if shadowing something else. */
+ else if (warn_shadow && !DECL_EXTERNAL (x)
+ /* No shadow warnings for internally generated vars unless
+ it's an implicit typedef (see create_implicit_typedef
+ in decl.c). */
+ && (! DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x))
+ /* No shadow warnings for vars made for inlining. */
+ && ! DECL_FROM_INLINE (x))
+ {
+ tree member;
+
+ if (nonlambda_method_basetype ())
+ member = lookup_member (current_nonlambda_class_type (),
+ name,
+ /*protect=*/0,
+ /*want_type=*/false,
+ tf_warning_or_error);
+ else
+ member = NULL_TREE;
+
+ if (member && !TREE_STATIC (member))
+ {
+ /* Location of previous decl is not useful in this case. */
+ warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'",
+ x);
+ }
+ else if (oldglobal != NULL_TREE
+ && (VAR_P (oldglobal)
+ /* If the old decl is a type decl, only warn if the
+ old decl is an explicit typedef or if both the
+ old and new decls are type decls. */
+ || (TREE_CODE (oldglobal) == TYPE_DECL
+ && (!DECL_ARTIFICIAL (oldglobal)
+ || TREE_CODE (x) == TYPE_DECL))))
+ /* XXX shadow warnings in outer-more namespaces */
+ {
+ if (warning_at (input_location, OPT_Wshadow,
+ "declaration of %qD shadows a "
+ "global declaration", x))
+ inform (DECL_SOURCE_LOCATION (oldglobal),
+ "shadowed declaration is here");
+ }
+ }
+ }
+
+ if (VAR_P (x))
+ maybe_register_incomplete_var (x);
+ }
+
+ if (need_new_binding)
+ add_decl_to_level (x,
+ DECL_NAMESPACE_SCOPE_P (x)
+ ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
+ : current_binding_level);
+
+ return x;
+}
+
+/* Wrapper for pushdecl_maybe_friend_1. */
+
+tree
+pushdecl_maybe_friend (tree x, bool is_friend)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = pushdecl_maybe_friend_1 (x, is_friend);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+/* Record a decl-node X as belonging to the current lexical scope. */
+
+tree
+pushdecl (tree x)
+{
+ return pushdecl_maybe_friend (x, false);
+}
+
+/* Enter DECL into the symbol table, if that's appropriate. Returns
+ DECL, or a modified version thereof. */
+
+tree
+maybe_push_decl (tree decl)
+{
+ tree type = TREE_TYPE (decl);
+
+ /* Add this decl to the current binding level, but not if it comes
+ from another scope, e.g. a static member variable. TEM may equal
+ DECL or it may be a previous decl of the same name. */
+ if (decl == error_mark_node
+ || (TREE_CODE (decl) != PARM_DECL
+ && DECL_CONTEXT (decl) != NULL_TREE
+ /* Definitions of namespace members outside their namespace are
+ possible. */
+ && !DECL_NAMESPACE_SCOPE_P (decl))
+ || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
+ || type == unknown_type_node
+ /* The declaration of a template specialization does not affect
+ the functions available for overload resolution, so we do not
+ call pushdecl. */
+ || (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_TEMPLATE_SPECIALIZATION (decl)))
+ return decl;
+ else
+ return pushdecl (decl);
+}
+
+/* Bind DECL to ID in the current_binding_level, assumed to be a local
+ binding level. If PUSH_USING is set in FLAGS, we know that DECL
+ doesn't really belong to this binding level, that it got here
+ through a using-declaration. */
+
+void
+push_local_binding (tree id, tree decl, int flags)
+{
+ cp_binding_level *b;
+
+ /* Skip over any local classes. This makes sense if we call
+ push_local_binding with a friend decl of a local class. */
+ b = innermost_nonclass_level ();
+
+ if (lookup_name_innermost_nonclass_level (id))
+ {
+ /* Supplement the existing binding. */
+ if (!supplement_binding (IDENTIFIER_BINDING (id), decl))
+ /* It didn't work. Something else must be bound at this
+ level. Do not add DECL to the list of things to pop
+ later. */
+ return;
+ }
+ else
+ /* Create a new binding. */
+ push_binding (id, decl, b);
+
+ if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING))
+ /* We must put the OVERLOAD into a TREE_LIST since the
+ TREE_CHAIN of an OVERLOAD is already used. Similarly for
+ decls that got here through a using-declaration. */
+ decl = build_tree_list (NULL_TREE, decl);
+
+ /* And put DECL on the list of things declared by the current
+ binding level. */
+ add_decl_to_level (decl, b);
+}
+
+/* Check to see whether or not DECL is a variable that would have been
+ in scope under the ARM, but is not in scope under the ANSI/ISO
+ standard. If so, issue an error message. If name lookup would
+ work in both cases, but return a different result, this function
+ returns the result of ANSI/ISO lookup. Otherwise, it returns
+ DECL. */
+
+tree
+check_for_out_of_scope_variable (tree decl)
+{
+ tree shadowed;
+
+ /* We only care about out of scope variables. */
+ if (!(VAR_P (decl) && DECL_DEAD_FOR_LOCAL (decl)))
+ return decl;
+
+ shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (decl)
+ ? DECL_SHADOWED_FOR_VAR (decl) : NULL_TREE ;
+ while (shadowed != NULL_TREE && VAR_P (shadowed)
+ && DECL_DEAD_FOR_LOCAL (shadowed))
+ shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (shadowed)
+ ? DECL_SHADOWED_FOR_VAR (shadowed) : NULL_TREE;
+ if (!shadowed)
+ shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (decl));
+ if (shadowed)
+ {
+ if (!DECL_ERROR_REPORTED (decl))
+ {
+ warning (0, "name lookup of %qD changed", DECL_NAME (decl));
+ warning (0, " matches this %q+D under ISO standard rules",
+ shadowed);
+ warning (0, " matches this %q+D under old rules", decl);
+ DECL_ERROR_REPORTED (decl) = 1;
+ }
+ return shadowed;
+ }
+
+ /* If we have already complained about this declaration, there's no
+ need to do it again. */
+ if (DECL_ERROR_REPORTED (decl))
+ return decl;
+
+ DECL_ERROR_REPORTED (decl) = 1;
+
+ if (TREE_TYPE (decl) == error_mark_node)
+ return decl;
+
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+ {
+ error ("name lookup of %qD changed for ISO %<for%> scoping",
+ DECL_NAME (decl));
+ error (" cannot use obsolete binding at %q+D because "
+ "it has a destructor", decl);
+ return error_mark_node;
+ }
+ else
+ {
+ permerror (input_location, "name lookup of %qD changed for ISO %<for%> scoping",
+ DECL_NAME (decl));
+ if (flag_permissive)
+ permerror (input_location, " using obsolete binding at %q+D", decl);
+ else
+ {
+ static bool hint;
+ if (!hint)
+ {
+ inform (input_location, "(if you use %<-fpermissive%> G++ will accept your code)");
+ hint = true;
+ }
+ }
+ }
+
+ return decl;
+}
+
+/* true means unconditionally make a BLOCK for the next level pushed. */
+
+static bool keep_next_level_flag;
+
+static int binding_depth = 0;
+
+static void
+indent (int depth)
+{
+ int i;
+
+ for (i = 0; i < depth * 2; i++)
+ putc (' ', stderr);
+}
+
+/* Return a string describing the kind of SCOPE we have. */
+static const char *
+cp_binding_level_descriptor (cp_binding_level *scope)
+{
+ /* The order of this table must match the "scope_kind"
+ enumerators. */
+ static const char* scope_kind_names[] = {
+ "block-scope",
+ "cleanup-scope",
+ "try-scope",
+ "catch-scope",
+ "for-scope",
+ "function-parameter-scope",
+ "class-scope",
+ "namespace-scope",
+ "template-parameter-scope",
+ "template-explicit-spec-scope"
+ };
+ const scope_kind kind = scope->explicit_spec_p
+ ? sk_template_spec : scope->kind;
+
+ return scope_kind_names[kind];
+}
+
+/* Output a debugging information about SCOPE when performing
+ ACTION at LINE. */
+static void
+cp_binding_level_debug (cp_binding_level *scope, int line, const char *action)
+{
+ const char *desc = cp_binding_level_descriptor (scope);
+ if (scope->this_entity)
+ verbatim ("%s %s(%E) %p %d\n", action, desc,
+ scope->this_entity, (void *) scope, line);
+ else
+ verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line);
+}
+
+/* Return the estimated initial size of the hashtable of a NAMESPACE
+ scope. */
+
+static inline size_t
+namespace_scope_ht_size (tree ns)
+{
+ tree name = DECL_NAME (ns);
+
+ return name == std_identifier
+ ? NAMESPACE_STD_HT_SIZE
+ : (name == global_scope_name
+ ? GLOBAL_SCOPE_HT_SIZE
+ : NAMESPACE_ORDINARY_HT_SIZE);
+}
+
+/* A chain of binding_level structures awaiting reuse. */
+
+static GTY((deletable)) cp_binding_level *free_binding_level;
+
+/* Insert SCOPE as the innermost binding level. */
+
+void
+push_binding_level (cp_binding_level *scope)
+{
+ /* Add it to the front of currently active scopes stack. */
+ scope->level_chain = current_binding_level;
+ current_binding_level = scope;
+ keep_next_level_flag = false;
+
+ if (ENABLE_SCOPE_CHECKING)
+ {
+ scope->binding_depth = binding_depth;
+ indent (binding_depth);
+ cp_binding_level_debug (scope, LOCATION_LINE (input_location),
+ "push");
+ binding_depth++;
+ }
+}
+
+/* Create a new KIND scope and make it the top of the active scopes stack.
+ ENTITY is the scope of the associated C++ entity (namespace, class,
+ function, C++0x enumeration); it is NULL otherwise. */
+
+cp_binding_level *
+begin_scope (scope_kind kind, tree entity)
+{
+ cp_binding_level *scope;
+
+ /* Reuse or create a struct for this binding level. */
+ if (!ENABLE_SCOPE_CHECKING && free_binding_level)
+ {
+ scope = free_binding_level;
+ memset (scope, 0, sizeof (cp_binding_level));
+ free_binding_level = scope->level_chain;
+ }
+ else
+ scope = ggc_alloc_cleared_cp_binding_level ();
+
+ scope->this_entity = entity;
+ scope->more_cleanups_ok = true;
+ switch (kind)
+ {
+ case sk_cleanup:
+ scope->keep = true;
+ break;
+
+ case sk_template_spec:
+ scope->explicit_spec_p = true;
+ kind = sk_template_parms;
+ /* Fall through. */
+ case sk_template_parms:
+ case sk_block:
+ case sk_try:
+ case sk_catch:
+ case sk_for:
+ case sk_cond:
+ case sk_class:
+ case sk_scoped_enum:
+ case sk_function_parms:
+ case sk_omp:
+ scope->keep = keep_next_level_flag;
+ break;
+
+ case sk_namespace:
+ NAMESPACE_LEVEL (entity) = scope;
+ vec_alloc (scope->static_decls,
+ (DECL_NAME (entity) == std_identifier
+ || DECL_NAME (entity) == global_scope_name) ? 200 : 10);
+ break;
+
+ default:
+ /* Should not happen. */
+ gcc_unreachable ();
+ break;
+ }
+ scope->kind = kind;
+
+ push_binding_level (scope);
+
+ return scope;
+}
+
+/* We're about to leave current scope. Pop the top of the stack of
+ currently active scopes. Return the enclosing scope, now active. */
+
+cp_binding_level *
+leave_scope (void)
+{
+ cp_binding_level *scope = current_binding_level;
+
+ if (scope->kind == sk_namespace && class_binding_level)
+ current_binding_level = class_binding_level;
+
+ /* We cannot leave a scope, if there are none left. */
+ if (NAMESPACE_LEVEL (global_namespace))
+ gcc_assert (!global_scope_p (scope));
+
+ if (ENABLE_SCOPE_CHECKING)
+ {
+ indent (--binding_depth);
+ cp_binding_level_debug (scope, LOCATION_LINE (input_location),
+ "leave");
+ }
+
+ /* Move one nesting level up. */
+ current_binding_level = scope->level_chain;
+
+ /* Namespace-scopes are left most probably temporarily, not
+ completely; they can be reopened later, e.g. in namespace-extension
+ or any name binding activity that requires us to resume a
+ namespace. For classes, we cache some binding levels. For other
+ scopes, we just make the structure available for reuse. */
+ if (scope->kind != sk_namespace
+ && scope->kind != sk_class)
+ {
+ scope->level_chain = free_binding_level;
+ gcc_assert (!ENABLE_SCOPE_CHECKING
+ || scope->binding_depth == binding_depth);
+ free_binding_level = scope;
+ }
+
+ /* Find the innermost enclosing class scope, and reset
+ CLASS_BINDING_LEVEL appropriately. */
+ if (scope->kind == sk_class)
+ {
+ class_binding_level = NULL;
+ for (scope = current_binding_level; scope; scope = scope->level_chain)
+ if (scope->kind == sk_class)
+ {
+ class_binding_level = scope;
+ break;
+ }
+ }
+
+ return current_binding_level;
+}
+
+static void
+resume_scope (cp_binding_level* b)
+{
+ /* Resuming binding levels is meant only for namespaces,
+ and those cannot nest into classes. */
+ gcc_assert (!class_binding_level);
+ /* Also, resuming a non-directly nested namespace is a no-no. */
+ gcc_assert (b->level_chain == current_binding_level);
+ current_binding_level = b;
+ if (ENABLE_SCOPE_CHECKING)
+ {
+ b->binding_depth = binding_depth;
+ indent (binding_depth);
+ cp_binding_level_debug (b, LOCATION_LINE (input_location), "resume");
+ binding_depth++;
+ }
+}
+
+/* Return the innermost binding level that is not for a class scope. */
+
+static cp_binding_level *
+innermost_nonclass_level (void)
+{
+ cp_binding_level *b;
+
+ b = current_binding_level;
+ while (b->kind == sk_class)
+ b = b->level_chain;
+
+ return b;
+}
+
+/* We're defining an object of type TYPE. If it needs a cleanup, but
+ we're not allowed to add any more objects with cleanups to the current
+ scope, create a new binding level. */
+
+void
+maybe_push_cleanup_level (tree type)
+{
+ if (type != error_mark_node
+ && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ && current_binding_level->more_cleanups_ok == 0)
+ {
+ begin_scope (sk_cleanup, NULL);
+ current_binding_level->statement_list = push_stmt_list ();
+ }
+}
+
+/* Return true if we are in the global binding level. */
+
+bool
+global_bindings_p (void)
+{
+ return global_scope_p (current_binding_level);
+}
+
+/* True if we are currently in a toplevel binding level. This
+ means either the global binding level or a namespace in a toplevel
+ binding level. Since there are no non-toplevel namespace levels,
+ this really means any namespace or template parameter level. We
+ also include a class whose context is toplevel. */
+
+bool
+toplevel_bindings_p (void)
+{
+ cp_binding_level *b = innermost_nonclass_level ();
+
+ return b->kind == sk_namespace || b->kind == sk_template_parms;
+}
+
+/* True if this is a namespace scope, or if we are defining a class
+ which is itself at namespace scope, or whose enclosing class is
+ such a class, etc. */
+
+bool
+namespace_bindings_p (void)
+{
+ cp_binding_level *b = innermost_nonclass_level ();
+
+ return b->kind == sk_namespace;
+}
+
+/* True if the innermost non-class scope is a block scope. */
+
+bool
+local_bindings_p (void)
+{
+ cp_binding_level *b = innermost_nonclass_level ();
+ return b->kind < sk_function_parms || b->kind == sk_omp;
+}
+
+/* True if the current level needs to have a BLOCK made. */
+
+bool
+kept_level_p (void)
+{
+ return (current_binding_level->blocks != NULL_TREE
+ || current_binding_level->keep
+ || current_binding_level->kind == sk_cleanup
+ || current_binding_level->names != NULL_TREE
+ || current_binding_level->using_directives);
+}
+
+/* Returns the kind of the innermost scope. */
+
+scope_kind
+innermost_scope_kind (void)
+{
+ return current_binding_level->kind;
+}
+
+/* Returns true if this scope was created to store template parameters. */
+
+bool
+template_parm_scope_p (void)
+{
+ return innermost_scope_kind () == sk_template_parms;
+}
+
+/* If KEEP is true, make a BLOCK node for the next binding level,
+ unconditionally. Otherwise, use the normal logic to decide whether
+ or not to create a BLOCK. */
+
+void
+keep_next_level (bool keep)
+{
+ keep_next_level_flag = keep;
+}
+
+/* Return the list of declarations of the current level.
+ Note that this list is in reverse order unless/until
+ you nreverse it; and when you do nreverse it, you must
+ store the result back using `storedecls' or you will lose. */
+
+tree
+getdecls (void)
+{
+ return current_binding_level->names;
+}
+
+/* Return how many function prototypes we are currently nested inside. */
+
+int
+function_parm_depth (void)
+{
+ int level = 0;
+ cp_binding_level *b;
+
+ for (b = current_binding_level;
+ b->kind == sk_function_parms;
+ b = b->level_chain)
+ ++level;
+
+ return level;
+}
+
+/* For debugging. */
+static int no_print_functions = 0;
+static int no_print_builtins = 0;
+
+static void
+print_binding_level (cp_binding_level* lvl)
+{
+ tree t;
+ int i = 0, len;
+ fprintf (stderr, " blocks=%p", (void *) lvl->blocks);
+ if (lvl->more_cleanups_ok)
+ fprintf (stderr, " more-cleanups-ok");
+ if (lvl->have_cleanups)
+ fprintf (stderr, " have-cleanups");
+ fprintf (stderr, "\n");
+ if (lvl->names)
+ {
+ fprintf (stderr, " names:\t");
+ /* We can probably fit 3 names to a line? */
+ for (t = lvl->names; t; t = TREE_CHAIN (t))
+ {
+ if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL))
+ continue;
+ if (no_print_builtins
+ && (TREE_CODE (t) == TYPE_DECL)
+ && DECL_IS_BUILTIN (t))
+ continue;
+
+ /* Function decls tend to have longer names. */
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ len = 3;
+ else
+ len = 2;
+ i += len;
+ if (i > 6)
+ {
+ fprintf (stderr, "\n\t");
+ i = len;
+ }
+ print_node_brief (stderr, "", t, 0);
+ if (t == error_mark_node)
+ break;
+ }
+ if (i)
+ fprintf (stderr, "\n");
+ }
+ if (vec_safe_length (lvl->class_shadowed))
+ {
+ size_t i;
+ cp_class_binding *b;
+ fprintf (stderr, " class-shadowed:");
+ FOR_EACH_VEC_ELT (*lvl->class_shadowed, i, b)
+ fprintf (stderr, " %s ", IDENTIFIER_POINTER (b->identifier));
+ fprintf (stderr, "\n");
+ }
+ if (lvl->type_shadowed)
+ {
+ fprintf (stderr, " type-shadowed:");
+ for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t))
+ {
+ fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+ }
+ fprintf (stderr, "\n");
+ }
+}
+
+DEBUG_FUNCTION void
+debug (cp_binding_level &ref)
+{
+ print_binding_level (&ref);
+}
+
+DEBUG_FUNCTION void
+debug (cp_binding_level *ptr)
+{
+ if (ptr)
+ debug (*ptr);
+ else
+ fprintf (stderr, "<nil>\n");
+}
+
+
+void
+print_other_binding_stack (cp_binding_level *stack)
+{
+ cp_binding_level *level;
+ for (level = stack; !global_scope_p (level); level = level->level_chain)
+ {
+ fprintf (stderr, "binding level %p\n", (void *) level);
+ print_binding_level (level);
+ }
+}
+
+void
+print_binding_stack (void)
+{
+ cp_binding_level *b;
+ fprintf (stderr, "current_binding_level=%p\n"
+ "class_binding_level=%p\n"
+ "NAMESPACE_LEVEL (global_namespace)=%p\n",
+ (void *) current_binding_level, (void *) class_binding_level,
+ (void *) NAMESPACE_LEVEL (global_namespace));
+ if (class_binding_level)
+ {
+ for (b = class_binding_level; b; b = b->level_chain)
+ if (b == current_binding_level)
+ break;
+ if (b)
+ b = class_binding_level;
+ else
+ b = current_binding_level;
+ }
+ else
+ b = current_binding_level;
+ print_other_binding_stack (b);
+ fprintf (stderr, "global:\n");
+ print_binding_level (NAMESPACE_LEVEL (global_namespace));
+}
+
+/* Return the type associated with ID. */
+
+static tree
+identifier_type_value_1 (tree id)
+{
+ /* There is no type with that name, anywhere. */
+ if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
+ return NULL_TREE;
+ /* This is not the type marker, but the real thing. */
+ if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
+ return REAL_IDENTIFIER_TYPE_VALUE (id);
+ /* Have to search for it. It must be on the global level, now.
+ Ask lookup_name not to return non-types. */
+ id = lookup_name_real (id, 2, 1, /*block_p=*/true, 0, 0);
+ if (id)
+ return TREE_TYPE (id);
+ return NULL_TREE;
+}
+
+/* Wrapper for identifier_type_value_1. */
+
+tree
+identifier_type_value (tree id)
+{
+ tree ret;
+ timevar_start (TV_NAME_LOOKUP);
+ ret = identifier_type_value_1 (id);
+ timevar_stop (TV_NAME_LOOKUP);
+ return ret;
+}
+
+
+/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
+ the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++. */
+
+tree
+identifier_global_value (tree t)
+{
+ return IDENTIFIER_GLOBAL_VALUE (t);
+}
+
+/* Push a definition of struct, union or enum tag named ID. into
+ binding_level B. DECL is a TYPE_DECL for the type. We assume that
+ the tag ID is not already defined. */
+
+static void
+set_identifier_type_value_with_scope (tree id, tree decl, cp_binding_level *b)
+{
+ tree type;
+
+ if (b->kind != sk_namespace)
+ {
+ /* Shadow the marker, not the real thing, so that the marker
+ gets restored later. */
+ tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
+ b->type_shadowed
+ = tree_cons (id, old_type_value, b->type_shadowed);
+ type = decl ? TREE_TYPE (decl) : NULL_TREE;
+ TREE_TYPE (b->type_shadowed) = type;
+ }
+ else
+ {
+ cxx_binding *binding =
+ binding_for_name (NAMESPACE_LEVEL (current_namespace), id);
+ gcc_assert (decl);
+ if (binding->value)
+ supplement_binding (binding, decl);
+ else
+ binding->value = decl;
+
+ /* Store marker instead of real type. */
+ type = global_type_node;
+ }
+ SET_IDENTIFIER_TYPE_VALUE (id, type);
+}
+
+/* As set_identifier_type_value_with_scope, but using
+ current_binding_level. */
+
+void
+set_identifier_type_value (tree id, tree decl)
+{
+ set_identifier_type_value_with_scope (id, decl, current_binding_level);
+}
+
+/* Return the name for the constructor (or destructor) for the
+ specified class TYPE. When given a template, this routine doesn't
+ lose the specialization. */
+
+static inline tree
+constructor_name_full (tree type)
+{
+ return TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (type));
+}
+
+/* Return the name for the constructor (or destructor) for the
+ specified class. When given a template, return the plain
+ unspecialized name. */
+
+tree
+constructor_name (tree type)
+{
+ tree name;
+ name = constructor_name_full (type);
+ if (IDENTIFIER_TEMPLATE (name))
+ name = IDENTIFIER_TEMPLATE (name);
+ return name;
+}
+
+/* Returns TRUE if NAME is the name for the constructor for TYPE,
+ which must be a class type. */
+
+bool
+constructor_name_p (tree name, tree type)
+{
+ tree ctor_name;
+
+ gcc_assert (MAYBE_CLASS_TYPE_P (type));
+
+ if (!name)
+ return false;
+
+ if (!identifier_p (name))
+ return false;
+
+ /* These don't have names. */
+ if (TREE_CODE (type) == DECLTYPE_TYPE
+ || TREE_CODE (type) == TYPEOF_TYPE)
+ return false;
+
+ ctor_name = constructor_name_full (type);
+ if (name == ctor_name)
+ return true;
+ if (IDENTIFIER_TEMPLATE (ctor_name)
+ && name == IDENTIFIER_TEMPLATE (ctor_name))
+ return true;
+ return false;
+}
+
+/* Counter used to create anonymous type names. */
+
+static GTY(()) int anon_cnt;
+
+/* Return an IDENTIFIER which can be used as a name for
+ anonymous structs and unions. */
+
+tree
+make_anon_name (void)
+{
+ char buf[32];
+
+ sprintf (buf, ANON_AGGRNAME_FORMAT, anon_cnt++);
+ return get_identifier (buf);
+}
+
+/* This code is practically identical to that for creating
+ anonymous names, but is just used for lambdas instead. This isn't really
+ necessary, but it's convenient to avoid treating lambdas like other
+ anonymous types. */
+
+static GTY(()) int lambda_cnt = 0;
+
+tree
+make_lambda_name (void)
+{
+ char buf[32];
+
+ sprintf (buf, LAMBDANAME_FORMAT, lambda_cnt++);
+ return get_identifier (buf);
+}
+
+/* Return (from the stack of) the BINDING, if any, established at SCOPE. */
+
+static inline cxx_binding *
+find_binding (cp_binding_level *scope, cxx_binding *binding)
+{
+ for (; binding != NULL; binding = binding->previous)
+ if (binding->scope == scope)
+ return binding;
+
+ return (cxx_binding *)0;
+}
+
+/* Return the binding for NAME in SCOPE, if any. Otherwise, return NULL. */
+
+static inline cxx_binding *
+cp_binding_level_find_binding_for_name (cp_binding_level *scope, tree name)
+{
+ cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
+ if (b)
+ {
+ /* Fold-in case where NAME is used only once. */
+ if (scope == b->scope && b->previous == NULL)
+ return b;
+ return find_binding (scope, b);
+ }
+ return NULL;
+}
+
+/* Always returns a binding for name in scope. If no binding is
+ found, make a new one. */
+
+static cxx_binding *
+binding_for_name (cp_binding_level *scope, tree name)
+{
+ cxx_binding *result;
+
+ result = cp_binding_level_find_binding_for_name (scope, name);
+ if (result)
+ return result;
+ /* Not found, make a new one. */
+ result = cxx_binding_make (NULL, NULL);
+ result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
+ result->scope = scope;
+ result->is_local = false;
+ result->value_is_inherited = false;
+ IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
+ return result;
+}
+
+/* Walk through the bindings associated to the name of FUNCTION,
+ and return the first declaration of a function with a
+ "C" linkage specification, a.k.a 'extern "C"'.
+ This function looks for the binding, regardless of which scope it
+ has been defined in. It basically looks in all the known scopes.
+ Note that this function does not lookup for bindings of builtin functions
+ or for functions declared in system headers. */
+static tree
+lookup_extern_c_fun_in_all_ns (tree function)
+{
+ tree name;
+ cxx_binding *iter;
+
+ gcc_assert (function && TREE_CODE (function) == FUNCTION_DECL);
+
+ name = DECL_NAME (function);
+ gcc_assert (name && identifier_p (name));
+
+ for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name);
+ iter;
+ iter = iter->previous)
+ {
+ tree ovl;
+ for (ovl = iter->value; ovl; ovl = OVL_NEXT (ovl))
+ {
+ tree decl = OVL_CURRENT (ovl);
+ if (decl
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_EXTERN_C_P (decl)
+ && !DECL_ARTIFICIAL (decl))
+ {
+ return decl;
+ }
+ }
+ }
+ return NULL;
+}
+
+/* Returns a list of C-linkage decls with the name NAME. */
+
+tree
+c_linkage_bindings (tree name)
+{
+ tree decls = NULL_TREE;
+ cxx_binding *iter;
+
+ for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name);
+ iter;
+ iter = iter->previous)
+ {
+ tree ovl;
+ for (ovl = iter->value; ovl; ovl = OVL_NEXT (ovl))
+ {
+ tree decl = OVL_CURRENT (ovl);
+ if (decl
+ && DECL_EXTERN_C_P (decl)
+ && !DECL_ARTIFICIAL (decl))
+ {
+ if (decls == NULL_TREE)
+ decls = decl;
+ else
+ decls = tree_cons (NULL_TREE, decl, decls);
+ }
+ }
+ }
+ return decls;
+}
+
+/* Insert another USING_DECL into the current binding level, returning
+ this declaration. If this is a redeclaration, do nothing, and
+ return NULL_TREE if this not in namespace scope (in namespace
+ scope, a using decl might extend any previous bindings). */
+
+static tree
+push_using_decl_1 (tree scope, tree name)
+{
+ tree decl;
+
+ gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL);
+ gcc_assert (identifier_p (name));
+ for (decl = current_binding_level->usings; decl; decl = DECL_CHAIN (decl))
+ if (USING_DECL_SCOPE (decl) == scope && DECL_NAME (decl) == name)
+ break;
+ if (decl)
+ return namespace_bindings_p () ? decl : NULL_TREE;
+ decl = build_lang_decl (USING_DECL, name, NULL_TREE);
+ USING_DECL_SCOPE (decl) = scope;
+ DECL_CHAIN (decl) = current_binding_level->usings;
+ current_binding_level->usings = decl;
+ return decl;
+}
+
+/* Wrapper for push_using_decl_1. */
+
+static tree
+push_using_decl (tree scope, tree name)
+{
+ tree ret;
+ timevar_start (TV_NAME_LOOKUP);
+ ret = push_using_decl_1 (scope, name);
+ timevar_stop (TV_NAME_LOOKUP);
+ return ret;
+}
+
+/* Same as pushdecl, but define X in binding-level LEVEL. We rely on the
+ caller to set DECL_CONTEXT properly.
+
+ Note that this must only be used when X will be the new innermost
+ binding for its name, as we tack it onto the front of IDENTIFIER_BINDING
+ without checking to see if the current IDENTIFIER_BINDING comes from a
+ closer binding level than LEVEL. */
+
+static tree
+pushdecl_with_scope_1 (tree x, cp_binding_level *level, bool is_friend)
+{
+ cp_binding_level *b;
+ tree function_decl = current_function_decl;
+
+ current_function_decl = NULL_TREE;
+ if (level->kind == sk_class)
+ {
+ b = class_binding_level;
+ class_binding_level = level;
+ pushdecl_class_level (x);
+ class_binding_level = b;
+ }
+ else
+ {
+ b = current_binding_level;
+ current_binding_level = level;
+ x = pushdecl_maybe_friend (x, is_friend);
+ current_binding_level = b;
+ }
+ current_function_decl = function_decl;
+ return x;
+}
+
+/* Wrapper for pushdecl_with_scope_1. */
+
+tree
+pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = pushdecl_with_scope_1 (x, level, is_friend);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+/* Helper function for push_overloaded_decl_1 and do_nonmember_using_decl.
+ Compares the parameter-type-lists of DECL1 and DECL2 and returns false
+ if they are different. If the DECLs are template functions, the return
+ types and the template parameter lists are compared too (DR 565). */
+
+static bool
+compparms_for_decl_and_using_decl (tree decl1, tree decl2)
+{
+ if (!compparms (TYPE_ARG_TYPES (TREE_TYPE (decl1)),
+ TYPE_ARG_TYPES (TREE_TYPE (decl2))))
+ return false;
+
+ if (! DECL_FUNCTION_TEMPLATE_P (decl1)
+ || ! DECL_FUNCTION_TEMPLATE_P (decl2))
+ return true;
+
+ return (comp_template_parms (DECL_TEMPLATE_PARMS (decl1),
+ DECL_TEMPLATE_PARMS (decl2))
+ && same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
+ TREE_TYPE (TREE_TYPE (decl2))));
+}
+
+/* DECL is a FUNCTION_DECL for a non-member function, which may have
+ other definitions already in place. We get around this by making
+ the value of the identifier point to a list of all the things that
+ want to be referenced by that name. It is then up to the users of
+ that name to decide what to do with that list.
+
+ DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its
+ DECL_TEMPLATE_RESULT. It is dealt with the same way.
+
+ FLAGS is a bitwise-or of the following values:
+ PUSH_LOCAL: Bind DECL in the current scope, rather than at
+ namespace scope.
+ PUSH_USING: DECL is being pushed as the result of a using
+ declaration.
+
+ IS_FRIEND is true if this is a friend declaration.
+
+ The value returned may be a previous declaration if we guessed wrong
+ about what language DECL should belong to (C or C++). Otherwise,
+ it's always DECL (and never something that's not a _DECL). */
+
+static tree
+push_overloaded_decl_1 (tree decl, int flags, bool is_friend)
+{
+ tree name = DECL_NAME (decl);
+ tree old;
+ tree new_binding;
+ int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));
+
+ if (doing_global)
+ old = namespace_binding (name, DECL_CONTEXT (decl));
+ else
+ old = lookup_name_innermost_nonclass_level (name);
+
+ if (old)
+ {
+ if (TREE_CODE (old) == TYPE_DECL && DECL_ARTIFICIAL (old))
+ {
+ tree t = TREE_TYPE (old);
+ if (MAYBE_CLASS_TYPE_P (t) && warn_shadow
+ && (! DECL_IN_SYSTEM_HEADER (decl)
+ || ! DECL_IN_SYSTEM_HEADER (old)))
+ warning (OPT_Wshadow, "%q#D hides constructor for %q#T", decl, t);
+ old = NULL_TREE;
+ }
+ else if (is_overloaded_fn (old))
+ {
+ tree tmp;
+
+ for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
+ {
+ tree fn = OVL_CURRENT (tmp);
+ tree dup;
+
+ if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
+ && !(flags & PUSH_USING)
+ && compparms_for_decl_and_using_decl (fn, decl)
+ && ! decls_match (fn, decl))
+ diagnose_name_conflict (decl, fn);
+
+ dup = duplicate_decls (decl, fn, is_friend);
+ /* If DECL was a redeclaration of FN -- even an invalid
+ one -- pass that information along to our caller. */
+ if (dup == fn || dup == error_mark_node)
+ return dup;
+ }
+
+ /* We don't overload implicit built-ins. duplicate_decls()
+ may fail to merge the decls if the new decl is e.g. a
+ template function. */
+ if (TREE_CODE (old) == FUNCTION_DECL
+ && DECL_ANTICIPATED (old)
+ && !DECL_HIDDEN_FRIEND_P (old))
+ old = NULL;
+ }
+ else if (old == error_mark_node)
+ /* Ignore the undefined symbol marker. */
+ old = NULL_TREE;
+ else
+ {
+ error ("previous non-function declaration %q+#D", old);
+ error ("conflicts with function declaration %q#D", decl);
+ return decl;
+ }
+ }
+
+ if (old || TREE_CODE (decl) == TEMPLATE_DECL
+ /* If it's a using declaration, we always need to build an OVERLOAD,
+ because it's the only way to remember that the declaration comes
+ from 'using', and have the lookup behave correctly. */
+ || (flags & PUSH_USING))
+ {
+ if (old && TREE_CODE (old) != OVERLOAD)
+ new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
+ else
+ new_binding = ovl_cons (decl, old);
+ if (flags & PUSH_USING)
+ OVL_USED (new_binding) = 1;
+ }
+ else
+ /* NAME is not ambiguous. */
+ new_binding = decl;
+
+ if (doing_global)
+ set_namespace_binding (name, current_namespace, new_binding);
+ else
+ {
+ /* We only create an OVERLOAD if there was a previous binding at
+ this level, or if decl is a template. In the former case, we
+ need to remove the old binding and replace it with the new
+ binding. We must also run through the NAMES on the binding
+ level where the name was bound to update the chain. */
+
+ if (TREE_CODE (new_binding) == OVERLOAD && old)
+ {
+ tree *d;
+
+ for (d = &IDENTIFIER_BINDING (name)->scope->names;
+ *d;
+ d = &TREE_CHAIN (*d))
+ if (*d == old
+ || (TREE_CODE (*d) == TREE_LIST
+ && TREE_VALUE (*d) == old))
+ {
+ if (TREE_CODE (*d) == TREE_LIST)
+ /* Just replace the old binding with the new. */
+ TREE_VALUE (*d) = new_binding;
+ else
+ /* Build a TREE_LIST to wrap the OVERLOAD. */
+ *d = tree_cons (NULL_TREE, new_binding,
+ TREE_CHAIN (*d));
+
+ /* And update the cxx_binding node. */
+ IDENTIFIER_BINDING (name)->value = new_binding;
+ return decl;
+ }
+
+ /* We should always find a previous binding in this case. */
+ gcc_unreachable ();
+ }
+
+ /* Install the new binding. */
+ push_local_binding (name, new_binding, flags);
+ }
+
+ return decl;
+}
+
+/* Wrapper for push_overloaded_decl_1. */
+
+static tree
+push_overloaded_decl (tree decl, int flags, bool is_friend)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = push_overloaded_decl_1 (decl, flags, is_friend);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+/* Check a non-member using-declaration. Return the name and scope
+ being used, and the USING_DECL, or NULL_TREE on failure. */
+
+static tree
+validate_nonmember_using_decl (tree decl, tree scope, tree name)
+{
+ /* [namespace.udecl]
+ A using-declaration for a class member shall be a
+ member-declaration. */
+ if (TYPE_P (scope))
+ {
+ error ("%qT is not a namespace", scope);
+ return NULL_TREE;
+ }
+ else if (scope == error_mark_node)
+ return NULL_TREE;
+
+ if (TREE_CODE (decl) == TEMPLATE_ID_EXPR)
+ {
+ /* 7.3.3/5
+ A using-declaration shall not name a template-id. */
+ error ("a using-declaration cannot specify a template-id. "
+ "Try %<using %D%>", name);
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (decl) == NAMESPACE_DECL)
+ {
+ error ("namespace %qD not allowed in using-declaration", decl);
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (decl) == SCOPE_REF)
+ {
+ /* It's a nested name with template parameter dependent scope.
+ This can only be using-declaration for class member. */
+ error ("%qT is not a namespace", TREE_OPERAND (decl, 0));
+ return NULL_TREE;
+ }
+
+ if (is_overloaded_fn (decl))
+ decl = get_first_fn (decl);
+
+ gcc_assert (DECL_P (decl));
+
+ /* Make a USING_DECL. */
+ tree using_decl = push_using_decl (scope, name);
+
+ if (using_decl == NULL_TREE
+ && at_function_scope_p ()
+ && VAR_P (decl))
+ /* C++11 7.3.3/10. */
+ error ("%qD is already declared in this scope", name);
+
+ return using_decl;
+}
+
+/* Process local and global using-declarations. */
+
+static void
+do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
+ tree *newval, tree *newtype)
+{
+ struct scope_binding decls = EMPTY_SCOPE_BINDING;
+
+ *newval = *newtype = NULL_TREE;
+ if (!qualified_lookup_using_namespace (name, scope, &decls, 0))
+ /* Lookup error */
+ return;
+
+ if (!decls.value && !decls.type)
+ {
+ error ("%qD not declared", name);
+ return;
+ }
+
+ /* Shift the old and new bindings around so we're comparing class and
+ enumeration names to each other. */
+ if (oldval && DECL_IMPLICIT_TYPEDEF_P (oldval))
+ {
+ oldtype = oldval;
+ oldval = NULL_TREE;
+ }
+
+ if (decls.value && DECL_IMPLICIT_TYPEDEF_P (decls.value))
+ {
+ decls.type = decls.value;
+ decls.value = NULL_TREE;
+ }
+
+ /* It is impossible to overload a built-in function; any explicit
+ declaration eliminates the built-in declaration. So, if OLDVAL
+ is a built-in, then we can just pretend it isn't there. */
+ if (oldval
+ && TREE_CODE (oldval) == FUNCTION_DECL
+ && DECL_ANTICIPATED (oldval)
+ && !DECL_HIDDEN_FRIEND_P (oldval))
+ oldval = NULL_TREE;
+
+ if (decls.value)
+ {
+ /* Check for using functions. */
+ if (is_overloaded_fn (decls.value))
+ {
+ tree tmp, tmp1;
+
+ if (oldval && !is_overloaded_fn (oldval))
+ {
+ error ("%qD is already declared in this scope", name);
+ oldval = NULL_TREE;
+ }
+
+ *newval = oldval;
+ for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
+ {
+ tree new_fn = OVL_CURRENT (tmp);
+
+ /* [namespace.udecl]
+
+ If a function declaration in namespace scope or block
+ scope has the same name and the same parameter types as a
+ function introduced by a using declaration the program is
+ ill-formed. */
+ for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
+ {
+ tree old_fn = OVL_CURRENT (tmp1);
+
+ if (new_fn == old_fn)
+ /* The function already exists in the current namespace. */
+ break;
+ else if (TREE_CODE (tmp1) == OVERLOAD && OVL_USED (tmp1))
+ continue; /* this is a using decl */
+ else if (compparms_for_decl_and_using_decl (new_fn, old_fn))
+ {
+ gcc_assert (!DECL_ANTICIPATED (old_fn)
+ || DECL_HIDDEN_FRIEND_P (old_fn));
+
+ /* There was already a non-using declaration in
+ this scope with the same parameter types. If both
+ are the same extern "C" functions, that's ok. */
+ if (decls_match (new_fn, old_fn))
+ break;
+ else
+ {
+ diagnose_name_conflict (new_fn, old_fn);
+ break;
+ }
+ }
+ }
+
+ /* If we broke out of the loop, there's no reason to add
+ this function to the using declarations for this
+ scope. */
+ if (tmp1)
+ continue;
+
+ /* If we are adding to an existing OVERLOAD, then we no
+ longer know the type of the set of functions. */
+ if (*newval && TREE_CODE (*newval) == OVERLOAD)
+ TREE_TYPE (*newval) = unknown_type_node;
+ /* Add this new function to the set. */
+ *newval = build_overload (OVL_CURRENT (tmp), *newval);
+ /* If there is only one function, then we use its type. (A
+ using-declaration naming a single function can be used in
+ contexts where overload resolution cannot be
+ performed.) */
+ if (TREE_CODE (*newval) != OVERLOAD)
+ {
+ *newval = ovl_cons (*newval, NULL_TREE);
+ TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+ }
+ OVL_USED (*newval) = 1;
+ }
+ }
+ else
+ {
+ *newval = decls.value;
+ if (oldval && !decls_match (*newval, oldval))
+ error ("%qD is already declared in this scope", name);
+ }
+ }
+ else
+ *newval = oldval;
+
+ if (decls.type && TREE_CODE (decls.type) == TREE_LIST)
+ {
+ error ("reference to %qD is ambiguous", name);
+ print_candidates (decls.type);
+ }
+ else
+ {
+ *newtype = decls.type;
+ if (oldtype && *newtype && !decls_match (oldtype, *newtype))
+ error ("%qD is already declared in this scope", name);
+ }
+
+ /* If *newval is empty, shift any class or enumeration name down. */
+ if (!*newval)
+ {
+ *newval = *newtype;
+ *newtype = NULL_TREE;
+ }
+}
+
+/* Process a using-declaration at function scope. */
+
+void
+do_local_using_decl (tree decl, tree scope, tree name)
+{
+ tree oldval, oldtype, newval, newtype;
+ tree orig_decl = decl;
+
+ decl = validate_nonmember_using_decl (decl, scope, name);
+ if (decl == NULL_TREE)
+ return;
+
+ if (building_stmt_list_p ()
+ && at_function_scope_p ())
+ add_decl_expr (decl);
+
+ oldval = lookup_name_innermost_nonclass_level (name);
+ oldtype = lookup_type_current_level (name);
+
+ do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
+
+ if (newval)
+ {
+ if (is_overloaded_fn (newval))
+ {
+ tree fn, term;
+
+ /* We only need to push declarations for those functions
+ that were not already bound in the current level.
+ The old value might be NULL_TREE, it might be a single
+ function, or an OVERLOAD. */
+ if (oldval && TREE_CODE (oldval) == OVERLOAD)
+ term = OVL_FUNCTION (oldval);
+ else
+ term = oldval;
+ for (fn = newval; fn && OVL_CURRENT (fn) != term;
+ fn = OVL_NEXT (fn))
+ push_overloaded_decl (OVL_CURRENT (fn),
+ PUSH_LOCAL | PUSH_USING,
+ false);
+ }
+ else
+ push_local_binding (name, newval, PUSH_USING);
+ }
+ if (newtype)
+ {
+ push_local_binding (name, newtype, PUSH_USING);
+ set_identifier_type_value (name, newtype);
+ }
+
+ /* Emit debug info. */
+ if (!processing_template_decl)
+ cp_emit_debug_info_for_using (orig_decl, current_scope());
+}
+
+/* Returns true if ROOT (a namespace, class, or function) encloses
+ CHILD. CHILD may be either a class type or a namespace. */
+
+bool
+is_ancestor (tree root, tree child)
+{
+ gcc_assert ((TREE_CODE (root) == NAMESPACE_DECL
+ || TREE_CODE (root) == FUNCTION_DECL
+ || CLASS_TYPE_P (root)));
+ gcc_assert ((TREE_CODE (child) == NAMESPACE_DECL
+ || CLASS_TYPE_P (child)));
+
+ /* The global namespace encloses everything. */
+ if (root == global_namespace)
+ return true;
+
+ while (true)
+ {
+ /* If we've run out of scopes, stop. */
+ if (!child)
+ return false;
+ /* If we've reached the ROOT, it encloses CHILD. */
+ if (root == child)
+ return true;
+ /* Go out one level. */
+ if (TYPE_P (child))
+ child = TYPE_NAME (child);
+ child = DECL_CONTEXT (child);
+ }
+}
+
+/* Enter the class or namespace scope indicated by T suitable for name
+ lookup. T can be arbitrary scope, not necessary nested inside the
+ current scope. Returns a non-null scope to pop iff pop_scope
+ should be called later to exit this scope. */
+
+tree
+push_scope (tree t)
+{
+ if (TREE_CODE (t) == NAMESPACE_DECL)
+ push_decl_namespace (t);
+ else if (CLASS_TYPE_P (t))
+ {
+ if (!at_class_scope_p ()
+ || !same_type_p (current_class_type, t))
+ push_nested_class (t);
+ else
+ /* T is the same as the current scope. There is therefore no
+ need to re-enter the scope. Since we are not actually
+ pushing a new scope, our caller should not call
+ pop_scope. */
+ t = NULL_TREE;
+ }
+
+ return t;
+}
+
+/* Leave scope pushed by push_scope. */
+
+void
+pop_scope (tree t)
+{
+ if (t == NULL_TREE)
+ return;
+ if (TREE_CODE (t) == NAMESPACE_DECL)
+ pop_decl_namespace ();
+ else if CLASS_TYPE_P (t)
+ pop_nested_class ();
+}
+
+/* Subroutine of push_inner_scope. */
+
+static void
+push_inner_scope_r (tree outer, tree inner)
+{
+ tree prev;
+
+ if (outer == inner
+ || (TREE_CODE (inner) != NAMESPACE_DECL && !CLASS_TYPE_P (inner)))
+ return;
+
+ prev = CP_DECL_CONTEXT (TREE_CODE (inner) == NAMESPACE_DECL ? inner : TYPE_NAME (inner));
+ if (outer != prev)
+ push_inner_scope_r (outer, prev);
+ if (TREE_CODE (inner) == NAMESPACE_DECL)
+ {
+ cp_binding_level *save_template_parm = 0;
+ /* Temporary take out template parameter scopes. They are saved
+ in reversed order in save_template_parm. */
+ while (current_binding_level->kind == sk_template_parms)
+ {
+ cp_binding_level *b = current_binding_level;
+ current_binding_level = b->level_chain;
+ b->level_chain = save_template_parm;
+ save_template_parm = b;
+ }
+
+ resume_scope (NAMESPACE_LEVEL (inner));
+ current_namespace = inner;
+
+ /* Restore template parameter scopes. */
+ while (save_template_parm)
+ {
+ cp_binding_level *b = save_template_parm;
+ save_template_parm = b->level_chain;
+ b->level_chain = current_binding_level;
+ current_binding_level = b;
+ }
+ }
+ else
+ pushclass (inner);
+}
+
+/* Enter the scope INNER from current scope. INNER must be a scope
+ nested inside current scope. This works with both name lookup and
+ pushing name into scope. In case a template parameter scope is present,
+ namespace is pushed under the template parameter scope according to
+ name lookup rule in 14.6.1/6.
+
+ Return the former current scope suitable for pop_inner_scope. */
+
+tree
+push_inner_scope (tree inner)
+{
+ tree outer = current_scope ();
+ if (!outer)
+ outer = current_namespace;
+
+ push_inner_scope_r (outer, inner);
+ return outer;
+}
+
+/* Exit the current scope INNER back to scope OUTER. */
+
+void
+pop_inner_scope (tree outer, tree inner)
+{
+ if (outer == inner
+ || (TREE_CODE (inner) != NAMESPACE_DECL && !CLASS_TYPE_P (inner)))
+ return;
+
+ while (outer != inner)
+ {
+ if (TREE_CODE (inner) == NAMESPACE_DECL)
+ {
+ cp_binding_level *save_template_parm = 0;
+ /* Temporary take out template parameter scopes. They are saved
+ in reversed order in save_template_parm. */
+ while (current_binding_level->kind == sk_template_parms)
+ {
+ cp_binding_level *b = current_binding_level;
+ current_binding_level = b->level_chain;
+ b->level_chain = save_template_parm;
+ save_template_parm = b;
+ }
+
+ pop_namespace ();
+
+ /* Restore template parameter scopes. */
+ while (save_template_parm)
+ {
+ cp_binding_level *b = save_template_parm;
+ save_template_parm = b->level_chain;
+ b->level_chain = current_binding_level;
+ current_binding_level = b;
+ }
+ }
+ else
+ popclass ();
+
+ inner = CP_DECL_CONTEXT (TREE_CODE (inner) == NAMESPACE_DECL ? inner : TYPE_NAME (inner));
+ }
+}
+
+/* Do a pushlevel for class declarations. */
+
+void
+pushlevel_class (void)
+{
+ class_binding_level = begin_scope (sk_class, current_class_type);
+}
+
+/* ...and a poplevel for class declarations. */
+
+void
+poplevel_class (void)
+{
+ cp_binding_level *level = class_binding_level;
+ cp_class_binding *cb;
+ size_t i;
+ tree shadowed;
+
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ gcc_assert (level != 0);
+
+ /* If we're leaving a toplevel class, cache its binding level. */
+ if (current_class_depth == 1)
+ previous_class_level = level;
+ for (shadowed = level->type_shadowed;
+ shadowed;
+ shadowed = TREE_CHAIN (shadowed))
+ SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
+
+ /* Remove the bindings for all of the class-level declarations. */
+ if (level->class_shadowed)
+ {
+ FOR_EACH_VEC_ELT (*level->class_shadowed, i, cb)
+ {
+ IDENTIFIER_BINDING (cb->identifier) = cb->base->previous;
+ cxx_binding_free (cb->base);
+ }
+ ggc_free (level->class_shadowed);
+ level->class_shadowed = NULL;
+ }
+
+ /* Now, pop out of the binding level which we created up in the
+ `pushlevel_class' routine. */
+ gcc_assert (current_binding_level == level);
+ leave_scope ();
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+}
+
+/* Set INHERITED_VALUE_BINDING_P on BINDING to true or false, as
+ appropriate. DECL is the value to which a name has just been
+ bound. CLASS_TYPE is the class in which the lookup occurred. */
+
+static void
+set_inherited_value_binding_p (cxx_binding *binding, tree decl,
+ tree class_type)
+{
+ if (binding->value == decl && TREE_CODE (decl) != TREE_LIST)
+ {
+ tree context;
+
+ if (TREE_CODE (decl) == OVERLOAD)
+ context = ovl_scope (decl);
+ else
+ {
+ gcc_assert (DECL_P (decl));
+ context = context_for_name_lookup (decl);
+ }
+
+ if (is_properly_derived_from (class_type, context))
+ INHERITED_VALUE_BINDING_P (binding) = 1;
+ else
+ INHERITED_VALUE_BINDING_P (binding) = 0;
+ }
+ else if (binding->value == decl)
+ /* We only encounter a TREE_LIST when there is an ambiguity in the
+ base classes. Such an ambiguity can be overridden by a
+ definition in this class. */
+ INHERITED_VALUE_BINDING_P (binding) = 1;
+ else
+ INHERITED_VALUE_BINDING_P (binding) = 0;
+}
+
+/* Make the declaration of X appear in CLASS scope. */
+
+bool
+pushdecl_class_level (tree x)
+{
+ tree name;
+ bool is_valid = true;
+ bool subtime;
+
+ /* Do nothing if we're adding to an outer lambda closure type,
+ outer_binding will add it later if it's needed. */
+ if (current_class_type != class_binding_level->this_entity)
+ return true;
+
+ subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ /* Get the name of X. */
+ if (TREE_CODE (x) == OVERLOAD)
+ name = DECL_NAME (get_first_fn (x));
+ else
+ name = DECL_NAME (x);
+
+ if (name)
+ {
+ is_valid = push_class_level_binding (name, x);
+ if (TREE_CODE (x) == TYPE_DECL)
+ set_identifier_type_value (name, x);
+ }
+ else if (ANON_AGGR_TYPE_P (TREE_TYPE (x)))
+ {
+ /* If X is an anonymous aggregate, all of its members are
+ treated as if they were members of the class containing the
+ aggregate, for naming purposes. */
+ tree f;
+
+ for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = DECL_CHAIN (f))
+ {
+ location_t save_location = input_location;
+ input_location = DECL_SOURCE_LOCATION (f);
+ if (!pushdecl_class_level (f))
+ is_valid = false;
+ input_location = save_location;
+ }
+ }
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return is_valid;
+}
+
+/* Return the BINDING (if any) for NAME in SCOPE, which is a class
+ scope. If the value returned is non-NULL, and the PREVIOUS field
+ is not set, callers must set the PREVIOUS field explicitly. */
+
+static cxx_binding *
+get_class_binding (tree name, cp_binding_level *scope)
+{
+ tree class_type;
+ tree type_binding;
+ tree value_binding;
+ cxx_binding *binding;
+
+ class_type = scope->this_entity;
+
+ /* Get the type binding. */
+ type_binding = lookup_member (class_type, name,
+ /*protect=*/2, /*want_type=*/true,
+ tf_warning_or_error);
+ /* Get the value binding. */
+ value_binding = lookup_member (class_type, name,
+ /*protect=*/2, /*want_type=*/false,
+ tf_warning_or_error);
+
+ if (value_binding
+ && (TREE_CODE (value_binding) == TYPE_DECL
+ || DECL_CLASS_TEMPLATE_P (value_binding)
+ || (TREE_CODE (value_binding) == TREE_LIST
+ && TREE_TYPE (value_binding) == error_mark_node
+ && (TREE_CODE (TREE_VALUE (value_binding))
+ == TYPE_DECL))))
+ /* We found a type binding, even when looking for a non-type
+ binding. This means that we already processed this binding
+ above. */
+ ;
+ else if (value_binding)
+ {
+ if (TREE_CODE (value_binding) == TREE_LIST
+ && TREE_TYPE (value_binding) == error_mark_node)
+ /* NAME is ambiguous. */
+ ;
+ else if (BASELINK_P (value_binding))
+ /* NAME is some overloaded functions. */
+ value_binding = BASELINK_FUNCTIONS (value_binding);
+ }
+
+ /* If we found either a type binding or a value binding, create a
+ new binding object. */
+ if (type_binding || value_binding)
+ {
+ binding = new_class_binding (name,
+ value_binding,
+ type_binding,
+ scope);
+ /* This is a class-scope binding, not a block-scope binding. */
+ LOCAL_BINDING_P (binding) = 0;
+ set_inherited_value_binding_p (binding, value_binding, class_type);
+ }
+ else
+ binding = NULL;
+
+ return binding;
+}
+
+/* Make the declaration(s) of X appear in CLASS scope under the name
+ NAME. Returns true if the binding is valid. */
+
+static bool
+push_class_level_binding_1 (tree name, tree x)
+{
+ cxx_binding *binding;
+ tree decl = x;
+ bool ok;
+
+ /* The class_binding_level will be NULL if x is a template
+ parameter name in a member template. */
+ if (!class_binding_level)
+ return true;
+
+ if (name == error_mark_node)
+ return false;
+
+ /* Can happen for an erroneous declaration (c++/60384). */
+ if (!identifier_p (name))
+ {
+ gcc_assert (errorcount || sorrycount);
+ return false;
+ }
+
+ /* Check for invalid member names. But don't worry about a default
+ argument-scope lambda being pushed after the class is complete. */
+ gcc_assert (TYPE_BEING_DEFINED (current_class_type)
+ || LAMBDA_TYPE_P (TREE_TYPE (decl)));
+ /* Check that we're pushing into the right binding level. */
+ gcc_assert (current_class_type == class_binding_level->this_entity);
+
+ /* We could have been passed a tree list if this is an ambiguous
+ declaration. If so, pull the declaration out because
+ check_template_shadow will not handle a TREE_LIST. */
+ if (TREE_CODE (decl) == TREE_LIST
+ && TREE_TYPE (decl) == error_mark_node)
+ decl = TREE_VALUE (decl);
+
+ if (!check_template_shadow (decl))
+ return false;
+
+ /* [class.mem]
+
+ If T is the name of a class, then each of the following shall
+ have a name different from T:
+
+ -- every static data member of class T;
+
+ -- every member of class T that is itself a type;
+
+ -- every enumerator of every member of class T that is an
+ enumerated type;
+
+ -- every member of every anonymous union that is a member of
+ class T.
+
+ (Non-static data members were also forbidden to have the same
+ name as T until TC1.) */
+ if ((VAR_P (x)
+ || TREE_CODE (x) == CONST_DECL
+ || (TREE_CODE (x) == TYPE_DECL
+ && !DECL_SELF_REFERENCE_P (x))
+ /* A data member of an anonymous union. */
+ || (TREE_CODE (x) == FIELD_DECL
+ && DECL_CONTEXT (x) != current_class_type))
+ && DECL_NAME (x) == constructor_name (current_class_type))
+ {
+ tree scope = context_for_name_lookup (x);
+ if (TYPE_P (scope) && same_type_p (scope, current_class_type))
+ {
+ error ("%qD has the same name as the class in which it is "
+ "declared",
+ x);
+ return false;
+ }
+ }
+
+ /* Get the current binding for NAME in this class, if any. */
+ binding = IDENTIFIER_BINDING (name);
+ if (!binding || binding->scope != class_binding_level)
+ {
+ binding = get_class_binding (name, class_binding_level);
+ /* If a new binding was created, put it at the front of the
+ IDENTIFIER_BINDING list. */
+ if (binding)
+ {
+ binding->previous = IDENTIFIER_BINDING (name);
+ IDENTIFIER_BINDING (name) = binding;
+ }
+ }
+
+ /* If there is already a binding, then we may need to update the
+ current value. */
+ if (binding && binding->value)
+ {
+ tree bval = binding->value;
+ tree old_decl = NULL_TREE;
+ tree target_decl = strip_using_decl (decl);
+ tree target_bval = strip_using_decl (bval);
+
+ if (INHERITED_VALUE_BINDING_P (binding))
+ {
+ /* If the old binding was from a base class, and was for a
+ tag name, slide it over to make room for the new binding.
+ The old binding is still visible if explicitly qualified
+ with a class-key. */
+ if (TREE_CODE (target_bval) == TYPE_DECL
+ && DECL_ARTIFICIAL (target_bval)
+ && !(TREE_CODE (target_decl) == TYPE_DECL
+ && DECL_ARTIFICIAL (target_decl)))
+ {
+ old_decl = binding->type;
+ binding->type = bval;
+ binding->value = NULL_TREE;
+ INHERITED_VALUE_BINDING_P (binding) = 0;
+ }
+ else
+ {
+ old_decl = bval;
+ /* Any inherited type declaration is hidden by the type
+ declaration in the derived class. */
+ if (TREE_CODE (target_decl) == TYPE_DECL
+ && DECL_ARTIFICIAL (target_decl))
+ binding->type = NULL_TREE;
+ }
+ }
+ else if (TREE_CODE (target_decl) == OVERLOAD
+ && is_overloaded_fn (target_bval))
+ old_decl = bval;
+ else if (TREE_CODE (decl) == USING_DECL
+ && TREE_CODE (bval) == USING_DECL
+ && same_type_p (USING_DECL_SCOPE (decl),
+ USING_DECL_SCOPE (bval)))
+ /* This is a using redeclaration that will be diagnosed later
+ in supplement_binding */
+ ;
+ else if (TREE_CODE (decl) == USING_DECL
+ && TREE_CODE (bval) == USING_DECL
+ && DECL_DEPENDENT_P (decl)
+ && DECL_DEPENDENT_P (bval))
+ return true;
+ else if (TREE_CODE (decl) == USING_DECL
+ && is_overloaded_fn (target_bval))
+ old_decl = bval;
+ else if (TREE_CODE (bval) == USING_DECL
+ && is_overloaded_fn (target_decl))
+ return true;
+
+ if (old_decl && binding->scope == class_binding_level)
+ {
+ binding->value = x;
+ /* It is always safe to clear INHERITED_VALUE_BINDING_P
+ here. This function is only used to register bindings
+ from with the class definition itself. */
+ INHERITED_VALUE_BINDING_P (binding) = 0;
+ return true;
+ }
+ }
+
+ /* Note that we declared this value so that we can issue an error if
+ this is an invalid redeclaration of a name already used for some
+ other purpose. */
+ note_name_declared_in_class (name, decl);
+
+ /* If we didn't replace an existing binding, put the binding on the
+ stack of bindings for the identifier, and update the shadowed
+ list. */
+ if (binding && binding->scope == class_binding_level)
+ /* Supplement the existing binding. */
+ ok = supplement_binding (binding, decl);
+ else
+ {
+ /* Create a new binding. */
+ push_binding (name, decl, class_binding_level);
+ ok = true;
+ }
+
+ return ok;
+}
+
+/* Wrapper for push_class_level_binding_1. */
+
+bool
+push_class_level_binding (tree name, tree x)
+{
+ bool ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = push_class_level_binding_1 (name, x);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+/* Process "using SCOPE::NAME" in a class scope. Return the
+ USING_DECL created. */
+
+tree
+do_class_using_decl (tree scope, tree name)
+{
+ /* The USING_DECL returned by this function. */
+ tree value;
+ /* The declaration (or declarations) name by this using
+ declaration. NULL if we are in a template and cannot figure out
+ what has been named. */
+ tree decl;
+ /* True if SCOPE is a dependent type. */
+ bool scope_dependent_p;
+ /* True if SCOPE::NAME is dependent. */
+ bool name_dependent_p;
+ /* True if any of the bases of CURRENT_CLASS_TYPE are dependent. */
+ bool bases_dependent_p;
+ tree binfo;
+ tree base_binfo;
+ int i;
+
+ if (name == error_mark_node)
+ return NULL_TREE;
+
+ if (!scope || !TYPE_P (scope))
+ {
+ error ("using-declaration for non-member at class scope");
+ return NULL_TREE;
+ }
+
+ /* Make sure the name is not invalid */
+ if (TREE_CODE (name) == BIT_NOT_EXPR)
+ {
+ error ("%<%T::%D%> names destructor", scope, name);
+ return NULL_TREE;
+ }
+ /* Using T::T declares inheriting ctors, even if T is a typedef. */
+ if (MAYBE_CLASS_TYPE_P (scope)
+ && ((TYPE_NAME (scope) && name == TYPE_IDENTIFIER (scope))
+ || constructor_name_p (name, scope)))
+ {
+ maybe_warn_cpp0x (CPP0X_INHERITING_CTORS);
+ name = ctor_identifier;
+ }
+ if (constructor_name_p (name, current_class_type))
+ {
+ error ("%<%T::%D%> names constructor in %qT",
+ scope, name, current_class_type);
+ return NULL_TREE;
+ }
+
+ scope_dependent_p = dependent_scope_p (scope);
+ name_dependent_p = (scope_dependent_p
+ || (IDENTIFIER_TYPENAME_P (name)
+ && dependent_type_p (TREE_TYPE (name))));
+
+ bases_dependent_p = false;
+ if (processing_template_decl)
+ for (binfo = TYPE_BINFO (current_class_type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo);
+ i++)
+ if (dependent_type_p (TREE_TYPE (base_binfo)))
+ {
+ bases_dependent_p = true;
+ break;
+ }
+
+ decl = NULL_TREE;
+
+ /* From [namespace.udecl]:
+
+ A using-declaration used as a member-declaration shall refer to a
+ member of a base class of the class being defined.
+
+ In general, we cannot check this constraint in a template because
+ we do not know the entire set of base classes of the current
+ class type. Morover, if SCOPE is dependent, it might match a
+ non-dependent base. */
+
+ if (!scope_dependent_p)
+ {
+ base_kind b_kind;
+ binfo = lookup_base (current_class_type, scope, ba_any, &b_kind,
+ tf_warning_or_error);
+ if (b_kind < bk_proper_base)
+ {
+ if (!bases_dependent_p)
+ {
+ error_not_base_type (scope, current_class_type);
+ return NULL_TREE;
+ }
+ }
+ else if (!name_dependent_p)
+ {
+ decl = lookup_member (binfo, name, 0, false, tf_warning_or_error);
+ if (!decl)
+ {
+ error ("no members matching %<%T::%D%> in %q#T", scope, name,
+ scope);
+ return NULL_TREE;
+ }
+ /* The binfo from which the functions came does not matter. */
+ if (BASELINK_P (decl))
+ decl = BASELINK_FUNCTIONS (decl);
+ }
+ }
+
+ value = build_lang_decl (USING_DECL, name, NULL_TREE);
+ USING_DECL_DECLS (value) = decl;
+ USING_DECL_SCOPE (value) = scope;
+ DECL_DEPENDENT_P (value) = !decl;
+
+ return value;
+}
+
+
+/* Return the binding value for name in scope. */
+
+
+static tree
+namespace_binding_1 (tree name, tree scope)
+{
+ cxx_binding *binding;
+
+ if (SCOPE_FILE_SCOPE_P (scope))
+ scope = global_namespace;
+ else
+ /* Unnecessary for the global namespace because it can't be an alias. */
+ scope = ORIGINAL_NAMESPACE (scope);
+
+ binding = cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+
+ return binding ? binding->value : NULL_TREE;
+}
+
+tree
+namespace_binding (tree name, tree scope)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = namespace_binding_1 (name, scope);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+/* Set the binding value for name in scope. */
+
+static void
+set_namespace_binding_1 (tree name, tree scope, tree val)
+{
+ cxx_binding *b;
+
+ if (scope == NULL_TREE)
+ scope = global_namespace;
+ b = binding_for_name (NAMESPACE_LEVEL (scope), name);
+ if (!b->value || TREE_CODE (val) == OVERLOAD || val == error_mark_node)
+ b->value = val;
+ else
+ supplement_binding (b, val);
+}
+
+/* Wrapper for set_namespace_binding_1. */
+
+void
+set_namespace_binding (tree name, tree scope, tree val)
+{
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ set_namespace_binding_1 (name, scope, val);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+}
+
+/* Set the context of a declaration to scope. Complain if we are not
+ outside scope. */
+
+void
+set_decl_namespace (tree decl, tree scope, bool friendp)
+{
+ tree old;
+
+ /* Get rid of namespace aliases. */
+ scope = ORIGINAL_NAMESPACE (scope);
+
+ /* It is ok for friends to be qualified in parallel space. */
+ if (!friendp && !is_ancestor (current_namespace, scope))
+ error ("declaration of %qD not in a namespace surrounding %qD",
+ decl, scope);
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
+
+ /* Writing "int N::i" to declare a variable within "N" is invalid. */
+ if (scope == current_namespace)
+ {
+ if (at_namespace_scope_p ())
+ error ("explicit qualification in declaration of %qD",
+ decl);
+ return;
+ }
+
+ /* See whether this has been declared in the namespace. */
+ old = lookup_qualified_name (scope, DECL_NAME (decl), false, true);
+ if (old == error_mark_node)
+ /* No old declaration at all. */
+ goto complain;
+ /* If it's a TREE_LIST, the result of the lookup was ambiguous. */
+ if (TREE_CODE (old) == TREE_LIST)
+ {
+ error ("reference to %qD is ambiguous", decl);
+ print_candidates (old);
+ return;
+ }
+ if (!is_overloaded_fn (decl))
+ {
+ /* We might have found OLD in an inline namespace inside SCOPE. */
+ if (TREE_CODE (decl) == TREE_CODE (old))
+ DECL_CONTEXT (decl) = DECL_CONTEXT (old);
+ /* Don't compare non-function decls with decls_match here, since
+ it can't check for the correct constness at this
+ point. pushdecl will find those errors later. */
+ return;
+ }
+ /* Since decl is a function, old should contain a function decl. */
+ if (!is_overloaded_fn (old))
+ goto complain;
+ /* A template can be explicitly specialized in any namespace. */
+ if (processing_explicit_instantiation)
+ return;
+ if (processing_template_decl || processing_specialization)
+ /* We have not yet called push_template_decl to turn a
+ FUNCTION_DECL into a TEMPLATE_DECL, so the declarations won't
+ match. But, we'll check later, when we construct the
+ template. */
+ return;
+ /* Instantiations or specializations of templates may be declared as
+ friends in any namespace. */
+ if (friendp && DECL_USE_TEMPLATE (decl))
+ return;
+ if (is_overloaded_fn (old))
+ {
+ tree found = NULL_TREE;
+ tree elt = old;
+ for (; elt; elt = OVL_NEXT (elt))
+ {
+ tree ofn = OVL_CURRENT (elt);
+ /* Adjust DECL_CONTEXT first so decls_match will return true
+ if DECL will match a declaration in an inline namespace. */
+ DECL_CONTEXT (decl) = DECL_CONTEXT (ofn);
+ if (decls_match (decl, ofn))
+ {
+ if (found && !decls_match (found, ofn))
+ {
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
+ error ("reference to %qD is ambiguous", decl);
+ print_candidates (old);
+ return;
+ }
+ found = ofn;
+ }
+ }
+ if (found)
+ {
+ if (!is_associated_namespace (scope, CP_DECL_CONTEXT (found)))
+ goto complain;
+ DECL_CONTEXT (decl) = DECL_CONTEXT (found);
+ return;
+ }
+ }
+ else
+ {
+ DECL_CONTEXT (decl) = DECL_CONTEXT (old);
+ if (decls_match (decl, old))
+ return;
+ }
+
+ /* It didn't work, go back to the explicit scope. */
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
+ complain:
+ error ("%qD should have been declared inside %qD", decl, scope);
+}
+
+/* Return the namespace where the current declaration is declared. */
+
+tree
+current_decl_namespace (void)
+{
+ tree result;
+ /* If we have been pushed into a different namespace, use it. */
+ if (!vec_safe_is_empty (decl_namespace_list))
+ return decl_namespace_list->last ();
+
+ if (current_class_type)
+ result = decl_namespace_context (current_class_type);
+ else if (current_function_decl)
+ result = decl_namespace_context (current_function_decl);
+ else
+ result = current_namespace;
+ return result;
+}
+
+/* Process any ATTRIBUTES on a namespace definition. Currently only
+ attribute visibility is meaningful, which is a property of the syntactic
+ block rather than the namespace as a whole, so we don't touch the
+ NAMESPACE_DECL at all. Returns true if attribute visibility is seen. */
+
+bool
+handle_namespace_attrs (tree ns, tree attributes)
+{
+ tree d;
+ bool saw_vis = false;
+
+ for (d = attributes; d; d = TREE_CHAIN (d))
+ {
+ tree name = get_attribute_name (d);
+ tree args = TREE_VALUE (d);
+
+ if (is_attribute_p ("visibility", name))
+ {
+ tree x = args ? TREE_VALUE (args) : NULL_TREE;
+ if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args))
+ {
+ warning (OPT_Wattributes,
+ "%qD attribute requires a single NTBS argument",
+ name);
+ continue;
+ }
+
+ if (!TREE_PUBLIC (ns))
+ warning (OPT_Wattributes,
+ "%qD attribute is meaningless since members of the "
+ "anonymous namespace get local symbols", name);
+
+ push_visibility (TREE_STRING_POINTER (x), 1);
+ saw_vis = true;
+ }
+ else
+ {
+ warning (OPT_Wattributes, "%qD attribute directive ignored",
+ name);
+ continue;
+ }
+ }
+
+ return saw_vis;
+}
+
+/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we
+ select a name that is unique to this compilation unit. */
+
+void
+push_namespace (tree name)
+{
+ tree d = NULL_TREE;
+ bool need_new = true;
+ bool implicit_use = false;
+ bool anon = !name;
+
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+
+ /* We should not get here if the global_namespace is not yet constructed
+ nor if NAME designates the global namespace: The global scope is
+ constructed elsewhere. */
+ gcc_assert (global_namespace != NULL && name != global_scope_name);
+
+ if (anon)
+ {
+ name = get_anonymous_namespace_name();
+ d = IDENTIFIER_NAMESPACE_VALUE (name);
+ if (d)
+ /* Reopening anonymous namespace. */
+ need_new = false;
+ implicit_use = true;
+ }
+ else
+ {
+ /* Check whether this is an extended namespace definition. */
+ d = IDENTIFIER_NAMESPACE_VALUE (name);
+ if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
+ {
+ tree dna = DECL_NAMESPACE_ALIAS (d);
+ if (dna)
+ {
+ /* We do some error recovery for, eg, the redeclaration
+ of M here:
+
+ namespace N {}
+ namespace M = N;
+ namespace M {}
+
+ However, in nasty cases like:
+
+ namespace N
+ {
+ namespace M = N;
+ namespace M {}
+ }
+
+ we just error out below, in duplicate_decls. */
+ if (NAMESPACE_LEVEL (dna)->level_chain
+ == current_binding_level)
+ {
+ error ("namespace alias %qD not allowed here, "
+ "assuming %qD", d, dna);
+ d = dna;
+ need_new = false;
+ }
+ }
+ else
+ need_new = false;
+ }
+ }
+
+ if (need_new)
+ {
+ /* Make a new namespace, binding the name to it. */
+ d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
+ DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
+ /* The name of this namespace is not visible to other translation
+ units if it is an anonymous namespace or member thereof. */
+ if (anon || decl_anon_ns_mem_p (current_namespace))
+ TREE_PUBLIC (d) = 0;
+ else
+ TREE_PUBLIC (d) = 1;
+ pushdecl (d);
+ if (anon)
+ {
+ /* Clear DECL_NAME for the benefit of debugging back ends. */
+ SET_DECL_ASSEMBLER_NAME (d, name);
+ DECL_NAME (d) = NULL_TREE;
+ }
+ begin_scope (sk_namespace, d);
+ }
+ else
+ resume_scope (NAMESPACE_LEVEL (d));
+
+ if (implicit_use)
+ do_using_directive (d);
+ /* Enter the name space. */
+ current_namespace = d;
+
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+}
+
+/* Pop from the scope of the current namespace. */
+
+void
+pop_namespace (void)
+{
+ gcc_assert (current_namespace != global_namespace);
+ current_namespace = CP_DECL_CONTEXT (current_namespace);
+ /* The binding level is not popped, as it might be re-opened later. */
+ leave_scope ();
+}
+
+/* Push into the scope of the namespace NS, even if it is deeply
+ nested within another namespace. */
+
+void
+push_nested_namespace (tree ns)
+{
+ if (ns == global_namespace)
+ push_to_top_level ();
+ else
+ {
+ push_nested_namespace (CP_DECL_CONTEXT (ns));
+ push_namespace (DECL_NAME (ns));
+ }
+}
+
+/* Pop back from the scope of the namespace NS, which was previously
+ entered with push_nested_namespace. */
+
+void
+pop_nested_namespace (tree ns)
+{
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ gcc_assert (current_namespace == ns);
+ while (ns != global_namespace)
+ {
+ pop_namespace ();
+ ns = CP_DECL_CONTEXT (ns);
+ }
+
+ pop_from_top_level ();
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+}
+
+/* Temporarily set the namespace for the current declaration. */
+
+void
+push_decl_namespace (tree decl)
+{
+ if (TREE_CODE (decl) != NAMESPACE_DECL)
+ decl = decl_namespace_context (decl);
+ vec_safe_push (decl_namespace_list, ORIGINAL_NAMESPACE (decl));
+}
+
+/* [namespace.memdef]/2 */
+
+void
+pop_decl_namespace (void)
+{
+ decl_namespace_list->pop ();
+}
+
+/* Return the namespace that is the common ancestor
+ of two given namespaces. */
+
+static tree
+namespace_ancestor_1 (tree ns1, tree ns2)
+{
+ tree nsr;
+ if (is_ancestor (ns1, ns2))
+ nsr = ns1;
+ else
+ nsr = namespace_ancestor_1 (CP_DECL_CONTEXT (ns1), ns2);
+ return nsr;
+}
+
+/* Wrapper for namespace_ancestor_1. */
+
+static tree
+namespace_ancestor (tree ns1, tree ns2)
+{
+ tree nsr;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ nsr = namespace_ancestor_1 (ns1, ns2);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return nsr;
+}
+
+/* Process a namespace-alias declaration. */
+
+void
+do_namespace_alias (tree alias, tree name_space)
+{
+ if (name_space == error_mark_node)
+ return;
+
+ gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
+
+ name_space = ORIGINAL_NAMESPACE (name_space);
+
+ /* Build the alias. */
+ alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
+ DECL_NAMESPACE_ALIAS (alias) = name_space;
+ DECL_EXTERNAL (alias) = 1;
+ DECL_CONTEXT (alias) = FROB_CONTEXT (current_scope ());
+ pushdecl (alias);
+
+ /* Emit debug info for namespace alias. */
+ if (!building_stmt_list_p ())
+ (*debug_hooks->global_decl) (alias);
+}
+
+/* Like pushdecl, only it places X in the current namespace,
+ if appropriate. */
+
+tree
+pushdecl_namespace_level (tree x, bool is_friend)
+{
+ cp_binding_level *b = current_binding_level;
+ tree t;
+
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace), is_friend);
+
+ /* Now, the type_shadowed stack may screw us. Munge it so it does
+ what we want. */
+ if (TREE_CODE (t) == TYPE_DECL)
+ {
+ tree name = DECL_NAME (t);
+ tree newval;
+ tree *ptr = (tree *)0;
+ for (; !global_scope_p (b); b = b->level_chain)
+ {
+ tree shadowed = b->type_shadowed;
+ for (; shadowed; shadowed = TREE_CHAIN (shadowed))
+ if (TREE_PURPOSE (shadowed) == name)
+ {
+ ptr = &TREE_VALUE (shadowed);
+ /* Can't break out of the loop here because sometimes
+ a binding level will have duplicate bindings for
+ PT names. It's gross, but I haven't time to fix it. */
+ }
+ }
+ newval = TREE_TYPE (t);
+ if (ptr == (tree *)0)
+ {
+ /* @@ This shouldn't be needed. My test case "zstring.cc" trips
+ up here if this is changed to an assertion. --KR */
+ SET_IDENTIFIER_TYPE_VALUE (name, t);
+ }
+ else
+ {
+ *ptr = newval;
+ }
+ }
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return t;
+}
+
+/* Insert USED into the using list of USER. Set INDIRECT_flag if this
+ directive is not directly from the source. Also find the common
+ ancestor and let our users know about the new namespace */
+
+static void
+add_using_namespace_1 (tree user, tree used, bool indirect)
+{
+ tree t;
+ /* Using oneself is a no-op. */
+ if (user == used)
+ return;
+ gcc_assert (TREE_CODE (user) == NAMESPACE_DECL);
+ gcc_assert (TREE_CODE (used) == NAMESPACE_DECL);
+ /* Check if we already have this. */
+ t = purpose_member (used, DECL_NAMESPACE_USING (user));
+ if (t != NULL_TREE)
+ {
+ if (!indirect)
+ /* Promote to direct usage. */
+ TREE_INDIRECT_USING (t) = 0;
+ return;
+ }
+
+ /* Add used to the user's using list. */
+ DECL_NAMESPACE_USING (user)
+ = tree_cons (used, namespace_ancestor (user, used),
+ DECL_NAMESPACE_USING (user));
+
+ TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
+
+ /* Add user to the used's users list. */
+ DECL_NAMESPACE_USERS (used)
+ = tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
+
+ /* Recursively add all namespaces used. */
+ for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
+ /* indirect usage */
+ add_using_namespace_1 (user, TREE_PURPOSE (t), 1);
+
+ /* Tell everyone using us about the new used namespaces. */
+ for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t))
+ add_using_namespace_1 (TREE_PURPOSE (t), used, 1);
+}
+
+/* Wrapper for add_using_namespace_1. */
+
+static void
+add_using_namespace (tree user, tree used, bool indirect)
+{
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ add_using_namespace_1 (user, used, indirect);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+}
+
+/* Process a using-declaration not appearing in class or local scope. */
+
+void
+do_toplevel_using_decl (tree decl, tree scope, tree name)
+{
+ tree oldval, oldtype, newval, newtype;
+ tree orig_decl = decl;
+ cxx_binding *binding;
+
+ decl = validate_nonmember_using_decl (decl, scope, name);
+ if (decl == NULL_TREE)
+ return;
+
+ binding = binding_for_name (NAMESPACE_LEVEL (current_namespace), name);
+
+ oldval = binding->value;
+ oldtype = binding->type;
+
+ do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
+
+ /* Emit debug info. */
+ if (!processing_template_decl)
+ cp_emit_debug_info_for_using (orig_decl, current_namespace);
+
+ /* Copy declarations found. */
+ if (newval)
+ binding->value = newval;
+ if (newtype)
+ binding->type = newtype;
+}
+
+/* Process a using-directive. */
+
+void
+do_using_directive (tree name_space)
+{
+ tree context = NULL_TREE;
+
+ if (name_space == error_mark_node)
+ return;
+
+ gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
+
+ if (building_stmt_list_p ())
+ add_stmt (build_stmt (input_location, USING_STMT, name_space));
+ name_space = ORIGINAL_NAMESPACE (name_space);
+
+ if (!toplevel_bindings_p ())
+ {
+ push_using_directive (name_space);
+ }
+ else
+ {
+ /* direct usage */
+ add_using_namespace (current_namespace, name_space, 0);
+ if (current_namespace != global_namespace)
+ context = current_namespace;
+
+ /* Emit debugging info. */
+ if (!processing_template_decl)
+ (*debug_hooks->imported_module_or_decl) (name_space, NULL_TREE,
+ context, false);
+ }
+}
+
+/* Deal with a using-directive seen by the parser. Currently we only
+ handle attributes here, since they cannot appear inside a template. */
+
+void
+parse_using_directive (tree name_space, tree attribs)
+{
+ tree a;
+
+ do_using_directive (name_space);
+
+ for (a = attribs; a; a = TREE_CHAIN (a))
+ {
+ tree name = TREE_PURPOSE (a);
+ if (is_attribute_p ("strong", name))
+ {
+ if (!toplevel_bindings_p ())
+ error ("strong using only meaningful at namespace scope");
+ else if (name_space != error_mark_node)
+ {
+ if (!is_ancestor (current_namespace, name_space))
+ error ("current namespace %qD does not enclose strongly used namespace %qD",
+ current_namespace, name_space);
+ DECL_NAMESPACE_ASSOCIATIONS (name_space)
+ = tree_cons (current_namespace, 0,
+ DECL_NAMESPACE_ASSOCIATIONS (name_space));
+ }
+ }
+ else
+ warning (OPT_Wattributes, "%qD attribute directive ignored", name);
+ }
+}
+
+/* Like pushdecl, only it places X in the global scope if appropriate.
+ Calls cp_finish_decl to register the variable, initializing it with
+ *INIT, if INIT is non-NULL. */
+
+static tree
+pushdecl_top_level_1 (tree x, tree *init, bool is_friend)
+{
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ push_to_top_level ();
+ x = pushdecl_namespace_level (x, is_friend);
+ if (init)
+ cp_finish_decl (x, *init, false, NULL_TREE, 0);
+ pop_from_top_level ();
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return x;
+}
+
+/* Like pushdecl, only it places X in the global scope if appropriate. */
+
+tree
+pushdecl_top_level (tree x)
+{
+ return pushdecl_top_level_1 (x, NULL, false);
+}
+
+/* Like pushdecl_top_level, but adding the IS_FRIEND parameter. */
+
+tree
+pushdecl_top_level_maybe_friend (tree x, bool is_friend)
+{
+ return pushdecl_top_level_1 (x, NULL, is_friend);
+}
+
+/* Like pushdecl, only it places X in the global scope if
+ appropriate. Calls cp_finish_decl to register the variable,
+ initializing it with INIT. */
+
+tree
+pushdecl_top_level_and_finish (tree x, tree init)
+{
+ return pushdecl_top_level_1 (x, &init, false);
+}
+
+/* Combines two sets of overloaded functions into an OVERLOAD chain, removing
+ duplicates. The first list becomes the tail of the result.
+
+ The algorithm is O(n^2). We could get this down to O(n log n) by
+ doing a sort on the addresses of the functions, if that becomes
+ necessary. */
+
+static tree
+merge_functions (tree s1, tree s2)
+{
+ for (; s2; s2 = OVL_NEXT (s2))
+ {
+ tree fn2 = OVL_CURRENT (s2);
+ tree fns1;
+
+ for (fns1 = s1; fns1; fns1 = OVL_NEXT (fns1))
+ {
+ tree fn1 = OVL_CURRENT (fns1);
+
+ /* If the function from S2 is already in S1, there is no
+ need to add it again. For `extern "C"' functions, we
+ might have two FUNCTION_DECLs for the same function, in
+ different namespaces, but let's leave them in in case
+ they have different default arguments. */
+ if (fn1 == fn2)
+ break;
+ }
+
+ /* If we exhausted all of the functions in S1, FN2 is new. */
+ if (!fns1)
+ s1 = build_overload (fn2, s1);
+ }
+ return s1;
+}
+
+/* Returns TRUE iff OLD and NEW are the same entity.
+
+ 3 [basic]/3: An entity is a value, object, reference, function,
+ enumerator, type, class member, template, template specialization,
+ namespace, parameter pack, or this.
+
+ 7.3.4 [namespace.udir]/4: If name lookup finds a declaration for a name
+ in two different namespaces, and the declarations do not declare the
+ same entity and do not declare functions, the use of the name is
+ ill-formed. */
+
+static bool
+same_entity_p (tree one, tree two)
+{
+ if (one == two)
+ return true;
+ if (!one || !two)
+ return false;
+ if (TREE_CODE (one) == TYPE_DECL
+ && TREE_CODE (two) == TYPE_DECL
+ && same_type_p (TREE_TYPE (one), TREE_TYPE (two)))
+ return true;
+ return false;
+}
+
+/* This should return an error not all definitions define functions.
+ It is not an error if we find two functions with exactly the
+ same signature, only if these are selected in overload resolution.
+ old is the current set of bindings, new_binding the freshly-found binding.
+ XXX Do we want to give *all* candidates in case of ambiguity?
+ XXX In what way should I treat extern declarations?
+ XXX I don't want to repeat the entire duplicate_decls here */
+
+static void
+ambiguous_decl (struct scope_binding *old, cxx_binding *new_binding, int flags)
+{
+ tree val, type;
+ gcc_assert (old != NULL);
+
+ /* Copy the type. */
+ type = new_binding->type;
+ if (LOOKUP_NAMESPACES_ONLY (flags)
+ || (type && hidden_name_p (type) && !(flags & LOOKUP_HIDDEN)))
+ type = NULL_TREE;
+
+ /* Copy the value. */
+ val = new_binding->value;
+ if (val)
+ {
+ if (hidden_name_p (val) && !(flags & LOOKUP_HIDDEN))
+ val = NULL_TREE;
+ else
+ switch (TREE_CODE (val))
+ {
+ case TEMPLATE_DECL:
+ /* If we expect types or namespaces, and not templates,
+ or this is not a template class. */
+ if ((LOOKUP_QUALIFIERS_ONLY (flags)
+ && !DECL_TYPE_TEMPLATE_P (val)))
+ val = NULL_TREE;
+ break;
+ case TYPE_DECL:
+ if (LOOKUP_NAMESPACES_ONLY (flags)
+ || (type && (flags & LOOKUP_PREFER_TYPES)))
+ val = NULL_TREE;
+ break;
+ case NAMESPACE_DECL:
+ if (LOOKUP_TYPES_ONLY (flags))
+ val = NULL_TREE;
+ break;
+ case FUNCTION_DECL:
+ /* Ignore built-in functions that are still anticipated. */
+ if (LOOKUP_QUALIFIERS_ONLY (flags))
+ val = NULL_TREE;
+ break;
+ default:
+ if (LOOKUP_QUALIFIERS_ONLY (flags))
+ val = NULL_TREE;
+ }
+ }
+
+ /* If val is hidden, shift down any class or enumeration name. */
+ if (!val)
+ {
+ val = type;
+ type = NULL_TREE;
+ }
+
+ if (!old->value)
+ old->value = val;
+ else if (val && !same_entity_p (val, old->value))
+ {
+ if (is_overloaded_fn (old->value) && is_overloaded_fn (val))
+ old->value = merge_functions (old->value, val);
+ else
+ {
+ old->value = tree_cons (NULL_TREE, old->value,
+ build_tree_list (NULL_TREE, val));
+ TREE_TYPE (old->value) = error_mark_node;
+ }
+ }
+
+ if (!old->type)
+ old->type = type;
+ else if (type && old->type != type)
+ {
+ old->type = tree_cons (NULL_TREE, old->type,
+ build_tree_list (NULL_TREE, type));
+ TREE_TYPE (old->type) = error_mark_node;
+ }
+}
+
+/* Return the declarations that are members of the namespace NS. */
+
+tree
+cp_namespace_decls (tree ns)
+{
+ return NAMESPACE_LEVEL (ns)->names;
+}
+
+/* Combine prefer_type and namespaces_only into flags. */
+
+static int
+lookup_flags (int prefer_type, int namespaces_only)
+{
+ if (namespaces_only)
+ return LOOKUP_PREFER_NAMESPACES;
+ if (prefer_type > 1)
+ return LOOKUP_PREFER_TYPES;
+ if (prefer_type > 0)
+ return LOOKUP_PREFER_BOTH;
+ return 0;
+}
+
+/* Given a lookup that returned VAL, use FLAGS to decide if we want to
+ ignore it or not. Subroutine of lookup_name_real and
+ lookup_type_scope. */
+
+static bool
+qualify_lookup (tree val, int flags)
+{
+ if (val == NULL_TREE)
+ return false;
+ if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
+ return true;
+ if (flags & LOOKUP_PREFER_TYPES)
+ {
+ tree target_val = strip_using_decl (val);
+ if (TREE_CODE (target_val) == TYPE_DECL
+ || TREE_CODE (target_val) == TEMPLATE_DECL)
+ return true;
+ }
+ if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
+ return false;
+ /* Look through lambda things that we shouldn't be able to see. */
+ if (is_lambda_ignored_entity (val))
+ return false;
+ return true;
+}
+
+/* Given a lookup that returned VAL, decide if we want to ignore it or
+ not based on DECL_ANTICIPATED. */
+
+bool
+hidden_name_p (tree val)
+{
+ if (DECL_P (val)
+ && DECL_LANG_SPECIFIC (val)
+ && TYPE_FUNCTION_OR_TEMPLATE_DECL_P (val)
+ && DECL_ANTICIPATED (val))
+ return true;
+ return false;
+}
+
+/* Remove any hidden friend functions from a possibly overloaded set
+ of functions. */
+
+tree
+remove_hidden_names (tree fns)
+{
+ if (!fns)
+ return fns;
+
+ if (TREE_CODE (fns) == FUNCTION_DECL && hidden_name_p (fns))
+ fns = NULL_TREE;
+ else if (TREE_CODE (fns) == OVERLOAD)
+ {
+ tree o;
+
+ for (o = fns; o; o = OVL_NEXT (o))
+ if (hidden_name_p (OVL_CURRENT (o)))
+ break;
+ if (o)
+ {
+ tree n = NULL_TREE;
+
+ for (o = fns; o; o = OVL_NEXT (o))
+ if (!hidden_name_p (OVL_CURRENT (o)))
+ n = build_overload (OVL_CURRENT (o), n);
+ fns = n;
+ }
+ }
+
+ return fns;
+}
+
+/* Suggest alternatives for NAME, an IDENTIFIER_NODE for which name
+ lookup failed. Search through all available namespaces and print out
+ possible candidates. */
+
+void
+suggest_alternatives_for (location_t location, tree name)
+{
+ vec<tree> candidates = vNULL;
+ vec<tree> namespaces_to_search = vNULL;
+ int max_to_search = PARAM_VALUE (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP);
+ int n_searched = 0;
+ tree t;
+ unsigned ix;
+
+ namespaces_to_search.safe_push (global_namespace);
+
+ while (!namespaces_to_search.is_empty ()
+ && n_searched < max_to_search)
+ {
+ tree scope = namespaces_to_search.pop ();
+ struct scope_binding binding = EMPTY_SCOPE_BINDING;
+ cp_binding_level *level = NAMESPACE_LEVEL (scope);
+
+ /* Look in this namespace. */
+ qualified_lookup_using_namespace (name, scope, &binding, 0);
+
+ n_searched++;
+
+ if (binding.value)
+ candidates.safe_push (binding.value);
+
+ /* Add child namespaces. */
+ for (t = level->namespaces; t; t = DECL_CHAIN (t))
+ namespaces_to_search.safe_push (t);
+ }
+
+ /* If we stopped before we could examine all namespaces, inform the
+ user. Do this even if we don't have any candidates, since there
+ might be more candidates further down that we weren't able to
+ find. */
+ if (n_searched >= max_to_search
+ && !namespaces_to_search.is_empty ())
+ inform (location,
+ "maximum limit of %d namespaces searched for %qE",
+ max_to_search, name);
+
+ namespaces_to_search.release ();
+
+ /* Nothing useful to report. */
+ if (candidates.is_empty ())
+ return;
+
+ inform_n (location, candidates.length (),
+ "suggested alternative:",
+ "suggested alternatives:");
+
+ FOR_EACH_VEC_ELT (candidates, ix, t)
+ inform (location_of (t), " %qE", t);
+
+ candidates.release ();
+}
+
+/* Unscoped lookup of a global: iterate over current namespaces,
+ considering using-directives. */
+
+static tree
+unqualified_namespace_lookup_1 (tree name, int flags)
+{
+ tree initial = current_decl_namespace ();
+ tree scope = initial;
+ tree siter;
+ cp_binding_level *level;
+ tree val = NULL_TREE;
+
+ for (; !val; scope = CP_DECL_CONTEXT (scope))
+ {
+ struct scope_binding binding = EMPTY_SCOPE_BINDING;
+ cxx_binding *b =
+ cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+
+ if (b)
+ ambiguous_decl (&binding, b, flags);
+
+ /* Add all _DECLs seen through local using-directives. */
+ for (level = current_binding_level;
+ level->kind != sk_namespace;
+ level = level->level_chain)
+ if (!lookup_using_namespace (name, &binding, level->using_directives,
+ scope, flags))
+ /* Give up because of error. */
+ return error_mark_node;
+
+ /* Add all _DECLs seen through global using-directives. */
+ /* XXX local and global using lists should work equally. */
+ siter = initial;
+ while (1)
+ {
+ if (!lookup_using_namespace (name, &binding,
+ DECL_NAMESPACE_USING (siter),
+ scope, flags))
+ /* Give up because of error. */
+ return error_mark_node;
+ if (siter == scope) break;
+ siter = CP_DECL_CONTEXT (siter);
+ }
+
+ val = binding.value;
+ if (scope == global_namespace)
+ break;
+ }
+ return val;
+}
+
+/* Wrapper for unqualified_namespace_lookup_1. */
+
+static tree
+unqualified_namespace_lookup (tree name, int flags)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = unqualified_namespace_lookup_1 (name, flags);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+/* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL
+ or a class TYPE). If IS_TYPE_P is TRUE, then ignore non-type
+ bindings.
+
+ Returns a DECL (or OVERLOAD, or BASELINK) representing the
+ declaration found. If no suitable declaration can be found,
+ ERROR_MARK_NODE is returned. If COMPLAIN is true and SCOPE is
+ neither a class-type nor a namespace a diagnostic is issued. */
+
+tree
+lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
+{
+ int flags = 0;
+ tree t = NULL_TREE;
+
+ if (TREE_CODE (scope) == NAMESPACE_DECL)
+ {
+ struct scope_binding binding = EMPTY_SCOPE_BINDING;
+
+ if (is_type_p)
+ flags |= LOOKUP_PREFER_TYPES;
+ if (qualified_lookup_using_namespace (name, scope, &binding, flags))
+ t = binding.value;
+ }
+ else if (cxx_dialect != cxx98 && TREE_CODE (scope) == ENUMERAL_TYPE)
+ t = lookup_enumerator (scope, name);
+ else if (is_class_type (scope, complain))
+ t = lookup_member (scope, name, 2, is_type_p, tf_warning_or_error);
+
+ if (!t)
+ return error_mark_node;
+ return t;
+}
+
+/* Subroutine of unqualified_namespace_lookup:
+ Add the bindings of NAME in used namespaces to VAL.
+ We are currently looking for names in namespace SCOPE, so we
+ look through USINGS for using-directives of namespaces
+ which have SCOPE as a common ancestor with the current scope.
+ Returns false on errors. */
+
+static bool
+lookup_using_namespace (tree name, struct scope_binding *val,
+ tree usings, tree scope, int flags)
+{
+ tree iter;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ /* Iterate over all used namespaces in current, searching for using
+ directives of scope. */
+ for (iter = usings; iter; iter = TREE_CHAIN (iter))
+ if (TREE_VALUE (iter) == scope)
+ {
+ tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
+ cxx_binding *val1 =
+ cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (used), name);
+ /* Resolve ambiguities. */
+ if (val1)
+ ambiguous_decl (val, val1, flags);
+ }
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return val->value != error_mark_node;
+}
+
+/* Returns true iff VEC contains TARGET. */
+
+static bool
+tree_vec_contains (vec<tree, va_gc> *vec, tree target)
+{
+ unsigned int i;
+ tree elt;
+ FOR_EACH_VEC_SAFE_ELT (vec,i,elt)
+ if (elt == target)
+ return true;
+ return false;
+}
+
+/* [namespace.qual]
+ Accepts the NAME to lookup and its qualifying SCOPE.
+ Returns the name/type pair found into the cxx_binding *RESULT,
+ or false on error. */
+
+static bool
+qualified_lookup_using_namespace (tree name, tree scope,
+ struct scope_binding *result, int flags)
+{
+ /* Maintain a list of namespaces visited... */
+ vec<tree, va_gc> *seen = NULL;
+ vec<tree, va_gc> *seen_inline = NULL;
+ /* ... and a list of namespace yet to see. */
+ vec<tree, va_gc> *todo = NULL;
+ vec<tree, va_gc> *todo_maybe = NULL;
+ vec<tree, va_gc> *todo_inline = NULL;
+ tree usings;
+ timevar_start (TV_NAME_LOOKUP);
+ /* Look through namespace aliases. */
+ scope = ORIGINAL_NAMESPACE (scope);
+
+ /* Algorithm: Starting with SCOPE, walk through the set of used
+ namespaces. For each used namespace, look through its inline
+ namespace set for any bindings and usings. If no bindings are
+ found, add any usings seen to the set of used namespaces. */
+ vec_safe_push (todo, scope);
+
+ while (todo->length ())
+ {
+ bool found_here;
+ scope = todo->pop ();
+ if (tree_vec_contains (seen, scope))
+ continue;
+ vec_safe_push (seen, scope);
+ vec_safe_push (todo_inline, scope);
+
+ found_here = false;
+ while (todo_inline->length ())
+ {
+ cxx_binding *binding;
+
+ scope = todo_inline->pop ();
+ if (tree_vec_contains (seen_inline, scope))
+ continue;
+ vec_safe_push (seen_inline, scope);
+
+ binding =
+ cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+ if (binding)
+ {
+ found_here = true;
+ ambiguous_decl (result, binding, flags);
+ }
+
+ for (usings = DECL_NAMESPACE_USING (scope); usings;
+ usings = TREE_CHAIN (usings))
+ if (!TREE_INDIRECT_USING (usings))
+ {
+ if (is_associated_namespace (scope, TREE_PURPOSE (usings)))
+ vec_safe_push (todo_inline, TREE_PURPOSE (usings));
+ else
+ vec_safe_push (todo_maybe, TREE_PURPOSE (usings));
+ }
+ }
+
+ if (found_here)
+ vec_safe_truncate (todo_maybe, 0);
+ else
+ while (vec_safe_length (todo_maybe))
+ vec_safe_push (todo, todo_maybe->pop ());
+ }
+ vec_free (todo);
+ vec_free (todo_maybe);
+ vec_free (todo_inline);
+ vec_free (seen);
+ vec_free (seen_inline);
+ timevar_stop (TV_NAME_LOOKUP);
+ return result->value != error_mark_node;
+}
+
+/* Subroutine of outer_binding.
+
+ Returns TRUE if BINDING is a binding to a template parameter of
+ SCOPE. In that case SCOPE is the scope of a primary template
+ parameter -- in the sense of G++, i.e, a template that has its own
+ template header.
+
+ Returns FALSE otherwise. */
+
+static bool
+binding_to_template_parms_of_scope_p (cxx_binding *binding,
+ cp_binding_level *scope)
+{
+ tree binding_value, tmpl, tinfo;
+ int level;
+
+ if (!binding || !scope || !scope->this_entity)
+ return false;
+
+ binding_value = binding->value ? binding->value : binding->type;
+ tinfo = get_template_info (scope->this_entity);
+
+ /* BINDING_VALUE must be a template parm. */
+ if (binding_value == NULL_TREE
+ || (!DECL_P (binding_value)
+ || !DECL_TEMPLATE_PARM_P (binding_value)))
+ return false;
+
+ /* The level of BINDING_VALUE. */
+ level =
+ template_type_parameter_p (binding_value)
+ ? TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX
+ (TREE_TYPE (binding_value)))
+ : TEMPLATE_PARM_LEVEL (DECL_INITIAL (binding_value));
+
+ /* The template of the current scope, iff said scope is a primary
+ template. */
+ tmpl = (tinfo
+ && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo))
+ ? TI_TEMPLATE (tinfo)
+ : NULL_TREE);
+
+ /* If the level of the parm BINDING_VALUE equals the depth of TMPL,
+ then BINDING_VALUE is a parameter of TMPL. */
+ return (tmpl && level == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)));
+}
+
+/* Return the innermost non-namespace binding for NAME from a scope
+ containing BINDING, or, if BINDING is NULL, the current scope.
+ Please note that for a given template, the template parameters are
+ considered to be in the scope containing the current scope.
+ If CLASS_P is false, then class bindings are ignored. */
+
+cxx_binding *
+outer_binding (tree name,
+ cxx_binding *binding,
+ bool class_p)
+{
+ cxx_binding *outer;
+ cp_binding_level *scope;
+ cp_binding_level *outer_scope;
+
+ if (binding)
+ {
+ scope = binding->scope->level_chain;
+ outer = binding->previous;
+ }
+ else
+ {
+ scope = current_binding_level;
+ outer = IDENTIFIER_BINDING (name);
+ }
+ outer_scope = outer ? outer->scope : NULL;
+
+ /* Because we create class bindings lazily, we might be missing a
+ class binding for NAME. If there are any class binding levels
+ between the LAST_BINDING_LEVEL and the scope in which OUTER was
+ declared, we must lookup NAME in those class scopes. */
+ if (class_p)
+ while (scope && scope != outer_scope && scope->kind != sk_namespace)
+ {
+ if (scope->kind == sk_class)
+ {
+ cxx_binding *class_binding;
+
+ class_binding = get_class_binding (name, scope);
+ if (class_binding)
+ {
+ /* Thread this new class-scope binding onto the
+ IDENTIFIER_BINDING list so that future lookups
+ find it quickly. */
+ class_binding->previous = outer;
+ if (binding)
+ binding->previous = class_binding;
+ else
+ IDENTIFIER_BINDING (name) = class_binding;
+ return class_binding;
+ }
+ }
+ /* If we are in a member template, the template parms of the member
+ template are considered to be inside the scope of the containing
+ class, but within G++ the class bindings are all pushed between the
+ template parms and the function body. So if the outer binding is
+ a template parm for the current scope, return it now rather than
+ look for a class binding. */
+ if (outer_scope && outer_scope->kind == sk_template_parms
+ && binding_to_template_parms_of_scope_p (outer, scope))
+ return outer;
+
+ scope = scope->level_chain;
+ }
+
+ return outer;
+}
+
+/* Return the innermost block-scope or class-scope value binding for
+ NAME, or NULL_TREE if there is no such binding. */
+
+tree
+innermost_non_namespace_value (tree name)
+{
+ cxx_binding *binding;
+ binding = outer_binding (name, /*binding=*/NULL, /*class_p=*/true);
+ return binding ? binding->value : NULL_TREE;
+}
+
+/* Look up NAME in the current binding level and its superiors in the
+ namespace of variables, functions and typedefs. Return a ..._DECL
+ node of some kind representing its definition if there is only one
+ such declaration, or return a TREE_LIST with all the overloaded
+ definitions if there are many, or return 0 if it is undefined.
+ Hidden name, either friend declaration or built-in function, are
+ not ignored.
+
+ If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
+ If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
+ Otherwise we prefer non-TYPE_DECLs.
+
+ If NONCLASS is nonzero, bindings in class scopes are ignored. If
+ BLOCK_P is false, bindings in block scopes are ignored. */
+
+static tree
+lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p,
+ int namespaces_only, int flags)
+{
+ cxx_binding *iter;
+ tree val = NULL_TREE;
+
+ /* Conversion operators are handled specially because ordinary
+ unqualified name lookup will not find template conversion
+ operators. */
+ if (IDENTIFIER_TYPENAME_P (name))
+ {
+ cp_binding_level *level;
+
+ for (level = current_binding_level;
+ level && level->kind != sk_namespace;
+ level = level->level_chain)
+ {
+ tree class_type;
+ tree operators;
+
+ /* A conversion operator can only be declared in a class
+ scope. */
+ if (level->kind != sk_class)
+ continue;
+
+ /* Lookup the conversion operator in the class. */
+ class_type = level->this_entity;
+ operators = lookup_fnfields (class_type, name, /*protect=*/0);
+ if (operators)
+ return operators;
+ }
+
+ return NULL_TREE;
+ }
+
+ flags |= lookup_flags (prefer_type, namespaces_only);
+
+ /* First, look in non-namespace scopes. */
+
+ if (current_class_type == NULL_TREE)
+ nonclass = 1;
+
+ if (block_p || !nonclass)
+ for (iter = outer_binding (name, NULL, !nonclass);
+ iter;
+ iter = outer_binding (name, iter, !nonclass))
+ {
+ tree binding;
+
+ /* Skip entities we don't want. */
+ if (LOCAL_BINDING_P (iter) ? !block_p : nonclass)
+ continue;
+
+ /* If this is the kind of thing we're looking for, we're done. */
+ if (qualify_lookup (iter->value, flags))
+ binding = iter->value;
+ else if ((flags & LOOKUP_PREFER_TYPES)
+ && qualify_lookup (iter->type, flags))
+ binding = iter->type;
+ else
+ binding = NULL_TREE;
+
+ if (binding)
+ {
+ if (hidden_name_p (binding))
+ {
+ /* A non namespace-scope binding can only be hidden in the
+ presence of a local class, due to friend declarations.
+
+ In particular, consider:
+
+ struct C;
+ void f() {
+ struct A {
+ friend struct B;
+ friend struct C;
+ void g() {
+ B* b; // error: B is hidden
+ C* c; // OK, finds ::C
+ }
+ };
+ B *b; // error: B is hidden
+ C *c; // OK, finds ::C
+ struct B {};
+ B *bb; // OK
+ }
+
+ The standard says that "B" is a local class in "f"
+ (but not nested within "A") -- but that name lookup
+ for "B" does not find this declaration until it is
+ declared directly with "f".
+
+ In particular:
+
+ [class.friend]
+
+ If a friend declaration appears in a local class and
+ the name specified is an unqualified name, a prior
+ declaration is looked up without considering scopes
+ that are outside the innermost enclosing non-class
+ scope. For a friend function declaration, if there is
+ no prior declaration, the program is ill-formed. For a
+ friend class declaration, if there is no prior
+ declaration, the class that is specified belongs to the
+ innermost enclosing non-class scope, but if it is
+ subsequently referenced, its name is not found by name
+ lookup until a matching declaration is provided in the
+ innermost enclosing nonclass scope.
+
+ So just keep looking for a non-hidden binding.
+ */
+ gcc_assert (TREE_CODE (binding) == TYPE_DECL);
+ continue;
+ }
+ val = binding;
+ break;
+ }
+ }
+
+ /* Now lookup in namespace scopes. */
+ if (!val)
+ val = unqualified_namespace_lookup (name, flags);
+
+ /* If we have a single function from a using decl, pull it out. */
+ if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val))
+ val = OVL_FUNCTION (val);
+
+ return val;
+}
+
+/* Wrapper for lookup_name_real_1. */
+
+tree
+lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
+ int namespaces_only, int flags)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = lookup_name_real_1 (name, prefer_type, nonclass, block_p,
+ namespaces_only, flags);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+tree
+lookup_name_nonclass (tree name)
+{
+ return lookup_name_real (name, 0, 1, /*block_p=*/true, 0, 0);
+}
+
+tree
+lookup_function_nonclass (tree name, vec<tree, va_gc> *args, bool block_p)
+{
+ return
+ lookup_arg_dependent (name,
+ lookup_name_real (name, 0, 1, block_p, 0, 0),
+ args);
+}
+
+tree
+lookup_name (tree name)
+{
+ return lookup_name_real (name, 0, 0, /*block_p=*/true, 0, 0);
+}
+
+tree
+lookup_name_prefer_type (tree name, int prefer_type)
+{
+ return lookup_name_real (name, prefer_type, 0, /*block_p=*/true, 0, 0);
+}
+
+/* Look up NAME for type used in elaborated name specifier in
+ the scopes given by SCOPE. SCOPE can be either TS_CURRENT or
+ TS_WITHIN_ENCLOSING_NON_CLASS. Although not implied by the
+ name, more scopes are checked if cleanup or template parameter
+ scope is encountered.
+
+ Unlike lookup_name_real, we make sure that NAME is actually
+ declared in the desired scope, not from inheritance, nor using
+ directive. For using declaration, there is DR138 still waiting
+ to be resolved. Hidden name coming from an earlier friend
+ declaration is also returned.
+
+ A TYPE_DECL best matching the NAME is returned. Catching error
+ and issuing diagnostics are caller's responsibility. */
+
+static tree
+lookup_type_scope_1 (tree name, tag_scope scope)
+{
+ cxx_binding *iter = NULL;
+ tree val = NULL_TREE;
+
+ /* Look in non-namespace scope first. */
+ if (current_binding_level->kind != sk_namespace)
+ iter = outer_binding (name, NULL, /*class_p=*/ true);
+ for (; iter; iter = outer_binding (name, iter, /*class_p=*/ true))
+ {
+ /* Check if this is the kind of thing we're looking for.
+ If SCOPE is TS_CURRENT, also make sure it doesn't come from
+ base class. For ITER->VALUE, we can simply use
+ INHERITED_VALUE_BINDING_P. For ITER->TYPE, we have to use
+ our own check.
+
+ We check ITER->TYPE before ITER->VALUE in order to handle
+ typedef struct C {} C;
+ correctly. */
+
+ if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES)
+ && (scope != ts_current
+ || LOCAL_BINDING_P (iter)
+ || DECL_CONTEXT (iter->type) == iter->scope->this_entity))
+ val = iter->type;
+ else if ((scope != ts_current
+ || !INHERITED_VALUE_BINDING_P (iter))
+ && qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
+ val = iter->value;
+
+ if (val)
+ break;
+ }
+
+ /* Look in namespace scope. */
+ if (!val)
+ {
+ iter = cp_binding_level_find_binding_for_name
+ (NAMESPACE_LEVEL (current_decl_namespace ()), name);
+
+ if (iter)
+ {
+ /* If this is the kind of thing we're looking for, we're done. */
+ if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES))
+ val = iter->type;
+ else if (qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
+ val = iter->value;
+ }
+
+ }
+
+ /* Type found, check if it is in the allowed scopes, ignoring cleanup
+ and template parameter scopes. */
+ if (val)
+ {
+ cp_binding_level *b = current_binding_level;
+ while (b)
+ {
+ if (iter->scope == b)
+ return val;
+
+ if (b->kind == sk_cleanup || b->kind == sk_template_parms
+ || b->kind == sk_function_parms)
+ b = b->level_chain;
+ else if (b->kind == sk_class
+ && scope == ts_within_enclosing_non_class)
+ b = b->level_chain;
+ else
+ break;
+ }
+ }
+
+ return NULL_TREE;
+}
+
+/* Wrapper for lookup_type_scope_1. */
+
+tree
+lookup_type_scope (tree name, tag_scope scope)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = lookup_type_scope_1 (name, scope);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+
+/* Similar to `lookup_name' but look only in the innermost non-class
+ binding level. */
+
+static tree
+lookup_name_innermost_nonclass_level_1 (tree name)
+{
+ cp_binding_level *b;
+ tree t = NULL_TREE;
+
+ b = innermost_nonclass_level ();
+
+ if (b->kind == sk_namespace)
+ {
+ t = IDENTIFIER_NAMESPACE_VALUE (name);
+
+ /* extern "C" function() */
+ if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
+ t = TREE_VALUE (t);
+ }
+ else if (IDENTIFIER_BINDING (name)
+ && LOCAL_BINDING_P (IDENTIFIER_BINDING (name)))
+ {
+ cxx_binding *binding;
+ binding = IDENTIFIER_BINDING (name);
+ while (1)
+ {
+ if (binding->scope == b
+ && !(VAR_P (binding->value)
+ && DECL_DEAD_FOR_LOCAL (binding->value)))
+ return binding->value;
+
+ if (b->kind == sk_cleanup)
+ b = b->level_chain;
+ else
+ break;
+ }
+ }
+
+ return t;
+}
+
+/* Wrapper for lookup_name_innermost_nonclass_level_1. */
+
+tree
+lookup_name_innermost_nonclass_level (tree name)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = lookup_name_innermost_nonclass_level_1 (name);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+
+/* Returns true iff DECL is a block-scope extern declaration of a function
+ or variable. */
+
+bool
+is_local_extern (tree decl)
+{
+ cxx_binding *binding;
+
+ /* For functions, this is easy. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ return DECL_LOCAL_FUNCTION_P (decl);
+
+ if (!VAR_P (decl))
+ return false;
+ if (!current_function_decl)
+ return false;
+
+ /* For variables, this is not easy. We need to look at the binding stack
+ for the identifier to see whether the decl we have is a local. */
+ for (binding = IDENTIFIER_BINDING (DECL_NAME (decl));
+ binding && binding->scope->kind != sk_namespace;
+ binding = binding->previous)
+ if (binding->value == decl)
+ return LOCAL_BINDING_P (binding);
+
+ return false;
+}
+
+/* Like lookup_name_innermost_nonclass_level, but for types. */
+
+static tree
+lookup_type_current_level (tree name)
+{
+ tree t = NULL_TREE;
+
+ timevar_start (TV_NAME_LOOKUP);
+ gcc_assert (current_binding_level->kind != sk_namespace);
+
+ if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
+ && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
+ {
+ cp_binding_level *b = current_binding_level;
+ while (1)
+ {
+ if (purpose_member (name, b->type_shadowed))
+ {
+ t = REAL_IDENTIFIER_TYPE_VALUE (name);
+ break;
+ }
+ if (b->kind == sk_cleanup)
+ b = b->level_chain;
+ else
+ break;
+ }
+ }
+
+ timevar_stop (TV_NAME_LOOKUP);
+ return t;
+}
+
+/* [basic.lookup.koenig] */
+/* A nonzero return value in the functions below indicates an error. */
+
+struct arg_lookup
+{
+ tree name;
+ vec<tree, va_gc> *args;
+ vec<tree, va_gc> *namespaces;
+ vec<tree, va_gc> *classes;
+ tree functions;
+ struct pointer_set_t *fn_set;
+};
+
+static bool arg_assoc (struct arg_lookup*, tree);
+static bool arg_assoc_args (struct arg_lookup*, tree);
+static bool arg_assoc_args_vec (struct arg_lookup*, vec<tree, va_gc> *);
+static bool arg_assoc_type (struct arg_lookup*, tree);
+static bool add_function (struct arg_lookup *, tree);
+static bool arg_assoc_namespace (struct arg_lookup *, tree);
+static bool arg_assoc_class_only (struct arg_lookup *, tree);
+static bool arg_assoc_bases (struct arg_lookup *, tree);
+static bool arg_assoc_class (struct arg_lookup *, tree);
+static bool arg_assoc_template_arg (struct arg_lookup*, tree);
+
+/* Add a function to the lookup structure.
+ Returns true on error. */
+
+static bool
+add_function (struct arg_lookup *k, tree fn)
+{
+ if (!is_overloaded_fn (fn))
+ /* All names except those of (possibly overloaded) functions and
+ function templates are ignored. */;
+ else if (k->fn_set && pointer_set_insert (k->fn_set, fn))
+ /* It's already in the list. */;
+ else if (!k->functions)
+ k->functions = fn;
+ else if (fn == k->functions)
+ ;
+ else
+ {
+ k->functions = build_overload (fn, k->functions);
+ if (TREE_CODE (k->functions) == OVERLOAD)
+ OVL_ARG_DEPENDENT (k->functions) = true;
+ }
+
+ return false;
+}
+
+/* Returns true iff CURRENT has declared itself to be an associated
+ namespace of SCOPE via a strong using-directive (or transitive chain
+ thereof). Both are namespaces. */
+
+bool
+is_associated_namespace (tree current, tree scope)
+{
+ vec<tree, va_gc> *seen = make_tree_vector ();
+ vec<tree, va_gc> *todo = make_tree_vector ();
+ tree t;
+ bool ret;
+
+ while (1)
+ {
+ if (scope == current)
+ {
+ ret = true;
+ break;
+ }
+ vec_safe_push (seen, scope);
+ for (t = DECL_NAMESPACE_ASSOCIATIONS (scope); t; t = TREE_CHAIN (t))
+ if (!vec_member (TREE_PURPOSE (t), seen))
+ vec_safe_push (todo, TREE_PURPOSE (t));
+ if (!todo->is_empty ())
+ {
+ scope = todo->last ();
+ todo->pop ();
+ }
+ else
+ {
+ ret = false;
+ break;
+ }
+ }
+
+ release_tree_vector (seen);
+ release_tree_vector (todo);
+
+ return ret;
+}
+
+/* Add functions of a namespace to the lookup structure.
+ Returns true on error. */
+
+static bool
+arg_assoc_namespace (struct arg_lookup *k, tree scope)
+{
+ tree value;
+
+ if (vec_member (scope, k->namespaces))
+ return false;
+ vec_safe_push (k->namespaces, scope);
+
+ /* Check out our super-users. */
+ for (value = DECL_NAMESPACE_ASSOCIATIONS (scope); value;
+ value = TREE_CHAIN (value))
+ if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
+ return true;
+
+ /* Also look down into inline namespaces. */
+ for (value = DECL_NAMESPACE_USING (scope); value;
+ value = TREE_CHAIN (value))
+ if (is_associated_namespace (scope, TREE_PURPOSE (value)))
+ if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
+ return true;
+
+ value = namespace_binding (k->name, scope);
+ if (!value)
+ return false;
+
+ for (; value; value = OVL_NEXT (value))
+ {
+ /* We don't want to find arbitrary hidden functions via argument
+ dependent lookup. We only want to find friends of associated
+ classes, which we'll do via arg_assoc_class. */
+ if (hidden_name_p (OVL_CURRENT (value)))
+ continue;
+
+ if (add_function (k, OVL_CURRENT (value)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Adds everything associated with a template argument to the lookup
+ structure. Returns true on error. */
+
+static bool
+arg_assoc_template_arg (struct arg_lookup *k, tree arg)
+{
+ /* [basic.lookup.koenig]
+
+ If T is a template-id, its associated namespaces and classes are
+ ... the namespaces and classes associated with the types of the
+ template arguments provided for template type parameters
+ (excluding template template parameters); the namespaces in which
+ any template template arguments are defined; and the classes in
+ which any member templates used as template template arguments
+ are defined. [Note: non-type template arguments do not
+ contribute to the set of associated namespaces. ] */
+
+ /* Consider first template template arguments. */
+ if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)
+ return false;
+ else if (TREE_CODE (arg) == TEMPLATE_DECL)
+ {
+ tree ctx = CP_DECL_CONTEXT (arg);
+
+ /* It's not a member template. */
+ if (TREE_CODE (ctx) == NAMESPACE_DECL)
+ return arg_assoc_namespace (k, ctx);
+ /* Otherwise, it must be member template. */
+ else
+ return arg_assoc_class_only (k, ctx);
+ }
+ /* It's an argument pack; handle it recursively. */
+ else if (ARGUMENT_PACK_P (arg))
+ {
+ tree args = ARGUMENT_PACK_ARGS (arg);
+ int i, len = TREE_VEC_LENGTH (args);
+ for (i = 0; i < len; ++i)
+ if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, i)))
+ return true;
+
+ return false;
+ }
+ /* It's not a template template argument, but it is a type template
+ argument. */
+ else if (TYPE_P (arg))
+ return arg_assoc_type (k, arg);
+ /* It's a non-type template argument. */
+ else
+ return false;
+}
+
+/* Adds the class and its friends to the lookup structure.
+ Returns true on error. */
+
+static bool
+arg_assoc_class_only (struct arg_lookup *k, tree type)
+{
+ tree list, friends, context;
+
+ /* Backend-built structures, such as __builtin_va_list, aren't
+ affected by all this. */
+ if (!CLASS_TYPE_P (type))
+ return false;
+
+ context = decl_namespace_context (type);
+ if (arg_assoc_namespace (k, context))
+ return true;
+
+ complete_type (type);
+
+ /* Process friends. */
+ for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
+ list = TREE_CHAIN (list))
+ if (k->name == FRIEND_NAME (list))
+ for (friends = FRIEND_DECLS (list); friends;
+ friends = TREE_CHAIN (friends))
+ {
+ tree fn = TREE_VALUE (friends);
+
+ /* Only interested in global functions with potentially hidden
+ (i.e. unqualified) declarations. */
+ if (CP_DECL_CONTEXT (fn) != context)
+ continue;
+ /* Template specializations are never found by name lookup.
+ (Templates themselves can be found, but not template
+ specializations.) */
+ if (TREE_CODE (fn) == FUNCTION_DECL && DECL_USE_TEMPLATE (fn))
+ continue;
+ if (add_function (k, fn))
+ return true;
+ }
+
+ return false;
+}
+
+/* Adds the class and its bases to the lookup structure.
+ Returns true on error. */
+
+static bool
+arg_assoc_bases (struct arg_lookup *k, tree type)
+{
+ if (arg_assoc_class_only (k, type))
+ return true;
+
+ if (TYPE_BINFO (type))
+ {
+ /* Process baseclasses. */
+ tree binfo, base_binfo;
+ int i;
+
+ for (binfo = TYPE_BINFO (type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ if (arg_assoc_bases (k, BINFO_TYPE (base_binfo)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Adds everything associated with a class argument type to the lookup
+ structure. Returns true on error.
+
+ If T is a class type (including unions), its associated classes are: the
+ class itself; the class of which it is a member, if any; and its direct
+ and indirect base classes. Its associated namespaces are the namespaces
+ of which its associated classes are members. Furthermore, if T is a
+ class template specialization, its associated namespaces and classes
+ also include: the namespaces and classes associated with the types of
+ the template arguments provided for template type parameters (excluding
+ template template parameters); the namespaces of which any template
+ template arguments are members; and the classes of which any member
+ templates used as template template arguments are members. [ Note:
+ non-type template arguments do not contribute to the set of associated
+ namespaces. --end note] */
+
+static bool
+arg_assoc_class (struct arg_lookup *k, tree type)
+{
+ tree list;
+ int i;
+
+ /* Backend build structures, such as __builtin_va_list, aren't
+ affected by all this. */
+ if (!CLASS_TYPE_P (type))
+ return false;
+
+ if (vec_member (type, k->classes))
+ return false;
+ vec_safe_push (k->classes, type);
+
+ if (TYPE_CLASS_SCOPE_P (type)
+ && arg_assoc_class_only (k, TYPE_CONTEXT (type)))
+ return true;
+
+ if (arg_assoc_bases (k, type))
+ return true;
+
+ /* Process template arguments. */
+ if (CLASSTYPE_TEMPLATE_INFO (type)
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
+ {
+ list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
+ for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
+ if (arg_assoc_template_arg (k, TREE_VEC_ELT (list, i)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Adds everything associated with a given type.
+ Returns 1 on error. */
+
+static bool
+arg_assoc_type (struct arg_lookup *k, tree type)
+{
+ /* As we do not get the type of non-type dependent expressions
+ right, we can end up with such things without a type. */
+ if (!type)
+ return false;
+
+ if (TYPE_PTRDATAMEM_P (type))
+ {
+ /* Pointer to member: associate class type and value type. */
+ if (arg_assoc_type (k, TYPE_PTRMEM_CLASS_TYPE (type)))
+ return true;
+ return arg_assoc_type (k, TYPE_PTRMEM_POINTED_TO_TYPE (type));
+ }
+ else switch (TREE_CODE (type))
+ {
+ case ERROR_MARK:
+ return false;
+ case VOID_TYPE:
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ case BOOLEAN_TYPE:
+ case FIXED_POINT_TYPE:
+ case DECLTYPE_TYPE:
+ case NULLPTR_TYPE:
+ return false;
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (type))
+ return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
+ case UNION_TYPE:
+ return arg_assoc_class (k, type);
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ case ARRAY_TYPE:
+ return arg_assoc_type (k, TREE_TYPE (type));
+ case ENUMERAL_TYPE:
+ if (TYPE_CLASS_SCOPE_P (type)
+ && arg_assoc_class_only (k, TYPE_CONTEXT (type)))
+ return true;
+ return arg_assoc_namespace (k, decl_namespace_context (type));
+ case METHOD_TYPE:
+ /* The basetype is referenced in the first arg type, so just
+ fall through. */
+ case FUNCTION_TYPE:
+ /* Associate the parameter types. */
+ if (arg_assoc_args (k, TYPE_ARG_TYPES (type)))
+ return true;
+ /* Associate the return type. */
+ return arg_assoc_type (k, TREE_TYPE (type));
+ case TEMPLATE_TYPE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ return false;
+ case TYPENAME_TYPE:
+ return false;
+ case LANG_TYPE:
+ gcc_assert (type == unknown_type_node
+ || type == init_list_type_node);
+ return false;
+ case TYPE_PACK_EXPANSION:
+ return arg_assoc_type (k, PACK_EXPANSION_PATTERN (type));
+
+ default:
+ gcc_unreachable ();
+ }
+ return false;
+}
+
+/* Adds everything associated with arguments. Returns true on error. */
+
+static bool
+arg_assoc_args (struct arg_lookup *k, tree args)
+{
+ for (; args; args = TREE_CHAIN (args))
+ if (arg_assoc (k, TREE_VALUE (args)))
+ return true;
+ return false;
+}
+
+/* Adds everything associated with an argument vector. Returns true
+ on error. */
+
+static bool
+arg_assoc_args_vec (struct arg_lookup *k, vec<tree, va_gc> *args)
+{
+ unsigned int ix;
+ tree arg;
+
+ FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
+ if (arg_assoc (k, arg))
+ return true;
+ return false;
+}
+
+/* Adds everything associated with a given tree_node. Returns 1 on error. */
+
+static bool
+arg_assoc (struct arg_lookup *k, tree n)
+{
+ if (n == error_mark_node)
+ return false;
+
+ if (TYPE_P (n))
+ return arg_assoc_type (k, n);
+
+ if (! type_unknown_p (n))
+ return arg_assoc_type (k, TREE_TYPE (n));
+
+ if (TREE_CODE (n) == ADDR_EXPR)
+ n = TREE_OPERAND (n, 0);
+ if (TREE_CODE (n) == COMPONENT_REF)
+ n = TREE_OPERAND (n, 1);
+ if (TREE_CODE (n) == OFFSET_REF)
+ n = TREE_OPERAND (n, 1);
+ while (TREE_CODE (n) == TREE_LIST)
+ n = TREE_VALUE (n);
+ if (BASELINK_P (n))
+ n = BASELINK_FUNCTIONS (n);
+
+ if (TREE_CODE (n) == FUNCTION_DECL)
+ return arg_assoc_type (k, TREE_TYPE (n));
+ if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
+ {
+ /* The working paper doesn't currently say how to handle template-id
+ arguments. The sensible thing would seem to be to handle the list
+ of template candidates like a normal overload set, and handle the
+ template arguments like we do for class template
+ specializations. */
+ tree templ = TREE_OPERAND (n, 0);
+ tree args = TREE_OPERAND (n, 1);
+ int ix;
+
+ /* First the templates. */
+ if (arg_assoc (k, templ))
+ return true;
+
+ /* Now the arguments. */
+ if (args)
+ for (ix = TREE_VEC_LENGTH (args); ix--;)
+ if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
+ return true;
+ }
+ else if (TREE_CODE (n) == OVERLOAD)
+ {
+ for (; n; n = OVL_NEXT (n))
+ if (arg_assoc_type (k, TREE_TYPE (OVL_CURRENT (n))))
+ return true;
+ }
+
+ return false;
+}
+
+/* Performs Koenig lookup depending on arguments, where fns
+ are the functions found in normal lookup. */
+
+static tree
+lookup_arg_dependent_1 (tree name, tree fns, vec<tree, va_gc> *args)
+{
+ struct arg_lookup k;
+
+ /* Remove any hidden friend functions from the list of functions
+ found so far. They will be added back by arg_assoc_class as
+ appropriate. */
+ fns = remove_hidden_names (fns);
+
+ k.name = name;
+ k.args = args;
+ k.functions = fns;
+ k.classes = make_tree_vector ();
+
+ /* We previously performed an optimization here by setting
+ NAMESPACES to the current namespace when it was safe. However, DR
+ 164 says that namespaces that were already searched in the first
+ stage of template processing are searched again (potentially
+ picking up later definitions) in the second stage. */
+ k.namespaces = make_tree_vector ();
+
+ /* We used to allow duplicates and let joust discard them, but
+ since the above change for DR 164 we end up with duplicates of
+ all the functions found by unqualified lookup. So keep track
+ of which ones we've seen. */
+ if (fns)
+ {
+ tree ovl;
+ /* We shouldn't be here if lookup found something other than
+ namespace-scope functions. */
+ gcc_assert (DECL_NAMESPACE_SCOPE_P (OVL_CURRENT (fns)));
+ k.fn_set = pointer_set_create ();
+ for (ovl = fns; ovl; ovl = OVL_NEXT (ovl))
+ pointer_set_insert (k.fn_set, OVL_CURRENT (ovl));
+ }
+ else
+ k.fn_set = NULL;
+
+ arg_assoc_args_vec (&k, args);
+
+ fns = k.functions;
+
+ if (fns
+ && !VAR_P (fns)
+ && !is_overloaded_fn (fns))
+ {
+ error ("argument dependent lookup finds %q+D", fns);
+ error (" in call to %qD", name);
+ fns = error_mark_node;
+ }
+
+ release_tree_vector (k.classes);
+ release_tree_vector (k.namespaces);
+ if (k.fn_set)
+ pointer_set_destroy (k.fn_set);
+
+ return fns;
+}
+
+/* Wrapper for lookup_arg_dependent_1. */
+
+tree
+lookup_arg_dependent (tree name, tree fns, vec<tree, va_gc> *args)
+{
+ tree ret;
+ bool subtime;
+ subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = lookup_arg_dependent_1 (name, fns, args);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+
+/* Add namespace to using_directives. Return NULL_TREE if nothing was
+ changed (i.e. there was already a directive), or the fresh
+ TREE_LIST otherwise. */
+
+static tree
+push_using_directive_1 (tree used)
+{
+ tree ud = current_binding_level->using_directives;
+ tree iter, ancestor;
+
+ /* Check if we already have this. */
+ if (purpose_member (used, ud) != NULL_TREE)
+ return NULL_TREE;
+
+ ancestor = namespace_ancestor (current_decl_namespace (), used);
+ ud = current_binding_level->using_directives;
+ ud = tree_cons (used, ancestor, ud);
+ current_binding_level->using_directives = ud;
+
+ /* Recursively add all namespaces used. */
+ for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
+ push_using_directive (TREE_PURPOSE (iter));
+
+ return ud;
+}
+
+/* Wrapper for push_using_directive_1. */
+
+static tree
+push_using_directive (tree used)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = push_using_directive_1 (used);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+/* The type TYPE is being declared. If it is a class template, or a
+ specialization of a class template, do any processing required and
+ perform error-checking. If IS_FRIEND is nonzero, this TYPE is
+ being declared a friend. B is the binding level at which this TYPE
+ should be bound.
+
+ Returns the TYPE_DECL for TYPE, which may have been altered by this
+ processing. */
+
+static tree
+maybe_process_template_type_declaration (tree type, int is_friend,
+ cp_binding_level *b)
+{
+ tree decl = TYPE_NAME (type);
+
+ if (processing_template_parmlist)
+ /* You can't declare a new template type in a template parameter
+ list. But, you can declare a non-template type:
+
+ template <class A*> struct S;
+
+ is a forward-declaration of `A'. */
+ ;
+ else if (b->kind == sk_namespace
+ && current_binding_level->kind != sk_namespace)
+ /* If this new type is being injected into a containing scope,
+ then it's not a template type. */
+ ;
+ else
+ {
+ gcc_assert (MAYBE_CLASS_TYPE_P (type)
+ || TREE_CODE (type) == ENUMERAL_TYPE);
+
+ if (processing_template_decl)
+ {
+ /* This may change after the call to
+ push_template_decl_real, but we want the original value. */
+ tree name = DECL_NAME (decl);
+
+ decl = push_template_decl_real (decl, is_friend);
+ if (decl == error_mark_node)
+ return error_mark_node;
+
+ /* If the current binding level is the binding level for the
+ template parameters (see the comment in
+ begin_template_parm_list) and the enclosing level is a class
+ scope, and we're not looking at a friend, push the
+ declaration of the member class into the class scope. In the
+ friend case, push_template_decl will already have put the
+ friend into global scope, if appropriate. */
+ if (TREE_CODE (type) != ENUMERAL_TYPE
+ && !is_friend && b->kind == sk_template_parms
+ && b->level_chain->kind == sk_class)
+ {
+ finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
+
+ if (!COMPLETE_TYPE_P (current_class_type))
+ {
+ maybe_add_class_template_decl_list (current_class_type,
+ type, /*friend_p=*/0);
+ /* Put this UTD in the table of UTDs for the class. */
+ if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
+ CLASSTYPE_NESTED_UTDS (current_class_type) =
+ binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+
+ binding_table_insert
+ (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
+ }
+ }
+ }
+ }
+
+ return decl;
+}
+
+/* Push a tag name NAME for struct/class/union/enum type TYPE. In case
+ that the NAME is a class template, the tag is processed but not pushed.
+
+ The pushed scope depend on the SCOPE parameter:
+ - When SCOPE is TS_CURRENT, put it into the inner-most non-sk_cleanup
+ scope.
+ - When SCOPE is TS_GLOBAL, put it in the inner-most non-class and
+ non-template-parameter scope. This case is needed for forward
+ declarations.
+ - When SCOPE is TS_WITHIN_ENCLOSING_NON_CLASS, this is similar to
+ TS_GLOBAL case except that names within template-parameter scopes
+ are not pushed at all.
+
+ Returns TYPE upon success and ERROR_MARK_NODE otherwise. */
+
+static tree
+pushtag_1 (tree name, tree type, tag_scope scope)
+{
+ cp_binding_level *b;
+ tree decl;
+
+ b = current_binding_level;
+ while (/* Cleanup scopes are not scopes from the point of view of
+ the language. */
+ b->kind == sk_cleanup
+ /* Neither are function parameter scopes. */
+ || b->kind == sk_function_parms
+ /* Neither are the scopes used to hold template parameters
+ for an explicit specialization. For an ordinary template
+ declaration, these scopes are not scopes from the point of
+ view of the language. */
+ || (b->kind == sk_template_parms
+ && (b->explicit_spec_p || scope == ts_global))
+ || (b->kind == sk_class
+ && (scope != ts_current
+ /* We may be defining a new type in the initializer
+ of a static member variable. We allow this when
+ not pedantic, and it is particularly useful for
+ type punning via an anonymous union. */
+ || COMPLETE_TYPE_P (b->this_entity))))
+ b = b->level_chain;
+
+ gcc_assert (identifier_p (name));
+
+ /* Do C++ gratuitous typedefing. */
+ if (identifier_type_value_1 (name) != type)
+ {
+ tree tdef;
+ int in_class = 0;
+ tree context = TYPE_CONTEXT (type);
+
+ if (! context)
+ {
+ tree cs = current_scope ();
+
+ if (scope == ts_current
+ || (cs && TREE_CODE (cs) == FUNCTION_DECL))
+ context = cs;
+ else if (cs != NULL_TREE && TYPE_P (cs))
+ /* When declaring a friend class of a local class, we want
+ to inject the newly named class into the scope
+ containing the local class, not the namespace
+ scope. */
+ context = decl_function_context (get_type_decl (cs));
+ }
+ if (!context)
+ context = current_namespace;
+
+ if (b->kind == sk_class
+ || (b->kind == sk_template_parms
+ && b->level_chain->kind == sk_class))
+ in_class = 1;
+
+ if (current_lang_name == lang_name_java)
+ TYPE_FOR_JAVA (type) = 1;
+
+ tdef = create_implicit_typedef (name, type);
+ DECL_CONTEXT (tdef) = FROB_CONTEXT (context);
+ if (scope == ts_within_enclosing_non_class)
+ {
+ /* This is a friend. Make this TYPE_DECL node hidden from
+ ordinary name lookup. Its corresponding TEMPLATE_DECL
+ will be marked in push_template_decl_real. */
+ retrofit_lang_decl (tdef);
+ DECL_ANTICIPATED (tdef) = 1;
+ DECL_FRIEND_P (tdef) = 1;
+ }
+
+ decl = maybe_process_template_type_declaration
+ (type, scope == ts_within_enclosing_non_class, b);
+ if (decl == error_mark_node)
+ return decl;
+
+ if (b->kind == sk_class)
+ {
+ if (!TYPE_BEING_DEFINED (current_class_type))
+ return error_mark_node;
+
+ if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
+ /* Put this TYPE_DECL on the TYPE_FIELDS list for the
+ class. But if it's a member template class, we want
+ the TEMPLATE_DECL, not the TYPE_DECL, so this is done
+ later. */
+ finish_member_declaration (decl);
+ else
+ pushdecl_class_level (decl);
+ }
+ else if (b->kind != sk_template_parms)
+ {
+ decl = pushdecl_with_scope_1 (decl, b, /*is_friend=*/false);
+ if (decl == error_mark_node)
+ return decl;
+ }
+
+ if (! in_class)
+ set_identifier_type_value_with_scope (name, tdef, b);
+
+ TYPE_CONTEXT (type) = DECL_CONTEXT (decl);
+
+ /* If this is a local class, keep track of it. We need this
+ information for name-mangling, and so that it is possible to
+ find all function definitions in a translation unit in a
+ convenient way. (It's otherwise tricky to find a member
+ function definition it's only pointed to from within a local
+ class.) */
+ if (TYPE_FUNCTION_SCOPE_P (type))
+ {
+ if (processing_template_decl)
+ {
+ /* Push a DECL_EXPR so we call pushtag at the right time in
+ template instantiation rather than in some nested context. */
+ add_decl_expr (decl);
+ }
+ else
+ vec_safe_push (local_classes, type);
+ }
+ }
+ if (b->kind == sk_class
+ && !COMPLETE_TYPE_P (current_class_type))
+ {
+ maybe_add_class_template_decl_list (current_class_type,
+ type, /*friend_p=*/0);
+
+ if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
+ CLASSTYPE_NESTED_UTDS (current_class_type)
+ = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+
+ binding_table_insert
+ (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
+ }
+
+ decl = TYPE_NAME (type);
+ gcc_assert (TREE_CODE (decl) == TYPE_DECL);
+
+ /* Set type visibility now if this is a forward declaration. */
+ TREE_PUBLIC (decl) = 1;
+ determine_visibility (decl);
+
+ return type;
+}
+
+/* Wrapper for pushtag_1. */
+
+tree
+pushtag (tree name, tree type, tag_scope scope)
+{
+ tree ret;
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ ret = pushtag_1 (name, type, scope);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+ return ret;
+}
+
+/* Subroutines for reverting temporarily to top-level for instantiation
+ of templates and such. We actually need to clear out the class- and
+ local-value slots of all identifiers, so that only the global values
+ are at all visible. Simply setting current_binding_level to the global
+ scope isn't enough, because more binding levels may be pushed. */
+struct saved_scope *scope_chain;
+
+/* Return true if ID has not already been marked. */
+
+static inline bool
+store_binding_p (tree id)
+{
+ if (!id || !IDENTIFIER_BINDING (id))
+ return false;
+
+ if (IDENTIFIER_MARKED (id))
+ return false;
+
+ return true;
+}
+
+/* Add an appropriate binding to *OLD_BINDINGS which needs to already
+ have enough space reserved. */
+
+static void
+store_binding (tree id, vec<cxx_saved_binding, va_gc> **old_bindings)
+{
+ cxx_saved_binding saved;
+
+ gcc_checking_assert (store_binding_p (id));
+
+ IDENTIFIER_MARKED (id) = 1;
+
+ saved.identifier = id;
+ saved.binding = IDENTIFIER_BINDING (id);
+ saved.real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
+ (*old_bindings)->quick_push (saved);
+ IDENTIFIER_BINDING (id) = NULL;
+}
+
+static void
+store_bindings (tree names, vec<cxx_saved_binding, va_gc> **old_bindings)
+{
+ static vec<tree> bindings_need_stored = vNULL;
+ tree t, id;
+ size_t i;
+
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ for (t = names; t; t = TREE_CHAIN (t))
+ {
+ if (TREE_CODE (t) == TREE_LIST)
+ id = TREE_PURPOSE (t);
+ else
+ id = DECL_NAME (t);
+
+ if (store_binding_p (id))
+ bindings_need_stored.safe_push (id);
+ }
+ if (!bindings_need_stored.is_empty ())
+ {
+ vec_safe_reserve_exact (*old_bindings, bindings_need_stored.length ());
+ for (i = 0; bindings_need_stored.iterate (i, &id); ++i)
+ {
+ /* We can appearantly have duplicates in NAMES. */
+ if (store_binding_p (id))
+ store_binding (id, old_bindings);
+ }
+ bindings_need_stored.truncate (0);
+ }
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+}
+
+/* Like store_bindings, but NAMES is a vector of cp_class_binding
+ objects, rather than a TREE_LIST. */
+
+static void
+store_class_bindings (vec<cp_class_binding, va_gc> *names,
+ vec<cxx_saved_binding, va_gc> **old_bindings)
+{
+ static vec<tree> bindings_need_stored = vNULL;
+ size_t i;
+ cp_class_binding *cb;
+
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ for (i = 0; vec_safe_iterate (names, i, &cb); ++i)
+ if (store_binding_p (cb->identifier))
+ bindings_need_stored.safe_push (cb->identifier);
+ if (!bindings_need_stored.is_empty ())
+ {
+ tree id;
+ vec_safe_reserve_exact (*old_bindings, bindings_need_stored.length ());
+ for (i = 0; bindings_need_stored.iterate (i, &id); ++i)
+ store_binding (id, old_bindings);
+ bindings_need_stored.truncate (0);
+ }
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+}
+
+void
+push_to_top_level (void)
+{
+ struct saved_scope *s;
+ cp_binding_level *b;
+ cxx_saved_binding *sb;
+ size_t i;
+ bool need_pop;
+
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ s = ggc_alloc_cleared_saved_scope ();
+
+ b = scope_chain ? current_binding_level : 0;
+
+ /* If we're in the middle of some function, save our state. */
+ if (cfun)
+ {
+ need_pop = true;
+ push_function_context ();
+ }
+ else
+ need_pop = false;
+
+ if (scope_chain && previous_class_level)
+ store_class_bindings (previous_class_level->class_shadowed,
+ &s->old_bindings);
+
+ /* Have to include the global scope, because class-scope decls
+ aren't listed anywhere useful. */
+ for (; b; b = b->level_chain)
+ {
+ tree t;
+
+ /* Template IDs are inserted into the global level. If they were
+ inserted into namespace level, finish_file wouldn't find them
+ when doing pending instantiations. Therefore, don't stop at
+ namespace level, but continue until :: . */
+ if (global_scope_p (b))
+ break;
+
+ store_bindings (b->names, &s->old_bindings);
+ /* We also need to check class_shadowed to save class-level type
+ bindings, since pushclass doesn't fill in b->names. */
+ if (b->kind == sk_class)
+ store_class_bindings (b->class_shadowed, &s->old_bindings);
+
+ /* Unwind type-value slots back to top level. */
+ for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
+ SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));
+ }
+
+ FOR_EACH_VEC_SAFE_ELT (s->old_bindings, i, sb)
+ IDENTIFIER_MARKED (sb->identifier) = 0;
+
+ s->prev = scope_chain;
+ s->bindings = b;
+ s->need_pop_function_context = need_pop;
+ s->function_decl = current_function_decl;
+ s->unevaluated_operand = cp_unevaluated_operand;
+ s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+ s->x_stmt_tree.stmts_are_full_exprs_p = true;
+
+ scope_chain = s;
+ current_function_decl = NULL_TREE;
+ vec_alloc (current_lang_base, 10);
+ current_lang_name = lang_name_cplusplus;
+ current_namespace = global_namespace;
+ push_class_stack ();
+ cp_unevaluated_operand = 0;
+ c_inhibit_evaluation_warnings = 0;
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+}
+
+static void
+pop_from_top_level_1 (void)
+{
+ struct saved_scope *s = scope_chain;
+ cxx_saved_binding *saved;
+ size_t i;
+
+ /* Clear out class-level bindings cache. */
+ if (previous_class_level)
+ invalidate_class_lookup_cache ();
+ pop_class_stack ();
+
+ current_lang_base = 0;
+
+ scope_chain = s->prev;
+ FOR_EACH_VEC_SAFE_ELT (s->old_bindings, i, saved)
+ {
+ tree id = saved->identifier;
+
+ IDENTIFIER_BINDING (id) = saved->binding;
+ SET_IDENTIFIER_TYPE_VALUE (id, saved->real_type_value);
+ }
+
+ /* If we were in the middle of compiling a function, restore our
+ state. */
+ if (s->need_pop_function_context)
+ pop_function_context ();
+ current_function_decl = s->function_decl;
+ cp_unevaluated_operand = s->unevaluated_operand;
+ c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings;
+}
+
+/* Wrapper for pop_from_top_level_1. */
+
+void
+pop_from_top_level (void)
+{
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ pop_from_top_level_1 ();
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+}
+
+
+/* Pop off extraneous binding levels left over due to syntax errors.
+
+ We don't pop past namespaces, as they might be valid. */
+
+void
+pop_everything (void)
+{
+ if (ENABLE_SCOPE_CHECKING)
+ verbatim ("XXX entering pop_everything ()\n");
+ while (!toplevel_bindings_p ())
+ {
+ if (current_binding_level->kind == sk_class)
+ pop_nested_class ();
+ else
+ poplevel (0, 0, 0);
+ }
+ if (ENABLE_SCOPE_CHECKING)
+ verbatim ("XXX leaving pop_everything ()\n");
+}
+
+/* Emit debugging information for using declarations and directives.
+ If input tree is overloaded fn then emit debug info for all
+ candidates. */
+
+void
+cp_emit_debug_info_for_using (tree t, tree context)
+{
+ /* Don't try to emit any debug information if we have errors. */
+ if (seen_error ())
+ return;
+
+ /* Ignore this FUNCTION_DECL if it refers to a builtin declaration
+ of a builtin function. */
+ if (TREE_CODE (t) == FUNCTION_DECL
+ && DECL_EXTERNAL (t)
+ && DECL_BUILT_IN (t))
+ return;
+
+ /* Do not supply context to imported_module_or_decl, if
+ it is a global namespace. */
+ if (context == global_namespace)
+ context = NULL_TREE;
+
+ if (BASELINK_P (t))
+ t = BASELINK_FUNCTIONS (t);
+
+ /* FIXME: Handle TEMPLATE_DECLs. */
+ for (t = OVL_CURRENT (t); t; t = OVL_NEXT (t))
+ if (TREE_CODE (t) != TEMPLATE_DECL)
+ {
+ if (building_stmt_list_p ())
+ add_stmt (build_stmt (input_location, USING_STMT, t));
+ else
+ (*debug_hooks->imported_module_or_decl) (t, NULL_TREE, context, false);
+ }
+}
+
+#include "gt-cp-name-lookup.h"
diff --git a/gcc-4.9/gcc/cp/name-lookup.h b/gcc-4.9/gcc/cp/name-lookup.h
new file mode 100644
index 000000000..a63442f85
--- /dev/null
+++ b/gcc-4.9/gcc/cp/name-lookup.h
@@ -0,0 +1,370 @@
+/* Declarations for C++ name lookup routines.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_CP_NAME_LOOKUP_H
+#define GCC_CP_NAME_LOOKUP_H
+
+#include "c-family/c-common.h"
+
+/* The type of dictionary used to map names to types declared at
+ a given scope. */
+typedef struct binding_table_s *binding_table;
+typedef struct binding_entry_s *binding_entry;
+
+/* The type of a routine repeatedly called by binding_table_foreach. */
+typedef void (*bt_foreach_proc) (binding_entry, void *);
+
+struct GTY(()) binding_entry_s {
+ binding_entry chain;
+ tree name;
+ tree type;
+};
+
+/* These macros indicate the initial chains count for binding_table. */
+#define SCOPE_DEFAULT_HT_SIZE (1 << 3)
+#define CLASS_SCOPE_HT_SIZE (1 << 3)
+#define NAMESPACE_ORDINARY_HT_SIZE (1 << 5)
+#define NAMESPACE_STD_HT_SIZE (1 << 8)
+#define GLOBAL_SCOPE_HT_SIZE (1 << 8)
+
+extern void binding_table_foreach (binding_table, bt_foreach_proc, void *);
+extern binding_entry binding_table_find (binding_table, tree);
+
+/* Datatype that represents binding established by a declaration between
+ a name and a C++ entity. */
+typedef struct cxx_binding cxx_binding;
+
+/* The datatype used to implement C++ scope. */
+typedef struct cp_binding_level cp_binding_level;
+
+/* Nonzero if this binding is for a local scope, as opposed to a class
+ or namespace scope. */
+#define LOCAL_BINDING_P(NODE) ((NODE)->is_local)
+
+/* True if NODE->value is from a base class of the class which is
+ currently being defined. */
+#define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited)
+
+struct GTY(()) cxx_binding {
+ /* Link to chain together various bindings for this name. */
+ cxx_binding *previous;
+ /* The non-type entity this name is bound to. */
+ tree value;
+ /* The type entity this name is bound to. */
+ tree type;
+ /* The scope at which this binding was made. */
+ cp_binding_level *scope;
+ unsigned value_is_inherited : 1;
+ unsigned is_local : 1;
+};
+
+/* Datatype used to temporarily save C++ bindings (for implicit
+ instantiations purposes and like). Implemented in decl.c. */
+typedef struct GTY(()) cxx_saved_binding {
+ /* The name of the current binding. */
+ tree identifier;
+ /* The binding we're saving. */
+ cxx_binding *binding;
+ tree real_type_value;
+} cxx_saved_binding;
+
+
+extern tree identifier_type_value (tree);
+extern void set_identifier_type_value (tree, tree);
+extern void pop_binding (tree, tree);
+extern void pop_bindings_and_leave_scope (void);
+extern tree constructor_name (tree);
+extern bool constructor_name_p (tree, tree);
+
+/* The kinds of scopes we recognize. */
+typedef enum scope_kind {
+ sk_block = 0, /* An ordinary block scope. This enumerator must
+ have the value zero because "cp_binding_level"
+ is initialized by using "memset" to set the
+ contents to zero, and the default scope kind
+ is "sk_block". */
+ sk_cleanup, /* A scope for (pseudo-)scope for cleanup. It is
+ pseudo in that it is transparent to name lookup
+ activities. */
+ sk_try, /* A try-block. */
+ sk_catch, /* A catch-block. */
+ sk_for, /* The scope of the variable declared in a
+ for-init-statement. */
+ sk_cond, /* The scope of the variable declared in the condition
+ of an if or switch statement. */
+ sk_function_parms, /* The scope containing function parameters. */
+ sk_class, /* The scope containing the members of a class. */
+ sk_scoped_enum, /* The scope containing the enumertors of a C++0x
+ scoped enumeration. */
+ sk_namespace, /* The scope containing the members of a
+ namespace, including the global scope. */
+ sk_template_parms, /* A scope for template parameters. */
+ sk_template_spec, /* Like sk_template_parms, but for an explicit
+ specialization. Since, by definition, an
+ explicit specialization is introduced by
+ "template <>", this scope is always empty. */
+ sk_omp /* An OpenMP structured block. */
+} scope_kind;
+
+/* The scope where the class/struct/union/enum tag applies. */
+typedef enum tag_scope {
+ ts_current = 0, /* Current scope only. This is for the
+ class-key identifier;
+ case mentioned in [basic.lookup.elab]/2,
+ or the class/enum definition
+ class-key identifier { ... }; */
+ ts_global = 1, /* All scopes. This is the 3.4.1
+ [basic.lookup.unqual] lookup mentioned
+ in [basic.lookup.elab]/2. */
+ ts_within_enclosing_non_class = 2, /* Search within enclosing non-class
+ only, for friend class lookup
+ according to [namespace.memdef]/3
+ and [class.friend]/9. */
+ ts_lambda = 3 /* Declaring a lambda closure. */
+} tag_scope;
+
+typedef struct GTY(()) cp_class_binding {
+ cxx_binding *base;
+ /* The bound name. */
+ tree identifier;
+} cp_class_binding;
+
+
+typedef struct GTY(()) cp_label_binding {
+ /* The bound LABEL_DECL. */
+ tree label;
+ /* The previous IDENTIFIER_LABEL_VALUE. */
+ tree prev_value;
+} cp_label_binding;
+
+
+/* For each binding contour we allocate a binding_level structure
+ which records the names defined in that contour.
+ Contours include:
+ 0) the global one
+ 1) one for each function definition,
+ where internal declarations of the parameters appear.
+ 2) one for each compound statement,
+ to record its declarations.
+
+ The current meaning of a name can be found by searching the levels
+ from the current one out to the global one.
+
+ Off to the side, may be the class_binding_level. This exists only
+ to catch class-local declarations. It is otherwise nonexistent.
+
+ Also there may be binding levels that catch cleanups that must be
+ run when exceptions occur. Thus, to see whether a name is bound in
+ the current scope, it is not enough to look in the
+ CURRENT_BINDING_LEVEL. You should use lookup_name_current_level
+ instead. */
+
+/* Note that the information in the `names' component of the global contour
+ is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
+
+struct GTY(()) cp_binding_level {
+ /* A chain of _DECL nodes for all variables, constants, functions,
+ and typedef types. These are in the reverse of the order
+ supplied. There may be OVERLOADs on this list, too, but they
+ are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */
+ tree names;
+
+ /* A chain of NAMESPACE_DECL nodes. */
+ tree namespaces;
+
+ /* An array of static functions and variables (for namespaces only) */
+ vec<tree, va_gc> *static_decls;
+
+ /* A list of USING_DECL nodes. */
+ tree usings;
+
+ /* A list of used namespaces. PURPOSE is the namespace,
+ VALUE the common ancestor with this binding_level's namespace. */
+ tree using_directives;
+
+ /* For the binding level corresponding to a class, the entities
+ declared in the class or its base classes. */
+ vec<cp_class_binding, va_gc> *class_shadowed;
+
+ /* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
+ is used for all binding levels. The TREE_PURPOSE is the name of
+ the entity, the TREE_TYPE is the associated type. In addition
+ the TREE_VALUE is the IDENTIFIER_TYPE_VALUE before we entered
+ the class. */
+ tree type_shadowed;
+
+ /* Similar to class_shadowed, but for IDENTIFIER_LABEL_VALUE, and
+ used for all binding levels. */
+ vec<cp_label_binding, va_gc> *shadowed_labels;
+
+ /* For each level (except not the global one),
+ a chain of BLOCK nodes for all the levels
+ that were entered and exited one level down. */
+ tree blocks;
+
+ /* The entity (namespace, class, function) the scope of which this
+ binding contour corresponds to. Otherwise NULL. */
+ tree this_entity;
+
+ /* The binding level which this one is contained in (inherits from). */
+ cp_binding_level *level_chain;
+
+ /* List of VAR_DECLS saved from a previous for statement.
+ These would be dead in ISO-conforming code, but might
+ be referenced in ARM-era code. */
+ vec<tree, va_gc> *dead_vars_from_for;
+
+ /* STATEMENT_LIST for statements in this binding contour.
+ Only used at present for SK_CLEANUP temporary bindings. */
+ tree statement_list;
+
+ /* Binding depth at which this level began. */
+ int binding_depth;
+
+ /* The kind of scope that this object represents. However, a
+ SK_TEMPLATE_SPEC scope is represented with KIND set to
+ SK_TEMPLATE_PARMS and EXPLICIT_SPEC_P set to true. */
+ ENUM_BITFIELD (scope_kind) kind : 4;
+
+ /* True if this scope is an SK_TEMPLATE_SPEC scope. This field is
+ only valid if KIND == SK_TEMPLATE_PARMS. */
+ BOOL_BITFIELD explicit_spec_p : 1;
+
+ /* true means make a BLOCK for this level regardless of all else. */
+ unsigned keep : 1;
+
+ /* Nonzero if this level can safely have additional
+ cleanup-needing variables added to it. */
+ unsigned more_cleanups_ok : 1;
+ unsigned have_cleanups : 1;
+
+ /* 24 bits left to fill a 32-bit word. */
+};
+
+/* The binding level currently in effect. */
+
+#define current_binding_level \
+ (*(cfun && cp_function_chain && cp_function_chain->bindings \
+ ? &cp_function_chain->bindings \
+ : &scope_chain->bindings))
+
+/* The binding level of the current class, if any. */
+
+#define class_binding_level scope_chain->class_bindings
+
+/* The tree node representing the global scope. */
+extern GTY(()) tree global_namespace;
+extern GTY(()) tree global_scope_name;
+
+/* Indicates that there is a type value in some namespace, although
+ that is not necessarily in scope at the moment. */
+
+extern GTY(()) tree global_type_node;
+
+/* True if SCOPE designates the global scope binding contour. */
+#define global_scope_p(SCOPE) \
+ ((SCOPE) == NAMESPACE_LEVEL (global_namespace))
+
+extern cp_binding_level *leave_scope (void);
+extern bool kept_level_p (void);
+extern bool global_bindings_p (void);
+extern bool toplevel_bindings_p (void);
+extern bool namespace_bindings_p (void);
+extern bool local_bindings_p (void);
+extern bool template_parm_scope_p (void);
+extern scope_kind innermost_scope_kind (void);
+extern cp_binding_level *begin_scope (scope_kind, tree);
+extern void print_binding_stack (void);
+extern void push_to_top_level (void);
+extern void pop_from_top_level (void);
+extern void pop_everything (void);
+extern void keep_next_level (bool);
+extern bool is_ancestor (tree, tree);
+extern tree push_scope (tree);
+extern void pop_scope (tree);
+extern tree push_inner_scope (tree);
+extern void pop_inner_scope (tree, tree);
+extern void push_binding_level (cp_binding_level *);
+
+extern void push_namespace (tree);
+extern void pop_namespace (void);
+extern void push_nested_namespace (tree);
+extern void pop_nested_namespace (tree);
+extern bool handle_namespace_attrs (tree, tree);
+extern void pushlevel_class (void);
+extern void poplevel_class (void);
+extern tree pushdecl_with_scope (tree, cp_binding_level *, bool);
+extern tree lookup_name_prefer_type (tree, int);
+extern tree lookup_name_real (tree, int, int, bool, int, int);
+extern tree lookup_type_scope (tree, tag_scope);
+extern tree namespace_binding (tree, tree);
+extern void set_namespace_binding (tree, tree, tree);
+extern bool hidden_name_p (tree);
+extern tree remove_hidden_names (tree);
+extern tree lookup_qualified_name (tree, tree, bool, bool);
+extern tree lookup_name_nonclass (tree);
+extern tree lookup_name_innermost_nonclass_level (tree);
+extern bool is_local_extern (tree);
+extern tree lookup_function_nonclass (tree, vec<tree, va_gc> *, bool);
+extern void push_local_binding (tree, tree, int);
+extern bool pushdecl_class_level (tree);
+extern tree pushdecl_namespace_level (tree, bool);
+extern bool push_class_level_binding (tree, tree);
+extern tree getdecls (void);
+extern int function_parm_depth (void);
+extern tree cp_namespace_decls (tree);
+extern void set_decl_namespace (tree, tree, bool);
+extern void push_decl_namespace (tree);
+extern void pop_decl_namespace (void);
+extern void do_namespace_alias (tree, tree);
+extern void do_toplevel_using_decl (tree, tree, tree);
+extern void do_local_using_decl (tree, tree, tree);
+extern tree do_class_using_decl (tree, tree);
+extern void do_using_directive (tree);
+extern tree lookup_arg_dependent (tree, tree, vec<tree, va_gc> *);
+extern bool is_associated_namespace (tree, tree);
+extern void parse_using_directive (tree, tree);
+extern tree innermost_non_namespace_value (tree);
+extern cxx_binding *outer_binding (tree, cxx_binding *, bool);
+extern void cp_emit_debug_info_for_using (tree, tree);
+
+/* Set *DECL to the (non-hidden) declaration for ID at global scope,
+ if present and return true; otherwise return false. */
+
+inline bool
+get_global_value_if_present (tree id, tree *decl)
+{
+ tree global_value = namespace_binding (id, global_namespace);
+ if (global_value)
+ *decl = global_value;
+ return global_value != NULL;
+}
+
+/* True is the binding of IDENTIFIER at global scope names a type. */
+
+inline bool
+is_typename_at_global_scope (tree id)
+{
+ tree global_value = namespace_binding (id, global_namespace);
+
+ return global_value && TREE_CODE (global_value) == TYPE_DECL;
+}
+
+#endif /* GCC_CP_NAME_LOOKUP_H */
diff --git a/gcc-4.9/gcc/cp/operators.def b/gcc-4.9/gcc/cp/operators.def
new file mode 100644
index 000000000..ee6555b60
--- /dev/null
+++ b/gcc-4.9/gcc/cp/operators.def
@@ -0,0 +1,157 @@
+/* -*-C-*-
+
+ This file contains definitions of the various C++ operators,
+ including both overloadable operators (like `+') and
+ non-overloadable operators (like the `?:' ternary operator).
+ Written by Mark Mitchell <mark@codesourcery.com>
+
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* The DEF_OPERATOR macro takes the following arguments:
+
+ NAME
+
+ The name of the operator, as a C string, but without the
+ preceding `operator'. This is the name that would be given in
+ the source program. For `operator +', for example, this would be
+ `+'.
+
+ CODE
+
+ The tree_code for this operator. For `operator +', for example,
+ this would be PLUS_EXPR. Because there are no tree codes for
+ assignment operators, the same tree-codes are reused; i.e.,
+ `operator +' will also have PLUS_EXPR as its CODE.
+
+ MANGLING
+
+ The mangling prefix for the operator, as a C string, and as
+ mangled under the new ABI. For `operator +', for example, this
+ would be "pl".
+
+ ARITY
+
+ The arity of the operator, or -1 if any arity is allowed. (As
+ for `operator ()'.) Postincrement and postdecrement operators
+ are marked as binary.
+
+ ASSN_P
+
+ A boolean value. If nonzero, this is an assignment operator.
+
+ Before including this file, you should define DEF_OPERATOR
+ to take these arguments.
+
+ There is code (such as in grok_op_properties) that depends on the
+ order the operators are presented in this file. In particular,
+ unary operators must precede binary operators. */
+
+/* Use DEF_SIMPLE_OPERATOR to define a non-assignment operator. Its
+ arguments are as for DEF_OPERATOR, but there is no need to provide
+ an ASSIGNMENT_P argument; it is always zero. */
+
+#define DEF_SIMPLE_OPERATOR(NAME, CODE, MANGLING, ARITY) \
+ DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, 0)
+
+/* Use DEF_ASSN_OPERATOR to define an assignment operator. Its
+ arguments are as for DEF_OPERATOR, but there is no need to provide
+ an ASSIGNMENT_P argument; it is always one. */
+
+#define DEF_ASSN_OPERATOR(NAME, CODE, MANGLING, ARITY) \
+ DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, 1)
+
+/* Memory allocation operators. */
+DEF_SIMPLE_OPERATOR ("new", NEW_EXPR, "nw", -1)
+DEF_SIMPLE_OPERATOR ("new []", VEC_NEW_EXPR, "na", -1)
+DEF_SIMPLE_OPERATOR ("delete", DELETE_EXPR, "dl", -1)
+DEF_SIMPLE_OPERATOR ("delete []", VEC_DELETE_EXPR, "da", -1)
+
+/* Unary operators. */
+DEF_SIMPLE_OPERATOR ("+", UNARY_PLUS_EXPR, "ps", 1)
+DEF_SIMPLE_OPERATOR ("-", NEGATE_EXPR, "ng", 1)
+DEF_SIMPLE_OPERATOR ("&", ADDR_EXPR, "ad", 1)
+DEF_SIMPLE_OPERATOR ("*", INDIRECT_REF, "de", 1)
+DEF_SIMPLE_OPERATOR ("~", BIT_NOT_EXPR, "co", 1)
+DEF_SIMPLE_OPERATOR ("!", TRUTH_NOT_EXPR, "nt", 1)
+DEF_SIMPLE_OPERATOR ("++", PREINCREMENT_EXPR, "pp", 1)
+DEF_SIMPLE_OPERATOR ("--", PREDECREMENT_EXPR, "mm", 1)
+DEF_SIMPLE_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", 1)
+/* These are extensions. */
+DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "az", 1)
+DEF_SIMPLE_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", 1)
+DEF_SIMPLE_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", 1)
+
+/* The cast operator. */
+DEF_SIMPLE_OPERATOR ("", TYPE_EXPR, "cv", 1)
+DEF_SIMPLE_OPERATOR ("", CAST_EXPR, "cv", 1)
+DEF_SIMPLE_OPERATOR ("dynamic_cast", DYNAMIC_CAST_EXPR, "dc", 1)
+DEF_SIMPLE_OPERATOR ("reinterpret_cast", REINTERPRET_CAST_EXPR, "rc", 1)
+DEF_SIMPLE_OPERATOR ("const_cast", CONST_CAST_EXPR, "cc", 1)
+DEF_SIMPLE_OPERATOR ("static_cast", STATIC_CAST_EXPR, "sc", 1)
+
+/* Binary operators. */
+DEF_SIMPLE_OPERATOR ("+", PLUS_EXPR, "pl", 2)
+DEF_SIMPLE_OPERATOR ("-", MINUS_EXPR, "mi", 2)
+DEF_SIMPLE_OPERATOR ("*", MULT_EXPR, "ml", 2)
+DEF_SIMPLE_OPERATOR ("/", TRUNC_DIV_EXPR, "dv", 2)
+DEF_SIMPLE_OPERATOR ("%", TRUNC_MOD_EXPR, "rm", 2)
+DEF_SIMPLE_OPERATOR ("&", BIT_AND_EXPR, "an", 2)
+DEF_SIMPLE_OPERATOR ("|", BIT_IOR_EXPR, "or", 2)
+DEF_SIMPLE_OPERATOR ("^", BIT_XOR_EXPR, "eo", 2)
+DEF_SIMPLE_OPERATOR ("<<", LSHIFT_EXPR, "ls", 2)
+DEF_SIMPLE_OPERATOR (">>", RSHIFT_EXPR, "rs", 2)
+DEF_SIMPLE_OPERATOR ("==", EQ_EXPR, "eq", 2)
+DEF_SIMPLE_OPERATOR ("!=", NE_EXPR, "ne", 2)
+DEF_SIMPLE_OPERATOR ("<", LT_EXPR, "lt", 2)
+DEF_SIMPLE_OPERATOR (">", GT_EXPR, "gt", 2)
+DEF_SIMPLE_OPERATOR ("<=", LE_EXPR, "le", 2)
+DEF_SIMPLE_OPERATOR (">=", GE_EXPR, "ge", 2)
+DEF_SIMPLE_OPERATOR ("&&", TRUTH_ANDIF_EXPR, "aa", 2)
+DEF_SIMPLE_OPERATOR ("||", TRUTH_ORIF_EXPR, "oo", 2)
+DEF_SIMPLE_OPERATOR (",", COMPOUND_EXPR, "cm", 2)
+DEF_SIMPLE_OPERATOR ("->*", MEMBER_REF, "pm", 2)
+DEF_SIMPLE_OPERATOR (".*", DOTSTAR_EXPR, "ds", 2)
+DEF_SIMPLE_OPERATOR ("->", COMPONENT_REF, "pt", 2)
+DEF_SIMPLE_OPERATOR ("[]", ARRAY_REF, "ix", 2)
+DEF_SIMPLE_OPERATOR ("++", POSTINCREMENT_EXPR, "pp", 2)
+DEF_SIMPLE_OPERATOR ("--", POSTDECREMENT_EXPR, "mm", 2)
+/* This one is needed for mangling. */
+DEF_SIMPLE_OPERATOR ("::", SCOPE_REF, "sr", 2)
+
+/* Assignment operators. */
+DEF_ASSN_OPERATOR ("=", NOP_EXPR, "aS", 2)
+DEF_ASSN_OPERATOR ("+=", PLUS_EXPR, "pL", 2)
+DEF_ASSN_OPERATOR ("-=", MINUS_EXPR, "mI", 2)
+DEF_ASSN_OPERATOR ("*=", MULT_EXPR, "mL", 2)
+DEF_ASSN_OPERATOR ("/=", TRUNC_DIV_EXPR, "dV", 2)
+DEF_ASSN_OPERATOR ("%=", TRUNC_MOD_EXPR, "rM", 2)
+DEF_ASSN_OPERATOR ("&=", BIT_AND_EXPR, "aN", 2)
+DEF_ASSN_OPERATOR ("|=", BIT_IOR_EXPR, "oR", 2)
+DEF_ASSN_OPERATOR ("^=", BIT_XOR_EXPR, "eO", 2)
+DEF_ASSN_OPERATOR ("<<=", LSHIFT_EXPR, "lS", 2)
+DEF_ASSN_OPERATOR (">>=", RSHIFT_EXPR, "rS", 2)
+
+/* Ternary operators. */
+DEF_SIMPLE_OPERATOR ("?:", COND_EXPR, "qu", 3)
+
+/* Miscellaneous. */
+DEF_SIMPLE_OPERATOR ("()", CALL_EXPR, "cl", -1)
+
+/* Variadic templates extension. */
+DEF_SIMPLE_OPERATOR ("...", EXPR_PACK_EXPANSION, "sp", 1)
diff --git a/gcc-4.9/gcc/cp/optimize.c b/gcc-4.9/gcc/cp/optimize.c
new file mode 100644
index 000000000..b089432a3
--- /dev/null
+++ b/gcc-4.9/gcc/cp/optimize.c
@@ -0,0 +1,661 @@
+/* Perform optimizations on tree structure.
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
+ Written by Mark Michell (mark@codesourcery.com).
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "cp-tree.h"
+#include "input.h"
+#include "params.h"
+#include "hashtab.h"
+#include "target.h"
+#include "debug.h"
+#include "tree-inline.h"
+#include "flags.h"
+#include "langhooks.h"
+#include "diagnostic-core.h"
+#include "dumpfile.h"
+#include "pointer-set.h"
+#include "tree-iterator.h"
+#include "cgraph.h"
+
+/* Prototypes. */
+
+static void update_cloned_parm (tree, tree, bool);
+
+/* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
+ or destructor. Update it to ensure that the source-position for
+ the cloned parameter matches that for the original, and that the
+ debugging generation code will be able to find the original PARM. */
+
+static void
+update_cloned_parm (tree parm, tree cloned_parm, bool first)
+{
+ DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
+
+ /* We may have taken its address. */
+ TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
+
+ /* The definition might have different constness. */
+ TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
+
+ TREE_USED (cloned_parm) = !first || TREE_USED (parm);
+
+ /* The name may have changed from the declaration. */
+ DECL_NAME (cloned_parm) = DECL_NAME (parm);
+ DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
+ TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
+
+ DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
+}
+
+
+/* FN is a function in High GIMPLE form that has a complete body and no
+ CFG. CLONE is a function whose body is to be set to a copy of FN,
+ mapping argument declarations according to the ARG_MAP splay_tree. */
+
+static void
+clone_body (tree clone, tree fn, void *arg_map)
+{
+ copy_body_data id;
+ tree stmts;
+
+ /* Clone the body, as if we were making an inline call. But, remap
+ the parameters in the callee to the parameters of caller. */
+ memset (&id, 0, sizeof (id));
+ id.src_fn = fn;
+ id.dst_fn = clone;
+ id.src_cfun = DECL_STRUCT_FUNCTION (fn);
+ id.decl_map = (struct pointer_map_t *) arg_map;
+
+ id.copy_decl = copy_decl_no_change;
+ id.transform_call_graph_edges = CB_CGE_DUPLICATE;
+ id.transform_new_cfg = true;
+ id.transform_return_to_modify = false;
+ id.transform_lang_insert_block = NULL;
+
+ /* We're not inside any EH region. */
+ id.eh_lp_nr = 0;
+
+ stmts = DECL_SAVED_TREE (fn);
+ walk_tree (&stmts, copy_tree_body_r, &id, NULL);
+
+ /* Also remap the initializer of any static variables so that they (in
+ particular, any label addresses) correspond to the base variant rather
+ than the abstract one. */
+ if (DECL_NAME (clone) == base_dtor_identifier
+ || DECL_NAME (clone) == base_ctor_identifier)
+ {
+ unsigned ix;
+ tree decl;
+
+ FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
+ walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
+ }
+
+ append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
+}
+
+/* DELETE_DTOR is a delete destructor whose body will be built.
+ COMPLETE_DTOR is the corresponding complete destructor. */
+
+static void
+build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
+{
+ tree call_dtor, call_delete;
+ tree parm = DECL_ARGUMENTS (delete_dtor);
+ tree virtual_size = cxx_sizeof (current_class_type);
+
+ /* Call the corresponding complete destructor. */
+ gcc_assert (complete_dtor);
+ call_dtor = build_cxx_call (complete_dtor, 1, &parm,
+ tf_warning_or_error);
+ add_stmt (call_dtor);
+
+ add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
+
+ /* Call the delete function. */
+ call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
+ virtual_size,
+ /*global_p=*/false,
+ /*placement=*/NULL_TREE,
+ /*alloc_fn=*/NULL_TREE,
+ tf_warning_or_error);
+ add_stmt (call_delete);
+
+ /* Return the address of the object. */
+ if (targetm.cxx.cdtor_returns_this ())
+ {
+ tree val = DECL_ARGUMENTS (delete_dtor);
+ val = build2 (MODIFY_EXPR, TREE_TYPE (val),
+ DECL_RESULT (delete_dtor), val);
+ add_stmt (build_stmt (0, RETURN_EXPR, val));
+ }
+}
+
+/* Return name of comdat group for complete and base ctor (or dtor)
+ that have the same body. If dtor is virtual, deleting dtor goes
+ into this comdat group as well. */
+
+static tree
+cdtor_comdat_group (tree complete, tree base)
+{
+ tree complete_name = DECL_COMDAT_GROUP (complete);
+ tree base_name = DECL_COMDAT_GROUP (base);
+ char *grp_name;
+ const char *p, *q;
+ bool diff_seen = false;
+ size_t idx;
+ if (complete_name == NULL)
+ complete_name = cxx_comdat_group (complete);
+ if (base_name == NULL)
+ base_name = cxx_comdat_group (base);
+ gcc_assert (IDENTIFIER_LENGTH (complete_name)
+ == IDENTIFIER_LENGTH (base_name));
+ grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
+ p = IDENTIFIER_POINTER (complete_name);
+ q = IDENTIFIER_POINTER (base_name);
+ for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
+ if (p[idx] == q[idx])
+ grp_name[idx] = p[idx];
+ else
+ {
+ gcc_assert (!diff_seen
+ && idx > 0
+ && (p[idx - 1] == 'C' || p[idx - 1] == 'D')
+ && p[idx] == '1'
+ && q[idx] == '2');
+ grp_name[idx] = '5';
+ diff_seen = true;
+ }
+ grp_name[idx] = '\0';
+ gcc_assert (diff_seen);
+ return get_identifier (grp_name);
+}
+
+/* Returns true iff we can make the base and complete [cd]tor aliases of
+ the same symbol rather than separate functions. */
+
+static bool
+can_alias_cdtor (tree fn)
+{
+#ifndef ASM_OUTPUT_DEF
+ /* If aliases aren't supported by the assembler, fail. */
+ return false;
+#endif
+ /* We can't use an alias if there are virtual bases. */
+ if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
+ return false;
+ /* ??? Why not use aliases with -frepo? */
+ if (flag_use_repository)
+ return false;
+ gcc_assert (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
+ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn));
+ /* Don't use aliases for weak/linkonce definitions unless we can put both
+ symbols in the same COMDAT group. */
+ return (DECL_INTERFACE_KNOWN (fn)
+ && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn))
+ && (!DECL_ONE_ONLY (fn)
+ || (HAVE_COMDAT_GROUP && DECL_WEAK (fn))));
+}
+
+/* FN is a [cd]tor, fns is a pointer to an array of length 3. Fill fns
+ with pointers to the base, complete, and deleting variants. */
+
+static void
+populate_clone_array (tree fn, tree *fns)
+{
+ tree clone;
+
+ fns[0] = NULL_TREE;
+ fns[1] = NULL_TREE;
+ fns[2] = NULL_TREE;
+
+ /* Look for the complete destructor which may be used to build the
+ delete destructor. */
+ FOR_EACH_CLONE (clone, fn)
+ if (DECL_NAME (clone) == complete_dtor_identifier
+ || DECL_NAME (clone) == complete_ctor_identifier)
+ fns[1] = clone;
+ else if (DECL_NAME (clone) == base_dtor_identifier
+ || DECL_NAME (clone) == base_ctor_identifier)
+ fns[0] = clone;
+ else if (DECL_NAME (clone) == deleting_dtor_identifier)
+ fns[2] = clone;
+ else
+ gcc_unreachable ();
+}
+
+/* FN is a constructor or destructor, and there are FUNCTION_DECLs
+ cloned from it nearby. Instead of cloning this body, leave it
+ alone and create tiny one-call bodies for the cloned
+ FUNCTION_DECLs. These clones are sibcall candidates, and their
+ resulting code will be very thunk-esque. */
+
+static bool
+maybe_thunk_body (tree fn, bool force)
+{
+ tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist;
+ tree last_arg, modify, *args;
+ int parmno, vtt_parmno, max_parms;
+ tree fns[3];
+
+ if (!force && !flag_declone_ctor_dtor)
+ return 0;
+
+ /* If function accepts variable arguments, give up. */
+ last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
+ if (last_arg != void_list_node)
+ return 0;
+
+ /* If we got this far, we've decided to turn the clones into thunks. */
+
+ /* We're going to generate code for fn, so it is no longer "abstract."
+ Also make the unified ctor/dtor private to either the translation unit
+ (for non-vague linkage ctors) or the COMDAT group (otherwise). */
+
+ populate_clone_array (fn, fns);
+ DECL_ABSTRACT (fn) = false;
+ if (!DECL_WEAK (fn))
+ {
+ TREE_PUBLIC (fn) = false;
+ DECL_EXTERNAL (fn) = false;
+ DECL_INTERFACE_KNOWN (fn) = true;
+ }
+ else if (HAVE_COMDAT_GROUP)
+ {
+ tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
+ DECL_COMDAT_GROUP (fns[0]) = comdat_group;
+ symtab_add_to_same_comdat_group (cgraph_get_create_node (fns[1]),
+ cgraph_get_create_node (fns[0]));
+ symtab_add_to_same_comdat_group (symtab_get_node (fn),
+ symtab_get_node (fns[0]));
+ if (fns[2])
+ /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
+ virtual, it goes into the same comdat group as well. */
+ symtab_add_to_same_comdat_group (cgraph_get_create_node (fns[2]),
+ symtab_get_node (fns[0]));
+ TREE_PUBLIC (fn) = false;
+ DECL_EXTERNAL (fn) = false;
+ DECL_INTERFACE_KNOWN (fn) = true;
+ /* function_and_variable_visibility doesn't want !PUBLIC decls to
+ have these flags set. */
+ DECL_WEAK (fn) = false;
+ DECL_COMDAT (fn) = false;
+ }
+
+ /* Find the vtt_parm, if present. */
+ for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
+ fn_parm;
+ ++parmno, fn_parm = TREE_CHAIN (fn_parm))
+ {
+ if (DECL_ARTIFICIAL (fn_parm)
+ && DECL_NAME (fn_parm) == vtt_parm_identifier)
+ {
+ /* Compensate for removed in_charge parameter. */
+ vtt_parmno = parmno;
+ break;
+ }
+ }
+
+ /* Allocate an argument buffer for build_cxx_call().
+ Make sure it is large enough for any of the clones. */
+ max_parms = 0;
+ FOR_EACH_CLONE (clone, fn)
+ {
+ int length = list_length (DECL_ARGUMENTS (fn));
+ if (length > max_parms)
+ max_parms = length;
+ }
+ args = (tree *) alloca (max_parms * sizeof (tree));
+
+ /* We know that any clones immediately follow FN in TYPE_METHODS. */
+ FOR_EACH_CLONE (clone, fn)
+ {
+ tree clone_parm;
+
+ /* If we've already generated a body for this clone, avoid
+ duplicating it. (Is it possible for a clone-list to grow after we
+ first see it?) */
+ if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
+ continue;
+
+ /* Start processing the function. */
+ start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
+
+ if (clone == fns[2])
+ {
+ for (clone_parm = DECL_ARGUMENTS (clone); clone_parm;
+ clone_parm = TREE_CHAIN (clone_parm))
+ DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE;
+ /* Build the delete destructor by calling complete destructor and
+ delete function. */
+ build_delete_destructor_body (clone, fns[1]);
+ }
+ else
+ {
+ /* Walk parameter lists together, creating parameter list for
+ call to original function. */
+ for (parmno = 0,
+ fn_parm = DECL_ARGUMENTS (fn),
+ fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
+ clone_parm = DECL_ARGUMENTS (clone);
+ fn_parm;
+ ++parmno,
+ fn_parm = TREE_CHAIN (fn_parm))
+ {
+ if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
+ {
+ gcc_assert (fn_parm_typelist);
+ /* Clobber argument with formal parameter type. */
+ args[parmno]
+ = convert (TREE_VALUE (fn_parm_typelist),
+ null_pointer_node);
+ }
+ else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
+ {
+ tree in_charge
+ = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
+ args[parmno] = in_charge;
+ }
+ /* Map other parameters to their equivalents in the cloned
+ function. */
+ else
+ {
+ gcc_assert (clone_parm);
+ DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
+ args[parmno] = clone_parm;
+ clone_parm = TREE_CHAIN (clone_parm);
+ }
+ if (fn_parm_typelist)
+ fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
+ }
+
+ /* We built this list backwards; fix now. */
+ mark_used (fn);
+ call = build_cxx_call (fn, parmno, args, tf_warning_or_error);
+ /* Arguments passed to the thunk by invisible reference should
+ be transmitted to the callee unchanged. Do not create a
+ temporary and invoke the copy constructor. The thunking
+ transformation must not introduce any constructor calls. */
+ CALL_FROM_THUNK_P (call) = 1;
+ block = make_node (BLOCK);
+ if (targetm.cxx.cdtor_returns_this ())
+ {
+ clone_result = DECL_RESULT (clone);
+ modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
+ clone_result, call);
+ modify = build1 (RETURN_EXPR, void_type_node, modify);
+ add_stmt (modify);
+ }
+ else
+ {
+ add_stmt (call);
+ }
+ bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone),
+ block, cur_stmt_list);
+ DECL_SAVED_TREE (clone) = push_stmt_list ();
+ add_stmt (bind);
+ }
+
+ DECL_ABSTRACT_ORIGIN (clone) = NULL;
+ expand_or_defer_fn (finish_function (0));
+ }
+ return 1;
+}
+
+/* FN is a function that has a complete body. Clone the body as
+ necessary. Returns nonzero if there's no longer any need to
+ process the main body. */
+
+bool
+maybe_clone_body (tree fn)
+{
+ tree comdat_group = NULL_TREE;
+ tree clone;
+ tree fns[3];
+ bool first = true;
+ int idx;
+ bool need_alias = false;
+
+ /* We only clone constructors and destructors. */
+ if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
+ && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
+ return 0;
+
+ populate_clone_array (fn, fns);
+
+ /* Remember if we can't have multiple clones for some reason. We need to
+ check this before we remap local static initializers in clone_body. */
+ if (!tree_versionable_function_p (fn))
+ need_alias = true;
+
+ /* We know that any clones immediately follow FN in the TYPE_METHODS
+ list. */
+ push_to_top_level ();
+ for (idx = 0; idx < 3; idx++)
+ {
+ tree parm;
+ tree clone_parm;
+
+ clone = fns[idx];
+ if (!clone)
+ continue;
+
+ /* Update CLONE's source position information to match FN's. */
+ DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
+ DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
+ DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
+ DECL_COMDAT (clone) = DECL_COMDAT (fn);
+ DECL_WEAK (clone) = DECL_WEAK (fn);
+
+ /* We don't copy the comdat group from fn to clone because the assembler
+ name of fn was corrupted by write_mangled_name by adding *INTERNAL*
+ to it. By doing so, it also corrupted the comdat group. */
+ if (DECL_ONE_ONLY (fn))
+ DECL_COMDAT_GROUP (clone) = cxx_comdat_group (clone);
+ DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
+ DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
+ DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
+ DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
+ DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
+ TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
+ DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
+ DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
+ DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
+ DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
+ DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
+
+ /* Adjust the parameter names and locations. */
+ parm = DECL_ARGUMENTS (fn);
+ clone_parm = DECL_ARGUMENTS (clone);
+ /* Update the `this' parameter, which is always first. */
+ update_cloned_parm (parm, clone_parm, first);
+ parm = DECL_CHAIN (parm);
+ clone_parm = DECL_CHAIN (clone_parm);
+ if (DECL_HAS_IN_CHARGE_PARM_P (fn))
+ parm = DECL_CHAIN (parm);
+ if (DECL_HAS_VTT_PARM_P (fn))
+ parm = DECL_CHAIN (parm);
+ if (DECL_HAS_VTT_PARM_P (clone))
+ clone_parm = DECL_CHAIN (clone_parm);
+ for (; parm;
+ parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
+ /* Update this parameter. */
+ update_cloned_parm (parm, clone_parm, first);
+ }
+
+ bool can_alias = can_alias_cdtor (fn);
+
+ /* If we decide to turn clones into thunks, they will branch to fn.
+ Must have original function available to call. */
+ if (!can_alias && maybe_thunk_body (fn, need_alias))
+ {
+ pop_from_top_level ();
+ /* We still need to emit the original function. */
+ return 0;
+ }
+
+ /* Emit the DWARF1 abstract instance. */
+ (*debug_hooks->deferred_inline_function) (fn);
+
+ /* We know that any clones immediately follow FN in the TYPE_METHODS list. */
+ for (idx = 0; idx < 3; idx++)
+ {
+ tree parm;
+ tree clone_parm;
+ int parmno;
+ struct pointer_map_t *decl_map;
+ bool alias = false;
+
+ clone = fns[idx];
+ if (!clone)
+ continue;
+
+ /* Start processing the function. */
+ start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
+
+ /* Tell cgraph if both ctors or both dtors are known to have
+ the same body. */
+ if (can_alias
+ && fns[0]
+ && idx == 1
+ && cgraph_same_body_alias (cgraph_get_create_node (fns[0]),
+ clone, fns[0]))
+ {
+ alias = true;
+ if (DECL_ONE_ONLY (fns[0]))
+ {
+ /* For comdat base and complete cdtors put them
+ into the same, *[CD]5* comdat group instead of
+ *[CD][12]*. */
+ comdat_group = cdtor_comdat_group (fns[1], fns[0]);
+ DECL_COMDAT_GROUP (fns[0]) = comdat_group;
+ symtab_add_to_same_comdat_group (symtab_get_node (clone),
+ symtab_get_node (fns[0]));
+ }
+ }
+
+ /* Build the delete destructor by calling complete destructor
+ and delete function. */
+ if (idx == 2)
+ {
+ build_delete_destructor_body (clone, fns[1]);
+ /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
+ virtual, it goes into the same comdat group as well. */
+ if (comdat_group)
+ symtab_add_to_same_comdat_group
+ (cgraph_get_create_node (clone),
+ symtab_get_node (fns[0]));
+ }
+ else if (alias)
+ /* No need to populate body. */ ;
+ else
+ {
+ /* If we can't have multiple copies of FN (say, because there's a
+ static local initialized with the address of a label), we need
+ to use an alias for the complete variant. */
+ if (idx == 1 && need_alias)
+ {
+ if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
+ sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
+ else
+ sorry ("making multiple clones of %qD", fn);
+ }
+
+ /* Remap the parameters. */
+ decl_map = pointer_map_create ();
+ for (parmno = 0,
+ parm = DECL_ARGUMENTS (fn),
+ clone_parm = DECL_ARGUMENTS (clone);
+ parm;
+ ++parmno,
+ parm = DECL_CHAIN (parm))
+ {
+ /* Map the in-charge parameter to an appropriate constant. */
+ if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
+ {
+ tree in_charge;
+ in_charge = in_charge_arg_for_name (DECL_NAME (clone));
+ *pointer_map_insert (decl_map, parm) = in_charge;
+ }
+ else if (DECL_ARTIFICIAL (parm)
+ && DECL_NAME (parm) == vtt_parm_identifier)
+ {
+ /* For a subobject constructor or destructor, the next
+ argument is the VTT parameter. Remap the VTT_PARM
+ from the CLONE to this parameter. */
+ if (DECL_HAS_VTT_PARM_P (clone))
+ {
+ DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
+ *pointer_map_insert (decl_map, parm) = clone_parm;
+ clone_parm = DECL_CHAIN (clone_parm);
+ }
+ /* Otherwise, map the VTT parameter to `NULL'. */
+ else
+ *pointer_map_insert (decl_map, parm)
+ = fold_convert (TREE_TYPE (parm), null_pointer_node);
+ }
+ /* Map other parameters to their equivalents in the cloned
+ function. */
+ else
+ {
+ *pointer_map_insert (decl_map, parm) = clone_parm;
+ clone_parm = DECL_CHAIN (clone_parm);
+ }
+ }
+
+ if (targetm.cxx.cdtor_returns_this ())
+ {
+ parm = DECL_RESULT (fn);
+ clone_parm = DECL_RESULT (clone);
+ *pointer_map_insert (decl_map, parm) = clone_parm;
+ }
+
+ /* Clone the body. */
+ clone_body (clone, fn, decl_map);
+
+ /* Clean up. */
+ pointer_map_destroy (decl_map);
+ }
+
+ /* The clone can throw iff the original function can throw. */
+ cp_function_chain->can_throw = !TREE_NOTHROW (fn);
+
+ /* Now, expand this function into RTL, if appropriate. */
+ finish_function (0);
+ BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
+ if (alias)
+ {
+ if (expand_or_defer_fn_1 (clone))
+ emit_associated_thunks (clone);
+ }
+ else
+ expand_or_defer_fn (clone);
+ first = false;
+ }
+ pop_from_top_level ();
+
+ /* We don't need to process the original function any further. */
+ return 1;
+}
diff --git a/gcc-4.9/gcc/cp/parser.c b/gcc-4.9/gcc/cp/parser.c
new file mode 100644
index 000000000..4ca08a13d
--- /dev/null
+++ b/gcc-4.9/gcc/cp/parser.c
@@ -0,0 +1,32131 @@
+/* C++ Parser.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Written by Mark Mitchell <mark@codesourcery.com>.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "timevar.h"
+#include "cpplib.h"
+#include "tree.h"
+#include "print-tree.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "trans-mem.h"
+#include "cp-tree.h"
+#include "intl.h"
+#include "c-family/c-pragma.h"
+#include "decl.h"
+#include "flags.h"
+#include "diagnostic-core.h"
+#include "target.h"
+#include "cgraph.h"
+#include "c-family/c-common.h"
+#include "c-family/c-objc.h"
+#include "plugin.h"
+#include "tree-pretty-print.h"
+#include "parser.h"
+#include "type-utils.h"
+#include "omp-low.h"
+
+
+/* The lexer. */
+
+/* The cp_lexer_* routines mediate between the lexer proper (in libcpp
+ and c-lex.c) and the C++ parser. */
+
+static cp_token eof_token =
+{
+ CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, false, false, 0, { NULL }
+};
+
+/* The various kinds of non integral constant we encounter. */
+typedef enum non_integral_constant {
+ NIC_NONE,
+ /* floating-point literal */
+ NIC_FLOAT,
+ /* %<this%> */
+ NIC_THIS,
+ /* %<__FUNCTION__%> */
+ NIC_FUNC_NAME,
+ /* %<__PRETTY_FUNCTION__%> */
+ NIC_PRETTY_FUNC,
+ /* %<__func__%> */
+ NIC_C99_FUNC,
+ /* "%<va_arg%> */
+ NIC_VA_ARG,
+ /* a cast */
+ NIC_CAST,
+ /* %<typeid%> operator */
+ NIC_TYPEID,
+ /* non-constant compound literals */
+ NIC_NCC,
+ /* a function call */
+ NIC_FUNC_CALL,
+ /* an increment */
+ NIC_INC,
+ /* an decrement */
+ NIC_DEC,
+ /* an array reference */
+ NIC_ARRAY_REF,
+ /* %<->%> */
+ NIC_ARROW,
+ /* %<.%> */
+ NIC_POINT,
+ /* the address of a label */
+ NIC_ADDR_LABEL,
+ /* %<*%> */
+ NIC_STAR,
+ /* %<&%> */
+ NIC_ADDR,
+ /* %<++%> */
+ NIC_PREINCREMENT,
+ /* %<--%> */
+ NIC_PREDECREMENT,
+ /* %<new%> */
+ NIC_NEW,
+ /* %<delete%> */
+ NIC_DEL,
+ /* calls to overloaded operators */
+ NIC_OVERLOADED,
+ /* an assignment */
+ NIC_ASSIGNMENT,
+ /* a comma operator */
+ NIC_COMMA,
+ /* a call to a constructor */
+ NIC_CONSTRUCTOR,
+ /* a transaction expression */
+ NIC_TRANSACTION
+} non_integral_constant;
+
+/* The various kinds of errors about name-lookup failing. */
+typedef enum name_lookup_error {
+ /* NULL */
+ NLE_NULL,
+ /* is not a type */
+ NLE_TYPE,
+ /* is not a class or namespace */
+ NLE_CXX98,
+ /* is not a class, namespace, or enumeration */
+ NLE_NOT_CXX98
+} name_lookup_error;
+
+/* The various kinds of required token */
+typedef enum required_token {
+ RT_NONE,
+ RT_SEMICOLON, /* ';' */
+ RT_OPEN_PAREN, /* '(' */
+ RT_CLOSE_BRACE, /* '}' */
+ RT_OPEN_BRACE, /* '{' */
+ RT_CLOSE_SQUARE, /* ']' */
+ RT_OPEN_SQUARE, /* '[' */
+ RT_COMMA, /* ',' */
+ RT_SCOPE, /* '::' */
+ RT_LESS, /* '<' */
+ RT_GREATER, /* '>' */
+ RT_EQ, /* '=' */
+ RT_ELLIPSIS, /* '...' */
+ RT_MULT, /* '*' */
+ RT_COMPL, /* '~' */
+ RT_COLON, /* ':' */
+ RT_COLON_SCOPE, /* ':' or '::' */
+ RT_CLOSE_PAREN, /* ')' */
+ RT_COMMA_CLOSE_PAREN, /* ',' or ')' */
+ RT_PRAGMA_EOL, /* end of line */
+ RT_NAME, /* identifier */
+
+ /* The type is CPP_KEYWORD */
+ RT_NEW, /* new */
+ RT_DELETE, /* delete */
+ RT_RETURN, /* return */
+ RT_WHILE, /* while */
+ RT_EXTERN, /* extern */
+ RT_STATIC_ASSERT, /* static_assert */
+ RT_DECLTYPE, /* decltype */
+ RT_OPERATOR, /* operator */
+ RT_CLASS, /* class */
+ RT_TEMPLATE, /* template */
+ RT_NAMESPACE, /* namespace */
+ RT_USING, /* using */
+ RT_ASM, /* asm */
+ RT_TRY, /* try */
+ RT_CATCH, /* catch */
+ RT_THROW, /* throw */
+ RT_LABEL, /* __label__ */
+ RT_AT_TRY, /* @try */
+ RT_AT_SYNCHRONIZED, /* @synchronized */
+ RT_AT_THROW, /* @throw */
+
+ RT_SELECT, /* selection-statement */
+ RT_INTERATION, /* iteration-statement */
+ RT_JUMP, /* jump-statement */
+ RT_CLASS_KEY, /* class-key */
+ RT_CLASS_TYPENAME_TEMPLATE, /* class, typename, or template */
+ RT_TRANSACTION_ATOMIC, /* __transaction_atomic */
+ RT_TRANSACTION_RELAXED, /* __transaction_relaxed */
+ RT_TRANSACTION_CANCEL /* __transaction_cancel */
+} required_token;
+
+/* Prototypes. */
+
+static cp_lexer *cp_lexer_new_main
+ (void);
+static cp_lexer *cp_lexer_new_from_tokens
+ (cp_token_cache *tokens);
+static void cp_lexer_destroy
+ (cp_lexer *);
+static int cp_lexer_saving_tokens
+ (const cp_lexer *);
+static cp_token *cp_lexer_token_at
+ (cp_lexer *, cp_token_position);
+static void cp_lexer_get_preprocessor_token
+ (cp_lexer *, cp_token *);
+static inline cp_token *cp_lexer_peek_token
+ (cp_lexer *);
+static cp_token *cp_lexer_peek_nth_token
+ (cp_lexer *, size_t);
+static inline bool cp_lexer_next_token_is
+ (cp_lexer *, enum cpp_ttype);
+static bool cp_lexer_next_token_is_not
+ (cp_lexer *, enum cpp_ttype);
+static bool cp_lexer_next_token_is_keyword
+ (cp_lexer *, enum rid);
+static cp_token *cp_lexer_consume_token
+ (cp_lexer *);
+static void cp_lexer_purge_token
+ (cp_lexer *);
+static void cp_lexer_purge_tokens_after
+ (cp_lexer *, cp_token_position);
+static void cp_lexer_save_tokens
+ (cp_lexer *);
+static void cp_lexer_commit_tokens
+ (cp_lexer *);
+static void cp_lexer_rollback_tokens
+ (cp_lexer *);
+static void cp_lexer_print_token
+ (FILE *, cp_token *);
+static inline bool cp_lexer_debugging_p
+ (cp_lexer *);
+static void cp_lexer_start_debugging
+ (cp_lexer *) ATTRIBUTE_UNUSED;
+static void cp_lexer_stop_debugging
+ (cp_lexer *) ATTRIBUTE_UNUSED;
+
+static cp_token_cache *cp_token_cache_new
+ (cp_token *, cp_token *);
+
+static void cp_parser_initial_pragma
+ (cp_token *);
+
+static tree cp_literal_operator_id
+ (const char *);
+
+static void cp_parser_cilk_simd
+ (cp_parser *, cp_token *);
+static bool cp_parser_omp_declare_reduction_exprs
+ (tree, cp_parser *);
+static tree cp_parser_cilk_simd_vectorlength
+ (cp_parser *, tree, bool);
+
+/* Manifest constants. */
+#define CP_LEXER_BUFFER_SIZE ((256 * 1024) / sizeof (cp_token))
+#define CP_SAVED_TOKEN_STACK 5
+
+/* Variables. */
+
+/* The stream to which debugging output should be written. */
+static FILE *cp_lexer_debug_stream;
+
+/* Nonzero if we are parsing an unevaluated operand: an operand to
+ sizeof, typeof, or alignof. */
+int cp_unevaluated_operand;
+
+/* Dump up to NUM tokens in BUFFER to FILE starting with token
+ START_TOKEN. If START_TOKEN is NULL, the dump starts with the
+ first token in BUFFER. If NUM is 0, dump all the tokens. If
+ CURR_TOKEN is set and it is one of the tokens in BUFFER, it will be
+ highlighted by surrounding it in [[ ]]. */
+
+static void
+cp_lexer_dump_tokens (FILE *file, vec<cp_token, va_gc> *buffer,
+ cp_token *start_token, unsigned num,
+ cp_token *curr_token)
+{
+ unsigned i, nprinted;
+ cp_token *token;
+ bool do_print;
+
+ fprintf (file, "%u tokens\n", vec_safe_length (buffer));
+
+ if (buffer == NULL)
+ return;
+
+ if (num == 0)
+ num = buffer->length ();
+
+ if (start_token == NULL)
+ start_token = buffer->address ();
+
+ if (start_token > buffer->address ())
+ {
+ cp_lexer_print_token (file, &(*buffer)[0]);
+ fprintf (file, " ... ");
+ }
+
+ do_print = false;
+ nprinted = 0;
+ for (i = 0; buffer->iterate (i, &token) && nprinted < num; i++)
+ {
+ if (token == start_token)
+ do_print = true;
+
+ if (!do_print)
+ continue;
+
+ nprinted++;
+ if (token == curr_token)
+ fprintf (file, "[[");
+
+ cp_lexer_print_token (file, token);
+
+ if (token == curr_token)
+ fprintf (file, "]]");
+
+ switch (token->type)
+ {
+ case CPP_SEMICOLON:
+ case CPP_OPEN_BRACE:
+ case CPP_CLOSE_BRACE:
+ case CPP_EOF:
+ fputc ('\n', file);
+ break;
+
+ default:
+ fputc (' ', file);
+ }
+ }
+
+ if (i == num && i < buffer->length ())
+ {
+ fprintf (file, " ... ");
+ cp_lexer_print_token (file, &buffer->last ());
+ }
+
+ fprintf (file, "\n");
+}
+
+
+/* Dump all tokens in BUFFER to stderr. */
+
+void
+cp_lexer_debug_tokens (vec<cp_token, va_gc> *buffer)
+{
+ cp_lexer_dump_tokens (stderr, buffer, NULL, 0, NULL);
+}
+
+DEBUG_FUNCTION void
+debug (vec<cp_token, va_gc> &ref)
+{
+ cp_lexer_dump_tokens (stderr, &ref, NULL, 0, NULL);
+}
+
+DEBUG_FUNCTION void
+debug (vec<cp_token, va_gc> *ptr)
+{
+ if (ptr)
+ debug (*ptr);
+ else
+ fprintf (stderr, "<nil>\n");
+}
+
+
+/* Dump the cp_parser tree field T to FILE if T is non-NULL. DESC is the
+ description for T. */
+
+static void
+cp_debug_print_tree_if_set (FILE *file, const char *desc, tree t)
+{
+ if (t)
+ {
+ fprintf (file, "%s: ", desc);
+ print_node_brief (file, "", t, 0);
+ }
+}
+
+
+/* Dump parser context C to FILE. */
+
+static void
+cp_debug_print_context (FILE *file, cp_parser_context *c)
+{
+ const char *status_s[] = { "OK", "ERROR", "COMMITTED" };
+ fprintf (file, "{ status = %s, scope = ", status_s[c->status]);
+ print_node_brief (file, "", c->object_type, 0);
+ fprintf (file, "}\n");
+}
+
+
+/* Print the stack of parsing contexts to FILE starting with FIRST. */
+
+static void
+cp_debug_print_context_stack (FILE *file, cp_parser_context *first)
+{
+ unsigned i;
+ cp_parser_context *c;
+
+ fprintf (file, "Parsing context stack:\n");
+ for (i = 0, c = first; c; c = c->next, i++)
+ {
+ fprintf (file, "\t#%u: ", i);
+ cp_debug_print_context (file, c);
+ }
+}
+
+
+/* Print the value of FLAG to FILE. DESC is a string describing the flag. */
+
+static void
+cp_debug_print_flag (FILE *file, const char *desc, bool flag)
+{
+ if (flag)
+ fprintf (file, "%s: true\n", desc);
+}
+
+
+/* Print an unparsed function entry UF to FILE. */
+
+static void
+cp_debug_print_unparsed_function (FILE *file, cp_unparsed_functions_entry *uf)
+{
+ unsigned i;
+ cp_default_arg_entry *default_arg_fn;
+ tree fn;
+
+ fprintf (file, "\tFunctions with default args:\n");
+ for (i = 0;
+ vec_safe_iterate (uf->funs_with_default_args, i, &default_arg_fn);
+ i++)
+ {
+ fprintf (file, "\t\tClass type: ");
+ print_node_brief (file, "", default_arg_fn->class_type, 0);
+ fprintf (file, "\t\tDeclaration: ");
+ print_node_brief (file, "", default_arg_fn->decl, 0);
+ fprintf (file, "\n");
+ }
+
+ fprintf (file, "\n\tFunctions with definitions that require "
+ "post-processing\n\t\t");
+ for (i = 0; vec_safe_iterate (uf->funs_with_definitions, i, &fn); i++)
+ {
+ print_node_brief (file, "", fn, 0);
+ fprintf (file, " ");
+ }
+ fprintf (file, "\n");
+
+ fprintf (file, "\n\tNon-static data members with initializers that require "
+ "post-processing\n\t\t");
+ for (i = 0; vec_safe_iterate (uf->nsdmis, i, &fn); i++)
+ {
+ print_node_brief (file, "", fn, 0);
+ fprintf (file, " ");
+ }
+ fprintf (file, "\n");
+}
+
+
+/* Print the stack of unparsed member functions S to FILE. */
+
+static void
+cp_debug_print_unparsed_queues (FILE *file,
+ vec<cp_unparsed_functions_entry, va_gc> *s)
+{
+ unsigned i;
+ cp_unparsed_functions_entry *uf;
+
+ fprintf (file, "Unparsed functions\n");
+ for (i = 0; vec_safe_iterate (s, i, &uf); i++)
+ {
+ fprintf (file, "#%u:\n", i);
+ cp_debug_print_unparsed_function (file, uf);
+ }
+}
+
+
+/* Dump the tokens in a window of size WINDOW_SIZE around the next_token for
+ the given PARSER. If FILE is NULL, the output is printed on stderr. */
+
+static void
+cp_debug_parser_tokens (FILE *file, cp_parser *parser, int window_size)
+{
+ cp_token *next_token, *first_token, *start_token;
+
+ if (file == NULL)
+ file = stderr;
+
+ next_token = parser->lexer->next_token;
+ first_token = parser->lexer->buffer->address ();
+ start_token = (next_token > first_token + window_size / 2)
+ ? next_token - window_size / 2
+ : first_token;
+ cp_lexer_dump_tokens (file, parser->lexer->buffer, start_token, window_size,
+ next_token);
+}
+
+
+/* Dump debugging information for the given PARSER. If FILE is NULL,
+ the output is printed on stderr. */
+
+void
+cp_debug_parser (FILE *file, cp_parser *parser)
+{
+ const size_t window_size = 20;
+ cp_token *token;
+ expanded_location eloc;
+
+ if (file == NULL)
+ file = stderr;
+
+ fprintf (file, "Parser state\n\n");
+ fprintf (file, "Number of tokens: %u\n",
+ vec_safe_length (parser->lexer->buffer));
+ cp_debug_print_tree_if_set (file, "Lookup scope", parser->scope);
+ cp_debug_print_tree_if_set (file, "Object scope",
+ parser->object_scope);
+ cp_debug_print_tree_if_set (file, "Qualifying scope",
+ parser->qualifying_scope);
+ cp_debug_print_context_stack (file, parser->context);
+ cp_debug_print_flag (file, "Allow GNU extensions",
+ parser->allow_gnu_extensions_p);
+ cp_debug_print_flag (file, "'>' token is greater-than",
+ parser->greater_than_is_operator_p);
+ cp_debug_print_flag (file, "Default args allowed in current "
+ "parameter list", parser->default_arg_ok_p);
+ cp_debug_print_flag (file, "Parsing integral constant-expression",
+ parser->integral_constant_expression_p);
+ cp_debug_print_flag (file, "Allow non-constant expression in current "
+ "constant-expression",
+ parser->allow_non_integral_constant_expression_p);
+ cp_debug_print_flag (file, "Seen non-constant expression",
+ parser->non_integral_constant_expression_p);
+ cp_debug_print_flag (file, "Local names and 'this' forbidden in "
+ "current context",
+ parser->local_variables_forbidden_p);
+ cp_debug_print_flag (file, "In unbraced linkage specification",
+ parser->in_unbraced_linkage_specification_p);
+ cp_debug_print_flag (file, "Parsing a declarator",
+ parser->in_declarator_p);
+ cp_debug_print_flag (file, "In template argument list",
+ parser->in_template_argument_list_p);
+ cp_debug_print_flag (file, "Parsing an iteration statement",
+ parser->in_statement & IN_ITERATION_STMT);
+ cp_debug_print_flag (file, "Parsing a switch statement",
+ parser->in_statement & IN_SWITCH_STMT);
+ cp_debug_print_flag (file, "Parsing a structured OpenMP block",
+ parser->in_statement & IN_OMP_BLOCK);
+ cp_debug_print_flag (file, "Parsing a Cilk Plus for loop",
+ parser->in_statement & IN_CILK_SIMD_FOR);
+ cp_debug_print_flag (file, "Parsing a an OpenMP loop",
+ parser->in_statement & IN_OMP_FOR);
+ cp_debug_print_flag (file, "Parsing an if statement",
+ parser->in_statement & IN_IF_STMT);
+ cp_debug_print_flag (file, "Parsing a type-id in an expression "
+ "context", parser->in_type_id_in_expr_p);
+ cp_debug_print_flag (file, "Declarations are implicitly extern \"C\"",
+ parser->implicit_extern_c);
+ cp_debug_print_flag (file, "String expressions should be translated "
+ "to execution character set",
+ parser->translate_strings_p);
+ cp_debug_print_flag (file, "Parsing function body outside of a "
+ "local class", parser->in_function_body);
+ cp_debug_print_flag (file, "Auto correct a colon to a scope operator",
+ parser->colon_corrects_to_scope_p);
+ cp_debug_print_flag (file, "Colon doesn't start a class definition",
+ parser->colon_doesnt_start_class_def_p);
+ if (parser->type_definition_forbidden_message)
+ fprintf (file, "Error message for forbidden type definitions: %s\n",
+ parser->type_definition_forbidden_message);
+ cp_debug_print_unparsed_queues (file, parser->unparsed_queues);
+ fprintf (file, "Number of class definitions in progress: %u\n",
+ parser->num_classes_being_defined);
+ fprintf (file, "Number of template parameter lists for the current "
+ "declaration: %u\n", parser->num_template_parameter_lists);
+ cp_debug_parser_tokens (file, parser, window_size);
+ token = parser->lexer->next_token;
+ fprintf (file, "Next token to parse:\n");
+ fprintf (file, "\tToken: ");
+ cp_lexer_print_token (file, token);
+ eloc = expand_location (token->location);
+ fprintf (file, "\n\tFile: %s\n", eloc.file);
+ fprintf (file, "\tLine: %d\n", eloc.line);
+ fprintf (file, "\tColumn: %d\n", eloc.column);
+}
+
+DEBUG_FUNCTION void
+debug (cp_parser &ref)
+{
+ cp_debug_parser (stderr, &ref);
+}
+
+DEBUG_FUNCTION void
+debug (cp_parser *ptr)
+{
+ if (ptr)
+ debug (*ptr);
+ else
+ fprintf (stderr, "<nil>\n");
+}
+
+/* Allocate memory for a new lexer object and return it. */
+
+static cp_lexer *
+cp_lexer_alloc (void)
+{
+ cp_lexer *lexer;
+
+ c_common_no_more_pch ();
+
+ /* Allocate the memory. */
+ lexer = ggc_alloc_cleared_cp_lexer ();
+
+ /* Initially we are not debugging. */
+ lexer->debugging_p = false;
+
+ lexer->saved_tokens.create (CP_SAVED_TOKEN_STACK);
+
+ /* Create the buffer. */
+ vec_alloc (lexer->buffer, CP_LEXER_BUFFER_SIZE);
+
+ return lexer;
+}
+
+
+/* Create a new main C++ lexer, the lexer that gets tokens from the
+ preprocessor. */
+
+static cp_lexer *
+cp_lexer_new_main (void)
+{
+ cp_lexer *lexer;
+ cp_token token;
+
+ /* It's possible that parsing the first pragma will load a PCH file,
+ which is a GC collection point. So we have to do that before
+ allocating any memory. */
+ cp_parser_initial_pragma (&token);
+
+ lexer = cp_lexer_alloc ();
+
+ /* Put the first token in the buffer. */
+ lexer->buffer->quick_push (token);
+
+ /* Get the remaining tokens from the preprocessor. */
+ while (token.type != CPP_EOF)
+ {
+ cp_lexer_get_preprocessor_token (lexer, &token);
+ vec_safe_push (lexer->buffer, token);
+ }
+
+ lexer->last_token = lexer->buffer->address ()
+ + lexer->buffer->length ()
+ - 1;
+ lexer->next_token = lexer->buffer->length ()
+ ? lexer->buffer->address ()
+ : &eof_token;
+
+ /* Subsequent preprocessor diagnostics should use compiler
+ diagnostic functions to get the compiler source location. */
+ done_lexing = true;
+
+ gcc_assert (!lexer->next_token->purged_p);
+ return lexer;
+}
+
+/* Create a new lexer whose token stream is primed with the tokens in
+ CACHE. When these tokens are exhausted, no new tokens will be read. */
+
+static cp_lexer *
+cp_lexer_new_from_tokens (cp_token_cache *cache)
+{
+ cp_token *first = cache->first;
+ cp_token *last = cache->last;
+ cp_lexer *lexer = ggc_alloc_cleared_cp_lexer ();
+
+ /* We do not own the buffer. */
+ lexer->buffer = NULL;
+ lexer->next_token = first == last ? &eof_token : first;
+ lexer->last_token = last;
+
+ lexer->saved_tokens.create (CP_SAVED_TOKEN_STACK);
+
+ /* Initially we are not debugging. */
+ lexer->debugging_p = false;
+
+ gcc_assert (!lexer->next_token->purged_p);
+ return lexer;
+}
+
+/* Frees all resources associated with LEXER. */
+
+static void
+cp_lexer_destroy (cp_lexer *lexer)
+{
+ vec_free (lexer->buffer);
+ lexer->saved_tokens.release ();
+ ggc_free (lexer);
+}
+
+/* Returns nonzero if debugging information should be output. */
+
+static inline bool
+cp_lexer_debugging_p (cp_lexer *lexer)
+{
+ return lexer->debugging_p;
+}
+
+
+static inline cp_token_position
+cp_lexer_token_position (cp_lexer *lexer, bool previous_p)
+{
+ gcc_assert (!previous_p || lexer->next_token != &eof_token);
+
+ return lexer->next_token - previous_p;
+}
+
+static inline cp_token *
+cp_lexer_token_at (cp_lexer * /*lexer*/, cp_token_position pos)
+{
+ return pos;
+}
+
+static inline void
+cp_lexer_set_token_position (cp_lexer *lexer, cp_token_position pos)
+{
+ lexer->next_token = cp_lexer_token_at (lexer, pos);
+}
+
+static inline cp_token_position
+cp_lexer_previous_token_position (cp_lexer *lexer)
+{
+ if (lexer->next_token == &eof_token)
+ return lexer->last_token - 1;
+ else
+ return cp_lexer_token_position (lexer, true);
+}
+
+static inline cp_token *
+cp_lexer_previous_token (cp_lexer *lexer)
+{
+ cp_token_position tp = cp_lexer_previous_token_position (lexer);
+
+ return cp_lexer_token_at (lexer, tp);
+}
+
+/* nonzero if we are presently saving tokens. */
+
+static inline int
+cp_lexer_saving_tokens (const cp_lexer* lexer)
+{
+ return lexer->saved_tokens.length () != 0;
+}
+
+/* Store the next token from the preprocessor in *TOKEN. Return true
+ if we reach EOF. If LEXER is NULL, assume we are handling an
+ initial #pragma pch_preprocess, and thus want the lexer to return
+ processed strings. */
+
+static void
+cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
+{
+ static int is_extern_c = 0;
+
+ /* Get a new token from the preprocessor. */
+ token->type
+ = c_lex_with_flags (&token->u.value, &token->location, &token->flags,
+ lexer == NULL ? 0 : C_LEX_STRING_NO_JOIN);
+ token->keyword = RID_MAX;
+ token->pragma_kind = PRAGMA_NONE;
+ token->purged_p = false;
+
+ /* On some systems, some header files are surrounded by an
+ implicit extern "C" block. Set a flag in the token if it
+ comes from such a header. */
+ is_extern_c += pending_lang_change;
+ pending_lang_change = 0;
+ token->implicit_extern_c = is_extern_c > 0;
+
+ /* Check to see if this token is a keyword. */
+ if (token->type == CPP_NAME)
+ {
+ if (C_IS_RESERVED_WORD (token->u.value))
+ {
+ /* Mark this token as a keyword. */
+ token->type = CPP_KEYWORD;
+ /* Record which keyword. */
+ token->keyword = C_RID_CODE (token->u.value);
+ }
+ else
+ {
+ if (warn_cxx0x_compat
+ && C_RID_CODE (token->u.value) >= RID_FIRST_CXX0X
+ && C_RID_CODE (token->u.value) <= RID_LAST_CXX0X)
+ {
+ /* Warn about the C++0x keyword (but still treat it as
+ an identifier). */
+ warning (OPT_Wc__0x_compat,
+ "identifier %qE is a keyword in C++11",
+ token->u.value);
+
+ /* Clear out the C_RID_CODE so we don't warn about this
+ particular identifier-turned-keyword again. */
+ C_SET_RID_CODE (token->u.value, RID_MAX);
+ }
+
+ token->ambiguous_p = false;
+ token->keyword = RID_MAX;
+ }
+ }
+ else if (token->type == CPP_AT_NAME)
+ {
+ /* This only happens in Objective-C++; it must be a keyword. */
+ token->type = CPP_KEYWORD;
+ switch (C_RID_CODE (token->u.value))
+ {
+ /* Replace 'class' with '@class', 'private' with '@private',
+ etc. This prevents confusion with the C++ keyword
+ 'class', and makes the tokens consistent with other
+ Objective-C 'AT' keywords. For example '@class' is
+ reported as RID_AT_CLASS which is consistent with
+ '@synchronized', which is reported as
+ RID_AT_SYNCHRONIZED.
+ */
+ case RID_CLASS: token->keyword = RID_AT_CLASS; break;
+ case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
+ case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
+ case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
+ case RID_THROW: token->keyword = RID_AT_THROW; break;
+ case RID_TRY: token->keyword = RID_AT_TRY; break;
+ case RID_CATCH: token->keyword = RID_AT_CATCH; break;
+ default: token->keyword = C_RID_CODE (token->u.value);
+ }
+ }
+ else if (token->type == CPP_PRAGMA)
+ {
+ /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
+ token->pragma_kind = ((enum pragma_kind)
+ TREE_INT_CST_LOW (token->u.value));
+ token->u.value = NULL_TREE;
+ }
+}
+
+/* Update the globals input_location and the input file stack from TOKEN. */
+static inline void
+cp_lexer_set_source_position_from_token (cp_token *token)
+{
+ if (token->type != CPP_EOF)
+ {
+ input_location = token->location;
+ }
+}
+
+/* Update the globals input_location and the input file stack from LEXER. */
+static inline void
+cp_lexer_set_source_position (cp_lexer *lexer)
+{
+ cp_token *token = cp_lexer_peek_token (lexer);
+ cp_lexer_set_source_position_from_token (token);
+}
+
+/* Return a pointer to the next token in the token stream, but do not
+ consume it. */
+
+static inline cp_token *
+cp_lexer_peek_token (cp_lexer *lexer)
+{
+ if (cp_lexer_debugging_p (lexer))
+ {
+ fputs ("cp_lexer: peeking at token: ", cp_lexer_debug_stream);
+ cp_lexer_print_token (cp_lexer_debug_stream, lexer->next_token);
+ putc ('\n', cp_lexer_debug_stream);
+ }
+ return lexer->next_token;
+}
+
+/* Return true if the next token has the indicated TYPE. */
+
+static inline bool
+cp_lexer_next_token_is (cp_lexer* lexer, enum cpp_ttype type)
+{
+ return cp_lexer_peek_token (lexer)->type == type;
+}
+
+/* Return true if the next token does not have the indicated TYPE. */
+
+static inline bool
+cp_lexer_next_token_is_not (cp_lexer* lexer, enum cpp_ttype type)
+{
+ return !cp_lexer_next_token_is (lexer, type);
+}
+
+/* Return true if the next token is the indicated KEYWORD. */
+
+static inline bool
+cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword)
+{
+ return cp_lexer_peek_token (lexer)->keyword == keyword;
+}
+
+static inline bool
+cp_lexer_nth_token_is_keyword (cp_lexer* lexer, size_t n, enum rid keyword)
+{
+ return cp_lexer_peek_nth_token (lexer, n)->keyword == keyword;
+}
+
+/* Return true if the next token is not the indicated KEYWORD. */
+
+static inline bool
+cp_lexer_next_token_is_not_keyword (cp_lexer* lexer, enum rid keyword)
+{
+ return cp_lexer_peek_token (lexer)->keyword != keyword;
+}
+
+/* Return true if the next token is a keyword for a decl-specifier. */
+
+static bool
+cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
+{
+ cp_token *token;
+
+ token = cp_lexer_peek_token (lexer);
+ switch (token->keyword)
+ {
+ /* auto specifier: storage-class-specifier in C++,
+ simple-type-specifier in C++0x. */
+ case RID_AUTO:
+ /* Storage classes. */
+ case RID_REGISTER:
+ case RID_STATIC:
+ case RID_EXTERN:
+ case RID_MUTABLE:
+ case RID_THREAD:
+ /* Elaborated type specifiers. */
+ case RID_ENUM:
+ case RID_CLASS:
+ case RID_STRUCT:
+ case RID_UNION:
+ case RID_TYPENAME:
+ /* Simple type specifiers. */
+ case RID_CHAR:
+ case RID_CHAR16:
+ case RID_CHAR32:
+ case RID_WCHAR:
+ case RID_BOOL:
+ case RID_SHORT:
+ case RID_INT:
+ case RID_LONG:
+ case RID_INT128:
+ case RID_SIGNED:
+ case RID_UNSIGNED:
+ case RID_FLOAT:
+ case RID_DOUBLE:
+ case RID_VOID:
+ /* GNU extensions. */
+ case RID_ATTRIBUTE:
+ case RID_TYPEOF:
+ /* C++0x extensions. */
+ case RID_DECLTYPE:
+ case RID_UNDERLYING_TYPE:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Returns TRUE iff the token T begins a decltype type. */
+
+static bool
+token_is_decltype (cp_token *t)
+{
+ return (t->keyword == RID_DECLTYPE
+ || t->type == CPP_DECLTYPE);
+}
+
+/* Returns TRUE iff the next token begins a decltype type. */
+
+static bool
+cp_lexer_next_token_is_decltype (cp_lexer *lexer)
+{
+ cp_token *t = cp_lexer_peek_token (lexer);
+ return token_is_decltype (t);
+}
+
+/* Return a pointer to the Nth token in the token stream. If N is 1,
+ then this is precisely equivalent to cp_lexer_peek_token (except
+ that it is not inline). One would like to disallow that case, but
+ there is one case (cp_parser_nth_token_starts_template_id) where
+ the caller passes a variable for N and it might be 1. */
+
+static cp_token *
+cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n)
+{
+ cp_token *token;
+
+ /* N is 1-based, not zero-based. */
+ gcc_assert (n > 0);
+
+ if (cp_lexer_debugging_p (lexer))
+ fprintf (cp_lexer_debug_stream,
+ "cp_lexer: peeking ahead %ld at token: ", (long)n);
+
+ --n;
+ token = lexer->next_token;
+ gcc_assert (!n || token != &eof_token);
+ while (n != 0)
+ {
+ ++token;
+ if (token == lexer->last_token)
+ {
+ token = &eof_token;
+ break;
+ }
+
+ if (!token->purged_p)
+ --n;
+ }
+
+ if (cp_lexer_debugging_p (lexer))
+ {
+ cp_lexer_print_token (cp_lexer_debug_stream, token);
+ putc ('\n', cp_lexer_debug_stream);
+ }
+
+ return token;
+}
+
+/* Return the next token, and advance the lexer's next_token pointer
+ to point to the next non-purged token. */
+
+static cp_token *
+cp_lexer_consume_token (cp_lexer* lexer)
+{
+ cp_token *token = lexer->next_token;
+
+ gcc_assert (token != &eof_token);
+ gcc_assert (!lexer->in_pragma || token->type != CPP_PRAGMA_EOL);
+
+ do
+ {
+ lexer->next_token++;
+ if (lexer->next_token == lexer->last_token)
+ {
+ lexer->next_token = &eof_token;
+ break;
+ }
+
+ }
+ while (lexer->next_token->purged_p);
+
+ cp_lexer_set_source_position_from_token (token);
+
+ /* Provide debugging output. */
+ if (cp_lexer_debugging_p (lexer))
+ {
+ fputs ("cp_lexer: consuming token: ", cp_lexer_debug_stream);
+ cp_lexer_print_token (cp_lexer_debug_stream, token);
+ putc ('\n', cp_lexer_debug_stream);
+ }
+
+ return token;
+}
+
+/* Permanently remove the next token from the token stream, and
+ advance the next_token pointer to refer to the next non-purged
+ token. */
+
+static void
+cp_lexer_purge_token (cp_lexer *lexer)
+{
+ cp_token *tok = lexer->next_token;
+
+ gcc_assert (tok != &eof_token);
+ tok->purged_p = true;
+ tok->location = UNKNOWN_LOCATION;
+ tok->u.value = NULL_TREE;
+ tok->keyword = RID_MAX;
+
+ do
+ {
+ tok++;
+ if (tok == lexer->last_token)
+ {
+ tok = &eof_token;
+ break;
+ }
+ }
+ while (tok->purged_p);
+ lexer->next_token = tok;
+}
+
+/* Permanently remove all tokens after TOK, up to, but not
+ including, the token that will be returned next by
+ cp_lexer_peek_token. */
+
+static void
+cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *tok)
+{
+ cp_token *peek = lexer->next_token;
+
+ if (peek == &eof_token)
+ peek = lexer->last_token;
+
+ gcc_assert (tok < peek);
+
+ for ( tok += 1; tok != peek; tok += 1)
+ {
+ tok->purged_p = true;
+ tok->location = UNKNOWN_LOCATION;
+ tok->u.value = NULL_TREE;
+ tok->keyword = RID_MAX;
+ }
+}
+
+/* Begin saving tokens. All tokens consumed after this point will be
+ preserved. */
+
+static void
+cp_lexer_save_tokens (cp_lexer* lexer)
+{
+ /* Provide debugging output. */
+ if (cp_lexer_debugging_p (lexer))
+ fprintf (cp_lexer_debug_stream, "cp_lexer: saving tokens\n");
+
+ lexer->saved_tokens.safe_push (lexer->next_token);
+}
+
+/* Commit to the portion of the token stream most recently saved. */
+
+static void
+cp_lexer_commit_tokens (cp_lexer* lexer)
+{
+ /* Provide debugging output. */
+ if (cp_lexer_debugging_p (lexer))
+ fprintf (cp_lexer_debug_stream, "cp_lexer: committing tokens\n");
+
+ lexer->saved_tokens.pop ();
+}
+
+/* Return all tokens saved since the last call to cp_lexer_save_tokens
+ to the token stream. Stop saving tokens. */
+
+static void
+cp_lexer_rollback_tokens (cp_lexer* lexer)
+{
+ /* Provide debugging output. */
+ if (cp_lexer_debugging_p (lexer))
+ fprintf (cp_lexer_debug_stream, "cp_lexer: restoring tokens\n");
+
+ lexer->next_token = lexer->saved_tokens.pop ();
+}
+
+/* Print a representation of the TOKEN on the STREAM. */
+
+static void
+cp_lexer_print_token (FILE * stream, cp_token *token)
+{
+ /* We don't use cpp_type2name here because the parser defines
+ a few tokens of its own. */
+ static const char *const token_names[] = {
+ /* cpplib-defined token types */
+#define OP(e, s) #e,
+#define TK(e, s) #e,
+ TTYPE_TABLE
+#undef OP
+#undef TK
+ /* C++ parser token types - see "Manifest constants", above. */
+ "KEYWORD",
+ "TEMPLATE_ID",
+ "NESTED_NAME_SPECIFIER",
+ };
+
+ /* For some tokens, print the associated data. */
+ switch (token->type)
+ {
+ case CPP_KEYWORD:
+ /* Some keywords have a value that is not an IDENTIFIER_NODE.
+ For example, `struct' is mapped to an INTEGER_CST. */
+ if (!identifier_p (token->u.value))
+ break;
+ /* else fall through */
+ case CPP_NAME:
+ fputs (IDENTIFIER_POINTER (token->u.value), stream);
+ break;
+
+ case CPP_STRING:
+ case CPP_STRING16:
+ case CPP_STRING32:
+ case CPP_WSTRING:
+ case CPP_UTF8STRING:
+ fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->u.value));
+ break;
+
+ case CPP_NUMBER:
+ print_generic_expr (stream, token->u.value, 0);
+ break;
+
+ default:
+ /* If we have a name for the token, print it out. Otherwise, we
+ simply give the numeric code. */
+ if (token->type < ARRAY_SIZE(token_names))
+ fputs (token_names[token->type], stream);
+ else
+ fprintf (stream, "[%d]", token->type);
+ break;
+ }
+}
+
+DEBUG_FUNCTION void
+debug (cp_token &ref)
+{
+ cp_lexer_print_token (stderr, &ref);
+ fprintf (stderr, "\n");
+}
+
+DEBUG_FUNCTION void
+debug (cp_token *ptr)
+{
+ if (ptr)
+ debug (*ptr);
+ else
+ fprintf (stderr, "<nil>\n");
+}
+
+
+/* Start emitting debugging information. */
+
+static void
+cp_lexer_start_debugging (cp_lexer* lexer)
+{
+ lexer->debugging_p = true;
+ cp_lexer_debug_stream = stderr;
+}
+
+/* Stop emitting debugging information. */
+
+static void
+cp_lexer_stop_debugging (cp_lexer* lexer)
+{
+ lexer->debugging_p = false;
+ cp_lexer_debug_stream = NULL;
+}
+
+/* Create a new cp_token_cache, representing a range of tokens. */
+
+static cp_token_cache *
+cp_token_cache_new (cp_token *first, cp_token *last)
+{
+ cp_token_cache *cache = ggc_alloc_cp_token_cache ();
+ cache->first = first;
+ cache->last = last;
+ return cache;
+}
+
+/* Diagnose if #pragma omp declare simd isn't followed immediately
+ by function declaration or definition. */
+
+static inline void
+cp_ensure_no_omp_declare_simd (cp_parser *parser)
+{
+ if (parser->omp_declare_simd && !parser->omp_declare_simd->error_seen)
+ {
+ error ("%<#pragma omp declare simd%> not immediately followed by "
+ "function declaration or definition");
+ parser->omp_declare_simd = NULL;
+ }
+}
+
+/* Finalize #pragma omp declare simd clauses after FNDECL has been parsed,
+ and put that into "omp declare simd" attribute. */
+
+static inline void
+cp_finalize_omp_declare_simd (cp_parser *parser, tree fndecl)
+{
+ if (__builtin_expect (parser->omp_declare_simd != NULL, 0))
+ {
+ if (fndecl == error_mark_node)
+ {
+ parser->omp_declare_simd = NULL;
+ return;
+ }
+ if (TREE_CODE (fndecl) != FUNCTION_DECL)
+ {
+ cp_ensure_no_omp_declare_simd (parser);
+ return;
+ }
+ }
+}
+
+/* Decl-specifiers. */
+
+/* Set *DECL_SPECS to represent an empty decl-specifier-seq. */
+
+static void
+clear_decl_specs (cp_decl_specifier_seq *decl_specs)
+{
+ memset (decl_specs, 0, sizeof (cp_decl_specifier_seq));
+}
+
+/* Declarators. */
+
+/* Nothing other than the parser should be creating declarators;
+ declarators are a semi-syntactic representation of C++ entities.
+ Other parts of the front end that need to create entities (like
+ VAR_DECLs or FUNCTION_DECLs) should do that directly. */
+
+static cp_declarator *make_call_declarator
+ (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, cp_ref_qualifier, tree, tree);
+static cp_declarator *make_array_declarator
+ (cp_declarator *, tree);
+static cp_declarator *make_pointer_declarator
+ (cp_cv_quals, cp_declarator *, tree);
+static cp_declarator *make_reference_declarator
+ (cp_cv_quals, cp_declarator *, bool, tree);
+static cp_parameter_declarator *make_parameter_declarator
+ (cp_decl_specifier_seq *, cp_declarator *, tree);
+static cp_declarator *make_ptrmem_declarator
+ (cp_cv_quals, tree, cp_declarator *, tree);
+
+/* An erroneous declarator. */
+static cp_declarator *cp_error_declarator;
+
+/* The obstack on which declarators and related data structures are
+ allocated. */
+static struct obstack declarator_obstack;
+
+/* Alloc BYTES from the declarator memory pool. */
+
+static inline void *
+alloc_declarator (size_t bytes)
+{
+ return obstack_alloc (&declarator_obstack, bytes);
+}
+
+/* Allocate a declarator of the indicated KIND. Clear fields that are
+ common to all declarators. */
+
+static cp_declarator *
+make_declarator (cp_declarator_kind kind)
+{
+ cp_declarator *declarator;
+
+ declarator = (cp_declarator *) alloc_declarator (sizeof (cp_declarator));
+ declarator->kind = kind;
+ declarator->attributes = NULL_TREE;
+ declarator->std_attributes = NULL_TREE;
+ declarator->declarator = NULL;
+ declarator->parameter_pack_p = false;
+ declarator->id_loc = UNKNOWN_LOCATION;
+
+ return declarator;
+}
+
+/* Make a declarator for a generalized identifier. If
+ QUALIFYING_SCOPE is non-NULL, the identifier is
+ QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is just
+ UNQUALIFIED_NAME. SFK indicates the kind of special function this
+ is, if any. */
+
+static cp_declarator *
+make_id_declarator (tree qualifying_scope, tree unqualified_name,
+ special_function_kind sfk)
+{
+ cp_declarator *declarator;
+
+ /* It is valid to write:
+
+ class C { void f(); };
+ typedef C D;
+ void D::f();
+
+ The standard is not clear about whether `typedef const C D' is
+ legal; as of 2002-09-15 the committee is considering that
+ question. EDG 3.0 allows that syntax. Therefore, we do as
+ well. */
+ if (qualifying_scope && TYPE_P (qualifying_scope))
+ qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope);
+
+ gcc_assert (identifier_p (unqualified_name)
+ || TREE_CODE (unqualified_name) == BIT_NOT_EXPR
+ || TREE_CODE (unqualified_name) == TEMPLATE_ID_EXPR);
+
+ declarator = make_declarator (cdk_id);
+ declarator->u.id.qualifying_scope = qualifying_scope;
+ declarator->u.id.unqualified_name = unqualified_name;
+ declarator->u.id.sfk = sfk;
+
+ return declarator;
+}
+
+/* Make a declarator for a pointer to TARGET. CV_QUALIFIERS is a list
+ of modifiers such as const or volatile to apply to the pointer
+ type, represented as identifiers. ATTRIBUTES represent the attributes that
+ appertain to the pointer or reference. */
+
+cp_declarator *
+make_pointer_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target,
+ tree attributes)
+{
+ cp_declarator *declarator;
+
+ declarator = make_declarator (cdk_pointer);
+ declarator->declarator = target;
+ declarator->u.pointer.qualifiers = cv_qualifiers;
+ declarator->u.pointer.class_type = NULL_TREE;
+ if (target)
+ {
+ declarator->id_loc = target->id_loc;
+ declarator->parameter_pack_p = target->parameter_pack_p;
+ target->parameter_pack_p = false;
+ }
+ else
+ declarator->parameter_pack_p = false;
+
+ declarator->std_attributes = attributes;
+
+ return declarator;
+}
+
+/* Like make_pointer_declarator -- but for references. ATTRIBUTES
+ represent the attributes that appertain to the pointer or
+ reference. */
+
+cp_declarator *
+make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target,
+ bool rvalue_ref, tree attributes)
+{
+ cp_declarator *declarator;
+
+ declarator = make_declarator (cdk_reference);
+ declarator->declarator = target;
+ declarator->u.reference.qualifiers = cv_qualifiers;
+ declarator->u.reference.rvalue_ref = rvalue_ref;
+ if (target)
+ {
+ declarator->id_loc = target->id_loc;
+ declarator->parameter_pack_p = target->parameter_pack_p;
+ target->parameter_pack_p = false;
+ }
+ else
+ declarator->parameter_pack_p = false;
+
+ declarator->std_attributes = attributes;
+
+ return declarator;
+}
+
+/* Like make_pointer_declarator -- but for a pointer to a non-static
+ member of CLASS_TYPE. ATTRIBUTES represent the attributes that
+ appertain to the pointer or reference. */
+
+cp_declarator *
+make_ptrmem_declarator (cp_cv_quals cv_qualifiers, tree class_type,
+ cp_declarator *pointee,
+ tree attributes)
+{
+ cp_declarator *declarator;
+
+ declarator = make_declarator (cdk_ptrmem);
+ declarator->declarator = pointee;
+ declarator->u.pointer.qualifiers = cv_qualifiers;
+ declarator->u.pointer.class_type = class_type;
+
+ if (pointee)
+ {
+ declarator->parameter_pack_p = pointee->parameter_pack_p;
+ pointee->parameter_pack_p = false;
+ }
+ else
+ declarator->parameter_pack_p = false;
+
+ declarator->std_attributes = attributes;
+
+ return declarator;
+}
+
+/* Make a declarator for the function given by TARGET, with the
+ indicated PARMS. The CV_QUALIFIERS aply to the function, as in
+ "const"-qualified member function. The EXCEPTION_SPECIFICATION
+ indicates what exceptions can be thrown. */
+
+cp_declarator *
+make_call_declarator (cp_declarator *target,
+ tree parms,
+ cp_cv_quals cv_qualifiers,
+ cp_virt_specifiers virt_specifiers,
+ cp_ref_qualifier ref_qualifier,
+ tree exception_specification,
+ tree late_return_type)
+{
+ cp_declarator *declarator;
+
+ declarator = make_declarator (cdk_function);
+ declarator->declarator = target;
+ declarator->u.function.parameters = parms;
+ declarator->u.function.qualifiers = cv_qualifiers;
+ declarator->u.function.virt_specifiers = virt_specifiers;
+ declarator->u.function.ref_qualifier = ref_qualifier;
+ declarator->u.function.exception_specification = exception_specification;
+ declarator->u.function.late_return_type = late_return_type;
+ if (target)
+ {
+ declarator->id_loc = target->id_loc;
+ declarator->parameter_pack_p = target->parameter_pack_p;
+ target->parameter_pack_p = false;
+ }
+ else
+ declarator->parameter_pack_p = false;
+
+ return declarator;
+}
+
+/* Make a declarator for an array of BOUNDS elements, each of which is
+ defined by ELEMENT. */
+
+cp_declarator *
+make_array_declarator (cp_declarator *element, tree bounds)
+{
+ cp_declarator *declarator;
+
+ declarator = make_declarator (cdk_array);
+ declarator->declarator = element;
+ declarator->u.array.bounds = bounds;
+ if (element)
+ {
+ declarator->id_loc = element->id_loc;
+ declarator->parameter_pack_p = element->parameter_pack_p;
+ element->parameter_pack_p = false;
+ }
+ else
+ declarator->parameter_pack_p = false;
+
+ return declarator;
+}
+
+/* Determine whether the declarator we've seen so far can be a
+ parameter pack, when followed by an ellipsis. */
+static bool
+declarator_can_be_parameter_pack (cp_declarator *declarator)
+{
+ /* Search for a declarator name, or any other declarator that goes
+ after the point where the ellipsis could appear in a parameter
+ pack. If we find any of these, then this declarator can not be
+ made into a parameter pack. */
+ bool found = false;
+ while (declarator && !found)
+ {
+ switch ((int)declarator->kind)
+ {
+ case cdk_id:
+ case cdk_array:
+ found = true;
+ break;
+
+ case cdk_error:
+ return true;
+
+ default:
+ declarator = declarator->declarator;
+ break;
+ }
+ }
+
+ return !found;
+}
+
+cp_parameter_declarator *no_parameters;
+
+/* Create a parameter declarator with the indicated DECL_SPECIFIERS,
+ DECLARATOR and DEFAULT_ARGUMENT. */
+
+cp_parameter_declarator *
+make_parameter_declarator (cp_decl_specifier_seq *decl_specifiers,
+ cp_declarator *declarator,
+ tree default_argument)
+{
+ cp_parameter_declarator *parameter;
+
+ parameter = ((cp_parameter_declarator *)
+ alloc_declarator (sizeof (cp_parameter_declarator)));
+ parameter->next = NULL;
+ if (decl_specifiers)
+ parameter->decl_specifiers = *decl_specifiers;
+ else
+ clear_decl_specs (&parameter->decl_specifiers);
+ parameter->declarator = declarator;
+ parameter->default_argument = default_argument;
+ parameter->ellipsis_p = false;
+
+ return parameter;
+}
+
+/* Returns true iff DECLARATOR is a declaration for a function. */
+
+static bool
+function_declarator_p (const cp_declarator *declarator)
+{
+ while (declarator)
+ {
+ if (declarator->kind == cdk_function
+ && declarator->declarator->kind == cdk_id)
+ return true;
+ if (declarator->kind == cdk_id
+ || declarator->kind == cdk_error)
+ return false;
+ declarator = declarator->declarator;
+ }
+ return false;
+}
+
+/* The parser. */
+
+/* Overview
+ --------
+
+ A cp_parser parses the token stream as specified by the C++
+ grammar. Its job is purely parsing, not semantic analysis. For
+ example, the parser breaks the token stream into declarators,
+ expressions, statements, and other similar syntactic constructs.
+ It does not check that the types of the expressions on either side
+ of an assignment-statement are compatible, or that a function is
+ not declared with a parameter of type `void'.
+
+ The parser invokes routines elsewhere in the compiler to perform
+ semantic analysis and to build up the abstract syntax tree for the
+ code processed.
+
+ The parser (and the template instantiation code, which is, in a
+ way, a close relative of parsing) are the only parts of the
+ compiler that should be calling push_scope and pop_scope, or
+ related functions. The parser (and template instantiation code)
+ keeps track of what scope is presently active; everything else
+ should simply honor that. (The code that generates static
+ initializers may also need to set the scope, in order to check
+ access control correctly when emitting the initializers.)
+
+ Methodology
+ -----------
+
+ The parser is of the standard recursive-descent variety. Upcoming
+ tokens in the token stream are examined in order to determine which
+ production to use when parsing a non-terminal. Some C++ constructs
+ require arbitrary look ahead to disambiguate. For example, it is
+ impossible, in the general case, to tell whether a statement is an
+ expression or declaration without scanning the entire statement.
+ Therefore, the parser is capable of "parsing tentatively." When the
+ parser is not sure what construct comes next, it enters this mode.
+ Then, while we attempt to parse the construct, the parser queues up
+ error messages, rather than issuing them immediately, and saves the
+ tokens it consumes. If the construct is parsed successfully, the
+ parser "commits", i.e., it issues any queued error messages and
+ the tokens that were being preserved are permanently discarded.
+ If, however, the construct is not parsed successfully, the parser
+ rolls back its state completely so that it can resume parsing using
+ a different alternative.
+
+ Future Improvements
+ -------------------
+
+ The performance of the parser could probably be improved substantially.
+ We could often eliminate the need to parse tentatively by looking ahead
+ a little bit. In some places, this approach might not entirely eliminate
+ the need to parse tentatively, but it might still speed up the average
+ case. */
+
+/* Flags that are passed to some parsing functions. These values can
+ be bitwise-ored together. */
+
+enum
+{
+ /* No flags. */
+ CP_PARSER_FLAGS_NONE = 0x0,
+ /* The construct is optional. If it is not present, then no error
+ should be issued. */
+ CP_PARSER_FLAGS_OPTIONAL = 0x1,
+ /* When parsing a type-specifier, treat user-defined type-names
+ as non-type identifiers. */
+ CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2,
+ /* When parsing a type-specifier, do not try to parse a class-specifier
+ or enum-specifier. */
+ CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS = 0x4,
+ /* When parsing a decl-specifier-seq, only allow type-specifier or
+ constexpr. */
+ CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR = 0x8
+};
+
+/* This type is used for parameters and variables which hold
+ combinations of the above flags. */
+typedef int cp_parser_flags;
+
+/* The different kinds of declarators we want to parse. */
+
+typedef enum cp_parser_declarator_kind
+{
+ /* We want an abstract declarator. */
+ CP_PARSER_DECLARATOR_ABSTRACT,
+ /* We want a named declarator. */
+ CP_PARSER_DECLARATOR_NAMED,
+ /* We don't mind, but the name must be an unqualified-id. */
+ CP_PARSER_DECLARATOR_EITHER
+} cp_parser_declarator_kind;
+
+/* The precedence values used to parse binary expressions. The minimum value
+ of PREC must be 1, because zero is reserved to quickly discriminate
+ binary operators from other tokens. */
+
+enum cp_parser_prec
+{
+ PREC_NOT_OPERATOR,
+ PREC_LOGICAL_OR_EXPRESSION,
+ PREC_LOGICAL_AND_EXPRESSION,
+ PREC_INCLUSIVE_OR_EXPRESSION,
+ PREC_EXCLUSIVE_OR_EXPRESSION,
+ PREC_AND_EXPRESSION,
+ PREC_EQUALITY_EXPRESSION,
+ PREC_RELATIONAL_EXPRESSION,
+ PREC_SHIFT_EXPRESSION,
+ PREC_ADDITIVE_EXPRESSION,
+ PREC_MULTIPLICATIVE_EXPRESSION,
+ PREC_PM_EXPRESSION,
+ NUM_PREC_VALUES = PREC_PM_EXPRESSION
+};
+
+/* A mapping from a token type to a corresponding tree node type, with a
+ precedence value. */
+
+typedef struct cp_parser_binary_operations_map_node
+{
+ /* The token type. */
+ enum cpp_ttype token_type;
+ /* The corresponding tree code. */
+ enum tree_code tree_type;
+ /* The precedence of this operator. */
+ enum cp_parser_prec prec;
+} cp_parser_binary_operations_map_node;
+
+typedef struct cp_parser_expression_stack_entry
+{
+ /* Left hand side of the binary operation we are currently
+ parsing. */
+ tree lhs;
+ /* Original tree code for left hand side, if it was a binary
+ expression itself (used for -Wparentheses). */
+ enum tree_code lhs_type;
+ /* Tree code for the binary operation we are parsing. */
+ enum tree_code tree_type;
+ /* Precedence of the binary operation we are parsing. */
+ enum cp_parser_prec prec;
+ /* Location of the binary operation we are parsing. */
+ location_t loc;
+} cp_parser_expression_stack_entry;
+
+/* The stack for storing partial expressions. We only need NUM_PREC_VALUES
+ entries because precedence levels on the stack are monotonically
+ increasing. */
+typedef struct cp_parser_expression_stack_entry
+ cp_parser_expression_stack[NUM_PREC_VALUES];
+
+/* Prototypes. */
+
+/* Constructors and destructors. */
+
+static cp_parser_context *cp_parser_context_new
+ (cp_parser_context *);
+
+/* Class variables. */
+
+static GTY((deletable)) cp_parser_context* cp_parser_context_free_list;
+
+/* The operator-precedence table used by cp_parser_binary_expression.
+ Transformed into an associative array (binops_by_token) by
+ cp_parser_new. */
+
+static const cp_parser_binary_operations_map_node binops[] = {
+ { CPP_DEREF_STAR, MEMBER_REF, PREC_PM_EXPRESSION },
+ { CPP_DOT_STAR, DOTSTAR_EXPR, PREC_PM_EXPRESSION },
+
+ { CPP_MULT, MULT_EXPR, PREC_MULTIPLICATIVE_EXPRESSION },
+ { CPP_DIV, TRUNC_DIV_EXPR, PREC_MULTIPLICATIVE_EXPRESSION },
+ { CPP_MOD, TRUNC_MOD_EXPR, PREC_MULTIPLICATIVE_EXPRESSION },
+
+ { CPP_PLUS, PLUS_EXPR, PREC_ADDITIVE_EXPRESSION },
+ { CPP_MINUS, MINUS_EXPR, PREC_ADDITIVE_EXPRESSION },
+
+ { CPP_LSHIFT, LSHIFT_EXPR, PREC_SHIFT_EXPRESSION },
+ { CPP_RSHIFT, RSHIFT_EXPR, PREC_SHIFT_EXPRESSION },
+
+ { CPP_LESS, LT_EXPR, PREC_RELATIONAL_EXPRESSION },
+ { CPP_GREATER, GT_EXPR, PREC_RELATIONAL_EXPRESSION },
+ { CPP_LESS_EQ, LE_EXPR, PREC_RELATIONAL_EXPRESSION },
+ { CPP_GREATER_EQ, GE_EXPR, PREC_RELATIONAL_EXPRESSION },
+
+ { CPP_EQ_EQ, EQ_EXPR, PREC_EQUALITY_EXPRESSION },
+ { CPP_NOT_EQ, NE_EXPR, PREC_EQUALITY_EXPRESSION },
+
+ { CPP_AND, BIT_AND_EXPR, PREC_AND_EXPRESSION },
+
+ { CPP_XOR, BIT_XOR_EXPR, PREC_EXCLUSIVE_OR_EXPRESSION },
+
+ { CPP_OR, BIT_IOR_EXPR, PREC_INCLUSIVE_OR_EXPRESSION },
+
+ { CPP_AND_AND, TRUTH_ANDIF_EXPR, PREC_LOGICAL_AND_EXPRESSION },
+
+ { CPP_OR_OR, TRUTH_ORIF_EXPR, PREC_LOGICAL_OR_EXPRESSION }
+};
+
+/* The same as binops, but initialized by cp_parser_new so that
+ binops_by_token[N].token_type == N. Used in cp_parser_binary_expression
+ for speed. */
+static cp_parser_binary_operations_map_node binops_by_token[N_CP_TTYPES];
+
+/* Constructors and destructors. */
+
+/* Construct a new context. The context below this one on the stack
+ is given by NEXT. */
+
+static cp_parser_context *
+cp_parser_context_new (cp_parser_context* next)
+{
+ cp_parser_context *context;
+
+ /* Allocate the storage. */
+ if (cp_parser_context_free_list != NULL)
+ {
+ /* Pull the first entry from the free list. */
+ context = cp_parser_context_free_list;
+ cp_parser_context_free_list = context->next;
+ memset (context, 0, sizeof (*context));
+ }
+ else
+ context = ggc_alloc_cleared_cp_parser_context ();
+
+ /* No errors have occurred yet in this context. */
+ context->status = CP_PARSER_STATUS_KIND_NO_ERROR;
+ /* If this is not the bottommost context, copy information that we
+ need from the previous context. */
+ if (next)
+ {
+ /* If, in the NEXT context, we are parsing an `x->' or `x.'
+ expression, then we are parsing one in this context, too. */
+ context->object_type = next->object_type;
+ /* Thread the stack. */
+ context->next = next;
+ }
+
+ return context;
+}
+
+/* Managing the unparsed function queues. */
+
+#define unparsed_funs_with_default_args \
+ parser->unparsed_queues->last ().funs_with_default_args
+#define unparsed_funs_with_definitions \
+ parser->unparsed_queues->last ().funs_with_definitions
+#define unparsed_nsdmis \
+ parser->unparsed_queues->last ().nsdmis
+
+static void
+push_unparsed_function_queues (cp_parser *parser)
+{
+ cp_unparsed_functions_entry e = {NULL, make_tree_vector (), NULL};
+ vec_safe_push (parser->unparsed_queues, e);
+}
+
+static void
+pop_unparsed_function_queues (cp_parser *parser)
+{
+ release_tree_vector (unparsed_funs_with_definitions);
+ parser->unparsed_queues->pop ();
+}
+
+/* Prototypes. */
+
+/* Constructors and destructors. */
+
+static cp_parser *cp_parser_new
+ (void);
+
+/* Routines to parse various constructs.
+
+ Those that return `tree' will return the error_mark_node (rather
+ than NULL_TREE) if a parse error occurs, unless otherwise noted.
+ Sometimes, they will return an ordinary node if error-recovery was
+ attempted, even though a parse error occurred. So, to check
+ whether or not a parse error occurred, you should always use
+ cp_parser_error_occurred. If the construct is optional (indicated
+ either by an `_opt' in the name of the function that does the
+ parsing or via a FLAGS parameter), then NULL_TREE is returned if
+ the construct is not present. */
+
+/* Lexical conventions [gram.lex] */
+
+static tree cp_parser_identifier
+ (cp_parser *);
+static tree cp_parser_string_literal
+ (cp_parser *, bool, bool);
+static tree cp_parser_userdef_char_literal
+ (cp_parser *);
+static tree cp_parser_userdef_string_literal
+ (cp_token *);
+static tree cp_parser_userdef_numeric_literal
+ (cp_parser *);
+
+/* Basic concepts [gram.basic] */
+
+static bool cp_parser_translation_unit
+ (cp_parser *);
+
+/* Expressions [gram.expr] */
+
+static tree cp_parser_primary_expression
+ (cp_parser *, bool, bool, bool, cp_id_kind *);
+static tree cp_parser_id_expression
+ (cp_parser *, bool, bool, bool *, bool, bool);
+static tree cp_parser_unqualified_id
+ (cp_parser *, bool, bool, bool, bool);
+static tree cp_parser_nested_name_specifier_opt
+ (cp_parser *, bool, bool, bool, bool);
+static tree cp_parser_nested_name_specifier
+ (cp_parser *, bool, bool, bool, bool);
+static tree cp_parser_qualifying_entity
+ (cp_parser *, bool, bool, bool, bool, bool);
+static tree cp_parser_postfix_expression
+ (cp_parser *, bool, bool, bool, bool, cp_id_kind *);
+static tree cp_parser_postfix_open_square_expression
+ (cp_parser *, tree, bool, bool);
+static tree cp_parser_postfix_dot_deref_expression
+ (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
+static vec<tree, va_gc> *cp_parser_parenthesized_expression_list
+ (cp_parser *, int, bool, bool, bool *);
+/* Values for the second parameter of cp_parser_parenthesized_expression_list. */
+enum { non_attr = 0, normal_attr = 1, id_attr = 2 };
+static void cp_parser_pseudo_destructor_name
+ (cp_parser *, tree, tree *, tree *);
+static tree cp_parser_unary_expression
+ (cp_parser *, bool, bool, cp_id_kind *);
+static enum tree_code cp_parser_unary_operator
+ (cp_token *);
+static tree cp_parser_new_expression
+ (cp_parser *);
+static vec<tree, va_gc> *cp_parser_new_placement
+ (cp_parser *);
+static tree cp_parser_new_type_id
+ (cp_parser *, tree *);
+static cp_declarator *cp_parser_new_declarator_opt
+ (cp_parser *);
+static cp_declarator *cp_parser_direct_new_declarator
+ (cp_parser *);
+static vec<tree, va_gc> *cp_parser_new_initializer
+ (cp_parser *);
+static tree cp_parser_delete_expression
+ (cp_parser *);
+static tree cp_parser_cast_expression
+ (cp_parser *, bool, bool, bool, cp_id_kind *);
+static tree cp_parser_binary_expression
+ (cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *);
+static tree cp_parser_question_colon_clause
+ (cp_parser *, tree);
+static tree cp_parser_assignment_expression
+ (cp_parser *, bool, cp_id_kind *);
+static enum tree_code cp_parser_assignment_operator_opt
+ (cp_parser *);
+static tree cp_parser_expression
+ (cp_parser *, bool, cp_id_kind *);
+static tree cp_parser_expression
+ (cp_parser *, bool, bool, cp_id_kind *);
+static tree cp_parser_constant_expression
+ (cp_parser *, bool, bool *);
+static tree cp_parser_builtin_offsetof
+ (cp_parser *);
+static tree cp_parser_lambda_expression
+ (cp_parser *);
+static void cp_parser_lambda_introducer
+ (cp_parser *, tree);
+static bool cp_parser_lambda_declarator_opt
+ (cp_parser *, tree);
+static void cp_parser_lambda_body
+ (cp_parser *, tree);
+
+/* Statements [gram.stmt.stmt] */
+
+static void cp_parser_statement
+ (cp_parser *, tree, bool, bool *);
+static void cp_parser_label_for_labeled_statement
+(cp_parser *, tree);
+static tree cp_parser_expression_statement
+ (cp_parser *, tree);
+static tree cp_parser_compound_statement
+ (cp_parser *, tree, bool, bool);
+static void cp_parser_statement_seq_opt
+ (cp_parser *, tree);
+static tree cp_parser_selection_statement
+ (cp_parser *, bool *);
+static tree cp_parser_condition
+ (cp_parser *);
+static tree cp_parser_iteration_statement
+ (cp_parser *, bool);
+static bool cp_parser_for_init_statement
+ (cp_parser *, tree *decl);
+static tree cp_parser_for
+ (cp_parser *, bool);
+static tree cp_parser_c_for
+ (cp_parser *, tree, tree, bool);
+static tree cp_parser_range_for
+ (cp_parser *, tree, tree, tree, bool);
+static void do_range_for_auto_deduction
+ (tree, tree);
+static tree cp_parser_perform_range_for_lookup
+ (tree, tree *, tree *);
+static tree cp_parser_range_for_member_function
+ (tree, tree);
+static tree cp_parser_jump_statement
+ (cp_parser *);
+static void cp_parser_declaration_statement
+ (cp_parser *);
+
+static tree cp_parser_implicitly_scoped_statement
+ (cp_parser *, bool *);
+static void cp_parser_already_scoped_statement
+ (cp_parser *);
+
+/* Declarations [gram.dcl.dcl] */
+
+static void cp_parser_declaration_seq_opt
+ (cp_parser *);
+static void cp_parser_declaration
+ (cp_parser *);
+static void cp_parser_block_declaration
+ (cp_parser *, bool);
+static void cp_parser_simple_declaration
+ (cp_parser *, bool, tree *);
+static void cp_parser_decl_specifier_seq
+ (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, int *);
+static tree cp_parser_storage_class_specifier_opt
+ (cp_parser *);
+static tree cp_parser_function_specifier_opt
+ (cp_parser *, cp_decl_specifier_seq *);
+static tree cp_parser_type_specifier
+ (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, bool,
+ int *, bool *);
+static tree cp_parser_simple_type_specifier
+ (cp_parser *, cp_decl_specifier_seq *, cp_parser_flags);
+static tree cp_parser_type_name
+ (cp_parser *);
+static tree cp_parser_nonclass_name
+ (cp_parser* parser);
+static tree cp_parser_elaborated_type_specifier
+ (cp_parser *, bool, bool);
+static tree cp_parser_enum_specifier
+ (cp_parser *);
+static void cp_parser_enumerator_list
+ (cp_parser *, tree);
+static void cp_parser_enumerator_definition
+ (cp_parser *, tree);
+static tree cp_parser_namespace_name
+ (cp_parser *);
+static void cp_parser_namespace_definition
+ (cp_parser *);
+static void cp_parser_namespace_body
+ (cp_parser *);
+static tree cp_parser_qualified_namespace_specifier
+ (cp_parser *);
+static void cp_parser_namespace_alias_definition
+ (cp_parser *);
+static bool cp_parser_using_declaration
+ (cp_parser *, bool);
+static void cp_parser_using_directive
+ (cp_parser *);
+static tree cp_parser_alias_declaration
+ (cp_parser *);
+static void cp_parser_asm_definition
+ (cp_parser *);
+static void cp_parser_linkage_specification
+ (cp_parser *);
+static void cp_parser_static_assert
+ (cp_parser *, bool);
+static tree cp_parser_decltype
+ (cp_parser *);
+
+/* Declarators [gram.dcl.decl] */
+
+static tree cp_parser_init_declarator
+ (cp_parser *, cp_decl_specifier_seq *, vec<deferred_access_check, va_gc> *, bool, bool, int, bool *, tree *);
+static cp_declarator *cp_parser_declarator
+ (cp_parser *, cp_parser_declarator_kind, int *, bool *, bool);
+static cp_declarator *cp_parser_direct_declarator
+ (cp_parser *, cp_parser_declarator_kind, int *, bool);
+static enum tree_code cp_parser_ptr_operator
+ (cp_parser *, tree *, cp_cv_quals *, tree *);
+static cp_cv_quals cp_parser_cv_qualifier_seq_opt
+ (cp_parser *);
+static cp_virt_specifiers cp_parser_virt_specifier_seq_opt
+ (cp_parser *);
+static cp_ref_qualifier cp_parser_ref_qualifier_opt
+ (cp_parser *);
+static tree cp_parser_late_return_type_opt
+ (cp_parser *, cp_declarator *, cp_cv_quals);
+static tree cp_parser_declarator_id
+ (cp_parser *, bool);
+static tree cp_parser_type_id
+ (cp_parser *);
+static tree cp_parser_template_type_arg
+ (cp_parser *);
+static tree cp_parser_trailing_type_id (cp_parser *);
+static tree cp_parser_type_id_1
+ (cp_parser *, bool, bool);
+static void cp_parser_type_specifier_seq
+ (cp_parser *, bool, bool, cp_decl_specifier_seq *);
+static tree cp_parser_parameter_declaration_clause
+ (cp_parser *);
+static tree cp_parser_parameter_declaration_list
+ (cp_parser *, bool *);
+static cp_parameter_declarator *cp_parser_parameter_declaration
+ (cp_parser *, bool, bool *);
+static tree cp_parser_default_argument
+ (cp_parser *, bool);
+static void cp_parser_function_body
+ (cp_parser *, bool);
+static tree cp_parser_initializer
+ (cp_parser *, bool *, bool *);
+static tree cp_parser_initializer_clause
+ (cp_parser *, bool *);
+static tree cp_parser_braced_list
+ (cp_parser*, bool*);
+static vec<constructor_elt, va_gc> *cp_parser_initializer_list
+ (cp_parser *, bool *);
+
+static bool cp_parser_ctor_initializer_opt_and_function_body
+ (cp_parser *, bool);
+
+static tree cp_parser_late_parsing_omp_declare_simd
+ (cp_parser *, tree);
+
+static tree cp_parser_late_parsing_cilk_simd_fn_info
+ (cp_parser *, tree);
+
+static tree synthesize_implicit_template_parm
+ (cp_parser *);
+static tree finish_fully_implicit_template
+ (cp_parser *, tree);
+
+/* Classes [gram.class] */
+
+static tree cp_parser_class_name
+ (cp_parser *, bool, bool, enum tag_types, bool, bool, bool);
+static tree cp_parser_class_specifier
+ (cp_parser *);
+static tree cp_parser_class_head
+ (cp_parser *, bool *);
+static enum tag_types cp_parser_class_key
+ (cp_parser *);
+static void cp_parser_member_specification_opt
+ (cp_parser *);
+static void cp_parser_member_declaration
+ (cp_parser *);
+static tree cp_parser_pure_specifier
+ (cp_parser *);
+static tree cp_parser_constant_initializer
+ (cp_parser *);
+
+/* Derived classes [gram.class.derived] */
+
+static tree cp_parser_base_clause
+ (cp_parser *);
+static tree cp_parser_base_specifier
+ (cp_parser *);
+
+/* Special member functions [gram.special] */
+
+static tree cp_parser_conversion_function_id
+ (cp_parser *);
+static tree cp_parser_conversion_type_id
+ (cp_parser *);
+static cp_declarator *cp_parser_conversion_declarator_opt
+ (cp_parser *);
+static bool cp_parser_ctor_initializer_opt
+ (cp_parser *);
+static void cp_parser_mem_initializer_list
+ (cp_parser *);
+static tree cp_parser_mem_initializer
+ (cp_parser *);
+static tree cp_parser_mem_initializer_id
+ (cp_parser *);
+
+/* Overloading [gram.over] */
+
+static tree cp_parser_operator_function_id
+ (cp_parser *);
+static tree cp_parser_operator
+ (cp_parser *);
+
+/* Templates [gram.temp] */
+
+static void cp_parser_template_declaration
+ (cp_parser *, bool);
+static tree cp_parser_template_parameter_list
+ (cp_parser *);
+static tree cp_parser_template_parameter
+ (cp_parser *, bool *, bool *);
+static tree cp_parser_type_parameter
+ (cp_parser *, bool *);
+static tree cp_parser_template_id
+ (cp_parser *, bool, bool, enum tag_types, bool);
+static tree cp_parser_template_name
+ (cp_parser *, bool, bool, bool, enum tag_types, bool *);
+static tree cp_parser_template_argument_list
+ (cp_parser *);
+static tree cp_parser_template_argument
+ (cp_parser *);
+static void cp_parser_explicit_instantiation
+ (cp_parser *);
+static void cp_parser_explicit_specialization
+ (cp_parser *);
+
+/* Exception handling [gram.exception] */
+
+static tree cp_parser_try_block
+ (cp_parser *);
+static bool cp_parser_function_try_block
+ (cp_parser *);
+static void cp_parser_handler_seq
+ (cp_parser *);
+static void cp_parser_handler
+ (cp_parser *);
+static tree cp_parser_exception_declaration
+ (cp_parser *);
+static tree cp_parser_throw_expression
+ (cp_parser *);
+static tree cp_parser_exception_specification_opt
+ (cp_parser *);
+static tree cp_parser_type_id_list
+ (cp_parser *);
+
+/* GNU Extensions */
+
+static tree cp_parser_asm_specification_opt
+ (cp_parser *);
+static tree cp_parser_asm_operand_list
+ (cp_parser *);
+static tree cp_parser_asm_clobber_list
+ (cp_parser *);
+static tree cp_parser_asm_label_list
+ (cp_parser *);
+static bool cp_next_tokens_can_be_attribute_p
+ (cp_parser *);
+static bool cp_next_tokens_can_be_gnu_attribute_p
+ (cp_parser *);
+static bool cp_next_tokens_can_be_std_attribute_p
+ (cp_parser *);
+static bool cp_nth_tokens_can_be_std_attribute_p
+ (cp_parser *, size_t);
+static bool cp_nth_tokens_can_be_gnu_attribute_p
+ (cp_parser *, size_t);
+static bool cp_nth_tokens_can_be_attribute_p
+ (cp_parser *, size_t);
+static tree cp_parser_attributes_opt
+ (cp_parser *);
+static tree cp_parser_gnu_attributes_opt
+ (cp_parser *);
+static tree cp_parser_gnu_attribute_list
+ (cp_parser *);
+static tree cp_parser_std_attribute
+ (cp_parser *);
+static tree cp_parser_std_attribute_spec
+ (cp_parser *);
+static tree cp_parser_std_attribute_spec_seq
+ (cp_parser *);
+static bool cp_parser_extension_opt
+ (cp_parser *, int *);
+static void cp_parser_label_declaration
+ (cp_parser *);
+
+/* Transactional Memory Extensions */
+
+static tree cp_parser_transaction
+ (cp_parser *, enum rid);
+static tree cp_parser_transaction_expression
+ (cp_parser *, enum rid);
+static bool cp_parser_function_transaction
+ (cp_parser *, enum rid);
+static tree cp_parser_transaction_cancel
+ (cp_parser *);
+
+enum pragma_context {
+ pragma_external,
+ pragma_member,
+ pragma_objc_icode,
+ pragma_stmt,
+ pragma_compound
+};
+static bool cp_parser_pragma
+ (cp_parser *, enum pragma_context);
+
+/* Objective-C++ Productions */
+
+static tree cp_parser_objc_message_receiver
+ (cp_parser *);
+static tree cp_parser_objc_message_args
+ (cp_parser *);
+static tree cp_parser_objc_message_expression
+ (cp_parser *);
+static tree cp_parser_objc_encode_expression
+ (cp_parser *);
+static tree cp_parser_objc_defs_expression
+ (cp_parser *);
+static tree cp_parser_objc_protocol_expression
+ (cp_parser *);
+static tree cp_parser_objc_selector_expression
+ (cp_parser *);
+static tree cp_parser_objc_expression
+ (cp_parser *);
+static bool cp_parser_objc_selector_p
+ (enum cpp_ttype);
+static tree cp_parser_objc_selector
+ (cp_parser *);
+static tree cp_parser_objc_protocol_refs_opt
+ (cp_parser *);
+static void cp_parser_objc_declaration
+ (cp_parser *, tree);
+static tree cp_parser_objc_statement
+ (cp_parser *);
+static bool cp_parser_objc_valid_prefix_attributes
+ (cp_parser *, tree *);
+static void cp_parser_objc_at_property_declaration
+ (cp_parser *) ;
+static void cp_parser_objc_at_synthesize_declaration
+ (cp_parser *) ;
+static void cp_parser_objc_at_dynamic_declaration
+ (cp_parser *) ;
+static tree cp_parser_objc_struct_declaration
+ (cp_parser *) ;
+
+/* Utility Routines */
+
+static tree cp_parser_lookup_name
+ (cp_parser *, tree, enum tag_types, bool, bool, bool, tree *, location_t);
+static tree cp_parser_lookup_name_simple
+ (cp_parser *, tree, location_t);
+static tree cp_parser_maybe_treat_template_as_class
+ (tree, bool);
+static bool cp_parser_check_declarator_template_parameters
+ (cp_parser *, cp_declarator *, location_t);
+static bool cp_parser_check_template_parameters
+ (cp_parser *, unsigned, location_t, cp_declarator *);
+static tree cp_parser_simple_cast_expression
+ (cp_parser *);
+static tree cp_parser_global_scope_opt
+ (cp_parser *, bool);
+static bool cp_parser_constructor_declarator_p
+ (cp_parser *, bool);
+static tree cp_parser_function_definition_from_specifiers_and_declarator
+ (cp_parser *, cp_decl_specifier_seq *, tree, const cp_declarator *);
+static tree cp_parser_function_definition_after_declarator
+ (cp_parser *, bool);
+static void cp_parser_template_declaration_after_export
+ (cp_parser *, bool);
+static void cp_parser_perform_template_parameter_access_checks
+ (vec<deferred_access_check, va_gc> *);
+static tree cp_parser_single_declaration
+ (cp_parser *, vec<deferred_access_check, va_gc> *, bool, bool, bool *);
+static tree cp_parser_functional_cast
+ (cp_parser *, tree);
+static tree cp_parser_save_member_function_body
+ (cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree);
+static tree cp_parser_save_nsdmi
+ (cp_parser *);
+static tree cp_parser_enclosed_template_argument_list
+ (cp_parser *);
+static void cp_parser_save_default_args
+ (cp_parser *, tree);
+static void cp_parser_late_parsing_for_member
+ (cp_parser *, tree);
+static tree cp_parser_late_parse_one_default_arg
+ (cp_parser *, tree, tree, tree);
+static void cp_parser_late_parsing_nsdmi
+ (cp_parser *, tree);
+static void cp_parser_late_parsing_default_args
+ (cp_parser *, tree);
+static tree cp_parser_sizeof_operand
+ (cp_parser *, enum rid);
+static tree cp_parser_trait_expr
+ (cp_parser *, enum rid);
+static bool cp_parser_declares_only_class_p
+ (cp_parser *);
+static void cp_parser_set_storage_class
+ (cp_parser *, cp_decl_specifier_seq *, enum rid, cp_token *);
+static void cp_parser_set_decl_spec_type
+ (cp_decl_specifier_seq *, tree, cp_token *, bool);
+static void set_and_check_decl_spec_loc
+ (cp_decl_specifier_seq *decl_specs,
+ cp_decl_spec ds, cp_token *);
+static bool cp_parser_friend_p
+ (const cp_decl_specifier_seq *);
+static void cp_parser_required_error
+ (cp_parser *, required_token, bool);
+static cp_token *cp_parser_require
+ (cp_parser *, enum cpp_ttype, required_token);
+static cp_token *cp_parser_require_keyword
+ (cp_parser *, enum rid, required_token);
+static bool cp_parser_token_starts_function_definition_p
+ (cp_token *);
+static bool cp_parser_next_token_starts_class_definition_p
+ (cp_parser *);
+static bool cp_parser_next_token_ends_template_argument_p
+ (cp_parser *);
+static bool cp_parser_nth_token_starts_template_argument_list_p
+ (cp_parser *, size_t);
+static enum tag_types cp_parser_token_is_class_key
+ (cp_token *);
+static void cp_parser_check_class_key
+ (enum tag_types, tree type);
+static void cp_parser_check_access_in_redeclaration
+ (tree type, location_t location);
+static bool cp_parser_optional_template_keyword
+ (cp_parser *);
+static void cp_parser_pre_parsed_nested_name_specifier
+ (cp_parser *);
+static bool cp_parser_cache_group
+ (cp_parser *, enum cpp_ttype, unsigned);
+static tree cp_parser_cache_defarg
+ (cp_parser *parser, bool nsdmi);
+static void cp_parser_parse_tentatively
+ (cp_parser *);
+static void cp_parser_commit_to_tentative_parse
+ (cp_parser *);
+static void cp_parser_commit_to_topmost_tentative_parse
+ (cp_parser *);
+static void cp_parser_abort_tentative_parse
+ (cp_parser *);
+static bool cp_parser_parse_definitely
+ (cp_parser *);
+static inline bool cp_parser_parsing_tentatively
+ (cp_parser *);
+static bool cp_parser_uncommitted_to_tentative_parse_p
+ (cp_parser *);
+static void cp_parser_error
+ (cp_parser *, const char *);
+static void cp_parser_name_lookup_error
+ (cp_parser *, tree, tree, name_lookup_error, location_t);
+static bool cp_parser_simulate_error
+ (cp_parser *);
+static bool cp_parser_check_type_definition
+ (cp_parser *);
+static void cp_parser_check_for_definition_in_return_type
+ (cp_declarator *, tree, location_t type_location);
+static void cp_parser_check_for_invalid_template_id
+ (cp_parser *, tree, enum tag_types, location_t location);
+static bool cp_parser_non_integral_constant_expression
+ (cp_parser *, non_integral_constant);
+static void cp_parser_diagnose_invalid_type_name
+ (cp_parser *, tree, tree, location_t);
+static bool cp_parser_parse_and_diagnose_invalid_type_name
+ (cp_parser *);
+static int cp_parser_skip_to_closing_parenthesis
+ (cp_parser *, bool, bool, bool);
+static void cp_parser_skip_to_end_of_statement
+ (cp_parser *);
+static void cp_parser_consume_semicolon_at_end_of_statement
+ (cp_parser *);
+static void cp_parser_skip_to_end_of_block_or_statement
+ (cp_parser *);
+static bool cp_parser_skip_to_closing_brace
+ (cp_parser *);
+static void cp_parser_skip_to_end_of_template_parameter_list
+ (cp_parser *);
+static void cp_parser_skip_to_pragma_eol
+ (cp_parser*, cp_token *);
+static bool cp_parser_error_occurred
+ (cp_parser *);
+static bool cp_parser_allow_gnu_extensions_p
+ (cp_parser *);
+static bool cp_parser_is_pure_string_literal
+ (cp_token *);
+static bool cp_parser_is_string_literal
+ (cp_token *);
+static bool cp_parser_is_keyword
+ (cp_token *, enum rid);
+static tree cp_parser_make_typename_type
+ (cp_parser *, tree, tree, location_t location);
+static cp_declarator * cp_parser_make_indirect_declarator
+ (enum tree_code, tree, cp_cv_quals, cp_declarator *, tree);
+
+/* Returns nonzero if we are parsing tentatively. */
+
+static inline bool
+cp_parser_parsing_tentatively (cp_parser* parser)
+{
+ return parser->context->next != NULL;
+}
+
+/* Returns nonzero if TOKEN is a string literal. */
+
+static bool
+cp_parser_is_pure_string_literal (cp_token* token)
+{
+ return (token->type == CPP_STRING ||
+ token->type == CPP_STRING16 ||
+ token->type == CPP_STRING32 ||
+ token->type == CPP_WSTRING ||
+ token->type == CPP_UTF8STRING);
+}
+
+/* Returns nonzero if TOKEN is a string literal
+ of a user-defined string literal. */
+
+static bool
+cp_parser_is_string_literal (cp_token* token)
+{
+ return (cp_parser_is_pure_string_literal (token) ||
+ token->type == CPP_STRING_USERDEF ||
+ token->type == CPP_STRING16_USERDEF ||
+ token->type == CPP_STRING32_USERDEF ||
+ token->type == CPP_WSTRING_USERDEF ||
+ token->type == CPP_UTF8STRING_USERDEF);
+}
+
+/* Returns nonzero if TOKEN is the indicated KEYWORD. */
+
+static bool
+cp_parser_is_keyword (cp_token* token, enum rid keyword)
+{
+ return token->keyword == keyword;
+}
+
+/* If not parsing tentatively, issue a diagnostic of the form
+ FILE:LINE: MESSAGE before TOKEN
+ where TOKEN is the next token in the input stream. MESSAGE
+ (specified by the caller) is usually of the form "expected
+ OTHER-TOKEN". */
+
+static void
+cp_parser_error (cp_parser* parser, const char* gmsgid)
+{
+ if (!cp_parser_simulate_error (parser))
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ /* This diagnostic makes more sense if it is tagged to the line
+ of the token we just peeked at. */
+ cp_lexer_set_source_position_from_token (token);
+
+ if (token->type == CPP_PRAGMA)
+ {
+ error_at (token->location,
+ "%<#pragma%> is not allowed here");
+ cp_parser_skip_to_pragma_eol (parser, token);
+ return;
+ }
+
+ c_parse_error (gmsgid,
+ /* Because c_parser_error does not understand
+ CPP_KEYWORD, keywords are treated like
+ identifiers. */
+ (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
+ token->u.value, token->flags);
+ }
+}
+
+/* Issue an error about name-lookup failing. NAME is the
+ IDENTIFIER_NODE DECL is the result of
+ the lookup (as returned from cp_parser_lookup_name). DESIRED is
+ the thing that we hoped to find. */
+
+static void
+cp_parser_name_lookup_error (cp_parser* parser,
+ tree name,
+ tree decl,
+ name_lookup_error desired,
+ location_t location)
+{
+ /* If name lookup completely failed, tell the user that NAME was not
+ declared. */
+ if (decl == error_mark_node)
+ {
+ if (parser->scope && parser->scope != global_namespace)
+ error_at (location, "%<%E::%E%> has not been declared",
+ parser->scope, name);
+ else if (parser->scope == global_namespace)
+ error_at (location, "%<::%E%> has not been declared", name);
+ else if (parser->object_scope
+ && !CLASS_TYPE_P (parser->object_scope))
+ error_at (location, "request for member %qE in non-class type %qT",
+ name, parser->object_scope);
+ else if (parser->object_scope)
+ error_at (location, "%<%T::%E%> has not been declared",
+ parser->object_scope, name);
+ else
+ error_at (location, "%qE has not been declared", name);
+ }
+ else if (parser->scope && parser->scope != global_namespace)
+ {
+ switch (desired)
+ {
+ case NLE_TYPE:
+ error_at (location, "%<%E::%E%> is not a type",
+ parser->scope, name);
+ break;
+ case NLE_CXX98:
+ error_at (location, "%<%E::%E%> is not a class or namespace",
+ parser->scope, name);
+ break;
+ case NLE_NOT_CXX98:
+ error_at (location,
+ "%<%E::%E%> is not a class, namespace, or enumeration",
+ parser->scope, name);
+ break;
+ default:
+ gcc_unreachable ();
+
+ }
+ }
+ else if (parser->scope == global_namespace)
+ {
+ switch (desired)
+ {
+ case NLE_TYPE:
+ error_at (location, "%<::%E%> is not a type", name);
+ break;
+ case NLE_CXX98:
+ error_at (location, "%<::%E%> is not a class or namespace", name);
+ break;
+ case NLE_NOT_CXX98:
+ error_at (location,
+ "%<::%E%> is not a class, namespace, or enumeration",
+ name);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else
+ {
+ switch (desired)
+ {
+ case NLE_TYPE:
+ error_at (location, "%qE is not a type", name);
+ break;
+ case NLE_CXX98:
+ error_at (location, "%qE is not a class or namespace", name);
+ break;
+ case NLE_NOT_CXX98:
+ error_at (location,
+ "%qE is not a class, namespace, or enumeration", name);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+}
+
+/* If we are parsing tentatively, remember that an error has occurred
+ during this tentative parse. Returns true if the error was
+ simulated; false if a message should be issued by the caller. */
+
+static bool
+cp_parser_simulate_error (cp_parser* parser)
+{
+ if (cp_parser_uncommitted_to_tentative_parse_p (parser))
+ {
+ parser->context->status = CP_PARSER_STATUS_KIND_ERROR;
+ return true;
+ }
+ return false;
+}
+
+/* This function is called when a type is defined. If type
+ definitions are forbidden at this point, an error message is
+ issued. */
+
+static bool
+cp_parser_check_type_definition (cp_parser* parser)
+{
+ /* If types are forbidden here, issue a message. */
+ if (parser->type_definition_forbidden_message)
+ {
+ /* Don't use `%s' to print the string, because quotations (`%<', `%>')
+ in the message need to be interpreted. */
+ error (parser->type_definition_forbidden_message);
+ return false;
+ }
+ return true;
+}
+
+/* This function is called when the DECLARATOR is processed. The TYPE
+ was a type defined in the decl-specifiers. If it is invalid to
+ define a type in the decl-specifiers for DECLARATOR, an error is
+ issued. TYPE_LOCATION is the location of TYPE and is used
+ for error reporting. */
+
+static void
+cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
+ tree type, location_t type_location)
+{
+ /* [dcl.fct] forbids type definitions in return types.
+ Unfortunately, it's not easy to know whether or not we are
+ processing a return type until after the fact. */
+ while (declarator
+ && (declarator->kind == cdk_pointer
+ || declarator->kind == cdk_reference
+ || declarator->kind == cdk_ptrmem))
+ declarator = declarator->declarator;
+ if (declarator
+ && declarator->kind == cdk_function)
+ {
+ error_at (type_location,
+ "new types may not be defined in a return type");
+ inform (type_location,
+ "(perhaps a semicolon is missing after the definition of %qT)",
+ type);
+ }
+}
+
+/* A type-specifier (TYPE) has been parsed which cannot be followed by
+ "<" in any valid C++ program. If the next token is indeed "<",
+ issue a message warning the user about what appears to be an
+ invalid attempt to form a template-id. LOCATION is the location
+ of the type-specifier (TYPE) */
+
+static void
+cp_parser_check_for_invalid_template_id (cp_parser* parser,
+ tree type,
+ enum tag_types tag_type,
+ location_t location)
+{
+ cp_token_position start = 0;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+ {
+ if (TYPE_P (type))
+ error_at (location, "%qT is not a template", type);
+ else if (identifier_p (type))
+ {
+ if (tag_type != none_type)
+ error_at (location, "%qE is not a class template", type);
+ else
+ error_at (location, "%qE is not a template", type);
+ }
+ else
+ error_at (location, "invalid template-id");
+ /* Remember the location of the invalid "<". */
+ if (cp_parser_uncommitted_to_tentative_parse_p (parser))
+ start = cp_lexer_token_position (parser->lexer, true);
+ /* Consume the "<". */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the template arguments. */
+ cp_parser_enclosed_template_argument_list (parser);
+ /* Permanently remove the invalid template arguments so that
+ this error message is not issued again. */
+ if (start)
+ cp_lexer_purge_tokens_after (parser->lexer, start);
+ }
+}
+
+/* If parsing an integral constant-expression, issue an error message
+ about the fact that THING appeared and return true. Otherwise,
+ return false. In either case, set
+ PARSER->NON_INTEGRAL_CONSTANT_EXPRESSION_P. */
+
+static bool
+cp_parser_non_integral_constant_expression (cp_parser *parser,
+ non_integral_constant thing)
+{
+ parser->non_integral_constant_expression_p = true;
+ if (parser->integral_constant_expression_p)
+ {
+ if (!parser->allow_non_integral_constant_expression_p)
+ {
+ const char *msg = NULL;
+ switch (thing)
+ {
+ case NIC_FLOAT:
+ error ("floating-point literal "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_CAST:
+ error ("a cast to a type other than an integral or "
+ "enumeration type cannot appear in a "
+ "constant-expression");
+ return true;
+ case NIC_TYPEID:
+ error ("%<typeid%> operator "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_NCC:
+ error ("non-constant compound literals "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_FUNC_CALL:
+ error ("a function call "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_INC:
+ error ("an increment "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_DEC:
+ error ("an decrement "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_ARRAY_REF:
+ error ("an array reference "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_ADDR_LABEL:
+ error ("the address of a label "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_OVERLOADED:
+ error ("calls to overloaded operators "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_ASSIGNMENT:
+ error ("an assignment cannot appear in a constant-expression");
+ return true;
+ case NIC_COMMA:
+ error ("a comma operator "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_CONSTRUCTOR:
+ error ("a call to a constructor "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_TRANSACTION:
+ error ("a transaction expression "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_THIS:
+ msg = "this";
+ break;
+ case NIC_FUNC_NAME:
+ msg = "__FUNCTION__";
+ break;
+ case NIC_PRETTY_FUNC:
+ msg = "__PRETTY_FUNCTION__";
+ break;
+ case NIC_C99_FUNC:
+ msg = "__func__";
+ break;
+ case NIC_VA_ARG:
+ msg = "va_arg";
+ break;
+ case NIC_ARROW:
+ msg = "->";
+ break;
+ case NIC_POINT:
+ msg = ".";
+ break;
+ case NIC_STAR:
+ msg = "*";
+ break;
+ case NIC_ADDR:
+ msg = "&";
+ break;
+ case NIC_PREINCREMENT:
+ msg = "++";
+ break;
+ case NIC_PREDECREMENT:
+ msg = "--";
+ break;
+ case NIC_NEW:
+ msg = "new";
+ break;
+ case NIC_DEL:
+ msg = "delete";
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ if (msg)
+ error ("%qs cannot appear in a constant-expression", msg);
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Emit a diagnostic for an invalid type name. SCOPE is the
+ qualifying scope (or NULL, if none) for ID. This function commits
+ to the current active tentative parse, if any. (Otherwise, the
+ problematic construct might be encountered again later, resulting
+ in duplicate error messages.) LOCATION is the location of ID. */
+
+static void
+cp_parser_diagnose_invalid_type_name (cp_parser *parser,
+ tree scope, tree id,
+ location_t location)
+{
+ tree decl, old_scope;
+ cp_parser_commit_to_tentative_parse (parser);
+ /* Try to lookup the identifier. */
+ old_scope = parser->scope;
+ parser->scope = scope;
+ decl = cp_parser_lookup_name_simple (parser, id, location);
+ parser->scope = old_scope;
+ /* If the lookup found a template-name, it means that the user forgot
+ to specify an argument list. Emit a useful error message. */
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ error_at (location,
+ "invalid use of template-name %qE without an argument list",
+ decl);
+ else if (TREE_CODE (id) == BIT_NOT_EXPR)
+ error_at (location, "invalid use of destructor %qD as a type", id);
+ else if (TREE_CODE (decl) == TYPE_DECL)
+ /* Something like 'unsigned A a;' */
+ error_at (location, "invalid combination of multiple type-specifiers");
+ else if (!parser->scope)
+ {
+ /* Issue an error message. */
+ error_at (location, "%qE does not name a type", id);
+ /* If we're in a template class, it's possible that the user was
+ referring to a type from a base class. For example:
+
+ template <typename T> struct A { typedef T X; };
+ template <typename T> struct B : public A<T> { X x; };
+
+ The user should have said "typename A<T>::X". */
+ if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_CONSTEXPR])
+ inform (location, "C++11 %<constexpr%> only available with "
+ "-std=c++11 or -std=gnu++11");
+ else if (processing_template_decl && current_class_type
+ && TYPE_BINFO (current_class_type))
+ {
+ tree b;
+
+ for (b = TREE_CHAIN (TYPE_BINFO (current_class_type));
+ b;
+ b = TREE_CHAIN (b))
+ {
+ tree base_type = BINFO_TYPE (b);
+ if (CLASS_TYPE_P (base_type)
+ && dependent_type_p (base_type))
+ {
+ tree field;
+ /* Go from a particular instantiation of the
+ template (which will have an empty TYPE_FIELDs),
+ to the main version. */
+ base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type);
+ for (field = TYPE_FIELDS (base_type);
+ field;
+ field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == TYPE_DECL
+ && DECL_NAME (field) == id)
+ {
+ inform (location,
+ "(perhaps %<typename %T::%E%> was intended)",
+ BINFO_TYPE (b), id);
+ break;
+ }
+ if (field)
+ break;
+ }
+ }
+ }
+ }
+ /* Here we diagnose qualified-ids where the scope is actually correct,
+ but the identifier does not resolve to a valid type name. */
+ else if (parser->scope != error_mark_node)
+ {
+ if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
+ {
+ if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+ error_at (location_of (id),
+ "%qE in namespace %qE does not name a template type",
+ id, parser->scope);
+ else
+ error_at (location_of (id),
+ "%qE in namespace %qE does not name a type",
+ id, parser->scope);
+ }
+ else if (CLASS_TYPE_P (parser->scope)
+ && constructor_name_p (id, parser->scope))
+ {
+ /* A<T>::A<T>() */
+ error_at (location, "%<%T::%E%> names the constructor, not"
+ " the type", parser->scope, id);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+ error_at (location, "and %qT has no template constructors",
+ parser->scope);
+ }
+ else if (TYPE_P (parser->scope)
+ && dependent_scope_p (parser->scope))
+ error_at (location, "need %<typename%> before %<%T::%E%> because "
+ "%qT is a dependent scope",
+ parser->scope, id, parser->scope);
+ else if (TYPE_P (parser->scope))
+ {
+ if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+ error_at (location_of (id),
+ "%qE in %q#T does not name a template type",
+ id, parser->scope);
+ else
+ error_at (location_of (id),
+ "%qE in %q#T does not name a type",
+ id, parser->scope);
+ }
+ else
+ gcc_unreachable ();
+ }
+}
+
+/* Check for a common situation where a type-name should be present,
+ but is not, and issue a sensible error message. Returns true if an
+ invalid type-name was detected.
+
+ The situation handled by this function are variable declarations of the
+ form `ID a', where `ID' is an id-expression and `a' is a plain identifier.
+ Usually, `ID' should name a type, but if we got here it means that it
+ does not. We try to emit the best possible error message depending on
+ how exactly the id-expression looks like. */
+
+static bool
+cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
+{
+ tree id;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* Avoid duplicate error about ambiguous lookup. */
+ if (token->type == CPP_NESTED_NAME_SPECIFIER)
+ {
+ cp_token *next = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (next->type == CPP_NAME && next->ambiguous_p)
+ goto out;
+ }
+
+ cp_parser_parse_tentatively (parser);
+ id = cp_parser_id_expression (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/NULL,
+ /*declarator_p=*/true,
+ /*optional_p=*/false);
+ /* If the next token is a (, this is a function with no explicit return
+ type, i.e. constructor, destructor or conversion op. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
+ || TREE_CODE (id) == TYPE_DECL)
+ {
+ cp_parser_abort_tentative_parse (parser);
+ return false;
+ }
+ if (!cp_parser_parse_definitely (parser))
+ return false;
+
+ /* Emit a diagnostic for the invalid type. */
+ cp_parser_diagnose_invalid_type_name (parser, parser->scope,
+ id, token->location);
+ out:
+ /* If we aren't in the middle of a declarator (i.e. in a
+ parameter-declaration-clause), skip to the end of the declaration;
+ there's no point in trying to process it. */
+ if (!parser->in_declarator_p)
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return true;
+}
+
+/* Consume tokens up to, and including, the next non-nested closing `)'.
+ Returns 1 iff we found a closing `)'. RECOVERING is true, if we
+ are doing error recovery. Returns -1 if OR_COMMA is true and we
+ found an unnested comma. */
+
+static int
+cp_parser_skip_to_closing_parenthesis (cp_parser *parser,
+ bool recovering,
+ bool or_comma,
+ bool consume_paren)
+{
+ unsigned paren_depth = 0;
+ unsigned brace_depth = 0;
+ unsigned square_depth = 0;
+
+ if (recovering && !or_comma
+ && cp_parser_uncommitted_to_tentative_parse_p (parser))
+ return 0;
+
+ while (true)
+ {
+ cp_token * token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_EOF:
+ case CPP_PRAGMA_EOL:
+ /* If we've run out of tokens, then there is no closing `)'. */
+ return 0;
+
+ /* This is good for lambda expression capture-lists. */
+ case CPP_OPEN_SQUARE:
+ ++square_depth;
+ break;
+ case CPP_CLOSE_SQUARE:
+ if (!square_depth--)
+ return 0;
+ break;
+
+ case CPP_SEMICOLON:
+ /* This matches the processing in skip_to_end_of_statement. */
+ if (!brace_depth)
+ return 0;
+ break;
+
+ case CPP_OPEN_BRACE:
+ ++brace_depth;
+ break;
+ case CPP_CLOSE_BRACE:
+ if (!brace_depth--)
+ return 0;
+ break;
+
+ case CPP_COMMA:
+ if (recovering && or_comma && !brace_depth && !paren_depth
+ && !square_depth)
+ return -1;
+ break;
+
+ case CPP_OPEN_PAREN:
+ if (!brace_depth)
+ ++paren_depth;
+ break;
+
+ case CPP_CLOSE_PAREN:
+ if (!brace_depth && !paren_depth--)
+ {
+ if (consume_paren)
+ cp_lexer_consume_token (parser->lexer);
+ return 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* Consume tokens until we reach the end of the current statement.
+ Normally, that will be just before consuming a `;'. However, if a
+ non-nested `}' comes first, then we stop before consuming that. */
+
+static void
+cp_parser_skip_to_end_of_statement (cp_parser* parser)
+{
+ unsigned nesting_depth = 0;
+
+ /* Unwind generic function template scope if necessary. */
+ if (parser->fully_implicit_function_template_p)
+ finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
+
+ while (true)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_EOF:
+ case CPP_PRAGMA_EOL:
+ /* If we've run out of tokens, stop. */
+ return;
+
+ case CPP_SEMICOLON:
+ /* If the next token is a `;', we have reached the end of the
+ statement. */
+ if (!nesting_depth)
+ return;
+ break;
+
+ case CPP_CLOSE_BRACE:
+ /* If this is a non-nested '}', stop before consuming it.
+ That way, when confronted with something like:
+
+ { 3 + }
+
+ we stop before consuming the closing '}', even though we
+ have not yet reached a `;'. */
+ if (nesting_depth == 0)
+ return;
+
+ /* If it is the closing '}' for a block that we have
+ scanned, stop -- but only after consuming the token.
+ That way given:
+
+ void f g () { ... }
+ typedef int I;
+
+ we will stop after the body of the erroneously declared
+ function, but before consuming the following `typedef'
+ declaration. */
+ if (--nesting_depth == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ return;
+ }
+
+ case CPP_OPEN_BRACE:
+ ++nesting_depth;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* This function is called at the end of a statement or declaration.
+ If the next token is a semicolon, it is consumed; otherwise, error
+ recovery is attempted. */
+
+static void
+cp_parser_consume_semicolon_at_end_of_statement (cp_parser *parser)
+{
+ /* Look for the trailing `;'. */
+ if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
+ {
+ /* If there is additional (erroneous) input, skip to the end of
+ the statement. */
+ cp_parser_skip_to_end_of_statement (parser);
+ /* If the next token is now a `;', consume it. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* Skip tokens until we have consumed an entire block, or until we
+ have consumed a non-nested `;'. */
+
+static void
+cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser)
+{
+ int nesting_depth = 0;
+
+ /* Unwind generic function template scope if necessary. */
+ if (parser->fully_implicit_function_template_p)
+ finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
+
+ while (nesting_depth >= 0)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_EOF:
+ case CPP_PRAGMA_EOL:
+ /* If we've run out of tokens, stop. */
+ return;
+
+ case CPP_SEMICOLON:
+ /* Stop if this is an unnested ';'. */
+ if (!nesting_depth)
+ nesting_depth = -1;
+ break;
+
+ case CPP_CLOSE_BRACE:
+ /* Stop if this is an unnested '}', or closes the outermost
+ nesting level. */
+ nesting_depth--;
+ if (nesting_depth < 0)
+ return;
+ if (!nesting_depth)
+ nesting_depth = -1;
+ break;
+
+ case CPP_OPEN_BRACE:
+ /* Nest. */
+ nesting_depth++;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* Skip tokens until a non-nested closing curly brace is the next
+ token, or there are no more tokens. Return true in the first case,
+ false otherwise. */
+
+static bool
+cp_parser_skip_to_closing_brace (cp_parser *parser)
+{
+ unsigned nesting_depth = 0;
+
+ while (true)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_EOF:
+ case CPP_PRAGMA_EOL:
+ /* If we've run out of tokens, stop. */
+ return false;
+
+ case CPP_CLOSE_BRACE:
+ /* If the next token is a non-nested `}', then we have reached
+ the end of the current block. */
+ if (nesting_depth-- == 0)
+ return true;
+ break;
+
+ case CPP_OPEN_BRACE:
+ /* If it the next token is a `{', then we are entering a new
+ block. Consume the entire block. */
+ ++nesting_depth;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* Consume tokens until we reach the end of the pragma. The PRAGMA_TOK
+ parameter is the PRAGMA token, allowing us to purge the entire pragma
+ sequence. */
+
+static void
+cp_parser_skip_to_pragma_eol (cp_parser* parser, cp_token *pragma_tok)
+{
+ cp_token *token;
+
+ parser->lexer->in_pragma = false;
+
+ do
+ token = cp_lexer_consume_token (parser->lexer);
+ while (token->type != CPP_PRAGMA_EOL && token->type != CPP_EOF);
+
+ /* Ensure that the pragma is not parsed again. */
+ cp_lexer_purge_tokens_after (parser->lexer, pragma_tok);
+}
+
+/* Require pragma end of line, resyncing with it as necessary. The
+ arguments are as for cp_parser_skip_to_pragma_eol. */
+
+static void
+cp_parser_require_pragma_eol (cp_parser *parser, cp_token *pragma_tok)
+{
+ parser->lexer->in_pragma = false;
+ if (!cp_parser_require (parser, CPP_PRAGMA_EOL, RT_PRAGMA_EOL))
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+}
+
+/* This is a simple wrapper around make_typename_type. When the id is
+ an unresolved identifier node, we can provide a superior diagnostic
+ using cp_parser_diagnose_invalid_type_name. */
+
+static tree
+cp_parser_make_typename_type (cp_parser *parser, tree scope,
+ tree id, location_t id_location)
+{
+ tree result;
+ if (identifier_p (id))
+ {
+ result = make_typename_type (scope, id, typename_type,
+ /*complain=*/tf_none);
+ if (result == error_mark_node)
+ cp_parser_diagnose_invalid_type_name (parser, scope, id, id_location);
+ return result;
+ }
+ return make_typename_type (scope, id, typename_type, tf_error);
+}
+
+/* This is a wrapper around the
+ make_{pointer,ptrmem,reference}_declarator functions that decides
+ which one to call based on the CODE and CLASS_TYPE arguments. The
+ CODE argument should be one of the values returned by
+ cp_parser_ptr_operator. ATTRIBUTES represent the attributes that
+ appertain to the pointer or reference. */
+
+static cp_declarator *
+cp_parser_make_indirect_declarator (enum tree_code code, tree class_type,
+ cp_cv_quals cv_qualifiers,
+ cp_declarator *target,
+ tree attributes)
+{
+ if (code == ERROR_MARK)
+ return cp_error_declarator;
+
+ if (code == INDIRECT_REF)
+ if (class_type == NULL_TREE)
+ return make_pointer_declarator (cv_qualifiers, target, attributes);
+ else
+ return make_ptrmem_declarator (cv_qualifiers, class_type,
+ target, attributes);
+ else if (code == ADDR_EXPR && class_type == NULL_TREE)
+ return make_reference_declarator (cv_qualifiers, target,
+ false, attributes);
+ else if (code == NON_LVALUE_EXPR && class_type == NULL_TREE)
+ return make_reference_declarator (cv_qualifiers, target,
+ true, attributes);
+ gcc_unreachable ();
+}
+
+/* Create a new C++ parser. */
+
+static cp_parser *
+cp_parser_new (void)
+{
+ cp_parser *parser;
+ cp_lexer *lexer;
+ unsigned i;
+
+ /* cp_lexer_new_main is called before doing GC allocation because
+ cp_lexer_new_main might load a PCH file. */
+ lexer = cp_lexer_new_main ();
+
+ /* Initialize the binops_by_token so that we can get the tree
+ directly from the token. */
+ for (i = 0; i < sizeof (binops) / sizeof (binops[0]); i++)
+ binops_by_token[binops[i].token_type] = binops[i];
+
+ parser = ggc_alloc_cleared_cp_parser ();
+ parser->lexer = lexer;
+ parser->context = cp_parser_context_new (NULL);
+
+ /* For now, we always accept GNU extensions. */
+ parser->allow_gnu_extensions_p = 1;
+
+ /* The `>' token is a greater-than operator, not the end of a
+ template-id. */
+ parser->greater_than_is_operator_p = true;
+
+ parser->default_arg_ok_p = true;
+
+ /* We are not parsing a constant-expression. */
+ parser->integral_constant_expression_p = false;
+ parser->allow_non_integral_constant_expression_p = false;
+ parser->non_integral_constant_expression_p = false;
+
+ /* Local variable names are not forbidden. */
+ parser->local_variables_forbidden_p = false;
+
+ /* We are not processing an `extern "C"' declaration. */
+ parser->in_unbraced_linkage_specification_p = false;
+
+ /* We are not processing a declarator. */
+ parser->in_declarator_p = false;
+
+ /* We are not processing a template-argument-list. */
+ parser->in_template_argument_list_p = false;
+
+ /* We are not in an iteration statement. */
+ parser->in_statement = 0;
+
+ /* We are not in a switch statement. */
+ parser->in_switch_statement_p = false;
+
+ /* We are not parsing a type-id inside an expression. */
+ parser->in_type_id_in_expr_p = false;
+
+ /* Declarations aren't implicitly extern "C". */
+ parser->implicit_extern_c = false;
+
+ /* String literals should be translated to the execution character set. */
+ parser->translate_strings_p = true;
+
+ /* We are not parsing a function body. */
+ parser->in_function_body = false;
+
+ /* We can correct until told otherwise. */
+ parser->colon_corrects_to_scope_p = true;
+
+ /* The unparsed function queue is empty. */
+ push_unparsed_function_queues (parser);
+
+ /* There are no classes being defined. */
+ parser->num_classes_being_defined = 0;
+
+ /* No template parameters apply. */
+ parser->num_template_parameter_lists = 0;
+
+ /* Not declaring an implicit function template. */
+ parser->auto_is_implicit_function_template_parm_p = false;
+ parser->fully_implicit_function_template_p = false;
+ parser->implicit_template_parms = 0;
+ parser->implicit_template_scope = 0;
+
+ return parser;
+}
+
+/* Create a cp_lexer structure which will emit the tokens in CACHE
+ and push it onto the parser's lexer stack. This is used for delayed
+ parsing of in-class method bodies and default arguments, and should
+ not be confused with tentative parsing. */
+static void
+cp_parser_push_lexer_for_tokens (cp_parser *parser, cp_token_cache *cache)
+{
+ cp_lexer *lexer = cp_lexer_new_from_tokens (cache);
+ lexer->next = parser->lexer;
+ parser->lexer = lexer;
+
+ /* Move the current source position to that of the first token in the
+ new lexer. */
+ cp_lexer_set_source_position_from_token (lexer->next_token);
+}
+
+/* Pop the top lexer off the parser stack. This is never used for the
+ "main" lexer, only for those pushed by cp_parser_push_lexer_for_tokens. */
+static void
+cp_parser_pop_lexer (cp_parser *parser)
+{
+ cp_lexer *lexer = parser->lexer;
+ parser->lexer = lexer->next;
+ cp_lexer_destroy (lexer);
+
+ /* Put the current source position back where it was before this
+ lexer was pushed. */
+ cp_lexer_set_source_position_from_token (parser->lexer->next_token);
+}
+
+/* Lexical conventions [gram.lex] */
+
+/* Parse an identifier. Returns an IDENTIFIER_NODE representing the
+ identifier. */
+
+static tree
+cp_parser_identifier (cp_parser* parser)
+{
+ cp_token *token;
+
+ /* Look for the identifier. */
+ token = cp_parser_require (parser, CPP_NAME, RT_NAME);
+ /* Return the value. */
+ return token ? token->u.value : error_mark_node;
+}
+
+/* Parse a sequence of adjacent string constants. Returns a
+ TREE_STRING representing the combined, nul-terminated string
+ constant. If TRANSLATE is true, translate the string to the
+ execution character set. If WIDE_OK is true, a wide string is
+ invalid here.
+
+ C++98 [lex.string] says that if a narrow string literal token is
+ adjacent to a wide string literal token, the behavior is undefined.
+ However, C99 6.4.5p4 says that this results in a wide string literal.
+ We follow C99 here, for consistency with the C front end.
+
+ This code is largely lifted from lex_string() in c-lex.c.
+
+ FUTURE: ObjC++ will need to handle @-strings here. */
+static tree
+cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
+{
+ tree value;
+ size_t count;
+ struct obstack str_ob;
+ cpp_string str, istr, *strs;
+ cp_token *tok;
+ enum cpp_ttype type, curr_type;
+ int have_suffix_p = 0;
+ tree string_tree;
+ tree suffix_id = NULL_TREE;
+ bool curr_tok_is_userdef_p = false;
+
+ tok = cp_lexer_peek_token (parser->lexer);
+ if (!cp_parser_is_string_literal (tok))
+ {
+ cp_parser_error (parser, "expected string-literal");
+ return error_mark_node;
+ }
+
+ if (cpp_userdef_string_p (tok->type))
+ {
+ string_tree = USERDEF_LITERAL_VALUE (tok->u.value);
+ curr_type = cpp_userdef_string_remove_type (tok->type);
+ curr_tok_is_userdef_p = true;
+ }
+ else
+ {
+ string_tree = tok->u.value;
+ curr_type = tok->type;
+ }
+ type = curr_type;
+
+ /* Try to avoid the overhead of creating and destroying an obstack
+ for the common case of just one string. */
+ if (!cp_parser_is_string_literal
+ (cp_lexer_peek_nth_token (parser->lexer, 2)))
+ {
+ cp_lexer_consume_token (parser->lexer);
+
+ str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
+ str.len = TREE_STRING_LENGTH (string_tree);
+ count = 1;
+
+ if (curr_tok_is_userdef_p)
+ {
+ suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value);
+ have_suffix_p = 1;
+ curr_type = cpp_userdef_string_remove_type (tok->type);
+ }
+ else
+ curr_type = tok->type;
+
+ strs = &str;
+ }
+ else
+ {
+ gcc_obstack_init (&str_ob);
+ count = 0;
+
+ do
+ {
+ cp_lexer_consume_token (parser->lexer);
+ count++;
+ str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
+ str.len = TREE_STRING_LENGTH (string_tree);
+
+ if (curr_tok_is_userdef_p)
+ {
+ tree curr_suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value);
+ if (have_suffix_p == 0)
+ {
+ suffix_id = curr_suffix_id;
+ have_suffix_p = 1;
+ }
+ else if (have_suffix_p == 1
+ && curr_suffix_id != suffix_id)
+ {
+ error ("inconsistent user-defined literal suffixes"
+ " %qD and %qD in string literal",
+ suffix_id, curr_suffix_id);
+ have_suffix_p = -1;
+ }
+ curr_type = cpp_userdef_string_remove_type (tok->type);
+ }
+ else
+ curr_type = tok->type;
+
+ if (type != curr_type)
+ {
+ if (type == CPP_STRING)
+ type = curr_type;
+ else if (curr_type != CPP_STRING)
+ error_at (tok->location,
+ "unsupported non-standard concatenation "
+ "of string literals");
+ }
+
+ obstack_grow (&str_ob, &str, sizeof (cpp_string));
+
+ tok = cp_lexer_peek_token (parser->lexer);
+ if (cpp_userdef_string_p (tok->type))
+ {
+ string_tree = USERDEF_LITERAL_VALUE (tok->u.value);
+ curr_type = cpp_userdef_string_remove_type (tok->type);
+ curr_tok_is_userdef_p = true;
+ }
+ else
+ {
+ string_tree = tok->u.value;
+ curr_type = tok->type;
+ curr_tok_is_userdef_p = false;
+ }
+ }
+ while (cp_parser_is_string_literal (tok));
+
+ strs = (cpp_string *) obstack_finish (&str_ob);
+ }
+
+ if (type != CPP_STRING && !wide_ok)
+ {
+ cp_parser_error (parser, "a wide string is invalid in this context");
+ type = CPP_STRING;
+ }
+
+ if ((translate ? cpp_interpret_string : cpp_interpret_string_notranslate)
+ (parse_in, strs, count, &istr, type))
+ {
+ value = build_string (istr.len, (const char *)istr.text);
+ free (CONST_CAST (unsigned char *, istr.text));
+
+ switch (type)
+ {
+ default:
+ case CPP_STRING:
+ case CPP_UTF8STRING:
+ TREE_TYPE (value) = char_array_type_node;
+ break;
+ case CPP_STRING16:
+ TREE_TYPE (value) = char16_array_type_node;
+ break;
+ case CPP_STRING32:
+ TREE_TYPE (value) = char32_array_type_node;
+ break;
+ case CPP_WSTRING:
+ TREE_TYPE (value) = wchar_array_type_node;
+ break;
+ }
+
+ value = fix_string_type (value);
+
+ if (have_suffix_p)
+ {
+ tree literal = build_userdef_literal (suffix_id, value,
+ OT_NONE, NULL_TREE);
+ tok->u.value = literal;
+ return cp_parser_userdef_string_literal (tok);
+ }
+ }
+ else
+ /* cpp_interpret_string has issued an error. */
+ value = error_mark_node;
+
+ if (count > 1)
+ obstack_free (&str_ob, 0);
+
+ return value;
+}
+
+/* Look up a literal operator with the name and the exact arguments. */
+
+static tree
+lookup_literal_operator (tree name, vec<tree, va_gc> *args)
+{
+ tree decl, fns;
+ decl = lookup_name (name);
+ if (!decl || !is_overloaded_fn (decl))
+ return error_mark_node;
+
+ for (fns = decl; fns; fns = OVL_NEXT (fns))
+ {
+ unsigned int ix;
+ bool found = true;
+ tree fn = OVL_CURRENT (fns);
+ tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ if (parmtypes != NULL_TREE)
+ {
+ for (ix = 0; ix < vec_safe_length (args) && parmtypes != NULL_TREE;
+ ++ix, parmtypes = TREE_CHAIN (parmtypes))
+ {
+ tree tparm = TREE_VALUE (parmtypes);
+ tree targ = TREE_TYPE ((*args)[ix]);
+ bool ptr = TYPE_PTR_P (tparm);
+ bool arr = TREE_CODE (targ) == ARRAY_TYPE;
+ if ((ptr || arr || !same_type_p (tparm, targ))
+ && (!ptr || !arr
+ || !same_type_p (TREE_TYPE (tparm),
+ TREE_TYPE (targ))))
+ found = false;
+ }
+ if (found
+ && ix == vec_safe_length (args)
+ /* May be this should be sufficient_parms_p instead,
+ depending on how exactly should user-defined literals
+ work in presence of default arguments on the literal
+ operator parameters. */
+ && parmtypes == void_list_node)
+ return fn;
+ }
+ }
+
+ return error_mark_node;
+}
+
+/* Parse a user-defined char constant. Returns a call to a user-defined
+ literal operator taking the character as an argument. */
+
+static tree
+cp_parser_userdef_char_literal (cp_parser *parser)
+{
+ cp_token *token = cp_lexer_consume_token (parser->lexer);
+ tree literal = token->u.value;
+ tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+ tree value = USERDEF_LITERAL_VALUE (literal);
+ tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+ tree decl, result;
+
+ /* Build up a call to the user-defined operator */
+ /* Lookup the name we got back from the id-expression. */
+ vec<tree, va_gc> *args = make_tree_vector ();
+ vec_safe_push (args, value);
+ decl = lookup_literal_operator (name, args);
+ if (!decl || decl == error_mark_node)
+ {
+ error ("unable to find character literal operator %qD with %qT argument",
+ name, TREE_TYPE (value));
+ release_tree_vector (args);
+ return error_mark_node;
+ }
+ result = finish_call_expr (decl, &args, false, true, tf_warning_or_error);
+ release_tree_vector (args);
+ if (result != error_mark_node)
+ return result;
+
+ error ("unable to find character literal operator %qD with %qT argument",
+ name, TREE_TYPE (value));
+ return error_mark_node;
+}
+
+/* A subroutine of cp_parser_userdef_numeric_literal to
+ create a char... template parameter pack from a string node. */
+
+static tree
+make_char_string_pack (tree value)
+{
+ tree charvec;
+ tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
+ const char *str = TREE_STRING_POINTER (value);
+ int i, len = TREE_STRING_LENGTH (value) - 1;
+ tree argvec = make_tree_vec (1);
+
+ /* Fill in CHARVEC with all of the parameters. */
+ charvec = make_tree_vec (len);
+ for (i = 0; i < len; ++i)
+ TREE_VEC_ELT (charvec, i) = build_int_cst (char_type_node, str[i]);
+
+ /* Build the argument packs. */
+ SET_ARGUMENT_PACK_ARGS (argpack, charvec);
+ TREE_TYPE (argpack) = char_type_node;
+
+ TREE_VEC_ELT (argvec, 0) = argpack;
+
+ return argvec;
+}
+
+/* A subroutine of cp_parser_userdef_numeric_literal to
+ create a char... template parameter pack from a string node. */
+
+static tree
+make_string_pack (tree value)
+{
+ tree charvec;
+ tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
+ const unsigned char *str
+ = (const unsigned char *) TREE_STRING_POINTER (value);
+ int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value))));
+ int len = TREE_STRING_LENGTH (value) / sz - 1;
+ tree argvec = make_tree_vec (2);
+
+ tree str_char_type_node = TREE_TYPE (TREE_TYPE (value));
+ str_char_type_node = TYPE_MAIN_VARIANT (str_char_type_node);
+
+ /* First template parm is character type. */
+ TREE_VEC_ELT (argvec, 0) = str_char_type_node;
+
+ /* Fill in CHARVEC with all of the parameters. */
+ charvec = make_tree_vec (len);
+ for (int i = 0; i < len; ++i)
+ TREE_VEC_ELT (charvec, i)
+ = double_int_to_tree (str_char_type_node,
+ double_int::from_buffer (str + i * sz, sz));
+
+ /* Build the argument packs. */
+ SET_ARGUMENT_PACK_ARGS (argpack, charvec);
+ TREE_TYPE (argpack) = str_char_type_node;
+
+ TREE_VEC_ELT (argvec, 1) = argpack;
+
+ return argvec;
+}
+
+/* Parse a user-defined numeric constant. returns a call to a user-defined
+ literal operator. */
+
+static tree
+cp_parser_userdef_numeric_literal (cp_parser *parser)
+{
+ cp_token *token = cp_lexer_consume_token (parser->lexer);
+ tree literal = token->u.value;
+ tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+ tree value = USERDEF_LITERAL_VALUE (literal);
+ int overflow = USERDEF_LITERAL_OVERFLOW (literal);
+ tree num_string = USERDEF_LITERAL_NUM_STRING (literal);
+ tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+ tree decl, result;
+ vec<tree, va_gc> *args;
+
+ /* Look for a literal operator taking the exact type of numeric argument
+ as the literal value. */
+ args = make_tree_vector ();
+ vec_safe_push (args, value);
+ decl = lookup_literal_operator (name, args);
+ if (decl && decl != error_mark_node)
+ {
+ result = finish_call_expr (decl, &args, false, true, tf_none);
+ if (result != error_mark_node)
+ {
+ if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && overflow > 0)
+ warning_at (token->location, OPT_Woverflow,
+ "integer literal exceeds range of %qT type",
+ long_long_unsigned_type_node);
+ else
+ {
+ if (overflow > 0)
+ warning_at (token->location, OPT_Woverflow,
+ "floating literal exceeds range of %qT type",
+ long_double_type_node);
+ else if (overflow < 0)
+ warning_at (token->location, OPT_Woverflow,
+ "floating literal truncated to zero");
+ }
+ release_tree_vector (args);
+ return result;
+ }
+ }
+ release_tree_vector (args);
+
+ /* If the numeric argument didn't work, look for a raw literal
+ operator taking a const char* argument consisting of the number
+ in string format. */
+ args = make_tree_vector ();
+ vec_safe_push (args, num_string);
+ decl = lookup_literal_operator (name, args);
+ if (decl && decl != error_mark_node)
+ {
+ result = finish_call_expr (decl, &args, false, true, tf_none);
+ if (result != error_mark_node)
+ {
+ release_tree_vector (args);
+ return result;
+ }
+ }
+ release_tree_vector (args);
+
+ /* If the raw literal didn't work, look for a non-type template
+ function with parameter pack char.... Call the function with
+ template parameter characters representing the number. */
+ args = make_tree_vector ();
+ decl = lookup_literal_operator (name, args);
+ if (decl && decl != error_mark_node)
+ {
+ tree tmpl_args = make_char_string_pack (num_string);
+ decl = lookup_template_function (decl, tmpl_args);
+ result = finish_call_expr (decl, &args, false, true, tf_none);
+ if (result != error_mark_node)
+ {
+ release_tree_vector (args);
+ return result;
+ }
+ }
+ release_tree_vector (args);
+
+ error ("unable to find numeric literal operator %qD", name);
+ if (!cpp_get_options (parse_in)->ext_numeric_literals)
+ inform (token->location, "use -std=gnu++11 or -fext-numeric-literals "
+ "to enable more built-in suffixes");
+ return error_mark_node;
+}
+
+/* Parse a user-defined string constant. Returns a call to a user-defined
+ literal operator taking a character pointer and the length of the string
+ as arguments. */
+
+static tree
+cp_parser_userdef_string_literal (cp_token *token)
+{
+ tree literal = token->u.value;
+ tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+ tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+ tree value = USERDEF_LITERAL_VALUE (literal);
+ int len = TREE_STRING_LENGTH (value)
+ / TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))) - 1;
+ tree decl, result;
+ vec<tree, va_gc> *args;
+
+ /* Look for a template function with typename parameter CharT
+ and parameter pack CharT... Call the function with
+ template parameter characters representing the string. */
+ args = make_tree_vector ();
+ decl = lookup_literal_operator (name, args);
+ if (decl && decl != error_mark_node)
+ {
+ tree tmpl_args = make_string_pack (value);
+ decl = lookup_template_function (decl, tmpl_args);
+ result = finish_call_expr (decl, &args, false, true, tf_none);
+ if (result != error_mark_node)
+ {
+ release_tree_vector (args);
+ return result;
+ }
+ }
+ release_tree_vector (args);
+
+ /* Build up a call to the user-defined operator */
+ /* Lookup the name we got back from the id-expression. */
+ args = make_tree_vector ();
+ vec_safe_push (args, value);
+ vec_safe_push (args, build_int_cst (size_type_node, len));
+ decl = lookup_name (name);
+ if (!decl || decl == error_mark_node)
+ {
+ error ("unable to find string literal operator %qD", name);
+ release_tree_vector (args);
+ return error_mark_node;
+ }
+ result = finish_call_expr (decl, &args, false, true, tf_none);
+ release_tree_vector (args);
+ if (result != error_mark_node)
+ return result;
+
+ error ("unable to find string literal operator %qD with %qT, %qT arguments",
+ name, TREE_TYPE (value), size_type_node);
+ return error_mark_node;
+}
+
+
+/* Basic concepts [gram.basic] */
+
+/* Parse a translation-unit.
+
+ translation-unit:
+ declaration-seq [opt]
+
+ Returns TRUE if all went well. */
+
+static bool
+cp_parser_translation_unit (cp_parser* parser)
+{
+ /* The address of the first non-permanent object on the declarator
+ obstack. */
+ static void *declarator_obstack_base;
+
+ bool success;
+
+ /* Create the declarator obstack, if necessary. */
+ if (!cp_error_declarator)
+ {
+ gcc_obstack_init (&declarator_obstack);
+ /* Create the error declarator. */
+ cp_error_declarator = make_declarator (cdk_error);
+ /* Create the empty parameter list. */
+ no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE);
+ /* Remember where the base of the declarator obstack lies. */
+ declarator_obstack_base = obstack_next_free (&declarator_obstack);
+ }
+
+ cp_parser_declaration_seq_opt (parser);
+
+ /* If there are no tokens left then all went well. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ {
+ /* Get rid of the token array; we don't need it any more. */
+ cp_lexer_destroy (parser->lexer);
+ parser->lexer = NULL;
+
+ /* This file might have been a context that's implicitly extern
+ "C". If so, pop the lang context. (Only relevant for PCH.) */
+ if (parser->implicit_extern_c)
+ {
+ pop_lang_context ();
+ parser->implicit_extern_c = false;
+ }
+
+ /* Finish up. */
+ finish_translation_unit ();
+
+ success = true;
+ }
+ else
+ {
+ cp_parser_error (parser, "expected declaration");
+ success = false;
+ }
+
+ /* Make sure the declarator obstack was fully cleaned up. */
+ gcc_assert (obstack_next_free (&declarator_obstack)
+ == declarator_obstack_base);
+
+ /* All went well. */
+ return success;
+}
+
+/* Return the appropriate tsubst flags for parsing, possibly in N3276
+ decltype context. */
+
+static inline tsubst_flags_t
+complain_flags (bool decltype_p)
+{
+ tsubst_flags_t complain = tf_warning_or_error;
+ if (decltype_p)
+ complain |= tf_decltype;
+ return complain;
+}
+
+/* Expressions [gram.expr] */
+
+/* Parse a primary-expression.
+
+ primary-expression:
+ literal
+ this
+ ( expression )
+ id-expression
+
+ GNU Extensions:
+
+ primary-expression:
+ ( compound-statement )
+ __builtin_va_arg ( assignment-expression , type-id )
+ __builtin_offsetof ( type-id , offsetof-expression )
+
+ C++ Extensions:
+ __has_nothrow_assign ( type-id )
+ __has_nothrow_constructor ( type-id )
+ __has_nothrow_copy ( type-id )
+ __has_trivial_assign ( type-id )
+ __has_trivial_constructor ( type-id )
+ __has_trivial_copy ( type-id )
+ __has_trivial_destructor ( type-id )
+ __has_virtual_destructor ( type-id )
+ __is_abstract ( type-id )
+ __is_base_of ( type-id , type-id )
+ __is_class ( type-id )
+ __is_convertible_to ( type-id , type-id )
+ __is_empty ( type-id )
+ __is_enum ( type-id )
+ __is_final ( type-id )
+ __is_literal_type ( type-id )
+ __is_pod ( type-id )
+ __is_polymorphic ( type-id )
+ __is_std_layout ( type-id )
+ __is_trivial ( type-id )
+ __is_union ( type-id )
+
+ Objective-C++ Extension:
+
+ primary-expression:
+ objc-expression
+
+ literal:
+ __null
+
+ ADDRESS_P is true iff this expression was immediately preceded by
+ "&" and therefore might denote a pointer-to-member. CAST_P is true
+ iff this expression is the target of a cast. TEMPLATE_ARG_P is
+ true iff this expression is a template argument.
+
+ Returns a representation of the expression. Upon return, *IDK
+ indicates what kind of id-expression (if any) was present. */
+
+static tree
+cp_parser_primary_expression (cp_parser *parser,
+ bool address_p,
+ bool cast_p,
+ bool template_arg_p,
+ bool decltype_p,
+ cp_id_kind *idk)
+{
+ cp_token *token = NULL;
+
+ /* Assume the primary expression is not an id-expression. */
+ *idk = CP_ID_KIND_NONE;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ switch (token->type)
+ {
+ /* literal:
+ integer-literal
+ character-literal
+ floating-literal
+ string-literal
+ boolean-literal
+ pointer-literal
+ user-defined-literal */
+ case CPP_CHAR:
+ case CPP_CHAR16:
+ case CPP_CHAR32:
+ case CPP_WCHAR:
+ case CPP_NUMBER:
+ if (TREE_CODE (token->u.value) == USERDEF_LITERAL)
+ return cp_parser_userdef_numeric_literal (parser);
+ token = cp_lexer_consume_token (parser->lexer);
+ if (TREE_CODE (token->u.value) == FIXED_CST)
+ {
+ error_at (token->location,
+ "fixed-point types not supported in C++");
+ return error_mark_node;
+ }
+ /* Floating-point literals are only allowed in an integral
+ constant expression if they are cast to an integral or
+ enumeration type. */
+ if (TREE_CODE (token->u.value) == REAL_CST
+ && parser->integral_constant_expression_p
+ && pedantic)
+ {
+ /* CAST_P will be set even in invalid code like "int(2.7 +
+ ...)". Therefore, we have to check that the next token
+ is sure to end the cast. */
+ if (cast_p)
+ {
+ cp_token *next_token;
+
+ next_token = cp_lexer_peek_token (parser->lexer);
+ if (/* The comma at the end of an
+ enumerator-definition. */
+ next_token->type != CPP_COMMA
+ /* The curly brace at the end of an enum-specifier. */
+ && next_token->type != CPP_CLOSE_BRACE
+ /* The end of a statement. */
+ && next_token->type != CPP_SEMICOLON
+ /* The end of the cast-expression. */
+ && next_token->type != CPP_CLOSE_PAREN
+ /* The end of an array bound. */
+ && next_token->type != CPP_CLOSE_SQUARE
+ /* The closing ">" in a template-argument-list. */
+ && (next_token->type != CPP_GREATER
+ || parser->greater_than_is_operator_p)
+ /* C++0x only: A ">>" treated like two ">" tokens,
+ in a template-argument-list. */
+ && (next_token->type != CPP_RSHIFT
+ || (cxx_dialect == cxx98)
+ || parser->greater_than_is_operator_p))
+ cast_p = false;
+ }
+
+ /* If we are within a cast, then the constraint that the
+ cast is to an integral or enumeration type will be
+ checked at that point. If we are not within a cast, then
+ this code is invalid. */
+ if (!cast_p)
+ cp_parser_non_integral_constant_expression (parser, NIC_FLOAT);
+ }
+ return token->u.value;
+
+ case CPP_CHAR_USERDEF:
+ case CPP_CHAR16_USERDEF:
+ case CPP_CHAR32_USERDEF:
+ case CPP_WCHAR_USERDEF:
+ return cp_parser_userdef_char_literal (parser);
+
+ case CPP_STRING:
+ case CPP_STRING16:
+ case CPP_STRING32:
+ case CPP_WSTRING:
+ case CPP_UTF8STRING:
+ case CPP_STRING_USERDEF:
+ case CPP_STRING16_USERDEF:
+ case CPP_STRING32_USERDEF:
+ case CPP_WSTRING_USERDEF:
+ case CPP_UTF8STRING_USERDEF:
+ /* ??? Should wide strings be allowed when parser->translate_strings_p
+ is false (i.e. in attributes)? If not, we can kill the third
+ argument to cp_parser_string_literal. */
+ return cp_parser_string_literal (parser,
+ parser->translate_strings_p,
+ true);
+
+ case CPP_OPEN_PAREN:
+ {
+ tree expr;
+ bool saved_greater_than_is_operator_p;
+
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Within a parenthesized expression, a `>' token is always
+ the greater-than operator. */
+ saved_greater_than_is_operator_p
+ = parser->greater_than_is_operator_p;
+ parser->greater_than_is_operator_p = true;
+ /* If we see `( { ' then we are looking at the beginning of
+ a GNU statement-expression. */
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ /* Statement-expressions are not allowed by the standard. */
+ pedwarn (token->location, OPT_Wpedantic,
+ "ISO C++ forbids braced-groups within expressions");
+
+ /* And they're not allowed outside of a function-body; you
+ cannot, for example, write:
+
+ int i = ({ int j = 3; j + 1; });
+
+ at class or namespace scope. */
+ if (!parser->in_function_body
+ || parser->in_template_argument_list_p)
+ {
+ error_at (token->location,
+ "statement-expressions are not allowed outside "
+ "functions nor in template-argument lists");
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ expr = error_mark_node;
+ }
+ else
+ {
+ /* Start the statement-expression. */
+ expr = begin_stmt_expr ();
+ /* Parse the compound-statement. */
+ cp_parser_compound_statement (parser, expr, false, false);
+ /* Finish up. */
+ expr = finish_stmt_expr (expr, false);
+ }
+ }
+ else
+ {
+ /* Parse the parenthesized expression. */
+ expr = cp_parser_expression (parser, cast_p, decltype_p, idk);
+ /* Let the front end know that this expression was
+ enclosed in parentheses. This matters in case, for
+ example, the expression is of the form `A::B', since
+ `&A::B' might be a pointer-to-member, but `&(A::B)' is
+ not. */
+ expr = finish_parenthesized_expr (expr);
+ /* DR 705: Wrapping an unqualified name in parentheses
+ suppresses arg-dependent lookup. We want to pass back
+ CP_ID_KIND_QUALIFIED for suppressing vtable lookup
+ (c++/37862), but none of the others. */
+ if (*idk != CP_ID_KIND_QUALIFIED)
+ *idk = CP_ID_KIND_NONE;
+ }
+ /* The `>' token might be the end of a template-id or
+ template-parameter-list now. */
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+ /* Consume the `)'. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_end_of_statement (parser);
+
+ return expr;
+ }
+
+ case CPP_OPEN_SQUARE:
+ if (c_dialect_objc ())
+ /* We have an Objective-C++ message. */
+ return cp_parser_objc_expression (parser);
+ {
+ tree lam = cp_parser_lambda_expression (parser);
+ /* Don't warn about a failed tentative parse. */
+ if (cp_parser_error_occurred (parser))
+ return error_mark_node;
+ maybe_warn_cpp0x (CPP0X_LAMBDA_EXPR);
+ return lam;
+ }
+
+ case CPP_OBJC_STRING:
+ if (c_dialect_objc ())
+ /* We have an Objective-C++ string literal. */
+ return cp_parser_objc_expression (parser);
+ cp_parser_error (parser, "expected primary-expression");
+ return error_mark_node;
+
+ case CPP_KEYWORD:
+ switch (token->keyword)
+ {
+ /* These two are the boolean literals. */
+ case RID_TRUE:
+ cp_lexer_consume_token (parser->lexer);
+ return boolean_true_node;
+ case RID_FALSE:
+ cp_lexer_consume_token (parser->lexer);
+ return boolean_false_node;
+
+ /* The `__null' literal. */
+ case RID_NULL:
+ cp_lexer_consume_token (parser->lexer);
+ return null_node;
+
+ /* The `nullptr' literal. */
+ case RID_NULLPTR:
+ cp_lexer_consume_token (parser->lexer);
+ return nullptr_node;
+
+ /* Recognize the `this' keyword. */
+ case RID_THIS:
+ cp_lexer_consume_token (parser->lexer);
+ if (parser->local_variables_forbidden_p)
+ {
+ error_at (token->location,
+ "%<this%> may not be used in this context");
+ return error_mark_node;
+ }
+ /* Pointers cannot appear in constant-expressions. */
+ if (cp_parser_non_integral_constant_expression (parser, NIC_THIS))
+ return error_mark_node;
+ return finish_this_expr ();
+
+ /* The `operator' keyword can be the beginning of an
+ id-expression. */
+ case RID_OPERATOR:
+ goto id_expression;
+
+ case RID_FUNCTION_NAME:
+ case RID_PRETTY_FUNCTION_NAME:
+ case RID_C99_FUNCTION_NAME:
+ {
+ non_integral_constant name;
+
+ /* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and
+ __func__ are the names of variables -- but they are
+ treated specially. Therefore, they are handled here,
+ rather than relying on the generic id-expression logic
+ below. Grammatically, these names are id-expressions.
+
+ Consume the token. */
+ token = cp_lexer_consume_token (parser->lexer);
+
+ switch (token->keyword)
+ {
+ case RID_FUNCTION_NAME:
+ name = NIC_FUNC_NAME;
+ break;
+ case RID_PRETTY_FUNCTION_NAME:
+ name = NIC_PRETTY_FUNC;
+ break;
+ case RID_C99_FUNCTION_NAME:
+ name = NIC_C99_FUNC;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (cp_parser_non_integral_constant_expression (parser, name))
+ return error_mark_node;
+
+ /* Look up the name. */
+ return finish_fname (token->u.value);
+ }
+
+ case RID_VA_ARG:
+ {
+ tree expression;
+ tree type;
+ source_location type_location;
+
+ /* The `__builtin_va_arg' construct is used to handle
+ `va_arg'. Consume the `__builtin_va_arg' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the opening `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ /* Now, parse the assignment-expression. */
+ expression = cp_parser_assignment_expression (parser,
+ /*cast_p=*/false, NULL);
+ /* Look for the `,'. */
+ cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+ type_location = cp_lexer_peek_token (parser->lexer)->location;
+ /* Parse the type-id. */
+ type = cp_parser_type_id (parser);
+ /* Look for the closing `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ /* Using `va_arg' in a constant-expression is not
+ allowed. */
+ if (cp_parser_non_integral_constant_expression (parser,
+ NIC_VA_ARG))
+ return error_mark_node;
+ return build_x_va_arg (type_location, expression, type);
+ }
+
+ case RID_OFFSETOF:
+ return cp_parser_builtin_offsetof (parser);
+
+ case RID_HAS_NOTHROW_ASSIGN:
+ case RID_HAS_NOTHROW_CONSTRUCTOR:
+ case RID_HAS_NOTHROW_COPY:
+ case RID_HAS_TRIVIAL_ASSIGN:
+ case RID_HAS_TRIVIAL_CONSTRUCTOR:
+ case RID_HAS_TRIVIAL_COPY:
+ case RID_HAS_TRIVIAL_DESTRUCTOR:
+ case RID_HAS_VIRTUAL_DESTRUCTOR:
+ case RID_IS_ABSTRACT:
+ case RID_IS_BASE_OF:
+ case RID_IS_CLASS:
+ case RID_IS_CONVERTIBLE_TO:
+ case RID_IS_EMPTY:
+ case RID_IS_ENUM:
+ case RID_IS_FINAL:
+ case RID_IS_LITERAL_TYPE:
+ case RID_IS_POD:
+ case RID_IS_POLYMORPHIC:
+ case RID_IS_STD_LAYOUT:
+ case RID_IS_TRIVIAL:
+ case RID_IS_UNION:
+ return cp_parser_trait_expr (parser, token->keyword);
+
+ /* Objective-C++ expressions. */
+ case RID_AT_ENCODE:
+ case RID_AT_PROTOCOL:
+ case RID_AT_SELECTOR:
+ return cp_parser_objc_expression (parser);
+
+ case RID_TEMPLATE:
+ if (parser->in_function_body
+ && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ == CPP_LESS))
+ {
+ error_at (token->location,
+ "a template declaration cannot appear at block scope");
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+ default:
+ cp_parser_error (parser, "expected primary-expression");
+ return error_mark_node;
+ }
+
+ /* An id-expression can start with either an identifier, a
+ `::' as the beginning of a qualified-id, or the "operator"
+ keyword. */
+ case CPP_NAME:
+ case CPP_SCOPE:
+ case CPP_TEMPLATE_ID:
+ case CPP_NESTED_NAME_SPECIFIER:
+ {
+ tree id_expression;
+ tree decl;
+ const char *error_msg;
+ bool template_p;
+ bool done;
+ cp_token *id_expr_token;
+
+ id_expression:
+ /* Parse the id-expression. */
+ id_expression
+ = cp_parser_id_expression (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ &template_p,
+ /*declarator_p=*/false,
+ /*optional_p=*/false);
+ if (id_expression == error_mark_node)
+ return error_mark_node;
+ id_expr_token = token;
+ token = cp_lexer_peek_token (parser->lexer);
+ done = (token->type != CPP_OPEN_SQUARE
+ && token->type != CPP_OPEN_PAREN
+ && token->type != CPP_DOT
+ && token->type != CPP_DEREF
+ && token->type != CPP_PLUS_PLUS
+ && token->type != CPP_MINUS_MINUS);
+ /* If we have a template-id, then no further lookup is
+ required. If the template-id was for a template-class, we
+ will sometimes have a TYPE_DECL at this point. */
+ if (TREE_CODE (id_expression) == TEMPLATE_ID_EXPR
+ || TREE_CODE (id_expression) == TYPE_DECL)
+ decl = id_expression;
+ /* Look up the name. */
+ else
+ {
+ tree ambiguous_decls;
+
+ /* If we already know that this lookup is ambiguous, then
+ we've already issued an error message; there's no reason
+ to check again. */
+ if (id_expr_token->type == CPP_NAME
+ && id_expr_token->ambiguous_p)
+ {
+ cp_parser_simulate_error (parser);
+ return error_mark_node;
+ }
+
+ decl = cp_parser_lookup_name (parser, id_expression,
+ none_type,
+ template_p,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true,
+ &ambiguous_decls,
+ id_expr_token->location);
+ /* If the lookup was ambiguous, an error will already have
+ been issued. */
+ if (ambiguous_decls)
+ return error_mark_node;
+
+ /* In Objective-C++, we may have an Objective-C 2.0
+ dot-syntax for classes here. */
+ if (c_dialect_objc ()
+ && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT
+ && TREE_CODE (decl) == TYPE_DECL
+ && objc_is_class_name (decl))
+ {
+ tree component;
+ cp_lexer_consume_token (parser->lexer);
+ component = cp_parser_identifier (parser);
+ if (component == error_mark_node)
+ return error_mark_node;
+
+ return objc_build_class_component_ref (id_expression, component);
+ }
+
+ /* In Objective-C++, an instance variable (ivar) may be preferred
+ to whatever cp_parser_lookup_name() found. */
+ decl = objc_lookup_ivar (decl, id_expression);
+
+ /* If name lookup gives us a SCOPE_REF, then the
+ qualifying scope was dependent. */
+ if (TREE_CODE (decl) == SCOPE_REF)
+ {
+ /* At this point, we do not know if DECL is a valid
+ integral constant expression. We assume that it is
+ in fact such an expression, so that code like:
+
+ template <int N> struct A {
+ int a[B<N>::i];
+ };
+
+ is accepted. At template-instantiation time, we
+ will check that B<N>::i is actually a constant. */
+ return decl;
+ }
+ /* Check to see if DECL is a local variable in a context
+ where that is forbidden. */
+ if (parser->local_variables_forbidden_p
+ && local_variable_p (decl))
+ {
+ /* It might be that we only found DECL because we are
+ trying to be generous with pre-ISO scoping rules.
+ For example, consider:
+
+ int i;
+ void g() {
+ for (int i = 0; i < 10; ++i) {}
+ extern void f(int j = i);
+ }
+
+ Here, name look up will originally find the out
+ of scope `i'. We need to issue a warning message,
+ but then use the global `i'. */
+ decl = check_for_out_of_scope_variable (decl);
+ if (local_variable_p (decl))
+ {
+ error_at (id_expr_token->location,
+ "local variable %qD may not appear in this context",
+ decl);
+ return error_mark_node;
+ }
+ }
+ }
+
+ decl = (finish_id_expression
+ (id_expression, decl, parser->scope,
+ idk,
+ parser->integral_constant_expression_p,
+ parser->allow_non_integral_constant_expression_p,
+ &parser->non_integral_constant_expression_p,
+ template_p, done, address_p,
+ template_arg_p,
+ &error_msg,
+ id_expr_token->location));
+ if (error_msg)
+ cp_parser_error (parser, error_msg);
+ return decl;
+ }
+
+ /* Anything else is an error. */
+ default:
+ cp_parser_error (parser, "expected primary-expression");
+ return error_mark_node;
+ }
+}
+
+static inline tree
+cp_parser_primary_expression (cp_parser *parser,
+ bool address_p,
+ bool cast_p,
+ bool template_arg_p,
+ cp_id_kind *idk)
+{
+ return cp_parser_primary_expression (parser, address_p, cast_p, template_arg_p,
+ /*decltype*/false, idk);
+}
+
+/* Parse an id-expression.
+
+ id-expression:
+ unqualified-id
+ qualified-id
+
+ qualified-id:
+ :: [opt] nested-name-specifier template [opt] unqualified-id
+ :: identifier
+ :: operator-function-id
+ :: template-id
+
+ Return a representation of the unqualified portion of the
+ identifier. Sets PARSER->SCOPE to the qualifying scope if there is
+ a `::' or nested-name-specifier.
+
+ Often, if the id-expression was a qualified-id, the caller will
+ want to make a SCOPE_REF to represent the qualified-id. This
+ function does not do this in order to avoid wastefully creating
+ SCOPE_REFs when they are not required.
+
+ If TEMPLATE_KEYWORD_P is true, then we have just seen the
+ `template' keyword.
+
+ If CHECK_DEPENDENCY_P is false, then names are looked up inside
+ uninstantiated templates.
+
+ If *TEMPLATE_P is non-NULL, it is set to true iff the
+ `template' keyword is used to explicitly indicate that the entity
+ named is a template.
+
+ If DECLARATOR_P is true, the id-expression is appearing as part of
+ a declarator, rather than as part of an expression. */
+
+static tree
+cp_parser_id_expression (cp_parser *parser,
+ bool template_keyword_p,
+ bool check_dependency_p,
+ bool *template_p,
+ bool declarator_p,
+ bool optional_p)
+{
+ bool global_scope_p;
+ bool nested_name_specifier_p;
+
+ /* Assume the `template' keyword was not used. */
+ if (template_p)
+ *template_p = template_keyword_p;
+
+ /* Look for the optional `::' operator. */
+ global_scope_p
+ = (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+ /* Look for the optional nested-name-specifier. */
+ nested_name_specifier_p
+ = (cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ check_dependency_p,
+ /*type_p=*/false,
+ declarator_p)
+ != NULL_TREE);
+ /* If there is a nested-name-specifier, then we are looking at
+ the first qualified-id production. */
+ if (nested_name_specifier_p)
+ {
+ tree saved_scope;
+ tree saved_object_scope;
+ tree saved_qualifying_scope;
+ tree unqualified_id;
+ bool is_template;
+
+ /* See if the next token is the `template' keyword. */
+ if (!template_p)
+ template_p = &is_template;
+ *template_p = cp_parser_optional_template_keyword (parser);
+ /* Name lookup we do during the processing of the
+ unqualified-id might obliterate SCOPE. */
+ saved_scope = parser->scope;
+ saved_object_scope = parser->object_scope;
+ saved_qualifying_scope = parser->qualifying_scope;
+ /* Process the final unqualified-id. */
+ unqualified_id = cp_parser_unqualified_id (parser, *template_p,
+ check_dependency_p,
+ declarator_p,
+ /*optional_p=*/false);
+ /* Restore the SAVED_SCOPE for our caller. */
+ parser->scope = saved_scope;
+ parser->object_scope = saved_object_scope;
+ parser->qualifying_scope = saved_qualifying_scope;
+
+ return unqualified_id;
+ }
+ /* Otherwise, if we are in global scope, then we are looking at one
+ of the other qualified-id productions. */
+ else if (global_scope_p)
+ {
+ cp_token *token;
+ tree id;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* If it's an identifier, and the next token is not a "<", then
+ we can avoid the template-id case. This is an optimization
+ for this common case. */
+ if (token->type == CPP_NAME
+ && !cp_parser_nth_token_starts_template_argument_list_p
+ (parser, 2))
+ return cp_parser_identifier (parser);
+
+ cp_parser_parse_tentatively (parser);
+ /* Try a template-id. */
+ id = cp_parser_template_id (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ none_type,
+ declarator_p);
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return id;
+
+ /* Peek at the next token. (Changes in the token buffer may
+ have invalidated the pointer obtained above.) */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_NAME:
+ return cp_parser_identifier (parser);
+
+ case CPP_KEYWORD:
+ if (token->keyword == RID_OPERATOR)
+ return cp_parser_operator_function_id (parser);
+ /* Fall through. */
+
+ default:
+ cp_parser_error (parser, "expected id-expression");
+ return error_mark_node;
+ }
+ }
+ else
+ return cp_parser_unqualified_id (parser, template_keyword_p,
+ /*check_dependency_p=*/true,
+ declarator_p,
+ optional_p);
+}
+
+/* Parse an unqualified-id.
+
+ unqualified-id:
+ identifier
+ operator-function-id
+ conversion-function-id
+ ~ class-name
+ template-id
+
+ If TEMPLATE_KEYWORD_P is TRUE, we have just seen the `template'
+ keyword, in a construct like `A::template ...'.
+
+ Returns a representation of unqualified-id. For the `identifier'
+ production, an IDENTIFIER_NODE is returned. For the `~ class-name'
+ production a BIT_NOT_EXPR is returned; the operand of the
+ BIT_NOT_EXPR is an IDENTIFIER_NODE for the class-name. For the
+ other productions, see the documentation accompanying the
+ corresponding parsing functions. If CHECK_DEPENDENCY_P is false,
+ names are looked up in uninstantiated templates. If DECLARATOR_P
+ is true, the unqualified-id is appearing as part of a declarator,
+ rather than as part of an expression. */
+
+static tree
+cp_parser_unqualified_id (cp_parser* parser,
+ bool template_keyword_p,
+ bool check_dependency_p,
+ bool declarator_p,
+ bool optional_p)
+{
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_NAME:
+ {
+ tree id;
+
+ /* We don't know yet whether or not this will be a
+ template-id. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a template-id. */
+ id = cp_parser_template_id (parser, template_keyword_p,
+ check_dependency_p,
+ none_type,
+ declarator_p);
+ /* If it worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return id;
+ /* Otherwise, it's an ordinary identifier. */
+ return cp_parser_identifier (parser);
+ }
+
+ case CPP_TEMPLATE_ID:
+ return cp_parser_template_id (parser, template_keyword_p,
+ check_dependency_p,
+ none_type,
+ declarator_p);
+
+ case CPP_COMPL:
+ {
+ tree type_decl;
+ tree qualifying_scope;
+ tree object_scope;
+ tree scope;
+ bool done;
+
+ /* Consume the `~' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the class-name. The standard, as written, seems to
+ say that:
+
+ template <typename T> struct S { ~S (); };
+ template <typename T> S<T>::~S() {}
+
+ is invalid, since `~' must be followed by a class-name, but
+ `S<T>' is dependent, and so not known to be a class.
+ That's not right; we need to look in uninstantiated
+ templates. A further complication arises from:
+
+ template <typename T> void f(T t) {
+ t.T::~T();
+ }
+
+ Here, it is not possible to look up `T' in the scope of `T'
+ itself. We must look in both the current scope, and the
+ scope of the containing complete expression.
+
+ Yet another issue is:
+
+ struct S {
+ int S;
+ ~S();
+ };
+
+ S::~S() {}
+
+ The standard does not seem to say that the `S' in `~S'
+ should refer to the type `S' and not the data member
+ `S::S'. */
+
+ /* DR 244 says that we look up the name after the "~" in the
+ same scope as we looked up the qualifying name. That idea
+ isn't fully worked out; it's more complicated than that. */
+ scope = parser->scope;
+ object_scope = parser->object_scope;
+ qualifying_scope = parser->qualifying_scope;
+
+ /* Check for invalid scopes. */
+ if (scope == error_mark_node)
+ {
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ cp_lexer_consume_token (parser->lexer);
+ return error_mark_node;
+ }
+ if (scope && TREE_CODE (scope) == NAMESPACE_DECL)
+ {
+ if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
+ error_at (token->location,
+ "scope %qT before %<~%> is not a class-name",
+ scope);
+ cp_parser_simulate_error (parser);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ cp_lexer_consume_token (parser->lexer);
+ return error_mark_node;
+ }
+ gcc_assert (!scope || TYPE_P (scope));
+
+ /* If the name is of the form "X::~X" it's OK even if X is a
+ typedef. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (scope
+ && token->type == CPP_NAME
+ && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ != CPP_LESS)
+ && (token->u.value == TYPE_IDENTIFIER (scope)
+ || (CLASS_TYPE_P (scope)
+ && constructor_name_p (token->u.value, scope))))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ return build_nt (BIT_NOT_EXPR, scope);
+ }
+
+ /* ~auto means the destructor of whatever the object is. */
+ if (cp_parser_is_keyword (token, RID_AUTO))
+ {
+ if (cxx_dialect < cxx1y)
+ pedwarn (input_location, 0,
+ "%<~auto%> only available with "
+ "-std=c++1y or -std=gnu++1y");
+ cp_lexer_consume_token (parser->lexer);
+ return build_nt (BIT_NOT_EXPR, make_auto ());
+ }
+
+ /* If there was an explicit qualification (S::~T), first look
+ in the scope given by the qualification (i.e., S).
+
+ Note: in the calls to cp_parser_class_name below we pass
+ typename_type so that lookup finds the injected-class-name
+ rather than the constructor. */
+ done = false;
+ type_decl = NULL_TREE;
+ if (scope)
+ {
+ cp_parser_parse_tentatively (parser);
+ type_decl = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ typename_type,
+ /*check_dependency=*/false,
+ /*class_head_p=*/false,
+ declarator_p);
+ if (cp_parser_parse_definitely (parser))
+ done = true;
+ }
+ /* In "N::S::~S", look in "N" as well. */
+ if (!done && scope && qualifying_scope)
+ {
+ cp_parser_parse_tentatively (parser);
+ parser->scope = qualifying_scope;
+ parser->object_scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ type_decl
+ = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ typename_type,
+ /*check_dependency=*/false,
+ /*class_head_p=*/false,
+ declarator_p);
+ if (cp_parser_parse_definitely (parser))
+ done = true;
+ }
+ /* In "p->S::~T", look in the scope given by "*p" as well. */
+ else if (!done && object_scope)
+ {
+ cp_parser_parse_tentatively (parser);
+ parser->scope = object_scope;
+ parser->object_scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ type_decl
+ = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ typename_type,
+ /*check_dependency=*/false,
+ /*class_head_p=*/false,
+ declarator_p);
+ if (cp_parser_parse_definitely (parser))
+ done = true;
+ }
+ /* Look in the surrounding context. */
+ if (!done)
+ {
+ parser->scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ if (processing_template_decl)
+ cp_parser_parse_tentatively (parser);
+ type_decl
+ = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ typename_type,
+ /*check_dependency=*/false,
+ /*class_head_p=*/false,
+ declarator_p);
+ if (processing_template_decl
+ && ! cp_parser_parse_definitely (parser))
+ {
+ /* We couldn't find a type with this name, so just accept
+ it and check for a match at instantiation time. */
+ type_decl = cp_parser_identifier (parser);
+ if (type_decl != error_mark_node)
+ type_decl = build_nt (BIT_NOT_EXPR, type_decl);
+ return type_decl;
+ }
+ }
+ /* If an error occurred, assume that the name of the
+ destructor is the same as the name of the qualifying
+ class. That allows us to keep parsing after running
+ into ill-formed destructor names. */
+ if (type_decl == error_mark_node && scope)
+ return build_nt (BIT_NOT_EXPR, scope);
+ else if (type_decl == error_mark_node)
+ return error_mark_node;
+
+ /* Check that destructor name and scope match. */
+ if (declarator_p && scope && !check_dtor_name (scope, type_decl))
+ {
+ if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
+ error_at (token->location,
+ "declaration of %<~%T%> as member of %qT",
+ type_decl, scope);
+ cp_parser_simulate_error (parser);
+ return error_mark_node;
+ }
+
+ /* [class.dtor]
+
+ A typedef-name that names a class shall not be used as the
+ identifier in the declarator for a destructor declaration. */
+ if (declarator_p
+ && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
+ && !DECL_SELF_REFERENCE_P (type_decl)
+ && !cp_parser_uncommitted_to_tentative_parse_p (parser))
+ error_at (token->location,
+ "typedef-name %qD used as destructor declarator",
+ type_decl);
+
+ return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
+ }
+
+ case CPP_KEYWORD:
+ if (token->keyword == RID_OPERATOR)
+ {
+ tree id;
+
+ /* This could be a template-id, so we try that first. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a template-id. */
+ id = cp_parser_template_id (parser, template_keyword_p,
+ /*check_dependency_p=*/true,
+ none_type,
+ declarator_p);
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return id;
+ /* We still don't know whether we're looking at an
+ operator-function-id or a conversion-function-id. */
+ cp_parser_parse_tentatively (parser);
+ /* Try an operator-function-id. */
+ id = cp_parser_operator_function_id (parser);
+ /* If that didn't work, try a conversion-function-id. */
+ if (!cp_parser_parse_definitely (parser))
+ id = cp_parser_conversion_function_id (parser);
+ else if (UDLIT_OPER_P (id))
+ {
+ /* 17.6.3.3.5 */
+ const char *name = UDLIT_OP_SUFFIX (id);
+ if (name[0] != '_' && !in_system_header_at (input_location)
+ && declarator_p)
+ warning (0, "literal operator suffixes not preceded by %<_%>"
+ " are reserved for future standardization");
+ }
+
+ return id;
+ }
+ /* Fall through. */
+
+ default:
+ if (optional_p)
+ return NULL_TREE;
+ cp_parser_error (parser, "expected unqualified-id");
+ return error_mark_node;
+ }
+}
+
+/* Parse an (optional) nested-name-specifier.
+
+ nested-name-specifier: [C++98]
+ class-or-namespace-name :: nested-name-specifier [opt]
+ class-or-namespace-name :: template nested-name-specifier [opt]
+
+ nested-name-specifier: [C++0x]
+ type-name ::
+ namespace-name ::
+ nested-name-specifier identifier ::
+ nested-name-specifier template [opt] simple-template-id ::
+
+ PARSER->SCOPE should be set appropriately before this function is
+ called. TYPENAME_KEYWORD_P is TRUE if the `typename' keyword is in
+ effect. TYPE_P is TRUE if we non-type bindings should be ignored
+ in name lookups.
+
+ Sets PARSER->SCOPE to the class (TYPE) or namespace
+ (NAMESPACE_DECL) specified by the nested-name-specifier, or leaves
+ it unchanged if there is no nested-name-specifier. Returns the new
+ scope iff there is a nested-name-specifier, or NULL_TREE otherwise.
+
+ If IS_DECLARATION is TRUE, the nested-name-specifier is known to be
+ part of a declaration and/or decl-specifier. */
+
+static tree
+cp_parser_nested_name_specifier_opt (cp_parser *parser,
+ bool typename_keyword_p,
+ bool check_dependency_p,
+ bool type_p,
+ bool is_declaration)
+{
+ bool success = false;
+ cp_token_position start = 0;
+ cp_token *token;
+
+ /* Remember where the nested-name-specifier starts. */
+ if (cp_parser_uncommitted_to_tentative_parse_p (parser))
+ {
+ start = cp_lexer_token_position (parser->lexer, false);
+ push_deferring_access_checks (dk_deferred);
+ }
+
+ while (true)
+ {
+ tree new_scope;
+ tree old_scope;
+ tree saved_qualifying_scope;
+ bool template_keyword_p;
+
+ /* Spot cases that cannot be the beginning of a
+ nested-name-specifier. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* If the next token is CPP_NESTED_NAME_SPECIFIER, just process
+ the already parsed nested-name-specifier. */
+ if (token->type == CPP_NESTED_NAME_SPECIFIER)
+ {
+ /* Grab the nested-name-specifier and continue the loop. */
+ cp_parser_pre_parsed_nested_name_specifier (parser);
+ /* If we originally encountered this nested-name-specifier
+ with IS_DECLARATION set to false, we will not have
+ resolved TYPENAME_TYPEs, so we must do so here. */
+ if (is_declaration
+ && TREE_CODE (parser->scope) == TYPENAME_TYPE)
+ {
+ new_scope = resolve_typename_type (parser->scope,
+ /*only_current_p=*/false);
+ if (TREE_CODE (new_scope) != TYPENAME_TYPE)
+ parser->scope = new_scope;
+ }
+ success = true;
+ continue;
+ }
+
+ /* Spot cases that cannot be the beginning of a
+ nested-name-specifier. On the second and subsequent times
+ through the loop, we look for the `template' keyword. */
+ if (success && token->keyword == RID_TEMPLATE)
+ ;
+ /* A template-id can start a nested-name-specifier. */
+ else if (token->type == CPP_TEMPLATE_ID)
+ ;
+ /* DR 743: decltype can be used in a nested-name-specifier. */
+ else if (token_is_decltype (token))
+ ;
+ else
+ {
+ /* If the next token is not an identifier, then it is
+ definitely not a type-name or namespace-name. */
+ if (token->type != CPP_NAME)
+ break;
+ /* If the following token is neither a `<' (to begin a
+ template-id), nor a `::', then we are not looking at a
+ nested-name-specifier. */
+ token = cp_lexer_peek_nth_token (parser->lexer, 2);
+
+ if (token->type == CPP_COLON
+ && parser->colon_corrects_to_scope_p
+ && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_NAME)
+ {
+ error_at (token->location,
+ "found %<:%> in nested-name-specifier, expected %<::%>");
+ token->type = CPP_SCOPE;
+ }
+
+ if (token->type != CPP_SCOPE
+ && !cp_parser_nth_token_starts_template_argument_list_p
+ (parser, 2))
+ break;
+ }
+
+ /* The nested-name-specifier is optional, so we parse
+ tentatively. */
+ cp_parser_parse_tentatively (parser);
+
+ /* Look for the optional `template' keyword, if this isn't the
+ first time through the loop. */
+ if (success)
+ template_keyword_p = cp_parser_optional_template_keyword (parser);
+ else
+ template_keyword_p = false;
+
+ /* Save the old scope since the name lookup we are about to do
+ might destroy it. */
+ old_scope = parser->scope;
+ saved_qualifying_scope = parser->qualifying_scope;
+ /* In a declarator-id like "X<T>::I::Y<T>" we must be able to
+ look up names in "X<T>::I" in order to determine that "Y" is
+ a template. So, if we have a typename at this point, we make
+ an effort to look through it. */
+ if (is_declaration
+ && !typename_keyword_p
+ && parser->scope
+ && TREE_CODE (parser->scope) == TYPENAME_TYPE)
+ parser->scope = resolve_typename_type (parser->scope,
+ /*only_current_p=*/false);
+ /* Parse the qualifying entity. */
+ new_scope
+ = cp_parser_qualifying_entity (parser,
+ typename_keyword_p,
+ template_keyword_p,
+ check_dependency_p,
+ type_p,
+ is_declaration);
+ /* Look for the `::' token. */
+ cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
+
+ /* If we found what we wanted, we keep going; otherwise, we're
+ done. */
+ if (!cp_parser_parse_definitely (parser))
+ {
+ bool error_p = false;
+
+ /* Restore the OLD_SCOPE since it was valid before the
+ failed attempt at finding the last
+ class-or-namespace-name. */
+ parser->scope = old_scope;
+ parser->qualifying_scope = saved_qualifying_scope;
+
+ /* If the next token is a decltype, and the one after that is a
+ `::', then the decltype has failed to resolve to a class or
+ enumeration type. Give this error even when parsing
+ tentatively since it can't possibly be valid--and we're going
+ to replace it with a CPP_NESTED_NAME_SPECIFIER below, so we
+ won't get another chance.*/
+ if (cp_lexer_next_token_is (parser->lexer, CPP_DECLTYPE)
+ && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ == CPP_SCOPE))
+ {
+ token = cp_lexer_consume_token (parser->lexer);
+ error_at (token->location, "decltype evaluates to %qT, "
+ "which is not a class or enumeration type",
+ token->u.value);
+ parser->scope = error_mark_node;
+ error_p = true;
+ /* As below. */
+ success = true;
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ if (cp_parser_uncommitted_to_tentative_parse_p (parser))
+ break;
+ /* If the next token is an identifier, and the one after
+ that is a `::', then any valid interpretation would have
+ found a class-or-namespace-name. */
+ while (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ == CPP_SCOPE)
+ && (cp_lexer_peek_nth_token (parser->lexer, 3)->type
+ != CPP_COMPL))
+ {
+ token = cp_lexer_consume_token (parser->lexer);
+ if (!error_p)
+ {
+ if (!token->ambiguous_p)
+ {
+ tree decl;
+ tree ambiguous_decls;
+
+ decl = cp_parser_lookup_name (parser, token->u.value,
+ none_type,
+ /*is_template=*/false,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true,
+ &ambiguous_decls,
+ token->location);
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ error_at (token->location,
+ "%qD used without template parameters",
+ decl);
+ else if (ambiguous_decls)
+ {
+ // cp_parser_lookup_name has the same diagnostic,
+ // thus make sure to emit it at most once.
+ if (cp_parser_uncommitted_to_tentative_parse_p
+ (parser))
+ {
+ error_at (token->location,
+ "reference to %qD is ambiguous",
+ token->u.value);
+ print_candidates (ambiguous_decls);
+ }
+ decl = error_mark_node;
+ }
+ else
+ {
+ if (cxx_dialect != cxx98)
+ cp_parser_name_lookup_error
+ (parser, token->u.value, decl, NLE_NOT_CXX98,
+ token->location);
+ else
+ cp_parser_name_lookup_error
+ (parser, token->u.value, decl, NLE_CXX98,
+ token->location);
+ }
+ }
+ parser->scope = error_mark_node;
+ error_p = true;
+ /* Treat this as a successful nested-name-specifier
+ due to:
+
+ [basic.lookup.qual]
+
+ If the name found is not a class-name (clause
+ _class_) or namespace-name (_namespace.def_), the
+ program is ill-formed. */
+ success = true;
+ }
+ cp_lexer_consume_token (parser->lexer);
+ }
+ break;
+ }
+ /* We've found one valid nested-name-specifier. */
+ success = true;
+ /* Name lookup always gives us a DECL. */
+ if (TREE_CODE (new_scope) == TYPE_DECL)
+ new_scope = TREE_TYPE (new_scope);
+ /* Uses of "template" must be followed by actual templates. */
+ if (template_keyword_p
+ && !(CLASS_TYPE_P (new_scope)
+ && ((CLASSTYPE_USE_TEMPLATE (new_scope)
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (new_scope)))
+ || CLASSTYPE_IS_TEMPLATE (new_scope)))
+ && !(TREE_CODE (new_scope) == TYPENAME_TYPE
+ && (TREE_CODE (TYPENAME_TYPE_FULLNAME (new_scope))
+ == TEMPLATE_ID_EXPR)))
+ permerror (input_location, TYPE_P (new_scope)
+ ? G_("%qT is not a template")
+ : G_("%qD is not a template"),
+ new_scope);
+ /* If it is a class scope, try to complete it; we are about to
+ be looking up names inside the class. */
+ if (TYPE_P (new_scope)
+ /* Since checking types for dependency can be expensive,
+ avoid doing it if the type is already complete. */
+ && !COMPLETE_TYPE_P (new_scope)
+ /* Do not try to complete dependent types. */
+ && !dependent_type_p (new_scope))
+ {
+ new_scope = complete_type (new_scope);
+ /* If it is a typedef to current class, use the current
+ class instead, as the typedef won't have any names inside
+ it yet. */
+ if (!COMPLETE_TYPE_P (new_scope)
+ && currently_open_class (new_scope))
+ new_scope = TYPE_MAIN_VARIANT (new_scope);
+ }
+ /* Make sure we look in the right scope the next time through
+ the loop. */
+ parser->scope = new_scope;
+ }
+
+ /* If parsing tentatively, replace the sequence of tokens that makes
+ up the nested-name-specifier with a CPP_NESTED_NAME_SPECIFIER
+ token. That way, should we re-parse the token stream, we will
+ not have to repeat the effort required to do the parse, nor will
+ we issue duplicate error messages. */
+ if (success && start)
+ {
+ cp_token *token;
+
+ token = cp_lexer_token_at (parser->lexer, start);
+ /* Reset the contents of the START token. */
+ token->type = CPP_NESTED_NAME_SPECIFIER;
+ /* Retrieve any deferred checks. Do not pop this access checks yet
+ so the memory will not be reclaimed during token replacing below. */
+ token->u.tree_check_value = ggc_alloc_cleared_tree_check ();
+ token->u.tree_check_value->value = parser->scope;
+ token->u.tree_check_value->checks = get_deferred_access_checks ();
+ token->u.tree_check_value->qualifying_scope =
+ parser->qualifying_scope;
+ token->keyword = RID_MAX;
+
+ /* Purge all subsequent tokens. */
+ cp_lexer_purge_tokens_after (parser->lexer, start);
+ }
+
+ if (start)
+ pop_to_parent_deferring_access_checks ();
+
+ return success ? parser->scope : NULL_TREE;
+}
+
+/* Parse a nested-name-specifier. See
+ cp_parser_nested_name_specifier_opt for details. This function
+ behaves identically, except that it will an issue an error if no
+ nested-name-specifier is present. */
+
+static tree
+cp_parser_nested_name_specifier (cp_parser *parser,
+ bool typename_keyword_p,
+ bool check_dependency_p,
+ bool type_p,
+ bool is_declaration)
+{
+ tree scope;
+
+ /* Look for the nested-name-specifier. */
+ scope = cp_parser_nested_name_specifier_opt (parser,
+ typename_keyword_p,
+ check_dependency_p,
+ type_p,
+ is_declaration);
+ /* If it was not present, issue an error message. */
+ if (!scope)
+ {
+ cp_parser_error (parser, "expected nested-name-specifier");
+ parser->scope = NULL_TREE;
+ }
+
+ return scope;
+}
+
+/* Parse the qualifying entity in a nested-name-specifier. For C++98,
+ this is either a class-name or a namespace-name (which corresponds
+ to the class-or-namespace-name production in the grammar). For
+ C++0x, it can also be a type-name that refers to an enumeration
+ type or a simple-template-id.
+
+ TYPENAME_KEYWORD_P is TRUE iff the `typename' keyword is in effect.
+ TEMPLATE_KEYWORD_P is TRUE iff the `template' keyword is in effect.
+ CHECK_DEPENDENCY_P is FALSE iff dependent names should be looked up.
+ TYPE_P is TRUE iff the next name should be taken as a class-name,
+ even the same name is declared to be another entity in the same
+ scope.
+
+ Returns the class (TYPE_DECL) or namespace (NAMESPACE_DECL)
+ specified by the class-or-namespace-name. If neither is found the
+ ERROR_MARK_NODE is returned. */
+
+static tree
+cp_parser_qualifying_entity (cp_parser *parser,
+ bool typename_keyword_p,
+ bool template_keyword_p,
+ bool check_dependency_p,
+ bool type_p,
+ bool is_declaration)
+{
+ tree saved_scope;
+ tree saved_qualifying_scope;
+ tree saved_object_scope;
+ tree scope;
+ bool only_class_p;
+ bool successful_parse_p;
+
+ /* DR 743: decltype can appear in a nested-name-specifier. */
+ if (cp_lexer_next_token_is_decltype (parser->lexer))
+ {
+ scope = cp_parser_decltype (parser);
+ if (TREE_CODE (scope) != ENUMERAL_TYPE
+ && !MAYBE_CLASS_TYPE_P (scope))
+ {
+ cp_parser_simulate_error (parser);
+ return error_mark_node;
+ }
+ if (TYPE_NAME (scope))
+ scope = TYPE_NAME (scope);
+ return scope;
+ }
+
+ /* Before we try to parse the class-name, we must save away the
+ current PARSER->SCOPE since cp_parser_class_name will destroy
+ it. */
+ saved_scope = parser->scope;
+ saved_qualifying_scope = parser->qualifying_scope;
+ saved_object_scope = parser->object_scope;
+ /* Try for a class-name first. If the SAVED_SCOPE is a type, then
+ there is no need to look for a namespace-name. */
+ only_class_p = template_keyword_p
+ || (saved_scope && TYPE_P (saved_scope) && cxx_dialect == cxx98);
+ if (!only_class_p)
+ cp_parser_parse_tentatively (parser);
+ scope = cp_parser_class_name (parser,
+ typename_keyword_p,
+ template_keyword_p,
+ type_p ? class_type : none_type,
+ check_dependency_p,
+ /*class_head_p=*/false,
+ is_declaration);
+ successful_parse_p = only_class_p || cp_parser_parse_definitely (parser);
+ /* If that didn't work and we're in C++0x mode, try for a type-name. */
+ if (!only_class_p
+ && cxx_dialect != cxx98
+ && !successful_parse_p)
+ {
+ /* Restore the saved scope. */
+ parser->scope = saved_scope;
+ parser->qualifying_scope = saved_qualifying_scope;
+ parser->object_scope = saved_object_scope;
+
+ /* Parse tentatively. */
+ cp_parser_parse_tentatively (parser);
+
+ /* Parse a type-name */
+ scope = cp_parser_type_name (parser);
+
+ /* "If the name found does not designate a namespace or a class,
+ enumeration, or dependent type, the program is ill-formed."
+
+ We cover classes and dependent types above and namespaces below,
+ so this code is only looking for enums. */
+ if (!scope || TREE_CODE (scope) != TYPE_DECL
+ || TREE_CODE (TREE_TYPE (scope)) != ENUMERAL_TYPE)
+ cp_parser_simulate_error (parser);
+
+ successful_parse_p = cp_parser_parse_definitely (parser);
+ }
+ /* If that didn't work, try for a namespace-name. */
+ if (!only_class_p && !successful_parse_p)
+ {
+ /* Restore the saved scope. */
+ parser->scope = saved_scope;
+ parser->qualifying_scope = saved_qualifying_scope;
+ parser->object_scope = saved_object_scope;
+ /* If we are not looking at an identifier followed by the scope
+ resolution operator, then this is not part of a
+ nested-name-specifier. (Note that this function is only used
+ to parse the components of a nested-name-specifier.) */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)
+ || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
+ return error_mark_node;
+ scope = cp_parser_namespace_name (parser);
+ }
+
+ return scope;
+}
+
+/* Parse a postfix-expression.
+
+ postfix-expression:
+ primary-expression
+ postfix-expression [ expression ]
+ postfix-expression ( expression-list [opt] )
+ simple-type-specifier ( expression-list [opt] )
+ typename :: [opt] nested-name-specifier identifier
+ ( expression-list [opt] )
+ typename :: [opt] nested-name-specifier template [opt] template-id
+ ( expression-list [opt] )
+ postfix-expression . template [opt] id-expression
+ postfix-expression -> template [opt] id-expression
+ postfix-expression . pseudo-destructor-name
+ postfix-expression -> pseudo-destructor-name
+ postfix-expression ++
+ postfix-expression --
+ dynamic_cast < type-id > ( expression )
+ static_cast < type-id > ( expression )
+ reinterpret_cast < type-id > ( expression )
+ const_cast < type-id > ( expression )
+ typeid ( expression )
+ typeid ( type-id )
+
+ GNU Extension:
+
+ postfix-expression:
+ ( type-id ) { initializer-list , [opt] }
+
+ This extension is a GNU version of the C99 compound-literal
+ construct. (The C99 grammar uses `type-name' instead of `type-id',
+ but they are essentially the same concept.)
+
+ If ADDRESS_P is true, the postfix expression is the operand of the
+ `&' operator. CAST_P is true if this expression is the target of a
+ cast.
+
+ If MEMBER_ACCESS_ONLY_P, we only allow postfix expressions that are
+ class member access expressions [expr.ref].
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
+ bool member_access_only_p, bool decltype_p,
+ cp_id_kind * pidk_return)
+{
+ cp_token *token;
+ location_t loc;
+ enum rid keyword;
+ cp_id_kind idk = CP_ID_KIND_NONE;
+ tree postfix_expression = NULL_TREE;
+ bool is_member_access = false;
+ int saved_in_statement = -1;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ loc = token->location;
+ /* Some of the productions are determined by keywords. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ case RID_DYNCAST:
+ case RID_STATCAST:
+ case RID_REINTCAST:
+ case RID_CONSTCAST:
+ {
+ tree type;
+ tree expression;
+ const char *saved_message;
+ bool saved_in_type_id_in_expr_p;
+
+ /* All of these can be handled in the same way from the point
+ of view of parsing. Begin by consuming the token
+ identifying the cast. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* New types cannot be defined in the cast. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in casts");
+
+ /* Look for the opening `<'. */
+ cp_parser_require (parser, CPP_LESS, RT_LESS);
+ /* Parse the type to which we are casting. */
+ saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
+ type = cp_parser_type_id (parser);
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+ /* Look for the closing `>'. */
+ cp_parser_require (parser, CPP_GREATER, RT_GREATER);
+ /* Restore the old message. */
+ parser->type_definition_forbidden_message = saved_message;
+
+ bool saved_greater_than_is_operator_p
+ = parser->greater_than_is_operator_p;
+ parser->greater_than_is_operator_p = true;
+
+ /* And the expression which is being cast. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ expression = cp_parser_expression (parser, /*cast_p=*/true, & idk);
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+
+ /* Only type conversions to integral or enumeration types
+ can be used in constant-expressions. */
+ if (!cast_valid_in_integral_constant_expression_p (type)
+ && cp_parser_non_integral_constant_expression (parser, NIC_CAST))
+ return error_mark_node;
+
+ switch (keyword)
+ {
+ case RID_DYNCAST:
+ postfix_expression
+ = build_dynamic_cast (type, expression, tf_warning_or_error);
+ break;
+ case RID_STATCAST:
+ postfix_expression
+ = build_static_cast (type, expression, tf_warning_or_error);
+ break;
+ case RID_REINTCAST:
+ postfix_expression
+ = build_reinterpret_cast (type, expression,
+ tf_warning_or_error);
+ break;
+ case RID_CONSTCAST:
+ postfix_expression
+ = build_const_cast (type, expression, tf_warning_or_error);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ break;
+
+ case RID_TYPEID:
+ {
+ tree type;
+ const char *saved_message;
+ bool saved_in_type_id_in_expr_p;
+
+ /* Consume the `typeid' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the `(' token. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ /* Types cannot be defined in a `typeid' expression. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in a %<typeid%> expression");
+ /* We can't be sure yet whether we're looking at a type-id or an
+ expression. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a type-id first. */
+ saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
+ type = cp_parser_type_id (parser);
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+ /* Look for the `)' token. Otherwise, we can't be sure that
+ we're not looking at an expression: consider `typeid (int
+ (3))', for example. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ /* If all went well, simply lookup the type-id. */
+ if (cp_parser_parse_definitely (parser))
+ postfix_expression = get_typeid (type, tf_warning_or_error);
+ /* Otherwise, fall back to the expression variant. */
+ else
+ {
+ tree expression;
+
+ /* Look for an expression. */
+ expression = cp_parser_expression (parser, /*cast_p=*/false, & idk);
+ /* Compute its typeid. */
+ postfix_expression = build_typeid (expression, tf_warning_or_error);
+ /* Look for the `)' token. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ }
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+ /* `typeid' may not appear in an integral constant expression. */
+ if (cp_parser_non_integral_constant_expression (parser, NIC_TYPEID))
+ return error_mark_node;
+ }
+ break;
+
+ case RID_TYPENAME:
+ {
+ tree type;
+ /* The syntax permitted here is the same permitted for an
+ elaborated-type-specifier. */
+ type = cp_parser_elaborated_type_specifier (parser,
+ /*is_friend=*/false,
+ /*is_declaration=*/false);
+ postfix_expression = cp_parser_functional_cast (parser, type);
+ }
+ break;
+
+ case RID_CILK_SPAWN:
+ {
+ cp_lexer_consume_token (parser->lexer);
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_SEMICOLON)
+ {
+ error_at (token->location, "%<_Cilk_spawn%> must be followed by "
+ "an expression");
+ postfix_expression = error_mark_node;
+ break;
+ }
+ else if (!current_function_decl)
+ {
+ error_at (token->location, "%<_Cilk_spawn%> may only be used "
+ "inside a function");
+ postfix_expression = error_mark_node;
+ break;
+ }
+ else
+ {
+ /* Consecutive _Cilk_spawns are not allowed in a statement. */
+ saved_in_statement = parser->in_statement;
+ parser->in_statement |= IN_CILK_SPAWN;
+ }
+ cfun->calls_cilk_spawn = 1;
+ postfix_expression =
+ cp_parser_postfix_expression (parser, false, false,
+ false, false, &idk);
+ if (!flag_cilkplus)
+ {
+ error_at (token->location, "-fcilkplus must be enabled to use"
+ " %<_Cilk_spawn%>");
+ cfun->calls_cilk_spawn = 0;
+ }
+ else if (saved_in_statement & IN_CILK_SPAWN)
+ {
+ error_at (token->location, "consecutive %<_Cilk_spawn%> keywords "
+ "are not permitted");
+ postfix_expression = error_mark_node;
+ cfun->calls_cilk_spawn = 0;
+ }
+ else
+ {
+ postfix_expression = build_cilk_spawn (token->location,
+ postfix_expression);
+ if (postfix_expression != error_mark_node)
+ SET_EXPR_LOCATION (postfix_expression, input_location);
+ parser->in_statement = parser->in_statement & ~IN_CILK_SPAWN;
+ }
+ break;
+ }
+
+ case RID_CILK_SYNC:
+ if (flag_cilkplus)
+ {
+ tree sync_expr = build_cilk_sync ();
+ SET_EXPR_LOCATION (sync_expr,
+ cp_lexer_peek_token (parser->lexer)->location);
+ finish_expr_stmt (sync_expr);
+ }
+ else
+ error_at (token->location, "-fcilkplus must be enabled to use"
+ " %<_Cilk_sync%>");
+ cp_lexer_consume_token (parser->lexer);
+ break;
+
+ case RID_BUILTIN_SHUFFLE:
+ {
+ vec<tree, va_gc> *vec;
+ unsigned int i;
+ tree p;
+
+ cp_lexer_consume_token (parser->lexer);
+ vec = cp_parser_parenthesized_expression_list (parser, non_attr,
+ /*cast_p=*/false, /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL);
+ if (vec == NULL)
+ return error_mark_node;
+
+ FOR_EACH_VEC_ELT (*vec, i, p)
+ mark_exp_read (p);
+
+ if (vec->length () == 2)
+ return build_x_vec_perm_expr (loc, (*vec)[0], NULL_TREE, (*vec)[1],
+ tf_warning_or_error);
+ else if (vec->length () == 3)
+ return build_x_vec_perm_expr (loc, (*vec)[0], (*vec)[1], (*vec)[2],
+ tf_warning_or_error);
+ else
+ {
+ error_at (loc, "wrong number of arguments to "
+ "%<__builtin_shuffle%>");
+ return error_mark_node;
+ }
+ break;
+ }
+
+ default:
+ {
+ tree type;
+
+ /* If the next thing is a simple-type-specifier, we may be
+ looking at a functional cast. We could also be looking at
+ an id-expression. So, we try the functional cast, and if
+ that doesn't work we fall back to the primary-expression. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for the simple-type-specifier. */
+ type = cp_parser_simple_type_specifier (parser,
+ /*decl_specs=*/NULL,
+ CP_PARSER_FLAGS_NONE);
+ /* Parse the cast itself. */
+ if (!cp_parser_error_occurred (parser))
+ postfix_expression
+ = cp_parser_functional_cast (parser, type);
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ break;
+
+ /* If the functional-cast didn't work out, try a
+ compound-literal. */
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ tree initializer = NULL_TREE;
+ bool compound_literal_p;
+
+ cp_parser_parse_tentatively (parser);
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Avoid calling cp_parser_type_id pointlessly, see comment
+ in cp_parser_cast_expression about c++/29234. */
+ cp_lexer_save_tokens (parser->lexer);
+
+ compound_literal_p
+ = (cp_parser_skip_to_closing_parenthesis (parser, false, false,
+ /*consume_paren=*/true)
+ && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE));
+
+ /* Roll back the tokens we skipped. */
+ cp_lexer_rollback_tokens (parser->lexer);
+
+ if (!compound_literal_p)
+ cp_parser_simulate_error (parser);
+ else
+ {
+ /* Parse the type. */
+ bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
+ type = cp_parser_type_id (parser);
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ }
+
+ /* If things aren't going well, there's no need to
+ keep going. */
+ if (!cp_parser_error_occurred (parser))
+ {
+ bool non_constant_p;
+ /* Parse the brace-enclosed initializer list. */
+ initializer = cp_parser_braced_list (parser,
+ &non_constant_p);
+ }
+ /* If that worked, we're definitely looking at a
+ compound-literal expression. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ /* Warn the user that a compound literal is not
+ allowed in standard C++. */
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ forbids compound-literals");
+ /* For simplicity, we disallow compound literals in
+ constant-expressions. We could
+ allow compound literals of integer type, whose
+ initializer was a constant, in constant
+ expressions. Permitting that usage, as a further
+ extension, would not change the meaning of any
+ currently accepted programs. (Of course, as
+ compound literals are not part of ISO C++, the
+ standard has nothing to say.) */
+ if (cp_parser_non_integral_constant_expression (parser,
+ NIC_NCC))
+ {
+ postfix_expression = error_mark_node;
+ break;
+ }
+ /* Form the representation of the compound-literal. */
+ postfix_expression
+ = finish_compound_literal (type, initializer,
+ tf_warning_or_error);
+ break;
+ }
+ }
+
+ /* It must be a primary-expression. */
+ postfix_expression
+ = cp_parser_primary_expression (parser, address_p, cast_p,
+ /*template_arg_p=*/false,
+ decltype_p,
+ &idk);
+ }
+ break;
+ }
+
+ /* Note that we don't need to worry about calling build_cplus_new on a
+ class-valued CALL_EXPR in decltype when it isn't the end of the
+ postfix-expression; unary_complex_lvalue will take care of that for
+ all these cases. */
+
+ /* Keep looping until the postfix-expression is complete. */
+ while (true)
+ {
+ if (idk == CP_ID_KIND_UNQUALIFIED
+ && identifier_p (postfix_expression)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
+ /* It is not a Koenig lookup function call. */
+ postfix_expression
+ = unqualified_name_lookup_error (postfix_expression);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_OPEN_SQUARE:
+ if (cp_next_tokens_can_be_std_attribute_p (parser))
+ {
+ cp_parser_error (parser,
+ "two consecutive %<[%> shall "
+ "only introduce an attribute");
+ return error_mark_node;
+ }
+ postfix_expression
+ = cp_parser_postfix_open_square_expression (parser,
+ postfix_expression,
+ false,
+ decltype_p);
+ idk = CP_ID_KIND_NONE;
+ is_member_access = false;
+ break;
+
+ case CPP_OPEN_PAREN:
+ /* postfix-expression ( expression-list [opt] ) */
+ {
+ bool koenig_p;
+ bool is_builtin_constant_p;
+ bool saved_integral_constant_expression_p = false;
+ bool saved_non_integral_constant_expression_p = false;
+ tsubst_flags_t complain = complain_flags (decltype_p);
+ vec<tree, va_gc> *args;
+
+ is_member_access = false;
+
+ is_builtin_constant_p
+ = DECL_IS_BUILTIN_CONSTANT_P (postfix_expression);
+ if (is_builtin_constant_p)
+ {
+ /* The whole point of __builtin_constant_p is to allow
+ non-constant expressions to appear as arguments. */
+ saved_integral_constant_expression_p
+ = parser->integral_constant_expression_p;
+ saved_non_integral_constant_expression_p
+ = parser->non_integral_constant_expression_p;
+ parser->integral_constant_expression_p = false;
+ }
+ args = (cp_parser_parenthesized_expression_list
+ (parser, non_attr,
+ /*cast_p=*/false, /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL));
+ if (is_builtin_constant_p)
+ {
+ parser->integral_constant_expression_p
+ = saved_integral_constant_expression_p;
+ parser->non_integral_constant_expression_p
+ = saved_non_integral_constant_expression_p;
+ }
+
+ if (args == NULL)
+ {
+ postfix_expression = error_mark_node;
+ break;
+ }
+
+ /* Function calls are not permitted in
+ constant-expressions. */
+ if (! builtin_valid_in_constant_expr_p (postfix_expression)
+ && cp_parser_non_integral_constant_expression (parser,
+ NIC_FUNC_CALL))
+ {
+ postfix_expression = error_mark_node;
+ release_tree_vector (args);
+ break;
+ }
+
+ koenig_p = false;
+ if (idk == CP_ID_KIND_UNQUALIFIED
+ || idk == CP_ID_KIND_TEMPLATE_ID)
+ {
+ if (identifier_p (postfix_expression))
+ {
+ if (!args->is_empty ())
+ {
+ koenig_p = true;
+ if (!any_type_dependent_arguments_p (args))
+ postfix_expression
+ = perform_koenig_lookup (postfix_expression, args,
+ complain);
+ }
+ else
+ postfix_expression
+ = unqualified_fn_lookup_error (postfix_expression);
+ }
+ /* We do not perform argument-dependent lookup if
+ normal lookup finds a non-function, in accordance
+ with the expected resolution of DR 218. */
+ else if (!args->is_empty ()
+ && is_overloaded_fn (postfix_expression))
+ {
+ tree fn = get_first_fn (postfix_expression);
+ fn = STRIP_TEMPLATE (fn);
+
+ /* Do not do argument dependent lookup if regular
+ lookup finds a member function or a block-scope
+ function declaration. [basic.lookup.argdep]/3 */
+ if (!DECL_FUNCTION_MEMBER_P (fn)
+ && !DECL_LOCAL_FUNCTION_P (fn))
+ {
+ koenig_p = true;
+ if (!any_type_dependent_arguments_p (args))
+ postfix_expression
+ = perform_koenig_lookup (postfix_expression, args,
+ complain);
+ }
+ }
+ }
+
+ if (TREE_CODE (postfix_expression) == COMPONENT_REF)
+ {
+ tree instance = TREE_OPERAND (postfix_expression, 0);
+ tree fn = TREE_OPERAND (postfix_expression, 1);
+
+ if (processing_template_decl
+ && (type_dependent_expression_p (instance)
+ || (!BASELINK_P (fn)
+ && TREE_CODE (fn) != FIELD_DECL)
+ || type_dependent_expression_p (fn)
+ || any_type_dependent_arguments_p (args)))
+ {
+ postfix_expression
+ = build_nt_call_vec (postfix_expression, args);
+ release_tree_vector (args);
+ break;
+ }
+
+ if (BASELINK_P (fn))
+ {
+ postfix_expression
+ = (build_new_method_call
+ (instance, fn, &args, NULL_TREE,
+ (idk == CP_ID_KIND_QUALIFIED
+ ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
+ : LOOKUP_NORMAL),
+ /*fn_p=*/NULL,
+ complain));
+ }
+ else
+ postfix_expression
+ = finish_call_expr (postfix_expression, &args,
+ /*disallow_virtual=*/false,
+ /*koenig_p=*/false,
+ complain);
+ }
+ else if (TREE_CODE (postfix_expression) == OFFSET_REF
+ || TREE_CODE (postfix_expression) == MEMBER_REF
+ || TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
+ postfix_expression = (build_offset_ref_call_from_tree
+ (postfix_expression, &args,
+ complain));
+ else if (idk == CP_ID_KIND_QUALIFIED)
+ /* A call to a static class member, or a namespace-scope
+ function. */
+ postfix_expression
+ = finish_call_expr (postfix_expression, &args,
+ /*disallow_virtual=*/true,
+ koenig_p,
+ complain);
+ else
+ /* All other function calls. */
+ postfix_expression
+ = finish_call_expr (postfix_expression, &args,
+ /*disallow_virtual=*/false,
+ koenig_p,
+ complain);
+
+ /* The POSTFIX_EXPRESSION is certainly no longer an id. */
+ idk = CP_ID_KIND_NONE;
+
+ release_tree_vector (args);
+ }
+ break;
+
+ case CPP_DOT:
+ case CPP_DEREF:
+ /* postfix-expression . template [opt] id-expression
+ postfix-expression . pseudo-destructor-name
+ postfix-expression -> template [opt] id-expression
+ postfix-expression -> pseudo-destructor-name */
+
+ /* Consume the `.' or `->' operator. */
+ cp_lexer_consume_token (parser->lexer);
+
+ postfix_expression
+ = cp_parser_postfix_dot_deref_expression (parser, token->type,
+ postfix_expression,
+ false, &idk, loc);
+
+ is_member_access = true;
+ break;
+
+ case CPP_PLUS_PLUS:
+ /* postfix-expression ++ */
+ /* Consume the `++' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Generate a representation for the complete expression. */
+ postfix_expression
+ = finish_increment_expr (postfix_expression,
+ POSTINCREMENT_EXPR);
+ /* Increments may not appear in constant-expressions. */
+ if (cp_parser_non_integral_constant_expression (parser, NIC_INC))
+ postfix_expression = error_mark_node;
+ idk = CP_ID_KIND_NONE;
+ is_member_access = false;
+ break;
+
+ case CPP_MINUS_MINUS:
+ /* postfix-expression -- */
+ /* Consume the `--' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Generate a representation for the complete expression. */
+ postfix_expression
+ = finish_increment_expr (postfix_expression,
+ POSTDECREMENT_EXPR);
+ /* Decrements may not appear in constant-expressions. */
+ if (cp_parser_non_integral_constant_expression (parser, NIC_DEC))
+ postfix_expression = error_mark_node;
+ idk = CP_ID_KIND_NONE;
+ is_member_access = false;
+ break;
+
+ default:
+ if (pidk_return != NULL)
+ * pidk_return = idk;
+ if (member_access_only_p)
+ return is_member_access? postfix_expression : error_mark_node;
+ else
+ return postfix_expression;
+ }
+ }
+
+ /* We should never get here. */
+ gcc_unreachable ();
+ return error_mark_node;
+}
+
+/* This function parses Cilk Plus array notations. If a normal array expr. is
+ parsed then the array index is passed back to the caller through *INIT_INDEX
+ and the function returns a NULL_TREE. If array notation expr. is parsed,
+ then *INIT_INDEX is ignored by the caller and the function returns
+ a tree of type ARRAY_NOTATION_REF. If some error occurred it returns
+ error_mark_node. */
+
+static tree
+cp_parser_array_notation (location_t loc, cp_parser *parser, tree *init_index,
+ tree array_value)
+{
+ cp_token *token = NULL;
+ tree length_index, stride = NULL_TREE, value_tree, array_type;
+ if (!array_value || array_value == error_mark_node)
+ {
+ cp_parser_skip_to_end_of_statement (parser);
+ return error_mark_node;
+ }
+
+ array_type = TREE_TYPE (array_value);
+
+ bool saved_colon_corrects = parser->colon_corrects_to_scope_p;
+ parser->colon_corrects_to_scope_p = false;
+ token = cp_lexer_peek_token (parser->lexer);
+
+ if (!token)
+ {
+ cp_parser_error (parser, "expected %<:%> or numeral");
+ return error_mark_node;
+ }
+ else if (token->type == CPP_COLON)
+ {
+ /* Consume the ':'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* If we are here, then we have a case like this A[:]. */
+ if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE)
+ {
+ cp_parser_error (parser, "expected %<]%>");
+ cp_parser_skip_to_end_of_statement (parser);
+ return error_mark_node;
+ }
+ *init_index = NULL_TREE;
+ stride = NULL_TREE;
+ length_index = NULL_TREE;
+ }
+ else
+ {
+ /* If we are here, then there are three valid possibilities:
+ 1. ARRAY [ EXP ]
+ 2. ARRAY [ EXP : EXP ]
+ 3. ARRAY [ EXP : EXP : EXP ] */
+
+ *init_index = cp_parser_expression (parser, false, NULL);
+ if (cp_lexer_peek_token (parser->lexer)->type != CPP_COLON)
+ {
+ /* This indicates that we have a normal array expression. */
+ parser->colon_corrects_to_scope_p = saved_colon_corrects;
+ return NULL_TREE;
+ }
+
+ /* Consume the ':'. */
+ cp_lexer_consume_token (parser->lexer);
+ length_index = cp_parser_expression (parser, false, NULL);
+ if (cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ stride = cp_parser_expression (parser, false, NULL);
+ }
+ }
+ parser->colon_corrects_to_scope_p = saved_colon_corrects;
+
+ if (*init_index == error_mark_node || length_index == error_mark_node
+ || stride == error_mark_node)
+ {
+ if (cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_SQUARE)
+ cp_lexer_consume_token (parser->lexer);
+ return error_mark_node;
+ }
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+
+ value_tree = build_array_notation_ref (loc, array_value, *init_index,
+ length_index, stride, array_type);
+ return value_tree;
+}
+
+/* A subroutine of cp_parser_postfix_expression that also gets hijacked
+ by cp_parser_builtin_offsetof. We're looking for
+
+ postfix-expression [ expression ]
+ postfix-expression [ braced-init-list ] (C++11)
+
+ FOR_OFFSETOF is set if we're being called in that context, which
+ changes how we deal with integer constant expressions. */
+
+static tree
+cp_parser_postfix_open_square_expression (cp_parser *parser,
+ tree postfix_expression,
+ bool for_offsetof,
+ bool decltype_p)
+{
+ tree index = NULL_TREE;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+ bool saved_greater_than_is_operator_p;
+
+ /* Consume the `[' token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ saved_greater_than_is_operator_p = parser->greater_than_is_operator_p;
+ parser->greater_than_is_operator_p = true;
+
+ /* Parse the index expression. */
+ /* ??? For offsetof, there is a question of what to allow here. If
+ offsetof is not being used in an integral constant expression context,
+ then we *could* get the right answer by computing the value at runtime.
+ If we are in an integral constant expression context, then we might
+ could accept any constant expression; hard to say without analysis.
+ Rather than open the barn door too wide right away, allow only integer
+ constant expressions here. */
+ if (for_offsetof)
+ index = cp_parser_constant_expression (parser, false, NULL);
+ else
+ {
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ bool expr_nonconst_p;
+ cp_lexer_set_source_position (parser->lexer);
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ index = cp_parser_braced_list (parser, &expr_nonconst_p);
+ if (flag_cilkplus
+ && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
+ {
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "braced list index is not allowed with array "
+ "notation");
+ cp_parser_skip_to_end_of_statement (parser);
+ return error_mark_node;
+ }
+ }
+ else if (flag_cilkplus)
+ {
+ /* Here are have these two options:
+ ARRAY[EXP : EXP] - Array notation expr with default
+ stride of 1.
+ ARRAY[EXP : EXP : EXP] - Array Notation with user-defined
+ stride. */
+ tree an_exp = cp_parser_array_notation (loc, parser, &index,
+ postfix_expression);
+ if (an_exp)
+ return an_exp;
+ }
+ else
+ index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ }
+
+ parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;
+
+ /* Look for the closing `]'. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+
+ /* Build the ARRAY_REF. */
+ postfix_expression = grok_array_decl (loc, postfix_expression,
+ index, decltype_p);
+
+ /* When not doing offsetof, array references are not permitted in
+ constant-expressions. */
+ if (!for_offsetof
+ && (cp_parser_non_integral_constant_expression (parser, NIC_ARRAY_REF)))
+ postfix_expression = error_mark_node;
+
+ return postfix_expression;
+}
+
+/* A subroutine of cp_parser_postfix_expression that also gets hijacked
+ by cp_parser_builtin_offsetof. We're looking for
+
+ postfix-expression . template [opt] id-expression
+ postfix-expression . pseudo-destructor-name
+ postfix-expression -> template [opt] id-expression
+ postfix-expression -> pseudo-destructor-name
+
+ FOR_OFFSETOF is set if we're being called in that context. That sorta
+ limits what of the above we'll actually accept, but nevermind.
+ TOKEN_TYPE is the "." or "->" token, which will already have been
+ removed from the stream. */
+
+static tree
+cp_parser_postfix_dot_deref_expression (cp_parser *parser,
+ enum cpp_ttype token_type,
+ tree postfix_expression,
+ bool for_offsetof, cp_id_kind *idk,
+ location_t location)
+{
+ tree name;
+ bool dependent_p;
+ bool pseudo_destructor_p;
+ tree scope = NULL_TREE;
+
+ /* If this is a `->' operator, dereference the pointer. */
+ if (token_type == CPP_DEREF)
+ postfix_expression = build_x_arrow (location, postfix_expression,
+ tf_warning_or_error);
+ /* Check to see whether or not the expression is type-dependent. */
+ dependent_p = type_dependent_expression_p (postfix_expression);
+ /* The identifier following the `->' or `.' is not qualified. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ *idk = CP_ID_KIND_NONE;
+
+ /* Enter the scope corresponding to the type of the object
+ given by the POSTFIX_EXPRESSION. */
+ if (!dependent_p && TREE_TYPE (postfix_expression) != NULL_TREE)
+ {
+ scope = TREE_TYPE (postfix_expression);
+ /* According to the standard, no expression should ever have
+ reference type. Unfortunately, we do not currently match
+ the standard in this respect in that our internal representation
+ of an expression may have reference type even when the standard
+ says it does not. Therefore, we have to manually obtain the
+ underlying type here. */
+ scope = non_reference (scope);
+ /* The type of the POSTFIX_EXPRESSION must be complete. */
+ if (scope == unknown_type_node)
+ {
+ error_at (location, "%qE does not have class type",
+ postfix_expression);
+ scope = NULL_TREE;
+ }
+ /* Unlike the object expression in other contexts, *this is not
+ required to be of complete type for purposes of class member
+ access (5.2.5) outside the member function body. */
+ else if (postfix_expression != current_class_ref
+ && !(processing_template_decl && scope == current_class_type))
+ scope = complete_type_or_else (scope, NULL_TREE);
+ /* Let the name lookup machinery know that we are processing a
+ class member access expression. */
+ parser->context->object_type = scope;
+ /* If something went wrong, we want to be able to discern that case,
+ as opposed to the case where there was no SCOPE due to the type
+ of expression being dependent. */
+ if (!scope)
+ scope = error_mark_node;
+ /* If the SCOPE was erroneous, make the various semantic analysis
+ functions exit quickly -- and without issuing additional error
+ messages. */
+ if (scope == error_mark_node)
+ postfix_expression = error_mark_node;
+ }
+
+ /* Assume this expression is not a pseudo-destructor access. */
+ pseudo_destructor_p = false;
+
+ /* If the SCOPE is a scalar type, then, if this is a valid program,
+ we must be looking at a pseudo-destructor-name. If POSTFIX_EXPRESSION
+ is type dependent, it can be pseudo-destructor-name or something else.
+ Try to parse it as pseudo-destructor-name first. */
+ if ((scope && SCALAR_TYPE_P (scope)) || dependent_p)
+ {
+ tree s;
+ tree type;
+
+ cp_parser_parse_tentatively (parser);
+ /* Parse the pseudo-destructor-name. */
+ s = NULL_TREE;
+ cp_parser_pseudo_destructor_name (parser, postfix_expression,
+ &s, &type);
+ if (dependent_p
+ && (cp_parser_error_occurred (parser)
+ || !SCALAR_TYPE_P (type)))
+ cp_parser_abort_tentative_parse (parser);
+ else if (cp_parser_parse_definitely (parser))
+ {
+ pseudo_destructor_p = true;
+ postfix_expression
+ = finish_pseudo_destructor_expr (postfix_expression,
+ s, type, location);
+ }
+ }
+
+ if (!pseudo_destructor_p)
+ {
+ /* If the SCOPE is not a scalar type, we are looking at an
+ ordinary class member access expression, rather than a
+ pseudo-destructor-name. */
+ bool template_p;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ /* Parse the id-expression. */
+ name = (cp_parser_id_expression
+ (parser,
+ cp_parser_optional_template_keyword (parser),
+ /*check_dependency_p=*/true,
+ &template_p,
+ /*declarator_p=*/false,
+ /*optional_p=*/false));
+ /* In general, build a SCOPE_REF if the member name is qualified.
+ However, if the name was not dependent and has already been
+ resolved; there is no need to build the SCOPE_REF. For example;
+
+ struct X { void f(); };
+ template <typename T> void f(T* t) { t->X::f(); }
+
+ Even though "t" is dependent, "X::f" is not and has been resolved
+ to a BASELINK; there is no need to include scope information. */
+
+ /* But we do need to remember that there was an explicit scope for
+ virtual function calls. */
+ if (parser->scope)
+ *idk = CP_ID_KIND_QUALIFIED;
+
+ /* If the name is a template-id that names a type, we will get a
+ TYPE_DECL here. That is invalid code. */
+ if (TREE_CODE (name) == TYPE_DECL)
+ {
+ error_at (token->location, "invalid use of %qD", name);
+ postfix_expression = error_mark_node;
+ }
+ else
+ {
+ if (name != error_mark_node && !BASELINK_P (name) && parser->scope)
+ {
+ if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
+ {
+ error_at (token->location, "%<%D::%D%> is not a class member",
+ parser->scope, name);
+ postfix_expression = error_mark_node;
+ }
+ else
+ name = build_qualified_name (/*type=*/NULL_TREE,
+ parser->scope,
+ name,
+ template_p);
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ }
+ if (parser->scope && name && BASELINK_P (name))
+ adjust_result_of_qualified_name_lookup
+ (name, parser->scope, scope);
+ postfix_expression
+ = finish_class_member_access_expr (postfix_expression, name,
+ template_p,
+ tf_warning_or_error);
+ }
+ }
+
+ /* We no longer need to look up names in the scope of the object on
+ the left-hand side of the `.' or `->' operator. */
+ parser->context->object_type = NULL_TREE;
+
+ /* Outside of offsetof, these operators may not appear in
+ constant-expressions. */
+ if (!for_offsetof
+ && (cp_parser_non_integral_constant_expression
+ (parser, token_type == CPP_DEREF ? NIC_ARROW : NIC_POINT)))
+ postfix_expression = error_mark_node;
+
+ return postfix_expression;
+}
+
+/* Parse a parenthesized expression-list.
+
+ expression-list:
+ assignment-expression
+ expression-list, assignment-expression
+
+ attribute-list:
+ expression-list
+ identifier
+ identifier, expression-list
+
+ CAST_P is true if this expression is the target of a cast.
+
+ ALLOW_EXPANSION_P is true if this expression allows expansion of an
+ argument pack.
+
+ Returns a vector of trees. Each element is a representation of an
+ assignment-expression. NULL is returned if the ( and or ) are
+ missing. An empty, but allocated, vector is returned on no
+ expressions. The parentheses are eaten. IS_ATTRIBUTE_LIST is id_attr
+ if we are parsing an attribute list for an attribute that wants a
+ plain identifier argument, normal_attr for an attribute that wants
+ an expression, or non_attr if we aren't parsing an attribute list. If
+ NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or
+ not all of the expressions in the list were constant. */
+
+static vec<tree, va_gc> *
+cp_parser_parenthesized_expression_list (cp_parser* parser,
+ int is_attribute_list,
+ bool cast_p,
+ bool allow_expansion_p,
+ bool *non_constant_p)
+{
+ vec<tree, va_gc> *expression_list;
+ bool fold_expr_p = is_attribute_list != non_attr;
+ tree identifier = NULL_TREE;
+ bool saved_greater_than_is_operator_p;
+
+ /* Assume all the expressions will be constant. */
+ if (non_constant_p)
+ *non_constant_p = false;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return NULL;
+
+ expression_list = make_tree_vector ();
+
+ /* Within a parenthesized expression, a `>' token is always
+ the greater-than operator. */
+ saved_greater_than_is_operator_p
+ = parser->greater_than_is_operator_p;
+ parser->greater_than_is_operator_p = true;
+
+ /* Consume expressions until there are no more. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
+ while (true)
+ {
+ tree expr;
+
+ /* At the beginning of attribute lists, check to see if the
+ next token is an identifier. */
+ if (is_attribute_list == id_attr
+ && cp_lexer_peek_token (parser->lexer)->type == CPP_NAME)
+ {
+ cp_token *token;
+
+ /* Consume the identifier. */
+ token = cp_lexer_consume_token (parser->lexer);
+ /* Save the identifier. */
+ identifier = token->u.value;
+ }
+ else
+ {
+ bool expr_non_constant_p;
+
+ /* Parse the next assignment-expression. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ /* A braced-init-list. */
+ cp_lexer_set_source_position (parser->lexer);
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ expr = cp_parser_braced_list (parser, &expr_non_constant_p);
+ if (non_constant_p && expr_non_constant_p)
+ *non_constant_p = true;
+ }
+ else if (non_constant_p)
+ {
+ expr = (cp_parser_constant_expression
+ (parser, /*allow_non_constant_p=*/true,
+ &expr_non_constant_p));
+ if (expr_non_constant_p)
+ *non_constant_p = true;
+ }
+ else
+ expr = cp_parser_assignment_expression (parser, cast_p, NULL);
+
+ if (fold_expr_p)
+ expr = fold_non_dependent_expr (expr);
+
+ /* If we have an ellipsis, then this is an expression
+ expansion. */
+ if (allow_expansion_p
+ && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ /* Consume the `...'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Build the argument pack. */
+ expr = make_pack_expansion (expr);
+ }
+
+ /* Add it to the list. We add error_mark_node
+ expressions to the list, so that we can still tell if
+ the correct form for a parenthesized expression-list
+ is found. That gives better errors. */
+ vec_safe_push (expression_list, expr);
+
+ if (expr == error_mark_node)
+ goto skip_comma;
+ }
+
+ /* After the first item, attribute lists look the same as
+ expression lists. */
+ is_attribute_list = non_attr;
+
+ get_comma:;
+ /* If the next token isn't a `,', then we are done. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+
+ /* Otherwise, consume the `,' and keep going. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ {
+ int ending;
+
+ skip_comma:;
+ /* We try and resync to an unnested comma, as that will give the
+ user better diagnostics. */
+ ending = cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/true,
+ /*consume_paren=*/true);
+ if (ending < 0)
+ goto get_comma;
+ if (!ending)
+ {
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+ return NULL;
+ }
+ }
+
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+
+ if (identifier)
+ vec_safe_insert (expression_list, 0, identifier);
+
+ return expression_list;
+}
+
+/* Parse a pseudo-destructor-name.
+
+ pseudo-destructor-name:
+ :: [opt] nested-name-specifier [opt] type-name :: ~ type-name
+ :: [opt] nested-name-specifier template template-id :: ~ type-name
+ :: [opt] nested-name-specifier [opt] ~ type-name
+
+ If either of the first two productions is used, sets *SCOPE to the
+ TYPE specified before the final `::'. Otherwise, *SCOPE is set to
+ NULL_TREE. *TYPE is set to the TYPE_DECL for the final type-name,
+ or ERROR_MARK_NODE if the parse fails. */
+
+static void
+cp_parser_pseudo_destructor_name (cp_parser* parser,
+ tree object,
+ tree* scope,
+ tree* type)
+{
+ bool nested_name_specifier_p;
+
+ /* Handle ~auto. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMPL)
+ && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_AUTO)
+ && !type_dependent_expression_p (object))
+ {
+ if (cxx_dialect < cxx1y)
+ pedwarn (input_location, 0,
+ "%<~auto%> only available with "
+ "-std=c++1y or -std=gnu++1y");
+ cp_lexer_consume_token (parser->lexer);
+ cp_lexer_consume_token (parser->lexer);
+ *scope = NULL_TREE;
+ *type = TREE_TYPE (object);
+ return;
+ }
+
+ /* Assume that things will not work out. */
+ *type = error_mark_node;
+
+ /* Look for the optional `::' operator. */
+ cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/true);
+ /* Look for the optional nested-name-specifier. */
+ nested_name_specifier_p
+ = (cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/false)
+ != NULL_TREE);
+ /* Now, if we saw a nested-name-specifier, we might be doing the
+ second production. */
+ if (nested_name_specifier_p
+ && cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
+ {
+ /* Consume the `template' keyword. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the template-id. */
+ cp_parser_template_id (parser,
+ /*template_keyword_p=*/true,
+ /*check_dependency_p=*/false,
+ class_type,
+ /*is_declaration=*/true);
+ /* Look for the `::' token. */
+ cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
+ }
+ /* If the next token is not a `~', then there might be some
+ additional qualification. */
+ else if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMPL))
+ {
+ /* At this point, we're looking for "type-name :: ~". The type-name
+ must not be a class-name, since this is a pseudo-destructor. So,
+ it must be either an enum-name, or a typedef-name -- both of which
+ are just identifiers. So, we peek ahead to check that the "::"
+ and "~" tokens are present; if they are not, then we can avoid
+ calling type_name. */
+ if (cp_lexer_peek_token (parser->lexer)->type != CPP_NAME
+ || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE
+ || cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_COMPL)
+ {
+ cp_parser_error (parser, "non-scalar type");
+ return;
+ }
+
+ /* Look for the type-name. */
+ *scope = TREE_TYPE (cp_parser_nonclass_name (parser));
+ if (*scope == error_mark_node)
+ return;
+
+ /* Look for the `::' token. */
+ cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
+ }
+ else
+ *scope = NULL_TREE;
+
+ /* Look for the `~'. */
+ cp_parser_require (parser, CPP_COMPL, RT_COMPL);
+
+ /* Once we see the ~, this has to be a pseudo-destructor. */
+ if (!processing_template_decl && !cp_parser_error_occurred (parser))
+ cp_parser_commit_to_topmost_tentative_parse (parser);
+
+ /* Look for the type-name again. We are not responsible for
+ checking that it matches the first type-name. */
+ *type = TREE_TYPE (cp_parser_nonclass_name (parser));
+}
+
+/* Parse a unary-expression.
+
+ unary-expression:
+ postfix-expression
+ ++ cast-expression
+ -- cast-expression
+ unary-operator cast-expression
+ sizeof unary-expression
+ sizeof ( type-id )
+ alignof ( type-id ) [C++0x]
+ new-expression
+ delete-expression
+
+ GNU Extensions:
+
+ unary-expression:
+ __extension__ cast-expression
+ __alignof__ unary-expression
+ __alignof__ ( type-id )
+ alignof unary-expression [C++0x]
+ __real__ cast-expression
+ __imag__ cast-expression
+ && identifier
+ sizeof ( type-id ) { initializer-list , [opt] }
+ alignof ( type-id ) { initializer-list , [opt] } [C++0x]
+ __alignof__ ( type-id ) { initializer-list , [opt] }
+
+ ADDRESS_P is true iff the unary-expression is appearing as the
+ operand of the `&' operator. CAST_P is true if this expression is
+ the target of a cast.
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
+ bool decltype_p, cp_id_kind * pidk)
+{
+ cp_token *token;
+ enum tree_code unary_operator;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Some keywords give away the kind of expression. */
+ if (token->type == CPP_KEYWORD)
+ {
+ enum rid keyword = token->keyword;
+
+ switch (keyword)
+ {
+ case RID_ALIGNOF:
+ case RID_SIZEOF:
+ {
+ tree operand, ret;
+ enum tree_code op;
+ location_t first_loc;
+
+ op = keyword == RID_ALIGNOF ? ALIGNOF_EXPR : SIZEOF_EXPR;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ first_loc = cp_lexer_peek_token (parser->lexer)->location;
+ /* Parse the operand. */
+ operand = cp_parser_sizeof_operand (parser, keyword);
+
+ if (TYPE_P (operand))
+ ret = cxx_sizeof_or_alignof_type (operand, op, true);
+ else
+ {
+ /* ISO C++ defines alignof only with types, not with
+ expressions. So pedwarn if alignof is used with a non-
+ type expression. However, __alignof__ is ok. */
+ if (!strcmp (IDENTIFIER_POINTER (token->u.value), "alignof"))
+ pedwarn (token->location, OPT_Wpedantic,
+ "ISO C++ does not allow %<alignof%> "
+ "with a non-type");
+
+ ret = cxx_sizeof_or_alignof_expr (operand, op, true);
+ }
+ /* For SIZEOF_EXPR, just issue diagnostics, but keep
+ SIZEOF_EXPR with the original operand. */
+ if (op == SIZEOF_EXPR && ret != error_mark_node)
+ {
+ if (TREE_CODE (ret) != SIZEOF_EXPR || TYPE_P (operand))
+ {
+ if (!processing_template_decl && TYPE_P (operand))
+ {
+ ret = build_min (SIZEOF_EXPR, size_type_node,
+ build1 (NOP_EXPR, operand,
+ error_mark_node));
+ SIZEOF_EXPR_TYPE_P (ret) = 1;
+ }
+ else
+ ret = build_min (SIZEOF_EXPR, size_type_node, operand);
+ TREE_SIDE_EFFECTS (ret) = 0;
+ TREE_READONLY (ret) = 1;
+ }
+ SET_EXPR_LOCATION (ret, first_loc);
+ }
+ return ret;
+ }
+
+ case RID_NEW:
+ return cp_parser_new_expression (parser);
+
+ case RID_DELETE:
+ return cp_parser_delete_expression (parser);
+
+ case RID_EXTENSION:
+ {
+ /* The saved value of the PEDANTIC flag. */
+ int saved_pedantic;
+ tree expr;
+
+ /* Save away the PEDANTIC flag. */
+ cp_parser_extension_opt (parser, &saved_pedantic);
+ /* Parse the cast-expression. */
+ expr = cp_parser_simple_cast_expression (parser);
+ /* Restore the PEDANTIC flag. */
+ pedantic = saved_pedantic;
+
+ return expr;
+ }
+
+ case RID_REALPART:
+ case RID_IMAGPART:
+ {
+ tree expression;
+
+ /* Consume the `__real__' or `__imag__' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the cast-expression. */
+ expression = cp_parser_simple_cast_expression (parser);
+ /* Create the complete representation. */
+ return build_x_unary_op (token->location,
+ (keyword == RID_REALPART
+ ? REALPART_EXPR : IMAGPART_EXPR),
+ expression,
+ tf_warning_or_error);
+ }
+ break;
+
+ case RID_TRANSACTION_ATOMIC:
+ case RID_TRANSACTION_RELAXED:
+ return cp_parser_transaction_expression (parser, keyword);
+
+ case RID_NOEXCEPT:
+ {
+ tree expr;
+ const char *saved_message;
+ bool saved_integral_constant_expression_p;
+ bool saved_non_integral_constant_expression_p;
+ bool saved_greater_than_is_operator_p;
+
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in %<noexcept%> expressions");
+
+ saved_integral_constant_expression_p
+ = parser->integral_constant_expression_p;
+ saved_non_integral_constant_expression_p
+ = parser->non_integral_constant_expression_p;
+ parser->integral_constant_expression_p = false;
+
+ saved_greater_than_is_operator_p
+ = parser->greater_than_is_operator_p;
+ parser->greater_than_is_operator_p = true;
+
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
+ expr = cp_parser_expression (parser, false, NULL);
+ --c_inhibit_evaluation_warnings;
+ --cp_unevaluated_operand;
+
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+
+ parser->integral_constant_expression_p
+ = saved_integral_constant_expression_p;
+ parser->non_integral_constant_expression_p
+ = saved_non_integral_constant_expression_p;
+
+ parser->type_definition_forbidden_message = saved_message;
+
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ return finish_noexcept_expr (expr, tf_warning_or_error);
+ }
+
+ default:
+ break;
+ }
+ }
+
+ /* Look for the `:: new' and `:: delete', which also signal the
+ beginning of a new-expression, or delete-expression,
+ respectively. If the next token is `::', then it might be one of
+ these. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ {
+ enum rid keyword;
+
+ /* See if the token after the `::' is one of the keywords in
+ which we're interested. */
+ keyword = cp_lexer_peek_nth_token (parser->lexer, 2)->keyword;
+ /* If it's `new', we have a new-expression. */
+ if (keyword == RID_NEW)
+ return cp_parser_new_expression (parser);
+ /* Similarly, for `delete'. */
+ else if (keyword == RID_DELETE)
+ return cp_parser_delete_expression (parser);
+ }
+
+ /* Look for a unary operator. */
+ unary_operator = cp_parser_unary_operator (token);
+ /* The `++' and `--' operators can be handled similarly, even though
+ they are not technically unary-operators in the grammar. */
+ if (unary_operator == ERROR_MARK)
+ {
+ if (token->type == CPP_PLUS_PLUS)
+ unary_operator = PREINCREMENT_EXPR;
+ else if (token->type == CPP_MINUS_MINUS)
+ unary_operator = PREDECREMENT_EXPR;
+ /* Handle the GNU address-of-label extension. */
+ else if (cp_parser_allow_gnu_extensions_p (parser)
+ && token->type == CPP_AND_AND)
+ {
+ tree identifier;
+ tree expression;
+ location_t loc = token->location;
+
+ /* Consume the '&&' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the identifier. */
+ identifier = cp_parser_identifier (parser);
+ /* Create an expression representing the address. */
+ expression = finish_label_address_expr (identifier, loc);
+ if (cp_parser_non_integral_constant_expression (parser,
+ NIC_ADDR_LABEL))
+ expression = error_mark_node;
+ return expression;
+ }
+ }
+ if (unary_operator != ERROR_MARK)
+ {
+ tree cast_expression;
+ tree expression = error_mark_node;
+ non_integral_constant non_constant_p = NIC_NONE;
+ location_t loc = token->location;
+ tsubst_flags_t complain = complain_flags (decltype_p);
+
+ /* Consume the operator token. */
+ token = cp_lexer_consume_token (parser->lexer);
+ /* Parse the cast-expression. */
+ cast_expression
+ = cp_parser_cast_expression (parser,
+ unary_operator == ADDR_EXPR,
+ /*cast_p=*/false,
+ /*decltype*/false,
+ pidk);
+ /* Now, build an appropriate representation. */
+ switch (unary_operator)
+ {
+ case INDIRECT_REF:
+ non_constant_p = NIC_STAR;
+ expression = build_x_indirect_ref (loc, cast_expression,
+ RO_UNARY_STAR,
+ complain);
+ break;
+
+ case ADDR_EXPR:
+ non_constant_p = NIC_ADDR;
+ /* Fall through. */
+ case BIT_NOT_EXPR:
+ expression = build_x_unary_op (loc, unary_operator,
+ cast_expression,
+ complain);
+ break;
+
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ non_constant_p = unary_operator == PREINCREMENT_EXPR
+ ? NIC_PREINCREMENT : NIC_PREDECREMENT;
+ /* Fall through. */
+ case UNARY_PLUS_EXPR:
+ case NEGATE_EXPR:
+ case TRUTH_NOT_EXPR:
+ expression = finish_unary_op_expr (loc, unary_operator,
+ cast_expression, complain);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (non_constant_p != NIC_NONE
+ && cp_parser_non_integral_constant_expression (parser,
+ non_constant_p))
+ expression = error_mark_node;
+
+ return expression;
+ }
+
+ return cp_parser_postfix_expression (parser, address_p, cast_p,
+ /*member_access_only_p=*/false,
+ decltype_p,
+ pidk);
+}
+
+static inline tree
+cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
+ cp_id_kind * pidk)
+{
+ return cp_parser_unary_expression (parser, address_p, cast_p,
+ /*decltype*/false, pidk);
+}
+
+/* Returns ERROR_MARK if TOKEN is not a unary-operator. If TOKEN is a
+ unary-operator, the corresponding tree code is returned. */
+
+static enum tree_code
+cp_parser_unary_operator (cp_token* token)
+{
+ switch (token->type)
+ {
+ case CPP_MULT:
+ return INDIRECT_REF;
+
+ case CPP_AND:
+ return ADDR_EXPR;
+
+ case CPP_PLUS:
+ return UNARY_PLUS_EXPR;
+
+ case CPP_MINUS:
+ return NEGATE_EXPR;
+
+ case CPP_NOT:
+ return TRUTH_NOT_EXPR;
+
+ case CPP_COMPL:
+ return BIT_NOT_EXPR;
+
+ default:
+ return ERROR_MARK;
+ }
+}
+
+/* Parse a new-expression.
+
+ new-expression:
+ :: [opt] new new-placement [opt] new-type-id new-initializer [opt]
+ :: [opt] new new-placement [opt] ( type-id ) new-initializer [opt]
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_new_expression (cp_parser* parser)
+{
+ bool global_scope_p;
+ vec<tree, va_gc> *placement;
+ tree type;
+ vec<tree, va_gc> *initializer;
+ tree nelts = NULL_TREE;
+ tree ret;
+
+ /* Look for the optional `::' operator. */
+ global_scope_p
+ = (cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+ /* Look for the `new' operator. */
+ cp_parser_require_keyword (parser, RID_NEW, RT_NEW);
+ /* There's no easy way to tell a new-placement from the
+ `( type-id )' construct. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for a new-placement. */
+ placement = cp_parser_new_placement (parser);
+ /* If that didn't work out, there's no new-placement. */
+ if (!cp_parser_parse_definitely (parser))
+ {
+ if (placement != NULL)
+ release_tree_vector (placement);
+ placement = NULL;
+ }
+
+ /* If the next token is a `(', then we have a parenthesized
+ type-id. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ cp_token *token;
+ const char *saved_message = parser->type_definition_forbidden_message;
+
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Parse the type-id. */
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in a new-expression");
+ type = cp_parser_type_id (parser);
+ parser->type_definition_forbidden_message = saved_message;
+
+ /* Look for the closing `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ token = cp_lexer_peek_token (parser->lexer);
+ /* There should not be a direct-new-declarator in this production,
+ but GCC used to allowed this, so we check and emit a sensible error
+ message for this case. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+ {
+ error_at (token->location,
+ "array bound forbidden after parenthesized type-id");
+ inform (token->location,
+ "try removing the parentheses around the type-id");
+ cp_parser_direct_new_declarator (parser);
+ }
+ }
+ /* Otherwise, there must be a new-type-id. */
+ else
+ type = cp_parser_new_type_id (parser, &nelts);
+
+ /* If the next token is a `(' or '{', then we have a new-initializer. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
+ || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ initializer = cp_parser_new_initializer (parser);
+ else
+ initializer = NULL;
+
+ /* A new-expression may not appear in an integral constant
+ expression. */
+ if (cp_parser_non_integral_constant_expression (parser, NIC_NEW))
+ ret = error_mark_node;
+ else
+ {
+ /* Create a representation of the new-expression. */
+ ret = build_new (&placement, type, nelts, &initializer, global_scope_p,
+ tf_warning_or_error);
+ }
+
+ if (placement != NULL)
+ release_tree_vector (placement);
+ if (initializer != NULL)
+ release_tree_vector (initializer);
+
+ return ret;
+}
+
+/* Parse a new-placement.
+
+ new-placement:
+ ( expression-list )
+
+ Returns the same representation as for an expression-list. */
+
+static vec<tree, va_gc> *
+cp_parser_new_placement (cp_parser* parser)
+{
+ vec<tree, va_gc> *expression_list;
+
+ /* Parse the expression-list. */
+ expression_list = (cp_parser_parenthesized_expression_list
+ (parser, non_attr, /*cast_p=*/false,
+ /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL));
+
+ return expression_list;
+}
+
+/* Parse a new-type-id.
+
+ new-type-id:
+ type-specifier-seq new-declarator [opt]
+
+ Returns the TYPE allocated. If the new-type-id indicates an array
+ type, *NELTS is set to the number of elements in the last array
+ bound; the TYPE will not include the last array bound. */
+
+static tree
+cp_parser_new_type_id (cp_parser* parser, tree *nelts)
+{
+ cp_decl_specifier_seq type_specifier_seq;
+ cp_declarator *new_declarator;
+ cp_declarator *declarator;
+ cp_declarator *outer_declarator;
+ const char *saved_message;
+
+ /* The type-specifier sequence must not contain type definitions.
+ (It cannot contain declarations of new types either, but if they
+ are not definitions we will catch that because they are not
+ complete.) */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in a new-type-id");
+ /* Parse the type-specifier-seq. */
+ cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+ /*is_trailing_return=*/false,
+ &type_specifier_seq);
+ /* Restore the old message. */
+ parser->type_definition_forbidden_message = saved_message;
+
+ if (type_specifier_seq.type == error_mark_node)
+ return error_mark_node;
+
+ /* Parse the new-declarator. */
+ new_declarator = cp_parser_new_declarator_opt (parser);
+
+ /* Determine the number of elements in the last array dimension, if
+ any. */
+ *nelts = NULL_TREE;
+ /* Skip down to the last array dimension. */
+ declarator = new_declarator;
+ outer_declarator = NULL;
+ while (declarator && (declarator->kind == cdk_pointer
+ || declarator->kind == cdk_ptrmem))
+ {
+ outer_declarator = declarator;
+ declarator = declarator->declarator;
+ }
+ while (declarator
+ && declarator->kind == cdk_array
+ && declarator->declarator
+ && declarator->declarator->kind == cdk_array)
+ {
+ outer_declarator = declarator;
+ declarator = declarator->declarator;
+ }
+
+ if (declarator && declarator->kind == cdk_array)
+ {
+ *nelts = declarator->u.array.bounds;
+ if (*nelts == error_mark_node)
+ *nelts = integer_one_node;
+
+ if (outer_declarator)
+ outer_declarator->declarator = declarator->declarator;
+ else
+ new_declarator = NULL;
+ }
+
+ return groktypename (&type_specifier_seq, new_declarator, false);
+}
+
+/* Parse an (optional) new-declarator.
+
+ new-declarator:
+ ptr-operator new-declarator [opt]
+ direct-new-declarator
+
+ Returns the declarator. */
+
+static cp_declarator *
+cp_parser_new_declarator_opt (cp_parser* parser)
+{
+ enum tree_code code;
+ tree type, std_attributes = NULL_TREE;
+ cp_cv_quals cv_quals;
+
+ /* We don't know if there's a ptr-operator next, or not. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for a ptr-operator. */
+ code = cp_parser_ptr_operator (parser, &type, &cv_quals, &std_attributes);
+ /* If that worked, look for more new-declarators. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ cp_declarator *declarator;
+
+ /* Parse another optional declarator. */
+ declarator = cp_parser_new_declarator_opt (parser);
+
+ declarator = cp_parser_make_indirect_declarator
+ (code, type, cv_quals, declarator, std_attributes);
+
+ return declarator;
+ }
+
+ /* If the next token is a `[', there is a direct-new-declarator. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+ return cp_parser_direct_new_declarator (parser);
+
+ return NULL;
+}
+
+/* Parse a direct-new-declarator.
+
+ direct-new-declarator:
+ [ expression ]
+ direct-new-declarator [constant-expression]
+
+ */
+
+static cp_declarator *
+cp_parser_direct_new_declarator (cp_parser* parser)
+{
+ cp_declarator *declarator = NULL;
+
+ while (true)
+ {
+ tree expression;
+ cp_token *token;
+
+ /* Look for the opening `['. */
+ cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
+
+ token = cp_lexer_peek_token (parser->lexer);
+ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ /* The standard requires that the expression have integral
+ type. DR 74 adds enumeration types. We believe that the
+ real intent is that these expressions be handled like the
+ expression in a `switch' condition, which also allows
+ classes with a single conversion to integral or
+ enumeration type. */
+ if (!processing_template_decl)
+ {
+ expression
+ = build_expr_type_conversion (WANT_INT | WANT_ENUM,
+ expression,
+ /*complain=*/true);
+ if (!expression)
+ {
+ error_at (token->location,
+ "expression in new-declarator must have integral "
+ "or enumeration type");
+ expression = error_mark_node;
+ }
+ }
+
+ /* Look for the closing `]'. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+
+ /* Add this bound to the declarator. */
+ declarator = make_array_declarator (declarator, expression);
+
+ /* If the next token is not a `[', then there are no more
+ bounds. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_SQUARE))
+ break;
+ }
+
+ return declarator;
+}
+
+/* Parse a new-initializer.
+
+ new-initializer:
+ ( expression-list [opt] )
+ braced-init-list
+
+ Returns a representation of the expression-list. */
+
+static vec<tree, va_gc> *
+cp_parser_new_initializer (cp_parser* parser)
+{
+ vec<tree, va_gc> *expression_list;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ tree t;
+ bool expr_non_constant_p;
+ cp_lexer_set_source_position (parser->lexer);
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ t = cp_parser_braced_list (parser, &expr_non_constant_p);
+ CONSTRUCTOR_IS_DIRECT_INIT (t) = 1;
+ expression_list = make_tree_vector_single (t);
+ }
+ else
+ expression_list = (cp_parser_parenthesized_expression_list
+ (parser, non_attr, /*cast_p=*/false,
+ /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL));
+
+ return expression_list;
+}
+
+/* Parse a delete-expression.
+
+ delete-expression:
+ :: [opt] delete cast-expression
+ :: [opt] delete [ ] cast-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_delete_expression (cp_parser* parser)
+{
+ bool global_scope_p;
+ bool array_p;
+ tree expression;
+
+ /* Look for the optional `::' operator. */
+ global_scope_p
+ = (cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+ /* Look for the `delete' keyword. */
+ cp_parser_require_keyword (parser, RID_DELETE, RT_DELETE);
+ /* See if the array syntax is in use. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+ {
+ /* Consume the `[' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the `]' token. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+ /* Remember that this is the `[]' construct. */
+ array_p = true;
+ }
+ else
+ array_p = false;
+
+ /* Parse the cast-expression. */
+ expression = cp_parser_simple_cast_expression (parser);
+
+ /* A delete-expression may not appear in an integral constant
+ expression. */
+ if (cp_parser_non_integral_constant_expression (parser, NIC_DEL))
+ return error_mark_node;
+
+ return delete_sanity (expression, NULL_TREE, array_p, global_scope_p,
+ tf_warning_or_error);
+}
+
+/* Returns true if TOKEN may start a cast-expression and false
+ otherwise. */
+
+static bool
+cp_parser_tokens_start_cast_expression (cp_parser *parser)
+{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ switch (token->type)
+ {
+ case CPP_COMMA:
+ case CPP_SEMICOLON:
+ case CPP_QUERY:
+ case CPP_COLON:
+ case CPP_CLOSE_SQUARE:
+ case CPP_CLOSE_PAREN:
+ case CPP_CLOSE_BRACE:
+ case CPP_OPEN_BRACE:
+ case CPP_DOT:
+ case CPP_DOT_STAR:
+ case CPP_DEREF:
+ case CPP_DEREF_STAR:
+ case CPP_DIV:
+ case CPP_MOD:
+ case CPP_LSHIFT:
+ case CPP_RSHIFT:
+ case CPP_LESS:
+ case CPP_GREATER:
+ case CPP_LESS_EQ:
+ case CPP_GREATER_EQ:
+ case CPP_EQ_EQ:
+ case CPP_NOT_EQ:
+ case CPP_EQ:
+ case CPP_MULT_EQ:
+ case CPP_DIV_EQ:
+ case CPP_MOD_EQ:
+ case CPP_PLUS_EQ:
+ case CPP_MINUS_EQ:
+ case CPP_RSHIFT_EQ:
+ case CPP_LSHIFT_EQ:
+ case CPP_AND_EQ:
+ case CPP_XOR_EQ:
+ case CPP_OR_EQ:
+ case CPP_XOR:
+ case CPP_OR:
+ case CPP_OR_OR:
+ case CPP_EOF:
+ return false;
+
+ case CPP_OPEN_PAREN:
+ /* In ((type ()) () the last () isn't a valid cast-expression,
+ so the whole must be parsed as postfix-expression. */
+ return cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ != CPP_CLOSE_PAREN;
+
+ /* '[' may start a primary-expression in obj-c++. */
+ case CPP_OPEN_SQUARE:
+ return c_dialect_objc ();
+
+ default:
+ return true;
+ }
+}
+
+/* Parse a cast-expression.
+
+ cast-expression:
+ unary-expression
+ ( type-id ) cast-expression
+
+ ADDRESS_P is true iff the unary-expression is appearing as the
+ operand of the `&' operator. CAST_P is true if this expression is
+ the target of a cast.
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
+ bool decltype_p, cp_id_kind * pidk)
+{
+ /* If it's a `(', then we might be looking at a cast. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ tree type = NULL_TREE;
+ tree expr = NULL_TREE;
+ bool cast_expression_p;
+ const char *saved_message;
+
+ /* There's no way to know yet whether or not this is a cast.
+ For example, `(int (3))' is a unary-expression, while `(int)
+ 3' is a cast. So, we resort to parsing tentatively. */
+ cp_parser_parse_tentatively (parser);
+ /* Types may not be defined in a cast. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in casts");
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* A very tricky bit is that `(struct S) { 3 }' is a
+ compound-literal (which we permit in C++ as an extension).
+ But, that construct is not a cast-expression -- it is a
+ postfix-expression. (The reason is that `(struct S) { 3 }.i'
+ is legal; if the compound-literal were a cast-expression,
+ you'd need an extra set of parentheses.) But, if we parse
+ the type-id, and it happens to be a class-specifier, then we
+ will commit to the parse at that point, because we cannot
+ undo the action that is done when creating a new class. So,
+ then we cannot back up and do a postfix-expression.
+ Another tricky case is the following (c++/29234):
+
+ struct S { void operator () (); };
+
+ void foo ()
+ {
+ ( S()() );
+ }
+
+ As a type-id we parse the parenthesized S()() as a function
+ returning a function, groktypename complains and we cannot
+ back up in this case either.
+
+ Therefore, we scan ahead to the closing `)', and check to see
+ if the tokens after the `)' can start a cast-expression. Otherwise
+ we are dealing with an unary-expression, a postfix-expression
+ or something else.
+
+ Save tokens so that we can put them back. */
+ cp_lexer_save_tokens (parser->lexer);
+
+ /* We may be looking at a cast-expression. */
+ cast_expression_p
+ = (cp_parser_skip_to_closing_parenthesis (parser, false, false,
+ /*consume_paren=*/true)
+ && cp_parser_tokens_start_cast_expression (parser));
+
+ /* Roll back the tokens we skipped. */
+ cp_lexer_rollback_tokens (parser->lexer);
+ /* If we aren't looking at a cast-expression, simulate an error so
+ that the call to cp_parser_parse_definitely below will fail. */
+ if (!cast_expression_p)
+ cp_parser_simulate_error (parser);
+ else
+ {
+ bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
+ /* Look for the type-id. */
+ type = cp_parser_type_id (parser);
+ /* Look for the closing `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+ }
+
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+
+ /* At this point this can only be either a cast or a
+ parenthesized ctor such as `(T ())' that looks like a cast to
+ function returning T. */
+ if (!cp_parser_error_occurred (parser))
+ {
+ cp_parser_parse_definitely (parser);
+ expr = cp_parser_cast_expression (parser,
+ /*address_p=*/false,
+ /*cast_p=*/true,
+ /*decltype_p=*/false,
+ pidk);
+
+ /* Warn about old-style casts, if so requested. */
+ if (warn_old_style_cast
+ && !in_system_header_at (input_location)
+ && !VOID_TYPE_P (type)
+ && current_lang_name != lang_name_c)
+ warning (OPT_Wold_style_cast, "use of old-style cast");
+
+ /* Only type conversions to integral or enumeration types
+ can be used in constant-expressions. */
+ if (!cast_valid_in_integral_constant_expression_p (type)
+ && cp_parser_non_integral_constant_expression (parser,
+ NIC_CAST))
+ return error_mark_node;
+
+ /* Perform the cast. */
+ expr = build_c_cast (input_location, type, expr);
+ return expr;
+ }
+ else
+ cp_parser_abort_tentative_parse (parser);
+ }
+
+ /* If we get here, then it's not a cast, so it must be a
+ unary-expression. */
+ return cp_parser_unary_expression (parser, address_p, cast_p,
+ decltype_p, pidk);
+}
+
+/* Parse a binary expression of the general form:
+
+ pm-expression:
+ cast-expression
+ pm-expression .* cast-expression
+ pm-expression ->* cast-expression
+
+ multiplicative-expression:
+ pm-expression
+ multiplicative-expression * pm-expression
+ multiplicative-expression / pm-expression
+ multiplicative-expression % pm-expression
+
+ additive-expression:
+ multiplicative-expression
+ additive-expression + multiplicative-expression
+ additive-expression - multiplicative-expression
+
+ shift-expression:
+ additive-expression
+ shift-expression << additive-expression
+ shift-expression >> additive-expression
+
+ relational-expression:
+ shift-expression
+ relational-expression < shift-expression
+ relational-expression > shift-expression
+ relational-expression <= shift-expression
+ relational-expression >= shift-expression
+
+ GNU Extension:
+
+ relational-expression:
+ relational-expression <? shift-expression
+ relational-expression >? shift-expression
+
+ equality-expression:
+ relational-expression
+ equality-expression == relational-expression
+ equality-expression != relational-expression
+
+ and-expression:
+ equality-expression
+ and-expression & equality-expression
+
+ exclusive-or-expression:
+ and-expression
+ exclusive-or-expression ^ and-expression
+
+ inclusive-or-expression:
+ exclusive-or-expression
+ inclusive-or-expression | exclusive-or-expression
+
+ logical-and-expression:
+ inclusive-or-expression
+ logical-and-expression && inclusive-or-expression
+
+ logical-or-expression:
+ logical-and-expression
+ logical-or-expression || logical-and-expression
+
+ All these are implemented with a single function like:
+
+ binary-expression:
+ simple-cast-expression
+ binary-expression <token> binary-expression
+
+ CAST_P is true if this expression is the target of a cast.
+
+ The binops_by_token map is used to get the tree codes for each <token> type.
+ binary-expressions are associated according to a precedence table. */
+
+#define TOKEN_PRECEDENCE(token) \
+(((token->type == CPP_GREATER \
+ || ((cxx_dialect != cxx98) && token->type == CPP_RSHIFT)) \
+ && !parser->greater_than_is_operator_p) \
+ ? PREC_NOT_OPERATOR \
+ : binops_by_token[token->type].prec)
+
+static tree
+cp_parser_binary_expression (cp_parser* parser, bool cast_p,
+ bool no_toplevel_fold_p,
+ bool decltype_p,
+ enum cp_parser_prec prec,
+ cp_id_kind * pidk)
+{
+ cp_parser_expression_stack stack;
+ cp_parser_expression_stack_entry *sp = &stack[0];
+ cp_parser_expression_stack_entry current;
+ tree rhs;
+ cp_token *token;
+ enum tree_code rhs_type;
+ enum cp_parser_prec new_prec, lookahead_prec;
+ tree overload;
+
+ /* Parse the first expression. */
+ current.lhs = cp_parser_cast_expression (parser, /*address_p=*/false,
+ cast_p, decltype_p, pidk);
+ current.lhs_type = ERROR_MARK;
+ current.prec = prec;
+
+ if (cp_parser_error_occurred (parser))
+ return error_mark_node;
+
+ for (;;)
+ {
+ /* Get an operator token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ if (warn_cxx0x_compat
+ && token->type == CPP_RSHIFT
+ && !parser->greater_than_is_operator_p)
+ {
+ if (warning_at (token->location, OPT_Wc__0x_compat,
+ "%<>>%> operator is treated"
+ " as two right angle brackets in C++11"))
+ inform (token->location,
+ "suggest parentheses around %<>>%> expression");
+ }
+
+ new_prec = TOKEN_PRECEDENCE (token);
+
+ /* Popping an entry off the stack means we completed a subexpression:
+ - either we found a token which is not an operator (`>' where it is not
+ an operator, or prec == PREC_NOT_OPERATOR), in which case popping
+ will happen repeatedly;
+ - or, we found an operator which has lower priority. This is the case
+ where the recursive descent *ascends*, as in `3 * 4 + 5' after
+ parsing `3 * 4'. */
+ if (new_prec <= current.prec)
+ {
+ if (sp == stack)
+ break;
+ else
+ goto pop;
+ }
+
+ get_rhs:
+ current.tree_type = binops_by_token[token->type].tree_type;
+ current.loc = token->location;
+
+ /* We used the operator token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* For "false && x" or "true || x", x will never be executed;
+ disable warnings while evaluating it. */
+ if (current.tree_type == TRUTH_ANDIF_EXPR)
+ c_inhibit_evaluation_warnings += current.lhs == truthvalue_false_node;
+ else if (current.tree_type == TRUTH_ORIF_EXPR)
+ c_inhibit_evaluation_warnings += current.lhs == truthvalue_true_node;
+
+ /* Extract another operand. It may be the RHS of this expression
+ or the LHS of a new, higher priority expression. */
+ rhs = cp_parser_simple_cast_expression (parser);
+ rhs_type = ERROR_MARK;
+
+ /* Get another operator token. Look up its precedence to avoid
+ building a useless (immediately popped) stack entry for common
+ cases such as 3 + 4 + 5 or 3 * 4 + 5. */
+ token = cp_lexer_peek_token (parser->lexer);
+ lookahead_prec = TOKEN_PRECEDENCE (token);
+ if (lookahead_prec > new_prec)
+ {
+ /* ... and prepare to parse the RHS of the new, higher priority
+ expression. Since precedence levels on the stack are
+ monotonically increasing, we do not have to care about
+ stack overflows. */
+ *sp = current;
+ ++sp;
+ current.lhs = rhs;
+ current.lhs_type = rhs_type;
+ current.prec = new_prec;
+ new_prec = lookahead_prec;
+ goto get_rhs;
+
+ pop:
+ lookahead_prec = new_prec;
+ /* If the stack is not empty, we have parsed into LHS the right side
+ (`4' in the example above) of an expression we had suspended.
+ We can use the information on the stack to recover the LHS (`3')
+ from the stack together with the tree code (`MULT_EXPR'), and
+ the precedence of the higher level subexpression
+ (`PREC_ADDITIVE_EXPRESSION'). TOKEN is the CPP_PLUS token,
+ which will be used to actually build the additive expression. */
+ rhs = current.lhs;
+ rhs_type = current.lhs_type;
+ --sp;
+ current = *sp;
+ }
+
+ /* Undo the disabling of warnings done above. */
+ if (current.tree_type == TRUTH_ANDIF_EXPR)
+ c_inhibit_evaluation_warnings -= current.lhs == truthvalue_false_node;
+ else if (current.tree_type == TRUTH_ORIF_EXPR)
+ c_inhibit_evaluation_warnings -= current.lhs == truthvalue_true_node;
+
+ overload = NULL;
+ /* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type ==
+ ERROR_MARK for everything that is not a binary expression.
+ This makes warn_about_parentheses miss some warnings that
+ involve unary operators. For unary expressions we should
+ pass the correct tree_code unless the unary expression was
+ surrounded by parentheses.
+ */
+ if (no_toplevel_fold_p
+ && lookahead_prec <= current.prec
+ && sp == stack)
+ current.lhs = build2 (current.tree_type,
+ TREE_CODE_CLASS (current.tree_type)
+ == tcc_comparison
+ ? boolean_type_node : TREE_TYPE (current.lhs),
+ current.lhs, rhs);
+ else
+ current.lhs = build_x_binary_op (current.loc, current.tree_type,
+ current.lhs, current.lhs_type,
+ rhs, rhs_type, &overload,
+ complain_flags (decltype_p));
+ current.lhs_type = current.tree_type;
+ if (EXPR_P (current.lhs))
+ SET_EXPR_LOCATION (current.lhs, current.loc);
+
+ /* If the binary operator required the use of an overloaded operator,
+ then this expression cannot be an integral constant-expression.
+ An overloaded operator can be used even if both operands are
+ otherwise permissible in an integral constant-expression if at
+ least one of the operands is of enumeration type. */
+
+ if (overload
+ && cp_parser_non_integral_constant_expression (parser,
+ NIC_OVERLOADED))
+ return error_mark_node;
+ }
+
+ return current.lhs;
+}
+
+static tree
+cp_parser_binary_expression (cp_parser* parser, bool cast_p,
+ bool no_toplevel_fold_p,
+ enum cp_parser_prec prec,
+ cp_id_kind * pidk)
+{
+ return cp_parser_binary_expression (parser, cast_p, no_toplevel_fold_p,
+ /*decltype*/false, prec, pidk);
+}
+
+/* Parse the `? expression : assignment-expression' part of a
+ conditional-expression. The LOGICAL_OR_EXPR is the
+ logical-or-expression that started the conditional-expression.
+ Returns a representation of the entire conditional-expression.
+
+ This routine is used by cp_parser_assignment_expression.
+
+ ? expression : assignment-expression
+
+ GNU Extensions:
+
+ ? : assignment-expression */
+
+static tree
+cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
+{
+ tree expr;
+ tree assignment_expr;
+ struct cp_token *token;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ /* Consume the `?' token. */
+ cp_lexer_consume_token (parser->lexer);
+ token = cp_lexer_peek_token (parser->lexer);
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && token->type == CPP_COLON)
+ {
+ pedwarn (token->location, OPT_Wpedantic,
+ "ISO C++ does not allow ?: with omitted middle operand");
+ /* Implicit true clause. */
+ expr = NULL_TREE;
+ c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_true_node;
+ warn_for_omitted_condop (token->location, logical_or_expr);
+ }
+ else
+ {
+ bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+ parser->colon_corrects_to_scope_p = false;
+ /* Parse the expression. */
+ c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_false_node;
+ expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ c_inhibit_evaluation_warnings +=
+ ((logical_or_expr == truthvalue_true_node)
+ - (logical_or_expr == truthvalue_false_node));
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+ }
+
+ /* The next token should be a `:'. */
+ cp_parser_require (parser, CPP_COLON, RT_COLON);
+ /* Parse the assignment-expression. */
+ assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
+ c_inhibit_evaluation_warnings -= logical_or_expr == truthvalue_true_node;
+
+ /* Build the conditional-expression. */
+ return build_x_conditional_expr (loc, logical_or_expr,
+ expr,
+ assignment_expr,
+ tf_warning_or_error);
+}
+
+/* Parse an assignment-expression.
+
+ assignment-expression:
+ conditional-expression
+ logical-or-expression assignment-operator assignment_expression
+ throw-expression
+
+ CAST_P is true if this expression is the target of a cast.
+ DECLTYPE_P is true if this expression is the operand of decltype.
+
+ Returns a representation for the expression. */
+
+static tree
+cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
+ bool decltype_p, cp_id_kind * pidk)
+{
+ tree expr;
+
+ /* If the next token is the `throw' keyword, then we're looking at
+ a throw-expression. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THROW))
+ expr = cp_parser_throw_expression (parser);
+ /* Otherwise, it must be that we are looking at a
+ logical-or-expression. */
+ else
+ {
+ /* Parse the binary expressions (logical-or-expression). */
+ expr = cp_parser_binary_expression (parser, cast_p, false,
+ decltype_p,
+ PREC_NOT_OPERATOR, pidk);
+ /* If the next token is a `?' then we're actually looking at a
+ conditional-expression. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
+ return cp_parser_question_colon_clause (parser, expr);
+ else
+ {
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ /* If it's an assignment-operator, we're using the second
+ production. */
+ enum tree_code assignment_operator
+ = cp_parser_assignment_operator_opt (parser);
+ if (assignment_operator != ERROR_MARK)
+ {
+ bool non_constant_p;
+ location_t saved_input_location;
+
+ /* Parse the right-hand side of the assignment. */
+ tree rhs = cp_parser_initializer_clause (parser, &non_constant_p);
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+
+ /* An assignment may not appear in a
+ constant-expression. */
+ if (cp_parser_non_integral_constant_expression (parser,
+ NIC_ASSIGNMENT))
+ return error_mark_node;
+ /* Build the assignment expression. Its default
+ location is the location of the '=' token. */
+ saved_input_location = input_location;
+ input_location = loc;
+ expr = build_x_modify_expr (loc, expr,
+ assignment_operator,
+ rhs,
+ complain_flags (decltype_p));
+ input_location = saved_input_location;
+ }
+ }
+ }
+
+ return expr;
+}
+
+static tree
+cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
+ cp_id_kind * pidk)
+{
+ return cp_parser_assignment_expression (parser, cast_p,
+ /*decltype*/false, pidk);
+}
+
+/* Parse an (optional) assignment-operator.
+
+ assignment-operator: one of
+ = *= /= %= += -= >>= <<= &= ^= |=
+
+ GNU Extension:
+
+ assignment-operator: one of
+ <?= >?=
+
+ If the next token is an assignment operator, the corresponding tree
+ code is returned, and the token is consumed. For example, for
+ `+=', PLUS_EXPR is returned. For `=' itself, the code returned is
+ NOP_EXPR. For `/', TRUNC_DIV_EXPR is returned; for `%',
+ TRUNC_MOD_EXPR is returned. If TOKEN is not an assignment
+ operator, ERROR_MARK is returned. */
+
+static enum tree_code
+cp_parser_assignment_operator_opt (cp_parser* parser)
+{
+ enum tree_code op;
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_EQ:
+ op = NOP_EXPR;
+ break;
+
+ case CPP_MULT_EQ:
+ op = MULT_EXPR;
+ break;
+
+ case CPP_DIV_EQ:
+ op = TRUNC_DIV_EXPR;
+ break;
+
+ case CPP_MOD_EQ:
+ op = TRUNC_MOD_EXPR;
+ break;
+
+ case CPP_PLUS_EQ:
+ op = PLUS_EXPR;
+ break;
+
+ case CPP_MINUS_EQ:
+ op = MINUS_EXPR;
+ break;
+
+ case CPP_RSHIFT_EQ:
+ op = RSHIFT_EXPR;
+ break;
+
+ case CPP_LSHIFT_EQ:
+ op = LSHIFT_EXPR;
+ break;
+
+ case CPP_AND_EQ:
+ op = BIT_AND_EXPR;
+ break;
+
+ case CPP_XOR_EQ:
+ op = BIT_XOR_EXPR;
+ break;
+
+ case CPP_OR_EQ:
+ op = BIT_IOR_EXPR;
+ break;
+
+ default:
+ /* Nothing else is an assignment operator. */
+ op = ERROR_MARK;
+ }
+
+ /* If it was an assignment operator, consume it. */
+ if (op != ERROR_MARK)
+ cp_lexer_consume_token (parser->lexer);
+
+ return op;
+}
+
+/* Parse an expression.
+
+ expression:
+ assignment-expression
+ expression , assignment-expression
+
+ CAST_P is true if this expression is the target of a cast.
+ DECLTYPE_P is true if this expression is the immediate operand of decltype,
+ except possibly parenthesized or on the RHS of a comma (N3276).
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_expression (cp_parser* parser, bool cast_p, bool decltype_p,
+ cp_id_kind * pidk)
+{
+ tree expression = NULL_TREE;
+ location_t loc = UNKNOWN_LOCATION;
+
+ while (true)
+ {
+ tree assignment_expression;
+
+ /* Parse the next assignment-expression. */
+ assignment_expression
+ = cp_parser_assignment_expression (parser, cast_p, decltype_p, pidk);
+
+ /* We don't create a temporary for a call that is the immediate operand
+ of decltype or on the RHS of a comma. But when we see a comma, we
+ need to create a temporary for a call on the LHS. */
+ if (decltype_p && !processing_template_decl
+ && TREE_CODE (assignment_expression) == CALL_EXPR
+ && CLASS_TYPE_P (TREE_TYPE (assignment_expression))
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ assignment_expression
+ = build_cplus_new (TREE_TYPE (assignment_expression),
+ assignment_expression, tf_warning_or_error);
+
+ /* If this is the first assignment-expression, we can just
+ save it away. */
+ if (!expression)
+ expression = assignment_expression;
+ else
+ expression = build_x_compound_expr (loc, expression,
+ assignment_expression,
+ complain_flags (decltype_p));
+ /* If the next token is not a comma, then we are done with the
+ expression. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Consume the `,'. */
+ loc = cp_lexer_peek_token (parser->lexer)->location;
+ cp_lexer_consume_token (parser->lexer);
+ /* A comma operator cannot appear in a constant-expression. */
+ if (cp_parser_non_integral_constant_expression (parser, NIC_COMMA))
+ expression = error_mark_node;
+ }
+
+ return expression;
+}
+
+static inline tree
+cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk)
+{
+ return cp_parser_expression (parser, cast_p, /*decltype*/false, pidk);
+}
+
+/* Parse a constant-expression.
+
+ constant-expression:
+ conditional-expression
+
+ If ALLOW_NON_CONSTANT_P a non-constant expression is silently
+ accepted. If ALLOW_NON_CONSTANT_P is true and the expression is not
+ constant, *NON_CONSTANT_P is set to TRUE. If ALLOW_NON_CONSTANT_P
+ is false, NON_CONSTANT_P should be NULL. */
+
+static tree
+cp_parser_constant_expression (cp_parser* parser,
+ bool allow_non_constant_p,
+ bool *non_constant_p)
+{
+ bool saved_integral_constant_expression_p;
+ bool saved_allow_non_integral_constant_expression_p;
+ bool saved_non_integral_constant_expression_p;
+ tree expression;
+
+ /* It might seem that we could simply parse the
+ conditional-expression, and then check to see if it were
+ TREE_CONSTANT. However, an expression that is TREE_CONSTANT is
+ one that the compiler can figure out is constant, possibly after
+ doing some simplifications or optimizations. The standard has a
+ precise definition of constant-expression, and we must honor
+ that, even though it is somewhat more restrictive.
+
+ For example:
+
+ int i[(2, 3)];
+
+ is not a legal declaration, because `(2, 3)' is not a
+ constant-expression. The `,' operator is forbidden in a
+ constant-expression. However, GCC's constant-folding machinery
+ will fold this operation to an INTEGER_CST for `3'. */
+
+ /* Save the old settings. */
+ saved_integral_constant_expression_p = parser->integral_constant_expression_p;
+ saved_allow_non_integral_constant_expression_p
+ = parser->allow_non_integral_constant_expression_p;
+ saved_non_integral_constant_expression_p = parser->non_integral_constant_expression_p;
+ /* We are now parsing a constant-expression. */
+ parser->integral_constant_expression_p = true;
+ parser->allow_non_integral_constant_expression_p
+ = (allow_non_constant_p || cxx_dialect >= cxx11);
+ parser->non_integral_constant_expression_p = false;
+ /* Although the grammar says "conditional-expression", we parse an
+ "assignment-expression", which also permits "throw-expression"
+ and the use of assignment operators. In the case that
+ ALLOW_NON_CONSTANT_P is false, we get better errors than we would
+ otherwise. In the case that ALLOW_NON_CONSTANT_P is true, it is
+ actually essential that we look for an assignment-expression.
+ For example, cp_parser_initializer_clauses uses this function to
+ determine whether a particular assignment-expression is in fact
+ constant. */
+ expression = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
+ /* Restore the old settings. */
+ parser->integral_constant_expression_p
+ = saved_integral_constant_expression_p;
+ parser->allow_non_integral_constant_expression_p
+ = saved_allow_non_integral_constant_expression_p;
+ if (cxx_dialect >= cxx11)
+ {
+ /* Require an rvalue constant expression here; that's what our
+ callers expect. Reference constant expressions are handled
+ separately in e.g. cp_parser_template_argument. */
+ bool is_const = potential_rvalue_constant_expression (expression);
+ parser->non_integral_constant_expression_p = !is_const;
+ if (!is_const && !allow_non_constant_p)
+ require_potential_rvalue_constant_expression (expression);
+ }
+ if (allow_non_constant_p)
+ *non_constant_p = parser->non_integral_constant_expression_p;
+ parser->non_integral_constant_expression_p
+ = saved_non_integral_constant_expression_p;
+
+ return expression;
+}
+
+/* Parse __builtin_offsetof.
+
+ offsetof-expression:
+ "__builtin_offsetof" "(" type-id "," offsetof-member-designator ")"
+
+ offsetof-member-designator:
+ id-expression
+ | offsetof-member-designator "." id-expression
+ | offsetof-member-designator "[" expression "]"
+ | offsetof-member-designator "->" id-expression */
+
+static tree
+cp_parser_builtin_offsetof (cp_parser *parser)
+{
+ int save_ice_p, save_non_ice_p;
+ tree type, expr;
+ cp_id_kind dummy;
+ cp_token *token;
+
+ /* We're about to accept non-integral-constant things, but will
+ definitely yield an integral constant expression. Save and
+ restore these values around our local parsing. */
+ save_ice_p = parser->integral_constant_expression_p;
+ save_non_ice_p = parser->non_integral_constant_expression_p;
+
+ /* Consume the "__builtin_offsetof" token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Consume the opening `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ /* Parse the type-id. */
+ type = cp_parser_type_id (parser);
+ /* Look for the `,'. */
+ cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* Build the (type *)null that begins the traditional offsetof macro. */
+ expr = build_static_cast (build_pointer_type (type), null_pointer_node,
+ tf_warning_or_error);
+
+ /* Parse the offsetof-member-designator. We begin as if we saw "expr->". */
+ expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DEREF, expr,
+ true, &dummy, token->location);
+ while (true)
+ {
+ token = cp_lexer_peek_token (parser->lexer);
+ switch (token->type)
+ {
+ case CPP_OPEN_SQUARE:
+ /* offsetof-member-designator "[" expression "]" */
+ expr = cp_parser_postfix_open_square_expression (parser, expr,
+ true, false);
+ break;
+
+ case CPP_DEREF:
+ /* offsetof-member-designator "->" identifier */
+ expr = grok_array_decl (token->location, expr,
+ integer_zero_node, false);
+ /* FALLTHRU */
+
+ case CPP_DOT:
+ /* offsetof-member-designator "." identifier */
+ cp_lexer_consume_token (parser->lexer);
+ expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT,
+ expr, true, &dummy,
+ token->location);
+ break;
+
+ case CPP_CLOSE_PAREN:
+ /* Consume the ")" token. */
+ cp_lexer_consume_token (parser->lexer);
+ goto success;
+
+ default:
+ /* Error. We know the following require will fail, but
+ that gives the proper error message. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
+ expr = error_mark_node;
+ goto failure;
+ }
+ }
+
+ success:
+ /* If we're processing a template, we can't finish the semantics yet.
+ Otherwise we can fold the entire expression now. */
+ if (processing_template_decl)
+ expr = build1 (OFFSETOF_EXPR, size_type_node, expr);
+ else
+ expr = finish_offsetof (expr);
+
+ failure:
+ parser->integral_constant_expression_p = save_ice_p;
+ parser->non_integral_constant_expression_p = save_non_ice_p;
+
+ return expr;
+}
+
+/* Parse a trait expression.
+
+ Returns a representation of the expression, the underlying type
+ of the type at issue when KEYWORD is RID_UNDERLYING_TYPE. */
+
+static tree
+cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
+{
+ cp_trait_kind kind;
+ tree type1, type2 = NULL_TREE;
+ bool binary = false;
+ cp_decl_specifier_seq decl_specs;
+
+ switch (keyword)
+ {
+ case RID_HAS_NOTHROW_ASSIGN:
+ kind = CPTK_HAS_NOTHROW_ASSIGN;
+ break;
+ case RID_HAS_NOTHROW_CONSTRUCTOR:
+ kind = CPTK_HAS_NOTHROW_CONSTRUCTOR;
+ break;
+ case RID_HAS_NOTHROW_COPY:
+ kind = CPTK_HAS_NOTHROW_COPY;
+ break;
+ case RID_HAS_TRIVIAL_ASSIGN:
+ kind = CPTK_HAS_TRIVIAL_ASSIGN;
+ break;
+ case RID_HAS_TRIVIAL_CONSTRUCTOR:
+ kind = CPTK_HAS_TRIVIAL_CONSTRUCTOR;
+ break;
+ case RID_HAS_TRIVIAL_COPY:
+ kind = CPTK_HAS_TRIVIAL_COPY;
+ break;
+ case RID_HAS_TRIVIAL_DESTRUCTOR:
+ kind = CPTK_HAS_TRIVIAL_DESTRUCTOR;
+ break;
+ case RID_HAS_VIRTUAL_DESTRUCTOR:
+ kind = CPTK_HAS_VIRTUAL_DESTRUCTOR;
+ break;
+ case RID_IS_ABSTRACT:
+ kind = CPTK_IS_ABSTRACT;
+ break;
+ case RID_IS_BASE_OF:
+ kind = CPTK_IS_BASE_OF;
+ binary = true;
+ break;
+ case RID_IS_CLASS:
+ kind = CPTK_IS_CLASS;
+ break;
+ case RID_IS_CONVERTIBLE_TO:
+ kind = CPTK_IS_CONVERTIBLE_TO;
+ binary = true;
+ break;
+ case RID_IS_EMPTY:
+ kind = CPTK_IS_EMPTY;
+ break;
+ case RID_IS_ENUM:
+ kind = CPTK_IS_ENUM;
+ break;
+ case RID_IS_FINAL:
+ kind = CPTK_IS_FINAL;
+ break;
+ case RID_IS_LITERAL_TYPE:
+ kind = CPTK_IS_LITERAL_TYPE;
+ break;
+ case RID_IS_POD:
+ kind = CPTK_IS_POD;
+ break;
+ case RID_IS_POLYMORPHIC:
+ kind = CPTK_IS_POLYMORPHIC;
+ break;
+ case RID_IS_STD_LAYOUT:
+ kind = CPTK_IS_STD_LAYOUT;
+ break;
+ case RID_IS_TRIVIAL:
+ kind = CPTK_IS_TRIVIAL;
+ break;
+ case RID_IS_UNION:
+ kind = CPTK_IS_UNION;
+ break;
+ case RID_UNDERLYING_TYPE:
+ kind = CPTK_UNDERLYING_TYPE;
+ break;
+ case RID_BASES:
+ kind = CPTK_BASES;
+ break;
+ case RID_DIRECT_BASES:
+ kind = CPTK_DIRECT_BASES;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+ type1 = cp_parser_type_id (parser);
+
+ if (type1 == error_mark_node)
+ return error_mark_node;
+
+ /* Build a trivial decl-specifier-seq. */
+ clear_decl_specs (&decl_specs);
+ decl_specs.type = type1;
+
+ /* Call grokdeclarator to figure out what type this is. */
+ type1 = grokdeclarator (NULL, &decl_specs, TYPENAME,
+ /*initialized=*/0, /*attrlist=*/NULL);
+
+ if (binary)
+ {
+ cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+
+ type2 = cp_parser_type_id (parser);
+
+ if (type2 == error_mark_node)
+ return error_mark_node;
+
+ /* Build a trivial decl-specifier-seq. */
+ clear_decl_specs (&decl_specs);
+ decl_specs.type = type2;
+
+ /* Call grokdeclarator to figure out what type this is. */
+ type2 = grokdeclarator (NULL, &decl_specs, TYPENAME,
+ /*initialized=*/0, /*attrlist=*/NULL);
+ }
+
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ /* Complete the trait expression, which may mean either processing
+ the trait expr now or saving it for template instantiation. */
+ switch(kind)
+ {
+ case CPTK_UNDERLYING_TYPE:
+ return finish_underlying_type (type1);
+ case CPTK_BASES:
+ return finish_bases (type1, false);
+ case CPTK_DIRECT_BASES:
+ return finish_bases (type1, true);
+ default:
+ return finish_trait_expr (kind, type1, type2);
+ }
+}
+
+/* Lambdas that appear in variable initializer or default argument scope
+ get that in their mangling, so we need to record it. We might as well
+ use the count for function and namespace scopes as well. */
+static GTY(()) tree lambda_scope;
+static GTY(()) int lambda_count;
+typedef struct GTY(()) tree_int
+{
+ tree t;
+ int i;
+} tree_int;
+static GTY(()) vec<tree_int, va_gc> *lambda_scope_stack;
+
+static void
+start_lambda_scope (tree decl)
+{
+ tree_int ti;
+ gcc_assert (decl);
+ /* Once we're inside a function, we ignore other scopes and just push
+ the function again so that popping works properly. */
+ if (current_function_decl && TREE_CODE (decl) != FUNCTION_DECL)
+ decl = current_function_decl;
+ ti.t = lambda_scope;
+ ti.i = lambda_count;
+ vec_safe_push (lambda_scope_stack, ti);
+ if (lambda_scope != decl)
+ {
+ /* Don't reset the count if we're still in the same function. */
+ lambda_scope = decl;
+ lambda_count = 0;
+ }
+}
+
+static void
+record_lambda_scope (tree lambda)
+{
+ LAMBDA_EXPR_EXTRA_SCOPE (lambda) = lambda_scope;
+ LAMBDA_EXPR_DISCRIMINATOR (lambda) = lambda_count++;
+}
+
+static void
+finish_lambda_scope (void)
+{
+ tree_int *p = &lambda_scope_stack->last ();
+ if (lambda_scope != p->t)
+ {
+ lambda_scope = p->t;
+ lambda_count = p->i;
+ }
+ lambda_scope_stack->pop ();
+}
+
+/* Parse a lambda expression.
+
+ lambda-expression:
+ lambda-introducer lambda-declarator [opt] compound-statement
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_lambda_expression (cp_parser* parser)
+{
+ tree lambda_expr = build_lambda_expr ();
+ tree type;
+ bool ok;
+
+ LAMBDA_EXPR_LOCATION (lambda_expr)
+ = cp_lexer_peek_token (parser->lexer)->location;
+
+ if (cp_unevaluated_operand)
+ error_at (LAMBDA_EXPR_LOCATION (lambda_expr),
+ "lambda-expression in unevaluated context");
+
+ /* We may be in the middle of deferred access check. Disable
+ it now. */
+ push_deferring_access_checks (dk_no_deferred);
+
+ cp_parser_lambda_introducer (parser, lambda_expr);
+
+ type = begin_lambda_type (lambda_expr);
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ record_lambda_scope (lambda_expr);
+
+ /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */
+ determine_visibility (TYPE_NAME (type));
+
+ /* Now that we've started the type, add the capture fields for any
+ explicit captures. */
+ register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));
+
+ {
+ /* Inside the class, surrounding template-parameter-lists do not apply. */
+ unsigned int saved_num_template_parameter_lists
+ = parser->num_template_parameter_lists;
+ unsigned char in_statement = parser->in_statement;
+ bool in_switch_statement_p = parser->in_switch_statement_p;
+ bool fully_implicit_function_template_p
+ = parser->fully_implicit_function_template_p;
+ tree implicit_template_parms = parser->implicit_template_parms;
+ cp_binding_level* implicit_template_scope = parser->implicit_template_scope;
+ bool auto_is_implicit_function_template_parm_p
+ = parser->auto_is_implicit_function_template_parm_p;
+
+ parser->num_template_parameter_lists = 0;
+ parser->in_statement = 0;
+ parser->in_switch_statement_p = false;
+ parser->fully_implicit_function_template_p = false;
+ parser->implicit_template_parms = 0;
+ parser->implicit_template_scope = 0;
+ parser->auto_is_implicit_function_template_parm_p = false;
+
+ /* By virtue of defining a local class, a lambda expression has access to
+ the private variables of enclosing classes. */
+
+ ok = cp_parser_lambda_declarator_opt (parser, lambda_expr);
+
+ if (ok)
+ cp_parser_lambda_body (parser, lambda_expr);
+ else if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+
+ /* The capture list was built up in reverse order; fix that now. */
+ LAMBDA_EXPR_CAPTURE_LIST (lambda_expr)
+ = nreverse (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));
+
+ if (ok)
+ maybe_add_lambda_conv_op (type);
+
+ type = finish_struct (type, /*attributes=*/NULL_TREE);
+
+ parser->num_template_parameter_lists = saved_num_template_parameter_lists;
+ parser->in_statement = in_statement;
+ parser->in_switch_statement_p = in_switch_statement_p;
+ parser->fully_implicit_function_template_p
+ = fully_implicit_function_template_p;
+ parser->implicit_template_parms = implicit_template_parms;
+ parser->implicit_template_scope = implicit_template_scope;
+ parser->auto_is_implicit_function_template_parm_p
+ = auto_is_implicit_function_template_parm_p;
+ }
+
+ pop_deferring_access_checks ();
+
+ /* This field is only used during parsing of the lambda. */
+ LAMBDA_EXPR_THIS_CAPTURE (lambda_expr) = NULL_TREE;
+
+ /* This lambda shouldn't have any proxies left at this point. */
+ gcc_assert (LAMBDA_EXPR_PENDING_PROXIES (lambda_expr) == NULL);
+ /* And now that we're done, push proxies for an enclosing lambda. */
+ insert_pending_capture_proxies ();
+
+ if (ok)
+ return build_lambda_object (lambda_expr);
+ else
+ return error_mark_node;
+}
+
+/* Parse the beginning of a lambda expression.
+
+ lambda-introducer:
+ [ lambda-capture [opt] ]
+
+ LAMBDA_EXPR is the current representation of the lambda expression. */
+
+static void
+cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
+{
+ /* Need commas after the first capture. */
+ bool first = true;
+
+ /* Eat the leading `['. */
+ cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
+
+ /* Record default capture mode. "[&" "[=" "[&," "[=," */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_AND)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_NAME)
+ LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_REFERENCE;
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_COPY;
+
+ if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ first = false;
+ }
+
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_SQUARE))
+ {
+ cp_token* capture_token;
+ tree capture_id;
+ tree capture_init_expr;
+ cp_id_kind idk = CP_ID_KIND_NONE;
+ bool explicit_init_p = false;
+
+ enum capture_kind_type
+ {
+ BY_COPY,
+ BY_REFERENCE
+ };
+ enum capture_kind_type capture_kind = BY_COPY;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ {
+ error ("expected end of capture-list");
+ return;
+ }
+
+ if (first)
+ first = false;
+ else
+ cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+
+ /* Possibly capture `this'. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THIS))
+ {
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+ if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY)
+ pedwarn (loc, 0, "explicit by-copy capture of %<this%> redundant "
+ "with by-copy capture default");
+ cp_lexer_consume_token (parser->lexer);
+ add_capture (lambda_expr,
+ /*id=*/this_identifier,
+ /*initializer=*/finish_this_expr(),
+ /*by_reference_p=*/false,
+ explicit_init_p);
+ continue;
+ }
+
+ /* Remember whether we want to capture as a reference or not. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_AND))
+ {
+ capture_kind = BY_REFERENCE;
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ /* Get the identifier. */
+ capture_token = cp_lexer_peek_token (parser->lexer);
+ capture_id = cp_parser_identifier (parser);
+
+ if (capture_id == error_mark_node)
+ /* Would be nice to have a cp_parser_skip_to_closing_x for general
+ delimiters, but I modified this to stop on unnested ']' as well. It
+ was already changed to stop on unnested '}', so the
+ "closing_parenthesis" name is no more misleading with my change. */
+ {
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/true,
+ /*consume_paren=*/true);
+ break;
+ }
+
+ /* Find the initializer for this capture. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)
+ || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
+ || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ bool direct, non_constant;
+ /* An explicit initializer exists. */
+ if (cxx_dialect < cxx1y)
+ pedwarn (input_location, 0,
+ "lambda capture initializers "
+ "only available with -std=c++1y or -std=gnu++1y");
+ capture_init_expr = cp_parser_initializer (parser, &direct,
+ &non_constant);
+ explicit_init_p = true;
+ if (capture_init_expr == NULL_TREE)
+ {
+ error ("empty initializer for lambda init-capture");
+ capture_init_expr = error_mark_node;
+ }
+ }
+ else
+ {
+ const char* error_msg;
+
+ /* Turn the identifier into an id-expression. */
+ capture_init_expr
+ = cp_parser_lookup_name_simple (parser, capture_id,
+ capture_token->location);
+
+ if (capture_init_expr == error_mark_node)
+ {
+ unqualified_name_lookup_error (capture_id);
+ continue;
+ }
+ else if (DECL_P (capture_init_expr)
+ && (!VAR_P (capture_init_expr)
+ && TREE_CODE (capture_init_expr) != PARM_DECL))
+ {
+ error_at (capture_token->location,
+ "capture of non-variable %qD ",
+ capture_init_expr);
+ inform (0, "%q+#D declared here", capture_init_expr);
+ continue;
+ }
+ if (VAR_P (capture_init_expr)
+ && decl_storage_duration (capture_init_expr) != dk_auto)
+ {
+ pedwarn (capture_token->location, 0, "capture of variable "
+ "%qD with non-automatic storage duration",
+ capture_init_expr);
+ inform (0, "%q+#D declared here", capture_init_expr);
+ continue;
+ }
+
+ capture_init_expr
+ = finish_id_expression
+ (capture_id,
+ capture_init_expr,
+ parser->scope,
+ &idk,
+ /*integral_constant_expression_p=*/false,
+ /*allow_non_integral_constant_expression_p=*/false,
+ /*non_integral_constant_expression_p=*/NULL,
+ /*template_p=*/false,
+ /*done=*/true,
+ /*address_p=*/false,
+ /*template_arg_p=*/false,
+ &error_msg,
+ capture_token->location);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ capture_init_expr = make_pack_expansion (capture_init_expr);
+ }
+ else
+ check_for_bare_parameter_packs (capture_init_expr);
+ }
+
+ if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE
+ && !explicit_init_p)
+ {
+ if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY
+ && capture_kind == BY_COPY)
+ pedwarn (capture_token->location, 0, "explicit by-copy capture "
+ "of %qD redundant with by-copy capture default",
+ capture_id);
+ if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_REFERENCE
+ && capture_kind == BY_REFERENCE)
+ pedwarn (capture_token->location, 0, "explicit by-reference "
+ "capture of %qD redundant with by-reference capture "
+ "default", capture_id);
+ }
+
+ add_capture (lambda_expr,
+ capture_id,
+ capture_init_expr,
+ /*by_reference_p=*/capture_kind == BY_REFERENCE,
+ explicit_init_p);
+ }
+
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+}
+
+/* Parse the (optional) middle of a lambda expression.
+
+ lambda-declarator:
+ < template-parameter-list [opt] >
+ ( parameter-declaration-clause [opt] )
+ attribute-specifier [opt]
+ mutable [opt]
+ exception-specification [opt]
+ lambda-return-type-clause [opt]
+
+ LAMBDA_EXPR is the current representation of the lambda expression. */
+
+static bool
+cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
+{
+ /* 5.1.1.4 of the standard says:
+ If a lambda-expression does not include a lambda-declarator, it is as if
+ the lambda-declarator were ().
+ This means an empty parameter list, no attributes, and no exception
+ specification. */
+ tree param_list = void_list_node;
+ tree attributes = NULL_TREE;
+ tree exception_spec = NULL_TREE;
+ tree template_param_list = NULL_TREE;
+
+ /* The template-parameter-list is optional, but must begin with
+ an opening angle if present. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+ {
+ if (cxx_dialect < cxx1y)
+ pedwarn (parser->lexer->next_token->location, 0,
+ "lambda templates are only available with "
+ "-std=c++1y or -std=gnu++1y");
+
+ cp_lexer_consume_token (parser->lexer);
+
+ template_param_list = cp_parser_template_parameter_list (parser);
+
+ cp_parser_skip_to_end_of_template_parameter_list (parser);
+
+ /* We just processed one more parameter list. */
+ ++parser->num_template_parameter_lists;
+ }
+
+ /* The parameter-declaration-clause is optional (unless
+ template-parameter-list was given), but must begin with an
+ opening parenthesis if present. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ cp_lexer_consume_token (parser->lexer);
+
+ begin_scope (sk_function_parms, /*entity=*/NULL_TREE);
+
+ /* Parse parameters. */
+ param_list = cp_parser_parameter_declaration_clause (parser);
+
+ /* Default arguments shall not be specified in the
+ parameter-declaration-clause of a lambda-declarator. */
+ for (tree t = param_list; t; t = TREE_CHAIN (t))
+ if (TREE_PURPOSE (t))
+ pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)), OPT_Wpedantic,
+ "default argument specified for lambda parameter");
+
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ attributes = cp_parser_attributes_opt (parser);
+
+ /* Parse optional `mutable' keyword. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_MUTABLE))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ LAMBDA_EXPR_MUTABLE_P (lambda_expr) = 1;
+ }
+
+ /* Parse optional exception specification. */
+ exception_spec = cp_parser_exception_specification_opt (parser);
+
+ /* Parse optional trailing return type. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ LAMBDA_EXPR_RETURN_TYPE (lambda_expr)
+ = cp_parser_trailing_type_id (parser);
+ }
+
+ /* The function parameters must be in scope all the way until after the
+ trailing-return-type in case of decltype. */
+ pop_bindings_and_leave_scope ();
+ }
+ else if (template_param_list != NULL_TREE) // generate diagnostic
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+ /* Create the function call operator.
+
+ Messing with declarators like this is no uglier than building up the
+ FUNCTION_DECL by hand, and this is less likely to get out of sync with
+ other code. */
+ {
+ cp_decl_specifier_seq return_type_specs;
+ cp_declarator* declarator;
+ tree fco;
+ int quals;
+ void *p;
+
+ clear_decl_specs (&return_type_specs);
+ if (LAMBDA_EXPR_RETURN_TYPE (lambda_expr))
+ return_type_specs.type = LAMBDA_EXPR_RETURN_TYPE (lambda_expr);
+ else
+ /* Maybe we will deduce the return type later. */
+ return_type_specs.type = make_auto ();
+
+ p = obstack_alloc (&declarator_obstack, 0);
+
+ declarator = make_id_declarator (NULL_TREE, ansi_opname (CALL_EXPR),
+ sfk_none);
+
+ quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr)
+ ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);
+ declarator = make_call_declarator (declarator, param_list, quals,
+ VIRT_SPEC_UNSPECIFIED,
+ REF_QUAL_NONE,
+ exception_spec,
+ /*late_return_type=*/NULL_TREE);
+ declarator->id_loc = LAMBDA_EXPR_LOCATION (lambda_expr);
+
+ fco = grokmethod (&return_type_specs,
+ declarator,
+ attributes);
+ if (fco != error_mark_node)
+ {
+ DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
+ DECL_ARTIFICIAL (fco) = 1;
+ /* Give the object parameter a different name. */
+ DECL_NAME (DECL_ARGUMENTS (fco)) = get_identifier ("__closure");
+ }
+ if (template_param_list)
+ {
+ fco = finish_member_template_decl (fco);
+ finish_template_decl (template_param_list);
+ --parser->num_template_parameter_lists;
+ }
+ else if (parser->fully_implicit_function_template_p)
+ fco = finish_fully_implicit_template (parser, fco);
+
+ finish_member_declaration (fco);
+
+ obstack_free (&declarator_obstack, p);
+
+ return (fco != error_mark_node);
+ }
+}
+
+/* Parse the body of a lambda expression, which is simply
+
+ compound-statement
+
+ but which requires special handling.
+ LAMBDA_EXPR is the current representation of the lambda expression. */
+
+static void
+cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
+{
+ bool nested = (current_function_decl != NULL_TREE);
+ bool local_variables_forbidden_p = parser->local_variables_forbidden_p;
+ if (nested)
+ push_function_context ();
+ else
+ /* Still increment function_depth so that we don't GC in the
+ middle of an expression. */
+ ++function_depth;
+ /* Clear this in case we're in the middle of a default argument. */
+ parser->local_variables_forbidden_p = false;
+
+ /* Finish the function call operator
+ - class_specifier
+ + late_parsing_for_member
+ + function_definition_after_declarator
+ + ctor_initializer_opt_and_function_body */
+ {
+ tree fco = lambda_function (lambda_expr);
+ tree body;
+ bool done = false;
+ tree compound_stmt;
+ tree cap;
+
+ /* Let the front end know that we are going to be defining this
+ function. */
+ start_preparsed_function (fco,
+ NULL_TREE,
+ SF_PRE_PARSED | SF_INCLASS_INLINE);
+
+ start_lambda_scope (fco);
+ body = begin_function_body ();
+
+ if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ goto out;
+
+ /* Push the proxies for any explicit captures. */
+ for (cap = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); cap;
+ cap = TREE_CHAIN (cap))
+ build_capture_proxy (TREE_PURPOSE (cap));
+
+ compound_stmt = begin_compound_stmt (0);
+
+ /* 5.1.1.4 of the standard says:
+ If a lambda-expression does not include a trailing-return-type, it
+ is as if the trailing-return-type denotes the following type:
+ * if the compound-statement is of the form
+ { return attribute-specifier [opt] expression ; }
+ the type of the returned expression after lvalue-to-rvalue
+ conversion (_conv.lval_ 4.1), array-to-pointer conversion
+ (_conv.array_ 4.2), and function-to-pointer conversion
+ (_conv.func_ 4.3);
+ * otherwise, void. */
+
+ /* In a lambda that has neither a lambda-return-type-clause
+ nor a deducible form, errors should be reported for return statements
+ in the body. Since we used void as the placeholder return type, parsing
+ the body as usual will give such desired behavior. */
+ if (!LAMBDA_EXPR_RETURN_TYPE (lambda_expr)
+ && cp_lexer_peek_nth_token (parser->lexer, 1)->keyword == RID_RETURN
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SEMICOLON)
+ {
+ tree expr = NULL_TREE;
+ cp_id_kind idk = CP_ID_KIND_NONE;
+
+ /* Parse tentatively in case there's more after the initial return
+ statement. */
+ cp_parser_parse_tentatively (parser);
+
+ cp_parser_require_keyword (parser, RID_RETURN, RT_RETURN);
+
+ expr = cp_parser_expression (parser, /*cast_p=*/false, &idk);
+
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+
+ if (cp_parser_parse_definitely (parser))
+ {
+ if (!processing_template_decl)
+ apply_deduced_return_type (fco, lambda_return_type (expr));
+
+ /* Will get error here if type not deduced yet. */
+ finish_return_stmt (expr);
+
+ done = true;
+ }
+ }
+
+ if (!done)
+ {
+ while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
+ cp_parser_label_declaration (parser);
+ cp_parser_statement_seq_opt (parser, NULL_TREE);
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ }
+
+ finish_compound_stmt (compound_stmt);
+
+ out:
+ finish_function_body (body);
+ finish_lambda_scope ();
+
+ /* Finish the function and generate code for it if necessary. */
+ tree fn = finish_function (/*inline*/2);
+
+ /* Only expand if the call op is not a template. */
+ if (!DECL_TEMPLATE_INFO (fco))
+ expand_or_defer_fn (fn);
+ }
+
+ parser->local_variables_forbidden_p = local_variables_forbidden_p;
+ if (nested)
+ pop_function_context();
+ else
+ --function_depth;
+}
+
+/* Statements [gram.stmt.stmt] */
+
+/* Parse a statement.
+
+ statement:
+ labeled-statement
+ expression-statement
+ compound-statement
+ selection-statement
+ iteration-statement
+ jump-statement
+ declaration-statement
+ try-block
+
+ C++11:
+
+ statement:
+ labeled-statement
+ attribute-specifier-seq (opt) expression-statement
+ attribute-specifier-seq (opt) compound-statement
+ attribute-specifier-seq (opt) selection-statement
+ attribute-specifier-seq (opt) iteration-statement
+ attribute-specifier-seq (opt) jump-statement
+ declaration-statement
+ attribute-specifier-seq (opt) try-block
+
+ TM Extension:
+
+ statement:
+ atomic-statement
+
+ IN_COMPOUND is true when the statement is nested inside a
+ cp_parser_compound_statement; this matters for certain pragmas.
+
+ If IF_P is not NULL, *IF_P is set to indicate whether the statement
+ is a (possibly labeled) if statement which is not enclosed in braces
+ and has an else clause. This is used to implement -Wparentheses. */
+
+static void
+cp_parser_statement (cp_parser* parser, tree in_statement_expr,
+ bool in_compound, bool *if_p)
+{
+ tree statement, std_attrs = NULL_TREE;
+ cp_token *token;
+ location_t statement_location, attrs_location;
+
+ restart:
+ if (if_p != NULL)
+ *if_p = false;
+ /* There is no statement yet. */
+ statement = NULL_TREE;
+
+ cp_lexer_save_tokens (parser->lexer);
+ attrs_location = cp_lexer_peek_token (parser->lexer)->location;
+ if (c_dialect_objc ())
+ /* In obj-c++, seeing '[[' might be the either the beginning of
+ c++11 attributes, or a nested objc-message-expression. So
+ let's parse the c++11 attributes tentatively. */
+ cp_parser_parse_tentatively (parser);
+ std_attrs = cp_parser_std_attribute_spec_seq (parser);
+ if (c_dialect_objc ())
+ {
+ if (!cp_parser_parse_definitely (parser))
+ std_attrs = NULL_TREE;
+ }
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Remember the location of the first token in the statement. */
+ statement_location = token->location;
+ /* If this is a keyword, then that will often determine what kind of
+ statement we have. */
+ if (token->type == CPP_KEYWORD)
+ {
+ enum rid keyword = token->keyword;
+
+ switch (keyword)
+ {
+ case RID_CASE:
+ case RID_DEFAULT:
+ /* Looks like a labeled-statement with a case label.
+ Parse the label, and then use tail recursion to parse
+ the statement. */
+ cp_parser_label_for_labeled_statement (parser, std_attrs);
+ goto restart;
+
+ case RID_IF:
+ case RID_SWITCH:
+ statement = cp_parser_selection_statement (parser, if_p);
+ break;
+
+ case RID_WHILE:
+ case RID_DO:
+ case RID_FOR:
+ statement = cp_parser_iteration_statement (parser, false);
+ break;
+
+ case RID_BREAK:
+ case RID_CONTINUE:
+ case RID_RETURN:
+ case RID_GOTO:
+ statement = cp_parser_jump_statement (parser);
+ break;
+
+ /* Objective-C++ exception-handling constructs. */
+ case RID_AT_TRY:
+ case RID_AT_CATCH:
+ case RID_AT_FINALLY:
+ case RID_AT_SYNCHRONIZED:
+ case RID_AT_THROW:
+ statement = cp_parser_objc_statement (parser);
+ break;
+
+ case RID_TRY:
+ statement = cp_parser_try_block (parser);
+ break;
+
+ case RID_NAMESPACE:
+ /* This must be a namespace alias definition. */
+ cp_parser_declaration_statement (parser);
+ return;
+
+ case RID_TRANSACTION_ATOMIC:
+ case RID_TRANSACTION_RELAXED:
+ statement = cp_parser_transaction (parser, keyword);
+ break;
+ case RID_TRANSACTION_CANCEL:
+ statement = cp_parser_transaction_cancel (parser);
+ break;
+
+ default:
+ /* It might be a keyword like `int' that can start a
+ declaration-statement. */
+ break;
+ }
+ }
+ else if (token->type == CPP_NAME)
+ {
+ /* If the next token is a `:', then we are looking at a
+ labeled-statement. */
+ token = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (token->type == CPP_COLON)
+ {
+ /* Looks like a labeled-statement with an ordinary label.
+ Parse the label, and then use tail recursion to parse
+ the statement. */
+
+ cp_parser_label_for_labeled_statement (parser, std_attrs);
+ goto restart;
+ }
+ }
+ /* Anything that starts with a `{' must be a compound-statement. */
+ else if (token->type == CPP_OPEN_BRACE)
+ statement = cp_parser_compound_statement (parser, NULL, false, false);
+ /* CPP_PRAGMA is a #pragma inside a function body, which constitutes
+ a statement all its own. */
+ else if (token->type == CPP_PRAGMA)
+ {
+ /* Only certain OpenMP pragmas are attached to statements, and thus
+ are considered statements themselves. All others are not. In
+ the context of a compound, accept the pragma as a "statement" and
+ return so that we can check for a close brace. Otherwise we
+ require a real statement and must go back and read one. */
+ if (in_compound)
+ cp_parser_pragma (parser, pragma_compound);
+ else if (!cp_parser_pragma (parser, pragma_stmt))
+ goto restart;
+ return;
+ }
+ else if (token->type == CPP_EOF)
+ {
+ cp_parser_error (parser, "expected statement");
+ return;
+ }
+
+ /* Everything else must be a declaration-statement or an
+ expression-statement. Try for the declaration-statement
+ first, unless we are looking at a `;', in which case we know that
+ we have an expression-statement. */
+ if (!statement)
+ {
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ if (std_attrs != NULL_TREE)
+ {
+ /* Attributes should be parsed as part of the the
+ declaration, so let's un-parse them. */
+ cp_lexer_rollback_tokens (parser->lexer);
+ std_attrs = NULL_TREE;
+ }
+
+ cp_parser_parse_tentatively (parser);
+ /* Try to parse the declaration-statement. */
+ cp_parser_declaration_statement (parser);
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return;
+ }
+ /* Look for an expression-statement instead. */
+ statement = cp_parser_expression_statement (parser, in_statement_expr);
+ }
+
+ /* Set the line number for the statement. */
+ if (statement && STATEMENT_CODE_P (TREE_CODE (statement)))
+ SET_EXPR_LOCATION (statement, statement_location);
+
+ /* Note that for now, we don't do anything with c++11 statements
+ parsed at this level. */
+ if (std_attrs != NULL_TREE)
+ warning_at (attrs_location,
+ OPT_Wattributes,
+ "attributes at the beginning of statement are ignored");
+}
+
+/* Parse the label for a labeled-statement, i.e.
+
+ identifier :
+ case constant-expression :
+ default :
+
+ GNU Extension:
+ case constant-expression ... constant-expression : statement
+
+ When a label is parsed without errors, the label is added to the
+ parse tree by the finish_* functions, so this function doesn't
+ have to return the label. */
+
+static void
+cp_parser_label_for_labeled_statement (cp_parser* parser, tree attributes)
+{
+ cp_token *token;
+ tree label = NULL_TREE;
+ bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+
+ /* The next token should be an identifier. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type != CPP_NAME
+ && token->type != CPP_KEYWORD)
+ {
+ cp_parser_error (parser, "expected labeled-statement");
+ return;
+ }
+
+ parser->colon_corrects_to_scope_p = false;
+ switch (token->keyword)
+ {
+ case RID_CASE:
+ {
+ tree expr, expr_hi;
+ cp_token *ellipsis;
+
+ /* Consume the `case' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the constant-expression. */
+ expr = cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/false,
+ NULL);
+
+ ellipsis = cp_lexer_peek_token (parser->lexer);
+ if (ellipsis->type == CPP_ELLIPSIS)
+ {
+ /* Consume the `...' token. */
+ cp_lexer_consume_token (parser->lexer);
+ expr_hi =
+ cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/false,
+ NULL);
+ /* We don't need to emit warnings here, as the common code
+ will do this for us. */
+ }
+ else
+ expr_hi = NULL_TREE;
+
+ if (parser->in_switch_statement_p)
+ finish_case_label (token->location, expr, expr_hi);
+ else
+ error_at (token->location,
+ "case label %qE not within a switch statement",
+ expr);
+ }
+ break;
+
+ case RID_DEFAULT:
+ /* Consume the `default' token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ if (parser->in_switch_statement_p)
+ finish_case_label (token->location, NULL_TREE, NULL_TREE);
+ else
+ error_at (token->location, "case label not within a switch statement");
+ break;
+
+ default:
+ /* Anything else must be an ordinary label. */
+ label = finish_label_stmt (cp_parser_identifier (parser));
+ break;
+ }
+
+ /* Require the `:' token. */
+ cp_parser_require (parser, CPP_COLON, RT_COLON);
+
+ /* An ordinary label may optionally be followed by attributes.
+ However, this is only permitted if the attributes are then
+ followed by a semicolon. This is because, for backward
+ compatibility, when parsing
+ lab: __attribute__ ((unused)) int i;
+ we want the attribute to attach to "i", not "lab". */
+ if (label != NULL_TREE
+ && cp_next_tokens_can_be_gnu_attribute_p (parser))
+ {
+ tree attrs;
+ cp_parser_parse_tentatively (parser);
+ attrs = cp_parser_gnu_attributes_opt (parser);
+ if (attrs == NULL_TREE
+ || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ cp_parser_abort_tentative_parse (parser);
+ else if (!cp_parser_parse_definitely (parser))
+ ;
+ else
+ attributes = chainon (attributes, attrs);
+ }
+
+ if (attributes != NULL_TREE)
+ cplus_decl_attributes (&label, attributes, 0);
+
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+}
+
+/* Parse an expression-statement.
+
+ expression-statement:
+ expression [opt] ;
+
+ Returns the new EXPR_STMT -- or NULL_TREE if the expression
+ statement consists of nothing more than an `;'. IN_STATEMENT_EXPR_P
+ indicates whether this expression-statement is part of an
+ expression statement. */
+
+static tree
+cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
+{
+ tree statement = NULL_TREE;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* If the next token is a ';', then there is no expression
+ statement. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ statement = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ if (statement == error_mark_node
+ && !cp_parser_uncommitted_to_tentative_parse_p (parser))
+ {
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+ }
+
+ /* Give a helpful message for "A<T>::type t;" and the like. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
+ && !cp_parser_uncommitted_to_tentative_parse_p (parser))
+ {
+ if (TREE_CODE (statement) == SCOPE_REF)
+ error_at (token->location, "need %<typename%> before %qE because "
+ "%qT is a dependent scope",
+ statement, TREE_OPERAND (statement, 0));
+ else if (is_overloaded_fn (statement)
+ && DECL_CONSTRUCTOR_P (get_first_fn (statement)))
+ {
+ /* A::A a; */
+ tree fn = get_first_fn (statement);
+ error_at (token->location,
+ "%<%T::%D%> names the constructor, not the type",
+ DECL_CONTEXT (fn), DECL_NAME (fn));
+ }
+ }
+
+ /* Consume the final `;'. */
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+
+ if (in_statement_expr
+ && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
+ /* This is the final expression statement of a statement
+ expression. */
+ statement = finish_stmt_expr_expr (statement, in_statement_expr);
+ else if (statement)
+ statement = finish_expr_stmt (statement);
+
+ return statement;
+}
+
+/* Parse a compound-statement.
+
+ compound-statement:
+ { statement-seq [opt] }
+
+ GNU extension:
+
+ compound-statement:
+ { label-declaration-seq [opt] statement-seq [opt] }
+
+ label-declaration-seq:
+ label-declaration
+ label-declaration-seq label-declaration
+
+ Returns a tree representing the statement. */
+
+static tree
+cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
+ bool in_try, bool function_body)
+{
+ tree compound_stmt;
+
+ /* Consume the `{'. */
+ if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ return error_mark_node;
+ if (DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+ && !function_body)
+ pedwarn (input_location, OPT_Wpedantic,
+ "compound-statement in constexpr function");
+ /* Begin the compound-statement. */
+ compound_stmt = begin_compound_stmt (in_try ? BCS_TRY_BLOCK : 0);
+ /* If the next keyword is `__label__' we have a label declaration. */
+ while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
+ cp_parser_label_declaration (parser);
+ /* Parse an (optional) statement-seq. */
+ cp_parser_statement_seq_opt (parser, in_statement_expr);
+ /* Finish the compound-statement. */
+ finish_compound_stmt (compound_stmt);
+ /* Consume the `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+
+ return compound_stmt;
+}
+
+/* Parse an (optional) statement-seq.
+
+ statement-seq:
+ statement
+ statement-seq [opt] statement */
+
+static void
+cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
+{
+ /* Scan statements until there aren't any more. */
+ while (true)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* If we are looking at a `}', then we have run out of
+ statements; the same is true if we have reached the end
+ of file, or have stumbled upon a stray '@end'. */
+ if (token->type == CPP_CLOSE_BRACE
+ || token->type == CPP_EOF
+ || token->type == CPP_PRAGMA_EOL
+ || (token->type == CPP_KEYWORD && token->keyword == RID_AT_END))
+ break;
+
+ /* If we are in a compound statement and find 'else' then
+ something went wrong. */
+ else if (token->type == CPP_KEYWORD && token->keyword == RID_ELSE)
+ {
+ if (parser->in_statement & IN_IF_STMT)
+ break;
+ else
+ {
+ token = cp_lexer_consume_token (parser->lexer);
+ error_at (token->location, "%<else%> without a previous %<if%>");
+ }
+ }
+
+ /* Parse the statement. */
+ cp_parser_statement (parser, in_statement_expr, true, NULL);
+ }
+}
+
+/* Parse a selection-statement.
+
+ selection-statement:
+ if ( condition ) statement
+ if ( condition ) statement else statement
+ switch ( condition ) statement
+
+ Returns the new IF_STMT or SWITCH_STMT.
+
+ If IF_P is not NULL, *IF_P is set to indicate whether the statement
+ is a (possibly labeled) if statement which is not enclosed in
+ braces and has an else clause. This is used to implement
+ -Wparentheses. */
+
+static tree
+cp_parser_selection_statement (cp_parser* parser, bool *if_p)
+{
+ cp_token *token;
+ enum rid keyword;
+
+ if (if_p != NULL)
+ *if_p = false;
+
+ /* Peek at the next token. */
+ token = cp_parser_require (parser, CPP_KEYWORD, RT_SELECT);
+
+ /* See what kind of keyword it is. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ case RID_IF:
+ case RID_SWITCH:
+ {
+ tree statement;
+ tree condition;
+
+ /* Look for the `('. */
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ {
+ cp_parser_skip_to_end_of_statement (parser);
+ return error_mark_node;
+ }
+
+ /* Begin the selection-statement. */
+ if (keyword == RID_IF)
+ statement = begin_if_stmt ();
+ else
+ statement = begin_switch_stmt ();
+
+ /* Parse the condition. */
+ condition = cp_parser_condition (parser);
+ /* Look for the `)'. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, true, false,
+ /*consume_paren=*/true);
+
+ if (keyword == RID_IF)
+ {
+ bool nested_if;
+ unsigned char in_statement;
+
+ /* Add the condition. */
+ finish_if_stmt_cond (condition, statement);
+
+ /* Parse the then-clause. */
+ in_statement = parser->in_statement;
+ parser->in_statement |= IN_IF_STMT;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ {
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+ add_stmt (build_empty_stmt (loc));
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_ELSE))
+ warning_at (loc, OPT_Wempty_body, "suggest braces around "
+ "empty body in an %<if%> statement");
+ nested_if = false;
+ }
+ else
+ cp_parser_implicitly_scoped_statement (parser, &nested_if);
+ parser->in_statement = in_statement;
+
+ finish_then_clause (statement);
+
+ /* If the next token is `else', parse the else-clause. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer,
+ RID_ELSE))
+ {
+ /* Consume the `else' keyword. */
+ cp_lexer_consume_token (parser->lexer);
+ begin_else_clause (statement);
+ /* Parse the else-clause. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ {
+ location_t loc;
+ loc = cp_lexer_peek_token (parser->lexer)->location;
+ warning_at (loc,
+ OPT_Wempty_body, "suggest braces around "
+ "empty body in an %<else%> statement");
+ add_stmt (build_empty_stmt (loc));
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ cp_parser_implicitly_scoped_statement (parser, NULL);
+
+ finish_else_clause (statement);
+
+ /* If we are currently parsing a then-clause, then
+ IF_P will not be NULL. We set it to true to
+ indicate that this if statement has an else clause.
+ This may trigger the Wparentheses warning below
+ when we get back up to the parent if statement. */
+ if (if_p != NULL)
+ *if_p = true;
+ }
+ else
+ {
+ /* This if statement does not have an else clause. If
+ NESTED_IF is true, then the then-clause is an if
+ statement which does have an else clause. We warn
+ about the potential ambiguity. */
+ if (nested_if)
+ warning_at (EXPR_LOCATION (statement), OPT_Wparentheses,
+ "suggest explicit braces to avoid ambiguous"
+ " %<else%>");
+ }
+
+ /* Now we're all done with the if-statement. */
+ finish_if_stmt (statement);
+ }
+ else
+ {
+ bool in_switch_statement_p;
+ unsigned char in_statement;
+
+ /* Add the condition. */
+ finish_switch_cond (condition, statement);
+
+ /* Parse the body of the switch-statement. */
+ in_switch_statement_p = parser->in_switch_statement_p;
+ in_statement = parser->in_statement;
+ parser->in_switch_statement_p = true;
+ parser->in_statement |= IN_SWITCH_STMT;
+ cp_parser_implicitly_scoped_statement (parser, NULL);
+ parser->in_switch_statement_p = in_switch_statement_p;
+ parser->in_statement = in_statement;
+
+ /* Now we're all done with the switch-statement. */
+ finish_switch_stmt (statement);
+ }
+
+ return statement;
+ }
+ break;
+
+ default:
+ cp_parser_error (parser, "expected selection-statement");
+ return error_mark_node;
+ }
+}
+
+/* Parse a condition.
+
+ condition:
+ expression
+ type-specifier-seq declarator = initializer-clause
+ type-specifier-seq declarator braced-init-list
+
+ GNU Extension:
+
+ condition:
+ type-specifier-seq declarator asm-specification [opt]
+ attributes [opt] = assignment-expression
+
+ Returns the expression that should be tested. */
+
+static tree
+cp_parser_condition (cp_parser* parser)
+{
+ cp_decl_specifier_seq type_specifiers;
+ const char *saved_message;
+ int declares_class_or_enum;
+
+ /* Try the declaration first. */
+ cp_parser_parse_tentatively (parser);
+ /* New types are not allowed in the type-specifier-seq for a
+ condition. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in conditions");
+ /* Parse the type-specifier-seq. */
+ cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR,
+ &type_specifiers,
+ &declares_class_or_enum);
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+ /* If all is well, we might be looking at a declaration. */
+ if (!cp_parser_error_occurred (parser))
+ {
+ tree decl;
+ tree asm_specification;
+ tree attributes;
+ cp_declarator *declarator;
+ tree initializer = NULL_TREE;
+
+ /* Parse the declarator. */
+ declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
+ /* Parse the asm-specification. */
+ asm_specification = cp_parser_asm_specification_opt (parser);
+ /* If the next token is not an `=' or '{', then we might still be
+ looking at an expression. For example:
+
+ if (A(a).x)
+
+ looks like a decl-specifier-seq and a declarator -- but then
+ there is no `=', so this is an expression. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
+ cp_parser_simulate_error (parser);
+
+ /* If we did see an `=' or '{', then we are looking at a declaration
+ for sure. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ tree pushed_scope;
+ bool non_constant_p;
+ bool flags = LOOKUP_ONLYCONVERTING;
+
+ /* Create the declaration. */
+ decl = start_decl (declarator, &type_specifiers,
+ /*initialized_p=*/true,
+ attributes, /*prefix_attributes=*/NULL_TREE,
+ &pushed_scope);
+
+ /* Parse the initializer. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ initializer = cp_parser_braced_list (parser, &non_constant_p);
+ CONSTRUCTOR_IS_DIRECT_INIT (initializer) = 1;
+ flags = 0;
+ }
+ else
+ {
+ /* Consume the `='. */
+ cp_parser_require (parser, CPP_EQ, RT_EQ);
+ initializer = cp_parser_initializer_clause (parser, &non_constant_p);
+ }
+ if (BRACE_ENCLOSED_INITIALIZER_P (initializer))
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+
+ /* Process the initializer. */
+ cp_finish_decl (decl,
+ initializer, !non_constant_p,
+ asm_specification,
+ flags);
+
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+
+ return convert_from_reference (decl);
+ }
+ }
+ /* If we didn't even get past the declarator successfully, we are
+ definitely not looking at a declaration. */
+ else
+ cp_parser_abort_tentative_parse (parser);
+
+ /* Otherwise, we are looking at an expression. */
+ return cp_parser_expression (parser, /*cast_p=*/false, NULL);
+}
+
+/* Parses a for-statement or range-for-statement until the closing ')',
+ not included. */
+
+static tree
+cp_parser_for (cp_parser *parser, bool ivdep)
+{
+ tree init, scope, decl;
+ bool is_range_for;
+
+ /* Begin the for-statement. */
+ scope = begin_for_scope (&init);
+
+ /* Parse the initialization. */
+ is_range_for = cp_parser_for_init_statement (parser, &decl);
+
+ if (is_range_for)
+ return cp_parser_range_for (parser, scope, init, decl, ivdep);
+ else
+ return cp_parser_c_for (parser, scope, init, ivdep);
+}
+
+static tree
+cp_parser_c_for (cp_parser *parser, tree scope, tree init, bool ivdep)
+{
+ /* Normal for loop */
+ tree condition = NULL_TREE;
+ tree expression = NULL_TREE;
+ tree stmt;
+
+ stmt = begin_for_stmt (scope, init);
+ /* The for-init-statement has already been parsed in
+ cp_parser_for_init_statement, so no work is needed here. */
+ finish_for_init_stmt (stmt);
+
+ /* If there's a condition, process it. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ condition = cp_parser_condition (parser);
+ else if (ivdep)
+ {
+ cp_parser_error (parser, "missing loop condition in loop with "
+ "%<GCC ivdep%> pragma");
+ condition = error_mark_node;
+ }
+ finish_for_cond (condition, stmt, ivdep);
+ /* Look for the `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+ /* If there's an expression, process it. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
+ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ finish_for_expr (expression, stmt);
+
+ return stmt;
+}
+
+/* Tries to parse a range-based for-statement:
+
+ range-based-for:
+ decl-specifier-seq declarator : expression
+
+ The decl-specifier-seq declarator and the `:' are already parsed by
+ cp_parser_for_init_statement. If processing_template_decl it returns a
+ newly created RANGE_FOR_STMT; if not, it is converted to a
+ regular FOR_STMT. */
+
+static tree
+cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl,
+ bool ivdep)
+{
+ tree stmt, range_expr;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ bool expr_non_constant_p;
+ range_expr = cp_parser_braced_list (parser, &expr_non_constant_p);
+ }
+ else
+ range_expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+
+ /* If in template, STMT is converted to a normal for-statement
+ at instantiation. If not, it is done just ahead. */
+ if (processing_template_decl)
+ {
+ if (check_for_bare_parameter_packs (range_expr))
+ range_expr = error_mark_node;
+ stmt = begin_range_for_stmt (scope, init);
+ if (ivdep)
+ RANGE_FOR_IVDEP (stmt) = 1;
+ finish_range_for_decl (stmt, range_decl, range_expr);
+ if (!type_dependent_expression_p (range_expr)
+ /* do_auto_deduction doesn't mess with template init-lists. */
+ && !BRACE_ENCLOSED_INITIALIZER_P (range_expr))
+ do_range_for_auto_deduction (range_decl, range_expr);
+ }
+ else
+ {
+ stmt = begin_for_stmt (scope, init);
+ stmt = cp_convert_range_for (stmt, range_decl, range_expr, ivdep);
+ }
+ return stmt;
+}
+
+/* Subroutine of cp_convert_range_for: given the initializer expression,
+ builds up the range temporary. */
+
+static tree
+build_range_temp (tree range_expr)
+{
+ tree range_type, range_temp;
+
+ /* Find out the type deduced by the declaration
+ `auto &&__range = range_expr'. */
+ range_type = cp_build_reference_type (make_auto (), true);
+ range_type = do_auto_deduction (range_type, range_expr,
+ type_uses_auto (range_type));
+
+ /* Create the __range variable. */
+ range_temp = build_decl (input_location, VAR_DECL,
+ get_identifier ("__for_range"), range_type);
+ TREE_USED (range_temp) = 1;
+ DECL_ARTIFICIAL (range_temp) = 1;
+
+ return range_temp;
+}
+
+/* Used by cp_parser_range_for in template context: we aren't going to
+ do a full conversion yet, but we still need to resolve auto in the
+ type of the for-range-declaration if present. This is basically
+ a shortcut version of cp_convert_range_for. */
+
+static void
+do_range_for_auto_deduction (tree decl, tree range_expr)
+{
+ tree auto_node = type_uses_auto (TREE_TYPE (decl));
+ if (auto_node)
+ {
+ tree begin_dummy, end_dummy, range_temp, iter_type, iter_decl;
+ range_temp = convert_from_reference (build_range_temp (range_expr));
+ iter_type = (cp_parser_perform_range_for_lookup
+ (range_temp, &begin_dummy, &end_dummy));
+ if (iter_type)
+ {
+ iter_decl = build_decl (input_location, VAR_DECL, NULL_TREE,
+ iter_type);
+ iter_decl = build_x_indirect_ref (input_location, iter_decl, RO_NULL,
+ tf_warning_or_error);
+ TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl),
+ iter_decl, auto_node);
+ }
+ }
+}
+
+/* Converts a range-based for-statement into a normal
+ for-statement, as per the definition.
+
+ for (RANGE_DECL : RANGE_EXPR)
+ BLOCK
+
+ should be equivalent to:
+
+ {
+ auto &&__range = RANGE_EXPR;
+ for (auto __begin = BEGIN_EXPR, end = END_EXPR;
+ __begin != __end;
+ ++__begin)
+ {
+ RANGE_DECL = *__begin;
+ BLOCK
+ }
+ }
+
+ If RANGE_EXPR is an array:
+ BEGIN_EXPR = __range
+ END_EXPR = __range + ARRAY_SIZE(__range)
+ Else if RANGE_EXPR has a member 'begin' or 'end':
+ BEGIN_EXPR = __range.begin()
+ END_EXPR = __range.end()
+ Else:
+ BEGIN_EXPR = begin(__range)
+ END_EXPR = end(__range);
+
+ If __range has a member 'begin' but not 'end', or vice versa, we must
+ still use the second alternative (it will surely fail, however).
+ When calling begin()/end() in the third alternative we must use
+ argument dependent lookup, but always considering 'std' as an associated
+ namespace. */
+
+tree
+cp_convert_range_for (tree statement, tree range_decl, tree range_expr,
+ bool ivdep)
+{
+ tree begin, end;
+ tree iter_type, begin_expr, end_expr;
+ tree condition, expression;
+
+ if (range_decl == error_mark_node || range_expr == error_mark_node)
+ /* If an error happened previously do nothing or else a lot of
+ unhelpful errors would be issued. */
+ begin_expr = end_expr = iter_type = error_mark_node;
+ else
+ {
+ tree range_temp;
+
+ if (TREE_CODE (range_expr) == VAR_DECL
+ && array_of_runtime_bound_p (TREE_TYPE (range_expr)))
+ /* Can't bind a reference to an array of runtime bound. */
+ range_temp = range_expr;
+ else
+ {
+ range_temp = build_range_temp (range_expr);
+ pushdecl (range_temp);
+ cp_finish_decl (range_temp, range_expr,
+ /*is_constant_init*/false, NULL_TREE,
+ LOOKUP_ONLYCONVERTING);
+ range_temp = convert_from_reference (range_temp);
+ }
+ iter_type = cp_parser_perform_range_for_lookup (range_temp,
+ &begin_expr, &end_expr);
+ }
+
+ /* The new for initialization statement. */
+ begin = build_decl (input_location, VAR_DECL,
+ get_identifier ("__for_begin"), iter_type);
+ TREE_USED (begin) = 1;
+ DECL_ARTIFICIAL (begin) = 1;
+ pushdecl (begin);
+ cp_finish_decl (begin, begin_expr,
+ /*is_constant_init*/false, NULL_TREE,
+ LOOKUP_ONLYCONVERTING);
+
+ end = build_decl (input_location, VAR_DECL,
+ get_identifier ("__for_end"), iter_type);
+ TREE_USED (end) = 1;
+ DECL_ARTIFICIAL (end) = 1;
+ pushdecl (end);
+ cp_finish_decl (end, end_expr,
+ /*is_constant_init*/false, NULL_TREE,
+ LOOKUP_ONLYCONVERTING);
+
+ finish_for_init_stmt (statement);
+
+ /* The new for condition. */
+ condition = build_x_binary_op (input_location, NE_EXPR,
+ begin, ERROR_MARK,
+ end, ERROR_MARK,
+ NULL, tf_warning_or_error);
+ finish_for_cond (condition, statement, ivdep);
+
+ /* The new increment expression. */
+ expression = finish_unary_op_expr (input_location,
+ PREINCREMENT_EXPR, begin,
+ tf_warning_or_error);
+ finish_for_expr (expression, statement);
+
+ /* The declaration is initialized with *__begin inside the loop body. */
+ cp_finish_decl (range_decl,
+ build_x_indirect_ref (input_location, begin, RO_NULL,
+ tf_warning_or_error),
+ /*is_constant_init*/false, NULL_TREE,
+ LOOKUP_ONLYCONVERTING);
+
+ return statement;
+}
+
+/* Solves BEGIN_EXPR and END_EXPR as described in cp_convert_range_for.
+ We need to solve both at the same time because the method used
+ depends on the existence of members begin or end.
+ Returns the type deduced for the iterator expression. */
+
+static tree
+cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end)
+{
+ if (error_operand_p (range))
+ {
+ *begin = *end = error_mark_node;
+ return error_mark_node;
+ }
+
+ if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (range))))
+ {
+ error ("range-based %<for%> expression of type %qT "
+ "has incomplete type", TREE_TYPE (range));
+ *begin = *end = error_mark_node;
+ return error_mark_node;
+ }
+ if (TREE_CODE (TREE_TYPE (range)) == ARRAY_TYPE)
+ {
+ /* If RANGE is an array, we will use pointer arithmetic. */
+ *begin = range;
+ *end = build_binary_op (input_location, PLUS_EXPR,
+ range,
+ array_type_nelts_top (TREE_TYPE (range)),
+ 0);
+ return build_pointer_type (TREE_TYPE (TREE_TYPE (range)));
+ }
+ else
+ {
+ /* If it is not an array, we must do a bit of magic. */
+ tree id_begin, id_end;
+ tree member_begin, member_end;
+
+ *begin = *end = error_mark_node;
+
+ id_begin = get_identifier ("begin");
+ id_end = get_identifier ("end");
+ member_begin = lookup_member (TREE_TYPE (range), id_begin,
+ /*protect=*/2, /*want_type=*/false,
+ tf_warning_or_error);
+ member_end = lookup_member (TREE_TYPE (range), id_end,
+ /*protect=*/2, /*want_type=*/false,
+ tf_warning_or_error);
+
+ if (member_begin != NULL_TREE || member_end != NULL_TREE)
+ {
+ /* Use the member functions. */
+ if (member_begin != NULL_TREE)
+ *begin = cp_parser_range_for_member_function (range, id_begin);
+ else
+ error ("range-based %<for%> expression of type %qT has an "
+ "%<end%> member but not a %<begin%>", TREE_TYPE (range));
+
+ if (member_end != NULL_TREE)
+ *end = cp_parser_range_for_member_function (range, id_end);
+ else
+ error ("range-based %<for%> expression of type %qT has a "
+ "%<begin%> member but not an %<end%>", TREE_TYPE (range));
+ }
+ else
+ {
+ /* Use global functions with ADL. */
+ vec<tree, va_gc> *vec;
+ vec = make_tree_vector ();
+
+ vec_safe_push (vec, range);
+
+ member_begin = perform_koenig_lookup (id_begin, vec,
+ tf_warning_or_error);
+ *begin = finish_call_expr (member_begin, &vec, false, true,
+ tf_warning_or_error);
+ member_end = perform_koenig_lookup (id_end, vec,
+ tf_warning_or_error);
+ *end = finish_call_expr (member_end, &vec, false, true,
+ tf_warning_or_error);
+
+ release_tree_vector (vec);
+ }
+
+ /* Last common checks. */
+ if (*begin == error_mark_node || *end == error_mark_node)
+ {
+ /* If one of the expressions is an error do no more checks. */
+ *begin = *end = error_mark_node;
+ return error_mark_node;
+ }
+ else if (type_dependent_expression_p (*begin)
+ || type_dependent_expression_p (*end))
+ /* Can happen, when, eg, in a template context, Koenig lookup
+ can't resolve begin/end (c++/58503). */
+ return NULL_TREE;
+ else
+ {
+ tree iter_type = cv_unqualified (TREE_TYPE (*begin));
+ /* The unqualified type of the __begin and __end temporaries should
+ be the same, as required by the multiple auto declaration. */
+ if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE (*end))))
+ error ("inconsistent begin/end types in range-based %<for%> "
+ "statement: %qT and %qT",
+ TREE_TYPE (*begin), TREE_TYPE (*end));
+ return iter_type;
+ }
+ }
+}
+
+/* Helper function for cp_parser_perform_range_for_lookup.
+ Builds a tree for RANGE.IDENTIFIER(). */
+
+static tree
+cp_parser_range_for_member_function (tree range, tree identifier)
+{
+ tree member, res;
+ vec<tree, va_gc> *vec;
+
+ member = finish_class_member_access_expr (range, identifier,
+ false, tf_warning_or_error);
+ if (member == error_mark_node)
+ return error_mark_node;
+
+ vec = make_tree_vector ();
+ res = finish_call_expr (member, &vec,
+ /*disallow_virtual=*/false,
+ /*koenig_p=*/false,
+ tf_warning_or_error);
+ release_tree_vector (vec);
+ return res;
+}
+
+/* Parse an iteration-statement.
+
+ iteration-statement:
+ while ( condition ) statement
+ do statement while ( expression ) ;
+ for ( for-init-statement condition [opt] ; expression [opt] )
+ statement
+
+ Returns the new WHILE_STMT, DO_STMT, FOR_STMT or RANGE_FOR_STMT. */
+
+static tree
+cp_parser_iteration_statement (cp_parser* parser, bool ivdep)
+{
+ cp_token *token;
+ enum rid keyword;
+ tree statement;
+ unsigned char in_statement;
+
+ /* Peek at the next token. */
+ token = cp_parser_require (parser, CPP_KEYWORD, RT_INTERATION);
+ if (!token)
+ return error_mark_node;
+
+ /* Remember whether or not we are already within an iteration
+ statement. */
+ in_statement = parser->in_statement;
+
+ /* See what kind of keyword it is. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ case RID_WHILE:
+ {
+ tree condition;
+
+ /* Begin the while-statement. */
+ statement = begin_while_stmt ();
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ /* Parse the condition. */
+ condition = cp_parser_condition (parser);
+ finish_while_stmt_cond (condition, statement, ivdep);
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ /* Parse the dependent statement. */
+ parser->in_statement = IN_ITERATION_STMT;
+ cp_parser_already_scoped_statement (parser);
+ parser->in_statement = in_statement;
+ /* We're done with the while-statement. */
+ finish_while_stmt (statement);
+ }
+ break;
+
+ case RID_DO:
+ {
+ tree expression;
+
+ /* Begin the do-statement. */
+ statement = begin_do_stmt ();
+ /* Parse the body of the do-statement. */
+ parser->in_statement = IN_ITERATION_STMT;
+ cp_parser_implicitly_scoped_statement (parser, NULL);
+ parser->in_statement = in_statement;
+ finish_do_body (statement);
+ /* Look for the `while' keyword. */
+ cp_parser_require_keyword (parser, RID_WHILE, RT_WHILE);
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ /* Parse the expression. */
+ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ /* We're done with the do-statement. */
+ finish_do_stmt (expression, statement, ivdep);
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ /* Look for the `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ }
+ break;
+
+ case RID_FOR:
+ {
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+ statement = cp_parser_for (parser, ivdep);
+
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ /* Parse the body of the for-statement. */
+ parser->in_statement = IN_ITERATION_STMT;
+ cp_parser_already_scoped_statement (parser);
+ parser->in_statement = in_statement;
+
+ /* We're done with the for-statement. */
+ finish_for_stmt (statement);
+ }
+ break;
+
+ default:
+ cp_parser_error (parser, "expected iteration-statement");
+ statement = error_mark_node;
+ break;
+ }
+
+ return statement;
+}
+
+/* Parse a for-init-statement or the declarator of a range-based-for.
+ Returns true if a range-based-for declaration is seen.
+
+ for-init-statement:
+ expression-statement
+ simple-declaration */
+
+static bool
+cp_parser_for_init_statement (cp_parser* parser, tree *decl)
+{
+ /* If the next token is a `;', then we have an empty
+ expression-statement. Grammatically, this is also a
+ simple-declaration, but an invalid one, because it does not
+ declare anything. Therefore, if we did not handle this case
+ specially, we would issue an error message about an invalid
+ declaration. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ bool is_range_for = false;
+ bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+
+ parser->colon_corrects_to_scope_p = false;
+
+ /* We're going to speculatively look for a declaration, falling back
+ to an expression, if necessary. */
+ cp_parser_parse_tentatively (parser);
+ /* Parse the declaration. */
+ cp_parser_simple_declaration (parser,
+ /*function_definition_allowed_p=*/false,
+ decl);
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ /* It is a range-for, consume the ':' */
+ cp_lexer_consume_token (parser->lexer);
+ is_range_for = true;
+ if (cxx_dialect < cxx11)
+ {
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "range-based %<for%> loops are not allowed "
+ "in C++98 mode");
+ *decl = error_mark_node;
+ }
+ }
+ else
+ /* The ';' is not consumed yet because we told
+ cp_parser_simple_declaration not to. */
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+ if (cp_parser_parse_definitely (parser))
+ return is_range_for;
+ /* If the tentative parse failed, then we shall need to look for an
+ expression-statement. */
+ }
+ /* If we are here, it is an expression-statement. */
+ cp_parser_expression_statement (parser, NULL_TREE);
+ return false;
+}
+
+/* Parse a jump-statement.
+
+ jump-statement:
+ break ;
+ continue ;
+ return expression [opt] ;
+ return braced-init-list ;
+ goto identifier ;
+
+ GNU extension:
+
+ jump-statement:
+ goto * expression ;
+
+ Returns the new BREAK_STMT, CONTINUE_STMT, RETURN_EXPR, or GOTO_EXPR. */
+
+static tree
+cp_parser_jump_statement (cp_parser* parser)
+{
+ tree statement = error_mark_node;
+ cp_token *token;
+ enum rid keyword;
+ unsigned char in_statement;
+
+ /* Peek at the next token. */
+ token = cp_parser_require (parser, CPP_KEYWORD, RT_JUMP);
+ if (!token)
+ return error_mark_node;
+
+ /* See what kind of keyword it is. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ case RID_BREAK:
+ in_statement = parser->in_statement & ~IN_IF_STMT;
+ switch (in_statement)
+ {
+ case 0:
+ error_at (token->location, "break statement not within loop or switch");
+ break;
+ default:
+ gcc_assert ((in_statement & IN_SWITCH_STMT)
+ || in_statement == IN_ITERATION_STMT);
+ statement = finish_break_stmt ();
+ if (in_statement == IN_ITERATION_STMT)
+ break_maybe_infinite_loop ();
+ break;
+ case IN_OMP_BLOCK:
+ error_at (token->location, "invalid exit from OpenMP structured block");
+ break;
+ case IN_OMP_FOR:
+ error_at (token->location, "break statement used with OpenMP for loop");
+ break;
+ case IN_CILK_SIMD_FOR:
+ error_at (token->location, "break statement used with Cilk Plus for loop");
+ break;
+ }
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ break;
+
+ case RID_CONTINUE:
+ switch (parser->in_statement & ~(IN_SWITCH_STMT | IN_IF_STMT))
+ {
+ case 0:
+ error_at (token->location, "continue statement not within a loop");
+ break;
+ case IN_CILK_SIMD_FOR:
+ error_at (token->location,
+ "continue statement within %<#pragma simd%> loop body");
+ /* Fall through. */
+ case IN_ITERATION_STMT:
+ case IN_OMP_FOR:
+ statement = finish_continue_stmt ();
+ break;
+ case IN_OMP_BLOCK:
+ error_at (token->location, "invalid exit from OpenMP structured block");
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ break;
+
+ case RID_RETURN:
+ {
+ tree expr;
+ bool expr_non_constant_p;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ cp_lexer_set_source_position (parser->lexer);
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ expr = cp_parser_braced_list (parser, &expr_non_constant_p);
+ }
+ else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ else
+ /* If the next token is a `;', then there is no
+ expression. */
+ expr = NULL_TREE;
+ /* Build the return-statement. */
+ statement = finish_return_stmt (expr);
+ /* Look for the final `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ }
+ break;
+
+ case RID_GOTO:
+ /* Create the goto-statement. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_MULT))
+ {
+ /* Issue a warning about this use of a GNU extension. */
+ pedwarn (token->location, OPT_Wpedantic, "ISO C++ forbids computed gotos");
+ /* Consume the '*' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the dependent expression. */
+ finish_goto_stmt (cp_parser_expression (parser, /*cast_p=*/false, NULL));
+ }
+ else
+ finish_goto_stmt (cp_parser_identifier (parser));
+ /* Look for the final `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ break;
+
+ default:
+ cp_parser_error (parser, "expected jump-statement");
+ break;
+ }
+
+ return statement;
+}
+
+/* Parse a declaration-statement.
+
+ declaration-statement:
+ block-declaration */
+
+static void
+cp_parser_declaration_statement (cp_parser* parser)
+{
+ void *p;
+
+ /* Get the high-water mark for the DECLARATOR_OBSTACK. */
+ p = obstack_alloc (&declarator_obstack, 0);
+
+ /* Parse the block-declaration. */
+ cp_parser_block_declaration (parser, /*statement_p=*/true);
+
+ /* Free any declarators allocated. */
+ obstack_free (&declarator_obstack, p);
+}
+
+/* Some dependent statements (like `if (cond) statement'), are
+ implicitly in their own scope. In other words, if the statement is
+ a single statement (as opposed to a compound-statement), it is
+ none-the-less treated as if it were enclosed in braces. Any
+ declarations appearing in the dependent statement are out of scope
+ after control passes that point. This function parses a statement,
+ but ensures that is in its own scope, even if it is not a
+ compound-statement.
+
+ If IF_P is not NULL, *IF_P is set to indicate whether the statement
+ is a (possibly labeled) if statement which is not enclosed in
+ braces and has an else clause. This is used to implement
+ -Wparentheses.
+
+ Returns the new statement. */
+
+static tree
+cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p)
+{
+ tree statement;
+
+ if (if_p != NULL)
+ *if_p = false;
+
+ /* Mark if () ; with a special NOP_EXPR. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ {
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+ cp_lexer_consume_token (parser->lexer);
+ statement = add_stmt (build_empty_stmt (loc));
+ }
+ /* if a compound is opened, we simply parse the statement directly. */
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ statement = cp_parser_compound_statement (parser, NULL, false, false);
+ /* If the token is not a `{', then we must take special action. */
+ else
+ {
+ /* Create a compound-statement. */
+ statement = begin_compound_stmt (0);
+ /* Parse the dependent-statement. */
+ cp_parser_statement (parser, NULL_TREE, false, if_p);
+ /* Finish the dummy compound-statement. */
+ finish_compound_stmt (statement);
+ }
+
+ /* Return the statement. */
+ return statement;
+}
+
+/* For some dependent statements (like `while (cond) statement'), we
+ have already created a scope. Therefore, even if the dependent
+ statement is a compound-statement, we do not want to create another
+ scope. */
+
+static void
+cp_parser_already_scoped_statement (cp_parser* parser)
+{
+ /* If the token is a `{', then we must take special action. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
+ cp_parser_statement (parser, NULL_TREE, false, NULL);
+ else
+ {
+ /* Avoid calling cp_parser_compound_statement, so that we
+ don't create a new scope. Do everything else by hand. */
+ cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
+ /* If the next keyword is `__label__' we have a label declaration. */
+ while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
+ cp_parser_label_declaration (parser);
+ /* Parse an (optional) statement-seq. */
+ cp_parser_statement_seq_opt (parser, NULL_TREE);
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ }
+}
+
+/* Declarations [gram.dcl.dcl] */
+
+/* Parse an optional declaration-sequence.
+
+ declaration-seq:
+ declaration
+ declaration-seq declaration */
+
+static void
+cp_parser_declaration_seq_opt (cp_parser* parser)
+{
+ while (true)
+ {
+ cp_token *token;
+
+ token = cp_lexer_peek_token (parser->lexer);
+
+ if (token->type == CPP_CLOSE_BRACE
+ || token->type == CPP_EOF
+ || token->type == CPP_PRAGMA_EOL)
+ break;
+
+ if (token->type == CPP_SEMICOLON)
+ {
+ /* A declaration consisting of a single semicolon is
+ invalid. Allow it unless we're being pedantic. */
+ cp_lexer_consume_token (parser->lexer);
+ if (!in_system_header_at (input_location))
+ pedwarn (input_location, OPT_Wpedantic, "extra %<;%>");
+ continue;
+ }
+
+ /* If we're entering or exiting a region that's implicitly
+ extern "C", modify the lang context appropriately. */
+ if (!parser->implicit_extern_c && token->implicit_extern_c)
+ {
+ push_lang_context (lang_name_c);
+ parser->implicit_extern_c = true;
+ }
+ else if (parser->implicit_extern_c && !token->implicit_extern_c)
+ {
+ pop_lang_context ();
+ parser->implicit_extern_c = false;
+ }
+
+ if (token->type == CPP_PRAGMA)
+ {
+ /* A top-level declaration can consist solely of a #pragma.
+ A nested declaration cannot, so this is done here and not
+ in cp_parser_declaration. (A #pragma at block scope is
+ handled in cp_parser_statement.) */
+ cp_parser_pragma (parser, pragma_external);
+ continue;
+ }
+
+ /* Parse the declaration itself. */
+ cp_parser_declaration (parser);
+ }
+}
+
+/* Parse a declaration.
+
+ declaration:
+ block-declaration
+ function-definition
+ template-declaration
+ explicit-instantiation
+ explicit-specialization
+ linkage-specification
+ namespace-definition
+
+ GNU extension:
+
+ declaration:
+ __extension__ declaration */
+
+static void
+cp_parser_declaration (cp_parser* parser)
+{
+ cp_token token1;
+ cp_token token2;
+ int saved_pedantic;
+ void *p;
+ tree attributes = NULL_TREE;
+
+ /* Check for the `__extension__' keyword. */
+ if (cp_parser_extension_opt (parser, &saved_pedantic))
+ {
+ /* Parse the qualified declaration. */
+ cp_parser_declaration (parser);
+ /* Restore the PEDANTIC flag. */
+ pedantic = saved_pedantic;
+
+ return;
+ }
+
+ /* Try to figure out what kind of declaration is present. */
+ token1 = *cp_lexer_peek_token (parser->lexer);
+
+ if (token1.type != CPP_EOF)
+ token2 = *cp_lexer_peek_nth_token (parser->lexer, 2);
+ else
+ {
+ token2.type = CPP_EOF;
+ token2.keyword = RID_MAX;
+ }
+
+ /* Get the high-water mark for the DECLARATOR_OBSTACK. */
+ p = obstack_alloc (&declarator_obstack, 0);
+
+ /* If the next token is `extern' and the following token is a string
+ literal, then we have a linkage specification. */
+ if (token1.keyword == RID_EXTERN
+ && cp_parser_is_pure_string_literal (&token2))
+ cp_parser_linkage_specification (parser);
+ /* If the next token is `template', then we have either a template
+ declaration, an explicit instantiation, or an explicit
+ specialization. */
+ else if (token1.keyword == RID_TEMPLATE)
+ {
+ /* `template <>' indicates a template specialization. */
+ if (token2.type == CPP_LESS
+ && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_GREATER)
+ cp_parser_explicit_specialization (parser);
+ /* `template <' indicates a template declaration. */
+ else if (token2.type == CPP_LESS)
+ cp_parser_template_declaration (parser, /*member_p=*/false);
+ /* Anything else must be an explicit instantiation. */
+ else
+ cp_parser_explicit_instantiation (parser);
+ }
+ /* If the next token is `export', then we have a template
+ declaration. */
+ else if (token1.keyword == RID_EXPORT)
+ cp_parser_template_declaration (parser, /*member_p=*/false);
+ /* If the next token is `extern', 'static' or 'inline' and the one
+ after that is `template', we have a GNU extended explicit
+ instantiation directive. */
+ else if (cp_parser_allow_gnu_extensions_p (parser)
+ && (token1.keyword == RID_EXTERN
+ || token1.keyword == RID_STATIC
+ || token1.keyword == RID_INLINE)
+ && token2.keyword == RID_TEMPLATE)
+ cp_parser_explicit_instantiation (parser);
+ /* If the next token is `namespace', check for a named or unnamed
+ namespace definition. */
+ else if (token1.keyword == RID_NAMESPACE
+ && (/* A named namespace definition. */
+ (token2.type == CPP_NAME
+ && (cp_lexer_peek_nth_token (parser->lexer, 3)->type
+ != CPP_EQ))
+ /* An unnamed namespace definition. */
+ || token2.type == CPP_OPEN_BRACE
+ || token2.keyword == RID_ATTRIBUTE))
+ cp_parser_namespace_definition (parser);
+ /* An inline (associated) namespace definition. */
+ else if (token1.keyword == RID_INLINE
+ && token2.keyword == RID_NAMESPACE)
+ cp_parser_namespace_definition (parser);
+ /* Objective-C++ declaration/definition. */
+ else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1.keyword))
+ cp_parser_objc_declaration (parser, NULL_TREE);
+ else if (c_dialect_objc ()
+ && token1.keyword == RID_ATTRIBUTE
+ && cp_parser_objc_valid_prefix_attributes (parser, &attributes))
+ cp_parser_objc_declaration (parser, attributes);
+ /* We must have either a block declaration or a function
+ definition. */
+ else
+ /* Try to parse a block-declaration, or a function-definition. */
+ cp_parser_block_declaration (parser, /*statement_p=*/false);
+
+ /* Free any declarators allocated. */
+ obstack_free (&declarator_obstack, p);
+}
+
+/* Parse a block-declaration.
+
+ block-declaration:
+ simple-declaration
+ asm-definition
+ namespace-alias-definition
+ using-declaration
+ using-directive
+
+ GNU Extension:
+
+ block-declaration:
+ __extension__ block-declaration
+
+ C++0x Extension:
+
+ block-declaration:
+ static_assert-declaration
+
+ If STATEMENT_P is TRUE, then this block-declaration is occurring as
+ part of a declaration-statement. */
+
+static void
+cp_parser_block_declaration (cp_parser *parser,
+ bool statement_p)
+{
+ cp_token *token1;
+ int saved_pedantic;
+
+ /* Check for the `__extension__' keyword. */
+ if (cp_parser_extension_opt (parser, &saved_pedantic))
+ {
+ /* Parse the qualified declaration. */
+ cp_parser_block_declaration (parser, statement_p);
+ /* Restore the PEDANTIC flag. */
+ pedantic = saved_pedantic;
+
+ return;
+ }
+
+ /* Peek at the next token to figure out which kind of declaration is
+ present. */
+ token1 = cp_lexer_peek_token (parser->lexer);
+
+ /* If the next keyword is `asm', we have an asm-definition. */
+ if (token1->keyword == RID_ASM)
+ {
+ if (statement_p)
+ cp_parser_commit_to_tentative_parse (parser);
+ cp_parser_asm_definition (parser);
+ }
+ /* If the next keyword is `namespace', we have a
+ namespace-alias-definition. */
+ else if (token1->keyword == RID_NAMESPACE)
+ cp_parser_namespace_alias_definition (parser);
+ /* If the next keyword is `using', we have a
+ using-declaration, a using-directive, or an alias-declaration. */
+ else if (token1->keyword == RID_USING)
+ {
+ cp_token *token2;
+
+ if (statement_p)
+ cp_parser_commit_to_tentative_parse (parser);
+ /* If the token after `using' is `namespace', then we have a
+ using-directive. */
+ token2 = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (token2->keyword == RID_NAMESPACE)
+ cp_parser_using_directive (parser);
+ /* If the second token after 'using' is '=', then we have an
+ alias-declaration. */
+ else if (cxx_dialect >= cxx11
+ && token2->type == CPP_NAME
+ && ((cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_EQ)
+ || (cp_nth_tokens_can_be_attribute_p (parser, 3))))
+ cp_parser_alias_declaration (parser);
+ /* Otherwise, it's a using-declaration. */
+ else
+ cp_parser_using_declaration (parser,
+ /*access_declaration_p=*/false);
+ }
+ /* If the next keyword is `__label__' we have a misplaced label
+ declaration. */
+ else if (token1->keyword == RID_LABEL)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ error_at (token1->location, "%<__label__%> not at the beginning of a block");
+ cp_parser_skip_to_end_of_statement (parser);
+ /* If the next token is now a `;', consume it. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* If the next token is `static_assert' we have a static assertion. */
+ else if (token1->keyword == RID_STATIC_ASSERT)
+ cp_parser_static_assert (parser, /*member_p=*/false);
+ /* Anything else must be a simple-declaration. */
+ else
+ cp_parser_simple_declaration (parser, !statement_p,
+ /*maybe_range_for_decl*/NULL);
+}
+
+/* Parse a simple-declaration.
+
+ simple-declaration:
+ decl-specifier-seq [opt] init-declarator-list [opt] ;
+
+ init-declarator-list:
+ init-declarator
+ init-declarator-list , init-declarator
+
+ If FUNCTION_DEFINITION_ALLOWED_P is TRUE, then we also recognize a
+ function-definition as a simple-declaration.
+
+ If MAYBE_RANGE_FOR_DECL is not NULL, the pointed tree will be set to the
+ parsed declaration if it is an uninitialized single declarator not followed
+ by a `;', or to error_mark_node otherwise. Either way, the trailing `;',
+ if present, will not be consumed. */
+
+static void
+cp_parser_simple_declaration (cp_parser* parser,
+ bool function_definition_allowed_p,
+ tree *maybe_range_for_decl)
+{
+ cp_decl_specifier_seq decl_specifiers;
+ int declares_class_or_enum;
+ bool saw_declarator;
+
+ if (maybe_range_for_decl)
+ *maybe_range_for_decl = NULL_TREE;
+
+ /* Defer access checks until we know what is being declared; the
+ checks for names appearing in the decl-specifier-seq should be
+ done as if we were in the scope of the thing being declared. */
+ push_deferring_access_checks (dk_deferred);
+
+ /* Parse the decl-specifier-seq. We have to keep track of whether
+ or not the decl-specifier-seq declares a named class or
+ enumeration type, since that is the only case in which the
+ init-declarator-list is allowed to be empty.
+
+ [dcl.dcl]
+
+ In a simple-declaration, the optional init-declarator-list can be
+ omitted only when declaring a class or enumeration, that is when
+ the decl-specifier-seq contains either a class-specifier, an
+ elaborated-type-specifier, or an enum-specifier. */
+ cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_OPTIONAL,
+ &decl_specifiers,
+ &declares_class_or_enum);
+ /* We no longer need to defer access checks. */
+ stop_deferring_access_checks ();
+
+ /* In a block scope, a valid declaration must always have a
+ decl-specifier-seq. By not trying to parse declarators, we can
+ resolve the declaration/expression ambiguity more quickly. */
+ if (!function_definition_allowed_p
+ && !decl_specifiers.any_specifiers_p)
+ {
+ cp_parser_error (parser, "expected declaration");
+ goto done;
+ }
+
+ /* If the next two tokens are both identifiers, the code is
+ erroneous. The usual cause of this situation is code like:
+
+ T t;
+
+ where "T" should name a type -- but does not. */
+ if (!decl_specifiers.any_type_specifiers_p
+ && cp_parser_parse_and_diagnose_invalid_type_name (parser))
+ {
+ /* If parsing tentatively, we should commit; we really are
+ looking at a declaration. */
+ cp_parser_commit_to_tentative_parse (parser);
+ /* Give up. */
+ goto done;
+ }
+
+ /* If we have seen at least one decl-specifier, and the next token
+ is not a parenthesis, then we must be looking at a declaration.
+ (After "int (" we might be looking at a functional cast.) */
+ if (decl_specifiers.any_specifiers_p
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)
+ && !cp_parser_error_occurred (parser))
+ cp_parser_commit_to_tentative_parse (parser);
+
+ /* Keep going until we hit the `;' at the end of the simple
+ declaration. */
+ saw_declarator = false;
+ while (cp_lexer_next_token_is_not (parser->lexer,
+ CPP_SEMICOLON))
+ {
+ cp_token *token;
+ bool function_definition_p;
+ tree decl;
+
+ if (saw_declarator)
+ {
+ /* If we are processing next declarator, coma is expected */
+ token = cp_lexer_peek_token (parser->lexer);
+ gcc_assert (token->type == CPP_COMMA);
+ cp_lexer_consume_token (parser->lexer);
+ if (maybe_range_for_decl)
+ *maybe_range_for_decl = error_mark_node;
+ }
+ else
+ saw_declarator = true;
+
+ /* Parse the init-declarator. */
+ decl = cp_parser_init_declarator (parser, &decl_specifiers,
+ /*checks=*/NULL,
+ function_definition_allowed_p,
+ /*member_p=*/false,
+ declares_class_or_enum,
+ &function_definition_p,
+ maybe_range_for_decl);
+ /* If an error occurred while parsing tentatively, exit quickly.
+ (That usually happens when in the body of a function; each
+ statement is treated as a declaration-statement until proven
+ otherwise.) */
+ if (cp_parser_error_occurred (parser))
+ goto done;
+ /* Handle function definitions specially. */
+ if (function_definition_p)
+ {
+ /* If the next token is a `,', then we are probably
+ processing something like:
+
+ void f() {}, *p;
+
+ which is erroneous. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ error_at (token->location,
+ "mixing"
+ " declarations and function-definitions is forbidden");
+ }
+ /* Otherwise, we're done with the list of declarators. */
+ else
+ {
+ pop_deferring_access_checks ();
+ return;
+ }
+ }
+ if (maybe_range_for_decl && *maybe_range_for_decl == NULL_TREE)
+ *maybe_range_for_decl = decl;
+ /* The next token should be either a `,' or a `;'. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's a `,', there are more declarators to come. */
+ if (token->type == CPP_COMMA)
+ /* will be consumed next time around */;
+ /* If it's a `;', we are done. */
+ else if (token->type == CPP_SEMICOLON || maybe_range_for_decl)
+ break;
+ /* Anything else is an error. */
+ else
+ {
+ /* If we have already issued an error message we don't need
+ to issue another one. */
+ if (decl != error_mark_node
+ || cp_parser_uncommitted_to_tentative_parse_p (parser))
+ cp_parser_error (parser, "expected %<,%> or %<;%>");
+ /* Skip tokens until we reach the end of the statement. */
+ cp_parser_skip_to_end_of_statement (parser);
+ /* If the next token is now a `;', consume it. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ goto done;
+ }
+ /* After the first time around, a function-definition is not
+ allowed -- even if it was OK at first. For example:
+
+ int i, f() {}
+
+ is not valid. */
+ function_definition_allowed_p = false;
+ }
+
+ /* Issue an error message if no declarators are present, and the
+ decl-specifier-seq does not itself declare a class or
+ enumeration: [dcl.dcl]/3. */
+ if (!saw_declarator)
+ {
+ if (cp_parser_declares_only_class_p (parser))
+ {
+ if (!declares_class_or_enum
+ && decl_specifiers.type
+ && OVERLOAD_TYPE_P (decl_specifiers.type))
+ /* Ensure an error is issued anyway when finish_decltype_type,
+ called via cp_parser_decl_specifier_seq, returns a class or
+ an enumeration (c++/51786). */
+ decl_specifiers.type = NULL_TREE;
+ shadow_tag (&decl_specifiers);
+ }
+ /* Perform any deferred access checks. */
+ perform_deferred_access_checks (tf_warning_or_error);
+ }
+
+ /* Consume the `;'. */
+ if (!maybe_range_for_decl)
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+ done:
+ pop_deferring_access_checks ();
+}
+
+/* Parse a decl-specifier-seq.
+
+ decl-specifier-seq:
+ decl-specifier-seq [opt] decl-specifier
+ decl-specifier attribute-specifier-seq [opt] (C++11)
+
+ decl-specifier:
+ storage-class-specifier
+ type-specifier
+ function-specifier
+ friend
+ typedef
+
+ GNU Extension:
+
+ decl-specifier:
+ attributes
+
+ Set *DECL_SPECS to a representation of the decl-specifier-seq.
+
+ The parser flags FLAGS is used to control type-specifier parsing.
+
+ *DECLARES_CLASS_OR_ENUM is set to the bitwise or of the following
+ flags:
+
+ 1: one of the decl-specifiers is an elaborated-type-specifier
+ (i.e., a type declaration)
+ 2: one of the decl-specifiers is an enum-specifier or a
+ class-specifier (i.e., a type definition)
+
+ */
+
+static void
+cp_parser_decl_specifier_seq (cp_parser* parser,
+ cp_parser_flags flags,
+ cp_decl_specifier_seq *decl_specs,
+ int* declares_class_or_enum)
+{
+ bool constructor_possible_p = !parser->in_declarator_p;
+ bool found_decl_spec = false;
+ cp_token *start_token = NULL;
+ cp_decl_spec ds;
+
+ /* Clear DECL_SPECS. */
+ clear_decl_specs (decl_specs);
+
+ /* Assume no class or enumeration type is declared. */
+ *declares_class_or_enum = 0;
+
+ /* Keep reading specifiers until there are no more to read. */
+ while (true)
+ {
+ bool constructor_p;
+ cp_token *token;
+ ds = ds_last;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* Save the first token of the decl spec list for error
+ reporting. */
+ if (!start_token)
+ start_token = token;
+ /* Handle attributes. */
+ if (cp_next_tokens_can_be_attribute_p (parser))
+ {
+ /* Parse the attributes. */
+ tree attrs = cp_parser_attributes_opt (parser);
+
+ /* In a sequence of declaration specifiers, c++11 attributes
+ appertain to the type that precede them. In that case
+ [dcl.spec]/1 says:
+
+ The attribute-specifier-seq affects the type only for
+ the declaration it appears in, not other declarations
+ involving the same type.
+
+ But for now let's force the user to position the
+ attribute either at the beginning of the declaration or
+ after the declarator-id, which would clearly mean that it
+ applies to the declarator. */
+ if (cxx11_attribute_p (attrs))
+ {
+ if (!found_decl_spec)
+ /* The c++11 attribute is at the beginning of the
+ declaration. It appertains to the entity being
+ declared. */;
+ else
+ {
+ if (decl_specs->type && CLASS_TYPE_P (decl_specs->type))
+ {
+ /* This is an attribute following a
+ class-specifier. */
+ if (decl_specs->type_definition_p)
+ warn_misplaced_attr_for_class_type (token->location,
+ decl_specs->type);
+ attrs = NULL_TREE;
+ }
+ else
+ {
+ decl_specs->std_attributes
+ = chainon (decl_specs->std_attributes,
+ attrs);
+ if (decl_specs->locations[ds_std_attribute] == 0)
+ decl_specs->locations[ds_std_attribute] = token->location;
+ }
+ continue;
+ }
+ }
+
+ decl_specs->attributes
+ = chainon (decl_specs->attributes,
+ attrs);
+ if (decl_specs->locations[ds_attribute] == 0)
+ decl_specs->locations[ds_attribute] = token->location;
+ continue;
+ }
+ /* Assume we will find a decl-specifier keyword. */
+ found_decl_spec = true;
+ /* If the next token is an appropriate keyword, we can simply
+ add it to the list. */
+ switch (token->keyword)
+ {
+ /* decl-specifier:
+ friend
+ constexpr */
+ case RID_FRIEND:
+ if (!at_class_scope_p ())
+ {
+ error_at (token->location, "%<friend%> used outside of class");
+ cp_lexer_purge_token (parser->lexer);
+ }
+ else
+ {
+ ds = ds_friend;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+ break;
+
+ case RID_CONSTEXPR:
+ ds = ds_constexpr;
+ cp_lexer_consume_token (parser->lexer);
+ break;
+
+ /* function-specifier:
+ inline
+ virtual
+ explicit */
+ case RID_INLINE:
+ case RID_VIRTUAL:
+ case RID_EXPLICIT:
+ cp_parser_function_specifier_opt (parser, decl_specs);
+ break;
+
+ /* decl-specifier:
+ typedef */
+ case RID_TYPEDEF:
+ ds = ds_typedef;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* A constructor declarator cannot appear in a typedef. */
+ constructor_possible_p = false;
+ /* The "typedef" keyword can only occur in a declaration; we
+ may as well commit at this point. */
+ cp_parser_commit_to_tentative_parse (parser);
+
+ if (decl_specs->storage_class != sc_none)
+ decl_specs->conflicting_specifiers_p = true;
+ break;
+
+ /* storage-class-specifier:
+ auto
+ register
+ static
+ extern
+ mutable
+
+ GNU Extension:
+ thread */
+ case RID_AUTO:
+ if (cxx_dialect == cxx98)
+ {
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Complain about `auto' as a storage specifier, if
+ we're complaining about C++0x compatibility. */
+ warning_at (token->location, OPT_Wc__0x_compat, "%<auto%>"
+ " changes meaning in C++11; please remove it");
+
+ /* Set the storage class anyway. */
+ cp_parser_set_storage_class (parser, decl_specs, RID_AUTO,
+ token);
+ }
+ else
+ /* C++0x auto type-specifier. */
+ found_decl_spec = false;
+ break;
+
+ case RID_REGISTER:
+ case RID_STATIC:
+ case RID_EXTERN:
+ case RID_MUTABLE:
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_set_storage_class (parser, decl_specs, token->keyword,
+ token);
+ break;
+ case RID_THREAD:
+ /* Consume the token. */
+ ds = ds_thread;
+ cp_lexer_consume_token (parser->lexer);
+ break;
+
+ default:
+ /* We did not yet find a decl-specifier yet. */
+ found_decl_spec = false;
+ break;
+ }
+
+ if (found_decl_spec
+ && (flags & CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR)
+ && token->keyword != RID_CONSTEXPR)
+ error ("decl-specifier invalid in condition");
+
+ if (ds != ds_last)
+ set_and_check_decl_spec_loc (decl_specs, ds, token);
+
+ /* Constructors are a special case. The `S' in `S()' is not a
+ decl-specifier; it is the beginning of the declarator. */
+ constructor_p
+ = (!found_decl_spec
+ && constructor_possible_p
+ && (cp_parser_constructor_declarator_p
+ (parser, decl_spec_seq_has_spec_p (decl_specs, ds_friend))));
+
+ /* If we don't have a DECL_SPEC yet, then we must be looking at
+ a type-specifier. */
+ if (!found_decl_spec && !constructor_p)
+ {
+ int decl_spec_declares_class_or_enum;
+ bool is_cv_qualifier;
+ tree type_spec;
+
+ type_spec
+ = cp_parser_type_specifier (parser, flags,
+ decl_specs,
+ /*is_declaration=*/true,
+ &decl_spec_declares_class_or_enum,
+ &is_cv_qualifier);
+ *declares_class_or_enum |= decl_spec_declares_class_or_enum;
+
+ /* If this type-specifier referenced a user-defined type
+ (a typedef, class-name, etc.), then we can't allow any
+ more such type-specifiers henceforth.
+
+ [dcl.spec]
+
+ The longest sequence of decl-specifiers that could
+ possibly be a type name is taken as the
+ decl-specifier-seq of a declaration. The sequence shall
+ be self-consistent as described below.
+
+ [dcl.type]
+
+ As a general rule, at most one type-specifier is allowed
+ in the complete decl-specifier-seq of a declaration. The
+ only exceptions are the following:
+
+ -- const or volatile can be combined with any other
+ type-specifier.
+
+ -- signed or unsigned can be combined with char, long,
+ short, or int.
+
+ -- ..
+
+ Example:
+
+ typedef char* Pc;
+ void g (const int Pc);
+
+ Here, Pc is *not* part of the decl-specifier seq; it's
+ the declarator. Therefore, once we see a type-specifier
+ (other than a cv-qualifier), we forbid any additional
+ user-defined types. We *do* still allow things like `int
+ int' to be considered a decl-specifier-seq, and issue the
+ error message later. */
+ if (type_spec && !is_cv_qualifier)
+ flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
+ /* A constructor declarator cannot follow a type-specifier. */
+ if (type_spec)
+ {
+ constructor_possible_p = false;
+ found_decl_spec = true;
+ if (!is_cv_qualifier)
+ decl_specs->any_type_specifiers_p = true;
+ }
+ }
+
+ /* If we still do not have a DECL_SPEC, then there are no more
+ decl-specifiers. */
+ if (!found_decl_spec)
+ break;
+
+ decl_specs->any_specifiers_p = true;
+ /* After we see one decl-specifier, further decl-specifiers are
+ always optional. */
+ flags |= CP_PARSER_FLAGS_OPTIONAL;
+ }
+
+ /* Don't allow a friend specifier with a class definition. */
+ if (decl_spec_seq_has_spec_p (decl_specs, ds_friend)
+ && (*declares_class_or_enum & 2))
+ error_at (decl_specs->locations[ds_friend],
+ "class definition may not be declared a friend");
+}
+
+/* Parse an (optional) storage-class-specifier.
+
+ storage-class-specifier:
+ auto
+ register
+ static
+ extern
+ mutable
+
+ GNU Extension:
+
+ storage-class-specifier:
+ thread
+
+ Returns an IDENTIFIER_NODE corresponding to the keyword used. */
+
+static tree
+cp_parser_storage_class_specifier_opt (cp_parser* parser)
+{
+ switch (cp_lexer_peek_token (parser->lexer)->keyword)
+ {
+ case RID_AUTO:
+ if (cxx_dialect != cxx98)
+ return NULL_TREE;
+ /* Fall through for C++98. */
+
+ case RID_REGISTER:
+ case RID_STATIC:
+ case RID_EXTERN:
+ case RID_MUTABLE:
+ case RID_THREAD:
+ /* Consume the token. */
+ return cp_lexer_consume_token (parser->lexer)->u.value;
+
+ default:
+ return NULL_TREE;
+ }
+}
+
+/* Parse an (optional) function-specifier.
+
+ function-specifier:
+ inline
+ virtual
+ explicit
+
+ Returns an IDENTIFIER_NODE corresponding to the keyword used.
+ Updates DECL_SPECS, if it is non-NULL. */
+
+static tree
+cp_parser_function_specifier_opt (cp_parser* parser,
+ cp_decl_specifier_seq *decl_specs)
+{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ switch (token->keyword)
+ {
+ case RID_INLINE:
+ set_and_check_decl_spec_loc (decl_specs, ds_inline, token);
+ break;
+
+ case RID_VIRTUAL:
+ /* 14.5.2.3 [temp.mem]
+
+ A member function template shall not be virtual. */
+ if (PROCESSING_REAL_TEMPLATE_DECL_P ())
+ error_at (token->location, "templates may not be %<virtual%>");
+ else
+ set_and_check_decl_spec_loc (decl_specs, ds_virtual, token);
+ break;
+
+ case RID_EXPLICIT:
+ set_and_check_decl_spec_loc (decl_specs, ds_explicit, token);
+ break;
+
+ default:
+ return NULL_TREE;
+ }
+
+ /* Consume the token. */
+ return cp_lexer_consume_token (parser->lexer)->u.value;
+}
+
+/* Parse a linkage-specification.
+
+ linkage-specification:
+ extern string-literal { declaration-seq [opt] }
+ extern string-literal declaration */
+
+static void
+cp_parser_linkage_specification (cp_parser* parser)
+{
+ tree linkage;
+
+ /* Look for the `extern' keyword. */
+ cp_parser_require_keyword (parser, RID_EXTERN, RT_EXTERN);
+
+ /* Look for the string-literal. */
+ linkage = cp_parser_string_literal (parser, false, false);
+
+ /* Transform the literal into an identifier. If the literal is a
+ wide-character string, or contains embedded NULs, then we can't
+ handle it as the user wants. */
+ if (strlen (TREE_STRING_POINTER (linkage))
+ != (size_t) (TREE_STRING_LENGTH (linkage) - 1))
+ {
+ cp_parser_error (parser, "invalid linkage-specification");
+ /* Assume C++ linkage. */
+ linkage = lang_name_cplusplus;
+ }
+ else
+ linkage = get_identifier (TREE_STRING_POINTER (linkage));
+
+ /* We're now using the new linkage. */
+ push_lang_context (linkage);
+
+ /* If the next token is a `{', then we're using the first
+ production. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ cp_ensure_no_omp_declare_simd (parser);
+
+ /* Consume the `{' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the declarations. */
+ cp_parser_declaration_seq_opt (parser);
+ /* Look for the closing `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ }
+ /* Otherwise, there's just one declaration. */
+ else
+ {
+ bool saved_in_unbraced_linkage_specification_p;
+
+ saved_in_unbraced_linkage_specification_p
+ = parser->in_unbraced_linkage_specification_p;
+ parser->in_unbraced_linkage_specification_p = true;
+ cp_parser_declaration (parser);
+ parser->in_unbraced_linkage_specification_p
+ = saved_in_unbraced_linkage_specification_p;
+ }
+
+ /* We're done with the linkage-specification. */
+ pop_lang_context ();
+}
+
+/* Parse a static_assert-declaration.
+
+ static_assert-declaration:
+ static_assert ( constant-expression , string-literal ) ;
+
+ If MEMBER_P, this static_assert is a class member. */
+
+static void
+cp_parser_static_assert(cp_parser *parser, bool member_p)
+{
+ tree condition;
+ tree message;
+ cp_token *token;
+ location_t saved_loc;
+ bool dummy;
+
+ /* Peek at the `static_assert' token so we can keep track of exactly
+ where the static assertion started. */
+ token = cp_lexer_peek_token (parser->lexer);
+ saved_loc = token->location;
+
+ /* Look for the `static_assert' keyword. */
+ if (!cp_parser_require_keyword (parser, RID_STATIC_ASSERT,
+ RT_STATIC_ASSERT))
+ return;
+
+ /* We know we are in a static assertion; commit to any tentative
+ parse. */
+ if (cp_parser_parsing_tentatively (parser))
+ cp_parser_commit_to_tentative_parse (parser);
+
+ /* Parse the `(' starting the static assertion condition. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+ /* Parse the constant-expression. Allow a non-constant expression
+ here in order to give better diagnostics in finish_static_assert. */
+ condition =
+ cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/true,
+ /*non_constant_p=*/&dummy);
+
+ /* Parse the separating `,'. */
+ cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+
+ /* Parse the string-literal message. */
+ message = cp_parser_string_literal (parser,
+ /*translate=*/false,
+ /*wide_ok=*/true);
+
+ /* A `)' completes the static assertion. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ /* A semicolon terminates the declaration. */
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+ /* Complete the static assertion, which may mean either processing
+ the static assert now or saving it for template instantiation. */
+ finish_static_assert (condition, message, saved_loc, member_p);
+}
+
+/* Parse the expression in decltype ( expression ). */
+
+static tree
+cp_parser_decltype_expr (cp_parser *parser,
+ bool &id_expression_or_member_access_p)
+{
+ cp_token *id_expr_start_token;
+ tree expr;
+
+ /* First, try parsing an id-expression. */
+ id_expr_start_token = cp_lexer_peek_token (parser->lexer);
+ cp_parser_parse_tentatively (parser);
+ expr = cp_parser_id_expression (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/NULL,
+ /*declarator_p=*/false,
+ /*optional_p=*/false);
+
+ if (!cp_parser_error_occurred (parser) && expr != error_mark_node)
+ {
+ bool non_integral_constant_expression_p = false;
+ tree id_expression = expr;
+ cp_id_kind idk;
+ const char *error_msg;
+
+ if (identifier_p (expr))
+ /* Lookup the name we got back from the id-expression. */
+ expr = cp_parser_lookup_name_simple (parser, expr,
+ id_expr_start_token->location);
+
+ if (expr
+ && expr != error_mark_node
+ && TREE_CODE (expr) != TEMPLATE_ID_EXPR
+ && TREE_CODE (expr) != TYPE_DECL
+ && (TREE_CODE (expr) != BIT_NOT_EXPR
+ || !TYPE_P (TREE_OPERAND (expr, 0)))
+ && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
+ {
+ /* Complete lookup of the id-expression. */
+ expr = (finish_id_expression
+ (id_expression, expr, parser->scope, &idk,
+ /*integral_constant_expression_p=*/false,
+ /*allow_non_integral_constant_expression_p=*/true,
+ &non_integral_constant_expression_p,
+ /*template_p=*/false,
+ /*done=*/true,
+ /*address_p=*/false,
+ /*template_arg_p=*/false,
+ &error_msg,
+ id_expr_start_token->location));
+
+ if (expr == error_mark_node)
+ /* We found an id-expression, but it was something that we
+ should not have found. This is an error, not something
+ we can recover from, so note that we found an
+ id-expression and we'll recover as gracefully as
+ possible. */
+ id_expression_or_member_access_p = true;
+ }
+
+ if (expr
+ && expr != error_mark_node
+ && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
+ /* We have an id-expression. */
+ id_expression_or_member_access_p = true;
+ }
+
+ if (!id_expression_or_member_access_p)
+ {
+ /* Abort the id-expression parse. */
+ cp_parser_abort_tentative_parse (parser);
+
+ /* Parsing tentatively, again. */
+ cp_parser_parse_tentatively (parser);
+
+ /* Parse a class member access. */
+ expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false, /*decltype*/true,
+ /*member_access_only_p=*/true, NULL);
+
+ if (expr
+ && expr != error_mark_node
+ && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
+ /* We have an id-expression. */
+ id_expression_or_member_access_p = true;
+ }
+
+ if (id_expression_or_member_access_p)
+ /* We have parsed the complete id-expression or member access. */
+ cp_parser_parse_definitely (parser);
+ else
+ {
+ /* Abort our attempt to parse an id-expression or member access
+ expression. */
+ cp_parser_abort_tentative_parse (parser);
+
+ /* Parse a full expression. */
+ expr = cp_parser_expression (parser, /*cast_p=*/false,
+ /*decltype*/true, NULL);
+ }
+
+ return expr;
+}
+
+/* Parse a `decltype' type. Returns the type.
+
+ simple-type-specifier:
+ decltype ( expression )
+ C++14 proposal:
+ decltype ( auto ) */
+
+static tree
+cp_parser_decltype (cp_parser *parser)
+{
+ tree expr;
+ bool id_expression_or_member_access_p = false;
+ const char *saved_message;
+ bool saved_integral_constant_expression_p;
+ bool saved_non_integral_constant_expression_p;
+ bool saved_greater_than_is_operator_p;
+ cp_token *start_token = cp_lexer_peek_token (parser->lexer);
+
+ if (start_token->type == CPP_DECLTYPE)
+ {
+ /* Already parsed. */
+ cp_lexer_consume_token (parser->lexer);
+ return start_token->u.value;
+ }
+
+ /* Look for the `decltype' token. */
+ if (!cp_parser_require_keyword (parser, RID_DECLTYPE, RT_DECLTYPE))
+ return error_mark_node;
+
+ /* Parse the opening `('. */
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return error_mark_node;
+
+ /* decltype (auto) */
+ if (cxx_dialect >= cxx1y
+ && cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ return error_mark_node;
+ expr = make_decltype_auto ();
+ AUTO_IS_DECLTYPE (expr) = true;
+ goto rewrite;
+ }
+
+ /* Types cannot be defined in a `decltype' expression. Save away the
+ old message. */
+ saved_message = parser->type_definition_forbidden_message;
+
+ /* And create the new one. */
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in %<decltype%> expressions");
+
+ /* The restrictions on constant-expressions do not apply inside
+ decltype expressions. */
+ saved_integral_constant_expression_p
+ = parser->integral_constant_expression_p;
+ saved_non_integral_constant_expression_p
+ = parser->non_integral_constant_expression_p;
+ parser->integral_constant_expression_p = false;
+
+ /* Within a parenthesized expression, a `>' token is always
+ the greater-than operator. */
+ saved_greater_than_is_operator_p
+ = parser->greater_than_is_operator_p;
+ parser->greater_than_is_operator_p = true;
+
+ /* Do not actually evaluate the expression. */
+ ++cp_unevaluated_operand;
+
+ /* Do not warn about problems with the expression. */
+ ++c_inhibit_evaluation_warnings;
+
+ expr = cp_parser_decltype_expr (parser, id_expression_or_member_access_p);
+
+ /* Go back to evaluating expressions. */
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+
+ /* The `>' token might be the end of a template-id or
+ template-parameter-list now. */
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+
+ /* Restore the old message and the integral constant expression
+ flags. */
+ parser->type_definition_forbidden_message = saved_message;
+ parser->integral_constant_expression_p
+ = saved_integral_constant_expression_p;
+ parser->non_integral_constant_expression_p
+ = saved_non_integral_constant_expression_p;
+
+ /* Parse to the closing `)'. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ {
+ cp_parser_skip_to_closing_parenthesis (parser, true, false,
+ /*consume_paren=*/true);
+ return error_mark_node;
+ }
+
+ expr = finish_decltype_type (expr, id_expression_or_member_access_p,
+ tf_warning_or_error);
+
+ rewrite:
+ /* Replace the decltype with a CPP_DECLTYPE so we don't need to parse
+ it again. */
+ start_token->type = CPP_DECLTYPE;
+ start_token->u.value = expr;
+ start_token->keyword = RID_MAX;
+ cp_lexer_purge_tokens_after (parser->lexer, start_token);
+
+ return expr;
+}
+
+/* Special member functions [gram.special] */
+
+/* Parse a conversion-function-id.
+
+ conversion-function-id:
+ operator conversion-type-id
+
+ Returns an IDENTIFIER_NODE representing the operator. */
+
+static tree
+cp_parser_conversion_function_id (cp_parser* parser)
+{
+ tree type;
+ tree saved_scope;
+ tree saved_qualifying_scope;
+ tree saved_object_scope;
+ tree pushed_scope = NULL_TREE;
+
+ /* Look for the `operator' token. */
+ if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR))
+ return error_mark_node;
+ /* When we parse the conversion-type-id, the current scope will be
+ reset. However, we need that information in able to look up the
+ conversion function later, so we save it here. */
+ saved_scope = parser->scope;
+ saved_qualifying_scope = parser->qualifying_scope;
+ saved_object_scope = parser->object_scope;
+ /* We must enter the scope of the class so that the names of
+ entities declared within the class are available in the
+ conversion-type-id. For example, consider:
+
+ struct S {
+ typedef int I;
+ operator I();
+ };
+
+ S::operator I() { ... }
+
+ In order to see that `I' is a type-name in the definition, we
+ must be in the scope of `S'. */
+ if (saved_scope)
+ pushed_scope = push_scope (saved_scope);
+ /* Parse the conversion-type-id. */
+ type = cp_parser_conversion_type_id (parser);
+ /* Leave the scope of the class, if any. */
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ /* Restore the saved scope. */
+ parser->scope = saved_scope;
+ parser->qualifying_scope = saved_qualifying_scope;
+ parser->object_scope = saved_object_scope;
+ /* If the TYPE is invalid, indicate failure. */
+ if (type == error_mark_node)
+ return error_mark_node;
+ return mangle_conv_op_name_for_type (type);
+}
+
+/* Parse a conversion-type-id:
+
+ conversion-type-id:
+ type-specifier-seq conversion-declarator [opt]
+
+ Returns the TYPE specified. */
+
+static tree
+cp_parser_conversion_type_id (cp_parser* parser)
+{
+ tree attributes;
+ cp_decl_specifier_seq type_specifiers;
+ cp_declarator *declarator;
+ tree type_specified;
+ const char *saved_message;
+
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
+
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in a conversion-type-id");
+
+ /* Parse the type-specifiers. */
+ cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+ /*is_trailing_return=*/false,
+ &type_specifiers);
+
+ parser->type_definition_forbidden_message = saved_message;
+
+ /* If that didn't work, stop. */
+ if (type_specifiers.type == error_mark_node)
+ return error_mark_node;
+ /* Parse the conversion-declarator. */
+ declarator = cp_parser_conversion_declarator_opt (parser);
+
+ type_specified = grokdeclarator (declarator, &type_specifiers, TYPENAME,
+ /*initialized=*/0, &attributes);
+ if (attributes)
+ cplus_decl_attributes (&type_specified, attributes, /*flags=*/0);
+
+ /* Don't give this error when parsing tentatively. This happens to
+ work because we always parse this definitively once. */
+ if (! cp_parser_uncommitted_to_tentative_parse_p (parser)
+ && type_uses_auto (type_specified))
+ {
+ if (cxx_dialect < cxx1y)
+ {
+ error ("invalid use of %<auto%> in conversion operator");
+ return error_mark_node;
+ }
+ else if (template_parm_scope_p ())
+ warning (0, "use of %<auto%> in member template "
+ "conversion operator can never be deduced");
+ }
+
+ return type_specified;
+}
+
+/* Parse an (optional) conversion-declarator.
+
+ conversion-declarator:
+ ptr-operator conversion-declarator [opt]
+
+ */
+
+static cp_declarator *
+cp_parser_conversion_declarator_opt (cp_parser* parser)
+{
+ enum tree_code code;
+ tree class_type, std_attributes = NULL_TREE;
+ cp_cv_quals cv_quals;
+
+ /* We don't know if there's a ptr-operator next, or not. */
+ cp_parser_parse_tentatively (parser);
+ /* Try the ptr-operator. */
+ code = cp_parser_ptr_operator (parser, &class_type, &cv_quals,
+ &std_attributes);
+ /* If it worked, look for more conversion-declarators. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ cp_declarator *declarator;
+
+ /* Parse another optional declarator. */
+ declarator = cp_parser_conversion_declarator_opt (parser);
+
+ declarator = cp_parser_make_indirect_declarator
+ (code, class_type, cv_quals, declarator, std_attributes);
+
+ return declarator;
+ }
+
+ return NULL;
+}
+
+/* Parse an (optional) ctor-initializer.
+
+ ctor-initializer:
+ : mem-initializer-list
+
+ Returns TRUE iff the ctor-initializer was actually present. */
+
+static bool
+cp_parser_ctor_initializer_opt (cp_parser* parser)
+{
+ /* If the next token is not a `:', then there is no
+ ctor-initializer. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
+ {
+ /* Do default initialization of any bases and members. */
+ if (DECL_CONSTRUCTOR_P (current_function_decl))
+ finish_mem_initializers (NULL_TREE);
+
+ return false;
+ }
+
+ /* Consume the `:' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* And the mem-initializer-list. */
+ cp_parser_mem_initializer_list (parser);
+
+ return true;
+}
+
+/* Parse a mem-initializer-list.
+
+ mem-initializer-list:
+ mem-initializer ... [opt]
+ mem-initializer ... [opt] , mem-initializer-list */
+
+static void
+cp_parser_mem_initializer_list (cp_parser* parser)
+{
+ tree mem_initializer_list = NULL_TREE;
+ tree target_ctor = error_mark_node;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* Let the semantic analysis code know that we are starting the
+ mem-initializer-list. */
+ if (!DECL_CONSTRUCTOR_P (current_function_decl))
+ error_at (token->location,
+ "only constructors take member initializers");
+
+ /* Loop through the list. */
+ while (true)
+ {
+ tree mem_initializer;
+
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Parse the mem-initializer. */
+ mem_initializer = cp_parser_mem_initializer (parser);
+ /* If the next token is a `...', we're expanding member initializers. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ /* Consume the `...'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* The TREE_PURPOSE must be a _TYPE, because base-specifiers
+ can be expanded but members cannot. */
+ if (mem_initializer != error_mark_node
+ && !TYPE_P (TREE_PURPOSE (mem_initializer)))
+ {
+ error_at (token->location,
+ "cannot expand initializer for member %<%D%>",
+ TREE_PURPOSE (mem_initializer));
+ mem_initializer = error_mark_node;
+ }
+
+ /* Construct the pack expansion type. */
+ if (mem_initializer != error_mark_node)
+ mem_initializer = make_pack_expansion (mem_initializer);
+ }
+ if (target_ctor != error_mark_node
+ && mem_initializer != error_mark_node)
+ {
+ error ("mem-initializer for %qD follows constructor delegation",
+ TREE_PURPOSE (mem_initializer));
+ mem_initializer = error_mark_node;
+ }
+ /* Look for a target constructor. */
+ if (mem_initializer != error_mark_node
+ && CLASS_TYPE_P (TREE_PURPOSE (mem_initializer))
+ && same_type_p (TREE_PURPOSE (mem_initializer), current_class_type))
+ {
+ maybe_warn_cpp0x (CPP0X_DELEGATING_CTORS);
+ if (mem_initializer_list)
+ {
+ error ("constructor delegation follows mem-initializer for %qD",
+ TREE_PURPOSE (mem_initializer_list));
+ mem_initializer = error_mark_node;
+ }
+ target_ctor = mem_initializer;
+ }
+ /* Add it to the list, unless it was erroneous. */
+ if (mem_initializer != error_mark_node)
+ {
+ TREE_CHAIN (mem_initializer) = mem_initializer_list;
+ mem_initializer_list = mem_initializer;
+ }
+ /* If the next token is not a `,', we're done. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Consume the `,' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ /* Perform semantic analysis. */
+ if (DECL_CONSTRUCTOR_P (current_function_decl))
+ finish_mem_initializers (mem_initializer_list);
+}
+
+/* Parse a mem-initializer.
+
+ mem-initializer:
+ mem-initializer-id ( expression-list [opt] )
+ mem-initializer-id braced-init-list
+
+ GNU extension:
+
+ mem-initializer:
+ ( expression-list [opt] )
+
+ Returns a TREE_LIST. The TREE_PURPOSE is the TYPE (for a base
+ class) or FIELD_DECL (for a non-static data member) to initialize;
+ the TREE_VALUE is the expression-list. An empty initialization
+ list is represented by void_list_node. */
+
+static tree
+cp_parser_mem_initializer (cp_parser* parser)
+{
+ tree mem_initializer_id;
+ tree expression_list;
+ tree member;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* Find out what is being initialized. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ permerror (token->location,
+ "anachronistic old-style base class initializer");
+ mem_initializer_id = NULL_TREE;
+ }
+ else
+ {
+ mem_initializer_id = cp_parser_mem_initializer_id (parser);
+ if (mem_initializer_id == error_mark_node)
+ return mem_initializer_id;
+ }
+ member = expand_member_init (mem_initializer_id);
+ if (member && !DECL_P (member))
+ in_base_initializer = 1;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ bool expr_non_constant_p;
+ cp_lexer_set_source_position (parser->lexer);
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
+ CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
+ expression_list = build_tree_list (NULL_TREE, expression_list);
+ }
+ else
+ {
+ vec<tree, va_gc> *vec;
+ vec = cp_parser_parenthesized_expression_list (parser, non_attr,
+ /*cast_p=*/false,
+ /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL);
+ if (vec == NULL)
+ return error_mark_node;
+ expression_list = build_tree_list_vec (vec);
+ release_tree_vector (vec);
+ }
+
+ if (expression_list == error_mark_node)
+ return error_mark_node;
+ if (!expression_list)
+ expression_list = void_type_node;
+
+ in_base_initializer = 0;
+
+ return member ? build_tree_list (member, expression_list) : error_mark_node;
+}
+
+/* Parse a mem-initializer-id.
+
+ mem-initializer-id:
+ :: [opt] nested-name-specifier [opt] class-name
+ identifier
+
+ Returns a TYPE indicating the class to be initializer for the first
+ production. Returns an IDENTIFIER_NODE indicating the data member
+ to be initialized for the second production. */
+
+static tree
+cp_parser_mem_initializer_id (cp_parser* parser)
+{
+ bool global_scope_p;
+ bool nested_name_specifier_p;
+ bool template_p = false;
+ tree id;
+
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* `typename' is not allowed in this context ([temp.res]). */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
+ {
+ error_at (token->location,
+ "keyword %<typename%> not allowed in this context (a qualified "
+ "member initializer is implicitly a type)");
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* Look for the optional `::' operator. */
+ global_scope_p
+ = (cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+ /* Look for the optional nested-name-specifier. The simplest way to
+ implement:
+
+ [temp.res]
+
+ The keyword `typename' is not permitted in a base-specifier or
+ mem-initializer; in these contexts a qualified name that
+ depends on a template-parameter is implicitly assumed to be a
+ type name.
+
+ is to assume that we have seen the `typename' keyword at this
+ point. */
+ nested_name_specifier_p
+ = (cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/true,
+ /*check_dependency_p=*/true,
+ /*type_p=*/true,
+ /*is_declaration=*/true)
+ != NULL_TREE);
+ if (nested_name_specifier_p)
+ template_p = cp_parser_optional_template_keyword (parser);
+ /* If there is a `::' operator or a nested-name-specifier, then we
+ are definitely looking for a class-name. */
+ if (global_scope_p || nested_name_specifier_p)
+ return cp_parser_class_name (parser,
+ /*typename_keyword_p=*/true,
+ /*template_keyword_p=*/template_p,
+ typename_type,
+ /*check_dependency_p=*/true,
+ /*class_head_p=*/false,
+ /*is_declaration=*/true);
+ /* Otherwise, we could also be looking for an ordinary identifier. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a class-name. */
+ id = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/true,
+ /*template_keyword_p=*/false,
+ none_type,
+ /*check_dependency_p=*/true,
+ /*class_head_p=*/false,
+ /*is_declaration=*/true);
+ /* If we found one, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return id;
+ /* Otherwise, look for an ordinary identifier. */
+ return cp_parser_identifier (parser);
+}
+
+/* Overloading [gram.over] */
+
+/* Parse an operator-function-id.
+
+ operator-function-id:
+ operator operator
+
+ Returns an IDENTIFIER_NODE for the operator which is a
+ human-readable spelling of the identifier, e.g., `operator +'. */
+
+static tree
+cp_parser_operator_function_id (cp_parser* parser)
+{
+ /* Look for the `operator' keyword. */
+ if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR))
+ return error_mark_node;
+ /* And then the name of the operator itself. */
+ return cp_parser_operator (parser);
+}
+
+/* Return an identifier node for a user-defined literal operator.
+ The suffix identifier is chained to the operator name identifier. */
+
+static tree
+cp_literal_operator_id (const char* name)
+{
+ tree identifier;
+ char *buffer = XNEWVEC (char, strlen (UDLIT_OP_ANSI_PREFIX)
+ + strlen (name) + 10);
+ sprintf (buffer, UDLIT_OP_ANSI_FORMAT, name);
+ identifier = get_identifier (buffer);
+
+ return identifier;
+}
+
+/* Parse an operator.
+
+ operator:
+ new delete new[] delete[] + - * / % ^ & | ~ ! = < >
+ += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= &&
+ || ++ -- , ->* -> () []
+
+ GNU Extensions:
+
+ operator:
+ <? >? <?= >?=
+
+ Returns an IDENTIFIER_NODE for the operator which is a
+ human-readable spelling of the identifier, e.g., `operator +'. */
+
+static tree
+cp_parser_operator (cp_parser* parser)
+{
+ tree id = NULL_TREE;
+ cp_token *token;
+ bool bad_encoding_prefix = false;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Figure out which operator we have. */
+ switch (token->type)
+ {
+ case CPP_KEYWORD:
+ {
+ enum tree_code op;
+
+ /* The keyword should be either `new' or `delete'. */
+ if (token->keyword == RID_NEW)
+ op = NEW_EXPR;
+ else if (token->keyword == RID_DELETE)
+ op = DELETE_EXPR;
+ else
+ break;
+
+ /* Consume the `new' or `delete' token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's a `[' token then this is the array variant of the
+ operator. */
+ if (token->type == CPP_OPEN_SQUARE)
+ {
+ /* Consume the `[' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the `]' token. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+ id = ansi_opname (op == NEW_EXPR
+ ? VEC_NEW_EXPR : VEC_DELETE_EXPR);
+ }
+ /* Otherwise, we have the non-array variant. */
+ else
+ id = ansi_opname (op);
+
+ return id;
+ }
+
+ case CPP_PLUS:
+ id = ansi_opname (PLUS_EXPR);
+ break;
+
+ case CPP_MINUS:
+ id = ansi_opname (MINUS_EXPR);
+ break;
+
+ case CPP_MULT:
+ id = ansi_opname (MULT_EXPR);
+ break;
+
+ case CPP_DIV:
+ id = ansi_opname (TRUNC_DIV_EXPR);
+ break;
+
+ case CPP_MOD:
+ id = ansi_opname (TRUNC_MOD_EXPR);
+ break;
+
+ case CPP_XOR:
+ id = ansi_opname (BIT_XOR_EXPR);
+ break;
+
+ case CPP_AND:
+ id = ansi_opname (BIT_AND_EXPR);
+ break;
+
+ case CPP_OR:
+ id = ansi_opname (BIT_IOR_EXPR);
+ break;
+
+ case CPP_COMPL:
+ id = ansi_opname (BIT_NOT_EXPR);
+ break;
+
+ case CPP_NOT:
+ id = ansi_opname (TRUTH_NOT_EXPR);
+ break;
+
+ case CPP_EQ:
+ id = ansi_assopname (NOP_EXPR);
+ break;
+
+ case CPP_LESS:
+ id = ansi_opname (LT_EXPR);
+ break;
+
+ case CPP_GREATER:
+ id = ansi_opname (GT_EXPR);
+ break;
+
+ case CPP_PLUS_EQ:
+ id = ansi_assopname (PLUS_EXPR);
+ break;
+
+ case CPP_MINUS_EQ:
+ id = ansi_assopname (MINUS_EXPR);
+ break;
+
+ case CPP_MULT_EQ:
+ id = ansi_assopname (MULT_EXPR);
+ break;
+
+ case CPP_DIV_EQ:
+ id = ansi_assopname (TRUNC_DIV_EXPR);
+ break;
+
+ case CPP_MOD_EQ:
+ id = ansi_assopname (TRUNC_MOD_EXPR);
+ break;
+
+ case CPP_XOR_EQ:
+ id = ansi_assopname (BIT_XOR_EXPR);
+ break;
+
+ case CPP_AND_EQ:
+ id = ansi_assopname (BIT_AND_EXPR);
+ break;
+
+ case CPP_OR_EQ:
+ id = ansi_assopname (BIT_IOR_EXPR);
+ break;
+
+ case CPP_LSHIFT:
+ id = ansi_opname (LSHIFT_EXPR);
+ break;
+
+ case CPP_RSHIFT:
+ id = ansi_opname (RSHIFT_EXPR);
+ break;
+
+ case CPP_LSHIFT_EQ:
+ id = ansi_assopname (LSHIFT_EXPR);
+ break;
+
+ case CPP_RSHIFT_EQ:
+ id = ansi_assopname (RSHIFT_EXPR);
+ break;
+
+ case CPP_EQ_EQ:
+ id = ansi_opname (EQ_EXPR);
+ break;
+
+ case CPP_NOT_EQ:
+ id = ansi_opname (NE_EXPR);
+ break;
+
+ case CPP_LESS_EQ:
+ id = ansi_opname (LE_EXPR);
+ break;
+
+ case CPP_GREATER_EQ:
+ id = ansi_opname (GE_EXPR);
+ break;
+
+ case CPP_AND_AND:
+ id = ansi_opname (TRUTH_ANDIF_EXPR);
+ break;
+
+ case CPP_OR_OR:
+ id = ansi_opname (TRUTH_ORIF_EXPR);
+ break;
+
+ case CPP_PLUS_PLUS:
+ id = ansi_opname (POSTINCREMENT_EXPR);
+ break;
+
+ case CPP_MINUS_MINUS:
+ id = ansi_opname (PREDECREMENT_EXPR);
+ break;
+
+ case CPP_COMMA:
+ id = ansi_opname (COMPOUND_EXPR);
+ break;
+
+ case CPP_DEREF_STAR:
+ id = ansi_opname (MEMBER_REF);
+ break;
+
+ case CPP_DEREF:
+ id = ansi_opname (COMPONENT_REF);
+ break;
+
+ case CPP_OPEN_PAREN:
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the matching `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ return ansi_opname (CALL_EXPR);
+
+ case CPP_OPEN_SQUARE:
+ /* Consume the `['. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the matching `]'. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+ return ansi_opname (ARRAY_REF);
+
+ case CPP_WSTRING:
+ case CPP_STRING16:
+ case CPP_STRING32:
+ case CPP_UTF8STRING:
+ bad_encoding_prefix = true;
+ /* Fall through. */
+
+ case CPP_STRING:
+ if (cxx_dialect == cxx98)
+ maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS);
+ if (bad_encoding_prefix)
+ {
+ error ("invalid encoding prefix in literal operator");
+ return error_mark_node;
+ }
+ if (TREE_STRING_LENGTH (token->u.value) > 2)
+ {
+ error ("expected empty string after %<operator%> keyword");
+ return error_mark_node;
+ }
+ /* Consume the string. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the suffix identifier. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_NAME)
+ {
+ id = cp_parser_identifier (parser);
+ if (id != error_mark_node)
+ {
+ const char *name = IDENTIFIER_POINTER (id);
+ return cp_literal_operator_id (name);
+ }
+ }
+ else if (token->type == CPP_KEYWORD)
+ {
+ error ("unexpected keyword;"
+ " remove space between quotes and suffix identifier");
+ return error_mark_node;
+ }
+ else
+ {
+ error ("expected suffix identifier");
+ return error_mark_node;
+ }
+
+ case CPP_WSTRING_USERDEF:
+ case CPP_STRING16_USERDEF:
+ case CPP_STRING32_USERDEF:
+ case CPP_UTF8STRING_USERDEF:
+ bad_encoding_prefix = true;
+ /* Fall through. */
+
+ case CPP_STRING_USERDEF:
+ if (cxx_dialect == cxx98)
+ maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS);
+ if (bad_encoding_prefix)
+ {
+ error ("invalid encoding prefix in literal operator");
+ return error_mark_node;
+ }
+ {
+ tree string_tree = USERDEF_LITERAL_VALUE (token->u.value);
+ if (TREE_STRING_LENGTH (string_tree) > 2)
+ {
+ error ("expected empty string after %<operator%> keyword");
+ return error_mark_node;
+ }
+ id = USERDEF_LITERAL_SUFFIX_ID (token->u.value);
+ /* Consume the user-defined string literal. */
+ cp_lexer_consume_token (parser->lexer);
+ if (id != error_mark_node)
+ {
+ const char *name = IDENTIFIER_POINTER (id);
+ return cp_literal_operator_id (name);
+ }
+ else
+ return error_mark_node;
+ }
+
+ default:
+ /* Anything else is an error. */
+ break;
+ }
+
+ /* If we have selected an identifier, we need to consume the
+ operator token. */
+ if (id)
+ cp_lexer_consume_token (parser->lexer);
+ /* Otherwise, no valid operator name was present. */
+ else
+ {
+ cp_parser_error (parser, "expected operator");
+ id = error_mark_node;
+ }
+
+ return id;
+}
+
+/* Parse a template-declaration.
+
+ template-declaration:
+ export [opt] template < template-parameter-list > declaration
+
+ If MEMBER_P is TRUE, this template-declaration occurs within a
+ class-specifier.
+
+ The grammar rule given by the standard isn't correct. What
+ is really meant is:
+
+ template-declaration:
+ export [opt] template-parameter-list-seq
+ decl-specifier-seq [opt] init-declarator [opt] ;
+ export [opt] template-parameter-list-seq
+ function-definition
+
+ template-parameter-list-seq:
+ template-parameter-list-seq [opt]
+ template < template-parameter-list > */
+
+static void
+cp_parser_template_declaration (cp_parser* parser, bool member_p)
+{
+ /* Check for `export'. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXPORT))
+ {
+ /* Consume the `export' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Warn that we do not support `export'. */
+ warning (0, "keyword %<export%> not implemented, and will be ignored");
+ }
+
+ cp_parser_template_declaration_after_export (parser, member_p);
+}
+
+/* Parse a template-parameter-list.
+
+ template-parameter-list:
+ template-parameter
+ template-parameter-list , template-parameter
+
+ Returns a TREE_LIST. Each node represents a template parameter.
+ The nodes are connected via their TREE_CHAINs. */
+
+static tree
+cp_parser_template_parameter_list (cp_parser* parser)
+{
+ tree parameter_list = NULL_TREE;
+
+ begin_template_parm_list ();
+
+ /* The loop below parses the template parms. We first need to know
+ the total number of template parms to be able to compute proper
+ canonical types of each dependent type. So after the loop, when
+ we know the total number of template parms,
+ end_template_parm_list computes the proper canonical types and
+ fixes up the dependent types accordingly. */
+ while (true)
+ {
+ tree parameter;
+ bool is_non_type;
+ bool is_parameter_pack;
+ location_t parm_loc;
+
+ /* Parse the template-parameter. */
+ parm_loc = cp_lexer_peek_token (parser->lexer)->location;
+ parameter = cp_parser_template_parameter (parser,
+ &is_non_type,
+ &is_parameter_pack);
+ /* Add it to the list. */
+ if (parameter != error_mark_node)
+ parameter_list = process_template_parm (parameter_list,
+ parm_loc,
+ parameter,
+ is_non_type,
+ is_parameter_pack);
+ else
+ {
+ tree err_parm = build_tree_list (parameter, parameter);
+ parameter_list = chainon (parameter_list, err_parm);
+ }
+
+ /* If the next token is not a `,', we're done. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Otherwise, consume the `,' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return end_template_parm_list (parameter_list);
+}
+
+/* Parse a template-parameter.
+
+ template-parameter:
+ type-parameter
+ parameter-declaration
+
+ If all goes well, returns a TREE_LIST. The TREE_VALUE represents
+ the parameter. The TREE_PURPOSE is the default value, if any.
+ Returns ERROR_MARK_NODE on failure. *IS_NON_TYPE is set to true
+ iff this parameter is a non-type parameter. *IS_PARAMETER_PACK is
+ set to true iff this parameter is a parameter pack. */
+
+static tree
+cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
+ bool *is_parameter_pack)
+{
+ cp_token *token;
+ cp_parameter_declarator *parameter_declarator;
+ cp_declarator *id_declarator;
+ tree parm;
+
+ /* Assume it is a type parameter or a template parameter. */
+ *is_non_type = false;
+ /* Assume it not a parameter pack. */
+ *is_parameter_pack = false;
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it is `class' or `template', we have a type-parameter. */
+ if (token->keyword == RID_TEMPLATE)
+ return cp_parser_type_parameter (parser, is_parameter_pack);
+ /* If it is `class' or `typename' we do not know yet whether it is a
+ type parameter or a non-type parameter. Consider:
+
+ template <typename T, typename T::X X> ...
+
+ or:
+
+ template <class C, class D*> ...
+
+ Here, the first parameter is a type parameter, and the second is
+ a non-type parameter. We can tell by looking at the token after
+ the identifier -- if it is a `,', `=', or `>' then we have a type
+ parameter. */
+ if (token->keyword == RID_TYPENAME || token->keyword == RID_CLASS)
+ {
+ /* Peek at the token after `class' or `typename'. */
+ token = cp_lexer_peek_nth_token (parser->lexer, 2);
+ /* If it's an ellipsis, we have a template type parameter
+ pack. */
+ if (token->type == CPP_ELLIPSIS)
+ return cp_parser_type_parameter (parser, is_parameter_pack);
+ /* If it's an identifier, skip it. */
+ if (token->type == CPP_NAME)
+ token = cp_lexer_peek_nth_token (parser->lexer, 3);
+ /* Now, see if the token looks like the end of a template
+ parameter. */
+ if (token->type == CPP_COMMA
+ || token->type == CPP_EQ
+ || token->type == CPP_GREATER)
+ return cp_parser_type_parameter (parser, is_parameter_pack);
+ }
+
+ /* Otherwise, it is a non-type parameter.
+
+ [temp.param]
+
+ When parsing a default template-argument for a non-type
+ template-parameter, the first non-nested `>' is taken as the end
+ of the template parameter-list rather than a greater-than
+ operator. */
+ *is_non_type = true;
+ parameter_declarator
+ = cp_parser_parameter_declaration (parser, /*template_parm_p=*/true,
+ /*parenthesized_p=*/NULL);
+
+ if (!parameter_declarator)
+ return error_mark_node;
+
+ /* If the parameter declaration is marked as a parameter pack, set
+ *IS_PARAMETER_PACK to notify the caller. Also, unmark the
+ declarator's PACK_EXPANSION_P, otherwise we'll get errors from
+ grokdeclarator. */
+ if (parameter_declarator->declarator
+ && parameter_declarator->declarator->parameter_pack_p)
+ {
+ *is_parameter_pack = true;
+ parameter_declarator->declarator->parameter_pack_p = false;
+ }
+
+ if (parameter_declarator->default_argument)
+ {
+ /* Can happen in some cases of erroneous input (c++/34892). */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ /* Consume the `...' for better error recovery. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* If the next token is an ellipsis, and we don't already have it
+ marked as a parameter pack, then we have a parameter pack (that
+ has no declarator). */
+ else if (!*is_parameter_pack
+ && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)
+ && (declarator_can_be_parameter_pack
+ (parameter_declarator->declarator)))
+ {
+ /* Consume the `...'. */
+ cp_lexer_consume_token (parser->lexer);
+ maybe_warn_variadic_templates ();
+
+ *is_parameter_pack = true;
+ }
+ /* We might end up with a pack expansion as the type of the non-type
+ template parameter, in which case this is a non-type template
+ parameter pack. */
+ else if (parameter_declarator->decl_specifiers.type
+ && PACK_EXPANSION_P (parameter_declarator->decl_specifiers.type))
+ {
+ *is_parameter_pack = true;
+ parameter_declarator->decl_specifiers.type =
+ PACK_EXPANSION_PATTERN (parameter_declarator->decl_specifiers.type);
+ }
+
+ if (*is_parameter_pack && cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ {
+ /* Parameter packs cannot have default arguments. However, a
+ user may try to do so, so we'll parse them and give an
+ appropriate diagnostic here. */
+
+ cp_token *start_token = cp_lexer_peek_token (parser->lexer);
+
+ /* Find the name of the parameter pack. */
+ id_declarator = parameter_declarator->declarator;
+ while (id_declarator && id_declarator->kind != cdk_id)
+ id_declarator = id_declarator->declarator;
+
+ if (id_declarator && id_declarator->kind == cdk_id)
+ error_at (start_token->location,
+ "template parameter pack %qD cannot have a default argument",
+ id_declarator->u.id.unqualified_name);
+ else
+ error_at (start_token->location,
+ "template parameter pack cannot have a default argument");
+
+ /* Parse the default argument, but throw away the result. */
+ cp_parser_default_argument (parser, /*template_parm_p=*/true);
+ }
+
+ parm = grokdeclarator (parameter_declarator->declarator,
+ &parameter_declarator->decl_specifiers,
+ TPARM, /*initialized=*/0,
+ /*attrlist=*/NULL);
+ if (parm == error_mark_node)
+ return error_mark_node;
+
+ return build_tree_list (parameter_declarator->default_argument, parm);
+}
+
+/* Parse a type-parameter.
+
+ type-parameter:
+ class identifier [opt]
+ class identifier [opt] = type-id
+ typename identifier [opt]
+ typename identifier [opt] = type-id
+ template < template-parameter-list > class identifier [opt]
+ template < template-parameter-list > class identifier [opt]
+ = id-expression
+
+ GNU Extension (variadic templates):
+
+ type-parameter:
+ class ... identifier [opt]
+ typename ... identifier [opt]
+
+ Returns a TREE_LIST. The TREE_VALUE is itself a TREE_LIST. The
+ TREE_PURPOSE is the default-argument, if any. The TREE_VALUE is
+ the declaration of the parameter.
+
+ Sets *IS_PARAMETER_PACK if this is a template parameter pack. */
+
+static tree
+cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
+{
+ cp_token *token;
+ tree parameter;
+
+ /* Look for a keyword to tell us what kind of parameter this is. */
+ token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_TYPENAME_TEMPLATE);
+ if (!token)
+ return error_mark_node;
+
+ switch (token->keyword)
+ {
+ case RID_CLASS:
+ case RID_TYPENAME:
+ {
+ tree identifier;
+ tree default_argument;
+
+ /* If the next token is an ellipsis, we have a template
+ argument pack. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ /* Consume the `...' token. */
+ cp_lexer_consume_token (parser->lexer);
+ maybe_warn_variadic_templates ();
+
+ *is_parameter_pack = true;
+ }
+
+ /* If the next token is an identifier, then it names the
+ parameter. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ identifier = cp_parser_identifier (parser);
+ else
+ identifier = NULL_TREE;
+
+ /* Create the parameter. */
+ parameter = finish_template_type_parm (class_type_node, identifier);
+
+ /* If the next token is an `=', we have a default argument. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ {
+ /* Consume the `=' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the default-argument. */
+ push_deferring_access_checks (dk_no_deferred);
+ default_argument = cp_parser_type_id (parser);
+
+ /* Template parameter packs cannot have default
+ arguments. */
+ if (*is_parameter_pack)
+ {
+ if (identifier)
+ error_at (token->location,
+ "template parameter pack %qD cannot have a "
+ "default argument", identifier);
+ else
+ error_at (token->location,
+ "template parameter packs cannot have "
+ "default arguments");
+ default_argument = NULL_TREE;
+ }
+ pop_deferring_access_checks ();
+ }
+ else
+ default_argument = NULL_TREE;
+
+ /* Create the combined representation of the parameter and the
+ default argument. */
+ parameter = build_tree_list (default_argument, parameter);
+ }
+ break;
+
+ case RID_TEMPLATE:
+ {
+ tree identifier;
+ tree default_argument;
+
+ /* Look for the `<'. */
+ cp_parser_require (parser, CPP_LESS, RT_LESS);
+ /* Parse the template-parameter-list. */
+ cp_parser_template_parameter_list (parser);
+ /* Look for the `>'. */
+ cp_parser_require (parser, CPP_GREATER, RT_GREATER);
+ /* Look for the `class' keyword. */
+ cp_parser_require_keyword (parser, RID_CLASS, RT_CLASS);
+ /* If the next token is an ellipsis, we have a template
+ argument pack. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ /* Consume the `...' token. */
+ cp_lexer_consume_token (parser->lexer);
+ maybe_warn_variadic_templates ();
+
+ *is_parameter_pack = true;
+ }
+ /* If the next token is an `=', then there is a
+ default-argument. If the next token is a `>', we are at
+ the end of the parameter-list. If the next token is a `,',
+ then we are at the end of this parameter. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ {
+ identifier = cp_parser_identifier (parser);
+ /* Treat invalid names as if the parameter were nameless. */
+ if (identifier == error_mark_node)
+ identifier = NULL_TREE;
+ }
+ else
+ identifier = NULL_TREE;
+
+ /* Create the template parameter. */
+ parameter = finish_template_template_parm (class_type_node,
+ identifier);
+
+ /* If the next token is an `=', then there is a
+ default-argument. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ {
+ bool is_template;
+
+ /* Consume the `='. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the id-expression. */
+ push_deferring_access_checks (dk_no_deferred);
+ /* save token before parsing the id-expression, for error
+ reporting */
+ token = cp_lexer_peek_token (parser->lexer);
+ default_argument
+ = cp_parser_id_expression (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/&is_template,
+ /*declarator_p=*/false,
+ /*optional_p=*/false);
+ if (TREE_CODE (default_argument) == TYPE_DECL)
+ /* If the id-expression was a template-id that refers to
+ a template-class, we already have the declaration here,
+ so no further lookup is needed. */
+ ;
+ else
+ /* Look up the name. */
+ default_argument
+ = cp_parser_lookup_name (parser, default_argument,
+ none_type,
+ /*is_template=*/is_template,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true,
+ /*ambiguous_decls=*/NULL,
+ token->location);
+ /* See if the default argument is valid. */
+ default_argument
+ = check_template_template_default_arg (default_argument);
+
+ /* Template parameter packs cannot have default
+ arguments. */
+ if (*is_parameter_pack)
+ {
+ if (identifier)
+ error_at (token->location,
+ "template parameter pack %qD cannot "
+ "have a default argument",
+ identifier);
+ else
+ error_at (token->location, "template parameter packs cannot "
+ "have default arguments");
+ default_argument = NULL_TREE;
+ }
+ pop_deferring_access_checks ();
+ }
+ else
+ default_argument = NULL_TREE;
+
+ /* Create the combined representation of the parameter and the
+ default argument. */
+ parameter = build_tree_list (default_argument, parameter);
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ break;
+ }
+
+ return parameter;
+}
+
+/* Parse a template-id.
+
+ template-id:
+ template-name < template-argument-list [opt] >
+
+ If TEMPLATE_KEYWORD_P is TRUE, then we have just seen the
+ `template' keyword. In this case, a TEMPLATE_ID_EXPR will be
+ returned. Otherwise, if the template-name names a function, or set
+ of functions, returns a TEMPLATE_ID_EXPR. If the template-name
+ names a class, returns a TYPE_DECL for the specialization.
+
+ If CHECK_DEPENDENCY_P is FALSE, names are looked up in
+ uninstantiated templates. */
+
+static tree
+cp_parser_template_id (cp_parser *parser,
+ bool template_keyword_p,
+ bool check_dependency_p,
+ enum tag_types tag_type,
+ bool is_declaration)
+{
+ int i;
+ tree templ;
+ tree arguments;
+ tree template_id;
+ cp_token_position start_of_id = 0;
+ deferred_access_check *chk;
+ vec<deferred_access_check, va_gc> *access_check;
+ cp_token *next_token = NULL, *next_token_2 = NULL;
+ bool is_identifier;
+
+ /* If the next token corresponds to a template-id, there is no need
+ to reparse it. */
+ next_token = cp_lexer_peek_token (parser->lexer);
+ if (next_token->type == CPP_TEMPLATE_ID)
+ {
+ struct tree_check *check_value;
+
+ /* Get the stored value. */
+ check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
+ /* Perform any access checks that were deferred. */
+ access_check = check_value->checks;
+ if (access_check)
+ {
+ FOR_EACH_VEC_ELT (*access_check, i, chk)
+ perform_or_defer_access_check (chk->binfo,
+ chk->decl,
+ chk->diag_decl,
+ tf_warning_or_error);
+ }
+ /* Return the stored value. */
+ return check_value->value;
+ }
+
+ /* Avoid performing name lookup if there is no possibility of
+ finding a template-id. */
+ if ((next_token->type != CPP_NAME && next_token->keyword != RID_OPERATOR)
+ || (next_token->type == CPP_NAME
+ && !cp_parser_nth_token_starts_template_argument_list_p
+ (parser, 2)))
+ {
+ cp_parser_error (parser, "expected template-id");
+ return error_mark_node;
+ }
+
+ /* Remember where the template-id starts. */
+ if (cp_parser_uncommitted_to_tentative_parse_p (parser))
+ start_of_id = cp_lexer_token_position (parser->lexer, false);
+
+ push_deferring_access_checks (dk_deferred);
+
+ /* Parse the template-name. */
+ is_identifier = false;
+ templ = cp_parser_template_name (parser, template_keyword_p,
+ check_dependency_p,
+ is_declaration,
+ tag_type,
+ &is_identifier);
+ if (templ == error_mark_node || is_identifier)
+ {
+ pop_deferring_access_checks ();
+ return templ;
+ }
+
+ /* If we find the sequence `[:' after a template-name, it's probably
+ a digraph-typo for `< ::'. Substitute the tokens and check if we can
+ parse correctly the argument list. */
+ next_token = cp_lexer_peek_token (parser->lexer);
+ next_token_2 = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (next_token->type == CPP_OPEN_SQUARE
+ && next_token->flags & DIGRAPH
+ && next_token_2->type == CPP_COLON
+ && !(next_token_2->flags & PREV_WHITE))
+ {
+ cp_parser_parse_tentatively (parser);
+ /* Change `:' into `::'. */
+ next_token_2->type = CPP_SCOPE;
+ /* Consume the first token (CPP_OPEN_SQUARE - which we pretend it is
+ CPP_LESS. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Parse the arguments. */
+ arguments = cp_parser_enclosed_template_argument_list (parser);
+ if (!cp_parser_parse_definitely (parser))
+ {
+ /* If we couldn't parse an argument list, then we revert our changes
+ and return simply an error. Maybe this is not a template-id
+ after all. */
+ next_token_2->type = CPP_COLON;
+ cp_parser_error (parser, "expected %<<%>");
+ pop_deferring_access_checks ();
+ return error_mark_node;
+ }
+ /* Otherwise, emit an error about the invalid digraph, but continue
+ parsing because we got our argument list. */
+ if (permerror (next_token->location,
+ "%<<::%> cannot begin a template-argument list"))
+ {
+ static bool hint = false;
+ inform (next_token->location,
+ "%<<:%> is an alternate spelling for %<[%>."
+ " Insert whitespace between %<<%> and %<::%>");
+ if (!hint && !flag_permissive)
+ {
+ inform (next_token->location, "(if you use %<-fpermissive%> "
+ "or %<-std=c++11%>, or %<-std=gnu++11%> G++ will "
+ "accept your code)");
+ hint = true;
+ }
+ }
+ }
+ else
+ {
+ /* Look for the `<' that starts the template-argument-list. */
+ if (!cp_parser_require (parser, CPP_LESS, RT_LESS))
+ {
+ pop_deferring_access_checks ();
+ return error_mark_node;
+ }
+ /* Parse the arguments. */
+ arguments = cp_parser_enclosed_template_argument_list (parser);
+ }
+
+ /* Build a representation of the specialization. */
+ if (identifier_p (templ))
+ template_id = build_min_nt_loc (next_token->location,
+ TEMPLATE_ID_EXPR,
+ templ, arguments);
+ else if (DECL_TYPE_TEMPLATE_P (templ)
+ || DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
+ {
+ bool entering_scope;
+ /* In "template <typename T> ... A<T>::", A<T> is the abstract A
+ template (rather than some instantiation thereof) only if
+ is not nested within some other construct. For example, in
+ "template <typename T> void f(T) { A<T>::", A<T> is just an
+ instantiation of A. */
+ entering_scope = (template_parm_scope_p ()
+ && cp_lexer_next_token_is (parser->lexer,
+ CPP_SCOPE));
+ template_id
+ = finish_template_type (templ, arguments, entering_scope);
+ }
+ else
+ {
+ /* If it's not a class-template or a template-template, it should be
+ a function-template. */
+ gcc_assert ((DECL_FUNCTION_TEMPLATE_P (templ)
+ || TREE_CODE (templ) == OVERLOAD
+ || BASELINK_P (templ)));
+
+ template_id = lookup_template_function (templ, arguments);
+ }
+
+ /* If parsing tentatively, replace the sequence of tokens that makes
+ up the template-id with a CPP_TEMPLATE_ID token. That way,
+ should we re-parse the token stream, we will not have to repeat
+ the effort required to do the parse, nor will we issue duplicate
+ error messages about problems during instantiation of the
+ template. */
+ if (start_of_id
+ /* Don't do this if we had a parse error in a declarator; re-parsing
+ might succeed if a name changes meaning (60361). */
+ && !(cp_parser_error_occurred (parser)
+ && cp_parser_parsing_tentatively (parser)
+ && parser->in_declarator_p))
+ {
+ cp_token *token = cp_lexer_token_at (parser->lexer, start_of_id);
+
+ /* Reset the contents of the START_OF_ID token. */
+ token->type = CPP_TEMPLATE_ID;
+ /* Retrieve any deferred checks. Do not pop this access checks yet
+ so the memory will not be reclaimed during token replacing below. */
+ token->u.tree_check_value = ggc_alloc_cleared_tree_check ();
+ token->u.tree_check_value->value = template_id;
+ token->u.tree_check_value->checks = get_deferred_access_checks ();
+ token->keyword = RID_MAX;
+
+ /* Purge all subsequent tokens. */
+ cp_lexer_purge_tokens_after (parser->lexer, start_of_id);
+
+ /* ??? Can we actually assume that, if template_id ==
+ error_mark_node, we will have issued a diagnostic to the
+ user, as opposed to simply marking the tentative parse as
+ failed? */
+ if (cp_parser_error_occurred (parser) && template_id != error_mark_node)
+ error_at (token->location, "parse error in template argument list");
+ }
+
+ pop_to_parent_deferring_access_checks ();
+ return template_id;
+}
+
+/* Parse a template-name.
+
+ template-name:
+ identifier
+
+ The standard should actually say:
+
+ template-name:
+ identifier
+ operator-function-id
+
+ A defect report has been filed about this issue.
+
+ A conversion-function-id cannot be a template name because they cannot
+ be part of a template-id. In fact, looking at this code:
+
+ a.operator K<int>()
+
+ the conversion-function-id is "operator K<int>", and K<int> is a type-id.
+ It is impossible to call a templated conversion-function-id with an
+ explicit argument list, since the only allowed template parameter is
+ the type to which it is converting.
+
+ If TEMPLATE_KEYWORD_P is true, then we have just seen the
+ `template' keyword, in a construction like:
+
+ T::template f<3>()
+
+ In that case `f' is taken to be a template-name, even though there
+ is no way of knowing for sure.
+
+ Returns the TEMPLATE_DECL for the template, or an OVERLOAD if the
+ name refers to a set of overloaded functions, at least one of which
+ is a template, or an IDENTIFIER_NODE with the name of the template,
+ if TEMPLATE_KEYWORD_P is true. If CHECK_DEPENDENCY_P is FALSE,
+ names are looked up inside uninstantiated templates. */
+
+static tree
+cp_parser_template_name (cp_parser* parser,
+ bool template_keyword_p,
+ bool check_dependency_p,
+ bool is_declaration,
+ enum tag_types tag_type,
+ bool *is_identifier)
+{
+ tree identifier;
+ tree decl;
+ tree fns;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* If the next token is `operator', then we have either an
+ operator-function-id or a conversion-function-id. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_OPERATOR))
+ {
+ /* We don't know whether we're looking at an
+ operator-function-id or a conversion-function-id. */
+ cp_parser_parse_tentatively (parser);
+ /* Try an operator-function-id. */
+ identifier = cp_parser_operator_function_id (parser);
+ /* If that didn't work, try a conversion-function-id. */
+ if (!cp_parser_parse_definitely (parser))
+ {
+ cp_parser_error (parser, "expected template-name");
+ return error_mark_node;
+ }
+ }
+ /* Look for the identifier. */
+ else
+ identifier = cp_parser_identifier (parser);
+
+ /* If we didn't find an identifier, we don't have a template-id. */
+ if (identifier == error_mark_node)
+ return error_mark_node;
+
+ /* If the name immediately followed the `template' keyword, then it
+ is a template-name. However, if the next token is not `<', then
+ we do not treat it as a template-name, since it is not being used
+ as part of a template-id. This enables us to handle constructs
+ like:
+
+ template <typename T> struct S { S(); };
+ template <typename T> S<T>::S();
+
+ correctly. We would treat `S' as a template -- if it were `S<T>'
+ -- but we do not if there is no `<'. */
+
+ if (processing_template_decl
+ && cp_parser_nth_token_starts_template_argument_list_p (parser, 1))
+ {
+ /* In a declaration, in a dependent context, we pretend that the
+ "template" keyword was present in order to improve error
+ recovery. For example, given:
+
+ template <typename T> void f(T::X<int>);
+
+ we want to treat "X<int>" as a template-id. */
+ if (is_declaration
+ && !template_keyword_p
+ && parser->scope && TYPE_P (parser->scope)
+ && check_dependency_p
+ && dependent_scope_p (parser->scope)
+ /* Do not do this for dtors (or ctors), since they never
+ need the template keyword before their name. */
+ && !constructor_name_p (identifier, parser->scope))
+ {
+ cp_token_position start = 0;
+
+ /* Explain what went wrong. */
+ error_at (token->location, "non-template %qD used as template",
+ identifier);
+ inform (token->location, "use %<%T::template %D%> to indicate that it is a template",
+ parser->scope, identifier);
+ /* If parsing tentatively, find the location of the "<" token. */
+ if (cp_parser_simulate_error (parser))
+ start = cp_lexer_token_position (parser->lexer, true);
+ /* Parse the template arguments so that we can issue error
+ messages about them. */
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_enclosed_template_argument_list (parser);
+ /* Skip tokens until we find a good place from which to
+ continue parsing. */
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/true,
+ /*consume_paren=*/false);
+ /* If parsing tentatively, permanently remove the
+ template argument list. That will prevent duplicate
+ error messages from being issued about the missing
+ "template" keyword. */
+ if (start)
+ cp_lexer_purge_tokens_after (parser->lexer, start);
+ if (is_identifier)
+ *is_identifier = true;
+ return identifier;
+ }
+
+ /* If the "template" keyword is present, then there is generally
+ no point in doing name-lookup, so we just return IDENTIFIER.
+ But, if the qualifying scope is non-dependent then we can
+ (and must) do name-lookup normally. */
+ if (template_keyword_p
+ && (!parser->scope
+ || (TYPE_P (parser->scope)
+ && dependent_type_p (parser->scope))))
+ return identifier;
+ }
+
+ /* Look up the name. */
+ decl = cp_parser_lookup_name (parser, identifier,
+ tag_type,
+ /*is_template=*/true,
+ /*is_namespace=*/false,
+ check_dependency_p,
+ /*ambiguous_decls=*/NULL,
+ token->location);
+
+ /* If DECL is a template, then the name was a template-name. */
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ ;
+ else
+ {
+ tree fn = NULL_TREE;
+
+ /* The standard does not explicitly indicate whether a name that
+ names a set of overloaded declarations, some of which are
+ templates, is a template-name. However, such a name should
+ be a template-name; otherwise, there is no way to form a
+ template-id for the overloaded templates. */
+ fns = BASELINK_P (decl) ? BASELINK_FUNCTIONS (decl) : decl;
+ if (TREE_CODE (fns) == OVERLOAD)
+ for (fn = fns; fn; fn = OVL_NEXT (fn))
+ if (TREE_CODE (OVL_CURRENT (fn)) == TEMPLATE_DECL)
+ break;
+
+ if (!fn)
+ {
+ /* The name does not name a template. */
+ cp_parser_error (parser, "expected template-name");
+ return error_mark_node;
+ }
+ }
+
+ /* If DECL is dependent, and refers to a function, then just return
+ its name; we will look it up again during template instantiation. */
+ if (DECL_FUNCTION_TEMPLATE_P (decl) || !DECL_P (decl))
+ {
+ tree scope = ovl_scope (decl);
+ if (TYPE_P (scope) && dependent_type_p (scope))
+ return identifier;
+ }
+
+ return decl;
+}
+
+/* Parse a template-argument-list.
+
+ template-argument-list:
+ template-argument ... [opt]
+ template-argument-list , template-argument ... [opt]
+
+ Returns a TREE_VEC containing the arguments. */
+
+static tree
+cp_parser_template_argument_list (cp_parser* parser)
+{
+ tree fixed_args[10];
+ unsigned n_args = 0;
+ unsigned alloced = 10;
+ tree *arg_ary = fixed_args;
+ tree vec;
+ bool saved_in_template_argument_list_p;
+ bool saved_ice_p;
+ bool saved_non_ice_p;
+
+ saved_in_template_argument_list_p = parser->in_template_argument_list_p;
+ parser->in_template_argument_list_p = true;
+ /* Even if the template-id appears in an integral
+ constant-expression, the contents of the argument list do
+ not. */
+ saved_ice_p = parser->integral_constant_expression_p;
+ parser->integral_constant_expression_p = false;
+ saved_non_ice_p = parser->non_integral_constant_expression_p;
+ parser->non_integral_constant_expression_p = false;
+
+ /* Parse the arguments. */
+ do
+ {
+ tree argument;
+
+ if (n_args)
+ /* Consume the comma. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Parse the template-argument. */
+ argument = cp_parser_template_argument (parser);
+
+ /* If the next token is an ellipsis, we're expanding a template
+ argument pack. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ if (argument == error_mark_node)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ error_at (token->location,
+ "expected parameter pack before %<...%>");
+ }
+ /* Consume the `...' token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Make the argument into a TYPE_PACK_EXPANSION or
+ EXPR_PACK_EXPANSION. */
+ argument = make_pack_expansion (argument);
+ }
+
+ if (n_args == alloced)
+ {
+ alloced *= 2;
+
+ if (arg_ary == fixed_args)
+ {
+ arg_ary = XNEWVEC (tree, alloced);
+ memcpy (arg_ary, fixed_args, sizeof (tree) * n_args);
+ }
+ else
+ arg_ary = XRESIZEVEC (tree, arg_ary, alloced);
+ }
+ arg_ary[n_args++] = argument;
+ }
+ while (cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
+
+ vec = make_tree_vec (n_args);
+
+ while (n_args--)
+ TREE_VEC_ELT (vec, n_args) = arg_ary[n_args];
+
+ if (arg_ary != fixed_args)
+ free (arg_ary);
+ parser->non_integral_constant_expression_p = saved_non_ice_p;
+ parser->integral_constant_expression_p = saved_ice_p;
+ parser->in_template_argument_list_p = saved_in_template_argument_list_p;
+#ifdef ENABLE_CHECKING
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
+#endif
+ return vec;
+}
+
+/* Parse a template-argument.
+
+ template-argument:
+ assignment-expression
+ type-id
+ id-expression
+
+ The representation is that of an assignment-expression, type-id, or
+ id-expression -- except that the qualified id-expression is
+ evaluated, so that the value returned is either a DECL or an
+ OVERLOAD.
+
+ Although the standard says "assignment-expression", it forbids
+ throw-expressions or assignments in the template argument.
+ Therefore, we use "conditional-expression" instead. */
+
+static tree
+cp_parser_template_argument (cp_parser* parser)
+{
+ tree argument;
+ bool template_p;
+ bool address_p;
+ bool maybe_type_id = false;
+ cp_token *token = NULL, *argument_start_token = NULL;
+ location_t loc = 0;
+ cp_id_kind idk;
+
+ /* There's really no way to know what we're looking at, so we just
+ try each alternative in order.
+
+ [temp.arg]
+
+ In a template-argument, an ambiguity between a type-id and an
+ expression is resolved to a type-id, regardless of the form of
+ the corresponding template-parameter.
+
+ Therefore, we try a type-id first. */
+ cp_parser_parse_tentatively (parser);
+ argument = cp_parser_template_type_arg (parser);
+ /* If there was no error parsing the type-id but the next token is a
+ '>>', our behavior depends on which dialect of C++ we're
+ parsing. In C++98, we probably found a typo for '> >'. But there
+ are type-id which are also valid expressions. For instance:
+
+ struct X { int operator >> (int); };
+ template <int V> struct Foo {};
+ Foo<X () >> 5> r;
+
+ Here 'X()' is a valid type-id of a function type, but the user just
+ wanted to write the expression "X() >> 5". Thus, we remember that we
+ found a valid type-id, but we still try to parse the argument as an
+ expression to see what happens.
+
+ In C++0x, the '>>' will be considered two separate '>'
+ tokens. */
+ if (!cp_parser_error_occurred (parser)
+ && cxx_dialect == cxx98
+ && cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
+ {
+ maybe_type_id = true;
+ cp_parser_abort_tentative_parse (parser);
+ }
+ else
+ {
+ /* If the next token isn't a `,' or a `>', then this argument wasn't
+ really finished. This means that the argument is not a valid
+ type-id. */
+ if (!cp_parser_next_token_ends_template_argument_p (parser))
+ cp_parser_error (parser, "expected template-argument");
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return argument;
+ }
+ /* We're still not sure what the argument will be. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a template. */
+ argument_start_token = cp_lexer_peek_token (parser->lexer);
+ argument = cp_parser_id_expression (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ &template_p,
+ /*declarator_p=*/false,
+ /*optional_p=*/false);
+ /* If the next token isn't a `,' or a `>', then this argument wasn't
+ really finished. */
+ if (!cp_parser_next_token_ends_template_argument_p (parser))
+ cp_parser_error (parser, "expected template-argument");
+ if (!cp_parser_error_occurred (parser))
+ {
+ /* Figure out what is being referred to. If the id-expression
+ was for a class template specialization, then we will have a
+ TYPE_DECL at this point. There is no need to do name lookup
+ at this point in that case. */
+ if (TREE_CODE (argument) != TYPE_DECL)
+ argument = cp_parser_lookup_name (parser, argument,
+ none_type,
+ /*is_template=*/template_p,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true,
+ /*ambiguous_decls=*/NULL,
+ argument_start_token->location);
+ if (TREE_CODE (argument) != TEMPLATE_DECL
+ && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
+ cp_parser_error (parser, "expected template-name");
+ }
+ if (cp_parser_parse_definitely (parser))
+ return argument;
+ /* It must be a non-type argument. There permitted cases are given
+ in [temp.arg.nontype]:
+
+ -- an integral constant-expression of integral or enumeration
+ type; or
+
+ -- the name of a non-type template-parameter; or
+
+ -- the name of an object or function with external linkage...
+
+ -- the address of an object or function with external linkage...
+
+ -- a pointer to member... */
+ /* Look for a non-type template parameter. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ cp_parser_parse_tentatively (parser);
+ argument = cp_parser_primary_expression (parser,
+ /*address_p=*/false,
+ /*cast_p=*/false,
+ /*template_arg_p=*/true,
+ &idk);
+ if (TREE_CODE (argument) != TEMPLATE_PARM_INDEX
+ || !cp_parser_next_token_ends_template_argument_p (parser))
+ cp_parser_simulate_error (parser);
+ if (cp_parser_parse_definitely (parser))
+ return argument;
+ }
+
+ /* If the next token is "&", the argument must be the address of an
+ object or function with external linkage. */
+ address_p = cp_lexer_next_token_is (parser->lexer, CPP_AND);
+ if (address_p)
+ {
+ loc = cp_lexer_peek_token (parser->lexer)->location;
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* See if we might have an id-expression. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_NAME
+ || token->keyword == RID_OPERATOR
+ || token->type == CPP_SCOPE
+ || token->type == CPP_TEMPLATE_ID
+ || token->type == CPP_NESTED_NAME_SPECIFIER)
+ {
+ cp_parser_parse_tentatively (parser);
+ argument = cp_parser_primary_expression (parser,
+ address_p,
+ /*cast_p=*/false,
+ /*template_arg_p=*/true,
+ &idk);
+ if (cp_parser_error_occurred (parser)
+ || !cp_parser_next_token_ends_template_argument_p (parser))
+ cp_parser_abort_tentative_parse (parser);
+ else
+ {
+ tree probe;
+
+ if (INDIRECT_REF_P (argument))
+ {
+ /* Strip the dereference temporarily. */
+ gcc_assert (REFERENCE_REF_P (argument));
+ argument = TREE_OPERAND (argument, 0);
+ }
+
+ /* If we're in a template, we represent a qualified-id referring
+ to a static data member as a SCOPE_REF even if the scope isn't
+ dependent so that we can check access control later. */
+ probe = argument;
+ if (TREE_CODE (probe) == SCOPE_REF)
+ probe = TREE_OPERAND (probe, 1);
+ if (VAR_P (probe))
+ {
+ /* A variable without external linkage might still be a
+ valid constant-expression, so no error is issued here
+ if the external-linkage check fails. */
+ if (!address_p && !DECL_EXTERNAL_LINKAGE_P (probe))
+ cp_parser_simulate_error (parser);
+ }
+ else if (is_overloaded_fn (argument))
+ /* All overloaded functions are allowed; if the external
+ linkage test does not pass, an error will be issued
+ later. */
+ ;
+ else if (address_p
+ && (TREE_CODE (argument) == OFFSET_REF
+ || TREE_CODE (argument) == SCOPE_REF))
+ /* A pointer-to-member. */
+ ;
+ else if (TREE_CODE (argument) == TEMPLATE_PARM_INDEX)
+ ;
+ else
+ cp_parser_simulate_error (parser);
+
+ if (cp_parser_parse_definitely (parser))
+ {
+ if (address_p)
+ argument = build_x_unary_op (loc, ADDR_EXPR, argument,
+ tf_warning_or_error);
+ else
+ argument = convert_from_reference (argument);
+ return argument;
+ }
+ }
+ }
+ /* If the argument started with "&", there are no other valid
+ alternatives at this point. */
+ if (address_p)
+ {
+ cp_parser_error (parser, "invalid non-type template argument");
+ return error_mark_node;
+ }
+
+ /* If the argument wasn't successfully parsed as a type-id followed
+ by '>>', the argument can only be a constant expression now.
+ Otherwise, we try parsing the constant-expression tentatively,
+ because the argument could really be a type-id. */
+ if (maybe_type_id)
+ cp_parser_parse_tentatively (parser);
+ argument = cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/false,
+ /*non_constant_p=*/NULL);
+ if (!maybe_type_id)
+ return argument;
+ if (!cp_parser_next_token_ends_template_argument_p (parser))
+ cp_parser_error (parser, "expected template-argument");
+ if (cp_parser_parse_definitely (parser))
+ return argument;
+ /* We did our best to parse the argument as a non type-id, but that
+ was the only alternative that matched (albeit with a '>' after
+ it). We can assume it's just a typo from the user, and a
+ diagnostic will then be issued. */
+ return cp_parser_template_type_arg (parser);
+}
+
+/* Parse an explicit-instantiation.
+
+ explicit-instantiation:
+ template declaration
+
+ Although the standard says `declaration', what it really means is:
+
+ explicit-instantiation:
+ template decl-specifier-seq [opt] declarator [opt] ;
+
+ Things like `template int S<int>::i = 5, int S<double>::j;' are not
+ supposed to be allowed. A defect report has been filed about this
+ issue.
+
+ GNU Extension:
+
+ explicit-instantiation:
+ storage-class-specifier template
+ decl-specifier-seq [opt] declarator [opt] ;
+ function-specifier template
+ decl-specifier-seq [opt] declarator [opt] ; */
+
+static void
+cp_parser_explicit_instantiation (cp_parser* parser)
+{
+ int declares_class_or_enum;
+ cp_decl_specifier_seq decl_specifiers;
+ tree extension_specifier = NULL_TREE;
+
+ timevar_push (TV_TEMPLATE_INST);
+
+ /* Look for an (optional) storage-class-specifier or
+ function-specifier. */
+ if (cp_parser_allow_gnu_extensions_p (parser))
+ {
+ extension_specifier
+ = cp_parser_storage_class_specifier_opt (parser);
+ if (!extension_specifier)
+ extension_specifier
+ = cp_parser_function_specifier_opt (parser,
+ /*decl_specs=*/NULL);
+ }
+
+ /* Look for the `template' keyword. */
+ cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE);
+ /* Let the front end know that we are processing an explicit
+ instantiation. */
+ begin_explicit_instantiation ();
+ /* [temp.explicit] says that we are supposed to ignore access
+ control while processing explicit instantiation directives. */
+ push_deferring_access_checks (dk_no_check);
+ /* Parse a decl-specifier-seq. */
+ cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_OPTIONAL,
+ &decl_specifiers,
+ &declares_class_or_enum);
+ /* If there was exactly one decl-specifier, and it declared a class,
+ and there's no declarator, then we have an explicit type
+ instantiation. */
+ if (declares_class_or_enum && cp_parser_declares_only_class_p (parser))
+ {
+ tree type;
+
+ type = check_tag_decl (&decl_specifiers,
+ /*explicit_type_instantiation_p=*/true);
+ /* Turn access control back on for names used during
+ template instantiation. */
+ pop_deferring_access_checks ();
+ if (type)
+ do_type_instantiation (type, extension_specifier,
+ /*complain=*/tf_error);
+ }
+ else
+ {
+ cp_declarator *declarator;
+ tree decl;
+
+ /* Parse the declarator. */
+ declarator
+ = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
+ if (declares_class_or_enum & 2)
+ cp_parser_check_for_definition_in_return_type (declarator,
+ decl_specifiers.type,
+ decl_specifiers.locations[ds_type_spec]);
+ if (declarator != cp_error_declarator)
+ {
+ if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_inline))
+ permerror (decl_specifiers.locations[ds_inline],
+ "explicit instantiation shall not use"
+ " %<inline%> specifier");
+ if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_constexpr))
+ permerror (decl_specifiers.locations[ds_constexpr],
+ "explicit instantiation shall not use"
+ " %<constexpr%> specifier");
+
+ decl = grokdeclarator (declarator, &decl_specifiers,
+ NORMAL, 0, &decl_specifiers.attributes);
+ /* Turn access control back on for names used during
+ template instantiation. */
+ pop_deferring_access_checks ();
+ /* Do the explicit instantiation. */
+ do_decl_instantiation (decl, extension_specifier);
+ }
+ else
+ {
+ pop_deferring_access_checks ();
+ /* Skip the body of the explicit instantiation. */
+ cp_parser_skip_to_end_of_statement (parser);
+ }
+ }
+ /* We're done with the instantiation. */
+ end_explicit_instantiation ();
+
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+
+ timevar_pop (TV_TEMPLATE_INST);
+}
+
+/* Parse an explicit-specialization.
+
+ explicit-specialization:
+ template < > declaration
+
+ Although the standard says `declaration', what it really means is:
+
+ explicit-specialization:
+ template <> decl-specifier [opt] init-declarator [opt] ;
+ template <> function-definition
+ template <> explicit-specialization
+ template <> template-declaration */
+
+static void
+cp_parser_explicit_specialization (cp_parser* parser)
+{
+ bool need_lang_pop;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* Look for the `template' keyword. */
+ cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE);
+ /* Look for the `<'. */
+ cp_parser_require (parser, CPP_LESS, RT_LESS);
+ /* Look for the `>'. */
+ cp_parser_require (parser, CPP_GREATER, RT_GREATER);
+ /* We have processed another parameter list. */
+ ++parser->num_template_parameter_lists;
+ /* [temp]
+
+ A template ... explicit specialization ... shall not have C
+ linkage. */
+ if (current_lang_name == lang_name_c)
+ {
+ error_at (token->location, "template specialization with C linkage");
+ /* Give it C++ linkage to avoid confusing other parts of the
+ front end. */
+ push_lang_context (lang_name_cplusplus);
+ need_lang_pop = true;
+ }
+ else
+ need_lang_pop = false;
+ /* Let the front end know that we are beginning a specialization. */
+ if (!begin_specialization ())
+ {
+ end_specialization ();
+ return;
+ }
+
+ /* If the next keyword is `template', we need to figure out whether
+ or not we're looking a template-declaration. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
+ {
+ if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_LESS
+ && cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_GREATER)
+ cp_parser_template_declaration_after_export (parser,
+ /*member_p=*/false);
+ else
+ cp_parser_explicit_specialization (parser);
+ }
+ else
+ /* Parse the dependent declaration. */
+ cp_parser_single_declaration (parser,
+ /*checks=*/NULL,
+ /*member_p=*/false,
+ /*explicit_specialization_p=*/true,
+ /*friend_p=*/NULL);
+ /* We're done with the specialization. */
+ end_specialization ();
+ /* For the erroneous case of a template with C linkage, we pushed an
+ implicit C++ linkage scope; exit that scope now. */
+ if (need_lang_pop)
+ pop_lang_context ();
+ /* We're done with this parameter list. */
+ --parser->num_template_parameter_lists;
+}
+
+/* Parse a type-specifier.
+
+ type-specifier:
+ simple-type-specifier
+ class-specifier
+ enum-specifier
+ elaborated-type-specifier
+ cv-qualifier
+
+ GNU Extension:
+
+ type-specifier:
+ __complex__
+
+ Returns a representation of the type-specifier. For a
+ class-specifier, enum-specifier, or elaborated-type-specifier, a
+ TREE_TYPE is returned; otherwise, a TYPE_DECL is returned.
+
+ The parser flags FLAGS is used to control type-specifier parsing.
+
+ If IS_DECLARATION is TRUE, then this type-specifier is appearing
+ in a decl-specifier-seq.
+
+ If DECLARES_CLASS_OR_ENUM is non-NULL, and the type-specifier is a
+ class-specifier, enum-specifier, or elaborated-type-specifier, then
+ *DECLARES_CLASS_OR_ENUM is set to a nonzero value. The value is 1
+ if a type is declared; 2 if it is defined. Otherwise, it is set to
+ zero.
+
+ If IS_CV_QUALIFIER is non-NULL, and the type-specifier is a
+ cv-qualifier, then IS_CV_QUALIFIER is set to TRUE. Otherwise, it
+ is set to FALSE. */
+
+static tree
+cp_parser_type_specifier (cp_parser* parser,
+ cp_parser_flags flags,
+ cp_decl_specifier_seq *decl_specs,
+ bool is_declaration,
+ int* declares_class_or_enum,
+ bool* is_cv_qualifier)
+{
+ tree type_spec = NULL_TREE;
+ cp_token *token;
+ enum rid keyword;
+ cp_decl_spec ds = ds_last;
+
+ /* Assume this type-specifier does not declare a new type. */
+ if (declares_class_or_enum)
+ *declares_class_or_enum = 0;
+ /* And that it does not specify a cv-qualifier. */
+ if (is_cv_qualifier)
+ *is_cv_qualifier = false;
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* If we're looking at a keyword, we can use that to guide the
+ production we choose. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ case RID_ENUM:
+ if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
+ goto elaborated_type_specifier;
+
+ /* Look for the enum-specifier. */
+ type_spec = cp_parser_enum_specifier (parser);
+ /* If that worked, we're done. */
+ if (type_spec)
+ {
+ if (declares_class_or_enum)
+ *declares_class_or_enum = 2;
+ if (decl_specs)
+ cp_parser_set_decl_spec_type (decl_specs,
+ type_spec,
+ token,
+ /*type_definition_p=*/true);
+ return type_spec;
+ }
+ else
+ goto elaborated_type_specifier;
+
+ /* Any of these indicate either a class-specifier, or an
+ elaborated-type-specifier. */
+ case RID_CLASS:
+ case RID_STRUCT:
+ case RID_UNION:
+ if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
+ goto elaborated_type_specifier;
+
+ /* Parse tentatively so that we can back up if we don't find a
+ class-specifier. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for the class-specifier. */
+ type_spec = cp_parser_class_specifier (parser);
+ invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, type_spec);
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ if (declares_class_or_enum)
+ *declares_class_or_enum = 2;
+ if (decl_specs)
+ cp_parser_set_decl_spec_type (decl_specs,
+ type_spec,
+ token,
+ /*type_definition_p=*/true);
+ return type_spec;
+ }
+
+ /* Fall through. */
+ elaborated_type_specifier:
+ /* We're declaring (not defining) a class or enum. */
+ if (declares_class_or_enum)
+ *declares_class_or_enum = 1;
+
+ /* Fall through. */
+ case RID_TYPENAME:
+ /* Look for an elaborated-type-specifier. */
+ type_spec
+ = (cp_parser_elaborated_type_specifier
+ (parser,
+ decl_spec_seq_has_spec_p (decl_specs, ds_friend),
+ is_declaration));
+ if (decl_specs)
+ cp_parser_set_decl_spec_type (decl_specs,
+ type_spec,
+ token,
+ /*type_definition_p=*/false);
+ return type_spec;
+
+ case RID_CONST:
+ ds = ds_const;
+ if (is_cv_qualifier)
+ *is_cv_qualifier = true;
+ break;
+
+ case RID_VOLATILE:
+ ds = ds_volatile;
+ if (is_cv_qualifier)
+ *is_cv_qualifier = true;
+ break;
+
+ case RID_RESTRICT:
+ ds = ds_restrict;
+ if (is_cv_qualifier)
+ *is_cv_qualifier = true;
+ break;
+
+ case RID_COMPLEX:
+ /* The `__complex__' keyword is a GNU extension. */
+ ds = ds_complex;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Handle simple keywords. */
+ if (ds != ds_last)
+ {
+ if (decl_specs)
+ {
+ set_and_check_decl_spec_loc (decl_specs, ds, token);
+ decl_specs->any_specifiers_p = true;
+ }
+ return cp_lexer_consume_token (parser->lexer)->u.value;
+ }
+
+ /* If we do not already have a type-specifier, assume we are looking
+ at a simple-type-specifier. */
+ type_spec = cp_parser_simple_type_specifier (parser,
+ decl_specs,
+ flags);
+
+ /* If we didn't find a type-specifier, and a type-specifier was not
+ optional in this context, issue an error message. */
+ if (!type_spec && !(flags & CP_PARSER_FLAGS_OPTIONAL))
+ {
+ cp_parser_error (parser, "expected type specifier");
+ return error_mark_node;
+ }
+
+ return type_spec;
+}
+
+/* Parse a simple-type-specifier.
+
+ simple-type-specifier:
+ :: [opt] nested-name-specifier [opt] type-name
+ :: [opt] nested-name-specifier template template-id
+ char
+ wchar_t
+ bool
+ short
+ int
+ long
+ signed
+ unsigned
+ float
+ double
+ void
+
+ C++0x Extension:
+
+ simple-type-specifier:
+ auto
+ decltype ( expression )
+ char16_t
+ char32_t
+ __underlying_type ( type-id )
+
+ GNU Extension:
+
+ simple-type-specifier:
+ __int128
+ __typeof__ unary-expression
+ __typeof__ ( type-id )
+ __typeof__ ( type-id ) { initializer-list , [opt] }
+
+ Returns the indicated TYPE_DECL. If DECL_SPECS is not NULL, it is
+ appropriately updated. */
+
+static tree
+cp_parser_simple_type_specifier (cp_parser* parser,
+ cp_decl_specifier_seq *decl_specs,
+ cp_parser_flags flags)
+{
+ tree type = NULL_TREE;
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* If we're looking at a keyword, things are easy. */
+ switch (token->keyword)
+ {
+ case RID_CHAR:
+ if (decl_specs)
+ decl_specs->explicit_char_p = true;
+ type = char_type_node;
+ break;
+ case RID_CHAR16:
+ type = char16_type_node;
+ break;
+ case RID_CHAR32:
+ type = char32_type_node;
+ break;
+ case RID_WCHAR:
+ type = wchar_type_node;
+ break;
+ case RID_BOOL:
+ type = boolean_type_node;
+ break;
+ case RID_SHORT:
+ set_and_check_decl_spec_loc (decl_specs, ds_short, token);
+ type = short_integer_type_node;
+ break;
+ case RID_INT:
+ if (decl_specs)
+ decl_specs->explicit_int_p = true;
+ type = integer_type_node;
+ break;
+ case RID_INT128:
+ if (!int128_integer_type_node)
+ break;
+ if (decl_specs)
+ decl_specs->explicit_int128_p = true;
+ type = int128_integer_type_node;
+ break;
+ case RID_LONG:
+ if (decl_specs)
+ set_and_check_decl_spec_loc (decl_specs, ds_long, token);
+ type = long_integer_type_node;
+ break;
+ case RID_SIGNED:
+ set_and_check_decl_spec_loc (decl_specs, ds_signed, token);
+ type = integer_type_node;
+ break;
+ case RID_UNSIGNED:
+ set_and_check_decl_spec_loc (decl_specs, ds_unsigned, token);
+ type = unsigned_type_node;
+ break;
+ case RID_FLOAT:
+ type = float_type_node;
+ break;
+ case RID_DOUBLE:
+ type = double_type_node;
+ break;
+ case RID_VOID:
+ type = void_type_node;
+ break;
+
+ case RID_AUTO:
+ maybe_warn_cpp0x (CPP0X_AUTO);
+ if (parser->auto_is_implicit_function_template_parm_p)
+ {
+ type = synthesize_implicit_template_parm (parser);
+
+ if (current_class_type && LAMBDA_TYPE_P (current_class_type))
+ {
+ if (cxx_dialect < cxx1y)
+ pedwarn (location_of (type), 0,
+ "use of %<auto%> in lambda parameter declaration "
+ "only available with "
+ "-std=c++1y or -std=gnu++1y");
+ }
+ else if (cxx_dialect < cxx1y)
+ pedwarn (location_of (type), 0,
+ "use of %<auto%> in parameter declaration "
+ "only available with "
+ "-std=c++1y or -std=gnu++1y");
+ else
+ pedwarn (location_of (type), OPT_Wpedantic,
+ "ISO C++ forbids use of %<auto%> in parameter "
+ "declaration");
+ }
+ else
+ type = make_auto ();
+ break;
+
+ case RID_DECLTYPE:
+ /* Since DR 743, decltype can either be a simple-type-specifier by
+ itself or begin a nested-name-specifier. Parsing it will replace
+ it with a CPP_DECLTYPE, so just rewind and let the CPP_DECLTYPE
+ handling below decide what to do. */
+ cp_parser_decltype (parser);
+ cp_lexer_set_token_position (parser->lexer, token);
+ break;
+
+ case RID_TYPEOF:
+ /* Consume the `typeof' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the operand to `typeof'. */
+ type = cp_parser_sizeof_operand (parser, RID_TYPEOF);
+ /* If it is not already a TYPE, take its type. */
+ if (!TYPE_P (type))
+ type = finish_typeof (type);
+
+ if (decl_specs)
+ cp_parser_set_decl_spec_type (decl_specs, type,
+ token,
+ /*type_definition_p=*/false);
+
+ return type;
+
+ case RID_UNDERLYING_TYPE:
+ type = cp_parser_trait_expr (parser, RID_UNDERLYING_TYPE);
+ if (decl_specs)
+ cp_parser_set_decl_spec_type (decl_specs, type,
+ token,
+ /*type_definition_p=*/false);
+
+ return type;
+
+ case RID_BASES:
+ case RID_DIRECT_BASES:
+ type = cp_parser_trait_expr (parser, token->keyword);
+ if (decl_specs)
+ cp_parser_set_decl_spec_type (decl_specs, type,
+ token,
+ /*type_definition_p=*/false);
+ return type;
+ default:
+ break;
+ }
+
+ /* If token is an already-parsed decltype not followed by ::,
+ it's a simple-type-specifier. */
+ if (token->type == CPP_DECLTYPE
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
+ {
+ type = token->u.value;
+ if (decl_specs)
+ cp_parser_set_decl_spec_type (decl_specs, type,
+ token,
+ /*type_definition_p=*/false);
+ cp_lexer_consume_token (parser->lexer);
+ return type;
+ }
+
+ /* If the type-specifier was for a built-in type, we're done. */
+ if (type)
+ {
+ /* Record the type. */
+ if (decl_specs
+ && (token->keyword != RID_SIGNED
+ && token->keyword != RID_UNSIGNED
+ && token->keyword != RID_SHORT
+ && token->keyword != RID_LONG))
+ cp_parser_set_decl_spec_type (decl_specs,
+ type,
+ token,
+ /*type_definition_p=*/false);
+ if (decl_specs)
+ decl_specs->any_specifiers_p = true;
+
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* There is no valid C++ program where a non-template type is
+ followed by a "<". That usually indicates that the user thought
+ that the type was a template. */
+ cp_parser_check_for_invalid_template_id (parser, type, none_type,
+ token->location);
+
+ return TYPE_NAME (type);
+ }
+
+ /* The type-specifier must be a user-defined type. */
+ if (!(flags & CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES))
+ {
+ bool qualified_p;
+ bool global_p;
+
+ /* Don't gobble tokens or issue error messages if this is an
+ optional type-specifier. */
+ if (flags & CP_PARSER_FLAGS_OPTIONAL)
+ cp_parser_parse_tentatively (parser);
+
+ /* Look for the optional `::' operator. */
+ global_p
+ = (cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+ /* Look for the nested-name specifier. */
+ qualified_p
+ = (cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/false)
+ != NULL_TREE);
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If we have seen a nested-name-specifier, and the next token
+ is `template', then we are using the template-id production. */
+ if (parser->scope
+ && cp_parser_optional_template_keyword (parser))
+ {
+ /* Look for the template-id. */
+ type = cp_parser_template_id (parser,
+ /*template_keyword_p=*/true,
+ /*check_dependency_p=*/true,
+ none_type,
+ /*is_declaration=*/false);
+ /* If the template-id did not name a type, we are out of
+ luck. */
+ if (TREE_CODE (type) != TYPE_DECL)
+ {
+ cp_parser_error (parser, "expected template-id for type");
+ type = NULL_TREE;
+ }
+ }
+ /* Otherwise, look for a type-name. */
+ else
+ type = cp_parser_type_name (parser);
+ /* Keep track of all name-lookups performed in class scopes. */
+ if (type
+ && !global_p
+ && !qualified_p
+ && TREE_CODE (type) == TYPE_DECL
+ && identifier_p (DECL_NAME (type)))
+ maybe_note_name_used_in_class (DECL_NAME (type), type);
+ /* If it didn't work out, we don't have a TYPE. */
+ if ((flags & CP_PARSER_FLAGS_OPTIONAL)
+ && !cp_parser_parse_definitely (parser))
+ type = NULL_TREE;
+ if (type && decl_specs)
+ cp_parser_set_decl_spec_type (decl_specs, type,
+ token,
+ /*type_definition_p=*/false);
+ }
+
+ /* If we didn't get a type-name, issue an error message. */
+ if (!type && !(flags & CP_PARSER_FLAGS_OPTIONAL))
+ {
+ cp_parser_error (parser, "expected type-name");
+ return error_mark_node;
+ }
+
+ if (type && type != error_mark_node)
+ {
+ /* See if TYPE is an Objective-C type, and if so, parse and
+ accept any protocol references following it. Do this before
+ the cp_parser_check_for_invalid_template_id() call, because
+ Objective-C types can be followed by '<...>' which would
+ enclose protocol names rather than template arguments, and so
+ everything is fine. */
+ if (c_dialect_objc () && !parser->scope
+ && (objc_is_id (type) || objc_is_class_name (type)))
+ {
+ tree protos = cp_parser_objc_protocol_refs_opt (parser);
+ tree qual_type = objc_get_protocol_qualified_type (type, protos);
+
+ /* Clobber the "unqualified" type previously entered into
+ DECL_SPECS with the new, improved protocol-qualified version. */
+ if (decl_specs)
+ decl_specs->type = qual_type;
+
+ return qual_type;
+ }
+
+ /* There is no valid C++ program where a non-template type is
+ followed by a "<". That usually indicates that the user
+ thought that the type was a template. */
+ cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type),
+ none_type,
+ token->location);
+ }
+
+ return type;
+}
+
+/* Parse a type-name.
+
+ type-name:
+ class-name
+ enum-name
+ typedef-name
+ simple-template-id [in c++0x]
+
+ enum-name:
+ identifier
+
+ typedef-name:
+ identifier
+
+ Returns a TYPE_DECL for the type. */
+
+static tree
+cp_parser_type_name (cp_parser* parser)
+{
+ tree type_decl;
+
+ /* We can't know yet whether it is a class-name or not. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a class-name. */
+ type_decl = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ none_type,
+ /*check_dependency_p=*/true,
+ /*class_head_p=*/false,
+ /*is_declaration=*/false);
+ /* If it's not a class-name, keep looking. */
+ if (!cp_parser_parse_definitely (parser))
+ {
+ if (cxx_dialect < cxx11)
+ /* It must be a typedef-name or an enum-name. */
+ return cp_parser_nonclass_name (parser);
+
+ cp_parser_parse_tentatively (parser);
+ /* It is either a simple-template-id representing an
+ instantiation of an alias template... */
+ type_decl = cp_parser_template_id (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ none_type,
+ /*is_declaration=*/false);
+ /* Note that this must be an instantiation of an alias template
+ because [temp.names]/6 says:
+
+ A template-id that names an alias template specialization
+ is a type-name.
+
+ Whereas [temp.names]/7 says:
+
+ A simple-template-id that names a class template
+ specialization is a class-name. */
+ if (type_decl != NULL_TREE
+ && TREE_CODE (type_decl) == TYPE_DECL
+ && TYPE_DECL_ALIAS_P (type_decl))
+ gcc_assert (DECL_TEMPLATE_INSTANTIATION (type_decl));
+ else
+ cp_parser_simulate_error (parser);
+
+ if (!cp_parser_parse_definitely (parser))
+ /* ... Or a typedef-name or an enum-name. */
+ return cp_parser_nonclass_name (parser);
+ }
+
+ return type_decl;
+}
+
+/* Parse a non-class type-name, that is, either an enum-name or a typedef-name.
+
+ enum-name:
+ identifier
+
+ typedef-name:
+ identifier
+
+ Returns a TYPE_DECL for the type. */
+
+static tree
+cp_parser_nonclass_name (cp_parser* parser)
+{
+ tree type_decl;
+ tree identifier;
+
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return error_mark_node;
+
+ /* Look up the type-name. */
+ type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
+
+ type_decl = strip_using_decl (type_decl);
+
+ if (TREE_CODE (type_decl) != TYPE_DECL
+ && (objc_is_id (identifier) || objc_is_class_name (identifier)))
+ {
+ /* See if this is an Objective-C type. */
+ tree protos = cp_parser_objc_protocol_refs_opt (parser);
+ tree type = objc_get_protocol_qualified_type (identifier, protos);
+ if (type)
+ type_decl = TYPE_NAME (type);
+ }
+
+ /* Issue an error if we did not find a type-name. */
+ if (TREE_CODE (type_decl) != TYPE_DECL
+ /* In Objective-C, we have the complication that class names are
+ normally type names and start declarations (eg, the
+ "NSObject" in "NSObject *object;"), but can be used in an
+ Objective-C 2.0 dot-syntax (as in "NSObject.version") which
+ is an expression. So, a classname followed by a dot is not a
+ valid type-name. */
+ || (objc_is_class_name (TREE_TYPE (type_decl))
+ && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT))
+ {
+ if (!cp_parser_simulate_error (parser))
+ cp_parser_name_lookup_error (parser, identifier, type_decl,
+ NLE_TYPE, token->location);
+ return error_mark_node;
+ }
+ /* Remember that the name was used in the definition of the
+ current class so that we can check later to see if the
+ meaning would have been different after the class was
+ entirely defined. */
+ else if (type_decl != error_mark_node
+ && !parser->scope)
+ maybe_note_name_used_in_class (identifier, type_decl);
+
+ return type_decl;
+}
+
+/* Parse an elaborated-type-specifier. Note that the grammar given
+ here incorporates the resolution to DR68.
+
+ elaborated-type-specifier:
+ class-key :: [opt] nested-name-specifier [opt] identifier
+ class-key :: [opt] nested-name-specifier [opt] template [opt] template-id
+ enum-key :: [opt] nested-name-specifier [opt] identifier
+ typename :: [opt] nested-name-specifier identifier
+ typename :: [opt] nested-name-specifier template [opt]
+ template-id
+
+ GNU extension:
+
+ elaborated-type-specifier:
+ class-key attributes :: [opt] nested-name-specifier [opt] identifier
+ class-key attributes :: [opt] nested-name-specifier [opt]
+ template [opt] template-id
+ enum attributes :: [opt] nested-name-specifier [opt] identifier
+
+ If IS_FRIEND is TRUE, then this elaborated-type-specifier is being
+ declared `friend'. If IS_DECLARATION is TRUE, then this
+ elaborated-type-specifier appears in a decl-specifiers-seq, i.e.,
+ something is being declared.
+
+ Returns the TYPE specified. */
+
+static tree
+cp_parser_elaborated_type_specifier (cp_parser* parser,
+ bool is_friend,
+ bool is_declaration)
+{
+ enum tag_types tag_type;
+ tree identifier;
+ tree type = NULL_TREE;
+ tree attributes = NULL_TREE;
+ tree globalscope;
+ cp_token *token = NULL;
+
+ /* See if we're looking at the `enum' keyword. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM))
+ {
+ /* Consume the `enum' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Remember that it's an enumeration type. */
+ tag_type = enum_type;
+ /* Issue a warning if the `struct' or `class' key (for C++0x scoped
+ enums) is used here. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_CLASS)
+ || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
+ {
+ pedwarn (input_location, 0, "elaborated-type-specifier "
+ "for a scoped enum must not use the %<%D%> keyword",
+ cp_lexer_peek_token (parser->lexer)->u.value);
+ /* Consume the `struct' or `class' and parse it anyway. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
+ }
+ /* Or, it might be `typename'. */
+ else if (cp_lexer_next_token_is_keyword (parser->lexer,
+ RID_TYPENAME))
+ {
+ /* Consume the `typename' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Remember that it's a `typename' type. */
+ tag_type = typename_type;
+ }
+ /* Otherwise it must be a class-key. */
+ else
+ {
+ tag_type = cp_parser_class_key (parser);
+ if (tag_type == none_type)
+ return error_mark_node;
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
+ }
+
+ /* Look for the `::' operator. */
+ globalscope = cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false);
+ /* Look for the nested-name-specifier. */
+ if (tag_type == typename_type && !globalscope)
+ {
+ if (!cp_parser_nested_name_specifier (parser,
+ /*typename_keyword_p=*/true,
+ /*check_dependency_p=*/true,
+ /*type_p=*/true,
+ is_declaration))
+ return error_mark_node;
+ }
+ else
+ /* Even though `typename' is not present, the proposed resolution
+ to Core Issue 180 says that in `class A<T>::B', `B' should be
+ considered a type-name, even if `A<T>' is dependent. */
+ cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/true,
+ /*check_dependency_p=*/true,
+ /*type_p=*/true,
+ is_declaration);
+ /* For everything but enumeration types, consider a template-id.
+ For an enumeration type, consider only a plain identifier. */
+ if (tag_type != enum_type)
+ {
+ bool template_p = false;
+ tree decl;
+
+ /* Allow the `template' keyword. */
+ template_p = cp_parser_optional_template_keyword (parser);
+ /* If we didn't see `template', we don't know if there's a
+ template-id or not. */
+ if (!template_p)
+ cp_parser_parse_tentatively (parser);
+ /* Parse the template-id. */
+ token = cp_lexer_peek_token (parser->lexer);
+ decl = cp_parser_template_id (parser, template_p,
+ /*check_dependency_p=*/true,
+ tag_type,
+ is_declaration);
+ /* If we didn't find a template-id, look for an ordinary
+ identifier. */
+ if (!template_p && !cp_parser_parse_definitely (parser))
+ ;
+ /* If DECL is a TEMPLATE_ID_EXPR, and the `typename' keyword is
+ in effect, then we must assume that, upon instantiation, the
+ template will correspond to a class. */
+ else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
+ && tag_type == typename_type)
+ type = make_typename_type (parser->scope, decl,
+ typename_type,
+ /*complain=*/tf_error);
+ /* If the `typename' keyword is in effect and DECL is not a type
+ decl, then type is non existent. */
+ else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
+ ;
+ else if (TREE_CODE (decl) == TYPE_DECL)
+ type = check_elaborated_type_specifier (tag_type, decl,
+ /*allow_template_p=*/true);
+ else if (decl == error_mark_node)
+ type = error_mark_node;
+ }
+
+ if (!type)
+ {
+ token = cp_lexer_peek_token (parser->lexer);
+ identifier = cp_parser_identifier (parser);
+
+ if (identifier == error_mark_node)
+ {
+ parser->scope = NULL_TREE;
+ return error_mark_node;
+ }
+
+ /* For a `typename', we needn't call xref_tag. */
+ if (tag_type == typename_type
+ && TREE_CODE (parser->scope) != NAMESPACE_DECL)
+ return cp_parser_make_typename_type (parser, parser->scope,
+ identifier,
+ token->location);
+ /* Look up a qualified name in the usual way. */
+ if (parser->scope)
+ {
+ tree decl;
+ tree ambiguous_decls;
+
+ decl = cp_parser_lookup_name (parser, identifier,
+ tag_type,
+ /*is_template=*/false,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true,
+ &ambiguous_decls,
+ token->location);
+
+ /* If the lookup was ambiguous, an error will already have been
+ issued. */
+ if (ambiguous_decls)
+ return error_mark_node;
+
+ /* If we are parsing friend declaration, DECL may be a
+ TEMPLATE_DECL tree node here. However, we need to check
+ whether this TEMPLATE_DECL results in valid code. Consider
+ the following example:
+
+ namespace N {
+ template <class T> class C {};
+ }
+ class X {
+ template <class T> friend class N::C; // #1, valid code
+ };
+ template <class T> class Y {
+ friend class N::C; // #2, invalid code
+ };
+
+ For both case #1 and #2, we arrive at a TEMPLATE_DECL after
+ name lookup of `N::C'. We see that friend declaration must
+ be template for the code to be valid. Note that
+ processing_template_decl does not work here since it is
+ always 1 for the above two cases. */
+
+ decl = (cp_parser_maybe_treat_template_as_class
+ (decl, /*tag_name_p=*/is_friend
+ && parser->num_template_parameter_lists));
+
+ if (TREE_CODE (decl) != TYPE_DECL)
+ {
+ cp_parser_diagnose_invalid_type_name (parser,
+ parser->scope,
+ identifier,
+ token->location);
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE)
+ {
+ bool allow_template = (parser->num_template_parameter_lists
+ || DECL_SELF_REFERENCE_P (decl));
+ type = check_elaborated_type_specifier (tag_type, decl,
+ allow_template);
+
+ if (type == error_mark_node)
+ return error_mark_node;
+ }
+
+ /* Forward declarations of nested types, such as
+
+ class C1::C2;
+ class C1::C2::C3;
+
+ are invalid unless all components preceding the final '::'
+ are complete. If all enclosing types are complete, these
+ declarations become merely pointless.
+
+ Invalid forward declarations of nested types are errors
+ caught elsewhere in parsing. Those that are pointless arrive
+ here. */
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
+ && !is_friend && !processing_explicit_instantiation)
+ warning (0, "declaration %qD does not declare anything", decl);
+
+ type = TREE_TYPE (decl);
+ }
+ else
+ {
+ /* An elaborated-type-specifier sometimes introduces a new type and
+ sometimes names an existing type. Normally, the rule is that it
+ introduces a new type only if there is not an existing type of
+ the same name already in scope. For example, given:
+
+ struct S {};
+ void f() { struct S s; }
+
+ the `struct S' in the body of `f' is the same `struct S' as in
+ the global scope; the existing definition is used. However, if
+ there were no global declaration, this would introduce a new
+ local class named `S'.
+
+ An exception to this rule applies to the following code:
+
+ namespace N { struct S; }
+
+ Here, the elaborated-type-specifier names a new type
+ unconditionally; even if there is already an `S' in the
+ containing scope this declaration names a new type.
+ This exception only applies if the elaborated-type-specifier
+ forms the complete declaration:
+
+ [class.name]
+
+ A declaration consisting solely of `class-key identifier ;' is
+ either a redeclaration of the name in the current scope or a
+ forward declaration of the identifier as a class name. It
+ introduces the name into the current scope.
+
+ We are in this situation precisely when the next token is a `;'.
+
+ An exception to the exception is that a `friend' declaration does
+ *not* name a new type; i.e., given:
+
+ struct S { friend struct T; };
+
+ `T' is not a new type in the scope of `S'.
+
+ Also, `new struct S' or `sizeof (struct S)' never results in the
+ definition of a new type; a new type can only be declared in a
+ declaration context. */
+
+ tag_scope ts;
+ bool template_p;
+
+ if (is_friend)
+ /* Friends have special name lookup rules. */
+ ts = ts_within_enclosing_non_class;
+ else if (is_declaration
+ && cp_lexer_next_token_is (parser->lexer,
+ CPP_SEMICOLON))
+ /* This is a `class-key identifier ;' */
+ ts = ts_current;
+ else
+ ts = ts_global;
+
+ template_p =
+ (parser->num_template_parameter_lists
+ && (cp_parser_next_token_starts_class_definition_p (parser)
+ || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)));
+ /* An unqualified name was used to reference this type, so
+ there were no qualifying templates. */
+ if (!cp_parser_check_template_parameters (parser,
+ /*num_templates=*/0,
+ token->location,
+ /*declarator=*/NULL))
+ return error_mark_node;
+ type = xref_tag (tag_type, identifier, ts, template_p);
+ }
+ }
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ /* Allow attributes on forward declarations of classes. */
+ if (attributes)
+ {
+ if (TREE_CODE (type) == TYPENAME_TYPE)
+ warning (OPT_Wattributes,
+ "attributes ignored on uninstantiated type");
+ else if (tag_type != enum_type && CLASSTYPE_TEMPLATE_INSTANTIATION (type)
+ && ! processing_explicit_instantiation)
+ warning (OPT_Wattributes,
+ "attributes ignored on template instantiation");
+ else if (is_declaration && cp_parser_declares_only_class_p (parser))
+ cplus_decl_attributes (&type, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
+ else
+ warning (OPT_Wattributes,
+ "attributes ignored on elaborated-type-specifier that is not a forward declaration");
+ }
+
+ if (tag_type != enum_type)
+ {
+ /* Indicate whether this class was declared as a `class' or as a
+ `struct'. */
+ if (TREE_CODE (type) == RECORD_TYPE)
+ CLASSTYPE_DECLARED_CLASS (type) = (tag_type == class_type);
+ cp_parser_check_class_key (tag_type, type);
+ }
+
+ /* A "<" cannot follow an elaborated type specifier. If that
+ happens, the user was probably trying to form a template-id. */
+ cp_parser_check_for_invalid_template_id (parser, type, tag_type,
+ token->location);
+
+ return type;
+}
+
+/* Parse an enum-specifier.
+
+ enum-specifier:
+ enum-head { enumerator-list [opt] }
+ enum-head { enumerator-list , } [C++0x]
+
+ enum-head:
+ enum-key identifier [opt] enum-base [opt]
+ enum-key nested-name-specifier identifier enum-base [opt]
+
+ enum-key:
+ enum
+ enum class [C++0x]
+ enum struct [C++0x]
+
+ enum-base: [C++0x]
+ : type-specifier-seq
+
+ opaque-enum-specifier:
+ enum-key identifier enum-base [opt] ;
+
+ GNU Extensions:
+ enum-key attributes[opt] identifier [opt] enum-base [opt]
+ { enumerator-list [opt] }attributes[opt]
+ enum-key attributes[opt] identifier [opt] enum-base [opt]
+ { enumerator-list, }attributes[opt] [C++0x]
+
+ Returns an ENUM_TYPE representing the enumeration, or NULL_TREE
+ if the token stream isn't an enum-specifier after all. */
+
+static tree
+cp_parser_enum_specifier (cp_parser* parser)
+{
+ tree identifier;
+ tree type = NULL_TREE;
+ tree prev_scope;
+ tree nested_name_specifier = NULL_TREE;
+ tree attributes;
+ bool scoped_enum_p = false;
+ bool has_underlying_type = false;
+ bool nested_being_defined = false;
+ bool new_value_list = false;
+ bool is_new_type = false;
+ bool is_anonymous = false;
+ tree underlying_type = NULL_TREE;
+ cp_token *type_start_token = NULL;
+ bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+
+ parser->colon_corrects_to_scope_p = false;
+
+ /* Parse tentatively so that we can back up if we don't find a
+ enum-specifier. */
+ cp_parser_parse_tentatively (parser);
+
+ /* Caller guarantees that the current token is 'enum', an identifier
+ possibly follows, and the token after that is an opening brace.
+ If we don't have an identifier, fabricate an anonymous name for
+ the enumeration being defined. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Parse the "class" or "struct", which indicates a scoped
+ enumeration type in C++0x. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_CLASS)
+ || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
+ {
+ if (cxx_dialect < cxx11)
+ maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
+
+ /* Consume the `struct' or `class' token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ scoped_enum_p = true;
+ }
+
+ attributes = cp_parser_attributes_opt (parser);
+
+ /* Clear the qualification. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+
+ /* Figure out in what scope the declaration is being placed. */
+ prev_scope = current_scope ();
+
+ type_start_token = cp_lexer_peek_token (parser->lexer);
+
+ push_deferring_access_checks (dk_no_check);
+ nested_name_specifier
+ = cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/true,
+ /*check_dependency_p=*/false,
+ /*type_p=*/false,
+ /*is_declaration=*/false);
+
+ if (nested_name_specifier)
+ {
+ tree name;
+
+ identifier = cp_parser_identifier (parser);
+ name = cp_parser_lookup_name (parser, identifier,
+ enum_type,
+ /*is_template=*/false,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true,
+ /*ambiguous_decls=*/NULL,
+ input_location);
+ if (name && name != error_mark_node)
+ {
+ type = TREE_TYPE (name);
+ if (TREE_CODE (type) == TYPENAME_TYPE)
+ {
+ /* Are template enums allowed in ISO? */
+ if (template_parm_scope_p ())
+ pedwarn (type_start_token->location, OPT_Wpedantic,
+ "%qD is an enumeration template", name);
+ /* ignore a typename reference, for it will be solved by name
+ in start_enum. */
+ type = NULL_TREE;
+ }
+ }
+ else if (nested_name_specifier == error_mark_node)
+ /* We already issued an error. */;
+ else
+ error_at (type_start_token->location,
+ "%qD is not an enumerator-name", identifier);
+ }
+ else
+ {
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ identifier = cp_parser_identifier (parser);
+ else
+ {
+ identifier = make_anon_name ();
+ is_anonymous = true;
+ if (scoped_enum_p)
+ error_at (type_start_token->location,
+ "anonymous scoped enum is not allowed");
+ }
+ }
+ pop_deferring_access_checks ();
+
+ /* Check for the `:' that denotes a specified underlying type in C++0x.
+ Note that a ':' could also indicate a bitfield width, however. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ cp_decl_specifier_seq type_specifiers;
+
+ /* Consume the `:'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Parse the type-specifier-seq. */
+ cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+ /*is_trailing_return=*/false,
+ &type_specifiers);
+
+ /* At this point this is surely not elaborated type specifier. */
+ if (!cp_parser_parse_definitely (parser))
+ return NULL_TREE;
+
+ if (cxx_dialect < cxx11)
+ maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
+
+ has_underlying_type = true;
+
+ /* If that didn't work, stop. */
+ if (type_specifiers.type != error_mark_node)
+ {
+ underlying_type = grokdeclarator (NULL, &type_specifiers, TYPENAME,
+ /*initialized=*/0, NULL);
+ if (underlying_type == error_mark_node
+ || check_for_bare_parameter_packs (underlying_type))
+ underlying_type = NULL_TREE;
+ }
+ }
+
+ /* Look for the `{' but don't consume it yet. */
+ if (!cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ if (cxx_dialect < cxx11 || (!scoped_enum_p && !underlying_type))
+ {
+ cp_parser_error (parser, "expected %<{%>");
+ if (has_underlying_type)
+ {
+ type = NULL_TREE;
+ goto out;
+ }
+ }
+ /* An opaque-enum-specifier must have a ';' here. */
+ if ((scoped_enum_p || underlying_type)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ cp_parser_error (parser, "expected %<;%> or %<{%>");
+ if (has_underlying_type)
+ {
+ type = NULL_TREE;
+ goto out;
+ }
+ }
+ }
+
+ if (!has_underlying_type && !cp_parser_parse_definitely (parser))
+ return NULL_TREE;
+
+ if (nested_name_specifier)
+ {
+ if (CLASS_TYPE_P (nested_name_specifier))
+ {
+ nested_being_defined = TYPE_BEING_DEFINED (nested_name_specifier);
+ TYPE_BEING_DEFINED (nested_name_specifier) = 1;
+ push_scope (nested_name_specifier);
+ }
+ else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL)
+ {
+ push_nested_namespace (nested_name_specifier);
+ }
+ }
+
+ /* Issue an error message if type-definitions are forbidden here. */
+ if (!cp_parser_check_type_definition (parser))
+ type = error_mark_node;
+ else
+ /* Create the new type. We do this before consuming the opening
+ brace so the enum will be recorded as being on the line of its
+ tag (or the 'enum' keyword, if there is no tag). */
+ type = start_enum (identifier, type, underlying_type,
+ scoped_enum_p, &is_new_type);
+
+ /* If the next token is not '{' it is an opaque-enum-specifier or an
+ elaborated-type-specifier. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ timevar_push (TV_PARSE_ENUM);
+ if (nested_name_specifier
+ && nested_name_specifier != error_mark_node)
+ {
+ /* The following catches invalid code such as:
+ enum class S<int>::E { A, B, C }; */
+ if (!processing_specialization
+ && CLASS_TYPE_P (nested_name_specifier)
+ && CLASSTYPE_USE_TEMPLATE (nested_name_specifier))
+ error_at (type_start_token->location, "cannot add an enumerator "
+ "list to a template instantiation");
+
+ if (TREE_CODE (nested_name_specifier) == TYPENAME_TYPE)
+ {
+ error_at (type_start_token->location,
+ "%<%T::%E%> has not been declared",
+ TYPE_CONTEXT (nested_name_specifier),
+ nested_name_specifier);
+ type = error_mark_node;
+ }
+ /* If that scope does not contain the scope in which the
+ class was originally declared, the program is invalid. */
+ else if (prev_scope && !is_ancestor (prev_scope,
+ nested_name_specifier))
+ {
+ if (at_namespace_scope_p ())
+ error_at (type_start_token->location,
+ "declaration of %qD in namespace %qD which does not "
+ "enclose %qD",
+ type, prev_scope, nested_name_specifier);
+ else
+ error_at (type_start_token->location,
+ "declaration of %qD in %qD which does not "
+ "enclose %qD",
+ type, prev_scope, nested_name_specifier);
+ type = error_mark_node;
+ }
+ }
+
+ if (scoped_enum_p)
+ begin_scope (sk_scoped_enum, type);
+
+ /* Consume the opening brace. */
+ cp_lexer_consume_token (parser->lexer);
+
+ if (type == error_mark_node)
+ ; /* Nothing to add */
+ else if (OPAQUE_ENUM_P (type)
+ || (cxx_dialect > cxx98 && processing_specialization))
+ {
+ new_value_list = true;
+ SET_OPAQUE_ENUM_P (type, false);
+ DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
+ }
+ else
+ {
+ error_at (type_start_token->location, "multiple definition of %q#T", type);
+ error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
+ "previous definition here");
+ type = error_mark_node;
+ }
+
+ if (type == error_mark_node)
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ /* If the next token is not '}', then there are some enumerators. */
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
+ {
+ if (is_anonymous && !scoped_enum_p)
+ pedwarn (type_start_token->location, OPT_Wpedantic,
+ "ISO C++ forbids empty anonymous enum");
+ }
+ else
+ cp_parser_enumerator_list (parser, type);
+
+ /* Consume the final '}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+
+ if (scoped_enum_p)
+ finish_scope ();
+ timevar_pop (TV_PARSE_ENUM);
+ }
+ else
+ {
+ /* If a ';' follows, then it is an opaque-enum-specifier
+ and additional restrictions apply. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ {
+ if (is_anonymous)
+ error_at (type_start_token->location,
+ "opaque-enum-specifier without name");
+ else if (nested_name_specifier)
+ error_at (type_start_token->location,
+ "opaque-enum-specifier must use a simple identifier");
+ }
+ }
+
+ /* Look for trailing attributes to apply to this enumeration, and
+ apply them if appropriate. */
+ if (cp_parser_allow_gnu_extensions_p (parser))
+ {
+ tree trailing_attr = cp_parser_gnu_attributes_opt (parser);
+ trailing_attr = chainon (trailing_attr, attributes);
+ cplus_decl_attributes (&type,
+ trailing_attr,
+ (int) ATTR_FLAG_TYPE_IN_PLACE);
+ }
+
+ /* Finish up the enumeration. */
+ if (type != error_mark_node)
+ {
+ if (new_value_list)
+ finish_enum_value_list (type);
+ if (is_new_type)
+ finish_enum (type);
+ }
+
+ if (nested_name_specifier)
+ {
+ if (CLASS_TYPE_P (nested_name_specifier))
+ {
+ TYPE_BEING_DEFINED (nested_name_specifier) = nested_being_defined;
+ pop_scope (nested_name_specifier);
+ }
+ else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL)
+ {
+ pop_nested_namespace (nested_name_specifier);
+ }
+ }
+ out:
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+ return type;
+}
+
+/* Parse an enumerator-list. The enumerators all have the indicated
+ TYPE.
+
+ enumerator-list:
+ enumerator-definition
+ enumerator-list , enumerator-definition */
+
+static void
+cp_parser_enumerator_list (cp_parser* parser, tree type)
+{
+ while (true)
+ {
+ /* Parse an enumerator-definition. */
+ cp_parser_enumerator_definition (parser, type);
+
+ /* If the next token is not a ',', we've reached the end of
+ the list. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Otherwise, consume the `,' and keep going. */
+ cp_lexer_consume_token (parser->lexer);
+ /* If the next token is a `}', there is a trailing comma. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
+ {
+ if (cxx_dialect < cxx11 && !in_system_header_at (input_location))
+ pedwarn (input_location, OPT_Wpedantic,
+ "comma at end of enumerator list");
+ break;
+ }
+ }
+}
+
+/* Parse an enumerator-definition. The enumerator has the indicated
+ TYPE.
+
+ enumerator-definition:
+ enumerator
+ enumerator = constant-expression
+
+ enumerator:
+ identifier */
+
+static void
+cp_parser_enumerator_definition (cp_parser* parser, tree type)
+{
+ tree identifier;
+ tree value;
+ location_t loc;
+
+ /* Save the input location because we are interested in the location
+ of the identifier and not the location of the explicit value. */
+ loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ /* Look for the identifier. */
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return;
+
+ /* If the next token is an '=', then there is an explicit value. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ {
+ /* Consume the `=' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the value. */
+ value = cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/false,
+ NULL);
+ }
+ else
+ value = NULL_TREE;
+
+ /* If we are processing a template, make sure the initializer of the
+ enumerator doesn't contain any bare template parameter pack. */
+ if (check_for_bare_parameter_packs (value))
+ value = error_mark_node;
+
+ /* integral_constant_value will pull out this expression, so make sure
+ it's folded as appropriate. */
+ value = fold_non_dependent_expr (value);
+
+ /* Create the enumerator. */
+ build_enumerator (identifier, value, type, loc);
+}
+
+/* Parse a namespace-name.
+
+ namespace-name:
+ original-namespace-name
+ namespace-alias
+
+ Returns the NAMESPACE_DECL for the namespace. */
+
+static tree
+cp_parser_namespace_name (cp_parser* parser)
+{
+ tree identifier;
+ tree namespace_decl;
+
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* Get the name of the namespace. */
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return error_mark_node;
+
+ /* Look up the identifier in the currently active scope. Look only
+ for namespaces, due to:
+
+ [basic.lookup.udir]
+
+ When looking up a namespace-name in a using-directive or alias
+ definition, only namespace names are considered.
+
+ And:
+
+ [basic.lookup.qual]
+
+ During the lookup of a name preceding the :: scope resolution
+ operator, object, function, and enumerator names are ignored.
+
+ (Note that cp_parser_qualifying_entity only calls this
+ function if the token after the name is the scope resolution
+ operator.) */
+ namespace_decl = cp_parser_lookup_name (parser, identifier,
+ none_type,
+ /*is_template=*/false,
+ /*is_namespace=*/true,
+ /*check_dependency=*/true,
+ /*ambiguous_decls=*/NULL,
+ token->location);
+ /* If it's not a namespace, issue an error. */
+ if (namespace_decl == error_mark_node
+ || TREE_CODE (namespace_decl) != NAMESPACE_DECL)
+ {
+ if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
+ error_at (token->location, "%qD is not a namespace-name", identifier);
+ cp_parser_error (parser, "expected namespace-name");
+ namespace_decl = error_mark_node;
+ }
+
+ return namespace_decl;
+}
+
+/* Parse a namespace-definition.
+
+ namespace-definition:
+ named-namespace-definition
+ unnamed-namespace-definition
+
+ named-namespace-definition:
+ original-namespace-definition
+ extension-namespace-definition
+
+ original-namespace-definition:
+ namespace identifier { namespace-body }
+
+ extension-namespace-definition:
+ namespace original-namespace-name { namespace-body }
+
+ unnamed-namespace-definition:
+ namespace { namespace-body } */
+
+static void
+cp_parser_namespace_definition (cp_parser* parser)
+{
+ tree identifier, attribs;
+ bool has_visibility;
+ bool is_inline;
+
+ cp_ensure_no_omp_declare_simd (parser);
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE))
+ {
+ maybe_warn_cpp0x (CPP0X_INLINE_NAMESPACES);
+ is_inline = true;
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ is_inline = false;
+
+ /* Look for the `namespace' keyword. */
+ cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
+
+ /* Get the name of the namespace. We do not attempt to distinguish
+ between an original-namespace-definition and an
+ extension-namespace-definition at this point. The semantic
+ analysis routines are responsible for that. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ identifier = cp_parser_identifier (parser);
+ else
+ identifier = NULL_TREE;
+
+ /* Parse any specified attributes. */
+ attribs = cp_parser_attributes_opt (parser);
+
+ /* Look for the `{' to start the namespace. */
+ cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
+ /* Start the namespace. */
+ push_namespace (identifier);
+
+ /* "inline namespace" is equivalent to a stub namespace definition
+ followed by a strong using directive. */
+ if (is_inline)
+ {
+ tree name_space = current_namespace;
+ /* Set up namespace association. */
+ DECL_NAMESPACE_ASSOCIATIONS (name_space)
+ = tree_cons (CP_DECL_CONTEXT (name_space), NULL_TREE,
+ DECL_NAMESPACE_ASSOCIATIONS (name_space));
+ /* Import the contents of the inline namespace. */
+ pop_namespace ();
+ do_using_directive (name_space);
+ push_namespace (identifier);
+ }
+
+ has_visibility = handle_namespace_attrs (current_namespace, attribs);
+
+ /* Parse the body of the namespace. */
+ cp_parser_namespace_body (parser);
+
+ if (has_visibility)
+ pop_visibility (1);
+
+ /* Finish the namespace. */
+ pop_namespace ();
+ /* Look for the final `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+}
+
+/* Parse a namespace-body.
+
+ namespace-body:
+ declaration-seq [opt] */
+
+static void
+cp_parser_namespace_body (cp_parser* parser)
+{
+ cp_parser_declaration_seq_opt (parser);
+}
+
+/* Parse a namespace-alias-definition.
+
+ namespace-alias-definition:
+ namespace identifier = qualified-namespace-specifier ; */
+
+static void
+cp_parser_namespace_alias_definition (cp_parser* parser)
+{
+ tree identifier;
+ tree namespace_specifier;
+
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* Look for the `namespace' keyword. */
+ cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
+ /* Look for the identifier. */
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return;
+ /* Look for the `=' token. */
+ if (!cp_parser_uncommitted_to_tentative_parse_p (parser)
+ && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ error_at (token->location, "%<namespace%> definition is not allowed here");
+ /* Skip the definition. */
+ cp_lexer_consume_token (parser->lexer);
+ if (cp_parser_skip_to_closing_brace (parser))
+ cp_lexer_consume_token (parser->lexer);
+ return;
+ }
+ cp_parser_require (parser, CPP_EQ, RT_EQ);
+ /* Look for the qualified-namespace-specifier. */
+ namespace_specifier
+ = cp_parser_qualified_namespace_specifier (parser);
+ /* Look for the `;' token. */
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+ /* Register the alias in the symbol table. */
+ do_namespace_alias (identifier, namespace_specifier);
+}
+
+/* Parse a qualified-namespace-specifier.
+
+ qualified-namespace-specifier:
+ :: [opt] nested-name-specifier [opt] namespace-name
+
+ Returns a NAMESPACE_DECL corresponding to the specified
+ namespace. */
+
+static tree
+cp_parser_qualified_namespace_specifier (cp_parser* parser)
+{
+ /* Look for the optional `::'. */
+ cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false);
+
+ /* Look for the optional nested-name-specifier. */
+ cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/true);
+
+ return cp_parser_namespace_name (parser);
+}
+
+/* Parse a using-declaration, or, if ACCESS_DECLARATION_P is true, an
+ access declaration.
+
+ using-declaration:
+ using typename [opt] :: [opt] nested-name-specifier unqualified-id ;
+ using :: unqualified-id ;
+
+ access-declaration:
+ qualified-id ;
+
+ */
+
+static bool
+cp_parser_using_declaration (cp_parser* parser,
+ bool access_declaration_p)
+{
+ cp_token *token;
+ bool typename_p = false;
+ bool global_scope_p;
+ tree decl;
+ tree identifier;
+ tree qscope;
+ int oldcount = errorcount;
+ cp_token *diag_token = NULL;
+
+ if (access_declaration_p)
+ {
+ diag_token = cp_lexer_peek_token (parser->lexer);
+ cp_parser_parse_tentatively (parser);
+ }
+ else
+ {
+ /* Look for the `using' keyword. */
+ cp_parser_require_keyword (parser, RID_USING, RT_USING);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* See if it's `typename'. */
+ if (token->keyword == RID_TYPENAME)
+ {
+ /* Remember that we've seen it. */
+ typename_p = true;
+ /* Consume the `typename' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+
+ /* Look for the optional global scope qualification. */
+ global_scope_p
+ = (cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+
+ /* If we saw `typename', or didn't see `::', then there must be a
+ nested-name-specifier present. */
+ if (typename_p || !global_scope_p)
+ {
+ qscope = cp_parser_nested_name_specifier (parser, typename_p,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/true);
+ if (!qscope && !cp_parser_uncommitted_to_tentative_parse_p (parser))
+ {
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return false;
+ }
+ }
+ /* Otherwise, we could be in either of the two productions. In that
+ case, treat the nested-name-specifier as optional. */
+ else
+ qscope = cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/true);
+ if (!qscope)
+ qscope = global_namespace;
+
+ if (access_declaration_p && cp_parser_error_occurred (parser))
+ /* Something has already gone wrong; there's no need to parse
+ further. Since an error has occurred, the return value of
+ cp_parser_parse_definitely will be false, as required. */
+ return cp_parser_parse_definitely (parser);
+
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Parse the unqualified-id. */
+ identifier = cp_parser_unqualified_id (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*declarator_p=*/true,
+ /*optional_p=*/false);
+
+ if (access_declaration_p)
+ {
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ cp_parser_simulate_error (parser);
+ if (!cp_parser_parse_definitely (parser))
+ return false;
+ }
+
+ /* The function we call to handle a using-declaration is different
+ depending on what scope we are in. */
+ if (qscope == error_mark_node || identifier == error_mark_node)
+ ;
+ else if (!identifier_p (identifier)
+ && TREE_CODE (identifier) != BIT_NOT_EXPR)
+ /* [namespace.udecl]
+
+ A using declaration shall not name a template-id. */
+ error_at (token->location,
+ "a template-id may not appear in a using-declaration");
+ else
+ {
+ if (at_class_scope_p ())
+ {
+ /* Create the USING_DECL. */
+ decl = do_class_using_decl (parser->scope, identifier);
+
+ if (decl && typename_p)
+ USING_DECL_TYPENAME_P (decl) = 1;
+
+ if (check_for_bare_parameter_packs (decl))
+ {
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ return false;
+ }
+ else
+ /* Add it to the list of members in this class. */
+ finish_member_declaration (decl);
+ }
+ else
+ {
+ decl = cp_parser_lookup_name_simple (parser,
+ identifier,
+ token->location);
+ if (decl == error_mark_node)
+ cp_parser_name_lookup_error (parser, identifier,
+ decl, NLE_NULL,
+ token->location);
+ else if (check_for_bare_parameter_packs (decl))
+ {
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ return false;
+ }
+ else if (!at_namespace_scope_p ())
+ do_local_using_decl (decl, qscope, identifier);
+ else
+ do_toplevel_using_decl (decl, qscope, identifier);
+ }
+ }
+
+ /* Look for the final `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+ if (access_declaration_p && errorcount == oldcount)
+ warning_at (diag_token->location, OPT_Wdeprecated,
+ "access declarations are deprecated "
+ "in favour of using-declarations; "
+ "suggestion: add the %<using%> keyword");
+
+ return true;
+}
+
+/* Parse an alias-declaration.
+
+ alias-declaration:
+ using identifier attribute-specifier-seq [opt] = type-id */
+
+static tree
+cp_parser_alias_declaration (cp_parser* parser)
+{
+ tree id, type, decl, pushed_scope = NULL_TREE, attributes;
+ location_t id_location;
+ cp_declarator *declarator;
+ cp_decl_specifier_seq decl_specs;
+ bool member_p;
+ const char *saved_message = NULL;
+
+ /* Look for the `using' keyword. */
+ cp_token *using_token
+ = cp_parser_require_keyword (parser, RID_USING, RT_USING);
+ if (using_token == NULL)
+ return error_mark_node;
+
+ id_location = cp_lexer_peek_token (parser->lexer)->location;
+ id = cp_parser_identifier (parser);
+ if (id == error_mark_node)
+ return error_mark_node;
+
+ cp_token *attrs_token = cp_lexer_peek_token (parser->lexer);
+ attributes = cp_parser_attributes_opt (parser);
+ if (attributes == error_mark_node)
+ return error_mark_node;
+
+ cp_parser_require (parser, CPP_EQ, RT_EQ);
+
+ if (cp_parser_error_occurred (parser))
+ return error_mark_node;
+
+ cp_parser_commit_to_tentative_parse (parser);
+
+ /* Now we are going to parse the type-id of the declaration. */
+
+ /*
+ [dcl.type]/3 says:
+
+ "A type-specifier-seq shall not define a class or enumeration
+ unless it appears in the type-id of an alias-declaration (7.1.3) that
+ is not the declaration of a template-declaration."
+
+ In other words, if we currently are in an alias template, the
+ type-id should not define a type.
+
+ So let's set parser->type_definition_forbidden_message in that
+ case; cp_parser_check_type_definition (called by
+ cp_parser_class_specifier) will then emit an error if a type is
+ defined in the type-id. */
+ if (parser->num_template_parameter_lists)
+ {
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message =
+ G_("types may not be defined in alias template declarations");
+ }
+
+ type = cp_parser_type_id (parser);
+
+ /* Restore the error message if need be. */
+ if (parser->num_template_parameter_lists)
+ parser->type_definition_forbidden_message = saved_message;
+
+ if (type == error_mark_node)
+ {
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+ if (cp_parser_error_occurred (parser))
+ {
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+
+ /* A typedef-name can also be introduced by an alias-declaration. The
+ identifier following the using keyword becomes a typedef-name. It has
+ the same semantics as if it were introduced by the typedef
+ specifier. In particular, it does not define a new type and it shall
+ not appear in the type-id. */
+
+ clear_decl_specs (&decl_specs);
+ decl_specs.type = type;
+ if (attributes != NULL_TREE)
+ {
+ decl_specs.attributes = attributes;
+ set_and_check_decl_spec_loc (&decl_specs,
+ ds_attribute,
+ attrs_token);
+ }
+ set_and_check_decl_spec_loc (&decl_specs,
+ ds_typedef,
+ using_token);
+ set_and_check_decl_spec_loc (&decl_specs,
+ ds_alias,
+ using_token);
+
+ declarator = make_id_declarator (NULL_TREE, id, sfk_none);
+ declarator->id_loc = id_location;
+
+ member_p = at_class_scope_p ();
+ if (member_p)
+ decl = grokfield (declarator, &decl_specs, NULL_TREE, false,
+ NULL_TREE, attributes);
+ else
+ decl = start_decl (declarator, &decl_specs, 0,
+ attributes, NULL_TREE, &pushed_scope);
+ if (decl == error_mark_node)
+ return decl;
+
+ cp_finish_decl (decl, NULL_TREE, 0, NULL_TREE, 0);
+
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+
+ /* If decl is a template, return its TEMPLATE_DECL so that it gets
+ added into the symbol table; otherwise, return the TYPE_DECL. */
+ if (DECL_LANG_SPECIFIC (decl)
+ && DECL_TEMPLATE_INFO (decl)
+ && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
+ {
+ decl = DECL_TI_TEMPLATE (decl);
+ if (member_p)
+ check_member_template (decl);
+ }
+
+ return decl;
+}
+
+/* Parse a using-directive.
+
+ using-directive:
+ using namespace :: [opt] nested-name-specifier [opt]
+ namespace-name ; */
+
+static void
+cp_parser_using_directive (cp_parser* parser)
+{
+ tree namespace_decl;
+ tree attribs;
+
+ /* Look for the `using' keyword. */
+ cp_parser_require_keyword (parser, RID_USING, RT_USING);
+ /* And the `namespace' keyword. */
+ cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
+ /* Look for the optional `::' operator. */
+ cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
+ /* And the optional nested-name-specifier. */
+ cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/true);
+ /* Get the namespace being used. */
+ namespace_decl = cp_parser_namespace_name (parser);
+ /* And any specified attributes. */
+ attribs = cp_parser_attributes_opt (parser);
+ /* Update the symbol table. */
+ parse_using_directive (namespace_decl, attribs);
+ /* Look for the final `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+}
+
+/* Parse an asm-definition.
+
+ asm-definition:
+ asm ( string-literal ) ;
+
+ GNU Extension:
+
+ asm-definition:
+ asm volatile [opt] ( string-literal ) ;
+ asm volatile [opt] ( string-literal : asm-operand-list [opt] ) ;
+ asm volatile [opt] ( string-literal : asm-operand-list [opt]
+ : asm-operand-list [opt] ) ;
+ asm volatile [opt] ( string-literal : asm-operand-list [opt]
+ : asm-operand-list [opt]
+ : asm-clobber-list [opt] ) ;
+ asm volatile [opt] goto ( string-literal : : asm-operand-list [opt]
+ : asm-clobber-list [opt]
+ : asm-goto-list ) ; */
+
+static void
+cp_parser_asm_definition (cp_parser* parser)
+{
+ tree string;
+ tree outputs = NULL_TREE;
+ tree inputs = NULL_TREE;
+ tree clobbers = NULL_TREE;
+ tree labels = NULL_TREE;
+ tree asm_stmt;
+ bool volatile_p = false;
+ bool extended_p = false;
+ bool invalid_inputs_p = false;
+ bool invalid_outputs_p = false;
+ bool goto_p = false;
+ required_token missing = RT_NONE;
+
+ /* Look for the `asm' keyword. */
+ cp_parser_require_keyword (parser, RID_ASM, RT_ASM);
+ /* See if the next token is `volatile'. */
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && cp_lexer_next_token_is_keyword (parser->lexer, RID_VOLATILE))
+ {
+ /* Remember that we saw the `volatile' keyword. */
+ volatile_p = true;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && parser->in_function_body
+ && cp_lexer_next_token_is_keyword (parser->lexer, RID_GOTO))
+ {
+ /* Remember that we saw the `goto' keyword. */
+ goto_p = true;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* Look for the opening `('. */
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return;
+ /* Look for the string. */
+ string = cp_parser_string_literal (parser, false, false);
+ if (string == error_mark_node)
+ {
+ cp_parser_skip_to_closing_parenthesis (parser, true, false,
+ /*consume_paren=*/true);
+ return;
+ }
+
+ /* If we're allowing GNU extensions, check for the extended assembly
+ syntax. Unfortunately, the `:' tokens need not be separated by
+ a space in C, and so, for compatibility, we tolerate that here
+ too. Doing that means that we have to treat the `::' operator as
+ two `:' tokens. */
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && parser->in_function_body
+ && (cp_lexer_next_token_is (parser->lexer, CPP_COLON)
+ || cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)))
+ {
+ bool inputs_p = false;
+ bool clobbers_p = false;
+ bool labels_p = false;
+
+ /* The extended syntax was used. */
+ extended_p = true;
+
+ /* Look for outputs. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ /* Consume the `:'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the output-operands. */
+ if (cp_lexer_next_token_is_not (parser->lexer,
+ CPP_COLON)
+ && cp_lexer_next_token_is_not (parser->lexer,
+ CPP_SCOPE)
+ && cp_lexer_next_token_is_not (parser->lexer,
+ CPP_CLOSE_PAREN)
+ && !goto_p)
+ outputs = cp_parser_asm_operand_list (parser);
+
+ if (outputs == error_mark_node)
+ invalid_outputs_p = true;
+ }
+ /* If the next token is `::', there are no outputs, and the
+ next token is the beginning of the inputs. */
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ /* The inputs are coming next. */
+ inputs_p = true;
+
+ /* Look for inputs. */
+ if (inputs_p
+ || cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ /* Consume the `:' or `::'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the output-operands. */
+ if (cp_lexer_next_token_is_not (parser->lexer,
+ CPP_COLON)
+ && cp_lexer_next_token_is_not (parser->lexer,
+ CPP_SCOPE)
+ && cp_lexer_next_token_is_not (parser->lexer,
+ CPP_CLOSE_PAREN))
+ inputs = cp_parser_asm_operand_list (parser);
+
+ if (inputs == error_mark_node)
+ invalid_inputs_p = true;
+ }
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ /* The clobbers are coming next. */
+ clobbers_p = true;
+
+ /* Look for clobbers. */
+ if (clobbers_p
+ || cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ clobbers_p = true;
+ /* Consume the `:' or `::'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the clobbers. */
+ if (cp_lexer_next_token_is_not (parser->lexer,
+ CPP_COLON)
+ && cp_lexer_next_token_is_not (parser->lexer,
+ CPP_CLOSE_PAREN))
+ clobbers = cp_parser_asm_clobber_list (parser);
+ }
+ else if (goto_p
+ && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ /* The labels are coming next. */
+ labels_p = true;
+
+ /* Look for labels. */
+ if (labels_p
+ || (goto_p && cp_lexer_next_token_is (parser->lexer, CPP_COLON)))
+ {
+ labels_p = true;
+ /* Consume the `:' or `::'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the labels. */
+ labels = cp_parser_asm_label_list (parser);
+ }
+
+ if (goto_p && !labels_p)
+ missing = clobbers_p ? RT_COLON : RT_COLON_SCOPE;
+ }
+ else if (goto_p)
+ missing = RT_COLON_SCOPE;
+
+ /* Look for the closing `)'. */
+ if (!cp_parser_require (parser, missing ? CPP_COLON : CPP_CLOSE_PAREN,
+ missing ? missing : RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, true, false,
+ /*consume_paren=*/true);
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+ if (!invalid_inputs_p && !invalid_outputs_p)
+ {
+ /* Create the ASM_EXPR. */
+ if (parser->in_function_body)
+ {
+ asm_stmt = finish_asm_stmt (volatile_p, string, outputs,
+ inputs, clobbers, labels);
+ /* If the extended syntax was not used, mark the ASM_EXPR. */
+ if (!extended_p)
+ {
+ tree temp = asm_stmt;
+ if (TREE_CODE (temp) == CLEANUP_POINT_EXPR)
+ temp = TREE_OPERAND (temp, 0);
+
+ ASM_INPUT_P (temp) = 1;
+ }
+ }
+ else
+ add_asm_node (string);
+ }
+}
+
+/* Declarators [gram.dcl.decl] */
+
+/* Parse an init-declarator.
+
+ init-declarator:
+ declarator initializer [opt]
+
+ GNU Extension:
+
+ init-declarator:
+ declarator asm-specification [opt] attributes [opt] initializer [opt]
+
+ function-definition:
+ decl-specifier-seq [opt] declarator ctor-initializer [opt]
+ function-body
+ decl-specifier-seq [opt] declarator function-try-block
+
+ GNU Extension:
+
+ function-definition:
+ __extension__ function-definition
+
+ TM Extension:
+
+ function-definition:
+ decl-specifier-seq [opt] declarator function-transaction-block
+
+ The DECL_SPECIFIERS apply to this declarator. Returns a
+ representation of the entity declared. If MEMBER_P is TRUE, then
+ this declarator appears in a class scope. The new DECL created by
+ this declarator is returned.
+
+ The CHECKS are access checks that should be performed once we know
+ what entity is being declared (and, therefore, what classes have
+ befriended it).
+
+ If FUNCTION_DEFINITION_ALLOWED_P then we handle the declarator and
+ for a function-definition here as well. If the declarator is a
+ declarator for a function-definition, *FUNCTION_DEFINITION_P will
+ be TRUE upon return. By that point, the function-definition will
+ have been completely parsed.
+
+ FUNCTION_DEFINITION_P may be NULL if FUNCTION_DEFINITION_ALLOWED_P
+ is FALSE.
+
+ If MAYBE_RANGE_FOR_DECL is not NULL, the pointed tree will be set to the
+ parsed declaration if it is an uninitialized single declarator not followed
+ by a `;', or to error_mark_node otherwise. Either way, the trailing `;',
+ if present, will not be consumed. If returned, this declarator will be
+ created with SD_INITIALIZED but will not call cp_finish_decl. */
+
+static tree
+cp_parser_init_declarator (cp_parser* parser,
+ cp_decl_specifier_seq *decl_specifiers,
+ vec<deferred_access_check, va_gc> *checks,
+ bool function_definition_allowed_p,
+ bool member_p,
+ int declares_class_or_enum,
+ bool* function_definition_p,
+ tree* maybe_range_for_decl)
+{
+ cp_token *token = NULL, *asm_spec_start_token = NULL,
+ *attributes_start_token = NULL;
+ cp_declarator *declarator;
+ tree prefix_attributes;
+ tree attributes = NULL;
+ tree asm_specification;
+ tree initializer;
+ tree decl = NULL_TREE;
+ tree scope;
+ int is_initialized;
+ /* Only valid if IS_INITIALIZED is true. In that case, CPP_EQ if
+ initialized with "= ..", CPP_OPEN_PAREN if initialized with
+ "(...)". */
+ enum cpp_ttype initialization_kind;
+ bool is_direct_init = false;
+ bool is_non_constant_init;
+ int ctor_dtor_or_conv_p;
+ bool friend_p;
+ tree pushed_scope = NULL_TREE;
+ bool range_for_decl_p = false;
+ bool saved_default_arg_ok_p = parser->default_arg_ok_p;
+
+ /* Gather the attributes that were provided with the
+ decl-specifiers. */
+ prefix_attributes = decl_specifiers->attributes;
+
+ /* Assume that this is not the declarator for a function
+ definition. */
+ if (function_definition_p)
+ *function_definition_p = false;
+
+ /* Default arguments are only permitted for function parameters. */
+ if (decl_spec_seq_has_spec_p (decl_specifiers, ds_typedef))
+ parser->default_arg_ok_p = false;
+
+ /* Defer access checks while parsing the declarator; we cannot know
+ what names are accessible until we know what is being
+ declared. */
+ resume_deferring_access_checks ();
+
+ /* Parse the declarator. */
+ token = cp_lexer_peek_token (parser->lexer);
+ declarator
+ = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+ &ctor_dtor_or_conv_p,
+ /*parenthesized_p=*/NULL,
+ member_p);
+ /* Gather up the deferred checks. */
+ stop_deferring_access_checks ();
+
+ parser->default_arg_ok_p = saved_default_arg_ok_p;
+
+ /* If the DECLARATOR was erroneous, there's no need to go
+ further. */
+ if (declarator == cp_error_declarator)
+ return error_mark_node;
+
+ /* Check that the number of template-parameter-lists is OK. */
+ if (!cp_parser_check_declarator_template_parameters (parser, declarator,
+ token->location))
+ return error_mark_node;
+
+ if (declares_class_or_enum & 2)
+ cp_parser_check_for_definition_in_return_type (declarator,
+ decl_specifiers->type,
+ decl_specifiers->locations[ds_type_spec]);
+
+ /* Figure out what scope the entity declared by the DECLARATOR is
+ located in. `grokdeclarator' sometimes changes the scope, so
+ we compute it now. */
+ scope = get_scope_of_declarator (declarator);
+
+ /* Perform any lookups in the declared type which were thought to be
+ dependent, but are not in the scope of the declarator. */
+ decl_specifiers->type
+ = maybe_update_decl_type (decl_specifiers->type, scope);
+
+ /* If we're allowing GNU extensions, look for an
+ asm-specification. */
+ if (cp_parser_allow_gnu_extensions_p (parser))
+ {
+ /* Look for an asm-specification. */
+ asm_spec_start_token = cp_lexer_peek_token (parser->lexer);
+ asm_specification = cp_parser_asm_specification_opt (parser);
+ }
+ else
+ asm_specification = NULL_TREE;
+
+ /* Look for attributes. */
+ attributes_start_token = cp_lexer_peek_token (parser->lexer);
+ attributes = cp_parser_attributes_opt (parser);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ if (function_declarator_p (declarator))
+ {
+ /* Check to see if the token indicates the start of a
+ function-definition. */
+ if (cp_parser_token_starts_function_definition_p (token))
+ {
+ if (!function_definition_allowed_p)
+ {
+ /* If a function-definition should not appear here, issue an
+ error message. */
+ cp_parser_error (parser,
+ "a function-definition is not allowed here");
+ return error_mark_node;
+ }
+
+ location_t func_brace_location
+ = cp_lexer_peek_token (parser->lexer)->location;
+
+ /* Neither attributes nor an asm-specification are allowed
+ on a function-definition. */
+ if (asm_specification)
+ error_at (asm_spec_start_token->location,
+ "an asm-specification is not allowed "
+ "on a function-definition");
+ if (attributes)
+ error_at (attributes_start_token->location,
+ "attributes are not allowed "
+ "on a function-definition");
+ /* This is a function-definition. */
+ *function_definition_p = true;
+
+ /* Parse the function definition. */
+ if (member_p)
+ decl = cp_parser_save_member_function_body (parser,
+ decl_specifiers,
+ declarator,
+ prefix_attributes);
+ else
+ decl =
+ (cp_parser_function_definition_from_specifiers_and_declarator
+ (parser, decl_specifiers, prefix_attributes, declarator));
+
+ if (decl != error_mark_node && DECL_STRUCT_FUNCTION (decl))
+ {
+ /* This is where the prologue starts... */
+ DECL_STRUCT_FUNCTION (decl)->function_start_locus
+ = func_brace_location;
+ }
+
+ return decl;
+ }
+ }
+
+ /* [dcl.dcl]
+
+ Only in function declarations for constructors, destructors, and
+ type conversions can the decl-specifier-seq be omitted.
+
+ We explicitly postpone this check past the point where we handle
+ function-definitions because we tolerate function-definitions
+ that are missing their return types in some modes. */
+ if (!decl_specifiers->any_specifiers_p && ctor_dtor_or_conv_p <= 0)
+ {
+ cp_parser_error (parser,
+ "expected constructor, destructor, or type conversion");
+ return error_mark_node;
+ }
+
+ /* An `=' or an `(', or an '{' in C++0x, indicates an initializer. */
+ if (token->type == CPP_EQ
+ || token->type == CPP_OPEN_PAREN
+ || token->type == CPP_OPEN_BRACE)
+ {
+ is_initialized = SD_INITIALIZED;
+ initialization_kind = token->type;
+ if (maybe_range_for_decl)
+ *maybe_range_for_decl = error_mark_node;
+
+ if (token->type == CPP_EQ
+ && function_declarator_p (declarator))
+ {
+ cp_token *t2 = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (t2->keyword == RID_DEFAULT)
+ is_initialized = SD_DEFAULTED;
+ else if (t2->keyword == RID_DELETE)
+ is_initialized = SD_DELETED;
+ }
+ }
+ else
+ {
+ /* If the init-declarator isn't initialized and isn't followed by a
+ `,' or `;', it's not a valid init-declarator. */
+ if (token->type != CPP_COMMA
+ && token->type != CPP_SEMICOLON)
+ {
+ if (maybe_range_for_decl && *maybe_range_for_decl != error_mark_node)
+ range_for_decl_p = true;
+ else
+ {
+ cp_parser_error (parser, "expected initializer");
+ return error_mark_node;
+ }
+ }
+ is_initialized = SD_UNINITIALIZED;
+ initialization_kind = CPP_EOF;
+ }
+
+ /* Because start_decl has side-effects, we should only call it if we
+ know we're going ahead. By this point, we know that we cannot
+ possibly be looking at any other construct. */
+ cp_parser_commit_to_tentative_parse (parser);
+
+ /* If the decl specifiers were bad, issue an error now that we're
+ sure this was intended to be a declarator. Then continue
+ declaring the variable(s), as int, to try to cut down on further
+ errors. */
+ if (decl_specifiers->any_specifiers_p
+ && decl_specifiers->type == error_mark_node)
+ {
+ cp_parser_error (parser, "invalid type in declaration");
+ decl_specifiers->type = integer_type_node;
+ }
+
+ /* Check to see whether or not this declaration is a friend. */
+ friend_p = cp_parser_friend_p (decl_specifiers);
+
+ /* Enter the newly declared entry in the symbol table. If we're
+ processing a declaration in a class-specifier, we wait until
+ after processing the initializer. */
+ if (!member_p)
+ {
+ if (parser->in_unbraced_linkage_specification_p)
+ decl_specifiers->storage_class = sc_extern;
+ decl = start_decl (declarator, decl_specifiers,
+ range_for_decl_p? SD_INITIALIZED : is_initialized,
+ attributes, prefix_attributes, &pushed_scope);
+ cp_finalize_omp_declare_simd (parser, decl);
+ /* Adjust location of decl if declarator->id_loc is more appropriate:
+ set, and decl wasn't merged with another decl, in which case its
+ location would be different from input_location, and more accurate. */
+ if (DECL_P (decl)
+ && declarator->id_loc != UNKNOWN_LOCATION
+ && DECL_SOURCE_LOCATION (decl) == input_location)
+ DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
+ }
+ else if (scope)
+ /* Enter the SCOPE. That way unqualified names appearing in the
+ initializer will be looked up in SCOPE. */
+ pushed_scope = push_scope (scope);
+
+ /* Perform deferred access control checks, now that we know in which
+ SCOPE the declared entity resides. */
+ if (!member_p && decl)
+ {
+ tree saved_current_function_decl = NULL_TREE;
+
+ /* If the entity being declared is a function, pretend that we
+ are in its scope. If it is a `friend', it may have access to
+ things that would not otherwise be accessible. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ saved_current_function_decl = current_function_decl;
+ current_function_decl = decl;
+ }
+
+ /* Perform access checks for template parameters. */
+ cp_parser_perform_template_parameter_access_checks (checks);
+
+ /* Perform the access control checks for the declarator and the
+ decl-specifiers. */
+ perform_deferred_access_checks (tf_warning_or_error);
+
+ /* Restore the saved value. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ current_function_decl = saved_current_function_decl;
+ }
+
+ /* Parse the initializer. */
+ initializer = NULL_TREE;
+ is_direct_init = false;
+ is_non_constant_init = true;
+ if (is_initialized)
+ {
+ if (function_declarator_p (declarator))
+ {
+ cp_token *initializer_start_token = cp_lexer_peek_token (parser->lexer);
+ if (initialization_kind == CPP_EQ)
+ initializer = cp_parser_pure_specifier (parser);
+ else
+ {
+ /* If the declaration was erroneous, we don't really
+ know what the user intended, so just silently
+ consume the initializer. */
+ if (decl != error_mark_node)
+ error_at (initializer_start_token->location,
+ "initializer provided for function");
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ }
+ }
+ else
+ {
+ /* We want to record the extra mangling scope for in-class
+ initializers of class members and initializers of static data
+ member templates. The former involves deferring
+ parsing of the initializer until end of class as with default
+ arguments. So right here we only handle the latter. */
+ if (!member_p && processing_template_decl)
+ start_lambda_scope (decl);
+ initializer = cp_parser_initializer (parser,
+ &is_direct_init,
+ &is_non_constant_init);
+ if (!member_p && processing_template_decl)
+ finish_lambda_scope ();
+ if (initializer == error_mark_node)
+ cp_parser_skip_to_end_of_statement (parser);
+ }
+ }
+
+ /* The old parser allows attributes to appear after a parenthesized
+ initializer. Mark Mitchell proposed removing this functionality
+ on the GCC mailing lists on 2002-08-13. This parser accepts the
+ attributes -- but ignores them. */
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && initialization_kind == CPP_OPEN_PAREN)
+ if (cp_parser_attributes_opt (parser))
+ warning (OPT_Wattributes,
+ "attributes after parenthesized initializer ignored");
+
+ /* A non-template declaration involving a function parameter list containing
+ an implicit template parameter will have been made into a template. If it
+ turns out that the resulting declaration is not an actual function then
+ finish the template declaration here. An error message will already have
+ been issued. */
+ if (parser->fully_implicit_function_template_p)
+ if (!function_declarator_p (declarator))
+ finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
+
+ /* For an in-class declaration, use `grokfield' to create the
+ declaration. */
+ if (member_p)
+ {
+ if (pushed_scope)
+ {
+ pop_scope (pushed_scope);
+ pushed_scope = NULL_TREE;
+ }
+ decl = grokfield (declarator, decl_specifiers,
+ initializer, !is_non_constant_init,
+ /*asmspec=*/NULL_TREE,
+ chainon (attributes, prefix_attributes));
+ if (decl && TREE_CODE (decl) == FUNCTION_DECL)
+ cp_parser_save_default_args (parser, decl);
+ cp_finalize_omp_declare_simd (parser, decl);
+ }
+
+ /* Finish processing the declaration. But, skip member
+ declarations. */
+ if (!member_p && decl && decl != error_mark_node && !range_for_decl_p)
+ {
+ cp_finish_decl (decl,
+ initializer, !is_non_constant_init,
+ asm_specification,
+ /* If the initializer is in parentheses, then this is
+ a direct-initialization, which means that an
+ `explicit' constructor is OK. Otherwise, an
+ `explicit' constructor cannot be used. */
+ ((is_direct_init || !is_initialized)
+ ? LOOKUP_NORMAL : LOOKUP_IMPLICIT));
+ }
+ else if ((cxx_dialect != cxx98) && friend_p
+ && decl && TREE_CODE (decl) == FUNCTION_DECL)
+ /* Core issue #226 (C++0x only): A default template-argument
+ shall not be specified in a friend class template
+ declaration. */
+ check_default_tmpl_args (decl, current_template_parms, /*is_primary=*/true,
+ /*is_partial=*/false, /*is_friend_decl=*/1);
+
+ if (!friend_p && pushed_scope)
+ pop_scope (pushed_scope);
+
+ if (function_declarator_p (declarator)
+ && parser->fully_implicit_function_template_p)
+ {
+ if (member_p)
+ decl = finish_fully_implicit_template (parser, decl);
+ else
+ finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
+ }
+
+ return decl;
+}
+
+/* Parse a declarator.
+
+ declarator:
+ direct-declarator
+ ptr-operator declarator
+
+ abstract-declarator:
+ ptr-operator abstract-declarator [opt]
+ direct-abstract-declarator
+
+ GNU Extensions:
+
+ declarator:
+ attributes [opt] direct-declarator
+ attributes [opt] ptr-operator declarator
+
+ abstract-declarator:
+ attributes [opt] ptr-operator abstract-declarator [opt]
+ attributes [opt] direct-abstract-declarator
+
+ If CTOR_DTOR_OR_CONV_P is not NULL, *CTOR_DTOR_OR_CONV_P is used to
+ detect constructor, destructor or conversion operators. It is set
+ to -1 if the declarator is a name, and +1 if it is a
+ function. Otherwise it is set to zero. Usually you just want to
+ test for >0, but internally the negative value is used.
+
+ (The reason for CTOR_DTOR_OR_CONV_P is that a declaration must have
+ a decl-specifier-seq unless it declares a constructor, destructor,
+ or conversion. It might seem that we could check this condition in
+ semantic analysis, rather than parsing, but that makes it difficult
+ to handle something like `f()'. We want to notice that there are
+ no decl-specifiers, and therefore realize that this is an
+ expression, not a declaration.)
+
+ If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
+ the declarator is a direct-declarator of the form "(...)".
+
+ MEMBER_P is true iff this declarator is a member-declarator. */
+
+static cp_declarator *
+cp_parser_declarator (cp_parser* parser,
+ cp_parser_declarator_kind dcl_kind,
+ int* ctor_dtor_or_conv_p,
+ bool* parenthesized_p,
+ bool member_p)
+{
+ cp_declarator *declarator;
+ enum tree_code code;
+ cp_cv_quals cv_quals;
+ tree class_type;
+ tree gnu_attributes = NULL_TREE, std_attributes = NULL_TREE;
+
+ /* Assume this is not a constructor, destructor, or type-conversion
+ operator. */
+ if (ctor_dtor_or_conv_p)
+ *ctor_dtor_or_conv_p = 0;
+
+ if (cp_parser_allow_gnu_extensions_p (parser))
+ gnu_attributes = cp_parser_gnu_attributes_opt (parser);
+
+ /* Check for the ptr-operator production. */
+ cp_parser_parse_tentatively (parser);
+ /* Parse the ptr-operator. */
+ code = cp_parser_ptr_operator (parser,
+ &class_type,
+ &cv_quals,
+ &std_attributes);
+
+ /* If that worked, then we have a ptr-operator. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ /* If a ptr-operator was found, then this declarator was not
+ parenthesized. */
+ if (parenthesized_p)
+ *parenthesized_p = true;
+ /* The dependent declarator is optional if we are parsing an
+ abstract-declarator. */
+ if (dcl_kind != CP_PARSER_DECLARATOR_NAMED)
+ cp_parser_parse_tentatively (parser);
+
+ /* Parse the dependent declarator. */
+ declarator = cp_parser_declarator (parser, dcl_kind,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
+
+ /* If we are parsing an abstract-declarator, we must handle the
+ case where the dependent declarator is absent. */
+ if (dcl_kind != CP_PARSER_DECLARATOR_NAMED
+ && !cp_parser_parse_definitely (parser))
+ declarator = NULL;
+
+ declarator = cp_parser_make_indirect_declarator
+ (code, class_type, cv_quals, declarator, std_attributes);
+ }
+ /* Everything else is a direct-declarator. */
+ else
+ {
+ if (parenthesized_p)
+ *parenthesized_p = cp_lexer_next_token_is (parser->lexer,
+ CPP_OPEN_PAREN);
+ declarator = cp_parser_direct_declarator (parser, dcl_kind,
+ ctor_dtor_or_conv_p,
+ member_p);
+ }
+
+ if (gnu_attributes && declarator && declarator != cp_error_declarator)
+ declarator->attributes = gnu_attributes;
+ return declarator;
+}
+
+/* Parse a direct-declarator or direct-abstract-declarator.
+
+ direct-declarator:
+ declarator-id
+ direct-declarator ( parameter-declaration-clause )
+ cv-qualifier-seq [opt]
+ ref-qualifier [opt]
+ exception-specification [opt]
+ direct-declarator [ constant-expression [opt] ]
+ ( declarator )
+
+ direct-abstract-declarator:
+ direct-abstract-declarator [opt]
+ ( parameter-declaration-clause )
+ cv-qualifier-seq [opt]
+ ref-qualifier [opt]
+ exception-specification [opt]
+ direct-abstract-declarator [opt] [ constant-expression [opt] ]
+ ( abstract-declarator )
+
+ Returns a representation of the declarator. DCL_KIND is
+ CP_PARSER_DECLARATOR_ABSTRACT, if we are parsing a
+ direct-abstract-declarator. It is CP_PARSER_DECLARATOR_NAMED, if
+ we are parsing a direct-declarator. It is
+ CP_PARSER_DECLARATOR_EITHER, if we can accept either - in the case
+ of ambiguity we prefer an abstract declarator, as per
+ [dcl.ambig.res]. CTOR_DTOR_OR_CONV_P and MEMBER_P are as for
+ cp_parser_declarator. */
+
+static cp_declarator *
+cp_parser_direct_declarator (cp_parser* parser,
+ cp_parser_declarator_kind dcl_kind,
+ int* ctor_dtor_or_conv_p,
+ bool member_p)
+{
+ cp_token *token;
+ cp_declarator *declarator = NULL;
+ tree scope = NULL_TREE;
+ bool saved_default_arg_ok_p = parser->default_arg_ok_p;
+ bool saved_in_declarator_p = parser->in_declarator_p;
+ bool first = true;
+ tree pushed_scope = NULL_TREE;
+
+ while (true)
+ {
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_OPEN_PAREN)
+ {
+ /* This is either a parameter-declaration-clause, or a
+ parenthesized declarator. When we know we are parsing a
+ named declarator, it must be a parenthesized declarator
+ if FIRST is true. For instance, `(int)' is a
+ parameter-declaration-clause, with an omitted
+ direct-abstract-declarator. But `((*))', is a
+ parenthesized abstract declarator. Finally, when T is a
+ template parameter `(T)' is a
+ parameter-declaration-clause, and not a parenthesized
+ named declarator.
+
+ We first try and parse a parameter-declaration-clause,
+ and then try a nested declarator (if FIRST is true).
+
+ It is not an error for it not to be a
+ parameter-declaration-clause, even when FIRST is
+ false. Consider,
+
+ int i (int);
+ int i (3);
+
+ The first is the declaration of a function while the
+ second is the definition of a variable, including its
+ initializer.
+
+ Having seen only the parenthesis, we cannot know which of
+ these two alternatives should be selected. Even more
+ complex are examples like:
+
+ int i (int (a));
+ int i (int (3));
+
+ The former is a function-declaration; the latter is a
+ variable initialization.
+
+ Thus again, we try a parameter-declaration-clause, and if
+ that fails, we back out and return. */
+
+ if (!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
+ {
+ tree params;
+ bool is_declarator = false;
+
+ /* In a member-declarator, the only valid interpretation
+ of a parenthesis is the start of a
+ parameter-declaration-clause. (It is invalid to
+ initialize a static data member with a parenthesized
+ initializer; only the "=" form of initialization is
+ permitted.) */
+ if (!member_p)
+ cp_parser_parse_tentatively (parser);
+
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ if (first)
+ {
+ /* If this is going to be an abstract declarator, we're
+ in a declarator and we can't have default args. */
+ parser->default_arg_ok_p = false;
+ parser->in_declarator_p = true;
+ }
+
+ begin_scope (sk_function_parms, NULL_TREE);
+
+ /* Parse the parameter-declaration-clause. */
+ params = cp_parser_parameter_declaration_clause (parser);
+
+ /* Consume the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ /* If all went well, parse the cv-qualifier-seq,
+ ref-qualifier and the exception-specification. */
+ if (member_p || cp_parser_parse_definitely (parser))
+ {
+ cp_cv_quals cv_quals;
+ cp_virt_specifiers virt_specifiers;
+ cp_ref_qualifier ref_qual;
+ tree exception_specification;
+ tree late_return;
+ tree attrs;
+ bool memfn = (member_p || (pushed_scope
+ && CLASS_TYPE_P (pushed_scope)));
+
+ is_declarator = true;
+
+ if (ctor_dtor_or_conv_p)
+ *ctor_dtor_or_conv_p = *ctor_dtor_or_conv_p < 0;
+ first = false;
+
+ /* Parse the cv-qualifier-seq. */
+ cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
+ /* Parse the ref-qualifier. */
+ ref_qual = cp_parser_ref_qualifier_opt (parser);
+ /* And the exception-specification. */
+ exception_specification
+ = cp_parser_exception_specification_opt (parser);
+
+ attrs = cp_parser_std_attribute_spec_seq (parser);
+
+ /* In here, we handle cases where attribute is used after
+ the function declaration. For example:
+ void func (int x) __attribute__((vector(..))); */
+ if (flag_cilkplus
+ && cp_next_tokens_can_be_gnu_attribute_p (parser))
+ {
+ cp_parser_parse_tentatively (parser);
+ tree attr = cp_parser_gnu_attributes_opt (parser);
+ if (cp_lexer_next_token_is_not (parser->lexer,
+ CPP_SEMICOLON)
+ && cp_lexer_next_token_is_not (parser->lexer,
+ CPP_OPEN_BRACE))
+ cp_parser_abort_tentative_parse (parser);
+ else if (!cp_parser_parse_definitely (parser))
+ ;
+ else
+ attrs = chainon (attr, attrs);
+ }
+ late_return = (cp_parser_late_return_type_opt
+ (parser, declarator,
+ memfn ? cv_quals : -1));
+
+
+ /* Parse the virt-specifier-seq. */
+ virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
+
+ /* Create the function-declarator. */
+ declarator = make_call_declarator (declarator,
+ params,
+ cv_quals,
+ virt_specifiers,
+ ref_qual,
+ exception_specification,
+ late_return);
+ declarator->std_attributes = attrs;
+ /* Any subsequent parameter lists are to do with
+ return type, so are not those of the declared
+ function. */
+ parser->default_arg_ok_p = false;
+ }
+
+ /* Remove the function parms from scope. */
+ pop_bindings_and_leave_scope ();
+
+ if (is_declarator)
+ /* Repeat the main loop. */
+ continue;
+ }
+
+ /* If this is the first, we can try a parenthesized
+ declarator. */
+ if (first)
+ {
+ bool saved_in_type_id_in_expr_p;
+
+ parser->default_arg_ok_p = saved_default_arg_ok_p;
+ parser->in_declarator_p = saved_in_declarator_p;
+
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the nested declarator. */
+ saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
+ declarator
+ = cp_parser_declarator (parser, dcl_kind, ctor_dtor_or_conv_p,
+ /*parenthesized_p=*/NULL,
+ member_p);
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+ first = false;
+ /* Expect a `)'. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ declarator = cp_error_declarator;
+ if (declarator == cp_error_declarator)
+ break;
+
+ goto handle_declarator;
+ }
+ /* Otherwise, we must be done. */
+ else
+ break;
+ }
+ else if ((!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
+ && token->type == CPP_OPEN_SQUARE
+ && !cp_next_tokens_can_be_attribute_p (parser))
+ {
+ /* Parse an array-declarator. */
+ tree bounds, attrs;
+
+ if (ctor_dtor_or_conv_p)
+ *ctor_dtor_or_conv_p = 0;
+
+ first = false;
+ parser->default_arg_ok_p = false;
+ parser->in_declarator_p = true;
+ /* Consume the `['. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If the next token is `]', then there is no
+ constant-expression. */
+ if (token->type != CPP_CLOSE_SQUARE)
+ {
+ bool non_constant_p;
+ bounds
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant=*/true,
+ &non_constant_p);
+ if (!non_constant_p)
+ /* OK */;
+ else if (error_operand_p (bounds))
+ /* Already gave an error. */;
+ else if (!parser->in_function_body
+ || current_binding_level->kind == sk_function_parms)
+ {
+ /* Normally, the array bound must be an integral constant
+ expression. However, as an extension, we allow VLAs
+ in function scopes as long as they aren't part of a
+ parameter declaration. */
+ cp_parser_error (parser,
+ "array bound is not an integer constant");
+ bounds = error_mark_node;
+ }
+ else if (processing_template_decl
+ && !type_dependent_expression_p (bounds))
+ {
+ /* Remember this wasn't a constant-expression. */
+ bounds = build_nop (TREE_TYPE (bounds), bounds);
+ TREE_SIDE_EFFECTS (bounds) = 1;
+ }
+ }
+ else
+ bounds = NULL_TREE;
+ /* Look for the closing `]'. */
+ if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
+ {
+ declarator = cp_error_declarator;
+ break;
+ }
+
+ attrs = cp_parser_std_attribute_spec_seq (parser);
+ declarator = make_array_declarator (declarator, bounds);
+ declarator->std_attributes = attrs;
+ }
+ else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
+ {
+ {
+ tree qualifying_scope;
+ tree unqualified_name;
+ tree attrs;
+ special_function_kind sfk;
+ bool abstract_ok;
+ bool pack_expansion_p = false;
+ cp_token *declarator_id_start_token;
+
+ /* Parse a declarator-id */
+ abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER);
+ if (abstract_ok)
+ {
+ cp_parser_parse_tentatively (parser);
+
+ /* If we see an ellipsis, we should be looking at a
+ parameter pack. */
+ if (token->type == CPP_ELLIPSIS)
+ {
+ /* Consume the `...' */
+ cp_lexer_consume_token (parser->lexer);
+
+ pack_expansion_p = true;
+ }
+ }
+
+ declarator_id_start_token = cp_lexer_peek_token (parser->lexer);
+ unqualified_name
+ = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok);
+ qualifying_scope = parser->scope;
+ if (abstract_ok)
+ {
+ bool okay = false;
+
+ if (!unqualified_name && pack_expansion_p)
+ {
+ /* Check whether an error occurred. */
+ okay = !cp_parser_error_occurred (parser);
+
+ /* We already consumed the ellipsis to mark a
+ parameter pack, but we have no way to report it,
+ so abort the tentative parse. We will be exiting
+ immediately anyway. */
+ cp_parser_abort_tentative_parse (parser);
+ }
+ else
+ okay = cp_parser_parse_definitely (parser);
+
+ if (!okay)
+ unqualified_name = error_mark_node;
+ else if (unqualified_name
+ && (qualifying_scope
+ || (!identifier_p (unqualified_name))))
+ {
+ cp_parser_error (parser, "expected unqualified-id");
+ unqualified_name = error_mark_node;
+ }
+ }
+
+ if (!unqualified_name)
+ return NULL;
+ if (unqualified_name == error_mark_node)
+ {
+ declarator = cp_error_declarator;
+ pack_expansion_p = false;
+ declarator->parameter_pack_p = false;
+ break;
+ }
+
+ attrs = cp_parser_std_attribute_spec_seq (parser);
+
+ if (qualifying_scope && at_namespace_scope_p ()
+ && TREE_CODE (qualifying_scope) == TYPENAME_TYPE)
+ {
+ /* In the declaration of a member of a template class
+ outside of the class itself, the SCOPE will sometimes
+ be a TYPENAME_TYPE. For example, given:
+
+ template <typename T>
+ int S<T>::R::i = 3;
+
+ the SCOPE will be a TYPENAME_TYPE for `S<T>::R'. In
+ this context, we must resolve S<T>::R to an ordinary
+ type, rather than a typename type.
+
+ The reason we normally avoid resolving TYPENAME_TYPEs
+ is that a specialization of `S' might render
+ `S<T>::R' not a type. However, if `S' is
+ specialized, then this `i' will not be used, so there
+ is no harm in resolving the types here. */
+ tree type;
+
+ /* Resolve the TYPENAME_TYPE. */
+ type = resolve_typename_type (qualifying_scope,
+ /*only_current_p=*/false);
+ /* If that failed, the declarator is invalid. */
+ if (TREE_CODE (type) == TYPENAME_TYPE)
+ {
+ if (typedef_variant_p (type))
+ error_at (declarator_id_start_token->location,
+ "cannot define member of dependent typedef "
+ "%qT", type);
+ else
+ error_at (declarator_id_start_token->location,
+ "%<%T::%E%> is not a type",
+ TYPE_CONTEXT (qualifying_scope),
+ TYPE_IDENTIFIER (qualifying_scope));
+ }
+ qualifying_scope = type;
+ }
+
+ sfk = sfk_none;
+
+ if (unqualified_name)
+ {
+ tree class_type;
+
+ if (qualifying_scope
+ && CLASS_TYPE_P (qualifying_scope))
+ class_type = qualifying_scope;
+ else
+ class_type = current_class_type;
+
+ if (TREE_CODE (unqualified_name) == TYPE_DECL)
+ {
+ tree name_type = TREE_TYPE (unqualified_name);
+ if (class_type && same_type_p (name_type, class_type))
+ {
+ if (qualifying_scope
+ && CLASSTYPE_USE_TEMPLATE (name_type))
+ {
+ error_at (declarator_id_start_token->location,
+ "invalid use of constructor as a template");
+ inform (declarator_id_start_token->location,
+ "use %<%T::%D%> instead of %<%T::%D%> to "
+ "name the constructor in a qualified name",
+ class_type,
+ DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
+ class_type, name_type);
+ declarator = cp_error_declarator;
+ break;
+ }
+ else
+ unqualified_name = constructor_name (class_type);
+ }
+ else
+ {
+ /* We do not attempt to print the declarator
+ here because we do not have enough
+ information about its original syntactic
+ form. */
+ cp_parser_error (parser, "invalid declarator");
+ declarator = cp_error_declarator;
+ break;
+ }
+ }
+
+ if (class_type)
+ {
+ if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
+ sfk = sfk_destructor;
+ else if (IDENTIFIER_TYPENAME_P (unqualified_name))
+ sfk = sfk_conversion;
+ else if (/* There's no way to declare a constructor
+ for an anonymous type, even if the type
+ got a name for linkage purposes. */
+ !TYPE_WAS_ANONYMOUS (class_type)
+ && constructor_name_p (unqualified_name,
+ class_type))
+ {
+ unqualified_name = constructor_name (class_type);
+ sfk = sfk_constructor;
+ }
+ else if (is_overloaded_fn (unqualified_name)
+ && DECL_CONSTRUCTOR_P (get_first_fn
+ (unqualified_name)))
+ sfk = sfk_constructor;
+
+ if (ctor_dtor_or_conv_p && sfk != sfk_none)
+ *ctor_dtor_or_conv_p = -1;
+ }
+ }
+ declarator = make_id_declarator (qualifying_scope,
+ unqualified_name,
+ sfk);
+ declarator->std_attributes = attrs;
+ declarator->id_loc = token->location;
+ declarator->parameter_pack_p = pack_expansion_p;
+
+ if (pack_expansion_p)
+ maybe_warn_variadic_templates ();
+ }
+
+ handle_declarator:;
+ scope = get_scope_of_declarator (declarator);
+ if (scope)
+ {
+ /* Any names that appear after the declarator-id for a
+ member are looked up in the containing scope. */
+ if (at_function_scope_p ())
+ {
+ /* But declarations with qualified-ids can't appear in a
+ function. */
+ cp_parser_error (parser, "qualified-id in declaration");
+ declarator = cp_error_declarator;
+ break;
+ }
+ pushed_scope = push_scope (scope);
+ }
+ parser->in_declarator_p = true;
+ if ((ctor_dtor_or_conv_p && *ctor_dtor_or_conv_p)
+ || (declarator && declarator->kind == cdk_id))
+ /* Default args are only allowed on function
+ declarations. */
+ parser->default_arg_ok_p = saved_default_arg_ok_p;
+ else
+ parser->default_arg_ok_p = false;
+
+ first = false;
+ }
+ /* We're done. */
+ else
+ break;
+ }
+
+ /* For an abstract declarator, we might wind up with nothing at this
+ point. That's an error; the declarator is not optional. */
+ if (!declarator)
+ cp_parser_error (parser, "expected declarator");
+
+ /* If we entered a scope, we must exit it now. */
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+
+ parser->default_arg_ok_p = saved_default_arg_ok_p;
+ parser->in_declarator_p = saved_in_declarator_p;
+
+ return declarator;
+}
+
+/* Parse a ptr-operator.
+
+ ptr-operator:
+ * attribute-specifier-seq [opt] cv-qualifier-seq [opt] (C++11)
+ * cv-qualifier-seq [opt]
+ &
+ :: [opt] nested-name-specifier * cv-qualifier-seq [opt]
+ nested-name-specifier * attribute-specifier-seq [opt] cv-qualifier-seq [opt] (C++11)
+
+ GNU Extension:
+
+ ptr-operator:
+ & cv-qualifier-seq [opt]
+
+ Returns INDIRECT_REF if a pointer, or pointer-to-member, was used.
+ Returns ADDR_EXPR if a reference was used, or NON_LVALUE_EXPR for
+ an rvalue reference. In the case of a pointer-to-member, *TYPE is
+ filled in with the TYPE containing the member. *CV_QUALS is
+ filled in with the cv-qualifier-seq, or TYPE_UNQUALIFIED, if there
+ are no cv-qualifiers. Returns ERROR_MARK if an error occurred.
+ Note that the tree codes returned by this function have nothing
+ to do with the types of trees that will be eventually be created
+ to represent the pointer or reference type being parsed. They are
+ just constants with suggestive names. */
+static enum tree_code
+cp_parser_ptr_operator (cp_parser* parser,
+ tree* type,
+ cp_cv_quals *cv_quals,
+ tree *attributes)
+{
+ enum tree_code code = ERROR_MARK;
+ cp_token *token;
+ tree attrs = NULL_TREE;
+
+ /* Assume that it's not a pointer-to-member. */
+ *type = NULL_TREE;
+ /* And that there are no cv-qualifiers. */
+ *cv_quals = TYPE_UNQUALIFIED;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* If it's a `*', `&' or `&&' we have a pointer or reference. */
+ if (token->type == CPP_MULT)
+ code = INDIRECT_REF;
+ else if (token->type == CPP_AND)
+ code = ADDR_EXPR;
+ else if ((cxx_dialect != cxx98) &&
+ token->type == CPP_AND_AND) /* C++0x only */
+ code = NON_LVALUE_EXPR;
+
+ if (code != ERROR_MARK)
+ {
+ /* Consume the `*', `&' or `&&'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* A `*' can be followed by a cv-qualifier-seq, and so can a
+ `&', if we are allowing GNU extensions. (The only qualifier
+ that can legally appear after `&' is `restrict', but that is
+ enforced during semantic analysis. */
+ if (code == INDIRECT_REF
+ || cp_parser_allow_gnu_extensions_p (parser))
+ *cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
+
+ attrs = cp_parser_std_attribute_spec_seq (parser);
+ if (attributes != NULL)
+ *attributes = attrs;
+ }
+ else
+ {
+ /* Try the pointer-to-member case. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for the optional `::' operator. */
+ cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false);
+ /* Look for the nested-name specifier. */
+ token = cp_lexer_peek_token (parser->lexer);
+ cp_parser_nested_name_specifier (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/false);
+ /* If we found it, and the next token is a `*', then we are
+ indeed looking at a pointer-to-member operator. */
+ if (!cp_parser_error_occurred (parser)
+ && cp_parser_require (parser, CPP_MULT, RT_MULT))
+ {
+ /* Indicate that the `*' operator was used. */
+ code = INDIRECT_REF;
+
+ if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
+ error_at (token->location, "%qD is a namespace", parser->scope);
+ else if (TREE_CODE (parser->scope) == ENUMERAL_TYPE)
+ error_at (token->location, "cannot form pointer to member of "
+ "non-class %q#T", parser->scope);
+ else
+ {
+ /* The type of which the member is a member is given by the
+ current SCOPE. */
+ *type = parser->scope;
+ /* The next name will not be qualified. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ /* Look for optional c++11 attributes. */
+ attrs = cp_parser_std_attribute_spec_seq (parser);
+ if (attributes != NULL)
+ *attributes = attrs;
+ /* Look for the optional cv-qualifier-seq. */
+ *cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
+ }
+ }
+ /* If that didn't work we don't have a ptr-operator. */
+ if (!cp_parser_parse_definitely (parser))
+ cp_parser_error (parser, "expected ptr-operator");
+ }
+
+ return code;
+}
+
+/* Parse an (optional) cv-qualifier-seq.
+
+ cv-qualifier-seq:
+ cv-qualifier cv-qualifier-seq [opt]
+
+ cv-qualifier:
+ const
+ volatile
+
+ GNU Extension:
+
+ cv-qualifier:
+ __restrict__
+
+ Returns a bitmask representing the cv-qualifiers. */
+
+static cp_cv_quals
+cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
+{
+ cp_cv_quals cv_quals = TYPE_UNQUALIFIED;
+
+ while (true)
+ {
+ cp_token *token;
+ cp_cv_quals cv_qualifier;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* See if it's a cv-qualifier. */
+ switch (token->keyword)
+ {
+ case RID_CONST:
+ cv_qualifier = TYPE_QUAL_CONST;
+ break;
+
+ case RID_VOLATILE:
+ cv_qualifier = TYPE_QUAL_VOLATILE;
+ break;
+
+ case RID_RESTRICT:
+ cv_qualifier = TYPE_QUAL_RESTRICT;
+ break;
+
+ default:
+ cv_qualifier = TYPE_UNQUALIFIED;
+ break;
+ }
+
+ if (!cv_qualifier)
+ break;
+
+ if (cv_quals & cv_qualifier)
+ {
+ error_at (token->location, "duplicate cv-qualifier");
+ cp_lexer_purge_token (parser->lexer);
+ }
+ else
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cv_quals |= cv_qualifier;
+ }
+ }
+
+ return cv_quals;
+}
+
+/* Parse an (optional) ref-qualifier
+
+ ref-qualifier:
+ &
+ &&
+
+ Returns cp_ref_qualifier representing ref-qualifier. */
+
+static cp_ref_qualifier
+cp_parser_ref_qualifier_opt (cp_parser* parser)
+{
+ cp_ref_qualifier ref_qual = REF_QUAL_NONE;
+
+ /* Don't try to parse bitwise '&' as a ref-qualifier (c++/57532). */
+ if (cxx_dialect < cxx11 && cp_parser_parsing_tentatively (parser))
+ return ref_qual;
+
+ while (true)
+ {
+ cp_ref_qualifier curr_ref_qual = REF_QUAL_NONE;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_AND:
+ curr_ref_qual = REF_QUAL_LVALUE;
+ break;
+
+ case CPP_AND_AND:
+ curr_ref_qual = REF_QUAL_RVALUE;
+ break;
+
+ default:
+ curr_ref_qual = REF_QUAL_NONE;
+ break;
+ }
+
+ if (!curr_ref_qual)
+ break;
+ else if (ref_qual)
+ {
+ error_at (token->location, "multiple ref-qualifiers");
+ cp_lexer_purge_token (parser->lexer);
+ }
+ else
+ {
+ ref_qual = curr_ref_qual;
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+
+ return ref_qual;
+}
+
+/* Parse an (optional) virt-specifier-seq.
+
+ virt-specifier-seq:
+ virt-specifier virt-specifier-seq [opt]
+
+ virt-specifier:
+ override
+ final
+
+ Returns a bitmask representing the virt-specifiers. */
+
+static cp_virt_specifiers
+cp_parser_virt_specifier_seq_opt (cp_parser* parser)
+{
+ cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
+
+ while (true)
+ {
+ cp_token *token;
+ cp_virt_specifiers virt_specifier;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* See if it's a virt-specifier-qualifier. */
+ if (token->type != CPP_NAME)
+ break;
+ if (!strcmp (IDENTIFIER_POINTER(token->u.value), "override"))
+ {
+ maybe_warn_cpp0x (CPP0X_OVERRIDE_CONTROLS);
+ virt_specifier = VIRT_SPEC_OVERRIDE;
+ }
+ else if (!strcmp (IDENTIFIER_POINTER(token->u.value), "final"))
+ {
+ maybe_warn_cpp0x (CPP0X_OVERRIDE_CONTROLS);
+ virt_specifier = VIRT_SPEC_FINAL;
+ }
+ else if (!strcmp (IDENTIFIER_POINTER(token->u.value), "__final"))
+ {
+ virt_specifier = VIRT_SPEC_FINAL;
+ }
+ else
+ break;
+
+ if (virt_specifiers & virt_specifier)
+ {
+ error_at (token->location, "duplicate virt-specifier");
+ cp_lexer_purge_token (parser->lexer);
+ }
+ else
+ {
+ cp_lexer_consume_token (parser->lexer);
+ virt_specifiers |= virt_specifier;
+ }
+ }
+ return virt_specifiers;
+}
+
+/* Used by handling of trailing-return-types and NSDMI, in which 'this'
+ is in scope even though it isn't real. */
+
+static void
+inject_this_parameter (tree ctype, cp_cv_quals quals)
+{
+ tree this_parm;
+
+ if (current_class_ptr)
+ {
+ /* We don't clear this between NSDMIs. Is it already what we want? */
+ tree type = TREE_TYPE (TREE_TYPE (current_class_ptr));
+ if (same_type_ignoring_top_level_qualifiers_p (ctype, type)
+ && cp_type_quals (type) == quals)
+ return;
+ }
+
+ this_parm = build_this_parm (ctype, quals);
+ /* Clear this first to avoid shortcut in cp_build_indirect_ref. */
+ current_class_ptr = NULL_TREE;
+ current_class_ref
+ = cp_build_indirect_ref (this_parm, RO_NULL, tf_warning_or_error);
+ current_class_ptr = this_parm;
+}
+
+/* Return true iff our current scope is a non-static data member
+ initializer. */
+
+bool
+parsing_nsdmi (void)
+{
+ /* We recognize NSDMI context by the context-less 'this' pointer set up
+ by the function above. */
+ if (current_class_ptr && DECL_CONTEXT (current_class_ptr) == NULL_TREE)
+ return true;
+ return false;
+}
+
+/* Parse a late-specified return type, if any. This is not a separate
+ non-terminal, but part of a function declarator, which looks like
+
+ -> trailing-type-specifier-seq abstract-declarator(opt)
+
+ Returns the type indicated by the type-id.
+
+ In addition to this this parses any queued up omp declare simd
+ clauses and Cilk Plus SIMD-enabled function's vector attributes.
+
+ QUALS is either a bitmask of cv_qualifiers or -1 for a non-member
+ function. */
+
+static tree
+cp_parser_late_return_type_opt (cp_parser* parser, cp_declarator *declarator,
+ cp_cv_quals quals)
+{
+ cp_token *token;
+ tree type = NULL_TREE;
+ bool declare_simd_p = (parser->omp_declare_simd
+ && declarator
+ && declarator->kind == cdk_id);
+
+ bool cilk_simd_fn_vector_p = (parser->cilk_simd_fn_info
+ && declarator && declarator->kind == cdk_id);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* A late-specified return type is indicated by an initial '->'. */
+ if (token->type != CPP_DEREF && !(declare_simd_p || cilk_simd_fn_vector_p))
+ return NULL_TREE;
+
+ tree save_ccp = current_class_ptr;
+ tree save_ccr = current_class_ref;
+ if (quals >= 0)
+ {
+ /* DR 1207: 'this' is in scope in the trailing return type. */
+ inject_this_parameter (current_class_type, quals);
+ }
+
+ if (token->type == CPP_DEREF)
+ {
+ /* Consume the ->. */
+ cp_lexer_consume_token (parser->lexer);
+
+ type = cp_parser_trailing_type_id (parser);
+ }
+
+ if (cilk_simd_fn_vector_p)
+ declarator->std_attributes
+ = cp_parser_late_parsing_cilk_simd_fn_info (parser,
+ declarator->std_attributes);
+ if (declare_simd_p)
+ declarator->std_attributes
+ = cp_parser_late_parsing_omp_declare_simd (parser,
+ declarator->std_attributes);
+
+ if (quals >= 0)
+ {
+ current_class_ptr = save_ccp;
+ current_class_ref = save_ccr;
+ }
+
+ return type;
+}
+
+/* Parse a declarator-id.
+
+ declarator-id:
+ id-expression
+ :: [opt] nested-name-specifier [opt] type-name
+
+ In the `id-expression' case, the value returned is as for
+ cp_parser_id_expression if the id-expression was an unqualified-id.
+ If the id-expression was a qualified-id, then a SCOPE_REF is
+ returned. The first operand is the scope (either a NAMESPACE_DECL
+ or TREE_TYPE), but the second is still just a representation of an
+ unqualified-id. */
+
+static tree
+cp_parser_declarator_id (cp_parser* parser, bool optional_p)
+{
+ tree id;
+ /* The expression must be an id-expression. Assume that qualified
+ names are the names of types so that:
+
+ template <class T>
+ int S<T>::R::i = 3;
+
+ will work; we must treat `S<T>::R' as the name of a type.
+ Similarly, assume that qualified names are templates, where
+ required, so that:
+
+ template <class T>
+ int S<T>::R<T>::i = 3;
+
+ will work, too. */
+ id = cp_parser_id_expression (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/false,
+ /*template_p=*/NULL,
+ /*declarator_p=*/true,
+ optional_p);
+ if (id && BASELINK_P (id))
+ id = BASELINK_FUNCTIONS (id);
+ return id;
+}
+
+/* Parse a type-id.
+
+ type-id:
+ type-specifier-seq abstract-declarator [opt]
+
+ Returns the TYPE specified. */
+
+static tree
+cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg,
+ bool is_trailing_return)
+{
+ cp_decl_specifier_seq type_specifier_seq;
+ cp_declarator *abstract_declarator;
+
+ /* Parse the type-specifier-seq. */
+ cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+ is_trailing_return,
+ &type_specifier_seq);
+ if (type_specifier_seq.type == error_mark_node)
+ return error_mark_node;
+
+ /* There might or might not be an abstract declarator. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for the declarator. */
+ abstract_declarator
+ = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_ABSTRACT, NULL,
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
+ /* Check to see if there really was a declarator. */
+ if (!cp_parser_parse_definitely (parser))
+ abstract_declarator = NULL;
+
+ if (type_specifier_seq.type
+ /* None of the valid uses of 'auto' in C++14 involve the type-id
+ nonterminal, but it is valid in a trailing-return-type. */
+ && !(cxx_dialect >= cxx1y && is_trailing_return)
+ && type_uses_auto (type_specifier_seq.type))
+ {
+ /* A type-id with type 'auto' is only ok if the abstract declarator
+ is a function declarator with a late-specified return type. */
+ if (abstract_declarator
+ && abstract_declarator->kind == cdk_function
+ && abstract_declarator->u.function.late_return_type)
+ /* OK */;
+ else
+ {
+ error ("invalid use of %<auto%>");
+ return error_mark_node;
+ }
+ }
+
+ return groktypename (&type_specifier_seq, abstract_declarator,
+ is_template_arg);
+}
+
+static tree cp_parser_type_id (cp_parser *parser)
+{
+ return cp_parser_type_id_1 (parser, false, false);
+}
+
+static tree cp_parser_template_type_arg (cp_parser *parser)
+{
+ tree r;
+ const char *saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in template arguments");
+ r = cp_parser_type_id_1 (parser, true, false);
+ parser->type_definition_forbidden_message = saved_message;
+ if (cxx_dialect >= cxx1y && type_uses_auto (r))
+ {
+ error ("invalid use of %<auto%> in template argument");
+ r = error_mark_node;
+ }
+ return r;
+}
+
+static tree cp_parser_trailing_type_id (cp_parser *parser)
+{
+ return cp_parser_type_id_1 (parser, false, true);
+}
+
+/* Parse a type-specifier-seq.
+
+ type-specifier-seq:
+ type-specifier type-specifier-seq [opt]
+
+ GNU extension:
+
+ type-specifier-seq:
+ attributes type-specifier-seq [opt]
+
+ If IS_DECLARATION is true, we are at the start of a "condition" or
+ exception-declaration, so we might be followed by a declarator-id.
+
+ If IS_TRAILING_RETURN is true, we are in a trailing-return-type,
+ i.e. we've just seen "->".
+
+ Sets *TYPE_SPECIFIER_SEQ to represent the sequence. */
+
+static void
+cp_parser_type_specifier_seq (cp_parser* parser,
+ bool is_declaration,
+ bool is_trailing_return,
+ cp_decl_specifier_seq *type_specifier_seq)
+{
+ bool seen_type_specifier = false;
+ cp_parser_flags flags = CP_PARSER_FLAGS_OPTIONAL;
+ cp_token *start_token = NULL;
+
+ /* Clear the TYPE_SPECIFIER_SEQ. */
+ clear_decl_specs (type_specifier_seq);
+
+ /* In the context of a trailing return type, enum E { } is an
+ elaborated-type-specifier followed by a function-body, not an
+ enum-specifier. */
+ if (is_trailing_return)
+ flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS;
+
+ /* Parse the type-specifiers and attributes. */
+ while (true)
+ {
+ tree type_specifier;
+ bool is_cv_qualifier;
+
+ /* Check for attributes first. */
+ if (cp_next_tokens_can_be_attribute_p (parser))
+ {
+ type_specifier_seq->attributes =
+ chainon (type_specifier_seq->attributes,
+ cp_parser_attributes_opt (parser));
+ continue;
+ }
+
+ /* record the token of the beginning of the type specifier seq,
+ for error reporting purposes*/
+ if (!start_token)
+ start_token = cp_lexer_peek_token (parser->lexer);
+
+ /* Look for the type-specifier. */
+ type_specifier = cp_parser_type_specifier (parser,
+ flags,
+ type_specifier_seq,
+ /*is_declaration=*/false,
+ NULL,
+ &is_cv_qualifier);
+ if (!type_specifier)
+ {
+ /* If the first type-specifier could not be found, this is not a
+ type-specifier-seq at all. */
+ if (!seen_type_specifier)
+ {
+ /* Set in_declarator_p to avoid skipping to the semicolon. */
+ int in_decl = parser->in_declarator_p;
+ parser->in_declarator_p = true;
+
+ if (cp_parser_uncommitted_to_tentative_parse_p (parser)
+ || !cp_parser_parse_and_diagnose_invalid_type_name (parser))
+ cp_parser_error (parser, "expected type-specifier");
+
+ parser->in_declarator_p = in_decl;
+
+ type_specifier_seq->type = error_mark_node;
+ return;
+ }
+ /* If subsequent type-specifiers could not be found, the
+ type-specifier-seq is complete. */
+ break;
+ }
+
+ seen_type_specifier = true;
+ /* The standard says that a condition can be:
+
+ type-specifier-seq declarator = assignment-expression
+
+ However, given:
+
+ struct S {};
+ if (int S = ...)
+
+ we should treat the "S" as a declarator, not as a
+ type-specifier. The standard doesn't say that explicitly for
+ type-specifier-seq, but it does say that for
+ decl-specifier-seq in an ordinary declaration. Perhaps it
+ would be clearer just to allow a decl-specifier-seq here, and
+ then add a semantic restriction that if any decl-specifiers
+ that are not type-specifiers appear, the program is invalid. */
+ if (is_declaration && !is_cv_qualifier)
+ flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
+ }
+}
+
+/* Return whether the function currently being declared has an associated
+ template parameter list. */
+
+static bool
+function_being_declared_is_template_p (cp_parser* parser)
+{
+ if (!current_template_parms || processing_template_parmlist)
+ return false;
+
+ if (parser->implicit_template_scope)
+ return true;
+
+ if (at_class_scope_p ()
+ && TYPE_BEING_DEFINED (current_class_type))
+ return parser->num_template_parameter_lists != 0;
+
+ return ((int) parser->num_template_parameter_lists > template_class_depth
+ (current_class_type));
+}
+
+/* Parse a parameter-declaration-clause.
+
+ parameter-declaration-clause:
+ parameter-declaration-list [opt] ... [opt]
+ parameter-declaration-list , ...
+
+ Returns a representation for the parameter declarations. A return
+ value of NULL indicates a parameter-declaration-clause consisting
+ only of an ellipsis. */
+
+static tree
+cp_parser_parameter_declaration_clause (cp_parser* parser)
+{
+ tree parameters;
+ cp_token *token;
+ bool ellipsis_p;
+ bool is_error;
+
+ struct cleanup {
+ cp_parser* parser;
+ int auto_is_implicit_function_template_parm_p;
+ ~cleanup() {
+ parser->auto_is_implicit_function_template_parm_p
+ = auto_is_implicit_function_template_parm_p;
+ }
+ } cleanup = { parser, parser->auto_is_implicit_function_template_parm_p };
+
+ (void) cleanup;
+
+ if (!processing_specialization
+ && !processing_template_parmlist
+ && !processing_explicit_instantiation)
+ if (!current_function_decl
+ || (current_class_type && LAMBDA_TYPE_P (current_class_type)))
+ parser->auto_is_implicit_function_template_parm_p = true;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Check for trivial parameter-declaration-clauses. */
+ if (token->type == CPP_ELLIPSIS)
+ {
+ /* Consume the `...' token. */
+ cp_lexer_consume_token (parser->lexer);
+ return NULL_TREE;
+ }
+ else if (token->type == CPP_CLOSE_PAREN)
+ /* There are no parameters. */
+ {
+#ifndef NO_IMPLICIT_EXTERN_C
+ if (in_system_header_at (input_location)
+ && current_class_type == NULL
+ && current_lang_name == lang_name_c)
+ return NULL_TREE;
+ else
+#endif
+ return void_list_node;
+ }
+ /* Check for `(void)', too, which is a special case. */
+ else if (token->keyword == RID_VOID
+ && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ == CPP_CLOSE_PAREN))
+ {
+ /* Consume the `void' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* There are no parameters. */
+ return void_list_node;
+ }
+
+ /* Parse the parameter-declaration-list. */
+ parameters = cp_parser_parameter_declaration_list (parser, &is_error);
+ /* If a parse error occurred while parsing the
+ parameter-declaration-list, then the entire
+ parameter-declaration-clause is erroneous. */
+ if (is_error)
+ return NULL;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's a `,', the clause should terminate with an ellipsis. */
+ if (token->type == CPP_COMMA)
+ {
+ /* Consume the `,'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Expect an ellipsis. */
+ ellipsis_p
+ = (cp_parser_require (parser, CPP_ELLIPSIS, RT_ELLIPSIS) != NULL);
+ }
+ /* It might also be `...' if the optional trailing `,' was
+ omitted. */
+ else if (token->type == CPP_ELLIPSIS)
+ {
+ /* Consume the `...' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* And remember that we saw it. */
+ ellipsis_p = true;
+ }
+ else
+ ellipsis_p = false;
+
+ /* Finish the parameter list. */
+ if (!ellipsis_p)
+ parameters = chainon (parameters, void_list_node);
+
+ return parameters;
+}
+
+/* Parse a parameter-declaration-list.
+
+ parameter-declaration-list:
+ parameter-declaration
+ parameter-declaration-list , parameter-declaration
+
+ Returns a representation of the parameter-declaration-list, as for
+ cp_parser_parameter_declaration_clause. However, the
+ `void_list_node' is never appended to the list. Upon return,
+ *IS_ERROR will be true iff an error occurred. */
+
+static tree
+cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
+{
+ tree parameters = NULL_TREE;
+ tree *tail = &parameters;
+ bool saved_in_unbraced_linkage_specification_p;
+ int index = 0;
+
+ /* Assume all will go well. */
+ *is_error = false;
+ /* The special considerations that apply to a function within an
+ unbraced linkage specifications do not apply to the parameters
+ to the function. */
+ saved_in_unbraced_linkage_specification_p
+ = parser->in_unbraced_linkage_specification_p;
+ parser->in_unbraced_linkage_specification_p = false;
+
+ /* Look for more parameters. */
+ while (true)
+ {
+ cp_parameter_declarator *parameter;
+ tree decl = error_mark_node;
+ bool parenthesized_p = false;
+ int template_parm_idx = (function_being_declared_is_template_p (parser)?
+ TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS
+ (current_template_parms)) : 0);
+
+ /* Parse the parameter. */
+ parameter
+ = cp_parser_parameter_declaration (parser,
+ /*template_parm_p=*/false,
+ &parenthesized_p);
+
+ /* We don't know yet if the enclosing context is deprecated, so wait
+ and warn in grokparms if appropriate. */
+ deprecated_state = DEPRECATED_SUPPRESS;
+
+ if (parameter)
+ {
+ /* If a function parameter pack was specified and an implicit template
+ parameter was introduced during cp_parser_parameter_declaration,
+ change any implicit parameters introduced into packs. */
+ if (parser->implicit_template_parms
+ && parameter->declarator
+ && parameter->declarator->parameter_pack_p)
+ {
+ int latest_template_parm_idx = TREE_VEC_LENGTH
+ (INNERMOST_TEMPLATE_PARMS (current_template_parms));
+
+ if (latest_template_parm_idx != template_parm_idx)
+ parameter->decl_specifiers.type = convert_generic_types_to_packs
+ (parameter->decl_specifiers.type,
+ template_parm_idx, latest_template_parm_idx);
+ }
+
+ decl = grokdeclarator (parameter->declarator,
+ &parameter->decl_specifiers,
+ PARM,
+ parameter->default_argument != NULL_TREE,
+ &parameter->decl_specifiers.attributes);
+ }
+
+ deprecated_state = DEPRECATED_NORMAL;
+
+ /* If a parse error occurred parsing the parameter declaration,
+ then the entire parameter-declaration-list is erroneous. */
+ if (decl == error_mark_node)
+ {
+ *is_error = true;
+ parameters = error_mark_node;
+ break;
+ }
+
+ if (parameter->decl_specifiers.attributes)
+ cplus_decl_attributes (&decl,
+ parameter->decl_specifiers.attributes,
+ 0);
+ if (DECL_NAME (decl))
+ decl = pushdecl (decl);
+
+ if (decl != error_mark_node)
+ {
+ retrofit_lang_decl (decl);
+ DECL_PARM_INDEX (decl) = ++index;
+ DECL_PARM_LEVEL (decl) = function_parm_depth ();
+ }
+
+ /* Add the new parameter to the list. */
+ *tail = build_tree_list (parameter->default_argument, decl);
+ tail = &TREE_CHAIN (*tail);
+
+ /* Peek at the next token. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)
+ || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)
+ /* These are for Objective-C++ */
+ || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
+ || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ /* The parameter-declaration-list is complete. */
+ break;
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ {
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_nth_token (parser->lexer, 2);
+ /* If it's an ellipsis, then the list is complete. */
+ if (token->type == CPP_ELLIPSIS)
+ break;
+ /* Otherwise, there must be more parameters. Consume the
+ `,'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* When parsing something like:
+
+ int i(float f, double d)
+
+ we can tell after seeing the declaration for "f" that we
+ are not looking at an initialization of a variable "i",
+ but rather at the declaration of a function "i".
+
+ Due to the fact that the parsing of template arguments
+ (as specified to a template-id) requires backtracking we
+ cannot use this technique when inside a template argument
+ list. */
+ if (!parser->in_template_argument_list_p
+ && !parser->in_type_id_in_expr_p
+ && cp_parser_uncommitted_to_tentative_parse_p (parser)
+ /* However, a parameter-declaration of the form
+ "float(f)" (which is a valid declaration of a
+ parameter "f") can also be interpreted as an
+ expression (the conversion of "f" to "float"). */
+ && !parenthesized_p)
+ cp_parser_commit_to_tentative_parse (parser);
+ }
+ else
+ {
+ cp_parser_error (parser, "expected %<,%> or %<...%>");
+ if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/false);
+ break;
+ }
+ }
+
+ parser->in_unbraced_linkage_specification_p
+ = saved_in_unbraced_linkage_specification_p;
+
+ /* Reset implicit_template_scope if we are about to leave the function
+ parameter list that introduced it. Note that for out-of-line member
+ definitions, there will be one or more class scopes before we get to
+ the template parameter scope. */
+
+ if (cp_binding_level *its = parser->implicit_template_scope)
+ if (cp_binding_level *maybe_its = current_binding_level->level_chain)
+ {
+ while (maybe_its->kind == sk_class)
+ maybe_its = maybe_its->level_chain;
+ if (maybe_its == its)
+ {
+ parser->implicit_template_parms = 0;
+ parser->implicit_template_scope = 0;
+ }
+ }
+
+ return parameters;
+}
+
+/* Parse a parameter declaration.
+
+ parameter-declaration:
+ decl-specifier-seq ... [opt] declarator
+ decl-specifier-seq declarator = assignment-expression
+ decl-specifier-seq ... [opt] abstract-declarator [opt]
+ decl-specifier-seq abstract-declarator [opt] = assignment-expression
+
+ If TEMPLATE_PARM_P is TRUE, then this parameter-declaration
+ declares a template parameter. (In that case, a non-nested `>'
+ token encountered during the parsing of the assignment-expression
+ is not interpreted as a greater-than operator.)
+
+ Returns a representation of the parameter, or NULL if an error
+ occurs. If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to
+ true iff the declarator is of the form "(p)". */
+
+static cp_parameter_declarator *
+cp_parser_parameter_declaration (cp_parser *parser,
+ bool template_parm_p,
+ bool *parenthesized_p)
+{
+ int declares_class_or_enum;
+ cp_decl_specifier_seq decl_specifiers;
+ cp_declarator *declarator;
+ tree default_argument;
+ cp_token *token = NULL, *declarator_token_start = NULL;
+ const char *saved_message;
+
+ /* In a template parameter, `>' is not an operator.
+
+ [temp.param]
+
+ When parsing a default template-argument for a non-type
+ template-parameter, the first non-nested `>' is taken as the end
+ of the template parameter-list rather than a greater-than
+ operator. */
+
+ /* Type definitions may not appear in parameter types. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in parameter types");
+
+ /* Parse the declaration-specifiers. */
+ cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_NONE,
+ &decl_specifiers,
+ &declares_class_or_enum);
+
+ /* Complain about missing 'typename' or other invalid type names. */
+ if (!decl_specifiers.any_type_specifiers_p
+ && cp_parser_parse_and_diagnose_invalid_type_name (parser))
+ decl_specifiers.type = error_mark_node;
+
+ /* If an error occurred, there's no reason to attempt to parse the
+ rest of the declaration. */
+ if (cp_parser_error_occurred (parser))
+ {
+ parser->type_definition_forbidden_message = saved_message;
+ return NULL;
+ }
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* If the next token is a `)', `,', `=', `>', or `...', then there
+ is no declarator. However, when variadic templates are enabled,
+ there may be a declarator following `...'. */
+ if (token->type == CPP_CLOSE_PAREN
+ || token->type == CPP_COMMA
+ || token->type == CPP_EQ
+ || token->type == CPP_GREATER)
+ {
+ declarator = NULL;
+ if (parenthesized_p)
+ *parenthesized_p = false;
+ }
+ /* Otherwise, there should be a declarator. */
+ else
+ {
+ bool saved_default_arg_ok_p = parser->default_arg_ok_p;
+ parser->default_arg_ok_p = false;
+
+ /* After seeing a decl-specifier-seq, if the next token is not a
+ "(", there is no possibility that the code is a valid
+ expression. Therefore, if parsing tentatively, we commit at
+ this point. */
+ if (!parser->in_template_argument_list_p
+ /* In an expression context, having seen:
+
+ (int((char ...
+
+ we cannot be sure whether we are looking at a
+ function-type (taking a "char" as a parameter) or a cast
+ of some object of type "char" to "int". */
+ && !parser->in_type_id_in_expr_p
+ && cp_parser_uncommitted_to_tentative_parse_p (parser)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
+ cp_parser_commit_to_tentative_parse (parser);
+ /* Parse the declarator. */
+ declarator_token_start = token;
+ declarator = cp_parser_declarator (parser,
+ CP_PARSER_DECLARATOR_EITHER,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ parenthesized_p,
+ /*member_p=*/false);
+ parser->default_arg_ok_p = saved_default_arg_ok_p;
+ /* After the declarator, allow more attributes. */
+ decl_specifiers.attributes
+ = chainon (decl_specifiers.attributes,
+ cp_parser_attributes_opt (parser));
+ }
+
+ /* If the next token is an ellipsis, and we have not seen a
+ declarator name, and the type of the declarator contains parameter
+ packs but it is not a TYPE_PACK_EXPANSION, then we actually have
+ a parameter pack expansion expression. Otherwise, leave the
+ ellipsis for a C-style variadic function. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ tree type = decl_specifiers.type;
+
+ if (type && DECL_P (type))
+ type = TREE_TYPE (type);
+
+ if (type
+ && TREE_CODE (type) != TYPE_PACK_EXPANSION
+ && declarator_can_be_parameter_pack (declarator)
+ && (!declarator || !declarator->parameter_pack_p)
+ && uses_parameter_packs (type))
+ {
+ /* Consume the `...'. */
+ cp_lexer_consume_token (parser->lexer);
+ maybe_warn_variadic_templates ();
+
+ /* Build a pack expansion type */
+ if (declarator)
+ declarator->parameter_pack_p = true;
+ else
+ decl_specifiers.type = make_pack_expansion (type);
+ }
+ }
+
+ /* The restriction on defining new types applies only to the type
+ of the parameter, not to the default argument. */
+ parser->type_definition_forbidden_message = saved_message;
+
+ /* If the next token is `=', then process a default argument. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ {
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If we are defining a class, then the tokens that make up the
+ default argument must be saved and processed later. */
+ if (!template_parm_p && at_class_scope_p ()
+ && TYPE_BEING_DEFINED (current_class_type)
+ && !LAMBDA_TYPE_P (current_class_type))
+ default_argument = cp_parser_cache_defarg (parser, /*nsdmi=*/false);
+ /* Outside of a class definition, we can just parse the
+ assignment-expression. */
+ else
+ default_argument
+ = cp_parser_default_argument (parser, template_parm_p);
+
+ if (!parser->default_arg_ok_p)
+ {
+ if (flag_permissive)
+ warning (0, "deprecated use of default argument for parameter of non-function");
+ else
+ {
+ error_at (token->location,
+ "default arguments are only "
+ "permitted for function parameters");
+ default_argument = NULL_TREE;
+ }
+ }
+ else if ((declarator && declarator->parameter_pack_p)
+ || (decl_specifiers.type
+ && PACK_EXPANSION_P (decl_specifiers.type)))
+ {
+ /* Find the name of the parameter pack. */
+ cp_declarator *id_declarator = declarator;
+ while (id_declarator && id_declarator->kind != cdk_id)
+ id_declarator = id_declarator->declarator;
+
+ if (id_declarator && id_declarator->kind == cdk_id)
+ error_at (declarator_token_start->location,
+ template_parm_p
+ ? G_("template parameter pack %qD "
+ "cannot have a default argument")
+ : G_("parameter pack %qD cannot have "
+ "a default argument"),
+ id_declarator->u.id.unqualified_name);
+ else
+ error_at (declarator_token_start->location,
+ template_parm_p
+ ? G_("template parameter pack cannot have "
+ "a default argument")
+ : G_("parameter pack cannot have a "
+ "default argument"));
+
+ default_argument = NULL_TREE;
+ }
+ }
+ else
+ default_argument = NULL_TREE;
+
+ return make_parameter_declarator (&decl_specifiers,
+ declarator,
+ default_argument);
+}
+
+/* Parse a default argument and return it.
+
+ TEMPLATE_PARM_P is true if this is a default argument for a
+ non-type template parameter. */
+static tree
+cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
+{
+ tree default_argument = NULL_TREE;
+ bool saved_greater_than_is_operator_p;
+ bool saved_local_variables_forbidden_p;
+ bool non_constant_p, is_direct_init;
+
+ /* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is
+ set correctly. */
+ saved_greater_than_is_operator_p = parser->greater_than_is_operator_p;
+ parser->greater_than_is_operator_p = !template_parm_p;
+ /* Local variable names (and the `this' keyword) may not
+ appear in a default argument. */
+ saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
+ parser->local_variables_forbidden_p = true;
+ /* Parse the assignment-expression. */
+ if (template_parm_p)
+ push_deferring_access_checks (dk_no_deferred);
+ tree saved_class_ptr = NULL_TREE;
+ tree saved_class_ref = NULL_TREE;
+ /* The "this" pointer is not valid in a default argument. */
+ if (cfun)
+ {
+ saved_class_ptr = current_class_ptr;
+ cp_function_chain->x_current_class_ptr = NULL_TREE;
+ saved_class_ref = current_class_ref;
+ cp_function_chain->x_current_class_ref = NULL_TREE;
+ }
+ default_argument
+ = cp_parser_initializer (parser, &is_direct_init, &non_constant_p);
+ /* Restore the "this" pointer. */
+ if (cfun)
+ {
+ cp_function_chain->x_current_class_ptr = saved_class_ptr;
+ cp_function_chain->x_current_class_ref = saved_class_ref;
+ }
+ if (BRACE_ENCLOSED_INITIALIZER_P (default_argument))
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ if (template_parm_p)
+ pop_deferring_access_checks ();
+ parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;
+ parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
+
+ return default_argument;
+}
+
+/* Parse a function-body.
+
+ function-body:
+ compound_statement */
+
+static void
+cp_parser_function_body (cp_parser *parser, bool in_function_try_block)
+{
+ cp_parser_compound_statement (parser, NULL, in_function_try_block, true);
+}
+
+/* Parse a ctor-initializer-opt followed by a function-body. Return
+ true if a ctor-initializer was present. When IN_FUNCTION_TRY_BLOCK
+ is true we are parsing a function-try-block. */
+
+static bool
+cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
+ bool in_function_try_block)
+{
+ tree body, list;
+ bool ctor_initializer_p;
+ const bool check_body_p =
+ DECL_CONSTRUCTOR_P (current_function_decl)
+ && DECL_DECLARED_CONSTEXPR_P (current_function_decl);
+ tree last = NULL;
+
+ /* Begin the function body. */
+ body = begin_function_body ();
+ /* Parse the optional ctor-initializer. */
+ ctor_initializer_p = cp_parser_ctor_initializer_opt (parser);
+
+ /* If we're parsing a constexpr constructor definition, we need
+ to check that the constructor body is indeed empty. However,
+ before we get to cp_parser_function_body lot of junk has been
+ generated, so we can't just check that we have an empty block.
+ Rather we take a snapshot of the outermost block, and check whether
+ cp_parser_function_body changed its state. */
+ if (check_body_p)
+ {
+ list = cur_stmt_list;
+ if (STATEMENT_LIST_TAIL (list))
+ last = STATEMENT_LIST_TAIL (list)->stmt;
+ }
+ /* Parse the function-body. */
+ cp_parser_function_body (parser, in_function_try_block);
+ if (check_body_p)
+ check_constexpr_ctor_body (last, list);
+ /* Finish the function body. */
+ finish_function_body (body);
+
+ return ctor_initializer_p;
+}
+
+/* Parse an initializer.
+
+ initializer:
+ = initializer-clause
+ ( expression-list )
+
+ Returns an expression representing the initializer. If no
+ initializer is present, NULL_TREE is returned.
+
+ *IS_DIRECT_INIT is set to FALSE if the `= initializer-clause'
+ production is used, and TRUE otherwise. *IS_DIRECT_INIT is
+ set to TRUE if there is no initializer present. If there is an
+ initializer, and it is not a constant-expression, *NON_CONSTANT_P
+ is set to true; otherwise it is set to false. */
+
+static tree
+cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
+ bool* non_constant_p)
+{
+ cp_token *token;
+ tree init;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* Let our caller know whether or not this initializer was
+ parenthesized. */
+ *is_direct_init = (token->type != CPP_EQ);
+ /* Assume that the initializer is constant. */
+ *non_constant_p = false;
+
+ if (token->type == CPP_EQ)
+ {
+ /* Consume the `='. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the initializer-clause. */
+ init = cp_parser_initializer_clause (parser, non_constant_p);
+ }
+ else if (token->type == CPP_OPEN_PAREN)
+ {
+ vec<tree, va_gc> *vec;
+ vec = cp_parser_parenthesized_expression_list (parser, non_attr,
+ /*cast_p=*/false,
+ /*allow_expansion_p=*/true,
+ non_constant_p);
+ if (vec == NULL)
+ return error_mark_node;
+ init = build_tree_list_vec (vec);
+ release_tree_vector (vec);
+ }
+ else if (token->type == CPP_OPEN_BRACE)
+ {
+ cp_lexer_set_source_position (parser->lexer);
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ init = cp_parser_braced_list (parser, non_constant_p);
+ CONSTRUCTOR_IS_DIRECT_INIT (init) = 1;
+ }
+ else
+ {
+ /* Anything else is an error. */
+ cp_parser_error (parser, "expected initializer");
+ init = error_mark_node;
+ }
+
+ return init;
+}
+
+/* Parse an initializer-clause.
+
+ initializer-clause:
+ assignment-expression
+ braced-init-list
+
+ Returns an expression representing the initializer.
+
+ If the `assignment-expression' production is used the value
+ returned is simply a representation for the expression.
+
+ Otherwise, calls cp_parser_braced_list. */
+
+static tree
+cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
+{
+ tree initializer;
+
+ /* Assume the expression is constant. */
+ *non_constant_p = false;
+
+ /* If it is not a `{', then we are looking at an
+ assignment-expression. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
+ {
+ initializer
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/true,
+ non_constant_p);
+ }
+ else
+ initializer = cp_parser_braced_list (parser, non_constant_p);
+
+ return initializer;
+}
+
+/* Parse a brace-enclosed initializer list.
+
+ braced-init-list:
+ { initializer-list , [opt] }
+ { }
+
+ Returns a CONSTRUCTOR. The CONSTRUCTOR_ELTS will be
+ the elements of the initializer-list (or NULL, if the last
+ production is used). The TREE_TYPE for the CONSTRUCTOR will be
+ NULL_TREE. There is no way to detect whether or not the optional
+ trailing `,' was provided. NON_CONSTANT_P is as for
+ cp_parser_initializer. */
+
+static tree
+cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
+{
+ tree initializer;
+
+ /* Consume the `{' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Create a CONSTRUCTOR to represent the braced-initializer. */
+ initializer = make_node (CONSTRUCTOR);
+ /* If it's not a `}', then there is a non-trivial initializer. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
+ {
+ /* Parse the initializer list. */
+ CONSTRUCTOR_ELTS (initializer)
+ = cp_parser_initializer_list (parser, non_constant_p);
+ /* A trailing `,' token is allowed. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ *non_constant_p = false;
+ /* Now, there should be a trailing `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ TREE_TYPE (initializer) = init_list_type_node;
+ return initializer;
+}
+
+/* Parse an initializer-list.
+
+ initializer-list:
+ initializer-clause ... [opt]
+ initializer-list , initializer-clause ... [opt]
+
+ GNU Extension:
+
+ initializer-list:
+ designation initializer-clause ...[opt]
+ initializer-list , designation initializer-clause ...[opt]
+
+ designation:
+ . identifier =
+ identifier :
+ [ constant-expression ] =
+
+ Returns a vec of constructor_elt. The VALUE of each elt is an expression
+ for the initializer. If the INDEX of the elt is non-NULL, it is the
+ IDENTIFIER_NODE naming the field to initialize. NON_CONSTANT_P is
+ as for cp_parser_initializer. */
+
+static vec<constructor_elt, va_gc> *
+cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
+{
+ vec<constructor_elt, va_gc> *v = NULL;
+
+ /* Assume all of the expressions are constant. */
+ *non_constant_p = false;
+
+ /* Parse the rest of the list. */
+ while (true)
+ {
+ cp_token *token;
+ tree designator;
+ tree initializer;
+ bool clause_non_constant_p;
+
+ /* If the next token is an identifier and the following one is a
+ colon, we are looking at the GNU designated-initializer
+ syntax. */
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
+ {
+ /* Warn the user that they are using an extension. */
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ does not allow designated initializers");
+ /* Consume the identifier. */
+ designator = cp_lexer_consume_token (parser->lexer)->u.value;
+ /* Consume the `:'. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* Also handle the C99 syntax, '. id ='. */
+ else if (cp_parser_allow_gnu_extensions_p (parser)
+ && cp_lexer_next_token_is (parser->lexer, CPP_DOT)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME
+ && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_EQ)
+ {
+ /* Warn the user that they are using an extension. */
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ does not allow C99 designated initializers");
+ /* Consume the `.'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Consume the identifier. */
+ designator = cp_lexer_consume_token (parser->lexer)->u.value;
+ /* Consume the `='. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* Also handle C99 array designators, '[ const ] ='. */
+ else if (cp_parser_allow_gnu_extensions_p (parser)
+ && !c_dialect_objc ()
+ && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+ {
+ /* In C++11, [ could start a lambda-introducer. */
+ bool non_const = false;
+
+ cp_parser_parse_tentatively (parser);
+ cp_lexer_consume_token (parser->lexer);
+ designator = cp_parser_constant_expression (parser, true, &non_const);
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+ cp_parser_require (parser, CPP_EQ, RT_EQ);
+ if (!cp_parser_parse_definitely (parser))
+ designator = NULL_TREE;
+ else if (non_const)
+ require_potential_rvalue_constant_expression (designator);
+ }
+ else
+ designator = NULL_TREE;
+
+ /* Parse the initializer. */
+ initializer = cp_parser_initializer_clause (parser,
+ &clause_non_constant_p);
+ /* If any clause is non-constant, so is the entire initializer. */
+ if (clause_non_constant_p)
+ *non_constant_p = true;
+
+ /* If we have an ellipsis, this is an initializer pack
+ expansion. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ /* Consume the `...'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Turn the initializer into an initializer expansion. */
+ initializer = make_pack_expansion (initializer);
+ }
+
+ /* Add it to the vector. */
+ CONSTRUCTOR_APPEND_ELT (v, designator, initializer);
+
+ /* If the next token is not a comma, we have reached the end of
+ the list. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_nth_token (parser->lexer, 2);
+ /* If the next token is a `}', then we're still done. An
+ initializer-clause can have a trailing `,' after the
+ initializer-list and before the closing `}'. */
+ if (token->type == CPP_CLOSE_BRACE)
+ break;
+
+ /* Consume the `,' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return v;
+}
+
+/* Classes [gram.class] */
+
+/* Parse a class-name.
+
+ class-name:
+ identifier
+ template-id
+
+ TYPENAME_KEYWORD_P is true iff the `typename' keyword has been used
+ to indicate that names looked up in dependent types should be
+ assumed to be types. TEMPLATE_KEYWORD_P is true iff the `template'
+ keyword has been used to indicate that the name that appears next
+ is a template. TAG_TYPE indicates the explicit tag given before
+ the type name, if any. If CHECK_DEPENDENCY_P is FALSE, names are
+ looked up in dependent scopes. If CLASS_HEAD_P is TRUE, this class
+ is the class being defined in a class-head.
+
+ Returns the TYPE_DECL representing the class. */
+
+static tree
+cp_parser_class_name (cp_parser *parser,
+ bool typename_keyword_p,
+ bool template_keyword_p,
+ enum tag_types tag_type,
+ bool check_dependency_p,
+ bool class_head_p,
+ bool is_declaration)
+{
+ tree decl;
+ tree scope;
+ bool typename_p;
+ cp_token *token;
+ tree identifier = NULL_TREE;
+
+ /* All class-names start with an identifier. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type != CPP_NAME && token->type != CPP_TEMPLATE_ID)
+ {
+ cp_parser_error (parser, "expected class-name");
+ return error_mark_node;
+ }
+
+ /* PARSER->SCOPE can be cleared when parsing the template-arguments
+ to a template-id, so we save it here. */
+ scope = parser->scope;
+ if (scope == error_mark_node)
+ return error_mark_node;
+
+ /* Any name names a type if we're following the `typename' keyword
+ in a qualified name where the enclosing scope is type-dependent. */
+ typename_p = (typename_keyword_p && scope && TYPE_P (scope)
+ && dependent_type_p (scope));
+ /* Handle the common case (an identifier, but not a template-id)
+ efficiently. */
+ if (token->type == CPP_NAME
+ && !cp_parser_nth_token_starts_template_argument_list_p (parser, 2))
+ {
+ cp_token *identifier_token;
+ bool ambiguous_p;
+
+ /* Look for the identifier. */
+ identifier_token = cp_lexer_peek_token (parser->lexer);
+ ambiguous_p = identifier_token->ambiguous_p;
+ identifier = cp_parser_identifier (parser);
+ /* If the next token isn't an identifier, we are certainly not
+ looking at a class-name. */
+ if (identifier == error_mark_node)
+ decl = error_mark_node;
+ /* If we know this is a type-name, there's no need to look it
+ up. */
+ else if (typename_p)
+ decl = identifier;
+ else
+ {
+ tree ambiguous_decls;
+ /* If we already know that this lookup is ambiguous, then
+ we've already issued an error message; there's no reason
+ to check again. */
+ if (ambiguous_p)
+ {
+ cp_parser_simulate_error (parser);
+ return error_mark_node;
+ }
+ /* If the next token is a `::', then the name must be a type
+ name.
+
+ [basic.lookup.qual]
+
+ During the lookup for a name preceding the :: scope
+ resolution operator, object, function, and enumerator
+ names are ignored. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ tag_type = typename_type;
+ /* Look up the name. */
+ decl = cp_parser_lookup_name (parser, identifier,
+ tag_type,
+ /*is_template=*/false,
+ /*is_namespace=*/false,
+ check_dependency_p,
+ &ambiguous_decls,
+ identifier_token->location);
+ if (ambiguous_decls)
+ {
+ if (cp_parser_parsing_tentatively (parser))
+ cp_parser_simulate_error (parser);
+ return error_mark_node;
+ }
+ }
+ }
+ else
+ {
+ /* Try a template-id. */
+ decl = cp_parser_template_id (parser, template_keyword_p,
+ check_dependency_p,
+ tag_type,
+ is_declaration);
+ if (decl == error_mark_node)
+ return error_mark_node;
+ }
+
+ decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p);
+
+ /* If this is a typename, create a TYPENAME_TYPE. */
+ if (typename_p && decl != error_mark_node)
+ {
+ decl = make_typename_type (scope, decl, typename_type,
+ /*complain=*/tf_error);
+ if (decl != error_mark_node)
+ decl = TYPE_NAME (decl);
+ }
+
+ decl = strip_using_decl (decl);
+
+ /* Check to see that it is really the name of a class. */
+ if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
+ && identifier_p (TREE_OPERAND (decl, 0))
+ && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ /* Situations like this:
+
+ template <typename T> struct A {
+ typename T::template X<int>::I i;
+ };
+
+ are problematic. Is `T::template X<int>' a class-name? The
+ standard does not seem to be definitive, but there is no other
+ valid interpretation of the following `::'. Therefore, those
+ names are considered class-names. */
+ {
+ decl = make_typename_type (scope, decl, tag_type, tf_error);
+ if (decl != error_mark_node)
+ decl = TYPE_NAME (decl);
+ }
+ else if (TREE_CODE (decl) != TYPE_DECL
+ || TREE_TYPE (decl) == error_mark_node
+ || !MAYBE_CLASS_TYPE_P (TREE_TYPE (decl))
+ /* In Objective-C 2.0, a classname followed by '.' starts a
+ dot-syntax expression, and it's not a type-name. */
+ || (c_dialect_objc ()
+ && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT
+ && objc_is_class_name (decl)))
+ decl = error_mark_node;
+
+ if (decl == error_mark_node)
+ cp_parser_error (parser, "expected class-name");
+ else if (identifier && !parser->scope)
+ maybe_note_name_used_in_class (identifier, decl);
+
+ return decl;
+}
+
+/* Parse a class-specifier.
+
+ class-specifier:
+ class-head { member-specification [opt] }
+
+ Returns the TREE_TYPE representing the class. */
+
+static tree
+cp_parser_class_specifier_1 (cp_parser* parser)
+{
+ tree type;
+ tree attributes = NULL_TREE;
+ bool nested_name_specifier_p;
+ unsigned saved_num_template_parameter_lists;
+ bool saved_in_function_body;
+ unsigned char in_statement;
+ bool in_switch_statement_p;
+ bool saved_in_unbraced_linkage_specification_p;
+ tree old_scope = NULL_TREE;
+ tree scope = NULL_TREE;
+ cp_token *closing_brace;
+
+ push_deferring_access_checks (dk_no_deferred);
+
+ /* Parse the class-head. */
+ type = cp_parser_class_head (parser,
+ &nested_name_specifier_p);
+ /* If the class-head was a semantic disaster, skip the entire body
+ of the class. */
+ if (!type)
+ {
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ pop_deferring_access_checks ();
+ return error_mark_node;
+ }
+
+ /* Look for the `{'. */
+ if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ {
+ pop_deferring_access_checks ();
+ return error_mark_node;
+ }
+
+ cp_ensure_no_omp_declare_simd (parser);
+
+ /* Issue an error message if type-definitions are forbidden here. */
+ cp_parser_check_type_definition (parser);
+ /* Remember that we are defining one more class. */
+ ++parser->num_classes_being_defined;
+ /* Inside the class, surrounding template-parameter-lists do not
+ apply. */
+ saved_num_template_parameter_lists
+ = parser->num_template_parameter_lists;
+ parser->num_template_parameter_lists = 0;
+ /* We are not in a function body. */
+ saved_in_function_body = parser->in_function_body;
+ parser->in_function_body = false;
+ /* Or in a loop. */
+ in_statement = parser->in_statement;
+ parser->in_statement = 0;
+ /* Or in a switch. */
+ in_switch_statement_p = parser->in_switch_statement_p;
+ parser->in_switch_statement_p = false;
+ /* We are not immediately inside an extern "lang" block. */
+ saved_in_unbraced_linkage_specification_p
+ = parser->in_unbraced_linkage_specification_p;
+ parser->in_unbraced_linkage_specification_p = false;
+
+ /* Start the class. */
+ if (nested_name_specifier_p)
+ {
+ scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
+ old_scope = push_inner_scope (scope);
+ }
+ type = begin_class_definition (type);
+
+ if (type == error_mark_node)
+ /* If the type is erroneous, skip the entire body of the class. */
+ cp_parser_skip_to_closing_brace (parser);
+ else
+ /* Parse the member-specification. */
+ cp_parser_member_specification_opt (parser);
+
+ /* Look for the trailing `}'. */
+ closing_brace = cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ /* Look for trailing attributes to apply to this class. */
+ if (cp_parser_allow_gnu_extensions_p (parser))
+ attributes = cp_parser_gnu_attributes_opt (parser);
+ if (type != error_mark_node)
+ type = finish_struct (type, attributes);
+ if (nested_name_specifier_p)
+ pop_inner_scope (old_scope, scope);
+
+ /* We've finished a type definition. Check for the common syntax
+ error of forgetting a semicolon after the definition. We need to
+ be careful, as we can't just check for not-a-semicolon and be done
+ with it; the user might have typed:
+
+ class X { } c = ...;
+ class X { } *p = ...;
+
+ and so forth. Instead, enumerate all the possible tokens that
+ might follow this production; if we don't see one of them, then
+ complain and silently insert the semicolon. */
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ bool want_semicolon = true;
+
+ if (cp_next_tokens_can_be_std_attribute_p (parser))
+ /* Don't try to parse c++11 attributes here. As per the
+ grammar, that should be a task for
+ cp_parser_decl_specifier_seq. */
+ want_semicolon = false;
+
+ switch (token->type)
+ {
+ case CPP_NAME:
+ case CPP_SEMICOLON:
+ case CPP_MULT:
+ case CPP_AND:
+ case CPP_OPEN_PAREN:
+ case CPP_CLOSE_PAREN:
+ case CPP_COMMA:
+ want_semicolon = false;
+ break;
+
+ /* While it's legal for type qualifiers and storage class
+ specifiers to follow type definitions in the grammar, only
+ compiler testsuites contain code like that. Assume that if
+ we see such code, then what we're really seeing is a case
+ like:
+
+ class X { }
+ const <type> var = ...;
+
+ or
+
+ class Y { }
+ static <type> func (...) ...
+
+ i.e. the qualifier or specifier applies to the next
+ declaration. To do so, however, we need to look ahead one
+ more token to see if *that* token is a type specifier.
+
+ This code could be improved to handle:
+
+ class Z { }
+ static const <type> var = ...; */
+ case CPP_KEYWORD:
+ if (keyword_is_decl_specifier (token->keyword))
+ {
+ cp_token *lookahead = cp_lexer_peek_nth_token (parser->lexer, 2);
+
+ /* Handling user-defined types here would be nice, but very
+ tricky. */
+ want_semicolon
+ = (lookahead->type == CPP_KEYWORD
+ && keyword_begins_type_specifier (lookahead->keyword));
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* If we don't have a type, then something is very wrong and we
+ shouldn't try to do anything clever. Likewise for not seeing the
+ closing brace. */
+ if (closing_brace && TYPE_P (type) && want_semicolon)
+ {
+ cp_token_position prev
+ = cp_lexer_previous_token_position (parser->lexer);
+ cp_token *prev_token = cp_lexer_token_at (parser->lexer, prev);
+ location_t loc = prev_token->location;
+
+ if (CLASSTYPE_DECLARED_CLASS (type))
+ error_at (loc, "expected %<;%> after class definition");
+ else if (TREE_CODE (type) == RECORD_TYPE)
+ error_at (loc, "expected %<;%> after struct definition");
+ else if (TREE_CODE (type) == UNION_TYPE)
+ error_at (loc, "expected %<;%> after union definition");
+ else
+ gcc_unreachable ();
+
+ /* Unget one token and smash it to look as though we encountered
+ a semicolon in the input stream. */
+ cp_lexer_set_token_position (parser->lexer, prev);
+ token = cp_lexer_peek_token (parser->lexer);
+ token->type = CPP_SEMICOLON;
+ token->keyword = RID_MAX;
+ }
+ }
+
+ /* If this class is not itself within the scope of another class,
+ then we need to parse the bodies of all of the queued function
+ definitions. Note that the queued functions defined in a class
+ are not always processed immediately following the
+ class-specifier for that class. Consider:
+
+ struct A {
+ struct B { void f() { sizeof (A); } };
+ };
+
+ If `f' were processed before the processing of `A' were
+ completed, there would be no way to compute the size of `A'.
+ Note that the nesting we are interested in here is lexical --
+ not the semantic nesting given by TYPE_CONTEXT. In particular,
+ for:
+
+ struct A { struct B; };
+ struct A::B { void f() { } };
+
+ there is no need to delay the parsing of `A::B::f'. */
+ if (--parser->num_classes_being_defined == 0)
+ {
+ tree decl;
+ tree class_type = NULL_TREE;
+ tree pushed_scope = NULL_TREE;
+ unsigned ix;
+ cp_default_arg_entry *e;
+ tree save_ccp, save_ccr;
+
+ /* In a first pass, parse default arguments to the functions.
+ Then, in a second pass, parse the bodies of the functions.
+ This two-phased approach handles cases like:
+
+ struct S {
+ void f() { g(); }
+ void g(int i = 3);
+ };
+
+ */
+ FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_default_args, ix, e)
+ {
+ decl = e->decl;
+ /* If there are default arguments that have not yet been processed,
+ take care of them now. */
+ if (class_type != e->class_type)
+ {
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ class_type = e->class_type;
+ pushed_scope = push_scope (class_type);
+ }
+ /* Make sure that any template parameters are in scope. */
+ maybe_begin_member_template_processing (decl);
+ /* Parse the default argument expressions. */
+ cp_parser_late_parsing_default_args (parser, decl);
+ /* Remove any template parameters from the symbol table. */
+ maybe_end_member_template_processing ();
+ }
+ vec_safe_truncate (unparsed_funs_with_default_args, 0);
+ /* Now parse any NSDMIs. */
+ save_ccp = current_class_ptr;
+ save_ccr = current_class_ref;
+ FOR_EACH_VEC_SAFE_ELT (unparsed_nsdmis, ix, decl)
+ {
+ if (class_type != DECL_CONTEXT (decl))
+ {
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ class_type = DECL_CONTEXT (decl);
+ pushed_scope = push_scope (class_type);
+ }
+ inject_this_parameter (class_type, TYPE_UNQUALIFIED);
+ cp_parser_late_parsing_nsdmi (parser, decl);
+ }
+ vec_safe_truncate (unparsed_nsdmis, 0);
+ current_class_ptr = save_ccp;
+ current_class_ref = save_ccr;
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ /* Now parse the body of the functions. */
+ if (flag_openmp)
+ {
+ /* OpenMP UDRs need to be parsed before all other functions. */
+ FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
+ if (DECL_OMP_DECLARE_REDUCTION_P (decl))
+ cp_parser_late_parsing_for_member (parser, decl);
+ FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
+ if (!DECL_OMP_DECLARE_REDUCTION_P (decl))
+ cp_parser_late_parsing_for_member (parser, decl);
+ }
+ else
+ FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
+ cp_parser_late_parsing_for_member (parser, decl);
+ vec_safe_truncate (unparsed_funs_with_definitions, 0);
+ }
+
+ /* Put back any saved access checks. */
+ pop_deferring_access_checks ();
+
+ /* Restore saved state. */
+ parser->in_switch_statement_p = in_switch_statement_p;
+ parser->in_statement = in_statement;
+ parser->in_function_body = saved_in_function_body;
+ parser->num_template_parameter_lists
+ = saved_num_template_parameter_lists;
+ parser->in_unbraced_linkage_specification_p
+ = saved_in_unbraced_linkage_specification_p;
+
+ return type;
+}
+
+static tree
+cp_parser_class_specifier (cp_parser* parser)
+{
+ tree ret;
+ timevar_push (TV_PARSE_STRUCT);
+ ret = cp_parser_class_specifier_1 (parser);
+ timevar_pop (TV_PARSE_STRUCT);
+ return ret;
+}
+
+/* Parse a class-head.
+
+ class-head:
+ class-key identifier [opt] base-clause [opt]
+ class-key nested-name-specifier identifier class-virt-specifier [opt] base-clause [opt]
+ class-key nested-name-specifier [opt] template-id
+ base-clause [opt]
+
+ class-virt-specifier:
+ final
+
+ GNU Extensions:
+ class-key attributes identifier [opt] base-clause [opt]
+ class-key attributes nested-name-specifier identifier base-clause [opt]
+ class-key attributes nested-name-specifier [opt] template-id
+ base-clause [opt]
+
+ Upon return BASES is initialized to the list of base classes (or
+ NULL, if there are none) in the same form returned by
+ cp_parser_base_clause.
+
+ Returns the TYPE of the indicated class. Sets
+ *NESTED_NAME_SPECIFIER_P to TRUE iff one of the productions
+ involving a nested-name-specifier was used, and FALSE otherwise.
+
+ Returns error_mark_node if this is not a class-head.
+
+ Returns NULL_TREE if the class-head is syntactically valid, but
+ semantically invalid in a way that means we should skip the entire
+ body of the class. */
+
+static tree
+cp_parser_class_head (cp_parser* parser,
+ bool* nested_name_specifier_p)
+{
+ tree nested_name_specifier;
+ enum tag_types class_key;
+ tree id = NULL_TREE;
+ tree type = NULL_TREE;
+ tree attributes;
+ tree bases;
+ cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
+ bool template_id_p = false;
+ bool qualified_p = false;
+ bool invalid_nested_name_p = false;
+ bool invalid_explicit_specialization_p = false;
+ bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+ tree pushed_scope = NULL_TREE;
+ unsigned num_templates;
+ cp_token *type_start_token = NULL, *nested_name_specifier_token_start = NULL;
+ /* Assume no nested-name-specifier will be present. */
+ *nested_name_specifier_p = false;
+ /* Assume no template parameter lists will be used in defining the
+ type. */
+ num_templates = 0;
+ parser->colon_corrects_to_scope_p = false;
+
+ /* Look for the class-key. */
+ class_key = cp_parser_class_key (parser);
+ if (class_key == none_type)
+ return error_mark_node;
+
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
+
+ /* If the next token is `::', that is invalid -- but sometimes
+ people do try to write:
+
+ struct ::S {};
+
+ Handle this gracefully by accepting the extra qualifier, and then
+ issuing an error about it later if this really is a
+ class-head. If it turns out just to be an elaborated type
+ specifier, remain silent. */
+ if (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false))
+ qualified_p = true;
+
+ push_deferring_access_checks (dk_no_check);
+
+ /* Determine the name of the class. Begin by looking for an
+ optional nested-name-specifier. */
+ nested_name_specifier_token_start = cp_lexer_peek_token (parser->lexer);
+ nested_name_specifier
+ = cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/false,
+ /*type_p=*/true,
+ /*is_declaration=*/false);
+ /* If there was a nested-name-specifier, then there *must* be an
+ identifier. */
+ if (nested_name_specifier)
+ {
+ type_start_token = cp_lexer_peek_token (parser->lexer);
+ /* Although the grammar says `identifier', it really means
+ `class-name' or `template-name'. You are only allowed to
+ define a class that has already been declared with this
+ syntax.
+
+ The proposed resolution for Core Issue 180 says that wherever
+ you see `class T::X' you should treat `X' as a type-name.
+
+ It is OK to define an inaccessible class; for example:
+
+ class A { class B; };
+ class A::B {};
+
+ We do not know if we will see a class-name, or a
+ template-name. We look for a class-name first, in case the
+ class-name is a template-id; if we looked for the
+ template-name first we would stop after the template-name. */
+ cp_parser_parse_tentatively (parser);
+ type = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ class_type,
+ /*check_dependency_p=*/false,
+ /*class_head_p=*/true,
+ /*is_declaration=*/false);
+ /* If that didn't work, ignore the nested-name-specifier. */
+ if (!cp_parser_parse_definitely (parser))
+ {
+ invalid_nested_name_p = true;
+ type_start_token = cp_lexer_peek_token (parser->lexer);
+ id = cp_parser_identifier (parser);
+ if (id == error_mark_node)
+ id = NULL_TREE;
+ }
+ /* If we could not find a corresponding TYPE, treat this
+ declaration like an unqualified declaration. */
+ if (type == error_mark_node)
+ nested_name_specifier = NULL_TREE;
+ /* Otherwise, count the number of templates used in TYPE and its
+ containing scopes. */
+ else
+ {
+ tree scope;
+
+ for (scope = TREE_TYPE (type);
+ scope && TREE_CODE (scope) != NAMESPACE_DECL;
+ scope = get_containing_scope (scope))
+ if (TYPE_P (scope)
+ && CLASS_TYPE_P (scope)
+ && CLASSTYPE_TEMPLATE_INFO (scope)
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope))
+ && (!CLASSTYPE_TEMPLATE_SPECIALIZATION (scope)
+ || uses_template_parms (CLASSTYPE_TI_ARGS (scope))))
+ ++num_templates;
+ }
+ }
+ /* Otherwise, the identifier is optional. */
+ else
+ {
+ /* We don't know whether what comes next is a template-id,
+ an identifier, or nothing at all. */
+ cp_parser_parse_tentatively (parser);
+ /* Check for a template-id. */
+ type_start_token = cp_lexer_peek_token (parser->lexer);
+ id = cp_parser_template_id (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ class_key,
+ /*is_declaration=*/true);
+ /* If that didn't work, it could still be an identifier. */
+ if (!cp_parser_parse_definitely (parser))
+ {
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ type_start_token = cp_lexer_peek_token (parser->lexer);
+ id = cp_parser_identifier (parser);
+ }
+ else
+ id = NULL_TREE;
+ }
+ else
+ {
+ template_id_p = true;
+ ++num_templates;
+ }
+ }
+
+ pop_deferring_access_checks ();
+
+ if (id)
+ {
+ cp_parser_check_for_invalid_template_id (parser, id,
+ class_key,
+ type_start_token->location);
+ }
+ virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
+
+ /* If it's not a `:' or a `{' then we can't really be looking at a
+ class-head, since a class-head only appears as part of a
+ class-specifier. We have to detect this situation before calling
+ xref_tag, since that has irreversible side-effects. */
+ if (!cp_parser_next_token_starts_class_definition_p (parser))
+ {
+ cp_parser_error (parser, "expected %<{%> or %<:%>");
+ type = error_mark_node;
+ goto out;
+ }
+
+ /* At this point, we're going ahead with the class-specifier, even
+ if some other problem occurs. */
+ cp_parser_commit_to_tentative_parse (parser);
+ if (virt_specifiers & VIRT_SPEC_OVERRIDE)
+ {
+ cp_parser_error (parser,
+ "cannot specify %<override%> for a class");
+ type = error_mark_node;
+ goto out;
+ }
+ /* Issue the error about the overly-qualified name now. */
+ if (qualified_p)
+ {
+ cp_parser_error (parser,
+ "global qualification of class name is invalid");
+ type = error_mark_node;
+ goto out;
+ }
+ else if (invalid_nested_name_p)
+ {
+ cp_parser_error (parser,
+ "qualified name does not name a class");
+ type = error_mark_node;
+ goto out;
+ }
+ else if (nested_name_specifier)
+ {
+ tree scope;
+
+ /* Reject typedef-names in class heads. */
+ if (!DECL_IMPLICIT_TYPEDEF_P (type))
+ {
+ error_at (type_start_token->location,
+ "invalid class name in declaration of %qD",
+ type);
+ type = NULL_TREE;
+ goto done;
+ }
+
+ /* Figure out in what scope the declaration is being placed. */
+ scope = current_scope ();
+ /* If that scope does not contain the scope in which the
+ class was originally declared, the program is invalid. */
+ if (scope && !is_ancestor (scope, nested_name_specifier))
+ {
+ if (at_namespace_scope_p ())
+ error_at (type_start_token->location,
+ "declaration of %qD in namespace %qD which does not "
+ "enclose %qD",
+ type, scope, nested_name_specifier);
+ else
+ error_at (type_start_token->location,
+ "declaration of %qD in %qD which does not enclose %qD",
+ type, scope, nested_name_specifier);
+ type = NULL_TREE;
+ goto done;
+ }
+ /* [dcl.meaning]
+
+ A declarator-id shall not be qualified except for the
+ definition of a ... nested class outside of its class
+ ... [or] the definition or explicit instantiation of a
+ class member of a namespace outside of its namespace. */
+ if (scope == nested_name_specifier)
+ {
+ permerror (nested_name_specifier_token_start->location,
+ "extra qualification not allowed");
+ nested_name_specifier = NULL_TREE;
+ num_templates = 0;
+ }
+ }
+ /* An explicit-specialization must be preceded by "template <>". If
+ it is not, try to recover gracefully. */
+ if (at_namespace_scope_p ()
+ && parser->num_template_parameter_lists == 0
+ && template_id_p)
+ {
+ error_at (type_start_token->location,
+ "an explicit specialization must be preceded by %<template <>%>");
+ invalid_explicit_specialization_p = true;
+ /* Take the same action that would have been taken by
+ cp_parser_explicit_specialization. */
+ ++parser->num_template_parameter_lists;
+ begin_specialization ();
+ }
+ /* There must be no "return" statements between this point and the
+ end of this function; set "type "to the correct return value and
+ use "goto done;" to return. */
+ /* Make sure that the right number of template parameters were
+ present. */
+ if (!cp_parser_check_template_parameters (parser, num_templates,
+ type_start_token->location,
+ /*declarator=*/NULL))
+ {
+ /* If something went wrong, there is no point in even trying to
+ process the class-definition. */
+ type = NULL_TREE;
+ goto done;
+ }
+
+ /* Look up the type. */
+ if (template_id_p)
+ {
+ if (TREE_CODE (id) == TEMPLATE_ID_EXPR
+ && (DECL_FUNCTION_TEMPLATE_P (TREE_OPERAND (id, 0))
+ || TREE_CODE (TREE_OPERAND (id, 0)) == OVERLOAD))
+ {
+ error_at (type_start_token->location,
+ "function template %qD redeclared as a class template", id);
+ type = error_mark_node;
+ }
+ else
+ {
+ type = TREE_TYPE (id);
+ type = maybe_process_partial_specialization (type);
+ }
+ if (nested_name_specifier)
+ pushed_scope = push_scope (nested_name_specifier);
+ }
+ else if (nested_name_specifier)
+ {
+ tree class_type;
+
+ /* Given:
+
+ template <typename T> struct S { struct T };
+ template <typename T> struct S<T>::T { };
+
+ we will get a TYPENAME_TYPE when processing the definition of
+ `S::T'. We need to resolve it to the actual type before we
+ try to define it. */
+ if (TREE_CODE (TREE_TYPE (type)) == TYPENAME_TYPE)
+ {
+ class_type = resolve_typename_type (TREE_TYPE (type),
+ /*only_current_p=*/false);
+ if (TREE_CODE (class_type) != TYPENAME_TYPE)
+ type = TYPE_NAME (class_type);
+ else
+ {
+ cp_parser_error (parser, "could not resolve typename type");
+ type = error_mark_node;
+ }
+ }
+
+ if (maybe_process_partial_specialization (TREE_TYPE (type))
+ == error_mark_node)
+ {
+ type = NULL_TREE;
+ goto done;
+ }
+
+ class_type = current_class_type;
+ /* Enter the scope indicated by the nested-name-specifier. */
+ pushed_scope = push_scope (nested_name_specifier);
+ /* Get the canonical version of this type. */
+ type = TYPE_MAIN_DECL (TREE_TYPE (type));
+ /* Call push_template_decl if it seems like we should be defining a
+ template either from the template headers or the type we're
+ defining, so that we diagnose both extra and missing headers. */
+ if ((PROCESSING_REAL_TEMPLATE_DECL_P ()
+ || (CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (type))
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE
+ (TREE_TYPE (type)))))
+ && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (type)))
+ {
+ type = push_template_decl (type);
+ if (type == error_mark_node)
+ {
+ type = NULL_TREE;
+ goto done;
+ }
+ }
+
+ type = TREE_TYPE (type);
+ *nested_name_specifier_p = true;
+ }
+ else /* The name is not a nested name. */
+ {
+ /* If the class was unnamed, create a dummy name. */
+ if (!id)
+ id = make_anon_name ();
+ type = xref_tag (class_key, id, /*tag_scope=*/ts_current,
+ parser->num_template_parameter_lists);
+ }
+
+ /* Indicate whether this class was declared as a `class' or as a
+ `struct'. */
+ if (TREE_CODE (type) == RECORD_TYPE)
+ CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_type);
+ cp_parser_check_class_key (class_key, type);
+
+ /* If this type was already complete, and we see another definition,
+ that's an error. */
+ if (type != error_mark_node && COMPLETE_TYPE_P (type))
+ {
+ error_at (type_start_token->location, "redefinition of %q#T",
+ type);
+ error_at (type_start_token->location, "previous definition of %q+#T",
+ type);
+ type = NULL_TREE;
+ goto done;
+ }
+ else if (type == error_mark_node)
+ type = NULL_TREE;
+
+ if (type)
+ {
+ /* Apply attributes now, before any use of the class as a template
+ argument in its base list. */
+ cplus_decl_attributes (&type, attributes, (int)ATTR_FLAG_TYPE_IN_PLACE);
+ fixup_attribute_variants (type);
+ }
+
+ /* We will have entered the scope containing the class; the names of
+ base classes should be looked up in that context. For example:
+
+ struct A { struct B {}; struct C; };
+ struct A::C : B {};
+
+ is valid. */
+
+ /* Get the list of base-classes, if there is one. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ /* PR59482: enter the class scope so that base-specifiers are looked
+ up correctly. */
+ if (type)
+ pushclass (type);
+ bases = cp_parser_base_clause (parser);
+ /* PR59482: get out of the previously pushed class scope so that the
+ subsequent pops pop the right thing. */
+ if (type)
+ popclass ();
+ }
+ else
+ bases = NULL_TREE;
+
+ /* If we're really defining a class, process the base classes.
+ If they're invalid, fail. */
+ if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
+ && !xref_basetypes (type, bases))
+ type = NULL_TREE;
+
+ done:
+ /* Leave the scope given by the nested-name-specifier. We will
+ enter the class scope itself while processing the members. */
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+
+ if (invalid_explicit_specialization_p)
+ {
+ end_specialization ();
+ --parser->num_template_parameter_lists;
+ }
+
+ if (type)
+ DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
+ if (type && (virt_specifiers & VIRT_SPEC_FINAL))
+ CLASSTYPE_FINAL (type) = 1;
+ out:
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+ return type;
+}
+
+/* Parse a class-key.
+
+ class-key:
+ class
+ struct
+ union
+
+ Returns the kind of class-key specified, or none_type to indicate
+ error. */
+
+static enum tag_types
+cp_parser_class_key (cp_parser* parser)
+{
+ cp_token *token;
+ enum tag_types tag_type;
+
+ /* Look for the class-key. */
+ token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_KEY);
+ if (!token)
+ return none_type;
+
+ /* Check to see if the TOKEN is a class-key. */
+ tag_type = cp_parser_token_is_class_key (token);
+ if (!tag_type)
+ cp_parser_error (parser, "expected class-key");
+ return tag_type;
+}
+
+/* Parse an (optional) member-specification.
+
+ member-specification:
+ member-declaration member-specification [opt]
+ access-specifier : member-specification [opt] */
+
+static void
+cp_parser_member_specification_opt (cp_parser* parser)
+{
+ while (true)
+ {
+ cp_token *token;
+ enum rid keyword;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's a `}', or EOF then we've seen all the members. */
+ if (token->type == CPP_CLOSE_BRACE
+ || token->type == CPP_EOF
+ || token->type == CPP_PRAGMA_EOL)
+ break;
+
+ /* See if this token is a keyword. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ case RID_PUBLIC:
+ case RID_PROTECTED:
+ case RID_PRIVATE:
+ /* Consume the access-specifier. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Remember which access-specifier is active. */
+ current_access_specifier = token->u.value;
+ /* Look for the `:'. */
+ cp_parser_require (parser, CPP_COLON, RT_COLON);
+ break;
+
+ default:
+ /* Accept #pragmas at class scope. */
+ if (token->type == CPP_PRAGMA)
+ {
+ cp_parser_pragma (parser, pragma_member);
+ break;
+ }
+
+ /* Otherwise, the next construction must be a
+ member-declaration. */
+ cp_parser_member_declaration (parser);
+ }
+ }
+}
+
+/* Parse a member-declaration.
+
+ member-declaration:
+ decl-specifier-seq [opt] member-declarator-list [opt] ;
+ function-definition ; [opt]
+ :: [opt] nested-name-specifier template [opt] unqualified-id ;
+ using-declaration
+ template-declaration
+ alias-declaration
+
+ member-declarator-list:
+ member-declarator
+ member-declarator-list , member-declarator
+
+ member-declarator:
+ declarator pure-specifier [opt]
+ declarator constant-initializer [opt]
+ identifier [opt] : constant-expression
+
+ GNU Extensions:
+
+ member-declaration:
+ __extension__ member-declaration
+
+ member-declarator:
+ declarator attributes [opt] pure-specifier [opt]
+ declarator attributes [opt] constant-initializer [opt]
+ identifier [opt] attributes [opt] : constant-expression
+
+ C++0x Extensions:
+
+ member-declaration:
+ static_assert-declaration */
+
+static void
+cp_parser_member_declaration (cp_parser* parser)
+{
+ cp_decl_specifier_seq decl_specifiers;
+ tree prefix_attributes;
+ tree decl;
+ int declares_class_or_enum;
+ bool friend_p;
+ cp_token *token = NULL;
+ cp_token *decl_spec_token_start = NULL;
+ cp_token *initializer_token_start = NULL;
+ int saved_pedantic;
+ bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+
+ /* Check for the `__extension__' keyword. */
+ if (cp_parser_extension_opt (parser, &saved_pedantic))
+ {
+ /* Recurse. */
+ cp_parser_member_declaration (parser);
+ /* Restore the old value of the PEDANTIC flag. */
+ pedantic = saved_pedantic;
+
+ return;
+ }
+
+ /* Check for a template-declaration. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
+ {
+ /* An explicit specialization here is an error condition, and we
+ expect the specialization handler to detect and report this. */
+ if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_LESS
+ && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_GREATER)
+ cp_parser_explicit_specialization (parser);
+ else
+ cp_parser_template_declaration (parser, /*member_p=*/true);
+
+ return;
+ }
+
+ /* Check for a using-declaration. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
+ {
+ if (cxx_dialect < cxx11)
+ {
+ /* Parse the using-declaration. */
+ cp_parser_using_declaration (parser,
+ /*access_declaration_p=*/false);
+ return;
+ }
+ else
+ {
+ tree decl;
+ bool alias_decl_expected;
+ cp_parser_parse_tentatively (parser);
+ decl = cp_parser_alias_declaration (parser);
+ /* Note that if we actually see the '=' token after the
+ identifier, cp_parser_alias_declaration commits the
+ tentative parse. In that case, we really expects an
+ alias-declaration. Otherwise, we expect a using
+ declaration. */
+ alias_decl_expected =
+ !cp_parser_uncommitted_to_tentative_parse_p (parser);
+ cp_parser_parse_definitely (parser);
+
+ if (alias_decl_expected)
+ finish_member_declaration (decl);
+ else
+ cp_parser_using_declaration (parser,
+ /*access_declaration_p=*/false);
+ return;
+ }
+ }
+
+ /* Check for @defs. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_DEFS))
+ {
+ tree ivar, member;
+ tree ivar_chains = cp_parser_objc_defs_expression (parser);
+ ivar = ivar_chains;
+ while (ivar)
+ {
+ member = ivar;
+ ivar = TREE_CHAIN (member);
+ TREE_CHAIN (member) = NULL_TREE;
+ finish_member_declaration (member);
+ }
+ return;
+ }
+
+ /* If the next token is `static_assert' we have a static assertion. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC_ASSERT))
+ {
+ cp_parser_static_assert (parser, /*member_p=*/true);
+ return;
+ }
+
+ parser->colon_corrects_to_scope_p = false;
+
+ if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
+ goto out;
+
+ /* Parse the decl-specifier-seq. */
+ decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
+ cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_OPTIONAL,
+ &decl_specifiers,
+ &declares_class_or_enum);
+ /* Check for an invalid type-name. */
+ if (!decl_specifiers.any_type_specifiers_p
+ && cp_parser_parse_and_diagnose_invalid_type_name (parser))
+ goto out;
+ /* If there is no declarator, then the decl-specifier-seq should
+ specify a type. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ {
+ /* If there was no decl-specifier-seq, and the next token is a
+ `;', then we have something like:
+
+ struct S { ; };
+
+ [class.mem]
+
+ Each member-declaration shall declare at least one member
+ name of the class. */
+ if (!decl_specifiers.any_specifiers_p)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ if (!in_system_header_at (token->location))
+ pedwarn (token->location, OPT_Wpedantic, "extra %<;%>");
+ }
+ else
+ {
+ tree type;
+
+ /* See if this declaration is a friend. */
+ friend_p = cp_parser_friend_p (&decl_specifiers);
+ /* If there were decl-specifiers, check to see if there was
+ a class-declaration. */
+ type = check_tag_decl (&decl_specifiers,
+ /*explicit_type_instantiation_p=*/false);
+ /* Nested classes have already been added to the class, but
+ a `friend' needs to be explicitly registered. */
+ if (friend_p)
+ {
+ /* If the `friend' keyword was present, the friend must
+ be introduced with a class-key. */
+ if (!declares_class_or_enum && cxx_dialect < cxx11)
+ pedwarn (decl_spec_token_start->location, OPT_Wpedantic,
+ "in C++03 a class-key must be used "
+ "when declaring a friend");
+ /* In this case:
+
+ template <typename T> struct A {
+ friend struct A<T>::B;
+ };
+
+ A<T>::B will be represented by a TYPENAME_TYPE, and
+ therefore not recognized by check_tag_decl. */
+ if (!type)
+ {
+ type = decl_specifiers.type;
+ if (type && TREE_CODE (type) == TYPE_DECL)
+ type = TREE_TYPE (type);
+ }
+ if (!type || !TYPE_P (type))
+ error_at (decl_spec_token_start->location,
+ "friend declaration does not name a class or "
+ "function");
+ else
+ make_friend_class (current_class_type, type,
+ /*complain=*/true);
+ }
+ /* If there is no TYPE, an error message will already have
+ been issued. */
+ else if (!type || type == error_mark_node)
+ ;
+ /* An anonymous aggregate has to be handled specially; such
+ a declaration really declares a data member (with a
+ particular type), as opposed to a nested class. */
+ else if (ANON_AGGR_TYPE_P (type))
+ {
+ /* C++11 9.5/6. */
+ if (decl_specifiers.storage_class != sc_none)
+ error_at (decl_spec_token_start->location,
+ "a storage class on an anonymous aggregate "
+ "in class scope is not allowed");
+
+ /* Remove constructors and such from TYPE, now that we
+ know it is an anonymous aggregate. */
+ fixup_anonymous_aggr (type);
+ /* And make the corresponding data member. */
+ decl = build_decl (decl_spec_token_start->location,
+ FIELD_DECL, NULL_TREE, type);
+ /* Add it to the class. */
+ finish_member_declaration (decl);
+ }
+ else
+ cp_parser_check_access_in_redeclaration
+ (TYPE_NAME (type),
+ decl_spec_token_start->location);
+ }
+ }
+ else
+ {
+ bool assume_semicolon = false;
+
+ /* Clear attributes from the decl_specifiers but keep them
+ around as prefix attributes that apply them to the entity
+ being declared. */
+ prefix_attributes = decl_specifiers.attributes;
+ decl_specifiers.attributes = NULL_TREE;
+
+ /* See if these declarations will be friends. */
+ friend_p = cp_parser_friend_p (&decl_specifiers);
+
+ /* Keep going until we hit the `;' at the end of the
+ declaration. */
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ tree attributes = NULL_TREE;
+ tree first_attribute;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* Check for a bitfield declaration. */
+ if (token->type == CPP_COLON
+ || (token->type == CPP_NAME
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ == CPP_COLON))
+ {
+ tree identifier;
+ tree width;
+
+ /* Get the name of the bitfield. Note that we cannot just
+ check TOKEN here because it may have been invalidated by
+ the call to cp_lexer_peek_nth_token above. */
+ if (cp_lexer_peek_token (parser->lexer)->type != CPP_COLON)
+ identifier = cp_parser_identifier (parser);
+ else
+ identifier = NULL_TREE;
+
+ /* Consume the `:' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Get the width of the bitfield. */
+ width
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant=*/false,
+ NULL);
+
+ /* Look for attributes that apply to the bitfield. */
+ attributes = cp_parser_attributes_opt (parser);
+ /* Remember which attributes are prefix attributes and
+ which are not. */
+ first_attribute = attributes;
+ /* Combine the attributes. */
+ attributes = chainon (prefix_attributes, attributes);
+
+ /* Create the bitfield declaration. */
+ decl = grokbitfield (identifier
+ ? make_id_declarator (NULL_TREE,
+ identifier,
+ sfk_none)
+ : NULL,
+ &decl_specifiers,
+ width,
+ attributes);
+ }
+ else
+ {
+ cp_declarator *declarator;
+ tree initializer;
+ tree asm_specification;
+ int ctor_dtor_or_conv_p;
+
+ /* Parse the declarator. */
+ declarator
+ = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+ &ctor_dtor_or_conv_p,
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/true);
+
+ /* If something went wrong parsing the declarator, make sure
+ that we at least consume some tokens. */
+ if (declarator == cp_error_declarator)
+ {
+ /* Skip to the end of the statement. */
+ cp_parser_skip_to_end_of_statement (parser);
+ /* If the next token is not a semicolon, that is
+ probably because we just skipped over the body of
+ a function. So, we consume a semicolon if
+ present, but do not issue an error message if it
+ is not present. */
+ if (cp_lexer_next_token_is (parser->lexer,
+ CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ goto out;
+ }
+
+ if (declares_class_or_enum & 2)
+ cp_parser_check_for_definition_in_return_type
+ (declarator, decl_specifiers.type,
+ decl_specifiers.locations[ds_type_spec]);
+
+ /* Look for an asm-specification. */
+ asm_specification = cp_parser_asm_specification_opt (parser);
+ /* Look for attributes that apply to the declaration. */
+ attributes = cp_parser_attributes_opt (parser);
+ /* Remember which attributes are prefix attributes and
+ which are not. */
+ first_attribute = attributes;
+ /* Combine the attributes. */
+ attributes = chainon (prefix_attributes, attributes);
+
+ /* If it's an `=', then we have a constant-initializer or a
+ pure-specifier. It is not correct to parse the
+ initializer before registering the member declaration
+ since the member declaration should be in scope while
+ its initializer is processed. However, the rest of the
+ front end does not yet provide an interface that allows
+ us to handle this correctly. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ {
+ /* In [class.mem]:
+
+ A pure-specifier shall be used only in the declaration of
+ a virtual function.
+
+ A member-declarator can contain a constant-initializer
+ only if it declares a static member of integral or
+ enumeration type.
+
+ Therefore, if the DECLARATOR is for a function, we look
+ for a pure-specifier; otherwise, we look for a
+ constant-initializer. When we call `grokfield', it will
+ perform more stringent semantics checks. */
+ initializer_token_start = cp_lexer_peek_token (parser->lexer);
+ if (function_declarator_p (declarator)
+ || (decl_specifiers.type
+ && TREE_CODE (decl_specifiers.type) == TYPE_DECL
+ && declarator->kind == cdk_id
+ && (TREE_CODE (TREE_TYPE (decl_specifiers.type))
+ == FUNCTION_TYPE)))
+ initializer = cp_parser_pure_specifier (parser);
+ else if (decl_specifiers.storage_class != sc_static)
+ initializer = cp_parser_save_nsdmi (parser);
+ else if (cxx_dialect >= cxx11)
+ {
+ bool nonconst;
+ /* Don't require a constant rvalue in C++11, since we
+ might want a reference constant. We'll enforce
+ constancy later. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the initializer. */
+ initializer = cp_parser_initializer_clause (parser,
+ &nonconst);
+ }
+ else
+ /* Parse the initializer. */
+ initializer = cp_parser_constant_initializer (parser);
+ }
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
+ && !function_declarator_p (declarator))
+ {
+ bool x;
+ if (decl_specifiers.storage_class != sc_static)
+ initializer = cp_parser_save_nsdmi (parser);
+ else
+ initializer = cp_parser_initializer (parser, &x, &x);
+ }
+ /* Otherwise, there is no initializer. */
+ else
+ initializer = NULL_TREE;
+
+ /* See if we are probably looking at a function
+ definition. We are certainly not looking at a
+ member-declarator. Calling `grokfield' has
+ side-effects, so we must not do it unless we are sure
+ that we are looking at a member-declarator. */
+ if (cp_parser_token_starts_function_definition_p
+ (cp_lexer_peek_token (parser->lexer)))
+ {
+ /* The grammar does not allow a pure-specifier to be
+ used when a member function is defined. (It is
+ possible that this fact is an oversight in the
+ standard, since a pure function may be defined
+ outside of the class-specifier. */
+ if (initializer && initializer_token_start)
+ error_at (initializer_token_start->location,
+ "pure-specifier on function-definition");
+ decl = cp_parser_save_member_function_body (parser,
+ &decl_specifiers,
+ declarator,
+ attributes);
+ if (parser->fully_implicit_function_template_p)
+ decl = finish_fully_implicit_template (parser, decl);
+ /* If the member was not a friend, declare it here. */
+ if (!friend_p)
+ finish_member_declaration (decl);
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If the next token is a semicolon, consume it. */
+ if (token->type == CPP_SEMICOLON)
+ cp_lexer_consume_token (parser->lexer);
+ goto out;
+ }
+ else
+ if (declarator->kind == cdk_function)
+ declarator->id_loc = token->location;
+ /* Create the declaration. */
+ decl = grokfield (declarator, &decl_specifiers,
+ initializer, /*init_const_expr_p=*/true,
+ asm_specification, attributes);
+ if (parser->fully_implicit_function_template_p)
+ {
+ if (friend_p)
+ finish_fully_implicit_template (parser, 0);
+ else
+ decl = finish_fully_implicit_template (parser, decl);
+ }
+ }
+
+ cp_finalize_omp_declare_simd (parser, decl);
+
+ /* Reset PREFIX_ATTRIBUTES. */
+ while (attributes && TREE_CHAIN (attributes) != first_attribute)
+ attributes = TREE_CHAIN (attributes);
+ if (attributes)
+ TREE_CHAIN (attributes) = NULL_TREE;
+
+ /* If there is any qualification still in effect, clear it
+ now; we will be starting fresh with the next declarator. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ /* If it's a `,', then there are more declarators. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ {
+ cp_token *token = cp_lexer_previous_token (parser->lexer);
+ error_at (token->location,
+ "stray %<,%> at end of member declaration");
+ }
+ }
+ /* If the next token isn't a `;', then we have a parse error. */
+ else if (cp_lexer_next_token_is_not (parser->lexer,
+ CPP_SEMICOLON))
+ {
+ /* The next token might be a ways away from where the
+ actual semicolon is missing. Find the previous token
+ and use that for our error position. */
+ cp_token *token = cp_lexer_previous_token (parser->lexer);
+ error_at (token->location,
+ "expected %<;%> at end of member declaration");
+
+ /* Assume that the user meant to provide a semicolon. If
+ we were to cp_parser_skip_to_end_of_statement, we might
+ skip to a semicolon inside a member function definition
+ and issue nonsensical error messages. */
+ assume_semicolon = true;
+ }
+
+ if (decl)
+ {
+ /* Add DECL to the list of members. */
+ if (!friend_p)
+ finish_member_declaration (decl);
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ cp_parser_save_default_args (parser, decl);
+ else if (TREE_CODE (decl) == FIELD_DECL
+ && !DECL_C_BIT_FIELD (decl)
+ && DECL_INITIAL (decl))
+ /* Add DECL to the queue of NSDMI to be parsed later. */
+ vec_safe_push (unparsed_nsdmis, decl);
+ }
+
+ if (assume_semicolon)
+ goto out;
+ }
+ }
+
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ out:
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+}
+
+/* Parse a pure-specifier.
+
+ pure-specifier:
+ = 0
+
+ Returns INTEGER_ZERO_NODE if a pure specifier is found.
+ Otherwise, ERROR_MARK_NODE is returned. */
+
+static tree
+cp_parser_pure_specifier (cp_parser* parser)
+{
+ cp_token *token;
+
+ /* Look for the `=' token. */
+ if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
+ return error_mark_node;
+ /* Look for the `0' token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ if (token->type == CPP_EOF
+ || token->type == CPP_PRAGMA_EOL)
+ return error_mark_node;
+
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Accept = default or = delete in c++0x mode. */
+ if (token->keyword == RID_DEFAULT
+ || token->keyword == RID_DELETE)
+ {
+ maybe_warn_cpp0x (CPP0X_DEFAULTED_DELETED);
+ return token->u.value;
+ }
+
+ /* c_lex_with_flags marks a single digit '0' with PURE_ZERO. */
+ if (token->type != CPP_NUMBER || !(token->flags & PURE_ZERO))
+ {
+ cp_parser_error (parser,
+ "invalid pure specifier (only %<= 0%> is allowed)");
+ cp_parser_skip_to_end_of_statement (parser);
+ return error_mark_node;
+ }
+ if (PROCESSING_REAL_TEMPLATE_DECL_P ())
+ {
+ error_at (token->location, "templates may not be %<virtual%>");
+ return error_mark_node;
+ }
+
+ return integer_zero_node;
+}
+
+/* Parse a constant-initializer.
+
+ constant-initializer:
+ = constant-expression
+
+ Returns a representation of the constant-expression. */
+
+static tree
+cp_parser_constant_initializer (cp_parser* parser)
+{
+ /* Look for the `=' token. */
+ if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
+ return error_mark_node;
+
+ /* It is invalid to write:
+
+ struct S { static const int i = { 7 }; };
+
+ */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ cp_parser_error (parser,
+ "a brace-enclosed initializer is not allowed here");
+ /* Consume the opening brace. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Skip the initializer. */
+ cp_parser_skip_to_closing_brace (parser);
+ /* Look for the trailing `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+
+ return error_mark_node;
+ }
+
+ return cp_parser_constant_expression (parser,
+ /*allow_non_constant=*/false,
+ NULL);
+}
+
+/* Derived classes [gram.class.derived] */
+
+/* Parse a base-clause.
+
+ base-clause:
+ : base-specifier-list
+
+ base-specifier-list:
+ base-specifier ... [opt]
+ base-specifier-list , base-specifier ... [opt]
+
+ Returns a TREE_LIST representing the base-classes, in the order in
+ which they were declared. The representation of each node is as
+ described by cp_parser_base_specifier.
+
+ In the case that no bases are specified, this function will return
+ NULL_TREE, not ERROR_MARK_NODE. */
+
+static tree
+cp_parser_base_clause (cp_parser* parser)
+{
+ tree bases = NULL_TREE;
+
+ /* Look for the `:' that begins the list. */
+ cp_parser_require (parser, CPP_COLON, RT_COLON);
+
+ /* Scan the base-specifier-list. */
+ while (true)
+ {
+ cp_token *token;
+ tree base;
+ bool pack_expansion_p = false;
+
+ /* Look for the base-specifier. */
+ base = cp_parser_base_specifier (parser);
+ /* Look for the (optional) ellipsis. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ /* Consume the `...'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ pack_expansion_p = true;
+ }
+
+ /* Add BASE to the front of the list. */
+ if (base && base != error_mark_node)
+ {
+ if (pack_expansion_p)
+ /* Make this a pack expansion type. */
+ TREE_VALUE (base) = make_pack_expansion (TREE_VALUE (base));
+
+ if (!check_for_bare_parameter_packs (TREE_VALUE (base)))
+ {
+ TREE_CHAIN (base) = bases;
+ bases = base;
+ }
+ }
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not a comma, then the list is complete. */
+ if (token->type != CPP_COMMA)
+ break;
+ /* Consume the `,'. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ /* PARSER->SCOPE may still be non-NULL at this point, if the last
+ base class had a qualified name. However, the next name that
+ appears is certainly not qualified. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+
+ return nreverse (bases);
+}
+
+/* Parse a base-specifier.
+
+ base-specifier:
+ :: [opt] nested-name-specifier [opt] class-name
+ virtual access-specifier [opt] :: [opt] nested-name-specifier
+ [opt] class-name
+ access-specifier virtual [opt] :: [opt] nested-name-specifier
+ [opt] class-name
+
+ Returns a TREE_LIST. The TREE_PURPOSE will be one of
+ ACCESS_{DEFAULT,PUBLIC,PROTECTED,PRIVATE}_[VIRTUAL]_NODE to
+ indicate the specifiers provided. The TREE_VALUE will be a TYPE
+ (or the ERROR_MARK_NODE) indicating the type that was specified. */
+
+static tree
+cp_parser_base_specifier (cp_parser* parser)
+{
+ cp_token *token;
+ bool done = false;
+ bool virtual_p = false;
+ bool duplicate_virtual_error_issued_p = false;
+ bool duplicate_access_error_issued_p = false;
+ bool class_scope_p, template_p;
+ tree access = access_default_node;
+ tree type;
+
+ /* Process the optional `virtual' and `access-specifier'. */
+ while (!done)
+ {
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Process `virtual'. */
+ switch (token->keyword)
+ {
+ case RID_VIRTUAL:
+ /* If `virtual' appears more than once, issue an error. */
+ if (virtual_p && !duplicate_virtual_error_issued_p)
+ {
+ cp_parser_error (parser,
+ "%<virtual%> specified more than once in base-specified");
+ duplicate_virtual_error_issued_p = true;
+ }
+
+ virtual_p = true;
+
+ /* Consume the `virtual' token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ break;
+
+ case RID_PUBLIC:
+ case RID_PROTECTED:
+ case RID_PRIVATE:
+ /* If more than one access specifier appears, issue an
+ error. */
+ if (access != access_default_node
+ && !duplicate_access_error_issued_p)
+ {
+ cp_parser_error (parser,
+ "more than one access specifier in base-specified");
+ duplicate_access_error_issued_p = true;
+ }
+
+ access = ridpointers[(int) token->keyword];
+
+ /* Consume the access-specifier. */
+ cp_lexer_consume_token (parser->lexer);
+
+ break;
+
+ default:
+ done = true;
+ break;
+ }
+ }
+ /* It is not uncommon to see programs mechanically, erroneously, use
+ the 'typename' keyword to denote (dependent) qualified types
+ as base classes. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
+ {
+ token = cp_lexer_peek_token (parser->lexer);
+ if (!processing_template_decl)
+ error_at (token->location,
+ "keyword %<typename%> not allowed outside of templates");
+ else
+ error_at (token->location,
+ "keyword %<typename%> not allowed in this context "
+ "(the base class is implicitly a type)");
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ /* Look for the optional `::' operator. */
+ cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
+ /* Look for the nested-name-specifier. The simplest way to
+ implement:
+
+ [temp.res]
+
+ The keyword `typename' is not permitted in a base-specifier or
+ mem-initializer; in these contexts a qualified name that
+ depends on a template-parameter is implicitly assumed to be a
+ type name.
+
+ is to pretend that we have seen the `typename' keyword at this
+ point. */
+ cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/true,
+ /*check_dependency_p=*/true,
+ typename_type,
+ /*is_declaration=*/true);
+ /* If the base class is given by a qualified name, assume that names
+ we see are type names or templates, as appropriate. */
+ class_scope_p = (parser->scope && TYPE_P (parser->scope));
+ template_p = class_scope_p && cp_parser_optional_template_keyword (parser);
+
+ if (!parser->scope
+ && cp_lexer_next_token_is_decltype (parser->lexer))
+ /* DR 950 allows decltype as a base-specifier. */
+ type = cp_parser_decltype (parser);
+ else
+ {
+ /* Otherwise, look for the class-name. */
+ type = cp_parser_class_name (parser,
+ class_scope_p,
+ template_p,
+ typename_type,
+ /*check_dependency_p=*/true,
+ /*class_head_p=*/false,
+ /*is_declaration=*/true);
+ type = TREE_TYPE (type);
+ }
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ return finish_base_specifier (type, access, virtual_p);
+}
+
+/* Exception handling [gram.exception] */
+
+/* Parse an (optional) noexcept-specification.
+
+ noexcept-specification:
+ noexcept ( constant-expression ) [opt]
+
+ If no noexcept-specification is present, returns NULL_TREE.
+ Otherwise, if REQUIRE_CONSTEXPR is false, then either parse and return any
+ expression if parentheses follow noexcept, or return BOOLEAN_TRUE_NODE if
+ there are no parentheses. CONSUMED_EXPR will be set accordingly.
+ Otherwise, returns a noexcept specification unless RETURN_COND is true,
+ in which case a boolean condition is returned instead. */
+
+static tree
+cp_parser_noexcept_specification_opt (cp_parser* parser,
+ bool require_constexpr,
+ bool* consumed_expr,
+ bool return_cond)
+{
+ cp_token *token;
+ const char *saved_message;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* Is it a noexcept-specification? */
+ if (cp_parser_is_keyword (token, RID_NOEXCEPT))
+ {
+ tree expr;
+ cp_lexer_consume_token (parser->lexer);
+
+ if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
+ {
+ cp_lexer_consume_token (parser->lexer);
+
+ if (require_constexpr)
+ {
+ /* Types may not be defined in an exception-specification. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in an exception-specification");
+
+ expr = cp_parser_constant_expression (parser, false, NULL);
+
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+ }
+ else
+ {
+ expr = cp_parser_expression (parser, false, NULL);
+ *consumed_expr = true;
+ }
+
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ }
+ else
+ {
+ expr = boolean_true_node;
+ if (!require_constexpr)
+ *consumed_expr = false;
+ }
+
+ /* We cannot build a noexcept-spec right away because this will check
+ that expr is a constexpr. */
+ if (!return_cond)
+ return build_noexcept_spec (expr, tf_warning_or_error);
+ else
+ return expr;
+ }
+ else
+ return NULL_TREE;
+}
+
+/* Parse an (optional) exception-specification.
+
+ exception-specification:
+ throw ( type-id-list [opt] )
+
+ Returns a TREE_LIST representing the exception-specification. The
+ TREE_VALUE of each node is a type. */
+
+static tree
+cp_parser_exception_specification_opt (cp_parser* parser)
+{
+ cp_token *token;
+ tree type_id_list;
+ const char *saved_message;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* Is it a noexcept-specification? */
+ type_id_list = cp_parser_noexcept_specification_opt(parser, true, NULL,
+ false);
+ if (type_id_list != NULL_TREE)
+ return type_id_list;
+
+ /* If it's not `throw', then there's no exception-specification. */
+ if (!cp_parser_is_keyword (token, RID_THROW))
+ return NULL_TREE;
+
+#if 0
+ /* Enable this once a lot of code has transitioned to noexcept? */
+ if (cxx_dialect >= cxx11 && !in_system_header_at (input_location))
+ warning (OPT_Wdeprecated, "dynamic exception specifications are "
+ "deprecated in C++0x; use %<noexcept%> instead");
+#endif
+
+ /* Consume the `throw'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not a `)', then there is a type-id-list. */
+ if (token->type != CPP_CLOSE_PAREN)
+ {
+ /* Types may not be defined in an exception-specification. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in an exception-specification");
+ /* Parse the type-id-list. */
+ type_id_list = cp_parser_type_id_list (parser);
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+ }
+ else
+ type_id_list = empty_except_spec;
+
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ return type_id_list;
+}
+
+/* Parse an (optional) type-id-list.
+
+ type-id-list:
+ type-id ... [opt]
+ type-id-list , type-id ... [opt]
+
+ Returns a TREE_LIST. The TREE_VALUE of each node is a TYPE,
+ in the order that the types were presented. */
+
+static tree
+cp_parser_type_id_list (cp_parser* parser)
+{
+ tree types = NULL_TREE;
+
+ while (true)
+ {
+ cp_token *token;
+ tree type;
+
+ /* Get the next type-id. */
+ type = cp_parser_type_id (parser);
+ /* Parse the optional ellipsis. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ /* Consume the `...'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Turn the type into a pack expansion expression. */
+ type = make_pack_expansion (type);
+ }
+ /* Add it to the list. */
+ types = add_exception_specifier (types, type, /*complain=*/1);
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it is not a `,', we are done. */
+ if (token->type != CPP_COMMA)
+ break;
+ /* Consume the `,'. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return nreverse (types);
+}
+
+/* Parse a try-block.
+
+ try-block:
+ try compound-statement handler-seq */
+
+static tree
+cp_parser_try_block (cp_parser* parser)
+{
+ tree try_block;
+
+ cp_parser_require_keyword (parser, RID_TRY, RT_TRY);
+ try_block = begin_try_block ();
+ cp_parser_compound_statement (parser, NULL, true, false);
+ finish_try_block (try_block);
+ cp_parser_handler_seq (parser);
+ finish_handler_sequence (try_block);
+
+ return try_block;
+}
+
+/* Parse a function-try-block.
+
+ function-try-block:
+ try ctor-initializer [opt] function-body handler-seq */
+
+static bool
+cp_parser_function_try_block (cp_parser* parser)
+{
+ tree compound_stmt;
+ tree try_block;
+ bool ctor_initializer_p;
+
+ /* Look for the `try' keyword. */
+ if (!cp_parser_require_keyword (parser, RID_TRY, RT_TRY))
+ return false;
+ /* Let the rest of the front end know where we are. */
+ try_block = begin_function_try_block (&compound_stmt);
+ /* Parse the function-body. */
+ ctor_initializer_p = cp_parser_ctor_initializer_opt_and_function_body
+ (parser, /*in_function_try_block=*/true);
+ /* We're done with the `try' part. */
+ finish_function_try_block (try_block);
+ /* Parse the handlers. */
+ cp_parser_handler_seq (parser);
+ /* We're done with the handlers. */
+ finish_function_handler_sequence (try_block, compound_stmt);
+
+ return ctor_initializer_p;
+}
+
+/* Parse a handler-seq.
+
+ handler-seq:
+ handler handler-seq [opt] */
+
+static void
+cp_parser_handler_seq (cp_parser* parser)
+{
+ while (true)
+ {
+ cp_token *token;
+
+ /* Parse the handler. */
+ cp_parser_handler (parser);
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not `catch' then there are no more handlers. */
+ if (!cp_parser_is_keyword (token, RID_CATCH))
+ break;
+ }
+}
+
+/* Parse a handler.
+
+ handler:
+ catch ( exception-declaration ) compound-statement */
+
+static void
+cp_parser_handler (cp_parser* parser)
+{
+ tree handler;
+ tree declaration;
+
+ cp_parser_require_keyword (parser, RID_CATCH, RT_CATCH);
+ handler = begin_handler ();
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ declaration = cp_parser_exception_declaration (parser);
+ finish_handler_parms (declaration, handler);
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ cp_parser_compound_statement (parser, NULL, false, false);
+ finish_handler (handler);
+}
+
+/* Parse an exception-declaration.
+
+ exception-declaration:
+ type-specifier-seq declarator
+ type-specifier-seq abstract-declarator
+ type-specifier-seq
+ ...
+
+ Returns a VAR_DECL for the declaration, or NULL_TREE if the
+ ellipsis variant is used. */
+
+static tree
+cp_parser_exception_declaration (cp_parser* parser)
+{
+ cp_decl_specifier_seq type_specifiers;
+ cp_declarator *declarator;
+ const char *saved_message;
+
+ /* If it's an ellipsis, it's easy to handle. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ /* Consume the `...' token. */
+ cp_lexer_consume_token (parser->lexer);
+ return NULL_TREE;
+ }
+
+ /* Types may not be defined in exception-declarations. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in exception-declarations");
+
+ /* Parse the type-specifier-seq. */
+ cp_parser_type_specifier_seq (parser, /*is_declaration=*/true,
+ /*is_trailing_return=*/false,
+ &type_specifiers);
+ /* If it's a `)', then there is no declarator. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
+ declarator = NULL;
+ else
+ declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
+
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+
+ if (!type_specifiers.any_specifiers_p)
+ return error_mark_node;
+
+ return grokdeclarator (declarator, &type_specifiers, CATCHPARM, 1, NULL);
+}
+
+/* Parse a throw-expression.
+
+ throw-expression:
+ throw assignment-expression [opt]
+
+ Returns a THROW_EXPR representing the throw-expression. */
+
+static tree
+cp_parser_throw_expression (cp_parser* parser)
+{
+ tree expression;
+ cp_token* token;
+
+ cp_parser_require_keyword (parser, RID_THROW, RT_THROW);
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Figure out whether or not there is an assignment-expression
+ following the "throw" keyword. */
+ if (token->type == CPP_COMMA
+ || token->type == CPP_SEMICOLON
+ || token->type == CPP_CLOSE_PAREN
+ || token->type == CPP_CLOSE_SQUARE
+ || token->type == CPP_CLOSE_BRACE
+ || token->type == CPP_COLON)
+ expression = NULL_TREE;
+ else
+ expression = cp_parser_assignment_expression (parser,
+ /*cast_p=*/false, NULL);
+
+ return build_throw (expression);
+}
+
+/* GNU Extensions */
+
+/* Parse an (optional) asm-specification.
+
+ asm-specification:
+ asm ( string-literal )
+
+ If the asm-specification is present, returns a STRING_CST
+ corresponding to the string-literal. Otherwise, returns
+ NULL_TREE. */
+
+static tree
+cp_parser_asm_specification_opt (cp_parser* parser)
+{
+ cp_token *token;
+ tree asm_specification;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If the next token isn't the `asm' keyword, then there's no
+ asm-specification. */
+ if (!cp_parser_is_keyword (token, RID_ASM))
+ return NULL_TREE;
+
+ /* Consume the `asm' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+ /* Look for the string-literal. */
+ asm_specification = cp_parser_string_literal (parser, false, false);
+
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ return asm_specification;
+}
+
+/* Parse an asm-operand-list.
+
+ asm-operand-list:
+ asm-operand
+ asm-operand-list , asm-operand
+
+ asm-operand:
+ string-literal ( expression )
+ [ string-literal ] string-literal ( expression )
+
+ Returns a TREE_LIST representing the operands. The TREE_VALUE of
+ each node is the expression. The TREE_PURPOSE is itself a
+ TREE_LIST whose TREE_PURPOSE is a STRING_CST for the bracketed
+ string-literal (or NULL_TREE if not present) and whose TREE_VALUE
+ is a STRING_CST for the string literal before the parenthesis. Returns
+ ERROR_MARK_NODE if any of the operands are invalid. */
+
+static tree
+cp_parser_asm_operand_list (cp_parser* parser)
+{
+ tree asm_operands = NULL_TREE;
+ bool invalid_operands = false;
+
+ while (true)
+ {
+ tree string_literal;
+ tree expression;
+ tree name;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+ {
+ /* Consume the `[' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Read the operand name. */
+ name = cp_parser_identifier (parser);
+ if (name != error_mark_node)
+ name = build_string (IDENTIFIER_LENGTH (name),
+ IDENTIFIER_POINTER (name));
+ /* Look for the closing `]'. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+ }
+ else
+ name = NULL_TREE;
+ /* Look for the string-literal. */
+ string_literal = cp_parser_string_literal (parser, false, false);
+
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ /* Parse the expression. */
+ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ if (name == error_mark_node
+ || string_literal == error_mark_node
+ || expression == error_mark_node)
+ invalid_operands = true;
+
+ /* Add this operand to the list. */
+ asm_operands = tree_cons (build_tree_list (name, string_literal),
+ expression,
+ asm_operands);
+ /* If the next token is not a `,', there are no more
+ operands. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Consume the `,'. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return invalid_operands ? error_mark_node : nreverse (asm_operands);
+}
+
+/* Parse an asm-clobber-list.
+
+ asm-clobber-list:
+ string-literal
+ asm-clobber-list , string-literal
+
+ Returns a TREE_LIST, indicating the clobbers in the order that they
+ appeared. The TREE_VALUE of each node is a STRING_CST. */
+
+static tree
+cp_parser_asm_clobber_list (cp_parser* parser)
+{
+ tree clobbers = NULL_TREE;
+
+ while (true)
+ {
+ tree string_literal;
+
+ /* Look for the string literal. */
+ string_literal = cp_parser_string_literal (parser, false, false);
+ /* Add it to the list. */
+ clobbers = tree_cons (NULL_TREE, string_literal, clobbers);
+ /* If the next token is not a `,', then the list is
+ complete. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Consume the `,' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return clobbers;
+}
+
+/* Parse an asm-label-list.
+
+ asm-label-list:
+ identifier
+ asm-label-list , identifier
+
+ Returns a TREE_LIST, indicating the labels in the order that they
+ appeared. The TREE_VALUE of each node is a label. */
+
+static tree
+cp_parser_asm_label_list (cp_parser* parser)
+{
+ tree labels = NULL_TREE;
+
+ while (true)
+ {
+ tree identifier, label, name;
+
+ /* Look for the identifier. */
+ identifier = cp_parser_identifier (parser);
+ if (!error_operand_p (identifier))
+ {
+ label = lookup_label (identifier);
+ if (TREE_CODE (label) == LABEL_DECL)
+ {
+ TREE_USED (label) = 1;
+ check_goto (label);
+ name = build_string (IDENTIFIER_LENGTH (identifier),
+ IDENTIFIER_POINTER (identifier));
+ labels = tree_cons (name, label, labels);
+ }
+ }
+ /* If the next token is not a `,', then the list is
+ complete. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Consume the `,' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return nreverse (labels);
+}
+
+/* Return TRUE iff the next tokens in the stream are possibly the
+ beginning of a GNU extension attribute. */
+
+static bool
+cp_next_tokens_can_be_gnu_attribute_p (cp_parser *parser)
+{
+ return cp_nth_tokens_can_be_gnu_attribute_p (parser, 1);
+}
+
+/* Return TRUE iff the next tokens in the stream are possibly the
+ beginning of a standard C++-11 attribute specifier. */
+
+static bool
+cp_next_tokens_can_be_std_attribute_p (cp_parser *parser)
+{
+ return cp_nth_tokens_can_be_std_attribute_p (parser, 1);
+}
+
+/* Return TRUE iff the next Nth tokens in the stream are possibly the
+ beginning of a standard C++-11 attribute specifier. */
+
+static bool
+cp_nth_tokens_can_be_std_attribute_p (cp_parser *parser, size_t n)
+{
+ cp_token *token = cp_lexer_peek_nth_token (parser->lexer, n);
+
+ return (cxx_dialect >= cxx11
+ && ((token->type == CPP_KEYWORD && token->keyword == RID_ALIGNAS)
+ || (token->type == CPP_OPEN_SQUARE
+ && (token = cp_lexer_peek_nth_token (parser->lexer, n + 1))
+ && token->type == CPP_OPEN_SQUARE)));
+}
+
+/* Return TRUE iff the next Nth tokens in the stream are possibly the
+ beginning of a GNU extension attribute. */
+
+static bool
+cp_nth_tokens_can_be_gnu_attribute_p (cp_parser *parser, size_t n)
+{
+ cp_token *token = cp_lexer_peek_nth_token (parser->lexer, n);
+
+ return token->type == CPP_KEYWORD && token->keyword == RID_ATTRIBUTE;
+}
+
+/* Return true iff the next tokens can be the beginning of either a
+ GNU attribute list, or a standard C++11 attribute sequence. */
+
+static bool
+cp_next_tokens_can_be_attribute_p (cp_parser *parser)
+{
+ return (cp_next_tokens_can_be_gnu_attribute_p (parser)
+ || cp_next_tokens_can_be_std_attribute_p (parser));
+}
+
+/* Return true iff the next Nth tokens can be the beginning of either
+ a GNU attribute list, or a standard C++11 attribute sequence. */
+
+static bool
+cp_nth_tokens_can_be_attribute_p (cp_parser *parser, size_t n)
+{
+ return (cp_nth_tokens_can_be_gnu_attribute_p (parser, n)
+ || cp_nth_tokens_can_be_std_attribute_p (parser, n));
+}
+
+/* Parse either a standard C++-11 attribute-specifier-seq, or a series
+ of GNU attributes, or return NULL. */
+
+static tree
+cp_parser_attributes_opt (cp_parser *parser)
+{
+ if (cp_next_tokens_can_be_gnu_attribute_p (parser))
+ return cp_parser_gnu_attributes_opt (parser);
+ return cp_parser_std_attribute_spec_seq (parser);
+}
+
+#define CILK_SIMD_FN_CLAUSE_MASK \
+ ((OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_VECTORLENGTH) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_LINEAR) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_UNIFORM) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_MASK) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_NOMASK))
+
+/* Parses the Cilk Plus SIMD-enabled function's attribute. Syntax:
+ vector [(<clauses>)] */
+
+static void
+cp_parser_cilk_simd_fn_vector_attrs (cp_parser *parser, cp_token *v_token)
+{
+ bool first_p = parser->cilk_simd_fn_info == NULL;
+ cp_token *token = v_token;
+ if (first_p)
+ {
+ parser->cilk_simd_fn_info = XNEW (cp_omp_declare_simd_data);
+ parser->cilk_simd_fn_info->error_seen = false;
+ parser->cilk_simd_fn_info->fndecl_seen = false;
+ parser->cilk_simd_fn_info->tokens = vNULL;
+ }
+ int paren_scope = 0;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ v_token = cp_lexer_peek_token (parser->lexer);
+ paren_scope++;
+ }
+ while (paren_scope > 0)
+ {
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_OPEN_PAREN)
+ paren_scope++;
+ else if (token->type == CPP_CLOSE_PAREN)
+ paren_scope--;
+ /* Do not push the last ')' */
+ if (!(token->type == CPP_CLOSE_PAREN && paren_scope == 0))
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ token->type = CPP_PRAGMA_EOL;
+ parser->lexer->next_token = token;
+ cp_lexer_consume_token (parser->lexer);
+
+ struct cp_token_cache *cp
+ = cp_token_cache_new (v_token, cp_lexer_peek_token (parser->lexer));
+ parser->cilk_simd_fn_info->tokens.safe_push (cp);
+}
+
+/* Parse an (optional) series of attributes.
+
+ attributes:
+ attributes attribute
+
+ attribute:
+ __attribute__ (( attribute-list [opt] ))
+
+ The return value is as for cp_parser_gnu_attribute_list. */
+
+static tree
+cp_parser_gnu_attributes_opt (cp_parser* parser)
+{
+ tree attributes = NULL_TREE;
+
+ while (true)
+ {
+ cp_token *token;
+ tree attribute_list;
+ bool ok = true;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not `__attribute__', then we're done. */
+ if (token->keyword != RID_ATTRIBUTE)
+ break;
+
+ /* Consume the `__attribute__' keyword. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the two `(' tokens. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type != CPP_CLOSE_PAREN)
+ /* Parse the attribute-list. */
+ attribute_list = cp_parser_gnu_attribute_list (parser);
+ else
+ /* If the next token is a `)', then there is no attribute
+ list. */
+ attribute_list = NULL;
+
+ /* Look for the two `)' tokens. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ ok = false;
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ ok = false;
+ if (!ok)
+ cp_parser_skip_to_end_of_statement (parser);
+
+ /* Add these new attributes to the list. */
+ attributes = chainon (attributes, attribute_list);
+ }
+
+ return attributes;
+}
+
+/* Returns true of NAME is an IDENTIFIER_NODE with identiifer "vector,"
+ "__vector" or "__vector__." */
+
+static inline bool
+is_cilkplus_vector_p (tree name)
+{
+ if (flag_cilkplus && is_attribute_p ("vector", name))
+ return true;
+ return false;
+}
+
+/* Parse a GNU attribute-list.
+
+ attribute-list:
+ attribute
+ attribute-list , attribute
+
+ attribute:
+ identifier
+ identifier ( identifier )
+ identifier ( identifier , expression-list )
+ identifier ( expression-list )
+
+ Returns a TREE_LIST, or NULL_TREE on error. Each node corresponds
+ to an attribute. The TREE_PURPOSE of each node is the identifier
+ indicating which attribute is in use. The TREE_VALUE represents
+ the arguments, if any. */
+
+static tree
+cp_parser_gnu_attribute_list (cp_parser* parser)
+{
+ tree attribute_list = NULL_TREE;
+ bool save_translate_strings_p = parser->translate_strings_p;
+
+ parser->translate_strings_p = false;
+ while (true)
+ {
+ cp_token *token;
+ tree identifier;
+ tree attribute;
+
+ /* Look for the identifier. We also allow keywords here; for
+ example `__attribute__ ((const))' is legal. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_NAME
+ || token->type == CPP_KEYWORD)
+ {
+ tree arguments = NULL_TREE;
+
+ /* Consume the token, but save it since we need it for the
+ SIMD enabled function parsing. */
+ cp_token *id_token = cp_lexer_consume_token (parser->lexer);
+
+ /* Save away the identifier that indicates which attribute
+ this is. */
+ identifier = (token->type == CPP_KEYWORD)
+ /* For keywords, use the canonical spelling, not the
+ parsed identifier. */
+ ? ridpointers[(int) token->keyword]
+ : id_token->u.value;
+
+ attribute = build_tree_list (identifier, NULL_TREE);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's an `(', then parse the attribute arguments. */
+ if (token->type == CPP_OPEN_PAREN)
+ {
+ vec<tree, va_gc> *vec;
+ int attr_flag = (attribute_takes_identifier_p (identifier)
+ ? id_attr : normal_attr);
+ if (is_cilkplus_vector_p (identifier))
+ {
+ cp_parser_cilk_simd_fn_vector_attrs (parser, id_token);
+ continue;
+ }
+ else
+ vec = cp_parser_parenthesized_expression_list
+ (parser, attr_flag, /*cast_p=*/false,
+ /*allow_expansion_p=*/false,
+ /*non_constant_p=*/NULL);
+ if (vec == NULL)
+ arguments = error_mark_node;
+ else
+ {
+ arguments = build_tree_list_vec (vec);
+ release_tree_vector (vec);
+ }
+ /* Save the arguments away. */
+ TREE_VALUE (attribute) = arguments;
+ }
+ else if (is_cilkplus_vector_p (identifier))
+ {
+ cp_parser_cilk_simd_fn_vector_attrs (parser, id_token);
+ continue;
+ }
+
+ if (arguments != error_mark_node)
+ {
+ /* Add this attribute to the list. */
+ TREE_CHAIN (attribute) = attribute_list;
+ attribute_list = attribute;
+ }
+
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+ /* Now, look for more attributes. If the next token isn't a
+ `,', we're done. */
+ if (token->type != CPP_COMMA)
+ break;
+
+ /* Consume the comma and keep going. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+ parser->translate_strings_p = save_translate_strings_p;
+
+ /* We built up the list in reverse order. */
+ return nreverse (attribute_list);
+}
+
+/* Parse a standard C++11 attribute.
+
+ The returned representation is a TREE_LIST which TREE_PURPOSE is
+ the scoped name of the attribute, and the TREE_VALUE is its
+ arguments list.
+
+ Note that the scoped name of the attribute is itself a TREE_LIST
+ which TREE_PURPOSE is the namespace of the attribute, and
+ TREE_VALUE its name. This is unlike a GNU attribute -- as parsed
+ by cp_parser_gnu_attribute_list -- that doesn't have any namespace
+ and which TREE_PURPOSE is directly the attribute name.
+
+ Clients of the attribute code should use get_attribute_namespace
+ and get_attribute_name to get the actual namespace and name of
+ attributes, regardless of their being GNU or C++11 attributes.
+
+ attribute:
+ attribute-token attribute-argument-clause [opt]
+
+ attribute-token:
+ identifier
+ attribute-scoped-token
+
+ attribute-scoped-token:
+ attribute-namespace :: identifier
+
+ attribute-namespace:
+ identifier
+
+ attribute-argument-clause:
+ ( balanced-token-seq )
+
+ balanced-token-seq:
+ balanced-token [opt]
+ balanced-token-seq balanced-token
+
+ balanced-token:
+ ( balanced-token-seq )
+ [ balanced-token-seq ]
+ { balanced-token-seq }. */
+
+static tree
+cp_parser_std_attribute (cp_parser *parser)
+{
+ tree attribute, attr_ns = NULL_TREE, attr_id = NULL_TREE, arguments;
+ cp_token *token;
+
+ /* First, parse name of the the attribute, a.k.a
+ attribute-token. */
+
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_NAME)
+ attr_id = token->u.value;
+ else if (token->type == CPP_KEYWORD)
+ attr_id = ridpointers[(int) token->keyword];
+ else if (token->flags & NAMED_OP)
+ attr_id = get_identifier (cpp_type2name (token->type, token->flags));
+
+ if (attr_id == NULL_TREE)
+ return NULL_TREE;
+
+ cp_lexer_consume_token (parser->lexer);
+
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_SCOPE)
+ {
+ /* We are seeing a scoped attribute token. */
+
+ cp_lexer_consume_token (parser->lexer);
+ attr_ns = attr_id;
+
+ token = cp_lexer_consume_token (parser->lexer);
+ if (token->type == CPP_NAME)
+ attr_id = token->u.value;
+ else if (token->type == CPP_KEYWORD)
+ attr_id = ridpointers[(int) token->keyword];
+ else
+ {
+ error_at (token->location,
+ "expected an identifier for the attribute name");
+ return error_mark_node;
+ }
+ attribute = build_tree_list (build_tree_list (attr_ns, attr_id),
+ NULL_TREE);
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+ else
+ {
+ attribute = build_tree_list (build_tree_list (NULL_TREE, attr_id),
+ NULL_TREE);
+ /* C++11 noreturn attribute is equivalent to GNU's. */
+ if (is_attribute_p ("noreturn", attr_id))
+ TREE_PURPOSE (TREE_PURPOSE (attribute)) = get_identifier ("gnu");
+ /* C++14 deprecated attribute is equivalent to GNU's. */
+ else if (cxx_dialect >= cxx1y && is_attribute_p ("deprecated", attr_id))
+ TREE_PURPOSE (TREE_PURPOSE (attribute)) = get_identifier ("gnu");
+ }
+
+ /* Now parse the optional argument clause of the attribute. */
+
+ if (token->type != CPP_OPEN_PAREN)
+ return attribute;
+
+ {
+ vec<tree, va_gc> *vec;
+ int attr_flag = normal_attr;
+
+ if (attr_ns == get_identifier ("gnu")
+ && attribute_takes_identifier_p (attr_id))
+ /* A GNU attribute that takes an identifier in parameter. */
+ attr_flag = id_attr;
+
+ vec = cp_parser_parenthesized_expression_list
+ (parser, attr_flag, /*cast_p=*/false,
+ /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL);
+ if (vec == NULL)
+ arguments = error_mark_node;
+ else
+ {
+ arguments = build_tree_list_vec (vec);
+ release_tree_vector (vec);
+ }
+
+ if (arguments == error_mark_node)
+ attribute = error_mark_node;
+ else
+ TREE_VALUE (attribute) = arguments;
+ }
+
+ return attribute;
+}
+
+/* Parse a list of standard C++-11 attributes.
+
+ attribute-list:
+ attribute [opt]
+ attribute-list , attribute[opt]
+ attribute ...
+ attribute-list , attribute ...
+*/
+
+static tree
+cp_parser_std_attribute_list (cp_parser *parser)
+{
+ tree attributes = NULL_TREE, attribute = NULL_TREE;
+ cp_token *token = NULL;
+
+ while (true)
+ {
+ attribute = cp_parser_std_attribute (parser);
+ if (attribute == error_mark_node)
+ break;
+ if (attribute != NULL_TREE)
+ {
+ TREE_CHAIN (attribute) = attributes;
+ attributes = attribute;
+ }
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type != CPP_COMMA)
+ break;
+ cp_lexer_consume_token (parser->lexer);
+ }
+ attributes = nreverse (attributes);
+ return attributes;
+}
+
+/* Parse a standard C++-11 attribute specifier.
+
+ attribute-specifier:
+ [ [ attribute-list ] ]
+ alignment-specifier
+
+ alignment-specifier:
+ alignas ( type-id ... [opt] )
+ alignas ( alignment-expression ... [opt] ). */
+
+static tree
+cp_parser_std_attribute_spec (cp_parser *parser)
+{
+ tree attributes = NULL_TREE;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ if (token->type == CPP_OPEN_SQUARE
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_SQUARE)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_lexer_consume_token (parser->lexer);
+
+ attributes = cp_parser_std_attribute_list (parser);
+
+ if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE)
+ || !cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
+ cp_parser_skip_to_end_of_statement (parser);
+ else
+ /* Warn about parsing c++11 attribute in non-c++1 mode, only
+ when we are sure that we have actually parsed them. */
+ maybe_warn_cpp0x (CPP0X_ATTRIBUTES);
+ }
+ else
+ {
+ tree alignas_expr;
+
+ /* Look for an alignment-specifier. */
+
+ token = cp_lexer_peek_token (parser->lexer);
+
+ if (token->type != CPP_KEYWORD
+ || token->keyword != RID_ALIGNAS)
+ return NULL_TREE;
+
+ cp_lexer_consume_token (parser->lexer);
+ maybe_warn_cpp0x (CPP0X_ATTRIBUTES);
+
+ if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN) == NULL)
+ {
+ cp_parser_error (parser, "expected %<(%>");
+ return error_mark_node;
+ }
+
+ cp_parser_parse_tentatively (parser);
+ alignas_expr = cp_parser_type_id (parser);
+
+ if (!cp_parser_parse_definitely (parser))
+ {
+ gcc_assert (alignas_expr == error_mark_node
+ || alignas_expr == NULL_TREE);
+
+ alignas_expr =
+ cp_parser_assignment_expression (parser, /*cast_p=*/false,
+ /**cp_id_kind=*/NULL);
+ if (alignas_expr == error_mark_node)
+ cp_parser_skip_to_end_of_statement (parser);
+ if (alignas_expr == NULL_TREE
+ || alignas_expr == error_mark_node)
+ return alignas_expr;
+ }
+
+ if (cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN) == NULL)
+ {
+ cp_parser_error (parser, "expected %<)%>");
+ return error_mark_node;
+ }
+
+ alignas_expr = cxx_alignas_expr (alignas_expr);
+
+ /* Build the C++-11 representation of an 'aligned'
+ attribute. */
+ attributes =
+ build_tree_list (build_tree_list (get_identifier ("gnu"),
+ get_identifier ("aligned")),
+ build_tree_list (NULL_TREE, alignas_expr));
+ }
+
+ return attributes;
+}
+
+/* Parse a standard C++-11 attribute-specifier-seq.
+
+ attribute-specifier-seq:
+ attribute-specifier-seq [opt] attribute-specifier
+ */
+
+static tree
+cp_parser_std_attribute_spec_seq (cp_parser *parser)
+{
+ tree attr_specs = NULL;
+
+ while (true)
+ {
+ tree attr_spec = cp_parser_std_attribute_spec (parser);
+ if (attr_spec == NULL_TREE)
+ break;
+ if (attr_spec == error_mark_node)
+ return error_mark_node;
+
+ TREE_CHAIN (attr_spec) = attr_specs;
+ attr_specs = attr_spec;
+ }
+
+ attr_specs = nreverse (attr_specs);
+ return attr_specs;
+}
+
+/* Parse an optional `__extension__' keyword. Returns TRUE if it is
+ present, and FALSE otherwise. *SAVED_PEDANTIC is set to the
+ current value of the PEDANTIC flag, regardless of whether or not
+ the `__extension__' keyword is present. The caller is responsible
+ for restoring the value of the PEDANTIC flag. */
+
+static bool
+cp_parser_extension_opt (cp_parser* parser, int* saved_pedantic)
+{
+ /* Save the old value of the PEDANTIC flag. */
+ *saved_pedantic = pedantic;
+
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXTENSION))
+ {
+ /* Consume the `__extension__' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* We're not being pedantic while the `__extension__' keyword is
+ in effect. */
+ pedantic = 0;
+
+ return true;
+ }
+
+ return false;
+}
+
+/* Parse a label declaration.
+
+ label-declaration:
+ __label__ label-declarator-seq ;
+
+ label-declarator-seq:
+ identifier , label-declarator-seq
+ identifier */
+
+static void
+cp_parser_label_declaration (cp_parser* parser)
+{
+ /* Look for the `__label__' keyword. */
+ cp_parser_require_keyword (parser, RID_LABEL, RT_LABEL);
+
+ while (true)
+ {
+ tree identifier;
+
+ /* Look for an identifier. */
+ identifier = cp_parser_identifier (parser);
+ /* If we failed, stop. */
+ if (identifier == error_mark_node)
+ break;
+ /* Declare it as a label. */
+ finish_label_decl (identifier);
+ /* If the next token is a `;', stop. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ break;
+ /* Look for the `,' separating the label declarations. */
+ cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+ }
+
+ /* Look for the final `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+}
+
+/* Support Functions */
+
+/* Looks up NAME in the current scope, as given by PARSER->SCOPE.
+ NAME should have one of the representations used for an
+ id-expression. If NAME is the ERROR_MARK_NODE, the ERROR_MARK_NODE
+ is returned. If PARSER->SCOPE is a dependent type, then a
+ SCOPE_REF is returned.
+
+ If NAME is a TEMPLATE_ID_EXPR, then it will be immediately
+ returned; the name was already resolved when the TEMPLATE_ID_EXPR
+ was formed. Abstractly, such entities should not be passed to this
+ function, because they do not need to be looked up, but it is
+ simpler to check for this special case here, rather than at the
+ call-sites.
+
+ In cases not explicitly covered above, this function returns a
+ DECL, OVERLOAD, or baselink representing the result of the lookup.
+ If there was no entity with the indicated NAME, the ERROR_MARK_NODE
+ is returned.
+
+ If TAG_TYPE is not NONE_TYPE, it indicates an explicit type keyword
+ (e.g., "struct") that was used. In that case bindings that do not
+ refer to types are ignored.
+
+ If IS_TEMPLATE is TRUE, bindings that do not refer to templates are
+ ignored.
+
+ If IS_NAMESPACE is TRUE, bindings that do not refer to namespaces
+ are ignored.
+
+ If CHECK_DEPENDENCY is TRUE, names are not looked up in dependent
+ types.
+
+ If AMBIGUOUS_DECLS is non-NULL, *AMBIGUOUS_DECLS is set to a
+ TREE_LIST of candidates if name-lookup results in an ambiguity, and
+ NULL_TREE otherwise. */
+
+static tree
+cp_parser_lookup_name (cp_parser *parser, tree name,
+ enum tag_types tag_type,
+ bool is_template,
+ bool is_namespace,
+ bool check_dependency,
+ tree *ambiguous_decls,
+ location_t name_location)
+{
+ tree decl;
+ tree object_type = parser->context->object_type;
+
+ /* Assume that the lookup will be unambiguous. */
+ if (ambiguous_decls)
+ *ambiguous_decls = NULL_TREE;
+
+ /* Now that we have looked up the name, the OBJECT_TYPE (if any) is
+ no longer valid. Note that if we are parsing tentatively, and
+ the parse fails, OBJECT_TYPE will be automatically restored. */
+ parser->context->object_type = NULL_TREE;
+
+ if (name == error_mark_node)
+ return error_mark_node;
+
+ /* A template-id has already been resolved; there is no lookup to
+ do. */
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ return name;
+ if (BASELINK_P (name))
+ {
+ gcc_assert (TREE_CODE (BASELINK_FUNCTIONS (name))
+ == TEMPLATE_ID_EXPR);
+ return name;
+ }
+
+ /* A BIT_NOT_EXPR is used to represent a destructor. By this point,
+ it should already have been checked to make sure that the name
+ used matches the type being destroyed. */
+ if (TREE_CODE (name) == BIT_NOT_EXPR)
+ {
+ tree type;
+
+ /* Figure out to which type this destructor applies. */
+ if (parser->scope)
+ type = parser->scope;
+ else if (object_type)
+ type = object_type;
+ else
+ type = current_class_type;
+ /* If that's not a class type, there is no destructor. */
+ if (!type || !CLASS_TYPE_P (type))
+ return error_mark_node;
+ if (CLASSTYPE_LAZY_DESTRUCTOR (type))
+ lazily_declare_fn (sfk_destructor, type);
+ if (!CLASSTYPE_DESTRUCTORS (type))
+ return error_mark_node;
+ /* If it was a class type, return the destructor. */
+ return CLASSTYPE_DESTRUCTORS (type);
+ }
+
+ /* By this point, the NAME should be an ordinary identifier. If
+ the id-expression was a qualified name, the qualifying scope is
+ stored in PARSER->SCOPE at this point. */
+ gcc_assert (identifier_p (name));
+
+ /* Perform the lookup. */
+ if (parser->scope)
+ {
+ bool dependent_p;
+
+ if (parser->scope == error_mark_node)
+ return error_mark_node;
+
+ /* If the SCOPE is dependent, the lookup must be deferred until
+ the template is instantiated -- unless we are explicitly
+ looking up names in uninstantiated templates. Even then, we
+ cannot look up the name if the scope is not a class type; it
+ might, for example, be a template type parameter. */
+ dependent_p = (TYPE_P (parser->scope)
+ && dependent_scope_p (parser->scope));
+ if ((check_dependency || !CLASS_TYPE_P (parser->scope))
+ && dependent_p)
+ /* Defer lookup. */
+ decl = error_mark_node;
+ else
+ {
+ tree pushed_scope = NULL_TREE;
+
+ /* If PARSER->SCOPE is a dependent type, then it must be a
+ class type, and we must not be checking dependencies;
+ otherwise, we would have processed this lookup above. So
+ that PARSER->SCOPE is not considered a dependent base by
+ lookup_member, we must enter the scope here. */
+ if (dependent_p)
+ pushed_scope = push_scope (parser->scope);
+
+ /* If the PARSER->SCOPE is a template specialization, it
+ may be instantiated during name lookup. In that case,
+ errors may be issued. Even if we rollback the current
+ tentative parse, those errors are valid. */
+ decl = lookup_qualified_name (parser->scope, name,
+ tag_type != none_type,
+ /*complain=*/true);
+
+ /* 3.4.3.1: In a lookup in which the constructor is an acceptable
+ lookup result and the nested-name-specifier nominates a class C:
+ * if the name specified after the nested-name-specifier, when
+ looked up in C, is the injected-class-name of C (Clause 9), or
+ * if the name specified after the nested-name-specifier is the
+ same as the identifier or the simple-template-id's template-
+ name in the last component of the nested-name-specifier,
+ the name is instead considered to name the constructor of
+ class C. [ Note: for example, the constructor is not an
+ acceptable lookup result in an elaborated-type-specifier so
+ the constructor would not be used in place of the
+ injected-class-name. --end note ] Such a constructor name
+ shall be used only in the declarator-id of a declaration that
+ names a constructor or in a using-declaration. */
+ if (tag_type == none_type
+ && DECL_SELF_REFERENCE_P (decl)
+ && same_type_p (DECL_CONTEXT (decl), parser->scope))
+ decl = lookup_qualified_name (parser->scope, ctor_identifier,
+ tag_type != none_type,
+ /*complain=*/true);
+
+ /* If we have a single function from a using decl, pull it out. */
+ if (TREE_CODE (decl) == OVERLOAD
+ && !really_overloaded_fn (decl))
+ decl = OVL_FUNCTION (decl);
+
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ }
+
+ /* If the scope is a dependent type and either we deferred lookup or
+ we did lookup but didn't find the name, rememeber the name. */
+ if (decl == error_mark_node && TYPE_P (parser->scope)
+ && dependent_type_p (parser->scope))
+ {
+ if (tag_type)
+ {
+ tree type;
+
+ /* The resolution to Core Issue 180 says that `struct
+ A::B' should be considered a type-name, even if `A'
+ is dependent. */
+ type = make_typename_type (parser->scope, name, tag_type,
+ /*complain=*/tf_error);
+ if (type != error_mark_node)
+ decl = TYPE_NAME (type);
+ }
+ else if (is_template
+ && (cp_parser_next_token_ends_template_argument_p (parser)
+ || cp_lexer_next_token_is (parser->lexer,
+ CPP_CLOSE_PAREN)))
+ decl = make_unbound_class_template (parser->scope,
+ name, NULL_TREE,
+ /*complain=*/tf_error);
+ else
+ decl = build_qualified_name (/*type=*/NULL_TREE,
+ parser->scope, name,
+ is_template);
+ }
+ parser->qualifying_scope = parser->scope;
+ parser->object_scope = NULL_TREE;
+ }
+ else if (object_type)
+ {
+ /* Look up the name in the scope of the OBJECT_TYPE, unless the
+ OBJECT_TYPE is not a class. */
+ if (CLASS_TYPE_P (object_type))
+ /* If the OBJECT_TYPE is a template specialization, it may
+ be instantiated during name lookup. In that case, errors
+ may be issued. Even if we rollback the current tentative
+ parse, those errors are valid. */
+ decl = lookup_member (object_type,
+ name,
+ /*protect=*/0,
+ tag_type != none_type,
+ tf_warning_or_error);
+ else
+ decl = NULL_TREE;
+
+ if (!decl)
+ /* Look it up in the enclosing context. */
+ decl = lookup_name_real (name, tag_type != none_type,
+ /*nonclass=*/0,
+ /*block_p=*/true, is_namespace, 0);
+ parser->object_scope = object_type;
+ parser->qualifying_scope = NULL_TREE;
+ }
+ else
+ {
+ decl = lookup_name_real (name, tag_type != none_type,
+ /*nonclass=*/0,
+ /*block_p=*/true, is_namespace, 0);
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ }
+
+ /* If the lookup failed, let our caller know. */
+ if (!decl || decl == error_mark_node)
+ return error_mark_node;
+
+ /* Pull out the template from an injected-class-name (or multiple). */
+ if (is_template)
+ decl = maybe_get_template_decl_from_type_decl (decl);
+
+ /* If it's a TREE_LIST, the result of the lookup was ambiguous. */
+ if (TREE_CODE (decl) == TREE_LIST)
+ {
+ if (ambiguous_decls)
+ *ambiguous_decls = decl;
+ /* The error message we have to print is too complicated for
+ cp_parser_error, so we incorporate its actions directly. */
+ if (!cp_parser_simulate_error (parser))
+ {
+ error_at (name_location, "reference to %qD is ambiguous",
+ name);
+ print_candidates (decl);
+ }
+ return error_mark_node;
+ }
+
+ gcc_assert (DECL_P (decl)
+ || TREE_CODE (decl) == OVERLOAD
+ || TREE_CODE (decl) == SCOPE_REF
+ || TREE_CODE (decl) == UNBOUND_CLASS_TEMPLATE
+ || BASELINK_P (decl));
+
+ /* If we have resolved the name of a member declaration, check to
+ see if the declaration is accessible. When the name resolves to
+ set of overloaded functions, accessibility is checked when
+ overload resolution is done.
+
+ During an explicit instantiation, access is not checked at all,
+ as per [temp.explicit]. */
+ if (DECL_P (decl))
+ check_accessibility_of_qualified_id (decl, object_type, parser->scope);
+
+ maybe_record_typedef_use (decl);
+
+ return decl;
+}
+
+/* Like cp_parser_lookup_name, but for use in the typical case where
+ CHECK_ACCESS is TRUE, IS_TYPE is FALSE, IS_TEMPLATE is FALSE,
+ IS_NAMESPACE is FALSE, and CHECK_DEPENDENCY is TRUE. */
+
+static tree
+cp_parser_lookup_name_simple (cp_parser* parser, tree name, location_t location)
+{
+ return cp_parser_lookup_name (parser, name,
+ none_type,
+ /*is_template=*/false,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true,
+ /*ambiguous_decls=*/NULL,
+ location);
+}
+
+/* If DECL is a TEMPLATE_DECL that can be treated like a TYPE_DECL in
+ the current context, return the TYPE_DECL. If TAG_NAME_P is
+ true, the DECL indicates the class being defined in a class-head,
+ or declared in an elaborated-type-specifier.
+
+ Otherwise, return DECL. */
+
+static tree
+cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p)
+{
+ /* If the TEMPLATE_DECL is being declared as part of a class-head,
+ the translation from TEMPLATE_DECL to TYPE_DECL occurs:
+
+ struct A {
+ template <typename T> struct B;
+ };
+
+ template <typename T> struct A::B {};
+
+ Similarly, in an elaborated-type-specifier:
+
+ namespace N { struct X{}; }
+
+ struct A {
+ template <typename T> friend struct N::X;
+ };
+
+ However, if the DECL refers to a class type, and we are in
+ the scope of the class, then the name lookup automatically
+ finds the TYPE_DECL created by build_self_reference rather
+ than a TEMPLATE_DECL. For example, in:
+
+ template <class T> struct S {
+ S s;
+ };
+
+ there is no need to handle such case. */
+
+ if (DECL_CLASS_TEMPLATE_P (decl) && tag_name_p)
+ return DECL_TEMPLATE_RESULT (decl);
+
+ return decl;
+}
+
+/* If too many, or too few, template-parameter lists apply to the
+ declarator, issue an error message. Returns TRUE if all went well,
+ and FALSE otherwise. */
+
+static bool
+cp_parser_check_declarator_template_parameters (cp_parser* parser,
+ cp_declarator *declarator,
+ location_t declarator_location)
+{
+ switch (declarator->kind)
+ {
+ case cdk_id:
+ {
+ unsigned num_templates = 0;
+ tree scope = declarator->u.id.qualifying_scope;
+
+ if (scope)
+ num_templates = num_template_headers_for_class (scope);
+ else if (TREE_CODE (declarator->u.id.unqualified_name)
+ == TEMPLATE_ID_EXPR)
+ /* If the DECLARATOR has the form `X<y>' then it uses one
+ additional level of template parameters. */
+ ++num_templates;
+
+ return cp_parser_check_template_parameters
+ (parser, num_templates, declarator_location, declarator);
+ }
+
+ case cdk_function:
+ case cdk_array:
+ case cdk_pointer:
+ case cdk_reference:
+ case cdk_ptrmem:
+ return (cp_parser_check_declarator_template_parameters
+ (parser, declarator->declarator, declarator_location));
+
+ case cdk_error:
+ return true;
+
+ default:
+ gcc_unreachable ();
+ }
+ return false;
+}
+
+/* NUM_TEMPLATES were used in the current declaration. If that is
+ invalid, return FALSE and issue an error messages. Otherwise,
+ return TRUE. If DECLARATOR is non-NULL, then we are checking a
+ declarator and we can print more accurate diagnostics. */
+
+static bool
+cp_parser_check_template_parameters (cp_parser* parser,
+ unsigned num_templates,
+ location_t location,
+ cp_declarator *declarator)
+{
+ /* If there are the same number of template classes and parameter
+ lists, that's OK. */
+ if (parser->num_template_parameter_lists == num_templates)
+ return true;
+ /* If there are more, but only one more, then we are referring to a
+ member template. That's OK too. */
+ if (parser->num_template_parameter_lists == num_templates + 1)
+ return true;
+ /* If there are more template classes than parameter lists, we have
+ something like:
+
+ template <class T> void S<T>::R<T>::f (); */
+ if (parser->num_template_parameter_lists < num_templates)
+ {
+ if (declarator && !current_function_decl)
+ error_at (location, "specializing member %<%T::%E%> "
+ "requires %<template<>%> syntax",
+ declarator->u.id.qualifying_scope,
+ declarator->u.id.unqualified_name);
+ else if (declarator)
+ error_at (location, "invalid declaration of %<%T::%E%>",
+ declarator->u.id.qualifying_scope,
+ declarator->u.id.unqualified_name);
+ else
+ error_at (location, "too few template-parameter-lists");
+ return false;
+ }
+ /* Otherwise, there are too many template parameter lists. We have
+ something like:
+
+ template <class T> template <class U> void S::f(); */
+ error_at (location, "too many template-parameter-lists");
+ return false;
+}
+
+/* Parse an optional `::' token indicating that the following name is
+ from the global namespace. If so, PARSER->SCOPE is set to the
+ GLOBAL_NAMESPACE. Otherwise, PARSER->SCOPE is set to NULL_TREE,
+ unless CURRENT_SCOPE_VALID_P is TRUE, in which case it is left alone.
+ Returns the new value of PARSER->SCOPE, if the `::' token is
+ present, and NULL_TREE otherwise. */
+
+static tree
+cp_parser_global_scope_opt (cp_parser* parser, bool current_scope_valid_p)
+{
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If we're looking at a `::' token then we're starting from the
+ global namespace, not our current location. */
+ if (token->type == CPP_SCOPE)
+ {
+ /* Consume the `::' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Set the SCOPE so that we know where to start the lookup. */
+ parser->scope = global_namespace;
+ parser->qualifying_scope = global_namespace;
+ parser->object_scope = NULL_TREE;
+
+ return parser->scope;
+ }
+ else if (!current_scope_valid_p)
+ {
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ }
+
+ return NULL_TREE;
+}
+
+/* Returns TRUE if the upcoming token sequence is the start of a
+ constructor declarator. If FRIEND_P is true, the declarator is
+ preceded by the `friend' specifier. */
+
+static bool
+cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
+{
+ bool constructor_p;
+ bool outside_class_specifier_p;
+ tree nested_name_specifier;
+ cp_token *next_token;
+
+ /* The common case is that this is not a constructor declarator, so
+ try to avoid doing lots of work if at all possible. It's not
+ valid declare a constructor at function scope. */
+ if (parser->in_function_body)
+ return false;
+ /* And only certain tokens can begin a constructor declarator. */
+ next_token = cp_lexer_peek_token (parser->lexer);
+ if (next_token->type != CPP_NAME
+ && next_token->type != CPP_SCOPE
+ && next_token->type != CPP_NESTED_NAME_SPECIFIER
+ && next_token->type != CPP_TEMPLATE_ID)
+ return false;
+
+ /* Parse tentatively; we are going to roll back all of the tokens
+ consumed here. */
+ cp_parser_parse_tentatively (parser);
+ /* Assume that we are looking at a constructor declarator. */
+ constructor_p = true;
+
+ /* Look for the optional `::' operator. */
+ cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false);
+ /* Look for the nested-name-specifier. */
+ nested_name_specifier
+ = (cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/false,
+ /*type_p=*/false,
+ /*is_declaration=*/false));
+
+ outside_class_specifier_p = (!at_class_scope_p ()
+ || !TYPE_BEING_DEFINED (current_class_type)
+ || friend_p);
+
+ /* Outside of a class-specifier, there must be a
+ nested-name-specifier. */
+ if (!nested_name_specifier && outside_class_specifier_p)
+ constructor_p = false;
+ else if (nested_name_specifier == error_mark_node)
+ constructor_p = false;
+
+ /* If we have a class scope, this is easy; DR 147 says that S::S always
+ names the constructor, and no other qualified name could. */
+ if (constructor_p && nested_name_specifier
+ && CLASS_TYPE_P (nested_name_specifier))
+ {
+ tree id = cp_parser_unqualified_id (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/false,
+ /*declarator_p=*/true,
+ /*optional_p=*/false);
+ if (is_overloaded_fn (id))
+ id = DECL_NAME (get_first_fn (id));
+ if (!constructor_name_p (id, nested_name_specifier))
+ constructor_p = false;
+ }
+ /* If we still think that this might be a constructor-declarator,
+ look for a class-name. */
+ else if (constructor_p)
+ {
+ /* If we have:
+
+ template <typename T> struct S {
+ S();
+ };
+
+ we must recognize that the nested `S' names a class. */
+ tree type_decl;
+ type_decl = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ none_type,
+ /*check_dependency_p=*/false,
+ /*class_head_p=*/false,
+ /*is_declaration=*/false);
+ /* If there was no class-name, then this is not a constructor.
+ Otherwise, if we are in a class-specifier and we aren't
+ handling a friend declaration, check that its type matches
+ current_class_type (c++/38313). Note: error_mark_node
+ is left alone for error recovery purposes. */
+ constructor_p = (!cp_parser_error_occurred (parser)
+ && (outside_class_specifier_p
+ || type_decl == error_mark_node
+ || same_type_p (current_class_type,
+ TREE_TYPE (type_decl))));
+
+ /* If we're still considering a constructor, we have to see a `(',
+ to begin the parameter-declaration-clause, followed by either a
+ `)', an `...', or a decl-specifier. We need to check for a
+ type-specifier to avoid being fooled into thinking that:
+
+ S (f) (int);
+
+ is a constructor. (It is actually a function named `f' that
+ takes one parameter (of type `int') and returns a value of type
+ `S'. */
+ if (constructor_p
+ && !cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ constructor_p = false;
+
+ if (constructor_p
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS)
+ /* A parameter declaration begins with a decl-specifier,
+ which is either the "attribute" keyword, a storage class
+ specifier, or (usually) a type-specifier. */
+ && !cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer))
+ {
+ tree type;
+ tree pushed_scope = NULL_TREE;
+ unsigned saved_num_template_parameter_lists;
+
+ /* Names appearing in the type-specifier should be looked up
+ in the scope of the class. */
+ if (current_class_type)
+ type = NULL_TREE;
+ else
+ {
+ type = TREE_TYPE (type_decl);
+ if (TREE_CODE (type) == TYPENAME_TYPE)
+ {
+ type = resolve_typename_type (type,
+ /*only_current_p=*/false);
+ if (TREE_CODE (type) == TYPENAME_TYPE)
+ {
+ cp_parser_abort_tentative_parse (parser);
+ return false;
+ }
+ }
+ pushed_scope = push_scope (type);
+ }
+
+ /* Inside the constructor parameter list, surrounding
+ template-parameter-lists do not apply. */
+ saved_num_template_parameter_lists
+ = parser->num_template_parameter_lists;
+ parser->num_template_parameter_lists = 0;
+
+ /* Look for the type-specifier. */
+ cp_parser_type_specifier (parser,
+ CP_PARSER_FLAGS_NONE,
+ /*decl_specs=*/NULL,
+ /*is_declarator=*/true,
+ /*declares_class_or_enum=*/NULL,
+ /*is_cv_qualifier=*/NULL);
+
+ parser->num_template_parameter_lists
+ = saved_num_template_parameter_lists;
+
+ /* Leave the scope of the class. */
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+
+ constructor_p = !cp_parser_error_occurred (parser);
+ }
+ }
+
+ /* We did not really want to consume any tokens. */
+ cp_parser_abort_tentative_parse (parser);
+
+ return constructor_p;
+}
+
+/* Parse the definition of the function given by the DECL_SPECIFIERS,
+ ATTRIBUTES, and DECLARATOR. The access checks have been deferred;
+ they must be performed once we are in the scope of the function.
+
+ Returns the function defined. */
+
+static tree
+cp_parser_function_definition_from_specifiers_and_declarator
+ (cp_parser* parser,
+ cp_decl_specifier_seq *decl_specifiers,
+ tree attributes,
+ const cp_declarator *declarator)
+{
+ tree fn;
+ bool success_p;
+
+ /* Begin the function-definition. */
+ success_p = start_function (decl_specifiers, declarator, attributes);
+
+ /* The things we're about to see are not directly qualified by any
+ template headers we've seen thus far. */
+ reset_specialization ();
+
+ /* If there were names looked up in the decl-specifier-seq that we
+ did not check, check them now. We must wait until we are in the
+ scope of the function to perform the checks, since the function
+ might be a friend. */
+ perform_deferred_access_checks (tf_warning_or_error);
+
+ if (success_p)
+ {
+ cp_finalize_omp_declare_simd (parser, current_function_decl);
+ parser->omp_declare_simd = NULL;
+ }
+
+ if (!success_p)
+ {
+ /* Skip the entire function. */
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ fn = error_mark_node;
+ }
+ else if (DECL_INITIAL (current_function_decl) != error_mark_node)
+ {
+ /* Seen already, skip it. An error message has already been output. */
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ fn = current_function_decl;
+ current_function_decl = NULL_TREE;
+ /* If this is a function from a class, pop the nested class. */
+ if (current_class_name)
+ pop_nested_class ();
+ }
+ else
+ {
+ timevar_id_t tv;
+ if (DECL_DECLARED_INLINE_P (current_function_decl))
+ tv = TV_PARSE_INLINE;
+ else
+ tv = TV_PARSE_FUNC;
+ timevar_push (tv);
+ fn = cp_parser_function_definition_after_declarator (parser,
+ /*inline_p=*/false);
+ timevar_pop (tv);
+ }
+
+ return fn;
+}
+
+/* Parse the part of a function-definition that follows the
+ declarator. INLINE_P is TRUE iff this function is an inline
+ function defined within a class-specifier.
+
+ Returns the function defined. */
+
+static tree
+cp_parser_function_definition_after_declarator (cp_parser* parser,
+ bool inline_p)
+{
+ tree fn;
+ bool ctor_initializer_p = false;
+ bool saved_in_unbraced_linkage_specification_p;
+ bool saved_in_function_body;
+ unsigned saved_num_template_parameter_lists;
+ cp_token *token;
+ bool fully_implicit_function_template_p
+ = parser->fully_implicit_function_template_p;
+ parser->fully_implicit_function_template_p = false;
+ tree implicit_template_parms
+ = parser->implicit_template_parms;
+ parser->implicit_template_parms = 0;
+ cp_binding_level* implicit_template_scope
+ = parser->implicit_template_scope;
+ parser->implicit_template_scope = 0;
+
+ saved_in_function_body = parser->in_function_body;
+ parser->in_function_body = true;
+ /* If the next token is `return', then the code may be trying to
+ make use of the "named return value" extension that G++ used to
+ support. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_RETURN))
+ {
+ /* Consume the `return' keyword. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the identifier that indicates what value is to be
+ returned. */
+ cp_parser_identifier (parser);
+ /* Issue an error message. */
+ error_at (token->location,
+ "named return values are no longer supported");
+ /* Skip tokens until we reach the start of the function body. */
+ while (true)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_OPEN_BRACE
+ || token->type == CPP_EOF
+ || token->type == CPP_PRAGMA_EOL)
+ break;
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+ /* The `extern' in `extern "C" void f () { ... }' does not apply to
+ anything declared inside `f'. */
+ saved_in_unbraced_linkage_specification_p
+ = parser->in_unbraced_linkage_specification_p;
+ parser->in_unbraced_linkage_specification_p = false;
+ /* Inside the function, surrounding template-parameter-lists do not
+ apply. */
+ saved_num_template_parameter_lists
+ = parser->num_template_parameter_lists;
+ parser->num_template_parameter_lists = 0;
+
+ start_lambda_scope (current_function_decl);
+
+ /* If the next token is `try', `__transaction_atomic', or
+ `__transaction_relaxed`, then we are looking at either function-try-block
+ or function-transaction-block. Note that all of these include the
+ function-body. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRANSACTION_ATOMIC))
+ ctor_initializer_p = cp_parser_function_transaction (parser,
+ RID_TRANSACTION_ATOMIC);
+ else if (cp_lexer_next_token_is_keyword (parser->lexer,
+ RID_TRANSACTION_RELAXED))
+ ctor_initializer_p = cp_parser_function_transaction (parser,
+ RID_TRANSACTION_RELAXED);
+ else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
+ ctor_initializer_p = cp_parser_function_try_block (parser);
+ else
+ ctor_initializer_p = cp_parser_ctor_initializer_opt_and_function_body
+ (parser, /*in_function_try_block=*/false);
+
+ finish_lambda_scope ();
+
+ /* Finish the function. */
+ fn = finish_function ((ctor_initializer_p ? 1 : 0) |
+ (inline_p ? 2 : 0));
+ /* Generate code for it, if necessary. */
+ expand_or_defer_fn (fn);
+ /* Restore the saved values. */
+ parser->in_unbraced_linkage_specification_p
+ = saved_in_unbraced_linkage_specification_p;
+ parser->num_template_parameter_lists
+ = saved_num_template_parameter_lists;
+ parser->in_function_body = saved_in_function_body;
+
+ parser->fully_implicit_function_template_p
+ = fully_implicit_function_template_p;
+ parser->implicit_template_parms
+ = implicit_template_parms;
+ parser->implicit_template_scope
+ = implicit_template_scope;
+
+ if (parser->fully_implicit_function_template_p)
+ finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
+
+ return fn;
+}
+
+/* Parse a template-declaration, assuming that the `export' (and
+ `extern') keywords, if present, has already been scanned. MEMBER_P
+ is as for cp_parser_template_declaration. */
+
+static void
+cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
+{
+ tree decl = NULL_TREE;
+ vec<deferred_access_check, va_gc> *checks;
+ tree parameter_list;
+ bool friend_p = false;
+ bool need_lang_pop;
+ cp_token *token;
+
+ /* Look for the `template' keyword. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (!cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE))
+ return;
+
+ /* And the `<'. */
+ if (!cp_parser_require (parser, CPP_LESS, RT_LESS))
+ return;
+ if (at_class_scope_p () && current_function_decl)
+ {
+ /* 14.5.2.2 [temp.mem]
+
+ A local class shall not have member templates. */
+ error_at (token->location,
+ "invalid declaration of member template in local class");
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return;
+ }
+ /* [temp]
+
+ A template ... shall not have C linkage. */
+ if (current_lang_name == lang_name_c)
+ {
+ error_at (token->location, "template with C linkage");
+ /* Give it C++ linkage to avoid confusing other parts of the
+ front end. */
+ push_lang_context (lang_name_cplusplus);
+ need_lang_pop = true;
+ }
+ else
+ need_lang_pop = false;
+
+ /* We cannot perform access checks on the template parameter
+ declarations until we know what is being declared, just as we
+ cannot check the decl-specifier list. */
+ push_deferring_access_checks (dk_deferred);
+
+ /* If the next token is `>', then we have an invalid
+ specialization. Rather than complain about an invalid template
+ parameter, issue an error message here. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER))
+ {
+ cp_parser_error (parser, "invalid explicit specialization");
+ begin_specialization ();
+ parameter_list = NULL_TREE;
+ }
+ else
+ {
+ /* Parse the template parameters. */
+ parameter_list = cp_parser_template_parameter_list (parser);
+ }
+
+ /* Get the deferred access checks from the parameter list. These
+ will be checked once we know what is being declared, as for a
+ member template the checks must be performed in the scope of the
+ class containing the member. */
+ checks = get_deferred_access_checks ();
+
+ /* Look for the `>'. */
+ cp_parser_skip_to_end_of_template_parameter_list (parser);
+ /* We just processed one more parameter list. */
+ ++parser->num_template_parameter_lists;
+ /* If the next token is `template', there are more template
+ parameters. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer,
+ RID_TEMPLATE))
+ cp_parser_template_declaration_after_export (parser, member_p);
+ else if (cxx_dialect >= cxx11
+ && cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
+ decl = cp_parser_alias_declaration (parser);
+ else
+ {
+ /* There are no access checks when parsing a template, as we do not
+ know if a specialization will be a friend. */
+ push_deferring_access_checks (dk_no_check);
+ token = cp_lexer_peek_token (parser->lexer);
+ decl = cp_parser_single_declaration (parser,
+ checks,
+ member_p,
+ /*explicit_specialization_p=*/false,
+ &friend_p);
+ pop_deferring_access_checks ();
+
+ /* If this is a member template declaration, let the front
+ end know. */
+ if (member_p && !friend_p && decl)
+ {
+ if (TREE_CODE (decl) == TYPE_DECL)
+ cp_parser_check_access_in_redeclaration (decl, token->location);
+
+ decl = finish_member_template_decl (decl);
+ }
+ else if (friend_p && decl
+ && DECL_DECLARES_TYPE_P (decl))
+ make_friend_class (current_class_type, TREE_TYPE (decl),
+ /*complain=*/true);
+ }
+ /* We are done with the current parameter list. */
+ --parser->num_template_parameter_lists;
+
+ pop_deferring_access_checks ();
+
+ /* Finish up. */
+ finish_template_decl (parameter_list);
+
+ /* Check the template arguments for a literal operator template. */
+ if (decl
+ && DECL_DECLARES_FUNCTION_P (decl)
+ && UDLIT_OPER_P (DECL_NAME (decl)))
+ {
+ bool ok = true;
+ if (parameter_list == NULL_TREE)
+ ok = false;
+ else
+ {
+ int num_parms = TREE_VEC_LENGTH (parameter_list);
+ if (num_parms == 1)
+ {
+ tree parm_list = TREE_VEC_ELT (parameter_list, 0);
+ tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
+ if (TREE_TYPE (parm) != char_type_node
+ || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
+ ok = false;
+ }
+ else if (num_parms == 2 && cxx_dialect >= cxx1y)
+ {
+ tree parm_type = TREE_VEC_ELT (parameter_list, 0);
+ tree type = INNERMOST_TEMPLATE_PARMS (parm_type);
+ tree parm_list = TREE_VEC_ELT (parameter_list, 1);
+ tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
+ if (TREE_TYPE (parm) != TREE_TYPE (type)
+ || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
+ ok = false;
+ }
+ else
+ ok = false;
+ }
+ if (!ok)
+ error ("literal operator template %qD has invalid parameter list."
+ " Expected non-type template argument pack <char...>"
+ " or <typename CharT, CharT...>",
+ decl);
+ }
+ /* Register member declarations. */
+ if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl))
+ finish_member_declaration (decl);
+ /* For the erroneous case of a template with C linkage, we pushed an
+ implicit C++ linkage scope; exit that scope now. */
+ if (need_lang_pop)
+ pop_lang_context ();
+ /* If DECL is a function template, we must return to parse it later.
+ (Even though there is no definition, there might be default
+ arguments that need handling.) */
+ if (member_p && decl
+ && DECL_DECLARES_FUNCTION_P (decl))
+ vec_safe_push (unparsed_funs_with_definitions, decl);
+}
+
+/* Perform the deferred access checks from a template-parameter-list.
+ CHECKS is a TREE_LIST of access checks, as returned by
+ get_deferred_access_checks. */
+
+static void
+cp_parser_perform_template_parameter_access_checks (vec<deferred_access_check, va_gc> *checks)
+{
+ ++processing_template_parmlist;
+ perform_access_checks (checks, tf_warning_or_error);
+ --processing_template_parmlist;
+}
+
+/* Parse a `decl-specifier-seq [opt] init-declarator [opt] ;' or
+ `function-definition' sequence that follows a template header.
+ If MEMBER_P is true, this declaration appears in a class scope.
+
+ Returns the DECL for the declared entity. If FRIEND_P is non-NULL,
+ *FRIEND_P is set to TRUE iff the declaration is a friend. */
+
+static tree
+cp_parser_single_declaration (cp_parser* parser,
+ vec<deferred_access_check, va_gc> *checks,
+ bool member_p,
+ bool explicit_specialization_p,
+ bool* friend_p)
+{
+ int declares_class_or_enum;
+ tree decl = NULL_TREE;
+ cp_decl_specifier_seq decl_specifiers;
+ bool function_definition_p = false;
+ cp_token *decl_spec_token_start;
+
+ /* This function is only used when processing a template
+ declaration. */
+ gcc_assert (innermost_scope_kind () == sk_template_parms
+ || innermost_scope_kind () == sk_template_spec);
+
+ /* Defer access checks until we know what is being declared. */
+ push_deferring_access_checks (dk_deferred);
+
+ /* Try the `decl-specifier-seq [opt] init-declarator [opt]'
+ alternative. */
+ decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
+ cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_OPTIONAL,
+ &decl_specifiers,
+ &declares_class_or_enum);
+ if (friend_p)
+ *friend_p = cp_parser_friend_p (&decl_specifiers);
+
+ /* There are no template typedefs. */
+ if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_typedef))
+ {
+ error_at (decl_spec_token_start->location,
+ "template declaration of %<typedef%>");
+ decl = error_mark_node;
+ }
+
+ /* Gather up the access checks that occurred the
+ decl-specifier-seq. */
+ stop_deferring_access_checks ();
+
+ /* Check for the declaration of a template class. */
+ if (declares_class_or_enum)
+ {
+ if (cp_parser_declares_only_class_p (parser))
+ {
+ decl = shadow_tag (&decl_specifiers);
+
+ /* In this case:
+
+ struct C {
+ friend template <typename T> struct A<T>::B;
+ };
+
+ A<T>::B will be represented by a TYPENAME_TYPE, and
+ therefore not recognized by shadow_tag. */
+ if (friend_p && *friend_p
+ && !decl
+ && decl_specifiers.type
+ && TYPE_P (decl_specifiers.type))
+ decl = decl_specifiers.type;
+
+ if (decl && decl != error_mark_node)
+ decl = TYPE_NAME (decl);
+ else
+ decl = error_mark_node;
+
+ /* Perform access checks for template parameters. */
+ cp_parser_perform_template_parameter_access_checks (checks);
+ }
+ }
+
+ /* Complain about missing 'typename' or other invalid type names. */
+ if (!decl_specifiers.any_type_specifiers_p
+ && cp_parser_parse_and_diagnose_invalid_type_name (parser))
+ {
+ /* cp_parser_parse_and_diagnose_invalid_type_name calls
+ cp_parser_skip_to_end_of_block_or_statement, so don't try to parse
+ the rest of this declaration. */
+ decl = error_mark_node;
+ goto out;
+ }
+
+ /* If it's not a template class, try for a template function. If
+ the next token is a `;', then this declaration does not declare
+ anything. But, if there were errors in the decl-specifiers, then
+ the error might well have come from an attempted class-specifier.
+ In that case, there's no need to warn about a missing declarator. */
+ if (!decl
+ && (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
+ || decl_specifiers.type != error_mark_node))
+ {
+ decl = cp_parser_init_declarator (parser,
+ &decl_specifiers,
+ checks,
+ /*function_definition_allowed_p=*/true,
+ member_p,
+ declares_class_or_enum,
+ &function_definition_p,
+ NULL);
+
+ /* 7.1.1-1 [dcl.stc]
+
+ A storage-class-specifier shall not be specified in an explicit
+ specialization... */
+ if (decl
+ && explicit_specialization_p
+ && decl_specifiers.storage_class != sc_none)
+ {
+ error_at (decl_spec_token_start->location,
+ "explicit template specialization cannot have a storage class");
+ decl = error_mark_node;
+ }
+
+ if (decl && VAR_P (decl))
+ check_template_variable (decl);
+ }
+
+ /* Look for a trailing `;' after the declaration. */
+ if (!function_definition_p
+ && (decl == error_mark_node
+ || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)))
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+
+ out:
+ pop_deferring_access_checks ();
+
+ /* Clear any current qualification; whatever comes next is the start
+ of something new. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+
+ return decl;
+}
+
+/* Parse a cast-expression that is not the operand of a unary "&". */
+
+static tree
+cp_parser_simple_cast_expression (cp_parser *parser)
+{
+ return cp_parser_cast_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false, /*decltype*/false, NULL);
+}
+
+/* Parse a functional cast to TYPE. Returns an expression
+ representing the cast. */
+
+static tree
+cp_parser_functional_cast (cp_parser* parser, tree type)
+{
+ vec<tree, va_gc> *vec;
+ tree expression_list;
+ tree cast;
+ bool nonconst_p;
+
+ if (!type)
+ type = error_mark_node;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ cp_lexer_set_source_position (parser->lexer);
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ expression_list = cp_parser_braced_list (parser, &nonconst_p);
+ CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
+ if (TREE_CODE (type) == TYPE_DECL)
+ type = TREE_TYPE (type);
+ return finish_compound_literal (type, expression_list,
+ tf_warning_or_error);
+ }
+
+
+ vec = cp_parser_parenthesized_expression_list (parser, non_attr,
+ /*cast_p=*/true,
+ /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL);
+ if (vec == NULL)
+ expression_list = error_mark_node;
+ else
+ {
+ expression_list = build_tree_list_vec (vec);
+ release_tree_vector (vec);
+ }
+
+ cast = build_functional_cast (type, expression_list,
+ tf_warning_or_error);
+ /* [expr.const]/1: In an integral constant expression "only type
+ conversions to integral or enumeration type can be used". */
+ if (TREE_CODE (type) == TYPE_DECL)
+ type = TREE_TYPE (type);
+ if (cast != error_mark_node
+ && !cast_valid_in_integral_constant_expression_p (type)
+ && cp_parser_non_integral_constant_expression (parser,
+ NIC_CONSTRUCTOR))
+ return error_mark_node;
+ return cast;
+}
+
+/* Save the tokens that make up the body of a member function defined
+ in a class-specifier. The DECL_SPECIFIERS and DECLARATOR have
+ already been parsed. The ATTRIBUTES are any GNU "__attribute__"
+ specifiers applied to the declaration. Returns the FUNCTION_DECL
+ for the member function. */
+
+static tree
+cp_parser_save_member_function_body (cp_parser* parser,
+ cp_decl_specifier_seq *decl_specifiers,
+ cp_declarator *declarator,
+ tree attributes)
+{
+ cp_token *first;
+ cp_token *last;
+ tree fn;
+
+ /* Create the FUNCTION_DECL. */
+ fn = grokmethod (decl_specifiers, declarator, attributes);
+ cp_finalize_omp_declare_simd (parser, fn);
+ /* If something went badly wrong, bail out now. */
+ if (fn == error_mark_node)
+ {
+ /* If there's a function-body, skip it. */
+ if (cp_parser_token_starts_function_definition_p
+ (cp_lexer_peek_token (parser->lexer)))
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+
+ /* Remember it, if there default args to post process. */
+ cp_parser_save_default_args (parser, fn);
+
+ /* Save away the tokens that make up the body of the
+ function. */
+ first = parser->lexer->next_token;
+ /* Handle function try blocks. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
+ cp_lexer_consume_token (parser->lexer);
+ /* We can have braced-init-list mem-initializers before the fn body. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
+ {
+ /* cache_group will stop after an un-nested { } pair, too. */
+ if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0))
+ break;
+
+ /* variadic mem-inits have ... after the ')'. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+ cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
+ /* Handle function try blocks. */
+ while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH))
+ cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
+ last = parser->lexer->next_token;
+
+ /* Save away the inline definition; we will process it when the
+ class is complete. */
+ DECL_PENDING_INLINE_INFO (fn) = cp_token_cache_new (first, last);
+ DECL_PENDING_INLINE_P (fn) = 1;
+
+ /* We need to know that this was defined in the class, so that
+ friend templates are handled correctly. */
+ DECL_INITIALIZED_IN_CLASS_P (fn) = 1;
+
+ /* Add FN to the queue of functions to be parsed later. */
+ vec_safe_push (unparsed_funs_with_definitions, fn);
+
+ return fn;
+}
+
+/* Save the tokens that make up the in-class initializer for a non-static
+ data member. Returns a DEFAULT_ARG. */
+
+static tree
+cp_parser_save_nsdmi (cp_parser* parser)
+{
+ return cp_parser_cache_defarg (parser, /*nsdmi=*/true);
+}
+
+/* Parse a template-argument-list, as well as the trailing ">" (but
+ not the opening "<"). See cp_parser_template_argument_list for the
+ return value. */
+
+static tree
+cp_parser_enclosed_template_argument_list (cp_parser* parser)
+{
+ tree arguments;
+ tree saved_scope;
+ tree saved_qualifying_scope;
+ tree saved_object_scope;
+ bool saved_greater_than_is_operator_p;
+ int saved_unevaluated_operand;
+ int saved_inhibit_evaluation_warnings;
+
+ /* [temp.names]
+
+ When parsing a template-id, the first non-nested `>' is taken as
+ the end of the template-argument-list rather than a greater-than
+ operator. */
+ saved_greater_than_is_operator_p
+ = parser->greater_than_is_operator_p;
+ parser->greater_than_is_operator_p = false;
+ /* Parsing the argument list may modify SCOPE, so we save it
+ here. */
+ saved_scope = parser->scope;
+ saved_qualifying_scope = parser->qualifying_scope;
+ saved_object_scope = parser->object_scope;
+ /* We need to evaluate the template arguments, even though this
+ template-id may be nested within a "sizeof". */
+ saved_unevaluated_operand = cp_unevaluated_operand;
+ cp_unevaluated_operand = 0;
+ saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+ c_inhibit_evaluation_warnings = 0;
+ /* Parse the template-argument-list itself. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER)
+ || cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
+ arguments = NULL_TREE;
+ else
+ arguments = cp_parser_template_argument_list (parser);
+ /* Look for the `>' that ends the template-argument-list. If we find
+ a '>>' instead, it's probably just a typo. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
+ {
+ if (cxx_dialect != cxx98)
+ {
+ /* In C++0x, a `>>' in a template argument list or cast
+ expression is considered to be two separate `>'
+ tokens. So, change the current token to a `>', but don't
+ consume it: it will be consumed later when the outer
+ template argument list (or cast expression) is parsed.
+ Note that this replacement of `>' for `>>' is necessary
+ even if we are parsing tentatively: in the tentative
+ case, after calling
+ cp_parser_enclosed_template_argument_list we will always
+ throw away all of the template arguments and the first
+ closing `>', either because the template argument list
+ was erroneous or because we are replacing those tokens
+ with a CPP_TEMPLATE_ID token. The second `>' (which will
+ not have been thrown away) is needed either to close an
+ outer template argument list or to complete a new-style
+ cast. */
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ token->type = CPP_GREATER;
+ }
+ else if (!saved_greater_than_is_operator_p)
+ {
+ /* If we're in a nested template argument list, the '>>' has
+ to be a typo for '> >'. We emit the error message, but we
+ continue parsing and we push a '>' as next token, so that
+ the argument list will be parsed correctly. Note that the
+ global source location is still on the token before the
+ '>>', so we need to say explicitly where we want it. */
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ error_at (token->location, "%<>>%> should be %<> >%> "
+ "within a nested template argument list");
+
+ token->type = CPP_GREATER;
+ }
+ else
+ {
+ /* If this is not a nested template argument list, the '>>'
+ is a typo for '>'. Emit an error message and continue.
+ Same deal about the token location, but here we can get it
+ right by consuming the '>>' before issuing the diagnostic. */
+ cp_token *token = cp_lexer_consume_token (parser->lexer);
+ error_at (token->location,
+ "spurious %<>>%>, use %<>%> to terminate "
+ "a template argument list");
+ }
+ }
+ else
+ cp_parser_skip_to_end_of_template_parameter_list (parser);
+ /* The `>' token might be a greater-than operator again now. */
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+ /* Restore the SAVED_SCOPE. */
+ parser->scope = saved_scope;
+ parser->qualifying_scope = saved_qualifying_scope;
+ parser->object_scope = saved_object_scope;
+ cp_unevaluated_operand = saved_unevaluated_operand;
+ c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
+
+ return arguments;
+}
+
+/* MEMBER_FUNCTION is a member function, or a friend. If default
+ arguments, or the body of the function have not yet been parsed,
+ parse them now. */
+
+static void
+cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
+{
+ timevar_push (TV_PARSE_INMETH);
+ /* If this member is a template, get the underlying
+ FUNCTION_DECL. */
+ if (DECL_FUNCTION_TEMPLATE_P (member_function))
+ member_function = DECL_TEMPLATE_RESULT (member_function);
+
+ /* There should not be any class definitions in progress at this
+ point; the bodies of members are only parsed outside of all class
+ definitions. */
+ gcc_assert (parser->num_classes_being_defined == 0);
+ /* While we're parsing the member functions we might encounter more
+ classes. We want to handle them right away, but we don't want
+ them getting mixed up with functions that are currently in the
+ queue. */
+ push_unparsed_function_queues (parser);
+
+ /* Make sure that any template parameters are in scope. */
+ maybe_begin_member_template_processing (member_function);
+
+ /* If the body of the function has not yet been parsed, parse it
+ now. */
+ if (DECL_PENDING_INLINE_P (member_function))
+ {
+ tree function_scope;
+ cp_token_cache *tokens;
+
+ /* The function is no longer pending; we are processing it. */
+ tokens = DECL_PENDING_INLINE_INFO (member_function);
+ DECL_PENDING_INLINE_INFO (member_function) = NULL;
+ DECL_PENDING_INLINE_P (member_function) = 0;
+
+ /* If this is a local class, enter the scope of the containing
+ function. */
+ function_scope = current_function_decl;
+ if (function_scope)
+ push_function_context ();
+
+ /* Push the body of the function onto the lexer stack. */
+ cp_parser_push_lexer_for_tokens (parser, tokens);
+
+ /* Let the front end know that we going to be defining this
+ function. */
+ start_preparsed_function (member_function, NULL_TREE,
+ SF_PRE_PARSED | SF_INCLASS_INLINE);
+
+ /* Don't do access checking if it is a templated function. */
+ if (processing_template_decl)
+ push_deferring_access_checks (dk_no_check);
+
+ /* #pragma omp declare reduction needs special parsing. */
+ if (DECL_OMP_DECLARE_REDUCTION_P (member_function))
+ {
+ parser->lexer->in_pragma = true;
+ cp_parser_omp_declare_reduction_exprs (member_function, parser);
+ finish_function (/*inline*/2);
+ cp_check_omp_declare_reduction (member_function);
+ }
+ else
+ /* Now, parse the body of the function. */
+ cp_parser_function_definition_after_declarator (parser,
+ /*inline_p=*/true);
+
+ if (processing_template_decl)
+ pop_deferring_access_checks ();
+
+ /* Leave the scope of the containing function. */
+ if (function_scope)
+ pop_function_context ();
+ cp_parser_pop_lexer (parser);
+ }
+
+ /* Remove any template parameters from the symbol table. */
+ maybe_end_member_template_processing ();
+
+ /* Restore the queue. */
+ pop_unparsed_function_queues (parser);
+ timevar_pop (TV_PARSE_INMETH);
+}
+
+/* If DECL contains any default args, remember it on the unparsed
+ functions queue. */
+
+static void
+cp_parser_save_default_args (cp_parser* parser, tree decl)
+{
+ tree probe;
+
+ for (probe = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ probe;
+ probe = TREE_CHAIN (probe))
+ if (TREE_PURPOSE (probe))
+ {
+ cp_default_arg_entry entry = {current_class_type, decl};
+ vec_safe_push (unparsed_funs_with_default_args, entry);
+ break;
+ }
+}
+
+/* DEFAULT_ARG contains the saved tokens for the initializer of DECL,
+ which is either a FIELD_DECL or PARM_DECL. Parse it and return
+ the result. For a PARM_DECL, PARMTYPE is the corresponding type
+ from the parameter-type-list. */
+
+static tree
+cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl,
+ tree default_arg, tree parmtype)
+{
+ cp_token_cache *tokens;
+ tree parsed_arg;
+ bool dummy;
+
+ if (default_arg == error_mark_node)
+ return error_mark_node;
+
+ /* Push the saved tokens for the default argument onto the parser's
+ lexer stack. */
+ tokens = DEFARG_TOKENS (default_arg);
+ cp_parser_push_lexer_for_tokens (parser, tokens);
+
+ start_lambda_scope (decl);
+
+ /* Parse the default argument. */
+ parsed_arg = cp_parser_initializer (parser, &dummy, &dummy);
+ if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg))
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+
+ finish_lambda_scope ();
+
+ if (parsed_arg == error_mark_node)
+ cp_parser_skip_to_end_of_statement (parser);
+
+ if (!processing_template_decl)
+ {
+ /* In a non-template class, check conversions now. In a template,
+ we'll wait and instantiate these as needed. */
+ if (TREE_CODE (decl) == PARM_DECL)
+ parsed_arg = check_default_argument (parmtype, parsed_arg,
+ tf_warning_or_error);
+ else
+ {
+ int flags = LOOKUP_IMPLICIT;
+ if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg)
+ && CONSTRUCTOR_IS_DIRECT_INIT (parsed_arg))
+ flags = LOOKUP_NORMAL;
+ parsed_arg = digest_init_flags (TREE_TYPE (decl), parsed_arg, flags);
+ if (TREE_CODE (parsed_arg) == TARGET_EXPR)
+ /* This represents the whole initialization. */
+ TARGET_EXPR_DIRECT_INIT_P (parsed_arg) = true;
+ }
+ }
+
+ /* If the token stream has not been completely used up, then
+ there was extra junk after the end of the default
+ argument. */
+ if (!cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ {
+ if (TREE_CODE (decl) == PARM_DECL)
+ cp_parser_error (parser, "expected %<,%>");
+ else
+ cp_parser_error (parser, "expected %<;%>");
+ }
+
+ /* Revert to the main lexer. */
+ cp_parser_pop_lexer (parser);
+
+ return parsed_arg;
+}
+
+/* FIELD is a non-static data member with an initializer which we saved for
+ later; parse it now. */
+
+static void
+cp_parser_late_parsing_nsdmi (cp_parser *parser, tree field)
+{
+ tree def;
+
+ maybe_begin_member_template_processing (field);
+
+ push_unparsed_function_queues (parser);
+ def = cp_parser_late_parse_one_default_arg (parser, field,
+ DECL_INITIAL (field),
+ NULL_TREE);
+ pop_unparsed_function_queues (parser);
+
+ maybe_end_member_template_processing ();
+
+ DECL_INITIAL (field) = def;
+}
+
+/* FN is a FUNCTION_DECL which may contains a parameter with an
+ unparsed DEFAULT_ARG. Parse the default args now. This function
+ assumes that the current scope is the scope in which the default
+ argument should be processed. */
+
+static void
+cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
+{
+ bool saved_local_variables_forbidden_p;
+ tree parm, parmdecl;
+
+ /* While we're parsing the default args, we might (due to the
+ statement expression extension) encounter more classes. We want
+ to handle them right away, but we don't want them getting mixed
+ up with default args that are currently in the queue. */
+ push_unparsed_function_queues (parser);
+
+ /* Local variable names (and the `this' keyword) may not appear
+ in a default argument. */
+ saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
+ parser->local_variables_forbidden_p = true;
+
+ push_defarg_context (fn);
+
+ for (parm = TYPE_ARG_TYPES (TREE_TYPE (fn)),
+ parmdecl = DECL_ARGUMENTS (fn);
+ parm && parm != void_list_node;
+ parm = TREE_CHAIN (parm),
+ parmdecl = DECL_CHAIN (parmdecl))
+ {
+ tree default_arg = TREE_PURPOSE (parm);
+ tree parsed_arg;
+ vec<tree, va_gc> *insts;
+ tree copy;
+ unsigned ix;
+
+ if (!default_arg)
+ continue;
+
+ if (TREE_CODE (default_arg) != DEFAULT_ARG)
+ /* This can happen for a friend declaration for a function
+ already declared with default arguments. */
+ continue;
+
+ parsed_arg
+ = cp_parser_late_parse_one_default_arg (parser, parmdecl,
+ default_arg,
+ TREE_VALUE (parm));
+ if (parsed_arg == error_mark_node)
+ {
+ continue;
+ }
+
+ TREE_PURPOSE (parm) = parsed_arg;
+
+ /* Update any instantiations we've already created. */
+ for (insts = DEFARG_INSTANTIATIONS (default_arg), ix = 0;
+ vec_safe_iterate (insts, ix, &copy); ix++)
+ TREE_PURPOSE (copy) = parsed_arg;
+ }
+
+ pop_defarg_context ();
+
+ /* Make sure no default arg is missing. */
+ check_default_args (fn);
+
+ /* Restore the state of local_variables_forbidden_p. */
+ parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
+
+ /* Restore the queue. */
+ pop_unparsed_function_queues (parser);
+}
+
+/* Subroutine of cp_parser_sizeof_operand, for handling C++11
+
+ sizeof ... ( identifier )
+
+ where the 'sizeof' token has already been consumed. */
+
+static tree
+cp_parser_sizeof_pack (cp_parser *parser)
+{
+ /* Consume the `...'. */
+ cp_lexer_consume_token (parser->lexer);
+ maybe_warn_variadic_templates ();
+
+ bool paren = cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN);
+ if (paren)
+ cp_lexer_consume_token (parser->lexer);
+ else
+ permerror (cp_lexer_peek_token (parser->lexer)->location,
+ "%<sizeof...%> argument must be surrounded by parentheses");
+
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ tree name = cp_parser_identifier (parser);
+ if (name == error_mark_node)
+ return error_mark_node;
+ /* The name is not qualified. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ tree expr = cp_parser_lookup_name_simple (parser, name, token->location);
+ if (expr == error_mark_node)
+ cp_parser_name_lookup_error (parser, name, expr, NLE_NULL,
+ token->location);
+ if (TREE_CODE (expr) == TYPE_DECL)
+ expr = TREE_TYPE (expr);
+ else if (TREE_CODE (expr) == CONST_DECL)
+ expr = DECL_INITIAL (expr);
+ expr = make_pack_expansion (expr);
+
+ if (paren)
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ return expr;
+}
+
+/* Parse the operand of `sizeof' (or a similar operator). Returns
+ either a TYPE or an expression, depending on the form of the
+ input. The KEYWORD indicates which kind of expression we have
+ encountered. */
+
+static tree
+cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
+{
+ tree expr = NULL_TREE;
+ const char *saved_message;
+ char *tmp;
+ bool saved_integral_constant_expression_p;
+ bool saved_non_integral_constant_expression_p;
+
+ /* If it's a `...', then we are computing the length of a parameter
+ pack. */
+ if (keyword == RID_SIZEOF
+ && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ return cp_parser_sizeof_pack (parser);
+
+ /* Types cannot be defined in a `sizeof' expression. Save away the
+ old message. */
+ saved_message = parser->type_definition_forbidden_message;
+ /* And create the new one. */
+ tmp = concat ("types may not be defined in %<",
+ IDENTIFIER_POINTER (ridpointers[keyword]),
+ "%> expressions", NULL);
+ parser->type_definition_forbidden_message = tmp;
+
+ /* The restrictions on constant-expressions do not apply inside
+ sizeof expressions. */
+ saved_integral_constant_expression_p
+ = parser->integral_constant_expression_p;
+ saved_non_integral_constant_expression_p
+ = parser->non_integral_constant_expression_p;
+ parser->integral_constant_expression_p = false;
+
+ /* Do not actually evaluate the expression. */
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
+ /* If it's a `(', then we might be looking at the type-id
+ construction. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ tree type = NULL_TREE;
+ bool compound_literal_p;
+
+ /* We can't be sure yet whether we're looking at a type-id or an
+ expression. */
+ cp_parser_parse_tentatively (parser);
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Note: as a GNU Extension, compound literals are considered
+ postfix-expressions as they are in C99, so they are valid
+ arguments to sizeof. See comment in cp_parser_cast_expression
+ for details. */
+ cp_lexer_save_tokens (parser->lexer);
+ /* Skip tokens until the next token is a closing parenthesis.
+ If we find the closing `)', and the next token is a `{', then
+ we are looking at a compound-literal. */
+ compound_literal_p
+ = (cp_parser_skip_to_closing_parenthesis (parser, false, false,
+ /*consume_paren=*/true)
+ && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE));
+ /* Roll back the tokens we skipped. */
+ cp_lexer_rollback_tokens (parser->lexer);
+ /* If we were looking at a compound-literal, simulate an error
+ so that the call to cp_parser_parse_definitely below will
+ fail. */
+ if (compound_literal_p)
+ cp_parser_simulate_error (parser);
+ else
+ {
+ bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
+ /* Look for the type-id. */
+ type = cp_parser_type_id (parser);
+ /* Look for the closing `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+ }
+
+ /* If all went well, then we're done. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ cp_decl_specifier_seq decl_specs;
+
+ /* Build a trivial decl-specifier-seq. */
+ clear_decl_specs (&decl_specs);
+ decl_specs.type = type;
+
+ /* Call grokdeclarator to figure out what type this is. */
+ expr = grokdeclarator (NULL,
+ &decl_specs,
+ TYPENAME,
+ /*initialized=*/0,
+ /*attrlist=*/NULL);
+ }
+ }
+
+ /* If the type-id production did not work out, then we must be
+ looking at the unary-expression production. */
+ if (!expr)
+ expr = cp_parser_unary_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false, NULL);
+
+ /* Go back to evaluating expressions. */
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+
+ /* Free the message we created. */
+ free (tmp);
+ /* And restore the old one. */
+ parser->type_definition_forbidden_message = saved_message;
+ parser->integral_constant_expression_p
+ = saved_integral_constant_expression_p;
+ parser->non_integral_constant_expression_p
+ = saved_non_integral_constant_expression_p;
+
+ return expr;
+}
+
+/* If the current declaration has no declarator, return true. */
+
+static bool
+cp_parser_declares_only_class_p (cp_parser *parser)
+{
+ /* If the next token is a `;' or a `,' then there is no
+ declarator. */
+ return (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
+ || cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
+}
+
+/* Update the DECL_SPECS to reflect the storage class indicated by
+ KEYWORD. */
+
+static void
+cp_parser_set_storage_class (cp_parser *parser,
+ cp_decl_specifier_seq *decl_specs,
+ enum rid keyword,
+ cp_token *token)
+{
+ cp_storage_class storage_class;
+
+ if (parser->in_unbraced_linkage_specification_p)
+ {
+ error_at (token->location, "invalid use of %qD in linkage specification",
+ ridpointers[keyword]);
+ return;
+ }
+ else if (decl_specs->storage_class != sc_none)
+ {
+ decl_specs->conflicting_specifiers_p = true;
+ return;
+ }
+
+ if ((keyword == RID_EXTERN || keyword == RID_STATIC)
+ && decl_spec_seq_has_spec_p (decl_specs, ds_thread)
+ && decl_specs->gnu_thread_keyword_p)
+ {
+ pedwarn (decl_specs->locations[ds_thread], 0,
+ "%<__thread%> before %qD", ridpointers[keyword]);
+ }
+
+ switch (keyword)
+ {
+ case RID_AUTO:
+ storage_class = sc_auto;
+ break;
+ case RID_REGISTER:
+ storage_class = sc_register;
+ break;
+ case RID_STATIC:
+ storage_class = sc_static;
+ break;
+ case RID_EXTERN:
+ storage_class = sc_extern;
+ break;
+ case RID_MUTABLE:
+ storage_class = sc_mutable;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ decl_specs->storage_class = storage_class;
+ set_and_check_decl_spec_loc (decl_specs, ds_storage_class, token);
+
+ /* A storage class specifier cannot be applied alongside a typedef
+ specifier. If there is a typedef specifier present then set
+ conflicting_specifiers_p which will trigger an error later
+ on in grokdeclarator. */
+ if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef))
+ decl_specs->conflicting_specifiers_p = true;
+}
+
+/* Update the DECL_SPECS to reflect the TYPE_SPEC. If TYPE_DEFINITION_P
+ is true, the type is a class or enum definition. */
+
+static void
+cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
+ tree type_spec,
+ cp_token *token,
+ bool type_definition_p)
+{
+ decl_specs->any_specifiers_p = true;
+
+ /* If the user tries to redeclare bool, char16_t, char32_t, or wchar_t
+ (with, for example, in "typedef int wchar_t;") we remember that
+ this is what happened. In system headers, we ignore these
+ declarations so that G++ can work with system headers that are not
+ C++-safe. */
+ if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef)
+ && !type_definition_p
+ && (type_spec == boolean_type_node
+ || type_spec == char16_type_node
+ || type_spec == char32_type_node
+ || type_spec == wchar_type_node)
+ && (decl_specs->type
+ || decl_spec_seq_has_spec_p (decl_specs, ds_long)
+ || decl_spec_seq_has_spec_p (decl_specs, ds_short)
+ || decl_spec_seq_has_spec_p (decl_specs, ds_unsigned)
+ || decl_spec_seq_has_spec_p (decl_specs, ds_signed)))
+ {
+ decl_specs->redefined_builtin_type = type_spec;
+ set_and_check_decl_spec_loc (decl_specs,
+ ds_redefined_builtin_type_spec,
+ token);
+ if (!decl_specs->type)
+ {
+ decl_specs->type = type_spec;
+ decl_specs->type_definition_p = false;
+ set_and_check_decl_spec_loc (decl_specs,ds_type_spec, token);
+ }
+ }
+ else if (decl_specs->type)
+ decl_specs->multiple_types_p = true;
+ else
+ {
+ decl_specs->type = type_spec;
+ decl_specs->type_definition_p = type_definition_p;
+ decl_specs->redefined_builtin_type = NULL_TREE;
+ set_and_check_decl_spec_loc (decl_specs, ds_type_spec, token);
+ }
+}
+
+/* True iff TOKEN is the GNU keyword __thread. */
+
+static bool
+token_is__thread (cp_token *token)
+{
+ gcc_assert (token->keyword == RID_THREAD);
+ return !strcmp (IDENTIFIER_POINTER (token->u.value), "__thread");
+}
+
+/* Set the location for a declarator specifier and check if it is
+ duplicated.
+
+ DECL_SPECS is the sequence of declarator specifiers onto which to
+ set the location.
+
+ DS is the single declarator specifier to set which location is to
+ be set onto the existing sequence of declarators.
+
+ LOCATION is the location for the declarator specifier to
+ consider. */
+
+static void
+set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs,
+ cp_decl_spec ds, cp_token *token)
+{
+ gcc_assert (ds < ds_last);
+
+ if (decl_specs == NULL)
+ return;
+
+ source_location location = token->location;
+
+ if (decl_specs->locations[ds] == 0)
+ {
+ decl_specs->locations[ds] = location;
+ if (ds == ds_thread)
+ decl_specs->gnu_thread_keyword_p = token_is__thread (token);
+ }
+ else
+ {
+ if (ds == ds_long)
+ {
+ if (decl_specs->locations[ds_long_long] != 0)
+ error_at (location,
+ "%<long long long%> is too long for GCC");
+ else
+ {
+ decl_specs->locations[ds_long_long] = location;
+ pedwarn_cxx98 (location,
+ OPT_Wlong_long,
+ "ISO C++ 1998 does not support %<long long%>");
+ }
+ }
+ else if (ds == ds_thread)
+ {
+ bool gnu = token_is__thread (token);
+ if (gnu != decl_specs->gnu_thread_keyword_p)
+ error_at (location,
+ "both %<__thread%> and %<thread_local%> specified");
+ else
+ error_at (location, "duplicate %qD", token->u.value);
+ }
+ else
+ {
+ static const char *const decl_spec_names[] = {
+ "signed",
+ "unsigned",
+ "short",
+ "long",
+ "const",
+ "volatile",
+ "restrict",
+ "inline",
+ "virtual",
+ "explicit",
+ "friend",
+ "typedef",
+ "using",
+ "constexpr",
+ "__complex"
+ };
+ error_at (location,
+ "duplicate %qs", decl_spec_names[ds]);
+ }
+ }
+}
+
+/* Return true iff the declarator specifier DS is present in the
+ sequence of declarator specifiers DECL_SPECS. */
+
+bool
+decl_spec_seq_has_spec_p (const cp_decl_specifier_seq * decl_specs,
+ cp_decl_spec ds)
+{
+ gcc_assert (ds < ds_last);
+
+ if (decl_specs == NULL)
+ return false;
+
+ return decl_specs->locations[ds] != 0;
+}
+
+/* DECL_SPECIFIERS is the representation of a decl-specifier-seq.
+ Returns TRUE iff `friend' appears among the DECL_SPECIFIERS. */
+
+static bool
+cp_parser_friend_p (const cp_decl_specifier_seq *decl_specifiers)
+{
+ return decl_spec_seq_has_spec_p (decl_specifiers, ds_friend);
+}
+
+/* Issue an error message indicating that TOKEN_DESC was expected.
+ If KEYWORD is true, it indicated this function is called by
+ cp_parser_require_keword and the required token can only be
+ a indicated keyword. */
+
+static void
+cp_parser_required_error (cp_parser *parser,
+ required_token token_desc,
+ bool keyword)
+{
+ switch (token_desc)
+ {
+ case RT_NEW:
+ cp_parser_error (parser, "expected %<new%>");
+ return;
+ case RT_DELETE:
+ cp_parser_error (parser, "expected %<delete%>");
+ return;
+ case RT_RETURN:
+ cp_parser_error (parser, "expected %<return%>");
+ return;
+ case RT_WHILE:
+ cp_parser_error (parser, "expected %<while%>");
+ return;
+ case RT_EXTERN:
+ cp_parser_error (parser, "expected %<extern%>");
+ return;
+ case RT_STATIC_ASSERT:
+ cp_parser_error (parser, "expected %<static_assert%>");
+ return;
+ case RT_DECLTYPE:
+ cp_parser_error (parser, "expected %<decltype%>");
+ return;
+ case RT_OPERATOR:
+ cp_parser_error (parser, "expected %<operator%>");
+ return;
+ case RT_CLASS:
+ cp_parser_error (parser, "expected %<class%>");
+ return;
+ case RT_TEMPLATE:
+ cp_parser_error (parser, "expected %<template%>");
+ return;
+ case RT_NAMESPACE:
+ cp_parser_error (parser, "expected %<namespace%>");
+ return;
+ case RT_USING:
+ cp_parser_error (parser, "expected %<using%>");
+ return;
+ case RT_ASM:
+ cp_parser_error (parser, "expected %<asm%>");
+ return;
+ case RT_TRY:
+ cp_parser_error (parser, "expected %<try%>");
+ return;
+ case RT_CATCH:
+ cp_parser_error (parser, "expected %<catch%>");
+ return;
+ case RT_THROW:
+ cp_parser_error (parser, "expected %<throw%>");
+ return;
+ case RT_LABEL:
+ cp_parser_error (parser, "expected %<__label__%>");
+ return;
+ case RT_AT_TRY:
+ cp_parser_error (parser, "expected %<@try%>");
+ return;
+ case RT_AT_SYNCHRONIZED:
+ cp_parser_error (parser, "expected %<@synchronized%>");
+ return;
+ case RT_AT_THROW:
+ cp_parser_error (parser, "expected %<@throw%>");
+ return;
+ case RT_TRANSACTION_ATOMIC:
+ cp_parser_error (parser, "expected %<__transaction_atomic%>");
+ return;
+ case RT_TRANSACTION_RELAXED:
+ cp_parser_error (parser, "expected %<__transaction_relaxed%>");
+ return;
+ default:
+ break;
+ }
+ if (!keyword)
+ {
+ switch (token_desc)
+ {
+ case RT_SEMICOLON:
+ cp_parser_error (parser, "expected %<;%>");
+ return;
+ case RT_OPEN_PAREN:
+ cp_parser_error (parser, "expected %<(%>");
+ return;
+ case RT_CLOSE_BRACE:
+ cp_parser_error (parser, "expected %<}%>");
+ return;
+ case RT_OPEN_BRACE:
+ cp_parser_error (parser, "expected %<{%>");
+ return;
+ case RT_CLOSE_SQUARE:
+ cp_parser_error (parser, "expected %<]%>");
+ return;
+ case RT_OPEN_SQUARE:
+ cp_parser_error (parser, "expected %<[%>");
+ return;
+ case RT_COMMA:
+ cp_parser_error (parser, "expected %<,%>");
+ return;
+ case RT_SCOPE:
+ cp_parser_error (parser, "expected %<::%>");
+ return;
+ case RT_LESS:
+ cp_parser_error (parser, "expected %<<%>");
+ return;
+ case RT_GREATER:
+ cp_parser_error (parser, "expected %<>%>");
+ return;
+ case RT_EQ:
+ cp_parser_error (parser, "expected %<=%>");
+ return;
+ case RT_ELLIPSIS:
+ cp_parser_error (parser, "expected %<...%>");
+ return;
+ case RT_MULT:
+ cp_parser_error (parser, "expected %<*%>");
+ return;
+ case RT_COMPL:
+ cp_parser_error (parser, "expected %<~%>");
+ return;
+ case RT_COLON:
+ cp_parser_error (parser, "expected %<:%>");
+ return;
+ case RT_COLON_SCOPE:
+ cp_parser_error (parser, "expected %<:%> or %<::%>");
+ return;
+ case RT_CLOSE_PAREN:
+ cp_parser_error (parser, "expected %<)%>");
+ return;
+ case RT_COMMA_CLOSE_PAREN:
+ cp_parser_error (parser, "expected %<,%> or %<)%>");
+ return;
+ case RT_PRAGMA_EOL:
+ cp_parser_error (parser, "expected end of line");
+ return;
+ case RT_NAME:
+ cp_parser_error (parser, "expected identifier");
+ return;
+ case RT_SELECT:
+ cp_parser_error (parser, "expected selection-statement");
+ return;
+ case RT_INTERATION:
+ cp_parser_error (parser, "expected iteration-statement");
+ return;
+ case RT_JUMP:
+ cp_parser_error (parser, "expected jump-statement");
+ return;
+ case RT_CLASS_KEY:
+ cp_parser_error (parser, "expected class-key");
+ return;
+ case RT_CLASS_TYPENAME_TEMPLATE:
+ cp_parser_error (parser,
+ "expected %<class%>, %<typename%>, or %<template%>");
+ return;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else
+ gcc_unreachable ();
+}
+
+
+
+/* If the next token is of the indicated TYPE, consume it. Otherwise,
+ issue an error message indicating that TOKEN_DESC was expected.
+
+ Returns the token consumed, if the token had the appropriate type.
+ Otherwise, returns NULL. */
+
+static cp_token *
+cp_parser_require (cp_parser* parser,
+ enum cpp_ttype type,
+ required_token token_desc)
+{
+ if (cp_lexer_next_token_is (parser->lexer, type))
+ return cp_lexer_consume_token (parser->lexer);
+ else
+ {
+ /* Output the MESSAGE -- unless we're parsing tentatively. */
+ if (!cp_parser_simulate_error (parser))
+ cp_parser_required_error (parser, token_desc, /*keyword=*/false);
+ return NULL;
+ }
+}
+
+/* An error message is produced if the next token is not '>'.
+ All further tokens are skipped until the desired token is
+ found or '{', '}', ';' or an unbalanced ')' or ']'. */
+
+static void
+cp_parser_skip_to_end_of_template_parameter_list (cp_parser* parser)
+{
+ /* Current level of '< ... >'. */
+ unsigned level = 0;
+ /* Ignore '<' and '>' nested inside '( ... )' or '[ ... ]'. */
+ unsigned nesting_depth = 0;
+
+ /* Are we ready, yet? If not, issue error message. */
+ if (cp_parser_require (parser, CPP_GREATER, RT_GREATER))
+ return;
+
+ /* Skip tokens until the desired token is found. */
+ while (true)
+ {
+ /* Peek at the next token. */
+ switch (cp_lexer_peek_token (parser->lexer)->type)
+ {
+ case CPP_LESS:
+ if (!nesting_depth)
+ ++level;
+ break;
+
+ case CPP_RSHIFT:
+ if (cxx_dialect == cxx98)
+ /* C++0x views the `>>' operator as two `>' tokens, but
+ C++98 does not. */
+ break;
+ else if (!nesting_depth && level-- == 0)
+ {
+ /* We've hit a `>>' where the first `>' closes the
+ template argument list, and the second `>' is
+ spurious. Just consume the `>>' and stop; we've
+ already produced at least one error. */
+ cp_lexer_consume_token (parser->lexer);
+ return;
+ }
+ /* Fall through for C++0x, so we handle the second `>' in
+ the `>>'. */
+
+ case CPP_GREATER:
+ if (!nesting_depth && level-- == 0)
+ {
+ /* We've reached the token we want, consume it and stop. */
+ cp_lexer_consume_token (parser->lexer);
+ return;
+ }
+ break;
+
+ case CPP_OPEN_PAREN:
+ case CPP_OPEN_SQUARE:
+ ++nesting_depth;
+ break;
+
+ case CPP_CLOSE_PAREN:
+ case CPP_CLOSE_SQUARE:
+ if (nesting_depth-- == 0)
+ return;
+ break;
+
+ case CPP_EOF:
+ case CPP_PRAGMA_EOL:
+ case CPP_SEMICOLON:
+ case CPP_OPEN_BRACE:
+ case CPP_CLOSE_BRACE:
+ /* The '>' was probably forgotten, don't look further. */
+ return;
+
+ default:
+ break;
+ }
+
+ /* Consume this token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* If the next token is the indicated keyword, consume it. Otherwise,
+ issue an error message indicating that TOKEN_DESC was expected.
+
+ Returns the token consumed, if the token had the appropriate type.
+ Otherwise, returns NULL. */
+
+static cp_token *
+cp_parser_require_keyword (cp_parser* parser,
+ enum rid keyword,
+ required_token token_desc)
+{
+ cp_token *token = cp_parser_require (parser, CPP_KEYWORD, token_desc);
+
+ if (token && token->keyword != keyword)
+ {
+ cp_parser_required_error (parser, token_desc, /*keyword=*/true);
+ return NULL;
+ }
+
+ return token;
+}
+
+/* Returns TRUE iff TOKEN is a token that can begin the body of a
+ function-definition. */
+
+static bool
+cp_parser_token_starts_function_definition_p (cp_token* token)
+{
+ return (/* An ordinary function-body begins with an `{'. */
+ token->type == CPP_OPEN_BRACE
+ /* A ctor-initializer begins with a `:'. */
+ || token->type == CPP_COLON
+ /* A function-try-block begins with `try'. */
+ || token->keyword == RID_TRY
+ /* A function-transaction-block begins with `__transaction_atomic'
+ or `__transaction_relaxed'. */
+ || token->keyword == RID_TRANSACTION_ATOMIC
+ || token->keyword == RID_TRANSACTION_RELAXED
+ /* The named return value extension begins with `return'. */
+ || token->keyword == RID_RETURN);
+}
+
+/* Returns TRUE iff the next token is the ":" or "{" beginning a class
+ definition. */
+
+static bool
+cp_parser_next_token_starts_class_definition_p (cp_parser *parser)
+{
+ cp_token *token;
+
+ token = cp_lexer_peek_token (parser->lexer);
+ return (token->type == CPP_OPEN_BRACE
+ || (token->type == CPP_COLON
+ && !parser->colon_doesnt_start_class_def_p));
+}
+
+/* Returns TRUE iff the next token is the "," or ">" (or `>>', in
+ C++0x) ending a template-argument. */
+
+static bool
+cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
+{
+ cp_token *token;
+
+ token = cp_lexer_peek_token (parser->lexer);
+ return (token->type == CPP_COMMA
+ || token->type == CPP_GREATER
+ || token->type == CPP_ELLIPSIS
+ || ((cxx_dialect != cxx98) && token->type == CPP_RSHIFT));
+}
+
+/* Returns TRUE iff the n-th token is a "<", or the n-th is a "[" and the
+ (n+1)-th is a ":" (which is a possible digraph typo for "< ::"). */
+
+static bool
+cp_parser_nth_token_starts_template_argument_list_p (cp_parser * parser,
+ size_t n)
+{
+ cp_token *token;
+
+ token = cp_lexer_peek_nth_token (parser->lexer, n);
+ if (token->type == CPP_LESS)
+ return true;
+ /* Check for the sequence `<::' in the original code. It would be lexed as
+ `[:', where `[' is a digraph, and there is no whitespace before
+ `:'. */
+ if (token->type == CPP_OPEN_SQUARE && token->flags & DIGRAPH)
+ {
+ cp_token *token2;
+ token2 = cp_lexer_peek_nth_token (parser->lexer, n+1);
+ if (token2->type == CPP_COLON && !(token2->flags & PREV_WHITE))
+ return true;
+ }
+ return false;
+}
+
+/* Returns the kind of tag indicated by TOKEN, if it is a class-key,
+ or none_type otherwise. */
+
+static enum tag_types
+cp_parser_token_is_class_key (cp_token* token)
+{
+ switch (token->keyword)
+ {
+ case RID_CLASS:
+ return class_type;
+ case RID_STRUCT:
+ return record_type;
+ case RID_UNION:
+ return union_type;
+
+ default:
+ return none_type;
+ }
+}
+
+/* Issue an error message if the CLASS_KEY does not match the TYPE. */
+
+static void
+cp_parser_check_class_key (enum tag_types class_key, tree type)
+{
+ if (type == error_mark_node)
+ return;
+ if ((TREE_CODE (type) == UNION_TYPE) != (class_key == union_type))
+ {
+ if (permerror (input_location, "%qs tag used in naming %q#T",
+ class_key == union_type ? "union"
+ : class_key == record_type ? "struct" : "class",
+ type))
+ inform (DECL_SOURCE_LOCATION (TYPE_NAME (type)),
+ "%q#T was previously declared here", type);
+ }
+}
+
+/* Issue an error message if DECL is redeclared with different
+ access than its original declaration [class.access.spec/3].
+ This applies to nested classes and nested class templates.
+ [class.mem/1]. */
+
+static void
+cp_parser_check_access_in_redeclaration (tree decl, location_t location)
+{
+ if (!decl || !CLASS_TYPE_P (TREE_TYPE (decl)))
+ return;
+
+ if ((TREE_PRIVATE (decl)
+ != (current_access_specifier == access_private_node))
+ || (TREE_PROTECTED (decl)
+ != (current_access_specifier == access_protected_node)))
+ error_at (location, "%qD redeclared with different access", decl);
+}
+
+/* Look for the `template' keyword, as a syntactic disambiguator.
+ Return TRUE iff it is present, in which case it will be
+ consumed. */
+
+static bool
+cp_parser_optional_template_keyword (cp_parser *parser)
+{
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
+ {
+ /* In C++98 the `template' keyword can only be used within templates;
+ outside templates the parser can always figure out what is a
+ template and what is not. In C++11, per the resolution of DR 468,
+ `template' is allowed in cases where it is not strictly necessary. */
+ if (!processing_template_decl
+ && pedantic && cxx_dialect == cxx98)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ pedwarn (token->location, OPT_Wpedantic,
+ "in C++98 %<template%> (as a disambiguator) is only "
+ "allowed within templates");
+ /* If this part of the token stream is rescanned, the same
+ error message would be generated. So, we purge the token
+ from the stream. */
+ cp_lexer_purge_token (parser->lexer);
+ return false;
+ }
+ else
+ {
+ /* Consume the `template' keyword. */
+ cp_lexer_consume_token (parser->lexer);
+ return true;
+ }
+ }
+ return false;
+}
+
+/* The next token is a CPP_NESTED_NAME_SPECIFIER. Consume the token,
+ set PARSER->SCOPE, and perform other related actions. */
+
+static void
+cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
+{
+ int i;
+ struct tree_check *check_value;
+ deferred_access_check *chk;
+ vec<deferred_access_check, va_gc> *checks;
+
+ /* Get the stored value. */
+ check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
+ /* Perform any access checks that were deferred. */
+ checks = check_value->checks;
+ if (checks)
+ {
+ FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
+ perform_or_defer_access_check (chk->binfo,
+ chk->decl,
+ chk->diag_decl, tf_warning_or_error);
+ }
+ /* Set the scope from the stored value. */
+ parser->scope = check_value->value;
+ parser->qualifying_scope = check_value->qualifying_scope;
+ parser->object_scope = NULL_TREE;
+}
+
+/* Consume tokens up through a non-nested END token. Returns TRUE if we
+ encounter the end of a block before what we were looking for. */
+
+static bool
+cp_parser_cache_group (cp_parser *parser,
+ enum cpp_ttype end,
+ unsigned depth)
+{
+ while (true)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* Abort a parenthesized expression if we encounter a semicolon. */
+ if ((end == CPP_CLOSE_PAREN || depth == 0)
+ && token->type == CPP_SEMICOLON)
+ return true;
+ /* If we've reached the end of the file, stop. */
+ if (token->type == CPP_EOF
+ || (end != CPP_PRAGMA_EOL
+ && token->type == CPP_PRAGMA_EOL))
+ return true;
+ if (token->type == CPP_CLOSE_BRACE && depth == 0)
+ /* We've hit the end of an enclosing block, so there's been some
+ kind of syntax error. */
+ return true;
+
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* See if it starts a new group. */
+ if (token->type == CPP_OPEN_BRACE)
+ {
+ cp_parser_cache_group (parser, CPP_CLOSE_BRACE, depth + 1);
+ /* In theory this should probably check end == '}', but
+ cp_parser_save_member_function_body needs it to exit
+ after either '}' or ')' when called with ')'. */
+ if (depth == 0)
+ return false;
+ }
+ else if (token->type == CPP_OPEN_PAREN)
+ {
+ cp_parser_cache_group (parser, CPP_CLOSE_PAREN, depth + 1);
+ if (depth == 0 && end == CPP_CLOSE_PAREN)
+ return false;
+ }
+ else if (token->type == CPP_PRAGMA)
+ cp_parser_cache_group (parser, CPP_PRAGMA_EOL, depth + 1);
+ else if (token->type == end)
+ return false;
+ }
+}
+
+/* Like above, for caching a default argument or NSDMI. Both of these are
+ terminated by a non-nested comma, but it can be unclear whether or not a
+ comma is nested in a template argument list unless we do more parsing.
+ In order to handle this ambiguity, when we encounter a ',' after a '<'
+ we try to parse what follows as a parameter-declaration-list (in the
+ case of a default argument) or a member-declarator (in the case of an
+ NSDMI). If that succeeds, then we stop caching. */
+
+static tree
+cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
+{
+ unsigned depth = 0;
+ int maybe_template_id = 0;
+ cp_token *first_token;
+ cp_token *token;
+ tree default_argument;
+
+ /* Add tokens until we have processed the entire default
+ argument. We add the range [first_token, token). */
+ first_token = cp_lexer_peek_token (parser->lexer);
+ if (first_token->type == CPP_OPEN_BRACE)
+ {
+ /* For list-initialization, this is straightforward. */
+ cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+ else while (true)
+ {
+ bool done = false;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* What we do depends on what token we have. */
+ switch (token->type)
+ {
+ /* In valid code, a default argument must be
+ immediately followed by a `,' `)', or `...'. */
+ case CPP_COMMA:
+ if (depth == 0 && maybe_template_id)
+ {
+ /* If we've seen a '<', we might be in a
+ template-argument-list. Until Core issue 325 is
+ resolved, we don't know how this situation ought
+ to be handled, so try to DTRT. We check whether
+ what comes after the comma is a valid parameter
+ declaration list. If it is, then the comma ends
+ the default argument; otherwise the default
+ argument continues. */
+ bool error = false;
+
+ /* Set ITALP so cp_parser_parameter_declaration_list
+ doesn't decide to commit to this parse. */
+ bool saved_italp = parser->in_template_argument_list_p;
+ parser->in_template_argument_list_p = true;
+
+ cp_parser_parse_tentatively (parser);
+ cp_lexer_consume_token (parser->lexer);
+
+ if (nsdmi)
+ {
+ int ctor_dtor_or_conv_p;
+ cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+ &ctor_dtor_or_conv_p,
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/true);
+ }
+ else
+ {
+ begin_scope (sk_function_parms, NULL_TREE);
+ cp_parser_parameter_declaration_list (parser, &error);
+ pop_bindings_and_leave_scope ();
+ }
+ if (!cp_parser_error_occurred (parser) && !error)
+ done = true;
+ cp_parser_abort_tentative_parse (parser);
+
+ parser->in_template_argument_list_p = saved_italp;
+ break;
+ }
+ case CPP_CLOSE_PAREN:
+ case CPP_ELLIPSIS:
+ /* If we run into a non-nested `;', `}', or `]',
+ then the code is invalid -- but the default
+ argument is certainly over. */
+ case CPP_SEMICOLON:
+ case CPP_CLOSE_BRACE:
+ case CPP_CLOSE_SQUARE:
+ if (depth == 0
+ /* Handle correctly int n = sizeof ... ( p ); */
+ && token->type != CPP_ELLIPSIS)
+ done = true;
+ /* Update DEPTH, if necessary. */
+ else if (token->type == CPP_CLOSE_PAREN
+ || token->type == CPP_CLOSE_BRACE
+ || token->type == CPP_CLOSE_SQUARE)
+ --depth;
+ break;
+
+ case CPP_OPEN_PAREN:
+ case CPP_OPEN_SQUARE:
+ case CPP_OPEN_BRACE:
+ ++depth;
+ break;
+
+ case CPP_LESS:
+ if (depth == 0)
+ /* This might be the comparison operator, or it might
+ start a template argument list. */
+ ++maybe_template_id;
+ break;
+
+ case CPP_RSHIFT:
+ if (cxx_dialect == cxx98)
+ break;
+ /* Fall through for C++0x, which treats the `>>'
+ operator like two `>' tokens in certain
+ cases. */
+
+ case CPP_GREATER:
+ if (depth == 0)
+ {
+ /* This might be an operator, or it might close a
+ template argument list. But if a previous '<'
+ started a template argument list, this will have
+ closed it, so we can't be in one anymore. */
+ maybe_template_id -= 1 + (token->type == CPP_RSHIFT);
+ if (maybe_template_id < 0)
+ maybe_template_id = 0;
+ }
+ break;
+
+ /* If we run out of tokens, issue an error message. */
+ case CPP_EOF:
+ case CPP_PRAGMA_EOL:
+ error_at (token->location, "file ends in default argument");
+ done = true;
+ break;
+
+ case CPP_NAME:
+ case CPP_SCOPE:
+ /* In these cases, we should look for template-ids.
+ For example, if the default argument is
+ `X<int, double>()', we need to do name lookup to
+ figure out whether or not `X' is a template; if
+ so, the `,' does not end the default argument.
+
+ That is not yet done. */
+ break;
+
+ default:
+ break;
+ }
+
+ /* If we've reached the end, stop. */
+ if (done)
+ break;
+
+ /* Add the token to the token block. */
+ token = cp_lexer_consume_token (parser->lexer);
+ }
+
+ /* Create a DEFAULT_ARG to represent the unparsed default
+ argument. */
+ default_argument = make_node (DEFAULT_ARG);
+ DEFARG_TOKENS (default_argument)
+ = cp_token_cache_new (first_token, token);
+ DEFARG_INSTANTIATIONS (default_argument) = NULL;
+
+ return default_argument;
+}
+
+/* Begin parsing tentatively. We always save tokens while parsing
+ tentatively so that if the tentative parsing fails we can restore the
+ tokens. */
+
+static void
+cp_parser_parse_tentatively (cp_parser* parser)
+{
+ /* Enter a new parsing context. */
+ parser->context = cp_parser_context_new (parser->context);
+ /* Begin saving tokens. */
+ cp_lexer_save_tokens (parser->lexer);
+ /* In order to avoid repetitive access control error messages,
+ access checks are queued up until we are no longer parsing
+ tentatively. */
+ push_deferring_access_checks (dk_deferred);
+}
+
+/* Commit to the currently active tentative parse. */
+
+static void
+cp_parser_commit_to_tentative_parse (cp_parser* parser)
+{
+ cp_parser_context *context;
+ cp_lexer *lexer;
+
+ /* Mark all of the levels as committed. */
+ lexer = parser->lexer;
+ for (context = parser->context; context->next; context = context->next)
+ {
+ if (context->status == CP_PARSER_STATUS_KIND_COMMITTED)
+ break;
+ context->status = CP_PARSER_STATUS_KIND_COMMITTED;
+ while (!cp_lexer_saving_tokens (lexer))
+ lexer = lexer->next;
+ cp_lexer_commit_tokens (lexer);
+ }
+}
+
+/* Commit to the topmost currently active tentative parse.
+
+ Note that this function shouldn't be called when there are
+ irreversible side-effects while in a tentative state. For
+ example, we shouldn't create a permanent entry in the symbol
+ table, or issue an error message that might not apply if the
+ tentative parse is aborted. */
+
+static void
+cp_parser_commit_to_topmost_tentative_parse (cp_parser* parser)
+{
+ cp_parser_context *context = parser->context;
+ cp_lexer *lexer = parser->lexer;
+
+ if (context)
+ {
+ if (context->status == CP_PARSER_STATUS_KIND_COMMITTED)
+ return;
+ context->status = CP_PARSER_STATUS_KIND_COMMITTED;
+
+ while (!cp_lexer_saving_tokens (lexer))
+ lexer = lexer->next;
+ cp_lexer_commit_tokens (lexer);
+ }
+}
+
+/* Abort the currently active tentative parse. All consumed tokens
+ will be rolled back, and no diagnostics will be issued. */
+
+static void
+cp_parser_abort_tentative_parse (cp_parser* parser)
+{
+ gcc_assert (parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED
+ || errorcount > 0);
+ cp_parser_simulate_error (parser);
+ /* Now, pretend that we want to see if the construct was
+ successfully parsed. */
+ cp_parser_parse_definitely (parser);
+}
+
+/* Stop parsing tentatively. If a parse error has occurred, restore the
+ token stream. Otherwise, commit to the tokens we have consumed.
+ Returns true if no error occurred; false otherwise. */
+
+static bool
+cp_parser_parse_definitely (cp_parser* parser)
+{
+ bool error_occurred;
+ cp_parser_context *context;
+
+ /* Remember whether or not an error occurred, since we are about to
+ destroy that information. */
+ error_occurred = cp_parser_error_occurred (parser);
+ /* Remove the topmost context from the stack. */
+ context = parser->context;
+ parser->context = context->next;
+ /* If no parse errors occurred, commit to the tentative parse. */
+ if (!error_occurred)
+ {
+ /* Commit to the tokens read tentatively, unless that was
+ already done. */
+ if (context->status != CP_PARSER_STATUS_KIND_COMMITTED)
+ cp_lexer_commit_tokens (parser->lexer);
+
+ pop_to_parent_deferring_access_checks ();
+ }
+ /* Otherwise, if errors occurred, roll back our state so that things
+ are just as they were before we began the tentative parse. */
+ else
+ {
+ cp_lexer_rollback_tokens (parser->lexer);
+ pop_deferring_access_checks ();
+ }
+ /* Add the context to the front of the free list. */
+ context->next = cp_parser_context_free_list;
+ cp_parser_context_free_list = context;
+
+ return !error_occurred;
+}
+
+/* Returns true if we are parsing tentatively and are not committed to
+ this tentative parse. */
+
+static bool
+cp_parser_uncommitted_to_tentative_parse_p (cp_parser* parser)
+{
+ return (cp_parser_parsing_tentatively (parser)
+ && parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED);
+}
+
+/* Returns nonzero iff an error has occurred during the most recent
+ tentative parse. */
+
+static bool
+cp_parser_error_occurred (cp_parser* parser)
+{
+ return (cp_parser_parsing_tentatively (parser)
+ && parser->context->status == CP_PARSER_STATUS_KIND_ERROR);
+}
+
+/* Returns nonzero if GNU extensions are allowed. */
+
+static bool
+cp_parser_allow_gnu_extensions_p (cp_parser* parser)
+{
+ return parser->allow_gnu_extensions_p;
+}
+
+/* Objective-C++ Productions */
+
+
+/* Parse an Objective-C expression, which feeds into a primary-expression
+ above.
+
+ objc-expression:
+ objc-message-expression
+ objc-string-literal
+ objc-encode-expression
+ objc-protocol-expression
+ objc-selector-expression
+
+ Returns a tree representation of the expression. */
+
+static tree
+cp_parser_objc_expression (cp_parser* parser)
+{
+ /* Try to figure out what kind of declaration is present. */
+ cp_token *kwd = cp_lexer_peek_token (parser->lexer);
+
+ switch (kwd->type)
+ {
+ case CPP_OPEN_SQUARE:
+ return cp_parser_objc_message_expression (parser);
+
+ case CPP_OBJC_STRING:
+ kwd = cp_lexer_consume_token (parser->lexer);
+ return objc_build_string_object (kwd->u.value);
+
+ case CPP_KEYWORD:
+ switch (kwd->keyword)
+ {
+ case RID_AT_ENCODE:
+ return cp_parser_objc_encode_expression (parser);
+
+ case RID_AT_PROTOCOL:
+ return cp_parser_objc_protocol_expression (parser);
+
+ case RID_AT_SELECTOR:
+ return cp_parser_objc_selector_expression (parser);
+
+ default:
+ break;
+ }
+ default:
+ error_at (kwd->location,
+ "misplaced %<@%D%> Objective-C++ construct",
+ kwd->u.value);
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ }
+
+ return error_mark_node;
+}
+
+/* Parse an Objective-C message expression.
+
+ objc-message-expression:
+ [ objc-message-receiver objc-message-args ]
+
+ Returns a representation of an Objective-C message. */
+
+static tree
+cp_parser_objc_message_expression (cp_parser* parser)
+{
+ tree receiver, messageargs;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '['. */
+ receiver = cp_parser_objc_message_receiver (parser);
+ messageargs = cp_parser_objc_message_args (parser);
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+
+ return objc_build_message_expr (receiver, messageargs);
+}
+
+/* Parse an objc-message-receiver.
+
+ objc-message-receiver:
+ expression
+ simple-type-specifier
+
+ Returns a representation of the type or expression. */
+
+static tree
+cp_parser_objc_message_receiver (cp_parser* parser)
+{
+ tree rcv;
+
+ /* An Objective-C message receiver may be either (1) a type
+ or (2) an expression. */
+ cp_parser_parse_tentatively (parser);
+ rcv = cp_parser_expression (parser, false, NULL);
+
+ if (cp_parser_parse_definitely (parser))
+ return rcv;
+
+ rcv = cp_parser_simple_type_specifier (parser,
+ /*decl_specs=*/NULL,
+ CP_PARSER_FLAGS_NONE);
+
+ return objc_get_class_reference (rcv);
+}
+
+/* Parse the arguments and selectors comprising an Objective-C message.
+
+ objc-message-args:
+ objc-selector
+ objc-selector-args
+ objc-selector-args , objc-comma-args
+
+ objc-selector-args:
+ objc-selector [opt] : assignment-expression
+ objc-selector-args objc-selector [opt] : assignment-expression
+
+ objc-comma-args:
+ assignment-expression
+ objc-comma-args , assignment-expression
+
+ Returns a TREE_LIST, with TREE_PURPOSE containing a list of
+ selector arguments and TREE_VALUE containing a list of comma
+ arguments. */
+
+static tree
+cp_parser_objc_message_args (cp_parser* parser)
+{
+ tree sel_args = NULL_TREE, addl_args = NULL_TREE;
+ bool maybe_unary_selector_p = true;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
+ {
+ tree selector = NULL_TREE, arg;
+
+ if (token->type != CPP_COLON)
+ selector = cp_parser_objc_selector (parser);
+
+ /* Detect if we have a unary selector. */
+ if (maybe_unary_selector_p
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
+ return build_tree_list (selector, NULL_TREE);
+
+ maybe_unary_selector_p = false;
+ cp_parser_require (parser, CPP_COLON, RT_COLON);
+ arg = cp_parser_assignment_expression (parser, false, NULL);
+
+ sel_args
+ = chainon (sel_args,
+ build_tree_list (selector, arg));
+
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+
+ /* Handle non-selector arguments, if any. */
+ while (token->type == CPP_COMMA)
+ {
+ tree arg;
+
+ cp_lexer_consume_token (parser->lexer);
+ arg = cp_parser_assignment_expression (parser, false, NULL);
+
+ addl_args
+ = chainon (addl_args,
+ build_tree_list (NULL_TREE, arg));
+
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+
+ if (sel_args == NULL_TREE && addl_args == NULL_TREE)
+ {
+ cp_parser_error (parser, "objective-c++ message argument(s) are expected");
+ return build_tree_list (error_mark_node, error_mark_node);
+ }
+
+ return build_tree_list (sel_args, addl_args);
+}
+
+/* Parse an Objective-C encode expression.
+
+ objc-encode-expression:
+ @encode objc-typename
+
+ Returns an encoded representation of the type argument. */
+
+static tree
+cp_parser_objc_encode_expression (cp_parser* parser)
+{
+ tree type;
+ cp_token *token;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '@encode'. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ token = cp_lexer_peek_token (parser->lexer);
+ type = complete_type (cp_parser_type_id (parser));
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ if (!type)
+ {
+ error_at (token->location,
+ "%<@encode%> must specify a type as an argument");
+ return error_mark_node;
+ }
+
+ /* This happens if we find @encode(T) (where T is a template
+ typename or something dependent on a template typename) when
+ parsing a template. In that case, we can't compile it
+ immediately, but we rather create an AT_ENCODE_EXPR which will
+ need to be instantiated when the template is used.
+ */
+ if (dependent_type_p (type))
+ {
+ tree value = build_min (AT_ENCODE_EXPR, size_type_node, type);
+ TREE_READONLY (value) = 1;
+ return value;
+ }
+
+ return objc_build_encode_expr (type);
+}
+
+/* Parse an Objective-C @defs expression. */
+
+static tree
+cp_parser_objc_defs_expression (cp_parser *parser)
+{
+ tree name;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '@defs'. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ name = cp_parser_identifier (parser);
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ return objc_get_class_ivars (name);
+}
+
+/* Parse an Objective-C protocol expression.
+
+ objc-protocol-expression:
+ @protocol ( identifier )
+
+ Returns a representation of the protocol expression. */
+
+static tree
+cp_parser_objc_protocol_expression (cp_parser* parser)
+{
+ tree proto;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ proto = cp_parser_identifier (parser);
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ return objc_build_protocol_expr (proto);
+}
+
+/* Parse an Objective-C selector expression.
+
+ objc-selector-expression:
+ @selector ( objc-method-signature )
+
+ objc-method-signature:
+ objc-selector
+ objc-selector-seq
+
+ objc-selector-seq:
+ objc-selector :
+ objc-selector-seq objc-selector :
+
+ Returns a representation of the method selector. */
+
+static tree
+cp_parser_objc_selector_expression (cp_parser* parser)
+{
+ tree sel_seq = NULL_TREE;
+ bool maybe_unary_selector_p = true;
+ cp_token *token;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '@selector'. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ token = cp_lexer_peek_token (parser->lexer);
+
+ while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON
+ || token->type == CPP_SCOPE)
+ {
+ tree selector = NULL_TREE;
+
+ if (token->type != CPP_COLON
+ || token->type == CPP_SCOPE)
+ selector = cp_parser_objc_selector (parser);
+
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE))
+ {
+ /* Detect if we have a unary selector. */
+ if (maybe_unary_selector_p)
+ {
+ sel_seq = selector;
+ goto finish_selector;
+ }
+ else
+ {
+ cp_parser_error (parser, "expected %<:%>");
+ }
+ }
+ maybe_unary_selector_p = false;
+ token = cp_lexer_consume_token (parser->lexer);
+
+ if (token->type == CPP_SCOPE)
+ {
+ sel_seq
+ = chainon (sel_seq,
+ build_tree_list (selector, NULL_TREE));
+ sel_seq
+ = chainon (sel_seq,
+ build_tree_list (NULL_TREE, NULL_TREE));
+ }
+ else
+ sel_seq
+ = chainon (sel_seq,
+ build_tree_list (selector, NULL_TREE));
+
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+
+ finish_selector:
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ return objc_build_selector_expr (loc, sel_seq);
+}
+
+/* Parse a list of identifiers.
+
+ objc-identifier-list:
+ identifier
+ objc-identifier-list , identifier
+
+ Returns a TREE_LIST of identifier nodes. */
+
+static tree
+cp_parser_objc_identifier_list (cp_parser* parser)
+{
+ tree identifier;
+ tree list;
+ cp_token *sep;
+
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return error_mark_node;
+
+ list = build_tree_list (NULL_TREE, identifier);
+ sep = cp_lexer_peek_token (parser->lexer);
+
+ while (sep->type == CPP_COMMA)
+ {
+ cp_lexer_consume_token (parser->lexer); /* Eat ','. */
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return list;
+
+ list = chainon (list, build_tree_list (NULL_TREE,
+ identifier));
+ sep = cp_lexer_peek_token (parser->lexer);
+ }
+
+ return list;
+}
+
+/* Parse an Objective-C alias declaration.
+
+ objc-alias-declaration:
+ @compatibility_alias identifier identifier ;
+
+ This function registers the alias mapping with the Objective-C front end.
+ It returns nothing. */
+
+static void
+cp_parser_objc_alias_declaration (cp_parser* parser)
+{
+ tree alias, orig;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '@compatibility_alias'. */
+ alias = cp_parser_identifier (parser);
+ orig = cp_parser_identifier (parser);
+ objc_declare_alias (alias, orig);
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+}
+
+/* Parse an Objective-C class forward-declaration.
+
+ objc-class-declaration:
+ @class objc-identifier-list ;
+
+ The function registers the forward declarations with the Objective-C
+ front end. It returns nothing. */
+
+static void
+cp_parser_objc_class_declaration (cp_parser* parser)
+{
+ cp_lexer_consume_token (parser->lexer); /* Eat '@class'. */
+ while (true)
+ {
+ tree id;
+
+ id = cp_parser_identifier (parser);
+ if (id == error_mark_node)
+ break;
+
+ objc_declare_class (id);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ else
+ break;
+ }
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+}
+
+/* Parse a list of Objective-C protocol references.
+
+ objc-protocol-refs-opt:
+ objc-protocol-refs [opt]
+
+ objc-protocol-refs:
+ < objc-identifier-list >
+
+ Returns a TREE_LIST of identifiers, if any. */
+
+static tree
+cp_parser_objc_protocol_refs_opt (cp_parser* parser)
+{
+ tree protorefs = NULL_TREE;
+
+ if(cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+ {
+ cp_lexer_consume_token (parser->lexer); /* Eat '<'. */
+ protorefs = cp_parser_objc_identifier_list (parser);
+ cp_parser_require (parser, CPP_GREATER, RT_GREATER);
+ }
+
+ return protorefs;
+}
+
+/* Parse a Objective-C visibility specification. */
+
+static void
+cp_parser_objc_visibility_spec (cp_parser* parser)
+{
+ cp_token *vis = cp_lexer_peek_token (parser->lexer);
+
+ switch (vis->keyword)
+ {
+ case RID_AT_PRIVATE:
+ objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
+ break;
+ case RID_AT_PROTECTED:
+ objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
+ break;
+ case RID_AT_PUBLIC:
+ objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
+ break;
+ case RID_AT_PACKAGE:
+ objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
+ break;
+ default:
+ return;
+ }
+
+ /* Eat '@private'/'@protected'/'@public'. */
+ cp_lexer_consume_token (parser->lexer);
+}
+
+/* Parse an Objective-C method type. Return 'true' if it is a class
+ (+) method, and 'false' if it is an instance (-) method. */
+
+static inline bool
+cp_parser_objc_method_type (cp_parser* parser)
+{
+ if (cp_lexer_consume_token (parser->lexer)->type == CPP_PLUS)
+ return true;
+ else
+ return false;
+}
+
+/* Parse an Objective-C protocol qualifier. */
+
+static tree
+cp_parser_objc_protocol_qualifiers (cp_parser* parser)
+{
+ tree quals = NULL_TREE, node;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ node = token->u.value;
+
+ while (node && identifier_p (node)
+ && (node == ridpointers [(int) RID_IN]
+ || node == ridpointers [(int) RID_OUT]
+ || node == ridpointers [(int) RID_INOUT]
+ || node == ridpointers [(int) RID_BYCOPY]
+ || node == ridpointers [(int) RID_BYREF]
+ || node == ridpointers [(int) RID_ONEWAY]))
+ {
+ quals = tree_cons (NULL_TREE, node, quals);
+ cp_lexer_consume_token (parser->lexer);
+ token = cp_lexer_peek_token (parser->lexer);
+ node = token->u.value;
+ }
+
+ return quals;
+}
+
+/* Parse an Objective-C typename. */
+
+static tree
+cp_parser_objc_typename (cp_parser* parser)
+{
+ tree type_name = NULL_TREE;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ tree proto_quals, cp_type = NULL_TREE;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '('. */
+ proto_quals = cp_parser_objc_protocol_qualifiers (parser);
+
+ /* An ObjC type name may consist of just protocol qualifiers, in which
+ case the type shall default to 'id'. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
+ {
+ cp_type = cp_parser_type_id (parser);
+
+ /* If the type could not be parsed, an error has already
+ been produced. For error recovery, behave as if it had
+ not been specified, which will use the default type
+ 'id'. */
+ if (cp_type == error_mark_node)
+ {
+ cp_type = NULL_TREE;
+ /* We need to skip to the closing parenthesis as
+ cp_parser_type_id() does not seem to do it for
+ us. */
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/false);
+ }
+ }
+
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ type_name = build_tree_list (proto_quals, cp_type);
+ }
+
+ return type_name;
+}
+
+/* Check to see if TYPE refers to an Objective-C selector name. */
+
+static bool
+cp_parser_objc_selector_p (enum cpp_ttype type)
+{
+ return (type == CPP_NAME || type == CPP_KEYWORD
+ || type == CPP_AND_AND || type == CPP_AND_EQ || type == CPP_AND
+ || type == CPP_OR || type == CPP_COMPL || type == CPP_NOT
+ || type == CPP_NOT_EQ || type == CPP_OR_OR || type == CPP_OR_EQ
+ || type == CPP_XOR || type == CPP_XOR_EQ);
+}
+
+/* Parse an Objective-C selector. */
+
+static tree
+cp_parser_objc_selector (cp_parser* parser)
+{
+ cp_token *token = cp_lexer_consume_token (parser->lexer);
+
+ if (!cp_parser_objc_selector_p (token->type))
+ {
+ error_at (token->location, "invalid Objective-C++ selector name");
+ return error_mark_node;
+ }
+
+ /* C++ operator names are allowed to appear in ObjC selectors. */
+ switch (token->type)
+ {
+ case CPP_AND_AND: return get_identifier ("and");
+ case CPP_AND_EQ: return get_identifier ("and_eq");
+ case CPP_AND: return get_identifier ("bitand");
+ case CPP_OR: return get_identifier ("bitor");
+ case CPP_COMPL: return get_identifier ("compl");
+ case CPP_NOT: return get_identifier ("not");
+ case CPP_NOT_EQ: return get_identifier ("not_eq");
+ case CPP_OR_OR: return get_identifier ("or");
+ case CPP_OR_EQ: return get_identifier ("or_eq");
+ case CPP_XOR: return get_identifier ("xor");
+ case CPP_XOR_EQ: return get_identifier ("xor_eq");
+ default: return token->u.value;
+ }
+}
+
+/* Parse an Objective-C params list. */
+
+static tree
+cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes)
+{
+ tree params = NULL_TREE;
+ bool maybe_unary_selector_p = true;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
+ {
+ tree selector = NULL_TREE, type_name, identifier;
+ tree parm_attr = NULL_TREE;
+
+ if (token->keyword == RID_ATTRIBUTE)
+ break;
+
+ if (token->type != CPP_COLON)
+ selector = cp_parser_objc_selector (parser);
+
+ /* Detect if we have a unary selector. */
+ if (maybe_unary_selector_p
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
+ {
+ params = selector; /* Might be followed by attributes. */
+ break;
+ }
+
+ maybe_unary_selector_p = false;
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+ {
+ /* Something went quite wrong. There should be a colon
+ here, but there is not. Stop parsing parameters. */
+ break;
+ }
+ type_name = cp_parser_objc_typename (parser);
+ /* New ObjC allows attributes on parameters too. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
+ parm_attr = cp_parser_attributes_opt (parser);
+ identifier = cp_parser_identifier (parser);
+
+ params
+ = chainon (params,
+ objc_build_keyword_decl (selector,
+ type_name,
+ identifier,
+ parm_attr));
+
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+
+ if (params == NULL_TREE)
+ {
+ cp_parser_error (parser, "objective-c++ method declaration is expected");
+ return error_mark_node;
+ }
+
+ /* We allow tail attributes for the method. */
+ if (token->keyword == RID_ATTRIBUTE)
+ {
+ *attributes = cp_parser_attributes_opt (parser);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
+ || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ return params;
+ cp_parser_error (parser,
+ "method attributes must be specified at the end");
+ return error_mark_node;
+ }
+
+ if (params == NULL_TREE)
+ {
+ cp_parser_error (parser, "objective-c++ method declaration is expected");
+ return error_mark_node;
+ }
+ return params;
+}
+
+/* Parse the non-keyword Objective-C params. */
+
+static tree
+cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp,
+ tree* attributes)
+{
+ tree params = make_node (TREE_LIST);
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ *ellipsisp = false; /* Initially, assume no ellipsis. */
+
+ while (token->type == CPP_COMMA)
+ {
+ cp_parameter_declarator *parmdecl;
+ tree parm;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat ','. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ if (token->type == CPP_ELLIPSIS)
+ {
+ cp_lexer_consume_token (parser->lexer); /* Eat '...'. */
+ *ellipsisp = true;
+ token = cp_lexer_peek_token (parser->lexer);
+ break;
+ }
+
+ /* TODO: parse attributes for tail parameters. */
+ parmdecl = cp_parser_parameter_declaration (parser, false, NULL);
+ parm = grokdeclarator (parmdecl->declarator,
+ &parmdecl->decl_specifiers,
+ PARM, /*initialized=*/0,
+ /*attrlist=*/NULL);
+
+ chainon (params, build_tree_list (NULL_TREE, parm));
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+
+ /* We allow tail attributes for the method. */
+ if (token->keyword == RID_ATTRIBUTE)
+ {
+ if (*attributes == NULL_TREE)
+ {
+ *attributes = cp_parser_attributes_opt (parser);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
+ || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ return params;
+ }
+ else
+ /* We have an error, but parse the attributes, so that we can
+ carry on. */
+ *attributes = cp_parser_attributes_opt (parser);
+
+ cp_parser_error (parser,
+ "method attributes must be specified at the end");
+ return error_mark_node;
+ }
+
+ return params;
+}
+
+/* Parse a linkage specification, a pragma, an extra semicolon or a block. */
+
+static void
+cp_parser_objc_interstitial_code (cp_parser* parser)
+{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* If the next token is `extern' and the following token is a string
+ literal, then we have a linkage specification. */
+ if (token->keyword == RID_EXTERN
+ && cp_parser_is_pure_string_literal
+ (cp_lexer_peek_nth_token (parser->lexer, 2)))
+ cp_parser_linkage_specification (parser);
+ /* Handle #pragma, if any. */
+ else if (token->type == CPP_PRAGMA)
+ cp_parser_pragma (parser, pragma_objc_icode);
+ /* Allow stray semicolons. */
+ else if (token->type == CPP_SEMICOLON)
+ cp_lexer_consume_token (parser->lexer);
+ /* Mark methods as optional or required, when building protocols. */
+ else if (token->keyword == RID_AT_OPTIONAL)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ objc_set_method_opt (true);
+ }
+ else if (token->keyword == RID_AT_REQUIRED)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ objc_set_method_opt (false);
+ }
+ else if (token->keyword == RID_NAMESPACE)
+ cp_parser_namespace_definition (parser);
+ /* Other stray characters must generate errors. */
+ else if (token->type == CPP_OPEN_BRACE || token->type == CPP_CLOSE_BRACE)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ error ("stray %qs between Objective-C++ methods",
+ token->type == CPP_OPEN_BRACE ? "{" : "}");
+ }
+ /* Finally, try to parse a block-declaration, or a function-definition. */
+ else
+ cp_parser_block_declaration (parser, /*statement_p=*/false);
+}
+
+/* Parse a method signature. */
+
+static tree
+cp_parser_objc_method_signature (cp_parser* parser, tree* attributes)
+{
+ tree rettype, kwdparms, optparms;
+ bool ellipsis = false;
+ bool is_class_method;
+
+ is_class_method = cp_parser_objc_method_type (parser);
+ rettype = cp_parser_objc_typename (parser);
+ *attributes = NULL_TREE;
+ kwdparms = cp_parser_objc_method_keyword_params (parser, attributes);
+ if (kwdparms == error_mark_node)
+ return error_mark_node;
+ optparms = cp_parser_objc_method_tail_params_opt (parser, &ellipsis, attributes);
+ if (optparms == error_mark_node)
+ return error_mark_node;
+
+ return objc_build_method_signature (is_class_method, rettype, kwdparms, optparms, ellipsis);
+}
+
+static bool
+cp_parser_objc_method_maybe_bad_prefix_attributes (cp_parser* parser)
+{
+ tree tattr;
+ cp_lexer_save_tokens (parser->lexer);
+ tattr = cp_parser_attributes_opt (parser);
+ gcc_assert (tattr) ;
+
+ /* If the attributes are followed by a method introducer, this is not allowed.
+ Dump the attributes and flag the situation. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_PLUS)
+ || cp_lexer_next_token_is (parser->lexer, CPP_MINUS))
+ return true;
+
+ /* Otherwise, the attributes introduce some interstitial code, possibly so
+ rewind to allow that check. */
+ cp_lexer_rollback_tokens (parser->lexer);
+ return false;
+}
+
+/* Parse an Objective-C method prototype list. */
+
+static void
+cp_parser_objc_method_prototype_list (cp_parser* parser)
+{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ while (token->keyword != RID_AT_END && token->type != CPP_EOF)
+ {
+ if (token->type == CPP_PLUS || token->type == CPP_MINUS)
+ {
+ tree attributes, sig;
+ bool is_class_method;
+ if (token->type == CPP_PLUS)
+ is_class_method = true;
+ else
+ is_class_method = false;
+ sig = cp_parser_objc_method_signature (parser, &attributes);
+ if (sig == error_mark_node)
+ {
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ token = cp_lexer_peek_token (parser->lexer);
+ continue;
+ }
+ objc_add_method_declaration (is_class_method, sig, attributes);
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+ }
+ else if (token->keyword == RID_AT_PROPERTY)
+ cp_parser_objc_at_property_declaration (parser);
+ else if (token->keyword == RID_ATTRIBUTE
+ && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
+ warning_at (cp_lexer_peek_token (parser->lexer)->location,
+ OPT_Wattributes,
+ "prefix attributes are ignored for methods");
+ else
+ /* Allow for interspersed non-ObjC++ code. */
+ cp_parser_objc_interstitial_code (parser);
+
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+
+ if (token->type != CPP_EOF)
+ cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */
+ else
+ cp_parser_error (parser, "expected %<@end%>");
+
+ objc_finish_interface ();
+}
+
+/* Parse an Objective-C method definition list. */
+
+static void
+cp_parser_objc_method_definition_list (cp_parser* parser)
+{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ while (token->keyword != RID_AT_END && token->type != CPP_EOF)
+ {
+ tree meth;
+
+ if (token->type == CPP_PLUS || token->type == CPP_MINUS)
+ {
+ cp_token *ptk;
+ tree sig, attribute;
+ bool is_class_method;
+ if (token->type == CPP_PLUS)
+ is_class_method = true;
+ else
+ is_class_method = false;
+ push_deferring_access_checks (dk_deferred);
+ sig = cp_parser_objc_method_signature (parser, &attribute);
+ if (sig == error_mark_node)
+ {
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ token = cp_lexer_peek_token (parser->lexer);
+ continue;
+ }
+ objc_start_method_definition (is_class_method, sig, attribute,
+ NULL_TREE);
+
+ /* For historical reasons, we accept an optional semicolon. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+
+ ptk = cp_lexer_peek_token (parser->lexer);
+ if (!(ptk->type == CPP_PLUS || ptk->type == CPP_MINUS
+ || ptk->type == CPP_EOF || ptk->keyword == RID_AT_END))
+ {
+ perform_deferred_access_checks (tf_warning_or_error);
+ stop_deferring_access_checks ();
+ meth = cp_parser_function_definition_after_declarator (parser,
+ false);
+ pop_deferring_access_checks ();
+ objc_finish_method_definition (meth);
+ }
+ }
+ /* The following case will be removed once @synthesize is
+ completely implemented. */
+ else if (token->keyword == RID_AT_PROPERTY)
+ cp_parser_objc_at_property_declaration (parser);
+ else if (token->keyword == RID_AT_SYNTHESIZE)
+ cp_parser_objc_at_synthesize_declaration (parser);
+ else if (token->keyword == RID_AT_DYNAMIC)
+ cp_parser_objc_at_dynamic_declaration (parser);
+ else if (token->keyword == RID_ATTRIBUTE
+ && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
+ warning_at (token->location, OPT_Wattributes,
+ "prefix attributes are ignored for methods");
+ else
+ /* Allow for interspersed non-ObjC++ code. */
+ cp_parser_objc_interstitial_code (parser);
+
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+
+ if (token->type != CPP_EOF)
+ cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */
+ else
+ cp_parser_error (parser, "expected %<@end%>");
+
+ objc_finish_implementation ();
+}
+
+/* Parse Objective-C ivars. */
+
+static void
+cp_parser_objc_class_ivars (cp_parser* parser)
+{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ if (token->type != CPP_OPEN_BRACE)
+ return; /* No ivars specified. */
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '{'. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ while (token->type != CPP_CLOSE_BRACE
+ && token->keyword != RID_AT_END && token->type != CPP_EOF)
+ {
+ cp_decl_specifier_seq declspecs;
+ int decl_class_or_enum_p;
+ tree prefix_attributes;
+
+ cp_parser_objc_visibility_spec (parser);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
+ break;
+
+ cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_OPTIONAL,
+ &declspecs,
+ &decl_class_or_enum_p);
+
+ /* auto, register, static, extern, mutable. */
+ if (declspecs.storage_class != sc_none)
+ {
+ cp_parser_error (parser, "invalid type for instance variable");
+ declspecs.storage_class = sc_none;
+ }
+
+ /* thread_local. */
+ if (decl_spec_seq_has_spec_p (&declspecs, ds_thread))
+ {
+ cp_parser_error (parser, "invalid type for instance variable");
+ declspecs.locations[ds_thread] = 0;
+ }
+
+ /* typedef. */
+ if (decl_spec_seq_has_spec_p (&declspecs, ds_typedef))
+ {
+ cp_parser_error (parser, "invalid type for instance variable");
+ declspecs.locations[ds_typedef] = 0;
+ }
+
+ prefix_attributes = declspecs.attributes;
+ declspecs.attributes = NULL_TREE;
+
+ /* Keep going until we hit the `;' at the end of the
+ declaration. */
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ tree width = NULL_TREE, attributes, first_attribute, decl;
+ cp_declarator *declarator = NULL;
+ int ctor_dtor_or_conv_p;
+
+ /* Check for a (possibly unnamed) bitfield declaration. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_COLON)
+ goto eat_colon;
+
+ if (token->type == CPP_NAME
+ && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ == CPP_COLON))
+ {
+ /* Get the name of the bitfield. */
+ declarator = make_id_declarator (NULL_TREE,
+ cp_parser_identifier (parser),
+ sfk_none);
+
+ eat_colon:
+ cp_lexer_consume_token (parser->lexer); /* Eat ':'. */
+ /* Get the width of the bitfield. */
+ width
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant=*/false,
+ NULL);
+ }
+ else
+ {
+ /* Parse the declarator. */
+ declarator
+ = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+ &ctor_dtor_or_conv_p,
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
+ }
+
+ /* Look for attributes that apply to the ivar. */
+ attributes = cp_parser_attributes_opt (parser);
+ /* Remember which attributes are prefix attributes and
+ which are not. */
+ first_attribute = attributes;
+ /* Combine the attributes. */
+ attributes = chainon (prefix_attributes, attributes);
+
+ if (width)
+ /* Create the bitfield declaration. */
+ decl = grokbitfield (declarator, &declspecs,
+ width,
+ attributes);
+ else
+ decl = grokfield (declarator, &declspecs,
+ NULL_TREE, /*init_const_expr_p=*/false,
+ NULL_TREE, attributes);
+
+ /* Add the instance variable. */
+ if (decl != error_mark_node && decl != NULL_TREE)
+ objc_add_instance_variable (decl);
+
+ /* Reset PREFIX_ATTRIBUTES. */
+ while (attributes && TREE_CHAIN (attributes) != first_attribute)
+ attributes = TREE_CHAIN (attributes);
+ if (attributes)
+ TREE_CHAIN (attributes) = NULL_TREE;
+
+ token = cp_lexer_peek_token (parser->lexer);
+
+ if (token->type == CPP_COMMA)
+ {
+ cp_lexer_consume_token (parser->lexer); /* Eat ','. */
+ continue;
+ }
+ break;
+ }
+
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+ token = cp_lexer_peek_token (parser->lexer);
+ }
+
+ if (token->keyword == RID_AT_END)
+ cp_parser_error (parser, "expected %<}%>");
+
+ /* Do not consume the RID_AT_END, so it will be read again as terminating
+ the @interface of @implementation. */
+ if (token->keyword != RID_AT_END && token->type != CPP_EOF)
+ cp_lexer_consume_token (parser->lexer); /* Eat '}'. */
+
+ /* For historical reasons, we accept an optional semicolon. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+}
+
+/* Parse an Objective-C protocol declaration. */
+
+static void
+cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes)
+{
+ tree proto, protorefs;
+ cp_token *tok;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
+ {
+ tok = cp_lexer_peek_token (parser->lexer);
+ error_at (tok->location, "identifier expected after %<@protocol%>");
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+ return;
+ }
+
+ /* See if we have a forward declaration or a definition. */
+ tok = cp_lexer_peek_nth_token (parser->lexer, 2);
+
+ /* Try a forward declaration first. */
+ if (tok->type == CPP_COMMA || tok->type == CPP_SEMICOLON)
+ {
+ while (true)
+ {
+ tree id;
+
+ id = cp_parser_identifier (parser);
+ if (id == error_mark_node)
+ break;
+
+ objc_declare_protocol (id, attributes);
+
+ if(cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ else
+ break;
+ }
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+ }
+
+ /* Ok, we got a full-fledged definition (or at least should). */
+ else
+ {
+ proto = cp_parser_identifier (parser);
+ protorefs = cp_parser_objc_protocol_refs_opt (parser);
+ objc_start_protocol (proto, protorefs, attributes);
+ cp_parser_objc_method_prototype_list (parser);
+ }
+}
+
+/* Parse an Objective-C superclass or category. */
+
+static void
+cp_parser_objc_superclass_or_category (cp_parser *parser,
+ bool iface_p,
+ tree *super,
+ tree *categ, bool *is_class_extension)
+{
+ cp_token *next = cp_lexer_peek_token (parser->lexer);
+
+ *super = *categ = NULL_TREE;
+ *is_class_extension = false;
+ if (next->type == CPP_COLON)
+ {
+ cp_lexer_consume_token (parser->lexer); /* Eat ':'. */
+ *super = cp_parser_identifier (parser);
+ }
+ else if (next->type == CPP_OPEN_PAREN)
+ {
+ cp_lexer_consume_token (parser->lexer); /* Eat '('. */
+
+ /* If there is no category name, and this is an @interface, we
+ have a class extension. */
+ if (iface_p && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
+ {
+ *categ = NULL_TREE;
+ *is_class_extension = true;
+ }
+ else
+ *categ = cp_parser_identifier (parser);
+
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ }
+}
+
+/* Parse an Objective-C class interface. */
+
+static void
+cp_parser_objc_class_interface (cp_parser* parser, tree attributes)
+{
+ tree name, super, categ, protos;
+ bool is_class_extension;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '@interface'. */
+ name = cp_parser_identifier (parser);
+ if (name == error_mark_node)
+ {
+ /* It's hard to recover because even if valid @interface stuff
+ is to follow, we can't compile it (or validate it) if we
+ don't even know which class it refers to. Let's assume this
+ was a stray '@interface' token in the stream and skip it.
+ */
+ return;
+ }
+ cp_parser_objc_superclass_or_category (parser, true, &super, &categ,
+ &is_class_extension);
+ protos = cp_parser_objc_protocol_refs_opt (parser);
+
+ /* We have either a class or a category on our hands. */
+ if (categ || is_class_extension)
+ objc_start_category_interface (name, categ, protos, attributes);
+ else
+ {
+ objc_start_class_interface (name, super, protos, attributes);
+ /* Handle instance variable declarations, if any. */
+ cp_parser_objc_class_ivars (parser);
+ objc_continue_interface ();
+ }
+
+ cp_parser_objc_method_prototype_list (parser);
+}
+
+/* Parse an Objective-C class implementation. */
+
+static void
+cp_parser_objc_class_implementation (cp_parser* parser)
+{
+ tree name, super, categ;
+ bool is_class_extension;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '@implementation'. */
+ name = cp_parser_identifier (parser);
+ if (name == error_mark_node)
+ {
+ /* It's hard to recover because even if valid @implementation
+ stuff is to follow, we can't compile it (or validate it) if
+ we don't even know which class it refers to. Let's assume
+ this was a stray '@implementation' token in the stream and
+ skip it.
+ */
+ return;
+ }
+ cp_parser_objc_superclass_or_category (parser, false, &super, &categ,
+ &is_class_extension);
+
+ /* We have either a class or a category on our hands. */
+ if (categ)
+ objc_start_category_implementation (name, categ);
+ else
+ {
+ objc_start_class_implementation (name, super);
+ /* Handle instance variable declarations, if any. */
+ cp_parser_objc_class_ivars (parser);
+ objc_continue_implementation ();
+ }
+
+ cp_parser_objc_method_definition_list (parser);
+}
+
+/* Consume the @end token and finish off the implementation. */
+
+static void
+cp_parser_objc_end_implementation (cp_parser* parser)
+{
+ cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */
+ objc_finish_implementation ();
+}
+
+/* Parse an Objective-C declaration. */
+
+static void
+cp_parser_objc_declaration (cp_parser* parser, tree attributes)
+{
+ /* Try to figure out what kind of declaration is present. */
+ cp_token *kwd = cp_lexer_peek_token (parser->lexer);
+
+ if (attributes)
+ switch (kwd->keyword)
+ {
+ case RID_AT_ALIAS:
+ case RID_AT_CLASS:
+ case RID_AT_END:
+ error_at (kwd->location, "attributes may not be specified before"
+ " the %<@%D%> Objective-C++ keyword",
+ kwd->u.value);
+ attributes = NULL;
+ break;
+ case RID_AT_IMPLEMENTATION:
+ warning_at (kwd->location, OPT_Wattributes,
+ "prefix attributes are ignored before %<@%D%>",
+ kwd->u.value);
+ attributes = NULL;
+ default:
+ break;
+ }
+
+ switch (kwd->keyword)
+ {
+ case RID_AT_ALIAS:
+ cp_parser_objc_alias_declaration (parser);
+ break;
+ case RID_AT_CLASS:
+ cp_parser_objc_class_declaration (parser);
+ break;
+ case RID_AT_PROTOCOL:
+ cp_parser_objc_protocol_declaration (parser, attributes);
+ break;
+ case RID_AT_INTERFACE:
+ cp_parser_objc_class_interface (parser, attributes);
+ break;
+ case RID_AT_IMPLEMENTATION:
+ cp_parser_objc_class_implementation (parser);
+ break;
+ case RID_AT_END:
+ cp_parser_objc_end_implementation (parser);
+ break;
+ default:
+ error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct",
+ kwd->u.value);
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ }
+}
+
+/* Parse an Objective-C try-catch-finally statement.
+
+ objc-try-catch-finally-stmt:
+ @try compound-statement objc-catch-clause-seq [opt]
+ objc-finally-clause [opt]
+
+ objc-catch-clause-seq:
+ objc-catch-clause objc-catch-clause-seq [opt]
+
+ objc-catch-clause:
+ @catch ( objc-exception-declaration ) compound-statement
+
+ objc-finally-clause:
+ @finally compound-statement
+
+ objc-exception-declaration:
+ parameter-declaration
+ '...'
+
+ where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
+
+ Returns NULL_TREE.
+
+ PS: This function is identical to c_parser_objc_try_catch_finally_statement
+ for C. Keep them in sync. */
+
+static tree
+cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
+{
+ location_t location;
+ tree stmt;
+
+ cp_parser_require_keyword (parser, RID_AT_TRY, RT_AT_TRY);
+ location = cp_lexer_peek_token (parser->lexer)->location;
+ objc_maybe_warn_exceptions (location);
+ /* NB: The @try block needs to be wrapped in its own STATEMENT_LIST
+ node, lest it get absorbed into the surrounding block. */
+ stmt = push_stmt_list ();
+ cp_parser_compound_statement (parser, NULL, false, false);
+ objc_begin_try_stmt (location, pop_stmt_list (stmt));
+
+ while (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_CATCH))
+ {
+ cp_parameter_declarator *parm;
+ tree parameter_declaration = error_mark_node;
+ bool seen_open_paren = false;
+
+ cp_lexer_consume_token (parser->lexer);
+ if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ seen_open_paren = true;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ /* We have "@catch (...)" (where the '...' are literally
+ what is in the code). Skip the '...'.
+ parameter_declaration is set to NULL_TREE, and
+ objc_being_catch_clauses() knows that that means
+ '...'. */
+ cp_lexer_consume_token (parser->lexer);
+ parameter_declaration = NULL_TREE;
+ }
+ else
+ {
+ /* We have "@catch (NSException *exception)" or something
+ like that. Parse the parameter declaration. */
+ parm = cp_parser_parameter_declaration (parser, false, NULL);
+ if (parm == NULL)
+ parameter_declaration = error_mark_node;
+ else
+ parameter_declaration = grokdeclarator (parm->declarator,
+ &parm->decl_specifiers,
+ PARM, /*initialized=*/0,
+ /*attrlist=*/NULL);
+ }
+ if (seen_open_paren)
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ else
+ {
+ /* If there was no open parenthesis, we are recovering from
+ an error, and we are trying to figure out what mistake
+ the user has made. */
+
+ /* If there is an immediate closing parenthesis, the user
+ probably forgot the opening one (ie, they typed "@catch
+ NSException *e)". Parse the closing parenthesis and keep
+ going. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
+ cp_lexer_consume_token (parser->lexer);
+
+ /* If these is no immediate closing parenthesis, the user
+ probably doesn't know that parenthesis are required at
+ all (ie, they typed "@catch NSException *e"). So, just
+ forget about the closing parenthesis and keep going. */
+ }
+ objc_begin_catch_clause (parameter_declaration);
+ cp_parser_compound_statement (parser, NULL, false, false);
+ objc_finish_catch_clause ();
+ }
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_FINALLY))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ location = cp_lexer_peek_token (parser->lexer)->location;
+ /* NB: The @finally block needs to be wrapped in its own STATEMENT_LIST
+ node, lest it get absorbed into the surrounding block. */
+ stmt = push_stmt_list ();
+ cp_parser_compound_statement (parser, NULL, false, false);
+ objc_build_finally_clause (location, pop_stmt_list (stmt));
+ }
+
+ return objc_finish_try_stmt ();
+}
+
+/* Parse an Objective-C synchronized statement.
+
+ objc-synchronized-stmt:
+ @synchronized ( expression ) compound-statement
+
+ Returns NULL_TREE. */
+
+static tree
+cp_parser_objc_synchronized_statement (cp_parser *parser)
+{
+ location_t location;
+ tree lock, stmt;
+
+ cp_parser_require_keyword (parser, RID_AT_SYNCHRONIZED, RT_AT_SYNCHRONIZED);
+
+ location = cp_lexer_peek_token (parser->lexer)->location;
+ objc_maybe_warn_exceptions (location);
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ lock = cp_parser_expression (parser, false, NULL);
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST
+ node, lest it get absorbed into the surrounding block. */
+ stmt = push_stmt_list ();
+ cp_parser_compound_statement (parser, NULL, false, false);
+
+ return objc_build_synchronized (location, lock, pop_stmt_list (stmt));
+}
+
+/* Parse an Objective-C throw statement.
+
+ objc-throw-stmt:
+ @throw assignment-expression [opt] ;
+
+ Returns a constructed '@throw' statement. */
+
+static tree
+cp_parser_objc_throw_statement (cp_parser *parser)
+{
+ tree expr = NULL_TREE;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ cp_parser_require_keyword (parser, RID_AT_THROW, RT_AT_THROW);
+
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+
+ return objc_build_throw_stmt (loc, expr);
+}
+
+/* Parse an Objective-C statement. */
+
+static tree
+cp_parser_objc_statement (cp_parser * parser)
+{
+ /* Try to figure out what kind of declaration is present. */
+ cp_token *kwd = cp_lexer_peek_token (parser->lexer);
+
+ switch (kwd->keyword)
+ {
+ case RID_AT_TRY:
+ return cp_parser_objc_try_catch_finally_statement (parser);
+ case RID_AT_SYNCHRONIZED:
+ return cp_parser_objc_synchronized_statement (parser);
+ case RID_AT_THROW:
+ return cp_parser_objc_throw_statement (parser);
+ default:
+ error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct",
+ kwd->u.value);
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ }
+
+ return error_mark_node;
+}
+
+/* If we are compiling ObjC++ and we see an __attribute__ we neeed to
+ look ahead to see if an objc keyword follows the attributes. This
+ is to detect the use of prefix attributes on ObjC @interface and
+ @protocol. */
+
+static bool
+cp_parser_objc_valid_prefix_attributes (cp_parser* parser, tree *attrib)
+{
+ cp_lexer_save_tokens (parser->lexer);
+ *attrib = cp_parser_attributes_opt (parser);
+ gcc_assert (*attrib);
+ if (OBJC_IS_AT_KEYWORD (cp_lexer_peek_token (parser->lexer)->keyword))
+ {
+ cp_lexer_commit_tokens (parser->lexer);
+ return true;
+ }
+ cp_lexer_rollback_tokens (parser->lexer);
+ return false;
+}
+
+/* This routine is a minimal replacement for
+ c_parser_struct_declaration () used when parsing the list of
+ types/names or ObjC++ properties. For example, when parsing the
+ code
+
+ @property (readonly) int a, b, c;
+
+ this function is responsible for parsing "int a, int b, int c" and
+ returning the declarations as CHAIN of DECLs.
+
+ TODO: Share this code with cp_parser_objc_class_ivars. It's very
+ similar parsing. */
+static tree
+cp_parser_objc_struct_declaration (cp_parser *parser)
+{
+ tree decls = NULL_TREE;
+ cp_decl_specifier_seq declspecs;
+ int decl_class_or_enum_p;
+ tree prefix_attributes;
+
+ cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_NONE,
+ &declspecs,
+ &decl_class_or_enum_p);
+
+ if (declspecs.type == error_mark_node)
+ return error_mark_node;
+
+ /* auto, register, static, extern, mutable. */
+ if (declspecs.storage_class != sc_none)
+ {
+ cp_parser_error (parser, "invalid type for property");
+ declspecs.storage_class = sc_none;
+ }
+
+ /* thread_local. */
+ if (decl_spec_seq_has_spec_p (&declspecs, ds_thread))
+ {
+ cp_parser_error (parser, "invalid type for property");
+ declspecs.locations[ds_thread] = 0;
+ }
+
+ /* typedef. */
+ if (decl_spec_seq_has_spec_p (&declspecs, ds_typedef))
+ {
+ cp_parser_error (parser, "invalid type for property");
+ declspecs.locations[ds_typedef] = 0;
+ }
+
+ prefix_attributes = declspecs.attributes;
+ declspecs.attributes = NULL_TREE;
+
+ /* Keep going until we hit the `;' at the end of the declaration. */
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ tree attributes, first_attribute, decl;
+ cp_declarator *declarator;
+ cp_token *token;
+
+ /* Parse the declarator. */
+ declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+ NULL, NULL, false);
+
+ /* Look for attributes that apply to the ivar. */
+ attributes = cp_parser_attributes_opt (parser);
+ /* Remember which attributes are prefix attributes and
+ which are not. */
+ first_attribute = attributes;
+ /* Combine the attributes. */
+ attributes = chainon (prefix_attributes, attributes);
+
+ decl = grokfield (declarator, &declspecs,
+ NULL_TREE, /*init_const_expr_p=*/false,
+ NULL_TREE, attributes);
+
+ if (decl == error_mark_node || decl == NULL_TREE)
+ return error_mark_node;
+
+ /* Reset PREFIX_ATTRIBUTES. */
+ while (attributes && TREE_CHAIN (attributes) != first_attribute)
+ attributes = TREE_CHAIN (attributes);
+ if (attributes)
+ TREE_CHAIN (attributes) = NULL_TREE;
+
+ DECL_CHAIN (decl) = decls;
+ decls = decl;
+
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_COMMA)
+ {
+ cp_lexer_consume_token (parser->lexer); /* Eat ','. */
+ continue;
+ }
+ else
+ break;
+ }
+ return decls;
+}
+
+/* Parse an Objective-C @property declaration. The syntax is:
+
+ objc-property-declaration:
+ '@property' objc-property-attributes[opt] struct-declaration ;
+
+ objc-property-attributes:
+ '(' objc-property-attribute-list ')'
+
+ objc-property-attribute-list:
+ objc-property-attribute
+ objc-property-attribute-list, objc-property-attribute
+
+ objc-property-attribute
+ 'getter' = identifier
+ 'setter' = identifier
+ 'readonly'
+ 'readwrite'
+ 'assign'
+ 'retain'
+ 'copy'
+ 'nonatomic'
+
+ For example:
+ @property NSString *name;
+ @property (readonly) id object;
+ @property (retain, nonatomic, getter=getTheName) id name;
+ @property int a, b, c;
+
+ PS: This function is identical to
+ c_parser_objc_at_property_declaration for C. Keep them in sync. */
+static void
+cp_parser_objc_at_property_declaration (cp_parser *parser)
+{
+ /* The following variables hold the attributes of the properties as
+ parsed. They are 'false' or 'NULL_TREE' if the attribute was not
+ seen. When we see an attribute, we set them to 'true' (if they
+ are boolean properties) or to the identifier (if they have an
+ argument, ie, for getter and setter). Note that here we only
+ parse the list of attributes, check the syntax and accumulate the
+ attributes that we find. objc_add_property_declaration() will
+ then process the information. */
+ bool property_assign = false;
+ bool property_copy = false;
+ tree property_getter_ident = NULL_TREE;
+ bool property_nonatomic = false;
+ bool property_readonly = false;
+ bool property_readwrite = false;
+ bool property_retain = false;
+ tree property_setter_ident = NULL_TREE;
+
+ /* 'properties' is the list of properties that we read. Usually a
+ single one, but maybe more (eg, in "@property int a, b, c;" there
+ are three). */
+ tree properties;
+ location_t loc;
+
+ loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '@property'. */
+
+ /* Parse the optional attribute list... */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ /* Eat the '('. */
+ cp_lexer_consume_token (parser->lexer);
+
+ while (true)
+ {
+ bool syntax_error = false;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ enum rid keyword;
+
+ if (token->type != CPP_NAME)
+ {
+ cp_parser_error (parser, "expected identifier");
+ break;
+ }
+ keyword = C_RID_CODE (token->u.value);
+ cp_lexer_consume_token (parser->lexer);
+ switch (keyword)
+ {
+ case RID_ASSIGN: property_assign = true; break;
+ case RID_COPY: property_copy = true; break;
+ case RID_NONATOMIC: property_nonatomic = true; break;
+ case RID_READONLY: property_readonly = true; break;
+ case RID_READWRITE: property_readwrite = true; break;
+ case RID_RETAIN: property_retain = true; break;
+
+ case RID_GETTER:
+ case RID_SETTER:
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ))
+ {
+ if (keyword == RID_GETTER)
+ cp_parser_error (parser,
+ "missing %<=%> (after %<getter%> attribute)");
+ else
+ cp_parser_error (parser,
+ "missing %<=%> (after %<setter%> attribute)");
+ syntax_error = true;
+ break;
+ }
+ cp_lexer_consume_token (parser->lexer); /* eat the = */
+ if (!cp_parser_objc_selector_p (cp_lexer_peek_token (parser->lexer)->type))
+ {
+ cp_parser_error (parser, "expected identifier");
+ syntax_error = true;
+ break;
+ }
+ if (keyword == RID_SETTER)
+ {
+ if (property_setter_ident != NULL_TREE)
+ {
+ cp_parser_error (parser, "the %<setter%> attribute may only be specified once");
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ property_setter_ident = cp_parser_objc_selector (parser);
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
+ cp_parser_error (parser, "setter name must terminate with %<:%>");
+ else
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ {
+ if (property_getter_ident != NULL_TREE)
+ {
+ cp_parser_error (parser, "the %<getter%> attribute may only be specified once");
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ property_getter_ident = cp_parser_objc_selector (parser);
+ }
+ break;
+ default:
+ cp_parser_error (parser, "unknown property attribute");
+ syntax_error = true;
+ break;
+ }
+
+ if (syntax_error)
+ break;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ else
+ break;
+ }
+
+ /* FIXME: "@property (setter, assign);" will generate a spurious
+ "error: expected ‘)’ before ‘,’ token". This is because
+ cp_parser_require, unlike the C counterpart, will produce an
+ error even if we are in error recovery. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ {
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ }
+ }
+
+ /* ... and the property declaration(s). */
+ properties = cp_parser_objc_struct_declaration (parser);
+
+ if (properties == error_mark_node)
+ {
+ cp_parser_skip_to_end_of_statement (parser);
+ /* If the next token is now a `;', consume it. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ return;
+ }
+
+ if (properties == NULL_TREE)
+ cp_parser_error (parser, "expected identifier");
+ else
+ {
+ /* Comma-separated properties are chained together in
+ reverse order; add them one by one. */
+ properties = nreverse (properties);
+
+ for (; properties; properties = TREE_CHAIN (properties))
+ objc_add_property_declaration (loc, copy_node (properties),
+ property_readonly, property_readwrite,
+ property_assign, property_retain,
+ property_copy, property_nonatomic,
+ property_getter_ident, property_setter_ident);
+ }
+
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+}
+
+/* Parse an Objective-C++ @synthesize declaration. The syntax is:
+
+ objc-synthesize-declaration:
+ @synthesize objc-synthesize-identifier-list ;
+
+ objc-synthesize-identifier-list:
+ objc-synthesize-identifier
+ objc-synthesize-identifier-list, objc-synthesize-identifier
+
+ objc-synthesize-identifier
+ identifier
+ identifier = identifier
+
+ For example:
+ @synthesize MyProperty;
+ @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
+
+ PS: This function is identical to c_parser_objc_at_synthesize_declaration
+ for C. Keep them in sync.
+*/
+static void
+cp_parser_objc_at_synthesize_declaration (cp_parser *parser)
+{
+ tree list = NULL_TREE;
+ location_t loc;
+ loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '@synthesize'. */
+ while (true)
+ {
+ tree property, ivar;
+ property = cp_parser_identifier (parser);
+ if (property == error_mark_node)
+ {
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+ return;
+ }
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ ivar = cp_parser_identifier (parser);
+ if (ivar == error_mark_node)
+ {
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+ return;
+ }
+ }
+ else
+ ivar = NULL_TREE;
+ list = chainon (list, build_tree_list (ivar, property));
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ else
+ break;
+ }
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+ objc_add_synthesize_declaration (loc, list);
+}
+
+/* Parse an Objective-C++ @dynamic declaration. The syntax is:
+
+ objc-dynamic-declaration:
+ @dynamic identifier-list ;
+
+ For example:
+ @dynamic MyProperty;
+ @dynamic MyProperty, AnotherProperty;
+
+ PS: This function is identical to c_parser_objc_at_dynamic_declaration
+ for C. Keep them in sync.
+*/
+static void
+cp_parser_objc_at_dynamic_declaration (cp_parser *parser)
+{
+ tree list = NULL_TREE;
+ location_t loc;
+ loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ cp_lexer_consume_token (parser->lexer); /* Eat '@dynamic'. */
+ while (true)
+ {
+ tree property;
+ property = cp_parser_identifier (parser);
+ if (property == error_mark_node)
+ {
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+ return;
+ }
+ list = chainon (list, build_tree_list (NULL, property));
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ else
+ break;
+ }
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+ objc_add_dynamic_declaration (loc, list);
+}
+
+
+/* OpenMP 2.5 / 3.0 / 3.1 / 4.0 parsing routines. */
+
+/* Returns name of the next clause.
+ If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
+ the token is not consumed. Otherwise appropriate pragma_omp_clause is
+ returned and the token is consumed. */
+
+static pragma_omp_clause
+cp_parser_omp_clause_name (cp_parser *parser)
+{
+ pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
+
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
+ result = PRAGMA_OMP_CLAUSE_IF;
+ else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT))
+ result = PRAGMA_OMP_CLAUSE_DEFAULT;
+ else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_PRIVATE))
+ result = PRAGMA_OMP_CLAUSE_PRIVATE;
+ else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
+ result = PRAGMA_OMP_CLAUSE_FOR;
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ switch (p[0])
+ {
+ case 'a':
+ if (!strcmp ("aligned", p))
+ result = PRAGMA_OMP_CLAUSE_ALIGNED;
+ break;
+ case 'c':
+ if (!strcmp ("collapse", p))
+ result = PRAGMA_OMP_CLAUSE_COLLAPSE;
+ else if (!strcmp ("copyin", p))
+ result = PRAGMA_OMP_CLAUSE_COPYIN;
+ else if (!strcmp ("copyprivate", p))
+ result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
+ break;
+ case 'd':
+ if (!strcmp ("depend", p))
+ result = PRAGMA_OMP_CLAUSE_DEPEND;
+ else if (!strcmp ("device", p))
+ result = PRAGMA_OMP_CLAUSE_DEVICE;
+ else if (!strcmp ("dist_schedule", p))
+ result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
+ break;
+ case 'f':
+ if (!strcmp ("final", p))
+ result = PRAGMA_OMP_CLAUSE_FINAL;
+ else if (!strcmp ("firstprivate", p))
+ result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
+ else if (!strcmp ("from", p))
+ result = PRAGMA_OMP_CLAUSE_FROM;
+ break;
+ case 'i':
+ if (!strcmp ("inbranch", p))
+ result = PRAGMA_OMP_CLAUSE_INBRANCH;
+ break;
+ case 'l':
+ if (!strcmp ("lastprivate", p))
+ result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
+ else if (!strcmp ("linear", p))
+ result = PRAGMA_OMP_CLAUSE_LINEAR;
+ break;
+ case 'm':
+ if (!strcmp ("map", p))
+ result = PRAGMA_OMP_CLAUSE_MAP;
+ else if (!strcmp ("mergeable", p))
+ result = PRAGMA_OMP_CLAUSE_MERGEABLE;
+ else if (flag_cilkplus && !strcmp ("mask", p))
+ result = PRAGMA_CILK_CLAUSE_MASK;
+ break;
+ case 'n':
+ if (!strcmp ("notinbranch", p))
+ result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
+ else if (!strcmp ("nowait", p))
+ result = PRAGMA_OMP_CLAUSE_NOWAIT;
+ else if (flag_cilkplus && !strcmp ("nomask", p))
+ result = PRAGMA_CILK_CLAUSE_NOMASK;
+ else if (!strcmp ("num_teams", p))
+ result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
+ else if (!strcmp ("num_threads", p))
+ result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
+ break;
+ case 'o':
+ if (!strcmp ("ordered", p))
+ result = PRAGMA_OMP_CLAUSE_ORDERED;
+ break;
+ case 'p':
+ if (!strcmp ("parallel", p))
+ result = PRAGMA_OMP_CLAUSE_PARALLEL;
+ else if (!strcmp ("proc_bind", p))
+ result = PRAGMA_OMP_CLAUSE_PROC_BIND;
+ break;
+ case 'r':
+ if (!strcmp ("reduction", p))
+ result = PRAGMA_OMP_CLAUSE_REDUCTION;
+ break;
+ case 's':
+ if (!strcmp ("safelen", p))
+ result = PRAGMA_OMP_CLAUSE_SAFELEN;
+ else if (!strcmp ("schedule", p))
+ result = PRAGMA_OMP_CLAUSE_SCHEDULE;
+ else if (!strcmp ("sections", p))
+ result = PRAGMA_OMP_CLAUSE_SECTIONS;
+ else if (!strcmp ("shared", p))
+ result = PRAGMA_OMP_CLAUSE_SHARED;
+ else if (!strcmp ("simdlen", p))
+ result = PRAGMA_OMP_CLAUSE_SIMDLEN;
+ break;
+ case 't':
+ if (!strcmp ("taskgroup", p))
+ result = PRAGMA_OMP_CLAUSE_TASKGROUP;
+ else if (!strcmp ("thread_limit", p))
+ result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
+ else if (!strcmp ("to", p))
+ result = PRAGMA_OMP_CLAUSE_TO;
+ break;
+ case 'u':
+ if (!strcmp ("uniform", p))
+ result = PRAGMA_OMP_CLAUSE_UNIFORM;
+ else if (!strcmp ("untied", p))
+ result = PRAGMA_OMP_CLAUSE_UNTIED;
+ break;
+ case 'v':
+ if (flag_cilkplus && !strcmp ("vectorlength", p))
+ result = PRAGMA_CILK_CLAUSE_VECTORLENGTH;
+ break;
+ }
+ }
+
+ if (result != PRAGMA_OMP_CLAUSE_NONE)
+ cp_lexer_consume_token (parser->lexer);
+
+ return result;
+}
+
+/* Validate that a clause of the given type does not already exist. */
+
+static void
+check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
+ const char *name, location_t location)
+{
+ tree c;
+
+ for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == code)
+ {
+ error_at (location, "too many %qs clauses", name);
+ break;
+ }
+}
+
+/* OpenMP 2.5:
+ variable-list:
+ identifier
+ variable-list , identifier
+
+ In addition, we match a closing parenthesis (or, if COLON is non-NULL,
+ colon). An opening parenthesis will have been consumed by the caller.
+
+ If KIND is nonzero, create the appropriate node and install the decl
+ in OMP_CLAUSE_DECL and add the node to the head of the list.
+
+ If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
+ return the list created.
+
+ COLON can be NULL if only closing parenthesis should end the list,
+ or pointer to bool which will receive false if the list is terminated
+ by closing parenthesis or true if the list is terminated by colon. */
+
+static tree
+cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
+ tree list, bool *colon)
+{
+ cp_token *token;
+ bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+ if (colon)
+ {
+ parser->colon_corrects_to_scope_p = false;
+ *colon = false;
+ }
+ while (1)
+ {
+ tree name, decl;
+
+ token = cp_lexer_peek_token (parser->lexer);
+ name = cp_parser_id_expression (parser, /*template_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/NULL,
+ /*declarator_p=*/false,
+ /*optional_p=*/false);
+ if (name == error_mark_node)
+ goto skip_comma;
+
+ decl = cp_parser_lookup_name_simple (parser, name, token->location);
+ if (decl == error_mark_node)
+ cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
+ token->location);
+ else if (kind != 0)
+ {
+ switch (kind)
+ {
+ case OMP_CLAUSE_MAP:
+ case OMP_CLAUSE_FROM:
+ case OMP_CLAUSE_TO:
+ case OMP_CLAUSE_DEPEND:
+ while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+ {
+ tree low_bound = NULL_TREE, length = NULL_TREE;
+
+ parser->colon_corrects_to_scope_p = false;
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ low_bound = cp_parser_expression (parser, /*cast_p=*/false,
+ NULL);
+ if (!colon)
+ parser->colon_corrects_to_scope_p
+ = saved_colon_corrects_to_scope_p;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
+ length = integer_one_node;
+ else
+ {
+ /* Look for `:'. */
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+ goto skip_comma;
+ if (!cp_lexer_next_token_is (parser->lexer,
+ CPP_CLOSE_SQUARE))
+ length = cp_parser_expression (parser,
+ /*cast_p=*/false,
+ NULL);
+ }
+ /* Look for the closing `]'. */
+ if (!cp_parser_require (parser, CPP_CLOSE_SQUARE,
+ RT_CLOSE_SQUARE))
+ goto skip_comma;
+ decl = tree_cons (low_bound, length, decl);
+ }
+ break;
+ default:
+ break;
+ }
+
+ tree u = build_omp_clause (token->location, kind);
+ OMP_CLAUSE_DECL (u) = decl;
+ OMP_CLAUSE_CHAIN (u) = list;
+ list = u;
+ }
+ else
+ list = tree_cons (decl, NULL_TREE, list);
+
+ get_comma:
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ if (colon)
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+
+ if (colon != NULL && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ *colon = true;
+ cp_parser_require (parser, CPP_COLON, RT_COLON);
+ return list;
+ }
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ {
+ int ending;
+
+ /* Try to resync to an unnested comma. Copied from
+ cp_parser_parenthesized_expression_list. */
+ skip_comma:
+ if (colon)
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+ ending = cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/true,
+ /*consume_paren=*/true);
+ if (ending < 0)
+ goto get_comma;
+ }
+
+ return list;
+}
+
+/* Similarly, but expect leading and trailing parenthesis. This is a very
+ common case for omp clauses. */
+
+static tree
+cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list)
+{
+ if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return cp_parser_omp_var_list_no_open (parser, kind, list, NULL);
+ return list;
+}
+
+/* OpenMP 3.0:
+ collapse ( constant-expression ) */
+
+static tree
+cp_parser_omp_clause_collapse (cp_parser *parser, tree list, location_t location)
+{
+ tree c, num;
+ location_t loc;
+ HOST_WIDE_INT n;
+
+ loc = cp_lexer_peek_token (parser->lexer)->location;
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ num = cp_parser_constant_expression (parser, false, NULL);
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ if (num == error_mark_node)
+ return list;
+ num = fold_non_dependent_expr (num);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
+ || !tree_fits_shwi_p (num)
+ || (n = tree_to_shwi (num)) <= 0
+ || (int) n != n)
+ {
+ error_at (loc, "collapse argument needs positive constant integer expression");
+ return list;
+ }
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse", location);
+ c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
+ OMP_CLAUSE_CHAIN (c) = list;
+ OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
+
+ return c;
+}
+
+/* OpenMP 2.5:
+ default ( shared | none ) */
+
+static tree
+cp_parser_omp_clause_default (cp_parser *parser, tree list, location_t location)
+{
+ enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
+ tree c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ switch (p[0])
+ {
+ case 'n':
+ if (strcmp ("none", p) != 0)
+ goto invalid_kind;
+ kind = OMP_CLAUSE_DEFAULT_NONE;
+ break;
+
+ case 's':
+ if (strcmp ("shared", p) != 0)
+ goto invalid_kind;
+ kind = OMP_CLAUSE_DEFAULT_SHARED;
+ break;
+
+ default:
+ goto invalid_kind;
+ }
+
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ {
+ invalid_kind:
+ cp_parser_error (parser, "expected %<none%> or %<shared%>");
+ }
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
+ return list;
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default", location);
+ c = build_omp_clause (location, OMP_CLAUSE_DEFAULT);
+ OMP_CLAUSE_CHAIN (c) = list;
+ OMP_CLAUSE_DEFAULT_KIND (c) = kind;
+
+ return c;
+}
+
+/* OpenMP 3.1:
+ final ( expression ) */
+
+static tree
+cp_parser_omp_clause_final (cp_parser *parser, tree list, location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_condition (parser);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_FINAL);
+ OMP_CLAUSE_FINAL_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 2.5:
+ if ( expression ) */
+
+static tree
+cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_condition (parser);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_IF);
+ OMP_CLAUSE_IF_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 3.1:
+ mergeable */
+
+static tree
+cp_parser_omp_clause_mergeable (cp_parser * /*parser*/,
+ tree list, location_t location)
+{
+ tree c;
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable",
+ location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_MERGEABLE);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
+/* OpenMP 2.5:
+ nowait */
+
+static tree
+cp_parser_omp_clause_nowait (cp_parser * /*parser*/,
+ tree list, location_t location)
+{
+ tree c;
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_NOWAIT);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
+/* OpenMP 2.5:
+ num_threads ( expression ) */
+
+static tree
+cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_expression (parser, false, NULL);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS,
+ "num_threads", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_NUM_THREADS);
+ OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 2.5:
+ ordered */
+
+static tree
+cp_parser_omp_clause_ordered (cp_parser * /*parser*/,
+ tree list, location_t location)
+{
+ tree c;
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED,
+ "ordered", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_ORDERED);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
+/* OpenMP 2.5:
+ reduction ( reduction-operator : variable-list )
+
+ reduction-operator:
+ One of: + * - & ^ | && ||
+
+ OpenMP 3.1:
+
+ reduction-operator:
+ One of: + * - & ^ | && || min max
+
+ OpenMP 4.0:
+
+ reduction-operator:
+ One of: + * - & ^ | && ||
+ id-expression */
+
+static tree
+cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
+{
+ enum tree_code code = ERROR_MARK;
+ tree nlist, c, id = NULL_TREE;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ switch (cp_lexer_peek_token (parser->lexer)->type)
+ {
+ case CPP_PLUS: code = PLUS_EXPR; break;
+ case CPP_MULT: code = MULT_EXPR; break;
+ case CPP_MINUS: code = MINUS_EXPR; break;
+ case CPP_AND: code = BIT_AND_EXPR; break;
+ case CPP_XOR: code = BIT_XOR_EXPR; break;
+ case CPP_OR: code = BIT_IOR_EXPR; break;
+ case CPP_AND_AND: code = TRUTH_ANDIF_EXPR; break;
+ case CPP_OR_OR: code = TRUTH_ORIF_EXPR; break;
+ default: break;
+ }
+
+ if (code != ERROR_MARK)
+ cp_lexer_consume_token (parser->lexer);
+ else
+ {
+ bool saved_colon_corrects_to_scope_p;
+ saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+ parser->colon_corrects_to_scope_p = false;
+ id = cp_parser_id_expression (parser, /*template_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/NULL,
+ /*declarator_p=*/false,
+ /*optional_p=*/false);
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+ if (identifier_p (id))
+ {
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp (p, "min") == 0)
+ code = MIN_EXPR;
+ else if (strcmp (p, "max") == 0)
+ code = MAX_EXPR;
+ else if (id == ansi_opname (PLUS_EXPR))
+ code = PLUS_EXPR;
+ else if (id == ansi_opname (MULT_EXPR))
+ code = MULT_EXPR;
+ else if (id == ansi_opname (MINUS_EXPR))
+ code = MINUS_EXPR;
+ else if (id == ansi_opname (BIT_AND_EXPR))
+ code = BIT_AND_EXPR;
+ else if (id == ansi_opname (BIT_IOR_EXPR))
+ code = BIT_IOR_EXPR;
+ else if (id == ansi_opname (BIT_XOR_EXPR))
+ code = BIT_XOR_EXPR;
+ else if (id == ansi_opname (TRUTH_ANDIF_EXPR))
+ code = TRUTH_ANDIF_EXPR;
+ else if (id == ansi_opname (TRUTH_ORIF_EXPR))
+ code = TRUTH_ORIF_EXPR;
+ id = omp_reduction_id (code, id, NULL_TREE);
+ tree scope = parser->scope;
+ if (scope)
+ id = build_qualified_name (NULL_TREE, scope, id, false);
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ }
+ else
+ {
+ error ("invalid reduction-identifier");
+ resync_fail:
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+ }
+ }
+
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+ goto resync_fail;
+
+ nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_REDUCTION, list,
+ NULL);
+ for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
+ {
+ OMP_CLAUSE_REDUCTION_CODE (c) = code;
+ OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = id;
+ }
+
+ return nlist;
+}
+
+/* OpenMP 2.5:
+ schedule ( schedule-kind )
+ schedule ( schedule-kind , expression )
+
+ schedule-kind:
+ static | dynamic | guided | runtime | auto */
+
+static tree
+cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location)
+{
+ tree c, t;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ c = build_omp_clause (location, OMP_CLAUSE_SCHEDULE);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ switch (p[0])
+ {
+ case 'd':
+ if (strcmp ("dynamic", p) != 0)
+ goto invalid_kind;
+ OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
+ break;
+
+ case 'g':
+ if (strcmp ("guided", p) != 0)
+ goto invalid_kind;
+ OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
+ break;
+
+ case 'r':
+ if (strcmp ("runtime", p) != 0)
+ goto invalid_kind;
+ OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
+ break;
+
+ default:
+ goto invalid_kind;
+ }
+ }
+ else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC))
+ OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
+ else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
+ OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
+ else
+ goto invalid_kind;
+ cp_lexer_consume_token (parser->lexer);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ {
+ cp_token *token;
+ cp_lexer_consume_token (parser->lexer);
+
+ token = cp_lexer_peek_token (parser->lexer);
+ t = cp_parser_assignment_expression (parser, false, NULL);
+
+ if (t == error_mark_node)
+ goto resync_fail;
+ else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
+ error_at (token->location, "schedule %<runtime%> does not take "
+ "a %<chunk_size%> parameter");
+ else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
+ error_at (token->location, "schedule %<auto%> does not take "
+ "a %<chunk_size%> parameter");
+ else
+ OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ goto resync_fail;
+ }
+ else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
+ goto resync_fail;
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule", location);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+
+ invalid_kind:
+ cp_parser_error (parser, "invalid schedule kind");
+ resync_fail:
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+}
+
+/* OpenMP 3.0:
+ untied */
+
+static tree
+cp_parser_omp_clause_untied (cp_parser * /*parser*/,
+ tree list, location_t location)
+{
+ tree c;
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_UNTIED);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
+/* OpenMP 4.0:
+ inbranch
+ notinbranch */
+
+static tree
+cp_parser_omp_clause_branch (cp_parser * /*parser*/, enum omp_clause_code code,
+ tree list, location_t location)
+{
+ check_no_duplicate_clause (list, code, omp_clause_code_name[code], location);
+ tree c = build_omp_clause (location, code);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
+/* OpenMP 4.0:
+ parallel
+ for
+ sections
+ taskgroup */
+
+static tree
+cp_parser_omp_clause_cancelkind (cp_parser * /*parser*/,
+ enum omp_clause_code code,
+ tree list, location_t location)
+{
+ tree c = build_omp_clause (location, code);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
+/* OpenMP 4.0:
+ num_teams ( expression ) */
+
+static tree
+cp_parser_omp_clause_num_teams (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_expression (parser, false, NULL);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS,
+ "num_teams", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_NUM_TEAMS);
+ OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.0:
+ thread_limit ( expression ) */
+
+static tree
+cp_parser_omp_clause_thread_limit (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_expression (parser, false, NULL);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
+ "thread_limit", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_THREAD_LIMIT);
+ OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.0:
+ aligned ( variable-list )
+ aligned ( variable-list : constant-expression ) */
+
+static tree
+cp_parser_omp_clause_aligned (cp_parser *parser, tree list)
+{
+ tree nlist, c, alignment = NULL_TREE;
+ bool colon;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_ALIGNED, list,
+ &colon);
+
+ if (colon)
+ {
+ alignment = cp_parser_constant_expression (parser, false, NULL);
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ if (alignment == error_mark_node)
+ alignment = NULL_TREE;
+ }
+
+ for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
+ OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
+
+ return nlist;
+}
+
+/* OpenMP 4.0:
+ linear ( variable-list )
+ linear ( variable-list : expression ) */
+
+static tree
+cp_parser_omp_clause_linear (cp_parser *parser, tree list,
+ bool is_cilk_simd_fn)
+{
+ tree nlist, c, step = integer_one_node;
+ bool colon;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_LINEAR, list,
+ &colon);
+
+ if (colon)
+ {
+ step = cp_parser_expression (parser, false, NULL);
+
+ if (is_cilk_simd_fn && TREE_CODE (step) == PARM_DECL)
+ {
+ sorry ("using parameters for %<linear%> step is not supported yet");
+ step = integer_one_node;
+ }
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ if (step == error_mark_node)
+ return list;
+ }
+
+ for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
+ OMP_CLAUSE_LINEAR_STEP (c) = step;
+
+ return nlist;
+}
+
+/* OpenMP 4.0:
+ safelen ( constant-expression ) */
+
+static tree
+cp_parser_omp_clause_safelen (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_constant_expression (parser, false, NULL);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_SAFELEN);
+ OMP_CLAUSE_SAFELEN_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.0:
+ simdlen ( constant-expression ) */
+
+static tree
+cp_parser_omp_clause_simdlen (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_constant_expression (parser, false, NULL);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_SIMDLEN);
+ OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.0:
+ depend ( depend-kind : variable-list )
+
+ depend-kind:
+ in | out | inout */
+
+static tree
+cp_parser_omp_clause_depend (cp_parser *parser, tree list)
+{
+ tree nlist, c;
+ enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INOUT;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp ("in", p) == 0)
+ kind = OMP_CLAUSE_DEPEND_IN;
+ else if (strcmp ("inout", p) == 0)
+ kind = OMP_CLAUSE_DEPEND_INOUT;
+ else if (strcmp ("out", p) == 0)
+ kind = OMP_CLAUSE_DEPEND_OUT;
+ else
+ goto invalid_kind;
+ }
+ else
+ goto invalid_kind;
+
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+ goto resync_fail;
+
+ nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_DEPEND, list,
+ NULL);
+
+ for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
+ OMP_CLAUSE_DEPEND_KIND (c) = kind;
+
+ return nlist;
+
+ invalid_kind:
+ cp_parser_error (parser, "invalid depend kind");
+ resync_fail:
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+}
+
+/* OpenMP 4.0:
+ map ( map-kind : variable-list )
+ map ( variable-list )
+
+ map-kind:
+ alloc | to | from | tofrom */
+
+static tree
+cp_parser_omp_clause_map (cp_parser *parser, tree list)
+{
+ tree nlist, c;
+ enum omp_clause_map_kind kind = OMP_CLAUSE_MAP_TOFROM;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp ("alloc", p) == 0)
+ kind = OMP_CLAUSE_MAP_ALLOC;
+ else if (strcmp ("to", p) == 0)
+ kind = OMP_CLAUSE_MAP_TO;
+ else if (strcmp ("from", p) == 0)
+ kind = OMP_CLAUSE_MAP_FROM;
+ else if (strcmp ("tofrom", p) == 0)
+ kind = OMP_CLAUSE_MAP_TOFROM;
+ else
+ {
+ cp_parser_error (parser, "invalid map kind");
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+ }
+ cp_lexer_consume_token (parser->lexer);
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_MAP, list,
+ NULL);
+
+ for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
+ OMP_CLAUSE_MAP_KIND (c) = kind;
+
+ return nlist;
+}
+
+/* OpenMP 4.0:
+ device ( expression ) */
+
+static tree
+cp_parser_omp_clause_device (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_expression (parser, false, NULL);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE,
+ "device", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_DEVICE);
+ OMP_CLAUSE_DEVICE_ID (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.0:
+ dist_schedule ( static )
+ dist_schedule ( static , expression ) */
+
+static tree
+cp_parser_omp_clause_dist_schedule (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree c, t;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ c = build_omp_clause (location, OMP_CLAUSE_DIST_SCHEDULE);
+
+ if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC))
+ goto invalid_kind;
+ cp_lexer_consume_token (parser->lexer);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ {
+ cp_lexer_consume_token (parser->lexer);
+
+ t = cp_parser_assignment_expression (parser, false, NULL);
+
+ if (t == error_mark_node)
+ goto resync_fail;
+ OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ goto resync_fail;
+ }
+ else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
+ goto resync_fail;
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE, "dist_schedule",
+ location);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+
+ invalid_kind:
+ cp_parser_error (parser, "invalid dist_schedule kind");
+ resync_fail:
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+}
+
+/* OpenMP 4.0:
+ proc_bind ( proc-bind-kind )
+
+ proc-bind-kind:
+ master | close | spread */
+
+static tree
+cp_parser_omp_clause_proc_bind (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree c;
+ enum omp_clause_proc_bind_kind kind;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp ("master", p) == 0)
+ kind = OMP_CLAUSE_PROC_BIND_MASTER;
+ else if (strcmp ("close", p) == 0)
+ kind = OMP_CLAUSE_PROC_BIND_CLOSE;
+ else if (strcmp ("spread", p) == 0)
+ kind = OMP_CLAUSE_PROC_BIND_SPREAD;
+ else
+ goto invalid_kind;
+ }
+ else
+ goto invalid_kind;
+
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
+ goto resync_fail;
+
+ c = build_omp_clause (location, OMP_CLAUSE_PROC_BIND);
+ check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind",
+ location);
+ OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+
+ invalid_kind:
+ cp_parser_error (parser, "invalid depend kind");
+ resync_fail:
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+}
+
+/* Parse all OpenMP clauses. The set clauses allowed by the directive
+ is a bitmask in MASK. Return the list of clauses found; the result
+ of clause default goes in *pdefault. */
+
+static tree
+cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
+ const char *where, cp_token *pragma_tok,
+ bool finish_p = true)
+{
+ tree clauses = NULL;
+ bool first = true;
+ cp_token *token = NULL;
+ bool cilk_simd_fn = false;
+
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
+ {
+ pragma_omp_clause c_kind;
+ const char *c_name;
+ tree prev = clauses;
+
+ if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+
+ token = cp_lexer_peek_token (parser->lexer);
+ c_kind = cp_parser_omp_clause_name (parser);
+
+ switch (c_kind)
+ {
+ case PRAGMA_OMP_CLAUSE_COLLAPSE:
+ clauses = cp_parser_omp_clause_collapse (parser, clauses,
+ token->location);
+ c_name = "collapse";
+ break;
+ case PRAGMA_OMP_CLAUSE_COPYIN:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_COPYIN, clauses);
+ c_name = "copyin";
+ break;
+ case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_COPYPRIVATE,
+ clauses);
+ c_name = "copyprivate";
+ break;
+ case PRAGMA_OMP_CLAUSE_DEFAULT:
+ clauses = cp_parser_omp_clause_default (parser, clauses,
+ token->location);
+ c_name = "default";
+ break;
+ case PRAGMA_OMP_CLAUSE_FINAL:
+ clauses = cp_parser_omp_clause_final (parser, clauses, token->location);
+ c_name = "final";
+ break;
+ case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FIRSTPRIVATE,
+ clauses);
+ c_name = "firstprivate";
+ break;
+ case PRAGMA_OMP_CLAUSE_IF:
+ clauses = cp_parser_omp_clause_if (parser, clauses, token->location);
+ c_name = "if";
+ break;
+ case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_LASTPRIVATE,
+ clauses);
+ c_name = "lastprivate";
+ break;
+ case PRAGMA_OMP_CLAUSE_MERGEABLE:
+ clauses = cp_parser_omp_clause_mergeable (parser, clauses,
+ token->location);
+ c_name = "mergeable";
+ break;
+ case PRAGMA_OMP_CLAUSE_NOWAIT:
+ clauses = cp_parser_omp_clause_nowait (parser, clauses, token->location);
+ c_name = "nowait";
+ break;
+ case PRAGMA_OMP_CLAUSE_NUM_THREADS:
+ clauses = cp_parser_omp_clause_num_threads (parser, clauses,
+ token->location);
+ c_name = "num_threads";
+ break;
+ case PRAGMA_OMP_CLAUSE_ORDERED:
+ clauses = cp_parser_omp_clause_ordered (parser, clauses,
+ token->location);
+ c_name = "ordered";
+ break;
+ case PRAGMA_OMP_CLAUSE_PRIVATE:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_PRIVATE,
+ clauses);
+ c_name = "private";
+ break;
+ case PRAGMA_OMP_CLAUSE_REDUCTION:
+ clauses = cp_parser_omp_clause_reduction (parser, clauses);
+ c_name = "reduction";
+ break;
+ case PRAGMA_OMP_CLAUSE_SCHEDULE:
+ clauses = cp_parser_omp_clause_schedule (parser, clauses,
+ token->location);
+ c_name = "schedule";
+ break;
+ case PRAGMA_OMP_CLAUSE_SHARED:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_SHARED,
+ clauses);
+ c_name = "shared";
+ break;
+ case PRAGMA_OMP_CLAUSE_UNTIED:
+ clauses = cp_parser_omp_clause_untied (parser, clauses,
+ token->location);
+ c_name = "untied";
+ break;
+ case PRAGMA_OMP_CLAUSE_INBRANCH:
+ case PRAGMA_CILK_CLAUSE_MASK:
+ clauses = cp_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
+ clauses, token->location);
+ c_name = "inbranch";
+ break;
+ case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
+ case PRAGMA_CILK_CLAUSE_NOMASK:
+ clauses = cp_parser_omp_clause_branch (parser,
+ OMP_CLAUSE_NOTINBRANCH,
+ clauses, token->location);
+ c_name = "notinbranch";
+ break;
+ case PRAGMA_OMP_CLAUSE_PARALLEL:
+ clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
+ clauses, token->location);
+ c_name = "parallel";
+ if (!first)
+ {
+ clause_not_first:
+ error_at (token->location, "%qs must be the first clause of %qs",
+ c_name, where);
+ clauses = prev;
+ }
+ break;
+ case PRAGMA_OMP_CLAUSE_FOR:
+ clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
+ clauses, token->location);
+ c_name = "for";
+ if (!first)
+ goto clause_not_first;
+ break;
+ case PRAGMA_OMP_CLAUSE_SECTIONS:
+ clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
+ clauses, token->location);
+ c_name = "sections";
+ if (!first)
+ goto clause_not_first;
+ break;
+ case PRAGMA_OMP_CLAUSE_TASKGROUP:
+ clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
+ clauses, token->location);
+ c_name = "taskgroup";
+ if (!first)
+ goto clause_not_first;
+ break;
+ case PRAGMA_OMP_CLAUSE_TO:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO,
+ clauses);
+ c_name = "to";
+ break;
+ case PRAGMA_OMP_CLAUSE_FROM:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FROM,
+ clauses);
+ c_name = "from";
+ break;
+ case PRAGMA_OMP_CLAUSE_UNIFORM:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_UNIFORM,
+ clauses);
+ c_name = "uniform";
+ break;
+ case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
+ clauses = cp_parser_omp_clause_num_teams (parser, clauses,
+ token->location);
+ c_name = "num_teams";
+ break;
+ case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
+ clauses = cp_parser_omp_clause_thread_limit (parser, clauses,
+ token->location);
+ c_name = "thread_limit";
+ break;
+ case PRAGMA_OMP_CLAUSE_ALIGNED:
+ clauses = cp_parser_omp_clause_aligned (parser, clauses);
+ c_name = "aligned";
+ break;
+ case PRAGMA_OMP_CLAUSE_LINEAR:
+ if (((mask >> PRAGMA_CILK_CLAUSE_VECTORLENGTH) & 1) != 0)
+ cilk_simd_fn = true;
+ clauses = cp_parser_omp_clause_linear (parser, clauses, cilk_simd_fn);
+ c_name = "linear";
+ break;
+ case PRAGMA_OMP_CLAUSE_DEPEND:
+ clauses = cp_parser_omp_clause_depend (parser, clauses);
+ c_name = "depend";
+ break;
+ case PRAGMA_OMP_CLAUSE_MAP:
+ clauses = cp_parser_omp_clause_map (parser, clauses);
+ c_name = "map";
+ break;
+ case PRAGMA_OMP_CLAUSE_DEVICE:
+ clauses = cp_parser_omp_clause_device (parser, clauses,
+ token->location);
+ c_name = "device";
+ break;
+ case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
+ clauses = cp_parser_omp_clause_dist_schedule (parser, clauses,
+ token->location);
+ c_name = "dist_schedule";
+ break;
+ case PRAGMA_OMP_CLAUSE_PROC_BIND:
+ clauses = cp_parser_omp_clause_proc_bind (parser, clauses,
+ token->location);
+ c_name = "proc_bind";
+ break;
+ case PRAGMA_OMP_CLAUSE_SAFELEN:
+ clauses = cp_parser_omp_clause_safelen (parser, clauses,
+ token->location);
+ c_name = "safelen";
+ break;
+ case PRAGMA_OMP_CLAUSE_SIMDLEN:
+ clauses = cp_parser_omp_clause_simdlen (parser, clauses,
+ token->location);
+ c_name = "simdlen";
+ break;
+ case PRAGMA_CILK_CLAUSE_VECTORLENGTH:
+ clauses = cp_parser_cilk_simd_vectorlength (parser, clauses, true);
+ c_name = "simdlen";
+ break;
+ default:
+ cp_parser_error (parser, "expected %<#pragma omp%> clause");
+ goto saw_error;
+ }
+
+ first = false;
+
+ if (((mask >> c_kind) & 1) == 0)
+ {
+ /* Remove the invalid clause(s) from the list to avoid
+ confusing the rest of the compiler. */
+ clauses = prev;
+ error_at (token->location, "%qs is not valid for %qs", c_name, where);
+ }
+ }
+ saw_error:
+ /* In Cilk Plus SIMD enabled functions there is no pragma_token, so
+ no reason to skip to the end. */
+ if (!(flag_cilkplus && pragma_tok == NULL))
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ if (finish_p)
+ return finish_omp_clauses (clauses);
+ return clauses;
+}
+
+/* OpenMP 2.5:
+ structured-block:
+ statement
+
+ In practice, we're also interested in adding the statement to an
+ outer node. So it is convenient if we work around the fact that
+ cp_parser_statement calls add_stmt. */
+
+static unsigned
+cp_parser_begin_omp_structured_block (cp_parser *parser)
+{
+ unsigned save = parser->in_statement;
+
+ /* Only move the values to IN_OMP_BLOCK if they weren't false.
+ This preserves the "not within loop or switch" style error messages
+ for nonsense cases like
+ void foo() {
+ #pragma omp single
+ break;
+ }
+ */
+ if (parser->in_statement)
+ parser->in_statement = IN_OMP_BLOCK;
+
+ return save;
+}
+
+static void
+cp_parser_end_omp_structured_block (cp_parser *parser, unsigned save)
+{
+ parser->in_statement = save;
+}
+
+static tree
+cp_parser_omp_structured_block (cp_parser *parser)
+{
+ tree stmt = begin_omp_structured_block ();
+ unsigned int save = cp_parser_begin_omp_structured_block (parser);
+
+ cp_parser_statement (parser, NULL_TREE, false, NULL);
+
+ cp_parser_end_omp_structured_block (parser, save);
+ return finish_omp_structured_block (stmt);
+}
+
+/* OpenMP 2.5:
+ # pragma omp atomic new-line
+ expression-stmt
+
+ expression-stmt:
+ x binop= expr | x++ | ++x | x-- | --x
+ binop:
+ +, *, -, /, &, ^, |, <<, >>
+
+ where x is an lvalue expression with scalar type.
+
+ OpenMP 3.1:
+ # pragma omp atomic new-line
+ update-stmt
+
+ # pragma omp atomic read new-line
+ read-stmt
+
+ # pragma omp atomic write new-line
+ write-stmt
+
+ # pragma omp atomic update new-line
+ update-stmt
+
+ # pragma omp atomic capture new-line
+ capture-stmt
+
+ # pragma omp atomic capture new-line
+ capture-block
+
+ read-stmt:
+ v = x
+ write-stmt:
+ x = expr
+ update-stmt:
+ expression-stmt | x = x binop expr
+ capture-stmt:
+ v = expression-stmt
+ capture-block:
+ { v = x; update-stmt; } | { update-stmt; v = x; }
+
+ OpenMP 4.0:
+ update-stmt:
+ expression-stmt | x = x binop expr | x = expr binop x
+ capture-stmt:
+ v = update-stmt
+ capture-block:
+ { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
+
+ where x and v are lvalue expressions with scalar type. */
+
+static void
+cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
+{
+ tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, lhs1 = NULL_TREE;
+ tree rhs1 = NULL_TREE, orig_lhs;
+ enum tree_code code = OMP_ATOMIC, opcode = NOP_EXPR;
+ bool structured_block = false;
+ bool seq_cst = false;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (!strcmp (p, "read"))
+ code = OMP_ATOMIC_READ;
+ else if (!strcmp (p, "write"))
+ code = NOP_EXPR;
+ else if (!strcmp (p, "update"))
+ code = OMP_ATOMIC;
+ else if (!strcmp (p, "capture"))
+ code = OMP_ATOMIC_CAPTURE_NEW;
+ else
+ p = NULL;
+ if (p)
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (!strcmp (p, "seq_cst"))
+ {
+ seq_cst = true;
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+
+ switch (code)
+ {
+ case OMP_ATOMIC_READ:
+ case NOP_EXPR: /* atomic write */
+ v = cp_parser_unary_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false, NULL);
+ if (v == error_mark_node)
+ goto saw_error;
+ if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
+ goto saw_error;
+ if (code == NOP_EXPR)
+ lhs = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ else
+ lhs = cp_parser_unary_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false, NULL);
+ if (lhs == error_mark_node)
+ goto saw_error;
+ if (code == NOP_EXPR)
+ {
+ /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
+ opcode. */
+ code = OMP_ATOMIC;
+ rhs = lhs;
+ lhs = v;
+ v = NULL_TREE;
+ }
+ goto done;
+ case OMP_ATOMIC_CAPTURE_NEW:
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ structured_block = true;
+ }
+ else
+ {
+ v = cp_parser_unary_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false, NULL);
+ if (v == error_mark_node)
+ goto saw_error;
+ if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
+ goto saw_error;
+ }
+ default:
+ break;
+ }
+
+restart:
+ lhs = cp_parser_unary_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false, NULL);
+ orig_lhs = lhs;
+ switch (TREE_CODE (lhs))
+ {
+ case ERROR_MARK:
+ goto saw_error;
+
+ case POSTINCREMENT_EXPR:
+ if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
+ code = OMP_ATOMIC_CAPTURE_OLD;
+ /* FALLTHROUGH */
+ case PREINCREMENT_EXPR:
+ lhs = TREE_OPERAND (lhs, 0);
+ opcode = PLUS_EXPR;
+ rhs = integer_one_node;
+ break;
+
+ case POSTDECREMENT_EXPR:
+ if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
+ code = OMP_ATOMIC_CAPTURE_OLD;
+ /* FALLTHROUGH */
+ case PREDECREMENT_EXPR:
+ lhs = TREE_OPERAND (lhs, 0);
+ opcode = MINUS_EXPR;
+ rhs = integer_one_node;
+ break;
+
+ case COMPOUND_EXPR:
+ if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
+ && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
+ && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
+ && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
+ (TREE_OPERAND (lhs, 1), 0), 0)))
+ == BOOLEAN_TYPE)
+ /* Undo effects of boolean_increment for post {in,de}crement. */
+ lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
+ /* FALLTHRU */
+ case MODIFY_EXPR:
+ if (TREE_CODE (lhs) == MODIFY_EXPR
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
+ {
+ /* Undo effects of boolean_increment. */
+ if (integer_onep (TREE_OPERAND (lhs, 1)))
+ {
+ /* This is pre or post increment. */
+ rhs = TREE_OPERAND (lhs, 1);
+ lhs = TREE_OPERAND (lhs, 0);
+ opcode = NOP_EXPR;
+ if (code == OMP_ATOMIC_CAPTURE_NEW
+ && !structured_block
+ && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
+ code = OMP_ATOMIC_CAPTURE_OLD;
+ break;
+ }
+ }
+ /* FALLTHRU */
+ default:
+ switch (cp_lexer_peek_token (parser->lexer)->type)
+ {
+ case CPP_MULT_EQ:
+ opcode = MULT_EXPR;
+ break;
+ case CPP_DIV_EQ:
+ opcode = TRUNC_DIV_EXPR;
+ break;
+ case CPP_PLUS_EQ:
+ opcode = PLUS_EXPR;
+ break;
+ case CPP_MINUS_EQ:
+ opcode = MINUS_EXPR;
+ break;
+ case CPP_LSHIFT_EQ:
+ opcode = LSHIFT_EXPR;
+ break;
+ case CPP_RSHIFT_EQ:
+ opcode = RSHIFT_EXPR;
+ break;
+ case CPP_AND_EQ:
+ opcode = BIT_AND_EXPR;
+ break;
+ case CPP_OR_EQ:
+ opcode = BIT_IOR_EXPR;
+ break;
+ case CPP_XOR_EQ:
+ opcode = BIT_XOR_EXPR;
+ break;
+ case CPP_EQ:
+ enum cp_parser_prec oprec;
+ cp_token *token;
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_parse_tentatively (parser);
+ rhs1 = cp_parser_simple_cast_expression (parser);
+ if (rhs1 == error_mark_node)
+ {
+ cp_parser_abort_tentative_parse (parser);
+ cp_parser_simple_cast_expression (parser);
+ goto saw_error;
+ }
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type != CPP_SEMICOLON && !cp_tree_equal (lhs, rhs1))
+ {
+ cp_parser_abort_tentative_parse (parser);
+ cp_parser_parse_tentatively (parser);
+ rhs = cp_parser_binary_expression (parser, false, true,
+ PREC_NOT_OPERATOR, NULL);
+ if (rhs == error_mark_node)
+ {
+ cp_parser_abort_tentative_parse (parser);
+ cp_parser_binary_expression (parser, false, true,
+ PREC_NOT_OPERATOR, NULL);
+ goto saw_error;
+ }
+ switch (TREE_CODE (rhs))
+ {
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ if (cp_tree_equal (lhs, TREE_OPERAND (rhs, 1)))
+ {
+ if (cp_parser_parse_definitely (parser))
+ {
+ opcode = TREE_CODE (rhs);
+ rhs1 = TREE_OPERAND (rhs, 0);
+ rhs = TREE_OPERAND (rhs, 1);
+ goto stmt_done;
+ }
+ else
+ goto saw_error;
+ }
+ break;
+ default:
+ break;
+ }
+ cp_parser_abort_tentative_parse (parser);
+ if (structured_block && code == OMP_ATOMIC_CAPTURE_OLD)
+ {
+ rhs = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ if (rhs == error_mark_node)
+ goto saw_error;
+ opcode = NOP_EXPR;
+ rhs1 = NULL_TREE;
+ goto stmt_done;
+ }
+ cp_parser_error (parser,
+ "invalid form of %<#pragma omp atomic%>");
+ goto saw_error;
+ }
+ if (!cp_parser_parse_definitely (parser))
+ goto saw_error;
+ switch (token->type)
+ {
+ case CPP_SEMICOLON:
+ if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
+ {
+ code = OMP_ATOMIC_CAPTURE_OLD;
+ v = lhs;
+ lhs = NULL_TREE;
+ lhs1 = rhs1;
+ rhs1 = NULL_TREE;
+ cp_lexer_consume_token (parser->lexer);
+ goto restart;
+ }
+ else if (structured_block)
+ {
+ opcode = NOP_EXPR;
+ rhs = rhs1;
+ rhs1 = NULL_TREE;
+ goto stmt_done;
+ }
+ cp_parser_error (parser,
+ "invalid form of %<#pragma omp atomic%>");
+ goto saw_error;
+ case CPP_MULT:
+ opcode = MULT_EXPR;
+ break;
+ case CPP_DIV:
+ opcode = TRUNC_DIV_EXPR;
+ break;
+ case CPP_PLUS:
+ opcode = PLUS_EXPR;
+ break;
+ case CPP_MINUS:
+ opcode = MINUS_EXPR;
+ break;
+ case CPP_LSHIFT:
+ opcode = LSHIFT_EXPR;
+ break;
+ case CPP_RSHIFT:
+ opcode = RSHIFT_EXPR;
+ break;
+ case CPP_AND:
+ opcode = BIT_AND_EXPR;
+ break;
+ case CPP_OR:
+ opcode = BIT_IOR_EXPR;
+ break;
+ case CPP_XOR:
+ opcode = BIT_XOR_EXPR;
+ break;
+ default:
+ cp_parser_error (parser,
+ "invalid operator for %<#pragma omp atomic%>");
+ goto saw_error;
+ }
+ oprec = TOKEN_PRECEDENCE (token);
+ gcc_assert (oprec != PREC_NOT_OPERATOR);
+ if (commutative_tree_code (opcode))
+ oprec = (enum cp_parser_prec) (oprec - 1);
+ cp_lexer_consume_token (parser->lexer);
+ rhs = cp_parser_binary_expression (parser, false, false,
+ oprec, NULL);
+ if (rhs == error_mark_node)
+ goto saw_error;
+ goto stmt_done;
+ /* FALLTHROUGH */
+ default:
+ cp_parser_error (parser,
+ "invalid operator for %<#pragma omp atomic%>");
+ goto saw_error;
+ }
+ cp_lexer_consume_token (parser->lexer);
+
+ rhs = cp_parser_expression (parser, false, NULL);
+ if (rhs == error_mark_node)
+ goto saw_error;
+ break;
+ }
+stmt_done:
+ if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
+ {
+ if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
+ goto saw_error;
+ v = cp_parser_unary_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false, NULL);
+ if (v == error_mark_node)
+ goto saw_error;
+ if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
+ goto saw_error;
+ lhs1 = cp_parser_unary_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false, NULL);
+ if (lhs1 == error_mark_node)
+ goto saw_error;
+ }
+ if (structured_block)
+ {
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ }
+done:
+ finish_omp_atomic (code, opcode, lhs, rhs, v, lhs1, rhs1, seq_cst);
+ if (!structured_block)
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+ return;
+
+ saw_error:
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ if (structured_block)
+ {
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
+ cp_lexer_consume_token (parser->lexer);
+ else if (code == OMP_ATOMIC_CAPTURE_NEW)
+ {
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+}
+
+
+/* OpenMP 2.5:
+ # pragma omp barrier new-line */
+
+static void
+cp_parser_omp_barrier (cp_parser *parser, cp_token *pragma_tok)
+{
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ finish_omp_barrier ();
+}
+
+/* OpenMP 2.5:
+ # pragma omp critical [(name)] new-line
+ structured-block */
+
+static tree
+cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok)
+{
+ tree stmt, name = NULL;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ cp_lexer_consume_token (parser->lexer);
+
+ name = cp_parser_identifier (parser);
+
+ if (name == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ if (name == error_mark_node)
+ name = NULL;
+ }
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+
+ stmt = cp_parser_omp_structured_block (parser);
+ return c_finish_omp_critical (input_location, stmt, name);
+}
+
+/* OpenMP 2.5:
+ # pragma omp flush flush-vars[opt] new-line
+
+ flush-vars:
+ ( variable-list ) */
+
+static void
+cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
+{
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ (void) cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+
+ finish_omp_flush ();
+}
+
+/* Helper function, to parse omp for increment expression. */
+
+static tree
+cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
+{
+ tree cond = cp_parser_binary_expression (parser, false, true,
+ PREC_NOT_OPERATOR, NULL);
+ if (cond == error_mark_node
+ || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ cp_parser_skip_to_end_of_statement (parser);
+ return error_mark_node;
+ }
+
+ switch (TREE_CODE (cond))
+ {
+ case GT_EXPR:
+ case GE_EXPR:
+ case LT_EXPR:
+ case LE_EXPR:
+ break;
+ case NE_EXPR:
+ if (code == CILK_SIMD)
+ break;
+ /* Fall through: OpenMP disallows NE_EXPR. */
+ default:
+ return error_mark_node;
+ }
+
+ /* If decl is an iterator, preserve LHS and RHS of the relational
+ expr until finish_omp_for. */
+ if (decl
+ && (type_dependent_expression_p (decl)
+ || CLASS_TYPE_P (TREE_TYPE (decl))))
+ return cond;
+
+ return build_x_binary_op (input_location, TREE_CODE (cond),
+ TREE_OPERAND (cond, 0), ERROR_MARK,
+ TREE_OPERAND (cond, 1), ERROR_MARK,
+ /*overload=*/NULL, tf_warning_or_error);
+}
+
+/* Helper function, to parse omp for increment expression. */
+
+static tree
+cp_parser_omp_for_incr (cp_parser *parser, tree decl)
+{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ enum tree_code op;
+ tree lhs, rhs;
+ cp_id_kind idk;
+ bool decl_first;
+
+ if (token->type == CPP_PLUS_PLUS || token->type == CPP_MINUS_MINUS)
+ {
+ op = (token->type == CPP_PLUS_PLUS
+ ? PREINCREMENT_EXPR : PREDECREMENT_EXPR);
+ cp_lexer_consume_token (parser->lexer);
+ lhs = cp_parser_simple_cast_expression (parser);
+ if (lhs != decl)
+ return error_mark_node;
+ return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
+ }
+
+ lhs = cp_parser_primary_expression (parser, false, false, false, &idk);
+ if (lhs != decl)
+ return error_mark_node;
+
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_PLUS_PLUS || token->type == CPP_MINUS_MINUS)
+ {
+ op = (token->type == CPP_PLUS_PLUS
+ ? POSTINCREMENT_EXPR : POSTDECREMENT_EXPR);
+ cp_lexer_consume_token (parser->lexer);
+ return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
+ }
+
+ op = cp_parser_assignment_operator_opt (parser);
+ if (op == ERROR_MARK)
+ return error_mark_node;
+
+ if (op != NOP_EXPR)
+ {
+ rhs = cp_parser_assignment_expression (parser, false, NULL);
+ rhs = build2 (op, TREE_TYPE (decl), decl, rhs);
+ return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
+ }
+
+ lhs = cp_parser_binary_expression (parser, false, false,
+ PREC_ADDITIVE_EXPRESSION, NULL);
+ token = cp_lexer_peek_token (parser->lexer);
+ decl_first = lhs == decl;
+ if (decl_first)
+ lhs = NULL_TREE;
+ if (token->type != CPP_PLUS
+ && token->type != CPP_MINUS)
+ return error_mark_node;
+
+ do
+ {
+ op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR;
+ cp_lexer_consume_token (parser->lexer);
+ rhs = cp_parser_binary_expression (parser, false, false,
+ PREC_ADDITIVE_EXPRESSION, NULL);
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first)
+ {
+ if (lhs == NULL_TREE)
+ {
+ if (op == PLUS_EXPR)
+ lhs = rhs;
+ else
+ lhs = build_x_unary_op (input_location, NEGATE_EXPR, rhs,
+ tf_warning_or_error);
+ }
+ else
+ lhs = build_x_binary_op (input_location, op, lhs, ERROR_MARK, rhs,
+ ERROR_MARK, NULL, tf_warning_or_error);
+ }
+ }
+ while (token->type == CPP_PLUS || token->type == CPP_MINUS);
+
+ if (!decl_first)
+ {
+ if (rhs != decl || op == MINUS_EXPR)
+ return error_mark_node;
+ rhs = build2 (op, TREE_TYPE (decl), lhs, decl);
+ }
+ else
+ rhs = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, lhs);
+
+ return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
+}
+
+/* Parse the initialization statement of either an OpenMP for loop or
+ a Cilk Plus for loop.
+
+ PARSING_OPENMP is true if parsing OpenMP, or false if parsing Cilk
+ Plus.
+
+ Return true if the resulting construct should have an
+ OMP_CLAUSE_PRIVATE added to it. */
+
+static bool
+cp_parser_omp_for_loop_init (cp_parser *parser,
+ bool parsing_openmp,
+ tree &this_pre_body,
+ vec<tree, va_gc> *for_block,
+ tree &init,
+ tree &decl,
+ tree &real_decl)
+{
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ return false;
+
+ bool add_private_clause = false;
+
+ /* See 2.5.1 (in OpenMP 3.0, similar wording is in 2.5 standard too):
+
+ init-expr:
+ var = lb
+ integer-type var = lb
+ random-access-iterator-type var = lb
+ pointer-type var = lb
+ */
+ cp_decl_specifier_seq type_specifiers;
+
+ /* First, try to parse as an initialized declaration. See
+ cp_parser_condition, from whence the bulk of this is copied. */
+
+ cp_parser_parse_tentatively (parser);
+ cp_parser_type_specifier_seq (parser, /*is_declaration=*/true,
+ /*is_trailing_return=*/false,
+ &type_specifiers);
+ if (cp_parser_parse_definitely (parser))
+ {
+ /* If parsing a type specifier seq succeeded, then this
+ MUST be a initialized declaration. */
+ tree asm_specification, attributes;
+ cp_declarator *declarator;
+
+ declarator = cp_parser_declarator (parser,
+ CP_PARSER_DECLARATOR_NAMED,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
+ attributes = cp_parser_attributes_opt (parser);
+ asm_specification = cp_parser_asm_specification_opt (parser);
+
+ if (declarator == cp_error_declarator)
+ cp_parser_skip_to_end_of_statement (parser);
+
+ else
+ {
+ tree pushed_scope, auto_node;
+
+ decl = start_decl (declarator, &type_specifiers,
+ SD_INITIALIZED, attributes,
+ /*prefix_attributes=*/NULL_TREE,
+ &pushed_scope);
+
+ auto_node = type_uses_auto (TREE_TYPE (decl));
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ))
+ {
+ if (cp_lexer_next_token_is (parser->lexer,
+ CPP_OPEN_PAREN))
+ {
+ if (parsing_openmp)
+ error ("parenthesized initialization is not allowed in "
+ "OpenMP %<for%> loop");
+ else
+ error ("parenthesized initialization is "
+ "not allowed in for-loop");
+ }
+ else
+ /* Trigger an error. */
+ cp_parser_require (parser, CPP_EQ, RT_EQ);
+
+ init = error_mark_node;
+ cp_parser_skip_to_end_of_statement (parser);
+ }
+ else if (CLASS_TYPE_P (TREE_TYPE (decl))
+ || type_dependent_expression_p (decl)
+ || auto_node)
+ {
+ bool is_direct_init, is_non_constant_init;
+
+ init = cp_parser_initializer (parser,
+ &is_direct_init,
+ &is_non_constant_init);
+
+ if (auto_node)
+ {
+ TREE_TYPE (decl)
+ = do_auto_deduction (TREE_TYPE (decl), init,
+ auto_node);
+
+ if (!CLASS_TYPE_P (TREE_TYPE (decl))
+ && !type_dependent_expression_p (decl))
+ goto non_class;
+ }
+
+ cp_finish_decl (decl, init, !is_non_constant_init,
+ asm_specification,
+ LOOKUP_ONLYCONVERTING);
+ if (CLASS_TYPE_P (TREE_TYPE (decl)))
+ {
+ vec_safe_push (for_block, this_pre_body);
+ init = NULL_TREE;
+ }
+ else
+ init = pop_stmt_list (this_pre_body);
+ this_pre_body = NULL_TREE;
+ }
+ else
+ {
+ /* Consume '='. */
+ cp_lexer_consume_token (parser->lexer);
+ init = cp_parser_assignment_expression (parser, false, NULL);
+
+ non_class:
+ if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
+ init = error_mark_node;
+ else
+ cp_finish_decl (decl, NULL_TREE,
+ /*init_const_expr_p=*/false,
+ asm_specification,
+ LOOKUP_ONLYCONVERTING);
+ }
+
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ }
+ }
+ else
+ {
+ cp_id_kind idk;
+ /* If parsing a type specifier sequence failed, then
+ this MUST be a simple expression. */
+ cp_parser_parse_tentatively (parser);
+ decl = cp_parser_primary_expression (parser, false, false,
+ false, &idk);
+ if (!cp_parser_error_occurred (parser)
+ && decl
+ && DECL_P (decl)
+ && CLASS_TYPE_P (TREE_TYPE (decl)))
+ {
+ tree rhs;
+
+ cp_parser_parse_definitely (parser);
+ cp_parser_require (parser, CPP_EQ, RT_EQ);
+ rhs = cp_parser_assignment_expression (parser, false, NULL);
+ finish_expr_stmt (build_x_modify_expr (EXPR_LOCATION (rhs),
+ decl, NOP_EXPR,
+ rhs,
+ tf_warning_or_error));
+ add_private_clause = true;
+ }
+ else
+ {
+ decl = NULL;
+ cp_parser_abort_tentative_parse (parser);
+ init = cp_parser_expression (parser, false, NULL);
+ if (init)
+ {
+ if (TREE_CODE (init) == MODIFY_EXPR
+ || TREE_CODE (init) == MODOP_EXPR)
+ real_decl = TREE_OPERAND (init, 0);
+ }
+ }
+ }
+ return add_private_clause;
+}
+
+/* Parse the restricted form of the for statement allowed by OpenMP. */
+
+static tree
+cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
+ tree *cclauses)
+{
+ tree init, cond, incr, body, decl, pre_body = NULL_TREE, ret;
+ tree real_decl, initv, condv, incrv, declv;
+ tree this_pre_body, cl;
+ location_t loc_first;
+ bool collapse_err = false;
+ int i, collapse = 1, nbraces = 0;
+ vec<tree, va_gc> *for_block = make_tree_vector ();
+
+ for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
+ if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
+ collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
+
+ gcc_assert (collapse >= 1);
+
+ declv = make_tree_vec (collapse);
+ initv = make_tree_vec (collapse);
+ condv = make_tree_vec (collapse);
+ incrv = make_tree_vec (collapse);
+
+ loc_first = cp_lexer_peek_token (parser->lexer)->location;
+
+ for (i = 0; i < collapse; i++)
+ {
+ int bracecount = 0;
+ bool add_private_clause = false;
+ location_t loc;
+
+ if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
+ {
+ cp_parser_error (parser, "for statement expected");
+ return NULL;
+ }
+ loc = cp_lexer_consume_token (parser->lexer)->location;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return NULL;
+
+ init = decl = real_decl = NULL;
+ this_pre_body = push_stmt_list ();
+
+ add_private_clause
+ |= cp_parser_omp_for_loop_init (parser,
+ /*parsing_openmp=*/code != CILK_SIMD,
+ this_pre_body, for_block,
+ init, decl, real_decl);
+
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ if (this_pre_body)
+ {
+ this_pre_body = pop_stmt_list (this_pre_body);
+ if (pre_body)
+ {
+ tree t = pre_body;
+ pre_body = push_stmt_list ();
+ add_stmt (t);
+ add_stmt (this_pre_body);
+ pre_body = pop_stmt_list (pre_body);
+ }
+ else
+ pre_body = this_pre_body;
+ }
+
+ if (decl)
+ real_decl = decl;
+ if (cclauses != NULL
+ && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL
+ && real_decl != NULL_TREE)
+ {
+ tree *c;
+ for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
+ if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE
+ && OMP_CLAUSE_DECL (*c) == real_decl)
+ {
+ error_at (loc, "iteration variable %qD"
+ " should not be firstprivate", real_decl);
+ *c = OMP_CLAUSE_CHAIN (*c);
+ }
+ else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_DECL (*c) == real_decl)
+ {
+ /* Add lastprivate (decl) clause to OMP_FOR_CLAUSES,
+ change it to shared (decl) in OMP_PARALLEL_CLAUSES. */
+ tree l = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
+ OMP_CLAUSE_DECL (l) = real_decl;
+ OMP_CLAUSE_CHAIN (l) = clauses;
+ CP_OMP_CLAUSE_INFO (l) = CP_OMP_CLAUSE_INFO (*c);
+ clauses = l;
+ OMP_CLAUSE_SET_CODE (*c, OMP_CLAUSE_SHARED);
+ CP_OMP_CLAUSE_INFO (*c) = NULL;
+ add_private_clause = false;
+ }
+ else
+ {
+ if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_PRIVATE
+ && OMP_CLAUSE_DECL (*c) == real_decl)
+ add_private_clause = false;
+ c = &OMP_CLAUSE_CHAIN (*c);
+ }
+ }
+
+ if (add_private_clause)
+ {
+ tree c;
+ for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
+ {
+ if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+ && OMP_CLAUSE_DECL (c) == decl)
+ break;
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+ && OMP_CLAUSE_DECL (c) == decl)
+ error_at (loc, "iteration variable %qD "
+ "should not be firstprivate",
+ decl);
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+ && OMP_CLAUSE_DECL (c) == decl)
+ error_at (loc, "iteration variable %qD should not be reduction",
+ decl);
+ }
+ if (c == NULL)
+ {
+ c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE);
+ OMP_CLAUSE_DECL (c) = decl;
+ c = finish_omp_clauses (c);
+ if (c)
+ {
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ }
+ }
+
+ cond = NULL;
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ cond = cp_parser_omp_for_cond (parser, decl, code);
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+ incr = NULL;
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
+ {
+ /* If decl is an iterator, preserve the operator on decl
+ until finish_omp_for. */
+ if (real_decl
+ && ((processing_template_decl
+ && !POINTER_TYPE_P (TREE_TYPE (real_decl)))
+ || CLASS_TYPE_P (TREE_TYPE (real_decl))))
+ incr = cp_parser_omp_for_incr (parser, real_decl);
+ else
+ incr = cp_parser_expression (parser, false, NULL);
+ if (CAN_HAVE_LOCATION_P (incr) && !EXPR_HAS_LOCATION (incr))
+ SET_EXPR_LOCATION (incr, input_location);
+ }
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ TREE_VEC_ELT (declv, i) = decl;
+ TREE_VEC_ELT (initv, i) = init;
+ TREE_VEC_ELT (condv, i) = cond;
+ TREE_VEC_ELT (incrv, i) = incr;
+
+ if (i == collapse - 1)
+ break;
+
+ /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
+ in between the collapsed for loops to be still considered perfectly
+ nested. Hopefully the final version clarifies this.
+ For now handle (multiple) {'s and empty statements. */
+ cp_parser_parse_tentatively (parser);
+ do
+ {
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
+ break;
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ bracecount++;
+ }
+ else if (bracecount
+ && cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ else
+ {
+ loc = cp_lexer_peek_token (parser->lexer)->location;
+ error_at (loc, "not enough collapsed for loops");
+ collapse_err = true;
+ cp_parser_abort_tentative_parse (parser);
+ declv = NULL_TREE;
+ break;
+ }
+ }
+ while (1);
+
+ if (declv)
+ {
+ cp_parser_parse_definitely (parser);
+ nbraces += bracecount;
+ }
+ }
+
+ /* Note that we saved the original contents of this flag when we entered
+ the structured block, and so we don't need to re-save it here. */
+ if (code == CILK_SIMD)
+ parser->in_statement = IN_CILK_SIMD_FOR;
+ else
+ parser->in_statement = IN_OMP_FOR;
+
+ /* Note that the grammar doesn't call for a structured block here,
+ though the loop as a whole is a structured block. */
+ body = push_stmt_list ();
+ cp_parser_statement (parser, NULL_TREE, false, NULL);
+ body = pop_stmt_list (body);
+
+ if (declv == NULL_TREE)
+ ret = NULL_TREE;
+ else
+ ret = finish_omp_for (loc_first, code, declv, initv, condv, incrv, body,
+ pre_body, clauses);
+
+ while (nbraces)
+ {
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ nbraces--;
+ }
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ else
+ {
+ if (!collapse_err)
+ {
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "collapsed loops not perfectly nested");
+ }
+ collapse_err = true;
+ cp_parser_statement_seq_opt (parser, NULL);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ break;
+ }
+ }
+
+ while (!for_block->is_empty ())
+ add_stmt (pop_stmt_list (for_block->pop ()));
+ release_tree_vector (for_block);
+
+ return ret;
+}
+
+/* Helper function for OpenMP parsing, split clauses and call
+ finish_omp_clauses on each of the set of clauses afterwards. */
+
+static void
+cp_omp_split_clauses (location_t loc, enum tree_code code,
+ omp_clause_mask mask, tree clauses, tree *cclauses)
+{
+ int i;
+ c_omp_split_clauses (loc, code, mask, clauses, cclauses);
+ for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
+ if (cclauses[i])
+ cclauses[i] = finish_omp_clauses (cclauses[i]);
+}
+
+/* OpenMP 4.0:
+ #pragma omp simd simd-clause[optseq] new-line
+ for-loop */
+
+#define OMP_SIMD_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
+
+static tree
+cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
+ char *p_name, omp_clause_mask mask, tree *cclauses)
+{
+ tree clauses, sb, ret;
+ unsigned int save;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ strcat (p_name, " simd");
+ mask |= OMP_SIMD_CLAUSE_MASK;
+ mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
+
+ clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
+ cclauses == NULL);
+ if (cclauses)
+ {
+ cp_omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
+ }
+
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+
+ ret = cp_parser_omp_for_loop (parser, OMP_SIMD, clauses, cclauses);
+
+ cp_parser_end_omp_structured_block (parser, save);
+ add_stmt (finish_omp_structured_block (sb));
+
+ return ret;
+}
+
+/* OpenMP 2.5:
+ #pragma omp for for-clause[optseq] new-line
+ for-loop
+
+ OpenMP 4.0:
+ #pragma omp for simd for-simd-clause[optseq] new-line
+ for-loop */
+
+#define OMP_FOR_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
+
+static tree
+cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
+ char *p_name, omp_clause_mask mask, tree *cclauses)
+{
+ tree clauses, sb, ret;
+ unsigned int save;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ strcat (p_name, " for");
+ mask |= OMP_FOR_CLAUSE_MASK;
+ if (cclauses)
+ mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp (p, "simd") == 0)
+ {
+ tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+ if (cclauses == NULL)
+ cclauses = cclauses_buf;
+
+ cp_lexer_consume_token (parser->lexer);
+ if (!flag_openmp) /* flag_openmp_simd */
+ return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
+ cclauses);
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+ ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
+ cclauses);
+ cp_parser_end_omp_structured_block (parser, save);
+ tree body = finish_omp_structured_block (sb);
+ if (ret == NULL)
+ return ret;
+ ret = make_node (OMP_FOR);
+ TREE_TYPE (ret) = void_type_node;
+ OMP_FOR_BODY (ret) = body;
+ OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
+ SET_EXPR_LOCATION (ret, loc);
+ add_stmt (ret);
+ return ret;
+ }
+ }
+ if (!flag_openmp) /* flag_openmp_simd */
+ {
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
+ cclauses == NULL);
+ if (cclauses)
+ {
+ cp_omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
+ }
+
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+
+ ret = cp_parser_omp_for_loop (parser, OMP_FOR, clauses, cclauses);
+
+ cp_parser_end_omp_structured_block (parser, save);
+ add_stmt (finish_omp_structured_block (sb));
+
+ return ret;
+}
+
+/* OpenMP 2.5:
+ # pragma omp master new-line
+ structured-block */
+
+static tree
+cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok)
+{
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ return c_finish_omp_master (input_location,
+ cp_parser_omp_structured_block (parser));
+}
+
+/* OpenMP 2.5:
+ # pragma omp ordered new-line
+ structured-block */
+
+static tree
+cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok)
+{
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ return c_finish_omp_ordered (loc, cp_parser_omp_structured_block (parser));
+}
+
+/* OpenMP 2.5:
+
+ section-scope:
+ { section-sequence }
+
+ section-sequence:
+ section-directive[opt] structured-block
+ section-sequence section-directive structured-block */
+
+static tree
+cp_parser_omp_sections_scope (cp_parser *parser)
+{
+ tree stmt, substmt;
+ bool error_suppress = false;
+ cp_token *tok;
+
+ if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ return NULL_TREE;
+
+ stmt = push_stmt_list ();
+
+ if (cp_lexer_peek_token (parser->lexer)->pragma_kind != PRAGMA_OMP_SECTION)
+ {
+ substmt = cp_parser_omp_structured_block (parser);
+ substmt = build1 (OMP_SECTION, void_type_node, substmt);
+ add_stmt (substmt);
+ }
+
+ while (1)
+ {
+ tok = cp_lexer_peek_token (parser->lexer);
+ if (tok->type == CPP_CLOSE_BRACE)
+ break;
+ if (tok->type == CPP_EOF)
+ break;
+
+ if (tok->pragma_kind == PRAGMA_OMP_SECTION)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_require_pragma_eol (parser, tok);
+ error_suppress = false;
+ }
+ else if (!error_suppress)
+ {
+ cp_parser_error (parser, "expected %<#pragma omp section%> or %<}%>");
+ error_suppress = true;
+ }
+
+ substmt = cp_parser_omp_structured_block (parser);
+ substmt = build1 (OMP_SECTION, void_type_node, substmt);
+ add_stmt (substmt);
+ }
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+
+ substmt = pop_stmt_list (stmt);
+
+ stmt = make_node (OMP_SECTIONS);
+ TREE_TYPE (stmt) = void_type_node;
+ OMP_SECTIONS_BODY (stmt) = substmt;
+
+ add_stmt (stmt);
+ return stmt;
+}
+
+/* OpenMP 2.5:
+ # pragma omp sections sections-clause[optseq] newline
+ sections-scope */
+
+#define OMP_SECTIONS_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
+
+static tree
+cp_parser_omp_sections (cp_parser *parser, cp_token *pragma_tok,
+ char *p_name, omp_clause_mask mask, tree *cclauses)
+{
+ tree clauses, ret;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ strcat (p_name, " sections");
+ mask |= OMP_SECTIONS_CLAUSE_MASK;
+ if (cclauses)
+ mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
+
+ clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
+ cclauses == NULL);
+ if (cclauses)
+ {
+ cp_omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
+ }
+
+ ret = cp_parser_omp_sections_scope (parser);
+ if (ret)
+ OMP_SECTIONS_CLAUSES (ret) = clauses;
+
+ return ret;
+}
+
+/* OpenMP 2.5:
+ # pragma omp parallel parallel-clause[optseq] new-line
+ structured-block
+ # pragma omp parallel for parallel-for-clause[optseq] new-line
+ structured-block
+ # pragma omp parallel sections parallel-sections-clause[optseq] new-line
+ structured-block
+
+ OpenMP 4.0:
+ # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
+ structured-block */
+
+#define OMP_PARALLEL_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
+
+static tree
+cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
+ char *p_name, omp_clause_mask mask, tree *cclauses)
+{
+ tree stmt, clauses, block;
+ unsigned int save;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ strcat (p_name, " parallel");
+ mask |= OMP_PARALLEL_CLAUSE_MASK;
+
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
+ {
+ tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+ if (cclauses == NULL)
+ cclauses = cclauses_buf;
+
+ cp_lexer_consume_token (parser->lexer);
+ if (!flag_openmp) /* flag_openmp_simd */
+ return cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses);
+ block = begin_omp_parallel ();
+ save = cp_parser_begin_omp_structured_block (parser);
+ cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses);
+ cp_parser_end_omp_structured_block (parser, save);
+ stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
+ block);
+ OMP_PARALLEL_COMBINED (stmt) = 1;
+ return stmt;
+ }
+ else if (cclauses)
+ {
+ error_at (loc, "expected %<for%> after %qs", p_name);
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+ else if (!flag_openmp) /* flag_openmp_simd */
+ {
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+ if (strcmp (p, "sections") == 0)
+ {
+ tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+ cclauses = cclauses_buf;
+
+ cp_lexer_consume_token (parser->lexer);
+ block = begin_omp_parallel ();
+ save = cp_parser_begin_omp_structured_block (parser);
+ cp_parser_omp_sections (parser, pragma_tok, p_name, mask, cclauses);
+ cp_parser_end_omp_structured_block (parser, save);
+ stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
+ block);
+ OMP_PARALLEL_COMBINED (stmt) = 1;
+ return stmt;
+ }
+ }
+
+ clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok);
+
+ block = begin_omp_parallel ();
+ save = cp_parser_begin_omp_structured_block (parser);
+ cp_parser_statement (parser, NULL_TREE, false, NULL);
+ cp_parser_end_omp_structured_block (parser, save);
+ stmt = finish_omp_parallel (clauses, block);
+ return stmt;
+}
+
+/* OpenMP 2.5:
+ # pragma omp single single-clause[optseq] new-line
+ structured-block */
+
+#define OMP_SINGLE_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
+
+static tree
+cp_parser_omp_single (cp_parser *parser, cp_token *pragma_tok)
+{
+ tree stmt = make_node (OMP_SINGLE);
+ TREE_TYPE (stmt) = void_type_node;
+
+ OMP_SINGLE_CLAUSES (stmt)
+ = cp_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
+ "#pragma omp single", pragma_tok);
+ OMP_SINGLE_BODY (stmt) = cp_parser_omp_structured_block (parser);
+
+ return add_stmt (stmt);
+}
+
+/* OpenMP 3.0:
+ # pragma omp task task-clause[optseq] new-line
+ structured-block */
+
+#define OMP_TASK_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND))
+
+static tree
+cp_parser_omp_task (cp_parser *parser, cp_token *pragma_tok)
+{
+ tree clauses, block;
+ unsigned int save;
+
+ clauses = cp_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
+ "#pragma omp task", pragma_tok);
+ block = begin_omp_task ();
+ save = cp_parser_begin_omp_structured_block (parser);
+ cp_parser_statement (parser, NULL_TREE, false, NULL);
+ cp_parser_end_omp_structured_block (parser, save);
+ return finish_omp_task (clauses, block);
+}
+
+/* OpenMP 3.0:
+ # pragma omp taskwait new-line */
+
+static void
+cp_parser_omp_taskwait (cp_parser *parser, cp_token *pragma_tok)
+{
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ finish_omp_taskwait ();
+}
+
+/* OpenMP 3.1:
+ # pragma omp taskyield new-line */
+
+static void
+cp_parser_omp_taskyield (cp_parser *parser, cp_token *pragma_tok)
+{
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ finish_omp_taskyield ();
+}
+
+/* OpenMP 4.0:
+ # pragma omp taskgroup new-line
+ structured-block */
+
+static tree
+cp_parser_omp_taskgroup (cp_parser *parser, cp_token *pragma_tok)
+{
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ return c_finish_omp_taskgroup (input_location,
+ cp_parser_omp_structured_block (parser));
+}
+
+
+/* OpenMP 2.5:
+ # pragma omp threadprivate (variable-list) */
+
+static void
+cp_parser_omp_threadprivate (cp_parser *parser, cp_token *pragma_tok)
+{
+ tree vars;
+
+ vars = cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+
+ finish_omp_threadprivate (vars);
+}
+
+/* OpenMP 4.0:
+ # pragma omp cancel cancel-clause[optseq] new-line */
+
+#define OMP_CANCEL_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
+
+static void
+cp_parser_omp_cancel (cp_parser *parser, cp_token *pragma_tok)
+{
+ tree clauses = cp_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
+ "#pragma omp cancel", pragma_tok);
+ finish_omp_cancel (clauses);
+}
+
+/* OpenMP 4.0:
+ # pragma omp cancellation point cancelpt-clause[optseq] new-line */
+
+#define OMP_CANCELLATION_POINT_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
+
+static void
+cp_parser_omp_cancellation_point (cp_parser *parser, cp_token *pragma_tok)
+{
+ tree clauses;
+ bool point_seen = false;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp (p, "point") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ point_seen = true;
+ }
+ }
+ if (!point_seen)
+ {
+ cp_parser_error (parser, "expected %<point%>");
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ return;
+ }
+
+ clauses = cp_parser_omp_all_clauses (parser,
+ OMP_CANCELLATION_POINT_CLAUSE_MASK,
+ "#pragma omp cancellation point",
+ pragma_tok);
+ finish_omp_cancellation_point (clauses);
+}
+
+/* OpenMP 4.0:
+ #pragma omp distribute distribute-clause[optseq] new-line
+ for-loop */
+
+#define OMP_DISTRIBUTE_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
+
+static tree
+cp_parser_omp_distribute (cp_parser *parser, cp_token *pragma_tok,
+ char *p_name, omp_clause_mask mask, tree *cclauses)
+{
+ tree clauses, sb, ret;
+ unsigned int save;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ strcat (p_name, " distribute");
+ mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+ bool simd = false;
+ bool parallel = false;
+
+ if (strcmp (p, "simd") == 0)
+ simd = true;
+ else
+ parallel = strcmp (p, "parallel") == 0;
+ if (parallel || simd)
+ {
+ tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+ if (cclauses == NULL)
+ cclauses = cclauses_buf;
+ cp_lexer_consume_token (parser->lexer);
+ if (!flag_openmp) /* flag_openmp_simd */
+ {
+ if (simd)
+ return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
+ cclauses);
+ else
+ return cp_parser_omp_parallel (parser, pragma_tok, p_name, mask,
+ cclauses);
+ }
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+ if (simd)
+ ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
+ cclauses);
+ else
+ ret = cp_parser_omp_parallel (parser, pragma_tok, p_name, mask,
+ cclauses);
+ cp_parser_end_omp_structured_block (parser, save);
+ tree body = finish_omp_structured_block (sb);
+ if (ret == NULL)
+ return ret;
+ ret = make_node (OMP_DISTRIBUTE);
+ TREE_TYPE (ret) = void_type_node;
+ OMP_FOR_BODY (ret) = body;
+ OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
+ SET_EXPR_LOCATION (ret, loc);
+ add_stmt (ret);
+ return ret;
+ }
+ }
+ if (!flag_openmp) /* flag_openmp_simd */
+ {
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
+ cclauses == NULL);
+ if (cclauses)
+ {
+ cp_omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
+ }
+
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+
+ ret = cp_parser_omp_for_loop (parser, OMP_DISTRIBUTE, clauses, NULL);
+
+ cp_parser_end_omp_structured_block (parser, save);
+ add_stmt (finish_omp_structured_block (sb));
+
+ return ret;
+}
+
+/* OpenMP 4.0:
+ # pragma omp teams teams-clause[optseq] new-line
+ structured-block */
+
+#define OMP_TEAMS_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
+
+static tree
+cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
+ char *p_name, omp_clause_mask mask, tree *cclauses)
+{
+ tree clauses, sb, ret;
+ unsigned int save;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ strcat (p_name, " teams");
+ mask |= OMP_TEAMS_CLAUSE_MASK;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+ if (strcmp (p, "distribute") == 0)
+ {
+ tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+ if (cclauses == NULL)
+ cclauses = cclauses_buf;
+
+ cp_lexer_consume_token (parser->lexer);
+ if (!flag_openmp) /* flag_openmp_simd */
+ return cp_parser_omp_distribute (parser, pragma_tok, p_name, mask,
+ cclauses);
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+ ret = cp_parser_omp_distribute (parser, pragma_tok, p_name, mask,
+ cclauses);
+ cp_parser_end_omp_structured_block (parser, save);
+ tree body = finish_omp_structured_block (sb);
+ if (ret == NULL)
+ return ret;
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
+ ret = make_node (OMP_TEAMS);
+ TREE_TYPE (ret) = void_type_node;
+ OMP_TEAMS_CLAUSES (ret) = clauses;
+ OMP_TEAMS_BODY (ret) = body;
+ return add_stmt (ret);
+ }
+ }
+ if (!flag_openmp) /* flag_openmp_simd */
+ {
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
+ cclauses == NULL);
+ if (cclauses)
+ {
+ cp_omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
+ }
+
+ tree stmt = make_node (OMP_TEAMS);
+ TREE_TYPE (stmt) = void_type_node;
+ OMP_TEAMS_CLAUSES (stmt) = clauses;
+ OMP_TEAMS_BODY (stmt) = cp_parser_omp_structured_block (parser);
+
+ return add_stmt (stmt);
+}
+
+/* OpenMP 4.0:
+ # pragma omp target data target-data-clause[optseq] new-line
+ structured-block */
+
+#define OMP_TARGET_DATA_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
+
+static tree
+cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok)
+{
+ tree stmt = make_node (OMP_TARGET_DATA);
+ TREE_TYPE (stmt) = void_type_node;
+
+ OMP_TARGET_DATA_CLAUSES (stmt)
+ = cp_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
+ "#pragma omp target data", pragma_tok);
+ keep_next_level (true);
+ OMP_TARGET_DATA_BODY (stmt) = cp_parser_omp_structured_block (parser);
+
+ SET_EXPR_LOCATION (stmt, pragma_tok->location);
+ return add_stmt (stmt);
+}
+
+/* OpenMP 4.0:
+ # pragma omp target update target-update-clause[optseq] new-line */
+
+#define OMP_TARGET_UPDATE_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
+
+static bool
+cp_parser_omp_target_update (cp_parser *parser, cp_token *pragma_tok,
+ enum pragma_context context)
+{
+ if (context == pragma_stmt)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma omp target update%> may only be "
+ "used in compound statements");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return false;
+ }
+
+ tree clauses
+ = cp_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
+ "#pragma omp target update", pragma_tok);
+ if (find_omp_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
+ && find_omp_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma omp target update must contain at least one "
+ "%<from%> or %<to%> clauses");
+ return false;
+ }
+
+ tree stmt = make_node (OMP_TARGET_UPDATE);
+ TREE_TYPE (stmt) = void_type_node;
+ OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
+ SET_EXPR_LOCATION (stmt, pragma_tok->location);
+ add_stmt (stmt);
+ return false;
+}
+
+/* OpenMP 4.0:
+ # pragma omp target target-clause[optseq] new-line
+ structured-block */
+
+#define OMP_TARGET_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
+
+static bool
+cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
+ enum pragma_context context)
+{
+ if (context != pragma_stmt && context != pragma_compound)
+ {
+ cp_parser_error (parser, "expected declaration specifiers");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return false;
+ }
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp (p, "teams") == 0)
+ {
+ tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
+ char p_name[sizeof ("#pragma omp target teams distribute "
+ "parallel for simd")];
+
+ cp_lexer_consume_token (parser->lexer);
+ strcpy (p_name, "#pragma omp target");
+ if (!flag_openmp) /* flag_openmp_simd */
+ return cp_parser_omp_teams (parser, pragma_tok, p_name,
+ OMP_TARGET_CLAUSE_MASK, cclauses);
+ keep_next_level (true);
+ tree sb = begin_omp_structured_block ();
+ unsigned save = cp_parser_begin_omp_structured_block (parser);
+ tree ret = cp_parser_omp_teams (parser, pragma_tok, p_name,
+ OMP_TARGET_CLAUSE_MASK, cclauses);
+ cp_parser_end_omp_structured_block (parser, save);
+ tree body = finish_omp_structured_block (sb);
+ if (ret == NULL)
+ return ret;
+ tree stmt = make_node (OMP_TARGET);
+ TREE_TYPE (stmt) = void_type_node;
+ OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
+ OMP_TARGET_BODY (stmt) = body;
+ add_stmt (stmt);
+ return true;
+ }
+ else if (!flag_openmp) /* flag_openmp_simd */
+ {
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+ else if (strcmp (p, "data") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_omp_target_data (parser, pragma_tok);
+ return true;
+ }
+ else if (strcmp (p, "update") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ return cp_parser_omp_target_update (parser, pragma_tok, context);
+ }
+ }
+
+ tree stmt = make_node (OMP_TARGET);
+ TREE_TYPE (stmt) = void_type_node;
+
+ OMP_TARGET_CLAUSES (stmt)
+ = cp_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
+ "#pragma omp target", pragma_tok);
+ keep_next_level (true);
+ OMP_TARGET_BODY (stmt) = cp_parser_omp_structured_block (parser);
+
+ SET_EXPR_LOCATION (stmt, pragma_tok->location);
+ add_stmt (stmt);
+ return true;
+}
+
+/* OpenMP 4.0:
+ # pragma omp declare simd declare-simd-clauses[optseq] new-line */
+
+#define OMP_DECLARE_SIMD_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
+
+static void
+cp_parser_omp_declare_simd (cp_parser *parser, cp_token *pragma_tok,
+ enum pragma_context context)
+{
+ bool first_p = parser->omp_declare_simd == NULL;
+ cp_omp_declare_simd_data data;
+ if (first_p)
+ {
+ data.error_seen = false;
+ data.fndecl_seen = false;
+ data.tokens = vNULL;
+ parser->omp_declare_simd = &data;
+ }
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_EOF))
+ cp_lexer_consume_token (parser->lexer);
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
+ parser->omp_declare_simd->error_seen = true;
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ struct cp_token_cache *cp
+ = cp_token_cache_new (pragma_tok, cp_lexer_peek_token (parser->lexer));
+ parser->omp_declare_simd->tokens.safe_push (cp);
+ if (first_p)
+ {
+ while (cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA))
+ cp_parser_pragma (parser, context);
+ switch (context)
+ {
+ case pragma_external:
+ cp_parser_declaration (parser);
+ break;
+ case pragma_member:
+ cp_parser_member_declaration (parser);
+ break;
+ case pragma_objc_icode:
+ cp_parser_block_declaration (parser, /*statement_p=*/false);
+ break;
+ default:
+ cp_parser_declaration_statement (parser);
+ break;
+ }
+ if (parser->omp_declare_simd
+ && !parser->omp_declare_simd->error_seen
+ && !parser->omp_declare_simd->fndecl_seen)
+ error_at (pragma_tok->location,
+ "%<#pragma omp declare simd%> not immediately followed by "
+ "function declaration or definition");
+ data.tokens.release ();
+ parser->omp_declare_simd = NULL;
+ }
+}
+
+/* Handles the delayed parsing of the Cilk Plus SIMD-enabled function.
+ This function is modelled similar to the late parsing of omp declare
+ simd. */
+
+static tree
+cp_parser_late_parsing_cilk_simd_fn_info (cp_parser *parser, tree attrs)
+{
+ struct cp_token_cache *ce;
+ cp_omp_declare_simd_data *info = parser->cilk_simd_fn_info;
+ int ii = 0;
+
+ if (parser->omp_declare_simd != NULL)
+ {
+ error ("%<#pragma omp declare simd%> cannot be used in the same function"
+ " marked as a Cilk Plus SIMD-enabled function");
+ XDELETE (parser->cilk_simd_fn_info);
+ parser->cilk_simd_fn_info = NULL;
+ return attrs;
+ }
+ if (!info->error_seen && info->fndecl_seen)
+ {
+ error ("vector attribute not immediately followed by a single function"
+ " declaration or definition");
+ info->error_seen = true;
+ }
+ if (info->error_seen)
+ return attrs;
+
+ FOR_EACH_VEC_ELT (info->tokens, ii, ce)
+ {
+ tree c, cl;
+
+ cp_parser_push_lexer_for_tokens (parser, ce);
+ parser->lexer->in_pragma = true;
+ cl = cp_parser_omp_all_clauses (parser, CILK_SIMD_FN_CLAUSE_MASK,
+ "SIMD-enabled functions attribute",
+ NULL);
+ cp_parser_pop_lexer (parser);
+ if (cl)
+ cl = tree_cons (NULL_TREE, cl, NULL_TREE);
+
+ c = build_tree_list (get_identifier ("cilk simd function"), NULL_TREE);
+ TREE_CHAIN (c) = attrs;
+ attrs = c;
+
+ c = build_tree_list (get_identifier ("omp declare simd"), cl);
+ TREE_CHAIN (c) = attrs;
+ if (processing_template_decl)
+ ATTR_IS_DEPENDENT (c) = 1;
+ attrs = c;
+ }
+ info->fndecl_seen = true;
+ XDELETE (parser->cilk_simd_fn_info);
+ parser->cilk_simd_fn_info = NULL;
+ return attrs;
+}
+
+/* Finalize #pragma omp declare simd clauses after direct declarator has
+ been parsed, and put that into "omp declare simd" attribute. */
+
+static tree
+cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
+{
+ struct cp_token_cache *ce;
+ cp_omp_declare_simd_data *data = parser->omp_declare_simd;
+ int i;
+
+ if (!data->error_seen && data->fndecl_seen)
+ {
+ error ("%<#pragma omp declare simd%> not immediately followed by "
+ "a single function declaration or definition");
+ data->error_seen = true;
+ return attrs;
+ }
+ if (data->error_seen)
+ return attrs;
+
+ FOR_EACH_VEC_ELT (data->tokens, i, ce)
+ {
+ tree c, cl;
+
+ cp_parser_push_lexer_for_tokens (parser, ce);
+ parser->lexer->in_pragma = true;
+ gcc_assert (cp_lexer_peek_token (parser->lexer)->type == CPP_PRAGMA);
+ cp_token *pragma_tok = cp_lexer_consume_token (parser->lexer);
+ cp_lexer_consume_token (parser->lexer);
+ cl = cp_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
+ "#pragma omp declare simd", pragma_tok);
+ cp_parser_pop_lexer (parser);
+ if (cl)
+ cl = tree_cons (NULL_TREE, cl, NULL_TREE);
+ c = build_tree_list (get_identifier ("omp declare simd"), cl);
+ TREE_CHAIN (c) = attrs;
+ if (processing_template_decl)
+ ATTR_IS_DEPENDENT (c) = 1;
+ attrs = c;
+ }
+
+ data->fndecl_seen = true;
+ return attrs;
+}
+
+
+/* OpenMP 4.0:
+ # pragma omp declare target new-line
+ declarations and definitions
+ # pragma omp end declare target new-line */
+
+static void
+cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
+{
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ scope_chain->omp_declare_target_attribute++;
+}
+
+static void
+cp_parser_omp_end_declare_target (cp_parser *parser, cp_token *pragma_tok)
+{
+ const char *p = "";
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ }
+ if (strcmp (p, "declare") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ p = "";
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ }
+ if (strcmp (p, "target") == 0)
+ cp_lexer_consume_token (parser->lexer);
+ else
+ {
+ cp_parser_error (parser, "expected %<target%>");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return;
+ }
+ }
+ else
+ {
+ cp_parser_error (parser, "expected %<declare%>");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return;
+ }
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ if (!scope_chain->omp_declare_target_attribute)
+ error_at (pragma_tok->location,
+ "%<#pragma omp end declare target%> without corresponding "
+ "%<#pragma omp declare target%>");
+ else
+ scope_chain->omp_declare_target_attribute--;
+}
+
+/* Helper function of cp_parser_omp_declare_reduction. Parse the combiner
+ expression and optional initializer clause of
+ #pragma omp declare reduction. We store the expression(s) as
+ either 3, 6 or 7 special statements inside of the artificial function's
+ body. The first two statements are DECL_EXPRs for the artificial
+ OMP_OUT resp. OMP_IN variables, followed by a statement with the combiner
+ expression that uses those variables.
+ If there was any INITIALIZER clause, this is followed by further statements,
+ the fourth and fifth statements are DECL_EXPRs for the artificial
+ OMP_PRIV resp. OMP_ORIG variables. If the INITIALIZER clause wasn't the
+ constructor variant (first token after open paren is not omp_priv),
+ then the sixth statement is a statement with the function call expression
+ that uses the OMP_PRIV and optionally OMP_ORIG variable.
+ Otherwise, the sixth statement is whatever statement cp_finish_decl emits
+ to initialize the OMP_PRIV artificial variable and there is seventh
+ statement, a DECL_EXPR of the OMP_PRIV statement again. */
+
+static bool
+cp_parser_omp_declare_reduction_exprs (tree fndecl, cp_parser *parser)
+{
+ tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
+ gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
+ type = TREE_TYPE (type);
+ tree omp_out = build_lang_decl (VAR_DECL, get_identifier ("omp_out"), type);
+ DECL_ARTIFICIAL (omp_out) = 1;
+ pushdecl (omp_out);
+ add_decl_expr (omp_out);
+ tree omp_in = build_lang_decl (VAR_DECL, get_identifier ("omp_in"), type);
+ DECL_ARTIFICIAL (omp_in) = 1;
+ pushdecl (omp_in);
+ add_decl_expr (omp_in);
+ tree combiner;
+ tree omp_priv = NULL_TREE, omp_orig = NULL_TREE, initializer = NULL_TREE;
+
+ keep_next_level (true);
+ tree block = begin_omp_structured_block ();
+ combiner = cp_parser_expression (parser, false, NULL);
+ finish_expr_stmt (combiner);
+ block = finish_omp_structured_block (block);
+ add_stmt (block);
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ return false;
+
+ const char *p = "";
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ }
+
+ if (strcmp (p, "initializer") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return false;
+
+ p = "";
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ }
+
+ omp_priv = build_lang_decl (VAR_DECL, get_identifier ("omp_priv"), type);
+ DECL_ARTIFICIAL (omp_priv) = 1;
+ pushdecl (omp_priv);
+ add_decl_expr (omp_priv);
+ omp_orig = build_lang_decl (VAR_DECL, get_identifier ("omp_orig"), type);
+ DECL_ARTIFICIAL (omp_orig) = 1;
+ pushdecl (omp_orig);
+ add_decl_expr (omp_orig);
+
+ keep_next_level (true);
+ block = begin_omp_structured_block ();
+
+ bool ctor = false;
+ if (strcmp (p, "omp_priv") == 0)
+ {
+ bool is_direct_init, is_non_constant_init;
+ ctor = true;
+ cp_lexer_consume_token (parser->lexer);
+ /* Reject initializer (omp_priv) and initializer (omp_priv ()). */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)
+ || (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ == CPP_CLOSE_PAREN
+ && cp_lexer_peek_nth_token (parser->lexer, 3)->type
+ == CPP_CLOSE_PAREN))
+ {
+ finish_omp_structured_block (block);
+ error ("invalid initializer clause");
+ return false;
+ }
+ initializer = cp_parser_initializer (parser, &is_direct_init,
+ &is_non_constant_init);
+ cp_finish_decl (omp_priv, initializer, !is_non_constant_init,
+ NULL_TREE, LOOKUP_ONLYCONVERTING);
+ }
+ else
+ {
+ cp_parser_parse_tentatively (parser);
+ tree fn_name = cp_parser_id_expression (parser, /*template_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/NULL,
+ /*declarator_p=*/false,
+ /*optional_p=*/false);
+ vec<tree, va_gc> *args;
+ if (fn_name == error_mark_node
+ || cp_parser_error_occurred (parser)
+ || !cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
+ || ((args = cp_parser_parenthesized_expression_list
+ (parser, non_attr, /*cast_p=*/false,
+ /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL)),
+ cp_parser_error_occurred (parser)))
+ {
+ finish_omp_structured_block (block);
+ cp_parser_abort_tentative_parse (parser);
+ cp_parser_error (parser, "expected id-expression (arguments)");
+ return false;
+ }
+ unsigned int i;
+ tree arg;
+ FOR_EACH_VEC_SAFE_ELT (args, i, arg)
+ if (arg == omp_priv
+ || (TREE_CODE (arg) == ADDR_EXPR
+ && TREE_OPERAND (arg, 0) == omp_priv))
+ break;
+ cp_parser_abort_tentative_parse (parser);
+ if (arg == NULL_TREE)
+ error ("one of the initializer call arguments should be %<omp_priv%>"
+ " or %<&omp_priv%>");
+ initializer = cp_parser_postfix_expression (parser, false, false, false,
+ false, NULL);
+ finish_expr_stmt (initializer);
+ }
+
+ block = finish_omp_structured_block (block);
+ cp_walk_tree (&block, cp_remove_omp_priv_cleanup_stmt, omp_priv, NULL);
+ finish_expr_stmt (block);
+
+ if (ctor)
+ add_decl_expr (omp_orig);
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ return false;
+ }
+
+ if (!cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA_EOL))
+ cp_parser_required_error (parser, RT_PRAGMA_EOL, /*keyword=*/false);
+
+ return true;
+}
+
+/* OpenMP 4.0
+ #pragma omp declare reduction (reduction-id : typename-list : expression) \
+ initializer-clause[opt] new-line
+
+ initializer-clause:
+ initializer (omp_priv initializer)
+ initializer (function-name (argument-list)) */
+
+static void
+cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
+ enum pragma_context)
+{
+ auto_vec<tree> types;
+ enum tree_code reduc_code = ERROR_MARK;
+ tree reduc_id = NULL_TREE, orig_reduc_id = NULL_TREE, type;
+ unsigned int i;
+ cp_token *first_token;
+ cp_token_cache *cp;
+ int errs;
+ void *p;
+
+ /* Get the high-water mark for the DECLARATOR_OBSTACK. */
+ p = obstack_alloc (&declarator_obstack, 0);
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ goto fail;
+
+ switch (cp_lexer_peek_token (parser->lexer)->type)
+ {
+ case CPP_PLUS:
+ reduc_code = PLUS_EXPR;
+ break;
+ case CPP_MULT:
+ reduc_code = MULT_EXPR;
+ break;
+ case CPP_MINUS:
+ reduc_code = MINUS_EXPR;
+ break;
+ case CPP_AND:
+ reduc_code = BIT_AND_EXPR;
+ break;
+ case CPP_XOR:
+ reduc_code = BIT_XOR_EXPR;
+ break;
+ case CPP_OR:
+ reduc_code = BIT_IOR_EXPR;
+ break;
+ case CPP_AND_AND:
+ reduc_code = TRUTH_ANDIF_EXPR;
+ break;
+ case CPP_OR_OR:
+ reduc_code = TRUTH_ORIF_EXPR;
+ break;
+ case CPP_NAME:
+ reduc_id = orig_reduc_id = cp_parser_identifier (parser);
+ break;
+ default:
+ cp_parser_error (parser, "expected %<+%>, %<*%>, %<-%>, %<&%>, %<^%>, "
+ "%<|%>, %<&&%>, %<||%> or identifier");
+ goto fail;
+ }
+
+ if (reduc_code != ERROR_MARK)
+ cp_lexer_consume_token (parser->lexer);
+
+ reduc_id = omp_reduction_id (reduc_code, reduc_id, NULL_TREE);
+ if (reduc_id == error_mark_node)
+ goto fail;
+
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+ goto fail;
+
+ /* Types may not be defined in declare reduction type list. */
+ const char *saved_message;
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = G_("types may not be defined in declare reduction type list");
+ bool saved_colon_corrects_to_scope_p;
+ saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+ parser->colon_corrects_to_scope_p = false;
+ bool saved_colon_doesnt_start_class_def_p;
+ saved_colon_doesnt_start_class_def_p
+ = parser->colon_doesnt_start_class_def_p;
+ parser->colon_doesnt_start_class_def_p = true;
+
+ while (true)
+ {
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+ type = cp_parser_type_id (parser);
+ if (type == error_mark_node)
+ ;
+ else if (ARITHMETIC_TYPE_P (type)
+ && (orig_reduc_id == NULL_TREE
+ || (TREE_CODE (type) != COMPLEX_TYPE
+ && (strcmp (IDENTIFIER_POINTER (orig_reduc_id),
+ "min") == 0
+ || strcmp (IDENTIFIER_POINTER (orig_reduc_id),
+ "max") == 0))))
+ error_at (loc, "predeclared arithmetic type %qT in "
+ "%<#pragma omp declare reduction%>", type);
+ else if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE
+ || TREE_CODE (type) == ARRAY_TYPE)
+ error_at (loc, "function or array type %qT in "
+ "%<#pragma omp declare reduction%>", type);
+ else if (TREE_CODE (type) == REFERENCE_TYPE)
+ error_at (loc, "reference type %qT in "
+ "%<#pragma omp declare reduction%>", type);
+ else if (TYPE_QUALS_NO_ADDR_SPACE (type))
+ error_at (loc, "const, volatile or __restrict qualified type %qT in "
+ "%<#pragma omp declare reduction%>", type);
+ else
+ types.safe_push (type);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ else
+ break;
+ }
+
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+ parser->colon_doesnt_start_class_def_p
+ = saved_colon_doesnt_start_class_def_p;
+
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON)
+ || types.is_empty ())
+ {
+ fail:
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ goto done;
+ }
+
+ first_token = cp_lexer_peek_token (parser->lexer);
+ cp = NULL;
+ errs = errorcount;
+ FOR_EACH_VEC_ELT (types, i, type)
+ {
+ tree fntype
+ = build_function_type_list (void_type_node,
+ cp_build_reference_type (type, false),
+ NULL_TREE);
+ tree this_reduc_id = reduc_id;
+ if (!dependent_type_p (type))
+ this_reduc_id = omp_reduction_id (ERROR_MARK, reduc_id, type);
+ tree fndecl = build_lang_decl (FUNCTION_DECL, this_reduc_id, fntype);
+ DECL_SOURCE_LOCATION (fndecl) = pragma_tok->location;
+ DECL_ARTIFICIAL (fndecl) = 1;
+ DECL_EXTERNAL (fndecl) = 1;
+ DECL_DECLARED_INLINE_P (fndecl) = 1;
+ DECL_IGNORED_P (fndecl) = 1;
+ DECL_OMP_DECLARE_REDUCTION_P (fndecl) = 1;
+ DECL_ATTRIBUTES (fndecl)
+ = tree_cons (get_identifier ("gnu_inline"), NULL_TREE,
+ DECL_ATTRIBUTES (fndecl));
+ if (processing_template_decl)
+ fndecl = push_template_decl (fndecl);
+ bool block_scope = false;
+ tree block = NULL_TREE;
+ if (current_function_decl)
+ {
+ block_scope = true;
+ DECL_CONTEXT (fndecl) = global_namespace;
+ if (!processing_template_decl)
+ pushdecl (fndecl);
+ }
+ else if (current_class_type)
+ {
+ if (cp == NULL)
+ {
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_EOF))
+ cp_lexer_consume_token (parser->lexer);
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
+ goto fail;
+ cp = cp_token_cache_new (first_token,
+ cp_lexer_peek_nth_token (parser->lexer,
+ 2));
+ }
+ DECL_STATIC_FUNCTION_P (fndecl) = 1;
+ finish_member_declaration (fndecl);
+ DECL_PENDING_INLINE_INFO (fndecl) = cp;
+ DECL_PENDING_INLINE_P (fndecl) = 1;
+ vec_safe_push (unparsed_funs_with_definitions, fndecl);
+ continue;
+ }
+ else
+ {
+ DECL_CONTEXT (fndecl) = current_namespace;
+ pushdecl (fndecl);
+ }
+ if (!block_scope)
+ start_preparsed_function (fndecl, NULL_TREE, SF_PRE_PARSED);
+ else
+ block = begin_omp_structured_block ();
+ if (cp)
+ {
+ cp_parser_push_lexer_for_tokens (parser, cp);
+ parser->lexer->in_pragma = true;
+ }
+ if (!cp_parser_omp_declare_reduction_exprs (fndecl, parser))
+ {
+ if (!block_scope)
+ finish_function (0);
+ else
+ DECL_CONTEXT (fndecl) = current_function_decl;
+ if (cp)
+ cp_parser_pop_lexer (parser);
+ goto fail;
+ }
+ if (cp)
+ cp_parser_pop_lexer (parser);
+ if (!block_scope)
+ finish_function (0);
+ else
+ {
+ DECL_CONTEXT (fndecl) = current_function_decl;
+ block = finish_omp_structured_block (block);
+ if (TREE_CODE (block) == BIND_EXPR)
+ DECL_SAVED_TREE (fndecl) = BIND_EXPR_BODY (block);
+ else if (TREE_CODE (block) == STATEMENT_LIST)
+ DECL_SAVED_TREE (fndecl) = block;
+ if (processing_template_decl)
+ add_decl_expr (fndecl);
+ }
+ cp_check_omp_declare_reduction (fndecl);
+ if (cp == NULL && types.length () > 1)
+ cp = cp_token_cache_new (first_token,
+ cp_lexer_peek_nth_token (parser->lexer, 2));
+ if (errs != errorcount)
+ break;
+ }
+
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+
+ done:
+ /* Free any declarators allocated. */
+ obstack_free (&declarator_obstack, p);
+}
+
+/* OpenMP 4.0
+ #pragma omp declare simd declare-simd-clauses[optseq] new-line
+ #pragma omp declare reduction (reduction-id : typename-list : expression) \
+ initializer-clause[opt] new-line
+ #pragma omp declare target new-line */
+
+static void
+cp_parser_omp_declare (cp_parser *parser, cp_token *pragma_tok,
+ enum pragma_context context)
+{
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp (p, "simd") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_omp_declare_simd (parser, pragma_tok,
+ context);
+ return;
+ }
+ cp_ensure_no_omp_declare_simd (parser);
+ if (strcmp (p, "reduction") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_omp_declare_reduction (parser, pragma_tok,
+ context);
+ return;
+ }
+ if (!flag_openmp) /* flag_openmp_simd */
+ {
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ return;
+ }
+ if (strcmp (p, "target") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_omp_declare_target (parser, pragma_tok);
+ return;
+ }
+ }
+ cp_parser_error (parser, "expected %<simd%> or %<reduction%> "
+ "or %<target%>");
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+}
+
+/* Main entry point to OpenMP statement pragmas. */
+
+static void
+cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok)
+{
+ tree stmt;
+ char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
+ omp_clause_mask mask (0);
+
+ switch (pragma_tok->pragma_kind)
+ {
+ case PRAGMA_OMP_ATOMIC:
+ cp_parser_omp_atomic (parser, pragma_tok);
+ return;
+ case PRAGMA_OMP_CRITICAL:
+ stmt = cp_parser_omp_critical (parser, pragma_tok);
+ break;
+ case PRAGMA_OMP_DISTRIBUTE:
+ strcpy (p_name, "#pragma omp");
+ stmt = cp_parser_omp_distribute (parser, pragma_tok, p_name, mask, NULL);
+ break;
+ case PRAGMA_OMP_FOR:
+ strcpy (p_name, "#pragma omp");
+ stmt = cp_parser_omp_for (parser, pragma_tok, p_name, mask, NULL);
+ break;
+ case PRAGMA_OMP_MASTER:
+ stmt = cp_parser_omp_master (parser, pragma_tok);
+ break;
+ case PRAGMA_OMP_ORDERED:
+ stmt = cp_parser_omp_ordered (parser, pragma_tok);
+ break;
+ case PRAGMA_OMP_PARALLEL:
+ strcpy (p_name, "#pragma omp");
+ stmt = cp_parser_omp_parallel (parser, pragma_tok, p_name, mask, NULL);
+ break;
+ case PRAGMA_OMP_SECTIONS:
+ strcpy (p_name, "#pragma omp");
+ stmt = cp_parser_omp_sections (parser, pragma_tok, p_name, mask, NULL);
+ break;
+ case PRAGMA_OMP_SIMD:
+ strcpy (p_name, "#pragma omp");
+ stmt = cp_parser_omp_simd (parser, pragma_tok, p_name, mask, NULL);
+ break;
+ case PRAGMA_OMP_SINGLE:
+ stmt = cp_parser_omp_single (parser, pragma_tok);
+ break;
+ case PRAGMA_OMP_TASK:
+ stmt = cp_parser_omp_task (parser, pragma_tok);
+ break;
+ case PRAGMA_OMP_TASKGROUP:
+ stmt = cp_parser_omp_taskgroup (parser, pragma_tok);
+ break;
+ case PRAGMA_OMP_TEAMS:
+ strcpy (p_name, "#pragma omp");
+ stmt = cp_parser_omp_teams (parser, pragma_tok, p_name, mask, NULL);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (stmt)
+ SET_EXPR_LOCATION (stmt, pragma_tok->location);
+}
+
+/* Transactional Memory parsing routines. */
+
+/* Parse a transaction attribute.
+
+ txn-attribute:
+ attribute
+ [ [ identifier ] ]
+
+ ??? Simplify this when C++0x bracket attributes are
+ implemented properly. */
+
+static tree
+cp_parser_txn_attribute_opt (cp_parser *parser)
+{
+ cp_token *token;
+ tree attr_name, attr = NULL;
+
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
+ return cp_parser_attributes_opt (parser);
+
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_SQUARE))
+ return NULL_TREE;
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE))
+ goto error1;
+
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_NAME || token->type == CPP_KEYWORD)
+ {
+ token = cp_lexer_consume_token (parser->lexer);
+
+ attr_name = (token->type == CPP_KEYWORD
+ /* For keywords, use the canonical spelling,
+ not the parsed identifier. */
+ ? ridpointers[(int) token->keyword]
+ : token->u.value);
+ attr = build_tree_list (attr_name, NULL_TREE);
+ }
+ else
+ cp_parser_error (parser, "expected identifier");
+
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+ error1:
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+ return attr;
+}
+
+/* Parse a __transaction_atomic or __transaction_relaxed statement.
+
+ transaction-statement:
+ __transaction_atomic txn-attribute[opt] txn-noexcept-spec[opt]
+ compound-statement
+ __transaction_relaxed txn-noexcept-spec[opt] compound-statement
+*/
+
+static tree
+cp_parser_transaction (cp_parser *parser, enum rid keyword)
+{
+ unsigned char old_in = parser->in_transaction;
+ unsigned char this_in = 1, new_in;
+ cp_token *token;
+ tree stmt, attrs, noex;
+
+ gcc_assert (keyword == RID_TRANSACTION_ATOMIC
+ || keyword == RID_TRANSACTION_RELAXED);
+ token = cp_parser_require_keyword (parser, keyword,
+ (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
+ : RT_TRANSACTION_RELAXED));
+ gcc_assert (token != NULL);
+
+ if (keyword == RID_TRANSACTION_RELAXED)
+ this_in |= TM_STMT_ATTR_RELAXED;
+ else
+ {
+ attrs = cp_parser_txn_attribute_opt (parser);
+ if (attrs)
+ this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
+ }
+
+ /* Parse a noexcept specification. */
+ noex = cp_parser_noexcept_specification_opt (parser, true, NULL, true);
+
+ /* Keep track if we're in the lexical scope of an outer transaction. */
+ new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
+
+ stmt = begin_transaction_stmt (token->location, NULL, this_in);
+
+ parser->in_transaction = new_in;
+ cp_parser_compound_statement (parser, NULL, false, false);
+ parser->in_transaction = old_in;
+
+ finish_transaction_stmt (stmt, NULL, this_in, noex);
+
+ return stmt;
+}
+
+/* Parse a __transaction_atomic or __transaction_relaxed expression.
+
+ transaction-expression:
+ __transaction_atomic txn-noexcept-spec[opt] ( expression )
+ __transaction_relaxed txn-noexcept-spec[opt] ( expression )
+*/
+
+static tree
+cp_parser_transaction_expression (cp_parser *parser, enum rid keyword)
+{
+ unsigned char old_in = parser->in_transaction;
+ unsigned char this_in = 1;
+ cp_token *token;
+ tree expr, noex;
+ bool noex_expr;
+
+ gcc_assert (keyword == RID_TRANSACTION_ATOMIC
+ || keyword == RID_TRANSACTION_RELAXED);
+
+ if (!flag_tm)
+ error (keyword == RID_TRANSACTION_RELAXED
+ ? G_("%<__transaction_relaxed%> without transactional memory "
+ "support enabled")
+ : G_("%<__transaction_atomic%> without transactional memory "
+ "support enabled"));
+
+ token = cp_parser_require_keyword (parser, keyword,
+ (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
+ : RT_TRANSACTION_RELAXED));
+ gcc_assert (token != NULL);
+
+ if (keyword == RID_TRANSACTION_RELAXED)
+ this_in |= TM_STMT_ATTR_RELAXED;
+
+ /* Set this early. This might mean that we allow transaction_cancel in
+ an expression that we find out later actually has to be a constexpr.
+ However, we expect that cxx_constant_value will be able to deal with
+ this; also, if the noexcept has no constexpr, then what we parse next
+ really is a transaction's body. */
+ parser->in_transaction = this_in;
+
+ /* Parse a noexcept specification. */
+ noex = cp_parser_noexcept_specification_opt (parser, false, &noex_expr,
+ true);
+
+ if (!noex || !noex_expr
+ || cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
+ {
+ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+ expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ expr = finish_parenthesized_expr (expr);
+
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ }
+ else
+ {
+ /* The only expression that is available got parsed for the noexcept
+ already. noexcept is true then. */
+ expr = noex;
+ noex = boolean_true_node;
+ }
+
+ expr = build_transaction_expr (token->location, expr, this_in, noex);
+ parser->in_transaction = old_in;
+
+ if (cp_parser_non_integral_constant_expression (parser, NIC_TRANSACTION))
+ return error_mark_node;
+
+ return (flag_tm ? expr : error_mark_node);
+}
+
+/* Parse a function-transaction-block.
+
+ function-transaction-block:
+ __transaction_atomic txn-attribute[opt] ctor-initializer[opt]
+ function-body
+ __transaction_atomic txn-attribute[opt] function-try-block
+ __transaction_relaxed ctor-initializer[opt] function-body
+ __transaction_relaxed function-try-block
+*/
+
+static bool
+cp_parser_function_transaction (cp_parser *parser, enum rid keyword)
+{
+ unsigned char old_in = parser->in_transaction;
+ unsigned char new_in = 1;
+ tree compound_stmt, stmt, attrs;
+ bool ctor_initializer_p;
+ cp_token *token;
+
+ gcc_assert (keyword == RID_TRANSACTION_ATOMIC
+ || keyword == RID_TRANSACTION_RELAXED);
+ token = cp_parser_require_keyword (parser, keyword,
+ (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
+ : RT_TRANSACTION_RELAXED));
+ gcc_assert (token != NULL);
+
+ if (keyword == RID_TRANSACTION_RELAXED)
+ new_in |= TM_STMT_ATTR_RELAXED;
+ else
+ {
+ attrs = cp_parser_txn_attribute_opt (parser);
+ if (attrs)
+ new_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
+ }
+
+ stmt = begin_transaction_stmt (token->location, &compound_stmt, new_in);
+
+ parser->in_transaction = new_in;
+
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
+ ctor_initializer_p = cp_parser_function_try_block (parser);
+ else
+ ctor_initializer_p = cp_parser_ctor_initializer_opt_and_function_body
+ (parser, /*in_function_try_block=*/false);
+
+ parser->in_transaction = old_in;
+
+ finish_transaction_stmt (stmt, compound_stmt, new_in, NULL_TREE);
+
+ return ctor_initializer_p;
+}
+
+/* Parse a __transaction_cancel statement.
+
+ cancel-statement:
+ __transaction_cancel txn-attribute[opt] ;
+ __transaction_cancel txn-attribute[opt] throw-expression ;
+
+ ??? Cancel and throw is not yet implemented. */
+
+static tree
+cp_parser_transaction_cancel (cp_parser *parser)
+{
+ cp_token *token;
+ bool is_outer = false;
+ tree stmt, attrs;
+
+ token = cp_parser_require_keyword (parser, RID_TRANSACTION_CANCEL,
+ RT_TRANSACTION_CANCEL);
+ gcc_assert (token != NULL);
+
+ attrs = cp_parser_txn_attribute_opt (parser);
+ if (attrs)
+ is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
+
+ /* ??? Parse cancel-and-throw here. */
+
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+ if (!flag_tm)
+ {
+ error_at (token->location, "%<__transaction_cancel%> without "
+ "transactional memory support enabled");
+ return error_mark_node;
+ }
+ else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
+ {
+ error_at (token->location, "%<__transaction_cancel%> within a "
+ "%<__transaction_relaxed%>");
+ return error_mark_node;
+ }
+ else if (is_outer)
+ {
+ if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
+ && !is_tm_may_cancel_outer (current_function_decl))
+ {
+ error_at (token->location, "outer %<__transaction_cancel%> not "
+ "within outer %<__transaction_atomic%>");
+ error_at (token->location,
+ " or a %<transaction_may_cancel_outer%> function");
+ return error_mark_node;
+ }
+ }
+ else if (parser->in_transaction == 0)
+ {
+ error_at (token->location, "%<__transaction_cancel%> not within "
+ "%<__transaction_atomic%>");
+ return error_mark_node;
+ }
+
+ stmt = build_tm_abort_call (token->location, is_outer);
+ add_stmt (stmt);
+
+ return stmt;
+}
+
+/* The parser. */
+
+static GTY (()) cp_parser *the_parser;
+
+
+/* Special handling for the first token or line in the file. The first
+ thing in the file might be #pragma GCC pch_preprocess, which loads a
+ PCH file, which is a GC collection point. So we need to handle this
+ first pragma without benefit of an existing lexer structure.
+
+ Always returns one token to the caller in *FIRST_TOKEN. This is
+ either the true first token of the file, or the first token after
+ the initial pragma. */
+
+static void
+cp_parser_initial_pragma (cp_token *first_token)
+{
+ tree name = NULL;
+
+ cp_lexer_get_preprocessor_token (NULL, first_token);
+ if (first_token->pragma_kind != PRAGMA_GCC_PCH_PREPROCESS)
+ return;
+
+ cp_lexer_get_preprocessor_token (NULL, first_token);
+ if (first_token->type == CPP_STRING)
+ {
+ name = first_token->u.value;
+
+ cp_lexer_get_preprocessor_token (NULL, first_token);
+ if (first_token->type != CPP_PRAGMA_EOL)
+ error_at (first_token->location,
+ "junk at end of %<#pragma GCC pch_preprocess%>");
+ }
+ else
+ error_at (first_token->location, "expected string literal");
+
+ /* Skip to the end of the pragma. */
+ while (first_token->type != CPP_PRAGMA_EOL && first_token->type != CPP_EOF)
+ cp_lexer_get_preprocessor_token (NULL, first_token);
+
+ /* Now actually load the PCH file. */
+ if (name)
+ c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
+
+ /* Read one more token to return to our caller. We have to do this
+ after reading the PCH file in, since its pointers have to be
+ live. */
+ cp_lexer_get_preprocessor_token (NULL, first_token);
+}
+
+/* Normal parsing of a pragma token. Here we can (and must) use the
+ regular lexer. */
+
+static bool
+cp_parser_pragma (cp_parser *parser, enum pragma_context context)
+{
+ cp_token *pragma_tok;
+ unsigned int id;
+
+ pragma_tok = cp_lexer_consume_token (parser->lexer);
+ gcc_assert (pragma_tok->type == CPP_PRAGMA);
+ parser->lexer->in_pragma = true;
+
+ id = pragma_tok->pragma_kind;
+ if (id != PRAGMA_OMP_DECLARE_REDUCTION)
+ cp_ensure_no_omp_declare_simd (parser);
+ switch (id)
+ {
+ case PRAGMA_GCC_PCH_PREPROCESS:
+ error_at (pragma_tok->location,
+ "%<#pragma GCC pch_preprocess%> must be first");
+ break;
+
+ case PRAGMA_OMP_BARRIER:
+ switch (context)
+ {
+ case pragma_compound:
+ cp_parser_omp_barrier (parser, pragma_tok);
+ return false;
+ case pragma_stmt:
+ error_at (pragma_tok->location, "%<#pragma omp barrier%> may only be "
+ "used in compound statements");
+ break;
+ default:
+ goto bad_stmt;
+ }
+ break;
+
+ case PRAGMA_OMP_FLUSH:
+ switch (context)
+ {
+ case pragma_compound:
+ cp_parser_omp_flush (parser, pragma_tok);
+ return false;
+ case pragma_stmt:
+ error_at (pragma_tok->location, "%<#pragma omp flush%> may only be "
+ "used in compound statements");
+ break;
+ default:
+ goto bad_stmt;
+ }
+ break;
+
+ case PRAGMA_OMP_TASKWAIT:
+ switch (context)
+ {
+ case pragma_compound:
+ cp_parser_omp_taskwait (parser, pragma_tok);
+ return false;
+ case pragma_stmt:
+ error_at (pragma_tok->location,
+ "%<#pragma omp taskwait%> may only be "
+ "used in compound statements");
+ break;
+ default:
+ goto bad_stmt;
+ }
+ break;
+
+ case PRAGMA_OMP_TASKYIELD:
+ switch (context)
+ {
+ case pragma_compound:
+ cp_parser_omp_taskyield (parser, pragma_tok);
+ return false;
+ case pragma_stmt:
+ error_at (pragma_tok->location,
+ "%<#pragma omp taskyield%> may only be "
+ "used in compound statements");
+ break;
+ default:
+ goto bad_stmt;
+ }
+ break;
+
+ case PRAGMA_OMP_CANCEL:
+ switch (context)
+ {
+ case pragma_compound:
+ cp_parser_omp_cancel (parser, pragma_tok);
+ return false;
+ case pragma_stmt:
+ error_at (pragma_tok->location,
+ "%<#pragma omp cancel%> may only be "
+ "used in compound statements");
+ break;
+ default:
+ goto bad_stmt;
+ }
+ break;
+
+ case PRAGMA_OMP_CANCELLATION_POINT:
+ switch (context)
+ {
+ case pragma_compound:
+ cp_parser_omp_cancellation_point (parser, pragma_tok);
+ return false;
+ case pragma_stmt:
+ error_at (pragma_tok->location,
+ "%<#pragma omp cancellation point%> may only be "
+ "used in compound statements");
+ break;
+ default:
+ goto bad_stmt;
+ }
+ break;
+
+ case PRAGMA_OMP_THREADPRIVATE:
+ cp_parser_omp_threadprivate (parser, pragma_tok);
+ return false;
+
+ case PRAGMA_OMP_DECLARE_REDUCTION:
+ cp_parser_omp_declare (parser, pragma_tok, context);
+ return false;
+
+ case PRAGMA_OMP_ATOMIC:
+ case PRAGMA_OMP_CRITICAL:
+ case PRAGMA_OMP_DISTRIBUTE:
+ case PRAGMA_OMP_FOR:
+ case PRAGMA_OMP_MASTER:
+ case PRAGMA_OMP_ORDERED:
+ case PRAGMA_OMP_PARALLEL:
+ case PRAGMA_OMP_SECTIONS:
+ case PRAGMA_OMP_SIMD:
+ case PRAGMA_OMP_SINGLE:
+ case PRAGMA_OMP_TASK:
+ case PRAGMA_OMP_TASKGROUP:
+ case PRAGMA_OMP_TEAMS:
+ if (context != pragma_stmt && context != pragma_compound)
+ goto bad_stmt;
+ cp_parser_omp_construct (parser, pragma_tok);
+ return true;
+
+ case PRAGMA_OMP_TARGET:
+ return cp_parser_omp_target (parser, pragma_tok, context);
+
+ case PRAGMA_OMP_END_DECLARE_TARGET:
+ cp_parser_omp_end_declare_target (parser, pragma_tok);
+ return false;
+
+ case PRAGMA_OMP_SECTION:
+ error_at (pragma_tok->location,
+ "%<#pragma omp section%> may only be used in "
+ "%<#pragma omp sections%> construct");
+ break;
+
+ case PRAGMA_IVDEP:
+ {
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ cp_token *tok;
+ tok = cp_lexer_peek_token (the_parser->lexer);
+ if (tok->type != CPP_KEYWORD
+ || (tok->keyword != RID_FOR && tok->keyword != RID_WHILE
+ && tok->keyword != RID_DO))
+ {
+ cp_parser_error (parser, "for, while or do statement expected");
+ return false;
+ }
+ cp_parser_iteration_statement (parser, true);
+ return true;
+ }
+
+ case PRAGMA_CILK_SIMD:
+ if (context == pragma_external)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma simd%> must be inside a function");
+ break;
+ }
+ cp_parser_cilk_simd (parser, pragma_tok);
+ return true;
+
+ default:
+ gcc_assert (id >= PRAGMA_FIRST_EXTERNAL);
+ c_invoke_pragma_handler (id);
+ break;
+
+ bad_stmt:
+ cp_parser_error (parser, "expected declaration specifiers");
+ break;
+ }
+
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return false;
+}
+
+/* The interface the pragma parsers have to the lexer. */
+
+enum cpp_ttype
+pragma_lex (tree *value)
+{
+ cp_token *tok;
+ enum cpp_ttype ret;
+
+ tok = cp_lexer_peek_token (the_parser->lexer);
+
+ ret = tok->type;
+ *value = tok->u.value;
+
+ if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
+ ret = CPP_EOF;
+ else if (ret == CPP_STRING)
+ *value = cp_parser_string_literal (the_parser, false, false);
+ else
+ {
+ cp_lexer_consume_token (the_parser->lexer);
+ if (ret == CPP_KEYWORD)
+ ret = CPP_NAME;
+ }
+
+ return ret;
+}
+
+
+/* External interface. */
+
+/* Parse one entire translation unit. */
+
+void
+c_parse_file (void)
+{
+ static bool already_called = false;
+
+ if (already_called)
+ {
+ sorry ("inter-module optimizations not implemented for C++");
+ return;
+ }
+ already_called = true;
+
+ the_parser = cp_parser_new ();
+ push_deferring_access_checks (flag_access_control
+ ? dk_no_deferred : dk_no_check);
+ cp_parser_translation_unit (the_parser);
+ the_parser = NULL;
+}
+
+/* Parses the Cilk Plus #pragma simd and SIMD-enabled function attribute's
+ vectorlength clause:
+ Syntax:
+ vectorlength ( constant-expression ) */
+
+static tree
+cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses,
+ bool is_simd_fn)
+{
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+ tree expr;
+ /* The vectorlength clause in #pragma simd behaves exactly like OpenMP's
+ safelen clause. Thus, vectorlength is represented as OMP 4.0
+ safelen. For SIMD-enabled function it is represented by OMP 4.0
+ simdlen. */
+ if (!is_simd_fn)
+ check_no_duplicate_clause (clauses, OMP_CLAUSE_SAFELEN, "vectorlength",
+ loc);
+ else
+ check_no_duplicate_clause (clauses, OMP_CLAUSE_SIMDLEN, "vectorlength",
+ loc);
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return error_mark_node;
+
+ expr = cp_parser_constant_expression (parser, false, NULL);
+ expr = maybe_constant_value (expr);
+
+ /* If expr == error_mark_node, then don't emit any errors nor
+ create a clause. if any of the above functions returns
+ error mark node then they would have emitted an error message. */
+ if (expr == error_mark_node)
+ ;
+ else if (!TREE_TYPE (expr)
+ || !TREE_CONSTANT (expr)
+ || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
+ error_at (loc, "vectorlength must be an integer constant");
+ else if (TREE_CONSTANT (expr)
+ && exact_log2 (TREE_INT_CST_LOW (expr)) == -1)
+ error_at (loc, "vectorlength must be a power of 2");
+ else
+ {
+ tree c;
+ if (!is_simd_fn)
+ {
+ c = build_omp_clause (loc, OMP_CLAUSE_SAFELEN);
+ OMP_CLAUSE_SAFELEN_EXPR (c) = expr;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ else
+ {
+ c = build_omp_clause (loc, OMP_CLAUSE_SIMDLEN);
+ OMP_CLAUSE_SIMDLEN_EXPR (c) = expr;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ }
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ return error_mark_node;
+ return clauses;
+}
+
+/* Handles the Cilk Plus #pragma simd linear clause.
+ Syntax:
+ linear ( simd-linear-variable-list )
+
+ simd-linear-variable-list:
+ simd-linear-variable
+ simd-linear-variable-list , simd-linear-variable
+
+ simd-linear-variable:
+ id-expression
+ id-expression : simd-linear-step
+
+ simd-linear-step:
+ conditional-expression */
+
+static tree
+cp_parser_cilk_simd_linear (cp_parser *parser, tree clauses)
+{
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return clauses;
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
+ {
+ cp_parser_error (parser, "expected identifier");
+ cp_parser_skip_to_closing_parenthesis (parser, false, false, true);
+ return error_mark_node;
+ }
+
+ bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+ parser->colon_corrects_to_scope_p = false;
+ while (1)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
+ {
+ cp_parser_error (parser, "expected variable-name");
+ clauses = error_mark_node;
+ break;
+ }
+
+ tree var_name = cp_parser_id_expression (parser, false, true, NULL,
+ false, false);
+ tree decl = cp_parser_lookup_name_simple (parser, var_name,
+ token->location);
+ if (decl == error_mark_node)
+ {
+ cp_parser_name_lookup_error (parser, var_name, decl, NLE_NULL,
+ token->location);
+ clauses = error_mark_node;
+ }
+ else
+ {
+ tree e = NULL_TREE;
+ tree step_size = integer_one_node;
+
+ /* If present, parse the linear step. Otherwise, assume the default
+ value of 1. */
+ if (cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
+ {
+ cp_lexer_consume_token (parser->lexer);
+
+ e = cp_parser_assignment_expression (parser, false, NULL);
+ e = maybe_constant_value (e);
+
+ if (e == error_mark_node)
+ {
+ /* If an error has occurred, then the whole pragma is
+ considered ill-formed. Thus, no reason to keep
+ parsing. */
+ clauses = error_mark_node;
+ break;
+ }
+ else if (type_dependent_expression_p (e)
+ || value_dependent_expression_p (e)
+ || (TREE_TYPE (e)
+ && INTEGRAL_TYPE_P (TREE_TYPE (e))
+ && (TREE_CONSTANT (e)
+ || DECL_P (e))))
+ step_size = e;
+ else
+ cp_parser_error (parser,
+ "step size must be an integer constant "
+ "expression or an integer variable");
+ }
+
+ /* Use the OMP_CLAUSE_LINEAR, which has the same semantics. */
+ tree l = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
+ OMP_CLAUSE_DECL (l) = decl;
+ OMP_CLAUSE_LINEAR_STEP (l) = step_size;
+ OMP_CLAUSE_CHAIN (l) = clauses;
+ clauses = l;
+ }
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
+ break;
+ else
+ {
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "expected %<,%> or %<)%> after %qE", decl);
+ clauses = error_mark_node;
+ break;
+ }
+ }
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+ cp_parser_skip_to_closing_parenthesis (parser, false, false, true);
+ return clauses;
+}
+
+/* Returns the name of the next clause. If the clause is not
+ recognized, then PRAGMA_CILK_CLAUSE_NONE is returned and the next
+ token is not consumed. Otherwise, the appropriate enum from the
+ pragma_simd_clause is returned and the token is consumed. */
+
+static pragma_omp_clause
+cp_parser_cilk_simd_clause_name (cp_parser *parser)
+{
+ pragma_omp_clause clause_type;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ if (token->keyword == RID_PRIVATE)
+ clause_type = PRAGMA_CILK_CLAUSE_PRIVATE;
+ else if (!token->u.value || token->type != CPP_NAME)
+ return PRAGMA_CILK_CLAUSE_NONE;
+ else if (!strcmp (IDENTIFIER_POINTER (token->u.value), "vectorlength"))
+ clause_type = PRAGMA_CILK_CLAUSE_VECTORLENGTH;
+ else if (!strcmp (IDENTIFIER_POINTER (token->u.value), "linear"))
+ clause_type = PRAGMA_CILK_CLAUSE_LINEAR;
+ else if (!strcmp (IDENTIFIER_POINTER (token->u.value), "firstprivate"))
+ clause_type = PRAGMA_CILK_CLAUSE_FIRSTPRIVATE;
+ else if (!strcmp (IDENTIFIER_POINTER (token->u.value), "lastprivate"))
+ clause_type = PRAGMA_CILK_CLAUSE_LASTPRIVATE;
+ else if (!strcmp (IDENTIFIER_POINTER (token->u.value), "reduction"))
+ clause_type = PRAGMA_CILK_CLAUSE_REDUCTION;
+ else
+ return PRAGMA_CILK_CLAUSE_NONE;
+
+ cp_lexer_consume_token (parser->lexer);
+ return clause_type;
+}
+
+/* Parses all the #pragma simd clauses. Returns a list of clauses found. */
+
+static tree
+cp_parser_cilk_simd_all_clauses (cp_parser *parser, cp_token *pragma_token)
+{
+ tree clauses = NULL_TREE;
+
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL)
+ && clauses != error_mark_node)
+ {
+ pragma_omp_clause c_kind;
+ c_kind = cp_parser_cilk_simd_clause_name (parser);
+ if (c_kind == PRAGMA_CILK_CLAUSE_VECTORLENGTH)
+ clauses = cp_parser_cilk_simd_vectorlength (parser, clauses, false);
+ else if (c_kind == PRAGMA_CILK_CLAUSE_LINEAR)
+ clauses = cp_parser_cilk_simd_linear (parser, clauses);
+ else if (c_kind == PRAGMA_CILK_CLAUSE_PRIVATE)
+ /* Use the OpenMP 4.0 equivalent function. */
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_PRIVATE, clauses);
+ else if (c_kind == PRAGMA_CILK_CLAUSE_FIRSTPRIVATE)
+ /* Use the OpenMP 4.0 equivalent function. */
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FIRSTPRIVATE,
+ clauses);
+ else if (c_kind == PRAGMA_CILK_CLAUSE_LASTPRIVATE)
+ /* Use the OMP 4.0 equivalent function. */
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_LASTPRIVATE,
+ clauses);
+ else if (c_kind == PRAGMA_CILK_CLAUSE_REDUCTION)
+ /* Use the OMP 4.0 equivalent function. */
+ clauses = cp_parser_omp_clause_reduction (parser, clauses);
+ else
+ {
+ clauses = error_mark_node;
+ cp_parser_error (parser, "expected %<#pragma simd%> clause");
+ break;
+ }
+ }
+
+ cp_parser_skip_to_pragma_eol (parser, pragma_token);
+
+ if (clauses == error_mark_node)
+ return error_mark_node;
+ else
+ return c_finish_cilk_clauses (clauses);
+}
+
+/* Main entry-point for parsing Cilk Plus <#pragma simd> for loops. */
+
+static void
+cp_parser_cilk_simd (cp_parser *parser, cp_token *pragma_token)
+{
+ tree clauses = cp_parser_cilk_simd_all_clauses (parser, pragma_token);
+
+ if (clauses == error_mark_node)
+ return;
+
+ if (cp_lexer_next_token_is_not_keyword (parser->lexer, RID_FOR))
+ {
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "for statement expected");
+ return;
+ }
+
+ tree sb = begin_omp_structured_block ();
+ int save = cp_parser_begin_omp_structured_block (parser);
+ tree ret = cp_parser_omp_for_loop (parser, CILK_SIMD, clauses, NULL);
+ if (ret)
+ cpp_validate_cilk_plus_loop (OMP_FOR_BODY (ret));
+ cp_parser_end_omp_structured_block (parser, save);
+ add_stmt (finish_omp_structured_block (sb));
+ return;
+}
+
+/* Create an identifier for a generic parameter type (a synthesized
+ template parameter implied by `auto' or a concept identifier). */
+
+static GTY(()) int generic_parm_count;
+static tree
+make_generic_type_name ()
+{
+ char buf[32];
+ sprintf (buf, "auto:%d", ++generic_parm_count);
+ return get_identifier (buf);
+}
+
+/* Predicate that behaves as is_auto_or_concept but matches the parent
+ node of the generic type rather than the generic type itself. This
+ allows for type transformation in add_implicit_template_parms. */
+
+static inline bool
+tree_type_is_auto_or_concept (const_tree t)
+{
+ return TREE_TYPE (t) && is_auto_or_concept (TREE_TYPE (t));
+}
+
+/* Add an implicit template type parameter to the CURRENT_TEMPLATE_PARMS
+ (creating a new template parameter list if necessary). Returns the newly
+ created template type parm. */
+
+tree
+synthesize_implicit_template_parm (cp_parser *parser)
+{
+ gcc_assert (current_binding_level->kind == sk_function_parms);
+
+ /* We are either continuing a function template that already contains implicit
+ template parameters, creating a new fully-implicit function template, or
+ extending an existing explicit function template with implicit template
+ parameters. */
+
+ cp_binding_level *const entry_scope = current_binding_level;
+
+ bool become_template = false;
+ cp_binding_level *parent_scope = 0;
+
+ if (parser->implicit_template_scope)
+ {
+ gcc_assert (parser->implicit_template_parms);
+
+ current_binding_level = parser->implicit_template_scope;
+ }
+ else
+ {
+ /* Roll back to the existing template parameter scope (in the case of
+ extending an explicit function template) or introduce a new template
+ parameter scope ahead of the function parameter scope (or class scope
+ in the case of out-of-line member definitions). The function scope is
+ added back after template parameter synthesis below. */
+
+ cp_binding_level *scope = entry_scope;
+
+ while (scope->kind == sk_function_parms)
+ {
+ parent_scope = scope;
+ scope = scope->level_chain;
+ }
+ if (current_class_type && !LAMBDA_TYPE_P (current_class_type))
+ {
+ /* If not defining a class, then any class scope is a scope level in
+ an out-of-line member definition. In this case simply wind back
+ beyond the first such scope to inject the template argument list.
+ Otherwise wind back to the class being defined. The latter can
+ occur in class member friend declarations such as:
+
+ class A {
+ void foo (auto);
+ };
+ class B {
+ friend void A::foo (auto);
+ };
+
+ The template argument list synthesized for the friend declaration
+ must be injected in the scope of 'B', just beyond the scope of 'A'
+ introduced by 'A::'. */
+
+ while (scope->kind == sk_class
+ && !TYPE_BEING_DEFINED (scope->this_entity))
+ {
+ parent_scope = scope;
+ scope = scope->level_chain;
+ }
+ }
+
+ current_binding_level = scope;
+
+ if (scope->kind != sk_template_parms
+ || !function_being_declared_is_template_p (parser))
+ {
+ /* Introduce a new template parameter list for implicit template
+ parameters. */
+
+ become_template = true;
+
+ parser->implicit_template_scope
+ = begin_scope (sk_template_parms, NULL);
+
+ ++processing_template_decl;
+
+ parser->fully_implicit_function_template_p = true;
+ ++parser->num_template_parameter_lists;
+ }
+ else
+ {
+ /* Synthesize implicit template parameters at the end of the explicit
+ template parameter list. */
+
+ gcc_assert (current_template_parms);
+
+ parser->implicit_template_scope = scope;
+
+ tree v = INNERMOST_TEMPLATE_PARMS (current_template_parms);
+ parser->implicit_template_parms
+ = TREE_VEC_ELT (v, TREE_VEC_LENGTH (v) - 1);
+ }
+ }
+
+ /* Synthesize a new template parameter and track the current template
+ parameter chain with implicit_template_parms. */
+
+ tree synth_id = make_generic_type_name ();
+ tree synth_tmpl_parm = finish_template_type_parm (class_type_node,
+ synth_id);
+ tree new_parm
+ = process_template_parm (parser->implicit_template_parms,
+ input_location,
+ build_tree_list (NULL_TREE, synth_tmpl_parm),
+ /*non_type=*/false,
+ /*param_pack=*/false);
+
+
+ if (parser->implicit_template_parms)
+ parser->implicit_template_parms
+ = TREE_CHAIN (parser->implicit_template_parms);
+ else
+ parser->implicit_template_parms = new_parm;
+
+ tree new_type = TREE_TYPE (getdecls ());
+
+ /* If creating a fully implicit function template, start the new implicit
+ template parameter list with this synthesized type, otherwise grow the
+ current template parameter list. */
+
+ if (become_template)
+ {
+ parent_scope->level_chain = current_binding_level;
+
+ tree new_parms = make_tree_vec (1);
+ TREE_VEC_ELT (new_parms, 0) = parser->implicit_template_parms;
+ current_template_parms = tree_cons (size_int (processing_template_decl),
+ new_parms, current_template_parms);
+ }
+ else
+ {
+ tree& new_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
+ int new_parm_idx = TREE_VEC_LENGTH (new_parms);
+ new_parms = grow_tree_vec (new_parms, new_parm_idx + 1);
+ TREE_VEC_ELT (new_parms, new_parm_idx) = parser->implicit_template_parms;
+ }
+
+ current_binding_level = entry_scope;
+
+ return new_type;
+}
+
+/* Finish the declaration of a fully implicit function template. Such a
+ template has no explicit template parameter list so has not been through the
+ normal template head and tail processing. synthesize_implicit_template_parm
+ tries to do the head; this tries to do the tail. MEMBER_DECL_OPT should be
+ provided if the declaration is a class member such that its template
+ declaration can be completed. If MEMBER_DECL_OPT is provided the finished
+ form is returned. Otherwise NULL_TREE is returned. */
+
+tree
+finish_fully_implicit_template (cp_parser *parser, tree member_decl_opt)
+{
+ gcc_assert (parser->fully_implicit_function_template_p);
+
+ if (member_decl_opt && member_decl_opt != error_mark_node
+ && DECL_VIRTUAL_P (member_decl_opt))
+ {
+ error_at (DECL_SOURCE_LOCATION (member_decl_opt),
+ "implicit templates may not be %<virtual%>");
+ DECL_VIRTUAL_P (member_decl_opt) = false;
+ }
+
+ if (member_decl_opt)
+ member_decl_opt = finish_member_template_decl (member_decl_opt);
+ end_template_decl ();
+
+ parser->fully_implicit_function_template_p = false;
+ --parser->num_template_parameter_lists;
+
+ return member_decl_opt;
+}
+
+#include "gt-cp-parser.h"
diff --git a/gcc-4.9/gcc/cp/parser.h b/gcc-4.9/gcc/cp/parser.h
new file mode 100644
index 000000000..d558c607f
--- /dev/null
+++ b/gcc-4.9/gcc/cp/parser.h
@@ -0,0 +1,408 @@
+/* Data structures and function exported by the C++ Parser.
+ Copyright (C) 2010-2014 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_CP_PARSER_H
+#define GCC_CP_PARSER_H
+
+#include "tree.h"
+#include "cp/cp-tree.h"
+#include "c-family/c-pragma.h"
+
+/* A token's value and its associated deferred access checks and
+ qualifying scope. */
+
+struct GTY(()) tree_check {
+ /* The value associated with the token. */
+ tree value;
+ /* The checks that have been associated with value. */
+ vec<deferred_access_check, va_gc> *checks;
+ /* The token's qualifying scope (used when it is a
+ CPP_NESTED_NAME_SPECIFIER). */
+ tree qualifying_scope;
+};
+
+/* A C++ token. */
+
+typedef struct GTY (()) cp_token {
+ /* The kind of token. */
+ ENUM_BITFIELD (cpp_ttype) type : 8;
+ /* If this token is a keyword, this value indicates which keyword.
+ Otherwise, this value is RID_MAX. */
+ ENUM_BITFIELD (rid) keyword : 8;
+ /* Token flags. */
+ unsigned char flags;
+ /* Identifier for the pragma. */
+ ENUM_BITFIELD (pragma_kind) pragma_kind : 6;
+ /* True if this token is from a context where it is implicitly extern "C" */
+ BOOL_BITFIELD implicit_extern_c : 1;
+ /* True for a CPP_NAME token that is not a keyword (i.e., for which
+ KEYWORD is RID_MAX) iff this name was looked up and found to be
+ ambiguous. An error has already been reported. */
+ BOOL_BITFIELD ambiguous_p : 1;
+ /* True for a token that has been purged. If a token is purged,
+ it is no longer a valid token and it should be considered
+ deleted. */
+ BOOL_BITFIELD purged_p : 1;
+ /* The location at which this token was found. */
+ location_t location;
+ /* The value associated with this token, if any. */
+ union cp_token_value {
+ /* Used for CPP_NESTED_NAME_SPECIFIER and CPP_TEMPLATE_ID. */
+ struct tree_check* GTY((tag ("1"))) tree_check_value;
+ /* Use for all other tokens. */
+ tree GTY((tag ("0"))) value;
+ } GTY((desc ("(%1.type == CPP_TEMPLATE_ID) || (%1.type == CPP_NESTED_NAME_SPECIFIER)"))) u;
+} cp_token;
+
+
+/* We use a stack of token pointer for saving token sets. */
+typedef struct cp_token *cp_token_position;
+
+/* The cp_lexer structure represents the C++ lexer. It is responsible
+ for managing the token stream from the preprocessor and supplying
+ it to the parser. Tokens are never added to the cp_lexer after
+ it is created. */
+
+typedef struct GTY (()) cp_lexer {
+ /* The memory allocated for the buffer. NULL if this lexer does not
+ own the token buffer. */
+ vec<cp_token, va_gc> *buffer;
+
+ /* A pointer just past the last available token. The tokens
+ in this lexer are [buffer, last_token). */
+ cp_token_position GTY ((skip)) last_token;
+
+ /* The next available token. If NEXT_TOKEN is &eof_token, then there are
+ no more available tokens. */
+ cp_token_position GTY ((skip)) next_token;
+
+ /* A stack indicating positions at which cp_lexer_save_tokens was
+ called. The top entry is the most recent position at which we
+ began saving tokens. If the stack is non-empty, we are saving
+ tokens. */
+ vec<cp_token_position> GTY ((skip)) saved_tokens;
+
+ /* The next lexer in a linked list of lexers. */
+ struct cp_lexer *next;
+
+ /* True if we should output debugging information. */
+ bool debugging_p;
+
+ /* True if we're in the context of parsing a pragma, and should not
+ increment past the end-of-line marker. */
+ bool in_pragma;
+} cp_lexer;
+
+
+/* cp_token_cache is a range of tokens. There is no need to represent
+ allocate heap memory for it, since tokens are never removed from the
+ lexer's array. There is also no need for the GC to walk through
+ a cp_token_cache, since everything in here is referenced through
+ a lexer. */
+
+typedef struct GTY(()) cp_token_cache {
+ /* The beginning of the token range. */
+ cp_token * GTY((skip)) first;
+
+ /* Points immediately after the last token in the range. */
+ cp_token * GTY ((skip)) last;
+} cp_token_cache;
+
+typedef cp_token_cache *cp_token_cache_ptr;
+
+struct cp_token_ident_d
+{
+ unsigned int ident_len;
+ const char *ident_str;
+ unsigned int before_len;
+ const char *before_str;
+ unsigned int after_len;
+ const char *after_str;
+};
+
+typedef struct cp_token_ident_d cp_token_ident;
+
+/* An entry in a queue of function arguments that require post-processing. */
+
+typedef struct GTY(()) cp_default_arg_entry_d {
+ /* The current_class_type when we parsed this arg. */
+ tree class_type;
+
+ /* The function decl itself. */
+ tree decl;
+} cp_default_arg_entry;
+
+
+/* An entry in a stack for member functions of local classes. */
+
+typedef struct GTY(()) cp_unparsed_functions_entry_d {
+ /* Functions with default arguments that require post-processing.
+ Functions appear in this list in declaration order. */
+ vec<cp_default_arg_entry, va_gc> *funs_with_default_args;
+
+ /* Functions with defintions that require post-processing. Functions
+ appear in this list in declaration order. */
+ vec<tree, va_gc> *funs_with_definitions;
+
+ /* Non-static data members with initializers that require post-processing.
+ FIELD_DECLs appear in this list in declaration order. */
+ vec<tree, va_gc> *nsdmis;
+} cp_unparsed_functions_entry;
+
+
+/* The status of a tentative parse. */
+
+typedef enum cp_parser_status_kind
+{
+ /* No errors have occurred. */
+ CP_PARSER_STATUS_KIND_NO_ERROR,
+ /* An error has occurred. */
+ CP_PARSER_STATUS_KIND_ERROR,
+ /* We are committed to this tentative parse, whether or not an error
+ has occurred. */
+ CP_PARSER_STATUS_KIND_COMMITTED
+} cp_parser_status_kind;
+
+
+/* Context that is saved and restored when parsing tentatively. */
+typedef struct GTY (()) cp_parser_context {
+ /* If this is a tentative parsing context, the status of the
+ tentative parse. */
+ enum cp_parser_status_kind status;
+ /* If non-NULL, we have just seen a `x->' or `x.' expression. Names
+ that are looked up in this context must be looked up both in the
+ scope given by OBJECT_TYPE (the type of `x' or `*x') and also in
+ the context of the containing expression. */
+ tree object_type;
+
+ /* The next parsing context in the stack. */
+ struct cp_parser_context *next;
+} cp_parser_context;
+
+
+/* Control structure for #pragma omp declare simd parsing. */
+struct cp_omp_declare_simd_data {
+ bool error_seen; /* Set if error has been reported. */
+ bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
+ vec<cp_token_cache_ptr> tokens;
+};
+
+
+/* The cp_parser structure represents the C++ parser. */
+
+typedef struct GTY(()) cp_parser {
+ /* The lexer from which we are obtaining tokens. */
+ cp_lexer *lexer;
+
+ /* The scope in which names should be looked up. If NULL_TREE, then
+ we look up names in the scope that is currently open in the
+ source program. If non-NULL, this is either a TYPE or
+ NAMESPACE_DECL for the scope in which we should look. It can
+ also be ERROR_MARK, when we've parsed a bogus scope.
+
+ This value is not cleared automatically after a name is looked
+ up, so we must be careful to clear it before starting a new look
+ up sequence. (If it is not cleared, then `X::Y' followed by `Z'
+ will look up `Z' in the scope of `X', rather than the current
+ scope.) Unfortunately, it is difficult to tell when name lookup
+ is complete, because we sometimes peek at a token, look it up,
+ and then decide not to consume it. */
+ tree scope;
+
+ /* OBJECT_SCOPE and QUALIFYING_SCOPE give the scopes in which the
+ last lookup took place. OBJECT_SCOPE is used if an expression
+ like "x->y" or "x.y" was used; it gives the type of "*x" or "x",
+ respectively. QUALIFYING_SCOPE is used for an expression of the
+ form "X::Y"; it refers to X. */
+ tree object_scope;
+ tree qualifying_scope;
+
+ /* A stack of parsing contexts. All but the bottom entry on the
+ stack will be tentative contexts.
+
+ We parse tentatively in order to determine which construct is in
+ use in some situations. For example, in order to determine
+ whether a statement is an expression-statement or a
+ declaration-statement we parse it tentatively as a
+ declaration-statement. If that fails, we then reparse the same
+ token stream as an expression-statement. */
+ cp_parser_context *context;
+
+ /* True if we are parsing GNU C++. If this flag is not set, then
+ GNU extensions are not recognized. */
+ bool allow_gnu_extensions_p;
+
+ /* TRUE if the `>' token should be interpreted as the greater-than
+ operator. FALSE if it is the end of a template-id or
+ template-parameter-list. In C++0x mode, this flag also applies to
+ `>>' tokens, which are viewed as two consecutive `>' tokens when
+ this flag is FALSE. */
+ bool greater_than_is_operator_p;
+
+ /* TRUE if default arguments are allowed within a parameter list
+ that starts at this point. FALSE if only a gnu extension makes
+ them permissible. */
+ bool default_arg_ok_p;
+
+ /* TRUE if we are parsing an integral constant-expression. See
+ [expr.const] for a precise definition. */
+ bool integral_constant_expression_p;
+
+ /* TRUE if we are parsing an integral constant-expression -- but a
+ non-constant expression should be permitted as well. This flag
+ is used when parsing an array bound so that GNU variable-length
+ arrays are tolerated. */
+ bool allow_non_integral_constant_expression_p;
+
+ /* TRUE if ALLOW_NON_CONSTANT_EXPRESSION_P is TRUE and something has
+ been seen that makes the expression non-constant. */
+ bool non_integral_constant_expression_p;
+
+ /* TRUE if local variable names and `this' are forbidden in the
+ current context. */
+ bool local_variables_forbidden_p;
+
+ /* TRUE if the declaration we are parsing is part of a
+ linkage-specification of the form `extern string-literal
+ declaration'. */
+ bool in_unbraced_linkage_specification_p;
+
+ /* TRUE if we are presently parsing a declarator, after the
+ direct-declarator. */
+ bool in_declarator_p;
+
+ /* TRUE if we are presently parsing a template-argument-list. */
+ bool in_template_argument_list_p;
+
+ /* Set to IN_ITERATION_STMT if parsing an iteration-statement,
+ to IN_OMP_BLOCK if parsing OpenMP structured block and
+ IN_OMP_FOR if parsing OpenMP loop. If parsing a switch statement,
+ this is bitwise ORed with IN_SWITCH_STMT, unless parsing an
+ iteration-statement, OpenMP block or loop within that switch. */
+#define IN_SWITCH_STMT 1
+#define IN_ITERATION_STMT 2
+#define IN_OMP_BLOCK 4
+#define IN_OMP_FOR 8
+#define IN_IF_STMT 16
+#define IN_CILK_SIMD_FOR 32
+#define IN_CILK_SPAWN 64
+ unsigned char in_statement;
+
+ /* TRUE if we are presently parsing the body of a switch statement.
+ Note that this doesn't quite overlap with in_statement above.
+ The difference relates to giving the right sets of error messages:
+ "case not in switch" vs "break statement used with OpenMP...". */
+ bool in_switch_statement_p;
+
+ /* TRUE if we are parsing a type-id in an expression context. In
+ such a situation, both "type (expr)" and "type (type)" are valid
+ alternatives. */
+ bool in_type_id_in_expr_p;
+
+ /* TRUE if we are currently in a header file where declarations are
+ implicitly extern "C". */
+ bool implicit_extern_c;
+
+ /* TRUE if strings in expressions should be translated to the execution
+ character set. */
+ bool translate_strings_p;
+
+ /* TRUE if we are presently parsing the body of a function, but not
+ a local class. */
+ bool in_function_body;
+
+ /* Nonzero if we're processing a __transaction_atomic or
+ __transaction_relaxed statement. */
+ unsigned char in_transaction;
+
+ /* TRUE if we can auto-correct a colon to a scope operator. */
+ bool colon_corrects_to_scope_p;
+
+ /* TRUE if : doesn't start a class definition. Should be only used
+ together with type_definition_forbidden_message non-NULL, in
+ contexts where new types may not be defined, and the type list
+ is terminated by colon. */
+ bool colon_doesnt_start_class_def_p;
+
+ /* If non-NULL, then we are parsing a construct where new type
+ definitions are not permitted. The string stored here will be
+ issued as an error message if a type is defined. */
+ const char *type_definition_forbidden_message;
+
+ /* A stack used for member functions of local classes. The lists
+ contained in an individual entry can only be processed once the
+ outermost class being defined is complete. */
+ vec<cp_unparsed_functions_entry, va_gc> *unparsed_queues;
+
+ /* The number of classes whose definitions are currently in
+ progress. */
+ unsigned num_classes_being_defined;
+
+ /* The number of template parameter lists that apply directly to the
+ current declaration. */
+ unsigned num_template_parameter_lists;
+
+ /* When parsing #pragma omp declare simd, this is a pointer to a
+ data structure with everything needed for parsing the clauses. */
+ cp_omp_declare_simd_data * GTY((skip)) omp_declare_simd;
+
+ /* When parsing the vector attribute in Cilk Plus SIMD-enabled function,
+ this is a pointer to data structure with everything needed for parsing
+ the clauses. The cp_omp_declare_simd_data struct will hold all the
+ necessary information, so creating another struct for this is not
+ necessary. */
+ cp_omp_declare_simd_data * GTY((skip)) cilk_simd_fn_info;
+
+ /* Nonzero if parsing a parameter list where 'auto' should trigger an implicit
+ template parameter. */
+ bool auto_is_implicit_function_template_parm_p;
+
+ /* TRUE if the function being declared was made a template due to its
+ parameter list containing generic type specifiers (`auto' or concept
+ identifiers) rather than an explicit template parameter list. */
+ bool fully_implicit_function_template_p;
+
+ /* Tracks the function's template parameter list when declaring a function
+ using generic type parameters. This is either a new chain in the case of a
+ fully implicit function template or an extension of the function's existing
+ template parameter list. This is tracked to optimize calls subsequent
+ calls to synthesize_implicit_template_parm during
+ cp_parser_parameter_declaration. */
+ tree implicit_template_parms;
+
+ /* The scope into which an implicit template parameter list has been
+ introduced or an existing template parameter list is being extended with
+ implicit template paramaters. In most cases this is the sk_function_parms
+ scope containing the use of a generic type. In the case of an out-of-line
+ member definition using a generic type, it is the sk_class scope. */
+ cp_binding_level* implicit_template_scope;
+
+} cp_parser;
+
+/* In parser.c */
+extern void debug (cp_token &ref);
+extern void debug (cp_token *ptr);
+extern void cp_lexer_debug_tokens (vec<cp_token, va_gc> *);
+extern void debug (vec<cp_token, va_gc> &ref);
+extern void debug (vec<cp_token, va_gc> *ptr);
+extern void cp_debug_parser (FILE *, cp_parser *);
+extern void debug (cp_parser &ref);
+extern void debug (cp_parser *ptr);
+
+#endif /* GCC_CP_PARSER_H */
diff --git a/gcc-4.9/gcc/cp/pt.c b/gcc-4.9/gcc/cp/pt.c
new file mode 100644
index 000000000..c791d031a
--- /dev/null
+++ b/gcc-4.9/gcc/cp/pt.c
@@ -0,0 +1,21975 @@
+/* Handle parameterized types (templates) for GNU -*- C++ -*-.
+ Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
+ Rewritten by Jason Merrill (jason@cygnus.com).
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Known bugs or deficiencies include:
+
+ all methods must be provided in header files; can't use a source
+ file that contains only the method templates and "just win". */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "varasm.h"
+#include "attribs.h"
+#include "stor-layout.h"
+#include "intl.h"
+#include "pointer-set.h"
+#include "flags.h"
+#include "cp-tree.h"
+#include "c-family/c-common.h"
+#include "c-family/c-objc.h"
+#include "cp-objcp-common.h"
+#include "tree-inline.h"
+#include "decl.h"
+#include "toplev.h"
+#include "timevar.h"
+#include "tree-iterator.h"
+#include "type-utils.h"
+#include "gimplify.h"
+
+/* The type of functions taking a tree, and some additional data, and
+ returning an int. */
+typedef int (*tree_fn_t) (tree, void*);
+
+/* The PENDING_TEMPLATES is a TREE_LIST of templates whose
+ instantiations have been deferred, either because their definitions
+ were not yet available, or because we were putting off doing the work. */
+struct GTY ((chain_next ("%h.next"))) pending_template {
+ struct pending_template *next;
+ struct tinst_level *tinst;
+};
+
+static GTY(()) struct pending_template *pending_templates;
+static GTY(()) struct pending_template *last_pending_template;
+
+int processing_template_parmlist;
+static int template_header_count;
+
+static GTY(()) tree saved_trees;
+static vec<int> inline_parm_levels;
+
+static GTY(()) struct tinst_level *current_tinst_level;
+
+static GTY(()) tree saved_access_scope;
+
+/* Live only within one (recursive) call to tsubst_expr. We use
+ this to pass the statement expression node from the STMT_EXPR
+ to the EXPR_STMT that is its result. */
+static tree cur_stmt_expr;
+
+/* True if we've recursed into fn_type_unification too many times. */
+static bool excessive_deduction_depth;
+
+typedef struct GTY(()) spec_entry
+{
+ tree tmpl;
+ tree args;
+ tree spec;
+} spec_entry;
+
+static GTY ((param_is (spec_entry)))
+ htab_t decl_specializations;
+
+static GTY ((param_is (spec_entry)))
+ htab_t type_specializations;
+
+/* Contains canonical template parameter types. The vector is indexed by
+ the TEMPLATE_TYPE_IDX of the template parameter. Each element is a
+ TREE_LIST, whose TREE_VALUEs contain the canonical template
+ parameters of various types and levels. */
+static GTY(()) vec<tree, va_gc> *canonical_template_parms;
+
+#define UNIFY_ALLOW_NONE 0
+#define UNIFY_ALLOW_MORE_CV_QUAL 1
+#define UNIFY_ALLOW_LESS_CV_QUAL 2
+#define UNIFY_ALLOW_DERIVED 4
+#define UNIFY_ALLOW_INTEGER 8
+#define UNIFY_ALLOW_OUTER_LEVEL 16
+#define UNIFY_ALLOW_OUTER_MORE_CV_QUAL 32
+#define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
+
+enum template_base_result {
+ tbr_incomplete_type,
+ tbr_ambiguous_baseclass,
+ tbr_success
+};
+
+static void push_access_scope (tree);
+static void pop_access_scope (tree);
+static bool resolve_overloaded_unification (tree, tree, tree, tree,
+ unification_kind_t, int,
+ bool);
+static int try_one_overload (tree, tree, tree, tree, tree,
+ unification_kind_t, int, bool, bool);
+static int unify (tree, tree, tree, tree, int, bool);
+static void add_pending_template (tree);
+static tree reopen_tinst_level (struct tinst_level *);
+static tree tsubst_initializer_list (tree, tree);
+static tree get_class_bindings (tree, tree, tree, tree);
+static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t,
+ bool, bool);
+static tree coerce_innermost_template_parms (tree, tree, tree, tsubst_flags_t,
+ bool, bool);
+static void tsubst_enum (tree, tree, tree);
+static tree add_to_template_args (tree, tree);
+static tree add_outermost_template_args (tree, tree);
+static bool check_instantiated_args (tree, tree, tsubst_flags_t);
+static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
+ tree);
+static int type_unification_real (tree, tree, tree, const tree *,
+ unsigned int, int, unification_kind_t, int,
+ vec<deferred_access_check, va_gc> **,
+ bool);
+static void note_template_header (int);
+static tree convert_nontype_argument_function (tree, tree);
+static tree convert_nontype_argument (tree, tree, tsubst_flags_t);
+static tree convert_template_argument (tree, tree, tree,
+ tsubst_flags_t, int, tree);
+static int for_each_template_parm (tree, tree_fn_t, void*,
+ struct pointer_set_t*, bool);
+static tree expand_template_argument_pack (tree);
+static tree build_template_parm_index (int, int, int, tree, tree);
+static bool inline_needs_template_parms (tree, bool);
+static void push_inline_template_parms_recursive (tree, int);
+static tree retrieve_local_specialization (tree);
+static void register_local_specialization (tree, tree);
+static hashval_t hash_specialization (const void *p);
+static tree reduce_template_parm_level (tree, tree, int, tree, tsubst_flags_t);
+static int mark_template_parm (tree, void *);
+static int template_parm_this_level_p (tree, void *);
+static tree tsubst_friend_function (tree, tree);
+static tree tsubst_friend_class (tree, tree);
+static int can_complete_type_without_circularity (tree);
+static tree get_bindings (tree, tree, tree, bool);
+static int template_decl_level (tree);
+static int check_cv_quals_for_unify (int, tree, tree);
+static void template_parm_level_and_index (tree, int*, int*);
+static int unify_pack_expansion (tree, tree, tree,
+ tree, unification_kind_t, bool, bool);
+static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
+static void regenerate_decl_from_template (tree, tree);
+static tree most_specialized_class (tree, tsubst_flags_t);
+static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
+static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree);
+static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
+static bool check_specialization_scope (void);
+static tree process_partial_specialization (tree);
+static void set_current_access_from_decl (tree);
+static enum template_base_result get_template_base (tree, tree, tree, tree,
+ bool , tree *);
+static tree try_class_unification (tree, tree, tree, tree, bool);
+static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
+ tree, tree);
+static bool template_template_parm_bindings_ok_p (tree, tree);
+static int template_args_equal (tree, tree);
+static void tsubst_default_arguments (tree, tsubst_flags_t);
+static tree for_each_template_parm_r (tree *, int *, void *);
+static tree copy_default_args_to_explicit_spec_1 (tree, tree);
+static void copy_default_args_to_explicit_spec (tree);
+static int invalid_nontype_parm_type_p (tree, tsubst_flags_t);
+static bool dependent_template_arg_p (tree);
+static bool any_template_arguments_need_structural_equality_p (tree);
+static bool dependent_type_p_r (tree);
+static tree tsubst_expr (tree, tree, tsubst_flags_t, tree, bool);
+static tree tsubst_copy (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_decl (tree, tree, tsubst_flags_t);
+static void perform_typedefs_access_check (tree tmpl, tree targs);
+static void append_type_to_template_for_access_check_1 (tree, tree, tree,
+ location_t);
+static tree listify (tree);
+static tree listify_autos (tree, tree);
+static tree template_parm_to_arg (tree t);
+static tree current_template_args (void);
+static tree tsubst_template_parm (tree, tree, tsubst_flags_t);
+static tree instantiate_alias_template (tree, tree, tsubst_flags_t);
+
+/* Make the current scope suitable for access checking when we are
+ processing T. T can be FUNCTION_DECL for instantiated function
+ template, VAR_DECL for static member variable, or TYPE_DECL for
+ alias template (needed by instantiate_decl). */
+
+static void
+push_access_scope (tree t)
+{
+ gcc_assert (VAR_OR_FUNCTION_DECL_P (t)
+ || TREE_CODE (t) == TYPE_DECL);
+
+ if (DECL_FRIEND_CONTEXT (t))
+ push_nested_class (DECL_FRIEND_CONTEXT (t));
+ else if (DECL_CLASS_SCOPE_P (t))
+ push_nested_class (DECL_CONTEXT (t));
+ else
+ push_to_top_level ();
+
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ {
+ saved_access_scope = tree_cons
+ (NULL_TREE, current_function_decl, saved_access_scope);
+ current_function_decl = t;
+ }
+}
+
+/* Restore the scope set up by push_access_scope. T is the node we
+ are processing. */
+
+static void
+pop_access_scope (tree t)
+{
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ {
+ current_function_decl = TREE_VALUE (saved_access_scope);
+ saved_access_scope = TREE_CHAIN (saved_access_scope);
+ }
+
+ if (DECL_FRIEND_CONTEXT (t) || DECL_CLASS_SCOPE_P (t))
+ pop_nested_class ();
+ else
+ pop_from_top_level ();
+}
+
+/* Do any processing required when DECL (a member template
+ declaration) is finished. Returns the TEMPLATE_DECL corresponding
+ to DECL, unless it is a specialization, in which case the DECL
+ itself is returned. */
+
+tree
+finish_member_template_decl (tree decl)
+{
+ if (decl == error_mark_node)
+ return error_mark_node;
+
+ gcc_assert (DECL_P (decl));
+
+ if (TREE_CODE (decl) == TYPE_DECL)
+ {
+ tree type;
+
+ type = TREE_TYPE (decl);
+ if (type == error_mark_node)
+ return error_mark_node;
+ if (MAYBE_CLASS_TYPE_P (type)
+ && CLASSTYPE_TEMPLATE_INFO (type)
+ && !CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
+ {
+ tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
+ check_member_template (tmpl);
+ return tmpl;
+ }
+ return NULL_TREE;
+ }
+ else if (TREE_CODE (decl) == FIELD_DECL)
+ error ("data member %qD cannot be a member template", decl);
+ else if (DECL_TEMPLATE_INFO (decl))
+ {
+ if (!DECL_TEMPLATE_SPECIALIZATION (decl))
+ {
+ check_member_template (DECL_TI_TEMPLATE (decl));
+ return DECL_TI_TEMPLATE (decl);
+ }
+ else
+ return decl;
+ }
+ else
+ error ("invalid member template declaration %qD", decl);
+
+ return error_mark_node;
+}
+
+/* Create a template info node. */
+
+tree
+build_template_info (tree template_decl, tree template_args)
+{
+ tree result = make_node (TEMPLATE_INFO);
+ TI_TEMPLATE (result) = template_decl;
+ TI_ARGS (result) = template_args;
+ return result;
+}
+
+/* Return the template info node corresponding to T, whatever T is. */
+
+tree
+get_template_info (const_tree t)
+{
+ tree tinfo = NULL_TREE;
+
+ if (!t || t == error_mark_node)
+ return NULL;
+
+ if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
+ tinfo = DECL_TEMPLATE_INFO (t);
+
+ if (!tinfo && DECL_IMPLICIT_TYPEDEF_P (t))
+ t = TREE_TYPE (t);
+
+ if (OVERLOAD_TYPE_P (t))
+ tinfo = TYPE_TEMPLATE_INFO (t);
+ else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ tinfo = TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t);
+
+ return tinfo;
+}
+
+/* Returns the template nesting level of the indicated class TYPE.
+
+ For example, in:
+ template <class T>
+ struct A
+ {
+ template <class U>
+ struct B {};
+ };
+
+ A<T>::B<U> has depth two, while A<T> has depth one.
+ Both A<T>::B<int> and A<int>::B<U> have depth one, if
+ they are instantiations, not specializations.
+
+ This function is guaranteed to return 0 if passed NULL_TREE so
+ that, for example, `template_class_depth (current_class_type)' is
+ always safe. */
+
+int
+template_class_depth (tree type)
+{
+ int depth;
+
+ for (depth = 0;
+ type && TREE_CODE (type) != NAMESPACE_DECL;
+ type = (TREE_CODE (type) == FUNCTION_DECL)
+ ? CP_DECL_CONTEXT (type) : CP_TYPE_CONTEXT (type))
+ {
+ tree tinfo = get_template_info (type);
+
+ if (tinfo && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo))
+ && uses_template_parms (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo))))
+ ++depth;
+ }
+
+ return depth;
+}
+
+/* Subroutine of maybe_begin_member_template_processing.
+ Returns true if processing DECL needs us to push template parms. */
+
+static bool
+inline_needs_template_parms (tree decl, bool nsdmi)
+{
+ if (!decl || (!nsdmi && ! DECL_TEMPLATE_INFO (decl)))
+ return false;
+
+ return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (most_general_template (decl)))
+ > (processing_template_decl + DECL_TEMPLATE_SPECIALIZATION (decl)));
+}
+
+/* Subroutine of maybe_begin_member_template_processing.
+ Push the template parms in PARMS, starting from LEVELS steps into the
+ chain, and ending at the beginning, since template parms are listed
+ innermost first. */
+
+static void
+push_inline_template_parms_recursive (tree parmlist, int levels)
+{
+ tree parms = TREE_VALUE (parmlist);
+ int i;
+
+ if (levels > 1)
+ push_inline_template_parms_recursive (TREE_CHAIN (parmlist), levels - 1);
+
+ ++processing_template_decl;
+ current_template_parms
+ = tree_cons (size_int (processing_template_decl),
+ parms, current_template_parms);
+ TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1;
+
+ begin_scope (TREE_VEC_LENGTH (parms) ? sk_template_parms : sk_template_spec,
+ NULL);
+ for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
+ {
+ tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+
+ if (parm == error_mark_node)
+ continue;
+
+ gcc_assert (DECL_P (parm));
+
+ switch (TREE_CODE (parm))
+ {
+ case TYPE_DECL:
+ case TEMPLATE_DECL:
+ pushdecl (parm);
+ break;
+
+ case PARM_DECL:
+ {
+ /* Make a CONST_DECL as is done in process_template_parm.
+ It is ugly that we recreate this here; the original
+ version built in process_template_parm is no longer
+ available. */
+ tree decl = build_decl (DECL_SOURCE_LOCATION (parm),
+ CONST_DECL, DECL_NAME (parm),
+ TREE_TYPE (parm));
+ DECL_ARTIFICIAL (decl) = 1;
+ TREE_CONSTANT (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ DECL_INITIAL (decl) = DECL_INITIAL (parm);
+ SET_DECL_TEMPLATE_PARM_P (decl);
+ pushdecl (decl);
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+}
+
+/* Restore the template parameter context for a member template, a
+ friend template defined in a class definition, or a non-template
+ member of template class. */
+
+void
+maybe_begin_member_template_processing (tree decl)
+{
+ tree parms;
+ int levels = 0;
+ bool nsdmi = TREE_CODE (decl) == FIELD_DECL;
+
+ if (nsdmi)
+ decl = (CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl))
+ ? CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (decl))
+ : NULL_TREE);
+
+ if (inline_needs_template_parms (decl, nsdmi))
+ {
+ parms = DECL_TEMPLATE_PARMS (most_general_template (decl));
+ levels = TMPL_PARMS_DEPTH (parms) - processing_template_decl;
+
+ if (DECL_TEMPLATE_SPECIALIZATION (decl))
+ {
+ --levels;
+ parms = TREE_CHAIN (parms);
+ }
+
+ push_inline_template_parms_recursive (parms, levels);
+ }
+
+ /* Remember how many levels of template parameters we pushed so that
+ we can pop them later. */
+ inline_parm_levels.safe_push (levels);
+}
+
+/* Undo the effects of maybe_begin_member_template_processing. */
+
+void
+maybe_end_member_template_processing (void)
+{
+ int i;
+ int last;
+
+ if (inline_parm_levels.length () == 0)
+ return;
+
+ last = inline_parm_levels.pop ();
+ for (i = 0; i < last; ++i)
+ {
+ --processing_template_decl;
+ current_template_parms = TREE_CHAIN (current_template_parms);
+ poplevel (0, 0, 0);
+ }
+}
+
+/* Return a new template argument vector which contains all of ARGS,
+ but has as its innermost set of arguments the EXTRA_ARGS. */
+
+static tree
+add_to_template_args (tree args, tree extra_args)
+{
+ tree new_args;
+ int extra_depth;
+ int i;
+ int j;
+
+ if (args == NULL_TREE || extra_args == error_mark_node)
+ return extra_args;
+
+ extra_depth = TMPL_ARGS_DEPTH (extra_args);
+ new_args = make_tree_vec (TMPL_ARGS_DEPTH (args) + extra_depth);
+
+ for (i = 1; i <= TMPL_ARGS_DEPTH (args); ++i)
+ SET_TMPL_ARGS_LEVEL (new_args, i, TMPL_ARGS_LEVEL (args, i));
+
+ for (j = 1; j <= extra_depth; ++j, ++i)
+ SET_TMPL_ARGS_LEVEL (new_args, i, TMPL_ARGS_LEVEL (extra_args, j));
+
+ return new_args;
+}
+
+/* Like add_to_template_args, but only the outermost ARGS are added to
+ the EXTRA_ARGS. In particular, all but TMPL_ARGS_DEPTH
+ (EXTRA_ARGS) levels are added. This function is used to combine
+ the template arguments from a partial instantiation with the
+ template arguments used to attain the full instantiation from the
+ partial instantiation. */
+
+static tree
+add_outermost_template_args (tree args, tree extra_args)
+{
+ tree new_args;
+
+ /* If there are more levels of EXTRA_ARGS than there are ARGS,
+ something very fishy is going on. */
+ gcc_assert (TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (extra_args));
+
+ /* If *all* the new arguments will be the EXTRA_ARGS, just return
+ them. */
+ if (TMPL_ARGS_DEPTH (args) == TMPL_ARGS_DEPTH (extra_args))
+ return extra_args;
+
+ /* For the moment, we make ARGS look like it contains fewer levels. */
+ TREE_VEC_LENGTH (args) -= TMPL_ARGS_DEPTH (extra_args);
+
+ new_args = add_to_template_args (args, extra_args);
+
+ /* Now, we restore ARGS to its full dimensions. */
+ TREE_VEC_LENGTH (args) += TMPL_ARGS_DEPTH (extra_args);
+
+ return new_args;
+}
+
+/* Return the N levels of innermost template arguments from the ARGS. */
+
+tree
+get_innermost_template_args (tree args, int n)
+{
+ tree new_args;
+ int extra_levels;
+ int i;
+
+ gcc_assert (n >= 0);
+
+ /* If N is 1, just return the innermost set of template arguments. */
+ if (n == 1)
+ return TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args));
+
+ /* If we're not removing anything, just return the arguments we were
+ given. */
+ extra_levels = TMPL_ARGS_DEPTH (args) - n;
+ gcc_assert (extra_levels >= 0);
+ if (extra_levels == 0)
+ return args;
+
+ /* Make a new set of arguments, not containing the outer arguments. */
+ new_args = make_tree_vec (n);
+ for (i = 1; i <= n; ++i)
+ SET_TMPL_ARGS_LEVEL (new_args, i,
+ TMPL_ARGS_LEVEL (args, i + extra_levels));
+
+ return new_args;
+}
+
+/* The inverse of get_innermost_template_args: Return all but the innermost
+ EXTRA_LEVELS levels of template arguments from the ARGS. */
+
+static tree
+strip_innermost_template_args (tree args, int extra_levels)
+{
+ tree new_args;
+ int n = TMPL_ARGS_DEPTH (args) - extra_levels;
+ int i;
+
+ gcc_assert (n >= 0);
+
+ /* If N is 1, just return the outermost set of template arguments. */
+ if (n == 1)
+ return TMPL_ARGS_LEVEL (args, 1);
+
+ /* If we're not removing anything, just return the arguments we were
+ given. */
+ gcc_assert (extra_levels >= 0);
+ if (extra_levels == 0)
+ return args;
+
+ /* Make a new set of arguments, not containing the inner arguments. */
+ new_args = make_tree_vec (n);
+ for (i = 1; i <= n; ++i)
+ SET_TMPL_ARGS_LEVEL (new_args, i,
+ TMPL_ARGS_LEVEL (args, i));
+
+ return new_args;
+}
+
+/* We've got a template header coming up; push to a new level for storing
+ the parms. */
+
+void
+begin_template_parm_list (void)
+{
+ /* We use a non-tag-transparent scope here, which causes pushtag to
+ put tags in this scope, rather than in the enclosing class or
+ namespace scope. This is the right thing, since we want
+ TEMPLATE_DECLS, and not TYPE_DECLS for template classes. For a
+ global template class, push_template_decl handles putting the
+ TEMPLATE_DECL into top-level scope. For a nested template class,
+ e.g.:
+
+ template <class T> struct S1 {
+ template <class T> struct S2 {};
+ };
+
+ pushtag contains special code to call pushdecl_with_scope on the
+ TEMPLATE_DECL for S2. */
+ begin_scope (sk_template_parms, NULL);
+ ++processing_template_decl;
+ ++processing_template_parmlist;
+ note_template_header (0);
+}
+
+/* This routine is called when a specialization is declared. If it is
+ invalid to declare a specialization here, an error is reported and
+ false is returned, otherwise this routine will return true. */
+
+static bool
+check_specialization_scope (void)
+{
+ tree scope = current_scope ();
+
+ /* [temp.expl.spec]
+
+ An explicit specialization shall be declared in the namespace of
+ which the template is a member, or, for member templates, in the
+ namespace of which the enclosing class or enclosing class
+ template is a member. An explicit specialization of a member
+ function, member class or static data member of a class template
+ shall be declared in the namespace of which the class template
+ is a member. */
+ if (scope && TREE_CODE (scope) != NAMESPACE_DECL)
+ {
+ error ("explicit specialization in non-namespace scope %qD", scope);
+ return false;
+ }
+
+ /* [temp.expl.spec]
+
+ In an explicit specialization declaration for a member of a class
+ template or a member template that appears in namespace scope,
+ the member template and some of its enclosing class templates may
+ remain unspecialized, except that the declaration shall not
+ explicitly specialize a class member template if its enclosing
+ class templates are not explicitly specialized as well. */
+ if (current_template_parms)
+ {
+ error ("enclosing class templates are not explicitly specialized");
+ return false;
+ }
+
+ return true;
+}
+
+/* We've just seen template <>. */
+
+bool
+begin_specialization (void)
+{
+ begin_scope (sk_template_spec, NULL);
+ note_template_header (1);
+ return check_specialization_scope ();
+}
+
+/* Called at then end of processing a declaration preceded by
+ template<>. */
+
+void
+end_specialization (void)
+{
+ finish_scope ();
+ reset_specialization ();
+}
+
+/* Any template <>'s that we have seen thus far are not referring to a
+ function specialization. */
+
+void
+reset_specialization (void)
+{
+ processing_specialization = 0;
+ template_header_count = 0;
+}
+
+/* We've just seen a template header. If SPECIALIZATION is nonzero,
+ it was of the form template <>. */
+
+static void
+note_template_header (int specialization)
+{
+ processing_specialization = specialization;
+ template_header_count++;
+}
+
+/* We're beginning an explicit instantiation. */
+
+void
+begin_explicit_instantiation (void)
+{
+ gcc_assert (!processing_explicit_instantiation);
+ processing_explicit_instantiation = true;
+}
+
+
+void
+end_explicit_instantiation (void)
+{
+ gcc_assert (processing_explicit_instantiation);
+ processing_explicit_instantiation = false;
+}
+
+/* An explicit specialization or partial specialization of TMPL is being
+ declared. Check that the namespace in which the specialization is
+ occurring is permissible. Returns false iff it is invalid to
+ specialize TMPL in the current namespace. */
+
+static bool
+check_specialization_namespace (tree tmpl)
+{
+ tree tpl_ns = decl_namespace_context (tmpl);
+
+ /* [tmpl.expl.spec]
+
+ An explicit specialization shall be declared in the namespace of
+ which the template is a member, or, for member templates, in the
+ namespace of which the enclosing class or enclosing class
+ template is a member. An explicit specialization of a member
+ function, member class or static data member of a class template
+ shall be declared in the namespace of which the class template is
+ a member. */
+ if (current_scope() != DECL_CONTEXT (tmpl)
+ && !at_namespace_scope_p ())
+ {
+ error ("specialization of %qD must appear at namespace scope", tmpl);
+ return false;
+ }
+ if (is_associated_namespace (current_namespace, tpl_ns))
+ /* Same or super-using namespace. */
+ return true;
+ else
+ {
+ permerror (input_location, "specialization of %qD in different namespace", tmpl);
+ permerror (input_location, " from definition of %q+#D", tmpl);
+ return false;
+ }
+}
+
+/* SPEC is an explicit instantiation. Check that it is valid to
+ perform this explicit instantiation in the current namespace. */
+
+static void
+check_explicit_instantiation_namespace (tree spec)
+{
+ tree ns;
+
+ /* DR 275: An explicit instantiation shall appear in an enclosing
+ namespace of its template. */
+ ns = decl_namespace_context (spec);
+ if (!is_ancestor (current_namespace, ns))
+ permerror (input_location, "explicit instantiation of %qD in namespace %qD "
+ "(which does not enclose namespace %qD)",
+ spec, current_namespace, ns);
+}
+
+/* The TYPE is being declared. If it is a template type, that means it
+ is a partial specialization. Do appropriate error-checking. */
+
+tree
+maybe_process_partial_specialization (tree type)
+{
+ tree context;
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ /* A lambda that appears in specialization context is not itself a
+ specialization. */
+ if (CLASS_TYPE_P (type) && CLASSTYPE_LAMBDA_EXPR (type))
+ return type;
+
+ if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ {
+ error ("name of class shadows template template parameter %qD",
+ TYPE_NAME (type));
+ return error_mark_node;
+ }
+
+ context = TYPE_CONTEXT (type);
+
+ if (TYPE_ALIAS_P (type))
+ {
+ if (TYPE_TEMPLATE_INFO (type)
+ && DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (type)))
+ error ("specialization of alias template %qD",
+ TYPE_TI_TEMPLATE (type));
+ else
+ error ("explicit specialization of non-template %qT", type);
+ return error_mark_node;
+ }
+ else if (CLASS_TYPE_P (type) && CLASSTYPE_USE_TEMPLATE (type))
+ {
+ /* This is for ordinary explicit specialization and partial
+ specialization of a template class such as:
+
+ template <> class C<int>;
+
+ or:
+
+ template <class T> class C<T*>;
+
+ Make sure that `C<int>' and `C<T*>' are implicit instantiations. */
+
+ if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
+ && !COMPLETE_TYPE_P (type))
+ {
+ if (!check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type))
+ && !at_namespace_scope_p ())
+ return error_mark_node;
+ SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type);
+ DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)) = input_location;
+ if (processing_template_decl)
+ {
+ if (push_template_decl (TYPE_MAIN_DECL (type))
+ == error_mark_node)
+ return error_mark_node;
+ }
+ }
+ else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
+ error ("specialization of %qT after instantiation", type);
+ else if (errorcount && !processing_specialization
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (type)
+ && !uses_template_parms (CLASSTYPE_TI_ARGS (type)))
+ /* Trying to define a specialization either without a template<> header
+ or in an inappropriate place. We've already given an error, so just
+ bail now so we don't actually define the specialization. */
+ return error_mark_node;
+ }
+ else if (CLASS_TYPE_P (type)
+ && !CLASSTYPE_USE_TEMPLATE (type)
+ && CLASSTYPE_TEMPLATE_INFO (type)
+ && context && CLASS_TYPE_P (context)
+ && CLASSTYPE_TEMPLATE_INFO (context))
+ {
+ /* This is for an explicit specialization of member class
+ template according to [temp.expl.spec/18]:
+
+ template <> template <class U> class C<int>::D;
+
+ The context `C<int>' must be an implicit instantiation.
+ Otherwise this is just a member class template declared
+ earlier like:
+
+ template <> class C<int> { template <class U> class D; };
+ template <> template <class U> class C<int>::D;
+
+ In the first case, `C<int>::D' is a specialization of `C<T>::D'
+ while in the second case, `C<int>::D' is a primary template
+ and `C<T>::D' may not exist. */
+
+ if (CLASSTYPE_IMPLICIT_INSTANTIATION (context)
+ && !COMPLETE_TYPE_P (type))
+ {
+ tree t;
+ tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
+
+ if (current_namespace
+ != decl_namespace_context (tmpl))
+ {
+ permerror (input_location, "specializing %q#T in different namespace", type);
+ permerror (input_location, " from definition of %q+#D", tmpl);
+ }
+
+ /* Check for invalid specialization after instantiation:
+
+ template <> template <> class C<int>::D<int>;
+ template <> template <class U> class C<int>::D; */
+
+ for (t = DECL_TEMPLATE_INSTANTIATIONS (tmpl);
+ t; t = TREE_CHAIN (t))
+ {
+ tree inst = TREE_VALUE (t);
+ if (CLASSTYPE_TEMPLATE_SPECIALIZATION (inst)
+ || !COMPLETE_OR_OPEN_TYPE_P (inst))
+ {
+ /* We already have a full specialization of this partial
+ instantiation, or a full specialization has been
+ looked up but not instantiated. Reassign it to the
+ new member specialization template. */
+ spec_entry elt;
+ spec_entry *entry;
+ void **slot;
+
+ elt.tmpl = most_general_template (tmpl);
+ elt.args = CLASSTYPE_TI_ARGS (inst);
+ elt.spec = inst;
+
+ htab_remove_elt (type_specializations, &elt);
+
+ elt.tmpl = tmpl;
+ elt.args = INNERMOST_TEMPLATE_ARGS (elt.args);
+
+ slot = htab_find_slot (type_specializations, &elt, INSERT);
+ entry = ggc_alloc_spec_entry ();
+ *entry = elt;
+ *slot = entry;
+ }
+ else
+ /* But if we've had an implicit instantiation, that's a
+ problem ([temp.expl.spec]/6). */
+ error ("specialization %qT after instantiation %qT",
+ type, inst);
+ }
+
+ /* Mark TYPE as a specialization. And as a result, we only
+ have one level of template argument for the innermost
+ class template. */
+ SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type);
+ DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)) = input_location;
+ CLASSTYPE_TI_ARGS (type)
+ = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
+ }
+ }
+ else if (processing_specialization)
+ {
+ /* Someday C++0x may allow for enum template specialization. */
+ if (cxx_dialect > cxx98 && TREE_CODE (type) == ENUMERAL_TYPE
+ && CLASS_TYPE_P (context) && CLASSTYPE_USE_TEMPLATE (context))
+ pedwarn (input_location, OPT_Wpedantic, "template specialization "
+ "of %qD not allowed by ISO C++", type);
+ else
+ {
+ error ("explicit specialization of non-template %qT", type);
+ return error_mark_node;
+ }
+ }
+
+ return type;
+}
+
+/* Returns nonzero if we can optimize the retrieval of specializations
+ for TMPL, a TEMPLATE_DECL. In particular, for such a template, we
+ do not use DECL_TEMPLATE_SPECIALIZATIONS at all. */
+
+static inline bool
+optimize_specialization_lookup_p (tree tmpl)
+{
+ return (DECL_FUNCTION_TEMPLATE_P (tmpl)
+ && DECL_CLASS_SCOPE_P (tmpl)
+ /* DECL_CLASS_SCOPE_P holds of T::f even if T is a template
+ parameter. */
+ && CLASS_TYPE_P (DECL_CONTEXT (tmpl))
+ /* The optimized lookup depends on the fact that the
+ template arguments for the member function template apply
+ purely to the containing class, which is not true if the
+ containing class is an explicit or partial
+ specialization. */
+ && !CLASSTYPE_TEMPLATE_SPECIALIZATION (DECL_CONTEXT (tmpl))
+ && !DECL_MEMBER_TEMPLATE_P (tmpl)
+ && !DECL_CONV_FN_P (tmpl)
+ /* It is possible to have a template that is not a member
+ template and is not a member of a template class:
+
+ template <typename T>
+ struct S { friend A::f(); };
+
+ Here, the friend function is a template, but the context does
+ not have template information. The optimized lookup relies
+ on having ARGS be the template arguments for both the class
+ and the function template. */
+ && !DECL_FRIEND_P (DECL_TEMPLATE_RESULT (tmpl)));
+}
+
+/* Retrieve the specialization (in the sense of [temp.spec] - a
+ specialization is either an instantiation or an explicit
+ specialization) of TMPL for the given template ARGS. If there is
+ no such specialization, return NULL_TREE. The ARGS are a vector of
+ arguments, or a vector of vectors of arguments, in the case of
+ templates with more than one level of parameters.
+
+ If TMPL is a type template and CLASS_SPECIALIZATIONS_P is true,
+ then we search for a partial specialization matching ARGS. This
+ parameter is ignored if TMPL is not a class template.
+
+ We can also look up a FIELD_DECL, if it is a lambda capture pack; the
+ result is a NONTYPE_ARGUMENT_PACK. */
+
+static tree
+retrieve_specialization (tree tmpl, tree args, hashval_t hash)
+{
+ if (tmpl == NULL_TREE)
+ return NULL_TREE;
+
+ if (args == error_mark_node)
+ return NULL_TREE;
+
+ gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL
+ || TREE_CODE (tmpl) == FIELD_DECL);
+
+ /* There should be as many levels of arguments as there are
+ levels of parameters. */
+ gcc_assert (TMPL_ARGS_DEPTH (args)
+ == (TREE_CODE (tmpl) == TEMPLATE_DECL
+ ? TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))
+ : template_class_depth (DECL_CONTEXT (tmpl))));
+
+ if (optimize_specialization_lookup_p (tmpl))
+ {
+ tree class_template;
+ tree class_specialization;
+ vec<tree, va_gc> *methods;
+ tree fns;
+ int idx;
+
+ /* The template arguments actually apply to the containing
+ class. Find the class specialization with those
+ arguments. */
+ class_template = CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (tmpl));
+ class_specialization
+ = retrieve_specialization (class_template, args, 0);
+ if (!class_specialization)
+ return NULL_TREE;
+ /* Now, find the appropriate entry in the CLASSTYPE_METHOD_VEC
+ for the specialization. */
+ idx = class_method_index_for_fn (class_specialization, tmpl);
+ if (idx == -1)
+ return NULL_TREE;
+ /* Iterate through the methods with the indicated name, looking
+ for the one that has an instance of TMPL. */
+ methods = CLASSTYPE_METHOD_VEC (class_specialization);
+ for (fns = (*methods)[idx]; fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (DECL_TEMPLATE_INFO (fn) && DECL_TI_TEMPLATE (fn) == tmpl
+ /* using-declarations can add base methods to the method vec,
+ and we don't want those here. */
+ && DECL_CONTEXT (fn) == class_specialization)
+ return fn;
+ }
+ return NULL_TREE;
+ }
+ else
+ {
+ spec_entry *found;
+ spec_entry elt;
+ htab_t specializations;
+
+ elt.tmpl = tmpl;
+ elt.args = args;
+ elt.spec = NULL_TREE;
+
+ if (DECL_CLASS_TEMPLATE_P (tmpl))
+ specializations = type_specializations;
+ else
+ specializations = decl_specializations;
+
+ if (hash == 0)
+ hash = hash_specialization (&elt);
+ found = (spec_entry *) htab_find_with_hash (specializations, &elt, hash);
+ if (found)
+ return found->spec;
+ }
+
+ return NULL_TREE;
+}
+
+/* Like retrieve_specialization, but for local declarations. */
+
+static tree
+retrieve_local_specialization (tree tmpl)
+{
+ void **slot;
+
+ if (local_specializations == NULL)
+ return NULL_TREE;
+
+ slot = pointer_map_contains (local_specializations, tmpl);
+ return slot ? (tree) *slot : NULL_TREE;
+}
+
+/* Returns nonzero iff DECL is a specialization of TMPL. */
+
+int
+is_specialization_of (tree decl, tree tmpl)
+{
+ tree t;
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ for (t = decl;
+ t != NULL_TREE;
+ t = DECL_TEMPLATE_INFO (t) ? DECL_TI_TEMPLATE (t) : NULL_TREE)
+ if (t == tmpl)
+ return 1;
+ }
+ else
+ {
+ gcc_assert (TREE_CODE (decl) == TYPE_DECL);
+
+ for (t = TREE_TYPE (decl);
+ t != NULL_TREE;
+ t = CLASSTYPE_USE_TEMPLATE (t)
+ ? TREE_TYPE (CLASSTYPE_TI_TEMPLATE (t)) : NULL_TREE)
+ if (same_type_ignoring_top_level_qualifiers_p (t, TREE_TYPE (tmpl)))
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Returns nonzero iff DECL is a specialization of friend declaration
+ FRIEND_DECL according to [temp.friend]. */
+
+bool
+is_specialization_of_friend (tree decl, tree friend_decl)
+{
+ bool need_template = true;
+ int template_depth;
+
+ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == TYPE_DECL);
+
+ /* For [temp.friend/6] when FRIEND_DECL is an ordinary member function
+ of a template class, we want to check if DECL is a specialization
+ if this. */
+ if (TREE_CODE (friend_decl) == FUNCTION_DECL
+ && DECL_TEMPLATE_INFO (friend_decl)
+ && !DECL_USE_TEMPLATE (friend_decl))
+ {
+ /* We want a TEMPLATE_DECL for `is_specialization_of'. */
+ friend_decl = DECL_TI_TEMPLATE (friend_decl);
+ need_template = false;
+ }
+ else if (TREE_CODE (friend_decl) == TEMPLATE_DECL
+ && !PRIMARY_TEMPLATE_P (friend_decl))
+ need_template = false;
+
+ /* There is nothing to do if this is not a template friend. */
+ if (TREE_CODE (friend_decl) != TEMPLATE_DECL)
+ return false;
+
+ if (is_specialization_of (decl, friend_decl))
+ return true;
+
+ /* [temp.friend/6]
+ A member of a class template may be declared to be a friend of a
+ non-template class. In this case, the corresponding member of
+ every specialization of the class template is a friend of the
+ class granting friendship.
+
+ For example, given a template friend declaration
+
+ template <class T> friend void A<T>::f();
+
+ the member function below is considered a friend
+
+ template <> struct A<int> {
+ void f();
+ };
+
+ For this type of template friend, TEMPLATE_DEPTH below will be
+ nonzero. To determine if DECL is a friend of FRIEND, we first
+ check if the enclosing class is a specialization of another. */
+
+ template_depth = template_class_depth (CP_DECL_CONTEXT (friend_decl));
+ if (template_depth
+ && DECL_CLASS_SCOPE_P (decl)
+ && is_specialization_of (TYPE_NAME (DECL_CONTEXT (decl)),
+ CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (friend_decl))))
+ {
+ /* Next, we check the members themselves. In order to handle
+ a few tricky cases, such as when FRIEND_DECL's are
+
+ template <class T> friend void A<T>::g(T t);
+ template <class T> template <T t> friend void A<T>::h();
+
+ and DECL's are
+
+ void A<int>::g(int);
+ template <int> void A<int>::h();
+
+ we need to figure out ARGS, the template arguments from
+ the context of DECL. This is required for template substitution
+ of `T' in the function parameter of `g' and template parameter
+ of `h' in the above examples. Here ARGS corresponds to `int'. */
+
+ tree context = DECL_CONTEXT (decl);
+ tree args = NULL_TREE;
+ int current_depth = 0;
+
+ while (current_depth < template_depth)
+ {
+ if (CLASSTYPE_TEMPLATE_INFO (context))
+ {
+ if (current_depth == 0)
+ args = TYPE_TI_ARGS (context);
+ else
+ args = add_to_template_args (TYPE_TI_ARGS (context), args);
+ current_depth++;
+ }
+ context = TYPE_CONTEXT (context);
+ }
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ bool is_template;
+ tree friend_type;
+ tree decl_type;
+ tree friend_args_type;
+ tree decl_args_type;
+
+ /* Make sure that both DECL and FRIEND_DECL are templates or
+ non-templates. */
+ is_template = DECL_TEMPLATE_INFO (decl)
+ && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl));
+ if (need_template ^ is_template)
+ return false;
+ else if (is_template)
+ {
+ /* If both are templates, check template parameter list. */
+ tree friend_parms
+ = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_decl),
+ args, tf_none);
+ if (!comp_template_parms
+ (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl)),
+ friend_parms))
+ return false;
+
+ decl_type = TREE_TYPE (DECL_TI_TEMPLATE (decl));
+ }
+ else
+ decl_type = TREE_TYPE (decl);
+
+ friend_type = tsubst_function_type (TREE_TYPE (friend_decl), args,
+ tf_none, NULL_TREE);
+ if (friend_type == error_mark_node)
+ return false;
+
+ /* Check if return types match. */
+ if (!same_type_p (TREE_TYPE (decl_type), TREE_TYPE (friend_type)))
+ return false;
+
+ /* Check if function parameter types match, ignoring the
+ `this' parameter. */
+ friend_args_type = TYPE_ARG_TYPES (friend_type);
+ decl_args_type = TYPE_ARG_TYPES (decl_type);
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (friend_decl))
+ friend_args_type = TREE_CHAIN (friend_args_type);
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ decl_args_type = TREE_CHAIN (decl_args_type);
+
+ return compparms (decl_args_type, friend_args_type);
+ }
+ else
+ {
+ /* DECL is a TYPE_DECL */
+ bool is_template;
+ tree decl_type = TREE_TYPE (decl);
+
+ /* Make sure that both DECL and FRIEND_DECL are templates or
+ non-templates. */
+ is_template
+ = CLASSTYPE_TEMPLATE_INFO (decl_type)
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (decl_type));
+
+ if (need_template ^ is_template)
+ return false;
+ else if (is_template)
+ {
+ tree friend_parms;
+ /* If both are templates, check the name of the two
+ TEMPLATE_DECL's first because is_friend didn't. */
+ if (DECL_NAME (CLASSTYPE_TI_TEMPLATE (decl_type))
+ != DECL_NAME (friend_decl))
+ return false;
+
+ /* Now check template parameter list. */
+ friend_parms
+ = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_decl),
+ args, tf_none);
+ return comp_template_parms
+ (DECL_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (decl_type)),
+ friend_parms);
+ }
+ else
+ return (DECL_NAME (decl)
+ == DECL_NAME (friend_decl));
+ }
+ }
+ return false;
+}
+
+/* Register the specialization SPEC as a specialization of TMPL with
+ the indicated ARGS. IS_FRIEND indicates whether the specialization
+ is actually just a friend declaration. Returns SPEC, or an
+ equivalent prior declaration, if available.
+
+ We also store instantiations of field packs in the hash table, even
+ though they are not themselves templates, to make lookup easier. */
+
+static tree
+register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
+ hashval_t hash)
+{
+ tree fn;
+ void **slot = NULL;
+ spec_entry elt;
+
+ gcc_assert ((TREE_CODE (tmpl) == TEMPLATE_DECL && DECL_P (spec))
+ || (TREE_CODE (tmpl) == FIELD_DECL
+ && TREE_CODE (spec) == NONTYPE_ARGUMENT_PACK));
+
+ if (TREE_CODE (spec) == FUNCTION_DECL
+ && uses_template_parms (DECL_TI_ARGS (spec)))
+ /* This is the FUNCTION_DECL for a partial instantiation. Don't
+ register it; we want the corresponding TEMPLATE_DECL instead.
+ We use `uses_template_parms (DECL_TI_ARGS (spec))' rather than
+ the more obvious `uses_template_parms (spec)' to avoid problems
+ with default function arguments. In particular, given
+ something like this:
+
+ template <class T> void f(T t1, T t = T())
+
+ the default argument expression is not substituted for in an
+ instantiation unless and until it is actually needed. */
+ return spec;
+
+ if (optimize_specialization_lookup_p (tmpl))
+ /* We don't put these specializations in the hash table, but we might
+ want to give an error about a mismatch. */
+ fn = retrieve_specialization (tmpl, args, 0);
+ else
+ {
+ elt.tmpl = tmpl;
+ elt.args = args;
+ elt.spec = spec;
+
+ if (hash == 0)
+ hash = hash_specialization (&elt);
+
+ slot =
+ htab_find_slot_with_hash (decl_specializations, &elt, hash, INSERT);
+ if (*slot)
+ fn = ((spec_entry *) *slot)->spec;
+ else
+ fn = NULL_TREE;
+ }
+
+ /* We can sometimes try to re-register a specialization that we've
+ already got. In particular, regenerate_decl_from_template calls
+ duplicate_decls which will update the specialization list. But,
+ we'll still get called again here anyhow. It's more convenient
+ to simply allow this than to try to prevent it. */
+ if (fn == spec)
+ return spec;
+ else if (fn && DECL_TEMPLATE_SPECIALIZATION (spec))
+ {
+ if (DECL_TEMPLATE_INSTANTIATION (fn))
+ {
+ if (DECL_ODR_USED (fn)
+ || DECL_EXPLICIT_INSTANTIATION (fn))
+ {
+ error ("specialization of %qD after instantiation",
+ fn);
+ return error_mark_node;
+ }
+ else
+ {
+ tree clone;
+ /* This situation should occur only if the first
+ specialization is an implicit instantiation, the
+ second is an explicit specialization, and the
+ implicit instantiation has not yet been used. That
+ situation can occur if we have implicitly
+ instantiated a member function and then specialized
+ it later.
+
+ We can also wind up here if a friend declaration that
+ looked like an instantiation turns out to be a
+ specialization:
+
+ template <class T> void foo(T);
+ class S { friend void foo<>(int) };
+ template <> void foo(int);
+
+ We transform the existing DECL in place so that any
+ pointers to it become pointers to the updated
+ declaration.
+
+ If there was a definition for the template, but not
+ for the specialization, we want this to look as if
+ there were no definition, and vice versa. */
+ DECL_INITIAL (fn) = NULL_TREE;
+ duplicate_decls (spec, fn, is_friend);
+ /* The call to duplicate_decls will have applied
+ [temp.expl.spec]:
+
+ An explicit specialization of a function template
+ is inline only if it is explicitly declared to be,
+ and independently of whether its function template
+ is.
+
+ to the primary function; now copy the inline bits to
+ the various clones. */
+ FOR_EACH_CLONE (clone, fn)
+ {
+ DECL_DECLARED_INLINE_P (clone)
+ = DECL_DECLARED_INLINE_P (fn);
+ DECL_SOURCE_LOCATION (clone)
+ = DECL_SOURCE_LOCATION (fn);
+ DECL_DELETED_FN (clone)
+ = DECL_DELETED_FN (fn);
+ }
+ check_specialization_namespace (tmpl);
+
+ return fn;
+ }
+ }
+ else if (DECL_TEMPLATE_SPECIALIZATION (fn))
+ {
+ if (!duplicate_decls (spec, fn, is_friend) && DECL_INITIAL (spec))
+ /* Dup decl failed, but this is a new definition. Set the
+ line number so any errors match this new
+ definition. */
+ DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (spec);
+
+ return fn;
+ }
+ }
+ else if (fn)
+ return duplicate_decls (spec, fn, is_friend);
+
+ /* A specialization must be declared in the same namespace as the
+ template it is specializing. */
+ if (DECL_P (spec) && DECL_TEMPLATE_SPECIALIZATION (spec)
+ && !check_specialization_namespace (tmpl))
+ DECL_CONTEXT (spec) = DECL_CONTEXT (tmpl);
+
+ if (slot != NULL /* !optimize_specialization_lookup_p (tmpl) */)
+ {
+ spec_entry *entry = ggc_alloc_spec_entry ();
+ gcc_assert (tmpl && args && spec);
+ *entry = elt;
+ *slot = entry;
+ if (TREE_CODE (spec) == FUNCTION_DECL && DECL_NAMESPACE_SCOPE_P (spec)
+ && PRIMARY_TEMPLATE_P (tmpl)
+ && DECL_SAVED_TREE (DECL_TEMPLATE_RESULT (tmpl)) == NULL_TREE)
+ /* TMPL is a forward declaration of a template function; keep a list
+ of all specializations in case we need to reassign them to a friend
+ template later in tsubst_friend_function. */
+ DECL_TEMPLATE_INSTANTIATIONS (tmpl)
+ = tree_cons (args, spec, DECL_TEMPLATE_INSTANTIATIONS (tmpl));
+ }
+
+ return spec;
+}
+
+/* Returns true iff two spec_entry nodes are equivalent. Only compares the
+ TMPL and ARGS members, ignores SPEC. */
+
+int comparing_specializations;
+
+static int
+eq_specializations (const void *p1, const void *p2)
+{
+ const spec_entry *e1 = (const spec_entry *)p1;
+ const spec_entry *e2 = (const spec_entry *)p2;
+ int equal;
+
+ ++comparing_specializations;
+ equal = (e1->tmpl == e2->tmpl
+ && comp_template_args (e1->args, e2->args));
+ --comparing_specializations;
+
+ return equal;
+}
+
+/* Returns a hash for a template TMPL and template arguments ARGS. */
+
+static hashval_t
+hash_tmpl_and_args (tree tmpl, tree args)
+{
+ hashval_t val = DECL_UID (tmpl);
+ return iterative_hash_template_arg (args, val);
+}
+
+/* Returns a hash for a spec_entry node based on the TMPL and ARGS members,
+ ignoring SPEC. */
+
+static hashval_t
+hash_specialization (const void *p)
+{
+ const spec_entry *e = (const spec_entry *)p;
+ return hash_tmpl_and_args (e->tmpl, e->args);
+}
+
+/* Recursively calculate a hash value for a template argument ARG, for use
+ in the hash tables of template specializations. */
+
+hashval_t
+iterative_hash_template_arg (tree arg, hashval_t val)
+{
+ unsigned HOST_WIDE_INT i;
+ enum tree_code code;
+ char tclass;
+
+ if (arg == NULL_TREE)
+ return iterative_hash_object (arg, val);
+
+ if (!TYPE_P (arg))
+ STRIP_NOPS (arg);
+
+ if (TREE_CODE (arg) == ARGUMENT_PACK_SELECT)
+ /* We can get one of these when re-hashing a previous entry in the middle
+ of substituting into a pack expansion. Just look through it. */
+ arg = ARGUMENT_PACK_SELECT_FROM_PACK (arg);
+
+ code = TREE_CODE (arg);
+ tclass = TREE_CODE_CLASS (code);
+
+ val = iterative_hash_object (code, val);
+
+ switch (code)
+ {
+ case ERROR_MARK:
+ return val;
+
+ case IDENTIFIER_NODE:
+ return iterative_hash_object (IDENTIFIER_HASH_VALUE (arg), val);
+
+ case TREE_VEC:
+ {
+ int i, len = TREE_VEC_LENGTH (arg);
+ for (i = 0; i < len; ++i)
+ val = iterative_hash_template_arg (TREE_VEC_ELT (arg, i), val);
+ return val;
+ }
+
+ case TYPE_PACK_EXPANSION:
+ case EXPR_PACK_EXPANSION:
+ val = iterative_hash_template_arg (PACK_EXPANSION_PATTERN (arg), val);
+ return iterative_hash_template_arg (PACK_EXPANSION_EXTRA_ARGS (arg), val);
+
+ case TYPE_ARGUMENT_PACK:
+ case NONTYPE_ARGUMENT_PACK:
+ return iterative_hash_template_arg (ARGUMENT_PACK_ARGS (arg), val);
+
+ case TREE_LIST:
+ for (; arg; arg = TREE_CHAIN (arg))
+ val = iterative_hash_template_arg (TREE_VALUE (arg), val);
+ return val;
+
+ case OVERLOAD:
+ for (; arg; arg = OVL_NEXT (arg))
+ val = iterative_hash_template_arg (OVL_CURRENT (arg), val);
+ return val;
+
+ case CONSTRUCTOR:
+ {
+ tree field, value;
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (arg), i, field, value)
+ {
+ val = iterative_hash_template_arg (field, val);
+ val = iterative_hash_template_arg (value, val);
+ }
+ return val;
+ }
+
+ case PARM_DECL:
+ if (!DECL_ARTIFICIAL (arg))
+ {
+ val = iterative_hash_object (DECL_PARM_INDEX (arg), val);
+ val = iterative_hash_object (DECL_PARM_LEVEL (arg), val);
+ }
+ return iterative_hash_template_arg (TREE_TYPE (arg), val);
+
+ case TARGET_EXPR:
+ return iterative_hash_template_arg (TARGET_EXPR_INITIAL (arg), val);
+
+ case PTRMEM_CST:
+ val = iterative_hash_template_arg (PTRMEM_CST_CLASS (arg), val);
+ return iterative_hash_template_arg (PTRMEM_CST_MEMBER (arg), val);
+
+ case TEMPLATE_PARM_INDEX:
+ val = iterative_hash_template_arg
+ (TREE_TYPE (TEMPLATE_PARM_DECL (arg)), val);
+ val = iterative_hash_object (TEMPLATE_PARM_LEVEL (arg), val);
+ return iterative_hash_object (TEMPLATE_PARM_IDX (arg), val);
+
+ case TRAIT_EXPR:
+ val = iterative_hash_object (TRAIT_EXPR_KIND (arg), val);
+ val = iterative_hash_template_arg (TRAIT_EXPR_TYPE1 (arg), val);
+ return iterative_hash_template_arg (TRAIT_EXPR_TYPE2 (arg), val);
+
+ case BASELINK:
+ val = iterative_hash_template_arg (BINFO_TYPE (BASELINK_BINFO (arg)),
+ val);
+ return iterative_hash_template_arg (DECL_NAME (get_first_fn (arg)),
+ val);
+
+ case MODOP_EXPR:
+ val = iterative_hash_template_arg (TREE_OPERAND (arg, 0), val);
+ code = TREE_CODE (TREE_OPERAND (arg, 1));
+ val = iterative_hash_object (code, val);
+ return iterative_hash_template_arg (TREE_OPERAND (arg, 2), val);
+
+ case LAMBDA_EXPR:
+ /* A lambda can't appear in a template arg, but don't crash on
+ erroneous input. */
+ gcc_assert (seen_error ());
+ return val;
+
+ case CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
+ case STATIC_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case NEW_EXPR:
+ val = iterative_hash_template_arg (TREE_TYPE (arg), val);
+ /* Now hash operands as usual. */
+ break;
+
+ default:
+ break;
+ }
+
+ switch (tclass)
+ {
+ case tcc_type:
+ if (TYPE_CANONICAL (arg))
+ return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)),
+ val);
+ else if (TREE_CODE (arg) == DECLTYPE_TYPE)
+ return iterative_hash_template_arg (DECLTYPE_TYPE_EXPR (arg), val);
+ /* Otherwise just compare the types during lookup. */
+ return val;
+
+ case tcc_declaration:
+ case tcc_constant:
+ return iterative_hash_expr (arg, val);
+
+ default:
+ gcc_assert (IS_EXPR_CODE_CLASS (tclass));
+ {
+ unsigned n = cp_tree_operand_length (arg);
+ for (i = 0; i < n; ++i)
+ val = iterative_hash_template_arg (TREE_OPERAND (arg, i), val);
+ return val;
+ }
+ }
+ gcc_unreachable ();
+ return 0;
+}
+
+/* Unregister the specialization SPEC as a specialization of TMPL.
+ Replace it with NEW_SPEC, if NEW_SPEC is non-NULL. Returns true
+ if the SPEC was listed as a specialization of TMPL.
+
+ Note that SPEC has been ggc_freed, so we can't look inside it. */
+
+bool
+reregister_specialization (tree spec, tree tinfo, tree new_spec)
+{
+ spec_entry *entry;
+ spec_entry elt;
+
+ elt.tmpl = most_general_template (TI_TEMPLATE (tinfo));
+ elt.args = TI_ARGS (tinfo);
+ elt.spec = NULL_TREE;
+
+ entry = (spec_entry *) htab_find (decl_specializations, &elt);
+ if (entry != NULL)
+ {
+ gcc_assert (entry->spec == spec || entry->spec == new_spec);
+ gcc_assert (new_spec != NULL_TREE);
+ entry->spec = new_spec;
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Like register_specialization, but for local declarations. We are
+ registering SPEC, an instantiation of TMPL. */
+
+static void
+register_local_specialization (tree spec, tree tmpl)
+{
+ void **slot;
+
+ slot = pointer_map_insert (local_specializations, tmpl);
+ *slot = spec;
+}
+
+/* TYPE is a class type. Returns true if TYPE is an explicitly
+ specialized class. */
+
+bool
+explicit_class_specialization_p (tree type)
+{
+ if (!CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
+ return false;
+ return !uses_template_parms (CLASSTYPE_TI_ARGS (type));
+}
+
+/* Print the list of functions at FNS, going through all the overloads
+ for each element of the list. Alternatively, FNS can not be a
+ TREE_LIST, in which case it will be printed together with all the
+ overloads.
+
+ MORE and *STR should respectively be FALSE and NULL when the function
+ is called from the outside. They are used internally on recursive
+ calls. print_candidates manages the two parameters and leaves NULL
+ in *STR when it ends. */
+
+static void
+print_candidates_1 (tree fns, bool more, const char **str)
+{
+ tree fn, fn2;
+ char *spaces = NULL;
+
+ for (fn = fns; fn; fn = OVL_NEXT (fn))
+ if (TREE_CODE (fn) == TREE_LIST)
+ {
+ for (fn2 = fn; fn2 != NULL_TREE; fn2 = TREE_CHAIN (fn2))
+ print_candidates_1 (TREE_VALUE (fn2),
+ TREE_CHAIN (fn2) || more, str);
+ }
+ else
+ {
+ tree cand = OVL_CURRENT (fn);
+ if (!*str)
+ {
+ /* Pick the prefix string. */
+ if (!more && !OVL_NEXT (fns))
+ {
+ inform (DECL_SOURCE_LOCATION (cand),
+ "candidate is: %#D", cand);
+ continue;
+ }
+
+ *str = _("candidates are:");
+ spaces = get_spaces (*str);
+ }
+ inform (DECL_SOURCE_LOCATION (cand), "%s %#D", *str, cand);
+ *str = spaces ? spaces : *str;
+ }
+
+ if (!more)
+ {
+ free (spaces);
+ *str = NULL;
+ }
+}
+
+/* Print the list of candidate FNS in an error message. FNS can also
+ be a TREE_LIST of non-functions in the case of an ambiguous lookup. */
+
+void
+print_candidates (tree fns)
+{
+ const char *str = NULL;
+ print_candidates_1 (fns, false, &str);
+ gcc_assert (str == NULL);
+}
+
+/* Returns the template (one of the functions given by TEMPLATE_ID)
+ which can be specialized to match the indicated DECL with the
+ explicit template args given in TEMPLATE_ID. The DECL may be
+ NULL_TREE if none is available. In that case, the functions in
+ TEMPLATE_ID are non-members.
+
+ If NEED_MEMBER_TEMPLATE is nonzero the function is known to be a
+ specialization of a member template.
+
+ The TEMPLATE_COUNT is the number of references to qualifying
+ template classes that appeared in the name of the function. See
+ check_explicit_specialization for a more accurate description.
+
+ TSK indicates what kind of template declaration (if any) is being
+ declared. TSK_TEMPLATE indicates that the declaration given by
+ DECL, though a FUNCTION_DECL, has template parameters, and is
+ therefore a template function.
+
+ The template args (those explicitly specified and those deduced)
+ are output in a newly created vector *TARGS_OUT.
+
+ If it is impossible to determine the result, an error message is
+ issued. The error_mark_node is returned to indicate failure. */
+
+static tree
+determine_specialization (tree template_id,
+ tree decl,
+ tree* targs_out,
+ int need_member_template,
+ int template_count,
+ tmpl_spec_kind tsk)
+{
+ tree fns;
+ tree targs;
+ tree explicit_targs;
+ tree candidates = NULL_TREE;
+ /* A TREE_LIST of templates of which DECL may be a specialization.
+ The TREE_VALUE of each node is a TEMPLATE_DECL. The
+ corresponding TREE_PURPOSE is the set of template arguments that,
+ when used to instantiate the template, would produce a function
+ with the signature of DECL. */
+ tree templates = NULL_TREE;
+ int header_count;
+ cp_binding_level *b;
+
+ *targs_out = NULL_TREE;
+
+ if (template_id == error_mark_node || decl == error_mark_node)
+ return error_mark_node;
+
+ /* We shouldn't be specializing a member template of an
+ unspecialized class template; we already gave an error in
+ check_specialization_scope, now avoid crashing. */
+ if (template_count && DECL_CLASS_SCOPE_P (decl)
+ && template_class_depth (DECL_CONTEXT (decl)) > 0)
+ {
+ gcc_assert (errorcount);
+ return error_mark_node;
+ }
+
+ fns = TREE_OPERAND (template_id, 0);
+ explicit_targs = TREE_OPERAND (template_id, 1);
+
+ if (fns == error_mark_node)
+ return error_mark_node;
+
+ /* Check for baselinks. */
+ if (BASELINK_P (fns))
+ fns = BASELINK_FUNCTIONS (fns);
+
+ if (!is_overloaded_fn (fns))
+ {
+ error ("%qD is not a function template", fns);
+ return error_mark_node;
+ }
+
+ /* Count the number of template headers specified for this
+ specialization. */
+ header_count = 0;
+ for (b = current_binding_level;
+ b->kind == sk_template_parms;
+ b = b->level_chain)
+ ++header_count;
+
+ for (; fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ {
+ tree decl_arg_types;
+ tree fn_arg_types;
+ tree insttype;
+
+ /* In case of explicit specialization, we need to check if
+ the number of template headers appearing in the specialization
+ is correct. This is usually done in check_explicit_specialization,
+ but the check done there cannot be exhaustive when specializing
+ member functions. Consider the following code:
+
+ template <> void A<int>::f(int);
+ template <> template <> void A<int>::f(int);
+
+ Assuming that A<int> is not itself an explicit specialization
+ already, the first line specializes "f" which is a non-template
+ member function, whilst the second line specializes "f" which
+ is a template member function. So both lines are syntactically
+ correct, and check_explicit_specialization does not reject
+ them.
+
+ Here, we can do better, as we are matching the specialization
+ against the declarations. We count the number of template
+ headers, and we check if they match TEMPLATE_COUNT + 1
+ (TEMPLATE_COUNT is the number of qualifying template classes,
+ plus there must be another header for the member template
+ itself).
+
+ Notice that if header_count is zero, this is not a
+ specialization but rather a template instantiation, so there
+ is no check we can perform here. */
+ if (header_count && header_count != template_count + 1)
+ continue;
+
+ /* Check that the number of template arguments at the
+ innermost level for DECL is the same as for FN. */
+ if (current_binding_level->kind == sk_template_parms
+ && !current_binding_level->explicit_spec_p
+ && (TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (fn))
+ != TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS
+ (current_template_parms))))
+ continue;
+
+ /* DECL might be a specialization of FN. */
+ decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
+
+ /* For a non-static member function, we need to make sure
+ that the const qualification is the same. Since
+ get_bindings does not try to merge the "this" parameter,
+ we must do the comparison explicitly. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !same_type_p (TREE_VALUE (fn_arg_types),
+ TREE_VALUE (decl_arg_types)))
+ continue;
+
+ /* Skip the "this" parameter and, for constructors of
+ classes with virtual bases, the VTT parameter. A
+ full specialization of a constructor will have a VTT
+ parameter, but a template never will. */
+ decl_arg_types
+ = skip_artificial_parms_for (decl, decl_arg_types);
+ fn_arg_types
+ = skip_artificial_parms_for (fn, fn_arg_types);
+
+ /* Function templates cannot be specializations; there are
+ no partial specializations of functions. Therefore, if
+ the type of DECL does not match FN, there is no
+ match. */
+ if (tsk == tsk_template)
+ {
+ if (compparms (fn_arg_types, decl_arg_types))
+ candidates = tree_cons (NULL_TREE, fn, candidates);
+ continue;
+ }
+
+ /* See whether this function might be a specialization of this
+ template. Suppress access control because we might be trying
+ to make this specialization a friend, and we have already done
+ access control for the declaration of the specialization. */
+ push_deferring_access_checks (dk_no_check);
+ targs = get_bindings (fn, decl, explicit_targs, /*check_ret=*/true);
+ pop_deferring_access_checks ();
+
+ if (!targs)
+ /* We cannot deduce template arguments that when used to
+ specialize TMPL will produce DECL. */
+ continue;
+
+ /* Make sure that the deduced arguments actually work. */
+ insttype = tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE);
+ if (insttype == error_mark_node)
+ continue;
+ fn_arg_types
+ = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (insttype));
+ if (!compparms (fn_arg_types, decl_arg_types))
+ continue;
+
+ /* Save this template, and the arguments deduced. */
+ templates = tree_cons (targs, fn, templates);
+ }
+ else if (need_member_template)
+ /* FN is an ordinary member function, and we need a
+ specialization of a member template. */
+ ;
+ else if (TREE_CODE (fn) != FUNCTION_DECL)
+ /* We can get IDENTIFIER_NODEs here in certain erroneous
+ cases. */
+ ;
+ else if (!DECL_FUNCTION_MEMBER_P (fn))
+ /* This is just an ordinary non-member function. Nothing can
+ be a specialization of that. */
+ ;
+ else if (DECL_ARTIFICIAL (fn))
+ /* Cannot specialize functions that are created implicitly. */
+ ;
+ else
+ {
+ tree decl_arg_types;
+
+ /* This is an ordinary member function. However, since
+ we're here, we can assume its enclosing class is a
+ template class. For example,
+
+ template <typename T> struct S { void f(); };
+ template <> void S<int>::f() {}
+
+ Here, S<int>::f is a non-template, but S<int> is a
+ template class. If FN has the same type as DECL, we
+ might be in business. */
+
+ if (!DECL_TEMPLATE_INFO (fn))
+ /* Its enclosing class is an explicit specialization
+ of a template class. This is not a candidate. */
+ continue;
+
+ if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),
+ TREE_TYPE (TREE_TYPE (fn))))
+ /* The return types differ. */
+ continue;
+
+ /* Adjust the type of DECL in case FN is a static member. */
+ decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ if (DECL_STATIC_FUNCTION_P (fn)
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ decl_arg_types = TREE_CHAIN (decl_arg_types);
+
+ if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
+ decl_arg_types))
+ /* They match! */
+ candidates = tree_cons (NULL_TREE, fn, candidates);
+ }
+ }
+
+ if (templates && TREE_CHAIN (templates))
+ {
+ /* We have:
+
+ [temp.expl.spec]
+
+ It is possible for a specialization with a given function
+ signature to be instantiated from more than one function
+ template. In such cases, explicit specification of the
+ template arguments must be used to uniquely identify the
+ function template specialization being specialized.
+
+ Note that here, there's no suggestion that we're supposed to
+ determine which of the candidate templates is most
+ specialized. However, we, also have:
+
+ [temp.func.order]
+
+ Partial ordering of overloaded function template
+ declarations is used in the following contexts to select
+ the function template to which a function template
+ specialization refers:
+
+ -- when an explicit specialization refers to a function
+ template.
+
+ So, we do use the partial ordering rules, at least for now.
+ This extension can only serve to make invalid programs valid,
+ so it's safe. And, there is strong anecdotal evidence that
+ the committee intended the partial ordering rules to apply;
+ the EDG front end has that behavior, and John Spicer claims
+ that the committee simply forgot to delete the wording in
+ [temp.expl.spec]. */
+ tree tmpl = most_specialized_instantiation (templates);
+ if (tmpl != error_mark_node)
+ {
+ templates = tmpl;
+ TREE_CHAIN (templates) = NULL_TREE;
+ }
+ }
+
+ if (templates == NULL_TREE && candidates == NULL_TREE)
+ {
+ error ("template-id %qD for %q+D does not match any template "
+ "declaration", template_id, decl);
+ if (header_count && header_count != template_count + 1)
+ inform (input_location, "saw %d %<template<>%>, need %d for "
+ "specializing a member function template",
+ header_count, template_count + 1);
+ return error_mark_node;
+ }
+ else if ((templates && TREE_CHAIN (templates))
+ || (candidates && TREE_CHAIN (candidates))
+ || (templates && candidates))
+ {
+ error ("ambiguous template specialization %qD for %q+D",
+ template_id, decl);
+ candidates = chainon (candidates, templates);
+ print_candidates (candidates);
+ return error_mark_node;
+ }
+
+ /* We have one, and exactly one, match. */
+ if (candidates)
+ {
+ tree fn = TREE_VALUE (candidates);
+ *targs_out = copy_node (DECL_TI_ARGS (fn));
+ /* DECL is a re-declaration or partial instantiation of a template
+ function. */
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ return fn;
+ /* It was a specialization of an ordinary member function in a
+ template class. */
+ return DECL_TI_TEMPLATE (fn);
+ }
+
+ /* It was a specialization of a template. */
+ targs = DECL_TI_ARGS (DECL_TEMPLATE_RESULT (TREE_VALUE (templates)));
+ if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (targs))
+ {
+ *targs_out = copy_node (targs);
+ SET_TMPL_ARGS_LEVEL (*targs_out,
+ TMPL_ARGS_DEPTH (*targs_out),
+ TREE_PURPOSE (templates));
+ }
+ else
+ *targs_out = TREE_PURPOSE (templates);
+ return TREE_VALUE (templates);
+}
+
+/* Returns a chain of parameter types, exactly like the SPEC_TYPES,
+ but with the default argument values filled in from those in the
+ TMPL_TYPES. */
+
+static tree
+copy_default_args_to_explicit_spec_1 (tree spec_types,
+ tree tmpl_types)
+{
+ tree new_spec_types;
+
+ if (!spec_types)
+ return NULL_TREE;
+
+ if (spec_types == void_list_node)
+ return void_list_node;
+
+ /* Substitute into the rest of the list. */
+ new_spec_types =
+ copy_default_args_to_explicit_spec_1 (TREE_CHAIN (spec_types),
+ TREE_CHAIN (tmpl_types));
+
+ /* Add the default argument for this parameter. */
+ return hash_tree_cons (TREE_PURPOSE (tmpl_types),
+ TREE_VALUE (spec_types),
+ new_spec_types);
+}
+
+/* DECL is an explicit specialization. Replicate default arguments
+ from the template it specializes. (That way, code like:
+
+ template <class T> void f(T = 3);
+ template <> void f(double);
+ void g () { f (); }
+
+ works, as required.) An alternative approach would be to look up
+ the correct default arguments at the call-site, but this approach
+ is consistent with how implicit instantiations are handled. */
+
+static void
+copy_default_args_to_explicit_spec (tree decl)
+{
+ tree tmpl;
+ tree spec_types;
+ tree tmpl_types;
+ tree new_spec_types;
+ tree old_type;
+ tree new_type;
+ tree t;
+ tree object_type = NULL_TREE;
+ tree in_charge = NULL_TREE;
+ tree vtt = NULL_TREE;
+
+ /* See if there's anything we need to do. */
+ tmpl = DECL_TI_TEMPLATE (decl);
+ tmpl_types = TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (tmpl)));
+ for (t = tmpl_types; t; t = TREE_CHAIN (t))
+ if (TREE_PURPOSE (t))
+ break;
+ if (!t)
+ return;
+
+ old_type = TREE_TYPE (decl);
+ spec_types = TYPE_ARG_TYPES (old_type);
+
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ {
+ /* Remove the this pointer, but remember the object's type for
+ CV quals. */
+ object_type = TREE_TYPE (TREE_VALUE (spec_types));
+ spec_types = TREE_CHAIN (spec_types);
+ tmpl_types = TREE_CHAIN (tmpl_types);
+
+ if (DECL_HAS_IN_CHARGE_PARM_P (decl))
+ {
+ /* DECL may contain more parameters than TMPL due to the extra
+ in-charge parameter in constructors and destructors. */
+ in_charge = spec_types;
+ spec_types = TREE_CHAIN (spec_types);
+ }
+ if (DECL_HAS_VTT_PARM_P (decl))
+ {
+ vtt = spec_types;
+ spec_types = TREE_CHAIN (spec_types);
+ }
+ }
+
+ /* Compute the merged default arguments. */
+ new_spec_types =
+ copy_default_args_to_explicit_spec_1 (spec_types, tmpl_types);
+
+ /* Compute the new FUNCTION_TYPE. */
+ if (object_type)
+ {
+ if (vtt)
+ new_spec_types = hash_tree_cons (TREE_PURPOSE (vtt),
+ TREE_VALUE (vtt),
+ new_spec_types);
+
+ if (in_charge)
+ /* Put the in-charge parameter back. */
+ new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),
+ TREE_VALUE (in_charge),
+ new_spec_types);
+
+ new_type = build_method_type_directly (object_type,
+ TREE_TYPE (old_type),
+ new_spec_types);
+ }
+ else
+ new_type = build_function_type (TREE_TYPE (old_type),
+ new_spec_types);
+ new_type = cp_build_type_attribute_variant (new_type,
+ TYPE_ATTRIBUTES (old_type));
+ new_type = build_exception_variant (new_type,
+ TYPE_RAISES_EXCEPTIONS (old_type));
+ TREE_TYPE (decl) = new_type;
+}
+
+/* Return the number of template headers we expect to see for a definition
+ or specialization of CTYPE or one of its non-template members. */
+
+int
+num_template_headers_for_class (tree ctype)
+{
+ int num_templates = 0;
+
+ while (ctype && CLASS_TYPE_P (ctype))
+ {
+ /* You're supposed to have one `template <...>' for every
+ template class, but you don't need one for a full
+ specialization. For example:
+
+ template <class T> struct S{};
+ template <> struct S<int> { void f(); };
+ void S<int>::f () {}
+
+ is correct; there shouldn't be a `template <>' for the
+ definition of `S<int>::f'. */
+ if (!CLASSTYPE_TEMPLATE_INFO (ctype))
+ /* If CTYPE does not have template information of any
+ kind, then it is not a template, nor is it nested
+ within a template. */
+ break;
+ if (explicit_class_specialization_p (ctype))
+ break;
+ if (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (ctype)))
+ ++num_templates;
+
+ ctype = TYPE_CONTEXT (ctype);
+ }
+
+ return num_templates;
+}
+
+/* Do a simple sanity check on the template headers that precede the
+ variable declaration DECL. */
+
+void
+check_template_variable (tree decl)
+{
+ tree ctx = CP_DECL_CONTEXT (decl);
+ int wanted = num_template_headers_for_class (ctx);
+ if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx))
+ permerror (DECL_SOURCE_LOCATION (decl),
+ "%qD is not a static data member of a class template", decl);
+ else if (template_header_count > wanted)
+ {
+ pedwarn (DECL_SOURCE_LOCATION (decl), 0,
+ "too many template headers for %D (should be %d)",
+ decl, wanted);
+ if (CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx))
+ inform (DECL_SOURCE_LOCATION (decl),
+ "members of an explicitly specialized class are defined "
+ "without a template header");
+ }
+}
+
+/* Check to see if the function just declared, as indicated in
+ DECLARATOR, and in DECL, is a specialization of a function
+ template. We may also discover that the declaration is an explicit
+ instantiation at this point.
+
+ Returns DECL, or an equivalent declaration that should be used
+ instead if all goes well. Issues an error message if something is
+ amiss. Returns error_mark_node if the error is not easily
+ recoverable.
+
+ FLAGS is a bitmask consisting of the following flags:
+
+ 2: The function has a definition.
+ 4: The function is a friend.
+
+ The TEMPLATE_COUNT is the number of references to qualifying
+ template classes that appeared in the name of the function. For
+ example, in
+
+ template <class T> struct S { void f(); };
+ void S<int>::f();
+
+ the TEMPLATE_COUNT would be 1. However, explicitly specialized
+ classes are not counted in the TEMPLATE_COUNT, so that in
+
+ template <class T> struct S {};
+ template <> struct S<int> { void f(); }
+ template <> void S<int>::f();
+
+ the TEMPLATE_COUNT would be 0. (Note that this declaration is
+ invalid; there should be no template <>.)
+
+ If the function is a specialization, it is marked as such via
+ DECL_TEMPLATE_SPECIALIZATION. Furthermore, its DECL_TEMPLATE_INFO
+ is set up correctly, and it is added to the list of specializations
+ for that template. */
+
+tree
+check_explicit_specialization (tree declarator,
+ tree decl,
+ int template_count,
+ int flags)
+{
+ int have_def = flags & 2;
+ int is_friend = flags & 4;
+ int specialization = 0;
+ int explicit_instantiation = 0;
+ int member_specialization = 0;
+ tree ctype = DECL_CLASS_CONTEXT (decl);
+ tree dname = DECL_NAME (decl);
+ tmpl_spec_kind tsk;
+
+ if (is_friend)
+ {
+ if (!processing_specialization)
+ tsk = tsk_none;
+ else
+ tsk = tsk_excessive_parms;
+ }
+ else
+ tsk = current_tmpl_spec_kind (template_count);
+
+ switch (tsk)
+ {
+ case tsk_none:
+ if (processing_specialization)
+ {
+ specialization = 1;
+ SET_DECL_TEMPLATE_SPECIALIZATION (decl);
+ }
+ else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
+ {
+ if (is_friend)
+ /* This could be something like:
+
+ template <class T> void f(T);
+ class S { friend void f<>(int); } */
+ specialization = 1;
+ else
+ {
+ /* This case handles bogus declarations like template <>
+ template <class T> void f<int>(); */
+
+ error ("template-id %qD in declaration of primary template",
+ declarator);
+ return decl;
+ }
+ }
+ break;
+
+ case tsk_invalid_member_spec:
+ /* The error has already been reported in
+ check_specialization_scope. */
+ return error_mark_node;
+
+ case tsk_invalid_expl_inst:
+ error ("template parameter list used in explicit instantiation");
+
+ /* Fall through. */
+
+ case tsk_expl_inst:
+ if (have_def)
+ error ("definition provided for explicit instantiation");
+
+ explicit_instantiation = 1;
+ break;
+
+ case tsk_excessive_parms:
+ case tsk_insufficient_parms:
+ if (tsk == tsk_excessive_parms)
+ error ("too many template parameter lists in declaration of %qD",
+ decl);
+ else if (template_header_count)
+ error("too few template parameter lists in declaration of %qD", decl);
+ else
+ error("explicit specialization of %qD must be introduced by "
+ "%<template <>%>", decl);
+
+ /* Fall through. */
+ case tsk_expl_spec:
+ SET_DECL_TEMPLATE_SPECIALIZATION (decl);
+ if (ctype)
+ member_specialization = 1;
+ else
+ specialization = 1;
+ break;
+
+ case tsk_template:
+ if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
+ {
+ /* This case handles bogus declarations like template <>
+ template <class T> void f<int>(); */
+
+ if (uses_template_parms (declarator))
+ error ("function template partial specialization %qD "
+ "is not allowed", declarator);
+ else
+ error ("template-id %qD in declaration of primary template",
+ declarator);
+ return decl;
+ }
+
+ if (ctype && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
+ /* This is a specialization of a member template, without
+ specialization the containing class. Something like:
+
+ template <class T> struct S {
+ template <class U> void f (U);
+ };
+ template <> template <class U> void S<int>::f(U) {}
+
+ That's a specialization -- but of the entire template. */
+ specialization = 1;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (specialization || member_specialization)
+ {
+ tree t = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ for (; t; t = TREE_CHAIN (t))
+ if (TREE_PURPOSE (t))
+ {
+ permerror (input_location,
+ "default argument specified in explicit specialization");
+ break;
+ }
+ }
+
+ if (specialization || member_specialization || explicit_instantiation)
+ {
+ tree tmpl = NULL_TREE;
+ tree targs = NULL_TREE;
+
+ /* Make sure that the declarator is a TEMPLATE_ID_EXPR. */
+ if (TREE_CODE (declarator) != TEMPLATE_ID_EXPR)
+ {
+ tree fns;
+
+ gcc_assert (identifier_p (declarator));
+ if (ctype)
+ fns = dname;
+ else
+ {
+ /* If there is no class context, the explicit instantiation
+ must be at namespace scope. */
+ gcc_assert (DECL_NAMESPACE_SCOPE_P (decl));
+
+ /* Find the namespace binding, using the declaration
+ context. */
+ fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname,
+ false, true);
+ if (fns == error_mark_node || !is_overloaded_fn (fns))
+ {
+ error ("%qD is not a template function", dname);
+ fns = error_mark_node;
+ }
+ else
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (!is_associated_namespace (CP_DECL_CONTEXT (decl),
+ CP_DECL_CONTEXT (fn)))
+ error ("%qD is not declared in %qD",
+ decl, current_namespace);
+ }
+ }
+
+ declarator = lookup_template_function (fns, NULL_TREE);
+ }
+
+ if (declarator == error_mark_node)
+ return error_mark_node;
+
+ if (ctype != NULL_TREE && TYPE_BEING_DEFINED (ctype))
+ {
+ if (!explicit_instantiation)
+ /* A specialization in class scope. This is invalid,
+ but the error will already have been flagged by
+ check_specialization_scope. */
+ return error_mark_node;
+ else
+ {
+ /* It's not valid to write an explicit instantiation in
+ class scope, e.g.:
+
+ class C { template void f(); }
+
+ This case is caught by the parser. However, on
+ something like:
+
+ template class C { void f(); };
+
+ (which is invalid) we can get here. The error will be
+ issued later. */
+ ;
+ }
+
+ return decl;
+ }
+ else if (ctype != NULL_TREE
+ && (identifier_p (TREE_OPERAND (declarator, 0))))
+ {
+ /* Find the list of functions in ctype that have the same
+ name as the declared function. */
+ tree name = TREE_OPERAND (declarator, 0);
+ tree fns = NULL_TREE;
+ int idx;
+
+ if (constructor_name_p (name, ctype))
+ {
+ int is_constructor = DECL_CONSTRUCTOR_P (decl);
+
+ if (is_constructor ? !TYPE_HAS_USER_CONSTRUCTOR (ctype)
+ : !CLASSTYPE_DESTRUCTORS (ctype))
+ {
+ /* From [temp.expl.spec]:
+
+ If such an explicit specialization for the member
+ of a class template names an implicitly-declared
+ special member function (clause _special_), the
+ program is ill-formed.
+
+ Similar language is found in [temp.explicit]. */
+ error ("specialization of implicitly-declared special member function");
+ return error_mark_node;
+ }
+
+ name = is_constructor ? ctor_identifier : dtor_identifier;
+ }
+
+ if (!DECL_CONV_FN_P (decl))
+ {
+ idx = lookup_fnfields_1 (ctype, name);
+ if (idx >= 0)
+ fns = (*CLASSTYPE_METHOD_VEC (ctype))[idx];
+ }
+ else
+ {
+ vec<tree, va_gc> *methods;
+ tree ovl;
+
+ /* For a type-conversion operator, we cannot do a
+ name-based lookup. We might be looking for `operator
+ int' which will be a specialization of `operator T'.
+ So, we find *all* the conversion operators, and then
+ select from them. */
+ fns = NULL_TREE;
+
+ methods = CLASSTYPE_METHOD_VEC (ctype);
+ if (methods)
+ for (idx = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ methods->iterate (idx, &ovl);
+ ++idx)
+ {
+ if (!DECL_CONV_FN_P (OVL_CURRENT (ovl)))
+ /* There are no more conversion functions. */
+ break;
+
+ /* Glue all these conversion functions together
+ with those we already have. */
+ for (; ovl; ovl = OVL_NEXT (ovl))
+ fns = ovl_cons (OVL_CURRENT (ovl), fns);
+ }
+ }
+
+ if (fns == NULL_TREE)
+ {
+ error ("no member function %qD declared in %qT", name, ctype);
+ return error_mark_node;
+ }
+ else
+ TREE_OPERAND (declarator, 0) = fns;
+ }
+
+ /* Figure out what exactly is being specialized at this point.
+ Note that for an explicit instantiation, even one for a
+ member function, we cannot tell apriori whether the
+ instantiation is for a member template, or just a member
+ function of a template class. Even if a member template is
+ being instantiated, the member template arguments may be
+ elided if they can be deduced from the rest of the
+ declaration. */
+ tmpl = determine_specialization (declarator, decl,
+ &targs,
+ member_specialization,
+ template_count,
+ tsk);
+
+ if (!tmpl || tmpl == error_mark_node)
+ /* We couldn't figure out what this declaration was
+ specializing. */
+ return error_mark_node;
+ else
+ {
+ tree gen_tmpl = most_general_template (tmpl);
+
+ if (explicit_instantiation)
+ {
+ /* We don't set DECL_EXPLICIT_INSTANTIATION here; that
+ is done by do_decl_instantiation later. */
+
+ int arg_depth = TMPL_ARGS_DEPTH (targs);
+ int parm_depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl));
+
+ if (arg_depth > parm_depth)
+ {
+ /* If TMPL is not the most general template (for
+ example, if TMPL is a friend template that is
+ injected into namespace scope), then there will
+ be too many levels of TARGS. Remove some of them
+ here. */
+ int i;
+ tree new_targs;
+
+ new_targs = make_tree_vec (parm_depth);
+ for (i = arg_depth - parm_depth; i < arg_depth; ++i)
+ TREE_VEC_ELT (new_targs, i - (arg_depth - parm_depth))
+ = TREE_VEC_ELT (targs, i);
+ targs = new_targs;
+ }
+
+ return instantiate_template (tmpl, targs, tf_error);
+ }
+
+ /* If we thought that the DECL was a member function, but it
+ turns out to be specializing a static member function,
+ make DECL a static member function as well. */
+ if (DECL_STATIC_FUNCTION_P (tmpl)
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ revert_static_member_fn (decl);
+
+ /* If this is a specialization of a member template of a
+ template class, we want to return the TEMPLATE_DECL, not
+ the specialization of it. */
+ if (tsk == tsk_template)
+ {
+ tree result = DECL_TEMPLATE_RESULT (tmpl);
+ SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
+ DECL_INITIAL (result) = NULL_TREE;
+ if (have_def)
+ {
+ tree parm;
+ DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
+ DECL_SOURCE_LOCATION (result)
+ = DECL_SOURCE_LOCATION (decl);
+ /* We want to use the argument list specified in the
+ definition, not in the original declaration. */
+ DECL_ARGUMENTS (result) = DECL_ARGUMENTS (decl);
+ for (parm = DECL_ARGUMENTS (result); parm;
+ parm = DECL_CHAIN (parm))
+ DECL_CONTEXT (parm) = result;
+ }
+ return register_specialization (tmpl, gen_tmpl, targs,
+ is_friend, 0);
+ }
+
+ /* Set up the DECL_TEMPLATE_INFO for DECL. */
+ DECL_TEMPLATE_INFO (decl) = build_template_info (tmpl, targs);
+
+ /* Inherit default function arguments from the template
+ DECL is specializing. */
+ copy_default_args_to_explicit_spec (decl);
+
+ /* This specialization has the same protection as the
+ template it specializes. */
+ TREE_PRIVATE (decl) = TREE_PRIVATE (gen_tmpl);
+ TREE_PROTECTED (decl) = TREE_PROTECTED (gen_tmpl);
+
+ /* 7.1.1-1 [dcl.stc]
+
+ A storage-class-specifier shall not be specified in an
+ explicit specialization...
+
+ The parser rejects these, so unless action is taken here,
+ explicit function specializations will always appear with
+ global linkage.
+
+ The action recommended by the C++ CWG in response to C++
+ defect report 605 is to make the storage class and linkage
+ of the explicit specialization match the templated function:
+
+ http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#605
+ */
+ if (tsk == tsk_expl_spec && DECL_FUNCTION_TEMPLATE_P (gen_tmpl))
+ {
+ tree tmpl_func = DECL_TEMPLATE_RESULT (gen_tmpl);
+ gcc_assert (TREE_CODE (tmpl_func) == FUNCTION_DECL);
+
+ /* This specialization has the same linkage and visibility as
+ the function template it specializes. */
+ TREE_PUBLIC (decl) = TREE_PUBLIC (tmpl_func);
+ if (! TREE_PUBLIC (decl))
+ {
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ DECL_NOT_REALLY_EXTERN (decl) = 1;
+ }
+ DECL_THIS_STATIC (decl) = DECL_THIS_STATIC (tmpl_func);
+ if (DECL_VISIBILITY_SPECIFIED (tmpl_func))
+ {
+ DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ DECL_VISIBILITY (decl) = DECL_VISIBILITY (tmpl_func);
+ }
+ }
+
+ /* If DECL is a friend declaration, declared using an
+ unqualified name, the namespace associated with DECL may
+ have been set incorrectly. For example, in:
+
+ template <typename T> void f(T);
+ namespace N {
+ struct S { friend void f<int>(int); }
+ }
+
+ we will have set the DECL_CONTEXT for the friend
+ declaration to N, rather than to the global namespace. */
+ if (DECL_NAMESPACE_SCOPE_P (decl))
+ DECL_CONTEXT (decl) = DECL_CONTEXT (tmpl);
+
+ if (is_friend && !have_def)
+ /* This is not really a declaration of a specialization.
+ It's just the name of an instantiation. But, it's not
+ a request for an instantiation, either. */
+ SET_DECL_IMPLICIT_INSTANTIATION (decl);
+
+ /* Register this specialization so that we can find it
+ again. */
+ decl = register_specialization (decl, gen_tmpl, targs, is_friend, 0);
+
+ /* A 'structor should already have clones. */
+ gcc_assert (decl == error_mark_node
+ || !(DECL_CONSTRUCTOR_P (decl)
+ || DECL_DESTRUCTOR_P (decl))
+ || DECL_CLONED_FUNCTION_P (DECL_CHAIN (decl)));
+ }
+ }
+
+ return decl;
+}
+
+/* Returns 1 iff PARMS1 and PARMS2 are identical sets of template
+ parameters. These are represented in the same format used for
+ DECL_TEMPLATE_PARMS. */
+
+int
+comp_template_parms (const_tree parms1, const_tree parms2)
+{
+ const_tree p1;
+ const_tree p2;
+
+ if (parms1 == parms2)
+ return 1;
+
+ for (p1 = parms1, p2 = parms2;
+ p1 != NULL_TREE && p2 != NULL_TREE;
+ p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2))
+ {
+ tree t1 = TREE_VALUE (p1);
+ tree t2 = TREE_VALUE (p2);
+ int i;
+
+ gcc_assert (TREE_CODE (t1) == TREE_VEC);
+ gcc_assert (TREE_CODE (t2) == TREE_VEC);
+
+ if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2))
+ return 0;
+
+ for (i = 0; i < TREE_VEC_LENGTH (t2); ++i)
+ {
+ tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
+ tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
+
+ /* If either of the template parameters are invalid, assume
+ they match for the sake of error recovery. */
+ if (parm1 == error_mark_node || parm2 == error_mark_node)
+ return 1;
+
+ if (TREE_CODE (parm1) != TREE_CODE (parm2))
+ return 0;
+
+ if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM
+ && (TEMPLATE_TYPE_PARAMETER_PACK (parm1)
+ == TEMPLATE_TYPE_PARAMETER_PACK (parm2)))
+ continue;
+ else if (!same_type_p (TREE_TYPE (parm1), TREE_TYPE (parm2)))
+ return 0;
+ }
+ }
+
+ if ((p1 != NULL_TREE) != (p2 != NULL_TREE))
+ /* One set of parameters has more parameters lists than the
+ other. */
+ return 0;
+
+ return 1;
+}
+
+/* Determine whether PARM is a parameter pack. */
+
+bool
+template_parameter_pack_p (const_tree parm)
+{
+ /* Determine if we have a non-type template parameter pack. */
+ if (TREE_CODE (parm) == PARM_DECL)
+ return (DECL_TEMPLATE_PARM_P (parm)
+ && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)));
+ if (TREE_CODE (parm) == TEMPLATE_PARM_INDEX)
+ return TEMPLATE_PARM_PARAMETER_PACK (parm);
+
+ /* If this is a list of template parameters, we could get a
+ TYPE_DECL or a TEMPLATE_DECL. */
+ if (TREE_CODE (parm) == TYPE_DECL || TREE_CODE (parm) == TEMPLATE_DECL)
+ parm = TREE_TYPE (parm);
+
+ /* Otherwise it must be a type template parameter. */
+ return ((TREE_CODE (parm) == TEMPLATE_TYPE_PARM
+ || TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM)
+ && TEMPLATE_TYPE_PARAMETER_PACK (parm));
+}
+
+/* Determine if T is a function parameter pack. */
+
+bool
+function_parameter_pack_p (const_tree t)
+{
+ if (t && TREE_CODE (t) == PARM_DECL)
+ return DECL_PACK_P (t);
+ return false;
+}
+
+/* Return the function template declaration of PRIMARY_FUNC_TMPL_INST.
+ PRIMARY_FUNC_TMPL_INST is a primary function template instantiation. */
+
+tree
+get_function_template_decl (const_tree primary_func_tmpl_inst)
+{
+ if (! primary_func_tmpl_inst
+ || TREE_CODE (primary_func_tmpl_inst) != FUNCTION_DECL
+ || ! primary_template_instantiation_p (primary_func_tmpl_inst))
+ return NULL;
+
+ return DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (primary_func_tmpl_inst));
+}
+
+/* Return true iff the function parameter PARAM_DECL was expanded
+ from the function parameter pack PACK. */
+
+bool
+function_parameter_expanded_from_pack_p (tree param_decl, tree pack)
+{
+ if (DECL_ARTIFICIAL (param_decl)
+ || !function_parameter_pack_p (pack))
+ return false;
+
+ /* The parameter pack and its pack arguments have the same
+ DECL_PARM_INDEX. */
+ return DECL_PARM_INDEX (pack) == DECL_PARM_INDEX (param_decl);
+}
+
+/* Determine whether ARGS describes a variadic template args list,
+ i.e., one that is terminated by a template argument pack. */
+
+static bool
+template_args_variadic_p (tree args)
+{
+ int nargs;
+ tree last_parm;
+
+ if (args == NULL_TREE)
+ return false;
+
+ args = INNERMOST_TEMPLATE_ARGS (args);
+ nargs = TREE_VEC_LENGTH (args);
+
+ if (nargs == 0)
+ return false;
+
+ last_parm = TREE_VEC_ELT (args, nargs - 1);
+
+ return ARGUMENT_PACK_P (last_parm);
+}
+
+/* Generate a new name for the parameter pack name NAME (an
+ IDENTIFIER_NODE) that incorporates its */
+
+static tree
+make_ith_pack_parameter_name (tree name, int i)
+{
+ /* Munge the name to include the parameter index. */
+#define NUMBUF_LEN 128
+ char numbuf[NUMBUF_LEN];
+ char* newname;
+ int newname_len;
+
+ if (name == NULL_TREE)
+ return name;
+ snprintf (numbuf, NUMBUF_LEN, "%i", i);
+ newname_len = IDENTIFIER_LENGTH (name)
+ + strlen (numbuf) + 2;
+ newname = (char*)alloca (newname_len);
+ snprintf (newname, newname_len,
+ "%s#%i", IDENTIFIER_POINTER (name), i);
+ return get_identifier (newname);
+}
+
+/* Return true if T is a primary function, class or alias template
+ instantiation. */
+
+bool
+primary_template_instantiation_p (const_tree t)
+{
+ if (!t)
+ return false;
+
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ return DECL_LANG_SPECIFIC (t)
+ && DECL_TEMPLATE_INSTANTIATION (t)
+ && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t));
+ else if (CLASS_TYPE_P (t) && !TYPE_DECL_ALIAS_P (TYPE_NAME (t)))
+ return CLASSTYPE_TEMPLATE_INSTANTIATION (t)
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t));
+ else if (alias_template_specialization_p (t))
+ return true;
+ return false;
+}
+
+/* Return true if PARM is a template template parameter. */
+
+bool
+template_template_parameter_p (const_tree parm)
+{
+ return DECL_TEMPLATE_TEMPLATE_PARM_P (parm);
+}
+
+/* Return true iff PARM is a DECL representing a type template
+ parameter. */
+
+bool
+template_type_parameter_p (const_tree parm)
+{
+ return (parm
+ && (TREE_CODE (parm) == TYPE_DECL
+ || TREE_CODE (parm) == TEMPLATE_DECL)
+ && DECL_TEMPLATE_PARM_P (parm));
+}
+
+/* Return the template parameters of T if T is a
+ primary template instantiation, NULL otherwise. */
+
+tree
+get_primary_template_innermost_parameters (const_tree t)
+{
+ tree parms = NULL, template_info = NULL;
+
+ if ((template_info = get_template_info (t))
+ && primary_template_instantiation_p (t))
+ parms = INNERMOST_TEMPLATE_PARMS
+ (DECL_TEMPLATE_PARMS (TI_TEMPLATE (template_info)));
+
+ return parms;
+}
+
+/* Return the template parameters of the LEVELth level from the full list
+ of template parameters PARMS. */
+
+tree
+get_template_parms_at_level (tree parms, int level)
+{
+ tree p;
+ if (!parms
+ || TREE_CODE (parms) != TREE_LIST
+ || level > TMPL_PARMS_DEPTH (parms))
+ return NULL_TREE;
+
+ for (p = parms; p; p = TREE_CHAIN (p))
+ if (TMPL_PARMS_DEPTH (p) == level)
+ return p;
+
+ return NULL_TREE;
+}
+
+/* Returns the template arguments of T if T is a template instantiation,
+ NULL otherwise. */
+
+tree
+get_template_innermost_arguments (const_tree t)
+{
+ tree args = NULL, template_info = NULL;
+
+ if ((template_info = get_template_info (t))
+ && TI_ARGS (template_info))
+ args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (template_info));
+
+ return args;
+}
+
+/* Return the argument pack elements of T if T is a template argument pack,
+ NULL otherwise. */
+
+tree
+get_template_argument_pack_elems (const_tree t)
+{
+ if (TREE_CODE (t) != TYPE_ARGUMENT_PACK
+ && TREE_CODE (t) != NONTYPE_ARGUMENT_PACK)
+ return NULL;
+
+ return ARGUMENT_PACK_ARGS (t);
+}
+
+/* Structure used to track the progress of find_parameter_packs_r. */
+struct find_parameter_pack_data
+{
+ /* TREE_LIST that will contain all of the parameter packs found by
+ the traversal. */
+ tree* parameter_packs;
+
+ /* Set of AST nodes that have been visited by the traversal. */
+ struct pointer_set_t *visited;
+};
+
+/* Identifies all of the argument packs that occur in a template
+ argument and appends them to the TREE_LIST inside DATA, which is a
+ find_parameter_pack_data structure. This is a subroutine of
+ make_pack_expansion and uses_parameter_packs. */
+static tree
+find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
+{
+ tree t = *tp;
+ struct find_parameter_pack_data* ppd =
+ (struct find_parameter_pack_data*)data;
+ bool parameter_pack_p = false;
+
+ /* Handle type aliases/typedefs. */
+ if (TYPE_ALIAS_P (t))
+ {
+ if (TYPE_TEMPLATE_INFO (t))
+ cp_walk_tree (&TYPE_TI_ARGS (t),
+ &find_parameter_packs_r,
+ ppd, ppd->visited);
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
+ /* Identify whether this is a parameter pack or not. */
+ switch (TREE_CODE (t))
+ {
+ case TEMPLATE_PARM_INDEX:
+ if (TEMPLATE_PARM_PARAMETER_PACK (t))
+ parameter_pack_p = true;
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ t = TYPE_MAIN_VARIANT (t);
+ case TEMPLATE_TEMPLATE_PARM:
+ if (TEMPLATE_TYPE_PARAMETER_PACK (t))
+ parameter_pack_p = true;
+ break;
+
+ case FIELD_DECL:
+ case PARM_DECL:
+ if (DECL_PACK_P (t))
+ {
+ /* We don't want to walk into the type of a PARM_DECL,
+ because we don't want to see the type parameter pack. */
+ *walk_subtrees = 0;
+ parameter_pack_p = true;
+ }
+ break;
+
+ /* Look through a lambda capture proxy to the field pack. */
+ case VAR_DECL:
+ if (DECL_HAS_VALUE_EXPR_P (t))
+ {
+ tree v = DECL_VALUE_EXPR (t);
+ cp_walk_tree (&v,
+ &find_parameter_packs_r,
+ ppd, ppd->visited);
+ *walk_subtrees = 0;
+ }
+ break;
+
+ case BASES:
+ parameter_pack_p = true;
+ break;
+ default:
+ /* Not a parameter pack. */
+ break;
+ }
+
+ if (parameter_pack_p)
+ {
+ /* Add this parameter pack to the list. */
+ *ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs);
+ }
+
+ if (TYPE_P (t))
+ cp_walk_tree (&TYPE_CONTEXT (t),
+ &find_parameter_packs_r, ppd, ppd->visited);
+
+ /* This switch statement will return immediately if we don't find a
+ parameter pack. */
+ switch (TREE_CODE (t))
+ {
+ case TEMPLATE_PARM_INDEX:
+ return NULL_TREE;
+
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ /* Check the template itself. */
+ cp_walk_tree (&TREE_TYPE (TYPE_TI_TEMPLATE (t)),
+ &find_parameter_packs_r, ppd, ppd->visited);
+ /* Check the template arguments. */
+ cp_walk_tree (&TYPE_TI_ARGS (t), &find_parameter_packs_r, ppd,
+ ppd->visited);
+ *walk_subtrees = 0;
+ return NULL_TREE;
+
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ return NULL_TREE;
+
+ case PARM_DECL:
+ return NULL_TREE;
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ return NULL_TREE;
+ /* Fall through. */
+
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ if (TYPE_TEMPLATE_INFO (t))
+ cp_walk_tree (&TYPE_TI_ARGS (t),
+ &find_parameter_packs_r, ppd, ppd->visited);
+
+ *walk_subtrees = 0;
+ return NULL_TREE;
+
+ case CONSTRUCTOR:
+ case TEMPLATE_DECL:
+ cp_walk_tree (&TREE_TYPE (t),
+ &find_parameter_packs_r, ppd, ppd->visited);
+ return NULL_TREE;
+
+ case TYPENAME_TYPE:
+ cp_walk_tree (&TYPENAME_TYPE_FULLNAME (t), &find_parameter_packs_r,
+ ppd, ppd->visited);
+ *walk_subtrees = 0;
+ return NULL_TREE;
+
+ case TYPE_PACK_EXPANSION:
+ case EXPR_PACK_EXPANSION:
+ *walk_subtrees = 0;
+ return NULL_TREE;
+
+ case INTEGER_TYPE:
+ cp_walk_tree (&TYPE_MAX_VALUE (t), &find_parameter_packs_r,
+ ppd, ppd->visited);
+ *walk_subtrees = 0;
+ return NULL_TREE;
+
+ case IDENTIFIER_NODE:
+ cp_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd,
+ ppd->visited);
+ *walk_subtrees = 0;
+ return NULL_TREE;
+
+ default:
+ return NULL_TREE;
+ }
+
+ return NULL_TREE;
+}
+
+/* Determines if the expression or type T uses any parameter packs. */
+bool
+uses_parameter_packs (tree t)
+{
+ tree parameter_packs = NULL_TREE;
+ struct find_parameter_pack_data ppd;
+ ppd.parameter_packs = &parameter_packs;
+ ppd.visited = pointer_set_create ();
+ cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
+ pointer_set_destroy (ppd.visited);
+ return parameter_packs != NULL_TREE;
+}
+
+/* Turn ARG, which may be an expression, type, or a TREE_LIST
+ representation a base-class initializer into a parameter pack
+ expansion. If all goes well, the resulting node will be an
+ EXPR_PACK_EXPANSION, TYPE_PACK_EXPANSION, or TREE_LIST,
+ respectively. */
+tree
+make_pack_expansion (tree arg)
+{
+ tree result;
+ tree parameter_packs = NULL_TREE;
+ bool for_types = false;
+ struct find_parameter_pack_data ppd;
+
+ if (!arg || arg == error_mark_node)
+ return arg;
+
+ if (TREE_CODE (arg) == TREE_LIST)
+ {
+ /* The only time we will see a TREE_LIST here is for a base
+ class initializer. In this case, the TREE_PURPOSE will be a
+ _TYPE node (representing the base class expansion we're
+ initializing) and the TREE_VALUE will be a TREE_LIST
+ containing the initialization arguments.
+
+ The resulting expansion looks somewhat different from most
+ expansions. Rather than returning just one _EXPANSION, we
+ return a TREE_LIST whose TREE_PURPOSE is a
+ TYPE_PACK_EXPANSION containing the bases that will be
+ initialized. The TREE_VALUE will be identical to the
+ original TREE_VALUE, which is a list of arguments that will
+ be passed to each base. We do not introduce any new pack
+ expansion nodes into the TREE_VALUE (although it is possible
+ that some already exist), because the TREE_PURPOSE and
+ TREE_VALUE all need to be expanded together with the same
+ _EXPANSION node. Note that the TYPE_PACK_EXPANSION in the
+ resulting TREE_PURPOSE will mention the parameter packs in
+ both the bases and the arguments to the bases. */
+ tree purpose;
+ tree value;
+ tree parameter_packs = NULL_TREE;
+
+ /* Determine which parameter packs will be used by the base
+ class expansion. */
+ ppd.visited = pointer_set_create ();
+ ppd.parameter_packs = &parameter_packs;
+ cp_walk_tree (&TREE_PURPOSE (arg), &find_parameter_packs_r,
+ &ppd, ppd.visited);
+
+ if (parameter_packs == NULL_TREE)
+ {
+ error ("base initializer expansion %<%T%> contains no parameter packs", arg);
+ pointer_set_destroy (ppd.visited);
+ return error_mark_node;
+ }
+
+ if (TREE_VALUE (arg) != void_type_node)
+ {
+ /* Collect the sets of parameter packs used in each of the
+ initialization arguments. */
+ for (value = TREE_VALUE (arg); value; value = TREE_CHAIN (value))
+ {
+ /* Determine which parameter packs will be expanded in this
+ argument. */
+ cp_walk_tree (&TREE_VALUE (value), &find_parameter_packs_r,
+ &ppd, ppd.visited);
+ }
+ }
+
+ pointer_set_destroy (ppd.visited);
+
+ /* Create the pack expansion type for the base type. */
+ purpose = cxx_make_type (TYPE_PACK_EXPANSION);
+ SET_PACK_EXPANSION_PATTERN (purpose, TREE_PURPOSE (arg));
+ PACK_EXPANSION_PARAMETER_PACKS (purpose) = parameter_packs;
+
+ /* Just use structural equality for these TYPE_PACK_EXPANSIONS;
+ they will rarely be compared to anything. */
+ SET_TYPE_STRUCTURAL_EQUALITY (purpose);
+
+ return tree_cons (purpose, TREE_VALUE (arg), NULL_TREE);
+ }
+
+ if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
+ for_types = true;
+
+ /* Build the PACK_EXPANSION_* node. */
+ result = for_types
+ ? cxx_make_type (TYPE_PACK_EXPANSION)
+ : make_node (EXPR_PACK_EXPANSION);
+ SET_PACK_EXPANSION_PATTERN (result, arg);
+ if (TREE_CODE (result) == EXPR_PACK_EXPANSION)
+ {
+ /* Propagate type and const-expression information. */
+ TREE_TYPE (result) = TREE_TYPE (arg);
+ TREE_CONSTANT (result) = TREE_CONSTANT (arg);
+ }
+ else
+ /* Just use structural equality for these TYPE_PACK_EXPANSIONS;
+ they will rarely be compared to anything. */
+ SET_TYPE_STRUCTURAL_EQUALITY (result);
+
+ /* Determine which parameter packs will be expanded. */
+ ppd.parameter_packs = &parameter_packs;
+ ppd.visited = pointer_set_create ();
+ cp_walk_tree (&arg, &find_parameter_packs_r, &ppd, ppd.visited);
+ pointer_set_destroy (ppd.visited);
+
+ /* Make sure we found some parameter packs. */
+ if (parameter_packs == NULL_TREE)
+ {
+ if (TYPE_P (arg))
+ error ("expansion pattern %<%T%> contains no argument packs", arg);
+ else
+ error ("expansion pattern %<%E%> contains no argument packs", arg);
+ return error_mark_node;
+ }
+ PACK_EXPANSION_PARAMETER_PACKS (result) = parameter_packs;
+
+ PACK_EXPANSION_LOCAL_P (result) = at_function_scope_p ();
+
+ return result;
+}
+
+/* Checks T for any "bare" parameter packs, which have not yet been
+ expanded, and issues an error if any are found. This operation can
+ only be done on full expressions or types (e.g., an expression
+ statement, "if" condition, etc.), because we could have expressions like:
+
+ foo(f(g(h(args)))...)
+
+ where "args" is a parameter pack. check_for_bare_parameter_packs
+ should not be called for the subexpressions args, h(args),
+ g(h(args)), or f(g(h(args))), because we would produce erroneous
+ error messages.
+
+ Returns TRUE and emits an error if there were bare parameter packs,
+ returns FALSE otherwise. */
+bool
+check_for_bare_parameter_packs (tree t)
+{
+ tree parameter_packs = NULL_TREE;
+ struct find_parameter_pack_data ppd;
+
+ if (!processing_template_decl || !t || t == error_mark_node)
+ return false;
+
+ if (TREE_CODE (t) == TYPE_DECL)
+ t = TREE_TYPE (t);
+
+ ppd.parameter_packs = &parameter_packs;
+ ppd.visited = pointer_set_create ();
+ cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
+ pointer_set_destroy (ppd.visited);
+
+ if (parameter_packs)
+ {
+ error ("parameter packs not expanded with %<...%>:");
+ while (parameter_packs)
+ {
+ tree pack = TREE_VALUE (parameter_packs);
+ tree name = NULL_TREE;
+
+ if (TREE_CODE (pack) == TEMPLATE_TYPE_PARM
+ || TREE_CODE (pack) == TEMPLATE_TEMPLATE_PARM)
+ name = TYPE_NAME (pack);
+ else if (TREE_CODE (pack) == TEMPLATE_PARM_INDEX)
+ name = DECL_NAME (TEMPLATE_PARM_DECL (pack));
+ else
+ name = DECL_NAME (pack);
+
+ if (name)
+ inform (input_location, " %qD", name);
+ else
+ inform (input_location, " <anonymous>");
+
+ parameter_packs = TREE_CHAIN (parameter_packs);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+/* Expand any parameter packs that occur in the template arguments in
+ ARGS. */
+tree
+expand_template_argument_pack (tree args)
+{
+ tree result_args = NULL_TREE;
+ int in_arg, out_arg = 0, nargs = args ? TREE_VEC_LENGTH (args) : 0;
+ int num_result_args = -1;
+ int non_default_args_count = -1;
+
+ /* First, determine if we need to expand anything, and the number of
+ slots we'll need. */
+ for (in_arg = 0; in_arg < nargs; ++in_arg)
+ {
+ tree arg = TREE_VEC_ELT (args, in_arg);
+ if (arg == NULL_TREE)
+ return args;
+ if (ARGUMENT_PACK_P (arg))
+ {
+ int num_packed = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg));
+ if (num_result_args < 0)
+ num_result_args = in_arg + num_packed;
+ else
+ num_result_args += num_packed;
+ }
+ else
+ {
+ if (num_result_args >= 0)
+ num_result_args++;
+ }
+ }
+
+ /* If no expansion is necessary, we're done. */
+ if (num_result_args < 0)
+ return args;
+
+ /* Expand arguments. */
+ result_args = make_tree_vec (num_result_args);
+ if (NON_DEFAULT_TEMPLATE_ARGS_COUNT (args))
+ non_default_args_count =
+ GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args);
+ for (in_arg = 0; in_arg < nargs; ++in_arg)
+ {
+ tree arg = TREE_VEC_ELT (args, in_arg);
+ if (ARGUMENT_PACK_P (arg))
+ {
+ tree packed = ARGUMENT_PACK_ARGS (arg);
+ int i, num_packed = TREE_VEC_LENGTH (packed);
+ for (i = 0; i < num_packed; ++i, ++out_arg)
+ TREE_VEC_ELT (result_args, out_arg) = TREE_VEC_ELT(packed, i);
+ if (non_default_args_count > 0)
+ non_default_args_count += num_packed - 1;
+ }
+ else
+ {
+ TREE_VEC_ELT (result_args, out_arg) = arg;
+ ++out_arg;
+ }
+ }
+ if (non_default_args_count >= 0)
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (result_args, non_default_args_count);
+ return result_args;
+}
+
+/* Checks if DECL shadows a template parameter.
+
+ [temp.local]: A template-parameter shall not be redeclared within its
+ scope (including nested scopes).
+
+ Emits an error and returns TRUE if the DECL shadows a parameter,
+ returns FALSE otherwise. */
+
+bool
+check_template_shadow (tree decl)
+{
+ tree olddecl;
+
+ /* If we're not in a template, we can't possibly shadow a template
+ parameter. */
+ if (!current_template_parms)
+ return true;
+
+ /* Figure out what we're shadowing. */
+ if (TREE_CODE (decl) == OVERLOAD)
+ decl = OVL_CURRENT (decl);
+ olddecl = innermost_non_namespace_value (DECL_NAME (decl));
+
+ /* If there's no previous binding for this name, we're not shadowing
+ anything, let alone a template parameter. */
+ if (!olddecl)
+ return true;
+
+ /* If we're not shadowing a template parameter, we're done. Note
+ that OLDDECL might be an OVERLOAD (or perhaps even an
+ ERROR_MARK), so we can't just blithely assume it to be a _DECL
+ node. */
+ if (!DECL_P (olddecl) || !DECL_TEMPLATE_PARM_P (olddecl))
+ return true;
+
+ /* We check for decl != olddecl to avoid bogus errors for using a
+ name inside a class. We check TPFI to avoid duplicate errors for
+ inline member templates. */
+ if (decl == olddecl
+ || (DECL_TEMPLATE_PARM_P (decl)
+ && TEMPLATE_PARMS_FOR_INLINE (current_template_parms)))
+ return true;
+
+ /* Don't complain about the injected class name, as we've already
+ complained about the class itself. */
+ if (DECL_SELF_REFERENCE_P (decl))
+ return false;
+
+ error ("declaration of %q+#D", decl);
+ error (" shadows template parm %q+#D", olddecl);
+ return false;
+}
+
+/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
+ ORIG_LEVEL, DECL, and TYPE. */
+
+static tree
+build_template_parm_index (int index,
+ int level,
+ int orig_level,
+ tree decl,
+ tree type)
+{
+ tree t = make_node (TEMPLATE_PARM_INDEX);
+ TEMPLATE_PARM_IDX (t) = index;
+ TEMPLATE_PARM_LEVEL (t) = level;
+ TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level;
+ TEMPLATE_PARM_DECL (t) = decl;
+ TREE_TYPE (t) = type;
+ TREE_CONSTANT (t) = TREE_CONSTANT (decl);
+ TREE_READONLY (t) = TREE_READONLY (decl);
+
+ return t;
+}
+
+/* Find the canonical type parameter for the given template type
+ parameter. Returns the canonical type parameter, which may be TYPE
+ if no such parameter existed. */
+
+static tree
+canonical_type_parameter (tree type)
+{
+ tree list;
+ int idx = TEMPLATE_TYPE_IDX (type);
+ if (!canonical_template_parms)
+ vec_alloc (canonical_template_parms, idx+1);
+
+ while (canonical_template_parms->length () <= (unsigned)idx)
+ vec_safe_push (canonical_template_parms, NULL_TREE);
+
+ list = (*canonical_template_parms)[idx];
+ while (list && !comptypes (type, TREE_VALUE (list), COMPARE_STRUCTURAL))
+ list = TREE_CHAIN (list);
+
+ if (list)
+ return TREE_VALUE (list);
+ else
+ {
+ (*canonical_template_parms)[idx]
+ = tree_cons (NULL_TREE, type,
+ (*canonical_template_parms)[idx]);
+ return type;
+ }
+}
+
+/* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose
+ TEMPLATE_PARM_LEVEL has been decreased by LEVELS. If such a
+ TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a
+ new one is created. */
+
+static tree
+reduce_template_parm_level (tree index, tree type, int levels, tree args,
+ tsubst_flags_t complain)
+{
+ if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
+ || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))
+ != TEMPLATE_PARM_LEVEL (index) - levels)
+ || !same_type_p (type, TREE_TYPE (TEMPLATE_PARM_DESCENDANTS (index))))
+ {
+ tree orig_decl = TEMPLATE_PARM_DECL (index);
+ tree decl, t;
+
+ decl = build_decl (DECL_SOURCE_LOCATION (orig_decl),
+ TREE_CODE (orig_decl), DECL_NAME (orig_decl), type);
+ TREE_CONSTANT (decl) = TREE_CONSTANT (orig_decl);
+ TREE_READONLY (decl) = TREE_READONLY (orig_decl);
+ DECL_ARTIFICIAL (decl) = 1;
+ SET_DECL_TEMPLATE_PARM_P (decl);
+
+ t = build_template_parm_index (TEMPLATE_PARM_IDX (index),
+ TEMPLATE_PARM_LEVEL (index) - levels,
+ TEMPLATE_PARM_ORIG_LEVEL (index),
+ decl, type);
+ TEMPLATE_PARM_DESCENDANTS (index) = t;
+ TEMPLATE_PARM_PARAMETER_PACK (t)
+ = TEMPLATE_PARM_PARAMETER_PACK (index);
+
+ /* Template template parameters need this. */
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ DECL_TEMPLATE_PARMS (decl) = tsubst_template_parms
+ (DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)),
+ args, complain);
+ }
+
+ return TEMPLATE_PARM_DESCENDANTS (index);
+}
+
+/* Process information from new template parameter PARM and append it
+ to the LIST being built. This new parameter is a non-type
+ parameter iff IS_NON_TYPE is true. This new parameter is a
+ parameter pack iff IS_PARAMETER_PACK is true. The location of PARM
+ is in PARM_LOC. NUM_TEMPLATE_PARMS is the size of the template
+ parameter list PARM belongs to. This is used used to create a
+ proper canonical type for the type of PARM that is to be created,
+ iff PARM is a type. If the size is not known, this parameter shall
+ be set to 0. */
+
+tree
+process_template_parm (tree list, location_t parm_loc, tree parm,
+ bool is_non_type, bool is_parameter_pack)
+{
+ tree decl = 0;
+ tree defval;
+ tree err_parm_list;
+ int idx = 0;
+
+ gcc_assert (TREE_CODE (parm) == TREE_LIST);
+ defval = TREE_PURPOSE (parm);
+
+ if (list)
+ {
+ tree p = tree_last (list);
+
+ if (p && TREE_VALUE (p) != error_mark_node)
+ {
+ p = TREE_VALUE (p);
+ if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
+ idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p));
+ else
+ idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p));
+ }
+
+ ++idx;
+ }
+ else
+ idx = 0;
+
+ if (is_non_type)
+ {
+ parm = TREE_VALUE (parm);
+
+ SET_DECL_TEMPLATE_PARM_P (parm);
+
+ if (TREE_TYPE (parm) == error_mark_node)
+ {
+ err_parm_list = build_tree_list (defval, parm);
+ TREE_VALUE (err_parm_list) = error_mark_node;
+ return chainon (list, err_parm_list);
+ }
+ else
+ {
+ /* [temp.param]
+
+ The top-level cv-qualifiers on the template-parameter are
+ ignored when determining its type. */
+ TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
+ if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
+ {
+ err_parm_list = build_tree_list (defval, parm);
+ TREE_VALUE (err_parm_list) = error_mark_node;
+ return chainon (list, err_parm_list);
+ }
+
+ if (uses_parameter_packs (TREE_TYPE (parm)) && !is_parameter_pack
+ /* If we're in a nested template parameter list, the template
+ template parameter could be a parameter pack. */
+ && processing_template_parmlist == 1)
+ {
+ /* This template parameter is not a parameter pack, but it
+ should be. Complain about "bare" parameter packs. */
+ check_for_bare_parameter_packs (TREE_TYPE (parm));
+
+ /* Recover by calling this a parameter pack. */
+ is_parameter_pack = true;
+ }
+ }
+
+ /* A template parameter is not modifiable. */
+ TREE_CONSTANT (parm) = 1;
+ TREE_READONLY (parm) = 1;
+ decl = build_decl (parm_loc,
+ CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
+ TREE_CONSTANT (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ DECL_INITIAL (parm) = DECL_INITIAL (decl)
+ = build_template_parm_index (idx, processing_template_decl,
+ processing_template_decl,
+ decl, TREE_TYPE (parm));
+
+ TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))
+ = is_parameter_pack;
+ }
+ else
+ {
+ tree t;
+ parm = TREE_VALUE (TREE_VALUE (parm));
+
+ if (parm && TREE_CODE (parm) == TEMPLATE_DECL)
+ {
+ t = cxx_make_type (TEMPLATE_TEMPLATE_PARM);
+ /* This is for distinguishing between real templates and template
+ template parameters */
+ TREE_TYPE (parm) = t;
+ TREE_TYPE (DECL_TEMPLATE_RESULT (parm)) = t;
+ decl = parm;
+ }
+ else
+ {
+ t = cxx_make_type (TEMPLATE_TYPE_PARM);
+ /* parm is either IDENTIFIER_NODE or NULL_TREE. */
+ decl = build_decl (parm_loc,
+ TYPE_DECL, parm, t);
+ }
+
+ TYPE_NAME (t) = decl;
+ TYPE_STUB_DECL (t) = decl;
+ parm = decl;
+ TEMPLATE_TYPE_PARM_INDEX (t)
+ = build_template_parm_index (idx, processing_template_decl,
+ processing_template_decl,
+ decl, TREE_TYPE (parm));
+ TEMPLATE_TYPE_PARAMETER_PACK (t) = is_parameter_pack;
+ TYPE_CANONICAL (t) = canonical_type_parameter (t);
+ }
+ DECL_ARTIFICIAL (decl) = 1;
+ SET_DECL_TEMPLATE_PARM_P (decl);
+ pushdecl (decl);
+ parm = build_tree_list (defval, parm);
+ return chainon (list, parm);
+}
+
+/* The end of a template parameter list has been reached. Process the
+ tree list into a parameter vector, converting each parameter into a more
+ useful form. Type parameters are saved as IDENTIFIER_NODEs, and others
+ as PARM_DECLs. */
+
+tree
+end_template_parm_list (tree parms)
+{
+ int nparms;
+ tree parm, next;
+ tree saved_parmlist = make_tree_vec (list_length (parms));
+
+ current_template_parms
+ = tree_cons (size_int (processing_template_decl),
+ saved_parmlist, current_template_parms);
+
+ for (parm = parms, nparms = 0; parm; parm = next, nparms++)
+ {
+ next = TREE_CHAIN (parm);
+ TREE_VEC_ELT (saved_parmlist, nparms) = parm;
+ TREE_CHAIN (parm) = NULL_TREE;
+ }
+
+ --processing_template_parmlist;
+
+ return saved_parmlist;
+}
+
+/* end_template_decl is called after a template declaration is seen. */
+
+void
+end_template_decl (void)
+{
+ reset_specialization ();
+
+ if (! processing_template_decl)
+ return;
+
+ /* This matches the pushlevel in begin_template_parm_list. */
+ finish_scope ();
+
+ --processing_template_decl;
+ current_template_parms = TREE_CHAIN (current_template_parms);
+}
+
+/* Takes a TREE_LIST representing a template parameter and convert it
+ into an argument suitable to be passed to the type substitution
+ functions. Note that If the TREE_LIST contains an error_mark
+ node, the returned argument is error_mark_node. */
+
+static tree
+template_parm_to_arg (tree t)
+{
+
+ if (t == NULL_TREE
+ || TREE_CODE (t) != TREE_LIST)
+ return t;
+
+ if (error_operand_p (TREE_VALUE (t)))
+ return error_mark_node;
+
+ t = TREE_VALUE (t);
+
+ if (TREE_CODE (t) == TYPE_DECL
+ || TREE_CODE (t) == TEMPLATE_DECL)
+ {
+ t = TREE_TYPE (t);
+
+ if (TEMPLATE_TYPE_PARAMETER_PACK (t))
+ {
+ /* Turn this argument into a TYPE_ARGUMENT_PACK
+ with a single element, which expands T. */
+ tree vec = make_tree_vec (1);
+#ifdef ENABLE_CHECKING
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
+ (vec, TREE_VEC_LENGTH (vec));
+#endif
+ TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
+
+ t = cxx_make_type (TYPE_ARGUMENT_PACK);
+ SET_ARGUMENT_PACK_ARGS (t, vec);
+ }
+ }
+ else
+ {
+ t = DECL_INITIAL (t);
+
+ if (TEMPLATE_PARM_PARAMETER_PACK (t))
+ {
+ /* Turn this argument into a NONTYPE_ARGUMENT_PACK
+ with a single element, which expands T. */
+ tree vec = make_tree_vec (1);
+ tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t));
+#ifdef ENABLE_CHECKING
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
+ (vec, TREE_VEC_LENGTH (vec));
+#endif
+ t = convert_from_reference (t);
+ TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
+
+ t = make_node (NONTYPE_ARGUMENT_PACK);
+ SET_ARGUMENT_PACK_ARGS (t, vec);
+ TREE_TYPE (t) = type;
+ }
+ else
+ t = convert_from_reference (t);
+ }
+ return t;
+}
+
+/* Given a set of template parameters, return them as a set of template
+ arguments. The template parameters are represented as a TREE_VEC, in
+ the form documented in cp-tree.h for template arguments. */
+
+static tree
+template_parms_to_args (tree parms)
+{
+ tree header;
+ tree args = NULL_TREE;
+ int length = TMPL_PARMS_DEPTH (parms);
+ int l = length;
+
+ /* If there is only one level of template parameters, we do not
+ create a TREE_VEC of TREE_VECs. Instead, we return a single
+ TREE_VEC containing the arguments. */
+ if (length > 1)
+ args = make_tree_vec (length);
+
+ for (header = parms; header; header = TREE_CHAIN (header))
+ {
+ tree a = copy_node (TREE_VALUE (header));
+ int i;
+
+ TREE_TYPE (a) = NULL_TREE;
+ for (i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i)
+ TREE_VEC_ELT (a, i) = template_parm_to_arg (TREE_VEC_ELT (a, i));
+
+#ifdef ENABLE_CHECKING
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (a, TREE_VEC_LENGTH (a));
+#endif
+
+ if (length > 1)
+ TREE_VEC_ELT (args, --l) = a;
+ else
+ args = a;
+ }
+
+ if (length > 1 && TREE_VEC_ELT (args, 0) == NULL_TREE)
+ /* This can happen for template parms of a template template
+ parameter, e.g:
+
+ template<template<class T, class U> class TT> struct S;
+
+ Consider the level of the parms of TT; T and U both have
+ level 2; TT has no template parm of level 1. So in this case
+ the first element of full_template_args is NULL_TREE. If we
+ leave it like this TMPL_ARGS_DEPTH on args returns 1 instead
+ of 2. This will make tsubst wrongly consider that T and U
+ have level 1. Instead, let's create a dummy vector as the
+ first element of full_template_args so that TMPL_ARGS_DEPTH
+ returns the correct depth for args. */
+ TREE_VEC_ELT (args, 0) = make_tree_vec (1);
+ return args;
+}
+
+/* Within the declaration of a template, return the currently active
+ template parameters as an argument TREE_VEC. */
+
+static tree
+current_template_args (void)
+{
+ return template_parms_to_args (current_template_parms);
+}
+
+/* Update the declared TYPE by doing any lookups which were thought to be
+ dependent, but are not now that we know the SCOPE of the declarator. */
+
+tree
+maybe_update_decl_type (tree orig_type, tree scope)
+{
+ tree type = orig_type;
+
+ if (type == NULL_TREE)
+ return type;
+
+ if (TREE_CODE (orig_type) == TYPE_DECL)
+ type = TREE_TYPE (type);
+
+ if (scope && TYPE_P (scope) && dependent_type_p (scope)
+ && dependent_type_p (type)
+ /* Don't bother building up the args in this case. */
+ && TREE_CODE (type) != TEMPLATE_TYPE_PARM)
+ {
+ /* tsubst in the args corresponding to the template parameters,
+ including auto if present. Most things will be unchanged, but
+ make_typename_type and tsubst_qualified_id will resolve
+ TYPENAME_TYPEs and SCOPE_REFs that were previously dependent. */
+ tree args = current_template_args ();
+ tree auto_node = type_uses_auto (type);
+ tree pushed;
+ if (auto_node)
+ {
+ tree auto_vec = make_tree_vec (1);
+ TREE_VEC_ELT (auto_vec, 0) = auto_node;
+ args = add_to_template_args (args, auto_vec);
+ }
+ pushed = push_scope (scope);
+ type = tsubst (type, args, tf_warning_or_error, NULL_TREE);
+ if (pushed)
+ pop_scope (scope);
+ }
+
+ if (type == error_mark_node)
+ return orig_type;
+
+ if (TREE_CODE (orig_type) == TYPE_DECL)
+ {
+ if (same_type_p (type, TREE_TYPE (orig_type)))
+ type = orig_type;
+ else
+ type = TYPE_NAME (type);
+ }
+ return type;
+}
+
+/* Return a TEMPLATE_DECL corresponding to DECL, using the indicated
+ template PARMS. If MEMBER_TEMPLATE_P is true, the new template is
+ a member template. Used by push_template_decl below. */
+
+static tree
+build_template_decl (tree decl, tree parms, bool member_template_p)
+{
+ tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE);
+ DECL_TEMPLATE_PARMS (tmpl) = parms;
+ DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
+ DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
+ DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p;
+
+ return tmpl;
+}
+
+struct template_parm_data
+{
+ /* The level of the template parameters we are currently
+ processing. */
+ int level;
+
+ /* The index of the specialization argument we are currently
+ processing. */
+ int current_arg;
+
+ /* An array whose size is the number of template parameters. The
+ elements are nonzero if the parameter has been used in any one
+ of the arguments processed so far. */
+ int* parms;
+
+ /* An array whose size is the number of template arguments. The
+ elements are nonzero if the argument makes use of template
+ parameters of this level. */
+ int* arg_uses_template_parms;
+};
+
+/* Subroutine of push_template_decl used to see if each template
+ parameter in a partial specialization is used in the explicit
+ argument list. If T is of the LEVEL given in DATA (which is
+ treated as a template_parm_data*), then DATA->PARMS is marked
+ appropriately. */
+
+static int
+mark_template_parm (tree t, void* data)
+{
+ int level;
+ int idx;
+ struct template_parm_data* tpd = (struct template_parm_data*) data;
+
+ if (TREE_CODE (t) == TEMPLATE_PARM_INDEX)
+ {
+ level = TEMPLATE_PARM_LEVEL (t);
+ idx = TEMPLATE_PARM_IDX (t);
+ }
+ else
+ {
+ level = TEMPLATE_TYPE_LEVEL (t);
+ idx = TEMPLATE_TYPE_IDX (t);
+ }
+
+ if (level == tpd->level)
+ {
+ tpd->parms[idx] = 1;
+ tpd->arg_uses_template_parms[tpd->current_arg] = 1;
+ }
+
+ /* Return zero so that for_each_template_parm will continue the
+ traversal of the tree; we want to mark *every* template parm. */
+ return 0;
+}
+
+/* Process the partial specialization DECL. */
+
+static tree
+process_partial_specialization (tree decl)
+{
+ tree type = TREE_TYPE (decl);
+ tree maintmpl = CLASSTYPE_TI_TEMPLATE (type);
+ tree specargs = CLASSTYPE_TI_ARGS (type);
+ tree inner_args = INNERMOST_TEMPLATE_ARGS (specargs);
+ tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl);
+ tree inner_parms;
+ tree inst;
+ int nargs = TREE_VEC_LENGTH (inner_args);
+ int ntparms;
+ int i;
+ bool did_error_intro = false;
+ struct template_parm_data tpd;
+ struct template_parm_data tpd2;
+
+ gcc_assert (current_template_parms);
+
+ inner_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
+ ntparms = TREE_VEC_LENGTH (inner_parms);
+
+ /* We check that each of the template parameters given in the
+ partial specialization is used in the argument list to the
+ specialization. For example:
+
+ template <class T> struct S;
+ template <class T> struct S<T*>;
+
+ The second declaration is OK because `T*' uses the template
+ parameter T, whereas
+
+ template <class T> struct S<int>;
+
+ is no good. Even trickier is:
+
+ template <class T>
+ struct S1
+ {
+ template <class U>
+ struct S2;
+ template <class U>
+ struct S2<T>;
+ };
+
+ The S2<T> declaration is actually invalid; it is a
+ full-specialization. Of course,
+
+ template <class U>
+ struct S2<T (*)(U)>;
+
+ or some such would have been OK. */
+ tpd.level = TMPL_PARMS_DEPTH (current_template_parms);
+ tpd.parms = XALLOCAVEC (int, ntparms);
+ memset (tpd.parms, 0, sizeof (int) * ntparms);
+
+ tpd.arg_uses_template_parms = XALLOCAVEC (int, nargs);
+ memset (tpd.arg_uses_template_parms, 0, sizeof (int) * nargs);
+ for (i = 0; i < nargs; ++i)
+ {
+ tpd.current_arg = i;
+ for_each_template_parm (TREE_VEC_ELT (inner_args, i),
+ &mark_template_parm,
+ &tpd,
+ NULL,
+ /*include_nondeduced_p=*/false);
+ }
+ for (i = 0; i < ntparms; ++i)
+ if (tpd.parms[i] == 0)
+ {
+ /* One of the template parms was not used in the
+ specialization. */
+ if (!did_error_intro)
+ {
+ error ("template parameters not used in partial specialization:");
+ did_error_intro = true;
+ }
+
+ error (" %qD", TREE_VALUE (TREE_VEC_ELT (inner_parms, i)));
+ }
+
+ if (did_error_intro)
+ return error_mark_node;
+
+ /* [temp.class.spec]
+
+ The argument list of the specialization shall not be identical to
+ the implicit argument list of the primary template. */
+ if (comp_template_args
+ (inner_args,
+ INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE
+ (maintmpl)))))
+ error ("partial specialization %qT does not specialize any template arguments", type);
+
+ /* A partial specialization that replaces multiple parameters of the
+ primary template with a pack expansion is less specialized for those
+ parameters. */
+ if (nargs < DECL_NTPARMS (maintmpl))
+ {
+ error ("partial specialization is not more specialized than the "
+ "primary template because it replaces multiple parameters "
+ "with a pack expansion");
+ inform (DECL_SOURCE_LOCATION (maintmpl), "primary template here");
+ return decl;
+ }
+
+ /* [temp.class.spec]
+
+ A partially specialized non-type argument expression shall not
+ involve template parameters of the partial specialization except
+ when the argument expression is a simple identifier.
+
+ The type of a template parameter corresponding to a specialized
+ non-type argument shall not be dependent on a parameter of the
+ specialization.
+
+ Also, we verify that pack expansions only occur at the
+ end of the argument list. */
+ gcc_assert (nargs == DECL_NTPARMS (maintmpl));
+ tpd2.parms = 0;
+ for (i = 0; i < nargs; ++i)
+ {
+ tree parm = TREE_VALUE (TREE_VEC_ELT (main_inner_parms, i));
+ tree arg = TREE_VEC_ELT (inner_args, i);
+ tree packed_args = NULL_TREE;
+ int j, len = 1;
+
+ if (ARGUMENT_PACK_P (arg))
+ {
+ /* Extract the arguments from the argument pack. We'll be
+ iterating over these in the following loop. */
+ packed_args = ARGUMENT_PACK_ARGS (arg);
+ len = TREE_VEC_LENGTH (packed_args);
+ }
+
+ for (j = 0; j < len; j++)
+ {
+ if (packed_args)
+ /* Get the Jth argument in the parameter pack. */
+ arg = TREE_VEC_ELT (packed_args, j);
+
+ if (PACK_EXPANSION_P (arg))
+ {
+ /* Pack expansions must come at the end of the
+ argument list. */
+ if ((packed_args && j < len - 1)
+ || (!packed_args && i < nargs - 1))
+ {
+ if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
+ error ("parameter pack argument %qE must be at the "
+ "end of the template argument list", arg);
+ else
+ error ("parameter pack argument %qT must be at the "
+ "end of the template argument list", arg);
+ }
+ }
+
+ if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
+ /* We only care about the pattern. */
+ arg = PACK_EXPANSION_PATTERN (arg);
+
+ if (/* These first two lines are the `non-type' bit. */
+ !TYPE_P (arg)
+ && TREE_CODE (arg) != TEMPLATE_DECL
+ /* This next two lines are the `argument expression is not just a
+ simple identifier' condition and also the `specialized
+ non-type argument' bit. */
+ && TREE_CODE (arg) != TEMPLATE_PARM_INDEX
+ && !(REFERENCE_REF_P (arg)
+ && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_PARM_INDEX))
+ {
+ if ((!packed_args && tpd.arg_uses_template_parms[i])
+ || (packed_args && uses_template_parms (arg)))
+ error ("template argument %qE involves template parameter(s)",
+ arg);
+ else
+ {
+ /* Look at the corresponding template parameter,
+ marking which template parameters its type depends
+ upon. */
+ tree type = TREE_TYPE (parm);
+
+ if (!tpd2.parms)
+ {
+ /* We haven't yet initialized TPD2. Do so now. */
+ tpd2.arg_uses_template_parms = XALLOCAVEC (int, nargs);
+ /* The number of parameters here is the number in the
+ main template, which, as checked in the assertion
+ above, is NARGS. */
+ tpd2.parms = XALLOCAVEC (int, nargs);
+ tpd2.level =
+ TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
+ }
+
+ /* Mark the template parameters. But this time, we're
+ looking for the template parameters of the main
+ template, not in the specialization. */
+ tpd2.current_arg = i;
+ tpd2.arg_uses_template_parms[i] = 0;
+ memset (tpd2.parms, 0, sizeof (int) * nargs);
+ for_each_template_parm (type,
+ &mark_template_parm,
+ &tpd2,
+ NULL,
+ /*include_nondeduced_p=*/false);
+
+ if (tpd2.arg_uses_template_parms [i])
+ {
+ /* The type depended on some template parameters.
+ If they are fully specialized in the
+ specialization, that's OK. */
+ int j;
+ int count = 0;
+ for (j = 0; j < nargs; ++j)
+ if (tpd2.parms[j] != 0
+ && tpd.arg_uses_template_parms [j])
+ ++count;
+ if (count != 0)
+ error_n (input_location, count,
+ "type %qT of template argument %qE depends "
+ "on a template parameter",
+ "type %qT of template argument %qE depends "
+ "on template parameters",
+ type,
+ arg);
+ }
+ }
+ }
+ }
+ }
+
+ /* We should only get here once. */
+ gcc_assert (!COMPLETE_TYPE_P (type));
+
+ tree tmpl = build_template_decl (decl, current_template_parms,
+ DECL_MEMBER_TEMPLATE_P (maintmpl));
+ TREE_TYPE (tmpl) = type;
+ DECL_TEMPLATE_RESULT (tmpl) = decl;
+ SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
+ DECL_TEMPLATE_INFO (tmpl) = build_template_info (maintmpl, specargs);
+ DECL_PRIMARY_TEMPLATE (tmpl) = maintmpl;
+
+ DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)
+ = tree_cons (specargs, tmpl,
+ DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
+ TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type;
+
+ for (inst = DECL_TEMPLATE_INSTANTIATIONS (maintmpl); inst;
+ inst = TREE_CHAIN (inst))
+ {
+ tree inst_type = TREE_VALUE (inst);
+ if (COMPLETE_TYPE_P (inst_type)
+ && CLASSTYPE_IMPLICIT_INSTANTIATION (inst_type))
+ {
+ tree spec = most_specialized_class (inst_type, tf_none);
+ if (spec && TREE_TYPE (spec) == type)
+ permerror (input_location,
+ "partial specialization of %qT after instantiation "
+ "of %qT", type, inst_type);
+ }
+ }
+
+ return decl;
+}
+
+/* PARM is a template parameter of some form; return the corresponding
+ TEMPLATE_PARM_INDEX. */
+
+static tree
+get_template_parm_index (tree parm)
+{
+ if (TREE_CODE (parm) == PARM_DECL
+ || TREE_CODE (parm) == CONST_DECL)
+ parm = DECL_INITIAL (parm);
+ else if (TREE_CODE (parm) == TYPE_DECL
+ || TREE_CODE (parm) == TEMPLATE_DECL)
+ parm = TREE_TYPE (parm);
+ if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM
+ || TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM)
+ parm = TEMPLATE_TYPE_PARM_INDEX (parm);
+ gcc_assert (TREE_CODE (parm) == TEMPLATE_PARM_INDEX);
+ return parm;
+}
+
+/* Subroutine of fixed_parameter_pack_p below. Look for any template
+ parameter packs used by the template parameter PARM. */
+
+static void
+fixed_parameter_pack_p_1 (tree parm, struct find_parameter_pack_data *ppd)
+{
+ /* A type parm can't refer to another parm. */
+ if (TREE_CODE (parm) == TYPE_DECL)
+ return;
+ else if (TREE_CODE (parm) == PARM_DECL)
+ {
+ cp_walk_tree (&TREE_TYPE (parm), &find_parameter_packs_r,
+ ppd, ppd->visited);
+ return;
+ }
+
+ gcc_assert (TREE_CODE (parm) == TEMPLATE_DECL);
+
+ tree vec = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (parm));
+ for (int i = 0; i < TREE_VEC_LENGTH (vec); ++i)
+ fixed_parameter_pack_p_1 (TREE_VALUE (TREE_VEC_ELT (vec, i)), ppd);
+}
+
+/* PARM is a template parameter pack. Return any parameter packs used in
+ its type or the type of any of its template parameters. If there are
+ any such packs, it will be instantiated into a fixed template parameter
+ list by partial instantiation rather than be fully deduced. */
+
+tree
+fixed_parameter_pack_p (tree parm)
+{
+ /* This can only be true in a member template. */
+ if (TEMPLATE_PARM_ORIG_LEVEL (get_template_parm_index (parm)) < 2)
+ return NULL_TREE;
+ /* This can only be true for a parameter pack. */
+ if (!template_parameter_pack_p (parm))
+ return NULL_TREE;
+ /* A type parm can't refer to another parm. */
+ if (TREE_CODE (parm) == TYPE_DECL)
+ return NULL_TREE;
+
+ tree parameter_packs = NULL_TREE;
+ struct find_parameter_pack_data ppd;
+ ppd.parameter_packs = &parameter_packs;
+ ppd.visited = pointer_set_create ();
+
+ fixed_parameter_pack_p_1 (parm, &ppd);
+
+ pointer_set_destroy (ppd.visited);
+ return parameter_packs;
+}
+
+/* Check that a template declaration's use of default arguments and
+ parameter packs is not invalid. Here, PARMS are the template
+ parameters. IS_PRIMARY is true if DECL is the thing declared by
+ a primary template. IS_PARTIAL is true if DECL is a partial
+ specialization.
+
+ IS_FRIEND_DECL is nonzero if DECL is a friend function template
+ declaration (but not a definition); 1 indicates a declaration, 2
+ indicates a redeclaration. When IS_FRIEND_DECL=2, no errors are
+ emitted for extraneous default arguments.
+
+ Returns TRUE if there were no errors found, FALSE otherwise. */
+
+bool
+check_default_tmpl_args (tree decl, tree parms, bool is_primary,
+ bool is_partial, int is_friend_decl)
+{
+ const char *msg;
+ int last_level_to_check;
+ tree parm_level;
+ bool no_errors = true;
+
+ /* [temp.param]
+
+ A default template-argument shall not be specified in a
+ function template declaration or a function template definition, nor
+ in the template-parameter-list of the definition of a member of a
+ class template. */
+
+ if (TREE_CODE (CP_DECL_CONTEXT (decl)) == FUNCTION_DECL)
+ /* You can't have a function template declaration in a local
+ scope, nor you can you define a member of a class template in a
+ local scope. */
+ return true;
+
+ if (TREE_CODE (decl) == TYPE_DECL
+ && TREE_TYPE (decl)
+ && LAMBDA_TYPE_P (TREE_TYPE (decl)))
+ /* A lambda doesn't have an explicit declaration; don't complain
+ about the parms of the enclosing class. */
+ return true;
+
+ if (current_class_type
+ && !TYPE_BEING_DEFINED (current_class_type)
+ && DECL_LANG_SPECIFIC (decl)
+ && DECL_DECLARES_FUNCTION_P (decl)
+ /* If this is either a friend defined in the scope of the class
+ or a member function. */
+ && (DECL_FUNCTION_MEMBER_P (decl)
+ ? same_type_p (DECL_CONTEXT (decl), current_class_type)
+ : DECL_FRIEND_CONTEXT (decl)
+ ? same_type_p (DECL_FRIEND_CONTEXT (decl), current_class_type)
+ : false)
+ /* And, if it was a member function, it really was defined in
+ the scope of the class. */
+ && (!DECL_FUNCTION_MEMBER_P (decl)
+ || DECL_INITIALIZED_IN_CLASS_P (decl)))
+ /* We already checked these parameters when the template was
+ declared, so there's no need to do it again now. This function
+ was defined in class scope, but we're processing its body now
+ that the class is complete. */
+ return true;
+
+ /* Core issue 226 (C++0x only): the following only applies to class
+ templates. */
+ if (is_primary
+ && ((cxx_dialect == cxx98) || TREE_CODE (decl) != FUNCTION_DECL))
+ {
+ /* [temp.param]
+
+ If a template-parameter has a default template-argument, all
+ subsequent template-parameters shall have a default
+ template-argument supplied. */
+ for (parm_level = parms; parm_level; parm_level = TREE_CHAIN (parm_level))
+ {
+ tree inner_parms = TREE_VALUE (parm_level);
+ int ntparms = TREE_VEC_LENGTH (inner_parms);
+ int seen_def_arg_p = 0;
+ int i;
+
+ for (i = 0; i < ntparms; ++i)
+ {
+ tree parm = TREE_VEC_ELT (inner_parms, i);
+
+ if (parm == error_mark_node)
+ continue;
+
+ if (TREE_PURPOSE (parm))
+ seen_def_arg_p = 1;
+ else if (seen_def_arg_p
+ && !template_parameter_pack_p (TREE_VALUE (parm)))
+ {
+ error ("no default argument for %qD", TREE_VALUE (parm));
+ /* For better subsequent error-recovery, we indicate that
+ there should have been a default argument. */
+ TREE_PURPOSE (parm) = error_mark_node;
+ no_errors = false;
+ }
+ else if (!is_partial
+ && !is_friend_decl
+ /* Don't complain about an enclosing partial
+ specialization. */
+ && parm_level == parms
+ && TREE_CODE (decl) == TYPE_DECL
+ && i < ntparms - 1
+ && template_parameter_pack_p (TREE_VALUE (parm))
+ /* A fixed parameter pack will be partially
+ instantiated into a fixed length list. */
+ && !fixed_parameter_pack_p (TREE_VALUE (parm)))
+ {
+ /* A primary class template can only have one
+ parameter pack, at the end of the template
+ parameter list. */
+
+ if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL)
+ error ("parameter pack %qE must be at the end of the"
+ " template parameter list", TREE_VALUE (parm));
+ else
+ error ("parameter pack %qT must be at the end of the"
+ " template parameter list",
+ TREE_TYPE (TREE_VALUE (parm)));
+
+ TREE_VALUE (TREE_VEC_ELT (inner_parms, i))
+ = error_mark_node;
+ no_errors = false;
+ }
+ }
+ }
+ }
+
+ if (((cxx_dialect == cxx98) && TREE_CODE (decl) != TYPE_DECL)
+ || is_partial
+ || !is_primary
+ || is_friend_decl)
+ /* For an ordinary class template, default template arguments are
+ allowed at the innermost level, e.g.:
+ template <class T = int>
+ struct S {};
+ but, in a partial specialization, they're not allowed even
+ there, as we have in [temp.class.spec]:
+
+ The template parameter list of a specialization shall not
+ contain default template argument values.
+
+ So, for a partial specialization, or for a function template
+ (in C++98/C++03), we look at all of them. */
+ ;
+ else
+ /* But, for a primary class template that is not a partial
+ specialization we look at all template parameters except the
+ innermost ones. */
+ parms = TREE_CHAIN (parms);
+
+ /* Figure out what error message to issue. */
+ if (is_friend_decl == 2)
+ msg = G_("default template arguments may not be used in function template "
+ "friend re-declaration");
+ else if (is_friend_decl)
+ msg = G_("default template arguments may not be used in function template "
+ "friend declarations");
+ else if (TREE_CODE (decl) == FUNCTION_DECL && (cxx_dialect == cxx98))
+ msg = G_("default template arguments may not be used in function templates "
+ "without -std=c++11 or -std=gnu++11");
+ else if (is_partial)
+ msg = G_("default template arguments may not be used in "
+ "partial specializations");
+ else
+ msg = G_("default argument for template parameter for class enclosing %qD");
+
+ if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
+ /* If we're inside a class definition, there's no need to
+ examine the parameters to the class itself. On the one
+ hand, they will be checked when the class is defined, and,
+ on the other, default arguments are valid in things like:
+ template <class T = double>
+ struct S { template <class U> void f(U); };
+ Here the default argument for `S' has no bearing on the
+ declaration of `f'. */
+ last_level_to_check = template_class_depth (current_class_type) + 1;
+ else
+ /* Check everything. */
+ last_level_to_check = 0;
+
+ for (parm_level = parms;
+ parm_level && TMPL_PARMS_DEPTH (parm_level) >= last_level_to_check;
+ parm_level = TREE_CHAIN (parm_level))
+ {
+ tree inner_parms = TREE_VALUE (parm_level);
+ int i;
+ int ntparms;
+
+ ntparms = TREE_VEC_LENGTH (inner_parms);
+ for (i = 0; i < ntparms; ++i)
+ {
+ if (TREE_VEC_ELT (inner_parms, i) == error_mark_node)
+ continue;
+
+ if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)))
+ {
+ if (msg)
+ {
+ no_errors = false;
+ if (is_friend_decl == 2)
+ return no_errors;
+
+ error (msg, decl);
+ msg = 0;
+ }
+
+ /* Clear out the default argument so that we are not
+ confused later. */
+ TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE;
+ }
+ }
+
+ /* At this point, if we're still interested in issuing messages,
+ they must apply to classes surrounding the object declared. */
+ if (msg)
+ msg = G_("default argument for template parameter for class "
+ "enclosing %qD");
+ }
+
+ return no_errors;
+}
+
+/* Worker for push_template_decl_real, called via
+ for_each_template_parm. DATA is really an int, indicating the
+ level of the parameters we are interested in. If T is a template
+ parameter of that level, return nonzero. */
+
+static int
+template_parm_this_level_p (tree t, void* data)
+{
+ int this_level = *(int *)data;
+ int level;
+
+ if (TREE_CODE (t) == TEMPLATE_PARM_INDEX)
+ level = TEMPLATE_PARM_LEVEL (t);
+ else
+ level = TEMPLATE_TYPE_LEVEL (t);
+ return level == this_level;
+}
+
+/* Creates a TEMPLATE_DECL for the indicated DECL using the template
+ parameters given by current_template_args, or reuses a
+ previously existing one, if appropriate. Returns the DECL, or an
+ equivalent one, if it is replaced via a call to duplicate_decls.
+
+ If IS_FRIEND is true, DECL is a friend declaration. */
+
+tree
+push_template_decl_real (tree decl, bool is_friend)
+{
+ tree tmpl;
+ tree args;
+ tree info;
+ tree ctx;
+ bool is_primary;
+ bool is_partial;
+ int new_template_p = 0;
+ /* True if the template is a member template, in the sense of
+ [temp.mem]. */
+ bool member_template_p = false;
+
+ if (decl == error_mark_node || !current_template_parms)
+ return error_mark_node;
+
+ /* See if this is a partial specialization. */
+ is_partial = (DECL_IMPLICIT_TYPEDEF_P (decl)
+ && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)));
+
+ if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl))
+ is_friend = true;
+
+ if (is_friend)
+ /* For a friend, we want the context of the friend function, not
+ the type of which it is a friend. */
+ ctx = CP_DECL_CONTEXT (decl);
+ else if (CP_DECL_CONTEXT (decl)
+ && TREE_CODE (CP_DECL_CONTEXT (decl)) != NAMESPACE_DECL)
+ /* In the case of a virtual function, we want the class in which
+ it is defined. */
+ ctx = CP_DECL_CONTEXT (decl);
+ else
+ /* Otherwise, if we're currently defining some class, the DECL
+ is assumed to be a member of the class. */
+ ctx = current_scope ();
+
+ if (ctx && TREE_CODE (ctx) == NAMESPACE_DECL)
+ ctx = NULL_TREE;
+
+ if (!DECL_CONTEXT (decl))
+ DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
+
+ /* See if this is a primary template. */
+ if (is_friend && ctx
+ && uses_template_parms_level (ctx, processing_template_decl))
+ /* A friend template that specifies a class context, i.e.
+ template <typename T> friend void A<T>::f();
+ is not primary. */
+ is_primary = false;
+ else
+ is_primary = template_parm_scope_p ();
+
+ if (is_primary)
+ {
+ if (DECL_CLASS_SCOPE_P (decl))
+ member_template_p = true;
+ if (TREE_CODE (decl) == TYPE_DECL
+ && ANON_AGGRNAME_P (DECL_NAME (decl)))
+ {
+ error ("template class without a name");
+ return error_mark_node;
+ }
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (DECL_DESTRUCTOR_P (decl))
+ {
+ /* [temp.mem]
+
+ A destructor shall not be a member template. */
+ error ("destructor %qD declared as member template", decl);
+ return error_mark_node;
+ }
+ if (NEW_DELETE_OPNAME_P (DECL_NAME (decl))
+ && (!prototype_p (TREE_TYPE (decl))
+ || TYPE_ARG_TYPES (TREE_TYPE (decl)) == void_list_node
+ || !TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)))
+ || (TREE_CHAIN (TYPE_ARG_TYPES ((TREE_TYPE (decl))))
+ == void_list_node)))
+ {
+ /* [basic.stc.dynamic.allocation]
+
+ An allocation function can be a function
+ template. ... Template allocation functions shall
+ have two or more parameters. */
+ error ("invalid template declaration of %qD", decl);
+ return error_mark_node;
+ }
+ }
+ else if (DECL_IMPLICIT_TYPEDEF_P (decl)
+ && CLASS_TYPE_P (TREE_TYPE (decl)))
+ /* OK */;
+ else if (TREE_CODE (decl) == TYPE_DECL
+ && TYPE_DECL_ALIAS_P (decl))
+ /* alias-declaration */
+ gcc_assert (!DECL_ARTIFICIAL (decl));
+ else
+ {
+ error ("template declaration of %q#D", decl);
+ return error_mark_node;
+ }
+ }
+
+ /* Check to see that the rules regarding the use of default
+ arguments are not being violated. */
+ check_default_tmpl_args (decl, current_template_parms,
+ is_primary, is_partial, /*is_friend_decl=*/0);
+
+ /* Ensure that there are no parameter packs in the type of this
+ declaration that have not been expanded. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ /* Check each of the arguments individually to see if there are
+ any bare parameter packs. */
+ tree type = TREE_TYPE (decl);
+ tree arg = DECL_ARGUMENTS (decl);
+ tree argtype = TYPE_ARG_TYPES (type);
+
+ while (arg && argtype)
+ {
+ if (!DECL_PACK_P (arg)
+ && check_for_bare_parameter_packs (TREE_TYPE (arg)))
+ {
+ /* This is a PARM_DECL that contains unexpanded parameter
+ packs. We have already complained about this in the
+ check_for_bare_parameter_packs call, so just replace
+ these types with ERROR_MARK_NODE. */
+ TREE_TYPE (arg) = error_mark_node;
+ TREE_VALUE (argtype) = error_mark_node;
+ }
+
+ arg = DECL_CHAIN (arg);
+ argtype = TREE_CHAIN (argtype);
+ }
+
+ /* Check for bare parameter packs in the return type and the
+ exception specifiers. */
+ if (check_for_bare_parameter_packs (TREE_TYPE (type)))
+ /* Errors were already issued, set return type to int
+ as the frontend doesn't expect error_mark_node as
+ the return type. */
+ TREE_TYPE (type) = integer_type_node;
+ if (check_for_bare_parameter_packs (TYPE_RAISES_EXCEPTIONS (type)))
+ TYPE_RAISES_EXCEPTIONS (type) = NULL_TREE;
+ }
+ else if (check_for_bare_parameter_packs ((TREE_CODE (decl) == TYPE_DECL
+ && TYPE_DECL_ALIAS_P (decl))
+ ? DECL_ORIGINAL_TYPE (decl)
+ : TREE_TYPE (decl)))
+ {
+ TREE_TYPE (decl) = error_mark_node;
+ return error_mark_node;
+ }
+
+ if (is_partial)
+ return process_partial_specialization (decl);
+
+ args = current_template_args ();
+
+ if (!ctx
+ || TREE_CODE (ctx) == FUNCTION_DECL
+ || (CLASS_TYPE_P (ctx) && TYPE_BEING_DEFINED (ctx))
+ || (TREE_CODE (decl) == TYPE_DECL
+ && LAMBDA_TYPE_P (TREE_TYPE (decl)))
+ || (is_friend && !DECL_TEMPLATE_INFO (decl)))
+ {
+ if (DECL_LANG_SPECIFIC (decl)
+ && DECL_TEMPLATE_INFO (decl)
+ && DECL_TI_TEMPLATE (decl))
+ tmpl = DECL_TI_TEMPLATE (decl);
+ /* If DECL is a TYPE_DECL for a class-template, then there won't
+ be DECL_LANG_SPECIFIC. The information equivalent to
+ DECL_TEMPLATE_INFO is found in TYPE_TEMPLATE_INFO instead. */
+ else if (DECL_IMPLICIT_TYPEDEF_P (decl)
+ && TYPE_TEMPLATE_INFO (TREE_TYPE (decl))
+ && TYPE_TI_TEMPLATE (TREE_TYPE (decl)))
+ {
+ /* Since a template declaration already existed for this
+ class-type, we must be redeclaring it here. Make sure
+ that the redeclaration is valid. */
+ redeclare_class_template (TREE_TYPE (decl),
+ current_template_parms);
+ /* We don't need to create a new TEMPLATE_DECL; just use the
+ one we already had. */
+ tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl));
+ }
+ else
+ {
+ tmpl = build_template_decl (decl, current_template_parms,
+ member_template_p);
+ new_template_p = 1;
+
+ if (DECL_LANG_SPECIFIC (decl)
+ && DECL_TEMPLATE_SPECIALIZATION (decl))
+ {
+ /* A specialization of a member template of a template
+ class. */
+ SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
+ DECL_TEMPLATE_INFO (tmpl) = DECL_TEMPLATE_INFO (decl);
+ DECL_TEMPLATE_INFO (decl) = NULL_TREE;
+ }
+ }
+ }
+ else
+ {
+ tree a, t, current, parms;
+ int i;
+ tree tinfo = get_template_info (decl);
+
+ if (!tinfo)
+ {
+ error ("template definition of non-template %q#D", decl);
+ return error_mark_node;
+ }
+
+ tmpl = TI_TEMPLATE (tinfo);
+
+ if (DECL_FUNCTION_TEMPLATE_P (tmpl)
+ && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
+ && DECL_TEMPLATE_SPECIALIZATION (decl)
+ && DECL_MEMBER_TEMPLATE_P (tmpl))
+ {
+ tree new_tmpl;
+
+ /* The declaration is a specialization of a member
+ template, declared outside the class. Therefore, the
+ innermost template arguments will be NULL, so we
+ replace them with the arguments determined by the
+ earlier call to check_explicit_specialization. */
+ args = DECL_TI_ARGS (decl);
+
+ new_tmpl
+ = build_template_decl (decl, current_template_parms,
+ member_template_p);
+ DECL_TEMPLATE_RESULT (new_tmpl) = decl;
+ TREE_TYPE (new_tmpl) = TREE_TYPE (decl);
+ DECL_TI_TEMPLATE (decl) = new_tmpl;
+ SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl);
+ DECL_TEMPLATE_INFO (new_tmpl)
+ = build_template_info (tmpl, args);
+
+ register_specialization (new_tmpl,
+ most_general_template (tmpl),
+ args,
+ is_friend, 0);
+ return decl;
+ }
+
+ /* Make sure the template headers we got make sense. */
+
+ parms = DECL_TEMPLATE_PARMS (tmpl);
+ i = TMPL_PARMS_DEPTH (parms);
+ if (TMPL_ARGS_DEPTH (args) != i)
+ {
+ error ("expected %d levels of template parms for %q#D, got %d",
+ i, decl, TMPL_ARGS_DEPTH (args));
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ return error_mark_node;
+ }
+ else
+ for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms))
+ {
+ a = TMPL_ARGS_LEVEL (args, i);
+ t = INNERMOST_TEMPLATE_PARMS (parms);
+
+ if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
+ {
+ if (current == decl)
+ error ("got %d template parameters for %q#D",
+ TREE_VEC_LENGTH (a), decl);
+ else
+ error ("got %d template parameters for %q#T",
+ TREE_VEC_LENGTH (a), current);
+ error (" but %d required", TREE_VEC_LENGTH (t));
+ /* Avoid crash in import_export_decl. */
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ return error_mark_node;
+ }
+
+ if (current == decl)
+ current = ctx;
+ else if (current == NULL_TREE)
+ /* Can happen in erroneous input. */
+ break;
+ else
+ current = get_containing_scope (current);
+ }
+
+ /* Check that the parms are used in the appropriate qualifying scopes
+ in the declarator. */
+ if (!comp_template_args
+ (TI_ARGS (tinfo),
+ TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl)))))
+ {
+ error ("\
+template arguments to %qD do not match original template %qD",
+ decl, DECL_TEMPLATE_RESULT (tmpl));
+ if (!uses_template_parms (TI_ARGS (tinfo)))
+ inform (input_location, "use template<> for an explicit specialization");
+ /* Avoid crash in import_export_decl. */
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ return error_mark_node;
+ }
+ }
+
+ DECL_TEMPLATE_RESULT (tmpl) = decl;
+ TREE_TYPE (tmpl) = TREE_TYPE (decl);
+
+ /* Push template declarations for global functions and types. Note
+ that we do not try to push a global template friend declared in a
+ template class; such a thing may well depend on the template
+ parameters of the class. */
+ if (new_template_p && !ctx
+ && !(is_friend && template_class_depth (current_class_type) > 0))
+ {
+ tmpl = pushdecl_namespace_level (tmpl, is_friend);
+ if (tmpl == error_mark_node)
+ return error_mark_node;
+
+ /* Hide template friend classes that haven't been declared yet. */
+ if (is_friend && TREE_CODE (decl) == TYPE_DECL)
+ {
+ DECL_ANTICIPATED (tmpl) = 1;
+ DECL_FRIEND_P (tmpl) = 1;
+ }
+ }
+
+ if (is_primary)
+ {
+ tree parms = DECL_TEMPLATE_PARMS (tmpl);
+ int i;
+
+ DECL_PRIMARY_TEMPLATE (tmpl) = tmpl;
+ if (DECL_CONV_FN_P (tmpl))
+ {
+ int depth = TMPL_PARMS_DEPTH (parms);
+
+ /* It is a conversion operator. See if the type converted to
+ depends on innermost template operands. */
+
+ if (uses_template_parms_level (TREE_TYPE (TREE_TYPE (tmpl)),
+ depth))
+ DECL_TEMPLATE_CONV_FN_P (tmpl) = 1;
+ }
+
+ /* Give template template parms a DECL_CONTEXT of the template
+ for which they are a parameter. */
+ parms = INNERMOST_TEMPLATE_PARMS (parms);
+ for (i = TREE_VEC_LENGTH (parms) - 1; i >= 0; --i)
+ {
+ tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+ if (TREE_CODE (parm) == TEMPLATE_DECL)
+ DECL_CONTEXT (parm) = tmpl;
+ }
+ }
+
+ /* The DECL_TI_ARGS of DECL contains full set of arguments referring
+ back to its most general template. If TMPL is a specialization,
+ ARGS may only have the innermost set of arguments. Add the missing
+ argument levels if necessary. */
+ if (DECL_TEMPLATE_INFO (tmpl))
+ args = add_outermost_template_args (DECL_TI_ARGS (tmpl), args);
+
+ info = build_template_info (tmpl, args);
+
+ if (DECL_IMPLICIT_TYPEDEF_P (decl))
+ SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info);
+ else
+ {
+ if (is_primary && !DECL_LANG_SPECIFIC (decl))
+ retrofit_lang_decl (decl);
+ if (DECL_LANG_SPECIFIC (decl))
+ DECL_TEMPLATE_INFO (decl) = info;
+ }
+
+ return DECL_TEMPLATE_RESULT (tmpl);
+}
+
+tree
+push_template_decl (tree decl)
+{
+ return push_template_decl_real (decl, false);
+}
+
+/* FN is an inheriting constructor that inherits from the constructor
+ template INHERITED; turn FN into a constructor template with a matching
+ template header. */
+
+tree
+add_inherited_template_parms (tree fn, tree inherited)
+{
+ tree inner_parms
+ = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (inherited));
+ inner_parms = copy_node (inner_parms);
+ tree parms
+ = tree_cons (size_int (processing_template_decl + 1),
+ inner_parms, current_template_parms);
+ tree tmpl = build_template_decl (fn, parms, /*member*/true);
+ tree args = template_parms_to_args (parms);
+ DECL_TEMPLATE_INFO (fn) = build_template_info (tmpl, args);
+ TREE_TYPE (tmpl) = TREE_TYPE (fn);
+ DECL_TEMPLATE_RESULT (tmpl) = fn;
+ DECL_ARTIFICIAL (tmpl) = true;
+ DECL_PRIMARY_TEMPLATE (tmpl) = tmpl;
+ return tmpl;
+}
+
+/* Called when a class template TYPE is redeclared with the indicated
+ template PARMS, e.g.:
+
+ template <class T> struct S;
+ template <class T> struct S {}; */
+
+bool
+redeclare_class_template (tree type, tree parms)
+{
+ tree tmpl;
+ tree tmpl_parms;
+ int i;
+
+ if (!TYPE_TEMPLATE_INFO (type))
+ {
+ error ("%qT is not a template type", type);
+ return false;
+ }
+
+ tmpl = TYPE_TI_TEMPLATE (type);
+ if (!PRIMARY_TEMPLATE_P (tmpl))
+ /* The type is nested in some template class. Nothing to worry
+ about here; there are no new template parameters for the nested
+ type. */
+ return true;
+
+ if (!parms)
+ {
+ error ("template specifiers not specified in declaration of %qD",
+ tmpl);
+ return false;
+ }
+
+ parms = INNERMOST_TEMPLATE_PARMS (parms);
+ tmpl_parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
+
+ if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms))
+ {
+ error_n (input_location, TREE_VEC_LENGTH (parms),
+ "redeclared with %d template parameter",
+ "redeclared with %d template parameters",
+ TREE_VEC_LENGTH (parms));
+ inform_n (input_location, TREE_VEC_LENGTH (tmpl_parms),
+ "previous declaration %q+D used %d template parameter",
+ "previous declaration %q+D used %d template parameters",
+ tmpl, TREE_VEC_LENGTH (tmpl_parms));
+ return false;
+ }
+
+ for (i = 0; i < TREE_VEC_LENGTH (tmpl_parms); ++i)
+ {
+ tree tmpl_parm;
+ tree parm;
+ tree tmpl_default;
+ tree parm_default;
+
+ if (TREE_VEC_ELT (tmpl_parms, i) == error_mark_node
+ || TREE_VEC_ELT (parms, i) == error_mark_node)
+ continue;
+
+ tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i));
+ if (tmpl_parm == error_mark_node)
+ return false;
+
+ parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+ tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i));
+ parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
+
+ /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
+ TEMPLATE_DECL. */
+ if (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
+ || (TREE_CODE (tmpl_parm) != TYPE_DECL
+ && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))
+ || (TREE_CODE (tmpl_parm) != PARM_DECL
+ && (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (tmpl_parm))
+ != TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm))))
+ || (TREE_CODE (tmpl_parm) == PARM_DECL
+ && (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (tmpl_parm))
+ != TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))))
+ {
+ error ("template parameter %q+#D", tmpl_parm);
+ error ("redeclared here as %q#D", parm);
+ return false;
+ }
+
+ if (tmpl_default != NULL_TREE && parm_default != NULL_TREE)
+ {
+ /* We have in [temp.param]:
+
+ A template-parameter may not be given default arguments
+ by two different declarations in the same scope. */
+ error_at (input_location, "redefinition of default argument for %q#D", parm);
+ inform (DECL_SOURCE_LOCATION (tmpl_parm),
+ "original definition appeared here");
+ return false;
+ }
+
+ if (parm_default != NULL_TREE)
+ /* Update the previous template parameters (which are the ones
+ that will really count) with the new default value. */
+ TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i)) = parm_default;
+ else if (tmpl_default != NULL_TREE)
+ /* Update the new parameters, too; they'll be used as the
+ parameters for any members. */
+ TREE_PURPOSE (TREE_VEC_ELT (parms, i)) = tmpl_default;
+ }
+
+ return true;
+}
+
+/* Simplify EXPR if it is a non-dependent expression. Returns the
+ (possibly simplified) expression. */
+
+tree
+fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain)
+{
+ if (expr == NULL_TREE)
+ return NULL_TREE;
+
+ /* If we're in a template, but EXPR isn't value dependent, simplify
+ it. We're supposed to treat:
+
+ template <typename T> void f(T[1 + 1]);
+ template <typename T> void f(T[2]);
+
+ as two declarations of the same function, for example. */
+ if (processing_template_decl
+ && !instantiation_dependent_expression_p (expr)
+ && potential_constant_expression (expr))
+ {
+ HOST_WIDE_INT saved_processing_template_decl;
+
+ saved_processing_template_decl = processing_template_decl;
+ processing_template_decl = 0;
+ expr = tsubst_copy_and_build (expr,
+ /*args=*/NULL_TREE,
+ complain,
+ /*in_decl=*/NULL_TREE,
+ /*function_p=*/false,
+ /*integral_constant_expression_p=*/true);
+ processing_template_decl = saved_processing_template_decl;
+ }
+ return expr;
+}
+
+tree
+fold_non_dependent_expr (tree expr)
+{
+ return fold_non_dependent_expr_sfinae (expr, tf_error);
+}
+
+/* Return TRUE iff T is a type alias, a TEMPLATE_DECL for an alias
+ template declaration, or a TYPE_DECL for an alias declaration. */
+
+bool
+alias_type_or_template_p (tree t)
+{
+ if (t == NULL_TREE)
+ return false;
+ return ((TREE_CODE (t) == TYPE_DECL && TYPE_DECL_ALIAS_P (t))
+ || (TYPE_P (t)
+ && TYPE_NAME (t)
+ && TYPE_DECL_ALIAS_P (TYPE_NAME (t)))
+ || DECL_ALIAS_TEMPLATE_P (t));
+}
+
+/* Return TRUE iff is a specialization of an alias template. */
+
+bool
+alias_template_specialization_p (const_tree t)
+{
+ if (t == NULL_TREE)
+ return false;
+
+ return (TYPE_P (t)
+ && TYPE_TEMPLATE_INFO (t)
+ && PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (t))
+ && DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t)));
+}
+
+/* Return the number of innermost template parameters in TMPL. */
+
+static int
+num_innermost_template_parms (tree tmpl)
+{
+ tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
+ return TREE_VEC_LENGTH (parms);
+}
+
+/* Return either TMPL or another template that it is equivalent to under DR
+ 1286: An alias that just changes the name of a template is equivalent to
+ the other template. */
+
+static tree
+get_underlying_template (tree tmpl)
+{
+ gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
+ while (DECL_ALIAS_TEMPLATE_P (tmpl))
+ {
+ tree result = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl));
+ if (TYPE_TEMPLATE_INFO (result))
+ {
+ tree sub = TYPE_TI_TEMPLATE (result);
+ if (PRIMARY_TEMPLATE_P (sub)
+ && (num_innermost_template_parms (tmpl)
+ == num_innermost_template_parms (sub)))
+ {
+ tree alias_args = INNERMOST_TEMPLATE_ARGS
+ (template_parms_to_args (DECL_TEMPLATE_PARMS (tmpl)));
+ if (!comp_template_args (TYPE_TI_ARGS (result), alias_args))
+ break;
+ /* The alias type is equivalent to the pattern of the
+ underlying template, so strip the alias. */
+ tmpl = sub;
+ continue;
+ }
+ }
+ break;
+ }
+ return tmpl;
+}
+
+/* Subroutine of convert_nontype_argument. Converts EXPR to TYPE, which
+ must be a function or a pointer-to-function type, as specified
+ in [temp.arg.nontype]: disambiguate EXPR if it is an overload set,
+ and check that the resulting function has external linkage. */
+
+static tree
+convert_nontype_argument_function (tree type, tree expr)
+{
+ tree fns = expr;
+ tree fn, fn_no_ptr;
+ linkage_kind linkage;
+
+ fn = instantiate_type (type, fns, tf_none);
+ if (fn == error_mark_node)
+ return error_mark_node;
+
+ fn_no_ptr = fn;
+ if (TREE_CODE (fn_no_ptr) == ADDR_EXPR)
+ fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0);
+ if (BASELINK_P (fn_no_ptr))
+ fn_no_ptr = BASELINK_FUNCTIONS (fn_no_ptr);
+
+ /* [temp.arg.nontype]/1
+
+ A template-argument for a non-type, non-template template-parameter
+ shall be one of:
+ [...]
+ -- the address of an object or function with external [C++11: or
+ internal] linkage. */
+
+ if (TREE_CODE (fn_no_ptr) != FUNCTION_DECL)
+ {
+ error ("%qE is not a valid template argument for type %qT", expr, type);
+ if (TYPE_PTR_P (type))
+ error ("it must be the address of a function with external linkage");
+ else
+ error ("it must be the name of a function with external linkage");
+ return NULL_TREE;
+ }
+
+ linkage = decl_linkage (fn_no_ptr);
+ if (cxx_dialect >= cxx11 ? linkage == lk_none : linkage != lk_external)
+ {
+ if (cxx_dialect >= cxx11)
+ error ("%qE is not a valid template argument for type %qT "
+ "because %qD has no linkage",
+ expr, type, fn_no_ptr);
+ else
+ error ("%qE is not a valid template argument for type %qT "
+ "because %qD does not have external linkage",
+ expr, type, fn_no_ptr);
+ return NULL_TREE;
+ }
+
+ return fn;
+}
+
+/* Subroutine of convert_nontype_argument.
+ Check if EXPR of type TYPE is a valid pointer-to-member constant.
+ Emit an error otherwise. */
+
+static bool
+check_valid_ptrmem_cst_expr (tree type, tree expr,
+ tsubst_flags_t complain)
+{
+ STRIP_NOPS (expr);
+ if (expr && (null_ptr_cst_p (expr) || TREE_CODE (expr) == PTRMEM_CST))
+ return true;
+ if (cxx_dialect >= cxx11 && null_member_pointer_value_p (expr))
+ return true;
+ if (complain & tf_error)
+ {
+ error ("%qE is not a valid template argument for type %qT",
+ expr, type);
+ error ("it must be a pointer-to-member of the form %<&X::Y%>");
+ }
+ return false;
+}
+
+/* Returns TRUE iff the address of OP is value-dependent.
+
+ 14.6.2.4 [temp.dep.temp]:
+ A non-integral non-type template-argument is dependent if its type is
+ dependent or it has either of the following forms
+ qualified-id
+ & qualified-id
+ and contains a nested-name-specifier which specifies a class-name that
+ names a dependent type.
+
+ We generalize this to just say that the address of a member of a
+ dependent class is value-dependent; the above doesn't cover the
+ address of a static data member named with an unqualified-id. */
+
+static bool
+has_value_dependent_address (tree op)
+{
+ /* We could use get_inner_reference here, but there's no need;
+ this is only relevant for template non-type arguments, which
+ can only be expressed as &id-expression. */
+ if (DECL_P (op))
+ {
+ tree ctx = CP_DECL_CONTEXT (op);
+ if (TYPE_P (ctx) && dependent_type_p (ctx))
+ return true;
+ }
+
+ return false;
+}
+
+/* The next set of functions are used for providing helpful explanatory
+ diagnostics for failed overload resolution. Their messages should be
+ indented by two spaces for consistency with the messages in
+ call.c */
+
+static int
+unify_success (bool /*explain_p*/)
+{
+ return 0;
+}
+
+static int
+unify_parameter_deduction_failure (bool explain_p, tree parm)
+{
+ if (explain_p)
+ inform (input_location,
+ " couldn't deduce template parameter %qD", parm);
+ return 1;
+}
+
+static int
+unify_invalid (bool /*explain_p*/)
+{
+ return 1;
+}
+
+static int
+unify_cv_qual_mismatch (bool explain_p, tree parm, tree arg)
+{
+ if (explain_p)
+ inform (input_location,
+ " types %qT and %qT have incompatible cv-qualifiers",
+ parm, arg);
+ return 1;
+}
+
+static int
+unify_type_mismatch (bool explain_p, tree parm, tree arg)
+{
+ if (explain_p)
+ inform (input_location, " mismatched types %qT and %qT", parm, arg);
+ return 1;
+}
+
+static int
+unify_parameter_pack_mismatch (bool explain_p, tree parm, tree arg)
+{
+ if (explain_p)
+ inform (input_location,
+ " template parameter %qD is not a parameter pack, but "
+ "argument %qD is",
+ parm, arg);
+ return 1;
+}
+
+static int
+unify_ptrmem_cst_mismatch (bool explain_p, tree parm, tree arg)
+{
+ if (explain_p)
+ inform (input_location,
+ " template argument %qE does not match "
+ "pointer-to-member constant %qE",
+ arg, parm);
+ return 1;
+}
+
+static int
+unify_expression_unequal (bool explain_p, tree parm, tree arg)
+{
+ if (explain_p)
+ inform (input_location, " %qE is not equivalent to %qE", parm, arg);
+ return 1;
+}
+
+static int
+unify_parameter_pack_inconsistent (bool explain_p, tree old_arg, tree new_arg)
+{
+ if (explain_p)
+ inform (input_location,
+ " inconsistent parameter pack deduction with %qT and %qT",
+ old_arg, new_arg);
+ return 1;
+}
+
+static int
+unify_inconsistency (bool explain_p, tree parm, tree first, tree second)
+{
+ if (explain_p)
+ {
+ if (TYPE_P (parm))
+ inform (input_location,
+ " deduced conflicting types for parameter %qT (%qT and %qT)",
+ parm, first, second);
+ else
+ inform (input_location,
+ " deduced conflicting values for non-type parameter "
+ "%qE (%qE and %qE)", parm, first, second);
+ }
+ return 1;
+}
+
+static int
+unify_vla_arg (bool explain_p, tree arg)
+{
+ if (explain_p)
+ inform (input_location,
+ " variable-sized array type %qT is not "
+ "a valid template argument",
+ arg);
+ return 1;
+}
+
+static int
+unify_method_type_error (bool explain_p, tree arg)
+{
+ if (explain_p)
+ inform (input_location,
+ " member function type %qT is not a valid template argument",
+ arg);
+ return 1;
+}
+
+static int
+unify_arity (bool explain_p, int have, int wanted)
+{
+ if (explain_p)
+ inform_n (input_location, wanted,
+ " candidate expects %d argument, %d provided",
+ " candidate expects %d arguments, %d provided",
+ wanted, have);
+ return 1;
+}
+
+static int
+unify_too_many_arguments (bool explain_p, int have, int wanted)
+{
+ return unify_arity (explain_p, have, wanted);
+}
+
+static int
+unify_too_few_arguments (bool explain_p, int have, int wanted)
+{
+ return unify_arity (explain_p, have, wanted);
+}
+
+static int
+unify_arg_conversion (bool explain_p, tree to_type,
+ tree from_type, tree arg)
+{
+ if (explain_p)
+ inform (EXPR_LOC_OR_LOC (arg, input_location),
+ " cannot convert %qE (type %qT) to type %qT",
+ arg, from_type, to_type);
+ return 1;
+}
+
+static int
+unify_no_common_base (bool explain_p, enum template_base_result r,
+ tree parm, tree arg)
+{
+ if (explain_p)
+ switch (r)
+ {
+ case tbr_ambiguous_baseclass:
+ inform (input_location, " %qT is an ambiguous base class of %qT",
+ parm, arg);
+ break;
+ default:
+ inform (input_location, " %qT is not derived from %qT", arg, parm);
+ break;
+ }
+ return 1;
+}
+
+static int
+unify_inconsistent_template_template_parameters (bool explain_p)
+{
+ if (explain_p)
+ inform (input_location,
+ " template parameters of a template template argument are "
+ "inconsistent with other deduced template arguments");
+ return 1;
+}
+
+static int
+unify_template_deduction_failure (bool explain_p, tree parm, tree arg)
+{
+ if (explain_p)
+ inform (input_location,
+ " can't deduce a template for %qT from non-template type %qT",
+ parm, arg);
+ return 1;
+}
+
+static int
+unify_template_argument_mismatch (bool explain_p, tree parm, tree arg)
+{
+ if (explain_p)
+ inform (input_location,
+ " template argument %qE does not match %qD", arg, parm);
+ return 1;
+}
+
+static int
+unify_overload_resolution_failure (bool explain_p, tree arg)
+{
+ if (explain_p)
+ inform (input_location,
+ " could not resolve address from overloaded function %qE",
+ arg);
+ return 1;
+}
+
+/* Attempt to convert the non-type template parameter EXPR to the
+ indicated TYPE. If the conversion is successful, return the
+ converted value. If the conversion is unsuccessful, return
+ NULL_TREE if we issued an error message, or error_mark_node if we
+ did not. We issue error messages for out-and-out bad template
+ parameters, but not simply because the conversion failed, since we
+ might be just trying to do argument deduction. Both TYPE and EXPR
+ must be non-dependent.
+
+ The conversion follows the special rules described in
+ [temp.arg.nontype], and it is much more strict than an implicit
+ conversion.
+
+ This function is called twice for each template argument (see
+ lookup_template_class for a more accurate description of this
+ problem). This means that we need to handle expressions which
+ are not valid in a C++ source, but can be created from the
+ first call (for instance, casts to perform conversions). These
+ hacks can go away after we fix the double coercion problem. */
+
+static tree
+convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
+{
+ tree expr_type;
+
+ /* Detect immediately string literals as invalid non-type argument.
+ This special-case is not needed for correctness (we would easily
+ catch this later), but only to provide better diagnostic for this
+ common user mistake. As suggested by DR 100, we do not mention
+ linkage issues in the diagnostic as this is not the point. */
+ /* FIXME we're making this OK. */
+ if (TREE_CODE (expr) == STRING_CST)
+ {
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument for type %qT "
+ "because string literals can never be used in this context",
+ expr, type);
+ return NULL_TREE;
+ }
+
+ /* Add the ADDR_EXPR now for the benefit of
+ value_dependent_expression_p. */
+ if (TYPE_PTROBV_P (type)
+ && TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE)
+ {
+ expr = decay_conversion (expr, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+ }
+
+ /* If we are in a template, EXPR may be non-dependent, but still
+ have a syntactic, rather than semantic, form. For example, EXPR
+ might be a SCOPE_REF, rather than the VAR_DECL to which the
+ SCOPE_REF refers. Preserving the qualifying scope is necessary
+ so that access checking can be performed when the template is
+ instantiated -- but here we need the resolved form so that we can
+ convert the argument. */
+ if (TYPE_REF_OBJ_P (type)
+ && has_value_dependent_address (expr))
+ /* If we want the address and it's value-dependent, don't fold. */;
+ else if (!type_unknown_p (expr))
+ expr = fold_non_dependent_expr_sfinae (expr, complain);
+ if (error_operand_p (expr))
+ return error_mark_node;
+ expr_type = TREE_TYPE (expr);
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ expr = mark_lvalue_use (expr);
+ else
+ expr = mark_rvalue_use (expr);
+
+ /* 14.3.2/5: The null pointer{,-to-member} conversion is applied
+ to a non-type argument of "nullptr". */
+ if (expr == nullptr_node && TYPE_PTR_OR_PTRMEM_P (type))
+ expr = convert (type, expr);
+
+ /* In C++11, integral or enumeration non-type template arguments can be
+ arbitrary constant expressions. Pointer and pointer to
+ member arguments can be general constant expressions that evaluate
+ to a null value, but otherwise still need to be of a specific form. */
+ if (cxx_dialect >= cxx11)
+ {
+ if (TREE_CODE (expr) == PTRMEM_CST)
+ /* A PTRMEM_CST is already constant, and a valid template
+ argument for a parameter of pointer to member type, we just want
+ to leave it in that form rather than lower it to a
+ CONSTRUCTOR. */;
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ expr = maybe_constant_value (expr);
+ else if (TYPE_PTR_OR_PTRMEM_P (type))
+ {
+ tree folded = maybe_constant_value (expr);
+ if (TYPE_PTR_P (type) ? integer_zerop (folded)
+ : null_member_pointer_value_p (folded))
+ expr = folded;
+ }
+ }
+
+ /* HACK: Due to double coercion, we can get a
+ NOP_EXPR<REFERENCE_TYPE>(ADDR_EXPR<POINTER_TYPE> (arg)) here,
+ which is the tree that we built on the first call (see
+ below when coercing to reference to object or to reference to
+ function). We just strip everything and get to the arg.
+ See g++.old-deja/g++.oliva/template4.C and g++.dg/template/nontype9.C
+ for examples. */
+ if (TYPE_REF_OBJ_P (type) || TYPE_REFFN_P (type))
+ {
+ tree probe_type, probe = expr;
+ if (REFERENCE_REF_P (probe))
+ probe = TREE_OPERAND (probe, 0);
+ probe_type = TREE_TYPE (probe);
+ if (TREE_CODE (probe) == NOP_EXPR)
+ {
+ /* ??? Maybe we could use convert_from_reference here, but we
+ would need to relax its constraints because the NOP_EXPR
+ could actually change the type to something more cv-qualified,
+ and this is not folded by convert_from_reference. */
+ tree addr = TREE_OPERAND (probe, 0);
+ if (TREE_CODE (probe_type) == REFERENCE_TYPE
+ && TREE_CODE (addr) == ADDR_EXPR
+ && TYPE_PTR_P (TREE_TYPE (addr))
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (probe_type),
+ TREE_TYPE (TREE_TYPE (addr)))))
+ {
+ expr = TREE_OPERAND (addr, 0);
+ expr_type = TREE_TYPE (probe_type);
+ }
+ }
+ }
+
+ /* We could also generate a NOP_EXPR(ADDR_EXPR()) when the
+ parameter is a pointer to object, through decay and
+ qualification conversion. Let's strip everything. */
+ else if (TREE_CODE (expr) == NOP_EXPR && TYPE_PTROBV_P (type))
+ {
+ tree probe = expr;
+ STRIP_NOPS (probe);
+ if (TREE_CODE (probe) == ADDR_EXPR
+ && TYPE_PTR_P (TREE_TYPE (probe)))
+ {
+ /* Skip the ADDR_EXPR only if it is part of the decay for
+ an array. Otherwise, it is part of the original argument
+ in the source code. */
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (probe, 0))) == ARRAY_TYPE)
+ probe = TREE_OPERAND (probe, 0);
+ expr = probe;
+ expr_type = TREE_TYPE (expr);
+ }
+ }
+
+ /* [temp.arg.nontype]/5, bullet 1
+
+ For a non-type template-parameter of integral or enumeration type,
+ integral promotions (_conv.prom_) and integral conversions
+ (_conv.integral_) are applied. */
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ {
+ tree t = build_integral_nontype_arg_conv (type, expr, complain);
+ t = maybe_constant_value (t);
+ if (t != error_mark_node)
+ expr = t;
+
+ if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (expr)))
+ return error_mark_node;
+
+ /* Notice that there are constant expressions like '4 % 0' which
+ do not fold into integer constants. */
+ if (TREE_CODE (expr) != INTEGER_CST)
+ {
+ if (complain & tf_error)
+ {
+ int errs = errorcount, warns = warningcount + werrorcount;
+ if (processing_template_decl
+ && !require_potential_constant_expression (expr))
+ return NULL_TREE;
+ expr = cxx_constant_value (expr);
+ if (errorcount > errs || warningcount + werrorcount > warns)
+ inform (EXPR_LOC_OR_LOC (expr, input_location),
+ "in template argument for type %qT ", type);
+ if (expr == error_mark_node)
+ return NULL_TREE;
+ /* else cxx_constant_value complained but gave us
+ a real constant, so go ahead. */
+ gcc_assert (TREE_CODE (expr) == INTEGER_CST);
+ }
+ else
+ return NULL_TREE;
+ }
+
+ /* Avoid typedef problems. */
+ if (TREE_TYPE (expr) != type)
+ expr = fold_convert (type, expr);
+ }
+ /* [temp.arg.nontype]/5, bullet 2
+
+ For a non-type template-parameter of type pointer to object,
+ qualification conversions (_conv.qual_) and the array-to-pointer
+ conversion (_conv.array_) are applied. */
+ else if (TYPE_PTROBV_P (type))
+ {
+ /* [temp.arg.nontype]/1 (TC1 version, DR 49):
+
+ A template-argument for a non-type, non-template template-parameter
+ shall be one of: [...]
+
+ -- the name of a non-type template-parameter;
+ -- the address of an object or function with external linkage, [...]
+ expressed as "& id-expression" where the & is optional if the name
+ refers to a function or array, or if the corresponding
+ template-parameter is a reference.
+
+ Here, we do not care about functions, as they are invalid anyway
+ for a parameter of type pointer-to-object. */
+
+ if (DECL_P (expr) && DECL_TEMPLATE_PARM_P (expr))
+ /* Non-type template parameters are OK. */
+ ;
+ else if (cxx_dialect >= cxx11 && integer_zerop (expr))
+ /* Null pointer values are OK in C++11. */;
+ else if (TREE_CODE (expr) != ADDR_EXPR
+ && TREE_CODE (expr_type) != ARRAY_TYPE)
+ {
+ if (VAR_P (expr))
+ {
+ error ("%qD is not a valid template argument "
+ "because %qD is a variable, not the address of "
+ "a variable",
+ expr, expr);
+ return NULL_TREE;
+ }
+ if (POINTER_TYPE_P (expr_type))
+ {
+ error ("%qE is not a valid template argument for %qT "
+ "because it is not the address of a variable",
+ expr, type);
+ return NULL_TREE;
+ }
+ /* Other values, like integer constants, might be valid
+ non-type arguments of some other type. */
+ return error_mark_node;
+ }
+ else
+ {
+ tree decl;
+
+ decl = ((TREE_CODE (expr) == ADDR_EXPR)
+ ? TREE_OPERAND (expr, 0) : expr);
+ if (!VAR_P (decl))
+ {
+ error ("%qE is not a valid template argument of type %qT "
+ "because %qE is not a variable",
+ expr, type, decl);
+ return NULL_TREE;
+ }
+ else if (cxx_dialect < cxx11 && !DECL_EXTERNAL_LINKAGE_P (decl))
+ {
+ error ("%qE is not a valid template argument of type %qT "
+ "because %qD does not have external linkage",
+ expr, type, decl);
+ return NULL_TREE;
+ }
+ else if (cxx_dialect >= cxx11 && decl_linkage (decl) == lk_none)
+ {
+ error ("%qE is not a valid template argument of type %qT "
+ "because %qD has no linkage",
+ expr, type, decl);
+ return NULL_TREE;
+ }
+ }
+
+ expr = decay_conversion (expr, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ expr = perform_qualification_conversions (type, expr);
+ if (expr == error_mark_node)
+ return error_mark_node;
+ }
+ /* [temp.arg.nontype]/5, bullet 3
+
+ For a non-type template-parameter of type reference to object, no
+ conversions apply. The type referred to by the reference may be more
+ cv-qualified than the (otherwise identical) type of the
+ template-argument. The template-parameter is bound directly to the
+ template-argument, which must be an lvalue. */
+ else if (TYPE_REF_OBJ_P (type))
+ {
+ if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type),
+ expr_type))
+ return error_mark_node;
+
+ if (!at_least_as_qualified_p (TREE_TYPE (type), expr_type))
+ {
+ error ("%qE is not a valid template argument for type %qT "
+ "because of conflicts in cv-qualification", expr, type);
+ return NULL_TREE;
+ }
+
+ if (!real_lvalue_p (expr))
+ {
+ error ("%qE is not a valid template argument for type %qT "
+ "because it is not an lvalue", expr, type);
+ return NULL_TREE;
+ }
+
+ /* [temp.arg.nontype]/1
+
+ A template-argument for a non-type, non-template template-parameter
+ shall be one of: [...]
+
+ -- the address of an object or function with external linkage. */
+ if (INDIRECT_REF_P (expr)
+ && TYPE_REF_OBJ_P (TREE_TYPE (TREE_OPERAND (expr, 0))))
+ {
+ expr = TREE_OPERAND (expr, 0);
+ if (DECL_P (expr))
+ {
+ error ("%q#D is not a valid template argument for type %qT "
+ "because a reference variable does not have a constant "
+ "address", expr, type);
+ return NULL_TREE;
+ }
+ }
+
+ if (!DECL_P (expr))
+ {
+ error ("%qE is not a valid template argument for type %qT "
+ "because it is not an object with external linkage",
+ expr, type);
+ return NULL_TREE;
+ }
+
+ if (!DECL_EXTERNAL_LINKAGE_P (expr))
+ {
+ error ("%qE is not a valid template argument for type %qT "
+ "because object %qD has not external linkage",
+ expr, type, expr);
+ return NULL_TREE;
+ }
+
+ expr = build_nop (type, build_address (expr));
+ }
+ /* [temp.arg.nontype]/5, bullet 4
+
+ For a non-type template-parameter of type pointer to function, only
+ the function-to-pointer conversion (_conv.func_) is applied. If the
+ template-argument represents a set of overloaded functions (or a
+ pointer to such), the matching function is selected from the set
+ (_over.over_). */
+ else if (TYPE_PTRFN_P (type))
+ {
+ /* If the argument is a template-id, we might not have enough
+ context information to decay the pointer. */
+ if (!type_unknown_p (expr_type))
+ {
+ expr = decay_conversion (expr, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+ }
+
+ if (cxx_dialect >= cxx11 && integer_zerop (expr))
+ /* Null pointer values are OK in C++11. */
+ return perform_qualification_conversions (type, expr);
+
+ expr = convert_nontype_argument_function (type, expr);
+ if (!expr || expr == error_mark_node)
+ return expr;
+ }
+ /* [temp.arg.nontype]/5, bullet 5
+
+ For a non-type template-parameter of type reference to function, no
+ conversions apply. If the template-argument represents a set of
+ overloaded functions, the matching function is selected from the set
+ (_over.over_). */
+ else if (TYPE_REFFN_P (type))
+ {
+ if (TREE_CODE (expr) == ADDR_EXPR)
+ {
+ error ("%qE is not a valid template argument for type %qT "
+ "because it is a pointer", expr, type);
+ inform (input_location, "try using %qE instead", TREE_OPERAND (expr, 0));
+ return NULL_TREE;
+ }
+
+ expr = convert_nontype_argument_function (type, expr);
+ if (!expr || expr == error_mark_node)
+ return expr;
+
+ expr = build_nop (type, build_address (expr));
+ }
+ /* [temp.arg.nontype]/5, bullet 6
+
+ For a non-type template-parameter of type pointer to member function,
+ no conversions apply. If the template-argument represents a set of
+ overloaded member functions, the matching member function is selected
+ from the set (_over.over_). */
+ else if (TYPE_PTRMEMFUNC_P (type))
+ {
+ expr = instantiate_type (type, expr, tf_none);
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ /* [temp.arg.nontype] bullet 1 says the pointer to member
+ expression must be a pointer-to-member constant. */
+ if (!check_valid_ptrmem_cst_expr (type, expr, complain))
+ return error_mark_node;
+
+ /* There is no way to disable standard conversions in
+ resolve_address_of_overloaded_function (called by
+ instantiate_type). It is possible that the call succeeded by
+ converting &B::I to &D::I (where B is a base of D), so we need
+ to reject this conversion here.
+
+ Actually, even if there was a way to disable standard conversions,
+ it would still be better to reject them here so that we can
+ provide a superior diagnostic. */
+ if (!same_type_p (TREE_TYPE (expr), type))
+ {
+ error ("%qE is not a valid template argument for type %qT "
+ "because it is of type %qT", expr, type,
+ TREE_TYPE (expr));
+ /* If we are just one standard conversion off, explain. */
+ if (can_convert_standard (type, TREE_TYPE (expr), complain))
+ inform (input_location,
+ "standard conversions are not allowed in this context");
+ return NULL_TREE;
+ }
+ }
+ /* [temp.arg.nontype]/5, bullet 7
+
+ For a non-type template-parameter of type pointer to data member,
+ qualification conversions (_conv.qual_) are applied. */
+ else if (TYPE_PTRDATAMEM_P (type))
+ {
+ /* [temp.arg.nontype] bullet 1 says the pointer to member
+ expression must be a pointer-to-member constant. */
+ if (!check_valid_ptrmem_cst_expr (type, expr, complain))
+ return error_mark_node;
+
+ expr = perform_qualification_conversions (type, expr);
+ if (expr == error_mark_node)
+ return expr;
+ }
+ else if (NULLPTR_TYPE_P (type))
+ {
+ if (expr != nullptr_node)
+ {
+ error ("%qE is not a valid template argument for type %qT "
+ "because it is of type %qT", expr, type, TREE_TYPE (expr));
+ return NULL_TREE;
+ }
+ return expr;
+ }
+ /* A template non-type parameter must be one of the above. */
+ else
+ gcc_unreachable ();
+
+ /* Sanity check: did we actually convert the argument to the
+ right type? */
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (expr)));
+ return expr;
+}
+
+/* Subroutine of coerce_template_template_parms, which returns 1 if
+ PARM_PARM and ARG_PARM match using the rule for the template
+ parameters of template template parameters. Both PARM and ARG are
+ template parameters; the rest of the arguments are the same as for
+ coerce_template_template_parms.
+ */
+static int
+coerce_template_template_parm (tree parm,
+ tree arg,
+ tsubst_flags_t complain,
+ tree in_decl,
+ tree outer_args)
+{
+ if (arg == NULL_TREE || arg == error_mark_node
+ || parm == NULL_TREE || parm == error_mark_node)
+ return 0;
+
+ if (TREE_CODE (arg) != TREE_CODE (parm))
+ return 0;
+
+ switch (TREE_CODE (parm))
+ {
+ case TEMPLATE_DECL:
+ /* We encounter instantiations of templates like
+ template <template <template <class> class> class TT>
+ class C; */
+ {
+ tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
+ tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
+
+ if (!coerce_template_template_parms
+ (parmparm, argparm, complain, in_decl, outer_args))
+ return 0;
+ }
+ /* Fall through. */
+
+ case TYPE_DECL:
+ if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (arg))
+ && !TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm)))
+ /* Argument is a parameter pack but parameter is not. */
+ return 0;
+ break;
+
+ case PARM_DECL:
+ /* The tsubst call is used to handle cases such as
+
+ template <int> class C {};
+ template <class T, template <T> class TT> class D {};
+ D<int, C> d;
+
+ i.e. the parameter list of TT depends on earlier parameters. */
+ if (!uses_template_parms (TREE_TYPE (arg))
+ && !same_type_p
+ (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl),
+ TREE_TYPE (arg)))
+ return 0;
+
+ if (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (arg))
+ && !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
+ /* Argument is a parameter pack but parameter is not. */
+ return 0;
+
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return 1;
+}
+
+
+/* Return 1 if PARM_PARMS and ARG_PARMS matches using rule for
+ template template parameters. Both PARM_PARMS and ARG_PARMS are
+ vectors of TREE_LIST nodes containing TYPE_DECL, TEMPLATE_DECL
+ or PARM_DECL.
+
+ Consider the example:
+ template <class T> class A;
+ template<template <class U> class TT> class B;
+
+ For B<A>, PARM_PARMS are the parameters to TT, while ARG_PARMS are
+ the parameters to A, and OUTER_ARGS contains A. */
+
+static int
+coerce_template_template_parms (tree parm_parms,
+ tree arg_parms,
+ tsubst_flags_t complain,
+ tree in_decl,
+ tree outer_args)
+{
+ int nparms, nargs, i;
+ tree parm, arg;
+ int variadic_p = 0;
+
+ gcc_assert (TREE_CODE (parm_parms) == TREE_VEC);
+ gcc_assert (TREE_CODE (arg_parms) == TREE_VEC);
+
+ nparms = TREE_VEC_LENGTH (parm_parms);
+ nargs = TREE_VEC_LENGTH (arg_parms);
+
+ /* Determine whether we have a parameter pack at the end of the
+ template template parameter's template parameter list. */
+ if (TREE_VEC_ELT (parm_parms, nparms - 1) != error_mark_node)
+ {
+ parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, nparms - 1));
+
+ if (parm == error_mark_node)
+ return 0;
+
+ switch (TREE_CODE (parm))
+ {
+ case TEMPLATE_DECL:
+ case TYPE_DECL:
+ if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm)))
+ variadic_p = 1;
+ break;
+
+ case PARM_DECL:
+ if (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
+ variadic_p = 1;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+
+ if (nargs != nparms
+ && !(variadic_p && nargs >= nparms - 1))
+ return 0;
+
+ /* Check all of the template parameters except the parameter pack at
+ the end (if any). */
+ for (i = 0; i < nparms - variadic_p; ++i)
+ {
+ if (TREE_VEC_ELT (parm_parms, i) == error_mark_node
+ || TREE_VEC_ELT (arg_parms, i) == error_mark_node)
+ continue;
+
+ parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i));
+ arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i));
+
+ if (!coerce_template_template_parm (parm, arg, complain, in_decl,
+ outer_args))
+ return 0;
+
+ }
+
+ if (variadic_p)
+ {
+ /* Check each of the template parameters in the template
+ argument against the template parameter pack at the end of
+ the template template parameter. */
+ if (TREE_VEC_ELT (parm_parms, i) == error_mark_node)
+ return 0;
+
+ parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i));
+
+ for (; i < nargs; ++i)
+ {
+ if (TREE_VEC_ELT (arg_parms, i) == error_mark_node)
+ continue;
+
+ arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i));
+
+ if (!coerce_template_template_parm (parm, arg, complain, in_decl,
+ outer_args))
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/* Verifies that the deduced template arguments (in TARGS) for the
+ template template parameters (in TPARMS) represent valid bindings,
+ by comparing the template parameter list of each template argument
+ to the template parameter list of its corresponding template
+ template parameter, in accordance with DR150. This
+ routine can only be called after all template arguments have been
+ deduced. It will return TRUE if all of the template template
+ parameter bindings are okay, FALSE otherwise. */
+bool
+template_template_parm_bindings_ok_p (tree tparms, tree targs)
+{
+ int i, ntparms = TREE_VEC_LENGTH (tparms);
+ bool ret = true;
+
+ /* We're dealing with template parms in this process. */
+ ++processing_template_decl;
+
+ targs = INNERMOST_TEMPLATE_ARGS (targs);
+
+ for (i = 0; i < ntparms; ++i)
+ {
+ tree tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
+ tree targ = TREE_VEC_ELT (targs, i);
+
+ if (TREE_CODE (tparm) == TEMPLATE_DECL && targ)
+ {
+ tree packed_args = NULL_TREE;
+ int idx, len = 1;
+
+ if (ARGUMENT_PACK_P (targ))
+ {
+ /* Look inside the argument pack. */
+ packed_args = ARGUMENT_PACK_ARGS (targ);
+ len = TREE_VEC_LENGTH (packed_args);
+ }
+
+ for (idx = 0; idx < len; ++idx)
+ {
+ tree targ_parms = NULL_TREE;
+
+ if (packed_args)
+ /* Extract the next argument from the argument
+ pack. */
+ targ = TREE_VEC_ELT (packed_args, idx);
+
+ if (PACK_EXPANSION_P (targ))
+ /* Look at the pattern of the pack expansion. */
+ targ = PACK_EXPANSION_PATTERN (targ);
+
+ /* Extract the template parameters from the template
+ argument. */
+ if (TREE_CODE (targ) == TEMPLATE_DECL)
+ targ_parms = DECL_INNERMOST_TEMPLATE_PARMS (targ);
+ else if (TREE_CODE (targ) == TEMPLATE_TEMPLATE_PARM)
+ targ_parms = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_NAME (targ));
+
+ /* Verify that we can coerce the template template
+ parameters from the template argument to the template
+ parameter. This requires an exact match. */
+ if (targ_parms
+ && !coerce_template_template_parms
+ (DECL_INNERMOST_TEMPLATE_PARMS (tparm),
+ targ_parms,
+ tf_none,
+ tparm,
+ targs))
+ {
+ ret = false;
+ goto out;
+ }
+ }
+ }
+ }
+
+ out:
+
+ --processing_template_decl;
+ return ret;
+}
+
+/* Since type attributes aren't mangled, we need to strip them from
+ template type arguments. */
+
+static tree
+canonicalize_type_argument (tree arg, tsubst_flags_t complain)
+{
+ tree mv;
+ if (!arg || arg == error_mark_node || arg == TYPE_CANONICAL (arg))
+ return arg;
+ mv = TYPE_MAIN_VARIANT (arg);
+ arg = strip_typedefs (arg);
+ if (TYPE_ALIGN (arg) != TYPE_ALIGN (mv)
+ || TYPE_ATTRIBUTES (arg) != TYPE_ATTRIBUTES (mv))
+ {
+ if (complain & tf_warning)
+ warning (0, "ignoring attributes on template argument %qT", arg);
+ arg = build_aligned_type (arg, TYPE_ALIGN (mv));
+ arg = cp_build_type_attribute_variant (arg, TYPE_ATTRIBUTES (mv));
+ }
+ return arg;
+}
+
+/* Convert the indicated template ARG as necessary to match the
+ indicated template PARM. Returns the converted ARG, or
+ error_mark_node if the conversion was unsuccessful. Error and
+ warning messages are issued under control of COMPLAIN. This
+ conversion is for the Ith parameter in the parameter list. ARGS is
+ the full set of template arguments deduced so far. */
+
+static tree
+convert_template_argument (tree parm,
+ tree arg,
+ tree args,
+ tsubst_flags_t complain,
+ int i,
+ tree in_decl)
+{
+ tree orig_arg;
+ tree val;
+ int is_type, requires_type, is_tmpl_type, requires_tmpl_type;
+
+ if (TREE_CODE (arg) == TREE_LIST
+ && TREE_CODE (TREE_VALUE (arg)) == OFFSET_REF)
+ {
+ /* The template argument was the name of some
+ member function. That's usually
+ invalid, but static members are OK. In any
+ case, grab the underlying fields/functions
+ and issue an error later if required. */
+ orig_arg = TREE_VALUE (arg);
+ TREE_TYPE (arg) = unknown_type_node;
+ }
+
+ orig_arg = arg;
+
+ requires_tmpl_type = TREE_CODE (parm) == TEMPLATE_DECL;
+ requires_type = (TREE_CODE (parm) == TYPE_DECL
+ || requires_tmpl_type);
+
+ /* When determining whether an argument pack expansion is a template,
+ look at the pattern. */
+ if (TREE_CODE (arg) == TYPE_PACK_EXPANSION)
+ arg = PACK_EXPANSION_PATTERN (arg);
+
+ /* Deal with an injected-class-name used as a template template arg. */
+ if (requires_tmpl_type && CLASS_TYPE_P (arg))
+ {
+ tree t = maybe_get_template_decl_from_type_decl (TYPE_NAME (arg));
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ {
+ if (cxx_dialect >= cxx11)
+ /* OK under DR 1004. */;
+ else if (complain & tf_warning_or_error)
+ pedwarn (input_location, OPT_Wpedantic, "injected-class-name %qD"
+ " used as template template argument", TYPE_NAME (arg));
+ else if (flag_pedantic_errors)
+ t = arg;
+
+ arg = t;
+ }
+ }
+
+ is_tmpl_type =
+ ((TREE_CODE (arg) == TEMPLATE_DECL
+ && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
+ || (requires_tmpl_type && TREE_CODE (arg) == TYPE_ARGUMENT_PACK)
+ || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
+
+ if (is_tmpl_type
+ && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE))
+ arg = TYPE_STUB_DECL (arg);
+
+ is_type = TYPE_P (arg) || is_tmpl_type;
+
+ if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
+ && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
+ {
+ if (TREE_CODE (TREE_OPERAND (arg, 1)) == BIT_NOT_EXPR)
+ {
+ if (complain & tf_error)
+ error ("invalid use of destructor %qE as a type", orig_arg);
+ return error_mark_node;
+ }
+
+ permerror (input_location,
+ "to refer to a type member of a template parameter, "
+ "use %<typename %E%>", orig_arg);
+
+ orig_arg = make_typename_type (TREE_OPERAND (arg, 0),
+ TREE_OPERAND (arg, 1),
+ typename_type,
+ complain);
+ arg = orig_arg;
+ is_type = 1;
+ }
+ if (is_type != requires_type)
+ {
+ if (in_decl)
+ {
+ if (complain & tf_error)
+ {
+ error ("type/value mismatch at argument %d in template "
+ "parameter list for %qD",
+ i + 1, in_decl);
+ if (is_type)
+ error (" expected a constant of type %qT, got %qT",
+ TREE_TYPE (parm),
+ (DECL_P (arg) ? DECL_NAME (arg) : orig_arg));
+ else if (requires_tmpl_type)
+ error (" expected a class template, got %qE", orig_arg);
+ else
+ error (" expected a type, got %qE", orig_arg);
+ }
+ }
+ return error_mark_node;
+ }
+ if (is_tmpl_type ^ requires_tmpl_type)
+ {
+ if (in_decl && (complain & tf_error))
+ {
+ error ("type/value mismatch at argument %d in template "
+ "parameter list for %qD",
+ i + 1, in_decl);
+ if (is_tmpl_type)
+ error (" expected a type, got %qT", DECL_NAME (arg));
+ else
+ error (" expected a class template, got %qT", orig_arg);
+ }
+ return error_mark_node;
+ }
+
+ if (is_type)
+ {
+ if (requires_tmpl_type)
+ {
+ if (template_parameter_pack_p (parm) && ARGUMENT_PACK_P (orig_arg))
+ val = orig_arg;
+ else if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE)
+ /* The number of argument required is not known yet.
+ Just accept it for now. */
+ val = TREE_TYPE (arg);
+ else
+ {
+ tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
+ tree argparm;
+
+ /* Strip alias templates that are equivalent to another
+ template. */
+ arg = get_underlying_template (arg);
+ argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
+
+ if (coerce_template_template_parms (parmparm, argparm,
+ complain, in_decl,
+ args))
+ {
+ val = arg;
+
+ /* TEMPLATE_TEMPLATE_PARM node is preferred over
+ TEMPLATE_DECL. */
+ if (val != error_mark_node)
+ {
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (val))
+ val = TREE_TYPE (val);
+ if (TREE_CODE (orig_arg) == TYPE_PACK_EXPANSION)
+ val = make_pack_expansion (val);
+ }
+ }
+ else
+ {
+ if (in_decl && (complain & tf_error))
+ {
+ error ("type/value mismatch at argument %d in "
+ "template parameter list for %qD",
+ i + 1, in_decl);
+ error (" expected a template of type %qD, got %qT",
+ parm, orig_arg);
+ }
+
+ val = error_mark_node;
+ }
+ }
+ }
+ else
+ val = orig_arg;
+ /* We only form one instance of each template specialization.
+ Therefore, if we use a non-canonical variant (i.e., a
+ typedef), any future messages referring to the type will use
+ the typedef, which is confusing if those future uses do not
+ themselves also use the typedef. */
+ if (TYPE_P (val))
+ val = canonicalize_type_argument (val, complain);
+ }
+ else
+ {
+ tree t = tsubst (TREE_TYPE (parm), args, complain, in_decl);
+
+ if (invalid_nontype_parm_type_p (t, complain))
+ return error_mark_node;
+
+ if (template_parameter_pack_p (parm) && ARGUMENT_PACK_P (orig_arg))
+ {
+ if (same_type_p (t, TREE_TYPE (orig_arg)))
+ val = orig_arg;
+ else
+ {
+ /* Not sure if this is reachable, but it doesn't hurt
+ to be robust. */
+ error ("type mismatch in nontype parameter pack");
+ val = error_mark_node;
+ }
+ }
+ else if (!dependent_template_arg_p (orig_arg)
+ && !uses_template_parms (t))
+ /* We used to call digest_init here. However, digest_init
+ will report errors, which we don't want when complain
+ is zero. More importantly, digest_init will try too
+ hard to convert things: for example, `0' should not be
+ converted to pointer type at this point according to
+ the standard. Accepting this is not merely an
+ extension, since deciding whether or not these
+ conversions can occur is part of determining which
+ function template to call, or whether a given explicit
+ argument specification is valid. */
+ val = convert_nontype_argument (t, orig_arg, complain);
+ else
+ val = strip_typedefs_expr (orig_arg);
+
+ if (val == NULL_TREE)
+ val = error_mark_node;
+ else if (val == error_mark_node && (complain & tf_error))
+ error ("could not convert template argument %qE to %qT", orig_arg, t);
+
+ if (TREE_CODE (val) == SCOPE_REF)
+ {
+ /* Strip typedefs from the SCOPE_REF. */
+ tree type = canonicalize_type_argument (TREE_TYPE (val), complain);
+ tree scope = canonicalize_type_argument (TREE_OPERAND (val, 0),
+ complain);
+ val = build_qualified_name (type, scope, TREE_OPERAND (val, 1),
+ QUALIFIED_NAME_IS_TEMPLATE (val));
+ }
+ }
+
+ return val;
+}
+
+/* Coerces the remaining template arguments in INNER_ARGS (from
+ ARG_IDX to the end) into the parameter pack at PARM_IDX in PARMS.
+ Returns the coerced argument pack. PARM_IDX is the position of this
+ parameter in the template parameter list. ARGS is the original
+ template argument list. */
+static tree
+coerce_template_parameter_pack (tree parms,
+ int parm_idx,
+ tree args,
+ tree inner_args,
+ int arg_idx,
+ tree new_args,
+ int* lost,
+ tree in_decl,
+ tsubst_flags_t complain)
+{
+ tree parm = TREE_VEC_ELT (parms, parm_idx);
+ int nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
+ tree packed_args;
+ tree argument_pack;
+ tree packed_parms = NULL_TREE;
+
+ if (arg_idx > nargs)
+ arg_idx = nargs;
+
+ if (tree packs = fixed_parameter_pack_p (TREE_VALUE (parm)))
+ {
+ /* When the template parameter is a non-type template parameter pack
+ or template template parameter pack whose type or template
+ parameters use parameter packs, we know exactly how many arguments
+ we are looking for. Build a vector of the instantiated decls for
+ these template parameters in PACKED_PARMS. */
+ /* We can't use make_pack_expansion here because it would interpret a
+ _DECL as a use rather than a declaration. */
+ tree decl = TREE_VALUE (parm);
+ tree exp = cxx_make_type (TYPE_PACK_EXPANSION);
+ SET_PACK_EXPANSION_PATTERN (exp, decl);
+ PACK_EXPANSION_PARAMETER_PACKS (exp) = packs;
+ SET_TYPE_STRUCTURAL_EQUALITY (exp);
+
+ TREE_VEC_LENGTH (args)--;
+ packed_parms = tsubst_pack_expansion (exp, args, complain, decl);
+ TREE_VEC_LENGTH (args)++;
+
+ if (packed_parms == error_mark_node)
+ return error_mark_node;
+
+ /* If we're doing a partial instantiation of a member template,
+ verify that all of the types used for the non-type
+ template parameter pack are, in fact, valid for non-type
+ template parameters. */
+ if (arg_idx < nargs
+ && PACK_EXPANSION_P (TREE_VEC_ELT (inner_args, arg_idx)))
+ {
+ int j, len = TREE_VEC_LENGTH (packed_parms);
+ for (j = 0; j < len; ++j)
+ {
+ tree t = TREE_TYPE (TREE_VEC_ELT (packed_parms, j));
+ if (invalid_nontype_parm_type_p (t, complain))
+ return error_mark_node;
+ }
+ }
+
+ packed_args = make_tree_vec (TREE_VEC_LENGTH (packed_parms));
+ }
+ else
+ packed_args = make_tree_vec (nargs - arg_idx);
+
+ /* Convert the remaining arguments, which will be a part of the
+ parameter pack "parm". */
+ for (; arg_idx < nargs; ++arg_idx)
+ {
+ tree arg = TREE_VEC_ELT (inner_args, arg_idx);
+ tree actual_parm = TREE_VALUE (parm);
+ int pack_idx = arg_idx - parm_idx;
+
+ if (packed_parms)
+ {
+ /* Once we've packed as many args as we have types, stop. */
+ if (pack_idx >= TREE_VEC_LENGTH (packed_parms))
+ break;
+ else if (PACK_EXPANSION_P (arg))
+ /* We don't know how many args we have yet, just
+ use the unconverted ones for now. */
+ return NULL_TREE;
+ else
+ actual_parm = TREE_VEC_ELT (packed_parms, pack_idx);
+ }
+
+ if (arg == error_mark_node)
+ {
+ if (complain & tf_error)
+ error ("template argument %d is invalid", arg_idx + 1);
+ }
+ else
+ arg = convert_template_argument (actual_parm,
+ arg, new_args, complain, parm_idx,
+ in_decl);
+ if (arg == error_mark_node)
+ (*lost)++;
+ TREE_VEC_ELT (packed_args, pack_idx) = arg;
+ }
+
+ if (arg_idx - parm_idx < TREE_VEC_LENGTH (packed_args)
+ && TREE_VEC_LENGTH (packed_args) > 0)
+ {
+ error ("wrong number of template arguments (%d, should be %d)",
+ arg_idx - parm_idx, TREE_VEC_LENGTH (packed_args));
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL
+ || TREE_CODE (TREE_VALUE (parm)) == TEMPLATE_DECL)
+ argument_pack = cxx_make_type (TYPE_ARGUMENT_PACK);
+ else
+ {
+ argument_pack = make_node (NONTYPE_ARGUMENT_PACK);
+ TREE_TYPE (argument_pack)
+ = tsubst (TREE_TYPE (TREE_VALUE (parm)), new_args, complain, in_decl);
+ TREE_CONSTANT (argument_pack) = 1;
+ }
+
+ SET_ARGUMENT_PACK_ARGS (argument_pack, packed_args);
+#ifdef ENABLE_CHECKING
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (packed_args,
+ TREE_VEC_LENGTH (packed_args));
+#endif
+ return argument_pack;
+}
+
+/* Returns the number of pack expansions in the template argument vector
+ ARGS. */
+
+static int
+pack_expansion_args_count (tree args)
+{
+ int i;
+ int count = 0;
+ if (args)
+ for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
+ {
+ tree elt = TREE_VEC_ELT (args, i);
+ if (elt && PACK_EXPANSION_P (elt))
+ ++count;
+ }
+ return count;
+}
+
+/* Convert all template arguments to their appropriate types, and
+ return a vector containing the innermost resulting template
+ arguments. If any error occurs, return error_mark_node. Error and
+ warning messages are issued under control of COMPLAIN.
+
+ If REQUIRE_ALL_ARGS is false, argument deduction will be performed
+ for arguments not specified in ARGS. Otherwise, if
+ USE_DEFAULT_ARGS is true, default arguments will be used to fill in
+ unspecified arguments. If REQUIRE_ALL_ARGS is true, but
+ USE_DEFAULT_ARGS is false, then all arguments must be specified in
+ ARGS. */
+
+static tree
+coerce_template_parms (tree parms,
+ tree args,
+ tree in_decl,
+ tsubst_flags_t complain,
+ bool require_all_args,
+ bool use_default_args)
+{
+ int nparms, nargs, parm_idx, arg_idx, lost = 0;
+ tree orig_inner_args;
+ tree inner_args;
+ tree new_args;
+ tree new_inner_args;
+ int saved_unevaluated_operand;
+ int saved_inhibit_evaluation_warnings;
+
+ /* When used as a boolean value, indicates whether this is a
+ variadic template parameter list. Since it's an int, we can also
+ subtract it from nparms to get the number of non-variadic
+ parameters. */
+ int variadic_p = 0;
+ int variadic_args_p = 0;
+ int post_variadic_parms = 0;
+
+ if (args == error_mark_node)
+ return error_mark_node;
+
+ nparms = TREE_VEC_LENGTH (parms);
+
+ /* Determine if there are any parameter packs. */
+ for (parm_idx = 0; parm_idx < nparms; ++parm_idx)
+ {
+ tree tparm = TREE_VALUE (TREE_VEC_ELT (parms, parm_idx));
+ if (variadic_p)
+ ++post_variadic_parms;
+ if (template_parameter_pack_p (tparm))
+ ++variadic_p;
+ }
+
+ inner_args = orig_inner_args = INNERMOST_TEMPLATE_ARGS (args);
+ /* If there are no parameters that follow a parameter pack, we need to
+ expand any argument packs so that we can deduce a parameter pack from
+ some non-packed args followed by an argument pack, as in variadic85.C.
+ If there are such parameters, we need to leave argument packs intact
+ so the arguments are assigned properly. This can happen when dealing
+ with a nested class inside a partial specialization of a class
+ template, as in variadic92.C, or when deducing a template parameter pack
+ from a sub-declarator, as in variadic114.C. */
+ if (!post_variadic_parms)
+ inner_args = expand_template_argument_pack (inner_args);
+
+ /* Count any pack expansion args. */
+ variadic_args_p = pack_expansion_args_count (inner_args);
+
+ nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
+ if ((nargs > nparms && !variadic_p)
+ || (nargs < nparms - variadic_p
+ && require_all_args
+ && !variadic_args_p
+ && (!use_default_args
+ || (TREE_VEC_ELT (parms, nargs) != error_mark_node
+ && !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))))
+ {
+ if (complain & tf_error)
+ {
+ if (variadic_p)
+ {
+ nparms -= variadic_p;
+ error ("wrong number of template arguments "
+ "(%d, should be %d or more)", nargs, nparms);
+ }
+ else
+ error ("wrong number of template arguments "
+ "(%d, should be %d)", nargs, nparms);
+
+ if (in_decl)
+ error ("provided for %q+D", in_decl);
+ }
+
+ return error_mark_node;
+ }
+ /* We can't pass a pack expansion to a non-pack parameter of an alias
+ template (DR 1430). */
+ else if (in_decl && DECL_ALIAS_TEMPLATE_P (in_decl)
+ && variadic_args_p
+ && nargs - variadic_args_p < nparms - variadic_p)
+ {
+ if (complain & tf_error)
+ {
+ for (int i = 0; i < TREE_VEC_LENGTH (inner_args); ++i)
+ {
+ tree arg = TREE_VEC_ELT (inner_args, i);
+ tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+
+ if (PACK_EXPANSION_P (arg)
+ && !template_parameter_pack_p (parm))
+ {
+ error ("pack expansion argument for non-pack parameter "
+ "%qD of alias template %qD", parm, in_decl);
+ inform (DECL_SOURCE_LOCATION (parm), "declared here");
+ goto found;
+ }
+ }
+ gcc_unreachable ();
+ found:;
+ }
+ return error_mark_node;
+ }
+
+ /* We need to evaluate the template arguments, even though this
+ template-id may be nested within a "sizeof". */
+ saved_unevaluated_operand = cp_unevaluated_operand;
+ cp_unevaluated_operand = 0;
+ saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+ c_inhibit_evaluation_warnings = 0;
+ new_inner_args = make_tree_vec (nparms);
+ new_args = add_outermost_template_args (args, new_inner_args);
+ int pack_adjust = 0;
+ for (parm_idx = 0, arg_idx = 0; parm_idx < nparms; parm_idx++, arg_idx++)
+ {
+ tree arg;
+ tree parm;
+
+ /* Get the Ith template parameter. */
+ parm = TREE_VEC_ELT (parms, parm_idx);
+
+ if (parm == error_mark_node)
+ {
+ TREE_VEC_ELT (new_inner_args, arg_idx) = error_mark_node;
+ continue;
+ }
+
+ /* Calculate the next argument. */
+ if (arg_idx < nargs)
+ arg = TREE_VEC_ELT (inner_args, arg_idx);
+ else
+ arg = NULL_TREE;
+
+ if (template_parameter_pack_p (TREE_VALUE (parm))
+ && !(arg && ARGUMENT_PACK_P (arg)))
+ {
+ /* Some arguments will be placed in the
+ template parameter pack PARM. */
+ arg = coerce_template_parameter_pack (parms, parm_idx, args,
+ inner_args, arg_idx,
+ new_args, &lost,
+ in_decl, complain);
+
+ if (arg == NULL_TREE)
+ {
+ /* We don't know how many args we have yet, just use the
+ unconverted (and still packed) ones for now. */
+ new_inner_args = orig_inner_args;
+ arg_idx = nargs;
+ break;
+ }
+
+ TREE_VEC_ELT (new_inner_args, parm_idx) = arg;
+
+ /* Store this argument. */
+ if (arg == error_mark_node)
+ {
+ lost++;
+ /* We are done with all of the arguments. */
+ arg_idx = nargs;
+ }
+ else
+ {
+ pack_adjust = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) - 1;
+ arg_idx += pack_adjust;
+ }
+
+ continue;
+ }
+ else if (arg)
+ {
+ if (PACK_EXPANSION_P (arg))
+ {
+ /* We don't know how many args we have yet, just
+ use the unconverted ones for now. */
+ new_inner_args = inner_args;
+ arg_idx = nargs;
+ break;
+ }
+ }
+ else if (require_all_args)
+ {
+ /* There must be a default arg in this case. */
+ arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args,
+ complain, in_decl);
+ /* The position of the first default template argument,
+ is also the number of non-defaulted arguments in NEW_INNER_ARGS.
+ Record that. */
+ if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,
+ arg_idx - pack_adjust);
+ }
+ else
+ break;
+
+ if (arg == error_mark_node)
+ {
+ if (complain & tf_error)
+ error ("template argument %d is invalid", arg_idx + 1);
+ }
+ else if (!arg)
+ /* This only occurs if there was an error in the template
+ parameter list itself (which we would already have
+ reported) that we are trying to recover from, e.g., a class
+ template with a parameter list such as
+ template<typename..., typename>. */
+ ++lost;
+ else
+ arg = convert_template_argument (TREE_VALUE (parm),
+ arg, new_args, complain,
+ parm_idx, in_decl);
+
+ if (arg == error_mark_node)
+ lost++;
+ TREE_VEC_ELT (new_inner_args, arg_idx - pack_adjust) = arg;
+ }
+ cp_unevaluated_operand = saved_unevaluated_operand;
+ c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
+
+ if (variadic_p && arg_idx < nargs)
+ {
+ if (complain & tf_error)
+ {
+ error ("wrong number of template arguments "
+ "(%d, should be %d)", nargs, arg_idx);
+ if (in_decl)
+ error ("provided for %q+D", in_decl);
+ }
+ return error_mark_node;
+ }
+
+ if (lost)
+ return error_mark_node;
+
+#ifdef ENABLE_CHECKING
+ if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,
+ TREE_VEC_LENGTH (new_inner_args));
+#endif
+
+ return new_inner_args;
+}
+
+/* Like coerce_template_parms. If PARMS represents all template
+ parameters levels, this function returns a vector of vectors
+ representing all the resulting argument levels. Note that in this
+ case, only the innermost arguments are coerced because the
+ outermost ones are supposed to have been coerced already.
+
+ Otherwise, if PARMS represents only (the innermost) vector of
+ parameters, this function returns a vector containing just the
+ innermost resulting arguments. */
+
+static tree
+coerce_innermost_template_parms (tree parms,
+ tree args,
+ tree in_decl,
+ tsubst_flags_t complain,
+ bool require_all_args,
+ bool use_default_args)
+{
+ int parms_depth = TMPL_PARMS_DEPTH (parms);
+ int args_depth = TMPL_ARGS_DEPTH (args);
+ tree coerced_args;
+
+ if (parms_depth > 1)
+ {
+ coerced_args = make_tree_vec (parms_depth);
+ tree level;
+ int cur_depth;
+
+ for (level = parms, cur_depth = parms_depth;
+ parms_depth > 0 && level != NULL_TREE;
+ level = TREE_CHAIN (level), --cur_depth)
+ {
+ tree l;
+ if (cur_depth == args_depth)
+ l = coerce_template_parms (TREE_VALUE (level),
+ args, in_decl, complain,
+ require_all_args,
+ use_default_args);
+ else
+ l = TMPL_ARGS_LEVEL (args, cur_depth);
+
+ if (l == error_mark_node)
+ return error_mark_node;
+
+ SET_TMPL_ARGS_LEVEL (coerced_args, cur_depth, l);
+ }
+ }
+ else
+ coerced_args = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parms),
+ args, in_decl, complain,
+ require_all_args,
+ use_default_args);
+ return coerced_args;
+}
+
+/* Returns 1 if template args OT and NT are equivalent. */
+
+static int
+template_args_equal (tree ot, tree nt)
+{
+ if (nt == ot)
+ return 1;
+ if (nt == NULL_TREE || ot == NULL_TREE)
+ return false;
+
+ if (TREE_CODE (nt) == TREE_VEC)
+ /* For member templates */
+ return TREE_CODE (ot) == TREE_VEC && comp_template_args (ot, nt);
+ else if (PACK_EXPANSION_P (ot))
+ return (PACK_EXPANSION_P (nt)
+ && template_args_equal (PACK_EXPANSION_PATTERN (ot),
+ PACK_EXPANSION_PATTERN (nt))
+ && template_args_equal (PACK_EXPANSION_EXTRA_ARGS (ot),
+ PACK_EXPANSION_EXTRA_ARGS (nt)));
+ else if (ARGUMENT_PACK_P (ot))
+ {
+ int i, len;
+ tree opack, npack;
+
+ if (!ARGUMENT_PACK_P (nt))
+ return 0;
+
+ opack = ARGUMENT_PACK_ARGS (ot);
+ npack = ARGUMENT_PACK_ARGS (nt);
+ len = TREE_VEC_LENGTH (opack);
+ if (TREE_VEC_LENGTH (npack) != len)
+ return 0;
+ for (i = 0; i < len; ++i)
+ if (!template_args_equal (TREE_VEC_ELT (opack, i),
+ TREE_VEC_ELT (npack, i)))
+ return 0;
+ return 1;
+ }
+ else if (ot && TREE_CODE (ot) == ARGUMENT_PACK_SELECT)
+ {
+ /* We get here probably because we are in the middle of substituting
+ into the pattern of a pack expansion. In that case the
+ ARGUMENT_PACK_SELECT temporarily replaces the pack argument we are
+ interested in. So we want to use the initial pack argument for
+ the comparison. */
+ ot = ARGUMENT_PACK_SELECT_FROM_PACK (ot);
+ if (nt && TREE_CODE (nt) == ARGUMENT_PACK_SELECT)
+ nt = ARGUMENT_PACK_SELECT_FROM_PACK (nt);
+ return template_args_equal (ot, nt);
+ }
+ else if (TYPE_P (nt))
+ return TYPE_P (ot) && same_type_p (ot, nt);
+ else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
+ return 0;
+ else
+ return cp_tree_equal (ot, nt);
+}
+
+/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets of
+ template arguments. Returns 0 otherwise, and updates OLDARG_PTR and
+ NEWARG_PTR with the offending arguments if they are non-NULL. */
+
+static int
+comp_template_args_with_info (tree oldargs, tree newargs,
+ tree *oldarg_ptr, tree *newarg_ptr)
+{
+ int i;
+
+ if (oldargs == newargs)
+ return 1;
+
+ if (!oldargs || !newargs)
+ return 0;
+
+ if (TREE_VEC_LENGTH (oldargs) != TREE_VEC_LENGTH (newargs))
+ return 0;
+
+ for (i = 0; i < TREE_VEC_LENGTH (oldargs); ++i)
+ {
+ tree nt = TREE_VEC_ELT (newargs, i);
+ tree ot = TREE_VEC_ELT (oldargs, i);
+
+ if (! template_args_equal (ot, nt))
+ {
+ if (oldarg_ptr != NULL)
+ *oldarg_ptr = ot;
+ if (newarg_ptr != NULL)
+ *newarg_ptr = nt;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets
+ of template arguments. Returns 0 otherwise. */
+
+int
+comp_template_args (tree oldargs, tree newargs)
+{
+ return comp_template_args_with_info (oldargs, newargs, NULL, NULL);
+}
+
+static void
+add_pending_template (tree d)
+{
+ tree ti = (TYPE_P (d)
+ ? CLASSTYPE_TEMPLATE_INFO (d)
+ : DECL_TEMPLATE_INFO (d));
+ struct pending_template *pt;
+ int level;
+
+ if (TI_PENDING_TEMPLATE_FLAG (ti))
+ return;
+
+ /* We are called both from instantiate_decl, where we've already had a
+ tinst_level pushed, and instantiate_template, where we haven't.
+ Compensate. */
+ level = !current_tinst_level || current_tinst_level->decl != d;
+
+ if (level)
+ push_tinst_level (d);
+
+ pt = ggc_alloc_pending_template ();
+ pt->next = NULL;
+ pt->tinst = current_tinst_level;
+ if (last_pending_template)
+ last_pending_template->next = pt;
+ else
+ pending_templates = pt;
+
+ last_pending_template = pt;
+
+ TI_PENDING_TEMPLATE_FLAG (ti) = 1;
+
+ if (level)
+ pop_tinst_level ();
+}
+
+
+/* Return a TEMPLATE_ID_EXPR corresponding to the indicated FNS and
+ ARGLIST. Valid choices for FNS are given in the cp-tree.def
+ documentation for TEMPLATE_ID_EXPR. */
+
+tree
+lookup_template_function (tree fns, tree arglist)
+{
+ tree type;
+
+ if (fns == error_mark_node || arglist == error_mark_node)
+ return error_mark_node;
+
+ gcc_assert (!arglist || TREE_CODE (arglist) == TREE_VEC);
+
+ if (!is_overloaded_fn (fns) && !identifier_p (fns))
+ {
+ error ("%q#D is not a function template", fns);
+ return error_mark_node;
+ }
+
+ if (BASELINK_P (fns))
+ {
+ BASELINK_FUNCTIONS (fns) = build2 (TEMPLATE_ID_EXPR,
+ unknown_type_node,
+ BASELINK_FUNCTIONS (fns),
+ arglist);
+ return fns;
+ }
+
+ type = TREE_TYPE (fns);
+ if (TREE_CODE (fns) == OVERLOAD || !type)
+ type = unknown_type_node;
+
+ return build2 (TEMPLATE_ID_EXPR, type, fns, arglist);
+}
+
+/* Within the scope of a template class S<T>, the name S gets bound
+ (in build_self_reference) to a TYPE_DECL for the class, not a
+ TEMPLATE_DECL. If DECL is a TYPE_DECL for current_class_type,
+ or one of its enclosing classes, and that type is a template,
+ return the associated TEMPLATE_DECL. Otherwise, the original
+ DECL is returned.
+
+ Also handle the case when DECL is a TREE_LIST of ambiguous
+ injected-class-names from different bases. */
+
+tree
+maybe_get_template_decl_from_type_decl (tree decl)
+{
+ if (decl == NULL_TREE)
+ return decl;
+
+ /* DR 176: A lookup that finds an injected-class-name (10.2
+ [class.member.lookup]) can result in an ambiguity in certain cases
+ (for example, if it is found in more than one base class). If all of
+ the injected-class-names that are found refer to specializations of
+ the same class template, and if the name is followed by a
+ template-argument-list, the reference refers to the class template
+ itself and not a specialization thereof, and is not ambiguous. */
+ if (TREE_CODE (decl) == TREE_LIST)
+ {
+ tree t, tmpl = NULL_TREE;
+ for (t = decl; t; t = TREE_CHAIN (t))
+ {
+ tree elt = maybe_get_template_decl_from_type_decl (TREE_VALUE (t));
+ if (!tmpl)
+ tmpl = elt;
+ else if (tmpl != elt)
+ break;
+ }
+ if (tmpl && t == NULL_TREE)
+ return tmpl;
+ else
+ return decl;
+ }
+
+ return (decl != NULL_TREE
+ && DECL_SELF_REFERENCE_P (decl)
+ && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl)))
+ ? CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl)) : decl;
+}
+
+/* Given an IDENTIFIER_NODE (or type TEMPLATE_DECL) and a chain of
+ parameters, find the desired type.
+
+ D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.
+
+ IN_DECL, if non-NULL, is the template declaration we are trying to
+ instantiate.
+
+ If ENTERING_SCOPE is nonzero, we are about to enter the scope of
+ the class we are looking up.
+
+ Issue error and warning messages under control of COMPLAIN.
+
+ If the template class is really a local class in a template
+ function, then the FUNCTION_CONTEXT is the function in which it is
+ being instantiated.
+
+ ??? Note that this function is currently called *twice* for each
+ template-id: the first time from the parser, while creating the
+ incomplete type (finish_template_type), and the second type during the
+ real instantiation (instantiate_template_class). This is surely something
+ that we want to avoid. It also causes some problems with argument
+ coercion (see convert_nontype_argument for more information on this). */
+
+static tree
+lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
+ int entering_scope, tsubst_flags_t complain)
+{
+ tree templ = NULL_TREE, parmlist;
+ tree t;
+ void **slot;
+ spec_entry *entry;
+ spec_entry elt;
+ hashval_t hash;
+
+ if (identifier_p (d1))
+ {
+ tree value = innermost_non_namespace_value (d1);
+ if (value && DECL_TEMPLATE_TEMPLATE_PARM_P (value))
+ templ = value;
+ else
+ {
+ if (context)
+ push_decl_namespace (context);
+ templ = lookup_name (d1);
+ templ = maybe_get_template_decl_from_type_decl (templ);
+ if (context)
+ pop_decl_namespace ();
+ }
+ if (templ)
+ context = DECL_CONTEXT (templ);
+ }
+ else if (TREE_CODE (d1) == TYPE_DECL && MAYBE_CLASS_TYPE_P (TREE_TYPE (d1)))
+ {
+ tree type = TREE_TYPE (d1);
+
+ /* If we are declaring a constructor, say A<T>::A<T>, we will get
+ an implicit typename for the second A. Deal with it. */
+ if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type))
+ type = TREE_TYPE (type);
+
+ if (CLASSTYPE_TEMPLATE_INFO (type))
+ {
+ templ = CLASSTYPE_TI_TEMPLATE (type);
+ d1 = DECL_NAME (templ);
+ }
+ }
+ else if (TREE_CODE (d1) == ENUMERAL_TYPE
+ || (TYPE_P (d1) && MAYBE_CLASS_TYPE_P (d1)))
+ {
+ templ = TYPE_TI_TEMPLATE (d1);
+ d1 = DECL_NAME (templ);
+ }
+ else if (TREE_CODE (d1) == TEMPLATE_DECL
+ && DECL_TEMPLATE_RESULT (d1)
+ && TREE_CODE (DECL_TEMPLATE_RESULT (d1)) == TYPE_DECL)
+ {
+ templ = d1;
+ d1 = DECL_NAME (templ);
+ context = DECL_CONTEXT (templ);
+ }
+ else if (DECL_TEMPLATE_TEMPLATE_PARM_P (d1))
+ {
+ templ = d1;
+ d1 = DECL_NAME (templ);
+ }
+
+ /* Issue an error message if we didn't find a template. */
+ if (! templ)
+ {
+ if (complain & tf_error)
+ error ("%qT is not a template", d1);
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (templ) != TEMPLATE_DECL
+ /* Make sure it's a user visible template, if it was named by
+ the user. */
+ || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (templ)
+ && !PRIMARY_TEMPLATE_P (templ)))
+ {
+ if (complain & tf_error)
+ {
+ error ("non-template type %qT used as a template", d1);
+ if (in_decl)
+ error ("for template declaration %q+D", in_decl);
+ }
+ return error_mark_node;
+ }
+
+ complain &= ~tf_user;
+
+ /* An alias that just changes the name of a template is equivalent to the
+ other template, so if any of the arguments are pack expansions, strip
+ the alias to avoid problems with a pack expansion passed to a non-pack
+ alias template parameter (DR 1430). */
+ if (pack_expansion_args_count (INNERMOST_TEMPLATE_ARGS (arglist)))
+ templ = get_underlying_template (templ);
+
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
+ {
+ /* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store
+ template arguments */
+
+ tree parm;
+ tree arglist2;
+ tree outer;
+
+ parmlist = DECL_INNERMOST_TEMPLATE_PARMS (templ);
+
+ /* Consider an example where a template template parameter declared as
+
+ template <class T, class U = std::allocator<T> > class TT
+
+ The template parameter level of T and U are one level larger than
+ of TT. To proper process the default argument of U, say when an
+ instantiation `TT<int>' is seen, we need to build the full
+ arguments containing {int} as the innermost level. Outer levels,
+ available when not appearing as default template argument, can be
+ obtained from the arguments of the enclosing template.
+
+ Suppose that TT is later substituted with std::vector. The above
+ instantiation is `TT<int, std::allocator<T> >' with TT at
+ level 1, and T at level 2, while the template arguments at level 1
+ becomes {std::vector} and the inner level 2 is {int}. */
+
+ outer = DECL_CONTEXT (templ);
+ if (outer)
+ outer = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (outer)));
+ else if (current_template_parms)
+ /* This is an argument of the current template, so we haven't set
+ DECL_CONTEXT yet. */
+ outer = current_template_args ();
+
+ if (outer)
+ arglist = add_to_template_args (outer, arglist);
+
+ arglist2 = coerce_template_parms (parmlist, arglist, templ,
+ complain,
+ /*require_all_args=*/true,
+ /*use_default_args=*/true);
+ if (arglist2 == error_mark_node
+ || (!uses_template_parms (arglist2)
+ && check_instantiated_args (templ, arglist2, complain)))
+ return error_mark_node;
+
+ parm = bind_template_template_parm (TREE_TYPE (templ), arglist2);
+ return parm;
+ }
+ else
+ {
+ tree template_type = TREE_TYPE (templ);
+ tree gen_tmpl;
+ tree type_decl;
+ tree found = NULL_TREE;
+ int arg_depth;
+ int parm_depth;
+ int is_dependent_type;
+ int use_partial_inst_tmpl = false;
+
+ if (template_type == error_mark_node)
+ /* An error occurred while building the template TEMPL, and a
+ diagnostic has most certainly been emitted for that
+ already. Let's propagate that error. */
+ return error_mark_node;
+
+ gen_tmpl = most_general_template (templ);
+ parmlist = DECL_TEMPLATE_PARMS (gen_tmpl);
+ parm_depth = TMPL_PARMS_DEPTH (parmlist);
+ arg_depth = TMPL_ARGS_DEPTH (arglist);
+
+ if (arg_depth == 1 && parm_depth > 1)
+ {
+ /* We've been given an incomplete set of template arguments.
+ For example, given:
+
+ template <class T> struct S1 {
+ template <class U> struct S2 {};
+ template <class U> struct S2<U*> {};
+ };
+
+ we will be called with an ARGLIST of `U*', but the
+ TEMPLATE will be `template <class T> template
+ <class U> struct S1<T>::S2'. We must fill in the missing
+ arguments. */
+ arglist
+ = add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (templ)),
+ arglist);
+ arg_depth = TMPL_ARGS_DEPTH (arglist);
+ }
+
+ /* Now we should have enough arguments. */
+ gcc_assert (parm_depth == arg_depth);
+
+ /* From here on, we're only interested in the most general
+ template. */
+
+ /* Calculate the BOUND_ARGS. These will be the args that are
+ actually tsubst'd into the definition to create the
+ instantiation. */
+ if (parm_depth > 1)
+ {
+ /* We have multiple levels of arguments to coerce, at once. */
+ int i;
+ int saved_depth = TMPL_ARGS_DEPTH (arglist);
+
+ tree bound_args = make_tree_vec (parm_depth);
+
+ for (i = saved_depth,
+ t = DECL_TEMPLATE_PARMS (gen_tmpl);
+ i > 0 && t != NULL_TREE;
+ --i, t = TREE_CHAIN (t))
+ {
+ tree a;
+ if (i == saved_depth)
+ a = coerce_template_parms (TREE_VALUE (t),
+ arglist, gen_tmpl,
+ complain,
+ /*require_all_args=*/true,
+ /*use_default_args=*/true);
+ else
+ /* Outer levels should have already been coerced. */
+ a = TMPL_ARGS_LEVEL (arglist, i);
+
+ /* Don't process further if one of the levels fails. */
+ if (a == error_mark_node)
+ {
+ /* Restore the ARGLIST to its full size. */
+ TREE_VEC_LENGTH (arglist) = saved_depth;
+ return error_mark_node;
+ }
+
+ SET_TMPL_ARGS_LEVEL (bound_args, i, a);
+
+ /* We temporarily reduce the length of the ARGLIST so
+ that coerce_template_parms will see only the arguments
+ corresponding to the template parameters it is
+ examining. */
+ TREE_VEC_LENGTH (arglist)--;
+ }
+
+ /* Restore the ARGLIST to its full size. */
+ TREE_VEC_LENGTH (arglist) = saved_depth;
+
+ arglist = bound_args;
+ }
+ else
+ arglist
+ = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
+ INNERMOST_TEMPLATE_ARGS (arglist),
+ gen_tmpl,
+ complain,
+ /*require_all_args=*/true,
+ /*use_default_args=*/true);
+
+ if (arglist == error_mark_node)
+ /* We were unable to bind the arguments. */
+ return error_mark_node;
+
+ /* In the scope of a template class, explicit references to the
+ template class refer to the type of the template, not any
+ instantiation of it. For example, in:
+
+ template <class T> class C { void f(C<T>); }
+
+ the `C<T>' is just the same as `C'. Outside of the
+ class, however, such a reference is an instantiation. */
+ if ((entering_scope
+ || !PRIMARY_TEMPLATE_P (gen_tmpl)
+ || currently_open_class (template_type))
+ /* comp_template_args is expensive, check it last. */
+ && comp_template_args (TYPE_TI_ARGS (template_type),
+ arglist))
+ return template_type;
+
+ /* If we already have this specialization, return it. */
+ elt.tmpl = gen_tmpl;
+ elt.args = arglist;
+ hash = hash_specialization (&elt);
+ entry = (spec_entry *) htab_find_with_hash (type_specializations,
+ &elt, hash);
+
+ if (entry)
+ return entry->spec;
+
+ is_dependent_type = uses_template_parms (arglist);
+
+ /* If the deduced arguments are invalid, then the binding
+ failed. */
+ if (!is_dependent_type
+ && check_instantiated_args (gen_tmpl,
+ INNERMOST_TEMPLATE_ARGS (arglist),
+ complain))
+ return error_mark_node;
+
+ if (!is_dependent_type
+ && !PRIMARY_TEMPLATE_P (gen_tmpl)
+ && !LAMBDA_TYPE_P (TREE_TYPE (gen_tmpl))
+ && TREE_CODE (CP_DECL_CONTEXT (gen_tmpl)) == NAMESPACE_DECL)
+ {
+ found = xref_tag_from_type (TREE_TYPE (gen_tmpl),
+ DECL_NAME (gen_tmpl),
+ /*tag_scope=*/ts_global);
+ return found;
+ }
+
+ context = tsubst (DECL_CONTEXT (gen_tmpl), arglist,
+ complain, in_decl);
+ if (context == error_mark_node)
+ return error_mark_node;
+
+ if (!context)
+ context = global_namespace;
+
+ /* Create the type. */
+ if (DECL_ALIAS_TEMPLATE_P (gen_tmpl))
+ {
+ /* The user referred to a specialization of an alias
+ template represented by GEN_TMPL.
+
+ [temp.alias]/2 says:
+
+ When a template-id refers to the specialization of an
+ alias template, it is equivalent to the associated
+ type obtained by substitution of its
+ template-arguments for the template-parameters in the
+ type-id of the alias template. */
+
+ t = tsubst (TREE_TYPE (gen_tmpl), arglist, complain, in_decl);
+ /* Note that the call above (by indirectly calling
+ register_specialization in tsubst_decl) registers the
+ TYPE_DECL representing the specialization of the alias
+ template. So next time someone substitutes ARGLIST for
+ the template parms into the alias template (GEN_TMPL),
+ she'll get that TYPE_DECL back. */
+
+ if (t == error_mark_node)
+ return t;
+ }
+ else if (TREE_CODE (template_type) == ENUMERAL_TYPE)
+ {
+ if (!is_dependent_type)
+ {
+ set_current_access_from_decl (TYPE_NAME (template_type));
+ t = start_enum (TYPE_IDENTIFIER (template_type), NULL_TREE,
+ tsubst (ENUM_UNDERLYING_TYPE (template_type),
+ arglist, complain, in_decl),
+ SCOPED_ENUM_P (template_type), NULL);
+
+ if (t == error_mark_node)
+ return t;
+ }
+ else
+ {
+ /* We don't want to call start_enum for this type, since
+ the values for the enumeration constants may involve
+ template parameters. And, no one should be interested
+ in the enumeration constants for such a type. */
+ t = cxx_make_type (ENUMERAL_TYPE);
+ SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type));
+ }
+ SET_OPAQUE_ENUM_P (t, OPAQUE_ENUM_P (template_type));
+ ENUM_FIXED_UNDERLYING_TYPE_P (t)
+ = ENUM_FIXED_UNDERLYING_TYPE_P (template_type);
+ }
+ else if (CLASS_TYPE_P (template_type))
+ {
+ t = make_class_type (TREE_CODE (template_type));
+ CLASSTYPE_DECLARED_CLASS (t)
+ = CLASSTYPE_DECLARED_CLASS (template_type);
+ SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
+ TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type);
+
+ /* A local class. Make sure the decl gets registered properly. */
+ if (context == current_function_decl)
+ pushtag (DECL_NAME (gen_tmpl), t, /*tag_scope=*/ts_current);
+
+ if (comp_template_args (CLASSTYPE_TI_ARGS (template_type), arglist))
+ /* This instantiation is another name for the primary
+ template type. Set the TYPE_CANONICAL field
+ appropriately. */
+ TYPE_CANONICAL (t) = template_type;
+ else if (any_template_arguments_need_structural_equality_p (arglist))
+ /* Some of the template arguments require structural
+ equality testing, so this template class requires
+ structural equality testing. */
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ }
+ else
+ gcc_unreachable ();
+
+ /* If we called start_enum or pushtag above, this information
+ will already be set up. */
+ if (!TYPE_NAME (t))
+ {
+ TYPE_CONTEXT (t) = FROB_CONTEXT (context);
+
+ type_decl = create_implicit_typedef (DECL_NAME (gen_tmpl), t);
+ DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t);
+ DECL_SOURCE_LOCATION (type_decl)
+ = DECL_SOURCE_LOCATION (TYPE_STUB_DECL (template_type));
+ }
+ else
+ type_decl = TYPE_NAME (t);
+
+ if (CLASS_TYPE_P (template_type))
+ {
+ TREE_PRIVATE (type_decl)
+ = TREE_PRIVATE (TYPE_MAIN_DECL (template_type));
+ TREE_PROTECTED (type_decl)
+ = TREE_PROTECTED (TYPE_MAIN_DECL (template_type));
+ if (CLASSTYPE_VISIBILITY_SPECIFIED (template_type))
+ {
+ DECL_VISIBILITY_SPECIFIED (type_decl) = 1;
+ DECL_VISIBILITY (type_decl) = CLASSTYPE_VISIBILITY (template_type);
+ }
+ }
+
+ /* Let's consider the explicit specialization of a member
+ of a class template specialization that is implicitly instantiated,
+ e.g.:
+ template<class T>
+ struct S
+ {
+ template<class U> struct M {}; //#0
+ };
+
+ template<>
+ template<>
+ struct S<int>::M<char> //#1
+ {
+ int i;
+ };
+ [temp.expl.spec]/4 says this is valid.
+
+ In this case, when we write:
+ S<int>::M<char> m;
+
+ M is instantiated from the CLASSTYPE_TI_TEMPLATE of #1, not from
+ the one of #0.
+
+ When we encounter #1, we want to store the partial instantiation
+ of M (template<class T> S<int>::M<T>) in its CLASSTYPE_TI_TEMPLATE.
+
+ For all cases other than this "explicit specialization of member of a
+ class template", we just want to store the most general template into
+ the CLASSTYPE_TI_TEMPLATE of M.
+
+ This case of "explicit specialization of member of a class template"
+ only happens when:
+ 1/ the enclosing class is an instantiation of, and therefore not
+ the same as, the context of the most general template, and
+ 2/ we aren't looking at the partial instantiation itself, i.e.
+ the innermost arguments are not the same as the innermost parms of
+ the most general template.
+
+ So it's only when 1/ and 2/ happens that we want to use the partial
+ instantiation of the member template in lieu of its most general
+ template. */
+
+ if (PRIMARY_TEMPLATE_P (gen_tmpl)
+ && TMPL_ARGS_HAVE_MULTIPLE_LEVELS (arglist)
+ /* the enclosing class must be an instantiation... */
+ && CLASS_TYPE_P (context)
+ && !same_type_p (context, DECL_CONTEXT (gen_tmpl)))
+ {
+ tree partial_inst_args;
+ TREE_VEC_LENGTH (arglist)--;
+ ++processing_template_decl;
+ partial_inst_args =
+ tsubst (INNERMOST_TEMPLATE_ARGS
+ (TYPE_TI_ARGS (TREE_TYPE (gen_tmpl))),
+ arglist, complain, NULL_TREE);
+ --processing_template_decl;
+ TREE_VEC_LENGTH (arglist)++;
+ use_partial_inst_tmpl =
+ /*...and we must not be looking at the partial instantiation
+ itself. */
+ !comp_template_args (INNERMOST_TEMPLATE_ARGS (arglist),
+ partial_inst_args);
+ }
+
+ if (!use_partial_inst_tmpl)
+ /* This case is easy; there are no member templates involved. */
+ found = gen_tmpl;
+ else
+ {
+ /* This is a full instantiation of a member template. Find
+ the partial instantiation of which this is an instance. */
+
+ /* Temporarily reduce by one the number of levels in the ARGLIST
+ so as to avoid comparing the last set of arguments. */
+ TREE_VEC_LENGTH (arglist)--;
+ found = tsubst (gen_tmpl, arglist, complain, NULL_TREE);
+ TREE_VEC_LENGTH (arglist)++;
+ /* FOUND is either a proper class type, or an alias
+ template specialization. In the later case, it's a
+ TYPE_DECL, resulting from the substituting of arguments
+ for parameters in the TYPE_DECL of the alias template
+ done earlier. So be careful while getting the template
+ of FOUND. */
+ found = TREE_CODE (found) == TYPE_DECL
+ ? TYPE_TI_TEMPLATE (TREE_TYPE (found))
+ : CLASSTYPE_TI_TEMPLATE (found);
+ }
+
+ SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));
+
+ elt.spec = t;
+ slot = htab_find_slot_with_hash (type_specializations,
+ &elt, hash, INSERT);
+ entry = ggc_alloc_spec_entry ();
+ *entry = elt;
+ *slot = entry;
+
+ /* Note this use of the partial instantiation so we can check it
+ later in maybe_process_partial_specialization. */
+ DECL_TEMPLATE_INSTANTIATIONS (found)
+ = tree_cons (arglist, t,
+ DECL_TEMPLATE_INSTANTIATIONS (found));
+
+ if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type
+ && !DECL_ALIAS_TEMPLATE_P (gen_tmpl))
+ /* Now that the type has been registered on the instantiations
+ list, we set up the enumerators. Because the enumeration
+ constants may involve the enumeration type itself, we make
+ sure to register the type first, and then create the
+ constants. That way, doing tsubst_expr for the enumeration
+ constants won't result in recursive calls here; we'll find
+ the instantiation and exit above. */
+ tsubst_enum (template_type, t, arglist);
+
+ if (CLASS_TYPE_P (template_type) && is_dependent_type)
+ /* If the type makes use of template parameters, the
+ code that generates debugging information will crash. */
+ DECL_IGNORED_P (TYPE_MAIN_DECL (t)) = 1;
+
+ /* Possibly limit visibility based on template args. */
+ TREE_PUBLIC (type_decl) = 1;
+ determine_visibility (type_decl);
+
+ return t;
+ }
+}
+
+/* Wrapper for lookup_template_class_1. */
+
+tree
+lookup_template_class (tree d1, tree arglist, tree in_decl, tree context,
+ int entering_scope, tsubst_flags_t complain)
+{
+ tree ret;
+ timevar_push (TV_TEMPLATE_INST);
+ ret = lookup_template_class_1 (d1, arglist, in_decl, context,
+ entering_scope, complain);
+ timevar_pop (TV_TEMPLATE_INST);
+ return ret;
+}
+
+struct pair_fn_data
+{
+ tree_fn_t fn;
+ void *data;
+ /* True when we should also visit template parameters that occur in
+ non-deduced contexts. */
+ bool include_nondeduced_p;
+ struct pointer_set_t *visited;
+};
+
+/* Called from for_each_template_parm via walk_tree. */
+
+static tree
+for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
+{
+ tree t = *tp;
+ struct pair_fn_data *pfd = (struct pair_fn_data *) d;
+ tree_fn_t fn = pfd->fn;
+ void *data = pfd->data;
+
+ if (TYPE_P (t)
+ && (pfd->include_nondeduced_p || TREE_CODE (t) != TYPENAME_TYPE)
+ && for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited,
+ pfd->include_nondeduced_p))
+ return error_mark_node;
+
+ switch (TREE_CODE (t))
+ {
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ break;
+ /* Fall through. */
+
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ if (!TYPE_TEMPLATE_INFO (t))
+ *walk_subtrees = 0;
+ else if (for_each_template_parm (TYPE_TI_ARGS (t),
+ fn, data, pfd->visited,
+ pfd->include_nondeduced_p))
+ return error_mark_node;
+ break;
+
+ case INTEGER_TYPE:
+ if (for_each_template_parm (TYPE_MIN_VALUE (t),
+ fn, data, pfd->visited,
+ pfd->include_nondeduced_p)
+ || for_each_template_parm (TYPE_MAX_VALUE (t),
+ fn, data, pfd->visited,
+ pfd->include_nondeduced_p))
+ return error_mark_node;
+ break;
+
+ case METHOD_TYPE:
+ /* Since we're not going to walk subtrees, we have to do this
+ explicitly here. */
+ if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data,
+ pfd->visited, pfd->include_nondeduced_p))
+ return error_mark_node;
+ /* Fall through. */
+
+ case FUNCTION_TYPE:
+ /* Check the return type. */
+ if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
+ pfd->include_nondeduced_p))
+ return error_mark_node;
+
+ /* Check the parameter types. Since default arguments are not
+ instantiated until they are needed, the TYPE_ARG_TYPES may
+ contain expressions that involve template parameters. But,
+ no-one should be looking at them yet. And, once they're
+ instantiated, they don't contain template parameters, so
+ there's no point in looking at them then, either. */
+ {
+ tree parm;
+
+ for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm))
+ if (for_each_template_parm (TREE_VALUE (parm), fn, data,
+ pfd->visited, pfd->include_nondeduced_p))
+ return error_mark_node;
+
+ /* Since we've already handled the TYPE_ARG_TYPES, we don't
+ want walk_tree walking into them itself. */
+ *walk_subtrees = 0;
+ }
+ break;
+
+ case TYPEOF_TYPE:
+ case UNDERLYING_TYPE:
+ if (pfd->include_nondeduced_p
+ && for_each_template_parm (TYPE_FIELDS (t), fn, data,
+ pfd->visited,
+ pfd->include_nondeduced_p))
+ return error_mark_node;
+ break;
+
+ case FUNCTION_DECL:
+ case VAR_DECL:
+ if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
+ && for_each_template_parm (DECL_TI_ARGS (t), fn, data,
+ pfd->visited, pfd->include_nondeduced_p))
+ return error_mark_node;
+ /* Fall through. */
+
+ case PARM_DECL:
+ case CONST_DECL:
+ if (TREE_CODE (t) == CONST_DECL && DECL_TEMPLATE_PARM_P (t)
+ && for_each_template_parm (DECL_INITIAL (t), fn, data,
+ pfd->visited, pfd->include_nondeduced_p))
+ return error_mark_node;
+ if (DECL_CONTEXT (t)
+ && pfd->include_nondeduced_p
+ && for_each_template_parm (DECL_CONTEXT (t), fn, data,
+ pfd->visited, pfd->include_nondeduced_p))
+ return error_mark_node;
+ break;
+
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ /* Record template parameters such as `T' inside `TT<T>'. */
+ if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited,
+ pfd->include_nondeduced_p))
+ return error_mark_node;
+ /* Fall through. */
+
+ case TEMPLATE_TEMPLATE_PARM:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ if (fn && (*fn)(t, data))
+ return error_mark_node;
+ else if (!fn)
+ return error_mark_node;
+ break;
+
+ case TEMPLATE_DECL:
+ /* A template template parameter is encountered. */
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
+ && for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
+ pfd->include_nondeduced_p))
+ return error_mark_node;
+
+ /* Already substituted template template parameter */
+ *walk_subtrees = 0;
+ break;
+
+ case TYPENAME_TYPE:
+ if (!fn
+ || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn,
+ data, pfd->visited,
+ pfd->include_nondeduced_p))
+ return error_mark_node;
+ break;
+
+ case CONSTRUCTOR:
+ if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))
+ && pfd->include_nondeduced_p
+ && for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE
+ (TREE_TYPE (t)), fn, data,
+ pfd->visited, pfd->include_nondeduced_p))
+ return error_mark_node;
+ break;
+
+ case INDIRECT_REF:
+ case COMPONENT_REF:
+ /* If there's no type, then this thing must be some expression
+ involving template parameters. */
+ if (!fn && !TREE_TYPE (t))
+ return error_mark_node;
+ break;
+
+ case MODOP_EXPR:
+ case CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case ARROW_EXPR:
+ case DOTSTAR_EXPR:
+ case TYPEID_EXPR:
+ case PSEUDO_DTOR_EXPR:
+ if (!fn)
+ return error_mark_node;
+ break;
+
+ default:
+ break;
+ }
+
+ /* We didn't find any template parameters we liked. */
+ return NULL_TREE;
+}
+
+/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM,
+ BOUND_TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX in T,
+ call FN with the parameter and the DATA.
+ If FN returns nonzero, the iteration is terminated, and
+ for_each_template_parm returns 1. Otherwise, the iteration
+ continues. If FN never returns a nonzero value, the value
+ returned by for_each_template_parm is 0. If FN is NULL, it is
+ considered to be the function which always returns 1.
+
+ If INCLUDE_NONDEDUCED_P, then this routine will also visit template
+ parameters that occur in non-deduced contexts. When false, only
+ visits those template parameters that can be deduced. */
+
+static int
+for_each_template_parm (tree t, tree_fn_t fn, void* data,
+ struct pointer_set_t *visited,
+ bool include_nondeduced_p)
+{
+ struct pair_fn_data pfd;
+ int result;
+
+ /* Set up. */
+ pfd.fn = fn;
+ pfd.data = data;
+ pfd.include_nondeduced_p = include_nondeduced_p;
+
+ /* Walk the tree. (Conceptually, we would like to walk without
+ duplicates, but for_each_template_parm_r recursively calls
+ for_each_template_parm, so we would need to reorganize a fair
+ bit to use walk_tree_without_duplicates, so we keep our own
+ visited list.) */
+ if (visited)
+ pfd.visited = visited;
+ else
+ pfd.visited = pointer_set_create ();
+ result = cp_walk_tree (&t,
+ for_each_template_parm_r,
+ &pfd,
+ pfd.visited) != NULL_TREE;
+
+ /* Clean up. */
+ if (!visited)
+ {
+ pointer_set_destroy (pfd.visited);
+ pfd.visited = 0;
+ }
+
+ return result;
+}
+
+/* Returns true if T depends on any template parameter. */
+
+int
+uses_template_parms (tree t)
+{
+ bool dependent_p;
+ int saved_processing_template_decl;
+
+ saved_processing_template_decl = processing_template_decl;
+ if (!saved_processing_template_decl)
+ processing_template_decl = 1;
+ if (TYPE_P (t))
+ dependent_p = dependent_type_p (t);
+ else if (TREE_CODE (t) == TREE_VEC)
+ dependent_p = any_dependent_template_arguments_p (t);
+ else if (TREE_CODE (t) == TREE_LIST)
+ dependent_p = (uses_template_parms (TREE_VALUE (t))
+ || uses_template_parms (TREE_CHAIN (t)));
+ else if (TREE_CODE (t) == TYPE_DECL)
+ dependent_p = dependent_type_p (TREE_TYPE (t));
+ else if (DECL_P (t)
+ || EXPR_P (t)
+ || TREE_CODE (t) == TEMPLATE_PARM_INDEX
+ || TREE_CODE (t) == OVERLOAD
+ || BASELINK_P (t)
+ || identifier_p (t)
+ || TREE_CODE (t) == TRAIT_EXPR
+ || TREE_CODE (t) == CONSTRUCTOR
+ || CONSTANT_CLASS_P (t))
+ dependent_p = (type_dependent_expression_p (t)
+ || value_dependent_expression_p (t));
+ else
+ {
+ gcc_assert (t == error_mark_node);
+ dependent_p = false;
+ }
+
+ processing_template_decl = saved_processing_template_decl;
+
+ return dependent_p;
+}
+
+/* Returns true iff current_function_decl is an incompletely instantiated
+ template. Useful instead of processing_template_decl because the latter
+ is set to 0 during fold_non_dependent_expr. */
+
+bool
+in_template_function (void)
+{
+ tree fn = current_function_decl;
+ bool ret;
+ ++processing_template_decl;
+ ret = (fn && DECL_LANG_SPECIFIC (fn)
+ && DECL_TEMPLATE_INFO (fn)
+ && any_dependent_template_arguments_p (DECL_TI_ARGS (fn)));
+ --processing_template_decl;
+ return ret;
+}
+
+/* Returns true if T depends on any template parameter with level LEVEL. */
+
+int
+uses_template_parms_level (tree t, int level)
+{
+ return for_each_template_parm (t, template_parm_this_level_p, &level, NULL,
+ /*include_nondeduced_p=*/true);
+}
+
+/* Returns TRUE iff INST is an instantiation we don't need to do in an
+ ill-formed translation unit, i.e. a variable or function that isn't
+ usable in a constant expression. */
+
+static inline bool
+neglectable_inst_p (tree d)
+{
+ return (DECL_P (d)
+ && !(TREE_CODE (d) == FUNCTION_DECL ? DECL_DECLARED_CONSTEXPR_P (d)
+ : decl_maybe_constant_var_p (d)));
+}
+
+/* Returns TRUE iff we should refuse to instantiate DECL because it's
+ neglectable and instantiated from within an erroneous instantiation. */
+
+static bool
+limit_bad_template_recursion (tree decl)
+{
+ struct tinst_level *lev = current_tinst_level;
+ int errs = errorcount + sorrycount;
+ if (lev == NULL || errs == 0 || !neglectable_inst_p (decl))
+ return false;
+
+ for (; lev; lev = lev->next)
+ if (neglectable_inst_p (lev->decl))
+ break;
+
+ return (lev && errs > lev->errors);
+}
+
+static int tinst_depth;
+extern int max_tinst_depth;
+int depth_reached;
+
+static GTY(()) struct tinst_level *last_error_tinst_level;
+
+/* We're starting to instantiate D; record the template instantiation context
+ for diagnostics and to restore it later. */
+
+int
+push_tinst_level (tree d)
+{
+ struct tinst_level *new_level;
+
+ if (tinst_depth >= max_tinst_depth)
+ {
+ last_error_tinst_level = current_tinst_level;
+ if (TREE_CODE (d) == TREE_LIST)
+ error ("template instantiation depth exceeds maximum of %d (use "
+ "-ftemplate-depth= to increase the maximum) substituting %qS",
+ max_tinst_depth, d);
+ else
+ error ("template instantiation depth exceeds maximum of %d (use "
+ "-ftemplate-depth= to increase the maximum) instantiating %qD",
+ max_tinst_depth, d);
+
+ print_instantiation_context ();
+
+ return 0;
+ }
+
+ /* If the current instantiation caused problems, don't let it instantiate
+ anything else. Do allow deduction substitution and decls usable in
+ constant expressions. */
+ if (limit_bad_template_recursion (d))
+ return 0;
+
+ new_level = ggc_alloc_tinst_level ();
+ new_level->decl = d;
+ new_level->locus = input_location;
+ new_level->errors = errorcount+sorrycount;
+ new_level->in_system_header_p = in_system_header_at (input_location);
+ new_level->next = current_tinst_level;
+ current_tinst_level = new_level;
+
+ ++tinst_depth;
+ if (GATHER_STATISTICS && (tinst_depth > depth_reached))
+ depth_reached = tinst_depth;
+
+ return 1;
+}
+
+/* We're done instantiating this template; return to the instantiation
+ context. */
+
+void
+pop_tinst_level (void)
+{
+ /* Restore the filename and line number stashed away when we started
+ this instantiation. */
+ input_location = current_tinst_level->locus;
+ current_tinst_level = current_tinst_level->next;
+ --tinst_depth;
+}
+
+/* We're instantiating a deferred template; restore the template
+ instantiation context in which the instantiation was requested, which
+ is one step out from LEVEL. Return the corresponding DECL or TYPE. */
+
+static tree
+reopen_tinst_level (struct tinst_level *level)
+{
+ struct tinst_level *t;
+
+ tinst_depth = 0;
+ for (t = level; t; t = t->next)
+ ++tinst_depth;
+
+ current_tinst_level = level;
+ pop_tinst_level ();
+ if (current_tinst_level)
+ current_tinst_level->errors = errorcount+sorrycount;
+ return level->decl;
+}
+
+/* Returns the TINST_LEVEL which gives the original instantiation
+ context. */
+
+struct tinst_level *
+outermost_tinst_level (void)
+{
+ struct tinst_level *level = current_tinst_level;
+ if (level)
+ while (level->next)
+ level = level->next;
+ return level;
+}
+
+/* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the
+ vector of template arguments, as for tsubst.
+
+ Returns an appropriate tsubst'd friend declaration. */
+
+static tree
+tsubst_friend_function (tree decl, tree args)
+{
+ tree new_friend;
+
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_TEMPLATE_INSTANTIATION (decl)
+ && TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL)
+ /* This was a friend declared with an explicit template
+ argument list, e.g.:
+
+ friend void f<>(T);
+
+ to indicate that f was a template instantiation, not a new
+ function declaration. Now, we have to figure out what
+ instantiation of what template. */
+ {
+ tree template_id, arglist, fns;
+ tree new_args;
+ tree tmpl;
+ tree ns = decl_namespace_context (TYPE_MAIN_DECL (current_class_type));
+
+ /* Friend functions are looked up in the containing namespace scope.
+ We must enter that scope, to avoid finding member functions of the
+ current class with same name. */
+ push_nested_namespace (ns);
+ fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args,
+ tf_warning_or_error, NULL_TREE,
+ /*integral_constant_expression_p=*/false);
+ pop_nested_namespace (ns);
+ arglist = tsubst (DECL_TI_ARGS (decl), args,
+ tf_warning_or_error, NULL_TREE);
+ template_id = lookup_template_function (fns, arglist);
+
+ new_friend = tsubst (decl, args, tf_warning_or_error, NULL_TREE);
+ tmpl = determine_specialization (template_id, new_friend,
+ &new_args,
+ /*need_member_template=*/0,
+ TREE_VEC_LENGTH (args),
+ tsk_none);
+ return instantiate_template (tmpl, new_args, tf_error);
+ }
+
+ new_friend = tsubst (decl, args, tf_warning_or_error, NULL_TREE);
+
+ /* The NEW_FRIEND will look like an instantiation, to the
+ compiler, but is not an instantiation from the point of view of
+ the language. For example, we might have had:
+
+ template <class T> struct S {
+ template <class U> friend void f(T, U);
+ };
+
+ Then, in S<int>, template <class U> void f(int, U) is not an
+ instantiation of anything. */
+ if (new_friend == error_mark_node)
+ return error_mark_node;
+
+ DECL_USE_TEMPLATE (new_friend) = 0;
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ {
+ DECL_USE_TEMPLATE (DECL_TEMPLATE_RESULT (new_friend)) = 0;
+ DECL_SAVED_TREE (DECL_TEMPLATE_RESULT (new_friend))
+ = DECL_SAVED_TREE (DECL_TEMPLATE_RESULT (decl));
+ }
+
+ /* The mangled name for the NEW_FRIEND is incorrect. The function
+ is not a template instantiation and should not be mangled like
+ one. Therefore, we forget the mangling here; we'll recompute it
+ later if we need it. */
+ if (TREE_CODE (new_friend) != TEMPLATE_DECL)
+ {
+ SET_DECL_RTL (new_friend, NULL);
+ SET_DECL_ASSEMBLER_NAME (new_friend, NULL_TREE);
+ }
+
+ if (DECL_NAMESPACE_SCOPE_P (new_friend))
+ {
+ tree old_decl;
+ tree new_friend_template_info;
+ tree new_friend_result_template_info;
+ tree ns;
+ int new_friend_is_defn;
+
+ /* We must save some information from NEW_FRIEND before calling
+ duplicate decls since that function will free NEW_FRIEND if
+ possible. */
+ new_friend_template_info = DECL_TEMPLATE_INFO (new_friend);
+ new_friend_is_defn =
+ (DECL_INITIAL (DECL_TEMPLATE_RESULT
+ (template_for_substitution (new_friend)))
+ != NULL_TREE);
+ if (TREE_CODE (new_friend) == TEMPLATE_DECL)
+ {
+ /* This declaration is a `primary' template. */
+ DECL_PRIMARY_TEMPLATE (new_friend) = new_friend;
+
+ new_friend_result_template_info
+ = DECL_TEMPLATE_INFO (DECL_TEMPLATE_RESULT (new_friend));
+ }
+ else
+ new_friend_result_template_info = NULL_TREE;
+
+ /* Make the init_value nonzero so pushdecl knows this is a defn. */
+ if (new_friend_is_defn)
+ DECL_INITIAL (new_friend) = error_mark_node;
+
+ /* Inside pushdecl_namespace_level, we will push into the
+ current namespace. However, the friend function should go
+ into the namespace of the template. */
+ ns = decl_namespace_context (new_friend);
+ push_nested_namespace (ns);
+ old_decl = pushdecl_namespace_level (new_friend, /*is_friend=*/true);
+ pop_nested_namespace (ns);
+
+ if (old_decl == error_mark_node)
+ return error_mark_node;
+
+ if (old_decl != new_friend)
+ {
+ /* This new friend declaration matched an existing
+ declaration. For example, given:
+
+ template <class T> void f(T);
+ template <class U> class C {
+ template <class T> friend void f(T) {}
+ };
+
+ the friend declaration actually provides the definition
+ of `f', once C has been instantiated for some type. So,
+ old_decl will be the out-of-class template declaration,
+ while new_friend is the in-class definition.
+
+ But, if `f' was called before this point, the
+ instantiation of `f' will have DECL_TI_ARGS corresponding
+ to `T' but not to `U', references to which might appear
+ in the definition of `f'. Previously, the most general
+ template for an instantiation of `f' was the out-of-class
+ version; now it is the in-class version. Therefore, we
+ run through all specialization of `f', adding to their
+ DECL_TI_ARGS appropriately. In particular, they need a
+ new set of outer arguments, corresponding to the
+ arguments for this class instantiation.
+
+ The same situation can arise with something like this:
+
+ friend void f(int);
+ template <class T> class C {
+ friend void f(T) {}
+ };
+
+ when `C<int>' is instantiated. Now, `f(int)' is defined
+ in the class. */
+
+ if (!new_friend_is_defn)
+ /* On the other hand, if the in-class declaration does
+ *not* provide a definition, then we don't want to alter
+ existing definitions. We can just leave everything
+ alone. */
+ ;
+ else
+ {
+ tree new_template = TI_TEMPLATE (new_friend_template_info);
+ tree new_args = TI_ARGS (new_friend_template_info);
+
+ /* Overwrite whatever template info was there before, if
+ any, with the new template information pertaining to
+ the declaration. */
+ DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
+
+ if (TREE_CODE (old_decl) != TEMPLATE_DECL)
+ {
+ /* We should have called reregister_specialization in
+ duplicate_decls. */
+ gcc_assert (retrieve_specialization (new_template,
+ new_args, 0)
+ == old_decl);
+
+ /* Instantiate it if the global has already been used. */
+ if (DECL_ODR_USED (old_decl))
+ instantiate_decl (old_decl, /*defer_ok=*/true,
+ /*expl_inst_class_mem_p=*/false);
+ }
+ else
+ {
+ tree t;
+
+ /* Indicate that the old function template is a partial
+ instantiation. */
+ DECL_TEMPLATE_INFO (DECL_TEMPLATE_RESULT (old_decl))
+ = new_friend_result_template_info;
+
+ gcc_assert (new_template
+ == most_general_template (new_template));
+ gcc_assert (new_template != old_decl);
+
+ /* Reassign any specializations already in the hash table
+ to the new more general template, and add the
+ additional template args. */
+ for (t = DECL_TEMPLATE_INSTANTIATIONS (old_decl);
+ t != NULL_TREE;
+ t = TREE_CHAIN (t))
+ {
+ tree spec = TREE_VALUE (t);
+ spec_entry elt;
+
+ elt.tmpl = old_decl;
+ elt.args = DECL_TI_ARGS (spec);
+ elt.spec = NULL_TREE;
+
+ htab_remove_elt (decl_specializations, &elt);
+
+ DECL_TI_ARGS (spec)
+ = add_outermost_template_args (new_args,
+ DECL_TI_ARGS (spec));
+
+ register_specialization
+ (spec, new_template, DECL_TI_ARGS (spec), true, 0);
+
+ }
+ DECL_TEMPLATE_INSTANTIATIONS (old_decl) = NULL_TREE;
+ }
+ }
+
+ /* The information from NEW_FRIEND has been merged into OLD_DECL
+ by duplicate_decls. */
+ new_friend = old_decl;
+ }
+ }
+ else
+ {
+ tree context = DECL_CONTEXT (new_friend);
+ bool dependent_p;
+
+ /* In the code
+ template <class T> class C {
+ template <class U> friend void C1<U>::f (); // case 1
+ friend void C2<T>::f (); // case 2
+ };
+ we only need to make sure CONTEXT is a complete type for
+ case 2. To distinguish between the two cases, we note that
+ CONTEXT of case 1 remains dependent type after tsubst while
+ this isn't true for case 2. */
+ ++processing_template_decl;
+ dependent_p = dependent_type_p (context);
+ --processing_template_decl;
+
+ if (!dependent_p
+ && !complete_type_or_else (context, NULL_TREE))
+ return error_mark_node;
+
+ if (COMPLETE_TYPE_P (context))
+ {
+ tree fn = new_friend;
+ /* do_friend adds the TEMPLATE_DECL for any member friend
+ template even if it isn't a member template, i.e.
+ template <class T> friend A<T>::f();
+ Look through it in that case. */
+ if (TREE_CODE (fn) == TEMPLATE_DECL
+ && !PRIMARY_TEMPLATE_P (fn))
+ fn = DECL_TEMPLATE_RESULT (fn);
+ /* Check to see that the declaration is really present, and,
+ possibly obtain an improved declaration. */
+ fn = check_classfn (context, fn, NULL_TREE);
+
+ if (fn)
+ new_friend = fn;
+ }
+ }
+
+ return new_friend;
+}
+
+/* FRIEND_TMPL is a friend TEMPLATE_DECL. ARGS is the vector of
+ template arguments, as for tsubst.
+
+ Returns an appropriate tsubst'd friend type or error_mark_node on
+ failure. */
+
+static tree
+tsubst_friend_class (tree friend_tmpl, tree args)
+{
+ tree friend_type;
+ tree tmpl;
+ tree context;
+
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (friend_tmpl))
+ {
+ tree t = tsubst (TREE_TYPE (friend_tmpl), args, tf_none, NULL_TREE);
+ return TREE_TYPE (t);
+ }
+
+ context = CP_DECL_CONTEXT (friend_tmpl);
+
+ if (context != global_namespace)
+ {
+ if (TREE_CODE (context) == NAMESPACE_DECL)
+ push_nested_namespace (context);
+ else
+ push_nested_class (tsubst (context, args, tf_none, NULL_TREE));
+ }
+
+ /* Look for a class template declaration. We look for hidden names
+ because two friend declarations of the same template are the
+ same. For example, in:
+
+ struct A {
+ template <typename> friend class F;
+ };
+ template <typename> struct B {
+ template <typename> friend class F;
+ };
+
+ both F templates are the same. */
+ tmpl = lookup_name_real (DECL_NAME (friend_tmpl), 0, 0,
+ /*block_p=*/true, 0, LOOKUP_HIDDEN);
+
+ /* But, if we don't find one, it might be because we're in a
+ situation like this:
+
+ template <class T>
+ struct S {
+ template <class U>
+ friend struct S;
+ };
+
+ Here, in the scope of (say) S<int>, `S' is bound to a TYPE_DECL
+ for `S<int>', not the TEMPLATE_DECL. */
+ if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
+ {
+ tmpl = lookup_name_prefer_type (DECL_NAME (friend_tmpl), 1);
+ tmpl = maybe_get_template_decl_from_type_decl (tmpl);
+ }
+
+ if (tmpl && DECL_CLASS_TEMPLATE_P (tmpl))
+ {
+ /* The friend template has already been declared. Just
+ check to see that the declarations match, and install any new
+ default parameters. We must tsubst the default parameters,
+ of course. We only need the innermost template parameters
+ because that is all that redeclare_class_template will look
+ at. */
+ if (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (friend_tmpl))
+ > TMPL_ARGS_DEPTH (args))
+ {
+ tree parms;
+ location_t saved_input_location;
+ parms = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl),
+ args, tf_warning_or_error);
+
+ saved_input_location = input_location;
+ input_location = DECL_SOURCE_LOCATION (friend_tmpl);
+ redeclare_class_template (TREE_TYPE (tmpl), parms);
+ input_location = saved_input_location;
+
+ }
+
+ friend_type = TREE_TYPE (tmpl);
+ }
+ else
+ {
+ /* The friend template has not already been declared. In this
+ case, the instantiation of the template class will cause the
+ injection of this template into the global scope. */
+ tmpl = tsubst (friend_tmpl, args, tf_warning_or_error, NULL_TREE);
+ if (tmpl == error_mark_node)
+ return error_mark_node;
+
+ /* The new TMPL is not an instantiation of anything, so we
+ forget its origins. We don't reset CLASSTYPE_TI_TEMPLATE for
+ the new type because that is supposed to be the corresponding
+ template decl, i.e., TMPL. */
+ DECL_USE_TEMPLATE (tmpl) = 0;
+ DECL_TEMPLATE_INFO (tmpl) = NULL_TREE;
+ CLASSTYPE_USE_TEMPLATE (TREE_TYPE (tmpl)) = 0;
+ CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl))
+ = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl)));
+
+ /* Inject this template into the global scope. */
+ friend_type = TREE_TYPE (pushdecl_top_level_maybe_friend (tmpl, true));
+ }
+
+ if (context != global_namespace)
+ {
+ if (TREE_CODE (context) == NAMESPACE_DECL)
+ pop_nested_namespace (context);
+ else
+ pop_nested_class ();
+ }
+
+ return friend_type;
+}
+
+/* Returns zero if TYPE cannot be completed later due to circularity.
+ Otherwise returns one. */
+
+static int
+can_complete_type_without_circularity (tree type)
+{
+ if (type == NULL_TREE || type == error_mark_node)
+ return 0;
+ else if (COMPLETE_TYPE_P (type))
+ return 1;
+ else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
+ return can_complete_type_without_circularity (TREE_TYPE (type));
+ else if (CLASS_TYPE_P (type)
+ && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type)))
+ return 0;
+ else
+ return 1;
+}
+
+static tree tsubst_omp_clauses (tree, bool, tree, tsubst_flags_t, tree);
+
+/* Apply any attributes which had to be deferred until instantiation
+ time. DECL_P, ATTRIBUTES and ATTR_FLAGS are as cplus_decl_attributes;
+ ARGS, COMPLAIN, IN_DECL are as tsubst. */
+
+static void
+apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
+ tree args, tsubst_flags_t complain, tree in_decl)
+{
+ tree last_dep = NULL_TREE;
+ tree t;
+ tree *p;
+
+ for (t = attributes; t; t = TREE_CHAIN (t))
+ if (ATTR_IS_DEPENDENT (t))
+ {
+ last_dep = t;
+ attributes = copy_list (attributes);
+ break;
+ }
+
+ if (DECL_P (*decl_p))
+ {
+ if (TREE_TYPE (*decl_p) == error_mark_node)
+ return;
+ p = &DECL_ATTRIBUTES (*decl_p);
+ }
+ else
+ p = &TYPE_ATTRIBUTES (*decl_p);
+
+ if (last_dep)
+ {
+ tree late_attrs = NULL_TREE;
+ tree *q = &late_attrs;
+
+ for (*p = attributes; *p; )
+ {
+ t = *p;
+ if (ATTR_IS_DEPENDENT (t))
+ {
+ *p = TREE_CHAIN (t);
+ TREE_CHAIN (t) = NULL_TREE;
+ if ((flag_openmp || flag_cilkplus)
+ && is_attribute_p ("omp declare simd",
+ get_attribute_name (t))
+ && TREE_VALUE (t))
+ {
+ tree clauses = TREE_VALUE (TREE_VALUE (t));
+ clauses = tsubst_omp_clauses (clauses, true, args,
+ complain, in_decl);
+ c_omp_declare_simd_clauses_to_decls (*decl_p, clauses);
+ clauses = finish_omp_clauses (clauses);
+ tree parms = DECL_ARGUMENTS (*decl_p);
+ clauses
+ = c_omp_declare_simd_clauses_to_numbers (parms, clauses);
+ if (clauses)
+ TREE_VALUE (TREE_VALUE (t)) = clauses;
+ else
+ TREE_VALUE (t) = NULL_TREE;
+ }
+ /* If the first attribute argument is an identifier, don't
+ pass it through tsubst. Attributes like mode, format,
+ cleanup and several target specific attributes expect it
+ unmodified. */
+ else if (attribute_takes_identifier_p (get_attribute_name (t))
+ && TREE_VALUE (t))
+ {
+ tree chain
+ = tsubst_expr (TREE_CHAIN (TREE_VALUE (t)), args, complain,
+ in_decl,
+ /*integral_constant_expression_p=*/false);
+ if (chain != TREE_CHAIN (TREE_VALUE (t)))
+ TREE_VALUE (t)
+ = tree_cons (NULL_TREE, TREE_VALUE (TREE_VALUE (t)),
+ chain);
+ }
+ else
+ TREE_VALUE (t)
+ = tsubst_expr (TREE_VALUE (t), args, complain, in_decl,
+ /*integral_constant_expression_p=*/false);
+ *q = t;
+ q = &TREE_CHAIN (t);
+ }
+ else
+ p = &TREE_CHAIN (t);
+ }
+
+ cplus_decl_attributes (decl_p, late_attrs, attr_flags);
+ }
+}
+
+/* Perform (or defer) access check for typedefs that were referenced
+ from within the template TMPL code.
+ This is a subroutine of instantiate_decl and instantiate_class_template.
+ TMPL is the template to consider and TARGS is the list of arguments of
+ that template. */
+
+static void
+perform_typedefs_access_check (tree tmpl, tree targs)
+{
+ location_t saved_location;
+ unsigned i;
+ qualified_typedef_usage_t *iter;
+
+ if (!tmpl
+ || (!CLASS_TYPE_P (tmpl)
+ && TREE_CODE (tmpl) != FUNCTION_DECL))
+ return;
+
+ saved_location = input_location;
+ FOR_EACH_VEC_SAFE_ELT (get_types_needing_access_check (tmpl), i, iter)
+ {
+ tree type_decl = iter->typedef_decl;
+ tree type_scope = iter->context;
+
+ if (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope))
+ continue;
+
+ if (uses_template_parms (type_decl))
+ type_decl = tsubst (type_decl, targs, tf_error, NULL_TREE);
+ if (uses_template_parms (type_scope))
+ type_scope = tsubst (type_scope, targs, tf_error, NULL_TREE);
+
+ /* Make access check error messages point to the location
+ of the use of the typedef. */
+ input_location = iter->locus;
+ perform_or_defer_access_check (TYPE_BINFO (type_scope),
+ type_decl, type_decl,
+ tf_warning_or_error);
+ }
+ input_location = saved_location;
+}
+
+static tree
+instantiate_class_template_1 (tree type)
+{
+ tree templ, args, pattern, t, member;
+ tree typedecl;
+ tree pbinfo;
+ tree base_list;
+ unsigned int saved_maximum_field_alignment;
+ tree fn_context;
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ if (COMPLETE_OR_OPEN_TYPE_P (type)
+ || uses_template_parms (type))
+ return type;
+
+ /* Figure out which template is being instantiated. */
+ templ = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
+ gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL);
+
+ /* Determine what specialization of the original template to
+ instantiate. */
+ t = most_specialized_class (type, tf_warning_or_error);
+ if (t == error_mark_node)
+ {
+ TYPE_BEING_DEFINED (type) = 1;
+ return error_mark_node;
+ }
+ else if (t)
+ {
+ /* This TYPE is actually an instantiation of a partial
+ specialization. We replace the innermost set of ARGS with
+ the arguments appropriate for substitution. For example,
+ given:
+
+ template <class T> struct S {};
+ template <class T> struct S<T*> {};
+
+ and supposing that we are instantiating S<int*>, ARGS will
+ presently be {int*} -- but we need {int}. */
+ pattern = TREE_TYPE (t);
+ args = TREE_PURPOSE (t);
+ }
+ else
+ {
+ pattern = TREE_TYPE (templ);
+ args = CLASSTYPE_TI_ARGS (type);
+ }
+
+ /* If the template we're instantiating is incomplete, then clearly
+ there's nothing we can do. */
+ if (!COMPLETE_TYPE_P (pattern))
+ return type;
+
+ /* If we've recursively instantiated too many templates, stop. */
+ if (! push_tinst_level (type))
+ return type;
+
+ /* Now we're really doing the instantiation. Mark the type as in
+ the process of being defined. */
+ TYPE_BEING_DEFINED (type) = 1;
+
+ /* We may be in the middle of deferred access check. Disable
+ it now. */
+ push_deferring_access_checks (dk_no_deferred);
+
+ fn_context = decl_function_context (TYPE_MAIN_DECL (type));
+ if (!fn_context)
+ push_to_top_level ();
+ /* Use #pragma pack from the template context. */
+ saved_maximum_field_alignment = maximum_field_alignment;
+ maximum_field_alignment = TYPE_PRECISION (pattern);
+
+ SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
+
+ /* Set the input location to the most specialized template definition.
+ This is needed if tsubsting causes an error. */
+ typedecl = TYPE_MAIN_DECL (pattern);
+ input_location = DECL_SOURCE_LOCATION (TYPE_NAME (type)) =
+ DECL_SOURCE_LOCATION (typedecl);
+
+ TYPE_PACKED (type) = TYPE_PACKED (pattern);
+ TYPE_ALIGN (type) = TYPE_ALIGN (pattern);
+ TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (pattern);
+ TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */
+ if (ANON_AGGR_TYPE_P (pattern))
+ SET_ANON_AGGR_TYPE_P (type);
+ if (CLASSTYPE_VISIBILITY_SPECIFIED (pattern))
+ {
+ CLASSTYPE_VISIBILITY_SPECIFIED (type) = 1;
+ CLASSTYPE_VISIBILITY (type) = CLASSTYPE_VISIBILITY (pattern);
+ /* Adjust visibility for template arguments. */
+ determine_visibility (TYPE_MAIN_DECL (type));
+ }
+ if (CLASS_TYPE_P (type))
+ CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern);
+
+ pbinfo = TYPE_BINFO (pattern);
+
+ /* We should never instantiate a nested class before its enclosing
+ class; we need to look up the nested class by name before we can
+ instantiate it, and that lookup should instantiate the enclosing
+ class. */
+ gcc_assert (!DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (pattern))
+ || COMPLETE_OR_OPEN_TYPE_P (TYPE_CONTEXT (type)));
+
+ base_list = NULL_TREE;
+ if (BINFO_N_BASE_BINFOS (pbinfo))
+ {
+ tree pbase_binfo;
+ tree pushed_scope;
+ int i;
+
+ /* We must enter the scope containing the type, as that is where
+ the accessibility of types named in dependent bases are
+ looked up from. */
+ pushed_scope = push_scope (CP_TYPE_CONTEXT (type));
+
+ /* Substitute into each of the bases to determine the actual
+ basetypes. */
+ for (i = 0; BINFO_BASE_ITERATE (pbinfo, i, pbase_binfo); i++)
+ {
+ tree base;
+ tree access = BINFO_BASE_ACCESS (pbinfo, i);
+ tree expanded_bases = NULL_TREE;
+ int idx, len = 1;
+
+ if (PACK_EXPANSION_P (BINFO_TYPE (pbase_binfo)))
+ {
+ expanded_bases =
+ tsubst_pack_expansion (BINFO_TYPE (pbase_binfo),
+ args, tf_error, NULL_TREE);
+ if (expanded_bases == error_mark_node)
+ continue;
+
+ len = TREE_VEC_LENGTH (expanded_bases);
+ }
+
+ for (idx = 0; idx < len; idx++)
+ {
+ if (expanded_bases)
+ /* Extract the already-expanded base class. */
+ base = TREE_VEC_ELT (expanded_bases, idx);
+ else
+ /* Substitute to figure out the base class. */
+ base = tsubst (BINFO_TYPE (pbase_binfo), args, tf_error,
+ NULL_TREE);
+
+ if (base == error_mark_node)
+ continue;
+
+ base_list = tree_cons (access, base, base_list);
+ if (BINFO_VIRTUAL_P (pbase_binfo))
+ TREE_TYPE (base_list) = integer_type_node;
+ }
+ }
+
+ /* The list is now in reverse order; correct that. */
+ base_list = nreverse (base_list);
+
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ }
+ /* Now call xref_basetypes to set up all the base-class
+ information. */
+ xref_basetypes (type, base_list);
+
+ apply_late_template_attributes (&type, TYPE_ATTRIBUTES (pattern),
+ (int) ATTR_FLAG_TYPE_IN_PLACE,
+ args, tf_error, NULL_TREE);
+ fixup_attribute_variants (type);
+
+ /* Now that our base classes are set up, enter the scope of the
+ class, so that name lookups into base classes, etc. will work
+ correctly. This is precisely analogous to what we do in
+ begin_class_definition when defining an ordinary non-template
+ class, except we also need to push the enclosing classes. */
+ push_nested_class (type);
+
+ /* Now members are processed in the order of declaration. */
+ for (member = CLASSTYPE_DECL_LIST (pattern);
+ member; member = TREE_CHAIN (member))
+ {
+ tree t = TREE_VALUE (member);
+
+ if (TREE_PURPOSE (member))
+ {
+ if (TYPE_P (t))
+ {
+ /* Build new CLASSTYPE_NESTED_UTDS. */
+
+ tree newtag;
+ bool class_template_p;
+
+ class_template_p = (TREE_CODE (t) != ENUMERAL_TYPE
+ && TYPE_LANG_SPECIFIC (t)
+ && CLASSTYPE_IS_TEMPLATE (t));
+ /* If the member is a class template, then -- even after
+ substitution -- there may be dependent types in the
+ template argument list for the class. We increment
+ PROCESSING_TEMPLATE_DECL so that dependent_type_p, as
+ that function will assume that no types are dependent
+ when outside of a template. */
+ if (class_template_p)
+ ++processing_template_decl;
+ newtag = tsubst (t, args, tf_error, NULL_TREE);
+ if (class_template_p)
+ --processing_template_decl;
+ if (newtag == error_mark_node)
+ continue;
+
+ if (TREE_CODE (newtag) != ENUMERAL_TYPE)
+ {
+ tree name = TYPE_IDENTIFIER (t);
+
+ if (class_template_p)
+ /* Unfortunately, lookup_template_class sets
+ CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
+ instantiation (i.e., for the type of a member
+ template class nested within a template class.)
+ This behavior is required for
+ maybe_process_partial_specialization to work
+ correctly, but is not accurate in this case;
+ the TAG is not an instantiation of anything.
+ (The corresponding TEMPLATE_DECL is an
+ instantiation, but the TYPE is not.) */
+ CLASSTYPE_USE_TEMPLATE (newtag) = 0;
+
+ /* Now, we call pushtag to put this NEWTAG into the scope of
+ TYPE. We first set up the IDENTIFIER_TYPE_VALUE to avoid
+ pushtag calling push_template_decl. We don't have to do
+ this for enums because it will already have been done in
+ tsubst_enum. */
+ if (name)
+ SET_IDENTIFIER_TYPE_VALUE (name, newtag);
+ pushtag (name, newtag, /*tag_scope=*/ts_current);
+ }
+ }
+ else if (DECL_DECLARES_FUNCTION_P (t))
+ {
+ /* Build new TYPE_METHODS. */
+ tree r;
+
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ ++processing_template_decl;
+ r = tsubst (t, args, tf_error, NULL_TREE);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ --processing_template_decl;
+ set_current_access_from_decl (r);
+ finish_member_declaration (r);
+ /* Instantiate members marked with attribute used. */
+ if (r != error_mark_node && DECL_PRESERVE_P (r))
+ mark_used (r);
+ if (TREE_CODE (r) == FUNCTION_DECL
+ && DECL_OMP_DECLARE_REDUCTION_P (r))
+ cp_check_omp_declare_reduction (r);
+ }
+ else
+ {
+ /* Build new TYPE_FIELDS. */
+ if (TREE_CODE (t) == STATIC_ASSERT)
+ {
+ tree condition;
+
+ ++c_inhibit_evaluation_warnings;
+ condition =
+ tsubst_expr (STATIC_ASSERT_CONDITION (t), args,
+ tf_warning_or_error, NULL_TREE,
+ /*integral_constant_expression_p=*/true);
+ --c_inhibit_evaluation_warnings;
+
+ finish_static_assert (condition,
+ STATIC_ASSERT_MESSAGE (t),
+ STATIC_ASSERT_SOURCE_LOCATION (t),
+ /*member_p=*/true);
+ }
+ else if (TREE_CODE (t) != CONST_DECL)
+ {
+ tree r;
+ tree vec = NULL_TREE;
+ int len = 1;
+
+ /* The file and line for this declaration, to
+ assist in error message reporting. Since we
+ called push_tinst_level above, we don't need to
+ restore these. */
+ input_location = DECL_SOURCE_LOCATION (t);
+
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ ++processing_template_decl;
+ r = tsubst (t, args, tf_warning_or_error, NULL_TREE);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ --processing_template_decl;
+
+ if (TREE_CODE (r) == TREE_VEC)
+ {
+ /* A capture pack became multiple fields. */
+ vec = r;
+ len = TREE_VEC_LENGTH (vec);
+ }
+
+ for (int i = 0; i < len; ++i)
+ {
+ if (vec)
+ r = TREE_VEC_ELT (vec, i);
+ if (VAR_P (r))
+ {
+ /* In [temp.inst]:
+
+ [t]he initialization (and any associated
+ side-effects) of a static data member does
+ not occur unless the static data member is
+ itself used in a way that requires the
+ definition of the static data member to
+ exist.
+
+ Therefore, we do not substitute into the
+ initialized for the static data member here. */
+ finish_static_data_member_decl
+ (r,
+ /*init=*/NULL_TREE,
+ /*init_const_expr_p=*/false,
+ /*asmspec_tree=*/NULL_TREE,
+ /*flags=*/0);
+ /* Instantiate members marked with attribute used. */
+ if (r != error_mark_node && DECL_PRESERVE_P (r))
+ mark_used (r);
+ }
+ else if (TREE_CODE (r) == FIELD_DECL)
+ {
+ /* Determine whether R has a valid type and can be
+ completed later. If R is invalid, then its type
+ is replaced by error_mark_node. */
+ tree rtype = TREE_TYPE (r);
+ if (can_complete_type_without_circularity (rtype))
+ complete_type (rtype);
+
+ if (!COMPLETE_TYPE_P (rtype))
+ {
+ cxx_incomplete_type_error (r, rtype);
+ TREE_TYPE (r) = error_mark_node;
+ }
+ }
+
+ /* If it is a TYPE_DECL for a class-scoped ENUMERAL_TYPE,
+ such a thing will already have been added to the field
+ list by tsubst_enum in finish_member_declaration in the
+ CLASSTYPE_NESTED_UTDS case above. */
+ if (!(TREE_CODE (r) == TYPE_DECL
+ && TREE_CODE (TREE_TYPE (r)) == ENUMERAL_TYPE
+ && DECL_ARTIFICIAL (r)))
+ {
+ set_current_access_from_decl (r);
+ finish_member_declaration (r);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (TYPE_P (t) || DECL_CLASS_TEMPLATE_P (t)
+ || DECL_TEMPLATE_TEMPLATE_PARM_P (t))
+ {
+ /* Build new CLASSTYPE_FRIEND_CLASSES. */
+
+ tree friend_type = t;
+ bool adjust_processing_template_decl = false;
+
+ if (TREE_CODE (friend_type) == TEMPLATE_DECL)
+ {
+ /* template <class T> friend class C; */
+ friend_type = tsubst_friend_class (friend_type, args);
+ adjust_processing_template_decl = true;
+ }
+ else if (TREE_CODE (friend_type) == UNBOUND_CLASS_TEMPLATE)
+ {
+ /* template <class T> friend class C::D; */
+ friend_type = tsubst (friend_type, args,
+ tf_warning_or_error, NULL_TREE);
+ if (TREE_CODE (friend_type) == TEMPLATE_DECL)
+ friend_type = TREE_TYPE (friend_type);
+ adjust_processing_template_decl = true;
+ }
+ else if (TREE_CODE (friend_type) == TYPENAME_TYPE
+ || TREE_CODE (friend_type) == TEMPLATE_TYPE_PARM)
+ {
+ /* This could be either
+
+ friend class T::C;
+
+ when dependent_type_p is false or
+
+ template <class U> friend class T::C;
+
+ otherwise. */
+ friend_type = tsubst (friend_type, args,
+ tf_warning_or_error, NULL_TREE);
+ /* Bump processing_template_decl for correct
+ dependent_type_p calculation. */
+ ++processing_template_decl;
+ if (dependent_type_p (friend_type))
+ adjust_processing_template_decl = true;
+ --processing_template_decl;
+ }
+ else if (!CLASSTYPE_USE_TEMPLATE (friend_type)
+ && hidden_name_p (TYPE_NAME (friend_type)))
+ {
+ /* friend class C;
+
+ where C hasn't been declared yet. Let's lookup name
+ from namespace scope directly, bypassing any name that
+ come from dependent base class. */
+ tree ns = decl_namespace_context (TYPE_MAIN_DECL (friend_type));
+
+ /* The call to xref_tag_from_type does injection for friend
+ classes. */
+ push_nested_namespace (ns);
+ friend_type =
+ xref_tag_from_type (friend_type, NULL_TREE,
+ /*tag_scope=*/ts_current);
+ pop_nested_namespace (ns);
+ }
+ else if (uses_template_parms (friend_type))
+ /* friend class C<T>; */
+ friend_type = tsubst (friend_type, args,
+ tf_warning_or_error, NULL_TREE);
+ /* Otherwise it's
+
+ friend class C;
+
+ where C is already declared or
+
+ friend class C<int>;
+
+ We don't have to do anything in these cases. */
+
+ if (adjust_processing_template_decl)
+ /* Trick make_friend_class into realizing that the friend
+ we're adding is a template, not an ordinary class. It's
+ important that we use make_friend_class since it will
+ perform some error-checking and output cross-reference
+ information. */
+ ++processing_template_decl;
+
+ if (friend_type != error_mark_node)
+ make_friend_class (type, friend_type, /*complain=*/false);
+
+ if (adjust_processing_template_decl)
+ --processing_template_decl;
+ }
+ else
+ {
+ /* Build new DECL_FRIENDLIST. */
+ tree r;
+
+ /* The file and line for this declaration, to
+ assist in error message reporting. Since we
+ called push_tinst_level above, we don't need to
+ restore these. */
+ input_location = DECL_SOURCE_LOCATION (t);
+
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ {
+ ++processing_template_decl;
+ push_deferring_access_checks (dk_no_check);
+ }
+
+ r = tsubst_friend_function (t, args);
+ add_friend (type, r, /*complain=*/false);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ {
+ pop_deferring_access_checks ();
+ --processing_template_decl;
+ }
+ }
+ }
+ }
+
+ if (tree expr = CLASSTYPE_LAMBDA_EXPR (type))
+ {
+ tree decl = lambda_function (type);
+ if (decl)
+ {
+ if (!DECL_TEMPLATE_INFO (decl)
+ || DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl)) != decl)
+ instantiate_decl (decl, false, false);
+
+ /* We need to instantiate the capture list from the template
+ after we've instantiated the closure members, but before we
+ consider adding the conversion op. Also keep any captures
+ that may have been added during instantiation of the op(). */
+ tree tmpl_expr = CLASSTYPE_LAMBDA_EXPR (pattern);
+ tree tmpl_cap
+ = tsubst_copy_and_build (LAMBDA_EXPR_CAPTURE_LIST (tmpl_expr),
+ args, tf_warning_or_error, NULL_TREE,
+ false, false);
+
+ LAMBDA_EXPR_CAPTURE_LIST (expr)
+ = chainon (tmpl_cap, nreverse (LAMBDA_EXPR_CAPTURE_LIST (expr)));
+
+ maybe_add_lambda_conv_op (type);
+ }
+ else
+ gcc_assert (errorcount);
+ }
+
+ /* Set the file and line number information to whatever is given for
+ the class itself. This puts error messages involving generated
+ implicit functions at a predictable point, and the same point
+ that would be used for non-template classes. */
+ input_location = DECL_SOURCE_LOCATION (typedecl);
+
+ unreverse_member_declarations (type);
+ finish_struct_1 (type);
+ TYPE_BEING_DEFINED (type) = 0;
+
+ /* We don't instantiate default arguments for member functions. 14.7.1:
+
+ The implicit instantiation of a class template specialization causes
+ the implicit instantiation of the declarations, but not of the
+ definitions or default arguments, of the class member functions,
+ member classes, static data members and member templates.... */
+
+ /* Some typedefs referenced from within the template code need to be access
+ checked at template instantiation time, i.e now. These types were
+ added to the template at parsing time. Let's get those and perform
+ the access checks then. */
+ perform_typedefs_access_check (pattern, args);
+ perform_deferred_access_checks (tf_warning_or_error);
+ pop_nested_class ();
+ maximum_field_alignment = saved_maximum_field_alignment;
+ if (!fn_context)
+ pop_from_top_level ();
+ pop_deferring_access_checks ();
+ pop_tinst_level ();
+
+ /* The vtable for a template class can be emitted in any translation
+ unit in which the class is instantiated. When there is no key
+ method, however, finish_struct_1 will already have added TYPE to
+ the keyed_classes list. */
+ if (TYPE_CONTAINS_VPTR_P (type) && CLASSTYPE_KEY_METHOD (type))
+ keyed_classes = tree_cons (NULL_TREE, type, keyed_classes);
+
+ return type;
+}
+
+/* Wrapper for instantiate_class_template_1. */
+
+tree
+instantiate_class_template (tree type)
+{
+ tree ret;
+ timevar_push (TV_TEMPLATE_INST);
+ ret = instantiate_class_template_1 (type);
+ timevar_pop (TV_TEMPLATE_INST);
+ return ret;
+}
+
+static tree
+tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+{
+ tree r;
+
+ if (!t)
+ r = t;
+ else if (TYPE_P (t))
+ r = tsubst (t, args, complain, in_decl);
+ else
+ {
+ if (!(complain & tf_warning))
+ ++c_inhibit_evaluation_warnings;
+ r = tsubst_expr (t, args, complain, in_decl,
+ /*integral_constant_expression_p=*/true);
+ if (!(complain & tf_warning))
+ --c_inhibit_evaluation_warnings;
+ }
+ return r;
+}
+
+/* Given a function parameter pack TMPL_PARM and some function parameters
+ instantiated from it at *SPEC_P, return a NONTYPE_ARGUMENT_PACK of them
+ and set *SPEC_P to point at the next point in the list. */
+
+static tree
+extract_fnparm_pack (tree tmpl_parm, tree *spec_p)
+{
+ /* Collect all of the extra "packed" parameters into an
+ argument pack. */
+ tree parmvec;
+ tree parmtypevec;
+ tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
+ tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK);
+ tree spec_parm = *spec_p;
+ int i, len;
+
+ for (len = 0; spec_parm; ++len, spec_parm = TREE_CHAIN (spec_parm))
+ if (tmpl_parm
+ && !function_parameter_expanded_from_pack_p (spec_parm, tmpl_parm))
+ break;
+
+ /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */
+ parmvec = make_tree_vec (len);
+ parmtypevec = make_tree_vec (len);
+ spec_parm = *spec_p;
+ for (i = 0; i < len; i++, spec_parm = DECL_CHAIN (spec_parm))
+ {
+ TREE_VEC_ELT (parmvec, i) = spec_parm;
+ TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm);
+ }
+
+ /* Build the argument packs. */
+ SET_ARGUMENT_PACK_ARGS (argpack, parmvec);
+ SET_ARGUMENT_PACK_ARGS (argtypepack, parmtypevec);
+ TREE_TYPE (argpack) = argtypepack;
+ *spec_p = spec_parm;
+
+ return argpack;
+}
+
+/* Give a chain SPEC_PARM of PARM_DECLs, pack them into a
+ NONTYPE_ARGUMENT_PACK. */
+
+static tree
+make_fnparm_pack (tree spec_parm)
+{
+ return extract_fnparm_pack (NULL_TREE, &spec_parm);
+}
+
+/* Return true iff the Ith element of the argument pack ARG_PACK is a
+ pack expansion. */
+
+static bool
+argument_pack_element_is_expansion_p (tree arg_pack, int i)
+{
+ tree vec = ARGUMENT_PACK_ARGS (arg_pack);
+ if (i >= TREE_VEC_LENGTH (vec))
+ return false;
+ return PACK_EXPANSION_P (TREE_VEC_ELT (vec, i));
+}
+
+
+/* Creates and return an ARGUMENT_PACK_SELECT tree node. */
+
+static tree
+make_argument_pack_select (tree arg_pack, unsigned index)
+{
+ tree aps = make_node (ARGUMENT_PACK_SELECT);
+
+ ARGUMENT_PACK_SELECT_FROM_PACK (aps) = arg_pack;
+ ARGUMENT_PACK_SELECT_INDEX (aps) = index;
+
+ return aps;
+}
+
+/* This is a subroutine of tsubst_pack_expansion.
+
+ It returns TRUE if we need to use the PACK_EXPANSION_EXTRA_ARGS
+ mechanism to store the (non complete list of) arguments of the
+ substitution and return a non substituted pack expansion, in order
+ to wait for when we have enough arguments to really perform the
+ substitution. */
+
+static bool
+use_pack_expansion_extra_args_p (tree parm_packs,
+ int arg_pack_len,
+ bool has_empty_arg)
+{
+ /* If one pack has an expansion and another pack has a normal
+ argument or if one pack has an empty argument and an another
+ one hasn't then tsubst_pack_expansion cannot perform the
+ substitution and need to fall back on the
+ PACK_EXPANSION_EXTRA mechanism. */
+ if (parm_packs == NULL_TREE)
+ return false;
+ else if (has_empty_arg)
+ return true;
+
+ bool has_expansion_arg = false;
+ for (int i = 0 ; i < arg_pack_len; ++i)
+ {
+ bool has_non_expansion_arg = false;
+ for (tree parm_pack = parm_packs;
+ parm_pack;
+ parm_pack = TREE_CHAIN (parm_pack))
+ {
+ tree arg = TREE_VALUE (parm_pack);
+
+ if (argument_pack_element_is_expansion_p (arg, i))
+ has_expansion_arg = true;
+ else
+ has_non_expansion_arg = true;
+ }
+
+ if (has_expansion_arg && has_non_expansion_arg)
+ return true;
+ }
+ return false;
+}
+
+/* [temp.variadic]/6 says that:
+
+ The instantiation of a pack expansion [...]
+ produces a list E1,E2, ..., En, where N is the number of elements
+ in the pack expansion parameters.
+
+ This subroutine of tsubst_pack_expansion produces one of these Ei.
+
+ PATTERN is the pattern of the pack expansion. PARM_PACKS is a
+ TREE_LIST in which each TREE_PURPOSE is a parameter pack of
+ PATTERN, and each TREE_VALUE is its corresponding argument pack.
+ INDEX is the index 'i' of the element Ei to produce. ARGS,
+ COMPLAIN, and IN_DECL are the same parameters as for the
+ tsubst_pack_expansion function.
+
+ The function returns the resulting Ei upon successful completion,
+ or error_mark_node.
+
+ Note that this function possibly modifies the ARGS parameter, so
+ it's the responsibility of the caller to restore it. */
+
+static tree
+gen_elem_of_pack_expansion_instantiation (tree pattern,
+ tree parm_packs,
+ unsigned index,
+ tree args /* This parm gets
+ modified. */,
+ tsubst_flags_t complain,
+ tree in_decl)
+{
+ tree t;
+ bool ith_elem_is_expansion = false;
+
+ /* For each parameter pack, change the substitution of the parameter
+ pack to the ith argument in its argument pack, then expand the
+ pattern. */
+ for (tree pack = parm_packs; pack; pack = TREE_CHAIN (pack))
+ {
+ tree parm = TREE_PURPOSE (pack);
+ tree arg_pack = TREE_VALUE (pack);
+ tree aps; /* instance of ARGUMENT_PACK_SELECT. */
+
+ ith_elem_is_expansion |=
+ argument_pack_element_is_expansion_p (arg_pack, index);
+
+ /* Select the Ith argument from the pack. */
+ if (TREE_CODE (parm) == PARM_DECL
+ || TREE_CODE (parm) == FIELD_DECL)
+ {
+ if (index == 0)
+ {
+ aps = make_argument_pack_select (arg_pack, index);
+ mark_used (parm);
+ register_local_specialization (aps, parm);
+ }
+ else
+ aps = retrieve_local_specialization (parm);
+ }
+ else
+ {
+ int idx, level;
+ template_parm_level_and_index (parm, &level, &idx);
+
+ if (index == 0)
+ {
+ aps = make_argument_pack_select (arg_pack, index);
+ /* Update the corresponding argument. */
+ TMPL_ARG (args, level, idx) = aps;
+ }
+ else
+ /* Re-use the ARGUMENT_PACK_SELECT. */
+ aps = TMPL_ARG (args, level, idx);
+ }
+ ARGUMENT_PACK_SELECT_INDEX (aps) = index;
+ }
+
+ /* Substitute into the PATTERN with the (possibly altered)
+ arguments. */
+ if (pattern == in_decl)
+ /* Expanding a fixed parameter pack from
+ coerce_template_parameter_pack. */
+ t = tsubst_decl (pattern, args, complain);
+ else if (!TYPE_P (pattern))
+ t = tsubst_expr (pattern, args, complain, in_decl,
+ /*integral_constant_expression_p=*/false);
+ else
+ t = tsubst (pattern, args, complain, in_decl);
+
+ /* If the Ith argument pack element is a pack expansion, then
+ the Ith element resulting from the substituting is going to
+ be a pack expansion as well. */
+ if (ith_elem_is_expansion)
+ t = make_pack_expansion (t);
+
+ return t;
+}
+
+/* Substitute ARGS into T, which is an pack expansion
+ (i.e. TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION). Returns a
+ TREE_VEC with the substituted arguments, a PACK_EXPANSION_* node
+ (if only a partial substitution could be performed) or
+ ERROR_MARK_NODE if there was an error. */
+tree
+tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
+ tree in_decl)
+{
+ tree pattern;
+ tree pack, packs = NULL_TREE;
+ bool unsubstituted_packs = false;
+ int i, len = -1;
+ tree result;
+ struct pointer_map_t *saved_local_specializations = NULL;
+ bool need_local_specializations = false;
+ int levels;
+
+ gcc_assert (PACK_EXPANSION_P (t));
+ pattern = PACK_EXPANSION_PATTERN (t);
+
+ /* Add in any args remembered from an earlier partial instantiation. */
+ args = add_to_template_args (PACK_EXPANSION_EXTRA_ARGS (t), args);
+
+ levels = TMPL_ARGS_DEPTH (args);
+
+ /* Determine the argument packs that will instantiate the parameter
+ packs used in the expansion expression. While we're at it,
+ compute the number of arguments to be expanded and make sure it
+ is consistent. */
+ for (pack = PACK_EXPANSION_PARAMETER_PACKS (t); pack;
+ pack = TREE_CHAIN (pack))
+ {
+ tree parm_pack = TREE_VALUE (pack);
+ tree arg_pack = NULL_TREE;
+ tree orig_arg = NULL_TREE;
+ int level = 0;
+
+ if (TREE_CODE (parm_pack) == BASES)
+ {
+ if (BASES_DIRECT (parm_pack))
+ return calculate_direct_bases (tsubst_expr (BASES_TYPE (parm_pack),
+ args, complain, in_decl, false));
+ else
+ return calculate_bases (tsubst_expr (BASES_TYPE (parm_pack),
+ args, complain, in_decl, false));
+ }
+ if (TREE_CODE (parm_pack) == PARM_DECL)
+ {
+ if (PACK_EXPANSION_LOCAL_P (t))
+ arg_pack = retrieve_local_specialization (parm_pack);
+ else
+ {
+ /* We can't rely on local_specializations for a parameter
+ name used later in a function declaration (such as in a
+ late-specified return type). Even if it exists, it might
+ have the wrong value for a recursive call. Just make a
+ dummy decl, since it's only used for its type. */
+ arg_pack = tsubst_decl (parm_pack, args, complain);
+ if (arg_pack && DECL_PACK_P (arg_pack))
+ /* Partial instantiation of the parm_pack, we can't build
+ up an argument pack yet. */
+ arg_pack = NULL_TREE;
+ else
+ arg_pack = make_fnparm_pack (arg_pack);
+ need_local_specializations = true;
+ }
+ }
+ else if (TREE_CODE (parm_pack) == FIELD_DECL)
+ arg_pack = tsubst_copy (parm_pack, args, complain, in_decl);
+ else
+ {
+ int idx;
+ template_parm_level_and_index (parm_pack, &level, &idx);
+
+ if (level <= levels)
+ arg_pack = TMPL_ARG (args, level, idx);
+ }
+
+ orig_arg = arg_pack;
+ if (arg_pack && TREE_CODE (arg_pack) == ARGUMENT_PACK_SELECT)
+ arg_pack = ARGUMENT_PACK_SELECT_FROM_PACK (arg_pack);
+
+ if (arg_pack && !ARGUMENT_PACK_P (arg_pack))
+ /* This can only happen if we forget to expand an argument
+ pack somewhere else. Just return an error, silently. */
+ {
+ result = make_tree_vec (1);
+ TREE_VEC_ELT (result, 0) = error_mark_node;
+ return result;
+ }
+
+ if (arg_pack)
+ {
+ int my_len =
+ TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack));
+
+ /* Don't bother trying to do a partial substitution with
+ incomplete packs; we'll try again after deduction. */
+ if (ARGUMENT_PACK_INCOMPLETE_P (arg_pack))
+ return t;
+
+ if (len < 0)
+ len = my_len;
+ else if (len != my_len)
+ {
+ if (!(complain & tf_error))
+ /* Fail quietly. */;
+ else if (TREE_CODE (t) == TYPE_PACK_EXPANSION)
+ error ("mismatched argument pack lengths while expanding "
+ "%<%T%>",
+ pattern);
+ else
+ error ("mismatched argument pack lengths while expanding "
+ "%<%E%>",
+ pattern);
+ return error_mark_node;
+ }
+
+ /* Keep track of the parameter packs and their corresponding
+ argument packs. */
+ packs = tree_cons (parm_pack, arg_pack, packs);
+ TREE_TYPE (packs) = orig_arg;
+ }
+ else
+ {
+ /* We can't substitute for this parameter pack. We use a flag as
+ well as the missing_level counter because function parameter
+ packs don't have a level. */
+ unsubstituted_packs = true;
+ }
+ }
+
+ /* We cannot expand this expansion expression, because we don't have
+ all of the argument packs we need. */
+ if (use_pack_expansion_extra_args_p (packs, len, unsubstituted_packs))
+ {
+ /* We got some full packs, but we can't substitute them in until we
+ have values for all the packs. So remember these until then. */
+
+ t = make_pack_expansion (pattern);
+ PACK_EXPANSION_EXTRA_ARGS (t) = args;
+ return t;
+ }
+ else if (unsubstituted_packs)
+ {
+ /* There were no real arguments, we're just replacing a parameter
+ pack with another version of itself. Substitute into the
+ pattern and return a PACK_EXPANSION_*. The caller will need to
+ deal with that. */
+ if (TREE_CODE (t) == EXPR_PACK_EXPANSION)
+ t = tsubst_expr (pattern, args, complain, in_decl,
+ /*integral_constant_expression_p=*/false);
+ else
+ t = tsubst (pattern, args, complain, in_decl);
+ t = make_pack_expansion (t);
+ return t;
+ }
+
+ gcc_assert (len >= 0);
+
+ if (need_local_specializations)
+ {
+ /* We're in a late-specified return type, so create our own local
+ specializations map; the current map is either NULL or (in the
+ case of recursive unification) might have bindings that we don't
+ want to use or alter. */
+ saved_local_specializations = local_specializations;
+ local_specializations = pointer_map_create ();
+ }
+
+ /* For each argument in each argument pack, substitute into the
+ pattern. */
+ result = make_tree_vec (len);
+ for (i = 0; i < len; ++i)
+ {
+ t = gen_elem_of_pack_expansion_instantiation (pattern, packs,
+ i,
+ args, complain,
+ in_decl);
+ TREE_VEC_ELT (result, i) = t;
+ if (t == error_mark_node)
+ {
+ result = error_mark_node;
+ break;
+ }
+ }
+
+ /* Update ARGS to restore the substitution from parameter packs to
+ their argument packs. */
+ for (pack = packs; pack; pack = TREE_CHAIN (pack))
+ {
+ tree parm = TREE_PURPOSE (pack);
+
+ if (TREE_CODE (parm) == PARM_DECL
+ || TREE_CODE (parm) == FIELD_DECL)
+ register_local_specialization (TREE_TYPE (pack), parm);
+ else
+ {
+ int idx, level;
+
+ if (TREE_VALUE (pack) == NULL_TREE)
+ continue;
+
+ template_parm_level_and_index (parm, &level, &idx);
+
+ /* Update the corresponding argument. */
+ if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
+ TREE_VEC_ELT (TREE_VEC_ELT (args, level -1 ), idx) =
+ TREE_TYPE (pack);
+ else
+ TREE_VEC_ELT (args, idx) = TREE_TYPE (pack);
+ }
+ }
+
+ if (need_local_specializations)
+ {
+ pointer_map_destroy (local_specializations);
+ local_specializations = saved_local_specializations;
+ }
+
+ return result;
+}
+
+/* Given PARM_DECL PARM, find the corresponding PARM_DECL in the template
+ TMPL. We do this using DECL_PARM_INDEX, which should work even with
+ parameter packs; all parms generated from a function parameter pack will
+ have the same DECL_PARM_INDEX. */
+
+tree
+get_pattern_parm (tree parm, tree tmpl)
+{
+ tree pattern = DECL_TEMPLATE_RESULT (tmpl);
+ tree patparm;
+
+ if (DECL_ARTIFICIAL (parm))
+ {
+ for (patparm = DECL_ARGUMENTS (pattern);
+ patparm; patparm = DECL_CHAIN (patparm))
+ if (DECL_ARTIFICIAL (patparm)
+ && DECL_NAME (parm) == DECL_NAME (patparm))
+ break;
+ }
+ else
+ {
+ patparm = FUNCTION_FIRST_USER_PARM (DECL_TEMPLATE_RESULT (tmpl));
+ patparm = chain_index (DECL_PARM_INDEX (parm)-1, patparm);
+ gcc_assert (DECL_PARM_INDEX (patparm)
+ == DECL_PARM_INDEX (parm));
+ }
+
+ return patparm;
+}
+
+/* Substitute ARGS into the vector or list of template arguments T. */
+
+static tree
+tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+{
+ tree orig_t = t;
+ int len, need_new = 0, i, expanded_len_adjust = 0, out;
+ tree *elts;
+
+ if (t == error_mark_node)
+ return error_mark_node;
+
+ len = TREE_VEC_LENGTH (t);
+ elts = XALLOCAVEC (tree, len);
+
+ for (i = 0; i < len; i++)
+ {
+ tree orig_arg = TREE_VEC_ELT (t, i);
+ tree new_arg;
+
+ if (TREE_CODE (orig_arg) == TREE_VEC)
+ new_arg = tsubst_template_args (orig_arg, args, complain, in_decl);
+ else if (PACK_EXPANSION_P (orig_arg))
+ {
+ /* Substitute into an expansion expression. */
+ new_arg = tsubst_pack_expansion (orig_arg, args, complain, in_decl);
+
+ if (TREE_CODE (new_arg) == TREE_VEC)
+ /* Add to the expanded length adjustment the number of
+ expanded arguments. We subtract one from this
+ measurement, because the argument pack expression
+ itself is already counted as 1 in
+ LEN. EXPANDED_LEN_ADJUST can actually be negative, if
+ the argument pack is empty. */
+ expanded_len_adjust += TREE_VEC_LENGTH (new_arg) - 1;
+ }
+ else if (ARGUMENT_PACK_P (orig_arg))
+ {
+ /* Substitute into each of the arguments. */
+ new_arg = TYPE_P (orig_arg)
+ ? cxx_make_type (TREE_CODE (orig_arg))
+ : make_node (TREE_CODE (orig_arg));
+
+ SET_ARGUMENT_PACK_ARGS (
+ new_arg,
+ tsubst_template_args (ARGUMENT_PACK_ARGS (orig_arg),
+ args, complain, in_decl));
+
+ if (ARGUMENT_PACK_ARGS (new_arg) == error_mark_node)
+ new_arg = error_mark_node;
+
+ if (TREE_CODE (new_arg) == NONTYPE_ARGUMENT_PACK) {
+ TREE_TYPE (new_arg) = tsubst (TREE_TYPE (orig_arg), args,
+ complain, in_decl);
+ TREE_CONSTANT (new_arg) = TREE_CONSTANT (orig_arg);
+
+ if (TREE_TYPE (new_arg) == error_mark_node)
+ new_arg = error_mark_node;
+ }
+ }
+ else
+ new_arg = tsubst_template_arg (orig_arg, args, complain, in_decl);
+
+ if (new_arg == error_mark_node)
+ return error_mark_node;
+
+ elts[i] = new_arg;
+ if (new_arg != orig_arg)
+ need_new = 1;
+ }
+
+ if (!need_new)
+ return t;
+
+ /* Make space for the expanded arguments coming from template
+ argument packs. */
+ t = make_tree_vec (len + expanded_len_adjust);
+ /* ORIG_T can contain TREE_VECs. That happens if ORIG_T contains the
+ arguments for a member template.
+ In that case each TREE_VEC in ORIG_T represents a level of template
+ arguments, and ORIG_T won't carry any non defaulted argument count.
+ It will rather be the nested TREE_VECs that will carry one.
+ In other words, ORIG_T carries a non defaulted argument count only
+ if it doesn't contain any nested TREE_VEC. */
+ if (NON_DEFAULT_TEMPLATE_ARGS_COUNT (orig_t))
+ {
+ int count = GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (orig_t);
+ count += expanded_len_adjust;
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (t, count);
+ }
+ for (i = 0, out = 0; i < len; i++)
+ {
+ if ((PACK_EXPANSION_P (TREE_VEC_ELT (orig_t, i))
+ || ARGUMENT_PACK_P (TREE_VEC_ELT (orig_t, i)))
+ && TREE_CODE (elts[i]) == TREE_VEC)
+ {
+ int idx;
+
+ /* Now expand the template argument pack "in place". */
+ for (idx = 0; idx < TREE_VEC_LENGTH (elts[i]); idx++, out++)
+ TREE_VEC_ELT (t, out) = TREE_VEC_ELT (elts[i], idx);
+ }
+ else
+ {
+ TREE_VEC_ELT (t, out) = elts[i];
+ out++;
+ }
+ }
+
+ return t;
+}
+
+/* Return the result of substituting ARGS into the template parameters
+ given by PARMS. If there are m levels of ARGS and m + n levels of
+ PARMS, then the result will contain n levels of PARMS. For
+ example, if PARMS is `template <class T> template <class U>
+ template <T*, U, class V>' and ARGS is {{int}, {double}} then the
+ result will be `template <int*, double, class V>'. */
+
+static tree
+tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
+{
+ tree r = NULL_TREE;
+ tree* new_parms;
+
+ /* When substituting into a template, we must set
+ PROCESSING_TEMPLATE_DECL as the template parameters may be
+ dependent if they are based on one-another, and the dependency
+ predicates are short-circuit outside of templates. */
+ ++processing_template_decl;
+
+ for (new_parms = &r;
+ parms && TMPL_PARMS_DEPTH (parms) > TMPL_ARGS_DEPTH (args);
+ new_parms = &(TREE_CHAIN (*new_parms)),
+ parms = TREE_CHAIN (parms))
+ {
+ tree new_vec =
+ make_tree_vec (TREE_VEC_LENGTH (TREE_VALUE (parms)));
+ int i;
+
+ for (i = 0; i < TREE_VEC_LENGTH (new_vec); ++i)
+ {
+ tree tuple;
+
+ if (parms == error_mark_node)
+ continue;
+
+ tuple = TREE_VEC_ELT (TREE_VALUE (parms), i);
+
+ if (tuple == error_mark_node)
+ continue;
+
+ TREE_VEC_ELT (new_vec, i) =
+ tsubst_template_parm (tuple, args, complain);
+ }
+
+ *new_parms =
+ tree_cons (size_int (TMPL_PARMS_DEPTH (parms)
+ - TMPL_ARGS_DEPTH (args)),
+ new_vec, NULL_TREE);
+ }
+
+ --processing_template_decl;
+
+ return r;
+}
+
+/* Return the result of substituting ARGS into one template parameter
+ given by T. T Must be a TREE_LIST which TREE_VALUE is the template
+ parameter and which TREE_PURPOSE is the default argument of the
+ template parameter. */
+
+static tree
+tsubst_template_parm (tree t, tree args, tsubst_flags_t complain)
+{
+ tree default_value, parm_decl;
+
+ if (args == NULL_TREE
+ || t == NULL_TREE
+ || t == error_mark_node)
+ return t;
+
+ gcc_assert (TREE_CODE (t) == TREE_LIST);
+
+ default_value = TREE_PURPOSE (t);
+ parm_decl = TREE_VALUE (t);
+
+ parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
+ if (TREE_CODE (parm_decl) == PARM_DECL
+ && invalid_nontype_parm_type_p (TREE_TYPE (parm_decl), complain))
+ parm_decl = error_mark_node;
+ default_value = tsubst_template_arg (default_value, args,
+ complain, NULL_TREE);
+
+ return build_tree_list (default_value, parm_decl);
+}
+
+/* Substitute the ARGS into the indicated aggregate (or enumeration)
+ type T. If T is not an aggregate or enumeration type, it is
+ handled as if by tsubst. IN_DECL is as for tsubst. If
+ ENTERING_SCOPE is nonzero, T is the context for a template which
+ we are presently tsubst'ing. Return the substituted value. */
+
+static tree
+tsubst_aggr_type (tree t,
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl,
+ int entering_scope)
+{
+ if (t == NULL_TREE)
+ return NULL_TREE;
+
+ switch (TREE_CODE (t))
+ {
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ return tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl);
+
+ /* Else fall through. */
+ case ENUMERAL_TYPE:
+ case UNION_TYPE:
+ if (TYPE_TEMPLATE_INFO (t) && uses_template_parms (t))
+ {
+ tree argvec;
+ tree context;
+ tree r;
+ int saved_unevaluated_operand;
+ int saved_inhibit_evaluation_warnings;
+
+ /* In "sizeof(X<I>)" we need to evaluate "I". */
+ saved_unevaluated_operand = cp_unevaluated_operand;
+ cp_unevaluated_operand = 0;
+ saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+ c_inhibit_evaluation_warnings = 0;
+
+ /* First, determine the context for the type we are looking
+ up. */
+ context = TYPE_CONTEXT (t);
+ if (context && TYPE_P (context))
+ {
+ context = tsubst_aggr_type (context, args, complain,
+ in_decl, /*entering_scope=*/1);
+ /* If context is a nested class inside a class template,
+ it may still need to be instantiated (c++/33959). */
+ context = complete_type (context);
+ }
+
+ /* Then, figure out what arguments are appropriate for the
+ type we are trying to find. For example, given:
+
+ template <class T> struct S;
+ template <class T, class U> void f(T, U) { S<U> su; }
+
+ and supposing that we are instantiating f<int, double>,
+ then our ARGS will be {int, double}, but, when looking up
+ S we only want {double}. */
+ argvec = tsubst_template_args (TYPE_TI_ARGS (t), args,
+ complain, in_decl);
+ if (argvec == error_mark_node)
+ r = error_mark_node;
+ else
+ {
+ r = lookup_template_class (t, argvec, in_decl, context,
+ entering_scope, complain);
+ r = cp_build_qualified_type_real (r, cp_type_quals (t), complain);
+ }
+
+ cp_unevaluated_operand = saved_unevaluated_operand;
+ c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
+
+ return r;
+ }
+ else
+ /* This is not a template type, so there's nothing to do. */
+ return t;
+
+ default:
+ return tsubst (t, args, complain, in_decl);
+ }
+}
+
+/* Substitute into the default argument ARG (a default argument for
+ FN), which has the indicated TYPE. */
+
+tree
+tsubst_default_argument (tree fn, tree type, tree arg, tsubst_flags_t complain)
+{
+ tree saved_class_ptr = NULL_TREE;
+ tree saved_class_ref = NULL_TREE;
+ int errs = errorcount + sorrycount;
+
+ /* This can happen in invalid code. */
+ if (TREE_CODE (arg) == DEFAULT_ARG)
+ return arg;
+
+ /* This default argument came from a template. Instantiate the
+ default argument here, not in tsubst. In the case of
+ something like:
+
+ template <class T>
+ struct S {
+ static T t();
+ void f(T = t());
+ };
+
+ we must be careful to do name lookup in the scope of S<T>,
+ rather than in the current class. */
+ push_access_scope (fn);
+ /* The "this" pointer is not valid in a default argument. */
+ if (cfun)
+ {
+ saved_class_ptr = current_class_ptr;
+ cp_function_chain->x_current_class_ptr = NULL_TREE;
+ saved_class_ref = current_class_ref;
+ cp_function_chain->x_current_class_ref = NULL_TREE;
+ }
+
+ push_deferring_access_checks(dk_no_deferred);
+ /* The default argument expression may cause implicitly defined
+ member functions to be synthesized, which will result in garbage
+ collection. We must treat this situation as if we were within
+ the body of function so as to avoid collecting live data on the
+ stack. */
+ ++function_depth;
+ arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
+ complain, NULL_TREE,
+ /*integral_constant_expression_p=*/false);
+ --function_depth;
+ pop_deferring_access_checks();
+
+ /* Restore the "this" pointer. */
+ if (cfun)
+ {
+ cp_function_chain->x_current_class_ptr = saved_class_ptr;
+ cp_function_chain->x_current_class_ref = saved_class_ref;
+ }
+
+ if (errorcount+sorrycount > errs
+ && (complain & tf_warning_or_error))
+ inform (input_location,
+ " when instantiating default argument for call to %D", fn);
+
+ /* Make sure the default argument is reasonable. */
+ arg = check_default_argument (type, arg, complain);
+
+ pop_access_scope (fn);
+
+ return arg;
+}
+
+/* Substitute into all the default arguments for FN. */
+
+static void
+tsubst_default_arguments (tree fn, tsubst_flags_t complain)
+{
+ tree arg;
+ tree tmpl_args;
+
+ tmpl_args = DECL_TI_ARGS (fn);
+
+ /* If this function is not yet instantiated, we certainly don't need
+ its default arguments. */
+ if (uses_template_parms (tmpl_args))
+ return;
+ /* Don't do this again for clones. */
+ if (DECL_CLONED_FUNCTION_P (fn))
+ return;
+
+ for (arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ arg;
+ arg = TREE_CHAIN (arg))
+ if (TREE_PURPOSE (arg))
+ TREE_PURPOSE (arg) = tsubst_default_argument (fn,
+ TREE_VALUE (arg),
+ TREE_PURPOSE (arg),
+ complain);
+}
+
+/* Substitute the ARGS into the T, which is a _DECL. Return the
+ result of the substitution. Issue error and warning messages under
+ control of COMPLAIN. */
+
+static tree
+tsubst_decl (tree t, tree args, tsubst_flags_t complain)
+{
+#define RETURN(EXP) do { r = (EXP); goto out; } while(0)
+ location_t saved_loc;
+ tree r = NULL_TREE;
+ tree in_decl = t;
+ hashval_t hash = 0;
+
+ /* Set the filename and linenumber to improve error-reporting. */
+ saved_loc = input_location;
+ input_location = DECL_SOURCE_LOCATION (t);
+
+ switch (TREE_CODE (t))
+ {
+ case TEMPLATE_DECL:
+ {
+ /* We can get here when processing a member function template,
+ member class template, or template template parameter. */
+ tree decl = DECL_TEMPLATE_RESULT (t);
+ tree spec;
+ tree tmpl_args;
+ tree full_args;
+
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
+ {
+ /* Template template parameter is treated here. */
+ tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ if (new_type == error_mark_node)
+ RETURN (error_mark_node);
+ /* If we get a real template back, return it. This can happen in
+ the context of most_specialized_class. */
+ if (TREE_CODE (new_type) == TEMPLATE_DECL)
+ return new_type;
+
+ r = copy_decl (t);
+ DECL_CHAIN (r) = NULL_TREE;
+ TREE_TYPE (r) = new_type;
+ DECL_TEMPLATE_RESULT (r)
+ = build_decl (DECL_SOURCE_LOCATION (decl),
+ TYPE_DECL, DECL_NAME (decl), new_type);
+ DECL_TEMPLATE_PARMS (r)
+ = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args,
+ complain);
+ TYPE_NAME (new_type) = r;
+ break;
+ }
+
+ /* We might already have an instance of this template.
+ The ARGS are for the surrounding class type, so the
+ full args contain the tsubst'd args for the context,
+ plus the innermost args from the template decl. */
+ tmpl_args = DECL_CLASS_TEMPLATE_P (t)
+ ? CLASSTYPE_TI_ARGS (TREE_TYPE (t))
+ : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
+ /* Because this is a template, the arguments will still be
+ dependent, even after substitution. If
+ PROCESSING_TEMPLATE_DECL is not set, the dependency
+ predicates will short-circuit. */
+ ++processing_template_decl;
+ full_args = tsubst_template_args (tmpl_args, args,
+ complain, in_decl);
+ --processing_template_decl;
+ if (full_args == error_mark_node)
+ RETURN (error_mark_node);
+
+ /* If this is a default template template argument,
+ tsubst might not have changed anything. */
+ if (full_args == tmpl_args)
+ RETURN (t);
+
+ hash = hash_tmpl_and_args (t, full_args);
+ spec = retrieve_specialization (t, full_args, hash);
+ if (spec != NULL_TREE)
+ {
+ r = spec;
+ break;
+ }
+
+ /* Make a new template decl. It will be similar to the
+ original, but will record the current template arguments.
+ We also create a new function declaration, which is just
+ like the old one, but points to this new template, rather
+ than the old one. */
+ r = copy_decl (t);
+ gcc_assert (DECL_LANG_SPECIFIC (r) != 0);
+ DECL_CHAIN (r) = NULL_TREE;
+
+ DECL_TEMPLATE_INFO (r) = build_template_info (t, args);
+
+ if (TREE_CODE (decl) == TYPE_DECL
+ && !TYPE_DECL_ALIAS_P (decl))
+ {
+ tree new_type;
+ ++processing_template_decl;
+ new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ --processing_template_decl;
+ if (new_type == error_mark_node)
+ RETURN (error_mark_node);
+
+ TREE_TYPE (r) = new_type;
+ /* For a partial specialization, we need to keep pointing to
+ the primary template. */
+ if (!DECL_TEMPLATE_SPECIALIZATION (t))
+ CLASSTYPE_TI_TEMPLATE (new_type) = r;
+ DECL_TEMPLATE_RESULT (r) = TYPE_MAIN_DECL (new_type);
+ DECL_TI_ARGS (r) = CLASSTYPE_TI_ARGS (new_type);
+ DECL_CONTEXT (r) = TYPE_CONTEXT (new_type);
+ }
+ else
+ {
+ tree new_decl;
+ ++processing_template_decl;
+ new_decl = tsubst (decl, args, complain, in_decl);
+ --processing_template_decl;
+ if (new_decl == error_mark_node)
+ RETURN (error_mark_node);
+
+ DECL_TEMPLATE_RESULT (r) = new_decl;
+ DECL_TI_TEMPLATE (new_decl) = r;
+ TREE_TYPE (r) = TREE_TYPE (new_decl);
+ DECL_TI_ARGS (r) = DECL_TI_ARGS (new_decl);
+ DECL_CONTEXT (r) = DECL_CONTEXT (new_decl);
+ }
+
+ SET_DECL_IMPLICIT_INSTANTIATION (r);
+ DECL_TEMPLATE_INSTANTIATIONS (r) = NULL_TREE;
+ DECL_TEMPLATE_SPECIALIZATIONS (r) = NULL_TREE;
+
+ /* The template parameters for this new template are all the
+ template parameters for the old template, except the
+ outermost level of parameters. */
+ DECL_TEMPLATE_PARMS (r)
+ = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args,
+ complain);
+
+ if (PRIMARY_TEMPLATE_P (t))
+ DECL_PRIMARY_TEMPLATE (r) = r;
+
+ if (TREE_CODE (decl) != TYPE_DECL)
+ /* Record this non-type partial instantiation. */
+ register_specialization (r, t,
+ DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)),
+ false, hash);
+ }
+ break;
+
+ case FUNCTION_DECL:
+ {
+ tree ctx;
+ tree argvec = NULL_TREE;
+ tree *friends;
+ tree gen_tmpl;
+ tree type;
+ int member;
+ int args_depth;
+ int parms_depth;
+
+ /* Nobody should be tsubst'ing into non-template functions. */
+ gcc_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE);
+
+ if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL)
+ {
+ tree spec;
+ bool dependent_p;
+
+ /* If T is not dependent, just return it. We have to
+ increment PROCESSING_TEMPLATE_DECL because
+ value_dependent_expression_p assumes that nothing is
+ dependent when PROCESSING_TEMPLATE_DECL is zero. */
+ ++processing_template_decl;
+ dependent_p = value_dependent_expression_p (t);
+ --processing_template_decl;
+ if (!dependent_p)
+ RETURN (t);
+
+ /* Calculate the most general template of which R is a
+ specialization, and the complete set of arguments used to
+ specialize R. */
+ gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
+ argvec = tsubst_template_args (DECL_TI_ARGS
+ (DECL_TEMPLATE_RESULT
+ (DECL_TI_TEMPLATE (t))),
+ args, complain, in_decl);
+ if (argvec == error_mark_node)
+ RETURN (error_mark_node);
+
+ /* Check to see if we already have this specialization. */
+ hash = hash_tmpl_and_args (gen_tmpl, argvec);
+ spec = retrieve_specialization (gen_tmpl, argvec, hash);
+
+ if (spec)
+ {
+ r = spec;
+ break;
+ }
+
+ /* We can see more levels of arguments than parameters if
+ there was a specialization of a member template, like
+ this:
+
+ template <class T> struct S { template <class U> void f(); }
+ template <> template <class U> void S<int>::f(U);
+
+ Here, we'll be substituting into the specialization,
+ because that's where we can find the code we actually
+ want to generate, but we'll have enough arguments for
+ the most general template.
+
+ We also deal with the peculiar case:
+
+ template <class T> struct S {
+ template <class U> friend void f();
+ };
+ template <class U> void f() {}
+ template S<int>;
+ template void f<double>();
+
+ Here, the ARGS for the instantiation of will be {int,
+ double}. But, we only need as many ARGS as there are
+ levels of template parameters in CODE_PATTERN. We are
+ careful not to get fooled into reducing the ARGS in
+ situations like:
+
+ template <class T> struct S { template <class U> void f(U); }
+ template <class T> template <> void S<T>::f(int) {}
+
+ which we can spot because the pattern will be a
+ specialization in this case. */
+ args_depth = TMPL_ARGS_DEPTH (args);
+ parms_depth =
+ TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (t)));
+ if (args_depth > parms_depth
+ && !DECL_TEMPLATE_SPECIALIZATION (t))
+ args = get_innermost_template_args (args, parms_depth);
+ }
+ else
+ {
+ /* This special case arises when we have something like this:
+
+ template <class T> struct S {
+ friend void f<int>(int, double);
+ };
+
+ Here, the DECL_TI_TEMPLATE for the friend declaration
+ will be an IDENTIFIER_NODE. We are being called from
+ tsubst_friend_function, and we want only to create a
+ new decl (R) with appropriate types so that we can call
+ determine_specialization. */
+ gen_tmpl = NULL_TREE;
+ }
+
+ if (DECL_CLASS_SCOPE_P (t))
+ {
+ if (DECL_NAME (t) == constructor_name (DECL_CONTEXT (t)))
+ member = 2;
+ else
+ member = 1;
+ ctx = tsubst_aggr_type (DECL_CONTEXT (t), args,
+ complain, t, /*entering_scope=*/1);
+ }
+ else
+ {
+ member = 0;
+ ctx = DECL_CONTEXT (t);
+ }
+ type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ if (type == error_mark_node)
+ RETURN (error_mark_node);
+
+ /* If we hit excessive deduction depth, the type is bogus even if
+ it isn't error_mark_node, so don't build a decl. */
+ if (excessive_deduction_depth)
+ RETURN (error_mark_node);
+
+ /* We do NOT check for matching decls pushed separately at this
+ point, as they may not represent instantiations of this
+ template, and in any case are considered separate under the
+ discrete model. */
+ r = copy_decl (t);
+ DECL_USE_TEMPLATE (r) = 0;
+ TREE_TYPE (r) = type;
+ /* Clear out the mangled name and RTL for the instantiation. */
+ SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
+ SET_DECL_RTL (r, NULL);
+ /* Leave DECL_INITIAL set on deleted instantiations. */
+ if (!DECL_DELETED_FN (r))
+ DECL_INITIAL (r) = NULL_TREE;
+ DECL_CONTEXT (r) = ctx;
+
+ /* OpenMP UDRs have the only argument a reference to the declared
+ type. We want to diagnose if the declared type is a reference,
+ which is invalid, but as references to references are usually
+ quietly merged, diagnose it here. */
+ if (DECL_OMP_DECLARE_REDUCTION_P (t))
+ {
+ tree argtype
+ = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (t))));
+ argtype = tsubst (argtype, args, complain, in_decl);
+ if (TREE_CODE (argtype) == REFERENCE_TYPE)
+ error_at (DECL_SOURCE_LOCATION (t),
+ "reference type %qT in "
+ "%<#pragma omp declare reduction%>", argtype);
+ if (strchr (IDENTIFIER_POINTER (DECL_NAME (t)), '~') == NULL)
+ DECL_NAME (r) = omp_reduction_id (ERROR_MARK, DECL_NAME (t),
+ argtype);
+ }
+
+ if (member && DECL_CONV_FN_P (r))
+ /* Type-conversion operator. Reconstruct the name, in
+ case it's the name of one of the template's parameters. */
+ DECL_NAME (r) = mangle_conv_op_name_for_type (TREE_TYPE (type));
+
+ DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args,
+ complain, t);
+ DECL_RESULT (r) = NULL_TREE;
+
+ TREE_STATIC (r) = 0;
+ TREE_PUBLIC (r) = TREE_PUBLIC (t);
+ DECL_EXTERNAL (r) = 1;
+ /* If this is an instantiation of a function with internal
+ linkage, we already know what object file linkage will be
+ assigned to the instantiation. */
+ DECL_INTERFACE_KNOWN (r) = !TREE_PUBLIC (r);
+ DECL_DEFER_OUTPUT (r) = 0;
+ DECL_CHAIN (r) = NULL_TREE;
+ DECL_PENDING_INLINE_INFO (r) = 0;
+ DECL_PENDING_INLINE_P (r) = 0;
+ DECL_SAVED_TREE (r) = NULL_TREE;
+ DECL_STRUCT_FUNCTION (r) = NULL;
+ TREE_USED (r) = 0;
+ /* We'll re-clone as appropriate in instantiate_template. */
+ DECL_CLONED_FUNCTION (r) = NULL_TREE;
+
+ /* If we aren't complaining now, return on error before we register
+ the specialization so that we'll complain eventually. */
+ if ((complain & tf_error) == 0
+ && IDENTIFIER_OPNAME_P (DECL_NAME (r))
+ && !grok_op_properties (r, /*complain=*/false))
+ RETURN (error_mark_node);
+
+ /* Set up the DECL_TEMPLATE_INFO for R. There's no need to do
+ this in the special friend case mentioned above where
+ GEN_TMPL is NULL. */
+ if (gen_tmpl)
+ {
+ DECL_TEMPLATE_INFO (r)
+ = build_template_info (gen_tmpl, argvec);
+ SET_DECL_IMPLICIT_INSTANTIATION (r);
+
+ tree new_r
+ = register_specialization (r, gen_tmpl, argvec, false, hash);
+ if (new_r != r)
+ /* We instantiated this while substituting into
+ the type earlier (template/friend54.C). */
+ RETURN (new_r);
+
+ /* We're not supposed to instantiate default arguments
+ until they are called, for a template. But, for a
+ declaration like:
+
+ template <class T> void f ()
+ { extern void g(int i = T()); }
+
+ we should do the substitution when the template is
+ instantiated. We handle the member function case in
+ instantiate_class_template since the default arguments
+ might refer to other members of the class. */
+ if (!member
+ && !PRIMARY_TEMPLATE_P (gen_tmpl)
+ && !uses_template_parms (argvec))
+ tsubst_default_arguments (r, complain);
+ }
+ else
+ DECL_TEMPLATE_INFO (r) = NULL_TREE;
+
+ /* Copy the list of befriending classes. */
+ for (friends = &DECL_BEFRIENDING_CLASSES (r);
+ *friends;
+ friends = &TREE_CHAIN (*friends))
+ {
+ *friends = copy_node (*friends);
+ TREE_VALUE (*friends) = tsubst (TREE_VALUE (*friends),
+ args, complain,
+ in_decl);
+ }
+
+ if (DECL_CONSTRUCTOR_P (r) || DECL_DESTRUCTOR_P (r))
+ {
+ maybe_retrofit_in_chrg (r);
+ if (DECL_CONSTRUCTOR_P (r))
+ grok_ctor_properties (ctx, r);
+ if (DECL_INHERITED_CTOR_BASE (r))
+ deduce_inheriting_ctor (r);
+ /* If this is an instantiation of a member template, clone it.
+ If it isn't, that'll be handled by
+ clone_constructors_and_destructors. */
+ if (PRIMARY_TEMPLATE_P (gen_tmpl))
+ clone_function_decl (r, /*update_method_vec_p=*/0);
+ }
+ else if ((complain & tf_error) != 0
+ && IDENTIFIER_OPNAME_P (DECL_NAME (r))
+ && !grok_op_properties (r, /*complain=*/true))
+ RETURN (error_mark_node);
+
+ if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t))
+ SET_DECL_FRIEND_CONTEXT (r,
+ tsubst (DECL_FRIEND_CONTEXT (t),
+ args, complain, in_decl));
+
+ /* Possibly limit visibility based on template args. */
+ DECL_VISIBILITY (r) = VISIBILITY_DEFAULT;
+ if (DECL_VISIBILITY_SPECIFIED (t))
+ {
+ DECL_VISIBILITY_SPECIFIED (r) = 0;
+ DECL_ATTRIBUTES (r)
+ = remove_attribute ("visibility", DECL_ATTRIBUTES (r));
+ }
+ determine_visibility (r);
+ if (DECL_DEFAULTED_OUTSIDE_CLASS_P (r)
+ && !processing_template_decl)
+ defaulted_late_check (r);
+
+ apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0,
+ args, complain, in_decl);
+ }
+ break;
+
+ case PARM_DECL:
+ {
+ tree type = NULL_TREE;
+ int i, len = 1;
+ tree expanded_types = NULL_TREE;
+ tree prev_r = NULL_TREE;
+ tree first_r = NULL_TREE;
+
+ if (DECL_PACK_P (t))
+ {
+ /* If there is a local specialization that isn't a
+ parameter pack, it means that we're doing a "simple"
+ substitution from inside tsubst_pack_expansion. Just
+ return the local specialization (which will be a single
+ parm). */
+ tree spec = retrieve_local_specialization (t);
+ if (spec
+ && TREE_CODE (spec) == PARM_DECL
+ && TREE_CODE (TREE_TYPE (spec)) != TYPE_PACK_EXPANSION)
+ RETURN (spec);
+
+ /* Expand the TYPE_PACK_EXPANSION that provides the types for
+ the parameters in this function parameter pack. */
+ expanded_types = tsubst_pack_expansion (TREE_TYPE (t), args,
+ complain, in_decl);
+ if (TREE_CODE (expanded_types) == TREE_VEC)
+ {
+ len = TREE_VEC_LENGTH (expanded_types);
+
+ /* Zero-length parameter packs are boring. Just substitute
+ into the chain. */
+ if (len == 0)
+ RETURN (tsubst (TREE_CHAIN (t), args, complain,
+ TREE_CHAIN (t)));
+ }
+ else
+ {
+ /* All we did was update the type. Make a note of that. */
+ type = expanded_types;
+ expanded_types = NULL_TREE;
+ }
+ }
+
+ /* Loop through all of the parameters we'll build. When T is
+ a function parameter pack, LEN is the number of expanded
+ types in EXPANDED_TYPES; otherwise, LEN is 1. */
+ r = NULL_TREE;
+ for (i = 0; i < len; ++i)
+ {
+ prev_r = r;
+ r = copy_node (t);
+ if (DECL_TEMPLATE_PARM_P (t))
+ SET_DECL_TEMPLATE_PARM_P (r);
+
+ if (expanded_types)
+ /* We're on the Ith parameter of the function parameter
+ pack. */
+ {
+ /* Get the Ith type. */
+ type = TREE_VEC_ELT (expanded_types, i);
+
+ /* Rename the parameter to include the index. */
+ DECL_NAME (r)
+ = make_ith_pack_parameter_name (DECL_NAME (r), i);
+ }
+ else if (!type)
+ /* We're dealing with a normal parameter. */
+ type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+
+ type = type_decays_to (type);
+ TREE_TYPE (r) = type;
+ cp_apply_type_quals_to_decl (cp_type_quals (type), r);
+
+ if (DECL_INITIAL (r))
+ {
+ if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
+ DECL_INITIAL (r) = TREE_TYPE (r);
+ else
+ DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
+ complain, in_decl);
+ }
+
+ DECL_CONTEXT (r) = NULL_TREE;
+
+ if (!DECL_TEMPLATE_PARM_P (r))
+ DECL_ARG_TYPE (r) = type_passed_as (type);
+
+ apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0,
+ args, complain, in_decl);
+
+ /* Keep track of the first new parameter we
+ generate. That's what will be returned to the
+ caller. */
+ if (!first_r)
+ first_r = r;
+
+ /* Build a proper chain of parameters when substituting
+ into a function parameter pack. */
+ if (prev_r)
+ DECL_CHAIN (prev_r) = r;
+ }
+
+ /* If cp_unevaluated_operand is set, we're just looking for a
+ single dummy parameter, so don't keep going. */
+ if (DECL_CHAIN (t) && !cp_unevaluated_operand)
+ DECL_CHAIN (r) = tsubst (DECL_CHAIN (t), args,
+ complain, DECL_CHAIN (t));
+
+ /* FIRST_R contains the start of the chain we've built. */
+ r = first_r;
+ }
+ break;
+
+ case FIELD_DECL:
+ {
+ tree type = NULL_TREE;
+ tree vec = NULL_TREE;
+ tree expanded_types = NULL_TREE;
+ int len = 1;
+
+ if (PACK_EXPANSION_P (TREE_TYPE (t)))
+ {
+ /* This field is a lambda capture pack. Return a TREE_VEC of
+ the expanded fields to instantiate_class_template_1 and
+ store them in the specializations hash table as a
+ NONTYPE_ARGUMENT_PACK so that tsubst_copy can find them. */
+ expanded_types = tsubst_pack_expansion (TREE_TYPE (t), args,
+ complain, in_decl);
+ if (TREE_CODE (expanded_types) == TREE_VEC)
+ {
+ len = TREE_VEC_LENGTH (expanded_types);
+ vec = make_tree_vec (len);
+ }
+ else
+ {
+ /* All we did was update the type. Make a note of that. */
+ type = expanded_types;
+ expanded_types = NULL_TREE;
+ }
+ }
+
+ for (int i = 0; i < len; ++i)
+ {
+ r = copy_decl (t);
+ if (expanded_types)
+ {
+ type = TREE_VEC_ELT (expanded_types, i);
+ DECL_NAME (r)
+ = make_ith_pack_parameter_name (DECL_NAME (r), i);
+ }
+ else if (!type)
+ type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+
+ if (type == error_mark_node)
+ RETURN (error_mark_node);
+ TREE_TYPE (r) = type;
+ cp_apply_type_quals_to_decl (cp_type_quals (type), r);
+
+ if (DECL_C_BIT_FIELD (r))
+ /* For bit-fields, DECL_INITIAL gives the number of bits. For
+ non-bit-fields DECL_INITIAL is a non-static data member
+ initializer, which gets deferred instantiation. */
+ DECL_INITIAL (r)
+ = tsubst_expr (DECL_INITIAL (t), args,
+ complain, in_decl,
+ /*integral_constant_expression_p=*/true);
+ else if (DECL_INITIAL (t))
+ {
+ /* Set up DECL_TEMPLATE_INFO so that we can get at the
+ NSDMI in perform_member_init. Still set DECL_INITIAL
+ so that we know there is one. */
+ DECL_INITIAL (r) = void_zero_node;
+ gcc_assert (DECL_LANG_SPECIFIC (r) == NULL);
+ retrofit_lang_decl (r);
+ DECL_TEMPLATE_INFO (r) = build_template_info (t, args);
+ }
+ /* We don't have to set DECL_CONTEXT here; it is set by
+ finish_member_declaration. */
+ DECL_CHAIN (r) = NULL_TREE;
+
+ apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0,
+ args, complain, in_decl);
+
+ if (vec)
+ TREE_VEC_ELT (vec, i) = r;
+ }
+
+ if (vec)
+ {
+ r = vec;
+ tree pack = make_node (NONTYPE_ARGUMENT_PACK);
+ tree tpack = cxx_make_type (TYPE_ARGUMENT_PACK);
+ SET_ARGUMENT_PACK_ARGS (pack, vec);
+ SET_ARGUMENT_PACK_ARGS (tpack, expanded_types);
+ TREE_TYPE (pack) = tpack;
+ register_specialization (pack, t, args, false, 0);
+ }
+ }
+ break;
+
+ case USING_DECL:
+ /* We reach here only for member using decls. We also need to check
+ uses_template_parms because DECL_DEPENDENT_P is not set for a
+ using-declaration that designates a member of the current
+ instantiation (c++/53549). */
+ if (DECL_DEPENDENT_P (t)
+ || uses_template_parms (USING_DECL_SCOPE (t)))
+ {
+ tree inst_scope = tsubst_copy (USING_DECL_SCOPE (t), args,
+ complain, in_decl);
+ tree name = tsubst_copy (DECL_NAME (t), args, complain, in_decl);
+ r = do_class_using_decl (inst_scope, name);
+ if (!r)
+ r = error_mark_node;
+ else
+ {
+ TREE_PROTECTED (r) = TREE_PROTECTED (t);
+ TREE_PRIVATE (r) = TREE_PRIVATE (t);
+ }
+ }
+ else
+ {
+ r = copy_node (t);
+ DECL_CHAIN (r) = NULL_TREE;
+ }
+ break;
+
+ case TYPE_DECL:
+ case VAR_DECL:
+ {
+ tree argvec = NULL_TREE;
+ tree gen_tmpl = NULL_TREE;
+ tree spec;
+ tree tmpl = NULL_TREE;
+ tree ctx;
+ tree type = NULL_TREE;
+ bool local_p;
+
+ if (TREE_TYPE (t) == error_mark_node)
+ RETURN (error_mark_node);
+
+ if (TREE_CODE (t) == TYPE_DECL
+ && t == TYPE_MAIN_DECL (TREE_TYPE (t)))
+ {
+ /* If this is the canonical decl, we don't have to
+ mess with instantiations, and often we can't (for
+ typename, template type parms and such). Note that
+ TYPE_NAME is not correct for the above test if
+ we've copied the type for a typedef. */
+ type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ if (type == error_mark_node)
+ RETURN (error_mark_node);
+ r = TYPE_NAME (type);
+ break;
+ }
+
+ /* Check to see if we already have the specialization we
+ need. */
+ spec = NULL_TREE;
+ if (DECL_CLASS_SCOPE_P (t) || DECL_NAMESPACE_SCOPE_P (t))
+ {
+ /* T is a static data member or namespace-scope entity.
+ We have to substitute into namespace-scope variables
+ (even though such entities are never templates) because
+ of cases like:
+
+ template <class T> void f() { extern T t; }
+
+ where the entity referenced is not known until
+ instantiation time. */
+ local_p = false;
+ ctx = DECL_CONTEXT (t);
+ if (DECL_CLASS_SCOPE_P (t))
+ {
+ ctx = tsubst_aggr_type (ctx, args,
+ complain,
+ in_decl, /*entering_scope=*/1);
+ /* If CTX is unchanged, then T is in fact the
+ specialization we want. That situation occurs when
+ referencing a static data member within in its own
+ class. We can use pointer equality, rather than
+ same_type_p, because DECL_CONTEXT is always
+ canonical... */
+ if (ctx == DECL_CONTEXT (t)
+ && (TREE_CODE (t) != TYPE_DECL
+ /* ... unless T is a member template; in which
+ case our caller can be willing to create a
+ specialization of that template represented
+ by T. */
+ || !(DECL_TI_TEMPLATE (t)
+ && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (t)))))
+ spec = t;
+ }
+
+ if (!spec)
+ {
+ tmpl = DECL_TI_TEMPLATE (t);
+ gen_tmpl = most_general_template (tmpl);
+ argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
+ if (argvec == error_mark_node)
+ RETURN (error_mark_node);
+ hash = hash_tmpl_and_args (gen_tmpl, argvec);
+ spec = retrieve_specialization (gen_tmpl, argvec, hash);
+ }
+ }
+ else
+ {
+ /* A local variable. */
+ local_p = true;
+ /* Subsequent calls to pushdecl will fill this in. */
+ ctx = NULL_TREE;
+ spec = retrieve_local_specialization (t);
+ }
+ /* If we already have the specialization we need, there is
+ nothing more to do. */
+ if (spec)
+ {
+ r = spec;
+ break;
+ }
+
+ /* Create a new node for the specialization we need. */
+ r = copy_decl (t);
+ if (type == NULL_TREE)
+ {
+ if (is_typedef_decl (t))
+ type = DECL_ORIGINAL_TYPE (t);
+ else
+ type = TREE_TYPE (t);
+ if (VAR_P (t)
+ && VAR_HAD_UNKNOWN_BOUND (t)
+ && type != error_mark_node)
+ type = strip_array_domain (type);
+ type = tsubst (type, args, complain, in_decl);
+ }
+ if (VAR_P (r))
+ {
+ /* Even if the original location is out of scope, the
+ newly substituted one is not. */
+ DECL_DEAD_FOR_LOCAL (r) = 0;
+ DECL_INITIALIZED_P (r) = 0;
+ DECL_TEMPLATE_INSTANTIATED (r) = 0;
+ if (type == error_mark_node)
+ RETURN (error_mark_node);
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ /* It may seem that this case cannot occur, since:
+
+ typedef void f();
+ void g() { f x; }
+
+ declares a function, not a variable. However:
+
+ typedef void f();
+ template <typename T> void g() { T t; }
+ template void g<f>();
+
+ is an attempt to declare a variable with function
+ type. */
+ error ("variable %qD has function type",
+ /* R is not yet sufficiently initialized, so we
+ just use its name. */
+ DECL_NAME (r));
+ RETURN (error_mark_node);
+ }
+ type = complete_type (type);
+ /* Wait until cp_finish_decl to set this again, to handle
+ circular dependency (template/instantiate6.C). */
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r) = 0;
+ type = check_var_type (DECL_NAME (r), type);
+
+ if (DECL_HAS_VALUE_EXPR_P (t))
+ {
+ tree ve = DECL_VALUE_EXPR (t);
+ ve = tsubst_expr (ve, args, complain, in_decl,
+ /*constant_expression_p=*/false);
+ if (REFERENCE_REF_P (ve))
+ {
+ gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
+ ve = TREE_OPERAND (ve, 0);
+ }
+ SET_DECL_VALUE_EXPR (r, ve);
+ }
+ }
+ else if (DECL_SELF_REFERENCE_P (t))
+ SET_DECL_SELF_REFERENCE_P (r);
+ TREE_TYPE (r) = type;
+ cp_apply_type_quals_to_decl (cp_type_quals (type), r);
+ DECL_CONTEXT (r) = ctx;
+ /* Clear out the mangled name and RTL for the instantiation. */
+ SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
+ if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL))
+ SET_DECL_RTL (r, NULL);
+ /* The initializer must not be expanded until it is required;
+ see [temp.inst]. */
+ DECL_INITIAL (r) = NULL_TREE;
+ if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL))
+ SET_DECL_RTL (r, NULL);
+ DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0;
+ if (VAR_P (r))
+ {
+ /* Possibly limit visibility based on template args. */
+ DECL_VISIBILITY (r) = VISIBILITY_DEFAULT;
+ if (DECL_VISIBILITY_SPECIFIED (t))
+ {
+ DECL_VISIBILITY_SPECIFIED (r) = 0;
+ DECL_ATTRIBUTES (r)
+ = remove_attribute ("visibility", DECL_ATTRIBUTES (r));
+ }
+ determine_visibility (r);
+ }
+
+ if (!local_p)
+ {
+ /* A static data member declaration is always marked
+ external when it is declared in-class, even if an
+ initializer is present. We mimic the non-template
+ processing here. */
+ DECL_EXTERNAL (r) = 1;
+
+ register_specialization (r, gen_tmpl, argvec, false, hash);
+ DECL_TEMPLATE_INFO (r) = build_template_info (tmpl, argvec);
+ SET_DECL_IMPLICIT_INSTANTIATION (r);
+ }
+ else if (!cp_unevaluated_operand)
+ register_local_specialization (r, t);
+
+ DECL_CHAIN (r) = NULL_TREE;
+
+ apply_late_template_attributes (&r, DECL_ATTRIBUTES (r),
+ /*flags=*/0,
+ args, complain, in_decl);
+
+ /* Preserve a typedef that names a type. */
+ if (is_typedef_decl (r))
+ {
+ DECL_ORIGINAL_TYPE (r) = NULL_TREE;
+ set_underlying_type (r);
+ }
+
+ layout_decl (r, 0);
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+#undef RETURN
+
+ out:
+ /* Restore the file and line information. */
+ input_location = saved_loc;
+
+ return r;
+}
+
+/* Substitute into the ARG_TYPES of a function type.
+ If END is a TREE_CHAIN, leave it and any following types
+ un-substituted. */
+
+static tree
+tsubst_arg_types (tree arg_types,
+ tree args,
+ tree end,
+ tsubst_flags_t complain,
+ tree in_decl)
+{
+ tree remaining_arg_types;
+ tree type = NULL_TREE;
+ int i = 1;
+ tree expanded_args = NULL_TREE;
+ tree default_arg;
+
+ if (!arg_types || arg_types == void_list_node || arg_types == end)
+ return arg_types;
+
+ remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types),
+ args, end, complain, in_decl);
+ if (remaining_arg_types == error_mark_node)
+ return error_mark_node;
+
+ if (PACK_EXPANSION_P (TREE_VALUE (arg_types)))
+ {
+ /* For a pack expansion, perform substitution on the
+ entire expression. Later on, we'll handle the arguments
+ one-by-one. */
+ expanded_args = tsubst_pack_expansion (TREE_VALUE (arg_types),
+ args, complain, in_decl);
+
+ if (TREE_CODE (expanded_args) == TREE_VEC)
+ /* So that we'll spin through the parameters, one by one. */
+ i = TREE_VEC_LENGTH (expanded_args);
+ else
+ {
+ /* We only partially substituted into the parameter
+ pack. Our type is TYPE_PACK_EXPANSION. */
+ type = expanded_args;
+ expanded_args = NULL_TREE;
+ }
+ }
+
+ while (i > 0) {
+ --i;
+
+ if (expanded_args)
+ type = TREE_VEC_ELT (expanded_args, i);
+ else if (!type)
+ type = tsubst (TREE_VALUE (arg_types), args, complain, in_decl);
+
+ if (type == error_mark_node)
+ return error_mark_node;
+ if (VOID_TYPE_P (type))
+ {
+ if (complain & tf_error)
+ {
+ error ("invalid parameter type %qT", type);
+ if (in_decl)
+ error ("in declaration %q+D", in_decl);
+ }
+ return error_mark_node;
+ }
+ /* DR 657. */
+ if (abstract_virtuals_error_sfinae (ACU_PARM, type, complain))
+ return error_mark_node;
+
+ /* Do array-to-pointer, function-to-pointer conversion, and ignore
+ top-level qualifiers as required. */
+ type = cv_unqualified (type_decays_to (type));
+
+ /* We do not substitute into default arguments here. The standard
+ mandates that they be instantiated only when needed, which is
+ done in build_over_call. */
+ default_arg = TREE_PURPOSE (arg_types);
+
+ if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG)
+ {
+ /* We've instantiated a template before its default arguments
+ have been parsed. This can happen for a nested template
+ class, and is not an error unless we require the default
+ argument in a call of this function. */
+ remaining_arg_types =
+ tree_cons (default_arg, type, remaining_arg_types);
+ vec_safe_push (DEFARG_INSTANTIATIONS(default_arg), remaining_arg_types);
+ }
+ else
+ remaining_arg_types =
+ hash_tree_cons (default_arg, type, remaining_arg_types);
+ }
+
+ return remaining_arg_types;
+}
+
+/* Substitute into a FUNCTION_TYPE or METHOD_TYPE. This routine does
+ *not* handle the exception-specification for FNTYPE, because the
+ initial substitution of explicitly provided template parameters
+ during argument deduction forbids substitution into the
+ exception-specification:
+
+ [temp.deduct]
+
+ All references in the function type of the function template to the
+ corresponding template parameters are replaced by the specified tem-
+ plate argument values. If a substitution in a template parameter or
+ in the function type of the function template results in an invalid
+ type, type deduction fails. [Note: The equivalent substitution in
+ exception specifications is done only when the function is instanti-
+ ated, at which point a program is ill-formed if the substitution
+ results in an invalid type.] */
+
+static tree
+tsubst_function_type (tree t,
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl)
+{
+ tree return_type;
+ tree arg_types;
+ tree fntype;
+
+ /* The TYPE_CONTEXT is not used for function/method types. */
+ gcc_assert (TYPE_CONTEXT (t) == NULL_TREE);
+
+ /* Substitute the return type. */
+ return_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ if (return_type == error_mark_node)
+ return error_mark_node;
+ /* DR 486 clarifies that creation of a function type with an
+ invalid return type is a deduction failure. */
+ if (TREE_CODE (return_type) == ARRAY_TYPE
+ || TREE_CODE (return_type) == FUNCTION_TYPE)
+ {
+ if (complain & tf_error)
+ {
+ if (TREE_CODE (return_type) == ARRAY_TYPE)
+ error ("function returning an array");
+ else
+ error ("function returning a function");
+ }
+ return error_mark_node;
+ }
+ /* And DR 657. */
+ if (abstract_virtuals_error_sfinae (ACU_RETURN, return_type, complain))
+ return error_mark_node;
+
+ /* Substitute the argument types. */
+ arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, NULL_TREE,
+ complain, in_decl);
+ if (arg_types == error_mark_node)
+ return error_mark_node;
+
+ /* Construct a new type node and return it. */
+ if (TREE_CODE (t) == FUNCTION_TYPE)
+ {
+ fntype = build_function_type (return_type, arg_types);
+ fntype = apply_memfn_quals (fntype,
+ type_memfn_quals (t),
+ type_memfn_rqual (t));
+ }
+ else
+ {
+ tree r = TREE_TYPE (TREE_VALUE (arg_types));
+ /* Don't pick up extra function qualifiers from the basetype. */
+ r = cp_build_qualified_type_real (r, type_memfn_quals (t), complain);
+ if (! MAYBE_CLASS_TYPE_P (r))
+ {
+ /* [temp.deduct]
+
+ Type deduction may fail for any of the following
+ reasons:
+
+ -- Attempting to create "pointer to member of T" when T
+ is not a class type. */
+ if (complain & tf_error)
+ error ("creating pointer to member function of non-class type %qT",
+ r);
+ return error_mark_node;
+ }
+
+ fntype = build_method_type_directly (r, return_type,
+ TREE_CHAIN (arg_types));
+ fntype = build_ref_qualified_type (fntype, type_memfn_rqual (t));
+ }
+ fntype = cp_build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
+
+ return fntype;
+}
+
+/* FNTYPE is a FUNCTION_TYPE or METHOD_TYPE. Substitute the template
+ ARGS into that specification, and return the substituted
+ specification. If there is no specification, return NULL_TREE. */
+
+static tree
+tsubst_exception_specification (tree fntype,
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl,
+ bool defer_ok)
+{
+ tree specs;
+ tree new_specs;
+
+ specs = TYPE_RAISES_EXCEPTIONS (fntype);
+ new_specs = NULL_TREE;
+ if (specs && TREE_PURPOSE (specs))
+ {
+ /* A noexcept-specifier. */
+ tree expr = TREE_PURPOSE (specs);
+ if (TREE_CODE (expr) == INTEGER_CST)
+ new_specs = expr;
+ else if (defer_ok)
+ {
+ /* Defer instantiation of noexcept-specifiers to avoid
+ excessive instantiations (c++/49107). */
+ new_specs = make_node (DEFERRED_NOEXCEPT);
+ if (DEFERRED_NOEXCEPT_SPEC_P (specs))
+ {
+ /* We already partially instantiated this member template,
+ so combine the new args with the old. */
+ DEFERRED_NOEXCEPT_PATTERN (new_specs)
+ = DEFERRED_NOEXCEPT_PATTERN (expr);
+ DEFERRED_NOEXCEPT_ARGS (new_specs)
+ = add_to_template_args (DEFERRED_NOEXCEPT_ARGS (expr), args);
+ }
+ else
+ {
+ DEFERRED_NOEXCEPT_PATTERN (new_specs) = expr;
+ DEFERRED_NOEXCEPT_ARGS (new_specs) = args;
+ }
+ }
+ else
+ new_specs = tsubst_copy_and_build
+ (expr, args, complain, in_decl, /*function_p=*/false,
+ /*integral_constant_expression_p=*/true);
+ new_specs = build_noexcept_spec (new_specs, complain);
+ }
+ else if (specs)
+ {
+ if (! TREE_VALUE (specs))
+ new_specs = specs;
+ else
+ while (specs)
+ {
+ tree spec;
+ int i, len = 1;
+ tree expanded_specs = NULL_TREE;
+
+ if (PACK_EXPANSION_P (TREE_VALUE (specs)))
+ {
+ /* Expand the pack expansion type. */
+ expanded_specs = tsubst_pack_expansion (TREE_VALUE (specs),
+ args, complain,
+ in_decl);
+
+ if (expanded_specs == error_mark_node)
+ return error_mark_node;
+ else if (TREE_CODE (expanded_specs) == TREE_VEC)
+ len = TREE_VEC_LENGTH (expanded_specs);
+ else
+ {
+ /* We're substituting into a member template, so
+ we got a TYPE_PACK_EXPANSION back. Add that
+ expansion and move on. */
+ gcc_assert (TREE_CODE (expanded_specs)
+ == TYPE_PACK_EXPANSION);
+ new_specs = add_exception_specifier (new_specs,
+ expanded_specs,
+ complain);
+ specs = TREE_CHAIN (specs);
+ continue;
+ }
+ }
+
+ for (i = 0; i < len; ++i)
+ {
+ if (expanded_specs)
+ spec = TREE_VEC_ELT (expanded_specs, i);
+ else
+ spec = tsubst (TREE_VALUE (specs), args, complain, in_decl);
+ if (spec == error_mark_node)
+ return spec;
+ new_specs = add_exception_specifier (new_specs, spec,
+ complain);
+ }
+
+ specs = TREE_CHAIN (specs);
+ }
+ }
+ return new_specs;
+}
+
+/* Take the tree structure T and replace template parameters used
+ therein with the argument vector ARGS. IN_DECL is an associated
+ decl for diagnostics. If an error occurs, returns ERROR_MARK_NODE.
+ Issue error and warning messages under control of COMPLAIN. Note
+ that we must be relatively non-tolerant of extensions here, in
+ order to preserve conformance; if we allow substitutions that
+ should not be allowed, we may allow argument deductions that should
+ not succeed, and therefore report ambiguous overload situations
+ where there are none. In theory, we could allow the substitution,
+ but indicate that it should have failed, and allow our caller to
+ make sure that the right thing happens, but we don't try to do this
+ yet.
+
+ This function is used for dealing with types, decls and the like;
+ for expressions, use tsubst_expr or tsubst_copy. */
+
+tree
+tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+{
+ enum tree_code code;
+ tree type, r = NULL_TREE;
+
+ if (t == NULL_TREE || t == error_mark_node
+ || t == integer_type_node
+ || t == void_type_node
+ || t == char_type_node
+ || t == unknown_type_node
+ || TREE_CODE (t) == NAMESPACE_DECL
+ || TREE_CODE (t) == TRANSLATION_UNIT_DECL)
+ return t;
+
+ if (DECL_P (t))
+ return tsubst_decl (t, args, complain);
+
+ if (args == NULL_TREE)
+ return t;
+
+ code = TREE_CODE (t);
+
+ if (code == IDENTIFIER_NODE)
+ type = IDENTIFIER_TYPE_VALUE (t);
+ else
+ type = TREE_TYPE (t);
+
+ gcc_assert (type != unknown_type_node);
+
+ /* Reuse typedefs. We need to do this to handle dependent attributes,
+ such as attribute aligned. */
+ if (TYPE_P (t)
+ && typedef_variant_p (t))
+ {
+ tree decl = TYPE_NAME (t);
+
+ if (alias_template_specialization_p (t))
+ {
+ /* DECL represents an alias template and we want to
+ instantiate it. */
+ tree tmpl = most_general_template (DECL_TI_TEMPLATE (decl));
+ tree gen_args = tsubst (DECL_TI_ARGS (decl), args, complain, in_decl);
+ r = instantiate_alias_template (tmpl, gen_args, complain);
+ }
+ else if (DECL_CLASS_SCOPE_P (decl)
+ && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl))
+ && uses_template_parms (DECL_CONTEXT (decl)))
+ {
+ tree tmpl = most_general_template (DECL_TI_TEMPLATE (decl));
+ tree gen_args = tsubst (DECL_TI_ARGS (decl), args, complain, in_decl);
+ r = retrieve_specialization (tmpl, gen_args, 0);
+ }
+ else if (DECL_FUNCTION_SCOPE_P (decl)
+ && DECL_TEMPLATE_INFO (DECL_CONTEXT (decl))
+ && uses_template_parms (DECL_TI_ARGS (DECL_CONTEXT (decl))))
+ r = retrieve_local_specialization (decl);
+ else
+ /* The typedef is from a non-template context. */
+ return t;
+
+ if (r)
+ {
+ r = TREE_TYPE (r);
+ r = cp_build_qualified_type_real
+ (r, cp_type_quals (t) | cp_type_quals (r),
+ complain | tf_ignore_bad_quals);
+ return r;
+ }
+ else
+ {
+ /* We don't have an instantiation yet, so drop the typedef. */
+ int quals = cp_type_quals (t);
+ t = DECL_ORIGINAL_TYPE (decl);
+ t = cp_build_qualified_type_real (t, quals,
+ complain | tf_ignore_bad_quals);
+ }
+ }
+
+ if (type
+ && code != TYPENAME_TYPE
+ && code != TEMPLATE_TYPE_PARM
+ && code != IDENTIFIER_NODE
+ && code != FUNCTION_TYPE
+ && code != METHOD_TYPE)
+ type = tsubst (type, args, complain, in_decl);
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ switch (code)
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ return tsubst_aggr_type (t, args, complain, in_decl,
+ /*entering_scope=*/0);
+
+ case ERROR_MARK:
+ case IDENTIFIER_NODE:
+ case VOID_TYPE:
+ case REAL_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ case BOOLEAN_TYPE:
+ case NULLPTR_TYPE:
+ case LANG_TYPE:
+ return t;
+
+ case INTEGER_TYPE:
+ if (t == integer_type_node)
+ return t;
+
+ if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST
+ && TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST)
+ return t;
+
+ {
+ tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
+
+ max = tsubst_expr (omax, args, complain, in_decl,
+ /*integral_constant_expression_p=*/false);
+
+ /* Fix up type of the magic NOP_EXPR with TREE_SIDE_EFFECTS if
+ needed. */
+ if (TREE_CODE (max) == NOP_EXPR
+ && TREE_SIDE_EFFECTS (omax)
+ && !TREE_TYPE (max))
+ TREE_TYPE (max) = TREE_TYPE (TREE_OPERAND (max, 0));
+
+ /* If we're in a partial instantiation, preserve the magic NOP_EXPR
+ with TREE_SIDE_EFFECTS that indicates this is not an integral
+ constant expression. */
+ if (processing_template_decl
+ && TREE_SIDE_EFFECTS (omax) && TREE_CODE (omax) == NOP_EXPR)
+ {
+ gcc_assert (TREE_CODE (max) == NOP_EXPR);
+ TREE_SIDE_EFFECTS (max) = 1;
+ }
+
+ return compute_array_index_type (NULL_TREE, max, complain);
+ }
+
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ {
+ int idx;
+ int level;
+ int levels;
+ tree arg = NULL_TREE;
+
+ r = NULL_TREE;
+
+ gcc_assert (TREE_VEC_LENGTH (args) > 0);
+ template_parm_level_and_index (t, &level, &idx);
+
+ levels = TMPL_ARGS_DEPTH (args);
+ if (level <= levels)
+ {
+ arg = TMPL_ARG (args, level, idx);
+
+ if (arg && TREE_CODE (arg) == ARGUMENT_PACK_SELECT)
+ {
+ /* See through ARGUMENT_PACK_SELECT arguments. */
+ arg = ARGUMENT_PACK_SELECT_ARG (arg);
+ /* If the selected argument is an expansion E, that most
+ likely means we were called from
+ gen_elem_of_pack_expansion_instantiation during the
+ substituting of pack an argument pack (which Ith
+ element is a pack expansion, where I is
+ ARGUMENT_PACK_SELECT_INDEX) into a pack expansion.
+ In this case, the Ith element resulting from this
+ substituting is going to be a pack expansion, which
+ pattern is the pattern of E. Let's return the
+ pattern of E, and
+ gen_elem_of_pack_expansion_instantiation will
+ build the resulting pack expansion from it. */
+ if (PACK_EXPANSION_P (arg))
+ arg = PACK_EXPANSION_PATTERN (arg);
+ }
+ }
+
+ if (arg == error_mark_node)
+ return error_mark_node;
+ else if (arg != NULL_TREE)
+ {
+ if (ARGUMENT_PACK_P (arg))
+ /* If ARG is an argument pack, we don't actually want to
+ perform a substitution here, because substitutions
+ for argument packs are only done
+ element-by-element. We can get to this point when
+ substituting the type of a non-type template
+ parameter pack, when that type actually contains
+ template parameter packs from an outer template, e.g.,
+
+ template<typename... Types> struct A {
+ template<Types... Values> struct B { };
+ }; */
+ return t;
+
+ if (code == TEMPLATE_TYPE_PARM)
+ {
+ int quals;
+ gcc_assert (TYPE_P (arg));
+
+ quals = cp_type_quals (arg) | cp_type_quals (t);
+
+ return cp_build_qualified_type_real
+ (arg, quals, complain | tf_ignore_bad_quals);
+ }
+ else if (code == BOUND_TEMPLATE_TEMPLATE_PARM)
+ {
+ /* We are processing a type constructed from a
+ template template parameter. */
+ tree argvec = tsubst (TYPE_TI_ARGS (t),
+ args, complain, in_decl);
+ if (argvec == error_mark_node)
+ return error_mark_node;
+
+ gcc_assert (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (arg) == TEMPLATE_DECL
+ || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
+
+ if (TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)
+ /* Consider this code:
+
+ template <template <class> class Template>
+ struct Internal {
+ template <class Arg> using Bind = Template<Arg>;
+ };
+
+ template <template <class> class Template, class Arg>
+ using Instantiate = Template<Arg>; //#0
+
+ template <template <class> class Template,
+ class Argument>
+ using Bind =
+ Instantiate<Internal<Template>::template Bind,
+ Argument>; //#1
+
+ When #1 is parsed, the
+ BOUND_TEMPLATE_TEMPLATE_PARM representing the
+ parameter `Template' in #0 matches the
+ UNBOUND_CLASS_TEMPLATE representing the argument
+ `Internal<Template>::template Bind'; We then want
+ to assemble the type `Bind<Argument>' that can't
+ be fully created right now, because
+ `Internal<Template>' not being complete, the Bind
+ template cannot be looked up in that context. So
+ we need to "store" `Bind<Argument>' for later
+ when the context of Bind becomes complete. Let's
+ store that in a TYPENAME_TYPE. */
+ return make_typename_type (TYPE_CONTEXT (arg),
+ build_nt (TEMPLATE_ID_EXPR,
+ TYPE_IDENTIFIER (arg),
+ argvec),
+ typename_type,
+ complain);
+
+ /* We can get a TEMPLATE_TEMPLATE_PARM here when we
+ are resolving nested-types in the signature of a
+ member function templates. Otherwise ARG is a
+ TEMPLATE_DECL and is the real template to be
+ instantiated. */
+ if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+ arg = TYPE_NAME (arg);
+
+ r = lookup_template_class (arg,
+ argvec, in_decl,
+ DECL_CONTEXT (arg),
+ /*entering_scope=*/0,
+ complain);
+ return cp_build_qualified_type_real
+ (r, cp_type_quals (t) | cp_type_quals (r), complain);
+ }
+ else
+ /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX. */
+ return convert_from_reference (unshare_expr (arg));
+ }
+
+ if (level == 1)
+ /* This can happen during the attempted tsubst'ing in
+ unify. This means that we don't yet have any information
+ about the template parameter in question. */
+ return t;
+
+ /* Early in template argument deduction substitution, we don't
+ want to reduce the level of 'auto', or it will be confused
+ with a normal template parm in subsequent deduction. */
+ if (is_auto (t) && (complain & tf_partial))
+ return t;
+
+ /* If we get here, we must have been looking at a parm for a
+ more deeply nested template. Make a new version of this
+ template parameter, but with a lower level. */
+ switch (code)
+ {
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ if (cp_type_quals (t))
+ {
+ r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
+ r = cp_build_qualified_type_real
+ (r, cp_type_quals (t),
+ complain | (code == TEMPLATE_TYPE_PARM
+ ? tf_ignore_bad_quals : 0));
+ }
+ else
+ {
+ r = copy_type (t);
+ TEMPLATE_TYPE_PARM_INDEX (r)
+ = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
+ r, levels, args, complain);
+ TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
+ TYPE_MAIN_VARIANT (r) = r;
+ TYPE_POINTER_TO (r) = NULL_TREE;
+ TYPE_REFERENCE_TO (r) = NULL_TREE;
+
+ if (TREE_CODE (r) == TEMPLATE_TEMPLATE_PARM)
+ /* We have reduced the level of the template
+ template parameter, but not the levels of its
+ template parameters, so canonical_type_parameter
+ will not be able to find the canonical template
+ template parameter for this level. Thus, we
+ require structural equality checking to compare
+ TEMPLATE_TEMPLATE_PARMs. */
+ SET_TYPE_STRUCTURAL_EQUALITY (r);
+ else if (TYPE_STRUCTURAL_EQUALITY_P (t))
+ SET_TYPE_STRUCTURAL_EQUALITY (r);
+ else
+ TYPE_CANONICAL (r) = canonical_type_parameter (r);
+
+ if (code == BOUND_TEMPLATE_TEMPLATE_PARM)
+ {
+ tree argvec = tsubst (TYPE_TI_ARGS (t), args,
+ complain, in_decl);
+ if (argvec == error_mark_node)
+ return error_mark_node;
+
+ TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
+ = build_template_info (TYPE_TI_TEMPLATE (t), argvec);
+ }
+ }
+ break;
+
+ case TEMPLATE_PARM_INDEX:
+ r = reduce_template_parm_level (t, type, levels, args, complain);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return r;
+ }
+
+ case TREE_LIST:
+ {
+ tree purpose, value, chain;
+
+ if (t == void_list_node)
+ return t;
+
+ purpose = TREE_PURPOSE (t);
+ if (purpose)
+ {
+ purpose = tsubst (purpose, args, complain, in_decl);
+ if (purpose == error_mark_node)
+ return error_mark_node;
+ }
+ value = TREE_VALUE (t);
+ if (value)
+ {
+ value = tsubst (value, args, complain, in_decl);
+ if (value == error_mark_node)
+ return error_mark_node;
+ }
+ chain = TREE_CHAIN (t);
+ if (chain && chain != void_type_node)
+ {
+ chain = tsubst (chain, args, complain, in_decl);
+ if (chain == error_mark_node)
+ return error_mark_node;
+ }
+ if (purpose == TREE_PURPOSE (t)
+ && value == TREE_VALUE (t)
+ && chain == TREE_CHAIN (t))
+ return t;
+ return hash_tree_cons (purpose, value, chain);
+ }
+
+ case TREE_BINFO:
+ /* We should never be tsubsting a binfo. */
+ gcc_unreachable ();
+
+ case TREE_VEC:
+ /* A vector of template arguments. */
+ gcc_assert (!type);
+ return tsubst_template_args (t, args, complain, in_decl);
+
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ {
+ if (type == TREE_TYPE (t) && TREE_CODE (type) != METHOD_TYPE)
+ return t;
+
+ /* [temp.deduct]
+
+ Type deduction may fail for any of the following
+ reasons:
+
+ -- Attempting to create a pointer to reference type.
+ -- Attempting to create a reference to a reference type or
+ a reference to void.
+
+ Core issue 106 says that creating a reference to a reference
+ during instantiation is no longer a cause for failure. We
+ only enforce this check in strict C++98 mode. */
+ if ((TREE_CODE (type) == REFERENCE_TYPE
+ && (((cxx_dialect == cxx98) && flag_iso) || code != REFERENCE_TYPE))
+ || (code == REFERENCE_TYPE && VOID_TYPE_P (type)))
+ {
+ static location_t last_loc;
+
+ /* We keep track of the last time we issued this error
+ message to avoid spewing a ton of messages during a
+ single bad template instantiation. */
+ if (complain & tf_error
+ && last_loc != input_location)
+ {
+ if (VOID_TYPE_P (type))
+ error ("forming reference to void");
+ else if (code == POINTER_TYPE)
+ error ("forming pointer to reference type %qT", type);
+ else
+ error ("forming reference to reference type %qT", type);
+ last_loc = input_location;
+ }
+
+ return error_mark_node;
+ }
+ else if (TREE_CODE (type) == FUNCTION_TYPE
+ && (type_memfn_quals (type) != TYPE_UNQUALIFIED
+ || type_memfn_rqual (type) != REF_QUAL_NONE))
+ {
+ if (complain & tf_error)
+ {
+ if (code == POINTER_TYPE)
+ error ("forming pointer to qualified function type %qT",
+ type);
+ else
+ error ("forming reference to qualified function type %qT",
+ type);
+ }
+ return error_mark_node;
+ }
+ else if (code == POINTER_TYPE)
+ {
+ r = build_pointer_type (type);
+ if (TREE_CODE (type) == METHOD_TYPE)
+ r = build_ptrmemfunc_type (r);
+ }
+ else if (TREE_CODE (type) == REFERENCE_TYPE)
+ /* In C++0x, during template argument substitution, when there is an
+ attempt to create a reference to a reference type, reference
+ collapsing is applied as described in [14.3.1/4 temp.arg.type]:
+
+ "If a template-argument for a template-parameter T names a type
+ that is a reference to a type A, an attempt to create the type
+ 'lvalue reference to cv T' creates the type 'lvalue reference to
+ A,' while an attempt to create the type type rvalue reference to
+ cv T' creates the type T"
+ */
+ r = cp_build_reference_type
+ (TREE_TYPE (type),
+ TYPE_REF_IS_RVALUE (t) && TYPE_REF_IS_RVALUE (type));
+ else
+ r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
+ r = cp_build_qualified_type_real (r, cp_type_quals (t), complain);
+
+ if (cxx_dialect >= cxx1y
+ && !(TREE_CODE (t) == REFERENCE_TYPE && REFERENCE_VLA_OK (t))
+ && array_of_runtime_bound_p (type)
+ && (flag_iso || warn_vla > 0))
+ {
+ if (complain & tf_warning_or_error)
+ pedwarn
+ (input_location, OPT_Wvla,
+ code == REFERENCE_TYPE
+ ? G_("cannot declare reference to array of runtime bound")
+ : G_("cannot declare pointer to array of runtime bound"));
+ else
+ r = error_mark_node;
+ }
+
+ if (r != error_mark_node)
+ /* Will this ever be needed for TYPE_..._TO values? */
+ layout_type (r);
+
+ return r;
+ }
+ case OFFSET_TYPE:
+ {
+ r = tsubst (TYPE_OFFSET_BASETYPE (t), args, complain, in_decl);
+ if (r == error_mark_node || !MAYBE_CLASS_TYPE_P (r))
+ {
+ /* [temp.deduct]
+
+ Type deduction may fail for any of the following
+ reasons:
+
+ -- Attempting to create "pointer to member of T" when T
+ is not a class type. */
+ if (complain & tf_error)
+ error ("creating pointer to member of non-class type %qT", r);
+ return error_mark_node;
+ }
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (complain & tf_error)
+ error ("creating pointer to member reference type %qT", type);
+ return error_mark_node;
+ }
+ if (VOID_TYPE_P (type))
+ {
+ if (complain & tf_error)
+ error ("creating pointer to member of type void");
+ return error_mark_node;
+ }
+ gcc_assert (TREE_CODE (type) != METHOD_TYPE);
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ /* The type of the implicit object parameter gets its
+ cv-qualifiers from the FUNCTION_TYPE. */
+ tree memptr;
+ tree method_type
+ = build_memfn_type (type, r, type_memfn_quals (type),
+ type_memfn_rqual (type));
+ memptr = build_ptrmemfunc_type (build_pointer_type (method_type));
+ return cp_build_qualified_type_real (memptr, cp_type_quals (t),
+ complain);
+ }
+ else
+ return cp_build_qualified_type_real (build_ptrmem_type (r, type),
+ cp_type_quals (t),
+ complain);
+ }
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ {
+ tree fntype;
+ tree specs;
+ fntype = tsubst_function_type (t, args, complain, in_decl);
+ if (fntype == error_mark_node)
+ return error_mark_node;
+
+ /* Substitute the exception specification. */
+ specs = tsubst_exception_specification (t, args, complain,
+ in_decl, /*defer_ok*/true);
+ if (specs == error_mark_node)
+ return error_mark_node;
+ if (specs)
+ fntype = build_exception_variant (fntype, specs);
+ return fntype;
+ }
+ case ARRAY_TYPE:
+ {
+ tree domain = tsubst (TYPE_DOMAIN (t), args, complain, in_decl);
+ if (domain == error_mark_node)
+ return error_mark_node;
+
+ /* As an optimization, we avoid regenerating the array type if
+ it will obviously be the same as T. */
+ if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
+ return t;
+
+ /* These checks should match the ones in grokdeclarator.
+
+ [temp.deduct]
+
+ The deduction may fail for any of the following reasons:
+
+ -- Attempting to create an array with an element type that
+ is void, a function type, or a reference type, or [DR337]
+ an abstract class type. */
+ if (VOID_TYPE_P (type)
+ || TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (complain & tf_error)
+ error ("creating array of %qT", type);
+ return error_mark_node;
+ }
+
+ if (abstract_virtuals_error_sfinae (ACU_ARRAY, type, complain))
+ return error_mark_node;
+
+ r = build_cplus_array_type (type, domain);
+
+ if (TYPE_USER_ALIGN (t))
+ {
+ TYPE_ALIGN (r) = TYPE_ALIGN (t);
+ TYPE_USER_ALIGN (r) = 1;
+ }
+
+ return r;
+ }
+
+ case TYPENAME_TYPE:
+ {
+ tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain,
+ in_decl, /*entering_scope=*/1);
+ tree f = tsubst_copy (TYPENAME_TYPE_FULLNAME (t), args,
+ complain, in_decl);
+
+ if (ctx == error_mark_node || f == error_mark_node)
+ return error_mark_node;
+
+ if (!MAYBE_CLASS_TYPE_P (ctx))
+ {
+ if (complain & tf_error)
+ error ("%qT is not a class, struct, or union type", ctx);
+ return error_mark_node;
+ }
+ else if (!uses_template_parms (ctx) && !TYPE_BEING_DEFINED (ctx))
+ {
+ /* Normally, make_typename_type does not require that the CTX
+ have complete type in order to allow things like:
+
+ template <class T> struct S { typename S<T>::X Y; };
+
+ But, such constructs have already been resolved by this
+ point, so here CTX really should have complete type, unless
+ it's a partial instantiation. */
+ ctx = complete_type (ctx);
+ if (!COMPLETE_TYPE_P (ctx))
+ {
+ if (complain & tf_error)
+ cxx_incomplete_type_error (NULL_TREE, ctx);
+ return error_mark_node;
+ }
+ }
+
+ f = make_typename_type (ctx, f, typename_type,
+ complain | tf_keep_type_decl);
+ if (f == error_mark_node)
+ return f;
+ if (TREE_CODE (f) == TYPE_DECL)
+ {
+ complain |= tf_ignore_bad_quals;
+ f = TREE_TYPE (f);
+ }
+
+ if (TREE_CODE (f) != TYPENAME_TYPE)
+ {
+ if (TYPENAME_IS_ENUM_P (t) && TREE_CODE (f) != ENUMERAL_TYPE)
+ {
+ if (complain & tf_error)
+ error ("%qT resolves to %qT, which is not an enumeration type",
+ t, f);
+ else
+ return error_mark_node;
+ }
+ else if (TYPENAME_IS_CLASS_P (t) && !CLASS_TYPE_P (f))
+ {
+ if (complain & tf_error)
+ error ("%qT resolves to %qT, which is is not a class type",
+ t, f);
+ else
+ return error_mark_node;
+ }
+ }
+
+ return cp_build_qualified_type_real
+ (f, cp_type_quals (f) | cp_type_quals (t), complain);
+ }
+
+ case UNBOUND_CLASS_TEMPLATE:
+ {
+ tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain,
+ in_decl, /*entering_scope=*/1);
+ tree name = TYPE_IDENTIFIER (t);
+ tree parm_list = DECL_TEMPLATE_PARMS (TYPE_NAME (t));
+
+ if (ctx == error_mark_node || name == error_mark_node)
+ return error_mark_node;
+
+ if (parm_list)
+ parm_list = tsubst_template_parms (parm_list, args, complain);
+ return make_unbound_class_template (ctx, name, parm_list, complain);
+ }
+
+ case TYPEOF_TYPE:
+ {
+ tree type;
+
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
+
+ type = tsubst_expr (TYPEOF_TYPE_EXPR (t), args,
+ complain, in_decl,
+ /*integral_constant_expression_p=*/false);
+
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+
+ type = finish_typeof (type);
+ return cp_build_qualified_type_real (type,
+ cp_type_quals (t)
+ | cp_type_quals (type),
+ complain);
+ }
+
+ case DECLTYPE_TYPE:
+ {
+ tree type;
+
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
+
+ type = tsubst_copy_and_build (DECLTYPE_TYPE_EXPR (t), args,
+ complain|tf_decltype, in_decl,
+ /*function_p*/false,
+ /*integral_constant_expression*/false);
+
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+
+ if (DECLTYPE_FOR_LAMBDA_CAPTURE (t))
+ type = lambda_capture_field_type (type,
+ DECLTYPE_FOR_INIT_CAPTURE (t));
+ else if (DECLTYPE_FOR_LAMBDA_PROXY (t))
+ type = lambda_proxy_type (type);
+ else
+ {
+ bool id = DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t);
+ if (id && TREE_CODE (DECLTYPE_TYPE_EXPR (t)) == BIT_NOT_EXPR
+ && EXPR_P (type))
+ /* In a template ~id could be either a complement expression
+ or an unqualified-id naming a destructor; if instantiating
+ it produces an expression, it's not an id-expression or
+ member access. */
+ id = false;
+ type = finish_decltype_type (type, id, complain);
+ }
+ return cp_build_qualified_type_real (type,
+ cp_type_quals (t)
+ | cp_type_quals (type),
+ complain);
+ }
+
+ case UNDERLYING_TYPE:
+ {
+ tree type = tsubst (UNDERLYING_TYPE_TYPE (t), args,
+ complain, in_decl);
+ return finish_underlying_type (type);
+ }
+
+ case TYPE_ARGUMENT_PACK:
+ case NONTYPE_ARGUMENT_PACK:
+ {
+ tree r = TYPE_P (t) ? cxx_make_type (code) : make_node (code);
+ tree packed_out =
+ tsubst_template_args (ARGUMENT_PACK_ARGS (t),
+ args,
+ complain,
+ in_decl);
+ SET_ARGUMENT_PACK_ARGS (r, packed_out);
+
+ /* For template nontype argument packs, also substitute into
+ the type. */
+ if (code == NONTYPE_ARGUMENT_PACK)
+ TREE_TYPE (r) = tsubst (TREE_TYPE (t), args, complain, in_decl);
+
+ return r;
+ }
+ break;
+
+ case INTEGER_CST:
+ case REAL_CST:
+ case STRING_CST:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case NEGATE_EXPR:
+ case NOP_EXPR:
+ case INDIRECT_REF:
+ case ADDR_EXPR:
+ case CALL_EXPR:
+ case ARRAY_REF:
+ case SCOPE_REF:
+ /* We should use one of the expression tsubsts for these codes. */
+ gcc_unreachable ();
+
+ default:
+ sorry ("use of %qs in template", get_tree_code_name (code));
+ return error_mark_node;
+ }
+}
+
+/* Like tsubst_expr for a BASELINK. OBJECT_TYPE, if non-NULL, is the
+ type of the expression on the left-hand side of the "." or "->"
+ operator. */
+
+static tree
+tsubst_baselink (tree baselink, tree object_type,
+ tree args, tsubst_flags_t complain, tree in_decl)
+{
+ tree name;
+ tree qualifying_scope;
+ tree fns;
+ tree optype;
+ tree template_args = 0;
+ bool template_id_p = false;
+ bool qualified = BASELINK_QUALIFIED_P (baselink);
+
+ /* A baselink indicates a function from a base class. Both the
+ BASELINK_ACCESS_BINFO and the base class referenced may
+ indicate bases of the template class, rather than the
+ instantiated class. In addition, lookups that were not
+ ambiguous before may be ambiguous now. Therefore, we perform
+ the lookup again. */
+ qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink));
+ qualifying_scope = tsubst (qualifying_scope, args,
+ complain, in_decl);
+ fns = BASELINK_FUNCTIONS (baselink);
+ optype = tsubst (BASELINK_OPTYPE (baselink), args, complain, in_decl);
+ if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
+ {
+ template_id_p = true;
+ template_args = TREE_OPERAND (fns, 1);
+ fns = TREE_OPERAND (fns, 0);
+ if (template_args)
+ template_args = tsubst_template_args (template_args, args,
+ complain, in_decl);
+ }
+ name = DECL_NAME (get_first_fn (fns));
+ if (IDENTIFIER_TYPENAME_P (name))
+ name = mangle_conv_op_name_for_type (optype);
+ baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
+ if (!baselink)
+ return error_mark_node;
+
+ /* If lookup found a single function, mark it as used at this
+ point. (If it lookup found multiple functions the one selected
+ later by overload resolution will be marked as used at that
+ point.) */
+ if (BASELINK_P (baselink))
+ fns = BASELINK_FUNCTIONS (baselink);
+ if (!template_id_p && !really_overloaded_fn (fns))
+ mark_used (OVL_CURRENT (fns));
+
+ /* Add back the template arguments, if present. */
+ if (BASELINK_P (baselink) && template_id_p)
+ BASELINK_FUNCTIONS (baselink)
+ = build_nt (TEMPLATE_ID_EXPR,
+ BASELINK_FUNCTIONS (baselink),
+ template_args);
+ /* Update the conversion operator type. */
+ BASELINK_OPTYPE (baselink) = optype;
+
+ if (!object_type)
+ object_type = current_class_type;
+
+ if (qualified)
+ baselink = adjust_result_of_qualified_name_lookup (baselink,
+ qualifying_scope,
+ object_type);
+ return baselink;
+}
+
+/* Like tsubst_expr for a SCOPE_REF, given by QUALIFIED_ID. DONE is
+ true if the qualified-id will be a postfix-expression in-and-of
+ itself; false if more of the postfix-expression follows the
+ QUALIFIED_ID. ADDRESS_P is true if the qualified-id is the operand
+ of "&". */
+
+static tree
+tsubst_qualified_id (tree qualified_id, tree args,
+ tsubst_flags_t complain, tree in_decl,
+ bool done, bool address_p)
+{
+ tree expr;
+ tree scope;
+ tree name;
+ bool is_template;
+ tree template_args;
+ location_t loc = UNKNOWN_LOCATION;
+
+ gcc_assert (TREE_CODE (qualified_id) == SCOPE_REF);
+
+ /* Figure out what name to look up. */
+ name = TREE_OPERAND (qualified_id, 1);
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ is_template = true;
+ loc = EXPR_LOCATION (name);
+ template_args = TREE_OPERAND (name, 1);
+ if (template_args)
+ template_args = tsubst_template_args (template_args, args,
+ complain, in_decl);
+ name = TREE_OPERAND (name, 0);
+ }
+ else
+ {
+ is_template = false;
+ template_args = NULL_TREE;
+ }
+
+ /* Substitute into the qualifying scope. When there are no ARGS, we
+ are just trying to simplify a non-dependent expression. In that
+ case the qualifying scope may be dependent, and, in any case,
+ substituting will not help. */
+ scope = TREE_OPERAND (qualified_id, 0);
+ if (args)
+ {
+ scope = tsubst (scope, args, complain, in_decl);
+ expr = tsubst_copy (name, args, complain, in_decl);
+ }
+ else
+ expr = name;
+
+ if (dependent_scope_p (scope))
+ {
+ if (is_template)
+ expr = build_min_nt_loc (loc, TEMPLATE_ID_EXPR, expr, template_args);
+ return build_qualified_name (NULL_TREE, scope, expr,
+ QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
+ }
+
+ if (!BASELINK_P (name) && !DECL_P (expr))
+ {
+ if (TREE_CODE (expr) == BIT_NOT_EXPR)
+ {
+ /* A BIT_NOT_EXPR is used to represent a destructor. */
+ if (!check_dtor_name (scope, TREE_OPERAND (expr, 0)))
+ {
+ error ("qualifying type %qT does not match destructor name ~%qT",
+ scope, TREE_OPERAND (expr, 0));
+ expr = error_mark_node;
+ }
+ else
+ expr = lookup_qualified_name (scope, complete_dtor_identifier,
+ /*is_type_p=*/0, false);
+ }
+ else
+ expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
+ if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL
+ ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL)
+ {
+ if (complain & tf_error)
+ {
+ error ("dependent-name %qE is parsed as a non-type, but "
+ "instantiation yields a type", qualified_id);
+ inform (input_location, "say %<typename %E%> if a type is meant", qualified_id);
+ }
+ return error_mark_node;
+ }
+ }
+
+ if (DECL_P (expr))
+ {
+ check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE,
+ scope);
+ /* Remember that there was a reference to this entity. */
+ mark_used (expr);
+ }
+
+ if (expr == error_mark_node || TREE_CODE (expr) == TREE_LIST)
+ {
+ if (complain & tf_error)
+ qualified_name_lookup_error (scope,
+ TREE_OPERAND (qualified_id, 1),
+ expr, input_location);
+ return error_mark_node;
+ }
+
+ if (is_template)
+ expr = lookup_template_function (expr, template_args);
+
+ if (expr == error_mark_node && complain & tf_error)
+ qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1),
+ expr, input_location);
+ else if (TYPE_P (scope))
+ {
+ expr = (adjust_result_of_qualified_name_lookup
+ (expr, scope, current_nonlambda_class_type ()));
+ expr = (finish_qualified_id_expr
+ (scope, expr, done, address_p && PTRMEM_OK_P (qualified_id),
+ QUALIFIED_NAME_IS_TEMPLATE (qualified_id),
+ /*template_arg_p=*/false, complain));
+ }
+
+ /* Expressions do not generally have reference type. */
+ if (TREE_CODE (expr) != SCOPE_REF
+ /* However, if we're about to form a pointer-to-member, we just
+ want the referenced member referenced. */
+ && TREE_CODE (expr) != OFFSET_REF)
+ expr = convert_from_reference (expr);
+
+ return expr;
+}
+
+/* Like tsubst, but deals with expressions. This function just replaces
+ template parms; to finish processing the resultant expression, use
+ tsubst_copy_and_build or tsubst_expr. */
+
+static tree
+tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+{
+ enum tree_code code;
+ tree r;
+
+ if (t == NULL_TREE || t == error_mark_node || args == NULL_TREE)
+ return t;
+
+ code = TREE_CODE (t);
+
+ switch (code)
+ {
+ case PARM_DECL:
+ r = retrieve_local_specialization (t);
+
+ if (r == NULL_TREE)
+ {
+ /* We get here for a use of 'this' in an NSDMI. */
+ if (DECL_NAME (t) == this_identifier
+ && at_function_scope_p ()
+ && DECL_CONSTRUCTOR_P (current_function_decl))
+ return current_class_ptr;
+
+ /* This can happen for a parameter name used later in a function
+ declaration (such as in a late-specified return type). Just
+ make a dummy decl, since it's only used for its type. */
+ gcc_assert (cp_unevaluated_operand != 0);
+ r = tsubst_decl (t, args, complain);
+ /* Give it the template pattern as its context; its true context
+ hasn't been instantiated yet and this is good enough for
+ mangling. */
+ DECL_CONTEXT (r) = DECL_CONTEXT (t);
+ }
+
+ if (TREE_CODE (r) == ARGUMENT_PACK_SELECT)
+ r = ARGUMENT_PACK_SELECT_ARG (r);
+ mark_used (r);
+ return r;
+
+ case CONST_DECL:
+ {
+ tree enum_type;
+ tree v;
+
+ if (DECL_TEMPLATE_PARM_P (t))
+ return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
+ /* There is no need to substitute into namespace-scope
+ enumerators. */
+ if (DECL_NAMESPACE_SCOPE_P (t))
+ return t;
+ /* If ARGS is NULL, then T is known to be non-dependent. */
+ if (args == NULL_TREE)
+ return integral_constant_value (t);
+
+ /* Unfortunately, we cannot just call lookup_name here.
+ Consider:
+
+ template <int I> int f() {
+ enum E { a = I };
+ struct S { void g() { E e = a; } };
+ };
+
+ When we instantiate f<7>::S::g(), say, lookup_name is not
+ clever enough to find f<7>::a. */
+ enum_type
+ = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl,
+ /*entering_scope=*/0);
+
+ for (v = TYPE_VALUES (enum_type);
+ v != NULL_TREE;
+ v = TREE_CHAIN (v))
+ if (TREE_PURPOSE (v) == DECL_NAME (t))
+ return TREE_VALUE (v);
+
+ /* We didn't find the name. That should never happen; if
+ name-lookup found it during preliminary parsing, we
+ should find it again here during instantiation. */
+ gcc_unreachable ();
+ }
+ return t;
+
+ case FIELD_DECL:
+ if (PACK_EXPANSION_P (TREE_TYPE (t)))
+ {
+ /* Check for a local specialization set up by
+ tsubst_pack_expansion. */
+ if (tree r = retrieve_local_specialization (t))
+ {
+ if (TREE_CODE (r) == ARGUMENT_PACK_SELECT)
+ r = ARGUMENT_PACK_SELECT_ARG (r);
+ return r;
+ }
+
+ /* When retrieving a capture pack from a generic lambda, remove the
+ lambda call op's own template argument list from ARGS. Only the
+ template arguments active for the closure type should be used to
+ retrieve the pack specialization. */
+ if (LAMBDA_FUNCTION_P (current_function_decl)
+ && (template_class_depth (DECL_CONTEXT (t))
+ != TMPL_ARGS_DEPTH (args)))
+ args = strip_innermost_template_args (args, 1);
+
+ /* Otherwise return the full NONTYPE_ARGUMENT_PACK that
+ tsubst_decl put in the hash table. */
+ return retrieve_specialization (t, args, 0);
+ }
+
+ if (DECL_CONTEXT (t))
+ {
+ tree ctx;
+
+ ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl,
+ /*entering_scope=*/1);
+ if (ctx != DECL_CONTEXT (t))
+ {
+ tree r = lookup_field (ctx, DECL_NAME (t), 0, false);
+ if (!r)
+ {
+ if (complain & tf_error)
+ error ("using invalid field %qD", t);
+ return error_mark_node;
+ }
+ return r;
+ }
+ }
+
+ return t;
+
+ case VAR_DECL:
+ case FUNCTION_DECL:
+ if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
+ r = tsubst (t, args, complain, in_decl);
+ else if (local_variable_p (t))
+ {
+ r = retrieve_local_specialization (t);
+ if (r == NULL_TREE)
+ {
+ if (DECL_ANON_UNION_VAR_P (t))
+ {
+ /* Just use name lookup to find a member alias for an
+ anonymous union, but then add it to the hash table. */
+ r = lookup_name (DECL_NAME (t));
+ gcc_assert (DECL_ANON_UNION_VAR_P (r));
+ register_local_specialization (r, t);
+ }
+ else
+ {
+ /* This can happen for a variable used in a late-specified
+ return type of a local lambda. Just make a dummy decl
+ since it's only used for its type. */
+ if (cp_unevaluated_operand)
+ return tsubst_decl (t, args, complain);
+ gcc_assert (errorcount || sorrycount);
+ return error_mark_node;
+ }
+ }
+ }
+ else
+ r = t;
+ mark_used (r);
+ return r;
+
+ case NAMESPACE_DECL:
+ return t;
+
+ case OVERLOAD:
+ /* An OVERLOAD will always be a non-dependent overload set; an
+ overload set from function scope will just be represented with an
+ IDENTIFIER_NODE, and from class scope with a BASELINK. */
+ gcc_assert (!uses_template_parms (t));
+ return t;
+
+ case BASELINK:
+ return tsubst_baselink (t, current_nonlambda_class_type (),
+ args, complain, in_decl);
+
+ case TEMPLATE_DECL:
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
+ return tsubst (TREE_TYPE (DECL_TEMPLATE_RESULT (t)),
+ args, complain, in_decl);
+ else if (DECL_FUNCTION_TEMPLATE_P (t) && DECL_MEMBER_TEMPLATE_P (t))
+ return tsubst (t, args, complain, in_decl);
+ else if (DECL_CLASS_SCOPE_P (t)
+ && uses_template_parms (DECL_CONTEXT (t)))
+ {
+ /* Template template argument like the following example need
+ special treatment:
+
+ template <template <class> class TT> struct C {};
+ template <class T> struct D {
+ template <class U> struct E {};
+ C<E> c; // #1
+ };
+ D<int> d; // #2
+
+ We are processing the template argument `E' in #1 for
+ the template instantiation #2. Originally, `E' is a
+ TEMPLATE_DECL with `D<T>' as its DECL_CONTEXT. Now we
+ have to substitute this with one having context `D<int>'. */
+
+ tree context = tsubst (DECL_CONTEXT (t), args, complain, in_decl);
+ return lookup_field (context, DECL_NAME(t), 0, false);
+ }
+ else
+ /* Ordinary template template argument. */
+ return t;
+
+ case CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
+ case CONVERT_EXPR:
+ case NOP_EXPR:
+ return build1
+ (code, tsubst (TREE_TYPE (t), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));
+
+ case SIZEOF_EXPR:
+ if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
+ {
+
+ tree expanded, op = TREE_OPERAND (t, 0);
+ int len = 0;
+
+ if (SIZEOF_EXPR_TYPE_P (t))
+ op = TREE_TYPE (op);
+
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
+ /* We only want to compute the number of arguments. */
+ expanded = tsubst_pack_expansion (op, args, complain, in_decl);
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+
+ if (TREE_CODE (expanded) == TREE_VEC)
+ len = TREE_VEC_LENGTH (expanded);
+
+ if (expanded == error_mark_node)
+ return error_mark_node;
+ else if (PACK_EXPANSION_P (expanded)
+ || (TREE_CODE (expanded) == TREE_VEC
+ && len > 0
+ && PACK_EXPANSION_P (TREE_VEC_ELT (expanded, len-1))))
+ {
+ if (TREE_CODE (expanded) == TREE_VEC)
+ expanded = TREE_VEC_ELT (expanded, len - 1);
+
+ if (TYPE_P (expanded))
+ return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR,
+ complain & tf_error);
+ else
+ return cxx_sizeof_or_alignof_expr (expanded, SIZEOF_EXPR,
+ complain & tf_error);
+ }
+ else
+ return build_int_cst (size_type_node, len);
+ }
+ if (SIZEOF_EXPR_TYPE_P (t))
+ {
+ r = tsubst (TREE_TYPE (TREE_OPERAND (t, 0)),
+ args, complain, in_decl);
+ r = build1 (NOP_EXPR, r, error_mark_node);
+ r = build1 (SIZEOF_EXPR,
+ tsubst (TREE_TYPE (t), args, complain, in_decl), r);
+ SIZEOF_EXPR_TYPE_P (r) = 1;
+ return r;
+ }
+ /* Fall through */
+
+ case INDIRECT_REF:
+ case NEGATE_EXPR:
+ case TRUTH_NOT_EXPR:
+ case BIT_NOT_EXPR:
+ case ADDR_EXPR:
+ case UNARY_PLUS_EXPR: /* Unary + */
+ case ALIGNOF_EXPR:
+ case AT_ENCODE_EXPR:
+ case ARROW_EXPR:
+ case THROW_EXPR:
+ case TYPEID_EXPR:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case PAREN_EXPR:
+ return build1
+ (code, tsubst (TREE_TYPE (t), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));
+
+ case COMPONENT_REF:
+ {
+ tree object;
+ tree name;
+
+ object = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+ name = TREE_OPERAND (t, 1);
+ if (TREE_CODE (name) == BIT_NOT_EXPR)
+ {
+ name = tsubst_copy (TREE_OPERAND (name, 0), args,
+ complain, in_decl);
+ name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
+ }
+ else if (TREE_CODE (name) == SCOPE_REF
+ && TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR)
+ {
+ tree base = tsubst_copy (TREE_OPERAND (name, 0), args,
+ complain, in_decl);
+ name = TREE_OPERAND (name, 1);
+ name = tsubst_copy (TREE_OPERAND (name, 0), args,
+ complain, in_decl);
+ name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
+ name = build_qualified_name (/*type=*/NULL_TREE,
+ base, name,
+ /*template_p=*/false);
+ }
+ else if (BASELINK_P (name))
+ name = tsubst_baselink (name,
+ non_reference (TREE_TYPE (object)),
+ args, complain,
+ in_decl);
+ else
+ name = tsubst_copy (name, args, complain, in_decl);
+ return build_nt (COMPONENT_REF, object, name, NULL_TREE);
+ }
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case TRUNC_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case RSHIFT_EXPR:
+ case LSHIFT_EXPR:
+ case RROTATE_EXPR:
+ case LROTATE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case MAX_EXPR:
+ case MIN_EXPR:
+ case LE_EXPR:
+ case GE_EXPR:
+ case LT_EXPR:
+ case GT_EXPR:
+ case COMPOUND_EXPR:
+ case DOTSTAR_EXPR:
+ case MEMBER_REF:
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ return build_nt
+ (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
+
+ case SCOPE_REF:
+ return build_qualified_name (/*type=*/NULL_TREE,
+ tsubst_copy (TREE_OPERAND (t, 0),
+ args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 1),
+ args, complain, in_decl),
+ QUALIFIED_NAME_IS_TEMPLATE (t));
+
+ case ARRAY_REF:
+ return build_nt
+ (ARRAY_REF,
+ tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
+ NULL_TREE, NULL_TREE);
+
+ case CALL_EXPR:
+ {
+ int n = VL_EXP_OPERAND_LENGTH (t);
+ tree result = build_vl_exp (CALL_EXPR, n);
+ int i;
+ for (i = 0; i < n; i++)
+ TREE_OPERAND (t, i) = tsubst_copy (TREE_OPERAND (t, i), args,
+ complain, in_decl);
+ return result;
+ }
+
+ case COND_EXPR:
+ case MODOP_EXPR:
+ case PSEUDO_DTOR_EXPR:
+ case VEC_PERM_EXPR:
+ {
+ r = build_nt
+ (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl));
+ TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
+ return r;
+ }
+
+ case NEW_EXPR:
+ {
+ r = build_nt
+ (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl));
+ NEW_EXPR_USE_GLOBAL (r) = NEW_EXPR_USE_GLOBAL (t);
+ return r;
+ }
+
+ case DELETE_EXPR:
+ {
+ r = build_nt
+ (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
+ DELETE_EXPR_USE_GLOBAL (r) = DELETE_EXPR_USE_GLOBAL (t);
+ DELETE_EXPR_USE_VEC (r) = DELETE_EXPR_USE_VEC (t);
+ return r;
+ }
+
+ case TEMPLATE_ID_EXPR:
+ {
+ /* Substituted template arguments */
+ tree fn = TREE_OPERAND (t, 0);
+ tree targs = TREE_OPERAND (t, 1);
+
+ fn = tsubst_copy (fn, args, complain, in_decl);
+ if (targs)
+ targs = tsubst_template_args (targs, args, complain, in_decl);
+
+ return lookup_template_function (fn, targs);
+ }
+
+ case TREE_LIST:
+ {
+ tree purpose, value, chain;
+
+ if (t == void_list_node)
+ return t;
+
+ purpose = TREE_PURPOSE (t);
+ if (purpose)
+ purpose = tsubst_copy (purpose, args, complain, in_decl);
+ value = TREE_VALUE (t);
+ if (value)
+ value = tsubst_copy (value, args, complain, in_decl);
+ chain = TREE_CHAIN (t);
+ if (chain && chain != void_type_node)
+ chain = tsubst_copy (chain, args, complain, in_decl);
+ if (purpose == TREE_PURPOSE (t)
+ && value == TREE_VALUE (t)
+ && chain == TREE_CHAIN (t))
+ return t;
+ return tree_cons (purpose, value, chain);
+ }
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ case INTEGER_TYPE:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ case OFFSET_TYPE:
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ case ARRAY_TYPE:
+ case TYPENAME_TYPE:
+ case UNBOUND_CLASS_TEMPLATE:
+ case TYPEOF_TYPE:
+ case DECLTYPE_TYPE:
+ case TYPE_DECL:
+ return tsubst (t, args, complain, in_decl);
+
+ case USING_DECL:
+ t = DECL_NAME (t);
+ /* Fall through. */
+ case IDENTIFIER_NODE:
+ if (IDENTIFIER_TYPENAME_P (t))
+ {
+ tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ return mangle_conv_op_name_for_type (new_type);
+ }
+ else
+ return t;
+
+ case CONSTRUCTOR:
+ /* This is handled by tsubst_copy_and_build. */
+ gcc_unreachable ();
+
+ case VA_ARG_EXPR:
+ return build_x_va_arg (EXPR_LOCATION (t),
+ tsubst_copy (TREE_OPERAND (t, 0), args, complain,
+ in_decl),
+ tsubst (TREE_TYPE (t), args, complain, in_decl));
+
+ case CLEANUP_POINT_EXPR:
+ /* We shouldn't have built any of these during initial template
+ generation. Instead, they should be built during instantiation
+ in response to the saved STMT_IS_FULL_EXPR_P setting. */
+ gcc_unreachable ();
+
+ case OFFSET_REF:
+ r = build2
+ (code, tsubst (TREE_TYPE (t), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
+ PTRMEM_OK_P (r) = PTRMEM_OK_P (t);
+ mark_used (TREE_OPERAND (r, 1));
+ return r;
+
+ case EXPR_PACK_EXPANSION:
+ error ("invalid use of pack expansion expression");
+ return error_mark_node;
+
+ case NONTYPE_ARGUMENT_PACK:
+ error ("use %<...%> to expand argument pack");
+ return error_mark_node;
+
+ case INTEGER_CST:
+ case REAL_CST:
+ case STRING_CST:
+ case COMPLEX_CST:
+ {
+ /* Instantiate any typedefs in the type. */
+ tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ r = fold_convert (type, t);
+ gcc_assert (TREE_CODE (r) == code);
+ return r;
+ }
+
+ case PTRMEM_CST:
+ /* These can sometimes show up in a partial instantiation, but never
+ involve template parms. */
+ gcc_assert (!uses_template_parms (t));
+ return t;
+
+ default:
+ /* We shouldn't get here, but keep going if !ENABLE_CHECKING. */
+ gcc_checking_assert (false);
+ return t;
+ }
+}
+
+/* Like tsubst_copy, but specifically for OpenMP clauses. */
+
+static tree
+tsubst_omp_clauses (tree clauses, bool declare_simd,
+ tree args, tsubst_flags_t complain, tree in_decl)
+{
+ tree new_clauses = NULL, nc, oc;
+
+ for (oc = clauses; oc ; oc = OMP_CLAUSE_CHAIN (oc))
+ {
+ nc = copy_node (oc);
+ OMP_CLAUSE_CHAIN (nc) = new_clauses;
+ new_clauses = nc;
+
+ switch (OMP_CLAUSE_CODE (nc))
+ {
+ case OMP_CLAUSE_LASTPRIVATE:
+ if (OMP_CLAUSE_LASTPRIVATE_STMT (oc))
+ {
+ OMP_CLAUSE_LASTPRIVATE_STMT (nc) = push_stmt_list ();
+ tsubst_expr (OMP_CLAUSE_LASTPRIVATE_STMT (oc), args, complain,
+ in_decl, /*integral_constant_expression_p=*/false);
+ OMP_CLAUSE_LASTPRIVATE_STMT (nc)
+ = pop_stmt_list (OMP_CLAUSE_LASTPRIVATE_STMT (nc));
+ }
+ /* FALLTHRU */
+ case OMP_CLAUSE_PRIVATE:
+ case OMP_CLAUSE_SHARED:
+ case OMP_CLAUSE_FIRSTPRIVATE:
+ case OMP_CLAUSE_COPYIN:
+ case OMP_CLAUSE_COPYPRIVATE:
+ case OMP_CLAUSE_IF:
+ case OMP_CLAUSE_NUM_THREADS:
+ case OMP_CLAUSE_SCHEDULE:
+ case OMP_CLAUSE_COLLAPSE:
+ case OMP_CLAUSE_FINAL:
+ case OMP_CLAUSE_DEPEND:
+ case OMP_CLAUSE_FROM:
+ case OMP_CLAUSE_TO:
+ case OMP_CLAUSE_UNIFORM:
+ case OMP_CLAUSE_MAP:
+ case OMP_CLAUSE_DEVICE:
+ case OMP_CLAUSE_DIST_SCHEDULE:
+ case OMP_CLAUSE_NUM_TEAMS:
+ case OMP_CLAUSE_THREAD_LIMIT:
+ case OMP_CLAUSE_SAFELEN:
+ case OMP_CLAUSE_SIMDLEN:
+ OMP_CLAUSE_OPERAND (nc, 0)
+ = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
+ in_decl, /*integral_constant_expression_p=*/false);
+ break;
+ case OMP_CLAUSE_REDUCTION:
+ if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (oc))
+ {
+ tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (oc);
+ if (TREE_CODE (placeholder) == SCOPE_REF)
+ {
+ tree scope = tsubst (TREE_OPERAND (placeholder, 0), args,
+ complain, in_decl);
+ OMP_CLAUSE_REDUCTION_PLACEHOLDER (nc)
+ = build_qualified_name (NULL_TREE, scope,
+ TREE_OPERAND (placeholder, 1),
+ false);
+ }
+ else
+ gcc_assert (identifier_p (placeholder));
+ }
+ OMP_CLAUSE_OPERAND (nc, 0)
+ = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
+ in_decl, /*integral_constant_expression_p=*/false);
+ break;
+ case OMP_CLAUSE_LINEAR:
+ case OMP_CLAUSE_ALIGNED:
+ OMP_CLAUSE_OPERAND (nc, 0)
+ = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
+ in_decl, /*integral_constant_expression_p=*/false);
+ OMP_CLAUSE_OPERAND (nc, 1)
+ = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain,
+ in_decl, /*integral_constant_expression_p=*/false);
+ break;
+
+ case OMP_CLAUSE_NOWAIT:
+ case OMP_CLAUSE_ORDERED:
+ case OMP_CLAUSE_DEFAULT:
+ case OMP_CLAUSE_UNTIED:
+ case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_INBRANCH:
+ case OMP_CLAUSE_NOTINBRANCH:
+ case OMP_CLAUSE_PROC_BIND:
+ case OMP_CLAUSE_FOR:
+ case OMP_CLAUSE_PARALLEL:
+ case OMP_CLAUSE_SECTIONS:
+ case OMP_CLAUSE_TASKGROUP:
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+
+ new_clauses = nreverse (new_clauses);
+ if (!declare_simd)
+ new_clauses = finish_omp_clauses (new_clauses);
+ return new_clauses;
+}
+
+/* Like tsubst_copy_and_build, but unshare TREE_LIST nodes. */
+
+static tree
+tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain,
+ tree in_decl)
+{
+#define RECUR(t) tsubst_copy_asm_operands (t, args, complain, in_decl)
+
+ tree purpose, value, chain;
+
+ if (t == NULL)
+ return t;
+
+ if (TREE_CODE (t) != TREE_LIST)
+ return tsubst_copy_and_build (t, args, complain, in_decl,
+ /*function_p=*/false,
+ /*integral_constant_expression_p=*/false);
+
+ if (t == void_list_node)
+ return t;
+
+ purpose = TREE_PURPOSE (t);
+ if (purpose)
+ purpose = RECUR (purpose);
+ value = TREE_VALUE (t);
+ if (value)
+ {
+ if (TREE_CODE (value) != LABEL_DECL)
+ value = RECUR (value);
+ else
+ {
+ value = lookup_label (DECL_NAME (value));
+ gcc_assert (TREE_CODE (value) == LABEL_DECL);
+ TREE_USED (value) = 1;
+ }
+ }
+ chain = TREE_CHAIN (t);
+ if (chain && chain != void_type_node)
+ chain = RECUR (chain);
+ return tree_cons (purpose, value, chain);
+#undef RECUR
+}
+
+/* Substitute one OMP_FOR iterator. */
+
+static void
+tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
+ tree condv, tree incrv, tree *clauses,
+ tree args, tsubst_flags_t complain, tree in_decl,
+ bool integral_constant_expression_p)
+{
+#define RECUR(NODE) \
+ tsubst_expr ((NODE), args, complain, in_decl, \
+ integral_constant_expression_p)
+ tree decl, init, cond, incr;
+
+ init = TREE_VEC_ELT (OMP_FOR_INIT (t), i);
+ gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
+ decl = TREE_OPERAND (init, 0);
+ init = TREE_OPERAND (init, 1);
+ tree decl_expr = NULL_TREE;
+ if (init && TREE_CODE (init) == DECL_EXPR)
+ {
+ /* We need to jump through some hoops to handle declarations in the
+ for-init-statement, since we might need to handle auto deduction,
+ but we need to keep control of initialization. */
+ decl_expr = init;
+ init = DECL_INITIAL (DECL_EXPR_DECL (init));
+ decl = tsubst_decl (decl, args, complain);
+ }
+ else
+ decl = RECUR (decl);
+ init = RECUR (init);
+
+ tree auto_node = type_uses_auto (TREE_TYPE (decl));
+ if (auto_node && init)
+ TREE_TYPE (decl)
+ = do_auto_deduction (TREE_TYPE (decl), init, auto_node);
+
+ gcc_assert (!type_dependent_expression_p (decl));
+
+ if (!CLASS_TYPE_P (TREE_TYPE (decl)))
+ {
+ if (decl_expr)
+ {
+ /* Declare the variable, but don't let that initialize it. */
+ tree init_sav = DECL_INITIAL (DECL_EXPR_DECL (decl_expr));
+ DECL_INITIAL (DECL_EXPR_DECL (decl_expr)) = NULL_TREE;
+ RECUR (decl_expr);
+ DECL_INITIAL (DECL_EXPR_DECL (decl_expr)) = init_sav;
+ }
+
+ cond = RECUR (TREE_VEC_ELT (OMP_FOR_COND (t), i));
+ incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i);
+ if (TREE_CODE (incr) == MODIFY_EXPR)
+ incr = build_x_modify_expr (EXPR_LOCATION (incr),
+ RECUR (TREE_OPERAND (incr, 0)), NOP_EXPR,
+ RECUR (TREE_OPERAND (incr, 1)),
+ complain);
+ else
+ incr = RECUR (incr);
+ TREE_VEC_ELT (declv, i) = decl;
+ TREE_VEC_ELT (initv, i) = init;
+ TREE_VEC_ELT (condv, i) = cond;
+ TREE_VEC_ELT (incrv, i) = incr;
+ return;
+ }
+
+ if (decl_expr)
+ {
+ /* Declare and initialize the variable. */
+ RECUR (decl_expr);
+ init = NULL_TREE;
+ }
+ else if (init)
+ {
+ tree c;
+ for (c = *clauses; c ; c = OMP_CLAUSE_CHAIN (c))
+ {
+ if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+ && OMP_CLAUSE_DECL (c) == decl)
+ break;
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+ && OMP_CLAUSE_DECL (c) == decl)
+ error ("iteration variable %qD should not be firstprivate", decl);
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+ && OMP_CLAUSE_DECL (c) == decl)
+ error ("iteration variable %qD should not be reduction", decl);
+ }
+ if (c == NULL)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
+ OMP_CLAUSE_DECL (c) = decl;
+ c = finish_omp_clauses (c);
+ if (c)
+ {
+ OMP_CLAUSE_CHAIN (c) = *clauses;
+ *clauses = c;
+ }
+ }
+ }
+ cond = TREE_VEC_ELT (OMP_FOR_COND (t), i);
+ if (COMPARISON_CLASS_P (cond))
+ cond = build2 (TREE_CODE (cond), boolean_type_node,
+ RECUR (TREE_OPERAND (cond, 0)),
+ RECUR (TREE_OPERAND (cond, 1)));
+ else
+ cond = RECUR (cond);
+ incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i);
+ switch (TREE_CODE (incr))
+ {
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ incr = build2 (TREE_CODE (incr), TREE_TYPE (decl),
+ RECUR (TREE_OPERAND (incr, 0)), NULL_TREE);
+ break;
+ case MODIFY_EXPR:
+ if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
+ || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
+ {
+ tree rhs = TREE_OPERAND (incr, 1);
+ incr = build2 (MODIFY_EXPR, TREE_TYPE (decl),
+ RECUR (TREE_OPERAND (incr, 0)),
+ build2 (TREE_CODE (rhs), TREE_TYPE (decl),
+ RECUR (TREE_OPERAND (rhs, 0)),
+ RECUR (TREE_OPERAND (rhs, 1))));
+ }
+ else
+ incr = RECUR (incr);
+ break;
+ case MODOP_EXPR:
+ if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
+ || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
+ {
+ tree lhs = RECUR (TREE_OPERAND (incr, 0));
+ incr = build2 (MODIFY_EXPR, TREE_TYPE (decl), lhs,
+ build2 (TREE_CODE (TREE_OPERAND (incr, 1)),
+ TREE_TYPE (decl), lhs,
+ RECUR (TREE_OPERAND (incr, 2))));
+ }
+ else if (TREE_CODE (TREE_OPERAND (incr, 1)) == NOP_EXPR
+ && (TREE_CODE (TREE_OPERAND (incr, 2)) == PLUS_EXPR
+ || (TREE_CODE (TREE_OPERAND (incr, 2)) == MINUS_EXPR)))
+ {
+ tree rhs = TREE_OPERAND (incr, 2);
+ incr = build2 (MODIFY_EXPR, TREE_TYPE (decl),
+ RECUR (TREE_OPERAND (incr, 0)),
+ build2 (TREE_CODE (rhs), TREE_TYPE (decl),
+ RECUR (TREE_OPERAND (rhs, 0)),
+ RECUR (TREE_OPERAND (rhs, 1))));
+ }
+ else
+ incr = RECUR (incr);
+ break;
+ default:
+ incr = RECUR (incr);
+ break;
+ }
+
+ TREE_VEC_ELT (declv, i) = decl;
+ TREE_VEC_ELT (initv, i) = init;
+ TREE_VEC_ELT (condv, i) = cond;
+ TREE_VEC_ELT (incrv, i) = incr;
+#undef RECUR
+}
+
+/* Like tsubst_copy for expressions, etc. but also does semantic
+ processing. */
+
+static tree
+tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
+ bool integral_constant_expression_p)
+{
+#define RETURN(EXP) do { r = (EXP); goto out; } while(0)
+#define RECUR(NODE) \
+ tsubst_expr ((NODE), args, complain, in_decl, \
+ integral_constant_expression_p)
+
+ tree stmt, tmp;
+ tree r;
+ location_t loc;
+
+ if (t == NULL_TREE || t == error_mark_node)
+ return t;
+
+ loc = input_location;
+ if (EXPR_HAS_LOCATION (t))
+ input_location = EXPR_LOCATION (t);
+ if (STATEMENT_CODE_P (TREE_CODE (t)))
+ current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
+
+ switch (TREE_CODE (t))
+ {
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
+ RECUR (tsi_stmt (i));
+ break;
+ }
+
+ case CTOR_INITIALIZER:
+ finish_mem_initializers (tsubst_initializer_list
+ (TREE_OPERAND (t, 0), args));
+ break;
+
+ case RETURN_EXPR:
+ finish_return_stmt (RECUR (TREE_OPERAND (t, 0)));
+ break;
+
+ case EXPR_STMT:
+ tmp = RECUR (EXPR_STMT_EXPR (t));
+ if (EXPR_STMT_STMT_EXPR_RESULT (t))
+ finish_stmt_expr_expr (tmp, cur_stmt_expr);
+ else
+ finish_expr_stmt (tmp);
+ break;
+
+ case USING_STMT:
+ do_using_directive (USING_STMT_NAMESPACE (t));
+ break;
+
+ case DECL_EXPR:
+ {
+ tree decl, pattern_decl;
+ tree init;
+
+ pattern_decl = decl = DECL_EXPR_DECL (t);
+ if (TREE_CODE (decl) == LABEL_DECL)
+ finish_label_decl (DECL_NAME (decl));
+ else if (TREE_CODE (decl) == USING_DECL)
+ {
+ tree scope = USING_DECL_SCOPE (decl);
+ tree name = DECL_NAME (decl);
+ tree decl;
+
+ scope = tsubst (scope, args, complain, in_decl);
+ decl = lookup_qualified_name (scope, name,
+ /*is_type_p=*/false,
+ /*complain=*/false);
+ if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
+ qualified_name_lookup_error (scope, name, decl, input_location);
+ else
+ do_local_using_decl (decl, scope, name);
+ }
+ else if (DECL_PACK_P (decl))
+ {
+ /* Don't build up decls for a variadic capture proxy, we'll
+ instantiate the elements directly as needed. */
+ break;
+ }
+ else
+ {
+ init = DECL_INITIAL (decl);
+ decl = tsubst (decl, args, complain, in_decl);
+ if (decl != error_mark_node)
+ {
+ /* By marking the declaration as instantiated, we avoid
+ trying to instantiate it. Since instantiate_decl can't
+ handle local variables, and since we've already done
+ all that needs to be done, that's the right thing to
+ do. */
+ if (VAR_P (decl))
+ DECL_TEMPLATE_INSTANTIATED (decl) = 1;
+ if (VAR_P (decl)
+ && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
+ /* Anonymous aggregates are a special case. */
+ finish_anon_union (decl);
+ else if (is_capture_proxy (DECL_EXPR_DECL (t)))
+ {
+ DECL_CONTEXT (decl) = current_function_decl;
+ if (DECL_NAME (decl) == this_identifier)
+ {
+ tree lam = DECL_CONTEXT (current_function_decl);
+ lam = CLASSTYPE_LAMBDA_EXPR (lam);
+ LAMBDA_EXPR_THIS_CAPTURE (lam) = decl;
+ }
+ insert_capture_proxy (decl);
+ }
+ else if (DECL_IMPLICIT_TYPEDEF_P (t))
+ /* We already did a pushtag. */;
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_OMP_DECLARE_REDUCTION_P (decl)
+ && DECL_FUNCTION_SCOPE_P (pattern_decl))
+ {
+ DECL_CONTEXT (decl) = NULL_TREE;
+ pushdecl (decl);
+ DECL_CONTEXT (decl) = current_function_decl;
+ cp_check_omp_declare_reduction (decl);
+ }
+ else
+ {
+ int const_init = false;
+ maybe_push_decl (decl);
+ if (VAR_P (decl)
+ && DECL_PRETTY_FUNCTION_P (decl))
+ {
+ /* For __PRETTY_FUNCTION__ we have to adjust the
+ initializer. */
+ const char *const name
+ = cxx_printable_name (current_function_decl, 2);
+ init = cp_fname_init (name, &TREE_TYPE (decl));
+ }
+ else
+ {
+ tree t = RECUR (init);
+
+ if (init && !t)
+ {
+ /* If we had an initializer but it
+ instantiated to nothing,
+ value-initialize the object. This will
+ only occur when the initializer was a
+ pack expansion where the parameter packs
+ used in that expansion were of length
+ zero. */
+ init = build_value_init (TREE_TYPE (decl),
+ complain);
+ if (TREE_CODE (init) == AGGR_INIT_EXPR)
+ init = get_target_expr_sfinae (init, complain);
+ }
+ else
+ init = t;
+ }
+
+ if (VAR_P (decl))
+ const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P
+ (pattern_decl));
+ cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
+ }
+ }
+ }
+
+ break;
+ }
+
+ case FOR_STMT:
+ stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
+ RECUR (FOR_INIT_STMT (t));
+ finish_for_init_stmt (stmt);
+ tmp = RECUR (FOR_COND (t));
+ finish_for_cond (tmp, stmt, false);
+ tmp = RECUR (FOR_EXPR (t));
+ finish_for_expr (tmp, stmt);
+ RECUR (FOR_BODY (t));
+ finish_for_stmt (stmt);
+ break;
+
+ case RANGE_FOR_STMT:
+ {
+ tree decl, expr;
+ stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
+ decl = RANGE_FOR_DECL (t);
+ decl = tsubst (decl, args, complain, in_decl);
+ maybe_push_decl (decl);
+ expr = RECUR (RANGE_FOR_EXPR (t));
+ stmt = cp_convert_range_for (stmt, decl, expr, RANGE_FOR_IVDEP (t));
+ RECUR (RANGE_FOR_BODY (t));
+ finish_for_stmt (stmt);
+ }
+ break;
+
+ case WHILE_STMT:
+ stmt = begin_while_stmt ();
+ tmp = RECUR (WHILE_COND (t));
+ finish_while_stmt_cond (tmp, stmt, false);
+ RECUR (WHILE_BODY (t));
+ finish_while_stmt (stmt);
+ break;
+
+ case DO_STMT:
+ stmt = begin_do_stmt ();
+ RECUR (DO_BODY (t));
+ finish_do_body (stmt);
+ tmp = RECUR (DO_COND (t));
+ finish_do_stmt (tmp, stmt, false);
+ break;
+
+ case IF_STMT:
+ stmt = begin_if_stmt ();
+ tmp = RECUR (IF_COND (t));
+ finish_if_stmt_cond (tmp, stmt);
+ RECUR (THEN_CLAUSE (t));
+ finish_then_clause (stmt);
+
+ if (ELSE_CLAUSE (t))
+ {
+ begin_else_clause (stmt);
+ RECUR (ELSE_CLAUSE (t));
+ finish_else_clause (stmt);
+ }
+
+ finish_if_stmt (stmt);
+ break;
+
+ case BIND_EXPR:
+ if (BIND_EXPR_BODY_BLOCK (t))
+ stmt = begin_function_body ();
+ else
+ stmt = begin_compound_stmt (BIND_EXPR_TRY_BLOCK (t)
+ ? BCS_TRY_BLOCK : 0);
+
+ RECUR (BIND_EXPR_BODY (t));
+
+ if (BIND_EXPR_BODY_BLOCK (t))
+ finish_function_body (stmt);
+ else
+ finish_compound_stmt (stmt);
+ break;
+
+ case BREAK_STMT:
+ finish_break_stmt ();
+ break;
+
+ case CONTINUE_STMT:
+ finish_continue_stmt ();
+ break;
+
+ case SWITCH_STMT:
+ stmt = begin_switch_stmt ();
+ tmp = RECUR (SWITCH_STMT_COND (t));
+ finish_switch_cond (tmp, stmt);
+ RECUR (SWITCH_STMT_BODY (t));
+ finish_switch_stmt (stmt);
+ break;
+
+ case CASE_LABEL_EXPR:
+ finish_case_label (EXPR_LOCATION (t),
+ RECUR (CASE_LOW (t)),
+ RECUR (CASE_HIGH (t)));
+ break;
+
+ case LABEL_EXPR:
+ {
+ tree decl = LABEL_EXPR_LABEL (t);
+ tree label;
+
+ label = finish_label_stmt (DECL_NAME (decl));
+ if (DECL_ATTRIBUTES (decl) != NULL_TREE)
+ cplus_decl_attributes (&label, DECL_ATTRIBUTES (decl), 0);
+ }
+ break;
+
+ case GOTO_EXPR:
+ tmp = GOTO_DESTINATION (t);
+ if (TREE_CODE (tmp) != LABEL_DECL)
+ /* Computed goto's must be tsubst'd into. On the other hand,
+ non-computed gotos must not be; the identifier in question
+ will have no binding. */
+ tmp = RECUR (tmp);
+ else
+ tmp = DECL_NAME (tmp);
+ finish_goto_stmt (tmp);
+ break;
+
+ case ASM_EXPR:
+ tmp = finish_asm_stmt
+ (ASM_VOLATILE_P (t),
+ RECUR (ASM_STRING (t)),
+ tsubst_copy_asm_operands (ASM_OUTPUTS (t), args, complain, in_decl),
+ tsubst_copy_asm_operands (ASM_INPUTS (t), args, complain, in_decl),
+ tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl),
+ tsubst_copy_asm_operands (ASM_LABELS (t), args, complain, in_decl));
+ {
+ tree asm_expr = tmp;
+ if (TREE_CODE (asm_expr) == CLEANUP_POINT_EXPR)
+ asm_expr = TREE_OPERAND (asm_expr, 0);
+ ASM_INPUT_P (asm_expr) = ASM_INPUT_P (t);
+ }
+ break;
+
+ case TRY_BLOCK:
+ if (CLEANUP_P (t))
+ {
+ stmt = begin_try_block ();
+ RECUR (TRY_STMTS (t));
+ finish_cleanup_try_block (stmt);
+ finish_cleanup (RECUR (TRY_HANDLERS (t)), stmt);
+ }
+ else
+ {
+ tree compound_stmt = NULL_TREE;
+
+ if (FN_TRY_BLOCK_P (t))
+ stmt = begin_function_try_block (&compound_stmt);
+ else
+ stmt = begin_try_block ();
+
+ RECUR (TRY_STMTS (t));
+
+ if (FN_TRY_BLOCK_P (t))
+ finish_function_try_block (stmt);
+ else
+ finish_try_block (stmt);
+
+ RECUR (TRY_HANDLERS (t));
+ if (FN_TRY_BLOCK_P (t))
+ finish_function_handler_sequence (stmt, compound_stmt);
+ else
+ finish_handler_sequence (stmt);
+ }
+ break;
+
+ case HANDLER:
+ {
+ tree decl = HANDLER_PARMS (t);
+
+ if (decl)
+ {
+ decl = tsubst (decl, args, complain, in_decl);
+ /* Prevent instantiate_decl from trying to instantiate
+ this variable. We've already done all that needs to be
+ done. */
+ if (decl != error_mark_node)
+ DECL_TEMPLATE_INSTANTIATED (decl) = 1;
+ }
+ stmt = begin_handler ();
+ finish_handler_parms (decl, stmt);
+ RECUR (HANDLER_BODY (t));
+ finish_handler (stmt);
+ }
+ break;
+
+ case TAG_DEFN:
+ tmp = tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
+ if (CLASS_TYPE_P (tmp))
+ {
+ /* Local classes are not independent templates; they are
+ instantiated along with their containing function. And this
+ way we don't have to deal with pushing out of one local class
+ to instantiate a member of another local class. */
+ tree fn;
+ /* Closures are handled by the LAMBDA_EXPR. */
+ gcc_assert (!LAMBDA_TYPE_P (TREE_TYPE (t)));
+ complete_type (tmp);
+ for (fn = TYPE_METHODS (tmp); fn; fn = DECL_CHAIN (fn))
+ if (!DECL_ARTIFICIAL (fn))
+ instantiate_decl (fn, /*defer_ok*/0, /*expl_inst_class*/false);
+ }
+ break;
+
+ case STATIC_ASSERT:
+ {
+ tree condition;
+
+ ++c_inhibit_evaluation_warnings;
+ condition =
+ tsubst_expr (STATIC_ASSERT_CONDITION (t),
+ args,
+ complain, in_decl,
+ /*integral_constant_expression_p=*/true);
+ --c_inhibit_evaluation_warnings;
+
+ finish_static_assert (condition,
+ STATIC_ASSERT_MESSAGE (t),
+ STATIC_ASSERT_SOURCE_LOCATION (t),
+ /*member_p=*/false);
+ }
+ break;
+
+ case OMP_PARALLEL:
+ tmp = tsubst_omp_clauses (OMP_PARALLEL_CLAUSES (t), false,
+ args, complain, in_decl);
+ stmt = begin_omp_parallel ();
+ RECUR (OMP_PARALLEL_BODY (t));
+ OMP_PARALLEL_COMBINED (finish_omp_parallel (tmp, stmt))
+ = OMP_PARALLEL_COMBINED (t);
+ break;
+
+ case OMP_TASK:
+ tmp = tsubst_omp_clauses (OMP_TASK_CLAUSES (t), false,
+ args, complain, in_decl);
+ stmt = begin_omp_task ();
+ RECUR (OMP_TASK_BODY (t));
+ finish_omp_task (tmp, stmt);
+ break;
+
+ case OMP_FOR:
+ case OMP_SIMD:
+ case CILK_SIMD:
+ case OMP_DISTRIBUTE:
+ {
+ tree clauses, body, pre_body;
+ tree declv = NULL_TREE, initv = NULL_TREE, condv = NULL_TREE;
+ tree incrv = NULL_TREE;
+ int i;
+
+ clauses = tsubst_omp_clauses (OMP_FOR_CLAUSES (t), false,
+ args, complain, in_decl);
+ if (OMP_FOR_INIT (t) != NULL_TREE)
+ {
+ declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
+ initv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
+ condv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
+ incrv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
+ }
+
+ stmt = begin_omp_structured_block ();
+
+ pre_body = push_stmt_list ();
+ RECUR (OMP_FOR_PRE_BODY (t));
+ pre_body = pop_stmt_list (pre_body);
+
+ if (OMP_FOR_INIT (t) != NULL_TREE)
+ for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (t)); i++)
+ tsubst_omp_for_iterator (t, i, declv, initv, condv, incrv,
+ &clauses, args, complain, in_decl,
+ integral_constant_expression_p);
+
+ body = push_stmt_list ();
+ RECUR (OMP_FOR_BODY (t));
+ body = pop_stmt_list (body);
+
+ if (OMP_FOR_INIT (t) != NULL_TREE)
+ t = finish_omp_for (EXPR_LOCATION (t), TREE_CODE (t), declv, initv,
+ condv, incrv, body, pre_body, clauses);
+ else
+ {
+ t = make_node (TREE_CODE (t));
+ TREE_TYPE (t) = void_type_node;
+ OMP_FOR_BODY (t) = body;
+ OMP_FOR_PRE_BODY (t) = pre_body;
+ OMP_FOR_CLAUSES (t) = clauses;
+ SET_EXPR_LOCATION (t, EXPR_LOCATION (t));
+ add_stmt (t);
+ }
+
+ add_stmt (finish_omp_structured_block (stmt));
+ }
+ break;
+
+ case OMP_SECTIONS:
+ case OMP_SINGLE:
+ case OMP_TEAMS:
+ case OMP_TARGET_DATA:
+ case OMP_TARGET:
+ tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false,
+ args, complain, in_decl);
+ stmt = push_stmt_list ();
+ RECUR (OMP_BODY (t));
+ stmt = pop_stmt_list (stmt);
+
+ t = copy_node (t);
+ OMP_BODY (t) = stmt;
+ OMP_CLAUSES (t) = tmp;
+ add_stmt (t);
+ break;
+
+ case OMP_TARGET_UPDATE:
+ tmp = tsubst_omp_clauses (OMP_TARGET_UPDATE_CLAUSES (t), false,
+ args, complain, in_decl);
+ t = copy_node (t);
+ OMP_CLAUSES (t) = tmp;
+ add_stmt (t);
+ break;
+
+ case OMP_SECTION:
+ case OMP_CRITICAL:
+ case OMP_MASTER:
+ case OMP_TASKGROUP:
+ case OMP_ORDERED:
+ stmt = push_stmt_list ();
+ RECUR (OMP_BODY (t));
+ stmt = pop_stmt_list (stmt);
+
+ t = copy_node (t);
+ OMP_BODY (t) = stmt;
+ add_stmt (t);
+ break;
+
+ case OMP_ATOMIC:
+ gcc_assert (OMP_ATOMIC_DEPENDENT_P (t));
+ if (TREE_CODE (TREE_OPERAND (t, 1)) != MODIFY_EXPR)
+ {
+ tree op1 = TREE_OPERAND (t, 1);
+ tree rhs1 = NULL_TREE;
+ tree lhs, rhs;
+ if (TREE_CODE (op1) == COMPOUND_EXPR)
+ {
+ rhs1 = RECUR (TREE_OPERAND (op1, 0));
+ op1 = TREE_OPERAND (op1, 1);
+ }
+ lhs = RECUR (TREE_OPERAND (op1, 0));
+ rhs = RECUR (TREE_OPERAND (op1, 1));
+ finish_omp_atomic (OMP_ATOMIC, TREE_CODE (op1), lhs, rhs,
+ NULL_TREE, NULL_TREE, rhs1,
+ OMP_ATOMIC_SEQ_CST (t));
+ }
+ else
+ {
+ tree op1 = TREE_OPERAND (t, 1);
+ tree v = NULL_TREE, lhs, rhs = NULL_TREE, lhs1 = NULL_TREE;
+ tree rhs1 = NULL_TREE;
+ enum tree_code code = TREE_CODE (TREE_OPERAND (op1, 1));
+ enum tree_code opcode = NOP_EXPR;
+ if (code == OMP_ATOMIC_READ)
+ {
+ v = RECUR (TREE_OPERAND (op1, 0));
+ lhs = RECUR (TREE_OPERAND (TREE_OPERAND (op1, 1), 0));
+ }
+ else if (code == OMP_ATOMIC_CAPTURE_OLD
+ || code == OMP_ATOMIC_CAPTURE_NEW)
+ {
+ tree op11 = TREE_OPERAND (TREE_OPERAND (op1, 1), 1);
+ v = RECUR (TREE_OPERAND (op1, 0));
+ lhs1 = RECUR (TREE_OPERAND (TREE_OPERAND (op1, 1), 0));
+ if (TREE_CODE (op11) == COMPOUND_EXPR)
+ {
+ rhs1 = RECUR (TREE_OPERAND (op11, 0));
+ op11 = TREE_OPERAND (op11, 1);
+ }
+ lhs = RECUR (TREE_OPERAND (op11, 0));
+ rhs = RECUR (TREE_OPERAND (op11, 1));
+ opcode = TREE_CODE (op11);
+ if (opcode == MODIFY_EXPR)
+ opcode = NOP_EXPR;
+ }
+ else
+ {
+ code = OMP_ATOMIC;
+ lhs = RECUR (TREE_OPERAND (op1, 0));
+ rhs = RECUR (TREE_OPERAND (op1, 1));
+ }
+ finish_omp_atomic (code, opcode, lhs, rhs, v, lhs1, rhs1,
+ OMP_ATOMIC_SEQ_CST (t));
+ }
+ break;
+
+ case TRANSACTION_EXPR:
+ {
+ int flags = 0;
+ flags |= (TRANSACTION_EXPR_OUTER (t) ? TM_STMT_ATTR_OUTER : 0);
+ flags |= (TRANSACTION_EXPR_RELAXED (t) ? TM_STMT_ATTR_RELAXED : 0);
+
+ if (TRANSACTION_EXPR_IS_STMT (t))
+ {
+ tree body = TRANSACTION_EXPR_BODY (t);
+ tree noex = NULL_TREE;
+ if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
+ {
+ noex = MUST_NOT_THROW_COND (body);
+ if (noex == NULL_TREE)
+ noex = boolean_true_node;
+ body = TREE_OPERAND (body, 0);
+ }
+ stmt = begin_transaction_stmt (input_location, NULL, flags);
+ RECUR (body);
+ finish_transaction_stmt (stmt, NULL, flags, RECUR (noex));
+ }
+ else
+ {
+ stmt = build_transaction_expr (EXPR_LOCATION (t),
+ RECUR (TRANSACTION_EXPR_BODY (t)),
+ flags, NULL_TREE);
+ RETURN (stmt);
+ }
+ }
+ break;
+
+ case MUST_NOT_THROW_EXPR:
+ RETURN (build_must_not_throw_expr (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (MUST_NOT_THROW_COND (t))));
+
+ case EXPR_PACK_EXPANSION:
+ error ("invalid use of pack expansion expression");
+ RETURN (error_mark_node);
+
+ case NONTYPE_ARGUMENT_PACK:
+ error ("use %<...%> to expand argument pack");
+ RETURN (error_mark_node);
+
+ case CILK_SPAWN_STMT:
+ cfun->calls_cilk_spawn = 1;
+ RETURN (build_cilk_spawn (EXPR_LOCATION (t), RECUR (CILK_SPAWN_FN (t))));
+
+ case CILK_SYNC_STMT:
+ RETURN (build_cilk_sync ());
+
+ case COMPOUND_EXPR:
+ tmp = RECUR (TREE_OPERAND (t, 0));
+ if (tmp == NULL_TREE)
+ /* If the first operand was a statement, we're done with it. */
+ RETURN (RECUR (TREE_OPERAND (t, 1)));
+ RETURN (build_x_compound_expr (EXPR_LOCATION (t), tmp,
+ RECUR (TREE_OPERAND (t, 1)),
+ complain));
+
+ case ANNOTATE_EXPR:
+ tmp = RECUR (TREE_OPERAND (t, 0));
+ RETURN (build2_loc (EXPR_LOCATION (t), ANNOTATE_EXPR,
+ TREE_TYPE (tmp), tmp, RECUR (TREE_OPERAND (t, 1))));
+
+ default:
+ gcc_assert (!STATEMENT_CODE_P (TREE_CODE (t)));
+
+ RETURN (tsubst_copy_and_build (t, args, complain, in_decl,
+ /*function_p=*/false,
+ integral_constant_expression_p));
+ }
+
+ RETURN (NULL_TREE);
+ out:
+ input_location = loc;
+ return r;
+#undef RECUR
+#undef RETURN
+}
+
+/* Instantiate the special body of the artificial DECL_OMP_DECLARE_REDUCTION
+ function. For description of the body see comment above
+ cp_parser_omp_declare_reduction_exprs. */
+
+static void
+tsubst_omp_udr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+{
+ if (t == NULL_TREE || t == error_mark_node)
+ return;
+
+ gcc_assert (TREE_CODE (t) == STATEMENT_LIST);
+
+ tree_stmt_iterator tsi;
+ int i;
+ tree stmts[7];
+ memset (stmts, 0, sizeof stmts);
+ for (i = 0, tsi = tsi_start (t);
+ i < 7 && !tsi_end_p (tsi);
+ i++, tsi_next (&tsi))
+ stmts[i] = tsi_stmt (tsi);
+ gcc_assert (tsi_end_p (tsi));
+
+ if (i >= 3)
+ {
+ gcc_assert (TREE_CODE (stmts[0]) == DECL_EXPR
+ && TREE_CODE (stmts[1]) == DECL_EXPR);
+ tree omp_out = tsubst (DECL_EXPR_DECL (stmts[0]),
+ args, complain, in_decl);
+ tree omp_in = tsubst (DECL_EXPR_DECL (stmts[1]),
+ args, complain, in_decl);
+ DECL_CONTEXT (omp_out) = current_function_decl;
+ DECL_CONTEXT (omp_in) = current_function_decl;
+ keep_next_level (true);
+ tree block = begin_omp_structured_block ();
+ tsubst_expr (stmts[2], args, complain, in_decl, false);
+ block = finish_omp_structured_block (block);
+ block = maybe_cleanup_point_expr_void (block);
+ add_decl_expr (omp_out);
+ if (TREE_NO_WARNING (DECL_EXPR_DECL (stmts[0])))
+ TREE_NO_WARNING (omp_out) = 1;
+ add_decl_expr (omp_in);
+ finish_expr_stmt (block);
+ }
+ if (i >= 6)
+ {
+ gcc_assert (TREE_CODE (stmts[3]) == DECL_EXPR
+ && TREE_CODE (stmts[4]) == DECL_EXPR);
+ tree omp_priv = tsubst (DECL_EXPR_DECL (stmts[3]),
+ args, complain, in_decl);
+ tree omp_orig = tsubst (DECL_EXPR_DECL (stmts[4]),
+ args, complain, in_decl);
+ DECL_CONTEXT (omp_priv) = current_function_decl;
+ DECL_CONTEXT (omp_orig) = current_function_decl;
+ keep_next_level (true);
+ tree block = begin_omp_structured_block ();
+ tsubst_expr (stmts[5], args, complain, in_decl, false);
+ block = finish_omp_structured_block (block);
+ block = maybe_cleanup_point_expr_void (block);
+ cp_walk_tree (&block, cp_remove_omp_priv_cleanup_stmt, omp_priv, NULL);
+ add_decl_expr (omp_priv);
+ add_decl_expr (omp_orig);
+ finish_expr_stmt (block);
+ if (i == 7)
+ add_decl_expr (omp_orig);
+ }
+}
+
+/* T is a postfix-expression that is not being used in a function
+ call. Return the substituted version of T. */
+
+static tree
+tsubst_non_call_postfix_expression (tree t, tree args,
+ tsubst_flags_t complain,
+ tree in_decl)
+{
+ if (TREE_CODE (t) == SCOPE_REF)
+ t = tsubst_qualified_id (t, args, complain, in_decl,
+ /*done=*/false, /*address_p=*/false);
+ else
+ t = tsubst_copy_and_build (t, args, complain, in_decl,
+ /*function_p=*/false,
+ /*integral_constant_expression_p=*/false);
+
+ return t;
+}
+
+/* Sentinel to disable certain warnings during template substitution. */
+
+struct warning_sentinel {
+ int &flag;
+ int val;
+ warning_sentinel(int& flag, bool suppress=true)
+ : flag(flag), val(flag) { if (suppress) flag = 0; }
+ ~warning_sentinel() { flag = val; }
+};
+
+/* Like tsubst but deals with expressions and performs semantic
+ analysis. FUNCTION_P is true if T is the "F" in "F (ARGS)". */
+
+tree
+tsubst_copy_and_build (tree t,
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl,
+ bool function_p,
+ bool integral_constant_expression_p)
+{
+#define RETURN(EXP) do { retval = (EXP); goto out; } while(0)
+#define RECUR(NODE) \
+ tsubst_copy_and_build (NODE, args, complain, in_decl, \
+ /*function_p=*/false, \
+ integral_constant_expression_p)
+
+ tree retval, op1;
+ location_t loc;
+
+ if (t == NULL_TREE || t == error_mark_node)
+ return t;
+
+ loc = input_location;
+ if (EXPR_HAS_LOCATION (t))
+ input_location = EXPR_LOCATION (t);
+
+ /* N3276 decltype magic only applies to calls at the top level or on the
+ right side of a comma. */
+ tsubst_flags_t decltype_flag = (complain & tf_decltype);
+ complain &= ~tf_decltype;
+
+ switch (TREE_CODE (t))
+ {
+ case USING_DECL:
+ t = DECL_NAME (t);
+ /* Fall through. */
+ case IDENTIFIER_NODE:
+ {
+ tree decl;
+ cp_id_kind idk;
+ bool non_integral_constant_expression_p;
+ const char *error_msg;
+
+ if (IDENTIFIER_TYPENAME_P (t))
+ {
+ tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ t = mangle_conv_op_name_for_type (new_type);
+ }
+
+ /* Look up the name. */
+ decl = lookup_name (t);
+
+ /* By convention, expressions use ERROR_MARK_NODE to indicate
+ failure, not NULL_TREE. */
+ if (decl == NULL_TREE)
+ decl = error_mark_node;
+
+ decl = finish_id_expression (t, decl, NULL_TREE,
+ &idk,
+ integral_constant_expression_p,
+ /*allow_non_integral_constant_expression_p=*/(cxx_dialect >= cxx11),
+ &non_integral_constant_expression_p,
+ /*template_p=*/false,
+ /*done=*/true,
+ /*address_p=*/false,
+ /*template_arg_p=*/false,
+ &error_msg,
+ input_location);
+ if (error_msg)
+ error (error_msg);
+ if (!function_p && identifier_p (decl))
+ {
+ if (complain & tf_error)
+ unqualified_name_lookup_error (decl);
+ decl = error_mark_node;
+ }
+ RETURN (decl);
+ }
+
+ case TEMPLATE_ID_EXPR:
+ {
+ tree object;
+ tree templ = RECUR (TREE_OPERAND (t, 0));
+ tree targs = TREE_OPERAND (t, 1);
+
+ if (targs)
+ targs = tsubst_template_args (targs, args, complain, in_decl);
+
+ if (TREE_CODE (templ) == COMPONENT_REF)
+ {
+ object = TREE_OPERAND (templ, 0);
+ templ = TREE_OPERAND (templ, 1);
+ }
+ else
+ object = NULL_TREE;
+ templ = lookup_template_function (templ, targs);
+
+ if (object)
+ RETURN (build3 (COMPONENT_REF, TREE_TYPE (templ),
+ object, templ, NULL_TREE));
+ else
+ RETURN (baselink_for_fns (templ));
+ }
+
+ case INDIRECT_REF:
+ {
+ tree r = RECUR (TREE_OPERAND (t, 0));
+
+ if (REFERENCE_REF_P (t))
+ {
+ /* A type conversion to reference type will be enclosed in
+ such an indirect ref, but the substitution of the cast
+ will have also added such an indirect ref. */
+ if (TREE_CODE (TREE_TYPE (r)) == REFERENCE_TYPE)
+ r = convert_from_reference (r);
+ }
+ else
+ r = build_x_indirect_ref (input_location, r, RO_UNARY_STAR,
+ complain|decltype_flag);
+ RETURN (r);
+ }
+
+ case NOP_EXPR:
+ RETURN (build_nop
+ (tsubst (TREE_TYPE (t), args, complain, in_decl),
+ RECUR (TREE_OPERAND (t, 0))));
+
+ case IMPLICIT_CONV_EXPR:
+ {
+ tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ tree expr = RECUR (TREE_OPERAND (t, 0));
+ int flags = LOOKUP_IMPLICIT;
+ if (IMPLICIT_CONV_EXPR_DIRECT_INIT (t))
+ flags = LOOKUP_NORMAL;
+ RETURN (perform_implicit_conversion_flags (type, expr, complain,
+ flags));
+ }
+
+ case CONVERT_EXPR:
+ RETURN (build1
+ (CONVERT_EXPR,
+ tsubst (TREE_TYPE (t), args, complain, in_decl),
+ RECUR (TREE_OPERAND (t, 0))));
+
+ case CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ {
+ tree type;
+ tree op, r = NULL_TREE;
+
+ type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ if (integral_constant_expression_p
+ && !cast_valid_in_integral_constant_expression_p (type))
+ {
+ if (complain & tf_error)
+ error ("a cast to a type other than an integral or "
+ "enumeration type cannot appear in a constant-expression");
+ RETURN (error_mark_node);
+ }
+
+ op = RECUR (TREE_OPERAND (t, 0));
+
+ warning_sentinel s(warn_useless_cast);
+ switch (TREE_CODE (t))
+ {
+ case CAST_EXPR:
+ r = build_functional_cast (type, op, complain);
+ break;
+ case REINTERPRET_CAST_EXPR:
+ r = build_reinterpret_cast (type, op, complain);
+ break;
+ case CONST_CAST_EXPR:
+ r = build_const_cast (type, op, complain);
+ break;
+ case DYNAMIC_CAST_EXPR:
+ r = build_dynamic_cast (type, op, complain);
+ break;
+ case STATIC_CAST_EXPR:
+ r = build_static_cast (type, op, complain);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ RETURN (r);
+ }
+
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
+ RETURN (build_x_unary_op (input_location, TREE_CODE (t), op1,
+ complain|decltype_flag));
+
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case NEGATE_EXPR:
+ case BIT_NOT_EXPR:
+ case ABS_EXPR:
+ case TRUTH_NOT_EXPR:
+ case UNARY_PLUS_EXPR: /* Unary + */
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ RETURN (build_x_unary_op (input_location, TREE_CODE (t),
+ RECUR (TREE_OPERAND (t, 0)),
+ complain|decltype_flag));
+
+ case FIX_TRUNC_EXPR:
+ RETURN (cp_build_unary_op (FIX_TRUNC_EXPR, RECUR (TREE_OPERAND (t, 0)),
+ 0, complain));
+
+ case ADDR_EXPR:
+ op1 = TREE_OPERAND (t, 0);
+ if (TREE_CODE (op1) == LABEL_DECL)
+ RETURN (finish_label_address_expr (DECL_NAME (op1),
+ EXPR_LOCATION (op1)));
+ if (TREE_CODE (op1) == SCOPE_REF)
+ op1 = tsubst_qualified_id (op1, args, complain, in_decl,
+ /*done=*/true, /*address_p=*/true);
+ else
+ op1 = tsubst_non_call_postfix_expression (op1, args, complain,
+ in_decl);
+ RETURN (build_x_unary_op (input_location, ADDR_EXPR, op1,
+ complain|decltype_flag));
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case TRUNC_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case RSHIFT_EXPR:
+ case LSHIFT_EXPR:
+ case RROTATE_EXPR:
+ case LROTATE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case MAX_EXPR:
+ case MIN_EXPR:
+ case LE_EXPR:
+ case GE_EXPR:
+ case LT_EXPR:
+ case GT_EXPR:
+ case MEMBER_REF:
+ case DOTSTAR_EXPR:
+ {
+ warning_sentinel s1(warn_type_limits);
+ warning_sentinel s2(warn_div_by_zero);
+ tree r = build_x_binary_op
+ (input_location, TREE_CODE (t),
+ RECUR (TREE_OPERAND (t, 0)),
+ (TREE_NO_WARNING (TREE_OPERAND (t, 0))
+ ? ERROR_MARK
+ : TREE_CODE (TREE_OPERAND (t, 0))),
+ RECUR (TREE_OPERAND (t, 1)),
+ (TREE_NO_WARNING (TREE_OPERAND (t, 1))
+ ? ERROR_MARK
+ : TREE_CODE (TREE_OPERAND (t, 1))),
+ /*overload=*/NULL,
+ complain|decltype_flag);
+ if (EXPR_P (r) && TREE_NO_WARNING (t))
+ TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
+
+ RETURN (r);
+ }
+
+ case POINTER_PLUS_EXPR:
+ return fold_build_pointer_plus (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)));
+
+ case SCOPE_REF:
+ RETURN (tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true,
+ /*address_p=*/false));
+ case ARRAY_REF:
+ op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
+ RETURN (build_x_array_ref (EXPR_LOCATION (t), op1,
+ RECUR (TREE_OPERAND (t, 1)),
+ complain|decltype_flag));
+
+ case ARRAY_NOTATION_REF:
+ {
+ tree start_index, length, stride;
+ op1 = tsubst_non_call_postfix_expression (ARRAY_NOTATION_ARRAY (t),
+ args, complain, in_decl);
+ start_index = RECUR (ARRAY_NOTATION_START (t));
+ length = RECUR (ARRAY_NOTATION_LENGTH (t));
+ stride = RECUR (ARRAY_NOTATION_STRIDE (t));
+ RETURN (build_array_notation_ref (EXPR_LOCATION (t), op1, start_index,
+ length, stride, TREE_TYPE (op1)));
+ }
+ case SIZEOF_EXPR:
+ if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
+ RETURN (tsubst_copy (t, args, complain, in_decl));
+ /* Fall through */
+
+ case ALIGNOF_EXPR:
+ {
+ tree r;
+
+ op1 = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
+ op1 = TREE_TYPE (op1);
+ if (!args)
+ {
+ /* When there are no ARGS, we are trying to evaluate a
+ non-dependent expression from the parser. Trying to do
+ the substitutions may not work. */
+ if (!TYPE_P (op1))
+ op1 = TREE_TYPE (op1);
+ }
+ else
+ {
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
+ if (TYPE_P (op1))
+ op1 = tsubst (op1, args, complain, in_decl);
+ else
+ op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
+ /*function_p=*/false,
+ /*integral_constant_expression_p=*/
+ false);
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+ }
+ if (TYPE_P (op1))
+ r = cxx_sizeof_or_alignof_type (op1, TREE_CODE (t),
+ complain & tf_error);
+ else
+ r = cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t),
+ complain & tf_error);
+ if (TREE_CODE (t) == SIZEOF_EXPR && r != error_mark_node)
+ {
+ if (TREE_CODE (r) != SIZEOF_EXPR || TYPE_P (op1))
+ {
+ if (!processing_template_decl && TYPE_P (op1))
+ {
+ r = build_min (SIZEOF_EXPR, size_type_node,
+ build1 (NOP_EXPR, op1, error_mark_node));
+ SIZEOF_EXPR_TYPE_P (r) = 1;
+ }
+ else
+ r = build_min (SIZEOF_EXPR, size_type_node, op1);
+ TREE_SIDE_EFFECTS (r) = 0;
+ TREE_READONLY (r) = 1;
+ }
+ SET_EXPR_LOCATION (r, EXPR_LOCATION (t));
+ }
+ RETURN (r);
+ }
+
+ case AT_ENCODE_EXPR:
+ {
+ op1 = TREE_OPERAND (t, 0);
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
+ op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
+ /*function_p=*/false,
+ /*integral_constant_expression_p=*/false);
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+ RETURN (objc_build_encode_expr (op1));
+ }
+
+ case NOEXCEPT_EXPR:
+ op1 = TREE_OPERAND (t, 0);
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
+ op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
+ /*function_p=*/false,
+ /*integral_constant_expression_p=*/false);
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+ RETURN (finish_noexcept_expr (op1, complain));
+
+ case MODOP_EXPR:
+ {
+ warning_sentinel s(warn_div_by_zero);
+ tree r = build_x_modify_expr
+ (EXPR_LOCATION (t),
+ RECUR (TREE_OPERAND (t, 0)),
+ TREE_CODE (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)),
+ complain|decltype_flag);
+ /* TREE_NO_WARNING must be set if either the expression was
+ parenthesized or it uses an operator such as >>= rather
+ than plain assignment. In the former case, it was already
+ set and must be copied. In the latter case,
+ build_x_modify_expr sets it and it must not be reset
+ here. */
+ if (TREE_NO_WARNING (t))
+ TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
+
+ RETURN (r);
+ }
+
+ case ARROW_EXPR:
+ op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
+ /* Remember that there was a reference to this entity. */
+ if (DECL_P (op1))
+ mark_used (op1);
+ RETURN (build_x_arrow (input_location, op1, complain));
+
+ case NEW_EXPR:
+ {
+ tree placement = RECUR (TREE_OPERAND (t, 0));
+ tree init = RECUR (TREE_OPERAND (t, 3));
+ vec<tree, va_gc> *placement_vec;
+ vec<tree, va_gc> *init_vec;
+ tree ret;
+
+ if (placement == NULL_TREE)
+ placement_vec = NULL;
+ else
+ {
+ placement_vec = make_tree_vector ();
+ for (; placement != NULL_TREE; placement = TREE_CHAIN (placement))
+ vec_safe_push (placement_vec, TREE_VALUE (placement));
+ }
+
+ /* If there was an initializer in the original tree, but it
+ instantiated to an empty list, then we should pass a
+ non-NULL empty vector to tell build_new that it was an
+ empty initializer() rather than no initializer. This can
+ only happen when the initializer is a pack expansion whose
+ parameter packs are of length zero. */
+ if (init == NULL_TREE && TREE_OPERAND (t, 3) == NULL_TREE)
+ init_vec = NULL;
+ else
+ {
+ init_vec = make_tree_vector ();
+ if (init == void_zero_node)
+ gcc_assert (init_vec != NULL);
+ else
+ {
+ for (; init != NULL_TREE; init = TREE_CHAIN (init))
+ vec_safe_push (init_vec, TREE_VALUE (init));
+ }
+ }
+
+ ret = build_new (&placement_vec,
+ tsubst (TREE_OPERAND (t, 1), args, complain, in_decl),
+ RECUR (TREE_OPERAND (t, 2)),
+ &init_vec,
+ NEW_EXPR_USE_GLOBAL (t),
+ complain);
+
+ if (placement_vec != NULL)
+ release_tree_vector (placement_vec);
+ if (init_vec != NULL)
+ release_tree_vector (init_vec);
+
+ RETURN (ret);
+ }
+
+ case DELETE_EXPR:
+ RETURN (delete_sanity
+ (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ DELETE_EXPR_USE_VEC (t),
+ DELETE_EXPR_USE_GLOBAL (t),
+ complain));
+
+ case COMPOUND_EXPR:
+ {
+ tree op0 = tsubst_copy_and_build (TREE_OPERAND (t, 0), args,
+ complain & ~tf_decltype, in_decl,
+ /*function_p=*/false,
+ integral_constant_expression_p);
+ RETURN (build_x_compound_expr (EXPR_LOCATION (t),
+ op0,
+ RECUR (TREE_OPERAND (t, 1)),
+ complain|decltype_flag));
+ }
+
+ case CALL_EXPR:
+ {
+ tree function;
+ vec<tree, va_gc> *call_args;
+ unsigned int nargs, i;
+ bool qualified_p;
+ bool koenig_p;
+ tree ret;
+
+ function = CALL_EXPR_FN (t);
+ /* When we parsed the expression, we determined whether or
+ not Koenig lookup should be performed. */
+ koenig_p = KOENIG_LOOKUP_P (t);
+ if (TREE_CODE (function) == SCOPE_REF)
+ {
+ qualified_p = true;
+ function = tsubst_qualified_id (function, args, complain, in_decl,
+ /*done=*/false,
+ /*address_p=*/false);
+ }
+ else if (koenig_p && identifier_p (function))
+ {
+ /* Do nothing; calling tsubst_copy_and_build on an identifier
+ would incorrectly perform unqualified lookup again.
+
+ Note that we can also have an IDENTIFIER_NODE if the earlier
+ unqualified lookup found a member function; in that case
+ koenig_p will be false and we do want to do the lookup
+ again to find the instantiated member function.
+
+ FIXME but doing that causes c++/15272, so we need to stop
+ using IDENTIFIER_NODE in that situation. */
+ qualified_p = false;
+ }
+ else
+ {
+ if (TREE_CODE (function) == COMPONENT_REF)
+ {
+ tree op = TREE_OPERAND (function, 1);
+
+ qualified_p = (TREE_CODE (op) == SCOPE_REF
+ || (BASELINK_P (op)
+ && BASELINK_QUALIFIED_P (op)));
+ }
+ else
+ qualified_p = false;
+
+ if (TREE_CODE (function) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
+ /* Avoid error about taking the address of a constructor. */
+ function = TREE_OPERAND (function, 0);
+
+ function = tsubst_copy_and_build (function, args, complain,
+ in_decl,
+ !qualified_p,
+ integral_constant_expression_p);
+
+ if (BASELINK_P (function))
+ qualified_p = true;
+ }
+
+ nargs = call_expr_nargs (t);
+ call_args = make_tree_vector ();
+ for (i = 0; i < nargs; ++i)
+ {
+ tree arg = CALL_EXPR_ARG (t, i);
+
+ if (!PACK_EXPANSION_P (arg))
+ vec_safe_push (call_args, RECUR (CALL_EXPR_ARG (t, i)));
+ else
+ {
+ /* Expand the pack expansion and push each entry onto
+ CALL_ARGS. */
+ arg = tsubst_pack_expansion (arg, args, complain, in_decl);
+ if (TREE_CODE (arg) == TREE_VEC)
+ {
+ unsigned int len, j;
+
+ len = TREE_VEC_LENGTH (arg);
+ for (j = 0; j < len; ++j)
+ {
+ tree value = TREE_VEC_ELT (arg, j);
+ if (value != NULL_TREE)
+ value = convert_from_reference (value);
+ vec_safe_push (call_args, value);
+ }
+ }
+ else
+ {
+ /* A partial substitution. Add one entry. */
+ vec_safe_push (call_args, arg);
+ }
+ }
+ }
+
+ /* We do not perform argument-dependent lookup if normal
+ lookup finds a non-function, in accordance with the
+ expected resolution of DR 218. */
+ if (koenig_p
+ && ((is_overloaded_fn (function)
+ /* If lookup found a member function, the Koenig lookup is
+ not appropriate, even if an unqualified-name was used
+ to denote the function. */
+ && !DECL_FUNCTION_MEMBER_P (get_first_fn (function)))
+ || identifier_p (function))
+ /* Only do this when substitution turns a dependent call
+ into a non-dependent call. */
+ && type_dependent_expression_p_push (t)
+ && !any_type_dependent_arguments_p (call_args))
+ function = perform_koenig_lookup (function, call_args, tf_none);
+
+ if (identifier_p (function)
+ && !any_type_dependent_arguments_p (call_args))
+ {
+ if (koenig_p && (complain & tf_warning_or_error))
+ {
+ /* For backwards compatibility and good diagnostics, try
+ the unqualified lookup again if we aren't in SFINAE
+ context. */
+ tree unq = (tsubst_copy_and_build
+ (function, args, complain, in_decl, true,
+ integral_constant_expression_p));
+ if (unq == error_mark_node)
+ RETURN (error_mark_node);
+
+ if (unq != function)
+ {
+ tree fn = unq;
+ if (INDIRECT_REF_P (fn))
+ fn = TREE_OPERAND (fn, 0);
+ if (TREE_CODE (fn) == COMPONENT_REF)
+ fn = TREE_OPERAND (fn, 1);
+ if (is_overloaded_fn (fn))
+ fn = get_first_fn (fn);
+ if (permerror (EXPR_LOC_OR_LOC (t, input_location),
+ "%qD was not declared in this scope, "
+ "and no declarations were found by "
+ "argument-dependent lookup at the point "
+ "of instantiation", function))
+ {
+ if (!DECL_P (fn))
+ /* Can't say anything more. */;
+ else if (DECL_CLASS_SCOPE_P (fn))
+ {
+ location_t loc = EXPR_LOC_OR_LOC (t,
+ input_location);
+ inform (loc,
+ "declarations in dependent base %qT are "
+ "not found by unqualified lookup",
+ DECL_CLASS_CONTEXT (fn));
+ if (current_class_ptr)
+ inform (loc,
+ "use %<this->%D%> instead", function);
+ else
+ inform (loc,
+ "use %<%T::%D%> instead",
+ current_class_name, function);
+ }
+ else
+ inform (0, "%q+D declared here, later in the "
+ "translation unit", fn);
+ }
+ function = unq;
+ }
+ }
+ if (identifier_p (function))
+ {
+ if (complain & tf_error)
+ unqualified_name_lookup_error (function);
+ release_tree_vector (call_args);
+ RETURN (error_mark_node);
+ }
+ }
+
+ /* Remember that there was a reference to this entity. */
+ if (DECL_P (function))
+ mark_used (function);
+
+ /* Put back tf_decltype for the actual call. */
+ complain |= decltype_flag;
+
+ if (TREE_CODE (function) == OFFSET_REF)
+ ret = build_offset_ref_call_from_tree (function, &call_args,
+ complain);
+ else if (TREE_CODE (function) == COMPONENT_REF)
+ {
+ tree instance = TREE_OPERAND (function, 0);
+ tree fn = TREE_OPERAND (function, 1);
+
+ if (processing_template_decl
+ && (type_dependent_expression_p (instance)
+ || (!BASELINK_P (fn)
+ && TREE_CODE (fn) != FIELD_DECL)
+ || type_dependent_expression_p (fn)
+ || any_type_dependent_arguments_p (call_args)))
+ ret = build_nt_call_vec (function, call_args);
+ else if (!BASELINK_P (fn))
+ ret = finish_call_expr (function, &call_args,
+ /*disallow_virtual=*/false,
+ /*koenig_p=*/false,
+ complain);
+ else
+ ret = (build_new_method_call
+ (instance, fn,
+ &call_args, NULL_TREE,
+ qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL,
+ /*fn_p=*/NULL,
+ complain));
+ }
+ else
+ ret = finish_call_expr (function, &call_args,
+ /*disallow_virtual=*/qualified_p,
+ koenig_p,
+ complain);
+
+ release_tree_vector (call_args);
+
+ RETURN (ret);
+ }
+
+ case COND_EXPR:
+ {
+ tree cond = RECUR (TREE_OPERAND (t, 0));
+ tree exp1, exp2;
+
+ if (TREE_CODE (cond) == INTEGER_CST)
+ {
+ if (integer_zerop (cond))
+ {
+ ++c_inhibit_evaluation_warnings;
+ exp1 = RECUR (TREE_OPERAND (t, 1));
+ --c_inhibit_evaluation_warnings;
+ exp2 = RECUR (TREE_OPERAND (t, 2));
+ }
+ else
+ {
+ exp1 = RECUR (TREE_OPERAND (t, 1));
+ ++c_inhibit_evaluation_warnings;
+ exp2 = RECUR (TREE_OPERAND (t, 2));
+ --c_inhibit_evaluation_warnings;
+ }
+ }
+ else
+ {
+ exp1 = RECUR (TREE_OPERAND (t, 1));
+ exp2 = RECUR (TREE_OPERAND (t, 2));
+ }
+
+ RETURN (build_x_conditional_expr (EXPR_LOCATION (t),
+ cond, exp1, exp2, complain));
+ }
+
+ case PSEUDO_DTOR_EXPR:
+ RETURN (finish_pseudo_destructor_expr
+ (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ tsubst (TREE_OPERAND (t, 2), args, complain, in_decl),
+ input_location));
+
+ case TREE_LIST:
+ {
+ tree purpose, value, chain;
+
+ if (t == void_list_node)
+ RETURN (t);
+
+ if ((TREE_PURPOSE (t) && PACK_EXPANSION_P (TREE_PURPOSE (t)))
+ || (TREE_VALUE (t) && PACK_EXPANSION_P (TREE_VALUE (t))))
+ {
+ /* We have pack expansions, so expand those and
+ create a new list out of it. */
+ tree purposevec = NULL_TREE;
+ tree valuevec = NULL_TREE;
+ tree chain;
+ int i, len = -1;
+
+ /* Expand the argument expressions. */
+ if (TREE_PURPOSE (t))
+ purposevec = tsubst_pack_expansion (TREE_PURPOSE (t), args,
+ complain, in_decl);
+ if (TREE_VALUE (t))
+ valuevec = tsubst_pack_expansion (TREE_VALUE (t), args,
+ complain, in_decl);
+
+ /* Build the rest of the list. */
+ chain = TREE_CHAIN (t);
+ if (chain && chain != void_type_node)
+ chain = RECUR (chain);
+
+ /* Determine the number of arguments. */
+ if (purposevec && TREE_CODE (purposevec) == TREE_VEC)
+ {
+ len = TREE_VEC_LENGTH (purposevec);
+ gcc_assert (!valuevec || len == TREE_VEC_LENGTH (valuevec));
+ }
+ else if (TREE_CODE (valuevec) == TREE_VEC)
+ len = TREE_VEC_LENGTH (valuevec);
+ else
+ {
+ /* Since we only performed a partial substitution into
+ the argument pack, we only RETURN (a single list
+ node. */
+ if (purposevec == TREE_PURPOSE (t)
+ && valuevec == TREE_VALUE (t)
+ && chain == TREE_CHAIN (t))
+ RETURN (t);
+
+ RETURN (tree_cons (purposevec, valuevec, chain));
+ }
+
+ /* Convert the argument vectors into a TREE_LIST */
+ i = len;
+ while (i > 0)
+ {
+ /* Grab the Ith values. */
+ i--;
+ purpose = purposevec ? TREE_VEC_ELT (purposevec, i)
+ : NULL_TREE;
+ value
+ = valuevec ? convert_from_reference (TREE_VEC_ELT (valuevec, i))
+ : NULL_TREE;
+
+ /* Build the list (backwards). */
+ chain = tree_cons (purpose, value, chain);
+ }
+
+ RETURN (chain);
+ }
+
+ purpose = TREE_PURPOSE (t);
+ if (purpose)
+ purpose = RECUR (purpose);
+ value = TREE_VALUE (t);
+ if (value)
+ value = RECUR (value);
+ chain = TREE_CHAIN (t);
+ if (chain && chain != void_type_node)
+ chain = RECUR (chain);
+ if (purpose == TREE_PURPOSE (t)
+ && value == TREE_VALUE (t)
+ && chain == TREE_CHAIN (t))
+ RETURN (t);
+ RETURN (tree_cons (purpose, value, chain));
+ }
+
+ case COMPONENT_REF:
+ {
+ tree object;
+ tree object_type;
+ tree member;
+ tree r;
+
+ object = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
+ /* Remember that there was a reference to this entity. */
+ if (DECL_P (object))
+ mark_used (object);
+ object_type = TREE_TYPE (object);
+
+ member = TREE_OPERAND (t, 1);
+ if (BASELINK_P (member))
+ member = tsubst_baselink (member,
+ non_reference (TREE_TYPE (object)),
+ args, complain, in_decl);
+ else
+ member = tsubst_copy (member, args, complain, in_decl);
+ if (member == error_mark_node)
+ RETURN (error_mark_node);
+
+ if (type_dependent_expression_p (object))
+ /* We can't do much here. */;
+ else if (!CLASS_TYPE_P (object_type))
+ {
+ if (scalarish_type_p (object_type))
+ {
+ tree s = NULL_TREE;
+ tree dtor = member;
+
+ if (TREE_CODE (dtor) == SCOPE_REF)
+ {
+ s = TREE_OPERAND (dtor, 0);
+ dtor = TREE_OPERAND (dtor, 1);
+ }
+ if (TREE_CODE (dtor) == BIT_NOT_EXPR)
+ {
+ dtor = TREE_OPERAND (dtor, 0);
+ if (TYPE_P (dtor))
+ RETURN (finish_pseudo_destructor_expr
+ (object, s, dtor, input_location));
+ }
+ }
+ }
+ else if (TREE_CODE (member) == SCOPE_REF
+ && TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR)
+ {
+ /* Lookup the template functions now that we know what the
+ scope is. */
+ tree scope = TREE_OPERAND (member, 0);
+ tree tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0);
+ tree args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
+ member = lookup_qualified_name (scope, tmpl,
+ /*is_type_p=*/false,
+ /*complain=*/false);
+ if (BASELINK_P (member))
+ {
+ BASELINK_FUNCTIONS (member)
+ = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
+ args);
+ member = (adjust_result_of_qualified_name_lookup
+ (member, BINFO_TYPE (BASELINK_BINFO (member)),
+ object_type));
+ }
+ else
+ {
+ qualified_name_lookup_error (scope, tmpl, member,
+ input_location);
+ RETURN (error_mark_node);
+ }
+ }
+ else if (TREE_CODE (member) == SCOPE_REF
+ && !CLASS_TYPE_P (TREE_OPERAND (member, 0))
+ && TREE_CODE (TREE_OPERAND (member, 0)) != NAMESPACE_DECL)
+ {
+ if (complain & tf_error)
+ {
+ if (TYPE_P (TREE_OPERAND (member, 0)))
+ error ("%qT is not a class or namespace",
+ TREE_OPERAND (member, 0));
+ else
+ error ("%qD is not a class or namespace",
+ TREE_OPERAND (member, 0));
+ }
+ RETURN (error_mark_node);
+ }
+ else if (TREE_CODE (member) == FIELD_DECL)
+ {
+ r = finish_non_static_data_member (member, object, NULL_TREE);
+ if (TREE_CODE (r) == COMPONENT_REF)
+ REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (t);
+ RETURN (r);
+ }
+
+ r = finish_class_member_access_expr (object, member,
+ /*template_p=*/false,
+ complain);
+ if (TREE_CODE (r) == COMPONENT_REF)
+ REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (t);
+ RETURN (r);
+ }
+
+ case THROW_EXPR:
+ RETURN (build_throw
+ (RECUR (TREE_OPERAND (t, 0))));
+
+ case CONSTRUCTOR:
+ {
+ vec<constructor_elt, va_gc> *n;
+ constructor_elt *ce;
+ unsigned HOST_WIDE_INT idx;
+ tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ bool process_index_p;
+ int newlen;
+ bool need_copy_p = false;
+ tree r;
+
+ if (type == error_mark_node)
+ RETURN (error_mark_node);
+
+ /* digest_init will do the wrong thing if we let it. */
+ if (type && TYPE_PTRMEMFUNC_P (type))
+ RETURN (t);
+
+ /* We do not want to process the index of aggregate
+ initializers as they are identifier nodes which will be
+ looked up by digest_init. */
+ process_index_p = !(type && MAYBE_CLASS_TYPE_P (type));
+
+ n = vec_safe_copy (CONSTRUCTOR_ELTS (t));
+ newlen = vec_safe_length (n);
+ FOR_EACH_VEC_SAFE_ELT (n, idx, ce)
+ {
+ if (ce->index && process_index_p
+ /* An identifier index is looked up in the type
+ being initialized, not the current scope. */
+ && TREE_CODE (ce->index) != IDENTIFIER_NODE)
+ ce->index = RECUR (ce->index);
+
+ if (PACK_EXPANSION_P (ce->value))
+ {
+ /* Substitute into the pack expansion. */
+ ce->value = tsubst_pack_expansion (ce->value, args, complain,
+ in_decl);
+
+ if (ce->value == error_mark_node
+ || PACK_EXPANSION_P (ce->value))
+ ;
+ else if (TREE_VEC_LENGTH (ce->value) == 1)
+ /* Just move the argument into place. */
+ ce->value = TREE_VEC_ELT (ce->value, 0);
+ else
+ {
+ /* Update the length of the final CONSTRUCTOR
+ arguments vector, and note that we will need to
+ copy.*/
+ newlen = newlen + TREE_VEC_LENGTH (ce->value) - 1;
+ need_copy_p = true;
+ }
+ }
+ else
+ ce->value = RECUR (ce->value);
+ }
+
+ if (need_copy_p)
+ {
+ vec<constructor_elt, va_gc> *old_n = n;
+
+ vec_alloc (n, newlen);
+ FOR_EACH_VEC_ELT (*old_n, idx, ce)
+ {
+ if (TREE_CODE (ce->value) == TREE_VEC)
+ {
+ int i, len = TREE_VEC_LENGTH (ce->value);
+ for (i = 0; i < len; ++i)
+ CONSTRUCTOR_APPEND_ELT (n, 0,
+ TREE_VEC_ELT (ce->value, i));
+ }
+ else
+ CONSTRUCTOR_APPEND_ELT (n, 0, ce->value);
+ }
+ }
+
+ r = build_constructor (init_list_type_node, n);
+ CONSTRUCTOR_IS_DIRECT_INIT (r) = CONSTRUCTOR_IS_DIRECT_INIT (t);
+
+ if (TREE_HAS_CONSTRUCTOR (t))
+ RETURN (finish_compound_literal (type, r, complain));
+
+ TREE_TYPE (r) = type;
+ RETURN (r);
+ }
+
+ case TYPEID_EXPR:
+ {
+ tree operand_0 = TREE_OPERAND (t, 0);
+ if (TYPE_P (operand_0))
+ {
+ operand_0 = tsubst (operand_0, args, complain, in_decl);
+ RETURN (get_typeid (operand_0, complain));
+ }
+ else
+ {
+ operand_0 = RECUR (operand_0);
+ RETURN (build_typeid (operand_0, complain));
+ }
+ }
+
+ case VAR_DECL:
+ if (!args)
+ RETURN (t);
+ else if (DECL_PACK_P (t))
+ {
+ /* We don't build decls for an instantiation of a
+ variadic capture proxy, we instantiate the elements
+ when needed. */
+ gcc_assert (DECL_HAS_VALUE_EXPR_P (t));
+ return RECUR (DECL_VALUE_EXPR (t));
+ }
+ /* Fall through */
+
+ case PARM_DECL:
+ {
+ tree r = tsubst_copy (t, args, complain, in_decl);
+
+ if (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE)
+ /* If the original type was a reference, we'll be wrapped in
+ the appropriate INDIRECT_REF. */
+ r = convert_from_reference (r);
+ RETURN (r);
+ }
+
+ case VA_ARG_EXPR:
+ RETURN (build_x_va_arg (EXPR_LOCATION (t),
+ RECUR (TREE_OPERAND (t, 0)),
+ tsubst (TREE_TYPE (t), args, complain, in_decl)));
+
+ case OFFSETOF_EXPR:
+ RETURN (finish_offsetof (RECUR (TREE_OPERAND (t, 0))));
+
+ case TRAIT_EXPR:
+ {
+ tree type1 = tsubst (TRAIT_EXPR_TYPE1 (t), args,
+ complain, in_decl);
+
+ tree type2 = TRAIT_EXPR_TYPE2 (t);
+ if (type2)
+ type2 = tsubst (type2, args, complain, in_decl);
+
+ RETURN (finish_trait_expr (TRAIT_EXPR_KIND (t), type1, type2));
+ }
+
+ case STMT_EXPR:
+ {
+ tree old_stmt_expr = cur_stmt_expr;
+ tree stmt_expr = begin_stmt_expr ();
+
+ cur_stmt_expr = stmt_expr;
+ tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl,
+ integral_constant_expression_p);
+ stmt_expr = finish_stmt_expr (stmt_expr, false);
+ cur_stmt_expr = old_stmt_expr;
+
+ /* If the resulting list of expression statement is empty,
+ fold it further into void_zero_node. */
+ if (empty_expr_stmt_p (stmt_expr))
+ stmt_expr = void_zero_node;
+
+ RETURN (stmt_expr);
+ }
+
+ case LAMBDA_EXPR:
+ {
+ tree r = build_lambda_expr ();
+
+ tree type = tsubst (LAMBDA_EXPR_CLOSURE (t), args, complain, NULL_TREE);
+ LAMBDA_EXPR_CLOSURE (r) = type;
+ CLASSTYPE_LAMBDA_EXPR (type) = r;
+
+ LAMBDA_EXPR_LOCATION (r)
+ = LAMBDA_EXPR_LOCATION (t);
+ LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (r)
+ = LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (t);
+ LAMBDA_EXPR_MUTABLE_P (r) = LAMBDA_EXPR_MUTABLE_P (t);
+ LAMBDA_EXPR_DISCRIMINATOR (r)
+ = (LAMBDA_EXPR_DISCRIMINATOR (t));
+ /* For a function scope, we want to use tsubst so that we don't
+ complain about referring to an auto function before its return
+ type has been deduced. Otherwise, we want to use tsubst_copy so
+ that we look up the existing field/parameter/variable rather
+ than build a new one. */
+ tree scope = LAMBDA_EXPR_EXTRA_SCOPE (t);
+ if (scope && TREE_CODE (scope) == FUNCTION_DECL)
+ scope = tsubst (scope, args, complain, in_decl);
+ else if (scope && TREE_CODE (scope) == PARM_DECL)
+ {
+ /* Look up the parameter we want directly, as tsubst_copy
+ doesn't do what we need. */
+ tree fn = tsubst (DECL_CONTEXT (scope), args, complain, in_decl);
+ tree parm = FUNCTION_FIRST_USER_PARM (fn);
+ while (DECL_PARM_INDEX (parm) != DECL_PARM_INDEX (scope))
+ parm = DECL_CHAIN (parm);
+ scope = parm;
+ /* FIXME Work around the parm not having DECL_CONTEXT set. */
+ if (DECL_CONTEXT (scope) == NULL_TREE)
+ DECL_CONTEXT (scope) = fn;
+ }
+ else
+ scope = RECUR (scope);
+ LAMBDA_EXPR_EXTRA_SCOPE (r) = scope;
+ LAMBDA_EXPR_RETURN_TYPE (r)
+ = tsubst (LAMBDA_EXPR_RETURN_TYPE (t), args, complain, in_decl);
+
+ gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (t) == NULL_TREE
+ && LAMBDA_EXPR_PENDING_PROXIES (t) == NULL);
+
+ /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */
+ determine_visibility (TYPE_NAME (type));
+ /* Now that we know visibility, instantiate the type so we have a
+ declaration of the op() for later calls to lambda_function. */
+ complete_type (type);
+
+ LAMBDA_EXPR_THIS_CAPTURE (r) = NULL_TREE;
+
+ RETURN (build_lambda_object (r));
+ }
+
+ case TARGET_EXPR:
+ /* We can get here for a constant initializer of non-dependent type.
+ FIXME stop folding in cp_parser_initializer_clause. */
+ {
+ tree r = get_target_expr_sfinae (RECUR (TARGET_EXPR_INITIAL (t)),
+ complain);
+ RETURN (r);
+ }
+
+ case TRANSACTION_EXPR:
+ RETURN (tsubst_expr(t, args, complain, in_decl,
+ integral_constant_expression_p));
+
+ case PAREN_EXPR:
+ RETURN (finish_parenthesized_expr (RECUR (TREE_OPERAND (t, 0))));
+
+ case VEC_PERM_EXPR:
+ RETURN (build_x_vec_perm_expr (input_location,
+ RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)),
+ complain));
+
+ default:
+ /* Handle Objective-C++ constructs, if appropriate. */
+ {
+ tree subst
+ = objcp_tsubst_copy_and_build (t, args, complain,
+ in_decl, /*function_p=*/false);
+ if (subst)
+ RETURN (subst);
+ }
+ RETURN (tsubst_copy (t, args, complain, in_decl));
+ }
+
+#undef RECUR
+#undef RETURN
+ out:
+ input_location = loc;
+ return retval;
+}
+
+/* Verify that the instantiated ARGS are valid. For type arguments,
+ make sure that the type's linkage is ok. For non-type arguments,
+ make sure they are constants if they are integral or enumerations.
+ Emit an error under control of COMPLAIN, and return TRUE on error. */
+
+static bool
+check_instantiated_arg (tree tmpl, tree t, tsubst_flags_t complain)
+{
+ if (dependent_template_arg_p (t))
+ return false;
+ if (ARGUMENT_PACK_P (t))
+ {
+ tree vec = ARGUMENT_PACK_ARGS (t);
+ int len = TREE_VEC_LENGTH (vec);
+ bool result = false;
+ int i;
+
+ for (i = 0; i < len; ++i)
+ if (check_instantiated_arg (tmpl, TREE_VEC_ELT (vec, i), complain))
+ result = true;
+ return result;
+ }
+ else if (TYPE_P (t))
+ {
+ /* [basic.link]: A name with no linkage (notably, the name
+ of a class or enumeration declared in a local scope)
+ shall not be used to declare an entity with linkage.
+ This implies that names with no linkage cannot be used as
+ template arguments
+
+ DR 757 relaxes this restriction for C++0x. */
+ tree nt = (cxx_dialect > cxx98 ? NULL_TREE
+ : no_linkage_check (t, /*relaxed_p=*/false));
+
+ if (nt)
+ {
+ /* DR 488 makes use of a type with no linkage cause
+ type deduction to fail. */
+ if (complain & tf_error)
+ {
+ if (TYPE_ANONYMOUS_P (nt))
+ error ("%qT is/uses anonymous type", t);
+ else
+ error ("template argument for %qD uses local type %qT",
+ tmpl, t);
+ }
+ return true;
+ }
+ /* In order to avoid all sorts of complications, we do not
+ allow variably-modified types as template arguments. */
+ else if (variably_modified_type_p (t, NULL_TREE))
+ {
+ if (complain & tf_error)
+ error ("%qT is a variably modified type", t);
+ return true;
+ }
+ }
+ /* Class template and alias template arguments should be OK. */
+ else if (DECL_TYPE_TEMPLATE_P (t))
+ ;
+ /* A non-type argument of integral or enumerated type must be a
+ constant. */
+ else if (TREE_TYPE (t)
+ && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t))
+ && !TREE_CONSTANT (t))
+ {
+ if (complain & tf_error)
+ error ("integral expression %qE is not constant", t);
+ return true;
+ }
+ return false;
+}
+
+static bool
+check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
+{
+ int ix, len = DECL_NTPARMS (tmpl);
+ bool result = false;
+
+ for (ix = 0; ix != len; ix++)
+ {
+ if (check_instantiated_arg (tmpl, TREE_VEC_ELT (args, ix), complain))
+ result = true;
+ }
+ if (result && (complain & tf_error))
+ error (" trying to instantiate %qD", tmpl);
+ return result;
+}
+
+/* We're out of SFINAE context now, so generate diagnostics for the access
+ errors we saw earlier when instantiating D from TMPL and ARGS. */
+
+static void
+recheck_decl_substitution (tree d, tree tmpl, tree args)
+{
+ tree pattern = DECL_TEMPLATE_RESULT (tmpl);
+ tree type = TREE_TYPE (pattern);
+ location_t loc = input_location;
+
+ push_access_scope (d);
+ push_deferring_access_checks (dk_no_deferred);
+ input_location = DECL_SOURCE_LOCATION (pattern);
+ tsubst (type, args, tf_warning_or_error, d);
+ input_location = loc;
+ pop_deferring_access_checks ();
+ pop_access_scope (d);
+}
+
+/* Instantiate the indicated variable, function, or alias template TMPL with
+ the template arguments in TARG_PTR. */
+
+static tree
+instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain)
+{
+ tree targ_ptr = orig_args;
+ tree fndecl;
+ tree gen_tmpl;
+ tree spec;
+ bool access_ok = true;
+
+ if (tmpl == error_mark_node)
+ return error_mark_node;
+
+ gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
+
+ /* If this function is a clone, handle it specially. */
+ if (DECL_CLONED_FUNCTION_P (tmpl))
+ {
+ tree spec;
+ tree clone;
+
+ /* Use DECL_ABSTRACT_ORIGIN because only FUNCTION_DECLs have
+ DECL_CLONED_FUNCTION. */
+ spec = instantiate_template (DECL_ABSTRACT_ORIGIN (tmpl),
+ targ_ptr, complain);
+ if (spec == error_mark_node)
+ return error_mark_node;
+
+ /* Look for the clone. */
+ FOR_EACH_CLONE (clone, spec)
+ if (DECL_NAME (clone) == DECL_NAME (tmpl))
+ return clone;
+ /* We should always have found the clone by now. */
+ gcc_unreachable ();
+ return NULL_TREE;
+ }
+
+ if (targ_ptr == error_mark_node)
+ return error_mark_node;
+
+ /* Check to see if we already have this specialization. */
+ gen_tmpl = most_general_template (tmpl);
+ if (tmpl != gen_tmpl)
+ /* The TMPL is a partial instantiation. To get a full set of
+ arguments we must add the arguments used to perform the
+ partial instantiation. */
+ targ_ptr = add_outermost_template_args (DECL_TI_ARGS (tmpl),
+ targ_ptr);
+
+ /* It would be nice to avoid hashing here and then again in tsubst_decl,
+ but it doesn't seem to be on the hot path. */
+ spec = retrieve_specialization (gen_tmpl, targ_ptr, 0);
+
+ gcc_assert (tmpl == gen_tmpl
+ || ((fndecl = retrieve_specialization (tmpl, orig_args, 0))
+ == spec)
+ || fndecl == NULL_TREE);
+
+ if (spec != NULL_TREE)
+ {
+ if (FNDECL_HAS_ACCESS_ERRORS (spec))
+ {
+ if (complain & tf_error)
+ recheck_decl_substitution (spec, gen_tmpl, targ_ptr);
+ return error_mark_node;
+ }
+ return spec;
+ }
+
+ if (check_instantiated_args (gen_tmpl, INNERMOST_TEMPLATE_ARGS (targ_ptr),
+ complain))
+ return error_mark_node;
+
+ /* We are building a FUNCTION_DECL, during which the access of its
+ parameters and return types have to be checked. However this
+ FUNCTION_DECL which is the desired context for access checking
+ is not built yet. We solve this chicken-and-egg problem by
+ deferring all checks until we have the FUNCTION_DECL. */
+ push_deferring_access_checks (dk_deferred);
+
+ /* Instantiation of the function happens in the context of the function
+ template, not the context of the overload resolution we're doing. */
+ push_to_top_level ();
+ /* If there are dependent arguments, e.g. because we're doing partial
+ ordering, make sure processing_template_decl stays set. */
+ if (uses_template_parms (targ_ptr))
+ ++processing_template_decl;
+ if (DECL_CLASS_SCOPE_P (gen_tmpl))
+ {
+ tree ctx = tsubst (DECL_CONTEXT (gen_tmpl), targ_ptr,
+ complain, gen_tmpl);
+ push_nested_class (ctx);
+ }
+ /* Substitute template parameters to obtain the specialization. */
+ fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl),
+ targ_ptr, complain, gen_tmpl);
+ if (DECL_CLASS_SCOPE_P (gen_tmpl))
+ pop_nested_class ();
+ pop_from_top_level ();
+
+ if (fndecl == error_mark_node)
+ {
+ pop_deferring_access_checks ();
+ return error_mark_node;
+ }
+
+ /* The DECL_TI_TEMPLATE should always be the immediate parent
+ template, not the most general template. */
+ DECL_TI_TEMPLATE (fndecl) = tmpl;
+
+ /* Now we know the specialization, compute access previously
+ deferred. */
+ push_access_scope (fndecl);
+ if (!perform_deferred_access_checks (complain))
+ access_ok = false;
+ pop_access_scope (fndecl);
+ pop_deferring_access_checks ();
+
+ /* If we've just instantiated the main entry point for a function,
+ instantiate all the alternate entry points as well. We do this
+ by cloning the instantiation of the main entry point, not by
+ instantiating the template clones. */
+ if (DECL_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (DECL_CHAIN (gen_tmpl)))
+ clone_function_decl (fndecl, /*update_method_vec_p=*/0);
+
+ if (!access_ok)
+ {
+ if (!(complain & tf_error))
+ {
+ /* Remember to reinstantiate when we're out of SFINAE so the user
+ can see the errors. */
+ FNDECL_HAS_ACCESS_ERRORS (fndecl) = true;
+ }
+ return error_mark_node;
+ }
+ return fndecl;
+}
+
+/* Wrapper for instantiate_template_1. */
+
+tree
+instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain)
+{
+ tree ret;
+ timevar_push (TV_TEMPLATE_INST);
+ ret = instantiate_template_1 (tmpl, orig_args, complain);
+ timevar_pop (TV_TEMPLATE_INST);
+ return ret;
+}
+
+/* Instantiate the alias template TMPL with ARGS. Also push a template
+ instantiation level, which instantiate_template doesn't do because
+ functions and variables have sufficient context established by the
+ callers. */
+
+static tree
+instantiate_alias_template (tree tmpl, tree args, tsubst_flags_t complain)
+{
+ struct pending_template *old_last_pend = last_pending_template;
+ struct tinst_level *old_error_tinst = last_error_tinst_level;
+ if (tmpl == error_mark_node || args == error_mark_node)
+ return error_mark_node;
+ tree tinst = build_tree_list (tmpl, args);
+ if (!push_tinst_level (tinst))
+ {
+ ggc_free (tinst);
+ return error_mark_node;
+ }
+
+ args =
+ coerce_innermost_template_parms (DECL_TEMPLATE_PARMS (tmpl),
+ args, tmpl, complain,
+ /*require_all_args=*/true,
+ /*use_default_args=*/true);
+
+ tree r = instantiate_template (tmpl, args, complain);
+ pop_tinst_level ();
+ /* We can't free this if a pending_template entry or last_error_tinst_level
+ is pointing at it. */
+ if (last_pending_template == old_last_pend
+ && last_error_tinst_level == old_error_tinst)
+ ggc_free (tinst);
+
+ return r;
+}
+
+/* PARM is a template parameter pack for FN. Returns true iff
+ PARM is used in a deducible way in the argument list of FN. */
+
+static bool
+pack_deducible_p (tree parm, tree fn)
+{
+ tree t = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ for (; t; t = TREE_CHAIN (t))
+ {
+ tree type = TREE_VALUE (t);
+ tree packs;
+ if (!PACK_EXPANSION_P (type))
+ continue;
+ for (packs = PACK_EXPANSION_PARAMETER_PACKS (type);
+ packs; packs = TREE_CHAIN (packs))
+ if (TREE_VALUE (packs) == parm)
+ {
+ /* The template parameter pack is used in a function parameter
+ pack. If this is the end of the parameter list, the
+ template parameter pack is deducible. */
+ if (TREE_CHAIN (t) == void_list_node)
+ return true;
+ else
+ /* Otherwise, not. Well, it could be deduced from
+ a non-pack parameter, but doing so would end up with
+ a deduction mismatch, so don't bother. */
+ return false;
+ }
+ }
+ /* The template parameter pack isn't used in any function parameter
+ packs, but it might be used deeper, e.g. tuple<Args...>. */
+ return true;
+}
+
+/* The FN is a TEMPLATE_DECL for a function. ARGS is an array with
+ NARGS elements of the arguments that are being used when calling
+ it. TARGS is a vector into which the deduced template arguments
+ are placed.
+
+ Returns either a FUNCTION_DECL for the matching specialization of FN or
+ NULL_TREE if no suitable specialization can be found. If EXPLAIN_P is
+ true, diagnostics will be printed to explain why it failed.
+
+ If FN is a conversion operator, or we are trying to produce a specific
+ specialization, RETURN_TYPE is the return type desired.
+
+ The EXPLICIT_TARGS are explicit template arguments provided via a
+ template-id.
+
+ The parameter STRICT is one of:
+
+ DEDUCE_CALL:
+ We are deducing arguments for a function call, as in
+ [temp.deduct.call].
+
+ DEDUCE_CONV:
+ We are deducing arguments for a conversion function, as in
+ [temp.deduct.conv].
+
+ DEDUCE_EXACT:
+ We are deducing arguments when doing an explicit instantiation
+ as in [temp.explicit], when determining an explicit specialization
+ as in [temp.expl.spec], or when taking the address of a function
+ template, as in [temp.deduct.funcaddr]. */
+
+tree
+fn_type_unification (tree fn,
+ tree explicit_targs,
+ tree targs,
+ const tree *args,
+ unsigned int nargs,
+ tree return_type,
+ unification_kind_t strict,
+ int flags,
+ bool explain_p,
+ bool decltype_p)
+{
+ tree parms;
+ tree fntype;
+ tree decl = NULL_TREE;
+ tsubst_flags_t complain = (explain_p ? tf_warning_or_error : tf_none);
+ bool ok;
+ static int deduction_depth;
+ struct pending_template *old_last_pend = last_pending_template;
+ struct tinst_level *old_error_tinst = last_error_tinst_level;
+ tree tparms = DECL_INNERMOST_TEMPLATE_PARMS (fn);
+ tree tinst;
+ tree r = error_mark_node;
+
+ if (decltype_p)
+ complain |= tf_decltype;
+
+ /* In C++0x, it's possible to have a function template whose type depends
+ on itself recursively. This is most obvious with decltype, but can also
+ occur with enumeration scope (c++/48969). So we need to catch infinite
+ recursion and reject the substitution at deduction time; this function
+ will return error_mark_node for any repeated substitution.
+
+ This also catches excessive recursion such as when f<N> depends on
+ f<N-1> across all integers, and returns error_mark_node for all the
+ substitutions back up to the initial one.
+
+ This is, of course, not reentrant. */
+ if (excessive_deduction_depth)
+ return error_mark_node;
+ tinst = build_tree_list (fn, NULL_TREE);
+ ++deduction_depth;
+
+ gcc_assert (TREE_CODE (fn) == TEMPLATE_DECL);
+
+ fntype = TREE_TYPE (fn);
+ if (explicit_targs)
+ {
+ /* [temp.deduct]
+
+ The specified template arguments must match the template
+ parameters in kind (i.e., type, nontype, template), and there
+ must not be more arguments than there are parameters;
+ otherwise type deduction fails.
+
+ Nontype arguments must match the types of the corresponding
+ nontype template parameters, or must be convertible to the
+ types of the corresponding nontype parameters as specified in
+ _temp.arg.nontype_, otherwise type deduction fails.
+
+ All references in the function type of the function template
+ to the corresponding template parameters are replaced by the
+ specified template argument values. If a substitution in a
+ template parameter or in the function type of the function
+ template results in an invalid type, type deduction fails. */
+ int i, len = TREE_VEC_LENGTH (tparms);
+ location_t loc = input_location;
+ bool incomplete = false;
+
+ /* Adjust any explicit template arguments before entering the
+ substitution context. */
+ explicit_targs
+ = (coerce_template_parms (tparms, explicit_targs, NULL_TREE,
+ complain,
+ /*require_all_args=*/false,
+ /*use_default_args=*/false));
+ if (explicit_targs == error_mark_node)
+ goto fail;
+
+ /* Substitute the explicit args into the function type. This is
+ necessary so that, for instance, explicitly declared function
+ arguments can match null pointed constants. If we were given
+ an incomplete set of explicit args, we must not do semantic
+ processing during substitution as we could create partial
+ instantiations. */
+ for (i = 0; i < len; i++)
+ {
+ tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
+ bool parameter_pack = false;
+ tree targ = TREE_VEC_ELT (explicit_targs, i);
+
+ /* Dig out the actual parm. */
+ if (TREE_CODE (parm) == TYPE_DECL
+ || TREE_CODE (parm) == TEMPLATE_DECL)
+ {
+ parm = TREE_TYPE (parm);
+ parameter_pack = TEMPLATE_TYPE_PARAMETER_PACK (parm);
+ }
+ else if (TREE_CODE (parm) == PARM_DECL)
+ {
+ parm = DECL_INITIAL (parm);
+ parameter_pack = TEMPLATE_PARM_PARAMETER_PACK (parm);
+ }
+
+ if (!parameter_pack && targ == NULL_TREE)
+ /* No explicit argument for this template parameter. */
+ incomplete = true;
+
+ if (parameter_pack && pack_deducible_p (parm, fn))
+ {
+ /* Mark the argument pack as "incomplete". We could
+ still deduce more arguments during unification.
+ We remove this mark in type_unification_real. */
+ if (targ)
+ {
+ ARGUMENT_PACK_INCOMPLETE_P(targ) = 1;
+ ARGUMENT_PACK_EXPLICIT_ARGS (targ)
+ = ARGUMENT_PACK_ARGS (targ);
+ }
+
+ /* We have some incomplete argument packs. */
+ incomplete = true;
+ }
+ }
+
+ TREE_VALUE (tinst) = explicit_targs;
+ if (!push_tinst_level (tinst))
+ {
+ excessive_deduction_depth = true;
+ goto fail;
+ }
+ processing_template_decl += incomplete;
+ input_location = DECL_SOURCE_LOCATION (fn);
+ /* Ignore any access checks; we'll see them again in
+ instantiate_template and they might have the wrong
+ access path at this point. */
+ push_deferring_access_checks (dk_deferred);
+ fntype = tsubst (TREE_TYPE (fn), explicit_targs,
+ complain | tf_partial, NULL_TREE);
+ pop_deferring_access_checks ();
+ input_location = loc;
+ processing_template_decl -= incomplete;
+ pop_tinst_level ();
+
+ if (fntype == error_mark_node)
+ goto fail;
+
+ /* Place the explicitly specified arguments in TARGS. */
+ for (i = NUM_TMPL_ARGS (explicit_targs); i--;)
+ TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i);
+ }
+
+ /* Never do unification on the 'this' parameter. */
+ parms = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (fntype));
+
+ if (return_type)
+ {
+ tree *new_args;
+
+ parms = tree_cons (NULL_TREE, TREE_TYPE (fntype), parms);
+ new_args = XALLOCAVEC (tree, nargs + 1);
+ new_args[0] = return_type;
+ memcpy (new_args + 1, args, nargs * sizeof (tree));
+ args = new_args;
+ ++nargs;
+ }
+
+ /* We allow incomplete unification without an error message here
+ because the standard doesn't seem to explicitly prohibit it. Our
+ callers must be ready to deal with unification failures in any
+ event. */
+
+ TREE_VALUE (tinst) = targs;
+ /* If we aren't explaining yet, push tinst context so we can see where
+ any errors (e.g. from class instantiations triggered by instantiation
+ of default template arguments) come from. If we are explaining, this
+ context is redundant. */
+ if (!explain_p && !push_tinst_level (tinst))
+ {
+ excessive_deduction_depth = true;
+ goto fail;
+ }
+
+ /* type_unification_real will pass back any access checks from default
+ template argument substitution. */
+ vec<deferred_access_check, va_gc> *checks;
+ checks = NULL;
+
+ ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
+ targs, parms, args, nargs, /*subr=*/0,
+ strict, flags, &checks, explain_p);
+ if (!explain_p)
+ pop_tinst_level ();
+ if (!ok)
+ goto fail;
+
+ /* Now that we have bindings for all of the template arguments,
+ ensure that the arguments deduced for the template template
+ parameters have compatible template parameter lists. We cannot
+ check this property before we have deduced all template
+ arguments, because the template parameter types of a template
+ template parameter might depend on prior template parameters
+ deduced after the template template parameter. The following
+ ill-formed example illustrates this issue:
+
+ template<typename T, template<T> class C> void f(C<5>, T);
+
+ template<int N> struct X {};
+
+ void g() {
+ f(X<5>(), 5l); // error: template argument deduction fails
+ }
+
+ The template parameter list of 'C' depends on the template type
+ parameter 'T', but 'C' is deduced to 'X' before 'T' is deduced to
+ 'long'. Thus, we can't check that 'C' cannot bind to 'X' at the
+ time that we deduce 'C'. */
+ if (!template_template_parm_bindings_ok_p
+ (DECL_INNERMOST_TEMPLATE_PARMS (fn), targs))
+ {
+ unify_inconsistent_template_template_parameters (explain_p);
+ goto fail;
+ }
+
+ /* All is well so far. Now, check:
+
+ [temp.deduct]
+
+ When all template arguments have been deduced, all uses of
+ template parameters in nondeduced contexts are replaced with
+ the corresponding deduced argument values. If the
+ substitution results in an invalid type, as described above,
+ type deduction fails. */
+ TREE_VALUE (tinst) = targs;
+ if (!push_tinst_level (tinst))
+ {
+ excessive_deduction_depth = true;
+ goto fail;
+ }
+
+ /* Also collect access checks from the instantiation. */
+ reopen_deferring_access_checks (checks);
+
+ decl = instantiate_template (fn, targs, complain);
+
+ checks = get_deferred_access_checks ();
+ pop_deferring_access_checks ();
+
+ pop_tinst_level ();
+
+ if (decl == error_mark_node)
+ goto fail;
+
+ /* Now perform any access checks encountered during substitution. */
+ push_access_scope (decl);
+ ok = perform_access_checks (checks, complain);
+ pop_access_scope (decl);
+ if (!ok)
+ goto fail;
+
+ /* If we're looking for an exact match, check that what we got
+ is indeed an exact match. It might not be if some template
+ parameters are used in non-deduced contexts. But don't check
+ for an exact match if we have dependent template arguments;
+ in that case we're doing partial ordering, and we already know
+ that we have two candidates that will provide the actual type. */
+ if (strict == DEDUCE_EXACT && !any_dependent_template_arguments_p (targs))
+ {
+ tree substed = TREE_TYPE (decl);
+ unsigned int i;
+
+ tree sarg
+ = skip_artificial_parms_for (decl, TYPE_ARG_TYPES (substed));
+ if (return_type)
+ sarg = tree_cons (NULL_TREE, TREE_TYPE (substed), sarg);
+ for (i = 0; i < nargs && sarg; ++i, sarg = TREE_CHAIN (sarg))
+ if (!same_type_p (args[i], TREE_VALUE (sarg)))
+ {
+ unify_type_mismatch (explain_p, args[i],
+ TREE_VALUE (sarg));
+ goto fail;
+ }
+ }
+
+ r = decl;
+
+ fail:
+ --deduction_depth;
+ if (excessive_deduction_depth)
+ {
+ if (deduction_depth == 0)
+ /* Reset once we're all the way out. */
+ excessive_deduction_depth = false;
+ }
+
+ /* We can't free this if a pending_template entry or last_error_tinst_level
+ is pointing at it. */
+ if (last_pending_template == old_last_pend
+ && last_error_tinst_level == old_error_tinst)
+ ggc_free (tinst);
+
+ return r;
+}
+
+/* Adjust types before performing type deduction, as described in
+ [temp.deduct.call] and [temp.deduct.conv]. The rules in these two
+ sections are symmetric. PARM is the type of a function parameter
+ or the return type of the conversion function. ARG is the type of
+ the argument passed to the call, or the type of the value
+ initialized with the result of the conversion function.
+ ARG_EXPR is the original argument expression, which may be null. */
+
+static int
+maybe_adjust_types_for_deduction (unification_kind_t strict,
+ tree* parm,
+ tree* arg,
+ tree arg_expr)
+{
+ int result = 0;
+
+ switch (strict)
+ {
+ case DEDUCE_CALL:
+ break;
+
+ case DEDUCE_CONV:
+ {
+ /* Swap PARM and ARG throughout the remainder of this
+ function; the handling is precisely symmetric since PARM
+ will initialize ARG rather than vice versa. */
+ tree* temp = parm;
+ parm = arg;
+ arg = temp;
+ break;
+ }
+
+ case DEDUCE_EXACT:
+ /* Core issue #873: Do the DR606 thing (see below) for these cases,
+ too, but here handle it by stripping the reference from PARM
+ rather than by adding it to ARG. */
+ if (TREE_CODE (*parm) == REFERENCE_TYPE
+ && TYPE_REF_IS_RVALUE (*parm)
+ && TREE_CODE (TREE_TYPE (*parm)) == TEMPLATE_TYPE_PARM
+ && cp_type_quals (TREE_TYPE (*parm)) == TYPE_UNQUALIFIED
+ && TREE_CODE (*arg) == REFERENCE_TYPE
+ && !TYPE_REF_IS_RVALUE (*arg))
+ *parm = TREE_TYPE (*parm);
+ /* Nothing else to do in this case. */
+ return 0;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (TREE_CODE (*parm) != REFERENCE_TYPE)
+ {
+ /* [temp.deduct.call]
+
+ If P is not a reference type:
+
+ --If A is an array type, the pointer type produced by the
+ array-to-pointer standard conversion (_conv.array_) is
+ used in place of A for type deduction; otherwise,
+
+ --If A is a function type, the pointer type produced by
+ the function-to-pointer standard conversion
+ (_conv.func_) is used in place of A for type deduction;
+ otherwise,
+
+ --If A is a cv-qualified type, the top level
+ cv-qualifiers of A's type are ignored for type
+ deduction. */
+ if (TREE_CODE (*arg) == ARRAY_TYPE)
+ *arg = build_pointer_type (TREE_TYPE (*arg));
+ else if (TREE_CODE (*arg) == FUNCTION_TYPE)
+ *arg = build_pointer_type (*arg);
+ else
+ *arg = TYPE_MAIN_VARIANT (*arg);
+ }
+
+ /* From C++0x [14.8.2.1/3 temp.deduct.call] (after DR606), "If P is
+ of the form T&&, where T is a template parameter, and the argument
+ is an lvalue, T is deduced as A& */
+ if (TREE_CODE (*parm) == REFERENCE_TYPE
+ && TYPE_REF_IS_RVALUE (*parm)
+ && TREE_CODE (TREE_TYPE (*parm)) == TEMPLATE_TYPE_PARM
+ && cp_type_quals (TREE_TYPE (*parm)) == TYPE_UNQUALIFIED
+ && (arg_expr ? real_lvalue_p (arg_expr)
+ /* try_one_overload doesn't provide an arg_expr, but
+ functions are always lvalues. */
+ : TREE_CODE (*arg) == FUNCTION_TYPE))
+ *arg = build_reference_type (*arg);
+
+ /* [temp.deduct.call]
+
+ If P is a cv-qualified type, the top level cv-qualifiers
+ of P's type are ignored for type deduction. If P is a
+ reference type, the type referred to by P is used for
+ type deduction. */
+ *parm = TYPE_MAIN_VARIANT (*parm);
+ if (TREE_CODE (*parm) == REFERENCE_TYPE)
+ {
+ *parm = TREE_TYPE (*parm);
+ result |= UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
+ }
+
+ /* DR 322. For conversion deduction, remove a reference type on parm
+ too (which has been swapped into ARG). */
+ if (strict == DEDUCE_CONV && TREE_CODE (*arg) == REFERENCE_TYPE)
+ *arg = TREE_TYPE (*arg);
+
+ return result;
+}
+
+/* Subroutine of unify_one_argument. PARM is a function parameter of a
+ template which does contain any deducible template parameters; check if
+ ARG is a suitable match for it. STRICT, FLAGS and EXPLAIN_P are as in
+ unify_one_argument. */
+
+static int
+check_non_deducible_conversion (tree parm, tree arg, int strict,
+ int flags, bool explain_p)
+{
+ tree type;
+
+ if (!TYPE_P (arg))
+ type = TREE_TYPE (arg);
+ else
+ type = arg;
+
+ if (same_type_p (parm, type))
+ return unify_success (explain_p);
+
+ if (strict == DEDUCE_CONV)
+ {
+ if (can_convert_arg (type, parm, NULL_TREE, flags,
+ explain_p ? tf_warning_or_error : tf_none))
+ return unify_success (explain_p);
+ }
+ else if (strict != DEDUCE_EXACT)
+ {
+ if (can_convert_arg (parm, type,
+ TYPE_P (arg) ? NULL_TREE : arg,
+ flags, explain_p ? tf_warning_or_error : tf_none))
+ return unify_success (explain_p);
+ }
+
+ if (strict == DEDUCE_EXACT)
+ return unify_type_mismatch (explain_p, parm, arg);
+ else
+ return unify_arg_conversion (explain_p, parm, type, arg);
+}
+
+static bool uses_deducible_template_parms (tree type);
+
+/* Returns true iff the expression EXPR is one from which a template
+ argument can be deduced. In other words, if it's an undecorated
+ use of a template non-type parameter. */
+
+static bool
+deducible_expression (tree expr)
+{
+ return (TREE_CODE (expr) == TEMPLATE_PARM_INDEX);
+}
+
+/* Returns true iff the array domain DOMAIN uses a template parameter in a
+ deducible way; that is, if it has a max value of <PARM> - 1. */
+
+static bool
+deducible_array_bound (tree domain)
+{
+ if (domain == NULL_TREE)
+ return false;
+
+ tree max = TYPE_MAX_VALUE (domain);
+ if (TREE_CODE (max) != MINUS_EXPR)
+ return false;
+
+ return deducible_expression (TREE_OPERAND (max, 0));
+}
+
+/* Returns true iff the template arguments ARGS use a template parameter
+ in a deducible way. */
+
+static bool
+deducible_template_args (tree args)
+{
+ for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
+ {
+ bool deducible;
+ tree elt = TREE_VEC_ELT (args, i);
+ if (ARGUMENT_PACK_P (elt))
+ deducible = deducible_template_args (ARGUMENT_PACK_ARGS (elt));
+ else
+ {
+ if (PACK_EXPANSION_P (elt))
+ elt = PACK_EXPANSION_PATTERN (elt);
+ if (TREE_CODE (elt) == TEMPLATE_TEMPLATE_PARM)
+ deducible = true;
+ else if (TYPE_P (elt))
+ deducible = uses_deducible_template_parms (elt);
+ else
+ deducible = deducible_expression (elt);
+ }
+ if (deducible)
+ return true;
+ }
+ return false;
+}
+
+/* Returns true iff TYPE contains any deducible references to template
+ parameters, as per 14.8.2.5. */
+
+static bool
+uses_deducible_template_parms (tree type)
+{
+ if (PACK_EXPANSION_P (type))
+ type = PACK_EXPANSION_PATTERN (type);
+
+ /* T
+ cv-list T
+ TT<T>
+ TT<i>
+ TT<> */
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
+ || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ return true;
+
+ /* T*
+ T&
+ T&& */
+ if (POINTER_TYPE_P (type))
+ return uses_deducible_template_parms (TREE_TYPE (type));
+
+ /* T[integer-constant ]
+ type [i] */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ return (uses_deducible_template_parms (TREE_TYPE (type))
+ || deducible_array_bound (TYPE_DOMAIN (type)));
+
+ /* T type ::*
+ type T::*
+ T T::*
+ T (type ::*)()
+ type (T::*)()
+ type (type ::*)(T)
+ type (T::*)(T)
+ T (type ::*)(T)
+ T (T::*)()
+ T (T::*)(T) */
+ if (TYPE_PTRMEM_P (type))
+ return (uses_deducible_template_parms (TYPE_PTRMEM_CLASS_TYPE (type))
+ || (uses_deducible_template_parms
+ (TYPE_PTRMEM_POINTED_TO_TYPE (type))));
+
+ /* template-name <T> (where template-name refers to a class template)
+ template-name <i> (where template-name refers to a class template) */
+ if (CLASS_TYPE_P (type)
+ && CLASSTYPE_TEMPLATE_INFO (type)
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
+ return deducible_template_args (INNERMOST_TEMPLATE_ARGS
+ (CLASSTYPE_TI_ARGS (type)));
+
+ /* type (T)
+ T()
+ T(T) */
+ if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
+ {
+ if (uses_deducible_template_parms (TREE_TYPE (type)))
+ return true;
+ tree parm = TYPE_ARG_TYPES (type);
+ if (TREE_CODE (type) == METHOD_TYPE)
+ parm = TREE_CHAIN (parm);
+ for (; parm; parm = TREE_CHAIN (parm))
+ if (uses_deducible_template_parms (TREE_VALUE (parm)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Subroutine of type_unification_real and unify_pack_expansion to
+ handle unification of a single P/A pair. Parameters are as
+ for those functions. */
+
+static int
+unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
+ int subr, unification_kind_t strict, int flags,
+ bool explain_p)
+{
+ tree arg_expr = NULL_TREE;
+ int arg_strict;
+
+ if (arg == error_mark_node || parm == error_mark_node)
+ return unify_invalid (explain_p);
+ if (arg == unknown_type_node)
+ /* We can't deduce anything from this, but we might get all the
+ template args from other function args. */
+ return unify_success (explain_p);
+
+ /* Implicit conversions (Clause 4) will be performed on a function
+ argument to convert it to the type of the corresponding function
+ parameter if the parameter type contains no template-parameters that
+ participate in template argument deduction. */
+ if (TYPE_P (parm) && !uses_template_parms (parm))
+ /* For function parameters that contain no template-parameters at all,
+ we have historically checked for convertibility in order to shortcut
+ consideration of this candidate. */
+ return check_non_deducible_conversion (parm, arg, strict, flags,
+ explain_p);
+ else if (strict == DEDUCE_CALL
+ && TYPE_P (parm) && !uses_deducible_template_parms (parm))
+ /* For function parameters with only non-deducible template parameters,
+ just return. */
+ return unify_success (explain_p);
+
+ switch (strict)
+ {
+ case DEDUCE_CALL:
+ arg_strict = (UNIFY_ALLOW_OUTER_LEVEL
+ | UNIFY_ALLOW_MORE_CV_QUAL
+ | UNIFY_ALLOW_DERIVED);
+ break;
+
+ case DEDUCE_CONV:
+ arg_strict = UNIFY_ALLOW_LESS_CV_QUAL;
+ break;
+
+ case DEDUCE_EXACT:
+ arg_strict = UNIFY_ALLOW_NONE;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ /* We only do these transformations if this is the top-level
+ parameter_type_list in a call or declaration matching; in other
+ situations (nested function declarators, template argument lists) we
+ won't be comparing a type to an expression, and we don't do any type
+ adjustments. */
+ if (!subr)
+ {
+ if (!TYPE_P (arg))
+ {
+ gcc_assert (TREE_TYPE (arg) != NULL_TREE);
+ if (type_unknown_p (arg))
+ {
+ /* [temp.deduct.type] A template-argument can be
+ deduced from a pointer to function or pointer
+ to member function argument if the set of
+ overloaded functions does not contain function
+ templates and at most one of a set of
+ overloaded functions provides a unique
+ match. */
+
+ if (resolve_overloaded_unification
+ (tparms, targs, parm, arg, strict,
+ arg_strict, explain_p))
+ return unify_success (explain_p);
+ return unify_overload_resolution_failure (explain_p, arg);
+ }
+
+ arg_expr = arg;
+ arg = unlowered_expr_type (arg);
+ if (arg == error_mark_node)
+ return unify_invalid (explain_p);
+ }
+
+ arg_strict |=
+ maybe_adjust_types_for_deduction (strict, &parm, &arg, arg_expr);
+ }
+ else
+ gcc_assert ((TYPE_P (parm) || TREE_CODE (parm) == TEMPLATE_DECL)
+ == (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL));
+
+ /* For deduction from an init-list we need the actual list. */
+ if (arg_expr && BRACE_ENCLOSED_INITIALIZER_P (arg_expr))
+ arg = arg_expr;
+ return unify (tparms, targs, parm, arg, arg_strict, explain_p);
+}
+
+/* Most parms like fn_type_unification.
+
+ If SUBR is 1, we're being called recursively (to unify the
+ arguments of a function or method parameter of a function
+ template).
+
+ CHECKS is a pointer to a vector of access checks encountered while
+ substituting default template arguments. */
+
+static int
+type_unification_real (tree tparms,
+ tree targs,
+ tree xparms,
+ const tree *xargs,
+ unsigned int xnargs,
+ int subr,
+ unification_kind_t strict,
+ int flags,
+ vec<deferred_access_check, va_gc> **checks,
+ bool explain_p)
+{
+ tree parm, arg;
+ int i;
+ int ntparms = TREE_VEC_LENGTH (tparms);
+ int saw_undeduced = 0;
+ tree parms;
+ const tree *args;
+ unsigned int nargs;
+ unsigned int ia;
+
+ gcc_assert (TREE_CODE (tparms) == TREE_VEC);
+ gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
+ gcc_assert (ntparms > 0);
+
+ /* Reset the number of non-defaulted template arguments contained
+ in TARGS. */
+ NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs) = NULL_TREE;
+
+ again:
+ parms = xparms;
+ args = xargs;
+ nargs = xnargs;
+
+ ia = 0;
+ while (parms && parms != void_list_node
+ && ia < nargs)
+ {
+ parm = TREE_VALUE (parms);
+
+ if (TREE_CODE (parm) == TYPE_PACK_EXPANSION
+ && (!TREE_CHAIN (parms) || TREE_CHAIN (parms) == void_list_node))
+ /* For a function parameter pack that occurs at the end of the
+ parameter-declaration-list, the type A of each remaining
+ argument of the call is compared with the type P of the
+ declarator-id of the function parameter pack. */
+ break;
+
+ parms = TREE_CHAIN (parms);
+
+ if (TREE_CODE (parm) == TYPE_PACK_EXPANSION)
+ /* For a function parameter pack that does not occur at the
+ end of the parameter-declaration-list, the type of the
+ parameter pack is a non-deduced context. */
+ continue;
+
+ arg = args[ia];
+ ++ia;
+
+ if (unify_one_argument (tparms, targs, parm, arg, subr, strict,
+ flags, explain_p))
+ return 1;
+ }
+
+ if (parms
+ && parms != void_list_node
+ && TREE_CODE (TREE_VALUE (parms)) == TYPE_PACK_EXPANSION)
+ {
+ /* Unify the remaining arguments with the pack expansion type. */
+ tree argvec;
+ tree parmvec = make_tree_vec (1);
+
+ /* Allocate a TREE_VEC and copy in all of the arguments */
+ argvec = make_tree_vec (nargs - ia);
+ for (i = 0; ia < nargs; ++ia, ++i)
+ TREE_VEC_ELT (argvec, i) = args[ia];
+
+ /* Copy the parameter into parmvec. */
+ TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms);
+ if (unify_pack_expansion (tparms, targs, parmvec, argvec, strict,
+ /*subr=*/subr, explain_p))
+ return 1;
+
+ /* Advance to the end of the list of parameters. */
+ parms = TREE_CHAIN (parms);
+ }
+
+ /* Fail if we've reached the end of the parm list, and more args
+ are present, and the parm list isn't variadic. */
+ if (ia < nargs && parms == void_list_node)
+ return unify_too_many_arguments (explain_p, nargs, ia);
+ /* Fail if parms are left and they don't have default values. */
+ if (parms && parms != void_list_node
+ && TREE_PURPOSE (parms) == NULL_TREE)
+ {
+ unsigned int count = nargs;
+ tree p = parms;
+ while (p && p != void_list_node)
+ {
+ count++;
+ p = TREE_CHAIN (p);
+ }
+ return unify_too_few_arguments (explain_p, ia, count);
+ }
+
+ if (!subr)
+ {
+ tsubst_flags_t complain = (explain_p
+ ? tf_warning_or_error
+ : tf_none);
+
+ for (i = 0; i < ntparms; i++)
+ {
+ tree targ = TREE_VEC_ELT (targs, i);
+ tree tparm = TREE_VEC_ELT (tparms, i);
+
+ /* Clear the "incomplete" flags on all argument packs now so that
+ substituting them into later default arguments works. */
+ if (targ && ARGUMENT_PACK_P (targ))
+ {
+ ARGUMENT_PACK_INCOMPLETE_P (targ) = 0;
+ ARGUMENT_PACK_EXPLICIT_ARGS (targ) = NULL_TREE;
+ }
+
+ if (targ || tparm == error_mark_node)
+ continue;
+ tparm = TREE_VALUE (tparm);
+
+ /* If this is an undeduced nontype parameter that depends on
+ a type parameter, try another pass; its type may have been
+ deduced from a later argument than the one from which
+ this parameter can be deduced. */
+ if (TREE_CODE (tparm) == PARM_DECL
+ && uses_template_parms (TREE_TYPE (tparm))
+ && !saw_undeduced++)
+ goto again;
+
+ /* Core issue #226 (C++0x) [temp.deduct]:
+
+ If a template argument has not been deduced, its
+ default template argument, if any, is used.
+
+ When we are in C++98 mode, TREE_PURPOSE will either
+ be NULL_TREE or ERROR_MARK_NODE, so we do not need
+ to explicitly check cxx_dialect here. */
+ if (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)))
+ {
+ tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
+ tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i));
+ reopen_deferring_access_checks (*checks);
+ location_t save_loc = input_location;
+ if (DECL_P (parm))
+ input_location = DECL_SOURCE_LOCATION (parm);
+ arg = tsubst_template_arg (arg, targs, complain, NULL_TREE);
+ arg = convert_template_argument (parm, arg, targs, complain,
+ i, NULL_TREE);
+ input_location = save_loc;
+ *checks = get_deferred_access_checks ();
+ pop_deferring_access_checks ();
+ if (arg == error_mark_node)
+ return 1;
+ else
+ {
+ TREE_VEC_ELT (targs, i) = arg;
+ /* The position of the first default template argument,
+ is also the number of non-defaulted arguments in TARGS.
+ Record that. */
+ if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
+ continue;
+ }
+ }
+
+ /* If the type parameter is a parameter pack, then it will
+ be deduced to an empty parameter pack. */
+ if (template_parameter_pack_p (tparm))
+ {
+ tree arg;
+
+ if (TREE_CODE (tparm) == TEMPLATE_PARM_INDEX)
+ {
+ arg = make_node (NONTYPE_ARGUMENT_PACK);
+ TREE_TYPE (arg) = TREE_TYPE (TEMPLATE_PARM_DECL (tparm));
+ TREE_CONSTANT (arg) = 1;
+ }
+ else
+ arg = cxx_make_type (TYPE_ARGUMENT_PACK);
+
+ SET_ARGUMENT_PACK_ARGS (arg, make_tree_vec (0));
+
+ TREE_VEC_ELT (targs, i) = arg;
+ continue;
+ }
+
+ return unify_parameter_deduction_failure (explain_p, tparm);
+ }
+ }
+#ifdef ENABLE_CHECKING
+ if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs));
+#endif
+
+ return unify_success (explain_p);
+}
+
+/* Subroutine of type_unification_real. Args are like the variables
+ at the call site. ARG is an overloaded function (or template-id);
+ we try deducing template args from each of the overloads, and if
+ only one succeeds, we go with that. Modifies TARGS and returns
+ true on success. */
+
+static bool
+resolve_overloaded_unification (tree tparms,
+ tree targs,
+ tree parm,
+ tree arg,
+ unification_kind_t strict,
+ int sub_strict,
+ bool explain_p)
+{
+ tree tempargs = copy_node (targs);
+ int good = 0;
+ tree goodfn = NULL_TREE;
+ bool addr_p;
+
+ if (TREE_CODE (arg) == ADDR_EXPR)
+ {
+ arg = TREE_OPERAND (arg, 0);
+ addr_p = true;
+ }
+ else
+ addr_p = false;
+
+ if (TREE_CODE (arg) == COMPONENT_REF)
+ /* Handle `&x' where `x' is some static or non-static member
+ function name. */
+ arg = TREE_OPERAND (arg, 1);
+
+ if (TREE_CODE (arg) == OFFSET_REF)
+ arg = TREE_OPERAND (arg, 1);
+
+ /* Strip baselink information. */
+ if (BASELINK_P (arg))
+ arg = BASELINK_FUNCTIONS (arg);
+
+ if (TREE_CODE (arg) == TEMPLATE_ID_EXPR)
+ {
+ /* If we got some explicit template args, we need to plug them into
+ the affected templates before we try to unify, in case the
+ explicit args will completely resolve the templates in question. */
+
+ int ok = 0;
+ tree expl_subargs = TREE_OPERAND (arg, 1);
+ arg = TREE_OPERAND (arg, 0);
+
+ for (; arg; arg = OVL_NEXT (arg))
+ {
+ tree fn = OVL_CURRENT (arg);
+ tree subargs, elem;
+
+ if (TREE_CODE (fn) != TEMPLATE_DECL)
+ continue;
+
+ subargs = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn),
+ expl_subargs, NULL_TREE, tf_none,
+ /*require_all_args=*/true,
+ /*use_default_args=*/true);
+ if (subargs != error_mark_node
+ && !any_dependent_template_arguments_p (subargs))
+ {
+ elem = TREE_TYPE (instantiate_template (fn, subargs, tf_none));
+ if (try_one_overload (tparms, targs, tempargs, parm,
+ elem, strict, sub_strict, addr_p, explain_p)
+ && (!goodfn || !same_type_p (goodfn, elem)))
+ {
+ goodfn = elem;
+ ++good;
+ }
+ }
+ else if (subargs)
+ ++ok;
+ }
+ /* If no templates (or more than one) are fully resolved by the
+ explicit arguments, this template-id is a non-deduced context; it
+ could still be OK if we deduce all template arguments for the
+ enclosing call through other arguments. */
+ if (good != 1)
+ good = ok;
+ }
+ else if (TREE_CODE (arg) != OVERLOAD
+ && TREE_CODE (arg) != FUNCTION_DECL)
+ /* If ARG is, for example, "(0, &f)" then its type will be unknown
+ -- but the deduction does not succeed because the expression is
+ not just the function on its own. */
+ return false;
+ else
+ for (; arg; arg = OVL_NEXT (arg))
+ if (try_one_overload (tparms, targs, tempargs, parm,
+ TREE_TYPE (OVL_CURRENT (arg)),
+ strict, sub_strict, addr_p, explain_p)
+ && (!goodfn || !decls_match (goodfn, OVL_CURRENT (arg))))
+ {
+ goodfn = OVL_CURRENT (arg);
+ ++good;
+ }
+
+ /* [temp.deduct.type] A template-argument can be deduced from a pointer
+ to function or pointer to member function argument if the set of
+ overloaded functions does not contain function templates and at most
+ one of a set of overloaded functions provides a unique match.
+
+ So if we found multiple possibilities, we return success but don't
+ deduce anything. */
+
+ if (good == 1)
+ {
+ int i = TREE_VEC_LENGTH (targs);
+ for (; i--; )
+ if (TREE_VEC_ELT (tempargs, i))
+ TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (tempargs, i);
+ }
+ if (good)
+ return true;
+
+ return false;
+}
+
+/* Core DR 115: In contexts where deduction is done and fails, or in
+ contexts where deduction is not done, if a template argument list is
+ specified and it, along with any default template arguments, identifies
+ a single function template specialization, then the template-id is an
+ lvalue for the function template specialization. */
+
+tree
+resolve_nondeduced_context (tree orig_expr)
+{
+ tree expr, offset, baselink;
+ bool addr;
+
+ if (!type_unknown_p (orig_expr))
+ return orig_expr;
+
+ expr = orig_expr;
+ addr = false;
+ offset = NULL_TREE;
+ baselink = NULL_TREE;
+
+ if (TREE_CODE (expr) == ADDR_EXPR)
+ {
+ expr = TREE_OPERAND (expr, 0);
+ addr = true;
+ }
+ if (TREE_CODE (expr) == OFFSET_REF)
+ {
+ offset = expr;
+ expr = TREE_OPERAND (expr, 1);
+ }
+ if (BASELINK_P (expr))
+ {
+ baselink = expr;
+ expr = BASELINK_FUNCTIONS (expr);
+ }
+
+ if (TREE_CODE (expr) == TEMPLATE_ID_EXPR)
+ {
+ int good = 0;
+ tree goodfn = NULL_TREE;
+
+ /* If we got some explicit template args, we need to plug them into
+ the affected templates before we try to unify, in case the
+ explicit args will completely resolve the templates in question. */
+
+ tree expl_subargs = TREE_OPERAND (expr, 1);
+ tree arg = TREE_OPERAND (expr, 0);
+ tree badfn = NULL_TREE;
+ tree badargs = NULL_TREE;
+
+ for (; arg; arg = OVL_NEXT (arg))
+ {
+ tree fn = OVL_CURRENT (arg);
+ tree subargs, elem;
+
+ if (TREE_CODE (fn) != TEMPLATE_DECL)
+ continue;
+
+ subargs = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn),
+ expl_subargs, NULL_TREE, tf_none,
+ /*require_all_args=*/true,
+ /*use_default_args=*/true);
+ if (subargs != error_mark_node
+ && !any_dependent_template_arguments_p (subargs))
+ {
+ elem = instantiate_template (fn, subargs, tf_none);
+ if (elem == error_mark_node)
+ {
+ badfn = fn;
+ badargs = subargs;
+ }
+ else if (elem && (!goodfn || !decls_match (goodfn, elem)))
+ {
+ goodfn = elem;
+ ++good;
+ }
+ }
+ }
+ if (good == 1)
+ {
+ mark_used (goodfn);
+ expr = goodfn;
+ if (baselink)
+ expr = build_baselink (BASELINK_BINFO (baselink),
+ BASELINK_ACCESS_BINFO (baselink),
+ expr, BASELINK_OPTYPE (baselink));
+ if (offset)
+ {
+ tree base
+ = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (offset, 0)));
+ expr = build_offset_ref (base, expr, addr, tf_warning_or_error);
+ }
+ if (addr)
+ expr = cp_build_addr_expr (expr, tf_warning_or_error);
+ return expr;
+ }
+ else if (good == 0 && badargs)
+ /* There were no good options and at least one bad one, so let the
+ user know what the problem is. */
+ instantiate_template (badfn, badargs, tf_warning_or_error);
+ }
+ return orig_expr;
+}
+
+/* Subroutine of resolve_overloaded_unification; does deduction for a single
+ overload. Fills TARGS with any deduced arguments, or error_mark_node if
+ different overloads deduce different arguments for a given parm.
+ ADDR_P is true if the expression for which deduction is being
+ performed was of the form "& fn" rather than simply "fn".
+
+ Returns 1 on success. */
+
+static int
+try_one_overload (tree tparms,
+ tree orig_targs,
+ tree targs,
+ tree parm,
+ tree arg,
+ unification_kind_t strict,
+ int sub_strict,
+ bool addr_p,
+ bool explain_p)
+{
+ int nargs;
+ tree tempargs;
+ int i;
+
+ if (arg == error_mark_node)
+ return 0;
+
+ /* [temp.deduct.type] A template-argument can be deduced from a pointer
+ to function or pointer to member function argument if the set of
+ overloaded functions does not contain function templates and at most
+ one of a set of overloaded functions provides a unique match.
+
+ So if this is a template, just return success. */
+
+ if (uses_template_parms (arg))
+ return 1;
+
+ if (TREE_CODE (arg) == METHOD_TYPE)
+ arg = build_ptrmemfunc_type (build_pointer_type (arg));
+ else if (addr_p)
+ arg = build_pointer_type (arg);
+
+ sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg, NULL);
+
+ /* We don't copy orig_targs for this because if we have already deduced
+ some template args from previous args, unify would complain when we
+ try to deduce a template parameter for the same argument, even though
+ there isn't really a conflict. */
+ nargs = TREE_VEC_LENGTH (targs);
+ tempargs = make_tree_vec (nargs);
+
+ if (unify (tparms, tempargs, parm, arg, sub_strict, explain_p))
+ return 0;
+
+ /* First make sure we didn't deduce anything that conflicts with
+ explicitly specified args. */
+ for (i = nargs; i--; )
+ {
+ tree elt = TREE_VEC_ELT (tempargs, i);
+ tree oldelt = TREE_VEC_ELT (orig_targs, i);
+
+ if (!elt)
+ /*NOP*/;
+ else if (uses_template_parms (elt))
+ /* Since we're unifying against ourselves, we will fill in
+ template args used in the function parm list with our own
+ template parms. Discard them. */
+ TREE_VEC_ELT (tempargs, i) = NULL_TREE;
+ else if (oldelt && !template_args_equal (oldelt, elt))
+ return 0;
+ }
+
+ for (i = nargs; i--; )
+ {
+ tree elt = TREE_VEC_ELT (tempargs, i);
+
+ if (elt)
+ TREE_VEC_ELT (targs, i) = elt;
+ }
+
+ return 1;
+}
+
+/* PARM is a template class (perhaps with unbound template
+ parameters). ARG is a fully instantiated type. If ARG can be
+ bound to PARM, return ARG, otherwise return NULL_TREE. TPARMS and
+ TARGS are as for unify. */
+
+static tree
+try_class_unification (tree tparms, tree targs, tree parm, tree arg,
+ bool explain_p)
+{
+ tree copy_of_targs;
+
+ if (!CLASSTYPE_TEMPLATE_INFO (arg)
+ || (most_general_template (CLASSTYPE_TI_TEMPLATE (arg))
+ != most_general_template (CLASSTYPE_TI_TEMPLATE (parm))))
+ return NULL_TREE;
+
+ /* We need to make a new template argument vector for the call to
+ unify. If we used TARGS, we'd clutter it up with the result of
+ the attempted unification, even if this class didn't work out.
+ We also don't want to commit ourselves to all the unifications
+ we've already done, since unification is supposed to be done on
+ an argument-by-argument basis. In other words, consider the
+ following pathological case:
+
+ template <int I, int J, int K>
+ struct S {};
+
+ template <int I, int J>
+ struct S<I, J, 2> : public S<I, I, I>, S<J, J, J> {};
+
+ template <int I, int J, int K>
+ void f(S<I, J, K>, S<I, I, I>);
+
+ void g() {
+ S<0, 0, 0> s0;
+ S<0, 1, 2> s2;
+
+ f(s0, s2);
+ }
+
+ Now, by the time we consider the unification involving `s2', we
+ already know that we must have `f<0, 0, 0>'. But, even though
+ `S<0, 1, 2>' is derived from `S<0, 0, 0>', the code is invalid
+ because there are two ways to unify base classes of S<0, 1, 2>
+ with S<I, I, I>. If we kept the already deduced knowledge, we
+ would reject the possibility I=1. */
+ copy_of_targs = make_tree_vec (TREE_VEC_LENGTH (targs));
+
+ /* If unification failed, we're done. */
+ if (unify (tparms, copy_of_targs, CLASSTYPE_TI_ARGS (parm),
+ CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE, explain_p))
+ return NULL_TREE;
+
+ return arg;
+}
+
+/* Given a template type PARM and a class type ARG, find the unique
+ base type in ARG that is an instance of PARM. We do not examine
+ ARG itself; only its base-classes. If there is not exactly one
+ appropriate base class, return NULL_TREE. PARM may be the type of
+ a partial specialization, as well as a plain template type. Used
+ by unify. */
+
+static enum template_base_result
+get_template_base (tree tparms, tree targs, tree parm, tree arg,
+ bool explain_p, tree *result)
+{
+ tree rval = NULL_TREE;
+ tree binfo;
+
+ gcc_assert (RECORD_OR_UNION_CODE_P (TREE_CODE (arg)));
+
+ binfo = TYPE_BINFO (complete_type (arg));
+ if (!binfo)
+ {
+ /* The type could not be completed. */
+ *result = NULL_TREE;
+ return tbr_incomplete_type;
+ }
+
+ /* Walk in inheritance graph order. The search order is not
+ important, and this avoids multiple walks of virtual bases. */
+ for (binfo = TREE_CHAIN (binfo); binfo; binfo = TREE_CHAIN (binfo))
+ {
+ tree r = try_class_unification (tparms, targs, parm,
+ BINFO_TYPE (binfo), explain_p);
+
+ if (r)
+ {
+ /* If there is more than one satisfactory baseclass, then:
+
+ [temp.deduct.call]
+
+ If they yield more than one possible deduced A, the type
+ deduction fails.
+
+ applies. */
+ if (rval && !same_type_p (r, rval))
+ {
+ *result = NULL_TREE;
+ return tbr_ambiguous_baseclass;
+ }
+
+ rval = r;
+ }
+ }
+
+ *result = rval;
+ return tbr_success;
+}
+
+/* Returns the level of DECL, which declares a template parameter. */
+
+static int
+template_decl_level (tree decl)
+{
+ switch (TREE_CODE (decl))
+ {
+ case TYPE_DECL:
+ case TEMPLATE_DECL:
+ return TEMPLATE_TYPE_LEVEL (TREE_TYPE (decl));
+
+ case PARM_DECL:
+ return TEMPLATE_PARM_LEVEL (DECL_INITIAL (decl));
+
+ default:
+ gcc_unreachable ();
+ }
+ return 0;
+}
+
+/* Decide whether ARG can be unified with PARM, considering only the
+ cv-qualifiers of each type, given STRICT as documented for unify.
+ Returns nonzero iff the unification is OK on that basis. */
+
+static int
+check_cv_quals_for_unify (int strict, tree arg, tree parm)
+{
+ int arg_quals = cp_type_quals (arg);
+ int parm_quals = cp_type_quals (parm);
+
+ if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM
+ && !(strict & UNIFY_ALLOW_OUTER_MORE_CV_QUAL))
+ {
+ /* Although a CVR qualifier is ignored when being applied to a
+ substituted template parameter ([8.3.2]/1 for example), that
+ does not allow us to unify "const T" with "int&" because both
+ types are not of the form "cv-list T" [14.8.2.5 temp.deduct.type].
+ It is ok when we're allowing additional CV qualifiers
+ at the outer level [14.8.2.1]/3,1st bullet. */
+ if ((TREE_CODE (arg) == REFERENCE_TYPE
+ || TREE_CODE (arg) == FUNCTION_TYPE
+ || TREE_CODE (arg) == METHOD_TYPE)
+ && (parm_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)))
+ return 0;
+
+ if ((!POINTER_TYPE_P (arg) && TREE_CODE (arg) != TEMPLATE_TYPE_PARM)
+ && (parm_quals & TYPE_QUAL_RESTRICT))
+ return 0;
+ }
+
+ if (!(strict & (UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_OUTER_MORE_CV_QUAL))
+ && (arg_quals & parm_quals) != parm_quals)
+ return 0;
+
+ if (!(strict & (UNIFY_ALLOW_LESS_CV_QUAL | UNIFY_ALLOW_OUTER_LESS_CV_QUAL))
+ && (parm_quals & arg_quals) != arg_quals)
+ return 0;
+
+ return 1;
+}
+
+/* Determines the LEVEL and INDEX for the template parameter PARM. */
+void
+template_parm_level_and_index (tree parm, int* level, int* index)
+{
+ if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM
+ || TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ {
+ *index = TEMPLATE_TYPE_IDX (parm);
+ *level = TEMPLATE_TYPE_LEVEL (parm);
+ }
+ else
+ {
+ *index = TEMPLATE_PARM_IDX (parm);
+ *level = TEMPLATE_PARM_LEVEL (parm);
+ }
+}
+
+#define RECUR_AND_CHECK_FAILURE(TP, TA, P, A, S, EP) \
+ do { \
+ if (unify (TP, TA, P, A, S, EP)) \
+ return 1; \
+ } while (0);
+
+/* Unifies the remaining arguments in PACKED_ARGS with the pack
+ expansion at the end of PACKED_PARMS. Returns 0 if the type
+ deduction succeeds, 1 otherwise. STRICT is the same as in
+ unify. CALL_ARGS_P is true iff PACKED_ARGS is actually a function
+ call argument list. We'll need to adjust the arguments to make them
+ types. SUBR tells us if this is from a recursive call to
+ type_unification_real, or for comparing two template argument
+ lists. */
+
+static int
+unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
+ tree packed_args, unification_kind_t strict,
+ bool subr, bool explain_p)
+{
+ tree parm
+ = TREE_VEC_ELT (packed_parms, TREE_VEC_LENGTH (packed_parms) - 1);
+ tree pattern = PACK_EXPANSION_PATTERN (parm);
+ tree pack, packs = NULL_TREE;
+ int i, start = TREE_VEC_LENGTH (packed_parms) - 1;
+
+ packed_args = expand_template_argument_pack (packed_args);
+
+ int len = TREE_VEC_LENGTH (packed_args);
+
+ /* Determine the parameter packs we will be deducing from the
+ pattern, and record their current deductions. */
+ for (pack = PACK_EXPANSION_PARAMETER_PACKS (parm);
+ pack; pack = TREE_CHAIN (pack))
+ {
+ tree parm_pack = TREE_VALUE (pack);
+ int idx, level;
+
+ /* Determine the index and level of this parameter pack. */
+ template_parm_level_and_index (parm_pack, &level, &idx);
+
+ /* Keep track of the parameter packs and their corresponding
+ argument packs. */
+ packs = tree_cons (parm_pack, TMPL_ARG (targs, level, idx), packs);
+ TREE_TYPE (packs) = make_tree_vec (len - start);
+ }
+
+ /* Loop through all of the arguments that have not yet been
+ unified and unify each with the pattern. */
+ for (i = start; i < len; i++)
+ {
+ tree parm;
+ bool any_explicit = false;
+ tree arg = TREE_VEC_ELT (packed_args, i);
+
+ /* For each parameter pack, set its TMPL_ARG to either NULL_TREE
+ or the element of its argument pack at the current index if
+ this argument was explicitly specified. */
+ for (pack = packs; pack; pack = TREE_CHAIN (pack))
+ {
+ int idx, level;
+ tree arg, pargs;
+ template_parm_level_and_index (TREE_PURPOSE (pack), &level, &idx);
+
+ arg = NULL_TREE;
+ if (TREE_VALUE (pack)
+ && (pargs = ARGUMENT_PACK_EXPLICIT_ARGS (TREE_VALUE (pack)))
+ && (i - start < TREE_VEC_LENGTH (pargs)))
+ {
+ any_explicit = true;
+ arg = TREE_VEC_ELT (pargs, i - start);
+ }
+ TMPL_ARG (targs, level, idx) = arg;
+ }
+
+ /* If we had explicit template arguments, substitute them into the
+ pattern before deduction. */
+ if (any_explicit)
+ {
+ /* Some arguments might still be unspecified or dependent. */
+ bool dependent;
+ ++processing_template_decl;
+ dependent = any_dependent_template_arguments_p (targs);
+ if (!dependent)
+ --processing_template_decl;
+ parm = tsubst (pattern, targs,
+ explain_p ? tf_warning_or_error : tf_none,
+ NULL_TREE);
+ if (dependent)
+ --processing_template_decl;
+ if (parm == error_mark_node)
+ return 1;
+ }
+ else
+ parm = pattern;
+
+ /* Unify the pattern with the current argument. */
+ if (unify_one_argument (tparms, targs, parm, arg, subr, strict,
+ LOOKUP_IMPLICIT, explain_p))
+ return 1;
+
+ /* For each parameter pack, collect the deduced value. */
+ for (pack = packs; pack; pack = TREE_CHAIN (pack))
+ {
+ int idx, level;
+ template_parm_level_and_index (TREE_PURPOSE (pack), &level, &idx);
+
+ TREE_VEC_ELT (TREE_TYPE (pack), i - start) =
+ TMPL_ARG (targs, level, idx);
+ }
+ }
+
+ /* Verify that the results of unification with the parameter packs
+ produce results consistent with what we've seen before, and make
+ the deduced argument packs available. */
+ for (pack = packs; pack; pack = TREE_CHAIN (pack))
+ {
+ tree old_pack = TREE_VALUE (pack);
+ tree new_args = TREE_TYPE (pack);
+ int i, len = TREE_VEC_LENGTH (new_args);
+ int idx, level;
+ bool nondeduced_p = false;
+
+ /* By default keep the original deduced argument pack.
+ If necessary, more specific code is going to update the
+ resulting deduced argument later down in this function. */
+ template_parm_level_and_index (TREE_PURPOSE (pack), &level, &idx);
+ TMPL_ARG (targs, level, idx) = old_pack;
+
+ /* If NEW_ARGS contains any NULL_TREE entries, we didn't
+ actually deduce anything. */
+ for (i = 0; i < len && !nondeduced_p; ++i)
+ if (TREE_VEC_ELT (new_args, i) == NULL_TREE)
+ nondeduced_p = true;
+ if (nondeduced_p)
+ continue;
+
+ if (old_pack && ARGUMENT_PACK_INCOMPLETE_P (old_pack))
+ {
+ /* If we had fewer function args than explicit template args,
+ just use the explicits. */
+ tree explicit_args = ARGUMENT_PACK_EXPLICIT_ARGS (old_pack);
+ int explicit_len = TREE_VEC_LENGTH (explicit_args);
+ if (len < explicit_len)
+ new_args = explicit_args;
+ }
+
+ if (!old_pack)
+ {
+ tree result;
+ /* Build the deduced *_ARGUMENT_PACK. */
+ if (TREE_CODE (TREE_PURPOSE (pack)) == TEMPLATE_PARM_INDEX)
+ {
+ result = make_node (NONTYPE_ARGUMENT_PACK);
+ TREE_TYPE (result) =
+ TREE_TYPE (TEMPLATE_PARM_DECL (TREE_PURPOSE (pack)));
+ TREE_CONSTANT (result) = 1;
+ }
+ else
+ result = cxx_make_type (TYPE_ARGUMENT_PACK);
+
+ SET_ARGUMENT_PACK_ARGS (result, new_args);
+
+ /* Note the deduced argument packs for this parameter
+ pack. */
+ TMPL_ARG (targs, level, idx) = result;
+ }
+ else if (ARGUMENT_PACK_INCOMPLETE_P (old_pack)
+ && (ARGUMENT_PACK_ARGS (old_pack)
+ == ARGUMENT_PACK_EXPLICIT_ARGS (old_pack)))
+ {
+ /* We only had the explicitly-provided arguments before, but
+ now we have a complete set of arguments. */
+ tree explicit_args = ARGUMENT_PACK_EXPLICIT_ARGS (old_pack);
+
+ SET_ARGUMENT_PACK_ARGS (old_pack, new_args);
+ ARGUMENT_PACK_INCOMPLETE_P (old_pack) = 1;
+ ARGUMENT_PACK_EXPLICIT_ARGS (old_pack) = explicit_args;
+ }
+ else
+ {
+ tree bad_old_arg = NULL_TREE, bad_new_arg = NULL_TREE;
+ tree old_args = ARGUMENT_PACK_ARGS (old_pack);
+
+ if (!comp_template_args_with_info (old_args, new_args,
+ &bad_old_arg, &bad_new_arg))
+ /* Inconsistent unification of this parameter pack. */
+ return unify_parameter_pack_inconsistent (explain_p,
+ bad_old_arg,
+ bad_new_arg);
+ }
+ }
+
+ return unify_success (explain_p);
+}
+
+/* Handle unification of the domain of an array. PARM_DOM and ARG_DOM are
+ INTEGER_TYPEs representing the TYPE_DOMAIN of ARRAY_TYPEs. The other
+ parameters and return value are as for unify. */
+
+static int
+unify_array_domain (tree tparms, tree targs,
+ tree parm_dom, tree arg_dom,
+ bool explain_p)
+{
+ tree parm_max;
+ tree arg_max;
+ bool parm_cst;
+ bool arg_cst;
+
+ /* Our representation of array types uses "N - 1" as the
+ TYPE_MAX_VALUE for an array with "N" elements, if "N" is
+ not an integer constant. We cannot unify arbitrarily
+ complex expressions, so we eliminate the MINUS_EXPRs
+ here. */
+ parm_max = TYPE_MAX_VALUE (parm_dom);
+ parm_cst = TREE_CODE (parm_max) == INTEGER_CST;
+ if (!parm_cst)
+ {
+ gcc_assert (TREE_CODE (parm_max) == MINUS_EXPR);
+ parm_max = TREE_OPERAND (parm_max, 0);
+ }
+ arg_max = TYPE_MAX_VALUE (arg_dom);
+ arg_cst = TREE_CODE (arg_max) == INTEGER_CST;
+ if (!arg_cst)
+ {
+ /* The ARG_MAX may not be a simple MINUS_EXPR, if we are
+ trying to unify the type of a variable with the type
+ of a template parameter. For example:
+
+ template <unsigned int N>
+ void f (char (&) [N]);
+ int g();
+ void h(int i) {
+ char a[g(i)];
+ f(a);
+ }
+
+ Here, the type of the ARG will be "int [g(i)]", and
+ may be a SAVE_EXPR, etc. */
+ if (TREE_CODE (arg_max) != MINUS_EXPR)
+ return unify_vla_arg (explain_p, arg_dom);
+ arg_max = TREE_OPERAND (arg_max, 0);
+ }
+
+ /* If only one of the bounds used a MINUS_EXPR, compensate
+ by adding one to the other bound. */
+ if (parm_cst && !arg_cst)
+ parm_max = fold_build2_loc (input_location, PLUS_EXPR,
+ integer_type_node,
+ parm_max,
+ integer_one_node);
+ else if (arg_cst && !parm_cst)
+ arg_max = fold_build2_loc (input_location, PLUS_EXPR,
+ integer_type_node,
+ arg_max,
+ integer_one_node);
+
+ return unify (tparms, targs, parm_max, arg_max,
+ UNIFY_ALLOW_INTEGER, explain_p);
+}
+
+/* Deduce the value of template parameters. TPARMS is the (innermost)
+ set of template parameters to a template. TARGS is the bindings
+ for those template parameters, as determined thus far; TARGS may
+ include template arguments for outer levels of template parameters
+ as well. PARM is a parameter to a template function, or a
+ subcomponent of that parameter; ARG is the corresponding argument.
+ This function attempts to match PARM with ARG in a manner
+ consistent with the existing assignments in TARGS. If more values
+ are deduced, then TARGS is updated.
+
+ Returns 0 if the type deduction succeeds, 1 otherwise. The
+ parameter STRICT is a bitwise or of the following flags:
+
+ UNIFY_ALLOW_NONE:
+ Require an exact match between PARM and ARG.
+ UNIFY_ALLOW_MORE_CV_QUAL:
+ Allow the deduced ARG to be more cv-qualified (by qualification
+ conversion) than ARG.
+ UNIFY_ALLOW_LESS_CV_QUAL:
+ Allow the deduced ARG to be less cv-qualified than ARG.
+ UNIFY_ALLOW_DERIVED:
+ Allow the deduced ARG to be a template base class of ARG,
+ or a pointer to a template base class of the type pointed to by
+ ARG.
+ UNIFY_ALLOW_INTEGER:
+ Allow any integral type to be deduced. See the TEMPLATE_PARM_INDEX
+ case for more information.
+ UNIFY_ALLOW_OUTER_LEVEL:
+ This is the outermost level of a deduction. Used to determine validity
+ of qualification conversions. A valid qualification conversion must
+ have const qualified pointers leading up to the inner type which
+ requires additional CV quals, except at the outer level, where const
+ is not required [conv.qual]. It would be normal to set this flag in
+ addition to setting UNIFY_ALLOW_MORE_CV_QUAL.
+ UNIFY_ALLOW_OUTER_MORE_CV_QUAL:
+ This is the outermost level of a deduction, and PARM can be more CV
+ qualified at this point.
+ UNIFY_ALLOW_OUTER_LESS_CV_QUAL:
+ This is the outermost level of a deduction, and PARM can be less CV
+ qualified at this point. */
+
+static int
+unify (tree tparms, tree targs, tree parm, tree arg, int strict,
+ bool explain_p)
+{
+ int idx;
+ tree targ;
+ tree tparm;
+ int strict_in = strict;
+
+ /* I don't think this will do the right thing with respect to types.
+ But the only case I've seen it in so far has been array bounds, where
+ signedness is the only information lost, and I think that will be
+ okay. */
+ while (TREE_CODE (parm) == NOP_EXPR)
+ parm = TREE_OPERAND (parm, 0);
+
+ if (arg == error_mark_node)
+ return unify_invalid (explain_p);
+ if (arg == unknown_type_node
+ || arg == init_list_type_node)
+ /* We can't deduce anything from this, but we might get all the
+ template args from other function args. */
+ return unify_success (explain_p);
+
+ /* If PARM uses template parameters, then we can't bail out here,
+ even if ARG == PARM, since we won't record unifications for the
+ template parameters. We might need them if we're trying to
+ figure out which of two things is more specialized. */
+ if (arg == parm && !uses_template_parms (parm))
+ return unify_success (explain_p);
+
+ /* Handle init lists early, so the rest of the function can assume
+ we're dealing with a type. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (arg))
+ {
+ tree elt, elttype;
+ unsigned i;
+ tree orig_parm = parm;
+
+ /* Replace T with std::initializer_list<T> for deduction. */
+ if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM
+ && flag_deduce_init_list)
+ parm = listify (parm);
+
+ if (!is_std_init_list (parm)
+ && TREE_CODE (parm) != ARRAY_TYPE)
+ /* We can only deduce from an initializer list argument if the
+ parameter is std::initializer_list or an array; otherwise this
+ is a non-deduced context. */
+ return unify_success (explain_p);
+
+ if (TREE_CODE (parm) == ARRAY_TYPE)
+ elttype = TREE_TYPE (parm);
+ else
+ elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
+ {
+ int elt_strict = strict;
+
+ if (elt == error_mark_node)
+ return unify_invalid (explain_p);
+
+ if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
+ {
+ tree type = TREE_TYPE (elt);
+ /* It should only be possible to get here for a call. */
+ gcc_assert (elt_strict & UNIFY_ALLOW_OUTER_LEVEL);
+ elt_strict |= maybe_adjust_types_for_deduction
+ (DEDUCE_CALL, &elttype, &type, elt);
+ elt = type;
+ }
+
+ RECUR_AND_CHECK_FAILURE (tparms, targs, elttype, elt, elt_strict,
+ explain_p);
+ }
+
+ if (TREE_CODE (parm) == ARRAY_TYPE
+ && deducible_array_bound (TYPE_DOMAIN (parm)))
+ {
+ /* Also deduce from the length of the initializer list. */
+ tree max = size_int (CONSTRUCTOR_NELTS (arg));
+ tree idx = compute_array_index_type (NULL_TREE, max, tf_none);
+ if (idx == error_mark_node)
+ return unify_invalid (explain_p);
+ return unify_array_domain (tparms, targs, TYPE_DOMAIN (parm),
+ idx, explain_p);
+ }
+
+ /* If the std::initializer_list<T> deduction worked, replace the
+ deduced A with std::initializer_list<A>. */
+ if (orig_parm != parm)
+ {
+ idx = TEMPLATE_TYPE_IDX (orig_parm);
+ targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
+ targ = listify (targ);
+ TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = targ;
+ }
+ return unify_success (explain_p);
+ }
+
+ /* Immediately reject some pairs that won't unify because of
+ cv-qualification mismatches. */
+ if (TREE_CODE (arg) == TREE_CODE (parm)
+ && TYPE_P (arg)
+ /* It is the elements of the array which hold the cv quals of an array
+ type, and the elements might be template type parms. We'll check
+ when we recurse. */
+ && TREE_CODE (arg) != ARRAY_TYPE
+ /* We check the cv-qualifiers when unifying with template type
+ parameters below. We want to allow ARG `const T' to unify with
+ PARM `T' for example, when computing which of two templates
+ is more specialized, for example. */
+ && TREE_CODE (arg) != TEMPLATE_TYPE_PARM
+ && !check_cv_quals_for_unify (strict_in, arg, parm))
+ return unify_cv_qual_mismatch (explain_p, parm, arg);
+
+ if (!(strict & UNIFY_ALLOW_OUTER_LEVEL)
+ && TYPE_P (parm) && !CP_TYPE_CONST_P (parm))
+ strict &= ~UNIFY_ALLOW_MORE_CV_QUAL;
+ strict &= ~UNIFY_ALLOW_OUTER_LEVEL;
+ strict &= ~UNIFY_ALLOW_DERIVED;
+ strict &= ~UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
+ strict &= ~UNIFY_ALLOW_OUTER_LESS_CV_QUAL;
+
+ switch (TREE_CODE (parm))
+ {
+ case TYPENAME_TYPE:
+ case SCOPE_REF:
+ case UNBOUND_CLASS_TEMPLATE:
+ /* In a type which contains a nested-name-specifier, template
+ argument values cannot be deduced for template parameters used
+ within the nested-name-specifier. */
+ return unify_success (explain_p);
+
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
+ if (tparm == error_mark_node)
+ return unify_invalid (explain_p);
+
+ if (TEMPLATE_TYPE_LEVEL (parm)
+ != template_decl_level (tparm))
+ /* The PARM is not one we're trying to unify. Just check
+ to see if it matches ARG. */
+ {
+ if (TREE_CODE (arg) == TREE_CODE (parm)
+ && (is_auto (parm) ? is_auto (arg)
+ : same_type_p (parm, arg)))
+ return unify_success (explain_p);
+ else
+ return unify_type_mismatch (explain_p, parm, arg);
+ }
+ idx = TEMPLATE_TYPE_IDX (parm);
+ targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
+ tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx));
+ if (tparm == error_mark_node)
+ return unify_invalid (explain_p);
+
+ /* Check for mixed types and values. */
+ if ((TREE_CODE (parm) == TEMPLATE_TYPE_PARM
+ && TREE_CODE (tparm) != TYPE_DECL)
+ || (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
+ && TREE_CODE (tparm) != TEMPLATE_DECL))
+ gcc_unreachable ();
+
+ if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ {
+ /* ARG must be constructed from a template class or a template
+ template parameter. */
+ if (TREE_CODE (arg) != BOUND_TEMPLATE_TEMPLATE_PARM
+ && !CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P (arg))
+ return unify_template_deduction_failure (explain_p, parm, arg);
+ {
+ tree parmvec = TYPE_TI_ARGS (parm);
+ /* An alias template name is never deduced. */
+ if (TYPE_ALIAS_P (arg))
+ arg = strip_typedefs (arg);
+ tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg));
+ tree full_argvec = add_to_template_args (targs, argvec);
+ tree parm_parms
+ = DECL_INNERMOST_TEMPLATE_PARMS
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (parm));
+ int i, len;
+ int parm_variadic_p = 0;
+
+ /* The resolution to DR150 makes clear that default
+ arguments for an N-argument may not be used to bind T
+ to a template template parameter with fewer than N
+ parameters. It is not safe to permit the binding of
+ default arguments as an extension, as that may change
+ the meaning of a conforming program. Consider:
+
+ struct Dense { static const unsigned int dim = 1; };
+
+ template <template <typename> class View,
+ typename Block>
+ void operator+(float, View<Block> const&);
+
+ template <typename Block,
+ unsigned int Dim = Block::dim>
+ struct Lvalue_proxy { operator float() const; };
+
+ void
+ test_1d (void) {
+ Lvalue_proxy<Dense> p;
+ float b;
+ b + p;
+ }
+
+ Here, if Lvalue_proxy is permitted to bind to View, then
+ the global operator+ will be used; if they are not, the
+ Lvalue_proxy will be converted to float. */
+ if (coerce_template_parms (parm_parms,
+ full_argvec,
+ TYPE_TI_TEMPLATE (parm),
+ (explain_p
+ ? tf_warning_or_error
+ : tf_none),
+ /*require_all_args=*/true,
+ /*use_default_args=*/false)
+ == error_mark_node)
+ return 1;
+
+ /* Deduce arguments T, i from TT<T> or TT<i>.
+ We check each element of PARMVEC and ARGVEC individually
+ rather than the whole TREE_VEC since they can have
+ different number of elements. */
+
+ parmvec = expand_template_argument_pack (parmvec);
+ argvec = expand_template_argument_pack (argvec);
+
+ len = TREE_VEC_LENGTH (parmvec);
+
+ /* Check if the parameters end in a pack, making them
+ variadic. */
+ if (len > 0
+ && PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, len - 1)))
+ parm_variadic_p = 1;
+
+ for (i = 0; i < len - parm_variadic_p; ++i)
+ /* If the template argument list of P contains a pack
+ expansion that is not the last template argument, the
+ entire template argument list is a non-deduced
+ context. */
+ if (PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, i)))
+ return unify_success (explain_p);
+
+ if (TREE_VEC_LENGTH (argvec) < len - parm_variadic_p)
+ return unify_too_few_arguments (explain_p,
+ TREE_VEC_LENGTH (argvec), len);
+
+ for (i = 0; i < len - parm_variadic_p; ++i)
+ {
+ RECUR_AND_CHECK_FAILURE (tparms, targs,
+ TREE_VEC_ELT (parmvec, i),
+ TREE_VEC_ELT (argvec, i),
+ UNIFY_ALLOW_NONE, explain_p);
+ }
+
+ if (parm_variadic_p
+ && unify_pack_expansion (tparms, targs,
+ parmvec, argvec,
+ DEDUCE_EXACT,
+ /*subr=*/true, explain_p))
+ return 1;
+ }
+ arg = TYPE_TI_TEMPLATE (arg);
+
+ /* Fall through to deduce template name. */
+ }
+
+ if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ {
+ /* Deduce template name TT from TT, TT<>, TT<T> and TT<i>. */
+
+ /* Simple cases: Value already set, does match or doesn't. */
+ if (targ != NULL_TREE && template_args_equal (targ, arg))
+ return unify_success (explain_p);
+ else if (targ)
+ return unify_inconsistency (explain_p, parm, targ, arg);
+ }
+ else
+ {
+ /* If PARM is `const T' and ARG is only `int', we don't have
+ a match unless we are allowing additional qualification.
+ If ARG is `const int' and PARM is just `T' that's OK;
+ that binds `const int' to `T'. */
+ if (!check_cv_quals_for_unify (strict_in | UNIFY_ALLOW_LESS_CV_QUAL,
+ arg, parm))
+ return unify_cv_qual_mismatch (explain_p, parm, arg);
+
+ /* Consider the case where ARG is `const volatile int' and
+ PARM is `const T'. Then, T should be `volatile int'. */
+ arg = cp_build_qualified_type_real
+ (arg, cp_type_quals (arg) & ~cp_type_quals (parm), tf_none);
+ if (arg == error_mark_node)
+ return unify_invalid (explain_p);
+
+ /* Simple cases: Value already set, does match or doesn't. */
+ if (targ != NULL_TREE && same_type_p (targ, arg))
+ return unify_success (explain_p);
+ else if (targ)
+ return unify_inconsistency (explain_p, parm, targ, arg);
+
+ /* Make sure that ARG is not a variable-sized array. (Note
+ that were talking about variable-sized arrays (like
+ `int[n]'), rather than arrays of unknown size (like
+ `int[]').) We'll get very confused by such a type since
+ the bound of the array is not constant, and therefore
+ not mangleable. Besides, such types are not allowed in
+ ISO C++, so we can do as we please here. We do allow
+ them for 'auto' deduction, since that isn't ABI-exposed. */
+ if (!is_auto (parm) && variably_modified_type_p (arg, NULL_TREE))
+ return unify_vla_arg (explain_p, arg);
+
+ /* Strip typedefs as in convert_template_argument. */
+ arg = canonicalize_type_argument (arg, tf_none);
+ }
+
+ /* If ARG is a parameter pack or an expansion, we cannot unify
+ against it unless PARM is also a parameter pack. */
+ if ((template_parameter_pack_p (arg) || PACK_EXPANSION_P (arg))
+ && !template_parameter_pack_p (parm))
+ return unify_parameter_pack_mismatch (explain_p, parm, arg);
+
+ /* If the argument deduction results is a METHOD_TYPE,
+ then there is a problem.
+ METHOD_TYPE doesn't map to any real C++ type the result of
+ the deduction can not be of that type. */
+ if (TREE_CODE (arg) == METHOD_TYPE)
+ return unify_method_type_error (explain_p, arg);
+
+ TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
+ return unify_success (explain_p);
+
+ case TEMPLATE_PARM_INDEX:
+ tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
+ if (tparm == error_mark_node)
+ return unify_invalid (explain_p);
+
+ if (TEMPLATE_PARM_LEVEL (parm)
+ != template_decl_level (tparm))
+ {
+ /* The PARM is not one we're trying to unify. Just check
+ to see if it matches ARG. */
+ int result = !(TREE_CODE (arg) == TREE_CODE (parm)
+ && cp_tree_equal (parm, arg));
+ if (result)
+ unify_expression_unequal (explain_p, parm, arg);
+ return result;
+ }
+
+ idx = TEMPLATE_PARM_IDX (parm);
+ targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
+
+ if (targ)
+ {
+ int x = !cp_tree_equal (targ, arg);
+ if (x)
+ unify_inconsistency (explain_p, parm, targ, arg);
+ return x;
+ }
+
+ /* [temp.deduct.type] If, in the declaration of a function template
+ with a non-type template-parameter, the non-type
+ template-parameter is used in an expression in the function
+ parameter-list and, if the corresponding template-argument is
+ deduced, the template-argument type shall match the type of the
+ template-parameter exactly, except that a template-argument
+ deduced from an array bound may be of any integral type.
+ The non-type parameter might use already deduced type parameters. */
+ tparm = tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE);
+ if (!TREE_TYPE (arg))
+ /* Template-parameter dependent expression. Just accept it for now.
+ It will later be processed in convert_template_argument. */
+ ;
+ else if (same_type_p (TREE_TYPE (arg), tparm))
+ /* OK */;
+ else if ((strict & UNIFY_ALLOW_INTEGER)
+ && CP_INTEGRAL_TYPE_P (tparm))
+ /* Convert the ARG to the type of PARM; the deduced non-type
+ template argument must exactly match the types of the
+ corresponding parameter. */
+ arg = fold (build_nop (tparm, arg));
+ else if (uses_template_parms (tparm))
+ /* We haven't deduced the type of this parameter yet. Try again
+ later. */
+ return unify_success (explain_p);
+ else
+ return unify_type_mismatch (explain_p, tparm, TREE_TYPE (arg));
+
+ /* If ARG is a parameter pack or an expansion, we cannot unify
+ against it unless PARM is also a parameter pack. */
+ if ((template_parameter_pack_p (arg) || PACK_EXPANSION_P (arg))
+ && !TEMPLATE_PARM_PARAMETER_PACK (parm))
+ return unify_parameter_pack_mismatch (explain_p, parm, arg);
+
+ arg = strip_typedefs_expr (arg);
+ TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
+ return unify_success (explain_p);
+
+ case PTRMEM_CST:
+ {
+ /* A pointer-to-member constant can be unified only with
+ another constant. */
+ if (TREE_CODE (arg) != PTRMEM_CST)
+ return unify_ptrmem_cst_mismatch (explain_p, parm, arg);
+
+ /* Just unify the class member. It would be useless (and possibly
+ wrong, depending on the strict flags) to unify also
+ PTRMEM_CST_CLASS, because we want to be sure that both parm and
+ arg refer to the same variable, even if through different
+ classes. For instance:
+
+ struct A { int x; };
+ struct B : A { };
+
+ Unification of &A::x and &B::x must succeed. */
+ return unify (tparms, targs, PTRMEM_CST_MEMBER (parm),
+ PTRMEM_CST_MEMBER (arg), strict, explain_p);
+ }
+
+ case POINTER_TYPE:
+ {
+ if (!TYPE_PTR_P (arg))
+ return unify_type_mismatch (explain_p, parm, arg);
+
+ /* [temp.deduct.call]
+
+ A can be another pointer or pointer to member type that can
+ be converted to the deduced A via a qualification
+ conversion (_conv.qual_).
+
+ We pass down STRICT here rather than UNIFY_ALLOW_NONE.
+ This will allow for additional cv-qualification of the
+ pointed-to types if appropriate. */
+
+ if (TREE_CODE (TREE_TYPE (arg)) == RECORD_TYPE)
+ /* The derived-to-base conversion only persists through one
+ level of pointers. */
+ strict |= (strict_in & UNIFY_ALLOW_DERIVED);
+
+ return unify (tparms, targs, TREE_TYPE (parm),
+ TREE_TYPE (arg), strict, explain_p);
+ }
+
+ case REFERENCE_TYPE:
+ if (TREE_CODE (arg) != REFERENCE_TYPE)
+ return unify_type_mismatch (explain_p, parm, arg);
+ return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
+ strict & UNIFY_ALLOW_MORE_CV_QUAL, explain_p);
+
+ case ARRAY_TYPE:
+ if (TREE_CODE (arg) != ARRAY_TYPE)
+ return unify_type_mismatch (explain_p, parm, arg);
+ if ((TYPE_DOMAIN (parm) == NULL_TREE)
+ != (TYPE_DOMAIN (arg) == NULL_TREE))
+ return unify_type_mismatch (explain_p, parm, arg);
+ RECUR_AND_CHECK_FAILURE (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
+ strict & UNIFY_ALLOW_MORE_CV_QUAL, explain_p);
+ if (TYPE_DOMAIN (parm) != NULL_TREE)
+ return unify_array_domain (tparms, targs, TYPE_DOMAIN (parm),
+ TYPE_DOMAIN (arg), explain_p);
+ return unify_success (explain_p);
+
+ case REAL_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ case INTEGER_TYPE:
+ case BOOLEAN_TYPE:
+ case ENUMERAL_TYPE:
+ case VOID_TYPE:
+ case NULLPTR_TYPE:
+ if (TREE_CODE (arg) != TREE_CODE (parm))
+ return unify_type_mismatch (explain_p, parm, arg);
+
+ /* We have already checked cv-qualification at the top of the
+ function. */
+ if (!same_type_ignoring_top_level_qualifiers_p (arg, parm))
+ return unify_type_mismatch (explain_p, parm, arg);
+
+ /* As far as unification is concerned, this wins. Later checks
+ will invalidate it if necessary. */
+ return unify_success (explain_p);
+
+ /* Types INTEGER_CST and MINUS_EXPR can come from array bounds. */
+ /* Type INTEGER_CST can come from ordinary constant template args. */
+ case INTEGER_CST:
+ while (TREE_CODE (arg) == NOP_EXPR)
+ arg = TREE_OPERAND (arg, 0);
+
+ if (TREE_CODE (arg) != INTEGER_CST)
+ return unify_template_argument_mismatch (explain_p, parm, arg);
+ return (tree_int_cst_equal (parm, arg)
+ ? unify_success (explain_p)
+ : unify_template_argument_mismatch (explain_p, parm, arg));
+
+ case TREE_VEC:
+ {
+ int i, len, argslen;
+ int parm_variadic_p = 0;
+
+ if (TREE_CODE (arg) != TREE_VEC)
+ return unify_template_argument_mismatch (explain_p, parm, arg);
+
+ len = TREE_VEC_LENGTH (parm);
+ argslen = TREE_VEC_LENGTH (arg);
+
+ /* Check for pack expansions in the parameters. */
+ for (i = 0; i < len; ++i)
+ {
+ if (PACK_EXPANSION_P (TREE_VEC_ELT (parm, i)))
+ {
+ if (i == len - 1)
+ /* We can unify against something with a trailing
+ parameter pack. */
+ parm_variadic_p = 1;
+ else
+ /* [temp.deduct.type]/9: If the template argument list of
+ P contains a pack expansion that is not the last
+ template argument, the entire template argument list
+ is a non-deduced context. */
+ return unify_success (explain_p);
+ }
+ }
+
+ /* If we don't have enough arguments to satisfy the parameters
+ (not counting the pack expression at the end), or we have
+ too many arguments for a parameter list that doesn't end in
+ a pack expression, we can't unify. */
+ if (parm_variadic_p
+ ? argslen < len - parm_variadic_p
+ : argslen != len)
+ return unify_arity (explain_p, TREE_VEC_LENGTH (arg), len);
+
+ /* Unify all of the parameters that precede the (optional)
+ pack expression. */
+ for (i = 0; i < len - parm_variadic_p; ++i)
+ {
+ RECUR_AND_CHECK_FAILURE (tparms, targs,
+ TREE_VEC_ELT (parm, i),
+ TREE_VEC_ELT (arg, i),
+ UNIFY_ALLOW_NONE, explain_p);
+ }
+ if (parm_variadic_p)
+ return unify_pack_expansion (tparms, targs, parm, arg,
+ DEDUCE_EXACT,
+ /*subr=*/true, explain_p);
+ return unify_success (explain_p);
+ }
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ if (TREE_CODE (arg) != TREE_CODE (parm))
+ return unify_type_mismatch (explain_p, parm, arg);
+
+ if (TYPE_PTRMEMFUNC_P (parm))
+ {
+ if (!TYPE_PTRMEMFUNC_P (arg))
+ return unify_type_mismatch (explain_p, parm, arg);
+
+ return unify (tparms, targs,
+ TYPE_PTRMEMFUNC_FN_TYPE (parm),
+ TYPE_PTRMEMFUNC_FN_TYPE (arg),
+ strict, explain_p);
+ }
+
+ if (CLASSTYPE_TEMPLATE_INFO (parm))
+ {
+ tree t = NULL_TREE;
+
+ if (strict_in & UNIFY_ALLOW_DERIVED)
+ {
+ /* First, we try to unify the PARM and ARG directly. */
+ t = try_class_unification (tparms, targs,
+ parm, arg, explain_p);
+
+ if (!t)
+ {
+ /* Fallback to the special case allowed in
+ [temp.deduct.call]:
+
+ If P is a class, and P has the form
+ template-id, then A can be a derived class of
+ the deduced A. Likewise, if P is a pointer to
+ a class of the form template-id, A can be a
+ pointer to a derived class pointed to by the
+ deduced A. */
+ enum template_base_result r;
+ r = get_template_base (tparms, targs, parm, arg,
+ explain_p, &t);
+
+ if (!t)
+ return unify_no_common_base (explain_p, r, parm, arg);
+ }
+ }
+ else if (CLASSTYPE_TEMPLATE_INFO (arg)
+ && (CLASSTYPE_TI_TEMPLATE (parm)
+ == CLASSTYPE_TI_TEMPLATE (arg)))
+ /* Perhaps PARM is something like S<U> and ARG is S<int>.
+ Then, we should unify `int' and `U'. */
+ t = arg;
+ else
+ /* There's no chance of unification succeeding. */
+ return unify_type_mismatch (explain_p, parm, arg);
+
+ return unify (tparms, targs, CLASSTYPE_TI_ARGS (parm),
+ CLASSTYPE_TI_ARGS (t), UNIFY_ALLOW_NONE, explain_p);
+ }
+ else if (!same_type_ignoring_top_level_qualifiers_p (parm, arg))
+ return unify_type_mismatch (explain_p, parm, arg);
+ return unify_success (explain_p);
+
+ case METHOD_TYPE:
+ case FUNCTION_TYPE:
+ {
+ unsigned int nargs;
+ tree *args;
+ tree a;
+ unsigned int i;
+
+ if (TREE_CODE (arg) != TREE_CODE (parm))
+ return unify_type_mismatch (explain_p, parm, arg);
+
+ /* CV qualifications for methods can never be deduced, they must
+ match exactly. We need to check them explicitly here,
+ because type_unification_real treats them as any other
+ cv-qualified parameter. */
+ if (TREE_CODE (parm) == METHOD_TYPE
+ && (!check_cv_quals_for_unify
+ (UNIFY_ALLOW_NONE,
+ class_of_this_parm (arg),
+ class_of_this_parm (parm))))
+ return unify_cv_qual_mismatch (explain_p, parm, arg);
+
+ RECUR_AND_CHECK_FAILURE (tparms, targs, TREE_TYPE (parm),
+ TREE_TYPE (arg), UNIFY_ALLOW_NONE, explain_p);
+
+ nargs = list_length (TYPE_ARG_TYPES (arg));
+ args = XALLOCAVEC (tree, nargs);
+ for (a = TYPE_ARG_TYPES (arg), i = 0;
+ a != NULL_TREE && a != void_list_node;
+ a = TREE_CHAIN (a), ++i)
+ args[i] = TREE_VALUE (a);
+ nargs = i;
+
+ return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
+ args, nargs, 1, DEDUCE_EXACT,
+ LOOKUP_NORMAL, NULL, explain_p);
+ }
+
+ case OFFSET_TYPE:
+ /* Unify a pointer to member with a pointer to member function, which
+ deduces the type of the member as a function type. */
+ if (TYPE_PTRMEMFUNC_P (arg))
+ {
+ /* Check top-level cv qualifiers */
+ if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm))
+ return unify_cv_qual_mismatch (explain_p, parm, arg);
+
+ RECUR_AND_CHECK_FAILURE (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
+ TYPE_PTRMEMFUNC_OBJECT_TYPE (arg),
+ UNIFY_ALLOW_NONE, explain_p);
+
+ /* Determine the type of the function we are unifying against. */
+ tree fntype = static_fn_type (arg);
+
+ return unify (tparms, targs, TREE_TYPE (parm), fntype, strict, explain_p);
+ }
+
+ if (TREE_CODE (arg) != OFFSET_TYPE)
+ return unify_type_mismatch (explain_p, parm, arg);
+ RECUR_AND_CHECK_FAILURE (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
+ TYPE_OFFSET_BASETYPE (arg),
+ UNIFY_ALLOW_NONE, explain_p);
+ return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
+ strict, explain_p);
+
+ case CONST_DECL:
+ if (DECL_TEMPLATE_PARM_P (parm))
+ return unify (tparms, targs, DECL_INITIAL (parm), arg, strict, explain_p);
+ if (arg != integral_constant_value (parm))
+ return unify_template_argument_mismatch (explain_p, parm, arg);
+ return unify_success (explain_p);
+
+ case FIELD_DECL:
+ case TEMPLATE_DECL:
+ /* Matched cases are handled by the ARG == PARM test above. */
+ return unify_template_argument_mismatch (explain_p, parm, arg);
+
+ case VAR_DECL:
+ /* A non-type template parameter that is a variable should be a
+ an integral constant, in which case, it whould have been
+ folded into its (constant) value. So we should not be getting
+ a variable here. */
+ gcc_unreachable ();
+
+ case TYPE_ARGUMENT_PACK:
+ case NONTYPE_ARGUMENT_PACK:
+ return unify (tparms, targs, ARGUMENT_PACK_ARGS (parm),
+ ARGUMENT_PACK_ARGS (arg), strict, explain_p);
+
+ case TYPEOF_TYPE:
+ case DECLTYPE_TYPE:
+ case UNDERLYING_TYPE:
+ /* Cannot deduce anything from TYPEOF_TYPE, DECLTYPE_TYPE,
+ or UNDERLYING_TYPE nodes. */
+ return unify_success (explain_p);
+
+ case ERROR_MARK:
+ /* Unification fails if we hit an error node. */
+ return unify_invalid (explain_p);
+
+ case INDIRECT_REF:
+ if (REFERENCE_REF_P (parm))
+ return unify (tparms, targs, TREE_OPERAND (parm, 0), arg,
+ strict, explain_p);
+ /* FALLTHRU */
+
+ default:
+ /* An unresolved overload is a nondeduced context. */
+ if (is_overloaded_fn (parm) || type_unknown_p (parm))
+ return unify_success (explain_p);
+ gcc_assert (EXPR_P (parm));
+
+ /* We must be looking at an expression. This can happen with
+ something like:
+
+ template <int I>
+ void foo(S<I>, S<I + 2>);
+
+ This is a "nondeduced context":
+
+ [deduct.type]
+
+ The nondeduced contexts are:
+
+ --A type that is a template-id in which one or more of
+ the template-arguments is an expression that references
+ a template-parameter.
+
+ In these cases, we assume deduction succeeded, but don't
+ actually infer any unifications. */
+
+ if (!uses_template_parms (parm)
+ && !template_args_equal (parm, arg))
+ return unify_expression_unequal (explain_p, parm, arg);
+ else
+ return unify_success (explain_p);
+ }
+}
+#undef RECUR_AND_CHECK_FAILURE
+
+/* Note that DECL can be defined in this translation unit, if
+ required. */
+
+static void
+mark_definable (tree decl)
+{
+ tree clone;
+ DECL_NOT_REALLY_EXTERN (decl) = 1;
+ FOR_EACH_CLONE (clone, decl)
+ DECL_NOT_REALLY_EXTERN (clone) = 1;
+}
+
+/* Called if RESULT is explicitly instantiated, or is a member of an
+ explicitly instantiated class. */
+
+void
+mark_decl_instantiated (tree result, int extern_p)
+{
+ SET_DECL_EXPLICIT_INSTANTIATION (result);
+
+ /* If this entity has already been written out, it's too late to
+ make any modifications. */
+ if (TREE_ASM_WRITTEN (result))
+ return;
+
+ /* For anonymous namespace we don't need to do anything. */
+ if (decl_anon_ns_mem_p (result))
+ {
+ gcc_assert (!TREE_PUBLIC (result));
+ return;
+ }
+
+ if (TREE_CODE (result) != FUNCTION_DECL)
+ /* The TREE_PUBLIC flag for function declarations will have been
+ set correctly by tsubst. */
+ TREE_PUBLIC (result) = 1;
+
+ /* This might have been set by an earlier implicit instantiation. */
+ DECL_COMDAT (result) = 0;
+
+ if (extern_p)
+ DECL_NOT_REALLY_EXTERN (result) = 0;
+ else
+ {
+ mark_definable (result);
+ mark_needed (result);
+ /* Always make artificials weak. */
+ if (DECL_ARTIFICIAL (result) && flag_weak)
+ comdat_linkage (result);
+ /* For WIN32 we also want to put explicit instantiations in
+ linkonce sections. */
+ else if (TREE_PUBLIC (result))
+ maybe_make_one_only (result);
+ }
+
+ /* If EXTERN_P, then this function will not be emitted -- unless
+ followed by an explicit instantiation, at which point its linkage
+ will be adjusted. If !EXTERN_P, then this function will be
+ emitted here. In neither circumstance do we want
+ import_export_decl to adjust the linkage. */
+ DECL_INTERFACE_KNOWN (result) = 1;
+}
+
+/* Subroutine of more_specialized_fn: check whether TARGS is missing any
+ important template arguments. If any are missing, we check whether
+ they're important by using error_mark_node for substituting into any
+ args that were used for partial ordering (the ones between ARGS and END)
+ and seeing if it bubbles up. */
+
+static bool
+check_undeduced_parms (tree targs, tree args, tree end)
+{
+ bool found = false;
+ int i;
+ for (i = TREE_VEC_LENGTH (targs) - 1; i >= 0; --i)
+ if (TREE_VEC_ELT (targs, i) == NULL_TREE)
+ {
+ found = true;
+ TREE_VEC_ELT (targs, i) = error_mark_node;
+ }
+ if (found)
+ {
+ tree substed = tsubst_arg_types (args, targs, end, tf_none, NULL_TREE);
+ if (substed == error_mark_node)
+ return true;
+ }
+ return false;
+}
+
+/* Given two function templates PAT1 and PAT2, return:
+
+ 1 if PAT1 is more specialized than PAT2 as described in [temp.func.order].
+ -1 if PAT2 is more specialized than PAT1.
+ 0 if neither is more specialized.
+
+ LEN indicates the number of parameters we should consider
+ (defaulted parameters should not be considered).
+
+ The 1998 std underspecified function template partial ordering, and
+ DR214 addresses the issue. We take pairs of arguments, one from
+ each of the templates, and deduce them against each other. One of
+ the templates will be more specialized if all the *other*
+ template's arguments deduce against its arguments and at least one
+ of its arguments *does* *not* deduce against the other template's
+ corresponding argument. Deduction is done as for class templates.
+ The arguments used in deduction have reference and top level cv
+ qualifiers removed. Iff both arguments were originally reference
+ types *and* deduction succeeds in both directions, an lvalue reference
+ wins against an rvalue reference and otherwise the template
+ with the more cv-qualified argument wins for that pairing (if
+ neither is more cv-qualified, they both are equal). Unlike regular
+ deduction, after all the arguments have been deduced in this way,
+ we do *not* verify the deduced template argument values can be
+ substituted into non-deduced contexts.
+
+ The logic can be a bit confusing here, because we look at deduce1 and
+ targs1 to see if pat2 is at least as specialized, and vice versa; if we
+ can find template arguments for pat1 to make arg1 look like arg2, that
+ means that arg2 is at least as specialized as arg1. */
+
+int
+more_specialized_fn (tree pat1, tree pat2, int len)
+{
+ tree decl1 = DECL_TEMPLATE_RESULT (pat1);
+ tree decl2 = DECL_TEMPLATE_RESULT (pat2);
+ tree targs1 = make_tree_vec (DECL_NTPARMS (pat1));
+ tree targs2 = make_tree_vec (DECL_NTPARMS (pat2));
+ tree tparms1 = DECL_INNERMOST_TEMPLATE_PARMS (pat1);
+ tree tparms2 = DECL_INNERMOST_TEMPLATE_PARMS (pat2);
+ tree args1 = TYPE_ARG_TYPES (TREE_TYPE (decl1));
+ tree args2 = TYPE_ARG_TYPES (TREE_TYPE (decl2));
+ tree origs1, origs2;
+ bool lose1 = false;
+ bool lose2 = false;
+
+ /* Remove the this parameter from non-static member functions. If
+ one is a non-static member function and the other is not a static
+ member function, remove the first parameter from that function
+ also. This situation occurs for operator functions where we
+ locate both a member function (with this pointer) and non-member
+ operator (with explicit first operand). */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl1))
+ {
+ len--; /* LEN is the number of significant arguments for DECL1 */
+ args1 = TREE_CHAIN (args1);
+ if (!DECL_STATIC_FUNCTION_P (decl2))
+ args2 = TREE_CHAIN (args2);
+ }
+ else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2))
+ {
+ args2 = TREE_CHAIN (args2);
+ if (!DECL_STATIC_FUNCTION_P (decl1))
+ {
+ len--;
+ args1 = TREE_CHAIN (args1);
+ }
+ }
+
+ /* If only one is a conversion operator, they are unordered. */
+ if (DECL_CONV_FN_P (decl1) != DECL_CONV_FN_P (decl2))
+ return 0;
+
+ /* Consider the return type for a conversion function */
+ if (DECL_CONV_FN_P (decl1))
+ {
+ args1 = tree_cons (NULL_TREE, TREE_TYPE (TREE_TYPE (decl1)), args1);
+ args2 = tree_cons (NULL_TREE, TREE_TYPE (TREE_TYPE (decl2)), args2);
+ len++;
+ }
+
+ processing_template_decl++;
+
+ origs1 = args1;
+ origs2 = args2;
+
+ while (len--
+ /* Stop when an ellipsis is seen. */
+ && args1 != NULL_TREE && args2 != NULL_TREE)
+ {
+ tree arg1 = TREE_VALUE (args1);
+ tree arg2 = TREE_VALUE (args2);
+ int deduce1, deduce2;
+ int quals1 = -1;
+ int quals2 = -1;
+ int ref1 = 0;
+ int ref2 = 0;
+
+ if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION
+ && TREE_CODE (arg2) == TYPE_PACK_EXPANSION)
+ {
+ /* When both arguments are pack expansions, we need only
+ unify the patterns themselves. */
+ arg1 = PACK_EXPANSION_PATTERN (arg1);
+ arg2 = PACK_EXPANSION_PATTERN (arg2);
+
+ /* This is the last comparison we need to do. */
+ len = 0;
+ }
+
+ if (TREE_CODE (arg1) == REFERENCE_TYPE)
+ {
+ ref1 = TYPE_REF_IS_RVALUE (arg1) + 1;
+ arg1 = TREE_TYPE (arg1);
+ quals1 = cp_type_quals (arg1);
+ }
+
+ if (TREE_CODE (arg2) == REFERENCE_TYPE)
+ {
+ ref2 = TYPE_REF_IS_RVALUE (arg2) + 1;
+ arg2 = TREE_TYPE (arg2);
+ quals2 = cp_type_quals (arg2);
+ }
+
+ arg1 = TYPE_MAIN_VARIANT (arg1);
+ arg2 = TYPE_MAIN_VARIANT (arg2);
+
+ if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION)
+ {
+ int i, len2 = list_length (args2);
+ tree parmvec = make_tree_vec (1);
+ tree argvec = make_tree_vec (len2);
+ tree ta = args2;
+
+ /* Setup the parameter vector, which contains only ARG1. */
+ TREE_VEC_ELT (parmvec, 0) = arg1;
+
+ /* Setup the argument vector, which contains the remaining
+ arguments. */
+ for (i = 0; i < len2; i++, ta = TREE_CHAIN (ta))
+ TREE_VEC_ELT (argvec, i) = TREE_VALUE (ta);
+
+ deduce1 = (unify_pack_expansion (tparms1, targs1, parmvec,
+ argvec, DEDUCE_EXACT,
+ /*subr=*/true, /*explain_p=*/false)
+ == 0);
+
+ /* We cannot deduce in the other direction, because ARG1 is
+ a pack expansion but ARG2 is not. */
+ deduce2 = 0;
+ }
+ else if (TREE_CODE (arg2) == TYPE_PACK_EXPANSION)
+ {
+ int i, len1 = list_length (args1);
+ tree parmvec = make_tree_vec (1);
+ tree argvec = make_tree_vec (len1);
+ tree ta = args1;
+
+ /* Setup the parameter vector, which contains only ARG1. */
+ TREE_VEC_ELT (parmvec, 0) = arg2;
+
+ /* Setup the argument vector, which contains the remaining
+ arguments. */
+ for (i = 0; i < len1; i++, ta = TREE_CHAIN (ta))
+ TREE_VEC_ELT (argvec, i) = TREE_VALUE (ta);
+
+ deduce2 = (unify_pack_expansion (tparms2, targs2, parmvec,
+ argvec, DEDUCE_EXACT,
+ /*subr=*/true, /*explain_p=*/false)
+ == 0);
+
+ /* We cannot deduce in the other direction, because ARG2 is
+ a pack expansion but ARG1 is not.*/
+ deduce1 = 0;
+ }
+
+ else
+ {
+ /* The normal case, where neither argument is a pack
+ expansion. */
+ deduce1 = (unify (tparms1, targs1, arg1, arg2,
+ UNIFY_ALLOW_NONE, /*explain_p=*/false)
+ == 0);
+ deduce2 = (unify (tparms2, targs2, arg2, arg1,
+ UNIFY_ALLOW_NONE, /*explain_p=*/false)
+ == 0);
+ }
+
+ /* If we couldn't deduce arguments for tparms1 to make arg1 match
+ arg2, then arg2 is not as specialized as arg1. */
+ if (!deduce1)
+ lose2 = true;
+ if (!deduce2)
+ lose1 = true;
+
+ /* "If, for a given type, deduction succeeds in both directions
+ (i.e., the types are identical after the transformations above)
+ and both P and A were reference types (before being replaced with
+ the type referred to above):
+ - if the type from the argument template was an lvalue reference and
+ the type from the parameter template was not, the argument type is
+ considered to be more specialized than the other; otherwise,
+ - if the type from the argument template is more cv-qualified
+ than the type from the parameter template (as described above),
+ the argument type is considered to be more specialized than the other;
+ otherwise,
+ - neither type is more specialized than the other." */
+
+ if (deduce1 && deduce2)
+ {
+ if (ref1 && ref2 && ref1 != ref2)
+ {
+ if (ref1 > ref2)
+ lose1 = true;
+ else
+ lose2 = true;
+ }
+ else if (quals1 != quals2 && quals1 >= 0 && quals2 >= 0)
+ {
+ if ((quals1 & quals2) == quals2)
+ lose2 = true;
+ if ((quals1 & quals2) == quals1)
+ lose1 = true;
+ }
+ }
+
+ if (lose1 && lose2)
+ /* We've failed to deduce something in either direction.
+ These must be unordered. */
+ break;
+
+ if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION
+ || TREE_CODE (arg2) == TYPE_PACK_EXPANSION)
+ /* We have already processed all of the arguments in our
+ handing of the pack expansion type. */
+ len = 0;
+
+ args1 = TREE_CHAIN (args1);
+ args2 = TREE_CHAIN (args2);
+ }
+
+ /* "In most cases, all template parameters must have values in order for
+ deduction to succeed, but for partial ordering purposes a template
+ parameter may remain without a value provided it is not used in the
+ types being used for partial ordering."
+
+ Thus, if we are missing any of the targs1 we need to substitute into
+ origs1, then pat2 is not as specialized as pat1. This can happen when
+ there is a nondeduced context. */
+ if (!lose2 && check_undeduced_parms (targs1, origs1, args1))
+ lose2 = true;
+ if (!lose1 && check_undeduced_parms (targs2, origs2, args2))
+ lose1 = true;
+
+ processing_template_decl--;
+
+ /* All things being equal, if the next argument is a pack expansion
+ for one function but not for the other, prefer the
+ non-variadic function. FIXME this is bogus; see c++/41958. */
+ if (lose1 == lose2
+ && args1 && TREE_VALUE (args1)
+ && args2 && TREE_VALUE (args2))
+ {
+ lose1 = TREE_CODE (TREE_VALUE (args1)) == TYPE_PACK_EXPANSION;
+ lose2 = TREE_CODE (TREE_VALUE (args2)) == TYPE_PACK_EXPANSION;
+ }
+
+ if (lose1 == lose2)
+ return 0;
+ else if (!lose1)
+ return 1;
+ else
+ return -1;
+}
+
+/* Determine which of two partial specializations of TMPL is more
+ specialized.
+
+ PAT1 is a TREE_LIST whose TREE_TYPE is the _TYPE node corresponding
+ to the first partial specialization. The TREE_VALUE is the
+ innermost set of template parameters for the partial
+ specialization. PAT2 is similar, but for the second template.
+
+ Return 1 if the first partial specialization is more specialized;
+ -1 if the second is more specialized; 0 if neither is more
+ specialized.
+
+ See [temp.class.order] for information about determining which of
+ two templates is more specialized. */
+
+static int
+more_specialized_class (tree tmpl, tree pat1, tree pat2)
+{
+ tree targs;
+ tree tmpl1, tmpl2;
+ int winner = 0;
+ bool any_deductions = false;
+
+ tmpl1 = TREE_TYPE (pat1);
+ tmpl2 = TREE_TYPE (pat2);
+
+ /* Just like what happens for functions, if we are ordering between
+ different class template specializations, we may encounter dependent
+ types in the arguments, and we need our dependency check functions
+ to behave correctly. */
+ ++processing_template_decl;
+ targs = get_class_bindings (tmpl, TREE_VALUE (pat1),
+ CLASSTYPE_TI_ARGS (tmpl1),
+ CLASSTYPE_TI_ARGS (tmpl2));
+ if (targs)
+ {
+ --winner;
+ any_deductions = true;
+ }
+
+ targs = get_class_bindings (tmpl, TREE_VALUE (pat2),
+ CLASSTYPE_TI_ARGS (tmpl2),
+ CLASSTYPE_TI_ARGS (tmpl1));
+ if (targs)
+ {
+ ++winner;
+ any_deductions = true;
+ }
+ --processing_template_decl;
+
+ /* In the case of a tie where at least one of the class templates
+ has a parameter pack at the end, the template with the most
+ non-packed parameters wins. */
+ if (winner == 0
+ && any_deductions
+ && (template_args_variadic_p (TREE_PURPOSE (pat1))
+ || template_args_variadic_p (TREE_PURPOSE (pat2))))
+ {
+ tree args1 = INNERMOST_TEMPLATE_ARGS (TREE_PURPOSE (pat1));
+ tree args2 = INNERMOST_TEMPLATE_ARGS (TREE_PURPOSE (pat2));
+ int len1 = TREE_VEC_LENGTH (args1);
+ int len2 = TREE_VEC_LENGTH (args2);
+
+ /* We don't count the pack expansion at the end. */
+ if (template_args_variadic_p (TREE_PURPOSE (pat1)))
+ --len1;
+ if (template_args_variadic_p (TREE_PURPOSE (pat2)))
+ --len2;
+
+ if (len1 > len2)
+ return 1;
+ else if (len1 < len2)
+ return -1;
+ }
+
+ return winner;
+}
+
+/* Return the template arguments that will produce the function signature
+ DECL from the function template FN, with the explicit template
+ arguments EXPLICIT_ARGS. If CHECK_RETTYPE is true, the return type must
+ also match. Return NULL_TREE if no satisfactory arguments could be
+ found. */
+
+static tree
+get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
+{
+ int ntparms = DECL_NTPARMS (fn);
+ tree targs = make_tree_vec (ntparms);
+ tree decl_type = TREE_TYPE (decl);
+ tree decl_arg_types;
+ tree *args;
+ unsigned int nargs, ix;
+ tree arg;
+
+ gcc_assert (decl != DECL_TEMPLATE_RESULT (fn));
+
+ /* Never do unification on the 'this' parameter. */
+ decl_arg_types = skip_artificial_parms_for (decl,
+ TYPE_ARG_TYPES (decl_type));
+
+ nargs = list_length (decl_arg_types);
+ args = XALLOCAVEC (tree, nargs);
+ for (arg = decl_arg_types, ix = 0;
+ arg != NULL_TREE && arg != void_list_node;
+ arg = TREE_CHAIN (arg), ++ix)
+ args[ix] = TREE_VALUE (arg);
+
+ if (fn_type_unification (fn, explicit_args, targs,
+ args, ix,
+ (check_rettype || DECL_CONV_FN_P (fn)
+ ? TREE_TYPE (decl_type) : NULL_TREE),
+ DEDUCE_EXACT, LOOKUP_NORMAL, /*explain_p=*/false,
+ /*decltype*/false)
+ == error_mark_node)
+ return NULL_TREE;
+
+ return targs;
+}
+
+/* Return the innermost template arguments that, when applied to a partial
+ specialization of TMPL whose innermost template parameters are
+ TPARMS, and whose specialization arguments are SPEC_ARGS, yield the
+ ARGS.
+
+ For example, suppose we have:
+
+ template <class T, class U> struct S {};
+ template <class T> struct S<T*, int> {};
+
+ Then, suppose we want to get `S<double*, int>'. The TPARMS will be
+ {T}, the SPEC_ARGS will be {T*, int} and the ARGS will be {double*,
+ int}. The resulting vector will be {double}, indicating that `T'
+ is bound to `double'. */
+
+static tree
+get_class_bindings (tree tmpl, tree tparms, tree spec_args, tree args)
+{
+ int i, ntparms = TREE_VEC_LENGTH (tparms);
+ tree deduced_args;
+ tree innermost_deduced_args;
+
+ innermost_deduced_args = make_tree_vec (ntparms);
+ if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
+ {
+ deduced_args = copy_node (args);
+ SET_TMPL_ARGS_LEVEL (deduced_args,
+ TMPL_ARGS_DEPTH (deduced_args),
+ innermost_deduced_args);
+ }
+ else
+ deduced_args = innermost_deduced_args;
+
+ if (unify (tparms, deduced_args,
+ INNERMOST_TEMPLATE_ARGS (spec_args),
+ INNERMOST_TEMPLATE_ARGS (args),
+ UNIFY_ALLOW_NONE, /*explain_p=*/false))
+ return NULL_TREE;
+
+ for (i = 0; i < ntparms; ++i)
+ if (! TREE_VEC_ELT (innermost_deduced_args, i))
+ return NULL_TREE;
+
+ /* Verify that nondeduced template arguments agree with the type
+ obtained from argument deduction.
+
+ For example:
+
+ struct A { typedef int X; };
+ template <class T, class U> struct C {};
+ template <class T> struct C<T, typename T::X> {};
+
+ Then with the instantiation `C<A, int>', we can deduce that
+ `T' is `A' but unify () does not check whether `typename T::X'
+ is `int'. */
+ spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE);
+ spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
+ spec_args, tmpl,
+ tf_none, false, false);
+ if (spec_args == error_mark_node
+ /* We only need to check the innermost arguments; the other
+ arguments will always agree. */
+ || !comp_template_args (INNERMOST_TEMPLATE_ARGS (spec_args),
+ INNERMOST_TEMPLATE_ARGS (args)))
+ return NULL_TREE;
+
+ /* Now that we have bindings for all of the template arguments,
+ ensure that the arguments deduced for the template template
+ parameters have compatible template parameter lists. See the use
+ of template_template_parm_bindings_ok_p in fn_type_unification
+ for more information. */
+ if (!template_template_parm_bindings_ok_p (tparms, deduced_args))
+ return NULL_TREE;
+
+ return deduced_args;
+}
+
+/* TEMPLATES is a TREE_LIST. Each TREE_VALUE is a TEMPLATE_DECL.
+ Return the TREE_LIST node with the most specialized template, if
+ any. If there is no most specialized template, the error_mark_node
+ is returned.
+
+ Note that this function does not look at, or modify, the
+ TREE_PURPOSE or TREE_TYPE of any of the nodes. Since the node
+ returned is one of the elements of INSTANTIATIONS, callers may
+ store information in the TREE_PURPOSE or TREE_TYPE of the nodes,
+ and retrieve it from the value returned. */
+
+tree
+most_specialized_instantiation (tree templates)
+{
+ tree fn, champ;
+
+ ++processing_template_decl;
+
+ champ = templates;
+ for (fn = TREE_CHAIN (templates); fn; fn = TREE_CHAIN (fn))
+ {
+ int fate = 0;
+
+ if (get_bindings (TREE_VALUE (champ),
+ DECL_TEMPLATE_RESULT (TREE_VALUE (fn)),
+ NULL_TREE, /*check_ret=*/true))
+ fate--;
+
+ if (get_bindings (TREE_VALUE (fn),
+ DECL_TEMPLATE_RESULT (TREE_VALUE (champ)),
+ NULL_TREE, /*check_ret=*/true))
+ fate++;
+
+ if (fate == -1)
+ champ = fn;
+ else if (!fate)
+ {
+ /* Equally specialized, move to next function. If there
+ is no next function, nothing's most specialized. */
+ fn = TREE_CHAIN (fn);
+ champ = fn;
+ if (!fn)
+ break;
+ }
+ }
+
+ if (champ)
+ /* Now verify that champ is better than everything earlier in the
+ instantiation list. */
+ for (fn = templates; fn != champ; fn = TREE_CHAIN (fn))
+ if (get_bindings (TREE_VALUE (champ),
+ DECL_TEMPLATE_RESULT (TREE_VALUE (fn)),
+ NULL_TREE, /*check_ret=*/true)
+ || !get_bindings (TREE_VALUE (fn),
+ DECL_TEMPLATE_RESULT (TREE_VALUE (champ)),
+ NULL_TREE, /*check_ret=*/true))
+ {
+ champ = NULL_TREE;
+ break;
+ }
+
+ processing_template_decl--;
+
+ if (!champ)
+ return error_mark_node;
+
+ return champ;
+}
+
+/* If DECL is a specialization of some template, return the most
+ general such template. Otherwise, returns NULL_TREE.
+
+ For example, given:
+
+ template <class T> struct S { template <class U> void f(U); };
+
+ if TMPL is `template <class U> void S<int>::f(U)' this will return
+ the full template. This function will not trace past partial
+ specializations, however. For example, given in addition:
+
+ template <class T> struct S<T*> { template <class U> void f(U); };
+
+ if TMPL is `template <class U> void S<int*>::f(U)' this will return
+ `template <class T> template <class U> S<T*>::f(U)'. */
+
+tree
+most_general_template (tree decl)
+{
+ /* If DECL is a FUNCTION_DECL, find the TEMPLATE_DECL of which it is
+ an immediate specialization. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (DECL_TEMPLATE_INFO (decl)) {
+ decl = DECL_TI_TEMPLATE (decl);
+
+ /* The DECL_TI_TEMPLATE can be an IDENTIFIER_NODE for a
+ template friend. */
+ if (TREE_CODE (decl) != TEMPLATE_DECL)
+ return NULL_TREE;
+ } else
+ return NULL_TREE;
+ }
+
+ /* Look for more and more general templates. */
+ while (DECL_TEMPLATE_INFO (decl))
+ {
+ /* The DECL_TI_TEMPLATE can be an IDENTIFIER_NODE in some cases.
+ (See cp-tree.h for details.) */
+ if (TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL)
+ break;
+
+ if (CLASS_TYPE_P (TREE_TYPE (decl))
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
+ break;
+
+ /* Stop if we run into an explicitly specialized class template. */
+ if (!DECL_NAMESPACE_SCOPE_P (decl)
+ && DECL_CONTEXT (decl)
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (DECL_CONTEXT (decl)))
+ break;
+
+ decl = DECL_TI_TEMPLATE (decl);
+ }
+
+ return decl;
+}
+
+/* Return the most specialized of the class template partial
+ specializations which can produce TYPE, a specialization of some class
+ template. The value returned is actually a TREE_LIST; the TREE_TYPE is
+ a _TYPE node corresponding to the partial specialization, while the
+ TREE_PURPOSE is the set of template arguments that must be
+ substituted into the TREE_TYPE in order to generate TYPE.
+
+ If the choice of partial specialization is ambiguous, a diagnostic
+ is issued, and the error_mark_node is returned. If there are no
+ partial specializations matching TYPE, then NULL_TREE is
+ returned, indicating that the primary template should be used. */
+
+static tree
+most_specialized_class (tree type, tsubst_flags_t complain)
+{
+ tree list = NULL_TREE;
+ tree t;
+ tree champ;
+ int fate;
+ bool ambiguous_p;
+ tree outer_args = NULL_TREE;
+
+ tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
+ tree main_tmpl = most_general_template (tmpl);
+ tree args = CLASSTYPE_TI_ARGS (type);
+
+ /* For determining which partial specialization to use, only the
+ innermost args are interesting. */
+ if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
+ {
+ outer_args = strip_innermost_template_args (args, 1);
+ args = INNERMOST_TEMPLATE_ARGS (args);
+ }
+
+ for (t = DECL_TEMPLATE_SPECIALIZATIONS (main_tmpl); t; t = TREE_CHAIN (t))
+ {
+ tree partial_spec_args;
+ tree spec_args;
+ tree spec_tmpl = TREE_VALUE (t);
+ tree orig_parms = DECL_INNERMOST_TEMPLATE_PARMS (spec_tmpl);
+
+ partial_spec_args = CLASSTYPE_TI_ARGS (TREE_TYPE (t));
+
+ ++processing_template_decl;
+
+ if (outer_args)
+ {
+ /* Discard the outer levels of args, and then substitute in the
+ template args from the enclosing class. */
+ partial_spec_args = INNERMOST_TEMPLATE_ARGS (partial_spec_args);
+ partial_spec_args = tsubst_template_args
+ (partial_spec_args, outer_args, tf_none, NULL_TREE);
+
+ /* And the same for the partial specialization TEMPLATE_DECL. */
+ spec_tmpl = tsubst (spec_tmpl, outer_args, tf_none, NULL_TREE);
+ }
+
+ partial_spec_args =
+ coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
+ partial_spec_args,
+ tmpl, tf_none,
+ /*require_all_args=*/true,
+ /*use_default_args=*/true);
+
+ --processing_template_decl;
+
+ if (partial_spec_args == error_mark_node)
+ return error_mark_node;
+ if (spec_tmpl == error_mark_node)
+ return error_mark_node;
+
+ tree parms = DECL_INNERMOST_TEMPLATE_PARMS (spec_tmpl);
+ spec_args = get_class_bindings (tmpl, parms,
+ partial_spec_args,
+ args);
+ if (spec_args)
+ {
+ if (outer_args)
+ spec_args = add_to_template_args (outer_args, spec_args);
+ list = tree_cons (spec_args, orig_parms, list);
+ TREE_TYPE (list) = TREE_TYPE (t);
+ }
+ }
+
+ if (! list)
+ return NULL_TREE;
+
+ ambiguous_p = false;
+ t = list;
+ champ = t;
+ t = TREE_CHAIN (t);
+ for (; t; t = TREE_CHAIN (t))
+ {
+ fate = more_specialized_class (tmpl, champ, t);
+ if (fate == 1)
+ ;
+ else
+ {
+ if (fate == 0)
+ {
+ t = TREE_CHAIN (t);
+ if (! t)
+ {
+ ambiguous_p = true;
+ break;
+ }
+ }
+ champ = t;
+ }
+ }
+
+ if (!ambiguous_p)
+ for (t = list; t && t != champ; t = TREE_CHAIN (t))
+ {
+ fate = more_specialized_class (tmpl, champ, t);
+ if (fate != 1)
+ {
+ ambiguous_p = true;
+ break;
+ }
+ }
+
+ if (ambiguous_p)
+ {
+ const char *str;
+ char *spaces = NULL;
+ if (!(complain & tf_error))
+ return error_mark_node;
+ error ("ambiguous class template instantiation for %q#T", type);
+ str = ngettext ("candidate is:", "candidates are:", list_length (list));
+ for (t = list; t; t = TREE_CHAIN (t))
+ {
+ error ("%s %+#T", spaces ? spaces : str, TREE_TYPE (t));
+ spaces = spaces ? spaces : get_spaces (str);
+ }
+ free (spaces);
+ return error_mark_node;
+ }
+
+ return champ;
+}
+
+/* Explicitly instantiate DECL. */
+
+void
+do_decl_instantiation (tree decl, tree storage)
+{
+ tree result = NULL_TREE;
+ int extern_p = 0;
+
+ if (!decl || decl == error_mark_node)
+ /* An error occurred, for which grokdeclarator has already issued
+ an appropriate message. */
+ return;
+ else if (! DECL_LANG_SPECIFIC (decl))
+ {
+ error ("explicit instantiation of non-template %q#D", decl);
+ return;
+ }
+ else if (VAR_P (decl))
+ {
+ /* There is an asymmetry here in the way VAR_DECLs and
+ FUNCTION_DECLs are handled by grokdeclarator. In the case of
+ the latter, the DECL we get back will be marked as a
+ template instantiation, and the appropriate
+ DECL_TEMPLATE_INFO will be set up. This does not happen for
+ VAR_DECLs so we do the lookup here. Probably, grokdeclarator
+ should handle VAR_DECLs as it currently handles
+ FUNCTION_DECLs. */
+ if (!DECL_CLASS_SCOPE_P (decl))
+ {
+ error ("%qD is not a static data member of a class template", decl);
+ return;
+ }
+ result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, false);
+ if (!result || !VAR_P (result))
+ {
+ error ("no matching template for %qD found", decl);
+ return;
+ }
+ if (!same_type_p (TREE_TYPE (result), TREE_TYPE (decl)))
+ {
+ error ("type %qT for explicit instantiation %qD does not match "
+ "declared type %qT", TREE_TYPE (result), decl,
+ TREE_TYPE (decl));
+ return;
+ }
+ }
+ else if (TREE_CODE (decl) != FUNCTION_DECL)
+ {
+ error ("explicit instantiation of %q#D", decl);
+ return;
+ }
+ else
+ result = decl;
+
+ /* Check for various error cases. Note that if the explicit
+ instantiation is valid the RESULT will currently be marked as an
+ *implicit* instantiation; DECL_EXPLICIT_INSTANTIATION is not set
+ until we get here. */
+
+ if (DECL_TEMPLATE_SPECIALIZATION (result))
+ {
+ /* DR 259 [temp.spec].
+
+ Both an explicit instantiation and a declaration of an explicit
+ specialization shall not appear in a program unless the explicit
+ instantiation follows a declaration of the explicit specialization.
+
+ For a given set of template parameters, if an explicit
+ instantiation of a template appears after a declaration of an
+ explicit specialization for that template, the explicit
+ instantiation has no effect. */
+ return;
+ }
+ else if (DECL_EXPLICIT_INSTANTIATION (result))
+ {
+ /* [temp.spec]
+
+ No program shall explicitly instantiate any template more
+ than once.
+
+ We check DECL_NOT_REALLY_EXTERN so as not to complain when
+ the first instantiation was `extern' and the second is not,
+ and EXTERN_P for the opposite case. */
+ if (DECL_NOT_REALLY_EXTERN (result) && !extern_p)
+ permerror (input_location, "duplicate explicit instantiation of %q#D", result);
+ /* If an "extern" explicit instantiation follows an ordinary
+ explicit instantiation, the template is instantiated. */
+ if (extern_p)
+ return;
+ }
+ else if (!DECL_IMPLICIT_INSTANTIATION (result))
+ {
+ error ("no matching template for %qD found", result);
+ return;
+ }
+ else if (!DECL_TEMPLATE_INFO (result))
+ {
+ permerror (input_location, "explicit instantiation of non-template %q#D", result);
+ return;
+ }
+
+ if (storage == NULL_TREE)
+ ;
+ else if (storage == ridpointers[(int) RID_EXTERN])
+ {
+ if (!in_system_header_at (input_location) && (cxx_dialect == cxx98))
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ 1998 forbids the use of %<extern%> on explicit "
+ "instantiations");
+ extern_p = 1;
+ }
+ else
+ error ("storage class %qD applied to template instantiation", storage);
+
+ check_explicit_instantiation_namespace (result);
+ mark_decl_instantiated (result, extern_p);
+ if (! extern_p)
+ instantiate_decl (result, /*defer_ok=*/1,
+ /*expl_inst_class_mem_p=*/false);
+}
+
+static void
+mark_class_instantiated (tree t, int extern_p)
+{
+ SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
+ SET_CLASSTYPE_INTERFACE_KNOWN (t);
+ CLASSTYPE_INTERFACE_ONLY (t) = extern_p;
+ TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = extern_p;
+ if (! extern_p)
+ {
+ CLASSTYPE_DEBUG_REQUESTED (t) = 1;
+ rest_of_type_compilation (t, 1);
+ }
+}
+
+/* Called from do_type_instantiation through binding_table_foreach to
+ do recursive instantiation for the type bound in ENTRY. */
+static void
+bt_instantiate_type_proc (binding_entry entry, void *data)
+{
+ tree storage = *(tree *) data;
+
+ if (MAYBE_CLASS_TYPE_P (entry->type)
+ && !uses_template_parms (CLASSTYPE_TI_ARGS (entry->type)))
+ do_type_instantiation (TYPE_MAIN_DECL (entry->type), storage, 0);
+}
+
+/* Called from do_type_instantiation to instantiate a member
+ (a member function or a static member variable) of an
+ explicitly instantiated class template. */
+static void
+instantiate_class_member (tree decl, int extern_p)
+{
+ mark_decl_instantiated (decl, extern_p);
+ if (! extern_p)
+ instantiate_decl (decl, /*defer_ok=*/1,
+ /*expl_inst_class_mem_p=*/true);
+}
+
+/* Perform an explicit instantiation of template class T. STORAGE, if
+ non-null, is the RID for extern, inline or static. COMPLAIN is
+ nonzero if this is called from the parser, zero if called recursively,
+ since the standard is unclear (as detailed below). */
+
+void
+do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
+{
+ int extern_p = 0;
+ int nomem_p = 0;
+ int static_p = 0;
+ int previous_instantiation_extern_p = 0;
+
+ if (TREE_CODE (t) == TYPE_DECL)
+ t = TREE_TYPE (t);
+
+ if (! CLASS_TYPE_P (t) || ! CLASSTYPE_TEMPLATE_INFO (t))
+ {
+ tree tmpl =
+ (TYPE_TEMPLATE_INFO (t)) ? TYPE_TI_TEMPLATE (t) : NULL;
+ if (tmpl)
+ error ("explicit instantiation of non-class template %qD", tmpl);
+ else
+ error ("explicit instantiation of non-template type %qT", t);
+ return;
+ }
+
+ complete_type (t);
+
+ if (!COMPLETE_TYPE_P (t))
+ {
+ if (complain & tf_error)
+ error ("explicit instantiation of %q#T before definition of template",
+ t);
+ return;
+ }
+
+ if (storage != NULL_TREE)
+ {
+ if (!in_system_header_at (input_location))
+ {
+ if (storage == ridpointers[(int) RID_EXTERN])
+ {
+ if (cxx_dialect == cxx98)
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ 1998 forbids the use of %<extern%> on "
+ "explicit instantiations");
+ }
+ else
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ forbids the use of %qE"
+ " on explicit instantiations", storage);
+ }
+
+ if (storage == ridpointers[(int) RID_INLINE])
+ nomem_p = 1;
+ else if (storage == ridpointers[(int) RID_EXTERN])
+ extern_p = 1;
+ else if (storage == ridpointers[(int) RID_STATIC])
+ static_p = 1;
+ else
+ {
+ error ("storage class %qD applied to template instantiation",
+ storage);
+ extern_p = 0;
+ }
+ }
+
+ if (CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
+ {
+ /* DR 259 [temp.spec].
+
+ Both an explicit instantiation and a declaration of an explicit
+ specialization shall not appear in a program unless the explicit
+ instantiation follows a declaration of the explicit specialization.
+
+ For a given set of template parameters, if an explicit
+ instantiation of a template appears after a declaration of an
+ explicit specialization for that template, the explicit
+ instantiation has no effect. */
+ return;
+ }
+ else if (CLASSTYPE_EXPLICIT_INSTANTIATION (t))
+ {
+ /* [temp.spec]
+
+ No program shall explicitly instantiate any template more
+ than once.
+
+ If PREVIOUS_INSTANTIATION_EXTERN_P, then the first explicit
+ instantiation was `extern'. If EXTERN_P then the second is.
+ These cases are OK. */
+ previous_instantiation_extern_p = CLASSTYPE_INTERFACE_ONLY (t);
+
+ if (!previous_instantiation_extern_p && !extern_p
+ && (complain & tf_error))
+ permerror (input_location, "duplicate explicit instantiation of %q#T", t);
+
+ /* If we've already instantiated the template, just return now. */
+ if (!CLASSTYPE_INTERFACE_ONLY (t))
+ return;
+ }
+
+ check_explicit_instantiation_namespace (TYPE_NAME (t));
+ mark_class_instantiated (t, extern_p);
+
+ if (nomem_p)
+ return;
+
+ {
+ tree tmp;
+
+ /* In contrast to implicit instantiation, where only the
+ declarations, and not the definitions, of members are
+ instantiated, we have here:
+
+ [temp.explicit]
+
+ The explicit instantiation of a class template specialization
+ implies the instantiation of all of its members not
+ previously explicitly specialized in the translation unit
+ containing the explicit instantiation.
+
+ Of course, we can't instantiate member template classes, since
+ we don't have any arguments for them. Note that the standard
+ is unclear on whether the instantiation of the members are
+ *explicit* instantiations or not. However, the most natural
+ interpretation is that it should be an explicit instantiation. */
+
+ if (! static_p)
+ for (tmp = TYPE_METHODS (t); tmp; tmp = DECL_CHAIN (tmp))
+ if (TREE_CODE (tmp) == FUNCTION_DECL
+ && DECL_TEMPLATE_INSTANTIATION (tmp))
+ instantiate_class_member (tmp, extern_p);
+
+ for (tmp = TYPE_FIELDS (t); tmp; tmp = DECL_CHAIN (tmp))
+ if (VAR_P (tmp) && DECL_TEMPLATE_INSTANTIATION (tmp))
+ instantiate_class_member (tmp, extern_p);
+
+ if (CLASSTYPE_NESTED_UTDS (t))
+ binding_table_foreach (CLASSTYPE_NESTED_UTDS (t),
+ bt_instantiate_type_proc, &storage);
+ }
+}
+
+/* Given a function DECL, which is a specialization of TMPL, modify
+ DECL to be a re-instantiation of TMPL with the same template
+ arguments. TMPL should be the template into which tsubst'ing
+ should occur for DECL, not the most general template.
+
+ One reason for doing this is a scenario like this:
+
+ template <class T>
+ void f(const T&, int i);
+
+ void g() { f(3, 7); }
+
+ template <class T>
+ void f(const T& t, const int i) { }
+
+ Note that when the template is first instantiated, with
+ instantiate_template, the resulting DECL will have no name for the
+ first parameter, and the wrong type for the second. So, when we go
+ to instantiate the DECL, we regenerate it. */
+
+static void
+regenerate_decl_from_template (tree decl, tree tmpl)
+{
+ /* The arguments used to instantiate DECL, from the most general
+ template. */
+ tree args;
+ tree code_pattern;
+
+ args = DECL_TI_ARGS (decl);
+ code_pattern = DECL_TEMPLATE_RESULT (tmpl);
+
+ /* Make sure that we can see identifiers, and compute access
+ correctly. */
+ push_access_scope (decl);
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ tree decl_parm;
+ tree pattern_parm;
+ tree specs;
+ int args_depth;
+ int parms_depth;
+
+ args_depth = TMPL_ARGS_DEPTH (args);
+ parms_depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl));
+ if (args_depth > parms_depth)
+ args = get_innermost_template_args (args, parms_depth);
+
+ specs = tsubst_exception_specification (TREE_TYPE (code_pattern),
+ args, tf_error, NULL_TREE,
+ /*defer_ok*/false);
+ if (specs && specs != error_mark_node)
+ TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl),
+ specs);
+
+ /* Merge parameter declarations. */
+ decl_parm = skip_artificial_parms_for (decl,
+ DECL_ARGUMENTS (decl));
+ pattern_parm
+ = skip_artificial_parms_for (code_pattern,
+ DECL_ARGUMENTS (code_pattern));
+ while (decl_parm && !DECL_PACK_P (pattern_parm))
+ {
+ tree parm_type;
+ tree attributes;
+
+ if (DECL_NAME (decl_parm) != DECL_NAME (pattern_parm))
+ DECL_NAME (decl_parm) = DECL_NAME (pattern_parm);
+ parm_type = tsubst (TREE_TYPE (pattern_parm), args, tf_error,
+ NULL_TREE);
+ parm_type = type_decays_to (parm_type);
+ if (!same_type_p (TREE_TYPE (decl_parm), parm_type))
+ TREE_TYPE (decl_parm) = parm_type;
+ attributes = DECL_ATTRIBUTES (pattern_parm);
+ if (DECL_ATTRIBUTES (decl_parm) != attributes)
+ {
+ DECL_ATTRIBUTES (decl_parm) = attributes;
+ cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0);
+ }
+ decl_parm = DECL_CHAIN (decl_parm);
+ pattern_parm = DECL_CHAIN (pattern_parm);
+ }
+ /* Merge any parameters that match with the function parameter
+ pack. */
+ if (pattern_parm && DECL_PACK_P (pattern_parm))
+ {
+ int i, len;
+ tree expanded_types;
+ /* Expand the TYPE_PACK_EXPANSION that provides the types for
+ the parameters in this function parameter pack. */
+ expanded_types = tsubst_pack_expansion (TREE_TYPE (pattern_parm),
+ args, tf_error, NULL_TREE);
+ len = TREE_VEC_LENGTH (expanded_types);
+ for (i = 0; i < len; i++)
+ {
+ tree parm_type;
+ tree attributes;
+
+ if (DECL_NAME (decl_parm) != DECL_NAME (pattern_parm))
+ /* Rename the parameter to include the index. */
+ DECL_NAME (decl_parm) =
+ make_ith_pack_parameter_name (DECL_NAME (pattern_parm), i);
+ parm_type = TREE_VEC_ELT (expanded_types, i);
+ parm_type = type_decays_to (parm_type);
+ if (!same_type_p (TREE_TYPE (decl_parm), parm_type))
+ TREE_TYPE (decl_parm) = parm_type;
+ attributes = DECL_ATTRIBUTES (pattern_parm);
+ if (DECL_ATTRIBUTES (decl_parm) != attributes)
+ {
+ DECL_ATTRIBUTES (decl_parm) = attributes;
+ cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0);
+ }
+ decl_parm = DECL_CHAIN (decl_parm);
+ }
+ }
+ /* Merge additional specifiers from the CODE_PATTERN. */
+ if (DECL_DECLARED_INLINE_P (code_pattern)
+ && !DECL_DECLARED_INLINE_P (decl))
+ DECL_DECLARED_INLINE_P (decl) = 1;
+ }
+ else if (VAR_P (decl))
+ {
+ DECL_INITIAL (decl) =
+ tsubst_expr (DECL_INITIAL (code_pattern), args,
+ tf_error, DECL_TI_TEMPLATE (decl),
+ /*integral_constant_expression_p=*/false);
+ if (VAR_HAD_UNKNOWN_BOUND (decl))
+ TREE_TYPE (decl) = tsubst (TREE_TYPE (code_pattern), args,
+ tf_error, DECL_TI_TEMPLATE (decl));
+ }
+ else
+ gcc_unreachable ();
+
+ pop_access_scope (decl);
+}
+
+/* Return the TEMPLATE_DECL into which DECL_TI_ARGS(DECL) should be
+ substituted to get DECL. */
+
+tree
+template_for_substitution (tree decl)
+{
+ tree tmpl = DECL_TI_TEMPLATE (decl);
+
+ /* Set TMPL to the template whose DECL_TEMPLATE_RESULT is the pattern
+ for the instantiation. This is not always the most general
+ template. Consider, for example:
+
+ template <class T>
+ struct S { template <class U> void f();
+ template <> void f<int>(); };
+
+ and an instantiation of S<double>::f<int>. We want TD to be the
+ specialization S<T>::f<int>, not the more general S<T>::f<U>. */
+ while (/* An instantiation cannot have a definition, so we need a
+ more general template. */
+ DECL_TEMPLATE_INSTANTIATION (tmpl)
+ /* We must also deal with friend templates. Given:
+
+ template <class T> struct S {
+ template <class U> friend void f() {};
+ };
+
+ S<int>::f<U> say, is not an instantiation of S<T>::f<U>,
+ so far as the language is concerned, but that's still
+ where we get the pattern for the instantiation from. On
+ other hand, if the definition comes outside the class, say:
+
+ template <class T> struct S {
+ template <class U> friend void f();
+ };
+ template <class U> friend void f() {}
+
+ we don't need to look any further. That's what the check for
+ DECL_INITIAL is for. */
+ || (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (tmpl)
+ && !DECL_INITIAL (DECL_TEMPLATE_RESULT (tmpl))))
+ {
+ /* The present template, TD, should not be a definition. If it
+ were a definition, we should be using it! Note that we
+ cannot restructure the loop to just keep going until we find
+ a template with a definition, since that might go too far if
+ a specialization was declared, but not defined. */
+ gcc_assert (!VAR_P (decl)
+ || DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (tmpl)));
+
+ /* Fetch the more general template. */
+ tmpl = DECL_TI_TEMPLATE (tmpl);
+ }
+
+ return tmpl;
+}
+
+/* Returns true if we need to instantiate this template instance even if we
+ know we aren't going to emit it.. */
+
+bool
+always_instantiate_p (tree decl)
+{
+ /* We always instantiate inline functions so that we can inline them. An
+ explicit instantiation declaration prohibits implicit instantiation of
+ non-inline functions. With high levels of optimization, we would
+ normally inline non-inline functions -- but we're not allowed to do
+ that for "extern template" functions. Therefore, we check
+ DECL_DECLARED_INLINE_P, rather than possibly_inlined_p. */
+ return ((TREE_CODE (decl) == FUNCTION_DECL
+ && (DECL_DECLARED_INLINE_P (decl)
+ || type_uses_auto (TREE_TYPE (TREE_TYPE (decl)))))
+ /* And we need to instantiate static data members so that
+ their initializers are available in integral constant
+ expressions. */
+ || (VAR_P (decl)
+ && decl_maybe_constant_var_p (decl)));
+}
+
+/* If FN has a noexcept-specifier that hasn't been instantiated yet,
+ instantiate it now, modifying TREE_TYPE (fn). */
+
+void
+maybe_instantiate_noexcept (tree fn)
+{
+ tree fntype, spec, noex, clone;
+
+ /* Don't instantiate a noexcept-specification from template context. */
+ if (processing_template_decl)
+ return;
+
+ if (DECL_CLONED_FUNCTION_P (fn))
+ fn = DECL_CLONED_FUNCTION (fn);
+ fntype = TREE_TYPE (fn);
+ spec = TYPE_RAISES_EXCEPTIONS (fntype);
+
+ if (!DEFERRED_NOEXCEPT_SPEC_P (spec))
+ return;
+
+ noex = TREE_PURPOSE (spec);
+
+ if (TREE_CODE (noex) == DEFERRED_NOEXCEPT)
+ {
+ if (push_tinst_level (fn))
+ {
+ push_access_scope (fn);
+ push_deferring_access_checks (dk_no_deferred);
+ input_location = DECL_SOURCE_LOCATION (fn);
+ noex = tsubst_copy_and_build (DEFERRED_NOEXCEPT_PATTERN (noex),
+ DEFERRED_NOEXCEPT_ARGS (noex),
+ tf_warning_or_error, fn,
+ /*function_p=*/false,
+ /*integral_constant_expression_p=*/true);
+ pop_deferring_access_checks ();
+ pop_access_scope (fn);
+ pop_tinst_level ();
+ spec = build_noexcept_spec (noex, tf_warning_or_error);
+ if (spec == error_mark_node)
+ spec = noexcept_false_spec;
+ }
+ else
+ spec = noexcept_false_spec;
+ }
+ else
+ {
+ /* This is an implicitly declared function, so NOEX is a list of
+ other functions to evaluate and merge. */
+ tree elt;
+ spec = noexcept_true_spec;
+ for (elt = noex; elt; elt = OVL_NEXT (elt))
+ {
+ tree fn = OVL_CURRENT (elt);
+ tree subspec;
+ maybe_instantiate_noexcept (fn);
+ subspec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
+ spec = merge_exception_specifiers (spec, subspec, NULL_TREE);
+ }
+ }
+
+ TREE_TYPE (fn) = build_exception_variant (fntype, spec);
+
+ FOR_EACH_CLONE (clone, fn)
+ {
+ if (TREE_TYPE (clone) == fntype)
+ TREE_TYPE (clone) = TREE_TYPE (fn);
+ else
+ TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec);
+ }
+}
+
+/* Produce the definition of D, a _DECL generated from a template. If
+ DEFER_OK is nonzero, then we don't have to actually do the
+ instantiation now; we just have to do it sometime. Normally it is
+ an error if this is an explicit instantiation but D is undefined.
+ EXPL_INST_CLASS_MEM_P is true iff D is a member of an
+ explicitly instantiated class template. */
+
+tree
+instantiate_decl (tree d, int defer_ok,
+ bool expl_inst_class_mem_p)
+{
+ tree tmpl = DECL_TI_TEMPLATE (d);
+ tree gen_args;
+ tree args;
+ tree td;
+ tree code_pattern;
+ tree spec;
+ tree gen_tmpl;
+ bool pattern_defined;
+ location_t saved_loc = input_location;
+ int saved_unevaluated_operand = cp_unevaluated_operand;
+ int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+ bool external_p;
+ tree fn_context;
+ bool nested;
+
+ /* This function should only be used to instantiate templates for
+ functions and static member variables. */
+ gcc_assert (VAR_OR_FUNCTION_DECL_P (d));
+
+ /* Variables are never deferred; if instantiation is required, they
+ are instantiated right away. That allows for better code in the
+ case that an expression refers to the value of the variable --
+ if the variable has a constant value the referring expression can
+ take advantage of that fact. */
+ if (VAR_P (d)
+ || DECL_DECLARED_CONSTEXPR_P (d))
+ defer_ok = 0;
+
+ /* Don't instantiate cloned functions. Instead, instantiate the
+ functions they cloned. */
+ if (TREE_CODE (d) == FUNCTION_DECL && DECL_CLONED_FUNCTION_P (d))
+ d = DECL_CLONED_FUNCTION (d);
+
+ if (DECL_TEMPLATE_INSTANTIATED (d)
+ || (TREE_CODE (d) == FUNCTION_DECL
+ && DECL_DEFAULTED_FN (d) && DECL_INITIAL (d))
+ || DECL_TEMPLATE_SPECIALIZATION (d))
+ /* D has already been instantiated or explicitly specialized, so
+ there's nothing for us to do here.
+
+ It might seem reasonable to check whether or not D is an explicit
+ instantiation, and, if so, stop here. But when an explicit
+ instantiation is deferred until the end of the compilation,
+ DECL_EXPLICIT_INSTANTIATION is set, even though we still need to do
+ the instantiation. */
+ return d;
+
+ /* Check to see whether we know that this template will be
+ instantiated in some other file, as with "extern template"
+ extension. */
+ external_p = (DECL_INTERFACE_KNOWN (d) && DECL_REALLY_EXTERN (d));
+
+ /* In general, we do not instantiate such templates. */
+ if (external_p && !always_instantiate_p (d))
+ return d;
+
+ gen_tmpl = most_general_template (tmpl);
+ gen_args = DECL_TI_ARGS (d);
+
+ if (tmpl != gen_tmpl)
+ /* We should already have the extra args. */
+ gcc_assert (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (gen_tmpl))
+ == TMPL_ARGS_DEPTH (gen_args));
+ /* And what's in the hash table should match D. */
+ gcc_assert ((spec = retrieve_specialization (gen_tmpl, gen_args, 0)) == d
+ || spec == NULL_TREE);
+
+ /* This needs to happen before any tsubsting. */
+ if (! push_tinst_level (d))
+ return d;
+
+ timevar_push (TV_TEMPLATE_INST);
+
+ /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
+ for the instantiation. */
+ td = template_for_substitution (d);
+ code_pattern = DECL_TEMPLATE_RESULT (td);
+
+ /* We should never be trying to instantiate a member of a class
+ template or partial specialization. */
+ gcc_assert (d != code_pattern);
+
+ if ((DECL_NAMESPACE_SCOPE_P (d) && !DECL_INITIALIZED_IN_CLASS_P (d))
+ || DECL_TEMPLATE_SPECIALIZATION (td))
+ /* In the case of a friend template whose definition is provided
+ outside the class, we may have too many arguments. Drop the
+ ones we don't need. The same is true for specializations. */
+ args = get_innermost_template_args
+ (gen_args, TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (td)));
+ else
+ args = gen_args;
+
+ if (TREE_CODE (d) == FUNCTION_DECL)
+ pattern_defined = (DECL_SAVED_TREE (code_pattern) != NULL_TREE
+ || DECL_DEFAULTED_OUTSIDE_CLASS_P (code_pattern));
+ else
+ pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
+
+ /* We may be in the middle of deferred access check. Disable it now. */
+ push_deferring_access_checks (dk_no_deferred);
+
+ /* Unless an explicit instantiation directive has already determined
+ the linkage of D, remember that a definition is available for
+ this entity. */
+ if (pattern_defined
+ && !DECL_INTERFACE_KNOWN (d)
+ && !DECL_NOT_REALLY_EXTERN (d))
+ mark_definable (d);
+
+ DECL_SOURCE_LOCATION (td) = DECL_SOURCE_LOCATION (code_pattern);
+ DECL_SOURCE_LOCATION (d) = DECL_SOURCE_LOCATION (code_pattern);
+ input_location = DECL_SOURCE_LOCATION (d);
+
+ /* If D is a member of an explicitly instantiated class template,
+ and no definition is available, treat it like an implicit
+ instantiation. */
+ if (!pattern_defined && expl_inst_class_mem_p
+ && DECL_EXPLICIT_INSTANTIATION (d))
+ {
+ /* Leave linkage flags alone on instantiations with anonymous
+ visibility. */
+ if (TREE_PUBLIC (d))
+ {
+ DECL_NOT_REALLY_EXTERN (d) = 0;
+ DECL_INTERFACE_KNOWN (d) = 0;
+ }
+ SET_DECL_IMPLICIT_INSTANTIATION (d);
+ }
+
+ if (TREE_CODE (d) == FUNCTION_DECL)
+ maybe_instantiate_noexcept (d);
+
+ /* Defer all other templates, unless we have been explicitly
+ forbidden from doing so. */
+ if (/* If there is no definition, we cannot instantiate the
+ template. */
+ ! pattern_defined
+ /* If it's OK to postpone instantiation, do so. */
+ || defer_ok
+ /* If this is a static data member that will be defined
+ elsewhere, we don't want to instantiate the entire data
+ member, but we do want to instantiate the initializer so that
+ we can substitute that elsewhere. */
+ || (external_p && VAR_P (d)))
+ {
+ /* The definition of the static data member is now required so
+ we must substitute the initializer. */
+ if (VAR_P (d)
+ && !DECL_INITIAL (d)
+ && DECL_INITIAL (code_pattern))
+ {
+ tree ns;
+ tree init;
+ bool const_init = false;
+
+ ns = decl_namespace_context (d);
+ push_nested_namespace (ns);
+ push_nested_class (DECL_CONTEXT (d));
+ init = tsubst_expr (DECL_INITIAL (code_pattern),
+ args,
+ tf_warning_or_error, NULL_TREE,
+ /*integral_constant_expression_p=*/false);
+ /* Make sure the initializer is still constant, in case of
+ circular dependency (template/instantiate6.C). */
+ const_init
+ = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (code_pattern);
+ cp_finish_decl (d, init, /*init_const_expr_p=*/const_init,
+ /*asmspec_tree=*/NULL_TREE,
+ LOOKUP_ONLYCONVERTING);
+ pop_nested_class ();
+ pop_nested_namespace (ns);
+ }
+
+ /* We restore the source position here because it's used by
+ add_pending_template. */
+ input_location = saved_loc;
+
+ if (at_eof && !pattern_defined
+ && DECL_EXPLICIT_INSTANTIATION (d)
+ && DECL_NOT_REALLY_EXTERN (d))
+ /* [temp.explicit]
+
+ The definition of a non-exported function template, a
+ non-exported member function template, or a non-exported
+ member function or static data member of a class template
+ shall be present in every translation unit in which it is
+ explicitly instantiated. */
+ permerror (input_location, "explicit instantiation of %qD "
+ "but no definition available", d);
+
+ /* If we're in unevaluated context, we just wanted to get the
+ constant value; this isn't an odr use, so don't queue
+ a full instantiation. */
+ if (cp_unevaluated_operand != 0)
+ goto out;
+ /* ??? Historically, we have instantiated inline functions, even
+ when marked as "extern template". */
+ if (!(external_p && VAR_P (d)))
+ add_pending_template (d);
+ goto out;
+ }
+ /* Tell the repository that D is available in this translation unit
+ -- and see if it is supposed to be instantiated here. */
+ if (TREE_PUBLIC (d) && !DECL_REALLY_EXTERN (d) && !repo_emit_p (d))
+ {
+ /* In a PCH file, despite the fact that the repository hasn't
+ requested instantiation in the PCH it is still possible that
+ an instantiation will be required in a file that includes the
+ PCH. */
+ if (pch_file)
+ add_pending_template (d);
+ /* Instantiate inline functions so that the inliner can do its
+ job, even though we'll not be emitting a copy of this
+ function. */
+ if (!(TREE_CODE (d) == FUNCTION_DECL && possibly_inlined_p (d)))
+ goto out;
+ }
+
+ fn_context = decl_function_context (d);
+ nested = (current_function_decl != NULL_TREE);
+ if (!fn_context)
+ push_to_top_level ();
+ else
+ {
+ if (nested)
+ push_function_context ();
+ cp_unevaluated_operand = 0;
+ c_inhibit_evaluation_warnings = 0;
+ }
+
+ /* Mark D as instantiated so that recursive calls to
+ instantiate_decl do not try to instantiate it again. */
+ DECL_TEMPLATE_INSTANTIATED (d) = 1;
+
+ /* Regenerate the declaration in case the template has been modified
+ by a subsequent redeclaration. */
+ regenerate_decl_from_template (d, td);
+
+ /* We already set the file and line above. Reset them now in case
+ they changed as a result of calling regenerate_decl_from_template. */
+ input_location = DECL_SOURCE_LOCATION (d);
+
+ if (VAR_P (d))
+ {
+ tree init;
+ bool const_init = false;
+
+ /* Clear out DECL_RTL; whatever was there before may not be right
+ since we've reset the type of the declaration. */
+ SET_DECL_RTL (d, NULL);
+ DECL_IN_AGGR_P (d) = 0;
+
+ /* The initializer is placed in DECL_INITIAL by
+ regenerate_decl_from_template so we don't need to
+ push/pop_access_scope again here. Pull it out so that
+ cp_finish_decl can process it. */
+ init = DECL_INITIAL (d);
+ DECL_INITIAL (d) = NULL_TREE;
+ DECL_INITIALIZED_P (d) = 0;
+
+ /* Clear DECL_EXTERNAL so that cp_finish_decl will process the
+ initializer. That function will defer actual emission until
+ we have a chance to determine linkage. */
+ DECL_EXTERNAL (d) = 0;
+
+ /* Enter the scope of D so that access-checking works correctly. */
+ push_nested_class (DECL_CONTEXT (d));
+ const_init = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (code_pattern);
+ cp_finish_decl (d, init, const_init, NULL_TREE, 0);
+ pop_nested_class ();
+ }
+ else if (TREE_CODE (d) == FUNCTION_DECL && DECL_DEFAULTED_FN (code_pattern))
+ synthesize_method (d);
+ else if (TREE_CODE (d) == FUNCTION_DECL)
+ {
+ struct pointer_map_t *saved_local_specializations;
+ tree subst_decl;
+ tree tmpl_parm;
+ tree spec_parm;
+ tree block = NULL_TREE;
+
+ /* Save away the current list, in case we are instantiating one
+ template from within the body of another. */
+ saved_local_specializations = local_specializations;
+
+ /* Set up the list of local specializations. */
+ local_specializations = pointer_map_create ();
+
+ /* Set up context. */
+ if (DECL_OMP_DECLARE_REDUCTION_P (code_pattern)
+ && TREE_CODE (DECL_CONTEXT (code_pattern)) == FUNCTION_DECL)
+ block = push_stmt_list ();
+ else
+ start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED);
+
+ /* Some typedefs referenced from within the template code need to be
+ access checked at template instantiation time, i.e now. These
+ types were added to the template at parsing time. Let's get those
+ and perform the access checks then. */
+ perform_typedefs_access_check (DECL_TEMPLATE_RESULT (gen_tmpl),
+ gen_args);
+
+ /* Create substitution entries for the parameters. */
+ subst_decl = DECL_TEMPLATE_RESULT (template_for_substitution (d));
+ tmpl_parm = DECL_ARGUMENTS (subst_decl);
+ spec_parm = DECL_ARGUMENTS (d);
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (d))
+ {
+ register_local_specialization (spec_parm, tmpl_parm);
+ spec_parm = skip_artificial_parms_for (d, spec_parm);
+ tmpl_parm = skip_artificial_parms_for (subst_decl, tmpl_parm);
+ }
+ for (; tmpl_parm; tmpl_parm = DECL_CHAIN (tmpl_parm))
+ {
+ if (!DECL_PACK_P (tmpl_parm))
+ {
+ register_local_specialization (spec_parm, tmpl_parm);
+ spec_parm = DECL_CHAIN (spec_parm);
+ }
+ else
+ {
+ /* Register the (value) argument pack as a specialization of
+ TMPL_PARM, then move on. */
+ tree argpack = extract_fnparm_pack (tmpl_parm, &spec_parm);
+ register_local_specialization (argpack, tmpl_parm);
+ }
+ }
+ gcc_assert (!spec_parm);
+
+ /* Substitute into the body of the function. */
+ if (DECL_OMP_DECLARE_REDUCTION_P (code_pattern))
+ tsubst_omp_udr (DECL_SAVED_TREE (code_pattern), args,
+ tf_warning_or_error, tmpl);
+ else
+ {
+ tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
+ tf_warning_or_error, tmpl,
+ /*integral_constant_expression_p=*/false);
+
+ /* Set the current input_location to the end of the function
+ so that finish_function knows where we are. */
+ input_location
+ = DECL_STRUCT_FUNCTION (code_pattern)->function_end_locus;
+
+ /* Remember if we saw an infinite loop in the template. */
+ current_function_infinite_loop
+ = DECL_STRUCT_FUNCTION (code_pattern)->language->infinite_loop;
+ }
+
+ /* We don't need the local specializations any more. */
+ pointer_map_destroy (local_specializations);
+ local_specializations = saved_local_specializations;
+
+ /* Finish the function. */
+ if (DECL_OMP_DECLARE_REDUCTION_P (code_pattern)
+ && TREE_CODE (DECL_CONTEXT (code_pattern)) == FUNCTION_DECL)
+ DECL_SAVED_TREE (d) = pop_stmt_list (block);
+ else
+ {
+ d = finish_function (0);
+ expand_or_defer_fn (d);
+ }
+
+ if (DECL_OMP_DECLARE_REDUCTION_P (code_pattern))
+ cp_check_omp_declare_reduction (d);
+ }
+
+ /* We're not deferring instantiation any more. */
+ TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0;
+
+ if (!fn_context)
+ pop_from_top_level ();
+ else if (nested)
+ pop_function_context ();
+
+out:
+ input_location = saved_loc;
+ cp_unevaluated_operand = saved_unevaluated_operand;
+ c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
+ pop_deferring_access_checks ();
+ pop_tinst_level ();
+
+ timevar_pop (TV_TEMPLATE_INST);
+
+ return d;
+}
+
+/* Run through the list of templates that we wish we could
+ instantiate, and instantiate any we can. RETRIES is the
+ number of times we retry pending template instantiation. */
+
+void
+instantiate_pending_templates (int retries)
+{
+ int reconsider;
+ location_t saved_loc = input_location;
+
+ /* Instantiating templates may trigger vtable generation. This in turn
+ may require further template instantiations. We place a limit here
+ to avoid infinite loop. */
+ if (pending_templates && retries >= max_tinst_depth)
+ {
+ tree decl = pending_templates->tinst->decl;
+
+ error ("template instantiation depth exceeds maximum of %d"
+ " instantiating %q+D, possibly from virtual table generation"
+ " (use -ftemplate-depth= to increase the maximum)",
+ max_tinst_depth, decl);
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ /* Pretend that we defined it. */
+ DECL_INITIAL (decl) = error_mark_node;
+ return;
+ }
+
+ do
+ {
+ struct pending_template **t = &pending_templates;
+ struct pending_template *last = NULL;
+ reconsider = 0;
+ while (*t)
+ {
+ tree instantiation = reopen_tinst_level ((*t)->tinst);
+ bool complete = false;
+
+ if (TYPE_P (instantiation))
+ {
+ tree fn;
+
+ if (!COMPLETE_TYPE_P (instantiation))
+ {
+ instantiate_class_template (instantiation);
+ if (CLASSTYPE_TEMPLATE_INSTANTIATION (instantiation))
+ for (fn = TYPE_METHODS (instantiation);
+ fn;
+ fn = TREE_CHAIN (fn))
+ if (! DECL_ARTIFICIAL (fn))
+ instantiate_decl (fn,
+ /*defer_ok=*/0,
+ /*expl_inst_class_mem_p=*/false);
+ if (COMPLETE_TYPE_P (instantiation))
+ reconsider = 1;
+ }
+
+ complete = COMPLETE_TYPE_P (instantiation);
+ }
+ else
+ {
+ if (!DECL_TEMPLATE_SPECIALIZATION (instantiation)
+ && !DECL_TEMPLATE_INSTANTIATED (instantiation))
+ {
+ instantiation
+ = instantiate_decl (instantiation,
+ /*defer_ok=*/0,
+ /*expl_inst_class_mem_p=*/false);
+ if (DECL_TEMPLATE_INSTANTIATED (instantiation))
+ reconsider = 1;
+ }
+
+ complete = (DECL_TEMPLATE_SPECIALIZATION (instantiation)
+ || DECL_TEMPLATE_INSTANTIATED (instantiation));
+ }
+
+ if (complete)
+ /* If INSTANTIATION has been instantiated, then we don't
+ need to consider it again in the future. */
+ *t = (*t)->next;
+ else
+ {
+ last = *t;
+ t = &(*t)->next;
+ }
+ tinst_depth = 0;
+ current_tinst_level = NULL;
+ }
+ last_pending_template = last;
+ }
+ while (reconsider);
+
+ input_location = saved_loc;
+}
+
+/* Substitute ARGVEC into T, which is a list of initializers for
+ either base class or a non-static data member. The TREE_PURPOSEs
+ are DECLs, and the TREE_VALUEs are the initializer values. Used by
+ instantiate_decl. */
+
+static tree
+tsubst_initializer_list (tree t, tree argvec)
+{
+ tree inits = NULL_TREE;
+
+ for (; t; t = TREE_CHAIN (t))
+ {
+ tree decl;
+ tree init;
+ tree expanded_bases = NULL_TREE;
+ tree expanded_arguments = NULL_TREE;
+ int i, len = 1;
+
+ if (TREE_CODE (TREE_PURPOSE (t)) == TYPE_PACK_EXPANSION)
+ {
+ tree expr;
+ tree arg;
+
+ /* Expand the base class expansion type into separate base
+ classes. */
+ expanded_bases = tsubst_pack_expansion (TREE_PURPOSE (t), argvec,
+ tf_warning_or_error,
+ NULL_TREE);
+ if (expanded_bases == error_mark_node)
+ continue;
+
+ /* We'll be building separate TREE_LISTs of arguments for
+ each base. */
+ len = TREE_VEC_LENGTH (expanded_bases);
+ expanded_arguments = make_tree_vec (len);
+ for (i = 0; i < len; i++)
+ TREE_VEC_ELT (expanded_arguments, i) = NULL_TREE;
+
+ /* Build a dummy EXPR_PACK_EXPANSION that will be used to
+ expand each argument in the TREE_VALUE of t. */
+ expr = make_node (EXPR_PACK_EXPANSION);
+ PACK_EXPANSION_LOCAL_P (expr) = true;
+ PACK_EXPANSION_PARAMETER_PACKS (expr) =
+ PACK_EXPANSION_PARAMETER_PACKS (TREE_PURPOSE (t));
+
+ if (TREE_VALUE (t) == void_type_node)
+ /* VOID_TYPE_NODE is used to indicate
+ value-initialization. */
+ {
+ for (i = 0; i < len; i++)
+ TREE_VEC_ELT (expanded_arguments, i) = void_type_node;
+ }
+ else
+ {
+ /* Substitute parameter packs into each argument in the
+ TREE_LIST. */
+ in_base_initializer = 1;
+ for (arg = TREE_VALUE (t); arg; arg = TREE_CHAIN (arg))
+ {
+ tree expanded_exprs;
+
+ /* Expand the argument. */
+ SET_PACK_EXPANSION_PATTERN (expr, TREE_VALUE (arg));
+ expanded_exprs
+ = tsubst_pack_expansion (expr, argvec,
+ tf_warning_or_error,
+ NULL_TREE);
+ if (expanded_exprs == error_mark_node)
+ continue;
+
+ /* Prepend each of the expanded expressions to the
+ corresponding TREE_LIST in EXPANDED_ARGUMENTS. */
+ for (i = 0; i < len; i++)
+ {
+ TREE_VEC_ELT (expanded_arguments, i) =
+ tree_cons (NULL_TREE,
+ TREE_VEC_ELT (expanded_exprs, i),
+ TREE_VEC_ELT (expanded_arguments, i));
+ }
+ }
+ in_base_initializer = 0;
+
+ /* Reverse all of the TREE_LISTs in EXPANDED_ARGUMENTS,
+ since we built them backwards. */
+ for (i = 0; i < len; i++)
+ {
+ TREE_VEC_ELT (expanded_arguments, i) =
+ nreverse (TREE_VEC_ELT (expanded_arguments, i));
+ }
+ }
+ }
+
+ for (i = 0; i < len; ++i)
+ {
+ if (expanded_bases)
+ {
+ decl = TREE_VEC_ELT (expanded_bases, i);
+ decl = expand_member_init (decl);
+ init = TREE_VEC_ELT (expanded_arguments, i);
+ }
+ else
+ {
+ tree tmp;
+ decl = tsubst_copy (TREE_PURPOSE (t), argvec,
+ tf_warning_or_error, NULL_TREE);
+
+ decl = expand_member_init (decl);
+ if (decl && !DECL_P (decl))
+ in_base_initializer = 1;
+
+ init = TREE_VALUE (t);
+ tmp = init;
+ if (init != void_type_node)
+ init = tsubst_expr (init, argvec,
+ tf_warning_or_error, NULL_TREE,
+ /*integral_constant_expression_p=*/false);
+ if (init == NULL_TREE && tmp != NULL_TREE)
+ /* If we had an initializer but it instantiated to nothing,
+ value-initialize the object. This will only occur when
+ the initializer was a pack expansion where the parameter
+ packs used in that expansion were of length zero. */
+ init = void_type_node;
+ in_base_initializer = 0;
+ }
+
+ if (decl)
+ {
+ init = build_tree_list (decl, init);
+ TREE_CHAIN (init) = inits;
+ inits = init;
+ }
+ }
+ }
+ return inits;
+}
+
+/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL. */
+
+static void
+set_current_access_from_decl (tree decl)
+{
+ if (TREE_PRIVATE (decl))
+ current_access_specifier = access_private_node;
+ else if (TREE_PROTECTED (decl))
+ current_access_specifier = access_protected_node;
+ else
+ current_access_specifier = access_public_node;
+}
+
+/* Instantiate an enumerated type. TAG is the template type, NEWTAG
+ is the instantiation (which should have been created with
+ start_enum) and ARGS are the template arguments to use. */
+
+static void
+tsubst_enum (tree tag, tree newtag, tree args)
+{
+ tree e;
+
+ if (SCOPED_ENUM_P (newtag))
+ begin_scope (sk_scoped_enum, newtag);
+
+ for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e))
+ {
+ tree value;
+ tree decl;
+
+ decl = TREE_VALUE (e);
+ /* Note that in a template enum, the TREE_VALUE is the
+ CONST_DECL, not the corresponding INTEGER_CST. */
+ value = tsubst_expr (DECL_INITIAL (decl),
+ args, tf_warning_or_error, NULL_TREE,
+ /*integral_constant_expression_p=*/true);
+
+ /* Give this enumeration constant the correct access. */
+ set_current_access_from_decl (decl);
+
+ /* Actually build the enumerator itself. */
+ build_enumerator
+ (DECL_NAME (decl), value, newtag, DECL_SOURCE_LOCATION (decl));
+ }
+
+ if (SCOPED_ENUM_P (newtag))
+ finish_scope ();
+
+ finish_enum_value_list (newtag);
+ finish_enum (newtag);
+
+ DECL_SOURCE_LOCATION (TYPE_NAME (newtag))
+ = DECL_SOURCE_LOCATION (TYPE_NAME (tag));
+}
+
+/* DECL is a FUNCTION_DECL that is a template specialization. Return
+ its type -- but without substituting the innermost set of template
+ arguments. So, innermost set of template parameters will appear in
+ the type. */
+
+tree
+get_mostly_instantiated_function_type (tree decl)
+{
+ tree fn_type;
+ tree tmpl;
+ tree targs;
+ tree tparms;
+ int parm_depth;
+
+ tmpl = most_general_template (DECL_TI_TEMPLATE (decl));
+ targs = DECL_TI_ARGS (decl);
+ tparms = DECL_TEMPLATE_PARMS (tmpl);
+ parm_depth = TMPL_PARMS_DEPTH (tparms);
+
+ /* There should be as many levels of arguments as there are levels
+ of parameters. */
+ gcc_assert (parm_depth == TMPL_ARGS_DEPTH (targs));
+
+ fn_type = TREE_TYPE (tmpl);
+
+ if (parm_depth == 1)
+ /* No substitution is necessary. */
+ ;
+ else
+ {
+ int i;
+ tree partial_args;
+
+ /* Replace the innermost level of the TARGS with NULL_TREEs to
+ let tsubst know not to substitute for those parameters. */
+ partial_args = make_tree_vec (TREE_VEC_LENGTH (targs));
+ for (i = 1; i < TMPL_ARGS_DEPTH (targs); ++i)
+ SET_TMPL_ARGS_LEVEL (partial_args, i,
+ TMPL_ARGS_LEVEL (targs, i));
+ SET_TMPL_ARGS_LEVEL (partial_args,
+ TMPL_ARGS_DEPTH (targs),
+ make_tree_vec (DECL_NTPARMS (tmpl)));
+
+ /* Make sure that we can see identifiers, and compute access
+ correctly. */
+ push_access_scope (decl);
+
+ ++processing_template_decl;
+ /* Now, do the (partial) substitution to figure out the
+ appropriate function type. */
+ fn_type = tsubst (fn_type, partial_args, tf_error, NULL_TREE);
+ --processing_template_decl;
+
+ /* Substitute into the template parameters to obtain the real
+ innermost set of parameters. This step is important if the
+ innermost set of template parameters contains value
+ parameters whose types depend on outer template parameters. */
+ TREE_VEC_LENGTH (partial_args)--;
+ tparms = tsubst_template_parms (tparms, partial_args, tf_error);
+
+ pop_access_scope (decl);
+ }
+
+ return fn_type;
+}
+
+/* Return truthvalue if we're processing a template different from
+ the last one involved in diagnostics. */
+int
+problematic_instantiation_changed (void)
+{
+ return current_tinst_level != last_error_tinst_level;
+}
+
+/* Remember current template involved in diagnostics. */
+void
+record_last_problematic_instantiation (void)
+{
+ last_error_tinst_level = current_tinst_level;
+}
+
+struct tinst_level *
+current_instantiation (void)
+{
+ return current_tinst_level;
+}
+
+/* [temp.param] Check that template non-type parm TYPE is of an allowable
+ type. Return zero for ok, nonzero for disallowed. Issue error and
+ warning messages under control of COMPLAIN. */
+
+static int
+invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain)
+{
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ return 0;
+ else if (POINTER_TYPE_P (type))
+ return 0;
+ else if (TYPE_PTRMEM_P (type))
+ return 0;
+ else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+ return 0;
+ else if (TREE_CODE (type) == TYPENAME_TYPE)
+ return 0;
+ else if (TREE_CODE (type) == DECLTYPE_TYPE)
+ return 0;
+ else if (TREE_CODE (type) == NULLPTR_TYPE)
+ return 0;
+
+ if (complain & tf_error)
+ {
+ if (type == error_mark_node)
+ inform (input_location, "invalid template non-type parameter");
+ else
+ error ("%q#T is not a valid type for a template non-type parameter",
+ type);
+ }
+ return 1;
+}
+
+/* Returns TRUE if TYPE is dependent, in the sense of [temp.dep.type].
+ Assumes that TYPE really is a type, and not the ERROR_MARK_NODE.*/
+
+static bool
+dependent_type_p_r (tree type)
+{
+ tree scope;
+
+ /* [temp.dep.type]
+
+ A type is dependent if it is:
+
+ -- a template parameter. Template template parameters are types
+ for us (since TYPE_P holds true for them) so we handle
+ them here. */
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
+ || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
+ return true;
+ /* -- a qualified-id with a nested-name-specifier which contains a
+ class-name that names a dependent type or whose unqualified-id
+ names a dependent type. */
+ if (TREE_CODE (type) == TYPENAME_TYPE)
+ return true;
+ /* -- a cv-qualified type where the cv-unqualified type is
+ dependent. */
+ type = TYPE_MAIN_VARIANT (type);
+ /* -- a compound type constructed from any dependent type. */
+ if (TYPE_PTRMEM_P (type))
+ return (dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
+ || dependent_type_p (TYPE_PTRMEM_POINTED_TO_TYPE
+ (type)));
+ else if (TYPE_PTR_P (type)
+ || TREE_CODE (type) == REFERENCE_TYPE)
+ return dependent_type_p (TREE_TYPE (type));
+ else if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
+ {
+ tree arg_type;
+
+ if (dependent_type_p (TREE_TYPE (type)))
+ return true;
+ for (arg_type = TYPE_ARG_TYPES (type);
+ arg_type;
+ arg_type = TREE_CHAIN (arg_type))
+ if (dependent_type_p (TREE_VALUE (arg_type)))
+ return true;
+ return false;
+ }
+ /* -- an array type constructed from any dependent type or whose
+ size is specified by a constant expression that is
+ value-dependent.
+
+ We checked for type- and value-dependence of the bounds in
+ compute_array_index_type, so TYPE_DEPENDENT_P is already set. */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (TYPE_DOMAIN (type)
+ && dependent_type_p (TYPE_DOMAIN (type)))
+ return true;
+ return dependent_type_p (TREE_TYPE (type));
+ }
+
+ /* -- a template-id in which either the template name is a template
+ parameter ... */
+ if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ return true;
+ /* ... or any of the template arguments is a dependent type or
+ an expression that is type-dependent or value-dependent. */
+ else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type)
+ && (any_dependent_template_arguments_p
+ (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type)))))
+ return true;
+
+ /* All TYPEOF_TYPEs, DECLTYPE_TYPEs, and UNDERLYING_TYPEs are
+ dependent; if the argument of the `typeof' expression is not
+ type-dependent, then it should already been have resolved. */
+ if (TREE_CODE (type) == TYPEOF_TYPE
+ || TREE_CODE (type) == DECLTYPE_TYPE
+ || TREE_CODE (type) == UNDERLYING_TYPE)
+ return true;
+
+ /* A template argument pack is dependent if any of its packed
+ arguments are. */
+ if (TREE_CODE (type) == TYPE_ARGUMENT_PACK)
+ {
+ tree args = ARGUMENT_PACK_ARGS (type);
+ int i, len = TREE_VEC_LENGTH (args);
+ for (i = 0; i < len; ++i)
+ if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
+ return true;
+ }
+
+ /* All TYPE_PACK_EXPANSIONs are dependent, because parameter packs must
+ be template parameters. */
+ if (TREE_CODE (type) == TYPE_PACK_EXPANSION)
+ return true;
+
+ /* The standard does not specifically mention types that are local
+ to template functions or local classes, but they should be
+ considered dependent too. For example:
+
+ template <int I> void f() {
+ enum E { a = I };
+ S<sizeof (E)> s;
+ }
+
+ The size of `E' cannot be known until the value of `I' has been
+ determined. Therefore, `E' must be considered dependent. */
+ scope = TYPE_CONTEXT (type);
+ if (scope && TYPE_P (scope))
+ return dependent_type_p (scope);
+ /* Don't use type_dependent_expression_p here, as it can lead
+ to infinite recursion trying to determine whether a lambda
+ nested in a lambda is dependent (c++/47687). */
+ else if (scope && TREE_CODE (scope) == FUNCTION_DECL
+ && DECL_LANG_SPECIFIC (scope)
+ && DECL_TEMPLATE_INFO (scope)
+ && (any_dependent_template_arguments_p
+ (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (scope)))))
+ return true;
+
+ /* Other types are non-dependent. */
+ return false;
+}
+
+/* Returns TRUE if TYPE is dependent, in the sense of
+ [temp.dep.type]. Note that a NULL type is considered dependent. */
+
+bool
+dependent_type_p (tree type)
+{
+ /* If there are no template parameters in scope, then there can't be
+ any dependent types. */
+ if (!processing_template_decl)
+ {
+ /* If we are not processing a template, then nobody should be
+ providing us with a dependent type. */
+ gcc_assert (type);
+ gcc_assert (TREE_CODE (type) != TEMPLATE_TYPE_PARM || is_auto (type));
+ return false;
+ }
+
+ /* If the type is NULL, we have not computed a type for the entity
+ in question; in that case, the type is dependent. */
+ if (!type)
+ return true;
+
+ /* Erroneous types can be considered non-dependent. */
+ if (type == error_mark_node)
+ return false;
+
+ /* If we have not already computed the appropriate value for TYPE,
+ do so now. */
+ if (!TYPE_DEPENDENT_P_VALID (type))
+ {
+ TYPE_DEPENDENT_P (type) = dependent_type_p_r (type);
+ TYPE_DEPENDENT_P_VALID (type) = 1;
+ }
+
+ return TYPE_DEPENDENT_P (type);
+}
+
+/* Returns TRUE if SCOPE is a dependent scope, in which we can't do any
+ lookup. In other words, a dependent type that is not the current
+ instantiation. */
+
+bool
+dependent_scope_p (tree scope)
+{
+ return (scope && TYPE_P (scope) && dependent_type_p (scope)
+ && !currently_open_class (scope));
+}
+
+/* T is a SCOPE_REF; return whether we need to consider it
+ instantiation-dependent so that we can check access at instantiation
+ time even though we know which member it resolves to. */
+
+static bool
+instantiation_dependent_scope_ref_p (tree t)
+{
+ if (DECL_P (TREE_OPERAND (t, 1))
+ && CLASS_TYPE_P (TREE_OPERAND (t, 0))
+ && accessible_in_template_p (TREE_OPERAND (t, 0),
+ TREE_OPERAND (t, 1)))
+ return false;
+ else
+ return true;
+}
+
+/* Returns TRUE if the EXPRESSION is value-dependent, in the sense of
+ [temp.dep.constexpr]. EXPRESSION is already known to be a constant
+ expression. */
+
+/* Note that this predicate is not appropriate for general expressions;
+ only constant expressions (that satisfy potential_constant_expression)
+ can be tested for value dependence. */
+
+bool
+value_dependent_expression_p (tree expression)
+{
+ if (!processing_template_decl)
+ return false;
+
+ /* A name declared with a dependent type. */
+ if (DECL_P (expression) && type_dependent_expression_p (expression))
+ return true;
+
+ switch (TREE_CODE (expression))
+ {
+ case IDENTIFIER_NODE:
+ /* A name that has not been looked up -- must be dependent. */
+ return true;
+
+ case TEMPLATE_PARM_INDEX:
+ /* A non-type template parm. */
+ return true;
+
+ case CONST_DECL:
+ /* A non-type template parm. */
+ if (DECL_TEMPLATE_PARM_P (expression))
+ return true;
+ return value_dependent_expression_p (DECL_INITIAL (expression));
+
+ case VAR_DECL:
+ /* A constant with literal type and is initialized
+ with an expression that is value-dependent.
+
+ Note that a non-dependent parenthesized initializer will have
+ already been replaced with its constant value, so if we see
+ a TREE_LIST it must be dependent. */
+ if (DECL_INITIAL (expression)
+ && decl_constant_var_p (expression)
+ && (TREE_CODE (DECL_INITIAL (expression)) == TREE_LIST
+ || value_dependent_expression_p (DECL_INITIAL (expression))))
+ return true;
+ return false;
+
+ case DYNAMIC_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CAST_EXPR:
+ /* These expressions are value-dependent if the type to which
+ the cast occurs is dependent or the expression being casted
+ is value-dependent. */
+ {
+ tree type = TREE_TYPE (expression);
+
+ if (dependent_type_p (type))
+ return true;
+
+ /* A functional cast has a list of operands. */
+ expression = TREE_OPERAND (expression, 0);
+ if (!expression)
+ {
+ /* If there are no operands, it must be an expression such
+ as "int()". This should not happen for aggregate types
+ because it would form non-constant expressions. */
+ gcc_assert (cxx_dialect >= cxx11
+ || INTEGRAL_OR_ENUMERATION_TYPE_P (type));
+
+ return false;
+ }
+
+ if (TREE_CODE (expression) == TREE_LIST)
+ return any_value_dependent_elements_p (expression);
+
+ return value_dependent_expression_p (expression);
+ }
+
+ case SIZEOF_EXPR:
+ if (SIZEOF_EXPR_TYPE_P (expression))
+ return dependent_type_p (TREE_TYPE (TREE_OPERAND (expression, 0)));
+ /* FALLTHRU */
+ case ALIGNOF_EXPR:
+ case TYPEID_EXPR:
+ /* A `sizeof' expression is value-dependent if the operand is
+ type-dependent or is a pack expansion. */
+ expression = TREE_OPERAND (expression, 0);
+ if (PACK_EXPANSION_P (expression))
+ return true;
+ else if (TYPE_P (expression))
+ return dependent_type_p (expression);
+ return instantiation_dependent_expression_p (expression);
+
+ case AT_ENCODE_EXPR:
+ /* An 'encode' expression is value-dependent if the operand is
+ type-dependent. */
+ expression = TREE_OPERAND (expression, 0);
+ return dependent_type_p (expression);
+
+ case NOEXCEPT_EXPR:
+ expression = TREE_OPERAND (expression, 0);
+ return instantiation_dependent_expression_p (expression);
+
+ case SCOPE_REF:
+ /* All instantiation-dependent expressions should also be considered
+ value-dependent. */
+ return instantiation_dependent_scope_ref_p (expression);
+
+ case COMPONENT_REF:
+ return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
+ || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
+
+ case NONTYPE_ARGUMENT_PACK:
+ /* A NONTYPE_ARGUMENT_PACK is value-dependent if any packed argument
+ is value-dependent. */
+ {
+ tree values = ARGUMENT_PACK_ARGS (expression);
+ int i, len = TREE_VEC_LENGTH (values);
+
+ for (i = 0; i < len; ++i)
+ if (value_dependent_expression_p (TREE_VEC_ELT (values, i)))
+ return true;
+
+ return false;
+ }
+
+ case TRAIT_EXPR:
+ {
+ tree type2 = TRAIT_EXPR_TYPE2 (expression);
+ return (dependent_type_p (TRAIT_EXPR_TYPE1 (expression))
+ || (type2 ? dependent_type_p (type2) : false));
+ }
+
+ case MODOP_EXPR:
+ return ((value_dependent_expression_p (TREE_OPERAND (expression, 0)))
+ || (value_dependent_expression_p (TREE_OPERAND (expression, 2))));
+
+ case ARRAY_REF:
+ return ((value_dependent_expression_p (TREE_OPERAND (expression, 0)))
+ || (value_dependent_expression_p (TREE_OPERAND (expression, 1))));
+
+ case ADDR_EXPR:
+ {
+ tree op = TREE_OPERAND (expression, 0);
+ return (value_dependent_expression_p (op)
+ || has_value_dependent_address (op));
+ }
+
+ case CALL_EXPR:
+ {
+ tree fn = get_callee_fndecl (expression);
+ int i, nargs;
+ if (!fn && value_dependent_expression_p (CALL_EXPR_FN (expression)))
+ return true;
+ nargs = call_expr_nargs (expression);
+ for (i = 0; i < nargs; ++i)
+ {
+ tree op = CALL_EXPR_ARG (expression, i);
+ /* In a call to a constexpr member function, look through the
+ implicit ADDR_EXPR on the object argument so that it doesn't
+ cause the call to be considered value-dependent. We also
+ look through it in potential_constant_expression. */
+ if (i == 0 && fn && DECL_DECLARED_CONSTEXPR_P (fn)
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && TREE_CODE (op) == ADDR_EXPR)
+ op = TREE_OPERAND (op, 0);
+ if (value_dependent_expression_p (op))
+ return true;
+ }
+ return false;
+ }
+
+ case TEMPLATE_ID_EXPR:
+ /* If a TEMPLATE_ID_EXPR involves a dependent name, it will be
+ type-dependent. */
+ return type_dependent_expression_p (expression);
+
+ case CONSTRUCTOR:
+ {
+ unsigned ix;
+ tree val;
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expression), ix, val)
+ if (value_dependent_expression_p (val))
+ return true;
+ return false;
+ }
+
+ case STMT_EXPR:
+ /* Treat a GNU statement expression as dependent to avoid crashing
+ under fold_non_dependent_expr; it can't be constant. */
+ return true;
+
+ default:
+ /* A constant expression is value-dependent if any subexpression is
+ value-dependent. */
+ switch (TREE_CODE_CLASS (TREE_CODE (expression)))
+ {
+ case tcc_reference:
+ case tcc_unary:
+ case tcc_comparison:
+ case tcc_binary:
+ case tcc_expression:
+ case tcc_vl_exp:
+ {
+ int i, len = cp_tree_operand_length (expression);
+
+ for (i = 0; i < len; i++)
+ {
+ tree t = TREE_OPERAND (expression, i);
+
+ /* In some cases, some of the operands may be missing.l
+ (For example, in the case of PREDECREMENT_EXPR, the
+ amount to increment by may be missing.) That doesn't
+ make the expression dependent. */
+ if (t && value_dependent_expression_p (t))
+ return true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ /* The expression is not value-dependent. */
+ return false;
+}
+
+/* Returns TRUE if the EXPRESSION is type-dependent, in the sense of
+ [temp.dep.expr]. Note that an expression with no type is
+ considered dependent. Other parts of the compiler arrange for an
+ expression with type-dependent subexpressions to have no type, so
+ this function doesn't have to be fully recursive. */
+
+bool
+type_dependent_expression_p (tree expression)
+{
+ if (!processing_template_decl)
+ return false;
+
+ if (expression == NULL_TREE || expression == error_mark_node)
+ return false;
+
+ /* An unresolved name is always dependent. */
+ if (identifier_p (expression) || TREE_CODE (expression) == USING_DECL)
+ return true;
+
+ /* Some expression forms are never type-dependent. */
+ if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR
+ || TREE_CODE (expression) == SIZEOF_EXPR
+ || TREE_CODE (expression) == ALIGNOF_EXPR
+ || TREE_CODE (expression) == AT_ENCODE_EXPR
+ || TREE_CODE (expression) == NOEXCEPT_EXPR
+ || TREE_CODE (expression) == TRAIT_EXPR
+ || TREE_CODE (expression) == TYPEID_EXPR
+ || TREE_CODE (expression) == DELETE_EXPR
+ || TREE_CODE (expression) == VEC_DELETE_EXPR
+ || TREE_CODE (expression) == THROW_EXPR)
+ return false;
+
+ /* The types of these expressions depends only on the type to which
+ the cast occurs. */
+ if (TREE_CODE (expression) == DYNAMIC_CAST_EXPR
+ || TREE_CODE (expression) == STATIC_CAST_EXPR
+ || TREE_CODE (expression) == CONST_CAST_EXPR
+ || TREE_CODE (expression) == REINTERPRET_CAST_EXPR
+ || TREE_CODE (expression) == IMPLICIT_CONV_EXPR
+ || TREE_CODE (expression) == CAST_EXPR)
+ return dependent_type_p (TREE_TYPE (expression));
+
+ /* The types of these expressions depends only on the type created
+ by the expression. */
+ if (TREE_CODE (expression) == NEW_EXPR
+ || TREE_CODE (expression) == VEC_NEW_EXPR)
+ {
+ /* For NEW_EXPR tree nodes created inside a template, either
+ the object type itself or a TREE_LIST may appear as the
+ operand 1. */
+ tree type = TREE_OPERAND (expression, 1);
+ if (TREE_CODE (type) == TREE_LIST)
+ /* This is an array type. We need to check array dimensions
+ as well. */
+ return dependent_type_p (TREE_VALUE (TREE_PURPOSE (type)))
+ || value_dependent_expression_p
+ (TREE_OPERAND (TREE_VALUE (type), 1));
+ else
+ return dependent_type_p (type);
+ }
+
+ if (TREE_CODE (expression) == SCOPE_REF)
+ {
+ tree scope = TREE_OPERAND (expression, 0);
+ tree name = TREE_OPERAND (expression, 1);
+
+ /* 14.6.2.2 [temp.dep.expr]: An id-expression is type-dependent if it
+ contains an identifier associated by name lookup with one or more
+ declarations declared with a dependent type, or...a
+ nested-name-specifier or qualified-id that names a member of an
+ unknown specialization. */
+ return (type_dependent_expression_p (name)
+ || dependent_scope_p (scope));
+ }
+
+ if (TREE_CODE (expression) == FUNCTION_DECL
+ && DECL_LANG_SPECIFIC (expression)
+ && DECL_TEMPLATE_INFO (expression)
+ && (any_dependent_template_arguments_p
+ (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
+ return true;
+
+ if (TREE_CODE (expression) == TEMPLATE_DECL
+ && !DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
+ return false;
+
+ if (TREE_CODE (expression) == STMT_EXPR)
+ expression = stmt_expr_value_expr (expression);
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (expression))
+ {
+ tree elt;
+ unsigned i;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expression), i, elt)
+ {
+ if (type_dependent_expression_p (elt))
+ return true;
+ }
+ return false;
+ }
+
+ /* A static data member of the current instantiation with incomplete
+ array type is type-dependent, as the definition and specializations
+ can have different bounds. */
+ if (VAR_P (expression)
+ && DECL_CLASS_SCOPE_P (expression)
+ && dependent_type_p (DECL_CONTEXT (expression))
+ && VAR_HAD_UNKNOWN_BOUND (expression))
+ return true;
+
+ /* An array of unknown bound depending on a variadic parameter, eg:
+
+ template<typename... Args>
+ void foo (Args... args)
+ {
+ int arr[] = { args... };
+ }
+
+ template<int... vals>
+ void bar ()
+ {
+ int arr[] = { vals... };
+ }
+
+ If the array has no length and has an initializer, it must be that
+ we couldn't determine its length in cp_complete_array_type because
+ it is dependent. */
+ if (VAR_P (expression)
+ && TREE_CODE (TREE_TYPE (expression)) == ARRAY_TYPE
+ && !TYPE_DOMAIN (TREE_TYPE (expression))
+ && DECL_INITIAL (expression))
+ return true;
+
+ if (TREE_TYPE (expression) == unknown_type_node)
+ {
+ if (TREE_CODE (expression) == ADDR_EXPR)
+ return type_dependent_expression_p (TREE_OPERAND (expression, 0));
+ if (TREE_CODE (expression) == COMPONENT_REF
+ || TREE_CODE (expression) == OFFSET_REF)
+ {
+ if (type_dependent_expression_p (TREE_OPERAND (expression, 0)))
+ return true;
+ expression = TREE_OPERAND (expression, 1);
+ if (identifier_p (expression))
+ return false;
+ }
+ /* SCOPE_REF with non-null TREE_TYPE is always non-dependent. */
+ if (TREE_CODE (expression) == SCOPE_REF)
+ return false;
+
+ /* Always dependent, on the number of arguments if nothing else. */
+ if (TREE_CODE (expression) == EXPR_PACK_EXPANSION)
+ return true;
+
+ if (BASELINK_P (expression))
+ expression = BASELINK_FUNCTIONS (expression);
+
+ if (TREE_CODE (expression) == TEMPLATE_ID_EXPR)
+ {
+ if (any_dependent_template_arguments_p
+ (TREE_OPERAND (expression, 1)))
+ return true;
+ expression = TREE_OPERAND (expression, 0);
+ }
+ gcc_assert (TREE_CODE (expression) == OVERLOAD
+ || TREE_CODE (expression) == FUNCTION_DECL);
+
+ while (expression)
+ {
+ if (type_dependent_expression_p (OVL_CURRENT (expression)))
+ return true;
+ expression = OVL_NEXT (expression);
+ }
+ return false;
+ }
+
+ gcc_assert (TREE_CODE (expression) != TYPE_DECL);
+
+ return (dependent_type_p (TREE_TYPE (expression)));
+}
+
+/* walk_tree callback function for instantiation_dependent_expression_p,
+ below. Returns non-zero if a dependent subexpression is found. */
+
+static tree
+instantiation_dependent_r (tree *tp, int *walk_subtrees,
+ void * /*data*/)
+{
+ if (TYPE_P (*tp))
+ {
+ /* We don't have to worry about decltype currently because decltype
+ of an instantiation-dependent expr is a dependent type. This
+ might change depending on the resolution of DR 1172. */
+ *walk_subtrees = false;
+ return NULL_TREE;
+ }
+ enum tree_code code = TREE_CODE (*tp);
+ switch (code)
+ {
+ /* Don't treat an argument list as dependent just because it has no
+ TREE_TYPE. */
+ case TREE_LIST:
+ case TREE_VEC:
+ return NULL_TREE;
+
+ case VAR_DECL:
+ case CONST_DECL:
+ /* A constant with a dependent initializer is dependent. */
+ if (value_dependent_expression_p (*tp))
+ return *tp;
+ break;
+
+ case TEMPLATE_PARM_INDEX:
+ return *tp;
+
+ /* Handle expressions with type operands. */
+ case SIZEOF_EXPR:
+ case ALIGNOF_EXPR:
+ case TYPEID_EXPR:
+ case AT_ENCODE_EXPR:
+ {
+ tree op = TREE_OPERAND (*tp, 0);
+ if (code == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (*tp))
+ op = TREE_TYPE (op);
+ if (TYPE_P (op))
+ {
+ if (dependent_type_p (op))
+ return *tp;
+ else
+ {
+ *walk_subtrees = false;
+ return NULL_TREE;
+ }
+ }
+ break;
+ }
+
+ case TRAIT_EXPR:
+ if (dependent_type_p (TRAIT_EXPR_TYPE1 (*tp))
+ || (TRAIT_EXPR_TYPE2 (*tp)
+ && dependent_type_p (TRAIT_EXPR_TYPE2 (*tp))))
+ return *tp;
+ *walk_subtrees = false;
+ return NULL_TREE;
+
+ case COMPONENT_REF:
+ if (identifier_p (TREE_OPERAND (*tp, 1)))
+ /* In a template, finish_class_member_access_expr creates a
+ COMPONENT_REF with an IDENTIFIER_NODE for op1 even if it isn't
+ type-dependent, so that we can check access control at
+ instantiation time (PR 42277). See also Core issue 1273. */
+ return *tp;
+ break;
+
+ case SCOPE_REF:
+ if (instantiation_dependent_scope_ref_p (*tp))
+ return *tp;
+ else
+ break;
+
+ /* Treat statement-expressions as dependent. */
+ case BIND_EXPR:
+ return *tp;
+
+ default:
+ break;
+ }
+
+ if (type_dependent_expression_p (*tp))
+ return *tp;
+ else
+ return NULL_TREE;
+}
+
+/* Returns TRUE if the EXPRESSION is instantiation-dependent, in the
+ sense defined by the ABI:
+
+ "An expression is instantiation-dependent if it is type-dependent
+ or value-dependent, or it has a subexpression that is type-dependent
+ or value-dependent." */
+
+bool
+instantiation_dependent_expression_p (tree expression)
+{
+ tree result;
+
+ if (!processing_template_decl)
+ return false;
+
+ if (expression == error_mark_node)
+ return false;
+
+ result = cp_walk_tree_without_duplicates (&expression,
+ instantiation_dependent_r, NULL);
+ return result != NULL_TREE;
+}
+
+/* Like type_dependent_expression_p, but it also works while not processing
+ a template definition, i.e. during substitution or mangling. */
+
+bool
+type_dependent_expression_p_push (tree expr)
+{
+ bool b;
+ ++processing_template_decl;
+ b = type_dependent_expression_p (expr);
+ --processing_template_decl;
+ return b;
+}
+
+/* Returns TRUE if ARGS contains a type-dependent expression. */
+
+bool
+any_type_dependent_arguments_p (const vec<tree, va_gc> *args)
+{
+ unsigned int i;
+ tree arg;
+
+ FOR_EACH_VEC_SAFE_ELT (args, i, arg)
+ {
+ if (type_dependent_expression_p (arg))
+ return true;
+ }
+ return false;
+}
+
+/* Returns TRUE if LIST (a TREE_LIST whose TREE_VALUEs are
+ expressions) contains any type-dependent expressions. */
+
+bool
+any_type_dependent_elements_p (const_tree list)
+{
+ for (; list; list = TREE_CHAIN (list))
+ if (type_dependent_expression_p (TREE_VALUE (list)))
+ return true;
+
+ return false;
+}
+
+/* Returns TRUE if LIST (a TREE_LIST whose TREE_VALUEs are
+ expressions) contains any value-dependent expressions. */
+
+bool
+any_value_dependent_elements_p (const_tree list)
+{
+ for (; list; list = TREE_CHAIN (list))
+ if (value_dependent_expression_p (TREE_VALUE (list)))
+ return true;
+
+ return false;
+}
+
+/* Returns TRUE if the ARG (a template argument) is dependent. */
+
+bool
+dependent_template_arg_p (tree arg)
+{
+ if (!processing_template_decl)
+ return false;
+
+ /* Assume a template argument that was wrongly written by the user
+ is dependent. This is consistent with what
+ any_dependent_template_arguments_p [that calls this function]
+ does. */
+ if (!arg || arg == error_mark_node)
+ return true;
+
+ if (TREE_CODE (arg) == ARGUMENT_PACK_SELECT)
+ arg = ARGUMENT_PACK_SELECT_ARG (arg);
+
+ if (TREE_CODE (arg) == TEMPLATE_DECL
+ || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+ return dependent_template_p (arg);
+ else if (ARGUMENT_PACK_P (arg))
+ {
+ tree args = ARGUMENT_PACK_ARGS (arg);
+ int i, len = TREE_VEC_LENGTH (args);
+ for (i = 0; i < len; ++i)
+ {
+ if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
+ return true;
+ }
+
+ return false;
+ }
+ else if (TYPE_P (arg))
+ return dependent_type_p (arg);
+ else
+ return (type_dependent_expression_p (arg)
+ || value_dependent_expression_p (arg));
+}
+
+/* Returns true if ARGS (a collection of template arguments) contains
+ any types that require structural equality testing. */
+
+bool
+any_template_arguments_need_structural_equality_p (tree args)
+{
+ int i;
+ int j;
+
+ if (!args)
+ return false;
+ if (args == error_mark_node)
+ return true;
+
+ for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
+ {
+ tree level = TMPL_ARGS_LEVEL (args, i + 1);
+ for (j = 0; j < TREE_VEC_LENGTH (level); ++j)
+ {
+ tree arg = TREE_VEC_ELT (level, j);
+ tree packed_args = NULL_TREE;
+ int k, len = 1;
+
+ if (ARGUMENT_PACK_P (arg))
+ {
+ /* Look inside the argument pack. */
+ packed_args = ARGUMENT_PACK_ARGS (arg);
+ len = TREE_VEC_LENGTH (packed_args);
+ }
+
+ for (k = 0; k < len; ++k)
+ {
+ if (packed_args)
+ arg = TREE_VEC_ELT (packed_args, k);
+
+ if (error_operand_p (arg))
+ return true;
+ else if (TREE_CODE (arg) == TEMPLATE_DECL)
+ continue;
+ else if (TYPE_P (arg) && TYPE_STRUCTURAL_EQUALITY_P (arg))
+ return true;
+ else if (!TYPE_P (arg) && TREE_TYPE (arg)
+ && TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (arg)))
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/* Returns true if ARGS (a collection of template arguments) contains
+ any dependent arguments. */
+
+bool
+any_dependent_template_arguments_p (const_tree args)
+{
+ int i;
+ int j;
+
+ if (!args)
+ return false;
+ if (args == error_mark_node)
+ return true;
+
+ for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
+ {
+ const_tree level = TMPL_ARGS_LEVEL (args, i + 1);
+ for (j = 0; j < TREE_VEC_LENGTH (level); ++j)
+ if (dependent_template_arg_p (TREE_VEC_ELT (level, j)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Returns TRUE if the template TMPL is dependent. */
+
+bool
+dependent_template_p (tree tmpl)
+{
+ if (TREE_CODE (tmpl) == OVERLOAD)
+ {
+ while (tmpl)
+ {
+ if (dependent_template_p (OVL_CURRENT (tmpl)))
+ return true;
+ tmpl = OVL_NEXT (tmpl);
+ }
+ return false;
+ }
+
+ /* Template template parameters are dependent. */
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)
+ || TREE_CODE (tmpl) == TEMPLATE_TEMPLATE_PARM)
+ return true;
+ /* So are names that have not been looked up. */
+ if (TREE_CODE (tmpl) == SCOPE_REF || identifier_p (tmpl))
+ return true;
+ /* So are member templates of dependent classes. */
+ if (TYPE_P (CP_DECL_CONTEXT (tmpl)))
+ return dependent_type_p (DECL_CONTEXT (tmpl));
+ return false;
+}
+
+/* Returns TRUE if the specialization TMPL<ARGS> is dependent. */
+
+bool
+dependent_template_id_p (tree tmpl, tree args)
+{
+ return (dependent_template_p (tmpl)
+ || any_dependent_template_arguments_p (args));
+}
+
+/* Returns TRUE if OMP_FOR with DECLV, INITV, CONDV and INCRV vectors
+ is dependent. */
+
+bool
+dependent_omp_for_p (tree declv, tree initv, tree condv, tree incrv)
+{
+ int i;
+
+ if (!processing_template_decl)
+ return false;
+
+ for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
+ {
+ tree decl = TREE_VEC_ELT (declv, i);
+ tree init = TREE_VEC_ELT (initv, i);
+ tree cond = TREE_VEC_ELT (condv, i);
+ tree incr = TREE_VEC_ELT (incrv, i);
+
+ if (type_dependent_expression_p (decl))
+ return true;
+
+ if (init && type_dependent_expression_p (init))
+ return true;
+
+ if (type_dependent_expression_p (cond))
+ return true;
+
+ if (COMPARISON_CLASS_P (cond)
+ && (type_dependent_expression_p (TREE_OPERAND (cond, 0))
+ || type_dependent_expression_p (TREE_OPERAND (cond, 1))))
+ return true;
+
+ if (TREE_CODE (incr) == MODOP_EXPR)
+ {
+ if (type_dependent_expression_p (TREE_OPERAND (incr, 0))
+ || type_dependent_expression_p (TREE_OPERAND (incr, 2)))
+ return true;
+ }
+ else if (type_dependent_expression_p (incr))
+ return true;
+ else if (TREE_CODE (incr) == MODIFY_EXPR)
+ {
+ if (type_dependent_expression_p (TREE_OPERAND (incr, 0)))
+ return true;
+ else if (BINARY_CLASS_P (TREE_OPERAND (incr, 1)))
+ {
+ tree t = TREE_OPERAND (incr, 1);
+ if (type_dependent_expression_p (TREE_OPERAND (t, 0))
+ || type_dependent_expression_p (TREE_OPERAND (t, 1)))
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/* TYPE is a TYPENAME_TYPE. Returns the ordinary TYPE to which the
+ TYPENAME_TYPE corresponds. Returns the original TYPENAME_TYPE if
+ no such TYPE can be found. Note that this function peers inside
+ uninstantiated templates and therefore should be used only in
+ extremely limited situations. ONLY_CURRENT_P restricts this
+ peering to the currently open classes hierarchy (which is required
+ when comparing types). */
+
+tree
+resolve_typename_type (tree type, bool only_current_p)
+{
+ tree scope;
+ tree name;
+ tree decl;
+ int quals;
+ tree pushed_scope;
+ tree result;
+
+ gcc_assert (TREE_CODE (type) == TYPENAME_TYPE);
+
+ scope = TYPE_CONTEXT (type);
+ /* Usually the non-qualified identifier of a TYPENAME_TYPE is
+ TYPE_IDENTIFIER (type). But when 'type' is a typedef variant of
+ a TYPENAME_TYPE node, then TYPE_NAME (type) is set to the TYPE_DECL representing
+ the typedef. In that case TYPE_IDENTIFIER (type) is not the non-qualified
+ identifier of the TYPENAME_TYPE anymore.
+ So by getting the TYPE_IDENTIFIER of the _main declaration_ of the
+ TYPENAME_TYPE instead, we avoid messing up with a possible
+ typedef variant case. */
+ name = TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (type));
+
+ /* If the SCOPE is itself a TYPENAME_TYPE, then we need to resolve
+ it first before we can figure out what NAME refers to. */
+ if (TREE_CODE (scope) == TYPENAME_TYPE)
+ {
+ if (TYPENAME_IS_RESOLVING_P (scope))
+ /* Given a class template A with a dependent base with nested type C,
+ typedef typename A::C::C C will land us here, as trying to resolve
+ the initial A::C leads to the local C typedef, which leads back to
+ A::C::C. So we break the recursion now. */
+ return type;
+ else
+ scope = resolve_typename_type (scope, only_current_p);
+ }
+ /* If we don't know what SCOPE refers to, then we cannot resolve the
+ TYPENAME_TYPE. */
+ if (TREE_CODE (scope) == TYPENAME_TYPE)
+ return type;
+ /* If the SCOPE is a template type parameter, we have no way of
+ resolving the name. */
+ if (TREE_CODE (scope) == TEMPLATE_TYPE_PARM)
+ return type;
+ /* If the SCOPE is not the current instantiation, there's no reason
+ to look inside it. */
+ if (only_current_p && !currently_open_class (scope))
+ return type;
+ /* If this is a typedef, we don't want to look inside (c++/11987). */
+ if (typedef_variant_p (type))
+ return type;
+ /* If SCOPE isn't the template itself, it will not have a valid
+ TYPE_FIELDS list. */
+ if (same_type_p (scope, CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope)))
+ /* scope is either the template itself or a compatible instantiation
+ like X<T>, so look up the name in the original template. */
+ scope = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope);
+ else
+ /* scope is a partial instantiation, so we can't do the lookup or we
+ will lose the template arguments. */
+ return type;
+ /* Enter the SCOPE so that name lookup will be resolved as if we
+ were in the class definition. In particular, SCOPE will no
+ longer be considered a dependent type. */
+ pushed_scope = push_scope (scope);
+ /* Look up the declaration. */
+ decl = lookup_member (scope, name, /*protect=*/0, /*want_type=*/true,
+ tf_warning_or_error);
+
+ result = NULL_TREE;
+
+ /* For a TYPENAME_TYPE like "typename X::template Y<T>", we want to
+ find a TEMPLATE_DECL. Otherwise, we want to find a TYPE_DECL. */
+ if (!decl)
+ /*nop*/;
+ else if (identifier_p (TYPENAME_TYPE_FULLNAME (type))
+ && TREE_CODE (decl) == TYPE_DECL)
+ {
+ result = TREE_TYPE (decl);
+ if (result == error_mark_node)
+ result = NULL_TREE;
+ }
+ else if (TREE_CODE (TYPENAME_TYPE_FULLNAME (type)) == TEMPLATE_ID_EXPR
+ && DECL_CLASS_TEMPLATE_P (decl))
+ {
+ tree tmpl;
+ tree args;
+ /* Obtain the template and the arguments. */
+ tmpl = TREE_OPERAND (TYPENAME_TYPE_FULLNAME (type), 0);
+ args = TREE_OPERAND (TYPENAME_TYPE_FULLNAME (type), 1);
+ /* Instantiate the template. */
+ result = lookup_template_class (tmpl, args, NULL_TREE, NULL_TREE,
+ /*entering_scope=*/0,
+ tf_error | tf_user);
+ if (result == error_mark_node)
+ result = NULL_TREE;
+ }
+
+ /* Leave the SCOPE. */
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+
+ /* If we failed to resolve it, return the original typename. */
+ if (!result)
+ return type;
+
+ /* If lookup found a typename type, resolve that too. */
+ if (TREE_CODE (result) == TYPENAME_TYPE && !TYPENAME_IS_RESOLVING_P (result))
+ {
+ /* Ill-formed programs can cause infinite recursion here, so we
+ must catch that. */
+ TYPENAME_IS_RESOLVING_P (type) = 1;
+ result = resolve_typename_type (result, only_current_p);
+ TYPENAME_IS_RESOLVING_P (type) = 0;
+ }
+
+ /* Qualify the resulting type. */
+ quals = cp_type_quals (type);
+ if (quals)
+ result = cp_build_qualified_type (result, cp_type_quals (result) | quals);
+
+ return result;
+}
+
+/* EXPR is an expression which is not type-dependent. Return a proxy
+ for EXPR that can be used to compute the types of larger
+ expressions containing EXPR. */
+
+tree
+build_non_dependent_expr (tree expr)
+{
+ tree inner_expr;
+
+#ifdef ENABLE_CHECKING
+ /* Try to get a constant value for all non-dependent expressions in
+ order to expose bugs in *_dependent_expression_p and constexpr. */
+ if (cxx_dialect >= cxx11)
+ maybe_constant_value (fold_non_dependent_expr_sfinae (expr, tf_none));
+#endif
+
+ /* Preserve OVERLOADs; the functions must be available to resolve
+ types. */
+ inner_expr = expr;
+ if (TREE_CODE (inner_expr) == STMT_EXPR)
+ inner_expr = stmt_expr_value_expr (inner_expr);
+ if (TREE_CODE (inner_expr) == ADDR_EXPR)
+ inner_expr = TREE_OPERAND (inner_expr, 0);
+ if (TREE_CODE (inner_expr) == COMPONENT_REF)
+ inner_expr = TREE_OPERAND (inner_expr, 1);
+ if (is_overloaded_fn (inner_expr)
+ || TREE_CODE (inner_expr) == OFFSET_REF)
+ return expr;
+ /* There is no need to return a proxy for a variable. */
+ if (VAR_P (expr))
+ return expr;
+ /* Preserve string constants; conversions from string constants to
+ "char *" are allowed, even though normally a "const char *"
+ cannot be used to initialize a "char *". */
+ if (TREE_CODE (expr) == STRING_CST)
+ return expr;
+ /* Preserve arithmetic constants, as an optimization -- there is no
+ reason to create a new node. */
+ if (TREE_CODE (expr) == INTEGER_CST || TREE_CODE (expr) == REAL_CST)
+ return expr;
+ /* Preserve THROW_EXPRs -- all throw-expressions have type "void".
+ There is at least one place where we want to know that a
+ particular expression is a throw-expression: when checking a ?:
+ expression, there are special rules if the second or third
+ argument is a throw-expression. */
+ if (TREE_CODE (expr) == THROW_EXPR)
+ return expr;
+
+ /* Don't wrap an initializer list, we need to be able to look inside. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+ return expr;
+
+ /* Don't wrap a dummy object, we need to be able to test for it. */
+ if (is_dummy_object (expr))
+ return expr;
+
+ if (TREE_CODE (expr) == COND_EXPR)
+ return build3 (COND_EXPR,
+ TREE_TYPE (expr),
+ TREE_OPERAND (expr, 0),
+ (TREE_OPERAND (expr, 1)
+ ? build_non_dependent_expr (TREE_OPERAND (expr, 1))
+ : build_non_dependent_expr (TREE_OPERAND (expr, 0))),
+ build_non_dependent_expr (TREE_OPERAND (expr, 2)));
+ if (TREE_CODE (expr) == COMPOUND_EXPR
+ && !COMPOUND_EXPR_OVERLOADED (expr))
+ return build2 (COMPOUND_EXPR,
+ TREE_TYPE (expr),
+ TREE_OPERAND (expr, 0),
+ build_non_dependent_expr (TREE_OPERAND (expr, 1)));
+
+ /* If the type is unknown, it can't really be non-dependent */
+ gcc_assert (TREE_TYPE (expr) != unknown_type_node);
+
+ /* Otherwise, build a NON_DEPENDENT_EXPR. */
+ return build1 (NON_DEPENDENT_EXPR, TREE_TYPE (expr), expr);
+}
+
+/* ARGS is a vector of expressions as arguments to a function call.
+ Replace the arguments with equivalent non-dependent expressions.
+ This modifies ARGS in place. */
+
+void
+make_args_non_dependent (vec<tree, va_gc> *args)
+{
+ unsigned int ix;
+ tree arg;
+
+ FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
+ {
+ tree newarg = build_non_dependent_expr (arg);
+ if (newarg != arg)
+ (*args)[ix] = newarg;
+ }
+}
+
+/* Returns a type which represents 'auto' or 'decltype(auto)'. We use a
+ TEMPLATE_TYPE_PARM with a level one deeper than the actual template
+ parms. */
+
+static tree
+make_auto_1 (tree name)
+{
+ tree au = cxx_make_type (TEMPLATE_TYPE_PARM);
+ TYPE_NAME (au) = build_decl (input_location,
+ TYPE_DECL, name, au);
+ TYPE_STUB_DECL (au) = TYPE_NAME (au);
+ TEMPLATE_TYPE_PARM_INDEX (au) = build_template_parm_index
+ (0, processing_template_decl + 1, processing_template_decl + 1,
+ TYPE_NAME (au), NULL_TREE);
+ TYPE_CANONICAL (au) = canonical_type_parameter (au);
+ DECL_ARTIFICIAL (TYPE_NAME (au)) = 1;
+ SET_DECL_TEMPLATE_PARM_P (TYPE_NAME (au));
+
+ return au;
+}
+
+tree
+make_decltype_auto (void)
+{
+ return make_auto_1 (get_identifier ("decltype(auto)"));
+}
+
+tree
+make_auto (void)
+{
+ return make_auto_1 (get_identifier ("auto"));
+}
+
+/* Given type ARG, return std::initializer_list<ARG>. */
+
+static tree
+listify (tree arg)
+{
+ tree std_init_list = namespace_binding
+ (get_identifier ("initializer_list"), std_node);
+ tree argvec;
+ if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
+ {
+ error ("deducing from brace-enclosed initializer list requires "
+ "#include <initializer_list>");
+ return error_mark_node;
+ }
+ argvec = make_tree_vec (1);
+ TREE_VEC_ELT (argvec, 0) = arg;
+ return lookup_template_class (std_init_list, argvec, NULL_TREE,
+ NULL_TREE, 0, tf_warning_or_error);
+}
+
+/* Replace auto in TYPE with std::initializer_list<auto>. */
+
+static tree
+listify_autos (tree type, tree auto_node)
+{
+ tree init_auto = listify (auto_node);
+ tree argvec = make_tree_vec (1);
+ TREE_VEC_ELT (argvec, 0) = init_auto;
+ if (processing_template_decl)
+ argvec = add_to_template_args (current_template_args (), argvec);
+ return tsubst (type, argvec, tf_warning_or_error, NULL_TREE);
+}
+
+/* Replace occurrences of 'auto' in TYPE with the appropriate type deduced
+ from INIT. AUTO_NODE is the TEMPLATE_TYPE_PARM used for 'auto' in TYPE. */
+
+tree
+do_auto_deduction (tree type, tree init, tree auto_node)
+{
+ tree targs;
+
+ if (init == error_mark_node)
+ return error_mark_node;
+
+ if (type_dependent_expression_p (init))
+ /* Defining a subset of type-dependent expressions that we can deduce
+ from ahead of time isn't worth the trouble. */
+ return type;
+
+ /* [dcl.spec.auto]: Obtain P from T by replacing the occurrences of auto
+ with either a new invented type template parameter U or, if the
+ initializer is a braced-init-list (8.5.4), with
+ std::initializer_list<U>. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (init))
+ type = listify_autos (type, auto_node);
+
+ init = resolve_nondeduced_context (init);
+
+ targs = make_tree_vec (1);
+ if (AUTO_IS_DECLTYPE (auto_node))
+ {
+ bool id = (DECL_P (init) || (TREE_CODE (init) == COMPONENT_REF
+ && !REF_PARENTHESIZED_P (init)));
+ TREE_VEC_ELT (targs, 0)
+ = finish_decltype_type (init, id, tf_warning_or_error);
+ if (type != auto_node)
+ {
+ error ("%qT as type rather than plain %<decltype(auto)%>", type);
+ return error_mark_node;
+ }
+ }
+ else
+ {
+ tree parms = build_tree_list (NULL_TREE, type);
+ tree tparms = make_tree_vec (1);
+ int val;
+
+ TREE_VEC_ELT (tparms, 0)
+ = build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
+ val = type_unification_real (tparms, targs, parms, &init, 1, 0,
+ DEDUCE_CALL, LOOKUP_NORMAL,
+ NULL, /*explain_p=*/false);
+ if (val > 0)
+ {
+ if (processing_template_decl)
+ /* Try again at instantiation time. */
+ return type;
+ if (type && type != error_mark_node)
+ /* If type is error_mark_node a diagnostic must have been
+ emitted by now. Also, having a mention to '<type error>'
+ in the diagnostic is not really useful to the user. */
+ {
+ if (cfun && auto_node == current_function_auto_return_pattern
+ && LAMBDA_FUNCTION_P (current_function_decl))
+ error ("unable to deduce lambda return type from %qE", init);
+ else
+ error ("unable to deduce %qT from %qE", type, init);
+ }
+ return error_mark_node;
+ }
+ }
+
+ /* If the list of declarators contains more than one declarator, the type
+ of each declared variable is determined as described above. If the
+ type deduced for the template parameter U is not the same in each
+ deduction, the program is ill-formed. */
+ if (TREE_TYPE (auto_node)
+ && !same_type_p (TREE_TYPE (auto_node), TREE_VEC_ELT (targs, 0)))
+ {
+ if (cfun && auto_node == current_function_auto_return_pattern
+ && LAMBDA_FUNCTION_P (current_function_decl))
+ error ("inconsistent types %qT and %qT deduced for "
+ "lambda return type", TREE_TYPE (auto_node),
+ TREE_VEC_ELT (targs, 0));
+ else
+ error ("inconsistent deduction for %qT: %qT and then %qT",
+ auto_node, TREE_TYPE (auto_node), TREE_VEC_ELT (targs, 0));
+ return error_mark_node;
+ }
+ TREE_TYPE (auto_node) = TREE_VEC_ELT (targs, 0);
+
+ if (processing_template_decl)
+ targs = add_to_template_args (current_template_args (), targs);
+ return tsubst (type, targs, tf_warning_or_error, NULL_TREE);
+}
+
+/* Substitutes LATE_RETURN_TYPE for 'auto' in TYPE and returns the
+ result. */
+
+tree
+splice_late_return_type (tree type, tree late_return_type)
+{
+ tree argvec;
+
+ if (late_return_type == NULL_TREE)
+ return type;
+ argvec = make_tree_vec (1);
+ TREE_VEC_ELT (argvec, 0) = late_return_type;
+ if (processing_template_parmlist)
+ /* For a late-specified return type in a template type-parameter, we
+ need to add a dummy argument level for its parmlist. */
+ argvec = add_to_template_args
+ (make_tree_vec (processing_template_parmlist), argvec);
+ if (current_template_parms)
+ argvec = add_to_template_args (current_template_args (), argvec);
+ return tsubst (type, argvec, tf_warning_or_error, NULL_TREE);
+}
+
+/* Returns true iff TYPE is a TEMPLATE_TYPE_PARM representing 'auto' or
+ 'decltype(auto)'. */
+
+bool
+is_auto (const_tree type)
+{
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
+ && (TYPE_IDENTIFIER (type) == get_identifier ("auto")
+ || TYPE_IDENTIFIER (type) == get_identifier ("decltype(auto)")))
+ return true;
+ else
+ return false;
+}
+
+/* Returns the TEMPLATE_TYPE_PARM in TYPE representing `auto' iff TYPE contains
+ a use of `auto'. Returns NULL_TREE otherwise. */
+
+tree
+type_uses_auto (tree type)
+{
+ return find_type_usage (type, is_auto);
+}
+
+/* Returns true iff TYPE is a TEMPLATE_TYPE_PARM representing 'auto',
+ 'decltype(auto)' or a concept. */
+
+bool
+is_auto_or_concept (const_tree type)
+{
+ return is_auto (type); // or concept
+}
+
+/* Returns the TEMPLATE_TYPE_PARM in TYPE representing a generic type (`auto' or
+ a concept identifier) iff TYPE contains a use of a generic type. Returns
+ NULL_TREE otherwise. */
+
+tree
+type_uses_auto_or_concept (tree type)
+{
+ return find_type_usage (type, is_auto_or_concept);
+}
+
+
+/* For a given template T, return the vector of typedefs referenced
+ in T for which access check is needed at T instantiation time.
+ T is either a FUNCTION_DECL or a RECORD_TYPE.
+ Those typedefs were added to T by the function
+ append_type_to_template_for_access_check. */
+
+vec<qualified_typedef_usage_t, va_gc> *
+get_types_needing_access_check (tree t)
+{
+ tree ti;
+ vec<qualified_typedef_usage_t, va_gc> *result = NULL;
+
+ if (!t || t == error_mark_node)
+ return NULL;
+
+ if (!(ti = get_template_info (t)))
+ return NULL;
+
+ if (CLASS_TYPE_P (t)
+ || TREE_CODE (t) == FUNCTION_DECL)
+ {
+ if (!TI_TEMPLATE (ti))
+ return NULL;
+
+ result = TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti);
+ }
+
+ return result;
+}
+
+/* Append the typedef TYPE_DECL used in template T to a list of typedefs
+ tied to T. That list of typedefs will be access checked at
+ T instantiation time.
+ T is either a FUNCTION_DECL or a RECORD_TYPE.
+ TYPE_DECL is a TYPE_DECL node representing a typedef.
+ SCOPE is the scope through which TYPE_DECL is accessed.
+ LOCATION is the location of the usage point of TYPE_DECL.
+
+ This function is a subroutine of
+ append_type_to_template_for_access_check. */
+
+static void
+append_type_to_template_for_access_check_1 (tree t,
+ tree type_decl,
+ tree scope,
+ location_t location)
+{
+ qualified_typedef_usage_t typedef_usage;
+ tree ti;
+
+ if (!t || t == error_mark_node)
+ return;
+
+ gcc_assert ((TREE_CODE (t) == FUNCTION_DECL
+ || CLASS_TYPE_P (t))
+ && type_decl
+ && TREE_CODE (type_decl) == TYPE_DECL
+ && scope);
+
+ if (!(ti = get_template_info (t)))
+ return;
+
+ gcc_assert (TI_TEMPLATE (ti));
+
+ typedef_usage.typedef_decl = type_decl;
+ typedef_usage.context = scope;
+ typedef_usage.locus = location;
+
+ vec_safe_push (TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti), typedef_usage);
+}
+
+/* Append TYPE_DECL to the template TEMPL.
+ TEMPL is either a class type, a FUNCTION_DECL or a a TEMPLATE_DECL.
+ At TEMPL instanciation time, TYPE_DECL will be checked to see
+ if it can be accessed through SCOPE.
+ LOCATION is the location of the usage point of TYPE_DECL.
+
+ e.g. consider the following code snippet:
+
+ class C
+ {
+ typedef int myint;
+ };
+
+ template<class U> struct S
+ {
+ C::myint mi; // <-- usage point of the typedef C::myint
+ };
+
+ S<char> s;
+
+ At S<char> instantiation time, we need to check the access of C::myint
+ In other words, we need to check the access of the myint typedef through
+ the C scope. For that purpose, this function will add the myint typedef
+ and the scope C through which its being accessed to a list of typedefs
+ tied to the template S. That list will be walked at template instantiation
+ time and access check performed on each typedefs it contains.
+ Note that this particular code snippet should yield an error because
+ myint is private to C. */
+
+void
+append_type_to_template_for_access_check (tree templ,
+ tree type_decl,
+ tree scope,
+ location_t location)
+{
+ qualified_typedef_usage_t *iter;
+ unsigned i;
+
+ gcc_assert (type_decl && (TREE_CODE (type_decl) == TYPE_DECL));
+
+ /* Make sure we don't append the type to the template twice. */
+ FOR_EACH_VEC_SAFE_ELT (get_types_needing_access_check (templ), i, iter)
+ if (iter->typedef_decl == type_decl && scope == iter->context)
+ return;
+
+ append_type_to_template_for_access_check_1 (templ, type_decl,
+ scope, location);
+}
+
+/* Convert the generic type parameters in PARM that match the types given in the
+ range [START_IDX, END_IDX) from the current_template_parms into generic type
+ packs. */
+
+tree
+convert_generic_types_to_packs (tree parm, int start_idx, int end_idx)
+{
+ tree current = current_template_parms;
+ int depth = TMPL_PARMS_DEPTH (current);
+ current = INNERMOST_TEMPLATE_PARMS (current);
+ tree replacement = make_tree_vec (TREE_VEC_LENGTH (current));
+
+ for (int i = 0; i < start_idx; ++i)
+ TREE_VEC_ELT (replacement, i)
+ = TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (current, i)));
+
+ for (int i = start_idx; i < end_idx; ++i)
+ {
+ /* Create a distinct parameter pack type from the current parm and add it
+ to the replacement args to tsubst below into the generic function
+ parameter. */
+
+ tree o = TREE_TYPE (TREE_VALUE
+ (TREE_VEC_ELT (current, i)));
+ tree t = copy_type (o);
+ TEMPLATE_TYPE_PARM_INDEX (t)
+ = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (o),
+ o, 0, 0, tf_none);
+ TREE_TYPE (TEMPLATE_TYPE_DECL (t)) = t;
+ TYPE_STUB_DECL (t) = TYPE_NAME (t) = TEMPLATE_TYPE_DECL (t);
+ TYPE_MAIN_VARIANT (t) = t;
+ TEMPLATE_TYPE_PARAMETER_PACK (t) = true;
+ TYPE_CANONICAL (t) = canonical_type_parameter (t);
+ TREE_VEC_ELT (replacement, i) = t;
+ TREE_VALUE (TREE_VEC_ELT (current, i)) = TREE_CHAIN (t);
+ }
+
+ for (int i = end_idx, e = TREE_VEC_LENGTH (current); i < e; ++i)
+ TREE_VEC_ELT (replacement, i)
+ = TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (current, i)));
+
+ /* If there are more levels then build up the replacement with the outer
+ template parms. */
+ if (depth > 1)
+ replacement = add_to_template_args (template_parms_to_args
+ (TREE_CHAIN (current_template_parms)),
+ replacement);
+
+ return tsubst (parm, replacement, tf_none, NULL_TREE);
+}
+
+
+/* Set up the hash tables for template instantiations. */
+
+void
+init_template_processing (void)
+{
+ decl_specializations = htab_create_ggc (37,
+ hash_specialization,
+ eq_specializations,
+ ggc_free);
+ type_specializations = htab_create_ggc (37,
+ hash_specialization,
+ eq_specializations,
+ ggc_free);
+}
+
+/* Print stats about the template hash tables for -fstats. */
+
+void
+print_template_statistics (void)
+{
+ fprintf (stderr, "decl_specializations: size %ld, %ld elements, "
+ "%f collisions\n", (long) htab_size (decl_specializations),
+ (long) htab_elements (decl_specializations),
+ htab_collisions (decl_specializations));
+ fprintf (stderr, "type_specializations: size %ld, %ld elements, "
+ "%f collisions\n", (long) htab_size (type_specializations),
+ (long) htab_elements (type_specializations),
+ htab_collisions (type_specializations));
+}
+
+#include "gt-cp-pt.h"
diff --git a/gcc-4.9/gcc/cp/ptree.c b/gcc-4.9/gcc/cp/ptree.c
new file mode 100644
index 000000000..e99f386ac
--- /dev/null
+++ b/gcc-4.9/gcc/cp/ptree.c
@@ -0,0 +1,240 @@
+/* Prints out trees in human readable form.
+ Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Hacked by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "print-tree.h"
+#include "cp-tree.h"
+
+void
+cxx_print_decl (FILE *file, tree node, int indent)
+{
+ if (TREE_CODE (node) == FIELD_DECL)
+ {
+ if (DECL_MUTABLE_P (node))
+ {
+ indent_to (file, indent + 3);
+ fprintf (file, " mutable ");
+ }
+ return;
+ }
+
+ if (!CODE_CONTAINS_STRUCT (TREE_CODE (node), TS_DECL_COMMON)
+ || !DECL_LANG_SPECIFIC (node))
+ return;
+ if (TREE_CODE (node) == FUNCTION_DECL)
+ {
+ int flags = TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE
+ |TFF_FUNCTION_DEFAULT_ARGUMENTS|TFF_EXCEPTION_SPECIFICATION ;
+ indent_to (file, indent + 3);
+ fprintf (file, " full-name \"%s\"", decl_as_string (node, flags));
+ }
+ else if (TREE_CODE (node) == TEMPLATE_DECL)
+ {
+ indent_to (file, indent + 3);
+ fprintf (file, " full-name \"%s\"",
+ decl_as_string (node, TFF_TEMPLATE_HEADER));
+ }
+
+ indent_to (file, indent + 3);
+ if (DECL_EXTERNAL (node) && DECL_NOT_REALLY_EXTERN (node))
+ fprintf (file, " not-really-extern");
+ if (TREE_CODE (node) == FUNCTION_DECL
+ && DECL_PENDING_INLINE_INFO (node))
+ fprintf (file, " pending-inline-info %p",
+ (void *) DECL_PENDING_INLINE_INFO (node));
+ if (VAR_OR_FUNCTION_DECL_P (node)
+ && DECL_TEMPLATE_INFO (node))
+ fprintf (file, " template-info %p",
+ (void *) DECL_TEMPLATE_INFO (node));
+}
+
+void
+cxx_print_type (FILE *file, tree node, int indent)
+{
+ switch (TREE_CODE (node))
+ {
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ indent_to (file, indent + 3);
+ fprintf (file, "index %d level %d orig_level %d",
+ TEMPLATE_TYPE_IDX (node), TEMPLATE_TYPE_LEVEL (node),
+ TEMPLATE_TYPE_ORIG_LEVEL (node));
+ return;
+
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ if (TYPE_RAISES_EXCEPTIONS (node))
+ print_node (file, "throws", TYPE_RAISES_EXCEPTIONS (node), indent + 4);
+ return;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ break;
+
+ case DECLTYPE_TYPE:
+ print_node (file, "expr", DECLTYPE_TYPE_EXPR (node), indent + 4);
+ return;
+
+ case TYPENAME_TYPE:
+ print_node (file, "fullname", TYPENAME_TYPE_FULLNAME (node),
+ indent + 4);
+ return;
+
+ case TYPE_PACK_EXPANSION:
+ print_node (file, "args", PACK_EXPANSION_EXTRA_ARGS (node), indent + 4);
+ return;
+
+ default:
+ return;
+ }
+
+ if (TYPE_PTRMEMFUNC_P (node))
+ print_node (file, "ptrmemfunc fn type", TYPE_PTRMEMFUNC_FN_TYPE (node),
+ indent + 4);
+
+ if (! CLASS_TYPE_P (node))
+ return;
+
+ indent_to (file, indent + 4);
+ fprintf (file, "full-name \"%s\"",
+ type_as_string (node, TFF_CLASS_KEY_OR_ENUM));
+
+ indent_to (file, indent + 3);
+
+ if (TYPE_NEEDS_CONSTRUCTING (node))
+ fputs ( " needs-constructor", file);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (node))
+ fputs (" needs-destructor", file);
+ if (TYPE_HAS_DEFAULT_CONSTRUCTOR (node))
+ fputs (" X()", file);
+ if (TYPE_HAS_CONVERSION (node))
+ fputs (" has-type-conversion", file);
+ if (TYPE_HAS_COPY_CTOR (node))
+ {
+ if (TYPE_HAS_CONST_COPY_CTOR (node))
+ fputs (" X(constX&)", file);
+ else
+ fputs (" X(X&)", file);
+ }
+ if (TYPE_HAS_NEW_OPERATOR (node))
+ fputs (" new", file);
+ if (TYPE_HAS_ARRAY_NEW_OPERATOR (node))
+ fputs (" new[]", file);
+ if (TYPE_GETS_DELETE (node) & 1)
+ fputs (" delete", file);
+ if (TYPE_GETS_DELETE (node) & 2)
+ fputs (" delete[]", file);
+ if (TYPE_HAS_COPY_ASSIGN (node))
+ fputs (" this=(X&)", file);
+ if (CLASSTYPE_SORTED_FIELDS (node))
+ fprintf (file, " sorted-fields %p",
+ (void *) CLASSTYPE_SORTED_FIELDS (node));
+
+ if (TREE_CODE (node) == RECORD_TYPE)
+ {
+ if (TYPE_BINFO (node))
+ fprintf (file, " n_parents=%d",
+ BINFO_N_BASE_BINFOS (TYPE_BINFO (node)));
+ else
+ fprintf (file, " no-binfo");
+
+ fprintf (file, " use_template=%d", CLASSTYPE_USE_TEMPLATE (node));
+ if (CLASSTYPE_INTERFACE_ONLY (node))
+ fprintf (file, " interface-only");
+ if (CLASSTYPE_INTERFACE_UNKNOWN (node))
+ fprintf (file, " interface-unknown");
+ }
+}
+
+
+static void
+cxx_print_binding (FILE *stream, cxx_binding *binding, const char *prefix)
+{
+ fprintf (stream, "%s <%p>",
+ prefix, (void *) binding);
+}
+
+void
+cxx_print_identifier (FILE *file, tree node, int indent)
+{
+ if (indent == 0)
+ fprintf (file, " ");
+ else
+ indent_to (file, indent + 4);
+ cxx_print_binding (file, IDENTIFIER_NAMESPACE_BINDINGS (node), "bindings");
+ if (indent == 0)
+ fprintf (file, " ");
+ else
+ indent_to (file, indent + 4);
+ cxx_print_binding (file, IDENTIFIER_BINDING (node), "local bindings");
+ print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
+ print_node (file, "template", IDENTIFIER_TEMPLATE (node), indent + 4);
+}
+
+void
+cxx_print_xnode (FILE *file, tree node, int indent)
+{
+ switch (TREE_CODE (node))
+ {
+ case BASELINK:
+ print_node (file, "functions", BASELINK_FUNCTIONS (node), indent + 4);
+ print_node (file, "binfo", BASELINK_BINFO (node), indent + 4);
+ print_node (file, "access_binfo", BASELINK_ACCESS_BINFO (node),
+ indent + 4);
+ break;
+ case OVERLOAD:
+ print_node (file, "function", OVL_FUNCTION (node), indent+4);
+ print_node (file, "chain", TREE_CHAIN (node), indent+4);
+ break;
+ case TEMPLATE_PARM_INDEX:
+ indent_to (file, indent + 3);
+ fprintf (file, "index %d level %d orig_level %d",
+ TEMPLATE_PARM_IDX (node), TEMPLATE_PARM_LEVEL (node),
+ TEMPLATE_PARM_ORIG_LEVEL (node));
+ break;
+ case TEMPLATE_INFO:
+ print_node (file, "template", TI_TEMPLATE (node), indent+4);
+ print_node (file, "args", TI_ARGS (node), indent+4);
+ if (TI_PENDING_TEMPLATE_FLAG (node))
+ {
+ indent_to (file, indent + 3);
+ fprintf (file, "pending_template");
+ }
+ break;
+ case ARGUMENT_PACK_SELECT:
+ print_node (file, "pack", ARGUMENT_PACK_SELECT_FROM_PACK (node),
+ indent+4);
+ indent_to (file, indent + 3);
+ fprintf (file, "index %d", ARGUMENT_PACK_SELECT_INDEX (node));
+ break;
+ case DEFERRED_NOEXCEPT:
+ print_node (file, "pattern", DEFERRED_NOEXCEPT_PATTERN (node), indent+4);
+ print_node (file, "args", DEFERRED_NOEXCEPT_ARGS (node), indent+4);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/gcc-4.9/gcc/cp/repo.c b/gcc-4.9/gcc/cp/repo.c
new file mode 100644
index 000000000..f076f23c8
--- /dev/null
+++ b/gcc-4.9/gcc/cp/repo.c
@@ -0,0 +1,377 @@
+/* Code to maintain a C++ template repository.
+ Copyright (C) 1995-2014 Free Software Foundation, Inc.
+ Contributed by Jason Merrill (jason@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* My strategy here is as follows:
+
+ Everything should be emitted in a translation unit where it is used.
+ The results of the automatic process should be easily reproducible with
+ explicit code. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "cp-tree.h"
+#include "input.h"
+#include "obstack.h"
+#include "toplev.h"
+#include "diagnostic-core.h"
+#include "flags.h"
+
+static const char *extract_string (const char **);
+static const char *get_base_filename (const char *);
+static FILE *open_repo_file (const char *);
+static char *afgets (FILE *);
+static FILE *reopen_repo_file_for_write (void);
+
+static GTY(()) vec<tree, va_gc> *pending_repo;
+static char *repo_name;
+
+static const char *old_args, *old_dir, *old_main;
+
+static struct obstack temporary_obstack;
+static bool temporary_obstack_initialized_p;
+
+/* Parse a reasonable subset of shell quoting syntax. */
+
+static const char *
+extract_string (const char **pp)
+{
+ const char *p = *pp;
+ int backquote = 0;
+ int inside = 0;
+
+ for (;;)
+ {
+ char c = *p;
+ if (c == '\0')
+ break;
+ ++p;
+ if (backquote)
+ {
+ obstack_1grow (&temporary_obstack, c);
+ backquote = 0;
+ }
+ else if (! inside && c == ' ')
+ break;
+ else if (! inside && c == '\\')
+ backquote = 1;
+ else if (c == '\'')
+ inside = !inside;
+ else
+ obstack_1grow (&temporary_obstack, c);
+ }
+
+ obstack_1grow (&temporary_obstack, '\0');
+ *pp = p;
+ return (char *) obstack_finish (&temporary_obstack);
+}
+
+static const char *
+get_base_filename (const char *filename)
+{
+ const char *p = getenv ("COLLECT_GCC_OPTIONS");
+ const char *output = NULL;
+ int compiling = 0;
+
+ while (p && *p)
+ {
+ const char *q = extract_string (&p);
+
+ if (strcmp (q, "-o") == 0)
+ {
+ if (flag_compare_debug)
+ /* Just in case aux_base_name was based on a name with two
+ or more '.'s, add an arbitrary extension that will be
+ stripped by the caller. */
+ output = concat (aux_base_name, ".o", NULL);
+ else
+ output = extract_string (&p);
+ }
+ else if (strcmp (q, "-c") == 0)
+ compiling = 1;
+ }
+
+ if (compiling && output)
+ return output;
+
+ if (p && ! compiling)
+ {
+ warning (0, "-frepo must be used with -c");
+ flag_use_repository = 0;
+ return NULL;
+ }
+
+ return lbasename (filename);
+}
+
+static FILE *
+open_repo_file (const char *filename)
+{
+ const char *p;
+ const char *s = get_base_filename (filename);
+
+ if (s == NULL)
+ return NULL;
+
+ p = lbasename (s);
+ p = strrchr (p, '.');
+ if (! p)
+ p = s + strlen (s);
+
+ repo_name = XNEWVEC (char, p - s + 5);
+ memcpy (repo_name, s, p - s);
+ memcpy (repo_name + (p - s), ".rpo", 5);
+
+ return fopen (repo_name, "r");
+}
+
+static char *
+afgets (FILE *stream)
+{
+ int c;
+ while ((c = getc (stream)) != EOF && c != '\n')
+ obstack_1grow (&temporary_obstack, c);
+ if (obstack_object_size (&temporary_obstack) == 0)
+ return NULL;
+ obstack_1grow (&temporary_obstack, '\0');
+ return (char *) obstack_finish (&temporary_obstack);
+}
+
+void
+init_repo (void)
+{
+ char *buf;
+ const char *p;
+ FILE *repo_file;
+
+ if (! flag_use_repository)
+ return;
+
+ /* When a PCH file is loaded, the entire identifier table is
+ replaced, with the result that IDENTIFIER_REPO_CHOSEN is cleared.
+ So, we have to reread the repository file. */
+ lang_post_pch_load = init_repo;
+
+ if (!temporary_obstack_initialized_p)
+ gcc_obstack_init (&temporary_obstack);
+
+ repo_file = open_repo_file (main_input_filename);
+
+ if (repo_file == 0)
+ return;
+
+ while ((buf = afgets (repo_file)))
+ {
+ switch (buf[0])
+ {
+ case 'A':
+ old_args = ggc_strdup (buf + 2);
+ break;
+ case 'D':
+ old_dir = ggc_strdup (buf + 2);
+ break;
+ case 'M':
+ old_main = ggc_strdup (buf + 2);
+ break;
+ case 'O':
+ /* A symbol that we were able to define the last time this
+ file was compiled. */
+ break;
+ case 'C':
+ /* A symbol that the prelinker has requested that we
+ define. */
+ {
+ tree id = get_identifier (buf + 2);
+ IDENTIFIER_REPO_CHOSEN (id) = 1;
+ }
+ break;
+ default:
+ error ("mysterious repository information in %s", repo_name);
+ }
+ obstack_free (&temporary_obstack, buf);
+ }
+ fclose (repo_file);
+
+ if (old_args && !get_random_seed (true)
+ && (p = strstr (old_args, "'-frandom-seed=")))
+ set_random_seed (extract_string (&p) + strlen ("-frandom-seed="));
+}
+
+static FILE *
+reopen_repo_file_for_write (void)
+{
+ FILE *repo_file = fopen (repo_name, "w");
+
+ if (repo_file == 0)
+ {
+ error ("can%'t create repository information file %qs", repo_name);
+ flag_use_repository = 0;
+ }
+
+ return repo_file;
+}
+
+/* Emit any pending repos. */
+
+void
+finish_repo (void)
+{
+ tree val;
+ char *dir, *args;
+ FILE *repo_file;
+ unsigned ix;
+
+ if (!flag_use_repository || flag_compare_debug)
+ return;
+
+ if (seen_error ())
+ return;
+
+ repo_file = reopen_repo_file_for_write ();
+ if (repo_file == 0)
+ goto out;
+
+ fprintf (repo_file, "M %s\n", main_input_filename);
+ dir = getpwd ();
+ fprintf (repo_file, "D %s\n", dir);
+ args = getenv ("COLLECT_GCC_OPTIONS");
+ if (args)
+ {
+ fprintf (repo_file, "A %s", args);
+ /* If -frandom-seed is not among the ARGS, then add the value
+ that we chose. That will ensure that the names of types from
+ anonymous namespaces will get the same mangling when this
+ file is recompiled. */
+ if (!strstr (args, "'-frandom-seed="))
+ fprintf (repo_file, " '-frandom-seed=" HOST_WIDE_INT_PRINT_HEX_PURE "'",
+ get_random_seed (false));
+ fprintf (repo_file, "\n");
+ }
+
+ FOR_EACH_VEC_SAFE_ELT_REVERSE (pending_repo, ix, val)
+ {
+ tree name = DECL_ASSEMBLER_NAME (val);
+ char type = IDENTIFIER_REPO_CHOSEN (name) ? 'C' : 'O';
+ fprintf (repo_file, "%c %s\n", type, IDENTIFIER_POINTER (name));
+ }
+
+ out:
+ if (repo_file)
+ fclose (repo_file);
+}
+
+/* DECL is a FUNCTION_DECL or VAR_DECL with vague linkage whose
+ definition is available in this translation unit. Returns 0 if
+ this definition should not be emitted in this translation unit
+ because it will be emitted elsewhere. Returns 1 if the repository
+ file indicates that that DECL should be emitted in this translation
+ unit, or 2 if the repository file is not in use. */
+
+int
+repo_emit_p (tree decl)
+{
+ int ret = 0;
+ gcc_assert (TREE_PUBLIC (decl));
+ gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
+ gcc_assert (!DECL_REALLY_EXTERN (decl));
+
+ /* When not using the repository, emit everything. */
+ if (!flag_use_repository)
+ return 2;
+
+ /* Only template instantiations are managed by the repository. This
+ is an artificial restriction; the code in the prelinker and here
+ will work fine if all entities with vague linkage are managed by
+ the repository. */
+ if (VAR_P (decl))
+ {
+ tree type = NULL_TREE;
+ if (DECL_VTABLE_OR_VTT_P (decl))
+ type = DECL_CONTEXT (decl);
+ else if (DECL_TINFO_P (decl))
+ type = TREE_TYPE (DECL_NAME (decl));
+ if (!DECL_TEMPLATE_INSTANTIATION (decl)
+ && (!TYPE_LANG_SPECIFIC (type)
+ || !CLASSTYPE_TEMPLATE_INSTANTIATION (type)))
+ return 2;
+ /* Const static data members initialized by constant expressions must
+ be processed where needed so that their definitions are
+ available. Still record them into *.rpo files, so if they
+ weren't actually emitted and collect2 requests them, they can
+ be provided. */
+ if (decl_maybe_constant_var_p (decl)
+ && DECL_CLASS_SCOPE_P (decl))
+ ret = 2;
+ }
+ else if (!DECL_TEMPLATE_INSTANTIATION (decl))
+ return 2;
+
+ if (DECL_EXPLICIT_INSTANTIATION (decl))
+ return 2;
+
+ /* For constructors and destructors, the repository contains
+ information about the clones -- not the original function --
+ because only the clones are emitted in the object file. */
+ if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
+ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
+ {
+ int emit_p = 0;
+ tree clone;
+ /* There is no early exit from this loop because we want to
+ ensure that all of the clones are marked as available in this
+ object file. */
+ FOR_EACH_CLONE (clone, decl)
+ /* The only possible results from the recursive call to
+ repo_emit_p are 0 or 1. */
+ if (repo_emit_p (clone))
+ emit_p = 1;
+ return emit_p;
+ }
+
+ /* Keep track of all available entities. */
+ if (!DECL_REPO_AVAILABLE_P (decl))
+ {
+ DECL_REPO_AVAILABLE_P (decl) = 1;
+ vec_safe_push (pending_repo, decl);
+ }
+
+ return IDENTIFIER_REPO_CHOSEN (DECL_ASSEMBLER_NAME (decl)) ? 1 : ret;
+}
+
+/* Returns true iff the prelinker has explicitly marked CLASS_TYPE for
+ export from this translation unit. */
+
+bool
+repo_export_class_p (const_tree class_type)
+{
+ if (!flag_use_repository)
+ return false;
+ if (!CLASSTYPE_VTABLES (class_type))
+ return false;
+ /* If the virtual table has been assigned to this translation unit,
+ export the class. */
+ return (IDENTIFIER_REPO_CHOSEN
+ (DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (class_type))));
+}
+
+#include "gt-cp-repo.h"
diff --git a/gcc-4.9/gcc/cp/rtti.c b/gcc-4.9/gcc/cp/rtti.c
new file mode 100644
index 000000000..a8e6d25c8
--- /dev/null
+++ b/gcc-4.9/gcc/cp/rtti.c
@@ -0,0 +1,1602 @@
+/* RunTime Type Identification
+ Copyright (C) 1995-2014 Free Software Foundation, Inc.
+ Mostly written by Jason Merrill (jason@cygnus.com).
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "intl.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "stor-layout.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "convert.h"
+#include "target.h"
+#include "c-family/c-pragma.h"
+
+/* C++ returns type information to the user in struct type_info
+ objects. We also use type information to implement dynamic_cast and
+ exception handlers. Type information for a particular type is
+ indicated with an ABI defined structure derived from type_info.
+ This would all be very straight forward, but for the fact that the
+ runtime library provides the definitions of the type_info structure
+ and the ABI defined derived classes. We cannot build declarations
+ of them directly in the compiler, but we need to layout objects of
+ their type. Somewhere we have to lie.
+
+ We define layout compatible POD-structs with compiler-defined names
+ and generate the appropriate initializations for them (complete
+ with explicit mention of their vtable). When we have to provide a
+ type_info to the user we reinterpret_cast the internal compiler
+ type to type_info. A well formed program can only explicitly refer
+ to the type_infos of complete types (& cv void). However, we chain
+ pointer type_infos to the pointed-to-type, and that can be
+ incomplete. We only need the addresses of such incomplete
+ type_info objects for static initialization.
+
+ The type information VAR_DECL of a type is held on the
+ IDENTIFIER_GLOBAL_VALUE of the type's mangled name. That VAR_DECL
+ will be the internal type. It will usually have the correct
+ internal type reflecting the kind of type it represents (pointer,
+ array, function, class, inherited class, etc). When the type it
+ represents is incomplete, it will have the internal type
+ corresponding to type_info. That will only happen at the end of
+ translation, when we are emitting the type info objects. */
+
+/* Auxiliary data we hold for each type_info derived object we need. */
+typedef struct GTY (()) tinfo_s {
+ tree type; /* The RECORD_TYPE for this type_info object */
+
+ tree vtable; /* The VAR_DECL of the vtable. Only filled at end of
+ translation. */
+
+ tree name; /* IDENTIFIER_NODE for the ABI specified name of
+ the type_info derived type. */
+} tinfo_s;
+
+
+typedef enum tinfo_kind
+{
+ TK_TYPE_INFO_TYPE, /* abi::__type_info_pseudo */
+ TK_BASE_TYPE, /* abi::__base_class_type_info */
+ TK_BUILTIN_TYPE, /* abi::__fundamental_type_info */
+ TK_ARRAY_TYPE, /* abi::__array_type_info */
+ TK_FUNCTION_TYPE, /* abi::__function_type_info */
+ TK_ENUMERAL_TYPE, /* abi::__enum_type_info */
+ TK_POINTER_TYPE, /* abi::__pointer_type_info */
+ TK_POINTER_MEMBER_TYPE, /* abi::__pointer_to_member_type_info */
+ TK_CLASS_TYPE, /* abi::__class_type_info */
+ TK_SI_CLASS_TYPE, /* abi::__si_class_type_info */
+ TK_FIXED /* end of fixed descriptors. */
+ /* ... abi::__vmi_type_info<I> */
+} tinfo_kind;
+
+/* Helper macro to get maximum scalar-width of pointer or of the 'long'-type.
+ This of interest for llp64 targets. */
+#define LONGPTR_T \
+ integer_types[(POINTER_SIZE <= TYPE_PRECISION (integer_types[itk_long]) \
+ ? itk_long : itk_long_long)]
+
+/* A vector of all tinfo decls that haven't yet been emitted. */
+vec<tree, va_gc> *unemitted_tinfo_decls;
+
+/* A vector of all type_info derived types we need. The first few are
+ fixed and created early. The remainder are for multiple inheritance
+ and are generated as needed. */
+static GTY (()) vec<tinfo_s, va_gc> *tinfo_descs;
+
+static tree ifnonnull (tree, tree, tsubst_flags_t);
+static tree tinfo_name (tree, bool);
+static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
+static tree throw_bad_cast (void);
+static tree throw_bad_typeid (void);
+static tree get_tinfo_ptr (tree);
+static bool typeid_ok_p (void);
+static int qualifier_flags (tree);
+static bool target_incomplete_p (tree);
+static tree tinfo_base_init (tinfo_s *, tree);
+static tree generic_initializer (tinfo_s *, tree);
+static tree ptr_initializer (tinfo_s *, tree);
+static tree ptm_initializer (tinfo_s *, tree);
+static tree class_initializer (tinfo_s *, tree, unsigned, ...);
+static void create_pseudo_type_info (int, const char *, ...);
+static tree get_pseudo_ti_init (tree, unsigned);
+static unsigned get_pseudo_ti_index (tree);
+static void create_tinfo_types (void);
+static bool typeinfo_in_lib_p (tree);
+
+static int doing_runtime = 0;
+
+static void
+push_abi_namespace (void)
+{
+ push_nested_namespace (abi_node);
+ push_visibility ("default", 2);
+}
+
+static void
+pop_abi_namespace (void)
+{
+ pop_visibility (2);
+ pop_nested_namespace (abi_node);
+}
+
+/* Declare language defined type_info type and a pointer to const
+ type_info. This is incomplete here, and will be completed when
+ the user #includes <typeinfo>. There are language defined
+ restrictions on what can be done until that is included. Create
+ the internal versions of the ABI types. */
+
+void
+init_rtti_processing (void)
+{
+ tree type_info_type;
+
+ push_namespace (std_identifier);
+ type_info_type = xref_tag (class_type, get_identifier ("type_info"),
+ /*tag_scope=*/ts_current, false);
+ pop_namespace ();
+ const_type_info_type_node
+ = cp_build_qualified_type (type_info_type, TYPE_QUAL_CONST);
+ type_info_ptr_type = build_pointer_type (const_type_info_type_node);
+
+ vec_alloc (unemitted_tinfo_decls, 124);
+
+ create_tinfo_types ();
+}
+
+/* Given the expression EXP of type `class *', return the head of the
+ object pointed to by EXP with type cv void*, if the class has any
+ virtual functions (TYPE_POLYMORPHIC_P), else just return the
+ expression. */
+
+tree
+build_headof (tree exp)
+{
+ tree type = TREE_TYPE (exp);
+ tree offset;
+ tree index;
+
+ gcc_assert (TYPE_PTR_P (type));
+ type = TREE_TYPE (type);
+
+ if (!TYPE_POLYMORPHIC_P (type))
+ return exp;
+
+ /* We use this a couple of times below, protect it. */
+ exp = save_expr (exp);
+
+ /* The offset-to-top field is at index -2 from the vptr. */
+ index = build_int_cst (NULL_TREE,
+ -2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
+
+ offset = build_vtbl_ref (cp_build_indirect_ref (exp, RO_NULL,
+ tf_warning_or_error),
+ index);
+
+ type = cp_build_qualified_type (ptr_type_node,
+ cp_type_quals (TREE_TYPE (exp)));
+ return fold_build_pointer_plus (exp, offset);
+}
+
+/* Get a bad_cast node for the program to throw...
+
+ See libstdc++/exception.cc for __throw_bad_cast */
+
+static tree
+throw_bad_cast (void)
+{
+ tree fn = get_identifier ("__cxa_bad_cast");
+ if (!get_global_value_if_present (fn, &fn))
+ fn = push_throw_library_fn (fn, build_function_type_list (ptr_type_node,
+ NULL_TREE));
+
+ return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
+}
+
+/* Return an expression for "__cxa_bad_typeid()". The expression
+ returned is an lvalue of type "const std::type_info". */
+
+static tree
+throw_bad_typeid (void)
+{
+ tree fn = get_identifier ("__cxa_bad_typeid");
+ if (!get_global_value_if_present (fn, &fn))
+ {
+ tree t;
+
+ t = build_reference_type (const_type_info_type_node);
+ t = build_function_type_list (t, NULL_TREE);
+ fn = push_throw_library_fn (fn, t);
+ }
+
+ return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
+}
+
+/* Return an lvalue expression whose type is "const std::type_info"
+ and whose value indicates the type of the expression EXP. If EXP
+ is a reference to a polymorphic class, return the dynamic type;
+ otherwise return the static type of the expression. */
+
+static tree
+get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain)
+{
+ tree type;
+ tree t;
+
+ if (error_operand_p (exp))
+ return error_mark_node;
+
+ exp = resolve_nondeduced_context (exp);
+
+ /* peel back references, so they match. */
+ type = non_reference (TREE_TYPE (exp));
+
+ /* Peel off cv qualifiers. */
+ type = TYPE_MAIN_VARIANT (type);
+
+ /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */
+ if (CLASS_TYPE_P (type) || type == unknown_type_node
+ || type == init_list_type_node)
+ type = complete_type_or_maybe_complain (type, exp, complain);
+
+ if (!type)
+ return error_mark_node;
+
+ /* If exp is a reference to polymorphic type, get the real type_info. */
+ if (TYPE_POLYMORPHIC_P (type) && ! resolves_to_fixed_type_p (exp, 0))
+ {
+ /* build reference to type_info from vtable. */
+ tree index;
+
+ /* The RTTI information is at index -1. */
+ index = build_int_cst (NULL_TREE,
+ -1 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
+ t = build_vtbl_ref (exp, index);
+ t = convert (type_info_ptr_type, t);
+ }
+ else
+ /* Otherwise return the type_info for the static type of the expr. */
+ t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
+
+ return cp_build_indirect_ref (t, RO_NULL, complain);
+}
+
+static bool
+typeid_ok_p (void)
+{
+ tree pseudo_type_info, type_info_type;
+
+ if (! flag_rtti)
+ {
+ error ("cannot use typeid with -fno-rtti");
+ return false;
+ }
+
+ if (!COMPLETE_TYPE_P (const_type_info_type_node))
+ {
+ error ("must #include <typeinfo> before using typeid");
+ return false;
+ }
+
+ pseudo_type_info = (*tinfo_descs)[TK_TYPE_INFO_TYPE].type;
+ type_info_type = TYPE_MAIN_VARIANT (const_type_info_type_node);
+
+ /* Make sure abi::__type_info_pseudo has the same alias set
+ as std::type_info. */
+ if (! TYPE_ALIAS_SET_KNOWN_P (pseudo_type_info))
+ TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type);
+ else
+ gcc_assert (TYPE_ALIAS_SET (pseudo_type_info)
+ == get_alias_set (type_info_type));
+
+ return true;
+}
+
+/* Return an expression for "typeid(EXP)". The expression returned is
+ an lvalue of type "const std::type_info". */
+
+tree
+build_typeid (tree exp, tsubst_flags_t complain)
+{
+ tree cond = NULL_TREE, initial_expr = exp;
+ int nonnull = 0;
+
+ if (exp == error_mark_node || !typeid_ok_p ())
+ return error_mark_node;
+
+ if (processing_template_decl)
+ return build_min (TYPEID_EXPR, const_type_info_type_node, exp);
+
+ /* FIXME when integrating with c_fully_fold, mark
+ resolves_to_fixed_type_p case as a non-constant expression. */
+ if (TYPE_POLYMORPHIC_P (TREE_TYPE (exp))
+ && ! resolves_to_fixed_type_p (exp, &nonnull)
+ && ! nonnull)
+ {
+ /* So we need to look into the vtable of the type of exp.
+ Make sure it isn't a null lvalue. */
+ exp = cp_build_addr_expr (exp, complain);
+ exp = stabilize_reference (exp);
+ cond = cp_convert (boolean_type_node, exp, complain);
+ exp = cp_build_indirect_ref (exp, RO_NULL, complain);
+ }
+
+ exp = get_tinfo_decl_dynamic (exp, complain);
+
+ if (exp == error_mark_node)
+ return error_mark_node;
+
+ if (cond)
+ {
+ tree bad = throw_bad_typeid ();
+
+ exp = build3 (COND_EXPR, TREE_TYPE (exp), cond, exp, bad);
+ }
+ else
+ mark_type_use (initial_expr);
+
+ return exp;
+}
+
+/* Generate the NTBS name of a type. If MARK_PRIVATE, put a '*' in front so that
+ comparisons will be done by pointer rather than string comparison. */
+static tree
+tinfo_name (tree type, bool mark_private)
+{
+ const char *name;
+ int length;
+ tree name_string;
+
+ name = mangle_type_string (type);
+ length = strlen (name);
+
+ if (mark_private)
+ {
+ /* Inject '*' at beginning of name to force pointer comparison. */
+ char* buf = (char*) XALLOCAVEC (char, length + 2);
+ buf[0] = '*';
+ memcpy (buf + 1, name, length + 1);
+ name_string = build_string (length + 2, buf);
+ }
+ else
+ name_string = build_string (length + 1, name);
+
+ return fix_string_type (name_string);
+}
+
+/* Return a VAR_DECL for the internal ABI defined type_info object for
+ TYPE. You must arrange that the decl is mark_used, if actually use
+ it --- decls in vtables are only used if the vtable is output. */
+
+tree
+get_tinfo_decl (tree type)
+{
+ tree name;
+ tree d;
+
+ if (variably_modified_type_p (type, /*fn=*/NULL_TREE))
+ {
+ if (array_of_runtime_bound_p (type))
+ error ("typeid of array of runtime bound");
+ else
+ error ("cannot create type information for type %qT because "
+ "it involves types of variable size",
+ type);
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (type) == METHOD_TYPE)
+ type = build_function_type (TREE_TYPE (type),
+ TREE_CHAIN (TYPE_ARG_TYPES (type)));
+
+ type = complete_type (type);
+
+ /* For a class type, the variable is cached in the type node
+ itself. */
+ if (CLASS_TYPE_P (type))
+ {
+ d = CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type));
+ if (d)
+ return d;
+ }
+
+ name = mangle_typeinfo_for_type (type);
+
+ d = IDENTIFIER_GLOBAL_VALUE (name);
+ if (!d)
+ {
+ int ix = get_pseudo_ti_index (type);
+ tinfo_s *ti = &(*tinfo_descs)[ix];
+
+ d = build_lang_decl (VAR_DECL, name, ti->type);
+ SET_DECL_ASSEMBLER_NAME (d, name);
+ /* Remember the type it is for. */
+ TREE_TYPE (name) = type;
+ DECL_TINFO_P (d) = 1;
+ DECL_ARTIFICIAL (d) = 1;
+ DECL_IGNORED_P (d) = 1;
+ TREE_READONLY (d) = 1;
+ TREE_STATIC (d) = 1;
+ /* Mark the variable as undefined -- but remember that we can
+ define it later if we need to do so. */
+ DECL_EXTERNAL (d) = 1;
+ DECL_NOT_REALLY_EXTERN (d) = 1;
+ set_linkage_according_to_type (type, d);
+
+ d = pushdecl_top_level_and_finish (d, NULL_TREE);
+ if (CLASS_TYPE_P (type))
+ CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d;
+
+ /* Add decl to the global array of tinfo decls. */
+ vec_safe_push (unemitted_tinfo_decls, d);
+ }
+
+ return d;
+}
+
+/* Return a pointer to a type_info object describing TYPE, suitably
+ cast to the language defined type. */
+
+static tree
+get_tinfo_ptr (tree type)
+{
+ tree decl = get_tinfo_decl (type);
+
+ mark_used (decl);
+ return build_nop (type_info_ptr_type,
+ build_address (decl));
+}
+
+/* Return the type_info object for TYPE. */
+
+tree
+get_typeid (tree type, tsubst_flags_t complain)
+{
+ if (type == error_mark_node || !typeid_ok_p ())
+ return error_mark_node;
+
+ if (processing_template_decl)
+ return build_min (TYPEID_EXPR, const_type_info_type_node, type);
+
+ /* If the type of the type-id is a reference type, the result of the
+ typeid expression refers to a type_info object representing the
+ referenced type. */
+ type = non_reference (type);
+
+ /* This is not one of the uses of a qualified function type in 8.3.5. */
+ if (TREE_CODE (type) == FUNCTION_TYPE
+ && (type_memfn_quals (type) != TYPE_UNQUALIFIED
+ || type_memfn_rqual (type) != REF_QUAL_NONE))
+ {
+ if (complain & tf_error)
+ error ("typeid of qualified function type %qT", type);
+ return error_mark_node;
+ }
+
+ /* The top-level cv-qualifiers of the lvalue expression or the type-id
+ that is the operand of typeid are always ignored. */
+ type = TYPE_MAIN_VARIANT (type);
+
+ /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */
+ if (CLASS_TYPE_P (type) || type == unknown_type_node
+ || type == init_list_type_node)
+ type = complete_type_or_maybe_complain (type, NULL_TREE, complain);
+
+ if (!type)
+ return error_mark_node;
+
+ return cp_build_indirect_ref (get_tinfo_ptr (type), RO_NULL, complain);
+}
+
+/* Check whether TEST is null before returning RESULT. If TEST is used in
+ RESULT, it must have previously had a save_expr applied to it. */
+
+static tree
+ifnonnull (tree test, tree result, tsubst_flags_t complain)
+{
+ return build3 (COND_EXPR, TREE_TYPE (result),
+ build2 (EQ_EXPR, boolean_type_node, test,
+ cp_convert (TREE_TYPE (test), nullptr_node,
+ complain)),
+ cp_convert (TREE_TYPE (result), nullptr_node, complain),
+ result);
+}
+
+/* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
+ paper. */
+
+static tree
+build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
+{
+ enum tree_code tc = TREE_CODE (type);
+ tree exprtype;
+ tree dcast_fn;
+ tree old_expr = expr;
+ const char *errstr = NULL;
+
+ /* Save casted types in the function's used types hash table. */
+ used_types_insert (type);
+
+ /* T shall be a pointer or reference to a complete class type, or
+ `pointer to cv void''. */
+ switch (tc)
+ {
+ case POINTER_TYPE:
+ if (VOID_TYPE_P (TREE_TYPE (type)))
+ break;
+ /* Fall through. */
+ case REFERENCE_TYPE:
+ if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (type)))
+ {
+ errstr = _("target is not pointer or reference to class");
+ goto fail;
+ }
+ if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
+ {
+ errstr = _("target is not pointer or reference to complete type");
+ goto fail;
+ }
+ break;
+
+ default:
+ errstr = _("target is not pointer or reference");
+ goto fail;
+ }
+
+ if (tc == POINTER_TYPE)
+ {
+ expr = decay_conversion (expr, complain);
+ exprtype = TREE_TYPE (expr);
+
+ /* If T is a pointer type, v shall be an rvalue of a pointer to
+ complete class type, and the result is an rvalue of type T. */
+
+ expr = mark_rvalue_use (expr);
+
+ if (!TYPE_PTR_P (exprtype))
+ {
+ errstr = _("source is not a pointer");
+ goto fail;
+ }
+ if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (exprtype)))
+ {
+ errstr = _("source is not a pointer to class");
+ goto fail;
+ }
+ if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
+ {
+ errstr = _("source is a pointer to incomplete type");
+ goto fail;
+ }
+ }
+ else
+ {
+ expr = mark_lvalue_use (expr);
+
+ exprtype = build_reference_type (TREE_TYPE (expr));
+
+ /* T is a reference type, v shall be an lvalue of a complete class
+ type, and the result is an lvalue of the type referred to by T. */
+
+ if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (exprtype)))
+ {
+ errstr = _("source is not of class type");
+ goto fail;
+ }
+ if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
+ {
+ errstr = _("source is of incomplete class type");
+ goto fail;
+ }
+
+ /* Apply trivial conversion T -> T& for dereferenced ptrs. */
+ expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
+ LOOKUP_NORMAL, NULL_TREE, complain);
+ }
+
+ /* The dynamic_cast operator shall not cast away constness. */
+ if (!at_least_as_qualified_p (TREE_TYPE (type),
+ TREE_TYPE (exprtype)))
+ {
+ errstr = _("conversion casts away constness");
+ goto fail;
+ }
+
+ /* If *type is an unambiguous accessible base class of *exprtype,
+ convert statically. */
+ {
+ tree binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type),
+ ba_check, NULL, complain);
+ if (binfo)
+ return build_static_cast (type, expr, complain);
+ }
+
+ /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
+ if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype)))
+ {
+ tree expr1;
+ /* if TYPE is `void *', return pointer to complete object. */
+ if (tc == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (type)))
+ {
+ /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
+ if (TREE_CODE (expr) == ADDR_EXPR
+ && VAR_P (TREE_OPERAND (expr, 0))
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
+ return build1 (NOP_EXPR, type, expr);
+
+ /* Since expr is used twice below, save it. */
+ expr = save_expr (expr);
+
+ expr1 = build_headof (expr);
+ if (TREE_TYPE (expr1) != type)
+ expr1 = build1 (NOP_EXPR, type, expr1);
+ return ifnonnull (expr, expr1, complain);
+ }
+ else
+ {
+ tree retval;
+ tree result, td2, td3;
+ tree elems[4];
+ tree static_type, target_type, boff;
+
+ /* If we got here, we can't convert statically. Therefore,
+ dynamic_cast<D&>(b) (b an object) cannot succeed. */
+ if (tc == REFERENCE_TYPE)
+ {
+ if (VAR_P (old_expr)
+ && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
+ {
+ tree expr = throw_bad_cast ();
+ if (complain & tf_warning)
+ warning (0, "dynamic_cast of %q#D to %q#T can never succeed",
+ old_expr, type);
+ /* Bash it to the expected type. */
+ TREE_TYPE (expr) = type;
+ return expr;
+ }
+ }
+ /* Ditto for dynamic_cast<D*>(&b). */
+ else if (TREE_CODE (expr) == ADDR_EXPR)
+ {
+ tree op = TREE_OPERAND (expr, 0);
+ if (VAR_P (op)
+ && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
+ {
+ if (complain & tf_warning)
+ warning (0, "dynamic_cast of %q#D to %q#T can never succeed",
+ op, type);
+ retval = build_int_cst (type, 0);
+ return retval;
+ }
+ }
+
+ /* Use of dynamic_cast when -fno-rtti is prohibited. */
+ if (!flag_rtti)
+ {
+ if (complain & tf_error)
+ error ("%<dynamic_cast%> not permitted with -fno-rtti");
+ return error_mark_node;
+ }
+
+ target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
+ static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
+ td2 = get_tinfo_decl (target_type);
+ mark_used (td2);
+ td2 = cp_build_addr_expr (td2, complain);
+ td3 = get_tinfo_decl (static_type);
+ mark_used (td3);
+ td3 = cp_build_addr_expr (td3, complain);
+
+ /* Determine how T and V are related. */
+ boff = dcast_base_hint (static_type, target_type);
+
+ /* Since expr is used twice below, save it. */
+ expr = save_expr (expr);
+
+ expr1 = expr;
+ if (tc == REFERENCE_TYPE)
+ expr1 = cp_build_addr_expr (expr1, complain);
+
+ elems[0] = expr1;
+ elems[1] = td3;
+ elems[2] = td2;
+ elems[3] = boff;
+
+ dcast_fn = dynamic_cast_node;
+ if (!dcast_fn)
+ {
+ tree tmp;
+ tree tinfo_ptr;
+ const char *name;
+
+ push_abi_namespace ();
+ tinfo_ptr = xref_tag (class_type,
+ get_identifier ("__class_type_info"),
+ /*tag_scope=*/ts_current, false);
+
+ tinfo_ptr = build_pointer_type
+ (cp_build_qualified_type
+ (tinfo_ptr, TYPE_QUAL_CONST));
+ name = "__dynamic_cast";
+ tmp = build_function_type_list (ptr_type_node,
+ const_ptr_type_node,
+ tinfo_ptr, tinfo_ptr,
+ ptrdiff_type_node, NULL_TREE);
+ dcast_fn = build_library_fn_ptr (name, tmp,
+ ECF_LEAF | ECF_PURE | ECF_NOTHROW);
+ pop_abi_namespace ();
+ dynamic_cast_node = dcast_fn;
+ }
+ result = build_cxx_call (dcast_fn, 4, elems, complain);
+
+ if (tc == REFERENCE_TYPE)
+ {
+ tree bad = throw_bad_cast ();
+ tree neq;
+
+ result = save_expr (result);
+ neq = cp_truthvalue_conversion (result);
+ return cp_convert (type,
+ build3 (COND_EXPR, TREE_TYPE (result),
+ neq, result, bad), complain);
+ }
+
+ /* Now back to the type we want from a void*. */
+ result = cp_convert (type, result, complain);
+ return ifnonnull (expr, result, complain);
+ }
+ }
+ else
+ errstr = _("source type is not polymorphic");
+
+ fail:
+ if (complain & tf_error)
+ error ("cannot dynamic_cast %qE (of type %q#T) to type %q#T (%s)",
+ old_expr, TREE_TYPE (old_expr), type, errstr);
+ return error_mark_node;
+}
+
+tree
+build_dynamic_cast (tree type, tree expr, tsubst_flags_t complain)
+{
+ tree r;
+
+ if (type == error_mark_node || expr == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ expr = build_min (DYNAMIC_CAST_EXPR, type, expr);
+ TREE_SIDE_EFFECTS (expr) = 1;
+ return convert_from_reference (expr);
+ }
+
+ r = convert_from_reference (build_dynamic_cast_1 (type, expr, complain));
+ if (r != error_mark_node)
+ maybe_warn_about_useless_cast (type, expr, complain);
+ return r;
+}
+
+/* Return the runtime bit mask encoding the qualifiers of TYPE. */
+
+static int
+qualifier_flags (tree type)
+{
+ int flags = 0;
+ int quals = cp_type_quals (type);
+
+ if (quals & TYPE_QUAL_CONST)
+ flags |= 1;
+ if (quals & TYPE_QUAL_VOLATILE)
+ flags |= 2;
+ if (quals & TYPE_QUAL_RESTRICT)
+ flags |= 4;
+ return flags;
+}
+
+/* Return true, if the pointer chain TYPE ends at an incomplete type, or
+ contains a pointer to member of an incomplete class. */
+
+static bool
+target_incomplete_p (tree type)
+{
+ while (true)
+ if (TYPE_PTRDATAMEM_P (type))
+ {
+ if (!COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type)))
+ return true;
+ type = TYPE_PTRMEM_POINTED_TO_TYPE (type);
+ }
+ else if (TYPE_PTR_P (type))
+ type = TREE_TYPE (type);
+ else
+ return !COMPLETE_OR_VOID_TYPE_P (type);
+}
+
+/* Returns true if TYPE involves an incomplete class type; in that
+ case, typeinfo variables for TYPE should be emitted with internal
+ linkage. */
+
+static bool
+involves_incomplete_p (tree type)
+{
+ switch (TREE_CODE (type))
+ {
+ case POINTER_TYPE:
+ return target_incomplete_p (TREE_TYPE (type));
+
+ case OFFSET_TYPE:
+ ptrmem:
+ return
+ (target_incomplete_p (TYPE_PTRMEM_POINTED_TO_TYPE (type))
+ || !COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type)));
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (type))
+ goto ptrmem;
+ /* Fall through. */
+ case UNION_TYPE:
+ if (!COMPLETE_TYPE_P (type))
+ return true;
+
+ default:
+ /* All other types do not involve incomplete class types. */
+ return false;
+ }
+}
+
+/* Return a CONSTRUCTOR for the common part of the type_info objects. This
+ is the vtable pointer and NTBS name. The NTBS name is emitted as a
+ comdat const char array, so it becomes a unique key for the type. Generate
+ and emit that VAR_DECL here. (We can't always emit the type_info itself
+ as comdat, because of pointers to incomplete.) */
+
+static tree
+tinfo_base_init (tinfo_s *ti, tree target)
+{
+ tree init;
+ tree name_decl;
+ tree vtable_ptr;
+ vec<constructor_elt, va_gc> *v;
+
+ {
+ tree name_name, name_string;
+
+ /* Generate the NTBS array variable. */
+ tree name_type = build_cplus_array_type
+ (cp_build_qualified_type (char_type_node, TYPE_QUAL_CONST),
+ NULL_TREE);
+
+ /* Determine the name of the variable -- and remember with which
+ type it is associated. */
+ name_name = mangle_typeinfo_string_for_type (target);
+ TREE_TYPE (name_name) = target;
+
+ name_decl = build_lang_decl (VAR_DECL, name_name, name_type);
+ SET_DECL_ASSEMBLER_NAME (name_decl, name_name);
+ DECL_ARTIFICIAL (name_decl) = 1;
+ DECL_IGNORED_P (name_decl) = 1;
+ TREE_READONLY (name_decl) = 1;
+ TREE_STATIC (name_decl) = 1;
+ DECL_EXTERNAL (name_decl) = 0;
+ DECL_TINFO_P (name_decl) = 1;
+ set_linkage_according_to_type (target, name_decl);
+ import_export_decl (name_decl);
+ name_string = tinfo_name (target, !TREE_PUBLIC (name_decl));
+ DECL_INITIAL (name_decl) = name_string;
+ mark_used (name_decl);
+ pushdecl_top_level_and_finish (name_decl, name_string);
+ }
+
+ vtable_ptr = ti->vtable;
+ if (!vtable_ptr)
+ {
+ tree real_type;
+ push_abi_namespace ();
+ real_type = xref_tag (class_type, ti->name,
+ /*tag_scope=*/ts_current, false);
+ pop_abi_namespace ();
+
+ if (!COMPLETE_TYPE_P (real_type))
+ {
+ /* We never saw a definition of this type, so we need to
+ tell the compiler that this is an exported class, as
+ indeed all of the __*_type_info classes are. */
+ SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
+ CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
+ }
+
+ vtable_ptr = get_vtable_decl (real_type, /*complete=*/1);
+ vtable_ptr = cp_build_addr_expr (vtable_ptr, tf_warning_or_error);
+
+ /* We need to point into the middle of the vtable. */
+ vtable_ptr = fold_build_pointer_plus
+ (vtable_ptr,
+ size_binop (MULT_EXPR,
+ size_int (2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE),
+ TYPE_SIZE_UNIT (vtable_entry_type)));
+
+ ti->vtable = vtable_ptr;
+ }
+
+ vec_alloc (v, 2);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, vtable_ptr);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
+ decay_conversion (name_decl, tf_warning_or_error));
+
+ init = build_constructor (init_list_type_node, v);
+ TREE_CONSTANT (init) = 1;
+ TREE_STATIC (init) = 1;
+
+ return init;
+}
+
+/* Return the CONSTRUCTOR expr for a type_info of TYPE. TI provides the
+ information about the particular type_info derivation, which adds no
+ additional fields to the type_info base. */
+
+static tree
+generic_initializer (tinfo_s *ti, tree target)
+{
+ tree init = tinfo_base_init (ti, target);
+
+ init = build_constructor_single (init_list_type_node, NULL_TREE, init);
+ TREE_CONSTANT (init) = 1;
+ TREE_STATIC (init) = 1;
+ return init;
+}
+
+/* Return the CONSTRUCTOR expr for a type_info of pointer TYPE.
+ TI provides information about the particular type_info derivation,
+ which adds target type and qualifier flags members to the type_info base. */
+
+static tree
+ptr_initializer (tinfo_s *ti, tree target)
+{
+ tree init = tinfo_base_init (ti, target);
+ tree to = TREE_TYPE (target);
+ int flags = qualifier_flags (to);
+ bool incomplete = target_incomplete_p (to);
+ vec<constructor_elt, va_gc> *v;
+ vec_alloc (v, 3);
+
+ if (incomplete)
+ flags |= 8;
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, flags));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
+ get_tinfo_ptr (TYPE_MAIN_VARIANT (to)));
+
+ init = build_constructor (init_list_type_node, v);
+ TREE_CONSTANT (init) = 1;
+ TREE_STATIC (init) = 1;
+ return init;
+}
+
+/* Return the CONSTRUCTOR expr for a type_info of pointer to member data TYPE.
+ TI provides information about the particular type_info derivation,
+ which adds class, target type and qualifier flags members to the type_info
+ base. */
+
+static tree
+ptm_initializer (tinfo_s *ti, tree target)
+{
+ tree init = tinfo_base_init (ti, target);
+ tree to = TYPE_PTRMEM_POINTED_TO_TYPE (target);
+ tree klass = TYPE_PTRMEM_CLASS_TYPE (target);
+ int flags = qualifier_flags (to);
+ bool incomplete = target_incomplete_p (to);
+ vec<constructor_elt, va_gc> *v;
+ vec_alloc (v, 4);
+
+ if (incomplete)
+ flags |= 0x8;
+ if (!COMPLETE_TYPE_P (klass))
+ flags |= 0x10;
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, flags));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
+ get_tinfo_ptr (TYPE_MAIN_VARIANT (to)));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, get_tinfo_ptr (klass));
+
+ init = build_constructor (init_list_type_node, v);
+ TREE_CONSTANT (init) = 1;
+ TREE_STATIC (init) = 1;
+ return init;
+}
+
+/* Return the CONSTRUCTOR expr for a type_info of class TYPE.
+ TI provides information about the particular __class_type_info derivation,
+ which adds hint flags and N extra initializers to the type_info base. */
+
+static tree
+class_initializer (tinfo_s *ti, tree target, unsigned n, ...)
+{
+ tree init = tinfo_base_init (ti, target);
+ va_list extra_inits;
+ unsigned i;
+ vec<constructor_elt, va_gc> *v;
+ vec_alloc (v, n+1);
+
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
+ va_start (extra_inits, n);
+ for (i = 0; i < n; i++)
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, va_arg (extra_inits, tree));
+ va_end (extra_inits);
+
+ init = build_constructor (init_list_type_node, v);
+ TREE_CONSTANT (init) = 1;
+ TREE_STATIC (init) = 1;
+ return init;
+}
+
+/* Returns true if the typeinfo for type should be placed in
+ the runtime library. */
+
+static bool
+typeinfo_in_lib_p (tree type)
+{
+ /* The typeinfo objects for `T*' and `const T*' are in the runtime
+ library for simple types T. */
+ if (TYPE_PTR_P (type)
+ && (cp_type_quals (TREE_TYPE (type)) == TYPE_QUAL_CONST
+ || cp_type_quals (TREE_TYPE (type)) == TYPE_UNQUALIFIED))
+ type = TREE_TYPE (type);
+
+ switch (TREE_CODE (type))
+ {
+ case INTEGER_TYPE:
+ case BOOLEAN_TYPE:
+ case REAL_TYPE:
+ case VOID_TYPE:
+ case NULLPTR_TYPE:
+ return true;
+
+ case LANG_TYPE:
+ /* fall through. */
+
+ default:
+ return false;
+ }
+}
+
+/* Generate the initializer for the type info describing TYPE. TK_INDEX is
+ the index of the descriptor in the tinfo_desc vector. */
+
+static tree
+get_pseudo_ti_init (tree type, unsigned tk_index)
+{
+ tinfo_s *ti = &(*tinfo_descs)[tk_index];
+
+ gcc_assert (at_eof);
+ switch (tk_index)
+ {
+ case TK_POINTER_MEMBER_TYPE:
+ return ptm_initializer (ti, type);
+
+ case TK_POINTER_TYPE:
+ return ptr_initializer (ti, type);
+
+ case TK_BUILTIN_TYPE:
+ case TK_ENUMERAL_TYPE:
+ case TK_FUNCTION_TYPE:
+ case TK_ARRAY_TYPE:
+ return generic_initializer (ti, type);
+
+ case TK_CLASS_TYPE:
+ return class_initializer (ti, type, 0);
+
+ case TK_SI_CLASS_TYPE:
+ {
+ tree base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), 0);
+ tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
+
+ /* get_tinfo_ptr might have reallocated the tinfo_descs vector. */
+ ti = &(*tinfo_descs)[tk_index];
+ return class_initializer (ti, type, 1, tinfo);
+ }
+
+ default:
+ {
+ int hint = ((CLASSTYPE_REPEATED_BASE_P (type) << 0)
+ | (CLASSTYPE_DIAMOND_SHAPED_P (type) << 1));
+ tree binfo = TYPE_BINFO (type);
+ int nbases = BINFO_N_BASE_BINFOS (binfo);
+ vec<tree, va_gc> *base_accesses = BINFO_BASE_ACCESSES (binfo);
+ tree offset_type = LONGPTR_T;
+ tree base_inits = NULL_TREE;
+ int ix;
+ vec<constructor_elt, va_gc> *init_vec = NULL;
+ constructor_elt *e;
+
+ gcc_assert (tk_index >= TK_FIXED);
+
+ vec_safe_grow (init_vec, nbases);
+ /* Generate the base information initializer. */
+ for (ix = nbases; ix--;)
+ {
+ tree base_binfo = BINFO_BASE_BINFO (binfo, ix);
+ tree base_init;
+ int flags = 0;
+ tree tinfo;
+ tree offset;
+ vec<constructor_elt, va_gc> *v;
+
+ if ((*base_accesses)[ix] == access_public_node)
+ flags |= 2;
+ tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
+ if (BINFO_VIRTUAL_P (base_binfo))
+ {
+ /* We store the vtable offset at which the virtual
+ base offset can be found. */
+ offset = BINFO_VPTR_FIELD (base_binfo);
+ flags |= 1;
+ }
+ else
+ offset = BINFO_OFFSET (base_binfo);
+
+ /* Combine offset and flags into one field. */
+ offset = fold_convert (offset_type, offset);
+ offset = fold_build2_loc (input_location,
+ LSHIFT_EXPR, offset_type, offset,
+ build_int_cst (offset_type, 8));
+ offset = fold_build2_loc (input_location,
+ BIT_IOR_EXPR, offset_type, offset,
+ build_int_cst (offset_type, flags));
+ vec_alloc (v, 2);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tinfo);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, offset);
+ base_init = build_constructor (init_list_type_node, v);
+ e = &(*init_vec)[ix];
+ e->index = NULL_TREE;
+ e->value = base_init;
+ }
+ base_inits = build_constructor (init_list_type_node, init_vec);
+
+ /* get_tinfo_ptr might have reallocated the tinfo_descs vector. */
+ ti = &(*tinfo_descs)[tk_index];
+ return class_initializer (ti, type, 3,
+ build_int_cst (NULL_TREE, hint),
+ build_int_cst (NULL_TREE, nbases),
+ base_inits);
+ }
+ }
+}
+
+/* Generate the RECORD_TYPE containing the data layout of a type_info
+ derivative as used by the runtime. This layout must be consistent with
+ that defined in the runtime support. Also generate the VAR_DECL for the
+ type's vtable. We explicitly manage the vtable member, and name it for
+ real type as used in the runtime. The RECORD type has a different name,
+ to avoid collisions. Return a TREE_LIST who's TINFO_PSEUDO_TYPE
+ is the generated type and TINFO_VTABLE_NAME is the name of the
+ vtable. We have to delay generating the VAR_DECL of the vtable
+ until the end of the translation, when we'll have seen the library
+ definition, if there was one.
+
+ REAL_NAME is the runtime's name of the type. Trailing arguments are
+ additional FIELD_DECL's for the structure. The final argument must be
+ NULL. */
+
+static void
+create_pseudo_type_info (int tk, const char *real_name, ...)
+{
+ tinfo_s *ti;
+ tree pseudo_type;
+ char *pseudo_name;
+ tree fields;
+ tree field_decl;
+ va_list ap;
+
+ va_start (ap, real_name);
+
+ /* Generate the pseudo type name. */
+ pseudo_name = (char *) alloca (strlen (real_name) + 30);
+ strcpy (pseudo_name, real_name);
+ strcat (pseudo_name, "_pseudo");
+ if (tk >= TK_FIXED)
+ sprintf (pseudo_name + strlen (pseudo_name), "%d", tk - TK_FIXED);
+
+ /* First field is the pseudo type_info base class. */
+ fields = build_decl (input_location,
+ FIELD_DECL, NULL_TREE,
+ (*tinfo_descs)[TK_TYPE_INFO_TYPE].type);
+
+ /* Now add the derived fields. */
+ while ((field_decl = va_arg (ap, tree)))
+ {
+ DECL_CHAIN (field_decl) = fields;
+ fields = field_decl;
+ }
+
+ /* Create the pseudo type. */
+ pseudo_type = make_class_type (RECORD_TYPE);
+ finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
+ CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
+
+ ti = &(*tinfo_descs)[tk];
+ ti->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
+ ti->name = get_identifier (real_name);
+ ti->vtable = NULL_TREE;
+
+ /* Pretend this is public so determine_visibility doesn't give vtables
+ internal linkage. */
+ TREE_PUBLIC (TYPE_MAIN_DECL (ti->type)) = 1;
+
+ va_end (ap);
+}
+
+/* Return the index of a pseudo type info type node used to describe
+ TYPE. TYPE must be a complete type (or cv void), except at the end
+ of the translation unit. */
+
+static unsigned
+get_pseudo_ti_index (tree type)
+{
+ unsigned ix;
+
+ switch (TREE_CODE (type))
+ {
+ case OFFSET_TYPE:
+ ix = TK_POINTER_MEMBER_TYPE;
+ break;
+
+ case POINTER_TYPE:
+ ix = TK_POINTER_TYPE;
+ break;
+
+ case ENUMERAL_TYPE:
+ ix = TK_ENUMERAL_TYPE;
+ break;
+
+ case FUNCTION_TYPE:
+ ix = TK_FUNCTION_TYPE;
+ break;
+
+ case ARRAY_TYPE:
+ ix = TK_ARRAY_TYPE;
+ break;
+
+ case UNION_TYPE:
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (type))
+ {
+ ix = TK_POINTER_MEMBER_TYPE;
+ break;
+ }
+ else if (!COMPLETE_TYPE_P (type))
+ {
+ if (!at_eof)
+ cxx_incomplete_type_error (NULL_TREE, type);
+ ix = TK_CLASS_TYPE;
+ break;
+ }
+ else if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
+ {
+ ix = TK_CLASS_TYPE;
+ break;
+ }
+ else
+ {
+ tree binfo = TYPE_BINFO (type);
+ vec<tree, va_gc> *base_accesses = BINFO_BASE_ACCESSES (binfo);
+ tree base_binfo = BINFO_BASE_BINFO (binfo, 0);
+ int num_bases = BINFO_N_BASE_BINFOS (binfo);
+
+ if (num_bases == 1
+ && (*base_accesses)[0] == access_public_node
+ && !BINFO_VIRTUAL_P (base_binfo)
+ && integer_zerop (BINFO_OFFSET (base_binfo)))
+ {
+ /* single non-virtual public. */
+ ix = TK_SI_CLASS_TYPE;
+ break;
+ }
+ else
+ {
+ tinfo_s *ti;
+ tree array_domain, base_array;
+
+ ix = TK_FIXED + num_bases;
+ if (vec_safe_length (tinfo_descs) <= ix)
+ {
+ /* too short, extend. */
+ unsigned len = vec_safe_length (tinfo_descs);
+
+ vec_safe_grow (tinfo_descs, ix + 1);
+ while (tinfo_descs->iterate (len++, &ti))
+ ti->type = ti->vtable = ti->name = NULL_TREE;
+ }
+ else if ((*tinfo_descs)[ix].type)
+ /* already created. */
+ break;
+
+ /* Create the array of __base_class_type_info entries.
+ G++ 3.2 allocated an array that had one too many
+ entries, and then filled that extra entries with
+ zeros. */
+ if (abi_version_at_least (2))
+ array_domain = build_index_type (size_int (num_bases - 1));
+ else
+ array_domain = build_index_type (size_int (num_bases));
+ base_array = build_array_type ((*tinfo_descs)[TK_BASE_TYPE].type,
+ array_domain);
+
+ push_abi_namespace ();
+ create_pseudo_type_info
+ (ix, "__vmi_class_type_info",
+ build_decl (input_location,
+ FIELD_DECL, NULL_TREE, integer_type_node),
+ build_decl (input_location,
+ FIELD_DECL, NULL_TREE, integer_type_node),
+ build_decl (input_location,
+ FIELD_DECL, NULL_TREE, base_array),
+ NULL);
+ pop_abi_namespace ();
+ break;
+ }
+ }
+ default:
+ ix = TK_BUILTIN_TYPE;
+ break;
+ }
+ return ix;
+}
+
+/* Make sure the required builtin types exist for generating the type_info
+ variable definitions. */
+
+static void
+create_tinfo_types (void)
+{
+ tinfo_s *ti;
+
+ gcc_assert (!tinfo_descs);
+
+ vec_safe_grow (tinfo_descs, TK_FIXED);
+
+ push_abi_namespace ();
+
+ /* Create the internal type_info structure. This is used as a base for
+ the other structures. */
+ {
+ tree field, fields;
+
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, const_ptr_type_node);
+ fields = field;
+
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, const_string_type_node);
+ DECL_CHAIN (field) = fields;
+ fields = field;
+
+ ti = &(*tinfo_descs)[TK_TYPE_INFO_TYPE];
+ ti->type = make_class_type (RECORD_TYPE);
+ ti->vtable = NULL_TREE;
+ ti->name = NULL_TREE;
+ finish_builtin_struct (ti->type, "__type_info_pseudo",
+ fields, NULL_TREE);
+ }
+
+ /* Fundamental type_info */
+ create_pseudo_type_info (TK_BUILTIN_TYPE, "__fundamental_type_info", NULL);
+
+ /* Array, function and enum type_info. No additional fields. */
+ create_pseudo_type_info (TK_ARRAY_TYPE, "__array_type_info", NULL);
+ create_pseudo_type_info (TK_FUNCTION_TYPE, "__function_type_info", NULL);
+ create_pseudo_type_info (TK_ENUMERAL_TYPE, "__enum_type_info", NULL);
+
+ /* Class type_info. No additional fields. */
+ create_pseudo_type_info (TK_CLASS_TYPE, "__class_type_info", NULL);
+
+ /* Single public non-virtual base class. Add pointer to base class.
+ This is really a descendant of __class_type_info. */
+ create_pseudo_type_info (TK_SI_CLASS_TYPE, "__si_class_type_info",
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, type_info_ptr_type),
+ NULL);
+
+ /* Base class internal helper. Pointer to base type, offset to base,
+ flags. */
+ {
+ tree field, fields;
+
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, type_info_ptr_type);
+ fields = field;
+
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, LONGPTR_T);
+ DECL_CHAIN (field) = fields;
+ fields = field;
+
+ ti = &(*tinfo_descs)[TK_BASE_TYPE];
+
+ ti->type = make_class_type (RECORD_TYPE);
+ ti->vtable = NULL_TREE;
+ ti->name = NULL_TREE;
+ finish_builtin_struct (ti->type, "__base_class_type_info_pseudo",
+ fields, NULL_TREE);
+ }
+
+ /* Pointer type_info. Adds two fields, qualification mask
+ and pointer to the pointed to type. This is really a descendant of
+ __pbase_type_info. */
+ create_pseudo_type_info (TK_POINTER_TYPE, "__pointer_type_info",
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, integer_type_node),
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, type_info_ptr_type),
+ NULL);
+
+ /* Pointer to member data type_info. Add qualifications flags,
+ pointer to the member's type info and pointer to the class.
+ This is really a descendant of __pbase_type_info. */
+ create_pseudo_type_info (TK_POINTER_MEMBER_TYPE,
+ "__pointer_to_member_type_info",
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, integer_type_node),
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, type_info_ptr_type),
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, type_info_ptr_type),
+ NULL);
+
+ pop_abi_namespace ();
+}
+
+/* Emit the type_info descriptors which are guaranteed to be in the runtime
+ support. Generating them here guarantees consistency with the other
+ structures. We use the following heuristic to determine when the runtime
+ is being generated. If std::__fundamental_type_info is defined, and its
+ destructor is defined, then the runtime is being built. */
+
+void
+emit_support_tinfos (void)
+{
+ /* Dummy static variable so we can put nullptr in the array; it will be
+ set before we actually start to walk the array. */
+ static tree *const fundamentals[] =
+ {
+ &void_type_node,
+ &boolean_type_node,
+ &wchar_type_node, &char16_type_node, &char32_type_node,
+ &char_type_node, &signed_char_type_node, &unsigned_char_type_node,
+ &short_integer_type_node, &short_unsigned_type_node,
+ &integer_type_node, &unsigned_type_node,
+ &long_integer_type_node, &long_unsigned_type_node,
+ &long_long_integer_type_node, &long_long_unsigned_type_node,
+ &int128_integer_type_node, &int128_unsigned_type_node,
+ &float_type_node, &double_type_node, &long_double_type_node,
+ &dfloat32_type_node, &dfloat64_type_node, &dfloat128_type_node,
+ &nullptr_type_node,
+ 0
+ };
+ int ix;
+ tree bltn_type, dtor;
+
+ push_abi_namespace ();
+ bltn_type = xref_tag (class_type,
+ get_identifier ("__fundamental_type_info"),
+ /*tag_scope=*/ts_current, false);
+ pop_abi_namespace ();
+ if (!COMPLETE_TYPE_P (bltn_type))
+ return;
+ dtor = CLASSTYPE_DESTRUCTORS (bltn_type);
+ if (!dtor || DECL_EXTERNAL (dtor))
+ return;
+ doing_runtime = 1;
+ for (ix = 0; fundamentals[ix]; ix++)
+ {
+ tree bltn = *fundamentals[ix];
+ tree types[3];
+ int i;
+
+ if (bltn == NULL_TREE)
+ continue;
+ types[0] = bltn;
+ types[1] = build_pointer_type (bltn);
+ types[2] = build_pointer_type (cp_build_qualified_type (bltn,
+ TYPE_QUAL_CONST));
+
+ for (i = 0; i < 3; ++i)
+ {
+ tree tinfo;
+
+ tinfo = get_tinfo_decl (types[i]);
+ TREE_USED (tinfo) = 1;
+ mark_needed (tinfo);
+ /* The C++ ABI requires that these objects be COMDAT. But,
+ On systems without weak symbols, initialized COMDAT
+ objects are emitted with internal linkage. (See
+ comdat_linkage for details.) Since we want these objects
+ to have external linkage so that copies do not have to be
+ emitted in code outside the runtime library, we make them
+ non-COMDAT here.
+
+ It might also not be necessary to follow this detail of the
+ ABI. */
+ if (!flag_weak || ! targetm.cxx.library_rtti_comdat ())
+ {
+ gcc_assert (TREE_PUBLIC (tinfo) && !DECL_COMDAT (tinfo));
+ DECL_INTERFACE_KNOWN (tinfo) = 1;
+ }
+ }
+ }
+}
+
+/* Finish a type info decl. DECL_PTR is a pointer to an unemitted
+ tinfo decl. Determine whether it needs emitting, and if so
+ generate the initializer. */
+
+bool
+emit_tinfo_decl (tree decl)
+{
+ tree type = TREE_TYPE (DECL_NAME (decl));
+ int in_library = typeinfo_in_lib_p (type);
+
+ gcc_assert (DECL_TINFO_P (decl));
+
+ if (in_library)
+ {
+ if (doing_runtime)
+ DECL_EXTERNAL (decl) = 0;
+ else
+ {
+ /* If we're not in the runtime, then DECL (which is already
+ DECL_EXTERNAL) will not be defined here. */
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ return false;
+ }
+ }
+ else if (involves_incomplete_p (type))
+ {
+ if (!decl_needed_p (decl))
+ return false;
+ /* If TYPE involves an incomplete class type, then the typeinfo
+ object will be emitted with internal linkage. There is no
+ way to know whether or not types are incomplete until the end
+ of the compilation, so this determination must be deferred
+ until this point. */
+ TREE_PUBLIC (decl) = 0;
+ DECL_EXTERNAL (decl) = 0;
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ }
+
+ import_export_decl (decl);
+ if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl))
+ {
+ tree init;
+
+ DECL_EXTERNAL (decl) = 0;
+ init = get_pseudo_ti_init (type, get_pseudo_ti_index (type));
+ DECL_INITIAL (decl) = init;
+ mark_used (decl);
+ cp_finish_decl (decl, init, false, NULL_TREE, 0);
+ return true;
+ }
+ else
+ return false;
+}
+
+#include "gt-cp-rtti.h"
diff --git a/gcc-4.9/gcc/cp/search.c b/gcc-4.9/gcc/cp/search.c
new file mode 100644
index 000000000..d99e18215
--- /dev/null
+++ b/gcc-4.9/gcc/cp/search.c
@@ -0,0 +1,2691 @@
+/* Breadth-first and depth-first routines for
+ searching multiple-inheritance lattice for GNU C++.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Contributed by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* High-level class interface. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "cp-tree.h"
+#include "intl.h"
+#include "flags.h"
+#include "toplev.h"
+#include "target.h"
+
+static int is_subobject_of_p (tree, tree);
+static tree dfs_lookup_base (tree, void *);
+static tree dfs_dcast_hint_pre (tree, void *);
+static tree dfs_dcast_hint_post (tree, void *);
+static tree dfs_debug_mark (tree, void *);
+static tree dfs_walk_once_r (tree, tree (*pre_fn) (tree, void *),
+ tree (*post_fn) (tree, void *), void *data);
+static void dfs_unmark_r (tree);
+static int check_hidden_convs (tree, int, int, tree, tree, tree);
+static tree split_conversions (tree, tree, tree, tree);
+static int lookup_conversions_r (tree, int, int,
+ tree, tree, tree, tree, tree *, tree *);
+static int look_for_overrides_r (tree, tree);
+static tree lookup_field_r (tree, void *);
+static tree dfs_accessible_post (tree, void *);
+static tree dfs_walk_once_accessible_r (tree, bool, bool,
+ tree (*pre_fn) (tree, void *),
+ tree (*post_fn) (tree, void *),
+ void *data);
+static tree dfs_walk_once_accessible (tree, bool,
+ tree (*pre_fn) (tree, void *),
+ tree (*post_fn) (tree, void *),
+ void *data);
+static tree dfs_access_in_type (tree, void *);
+static access_kind access_in_type (tree, tree);
+static int protected_accessible_p (tree, tree, tree);
+static int friend_accessible_p (tree, tree, tree);
+static tree dfs_get_pure_virtuals (tree, void *);
+
+
+/* Variables for gathering statistics. */
+static int n_fields_searched;
+static int n_calls_lookup_field, n_calls_lookup_field_1;
+static int n_calls_lookup_fnfields, n_calls_lookup_fnfields_1;
+static int n_calls_get_base_type;
+static int n_outer_fields_searched;
+static int n_contexts_saved;
+
+
+/* Data for lookup_base and its workers. */
+
+struct lookup_base_data_s
+{
+ tree t; /* type being searched. */
+ tree base; /* The base type we're looking for. */
+ tree binfo; /* Found binfo. */
+ bool via_virtual; /* Found via a virtual path. */
+ bool ambiguous; /* Found multiply ambiguous */
+ bool repeated_base; /* Whether there are repeated bases in the
+ hierarchy. */
+ bool want_any; /* Whether we want any matching binfo. */
+};
+
+/* Worker function for lookup_base. See if we've found the desired
+ base and update DATA_ (a pointer to LOOKUP_BASE_DATA_S). */
+
+static tree
+dfs_lookup_base (tree binfo, void *data_)
+{
+ struct lookup_base_data_s *data = (struct lookup_base_data_s *) data_;
+
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->base))
+ {
+ if (!data->binfo)
+ {
+ data->binfo = binfo;
+ data->via_virtual
+ = binfo_via_virtual (data->binfo, data->t) != NULL_TREE;
+
+ if (!data->repeated_base)
+ /* If there are no repeated bases, we can stop now. */
+ return binfo;
+
+ if (data->want_any && !data->via_virtual)
+ /* If this is a non-virtual base, then we can't do
+ better. */
+ return binfo;
+
+ return dfs_skip_bases;
+ }
+ else
+ {
+ gcc_assert (binfo != data->binfo);
+
+ /* We've found more than one matching binfo. */
+ if (!data->want_any)
+ {
+ /* This is immediately ambiguous. */
+ data->binfo = NULL_TREE;
+ data->ambiguous = true;
+ return error_mark_node;
+ }
+
+ /* Prefer one via a non-virtual path. */
+ if (!binfo_via_virtual (binfo, data->t))
+ {
+ data->binfo = binfo;
+ data->via_virtual = false;
+ return binfo;
+ }
+
+ /* There must be repeated bases, otherwise we'd have stopped
+ on the first base we found. */
+ return dfs_skip_bases;
+ }
+ }
+
+ return NULL_TREE;
+}
+
+/* Returns true if type BASE is accessible in T. (BASE is known to be
+ a (possibly non-proper) base class of T.) If CONSIDER_LOCAL_P is
+ true, consider any special access of the current scope, or access
+ bestowed by friendship. */
+
+bool
+accessible_base_p (tree t, tree base, bool consider_local_p)
+{
+ tree decl;
+
+ /* [class.access.base]
+
+ A base class is said to be accessible if an invented public
+ member of the base class is accessible.
+
+ If BASE is a non-proper base, this condition is trivially
+ true. */
+ if (same_type_p (t, base))
+ return true;
+ /* Rather than inventing a public member, we use the implicit
+ public typedef created in the scope of every class. */
+ decl = TYPE_FIELDS (base);
+ while (!DECL_SELF_REFERENCE_P (decl))
+ decl = DECL_CHAIN (decl);
+ while (ANON_AGGR_TYPE_P (t))
+ t = TYPE_CONTEXT (t);
+ return accessible_p (t, decl, consider_local_p);
+}
+
+/* Lookup BASE in the hierarchy dominated by T. Do access checking as
+ ACCESS specifies. Return the binfo we discover. If KIND_PTR is
+ non-NULL, fill with information about what kind of base we
+ discovered.
+
+ If the base is inaccessible, or ambiguous, then error_mark_node is
+ returned. If the tf_error bit of COMPLAIN is not set, no error
+ is issued. */
+
+tree
+lookup_base (tree t, tree base, base_access access,
+ base_kind *kind_ptr, tsubst_flags_t complain)
+{
+ tree binfo;
+ tree t_binfo;
+ base_kind bk;
+
+ /* "Nothing" is definitely not derived from Base. */
+ if (t == NULL_TREE)
+ {
+ if (kind_ptr)
+ *kind_ptr = bk_not_base;
+ return NULL_TREE;
+ }
+
+ if (t == error_mark_node || base == error_mark_node)
+ {
+ if (kind_ptr)
+ *kind_ptr = bk_not_base;
+ return error_mark_node;
+ }
+ gcc_assert (TYPE_P (base));
+
+ if (!TYPE_P (t))
+ {
+ t_binfo = t;
+ t = BINFO_TYPE (t);
+ }
+ else
+ {
+ t = complete_type (TYPE_MAIN_VARIANT (t));
+ t_binfo = TYPE_BINFO (t);
+ }
+
+ base = TYPE_MAIN_VARIANT (base);
+
+ /* If BASE is incomplete, it can't be a base of T--and instantiating it
+ might cause an error. */
+ if (t_binfo && CLASS_TYPE_P (base) && COMPLETE_OR_OPEN_TYPE_P (base))
+ {
+ struct lookup_base_data_s data;
+
+ data.t = t;
+ data.base = base;
+ data.binfo = NULL_TREE;
+ data.ambiguous = data.via_virtual = false;
+ data.repeated_base = CLASSTYPE_REPEATED_BASE_P (t);
+ data.want_any = access == ba_any;
+
+ dfs_walk_once (t_binfo, dfs_lookup_base, NULL, &data);
+ binfo = data.binfo;
+
+ if (!binfo)
+ bk = data.ambiguous ? bk_ambig : bk_not_base;
+ else if (binfo == t_binfo)
+ bk = bk_same_type;
+ else if (data.via_virtual)
+ bk = bk_via_virtual;
+ else
+ bk = bk_proper_base;
+ }
+ else
+ {
+ binfo = NULL_TREE;
+ bk = bk_not_base;
+ }
+
+ /* Check that the base is unambiguous and accessible. */
+ if (access != ba_any)
+ switch (bk)
+ {
+ case bk_not_base:
+ break;
+
+ case bk_ambig:
+ if (complain & tf_error)
+ error ("%qT is an ambiguous base of %qT", base, t);
+ binfo = error_mark_node;
+ break;
+
+ default:
+ if ((access & ba_check_bit)
+ /* If BASE is incomplete, then BASE and TYPE are probably
+ the same, in which case BASE is accessible. If they
+ are not the same, then TYPE is invalid. In that case,
+ there's no need to issue another error here, and
+ there's no implicit typedef to use in the code that
+ follows, so we skip the check. */
+ && COMPLETE_TYPE_P (base)
+ && !accessible_base_p (t, base, !(access & ba_ignore_scope)))
+ {
+ if (complain & tf_error)
+ error ("%qT is an inaccessible base of %qT", base, t);
+ binfo = error_mark_node;
+ bk = bk_inaccessible;
+ }
+ break;
+ }
+
+ if (kind_ptr)
+ *kind_ptr = bk;
+
+ return binfo;
+}
+
+/* Data for dcast_base_hint walker. */
+
+struct dcast_data_s
+{
+ tree subtype; /* The base type we're looking for. */
+ int virt_depth; /* Number of virtual bases encountered from most
+ derived. */
+ tree offset; /* Best hint offset discovered so far. */
+ bool repeated_base; /* Whether there are repeated bases in the
+ hierarchy. */
+};
+
+/* Worker for dcast_base_hint. Search for the base type being cast
+ from. */
+
+static tree
+dfs_dcast_hint_pre (tree binfo, void *data_)
+{
+ struct dcast_data_s *data = (struct dcast_data_s *) data_;
+
+ if (BINFO_VIRTUAL_P (binfo))
+ data->virt_depth++;
+
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->subtype))
+ {
+ if (data->virt_depth)
+ {
+ data->offset = ssize_int (-1);
+ return data->offset;
+ }
+ if (data->offset)
+ data->offset = ssize_int (-3);
+ else
+ data->offset = BINFO_OFFSET (binfo);
+
+ return data->repeated_base ? dfs_skip_bases : data->offset;
+ }
+
+ return NULL_TREE;
+}
+
+/* Worker for dcast_base_hint. Track the virtual depth. */
+
+static tree
+dfs_dcast_hint_post (tree binfo, void *data_)
+{
+ struct dcast_data_s *data = (struct dcast_data_s *) data_;
+
+ if (BINFO_VIRTUAL_P (binfo))
+ data->virt_depth--;
+
+ return NULL_TREE;
+}
+
+/* The dynamic cast runtime needs a hint about how the static SUBTYPE type
+ started from is related to the required TARGET type, in order to optimize
+ the inheritance graph search. This information is independent of the
+ current context, and ignores private paths, hence get_base_distance is
+ inappropriate. Return a TREE specifying the base offset, BOFF.
+ BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset BOFF,
+ and there are no public virtual SUBTYPE bases.
+ BOFF == -1, SUBTYPE occurs as multiple public virtual or non-virtual bases.
+ BOFF == -2, SUBTYPE is not a public base.
+ BOFF == -3, SUBTYPE occurs as multiple public non-virtual bases. */
+
+tree
+dcast_base_hint (tree subtype, tree target)
+{
+ struct dcast_data_s data;
+
+ data.subtype = subtype;
+ data.virt_depth = 0;
+ data.offset = NULL_TREE;
+ data.repeated_base = CLASSTYPE_REPEATED_BASE_P (target);
+
+ dfs_walk_once_accessible (TYPE_BINFO (target), /*friends=*/false,
+ dfs_dcast_hint_pre, dfs_dcast_hint_post, &data);
+ return data.offset ? data.offset : ssize_int (-2);
+}
+
+/* Search for a member with name NAME in a multiple inheritance
+ lattice specified by TYPE. If it does not exist, return NULL_TREE.
+ If the member is ambiguously referenced, return `error_mark_node'.
+ Otherwise, return a DECL with the indicated name. If WANT_TYPE is
+ true, type declarations are preferred. */
+
+/* Do a 1-level search for NAME as a member of TYPE. The caller must
+ figure out whether it can access this field. (Since it is only one
+ level, this is reasonable.) */
+
+tree
+lookup_field_1 (tree type, tree name, bool want_type)
+{
+ tree field;
+
+ gcc_assert (identifier_p (name));
+
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
+ || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (type) == TYPENAME_TYPE)
+ /* The TYPE_FIELDS of a TEMPLATE_TYPE_PARM and
+ BOUND_TEMPLATE_TEMPLATE_PARM are not fields at all;
+ instead TYPE_FIELDS is the TEMPLATE_PARM_INDEX. (Miraculously,
+ the code often worked even when we treated the index as a list
+ of fields!)
+ The TYPE_FIELDS of TYPENAME_TYPE is its TYPENAME_TYPE_FULLNAME. */
+ return NULL_TREE;
+
+ if (CLASSTYPE_SORTED_FIELDS (type))
+ {
+ tree *fields = &CLASSTYPE_SORTED_FIELDS (type)->elts[0];
+ int lo = 0, hi = CLASSTYPE_SORTED_FIELDS (type)->len;
+ int i;
+
+ while (lo < hi)
+ {
+ i = (lo + hi) / 2;
+
+ if (GATHER_STATISTICS)
+ n_fields_searched++;
+
+ if (DECL_NAME (fields[i]) > name)
+ hi = i;
+ else if (DECL_NAME (fields[i]) < name)
+ lo = i + 1;
+ else
+ {
+ field = NULL_TREE;
+
+ /* We might have a nested class and a field with the
+ same name; we sorted them appropriately via
+ field_decl_cmp, so just look for the first or last
+ field with this name. */
+ if (want_type)
+ {
+ do
+ field = fields[i--];
+ while (i >= lo && DECL_NAME (fields[i]) == name);
+ if (!DECL_DECLARES_TYPE_P (field))
+ field = NULL_TREE;
+ }
+ else
+ {
+ do
+ field = fields[i++];
+ while (i < hi && DECL_NAME (fields[i]) == name);
+ }
+
+ if (field)
+ {
+ field = strip_using_decl (field);
+ if (is_overloaded_fn (field))
+ field = NULL_TREE;
+ }
+
+ return field;
+ }
+ }
+ return NULL_TREE;
+ }
+
+ field = TYPE_FIELDS (type);
+
+ if (GATHER_STATISTICS)
+ n_calls_lookup_field_1++;
+
+ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ {
+ tree decl = field;
+
+ if (GATHER_STATISTICS)
+ n_fields_searched++;
+
+ gcc_assert (DECL_P (field));
+ if (DECL_NAME (field) == NULL_TREE
+ && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
+ {
+ tree temp = lookup_field_1 (TREE_TYPE (field), name, want_type);
+ if (temp)
+ return temp;
+ }
+
+ if (TREE_CODE (decl) == USING_DECL
+ && DECL_NAME (decl) == name)
+ {
+ decl = strip_using_decl (decl);
+ if (is_overloaded_fn (decl))
+ continue;
+ }
+
+ if (DECL_NAME (decl) == name
+ && (!want_type || DECL_DECLARES_TYPE_P (decl)))
+ return decl;
+ }
+ /* Not found. */
+ if (name == vptr_identifier)
+ {
+ /* Give the user what s/he thinks s/he wants. */
+ if (TYPE_POLYMORPHIC_P (type))
+ return TYPE_VFIELD (type);
+ }
+ return NULL_TREE;
+}
+
+/* Return the FUNCTION_DECL, RECORD_TYPE, UNION_TYPE, or
+ NAMESPACE_DECL corresponding to the innermost non-block scope. */
+
+tree
+current_scope (void)
+{
+ /* There are a number of cases we need to be aware of here:
+ current_class_type current_function_decl
+ global NULL NULL
+ fn-local NULL SET
+ class-local SET NULL
+ class->fn SET SET
+ fn->class SET SET
+
+ Those last two make life interesting. If we're in a function which is
+ itself inside a class, we need decls to go into the fn's decls (our
+ second case below). But if we're in a class and the class itself is
+ inside a function, we need decls to go into the decls for the class. To
+ achieve this last goal, we must see if, when both current_class_ptr and
+ current_function_decl are set, the class was declared inside that
+ function. If so, we know to put the decls into the class's scope. */
+ if (current_function_decl && current_class_type
+ && ((DECL_FUNCTION_MEMBER_P (current_function_decl)
+ && same_type_p (DECL_CONTEXT (current_function_decl),
+ current_class_type))
+ || (DECL_FRIEND_CONTEXT (current_function_decl)
+ && same_type_p (DECL_FRIEND_CONTEXT (current_function_decl),
+ current_class_type))))
+ return current_function_decl;
+ if (current_class_type)
+ return current_class_type;
+ if (current_function_decl)
+ return current_function_decl;
+ return current_namespace;
+}
+
+/* Returns nonzero if we are currently in a function scope. Note
+ that this function returns zero if we are within a local class, but
+ not within a member function body of the local class. */
+
+int
+at_function_scope_p (void)
+{
+ tree cs = current_scope ();
+ /* Also check cfun to make sure that we're really compiling
+ this function (as opposed to having set current_function_decl
+ for access checking or some such). */
+ return (cs && TREE_CODE (cs) == FUNCTION_DECL
+ && cfun && cfun->decl == current_function_decl);
+}
+
+/* Returns true if the innermost active scope is a class scope. */
+
+bool
+at_class_scope_p (void)
+{
+ tree cs = current_scope ();
+ return cs && TYPE_P (cs);
+}
+
+/* Returns true if the innermost active scope is a namespace scope. */
+
+bool
+at_namespace_scope_p (void)
+{
+ tree cs = current_scope ();
+ return cs && TREE_CODE (cs) == NAMESPACE_DECL;
+}
+
+/* Return the scope of DECL, as appropriate when doing name-lookup. */
+
+tree
+context_for_name_lookup (tree decl)
+{
+ /* [class.union]
+
+ For the purposes of name lookup, after the anonymous union
+ definition, the members of the anonymous union are considered to
+ have been defined in the scope in which the anonymous union is
+ declared. */
+ tree context = DECL_CONTEXT (decl);
+
+ while (context && TYPE_P (context)
+ && (ANON_AGGR_TYPE_P (context) || UNSCOPED_ENUM_P (context)))
+ context = TYPE_CONTEXT (context);
+ if (!context)
+ context = global_namespace;
+
+ return context;
+}
+
+/* The accessibility routines use BINFO_ACCESS for scratch space
+ during the computation of the accessibility of some declaration. */
+
+#define BINFO_ACCESS(NODE) \
+ ((access_kind) ((TREE_PUBLIC (NODE) << 1) | TREE_PRIVATE (NODE)))
+
+/* Set the access associated with NODE to ACCESS. */
+
+#define SET_BINFO_ACCESS(NODE, ACCESS) \
+ ((TREE_PUBLIC (NODE) = ((ACCESS) & 2) != 0), \
+ (TREE_PRIVATE (NODE) = ((ACCESS) & 1) != 0))
+
+/* Called from access_in_type via dfs_walk. Calculate the access to
+ DATA (which is really a DECL) in BINFO. */
+
+static tree
+dfs_access_in_type (tree binfo, void *data)
+{
+ tree decl = (tree) data;
+ tree type = BINFO_TYPE (binfo);
+ access_kind access = ak_none;
+
+ if (context_for_name_lookup (decl) == type)
+ {
+ /* If we have descended to the scope of DECL, just note the
+ appropriate access. */
+ if (TREE_PRIVATE (decl))
+ access = ak_private;
+ else if (TREE_PROTECTED (decl))
+ access = ak_protected;
+ else
+ access = ak_public;
+ }
+ else
+ {
+ /* First, check for an access-declaration that gives us more
+ access to the DECL. */
+ if (DECL_LANG_SPECIFIC (decl) && !DECL_DISCRIMINATOR_P (decl))
+ {
+ tree decl_access = purpose_member (type, DECL_ACCESS (decl));
+
+ if (decl_access)
+ {
+ decl_access = TREE_VALUE (decl_access);
+
+ if (decl_access == access_public_node)
+ access = ak_public;
+ else if (decl_access == access_protected_node)
+ access = ak_protected;
+ else if (decl_access == access_private_node)
+ access = ak_private;
+ else
+ gcc_unreachable ();
+ }
+ }
+
+ if (!access)
+ {
+ int i;
+ tree base_binfo;
+ vec<tree, va_gc> *accesses;
+
+ /* Otherwise, scan our baseclasses, and pick the most favorable
+ access. */
+ accesses = BINFO_BASE_ACCESSES (binfo);
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ {
+ tree base_access = (*accesses)[i];
+ access_kind base_access_now = BINFO_ACCESS (base_binfo);
+
+ if (base_access_now == ak_none || base_access_now == ak_private)
+ /* If it was not accessible in the base, or only
+ accessible as a private member, we can't access it
+ all. */
+ base_access_now = ak_none;
+ else if (base_access == access_protected_node)
+ /* Public and protected members in the base become
+ protected here. */
+ base_access_now = ak_protected;
+ else if (base_access == access_private_node)
+ /* Public and protected members in the base become
+ private here. */
+ base_access_now = ak_private;
+
+ /* See if the new access, via this base, gives more
+ access than our previous best access. */
+ if (base_access_now != ak_none
+ && (access == ak_none || base_access_now < access))
+ {
+ access = base_access_now;
+
+ /* If the new access is public, we can't do better. */
+ if (access == ak_public)
+ break;
+ }
+ }
+ }
+ }
+
+ /* Note the access to DECL in TYPE. */
+ SET_BINFO_ACCESS (binfo, access);
+
+ return NULL_TREE;
+}
+
+/* Return the access to DECL in TYPE. */
+
+static access_kind
+access_in_type (tree type, tree decl)
+{
+ tree binfo = TYPE_BINFO (type);
+
+ /* We must take into account
+
+ [class.paths]
+
+ If a name can be reached by several paths through a multiple
+ inheritance graph, the access is that of the path that gives
+ most access.
+
+ The algorithm we use is to make a post-order depth-first traversal
+ of the base-class hierarchy. As we come up the tree, we annotate
+ each node with the most lenient access. */
+ dfs_walk_once (binfo, NULL, dfs_access_in_type, decl);
+
+ return BINFO_ACCESS (binfo);
+}
+
+/* Returns nonzero if it is OK to access DECL through an object
+ indicated by BINFO in the context of DERIVED. */
+
+static int
+protected_accessible_p (tree decl, tree derived, tree binfo)
+{
+ access_kind access;
+
+ /* We're checking this clause from [class.access.base]
+
+ m as a member of N is protected, and the reference occurs in a
+ member or friend of class N, or in a member or friend of a
+ class P derived from N, where m as a member of P is public, private
+ or protected.
+
+ Here DERIVED is a possible P, DECL is m and BINFO_TYPE (binfo) is N. */
+
+ /* If DERIVED isn't derived from N, then it can't be a P. */
+ if (!DERIVED_FROM_P (BINFO_TYPE (binfo), derived))
+ return 0;
+
+ access = access_in_type (derived, decl);
+
+ /* If m is inaccessible in DERIVED, then it's not a P. */
+ if (access == ak_none)
+ return 0;
+
+ /* [class.protected]
+
+ When a friend or a member function of a derived class references
+ a protected nonstatic member of a base class, an access check
+ applies in addition to those described earlier in clause
+ _class.access_) Except when forming a pointer to member
+ (_expr.unary.op_), the access must be through a pointer to,
+ reference to, or object of the derived class itself (or any class
+ derived from that class) (_expr.ref_). If the access is to form
+ a pointer to member, the nested-name-specifier shall name the
+ derived class (or any class derived from that class). */
+ if (DECL_NONSTATIC_MEMBER_P (decl))
+ {
+ /* We can tell through what the reference is occurring by
+ chasing BINFO up to the root. */
+ tree t = binfo;
+ while (BINFO_INHERITANCE_CHAIN (t))
+ t = BINFO_INHERITANCE_CHAIN (t);
+
+ if (!DERIVED_FROM_P (derived, BINFO_TYPE (t)))
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Returns nonzero if SCOPE is a friend of a type which would be able
+ to access DECL through the object indicated by BINFO. */
+
+static int
+friend_accessible_p (tree scope, tree decl, tree binfo)
+{
+ tree befriending_classes;
+ tree t;
+
+ if (!scope)
+ return 0;
+
+ if (DECL_DECLARES_FUNCTION_P (scope))
+ befriending_classes = DECL_BEFRIENDING_CLASSES (scope);
+ else if (TYPE_P (scope))
+ befriending_classes = CLASSTYPE_BEFRIENDING_CLASSES (scope);
+ else
+ return 0;
+
+ for (t = befriending_classes; t; t = TREE_CHAIN (t))
+ if (protected_accessible_p (decl, TREE_VALUE (t), binfo))
+ return 1;
+
+ /* Nested classes have the same access as their enclosing types, as
+ per DR 45 (this is a change from the standard). */
+ if (TYPE_P (scope))
+ for (t = TYPE_CONTEXT (scope); t && TYPE_P (t); t = TYPE_CONTEXT (t))
+ if (protected_accessible_p (decl, t, binfo))
+ return 1;
+
+ if (DECL_DECLARES_FUNCTION_P (scope))
+ {
+ /* Perhaps this SCOPE is a member of a class which is a
+ friend. */
+ if (DECL_CLASS_SCOPE_P (scope)
+ && friend_accessible_p (DECL_CONTEXT (scope), decl, binfo))
+ return 1;
+
+ /* Or an instantiation of something which is a friend. */
+ if (DECL_TEMPLATE_INFO (scope))
+ {
+ int ret;
+ /* Increment processing_template_decl to make sure that
+ dependent_type_p works correctly. */
+ ++processing_template_decl;
+ ret = friend_accessible_p (DECL_TI_TEMPLATE (scope), decl, binfo);
+ --processing_template_decl;
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/* Called via dfs_walk_once_accessible from accessible_p */
+
+static tree
+dfs_accessible_post (tree binfo, void * /*data*/)
+{
+ if (BINFO_ACCESS (binfo) != ak_none)
+ {
+ tree scope = current_scope ();
+ if (scope && TREE_CODE (scope) != NAMESPACE_DECL
+ && is_friend (BINFO_TYPE (binfo), scope))
+ return binfo;
+ }
+
+ return NULL_TREE;
+}
+
+/* Like accessible_p below, but within a template returns true iff DECL is
+ accessible in TYPE to all possible instantiations of the template. */
+
+int
+accessible_in_template_p (tree type, tree decl)
+{
+ int save_ptd = processing_template_decl;
+ processing_template_decl = 0;
+ int val = accessible_p (type, decl, false);
+ processing_template_decl = save_ptd;
+ return val;
+}
+
+/* DECL is a declaration from a base class of TYPE, which was the
+ class used to name DECL. Return nonzero if, in the current
+ context, DECL is accessible. If TYPE is actually a BINFO node,
+ then we can tell in what context the access is occurring by looking
+ at the most derived class along the path indicated by BINFO. If
+ CONSIDER_LOCAL is true, do consider special access the current
+ scope or friendship thereof we might have. */
+
+int
+accessible_p (tree type, tree decl, bool consider_local_p)
+{
+ tree binfo;
+ tree scope;
+ access_kind access;
+
+ /* Nonzero if it's OK to access DECL if it has protected
+ accessibility in TYPE. */
+ int protected_ok = 0;
+
+ /* If this declaration is in a block or namespace scope, there's no
+ access control. */
+ if (!TYPE_P (context_for_name_lookup (decl)))
+ return 1;
+
+ /* There is no need to perform access checks inside a thunk. */
+ scope = current_scope ();
+ if (scope && DECL_THUNK_P (scope))
+ return 1;
+
+ /* In a template declaration, we cannot be sure whether the
+ particular specialization that is instantiated will be a friend
+ or not. Therefore, all access checks are deferred until
+ instantiation. However, PROCESSING_TEMPLATE_DECL is set in the
+ parameter list for a template (because we may see dependent types
+ in default arguments for template parameters), and access
+ checking should be performed in the outermost parameter list. */
+ if (processing_template_decl
+ && (!processing_template_parmlist || processing_template_decl > 1))
+ return 1;
+
+ if (!TYPE_P (type))
+ {
+ binfo = type;
+ type = BINFO_TYPE (type);
+ }
+ else
+ binfo = TYPE_BINFO (type);
+
+ /* [class.access.base]
+
+ A member m is accessible when named in class N if
+
+ --m as a member of N is public, or
+
+ --m as a member of N is private, and the reference occurs in a
+ member or friend of class N, or
+
+ --m as a member of N is protected, and the reference occurs in a
+ member or friend of class N, or in a member or friend of a
+ class P derived from N, where m as a member of P is private or
+ protected, or
+
+ --there exists a base class B of N that is accessible at the point
+ of reference, and m is accessible when named in class B.
+
+ We walk the base class hierarchy, checking these conditions. */
+
+ if (consider_local_p)
+ {
+ /* Figure out where the reference is occurring. Check to see if
+ DECL is private or protected in this scope, since that will
+ determine whether protected access is allowed. */
+ if (current_class_type)
+ protected_ok = protected_accessible_p (decl,
+ current_class_type, binfo);
+
+ /* Now, loop through the classes of which we are a friend. */
+ if (!protected_ok)
+ protected_ok = friend_accessible_p (scope, decl, binfo);
+ }
+
+ /* Standardize the binfo that access_in_type will use. We don't
+ need to know what path was chosen from this point onwards. */
+ binfo = TYPE_BINFO (type);
+
+ /* Compute the accessibility of DECL in the class hierarchy
+ dominated by type. */
+ access = access_in_type (type, decl);
+ if (access == ak_public
+ || (access == ak_protected && protected_ok))
+ return 1;
+
+ if (!consider_local_p)
+ return 0;
+
+ /* Walk the hierarchy again, looking for a base class that allows
+ access. */
+ return dfs_walk_once_accessible (binfo, /*friends=*/true,
+ NULL, dfs_accessible_post, NULL)
+ != NULL_TREE;
+}
+
+struct lookup_field_info {
+ /* The type in which we're looking. */
+ tree type;
+ /* The name of the field for which we're looking. */
+ tree name;
+ /* If non-NULL, the current result of the lookup. */
+ tree rval;
+ /* The path to RVAL. */
+ tree rval_binfo;
+ /* If non-NULL, the lookup was ambiguous, and this is a list of the
+ candidates. */
+ tree ambiguous;
+ /* If nonzero, we are looking for types, not data members. */
+ int want_type;
+ /* If something went wrong, a message indicating what. */
+ const char *errstr;
+};
+
+/* Nonzero for a class member means that it is shared between all objects
+ of that class.
+
+ [class.member.lookup]:If the resulting set of declarations are not all
+ from sub-objects of the same type, or the set has a nonstatic member
+ and includes members from distinct sub-objects, there is an ambiguity
+ and the program is ill-formed.
+
+ This function checks that T contains no nonstatic members. */
+
+int
+shared_member_p (tree t)
+{
+ if (VAR_P (t) || TREE_CODE (t) == TYPE_DECL \
+ || TREE_CODE (t) == CONST_DECL)
+ return 1;
+ if (is_overloaded_fn (t))
+ {
+ t = get_fns (t);
+ for (; t; t = OVL_NEXT (t))
+ {
+ tree fn = OVL_CURRENT (t);
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+ return 0;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/* Routine to see if the sub-object denoted by the binfo PARENT can be
+ found as a base class and sub-object of the object denoted by
+ BINFO. */
+
+static int
+is_subobject_of_p (tree parent, tree binfo)
+{
+ tree probe;
+
+ for (probe = parent; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
+ {
+ if (probe == binfo)
+ return 1;
+ if (BINFO_VIRTUAL_P (probe))
+ return (binfo_for_vbase (BINFO_TYPE (probe), BINFO_TYPE (binfo))
+ != NULL_TREE);
+ }
+ return 0;
+}
+
+/* DATA is really a struct lookup_field_info. Look for a field with
+ the name indicated there in BINFO. If this function returns a
+ non-NULL value it is the result of the lookup. Called from
+ lookup_field via breadth_first_search. */
+
+static tree
+lookup_field_r (tree binfo, void *data)
+{
+ struct lookup_field_info *lfi = (struct lookup_field_info *) data;
+ tree type = BINFO_TYPE (binfo);
+ tree nval = NULL_TREE;
+
+ /* If this is a dependent base, don't look in it. */
+ if (BINFO_DEPENDENT_BASE_P (binfo))
+ return NULL_TREE;
+
+ /* If this base class is hidden by the best-known value so far, we
+ don't need to look. */
+ if (lfi->rval_binfo && BINFO_INHERITANCE_CHAIN (binfo) == lfi->rval_binfo
+ && !BINFO_VIRTUAL_P (binfo))
+ return dfs_skip_bases;
+
+ /* First, look for a function. There can't be a function and a data
+ member with the same name, and if there's a function and a type
+ with the same name, the type is hidden by the function. */
+ if (!lfi->want_type)
+ nval = lookup_fnfields_slot (type, lfi->name);
+
+ if (!nval)
+ /* Look for a data member or type. */
+ nval = lookup_field_1 (type, lfi->name, lfi->want_type);
+
+ /* If there is no declaration with the indicated name in this type,
+ then there's nothing to do. */
+ if (!nval)
+ goto done;
+
+ /* If we're looking up a type (as with an elaborated type specifier)
+ we ignore all non-types we find. */
+ if (lfi->want_type && !DECL_DECLARES_TYPE_P (nval))
+ {
+ if (lfi->name == TYPE_IDENTIFIER (type))
+ {
+ /* If the aggregate has no user defined constructors, we allow
+ it to have fields with the same name as the enclosing type.
+ If we are looking for that name, find the corresponding
+ TYPE_DECL. */
+ for (nval = TREE_CHAIN (nval); nval; nval = TREE_CHAIN (nval))
+ if (DECL_NAME (nval) == lfi->name
+ && TREE_CODE (nval) == TYPE_DECL)
+ break;
+ }
+ else
+ nval = NULL_TREE;
+ if (!nval && CLASSTYPE_NESTED_UTDS (type) != NULL)
+ {
+ binding_entry e = binding_table_find (CLASSTYPE_NESTED_UTDS (type),
+ lfi->name);
+ if (e != NULL)
+ nval = TYPE_MAIN_DECL (e->type);
+ else
+ goto done;
+ }
+ }
+
+ /* If the lookup already found a match, and the new value doesn't
+ hide the old one, we might have an ambiguity. */
+ if (lfi->rval_binfo
+ && !is_subobject_of_p (lfi->rval_binfo, binfo))
+
+ {
+ if (nval == lfi->rval && shared_member_p (nval))
+ /* The two things are really the same. */
+ ;
+ else if (is_subobject_of_p (binfo, lfi->rval_binfo))
+ /* The previous value hides the new one. */
+ ;
+ else
+ {
+ /* We have a real ambiguity. We keep a chain of all the
+ candidates. */
+ if (!lfi->ambiguous && lfi->rval)
+ {
+ /* This is the first time we noticed an ambiguity. Add
+ what we previously thought was a reasonable candidate
+ to the list. */
+ lfi->ambiguous = tree_cons (NULL_TREE, lfi->rval, NULL_TREE);
+ TREE_TYPE (lfi->ambiguous) = error_mark_node;
+ }
+
+ /* Add the new value. */
+ lfi->ambiguous = tree_cons (NULL_TREE, nval, lfi->ambiguous);
+ TREE_TYPE (lfi->ambiguous) = error_mark_node;
+ lfi->errstr = G_("request for member %qD is ambiguous");
+ }
+ }
+ else
+ {
+ lfi->rval = nval;
+ lfi->rval_binfo = binfo;
+ }
+
+ done:
+ /* Don't look for constructors or destructors in base classes. */
+ if (IDENTIFIER_CTOR_OR_DTOR_P (lfi->name))
+ return dfs_skip_bases;
+ return NULL_TREE;
+}
+
+/* Return a "baselink" with BASELINK_BINFO, BASELINK_ACCESS_BINFO,
+ BASELINK_FUNCTIONS, and BASELINK_OPTYPE set to BINFO, ACCESS_BINFO,
+ FUNCTIONS, and OPTYPE respectively. */
+
+tree
+build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)
+{
+ tree baselink;
+
+ gcc_assert (TREE_CODE (functions) == FUNCTION_DECL
+ || TREE_CODE (functions) == TEMPLATE_DECL
+ || TREE_CODE (functions) == TEMPLATE_ID_EXPR
+ || TREE_CODE (functions) == OVERLOAD);
+ gcc_assert (!optype || TYPE_P (optype));
+ gcc_assert (TREE_TYPE (functions));
+
+ baselink = make_node (BASELINK);
+ TREE_TYPE (baselink) = TREE_TYPE (functions);
+ BASELINK_BINFO (baselink) = binfo;
+ BASELINK_ACCESS_BINFO (baselink) = access_binfo;
+ BASELINK_FUNCTIONS (baselink) = functions;
+ BASELINK_OPTYPE (baselink) = optype;
+
+ return baselink;
+}
+
+/* Look for a member named NAME in an inheritance lattice dominated by
+ XBASETYPE. If PROTECT is 0 or two, we do not check access. If it
+ is 1, we enforce accessibility. If PROTECT is zero, then, for an
+ ambiguous lookup, we return NULL. If PROTECT is 1, we issue error
+ messages about inaccessible or ambiguous lookup. If PROTECT is 2,
+ we return a TREE_LIST whose TREE_TYPE is error_mark_node and whose
+ TREE_VALUEs are the list of ambiguous candidates.
+
+ WANT_TYPE is 1 when we should only return TYPE_DECLs.
+
+ If nothing can be found return NULL_TREE and do not issue an error. */
+
+tree
+lookup_member (tree xbasetype, tree name, int protect, bool want_type,
+ tsubst_flags_t complain)
+{
+ tree rval, rval_binfo = NULL_TREE;
+ tree type = NULL_TREE, basetype_path = NULL_TREE;
+ struct lookup_field_info lfi;
+
+ /* rval_binfo is the binfo associated with the found member, note,
+ this can be set with useful information, even when rval is not
+ set, because it must deal with ALL members, not just non-function
+ members. It is used for ambiguity checking and the hidden
+ checks. Whereas rval is only set if a proper (not hidden)
+ non-function member is found. */
+
+ const char *errstr = 0;
+
+ if (name == error_mark_node
+ || xbasetype == NULL_TREE
+ || xbasetype == error_mark_node)
+ return NULL_TREE;
+
+ gcc_assert (identifier_p (name));
+
+ if (TREE_CODE (xbasetype) == TREE_BINFO)
+ {
+ type = BINFO_TYPE (xbasetype);
+ basetype_path = xbasetype;
+ }
+ else
+ {
+ if (!RECORD_OR_UNION_CODE_P (TREE_CODE (xbasetype)))
+ return NULL_TREE;
+ type = xbasetype;
+ xbasetype = NULL_TREE;
+ }
+
+ type = complete_type (type);
+ if (!basetype_path)
+ basetype_path = TYPE_BINFO (type);
+
+ if (!basetype_path)
+ return NULL_TREE;
+
+ if (GATHER_STATISTICS)
+ n_calls_lookup_field++;
+
+ memset (&lfi, 0, sizeof (lfi));
+ lfi.type = type;
+ lfi.name = name;
+ lfi.want_type = want_type;
+ dfs_walk_all (basetype_path, &lookup_field_r, NULL, &lfi);
+ rval = lfi.rval;
+ rval_binfo = lfi.rval_binfo;
+ if (rval_binfo)
+ type = BINFO_TYPE (rval_binfo);
+ errstr = lfi.errstr;
+
+ /* If we are not interested in ambiguities, don't report them;
+ just return NULL_TREE. */
+ if (!protect && lfi.ambiguous)
+ return NULL_TREE;
+
+ if (protect == 2)
+ {
+ if (lfi.ambiguous)
+ return lfi.ambiguous;
+ else
+ protect = 0;
+ }
+
+ /* [class.access]
+
+ In the case of overloaded function names, access control is
+ applied to the function selected by overloaded resolution.
+
+ We cannot check here, even if RVAL is only a single non-static
+ member function, since we do not know what the "this" pointer
+ will be. For:
+
+ class A { protected: void f(); };
+ class B : public A {
+ void g(A *p) {
+ f(); // OK
+ p->f(); // Not OK.
+ }
+ };
+
+ only the first call to "f" is valid. However, if the function is
+ static, we can check. */
+ if (rval && protect
+ && !really_overloaded_fn (rval))
+ {
+ tree decl = is_overloaded_fn (rval) ? get_first_fn (rval) : rval;
+ if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
+ && !perform_or_defer_access_check (basetype_path, decl, decl,
+ complain))
+ rval = error_mark_node;
+ }
+
+ if (errstr && protect)
+ {
+ if (complain & tf_error)
+ {
+ error (errstr, name, type);
+ if (lfi.ambiguous)
+ print_candidates (lfi.ambiguous);
+ }
+ rval = error_mark_node;
+ }
+
+ if (rval && is_overloaded_fn (rval))
+ rval = build_baselink (rval_binfo, basetype_path, rval,
+ (IDENTIFIER_TYPENAME_P (name)
+ ? TREE_TYPE (name): NULL_TREE));
+ return rval;
+}
+
+/* Like lookup_member, except that if we find a function member we
+ return NULL_TREE. */
+
+tree
+lookup_field (tree xbasetype, tree name, int protect, bool want_type)
+{
+ tree rval = lookup_member (xbasetype, name, protect, want_type,
+ tf_warning_or_error);
+
+ /* Ignore functions, but propagate the ambiguity list. */
+ if (!error_operand_p (rval)
+ && (rval && BASELINK_P (rval)))
+ return NULL_TREE;
+
+ return rval;
+}
+
+/* Like lookup_member, except that if we find a non-function member we
+ return NULL_TREE. */
+
+tree
+lookup_fnfields (tree xbasetype, tree name, int protect)
+{
+ tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/false,
+ tf_warning_or_error);
+
+ /* Ignore non-functions, but propagate the ambiguity list. */
+ if (!error_operand_p (rval)
+ && (rval && !BASELINK_P (rval)))
+ return NULL_TREE;
+
+ return rval;
+}
+
+/* Return the index in the CLASSTYPE_METHOD_VEC for CLASS_TYPE
+ corresponding to "operator TYPE ()", or -1 if there is no such
+ operator. Only CLASS_TYPE itself is searched; this routine does
+ not scan the base classes of CLASS_TYPE. */
+
+static int
+lookup_conversion_operator (tree class_type, tree type)
+{
+ int tpl_slot = -1;
+
+ if (TYPE_HAS_CONVERSION (class_type))
+ {
+ int i;
+ tree fn;
+ vec<tree, va_gc> *methods = CLASSTYPE_METHOD_VEC (class_type);
+
+ for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ vec_safe_iterate (methods, i, &fn); ++i)
+ {
+ /* All the conversion operators come near the beginning of
+ the class. Therefore, if FN is not a conversion
+ operator, there is no matching conversion operator in
+ CLASS_TYPE. */
+ fn = OVL_CURRENT (fn);
+ if (!DECL_CONV_FN_P (fn))
+ break;
+
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ /* All the templated conversion functions are on the same
+ slot, so remember it. */
+ tpl_slot = i;
+ else if (same_type_p (DECL_CONV_FN_TYPE (fn), type))
+ return i;
+ }
+ }
+
+ return tpl_slot;
+}
+
+/* TYPE is a class type. Return the index of the fields within
+ the method vector with name NAME, or -1 if no such field exists.
+ Does not lazily declare implicitly-declared member functions. */
+
+static int
+lookup_fnfields_idx_nolazy (tree type, tree name)
+{
+ vec<tree, va_gc> *method_vec;
+ tree fn;
+ tree tmp;
+ size_t i;
+
+ if (!CLASS_TYPE_P (type))
+ return -1;
+
+ method_vec = CLASSTYPE_METHOD_VEC (type);
+ if (!method_vec)
+ return -1;
+
+ if (GATHER_STATISTICS)
+ n_calls_lookup_fnfields_1++;
+
+ /* Constructors are first... */
+ if (name == ctor_identifier)
+ {
+ fn = CLASSTYPE_CONSTRUCTORS (type);
+ return fn ? CLASSTYPE_CONSTRUCTOR_SLOT : -1;
+ }
+ /* and destructors are second. */
+ if (name == dtor_identifier)
+ {
+ fn = CLASSTYPE_DESTRUCTORS (type);
+ return fn ? CLASSTYPE_DESTRUCTOR_SLOT : -1;
+ }
+ if (IDENTIFIER_TYPENAME_P (name))
+ return lookup_conversion_operator (type, TREE_TYPE (name));
+
+ /* Skip the conversion operators. */
+ for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ vec_safe_iterate (method_vec, i, &fn);
+ ++i)
+ if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
+ break;
+
+ /* If the type is complete, use binary search. */
+ if (COMPLETE_TYPE_P (type))
+ {
+ int lo;
+ int hi;
+
+ lo = i;
+ hi = method_vec->length ();
+ while (lo < hi)
+ {
+ i = (lo + hi) / 2;
+
+ if (GATHER_STATISTICS)
+ n_outer_fields_searched++;
+
+ tmp = (*method_vec)[i];
+ tmp = DECL_NAME (OVL_CURRENT (tmp));
+ if (tmp > name)
+ hi = i;
+ else if (tmp < name)
+ lo = i + 1;
+ else
+ return i;
+ }
+ }
+ else
+ for (; vec_safe_iterate (method_vec, i, &fn); ++i)
+ {
+ if (GATHER_STATISTICS)
+ n_outer_fields_searched++;
+ if (DECL_NAME (OVL_CURRENT (fn)) == name)
+ return i;
+ }
+
+ return -1;
+}
+
+/* TYPE is a class type. Return the index of the fields within
+ the method vector with name NAME, or -1 if no such field exists. */
+
+int
+lookup_fnfields_1 (tree type, tree name)
+{
+ if (!CLASS_TYPE_P (type))
+ return -1;
+
+ if (COMPLETE_TYPE_P (type))
+ {
+ if ((name == ctor_identifier
+ || name == base_ctor_identifier
+ || name == complete_ctor_identifier))
+ {
+ if (CLASSTYPE_LAZY_DEFAULT_CTOR (type))
+ lazily_declare_fn (sfk_constructor, type);
+ if (CLASSTYPE_LAZY_COPY_CTOR (type))
+ lazily_declare_fn (sfk_copy_constructor, type);
+ if (CLASSTYPE_LAZY_MOVE_CTOR (type))
+ lazily_declare_fn (sfk_move_constructor, type);
+ }
+ else if (name == ansi_assopname (NOP_EXPR))
+ {
+ if (CLASSTYPE_LAZY_COPY_ASSIGN (type))
+ lazily_declare_fn (sfk_copy_assignment, type);
+ if (CLASSTYPE_LAZY_MOVE_ASSIGN (type))
+ lazily_declare_fn (sfk_move_assignment, type);
+ }
+ else if ((name == dtor_identifier
+ || name == base_dtor_identifier
+ || name == complete_dtor_identifier
+ || name == deleting_dtor_identifier)
+ && CLASSTYPE_LAZY_DESTRUCTOR (type))
+ lazily_declare_fn (sfk_destructor, type);
+ }
+
+ return lookup_fnfields_idx_nolazy (type, name);
+}
+
+/* TYPE is a class type. Return the field within the method vector with
+ name NAME, or NULL_TREE if no such field exists. */
+
+tree
+lookup_fnfields_slot (tree type, tree name)
+{
+ int ix = lookup_fnfields_1 (complete_type (type), name);
+ if (ix < 0)
+ return NULL_TREE;
+ return (*CLASSTYPE_METHOD_VEC (type))[ix];
+}
+
+/* As above, but avoid lazily declaring functions. */
+
+tree
+lookup_fnfields_slot_nolazy (tree type, tree name)
+{
+ int ix = lookup_fnfields_idx_nolazy (complete_type (type), name);
+ if (ix < 0)
+ return NULL_TREE;
+ return (*CLASSTYPE_METHOD_VEC (type))[ix];
+}
+
+/* Like lookup_fnfields_1, except that the name is extracted from
+ FUNCTION, which is a FUNCTION_DECL or a TEMPLATE_DECL. */
+
+int
+class_method_index_for_fn (tree class_type, tree function)
+{
+ gcc_assert (DECL_DECLARES_FUNCTION_P (function));
+
+ return lookup_fnfields_1 (class_type,
+ DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
+ DECL_DESTRUCTOR_P (function) ? dtor_identifier :
+ DECL_NAME (function));
+}
+
+
+/* DECL is the result of a qualified name lookup. QUALIFYING_SCOPE is
+ the class or namespace used to qualify the name. CONTEXT_CLASS is
+ the class corresponding to the object in which DECL will be used.
+ Return a possibly modified version of DECL that takes into account
+ the CONTEXT_CLASS.
+
+ In particular, consider an expression like `B::m' in the context of
+ a derived class `D'. If `B::m' has been resolved to a BASELINK,
+ then the most derived class indicated by the BASELINK_BINFO will be
+ `B', not `D'. This function makes that adjustment. */
+
+tree
+adjust_result_of_qualified_name_lookup (tree decl,
+ tree qualifying_scope,
+ tree context_class)
+{
+ if (context_class && context_class != error_mark_node
+ && CLASS_TYPE_P (context_class)
+ && CLASS_TYPE_P (qualifying_scope)
+ && DERIVED_FROM_P (qualifying_scope, context_class)
+ && BASELINK_P (decl))
+ {
+ tree base;
+
+ /* Look for the QUALIFYING_SCOPE as a base of the CONTEXT_CLASS.
+ Because we do not yet know which function will be chosen by
+ overload resolution, we cannot yet check either accessibility
+ or ambiguity -- in either case, the choice of a static member
+ function might make the usage valid. */
+ base = lookup_base (context_class, qualifying_scope,
+ ba_unique, NULL, tf_none);
+ if (base && base != error_mark_node)
+ {
+ BASELINK_ACCESS_BINFO (decl) = base;
+ BASELINK_BINFO (decl)
+ = lookup_base (base, BINFO_TYPE (BASELINK_BINFO (decl)),
+ ba_unique, NULL, tf_none);
+ }
+ }
+
+ if (BASELINK_P (decl))
+ BASELINK_QUALIFIED_P (decl) = true;
+
+ return decl;
+}
+
+
+/* Walk the class hierarchy within BINFO, in a depth-first traversal.
+ PRE_FN is called in preorder, while POST_FN is called in postorder.
+ If PRE_FN returns DFS_SKIP_BASES, child binfos will not be
+ walked. If PRE_FN or POST_FN returns a different non-NULL value,
+ that value is immediately returned and the walk is terminated. One
+ of PRE_FN and POST_FN can be NULL. At each node, PRE_FN and
+ POST_FN are passed the binfo to examine and the caller's DATA
+ value. All paths are walked, thus virtual and morally virtual
+ binfos can be multiply walked. */
+
+tree
+dfs_walk_all (tree binfo, tree (*pre_fn) (tree, void *),
+ tree (*post_fn) (tree, void *), void *data)
+{
+ tree rval;
+ unsigned ix;
+ tree base_binfo;
+
+ /* Call the pre-order walking function. */
+ if (pre_fn)
+ {
+ rval = pre_fn (binfo, data);
+ if (rval)
+ {
+ if (rval == dfs_skip_bases)
+ goto skip_bases;
+ return rval;
+ }
+ }
+
+ /* Find the next child binfo to walk. */
+ for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
+ {
+ rval = dfs_walk_all (base_binfo, pre_fn, post_fn, data);
+ if (rval)
+ return rval;
+ }
+
+ skip_bases:
+ /* Call the post-order walking function. */
+ if (post_fn)
+ {
+ rval = post_fn (binfo, data);
+ gcc_assert (rval != dfs_skip_bases);
+ return rval;
+ }
+
+ return NULL_TREE;
+}
+
+/* Worker for dfs_walk_once. This behaves as dfs_walk_all, except
+ that binfos are walked at most once. */
+
+static tree
+dfs_walk_once_r (tree binfo, tree (*pre_fn) (tree, void *),
+ tree (*post_fn) (tree, void *), void *data)
+{
+ tree rval;
+ unsigned ix;
+ tree base_binfo;
+
+ /* Call the pre-order walking function. */
+ if (pre_fn)
+ {
+ rval = pre_fn (binfo, data);
+ if (rval)
+ {
+ if (rval == dfs_skip_bases)
+ goto skip_bases;
+
+ return rval;
+ }
+ }
+
+ /* Find the next child binfo to walk. */
+ for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
+ {
+ if (BINFO_VIRTUAL_P (base_binfo))
+ {
+ if (BINFO_MARKED (base_binfo))
+ continue;
+ BINFO_MARKED (base_binfo) = 1;
+ }
+
+ rval = dfs_walk_once_r (base_binfo, pre_fn, post_fn, data);
+ if (rval)
+ return rval;
+ }
+
+ skip_bases:
+ /* Call the post-order walking function. */
+ if (post_fn)
+ {
+ rval = post_fn (binfo, data);
+ gcc_assert (rval != dfs_skip_bases);
+ return rval;
+ }
+
+ return NULL_TREE;
+}
+
+/* Worker for dfs_walk_once. Recursively unmark the virtual base binfos of
+ BINFO. */
+
+static void
+dfs_unmark_r (tree binfo)
+{
+ unsigned ix;
+ tree base_binfo;
+
+ /* Process the basetypes. */
+ for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
+ {
+ if (BINFO_VIRTUAL_P (base_binfo))
+ {
+ if (!BINFO_MARKED (base_binfo))
+ continue;
+ BINFO_MARKED (base_binfo) = 0;
+ }
+ /* Only walk, if it can contain more virtual bases. */
+ if (CLASSTYPE_VBASECLASSES (BINFO_TYPE (base_binfo)))
+ dfs_unmark_r (base_binfo);
+ }
+}
+
+/* Like dfs_walk_all, except that binfos are not multiply walked. For
+ non-diamond shaped hierarchies this is the same as dfs_walk_all.
+ For diamond shaped hierarchies we must mark the virtual bases, to
+ avoid multiple walks. */
+
+tree
+dfs_walk_once (tree binfo, tree (*pre_fn) (tree, void *),
+ tree (*post_fn) (tree, void *), void *data)
+{
+ static int active = 0; /* We must not be called recursively. */
+ tree rval;
+
+ gcc_assert (pre_fn || post_fn);
+ gcc_assert (!active);
+ active++;
+
+ if (!CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo)))
+ /* We are not diamond shaped, and therefore cannot encounter the
+ same binfo twice. */
+ rval = dfs_walk_all (binfo, pre_fn, post_fn, data);
+ else
+ {
+ rval = dfs_walk_once_r (binfo, pre_fn, post_fn, data);
+ if (!BINFO_INHERITANCE_CHAIN (binfo))
+ {
+ /* We are at the top of the hierarchy, and can use the
+ CLASSTYPE_VBASECLASSES list for unmarking the virtual
+ bases. */
+ vec<tree, va_gc> *vbases;
+ unsigned ix;
+ tree base_binfo;
+
+ for (vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)), ix = 0;
+ vec_safe_iterate (vbases, ix, &base_binfo); ix++)
+ BINFO_MARKED (base_binfo) = 0;
+ }
+ else
+ dfs_unmark_r (binfo);
+ }
+
+ active--;
+
+ return rval;
+}
+
+/* Worker function for dfs_walk_once_accessible. Behaves like
+ dfs_walk_once_r, except (a) FRIENDS_P is true if special
+ access given by the current context should be considered, (b) ONCE
+ indicates whether bases should be marked during traversal. */
+
+static tree
+dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
+ tree (*pre_fn) (tree, void *),
+ tree (*post_fn) (tree, void *), void *data)
+{
+ tree rval = NULL_TREE;
+ unsigned ix;
+ tree base_binfo;
+
+ /* Call the pre-order walking function. */
+ if (pre_fn)
+ {
+ rval = pre_fn (binfo, data);
+ if (rval)
+ {
+ if (rval == dfs_skip_bases)
+ goto skip_bases;
+
+ return rval;
+ }
+ }
+
+ /* Find the next child binfo to walk. */
+ for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
+ {
+ bool mark = once && BINFO_VIRTUAL_P (base_binfo);
+
+ if (mark && BINFO_MARKED (base_binfo))
+ continue;
+
+ /* If the base is inherited via private or protected
+ inheritance, then we can't see it, unless we are a friend of
+ the current binfo. */
+ if (BINFO_BASE_ACCESS (binfo, ix) != access_public_node)
+ {
+ tree scope;
+ if (!friends_p)
+ continue;
+ scope = current_scope ();
+ if (!scope
+ || TREE_CODE (scope) == NAMESPACE_DECL
+ || !is_friend (BINFO_TYPE (binfo), scope))
+ continue;
+ }
+
+ if (mark)
+ BINFO_MARKED (base_binfo) = 1;
+
+ rval = dfs_walk_once_accessible_r (base_binfo, friends_p, once,
+ pre_fn, post_fn, data);
+ if (rval)
+ return rval;
+ }
+
+ skip_bases:
+ /* Call the post-order walking function. */
+ if (post_fn)
+ {
+ rval = post_fn (binfo, data);
+ gcc_assert (rval != dfs_skip_bases);
+ return rval;
+ }
+
+ return NULL_TREE;
+}
+
+/* Like dfs_walk_once except that only accessible bases are walked.
+ FRIENDS_P indicates whether friendship of the local context
+ should be considered when determining accessibility. */
+
+static tree
+dfs_walk_once_accessible (tree binfo, bool friends_p,
+ tree (*pre_fn) (tree, void *),
+ tree (*post_fn) (tree, void *), void *data)
+{
+ bool diamond_shaped = CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo));
+ tree rval = dfs_walk_once_accessible_r (binfo, friends_p, diamond_shaped,
+ pre_fn, post_fn, data);
+
+ if (diamond_shaped)
+ {
+ if (!BINFO_INHERITANCE_CHAIN (binfo))
+ {
+ /* We are at the top of the hierarchy, and can use the
+ CLASSTYPE_VBASECLASSES list for unmarking the virtual
+ bases. */
+ vec<tree, va_gc> *vbases;
+ unsigned ix;
+ tree base_binfo;
+
+ for (vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)), ix = 0;
+ vec_safe_iterate (vbases, ix, &base_binfo); ix++)
+ BINFO_MARKED (base_binfo) = 0;
+ }
+ else
+ dfs_unmark_r (binfo);
+ }
+ return rval;
+}
+
+/* Check that virtual overrider OVERRIDER is acceptable for base function
+ BASEFN. Issue diagnostic, and return zero, if unacceptable. */
+
+static int
+check_final_overrider (tree overrider, tree basefn)
+{
+ tree over_type = TREE_TYPE (overrider);
+ tree base_type = TREE_TYPE (basefn);
+ tree over_return = fndecl_declared_return_type (overrider);
+ tree base_return = fndecl_declared_return_type (basefn);
+ tree over_throw, base_throw;
+
+ int fail = 0;
+
+ if (DECL_INVALID_OVERRIDER_P (overrider))
+ return 0;
+
+ if (same_type_p (base_return, over_return))
+ /* OK */;
+ else if ((CLASS_TYPE_P (over_return) && CLASS_TYPE_P (base_return))
+ || (TREE_CODE (base_return) == TREE_CODE (over_return)
+ && POINTER_TYPE_P (base_return)))
+ {
+ /* Potentially covariant. */
+ unsigned base_quals, over_quals;
+
+ fail = !POINTER_TYPE_P (base_return);
+ if (!fail)
+ {
+ fail = cp_type_quals (base_return) != cp_type_quals (over_return);
+
+ base_return = TREE_TYPE (base_return);
+ over_return = TREE_TYPE (over_return);
+ }
+ base_quals = cp_type_quals (base_return);
+ over_quals = cp_type_quals (over_return);
+
+ if ((base_quals & over_quals) != over_quals)
+ fail = 1;
+
+ if (CLASS_TYPE_P (base_return) && CLASS_TYPE_P (over_return))
+ {
+ /* Strictly speaking, the standard requires the return type to be
+ complete even if it only differs in cv-quals, but that seems
+ like a bug in the wording. */
+ if (!same_type_ignoring_top_level_qualifiers_p (base_return,
+ over_return))
+ {
+ tree binfo = lookup_base (over_return, base_return,
+ ba_check, NULL, tf_none);
+
+ if (!binfo || binfo == error_mark_node)
+ fail = 1;
+ }
+ }
+ else if (can_convert_standard (TREE_TYPE (base_type),
+ TREE_TYPE (over_type),
+ tf_warning_or_error))
+ /* GNU extension, allow trivial pointer conversions such as
+ converting to void *, or qualification conversion. */
+ {
+ if (pedwarn (DECL_SOURCE_LOCATION (overrider), 0,
+ "invalid covariant return type for %q#D", overrider))
+ inform (DECL_SOURCE_LOCATION (basefn),
+ " overriding %q+#D", basefn);
+ }
+ else
+ fail = 2;
+ }
+ else
+ fail = 2;
+ if (!fail)
+ /* OK */;
+ else
+ {
+ if (fail == 1)
+ {
+ error ("invalid covariant return type for %q+#D", overrider);
+ error (" overriding %q+#D", basefn);
+ }
+ else
+ {
+ error ("conflicting return type specified for %q+#D", overrider);
+ error (" overriding %q+#D", basefn);
+ }
+ DECL_INVALID_OVERRIDER_P (overrider) = 1;
+ return 0;
+ }
+
+ /* Check throw specifier is at least as strict. */
+ maybe_instantiate_noexcept (basefn);
+ maybe_instantiate_noexcept (overrider);
+ base_throw = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (basefn));
+ over_throw = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (overrider));
+
+ if (!comp_except_specs (base_throw, over_throw, ce_derived))
+ {
+ error ("looser throw specifier for %q+#F", overrider);
+ error (" overriding %q+#F", basefn);
+ DECL_INVALID_OVERRIDER_P (overrider) = 1;
+ return 0;
+ }
+
+ /* Check for conflicting type attributes. */
+ if (!comp_type_attributes (over_type, base_type))
+ {
+ error ("conflicting type attributes specified for %q+#D", overrider);
+ error (" overriding %q+#D", basefn);
+ DECL_INVALID_OVERRIDER_P (overrider) = 1;
+ return 0;
+ }
+
+ if (DECL_DELETED_FN (basefn) != DECL_DELETED_FN (overrider))
+ {
+ if (DECL_DELETED_FN (overrider))
+ {
+ error ("deleted function %q+D", overrider);
+ error ("overriding non-deleted function %q+D", basefn);
+ maybe_explain_implicit_delete (overrider);
+ }
+ else
+ {
+ error ("non-deleted function %q+D", overrider);
+ error ("overriding deleted function %q+D", basefn);
+ }
+ return 0;
+ }
+ if (DECL_FINAL_P (basefn))
+ {
+ error ("virtual function %q+D", overrider);
+ error ("overriding final function %q+D", basefn);
+ return 0;
+ }
+ return 1;
+}
+
+/* Given a class TYPE, and a function decl FNDECL, look for
+ virtual functions in TYPE's hierarchy which FNDECL overrides.
+ We do not look in TYPE itself, only its bases.
+
+ Returns nonzero, if we find any. Set FNDECL's DECL_VIRTUAL_P, if we
+ find that it overrides anything.
+
+ We check that every function which is overridden, is correctly
+ overridden. */
+
+int
+look_for_overrides (tree type, tree fndecl)
+{
+ tree binfo = TYPE_BINFO (type);
+ tree base_binfo;
+ int ix;
+ int found = 0;
+
+ /* A constructor for a class T does not override a function T
+ in a base class. */
+ if (DECL_CONSTRUCTOR_P (fndecl))
+ return 0;
+
+ for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
+ {
+ tree basetype = BINFO_TYPE (base_binfo);
+
+ if (TYPE_POLYMORPHIC_P (basetype))
+ found += look_for_overrides_r (basetype, fndecl);
+ }
+ return found;
+}
+
+/* Look in TYPE for virtual functions with the same signature as
+ FNDECL. */
+
+tree
+look_for_overrides_here (tree type, tree fndecl)
+{
+ int ix;
+
+ /* If there are no methods in TYPE (meaning that only implicitly
+ declared methods will ever be provided for TYPE), then there are
+ no virtual functions. */
+ if (!CLASSTYPE_METHOD_VEC (type))
+ return NULL_TREE;
+
+ if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fndecl))
+ ix = CLASSTYPE_DESTRUCTOR_SLOT;
+ else
+ ix = lookup_fnfields_1 (type, DECL_NAME (fndecl));
+ if (ix >= 0)
+ {
+ tree fns = (*CLASSTYPE_METHOD_VEC (type))[ix];
+
+ for (; fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ if (!DECL_VIRTUAL_P (fn))
+ /* Not a virtual. */;
+ else if (DECL_CONTEXT (fn) != type)
+ /* Introduced with a using declaration. */;
+ else if (DECL_STATIC_FUNCTION_P (fndecl))
+ {
+ tree btypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ tree dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+ if (compparms (TREE_CHAIN (btypes), dtypes))
+ return fn;
+ }
+ else if (same_signature_p (fndecl, fn))
+ return fn;
+ }
+ }
+ return NULL_TREE;
+}
+
+/* Look in TYPE for virtual functions overridden by FNDECL. Check both
+ TYPE itself and its bases. */
+
+static int
+look_for_overrides_r (tree type, tree fndecl)
+{
+ tree fn = look_for_overrides_here (type, fndecl);
+ if (fn)
+ {
+ if (DECL_STATIC_FUNCTION_P (fndecl))
+ {
+ /* A static member function cannot match an inherited
+ virtual member function. */
+ error ("%q+#D cannot be declared", fndecl);
+ error (" since %q+#D declared in base class", fn);
+ }
+ else
+ {
+ /* It's definitely virtual, even if not explicitly set. */
+ DECL_VIRTUAL_P (fndecl) = 1;
+ check_final_overrider (fndecl, fn);
+ }
+ return 1;
+ }
+
+ /* We failed to find one declared in this class. Look in its bases. */
+ return look_for_overrides (type, fndecl);
+}
+
+/* Called via dfs_walk from dfs_get_pure_virtuals. */
+
+static tree
+dfs_get_pure_virtuals (tree binfo, void *data)
+{
+ tree type = (tree) data;
+
+ /* We're not interested in primary base classes; the derived class
+ of which they are a primary base will contain the information we
+ need. */
+ if (!BINFO_PRIMARY_P (binfo))
+ {
+ tree virtuals;
+
+ for (virtuals = BINFO_VIRTUALS (binfo);
+ virtuals;
+ virtuals = TREE_CHAIN (virtuals))
+ if (DECL_PURE_VIRTUAL_P (BV_FN (virtuals)))
+ vec_safe_push (CLASSTYPE_PURE_VIRTUALS (type), BV_FN (virtuals));
+ }
+
+ return NULL_TREE;
+}
+
+/* Set CLASSTYPE_PURE_VIRTUALS for TYPE. */
+
+void
+get_pure_virtuals (tree type)
+{
+ /* Clear the CLASSTYPE_PURE_VIRTUALS list; whatever is already there
+ is going to be overridden. */
+ CLASSTYPE_PURE_VIRTUALS (type) = NULL;
+ /* Now, run through all the bases which are not primary bases, and
+ collect the pure virtual functions. We look at the vtable in
+ each class to determine what pure virtual functions are present.
+ (A primary base is not interesting because the derived class of
+ which it is a primary base will contain vtable entries for the
+ pure virtuals in the base class. */
+ dfs_walk_once (TYPE_BINFO (type), NULL, dfs_get_pure_virtuals, type);
+
+ /* Treat a virtual destructor in an abstract class as pure even if it
+ isn't declared as pure; there is no way it would be called through the
+ vtable except during construction, which causes undefined behavior. */
+ if (CLASSTYPE_PURE_VIRTUALS (type)
+ && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ {
+ tree dtor = CLASSTYPE_DESTRUCTORS (type);
+ if (dtor && DECL_VIRTUAL_P (dtor) && !DECL_PURE_VIRTUAL_P (dtor))
+ {
+ tree clone;
+ DECL_PURE_VIRTUAL_P (dtor) = true;
+ FOR_EACH_CLONE (clone, dtor)
+ DECL_PURE_VIRTUAL_P (clone) = true;
+ }
+ }
+}
+
+/* Debug info for C++ classes can get very large; try to avoid
+ emitting it everywhere.
+
+ Note that this optimization wins even when the target supports
+ BINCL (if only slightly), and reduces the amount of work for the
+ linker. */
+
+void
+maybe_suppress_debug_info (tree t)
+{
+ if (write_symbols == NO_DEBUG)
+ return;
+
+ /* We might have set this earlier in cp_finish_decl. */
+ TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 0;
+
+ /* Always emit the information for each class every time. */
+ if (flag_emit_class_debug_always)
+ return;
+
+ /* If we already know how we're handling this class, handle debug info
+ the same way. */
+ if (CLASSTYPE_INTERFACE_KNOWN (t))
+ {
+ if (CLASSTYPE_INTERFACE_ONLY (t))
+ TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
+ /* else don't set it. */
+ }
+ /* If the class has a vtable, write out the debug info along with
+ the vtable. */
+ else if (TYPE_CONTAINS_VPTR_P (t))
+ TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
+
+ /* Otherwise, just emit the debug info normally. */
+}
+
+/* Note that we want debugging information for a base class of a class
+ whose vtable is being emitted. Normally, this would happen because
+ calling the constructor for a derived class implies calling the
+ constructors for all bases, which involve initializing the
+ appropriate vptr with the vtable for the base class; but in the
+ presence of optimization, this initialization may be optimized
+ away, so we tell finish_vtable_vardecl that we want the debugging
+ information anyway. */
+
+static tree
+dfs_debug_mark (tree binfo, void * /*data*/)
+{
+ tree t = BINFO_TYPE (binfo);
+
+ if (CLASSTYPE_DEBUG_REQUESTED (t))
+ return dfs_skip_bases;
+
+ CLASSTYPE_DEBUG_REQUESTED (t) = 1;
+
+ return NULL_TREE;
+}
+
+/* Write out the debugging information for TYPE, whose vtable is being
+ emitted. Also walk through our bases and note that we want to
+ write out information for them. This avoids the problem of not
+ writing any debug info for intermediate basetypes whose
+ constructors, and thus the references to their vtables, and thus
+ the vtables themselves, were optimized away. */
+
+void
+note_debug_info_needed (tree type)
+{
+ if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type)))
+ {
+ TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type)) = 0;
+ rest_of_type_compilation (type, toplevel_bindings_p ());
+ }
+
+ dfs_walk_all (TYPE_BINFO (type), dfs_debug_mark, NULL, 0);
+}
+
+void
+print_search_statistics (void)
+{
+ if (! GATHER_STATISTICS)
+ {
+ fprintf (stderr, "no search statistics\n");
+ return;
+ }
+
+ fprintf (stderr, "%d fields searched in %d[%d] calls to lookup_field[_1]\n",
+ n_fields_searched, n_calls_lookup_field, n_calls_lookup_field_1);
+ fprintf (stderr, "%d fnfields searched in %d calls to lookup_fnfields\n",
+ n_outer_fields_searched, n_calls_lookup_fnfields);
+ fprintf (stderr, "%d calls to get_base_type\n", n_calls_get_base_type);
+}
+
+void
+reinit_search_statistics (void)
+{
+ n_fields_searched = 0;
+ n_calls_lookup_field = 0, n_calls_lookup_field_1 = 0;
+ n_calls_lookup_fnfields = 0, n_calls_lookup_fnfields_1 = 0;
+ n_calls_get_base_type = 0;
+ n_outer_fields_searched = 0;
+ n_contexts_saved = 0;
+}
+
+/* Helper for lookup_conversions_r. TO_TYPE is the type converted to
+ by a conversion op in base BINFO. VIRTUAL_DEPTH is nonzero if
+ BINFO is morally virtual, and VIRTUALNESS is nonzero if virtual
+ bases have been encountered already in the tree walk. PARENT_CONVS
+ is the list of lists of conversion functions that could hide CONV
+ and OTHER_CONVS is the list of lists of conversion functions that
+ could hide or be hidden by CONV, should virtualness be involved in
+ the hierarchy. Merely checking the conversion op's name is not
+ enough because two conversion operators to the same type can have
+ different names. Return nonzero if we are visible. */
+
+static int
+check_hidden_convs (tree binfo, int virtual_depth, int virtualness,
+ tree to_type, tree parent_convs, tree other_convs)
+{
+ tree level, probe;
+
+ /* See if we are hidden by a parent conversion. */
+ for (level = parent_convs; level; level = TREE_CHAIN (level))
+ for (probe = TREE_VALUE (level); probe; probe = TREE_CHAIN (probe))
+ if (same_type_p (to_type, TREE_TYPE (probe)))
+ return 0;
+
+ if (virtual_depth || virtualness)
+ {
+ /* In a virtual hierarchy, we could be hidden, or could hide a
+ conversion function on the other_convs list. */
+ for (level = other_convs; level; level = TREE_CHAIN (level))
+ {
+ int we_hide_them;
+ int they_hide_us;
+ tree *prev, other;
+
+ if (!(virtual_depth || TREE_STATIC (level)))
+ /* Neither is morally virtual, so cannot hide each other. */
+ continue;
+
+ if (!TREE_VALUE (level))
+ /* They evaporated away already. */
+ continue;
+
+ they_hide_us = (virtual_depth
+ && original_binfo (binfo, TREE_PURPOSE (level)));
+ we_hide_them = (!they_hide_us && TREE_STATIC (level)
+ && original_binfo (TREE_PURPOSE (level), binfo));
+
+ if (!(we_hide_them || they_hide_us))
+ /* Neither is within the other, so no hiding can occur. */
+ continue;
+
+ for (prev = &TREE_VALUE (level), other = *prev; other;)
+ {
+ if (same_type_p (to_type, TREE_TYPE (other)))
+ {
+ if (they_hide_us)
+ /* We are hidden. */
+ return 0;
+
+ if (we_hide_them)
+ {
+ /* We hide the other one. */
+ other = TREE_CHAIN (other);
+ *prev = other;
+ continue;
+ }
+ }
+ prev = &TREE_CHAIN (other);
+ other = *prev;
+ }
+ }
+ }
+ return 1;
+}
+
+/* Helper for lookup_conversions_r. PARENT_CONVS is a list of lists
+ of conversion functions, the first slot will be for the current
+ binfo, if MY_CONVS is non-NULL. CHILD_CONVS is the list of lists
+ of conversion functions from children of the current binfo,
+ concatenated with conversions from elsewhere in the hierarchy --
+ that list begins with OTHER_CONVS. Return a single list of lists
+ containing only conversions from the current binfo and its
+ children. */
+
+static tree
+split_conversions (tree my_convs, tree parent_convs,
+ tree child_convs, tree other_convs)
+{
+ tree t;
+ tree prev;
+
+ /* Remove the original other_convs portion from child_convs. */
+ for (prev = NULL, t = child_convs;
+ t != other_convs; prev = t, t = TREE_CHAIN (t))
+ continue;
+
+ if (prev)
+ TREE_CHAIN (prev) = NULL_TREE;
+ else
+ child_convs = NULL_TREE;
+
+ /* Attach the child convs to any we had at this level. */
+ if (my_convs)
+ {
+ my_convs = parent_convs;
+ TREE_CHAIN (my_convs) = child_convs;
+ }
+ else
+ my_convs = child_convs;
+
+ return my_convs;
+}
+
+/* Worker for lookup_conversions. Lookup conversion functions in
+ BINFO and its children. VIRTUAL_DEPTH is nonzero, if BINFO is in
+ a morally virtual base, and VIRTUALNESS is nonzero, if we've
+ encountered virtual bases already in the tree walk. PARENT_CONVS &
+ PARENT_TPL_CONVS are lists of list of conversions within parent
+ binfos. OTHER_CONVS and OTHER_TPL_CONVS are conversions found
+ elsewhere in the tree. Return the conversions found within this
+ portion of the graph in CONVS and TPL_CONVS. Return nonzero is we
+ encountered virtualness. We keep template and non-template
+ conversions separate, to avoid unnecessary type comparisons.
+
+ The located conversion functions are held in lists of lists. The
+ TREE_VALUE of the outer list is the list of conversion functions
+ found in a particular binfo. The TREE_PURPOSE of both the outer
+ and inner lists is the binfo at which those conversions were
+ found. TREE_STATIC is set for those lists within of morally
+ virtual binfos. The TREE_VALUE of the inner list is the conversion
+ function or overload itself. The TREE_TYPE of each inner list node
+ is the converted-to type. */
+
+static int
+lookup_conversions_r (tree binfo,
+ int virtual_depth, int virtualness,
+ tree parent_convs, tree parent_tpl_convs,
+ tree other_convs, tree other_tpl_convs,
+ tree *convs, tree *tpl_convs)
+{
+ int my_virtualness = 0;
+ tree my_convs = NULL_TREE;
+ tree my_tpl_convs = NULL_TREE;
+ tree child_convs = NULL_TREE;
+ tree child_tpl_convs = NULL_TREE;
+ unsigned i;
+ tree base_binfo;
+ vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
+ tree conv;
+
+ /* If we have no conversion operators, then don't look. */
+ if (!TYPE_HAS_CONVERSION (BINFO_TYPE (binfo)))
+ {
+ *convs = *tpl_convs = NULL_TREE;
+
+ return 0;
+ }
+
+ if (BINFO_VIRTUAL_P (binfo))
+ virtual_depth++;
+
+ /* First, locate the unhidden ones at this level. */
+ for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ vec_safe_iterate (method_vec, i, &conv);
+ ++i)
+ {
+ tree cur = OVL_CURRENT (conv);
+
+ if (!DECL_CONV_FN_P (cur))
+ break;
+
+ if (TREE_CODE (cur) == TEMPLATE_DECL)
+ {
+ /* Only template conversions can be overloaded, and we must
+ flatten them out and check each one individually. */
+ tree tpls;
+
+ for (tpls = conv; tpls; tpls = OVL_NEXT (tpls))
+ {
+ tree tpl = OVL_CURRENT (tpls);
+ tree type = DECL_CONV_FN_TYPE (tpl);
+
+ if (check_hidden_convs (binfo, virtual_depth, virtualness,
+ type, parent_tpl_convs, other_tpl_convs))
+ {
+ my_tpl_convs = tree_cons (binfo, tpl, my_tpl_convs);
+ TREE_TYPE (my_tpl_convs) = type;
+ if (virtual_depth)
+ {
+ TREE_STATIC (my_tpl_convs) = 1;
+ my_virtualness = 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ tree name = DECL_NAME (cur);
+
+ if (!IDENTIFIER_MARKED (name))
+ {
+ tree type = DECL_CONV_FN_TYPE (cur);
+ if (type_uses_auto (type))
+ {
+ mark_used (cur);
+ type = DECL_CONV_FN_TYPE (cur);
+ }
+
+ if (check_hidden_convs (binfo, virtual_depth, virtualness,
+ type, parent_convs, other_convs))
+ {
+ my_convs = tree_cons (binfo, conv, my_convs);
+ TREE_TYPE (my_convs) = type;
+ if (virtual_depth)
+ {
+ TREE_STATIC (my_convs) = 1;
+ my_virtualness = 1;
+ }
+ IDENTIFIER_MARKED (name) = 1;
+ }
+ }
+ }
+ }
+
+ if (my_convs)
+ {
+ parent_convs = tree_cons (binfo, my_convs, parent_convs);
+ if (virtual_depth)
+ TREE_STATIC (parent_convs) = 1;
+ }
+
+ if (my_tpl_convs)
+ {
+ parent_tpl_convs = tree_cons (binfo, my_tpl_convs, parent_tpl_convs);
+ if (virtual_depth)
+ TREE_STATIC (parent_tpl_convs) = 1;
+ }
+
+ child_convs = other_convs;
+ child_tpl_convs = other_tpl_convs;
+
+ /* Now iterate over each base, looking for more conversions. */
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ {
+ tree base_convs, base_tpl_convs;
+ unsigned base_virtualness;
+
+ base_virtualness = lookup_conversions_r (base_binfo,
+ virtual_depth, virtualness,
+ parent_convs, parent_tpl_convs,
+ child_convs, child_tpl_convs,
+ &base_convs, &base_tpl_convs);
+ if (base_virtualness)
+ my_virtualness = virtualness = 1;
+ child_convs = chainon (base_convs, child_convs);
+ child_tpl_convs = chainon (base_tpl_convs, child_tpl_convs);
+ }
+
+ /* Unmark the conversions found at this level */
+ for (conv = my_convs; conv; conv = TREE_CHAIN (conv))
+ IDENTIFIER_MARKED (DECL_NAME (OVL_CURRENT (TREE_VALUE (conv)))) = 0;
+
+ *convs = split_conversions (my_convs, parent_convs,
+ child_convs, other_convs);
+ *tpl_convs = split_conversions (my_tpl_convs, parent_tpl_convs,
+ child_tpl_convs, other_tpl_convs);
+
+ return my_virtualness;
+}
+
+/* Return a TREE_LIST containing all the non-hidden user-defined
+ conversion functions for TYPE (and its base-classes). The
+ TREE_VALUE of each node is the FUNCTION_DECL of the conversion
+ function. The TREE_PURPOSE is the BINFO from which the conversion
+ functions in this node were selected. This function is effectively
+ performing a set of member lookups as lookup_fnfield does, but
+ using the type being converted to as the unique key, rather than the
+ field name. */
+
+tree
+lookup_conversions (tree type)
+{
+ tree convs, tpl_convs;
+ tree list = NULL_TREE;
+
+ complete_type (type);
+ if (!CLASS_TYPE_P (type) || !TYPE_BINFO (type))
+ return NULL_TREE;
+
+ lookup_conversions_r (TYPE_BINFO (type), 0, 0,
+ NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
+ &convs, &tpl_convs);
+
+ /* Flatten the list-of-lists */
+ for (; convs; convs = TREE_CHAIN (convs))
+ {
+ tree probe, next;
+
+ for (probe = TREE_VALUE (convs); probe; probe = next)
+ {
+ next = TREE_CHAIN (probe);
+
+ TREE_CHAIN (probe) = list;
+ list = probe;
+ }
+ }
+
+ for (; tpl_convs; tpl_convs = TREE_CHAIN (tpl_convs))
+ {
+ tree probe, next;
+
+ for (probe = TREE_VALUE (tpl_convs); probe; probe = next)
+ {
+ next = TREE_CHAIN (probe);
+
+ TREE_CHAIN (probe) = list;
+ list = probe;
+ }
+ }
+
+ return list;
+}
+
+/* Returns the binfo of the first direct or indirect virtual base derived
+ from BINFO, or NULL if binfo is not via virtual. */
+
+tree
+binfo_from_vbase (tree binfo)
+{
+ for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo))
+ {
+ if (BINFO_VIRTUAL_P (binfo))
+ return binfo;
+ }
+ return NULL_TREE;
+}
+
+/* Returns the binfo of the first direct or indirect virtual base derived
+ from BINFO up to the TREE_TYPE, LIMIT, or NULL if binfo is not
+ via virtual. */
+
+tree
+binfo_via_virtual (tree binfo, tree limit)
+{
+ if (limit && !CLASSTYPE_VBASECLASSES (limit))
+ /* LIMIT has no virtual bases, so BINFO cannot be via one. */
+ return NULL_TREE;
+
+ for (; binfo && !SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), limit);
+ binfo = BINFO_INHERITANCE_CHAIN (binfo))
+ {
+ if (BINFO_VIRTUAL_P (binfo))
+ return binfo;
+ }
+ return NULL_TREE;
+}
+
+/* BINFO is a base binfo in the complete type BINFO_TYPE (HERE).
+ Find the equivalent binfo within whatever graph HERE is located.
+ This is the inverse of original_binfo. */
+
+tree
+copied_binfo (tree binfo, tree here)
+{
+ tree result = NULL_TREE;
+
+ if (BINFO_VIRTUAL_P (binfo))
+ {
+ tree t;
+
+ for (t = here; BINFO_INHERITANCE_CHAIN (t);
+ t = BINFO_INHERITANCE_CHAIN (t))
+ continue;
+
+ result = binfo_for_vbase (BINFO_TYPE (binfo), BINFO_TYPE (t));
+ }
+ else if (BINFO_INHERITANCE_CHAIN (binfo))
+ {
+ tree cbinfo;
+ tree base_binfo;
+ int ix;
+
+ cbinfo = copied_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
+ for (ix = 0; BINFO_BASE_ITERATE (cbinfo, ix, base_binfo); ix++)
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo), BINFO_TYPE (binfo)))
+ {
+ result = base_binfo;
+ break;
+ }
+ }
+ else
+ {
+ gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (here), BINFO_TYPE (binfo)));
+ result = here;
+ }
+
+ gcc_assert (result);
+ return result;
+}
+
+tree
+binfo_for_vbase (tree base, tree t)
+{
+ unsigned ix;
+ tree binfo;
+ vec<tree, va_gc> *vbases;
+
+ for (vbases = CLASSTYPE_VBASECLASSES (t), ix = 0;
+ vec_safe_iterate (vbases, ix, &binfo); ix++)
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), base))
+ return binfo;
+ return NULL;
+}
+
+/* BINFO is some base binfo of HERE, within some other
+ hierarchy. Return the equivalent binfo, but in the hierarchy
+ dominated by HERE. This is the inverse of copied_binfo. If BINFO
+ is not a base binfo of HERE, returns NULL_TREE. */
+
+tree
+original_binfo (tree binfo, tree here)
+{
+ tree result = NULL;
+
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (here)))
+ result = here;
+ else if (BINFO_VIRTUAL_P (binfo))
+ result = (CLASSTYPE_VBASECLASSES (BINFO_TYPE (here))
+ ? binfo_for_vbase (BINFO_TYPE (binfo), BINFO_TYPE (here))
+ : NULL_TREE);
+ else if (BINFO_INHERITANCE_CHAIN (binfo))
+ {
+ tree base_binfos;
+
+ base_binfos = original_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
+ if (base_binfos)
+ {
+ int ix;
+ tree base_binfo;
+
+ for (ix = 0; (base_binfo = BINFO_BASE_BINFO (base_binfos, ix)); ix++)
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo),
+ BINFO_TYPE (binfo)))
+ {
+ result = base_binfo;
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
diff --git a/gcc-4.9/gcc/cp/semantics.c b/gcc-4.9/gcc/cp/semantics.c
new file mode 100644
index 000000000..886fbb88b
--- /dev/null
+++ b/gcc-4.9/gcc/cp/semantics.c
@@ -0,0 +1,10691 @@
+/* Perform the semantic phase of parsing, i.e., the process of
+ building tree structure, checking semantic consistency, and
+ building RTL. These routines are used both during actual parsing
+ and during the instantiation of template functions.
+
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
+ Written by Mark Mitchell (mmitchell@usa.net) based on code found
+ formerly in parse.y and pt.c.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stmt.h"
+#include "varasm.h"
+#include "stor-layout.h"
+#include "stringpool.h"
+#include "cp-tree.h"
+#include "c-family/c-common.h"
+#include "c-family/c-objc.h"
+#include "tree-inline.h"
+#include "intl.h"
+#include "toplev.h"
+#include "flags.h"
+#include "timevar.h"
+#include "diagnostic.h"
+#include "cgraph.h"
+#include "tree-iterator.h"
+#include "target.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "gimplify.h"
+#include "bitmap.h"
+#include "omp-low.h"
+
+static bool verify_constant (tree, bool, bool *, bool *);
+#define VERIFY_CONSTANT(X) \
+do { \
+ if (verify_constant ((X), allow_non_constant, non_constant_p, overflow_p)) \
+ return t; \
+ } while (0)
+
+/* There routines provide a modular interface to perform many parsing
+ operations. They may therefore be used during actual parsing, or
+ during template instantiation, which may be regarded as a
+ degenerate form of parsing. */
+
+static tree maybe_convert_cond (tree);
+static tree finalize_nrv_r (tree *, int *, void *);
+static tree capture_decltype (tree);
+
+
+/* Deferred Access Checking Overview
+ ---------------------------------
+
+ Most C++ expressions and declarations require access checking
+ to be performed during parsing. However, in several cases,
+ this has to be treated differently.
+
+ For member declarations, access checking has to be deferred
+ until more information about the declaration is known. For
+ example:
+
+ class A {
+ typedef int X;
+ public:
+ X f();
+ };
+
+ A::X A::f();
+ A::X g();
+
+ When we are parsing the function return type `A::X', we don't
+ really know if this is allowed until we parse the function name.
+
+ Furthermore, some contexts require that access checking is
+ never performed at all. These include class heads, and template
+ instantiations.
+
+ Typical use of access checking functions is described here:
+
+ 1. When we enter a context that requires certain access checking
+ mode, the function `push_deferring_access_checks' is called with
+ DEFERRING argument specifying the desired mode. Access checking
+ may be performed immediately (dk_no_deferred), deferred
+ (dk_deferred), or not performed (dk_no_check).
+
+ 2. When a declaration such as a type, or a variable, is encountered,
+ the function `perform_or_defer_access_check' is called. It
+ maintains a vector of all deferred checks.
+
+ 3. The global `current_class_type' or `current_function_decl' is then
+ setup by the parser. `enforce_access' relies on these information
+ to check access.
+
+ 4. Upon exiting the context mentioned in step 1,
+ `perform_deferred_access_checks' is called to check all declaration
+ stored in the vector. `pop_deferring_access_checks' is then
+ called to restore the previous access checking mode.
+
+ In case of parsing error, we simply call `pop_deferring_access_checks'
+ without `perform_deferred_access_checks'. */
+
+typedef struct GTY(()) deferred_access {
+ /* A vector representing name-lookups for which we have deferred
+ checking access controls. We cannot check the accessibility of
+ names used in a decl-specifier-seq until we know what is being
+ declared because code like:
+
+ class A {
+ class B {};
+ B* f();
+ }
+
+ A::B* A::f() { return 0; }
+
+ is valid, even though `A::B' is not generally accessible. */
+ vec<deferred_access_check, va_gc> * GTY(()) deferred_access_checks;
+
+ /* The current mode of access checks. */
+ enum deferring_kind deferring_access_checks_kind;
+
+} deferred_access;
+
+/* Data for deferred access checking. */
+static GTY(()) vec<deferred_access, va_gc> *deferred_access_stack;
+static GTY(()) unsigned deferred_access_no_check;
+
+/* Save the current deferred access states and start deferred
+ access checking iff DEFER_P is true. */
+
+void
+push_deferring_access_checks (deferring_kind deferring)
+{
+ /* For context like template instantiation, access checking
+ disabling applies to all nested context. */
+ if (deferred_access_no_check || deferring == dk_no_check)
+ deferred_access_no_check++;
+ else
+ {
+ deferred_access e = {NULL, deferring};
+ vec_safe_push (deferred_access_stack, e);
+ }
+}
+
+/* Save the current deferred access states and start deferred access
+ checking, continuing the set of deferred checks in CHECKS. */
+
+void
+reopen_deferring_access_checks (vec<deferred_access_check, va_gc> * checks)
+{
+ push_deferring_access_checks (dk_deferred);
+ if (!deferred_access_no_check)
+ deferred_access_stack->last().deferred_access_checks = checks;
+}
+
+/* Resume deferring access checks again after we stopped doing
+ this previously. */
+
+void
+resume_deferring_access_checks (void)
+{
+ if (!deferred_access_no_check)
+ deferred_access_stack->last().deferring_access_checks_kind = dk_deferred;
+}
+
+/* Stop deferring access checks. */
+
+void
+stop_deferring_access_checks (void)
+{
+ if (!deferred_access_no_check)
+ deferred_access_stack->last().deferring_access_checks_kind = dk_no_deferred;
+}
+
+/* Discard the current deferred access checks and restore the
+ previous states. */
+
+void
+pop_deferring_access_checks (void)
+{
+ if (deferred_access_no_check)
+ deferred_access_no_check--;
+ else
+ deferred_access_stack->pop ();
+}
+
+/* Returns a TREE_LIST representing the deferred checks.
+ The TREE_PURPOSE of each node is the type through which the
+ access occurred; the TREE_VALUE is the declaration named.
+ */
+
+vec<deferred_access_check, va_gc> *
+get_deferred_access_checks (void)
+{
+ if (deferred_access_no_check)
+ return NULL;
+ else
+ return (deferred_access_stack->last().deferred_access_checks);
+}
+
+/* Take current deferred checks and combine with the
+ previous states if we also defer checks previously.
+ Otherwise perform checks now. */
+
+void
+pop_to_parent_deferring_access_checks (void)
+{
+ if (deferred_access_no_check)
+ deferred_access_no_check--;
+ else
+ {
+ vec<deferred_access_check, va_gc> *checks;
+ deferred_access *ptr;
+
+ checks = (deferred_access_stack->last ().deferred_access_checks);
+
+ deferred_access_stack->pop ();
+ ptr = &deferred_access_stack->last ();
+ if (ptr->deferring_access_checks_kind == dk_no_deferred)
+ {
+ /* Check access. */
+ perform_access_checks (checks, tf_warning_or_error);
+ }
+ else
+ {
+ /* Merge with parent. */
+ int i, j;
+ deferred_access_check *chk, *probe;
+
+ FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
+ {
+ FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, j, probe)
+ {
+ if (probe->binfo == chk->binfo &&
+ probe->decl == chk->decl &&
+ probe->diag_decl == chk->diag_decl)
+ goto found;
+ }
+ /* Insert into parent's checks. */
+ vec_safe_push (ptr->deferred_access_checks, *chk);
+ found:;
+ }
+ }
+ }
+}
+
+/* Perform the access checks in CHECKS. The TREE_PURPOSE of each node
+ is the BINFO indicating the qualifying scope used to access the
+ DECL node stored in the TREE_VALUE of the node. If CHECKS is empty
+ or we aren't in SFINAE context or all the checks succeed return TRUE,
+ otherwise FALSE. */
+
+bool
+perform_access_checks (vec<deferred_access_check, va_gc> *checks,
+ tsubst_flags_t complain)
+{
+ int i;
+ deferred_access_check *chk;
+ location_t loc = input_location;
+ bool ok = true;
+
+ if (!checks)
+ return true;
+
+ FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
+ {
+ input_location = chk->loc;
+ ok &= enforce_access (chk->binfo, chk->decl, chk->diag_decl, complain);
+ }
+
+ input_location = loc;
+ return (complain & tf_error) ? true : ok;
+}
+
+/* Perform the deferred access checks.
+
+ After performing the checks, we still have to keep the list
+ `deferred_access_stack->deferred_access_checks' since we may want
+ to check access for them again later in a different context.
+ For example:
+
+ class A {
+ typedef int X;
+ static X a;
+ };
+ A::X A::a, x; // No error for `A::a', error for `x'
+
+ We have to perform deferred access of `A::X', first with `A::a',
+ next with `x'. Return value like perform_access_checks above. */
+
+bool
+perform_deferred_access_checks (tsubst_flags_t complain)
+{
+ return perform_access_checks (get_deferred_access_checks (), complain);
+}
+
+/* Defer checking the accessibility of DECL, when looked up in
+ BINFO. DIAG_DECL is the declaration to use to print diagnostics.
+ Return value like perform_access_checks above. */
+
+bool
+perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl,
+ tsubst_flags_t complain)
+{
+ int i;
+ deferred_access *ptr;
+ deferred_access_check *chk;
+
+
+ /* Exit if we are in a context that no access checking is performed.
+ */
+ if (deferred_access_no_check)
+ return true;
+
+ gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
+
+ ptr = &deferred_access_stack->last ();
+
+ /* If we are not supposed to defer access checks, just check now. */
+ if (ptr->deferring_access_checks_kind == dk_no_deferred)
+ {
+ bool ok = enforce_access (binfo, decl, diag_decl, complain);
+ return (complain & tf_error) ? true : ok;
+ }
+
+ /* See if we are already going to perform this check. */
+ FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, i, chk)
+ {
+ if (chk->decl == decl && chk->binfo == binfo &&
+ chk->diag_decl == diag_decl)
+ {
+ return true;
+ }
+ }
+ /* If not, record the check. */
+ deferred_access_check new_access = {binfo, decl, diag_decl, input_location};
+ vec_safe_push (ptr->deferred_access_checks, new_access);
+
+ return true;
+}
+
+/* Returns nonzero if the current statement is a full expression,
+ i.e. temporaries created during that statement should be destroyed
+ at the end of the statement. */
+
+int
+stmts_are_full_exprs_p (void)
+{
+ return current_stmt_tree ()->stmts_are_full_exprs_p;
+}
+
+/* T is a statement. Add it to the statement-tree. This is the C++
+ version. The C/ObjC frontends have a slightly different version of
+ this function. */
+
+tree
+add_stmt (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+
+ if (EXPR_P (t) && code != LABEL_EXPR)
+ {
+ if (!EXPR_HAS_LOCATION (t))
+ SET_EXPR_LOCATION (t, input_location);
+
+ /* When we expand a statement-tree, we must know whether or not the
+ statements are full-expressions. We record that fact here. */
+ STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
+ }
+
+ /* Add T to the statement-tree. Non-side-effect statements need to be
+ recorded during statement expressions. */
+ gcc_checking_assert (!stmt_list_stack->is_empty ());
+ append_to_statement_list_force (t, &cur_stmt_list);
+
+ return t;
+}
+
+/* Returns the stmt_tree to which statements are currently being added. */
+
+stmt_tree
+current_stmt_tree (void)
+{
+ return (cfun
+ ? &cfun->language->base.x_stmt_tree
+ : &scope_chain->x_stmt_tree);
+}
+
+/* If statements are full expressions, wrap STMT in a CLEANUP_POINT_EXPR. */
+
+static tree
+maybe_cleanup_point_expr (tree expr)
+{
+ if (!processing_template_decl && stmts_are_full_exprs_p ())
+ expr = fold_build_cleanup_point_expr (TREE_TYPE (expr), expr);
+ return expr;
+}
+
+/* Like maybe_cleanup_point_expr except have the type of the new expression be
+ void so we don't need to create a temporary variable to hold the inner
+ expression. The reason why we do this is because the original type might be
+ an aggregate and we cannot create a temporary variable for that type. */
+
+tree
+maybe_cleanup_point_expr_void (tree expr)
+{
+ if (!processing_template_decl && stmts_are_full_exprs_p ())
+ expr = fold_build_cleanup_point_expr (void_type_node, expr);
+ return expr;
+}
+
+
+
+/* Create a declaration statement for the declaration given by the DECL. */
+
+void
+add_decl_expr (tree decl)
+{
+ tree r = build_stmt (input_location, DECL_EXPR, decl);
+ if (DECL_INITIAL (decl)
+ || (DECL_SIZE (decl) && TREE_SIDE_EFFECTS (DECL_SIZE (decl))))
+ r = maybe_cleanup_point_expr_void (r);
+ add_stmt (r);
+}
+
+/* Finish a scope. */
+
+tree
+do_poplevel (tree stmt_list)
+{
+ tree block = NULL;
+
+ if (stmts_are_full_exprs_p ())
+ block = poplevel (kept_level_p (), 1, 0);
+
+ stmt_list = pop_stmt_list (stmt_list);
+
+ if (!processing_template_decl)
+ {
+ stmt_list = c_build_bind_expr (input_location, block, stmt_list);
+ /* ??? See c_end_compound_stmt re statement expressions. */
+ }
+
+ return stmt_list;
+}
+
+/* Begin a new scope. */
+
+static tree
+do_pushlevel (scope_kind sk)
+{
+ tree ret = push_stmt_list ();
+ if (stmts_are_full_exprs_p ())
+ begin_scope (sk, NULL);
+ return ret;
+}
+
+/* Queue a cleanup. CLEANUP is an expression/statement to be executed
+ when the current scope is exited. EH_ONLY is true when this is not
+ meant to apply to normal control flow transfer. */
+
+void
+push_cleanup (tree decl, tree cleanup, bool eh_only)
+{
+ tree stmt = build_stmt (input_location, CLEANUP_STMT, NULL, cleanup, decl);
+ CLEANUP_EH_ONLY (stmt) = eh_only;
+ add_stmt (stmt);
+ CLEANUP_BODY (stmt) = push_stmt_list ();
+}
+
+/* Simple infinite loop tracking for -Wreturn-type. We keep a stack of all
+ the current loops, represented by 'NULL_TREE' if we've seen a possible
+ exit, and 'error_mark_node' if not. This is currently used only to
+ suppress the warning about a function with no return statements, and
+ therefore we don't bother noting returns as possible exits. We also
+ don't bother with gotos. */
+
+static void
+begin_maybe_infinite_loop (tree cond)
+{
+ /* Only track this while parsing a function, not during instantiation. */
+ if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl)
+ && !processing_template_decl))
+ return;
+ bool maybe_infinite = true;
+ if (cond)
+ {
+ cond = fold_non_dependent_expr_sfinae (cond, tf_none);
+ cond = maybe_constant_value (cond);
+ maybe_infinite = integer_nonzerop (cond);
+ }
+ vec_safe_push (cp_function_chain->infinite_loops,
+ maybe_infinite ? error_mark_node : NULL_TREE);
+
+}
+
+/* A break is a possible exit for the current loop. */
+
+void
+break_maybe_infinite_loop (void)
+{
+ if (!cfun)
+ return;
+ cp_function_chain->infinite_loops->last() = NULL_TREE;
+}
+
+/* If we reach the end of the loop without seeing a possible exit, we have
+ an infinite loop. */
+
+static void
+end_maybe_infinite_loop (tree cond)
+{
+ if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl)
+ && !processing_template_decl))
+ return;
+ tree current = cp_function_chain->infinite_loops->pop();
+ if (current != NULL_TREE)
+ {
+ cond = fold_non_dependent_expr (cond);
+ cond = maybe_constant_value (cond);
+ if (integer_nonzerop (cond))
+ current_function_infinite_loop = 1;
+ }
+}
+
+
+/* Begin a conditional that might contain a declaration. When generating
+ normal code, we want the declaration to appear before the statement
+ containing the conditional. When generating template code, we want the
+ conditional to be rendered as the raw DECL_EXPR. */
+
+static void
+begin_cond (tree *cond_p)
+{
+ if (processing_template_decl)
+ *cond_p = push_stmt_list ();
+}
+
+/* Finish such a conditional. */
+
+static void
+finish_cond (tree *cond_p, tree expr)
+{
+ if (processing_template_decl)
+ {
+ tree cond = pop_stmt_list (*cond_p);
+
+ if (expr == NULL_TREE)
+ /* Empty condition in 'for'. */
+ gcc_assert (empty_expr_stmt_p (cond));
+ else if (check_for_bare_parameter_packs (expr))
+ expr = error_mark_node;
+ else if (!empty_expr_stmt_p (cond))
+ expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
+ }
+ *cond_p = expr;
+}
+
+/* If *COND_P specifies a conditional with a declaration, transform the
+ loop such that
+ while (A x = 42) { }
+ for (; A x = 42;) { }
+ becomes
+ while (true) { A x = 42; if (!x) break; }
+ for (;;) { A x = 42; if (!x) break; }
+ The statement list for BODY will be empty if the conditional did
+ not declare anything. */
+
+static void
+simplify_loop_decl_cond (tree *cond_p, tree body)
+{
+ tree cond, if_stmt;
+
+ if (!TREE_SIDE_EFFECTS (body))
+ return;
+
+ cond = *cond_p;
+ *cond_p = boolean_true_node;
+
+ if_stmt = begin_if_stmt ();
+ cond = cp_build_unary_op (TRUTH_NOT_EXPR, cond, 0, tf_warning_or_error);
+ finish_if_stmt_cond (cond, if_stmt);
+ finish_break_stmt ();
+ finish_then_clause (if_stmt);
+ finish_if_stmt (if_stmt);
+}
+
+/* Finish a goto-statement. */
+
+tree
+finish_goto_stmt (tree destination)
+{
+ if (identifier_p (destination))
+ destination = lookup_label (destination);
+
+ /* We warn about unused labels with -Wunused. That means we have to
+ mark the used labels as used. */
+ if (TREE_CODE (destination) == LABEL_DECL)
+ TREE_USED (destination) = 1;
+ else
+ {
+ destination = mark_rvalue_use (destination);
+ if (!processing_template_decl)
+ {
+ destination = cp_convert (ptr_type_node, destination,
+ tf_warning_or_error);
+ if (error_operand_p (destination))
+ return NULL_TREE;
+ destination
+ = fold_build_cleanup_point_expr (TREE_TYPE (destination),
+ destination);
+ }
+ }
+
+ check_goto (destination);
+
+ return add_stmt (build_stmt (input_location, GOTO_EXPR, destination));
+}
+
+/* COND is the condition-expression for an if, while, etc.,
+ statement. Convert it to a boolean value, if appropriate.
+ In addition, verify sequence points if -Wsequence-point is enabled. */
+
+static tree
+maybe_convert_cond (tree cond)
+{
+ /* Empty conditions remain empty. */
+ if (!cond)
+ return NULL_TREE;
+
+ /* Wait until we instantiate templates before doing conversion. */
+ if (processing_template_decl)
+ return cond;
+
+ if (warn_sequence_point)
+ verify_sequence_points (cond);
+
+ /* Do the conversion. */
+ cond = convert_from_reference (cond);
+
+ if (TREE_CODE (cond) == MODIFY_EXPR
+ && !TREE_NO_WARNING (cond)
+ && warn_parentheses)
+ {
+ warning (OPT_Wparentheses,
+ "suggest parentheses around assignment used as truth value");
+ TREE_NO_WARNING (cond) = 1;
+ }
+
+ return condition_conversion (cond);
+}
+
+/* Finish an expression-statement, whose EXPRESSION is as indicated. */
+
+tree
+finish_expr_stmt (tree expr)
+{
+ tree r = NULL_TREE;
+
+ if (expr != NULL_TREE)
+ {
+ if (!processing_template_decl)
+ {
+ if (warn_sequence_point)
+ verify_sequence_points (expr);
+ expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
+ }
+ else if (!type_dependent_expression_p (expr))
+ convert_to_void (build_non_dependent_expr (expr), ICV_STATEMENT,
+ tf_warning_or_error);
+
+ if (check_for_bare_parameter_packs (expr))
+ expr = error_mark_node;
+
+ /* Simplification of inner statement expressions, compound exprs,
+ etc can result in us already having an EXPR_STMT. */
+ if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
+ {
+ if (TREE_CODE (expr) != EXPR_STMT)
+ expr = build_stmt (input_location, EXPR_STMT, expr);
+ expr = maybe_cleanup_point_expr_void (expr);
+ }
+
+ r = add_stmt (expr);
+ }
+
+ return r;
+}
+
+
+/* Begin an if-statement. Returns a newly created IF_STMT if
+ appropriate. */
+
+tree
+begin_if_stmt (void)
+{
+ tree r, scope;
+ scope = do_pushlevel (sk_cond);
+ r = build_stmt (input_location, IF_STMT, NULL_TREE,
+ NULL_TREE, NULL_TREE, scope);
+ begin_cond (&IF_COND (r));
+ return r;
+}
+
+/* Process the COND of an if-statement, which may be given by
+ IF_STMT. */
+
+void
+finish_if_stmt_cond (tree cond, tree if_stmt)
+{
+ finish_cond (&IF_COND (if_stmt), maybe_convert_cond (cond));
+ add_stmt (if_stmt);
+ THEN_CLAUSE (if_stmt) = push_stmt_list ();
+}
+
+/* Finish the then-clause of an if-statement, which may be given by
+ IF_STMT. */
+
+tree
+finish_then_clause (tree if_stmt)
+{
+ THEN_CLAUSE (if_stmt) = pop_stmt_list (THEN_CLAUSE (if_stmt));
+ return if_stmt;
+}
+
+/* Begin the else-clause of an if-statement. */
+
+void
+begin_else_clause (tree if_stmt)
+{
+ ELSE_CLAUSE (if_stmt) = push_stmt_list ();
+}
+
+/* Finish the else-clause of an if-statement, which may be given by
+ IF_STMT. */
+
+void
+finish_else_clause (tree if_stmt)
+{
+ ELSE_CLAUSE (if_stmt) = pop_stmt_list (ELSE_CLAUSE (if_stmt));
+}
+
+/* Finish an if-statement. */
+
+void
+finish_if_stmt (tree if_stmt)
+{
+ tree scope = IF_SCOPE (if_stmt);
+ IF_SCOPE (if_stmt) = NULL;
+ add_stmt (do_poplevel (scope));
+}
+
+/* Begin a while-statement. Returns a newly created WHILE_STMT if
+ appropriate. */
+
+tree
+begin_while_stmt (void)
+{
+ tree r;
+ r = build_stmt (input_location, WHILE_STMT, NULL_TREE, NULL_TREE);
+ add_stmt (r);
+ WHILE_BODY (r) = do_pushlevel (sk_block);
+ begin_cond (&WHILE_COND (r));
+ return r;
+}
+
+/* Process the COND of a while-statement, which may be given by
+ WHILE_STMT. */
+
+void
+finish_while_stmt_cond (tree cond, tree while_stmt, bool ivdep)
+{
+ cond = maybe_convert_cond (cond);
+ finish_cond (&WHILE_COND (while_stmt), cond);
+ begin_maybe_infinite_loop (cond);
+ if (ivdep && cond != error_mark_node)
+ WHILE_COND (while_stmt) = build2 (ANNOTATE_EXPR,
+ TREE_TYPE (WHILE_COND (while_stmt)),
+ WHILE_COND (while_stmt),
+ build_int_cst (integer_type_node,
+ annot_expr_ivdep_kind));
+ simplify_loop_decl_cond (&WHILE_COND (while_stmt), WHILE_BODY (while_stmt));
+}
+
+/* Finish a while-statement, which may be given by WHILE_STMT. */
+
+void
+finish_while_stmt (tree while_stmt)
+{
+ end_maybe_infinite_loop (boolean_true_node);
+ WHILE_BODY (while_stmt) = do_poplevel (WHILE_BODY (while_stmt));
+}
+
+/* Begin a do-statement. Returns a newly created DO_STMT if
+ appropriate. */
+
+tree
+begin_do_stmt (void)
+{
+ tree r = build_stmt (input_location, DO_STMT, NULL_TREE, NULL_TREE);
+ begin_maybe_infinite_loop (boolean_true_node);
+ add_stmt (r);
+ DO_BODY (r) = push_stmt_list ();
+ return r;
+}
+
+/* Finish the body of a do-statement, which may be given by DO_STMT. */
+
+void
+finish_do_body (tree do_stmt)
+{
+ tree body = DO_BODY (do_stmt) = pop_stmt_list (DO_BODY (do_stmt));
+
+ if (TREE_CODE (body) == STATEMENT_LIST && STATEMENT_LIST_TAIL (body))
+ body = STATEMENT_LIST_TAIL (body)->stmt;
+
+ if (IS_EMPTY_STMT (body))
+ warning (OPT_Wempty_body,
+ "suggest explicit braces around empty body in %<do%> statement");
+}
+
+/* Finish a do-statement, which may be given by DO_STMT, and whose
+ COND is as indicated. */
+
+void
+finish_do_stmt (tree cond, tree do_stmt, bool ivdep)
+{
+ cond = maybe_convert_cond (cond);
+ end_maybe_infinite_loop (cond);
+ if (ivdep && cond != error_mark_node)
+ cond = build2 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
+ build_int_cst (integer_type_node, annot_expr_ivdep_kind));
+ DO_COND (do_stmt) = cond;
+}
+
+/* Finish a return-statement. The EXPRESSION returned, if any, is as
+ indicated. */
+
+tree
+finish_return_stmt (tree expr)
+{
+ tree r;
+ bool no_warning;
+
+ expr = check_return_expr (expr, &no_warning);
+
+ if (error_operand_p (expr)
+ || (flag_openmp && !check_omp_return ()))
+ return error_mark_node;
+ if (!processing_template_decl)
+ {
+ if (warn_sequence_point)
+ verify_sequence_points (expr);
+
+ if (DECL_DESTRUCTOR_P (current_function_decl)
+ || (DECL_CONSTRUCTOR_P (current_function_decl)
+ && targetm.cxx.cdtor_returns_this ()))
+ {
+ /* Similarly, all destructors must run destructors for
+ base-classes before returning. So, all returns in a
+ destructor get sent to the DTOR_LABEL; finish_function emits
+ code to return a value there. */
+ return finish_goto_stmt (cdtor_label);
+ }
+ }
+
+ r = build_stmt (input_location, RETURN_EXPR, expr);
+ TREE_NO_WARNING (r) |= no_warning;
+ r = maybe_cleanup_point_expr_void (r);
+ r = add_stmt (r);
+
+ return r;
+}
+
+/* Begin the scope of a for-statement or a range-for-statement.
+ Both the returned trees are to be used in a call to
+ begin_for_stmt or begin_range_for_stmt. */
+
+tree
+begin_for_scope (tree *init)
+{
+ tree scope = NULL_TREE;
+ if (flag_new_for_scope > 0)
+ scope = do_pushlevel (sk_for);
+
+ if (processing_template_decl)
+ *init = push_stmt_list ();
+ else
+ *init = NULL_TREE;
+
+ return scope;
+}
+
+/* Begin a for-statement. Returns a new FOR_STMT.
+ SCOPE and INIT should be the return of begin_for_scope,
+ or both NULL_TREE */
+
+tree
+begin_for_stmt (tree scope, tree init)
+{
+ tree r;
+
+ r = build_stmt (input_location, FOR_STMT, NULL_TREE, NULL_TREE,
+ NULL_TREE, NULL_TREE, NULL_TREE);
+
+ if (scope == NULL_TREE)
+ {
+ gcc_assert (!init || !(flag_new_for_scope > 0));
+ if (!init)
+ scope = begin_for_scope (&init);
+ }
+ FOR_INIT_STMT (r) = init;
+ FOR_SCOPE (r) = scope;
+
+ return r;
+}
+
+/* Finish the for-init-statement of a for-statement, which may be
+ given by FOR_STMT. */
+
+void
+finish_for_init_stmt (tree for_stmt)
+{
+ if (processing_template_decl)
+ FOR_INIT_STMT (for_stmt) = pop_stmt_list (FOR_INIT_STMT (for_stmt));
+ add_stmt (for_stmt);
+ FOR_BODY (for_stmt) = do_pushlevel (sk_block);
+ begin_cond (&FOR_COND (for_stmt));
+}
+
+/* Finish the COND of a for-statement, which may be given by
+ FOR_STMT. */
+
+void
+finish_for_cond (tree cond, tree for_stmt, bool ivdep)
+{
+ cond = maybe_convert_cond (cond);
+ finish_cond (&FOR_COND (for_stmt), cond);
+ begin_maybe_infinite_loop (cond);
+ if (ivdep && cond != error_mark_node)
+ FOR_COND (for_stmt) = build2 (ANNOTATE_EXPR,
+ TREE_TYPE (FOR_COND (for_stmt)),
+ FOR_COND (for_stmt),
+ build_int_cst (integer_type_node,
+ annot_expr_ivdep_kind));
+ simplify_loop_decl_cond (&FOR_COND (for_stmt), FOR_BODY (for_stmt));
+}
+
+/* Finish the increment-EXPRESSION in a for-statement, which may be
+ given by FOR_STMT. */
+
+void
+finish_for_expr (tree expr, tree for_stmt)
+{
+ if (!expr)
+ return;
+ /* If EXPR is an overloaded function, issue an error; there is no
+ context available to use to perform overload resolution. */
+ if (type_unknown_p (expr))
+ {
+ cxx_incomplete_type_error (expr, TREE_TYPE (expr));
+ expr = error_mark_node;
+ }
+ if (!processing_template_decl)
+ {
+ if (warn_sequence_point)
+ verify_sequence_points (expr);
+ expr = convert_to_void (expr, ICV_THIRD_IN_FOR,
+ tf_warning_or_error);
+ }
+ else if (!type_dependent_expression_p (expr))
+ convert_to_void (build_non_dependent_expr (expr), ICV_THIRD_IN_FOR,
+ tf_warning_or_error);
+ expr = maybe_cleanup_point_expr_void (expr);
+ if (check_for_bare_parameter_packs (expr))
+ expr = error_mark_node;
+ FOR_EXPR (for_stmt) = expr;
+}
+
+/* Finish the body of a for-statement, which may be given by
+ FOR_STMT. The increment-EXPR for the loop must be
+ provided.
+ It can also finish RANGE_FOR_STMT. */
+
+void
+finish_for_stmt (tree for_stmt)
+{
+ end_maybe_infinite_loop (boolean_true_node);
+
+ if (TREE_CODE (for_stmt) == RANGE_FOR_STMT)
+ RANGE_FOR_BODY (for_stmt) = do_poplevel (RANGE_FOR_BODY (for_stmt));
+ else
+ FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt));
+
+ /* Pop the scope for the body of the loop. */
+ if (flag_new_for_scope > 0)
+ {
+ tree scope;
+ tree *scope_ptr = (TREE_CODE (for_stmt) == RANGE_FOR_STMT
+ ? &RANGE_FOR_SCOPE (for_stmt)
+ : &FOR_SCOPE (for_stmt));
+ scope = *scope_ptr;
+ *scope_ptr = NULL;
+ add_stmt (do_poplevel (scope));
+ }
+}
+
+/* Begin a range-for-statement. Returns a new RANGE_FOR_STMT.
+ SCOPE and INIT should be the return of begin_for_scope,
+ or both NULL_TREE .
+ To finish it call finish_for_stmt(). */
+
+tree
+begin_range_for_stmt (tree scope, tree init)
+{
+ tree r;
+
+ begin_maybe_infinite_loop (boolean_false_node);
+
+ r = build_stmt (input_location, RANGE_FOR_STMT,
+ NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
+
+ if (scope == NULL_TREE)
+ {
+ gcc_assert (!init || !(flag_new_for_scope > 0));
+ if (!init)
+ scope = begin_for_scope (&init);
+ }
+
+ /* RANGE_FOR_STMTs do not use nor save the init tree, so we
+ pop it now. */
+ if (init)
+ pop_stmt_list (init);
+ RANGE_FOR_SCOPE (r) = scope;
+
+ return r;
+}
+
+/* Finish the head of a range-based for statement, which may
+ be given by RANGE_FOR_STMT. DECL must be the declaration
+ and EXPR must be the loop expression. */
+
+void
+finish_range_for_decl (tree range_for_stmt, tree decl, tree expr)
+{
+ RANGE_FOR_DECL (range_for_stmt) = decl;
+ RANGE_FOR_EXPR (range_for_stmt) = expr;
+ add_stmt (range_for_stmt);
+ RANGE_FOR_BODY (range_for_stmt) = do_pushlevel (sk_block);
+}
+
+/* Finish a break-statement. */
+
+tree
+finish_break_stmt (void)
+{
+ /* In switch statements break is sometimes stylistically used after
+ a return statement. This can lead to spurious warnings about
+ control reaching the end of a non-void function when it is
+ inlined. Note that we are calling block_may_fallthru with
+ language specific tree nodes; this works because
+ block_may_fallthru returns true when given something it does not
+ understand. */
+ if (!block_may_fallthru (cur_stmt_list))
+ return void_zero_node;
+ return add_stmt (build_stmt (input_location, BREAK_STMT));
+}
+
+/* Finish a continue-statement. */
+
+tree
+finish_continue_stmt (void)
+{
+ return add_stmt (build_stmt (input_location, CONTINUE_STMT));
+}
+
+/* Begin a switch-statement. Returns a new SWITCH_STMT if
+ appropriate. */
+
+tree
+begin_switch_stmt (void)
+{
+ tree r, scope;
+
+ scope = do_pushlevel (sk_cond);
+ r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE, scope);
+
+ begin_cond (&SWITCH_STMT_COND (r));
+
+ return r;
+}
+
+/* Finish the cond of a switch-statement. */
+
+void
+finish_switch_cond (tree cond, tree switch_stmt)
+{
+ tree orig_type = NULL;
+ if (!processing_template_decl)
+ {
+ /* Convert the condition to an integer or enumeration type. */
+ cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true);
+ if (cond == NULL_TREE)
+ {
+ error ("switch quantity not an integer");
+ cond = error_mark_node;
+ }
+ orig_type = TREE_TYPE (cond);
+ if (cond != error_mark_node)
+ {
+ /* [stmt.switch]
+
+ Integral promotions are performed. */
+ cond = perform_integral_promotions (cond);
+ cond = maybe_cleanup_point_expr (cond);
+ }
+ }
+ if (check_for_bare_parameter_packs (cond))
+ cond = error_mark_node;
+ else if (!processing_template_decl && warn_sequence_point)
+ verify_sequence_points (cond);
+
+ finish_cond (&SWITCH_STMT_COND (switch_stmt), cond);
+ SWITCH_STMT_TYPE (switch_stmt) = orig_type;
+ add_stmt (switch_stmt);
+ push_switch (switch_stmt);
+ SWITCH_STMT_BODY (switch_stmt) = push_stmt_list ();
+}
+
+/* Finish the body of a switch-statement, which may be given by
+ SWITCH_STMT. The COND to switch on is indicated. */
+
+void
+finish_switch_stmt (tree switch_stmt)
+{
+ tree scope;
+
+ SWITCH_STMT_BODY (switch_stmt) =
+ pop_stmt_list (SWITCH_STMT_BODY (switch_stmt));
+ pop_switch ();
+
+ scope = SWITCH_STMT_SCOPE (switch_stmt);
+ SWITCH_STMT_SCOPE (switch_stmt) = NULL;
+ add_stmt (do_poplevel (scope));
+}
+
+/* Begin a try-block. Returns a newly-created TRY_BLOCK if
+ appropriate. */
+
+tree
+begin_try_block (void)
+{
+ tree r = build_stmt (input_location, TRY_BLOCK, NULL_TREE, NULL_TREE);
+ add_stmt (r);
+ TRY_STMTS (r) = push_stmt_list ();
+ return r;
+}
+
+/* Likewise, for a function-try-block. The block returned in
+ *COMPOUND_STMT is an artificial outer scope, containing the
+ function-try-block. */
+
+tree
+begin_function_try_block (tree *compound_stmt)
+{
+ tree r;
+ /* This outer scope does not exist in the C++ standard, but we need
+ a place to put __FUNCTION__ and similar variables. */
+ *compound_stmt = begin_compound_stmt (0);
+ r = begin_try_block ();
+ FN_TRY_BLOCK_P (r) = 1;
+ return r;
+}
+
+/* Finish a try-block, which may be given by TRY_BLOCK. */
+
+void
+finish_try_block (tree try_block)
+{
+ TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block));
+ TRY_HANDLERS (try_block) = push_stmt_list ();
+}
+
+/* Finish the body of a cleanup try-block, which may be given by
+ TRY_BLOCK. */
+
+void
+finish_cleanup_try_block (tree try_block)
+{
+ TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block));
+}
+
+/* Finish an implicitly generated try-block, with a cleanup is given
+ by CLEANUP. */
+
+void
+finish_cleanup (tree cleanup, tree try_block)
+{
+ TRY_HANDLERS (try_block) = cleanup;
+ CLEANUP_P (try_block) = 1;
+}
+
+/* Likewise, for a function-try-block. */
+
+void
+finish_function_try_block (tree try_block)
+{
+ finish_try_block (try_block);
+ /* FIXME : something queer about CTOR_INITIALIZER somehow following
+ the try block, but moving it inside. */
+ in_function_try_handler = 1;
+}
+
+/* Finish a handler-sequence for a try-block, which may be given by
+ TRY_BLOCK. */
+
+void
+finish_handler_sequence (tree try_block)
+{
+ TRY_HANDLERS (try_block) = pop_stmt_list (TRY_HANDLERS (try_block));
+ check_handlers (TRY_HANDLERS (try_block));
+}
+
+/* Finish the handler-seq for a function-try-block, given by
+ TRY_BLOCK. COMPOUND_STMT is the outer block created by
+ begin_function_try_block. */
+
+void
+finish_function_handler_sequence (tree try_block, tree compound_stmt)
+{
+ in_function_try_handler = 0;
+ finish_handler_sequence (try_block);
+ finish_compound_stmt (compound_stmt);
+}
+
+/* Begin a handler. Returns a HANDLER if appropriate. */
+
+tree
+begin_handler (void)
+{
+ tree r;
+
+ r = build_stmt (input_location, HANDLER, NULL_TREE, NULL_TREE);
+ add_stmt (r);
+
+ /* Create a binding level for the eh_info and the exception object
+ cleanup. */
+ HANDLER_BODY (r) = do_pushlevel (sk_catch);
+
+ return r;
+}
+
+/* Finish the handler-parameters for a handler, which may be given by
+ HANDLER. DECL is the declaration for the catch parameter, or NULL
+ if this is a `catch (...)' clause. */
+
+void
+finish_handler_parms (tree decl, tree handler)
+{
+ tree type = NULL_TREE;
+ if (processing_template_decl)
+ {
+ if (decl)
+ {
+ decl = pushdecl (decl);
+ decl = push_template_decl (decl);
+ HANDLER_PARMS (handler) = decl;
+ type = TREE_TYPE (decl);
+ }
+ }
+ else
+ type = expand_start_catch_block (decl);
+ HANDLER_TYPE (handler) = type;
+}
+
+/* Finish a handler, which may be given by HANDLER. The BLOCKs are
+ the return value from the matching call to finish_handler_parms. */
+
+void
+finish_handler (tree handler)
+{
+ if (!processing_template_decl)
+ expand_end_catch_block ();
+ HANDLER_BODY (handler) = do_poplevel (HANDLER_BODY (handler));
+}
+
+/* Begin a compound statement. FLAGS contains some bits that control the
+ behavior and context. If BCS_NO_SCOPE is set, the compound statement
+ does not define a scope. If BCS_FN_BODY is set, this is the outermost
+ block of a function. If BCS_TRY_BLOCK is set, this is the block
+ created on behalf of a TRY statement. Returns a token to be passed to
+ finish_compound_stmt. */
+
+tree
+begin_compound_stmt (unsigned int flags)
+{
+ tree r;
+
+ if (flags & BCS_NO_SCOPE)
+ {
+ r = push_stmt_list ();
+ STATEMENT_LIST_NO_SCOPE (r) = 1;
+
+ /* Normally, we try hard to keep the BLOCK for a statement-expression.
+ But, if it's a statement-expression with a scopeless block, there's
+ nothing to keep, and we don't want to accidentally keep a block
+ *inside* the scopeless block. */
+ keep_next_level (false);
+ }
+ else
+ r = do_pushlevel (flags & BCS_TRY_BLOCK ? sk_try : sk_block);
+
+ /* When processing a template, we need to remember where the braces were,
+ so that we can set up identical scopes when instantiating the template
+ later. BIND_EXPR is a handy candidate for this.
+ Note that do_poplevel won't create a BIND_EXPR itself here (and thus
+ result in nested BIND_EXPRs), since we don't build BLOCK nodes when
+ processing templates. */
+ if (processing_template_decl)
+ {
+ r = build3 (BIND_EXPR, NULL, NULL, r, NULL);
+ BIND_EXPR_TRY_BLOCK (r) = (flags & BCS_TRY_BLOCK) != 0;
+ BIND_EXPR_BODY_BLOCK (r) = (flags & BCS_FN_BODY) != 0;
+ TREE_SIDE_EFFECTS (r) = 1;
+ }
+
+ return r;
+}
+
+/* Finish a compound-statement, which is given by STMT. */
+
+void
+finish_compound_stmt (tree stmt)
+{
+ if (TREE_CODE (stmt) == BIND_EXPR)
+ {
+ tree body = do_poplevel (BIND_EXPR_BODY (stmt));
+ /* If the STATEMENT_LIST is empty and this BIND_EXPR isn't special,
+ discard the BIND_EXPR so it can be merged with the containing
+ STATEMENT_LIST. */
+ if (TREE_CODE (body) == STATEMENT_LIST
+ && STATEMENT_LIST_HEAD (body) == NULL
+ && !BIND_EXPR_BODY_BLOCK (stmt)
+ && !BIND_EXPR_TRY_BLOCK (stmt))
+ stmt = body;
+ else
+ BIND_EXPR_BODY (stmt) = body;
+ }
+ else if (STATEMENT_LIST_NO_SCOPE (stmt))
+ stmt = pop_stmt_list (stmt);
+ else
+ {
+ /* Destroy any ObjC "super" receivers that may have been
+ created. */
+ objc_clear_super_receiver ();
+
+ stmt = do_poplevel (stmt);
+ }
+
+ /* ??? See c_end_compound_stmt wrt statement expressions. */
+ add_stmt (stmt);
+}
+
+/* Finish an asm-statement, whose components are a STRING, some
+ OUTPUT_OPERANDS, some INPUT_OPERANDS, some CLOBBERS and some
+ LABELS. Also note whether the asm-statement should be
+ considered volatile. */
+
+tree
+finish_asm_stmt (int volatile_p, tree string, tree output_operands,
+ tree input_operands, tree clobbers, tree labels)
+{
+ tree r;
+ tree t;
+ int ninputs = list_length (input_operands);
+ int noutputs = list_length (output_operands);
+
+ if (!processing_template_decl)
+ {
+ const char *constraint;
+ const char **oconstraints;
+ bool allows_mem, allows_reg, is_inout;
+ tree operand;
+ int i;
+
+ oconstraints = XALLOCAVEC (const char *, noutputs);
+
+ string = resolve_asm_operand_names (string, output_operands,
+ input_operands, labels);
+
+ for (i = 0, t = output_operands; t; t = TREE_CHAIN (t), ++i)
+ {
+ operand = TREE_VALUE (t);
+
+ /* ??? Really, this should not be here. Users should be using a
+ proper lvalue, dammit. But there's a long history of using
+ casts in the output operands. In cases like longlong.h, this
+ becomes a primitive form of typechecking -- if the cast can be
+ removed, then the output operand had a type of the proper width;
+ otherwise we'll get an error. Gross, but ... */
+ STRIP_NOPS (operand);
+
+ operand = mark_lvalue_use (operand);
+
+ if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
+ operand = error_mark_node;
+
+ if (operand != error_mark_node
+ && (TREE_READONLY (operand)
+ || CP_TYPE_CONST_P (TREE_TYPE (operand))
+ /* Functions are not modifiable, even though they are
+ lvalues. */
+ || TREE_CODE (TREE_TYPE (operand)) == FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (operand)) == METHOD_TYPE
+ /* If it's an aggregate and any field is const, then it is
+ effectively const. */
+ || (CLASS_TYPE_P (TREE_TYPE (operand))
+ && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
+ cxx_readonly_error (operand, lv_asm);
+
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
+ oconstraints[i] = constraint;
+
+ if (parse_output_constraint (&constraint, i, ninputs, noutputs,
+ &allows_mem, &allows_reg, &is_inout))
+ {
+ /* If the operand is going to end up in memory,
+ mark it addressable. */
+ if (!allows_reg && !cxx_mark_addressable (operand))
+ operand = error_mark_node;
+ }
+ else
+ operand = error_mark_node;
+
+ TREE_VALUE (t) = operand;
+ }
+
+ for (i = 0, t = input_operands; t; ++i, t = TREE_CHAIN (t))
+ {
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
+ bool constraint_parsed
+ = parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
+ oconstraints, &allows_mem, &allows_reg);
+ /* If the operand is going to end up in memory, don't call
+ decay_conversion. */
+ if (constraint_parsed && !allows_reg && allows_mem)
+ operand = mark_lvalue_use (TREE_VALUE (t));
+ else
+ operand = decay_conversion (TREE_VALUE (t), tf_warning_or_error);
+
+ /* If the type of the operand hasn't been determined (e.g.,
+ because it involves an overloaded function), then issue
+ an error message. There's no context available to
+ resolve the overloading. */
+ if (TREE_TYPE (operand) == unknown_type_node)
+ {
+ error ("type of asm operand %qE could not be determined",
+ TREE_VALUE (t));
+ operand = error_mark_node;
+ }
+
+ if (constraint_parsed)
+ {
+ /* If the operand is going to end up in memory,
+ mark it addressable. */
+ if (!allows_reg && allows_mem)
+ {
+ /* Strip the nops as we allow this case. FIXME, this really
+ should be rejected or made deprecated. */
+ STRIP_NOPS (operand);
+ if (!cxx_mark_addressable (operand))
+ operand = error_mark_node;
+ }
+ else if (!allows_reg && !allows_mem)
+ {
+ /* If constraint allows neither register nor memory,
+ try harder to get a constant. */
+ tree constop = maybe_constant_value (operand);
+ if (TREE_CONSTANT (constop))
+ operand = constop;
+ }
+ }
+ else
+ operand = error_mark_node;
+
+ TREE_VALUE (t) = operand;
+ }
+ }
+
+ r = build_stmt (input_location, ASM_EXPR, string,
+ output_operands, input_operands,
+ clobbers, labels);
+ ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
+ r = maybe_cleanup_point_expr_void (r);
+ return add_stmt (r);
+}
+
+/* Finish a label with the indicated NAME. Returns the new label. */
+
+tree
+finish_label_stmt (tree name)
+{
+ tree decl = define_label (input_location, name);
+
+ if (decl == error_mark_node)
+ return error_mark_node;
+
+ add_stmt (build_stmt (input_location, LABEL_EXPR, decl));
+
+ return decl;
+}
+
+/* Finish a series of declarations for local labels. G++ allows users
+ to declare "local" labels, i.e., labels with scope. This extension
+ is useful when writing code involving statement-expressions. */
+
+void
+finish_label_decl (tree name)
+{
+ if (!at_function_scope_p ())
+ {
+ error ("__label__ declarations are only allowed in function scopes");
+ return;
+ }
+
+ add_decl_expr (declare_local_label (name));
+}
+
+/* When DECL goes out of scope, make sure that CLEANUP is executed. */
+
+void
+finish_decl_cleanup (tree decl, tree cleanup)
+{
+ push_cleanup (decl, cleanup, false);
+}
+
+/* If the current scope exits with an exception, run CLEANUP. */
+
+void
+finish_eh_cleanup (tree cleanup)
+{
+ push_cleanup (NULL, cleanup, true);
+}
+
+/* The MEM_INITS is a list of mem-initializers, in reverse of the
+ order they were written by the user. Each node is as for
+ emit_mem_initializers. */
+
+void
+finish_mem_initializers (tree mem_inits)
+{
+ /* Reorder the MEM_INITS so that they are in the order they appeared
+ in the source program. */
+ mem_inits = nreverse (mem_inits);
+
+ if (processing_template_decl)
+ {
+ tree mem;
+
+ for (mem = mem_inits; mem; mem = TREE_CHAIN (mem))
+ {
+ /* If the TREE_PURPOSE is a TYPE_PACK_EXPANSION, skip the
+ check for bare parameter packs in the TREE_VALUE, because
+ any parameter packs in the TREE_VALUE have already been
+ bound as part of the TREE_PURPOSE. See
+ make_pack_expansion for more information. */
+ if (TREE_CODE (TREE_PURPOSE (mem)) != TYPE_PACK_EXPANSION
+ && check_for_bare_parameter_packs (TREE_VALUE (mem)))
+ TREE_VALUE (mem) = error_mark_node;
+ }
+
+ add_stmt (build_min_nt_loc (UNKNOWN_LOCATION,
+ CTOR_INITIALIZER, mem_inits));
+ }
+ else
+ emit_mem_initializers (mem_inits);
+}
+
+/* Obfuscate EXPR if it looks like an id-expression or member access so
+ that the call to finish_decltype in do_auto_deduction will give the
+ right result. */
+
+tree
+force_paren_expr (tree expr)
+{
+ /* This is only needed for decltype(auto) in C++14. */
+ if (cxx_dialect < cxx1y)
+ return expr;
+
+ /* If we're in unevaluated context, we can't be deducing a
+ return/initializer type, so we don't need to mess with this. */
+ if (cp_unevaluated_operand)
+ return expr;
+
+ if (!DECL_P (expr) && TREE_CODE (expr) != COMPONENT_REF
+ && TREE_CODE (expr) != SCOPE_REF)
+ return expr;
+
+ if (TREE_CODE (expr) == COMPONENT_REF)
+ REF_PARENTHESIZED_P (expr) = true;
+ else if (type_dependent_expression_p (expr))
+ expr = build1 (PAREN_EXPR, TREE_TYPE (expr), expr);
+ else
+ {
+ cp_lvalue_kind kind = lvalue_kind (expr);
+ if ((kind & ~clk_class) != clk_none)
+ {
+ tree type = unlowered_expr_type (expr);
+ bool rval = !!(kind & clk_rvalueref);
+ type = cp_build_reference_type (type, rval);
+ expr = build_static_cast (type, expr, tf_error);
+ }
+ }
+
+ return expr;
+}
+
+/* Finish a parenthesized expression EXPR. */
+
+tree
+finish_parenthesized_expr (tree expr)
+{
+ if (EXPR_P (expr))
+ /* This inhibits warnings in c_common_truthvalue_conversion. */
+ TREE_NO_WARNING (expr) = 1;
+
+ if (TREE_CODE (expr) == OFFSET_REF
+ || TREE_CODE (expr) == SCOPE_REF)
+ /* [expr.unary.op]/3 The qualified id of a pointer-to-member must not be
+ enclosed in parentheses. */
+ PTRMEM_OK_P (expr) = 0;
+
+ if (TREE_CODE (expr) == STRING_CST)
+ PAREN_STRING_LITERAL_P (expr) = 1;
+
+ expr = force_paren_expr (expr);
+
+ return expr;
+}
+
+/* Finish a reference to a non-static data member (DECL) that is not
+ preceded by `.' or `->'. */
+
+tree
+finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
+{
+ gcc_assert (TREE_CODE (decl) == FIELD_DECL);
+
+ if (!object)
+ {
+ tree scope = qualifying_scope;
+ if (scope == NULL_TREE)
+ scope = context_for_name_lookup (decl);
+ object = maybe_dummy_object (scope, NULL);
+ }
+
+ object = maybe_resolve_dummy (object);
+ if (object == error_mark_node)
+ return error_mark_node;
+
+ /* DR 613: Can use non-static data members without an associated
+ object in sizeof/decltype/alignof. */
+ if (is_dummy_object (object) && cp_unevaluated_operand == 0
+ && (!processing_template_decl || !current_class_ref))
+ {
+ if (current_function_decl
+ && DECL_STATIC_FUNCTION_P (current_function_decl))
+ error ("invalid use of member %q+D in static member function", decl);
+ else
+ error ("invalid use of non-static data member %q+D", decl);
+ error ("from this location");
+
+ return error_mark_node;
+ }
+
+ if (current_class_ptr)
+ TREE_USED (current_class_ptr) = 1;
+ if (processing_template_decl && !qualifying_scope)
+ {
+ tree type = TREE_TYPE (decl);
+
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ /* Quals on the object don't matter. */;
+ else if (PACK_EXPANSION_P (type))
+ /* Don't bother trying to represent this. */
+ type = NULL_TREE;
+ else
+ {
+ /* Set the cv qualifiers. */
+ int quals = cp_type_quals (TREE_TYPE (object));
+
+ if (DECL_MUTABLE_P (decl))
+ quals &= ~TYPE_QUAL_CONST;
+
+ quals |= cp_type_quals (TREE_TYPE (decl));
+ type = cp_build_qualified_type (type, quals);
+ }
+
+ return (convert_from_reference
+ (build_min (COMPONENT_REF, type, object, decl, NULL_TREE)));
+ }
+ /* If PROCESSING_TEMPLATE_DECL is nonzero here, then
+ QUALIFYING_SCOPE is also non-null. Wrap this in a SCOPE_REF
+ for now. */
+ else if (processing_template_decl)
+ return build_qualified_name (TREE_TYPE (decl),
+ qualifying_scope,
+ decl,
+ /*template_p=*/false);
+ else
+ {
+ tree access_type = TREE_TYPE (object);
+
+ perform_or_defer_access_check (TYPE_BINFO (access_type), decl,
+ decl, tf_warning_or_error);
+
+ /* If the data member was named `C::M', convert `*this' to `C'
+ first. */
+ if (qualifying_scope)
+ {
+ tree binfo = NULL_TREE;
+ object = build_scoped_ref (object, qualifying_scope,
+ &binfo);
+ }
+
+ return build_class_member_access_expr (object, decl,
+ /*access_path=*/NULL_TREE,
+ /*preserve_reference=*/false,
+ tf_warning_or_error);
+ }
+}
+
+/* If we are currently parsing a template and we encountered a typedef
+ TYPEDEF_DECL that is being accessed though CONTEXT, this function
+ adds the typedef to a list tied to the current template.
+ At template instantiation time, that list is walked and access check
+ performed for each typedef.
+ LOCATION is the location of the usage point of TYPEDEF_DECL. */
+
+void
+add_typedef_to_current_template_for_access_check (tree typedef_decl,
+ tree context,
+ location_t location)
+{
+ tree template_info = NULL;
+ tree cs = current_scope ();
+
+ if (!is_typedef_decl (typedef_decl)
+ || !context
+ || !CLASS_TYPE_P (context)
+ || !cs)
+ return;
+
+ if (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL)
+ template_info = get_template_info (cs);
+
+ if (template_info
+ && TI_TEMPLATE (template_info)
+ && !currently_open_class (context))
+ append_type_to_template_for_access_check (cs, typedef_decl,
+ context, location);
+}
+
+/* DECL was the declaration to which a qualified-id resolved. Issue
+ an error message if it is not accessible. If OBJECT_TYPE is
+ non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the
+ type of `*x', or `x', respectively. If the DECL was named as
+ `A::B' then NESTED_NAME_SPECIFIER is `A'. */
+
+void
+check_accessibility_of_qualified_id (tree decl,
+ tree object_type,
+ tree nested_name_specifier)
+{
+ tree scope;
+ tree qualifying_type = NULL_TREE;
+
+ /* If we are parsing a template declaration and if decl is a typedef,
+ add it to a list tied to the template.
+ At template instantiation time, that list will be walked and
+ access check performed. */
+ add_typedef_to_current_template_for_access_check (decl,
+ nested_name_specifier
+ ? nested_name_specifier
+ : DECL_CONTEXT (decl),
+ input_location);
+
+ /* If we're not checking, return immediately. */
+ if (deferred_access_no_check)
+ return;
+
+ /* Determine the SCOPE of DECL. */
+ scope = context_for_name_lookup (decl);
+ /* If the SCOPE is not a type, then DECL is not a member. */
+ if (!TYPE_P (scope))
+ return;
+ /* Compute the scope through which DECL is being accessed. */
+ if (object_type
+ /* OBJECT_TYPE might not be a class type; consider:
+
+ class A { typedef int I; };
+ I *p;
+ p->A::I::~I();
+
+ In this case, we will have "A::I" as the DECL, but "I" as the
+ OBJECT_TYPE. */
+ && CLASS_TYPE_P (object_type)
+ && DERIVED_FROM_P (scope, object_type))
+ /* If we are processing a `->' or `.' expression, use the type of the
+ left-hand side. */
+ qualifying_type = object_type;
+ else if (nested_name_specifier)
+ {
+ /* If the reference is to a non-static member of the
+ current class, treat it as if it were referenced through
+ `this'. */
+ if (DECL_NONSTATIC_MEMBER_P (decl)
+ && current_class_ptr
+ && DERIVED_FROM_P (scope, current_class_type))
+ qualifying_type = current_class_type;
+ /* Otherwise, use the type indicated by the
+ nested-name-specifier. */
+ else
+ qualifying_type = nested_name_specifier;
+ }
+ else
+ /* Otherwise, the name must be from the current class or one of
+ its bases. */
+ qualifying_type = currently_open_derived_class (scope);
+
+ if (qualifying_type
+ /* It is possible for qualifying type to be a TEMPLATE_TYPE_PARM
+ or similar in a default argument value. */
+ && CLASS_TYPE_P (qualifying_type)
+ && !dependent_type_p (qualifying_type))
+ perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl,
+ decl, tf_warning_or_error);
+}
+
+/* EXPR is the result of a qualified-id. The QUALIFYING_CLASS was the
+ class named to the left of the "::" operator. DONE is true if this
+ expression is a complete postfix-expression; it is false if this
+ expression is followed by '->', '[', '(', etc. ADDRESS_P is true
+ iff this expression is the operand of '&'. TEMPLATE_P is true iff
+ the qualified-id was of the form "A::template B". TEMPLATE_ARG_P
+ is true iff this qualified name appears as a template argument. */
+
+tree
+finish_qualified_id_expr (tree qualifying_class,
+ tree expr,
+ bool done,
+ bool address_p,
+ bool template_p,
+ bool template_arg_p,
+ tsubst_flags_t complain)
+{
+ gcc_assert (TYPE_P (qualifying_class));
+
+ if (error_operand_p (expr))
+ return error_mark_node;
+
+ if ((DECL_P (expr) || BASELINK_P (expr))
+ && !mark_used (expr, complain))
+ return error_mark_node;
+
+ if (template_p)
+ check_template_keyword (expr);
+
+ /* If EXPR occurs as the operand of '&', use special handling that
+ permits a pointer-to-member. */
+ if (address_p && done)
+ {
+ if (TREE_CODE (expr) == SCOPE_REF)
+ expr = TREE_OPERAND (expr, 1);
+ expr = build_offset_ref (qualifying_class, expr,
+ /*address_p=*/true, complain);
+ return expr;
+ }
+
+ /* No need to check access within an enum. */
+ if (TREE_CODE (qualifying_class) == ENUMERAL_TYPE)
+ return expr;
+
+ /* Within the scope of a class, turn references to non-static
+ members into expression of the form "this->...". */
+ if (template_arg_p)
+ /* But, within a template argument, we do not want make the
+ transformation, as there is no "this" pointer. */
+ ;
+ else if (TREE_CODE (expr) == FIELD_DECL)
+ {
+ push_deferring_access_checks (dk_no_check);
+ expr = finish_non_static_data_member (expr, NULL_TREE,
+ qualifying_class);
+ pop_deferring_access_checks ();
+ }
+ else if (BASELINK_P (expr) && !processing_template_decl)
+ {
+ /* See if any of the functions are non-static members. */
+ /* If so, the expression may be relative to 'this'. */
+ if (!shared_member_p (expr)
+ && current_class_ptr
+ && DERIVED_FROM_P (qualifying_class,
+ current_nonlambda_class_type ()))
+ expr = (build_class_member_access_expr
+ (maybe_dummy_object (qualifying_class, NULL),
+ expr,
+ BASELINK_ACCESS_BINFO (expr),
+ /*preserve_reference=*/false,
+ complain));
+ else if (done)
+ /* The expression is a qualified name whose address is not
+ being taken. */
+ expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false,
+ complain);
+ }
+ else if (BASELINK_P (expr))
+ ;
+ else
+ {
+ /* In a template, return a SCOPE_REF for most qualified-ids
+ so that we can check access at instantiation time. But if
+ we're looking at a member of the current instantiation, we
+ know we have access and building up the SCOPE_REF confuses
+ non-type template argument handling. */
+ if (processing_template_decl
+ && !currently_open_class (qualifying_class))
+ expr = build_qualified_name (TREE_TYPE (expr),
+ qualifying_class, expr,
+ template_p);
+
+ expr = convert_from_reference (expr);
+ }
+
+ return expr;
+}
+
+/* Begin a statement-expression. The value returned must be passed to
+ finish_stmt_expr. */
+
+tree
+begin_stmt_expr (void)
+{
+ return push_stmt_list ();
+}
+
+/* Process the final expression of a statement expression. EXPR can be
+ NULL, if the final expression is empty. Return a STATEMENT_LIST
+ containing all the statements in the statement-expression, or
+ ERROR_MARK_NODE if there was an error. */
+
+tree
+finish_stmt_expr_expr (tree expr, tree stmt_expr)
+{
+ if (error_operand_p (expr))
+ {
+ /* The type of the statement-expression is the type of the last
+ expression. */
+ TREE_TYPE (stmt_expr) = error_mark_node;
+ return error_mark_node;
+ }
+
+ /* If the last statement does not have "void" type, then the value
+ of the last statement is the value of the entire expression. */
+ if (expr)
+ {
+ tree type = TREE_TYPE (expr);
+
+ if (processing_template_decl)
+ {
+ expr = build_stmt (input_location, EXPR_STMT, expr);
+ expr = add_stmt (expr);
+ /* Mark the last statement so that we can recognize it as such at
+ template-instantiation time. */
+ EXPR_STMT_STMT_EXPR_RESULT (expr) = 1;
+ }
+ else if (VOID_TYPE_P (type))
+ {
+ /* Just treat this like an ordinary statement. */
+ expr = finish_expr_stmt (expr);
+ }
+ else
+ {
+ /* It actually has a value we need to deal with. First, force it
+ to be an rvalue so that we won't need to build up a copy
+ constructor call later when we try to assign it to something. */
+ expr = force_rvalue (expr, tf_warning_or_error);
+ if (error_operand_p (expr))
+ return error_mark_node;
+
+ /* Update for array-to-pointer decay. */
+ type = TREE_TYPE (expr);
+
+ /* Wrap it in a CLEANUP_POINT_EXPR and add it to the list like a
+ normal statement, but don't convert to void or actually add
+ the EXPR_STMT. */
+ if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
+ expr = maybe_cleanup_point_expr (expr);
+ add_stmt (expr);
+ }
+
+ /* The type of the statement-expression is the type of the last
+ expression. */
+ TREE_TYPE (stmt_expr) = type;
+ }
+
+ return stmt_expr;
+}
+
+/* Finish a statement-expression. EXPR should be the value returned
+ by the previous begin_stmt_expr. Returns an expression
+ representing the statement-expression. */
+
+tree
+finish_stmt_expr (tree stmt_expr, bool has_no_scope)
+{
+ tree type;
+ tree result;
+
+ if (error_operand_p (stmt_expr))
+ {
+ pop_stmt_list (stmt_expr);
+ return error_mark_node;
+ }
+
+ gcc_assert (TREE_CODE (stmt_expr) == STATEMENT_LIST);
+
+ type = TREE_TYPE (stmt_expr);
+ result = pop_stmt_list (stmt_expr);
+ TREE_TYPE (result) = type;
+
+ if (processing_template_decl)
+ {
+ result = build_min (STMT_EXPR, type, result);
+ TREE_SIDE_EFFECTS (result) = 1;
+ STMT_EXPR_NO_SCOPE (result) = has_no_scope;
+ }
+ else if (CLASS_TYPE_P (type))
+ {
+ /* Wrap the statement-expression in a TARGET_EXPR so that the
+ temporary object created by the final expression is destroyed at
+ the end of the full-expression containing the
+ statement-expression. */
+ result = force_target_expr (type, result, tf_warning_or_error);
+ }
+
+ return result;
+}
+
+/* Returns the expression which provides the value of STMT_EXPR. */
+
+tree
+stmt_expr_value_expr (tree stmt_expr)
+{
+ tree t = STMT_EXPR_STMT (stmt_expr);
+
+ if (TREE_CODE (t) == BIND_EXPR)
+ t = BIND_EXPR_BODY (t);
+
+ if (TREE_CODE (t) == STATEMENT_LIST && STATEMENT_LIST_TAIL (t))
+ t = STATEMENT_LIST_TAIL (t)->stmt;
+
+ if (TREE_CODE (t) == EXPR_STMT)
+ t = EXPR_STMT_EXPR (t);
+
+ return t;
+}
+
+/* Return TRUE iff EXPR_STMT is an empty list of
+ expression statements. */
+
+bool
+empty_expr_stmt_p (tree expr_stmt)
+{
+ tree body = NULL_TREE;
+
+ if (expr_stmt == void_zero_node)
+ return true;
+
+ if (expr_stmt)
+ {
+ if (TREE_CODE (expr_stmt) == EXPR_STMT)
+ body = EXPR_STMT_EXPR (expr_stmt);
+ else if (TREE_CODE (expr_stmt) == STATEMENT_LIST)
+ body = expr_stmt;
+ }
+
+ if (body)
+ {
+ if (TREE_CODE (body) == STATEMENT_LIST)
+ return tsi_end_p (tsi_start (body));
+ else
+ return empty_expr_stmt_p (body);
+ }
+ return false;
+}
+
+/* Perform Koenig lookup. FN is the postfix-expression representing
+ the function (or functions) to call; ARGS are the arguments to the
+ call. Returns the functions to be considered by overload resolution. */
+
+tree
+perform_koenig_lookup (tree fn, vec<tree, va_gc> *args,
+ tsubst_flags_t complain)
+{
+ tree identifier = NULL_TREE;
+ tree functions = NULL_TREE;
+ tree tmpl_args = NULL_TREE;
+ bool template_id = false;
+
+ if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+ {
+ /* Use a separate flag to handle null args. */
+ template_id = true;
+ tmpl_args = TREE_OPERAND (fn, 1);
+ fn = TREE_OPERAND (fn, 0);
+ }
+
+ /* Find the name of the overloaded function. */
+ if (identifier_p (fn))
+ identifier = fn;
+ else if (is_overloaded_fn (fn))
+ {
+ functions = fn;
+ identifier = DECL_NAME (get_first_fn (functions));
+ }
+ else if (DECL_P (fn))
+ {
+ functions = fn;
+ identifier = DECL_NAME (fn);
+ }
+
+ /* A call to a namespace-scope function using an unqualified name.
+
+ Do Koenig lookup -- unless any of the arguments are
+ type-dependent. */
+ if (!any_type_dependent_arguments_p (args)
+ && !any_dependent_template_arguments_p (tmpl_args))
+ {
+ fn = lookup_arg_dependent (identifier, functions, args);
+ if (!fn)
+ {
+ /* The unqualified name could not be resolved. */
+ if (complain)
+ fn = unqualified_fn_lookup_error (identifier);
+ else
+ fn = identifier;
+ }
+ }
+
+ if (fn && template_id)
+ fn = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fn, tmpl_args);
+
+ return fn;
+}
+
+/* Generate an expression for `FN (ARGS)'. This may change the
+ contents of ARGS.
+
+ If DISALLOW_VIRTUAL is true, the call to FN will be not generated
+ as a virtual call, even if FN is virtual. (This flag is set when
+ encountering an expression where the function name is explicitly
+ qualified. For example a call to `X::f' never generates a virtual
+ call.)
+
+ Returns code for the call. */
+
+tree
+finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
+ bool koenig_p, tsubst_flags_t complain)
+{
+ tree result;
+ tree orig_fn;
+ vec<tree, va_gc> *orig_args = NULL;
+
+ if (fn == error_mark_node)
+ return error_mark_node;
+
+ gcc_assert (!TYPE_P (fn));
+
+ orig_fn = fn;
+
+ if (processing_template_decl)
+ {
+ /* If the call expression is dependent, build a CALL_EXPR node
+ with no type; type_dependent_expression_p recognizes
+ expressions with no type as being dependent. */
+ if (type_dependent_expression_p (fn)
+ || any_type_dependent_arguments_p (*args)
+ /* For a non-static member function that doesn't have an
+ explicit object argument, we need to specifically
+ test the type dependency of the "this" pointer because it
+ is not included in *ARGS even though it is considered to
+ be part of the list of arguments. Note that this is
+ related to CWG issues 515 and 1005. */
+ || (TREE_CODE (fn) != COMPONENT_REF
+ && non_static_member_function_p (fn)
+ && current_class_ref
+ && type_dependent_expression_p (current_class_ref)))
+ {
+ result = build_nt_call_vec (fn, *args);
+ SET_EXPR_LOCATION (result, EXPR_LOC_OR_LOC (fn, input_location));
+ KOENIG_LOOKUP_P (result) = koenig_p;
+ if (cfun)
+ {
+ do
+ {
+ tree fndecl = OVL_CURRENT (fn);
+ if (TREE_CODE (fndecl) != FUNCTION_DECL
+ || !TREE_THIS_VOLATILE (fndecl))
+ break;
+ fn = OVL_NEXT (fn);
+ }
+ while (fn);
+ if (!fn)
+ current_function_returns_abnormally = 1;
+ }
+ return result;
+ }
+ orig_args = make_tree_vector_copy (*args);
+ if (!BASELINK_P (fn)
+ && TREE_CODE (fn) != PSEUDO_DTOR_EXPR
+ && TREE_TYPE (fn) != unknown_type_node)
+ fn = build_non_dependent_expr (fn);
+ make_args_non_dependent (*args);
+ }
+
+ if (TREE_CODE (fn) == COMPONENT_REF)
+ {
+ tree member = TREE_OPERAND (fn, 1);
+ if (BASELINK_P (member))
+ {
+ tree object = TREE_OPERAND (fn, 0);
+ return build_new_method_call (object, member,
+ args, NULL_TREE,
+ (disallow_virtual
+ ? LOOKUP_NORMAL | LOOKUP_NONVIRTUAL
+ : LOOKUP_NORMAL),
+ /*fn_p=*/NULL,
+ complain);
+ }
+ }
+
+ /* Per 13.3.1.1, '(&f)(...)' is the same as '(f)(...)'. */
+ if (TREE_CODE (fn) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (fn, 0)) == OVERLOAD)
+ fn = TREE_OPERAND (fn, 0);
+
+ if (is_overloaded_fn (fn))
+ fn = baselink_for_fns (fn);
+
+ result = NULL_TREE;
+ if (BASELINK_P (fn))
+ {
+ tree object;
+
+ /* A call to a member function. From [over.call.func]:
+
+ If the keyword this is in scope and refers to the class of
+ that member function, or a derived class thereof, then the
+ function call is transformed into a qualified function call
+ using (*this) as the postfix-expression to the left of the
+ . operator.... [Otherwise] a contrived object of type T
+ becomes the implied object argument.
+
+ In this situation:
+
+ struct A { void f(); };
+ struct B : public A {};
+ struct C : public A { void g() { B::f(); }};
+
+ "the class of that member function" refers to `A'. But 11.2
+ [class.access.base] says that we need to convert 'this' to B* as
+ part of the access, so we pass 'B' to maybe_dummy_object. */
+
+ object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
+ NULL);
+
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (object))
+ {
+ tree ret = build_nt_call_vec (orig_fn, orig_args);
+ release_tree_vector (orig_args);
+ return ret;
+ }
+ object = build_non_dependent_expr (object);
+ }
+
+ result = build_new_method_call (object, fn, args, NULL_TREE,
+ (disallow_virtual
+ ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
+ : LOOKUP_NORMAL),
+ /*fn_p=*/NULL,
+ complain);
+ }
+ else if (is_overloaded_fn (fn))
+ {
+ /* If the function is an overloaded builtin, resolve it. */
+ if (TREE_CODE (fn) == FUNCTION_DECL
+ && (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
+ || DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD))
+ result = resolve_overloaded_builtin (input_location, fn, *args);
+
+ if (!result)
+ {
+ if (warn_sizeof_pointer_memaccess
+ && !vec_safe_is_empty (*args)
+ && !processing_template_decl)
+ {
+ location_t sizeof_arg_loc[3];
+ tree sizeof_arg[3];
+ unsigned int i;
+ for (i = 0; i < 3; i++)
+ {
+ tree t;
+
+ sizeof_arg_loc[i] = UNKNOWN_LOCATION;
+ sizeof_arg[i] = NULL_TREE;
+ if (i >= (*args)->length ())
+ continue;
+ t = (**args)[i];
+ if (TREE_CODE (t) != SIZEOF_EXPR)
+ continue;
+ if (SIZEOF_EXPR_TYPE_P (t))
+ sizeof_arg[i] = TREE_TYPE (TREE_OPERAND (t, 0));
+ else
+ sizeof_arg[i] = TREE_OPERAND (t, 0);
+ sizeof_arg_loc[i] = EXPR_LOCATION (t);
+ }
+ sizeof_pointer_memaccess_warning
+ (sizeof_arg_loc, fn, *args,
+ sizeof_arg, same_type_ignoring_top_level_qualifiers_p);
+ }
+
+ /* A call to a namespace-scope function. */
+ result = build_new_function_call (fn, args, koenig_p, complain);
+ }
+ }
+ else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
+ {
+ if (!vec_safe_is_empty (*args))
+ error ("arguments to destructor are not allowed");
+ /* Mark the pseudo-destructor call as having side-effects so
+ that we do not issue warnings about its use. */
+ result = build1 (NOP_EXPR,
+ void_type_node,
+ TREE_OPERAND (fn, 0));
+ TREE_SIDE_EFFECTS (result) = 1;
+ }
+ else if (CLASS_TYPE_P (TREE_TYPE (fn)))
+ /* If the "function" is really an object of class type, it might
+ have an overloaded `operator ()'. */
+ result = build_op_call (fn, args, complain);
+
+ if (!result)
+ /* A call where the function is unknown. */
+ result = cp_build_function_call_vec (fn, args, complain);
+
+ if (processing_template_decl && result != error_mark_node)
+ {
+ if (INDIRECT_REF_P (result))
+ result = TREE_OPERAND (result, 0);
+ result = build_call_vec (TREE_TYPE (result), orig_fn, orig_args);
+ SET_EXPR_LOCATION (result, input_location);
+ KOENIG_LOOKUP_P (result) = koenig_p;
+ release_tree_vector (orig_args);
+ result = convert_from_reference (result);
+ }
+
+ if (koenig_p)
+ {
+ /* Free garbage OVERLOADs from arg-dependent lookup. */
+ tree next = NULL_TREE;
+ for (fn = orig_fn;
+ fn && TREE_CODE (fn) == OVERLOAD && OVL_ARG_DEPENDENT (fn);
+ fn = next)
+ {
+ if (processing_template_decl)
+ /* In a template, we'll re-use them at instantiation time. */
+ OVL_ARG_DEPENDENT (fn) = false;
+ else
+ {
+ next = OVL_CHAIN (fn);
+ ggc_free (fn);
+ }
+ }
+ }
+
+ return result;
+}
+
+/* Finish a call to a postfix increment or decrement or EXPR. (Which
+ is indicated by CODE, which should be POSTINCREMENT_EXPR or
+ POSTDECREMENT_EXPR.) */
+
+tree
+finish_increment_expr (tree expr, enum tree_code code)
+{
+ return build_x_unary_op (input_location, code, expr, tf_warning_or_error);
+}
+
+/* Finish a use of `this'. Returns an expression for `this'. */
+
+tree
+finish_this_expr (void)
+{
+ tree result;
+
+ if (current_class_ptr)
+ {
+ tree type = TREE_TYPE (current_class_ref);
+
+ /* In a lambda expression, 'this' refers to the captured 'this'. */
+ if (LAMBDA_TYPE_P (type))
+ result = lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (type));
+ else
+ result = current_class_ptr;
+ }
+ else if (current_function_decl
+ && DECL_STATIC_FUNCTION_P (current_function_decl))
+ {
+ error ("%<this%> is unavailable for static member functions");
+ result = error_mark_node;
+ }
+ else
+ {
+ if (current_function_decl)
+ error ("invalid use of %<this%> in non-member function");
+ else
+ error ("invalid use of %<this%> at top level");
+ result = error_mark_node;
+ }
+
+ /* The keyword 'this' is a prvalue expression. */
+ result = rvalue (result);
+
+ return result;
+}
+
+/* Finish a pseudo-destructor expression. If SCOPE is NULL, the
+ expression was of the form `OBJECT.~DESTRUCTOR' where DESTRUCTOR is
+ the TYPE for the type given. If SCOPE is non-NULL, the expression
+ was of the form `OBJECT.SCOPE::~DESTRUCTOR'. */
+
+tree
+finish_pseudo_destructor_expr (tree object, tree scope, tree destructor,
+ location_t loc)
+{
+ if (object == error_mark_node || destructor == error_mark_node)
+ return error_mark_node;
+
+ gcc_assert (TYPE_P (destructor));
+
+ if (!processing_template_decl)
+ {
+ if (scope == error_mark_node)
+ {
+ error_at (loc, "invalid qualifying scope in pseudo-destructor name");
+ return error_mark_node;
+ }
+ if (is_auto (destructor))
+ destructor = TREE_TYPE (object);
+ if (scope && TYPE_P (scope) && !check_dtor_name (scope, destructor))
+ {
+ error_at (loc,
+ "qualified type %qT does not match destructor name ~%qT",
+ scope, destructor);
+ return error_mark_node;
+ }
+
+
+ /* [expr.pseudo] says both:
+
+ The type designated by the pseudo-destructor-name shall be
+ the same as the object type.
+
+ and:
+
+ The cv-unqualified versions of the object type and of the
+ type designated by the pseudo-destructor-name shall be the
+ same type.
+
+ We implement the more generous second sentence, since that is
+ what most other compilers do. */
+ if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object),
+ destructor))
+ {
+ error_at (loc, "%qE is not of type %qT", object, destructor);
+ return error_mark_node;
+ }
+ }
+
+ return build3_loc (loc, PSEUDO_DTOR_EXPR, void_type_node, object,
+ scope, destructor);
+}
+
+/* Finish an expression of the form CODE EXPR. */
+
+tree
+finish_unary_op_expr (location_t loc, enum tree_code code, tree expr,
+ tsubst_flags_t complain)
+{
+ tree result = build_x_unary_op (loc, code, expr, complain);
+ if ((complain & tf_warning)
+ && TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (expr))
+ overflow_warning (input_location, result);
+
+ return result;
+}
+
+/* Finish a compound-literal expression. TYPE is the type to which
+ the CONSTRUCTOR in COMPOUND_LITERAL is being cast. */
+
+tree
+finish_compound_literal (tree type, tree compound_literal,
+ tsubst_flags_t complain)
+{
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ compound_literal
+ = finish_compound_literal (TREE_TYPE (type), compound_literal,
+ complain);
+ return cp_build_c_cast (type, compound_literal, complain);
+ }
+
+ if (!TYPE_OBJ_P (type))
+ {
+ if (complain & tf_error)
+ error ("compound literal of non-object type %qT", type);
+ return error_mark_node;
+ }
+
+ if (processing_template_decl)
+ {
+ TREE_TYPE (compound_literal) = type;
+ /* Mark the expression as a compound literal. */
+ TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
+ return compound_literal;
+ }
+
+ type = complete_type (type);
+
+ if (TYPE_NON_AGGREGATE_CLASS (type))
+ {
+ /* Trying to deal with a CONSTRUCTOR instead of a TREE_LIST
+ everywhere that deals with function arguments would be a pain, so
+ just wrap it in a TREE_LIST. The parser set a flag so we know
+ that it came from T{} rather than T({}). */
+ CONSTRUCTOR_IS_DIRECT_INIT (compound_literal) = 1;
+ compound_literal = build_tree_list (NULL_TREE, compound_literal);
+ return build_functional_cast (type, compound_literal, complain);
+ }
+
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && check_array_initializer (NULL_TREE, type, compound_literal))
+ return error_mark_node;
+ compound_literal = reshape_init (type, compound_literal, complain);
+ if (SCALAR_TYPE_P (type)
+ && !BRACE_ENCLOSED_INITIALIZER_P (compound_literal)
+ && (complain & tf_warning_or_error))
+ check_narrowing (type, compound_literal);
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_DOMAIN (type) == NULL_TREE)
+ {
+ cp_complete_array_type_or_error (&type, compound_literal,
+ false, complain);
+ if (type == error_mark_node)
+ return error_mark_node;
+ }
+ compound_literal = digest_init (type, compound_literal, complain);
+ if (TREE_CODE (compound_literal) == CONSTRUCTOR)
+ TREE_HAS_CONSTRUCTOR (compound_literal) = true;
+ /* Put static/constant array temporaries in static variables, but always
+ represent class temporaries with TARGET_EXPR so we elide copies. */
+ if ((!at_function_scope_p () || CP_TYPE_CONST_P (type))
+ && TREE_CODE (type) == ARRAY_TYPE
+ && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ && !cp_unevaluated_operand
+ && initializer_constant_valid_p (compound_literal, type))
+ {
+ tree decl = create_temporary_var (type);
+ DECL_INITIAL (decl) = compound_literal;
+ TREE_STATIC (decl) = 1;
+ if (literal_type_p (type) && CP_TYPE_CONST_NON_VOLATILE_P (type))
+ {
+ /* 5.19 says that a constant expression can include an
+ lvalue-rvalue conversion applied to "a glvalue of literal type
+ that refers to a non-volatile temporary object initialized
+ with a constant expression". Rather than try to communicate
+ that this VAR_DECL is a temporary, just mark it constexpr. */
+ DECL_DECLARED_CONSTEXPR_P (decl) = true;
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
+ TREE_CONSTANT (decl) = true;
+ }
+ cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
+ decl = pushdecl_top_level (decl);
+ DECL_NAME (decl) = make_anon_name ();
+ SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+ /* Make sure the destructor is callable. */
+ tree clean = cxx_maybe_build_cleanup (decl, complain);
+ if (clean == error_mark_node)
+ return error_mark_node;
+ return decl;
+ }
+ else
+ return get_target_expr_sfinae (compound_literal, complain);
+}
+
+/* Return the declaration for the function-name variable indicated by
+ ID. */
+
+tree
+finish_fname (tree id)
+{
+ tree decl;
+
+ decl = fname_decl (input_location, C_RID_CODE (id), id);
+ if (processing_template_decl && current_function_decl
+ && decl != error_mark_node)
+ decl = DECL_NAME (decl);
+ return decl;
+}
+
+/* Finish a translation unit. */
+
+void
+finish_translation_unit (void)
+{
+ /* In case there were missing closebraces,
+ get us back to the global binding level. */
+ pop_everything ();
+ while (current_namespace != global_namespace)
+ pop_namespace ();
+
+ /* Do file scope __FUNCTION__ et al. */
+ finish_fname_decls ();
+}
+
+/* Finish a template type parameter, specified as AGGR IDENTIFIER.
+ Returns the parameter. */
+
+tree
+finish_template_type_parm (tree aggr, tree identifier)
+{
+ if (aggr != class_type_node)
+ {
+ permerror (input_location, "template type parameters must use the keyword %<class%> or %<typename%>");
+ aggr = class_type_node;
+ }
+
+ return build_tree_list (aggr, identifier);
+}
+
+/* Finish a template template parameter, specified as AGGR IDENTIFIER.
+ Returns the parameter. */
+
+tree
+finish_template_template_parm (tree aggr, tree identifier)
+{
+ tree decl = build_decl (input_location,
+ TYPE_DECL, identifier, NULL_TREE);
+ tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE);
+ DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
+ DECL_TEMPLATE_RESULT (tmpl) = decl;
+ DECL_ARTIFICIAL (decl) = 1;
+ end_template_decl ();
+
+ gcc_assert (DECL_TEMPLATE_PARMS (tmpl));
+
+ check_default_tmpl_args (decl, DECL_TEMPLATE_PARMS (tmpl),
+ /*is_primary=*/true, /*is_partial=*/false,
+ /*is_friend=*/0);
+
+ return finish_template_type_parm (aggr, tmpl);
+}
+
+/* ARGUMENT is the default-argument value for a template template
+ parameter. If ARGUMENT is invalid, issue error messages and return
+ the ERROR_MARK_NODE. Otherwise, ARGUMENT itself is returned. */
+
+tree
+check_template_template_default_arg (tree argument)
+{
+ if (TREE_CODE (argument) != TEMPLATE_DECL
+ && TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM
+ && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
+ {
+ if (TREE_CODE (argument) == TYPE_DECL)
+ error ("invalid use of type %qT as a default value for a template "
+ "template-parameter", TREE_TYPE (argument));
+ else
+ error ("invalid default argument for a template template parameter");
+ return error_mark_node;
+ }
+
+ return argument;
+}
+
+/* Begin a class definition, as indicated by T. */
+
+tree
+begin_class_definition (tree t)
+{
+ if (error_operand_p (t) || error_operand_p (TYPE_MAIN_DECL (t)))
+ return error_mark_node;
+
+ if (processing_template_parmlist)
+ {
+ error ("definition of %q#T inside template parameter list", t);
+ return error_mark_node;
+ }
+
+ /* According to the C++ ABI, decimal classes defined in ISO/IEC TR 24733
+ are passed the same as decimal scalar types. */
+ if (TREE_CODE (t) == RECORD_TYPE
+ && !processing_template_decl)
+ {
+ tree ns = TYPE_CONTEXT (t);
+ if (ns && TREE_CODE (ns) == NAMESPACE_DECL
+ && DECL_CONTEXT (ns) == std_node
+ && DECL_NAME (ns)
+ && !strcmp (IDENTIFIER_POINTER (DECL_NAME (ns)), "decimal"))
+ {
+ const char *n = TYPE_NAME_STRING (t);
+ if ((strcmp (n, "decimal32") == 0)
+ || (strcmp (n, "decimal64") == 0)
+ || (strcmp (n, "decimal128") == 0))
+ TYPE_TRANSPARENT_AGGR (t) = 1;
+ }
+ }
+
+ /* A non-implicit typename comes from code like:
+
+ template <typename T> struct A {
+ template <typename U> struct A<T>::B ...
+
+ This is erroneous. */
+ else if (TREE_CODE (t) == TYPENAME_TYPE)
+ {
+ error ("invalid definition of qualified type %qT", t);
+ t = error_mark_node;
+ }
+
+ if (t == error_mark_node || ! MAYBE_CLASS_TYPE_P (t))
+ {
+ t = make_class_type (RECORD_TYPE);
+ pushtag (make_anon_name (), t, /*tag_scope=*/ts_current);
+ }
+
+ if (TYPE_BEING_DEFINED (t))
+ {
+ t = make_class_type (TREE_CODE (t));
+ pushtag (TYPE_IDENTIFIER (t), t, /*tag_scope=*/ts_current);
+ }
+ maybe_process_partial_specialization (t);
+ pushclass (t);
+ TYPE_BEING_DEFINED (t) = 1;
+
+ if (flag_pack_struct)
+ {
+ tree v;
+ TYPE_PACKED (t) = 1;
+ /* Even though the type is being defined for the first time
+ here, there might have been a forward declaration, so there
+ might be cv-qualified variants of T. */
+ for (v = TYPE_NEXT_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
+ TYPE_PACKED (v) = 1;
+ }
+ /* Reset the interface data, at the earliest possible
+ moment, as it might have been set via a class foo;
+ before. */
+ if (! TYPE_ANONYMOUS_P (t))
+ {
+ struct c_fileinfo *finfo = \
+ get_fileinfo (LOCATION_FILE (input_location));
+ CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
+ SET_CLASSTYPE_INTERFACE_UNKNOWN_X
+ (t, finfo->interface_unknown);
+ }
+ reset_specialization();
+
+ /* Make a declaration for this class in its own scope. */
+ build_self_reference ();
+
+ return t;
+}
+
+/* Finish the member declaration given by DECL. */
+
+void
+finish_member_declaration (tree decl)
+{
+ if (decl == error_mark_node || decl == NULL_TREE)
+ return;
+
+ if (decl == void_type_node)
+ /* The COMPONENT was a friend, not a member, and so there's
+ nothing for us to do. */
+ return;
+
+ /* We should see only one DECL at a time. */
+ gcc_assert (DECL_CHAIN (decl) == NULL_TREE);
+
+ /* Set up access control for DECL. */
+ TREE_PRIVATE (decl)
+ = (current_access_specifier == access_private_node);
+ TREE_PROTECTED (decl)
+ = (current_access_specifier == access_protected_node);
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ {
+ TREE_PRIVATE (DECL_TEMPLATE_RESULT (decl)) = TREE_PRIVATE (decl);
+ TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl);
+ }
+
+ /* Mark the DECL as a member of the current class, unless it's
+ a member of an enumeration. */
+ if (TREE_CODE (decl) != CONST_DECL)
+ DECL_CONTEXT (decl) = current_class_type;
+
+ /* Check for bare parameter packs in the member variable declaration. */
+ if (TREE_CODE (decl) == FIELD_DECL)
+ {
+ if (check_for_bare_parameter_packs (TREE_TYPE (decl)))
+ TREE_TYPE (decl) = error_mark_node;
+ if (check_for_bare_parameter_packs (DECL_ATTRIBUTES (decl)))
+ DECL_ATTRIBUTES (decl) = NULL_TREE;
+ }
+
+ /* [dcl.link]
+
+ A C language linkage is ignored for the names of class members
+ and the member function type of class member functions. */
+ if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c)
+ SET_DECL_LANGUAGE (decl, lang_cplusplus);
+
+ /* Put functions on the TYPE_METHODS list and everything else on the
+ TYPE_FIELDS list. Note that these are built up in reverse order.
+ We reverse them (to obtain declaration order) in finish_struct. */
+ if (DECL_DECLARES_FUNCTION_P (decl))
+ {
+ /* We also need to add this function to the
+ CLASSTYPE_METHOD_VEC. */
+ if (add_method (current_class_type, decl, NULL_TREE))
+ {
+ DECL_CHAIN (decl) = TYPE_METHODS (current_class_type);
+ TYPE_METHODS (current_class_type) = decl;
+
+ maybe_add_class_template_decl_list (current_class_type, decl,
+ /*friend_p=*/0);
+ }
+ }
+ /* Enter the DECL into the scope of the class, if the class
+ isn't a closure (whose fields are supposed to be unnamed). */
+ else if (CLASSTYPE_LAMBDA_EXPR (current_class_type)
+ || pushdecl_class_level (decl))
+ {
+ if (TREE_CODE (decl) == USING_DECL)
+ {
+ /* For now, ignore class-scope USING_DECLS, so that
+ debugging backends do not see them. */
+ DECL_IGNORED_P (decl) = 1;
+ }
+
+ /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields
+ go at the beginning. The reason is that lookup_field_1
+ searches the list in order, and we want a field name to
+ override a type name so that the "struct stat hack" will
+ work. In particular:
+
+ struct S { enum E { }; int E } s;
+ s.E = 3;
+
+ is valid. In addition, the FIELD_DECLs must be maintained in
+ declaration order so that class layout works as expected.
+ However, we don't need that order until class layout, so we
+ save a little time by putting FIELD_DECLs on in reverse order
+ here, and then reversing them in finish_struct_1. (We could
+ also keep a pointer to the correct insertion points in the
+ list.) */
+
+ if (TREE_CODE (decl) == TYPE_DECL)
+ TYPE_FIELDS (current_class_type)
+ = chainon (TYPE_FIELDS (current_class_type), decl);
+ else
+ {
+ DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type);
+ TYPE_FIELDS (current_class_type) = decl;
+ }
+
+ maybe_add_class_template_decl_list (current_class_type, decl,
+ /*friend_p=*/0);
+ }
+
+ if (pch_file)
+ note_decl_for_pch (decl);
+}
+
+/* DECL has been declared while we are building a PCH file. Perform
+ actions that we might normally undertake lazily, but which can be
+ performed now so that they do not have to be performed in
+ translation units which include the PCH file. */
+
+void
+note_decl_for_pch (tree decl)
+{
+ gcc_assert (pch_file);
+
+ /* There's a good chance that we'll have to mangle names at some
+ point, even if only for emission in debugging information. */
+ if (VAR_OR_FUNCTION_DECL_P (decl)
+ && !processing_template_decl)
+ mangle_decl (decl);
+}
+
+/* Finish processing a complete template declaration. The PARMS are
+ the template parameters. */
+
+void
+finish_template_decl (tree parms)
+{
+ if (parms)
+ end_template_decl ();
+ else
+ end_specialization ();
+}
+
+/* Finish processing a template-id (which names a type) of the form
+ NAME < ARGS >. Return the TYPE_DECL for the type named by the
+ template-id. If ENTERING_SCOPE is nonzero we are about to enter
+ the scope of template-id indicated. */
+
+tree
+finish_template_type (tree name, tree args, int entering_scope)
+{
+ tree type;
+
+ type = lookup_template_class (name, args,
+ NULL_TREE, NULL_TREE, entering_scope,
+ tf_warning_or_error | tf_user);
+ if (type == error_mark_node)
+ return type;
+ else if (CLASS_TYPE_P (type) && !alias_type_or_template_p (type))
+ return TYPE_STUB_DECL (type);
+ else
+ return TYPE_NAME (type);
+}
+
+/* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER.
+ Return a TREE_LIST containing the ACCESS_SPECIFIER and the
+ BASE_CLASS, or NULL_TREE if an error occurred. The
+ ACCESS_SPECIFIER is one of
+ access_{default,public,protected_private}_node. For a virtual base
+ we set TREE_TYPE. */
+
+tree
+finish_base_specifier (tree base, tree access, bool virtual_p)
+{
+ tree result;
+
+ if (base == error_mark_node)
+ {
+ error ("invalid base-class specification");
+ result = NULL_TREE;
+ }
+ else if (! MAYBE_CLASS_TYPE_P (base))
+ {
+ error ("%qT is not a class type", base);
+ result = NULL_TREE;
+ }
+ else
+ {
+ if (cp_type_quals (base) != 0)
+ {
+ /* DR 484: Can a base-specifier name a cv-qualified
+ class type? */
+ base = TYPE_MAIN_VARIANT (base);
+ }
+ result = build_tree_list (access, base);
+ if (virtual_p)
+ TREE_TYPE (result) = integer_type_node;
+ }
+
+ return result;
+}
+
+/* If FNS is a member function, a set of member functions, or a
+ template-id referring to one or more member functions, return a
+ BASELINK for FNS, incorporating the current access context.
+ Otherwise, return FNS unchanged. */
+
+tree
+baselink_for_fns (tree fns)
+{
+ tree scope;
+ tree cl;
+
+ if (BASELINK_P (fns)
+ || error_operand_p (fns))
+ return fns;
+
+ scope = ovl_scope (fns);
+ if (!CLASS_TYPE_P (scope))
+ return fns;
+
+ cl = currently_open_derived_class (scope);
+ if (!cl)
+ cl = scope;
+ cl = TYPE_BINFO (cl);
+ return build_baselink (cl, cl, fns, /*optype=*/NULL_TREE);
+}
+
+/* Returns true iff DECL is a variable from a function outside
+ the current one. */
+
+static bool
+outer_var_p (tree decl)
+{
+ return ((VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
+ && DECL_FUNCTION_SCOPE_P (decl)
+ && (DECL_CONTEXT (decl) != current_function_decl
+ || parsing_nsdmi ()));
+}
+
+/* As above, but also checks that DECL is automatic. */
+
+static bool
+outer_automatic_var_p (tree decl)
+{
+ return (outer_var_p (decl)
+ && !TREE_STATIC (decl));
+}
+
+/* ID_EXPRESSION is a representation of parsed, but unprocessed,
+ id-expression. (See cp_parser_id_expression for details.) SCOPE,
+ if non-NULL, is the type or namespace used to explicitly qualify
+ ID_EXPRESSION. DECL is the entity to which that name has been
+ resolved.
+
+ *CONSTANT_EXPRESSION_P is true if we are presently parsing a
+ constant-expression. In that case, *NON_CONSTANT_EXPRESSION_P will
+ be set to true if this expression isn't permitted in a
+ constant-expression, but it is otherwise not set by this function.
+ *ALLOW_NON_CONSTANT_EXPRESSION_P is true if we are parsing a
+ constant-expression, but a non-constant expression is also
+ permissible.
+
+ DONE is true if this expression is a complete postfix-expression;
+ it is false if this expression is followed by '->', '[', '(', etc.
+ ADDRESS_P is true iff this expression is the operand of '&'.
+ TEMPLATE_P is true iff the qualified-id was of the form
+ "A::template B". TEMPLATE_ARG_P is true iff this qualified name
+ appears as a template argument.
+
+ If an error occurs, and it is the kind of error that might cause
+ the parser to abort a tentative parse, *ERROR_MSG is filled in. It
+ is the caller's responsibility to issue the message. *ERROR_MSG
+ will be a string with static storage duration, so the caller need
+ not "free" it.
+
+ Return an expression for the entity, after issuing appropriate
+ diagnostics. This function is also responsible for transforming a
+ reference to a non-static member into a COMPONENT_REF that makes
+ the use of "this" explicit.
+
+ Upon return, *IDK will be filled in appropriately. */
+tree
+finish_id_expression (tree id_expression,
+ tree decl,
+ tree scope,
+ cp_id_kind *idk,
+ bool integral_constant_expression_p,
+ bool allow_non_integral_constant_expression_p,
+ bool *non_integral_constant_expression_p,
+ bool template_p,
+ bool done,
+ bool address_p,
+ bool template_arg_p,
+ const char **error_msg,
+ location_t location)
+{
+ decl = strip_using_decl (decl);
+
+ /* Initialize the output parameters. */
+ *idk = CP_ID_KIND_NONE;
+ *error_msg = NULL;
+
+ if (id_expression == error_mark_node)
+ return error_mark_node;
+ /* If we have a template-id, then no further lookup is
+ required. If the template-id was for a template-class, we
+ will sometimes have a TYPE_DECL at this point. */
+ else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
+ || TREE_CODE (decl) == TYPE_DECL)
+ ;
+ /* Look up the name. */
+ else
+ {
+ if (decl == error_mark_node)
+ {
+ /* Name lookup failed. */
+ if (scope
+ && (!TYPE_P (scope)
+ || (!dependent_type_p (scope)
+ && !(identifier_p (id_expression)
+ && IDENTIFIER_TYPENAME_P (id_expression)
+ && dependent_type_p (TREE_TYPE (id_expression))))))
+ {
+ /* If the qualifying type is non-dependent (and the name
+ does not name a conversion operator to a dependent
+ type), issue an error. */
+ qualified_name_lookup_error (scope, id_expression, decl, location);
+ return error_mark_node;
+ }
+ else if (!scope)
+ {
+ /* It may be resolved via Koenig lookup. */
+ *idk = CP_ID_KIND_UNQUALIFIED;
+ return id_expression;
+ }
+ else
+ decl = id_expression;
+ }
+ /* If DECL is a variable that would be out of scope under
+ ANSI/ISO rules, but in scope in the ARM, name lookup
+ will succeed. Issue a diagnostic here. */
+ else
+ decl = check_for_out_of_scope_variable (decl);
+
+ /* Remember that the name was used in the definition of
+ the current class so that we can check later to see if
+ the meaning would have been different after the class
+ was entirely defined. */
+ if (!scope && decl != error_mark_node && identifier_p (id_expression))
+ maybe_note_name_used_in_class (id_expression, decl);
+
+ /* Disallow uses of local variables from containing functions, except
+ within lambda-expressions. */
+ if (!outer_var_p (decl))
+ /* OK */;
+ else if (TREE_STATIC (decl)
+ /* It's not a use (3.2) if we're in an unevaluated context. */
+ || cp_unevaluated_operand)
+ {
+ if (processing_template_decl)
+ /* For a use of an outer static/unevaluated var, return the id
+ so that we'll look it up again in the instantiation. */
+ return id_expression;
+ }
+ else
+ {
+ tree context = DECL_CONTEXT (decl);
+ tree containing_function = current_function_decl;
+ tree lambda_stack = NULL_TREE;
+ tree lambda_expr = NULL_TREE;
+ tree initializer = convert_from_reference (decl);
+
+ /* Mark it as used now even if the use is ill-formed. */
+ mark_used (decl);
+
+ /* Core issue 696: "[At the July 2009 meeting] the CWG expressed
+ support for an approach in which a reference to a local
+ [constant] automatic variable in a nested class or lambda body
+ would enter the expression as an rvalue, which would reduce
+ the complexity of the problem"
+
+ FIXME update for final resolution of core issue 696. */
+ if (decl_constant_var_p (decl))
+ {
+ if (processing_template_decl)
+ /* In a template, the constant value may not be in a usable
+ form, so look it up again at instantiation time. */
+ return id_expression;
+ else
+ return integral_constant_value (decl);
+ }
+
+ if (parsing_nsdmi ())
+ containing_function = NULL_TREE;
+ /* If we are in a lambda function, we can move out until we hit
+ 1. the context,
+ 2. a non-lambda function, or
+ 3. a non-default capturing lambda function. */
+ else while (context != containing_function
+ && LAMBDA_FUNCTION_P (containing_function))
+ {
+ lambda_expr = CLASSTYPE_LAMBDA_EXPR
+ (DECL_CONTEXT (containing_function));
+
+ if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr)
+ == CPLD_NONE)
+ break;
+
+ lambda_stack = tree_cons (NULL_TREE,
+ lambda_expr,
+ lambda_stack);
+
+ containing_function
+ = decl_function_context (containing_function);
+ }
+
+ if (lambda_expr && TREE_CODE (decl) == VAR_DECL
+ && DECL_ANON_UNION_VAR_P (decl))
+ {
+ error ("cannot capture member %qD of anonymous union", decl);
+ return error_mark_node;
+ }
+ if (context == containing_function)
+ {
+ decl = add_default_capture (lambda_stack,
+ /*id=*/DECL_NAME (decl),
+ initializer);
+ }
+ else if (lambda_expr)
+ {
+ error ("%qD is not captured", decl);
+ return error_mark_node;
+ }
+ else
+ {
+ error (VAR_P (decl)
+ ? G_("use of local variable with automatic storage from containing function")
+ : G_("use of parameter from containing function"));
+ inform (input_location, "%q+#D declared here", decl);
+ return error_mark_node;
+ }
+ }
+
+ /* Also disallow uses of function parameters outside the function
+ body, except inside an unevaluated context (i.e. decltype). */
+ if (TREE_CODE (decl) == PARM_DECL
+ && DECL_CONTEXT (decl) == NULL_TREE
+ && !cp_unevaluated_operand)
+ {
+ *error_msg = "use of parameter outside function body";
+ return error_mark_node;
+ }
+ }
+
+ /* If we didn't find anything, or what we found was a type,
+ then this wasn't really an id-expression. */
+ if (TREE_CODE (decl) == TEMPLATE_DECL
+ && !DECL_FUNCTION_TEMPLATE_P (decl))
+ {
+ *error_msg = "missing template arguments";
+ return error_mark_node;
+ }
+ else if (TREE_CODE (decl) == TYPE_DECL
+ || TREE_CODE (decl) == NAMESPACE_DECL)
+ {
+ *error_msg = "expected primary-expression";
+ return error_mark_node;
+ }
+
+ /* If the name resolved to a template parameter, there is no
+ need to look it up again later. */
+ if ((TREE_CODE (decl) == CONST_DECL && DECL_TEMPLATE_PARM_P (decl))
+ || TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
+ {
+ tree r;
+
+ *idk = CP_ID_KIND_NONE;
+ if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
+ decl = TEMPLATE_PARM_DECL (decl);
+ r = convert_from_reference (DECL_INITIAL (decl));
+
+ if (integral_constant_expression_p
+ && !dependent_type_p (TREE_TYPE (decl))
+ && !(INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (r))))
+ {
+ if (!allow_non_integral_constant_expression_p)
+ error ("template parameter %qD of type %qT is not allowed in "
+ "an integral constant expression because it is not of "
+ "integral or enumeration type", decl, TREE_TYPE (decl));
+ *non_integral_constant_expression_p = true;
+ }
+ return r;
+ }
+ else
+ {
+ bool dependent_p;
+
+ /* If the declaration was explicitly qualified indicate
+ that. The semantics of `A::f(3)' are different than
+ `f(3)' if `f' is virtual. */
+ *idk = (scope
+ ? CP_ID_KIND_QUALIFIED
+ : (TREE_CODE (decl) == TEMPLATE_ID_EXPR
+ ? CP_ID_KIND_TEMPLATE_ID
+ : CP_ID_KIND_UNQUALIFIED));
+
+
+ /* [temp.dep.expr]
+
+ An id-expression is type-dependent if it contains an
+ identifier that was declared with a dependent type.
+
+ The standard is not very specific about an id-expression that
+ names a set of overloaded functions. What if some of them
+ have dependent types and some of them do not? Presumably,
+ such a name should be treated as a dependent name. */
+ /* Assume the name is not dependent. */
+ dependent_p = false;
+ if (!processing_template_decl)
+ /* No names are dependent outside a template. */
+ ;
+ else if (TREE_CODE (decl) == CONST_DECL)
+ /* We don't want to treat enumerators as dependent. */
+ ;
+ /* A template-id where the name of the template was not resolved
+ is definitely dependent. */
+ else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
+ && (identifier_p (TREE_OPERAND (decl, 0))))
+ dependent_p = true;
+ /* For anything except an overloaded function, just check its
+ type. */
+ else if (!is_overloaded_fn (decl))
+ dependent_p
+ = dependent_type_p (TREE_TYPE (decl));
+ /* For a set of overloaded functions, check each of the
+ functions. */
+ else
+ {
+ tree fns = decl;
+
+ if (BASELINK_P (fns))
+ fns = BASELINK_FUNCTIONS (fns);
+
+ /* For a template-id, check to see if the template
+ arguments are dependent. */
+ if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
+ {
+ tree args = TREE_OPERAND (fns, 1);
+ dependent_p = any_dependent_template_arguments_p (args);
+ /* The functions are those referred to by the
+ template-id. */
+ fns = TREE_OPERAND (fns, 0);
+ }
+
+ /* If there are no dependent template arguments, go through
+ the overloaded functions. */
+ while (fns && !dependent_p)
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ /* Member functions of dependent classes are
+ dependent. */
+ if (TREE_CODE (fn) == FUNCTION_DECL
+ && type_dependent_expression_p (fn))
+ dependent_p = true;
+ else if (TREE_CODE (fn) == TEMPLATE_DECL
+ && dependent_template_p (fn))
+ dependent_p = true;
+
+ fns = OVL_NEXT (fns);
+ }
+ }
+
+ /* If the name was dependent on a template parameter, we will
+ resolve the name at instantiation time. */
+ if (dependent_p)
+ {
+ /* Create a SCOPE_REF for qualified names, if the scope is
+ dependent. */
+ if (scope)
+ {
+ if (TYPE_P (scope))
+ {
+ if (address_p && done)
+ decl = finish_qualified_id_expr (scope, decl,
+ done, address_p,
+ template_p,
+ template_arg_p,
+ tf_warning_or_error);
+ else
+ {
+ tree type = NULL_TREE;
+ if (DECL_P (decl) && !dependent_scope_p (scope))
+ type = TREE_TYPE (decl);
+ decl = build_qualified_name (type,
+ scope,
+ id_expression,
+ template_p);
+ }
+ }
+ if (TREE_TYPE (decl))
+ decl = convert_from_reference (decl);
+ return decl;
+ }
+ /* A TEMPLATE_ID already contains all the information we
+ need. */
+ if (TREE_CODE (id_expression) == TEMPLATE_ID_EXPR)
+ return id_expression;
+ *idk = CP_ID_KIND_UNQUALIFIED_DEPENDENT;
+ /* If we found a variable, then name lookup during the
+ instantiation will always resolve to the same VAR_DECL
+ (or an instantiation thereof). */
+ if (VAR_P (decl)
+ || TREE_CODE (decl) == PARM_DECL)
+ {
+ mark_used (decl);
+ return convert_from_reference (decl);
+ }
+ /* The same is true for FIELD_DECL, but we also need to
+ make sure that the syntax is correct. */
+ else if (TREE_CODE (decl) == FIELD_DECL)
+ {
+ /* Since SCOPE is NULL here, this is an unqualified name.
+ Access checking has been performed during name lookup
+ already. Turn off checking to avoid duplicate errors. */
+ push_deferring_access_checks (dk_no_check);
+ decl = finish_non_static_data_member
+ (decl, NULL_TREE,
+ /*qualifying_scope=*/NULL_TREE);
+ pop_deferring_access_checks ();
+ return decl;
+ }
+ return id_expression;
+ }
+
+ if (TREE_CODE (decl) == NAMESPACE_DECL)
+ {
+ error ("use of namespace %qD as expression", decl);
+ return error_mark_node;
+ }
+ else if (DECL_CLASS_TEMPLATE_P (decl))
+ {
+ error ("use of class template %qT as expression", decl);
+ return error_mark_node;
+ }
+ else if (TREE_CODE (decl) == TREE_LIST)
+ {
+ /* Ambiguous reference to base members. */
+ error ("request for member %qD is ambiguous in "
+ "multiple inheritance lattice", id_expression);
+ print_candidates (decl);
+ return error_mark_node;
+ }
+
+ /* Mark variable-like entities as used. Functions are similarly
+ marked either below or after overload resolution. */
+ if ((VAR_P (decl)
+ || TREE_CODE (decl) == PARM_DECL
+ || TREE_CODE (decl) == CONST_DECL
+ || TREE_CODE (decl) == RESULT_DECL)
+ && !mark_used (decl))
+ return error_mark_node;
+
+ /* Only certain kinds of names are allowed in constant
+ expression. Template parameters have already
+ been handled above. */
+ if (! error_operand_p (decl)
+ && integral_constant_expression_p
+ && ! decl_constant_var_p (decl)
+ && TREE_CODE (decl) != CONST_DECL
+ && ! builtin_valid_in_constant_expr_p (decl))
+ {
+ if (!allow_non_integral_constant_expression_p)
+ {
+ error ("%qD cannot appear in a constant-expression", decl);
+ return error_mark_node;
+ }
+ *non_integral_constant_expression_p = true;
+ }
+
+ tree wrap;
+ if (VAR_P (decl)
+ && !cp_unevaluated_operand
+ && DECL_THREAD_LOCAL_P (decl)
+ && (wrap = get_tls_wrapper_fn (decl)))
+ {
+ /* Replace an evaluated use of the thread_local variable with
+ a call to its wrapper. */
+ decl = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
+ }
+ else if (scope)
+ {
+ decl = (adjust_result_of_qualified_name_lookup
+ (decl, scope, current_nonlambda_class_type()));
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ mark_used (decl);
+
+ if (TYPE_P (scope))
+ decl = finish_qualified_id_expr (scope,
+ decl,
+ done,
+ address_p,
+ template_p,
+ template_arg_p,
+ tf_warning_or_error);
+ else
+ decl = convert_from_reference (decl);
+ }
+ else if (TREE_CODE (decl) == FIELD_DECL)
+ {
+ /* Since SCOPE is NULL here, this is an unqualified name.
+ Access checking has been performed during name lookup
+ already. Turn off checking to avoid duplicate errors. */
+ push_deferring_access_checks (dk_no_check);
+ decl = finish_non_static_data_member (decl, NULL_TREE,
+ /*qualifying_scope=*/NULL_TREE);
+ pop_deferring_access_checks ();
+ }
+ else if (is_overloaded_fn (decl))
+ {
+ tree first_fn;
+
+ first_fn = get_first_fn (decl);
+ if (TREE_CODE (first_fn) == TEMPLATE_DECL)
+ first_fn = DECL_TEMPLATE_RESULT (first_fn);
+
+ if (!really_overloaded_fn (decl)
+ && !mark_used (first_fn))
+ return error_mark_node;
+
+ if (!template_arg_p
+ && TREE_CODE (first_fn) == FUNCTION_DECL
+ && DECL_FUNCTION_MEMBER_P (first_fn)
+ && !shared_member_p (decl))
+ {
+ /* A set of member functions. */
+ decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
+ return finish_class_member_access_expr (decl, id_expression,
+ /*template_p=*/false,
+ tf_warning_or_error);
+ }
+
+ decl = baselink_for_fns (decl);
+ }
+ else
+ {
+ if (DECL_P (decl) && DECL_NONLOCAL (decl)
+ && DECL_CLASS_SCOPE_P (decl))
+ {
+ tree context = context_for_name_lookup (decl);
+ if (context != current_class_type)
+ {
+ tree path = currently_open_derived_class (context);
+ perform_or_defer_access_check (TYPE_BINFO (path),
+ decl, decl,
+ tf_warning_or_error);
+ }
+ }
+
+ decl = convert_from_reference (decl);
+ }
+ }
+
+ /* Handle references (c++/56130). */
+ tree t = REFERENCE_REF_P (decl) ? TREE_OPERAND (decl, 0) : decl;
+ if (TREE_DEPRECATED (t))
+ warn_deprecated_use (t, NULL_TREE);
+
+ return decl;
+}
+
+/* Implement the __typeof keyword: Return the type of EXPR, suitable for
+ use as a type-specifier. */
+
+tree
+finish_typeof (tree expr)
+{
+ tree type;
+
+ if (type_dependent_expression_p (expr))
+ {
+ type = cxx_make_type (TYPEOF_TYPE);
+ TYPEOF_TYPE_EXPR (type) = expr;
+ SET_TYPE_STRUCTURAL_EQUALITY (type);
+
+ return type;
+ }
+
+ expr = mark_type_use (expr);
+
+ type = unlowered_expr_type (expr);
+
+ if (!type || type == unknown_type_node)
+ {
+ error ("type of %qE is unknown", expr);
+ return error_mark_node;
+ }
+
+ return type;
+}
+
+/* Implement the __underlying_type keyword: Return the underlying
+ type of TYPE, suitable for use as a type-specifier. */
+
+tree
+finish_underlying_type (tree type)
+{
+ tree underlying_type;
+
+ if (processing_template_decl)
+ {
+ underlying_type = cxx_make_type (UNDERLYING_TYPE);
+ UNDERLYING_TYPE_TYPE (underlying_type) = type;
+ SET_TYPE_STRUCTURAL_EQUALITY (underlying_type);
+
+ return underlying_type;
+ }
+
+ complete_type (type);
+
+ if (TREE_CODE (type) != ENUMERAL_TYPE)
+ {
+ error ("%qT is not an enumeration type", type);
+ return error_mark_node;
+ }
+
+ underlying_type = ENUM_UNDERLYING_TYPE (type);
+
+ /* Fixup necessary in this case because ENUM_UNDERLYING_TYPE
+ includes TYPE_MIN_VALUE and TYPE_MAX_VALUE information.
+ See finish_enum_value_list for details. */
+ if (!ENUM_FIXED_UNDERLYING_TYPE_P (type))
+ underlying_type
+ = c_common_type_for_mode (TYPE_MODE (underlying_type),
+ TYPE_UNSIGNED (underlying_type));
+
+ return underlying_type;
+}
+
+/* Implement the __direct_bases keyword: Return the direct base classes
+ of type */
+
+tree
+calculate_direct_bases (tree type)
+{
+ vec<tree, va_gc> *vector = make_tree_vector();
+ tree bases_vec = NULL_TREE;
+ vec<tree, va_gc> *base_binfos;
+ tree binfo;
+ unsigned i;
+
+ complete_type (type);
+
+ if (!NON_UNION_CLASS_TYPE_P (type))
+ return make_tree_vec (0);
+
+ base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
+
+ /* Virtual bases are initialized first */
+ for (i = 0; base_binfos->iterate (i, &binfo); i++)
+ {
+ if (BINFO_VIRTUAL_P (binfo))
+ {
+ vec_safe_push (vector, binfo);
+ }
+ }
+
+ /* Now non-virtuals */
+ for (i = 0; base_binfos->iterate (i, &binfo); i++)
+ {
+ if (!BINFO_VIRTUAL_P (binfo))
+ {
+ vec_safe_push (vector, binfo);
+ }
+ }
+
+
+ bases_vec = make_tree_vec (vector->length ());
+
+ for (i = 0; i < vector->length (); ++i)
+ {
+ TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]);
+ }
+ return bases_vec;
+}
+
+/* Implement the __bases keyword: Return the base classes
+ of type */
+
+/* Find morally non-virtual base classes by walking binfo hierarchy */
+/* Virtual base classes are handled separately in finish_bases */
+
+static tree
+dfs_calculate_bases_pre (tree binfo, void * /*data_*/)
+{
+ /* Don't walk bases of virtual bases */
+ return BINFO_VIRTUAL_P (binfo) ? dfs_skip_bases : NULL_TREE;
+}
+
+static tree
+dfs_calculate_bases_post (tree binfo, void *data_)
+{
+ vec<tree, va_gc> **data = ((vec<tree, va_gc> **) data_);
+ if (!BINFO_VIRTUAL_P (binfo))
+ {
+ vec_safe_push (*data, BINFO_TYPE (binfo));
+ }
+ return NULL_TREE;
+}
+
+/* Calculates the morally non-virtual base classes of a class */
+static vec<tree, va_gc> *
+calculate_bases_helper (tree type)
+{
+ vec<tree, va_gc> *vector = make_tree_vector();
+
+ /* Now add non-virtual base classes in order of construction */
+ dfs_walk_all (TYPE_BINFO (type),
+ dfs_calculate_bases_pre, dfs_calculate_bases_post, &vector);
+ return vector;
+}
+
+tree
+calculate_bases (tree type)
+{
+ vec<tree, va_gc> *vector = make_tree_vector();
+ tree bases_vec = NULL_TREE;
+ unsigned i;
+ vec<tree, va_gc> *vbases;
+ vec<tree, va_gc> *nonvbases;
+ tree binfo;
+
+ complete_type (type);
+
+ if (!NON_UNION_CLASS_TYPE_P (type))
+ return make_tree_vec (0);
+
+ /* First go through virtual base classes */
+ for (vbases = CLASSTYPE_VBASECLASSES (type), i = 0;
+ vec_safe_iterate (vbases, i, &binfo); i++)
+ {
+ vec<tree, va_gc> *vbase_bases;
+ vbase_bases = calculate_bases_helper (BINFO_TYPE (binfo));
+ vec_safe_splice (vector, vbase_bases);
+ release_tree_vector (vbase_bases);
+ }
+
+ /* Now for the non-virtual bases */
+ nonvbases = calculate_bases_helper (type);
+ vec_safe_splice (vector, nonvbases);
+ release_tree_vector (nonvbases);
+
+ /* Last element is entire class, so don't copy */
+ bases_vec = make_tree_vec (vector->length () - 1);
+
+ for (i = 0; i < vector->length () - 1; ++i)
+ {
+ TREE_VEC_ELT (bases_vec, i) = (*vector)[i];
+ }
+ release_tree_vector (vector);
+ return bases_vec;
+}
+
+tree
+finish_bases (tree type, bool direct)
+{
+ tree bases = NULL_TREE;
+
+ if (!processing_template_decl)
+ {
+ /* Parameter packs can only be used in templates */
+ error ("Parameter pack __bases only valid in template declaration");
+ return error_mark_node;
+ }
+
+ bases = cxx_make_type (BASES);
+ BASES_TYPE (bases) = type;
+ BASES_DIRECT (bases) = direct;
+ SET_TYPE_STRUCTURAL_EQUALITY (bases);
+
+ return bases;
+}
+
+/* Perform C++-specific checks for __builtin_offsetof before calling
+ fold_offsetof. */
+
+tree
+finish_offsetof (tree expr)
+{
+ if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
+ {
+ error ("cannot apply %<offsetof%> to destructor %<~%T%>",
+ TREE_OPERAND (expr, 2));
+ return error_mark_node;
+ }
+ if (TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE
+ || TREE_TYPE (expr) == unknown_type_node)
+ {
+ if (INDIRECT_REF_P (expr))
+ error ("second operand of %<offsetof%> is neither a single "
+ "identifier nor a sequence of member accesses and "
+ "array references");
+ else
+ {
+ if (TREE_CODE (expr) == COMPONENT_REF
+ || TREE_CODE (expr) == COMPOUND_EXPR)
+ expr = TREE_OPERAND (expr, 1);
+ error ("cannot apply %<offsetof%> to member function %qD", expr);
+ }
+ return error_mark_node;
+ }
+ if (REFERENCE_REF_P (expr))
+ expr = TREE_OPERAND (expr, 0);
+ if (TREE_CODE (expr) == COMPONENT_REF)
+ {
+ tree object = TREE_OPERAND (expr, 0);
+ if (!complete_type_or_else (TREE_TYPE (object), object))
+ return error_mark_node;
+ }
+ return fold_offsetof (expr);
+}
+
+/* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This
+ function is broken out from the above for the benefit of the tree-ssa
+ project. */
+
+void
+simplify_aggr_init_expr (tree *tp)
+{
+ tree aggr_init_expr = *tp;
+
+ /* Form an appropriate CALL_EXPR. */
+ tree fn = AGGR_INIT_EXPR_FN (aggr_init_expr);
+ tree slot = AGGR_INIT_EXPR_SLOT (aggr_init_expr);
+ tree type = TREE_TYPE (slot);
+
+ tree call_expr;
+ enum style_t { ctor, arg, pcc } style;
+
+ if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
+ style = ctor;
+#ifdef PCC_STATIC_STRUCT_RETURN
+ else if (1)
+ style = pcc;
+#endif
+ else
+ {
+ gcc_assert (TREE_ADDRESSABLE (type));
+ style = arg;
+ }
+
+ call_expr = build_call_array_loc (input_location,
+ TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
+ fn,
+ aggr_init_expr_nargs (aggr_init_expr),
+ AGGR_INIT_EXPR_ARGP (aggr_init_expr));
+ TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr);
+
+ if (style == ctor)
+ {
+ /* Replace the first argument to the ctor with the address of the
+ slot. */
+ cxx_mark_addressable (slot);
+ CALL_EXPR_ARG (call_expr, 0) =
+ build1 (ADDR_EXPR, build_pointer_type (type), slot);
+ }
+ else if (style == arg)
+ {
+ /* Just mark it addressable here, and leave the rest to
+ expand_call{,_inline}. */
+ cxx_mark_addressable (slot);
+ CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true;
+ call_expr = build2 (INIT_EXPR, TREE_TYPE (call_expr), slot, call_expr);
+ }
+ else if (style == pcc)
+ {
+ /* If we're using the non-reentrant PCC calling convention, then we
+ need to copy the returned value out of the static buffer into the
+ SLOT. */
+ push_deferring_access_checks (dk_no_check);
+ call_expr = build_aggr_init (slot, call_expr,
+ DIRECT_BIND | LOOKUP_ONLYCONVERTING,
+ tf_warning_or_error);
+ pop_deferring_access_checks ();
+ call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot);
+ }
+
+ if (AGGR_INIT_ZERO_FIRST (aggr_init_expr))
+ {
+ tree init = build_zero_init (type, NULL_TREE,
+ /*static_storage_p=*/false);
+ init = build2 (INIT_EXPR, void_type_node, slot, init);
+ call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (call_expr),
+ init, call_expr);
+ }
+
+ *tp = call_expr;
+}
+
+/* Emit all thunks to FN that should be emitted when FN is emitted. */
+
+void
+emit_associated_thunks (tree fn)
+{
+ /* When we use vcall offsets, we emit thunks with the virtual
+ functions to which they thunk. The whole point of vcall offsets
+ is so that you can know statically the entire set of thunks that
+ will ever be needed for a given virtual function, thereby
+ enabling you to output all the thunks with the function itself. */
+ if (DECL_VIRTUAL_P (fn)
+ /* Do not emit thunks for extern template instantiations. */
+ && ! DECL_REALLY_EXTERN (fn))
+ {
+ tree thunk;
+
+ for (thunk = DECL_THUNKS (fn); thunk; thunk = DECL_CHAIN (thunk))
+ {
+ if (!THUNK_ALIAS (thunk))
+ {
+ use_thunk (thunk, /*emit_p=*/1);
+ if (DECL_RESULT_THUNK_P (thunk))
+ {
+ tree probe;
+
+ for (probe = DECL_THUNKS (thunk);
+ probe; probe = DECL_CHAIN (probe))
+ use_thunk (probe, /*emit_p=*/1);
+ }
+ }
+ else
+ gcc_assert (!DECL_THUNKS (thunk));
+ }
+ }
+}
+
+/* Returns true iff FUN is an instantiation of a constexpr function
+ template. */
+
+static inline bool
+is_instantiation_of_constexpr (tree fun)
+{
+ return (DECL_TEMPLOID_INSTANTIATION (fun)
+ && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun)));
+}
+
+/* Generate RTL for FN. */
+
+bool
+expand_or_defer_fn_1 (tree fn)
+{
+ /* When the parser calls us after finishing the body of a template
+ function, we don't really want to expand the body. */
+ if (processing_template_decl)
+ {
+ /* Normally, collection only occurs in rest_of_compilation. So,
+ if we don't collect here, we never collect junk generated
+ during the processing of templates until we hit a
+ non-template function. It's not safe to do this inside a
+ nested class, though, as the parser may have local state that
+ is not a GC root. */
+ if (!function_depth)
+ ggc_collect ();
+ return false;
+ }
+
+ gcc_assert (DECL_SAVED_TREE (fn));
+
+ /* We make a decision about linkage for these functions at the end
+ of the compilation. Until that point, we do not want the back
+ end to output them -- but we do want it to see the bodies of
+ these functions so that it can inline them as appropriate. */
+ if (DECL_DECLARED_INLINE_P (fn) || DECL_IMPLICIT_INSTANTIATION (fn))
+ {
+ if (DECL_INTERFACE_KNOWN (fn))
+ /* We've already made a decision as to how this function will
+ be handled. */;
+ else if (!at_eof)
+ tentative_decl_linkage (fn);
+ else
+ import_export_decl (fn);
+
+ /* If the user wants us to keep all inline functions, then mark
+ this function as needed so that finish_file will make sure to
+ output it later. Similarly, all dllexport'd functions must
+ be emitted; there may be callers in other DLLs. */
+ if ((flag_keep_inline_functions
+ && DECL_DECLARED_INLINE_P (fn)
+ && !DECL_REALLY_EXTERN (fn))
+ || (flag_keep_inline_dllexport
+ && lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn))))
+ {
+ mark_needed (fn);
+ DECL_EXTERNAL (fn) = 0;
+ }
+ }
+
+ /* If this is a constructor or destructor body, we have to clone
+ it. */
+ if (maybe_clone_body (fn))
+ {
+ /* We don't want to process FN again, so pretend we've written
+ it out, even though we haven't. */
+ TREE_ASM_WRITTEN (fn) = 1;
+ /* If this is an instantiation of a constexpr function, keep
+ DECL_SAVED_TREE for explain_invalid_constexpr_fn. */
+ if (!is_instantiation_of_constexpr (fn))
+ DECL_SAVED_TREE (fn) = NULL_TREE;
+ return false;
+ }
+
+ /* There's no reason to do any of the work here if we're only doing
+ semantic analysis; this code just generates RTL. */
+ if (flag_syntax_only)
+ return false;
+
+ return true;
+}
+
+void
+expand_or_defer_fn (tree fn)
+{
+ if (expand_or_defer_fn_1 (fn))
+ {
+ function_depth++;
+
+ /* Expand or defer, at the whim of the compilation unit manager. */
+ cgraph_finalize_function (fn, function_depth > 1);
+ emit_associated_thunks (fn);
+
+ function_depth--;
+ }
+}
+
+struct nrv_data
+{
+ tree var;
+ tree result;
+ hash_table <pointer_hash <tree_node> > visited;
+};
+
+/* Helper function for walk_tree, used by finalize_nrv below. */
+
+static tree
+finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
+{
+ struct nrv_data *dp = (struct nrv_data *)data;
+ tree_node **slot;
+
+ /* No need to walk into types. There wouldn't be any need to walk into
+ non-statements, except that we have to consider STMT_EXPRs. */
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ /* Change all returns to just refer to the RESULT_DECL; this is a nop,
+ but differs from using NULL_TREE in that it indicates that we care
+ about the value of the RESULT_DECL. */
+ else if (TREE_CODE (*tp) == RETURN_EXPR)
+ TREE_OPERAND (*tp, 0) = dp->result;
+ /* Change all cleanups for the NRV to only run when an exception is
+ thrown. */
+ else if (TREE_CODE (*tp) == CLEANUP_STMT
+ && CLEANUP_DECL (*tp) == dp->var)
+ CLEANUP_EH_ONLY (*tp) = 1;
+ /* Replace the DECL_EXPR for the NRV with an initialization of the
+ RESULT_DECL, if needed. */
+ else if (TREE_CODE (*tp) == DECL_EXPR
+ && DECL_EXPR_DECL (*tp) == dp->var)
+ {
+ tree init;
+ if (DECL_INITIAL (dp->var)
+ && DECL_INITIAL (dp->var) != error_mark_node)
+ init = build2 (INIT_EXPR, void_type_node, dp->result,
+ DECL_INITIAL (dp->var));
+ else
+ init = build_empty_stmt (EXPR_LOCATION (*tp));
+ DECL_INITIAL (dp->var) = NULL_TREE;
+ SET_EXPR_LOCATION (init, EXPR_LOCATION (*tp));
+ *tp = init;
+ }
+ /* And replace all uses of the NRV with the RESULT_DECL. */
+ else if (*tp == dp->var)
+ *tp = dp->result;
+
+ /* Avoid walking into the same tree more than once. Unfortunately, we
+ can't just use walk_tree_without duplicates because it would only call
+ us for the first occurrence of dp->var in the function body. */
+ slot = dp->visited.find_slot (*tp, INSERT);
+ if (*slot)
+ *walk_subtrees = 0;
+ else
+ *slot = *tp;
+
+ /* Keep iterating. */
+ return NULL_TREE;
+}
+
+/* Called from finish_function to implement the named return value
+ optimization by overriding all the RETURN_EXPRs and pertinent
+ CLEANUP_STMTs and replacing all occurrences of VAR with RESULT, the
+ RESULT_DECL for the function. */
+
+void
+finalize_nrv (tree *tp, tree var, tree result)
+{
+ struct nrv_data data;
+
+ /* Copy name from VAR to RESULT. */
+ DECL_NAME (result) = DECL_NAME (var);
+ /* Don't forget that we take its address. */
+ TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (var);
+ /* Finally set DECL_VALUE_EXPR to avoid assigning
+ a stack slot at -O0 for the original var and debug info
+ uses RESULT location for VAR. */
+ SET_DECL_VALUE_EXPR (var, result);
+ DECL_HAS_VALUE_EXPR_P (var) = 1;
+
+ data.var = var;
+ data.result = result;
+ data.visited.create (37);
+ cp_walk_tree (tp, finalize_nrv_r, &data, 0);
+ data.visited.dispose ();
+}
+
+/* Create CP_OMP_CLAUSE_INFO for clause C. Returns true if it is invalid. */
+
+bool
+cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
+ bool need_copy_ctor, bool need_copy_assignment,
+ bool need_dtor)
+{
+ int save_errorcount = errorcount;
+ tree info, t;
+
+ /* Always allocate 3 elements for simplicity. These are the
+ function decls for the ctor, dtor, and assignment op.
+ This layout is known to the three lang hooks,
+ cxx_omp_clause_default_init, cxx_omp_clause_copy_init,
+ and cxx_omp_clause_assign_op. */
+ info = make_tree_vec (3);
+ CP_OMP_CLAUSE_INFO (c) = info;
+
+ if (need_default_ctor || need_copy_ctor)
+ {
+ if (need_default_ctor)
+ t = get_default_ctor (type);
+ else
+ t = get_copy_ctor (type, tf_warning_or_error);
+
+ if (t && !trivial_fn_p (t))
+ TREE_VEC_ELT (info, 0) = t;
+ }
+
+ if (need_dtor && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ TREE_VEC_ELT (info, 1) = get_dtor (type, tf_warning_or_error);
+
+ if (need_copy_assignment)
+ {
+ t = get_copy_assign (type);
+
+ if (t && !trivial_fn_p (t))
+ TREE_VEC_ELT (info, 2) = t;
+ }
+
+ return errorcount != save_errorcount;
+}
+
+/* Helper function for handle_omp_array_sections. Called recursively
+ to handle multiple array-section-subscripts. C is the clause,
+ T current expression (initially OMP_CLAUSE_DECL), which is either
+ a TREE_LIST for array-section-subscript (TREE_PURPOSE is low-bound
+ expression if specified, TREE_VALUE length expression if specified,
+ TREE_CHAIN is what it has been specified after, or some decl.
+ TYPES vector is populated with array section types, MAYBE_ZERO_LEN
+ set to true if any of the array-section-subscript could have length
+ of zero (explicit or implicit), FIRST_NON_ONE is the index of the
+ first array-section-subscript which is known not to have length
+ of one. Given say:
+ map(a[:b][2:1][:c][:2][:d][e:f][2:5])
+ FIRST_NON_ONE will be 3, array-section-subscript [:b], [2:1] and [:c]
+ all are or may have length of 1, array-section-subscript [:2] is the
+ first one knonwn not to have length 1. For array-section-subscript
+ <= FIRST_NON_ONE we diagnose non-contiguous arrays if low bound isn't
+ 0 or length isn't the array domain max + 1, for > FIRST_NON_ONE we
+ can if MAYBE_ZERO_LEN is false. MAYBE_ZERO_LEN will be true in the above
+ case though, as some lengths could be zero. */
+
+static tree
+handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
+ bool &maybe_zero_len, unsigned int &first_non_one)
+{
+ tree ret, low_bound, length, type;
+ if (TREE_CODE (t) != TREE_LIST)
+ {
+ if (error_operand_p (t))
+ return error_mark_node;
+ if (type_dependent_expression_p (t))
+ return NULL_TREE;
+ if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
+ {
+ if (processing_template_decl)
+ return NULL_TREE;
+ if (DECL_P (t))
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qD is not a variable in %qs clause", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ else
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE is not a variable in %qs clause", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ return error_mark_node;
+ }
+ else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
+ && TREE_CODE (t) == VAR_DECL && DECL_THREAD_LOCAL_P (t))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qD is threadprivate variable in %qs clause", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ return error_mark_node;
+ }
+ t = convert_from_reference (t);
+ return t;
+ }
+
+ ret = handle_omp_array_sections_1 (c, TREE_CHAIN (t), types,
+ maybe_zero_len, first_non_one);
+ if (ret == error_mark_node || ret == NULL_TREE)
+ return ret;
+
+ type = TREE_TYPE (ret);
+ low_bound = TREE_PURPOSE (t);
+ length = TREE_VALUE (t);
+ if ((low_bound && type_dependent_expression_p (low_bound))
+ || (length && type_dependent_expression_p (length)))
+ return NULL_TREE;
+
+ if (low_bound == error_mark_node || length == error_mark_node)
+ return error_mark_node;
+
+ if (low_bound && !INTEGRAL_TYPE_P (TREE_TYPE (low_bound)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "low bound %qE of array section does not have integral type",
+ low_bound);
+ return error_mark_node;
+ }
+ if (length && !INTEGRAL_TYPE_P (TREE_TYPE (length)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "length %qE of array section does not have integral type",
+ length);
+ return error_mark_node;
+ }
+ if (low_bound
+ && TREE_CODE (low_bound) == INTEGER_CST
+ && TYPE_PRECISION (TREE_TYPE (low_bound))
+ > TYPE_PRECISION (sizetype))
+ low_bound = fold_convert (sizetype, low_bound);
+ if (length
+ && TREE_CODE (length) == INTEGER_CST
+ && TYPE_PRECISION (TREE_TYPE (length))
+ > TYPE_PRECISION (sizetype))
+ length = fold_convert (sizetype, length);
+ if (low_bound == NULL_TREE)
+ low_bound = integer_zero_node;
+
+ if (length != NULL_TREE)
+ {
+ if (!integer_nonzerop (length))
+ maybe_zero_len = true;
+ if (first_non_one == types.length ()
+ && (TREE_CODE (length) != INTEGER_CST || integer_onep (length)))
+ first_non_one++;
+ }
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (length == NULL_TREE
+ && (TYPE_DOMAIN (type) == NULL_TREE
+ || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "for unknown bound array type length expression must "
+ "be specified");
+ return error_mark_node;
+ }
+ if (TREE_CODE (low_bound) == INTEGER_CST
+ && tree_int_cst_sgn (low_bound) == -1)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "negative low bound in array section in %qs clause",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ return error_mark_node;
+ }
+ if (length != NULL_TREE
+ && TREE_CODE (length) == INTEGER_CST
+ && tree_int_cst_sgn (length) == -1)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "negative length in array section in %qs clause",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ return error_mark_node;
+ }
+ if (TYPE_DOMAIN (type)
+ && TYPE_MAX_VALUE (TYPE_DOMAIN (type))
+ && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
+ == INTEGER_CST)
+ {
+ tree size = size_binop (PLUS_EXPR,
+ TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
+ size_one_node);
+ if (TREE_CODE (low_bound) == INTEGER_CST)
+ {
+ if (tree_int_cst_lt (size, low_bound))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "low bound %qE above array section size "
+ "in %qs clause", low_bound,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ return error_mark_node;
+ }
+ if (tree_int_cst_equal (size, low_bound))
+ maybe_zero_len = true;
+ else if (length == NULL_TREE
+ && first_non_one == types.length ()
+ && tree_int_cst_equal
+ (TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
+ low_bound))
+ first_non_one++;
+ }
+ else if (length == NULL_TREE)
+ {
+ maybe_zero_len = true;
+ if (first_non_one == types.length ())
+ first_non_one++;
+ }
+ if (length && TREE_CODE (length) == INTEGER_CST)
+ {
+ if (tree_int_cst_lt (size, length))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "length %qE above array section size "
+ "in %qs clause", length,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ return error_mark_node;
+ }
+ if (TREE_CODE (low_bound) == INTEGER_CST)
+ {
+ tree lbpluslen
+ = size_binop (PLUS_EXPR,
+ fold_convert (sizetype, low_bound),
+ fold_convert (sizetype, length));
+ if (TREE_CODE (lbpluslen) == INTEGER_CST
+ && tree_int_cst_lt (size, lbpluslen))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "high bound %qE above array section size "
+ "in %qs clause", lbpluslen,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ return error_mark_node;
+ }
+ }
+ }
+ }
+ else if (length == NULL_TREE)
+ {
+ maybe_zero_len = true;
+ if (first_non_one == types.length ())
+ first_non_one++;
+ }
+
+ /* For [lb:] we will need to evaluate lb more than once. */
+ if (length == NULL_TREE && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
+ {
+ tree lb = cp_save_expr (low_bound);
+ if (lb != low_bound)
+ {
+ TREE_PURPOSE (t) = lb;
+ low_bound = lb;
+ }
+ }
+ }
+ else if (TREE_CODE (type) == POINTER_TYPE)
+ {
+ if (length == NULL_TREE)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "for pointer type length expression must be specified");
+ return error_mark_node;
+ }
+ /* If there is a pointer type anywhere but in the very first
+ array-section-subscript, the array section can't be contiguous. */
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
+ && TREE_CODE (TREE_CHAIN (t)) == TREE_LIST)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "array section is not contiguous in %qs clause",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ return error_mark_node;
+ }
+ }
+ else
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE does not have pointer or array type", ret);
+ return error_mark_node;
+ }
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
+ types.safe_push (TREE_TYPE (ret));
+ /* We will need to evaluate lb more than once. */
+ tree lb = cp_save_expr (low_bound);
+ if (lb != low_bound)
+ {
+ TREE_PURPOSE (t) = lb;
+ low_bound = lb;
+ }
+ ret = grok_array_decl (OMP_CLAUSE_LOCATION (c), ret, low_bound, false);
+ return ret;
+}
+
+/* Handle array sections for clause C. */
+
+static bool
+handle_omp_array_sections (tree c)
+{
+ bool maybe_zero_len = false;
+ unsigned int first_non_one = 0;
+ auto_vec<tree> types;
+ tree first = handle_omp_array_sections_1 (c, OMP_CLAUSE_DECL (c), types,
+ maybe_zero_len, first_non_one);
+ if (first == error_mark_node)
+ return true;
+ if (first == NULL_TREE)
+ return false;
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
+ {
+ tree t = OMP_CLAUSE_DECL (c);
+ tree tem = NULL_TREE;
+ if (processing_template_decl)
+ return false;
+ /* Need to evaluate side effects in the length expressions
+ if any. */
+ while (TREE_CODE (t) == TREE_LIST)
+ {
+ if (TREE_VALUE (t) && TREE_SIDE_EFFECTS (TREE_VALUE (t)))
+ {
+ if (tem == NULL_TREE)
+ tem = TREE_VALUE (t);
+ else
+ tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem),
+ TREE_VALUE (t), tem);
+ }
+ t = TREE_CHAIN (t);
+ }
+ if (tem)
+ first = build2 (COMPOUND_EXPR, TREE_TYPE (first), tem, first);
+ OMP_CLAUSE_DECL (c) = first;
+ }
+ else
+ {
+ unsigned int num = types.length (), i;
+ tree t, side_effects = NULL_TREE, size = NULL_TREE;
+ tree condition = NULL_TREE;
+
+ if (int_size_in_bytes (TREE_TYPE (first)) <= 0)
+ maybe_zero_len = true;
+ if (processing_template_decl && maybe_zero_len)
+ return false;
+
+ for (i = num, t = OMP_CLAUSE_DECL (c); i > 0;
+ t = TREE_CHAIN (t))
+ {
+ tree low_bound = TREE_PURPOSE (t);
+ tree length = TREE_VALUE (t);
+
+ i--;
+ if (low_bound
+ && TREE_CODE (low_bound) == INTEGER_CST
+ && TYPE_PRECISION (TREE_TYPE (low_bound))
+ > TYPE_PRECISION (sizetype))
+ low_bound = fold_convert (sizetype, low_bound);
+ if (length
+ && TREE_CODE (length) == INTEGER_CST
+ && TYPE_PRECISION (TREE_TYPE (length))
+ > TYPE_PRECISION (sizetype))
+ length = fold_convert (sizetype, length);
+ if (low_bound == NULL_TREE)
+ low_bound = integer_zero_node;
+ if (!maybe_zero_len && i > first_non_one)
+ {
+ if (integer_nonzerop (low_bound))
+ goto do_warn_noncontiguous;
+ if (length != NULL_TREE
+ && TREE_CODE (length) == INTEGER_CST
+ && TYPE_DOMAIN (types[i])
+ && TYPE_MAX_VALUE (TYPE_DOMAIN (types[i]))
+ && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])))
+ == INTEGER_CST)
+ {
+ tree size;
+ size = size_binop (PLUS_EXPR,
+ TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])),
+ size_one_node);
+ if (!tree_int_cst_equal (length, size))
+ {
+ do_warn_noncontiguous:
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "array section is not contiguous in %qs "
+ "clause",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ return true;
+ }
+ }
+ if (!processing_template_decl
+ && length != NULL_TREE
+ && TREE_SIDE_EFFECTS (length))
+ {
+ if (side_effects == NULL_TREE)
+ side_effects = length;
+ else
+ side_effects = build2 (COMPOUND_EXPR,
+ TREE_TYPE (side_effects),
+ length, side_effects);
+ }
+ }
+ else if (processing_template_decl)
+ continue;
+ else
+ {
+ tree l;
+
+ if (i > first_non_one && length && integer_nonzerop (length))
+ continue;
+ if (length)
+ l = fold_convert (sizetype, length);
+ else
+ {
+ l = size_binop (PLUS_EXPR,
+ TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])),
+ size_one_node);
+ l = size_binop (MINUS_EXPR, l,
+ fold_convert (sizetype, low_bound));
+ }
+ if (i > first_non_one)
+ {
+ l = fold_build2 (NE_EXPR, boolean_type_node, l,
+ size_zero_node);
+ if (condition == NULL_TREE)
+ condition = l;
+ else
+ condition = fold_build2 (BIT_AND_EXPR, boolean_type_node,
+ l, condition);
+ }
+ else if (size == NULL_TREE)
+ {
+ size = size_in_bytes (TREE_TYPE (types[i]));
+ size = size_binop (MULT_EXPR, size, l);
+ if (condition)
+ size = fold_build3 (COND_EXPR, sizetype, condition,
+ size, size_zero_node);
+ }
+ else
+ size = size_binop (MULT_EXPR, size, l);
+ }
+ }
+ if (!processing_template_decl)
+ {
+ if (side_effects)
+ size = build2 (COMPOUND_EXPR, sizetype, side_effects, size);
+ OMP_CLAUSE_DECL (c) = first;
+ OMP_CLAUSE_SIZE (c) = size;
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
+ return false;
+ tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+ OMP_CLAUSE_MAP);
+ OMP_CLAUSE_MAP_KIND (c2) = OMP_CLAUSE_MAP_POINTER;
+ if (!cxx_mark_addressable (t))
+ return false;
+ OMP_CLAUSE_DECL (c2) = t;
+ t = build_fold_addr_expr (first);
+ t = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
+ ptrdiff_type_node, t);
+ tree ptr = OMP_CLAUSE_DECL (c2);
+ ptr = convert_from_reference (ptr);
+ if (!POINTER_TYPE_P (TREE_TYPE (ptr)))
+ ptr = build_fold_addr_expr (ptr);
+ t = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR,
+ ptrdiff_type_node, t,
+ fold_convert_loc (OMP_CLAUSE_LOCATION (c),
+ ptrdiff_type_node, ptr));
+ OMP_CLAUSE_SIZE (c2) = t;
+ OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
+ OMP_CLAUSE_CHAIN (c) = c2;
+ ptr = OMP_CLAUSE_DECL (c2);
+ if (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
+ && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (ptr))))
+ {
+ tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+ OMP_CLAUSE_MAP);
+ OMP_CLAUSE_MAP_KIND (c3) = OMP_CLAUSE_MAP_POINTER;
+ OMP_CLAUSE_DECL (c3) = ptr;
+ OMP_CLAUSE_DECL (c2) = convert_from_reference (ptr);
+ OMP_CLAUSE_SIZE (c3) = size_zero_node;
+ OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (c2);
+ OMP_CLAUSE_CHAIN (c2) = c3;
+ }
+ }
+ }
+ return false;
+}
+
+/* Return identifier to look up for omp declare reduction. */
+
+tree
+omp_reduction_id (enum tree_code reduction_code, tree reduction_id, tree type)
+{
+ const char *p = NULL;
+ const char *m = NULL;
+ switch (reduction_code)
+ {
+ case PLUS_EXPR:
+ case MULT_EXPR:
+ case MINUS_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_XOR_EXPR:
+ case BIT_IOR_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ reduction_id = ansi_opname (reduction_code);
+ break;
+ case MIN_EXPR:
+ p = "min";
+ break;
+ case MAX_EXPR:
+ p = "max";
+ break;
+ default:
+ break;
+ }
+
+ if (p == NULL)
+ {
+ if (TREE_CODE (reduction_id) != IDENTIFIER_NODE)
+ return error_mark_node;
+ p = IDENTIFIER_POINTER (reduction_id);
+ }
+
+ if (type != NULL_TREE)
+ m = mangle_type_string (TYPE_MAIN_VARIANT (type));
+
+ const char prefix[] = "omp declare reduction ";
+ size_t lenp = sizeof (prefix);
+ if (strncmp (p, prefix, lenp - 1) == 0)
+ lenp = 1;
+ size_t len = strlen (p);
+ size_t lenm = m ? strlen (m) + 1 : 0;
+ char *name = XALLOCAVEC (char, lenp + len + lenm);
+ if (lenp > 1)
+ memcpy (name, prefix, lenp - 1);
+ memcpy (name + lenp - 1, p, len + 1);
+ if (m)
+ {
+ name[lenp + len - 1] = '~';
+ memcpy (name + lenp + len, m, lenm);
+ }
+ return get_identifier (name);
+}
+
+/* Lookup OpenMP UDR ID for TYPE, return the corresponding artificial
+ FUNCTION_DECL or NULL_TREE if not found. */
+
+static tree
+omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp,
+ vec<tree> *ambiguousp)
+{
+ tree orig_id = id;
+ tree baselink = NULL_TREE;
+ if (identifier_p (id))
+ {
+ cp_id_kind idk;
+ bool nonint_cst_expression_p;
+ const char *error_msg;
+ id = omp_reduction_id (ERROR_MARK, id, type);
+ tree decl = lookup_name (id);
+ if (decl == NULL_TREE)
+ decl = error_mark_node;
+ id = finish_id_expression (id, decl, NULL_TREE, &idk, false, true,
+ &nonint_cst_expression_p, false, true, false,
+ false, &error_msg, loc);
+ if (idk == CP_ID_KIND_UNQUALIFIED
+ && identifier_p (id))
+ {
+ vec<tree, va_gc> *args = NULL;
+ vec_safe_push (args, build_reference_type (type));
+ id = perform_koenig_lookup (id, args, tf_none);
+ }
+ }
+ else if (TREE_CODE (id) == SCOPE_REF)
+ id = lookup_qualified_name (TREE_OPERAND (id, 0),
+ omp_reduction_id (ERROR_MARK,
+ TREE_OPERAND (id, 1),
+ type),
+ false, false);
+ tree fns = id;
+ if (id && is_overloaded_fn (id))
+ id = get_fns (id);
+ for (; id; id = OVL_NEXT (id))
+ {
+ tree fndecl = OVL_CURRENT (id);
+ if (TREE_CODE (fndecl) == FUNCTION_DECL)
+ {
+ tree argtype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
+ if (same_type_p (TREE_TYPE (argtype), type))
+ break;
+ }
+ }
+ if (id && BASELINK_P (fns))
+ {
+ if (baselinkp)
+ *baselinkp = fns;
+ else
+ baselink = fns;
+ }
+ if (id == NULL_TREE && CLASS_TYPE_P (type) && TYPE_BINFO (type))
+ {
+ vec<tree> ambiguous = vNULL;
+ tree binfo = TYPE_BINFO (type), base_binfo, ret = NULL_TREE;
+ unsigned int ix;
+ if (ambiguousp == NULL)
+ ambiguousp = &ambiguous;
+ for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
+ {
+ id = omp_reduction_lookup (loc, orig_id, BINFO_TYPE (base_binfo),
+ baselinkp ? baselinkp : &baselink,
+ ambiguousp);
+ if (id == NULL_TREE)
+ continue;
+ if (!ambiguousp->is_empty ())
+ ambiguousp->safe_push (id);
+ else if (ret != NULL_TREE)
+ {
+ ambiguousp->safe_push (ret);
+ ambiguousp->safe_push (id);
+ ret = NULL_TREE;
+ }
+ else
+ ret = id;
+ }
+ if (ambiguousp != &ambiguous)
+ return ret;
+ if (!ambiguous.is_empty ())
+ {
+ const char *str = _("candidates are:");
+ unsigned int idx;
+ tree udr;
+ error_at (loc, "user defined reduction lookup is ambiguous");
+ FOR_EACH_VEC_ELT (ambiguous, idx, udr)
+ {
+ inform (DECL_SOURCE_LOCATION (udr), "%s %#D", str, udr);
+ if (idx == 0)
+ str = get_spaces (str);
+ }
+ ambiguous.release ();
+ ret = error_mark_node;
+ baselink = NULL_TREE;
+ }
+ id = ret;
+ }
+ if (id && baselink)
+ perform_or_defer_access_check (BASELINK_BINFO (baselink),
+ id, id, tf_warning_or_error);
+ return id;
+}
+
+/* Helper function for cp_parser_omp_declare_reduction_exprs
+ and tsubst_omp_udr.
+ Remove CLEANUP_STMT for data (omp_priv variable).
+ Also append INIT_EXPR for DECL_INITIAL of omp_priv after its
+ DECL_EXPR. */
+
+tree
+cp_remove_omp_priv_cleanup_stmt (tree *tp, int *walk_subtrees, void *data)
+{
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ else if (TREE_CODE (*tp) == CLEANUP_STMT && CLEANUP_DECL (*tp) == (tree) data)
+ *tp = CLEANUP_BODY (*tp);
+ else if (TREE_CODE (*tp) == DECL_EXPR)
+ {
+ tree decl = DECL_EXPR_DECL (*tp);
+ if (!processing_template_decl
+ && decl == (tree) data
+ && DECL_INITIAL (decl)
+ && DECL_INITIAL (decl) != error_mark_node)
+ {
+ tree list = NULL_TREE;
+ append_to_statement_list_force (*tp, &list);
+ tree init_expr = build2 (INIT_EXPR, void_type_node,
+ decl, DECL_INITIAL (decl));
+ DECL_INITIAL (decl) = NULL_TREE;
+ append_to_statement_list_force (init_expr, &list);
+ *tp = list;
+ }
+ }
+ return NULL_TREE;
+}
+
+/* Data passed from cp_check_omp_declare_reduction to
+ cp_check_omp_declare_reduction_r. */
+
+struct cp_check_omp_declare_reduction_data
+{
+ location_t loc;
+ tree stmts[7];
+ bool combiner_p;
+};
+
+/* Helper function for cp_check_omp_declare_reduction, called via
+ cp_walk_tree. */
+
+static tree
+cp_check_omp_declare_reduction_r (tree *tp, int *, void *data)
+{
+ struct cp_check_omp_declare_reduction_data *udr_data
+ = (struct cp_check_omp_declare_reduction_data *) data;
+ if (SSA_VAR_P (*tp)
+ && !DECL_ARTIFICIAL (*tp)
+ && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 0 : 3])
+ && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 1 : 4]))
+ {
+ location_t loc = udr_data->loc;
+ if (udr_data->combiner_p)
+ error_at (loc, "%<#pragma omp declare reduction%> combiner refers to "
+ "variable %qD which is not %<omp_out%> nor %<omp_in%>",
+ *tp);
+ else
+ error_at (loc, "%<#pragma omp declare reduction%> initializer refers "
+ "to variable %qD which is not %<omp_priv%> nor "
+ "%<omp_orig%>",
+ *tp);
+ return *tp;
+ }
+ return NULL_TREE;
+}
+
+/* Diagnose violation of OpenMP #pragma omp declare reduction restrictions. */
+
+void
+cp_check_omp_declare_reduction (tree udr)
+{
+ tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (udr)));
+ gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
+ type = TREE_TYPE (type);
+ int i;
+ location_t loc = DECL_SOURCE_LOCATION (udr);
+
+ if (type == error_mark_node)
+ return;
+ if (ARITHMETIC_TYPE_P (type))
+ {
+ static enum tree_code predef_codes[]
+ = { PLUS_EXPR, MULT_EXPR, MINUS_EXPR, BIT_AND_EXPR, BIT_XOR_EXPR,
+ BIT_IOR_EXPR, TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR };
+ for (i = 0; i < 8; i++)
+ {
+ tree id = omp_reduction_id (predef_codes[i], NULL_TREE, NULL_TREE);
+ const char *n1 = IDENTIFIER_POINTER (DECL_NAME (udr));
+ const char *n2 = IDENTIFIER_POINTER (id);
+ if (strncmp (n1, n2, IDENTIFIER_LENGTH (id)) == 0
+ && (n1[IDENTIFIER_LENGTH (id)] == '~'
+ || n1[IDENTIFIER_LENGTH (id)] == '\0'))
+ break;
+ }
+
+ if (i == 8
+ && TREE_CODE (type) != COMPLEX_EXPR)
+ {
+ const char prefix_minmax[] = "omp declare reduction m";
+ size_t prefix_size = sizeof (prefix_minmax) - 1;
+ const char *n = IDENTIFIER_POINTER (DECL_NAME (udr));
+ if (strncmp (IDENTIFIER_POINTER (DECL_NAME (udr)),
+ prefix_minmax, prefix_size) == 0
+ && ((n[prefix_size] == 'i' && n[prefix_size + 1] == 'n')
+ || (n[prefix_size] == 'a' && n[prefix_size + 1] == 'x'))
+ && (n[prefix_size + 2] == '~' || n[prefix_size + 2] == '\0'))
+ i = 0;
+ }
+ if (i < 8)
+ {
+ error_at (loc, "predeclared arithmetic type %qT in "
+ "%<#pragma omp declare reduction%>", type);
+ return;
+ }
+ }
+ else if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE
+ || TREE_CODE (type) == ARRAY_TYPE)
+ {
+ error_at (loc, "function or array type %qT in "
+ "%<#pragma omp declare reduction%>", type);
+ return;
+ }
+ else if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ error_at (loc, "reference type %qT in %<#pragma omp declare reduction%>",
+ type);
+ return;
+ }
+ else if (TYPE_QUALS_NO_ADDR_SPACE (type))
+ {
+ error_at (loc, "const, volatile or __restrict qualified type %qT in "
+ "%<#pragma omp declare reduction%>", type);
+ return;
+ }
+
+ tree body = DECL_SAVED_TREE (udr);
+ if (body == NULL_TREE || TREE_CODE (body) != STATEMENT_LIST)
+ return;
+
+ tree_stmt_iterator tsi;
+ struct cp_check_omp_declare_reduction_data data;
+ memset (data.stmts, 0, sizeof data.stmts);
+ for (i = 0, tsi = tsi_start (body);
+ i < 7 && !tsi_end_p (tsi);
+ i++, tsi_next (&tsi))
+ data.stmts[i] = tsi_stmt (tsi);
+ data.loc = loc;
+ gcc_assert (tsi_end_p (tsi));
+ if (i >= 3)
+ {
+ gcc_assert (TREE_CODE (data.stmts[0]) == DECL_EXPR
+ && TREE_CODE (data.stmts[1]) == DECL_EXPR);
+ if (TREE_NO_WARNING (DECL_EXPR_DECL (data.stmts[0])))
+ return;
+ data.combiner_p = true;
+ if (cp_walk_tree (&data.stmts[2], cp_check_omp_declare_reduction_r,
+ &data, NULL))
+ TREE_NO_WARNING (DECL_EXPR_DECL (data.stmts[0])) = 1;
+ }
+ if (i >= 6)
+ {
+ gcc_assert (TREE_CODE (data.stmts[3]) == DECL_EXPR
+ && TREE_CODE (data.stmts[4]) == DECL_EXPR);
+ data.combiner_p = false;
+ if (cp_walk_tree (&data.stmts[5], cp_check_omp_declare_reduction_r,
+ &data, NULL)
+ || cp_walk_tree (&DECL_INITIAL (DECL_EXPR_DECL (data.stmts[3])),
+ cp_check_omp_declare_reduction_r, &data, NULL))
+ TREE_NO_WARNING (DECL_EXPR_DECL (data.stmts[0])) = 1;
+ if (i == 7)
+ gcc_assert (TREE_CODE (data.stmts[6]) == DECL_EXPR);
+ }
+}
+
+/* Helper function of finish_omp_clauses. Clone STMT as if we were making
+ an inline call. But, remap
+ the OMP_DECL1 VAR_DECL (omp_out resp. omp_orig) to PLACEHOLDER
+ and OMP_DECL2 VAR_DECL (omp_in resp. omp_priv) to DECL. */
+
+static tree
+clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
+ tree decl, tree placeholder)
+{
+ copy_body_data id;
+ struct pointer_map_t *decl_map = pointer_map_create ();
+
+ *pointer_map_insert (decl_map, omp_decl1) = placeholder;
+ *pointer_map_insert (decl_map, omp_decl2) = decl;
+ memset (&id, 0, sizeof (id));
+ id.src_fn = DECL_CONTEXT (omp_decl1);
+ id.dst_fn = current_function_decl;
+ id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn);
+ id.decl_map = decl_map;
+
+ id.copy_decl = copy_decl_no_change;
+ id.transform_call_graph_edges = CB_CGE_DUPLICATE;
+ id.transform_new_cfg = true;
+ id.transform_return_to_modify = false;
+ id.transform_lang_insert_block = NULL;
+ id.eh_lp_nr = 0;
+ walk_tree (&stmt, copy_tree_body_r, &id, NULL);
+ pointer_map_destroy (decl_map);
+ return stmt;
+}
+
+/* Helper function of finish_omp_clauses, called via cp_walk_tree.
+ Find OMP_CLAUSE_PLACEHOLDER (passed in DATA) in *TP. */
+
+static tree
+find_omp_placeholder_r (tree *tp, int *, void *data)
+{
+ if (*tp == (tree) data)
+ return *tp;
+ return NULL_TREE;
+}
+
+/* Helper function of finish_omp_clauses. Handle OMP_CLAUSE_REDUCTION C.
+ Return true if there is some error and the clause should be removed. */
+
+static bool
+finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
+{
+ tree t = OMP_CLAUSE_DECL (c);
+ bool predefined = false;
+ tree type = TREE_TYPE (t);
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ type = TREE_TYPE (type);
+ if (type == error_mark_node)
+ return true;
+ else if (ARITHMETIC_TYPE_P (type))
+ switch (OMP_CLAUSE_REDUCTION_CODE (c))
+ {
+ case PLUS_EXPR:
+ case MULT_EXPR:
+ case MINUS_EXPR:
+ predefined = true;
+ break;
+ case MIN_EXPR:
+ case MAX_EXPR:
+ if (TREE_CODE (type) == COMPLEX_TYPE)
+ break;
+ predefined = true;
+ break;
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ if (FLOAT_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE)
+ break;
+ predefined = true;
+ break;
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ if (FLOAT_TYPE_P (type))
+ break;
+ predefined = true;
+ break;
+ default:
+ break;
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE || TYPE_READONLY (type))
+ {
+ error ("%qE has invalid type for %<reduction%>", t);
+ return true;
+ }
+ else if (!processing_template_decl)
+ {
+ t = require_complete_type (t);
+ if (t == error_mark_node)
+ return true;
+ OMP_CLAUSE_DECL (c) = t;
+ }
+
+ if (predefined)
+ {
+ OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE;
+ return false;
+ }
+ else if (processing_template_decl)
+ return false;
+
+ tree id = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
+
+ type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ type = TREE_TYPE (type);
+ OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE;
+ if (id == NULL_TREE)
+ id = omp_reduction_id (OMP_CLAUSE_REDUCTION_CODE (c),
+ NULL_TREE, NULL_TREE);
+ id = omp_reduction_lookup (OMP_CLAUSE_LOCATION (c), id, type, NULL, NULL);
+ if (id)
+ {
+ if (id == error_mark_node)
+ return true;
+ id = OVL_CURRENT (id);
+ mark_used (id);
+ tree body = DECL_SAVED_TREE (id);
+ if (TREE_CODE (body) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator tsi;
+ tree placeholder = NULL_TREE;
+ int i;
+ tree stmts[7];
+ tree atype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (id)));
+ atype = TREE_TYPE (atype);
+ bool need_static_cast = !same_type_p (type, atype);
+ memset (stmts, 0, sizeof stmts);
+ for (i = 0, tsi = tsi_start (body);
+ i < 7 && !tsi_end_p (tsi);
+ i++, tsi_next (&tsi))
+ stmts[i] = tsi_stmt (tsi);
+ gcc_assert (tsi_end_p (tsi));
+
+ if (i >= 3)
+ {
+ gcc_assert (TREE_CODE (stmts[0]) == DECL_EXPR
+ && TREE_CODE (stmts[1]) == DECL_EXPR);
+ placeholder = build_lang_decl (VAR_DECL, NULL_TREE, type);
+ DECL_ARTIFICIAL (placeholder) = 1;
+ DECL_IGNORED_P (placeholder) = 1;
+ OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = placeholder;
+ if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[0])))
+ cxx_mark_addressable (placeholder);
+ if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[1]))
+ && TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
+ != REFERENCE_TYPE)
+ cxx_mark_addressable (OMP_CLAUSE_DECL (c));
+ tree omp_out = placeholder;
+ tree omp_in = convert_from_reference (OMP_CLAUSE_DECL (c));
+ if (need_static_cast)
+ {
+ tree rtype = build_reference_type (atype);
+ omp_out = build_static_cast (rtype, omp_out,
+ tf_warning_or_error);
+ omp_in = build_static_cast (rtype, omp_in,
+ tf_warning_or_error);
+ if (omp_out == error_mark_node || omp_in == error_mark_node)
+ return true;
+ omp_out = convert_from_reference (omp_out);
+ omp_in = convert_from_reference (omp_in);
+ }
+ OMP_CLAUSE_REDUCTION_MERGE (c)
+ = clone_omp_udr (stmts[2], DECL_EXPR_DECL (stmts[0]),
+ DECL_EXPR_DECL (stmts[1]), omp_in, omp_out);
+ }
+ if (i >= 6)
+ {
+ gcc_assert (TREE_CODE (stmts[3]) == DECL_EXPR
+ && TREE_CODE (stmts[4]) == DECL_EXPR);
+ if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[3])))
+ cxx_mark_addressable (OMP_CLAUSE_DECL (c));
+ if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[4])))
+ cxx_mark_addressable (placeholder);
+ tree omp_priv = convert_from_reference (OMP_CLAUSE_DECL (c));
+ tree omp_orig = placeholder;
+ if (need_static_cast)
+ {
+ if (i == 7)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "user defined reduction with constructor "
+ "initializer for base class %qT", atype);
+ return true;
+ }
+ tree rtype = build_reference_type (atype);
+ omp_priv = build_static_cast (rtype, omp_priv,
+ tf_warning_or_error);
+ omp_orig = build_static_cast (rtype, omp_orig,
+ tf_warning_or_error);
+ if (omp_priv == error_mark_node
+ || omp_orig == error_mark_node)
+ return true;
+ omp_priv = convert_from_reference (omp_priv);
+ omp_orig = convert_from_reference (omp_orig);
+ }
+ if (i == 6)
+ *need_default_ctor = true;
+ OMP_CLAUSE_REDUCTION_INIT (c)
+ = clone_omp_udr (stmts[5], DECL_EXPR_DECL (stmts[4]),
+ DECL_EXPR_DECL (stmts[3]),
+ omp_priv, omp_orig);
+ if (cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
+ find_omp_placeholder_r, placeholder, NULL))
+ OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c) = 1;
+ }
+ else if (i >= 3)
+ {
+ if (CLASS_TYPE_P (type) && !pod_type_p (type))
+ *need_default_ctor = true;
+ else
+ {
+ tree init;
+ tree v = convert_from_reference (t);
+ if (AGGREGATE_TYPE_P (TREE_TYPE (v)))
+ init = build_constructor (TREE_TYPE (v), NULL);
+ else
+ init = fold_convert (TREE_TYPE (v), integer_zero_node);
+ OMP_CLAUSE_REDUCTION_INIT (c)
+ = build2 (INIT_EXPR, TREE_TYPE (v), v, init);
+ }
+ }
+ }
+ }
+ if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
+ *need_dtor = true;
+ else
+ {
+ error ("user defined reduction not found for %qD", t);
+ return true;
+ }
+ return false;
+}
+
+/* For all elements of CLAUSES, validate them vs OpenMP constraints.
+ Remove any elements from the list that are invalid. */
+
+tree
+finish_omp_clauses (tree clauses)
+{
+ bitmap_head generic_head, firstprivate_head, lastprivate_head;
+ bitmap_head aligned_head;
+ tree c, t, *pc = &clauses;
+ bool branch_seen = false;
+ bool copyprivate_seen = false;
+
+ bitmap_obstack_initialize (NULL);
+ bitmap_initialize (&generic_head, &bitmap_default_obstack);
+ bitmap_initialize (&firstprivate_head, &bitmap_default_obstack);
+ bitmap_initialize (&lastprivate_head, &bitmap_default_obstack);
+ bitmap_initialize (&aligned_head, &bitmap_default_obstack);
+
+ for (pc = &clauses, c = clauses; c ; c = *pc)
+ {
+ bool remove = false;
+
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_SHARED:
+ goto check_dup_generic;
+ case OMP_CLAUSE_PRIVATE:
+ goto check_dup_generic;
+ case OMP_CLAUSE_REDUCTION:
+ goto check_dup_generic;
+ case OMP_CLAUSE_COPYPRIVATE:
+ copyprivate_seen = true;
+ goto check_dup_generic;
+ case OMP_CLAUSE_COPYIN:
+ goto check_dup_generic;
+ case OMP_CLAUSE_LINEAR:
+ t = OMP_CLAUSE_DECL (c);
+ if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t))
+ && TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
+ {
+ error ("linear clause applied to non-integral non-pointer "
+ "variable with %qT type", TREE_TYPE (t));
+ remove = true;
+ break;
+ }
+ t = OMP_CLAUSE_LINEAR_STEP (c);
+ if (t == NULL_TREE)
+ t = integer_one_node;
+ if (t == error_mark_node)
+ {
+ remove = true;
+ break;
+ }
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("linear step expression must be integral");
+ remove = true;
+ break;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ {
+ if (TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL)
+ t = maybe_constant_value (t);
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
+ == POINTER_TYPE)
+ {
+ t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
+ OMP_CLAUSE_DECL (c), t);
+ t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
+ MINUS_EXPR, sizetype, t,
+ OMP_CLAUSE_DECL (c));
+ if (t == error_mark_node)
+ {
+ remove = true;
+ break;
+ }
+ }
+ }
+ OMP_CLAUSE_LINEAR_STEP (c) = t;
+ }
+ goto check_dup_generic;
+ check_dup_generic:
+ t = OMP_CLAUSE_DECL (c);
+ if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
+ {
+ if (processing_template_decl)
+ break;
+ if (DECL_P (t))
+ error ("%qD is not a variable in clause %qs", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ else
+ error ("%qE is not a variable in clause %qs", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ else if (bitmap_bit_p (&generic_head, DECL_UID (t))
+ || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
+ || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
+ {
+ error ("%qD appears more than once in data clauses", t);
+ remove = true;
+ }
+ else
+ bitmap_set_bit (&generic_head, DECL_UID (t));
+ break;
+
+ case OMP_CLAUSE_FIRSTPRIVATE:
+ t = OMP_CLAUSE_DECL (c);
+ if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
+ {
+ if (processing_template_decl)
+ break;
+ if (DECL_P (t))
+ error ("%qD is not a variable in clause %<firstprivate%>", t);
+ else
+ error ("%qE is not a variable in clause %<firstprivate%>", t);
+ remove = true;
+ }
+ else if (bitmap_bit_p (&generic_head, DECL_UID (t))
+ || bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
+ {
+ error ("%qD appears more than once in data clauses", t);
+ remove = true;
+ }
+ else
+ bitmap_set_bit (&firstprivate_head, DECL_UID (t));
+ break;
+
+ case OMP_CLAUSE_LASTPRIVATE:
+ t = OMP_CLAUSE_DECL (c);
+ if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
+ {
+ if (processing_template_decl)
+ break;
+ if (DECL_P (t))
+ error ("%qD is not a variable in clause %<lastprivate%>", t);
+ else
+ error ("%qE is not a variable in clause %<lastprivate%>", t);
+ remove = true;
+ }
+ else if (bitmap_bit_p (&generic_head, DECL_UID (t))
+ || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
+ {
+ error ("%qD appears more than once in data clauses", t);
+ remove = true;
+ }
+ else
+ bitmap_set_bit (&lastprivate_head, DECL_UID (t));
+ break;
+
+ case OMP_CLAUSE_IF:
+ t = OMP_CLAUSE_IF_EXPR (c);
+ t = maybe_convert_cond (t);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_IF_EXPR (c) = t;
+ break;
+
+ case OMP_CLAUSE_FINAL:
+ t = OMP_CLAUSE_FINAL_EXPR (c);
+ t = maybe_convert_cond (t);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_FINAL_EXPR (c) = t;
+ break;
+
+ case OMP_CLAUSE_NUM_THREADS:
+ t = OMP_CLAUSE_NUM_THREADS_EXPR (c);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("num_threads expression must be integral");
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
+ }
+ break;
+
+ case OMP_CLAUSE_SCHEDULE:
+ t = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c);
+ if (t == NULL)
+ ;
+ else if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("schedule chunk size expression must be integral");
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
+ }
+ break;
+
+ case OMP_CLAUSE_SIMDLEN:
+ case OMP_CLAUSE_SAFELEN:
+ t = OMP_CLAUSE_OPERAND (c, 0);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("%qs length expression must be integral",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ t = maybe_constant_value (t);
+ if (!processing_template_decl)
+ {
+ if (TREE_CODE (t) != INTEGER_CST
+ || tree_int_cst_sgn (t) != 1)
+ {
+ error ("%qs length expression must be positive constant"
+ " integer expression",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ }
+ OMP_CLAUSE_OPERAND (c, 0) = t;
+ }
+ break;
+
+ case OMP_CLAUSE_NUM_TEAMS:
+ t = OMP_CLAUSE_NUM_TEAMS_EXPR (c);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("%<num_teams%> expression must be integral");
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
+ }
+ break;
+
+ case OMP_CLAUSE_THREAD_LIMIT:
+ t = OMP_CLAUSE_THREAD_LIMIT_EXPR (c);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("%<thread_limit%> expression must be integral");
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
+ }
+ break;
+
+ case OMP_CLAUSE_DEVICE:
+ t = OMP_CLAUSE_DEVICE_ID (c);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("%<device%> id must be integral");
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_DEVICE_ID (c) = t;
+ }
+ break;
+
+ case OMP_CLAUSE_DIST_SCHEDULE:
+ t = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c);
+ if (t == NULL)
+ ;
+ else if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("%<dist_schedule%> chunk size expression must be "
+ "integral");
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
+ }
+ break;
+
+ case OMP_CLAUSE_ALIGNED:
+ t = OMP_CLAUSE_DECL (c);
+ if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
+ {
+ if (processing_template_decl)
+ break;
+ if (DECL_P (t))
+ error ("%qD is not a variable in %<aligned%> clause", t);
+ else
+ error ("%qE is not a variable in %<aligned%> clause", t);
+ remove = true;
+ }
+ else if (!type_dependent_expression_p (t)
+ && TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
+ && (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE
+ || (!POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (t)))
+ && (TREE_CODE (TREE_TYPE (TREE_TYPE (t)))
+ != ARRAY_TYPE))))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE in %<aligned%> clause is neither a pointer nor "
+ "an array nor a reference to pointer or array", t);
+ remove = true;
+ }
+ else if (bitmap_bit_p (&aligned_head, DECL_UID (t)))
+ {
+ error ("%qD appears more than once in %<aligned%> clauses", t);
+ remove = true;
+ }
+ else
+ bitmap_set_bit (&aligned_head, DECL_UID (t));
+ t = OMP_CLAUSE_ALIGNED_ALIGNMENT (c);
+ if (t == error_mark_node)
+ remove = true;
+ else if (t == NULL_TREE)
+ break;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("%<aligned%> clause alignment expression must "
+ "be integral");
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ t = maybe_constant_value (t);
+ if (!processing_template_decl)
+ {
+ if (TREE_CODE (t) != INTEGER_CST
+ || tree_int_cst_sgn (t) != 1)
+ {
+ error ("%<aligned%> clause alignment expression must be "
+ "positive constant integer expression");
+ remove = true;
+ }
+ }
+ OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = t;
+ }
+ break;
+
+ case OMP_CLAUSE_DEPEND:
+ t = OMP_CLAUSE_DECL (c);
+ if (TREE_CODE (t) == TREE_LIST)
+ {
+ if (handle_omp_array_sections (c))
+ remove = true;
+ break;
+ }
+ if (t == error_mark_node)
+ remove = true;
+ else if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
+ {
+ if (processing_template_decl)
+ break;
+ if (DECL_P (t))
+ error ("%qD is not a variable in %<depend%> clause", t);
+ else
+ error ("%qE is not a variable in %<depend%> clause", t);
+ remove = true;
+ }
+ else if (!processing_template_decl
+ && !cxx_mark_addressable (t))
+ remove = true;
+ break;
+
+ case OMP_CLAUSE_MAP:
+ case OMP_CLAUSE_TO:
+ case OMP_CLAUSE_FROM:
+ t = OMP_CLAUSE_DECL (c);
+ if (TREE_CODE (t) == TREE_LIST)
+ {
+ if (handle_omp_array_sections (c))
+ remove = true;
+ else
+ {
+ t = OMP_CLAUSE_DECL (c);
+ if (!cp_omp_mappable_type (TREE_TYPE (t)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "array section does not have mappable type "
+ "in %qs clause",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ }
+ break;
+ }
+ if (t == error_mark_node)
+ remove = true;
+ else if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
+ {
+ if (processing_template_decl)
+ break;
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
+ && OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER)
+ break;
+ if (DECL_P (t))
+ error ("%qD is not a variable in %qs clause", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ else
+ error ("%qE is not a variable in %qs clause", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ else if (TREE_CODE (t) == VAR_DECL && DECL_THREAD_LOCAL_P (t))
+ {
+ error ("%qD is threadprivate variable in %qs clause", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ else if (!processing_template_decl
+ && TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE
+ && !cxx_mark_addressable (t))
+ remove = true;
+ else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
+ && OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER)
+ && !cp_omp_mappable_type ((TREE_CODE (TREE_TYPE (t))
+ == REFERENCE_TYPE)
+ ? TREE_TYPE (TREE_TYPE (t))
+ : TREE_TYPE (t)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qD does not have a mappable type in %qs clause", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ else if (bitmap_bit_p (&generic_head, DECL_UID (t)))
+ {
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
+ error ("%qD appears more than once in motion clauses", t);
+ else
+ error ("%qD appears more than once in map clauses", t);
+ remove = true;
+ }
+ else
+ bitmap_set_bit (&generic_head, DECL_UID (t));
+ break;
+
+ case OMP_CLAUSE_UNIFORM:
+ t = OMP_CLAUSE_DECL (c);
+ if (TREE_CODE (t) != PARM_DECL)
+ {
+ if (processing_template_decl)
+ break;
+ if (DECL_P (t))
+ error ("%qD is not an argument in %<uniform%> clause", t);
+ else
+ error ("%qE is not an argument in %<uniform%> clause", t);
+ remove = true;
+ break;
+ }
+ goto check_dup_generic;
+
+ case OMP_CLAUSE_NOWAIT:
+ case OMP_CLAUSE_ORDERED:
+ case OMP_CLAUSE_DEFAULT:
+ case OMP_CLAUSE_UNTIED:
+ case OMP_CLAUSE_COLLAPSE:
+ case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_PARALLEL:
+ case OMP_CLAUSE_FOR:
+ case OMP_CLAUSE_SECTIONS:
+ case OMP_CLAUSE_TASKGROUP:
+ case OMP_CLAUSE_PROC_BIND:
+ break;
+
+ case OMP_CLAUSE_INBRANCH:
+ case OMP_CLAUSE_NOTINBRANCH:
+ if (branch_seen)
+ {
+ error ("%<inbranch%> clause is incompatible with "
+ "%<notinbranch%>");
+ remove = true;
+ }
+ branch_seen = true;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (remove)
+ *pc = OMP_CLAUSE_CHAIN (c);
+ else
+ pc = &OMP_CLAUSE_CHAIN (c);
+ }
+
+ for (pc = &clauses, c = clauses; c ; c = *pc)
+ {
+ enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
+ bool remove = false;
+ bool need_complete_non_reference = false;
+ bool need_default_ctor = false;
+ bool need_copy_ctor = false;
+ bool need_copy_assignment = false;
+ bool need_implicitly_determined = false;
+ bool need_dtor = false;
+ tree type, inner_type;
+
+ switch (c_kind)
+ {
+ case OMP_CLAUSE_SHARED:
+ need_implicitly_determined = true;
+ break;
+ case OMP_CLAUSE_PRIVATE:
+ need_complete_non_reference = true;
+ need_default_ctor = true;
+ need_dtor = true;
+ need_implicitly_determined = true;
+ break;
+ case OMP_CLAUSE_FIRSTPRIVATE:
+ need_complete_non_reference = true;
+ need_copy_ctor = true;
+ need_dtor = true;
+ need_implicitly_determined = true;
+ break;
+ case OMP_CLAUSE_LASTPRIVATE:
+ need_complete_non_reference = true;
+ need_copy_assignment = true;
+ need_implicitly_determined = true;
+ break;
+ case OMP_CLAUSE_REDUCTION:
+ need_implicitly_determined = true;
+ break;
+ case OMP_CLAUSE_COPYPRIVATE:
+ need_copy_assignment = true;
+ break;
+ case OMP_CLAUSE_COPYIN:
+ need_copy_assignment = true;
+ break;
+ case OMP_CLAUSE_NOWAIT:
+ if (copyprivate_seen)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<nowait%> clause must not be used together "
+ "with %<copyprivate%>");
+ *pc = OMP_CLAUSE_CHAIN (c);
+ continue;
+ }
+ /* FALLTHRU */
+ default:
+ pc = &OMP_CLAUSE_CHAIN (c);
+ continue;
+ }
+
+ t = OMP_CLAUSE_DECL (c);
+ if (processing_template_decl
+ && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
+ {
+ pc = &OMP_CLAUSE_CHAIN (c);
+ continue;
+ }
+
+ switch (c_kind)
+ {
+ case OMP_CLAUSE_LASTPRIVATE:
+ if (!bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
+ {
+ need_default_ctor = true;
+ need_dtor = true;
+ }
+ break;
+
+ case OMP_CLAUSE_REDUCTION:
+ if (finish_omp_reduction_clause (c, &need_default_ctor,
+ &need_dtor))
+ remove = true;
+ else
+ t = OMP_CLAUSE_DECL (c);
+ break;
+
+ case OMP_CLAUSE_COPYIN:
+ if (!VAR_P (t) || !DECL_THREAD_LOCAL_P (t))
+ {
+ error ("%qE must be %<threadprivate%> for %<copyin%>", t);
+ remove = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (need_complete_non_reference || need_copy_assignment)
+ {
+ t = require_complete_type (t);
+ if (t == error_mark_node)
+ remove = true;
+ else if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE
+ && need_complete_non_reference)
+ {
+ error ("%qE has reference type for %qs", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ }
+ if (need_implicitly_determined)
+ {
+ const char *share_name = NULL;
+
+ if (VAR_P (t) && DECL_THREAD_LOCAL_P (t))
+ share_name = "threadprivate";
+ else switch (cxx_omp_predetermined_sharing (t))
+ {
+ case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
+ break;
+ case OMP_CLAUSE_DEFAULT_SHARED:
+ /* const vars may be specified in firstprivate clause. */
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+ && cxx_omp_const_qual_no_mutable (t))
+ break;
+ share_name = "shared";
+ break;
+ case OMP_CLAUSE_DEFAULT_PRIVATE:
+ share_name = "private";
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ if (share_name)
+ {
+ error ("%qE is predetermined %qs for %qs",
+ t, share_name, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ }
+
+ /* We're interested in the base element, not arrays. */
+ inner_type = type = TREE_TYPE (t);
+ while (TREE_CODE (inner_type) == ARRAY_TYPE)
+ inner_type = TREE_TYPE (inner_type);
+
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+ && TREE_CODE (inner_type) == REFERENCE_TYPE)
+ inner_type = TREE_TYPE (inner_type);
+
+ /* Check for special function availability by building a call to one.
+ Save the results, because later we won't be in the right context
+ for making these queries. */
+ if (CLASS_TYPE_P (inner_type)
+ && COMPLETE_TYPE_P (inner_type)
+ && (need_default_ctor || need_copy_ctor
+ || need_copy_assignment || need_dtor)
+ && !type_dependent_expression_p (t)
+ && cxx_omp_create_clause_info (c, inner_type, need_default_ctor,
+ need_copy_ctor, need_copy_assignment,
+ need_dtor))
+ remove = true;
+
+ if (remove)
+ *pc = OMP_CLAUSE_CHAIN (c);
+ else
+ pc = &OMP_CLAUSE_CHAIN (c);
+ }
+
+ bitmap_obstack_release (NULL);
+ return clauses;
+}
+
+/* For all variables in the tree_list VARS, mark them as thread local. */
+
+void
+finish_omp_threadprivate (tree vars)
+{
+ tree t;
+
+ /* Mark every variable in VARS to be assigned thread local storage. */
+ for (t = vars; t; t = TREE_CHAIN (t))
+ {
+ tree v = TREE_PURPOSE (t);
+
+ if (error_operand_p (v))
+ ;
+ else if (!VAR_P (v))
+ error ("%<threadprivate%> %qD is not file, namespace "
+ "or block scope variable", v);
+ /* If V had already been marked threadprivate, it doesn't matter
+ whether it had been used prior to this point. */
+ else if (TREE_USED (v)
+ && (DECL_LANG_SPECIFIC (v) == NULL
+ || !CP_DECL_THREADPRIVATE_P (v)))
+ error ("%qE declared %<threadprivate%> after first use", v);
+ else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
+ error ("automatic variable %qE cannot be %<threadprivate%>", v);
+ else if (! COMPLETE_TYPE_P (complete_type (TREE_TYPE (v))))
+ error ("%<threadprivate%> %qE has incomplete type", v);
+ else if (TREE_STATIC (v) && TYPE_P (CP_DECL_CONTEXT (v))
+ && CP_DECL_CONTEXT (v) != current_class_type)
+ error ("%<threadprivate%> %qE directive not "
+ "in %qT definition", v, CP_DECL_CONTEXT (v));
+ else
+ {
+ /* Allocate a LANG_SPECIFIC structure for V, if needed. */
+ if (DECL_LANG_SPECIFIC (v) == NULL)
+ {
+ retrofit_lang_decl (v);
+
+ /* Make sure that DECL_DISCRIMINATOR_P continues to be true
+ after the allocation of the lang_decl structure. */
+ if (DECL_DISCRIMINATOR_P (v))
+ DECL_LANG_SPECIFIC (v)->u.base.u2sel = 1;
+ }
+
+ if (! DECL_THREAD_LOCAL_P (v))
+ {
+ DECL_TLS_MODEL (v) = decl_default_tls_model (v);
+ /* If rtl has been already set for this var, call
+ make_decl_rtl once again, so that encode_section_info
+ has a chance to look at the new decl flags. */
+ if (DECL_RTL_SET_P (v))
+ make_decl_rtl (v);
+ }
+ CP_DECL_THREADPRIVATE_P (v) = 1;
+ }
+ }
+}
+
+/* Build an OpenMP structured block. */
+
+tree
+begin_omp_structured_block (void)
+{
+ return do_pushlevel (sk_omp);
+}
+
+tree
+finish_omp_structured_block (tree block)
+{
+ return do_poplevel (block);
+}
+
+/* Similarly, except force the retention of the BLOCK. */
+
+tree
+begin_omp_parallel (void)
+{
+ keep_next_level (true);
+ return begin_omp_structured_block ();
+}
+
+tree
+finish_omp_parallel (tree clauses, tree body)
+{
+ tree stmt;
+
+ body = finish_omp_structured_block (body);
+
+ stmt = make_node (OMP_PARALLEL);
+ TREE_TYPE (stmt) = void_type_node;
+ OMP_PARALLEL_CLAUSES (stmt) = clauses;
+ OMP_PARALLEL_BODY (stmt) = body;
+
+ return add_stmt (stmt);
+}
+
+tree
+begin_omp_task (void)
+{
+ keep_next_level (true);
+ return begin_omp_structured_block ();
+}
+
+tree
+finish_omp_task (tree clauses, tree body)
+{
+ tree stmt;
+
+ body = finish_omp_structured_block (body);
+
+ stmt = make_node (OMP_TASK);
+ TREE_TYPE (stmt) = void_type_node;
+ OMP_TASK_CLAUSES (stmt) = clauses;
+ OMP_TASK_BODY (stmt) = body;
+
+ return add_stmt (stmt);
+}
+
+/* Helper function for finish_omp_for. Convert Ith random access iterator
+ into integral iterator. Return FALSE if successful. */
+
+static bool
+handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
+ tree condv, tree incrv, tree *body,
+ tree *pre_body, tree clauses)
+{
+ tree diff, iter_init, iter_incr = NULL, last;
+ tree incr_var = NULL, orig_pre_body, orig_body, c;
+ tree decl = TREE_VEC_ELT (declv, i);
+ tree init = TREE_VEC_ELT (initv, i);
+ tree cond = TREE_VEC_ELT (condv, i);
+ tree incr = TREE_VEC_ELT (incrv, i);
+ tree iter = decl;
+ location_t elocus = locus;
+
+ if (init && EXPR_HAS_LOCATION (init))
+ elocus = EXPR_LOCATION (init);
+
+ switch (TREE_CODE (cond))
+ {
+ case GT_EXPR:
+ case GE_EXPR:
+ case LT_EXPR:
+ case LE_EXPR:
+ if (TREE_OPERAND (cond, 1) == iter)
+ cond = build2 (swap_tree_comparison (TREE_CODE (cond)),
+ TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0));
+ if (TREE_OPERAND (cond, 0) != iter)
+ cond = error_mark_node;
+ else
+ {
+ tree tem = build_x_binary_op (EXPR_LOCATION (cond),
+ TREE_CODE (cond),
+ iter, ERROR_MARK,
+ TREE_OPERAND (cond, 1), ERROR_MARK,
+ NULL, tf_warning_or_error);
+ if (error_operand_p (tem))
+ return true;
+ }
+ break;
+ default:
+ cond = error_mark_node;
+ break;
+ }
+ if (cond == error_mark_node)
+ {
+ error_at (elocus, "invalid controlling predicate");
+ return true;
+ }
+ diff = build_x_binary_op (elocus, MINUS_EXPR, TREE_OPERAND (cond, 1),
+ ERROR_MARK, iter, ERROR_MARK, NULL,
+ tf_warning_or_error);
+ if (error_operand_p (diff))
+ return true;
+ if (TREE_CODE (TREE_TYPE (diff)) != INTEGER_TYPE)
+ {
+ error_at (elocus, "difference between %qE and %qD does not have integer type",
+ TREE_OPERAND (cond, 1), iter);
+ return true;
+ }
+
+ switch (TREE_CODE (incr))
+ {
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ if (TREE_OPERAND (incr, 0) != iter)
+ {
+ incr = error_mark_node;
+ break;
+ }
+ iter_incr = build_x_unary_op (EXPR_LOCATION (incr),
+ TREE_CODE (incr), iter,
+ tf_warning_or_error);
+ if (error_operand_p (iter_incr))
+ return true;
+ else if (TREE_CODE (incr) == PREINCREMENT_EXPR
+ || TREE_CODE (incr) == POSTINCREMENT_EXPR)
+ incr = integer_one_node;
+ else
+ incr = integer_minus_one_node;
+ break;
+ case MODIFY_EXPR:
+ if (TREE_OPERAND (incr, 0) != iter)
+ incr = error_mark_node;
+ else if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
+ || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
+ {
+ tree rhs = TREE_OPERAND (incr, 1);
+ if (TREE_OPERAND (rhs, 0) == iter)
+ {
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 1)))
+ != INTEGER_TYPE)
+ incr = error_mark_node;
+ else
+ {
+ iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs),
+ iter, TREE_CODE (rhs),
+ TREE_OPERAND (rhs, 1),
+ tf_warning_or_error);
+ if (error_operand_p (iter_incr))
+ return true;
+ incr = TREE_OPERAND (rhs, 1);
+ incr = cp_convert (TREE_TYPE (diff), incr,
+ tf_warning_or_error);
+ if (TREE_CODE (rhs) == MINUS_EXPR)
+ {
+ incr = build1 (NEGATE_EXPR, TREE_TYPE (diff), incr);
+ incr = fold_if_not_in_template (incr);
+ }
+ if (TREE_CODE (incr) != INTEGER_CST
+ && (TREE_CODE (incr) != NOP_EXPR
+ || (TREE_CODE (TREE_OPERAND (incr, 0))
+ != INTEGER_CST)))
+ iter_incr = NULL;
+ }
+ }
+ else if (TREE_OPERAND (rhs, 1) == iter)
+ {
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) != INTEGER_TYPE
+ || TREE_CODE (rhs) != PLUS_EXPR)
+ incr = error_mark_node;
+ else
+ {
+ iter_incr = build_x_binary_op (EXPR_LOCATION (rhs),
+ PLUS_EXPR,
+ TREE_OPERAND (rhs, 0),
+ ERROR_MARK, iter,
+ ERROR_MARK, NULL,
+ tf_warning_or_error);
+ if (error_operand_p (iter_incr))
+ return true;
+ iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs),
+ iter, NOP_EXPR,
+ iter_incr,
+ tf_warning_or_error);
+ if (error_operand_p (iter_incr))
+ return true;
+ incr = TREE_OPERAND (rhs, 0);
+ iter_incr = NULL;
+ }
+ }
+ else
+ incr = error_mark_node;
+ }
+ else
+ incr = error_mark_node;
+ break;
+ default:
+ incr = error_mark_node;
+ break;
+ }
+
+ if (incr == error_mark_node)
+ {
+ error_at (elocus, "invalid increment expression");
+ return true;
+ }
+
+ incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error);
+ for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_DECL (c) == iter)
+ break;
+
+ decl = create_temporary_var (TREE_TYPE (diff));
+ pushdecl (decl);
+ add_decl_expr (decl);
+ last = create_temporary_var (TREE_TYPE (diff));
+ pushdecl (last);
+ add_decl_expr (last);
+ if (c && iter_incr == NULL)
+ {
+ incr_var = create_temporary_var (TREE_TYPE (diff));
+ pushdecl (incr_var);
+ add_decl_expr (incr_var);
+ }
+ gcc_assert (stmts_are_full_exprs_p ());
+
+ orig_pre_body = *pre_body;
+ *pre_body = push_stmt_list ();
+ if (orig_pre_body)
+ add_stmt (orig_pre_body);
+ if (init != NULL)
+ finish_expr_stmt (build_x_modify_expr (elocus,
+ iter, NOP_EXPR, init,
+ tf_warning_or_error));
+ init = build_int_cst (TREE_TYPE (diff), 0);
+ if (c && iter_incr == NULL)
+ {
+ finish_expr_stmt (build_x_modify_expr (elocus,
+ incr_var, NOP_EXPR,
+ incr, tf_warning_or_error));
+ incr = incr_var;
+ iter_incr = build_x_modify_expr (elocus,
+ iter, PLUS_EXPR, incr,
+ tf_warning_or_error);
+ }
+ finish_expr_stmt (build_x_modify_expr (elocus,
+ last, NOP_EXPR, init,
+ tf_warning_or_error));
+ *pre_body = pop_stmt_list (*pre_body);
+
+ cond = cp_build_binary_op (elocus,
+ TREE_CODE (cond), decl, diff,
+ tf_warning_or_error);
+ incr = build_modify_expr (elocus, decl, NULL_TREE, PLUS_EXPR,
+ elocus, incr, NULL_TREE);
+
+ orig_body = *body;
+ *body = push_stmt_list ();
+ iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), decl, last);
+ iter_init = build_x_modify_expr (elocus,
+ iter, PLUS_EXPR, iter_init,
+ tf_warning_or_error);
+ iter_init = build1 (NOP_EXPR, void_type_node, iter_init);
+ finish_expr_stmt (iter_init);
+ finish_expr_stmt (build_x_modify_expr (elocus,
+ last, NOP_EXPR, decl,
+ tf_warning_or_error));
+ add_stmt (orig_body);
+ *body = pop_stmt_list (*body);
+
+ if (c)
+ {
+ OMP_CLAUSE_LASTPRIVATE_STMT (c) = push_stmt_list ();
+ finish_expr_stmt (iter_incr);
+ OMP_CLAUSE_LASTPRIVATE_STMT (c)
+ = pop_stmt_list (OMP_CLAUSE_LASTPRIVATE_STMT (c));
+ }
+
+ TREE_VEC_ELT (declv, i) = decl;
+ TREE_VEC_ELT (initv, i) = init;
+ TREE_VEC_ELT (condv, i) = cond;
+ TREE_VEC_ELT (incrv, i) = incr;
+
+ return false;
+}
+
+/* Build and validate an OMP_FOR statement. CLAUSES, BODY, COND, INCR
+ are directly for their associated operands in the statement. DECL
+ and INIT are a combo; if DECL is NULL then INIT ought to be a
+ MODIFY_EXPR, and the DECL should be extracted. PRE_BODY are
+ optional statements that need to go before the loop into its
+ sk_omp scope. */
+
+tree
+finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
+ tree condv, tree incrv, tree body, tree pre_body, tree clauses)
+{
+ tree omp_for = NULL, orig_incr = NULL;
+ tree decl, init, cond, incr;
+ location_t elocus;
+ int i;
+
+ gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
+ gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
+ gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
+ for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
+ {
+ decl = TREE_VEC_ELT (declv, i);
+ init = TREE_VEC_ELT (initv, i);
+ cond = TREE_VEC_ELT (condv, i);
+ incr = TREE_VEC_ELT (incrv, i);
+ elocus = locus;
+
+ if (decl == NULL)
+ {
+ if (init != NULL)
+ switch (TREE_CODE (init))
+ {
+ case MODIFY_EXPR:
+ decl = TREE_OPERAND (init, 0);
+ init = TREE_OPERAND (init, 1);
+ break;
+ case MODOP_EXPR:
+ if (TREE_CODE (TREE_OPERAND (init, 1)) == NOP_EXPR)
+ {
+ decl = TREE_OPERAND (init, 0);
+ init = TREE_OPERAND (init, 2);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (decl == NULL)
+ {
+ error_at (locus,
+ "expected iteration declaration or initialization");
+ return NULL;
+ }
+ }
+
+ if (init && EXPR_HAS_LOCATION (init))
+ elocus = EXPR_LOCATION (init);
+
+ if (cond == NULL)
+ {
+ error_at (elocus, "missing controlling predicate");
+ return NULL;
+ }
+
+ if (incr == NULL)
+ {
+ error_at (elocus, "missing increment expression");
+ return NULL;
+ }
+
+ TREE_VEC_ELT (declv, i) = decl;
+ TREE_VEC_ELT (initv, i) = init;
+ }
+
+ if (dependent_omp_for_p (declv, initv, condv, incrv))
+ {
+ tree stmt;
+
+ stmt = make_node (code);
+
+ for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
+ {
+ /* This is really just a place-holder. We'll be decomposing this
+ again and going through the cp_build_modify_expr path below when
+ we instantiate the thing. */
+ TREE_VEC_ELT (initv, i)
+ = build2 (MODIFY_EXPR, void_type_node, TREE_VEC_ELT (declv, i),
+ TREE_VEC_ELT (initv, i));
+ }
+
+ TREE_TYPE (stmt) = void_type_node;
+ OMP_FOR_INIT (stmt) = initv;
+ OMP_FOR_COND (stmt) = condv;
+ OMP_FOR_INCR (stmt) = incrv;
+ OMP_FOR_BODY (stmt) = body;
+ OMP_FOR_PRE_BODY (stmt) = pre_body;
+ OMP_FOR_CLAUSES (stmt) = clauses;
+
+ SET_EXPR_LOCATION (stmt, locus);
+ return add_stmt (stmt);
+ }
+
+ if (processing_template_decl)
+ orig_incr = make_tree_vec (TREE_VEC_LENGTH (incrv));
+
+ for (i = 0; i < TREE_VEC_LENGTH (declv); )
+ {
+ decl = TREE_VEC_ELT (declv, i);
+ init = TREE_VEC_ELT (initv, i);
+ cond = TREE_VEC_ELT (condv, i);
+ incr = TREE_VEC_ELT (incrv, i);
+ if (orig_incr)
+ TREE_VEC_ELT (orig_incr, i) = incr;
+ elocus = locus;
+
+ if (init && EXPR_HAS_LOCATION (init))
+ elocus = EXPR_LOCATION (init);
+
+ if (!DECL_P (decl))
+ {
+ error_at (elocus, "expected iteration declaration or initialization");
+ return NULL;
+ }
+
+ if (incr && TREE_CODE (incr) == MODOP_EXPR)
+ {
+ if (orig_incr)
+ TREE_VEC_ELT (orig_incr, i) = incr;
+ incr = cp_build_modify_expr (TREE_OPERAND (incr, 0),
+ TREE_CODE (TREE_OPERAND (incr, 1)),
+ TREE_OPERAND (incr, 2),
+ tf_warning_or_error);
+ }
+
+ if (CLASS_TYPE_P (TREE_TYPE (decl)))
+ {
+ if (code == OMP_SIMD)
+ {
+ error_at (elocus, "%<#pragma omp simd%> used with class "
+ "iteration variable %qE", decl);
+ return NULL;
+ }
+ if (handle_omp_for_class_iterator (i, locus, declv, initv, condv,
+ incrv, &body, &pre_body, clauses))
+ return NULL;
+ continue;
+ }
+
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
+ && !TYPE_PTR_P (TREE_TYPE (decl)))
+ {
+ error_at (elocus, "invalid type for iteration variable %qE", decl);
+ return NULL;
+ }
+
+ if (!processing_template_decl)
+ {
+ init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
+ init = cp_build_modify_expr (decl, NOP_EXPR, init, tf_warning_or_error);
+ }
+ else
+ init = build2 (MODIFY_EXPR, void_type_node, decl, init);
+ if (cond
+ && TREE_SIDE_EFFECTS (cond)
+ && COMPARISON_CLASS_P (cond)
+ && !processing_template_decl)
+ {
+ tree t = TREE_OPERAND (cond, 0);
+ if (TREE_SIDE_EFFECTS (t)
+ && t != decl
+ && (TREE_CODE (t) != NOP_EXPR
+ || TREE_OPERAND (t, 0) != decl))
+ TREE_OPERAND (cond, 0)
+ = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+
+ t = TREE_OPERAND (cond, 1);
+ if (TREE_SIDE_EFFECTS (t)
+ && t != decl
+ && (TREE_CODE (t) != NOP_EXPR
+ || TREE_OPERAND (t, 0) != decl))
+ TREE_OPERAND (cond, 1)
+ = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
+ if (decl == error_mark_node || init == error_mark_node)
+ return NULL;
+
+ TREE_VEC_ELT (declv, i) = decl;
+ TREE_VEC_ELT (initv, i) = init;
+ TREE_VEC_ELT (condv, i) = cond;
+ TREE_VEC_ELT (incrv, i) = incr;
+ i++;
+ }
+
+ if (IS_EMPTY_STMT (pre_body))
+ pre_body = NULL;
+
+ omp_for = c_finish_omp_for (locus, code, declv, initv, condv, incrv,
+ body, pre_body);
+
+ if (omp_for == NULL)
+ return NULL;
+
+ for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
+ {
+ decl = TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i), 0);
+ incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i);
+
+ if (TREE_CODE (incr) != MODIFY_EXPR)
+ continue;
+
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (incr, 1))
+ && BINARY_CLASS_P (TREE_OPERAND (incr, 1))
+ && !processing_template_decl)
+ {
+ tree t = TREE_OPERAND (TREE_OPERAND (incr, 1), 0);
+ if (TREE_SIDE_EFFECTS (t)
+ && t != decl
+ && (TREE_CODE (t) != NOP_EXPR
+ || TREE_OPERAND (t, 0) != decl))
+ TREE_OPERAND (TREE_OPERAND (incr, 1), 0)
+ = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+
+ t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
+ if (TREE_SIDE_EFFECTS (t)
+ && t != decl
+ && (TREE_CODE (t) != NOP_EXPR
+ || TREE_OPERAND (t, 0) != decl))
+ TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
+ = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
+
+ if (orig_incr)
+ TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i) = TREE_VEC_ELT (orig_incr, i);
+ }
+ if (omp_for != NULL)
+ OMP_FOR_CLAUSES (omp_for) = clauses;
+ return omp_for;
+}
+
+void
+finish_omp_atomic (enum tree_code code, enum tree_code opcode, tree lhs,
+ tree rhs, tree v, tree lhs1, tree rhs1, bool seq_cst)
+{
+ tree orig_lhs;
+ tree orig_rhs;
+ tree orig_v;
+ tree orig_lhs1;
+ tree orig_rhs1;
+ bool dependent_p;
+ tree stmt;
+
+ orig_lhs = lhs;
+ orig_rhs = rhs;
+ orig_v = v;
+ orig_lhs1 = lhs1;
+ orig_rhs1 = rhs1;
+ dependent_p = false;
+ stmt = NULL_TREE;
+
+ /* Even in a template, we can detect invalid uses of the atomic
+ pragma if neither LHS nor RHS is type-dependent. */
+ if (processing_template_decl)
+ {
+ dependent_p = (type_dependent_expression_p (lhs)
+ || (rhs && type_dependent_expression_p (rhs))
+ || (v && type_dependent_expression_p (v))
+ || (lhs1 && type_dependent_expression_p (lhs1))
+ || (rhs1 && type_dependent_expression_p (rhs1)));
+ if (!dependent_p)
+ {
+ lhs = build_non_dependent_expr (lhs);
+ if (rhs)
+ rhs = build_non_dependent_expr (rhs);
+ if (v)
+ v = build_non_dependent_expr (v);
+ if (lhs1)
+ lhs1 = build_non_dependent_expr (lhs1);
+ if (rhs1)
+ rhs1 = build_non_dependent_expr (rhs1);
+ }
+ }
+ if (!dependent_p)
+ {
+ bool swapped = false;
+ if (rhs1 && cp_tree_equal (lhs, rhs))
+ {
+ tree tem = rhs;
+ rhs = rhs1;
+ rhs1 = tem;
+ swapped = !commutative_tree_code (opcode);
+ }
+ if (rhs1 && !cp_tree_equal (lhs, rhs1))
+ {
+ if (code == OMP_ATOMIC)
+ error ("%<#pragma omp atomic update%> uses two different "
+ "expressions for memory");
+ else
+ error ("%<#pragma omp atomic capture%> uses two different "
+ "expressions for memory");
+ return;
+ }
+ if (lhs1 && !cp_tree_equal (lhs, lhs1))
+ {
+ if (code == OMP_ATOMIC)
+ error ("%<#pragma omp atomic update%> uses two different "
+ "expressions for memory");
+ else
+ error ("%<#pragma omp atomic capture%> uses two different "
+ "expressions for memory");
+ return;
+ }
+ stmt = c_finish_omp_atomic (input_location, code, opcode, lhs, rhs,
+ v, lhs1, rhs1, swapped, seq_cst);
+ if (stmt == error_mark_node)
+ return;
+ }
+ if (processing_template_decl)
+ {
+ if (code == OMP_ATOMIC_READ)
+ {
+ stmt = build_min_nt_loc (EXPR_LOCATION (orig_lhs),
+ OMP_ATOMIC_READ, orig_lhs);
+ OMP_ATOMIC_SEQ_CST (stmt) = seq_cst;
+ stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
+ }
+ else
+ {
+ if (opcode == NOP_EXPR)
+ stmt = build2 (MODIFY_EXPR, void_type_node, orig_lhs, orig_rhs);
+ else
+ stmt = build2 (opcode, void_type_node, orig_lhs, orig_rhs);
+ if (orig_rhs1)
+ stmt = build_min_nt_loc (EXPR_LOCATION (orig_rhs1),
+ COMPOUND_EXPR, orig_rhs1, stmt);
+ if (code != OMP_ATOMIC)
+ {
+ stmt = build_min_nt_loc (EXPR_LOCATION (orig_lhs1),
+ code, orig_lhs1, stmt);
+ OMP_ATOMIC_SEQ_CST (stmt) = seq_cst;
+ stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
+ }
+ }
+ stmt = build2 (OMP_ATOMIC, void_type_node, integer_zero_node, stmt);
+ OMP_ATOMIC_SEQ_CST (stmt) = seq_cst;
+ }
+ finish_expr_stmt (stmt);
+}
+
+void
+finish_omp_barrier (void)
+{
+ tree fn = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
+ vec<tree, va_gc> *vec = make_tree_vector ();
+ tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+ release_tree_vector (vec);
+ finish_expr_stmt (stmt);
+}
+
+void
+finish_omp_flush (void)
+{
+ tree fn = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
+ vec<tree, va_gc> *vec = make_tree_vector ();
+ tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+ release_tree_vector (vec);
+ finish_expr_stmt (stmt);
+}
+
+void
+finish_omp_taskwait (void)
+{
+ tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
+ vec<tree, va_gc> *vec = make_tree_vector ();
+ tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+ release_tree_vector (vec);
+ finish_expr_stmt (stmt);
+}
+
+void
+finish_omp_taskyield (void)
+{
+ tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
+ vec<tree, va_gc> *vec = make_tree_vector ();
+ tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+ release_tree_vector (vec);
+ finish_expr_stmt (stmt);
+}
+
+void
+finish_omp_cancel (tree clauses)
+{
+ tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
+ int mask = 0;
+ if (find_omp_clause (clauses, OMP_CLAUSE_PARALLEL))
+ mask = 1;
+ else if (find_omp_clause (clauses, OMP_CLAUSE_FOR))
+ mask = 2;
+ else if (find_omp_clause (clauses, OMP_CLAUSE_SECTIONS))
+ mask = 4;
+ else if (find_omp_clause (clauses, OMP_CLAUSE_TASKGROUP))
+ mask = 8;
+ else
+ {
+ error ("%<#pragma omp cancel must specify one of "
+ "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
+ return;
+ }
+ vec<tree, va_gc> *vec = make_tree_vector ();
+ tree ifc = find_omp_clause (clauses, OMP_CLAUSE_IF);
+ if (ifc != NULL_TREE)
+ {
+ tree type = TREE_TYPE (OMP_CLAUSE_IF_EXPR (ifc));
+ ifc = fold_build2_loc (OMP_CLAUSE_LOCATION (ifc), NE_EXPR,
+ boolean_type_node, OMP_CLAUSE_IF_EXPR (ifc),
+ build_zero_cst (type));
+ }
+ else
+ ifc = boolean_true_node;
+ vec->quick_push (build_int_cst (integer_type_node, mask));
+ vec->quick_push (ifc);
+ tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+ release_tree_vector (vec);
+ finish_expr_stmt (stmt);
+}
+
+void
+finish_omp_cancellation_point (tree clauses)
+{
+ tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCELLATION_POINT);
+ int mask = 0;
+ if (find_omp_clause (clauses, OMP_CLAUSE_PARALLEL))
+ mask = 1;
+ else if (find_omp_clause (clauses, OMP_CLAUSE_FOR))
+ mask = 2;
+ else if (find_omp_clause (clauses, OMP_CLAUSE_SECTIONS))
+ mask = 4;
+ else if (find_omp_clause (clauses, OMP_CLAUSE_TASKGROUP))
+ mask = 8;
+ else
+ {
+ error ("%<#pragma omp cancellation point must specify one of "
+ "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
+ return;
+ }
+ vec<tree, va_gc> *vec
+ = make_tree_vector_single (build_int_cst (integer_type_node, mask));
+ tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+ release_tree_vector (vec);
+ finish_expr_stmt (stmt);
+}
+
+/* Begin a __transaction_atomic or __transaction_relaxed statement.
+ If PCOMPOUND is non-null, this is for a function-transaction-block, and we
+ should create an extra compound stmt. */
+
+tree
+begin_transaction_stmt (location_t loc, tree *pcompound, int flags)
+{
+ tree r;
+
+ if (pcompound)
+ *pcompound = begin_compound_stmt (0);
+
+ r = build_stmt (loc, TRANSACTION_EXPR, NULL_TREE);
+
+ /* Only add the statement to the function if support enabled. */
+ if (flag_tm)
+ add_stmt (r);
+ else
+ error_at (loc, ((flags & TM_STMT_ATTR_RELAXED) != 0
+ ? G_("%<__transaction_relaxed%> without "
+ "transactional memory support enabled")
+ : G_("%<__transaction_atomic%> without "
+ "transactional memory support enabled")));
+
+ TRANSACTION_EXPR_BODY (r) = push_stmt_list ();
+ TREE_SIDE_EFFECTS (r) = 1;
+ return r;
+}
+
+/* End a __transaction_atomic or __transaction_relaxed statement.
+ If COMPOUND_STMT is non-null, this is for a function-transaction-block,
+ and we should end the compound. If NOEX is non-NULL, we wrap the body in
+ a MUST_NOT_THROW_EXPR with NOEX as condition. */
+
+void
+finish_transaction_stmt (tree stmt, tree compound_stmt, int flags, tree noex)
+{
+ TRANSACTION_EXPR_BODY (stmt) = pop_stmt_list (TRANSACTION_EXPR_BODY (stmt));
+ TRANSACTION_EXPR_OUTER (stmt) = (flags & TM_STMT_ATTR_OUTER) != 0;
+ TRANSACTION_EXPR_RELAXED (stmt) = (flags & TM_STMT_ATTR_RELAXED) != 0;
+ TRANSACTION_EXPR_IS_STMT (stmt) = 1;
+
+ /* noexcept specifications are not allowed for function transactions. */
+ gcc_assert (!(noex && compound_stmt));
+ if (noex)
+ {
+ tree body = build_must_not_throw_expr (TRANSACTION_EXPR_BODY (stmt),
+ noex);
+ /* This may not be true when the STATEMENT_LIST is empty. */
+ if (EXPR_P (body))
+ SET_EXPR_LOCATION (body, EXPR_LOCATION (TRANSACTION_EXPR_BODY (stmt)));
+ TREE_SIDE_EFFECTS (body) = 1;
+ TRANSACTION_EXPR_BODY (stmt) = body;
+ }
+
+ if (compound_stmt)
+ finish_compound_stmt (compound_stmt);
+}
+
+/* Build a __transaction_atomic or __transaction_relaxed expression. If
+ NOEX is non-NULL, we wrap the body in a MUST_NOT_THROW_EXPR with NOEX as
+ condition. */
+
+tree
+build_transaction_expr (location_t loc, tree expr, int flags, tree noex)
+{
+ tree ret;
+ if (noex)
+ {
+ expr = build_must_not_throw_expr (expr, noex);
+ if (EXPR_P (expr))
+ SET_EXPR_LOCATION (expr, loc);
+ TREE_SIDE_EFFECTS (expr) = 1;
+ }
+ ret = build1 (TRANSACTION_EXPR, TREE_TYPE (expr), expr);
+ if (flags & TM_STMT_ATTR_RELAXED)
+ TRANSACTION_EXPR_RELAXED (ret) = 1;
+ TREE_SIDE_EFFECTS (ret) = 1;
+ SET_EXPR_LOCATION (ret, loc);
+ return ret;
+}
+
+void
+init_cp_semantics (void)
+{
+}
+
+/* Build a STATIC_ASSERT for a static assertion with the condition
+ CONDITION and the message text MESSAGE. LOCATION is the location
+ of the static assertion in the source code. When MEMBER_P, this
+ static assertion is a member of a class. */
+void
+finish_static_assert (tree condition, tree message, location_t location,
+ bool member_p)
+{
+ if (message == NULL_TREE
+ || message == error_mark_node
+ || condition == NULL_TREE
+ || condition == error_mark_node)
+ return;
+
+ if (check_for_bare_parameter_packs (condition))
+ condition = error_mark_node;
+
+ if (type_dependent_expression_p (condition)
+ || value_dependent_expression_p (condition))
+ {
+ /* We're in a template; build a STATIC_ASSERT and put it in
+ the right place. */
+ tree assertion;
+
+ assertion = make_node (STATIC_ASSERT);
+ STATIC_ASSERT_CONDITION (assertion) = condition;
+ STATIC_ASSERT_MESSAGE (assertion) = message;
+ STATIC_ASSERT_SOURCE_LOCATION (assertion) = location;
+
+ if (member_p)
+ maybe_add_class_template_decl_list (current_class_type,
+ assertion,
+ /*friend_p=*/0);
+ else
+ add_stmt (assertion);
+
+ return;
+ }
+
+ /* Fold the expression and convert it to a boolean value. */
+ condition = fold_non_dependent_expr (condition);
+ condition = cp_convert (boolean_type_node, condition, tf_warning_or_error);
+ condition = maybe_constant_value (condition);
+
+ if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition))
+ /* Do nothing; the condition is satisfied. */
+ ;
+ else
+ {
+ location_t saved_loc = input_location;
+
+ input_location = location;
+ if (TREE_CODE (condition) == INTEGER_CST
+ && integer_zerop (condition))
+ /* Report the error. */
+ error ("static assertion failed: %s", TREE_STRING_POINTER (message));
+ else if (condition && condition != error_mark_node)
+ {
+ error ("non-constant condition for static assertion");
+ if (require_potential_rvalue_constant_expression (condition))
+ cxx_constant_value (condition);
+ }
+ input_location = saved_loc;
+ }
+}
+
+/* Implements the C++0x decltype keyword. Returns the type of EXPR,
+ suitable for use as a type-specifier.
+
+ ID_EXPRESSION_OR_MEMBER_ACCESS_P is true when EXPR was parsed as an
+ id-expression or a class member access, FALSE when it was parsed as
+ a full expression. */
+
+tree
+finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
+ tsubst_flags_t complain)
+{
+ tree type = NULL_TREE;
+
+ if (!expr || error_operand_p (expr))
+ return error_mark_node;
+
+ if (TYPE_P (expr)
+ || TREE_CODE (expr) == TYPE_DECL
+ || (TREE_CODE (expr) == BIT_NOT_EXPR
+ && TYPE_P (TREE_OPERAND (expr, 0))))
+ {
+ if (complain & tf_error)
+ error ("argument to decltype must be an expression");
+ return error_mark_node;
+ }
+
+ /* Depending on the resolution of DR 1172, we may later need to distinguish
+ instantiation-dependent but not type-dependent expressions so that, say,
+ A<decltype(sizeof(T))>::U doesn't require 'typename'. */
+ if (instantiation_dependent_expression_p (expr))
+ {
+ type = cxx_make_type (DECLTYPE_TYPE);
+ DECLTYPE_TYPE_EXPR (type) = expr;
+ DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)
+ = id_expression_or_member_access_p;
+ SET_TYPE_STRUCTURAL_EQUALITY (type);
+
+ return type;
+ }
+
+ /* The type denoted by decltype(e) is defined as follows: */
+
+ expr = resolve_nondeduced_context (expr);
+
+ if (invalid_nonstatic_memfn_p (expr, complain))
+ return error_mark_node;
+
+ if (type_unknown_p (expr))
+ {
+ if (complain & tf_error)
+ error ("decltype cannot resolve address of overloaded function");
+ return error_mark_node;
+ }
+
+ /* To get the size of a static data member declared as an array of
+ unknown bound, we need to instantiate it. */
+ if (VAR_P (expr)
+ && VAR_HAD_UNKNOWN_BOUND (expr)
+ && DECL_TEMPLATE_INSTANTIATION (expr))
+ instantiate_decl (expr, /*defer_ok*/true, /*expl_inst_mem*/false);
+
+ if (id_expression_or_member_access_p)
+ {
+ /* If e is an id-expression or a class member access (5.2.5
+ [expr.ref]), decltype(e) is defined as the type of the entity
+ named by e. If there is no such entity, or e names a set of
+ overloaded functions, the program is ill-formed. */
+ if (identifier_p (expr))
+ expr = lookup_name (expr);
+
+ if (INDIRECT_REF_P (expr))
+ /* This can happen when the expression is, e.g., "a.b". Just
+ look at the underlying operand. */
+ expr = TREE_OPERAND (expr, 0);
+
+ if (TREE_CODE (expr) == OFFSET_REF
+ || TREE_CODE (expr) == MEMBER_REF
+ || TREE_CODE (expr) == SCOPE_REF)
+ /* We're only interested in the field itself. If it is a
+ BASELINK, we will need to see through it in the next
+ step. */
+ expr = TREE_OPERAND (expr, 1);
+
+ if (BASELINK_P (expr))
+ /* See through BASELINK nodes to the underlying function. */
+ expr = BASELINK_FUNCTIONS (expr);
+
+ switch (TREE_CODE (expr))
+ {
+ case FIELD_DECL:
+ if (DECL_BIT_FIELD_TYPE (expr))
+ {
+ type = DECL_BIT_FIELD_TYPE (expr);
+ break;
+ }
+ /* Fall through for fields that aren't bitfields. */
+
+ case FUNCTION_DECL:
+ case VAR_DECL:
+ case CONST_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ case TEMPLATE_PARM_INDEX:
+ expr = mark_type_use (expr);
+ type = TREE_TYPE (expr);
+ break;
+
+ case ERROR_MARK:
+ type = error_mark_node;
+ break;
+
+ case COMPONENT_REF:
+ case COMPOUND_EXPR:
+ mark_type_use (expr);
+ type = is_bitfield_expr_with_lowered_type (expr);
+ if (!type)
+ type = TREE_TYPE (TREE_OPERAND (expr, 1));
+ break;
+
+ case BIT_FIELD_REF:
+ gcc_unreachable ();
+
+ case INTEGER_CST:
+ case PTRMEM_CST:
+ /* We can get here when the id-expression refers to an
+ enumerator or non-type template parameter. */
+ type = TREE_TYPE (expr);
+ break;
+
+ default:
+ /* Handle instantiated template non-type arguments. */
+ type = TREE_TYPE (expr);
+ break;
+ }
+ }
+ else
+ {
+ /* Within a lambda-expression:
+
+ Every occurrence of decltype((x)) where x is a possibly
+ parenthesized id-expression that names an entity of
+ automatic storage duration is treated as if x were
+ transformed into an access to a corresponding data member
+ of the closure type that would have been declared if x
+ were a use of the denoted entity. */
+ if (outer_automatic_var_p (expr)
+ && current_function_decl
+ && LAMBDA_FUNCTION_P (current_function_decl))
+ type = capture_decltype (expr);
+ else if (error_operand_p (expr))
+ type = error_mark_node;
+ else if (expr == current_class_ptr)
+ /* If the expression is just "this", we want the
+ cv-unqualified pointer for the "this" type. */
+ type = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
+ else
+ {
+ /* Otherwise, where T is the type of e, if e is an lvalue,
+ decltype(e) is defined as T&; if an xvalue, T&&; otherwise, T. */
+ cp_lvalue_kind clk = lvalue_kind (expr);
+ type = unlowered_expr_type (expr);
+ gcc_assert (TREE_CODE (type) != REFERENCE_TYPE);
+
+ /* For vector types, pick a non-opaque variant. */
+ if (TREE_CODE (type) == VECTOR_TYPE)
+ type = strip_typedefs (type);
+
+ if (clk != clk_none && !(clk & clk_class))
+ type = cp_build_reference_type (type, (clk & clk_rvalueref));
+ }
+ }
+
+ if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type)
+ && (flag_iso || warn_vla > 0))
+ {
+ if (complain & tf_warning_or_error)
+ pedwarn (input_location, OPT_Wvla,
+ "taking decltype of array of runtime bound");
+ else
+ return error_mark_node;
+ }
+
+ return type;
+}
+
+/* Called from trait_expr_value to evaluate either __has_nothrow_assign or
+ __has_nothrow_copy, depending on assign_p. */
+
+static bool
+classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p)
+{
+ tree fns;
+
+ if (assign_p)
+ {
+ int ix;
+ ix = lookup_fnfields_1 (type, ansi_assopname (NOP_EXPR));
+ if (ix < 0)
+ return false;
+ fns = (*CLASSTYPE_METHOD_VEC (type))[ix];
+ }
+ else if (TYPE_HAS_COPY_CTOR (type))
+ {
+ /* If construction of the copy constructor was postponed, create
+ it now. */
+ if (CLASSTYPE_LAZY_COPY_CTOR (type))
+ lazily_declare_fn (sfk_copy_constructor, type);
+ if (CLASSTYPE_LAZY_MOVE_CTOR (type))
+ lazily_declare_fn (sfk_move_constructor, type);
+ fns = CLASSTYPE_CONSTRUCTORS (type);
+ }
+ else
+ return false;
+
+ for (; fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ if (assign_p)
+ {
+ if (copy_fn_p (fn) == 0)
+ continue;
+ }
+ else if (copy_fn_p (fn) <= 0)
+ continue;
+
+ maybe_instantiate_noexcept (fn);
+ if (!TYPE_NOTHROW_P (TREE_TYPE (fn)))
+ return false;
+ }
+
+ return true;
+}
+
+/* Actually evaluates the trait. */
+
+static bool
+trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
+{
+ enum tree_code type_code1;
+ tree t;
+
+ type_code1 = TREE_CODE (type1);
+
+ switch (kind)
+ {
+ case CPTK_HAS_NOTHROW_ASSIGN:
+ type1 = strip_array_types (type1);
+ return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
+ && (trait_expr_value (CPTK_HAS_TRIVIAL_ASSIGN, type1, type2)
+ || (CLASS_TYPE_P (type1)
+ && classtype_has_nothrow_assign_or_copy_p (type1,
+ true))));
+
+ case CPTK_HAS_TRIVIAL_ASSIGN:
+ /* ??? The standard seems to be missing the "or array of such a class
+ type" wording for this trait. */
+ type1 = strip_array_types (type1);
+ return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
+ && (trivial_type_p (type1)
+ || (CLASS_TYPE_P (type1)
+ && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
+
+ case CPTK_HAS_NOTHROW_CONSTRUCTOR:
+ type1 = strip_array_types (type1);
+ return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
+ || (CLASS_TYPE_P (type1)
+ && (t = locate_ctor (type1))
+ && (maybe_instantiate_noexcept (t),
+ TYPE_NOTHROW_P (TREE_TYPE (t)))));
+
+ case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
+ type1 = strip_array_types (type1);
+ return (trivial_type_p (type1)
+ || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
+
+ case CPTK_HAS_NOTHROW_COPY:
+ type1 = strip_array_types (type1);
+ return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
+ || (CLASS_TYPE_P (type1)
+ && classtype_has_nothrow_assign_or_copy_p (type1, false)));
+
+ case CPTK_HAS_TRIVIAL_COPY:
+ /* ??? The standard seems to be missing the "or array of such a class
+ type" wording for this trait. */
+ type1 = strip_array_types (type1);
+ return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
+ || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_COPY_CTOR (type1)));
+
+ case CPTK_HAS_TRIVIAL_DESTRUCTOR:
+ type1 = strip_array_types (type1);
+ return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
+ || (CLASS_TYPE_P (type1)
+ && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
+
+ case CPTK_HAS_VIRTUAL_DESTRUCTOR:
+ return type_has_virtual_destructor (type1);
+
+ case CPTK_IS_ABSTRACT:
+ return (ABSTRACT_CLASS_TYPE_P (type1));
+
+ case CPTK_IS_BASE_OF:
+ return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
+ && (same_type_ignoring_top_level_qualifiers_p (type1, type2)
+ || DERIVED_FROM_P (type1, type2)));
+
+ case CPTK_IS_CLASS:
+ return (NON_UNION_CLASS_TYPE_P (type1));
+
+ case CPTK_IS_CONVERTIBLE_TO:
+ /* TODO */
+ return false;
+
+ case CPTK_IS_EMPTY:
+ return (NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1));
+
+ case CPTK_IS_ENUM:
+ return (type_code1 == ENUMERAL_TYPE);
+
+ case CPTK_IS_FINAL:
+ return (CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1));
+
+ case CPTK_IS_LITERAL_TYPE:
+ return (literal_type_p (type1));
+
+ case CPTK_IS_POD:
+ return (pod_type_p (type1));
+
+ case CPTK_IS_POLYMORPHIC:
+ return (CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1));
+
+ case CPTK_IS_STD_LAYOUT:
+ return (std_layout_type_p (type1));
+
+ case CPTK_IS_TRIVIAL:
+ return (trivial_type_p (type1));
+
+ case CPTK_IS_UNION:
+ return (type_code1 == UNION_TYPE);
+
+ default:
+ gcc_unreachable ();
+ return false;
+ }
+}
+
+/* If TYPE is an array of unknown bound, or (possibly cv-qualified)
+ void, or a complete type, returns it, otherwise NULL_TREE. */
+
+static tree
+check_trait_type (tree type)
+{
+ if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)
+ && COMPLETE_TYPE_P (TREE_TYPE (type)))
+ return type;
+
+ if (VOID_TYPE_P (type))
+ return type;
+
+ return complete_type_or_else (strip_array_types (type), NULL_TREE);
+}
+
+/* Process a trait expression. */
+
+tree
+finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
+{
+ gcc_assert (kind == CPTK_HAS_NOTHROW_ASSIGN
+ || kind == CPTK_HAS_NOTHROW_CONSTRUCTOR
+ || kind == CPTK_HAS_NOTHROW_COPY
+ || kind == CPTK_HAS_TRIVIAL_ASSIGN
+ || kind == CPTK_HAS_TRIVIAL_CONSTRUCTOR
+ || kind == CPTK_HAS_TRIVIAL_COPY
+ || kind == CPTK_HAS_TRIVIAL_DESTRUCTOR
+ || kind == CPTK_HAS_VIRTUAL_DESTRUCTOR
+ || kind == CPTK_IS_ABSTRACT
+ || kind == CPTK_IS_BASE_OF
+ || kind == CPTK_IS_CLASS
+ || kind == CPTK_IS_CONVERTIBLE_TO
+ || kind == CPTK_IS_EMPTY
+ || kind == CPTK_IS_ENUM
+ || kind == CPTK_IS_FINAL
+ || kind == CPTK_IS_LITERAL_TYPE
+ || kind == CPTK_IS_POD
+ || kind == CPTK_IS_POLYMORPHIC
+ || kind == CPTK_IS_STD_LAYOUT
+ || kind == CPTK_IS_TRIVIAL
+ || kind == CPTK_IS_UNION);
+
+ if (kind == CPTK_IS_CONVERTIBLE_TO)
+ {
+ sorry ("__is_convertible_to");
+ return error_mark_node;
+ }
+
+ if (type1 == error_mark_node
+ || ((kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
+ && type2 == error_mark_node))
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ tree trait_expr = make_node (TRAIT_EXPR);
+ TREE_TYPE (trait_expr) = boolean_type_node;
+ TRAIT_EXPR_TYPE1 (trait_expr) = type1;
+ TRAIT_EXPR_TYPE2 (trait_expr) = type2;
+ TRAIT_EXPR_KIND (trait_expr) = kind;
+ return trait_expr;
+ }
+
+ switch (kind)
+ {
+ case CPTK_HAS_NOTHROW_ASSIGN:
+ case CPTK_HAS_TRIVIAL_ASSIGN:
+ case CPTK_HAS_NOTHROW_CONSTRUCTOR:
+ case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
+ case CPTK_HAS_NOTHROW_COPY:
+ case CPTK_HAS_TRIVIAL_COPY:
+ case CPTK_HAS_TRIVIAL_DESTRUCTOR:
+ case CPTK_HAS_VIRTUAL_DESTRUCTOR:
+ case CPTK_IS_ABSTRACT:
+ case CPTK_IS_EMPTY:
+ case CPTK_IS_FINAL:
+ case CPTK_IS_LITERAL_TYPE:
+ case CPTK_IS_POD:
+ case CPTK_IS_POLYMORPHIC:
+ case CPTK_IS_STD_LAYOUT:
+ case CPTK_IS_TRIVIAL:
+ if (!check_trait_type (type1))
+ return error_mark_node;
+ break;
+
+ case CPTK_IS_BASE_OF:
+ if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
+ && !same_type_ignoring_top_level_qualifiers_p (type1, type2)
+ && !complete_type_or_else (type2, NULL_TREE))
+ /* We already issued an error. */
+ return error_mark_node;
+ break;
+
+ case CPTK_IS_CLASS:
+ case CPTK_IS_ENUM:
+ case CPTK_IS_UNION:
+ break;
+
+ case CPTK_IS_CONVERTIBLE_TO:
+ default:
+ gcc_unreachable ();
+ }
+
+ return (trait_expr_value (kind, type1, type2)
+ ? boolean_true_node : boolean_false_node);
+}
+
+/* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64,
+ which is ignored for C++. */
+
+void
+set_float_const_decimal64 (void)
+{
+}
+
+void
+clear_float_const_decimal64 (void)
+{
+}
+
+bool
+float_const_decimal64_p (void)
+{
+ return 0;
+}
+
+
+/* Return true if T is a literal type. */
+
+bool
+literal_type_p (tree t)
+{
+ if (SCALAR_TYPE_P (t)
+ || TREE_CODE (t) == VECTOR_TYPE
+ || TREE_CODE (t) == REFERENCE_TYPE)
+ return true;
+ if (CLASS_TYPE_P (t))
+ {
+ t = complete_type (t);
+ gcc_assert (COMPLETE_TYPE_P (t) || errorcount);
+ return CLASSTYPE_LITERAL_P (t);
+ }
+ if (TREE_CODE (t) == ARRAY_TYPE)
+ return literal_type_p (strip_array_types (t));
+ return false;
+}
+
+/* If DECL is a variable declared `constexpr', require its type
+ be literal. Return the DECL if OK, otherwise NULL. */
+
+tree
+ensure_literal_type_for_constexpr_object (tree decl)
+{
+ tree type = TREE_TYPE (decl);
+ if (VAR_P (decl) && DECL_DECLARED_CONSTEXPR_P (decl)
+ && !processing_template_decl)
+ {
+ tree stype = strip_array_types (type);
+ if (CLASS_TYPE_P (stype) && !COMPLETE_TYPE_P (complete_type (stype)))
+ /* Don't complain here, we'll complain about incompleteness
+ when we try to initialize the variable. */;
+ else if (!literal_type_p (type))
+ {
+ error ("the type %qT of constexpr variable %qD is not literal",
+ type, decl);
+ explain_non_literal_class (type);
+ return NULL;
+ }
+ }
+ return decl;
+}
+
+/* Representation of entries in the constexpr function definition table. */
+
+typedef struct GTY(()) constexpr_fundef {
+ tree decl;
+ tree body;
+} constexpr_fundef;
+
+/* This table holds all constexpr function definitions seen in
+ the current translation unit. */
+
+static GTY ((param_is (constexpr_fundef))) htab_t constexpr_fundef_table;
+
+/* Utility function used for managing the constexpr function table.
+ Return true if the entries pointed to by P and Q are for the
+ same constexpr function. */
+
+static inline int
+constexpr_fundef_equal (const void *p, const void *q)
+{
+ const constexpr_fundef *lhs = (const constexpr_fundef *) p;
+ const constexpr_fundef *rhs = (const constexpr_fundef *) q;
+ return lhs->decl == rhs->decl;
+}
+
+/* Utility function used for managing the constexpr function table.
+ Return a hash value for the entry pointed to by Q. */
+
+static inline hashval_t
+constexpr_fundef_hash (const void *p)
+{
+ const constexpr_fundef *fundef = (const constexpr_fundef *) p;
+ return DECL_UID (fundef->decl);
+}
+
+/* Return a previously saved definition of function FUN. */
+
+static constexpr_fundef *
+retrieve_constexpr_fundef (tree fun)
+{
+ constexpr_fundef fundef = { NULL, NULL };
+ if (constexpr_fundef_table == NULL)
+ return NULL;
+
+ fundef.decl = fun;
+ return (constexpr_fundef *) htab_find (constexpr_fundef_table, &fundef);
+}
+
+/* Check whether the parameter and return types of FUN are valid for a
+ constexpr function, and complain if COMPLAIN. */
+
+static bool
+is_valid_constexpr_fn (tree fun, bool complain)
+{
+ bool ret = true;
+
+ if (DECL_INHERITED_CTOR_BASE (fun)
+ && TREE_CODE (fun) == TEMPLATE_DECL)
+ {
+ ret = false;
+ if (complain)
+ error ("inherited constructor %qD is not constexpr",
+ get_inherited_ctor (fun));
+ }
+ else
+ {
+ for (tree parm = FUNCTION_FIRST_USER_PARM (fun);
+ parm != NULL_TREE; parm = TREE_CHAIN (parm))
+ if (!literal_type_p (TREE_TYPE (parm)))
+ {
+ ret = false;
+ if (complain)
+ {
+ error ("invalid type for parameter %d of constexpr "
+ "function %q+#D", DECL_PARM_INDEX (parm), fun);
+ explain_non_literal_class (TREE_TYPE (parm));
+ }
+ }
+ }
+
+ if (!DECL_CONSTRUCTOR_P (fun))
+ {
+ tree rettype = TREE_TYPE (TREE_TYPE (fun));
+ if (!literal_type_p (rettype))
+ {
+ ret = false;
+ if (complain)
+ {
+ error ("invalid return type %qT of constexpr function %q+D",
+ rettype, fun);
+ explain_non_literal_class (rettype);
+ }
+ }
+
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)
+ && !CLASSTYPE_LITERAL_P (DECL_CONTEXT (fun)))
+ {
+ ret = false;
+ if (complain)
+ {
+ error ("enclosing class of constexpr non-static member "
+ "function %q+#D is not a literal type", fun);
+ explain_non_literal_class (DECL_CONTEXT (fun));
+ }
+ }
+ }
+ else if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun)))
+ {
+ ret = false;
+ if (complain)
+ error ("%q#T has virtual base classes", DECL_CONTEXT (fun));
+ }
+
+ return ret;
+}
+
+/* Subroutine of build_data_member_initialization. MEMBER is a COMPONENT_REF
+ for a member of an anonymous aggregate, INIT is the initializer for that
+ member, and VEC_OUTER is the vector of constructor elements for the class
+ whose constructor we are processing. Add the initializer to the vector
+ and return true to indicate success. */
+
+static bool
+build_anon_member_initialization (tree member, tree init,
+ vec<constructor_elt, va_gc> **vec_outer)
+{
+ /* MEMBER presents the relevant fields from the inside out, but we need
+ to build up the initializer from the outside in so that we can reuse
+ previously built CONSTRUCTORs if this is, say, the second field in an
+ anonymous struct. So we use a vec as a stack. */
+ auto_vec<tree, 2> fields;
+ do
+ {
+ fields.safe_push (TREE_OPERAND (member, 1));
+ member = TREE_OPERAND (member, 0);
+ }
+ while (ANON_AGGR_TYPE_P (TREE_TYPE (member))
+ && TREE_CODE (member) == COMPONENT_REF);
+
+ /* VEC has the constructor elements vector for the context of FIELD.
+ If FIELD is an anonymous aggregate, we will push inside it. */
+ vec<constructor_elt, va_gc> **vec = vec_outer;
+ tree field;
+ while (field = fields.pop(),
+ ANON_AGGR_TYPE_P (TREE_TYPE (field)))
+ {
+ tree ctor;
+ /* If there is already an outer constructor entry for the anonymous
+ aggregate FIELD, use it; otherwise, insert one. */
+ if (vec_safe_is_empty (*vec)
+ || (*vec)->last().index != field)
+ {
+ ctor = build_constructor (TREE_TYPE (field), NULL);
+ CONSTRUCTOR_APPEND_ELT (*vec, field, ctor);
+ }
+ else
+ ctor = (*vec)->last().value;
+ vec = &CONSTRUCTOR_ELTS (ctor);
+ }
+
+ /* Now we're at the innermost field, the one that isn't an anonymous
+ aggregate. Add its initializer to the CONSTRUCTOR and we're done. */
+ gcc_assert (fields.is_empty());
+ CONSTRUCTOR_APPEND_ELT (*vec, field, init);
+
+ return true;
+}
+
+/* Subroutine of build_constexpr_constructor_member_initializers.
+ The expression tree T represents a data member initialization
+ in a (constexpr) constructor definition. Build a pairing of
+ the data member with its initializer, and prepend that pair
+ to the existing initialization pair INITS. */
+
+static bool
+build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
+{
+ tree member, init;
+ if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
+ t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) == EXPR_STMT)
+ t = TREE_OPERAND (t, 0);
+ if (t == error_mark_node)
+ return false;
+ if (TREE_CODE (t) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
+ {
+ if (! build_data_member_initialization (tsi_stmt (i), vec))
+ return false;
+ }
+ return true;
+ }
+ if (TREE_CODE (t) == CLEANUP_STMT)
+ {
+ /* We can't see a CLEANUP_STMT in a constructor for a literal class,
+ but we can in a constexpr constructor for a non-literal class. Just
+ ignore it; either all the initialization will be constant, in which
+ case the cleanup can't run, or it can't be constexpr.
+ Still recurse into CLEANUP_BODY. */
+ return build_data_member_initialization (CLEANUP_BODY (t), vec);
+ }
+ if (TREE_CODE (t) == CONVERT_EXPR)
+ t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) == INIT_EXPR
+ || TREE_CODE (t) == MODIFY_EXPR)
+ {
+ member = TREE_OPERAND (t, 0);
+ init = break_out_target_exprs (TREE_OPERAND (t, 1));
+ }
+ else if (TREE_CODE (t) == CALL_EXPR)
+ {
+ member = CALL_EXPR_ARG (t, 0);
+ /* We don't use build_cplus_new here because it complains about
+ abstract bases. Leaving the call unwrapped means that it has the
+ wrong type, but cxx_eval_constant_expression doesn't care. */
+ init = break_out_target_exprs (t);
+ }
+ else if (TREE_CODE (t) == DECL_EXPR)
+ /* Declaring a temporary, don't add it to the CONSTRUCTOR. */
+ return true;
+ else
+ gcc_unreachable ();
+ if (INDIRECT_REF_P (member))
+ member = TREE_OPERAND (member, 0);
+ if (TREE_CODE (member) == NOP_EXPR)
+ {
+ tree op = member;
+ STRIP_NOPS (op);
+ if (TREE_CODE (op) == ADDR_EXPR)
+ {
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (TREE_TYPE (op)),
+ TREE_TYPE (TREE_TYPE (member))));
+ /* Initializing a cv-qualified member; we need to look through
+ the const_cast. */
+ member = op;
+ }
+ else if (op == current_class_ptr
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (TREE_TYPE (member)),
+ current_class_type)))
+ /* Delegating constructor. */
+ member = op;
+ else
+ {
+ /* This is an initializer for an empty base; keep it for now so
+ we can check it in cxx_eval_bare_aggregate. */
+ gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))));
+ }
+ }
+ if (TREE_CODE (member) == ADDR_EXPR)
+ member = TREE_OPERAND (member, 0);
+ if (TREE_CODE (member) == COMPONENT_REF)
+ {
+ tree aggr = TREE_OPERAND (member, 0);
+ if (TREE_CODE (aggr) != COMPONENT_REF)
+ /* Normal member initialization. */
+ member = TREE_OPERAND (member, 1);
+ else if (ANON_AGGR_TYPE_P (TREE_TYPE (aggr)))
+ /* Initializing a member of an anonymous union. */
+ return build_anon_member_initialization (member, init, vec);
+ else
+ /* We're initializing a vtable pointer in a base. Leave it as
+ COMPONENT_REF so we remember the path to get to the vfield. */
+ gcc_assert (TREE_TYPE (member) == vtbl_ptr_type_node);
+ }
+
+ CONSTRUCTOR_APPEND_ELT (*vec, member, init);
+ return true;
+}
+
+/* Make sure that there are no statements after LAST in the constructor
+ body represented by LIST. */
+
+bool
+check_constexpr_ctor_body (tree last, tree list)
+{
+ bool ok = true;
+ if (TREE_CODE (list) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator i = tsi_last (list);
+ for (; !tsi_end_p (i); tsi_prev (&i))
+ {
+ tree t = tsi_stmt (i);
+ if (t == last)
+ break;
+ if (TREE_CODE (t) == BIND_EXPR)
+ {
+ if (BIND_EXPR_VARS (t))
+ {
+ ok = false;
+ break;
+ }
+ if (!check_constexpr_ctor_body (last, BIND_EXPR_BODY (t)))
+ return false;
+ else
+ continue;
+ }
+ /* We currently allow typedefs and static_assert.
+ FIXME allow them in the standard, too. */
+ if (TREE_CODE (t) != STATIC_ASSERT)
+ {
+ ok = false;
+ break;
+ }
+ }
+ }
+ else if (list != last
+ && TREE_CODE (list) != STATIC_ASSERT)
+ ok = false;
+ if (!ok)
+ {
+ error ("constexpr constructor does not have empty body");
+ DECL_DECLARED_CONSTEXPR_P (current_function_decl) = false;
+ }
+ return ok;
+}
+
+/* V is a vector of constructor elements built up for the base and member
+ initializers of a constructor for TYPE. They need to be in increasing
+ offset order, which they might not be yet if TYPE has a primary base
+ which is not first in the base-clause or a vptr and at least one base
+ all of which are non-primary. */
+
+static vec<constructor_elt, va_gc> *
+sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v)
+{
+ tree pri = CLASSTYPE_PRIMARY_BINFO (type);
+ tree field_type;
+ constructor_elt elt;
+ int i;
+
+ if (pri)
+ field_type = BINFO_TYPE (pri);
+ else if (TYPE_CONTAINS_VPTR_P (type))
+ field_type = vtbl_ptr_type_node;
+ else
+ return v;
+
+ /* Find the element for the primary base or vptr and move it to the
+ beginning of the vec. */
+ vec<constructor_elt, va_gc> &vref = *v;
+ for (i = 0; ; ++i)
+ if (TREE_TYPE (vref[i].index) == field_type)
+ break;
+
+ if (i > 0)
+ {
+ elt = vref[i];
+ for (; i > 0; --i)
+ vref[i] = vref[i-1];
+ vref[0] = elt;
+ }
+
+ return v;
+}
+
+/* Build compile-time evalable representations of member-initializer list
+ for a constexpr constructor. */
+
+static tree
+build_constexpr_constructor_member_initializers (tree type, tree body)
+{
+ vec<constructor_elt, va_gc> *vec = NULL;
+ bool ok = true;
+ if (TREE_CODE (body) == MUST_NOT_THROW_EXPR
+ || TREE_CODE (body) == EH_SPEC_BLOCK)
+ body = TREE_OPERAND (body, 0);
+ if (TREE_CODE (body) == STATEMENT_LIST)
+ body = STATEMENT_LIST_HEAD (body)->stmt;
+ body = BIND_EXPR_BODY (body);
+ if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
+ {
+ body = TREE_OPERAND (body, 0);
+ if (TREE_CODE (body) == EXPR_STMT)
+ body = TREE_OPERAND (body, 0);
+ if (TREE_CODE (body) == INIT_EXPR
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (TREE_OPERAND (body, 0)),
+ current_class_type)))
+ {
+ /* Trivial copy. */
+ return TREE_OPERAND (body, 1);
+ }
+ ok = build_data_member_initialization (body, &vec);
+ }
+ else if (TREE_CODE (body) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i))
+ {
+ ok = build_data_member_initialization (tsi_stmt (i), &vec);
+ if (!ok)
+ break;
+ }
+ }
+ else if (TREE_CODE (body) == TRY_BLOCK)
+ {
+ error ("body of %<constexpr%> constructor cannot be "
+ "a function-try-block");
+ return error_mark_node;
+ }
+ else if (EXPR_P (body))
+ ok = build_data_member_initialization (body, &vec);
+ else
+ gcc_assert (errorcount > 0);
+ if (ok)
+ {
+ if (vec_safe_length (vec) > 0)
+ {
+ /* In a delegating constructor, return the target. */
+ constructor_elt *ce = &(*vec)[0];
+ if (ce->index == current_class_ptr)
+ {
+ body = ce->value;
+ vec_free (vec);
+ return body;
+ }
+ }
+ vec = sort_constexpr_mem_initializers (type, vec);
+ return build_constructor (type, vec);
+ }
+ else
+ return error_mark_node;
+}
+
+/* Subroutine of register_constexpr_fundef. BODY is the body of a function
+ declared to be constexpr, or a sub-statement thereof. Returns the
+ return value if suitable, error_mark_node for a statement not allowed in
+ a constexpr function, or NULL_TREE if no return value was found. */
+
+static tree
+constexpr_fn_retval (tree body)
+{
+ switch (TREE_CODE (body))
+ {
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ tree expr = NULL_TREE;
+ for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i))
+ {
+ tree s = constexpr_fn_retval (tsi_stmt (i));
+ if (s == error_mark_node)
+ return error_mark_node;
+ else if (s == NULL_TREE)
+ /* Keep iterating. */;
+ else if (expr)
+ /* Multiple return statements. */
+ return error_mark_node;
+ else
+ expr = s;
+ }
+ return expr;
+ }
+
+ case RETURN_EXPR:
+ return break_out_target_exprs (TREE_OPERAND (body, 0));
+
+ case DECL_EXPR:
+ if (TREE_CODE (DECL_EXPR_DECL (body)) == USING_DECL)
+ return NULL_TREE;
+ return error_mark_node;
+
+ case CLEANUP_POINT_EXPR:
+ return constexpr_fn_retval (TREE_OPERAND (body, 0));
+
+ case USING_STMT:
+ return NULL_TREE;
+
+ default:
+ return error_mark_node;
+ }
+}
+
+/* Subroutine of register_constexpr_fundef. BODY is the DECL_SAVED_TREE of
+ FUN; do the necessary transformations to turn it into a single expression
+ that we can store in the hash table. */
+
+static tree
+massage_constexpr_body (tree fun, tree body)
+{
+ if (DECL_CONSTRUCTOR_P (fun))
+ body = build_constexpr_constructor_member_initializers
+ (DECL_CONTEXT (fun), body);
+ else
+ {
+ if (TREE_CODE (body) == EH_SPEC_BLOCK)
+ body = EH_SPEC_STMTS (body);
+ if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
+ body = TREE_OPERAND (body, 0);
+ if (TREE_CODE (body) == BIND_EXPR)
+ body = BIND_EXPR_BODY (body);
+ body = constexpr_fn_retval (body);
+ }
+ return body;
+}
+
+/* FUN is a constexpr constructor with massaged body BODY. Return true
+ if some bases/fields are uninitialized, and complain if COMPLAIN. */
+
+static bool
+cx_check_missing_mem_inits (tree fun, tree body, bool complain)
+{
+ bool bad;
+ tree field;
+ unsigned i, nelts;
+ tree ctype;
+
+ if (TREE_CODE (body) != CONSTRUCTOR)
+ return false;
+
+ nelts = CONSTRUCTOR_NELTS (body);
+ ctype = DECL_CONTEXT (fun);
+ field = TYPE_FIELDS (ctype);
+
+ if (TREE_CODE (ctype) == UNION_TYPE)
+ {
+ if (nelts == 0 && next_initializable_field (field))
+ {
+ if (complain)
+ error ("%<constexpr%> constructor for union %qT must "
+ "initialize exactly one non-static data member", ctype);
+ return true;
+ }
+ return false;
+ }
+
+ bad = false;
+ for (i = 0; i <= nelts; ++i)
+ {
+ tree index;
+ if (i == nelts)
+ index = NULL_TREE;
+ else
+ {
+ index = CONSTRUCTOR_ELT (body, i)->index;
+ /* Skip base and vtable inits. */
+ if (TREE_CODE (index) != FIELD_DECL
+ || DECL_ARTIFICIAL (index))
+ continue;
+ }
+ for (; field != index; field = DECL_CHAIN (field))
+ {
+ tree ftype;
+ if (TREE_CODE (field) != FIELD_DECL
+ || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))
+ || DECL_ARTIFICIAL (field))
+ continue;
+ ftype = strip_array_types (TREE_TYPE (field));
+ if (type_has_constexpr_default_constructor (ftype))
+ {
+ /* It's OK to skip a member with a trivial constexpr ctor.
+ A constexpr ctor that isn't trivial should have been
+ added in by now. */
+ gcc_checking_assert (!TYPE_HAS_COMPLEX_DFLT (ftype)
+ || errorcount != 0);
+ continue;
+ }
+ if (!complain)
+ return true;
+ error ("uninitialized member %qD in %<constexpr%> constructor",
+ field);
+ bad = true;
+ }
+ if (field == NULL_TREE)
+ break;
+ field = DECL_CHAIN (field);
+ }
+
+ return bad;
+}
+
+/* We are processing the definition of the constexpr function FUN.
+ Check that its BODY fulfills the propriate requirements and
+ enter it in the constexpr function definition table.
+ For constructor BODY is actually the TREE_LIST of the
+ member-initializer list. */
+
+tree
+register_constexpr_fundef (tree fun, tree body)
+{
+ constexpr_fundef entry;
+ constexpr_fundef **slot;
+
+ if (!is_valid_constexpr_fn (fun, !DECL_GENERATED_P (fun)))
+ return NULL;
+
+ body = massage_constexpr_body (fun, body);
+ if (body == NULL_TREE || body == error_mark_node)
+ {
+ if (!DECL_CONSTRUCTOR_P (fun))
+ error ("body of constexpr function %qD not a return-statement", fun);
+ return NULL;
+ }
+
+ if (!potential_rvalue_constant_expression (body))
+ {
+ if (!DECL_GENERATED_P (fun))
+ require_potential_rvalue_constant_expression (body);
+ return NULL;
+ }
+
+ if (DECL_CONSTRUCTOR_P (fun)
+ && cx_check_missing_mem_inits (fun, body, !DECL_GENERATED_P (fun)))
+ return NULL;
+
+ /* Create the constexpr function table if necessary. */
+ if (constexpr_fundef_table == NULL)
+ constexpr_fundef_table = htab_create_ggc (101,
+ constexpr_fundef_hash,
+ constexpr_fundef_equal,
+ ggc_free);
+ entry.decl = fun;
+ entry.body = body;
+ slot = (constexpr_fundef **)
+ htab_find_slot (constexpr_fundef_table, &entry, INSERT);
+
+ gcc_assert (*slot == NULL);
+ *slot = ggc_alloc_constexpr_fundef ();
+ **slot = entry;
+
+ return fun;
+}
+
+/* FUN is a non-constexpr function called in a context that requires a
+ constant expression. If it comes from a constexpr template, explain why
+ the instantiation isn't constexpr. */
+
+void
+explain_invalid_constexpr_fn (tree fun)
+{
+ static struct pointer_set_t *diagnosed;
+ tree body;
+ location_t save_loc;
+ /* Only diagnose defaulted functions or instantiations. */
+ if (!DECL_DEFAULTED_FN (fun)
+ && !is_instantiation_of_constexpr (fun))
+ return;
+ if (diagnosed == NULL)
+ diagnosed = pointer_set_create ();
+ if (pointer_set_insert (diagnosed, fun) != 0)
+ /* Already explained. */
+ return;
+
+ save_loc = input_location;
+ input_location = DECL_SOURCE_LOCATION (fun);
+ inform (0, "%q+D is not usable as a constexpr function because:", fun);
+ /* First check the declaration. */
+ if (is_valid_constexpr_fn (fun, true))
+ {
+ /* Then if it's OK, the body. */
+ if (DECL_DEFAULTED_FN (fun))
+ explain_implicit_non_constexpr (fun);
+ else
+ {
+ body = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
+ require_potential_rvalue_constant_expression (body);
+ if (DECL_CONSTRUCTOR_P (fun))
+ cx_check_missing_mem_inits (fun, body, true);
+ }
+ }
+ input_location = save_loc;
+}
+
+/* Objects of this type represent calls to constexpr functions
+ along with the bindings of parameters to their arguments, for
+ the purpose of compile time evaluation. */
+
+typedef struct GTY(()) constexpr_call {
+ /* Description of the constexpr function definition. */
+ constexpr_fundef *fundef;
+ /* Parameter bindings environment. A TREE_LIST where each TREE_PURPOSE
+ is a parameter _DECL and the TREE_VALUE is the value of the parameter.
+ Note: This arrangement is made to accommodate the use of
+ iterative_hash_template_arg (see pt.c). If you change this
+ representation, also change the hash calculation in
+ cxx_eval_call_expression. */
+ tree bindings;
+ /* Result of the call.
+ NULL means the call is being evaluated.
+ error_mark_node means that the evaluation was erroneous;
+ otherwise, the actuall value of the call. */
+ tree result;
+ /* The hash of this call; we remember it here to avoid having to
+ recalculate it when expanding the hash table. */
+ hashval_t hash;
+} constexpr_call;
+
+/* A table of all constexpr calls that have been evaluated by the
+ compiler in this translation unit. */
+
+static GTY ((param_is (constexpr_call))) htab_t constexpr_call_table;
+
+static tree cxx_eval_constant_expression (const constexpr_call *, tree,
+ bool, bool, bool *, bool *);
+
+/* Compute a hash value for a constexpr call representation. */
+
+static hashval_t
+constexpr_call_hash (const void *p)
+{
+ const constexpr_call *info = (const constexpr_call *) p;
+ return info->hash;
+}
+
+/* Return 1 if the objects pointed to by P and Q represent calls
+ to the same constexpr function with the same arguments.
+ Otherwise, return 0. */
+
+static int
+constexpr_call_equal (const void *p, const void *q)
+{
+ const constexpr_call *lhs = (const constexpr_call *) p;
+ const constexpr_call *rhs = (const constexpr_call *) q;
+ tree lhs_bindings;
+ tree rhs_bindings;
+ if (lhs == rhs)
+ return 1;
+ if (!constexpr_fundef_equal (lhs->fundef, rhs->fundef))
+ return 0;
+ lhs_bindings = lhs->bindings;
+ rhs_bindings = rhs->bindings;
+ while (lhs_bindings != NULL && rhs_bindings != NULL)
+ {
+ tree lhs_arg = TREE_VALUE (lhs_bindings);
+ tree rhs_arg = TREE_VALUE (rhs_bindings);
+ gcc_assert (TREE_TYPE (lhs_arg) == TREE_TYPE (rhs_arg));
+ if (!cp_tree_equal (lhs_arg, rhs_arg))
+ return 0;
+ lhs_bindings = TREE_CHAIN (lhs_bindings);
+ rhs_bindings = TREE_CHAIN (rhs_bindings);
+ }
+ return lhs_bindings == rhs_bindings;
+}
+
+/* Initialize the constexpr call table, if needed. */
+
+static void
+maybe_initialize_constexpr_call_table (void)
+{
+ if (constexpr_call_table == NULL)
+ constexpr_call_table = htab_create_ggc (101,
+ constexpr_call_hash,
+ constexpr_call_equal,
+ ggc_free);
+}
+
+/* Return true if T designates the implied `this' parameter. */
+
+static inline bool
+is_this_parameter (tree t)
+{
+ return t == current_class_ptr;
+}
+
+/* We have an expression tree T that represents a call, either CALL_EXPR
+ or AGGR_INIT_EXPR. If the call is lexically to a named function,
+ retrun the _DECL for that function. */
+
+static tree
+get_function_named_in_call (tree t)
+{
+ tree fun = NULL;
+ switch (TREE_CODE (t))
+ {
+ case CALL_EXPR:
+ fun = CALL_EXPR_FN (t);
+ break;
+
+ case AGGR_INIT_EXPR:
+ fun = AGGR_INIT_EXPR_FN (t);
+ break;
+
+ default:
+ gcc_unreachable();
+ break;
+ }
+ if (TREE_CODE (fun) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (fun, 0)) == FUNCTION_DECL)
+ fun = TREE_OPERAND (fun, 0);
+ return fun;
+}
+
+/* We have an expression tree T that represents a call, either CALL_EXPR
+ or AGGR_INIT_EXPR. Return the Nth argument. */
+
+static inline tree
+get_nth_callarg (tree t, int n)
+{
+ switch (TREE_CODE (t))
+ {
+ case CALL_EXPR:
+ return CALL_EXPR_ARG (t, n);
+
+ case AGGR_INIT_EXPR:
+ return AGGR_INIT_EXPR_ARG (t, n);
+
+ default:
+ gcc_unreachable ();
+ return NULL;
+ }
+}
+
+/* Look up the binding of the function parameter T in a constexpr
+ function call context CALL. */
+
+static tree
+lookup_parameter_binding (const constexpr_call *call, tree t)
+{
+ tree b = purpose_member (t, call->bindings);
+ return TREE_VALUE (b);
+}
+
+/* Attempt to evaluate T which represents a call to a builtin function.
+ We assume here that all builtin functions evaluate to scalar types
+ represented by _CST nodes. */
+
+static tree
+cxx_eval_builtin_function_call (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ const int nargs = call_expr_nargs (t);
+ tree *args = (tree *) alloca (nargs * sizeof (tree));
+ tree new_call;
+ int i;
+ for (i = 0; i < nargs; ++i)
+ {
+ args[i] = cxx_eval_constant_expression (call, CALL_EXPR_ARG (t, i),
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ if (allow_non_constant && *non_constant_p)
+ return t;
+ }
+ if (*non_constant_p)
+ return t;
+ new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
+ CALL_EXPR_FN (t), nargs, args);
+ new_call = fold (new_call);
+ VERIFY_CONSTANT (new_call);
+ return new_call;
+}
+
+/* TEMP is the constant value of a temporary object of type TYPE. Adjust
+ the type of the value to match. */
+
+static tree
+adjust_temp_type (tree type, tree temp)
+{
+ if (TREE_TYPE (temp) == type)
+ return temp;
+ /* Avoid wrapping an aggregate value in a NOP_EXPR. */
+ if (TREE_CODE (temp) == CONSTRUCTOR)
+ return build_constructor (type, CONSTRUCTOR_ELTS (temp));
+ gcc_assert (scalarish_type_p (type));
+ return cp_fold_convert (type, temp);
+}
+
+/* Subroutine of cxx_eval_call_expression.
+ We are processing a call expression (either CALL_EXPR or
+ AGGR_INIT_EXPR) in the call context of OLD_CALL. Evaluate
+ all arguments and bind their values to correspondings
+ parameters, making up the NEW_CALL context. */
+
+static void
+cxx_bind_parameters_in_call (const constexpr_call *old_call, tree t,
+ constexpr_call *new_call,
+ bool allow_non_constant,
+ bool *non_constant_p, bool *overflow_p)
+{
+ const int nargs = call_expr_nargs (t);
+ tree fun = new_call->fundef->decl;
+ tree parms = DECL_ARGUMENTS (fun);
+ int i;
+ for (i = 0; i < nargs; ++i)
+ {
+ tree x, arg;
+ tree type = parms ? TREE_TYPE (parms) : void_type_node;
+ /* For member function, the first argument is a pointer to the implied
+ object. And for an object construction, don't bind `this' before
+ it is fully constructed. */
+ if (i == 0 && DECL_CONSTRUCTOR_P (fun))
+ goto next;
+ x = get_nth_callarg (t, i);
+ if (parms && DECL_BY_REFERENCE (parms))
+ {
+ /* cp_genericize made this a reference for argument passing, but
+ we don't want to treat it like one for constexpr evaluation. */
+ gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
+ gcc_assert (TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE);
+ type = TREE_TYPE (type);
+ x = convert_from_reference (x);
+ }
+ arg = cxx_eval_constant_expression (old_call, x, allow_non_constant,
+ TREE_CODE (type) == REFERENCE_TYPE,
+ non_constant_p, overflow_p);
+ /* Don't VERIFY_CONSTANT here. */
+ if (*non_constant_p && allow_non_constant)
+ return;
+ /* Just discard ellipsis args after checking their constantitude. */
+ if (!parms)
+ continue;
+ if (*non_constant_p)
+ /* Don't try to adjust the type of non-constant args. */
+ goto next;
+
+ /* Make sure the binding has the same type as the parm. */
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ arg = adjust_temp_type (type, arg);
+ new_call->bindings = tree_cons (parms, arg, new_call->bindings);
+ next:
+ parms = TREE_CHAIN (parms);
+ }
+}
+
+/* Variables and functions to manage constexpr call expansion context.
+ These do not need to be marked for PCH or GC. */
+
+/* FIXME remember and print actual constant arguments. */
+static vec<tree> call_stack = vNULL;
+static int call_stack_tick;
+static int last_cx_error_tick;
+
+static bool
+push_cx_call_context (tree call)
+{
+ ++call_stack_tick;
+ if (!EXPR_HAS_LOCATION (call))
+ SET_EXPR_LOCATION (call, input_location);
+ call_stack.safe_push (call);
+ if (call_stack.length () > (unsigned) max_constexpr_depth)
+ return false;
+ return true;
+}
+
+static void
+pop_cx_call_context (void)
+{
+ ++call_stack_tick;
+ call_stack.pop ();
+}
+
+vec<tree>
+cx_error_context (void)
+{
+ vec<tree> r = vNULL;
+ if (call_stack_tick != last_cx_error_tick
+ && !call_stack.is_empty ())
+ r = call_stack;
+ last_cx_error_tick = call_stack_tick;
+ return r;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ Evaluate the call expression tree T in the context of OLD_CALL expression
+ evaluation. */
+
+static tree
+cxx_eval_call_expression (const constexpr_call *old_call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ location_t loc = EXPR_LOC_OR_LOC (t, input_location);
+ tree fun = get_function_named_in_call (t);
+ tree result;
+ constexpr_call new_call = { NULL, NULL, NULL, 0 };
+ constexpr_call **slot;
+ constexpr_call *entry;
+ bool depth_ok;
+
+ if (TREE_CODE (fun) != FUNCTION_DECL)
+ {
+ /* Might be a constexpr function pointer. */
+ fun = cxx_eval_constant_expression (old_call, fun, allow_non_constant,
+ /*addr*/false, non_constant_p, overflow_p);
+ if (TREE_CODE (fun) == ADDR_EXPR)
+ fun = TREE_OPERAND (fun, 0);
+ }
+ if (TREE_CODE (fun) != FUNCTION_DECL)
+ {
+ if (!allow_non_constant && !*non_constant_p)
+ error_at (loc, "expression %qE does not designate a constexpr "
+ "function", fun);
+ *non_constant_p = true;
+ return t;
+ }
+ if (DECL_CLONED_FUNCTION_P (fun))
+ fun = DECL_CLONED_FUNCTION (fun);
+ if (is_builtin_fn (fun))
+ return cxx_eval_builtin_function_call (old_call, t, allow_non_constant,
+ addr, non_constant_p, overflow_p);
+ if (!DECL_DECLARED_CONSTEXPR_P (fun))
+ {
+ if (!allow_non_constant)
+ {
+ error_at (loc, "call to non-constexpr function %qD", fun);
+ explain_invalid_constexpr_fn (fun);
+ }
+ *non_constant_p = true;
+ return t;
+ }
+
+ /* Shortcut trivial constructor/op=. */
+ if (trivial_fn_p (fun))
+ {
+ if (call_expr_nargs (t) == 2)
+ {
+ tree arg = convert_from_reference (get_nth_callarg (t, 1));
+ return cxx_eval_constant_expression (old_call, arg, allow_non_constant,
+ addr, non_constant_p, overflow_p);
+ }
+ else if (TREE_CODE (t) == AGGR_INIT_EXPR
+ && AGGR_INIT_ZERO_FIRST (t))
+ return build_zero_init (DECL_CONTEXT (fun), NULL_TREE, false);
+ }
+
+ /* If in direct recursive call, optimize definition search. */
+ if (old_call != NULL && old_call->fundef->decl == fun)
+ new_call.fundef = old_call->fundef;
+ else
+ {
+ new_call.fundef = retrieve_constexpr_fundef (fun);
+ if (new_call.fundef == NULL || new_call.fundef->body == NULL)
+ {
+ if (!allow_non_constant)
+ {
+ if (DECL_INITIAL (fun))
+ {
+ /* The definition of fun was somehow unsuitable. */
+ error_at (loc, "%qD called in a constant expression", fun);
+ explain_invalid_constexpr_fn (fun);
+ }
+ else
+ error_at (loc, "%qD used before its definition", fun);
+ }
+ *non_constant_p = true;
+ return t;
+ }
+ }
+ cxx_bind_parameters_in_call (old_call, t, &new_call,
+ allow_non_constant, non_constant_p, overflow_p);
+ if (*non_constant_p)
+ return t;
+
+ depth_ok = push_cx_call_context (t);
+
+ new_call.hash
+ = iterative_hash_template_arg (new_call.bindings,
+ constexpr_fundef_hash (new_call.fundef));
+
+ /* If we have seen this call before, we are done. */
+ maybe_initialize_constexpr_call_table ();
+ slot = (constexpr_call **)
+ htab_find_slot (constexpr_call_table, &new_call, INSERT);
+ entry = *slot;
+ if (entry == NULL)
+ {
+ /* We need to keep a pointer to the entry, not just the slot, as the
+ slot can move in the call to cxx_eval_builtin_function_call. */
+ *slot = entry = ggc_alloc_constexpr_call ();
+ *entry = new_call;
+ }
+ /* Calls which are in progress have their result set to NULL
+ so that we can detect circular dependencies. */
+ else if (entry->result == NULL)
+ {
+ if (!allow_non_constant)
+ error ("call has circular dependency");
+ *non_constant_p = true;
+ entry->result = result = error_mark_node;
+ }
+
+ if (!depth_ok)
+ {
+ if (!allow_non_constant)
+ error ("constexpr evaluation depth exceeds maximum of %d (use "
+ "-fconstexpr-depth= to increase the maximum)",
+ max_constexpr_depth);
+ *non_constant_p = true;
+ entry->result = result = error_mark_node;
+ }
+ else
+ {
+ result = entry->result;
+ if (!result || result == error_mark_node)
+ result = (cxx_eval_constant_expression
+ (&new_call, new_call.fundef->body,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p));
+ if (result == error_mark_node)
+ *non_constant_p = true;
+ if (*non_constant_p)
+ entry->result = result = error_mark_node;
+ else
+ {
+ /* If this was a call to initialize an object, set the type of
+ the CONSTRUCTOR to the type of that object. */
+ if (DECL_CONSTRUCTOR_P (fun))
+ {
+ tree ob_arg = get_nth_callarg (t, 0);
+ STRIP_NOPS (ob_arg);
+ gcc_assert (TYPE_PTR_P (TREE_TYPE (ob_arg))
+ && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (ob_arg))));
+ result = adjust_temp_type (TREE_TYPE (TREE_TYPE (ob_arg)),
+ result);
+ }
+ entry->result = result;
+ }
+ }
+
+ pop_cx_call_context ();
+ return unshare_expr (result);
+}
+
+/* FIXME speed this up, it's taking 16% of compile time on sieve testcase. */
+
+bool
+reduced_constant_expression_p (tree t)
+{
+ if (TREE_CODE (t) == PTRMEM_CST)
+ /* Even if we can't lower this yet, it's constant. */
+ return true;
+ /* FIXME are we calling this too much? */
+ return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
+}
+
+/* Some expressions may have constant operands but are not constant
+ themselves, such as 1/0. Call this function (or rather, the macro
+ following it) to check for that condition.
+
+ We only call this in places that require an arithmetic constant, not in
+ places where we might have a non-constant expression that can be a
+ component of a constant expression, such as the address of a constexpr
+ variable that might be dereferenced later. */
+
+static bool
+verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
+ bool *overflow_p)
+{
+ if (!*non_constant_p && !reduced_constant_expression_p (t))
+ {
+ if (!allow_non_constant)
+ error ("%q+E is not a constant expression", t);
+ *non_constant_p = true;
+ }
+ if (TREE_OVERFLOW_P (t))
+ {
+ if (!allow_non_constant)
+ {
+ permerror (input_location, "overflow in constant expression");
+ /* If we're being permissive (and are in an enforcing
+ context), ignore the overflow. */
+ if (flag_permissive)
+ return *non_constant_p;
+ }
+ *overflow_p = true;
+ }
+ return *non_constant_p;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ Attempt to reduce the unary expression tree T to a compile time value.
+ If successful, return the value. Otherwise issue a diagnostic
+ and return error_mark_node. */
+
+static tree
+cxx_eval_unary_expression (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ tree r;
+ tree orig_arg = TREE_OPERAND (t, 0);
+ tree arg = cxx_eval_constant_expression (call, orig_arg, allow_non_constant,
+ addr, non_constant_p, overflow_p);
+ VERIFY_CONSTANT (arg);
+ if (arg == orig_arg)
+ return t;
+ r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), arg);
+ VERIFY_CONSTANT (r);
+ return r;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ Like cxx_eval_unary_expression, except for binary expressions. */
+
+static tree
+cxx_eval_binary_expression (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ tree r;
+ tree orig_lhs = TREE_OPERAND (t, 0);
+ tree orig_rhs = TREE_OPERAND (t, 1);
+ tree lhs, rhs;
+ lhs = cxx_eval_constant_expression (call, orig_lhs,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ VERIFY_CONSTANT (lhs);
+ rhs = cxx_eval_constant_expression (call, orig_rhs,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ VERIFY_CONSTANT (rhs);
+ if (lhs == orig_lhs && rhs == orig_rhs)
+ return t;
+ r = fold_build2 (TREE_CODE (t), TREE_TYPE (t), lhs, rhs);
+ VERIFY_CONSTANT (r);
+ return r;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ Attempt to evaluate condition expressions. Dead branches are not
+ looked into. */
+
+static tree
+cxx_eval_conditional_expression (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ tree val = cxx_eval_constant_expression (call, TREE_OPERAND (t, 0),
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ VERIFY_CONSTANT (val);
+ /* Don't VERIFY_CONSTANT the other operands. */
+ if (integer_zerop (val))
+ return cxx_eval_constant_expression (call, TREE_OPERAND (t, 2),
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ return cxx_eval_constant_expression (call, TREE_OPERAND (t, 1),
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ Attempt to reduce a reference to an array slot. */
+
+static tree
+cxx_eval_array_reference (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ tree oldary = TREE_OPERAND (t, 0);
+ tree ary = cxx_eval_constant_expression (call, oldary,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ tree index, oldidx;
+ HOST_WIDE_INT i;
+ tree elem_type;
+ unsigned len, elem_nchars = 1;
+ if (*non_constant_p)
+ return t;
+ oldidx = TREE_OPERAND (t, 1);
+ index = cxx_eval_constant_expression (call, oldidx,
+ allow_non_constant, false,
+ non_constant_p, overflow_p);
+ VERIFY_CONSTANT (index);
+ if (addr && ary == oldary && index == oldidx)
+ return t;
+ else if (addr)
+ return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
+ elem_type = TREE_TYPE (TREE_TYPE (ary));
+ if (TREE_CODE (ary) == CONSTRUCTOR)
+ len = CONSTRUCTOR_NELTS (ary);
+ else if (TREE_CODE (ary) == STRING_CST)
+ {
+ elem_nchars = (TYPE_PRECISION (elem_type)
+ / TYPE_PRECISION (char_type_node));
+ len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
+ }
+ else
+ {
+ /* We can't do anything with other tree codes, so use
+ VERIFY_CONSTANT to complain and fail. */
+ VERIFY_CONSTANT (ary);
+ gcc_unreachable ();
+ }
+ if (compare_tree_int (index, len) >= 0)
+ {
+ if (tree_int_cst_lt (index, array_type_nelts_top (TREE_TYPE (ary))))
+ {
+ /* If it's within the array bounds but doesn't have an explicit
+ initializer, it's value-initialized. */
+ tree val = build_value_init (elem_type, tf_warning_or_error);
+ return cxx_eval_constant_expression (call, val,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ }
+
+ if (!allow_non_constant)
+ error ("array subscript out of bound");
+ *non_constant_p = true;
+ return t;
+ }
+ else if (tree_int_cst_lt (index, integer_zero_node))
+ {
+ if (!allow_non_constant)
+ error ("negative array subscript");
+ *non_constant_p = true;
+ return t;
+ }
+ i = tree_to_shwi (index);
+ if (TREE_CODE (ary) == CONSTRUCTOR)
+ return (*CONSTRUCTOR_ELTS (ary))[i].value;
+ else if (elem_nchars == 1)
+ return build_int_cst (cv_unqualified (TREE_TYPE (TREE_TYPE (ary))),
+ TREE_STRING_POINTER (ary)[i]);
+ else
+ {
+ tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (ary)));
+ return native_interpret_expr (type, (const unsigned char *)
+ TREE_STRING_POINTER (ary)
+ + i * elem_nchars, elem_nchars);
+ }
+ /* Don't VERIFY_CONSTANT here. */
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ Attempt to reduce a field access of a value of class type. */
+
+static tree
+cxx_eval_component_reference (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ unsigned HOST_WIDE_INT i;
+ tree field;
+ tree value;
+ tree part = TREE_OPERAND (t, 1);
+ tree orig_whole = TREE_OPERAND (t, 0);
+ tree whole = cxx_eval_constant_expression (call, orig_whole,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ if (whole == orig_whole)
+ return t;
+ if (addr)
+ return fold_build3 (COMPONENT_REF, TREE_TYPE (t),
+ whole, part, NULL_TREE);
+ /* Don't VERIFY_CONSTANT here; we only want to check that we got a
+ CONSTRUCTOR. */
+ if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR)
+ {
+ if (!allow_non_constant)
+ error ("%qE is not a constant expression", orig_whole);
+ *non_constant_p = true;
+ }
+ if (DECL_MUTABLE_P (part))
+ {
+ if (!allow_non_constant)
+ error ("mutable %qD is not usable in a constant expression", part);
+ *non_constant_p = true;
+ }
+ if (*non_constant_p)
+ return t;
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
+ {
+ if (field == part)
+ return value;
+ }
+ if (TREE_CODE (TREE_TYPE (whole)) == UNION_TYPE
+ && CONSTRUCTOR_NELTS (whole) > 0)
+ {
+ /* DR 1188 says we don't have to deal with this. */
+ if (!allow_non_constant)
+ error ("accessing %qD member instead of initialized %qD member in "
+ "constant expression", part, CONSTRUCTOR_ELT (whole, 0)->index);
+ *non_constant_p = true;
+ return t;
+ }
+
+ /* If there's no explicit init for this field, it's value-initialized. */
+ value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
+ return cxx_eval_constant_expression (call, value,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ Attempt to reduce a field access of a value of class type that is
+ expressed as a BIT_FIELD_REF. */
+
+static tree
+cxx_eval_bit_field_ref (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ tree orig_whole = TREE_OPERAND (t, 0);
+ tree retval, fldval, utype, mask;
+ bool fld_seen = false;
+ HOST_WIDE_INT istart, isize;
+ tree whole = cxx_eval_constant_expression (call, orig_whole,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ tree start, field, value;
+ unsigned HOST_WIDE_INT i;
+
+ if (whole == orig_whole)
+ return t;
+ /* Don't VERIFY_CONSTANT here; we only want to check that we got a
+ CONSTRUCTOR. */
+ if (!*non_constant_p
+ && TREE_CODE (whole) != VECTOR_CST
+ && TREE_CODE (whole) != CONSTRUCTOR)
+ {
+ if (!allow_non_constant)
+ error ("%qE is not a constant expression", orig_whole);
+ *non_constant_p = true;
+ }
+ if (*non_constant_p)
+ return t;
+
+ if (TREE_CODE (whole) == VECTOR_CST)
+ return fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole,
+ TREE_OPERAND (t, 1), TREE_OPERAND (t, 2));
+
+ start = TREE_OPERAND (t, 2);
+ istart = tree_to_shwi (start);
+ isize = tree_to_shwi (TREE_OPERAND (t, 1));
+ utype = TREE_TYPE (t);
+ if (!TYPE_UNSIGNED (utype))
+ utype = build_nonstandard_integer_type (TYPE_PRECISION (utype), 1);
+ retval = build_int_cst (utype, 0);
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
+ {
+ tree bitpos = bit_position (field);
+ if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1))
+ return value;
+ if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE
+ && TREE_CODE (value) == INTEGER_CST
+ && tree_fits_shwi_p (bitpos)
+ && tree_fits_shwi_p (DECL_SIZE (field)))
+ {
+ HOST_WIDE_INT bit = tree_to_shwi (bitpos);
+ HOST_WIDE_INT sz = tree_to_shwi (DECL_SIZE (field));
+ HOST_WIDE_INT shift;
+ if (bit >= istart && bit + sz <= istart + isize)
+ {
+ fldval = fold_convert (utype, value);
+ mask = build_int_cst_type (utype, -1);
+ mask = fold_build2 (LSHIFT_EXPR, utype, mask,
+ size_int (TYPE_PRECISION (utype) - sz));
+ mask = fold_build2 (RSHIFT_EXPR, utype, mask,
+ size_int (TYPE_PRECISION (utype) - sz));
+ fldval = fold_build2 (BIT_AND_EXPR, utype, fldval, mask);
+ shift = bit - istart;
+ if (BYTES_BIG_ENDIAN)
+ shift = TYPE_PRECISION (utype) - shift - sz;
+ fldval = fold_build2 (LSHIFT_EXPR, utype, fldval,
+ size_int (shift));
+ retval = fold_build2 (BIT_IOR_EXPR, utype, retval, fldval);
+ fld_seen = true;
+ }
+ }
+ }
+ if (fld_seen)
+ return fold_convert (TREE_TYPE (t), retval);
+ gcc_unreachable ();
+ return error_mark_node;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ Evaluate a short-circuited logical expression T in the context
+ of a given constexpr CALL. BAILOUT_VALUE is the value for
+ early return. CONTINUE_VALUE is used here purely for
+ sanity check purposes. */
+
+static tree
+cxx_eval_logical_expression (const constexpr_call *call, tree t,
+ tree bailout_value, tree continue_value,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ tree r;
+ tree lhs = cxx_eval_constant_expression (call, TREE_OPERAND (t, 0),
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ VERIFY_CONSTANT (lhs);
+ if (tree_int_cst_equal (lhs, bailout_value))
+ return lhs;
+ gcc_assert (tree_int_cst_equal (lhs, continue_value));
+ r = cxx_eval_constant_expression (call, TREE_OPERAND (t, 1),
+ allow_non_constant, addr, non_constant_p, overflow_p);
+ VERIFY_CONSTANT (r);
+ return r;
+}
+
+/* REF is a COMPONENT_REF designating a particular field. V is a vector of
+ CONSTRUCTOR elements to initialize (part of) an object containing that
+ field. Return a pointer to the constructor_elt corresponding to the
+ initialization of the field. */
+
+static constructor_elt *
+base_field_constructor_elt (vec<constructor_elt, va_gc> *v, tree ref)
+{
+ tree aggr = TREE_OPERAND (ref, 0);
+ tree field = TREE_OPERAND (ref, 1);
+ HOST_WIDE_INT i;
+ constructor_elt *ce;
+
+ gcc_assert (TREE_CODE (ref) == COMPONENT_REF);
+
+ if (TREE_CODE (aggr) == COMPONENT_REF)
+ {
+ constructor_elt *base_ce
+ = base_field_constructor_elt (v, aggr);
+ v = CONSTRUCTOR_ELTS (base_ce->value);
+ }
+
+ for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
+ if (ce->index == field)
+ return ce;
+
+ gcc_unreachable ();
+ return NULL;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ The expression tree T denotes a C-style array or a C-style
+ aggregate. Reduce it to a constant expression. */
+
+static tree
+cxx_eval_bare_aggregate (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
+ vec<constructor_elt, va_gc> *n;
+ vec_alloc (n, vec_safe_length (v));
+ constructor_elt *ce;
+ HOST_WIDE_INT i;
+ bool changed = false;
+ gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (t));
+ for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
+ {
+ tree elt = cxx_eval_constant_expression (call, ce->value,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ /* Don't VERIFY_CONSTANT here. */
+ if (allow_non_constant && *non_constant_p)
+ goto fail;
+ if (elt != ce->value)
+ changed = true;
+ if (ce->index && TREE_CODE (ce->index) == COMPONENT_REF)
+ {
+ /* This is an initialization of a vfield inside a base
+ subaggregate that we already initialized; push this
+ initialization into the previous initialization. */
+ constructor_elt *inner = base_field_constructor_elt (n, ce->index);
+ inner->value = elt;
+ }
+ else if (ce->index && TREE_CODE (ce->index) == NOP_EXPR)
+ {
+ /* This is an initializer for an empty base; now that we've
+ checked that it's constant, we can ignore it. */
+ gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (ce->index))));
+ }
+ else
+ CONSTRUCTOR_APPEND_ELT (n, ce->index, elt);
+ }
+ if (*non_constant_p || !changed)
+ {
+ fail:
+ vec_free (n);
+ return t;
+ }
+ t = build_constructor (TREE_TYPE (t), n);
+ TREE_CONSTANT (t) = true;
+ if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+ t = fold (t);
+ return t;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ The expression tree T is a VEC_INIT_EXPR which denotes the desired
+ initialization of a non-static data member of array type. Reduce it to a
+ CONSTRUCTOR.
+
+ Note that apart from value-initialization (when VALUE_INIT is true),
+ this is only intended to support value-initialization and the
+ initializations done by defaulted constructors for classes with
+ non-static data members of array type. In this case, VEC_INIT_EXPR_INIT
+ will either be NULL_TREE for the default constructor, or a COMPONENT_REF
+ for the copy/move constructor. */
+
+static tree
+cxx_eval_vec_init_1 (const constexpr_call *call, tree atype, tree init,
+ bool value_init, bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ tree elttype = TREE_TYPE (atype);
+ int max = tree_to_shwi (array_type_nelts (atype));
+ vec<constructor_elt, va_gc> *n;
+ vec_alloc (n, max + 1);
+ bool pre_init = false;
+ int i;
+
+ /* For the default constructor, build up a call to the default
+ constructor of the element type. We only need to handle class types
+ here, as for a constructor to be constexpr, all members must be
+ initialized, which for a defaulted default constructor means they must
+ be of a class type with a constexpr default constructor. */
+ if (TREE_CODE (elttype) == ARRAY_TYPE)
+ /* We only do this at the lowest level. */;
+ else if (value_init)
+ {
+ init = build_value_init (elttype, tf_warning_or_error);
+ init = cxx_eval_constant_expression
+ (call, init, allow_non_constant, addr, non_constant_p, overflow_p);
+ pre_init = true;
+ }
+ else if (!init)
+ {
+ vec<tree, va_gc> *argvec = make_tree_vector ();
+ init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ &argvec, elttype, LOOKUP_NORMAL,
+ tf_warning_or_error);
+ release_tree_vector (argvec);
+ init = cxx_eval_constant_expression (call, init, allow_non_constant,
+ addr, non_constant_p, overflow_p);
+ pre_init = true;
+ }
+
+ if (*non_constant_p && !allow_non_constant)
+ goto fail;
+
+ for (i = 0; i <= max; ++i)
+ {
+ tree idx = build_int_cst (size_type_node, i);
+ tree eltinit;
+ if (TREE_CODE (elttype) == ARRAY_TYPE)
+ {
+ /* A multidimensional array; recurse. */
+ if (value_init || init == NULL_TREE)
+ eltinit = NULL_TREE;
+ else
+ eltinit = cp_build_array_ref (input_location, init, idx,
+ tf_warning_or_error);
+ eltinit = cxx_eval_vec_init_1 (call, elttype, eltinit, value_init,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ }
+ else if (pre_init)
+ {
+ /* Initializing an element using value or default initialization
+ we just pre-built above. */
+ if (i == 0)
+ eltinit = init;
+ else
+ eltinit = unshare_expr (init);
+ }
+ else
+ {
+ /* Copying an element. */
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ (atype, TREE_TYPE (init)));
+ eltinit = cp_build_array_ref (input_location, init, idx,
+ tf_warning_or_error);
+ if (!real_lvalue_p (init))
+ eltinit = move (eltinit);
+ eltinit = force_rvalue (eltinit, tf_warning_or_error);
+ eltinit = cxx_eval_constant_expression
+ (call, eltinit, allow_non_constant, addr, non_constant_p, overflow_p);
+ }
+ if (*non_constant_p && !allow_non_constant)
+ goto fail;
+ CONSTRUCTOR_APPEND_ELT (n, idx, eltinit);
+ }
+
+ if (!*non_constant_p)
+ {
+ init = build_constructor (atype, n);
+ TREE_CONSTANT (init) = true;
+ return init;
+ }
+
+ fail:
+ vec_free (n);
+ return init;
+}
+
+static tree
+cxx_eval_vec_init (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ tree atype = TREE_TYPE (t);
+ tree init = VEC_INIT_EXPR_INIT (t);
+ tree r = cxx_eval_vec_init_1 (call, atype, init,
+ VEC_INIT_EXPR_VALUE_INIT (t),
+ allow_non_constant, addr, non_constant_p, overflow_p);
+ if (*non_constant_p)
+ return t;
+ else
+ return r;
+}
+
+/* A less strict version of fold_indirect_ref_1, which requires cv-quals to
+ match. We want to be less strict for simple *& folding; if we have a
+ non-const temporary that we access through a const pointer, that should
+ work. We handle this here rather than change fold_indirect_ref_1
+ because we're dealing with things like ADDR_EXPR of INTEGER_CST which
+ don't really make sense outside of constant expression evaluation. Also
+ we want to allow folding to COMPONENT_REF, which could cause trouble
+ with TBAA in fold_indirect_ref_1.
+
+ Try to keep this function synced with fold_indirect_ref_1. */
+
+static tree
+cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
+{
+ tree sub, subtype;
+
+ sub = op0;
+ STRIP_NOPS (sub);
+ subtype = TREE_TYPE (sub);
+ if (!POINTER_TYPE_P (subtype))
+ return NULL_TREE;
+
+ if (TREE_CODE (sub) == ADDR_EXPR)
+ {
+ tree op = TREE_OPERAND (sub, 0);
+ tree optype = TREE_TYPE (op);
+
+ /* *&CONST_DECL -> to the value of the const decl. */
+ if (TREE_CODE (op) == CONST_DECL)
+ return DECL_INITIAL (op);
+ /* *&p => p; make sure to handle *&"str"[cst] here. */
+ if (same_type_ignoring_top_level_qualifiers_p (optype, type))
+ {
+ tree fop = fold_read_from_constant_string (op);
+ if (fop)
+ return fop;
+ else
+ return op;
+ }
+ /* *(foo *)&fooarray => fooarray[0] */
+ else if (TREE_CODE (optype) == ARRAY_TYPE
+ && (same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (optype))))
+ {
+ tree type_domain = TYPE_DOMAIN (optype);
+ tree min_val = size_zero_node;
+ if (type_domain && TYPE_MIN_VALUE (type_domain))
+ min_val = TYPE_MIN_VALUE (type_domain);
+ return build4_loc (loc, ARRAY_REF, type, op, min_val,
+ NULL_TREE, NULL_TREE);
+ }
+ /* *(foo *)&complexfoo => __real__ complexfoo */
+ else if (TREE_CODE (optype) == COMPLEX_TYPE
+ && (same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (optype))))
+ return fold_build1_loc (loc, REALPART_EXPR, type, op);
+ /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
+ else if (TREE_CODE (optype) == VECTOR_TYPE
+ && (same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (optype))))
+ {
+ tree part_width = TYPE_SIZE (type);
+ tree index = bitsize_int (0);
+ return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, index);
+ }
+ /* Also handle conversion to an empty base class, which
+ is represented with a NOP_EXPR. */
+ else if (is_empty_class (type)
+ && CLASS_TYPE_P (optype)
+ && DERIVED_FROM_P (type, optype))
+ {
+ *empty_base = true;
+ return op;
+ }
+ /* *(foo *)&struct_with_foo_field => COMPONENT_REF */
+ else if (RECORD_OR_UNION_TYPE_P (optype))
+ {
+ tree field = TYPE_FIELDS (optype);
+ for (; field; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL
+ && integer_zerop (byte_position (field))
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (field), type)))
+ {
+ return fold_build3 (COMPONENT_REF, type, op, field, NULL_TREE);
+ break;
+ }
+ }
+ }
+ else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
+ && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
+ {
+ tree op00 = TREE_OPERAND (sub, 0);
+ tree op01 = TREE_OPERAND (sub, 1);
+
+ STRIP_NOPS (op00);
+ if (TREE_CODE (op00) == ADDR_EXPR)
+ {
+ tree op00type;
+ op00 = TREE_OPERAND (op00, 0);
+ op00type = TREE_TYPE (op00);
+
+ /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */
+ if (TREE_CODE (op00type) == VECTOR_TYPE
+ && (same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (op00type))))
+ {
+ HOST_WIDE_INT offset = tree_to_shwi (op01);
+ tree part_width = TYPE_SIZE (type);
+ unsigned HOST_WIDE_INT part_widthi = tree_to_shwi (part_width)/BITS_PER_UNIT;
+ unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
+ tree index = bitsize_int (indexi);
+
+ if (offset / part_widthi < TYPE_VECTOR_SUBPARTS (op00type))
+ return fold_build3_loc (loc,
+ BIT_FIELD_REF, type, op00,
+ part_width, index);
+
+ }
+ /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
+ else if (TREE_CODE (op00type) == COMPLEX_TYPE
+ && (same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (op00type))))
+ {
+ tree size = TYPE_SIZE_UNIT (type);
+ if (tree_int_cst_equal (size, op01))
+ return fold_build1_loc (loc, IMAGPART_EXPR, type, op00);
+ }
+ /* ((foo *)&fooarray)[1] => fooarray[1] */
+ else if (TREE_CODE (op00type) == ARRAY_TYPE
+ && (same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (op00type))))
+ {
+ tree type_domain = TYPE_DOMAIN (op00type);
+ tree min_val = size_zero_node;
+ if (type_domain && TYPE_MIN_VALUE (type_domain))
+ min_val = TYPE_MIN_VALUE (type_domain);
+ op01 = size_binop_loc (loc, EXACT_DIV_EXPR, op01,
+ TYPE_SIZE_UNIT (type));
+ op01 = size_binop_loc (loc, PLUS_EXPR, op01, min_val);
+ return build4_loc (loc, ARRAY_REF, type, op00, op01,
+ NULL_TREE, NULL_TREE);
+ }
+ /* Also handle conversion to an empty base class, which
+ is represented with a NOP_EXPR. */
+ else if (is_empty_class (type)
+ && CLASS_TYPE_P (op00type)
+ && DERIVED_FROM_P (type, op00type))
+ {
+ *empty_base = true;
+ return op00;
+ }
+ /* ((foo *)&struct_with_foo_field)[1] => COMPONENT_REF */
+ else if (RECORD_OR_UNION_TYPE_P (op00type))
+ {
+ tree field = TYPE_FIELDS (op00type);
+ for (; field; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL
+ && tree_int_cst_equal (byte_position (field), op01)
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (field), type)))
+ {
+ return fold_build3 (COMPONENT_REF, type, op00,
+ field, NULL_TREE);
+ break;
+ }
+ }
+ }
+ }
+ /* *(foo *)fooarrptr => (*fooarrptr)[0] */
+ else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
+ && (same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (TREE_TYPE (subtype)))))
+ {
+ tree type_domain;
+ tree min_val = size_zero_node;
+ tree newsub = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL);
+ if (newsub)
+ sub = newsub;
+ else
+ sub = build1_loc (loc, INDIRECT_REF, TREE_TYPE (subtype), sub);
+ type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
+ if (type_domain && TYPE_MIN_VALUE (type_domain))
+ min_val = TYPE_MIN_VALUE (type_domain);
+ return build4_loc (loc, ARRAY_REF, type, sub, min_val, NULL_TREE,
+ NULL_TREE);
+ }
+
+ return NULL_TREE;
+}
+
+static tree
+cxx_eval_indirect_ref (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ tree orig_op0 = TREE_OPERAND (t, 0);
+ tree op0 = cxx_eval_constant_expression (call, orig_op0, allow_non_constant,
+ /*addr*/false, non_constant_p, overflow_p);
+ bool empty_base = false;
+ tree r;
+
+ /* Don't VERIFY_CONSTANT here. */
+ if (*non_constant_p)
+ return t;
+
+ r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0,
+ &empty_base);
+
+ if (r)
+ r = cxx_eval_constant_expression (call, r, allow_non_constant,
+ addr, non_constant_p, overflow_p);
+ else
+ {
+ tree sub = op0;
+ STRIP_NOPS (sub);
+ if (TREE_CODE (sub) == ADDR_EXPR)
+ {
+ /* We couldn't fold to a constant value. Make sure it's not
+ something we should have been able to fold. */
+ gcc_assert (!same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
+ /* DR 1188 says we don't have to deal with this. */
+ if (!allow_non_constant)
+ error ("accessing value of %qE through a %qT glvalue in a "
+ "constant expression", build_fold_indirect_ref (sub),
+ TREE_TYPE (t));
+ *non_constant_p = true;
+ return t;
+ }
+ }
+
+ /* If we're pulling out the value of an empty base, make sure
+ that the whole object is constant and then return an empty
+ CONSTRUCTOR. */
+ if (empty_base)
+ {
+ VERIFY_CONSTANT (r);
+ r = build_constructor (TREE_TYPE (t), NULL);
+ TREE_CONSTANT (r) = true;
+ }
+
+ if (r == NULL_TREE)
+ {
+ if (addr && op0 != orig_op0)
+ return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
+ if (!addr)
+ VERIFY_CONSTANT (t);
+ return t;
+ }
+ return r;
+}
+
+/* Complain about R, a VAR_DECL, not being usable in a constant expression.
+ Shared between potential_constant_expression and
+ cxx_eval_constant_expression. */
+
+static void
+non_const_var_error (tree r)
+{
+ tree type = TREE_TYPE (r);
+ error ("the value of %qD is not usable in a constant "
+ "expression", r);
+ /* Avoid error cascade. */
+ if (DECL_INITIAL (r) == error_mark_node)
+ return;
+ if (DECL_DECLARED_CONSTEXPR_P (r))
+ inform (DECL_SOURCE_LOCATION (r),
+ "%qD used in its own initializer", r);
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ {
+ if (!CP_TYPE_CONST_P (type))
+ inform (DECL_SOURCE_LOCATION (r),
+ "%q#D is not const", r);
+ else if (CP_TYPE_VOLATILE_P (type))
+ inform (DECL_SOURCE_LOCATION (r),
+ "%q#D is volatile", r);
+ else if (!DECL_INITIAL (r)
+ || !TREE_CONSTANT (DECL_INITIAL (r)))
+ inform (DECL_SOURCE_LOCATION (r),
+ "%qD was not initialized with a constant "
+ "expression", r);
+ else
+ gcc_unreachable ();
+ }
+ else
+ {
+ if (cxx_dialect >= cxx11 && !DECL_DECLARED_CONSTEXPR_P (r))
+ inform (DECL_SOURCE_LOCATION (r),
+ "%qD was not declared %<constexpr%>", r);
+ else
+ inform (DECL_SOURCE_LOCATION (r),
+ "%qD does not have integral or enumeration type",
+ r);
+ }
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ Like cxx_eval_unary_expression, except for trinary expressions. */
+
+static tree
+cxx_eval_trinary_expression (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ int i;
+ tree args[3];
+ tree val;
+
+ for (i = 0; i < 3; i++)
+ {
+ args[i] = cxx_eval_constant_expression (call, TREE_OPERAND (t, i),
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ VERIFY_CONSTANT (args[i]);
+ }
+
+ val = fold_ternary_loc (EXPR_LOCATION (t), TREE_CODE (t), TREE_TYPE (t),
+ args[0], args[1], args[2]);
+ if (val == NULL_TREE)
+ return t;
+ VERIFY_CONSTANT (val);
+ return val;
+}
+
+/* Attempt to reduce the expression T to a constant value.
+ On failure, issue diagnostic and return error_mark_node. */
+/* FIXME unify with c_fully_fold */
+
+static tree
+cxx_eval_constant_expression (const constexpr_call *call, tree t,
+ bool allow_non_constant, bool addr,
+ bool *non_constant_p, bool *overflow_p)
+{
+ tree r = t;
+
+ if (t == error_mark_node)
+ {
+ *non_constant_p = true;
+ return t;
+ }
+ if (CONSTANT_CLASS_P (t))
+ {
+ if (TREE_CODE (t) == PTRMEM_CST)
+ t = cplus_expand_constant (t);
+ else if (TREE_OVERFLOW (t) && (!flag_permissive || allow_non_constant))
+ *overflow_p = true;
+ return t;
+ }
+ if (TREE_CODE (t) != NOP_EXPR
+ && reduced_constant_expression_p (t))
+ return fold (t);
+
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ if (addr)
+ return t;
+ /* else fall through. */
+ case CONST_DECL:
+ r = integral_constant_value (t);
+ if (TREE_CODE (r) == TARGET_EXPR
+ && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
+ r = TARGET_EXPR_INITIAL (r);
+ if (DECL_P (r))
+ {
+ if (!allow_non_constant)
+ non_const_var_error (r);
+ *non_constant_p = true;
+ }
+ break;
+
+ case FUNCTION_DECL:
+ case TEMPLATE_DECL:
+ case LABEL_DECL:
+ return t;
+
+ case PARM_DECL:
+ if (call && DECL_CONTEXT (t) == call->fundef->decl)
+ {
+ if (DECL_ARTIFICIAL (t) && DECL_CONSTRUCTOR_P (DECL_CONTEXT (t)))
+ {
+ if (!allow_non_constant)
+ sorry ("use of the value of the object being constructed "
+ "in a constant expression");
+ *non_constant_p = true;
+ }
+ else
+ r = lookup_parameter_binding (call, t);
+ }
+ else if (addr)
+ /* Defer in case this is only used for its type. */;
+ else
+ {
+ if (!allow_non_constant)
+ error ("%qE is not a constant expression", t);
+ *non_constant_p = true;
+ }
+ break;
+
+ case CALL_EXPR:
+ case AGGR_INIT_EXPR:
+ r = cxx_eval_call_expression (call, t, allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case TARGET_EXPR:
+ if (!literal_type_p (TREE_TYPE (t)))
+ {
+ if (!allow_non_constant)
+ {
+ error ("temporary of non-literal type %qT in a "
+ "constant expression", TREE_TYPE (t));
+ explain_non_literal_class (TREE_TYPE (t));
+ }
+ *non_constant_p = true;
+ break;
+ }
+ /* else fall through. */
+ case INIT_EXPR:
+ /* Pass false for 'addr' because these codes indicate
+ initialization of a temporary. */
+ r = cxx_eval_constant_expression (call, TREE_OPERAND (t, 1),
+ allow_non_constant, false,
+ non_constant_p, overflow_p);
+ if (!*non_constant_p)
+ /* Adjust the type of the result to the type of the temporary. */
+ r = adjust_temp_type (TREE_TYPE (t), r);
+ break;
+
+ case SCOPE_REF:
+ r = cxx_eval_constant_expression (call, TREE_OPERAND (t, 1),
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case RETURN_EXPR:
+ case NON_LVALUE_EXPR:
+ case TRY_CATCH_EXPR:
+ case CLEANUP_POINT_EXPR:
+ case MUST_NOT_THROW_EXPR:
+ case SAVE_EXPR:
+ r = cxx_eval_constant_expression (call, TREE_OPERAND (t, 0),
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ /* These differ from cxx_eval_unary_expression in that this doesn't
+ check for a constant operand or result; an address can be
+ constant without its operand being, and vice versa. */
+ case INDIRECT_REF:
+ r = cxx_eval_indirect_ref (call, t, allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case ADDR_EXPR:
+ {
+ tree oldop = TREE_OPERAND (t, 0);
+ tree op = cxx_eval_constant_expression (call, oldop,
+ allow_non_constant,
+ /*addr*/true,
+ non_constant_p, overflow_p);
+ /* Don't VERIFY_CONSTANT here. */
+ if (*non_constant_p)
+ return t;
+ /* This function does more aggressive folding than fold itself. */
+ r = build_fold_addr_expr_with_type (op, TREE_TYPE (t));
+ if (TREE_CODE (r) == ADDR_EXPR && TREE_OPERAND (r, 0) == oldop)
+ return t;
+ break;
+ }
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case CONJ_EXPR:
+ case FIX_TRUNC_EXPR:
+ case FLOAT_EXPR:
+ case NEGATE_EXPR:
+ case ABS_EXPR:
+ case BIT_NOT_EXPR:
+ case TRUTH_NOT_EXPR:
+ case FIXED_CONVERT_EXPR:
+ r = cxx_eval_unary_expression (call, t, allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case SIZEOF_EXPR:
+ if (SIZEOF_EXPR_TYPE_P (t))
+ r = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (t, 0)),
+ SIZEOF_EXPR, false);
+ else if (TYPE_P (TREE_OPERAND (t, 0)))
+ r = cxx_sizeof_or_alignof_type (TREE_OPERAND (t, 0), SIZEOF_EXPR,
+ false);
+ else
+ r = cxx_sizeof_or_alignof_expr (TREE_OPERAND (t, 0), SIZEOF_EXPR,
+ false);
+ if (r == error_mark_node)
+ r = size_one_node;
+ VERIFY_CONSTANT (r);
+ break;
+
+ case COMPOUND_EXPR:
+ {
+ /* check_return_expr sometimes wraps a TARGET_EXPR in a
+ COMPOUND_EXPR; don't get confused. Also handle EMPTY_CLASS_EXPR
+ introduced by build_call_a. */
+ tree op0 = TREE_OPERAND (t, 0);
+ tree op1 = TREE_OPERAND (t, 1);
+ STRIP_NOPS (op1);
+ if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
+ || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
+ r = cxx_eval_constant_expression (call, op0, allow_non_constant,
+ addr, non_constant_p, overflow_p);
+ else
+ {
+ /* Check that the LHS is constant and then discard it. */
+ cxx_eval_constant_expression (call, op0, allow_non_constant,
+ false, non_constant_p, overflow_p);
+ op1 = TREE_OPERAND (t, 1);
+ r = cxx_eval_constant_expression (call, op1, allow_non_constant,
+ addr, non_constant_p, overflow_p);
+ }
+ }
+ break;
+
+ case POINTER_PLUS_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ case RDIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case MIN_EXPR:
+ case MAX_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case BIT_AND_EXPR:
+ case TRUTH_XOR_EXPR:
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case UNORDERED_EXPR:
+ case ORDERED_EXPR:
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ case LTGT_EXPR:
+ case RANGE_EXPR:
+ case COMPLEX_EXPR:
+ r = cxx_eval_binary_expression (call, t, allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ /* fold can introduce non-IF versions of these; still treat them as
+ short-circuiting. */
+ case TRUTH_AND_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ r = cxx_eval_logical_expression (call, t, boolean_false_node,
+ boolean_true_node,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case TRUTH_OR_EXPR:
+ case TRUTH_ORIF_EXPR:
+ r = cxx_eval_logical_expression (call, t, boolean_true_node,
+ boolean_false_node,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case ARRAY_REF:
+ r = cxx_eval_array_reference (call, t, allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case COMPONENT_REF:
+ if (is_overloaded_fn (t))
+ {
+ /* We can only get here in checking mode via
+ build_non_dependent_expr, because any expression that
+ calls or takes the address of the function will have
+ pulled a FUNCTION_DECL out of the COMPONENT_REF. */
+ gcc_checking_assert (allow_non_constant || errorcount);
+ *non_constant_p = true;
+ return t;
+ }
+ r = cxx_eval_component_reference (call, t, allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case BIT_FIELD_REF:
+ r = cxx_eval_bit_field_ref (call, t, allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case COND_EXPR:
+ case VEC_COND_EXPR:
+ r = cxx_eval_conditional_expression (call, t, allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case CONSTRUCTOR:
+ r = cxx_eval_bare_aggregate (call, t, allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case VEC_INIT_EXPR:
+ /* We can get this in a defaulted constructor for a class with a
+ non-static data member of array type. Either the initializer will
+ be NULL, meaning default-initialization, or it will be an lvalue
+ or xvalue of the same type, meaning direct-initialization from the
+ corresponding member. */
+ r = cxx_eval_vec_init (call, t, allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case FMA_EXPR:
+ case VEC_PERM_EXPR:
+ r = cxx_eval_trinary_expression (call, t, allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ break;
+
+ case CONVERT_EXPR:
+ case VIEW_CONVERT_EXPR:
+ case NOP_EXPR:
+ {
+ tree oldop = TREE_OPERAND (t, 0);
+ tree op = cxx_eval_constant_expression (call, oldop,
+ allow_non_constant, addr,
+ non_constant_p, overflow_p);
+ if (*non_constant_p)
+ return t;
+ if (POINTER_TYPE_P (TREE_TYPE (t))
+ && TREE_CODE (op) == INTEGER_CST
+ && !integer_zerop (op))
+ {
+ if (!allow_non_constant)
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
+ "reinterpret_cast from integer to pointer");
+ *non_constant_p = true;
+ return t;
+ }
+ if (op == oldop)
+ /* We didn't fold at the top so we could check for ptr-int
+ conversion. */
+ return fold (t);
+ r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), op);
+ /* Conversion of an out-of-range value has implementation-defined
+ behavior; the language considers it different from arithmetic
+ overflow, which is undefined. */
+ if (TREE_OVERFLOW_P (r) && !TREE_OVERFLOW_P (op))
+ TREE_OVERFLOW (r) = false;
+ }
+ break;
+
+ case EMPTY_CLASS_EXPR:
+ /* This is good enough for a function argument that might not get
+ used, and they can't do anything with it, so just return it. */
+ return t;
+
+ case LAMBDA_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case NEW_EXPR:
+ case VEC_NEW_EXPR:
+ case DELETE_EXPR:
+ case VEC_DELETE_EXPR:
+ case THROW_EXPR:
+ case MODIFY_EXPR:
+ case MODOP_EXPR:
+ /* GCC internal stuff. */
+ case VA_ARG_EXPR:
+ case OBJ_TYPE_REF:
+ case WITH_CLEANUP_EXPR:
+ case STATEMENT_LIST:
+ case BIND_EXPR:
+ case NON_DEPENDENT_EXPR:
+ case BASELINK:
+ case EXPR_STMT:
+ case OFFSET_REF:
+ if (!allow_non_constant)
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
+ "expression %qE is not a constant-expression", t);
+ *non_constant_p = true;
+ break;
+
+ default:
+ internal_error ("unexpected expression %qE of kind %s", t,
+ get_tree_code_name (TREE_CODE (t)));
+ *non_constant_p = true;
+ break;
+ }
+
+ if (r == error_mark_node)
+ *non_constant_p = true;
+
+ if (*non_constant_p)
+ return t;
+ else
+ return r;
+}
+
+static tree
+cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant)
+{
+ bool non_constant_p = false;
+ bool overflow_p = false;
+ tree r = cxx_eval_constant_expression (NULL, t, allow_non_constant,
+ false, &non_constant_p, &overflow_p);
+
+ verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
+
+ if (TREE_CODE (t) != CONSTRUCTOR
+ && cp_has_mutable_p (TREE_TYPE (t)))
+ {
+ /* We allow a mutable type if the original expression was a
+ CONSTRUCTOR so that we can do aggregate initialization of
+ constexpr variables. */
+ if (!allow_non_constant)
+ error ("%qT cannot be the type of a complete constant expression "
+ "because it has mutable sub-objects", TREE_TYPE (t));
+ non_constant_p = true;
+ }
+
+ /* Technically we should check this for all subexpressions, but that
+ runs into problems with our internal representation of pointer
+ subtraction and the 5.19 rules are still in flux. */
+ if (CONVERT_EXPR_CODE_P (TREE_CODE (r))
+ && ARITHMETIC_TYPE_P (TREE_TYPE (r))
+ && TREE_CODE (TREE_OPERAND (r, 0)) == ADDR_EXPR)
+ {
+ if (!allow_non_constant)
+ error ("conversion from pointer type %qT "
+ "to arithmetic type %qT in a constant-expression",
+ TREE_TYPE (TREE_OPERAND (r, 0)), TREE_TYPE (r));
+ non_constant_p = true;
+ }
+
+ if (!non_constant_p && overflow_p)
+ non_constant_p = true;
+
+ if (non_constant_p && !allow_non_constant)
+ return error_mark_node;
+ else if (non_constant_p && TREE_CONSTANT (r))
+ {
+ /* This isn't actually constant, so unset TREE_CONSTANT. */
+ if (EXPR_P (r))
+ r = copy_node (r);
+ else if (TREE_CODE (r) == CONSTRUCTOR)
+ r = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (r), r);
+ else
+ r = build_nop (TREE_TYPE (r), r);
+ TREE_CONSTANT (r) = false;
+ }
+ else if (non_constant_p || r == t)
+ return t;
+
+ if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
+ {
+ if (TREE_CODE (t) == TARGET_EXPR
+ && TARGET_EXPR_INITIAL (t) == r)
+ return t;
+ else
+ {
+ r = get_target_expr (r);
+ TREE_CONSTANT (r) = true;
+ return r;
+ }
+ }
+ else
+ return r;
+}
+
+/* Returns true if T is a valid subexpression of a constant expression,
+ even if it isn't itself a constant expression. */
+
+bool
+is_sub_constant_expr (tree t)
+{
+ bool non_constant_p = false;
+ bool overflow_p = false;
+ cxx_eval_constant_expression (NULL, t, true, false, &non_constant_p,
+ &overflow_p);
+ return !non_constant_p && !overflow_p;
+}
+
+/* If T represents a constant expression returns its reduced value.
+ Otherwise return error_mark_node. If T is dependent, then
+ return NULL. */
+
+tree
+cxx_constant_value (tree t)
+{
+ return cxx_eval_outermost_constant_expr (t, false);
+}
+
+/* If T is a constant expression, returns its reduced value.
+ Otherwise, if T does not have TREE_CONSTANT set, returns T.
+ Otherwise, returns a version of T without TREE_CONSTANT. */
+
+tree
+maybe_constant_value (tree t)
+{
+ tree r;
+
+ if (instantiation_dependent_expression_p (t)
+ || type_unknown_p (t)
+ || BRACE_ENCLOSED_INITIALIZER_P (t)
+ || !potential_constant_expression (t))
+ {
+ if (TREE_OVERFLOW_P (t))
+ {
+ t = build_nop (TREE_TYPE (t), t);
+ TREE_CONSTANT (t) = false;
+ }
+ return t;
+ }
+
+ r = cxx_eval_outermost_constant_expr (t, true);
+#ifdef ENABLE_CHECKING
+ /* cp_tree_equal looks through NOPs, so allow them. */
+ gcc_assert (r == t
+ || CONVERT_EXPR_P (t)
+ || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
+ || !cp_tree_equal (r, t));
+#endif
+ return r;
+}
+
+/* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather
+ than wrapped in a TARGET_EXPR. */
+
+tree
+maybe_constant_init (tree t)
+{
+ t = maybe_constant_value (t);
+ if (TREE_CODE (t) == TARGET_EXPR)
+ {
+ tree init = TARGET_EXPR_INITIAL (t);
+ if (TREE_CODE (init) == CONSTRUCTOR)
+ t = init;
+ }
+ return t;
+}
+
+#if 0
+/* FIXME see ADDR_EXPR section in potential_constant_expression_1. */
+/* Return true if the object referred to by REF has automatic or thread
+ local storage. */
+
+enum { ck_ok, ck_bad, ck_unknown };
+static int
+check_automatic_or_tls (tree ref)
+{
+ enum machine_mode mode;
+ HOST_WIDE_INT bitsize, bitpos;
+ tree offset;
+ int volatilep = 0, unsignedp = 0;
+ tree decl = get_inner_reference (ref, &bitsize, &bitpos, &offset,
+ &mode, &unsignedp, &volatilep, false);
+ duration_kind dk;
+
+ /* If there isn't a decl in the middle, we don't know the linkage here,
+ and this isn't a constant expression anyway. */
+ if (!DECL_P (decl))
+ return ck_unknown;
+ dk = decl_storage_duration (decl);
+ return (dk == dk_auto || dk == dk_thread) ? ck_bad : ck_ok;
+}
+#endif
+
+/* Return true if T denotes a potentially constant expression. Issue
+ diagnostic as appropriate under control of FLAGS. If WANT_RVAL is true,
+ an lvalue-rvalue conversion is implied.
+
+ C++0x [expr.const] used to say
+
+ 6 An expression is a potential constant expression if it is
+ a constant expression where all occurrences of function
+ parameters are replaced by arbitrary constant expressions
+ of the appropriate type.
+
+ 2 A conditional expression is a constant expression unless it
+ involves one of the following as a potentially evaluated
+ subexpression (3.2), but subexpressions of logical AND (5.14),
+ logical OR (5.15), and conditional (5.16) operations that are
+ not evaluated are not considered. */
+
+static bool
+potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
+{
+ enum { any = false, rval = true };
+ int i;
+ tree tmp;
+
+ if (t == error_mark_node)
+ return false;
+ if (t == NULL_TREE)
+ return true;
+ if (TREE_THIS_VOLATILE (t))
+ {
+ if (flags & tf_error)
+ error ("expression %qE has side-effects", t);
+ return false;
+ }
+ if (CONSTANT_CLASS_P (t))
+ return true;
+
+ switch (TREE_CODE (t))
+ {
+ case FUNCTION_DECL:
+ case BASELINK:
+ case TEMPLATE_DECL:
+ case OVERLOAD:
+ case TEMPLATE_ID_EXPR:
+ case LABEL_DECL:
+ case LABEL_EXPR:
+ case CONST_DECL:
+ case SIZEOF_EXPR:
+ case ALIGNOF_EXPR:
+ case OFFSETOF_EXPR:
+ case NOEXCEPT_EXPR:
+ case TEMPLATE_PARM_INDEX:
+ case TRAIT_EXPR:
+ case IDENTIFIER_NODE:
+ case USERDEF_LITERAL:
+ /* We can see a FIELD_DECL in a pointer-to-member expression. */
+ case FIELD_DECL:
+ case PARM_DECL:
+ case USING_DECL:
+ return true;
+
+ case AGGR_INIT_EXPR:
+ case CALL_EXPR:
+ /* -- an invocation of a function other than a constexpr function
+ or a constexpr constructor. */
+ {
+ tree fun = get_function_named_in_call (t);
+ const int nargs = call_expr_nargs (t);
+ i = 0;
+
+ if (is_overloaded_fn (fun))
+ {
+ if (TREE_CODE (fun) == FUNCTION_DECL)
+ {
+ if (builtin_valid_in_constant_expr_p (fun))
+ return true;
+ if (!DECL_DECLARED_CONSTEXPR_P (fun)
+ /* Allow any built-in function; if the expansion
+ isn't constant, we'll deal with that then. */
+ && !is_builtin_fn (fun))
+ {
+ if (flags & tf_error)
+ {
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
+ "call to non-constexpr function %qD", fun);
+ explain_invalid_constexpr_fn (fun);
+ }
+ return false;
+ }
+ /* A call to a non-static member function takes the address
+ of the object as the first argument. But in a constant
+ expression the address will be folded away, so look
+ through it now. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)
+ && !DECL_CONSTRUCTOR_P (fun))
+ {
+ tree x = get_nth_callarg (t, 0);
+ if (is_this_parameter (x))
+ {
+ if (DECL_CONTEXT (x) == NULL_TREE
+ || DECL_CONSTRUCTOR_P (DECL_CONTEXT (x)))
+ {
+ if (flags & tf_error)
+ sorry ("calling a member function of the "
+ "object being constructed in a constant "
+ "expression");
+ return false;
+ }
+ /* Otherwise OK. */;
+ }
+ else if (!potential_constant_expression_1 (x, rval, flags))
+ return false;
+ i = 1;
+ }
+ }
+ else
+ {
+ if (!potential_constant_expression_1 (fun, true, flags))
+ return false;
+ fun = get_first_fn (fun);
+ }
+ /* Skip initial arguments to base constructors. */
+ if (DECL_BASE_CONSTRUCTOR_P (fun))
+ i = num_artificial_parms_for (fun);
+ fun = DECL_ORIGIN (fun);
+ }
+ else
+ {
+ if (potential_constant_expression_1 (fun, rval, flags))
+ /* Might end up being a constant function pointer. */;
+ else
+ return false;
+ }
+ for (; i < nargs; ++i)
+ {
+ tree x = get_nth_callarg (t, i);
+ if (!potential_constant_expression_1 (x, rval, flags))
+ return false;
+ }
+ return true;
+ }
+
+ case NON_LVALUE_EXPR:
+ /* -- an lvalue-to-rvalue conversion (4.1) unless it is applied to
+ -- an lvalue of integral type that refers to a non-volatile
+ const variable or static data member initialized with
+ constant expressions, or
+
+ -- an lvalue of literal type that refers to non-volatile
+ object defined with constexpr, or that refers to a
+ sub-object of such an object; */
+ return potential_constant_expression_1 (TREE_OPERAND (t, 0), rval, flags);
+
+ case VAR_DECL:
+ if (want_rval && !decl_constant_var_p (t)
+ && !dependent_type_p (TREE_TYPE (t)))
+ {
+ if (flags & tf_error)
+ non_const_var_error (t);
+ return false;
+ }
+ return true;
+
+ case NOP_EXPR:
+ case CONVERT_EXPR:
+ case VIEW_CONVERT_EXPR:
+ /* -- a reinterpret_cast. FIXME not implemented, and this rule
+ may change to something more specific to type-punning (DR 1312). */
+ {
+ tree from = TREE_OPERAND (t, 0);
+ if (POINTER_TYPE_P (TREE_TYPE (t))
+ && TREE_CODE (from) == INTEGER_CST
+ && !integer_zerop (from))
+ {
+ if (flags & tf_error)
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
+ "reinterpret_cast from integer to pointer");
+ return false;
+ }
+ return (potential_constant_expression_1
+ (from, TREE_CODE (t) != VIEW_CONVERT_EXPR, flags));
+ }
+
+ case ADDR_EXPR:
+ /* -- a unary operator & that is applied to an lvalue that
+ designates an object with thread or automatic storage
+ duration; */
+ t = TREE_OPERAND (t, 0);
+#if 0
+ /* FIXME adjust when issue 1197 is fully resolved. For now don't do
+ any checking here, as we might dereference the pointer later. If
+ we remove this code, also remove check_automatic_or_tls. */
+ i = check_automatic_or_tls (t);
+ if (i == ck_ok)
+ return true;
+ if (i == ck_bad)
+ {
+ if (flags & tf_error)
+ error ("address-of an object %qE with thread local or "
+ "automatic storage is not a constant expression", t);
+ return false;
+ }
+#endif
+ return potential_constant_expression_1 (t, any, flags);
+
+ case COMPONENT_REF:
+ case BIT_FIELD_REF:
+ case ARROW_EXPR:
+ case OFFSET_REF:
+ /* -- a class member access unless its postfix-expression is
+ of literal type or of pointer to literal type. */
+ /* This test would be redundant, as it follows from the
+ postfix-expression being a potential constant expression. */
+ return potential_constant_expression_1 (TREE_OPERAND (t, 0),
+ want_rval, flags);
+
+ case EXPR_PACK_EXPANSION:
+ return potential_constant_expression_1 (PACK_EXPANSION_PATTERN (t),
+ want_rval, flags);
+
+ case INDIRECT_REF:
+ {
+ tree x = TREE_OPERAND (t, 0);
+ STRIP_NOPS (x);
+ if (is_this_parameter (x))
+ {
+ if (DECL_CONTEXT (x)
+ && !DECL_DECLARED_CONSTEXPR_P (DECL_CONTEXT (x)))
+ {
+ if (flags & tf_error)
+ error ("use of %<this%> in a constant expression");
+ return false;
+ }
+ if (want_rval && DECL_CONTEXT (x)
+ && DECL_CONSTRUCTOR_P (DECL_CONTEXT (x)))
+ {
+ if (flags & tf_error)
+ sorry ("use of the value of the object being constructed "
+ "in a constant expression");
+ return false;
+ }
+ return true;
+ }
+ return potential_constant_expression_1 (x, rval, flags);
+ }
+
+ case LAMBDA_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case PSEUDO_DTOR_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case NEW_EXPR:
+ case VEC_NEW_EXPR:
+ case DELETE_EXPR:
+ case VEC_DELETE_EXPR:
+ case THROW_EXPR:
+ case MODIFY_EXPR:
+ case MODOP_EXPR:
+ case OMP_ATOMIC:
+ case OMP_ATOMIC_READ:
+ case OMP_ATOMIC_CAPTURE_OLD:
+ case OMP_ATOMIC_CAPTURE_NEW:
+ /* GCC internal stuff. */
+ case VA_ARG_EXPR:
+ case OBJ_TYPE_REF:
+ case WITH_CLEANUP_EXPR:
+ case CLEANUP_POINT_EXPR:
+ case MUST_NOT_THROW_EXPR:
+ case TRY_CATCH_EXPR:
+ case STATEMENT_LIST:
+ /* Don't bother trying to define a subset of statement-expressions to
+ be constant-expressions, at least for now. */
+ case STMT_EXPR:
+ case EXPR_STMT:
+ case BIND_EXPR:
+ case TRANSACTION_EXPR:
+ case IF_STMT:
+ case DO_STMT:
+ case FOR_STMT:
+ case WHILE_STMT:
+ if (flags & tf_error)
+ error ("expression %qE is not a constant-expression", t);
+ return false;
+
+ case TYPEID_EXPR:
+ /* -- a typeid expression whose operand is of polymorphic
+ class type; */
+ {
+ tree e = TREE_OPERAND (t, 0);
+ if (!TYPE_P (e) && !type_dependent_expression_p (e)
+ && TYPE_POLYMORPHIC_P (TREE_TYPE (e)))
+ {
+ if (flags & tf_error)
+ error ("typeid-expression is not a constant expression "
+ "because %qE is of polymorphic type", e);
+ return false;
+ }
+ return true;
+ }
+
+ case MINUS_EXPR:
+ /* -- a subtraction where both operands are pointers. */
+ if (TYPE_PTR_P (TREE_OPERAND (t, 0))
+ && TYPE_PTR_P (TREE_OPERAND (t, 1)))
+ {
+ if (flags & tf_error)
+ error ("difference of two pointer expressions is not "
+ "a constant expression");
+ return false;
+ }
+ want_rval = true;
+ goto binary;
+
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ /* -- a relational or equality operator where at least
+ one of the operands is a pointer. */
+ if (TYPE_PTR_P (TREE_OPERAND (t, 0))
+ || TYPE_PTR_P (TREE_OPERAND (t, 1)))
+ {
+ if (flags & tf_error)
+ error ("pointer comparison expression is not a "
+ "constant expression");
+ return false;
+ }
+ want_rval = true;
+ goto binary;
+
+ case BIT_NOT_EXPR:
+ /* A destructor. */
+ if (TYPE_P (TREE_OPERAND (t, 0)))
+ return true;
+ /* else fall through. */
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case CONJ_EXPR:
+ case SAVE_EXPR:
+ case FIX_TRUNC_EXPR:
+ case FLOAT_EXPR:
+ case NEGATE_EXPR:
+ case ABS_EXPR:
+ case TRUTH_NOT_EXPR:
+ case FIXED_CONVERT_EXPR:
+ case UNARY_PLUS_EXPR:
+ return potential_constant_expression_1 (TREE_OPERAND (t, 0), rval,
+ flags);
+
+ case CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
+ if (cxx_dialect < cxx11
+ && !dependent_type_p (TREE_TYPE (t))
+ && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)))
+ /* In C++98, a conversion to non-integral type can't be part of a
+ constant expression. */
+ {
+ if (flags & tf_error)
+ error ("cast to non-integral type %qT in a constant expression",
+ TREE_TYPE (t));
+ return false;
+ }
+
+ return (potential_constant_expression_1
+ (TREE_OPERAND (t, 0),
+ TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE, flags));
+
+ case PAREN_EXPR:
+ case NON_DEPENDENT_EXPR:
+ /* For convenience. */
+ case RETURN_EXPR:
+ return potential_constant_expression_1 (TREE_OPERAND (t, 0),
+ want_rval, flags);
+
+ case SCOPE_REF:
+ return potential_constant_expression_1 (TREE_OPERAND (t, 1),
+ want_rval, flags);
+
+ case TARGET_EXPR:
+ if (!literal_type_p (TREE_TYPE (t)))
+ {
+ if (flags & tf_error)
+ {
+ error ("temporary of non-literal type %qT in a "
+ "constant expression", TREE_TYPE (t));
+ explain_non_literal_class (TREE_TYPE (t));
+ }
+ return false;
+ }
+ case INIT_EXPR:
+ return potential_constant_expression_1 (TREE_OPERAND (t, 1),
+ rval, flags);
+
+ case CONSTRUCTOR:
+ {
+ vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
+ constructor_elt *ce;
+ for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
+ if (!potential_constant_expression_1 (ce->value, want_rval, flags))
+ return false;
+ return true;
+ }
+
+ case TREE_LIST:
+ {
+ gcc_assert (TREE_PURPOSE (t) == NULL_TREE
+ || DECL_P (TREE_PURPOSE (t)));
+ if (!potential_constant_expression_1 (TREE_VALUE (t), want_rval,
+ flags))
+ return false;
+ if (TREE_CHAIN (t) == NULL_TREE)
+ return true;
+ return potential_constant_expression_1 (TREE_CHAIN (t), want_rval,
+ flags);
+ }
+
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ {
+ tree denom = TREE_OPERAND (t, 1);
+ if (!potential_constant_expression_1 (denom, rval, flags))
+ return false;
+ /* We can't call cxx_eval_outermost_constant_expr on an expression
+ that hasn't been through fold_non_dependent_expr yet. */
+ if (!processing_template_decl)
+ denom = cxx_eval_outermost_constant_expr (denom, true);
+ if (integer_zerop (denom))
+ {
+ if (flags & tf_error)
+ error ("division by zero is not a constant-expression");
+ return false;
+ }
+ else
+ {
+ want_rval = true;
+ return potential_constant_expression_1 (TREE_OPERAND (t, 0),
+ want_rval, flags);
+ }
+ }
+
+ case COMPOUND_EXPR:
+ {
+ /* check_return_expr sometimes wraps a TARGET_EXPR in a
+ COMPOUND_EXPR; don't get confused. Also handle EMPTY_CLASS_EXPR
+ introduced by build_call_a. */
+ tree op0 = TREE_OPERAND (t, 0);
+ tree op1 = TREE_OPERAND (t, 1);
+ STRIP_NOPS (op1);
+ if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
+ || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
+ return potential_constant_expression_1 (op0, want_rval, flags);
+ else
+ goto binary;
+ }
+
+ /* If the first operand is the non-short-circuit constant, look at
+ the second operand; otherwise we only care about the first one for
+ potentiality. */
+ case TRUTH_AND_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ tmp = boolean_true_node;
+ goto truth;
+ case TRUTH_OR_EXPR:
+ case TRUTH_ORIF_EXPR:
+ tmp = boolean_false_node;
+ truth:
+ {
+ tree op = TREE_OPERAND (t, 0);
+ if (!potential_constant_expression_1 (op, rval, flags))
+ return false;
+ if (!processing_template_decl)
+ op = cxx_eval_outermost_constant_expr (op, true);
+ if (tree_int_cst_equal (op, tmp))
+ return potential_constant_expression_1 (TREE_OPERAND (t, 1), rval, flags);
+ else
+ return true;
+ }
+
+ case PLUS_EXPR:
+ case MULT_EXPR:
+ case POINTER_PLUS_EXPR:
+ case RDIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case MIN_EXPR:
+ case MAX_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case BIT_AND_EXPR:
+ case TRUTH_XOR_EXPR:
+ case UNORDERED_EXPR:
+ case ORDERED_EXPR:
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ case LTGT_EXPR:
+ case RANGE_EXPR:
+ case COMPLEX_EXPR:
+ want_rval = true;
+ /* Fall through. */
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ case MEMBER_REF:
+ case DOTSTAR_EXPR:
+ binary:
+ for (i = 0; i < 2; ++i)
+ if (!potential_constant_expression_1 (TREE_OPERAND (t, i),
+ want_rval, flags))
+ return false;
+ return true;
+
+ case CILK_SYNC_STMT:
+ case CILK_SPAWN_STMT:
+ case ARRAY_NOTATION_REF:
+ return false;
+
+ case FMA_EXPR:
+ case VEC_PERM_EXPR:
+ for (i = 0; i < 3; ++i)
+ if (!potential_constant_expression_1 (TREE_OPERAND (t, i),
+ true, flags))
+ return false;
+ return true;
+
+ case COND_EXPR:
+ case VEC_COND_EXPR:
+ /* If the condition is a known constant, we know which of the legs we
+ care about; otherwise we only require that the condition and
+ either of the legs be potentially constant. */
+ tmp = TREE_OPERAND (t, 0);
+ if (!potential_constant_expression_1 (tmp, rval, flags))
+ return false;
+ if (!processing_template_decl)
+ tmp = cxx_eval_outermost_constant_expr (tmp, true);
+ if (integer_zerop (tmp))
+ return potential_constant_expression_1 (TREE_OPERAND (t, 2),
+ want_rval, flags);
+ else if (TREE_CODE (tmp) == INTEGER_CST)
+ return potential_constant_expression_1 (TREE_OPERAND (t, 1),
+ want_rval, flags);
+ for (i = 1; i < 3; ++i)
+ if (potential_constant_expression_1 (TREE_OPERAND (t, i),
+ want_rval, tf_none))
+ return true;
+ if (flags & tf_error)
+ error ("expression %qE is not a constant-expression", t);
+ return false;
+
+ case VEC_INIT_EXPR:
+ if (VEC_INIT_EXPR_IS_CONSTEXPR (t))
+ return true;
+ if (flags & tf_error)
+ {
+ error ("non-constant array initialization");
+ diagnose_non_constexpr_vec_init (t);
+ }
+ return false;
+
+ default:
+ if (objc_is_property_ref (t))
+ return false;
+
+ sorry ("unexpected AST of kind %s", get_tree_code_name (TREE_CODE (t)));
+ gcc_unreachable();
+ return false;
+ }
+}
+
+/* The main entry point to the above. */
+
+bool
+potential_constant_expression (tree t)
+{
+ return potential_constant_expression_1 (t, false, tf_none);
+}
+
+/* As above, but require a constant rvalue. */
+
+bool
+potential_rvalue_constant_expression (tree t)
+{
+ return potential_constant_expression_1 (t, true, tf_none);
+}
+
+/* Like above, but complain about non-constant expressions. */
+
+bool
+require_potential_constant_expression (tree t)
+{
+ return potential_constant_expression_1 (t, false, tf_warning_or_error);
+}
+
+/* Cross product of the above. */
+
+bool
+require_potential_rvalue_constant_expression (tree t)
+{
+ return potential_constant_expression_1 (t, true, tf_warning_or_error);
+}
+
+/* Insert the deduced return type for an auto function. */
+
+void
+apply_deduced_return_type (tree fco, tree return_type)
+{
+ tree result;
+
+ if (return_type == error_mark_node)
+ return;
+
+ if (LAMBDA_FUNCTION_P (fco))
+ {
+ tree lambda = CLASSTYPE_LAMBDA_EXPR (current_class_type);
+ LAMBDA_EXPR_RETURN_TYPE (lambda) = return_type;
+ }
+
+ if (DECL_CONV_FN_P (fco))
+ DECL_NAME (fco) = mangle_conv_op_name_for_type (return_type);
+
+ TREE_TYPE (fco) = change_return_type (return_type, TREE_TYPE (fco));
+
+ result = DECL_RESULT (fco);
+ if (result == NULL_TREE)
+ return;
+ if (TREE_TYPE (result) == return_type)
+ return;
+
+ /* We already have a DECL_RESULT from start_preparsed_function.
+ Now we need to redo the work it and allocate_struct_function
+ did to reflect the new type. */
+ gcc_assert (current_function_decl == fco);
+ result = build_decl (input_location, RESULT_DECL, NULL_TREE,
+ TYPE_MAIN_VARIANT (return_type));
+ DECL_ARTIFICIAL (result) = 1;
+ DECL_IGNORED_P (result) = 1;
+ cp_apply_type_quals_to_decl (cp_type_quals (return_type),
+ result);
+
+ DECL_RESULT (fco) = result;
+
+ if (!processing_template_decl)
+ {
+ bool aggr = aggregate_value_p (result, fco);
+#ifdef PCC_STATIC_STRUCT_RETURN
+ cfun->returns_pcc_struct = aggr;
+#endif
+ cfun->returns_struct = aggr;
+ }
+
+}
+
+/* DECL is a local variable or parameter from the surrounding scope of a
+ lambda-expression. Returns the decltype for a use of the capture field
+ for DECL even if it hasn't been captured yet. */
+
+static tree
+capture_decltype (tree decl)
+{
+ tree lam = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (current_function_decl));
+ /* FIXME do lookup instead of list walk? */
+ tree cap = value_member (decl, LAMBDA_EXPR_CAPTURE_LIST (lam));
+ tree type;
+
+ if (cap)
+ type = TREE_TYPE (TREE_PURPOSE (cap));
+ else
+ switch (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam))
+ {
+ case CPLD_NONE:
+ error ("%qD is not captured", decl);
+ return error_mark_node;
+
+ case CPLD_COPY:
+ type = TREE_TYPE (decl);
+ if (TREE_CODE (type) == REFERENCE_TYPE
+ && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
+ type = TREE_TYPE (type);
+ break;
+
+ case CPLD_REFERENCE:
+ type = TREE_TYPE (decl);
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ type = build_reference_type (TREE_TYPE (decl));
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ {
+ if (!LAMBDA_EXPR_MUTABLE_P (lam))
+ type = cp_build_qualified_type (type, (cp_type_quals (type)
+ |TYPE_QUAL_CONST));
+ type = build_reference_type (type);
+ }
+ return type;
+}
+
+#include "gt-cp-semantics.h"
diff --git a/gcc-4.9/gcc/cp/tree.c b/gcc-4.9/gcc/cp/tree.c
new file mode 100644
index 000000000..5567253a6
--- /dev/null
+++ b/gcc-4.9/gcc/cp/tree.c
@@ -0,0 +1,4112 @@
+/* Language-dependent node constructors for parse phase of GNU compiler.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Hacked by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stor-layout.h"
+#include "print-tree.h"
+#include "tree-iterator.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "tree-inline.h"
+#include "debug.h"
+#include "convert.h"
+#include "cgraph.h"
+#include "splay-tree.h"
+#include "hash-table.h"
+#include "gimple-expr.h"
+#include "gimplify.h"
+
+static tree bot_manip (tree *, int *, void *);
+static tree bot_replace (tree *, int *, void *);
+static int list_hash_eq (const void *, const void *);
+static hashval_t list_hash_pieces (tree, tree, tree);
+static hashval_t list_hash (const void *);
+static tree build_target_expr (tree, tree, tsubst_flags_t);
+static tree count_trees_r (tree *, int *, void *);
+static tree verify_stmt_tree_r (tree *, int *, void *);
+static tree build_local_temp (tree);
+
+static tree handle_java_interface_attribute (tree *, tree, tree, int, bool *);
+static tree handle_com_interface_attribute (tree *, tree, tree, int, bool *);
+static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
+static tree handle_abi_tag_attribute (tree *, tree, tree, int, bool *);
+
+/* If REF is an lvalue, returns the kind of lvalue that REF is.
+ Otherwise, returns clk_none. */
+
+cp_lvalue_kind
+lvalue_kind (const_tree ref)
+{
+ cp_lvalue_kind op1_lvalue_kind = clk_none;
+ cp_lvalue_kind op2_lvalue_kind = clk_none;
+
+ /* Expressions of reference type are sometimes wrapped in
+ INDIRECT_REFs. INDIRECT_REFs are just internal compiler
+ representation, not part of the language, so we have to look
+ through them. */
+ if (REFERENCE_REF_P (ref))
+ return lvalue_kind (TREE_OPERAND (ref, 0));
+
+ if (TREE_TYPE (ref)
+ && TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
+ {
+ /* unnamed rvalue references are rvalues */
+ if (TYPE_REF_IS_RVALUE (TREE_TYPE (ref))
+ && TREE_CODE (ref) != PARM_DECL
+ && !VAR_P (ref)
+ && TREE_CODE (ref) != COMPONENT_REF
+ /* Functions are always lvalues. */
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (ref))) != FUNCTION_TYPE)
+ return clk_rvalueref;
+
+ /* lvalue references and named rvalue references are lvalues. */
+ return clk_ordinary;
+ }
+
+ if (ref == current_class_ptr)
+ return clk_none;
+
+ switch (TREE_CODE (ref))
+ {
+ case SAVE_EXPR:
+ return clk_none;
+ /* preincrements and predecrements are valid lvals, provided
+ what they refer to are valid lvals. */
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case TRY_CATCH_EXPR:
+ case WITH_CLEANUP_EXPR:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ return lvalue_kind (TREE_OPERAND (ref, 0));
+
+ case COMPONENT_REF:
+ op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
+ /* Look at the member designator. */
+ if (!op1_lvalue_kind)
+ ;
+ else if (is_overloaded_fn (TREE_OPERAND (ref, 1)))
+ /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
+ situations. If we're seeing a COMPONENT_REF, it's a non-static
+ member, so it isn't an lvalue. */
+ op1_lvalue_kind = clk_none;
+ else if (TREE_CODE (TREE_OPERAND (ref, 1)) != FIELD_DECL)
+ /* This can be IDENTIFIER_NODE in a template. */;
+ else if (DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
+ {
+ /* Clear the ordinary bit. If this object was a class
+ rvalue we want to preserve that information. */
+ op1_lvalue_kind &= ~clk_ordinary;
+ /* The lvalue is for a bitfield. */
+ op1_lvalue_kind |= clk_bitfield;
+ }
+ else if (DECL_PACKED (TREE_OPERAND (ref, 1)))
+ op1_lvalue_kind |= clk_packed;
+
+ return op1_lvalue_kind;
+
+ case STRING_CST:
+ case COMPOUND_LITERAL_EXPR:
+ return clk_ordinary;
+
+ case CONST_DECL:
+ /* CONST_DECL without TREE_STATIC are enumeration values and
+ thus not lvalues. With TREE_STATIC they are used by ObjC++
+ in objc_build_string_object and need to be considered as
+ lvalues. */
+ if (! TREE_STATIC (ref))
+ return clk_none;
+ case VAR_DECL:
+ if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
+ && DECL_LANG_SPECIFIC (ref)
+ && DECL_IN_AGGR_P (ref))
+ return clk_none;
+ case INDIRECT_REF:
+ case ARROW_EXPR:
+ case ARRAY_REF:
+ case ARRAY_NOTATION_REF:
+ case PARM_DECL:
+ case RESULT_DECL:
+ return clk_ordinary;
+
+ /* A scope ref in a template, left as SCOPE_REF to support later
+ access checking. */
+ case SCOPE_REF:
+ gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE (ref)));
+ {
+ tree op = TREE_OPERAND (ref, 1);
+ if (TREE_CODE (op) == FIELD_DECL)
+ return (DECL_C_BIT_FIELD (op) ? clk_bitfield : clk_ordinary);
+ else
+ return lvalue_kind (op);
+ }
+
+ case MAX_EXPR:
+ case MIN_EXPR:
+ /* Disallow <? and >? as lvalues if either argument side-effects. */
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (ref, 0))
+ || TREE_SIDE_EFFECTS (TREE_OPERAND (ref, 1)))
+ return clk_none;
+ op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
+ op2_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1));
+ break;
+
+ case COND_EXPR:
+ op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1)
+ ? TREE_OPERAND (ref, 1)
+ : TREE_OPERAND (ref, 0));
+ op2_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 2));
+ break;
+
+ case MODIFY_EXPR:
+ case TYPEID_EXPR:
+ return clk_ordinary;
+
+ case COMPOUND_EXPR:
+ return lvalue_kind (TREE_OPERAND (ref, 1));
+
+ case TARGET_EXPR:
+ return clk_class;
+
+ case VA_ARG_EXPR:
+ return (CLASS_TYPE_P (TREE_TYPE (ref)) ? clk_class : clk_none);
+
+ case CALL_EXPR:
+ /* We can see calls outside of TARGET_EXPR in templates. */
+ if (CLASS_TYPE_P (TREE_TYPE (ref)))
+ return clk_class;
+ return clk_none;
+
+ case FUNCTION_DECL:
+ /* All functions (except non-static-member functions) are
+ lvalues. */
+ return (DECL_NONSTATIC_MEMBER_FUNCTION_P (ref)
+ ? clk_none : clk_ordinary);
+
+ case BASELINK:
+ /* We now represent a reference to a single static member function
+ with a BASELINK. */
+ /* This CONST_CAST is okay because BASELINK_FUNCTIONS returns
+ its argument unmodified and we assign it to a const_tree. */
+ return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));
+
+ case NON_DEPENDENT_EXPR:
+ /* We just return clk_ordinary for NON_DEPENDENT_EXPR in C++98, but
+ in C++11 lvalues don't bind to rvalue references, so we need to
+ work harder to avoid bogus errors (c++/44870). */
+ if (cxx_dialect < cxx11)
+ return clk_ordinary;
+ else
+ return lvalue_kind (TREE_OPERAND (ref, 0));
+
+ default:
+ if (!TREE_TYPE (ref))
+ return clk_none;
+ if (CLASS_TYPE_P (TREE_TYPE (ref)))
+ return clk_class;
+ break;
+ }
+
+ /* If one operand is not an lvalue at all, then this expression is
+ not an lvalue. */
+ if (!op1_lvalue_kind || !op2_lvalue_kind)
+ return clk_none;
+
+ /* Otherwise, it's an lvalue, and it has all the odd properties
+ contributed by either operand. */
+ op1_lvalue_kind = op1_lvalue_kind | op2_lvalue_kind;
+ /* It's not an ordinary lvalue if it involves any other kind. */
+ if ((op1_lvalue_kind & ~clk_ordinary) != clk_none)
+ op1_lvalue_kind &= ~clk_ordinary;
+ /* It can't be both a pseudo-lvalue and a non-addressable lvalue.
+ A COND_EXPR of those should be wrapped in a TARGET_EXPR. */
+ if ((op1_lvalue_kind & (clk_rvalueref|clk_class))
+ && (op1_lvalue_kind & (clk_bitfield|clk_packed)))
+ op1_lvalue_kind = clk_none;
+ return op1_lvalue_kind;
+}
+
+/* Returns the kind of lvalue that REF is, in the sense of
+ [basic.lval]. This function should really be named lvalue_p; it
+ computes the C++ definition of lvalue. */
+
+cp_lvalue_kind
+real_lvalue_p (const_tree ref)
+{
+ cp_lvalue_kind kind = lvalue_kind (ref);
+ if (kind & (clk_rvalueref|clk_class))
+ return clk_none;
+ else
+ return kind;
+}
+
+/* This differs from real_lvalue_p in that class rvalues are considered
+ lvalues. */
+
+bool
+lvalue_p (const_tree ref)
+{
+ return (lvalue_kind (ref) != clk_none);
+}
+
+/* This differs from real_lvalue_p in that rvalues formed by dereferencing
+ rvalue references are considered rvalues. */
+
+bool
+lvalue_or_rvalue_with_address_p (const_tree ref)
+{
+ cp_lvalue_kind kind = lvalue_kind (ref);
+ if (kind & clk_class)
+ return false;
+ else
+ return (kind != clk_none);
+}
+
+/* Returns true if REF is an xvalue, false otherwise. */
+
+bool
+xvalue_p (const_tree ref)
+{
+ return (lvalue_kind (ref) == clk_rvalueref);
+}
+
+/* Test whether DECL is a builtin that may appear in a
+ constant-expression. */
+
+bool
+builtin_valid_in_constant_expr_p (const_tree decl)
+{
+ /* At present BUILT_IN_CONSTANT_P is the only builtin we're allowing
+ in constant-expressions. We may want to add other builtins later. */
+ return DECL_IS_BUILTIN_CONSTANT_P (decl);
+}
+
+/* Build a TARGET_EXPR, initializing the DECL with the VALUE. */
+
+static tree
+build_target_expr (tree decl, tree value, tsubst_flags_t complain)
+{
+ tree t;
+ tree type = TREE_TYPE (decl);
+
+#ifdef ENABLE_CHECKING
+ gcc_assert (VOID_TYPE_P (TREE_TYPE (value))
+ || TREE_TYPE (decl) == TREE_TYPE (value)
+ /* On ARM ctors return 'this'. */
+ || (TYPE_PTR_P (TREE_TYPE (value))
+ && TREE_CODE (value) == CALL_EXPR)
+ || useless_type_conversion_p (TREE_TYPE (decl),
+ TREE_TYPE (value)));
+#endif
+
+ t = cxx_maybe_build_cleanup (decl, complain);
+ if (t == error_mark_node)
+ return error_mark_node;
+ t = build4 (TARGET_EXPR, type, decl, value, t, NULL_TREE);
+ /* We always set TREE_SIDE_EFFECTS so that expand_expr does not
+ ignore the TARGET_EXPR. If there really turn out to be no
+ side-effects, then the optimizer should be able to get rid of
+ whatever code is generated anyhow. */
+ TREE_SIDE_EFFECTS (t) = 1;
+
+ return t;
+}
+
+/* Return an undeclared local temporary of type TYPE for use in building a
+ TARGET_EXPR. */
+
+static tree
+build_local_temp (tree type)
+{
+ tree slot = build_decl (input_location,
+ VAR_DECL, NULL_TREE, type);
+ DECL_ARTIFICIAL (slot) = 1;
+ DECL_IGNORED_P (slot) = 1;
+ DECL_CONTEXT (slot) = current_function_decl;
+ layout_decl (slot, 0);
+ return slot;
+}
+
+/* Set various status flags when building an AGGR_INIT_EXPR object T. */
+
+static void
+process_aggr_init_operands (tree t)
+{
+ bool side_effects;
+
+ side_effects = TREE_SIDE_EFFECTS (t);
+ if (!side_effects)
+ {
+ int i, n;
+ n = TREE_OPERAND_LENGTH (t);
+ for (i = 1; i < n; i++)
+ {
+ tree op = TREE_OPERAND (t, i);
+ if (op && TREE_SIDE_EFFECTS (op))
+ {
+ side_effects = 1;
+ break;
+ }
+ }
+ }
+ TREE_SIDE_EFFECTS (t) = side_effects;
+}
+
+/* Build an AGGR_INIT_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE,
+ FN, and SLOT. NARGS is the number of call arguments which are specified
+ as a tree array ARGS. */
+
+static tree
+build_aggr_init_array (tree return_type, tree fn, tree slot, int nargs,
+ tree *args)
+{
+ tree t;
+ int i;
+
+ t = build_vl_exp (AGGR_INIT_EXPR, nargs + 3);
+ TREE_TYPE (t) = return_type;
+ AGGR_INIT_EXPR_FN (t) = fn;
+ AGGR_INIT_EXPR_SLOT (t) = slot;
+ for (i = 0; i < nargs; i++)
+ AGGR_INIT_EXPR_ARG (t, i) = args[i];
+ process_aggr_init_operands (t);
+ return t;
+}
+
+/* INIT is a CALL_EXPR or AGGR_INIT_EXPR which needs info about its
+ target. TYPE is the type to be initialized.
+
+ Build an AGGR_INIT_EXPR to represent the initialization. This function
+ differs from build_cplus_new in that an AGGR_INIT_EXPR can only be used
+ to initialize another object, whereas a TARGET_EXPR can either
+ initialize another object or create its own temporary object, and as a
+ result building up a TARGET_EXPR requires that the type's destructor be
+ callable. */
+
+tree
+build_aggr_init_expr (tree type, tree init)
+{
+ tree fn;
+ tree slot;
+ tree rval;
+ int is_ctor;
+
+ /* Don't build AGGR_INIT_EXPR in a template. */
+ if (processing_template_decl)
+ return init;
+
+ if (TREE_CODE (init) == CALL_EXPR)
+ fn = CALL_EXPR_FN (init);
+ else if (TREE_CODE (init) == AGGR_INIT_EXPR)
+ fn = AGGR_INIT_EXPR_FN (init);
+ else
+ return convert (type, init);
+
+ is_ctor = (TREE_CODE (fn) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
+ && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
+
+ /* We split the CALL_EXPR into its function and its arguments here.
+ Then, in expand_expr, we put them back together. The reason for
+ this is that this expression might be a default argument
+ expression. In that case, we need a new temporary every time the
+ expression is used. That's what break_out_target_exprs does; it
+ replaces every AGGR_INIT_EXPR with a copy that uses a fresh
+ temporary slot. Then, expand_expr builds up a call-expression
+ using the new slot. */
+
+ /* If we don't need to use a constructor to create an object of this
+ type, don't mess with AGGR_INIT_EXPR. */
+ if (is_ctor || TREE_ADDRESSABLE (type))
+ {
+ slot = build_local_temp (type);
+
+ if (TREE_CODE(init) == CALL_EXPR)
+ rval = build_aggr_init_array (void_type_node, fn, slot,
+ call_expr_nargs (init),
+ CALL_EXPR_ARGP (init));
+ else
+ rval = build_aggr_init_array (void_type_node, fn, slot,
+ aggr_init_expr_nargs (init),
+ AGGR_INIT_EXPR_ARGP (init));
+ TREE_SIDE_EFFECTS (rval) = 1;
+ AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
+ TREE_NOTHROW (rval) = TREE_NOTHROW (init);
+ }
+ else
+ rval = init;
+
+ return rval;
+}
+
+/* INIT is a CALL_EXPR or AGGR_INIT_EXPR which needs info about its
+ target. TYPE is the type that this initialization should appear to
+ have.
+
+ Build an encapsulation of the initialization to perform
+ and return it so that it can be processed by language-independent
+ and language-specific expression expanders. */
+
+tree
+build_cplus_new (tree type, tree init, tsubst_flags_t complain)
+{
+ tree rval = build_aggr_init_expr (type, init);
+ tree slot;
+
+ if (!complete_type_or_maybe_complain (type, init, complain))
+ return error_mark_node;
+
+ /* Make sure that we're not trying to create an instance of an
+ abstract class. */
+ if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain))
+ return error_mark_node;
+
+ if (TREE_CODE (rval) == AGGR_INIT_EXPR)
+ slot = AGGR_INIT_EXPR_SLOT (rval);
+ else if (TREE_CODE (rval) == CALL_EXPR
+ || TREE_CODE (rval) == CONSTRUCTOR)
+ slot = build_local_temp (type);
+ else
+ return rval;
+
+ rval = build_target_expr (slot, rval, complain);
+
+ if (rval != error_mark_node)
+ TARGET_EXPR_IMPLICIT_P (rval) = 1;
+
+ return rval;
+}
+
+/* Subroutine of build_vec_init_expr: Build up a single element
+ intialization as a proxy for the full array initialization to get things
+ marked as used and any appropriate diagnostics.
+
+ Since we're deferring building the actual constructor calls until
+ gimplification time, we need to build one now and throw it away so
+ that the relevant constructor gets mark_used before cgraph decides
+ what functions are needed. Here we assume that init is either
+ NULL_TREE, void_type_node (indicating value-initialization), or
+ another array to copy. */
+
+static tree
+build_vec_init_elt (tree type, tree init, tsubst_flags_t complain)
+{
+ tree inner_type = strip_array_types (type);
+ vec<tree, va_gc> *argvec;
+
+ if (integer_zerop (array_type_nelts_total (type))
+ || !CLASS_TYPE_P (inner_type))
+ /* No interesting initialization to do. */
+ return integer_zero_node;
+ else if (init == void_type_node)
+ return build_value_init (inner_type, complain);
+
+ gcc_assert (init == NULL_TREE
+ || (same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (init))));
+
+ argvec = make_tree_vector ();
+ if (init)
+ {
+ tree init_type = strip_array_types (TREE_TYPE (init));
+ tree dummy = build_dummy_object (init_type);
+ if (!real_lvalue_p (init))
+ dummy = move (dummy);
+ argvec->quick_push (dummy);
+ }
+ init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ &argvec, inner_type, LOOKUP_NORMAL,
+ complain);
+ release_tree_vector (argvec);
+
+ /* For a trivial constructor, build_over_call creates a TARGET_EXPR. But
+ we don't want one here because we aren't creating a temporary. */
+ if (TREE_CODE (init) == TARGET_EXPR)
+ init = TARGET_EXPR_INITIAL (init);
+
+ return init;
+}
+
+/* Return a TARGET_EXPR which expresses the initialization of an array to
+ be named later, either default-initialization or copy-initialization
+ from another array of the same type. */
+
+tree
+build_vec_init_expr (tree type, tree init, tsubst_flags_t complain)
+{
+ tree slot;
+ bool value_init = false;
+ tree elt_init = build_vec_init_elt (type, init, complain);
+
+ if (init == void_type_node)
+ {
+ value_init = true;
+ init = NULL_TREE;
+ }
+
+ slot = build_local_temp (type);
+ init = build2 (VEC_INIT_EXPR, type, slot, init);
+ TREE_SIDE_EFFECTS (init) = true;
+ SET_EXPR_LOCATION (init, input_location);
+
+ if (cxx_dialect >= cxx11
+ && potential_constant_expression (elt_init))
+ VEC_INIT_EXPR_IS_CONSTEXPR (init) = true;
+ VEC_INIT_EXPR_VALUE_INIT (init) = value_init;
+
+ return init;
+}
+
+/* Give a helpful diagnostic for a non-constexpr VEC_INIT_EXPR in a context
+ that requires a constant expression. */
+
+void
+diagnose_non_constexpr_vec_init (tree expr)
+{
+ tree type = TREE_TYPE (VEC_INIT_EXPR_SLOT (expr));
+ tree init, elt_init;
+ if (VEC_INIT_EXPR_VALUE_INIT (expr))
+ init = void_type_node;
+ else
+ init = VEC_INIT_EXPR_INIT (expr);
+
+ elt_init = build_vec_init_elt (type, init, tf_warning_or_error);
+ require_potential_constant_expression (elt_init);
+}
+
+tree
+build_array_copy (tree init)
+{
+ return build_vec_init_expr (TREE_TYPE (init), init, tf_warning_or_error);
+}
+
+/* Build a TARGET_EXPR using INIT to initialize a new temporary of the
+ indicated TYPE. */
+
+tree
+build_target_expr_with_type (tree init, tree type, tsubst_flags_t complain)
+{
+ gcc_assert (!VOID_TYPE_P (type));
+
+ if (TREE_CODE (init) == TARGET_EXPR
+ || init == error_mark_node)
+ return init;
+ else if (CLASS_TYPE_P (type) && type_has_nontrivial_copy_init (type)
+ && !VOID_TYPE_P (TREE_TYPE (init))
+ && TREE_CODE (init) != COND_EXPR
+ && TREE_CODE (init) != CONSTRUCTOR
+ && TREE_CODE (init) != VA_ARG_EXPR)
+ /* We need to build up a copy constructor call. A void initializer
+ means we're being called from bot_manip. COND_EXPR is a special
+ case because we already have copies on the arms and we don't want
+ another one here. A CONSTRUCTOR is aggregate initialization, which
+ is handled separately. A VA_ARG_EXPR is magic creation of an
+ aggregate; there's no additional work to be done. */
+ return force_rvalue (init, complain);
+
+ return force_target_expr (type, init, complain);
+}
+
+/* Like the above function, but without the checking. This function should
+ only be used by code which is deliberately trying to subvert the type
+ system, such as call_builtin_trap. Or build_over_call, to avoid
+ infinite recursion. */
+
+tree
+force_target_expr (tree type, tree init, tsubst_flags_t complain)
+{
+ tree slot;
+
+ gcc_assert (!VOID_TYPE_P (type));
+
+ slot = build_local_temp (type);
+ return build_target_expr (slot, init, complain);
+}
+
+/* Like build_target_expr_with_type, but use the type of INIT. */
+
+tree
+get_target_expr_sfinae (tree init, tsubst_flags_t complain)
+{
+ if (TREE_CODE (init) == AGGR_INIT_EXPR)
+ return build_target_expr (AGGR_INIT_EXPR_SLOT (init), init, complain);
+ else if (TREE_CODE (init) == VEC_INIT_EXPR)
+ return build_target_expr (VEC_INIT_EXPR_SLOT (init), init, complain);
+ else
+ return build_target_expr_with_type (init, TREE_TYPE (init), complain);
+}
+
+tree
+get_target_expr (tree init)
+{
+ return get_target_expr_sfinae (init, tf_warning_or_error);
+}
+
+/* If EXPR is a bitfield reference, convert it to the declared type of
+ the bitfield, and return the resulting expression. Otherwise,
+ return EXPR itself. */
+
+tree
+convert_bitfield_to_declared_type (tree expr)
+{
+ tree bitfield_type;
+
+ bitfield_type = is_bitfield_expr_with_lowered_type (expr);
+ if (bitfield_type)
+ expr = convert_to_integer (TYPE_MAIN_VARIANT (bitfield_type),
+ expr);
+ return expr;
+}
+
+/* EXPR is being used in an rvalue context. Return a version of EXPR
+ that is marked as an rvalue. */
+
+tree
+rvalue (tree expr)
+{
+ tree type;
+
+ if (error_operand_p (expr))
+ return expr;
+
+ expr = mark_rvalue_use (expr);
+
+ /* [basic.lval]
+
+ Non-class rvalues always have cv-unqualified types. */
+ type = TREE_TYPE (expr);
+ if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
+ type = cv_unqualified (type);
+
+ /* We need to do this for rvalue refs as well to get the right answer
+ from decltype; see c++/36628. */
+ if (!processing_template_decl && lvalue_or_rvalue_with_address_p (expr))
+ expr = build1 (NON_LVALUE_EXPR, type, expr);
+ else if (type != TREE_TYPE (expr))
+ expr = build_nop (type, expr);
+
+ return expr;
+}
+
+
+/* Hash an ARRAY_TYPE. K is really of type `tree'. */
+
+static hashval_t
+cplus_array_hash (const void* k)
+{
+ hashval_t hash;
+ const_tree const t = (const_tree) k;
+
+ hash = TYPE_UID (TREE_TYPE (t));
+ if (TYPE_DOMAIN (t))
+ hash ^= TYPE_UID (TYPE_DOMAIN (t));
+ return hash;
+}
+
+typedef struct cplus_array_info {
+ tree type;
+ tree domain;
+} cplus_array_info;
+
+/* Compare two ARRAY_TYPEs. K1 is really of type `tree', K2 is really
+ of type `cplus_array_info*'. */
+
+static int
+cplus_array_compare (const void * k1, const void * k2)
+{
+ const_tree const t1 = (const_tree) k1;
+ const cplus_array_info *const t2 = (const cplus_array_info*) k2;
+
+ return (TREE_TYPE (t1) == t2->type && TYPE_DOMAIN (t1) == t2->domain);
+}
+
+/* Hash table containing dependent array types, which are unsuitable for
+ the language-independent type hash table. */
+static GTY ((param_is (union tree_node))) htab_t cplus_array_htab;
+
+/* Like build_array_type, but handle special C++ semantics. */
+
+tree
+build_cplus_array_type (tree elt_type, tree index_type)
+{
+ tree t;
+
+ if (elt_type == error_mark_node || index_type == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl
+ && (dependent_type_p (elt_type)
+ || (index_type && !TREE_CONSTANT (TYPE_MAX_VALUE (index_type)))))
+ {
+ void **e;
+ cplus_array_info cai;
+ hashval_t hash;
+
+ if (cplus_array_htab == NULL)
+ cplus_array_htab = htab_create_ggc (61, &cplus_array_hash,
+ &cplus_array_compare, NULL);
+
+ hash = TYPE_UID (elt_type);
+ if (index_type)
+ hash ^= TYPE_UID (index_type);
+ cai.type = elt_type;
+ cai.domain = index_type;
+
+ e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash, INSERT);
+ if (*e)
+ /* We have found the type: we're done. */
+ return (tree) *e;
+ else
+ {
+ /* Build a new array type. */
+ t = cxx_make_type (ARRAY_TYPE);
+ TREE_TYPE (t) = elt_type;
+ TYPE_DOMAIN (t) = index_type;
+
+ /* Store it in the hash table. */
+ *e = t;
+
+ /* Set the canonical type for this new node. */
+ if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
+ || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)))
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else if (TYPE_CANONICAL (elt_type) != elt_type
+ || (index_type
+ && TYPE_CANONICAL (index_type) != index_type))
+ TYPE_CANONICAL (t)
+ = build_cplus_array_type
+ (TYPE_CANONICAL (elt_type),
+ index_type ? TYPE_CANONICAL (index_type) : index_type);
+ else
+ TYPE_CANONICAL (t) = t;
+ }
+ }
+ else
+ {
+ if (!TYPE_STRUCTURAL_EQUALITY_P (elt_type)
+ && !(index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))
+ && (TYPE_CANONICAL (elt_type) != elt_type
+ || (index_type && TYPE_CANONICAL (index_type) != index_type)))
+ /* Make sure that the canonical type is on the appropriate
+ variants list. */
+ build_cplus_array_type
+ (TYPE_CANONICAL (elt_type),
+ index_type ? TYPE_CANONICAL (index_type) : index_type);
+ t = build_array_type (elt_type, index_type);
+ }
+
+ /* Push these needs up so that initialization takes place
+ more easily. */
+ bool needs_ctor
+ = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type));
+ TYPE_NEEDS_CONSTRUCTING (t) = needs_ctor;
+ bool needs_dtor
+ = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type));
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = needs_dtor;
+
+ /* We want TYPE_MAIN_VARIANT of an array to strip cv-quals from the
+ element type as well, so fix it up if needed. */
+ if (elt_type != TYPE_MAIN_VARIANT (elt_type))
+ {
+ tree m = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type),
+ index_type);
+
+ if (TYPE_MAIN_VARIANT (t) != m)
+ {
+ if (COMPLETE_TYPE_P (TREE_TYPE (t)) && !COMPLETE_TYPE_P (m))
+ {
+ /* m was built before the element type was complete, so we
+ also need to copy the layout info from t. We might
+ end up doing this multiple times if t is an array of
+ unknown bound. */
+ tree size = TYPE_SIZE (t);
+ tree size_unit = TYPE_SIZE_UNIT (t);
+ unsigned int align = TYPE_ALIGN (t);
+ unsigned int user_align = TYPE_USER_ALIGN (t);
+ enum machine_mode mode = TYPE_MODE (t);
+ for (tree var = m; var; var = TYPE_NEXT_VARIANT (var))
+ {
+ TYPE_SIZE (var) = size;
+ TYPE_SIZE_UNIT (var) = size_unit;
+ TYPE_ALIGN (var) = align;
+ TYPE_USER_ALIGN (var) = user_align;
+ SET_TYPE_MODE (var, mode);
+ TYPE_NEEDS_CONSTRUCTING (var) = needs_ctor;
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (var) = needs_dtor;
+ }
+ }
+
+ TYPE_MAIN_VARIANT (t) = m;
+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
+ TYPE_NEXT_VARIANT (m) = t;
+ }
+ }
+
+ /* Avoid spurious warnings with VLAs (c++/54583). */
+ if (TYPE_SIZE (t) && EXPR_P (TYPE_SIZE (t)))
+ TREE_NO_WARNING (TYPE_SIZE (t)) = 1;
+
+ return t;
+}
+
+/* Return an ARRAY_TYPE with element type ELT and length N. */
+
+tree
+build_array_of_n_type (tree elt, int n)
+{
+ return build_cplus_array_type (elt, build_index_type (size_int (n - 1)));
+}
+
+/* True iff T is a C++1y array of runtime bound (VLA). */
+
+bool
+array_of_runtime_bound_p (tree t)
+{
+ if (!t || TREE_CODE (t) != ARRAY_TYPE)
+ return false;
+ tree dom = TYPE_DOMAIN (t);
+ if (!dom)
+ return false;
+ tree max = TYPE_MAX_VALUE (dom);
+ return (!potential_rvalue_constant_expression (max)
+ || (!value_dependent_expression_p (max) && !TREE_CONSTANT (max)));
+}
+
+/* Return a reference type node referring to TO_TYPE. If RVAL is
+ true, return an rvalue reference type, otherwise return an lvalue
+ reference type. If a type node exists, reuse it, otherwise create
+ a new one. */
+tree
+cp_build_reference_type (tree to_type, bool rval)
+{
+ tree lvalue_ref, t;
+ lvalue_ref = build_reference_type (to_type);
+ if (!rval)
+ return lvalue_ref;
+
+ /* This code to create rvalue reference types is based on and tied
+ to the code creating lvalue reference types in the middle-end
+ functions build_reference_type_for_mode and build_reference_type.
+
+ It works by putting the rvalue reference type nodes after the
+ lvalue reference nodes in the TYPE_NEXT_REF_TO linked list, so
+ they will effectively be ignored by the middle end. */
+
+ for (t = lvalue_ref; (t = TYPE_NEXT_REF_TO (t)); )
+ if (TYPE_REF_IS_RVALUE (t))
+ return t;
+
+ t = build_distinct_type_copy (lvalue_ref);
+
+ TYPE_REF_IS_RVALUE (t) = true;
+ TYPE_NEXT_REF_TO (t) = TYPE_NEXT_REF_TO (lvalue_ref);
+ TYPE_NEXT_REF_TO (lvalue_ref) = t;
+
+ if (TYPE_STRUCTURAL_EQUALITY_P (to_type))
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else if (TYPE_CANONICAL (to_type) != to_type)
+ TYPE_CANONICAL (t)
+ = cp_build_reference_type (TYPE_CANONICAL (to_type), rval);
+ else
+ TYPE_CANONICAL (t) = t;
+
+ layout_type (t);
+
+ return t;
+
+}
+
+/* Returns EXPR cast to rvalue reference type, like std::move. */
+
+tree
+move (tree expr)
+{
+ tree type = TREE_TYPE (expr);
+ gcc_assert (TREE_CODE (type) != REFERENCE_TYPE);
+ type = cp_build_reference_type (type, /*rval*/true);
+ return build_static_cast (type, expr, tf_warning_or_error);
+}
+
+/* Used by the C++ front end to build qualified array types. However,
+ the C version of this function does not properly maintain canonical
+ types (which are not used in C). */
+tree
+c_build_qualified_type (tree type, int type_quals)
+{
+ return cp_build_qualified_type (type, type_quals);
+}
+
+
+/* Make a variant of TYPE, qualified with the TYPE_QUALS. Handles
+ arrays correctly. In particular, if TYPE is an array of T's, and
+ TYPE_QUALS is non-empty, returns an array of qualified T's.
+
+ FLAGS determines how to deal with ill-formed qualifications. If
+ tf_ignore_bad_quals is set, then bad qualifications are dropped
+ (this is permitted if TYPE was introduced via a typedef or template
+ type parameter). If bad qualifications are dropped and tf_warning
+ is set, then a warning is issued for non-const qualifications. If
+ tf_ignore_bad_quals is not set and tf_error is not set, we
+ return error_mark_node. Otherwise, we issue an error, and ignore
+ the qualifications.
+
+ Qualification of a reference type is valid when the reference came
+ via a typedef or template type argument. [dcl.ref] No such
+ dispensation is provided for qualifying a function type. [dcl.fct]
+ DR 295 queries this and the proposed resolution brings it into line
+ with qualifying a reference. We implement the DR. We also behave
+ in a similar manner for restricting non-pointer types. */
+
+tree
+cp_build_qualified_type_real (tree type,
+ int type_quals,
+ tsubst_flags_t complain)
+{
+ tree result;
+ int bad_quals = TYPE_UNQUALIFIED;
+
+ if (type == error_mark_node)
+ return type;
+
+ if (type_quals == cp_type_quals (type))
+ return type;
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ /* In C++, the qualification really applies to the array element
+ type. Obtain the appropriately qualified element type. */
+ tree t;
+ tree element_type
+ = cp_build_qualified_type_real (TREE_TYPE (type),
+ type_quals,
+ complain);
+
+ if (element_type == error_mark_node)
+ return error_mark_node;
+
+ /* See if we already have an identically qualified type. Tests
+ should be equivalent to those in check_qualified_type. */
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ if (TREE_TYPE (t) == element_type
+ && TYPE_NAME (t) == TYPE_NAME (type)
+ && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
+ && attribute_list_equal (TYPE_ATTRIBUTES (t),
+ TYPE_ATTRIBUTES (type)))
+ break;
+
+ if (!t)
+ {
+ t = build_cplus_array_type (element_type, TYPE_DOMAIN (type));
+
+ /* Keep the typedef name. */
+ if (TYPE_NAME (t) != TYPE_NAME (type))
+ {
+ t = build_variant_type_copy (t);
+ TYPE_NAME (t) = TYPE_NAME (type);
+ }
+ }
+
+ /* Even if we already had this variant, we update
+ TYPE_NEEDS_CONSTRUCTING and TYPE_HAS_NONTRIVIAL_DESTRUCTOR in case
+ they changed since the variant was originally created.
+
+ This seems hokey; if there is some way to use a previous
+ variant *without* coming through here,
+ TYPE_NEEDS_CONSTRUCTING will never be updated. */
+ TYPE_NEEDS_CONSTRUCTING (t)
+ = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (element_type));
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
+ = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (element_type));
+ return t;
+ }
+ else if (TYPE_PTRMEMFUNC_P (type))
+ {
+ /* For a pointer-to-member type, we can't just return a
+ cv-qualified version of the RECORD_TYPE. If we do, we
+ haven't changed the field that contains the actual pointer to
+ a method, and so TYPE_PTRMEMFUNC_FN_TYPE will be wrong. */
+ tree t;
+
+ t = TYPE_PTRMEMFUNC_FN_TYPE (type);
+ t = cp_build_qualified_type_real (t, type_quals, complain);
+ return build_ptrmemfunc_type (t);
+ }
+ else if (TREE_CODE (type) == TYPE_PACK_EXPANSION)
+ {
+ tree t = PACK_EXPANSION_PATTERN (type);
+
+ t = cp_build_qualified_type_real (t, type_quals, complain);
+ return make_pack_expansion (t);
+ }
+
+ /* A reference or method type shall not be cv-qualified.
+ [dcl.ref], [dcl.fct]. This used to be an error, but as of DR 295
+ (in CD1) we always ignore extra cv-quals on functions. */
+ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
+ && (TREE_CODE (type) == REFERENCE_TYPE
+ || TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE))
+ {
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ }
+
+ /* But preserve any function-cv-quals on a FUNCTION_TYPE. */
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ type_quals |= type_memfn_quals (type);
+
+ /* A restrict-qualified type must be a pointer (or reference)
+ to object or incomplete type. */
+ if ((type_quals & TYPE_QUAL_RESTRICT)
+ && TREE_CODE (type) != TEMPLATE_TYPE_PARM
+ && TREE_CODE (type) != TYPENAME_TYPE
+ && !POINTER_TYPE_P (type))
+ {
+ bad_quals |= TYPE_QUAL_RESTRICT;
+ type_quals &= ~TYPE_QUAL_RESTRICT;
+ }
+
+ if (bad_quals == TYPE_UNQUALIFIED
+ || (complain & tf_ignore_bad_quals))
+ /*OK*/;
+ else if (!(complain & tf_error))
+ return error_mark_node;
+ else
+ {
+ tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
+ error ("%qV qualifiers cannot be applied to %qT",
+ bad_type, type);
+ }
+
+ /* Retrieve (or create) the appropriately qualified variant. */
+ result = build_qualified_type (type, type_quals);
+
+ /* Preserve exception specs and ref-qualifier since build_qualified_type
+ doesn't know about them. */
+ if (TREE_CODE (result) == FUNCTION_TYPE
+ || TREE_CODE (result) == METHOD_TYPE)
+ {
+ result = build_exception_variant (result, TYPE_RAISES_EXCEPTIONS (type));
+ result = build_ref_qualified_type (result, type_memfn_rqual (type));
+ }
+
+ /* If this was a pointer-to-method type, and we just made a copy,
+ then we need to unshare the record that holds the cached
+ pointer-to-member-function type, because these will be distinct
+ between the unqualified and qualified types. */
+ if (result != type
+ && TYPE_PTR_P (type)
+ && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE
+ && TYPE_LANG_SPECIFIC (result) == TYPE_LANG_SPECIFIC (type))
+ TYPE_LANG_SPECIFIC (result) = NULL;
+
+ /* We may also have ended up building a new copy of the canonical
+ type of a pointer-to-method type, which could have the same
+ sharing problem described above. */
+ if (TYPE_CANONICAL (result) != TYPE_CANONICAL (type)
+ && TYPE_PTR_P (type)
+ && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE
+ && (TYPE_LANG_SPECIFIC (TYPE_CANONICAL (result))
+ == TYPE_LANG_SPECIFIC (TYPE_CANONICAL (type))))
+ TYPE_LANG_SPECIFIC (TYPE_CANONICAL (result)) = NULL;
+
+ return result;
+}
+
+/* Return TYPE with const and volatile removed. */
+
+tree
+cv_unqualified (tree type)
+{
+ int quals;
+
+ if (type == error_mark_node)
+ return type;
+
+ quals = cp_type_quals (type);
+ quals &= ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
+ return cp_build_qualified_type (type, quals);
+}
+
+/* Builds a qualified variant of T that is not a typedef variant.
+ E.g. consider the following declarations:
+ typedef const int ConstInt;
+ typedef ConstInt* PtrConstInt;
+ If T is PtrConstInt, this function returns a type representing
+ const int*.
+ In other words, if T is a typedef, the function returns the underlying type.
+ The cv-qualification and attributes of the type returned match the
+ input type.
+ They will always be compatible types.
+ The returned type is built so that all of its subtypes
+ recursively have their typedefs stripped as well.
+
+ This is different from just returning TYPE_CANONICAL (T)
+ Because of several reasons:
+ * If T is a type that needs structural equality
+ its TYPE_CANONICAL (T) will be NULL.
+ * TYPE_CANONICAL (T) desn't carry type attributes
+ and loses template parameter names. */
+
+tree
+strip_typedefs (tree t)
+{
+ tree result = NULL, type = NULL, t0 = NULL;
+
+ if (!t || t == error_mark_node || t == TYPE_CANONICAL (t))
+ return t;
+
+ gcc_assert (TYPE_P (t));
+
+ switch (TREE_CODE (t))
+ {
+ case POINTER_TYPE:
+ type = strip_typedefs (TREE_TYPE (t));
+ result = build_pointer_type (type);
+ break;
+ case REFERENCE_TYPE:
+ type = strip_typedefs (TREE_TYPE (t));
+ result = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
+ break;
+ case OFFSET_TYPE:
+ t0 = strip_typedefs (TYPE_OFFSET_BASETYPE (t));
+ type = strip_typedefs (TREE_TYPE (t));
+ result = build_offset_type (t0, type);
+ break;
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ {
+ t0 = strip_typedefs (TYPE_PTRMEMFUNC_FN_TYPE (t));
+ result = build_ptrmemfunc_type (t0);
+ }
+ break;
+ case ARRAY_TYPE:
+ type = strip_typedefs (TREE_TYPE (t));
+ t0 = strip_typedefs (TYPE_DOMAIN (t));;
+ result = build_cplus_array_type (type, t0);
+ break;
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ {
+ tree arg_types = NULL, arg_node, arg_type;
+ for (arg_node = TYPE_ARG_TYPES (t);
+ arg_node;
+ arg_node = TREE_CHAIN (arg_node))
+ {
+ if (arg_node == void_list_node)
+ break;
+ arg_type = strip_typedefs (TREE_VALUE (arg_node));
+ gcc_assert (arg_type);
+
+ arg_types =
+ tree_cons (TREE_PURPOSE (arg_node), arg_type, arg_types);
+ }
+
+ if (arg_types)
+ arg_types = nreverse (arg_types);
+
+ /* A list of parameters not ending with an ellipsis
+ must end with void_list_node. */
+ if (arg_node)
+ arg_types = chainon (arg_types, void_list_node);
+
+ type = strip_typedefs (TREE_TYPE (t));
+ if (TREE_CODE (t) == METHOD_TYPE)
+ {
+ tree class_type = TREE_TYPE (TREE_VALUE (arg_types));
+ gcc_assert (class_type);
+ result =
+ build_method_type_directly (class_type, type,
+ TREE_CHAIN (arg_types));
+ result
+ = build_ref_qualified_type (result, type_memfn_rqual (t));
+ }
+ else
+ {
+ result = build_function_type (type,
+ arg_types);
+ result = apply_memfn_quals (result,
+ type_memfn_quals (t),
+ type_memfn_rqual (t));
+ }
+
+ if (TYPE_RAISES_EXCEPTIONS (t))
+ result = build_exception_variant (result,
+ TYPE_RAISES_EXCEPTIONS (t));
+ }
+ break;
+ case TYPENAME_TYPE:
+ {
+ tree fullname = TYPENAME_TYPE_FULLNAME (t);
+ if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR
+ && TREE_OPERAND (fullname, 1))
+ {
+ tree args = TREE_OPERAND (fullname, 1);
+ tree new_args = copy_node (args);
+ bool changed = false;
+ for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
+ {
+ tree arg = TREE_VEC_ELT (args, i);
+ tree strip_arg;
+ if (TYPE_P (arg))
+ strip_arg = strip_typedefs (arg);
+ else
+ strip_arg = strip_typedefs_expr (arg);
+ TREE_VEC_ELT (new_args, i) = strip_arg;
+ if (strip_arg != arg)
+ changed = true;
+ }
+ if (changed)
+ {
+ NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_args)
+ = NON_DEFAULT_TEMPLATE_ARGS_COUNT (args);
+ fullname
+ = lookup_template_function (TREE_OPERAND (fullname, 0),
+ new_args);
+ }
+ else
+ ggc_free (new_args);
+ }
+ result = make_typename_type (strip_typedefs (TYPE_CONTEXT (t)),
+ fullname, typename_type, tf_none);
+ }
+ break;
+ case DECLTYPE_TYPE:
+ result = strip_typedefs_expr (DECLTYPE_TYPE_EXPR (t));
+ if (result == DECLTYPE_TYPE_EXPR (t))
+ return t;
+ else
+ result = (finish_decltype_type
+ (result,
+ DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t),
+ tf_none));
+ break;
+ default:
+ break;
+ }
+
+ if (!result)
+ result = TYPE_MAIN_VARIANT (t);
+ if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result)
+ || TYPE_ALIGN (t) != TYPE_ALIGN (result))
+ {
+ gcc_assert (TYPE_USER_ALIGN (t));
+ if (TYPE_ALIGN (t) == TYPE_ALIGN (result))
+ result = build_variant_type_copy (result);
+ else
+ result = build_aligned_type (result, TYPE_ALIGN (t));
+ TYPE_USER_ALIGN (result) = true;
+ }
+ if (TYPE_ATTRIBUTES (t))
+ result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t));
+ return cp_build_qualified_type (result, cp_type_quals (t));
+}
+
+/* Like strip_typedefs above, but works on expressions, so that in
+
+ template<class T> struct A
+ {
+ typedef T TT;
+ B<sizeof(TT)> b;
+ };
+
+ sizeof(TT) is replaced by sizeof(T). */
+
+tree
+strip_typedefs_expr (tree t)
+{
+ unsigned i,n;
+ tree r, type, *ops;
+ enum tree_code code;
+
+ if (t == NULL_TREE || t == error_mark_node)
+ return t;
+
+ if (DECL_P (t) || CONSTANT_CLASS_P (t))
+ return t;
+
+ /* Some expressions have type operands, so let's handle types here rather
+ than check TYPE_P in multiple places below. */
+ if (TYPE_P (t))
+ return strip_typedefs (t);
+
+ code = TREE_CODE (t);
+ switch (code)
+ {
+ case IDENTIFIER_NODE:
+ case TEMPLATE_PARM_INDEX:
+ case OVERLOAD:
+ case BASELINK:
+ case ARGUMENT_PACK_SELECT:
+ return t;
+
+ case TRAIT_EXPR:
+ {
+ tree type1 = strip_typedefs (TRAIT_EXPR_TYPE1 (t));
+ tree type2 = strip_typedefs (TRAIT_EXPR_TYPE2 (t));
+ if (type1 == TRAIT_EXPR_TYPE1 (t)
+ && type2 == TRAIT_EXPR_TYPE2 (t))
+ return t;
+ r = copy_node (t);
+ TRAIT_EXPR_TYPE1 (t) = type1;
+ TRAIT_EXPR_TYPE2 (t) = type2;
+ return r;
+ }
+
+ case TREE_LIST:
+ {
+ vec<tree, va_gc> *vec = make_tree_vector ();
+ bool changed = false;
+ tree it;
+ for (it = t; it; it = TREE_CHAIN (it))
+ {
+ tree val = strip_typedefs_expr (TREE_VALUE (t));
+ vec_safe_push (vec, val);
+ if (val != TREE_VALUE (t))
+ changed = true;
+ gcc_assert (TREE_PURPOSE (it) == NULL_TREE);
+ }
+ if (changed)
+ {
+ r = NULL_TREE;
+ FOR_EACH_VEC_ELT_REVERSE (*vec, i, it)
+ r = tree_cons (NULL_TREE, it, r);
+ }
+ else
+ r = t;
+ release_tree_vector (vec);
+ return r;
+ }
+
+ case TREE_VEC:
+ {
+ bool changed = false;
+ vec<tree, va_gc> *vec = make_tree_vector ();
+ n = TREE_VEC_LENGTH (t);
+ vec_safe_reserve (vec, n);
+ for (i = 0; i < n; ++i)
+ {
+ tree op = strip_typedefs_expr (TREE_VEC_ELT (t, i));
+ vec->quick_push (op);
+ if (op != TREE_VEC_ELT (t, i))
+ changed = true;
+ }
+ if (changed)
+ {
+ r = copy_node (t);
+ for (i = 0; i < n; ++i)
+ TREE_VEC_ELT (r, i) = (*vec)[i];
+ NON_DEFAULT_TEMPLATE_ARGS_COUNT (r)
+ = NON_DEFAULT_TEMPLATE_ARGS_COUNT (t);
+ }
+ else
+ r = t;
+ release_tree_vector (vec);
+ return r;
+ }
+
+ case CONSTRUCTOR:
+ {
+ bool changed = false;
+ vec<constructor_elt, va_gc> *vec
+ = vec_safe_copy (CONSTRUCTOR_ELTS (t));
+ n = CONSTRUCTOR_NELTS (t);
+ type = strip_typedefs (TREE_TYPE (t));
+ for (i = 0; i < n; ++i)
+ {
+ constructor_elt *e = &(*vec)[i];
+ tree op = strip_typedefs_expr (e->value);
+ if (op != e->value)
+ {
+ changed = true;
+ e->value = op;
+ }
+ gcc_checking_assert (e->index == strip_typedefs_expr (e->index));
+ }
+
+ if (!changed && type == TREE_TYPE (t))
+ {
+ vec_free (vec);
+ return t;
+ }
+ else
+ {
+ r = copy_node (t);
+ TREE_TYPE (r) = type;
+ CONSTRUCTOR_ELTS (r) = vec;
+ return r;
+ }
+ }
+
+ case LAMBDA_EXPR:
+ error ("lambda-expression in a constant expression");
+ return error_mark_node;
+
+ default:
+ break;
+ }
+
+ gcc_assert (EXPR_P (t));
+
+ n = TREE_OPERAND_LENGTH (t);
+ ops = XALLOCAVEC (tree, n);
+ type = TREE_TYPE (t);
+
+ switch (code)
+ {
+ CASE_CONVERT:
+ case IMPLICIT_CONV_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CAST_EXPR:
+ case NEW_EXPR:
+ type = strip_typedefs (type);
+ /* fallthrough */
+
+ default:
+ for (i = 0; i < n; ++i)
+ ops[i] = strip_typedefs_expr (TREE_OPERAND (t, i));
+ break;
+ }
+
+ /* If nothing changed, return t. */
+ for (i = 0; i < n; ++i)
+ if (ops[i] != TREE_OPERAND (t, i))
+ break;
+ if (i == n && type == TREE_TYPE (t))
+ return t;
+
+ r = copy_node (t);
+ TREE_TYPE (r) = type;
+ for (i = 0; i < n; ++i)
+ TREE_OPERAND (r, i) = ops[i];
+ return r;
+}
+
+/* Makes a copy of BINFO and TYPE, which is to be inherited into a
+ graph dominated by T. If BINFO is NULL, TYPE is a dependent base,
+ and we do a shallow copy. If BINFO is non-NULL, we do a deep copy.
+ VIRT indicates whether TYPE is inherited virtually or not.
+ IGO_PREV points at the previous binfo of the inheritance graph
+ order chain. The newly copied binfo's TREE_CHAIN forms this
+ ordering.
+
+ The CLASSTYPE_VBASECLASSES vector of T is constructed in the
+ correct order. That is in the order the bases themselves should be
+ constructed in.
+
+ The BINFO_INHERITANCE of a virtual base class points to the binfo
+ of the most derived type. ??? We could probably change this so that
+ BINFO_INHERITANCE becomes synonymous with BINFO_PRIMARY, and hence
+ remove a field. They currently can only differ for primary virtual
+ virtual bases. */
+
+tree
+copy_binfo (tree binfo, tree type, tree t, tree *igo_prev, int virt)
+{
+ tree new_binfo;
+
+ if (virt)
+ {
+ /* See if we've already made this virtual base. */
+ new_binfo = binfo_for_vbase (type, t);
+ if (new_binfo)
+ return new_binfo;
+ }
+
+ new_binfo = make_tree_binfo (binfo ? BINFO_N_BASE_BINFOS (binfo) : 0);
+ BINFO_TYPE (new_binfo) = type;
+
+ /* Chain it into the inheritance graph. */
+ TREE_CHAIN (*igo_prev) = new_binfo;
+ *igo_prev = new_binfo;
+
+ if (binfo && !BINFO_DEPENDENT_BASE_P (binfo))
+ {
+ int ix;
+ tree base_binfo;
+
+ gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), type));
+
+ BINFO_OFFSET (new_binfo) = BINFO_OFFSET (binfo);
+ BINFO_VIRTUALS (new_binfo) = BINFO_VIRTUALS (binfo);
+
+ /* We do not need to copy the accesses, as they are read only. */
+ BINFO_BASE_ACCESSES (new_binfo) = BINFO_BASE_ACCESSES (binfo);
+
+ /* Recursively copy base binfos of BINFO. */
+ for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
+ {
+ tree new_base_binfo;
+ new_base_binfo = copy_binfo (base_binfo, BINFO_TYPE (base_binfo),
+ t, igo_prev,
+ BINFO_VIRTUAL_P (base_binfo));
+
+ if (!BINFO_INHERITANCE_CHAIN (new_base_binfo))
+ BINFO_INHERITANCE_CHAIN (new_base_binfo) = new_binfo;
+ BINFO_BASE_APPEND (new_binfo, new_base_binfo);
+ }
+ }
+ else
+ BINFO_DEPENDENT_BASE_P (new_binfo) = 1;
+
+ if (virt)
+ {
+ /* Push it onto the list after any virtual bases it contains
+ will have been pushed. */
+ CLASSTYPE_VBASECLASSES (t)->quick_push (new_binfo);
+ BINFO_VIRTUAL_P (new_binfo) = 1;
+ BINFO_INHERITANCE_CHAIN (new_binfo) = TYPE_BINFO (t);
+ }
+
+ return new_binfo;
+}
+
+/* Hashing of lists so that we don't make duplicates.
+ The entry point is `list_hash_canon'. */
+
+/* Now here is the hash table. When recording a list, it is added
+ to the slot whose index is the hash code mod the table size.
+ Note that the hash table is used for several kinds of lists.
+ While all these live in the same table, they are completely independent,
+ and the hash code is computed differently for each of these. */
+
+static GTY ((param_is (union tree_node))) htab_t list_hash_table;
+
+struct list_proxy
+{
+ tree purpose;
+ tree value;
+ tree chain;
+};
+
+/* Compare ENTRY (an entry in the hash table) with DATA (a list_proxy
+ for a node we are thinking about adding). */
+
+static int
+list_hash_eq (const void* entry, const void* data)
+{
+ const_tree const t = (const_tree) entry;
+ const struct list_proxy *const proxy = (const struct list_proxy *) data;
+
+ return (TREE_VALUE (t) == proxy->value
+ && TREE_PURPOSE (t) == proxy->purpose
+ && TREE_CHAIN (t) == proxy->chain);
+}
+
+/* Compute a hash code for a list (chain of TREE_LIST nodes
+ with goodies in the TREE_PURPOSE, TREE_VALUE, and bits of the
+ TREE_COMMON slots), by adding the hash codes of the individual entries. */
+
+static hashval_t
+list_hash_pieces (tree purpose, tree value, tree chain)
+{
+ hashval_t hashcode = 0;
+
+ if (chain)
+ hashcode += TREE_HASH (chain);
+
+ if (value)
+ hashcode += TREE_HASH (value);
+ else
+ hashcode += 1007;
+ if (purpose)
+ hashcode += TREE_HASH (purpose);
+ else
+ hashcode += 1009;
+ return hashcode;
+}
+
+/* Hash an already existing TREE_LIST. */
+
+static hashval_t
+list_hash (const void* p)
+{
+ const_tree const t = (const_tree) p;
+ return list_hash_pieces (TREE_PURPOSE (t),
+ TREE_VALUE (t),
+ TREE_CHAIN (t));
+}
+
+/* Given list components PURPOSE, VALUE, AND CHAIN, return the canonical
+ object for an identical list if one already exists. Otherwise, build a
+ new one, and record it as the canonical object. */
+
+tree
+hash_tree_cons (tree purpose, tree value, tree chain)
+{
+ int hashcode = 0;
+ void **slot;
+ struct list_proxy proxy;
+
+ /* Hash the list node. */
+ hashcode = list_hash_pieces (purpose, value, chain);
+ /* Create a proxy for the TREE_LIST we would like to create. We
+ don't actually create it so as to avoid creating garbage. */
+ proxy.purpose = purpose;
+ proxy.value = value;
+ proxy.chain = chain;
+ /* See if it is already in the table. */
+ slot = htab_find_slot_with_hash (list_hash_table, &proxy, hashcode,
+ INSERT);
+ /* If not, create a new node. */
+ if (!*slot)
+ *slot = tree_cons (purpose, value, chain);
+ return (tree) *slot;
+}
+
+/* Constructor for hashed lists. */
+
+tree
+hash_tree_chain (tree value, tree chain)
+{
+ return hash_tree_cons (NULL_TREE, value, chain);
+}
+
+void
+debug_binfo (tree elem)
+{
+ HOST_WIDE_INT n;
+ tree virtuals;
+
+ fprintf (stderr, "type \"%s\", offset = " HOST_WIDE_INT_PRINT_DEC
+ "\nvtable type:\n",
+ TYPE_NAME_STRING (BINFO_TYPE (elem)),
+ TREE_INT_CST_LOW (BINFO_OFFSET (elem)));
+ debug_tree (BINFO_TYPE (elem));
+ if (BINFO_VTABLE (elem))
+ fprintf (stderr, "vtable decl \"%s\"\n",
+ IDENTIFIER_POINTER (DECL_NAME (get_vtbl_decl_for_binfo (elem))));
+ else
+ fprintf (stderr, "no vtable decl yet\n");
+ fprintf (stderr, "virtuals:\n");
+ virtuals = BINFO_VIRTUALS (elem);
+ n = 0;
+
+ while (virtuals)
+ {
+ tree fndecl = TREE_VALUE (virtuals);
+ fprintf (stderr, "%s [%ld =? %ld]\n",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)),
+ (long) n, (long) TREE_INT_CST_LOW (DECL_VINDEX (fndecl)));
+ ++n;
+ virtuals = TREE_CHAIN (virtuals);
+ }
+}
+
+/* Build a representation for the qualified name SCOPE::NAME. TYPE is
+ the type of the result expression, if known, or NULL_TREE if the
+ resulting expression is type-dependent. If TEMPLATE_P is true,
+ NAME is known to be a template because the user explicitly used the
+ "template" keyword after the "::".
+
+ All SCOPE_REFs should be built by use of this function. */
+
+tree
+build_qualified_name (tree type, tree scope, tree name, bool template_p)
+{
+ tree t;
+ if (type == error_mark_node
+ || scope == error_mark_node
+ || name == error_mark_node)
+ return error_mark_node;
+ t = build2 (SCOPE_REF, type, scope, name);
+ QUALIFIED_NAME_IS_TEMPLATE (t) = template_p;
+ PTRMEM_OK_P (t) = true;
+ if (type)
+ t = convert_from_reference (t);
+ return t;
+}
+
+/* Like check_qualified_type, but also check ref-qualifier and exception
+ specification. */
+
+static bool
+cp_check_qualified_type (const_tree cand, const_tree base, int type_quals,
+ cp_ref_qualifier rqual, tree raises)
+{
+ return (check_qualified_type (cand, base, type_quals)
+ && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (cand),
+ ce_exact)
+ && type_memfn_rqual (cand) == rqual);
+}
+
+/* Build the FUNCTION_TYPE or METHOD_TYPE with the ref-qualifier RQUAL. */
+
+tree
+build_ref_qualified_type (tree type, cp_ref_qualifier rqual)
+{
+ tree t;
+
+ if (rqual == type_memfn_rqual (type))
+ return type;
+
+ int type_quals = TYPE_QUALS (type);
+ tree raises = TYPE_RAISES_EXCEPTIONS (type);
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ if (cp_check_qualified_type (t, type, type_quals, rqual, raises))
+ return t;
+
+ t = build_variant_type_copy (type);
+ switch (rqual)
+ {
+ case REF_QUAL_RVALUE:
+ FUNCTION_RVALUE_QUALIFIED (t) = 1;
+ FUNCTION_REF_QUALIFIED (t) = 1;
+ break;
+ case REF_QUAL_LVALUE:
+ FUNCTION_RVALUE_QUALIFIED (t) = 0;
+ FUNCTION_REF_QUALIFIED (t) = 1;
+ break;
+ default:
+ FUNCTION_REF_QUALIFIED (t) = 0;
+ break;
+ }
+
+ if (TYPE_STRUCTURAL_EQUALITY_P (type))
+ /* Propagate structural equality. */
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else if (TYPE_CANONICAL (type) != type)
+ /* Build the underlying canonical type, since it is different
+ from TYPE. */
+ TYPE_CANONICAL (t) = build_ref_qualified_type (TYPE_CANONICAL (type),
+ rqual);
+ else
+ /* T is its own canonical type. */
+ TYPE_CANONICAL (t) = t;
+
+ return t;
+}
+
+/* Returns nonzero if X is an expression for a (possibly overloaded)
+ function. If "f" is a function or function template, "f", "c->f",
+ "c.f", "C::f", and "f<int>" will all be considered possibly
+ overloaded functions. Returns 2 if the function is actually
+ overloaded, i.e., if it is impossible to know the type of the
+ function without performing overload resolution. */
+
+int
+is_overloaded_fn (tree x)
+{
+ /* A baselink is also considered an overloaded function. */
+ if (TREE_CODE (x) == OFFSET_REF
+ || TREE_CODE (x) == COMPONENT_REF)
+ x = TREE_OPERAND (x, 1);
+ if (BASELINK_P (x))
+ x = BASELINK_FUNCTIONS (x);
+ if (TREE_CODE (x) == TEMPLATE_ID_EXPR)
+ x = TREE_OPERAND (x, 0);
+ if (DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x))
+ || (TREE_CODE (x) == OVERLOAD && OVL_CHAIN (x)))
+ return 2;
+ return (TREE_CODE (x) == FUNCTION_DECL
+ || TREE_CODE (x) == OVERLOAD);
+}
+
+/* X is the CALL_EXPR_FN of a CALL_EXPR. If X represents a dependent name
+ (14.6.2), return the IDENTIFIER_NODE for that name. Otherwise, return
+ NULL_TREE. */
+
+tree
+dependent_name (tree x)
+{
+ if (identifier_p (x))
+ return x;
+ if (TREE_CODE (x) != COMPONENT_REF
+ && TREE_CODE (x) != OFFSET_REF
+ && TREE_CODE (x) != BASELINK
+ && is_overloaded_fn (x))
+ return DECL_NAME (get_first_fn (x));
+ return NULL_TREE;
+}
+
+/* Returns true iff X is an expression for an overloaded function
+ whose type cannot be known without performing overload
+ resolution. */
+
+bool
+really_overloaded_fn (tree x)
+{
+ return is_overloaded_fn (x) == 2;
+}
+
+tree
+get_fns (tree from)
+{
+ gcc_assert (is_overloaded_fn (from));
+ /* A baselink is also considered an overloaded function. */
+ if (TREE_CODE (from) == OFFSET_REF
+ || TREE_CODE (from) == COMPONENT_REF)
+ from = TREE_OPERAND (from, 1);
+ if (BASELINK_P (from))
+ from = BASELINK_FUNCTIONS (from);
+ if (TREE_CODE (from) == TEMPLATE_ID_EXPR)
+ from = TREE_OPERAND (from, 0);
+ return from;
+}
+
+tree
+get_first_fn (tree from)
+{
+ return OVL_CURRENT (get_fns (from));
+}
+
+/* Return a new OVL node, concatenating it with the old one. */
+
+tree
+ovl_cons (tree decl, tree chain)
+{
+ tree result = make_node (OVERLOAD);
+ TREE_TYPE (result) = unknown_type_node;
+ OVL_FUNCTION (result) = decl;
+ TREE_CHAIN (result) = chain;
+
+ return result;
+}
+
+/* Build a new overloaded function. If this is the first one,
+ just return it; otherwise, ovl_cons the _DECLs */
+
+tree
+build_overload (tree decl, tree chain)
+{
+ if (! chain && TREE_CODE (decl) != TEMPLATE_DECL)
+ return decl;
+ return ovl_cons (decl, chain);
+}
+
+/* Return the scope where the overloaded functions OVL were found. */
+
+tree
+ovl_scope (tree ovl)
+{
+ if (TREE_CODE (ovl) == OFFSET_REF
+ || TREE_CODE (ovl) == COMPONENT_REF)
+ ovl = TREE_OPERAND (ovl, 1);
+ if (TREE_CODE (ovl) == BASELINK)
+ return BINFO_TYPE (BASELINK_BINFO (ovl));
+ if (TREE_CODE (ovl) == TEMPLATE_ID_EXPR)
+ ovl = TREE_OPERAND (ovl, 0);
+ /* Skip using-declarations. */
+ while (TREE_CODE (ovl) == OVERLOAD && OVL_USED (ovl) && OVL_CHAIN (ovl))
+ ovl = OVL_CHAIN (ovl);
+ return CP_DECL_CONTEXT (OVL_CURRENT (ovl));
+}
+
+/* Return TRUE if FN is a non-static member function, FALSE otherwise.
+ This function looks into BASELINK and OVERLOAD nodes. */
+
+bool
+non_static_member_function_p (tree fn)
+{
+ if (fn == NULL_TREE)
+ return false;
+
+ if (is_overloaded_fn (fn))
+ fn = get_first_fn (fn);
+
+ return (DECL_P (fn)
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn));
+}
+
+
+#define PRINT_RING_SIZE 4
+
+static const char *
+cxx_printable_name_internal (tree decl, int v, bool translate)
+{
+ static unsigned int uid_ring[PRINT_RING_SIZE];
+ static char *print_ring[PRINT_RING_SIZE];
+ static bool trans_ring[PRINT_RING_SIZE];
+ static int ring_counter;
+ int i;
+
+ /* Only cache functions. */
+ if (v < 2
+ || TREE_CODE (decl) != FUNCTION_DECL
+ || DECL_LANG_SPECIFIC (decl) == 0)
+ return lang_decl_name (decl, v, translate);
+
+ /* See if this print name is lying around. */
+ for (i = 0; i < PRINT_RING_SIZE; i++)
+ if (uid_ring[i] == DECL_UID (decl) && translate == trans_ring[i])
+ /* yes, so return it. */
+ return print_ring[i];
+
+ if (++ring_counter == PRINT_RING_SIZE)
+ ring_counter = 0;
+
+ if (current_function_decl != NULL_TREE)
+ {
+ /* There may be both translated and untranslated versions of the
+ name cached. */
+ for (i = 0; i < 2; i++)
+ {
+ if (uid_ring[ring_counter] == DECL_UID (current_function_decl))
+ ring_counter += 1;
+ if (ring_counter == PRINT_RING_SIZE)
+ ring_counter = 0;
+ }
+ gcc_assert (uid_ring[ring_counter] != DECL_UID (current_function_decl));
+ }
+
+ free (print_ring[ring_counter]);
+
+ print_ring[ring_counter] = xstrdup (lang_decl_name (decl, v, translate));
+ uid_ring[ring_counter] = DECL_UID (decl);
+ trans_ring[ring_counter] = translate;
+ return print_ring[ring_counter];
+}
+
+const char *
+cxx_printable_name (tree decl, int v)
+{
+ return cxx_printable_name_internal (decl, v, false);
+}
+
+const char *
+cxx_printable_name_translate (tree decl, int v)
+{
+ return cxx_printable_name_internal (decl, v, true);
+}
+
+/* Build the FUNCTION_TYPE or METHOD_TYPE which may throw exceptions
+ listed in RAISES. */
+
+tree
+build_exception_variant (tree type, tree raises)
+{
+ tree v;
+ int type_quals;
+
+ if (comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (type), ce_exact))
+ return type;
+
+ type_quals = TYPE_QUALS (type);
+ cp_ref_qualifier rqual = type_memfn_rqual (type);
+ for (v = TYPE_MAIN_VARIANT (type); v; v = TYPE_NEXT_VARIANT (v))
+ if (cp_check_qualified_type (v, type, type_quals, rqual, raises))
+ return v;
+
+ /* Need to build a new variant. */
+ v = build_variant_type_copy (type);
+ TYPE_RAISES_EXCEPTIONS (v) = raises;
+ return v;
+}
+
+/* Given a TEMPLATE_TEMPLATE_PARM node T, create a new
+ BOUND_TEMPLATE_TEMPLATE_PARM bound with NEWARGS as its template
+ arguments. */
+
+tree
+bind_template_template_parm (tree t, tree newargs)
+{
+ tree decl = TYPE_NAME (t);
+ tree t2;
+
+ t2 = cxx_make_type (BOUND_TEMPLATE_TEMPLATE_PARM);
+ decl = build_decl (input_location,
+ TYPE_DECL, DECL_NAME (decl), NULL_TREE);
+
+ /* These nodes have to be created to reflect new TYPE_DECL and template
+ arguments. */
+ TEMPLATE_TYPE_PARM_INDEX (t2) = copy_node (TEMPLATE_TYPE_PARM_INDEX (t));
+ TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (t2)) = decl;
+ TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2)
+ = build_template_info (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t), newargs);
+
+ TREE_TYPE (decl) = t2;
+ TYPE_NAME (t2) = decl;
+ TYPE_STUB_DECL (t2) = decl;
+ TYPE_SIZE (t2) = 0;
+ SET_TYPE_STRUCTURAL_EQUALITY (t2);
+
+ return t2;
+}
+
+/* Called from count_trees via walk_tree. */
+
+static tree
+count_trees_r (tree *tp, int *walk_subtrees, void *data)
+{
+ ++*((int *) data);
+
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+
+ return NULL_TREE;
+}
+
+/* Debugging function for measuring the rough complexity of a tree
+ representation. */
+
+int
+count_trees (tree t)
+{
+ int n_trees = 0;
+ cp_walk_tree_without_duplicates (&t, count_trees_r, &n_trees);
+ return n_trees;
+}
+
+/* Called from verify_stmt_tree via walk_tree. */
+
+static tree
+verify_stmt_tree_r (tree* tp, int * /*walk_subtrees*/, void* data)
+{
+ tree t = *tp;
+ hash_table <pointer_hash <tree_node> > *statements
+ = static_cast <hash_table <pointer_hash <tree_node> > *> (data);
+ tree_node **slot;
+
+ if (!STATEMENT_CODE_P (TREE_CODE (t)))
+ return NULL_TREE;
+
+ /* If this statement is already present in the hash table, then
+ there is a circularity in the statement tree. */
+ gcc_assert (!statements->find (t));
+
+ slot = statements->find_slot (t, INSERT);
+ *slot = t;
+
+ return NULL_TREE;
+}
+
+/* Debugging function to check that the statement T has not been
+ corrupted. For now, this function simply checks that T contains no
+ circularities. */
+
+void
+verify_stmt_tree (tree t)
+{
+ hash_table <pointer_hash <tree_node> > statements;
+ statements.create (37);
+ cp_walk_tree (&t, verify_stmt_tree_r, &statements, NULL);
+ statements.dispose ();
+}
+
+/* Check if the type T depends on a type with no linkage and if so, return
+ it. If RELAXED_P then do not consider a class type declared within
+ a vague-linkage function to have no linkage. */
+
+tree
+no_linkage_check (tree t, bool relaxed_p)
+{
+ tree r;
+
+ /* There's no point in checking linkage on template functions; we
+ can't know their complete types. */
+ if (processing_template_decl)
+ return NULL_TREE;
+
+ switch (TREE_CODE (t))
+ {
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ goto ptrmem;
+ /* Lambda types that don't have mangling scope have no linkage. We
+ check CLASSTYPE_LAMBDA_EXPR for error_mark_node because
+ when we get here from pushtag none of the lambda information is
+ set up yet, so we want to assume that the lambda has linkage and
+ fix it up later if not. */
+ if (CLASSTYPE_LAMBDA_EXPR (t)
+ && CLASSTYPE_LAMBDA_EXPR (t) != error_mark_node
+ && LAMBDA_TYPE_EXTRA_SCOPE (t) == NULL_TREE)
+ return t;
+ /* Fall through. */
+ case UNION_TYPE:
+ if (!CLASS_TYPE_P (t))
+ return NULL_TREE;
+ /* Fall through. */
+ case ENUMERAL_TYPE:
+ /* Only treat anonymous types as having no linkage if they're at
+ namespace scope. This is core issue 966. */
+ if (TYPE_ANONYMOUS_P (t) && TYPE_NAMESPACE_SCOPE_P (t))
+ return t;
+
+ for (r = CP_TYPE_CONTEXT (t); ; )
+ {
+ /* If we're a nested type of a !TREE_PUBLIC class, we might not
+ have linkage, or we might just be in an anonymous namespace.
+ If we're in a TREE_PUBLIC class, we have linkage. */
+ if (TYPE_P (r) && !TREE_PUBLIC (TYPE_NAME (r)))
+ return no_linkage_check (TYPE_CONTEXT (t), relaxed_p);
+ else if (TREE_CODE (r) == FUNCTION_DECL)
+ {
+ if (!relaxed_p || !vague_linkage_p (r))
+ return t;
+ else
+ r = CP_DECL_CONTEXT (r);
+ }
+ else
+ break;
+ }
+
+ return NULL_TREE;
+
+ case ARRAY_TYPE:
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ case VECTOR_TYPE:
+ return no_linkage_check (TREE_TYPE (t), relaxed_p);
+
+ case OFFSET_TYPE:
+ ptrmem:
+ r = no_linkage_check (TYPE_PTRMEM_POINTED_TO_TYPE (t),
+ relaxed_p);
+ if (r)
+ return r;
+ return no_linkage_check (TYPE_PTRMEM_CLASS_TYPE (t), relaxed_p);
+
+ case METHOD_TYPE:
+ r = no_linkage_check (TYPE_METHOD_BASETYPE (t), relaxed_p);
+ if (r)
+ return r;
+ /* Fall through. */
+ case FUNCTION_TYPE:
+ {
+ tree parm;
+ for (parm = TYPE_ARG_TYPES (t);
+ parm && parm != void_list_node;
+ parm = TREE_CHAIN (parm))
+ {
+ r = no_linkage_check (TREE_VALUE (parm), relaxed_p);
+ if (r)
+ return r;
+ }
+ return no_linkage_check (TREE_TYPE (t), relaxed_p);
+ }
+
+ default:
+ return NULL_TREE;
+ }
+}
+
+extern int depth_reached;
+
+void
+cxx_print_statistics (void)
+{
+ print_search_statistics ();
+ print_class_statistics ();
+ print_template_statistics ();
+ if (GATHER_STATISTICS)
+ fprintf (stderr, "maximum template instantiation depth reached: %d\n",
+ depth_reached);
+}
+
+/* Return, as an INTEGER_CST node, the number of elements for TYPE
+ (which is an ARRAY_TYPE). This counts only elements of the top
+ array. */
+
+tree
+array_type_nelts_top (tree type)
+{
+ return fold_build2_loc (input_location,
+ PLUS_EXPR, sizetype,
+ array_type_nelts (type),
+ size_one_node);
+}
+
+/* Return, as an INTEGER_CST node, the number of elements for TYPE
+ (which is an ARRAY_TYPE). This one is a recursive count of all
+ ARRAY_TYPEs that are clumped together. */
+
+tree
+array_type_nelts_total (tree type)
+{
+ tree sz = array_type_nelts_top (type);
+ type = TREE_TYPE (type);
+ while (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree n = array_type_nelts_top (type);
+ sz = fold_build2_loc (input_location,
+ MULT_EXPR, sizetype, sz, n);
+ type = TREE_TYPE (type);
+ }
+ return sz;
+}
+
+/* Called from break_out_target_exprs via mapcar. */
+
+static tree
+bot_manip (tree* tp, int* walk_subtrees, void* data)
+{
+ splay_tree target_remap = ((splay_tree) data);
+ tree t = *tp;
+
+ if (!TYPE_P (t) && TREE_CONSTANT (t) && !TREE_SIDE_EFFECTS (t))
+ {
+ /* There can't be any TARGET_EXPRs or their slot variables below this
+ point. But we must make a copy, in case subsequent processing
+ alters any part of it. For example, during gimplification a cast
+ of the form (T) &X::f (where "f" is a member function) will lead
+ to replacing the PTRMEM_CST for &X::f with a VAR_DECL. */
+ *walk_subtrees = 0;
+ *tp = unshare_expr (t);
+ return NULL_TREE;
+ }
+ if (TREE_CODE (t) == TARGET_EXPR)
+ {
+ tree u;
+
+ if (TREE_CODE (TREE_OPERAND (t, 1)) == AGGR_INIT_EXPR)
+ {
+ u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1),
+ tf_warning_or_error);
+ if (AGGR_INIT_ZERO_FIRST (TREE_OPERAND (t, 1)))
+ AGGR_INIT_ZERO_FIRST (TREE_OPERAND (u, 1)) = true;
+ }
+ else
+ u = build_target_expr_with_type (TREE_OPERAND (t, 1), TREE_TYPE (t),
+ tf_warning_or_error);
+
+ TARGET_EXPR_IMPLICIT_P (u) = TARGET_EXPR_IMPLICIT_P (t);
+ TARGET_EXPR_LIST_INIT_P (u) = TARGET_EXPR_LIST_INIT_P (t);
+ TARGET_EXPR_DIRECT_INIT_P (u) = TARGET_EXPR_DIRECT_INIT_P (t);
+
+ /* Map the old variable to the new one. */
+ splay_tree_insert (target_remap,
+ (splay_tree_key) TREE_OPERAND (t, 0),
+ (splay_tree_value) TREE_OPERAND (u, 0));
+
+ TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1));
+
+ /* Replace the old expression with the new version. */
+ *tp = u;
+ /* We don't have to go below this point; the recursive call to
+ break_out_target_exprs will have handled anything below this
+ point. */
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
+ /* Make a copy of this node. */
+ t = copy_tree_r (tp, walk_subtrees, NULL);
+ if (TREE_CODE (*tp) == CALL_EXPR)
+ {
+ set_flags_from_callee (*tp);
+
+ /* builtin_LINE and builtin_FILE get the location where the default
+ argument is expanded, not where the call was written. */
+ tree callee = get_callee_fndecl (*tp);
+ if (callee && DECL_BUILT_IN (callee))
+ switch (DECL_FUNCTION_CODE (callee))
+ {
+ case BUILT_IN_FILE:
+ case BUILT_IN_LINE:
+ SET_EXPR_LOCATION (*tp, input_location);
+ }
+ }
+ return t;
+}
+
+/* Replace all remapped VAR_DECLs in T with their new equivalents.
+ DATA is really a splay-tree mapping old variables to new
+ variables. */
+
+static tree
+bot_replace (tree* t, int* /*walk_subtrees*/, void* data)
+{
+ splay_tree target_remap = ((splay_tree) data);
+
+ if (VAR_P (*t))
+ {
+ splay_tree_node n = splay_tree_lookup (target_remap,
+ (splay_tree_key) *t);
+ if (n)
+ *t = (tree) n->value;
+ }
+ else if (TREE_CODE (*t) == PARM_DECL
+ && DECL_NAME (*t) == this_identifier)
+ {
+ /* In an NSDMI we need to replace the 'this' parameter we used for
+ parsing with the real one for this function. */
+ *t = current_class_ptr;
+ }
+ else if (TREE_CODE (*t) == CONVERT_EXPR
+ && CONVERT_EXPR_VBASE_PATH (*t))
+ {
+ /* In an NSDMI build_base_path defers building conversions to virtual
+ bases, and we handle it here. */
+ tree basetype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (*t)));
+ vec<tree, va_gc> *vbases = CLASSTYPE_VBASECLASSES (current_class_type);
+ int i; tree binfo;
+ FOR_EACH_VEC_SAFE_ELT (vbases, i, binfo)
+ if (BINFO_TYPE (binfo) == basetype)
+ break;
+ *t = build_base_path (PLUS_EXPR, TREE_OPERAND (*t, 0), binfo, true,
+ tf_warning_or_error);
+ }
+
+ return NULL_TREE;
+}
+
+/* When we parse a default argument expression, we may create
+ temporary variables via TARGET_EXPRs. When we actually use the
+ default-argument expression, we make a copy of the expression
+ and replace the temporaries with appropriate local versions. */
+
+tree
+break_out_target_exprs (tree t)
+{
+ static int target_remap_count;
+ static splay_tree target_remap;
+
+ if (!target_remap_count++)
+ target_remap = splay_tree_new (splay_tree_compare_pointers,
+ /*splay_tree_delete_key_fn=*/NULL,
+ /*splay_tree_delete_value_fn=*/NULL);
+ cp_walk_tree (&t, bot_manip, target_remap, NULL);
+ cp_walk_tree (&t, bot_replace, target_remap, NULL);
+
+ if (!--target_remap_count)
+ {
+ splay_tree_delete (target_remap);
+ target_remap = NULL;
+ }
+
+ return t;
+}
+
+/* Similar to `build_nt', but for template definitions of dependent
+ expressions */
+
+tree
+build_min_nt_loc (location_t loc, enum tree_code code, ...)
+{
+ tree t;
+ int length;
+ int i;
+ va_list p;
+
+ gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+
+ va_start (p, code);
+
+ t = make_node (code);
+ SET_EXPR_LOCATION (t, loc);
+ length = TREE_CODE_LENGTH (code);
+
+ for (i = 0; i < length; i++)
+ {
+ tree x = va_arg (p, tree);
+ TREE_OPERAND (t, i) = x;
+ }
+
+ va_end (p);
+ return t;
+}
+
+
+/* Similar to `build', but for template definitions. */
+
+tree
+build_min (enum tree_code code, tree tt, ...)
+{
+ tree t;
+ int length;
+ int i;
+ va_list p;
+
+ gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+
+ va_start (p, tt);
+
+ t = make_node (code);
+ length = TREE_CODE_LENGTH (code);
+ TREE_TYPE (t) = tt;
+
+ for (i = 0; i < length; i++)
+ {
+ tree x = va_arg (p, tree);
+ TREE_OPERAND (t, i) = x;
+ if (x && !TYPE_P (x) && TREE_SIDE_EFFECTS (x))
+ TREE_SIDE_EFFECTS (t) = 1;
+ }
+
+ va_end (p);
+ return t;
+}
+
+/* Similar to `build', but for template definitions of non-dependent
+ expressions. NON_DEP is the non-dependent expression that has been
+ built. */
+
+tree
+build_min_non_dep (enum tree_code code, tree non_dep, ...)
+{
+ tree t;
+ int length;
+ int i;
+ va_list p;
+
+ gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+
+ va_start (p, non_dep);
+
+ if (REFERENCE_REF_P (non_dep))
+ non_dep = TREE_OPERAND (non_dep, 0);
+
+ t = make_node (code);
+ length = TREE_CODE_LENGTH (code);
+ TREE_TYPE (t) = TREE_TYPE (non_dep);
+ TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
+
+ for (i = 0; i < length; i++)
+ {
+ tree x = va_arg (p, tree);
+ TREE_OPERAND (t, i) = x;
+ }
+
+ if (code == COMPOUND_EXPR && TREE_CODE (non_dep) != COMPOUND_EXPR)
+ /* This should not be considered a COMPOUND_EXPR, because it
+ resolves to an overload. */
+ COMPOUND_EXPR_OVERLOADED (t) = 1;
+
+ va_end (p);
+ return convert_from_reference (t);
+}
+
+/* Similar to `build_nt_call_vec', but for template definitions of
+ non-dependent expressions. NON_DEP is the non-dependent expression
+ that has been built. */
+
+tree
+build_min_non_dep_call_vec (tree non_dep, tree fn, vec<tree, va_gc> *argvec)
+{
+ tree t = build_nt_call_vec (fn, argvec);
+ if (REFERENCE_REF_P (non_dep))
+ non_dep = TREE_OPERAND (non_dep, 0);
+ TREE_TYPE (t) = TREE_TYPE (non_dep);
+ TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
+ return convert_from_reference (t);
+}
+
+tree
+get_type_decl (tree t)
+{
+ if (TREE_CODE (t) == TYPE_DECL)
+ return t;
+ if (TYPE_P (t))
+ return TYPE_STUB_DECL (t);
+ gcc_assert (t == error_mark_node);
+ return t;
+}
+
+/* Returns the namespace that contains DECL, whether directly or
+ indirectly. */
+
+tree
+decl_namespace_context (tree decl)
+{
+ while (1)
+ {
+ if (TREE_CODE (decl) == NAMESPACE_DECL)
+ return decl;
+ else if (TYPE_P (decl))
+ decl = CP_DECL_CONTEXT (TYPE_MAIN_DECL (decl));
+ else
+ decl = CP_DECL_CONTEXT (decl);
+ }
+}
+
+/* Returns true if decl is within an anonymous namespace, however deeply
+ nested, or false otherwise. */
+
+bool
+decl_anon_ns_mem_p (const_tree decl)
+{
+ while (1)
+ {
+ if (decl == NULL_TREE || decl == error_mark_node)
+ return false;
+ if (TREE_CODE (decl) == NAMESPACE_DECL
+ && DECL_NAME (decl) == NULL_TREE)
+ return true;
+ /* Classes and namespaces inside anonymous namespaces have
+ TREE_PUBLIC == 0, so we can shortcut the search. */
+ else if (TYPE_P (decl))
+ return (TREE_PUBLIC (TYPE_MAIN_DECL (decl)) == 0);
+ else if (TREE_CODE (decl) == NAMESPACE_DECL)
+ return (TREE_PUBLIC (decl) == 0);
+ else
+ decl = DECL_CONTEXT (decl);
+ }
+}
+
+/* Subroutine of cp_tree_equal: t1 and t2 are the CALL_EXPR_FNs of two
+ CALL_EXPRS. Return whether they are equivalent. */
+
+static bool
+called_fns_equal (tree t1, tree t2)
+{
+ /* Core 1321: dependent names are equivalent even if the overload sets
+ are different. But do compare explicit template arguments. */
+ tree name1 = dependent_name (t1);
+ tree name2 = dependent_name (t2);
+ if (name1 || name2)
+ {
+ tree targs1 = NULL_TREE, targs2 = NULL_TREE;
+
+ if (name1 != name2)
+ return false;
+
+ if (TREE_CODE (t1) == TEMPLATE_ID_EXPR)
+ targs1 = TREE_OPERAND (t1, 1);
+ if (TREE_CODE (t2) == TEMPLATE_ID_EXPR)
+ targs2 = TREE_OPERAND (t2, 1);
+ return cp_tree_equal (targs1, targs2);
+ }
+ else
+ return cp_tree_equal (t1, t2);
+}
+
+/* Return truthvalue of whether T1 is the same tree structure as T2.
+ Return 1 if they are the same. Return 0 if they are different. */
+
+bool
+cp_tree_equal (tree t1, tree t2)
+{
+ enum tree_code code1, code2;
+
+ if (t1 == t2)
+ return true;
+ if (!t1 || !t2)
+ return false;
+
+ for (code1 = TREE_CODE (t1);
+ CONVERT_EXPR_CODE_P (code1)
+ || code1 == NON_LVALUE_EXPR;
+ code1 = TREE_CODE (t1))
+ t1 = TREE_OPERAND (t1, 0);
+ for (code2 = TREE_CODE (t2);
+ CONVERT_EXPR_CODE_P (code2)
+ || code2 == NON_LVALUE_EXPR;
+ code2 = TREE_CODE (t2))
+ t2 = TREE_OPERAND (t2, 0);
+
+ /* They might have become equal now. */
+ if (t1 == t2)
+ return true;
+
+ if (code1 != code2)
+ return false;
+
+ switch (code1)
+ {
+ case INTEGER_CST:
+ return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
+ && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
+
+ case REAL_CST:
+ return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
+
+ case STRING_CST:
+ return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
+ && !memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
+ TREE_STRING_LENGTH (t1));
+
+ case FIXED_CST:
+ return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1),
+ TREE_FIXED_CST (t2));
+
+ case COMPLEX_CST:
+ return cp_tree_equal (TREE_REALPART (t1), TREE_REALPART (t2))
+ && cp_tree_equal (TREE_IMAGPART (t1), TREE_IMAGPART (t2));
+
+ case VECTOR_CST:
+ return operand_equal_p (t1, t2, OEP_ONLY_CONST);
+
+ case CONSTRUCTOR:
+ /* We need to do this when determining whether or not two
+ non-type pointer to member function template arguments
+ are the same. */
+ if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
+ || CONSTRUCTOR_NELTS (t1) != CONSTRUCTOR_NELTS (t2))
+ return false;
+ {
+ tree field, value;
+ unsigned int i;
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t1), i, field, value)
+ {
+ constructor_elt *elt2 = CONSTRUCTOR_ELT (t2, i);
+ if (!cp_tree_equal (field, elt2->index)
+ || !cp_tree_equal (value, elt2->value))
+ return false;
+ }
+ }
+ return true;
+
+ case TREE_LIST:
+ if (!cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)))
+ return false;
+ if (!cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2)))
+ return false;
+ return cp_tree_equal (TREE_CHAIN (t1), TREE_CHAIN (t2));
+
+ case SAVE_EXPR:
+ return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
+
+ case CALL_EXPR:
+ {
+ tree arg1, arg2;
+ call_expr_arg_iterator iter1, iter2;
+ if (!called_fns_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
+ return false;
+ for (arg1 = first_call_expr_arg (t1, &iter1),
+ arg2 = first_call_expr_arg (t2, &iter2);
+ arg1 && arg2;
+ arg1 = next_call_expr_arg (&iter1),
+ arg2 = next_call_expr_arg (&iter2))
+ if (!cp_tree_equal (arg1, arg2))
+ return false;
+ if (arg1 || arg2)
+ return false;
+ return true;
+ }
+
+ case TARGET_EXPR:
+ {
+ tree o1 = TREE_OPERAND (t1, 0);
+ tree o2 = TREE_OPERAND (t2, 0);
+
+ /* Special case: if either target is an unallocated VAR_DECL,
+ it means that it's going to be unified with whatever the
+ TARGET_EXPR is really supposed to initialize, so treat it
+ as being equivalent to anything. */
+ if (VAR_P (o1) && DECL_NAME (o1) == NULL_TREE
+ && !DECL_RTL_SET_P (o1))
+ /*Nop*/;
+ else if (VAR_P (o2) && DECL_NAME (o2) == NULL_TREE
+ && !DECL_RTL_SET_P (o2))
+ /*Nop*/;
+ else if (!cp_tree_equal (o1, o2))
+ return false;
+
+ return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
+ }
+
+ case WITH_CLEANUP_EXPR:
+ if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+ return false;
+ return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t1, 1));
+
+ case COMPONENT_REF:
+ if (TREE_OPERAND (t1, 1) != TREE_OPERAND (t2, 1))
+ return false;
+ return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
+
+ case PARM_DECL:
+ /* For comparing uses of parameters in late-specified return types
+ with an out-of-class definition of the function, but can also come
+ up for expressions that involve 'this' in a member function
+ template. */
+
+ if (comparing_specializations)
+ /* When comparing hash table entries, only an exact match is
+ good enough; we don't want to replace 'this' with the
+ version from another function. */
+ return false;
+
+ if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ {
+ if (DECL_ARTIFICIAL (t1) ^ DECL_ARTIFICIAL (t2))
+ return false;
+ if (DECL_ARTIFICIAL (t1)
+ || (DECL_PARM_LEVEL (t1) == DECL_PARM_LEVEL (t2)
+ && DECL_PARM_INDEX (t1) == DECL_PARM_INDEX (t2)))
+ return true;
+ }
+ return false;
+
+ case VAR_DECL:
+ case CONST_DECL:
+ case FIELD_DECL:
+ case FUNCTION_DECL:
+ case TEMPLATE_DECL:
+ case IDENTIFIER_NODE:
+ case SSA_NAME:
+ return false;
+
+ case BASELINK:
+ return (BASELINK_BINFO (t1) == BASELINK_BINFO (t2)
+ && BASELINK_ACCESS_BINFO (t1) == BASELINK_ACCESS_BINFO (t2)
+ && BASELINK_QUALIFIED_P (t1) == BASELINK_QUALIFIED_P (t2)
+ && cp_tree_equal (BASELINK_FUNCTIONS (t1),
+ BASELINK_FUNCTIONS (t2)));
+
+ case TEMPLATE_PARM_INDEX:
+ return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
+ && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
+ && (TEMPLATE_PARM_PARAMETER_PACK (t1)
+ == TEMPLATE_PARM_PARAMETER_PACK (t2))
+ && same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)),
+ TREE_TYPE (TEMPLATE_PARM_DECL (t2))));
+
+ case TEMPLATE_ID_EXPR:
+ return (cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))
+ && cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)));
+
+ case TREE_VEC:
+ {
+ unsigned ix;
+ if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2))
+ return false;
+ for (ix = TREE_VEC_LENGTH (t1); ix--;)
+ if (!cp_tree_equal (TREE_VEC_ELT (t1, ix),
+ TREE_VEC_ELT (t2, ix)))
+ return false;
+ return true;
+ }
+
+ case SIZEOF_EXPR:
+ case ALIGNOF_EXPR:
+ {
+ tree o1 = TREE_OPERAND (t1, 0);
+ tree o2 = TREE_OPERAND (t2, 0);
+
+ if (code1 == SIZEOF_EXPR)
+ {
+ if (SIZEOF_EXPR_TYPE_P (t1))
+ o1 = TREE_TYPE (o1);
+ if (SIZEOF_EXPR_TYPE_P (t2))
+ o2 = TREE_TYPE (o2);
+ }
+ if (TREE_CODE (o1) != TREE_CODE (o2))
+ return false;
+ if (TYPE_P (o1))
+ return same_type_p (o1, o2);
+ else
+ return cp_tree_equal (o1, o2);
+ }
+
+ case MODOP_EXPR:
+ {
+ tree t1_op1, t2_op1;
+
+ if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+ return false;
+
+ t1_op1 = TREE_OPERAND (t1, 1);
+ t2_op1 = TREE_OPERAND (t2, 1);
+ if (TREE_CODE (t1_op1) != TREE_CODE (t2_op1))
+ return false;
+
+ return cp_tree_equal (TREE_OPERAND (t1, 2), TREE_OPERAND (t2, 2));
+ }
+
+ case PTRMEM_CST:
+ /* Two pointer-to-members are the same if they point to the same
+ field or function in the same class. */
+ if (PTRMEM_CST_MEMBER (t1) != PTRMEM_CST_MEMBER (t2))
+ return false;
+
+ return same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2));
+
+ case OVERLOAD:
+ if (OVL_FUNCTION (t1) != OVL_FUNCTION (t2))
+ return false;
+ return cp_tree_equal (OVL_CHAIN (t1), OVL_CHAIN (t2));
+
+ case TRAIT_EXPR:
+ if (TRAIT_EXPR_KIND (t1) != TRAIT_EXPR_KIND (t2))
+ return false;
+ return same_type_p (TRAIT_EXPR_TYPE1 (t1), TRAIT_EXPR_TYPE1 (t2))
+ && same_type_p (TRAIT_EXPR_TYPE2 (t1), TRAIT_EXPR_TYPE2 (t2));
+
+ case CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
+ case NEW_EXPR:
+ if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
+ /* Now compare operands as usual. */
+ break;
+
+ case DEFERRED_NOEXCEPT:
+ return (cp_tree_equal (DEFERRED_NOEXCEPT_PATTERN (t1),
+ DEFERRED_NOEXCEPT_PATTERN (t2))
+ && comp_template_args (DEFERRED_NOEXCEPT_ARGS (t1),
+ DEFERRED_NOEXCEPT_ARGS (t2)));
+ break;
+
+ default:
+ break;
+ }
+
+ switch (TREE_CODE_CLASS (code1))
+ {
+ case tcc_unary:
+ case tcc_binary:
+ case tcc_comparison:
+ case tcc_expression:
+ case tcc_vl_exp:
+ case tcc_reference:
+ case tcc_statement:
+ {
+ int i, n;
+
+ n = cp_tree_operand_length (t1);
+ if (TREE_CODE_CLASS (code1) == tcc_vl_exp
+ && n != TREE_OPERAND_LENGTH (t2))
+ return false;
+
+ for (i = 0; i < n; ++i)
+ if (!cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i)))
+ return false;
+
+ return true;
+ }
+
+ case tcc_type:
+ return same_type_p (t1, t2);
+ default:
+ gcc_unreachable ();
+ }
+ /* We can get here with --disable-checking. */
+ return false;
+}
+
+/* The type of ARG when used as an lvalue. */
+
+tree
+lvalue_type (tree arg)
+{
+ tree type = TREE_TYPE (arg);
+ return type;
+}
+
+/* The type of ARG for printing error messages; denote lvalues with
+ reference types. */
+
+tree
+error_type (tree arg)
+{
+ tree type = TREE_TYPE (arg);
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ ;
+ else if (TREE_CODE (type) == ERROR_MARK)
+ ;
+ else if (real_lvalue_p (arg))
+ type = build_reference_type (lvalue_type (arg));
+ else if (MAYBE_CLASS_TYPE_P (type))
+ type = lvalue_type (arg);
+
+ return type;
+}
+
+/* Does FUNCTION use a variable-length argument list? */
+
+int
+varargs_function_p (const_tree function)
+{
+ return stdarg_p (TREE_TYPE (function));
+}
+
+/* Returns 1 if decl is a member of a class. */
+
+int
+member_p (const_tree decl)
+{
+ const_tree const ctx = DECL_CONTEXT (decl);
+ return (ctx && TYPE_P (ctx));
+}
+
+/* Create a placeholder for member access where we don't actually have an
+ object that the access is against. */
+
+tree
+build_dummy_object (tree type)
+{
+ tree decl = build1 (NOP_EXPR, build_pointer_type (type), void_zero_node);
+ return cp_build_indirect_ref (decl, RO_NULL, tf_warning_or_error);
+}
+
+/* We've gotten a reference to a member of TYPE. Return *this if appropriate,
+ or a dummy object otherwise. If BINFOP is non-0, it is filled with the
+ binfo path from current_class_type to TYPE, or 0. */
+
+tree
+maybe_dummy_object (tree type, tree* binfop)
+{
+ tree decl, context;
+ tree binfo;
+ tree current = current_nonlambda_class_type ();
+
+ if (current
+ && (binfo = lookup_base (current, type, ba_any, NULL,
+ tf_warning_or_error)))
+ context = current;
+ else
+ {
+ /* Reference from a nested class member function. */
+ context = type;
+ binfo = TYPE_BINFO (type);
+ }
+
+ if (binfop)
+ *binfop = binfo;
+
+ if (current_class_ref
+ /* current_class_ref might not correspond to current_class_type if
+ we're in tsubst_default_argument or a lambda-declarator; in either
+ case, we want to use current_class_ref if it matches CONTEXT. */
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (current_class_ref), context)))
+ decl = current_class_ref;
+ else
+ decl = build_dummy_object (context);
+
+ return decl;
+}
+
+/* Returns 1 if OB is a placeholder object, or a pointer to one. */
+
+int
+is_dummy_object (const_tree ob)
+{
+ if (INDIRECT_REF_P (ob))
+ ob = TREE_OPERAND (ob, 0);
+ return (TREE_CODE (ob) == NOP_EXPR
+ && TREE_OPERAND (ob, 0) == void_zero_node);
+}
+
+/* Returns 1 iff type T is something we want to treat as a scalar type for
+ the purpose of deciding whether it is trivial/POD/standard-layout. */
+
+bool
+scalarish_type_p (const_tree t)
+{
+ if (t == error_mark_node)
+ return 1;
+
+ return (SCALAR_TYPE_P (t)
+ || TREE_CODE (t) == VECTOR_TYPE);
+}
+
+/* Returns true iff T requires non-trivial default initialization. */
+
+bool
+type_has_nontrivial_default_init (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return TYPE_HAS_COMPLEX_DFLT (t);
+ else
+ return 0;
+}
+
+/* Returns true iff copying an object of type T (including via move
+ constructor) is non-trivial. That is, T has no non-trivial copy
+ constructors and no non-trivial move constructors. */
+
+bool
+type_has_nontrivial_copy_init (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ {
+ gcc_assert (COMPLETE_TYPE_P (t));
+ return ((TYPE_HAS_COPY_CTOR (t)
+ && TYPE_HAS_COMPLEX_COPY_CTOR (t))
+ || TYPE_HAS_COMPLEX_MOVE_CTOR (t));
+ }
+ else
+ return 0;
+}
+
+/* Returns 1 iff type T is a trivially copyable type, as defined in
+ [basic.types] and [class]. */
+
+bool
+trivially_copyable_p (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return ((!TYPE_HAS_COPY_CTOR (t)
+ || !TYPE_HAS_COMPLEX_COPY_CTOR (t))
+ && !TYPE_HAS_COMPLEX_MOVE_CTOR (t)
+ && (!TYPE_HAS_COPY_ASSIGN (t)
+ || !TYPE_HAS_COMPLEX_COPY_ASSIGN (t))
+ && !TYPE_HAS_COMPLEX_MOVE_ASSIGN (t)
+ && TYPE_HAS_TRIVIAL_DESTRUCTOR (t));
+ else
+ return scalarish_type_p (t);
+}
+
+/* Returns 1 iff type T is a trivial type, as defined in [basic.types] and
+ [class]. */
+
+bool
+trivial_type_p (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return (TYPE_HAS_TRIVIAL_DFLT (t)
+ && trivially_copyable_p (t));
+ else
+ return scalarish_type_p (t);
+}
+
+/* Returns 1 iff type T is a POD type, as defined in [basic.types]. */
+
+bool
+pod_type_p (const_tree t)
+{
+ /* This CONST_CAST is okay because strip_array_types returns its
+ argument unmodified and we assign it to a const_tree. */
+ t = strip_array_types (CONST_CAST_TREE(t));
+
+ if (!CLASS_TYPE_P (t))
+ return scalarish_type_p (t);
+ else if (cxx_dialect > cxx98)
+ /* [class]/10: A POD struct is a class that is both a trivial class and a
+ standard-layout class, and has no non-static data members of type
+ non-POD struct, non-POD union (or array of such types).
+
+ We don't need to check individual members because if a member is
+ non-std-layout or non-trivial, the class will be too. */
+ return (std_layout_type_p (t) && trivial_type_p (t));
+ else
+ /* The C++98 definition of POD is different. */
+ return !CLASSTYPE_NON_LAYOUT_POD_P (t);
+}
+
+/* Returns true iff T is POD for the purpose of layout, as defined in the
+ C++ ABI. */
+
+bool
+layout_pod_type_p (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return !CLASSTYPE_NON_LAYOUT_POD_P (t);
+ else
+ return scalarish_type_p (t);
+}
+
+/* Returns true iff T is a standard-layout type, as defined in
+ [basic.types]. */
+
+bool
+std_layout_type_p (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return !CLASSTYPE_NON_STD_LAYOUT (t);
+ else
+ return scalarish_type_p (t);
+}
+
+/* Nonzero iff type T is a class template implicit specialization. */
+
+bool
+class_tmpl_impl_spec_p (const_tree t)
+{
+ return CLASS_TYPE_P (t) && CLASSTYPE_TEMPLATE_INSTANTIATION (t);
+}
+
+/* Returns 1 iff zero initialization of type T means actually storing
+ zeros in it. */
+
+int
+zero_init_p (const_tree t)
+{
+ /* This CONST_CAST is okay because strip_array_types returns its
+ argument unmodified and we assign it to a const_tree. */
+ t = strip_array_types (CONST_CAST_TREE(t));
+
+ if (t == error_mark_node)
+ return 1;
+
+ /* NULL pointers to data members are initialized with -1. */
+ if (TYPE_PTRDATAMEM_P (t))
+ return 0;
+
+ /* Classes that contain types that can't be zero-initialized, cannot
+ be zero-initialized themselves. */
+ if (CLASS_TYPE_P (t) && CLASSTYPE_NON_ZERO_INIT_P (t))
+ return 0;
+
+ return 1;
+}
+
+/* Table of valid C++ attributes. */
+const struct attribute_spec cxx_attribute_table[] =
+{
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
+ affects_type_identity } */
+ { "java_interface", 0, 0, false, false, false,
+ handle_java_interface_attribute, false },
+ { "com_interface", 0, 0, false, false, false,
+ handle_com_interface_attribute, false },
+ { "init_priority", 1, 1, true, false, false,
+ handle_init_priority_attribute, false },
+ { "abi_tag", 1, -1, false, false, false,
+ handle_abi_tag_attribute, true },
+ { NULL, 0, 0, false, false, false, NULL, false }
+};
+
+/* Handle a "java_interface" attribute; arguments as in
+ struct attribute_spec.handler. */
+static tree
+handle_java_interface_attribute (tree* node,
+ tree name,
+ tree /*args*/,
+ int flags,
+ bool* no_add_attrs)
+{
+ if (DECL_P (*node)
+ || !CLASS_TYPE_P (*node)
+ || !TYPE_FOR_JAVA (*node))
+ {
+ error ("%qE attribute can only be applied to Java class definitions",
+ name);
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ *node = build_variant_type_copy (*node);
+ TYPE_JAVA_INTERFACE (*node) = 1;
+
+ return NULL_TREE;
+}
+
+/* Handle a "com_interface" attribute; arguments as in
+ struct attribute_spec.handler. */
+static tree
+handle_com_interface_attribute (tree* node,
+ tree name,
+ tree /*args*/,
+ int /*flags*/,
+ bool* no_add_attrs)
+{
+ static int warned;
+
+ *no_add_attrs = true;
+
+ if (DECL_P (*node)
+ || !CLASS_TYPE_P (*node)
+ || *node != TYPE_MAIN_VARIANT (*node))
+ {
+ warning (OPT_Wattributes, "%qE attribute can only be applied "
+ "to class definitions", name);
+ return NULL_TREE;
+ }
+
+ if (!warned++)
+ warning (0, "%qE is obsolete; g++ vtables are now COM-compatible by default",
+ name);
+
+ return NULL_TREE;
+}
+
+/* Handle an "init_priority" attribute; arguments as in
+ struct attribute_spec.handler. */
+static tree
+handle_init_priority_attribute (tree* node,
+ tree name,
+ tree args,
+ int /*flags*/,
+ bool* no_add_attrs)
+{
+ tree initp_expr = TREE_VALUE (args);
+ tree decl = *node;
+ tree type = TREE_TYPE (decl);
+ int pri;
+
+ STRIP_NOPS (initp_expr);
+ initp_expr = default_conversion (initp_expr);
+
+ if (!initp_expr || TREE_CODE (initp_expr) != INTEGER_CST)
+ {
+ error ("requested init_priority is not an integer constant");
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ pri = TREE_INT_CST_LOW (initp_expr);
+
+ type = strip_array_types (type);
+
+ if (decl == NULL_TREE
+ || !VAR_P (decl)
+ || !TREE_STATIC (decl)
+ || DECL_EXTERNAL (decl)
+ || (TREE_CODE (type) != RECORD_TYPE
+ && TREE_CODE (type) != UNION_TYPE)
+ /* Static objects in functions are initialized the
+ first time control passes through that
+ function. This is not precise enough to pin down an
+ init_priority value, so don't allow it. */
+ || current_function_decl)
+ {
+ error ("can only use %qE attribute on file-scope definitions "
+ "of objects of class type", name);
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ if (pri > MAX_INIT_PRIORITY || pri <= 0)
+ {
+ error ("requested init_priority is out of range");
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ /* Check for init_priorities that are reserved for
+ language and runtime support implementations.*/
+ if (pri <= MAX_RESERVED_INIT_PRIORITY)
+ {
+ warning
+ (0, "requested init_priority is reserved for internal use");
+ }
+
+ if (SUPPORTS_INIT_PRIORITY)
+ {
+ SET_DECL_INIT_PRIORITY (decl, pri);
+ DECL_HAS_INIT_PRIORITY_P (decl) = 1;
+ return NULL_TREE;
+ }
+ else
+ {
+ error ("%qE attribute is not supported on this platform", name);
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+}
+
+/* DECL is being redeclared; the old declaration had the abi tags in OLD,
+ and the new one has the tags in NEW_. Give an error if there are tags
+ in NEW_ that weren't in OLD. */
+
+bool
+check_abi_tag_redeclaration (const_tree decl, const_tree old, const_tree new_)
+{
+ if (old && TREE_CODE (TREE_VALUE (old)) == TREE_LIST)
+ old = TREE_VALUE (old);
+ if (new_ && TREE_CODE (TREE_VALUE (new_)) == TREE_LIST)
+ new_ = TREE_VALUE (new_);
+ bool err = false;
+ for (const_tree t = new_; t; t = TREE_CHAIN (t))
+ {
+ tree str = TREE_VALUE (t);
+ for (const_tree in = old; in; in = TREE_CHAIN (in))
+ {
+ tree ostr = TREE_VALUE (in);
+ if (cp_tree_equal (str, ostr))
+ goto found;
+ }
+ error ("redeclaration of %qD adds abi tag %E", decl, str);
+ err = true;
+ found:;
+ }
+ if (err)
+ {
+ inform (DECL_SOURCE_LOCATION (decl), "previous declaration here");
+ return false;
+ }
+ return true;
+}
+
+/* Handle an "abi_tag" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_abi_tag_attribute (tree* node, tree name, tree args,
+ int flags, bool* no_add_attrs)
+{
+ if (TYPE_P (*node))
+ {
+ if (!OVERLOAD_TYPE_P (*node))
+ {
+ error ("%qE attribute applied to non-class, non-enum type %qT",
+ name, *node);
+ goto fail;
+ }
+ else if (!(flags & (int)ATTR_FLAG_TYPE_IN_PLACE))
+ {
+ error ("%qE attribute applied to %qT after its definition",
+ name, *node);
+ goto fail;
+ }
+
+ tree attributes = TYPE_ATTRIBUTES (*node);
+ tree decl = TYPE_NAME (*node);
+
+ /* Make sure all declarations have the same abi tags. */
+ if (DECL_SOURCE_LOCATION (decl) != input_location)
+ {
+ if (!check_abi_tag_redeclaration (decl,
+ lookup_attribute ("abi_tag",
+ attributes),
+ args))
+ goto fail;
+ }
+ }
+ else
+ {
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ error ("%qE attribute applied to non-function %qD", name, *node);
+ goto fail;
+ }
+ else if (DECL_LANGUAGE (*node) == lang_c)
+ {
+ error ("%qE attribute applied to extern \"C\" function %qD",
+ name, *node);
+ goto fail;
+ }
+ }
+
+ return NULL_TREE;
+
+ fail:
+ *no_add_attrs = true;
+ return NULL_TREE;
+}
+
+/* Return a new PTRMEM_CST of the indicated TYPE. The MEMBER is the
+ thing pointed to by the constant. */
+
+tree
+make_ptrmem_cst (tree type, tree member)
+{
+ tree ptrmem_cst = make_node (PTRMEM_CST);
+ TREE_TYPE (ptrmem_cst) = type;
+ PTRMEM_CST_MEMBER (ptrmem_cst) = member;
+ return ptrmem_cst;
+}
+
+/* Build a variant of TYPE that has the indicated ATTRIBUTES. May
+ return an existing type if an appropriate type already exists. */
+
+tree
+cp_build_type_attribute_variant (tree type, tree attributes)
+{
+ tree new_type;
+
+ new_type = build_type_attribute_variant (type, attributes);
+ if (TREE_CODE (new_type) == FUNCTION_TYPE
+ || TREE_CODE (new_type) == METHOD_TYPE)
+ {
+ new_type = build_exception_variant (new_type,
+ TYPE_RAISES_EXCEPTIONS (type));
+ new_type = build_ref_qualified_type (new_type,
+ type_memfn_rqual (type));
+ }
+
+ /* Making a new main variant of a class type is broken. */
+ gcc_assert (!CLASS_TYPE_P (type) || new_type == type);
+
+ return new_type;
+}
+
+/* Return TRUE if TYPE1 and TYPE2 are identical for type hashing purposes.
+ Called only after doing all language independent checks. Only
+ to check TYPE_RAISES_EXCEPTIONS for FUNCTION_TYPE, the rest is already
+ compared in type_hash_eq. */
+
+bool
+cxx_type_hash_eq (const_tree typea, const_tree typeb)
+{
+ gcc_assert (TREE_CODE (typea) == FUNCTION_TYPE
+ || TREE_CODE (typea) == METHOD_TYPE);
+
+ return comp_except_specs (TYPE_RAISES_EXCEPTIONS (typea),
+ TYPE_RAISES_EXCEPTIONS (typeb), ce_exact);
+}
+
+/* Apply FUNC to all language-specific sub-trees of TP in a pre-order
+ traversal. Called from walk_tree. */
+
+tree
+cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
+ void *data, struct pointer_set_t *pset)
+{
+ enum tree_code code = TREE_CODE (*tp);
+ tree result;
+
+#define WALK_SUBTREE(NODE) \
+ do \
+ { \
+ result = cp_walk_tree (&(NODE), func, data, pset); \
+ if (result) goto out; \
+ } \
+ while (0)
+
+ /* Not one of the easy cases. We must explicitly go through the
+ children. */
+ result = NULL_TREE;
+ switch (code)
+ {
+ case DEFAULT_ARG:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ case UNBOUND_CLASS_TEMPLATE:
+ case TEMPLATE_PARM_INDEX:
+ case TEMPLATE_TYPE_PARM:
+ case TYPENAME_TYPE:
+ case TYPEOF_TYPE:
+ case UNDERLYING_TYPE:
+ /* None of these have subtrees other than those already walked
+ above. */
+ *walk_subtrees_p = 0;
+ break;
+
+ case BASELINK:
+ WALK_SUBTREE (BASELINK_FUNCTIONS (*tp));
+ *walk_subtrees_p = 0;
+ break;
+
+ case PTRMEM_CST:
+ WALK_SUBTREE (TREE_TYPE (*tp));
+ *walk_subtrees_p = 0;
+ break;
+
+ case TREE_LIST:
+ WALK_SUBTREE (TREE_PURPOSE (*tp));
+ break;
+
+ case OVERLOAD:
+ WALK_SUBTREE (OVL_FUNCTION (*tp));
+ WALK_SUBTREE (OVL_CHAIN (*tp));
+ *walk_subtrees_p = 0;
+ break;
+
+ case USING_DECL:
+ WALK_SUBTREE (DECL_NAME (*tp));
+ WALK_SUBTREE (USING_DECL_SCOPE (*tp));
+ WALK_SUBTREE (USING_DECL_DECLS (*tp));
+ *walk_subtrees_p = 0;
+ break;
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (*tp))
+ WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE (*tp));
+ break;
+
+ case TYPE_ARGUMENT_PACK:
+ case NONTYPE_ARGUMENT_PACK:
+ {
+ tree args = ARGUMENT_PACK_ARGS (*tp);
+ int i, len = TREE_VEC_LENGTH (args);
+ for (i = 0; i < len; i++)
+ WALK_SUBTREE (TREE_VEC_ELT (args, i));
+ }
+ break;
+
+ case TYPE_PACK_EXPANSION:
+ WALK_SUBTREE (TREE_TYPE (*tp));
+ WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
+ *walk_subtrees_p = 0;
+ break;
+
+ case EXPR_PACK_EXPANSION:
+ WALK_SUBTREE (TREE_OPERAND (*tp, 0));
+ WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
+ *walk_subtrees_p = 0;
+ break;
+
+ case CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
+ if (TREE_TYPE (*tp))
+ WALK_SUBTREE (TREE_TYPE (*tp));
+
+ {
+ int i;
+ for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (*tp)); ++i)
+ WALK_SUBTREE (TREE_OPERAND (*tp, i));
+ }
+ *walk_subtrees_p = 0;
+ break;
+
+ case TRAIT_EXPR:
+ WALK_SUBTREE (TRAIT_EXPR_TYPE1 (*tp));
+ WALK_SUBTREE (TRAIT_EXPR_TYPE2 (*tp));
+ *walk_subtrees_p = 0;
+ break;
+
+ case DECLTYPE_TYPE:
+ WALK_SUBTREE (DECLTYPE_TYPE_EXPR (*tp));
+ *walk_subtrees_p = 0;
+ break;
+
+
+ default:
+ return NULL_TREE;
+ }
+
+ /* We didn't find what we were looking for. */
+ out:
+ return result;
+
+#undef WALK_SUBTREE
+}
+
+/* Like save_expr, but for C++. */
+
+tree
+cp_save_expr (tree expr)
+{
+ /* There is no reason to create a SAVE_EXPR within a template; if
+ needed, we can create the SAVE_EXPR when instantiating the
+ template. Furthermore, the middle-end cannot handle C++-specific
+ tree codes. */
+ if (processing_template_decl)
+ return expr;
+ return save_expr (expr);
+}
+
+/* Initialize tree.c. */
+
+void
+init_tree (void)
+{
+ list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL);
+}
+
+/* Returns the kind of special function that DECL (a FUNCTION_DECL)
+ is. Note that sfk_none is zero, so this function can be used as a
+ predicate to test whether or not DECL is a special function. */
+
+special_function_kind
+special_function_p (const_tree decl)
+{
+ /* Rather than doing all this stuff with magic names, we should
+ probably have a field of type `special_function_kind' in
+ DECL_LANG_SPECIFIC. */
+ if (DECL_INHERITED_CTOR_BASE (decl))
+ return sfk_inheriting_constructor;
+ if (DECL_COPY_CONSTRUCTOR_P (decl))
+ return sfk_copy_constructor;
+ if (DECL_MOVE_CONSTRUCTOR_P (decl))
+ return sfk_move_constructor;
+ if (DECL_CONSTRUCTOR_P (decl))
+ return sfk_constructor;
+ if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
+ {
+ if (copy_fn_p (decl))
+ return sfk_copy_assignment;
+ if (move_fn_p (decl))
+ return sfk_move_assignment;
+ }
+ if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
+ return sfk_destructor;
+ if (DECL_COMPLETE_DESTRUCTOR_P (decl))
+ return sfk_complete_destructor;
+ if (DECL_BASE_DESTRUCTOR_P (decl))
+ return sfk_base_destructor;
+ if (DECL_DELETING_DESTRUCTOR_P (decl))
+ return sfk_deleting_destructor;
+ if (DECL_CONV_FN_P (decl))
+ return sfk_conversion;
+
+ return sfk_none;
+}
+
+/* Returns nonzero if TYPE is a character type, including wchar_t. */
+
+int
+char_type_p (tree type)
+{
+ return (same_type_p (type, char_type_node)
+ || same_type_p (type, unsigned_char_type_node)
+ || same_type_p (type, signed_char_type_node)
+ || same_type_p (type, char16_type_node)
+ || same_type_p (type, char32_type_node)
+ || same_type_p (type, wchar_type_node));
+}
+
+/* Returns the kind of linkage associated with the indicated DECL. Th
+ value returned is as specified by the language standard; it is
+ independent of implementation details regarding template
+ instantiation, etc. For example, it is possible that a declaration
+ to which this function assigns external linkage would not show up
+ as a global symbol when you run `nm' on the resulting object file. */
+
+linkage_kind
+decl_linkage (tree decl)
+{
+ /* This function doesn't attempt to calculate the linkage from first
+ principles as given in [basic.link]. Instead, it makes use of
+ the fact that we have already set TREE_PUBLIC appropriately, and
+ then handles a few special cases. Ideally, we would calculate
+ linkage first, and then transform that into a concrete
+ implementation. */
+
+ /* Things that don't have names have no linkage. */
+ if (!DECL_NAME (decl))
+ return lk_none;
+
+ /* Fields have no linkage. */
+ if (TREE_CODE (decl) == FIELD_DECL)
+ return lk_none;
+
+ /* Things that are TREE_PUBLIC have external linkage. */
+ if (TREE_PUBLIC (decl))
+ return lk_external;
+
+ if (TREE_CODE (decl) == NAMESPACE_DECL)
+ return lk_external;
+
+ /* Linkage of a CONST_DECL depends on the linkage of the enumeration
+ type. */
+ if (TREE_CODE (decl) == CONST_DECL)
+ return decl_linkage (TYPE_NAME (DECL_CONTEXT (decl)));
+
+ /* Some things that are not TREE_PUBLIC have external linkage, too.
+ For example, on targets that don't have weak symbols, we make all
+ template instantiations have internal linkage (in the object
+ file), but the symbols should still be treated as having external
+ linkage from the point of view of the language. */
+ if (VAR_OR_FUNCTION_DECL_P (decl)
+ && DECL_COMDAT (decl))
+ return lk_external;
+
+ /* Things in local scope do not have linkage, if they don't have
+ TREE_PUBLIC set. */
+ if (decl_function_context (decl))
+ return lk_none;
+
+ /* Members of the anonymous namespace also have TREE_PUBLIC unset, but
+ are considered to have external linkage for language purposes. DECLs
+ really meant to have internal linkage have DECL_THIS_STATIC set. */
+ if (TREE_CODE (decl) == TYPE_DECL)
+ return lk_external;
+ if (VAR_OR_FUNCTION_DECL_P (decl))
+ {
+ if (!DECL_THIS_STATIC (decl))
+ return lk_external;
+
+ /* Static data members and static member functions from classes
+ in anonymous namespace also don't have TREE_PUBLIC set. */
+ if (DECL_CLASS_CONTEXT (decl))
+ return lk_external;
+ }
+
+ /* Everything else has internal linkage. */
+ return lk_internal;
+}
+
+/* Returns the storage duration of the object or reference associated with
+ the indicated DECL, which should be a VAR_DECL or PARM_DECL. */
+
+duration_kind
+decl_storage_duration (tree decl)
+{
+ if (TREE_CODE (decl) == PARM_DECL)
+ return dk_auto;
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ return dk_static;
+ gcc_assert (VAR_P (decl));
+ if (!TREE_STATIC (decl)
+ && !DECL_EXTERNAL (decl))
+ return dk_auto;
+ if (DECL_THREAD_LOCAL_P (decl))
+ return dk_thread;
+ return dk_static;
+}
+
+/* EXP is an expression that we want to pre-evaluate. Returns (in
+ *INITP) an expression that will perform the pre-evaluation. The
+ value returned by this function is a side-effect free expression
+ equivalent to the pre-evaluated expression. Callers must ensure
+ that *INITP is evaluated before EXP. */
+
+tree
+stabilize_expr (tree exp, tree* initp)
+{
+ tree init_expr;
+
+ if (!TREE_SIDE_EFFECTS (exp))
+ init_expr = NULL_TREE;
+ else if (VOID_TYPE_P (TREE_TYPE (exp)))
+ {
+ init_expr = exp;
+ exp = void_zero_node;
+ }
+ /* There are no expressions with REFERENCE_TYPE, but there can be call
+ arguments with such a type; just treat it as a pointer. */
+ else if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE
+ || SCALAR_TYPE_P (TREE_TYPE (exp))
+ || !lvalue_or_rvalue_with_address_p (exp))
+ {
+ init_expr = get_target_expr (exp);
+ exp = TARGET_EXPR_SLOT (init_expr);
+ }
+ else
+ {
+ bool xval = !real_lvalue_p (exp);
+ exp = cp_build_addr_expr (exp, tf_warning_or_error);
+ init_expr = get_target_expr (exp);
+ exp = TARGET_EXPR_SLOT (init_expr);
+ exp = cp_build_indirect_ref (exp, RO_NULL, tf_warning_or_error);
+ if (xval)
+ exp = move (exp);
+ }
+ *initp = init_expr;
+
+ gcc_assert (!TREE_SIDE_EFFECTS (exp));
+ return exp;
+}
+
+/* Add NEW_EXPR, an expression whose value we don't care about, after the
+ similar expression ORIG. */
+
+tree
+add_stmt_to_compound (tree orig, tree new_expr)
+{
+ if (!new_expr || !TREE_SIDE_EFFECTS (new_expr))
+ return orig;
+ if (!orig || !TREE_SIDE_EFFECTS (orig))
+ return new_expr;
+ return build2 (COMPOUND_EXPR, void_type_node, orig, new_expr);
+}
+
+/* Like stabilize_expr, but for a call whose arguments we want to
+ pre-evaluate. CALL is modified in place to use the pre-evaluated
+ arguments, while, upon return, *INITP contains an expression to
+ compute the arguments. */
+
+void
+stabilize_call (tree call, tree *initp)
+{
+ tree inits = NULL_TREE;
+ int i;
+ int nargs = call_expr_nargs (call);
+
+ if (call == error_mark_node || processing_template_decl)
+ {
+ *initp = NULL_TREE;
+ return;
+ }
+
+ gcc_assert (TREE_CODE (call) == CALL_EXPR);
+
+ for (i = 0; i < nargs; i++)
+ {
+ tree init;
+ CALL_EXPR_ARG (call, i) =
+ stabilize_expr (CALL_EXPR_ARG (call, i), &init);
+ inits = add_stmt_to_compound (inits, init);
+ }
+
+ *initp = inits;
+}
+
+/* Like stabilize_expr, but for an AGGR_INIT_EXPR whose arguments we want
+ to pre-evaluate. CALL is modified in place to use the pre-evaluated
+ arguments, while, upon return, *INITP contains an expression to
+ compute the arguments. */
+
+static void
+stabilize_aggr_init (tree call, tree *initp)
+{
+ tree inits = NULL_TREE;
+ int i;
+ int nargs = aggr_init_expr_nargs (call);
+
+ if (call == error_mark_node)
+ return;
+
+ gcc_assert (TREE_CODE (call) == AGGR_INIT_EXPR);
+
+ for (i = 0; i < nargs; i++)
+ {
+ tree init;
+ AGGR_INIT_EXPR_ARG (call, i) =
+ stabilize_expr (AGGR_INIT_EXPR_ARG (call, i), &init);
+ inits = add_stmt_to_compound (inits, init);
+ }
+
+ *initp = inits;
+}
+
+/* Like stabilize_expr, but for an initialization.
+
+ If the initialization is for an object of class type, this function
+ takes care not to introduce additional temporaries.
+
+ Returns TRUE iff the expression was successfully pre-evaluated,
+ i.e., if INIT is now side-effect free, except for, possibly, a
+ single call to a constructor. */
+
+bool
+stabilize_init (tree init, tree *initp)
+{
+ tree t = init;
+
+ *initp = NULL_TREE;
+
+ if (t == error_mark_node || processing_template_decl)
+ return true;
+
+ if (TREE_CODE (t) == INIT_EXPR)
+ t = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == TARGET_EXPR)
+ t = TARGET_EXPR_INITIAL (t);
+
+ /* If the RHS can be stabilized without breaking copy elision, stabilize
+ it. We specifically don't stabilize class prvalues here because that
+ would mean an extra copy, but they might be stabilized below. */
+ if (TREE_CODE (init) == INIT_EXPR
+ && TREE_CODE (t) != CONSTRUCTOR
+ && TREE_CODE (t) != AGGR_INIT_EXPR
+ && (SCALAR_TYPE_P (TREE_TYPE (t))
+ || lvalue_or_rvalue_with_address_p (t)))
+ {
+ TREE_OPERAND (init, 1) = stabilize_expr (t, initp);
+ return true;
+ }
+
+ if (TREE_CODE (t) == COMPOUND_EXPR
+ && TREE_CODE (init) == INIT_EXPR)
+ {
+ tree last = expr_last (t);
+ /* Handle stabilizing the EMPTY_CLASS_EXPR pattern. */
+ if (!TREE_SIDE_EFFECTS (last))
+ {
+ *initp = t;
+ TREE_OPERAND (init, 1) = last;
+ return true;
+ }
+ }
+
+ if (TREE_CODE (t) == CONSTRUCTOR)
+ {
+ /* Aggregate initialization: stabilize each of the field
+ initializers. */
+ unsigned i;
+ constructor_elt *ce;
+ bool good = true;
+ vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
+ for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
+ {
+ tree type = TREE_TYPE (ce->value);
+ tree subinit;
+ if (TREE_CODE (type) == REFERENCE_TYPE
+ || SCALAR_TYPE_P (type))
+ ce->value = stabilize_expr (ce->value, &subinit);
+ else if (!stabilize_init (ce->value, &subinit))
+ good = false;
+ *initp = add_stmt_to_compound (*initp, subinit);
+ }
+ return good;
+ }
+
+ if (TREE_CODE (t) == CALL_EXPR)
+ {
+ stabilize_call (t, initp);
+ return true;
+ }
+
+ if (TREE_CODE (t) == AGGR_INIT_EXPR)
+ {
+ stabilize_aggr_init (t, initp);
+ return true;
+ }
+
+ /* The initialization is being performed via a bitwise copy -- and
+ the item copied may have side effects. */
+ return !TREE_SIDE_EFFECTS (init);
+}
+
+/* Like "fold", but should be used whenever we might be processing the
+ body of a template. */
+
+tree
+fold_if_not_in_template (tree expr)
+{
+ /* In the body of a template, there is never any need to call
+ "fold". We will call fold later when actually instantiating the
+ template. Integral constant expressions in templates will be
+ evaluated via fold_non_dependent_expr, as necessary. */
+ if (processing_template_decl)
+ return expr;
+
+ /* Fold C++ front-end specific tree codes. */
+ if (TREE_CODE (expr) == UNARY_PLUS_EXPR)
+ return fold_convert (TREE_TYPE (expr), TREE_OPERAND (expr, 0));
+
+ return fold (expr);
+}
+
+/* Returns true if a cast to TYPE may appear in an integral constant
+ expression. */
+
+bool
+cast_valid_in_integral_constant_expression_p (tree type)
+{
+ return (INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+ || cxx_dialect >= cxx11
+ || dependent_type_p (type)
+ || type == error_mark_node);
+}
+
+/* Return true if we need to fix linkage information of DECL. */
+
+static bool
+cp_fix_function_decl_p (tree decl)
+{
+ /* Skip if DECL is not externally visible. */
+ if (!TREE_PUBLIC (decl))
+ return false;
+
+ /* We need to fix DECL if it a appears to be exported but with no
+ function body. Thunks do not have CFGs and we may need to
+ handle them specially later. */
+ if (!gimple_has_body_p (decl)
+ && !DECL_THUNK_P (decl)
+ && !DECL_EXTERNAL (decl))
+ {
+ struct cgraph_node *node = cgraph_get_node (decl);
+
+ /* Don't fix same_body aliases. Although they don't have their own
+ CFG, they share it with what they alias to. */
+ if (!node || !node->alias
+ || !vec_safe_length (node->ref_list.references))
+ return true;
+ }
+
+ return false;
+}
+
+/* Clean the C++ specific parts of the tree T. */
+
+void
+cp_free_lang_data (tree t)
+{
+ if (TREE_CODE (t) == METHOD_TYPE
+ || TREE_CODE (t) == FUNCTION_TYPE)
+ {
+ /* Default args are not interesting anymore. */
+ tree argtypes = TYPE_ARG_TYPES (t);
+ while (argtypes)
+ {
+ TREE_PURPOSE (argtypes) = 0;
+ argtypes = TREE_CHAIN (argtypes);
+ }
+ }
+ else if (TREE_CODE (t) == FUNCTION_DECL
+ && cp_fix_function_decl_p (t))
+ {
+ /* If T is used in this translation unit at all, the definition
+ must exist somewhere else since we have decided to not emit it
+ in this TU. So make it an external reference. */
+ DECL_EXTERNAL (t) = 1;
+ TREE_STATIC (t) = 0;
+ }
+ if (TREE_CODE (t) == NAMESPACE_DECL)
+ {
+ /* The list of users of a namespace isn't useful for the middle-end
+ or debug generators. */
+ DECL_NAMESPACE_USERS (t) = NULL_TREE;
+ /* Neither do we need the leftover chaining of namespaces
+ from the binding level. */
+ DECL_CHAIN (t) = NULL_TREE;
+ }
+}
+
+/* Stub for c-common. Please keep in sync with c-decl.c.
+ FIXME: If address space support is target specific, then this
+ should be a C target hook. But currently this is not possible,
+ because this function is called via REGISTER_TARGET_PRAGMAS. */
+void
+c_register_addr_space (const char * /*word*/, addr_space_t /*as*/)
+{
+}
+
+/* Return the number of operands in T that we care about for things like
+ mangling. */
+
+int
+cp_tree_operand_length (const_tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+
+ switch (code)
+ {
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ return 1;
+
+ case ARRAY_REF:
+ return 2;
+
+ case EXPR_PACK_EXPANSION:
+ return 1;
+
+ default:
+ return TREE_OPERAND_LENGTH (t);
+ }
+}
+
+/* Implement -Wzero_as_null_pointer_constant. Return true if the
+ conditions for the warning hold, false otherwise. */
+bool
+maybe_warn_zero_as_null_pointer_constant (tree expr, location_t loc)
+{
+ if (c_inhibit_evaluation_warnings == 0
+ && !NULLPTR_TYPE_P (TREE_TYPE (expr)))
+ {
+ warning_at (loc, OPT_Wzero_as_null_pointer_constant,
+ "zero as null pointer constant");
+ return true;
+ }
+ return false;
+}
+
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+/* Complain that some language-specific thing hanging off a tree
+ node has been accessed improperly. */
+
+void
+lang_check_failed (const char* file, int line, const char* function)
+{
+ internal_error ("lang_* check: failed in %s, at %s:%d",
+ function, trim_filename (file), line);
+}
+#endif /* ENABLE_TREE_CHECKING */
+
+#include "gt-cp-tree.h"
diff --git a/gcc-4.9/gcc/cp/type-utils.h b/gcc-4.9/gcc/cp/type-utils.h
new file mode 100644
index 000000000..6f115b1e7
--- /dev/null
+++ b/gcc-4.9/gcc/cp/type-utils.h
@@ -0,0 +1,55 @@
+/* Utilities for querying and manipulating type trees.
+ Copyright (C) 2013-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_CP_TYPE_UTILS_H
+#define GCC_CP_TYPE_UTILS_H
+
+/* Returns the first tree within T that is directly matched by PRED. T may be a
+ type or PARM_DECL and is incrementally decomposed toward its type-specifier
+ until a match is found. NULL_TREE is returned if PRED does not match any
+ part of T.
+
+ This is primarily intended for detecting whether T uses `auto' or a concept
+ identifier. Since either of these can only appear as a type-specifier for
+ the declaration in question, only top-level qualifications are traversed;
+ find_type_usage does not look through the whole type. */
+
+inline tree
+find_type_usage (tree t, bool (*pred) (const_tree))
+{
+ enum tree_code code;
+ if (pred (t))
+ return t;
+
+ code = TREE_CODE (t);
+
+ if (code == POINTER_TYPE || code == REFERENCE_TYPE
+ || code == PARM_DECL || code == OFFSET_TYPE
+ || code == FUNCTION_TYPE || code == METHOD_TYPE
+ || code == ARRAY_TYPE)
+ return find_type_usage (TREE_TYPE (t), pred);
+
+ if (TYPE_PTRMEMFUNC_P (t))
+ return find_type_usage
+ (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t)), pred);
+
+ return NULL_TREE;
+}
+
+#endif // GCC_CP_TYPE_UTILS_H
diff --git a/gcc-4.9/gcc/cp/typeck.c b/gcc-4.9/gcc/cp/typeck.c
new file mode 100644
index 000000000..559f19b55
--- /dev/null
+++ b/gcc-4.9/gcc/cp/typeck.c
@@ -0,0 +1,9202 @@
+/* Build expressions with type checking for C++ compiler.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Hacked by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* This file is part of the C++ front end.
+ It contains routines to build C++ expressions given their operands,
+ including computing the types of the result, C and C++ specific error
+ checks, and some optimization. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stor-layout.h"
+#include "varasm.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "diagnostic.h"
+#include "intl.h"
+#include "target.h"
+#include "convert.h"
+#include "c-family/c-common.h"
+#include "c-family/c-objc.h"
+#include "c-family/c-ubsan.h"
+#include "params.h"
+
+static tree pfn_from_ptrmemfunc (tree);
+static tree delta_from_ptrmemfunc (tree);
+static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int,
+ tsubst_flags_t, int);
+static tree cp_pointer_int_sum (enum tree_code, tree, tree, tsubst_flags_t);
+static tree rationalize_conditional_expr (enum tree_code, tree,
+ tsubst_flags_t);
+static int comp_ptr_ttypes_real (tree, tree, int);
+static bool comp_except_types (tree, tree, bool);
+static bool comp_array_types (const_tree, const_tree, bool);
+static tree pointer_diff (tree, tree, tree, tsubst_flags_t);
+static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
+static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
+static bool casts_away_constness (tree, tree, tsubst_flags_t);
+static void maybe_warn_about_returning_address_of_local (tree);
+static tree lookup_destructor (tree, tree, tree, tsubst_flags_t);
+static void warn_args_num (location_t, tree, bool);
+static int convert_arguments (tree, vec<tree, va_gc> **, tree, int,
+ tsubst_flags_t);
+
+/* Do `exp = require_complete_type (exp);' to make sure exp
+ does not have an incomplete type. (That includes void types.)
+ Returns error_mark_node if the VALUE does not have
+ complete type when this function returns. */
+
+tree
+require_complete_type_sfinae (tree value, tsubst_flags_t complain)
+{
+ tree type;
+
+ if (processing_template_decl || value == error_mark_node)
+ return value;
+
+ if (TREE_CODE (value) == OVERLOAD)
+ type = unknown_type_node;
+ else
+ type = TREE_TYPE (value);
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ /* First, detect a valid value with a complete type. */
+ if (COMPLETE_TYPE_P (type))
+ return value;
+
+ if (complete_type_or_maybe_complain (type, value, complain))
+ return value;
+ else
+ return error_mark_node;
+}
+
+tree
+require_complete_type (tree value)
+{
+ return require_complete_type_sfinae (value, tf_warning_or_error);
+}
+
+/* Try to complete TYPE, if it is incomplete. For example, if TYPE is
+ a template instantiation, do the instantiation. Returns TYPE,
+ whether or not it could be completed, unless something goes
+ horribly wrong, in which case the error_mark_node is returned. */
+
+tree
+complete_type (tree type)
+{
+ if (type == NULL_TREE)
+ /* Rather than crash, we return something sure to cause an error
+ at some point. */
+ return error_mark_node;
+
+ if (type == error_mark_node || COMPLETE_TYPE_P (type))
+ ;
+ else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
+ {
+ tree t = complete_type (TREE_TYPE (type));
+ unsigned int needs_constructing, has_nontrivial_dtor;
+ if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
+ layout_type (type);
+ needs_constructing
+ = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
+ has_nontrivial_dtor
+ = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ {
+ TYPE_NEEDS_CONSTRUCTING (t) = needs_constructing;
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = has_nontrivial_dtor;
+ }
+ }
+ else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
+ instantiate_class_template (TYPE_MAIN_VARIANT (type));
+
+ return type;
+}
+
+/* Like complete_type, but issue an error if the TYPE cannot be completed.
+ VALUE is used for informative diagnostics.
+ Returns NULL_TREE if the type cannot be made complete. */
+
+tree
+complete_type_or_maybe_complain (tree type, tree value, tsubst_flags_t complain)
+{
+ type = complete_type (type);
+ if (type == error_mark_node)
+ /* We already issued an error. */
+ return NULL_TREE;
+ else if (!COMPLETE_TYPE_P (type))
+ {
+ if (complain & tf_error)
+ cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
+ return NULL_TREE;
+ }
+ else
+ return type;
+}
+
+tree
+complete_type_or_else (tree type, tree value)
+{
+ return complete_type_or_maybe_complain (type, value, tf_warning_or_error);
+}
+
+/* Return truthvalue of whether type of EXP is instantiated. */
+
+int
+type_unknown_p (const_tree exp)
+{
+ return (TREE_CODE (exp) == TREE_LIST
+ || TREE_TYPE (exp) == unknown_type_node);
+}
+
+
+/* Return the common type of two parameter lists.
+ We assume that comptypes has already been done and returned 1;
+ if that isn't so, this may crash.
+
+ As an optimization, free the space we allocate if the parameter
+ lists are already common. */
+
+static tree
+commonparms (tree p1, tree p2)
+{
+ tree oldargs = p1, newargs, n;
+ int i, len;
+ int any_change = 0;
+
+ len = list_length (p1);
+ newargs = tree_last (p1);
+
+ if (newargs == void_list_node)
+ i = 1;
+ else
+ {
+ i = 0;
+ newargs = 0;
+ }
+
+ for (; i < len; i++)
+ newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
+
+ n = newargs;
+
+ for (i = 0; p1;
+ p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n), i++)
+ {
+ if (TREE_PURPOSE (p1) && !TREE_PURPOSE (p2))
+ {
+ TREE_PURPOSE (n) = TREE_PURPOSE (p1);
+ any_change = 1;
+ }
+ else if (! TREE_PURPOSE (p1))
+ {
+ if (TREE_PURPOSE (p2))
+ {
+ TREE_PURPOSE (n) = TREE_PURPOSE (p2);
+ any_change = 1;
+ }
+ }
+ else
+ {
+ if (1 != simple_cst_equal (TREE_PURPOSE (p1), TREE_PURPOSE (p2)))
+ any_change = 1;
+ TREE_PURPOSE (n) = TREE_PURPOSE (p2);
+ }
+ if (TREE_VALUE (p1) != TREE_VALUE (p2))
+ {
+ any_change = 1;
+ TREE_VALUE (n) = merge_types (TREE_VALUE (p1), TREE_VALUE (p2));
+ }
+ else
+ TREE_VALUE (n) = TREE_VALUE (p1);
+ }
+ if (! any_change)
+ return oldargs;
+
+ return newargs;
+}
+
+/* Given a type, perhaps copied for a typedef,
+ find the "original" version of it. */
+static tree
+original_type (tree t)
+{
+ int quals = cp_type_quals (t);
+ while (t != error_mark_node
+ && TYPE_NAME (t) != NULL_TREE)
+ {
+ tree x = TYPE_NAME (t);
+ if (TREE_CODE (x) != TYPE_DECL)
+ break;
+ x = DECL_ORIGINAL_TYPE (x);
+ if (x == NULL_TREE)
+ break;
+ t = x;
+ }
+ return cp_build_qualified_type (t, quals);
+}
+
+/* Return the common type for two arithmetic types T1 and T2 under the
+ usual arithmetic conversions. The default conversions have already
+ been applied, and enumerated types converted to their compatible
+ integer types. */
+
+static tree
+cp_common_type (tree t1, tree t2)
+{
+ enum tree_code code1 = TREE_CODE (t1);
+ enum tree_code code2 = TREE_CODE (t2);
+ tree attributes;
+
+
+ /* In what follows, we slightly generalize the rules given in [expr] so
+ as to deal with `long long' and `complex'. First, merge the
+ attributes. */
+ attributes = (*targetm.merge_type_attributes) (t1, t2);
+
+ if (SCOPED_ENUM_P (t1) || SCOPED_ENUM_P (t2))
+ {
+ if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
+ return build_type_attribute_variant (t1, attributes);
+ else
+ return NULL_TREE;
+ }
+
+ /* FIXME: Attributes. */
+ gcc_assert (ARITHMETIC_TYPE_P (t1)
+ || TREE_CODE (t1) == VECTOR_TYPE
+ || UNSCOPED_ENUM_P (t1));
+ gcc_assert (ARITHMETIC_TYPE_P (t2)
+ || TREE_CODE (t2) == VECTOR_TYPE
+ || UNSCOPED_ENUM_P (t2));
+
+ /* If one type is complex, form the common type of the non-complex
+ components, then make that complex. Use T1 or T2 if it is the
+ required type. */
+ if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
+ {
+ tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
+ tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
+ tree subtype
+ = type_after_usual_arithmetic_conversions (subtype1, subtype2);
+
+ if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
+ return build_type_attribute_variant (t1, attributes);
+ else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
+ return build_type_attribute_variant (t2, attributes);
+ else
+ return build_type_attribute_variant (build_complex_type (subtype),
+ attributes);
+ }
+
+ if (code1 == VECTOR_TYPE)
+ {
+ /* When we get here we should have two vectors of the same size.
+ Just prefer the unsigned one if present. */
+ if (TYPE_UNSIGNED (t1))
+ return build_type_attribute_variant (t1, attributes);
+ else
+ return build_type_attribute_variant (t2, attributes);
+ }
+
+ /* If only one is real, use it as the result. */
+ if (code1 == REAL_TYPE && code2 != REAL_TYPE)
+ return build_type_attribute_variant (t1, attributes);
+ if (code2 == REAL_TYPE && code1 != REAL_TYPE)
+ return build_type_attribute_variant (t2, attributes);
+
+ /* Both real or both integers; use the one with greater precision. */
+ if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
+ return build_type_attribute_variant (t1, attributes);
+ else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
+ return build_type_attribute_variant (t2, attributes);
+
+ /* The types are the same; no need to do anything fancy. */
+ if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
+ return build_type_attribute_variant (t1, attributes);
+
+ if (code1 != REAL_TYPE)
+ {
+ /* If one is unsigned long long, then convert the other to unsigned
+ long long. */
+ if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_unsigned_type_node)
+ || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_unsigned_type_node))
+ return build_type_attribute_variant (long_long_unsigned_type_node,
+ attributes);
+ /* If one is a long long, and the other is an unsigned long, and
+ long long can represent all the values of an unsigned long, then
+ convert to a long long. Otherwise, convert to an unsigned long
+ long. Otherwise, if either operand is long long, convert the
+ other to long long.
+
+ Since we're here, we know the TYPE_PRECISION is the same;
+ therefore converting to long long cannot represent all the values
+ of an unsigned long, so we choose unsigned long long in that
+ case. */
+ if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_integer_type_node)
+ || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_integer_type_node))
+ {
+ tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+ ? long_long_unsigned_type_node
+ : long_long_integer_type_node);
+ return build_type_attribute_variant (t, attributes);
+ }
+ if (int128_integer_type_node != NULL_TREE
+ && (same_type_p (TYPE_MAIN_VARIANT (t1),
+ int128_integer_type_node)
+ || same_type_p (TYPE_MAIN_VARIANT (t2),
+ int128_integer_type_node)))
+ {
+ tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+ ? int128_unsigned_type_node
+ : int128_integer_type_node);
+ return build_type_attribute_variant (t, attributes);
+ }
+
+ /* Go through the same procedure, but for longs. */
+ if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node)
+ || same_type_p (TYPE_MAIN_VARIANT (t2), long_unsigned_type_node))
+ return build_type_attribute_variant (long_unsigned_type_node,
+ attributes);
+ if (same_type_p (TYPE_MAIN_VARIANT (t1), long_integer_type_node)
+ || same_type_p (TYPE_MAIN_VARIANT (t2), long_integer_type_node))
+ {
+ tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+ ? long_unsigned_type_node : long_integer_type_node);
+ return build_type_attribute_variant (t, attributes);
+ }
+ /* Otherwise prefer the unsigned one. */
+ if (TYPE_UNSIGNED (t1))
+ return build_type_attribute_variant (t1, attributes);
+ else
+ return build_type_attribute_variant (t2, attributes);
+ }
+ else
+ {
+ if (same_type_p (TYPE_MAIN_VARIANT (t1), long_double_type_node)
+ || same_type_p (TYPE_MAIN_VARIANT (t2), long_double_type_node))
+ return build_type_attribute_variant (long_double_type_node,
+ attributes);
+ if (same_type_p (TYPE_MAIN_VARIANT (t1), double_type_node)
+ || same_type_p (TYPE_MAIN_VARIANT (t2), double_type_node))
+ return build_type_attribute_variant (double_type_node,
+ attributes);
+ if (same_type_p (TYPE_MAIN_VARIANT (t1), float_type_node)
+ || same_type_p (TYPE_MAIN_VARIANT (t2), float_type_node))
+ return build_type_attribute_variant (float_type_node,
+ attributes);
+
+ /* Two floating-point types whose TYPE_MAIN_VARIANTs are none of
+ the standard C++ floating-point types. Logic earlier in this
+ function has already eliminated the possibility that
+ TYPE_PRECISION (t2) != TYPE_PRECISION (t1), so there's no
+ compelling reason to choose one or the other. */
+ return build_type_attribute_variant (t1, attributes);
+ }
+}
+
+/* T1 and T2 are arithmetic or enumeration types. Return the type
+ that will result from the "usual arithmetic conversions" on T1 and
+ T2 as described in [expr]. */
+
+tree
+type_after_usual_arithmetic_conversions (tree t1, tree t2)
+{
+ gcc_assert (ARITHMETIC_TYPE_P (t1)
+ || TREE_CODE (t1) == VECTOR_TYPE
+ || UNSCOPED_ENUM_P (t1));
+ gcc_assert (ARITHMETIC_TYPE_P (t2)
+ || TREE_CODE (t2) == VECTOR_TYPE
+ || UNSCOPED_ENUM_P (t2));
+
+ /* Perform the integral promotions. We do not promote real types here. */
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (t1)
+ && INTEGRAL_OR_ENUMERATION_TYPE_P (t2))
+ {
+ t1 = type_promotes_to (t1);
+ t2 = type_promotes_to (t2);
+ }
+
+ return cp_common_type (t1, t2);
+}
+
+static void
+composite_pointer_error (diagnostic_t kind, tree t1, tree t2,
+ composite_pointer_operation operation)
+{
+ switch (operation)
+ {
+ case CPO_COMPARISON:
+ emit_diagnostic (kind, input_location, 0,
+ "comparison between "
+ "distinct pointer types %qT and %qT lacks a cast",
+ t1, t2);
+ break;
+ case CPO_CONVERSION:
+ emit_diagnostic (kind, input_location, 0,
+ "conversion between "
+ "distinct pointer types %qT and %qT lacks a cast",
+ t1, t2);
+ break;
+ case CPO_CONDITIONAL_EXPR:
+ emit_diagnostic (kind, input_location, 0,
+ "conditional expression between "
+ "distinct pointer types %qT and %qT lacks a cast",
+ t1, t2);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Subroutine of composite_pointer_type to implement the recursive
+ case. See that function for documentation of the parameters. */
+
+static tree
+composite_pointer_type_r (tree t1, tree t2,
+ composite_pointer_operation operation,
+ tsubst_flags_t complain)
+{
+ tree pointee1;
+ tree pointee2;
+ tree result_type;
+ tree attributes;
+
+ /* Determine the types pointed to by T1 and T2. */
+ if (TYPE_PTR_P (t1))
+ {
+ pointee1 = TREE_TYPE (t1);
+ pointee2 = TREE_TYPE (t2);
+ }
+ else
+ {
+ pointee1 = TYPE_PTRMEM_POINTED_TO_TYPE (t1);
+ pointee2 = TYPE_PTRMEM_POINTED_TO_TYPE (t2);
+ }
+
+ /* [expr.rel]
+
+ Otherwise, the composite pointer type is a pointer type
+ similar (_conv.qual_) to the type of one of the operands,
+ with a cv-qualification signature (_conv.qual_) that is the
+ union of the cv-qualification signatures of the operand
+ types. */
+ if (same_type_ignoring_top_level_qualifiers_p (pointee1, pointee2))
+ result_type = pointee1;
+ else if ((TYPE_PTR_P (pointee1) && TYPE_PTR_P (pointee2))
+ || (TYPE_PTRMEM_P (pointee1) && TYPE_PTRMEM_P (pointee2)))
+ {
+ result_type = composite_pointer_type_r (pointee1, pointee2, operation,
+ complain);
+ if (result_type == error_mark_node)
+ return error_mark_node;
+ }
+ else
+ {
+ if (complain & tf_error)
+ composite_pointer_error (DK_PERMERROR, t1, t2, operation);
+ else
+ return error_mark_node;
+ result_type = void_type_node;
+ }
+ result_type = cp_build_qualified_type (result_type,
+ (cp_type_quals (pointee1)
+ | cp_type_quals (pointee2)));
+ /* If the original types were pointers to members, so is the
+ result. */
+ if (TYPE_PTRMEM_P (t1))
+ {
+ if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
+ TYPE_PTRMEM_CLASS_TYPE (t2)))
+ {
+ if (complain & tf_error)
+ composite_pointer_error (DK_PERMERROR, t1, t2, operation);
+ else
+ return error_mark_node;
+ }
+ result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
+ result_type);
+ }
+ else
+ result_type = build_pointer_type (result_type);
+
+ /* Merge the attributes. */
+ attributes = (*targetm.merge_type_attributes) (t1, t2);
+ return build_type_attribute_variant (result_type, attributes);
+}
+
+/* Return the composite pointer type (see [expr.rel]) for T1 and T2.
+ ARG1 and ARG2 are the values with those types. The OPERATION is to
+ describe the operation between the pointer types,
+ in case an error occurs.
+
+ This routine also implements the computation of a common type for
+ pointers-to-members as per [expr.eq]. */
+
+tree
+composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
+ composite_pointer_operation operation,
+ tsubst_flags_t complain)
+{
+ tree class1;
+ tree class2;
+
+ /* [expr.rel]
+
+ If one operand is a null pointer constant, the composite pointer
+ type is the type of the other operand. */
+ if (null_ptr_cst_p (arg1))
+ return t2;
+ if (null_ptr_cst_p (arg2))
+ return t1;
+
+ /* We have:
+
+ [expr.rel]
+
+ If one of the operands has type "pointer to cv1 void*", then
+ the other has type "pointer to cv2T", and the composite pointer
+ type is "pointer to cv12 void", where cv12 is the union of cv1
+ and cv2.
+
+ If either type is a pointer to void, make sure it is T1. */
+ if (TYPE_PTR_P (t2) && VOID_TYPE_P (TREE_TYPE (t2)))
+ {
+ tree t;
+ t = t1;
+ t1 = t2;
+ t2 = t;
+ }
+
+ /* Now, if T1 is a pointer to void, merge the qualifiers. */
+ if (TYPE_PTR_P (t1) && VOID_TYPE_P (TREE_TYPE (t1)))
+ {
+ tree attributes;
+ tree result_type;
+
+ if (TYPE_PTRFN_P (t2) && (complain & tf_error))
+ {
+ switch (operation)
+ {
+ case CPO_COMPARISON:
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ forbids comparison between "
+ "pointer of type %<void *%> and pointer-to-function");
+ break;
+ case CPO_CONVERSION:
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ forbids conversion between "
+ "pointer of type %<void *%> and pointer-to-function");
+ break;
+ case CPO_CONDITIONAL_EXPR:
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ forbids conditional expression between "
+ "pointer of type %<void *%> and pointer-to-function");
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ result_type
+ = cp_build_qualified_type (void_type_node,
+ (cp_type_quals (TREE_TYPE (t1))
+ | cp_type_quals (TREE_TYPE (t2))));
+ result_type = build_pointer_type (result_type);
+ /* Merge the attributes. */
+ attributes = (*targetm.merge_type_attributes) (t1, t2);
+ return build_type_attribute_variant (result_type, attributes);
+ }
+
+ if (c_dialect_objc () && TYPE_PTR_P (t1)
+ && TYPE_PTR_P (t2))
+ {
+ if (objc_have_common_type (t1, t2, -3, NULL_TREE))
+ return objc_common_type (t1, t2);
+ }
+
+ /* [expr.eq] permits the application of a pointer conversion to
+ bring the pointers to a common type. */
+ if (TYPE_PTR_P (t1) && TYPE_PTR_P (t2)
+ && CLASS_TYPE_P (TREE_TYPE (t1))
+ && CLASS_TYPE_P (TREE_TYPE (t2))
+ && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t1),
+ TREE_TYPE (t2)))
+ {
+ class1 = TREE_TYPE (t1);
+ class2 = TREE_TYPE (t2);
+
+ if (DERIVED_FROM_P (class1, class2))
+ t2 = (build_pointer_type
+ (cp_build_qualified_type (class1, cp_type_quals (class2))));
+ else if (DERIVED_FROM_P (class2, class1))
+ t1 = (build_pointer_type
+ (cp_build_qualified_type (class2, cp_type_quals (class1))));
+ else
+ {
+ if (complain & tf_error)
+ composite_pointer_error (DK_ERROR, t1, t2, operation);
+ return error_mark_node;
+ }
+ }
+ /* [expr.eq] permits the application of a pointer-to-member
+ conversion to change the class type of one of the types. */
+ else if (TYPE_PTRMEM_P (t1)
+ && !same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
+ TYPE_PTRMEM_CLASS_TYPE (t2)))
+ {
+ class1 = TYPE_PTRMEM_CLASS_TYPE (t1);
+ class2 = TYPE_PTRMEM_CLASS_TYPE (t2);
+
+ if (DERIVED_FROM_P (class1, class2))
+ t1 = build_ptrmem_type (class2, TYPE_PTRMEM_POINTED_TO_TYPE (t1));
+ else if (DERIVED_FROM_P (class2, class1))
+ t2 = build_ptrmem_type (class1, TYPE_PTRMEM_POINTED_TO_TYPE (t2));
+ else
+ {
+ if (complain & tf_error)
+ switch (operation)
+ {
+ case CPO_COMPARISON:
+ error ("comparison between distinct "
+ "pointer-to-member types %qT and %qT lacks a cast",
+ t1, t2);
+ break;
+ case CPO_CONVERSION:
+ error ("conversion between distinct "
+ "pointer-to-member types %qT and %qT lacks a cast",
+ t1, t2);
+ break;
+ case CPO_CONDITIONAL_EXPR:
+ error ("conditional expression between distinct "
+ "pointer-to-member types %qT and %qT lacks a cast",
+ t1, t2);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ return error_mark_node;
+ }
+ }
+
+ return composite_pointer_type_r (t1, t2, operation, complain);
+}
+
+/* Return the merged type of two types.
+ We assume that comptypes has already been done and returned 1;
+ if that isn't so, this may crash.
+
+ This just combines attributes and default arguments; any other
+ differences would cause the two types to compare unalike. */
+
+tree
+merge_types (tree t1, tree t2)
+{
+ enum tree_code code1;
+ enum tree_code code2;
+ tree attributes;
+
+ /* Save time if the two types are the same. */
+ if (t1 == t2)
+ return t1;
+ if (original_type (t1) == original_type (t2))
+ return t1;
+
+ /* If one type is nonsense, use the other. */
+ if (t1 == error_mark_node)
+ return t2;
+ if (t2 == error_mark_node)
+ return t1;
+
+ /* Handle merging an auto redeclaration with a previous deduced
+ return type. */
+ if (is_auto (t1))
+ return t2;
+
+ /* Merge the attributes. */
+ attributes = (*targetm.merge_type_attributes) (t1, t2);
+
+ if (TYPE_PTRMEMFUNC_P (t1))
+ t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
+ if (TYPE_PTRMEMFUNC_P (t2))
+ t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
+
+ code1 = TREE_CODE (t1);
+ code2 = TREE_CODE (t2);
+ if (code1 != code2)
+ {
+ gcc_assert (code1 == TYPENAME_TYPE || code2 == TYPENAME_TYPE);
+ if (code1 == TYPENAME_TYPE)
+ {
+ t1 = resolve_typename_type (t1, /*only_current_p=*/true);
+ code1 = TREE_CODE (t1);
+ }
+ else
+ {
+ t2 = resolve_typename_type (t2, /*only_current_p=*/true);
+ code2 = TREE_CODE (t2);
+ }
+ }
+
+ switch (code1)
+ {
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ /* For two pointers, do this recursively on the target type. */
+ {
+ tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
+ int quals = cp_type_quals (t1);
+
+ if (code1 == POINTER_TYPE)
+ t1 = build_pointer_type (target);
+ else
+ t1 = cp_build_reference_type (target, TYPE_REF_IS_RVALUE (t1));
+ t1 = build_type_attribute_variant (t1, attributes);
+ t1 = cp_build_qualified_type (t1, quals);
+
+ if (TREE_CODE (target) == METHOD_TYPE)
+ t1 = build_ptrmemfunc_type (t1);
+
+ return t1;
+ }
+
+ case OFFSET_TYPE:
+ {
+ int quals;
+ tree pointee;
+ quals = cp_type_quals (t1);
+ pointee = merge_types (TYPE_PTRMEM_POINTED_TO_TYPE (t1),
+ TYPE_PTRMEM_POINTED_TO_TYPE (t2));
+ t1 = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
+ pointee);
+ t1 = cp_build_qualified_type (t1, quals);
+ break;
+ }
+
+ case ARRAY_TYPE:
+ {
+ tree elt = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
+ /* Save space: see if the result is identical to one of the args. */
+ if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
+ return build_type_attribute_variant (t1, attributes);
+ if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
+ return build_type_attribute_variant (t2, attributes);
+ /* Merge the element types, and have a size if either arg has one. */
+ t1 = build_cplus_array_type
+ (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
+ break;
+ }
+
+ case FUNCTION_TYPE:
+ /* Function types: prefer the one that specified arg types.
+ If both do, merge the arg types. Also merge the return types. */
+ {
+ tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
+ tree p1 = TYPE_ARG_TYPES (t1);
+ tree p2 = TYPE_ARG_TYPES (t2);
+ tree parms;
+ tree rval, raises;
+
+ /* Save space: see if the result is identical to one of the args. */
+ if (valtype == TREE_TYPE (t1) && ! p2)
+ return cp_build_type_attribute_variant (t1, attributes);
+ if (valtype == TREE_TYPE (t2) && ! p1)
+ return cp_build_type_attribute_variant (t2, attributes);
+
+ /* Simple way if one arg fails to specify argument types. */
+ if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
+ parms = p2;
+ else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
+ parms = p1;
+ else
+ parms = commonparms (p1, p2);
+
+ rval = build_function_type (valtype, parms);
+ gcc_assert (type_memfn_quals (t1) == type_memfn_quals (t2));
+ gcc_assert (type_memfn_rqual (t1) == type_memfn_rqual (t2));
+ rval = apply_memfn_quals (rval,
+ type_memfn_quals (t1),
+ type_memfn_rqual (t1));
+ raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
+ TYPE_RAISES_EXCEPTIONS (t2),
+ NULL_TREE);
+ t1 = build_exception_variant (rval, raises);
+ break;
+ }
+
+ case METHOD_TYPE:
+ {
+ /* Get this value the long way, since TYPE_METHOD_BASETYPE
+ is just the main variant of this. */
+ tree basetype = class_of_this_parm (t2);
+ tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
+ TYPE_RAISES_EXCEPTIONS (t2),
+ NULL_TREE);
+ cp_ref_qualifier rqual = type_memfn_rqual (t1);
+ tree t3;
+
+ /* If this was a member function type, get back to the
+ original type of type member function (i.e., without
+ the class instance variable up front. */
+ t1 = build_function_type (TREE_TYPE (t1),
+ TREE_CHAIN (TYPE_ARG_TYPES (t1)));
+ t2 = build_function_type (TREE_TYPE (t2),
+ TREE_CHAIN (TYPE_ARG_TYPES (t2)));
+ t3 = merge_types (t1, t2);
+ t3 = build_method_type_directly (basetype, TREE_TYPE (t3),
+ TYPE_ARG_TYPES (t3));
+ t1 = build_exception_variant (t3, raises);
+ t1 = build_ref_qualified_type (t1, rqual);
+ break;
+ }
+
+ case TYPENAME_TYPE:
+ /* There is no need to merge attributes into a TYPENAME_TYPE.
+ When the type is instantiated it will have whatever
+ attributes result from the instantiation. */
+ return t1;
+
+ default:;
+ }
+
+ if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes))
+ return t1;
+ else if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes))
+ return t2;
+ else
+ return cp_build_type_attribute_variant (t1, attributes);
+}
+
+/* Return the ARRAY_TYPE type without its domain. */
+
+tree
+strip_array_domain (tree type)
+{
+ tree t2;
+ gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
+ if (TYPE_DOMAIN (type) == NULL_TREE)
+ return type;
+ t2 = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
+ return cp_build_type_attribute_variant (t2, TYPE_ATTRIBUTES (type));
+}
+
+/* Wrapper around cp_common_type that is used by c-common.c and other
+ front end optimizations that remove promotions.
+
+ Return the common type for two arithmetic types T1 and T2 under the
+ usual arithmetic conversions. The default conversions have already
+ been applied, and enumerated types converted to their compatible
+ integer types. */
+
+tree
+common_type (tree t1, tree t2)
+{
+ /* If one type is nonsense, use the other */
+ if (t1 == error_mark_node)
+ return t2;
+ if (t2 == error_mark_node)
+ return t1;
+
+ return cp_common_type (t1, t2);
+}
+
+/* Return the common type of two pointer types T1 and T2. This is the
+ type for the result of most arithmetic operations if the operands
+ have the given two types.
+
+ We assume that comp_target_types has already been done and returned
+ nonzero; if that isn't so, this may crash. */
+
+tree
+common_pointer_type (tree t1, tree t2)
+{
+ gcc_assert ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
+ || (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2))
+ || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)));
+
+ return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
+ CPO_CONVERSION, tf_warning_or_error);
+}
+
+/* Compare two exception specifier types for exactness or subsetness, if
+ allowed. Returns false for mismatch, true for match (same, or
+ derived and !exact).
+
+ [except.spec] "If a class X ... objects of class X or any class publicly
+ and unambiguously derived from X. Similarly, if a pointer type Y * ...
+ exceptions of type Y * or that are pointers to any type publicly and
+ unambiguously derived from Y. Otherwise a function only allows exceptions
+ that have the same type ..."
+ This does not mention cv qualifiers and is different to what throw
+ [except.throw] and catch [except.catch] will do. They will ignore the
+ top level cv qualifiers, and allow qualifiers in the pointer to class
+ example.
+
+ We implement the letter of the standard. */
+
+static bool
+comp_except_types (tree a, tree b, bool exact)
+{
+ if (same_type_p (a, b))
+ return true;
+ else if (!exact)
+ {
+ if (cp_type_quals (a) || cp_type_quals (b))
+ return false;
+
+ if (TYPE_PTR_P (a) && TYPE_PTR_P (b))
+ {
+ a = TREE_TYPE (a);
+ b = TREE_TYPE (b);
+ if (cp_type_quals (a) || cp_type_quals (b))
+ return false;
+ }
+
+ if (TREE_CODE (a) != RECORD_TYPE
+ || TREE_CODE (b) != RECORD_TYPE)
+ return false;
+
+ if (publicly_uniquely_derived_p (a, b))
+ return true;
+ }
+ return false;
+}
+
+/* Return true if TYPE1 and TYPE2 are equivalent exception specifiers.
+ If EXACT is ce_derived, T2 can be stricter than T1 (according to 15.4/5).
+ If EXACT is ce_normal, the compatibility rules in 15.4/3 apply.
+ If EXACT is ce_exact, the specs must be exactly the same. Exception lists
+ are unordered, but we've already filtered out duplicates. Most lists will
+ be in order, we should try to make use of that. */
+
+bool
+comp_except_specs (const_tree t1, const_tree t2, int exact)
+{
+ const_tree probe;
+ const_tree base;
+ int length = 0;
+
+ if (t1 == t2)
+ return true;
+
+ /* First handle noexcept. */
+ if (exact < ce_exact)
+ {
+ /* noexcept(false) is compatible with no exception-specification,
+ and stricter than any spec. */
+ if (t1 == noexcept_false_spec)
+ return t2 == NULL_TREE || exact == ce_derived;
+ /* Even a derived noexcept(false) is compatible with no
+ exception-specification. */
+ if (t2 == noexcept_false_spec)
+ return t1 == NULL_TREE;
+
+ /* Otherwise, if we aren't looking for an exact match, noexcept is
+ equivalent to throw(). */
+ if (t1 == noexcept_true_spec)
+ t1 = empty_except_spec;
+ if (t2 == noexcept_true_spec)
+ t2 = empty_except_spec;
+ }
+
+ /* If any noexcept is left, it is only comparable to itself;
+ either we're looking for an exact match or we're redeclaring a
+ template with dependent noexcept. */
+ if ((t1 && TREE_PURPOSE (t1))
+ || (t2 && TREE_PURPOSE (t2)))
+ return (t1 && t2
+ && cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)));
+
+ if (t1 == NULL_TREE) /* T1 is ... */
+ return t2 == NULL_TREE || exact == ce_derived;
+ if (!TREE_VALUE (t1)) /* t1 is EMPTY */
+ return t2 != NULL_TREE && !TREE_VALUE (t2);
+ if (t2 == NULL_TREE) /* T2 is ... */
+ return false;
+ if (TREE_VALUE (t1) && !TREE_VALUE (t2)) /* T2 is EMPTY, T1 is not */
+ return exact == ce_derived;
+
+ /* Neither set is ... or EMPTY, make sure each part of T2 is in T1.
+ Count how many we find, to determine exactness. For exact matching and
+ ordered T1, T2, this is an O(n) operation, otherwise its worst case is
+ O(nm). */
+ for (base = t1; t2 != NULL_TREE; t2 = TREE_CHAIN (t2))
+ {
+ for (probe = base; probe != NULL_TREE; probe = TREE_CHAIN (probe))
+ {
+ tree a = TREE_VALUE (probe);
+ tree b = TREE_VALUE (t2);
+
+ if (comp_except_types (a, b, exact))
+ {
+ if (probe == base && exact > ce_derived)
+ base = TREE_CHAIN (probe);
+ length++;
+ break;
+ }
+ }
+ if (probe == NULL_TREE)
+ return false;
+ }
+ return exact == ce_derived || base == NULL_TREE || length == list_length (t1);
+}
+
+/* Compare the array types T1 and T2. ALLOW_REDECLARATION is true if
+ [] can match [size]. */
+
+static bool
+comp_array_types (const_tree t1, const_tree t2, bool allow_redeclaration)
+{
+ tree d1;
+ tree d2;
+ tree max1, max2;
+
+ if (t1 == t2)
+ return true;
+
+ /* The type of the array elements must be the same. */
+ if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
+
+ d1 = TYPE_DOMAIN (t1);
+ d2 = TYPE_DOMAIN (t2);
+
+ if (d1 == d2)
+ return true;
+
+ /* If one of the arrays is dimensionless, and the other has a
+ dimension, they are of different types. However, it is valid to
+ write:
+
+ extern int a[];
+ int a[3];
+
+ by [basic.link]:
+
+ declarations for an array object can specify
+ array types that differ by the presence or absence of a major
+ array bound (_dcl.array_). */
+ if (!d1 || !d2)
+ return allow_redeclaration;
+
+ /* Check that the dimensions are the same. */
+
+ if (!cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)))
+ return false;
+ max1 = TYPE_MAX_VALUE (d1);
+ max2 = TYPE_MAX_VALUE (d2);
+ if (processing_template_decl && !abi_version_at_least (2)
+ && !value_dependent_expression_p (max1)
+ && !value_dependent_expression_p (max2))
+ {
+ /* With abi-1 we do not fold non-dependent array bounds, (and
+ consequently mangle them incorrectly). We must therefore
+ fold them here, to verify the domains have the same
+ value. */
+ max1 = fold (max1);
+ max2 = fold (max2);
+ }
+
+ if (!cp_tree_equal (max1, max2))
+ return false;
+
+ return true;
+}
+
+/* Compare the relative position of T1 and T2 into their respective
+ template parameter list.
+ T1 and T2 must be template parameter types.
+ Return TRUE if T1 and T2 have the same position, FALSE otherwise. */
+
+static bool
+comp_template_parms_position (tree t1, tree t2)
+{
+ tree index1, index2;
+ gcc_assert (t1 && t2
+ && TREE_CODE (t1) == TREE_CODE (t2)
+ && (TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (t1) == TEMPLATE_TYPE_PARM));
+
+ index1 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t1));
+ index2 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t2));
+
+ /* Then compare their relative position. */
+ if (TEMPLATE_PARM_IDX (index1) != TEMPLATE_PARM_IDX (index2)
+ || TEMPLATE_PARM_LEVEL (index1) != TEMPLATE_PARM_LEVEL (index2)
+ || (TEMPLATE_PARM_PARAMETER_PACK (index1)
+ != TEMPLATE_PARM_PARAMETER_PACK (index2)))
+ return false;
+
+ /* In C++14 we can end up comparing 'auto' to a normal template
+ parameter. Don't confuse them. */
+ if (cxx_dialect >= cxx1y && (is_auto (t1) || is_auto (t2)))
+ return TYPE_IDENTIFIER (t1) == TYPE_IDENTIFIER (t2);
+
+ return true;
+}
+
+/* Subroutine in comptypes. */
+
+static bool
+structural_comptypes (tree t1, tree t2, int strict)
+{
+ if (t1 == t2)
+ return true;
+
+ /* Suppress errors caused by previously reported errors. */
+ if (t1 == error_mark_node || t2 == error_mark_node)
+ return false;
+
+ gcc_assert (TYPE_P (t1) && TYPE_P (t2));
+
+ /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
+ current instantiation. */
+ if (TREE_CODE (t1) == TYPENAME_TYPE)
+ t1 = resolve_typename_type (t1, /*only_current_p=*/true);
+
+ if (TREE_CODE (t2) == TYPENAME_TYPE)
+ t2 = resolve_typename_type (t2, /*only_current_p=*/true);
+
+ if (TYPE_PTRMEMFUNC_P (t1))
+ t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
+ if (TYPE_PTRMEMFUNC_P (t2))
+ t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
+
+ /* Different classes of types can't be compatible. */
+ if (TREE_CODE (t1) != TREE_CODE (t2))
+ return false;
+
+ /* Qualifiers must match. For array types, we will check when we
+ recur on the array element types. */
+ if (TREE_CODE (t1) != ARRAY_TYPE
+ && cp_type_quals (t1) != cp_type_quals (t2))
+ return false;
+ if (TREE_CODE (t1) == FUNCTION_TYPE
+ && type_memfn_quals (t1) != type_memfn_quals (t2))
+ return false;
+ /* Need to check this before TYPE_MAIN_VARIANT.
+ FIXME function qualifiers should really change the main variant. */
+ if ((TREE_CODE (t1) == FUNCTION_TYPE
+ || TREE_CODE (t1) == METHOD_TYPE)
+ && type_memfn_rqual (t1) != type_memfn_rqual (t2))
+ return false;
+ if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
+ return false;
+
+ /* Allow for two different type nodes which have essentially the same
+ definition. Note that we already checked for equality of the type
+ qualifiers (just above). */
+
+ if (TREE_CODE (t1) != ARRAY_TYPE
+ && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
+ return true;
+
+
+ /* Compare the types. Break out if they could be the same. */
+ switch (TREE_CODE (t1))
+ {
+ case VOID_TYPE:
+ case BOOLEAN_TYPE:
+ /* All void and bool types are the same. */
+ break;
+
+ case INTEGER_TYPE:
+ case FIXED_POINT_TYPE:
+ case REAL_TYPE:
+ /* With these nodes, we can't determine type equivalence by
+ looking at what is stored in the nodes themselves, because
+ two nodes might have different TYPE_MAIN_VARIANTs but still
+ represent the same type. For example, wchar_t and int could
+ have the same properties (TYPE_PRECISION, TYPE_MIN_VALUE,
+ TYPE_MAX_VALUE, etc.), but have different TYPE_MAIN_VARIANTs
+ and are distinct types. On the other hand, int and the
+ following typedef
+
+ typedef int INT __attribute((may_alias));
+
+ have identical properties, different TYPE_MAIN_VARIANTs, but
+ represent the same type. The canonical type system keeps
+ track of equivalence in this case, so we fall back on it. */
+ return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
+
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ if (!comp_template_parms_position (t1, t2))
+ return false;
+ if (!comp_template_parms
+ (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
+ DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
+ return false;
+ if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
+ break;
+ /* Don't check inheritance. */
+ strict = COMPARE_STRICT;
+ /* Fall through. */
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
+ && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
+ || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ && comp_template_args (TYPE_TI_ARGS (t1), TYPE_TI_ARGS (t2)))
+ break;
+
+ if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
+ break;
+ else if ((strict & COMPARE_DERIVED) && DERIVED_FROM_P (t2, t1))
+ break;
+
+ return false;
+
+ case OFFSET_TYPE:
+ if (!comptypes (TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2),
+ strict & ~COMPARE_REDECLARATION))
+ return false;
+ if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
+ break;
+
+ case REFERENCE_TYPE:
+ if (TYPE_REF_IS_RVALUE (t1) != TYPE_REF_IS_RVALUE (t2))
+ return false;
+ /* fall through to checks for pointer types */
+
+ case POINTER_TYPE:
+ if (TYPE_MODE (t1) != TYPE_MODE (t2)
+ || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2)
+ || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
+ break;
+
+ case METHOD_TYPE:
+ case FUNCTION_TYPE:
+ if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
+ if (!compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)))
+ return false;
+ break;
+
+ case ARRAY_TYPE:
+ /* Target types must match incl. qualifiers. */
+ if (!comp_array_types (t1, t2, !!(strict & COMPARE_REDECLARATION)))
+ return false;
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ /* If T1 and T2 don't have the same relative position in their
+ template parameters set, they can't be equal. */
+ if (!comp_template_parms_position (t1, t2))
+ return false;
+ break;
+
+ case TYPENAME_TYPE:
+ if (!cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
+ TYPENAME_TYPE_FULLNAME (t2)))
+ return false;
+ /* Qualifiers don't matter on scopes. */
+ if (!same_type_ignoring_top_level_qualifiers_p (TYPE_CONTEXT (t1),
+ TYPE_CONTEXT (t2)))
+ return false;
+ break;
+
+ case UNBOUND_CLASS_TEMPLATE:
+ if (!cp_tree_equal (TYPE_IDENTIFIER (t1), TYPE_IDENTIFIER (t2)))
+ return false;
+ if (!same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)))
+ return false;
+ break;
+
+ case COMPLEX_TYPE:
+ if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
+ break;
+
+ case VECTOR_TYPE:
+ if (TYPE_VECTOR_SUBPARTS (t1) != TYPE_VECTOR_SUBPARTS (t2)
+ || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
+ break;
+
+ case TYPE_PACK_EXPANSION:
+ return (same_type_p (PACK_EXPANSION_PATTERN (t1),
+ PACK_EXPANSION_PATTERN (t2))
+ && comp_template_args (PACK_EXPANSION_EXTRA_ARGS (t1),
+ PACK_EXPANSION_EXTRA_ARGS (t2)));
+
+ case DECLTYPE_TYPE:
+ if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t1)
+ != DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t2)
+ || (DECLTYPE_FOR_LAMBDA_CAPTURE (t1)
+ != DECLTYPE_FOR_LAMBDA_CAPTURE (t2))
+ || (DECLTYPE_FOR_LAMBDA_PROXY (t1)
+ != DECLTYPE_FOR_LAMBDA_PROXY (t2))
+ || !cp_tree_equal (DECLTYPE_TYPE_EXPR (t1),
+ DECLTYPE_TYPE_EXPR (t2)))
+ return false;
+ break;
+
+ case UNDERLYING_TYPE:
+ return same_type_p (UNDERLYING_TYPE_TYPE (t1),
+ UNDERLYING_TYPE_TYPE (t2));
+
+ default:
+ return false;
+ }
+
+ /* If we get here, we know that from a target independent POV the
+ types are the same. Make sure the target attributes are also
+ the same. */
+ return comp_type_attributes (t1, t2);
+}
+
+/* Return true if T1 and T2 are related as allowed by STRICT. STRICT
+ is a bitwise-or of the COMPARE_* flags. */
+
+bool
+comptypes (tree t1, tree t2, int strict)
+{
+ if (strict == COMPARE_STRICT)
+ {
+ if (t1 == t2)
+ return true;
+
+ if (t1 == error_mark_node || t2 == error_mark_node)
+ return false;
+
+ if (TYPE_STRUCTURAL_EQUALITY_P (t1) || TYPE_STRUCTURAL_EQUALITY_P (t2))
+ /* At least one of the types requires structural equality, so
+ perform a deep check. */
+ return structural_comptypes (t1, t2, strict);
+
+#ifdef ENABLE_CHECKING
+ if (USE_CANONICAL_TYPES)
+ {
+ bool result = structural_comptypes (t1, t2, strict);
+
+ if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
+ /* The two types are structurally equivalent, but their
+ canonical types were different. This is a failure of the
+ canonical type propagation code.*/
+ internal_error
+ ("canonical types differ for identical types %T and %T",
+ t1, t2);
+ else if (!result && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2))
+ /* Two types are structurally different, but the canonical
+ types are the same. This means we were over-eager in
+ assigning canonical types. */
+ internal_error
+ ("same canonical type node for different types %T and %T",
+ t1, t2);
+
+ return result;
+ }
+#else
+ if (USE_CANONICAL_TYPES)
+ return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
+#endif
+ else
+ return structural_comptypes (t1, t2, strict);
+ }
+ else if (strict == COMPARE_STRUCTURAL)
+ return structural_comptypes (t1, t2, COMPARE_STRICT);
+ else
+ return structural_comptypes (t1, t2, strict);
+}
+
+/* Returns nonzero iff TYPE1 and TYPE2 are the same type, ignoring
+ top-level qualifiers. */
+
+bool
+same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2)
+{
+ if (type1 == error_mark_node || type2 == error_mark_node)
+ return false;
+
+ return same_type_p (TYPE_MAIN_VARIANT (type1), TYPE_MAIN_VARIANT (type2));
+}
+
+/* Returns 1 if TYPE1 is at least as qualified as TYPE2. */
+
+bool
+at_least_as_qualified_p (const_tree type1, const_tree type2)
+{
+ int q1 = cp_type_quals (type1);
+ int q2 = cp_type_quals (type2);
+
+ /* All qualifiers for TYPE2 must also appear in TYPE1. */
+ return (q1 & q2) == q2;
+}
+
+/* Returns 1 if TYPE1 is more cv-qualified than TYPE2, -1 if TYPE2 is
+ more cv-qualified that TYPE1, and 0 otherwise. */
+
+int
+comp_cv_qualification (const_tree type1, const_tree type2)
+{
+ int q1 = cp_type_quals (type1);
+ int q2 = cp_type_quals (type2);
+
+ if (q1 == q2)
+ return 0;
+
+ if ((q1 & q2) == q2)
+ return 1;
+ else if ((q1 & q2) == q1)
+ return -1;
+
+ return 0;
+}
+
+/* Returns 1 if the cv-qualification signature of TYPE1 is a proper
+ subset of the cv-qualification signature of TYPE2, and the types
+ are similar. Returns -1 if the other way 'round, and 0 otherwise. */
+
+int
+comp_cv_qual_signature (tree type1, tree type2)
+{
+ if (comp_ptr_ttypes_real (type2, type1, -1))
+ return 1;
+ else if (comp_ptr_ttypes_real (type1, type2, -1))
+ return -1;
+ else
+ return 0;
+}
+
+/* Subroutines of `comptypes'. */
+
+/* Return true if two parameter type lists PARMS1 and PARMS2 are
+ equivalent in the sense that functions with those parameter types
+ can have equivalent types. The two lists must be equivalent,
+ element by element. */
+
+bool
+compparms (const_tree parms1, const_tree parms2)
+{
+ const_tree t1, t2;
+
+ /* An unspecified parmlist matches any specified parmlist
+ whose argument types don't need default promotions. */
+
+ for (t1 = parms1, t2 = parms2;
+ t1 || t2;
+ t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
+ {
+ /* If one parmlist is shorter than the other,
+ they fail to match. */
+ if (!t1 || !t2)
+ return false;
+ if (!same_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
+ return false;
+ }
+ return true;
+}
+
+
+/* Process a sizeof or alignof expression where the operand is a
+ type. */
+
+tree
+cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
+{
+ tree value;
+ bool dependent_p;
+
+ gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ type = non_reference (type);
+ if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ if (complain)
+ pedwarn (input_location, OPT_Wpointer_arith,
+ "invalid application of %qs to a member function",
+ operator_name_info[(int) op].name);
+ value = size_one_node;
+ }
+
+ dependent_p = dependent_type_p (type);
+ if (!dependent_p)
+ complete_type (type);
+ if (dependent_p
+ /* VLA types will have a non-constant size. In the body of an
+ uninstantiated template, we don't need to try to compute the
+ value, because the sizeof expression is not an integral
+ constant expression in that case. And, if we do try to
+ compute the value, we'll likely end up with SAVE_EXPRs, which
+ the template substitution machinery does not expect to see. */
+ || (processing_template_decl
+ && COMPLETE_TYPE_P (type)
+ && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
+ {
+ value = build_min (op, size_type_node, type);
+ TREE_READONLY (value) = 1;
+ return value;
+ }
+
+ if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type)
+ && (flag_iso || warn_vla > 0))
+ {
+ if (complain & tf_warning_or_error)
+ pedwarn (input_location, OPT_Wvla,
+ "taking sizeof array of runtime bound");
+ else
+ return error_mark_node;
+ }
+
+ return c_sizeof_or_alignof_type (input_location, complete_type (type),
+ op == SIZEOF_EXPR, false,
+ complain);
+}
+
+/* Return the size of the type, without producing any warnings for
+ types whose size cannot be taken. This routine should be used only
+ in some other routine that has already produced a diagnostic about
+ using the size of such a type. */
+tree
+cxx_sizeof_nowarn (tree type)
+{
+ if (TREE_CODE (type) == FUNCTION_TYPE
+ || VOID_TYPE_P (type)
+ || TREE_CODE (type) == ERROR_MARK)
+ return size_one_node;
+ else if (!COMPLETE_TYPE_P (type))
+ return size_zero_node;
+ else
+ return cxx_sizeof_or_alignof_type (type, SIZEOF_EXPR, false);
+}
+
+/* Process a sizeof expression where the operand is an expression. */
+
+static tree
+cxx_sizeof_expr (tree e, tsubst_flags_t complain)
+{
+ if (e == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ e = build_min (SIZEOF_EXPR, size_type_node, e);
+ TREE_SIDE_EFFECTS (e) = 0;
+ TREE_READONLY (e) = 1;
+
+ return e;
+ }
+
+ /* To get the size of a static data member declared as an array of
+ unknown bound, we need to instantiate it. */
+ if (VAR_P (e)
+ && VAR_HAD_UNKNOWN_BOUND (e)
+ && DECL_TEMPLATE_INSTANTIATION (e))
+ instantiate_decl (e, /*defer_ok*/true, /*expl_inst_mem*/false);
+
+ e = mark_type_use (e);
+
+ if (TREE_CODE (e) == COMPONENT_REF
+ && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
+ && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
+ {
+ if (complain & tf_error)
+ error ("invalid application of %<sizeof%> to a bit-field");
+ else
+ return error_mark_node;
+ e = char_type_node;
+ }
+ else if (is_overloaded_fn (e))
+ {
+ if (complain & tf_error)
+ permerror (input_location, "ISO C++ forbids applying %<sizeof%> to an expression of "
+ "function type");
+ else
+ return error_mark_node;
+ e = char_type_node;
+ }
+ else if (type_unknown_p (e))
+ {
+ if (complain & tf_error)
+ cxx_incomplete_type_error (e, TREE_TYPE (e));
+ else
+ return error_mark_node;
+ e = char_type_node;
+ }
+ else
+ e = TREE_TYPE (e);
+
+ return cxx_sizeof_or_alignof_type (e, SIZEOF_EXPR, complain & tf_error);
+}
+
+/* Implement the __alignof keyword: Return the minimum required
+ alignment of E, measured in bytes. For VAR_DECL's and
+ FIELD_DECL's return DECL_ALIGN (which can be set from an
+ "aligned" __attribute__ specification). */
+
+static tree
+cxx_alignof_expr (tree e, tsubst_flags_t complain)
+{
+ tree t;
+
+ if (e == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ e = build_min (ALIGNOF_EXPR, size_type_node, e);
+ TREE_SIDE_EFFECTS (e) = 0;
+ TREE_READONLY (e) = 1;
+
+ return e;
+ }
+
+ e = mark_type_use (e);
+
+ if (VAR_P (e))
+ t = size_int (DECL_ALIGN_UNIT (e));
+ else if (TREE_CODE (e) == COMPONENT_REF
+ && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
+ && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
+ {
+ if (complain & tf_error)
+ error ("invalid application of %<__alignof%> to a bit-field");
+ else
+ return error_mark_node;
+ t = size_one_node;
+ }
+ else if (TREE_CODE (e) == COMPONENT_REF
+ && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL)
+ t = size_int (DECL_ALIGN_UNIT (TREE_OPERAND (e, 1)));
+ else if (is_overloaded_fn (e))
+ {
+ if (complain & tf_error)
+ permerror (input_location, "ISO C++ forbids applying %<__alignof%> to an expression of "
+ "function type");
+ else
+ return error_mark_node;
+ if (TREE_CODE (e) == FUNCTION_DECL)
+ t = size_int (DECL_ALIGN_UNIT (e));
+ else
+ t = size_one_node;
+ }
+ else if (type_unknown_p (e))
+ {
+ if (complain & tf_error)
+ cxx_incomplete_type_error (e, TREE_TYPE (e));
+ else
+ return error_mark_node;
+ t = size_one_node;
+ }
+ else
+ return cxx_sizeof_or_alignof_type (TREE_TYPE (e), ALIGNOF_EXPR,
+ complain & tf_error);
+
+ return fold_convert (size_type_node, t);
+}
+
+/* Process a sizeof or alignof expression E with code OP where the operand
+ is an expression. */
+
+tree
+cxx_sizeof_or_alignof_expr (tree e, enum tree_code op, bool complain)
+{
+ if (op == SIZEOF_EXPR)
+ return cxx_sizeof_expr (e, complain? tf_warning_or_error : tf_none);
+ else
+ return cxx_alignof_expr (e, complain? tf_warning_or_error : tf_none);
+}
+
+/* Build a representation of an expression 'alignas(E).' Return the
+ folded integer value of E if it is an integral constant expression
+ that resolves to a valid alignment. If E depends on a template
+ parameter, return a syntactic representation tree of kind
+ ALIGNOF_EXPR. Otherwise, return an error_mark_node if the
+ expression is ill formed, or NULL_TREE if E is NULL_TREE. */
+
+tree
+cxx_alignas_expr (tree e)
+{
+ if (e == NULL_TREE || e == error_mark_node
+ || (!TYPE_P (e) && !require_potential_rvalue_constant_expression (e)))
+ return e;
+
+ if (TYPE_P (e))
+ /* [dcl.align]/3:
+
+ When the alignment-specifier is of the form
+ alignas(type-id ), it shall have the same effect as
+ alignas(alignof(type-id )). */
+
+ return cxx_sizeof_or_alignof_type (e, ALIGNOF_EXPR, false);
+
+ /* If we reach this point, it means the alignas expression if of
+ the form "alignas(assignment-expression)", so we should follow
+ what is stated by [dcl.align]/2. */
+
+ if (value_dependent_expression_p (e))
+ /* Leave value-dependent expression alone for now. */
+ return e;
+
+ e = fold_non_dependent_expr (e);
+ e = mark_rvalue_use (e);
+
+ /* [dcl.align]/2 says:
+
+ the assignment-expression shall be an integral constant
+ expression. */
+
+ return cxx_constant_value (e);
+}
+
+
+/* EXPR is being used in a context that is not a function call.
+ Enforce:
+
+ [expr.ref]
+
+ The expression can be used only as the left-hand operand of a
+ member function call.
+
+ [expr.mptr.operator]
+
+ If the result of .* or ->* is a function, then that result can be
+ used only as the operand for the function call operator ().
+
+ by issuing an error message if appropriate. Returns true iff EXPR
+ violates these rules. */
+
+bool
+invalid_nonstatic_memfn_p (tree expr, tsubst_flags_t complain)
+{
+ if (expr == NULL_TREE)
+ return false;
+ /* Don't enforce this in MS mode. */
+ if (flag_ms_extensions)
+ return false;
+ if (is_overloaded_fn (expr) && !really_overloaded_fn (expr))
+ expr = get_first_fn (expr);
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (expr))
+ {
+ if (complain & tf_error)
+ error ("invalid use of non-static member function");
+ return true;
+ }
+ return false;
+}
+
+/* If EXP is a reference to a bitfield, and the type of EXP does not
+ match the declared type of the bitfield, return the declared type
+ of the bitfield. Otherwise, return NULL_TREE. */
+
+tree
+is_bitfield_expr_with_lowered_type (const_tree exp)
+{
+ switch (TREE_CODE (exp))
+ {
+ case COND_EXPR:
+ if (!is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1)
+ ? TREE_OPERAND (exp, 1)
+ : TREE_OPERAND (exp, 0)))
+ return NULL_TREE;
+ return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 2));
+
+ case COMPOUND_EXPR:
+ return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1));
+
+ case MODIFY_EXPR:
+ case SAVE_EXPR:
+ return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
+
+ case COMPONENT_REF:
+ {
+ tree field;
+
+ field = TREE_OPERAND (exp, 1);
+ if (TREE_CODE (field) != FIELD_DECL || !DECL_BIT_FIELD_TYPE (field))
+ return NULL_TREE;
+ if (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (exp), DECL_BIT_FIELD_TYPE (field)))
+ return NULL_TREE;
+ return DECL_BIT_FIELD_TYPE (field);
+ }
+
+ CASE_CONVERT:
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (exp, 0)))
+ == TYPE_MAIN_VARIANT (TREE_TYPE (exp)))
+ return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
+ /* Fallthrough. */
+
+ default:
+ return NULL_TREE;
+ }
+}
+
+/* Like is_bitfield_with_lowered_type, except that if EXP is not a
+ bitfield with a lowered type, the type of EXP is returned, rather
+ than NULL_TREE. */
+
+tree
+unlowered_expr_type (const_tree exp)
+{
+ tree type;
+ tree etype = TREE_TYPE (exp);
+
+ type = is_bitfield_expr_with_lowered_type (exp);
+ if (type)
+ type = cp_build_qualified_type (type, cp_type_quals (etype));
+ else
+ type = etype;
+
+ return type;
+}
+
+/* Perform the conversions in [expr] that apply when an lvalue appears
+ in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
+ function-to-pointer conversions. In addition, manifest constants
+ are replaced by their values, and bitfield references are converted
+ to their declared types. Note that this function does not perform the
+ lvalue-to-rvalue conversion for class types. If you need that conversion
+ to for class types, then you probably need to use force_rvalue.
+
+ Although the returned value is being used as an rvalue, this
+ function does not wrap the returned expression in a
+ NON_LVALUE_EXPR; the caller is expected to be mindful of the fact
+ that the return value is no longer an lvalue. */
+
+tree
+decay_conversion (tree exp, tsubst_flags_t complain)
+{
+ tree type;
+ enum tree_code code;
+ location_t loc = EXPR_LOC_OR_LOC (exp, input_location);
+
+ type = TREE_TYPE (exp);
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ exp = mark_rvalue_use (exp);
+
+ exp = resolve_nondeduced_context (exp);
+ if (type_unknown_p (exp))
+ {
+ if (complain & tf_error)
+ cxx_incomplete_type_error (exp, TREE_TYPE (exp));
+ return error_mark_node;
+ }
+
+ code = TREE_CODE (type);
+
+ /* For an array decl decay_conversion should not try to return its
+ initializer. */
+ if (code != ARRAY_TYPE)
+ {
+ /* FIXME remove? at least need to remember that this isn't really a
+ constant expression if EXP isn't decl_constant_var_p, like with
+ C_MAYBE_CONST_EXPR. */
+ exp = decl_constant_value_safe (exp);
+ if (error_operand_p (exp))
+ return error_mark_node;
+ }
+
+ if (NULLPTR_TYPE_P (type) && !TREE_SIDE_EFFECTS (exp))
+ return nullptr_node;
+
+ /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
+ Leave such NOP_EXPRs, since RHS is being used in non-lvalue context. */
+ if (code == VOID_TYPE)
+ {
+ if (complain & tf_error)
+ error_at (loc, "void value not ignored as it ought to be");
+ return error_mark_node;
+ }
+ if (invalid_nonstatic_memfn_p (exp, complain))
+ return error_mark_node;
+ if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
+ return cp_build_addr_expr (exp, complain);
+ if (code == ARRAY_TYPE)
+ {
+ tree adr;
+ tree ptrtype;
+
+ if (INDIRECT_REF_P (exp))
+ return build_nop (build_pointer_type (TREE_TYPE (type)),
+ TREE_OPERAND (exp, 0));
+
+ if (TREE_CODE (exp) == COMPOUND_EXPR)
+ {
+ tree op1 = decay_conversion (TREE_OPERAND (exp, 1), complain);
+ if (op1 == error_mark_node)
+ return error_mark_node;
+ return build2 (COMPOUND_EXPR, TREE_TYPE (op1),
+ TREE_OPERAND (exp, 0), op1);
+ }
+
+ if (!lvalue_p (exp)
+ && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))
+ {
+ if (complain & tf_error)
+ error_at (loc, "invalid use of non-lvalue array");
+ return error_mark_node;
+ }
+
+ /* Don't let an array compound literal decay to a pointer. It can
+ still be used to initialize an array or bind to a reference. */
+ if (TREE_CODE (exp) == TARGET_EXPR)
+ {
+ if (complain & tf_error)
+ error_at (loc, "taking address of temporary array");
+ return error_mark_node;
+ }
+
+ ptrtype = build_pointer_type (TREE_TYPE (type));
+
+ if (VAR_P (exp))
+ {
+ if (!cxx_mark_addressable (exp))
+ return error_mark_node;
+ adr = build_nop (ptrtype, build_address (exp));
+ return adr;
+ }
+ /* This way is better for a COMPONENT_REF since it can
+ simplify the offset for a component. */
+ adr = cp_build_addr_expr (exp, complain);
+ return cp_convert (ptrtype, adr, complain);
+ }
+
+ /* If a bitfield is used in a context where integral promotion
+ applies, then the caller is expected to have used
+ default_conversion. That function promotes bitfields correctly
+ before calling this function. At this point, if we have a
+ bitfield referenced, we may assume that is not subject to
+ promotion, and that, therefore, the type of the resulting rvalue
+ is the declared type of the bitfield. */
+ exp = convert_bitfield_to_declared_type (exp);
+
+ /* We do not call rvalue() here because we do not want to wrap EXP
+ in a NON_LVALUE_EXPR. */
+
+ /* [basic.lval]
+
+ Non-class rvalues always have cv-unqualified types. */
+ type = TREE_TYPE (exp);
+ if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
+ exp = build_nop (cv_unqualified (type), exp);
+
+ return exp;
+}
+
+/* Perform preparatory conversions, as part of the "usual arithmetic
+ conversions". In particular, as per [expr]:
+
+ Whenever an lvalue expression appears as an operand of an
+ operator that expects the rvalue for that operand, the
+ lvalue-to-rvalue, array-to-pointer, or function-to-pointer
+ standard conversions are applied to convert the expression to an
+ rvalue.
+
+ In addition, we perform integral promotions here, as those are
+ applied to both operands to a binary operator before determining
+ what additional conversions should apply. */
+
+static tree
+cp_default_conversion (tree exp, tsubst_flags_t complain)
+{
+ /* Check for target-specific promotions. */
+ tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
+ if (promoted_type)
+ exp = cp_convert (promoted_type, exp, complain);
+ /* Perform the integral promotions first so that bitfield
+ expressions (which may promote to "int", even if the bitfield is
+ declared "unsigned") are promoted correctly. */
+ else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
+ exp = cp_perform_integral_promotions (exp, complain);
+ /* Perform the other conversions. */
+ exp = decay_conversion (exp, complain);
+
+ return exp;
+}
+
+/* C version. */
+
+tree
+default_conversion (tree exp)
+{
+ return cp_default_conversion (exp, tf_warning_or_error);
+}
+
+/* EXPR is an expression with an integral or enumeration type.
+ Perform the integral promotions in [conv.prom], and return the
+ converted value. */
+
+tree
+cp_perform_integral_promotions (tree expr, tsubst_flags_t complain)
+{
+ tree type;
+ tree promoted_type;
+
+ expr = mark_rvalue_use (expr);
+
+ /* [conv.prom]
+
+ If the bitfield has an enumerated type, it is treated as any
+ other value of that type for promotion purposes. */
+ type = is_bitfield_expr_with_lowered_type (expr);
+ if (!type || TREE_CODE (type) != ENUMERAL_TYPE)
+ type = TREE_TYPE (expr);
+ gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
+ /* Scoped enums don't promote. */
+ if (SCOPED_ENUM_P (type))
+ return expr;
+ promoted_type = type_promotes_to (type);
+ if (type != promoted_type)
+ expr = cp_convert (promoted_type, expr, complain);
+ return expr;
+}
+
+/* C version. */
+
+tree
+perform_integral_promotions (tree expr)
+{
+ return cp_perform_integral_promotions (expr, tf_warning_or_error);
+}
+
+/* Returns nonzero iff exp is a STRING_CST or the result of applying
+ decay_conversion to one. */
+
+int
+string_conv_p (const_tree totype, const_tree exp, int warn)
+{
+ tree t;
+
+ if (!TYPE_PTR_P (totype))
+ return 0;
+
+ t = TREE_TYPE (totype);
+ if (!same_type_p (t, char_type_node)
+ && !same_type_p (t, char16_type_node)
+ && !same_type_p (t, char32_type_node)
+ && !same_type_p (t, wchar_type_node))
+ return 0;
+
+ if (TREE_CODE (exp) == STRING_CST)
+ {
+ /* Make sure that we don't try to convert between char and wide chars. */
+ if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (exp))), t))
+ return 0;
+ }
+ else
+ {
+ /* Is this a string constant which has decayed to 'const char *'? */
+ t = build_pointer_type (cp_build_qualified_type (t, TYPE_QUAL_CONST));
+ if (!same_type_p (TREE_TYPE (exp), t))
+ return 0;
+ STRIP_NOPS (exp);
+ if (TREE_CODE (exp) != ADDR_EXPR
+ || TREE_CODE (TREE_OPERAND (exp, 0)) != STRING_CST)
+ return 0;
+ }
+
+ /* This warning is not very useful, as it complains about printf. */
+ if (warn)
+ warning (OPT_Wwrite_strings,
+ "deprecated conversion from string constant to %qT",
+ totype);
+
+ return 1;
+}
+
+/* Given a COND_EXPR, MIN_EXPR, or MAX_EXPR in T, return it in a form that we
+ can, for example, use as an lvalue. This code used to be in
+ unary_complex_lvalue, but we needed it to deal with `a = (d == c) ? b : c'
+ expressions, where we're dealing with aggregates. But now it's again only
+ called from unary_complex_lvalue. The case (in particular) that led to
+ this was with CODE == ADDR_EXPR, since it's not an lvalue when we'd
+ get it there. */
+
+static tree
+rationalize_conditional_expr (enum tree_code code, tree t,
+ tsubst_flags_t complain)
+{
+ location_t loc = EXPR_LOC_OR_LOC (t, input_location);
+
+ /* For MIN_EXPR or MAX_EXPR, fold-const.c has arranged things so that
+ the first operand is always the one to be used if both operands
+ are equal, so we know what conditional expression this used to be. */
+ if (TREE_CODE (t) == MIN_EXPR || TREE_CODE (t) == MAX_EXPR)
+ {
+ tree op0 = TREE_OPERAND (t, 0);
+ tree op1 = TREE_OPERAND (t, 1);
+
+ /* The following code is incorrect if either operand side-effects. */
+ gcc_assert (!TREE_SIDE_EFFECTS (op0)
+ && !TREE_SIDE_EFFECTS (op1));
+ return
+ build_conditional_expr (loc,
+ build_x_binary_op (loc,
+ (TREE_CODE (t) == MIN_EXPR
+ ? LE_EXPR : GE_EXPR),
+ op0, TREE_CODE (op0),
+ op1, TREE_CODE (op1),
+ /*overload=*/NULL,
+ complain),
+ cp_build_unary_op (code, op0, 0, complain),
+ cp_build_unary_op (code, op1, 0, complain),
+ complain);
+ }
+
+ return
+ build_conditional_expr (loc, TREE_OPERAND (t, 0),
+ cp_build_unary_op (code, TREE_OPERAND (t, 1), 0,
+ complain),
+ cp_build_unary_op (code, TREE_OPERAND (t, 2), 0,
+ complain),
+ complain);
+}
+
+/* Given the TYPE of an anonymous union field inside T, return the
+ FIELD_DECL for the field. If not found return NULL_TREE. Because
+ anonymous unions can nest, we must also search all anonymous unions
+ that are directly reachable. */
+
+tree
+lookup_anon_field (tree t, tree type)
+{
+ tree field;
+
+ for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
+ {
+ if (TREE_STATIC (field))
+ continue;
+ if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
+ continue;
+
+ /* If we find it directly, return the field. */
+ if (DECL_NAME (field) == NULL_TREE
+ && type == TYPE_MAIN_VARIANT (TREE_TYPE (field)))
+ {
+ return field;
+ }
+
+ /* Otherwise, it could be nested, search harder. */
+ if (DECL_NAME (field) == NULL_TREE
+ && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
+ {
+ tree subfield = lookup_anon_field (TREE_TYPE (field), type);
+ if (subfield)
+ return subfield;
+ }
+ }
+ return NULL_TREE;
+}
+
+/* Build an expression representing OBJECT.MEMBER. OBJECT is an
+ expression; MEMBER is a DECL or baselink. If ACCESS_PATH is
+ non-NULL, it indicates the path to the base used to name MEMBER.
+ If PRESERVE_REFERENCE is true, the expression returned will have
+ REFERENCE_TYPE if the MEMBER does. Otherwise, the expression
+ returned will have the type referred to by the reference.
+
+ This function does not perform access control; that is either done
+ earlier by the parser when the name of MEMBER is resolved to MEMBER
+ itself, or later when overload resolution selects one of the
+ functions indicated by MEMBER. */
+
+tree
+build_class_member_access_expr (tree object, tree member,
+ tree access_path, bool preserve_reference,
+ tsubst_flags_t complain)
+{
+ tree object_type;
+ tree member_scope;
+ tree result = NULL_TREE;
+ tree using_decl = NULL_TREE;
+
+ if (error_operand_p (object) || error_operand_p (member))
+ return error_mark_node;
+
+ gcc_assert (DECL_P (member) || BASELINK_P (member));
+
+ /* [expr.ref]
+
+ The type of the first expression shall be "class object" (of a
+ complete type). */
+ object_type = TREE_TYPE (object);
+ if (!currently_open_class (object_type)
+ && !complete_type_or_maybe_complain (object_type, object, complain))
+ return error_mark_node;
+ if (!CLASS_TYPE_P (object_type))
+ {
+ if (complain & tf_error)
+ {
+ if (POINTER_TYPE_P (object_type)
+ && CLASS_TYPE_P (TREE_TYPE (object_type)))
+ error ("request for member %qD in %qE, which is of pointer "
+ "type %qT (maybe you meant to use %<->%> ?)",
+ member, object, object_type);
+ else
+ error ("request for member %qD in %qE, which is of non-class "
+ "type %qT", member, object, object_type);
+ }
+ return error_mark_node;
+ }
+
+ /* The standard does not seem to actually say that MEMBER must be a
+ member of OBJECT_TYPE. However, that is clearly what is
+ intended. */
+ if (DECL_P (member))
+ {
+ member_scope = DECL_CLASS_CONTEXT (member);
+ mark_used (member);
+ if (TREE_DEPRECATED (member))
+ warn_deprecated_use (member, NULL_TREE);
+ }
+ else
+ member_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (member));
+ /* If MEMBER is from an anonymous aggregate, MEMBER_SCOPE will
+ presently be the anonymous union. Go outwards until we find a
+ type related to OBJECT_TYPE. */
+ while ((ANON_AGGR_TYPE_P (member_scope) || UNSCOPED_ENUM_P (member_scope))
+ && !same_type_ignoring_top_level_qualifiers_p (member_scope,
+ object_type))
+ member_scope = TYPE_CONTEXT (member_scope);
+ if (!member_scope || !DERIVED_FROM_P (member_scope, object_type))
+ {
+ if (complain & tf_error)
+ {
+ if (TREE_CODE (member) == FIELD_DECL)
+ error ("invalid use of nonstatic data member %qE", member);
+ else
+ error ("%qD is not a member of %qT", member, object_type);
+ }
+ return error_mark_node;
+ }
+
+ /* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x' into
+ `(*(a ? &b : &c)).x', and so on. A COND_EXPR is only an lvalue
+ in the front end; only _DECLs and _REFs are lvalues in the back end. */
+ {
+ tree temp = unary_complex_lvalue (ADDR_EXPR, object);
+ if (temp)
+ object = cp_build_indirect_ref (temp, RO_NULL, complain);
+ }
+
+ /* In [expr.ref], there is an explicit list of the valid choices for
+ MEMBER. We check for each of those cases here. */
+ if (VAR_P (member))
+ {
+ /* A static data member. */
+ result = member;
+ mark_exp_read (object);
+ /* If OBJECT has side-effects, they are supposed to occur. */
+ if (TREE_SIDE_EFFECTS (object))
+ result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
+ }
+ else if (TREE_CODE (member) == FIELD_DECL)
+ {
+ /* A non-static data member. */
+ bool null_object_p;
+ int type_quals;
+ tree member_type;
+
+ null_object_p = (INDIRECT_REF_P (object)
+ && integer_zerop (TREE_OPERAND (object, 0)));
+
+ /* Convert OBJECT to the type of MEMBER. */
+ if (!same_type_p (TYPE_MAIN_VARIANT (object_type),
+ TYPE_MAIN_VARIANT (member_scope)))
+ {
+ tree binfo;
+ base_kind kind;
+
+ binfo = lookup_base (access_path ? access_path : object_type,
+ member_scope, ba_unique, &kind, complain);
+ if (binfo == error_mark_node)
+ return error_mark_node;
+
+ /* It is invalid to try to get to a virtual base of a
+ NULL object. The most common cause is invalid use of
+ offsetof macro. */
+ if (null_object_p && kind == bk_via_virtual)
+ {
+ if (complain & tf_error)
+ {
+ error ("invalid access to non-static data member %qD of "
+ "NULL object",
+ member);
+ error ("(perhaps the %<offsetof%> macro was used incorrectly)");
+ }
+ return error_mark_node;
+ }
+
+ /* Convert to the base. */
+ object = build_base_path (PLUS_EXPR, object, binfo,
+ /*nonnull=*/1, complain);
+ /* If we found the base successfully then we should be able
+ to convert to it successfully. */
+ gcc_assert (object != error_mark_node);
+ }
+
+ /* Complain about other invalid uses of offsetof, even though they will
+ give the right answer. Note that we complain whether or not they
+ actually used the offsetof macro, since there's no way to know at this
+ point. So we just give a warning, instead of a pedwarn. */
+ /* Do not produce this warning for base class field references, because
+ we know for a fact that didn't come from offsetof. This does occur
+ in various testsuite cases where a null object is passed where a
+ vtable access is required. */
+ if (null_object_p && warn_invalid_offsetof
+ && CLASSTYPE_NON_STD_LAYOUT (object_type)
+ && !DECL_FIELD_IS_BASE (member)
+ && cp_unevaluated_operand == 0
+ && (complain & tf_warning))
+ {
+ warning (OPT_Winvalid_offsetof,
+ "invalid access to non-static data member %qD "
+ " of NULL object", member);
+ warning (OPT_Winvalid_offsetof,
+ "(perhaps the %<offsetof%> macro was used incorrectly)");
+ }
+
+ /* If MEMBER is from an anonymous aggregate, we have converted
+ OBJECT so that it refers to the class containing the
+ anonymous union. Generate a reference to the anonymous union
+ itself, and recur to find MEMBER. */
+ if (ANON_AGGR_TYPE_P (DECL_CONTEXT (member))
+ /* When this code is called from build_field_call, the
+ object already has the type of the anonymous union.
+ That is because the COMPONENT_REF was already
+ constructed, and was then disassembled before calling
+ build_field_call. After the function-call code is
+ cleaned up, this waste can be eliminated. */
+ && (!same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (object), DECL_CONTEXT (member))))
+ {
+ tree anonymous_union;
+
+ anonymous_union = lookup_anon_field (TREE_TYPE (object),
+ DECL_CONTEXT (member));
+ object = build_class_member_access_expr (object,
+ anonymous_union,
+ /*access_path=*/NULL_TREE,
+ preserve_reference,
+ complain);
+ }
+
+ /* Compute the type of the field, as described in [expr.ref]. */
+ type_quals = TYPE_UNQUALIFIED;
+ member_type = TREE_TYPE (member);
+ if (TREE_CODE (member_type) != REFERENCE_TYPE)
+ {
+ type_quals = (cp_type_quals (member_type)
+ | cp_type_quals (object_type));
+
+ /* A field is const (volatile) if the enclosing object, or the
+ field itself, is const (volatile). But, a mutable field is
+ not const, even within a const object. */
+ if (DECL_MUTABLE_P (member))
+ type_quals &= ~TYPE_QUAL_CONST;
+ member_type = cp_build_qualified_type (member_type, type_quals);
+ }
+
+ result = build3 (COMPONENT_REF, member_type, object, member,
+ NULL_TREE);
+ result = fold_if_not_in_template (result);
+
+ /* Mark the expression const or volatile, as appropriate. Even
+ though we've dealt with the type above, we still have to mark the
+ expression itself. */
+ if (type_quals & TYPE_QUAL_CONST)
+ TREE_READONLY (result) = 1;
+ if (type_quals & TYPE_QUAL_VOLATILE)
+ TREE_THIS_VOLATILE (result) = 1;
+ }
+ else if (BASELINK_P (member))
+ {
+ /* The member is a (possibly overloaded) member function. */
+ tree functions;
+ tree type;
+
+ /* If the MEMBER is exactly one static member function, then we
+ know the type of the expression. Otherwise, we must wait
+ until overload resolution has been performed. */
+ functions = BASELINK_FUNCTIONS (member);
+ if (TREE_CODE (functions) == FUNCTION_DECL
+ && DECL_STATIC_FUNCTION_P (functions))
+ type = TREE_TYPE (functions);
+ else
+ type = unknown_type_node;
+ /* Note that we do not convert OBJECT to the BASELINK_BINFO
+ base. That will happen when the function is called. */
+ result = build3 (COMPONENT_REF, type, object, member, NULL_TREE);
+ }
+ else if (TREE_CODE (member) == CONST_DECL)
+ {
+ /* The member is an enumerator. */
+ result = member;
+ /* If OBJECT has side-effects, they are supposed to occur. */
+ if (TREE_SIDE_EFFECTS (object))
+ result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
+ object, result);
+ }
+ else if ((using_decl = strip_using_decl (member)) != member)
+ result = build_class_member_access_expr (object,
+ using_decl,
+ access_path, preserve_reference,
+ complain);
+ else
+ {
+ if (complain & tf_error)
+ error ("invalid use of %qD", member);
+ return error_mark_node;
+ }
+
+ if (!preserve_reference)
+ /* [expr.ref]
+
+ If E2 is declared to have type "reference to T", then ... the
+ type of E1.E2 is T. */
+ result = convert_from_reference (result);
+
+ return result;
+}
+
+/* Return the destructor denoted by OBJECT.SCOPE::DTOR_NAME, or, if
+ SCOPE is NULL, by OBJECT.DTOR_NAME, where DTOR_NAME is ~type. */
+
+static tree
+lookup_destructor (tree object, tree scope, tree dtor_name,
+ tsubst_flags_t complain)
+{
+ tree object_type = TREE_TYPE (object);
+ tree dtor_type = TREE_OPERAND (dtor_name, 0);
+ tree expr;
+
+ /* We've already complained about this destructor. */
+ if (dtor_type == error_mark_node)
+ return error_mark_node;
+
+ if (scope && !check_dtor_name (scope, dtor_type))
+ {
+ if (complain & tf_error)
+ error ("qualified type %qT does not match destructor name ~%qT",
+ scope, dtor_type);
+ return error_mark_node;
+ }
+ if (is_auto (dtor_type))
+ dtor_type = object_type;
+ else if (identifier_p (dtor_type))
+ {
+ /* In a template, names we can't find a match for are still accepted
+ destructor names, and we check them here. */
+ if (check_dtor_name (object_type, dtor_type))
+ dtor_type = object_type;
+ else
+ {
+ if (complain & tf_error)
+ error ("object type %qT does not match destructor name ~%qT",
+ object_type, dtor_type);
+ return error_mark_node;
+ }
+
+ }
+ else if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type)))
+ {
+ if (complain & tf_error)
+ error ("the type being destroyed is %qT, but the destructor "
+ "refers to %qT", TYPE_MAIN_VARIANT (object_type), dtor_type);
+ return error_mark_node;
+ }
+ expr = lookup_member (dtor_type, complete_dtor_identifier,
+ /*protect=*/1, /*want_type=*/false,
+ tf_warning_or_error);
+ expr = (adjust_result_of_qualified_name_lookup
+ (expr, dtor_type, object_type));
+ if (scope == NULL_TREE)
+ /* We need to call adjust_result_of_qualified_name_lookup in case the
+ destructor names a base class, but we unset BASELINK_QUALIFIED_P so
+ that we still get virtual function binding. */
+ BASELINK_QUALIFIED_P (expr) = false;
+ return expr;
+}
+
+/* An expression of the form "A::template B" has been resolved to
+ DECL. Issue a diagnostic if B is not a template or template
+ specialization. */
+
+void
+check_template_keyword (tree decl)
+{
+ /* The standard says:
+
+ [temp.names]
+
+ If a name prefixed by the keyword template is not a member
+ template, the program is ill-formed.
+
+ DR 228 removed the restriction that the template be a member
+ template.
+
+ DR 96, if accepted would add the further restriction that explicit
+ template arguments must be provided if the template keyword is
+ used, but, as of 2005-10-16, that DR is still in "drafting". If
+ this DR is accepted, then the semantic checks here can be
+ simplified, as the entity named must in fact be a template
+ specialization, rather than, as at present, a set of overloaded
+ functions containing at least one template function. */
+ if (TREE_CODE (decl) != TEMPLATE_DECL
+ && TREE_CODE (decl) != TEMPLATE_ID_EXPR)
+ {
+ if (!is_overloaded_fn (decl))
+ permerror (input_location, "%qD is not a template", decl);
+ else
+ {
+ tree fns;
+ fns = decl;
+ if (BASELINK_P (fns))
+ fns = BASELINK_FUNCTIONS (fns);
+ while (fns)
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (TREE_CODE (fn) == TEMPLATE_DECL
+ || TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+ break;
+ if (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_USE_TEMPLATE (fn)
+ && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (fn)))
+ break;
+ fns = OVL_NEXT (fns);
+ }
+ if (!fns)
+ permerror (input_location, "%qD is not a template", decl);
+ }
+ }
+}
+
+/* This function is called by the parser to process a class member
+ access expression of the form OBJECT.NAME. NAME is a node used by
+ the parser to represent a name; it is not yet a DECL. It may,
+ however, be a BASELINK where the BASELINK_FUNCTIONS is a
+ TEMPLATE_ID_EXPR. Templates must be looked up by the parser, and
+ there is no reason to do the lookup twice, so the parser keeps the
+ BASELINK. TEMPLATE_P is true iff NAME was explicitly declared to
+ be a template via the use of the "A::template B" syntax. */
+
+tree
+finish_class_member_access_expr (tree object, tree name, bool template_p,
+ tsubst_flags_t complain)
+{
+ tree expr;
+ tree object_type;
+ tree member;
+ tree access_path = NULL_TREE;
+ tree orig_object = object;
+ tree orig_name = name;
+
+ if (object == error_mark_node || name == error_mark_node)
+ return error_mark_node;
+
+ /* If OBJECT is an ObjC class instance, we must obey ObjC access rules. */
+ if (!objc_is_public (object, name))
+ return error_mark_node;
+
+ object_type = TREE_TYPE (object);
+
+ if (processing_template_decl)
+ {
+ if (/* If OBJECT_TYPE is dependent, so is OBJECT.NAME. */
+ dependent_type_p (object_type)
+ /* If NAME is just an IDENTIFIER_NODE, then the expression
+ is dependent. */
+ || identifier_p (object)
+ /* If NAME is "f<args>", where either 'f' or 'args' is
+ dependent, then the expression is dependent. */
+ || (TREE_CODE (name) == TEMPLATE_ID_EXPR
+ && dependent_template_id_p (TREE_OPERAND (name, 0),
+ TREE_OPERAND (name, 1)))
+ /* If NAME is "T::X" where "T" is dependent, then the
+ expression is dependent. */
+ || (TREE_CODE (name) == SCOPE_REF
+ && TYPE_P (TREE_OPERAND (name, 0))
+ && dependent_type_p (TREE_OPERAND (name, 0))))
+ return build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF,
+ object, name, NULL_TREE);
+ object = build_non_dependent_expr (object);
+ }
+ else if (c_dialect_objc ()
+ && identifier_p (name)
+ && (expr = objc_maybe_build_component_ref (object, name)))
+ return expr;
+
+ /* [expr.ref]
+
+ The type of the first expression shall be "class object" (of a
+ complete type). */
+ if (!currently_open_class (object_type)
+ && !complete_type_or_maybe_complain (object_type, object, complain))
+ return error_mark_node;
+ if (!CLASS_TYPE_P (object_type))
+ {
+ if (complain & tf_error)
+ {
+ if (POINTER_TYPE_P (object_type)
+ && CLASS_TYPE_P (TREE_TYPE (object_type)))
+ error ("request for member %qD in %qE, which is of pointer "
+ "type %qT (maybe you meant to use %<->%> ?)",
+ name, object, object_type);
+ else
+ error ("request for member %qD in %qE, which is of non-class "
+ "type %qT", name, object, object_type);
+ }
+ return error_mark_node;
+ }
+
+ if (BASELINK_P (name))
+ /* A member function that has already been looked up. */
+ member = name;
+ else
+ {
+ bool is_template_id = false;
+ tree template_args = NULL_TREE;
+ tree scope;
+
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ is_template_id = true;
+ template_args = TREE_OPERAND (name, 1);
+ name = TREE_OPERAND (name, 0);
+
+ if (TREE_CODE (name) == OVERLOAD)
+ name = DECL_NAME (get_first_fn (name));
+ else if (DECL_P (name))
+ name = DECL_NAME (name);
+ }
+
+ if (TREE_CODE (name) == SCOPE_REF)
+ {
+ /* A qualified name. The qualifying class or namespace `S'
+ has already been looked up; it is either a TYPE or a
+ NAMESPACE_DECL. */
+ scope = TREE_OPERAND (name, 0);
+ name = TREE_OPERAND (name, 1);
+
+ /* If SCOPE is a namespace, then the qualified name does not
+ name a member of OBJECT_TYPE. */
+ if (TREE_CODE (scope) == NAMESPACE_DECL)
+ {
+ if (complain & tf_error)
+ error ("%<%D::%D%> is not a member of %qT",
+ scope, name, object_type);
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (scope) == ENUMERAL_TYPE)
+ {
+ /* Looking up a member enumerator (c++/56793). */
+ if (!TYPE_CLASS_SCOPE_P (scope)
+ || !DERIVED_FROM_P (TYPE_CONTEXT (scope), object_type))
+ {
+ if (complain & tf_error)
+ error ("%<%D::%D%> is not a member of %qT",
+ scope, name, object_type);
+ return error_mark_node;
+ }
+ tree val = lookup_enumerator (scope, name);
+ if (TREE_SIDE_EFFECTS (object))
+ val = build2 (COMPOUND_EXPR, TREE_TYPE (val), object, val);
+ return val;
+ }
+
+ gcc_assert (CLASS_TYPE_P (scope));
+ gcc_assert (identifier_p (name) || TREE_CODE (name) == BIT_NOT_EXPR);
+
+ if (constructor_name_p (name, scope))
+ {
+ if (complain & tf_error)
+ error ("cannot call constructor %<%T::%D%> directly",
+ scope, name);
+ return error_mark_node;
+ }
+
+ /* Find the base of OBJECT_TYPE corresponding to SCOPE. */
+ access_path = lookup_base (object_type, scope, ba_check,
+ NULL, complain);
+ if (access_path == error_mark_node)
+ return error_mark_node;
+ if (!access_path)
+ {
+ if (complain & tf_error)
+ error ("%qT is not a base of %qT", scope, object_type);
+ return error_mark_node;
+ }
+ }
+ else
+ {
+ scope = NULL_TREE;
+ access_path = object_type;
+ }
+
+ if (TREE_CODE (name) == BIT_NOT_EXPR)
+ member = lookup_destructor (object, scope, name, complain);
+ else
+ {
+ /* Look up the member. */
+ member = lookup_member (access_path, name, /*protect=*/1,
+ /*want_type=*/false, complain);
+ if (member == NULL_TREE)
+ {
+ if (complain & tf_error)
+ error ("%qD has no member named %qE",
+ TREE_CODE (access_path) == TREE_BINFO
+ ? TREE_TYPE (access_path) : object_type, name);
+ return error_mark_node;
+ }
+ if (member == error_mark_node)
+ return error_mark_node;
+ }
+
+ if (is_template_id)
+ {
+ tree templ = member;
+
+ if (BASELINK_P (templ))
+ templ = lookup_template_function (templ, template_args);
+ else
+ {
+ if (complain & tf_error)
+ error ("%qD is not a member template function", name);
+ return error_mark_node;
+ }
+ }
+ }
+
+ if (TREE_DEPRECATED (member))
+ warn_deprecated_use (member, NULL_TREE);
+
+ if (template_p)
+ check_template_keyword (member);
+
+ expr = build_class_member_access_expr (object, member, access_path,
+ /*preserve_reference=*/false,
+ complain);
+ if (processing_template_decl && expr != error_mark_node)
+ {
+ if (BASELINK_P (member))
+ {
+ if (TREE_CODE (orig_name) == SCOPE_REF)
+ BASELINK_QUALIFIED_P (member) = 1;
+ orig_name = member;
+ }
+ return build_min_non_dep (COMPONENT_REF, expr,
+ orig_object, orig_name,
+ NULL_TREE);
+ }
+
+ return expr;
+}
+
+/* Build a COMPONENT_REF of OBJECT and MEMBER with the appropriate
+ type. */
+
+tree
+build_simple_component_ref (tree object, tree member)
+{
+ tree type = cp_build_qualified_type (TREE_TYPE (member),
+ cp_type_quals (TREE_TYPE (object)));
+ return fold_build3_loc (input_location,
+ COMPONENT_REF, type,
+ object, member, NULL_TREE);
+}
+
+/* Return an expression for the MEMBER_NAME field in the internal
+ representation of PTRMEM, a pointer-to-member function. (Each
+ pointer-to-member function type gets its own RECORD_TYPE so it is
+ more convenient to access the fields by name than by FIELD_DECL.)
+ This routine converts the NAME to a FIELD_DECL and then creates the
+ node for the complete expression. */
+
+tree
+build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
+{
+ tree ptrmem_type;
+ tree member;
+
+ /* This code is a stripped down version of
+ build_class_member_access_expr. It does not work to use that
+ routine directly because it expects the object to be of class
+ type. */
+ ptrmem_type = TREE_TYPE (ptrmem);
+ gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type));
+ member = lookup_member (ptrmem_type, member_name, /*protect=*/0,
+ /*want_type=*/false, tf_warning_or_error);
+ return build_simple_component_ref (ptrmem, member);
+}
+
+/* Given an expression PTR for a pointer, return an expression
+ for the value pointed to.
+ ERRORSTRING is the name of the operator to appear in error messages.
+
+ This function may need to overload OPERATOR_FNNAME.
+ Must also handle REFERENCE_TYPEs for C++. */
+
+tree
+build_x_indirect_ref (location_t loc, tree expr, ref_operator errorstring,
+ tsubst_flags_t complain)
+{
+ tree orig_expr = expr;
+ tree rval;
+
+ if (processing_template_decl)
+ {
+ /* Retain the type if we know the operand is a pointer. */
+ if (TREE_TYPE (expr) && POINTER_TYPE_P (TREE_TYPE (expr)))
+ return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
+ if (type_dependent_expression_p (expr))
+ return build_min_nt_loc (loc, INDIRECT_REF, expr);
+ expr = build_non_dependent_expr (expr);
+ }
+
+ rval = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, expr,
+ NULL_TREE, NULL_TREE, /*overload=*/NULL, complain);
+ if (!rval)
+ rval = cp_build_indirect_ref (expr, errorstring, complain);
+
+ if (processing_template_decl && rval != error_mark_node)
+ return build_min_non_dep (INDIRECT_REF, rval, orig_expr);
+ else
+ return rval;
+}
+
+/* Helper function called from c-common. */
+tree
+build_indirect_ref (location_t /*loc*/,
+ tree ptr, ref_operator errorstring)
+{
+ return cp_build_indirect_ref (ptr, errorstring, tf_warning_or_error);
+}
+
+tree
+cp_build_indirect_ref (tree ptr, ref_operator errorstring,
+ tsubst_flags_t complain)
+{
+ tree pointer, type;
+
+ if (ptr == current_class_ptr
+ || (TREE_CODE (ptr) == NOP_EXPR
+ && TREE_OPERAND (ptr, 0) == current_class_ptr
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (ptr), TREE_TYPE (current_class_ptr)))))
+ return current_class_ref;
+
+ pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
+ ? ptr : decay_conversion (ptr, complain));
+ if (pointer == error_mark_node)
+ return error_mark_node;
+
+ type = TREE_TYPE (pointer);
+
+ if (POINTER_TYPE_P (type))
+ {
+ /* [expr.unary.op]
+
+ If the type of the expression is "pointer to T," the type
+ of the result is "T." */
+ tree t = TREE_TYPE (type);
+
+ if (CONVERT_EXPR_P (ptr)
+ || TREE_CODE (ptr) == VIEW_CONVERT_EXPR)
+ {
+ /* If a warning is issued, mark it to avoid duplicates from
+ the backend. This only needs to be done at
+ warn_strict_aliasing > 2. */
+ if (warn_strict_aliasing > 2)
+ if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (ptr, 0)),
+ type, TREE_OPERAND (ptr, 0)))
+ TREE_NO_WARNING (ptr) = 1;
+ }
+
+ if (VOID_TYPE_P (t))
+ {
+ /* A pointer to incomplete type (other than cv void) can be
+ dereferenced [expr.unary.op]/1 */
+ if (complain & tf_error)
+ error ("%qT is not a pointer-to-object type", type);
+ return error_mark_node;
+ }
+ else if (TREE_CODE (pointer) == ADDR_EXPR
+ && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
+ /* The POINTER was something like `&x'. We simplify `*&x' to
+ `x'. */
+ return TREE_OPERAND (pointer, 0);
+ else
+ {
+ tree ref = build1 (INDIRECT_REF, t, pointer);
+
+ /* We *must* set TREE_READONLY when dereferencing a pointer to const,
+ so that we get the proper error message if the result is used
+ to assign to. Also, &* is supposed to be a no-op. */
+ TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
+ TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
+ TREE_SIDE_EFFECTS (ref)
+ = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer));
+ return ref;
+ }
+ }
+ else if (!(complain & tf_error))
+ /* Don't emit any errors; we'll just return ERROR_MARK_NODE later. */
+ ;
+ /* `pointer' won't be an error_mark_node if we were given a
+ pointer to member, so it's cool to check for this here. */
+ else if (TYPE_PTRMEM_P (type))
+ switch (errorstring)
+ {
+ case RO_ARRAY_INDEXING:
+ error ("invalid use of array indexing on pointer to member");
+ break;
+ case RO_UNARY_STAR:
+ error ("invalid use of unary %<*%> on pointer to member");
+ break;
+ case RO_IMPLICIT_CONVERSION:
+ error ("invalid use of implicit conversion on pointer to member");
+ break;
+ case RO_ARROW_STAR:
+ error ("left hand operand of %<->*%> must be a pointer to class, "
+ "but is a pointer to member of type %qT", type);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ else if (pointer != error_mark_node)
+ invalid_indirection_error (input_location, type, errorstring);
+
+ return error_mark_node;
+}
+
+/* This handles expressions of the form "a[i]", which denotes
+ an array reference.
+
+ This is logically equivalent in C to *(a+i), but we may do it differently.
+ If A is a variable or a member, we generate a primitive ARRAY_REF.
+ This avoids forcing the array out of registers, and can work on
+ arrays that are not lvalues (for example, members of structures returned
+ by functions).
+
+ If INDEX is of some user-defined type, it must be converted to
+ integer type. Otherwise, to make a compatible PLUS_EXPR, it
+ will inherit the type of the array, which will be some pointer type.
+
+ LOC is the location to use in building the array reference. */
+
+tree
+cp_build_array_ref (location_t loc, tree array, tree idx,
+ tsubst_flags_t complain)
+{
+ tree ret;
+
+ if (idx == 0)
+ {
+ if (complain & tf_error)
+ error_at (loc, "subscript missing in array reference");
+ return error_mark_node;
+ }
+
+ /* If an array's index is an array notation, then its rank cannot be
+ greater than one. */
+ if (flag_cilkplus && contains_array_notation_expr (idx))
+ {
+ size_t rank = 0;
+
+ /* If find_rank returns false, then it should have reported an error,
+ thus it is unnecessary for repetition. */
+ if (!find_rank (loc, idx, idx, true, &rank))
+ return error_mark_node;
+ if (rank > 1)
+ {
+ error_at (loc, "rank of the array%'s index is greater than 1");
+ return error_mark_node;
+ }
+ }
+ if (TREE_TYPE (array) == error_mark_node
+ || TREE_TYPE (idx) == error_mark_node)
+ return error_mark_node;
+
+ /* If ARRAY is a COMPOUND_EXPR or COND_EXPR, move our reference
+ inside it. */
+ switch (TREE_CODE (array))
+ {
+ case COMPOUND_EXPR:
+ {
+ tree value = cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
+ complain);
+ ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
+ TREE_OPERAND (array, 0), value);
+ SET_EXPR_LOCATION (ret, loc);
+ return ret;
+ }
+
+ case COND_EXPR:
+ ret = build_conditional_expr
+ (loc, TREE_OPERAND (array, 0),
+ cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
+ complain),
+ cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx,
+ complain),
+ complain);
+ protected_set_expr_location (ret, loc);
+ return ret;
+
+ default:
+ break;
+ }
+
+ convert_vector_to_pointer_for_subscript (loc, &array, idx);
+
+ if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
+ {
+ tree rval, type;
+
+ warn_array_subscript_with_type_char (idx);
+
+ if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
+ {
+ if (complain & tf_error)
+ error_at (loc, "array subscript is not an integer");
+ return error_mark_node;
+ }
+
+ /* Apply integral promotions *after* noticing character types.
+ (It is unclear why we do these promotions -- the standard
+ does not say that we should. In fact, the natural thing would
+ seem to be to convert IDX to ptrdiff_t; we're performing
+ pointer arithmetic.) */
+ idx = cp_perform_integral_promotions (idx, complain);
+
+ /* An array that is indexed by a non-constant
+ cannot be stored in a register; we must be able to do
+ address arithmetic on its address.
+ Likewise an array of elements of variable size. */
+ if (TREE_CODE (idx) != INTEGER_CST
+ || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
+ && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
+ != INTEGER_CST)))
+ {
+ if (!cxx_mark_addressable (array))
+ return error_mark_node;
+ }
+
+ /* An array that is indexed by a constant value which is not within
+ the array bounds cannot be stored in a register either; because we
+ would get a crash in store_bit_field/extract_bit_field when trying
+ to access a non-existent part of the register. */
+ if (TREE_CODE (idx) == INTEGER_CST
+ && TYPE_DOMAIN (TREE_TYPE (array))
+ && ! int_fits_type_p (idx, TYPE_DOMAIN (TREE_TYPE (array))))
+ {
+ if (!cxx_mark_addressable (array))
+ return error_mark_node;
+ }
+
+ if (!lvalue_p (array) && (complain & tf_error))
+ pedwarn (loc, OPT_Wpedantic,
+ "ISO C++ forbids subscripting non-lvalue array");
+
+ /* Note in C++ it is valid to subscript a `register' array, since
+ it is valid to take the address of something with that
+ storage specification. */
+ if (extra_warnings)
+ {
+ tree foo = array;
+ while (TREE_CODE (foo) == COMPONENT_REF)
+ foo = TREE_OPERAND (foo, 0);
+ if (VAR_P (foo) && DECL_REGISTER (foo)
+ && (complain & tf_warning))
+ warning_at (loc, OPT_Wextra,
+ "subscripting array declared %<register%>");
+ }
+
+ type = TREE_TYPE (TREE_TYPE (array));
+ rval = build4 (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
+ /* Array ref is const/volatile if the array elements are
+ or if the array is.. */
+ TREE_READONLY (rval)
+ |= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
+ TREE_SIDE_EFFECTS (rval)
+ |= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
+ TREE_THIS_VOLATILE (rval)
+ |= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
+ ret = require_complete_type_sfinae (fold_if_not_in_template (rval),
+ complain);
+ protected_set_expr_location (ret, loc);
+ return ret;
+ }
+
+ {
+ tree ar = cp_default_conversion (array, complain);
+ tree ind = cp_default_conversion (idx, complain);
+
+ /* Put the integer in IND to simplify error checking. */
+ if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
+ {
+ tree temp = ar;
+ ar = ind;
+ ind = temp;
+ }
+
+ if (ar == error_mark_node || ind == error_mark_node)
+ return error_mark_node;
+
+ if (!TYPE_PTR_P (TREE_TYPE (ar)))
+ {
+ if (complain & tf_error)
+ error_at (loc, "subscripted value is neither array nor pointer");
+ return error_mark_node;
+ }
+ if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
+ {
+ if (complain & tf_error)
+ error_at (loc, "array subscript is not an integer");
+ return error_mark_node;
+ }
+
+ warn_array_subscript_with_type_char (idx);
+
+ ret = cp_build_indirect_ref (cp_build_binary_op (input_location,
+ PLUS_EXPR, ar, ind,
+ complain),
+ RO_ARRAY_INDEXING,
+ complain);
+ protected_set_expr_location (ret, loc);
+ return ret;
+ }
+}
+
+/* Entry point for Obj-C++. */
+
+tree
+build_array_ref (location_t loc, tree array, tree idx)
+{
+ return cp_build_array_ref (loc, array, idx, tf_warning_or_error);
+}
+
+/* Resolve a pointer to member function. INSTANCE is the object
+ instance to use, if the member points to a virtual member.
+
+ This used to avoid checking for virtual functions if basetype
+ has no virtual functions, according to an earlier ANSI draft.
+ With the final ISO C++ rules, such an optimization is
+ incorrect: A pointer to a derived member can be static_cast
+ to pointer-to-base-member, as long as the dynamic object
+ later has the right member. So now we only do this optimization
+ when we know the dynamic type of the object. */
+
+tree
+get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
+ tsubst_flags_t complain)
+{
+ if (TREE_CODE (function) == OFFSET_REF)
+ function = TREE_OPERAND (function, 1);
+
+ if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
+ {
+ tree idx, delta, e1, e2, e3, vtbl;
+ bool nonvirtual;
+ tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
+ tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
+
+ tree instance_ptr = *instance_ptrptr;
+ tree instance_save_expr = 0;
+ if (instance_ptr == error_mark_node)
+ {
+ if (TREE_CODE (function) == PTRMEM_CST)
+ {
+ /* Extracting the function address from a pmf is only
+ allowed with -Wno-pmf-conversions. It only works for
+ pmf constants. */
+ e1 = build_addr_func (PTRMEM_CST_MEMBER (function), complain);
+ e1 = convert (fntype, e1);
+ return e1;
+ }
+ else
+ {
+ if (complain & tf_error)
+ error ("object missing in use of %qE", function);
+ return error_mark_node;
+ }
+ }
+
+ /* True if we know that the dynamic type of the object doesn't have
+ virtual functions, so we can assume the PFN field is a pointer. */
+ nonvirtual = (COMPLETE_TYPE_P (basetype)
+ && !TYPE_POLYMORPHIC_P (basetype)
+ && resolves_to_fixed_type_p (instance_ptr, 0));
+
+ if (TREE_SIDE_EFFECTS (instance_ptr))
+ instance_ptr = instance_save_expr = save_expr (instance_ptr);
+
+ if (TREE_SIDE_EFFECTS (function))
+ function = save_expr (function);
+
+ /* Start by extracting all the information from the PMF itself. */
+ e3 = pfn_from_ptrmemfunc (function);
+ delta = delta_from_ptrmemfunc (function);
+ idx = build1 (NOP_EXPR, vtable_index_type, e3);
+ switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
+ {
+ case ptrmemfunc_vbit_in_pfn:
+ e1 = cp_build_binary_op (input_location,
+ BIT_AND_EXPR, idx, integer_one_node,
+ complain);
+ idx = cp_build_binary_op (input_location,
+ MINUS_EXPR, idx, integer_one_node,
+ complain);
+ if (idx == error_mark_node)
+ return error_mark_node;
+ break;
+
+ case ptrmemfunc_vbit_in_delta:
+ e1 = cp_build_binary_op (input_location,
+ BIT_AND_EXPR, delta, integer_one_node,
+ complain);
+ delta = cp_build_binary_op (input_location,
+ RSHIFT_EXPR, delta, integer_one_node,
+ complain);
+ if (delta == error_mark_node)
+ return error_mark_node;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (e1 == error_mark_node)
+ return error_mark_node;
+
+ /* Convert down to the right base before using the instance. A
+ special case is that in a pointer to member of class C, C may
+ be incomplete. In that case, the function will of course be
+ a member of C, and no conversion is required. In fact,
+ lookup_base will fail in that case, because incomplete
+ classes do not have BINFOs. */
+ if (!same_type_ignoring_top_level_qualifiers_p
+ (basetype, TREE_TYPE (TREE_TYPE (instance_ptr))))
+ {
+ basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
+ basetype, ba_check, NULL, complain);
+ instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype,
+ 1, complain);
+ if (instance_ptr == error_mark_node)
+ return error_mark_node;
+ }
+ /* ...and then the delta in the PMF. */
+ instance_ptr = fold_build_pointer_plus (instance_ptr, delta);
+
+ /* Hand back the adjusted 'this' argument to our caller. */
+ *instance_ptrptr = instance_ptr;
+
+ if (nonvirtual)
+ /* Now just return the pointer. */
+ return e3;
+
+ /* Next extract the vtable pointer from the object. */
+ vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
+ instance_ptr);
+ vtbl = cp_build_indirect_ref (vtbl, RO_NULL, complain);
+ if (vtbl == error_mark_node)
+ return error_mark_node;
+
+ /* Finally, extract the function pointer from the vtable. */
+ e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
+ e2 = cp_build_indirect_ref (e2, RO_NULL, complain);
+ if (e2 == error_mark_node)
+ return error_mark_node;
+ TREE_CONSTANT (e2) = 1;
+
+ /* When using function descriptors, the address of the
+ vtable entry is treated as a function pointer. */
+ if (TARGET_VTABLE_USES_DESCRIPTORS)
+ e2 = build1 (NOP_EXPR, TREE_TYPE (e2),
+ cp_build_addr_expr (e2, complain));
+
+ e2 = fold_convert (TREE_TYPE (e3), e2);
+ e1 = build_conditional_expr (input_location, e1, e2, e3, complain);
+ if (e1 == error_mark_node)
+ return error_mark_node;
+
+ /* Make sure this doesn't get evaluated first inside one of the
+ branches of the COND_EXPR. */
+ if (instance_save_expr)
+ e1 = build2 (COMPOUND_EXPR, TREE_TYPE (e1),
+ instance_save_expr, e1);
+
+ function = e1;
+ }
+ return function;
+}
+
+/* Used by the C-common bits. */
+tree
+build_function_call (location_t /*loc*/,
+ tree function, tree params)
+{
+ return cp_build_function_call (function, params, tf_warning_or_error);
+}
+
+/* Used by the C-common bits. */
+tree
+build_function_call_vec (location_t /*loc*/, vec<location_t> /*arg_loc*/,
+ tree function, vec<tree, va_gc> *params,
+ vec<tree, va_gc> * /*origtypes*/)
+{
+ vec<tree, va_gc> *orig_params = params;
+ tree ret = cp_build_function_call_vec (function, &params,
+ tf_warning_or_error);
+
+ /* cp_build_function_call_vec can reallocate PARAMS by adding
+ default arguments. That should never happen here. Verify
+ that. */
+ gcc_assert (params == orig_params);
+
+ return ret;
+}
+
+/* Build a function call using a tree list of arguments. */
+
+tree
+cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
+{
+ vec<tree, va_gc> *vec;
+ tree ret;
+
+ vec = make_tree_vector ();
+ for (; params != NULL_TREE; params = TREE_CHAIN (params))
+ vec_safe_push (vec, TREE_VALUE (params));
+ ret = cp_build_function_call_vec (function, &vec, complain);
+ release_tree_vector (vec);
+ return ret;
+}
+
+/* Build a function call using varargs. */
+
+tree
+cp_build_function_call_nary (tree function, tsubst_flags_t complain, ...)
+{
+ vec<tree, va_gc> *vec;
+ va_list args;
+ tree ret, t;
+
+ vec = make_tree_vector ();
+ va_start (args, complain);
+ for (t = va_arg (args, tree); t != NULL_TREE; t = va_arg (args, tree))
+ vec_safe_push (vec, t);
+ va_end (args);
+ ret = cp_build_function_call_vec (function, &vec, complain);
+ release_tree_vector (vec);
+ return ret;
+}
+
+/* Build a function call using a vector of arguments. PARAMS may be
+ NULL if there are no parameters. This changes the contents of
+ PARAMS. */
+
+tree
+cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
+ tsubst_flags_t complain)
+{
+ tree fntype, fndecl;
+ int is_method;
+ tree original = function;
+ int nargs;
+ tree *argarray;
+ tree parm_types;
+ vec<tree, va_gc> *allocated = NULL;
+ tree ret;
+
+ /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
+ expressions, like those used for ObjC messenger dispatches. */
+ if (params != NULL && !vec_safe_is_empty (*params))
+ function = objc_rewrite_function_call (function, (**params)[0]);
+
+ /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
+ Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context. */
+ if (TREE_CODE (function) == NOP_EXPR
+ && TREE_TYPE (function) == TREE_TYPE (TREE_OPERAND (function, 0)))
+ function = TREE_OPERAND (function, 0);
+
+ if (TREE_CODE (function) == FUNCTION_DECL)
+ {
+ mark_used (function);
+ fndecl = function;
+
+ /* Convert anything with function type to a pointer-to-function. */
+ if (DECL_MAIN_P (function) && (complain & tf_error))
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ forbids calling %<::main%> from within program");
+
+ function = build_addr_func (function, complain);
+ }
+ else
+ {
+ fndecl = NULL_TREE;
+
+ function = build_addr_func (function, complain);
+ }
+
+ if (function == error_mark_node)
+ return error_mark_node;
+
+ fntype = TREE_TYPE (function);
+
+ if (TYPE_PTRMEMFUNC_P (fntype))
+ {
+ if (complain & tf_error)
+ error ("must use %<.*%> or %<->*%> to call pointer-to-member "
+ "function in %<%E (...)%>, e.g. %<(... ->* %E) (...)%>",
+ original, original);
+ return error_mark_node;
+ }
+
+ is_method = (TYPE_PTR_P (fntype)
+ && TREE_CODE (TREE_TYPE (fntype)) == METHOD_TYPE);
+
+ if (!(TYPE_PTRFN_P (fntype)
+ || is_method
+ || TREE_CODE (function) == TEMPLATE_ID_EXPR))
+ {
+ if (complain & tf_error)
+ {
+ if (!flag_diagnostics_show_caret)
+ error_at (input_location,
+ "%qE cannot be used as a function", original);
+ else if (DECL_P (original))
+ error_at (input_location,
+ "%qD cannot be used as a function", original);
+ else
+ error_at (input_location,
+ "expression cannot be used as a function");
+ }
+
+ return error_mark_node;
+ }
+
+ /* fntype now gets the type of function pointed to. */
+ fntype = TREE_TYPE (fntype);
+ parm_types = TYPE_ARG_TYPES (fntype);
+
+ if (params == NULL)
+ {
+ allocated = make_tree_vector ();
+ params = &allocated;
+ }
+
+ nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
+ complain);
+ if (nargs < 0)
+ return error_mark_node;
+
+ argarray = (*params)->address ();
+
+ /* Check for errors in format strings and inappropriately
+ null parameters. */
+ check_function_arguments (fntype, nargs, argarray);
+
+ ret = build_cxx_call (function, nargs, argarray, complain);
+
+ if (allocated != NULL)
+ release_tree_vector (allocated);
+
+ return ret;
+}
+
+/* Subroutine of convert_arguments.
+ Warn about wrong number of args are genereted. */
+
+static void
+warn_args_num (location_t loc, tree fndecl, bool too_many_p)
+{
+ if (fndecl)
+ {
+ if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
+ {
+ if (DECL_NAME (fndecl) == NULL_TREE
+ || IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (fndecl)))
+ error_at (loc,
+ too_many_p
+ ? G_("too many arguments to constructor %q#D")
+ : G_("too few arguments to constructor %q#D"),
+ fndecl);
+ else
+ error_at (loc,
+ too_many_p
+ ? G_("too many arguments to member function %q#D")
+ : G_("too few arguments to member function %q#D"),
+ fndecl);
+ }
+ else
+ error_at (loc,
+ too_many_p
+ ? G_("too many arguments to function %q#D")
+ : G_("too few arguments to function %q#D"),
+ fndecl);
+ inform (DECL_SOURCE_LOCATION (fndecl),
+ "declared here");
+ }
+ else
+ {
+ if (c_dialect_objc () && objc_message_selector ())
+ error_at (loc,
+ too_many_p
+ ? G_("too many arguments to method %q#D")
+ : G_("too few arguments to method %q#D"),
+ objc_message_selector ());
+ else
+ error_at (loc, too_many_p ? G_("too many arguments to function")
+ : G_("too few arguments to function"));
+ }
+}
+
+/* Convert the actual parameter expressions in the list VALUES to the
+ types in the list TYPELIST. The converted expressions are stored
+ back in the VALUES vector.
+ If parmdecls is exhausted, or when an element has NULL as its type,
+ perform the default conversions.
+
+ NAME is an IDENTIFIER_NODE or 0. It is used only for error messages.
+
+ This is also where warnings about wrong number of args are generated.
+
+ Returns the actual number of arguments processed (which might be less
+ than the length of the vector), or -1 on error.
+
+ In C++, unspecified trailing parameters can be filled in with their
+ default arguments, if such were specified. Do so here. */
+
+static int
+convert_arguments (tree typelist, vec<tree, va_gc> **values, tree fndecl,
+ int flags, tsubst_flags_t complain)
+{
+ tree typetail;
+ unsigned int i;
+
+ /* Argument passing is always copy-initialization. */
+ flags |= LOOKUP_ONLYCONVERTING;
+
+ for (i = 0, typetail = typelist;
+ i < vec_safe_length (*values);
+ i++)
+ {
+ tree type = typetail ? TREE_VALUE (typetail) : 0;
+ tree val = (**values)[i];
+
+ if (val == error_mark_node || type == error_mark_node)
+ return -1;
+
+ if (type == void_type_node)
+ {
+ if (complain & tf_error)
+ {
+ warn_args_num (input_location, fndecl, /*too_many_p=*/true);
+ return i;
+ }
+ else
+ return -1;
+ }
+
+ /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
+ Strip such NOP_EXPRs, since VAL is used in non-lvalue context. */
+ if (TREE_CODE (val) == NOP_EXPR
+ && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0))
+ && (type == 0 || TREE_CODE (type) != REFERENCE_TYPE))
+ val = TREE_OPERAND (val, 0);
+
+ if (type == 0 || TREE_CODE (type) != REFERENCE_TYPE)
+ {
+ if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
+ || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)
+ val = decay_conversion (val, complain);
+ }
+
+ if (val == error_mark_node)
+ return -1;
+
+ if (type != 0)
+ {
+ /* Formal parm type is specified by a function prototype. */
+ tree parmval;
+
+ if (!COMPLETE_TYPE_P (complete_type (type)))
+ {
+ if (complain & tf_error)
+ {
+ if (fndecl)
+ error ("parameter %P of %qD has incomplete type %qT",
+ i, fndecl, type);
+ else
+ error ("parameter %P has incomplete type %qT", i, type);
+ }
+ parmval = error_mark_node;
+ }
+ else
+ {
+ parmval = convert_for_initialization
+ (NULL_TREE, type, val, flags,
+ ICR_ARGPASS, fndecl, i, complain);
+ parmval = convert_for_arg_passing (type, parmval, complain);
+ }
+
+ if (parmval == error_mark_node)
+ return -1;
+
+ (**values)[i] = parmval;
+ }
+ else
+ {
+ if (fndecl && magic_varargs_p (fndecl))
+ /* Don't do ellipsis conversion for __built_in_constant_p
+ as this will result in spurious errors for non-trivial
+ types. */
+ val = require_complete_type_sfinae (val, complain);
+ else
+ val = convert_arg_to_ellipsis (val, complain);
+
+ (**values)[i] = val;
+ }
+
+ if (typetail)
+ typetail = TREE_CHAIN (typetail);
+ }
+
+ if (typetail != 0 && typetail != void_list_node)
+ {
+ /* See if there are default arguments that can be used. Because
+ we hold default arguments in the FUNCTION_TYPE (which is so
+ wrong), we can see default parameters here from deduced
+ contexts (and via typeof) for indirect function calls.
+ Fortunately we know whether we have a function decl to
+ provide default arguments in a language conformant
+ manner. */
+ if (fndecl && TREE_PURPOSE (typetail)
+ && TREE_CODE (TREE_PURPOSE (typetail)) != DEFAULT_ARG)
+ {
+ for (; typetail != void_list_node; ++i)
+ {
+ tree parmval
+ = convert_default_arg (TREE_VALUE (typetail),
+ TREE_PURPOSE (typetail),
+ fndecl, i, complain);
+
+ if (parmval == error_mark_node)
+ return -1;
+
+ vec_safe_push (*values, parmval);
+ typetail = TREE_CHAIN (typetail);
+ /* ends with `...'. */
+ if (typetail == NULL_TREE)
+ break;
+ }
+ }
+ else
+ {
+ if (complain & tf_error)
+ warn_args_num (input_location, fndecl, /*too_many_p=*/false);
+ return -1;
+ }
+ }
+
+ return (int) i;
+}
+
+/* Build a binary-operation expression, after performing default
+ conversions on the operands. CODE is the kind of expression to
+ build. ARG1 and ARG2 are the arguments. ARG1_CODE and ARG2_CODE
+ are the tree codes which correspond to ARG1 and ARG2 when issuing
+ warnings about possibly misplaced parentheses. They may differ
+ from the TREE_CODE of ARG1 and ARG2 if the parser has done constant
+ folding (e.g., if the parser sees "a | 1 + 1", it may call this
+ routine with ARG2 being an INTEGER_CST and ARG2_CODE == PLUS_EXPR).
+ To avoid issuing any parentheses warnings, pass ARG1_CODE and/or
+ ARG2_CODE as ERROR_MARK. */
+
+tree
+build_x_binary_op (location_t loc, enum tree_code code, tree arg1,
+ enum tree_code arg1_code, tree arg2,
+ enum tree_code arg2_code, tree *overload,
+ tsubst_flags_t complain)
+{
+ tree orig_arg1;
+ tree orig_arg2;
+ tree expr;
+
+ orig_arg1 = arg1;
+ orig_arg2 = arg2;
+
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (arg1)
+ || type_dependent_expression_p (arg2))
+ return build_min_nt_loc (loc, code, arg1, arg2);
+ arg1 = build_non_dependent_expr (arg1);
+ arg2 = build_non_dependent_expr (arg2);
+ }
+
+ if (code == DOTSTAR_EXPR)
+ expr = build_m_component_ref (arg1, arg2, complain);
+ else
+ expr = build_new_op (loc, code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
+ overload, complain);
+
+ /* Check for cases such as x+y<<z which users are likely to
+ misinterpret. But don't warn about obj << x + y, since that is a
+ common idiom for I/O. */
+ if (warn_parentheses
+ && (complain & tf_warning)
+ && !processing_template_decl
+ && !error_operand_p (arg1)
+ && !error_operand_p (arg2)
+ && (code != LSHIFT_EXPR
+ || !CLASS_TYPE_P (TREE_TYPE (arg1))))
+ warn_about_parentheses (loc, code, arg1_code, orig_arg1,
+ arg2_code, orig_arg2);
+
+ if (processing_template_decl && expr != error_mark_node)
+ return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
+
+ return expr;
+}
+
+/* Build and return an ARRAY_REF expression. */
+
+tree
+build_x_array_ref (location_t loc, tree arg1, tree arg2,
+ tsubst_flags_t complain)
+{
+ tree orig_arg1 = arg1;
+ tree orig_arg2 = arg2;
+ tree expr;
+
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (arg1)
+ || type_dependent_expression_p (arg2))
+ return build_min_nt_loc (loc, ARRAY_REF, arg1, arg2,
+ NULL_TREE, NULL_TREE);
+ arg1 = build_non_dependent_expr (arg1);
+ arg2 = build_non_dependent_expr (arg2);
+ }
+
+ expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, arg1, arg2,
+ NULL_TREE, /*overload=*/NULL, complain);
+
+ if (processing_template_decl && expr != error_mark_node)
+ return build_min_non_dep (ARRAY_REF, expr, orig_arg1, orig_arg2,
+ NULL_TREE, NULL_TREE);
+ return expr;
+}
+
+/* Return whether OP is an expression of enum type cast to integer
+ type. In C++ even unsigned enum types are cast to signed integer
+ types. We do not want to issue warnings about comparisons between
+ signed and unsigned types when one of the types is an enum type.
+ Those warnings are always false positives in practice. */
+
+static bool
+enum_cast_to_int (tree op)
+{
+ if (TREE_CODE (op) == NOP_EXPR
+ && TREE_TYPE (op) == integer_type_node
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == ENUMERAL_TYPE
+ && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 0))))
+ return true;
+
+ /* The cast may have been pushed into a COND_EXPR. */
+ if (TREE_CODE (op) == COND_EXPR)
+ return (enum_cast_to_int (TREE_OPERAND (op, 1))
+ || enum_cast_to_int (TREE_OPERAND (op, 2)));
+
+ return false;
+}
+
+/* For the c-common bits. */
+tree
+build_binary_op (location_t location, enum tree_code code, tree op0, tree op1,
+ int /*convert_p*/)
+{
+ return cp_build_binary_op (location, code, op0, op1, tf_warning_or_error);
+}
+
+
+/* Build a binary-operation expression without default conversions.
+ CODE is the kind of expression to build.
+ LOCATION is the location_t of the operator in the source code.
+ This function differs from `build' in several ways:
+ the data type of the result is computed and recorded in it,
+ warnings are generated if arg data types are invalid,
+ special handling for addition and subtraction of pointers is known,
+ and some optimization is done (operations on narrow ints
+ are done in the narrower type when that gives the same result).
+ Constant folding is also done before the result is returned.
+
+ Note that the operands will never have enumeral types
+ because either they have just had the default conversions performed
+ or they have both just been converted to some other type in which
+ the arithmetic is to be done.
+
+ C++: must do special pointer arithmetic when implementing
+ multiple inheritance, and deal with pointer to member functions. */
+
+tree
+cp_build_binary_op (location_t location,
+ enum tree_code code, tree orig_op0, tree orig_op1,
+ tsubst_flags_t complain)
+{
+ tree op0, op1;
+ enum tree_code code0, code1;
+ tree type0, type1;
+ const char *invalid_op_diag;
+
+ /* Expression code to give to the expression when it is built.
+ Normally this is CODE, which is what the caller asked for,
+ but in some special cases we change it. */
+ enum tree_code resultcode = code;
+
+ /* Data type in which the computation is to be performed.
+ In the simplest cases this is the common type of the arguments. */
+ tree result_type = NULL;
+
+ /* Nonzero means operands have already been type-converted
+ in whatever way is necessary.
+ Zero means they need to be converted to RESULT_TYPE. */
+ int converted = 0;
+
+ /* Nonzero means create the expression with this type, rather than
+ RESULT_TYPE. */
+ tree build_type = 0;
+
+ /* Nonzero means after finally constructing the expression
+ convert it to this type. */
+ tree final_type = 0;
+
+ tree result;
+ tree orig_type = NULL;
+
+ /* Nonzero if this is an operation like MIN or MAX which can
+ safely be computed in short if both args are promoted shorts.
+ Also implies COMMON.
+ -1 indicates a bitwise operation; this makes a difference
+ in the exact conditions for when it is safe to do the operation
+ in a narrower mode. */
+ int shorten = 0;
+
+ /* Nonzero if this is a comparison operation;
+ if both args are promoted shorts, compare the original shorts.
+ Also implies COMMON. */
+ int short_compare = 0;
+
+ /* Nonzero means set RESULT_TYPE to the common type of the args. */
+ int common = 0;
+
+ /* True if both operands have arithmetic type. */
+ bool arithmetic_types_p;
+
+ /* Apply default conversions. */
+ op0 = orig_op0;
+ op1 = orig_op1;
+
+ /* Remember whether we're doing / or %. */
+ bool doing_div_or_mod = false;
+
+ /* Remember whether we're doing << or >>. */
+ bool doing_shift = false;
+
+ /* Tree holding instrumentation expression. */
+ tree instrument_expr = NULL;
+
+ if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
+ || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
+ || code == TRUTH_XOR_EXPR)
+ {
+ if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
+ op0 = decay_conversion (op0, complain);
+ if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
+ op1 = decay_conversion (op1, complain);
+ }
+ else
+ {
+ if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
+ op0 = cp_default_conversion (op0, complain);
+ if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
+ op1 = cp_default_conversion (op1, complain);
+ }
+
+ /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
+ STRIP_TYPE_NOPS (op0);
+ STRIP_TYPE_NOPS (op1);
+
+ /* DTRT if one side is an overloaded function, but complain about it. */
+ if (type_unknown_p (op0))
+ {
+ tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none);
+ if (t != error_mark_node)
+ {
+ if (complain & tf_error)
+ permerror (input_location, "assuming cast to type %qT from overloaded function",
+ TREE_TYPE (t));
+ op0 = t;
+ }
+ }
+ if (type_unknown_p (op1))
+ {
+ tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none);
+ if (t != error_mark_node)
+ {
+ if (complain & tf_error)
+ permerror (input_location, "assuming cast to type %qT from overloaded function",
+ TREE_TYPE (t));
+ op1 = t;
+ }
+ }
+
+ type0 = TREE_TYPE (op0);
+ type1 = TREE_TYPE (op1);
+
+ /* The expression codes of the data types of the arguments tell us
+ whether the arguments are integers, floating, pointers, etc. */
+ code0 = TREE_CODE (type0);
+ code1 = TREE_CODE (type1);
+
+ /* If an error was already reported for one of the arguments,
+ avoid reporting another error. */
+ if (code0 == ERROR_MARK || code1 == ERROR_MARK)
+ return error_mark_node;
+
+ if ((invalid_op_diag
+ = targetm.invalid_binary_op (code, type0, type1)))
+ {
+ if (complain & tf_error)
+ error (invalid_op_diag);
+ return error_mark_node;
+ }
+
+ /* Issue warnings about peculiar, but valid, uses of NULL. */
+ if ((orig_op0 == null_node || orig_op1 == null_node)
+ /* It's reasonable to use pointer values as operands of &&
+ and ||, so NULL is no exception. */
+ && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR
+ && ( /* Both are NULL (or 0) and the operation was not a
+ comparison or a pointer subtraction. */
+ (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)
+ && code != EQ_EXPR && code != NE_EXPR && code != MINUS_EXPR)
+ /* Or if one of OP0 or OP1 is neither a pointer nor NULL. */
+ || (!null_ptr_cst_p (orig_op0)
+ && !TYPE_PTR_OR_PTRMEM_P (type0))
+ || (!null_ptr_cst_p (orig_op1)
+ && !TYPE_PTR_OR_PTRMEM_P (type1)))
+ && (complain & tf_warning))
+ {
+ source_location loc =
+ expansion_point_location_if_in_system_header (input_location);
+
+ warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic");
+ }
+
+ /* In case when one of the operands of the binary operation is
+ a vector and another is a scalar -- convert scalar to vector. */
+ if ((code0 == VECTOR_TYPE) != (code1 == VECTOR_TYPE))
+ {
+ enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1,
+ complain & tf_error);
+
+ switch (convert_flag)
+ {
+ case stv_error:
+ return error_mark_node;
+ case stv_firstarg:
+ {
+ op0 = save_expr (op0);
+ op0 = convert (TREE_TYPE (type1), op0);
+ op0 = build_vector_from_val (type1, op0);
+ type0 = TREE_TYPE (op0);
+ code0 = TREE_CODE (type0);
+ converted = 1;
+ break;
+ }
+ case stv_secondarg:
+ {
+ op1 = save_expr (op1);
+ op1 = convert (TREE_TYPE (type0), op1);
+ op1 = build_vector_from_val (type0, op1);
+ type1 = TREE_TYPE (op1);
+ code1 = TREE_CODE (type1);
+ converted = 1;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ switch (code)
+ {
+ case MINUS_EXPR:
+ /* Subtraction of two similar pointers.
+ We must subtract them as integers, then divide by object size. */
+ if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
+ && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
+ TREE_TYPE (type1)))
+ return pointer_diff (op0, op1, common_pointer_type (type0, type1),
+ complain);
+ /* In all other cases except pointer - int, the usual arithmetic
+ rules apply. */
+ else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
+ {
+ common = 1;
+ break;
+ }
+ /* The pointer - int case is just like pointer + int; fall
+ through. */
+ case PLUS_EXPR:
+ if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
+ && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
+ {
+ tree ptr_operand;
+ tree int_operand;
+ ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1);
+ int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1);
+ if (processing_template_decl)
+ {
+ result_type = TREE_TYPE (ptr_operand);
+ break;
+ }
+ return cp_pointer_int_sum (code,
+ ptr_operand,
+ int_operand,
+ complain);
+ }
+ common = 1;
+ break;
+
+ case MULT_EXPR:
+ common = 1;
+ break;
+
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
+ || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
+ || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
+ {
+ enum tree_code tcode0 = code0, tcode1 = code1;
+ tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+ cop1 = maybe_constant_value (cop1);
+
+ if (tcode0 == INTEGER_TYPE)
+ doing_div_or_mod = true;
+
+ warn_for_div_by_zero (location, cop1);
+
+ if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
+ tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
+ if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE)
+ tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
+
+ if (!(tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE))
+ resultcode = RDIV_EXPR;
+ else
+ /* When dividing two signed integers, we have to promote to int.
+ unless we divide by a constant != -1. Note that default
+ conversion will have been performed on the operands at this
+ point, so we have to dig out the original type to find out if
+ it was unsigned. */
+ shorten = ((TREE_CODE (op0) == NOP_EXPR
+ && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
+ || (TREE_CODE (op1) == INTEGER_CST
+ && ! integer_all_onesp (op1)));
+
+ common = 1;
+ }
+ break;
+
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ if ((code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && !VECTOR_FLOAT_TYPE_P (type0)
+ && !VECTOR_FLOAT_TYPE_P (type1)))
+ shorten = -1;
+ break;
+
+ case TRUNC_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ {
+ tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+ cop1 = maybe_constant_value (cop1);
+
+ if (code0 == INTEGER_TYPE)
+ doing_div_or_mod = true;
+ warn_for_div_by_zero (location, cop1);
+ }
+
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
+ common = 1;
+ else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ {
+ /* Although it would be tempting to shorten always here, that loses
+ on some targets, since the modulo instruction is undefined if the
+ quotient can't be represented in the computation mode. We shorten
+ only if unsigned or if dividing by something we know != -1. */
+ shorten = ((TREE_CODE (op0) == NOP_EXPR
+ && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
+ || (TREE_CODE (op1) == INTEGER_CST
+ && ! integer_all_onesp (op1)));
+ common = 1;
+ }
+ break;
+
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ if (VECTOR_TYPE_P (type0) || VECTOR_TYPE_P (type1))
+ {
+ sorry ("logical operation on vector type");
+ return error_mark_node;
+ }
+ result_type = boolean_type_node;
+ break;
+
+ /* Shift operations: result has same type as first operand;
+ always convert second operand to int.
+ Also set SHORT_SHIFT if shifting rightward. */
+
+ case RSHIFT_EXPR:
+ if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
+ {
+ result_type = type0;
+ converted = 1;
+ }
+ else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
+ && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1))
+ {
+ result_type = type0;
+ converted = 1;
+ }
+ else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ {
+ tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+ const_op1 = maybe_constant_value (const_op1);
+ if (TREE_CODE (const_op1) != INTEGER_CST)
+ const_op1 = op1;
+ result_type = type0;
+ doing_shift = true;
+ if (TREE_CODE (const_op1) == INTEGER_CST)
+ {
+ if (tree_int_cst_lt (const_op1, integer_zero_node))
+ {
+ if ((complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
+ warning (0, "right shift count is negative");
+ }
+ else
+ {
+ if (compare_tree_int (const_op1, TYPE_PRECISION (type0)) >= 0
+ && (complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
+ warning (0, "right shift count >= width of type");
+ }
+ }
+ /* Convert the shift-count to an integer, regardless of
+ size of value being shifted. */
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
+ op1 = cp_convert (integer_type_node, op1, complain);
+ /* Avoid converting op1 to result_type later. */
+ converted = 1;
+ }
+ break;
+
+ case LSHIFT_EXPR:
+ if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
+ {
+ result_type = type0;
+ converted = 1;
+ }
+ else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
+ && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1))
+ {
+ result_type = type0;
+ converted = 1;
+ }
+ else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ {
+ tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+ const_op1 = maybe_constant_value (const_op1);
+ if (TREE_CODE (const_op1) != INTEGER_CST)
+ const_op1 = op1;
+ result_type = type0;
+ doing_shift = true;
+ if (TREE_CODE (const_op1) == INTEGER_CST)
+ {
+ if (tree_int_cst_lt (const_op1, integer_zero_node))
+ {
+ if ((complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
+ warning (0, "left shift count is negative");
+ }
+ else if (compare_tree_int (const_op1,
+ TYPE_PRECISION (type0)) >= 0)
+ {
+ if ((complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
+ warning (0, "left shift count >= width of type");
+ }
+ }
+ /* Convert the shift-count to an integer, regardless of
+ size of value being shifted. */
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
+ op1 = cp_convert (integer_type_node, op1, complain);
+ /* Avoid converting op1 to result_type later. */
+ converted = 1;
+ }
+ break;
+
+ case RROTATE_EXPR:
+ case LROTATE_EXPR:
+ if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ {
+ result_type = type0;
+ if (TREE_CODE (op1) == INTEGER_CST)
+ {
+ if (tree_int_cst_lt (op1, integer_zero_node))
+ {
+ if (complain & tf_warning)
+ warning (0, (code == LROTATE_EXPR)
+ ? G_("left rotate count is negative")
+ : G_("right rotate count is negative"));
+ }
+ else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
+ {
+ if (complain & tf_warning)
+ warning (0, (code == LROTATE_EXPR)
+ ? G_("left rotate count >= width of type")
+ : G_("right rotate count >= width of type"));
+ }
+ }
+ /* Convert the shift-count to an integer, regardless of
+ size of value being shifted. */
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
+ op1 = cp_convert (integer_type_node, op1, complain);
+ }
+ break;
+
+ case EQ_EXPR:
+ case NE_EXPR:
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
+ goto vector_compare;
+ if ((complain & tf_warning)
+ && (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)))
+ warning (OPT_Wfloat_equal,
+ "comparing floating point with == or != is unsafe");
+ if ((complain & tf_warning)
+ && ((TREE_CODE (orig_op0) == STRING_CST && !integer_zerop (op1))
+ || (TREE_CODE (orig_op1) == STRING_CST && !integer_zerop (op0))))
+ warning (OPT_Waddress, "comparison with string literal results in unspecified behaviour");
+
+ build_type = boolean_type_node;
+ if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
+ || code0 == COMPLEX_TYPE || code0 == ENUMERAL_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
+ || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE))
+ short_compare = 1;
+ else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
+ || (TYPE_PTRDATAMEM_P (type0) && TYPE_PTRDATAMEM_P (type1)))
+ result_type = composite_pointer_type (type0, type1, op0, op1,
+ CPO_COMPARISON, complain);
+ else if ((code0 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type0))
+ && null_ptr_cst_p (op1))
+ {
+ if (TREE_CODE (op0) == ADDR_EXPR
+ && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
+ {
+ if ((complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
+ warning (OPT_Waddress, "the address of %qD will never be NULL",
+ TREE_OPERAND (op0, 0));
+ }
+ result_type = type0;
+ }
+ else if ((code1 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type1))
+ && null_ptr_cst_p (op0))
+ {
+ if (TREE_CODE (op1) == ADDR_EXPR
+ && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
+ {
+ if ((complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
+ warning (OPT_Waddress, "the address of %qD will never be NULL",
+ TREE_OPERAND (op1, 0));
+ }
+ result_type = type1;
+ }
+ else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1))
+ /* One of the operands must be of nullptr_t type. */
+ result_type = TREE_TYPE (nullptr_node);
+ else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+ {
+ result_type = type0;
+ if (complain & tf_error)
+ permerror (input_location, "ISO C++ forbids comparison between pointer and integer");
+ else
+ return error_mark_node;
+ }
+ else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
+ {
+ result_type = type1;
+ if (complain & tf_error)
+ permerror (input_location, "ISO C++ forbids comparison between pointer and integer");
+ else
+ return error_mark_node;
+ }
+ else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (op1))
+ {
+ if (TARGET_PTRMEMFUNC_VBIT_LOCATION
+ == ptrmemfunc_vbit_in_delta)
+ {
+ tree pfn0, delta0, e1, e2;
+
+ if (TREE_SIDE_EFFECTS (op0))
+ op0 = save_expr (op0);
+
+ pfn0 = pfn_from_ptrmemfunc (op0);
+ delta0 = delta_from_ptrmemfunc (op0);
+ e1 = cp_build_binary_op (location,
+ EQ_EXPR,
+ pfn0,
+ build_zero_cst (TREE_TYPE (pfn0)),
+ complain);
+ e2 = cp_build_binary_op (location,
+ BIT_AND_EXPR,
+ delta0,
+ integer_one_node,
+ complain);
+
+ if (complain & tf_warning)
+ maybe_warn_zero_as_null_pointer_constant (op1, input_location);
+
+ e2 = cp_build_binary_op (location,
+ EQ_EXPR, e2, integer_zero_node,
+ complain);
+ op0 = cp_build_binary_op (location,
+ TRUTH_ANDIF_EXPR, e1, e2,
+ complain);
+ op1 = cp_convert (TREE_TYPE (op0), integer_one_node, complain);
+ }
+ else
+ {
+ op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
+ op1 = cp_convert (TREE_TYPE (op0), op1, complain);
+ }
+ result_type = TREE_TYPE (op0);
+ }
+ else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (op0))
+ return cp_build_binary_op (location, code, op1, op0, complain);
+ else if (TYPE_PTRMEMFUNC_P (type0) && TYPE_PTRMEMFUNC_P (type1))
+ {
+ tree type;
+ /* E will be the final comparison. */
+ tree e;
+ /* E1 and E2 are for scratch. */
+ tree e1;
+ tree e2;
+ tree pfn0;
+ tree pfn1;
+ tree delta0;
+ tree delta1;
+
+ type = composite_pointer_type (type0, type1, op0, op1,
+ CPO_COMPARISON, complain);
+
+ if (!same_type_p (TREE_TYPE (op0), type))
+ op0 = cp_convert_and_check (type, op0, complain);
+ if (!same_type_p (TREE_TYPE (op1), type))
+ op1 = cp_convert_and_check (type, op1, complain);
+
+ if (op0 == error_mark_node || op1 == error_mark_node)
+ return error_mark_node;
+
+ if (TREE_SIDE_EFFECTS (op0))
+ op0 = save_expr (op0);
+ if (TREE_SIDE_EFFECTS (op1))
+ op1 = save_expr (op1);
+
+ pfn0 = pfn_from_ptrmemfunc (op0);
+ pfn1 = pfn_from_ptrmemfunc (op1);
+ delta0 = delta_from_ptrmemfunc (op0);
+ delta1 = delta_from_ptrmemfunc (op1);
+ if (TARGET_PTRMEMFUNC_VBIT_LOCATION
+ == ptrmemfunc_vbit_in_delta)
+ {
+ /* We generate:
+
+ (op0.pfn == op1.pfn
+ && ((op0.delta == op1.delta)
+ || (!op0.pfn && op0.delta & 1 == 0
+ && op1.delta & 1 == 0))
+
+ The reason for the `!op0.pfn' bit is that a NULL
+ pointer-to-member is any member with a zero PFN and
+ LSB of the DELTA field is 0. */
+
+ e1 = cp_build_binary_op (location, BIT_AND_EXPR,
+ delta0,
+ integer_one_node,
+ complain);
+ e1 = cp_build_binary_op (location,
+ EQ_EXPR, e1, integer_zero_node,
+ complain);
+ e2 = cp_build_binary_op (location, BIT_AND_EXPR,
+ delta1,
+ integer_one_node,
+ complain);
+ e2 = cp_build_binary_op (location,
+ EQ_EXPR, e2, integer_zero_node,
+ complain);
+ e1 = cp_build_binary_op (location,
+ TRUTH_ANDIF_EXPR, e2, e1,
+ complain);
+ e2 = cp_build_binary_op (location, EQ_EXPR,
+ pfn0,
+ build_zero_cst (TREE_TYPE (pfn0)),
+ complain);
+ e2 = cp_build_binary_op (location,
+ TRUTH_ANDIF_EXPR, e2, e1, complain);
+ e1 = cp_build_binary_op (location,
+ EQ_EXPR, delta0, delta1, complain);
+ e1 = cp_build_binary_op (location,
+ TRUTH_ORIF_EXPR, e1, e2, complain);
+ }
+ else
+ {
+ /* We generate:
+
+ (op0.pfn == op1.pfn
+ && (!op0.pfn || op0.delta == op1.delta))
+
+ The reason for the `!op0.pfn' bit is that a NULL
+ pointer-to-member is any member with a zero PFN; the
+ DELTA field is unspecified. */
+
+ e1 = cp_build_binary_op (location,
+ EQ_EXPR, delta0, delta1, complain);
+ e2 = cp_build_binary_op (location,
+ EQ_EXPR,
+ pfn0,
+ build_zero_cst (TREE_TYPE (pfn0)),
+ complain);
+ e1 = cp_build_binary_op (location,
+ TRUTH_ORIF_EXPR, e1, e2, complain);
+ }
+ e2 = build2 (EQ_EXPR, boolean_type_node, pfn0, pfn1);
+ e = cp_build_binary_op (location,
+ TRUTH_ANDIF_EXPR, e2, e1, complain);
+ if (code == EQ_EXPR)
+ return e;
+ return cp_build_binary_op (location,
+ EQ_EXPR, e, integer_zero_node, complain);
+ }
+ else
+ {
+ gcc_assert (!TYPE_PTRMEMFUNC_P (type0)
+ || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type0),
+ type1));
+ gcc_assert (!TYPE_PTRMEMFUNC_P (type1)
+ || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type1),
+ type0));
+ }
+
+ break;
+
+ case MAX_EXPR:
+ case MIN_EXPR:
+ if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
+ shorten = 1;
+ else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
+ result_type = composite_pointer_type (type0, type1, op0, op1,
+ CPO_COMPARISON, complain);
+ break;
+
+ case LE_EXPR:
+ case GE_EXPR:
+ case LT_EXPR:
+ case GT_EXPR:
+ if (TREE_CODE (orig_op0) == STRING_CST
+ || TREE_CODE (orig_op1) == STRING_CST)
+ {
+ if (complain & tf_warning)
+ warning (OPT_Waddress, "comparison with string literal results in unspecified behaviour");
+ }
+
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
+ {
+ vector_compare:
+ tree intt;
+ if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
+ TREE_TYPE (type1))
+ && !vector_types_compatible_elements_p (type0, type1))
+ {
+ if (complain & tf_error)
+ {
+ error_at (location, "comparing vectors with different "
+ "element types");
+ inform (location, "operand types are %qT and %qT",
+ type0, type1);
+ }
+ return error_mark_node;
+ }
+
+ if (TYPE_VECTOR_SUBPARTS (type0) != TYPE_VECTOR_SUBPARTS (type1))
+ {
+ if (complain & tf_error)
+ {
+ error_at (location, "comparing vectors with different "
+ "number of elements");
+ inform (location, "operand types are %qT and %qT",
+ type0, type1);
+ }
+ return error_mark_node;
+ }
+
+ /* Always construct signed integer vector type. */
+ intt = c_common_type_for_size (GET_MODE_BITSIZE
+ (TYPE_MODE (TREE_TYPE (type0))), 0);
+ if (!intt)
+ {
+ if (complain & tf_error)
+ error_at (location, "could not find an integer type "
+ "of the same size as %qT", TREE_TYPE (type0));
+ return error_mark_node;
+ }
+ result_type = build_opaque_vector_type (intt,
+ TYPE_VECTOR_SUBPARTS (type0));
+ converted = 1;
+ break;
+ }
+ build_type = boolean_type_node;
+ if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
+ || code0 == ENUMERAL_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
+ || code1 == ENUMERAL_TYPE))
+ short_compare = 1;
+ else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
+ result_type = composite_pointer_type (type0, type1, op0, op1,
+ CPO_COMPARISON, complain);
+ else if (code0 == POINTER_TYPE && null_ptr_cst_p (op1))
+ {
+ result_type = type0;
+ if (extra_warnings && (complain & tf_warning))
+ warning (OPT_Wextra,
+ "ordered comparison of pointer with integer zero");
+ }
+ else if (code1 == POINTER_TYPE && null_ptr_cst_p (op0))
+ {
+ result_type = type1;
+ if (extra_warnings && (complain & tf_warning))
+ warning (OPT_Wextra,
+ "ordered comparison of pointer with integer zero");
+ }
+ else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1))
+ /* One of the operands must be of nullptr_t type. */
+ result_type = TREE_TYPE (nullptr_node);
+ else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+ {
+ result_type = type0;
+ if (complain & tf_error)
+ permerror (input_location, "ISO C++ forbids comparison between pointer and integer");
+ else
+ return error_mark_node;
+ }
+ else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
+ {
+ result_type = type1;
+ if (complain & tf_error)
+ permerror (input_location, "ISO C++ forbids comparison between pointer and integer");
+ else
+ return error_mark_node;
+ }
+ break;
+
+ case UNORDERED_EXPR:
+ case ORDERED_EXPR:
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ build_type = integer_type_node;
+ if (code0 != REAL_TYPE || code1 != REAL_TYPE)
+ {
+ if (complain & tf_error)
+ error ("unordered comparison on non-floating point argument");
+ return error_mark_node;
+ }
+ common = 1;
+ break;
+
+ default:
+ break;
+ }
+
+ if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
+ || code0 == ENUMERAL_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
+ || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE)))
+ arithmetic_types_p = 1;
+ else
+ {
+ arithmetic_types_p = 0;
+ /* Vector arithmetic is only allowed when both sides are vectors. */
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
+ {
+ if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
+ || !vector_types_compatible_elements_p (type0, type1))
+ {
+ if (complain & tf_error)
+ binary_op_error (location, code, type0, type1);
+ return error_mark_node;
+ }
+ arithmetic_types_p = 1;
+ }
+ }
+ /* Determine the RESULT_TYPE, if it is not already known. */
+ if (!result_type
+ && arithmetic_types_p
+ && (shorten || common || short_compare))
+ {
+ result_type = cp_common_type (type0, type1);
+ if (complain & tf_warning)
+ do_warn_double_promotion (result_type, type0, type1,
+ "implicit conversion from %qT to %qT "
+ "to match other operand of binary "
+ "expression",
+ location);
+ }
+
+ if (!result_type)
+ {
+ if (complain & tf_error)
+ error ("invalid operands of types %qT and %qT to binary %qO",
+ TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
+ return error_mark_node;
+ }
+
+ /* If we're in a template, the only thing we need to know is the
+ RESULT_TYPE. */
+ if (processing_template_decl)
+ {
+ /* Since the middle-end checks the type when doing a build2, we
+ need to build the tree in pieces. This built tree will never
+ get out of the front-end as we replace it when instantiating
+ the template. */
+ tree tmp = build2 (resultcode,
+ build_type ? build_type : result_type,
+ NULL_TREE, op1);
+ TREE_OPERAND (tmp, 0) = op0;
+ return tmp;
+ }
+
+ if (arithmetic_types_p)
+ {
+ bool first_complex = (code0 == COMPLEX_TYPE);
+ bool second_complex = (code1 == COMPLEX_TYPE);
+ int none_complex = (!first_complex && !second_complex);
+
+ /* Adapted from patch for c/24581. */
+ if (first_complex != second_complex
+ && (code == PLUS_EXPR
+ || code == MINUS_EXPR
+ || code == MULT_EXPR
+ || (code == TRUNC_DIV_EXPR && first_complex))
+ && TREE_CODE (TREE_TYPE (result_type)) == REAL_TYPE
+ && flag_signed_zeros)
+ {
+ /* An operation on mixed real/complex operands must be
+ handled specially, but the language-independent code can
+ more easily optimize the plain complex arithmetic if
+ -fno-signed-zeros. */
+ tree real_type = TREE_TYPE (result_type);
+ tree real, imag;
+ if (first_complex)
+ {
+ if (TREE_TYPE (op0) != result_type)
+ op0 = cp_convert_and_check (result_type, op0, complain);
+ if (TREE_TYPE (op1) != real_type)
+ op1 = cp_convert_and_check (real_type, op1, complain);
+ }
+ else
+ {
+ if (TREE_TYPE (op0) != real_type)
+ op0 = cp_convert_and_check (real_type, op0, complain);
+ if (TREE_TYPE (op1) != result_type)
+ op1 = cp_convert_and_check (result_type, op1, complain);
+ }
+ if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
+ return error_mark_node;
+ if (first_complex)
+ {
+ op0 = save_expr (op0);
+ real = cp_build_unary_op (REALPART_EXPR, op0, 1, complain);
+ imag = cp_build_unary_op (IMAGPART_EXPR, op0, 1, complain);
+ switch (code)
+ {
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ op1 = save_expr (op1);
+ imag = build2 (resultcode, real_type, imag, op1);
+ /* Fall through. */
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ real = build2 (resultcode, real_type, real, op1);
+ break;
+ default:
+ gcc_unreachable();
+ }
+ }
+ else
+ {
+ op1 = save_expr (op1);
+ real = cp_build_unary_op (REALPART_EXPR, op1, 1, complain);
+ imag = cp_build_unary_op (IMAGPART_EXPR, op1, 1, complain);
+ switch (code)
+ {
+ case MULT_EXPR:
+ op0 = save_expr (op0);
+ imag = build2 (resultcode, real_type, op0, imag);
+ /* Fall through. */
+ case PLUS_EXPR:
+ real = build2 (resultcode, real_type, op0, real);
+ break;
+ case MINUS_EXPR:
+ real = build2 (resultcode, real_type, op0, real);
+ imag = build1 (NEGATE_EXPR, real_type, imag);
+ break;
+ default:
+ gcc_unreachable();
+ }
+ }
+ real = fold_if_not_in_template (real);
+ imag = fold_if_not_in_template (imag);
+ result = build2 (COMPLEX_EXPR, result_type, real, imag);
+ result = fold_if_not_in_template (result);
+ return result;
+ }
+
+ /* For certain operations (which identify themselves by shorten != 0)
+ if both args were extended from the same smaller type,
+ do the arithmetic in that type and then extend.
+
+ shorten !=0 and !=1 indicates a bitwise operation.
+ For them, this optimization is safe only if
+ both args are zero-extended or both are sign-extended.
+ Otherwise, we might change the result.
+ E.g., (short)-1 | (unsigned short)-1 is (int)-1
+ but calculated in (unsigned short) it would be (unsigned short)-1. */
+
+ if (shorten && none_complex)
+ {
+ orig_type = result_type;
+ final_type = result_type;
+ result_type = shorten_binary_op (result_type, op0, op1,
+ shorten == -1);
+ }
+
+ /* Comparison operations are shortened too but differently.
+ They identify themselves by setting short_compare = 1. */
+
+ if (short_compare)
+ {
+ /* Don't write &op0, etc., because that would prevent op0
+ from being kept in a register.
+ Instead, make copies of the our local variables and
+ pass the copies by reference, then copy them back afterward. */
+ tree xop0 = op0, xop1 = op1, xresult_type = result_type;
+ enum tree_code xresultcode = resultcode;
+ tree val
+ = shorten_compare (location, &xop0, &xop1, &xresult_type,
+ &xresultcode);
+ if (val != 0)
+ return cp_convert (boolean_type_node, val, complain);
+ op0 = xop0, op1 = xop1;
+ converted = 1;
+ resultcode = xresultcode;
+ }
+
+ if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
+ && warn_sign_compare
+ /* Do not warn until the template is instantiated; we cannot
+ bound the ranges of the arguments until that point. */
+ && !processing_template_decl
+ && (complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0
+ /* Even unsigned enum types promote to signed int. We don't
+ want to issue -Wsign-compare warnings for this case. */
+ && !enum_cast_to_int (orig_op0)
+ && !enum_cast_to_int (orig_op1))
+ {
+ tree oop0 = maybe_constant_value (orig_op0);
+ tree oop1 = maybe_constant_value (orig_op1);
+
+ if (TREE_CODE (oop0) != INTEGER_CST)
+ oop0 = orig_op0;
+ if (TREE_CODE (oop1) != INTEGER_CST)
+ oop1 = orig_op1;
+ warn_for_sign_compare (location, oop0, oop1, op0, op1,
+ result_type, resultcode);
+ }
+ }
+
+ /* If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
+ Then the expression will be built.
+ It will be given type FINAL_TYPE if that is nonzero;
+ otherwise, it will be given type RESULT_TYPE. */
+ if (! converted)
+ {
+ if (TREE_TYPE (op0) != result_type)
+ op0 = cp_convert_and_check (result_type, op0, complain);
+ if (TREE_TYPE (op1) != result_type)
+ op1 = cp_convert_and_check (result_type, op1, complain);
+
+ if (op0 == error_mark_node || op1 == error_mark_node)
+ return error_mark_node;
+ }
+
+ if (build_type == NULL_TREE)
+ build_type = result_type;
+
+ if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE))
+ && !processing_template_decl
+ && current_function_decl != 0
+ && !lookup_attribute ("no_sanitize_undefined",
+ DECL_ATTRIBUTES (current_function_decl))
+ && (doing_div_or_mod || doing_shift))
+ {
+ /* OP0 and/or OP1 might have side-effects. */
+ op0 = cp_save_expr (op0);
+ op1 = cp_save_expr (op1);
+ op0 = maybe_constant_value (fold_non_dependent_expr_sfinae (op0,
+ tf_none));
+ op1 = maybe_constant_value (fold_non_dependent_expr_sfinae (op1,
+ tf_none));
+ if (doing_div_or_mod && (flag_sanitize & SANITIZE_DIVIDE))
+ {
+ /* For diagnostics we want to use the promoted types without
+ shorten_binary_op. So convert the arguments to the
+ original result_type. */
+ tree cop0 = op0;
+ tree cop1 = op1;
+ if (orig_type != NULL && result_type != orig_type)
+ {
+ cop0 = cp_convert (orig_type, op0, complain);
+ cop1 = cp_convert (orig_type, op1, complain);
+ }
+ instrument_expr = ubsan_instrument_division (location, cop0, cop1);
+ }
+ else if (doing_shift && (flag_sanitize & SANITIZE_SHIFT))
+ instrument_expr = ubsan_instrument_shift (location, code, op0, op1);
+ }
+
+ result = build2 (resultcode, build_type, op0, op1);
+ result = fold_if_not_in_template (result);
+ if (final_type != 0)
+ result = cp_convert (final_type, result, complain);
+
+ if (TREE_OVERFLOW_P (result)
+ && !TREE_OVERFLOW_P (op0)
+ && !TREE_OVERFLOW_P (op1))
+ overflow_warning (location, result);
+
+ if (instrument_expr != NULL)
+ result = fold_build2 (COMPOUND_EXPR, TREE_TYPE (result),
+ instrument_expr, result);
+
+ return result;
+}
+
+/* Build a VEC_PERM_EXPR.
+ This is a simple wrapper for c_build_vec_perm_expr. */
+tree
+build_x_vec_perm_expr (location_t loc,
+ tree arg0, tree arg1, tree arg2,
+ tsubst_flags_t complain)
+{
+ tree orig_arg0 = arg0;
+ tree orig_arg1 = arg1;
+ tree orig_arg2 = arg2;
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (arg0)
+ || type_dependent_expression_p (arg1)
+ || type_dependent_expression_p (arg2))
+ return build_min_nt_loc (loc, VEC_PERM_EXPR, arg0, arg1, arg2);
+ arg0 = build_non_dependent_expr (arg0);
+ if (arg1)
+ arg1 = build_non_dependent_expr (arg1);
+ arg2 = build_non_dependent_expr (arg2);
+ }
+ tree exp = c_build_vec_perm_expr (loc, arg0, arg1, arg2, complain & tf_error);
+ if (processing_template_decl && exp != error_mark_node)
+ return build_min_non_dep (VEC_PERM_EXPR, exp, orig_arg0,
+ orig_arg1, orig_arg2);
+ return exp;
+}
+
+/* Return a tree for the sum or difference (RESULTCODE says which)
+ of pointer PTROP and integer INTOP. */
+
+static tree
+cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
+ tsubst_flags_t complain)
+{
+ tree res_type = TREE_TYPE (ptrop);
+
+ /* pointer_int_sum() uses size_in_bytes() on the TREE_TYPE(res_type)
+ in certain circumstance (when it's valid to do so). So we need
+ to make sure it's complete. We don't need to check here, if we
+ can actually complete it at all, as those checks will be done in
+ pointer_int_sum() anyway. */
+ complete_type (TREE_TYPE (res_type));
+
+ return pointer_int_sum (input_location, resultcode, ptrop,
+ fold_if_not_in_template (intop),
+ complain & tf_warning_or_error);
+}
+
+/* Return a tree for the difference of pointers OP0 and OP1.
+ The resulting tree has type int. */
+
+static tree
+pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
+{
+ tree result;
+ tree restype = ptrdiff_type_node;
+ tree target_type = TREE_TYPE (ptrtype);
+
+ if (!complete_type_or_else (target_type, NULL_TREE))
+ return error_mark_node;
+
+ if (VOID_TYPE_P (target_type))
+ {
+ if (complain & tf_error)
+ permerror (input_location, "ISO C++ forbids using pointer of "
+ "type %<void *%> in subtraction");
+ else
+ return error_mark_node;
+ }
+ if (TREE_CODE (target_type) == FUNCTION_TYPE)
+ {
+ if (complain & tf_error)
+ permerror (input_location, "ISO C++ forbids using pointer to "
+ "a function in subtraction");
+ else
+ return error_mark_node;
+ }
+ if (TREE_CODE (target_type) == METHOD_TYPE)
+ {
+ if (complain & tf_error)
+ permerror (input_location, "ISO C++ forbids using pointer to "
+ "a method in subtraction");
+ else
+ return error_mark_node;
+ }
+
+ /* First do the subtraction as integers;
+ then drop through to build the divide operator. */
+
+ op0 = cp_build_binary_op (input_location,
+ MINUS_EXPR,
+ cp_convert (restype, op0, complain),
+ cp_convert (restype, op1, complain),
+ complain);
+
+ /* This generates an error if op1 is a pointer to an incomplete type. */
+ if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
+ {
+ if (complain & tf_error)
+ error ("invalid use of a pointer to an incomplete type in "
+ "pointer arithmetic");
+ else
+ return error_mark_node;
+ }
+
+ if (pointer_to_zero_sized_aggr_p (TREE_TYPE (op1)))
+ {
+ if (complain & tf_error)
+ error ("arithmetic on pointer to an empty aggregate");
+ else
+ return error_mark_node;
+ }
+
+ op1 = (TYPE_PTROB_P (ptrtype)
+ ? size_in_bytes (target_type)
+ : integer_one_node);
+
+ /* Do the division. */
+
+ result = build2 (EXACT_DIV_EXPR, restype, op0,
+ cp_convert (restype, op1, complain));
+ return fold_if_not_in_template (result);
+}
+
+/* Construct and perhaps optimize a tree representation
+ for a unary operation. CODE, a tree_code, specifies the operation
+ and XARG is the operand. */
+
+tree
+build_x_unary_op (location_t loc, enum tree_code code, tree xarg,
+ tsubst_flags_t complain)
+{
+ tree orig_expr = xarg;
+ tree exp;
+ int ptrmem = 0;
+
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (xarg))
+ return build_min_nt_loc (loc, code, xarg, NULL_TREE);
+
+ xarg = build_non_dependent_expr (xarg);
+ }
+
+ exp = NULL_TREE;
+
+ /* [expr.unary.op] says:
+
+ The address of an object of incomplete type can be taken.
+
+ (And is just the ordinary address operator, not an overloaded
+ "operator &".) However, if the type is a template
+ specialization, we must complete the type at this point so that
+ an overloaded "operator &" will be available if required. */
+ if (code == ADDR_EXPR
+ && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
+ && ((CLASS_TYPE_P (TREE_TYPE (xarg))
+ && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
+ || (TREE_CODE (xarg) == OFFSET_REF)))
+ /* Don't look for a function. */;
+ else
+ exp = build_new_op (loc, code, LOOKUP_NORMAL, xarg, NULL_TREE,
+ NULL_TREE, /*overload=*/NULL, complain);
+ if (!exp && code == ADDR_EXPR)
+ {
+ if (is_overloaded_fn (xarg))
+ {
+ tree fn = get_first_fn (xarg);
+ if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
+ {
+ if (complain & tf_error)
+ error (DECL_CONSTRUCTOR_P (fn)
+ ? G_("taking address of constructor %qE")
+ : G_("taking address of destructor %qE"),
+ xarg);
+ return error_mark_node;
+ }
+ }
+
+ /* A pointer to member-function can be formed only by saying
+ &X::mf. */
+ if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
+ && (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg)))
+ {
+ if (TREE_CODE (xarg) != OFFSET_REF
+ || !TYPE_P (TREE_OPERAND (xarg, 0)))
+ {
+ if (complain & tf_error)
+ {
+ error ("invalid use of %qE to form a "
+ "pointer-to-member-function", xarg);
+ if (TREE_CODE (xarg) != OFFSET_REF)
+ inform (input_location, " a qualified-id is required");
+ }
+ return error_mark_node;
+ }
+ else
+ {
+ if (complain & tf_error)
+ error ("parentheses around %qE cannot be used to form a"
+ " pointer-to-member-function",
+ xarg);
+ else
+ return error_mark_node;
+ PTRMEM_OK_P (xarg) = 1;
+ }
+ }
+
+ if (TREE_CODE (xarg) == OFFSET_REF)
+ {
+ ptrmem = PTRMEM_OK_P (xarg);
+
+ if (!ptrmem && !flag_ms_extensions
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
+ {
+ /* A single non-static member, make sure we don't allow a
+ pointer-to-member. */
+ xarg = build2 (OFFSET_REF, TREE_TYPE (xarg),
+ TREE_OPERAND (xarg, 0),
+ ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE));
+ PTRMEM_OK_P (xarg) = ptrmem;
+ }
+ }
+
+ exp = cp_build_addr_expr_strict (xarg, complain);
+ }
+
+ if (processing_template_decl && exp != error_mark_node)
+ exp = build_min_non_dep (code, exp, orig_expr,
+ /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
+ if (TREE_CODE (exp) == ADDR_EXPR)
+ PTRMEM_OK_P (exp) = ptrmem;
+ return exp;
+}
+
+/* Like c_common_truthvalue_conversion, but handle pointer-to-member
+ constants, where a null value is represented by an INTEGER_CST of
+ -1. */
+
+tree
+cp_truthvalue_conversion (tree expr)
+{
+ tree type = TREE_TYPE (expr);
+ if (TYPE_PTRDATAMEM_P (type)
+ /* Avoid ICE on invalid use of non-static member function. */
+ || TREE_CODE (expr) == FUNCTION_DECL)
+ return build_binary_op (EXPR_LOCATION (expr),
+ NE_EXPR, expr, nullptr_node, 1);
+ else if (TYPE_PTR_P (type) || TYPE_PTRMEMFUNC_P (type))
+ {
+ /* With -Wzero-as-null-pointer-constant do not warn for an
+ 'if (p)' or a 'while (!p)', where p is a pointer. */
+ tree ret;
+ ++c_inhibit_evaluation_warnings;
+ ret = c_common_truthvalue_conversion (input_location, expr);
+ --c_inhibit_evaluation_warnings;
+ return ret;
+ }
+ else
+ return c_common_truthvalue_conversion (input_location, expr);
+}
+
+/* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR. */
+
+tree
+condition_conversion (tree expr)
+{
+ tree t;
+ if (processing_template_decl)
+ return expr;
+ t = perform_implicit_conversion_flags (boolean_type_node, expr,
+ tf_warning_or_error, LOOKUP_NORMAL);
+ t = fold_build_cleanup_point_expr (boolean_type_node, t);
+ return t;
+}
+
+/* Returns the address of T. This function will fold away
+ ADDR_EXPR of INDIRECT_REF. */
+
+tree
+build_address (tree t)
+{
+ if (error_operand_p (t) || !cxx_mark_addressable (t))
+ return error_mark_node;
+ t = build_fold_addr_expr (t);
+ if (TREE_CODE (t) != ADDR_EXPR)
+ t = rvalue (t);
+ return t;
+}
+
+/* Returns the address of T with type TYPE. */
+
+tree
+build_typed_address (tree t, tree type)
+{
+ if (error_operand_p (t) || !cxx_mark_addressable (t))
+ return error_mark_node;
+ t = build_fold_addr_expr_with_type (t, type);
+ if (TREE_CODE (t) != ADDR_EXPR)
+ t = rvalue (t);
+ return t;
+}
+
+/* Return a NOP_EXPR converting EXPR to TYPE. */
+
+tree
+build_nop (tree type, tree expr)
+{
+ if (type == error_mark_node || error_operand_p (expr))
+ return expr;
+ return build1 (NOP_EXPR, type, expr);
+}
+
+/* Take the address of ARG, whatever that means under C++ semantics.
+ If STRICT_LVALUE is true, require an lvalue; otherwise, allow xvalues
+ and class rvalues as well.
+
+ Nothing should call this function directly; instead, callers should use
+ cp_build_addr_expr or cp_build_addr_expr_strict. */
+
+static tree
+cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
+{
+ tree argtype;
+ tree val;
+
+ if (!arg || error_operand_p (arg))
+ return error_mark_node;
+
+ arg = mark_lvalue_use (arg);
+ argtype = lvalue_type (arg);
+
+ gcc_assert (!identifier_p (arg) || !IDENTIFIER_OPNAME_P (arg));
+
+ if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
+ && !really_overloaded_fn (TREE_OPERAND (arg, 1)))
+ {
+ /* They're trying to take the address of a unique non-static
+ member function. This is ill-formed (except in MS-land),
+ but let's try to DTRT.
+ Note: We only handle unique functions here because we don't
+ want to complain if there's a static overload; non-unique
+ cases will be handled by instantiate_type. But we need to
+ handle this case here to allow casts on the resulting PMF.
+ We could defer this in non-MS mode, but it's easier to give
+ a useful error here. */
+
+ /* Inside constant member functions, the `this' pointer
+ contains an extra const qualifier. TYPE_MAIN_VARIANT
+ is used here to remove this const from the diagnostics
+ and the created OFFSET_REF. */
+ tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0)));
+ tree fn = get_first_fn (TREE_OPERAND (arg, 1));
+ mark_used (fn);
+
+ if (! flag_ms_extensions)
+ {
+ tree name = DECL_NAME (fn);
+ if (!(complain & tf_error))
+ return error_mark_node;
+ else if (current_class_type
+ && TREE_OPERAND (arg, 0) == current_class_ref)
+ /* An expression like &memfn. */
+ permerror (input_location, "ISO C++ forbids taking the address of an unqualified"
+ " or parenthesized non-static member function to form"
+ " a pointer to member function. Say %<&%T::%D%>",
+ base, name);
+ else
+ permerror (input_location, "ISO C++ forbids taking the address of a bound member"
+ " function to form a pointer to member function."
+ " Say %<&%T::%D%>",
+ base, name);
+ }
+ arg = build_offset_ref (base, fn, /*address_p=*/true, complain);
+ }
+
+ /* Uninstantiated types are all functions. Taking the
+ address of a function is a no-op, so just return the
+ argument. */
+ if (type_unknown_p (arg))
+ return build1 (ADDR_EXPR, unknown_type_node, arg);
+
+ if (TREE_CODE (arg) == OFFSET_REF)
+ /* We want a pointer to member; bypass all the code for actually taking
+ the address of something. */
+ goto offset_ref;
+
+ /* Anything not already handled and not a true memory reference
+ is an error. */
+ if (TREE_CODE (argtype) != FUNCTION_TYPE
+ && TREE_CODE (argtype) != METHOD_TYPE)
+ {
+ cp_lvalue_kind kind = lvalue_kind (arg);
+ if (kind == clk_none)
+ {
+ if (complain & tf_error)
+ lvalue_error (input_location, lv_addressof);
+ return error_mark_node;
+ }
+ if (strict_lvalue && (kind & (clk_rvalueref|clk_class)))
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+ if (kind & clk_class)
+ /* Make this a permerror because we used to accept it. */
+ permerror (input_location, "taking address of temporary");
+ else
+ error ("taking address of xvalue (rvalue reference)");
+ }
+ }
+
+ if (TREE_CODE (argtype) == REFERENCE_TYPE)
+ {
+ tree type = build_pointer_type (TREE_TYPE (argtype));
+ arg = build1 (CONVERT_EXPR, type, arg);
+ return arg;
+ }
+ else if (pedantic && DECL_MAIN_P (arg))
+ {
+ /* ARM $3.4 */
+ /* Apparently a lot of autoconf scripts for C++ packages do this,
+ so only complain if -Wpedantic. */
+ if (complain & (flag_pedantic_errors ? tf_error : tf_warning))
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ forbids taking address of function %<::main%>");
+ else if (flag_pedantic_errors)
+ return error_mark_node;
+ }
+
+ /* Let &* cancel out to simplify resulting code. */
+ if (INDIRECT_REF_P (arg))
+ {
+ /* We don't need to have `current_class_ptr' wrapped in a
+ NON_LVALUE_EXPR node. */
+ if (arg == current_class_ref)
+ return current_class_ptr;
+
+ arg = TREE_OPERAND (arg, 0);
+ if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
+ {
+ tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
+ arg = build1 (CONVERT_EXPR, type, arg);
+ }
+ else
+ /* Don't let this be an lvalue. */
+ arg = rvalue (arg);
+ return arg;
+ }
+
+ /* ??? Cope with user tricks that amount to offsetof. */
+ if (TREE_CODE (argtype) != FUNCTION_TYPE
+ && TREE_CODE (argtype) != METHOD_TYPE
+ && argtype != unknown_type_node
+ && (val = get_base_address (arg))
+ && COMPLETE_TYPE_P (TREE_TYPE (val))
+ && INDIRECT_REF_P (val)
+ && TREE_CONSTANT (TREE_OPERAND (val, 0)))
+ {
+ tree type = build_pointer_type (argtype);
+ return fold_convert (type, fold_offsetof_1 (arg));
+ }
+
+ /* Handle complex lvalues (when permitted)
+ by reduction to simpler cases. */
+ val = unary_complex_lvalue (ADDR_EXPR, arg);
+ if (val != 0)
+ return val;
+
+ switch (TREE_CODE (arg))
+ {
+ CASE_CONVERT:
+ case FLOAT_EXPR:
+ case FIX_TRUNC_EXPR:
+ /* Even if we're not being pedantic, we cannot allow this
+ extension when we're instantiating in a SFINAE
+ context. */
+ if (! lvalue_p (arg) && complain == tf_none)
+ {
+ if (complain & tf_error)
+ permerror (input_location, "ISO C++ forbids taking the address of a cast to a non-lvalue expression");
+ else
+ return error_mark_node;
+ }
+ break;
+
+ case BASELINK:
+ arg = BASELINK_FUNCTIONS (arg);
+ /* Fall through. */
+
+ case OVERLOAD:
+ arg = OVL_CURRENT (arg);
+ break;
+
+ case OFFSET_REF:
+ offset_ref:
+ /* Turn a reference to a non-static data member into a
+ pointer-to-member. */
+ {
+ tree type;
+ tree t;
+
+ gcc_assert (PTRMEM_OK_P (arg));
+
+ t = TREE_OPERAND (arg, 1);
+ if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
+ {
+ if (complain & tf_error)
+ error ("cannot create pointer to reference member %qD", t);
+ return error_mark_node;
+ }
+
+ type = build_ptrmem_type (context_for_name_lookup (t),
+ TREE_TYPE (t));
+ t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
+ return t;
+ }
+
+ default:
+ break;
+ }
+
+ if (argtype != error_mark_node)
+ {
+ if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (argtype)
+ && (flag_iso || warn_vla > 0))
+ {
+ if (complain & tf_warning_or_error)
+ pedwarn (input_location, OPT_Wvla,
+ "taking address of array of runtime bound");
+ else
+ return error_mark_node;
+ }
+ argtype = build_pointer_type (argtype);
+ }
+
+ /* In a template, we are processing a non-dependent expression
+ so we can just form an ADDR_EXPR with the correct type. */
+ if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
+ {
+ val = build_address (arg);
+ if (TREE_CODE (arg) == OFFSET_REF)
+ PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
+ }
+ else if (BASELINK_P (TREE_OPERAND (arg, 1)))
+ {
+ tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
+
+ /* We can only get here with a single static member
+ function. */
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_STATIC_FUNCTION_P (fn));
+ mark_used (fn);
+ val = build_address (fn);
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
+ /* Do not lose object's side effects. */
+ val = build2 (COMPOUND_EXPR, TREE_TYPE (val),
+ TREE_OPERAND (arg, 0), val);
+ }
+ else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
+ {
+ if (complain & tf_error)
+ error ("attempt to take address of bit-field structure member %qD",
+ TREE_OPERAND (arg, 1));
+ return error_mark_node;
+ }
+ else
+ {
+ tree object = TREE_OPERAND (arg, 0);
+ tree field = TREE_OPERAND (arg, 1);
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (object), decl_type_context (field)));
+ val = build_address (arg);
+ }
+
+ if (TYPE_PTR_P (argtype)
+ && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
+ {
+ build_ptrmemfunc_type (argtype);
+ val = build_ptrmemfunc (argtype, val, 0,
+ /*c_cast_p=*/false,
+ complain);
+ }
+
+ return val;
+}
+
+/* Take the address of ARG if it has one, even if it's an rvalue. */
+
+tree
+cp_build_addr_expr (tree arg, tsubst_flags_t complain)
+{
+ return cp_build_addr_expr_1 (arg, 0, complain);
+}
+
+/* Take the address of ARG, but only if it's an lvalue. */
+
+tree
+cp_build_addr_expr_strict (tree arg, tsubst_flags_t complain)
+{
+ return cp_build_addr_expr_1 (arg, 1, complain);
+}
+
+/* C++: Must handle pointers to members.
+
+ Perhaps type instantiation should be extended to handle conversion
+ from aggregates to types we don't yet know we want? (Or are those
+ cases typically errors which should be reported?)
+
+ NOCONVERT nonzero suppresses the default promotions
+ (such as from short to int). */
+
+tree
+cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
+ tsubst_flags_t complain)
+{
+ /* No default_conversion here. It causes trouble for ADDR_EXPR. */
+ tree arg = xarg;
+ tree argtype = 0;
+ const char *errstring = NULL;
+ tree val;
+ const char *invalid_op_diag;
+
+ if (!arg || error_operand_p (arg))
+ return error_mark_node;
+
+ if ((invalid_op_diag
+ = targetm.invalid_unary_op ((code == UNARY_PLUS_EXPR
+ ? CONVERT_EXPR
+ : code),
+ TREE_TYPE (xarg))))
+ {
+ if (complain & tf_error)
+ error (invalid_op_diag);
+ return error_mark_node;
+ }
+
+ switch (code)
+ {
+ case UNARY_PLUS_EXPR:
+ case NEGATE_EXPR:
+ {
+ int flags = WANT_ARITH | WANT_ENUM;
+ /* Unary plus (but not unary minus) is allowed on pointers. */
+ if (code == UNARY_PLUS_EXPR)
+ flags |= WANT_POINTER;
+ arg = build_expr_type_conversion (flags, arg, true);
+ if (!arg)
+ errstring = (code == NEGATE_EXPR
+ ? _("wrong type argument to unary minus")
+ : _("wrong type argument to unary plus"));
+ else
+ {
+ if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
+ arg = cp_perform_integral_promotions (arg, complain);
+
+ /* Make sure the result is not an lvalue: a unary plus or minus
+ expression is always a rvalue. */
+ arg = rvalue (arg);
+ }
+ }
+ break;
+
+ case BIT_NOT_EXPR:
+ if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
+ {
+ code = CONJ_EXPR;
+ if (!noconvert)
+ {
+ arg = cp_default_conversion (arg, complain);
+ if (arg == error_mark_node)
+ return error_mark_node;
+ }
+ }
+ else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM
+ | WANT_VECTOR_OR_COMPLEX,
+ arg, true)))
+ errstring = _("wrong type argument to bit-complement");
+ else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
+ arg = cp_perform_integral_promotions (arg, complain);
+ break;
+
+ case ABS_EXPR:
+ if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
+ errstring = _("wrong type argument to abs");
+ else if (!noconvert)
+ {
+ arg = cp_default_conversion (arg, complain);
+ if (arg == error_mark_node)
+ return error_mark_node;
+ }
+ break;
+
+ case CONJ_EXPR:
+ /* Conjugating a real value is a no-op, but allow it anyway. */
+ if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
+ errstring = _("wrong type argument to conjugation");
+ else if (!noconvert)
+ {
+ arg = cp_default_conversion (arg, complain);
+ if (arg == error_mark_node)
+ return error_mark_node;
+ }
+ break;
+
+ case TRUTH_NOT_EXPR:
+ arg = perform_implicit_conversion (boolean_type_node, arg,
+ complain);
+ val = invert_truthvalue_loc (input_location, arg);
+ if (arg != error_mark_node)
+ return val;
+ errstring = _("in argument to unary !");
+ break;
+
+ case NOP_EXPR:
+ break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ arg = build_real_imag_expr (input_location, code, arg);
+ if (arg == error_mark_node)
+ return arg;
+ else
+ return fold_if_not_in_template (arg);
+
+ case PREINCREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ /* Handle complex lvalues (when permitted)
+ by reduction to simpler cases. */
+
+ val = unary_complex_lvalue (code, arg);
+ if (val != 0)
+ return val;
+
+ arg = mark_lvalue_use (arg);
+
+ /* Increment or decrement the real part of the value,
+ and don't change the imaginary part. */
+ if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
+ {
+ tree real, imag;
+
+ arg = stabilize_reference (arg);
+ real = cp_build_unary_op (REALPART_EXPR, arg, 1, complain);
+ imag = cp_build_unary_op (IMAGPART_EXPR, arg, 1, complain);
+ real = cp_build_unary_op (code, real, 1, complain);
+ if (real == error_mark_node || imag == error_mark_node)
+ return error_mark_node;
+ return build2 (COMPLEX_EXPR, TREE_TYPE (arg),
+ real, imag);
+ }
+
+ /* Report invalid types. */
+
+ if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER,
+ arg, true)))
+ {
+ if (code == PREINCREMENT_EXPR)
+ errstring = _("no pre-increment operator for type");
+ else if (code == POSTINCREMENT_EXPR)
+ errstring = _("no post-increment operator for type");
+ else if (code == PREDECREMENT_EXPR)
+ errstring = _("no pre-decrement operator for type");
+ else
+ errstring = _("no post-decrement operator for type");
+ break;
+ }
+ else if (arg == error_mark_node)
+ return error_mark_node;
+
+ /* Report something read-only. */
+
+ if (CP_TYPE_CONST_P (TREE_TYPE (arg))
+ || TREE_READONLY (arg))
+ {
+ if (complain & tf_error)
+ cxx_readonly_error (arg, ((code == PREINCREMENT_EXPR
+ || code == POSTINCREMENT_EXPR)
+ ? lv_increment : lv_decrement));
+ else
+ return error_mark_node;
+ }
+
+ {
+ tree inc;
+ tree declared_type = unlowered_expr_type (arg);
+
+ argtype = TREE_TYPE (arg);
+
+ /* ARM $5.2.5 last annotation says this should be forbidden. */
+ if (TREE_CODE (argtype) == ENUMERAL_TYPE)
+ {
+ if (complain & tf_error)
+ permerror (input_location, (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
+ ? G_("ISO C++ forbids incrementing an enum")
+ : G_("ISO C++ forbids decrementing an enum"));
+ else
+ return error_mark_node;
+ }
+
+ /* Compute the increment. */
+
+ if (TYPE_PTR_P (argtype))
+ {
+ tree type = complete_type (TREE_TYPE (argtype));
+
+ if (!COMPLETE_OR_VOID_TYPE_P (type))
+ {
+ if (complain & tf_error)
+ error (((code == PREINCREMENT_EXPR
+ || code == POSTINCREMENT_EXPR))
+ ? G_("cannot increment a pointer to incomplete type %qT")
+ : G_("cannot decrement a pointer to incomplete type %qT"),
+ TREE_TYPE (argtype));
+ else
+ return error_mark_node;
+ }
+ else if (!TYPE_PTROB_P (argtype))
+ {
+ if (complain & tf_error)
+ pedwarn (input_location, OPT_Wpointer_arith,
+ (code == PREINCREMENT_EXPR
+ || code == POSTINCREMENT_EXPR)
+ ? G_("ISO C++ forbids incrementing a pointer of type %qT")
+ : G_("ISO C++ forbids decrementing a pointer of type %qT"),
+ argtype);
+ else
+ return error_mark_node;
+ }
+
+ inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
+ }
+ else
+ inc = VECTOR_TYPE_P (argtype)
+ ? build_one_cst (argtype)
+ : integer_one_node;
+
+ inc = cp_convert (argtype, inc, complain);
+
+ /* If 'arg' is an Objective-C PROPERTY_REF expression, then we
+ need to ask Objective-C to build the increment or decrement
+ expression for it. */
+ if (objc_is_property_ref (arg))
+ return objc_build_incr_expr_for_property_ref (input_location, code,
+ arg, inc);
+
+ /* Complain about anything else that is not a true lvalue. */
+ if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
+ || code == POSTINCREMENT_EXPR)
+ ? lv_increment : lv_decrement),
+ complain))
+ return error_mark_node;
+
+ /* Forbid using -- on `bool'. */
+ if (TREE_CODE (declared_type) == BOOLEAN_TYPE)
+ {
+ if (code == POSTDECREMENT_EXPR || code == PREDECREMENT_EXPR)
+ {
+ if (complain & tf_error)
+ error ("invalid use of Boolean expression as operand "
+ "to %<operator--%>");
+ return error_mark_node;
+ }
+ val = boolean_increment (code, arg);
+ }
+ else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
+ /* An rvalue has no cv-qualifiers. */
+ val = build2 (code, cv_unqualified (TREE_TYPE (arg)), arg, inc);
+ else
+ val = build2 (code, TREE_TYPE (arg), arg, inc);
+
+ TREE_SIDE_EFFECTS (val) = 1;
+ return val;
+ }
+
+ case ADDR_EXPR:
+ /* Note that this operation never does default_conversion
+ regardless of NOCONVERT. */
+ return cp_build_addr_expr (arg, complain);
+
+ default:
+ break;
+ }
+
+ if (!errstring)
+ {
+ if (argtype == 0)
+ argtype = TREE_TYPE (arg);
+ return fold_if_not_in_template (build1 (code, argtype, arg));
+ }
+
+ if (complain & tf_error)
+ error ("%s", errstring);
+ return error_mark_node;
+}
+
+/* Hook for the c-common bits that build a unary op. */
+tree
+build_unary_op (location_t /*location*/,
+ enum tree_code code, tree xarg, int noconvert)
+{
+ return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
+}
+
+/* Apply unary lvalue-demanding operator CODE to the expression ARG
+ for certain kinds of expressions which are not really lvalues
+ but which we can accept as lvalues.
+
+ If ARG is not a kind of expression we can handle, return
+ NULL_TREE. */
+
+tree
+unary_complex_lvalue (enum tree_code code, tree arg)
+{
+ /* Inside a template, making these kinds of adjustments is
+ pointless; we are only concerned with the type of the
+ expression. */
+ if (processing_template_decl)
+ return NULL_TREE;
+
+ /* Handle (a, b) used as an "lvalue". */
+ if (TREE_CODE (arg) == COMPOUND_EXPR)
+ {
+ tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 1), 0,
+ tf_warning_or_error);
+ return build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
+ TREE_OPERAND (arg, 0), real_result);
+ }
+
+ /* Handle (a ? b : c) used as an "lvalue". */
+ if (TREE_CODE (arg) == COND_EXPR
+ || TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR)
+ return rationalize_conditional_expr (code, arg, tf_warning_or_error);
+
+ /* Handle (a = b), (++a), and (--a) used as an "lvalue". */
+ if (TREE_CODE (arg) == MODIFY_EXPR
+ || TREE_CODE (arg) == PREINCREMENT_EXPR
+ || TREE_CODE (arg) == PREDECREMENT_EXPR)
+ {
+ tree lvalue = TREE_OPERAND (arg, 0);
+ if (TREE_SIDE_EFFECTS (lvalue))
+ {
+ lvalue = stabilize_reference (lvalue);
+ arg = build2 (TREE_CODE (arg), TREE_TYPE (arg),
+ lvalue, TREE_OPERAND (arg, 1));
+ }
+ return unary_complex_lvalue
+ (code, build2 (COMPOUND_EXPR, TREE_TYPE (lvalue), arg, lvalue));
+ }
+
+ if (code != ADDR_EXPR)
+ return NULL_TREE;
+
+ /* Handle (a = b) used as an "lvalue" for `&'. */
+ if (TREE_CODE (arg) == MODIFY_EXPR
+ || TREE_CODE (arg) == INIT_EXPR)
+ {
+ tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 0), 0,
+ tf_warning_or_error);
+ arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
+ arg, real_result);
+ TREE_NO_WARNING (arg) = 1;
+ return arg;
+ }
+
+ if (TREE_CODE (TREE_TYPE (arg)) == FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (arg)) == METHOD_TYPE
+ || TREE_CODE (arg) == OFFSET_REF)
+ return NULL_TREE;
+
+ /* We permit compiler to make function calls returning
+ objects of aggregate type look like lvalues. */
+ {
+ tree targ = arg;
+
+ if (TREE_CODE (targ) == SAVE_EXPR)
+ targ = TREE_OPERAND (targ, 0);
+
+ if (TREE_CODE (targ) == CALL_EXPR && MAYBE_CLASS_TYPE_P (TREE_TYPE (targ)))
+ {
+ if (TREE_CODE (arg) == SAVE_EXPR)
+ targ = arg;
+ else
+ targ = build_cplus_new (TREE_TYPE (arg), arg, tf_warning_or_error);
+ return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ);
+ }
+
+ if (TREE_CODE (arg) == SAVE_EXPR && INDIRECT_REF_P (targ))
+ return build3 (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
+ TREE_OPERAND (targ, 0), current_function_decl, NULL);
+ }
+
+ /* Don't let anything else be handled specially. */
+ return NULL_TREE;
+}
+
+/* Mark EXP saying that we need to be able to take the
+ address of it; it should not be allocated in a register.
+ Value is true if successful.
+
+ C++: we do not allow `current_class_ptr' to be addressable. */
+
+bool
+cxx_mark_addressable (tree exp)
+{
+ tree x = exp;
+
+ while (1)
+ switch (TREE_CODE (x))
+ {
+ case ADDR_EXPR:
+ case COMPONENT_REF:
+ case ARRAY_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ x = TREE_OPERAND (x, 0);
+ break;
+
+ case PARM_DECL:
+ if (x == current_class_ptr)
+ {
+ error ("cannot take the address of %<this%>, which is an rvalue expression");
+ TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later. */
+ return true;
+ }
+ /* Fall through. */
+
+ case VAR_DECL:
+ /* Caller should not be trying to mark initialized
+ constant fields addressable. */
+ gcc_assert (DECL_LANG_SPECIFIC (x) == 0
+ || DECL_IN_AGGR_P (x) == 0
+ || TREE_STATIC (x)
+ || DECL_EXTERNAL (x));
+ /* Fall through. */
+
+ case RESULT_DECL:
+ if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
+ && !DECL_ARTIFICIAL (x))
+ {
+ if (VAR_P (x) && DECL_HARD_REGISTER (x))
+ {
+ error
+ ("address of explicit register variable %qD requested", x);
+ return false;
+ }
+ else if (extra_warnings)
+ warning
+ (OPT_Wextra, "address requested for %qD, which is declared %<register%>", x);
+ }
+ TREE_ADDRESSABLE (x) = 1;
+ return true;
+
+ case CONST_DECL:
+ case FUNCTION_DECL:
+ TREE_ADDRESSABLE (x) = 1;
+ return true;
+
+ case CONSTRUCTOR:
+ TREE_ADDRESSABLE (x) = 1;
+ return true;
+
+ case TARGET_EXPR:
+ TREE_ADDRESSABLE (x) = 1;
+ cxx_mark_addressable (TREE_OPERAND (x, 0));
+ return true;
+
+ default:
+ return true;
+ }
+}
+
+/* Build and return a conditional expression IFEXP ? OP1 : OP2. */
+
+tree
+build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2,
+ tsubst_flags_t complain)
+{
+ tree orig_ifexp = ifexp;
+ tree orig_op1 = op1;
+ tree orig_op2 = op2;
+ tree expr;
+
+ if (processing_template_decl)
+ {
+ /* The standard says that the expression is type-dependent if
+ IFEXP is type-dependent, even though the eventual type of the
+ expression doesn't dependent on IFEXP. */
+ if (type_dependent_expression_p (ifexp)
+ /* As a GNU extension, the middle operand may be omitted. */
+ || (op1 && type_dependent_expression_p (op1))
+ || type_dependent_expression_p (op2))
+ return build_min_nt_loc (loc, COND_EXPR, ifexp, op1, op2);
+ ifexp = build_non_dependent_expr (ifexp);
+ if (op1)
+ op1 = build_non_dependent_expr (op1);
+ op2 = build_non_dependent_expr (op2);
+ }
+
+ expr = build_conditional_expr (loc, ifexp, op1, op2, complain);
+ if (processing_template_decl && expr != error_mark_node
+ && TREE_CODE (expr) != VEC_COND_EXPR)
+ {
+ tree min = build_min_non_dep (COND_EXPR, expr,
+ orig_ifexp, orig_op1, orig_op2);
+ /* In C++11, remember that the result is an lvalue or xvalue.
+ In C++98, lvalue_kind can just assume lvalue in a template. */
+ if (cxx_dialect >= cxx11
+ && lvalue_or_rvalue_with_address_p (expr)
+ && !lvalue_or_rvalue_with_address_p (min))
+ TREE_TYPE (min) = cp_build_reference_type (TREE_TYPE (min),
+ !real_lvalue_p (expr));
+ expr = convert_from_reference (min);
+ }
+ return expr;
+}
+
+/* Given a list of expressions, return a compound expression
+ that performs them all and returns the value of the last of them. */
+
+tree
+build_x_compound_expr_from_list (tree list, expr_list_kind exp,
+ tsubst_flags_t complain)
+{
+ tree expr = TREE_VALUE (list);
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && !CONSTRUCTOR_IS_DIRECT_INIT (expr))
+ {
+ if (complain & tf_error)
+ pedwarn (EXPR_LOC_OR_LOC (expr, input_location), 0,
+ "list-initializer for non-class type must not "
+ "be parenthesized");
+ else
+ return error_mark_node;
+ }
+
+ if (TREE_CHAIN (list))
+ {
+ if (complain & tf_error)
+ switch (exp)
+ {
+ case ELK_INIT:
+ permerror (input_location, "expression list treated as compound "
+ "expression in initializer");
+ break;
+ case ELK_MEM_INIT:
+ permerror (input_location, "expression list treated as compound "
+ "expression in mem-initializer");
+ break;
+ case ELK_FUNC_CAST:
+ permerror (input_location, "expression list treated as compound "
+ "expression in functional cast");
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ else
+ return error_mark_node;
+
+ for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
+ expr = build_x_compound_expr (EXPR_LOCATION (TREE_VALUE (list)),
+ expr, TREE_VALUE (list), complain);
+ }
+
+ return expr;
+}
+
+/* Like build_x_compound_expr_from_list, but using a VEC. */
+
+tree
+build_x_compound_expr_from_vec (vec<tree, va_gc> *vec, const char *msg,
+ tsubst_flags_t complain)
+{
+ if (vec_safe_is_empty (vec))
+ return NULL_TREE;
+ else if (vec->length () == 1)
+ return (*vec)[0];
+ else
+ {
+ tree expr;
+ unsigned int ix;
+ tree t;
+
+ if (msg != NULL)
+ {
+ if (complain & tf_error)
+ permerror (input_location,
+ "%s expression list treated as compound expression",
+ msg);
+ else
+ return error_mark_node;
+ }
+
+ expr = (*vec)[0];
+ for (ix = 1; vec->iterate (ix, &t); ++ix)
+ expr = build_x_compound_expr (EXPR_LOCATION (t), expr,
+ t, complain);
+
+ return expr;
+ }
+}
+
+/* Handle overloading of the ',' operator when needed. */
+
+tree
+build_x_compound_expr (location_t loc, tree op1, tree op2,
+ tsubst_flags_t complain)
+{
+ tree result;
+ tree orig_op1 = op1;
+ tree orig_op2 = op2;
+
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (op1)
+ || type_dependent_expression_p (op2))
+ return build_min_nt_loc (loc, COMPOUND_EXPR, op1, op2);
+ op1 = build_non_dependent_expr (op1);
+ op2 = build_non_dependent_expr (op2);
+ }
+
+ result = build_new_op (loc, COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2,
+ NULL_TREE, /*overload=*/NULL, complain);
+ if (!result)
+ result = cp_build_compound_expr (op1, op2, complain);
+
+ if (processing_template_decl && result != error_mark_node)
+ return build_min_non_dep (COMPOUND_EXPR, result, orig_op1, orig_op2);
+
+ return result;
+}
+
+/* Like cp_build_compound_expr, but for the c-common bits. */
+
+tree
+build_compound_expr (location_t /*loc*/, tree lhs, tree rhs)
+{
+ return cp_build_compound_expr (lhs, rhs, tf_warning_or_error);
+}
+
+/* Build a compound expression. */
+
+tree
+cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain)
+{
+ lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain);
+
+ if (lhs == error_mark_node || rhs == error_mark_node)
+ return error_mark_node;
+
+ if (flag_cilkplus
+ && (TREE_CODE (lhs) == CILK_SPAWN_STMT
+ || TREE_CODE (rhs) == CILK_SPAWN_STMT))
+ {
+ location_t loc = (EXPR_HAS_LOCATION (lhs) ? EXPR_LOCATION (lhs)
+ : EXPR_LOCATION (rhs));
+ error_at (loc,
+ "spawned function call cannot be part of a comma expression");
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (rhs) == TARGET_EXPR)
+ {
+ /* If the rhs is a TARGET_EXPR, then build the compound
+ expression inside the target_expr's initializer. This
+ helps the compiler to eliminate unnecessary temporaries. */
+ tree init = TREE_OPERAND (rhs, 1);
+
+ init = build2 (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
+ TREE_OPERAND (rhs, 1) = init;
+
+ return rhs;
+ }
+
+ if (type_unknown_p (rhs))
+ {
+ if (complain & tf_error)
+ error ("no context to resolve type of %qE", rhs);
+ return error_mark_node;
+ }
+
+ return build2 (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
+}
+
+/* Issue a diagnostic message if casting from SRC_TYPE to DEST_TYPE
+ casts away constness. CAST gives the type of cast. Returns true
+ if the cast is ill-formed, false if it is well-formed.
+
+ ??? This function warns for casting away any qualifier not just
+ const. We would like to specify exactly what qualifiers are casted
+ away.
+*/
+
+static bool
+check_for_casting_away_constness (tree src_type, tree dest_type,
+ enum tree_code cast, tsubst_flags_t complain)
+{
+ /* C-style casts are allowed to cast away constness. With
+ WARN_CAST_QUAL, we still want to issue a warning. */
+ if (cast == CAST_EXPR && !warn_cast_qual)
+ return false;
+
+ if (!casts_away_constness (src_type, dest_type, complain))
+ return false;
+
+ switch (cast)
+ {
+ case CAST_EXPR:
+ if (complain & tf_warning)
+ warning (OPT_Wcast_qual,
+ "cast from type %qT to type %qT casts away qualifiers",
+ src_type, dest_type);
+ return false;
+
+ case STATIC_CAST_EXPR:
+ if (complain & tf_error)
+ error ("static_cast from type %qT to type %qT casts away qualifiers",
+ src_type, dest_type);
+ return true;
+
+ case REINTERPRET_CAST_EXPR:
+ if (complain & tf_error)
+ error ("reinterpret_cast from type %qT to type %qT casts away qualifiers",
+ src_type, dest_type);
+ return true;
+
+ default:
+ gcc_unreachable();
+ }
+}
+
+/*
+ Warns if the cast from expression EXPR to type TYPE is useless.
+ */
+void
+maybe_warn_about_useless_cast (tree type, tree expr, tsubst_flags_t complain)
+{
+ if (warn_useless_cast
+ && complain & tf_warning)
+ {
+ /* In C++14 mode, this interacts badly with force_paren_expr. And it
+ isn't necessary in any mode, because the code below handles
+ glvalues properly. For 4.9, just skip it in C++14 mode. */
+ if (cxx_dialect < cxx1y && REFERENCE_REF_P (expr))
+ expr = TREE_OPERAND (expr, 0);
+
+ if ((TREE_CODE (type) == REFERENCE_TYPE
+ && (TYPE_REF_IS_RVALUE (type)
+ ? xvalue_p (expr) : real_lvalue_p (expr))
+ && same_type_p (TREE_TYPE (expr), TREE_TYPE (type)))
+ || same_type_p (TREE_TYPE (expr), type))
+ warning (OPT_Wuseless_cast, "useless cast to type %qT", type);
+ }
+}
+
+/* Convert EXPR (an expression with pointer-to-member type) to TYPE
+ (another pointer-to-member type in the same hierarchy) and return
+ the converted expression. If ALLOW_INVERSE_P is permitted, a
+ pointer-to-derived may be converted to pointer-to-base; otherwise,
+ only the other direction is permitted. If C_CAST_P is true, this
+ conversion is taking place as part of a C-style cast. */
+
+tree
+convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
+ bool c_cast_p, tsubst_flags_t complain)
+{
+ if (TYPE_PTRDATAMEM_P (type))
+ {
+ tree delta;
+
+ if (TREE_CODE (expr) == PTRMEM_CST)
+ expr = cplus_expand_constant (expr);
+ delta = get_delta_difference (TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (expr)),
+ TYPE_PTRMEM_CLASS_TYPE (type),
+ allow_inverse_p,
+ c_cast_p, complain);
+ if (delta == error_mark_node)
+ return error_mark_node;
+
+ if (!integer_zerop (delta))
+ {
+ tree cond, op1, op2;
+
+ cond = cp_build_binary_op (input_location,
+ EQ_EXPR,
+ expr,
+ build_int_cst (TREE_TYPE (expr), -1),
+ complain);
+ op1 = build_nop (ptrdiff_type_node, expr);
+ op2 = cp_build_binary_op (input_location,
+ PLUS_EXPR, op1, delta,
+ complain);
+
+ expr = fold_build3_loc (input_location,
+ COND_EXPR, ptrdiff_type_node, cond, op1, op2);
+
+ }
+
+ return build_nop (type, expr);
+ }
+ else
+ return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr,
+ allow_inverse_p, c_cast_p, complain);
+}
+
+/* Perform a static_cast from EXPR to TYPE. When C_CAST_P is true,
+ this static_cast is being attempted as one of the possible casts
+ allowed by a C-style cast. (In that case, accessibility of base
+ classes is not considered, and it is OK to cast away
+ constness.) Return the result of the cast. *VALID_P is set to
+ indicate whether or not the cast was valid. */
+
+static tree
+build_static_cast_1 (tree type, tree expr, bool c_cast_p,
+ bool *valid_p, tsubst_flags_t complain)
+{
+ tree intype;
+ tree result;
+ cp_lvalue_kind clk;
+
+ /* Assume the cast is valid. */
+ *valid_p = true;
+
+ intype = unlowered_expr_type (expr);
+
+ /* Save casted types in the function's used types hash table. */
+ used_types_insert (type);
+
+ /* [expr.static.cast]
+
+ An lvalue of type "cv1 B", where B is a class type, can be cast
+ to type "reference to cv2 D", where D is a class derived (clause
+ _class.derived_) from B, if a valid standard conversion from
+ "pointer to D" to "pointer to B" exists (_conv.ptr_), cv2 is the
+ same cv-qualification as, or greater cv-qualification than, cv1,
+ and B is not a virtual base class of D. */
+ /* We check this case before checking the validity of "TYPE t =
+ EXPR;" below because for this case:
+
+ struct B {};
+ struct D : public B { D(const B&); };
+ extern B& b;
+ void f() { static_cast<const D&>(b); }
+
+ we want to avoid constructing a new D. The standard is not
+ completely clear about this issue, but our interpretation is
+ consistent with other compilers. */
+ if (TREE_CODE (type) == REFERENCE_TYPE
+ && CLASS_TYPE_P (TREE_TYPE (type))
+ && CLASS_TYPE_P (intype)
+ && (TYPE_REF_IS_RVALUE (type) || real_lvalue_p (expr))
+ && DERIVED_FROM_P (intype, TREE_TYPE (type))
+ && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
+ build_pointer_type (TYPE_MAIN_VARIANT
+ (TREE_TYPE (type))),
+ complain)
+ && (c_cast_p
+ || at_least_as_qualified_p (TREE_TYPE (type), intype)))
+ {
+ tree base;
+
+ /* There is a standard conversion from "D*" to "B*" even if "B"
+ is ambiguous or inaccessible. If this is really a
+ static_cast, then we check both for inaccessibility and
+ ambiguity. However, if this is a static_cast being performed
+ because the user wrote a C-style cast, then accessibility is
+ not considered. */
+ base = lookup_base (TREE_TYPE (type), intype,
+ c_cast_p ? ba_unique : ba_check,
+ NULL, complain);
+
+ /* Convert from "B*" to "D*". This function will check that "B"
+ is not a virtual base of "D". */
+ expr = build_base_path (MINUS_EXPR, build_address (expr),
+ base, /*nonnull=*/false, complain);
+ /* Convert the pointer to a reference -- but then remember that
+ there are no expressions with reference type in C++.
+
+ We call rvalue so that there's an actual tree code
+ (NON_LVALUE_EXPR) for the static_cast; otherwise, if the operand
+ is a variable with the same type, the conversion would get folded
+ away, leaving just the variable and causing lvalue_kind to give
+ the wrong answer. */
+ return convert_from_reference (rvalue (cp_fold_convert (type, expr)));
+ }
+
+ /* "A glvalue of type cv1 T1 can be cast to type rvalue reference to
+ cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)." */
+ if (TREE_CODE (type) == REFERENCE_TYPE
+ && TYPE_REF_IS_RVALUE (type)
+ && (clk = real_lvalue_p (expr))
+ && reference_related_p (TREE_TYPE (type), intype)
+ && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
+ {
+ if (clk == clk_ordinary)
+ {
+ /* Handle the (non-bit-field) lvalue case here by casting to
+ lvalue reference and then changing it to an rvalue reference.
+ Casting an xvalue to rvalue reference will be handled by the
+ main code path. */
+ tree lref = cp_build_reference_type (TREE_TYPE (type), false);
+ result = (perform_direct_initialization_if_possible
+ (lref, expr, c_cast_p, complain));
+ result = cp_fold_convert (type, result);
+ /* Make sure we don't fold back down to a named rvalue reference,
+ because that would be an lvalue. */
+ if (DECL_P (result))
+ result = build1 (NON_LVALUE_EXPR, type, result);
+ return convert_from_reference (result);
+ }
+ else
+ /* For a bit-field or packed field, bind to a temporary. */
+ expr = rvalue (expr);
+ }
+
+ /* Resolve overloaded address here rather than once in
+ implicit_conversion and again in the inverse code below. */
+ if (TYPE_PTRMEMFUNC_P (type) && type_unknown_p (expr))
+ {
+ expr = instantiate_type (type, expr, complain);
+ intype = TREE_TYPE (expr);
+ }
+
+ /* [expr.static.cast]
+
+ Any expression can be explicitly converted to type cv void. */
+ if (VOID_TYPE_P (type))
+ return convert_to_void (expr, ICV_CAST, complain);
+
+ /* [class.abstract]
+ An abstract class shall not be used ... as the type of an explicit
+ conversion. */
+ if (abstract_virtuals_error_sfinae (ACU_CAST, type, complain))
+ return error_mark_node;
+
+ /* [expr.static.cast]
+
+ An expression e can be explicitly converted to a type T using a
+ static_cast of the form static_cast<T>(e) if the declaration T
+ t(e);" is well-formed, for some invented temporary variable
+ t. */
+ result = perform_direct_initialization_if_possible (type, expr,
+ c_cast_p, complain);
+ if (result)
+ {
+ result = convert_from_reference (result);
+
+ /* [expr.static.cast]
+
+ If T is a reference type, the result is an lvalue; otherwise,
+ the result is an rvalue. */
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ result = rvalue (result);
+ return result;
+ }
+
+ /* [expr.static.cast]
+
+ The inverse of any standard conversion sequence (clause _conv_),
+ other than the lvalue-to-rvalue (_conv.lval_), array-to-pointer
+ (_conv.array_), function-to-pointer (_conv.func_), and boolean
+ (_conv.bool_) conversions, can be performed explicitly using
+ static_cast subject to the restriction that the explicit
+ conversion does not cast away constness (_expr.const.cast_), and
+ the following additional rules for specific cases: */
+ /* For reference, the conversions not excluded are: integral
+ promotions, floating point promotion, integral conversions,
+ floating point conversions, floating-integral conversions,
+ pointer conversions, and pointer to member conversions. */
+ /* DR 128
+
+ A value of integral _or enumeration_ type can be explicitly
+ converted to an enumeration type. */
+ /* The effect of all that is that any conversion between any two
+ types which are integral, floating, or enumeration types can be
+ performed. */
+ if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+ || SCALAR_FLOAT_TYPE_P (type))
+ && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
+ || SCALAR_FLOAT_TYPE_P (intype)))
+ return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain);
+
+ if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
+ && CLASS_TYPE_P (TREE_TYPE (type))
+ && CLASS_TYPE_P (TREE_TYPE (intype))
+ && can_convert (build_pointer_type (TYPE_MAIN_VARIANT
+ (TREE_TYPE (intype))),
+ build_pointer_type (TYPE_MAIN_VARIANT
+ (TREE_TYPE (type))),
+ complain))
+ {
+ tree base;
+
+ if (!c_cast_p
+ && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
+ complain))
+ return error_mark_node;
+ base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
+ c_cast_p ? ba_unique : ba_check,
+ NULL, complain);
+ expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false,
+ complain);
+ return cp_fold_convert(type, expr);
+ }
+
+ if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
+ || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
+ {
+ tree c1;
+ tree c2;
+ tree t1;
+ tree t2;
+
+ c1 = TYPE_PTRMEM_CLASS_TYPE (intype);
+ c2 = TYPE_PTRMEM_CLASS_TYPE (type);
+
+ if (TYPE_PTRDATAMEM_P (type))
+ {
+ t1 = (build_ptrmem_type
+ (c1,
+ TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (intype))));
+ t2 = (build_ptrmem_type
+ (c2,
+ TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (type))));
+ }
+ else
+ {
+ t1 = intype;
+ t2 = type;
+ }
+ if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain))
+ {
+ if (!c_cast_p
+ && check_for_casting_away_constness (intype, type,
+ STATIC_CAST_EXPR,
+ complain))
+ return error_mark_node;
+ return convert_ptrmem (type, expr, /*allow_inverse_p=*/1,
+ c_cast_p, complain);
+ }
+ }
+
+ /* [expr.static.cast]
+
+ An rvalue of type "pointer to cv void" can be explicitly
+ converted to a pointer to object type. A value of type pointer
+ to object converted to "pointer to cv void" and back to the
+ original pointer type will have its original value. */
+ if (TYPE_PTR_P (intype)
+ && VOID_TYPE_P (TREE_TYPE (intype))
+ && TYPE_PTROB_P (type))
+ {
+ if (!c_cast_p
+ && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
+ complain))
+ return error_mark_node;
+ return build_nop (type, expr);
+ }
+
+ *valid_p = false;
+ return error_mark_node;
+}
+
+/* Return an expression representing static_cast<TYPE>(EXPR). */
+
+tree
+build_static_cast (tree type, tree expr, tsubst_flags_t complain)
+{
+ tree result;
+ bool valid_p;
+
+ if (type == error_mark_node || expr == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ expr = build_min (STATIC_CAST_EXPR, type, expr);
+ /* We don't know if it will or will not have side effects. */
+ TREE_SIDE_EFFECTS (expr) = 1;
+ return convert_from_reference (expr);
+ }
+
+ /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
+ Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */
+ if (TREE_CODE (type) != REFERENCE_TYPE
+ && TREE_CODE (expr) == NOP_EXPR
+ && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
+ expr = TREE_OPERAND (expr, 0);
+
+ result = build_static_cast_1 (type, expr, /*c_cast_p=*/false, &valid_p,
+ complain);
+ if (valid_p)
+ {
+ if (result != error_mark_node)
+ maybe_warn_about_useless_cast (type, expr, complain);
+ return result;
+ }
+
+ if (complain & tf_error)
+ error ("invalid static_cast from type %qT to type %qT",
+ TREE_TYPE (expr), type);
+ return error_mark_node;
+}
+
+/* EXPR is an expression with member function or pointer-to-member
+ function type. TYPE is a pointer type. Converting EXPR to TYPE is
+ not permitted by ISO C++, but we accept it in some modes. If we
+ are not in one of those modes, issue a diagnostic. Return the
+ converted expression. */
+
+tree
+convert_member_func_to_ptr (tree type, tree expr, tsubst_flags_t complain)
+{
+ tree intype;
+ tree decl;
+
+ intype = TREE_TYPE (expr);
+ gcc_assert (TYPE_PTRMEMFUNC_P (intype)
+ || TREE_CODE (intype) == METHOD_TYPE);
+
+ if (!(complain & tf_warning_or_error))
+ return error_mark_node;
+
+ if (pedantic || warn_pmf2ptr)
+ pedwarn (input_location, pedantic ? OPT_Wpedantic : OPT_Wpmf_conversions,
+ "converting from %qT to %qT", intype, type);
+
+ if (TREE_CODE (intype) == METHOD_TYPE)
+ expr = build_addr_func (expr, complain);
+ else if (TREE_CODE (expr) == PTRMEM_CST)
+ expr = build_address (PTRMEM_CST_MEMBER (expr));
+ else
+ {
+ decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype), 0);
+ decl = build_address (decl);
+ expr = get_member_function_from_ptrfunc (&decl, expr, complain);
+ }
+
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ return build_nop (type, expr);
+}
+
+/* Return a representation for a reinterpret_cast from EXPR to TYPE.
+ If C_CAST_P is true, this reinterpret cast is being done as part of
+ a C-style cast. If VALID_P is non-NULL, *VALID_P is set to
+ indicate whether or not reinterpret_cast was valid. */
+
+static tree
+build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
+ bool *valid_p, tsubst_flags_t complain)
+{
+ tree intype;
+
+ /* Assume the cast is invalid. */
+ if (valid_p)
+ *valid_p = true;
+
+ if (type == error_mark_node || error_operand_p (expr))
+ return error_mark_node;
+
+ intype = TREE_TYPE (expr);
+
+ /* Save casted types in the function's used types hash table. */
+ used_types_insert (type);
+
+ /* [expr.reinterpret.cast]
+ An lvalue expression of type T1 can be cast to the type
+ "reference to T2" if an expression of type "pointer to T1" can be
+ explicitly converted to the type "pointer to T2" using a
+ reinterpret_cast. */
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (! real_lvalue_p (expr))
+ {
+ if (complain & tf_error)
+ error ("invalid cast of an rvalue expression of type "
+ "%qT to type %qT",
+ intype, type);
+ return error_mark_node;
+ }
+
+ /* Warn about a reinterpret_cast from "A*" to "B&" if "A" and
+ "B" are related class types; the reinterpret_cast does not
+ adjust the pointer. */
+ if (TYPE_PTR_P (intype)
+ && (complain & tf_warning)
+ && (comptypes (TREE_TYPE (intype), TREE_TYPE (type),
+ COMPARE_BASE | COMPARE_DERIVED)))
+ warning (0, "casting %qT to %qT does not dereference pointer",
+ intype, type);
+
+ expr = cp_build_addr_expr (expr, complain);
+
+ if (warn_strict_aliasing > 2)
+ strict_aliasing_warning (TREE_TYPE (expr), type, expr);
+
+ if (expr != error_mark_node)
+ expr = build_reinterpret_cast_1
+ (build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
+ valid_p, complain);
+ if (expr != error_mark_node)
+ /* cp_build_indirect_ref isn't right for rvalue refs. */
+ expr = convert_from_reference (fold_convert (type, expr));
+ return expr;
+ }
+
+ /* As a G++ extension, we consider conversions from member
+ functions, and pointers to member functions to
+ pointer-to-function and pointer-to-void types. If
+ -Wno-pmf-conversions has not been specified,
+ convert_member_func_to_ptr will issue an error message. */
+ if ((TYPE_PTRMEMFUNC_P (intype)
+ || TREE_CODE (intype) == METHOD_TYPE)
+ && TYPE_PTR_P (type)
+ && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
+ || VOID_TYPE_P (TREE_TYPE (type))))
+ return convert_member_func_to_ptr (type, expr, complain);
+
+ /* If the cast is not to a reference type, the lvalue-to-rvalue,
+ array-to-pointer, and function-to-pointer conversions are
+ performed. */
+ expr = decay_conversion (expr, complain);
+
+ /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
+ Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */
+ if (TREE_CODE (expr) == NOP_EXPR
+ && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
+ expr = TREE_OPERAND (expr, 0);
+
+ if (error_operand_p (expr))
+ return error_mark_node;
+
+ intype = TREE_TYPE (expr);
+
+ /* [expr.reinterpret.cast]
+ A pointer can be converted to any integral type large enough to
+ hold it. ... A value of type std::nullptr_t can be converted to
+ an integral type; the conversion has the same meaning and
+ validity as a conversion of (void*)0 to the integral type. */
+ if (CP_INTEGRAL_TYPE_P (type)
+ && (TYPE_PTR_P (intype) || NULLPTR_TYPE_P (intype)))
+ {
+ if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
+ {
+ if (complain & tf_error)
+ permerror (input_location, "cast from %qT to %qT loses precision",
+ intype, type);
+ else
+ return error_mark_node;
+ }
+ if (NULLPTR_TYPE_P (intype))
+ return build_int_cst (type, 0);
+ }
+ /* [expr.reinterpret.cast]
+ A value of integral or enumeration type can be explicitly
+ converted to a pointer. */
+ else if (TYPE_PTR_P (type) && INTEGRAL_OR_ENUMERATION_TYPE_P (intype))
+ /* OK */
+ ;
+ else if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+ || TYPE_PTR_OR_PTRMEM_P (type))
+ && same_type_p (type, intype))
+ /* DR 799 */
+ return fold_if_not_in_template (build_nop (type, expr));
+ else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
+ || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
+ return fold_if_not_in_template (build_nop (type, expr));
+ else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
+ || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
+ {
+ tree sexpr = expr;
+
+ if (!c_cast_p
+ && check_for_casting_away_constness (intype, type,
+ REINTERPRET_CAST_EXPR,
+ complain))
+ return error_mark_node;
+ /* Warn about possible alignment problems. */
+ if (STRICT_ALIGNMENT && warn_cast_align
+ && (complain & tf_warning)
+ && !VOID_TYPE_P (type)
+ && TREE_CODE (TREE_TYPE (intype)) != FUNCTION_TYPE
+ && COMPLETE_TYPE_P (TREE_TYPE (type))
+ && COMPLETE_TYPE_P (TREE_TYPE (intype))
+ && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (intype)))
+ warning (OPT_Wcast_align, "cast from %qT to %qT "
+ "increases required alignment of target type", intype, type);
+
+ /* We need to strip nops here, because the front end likes to
+ create (int *)&a for array-to-pointer decay, instead of &a[0]. */
+ STRIP_NOPS (sexpr);
+ if (warn_strict_aliasing <= 2)
+ strict_aliasing_warning (intype, type, sexpr);
+
+ return fold_if_not_in_template (build_nop (type, expr));
+ }
+ else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
+ || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
+ {
+ if (complain & tf_warning)
+ /* C++11 5.2.10 p8 says that "Converting a function pointer to an
+ object pointer type or vice versa is conditionally-supported." */
+ warning (OPT_Wconditionally_supported,
+ "casting between pointer-to-function and pointer-to-object "
+ "is conditionally-supported");
+ return fold_if_not_in_template (build_nop (type, expr));
+ }
+ else if (TREE_CODE (type) == VECTOR_TYPE)
+ return fold_if_not_in_template (convert_to_vector (type, expr));
+ else if (TREE_CODE (intype) == VECTOR_TYPE
+ && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ return fold_if_not_in_template (convert_to_integer (type, expr));
+ else
+ {
+ if (valid_p)
+ *valid_p = false;
+ if (complain & tf_error)
+ error ("invalid cast from type %qT to type %qT", intype, type);
+ return error_mark_node;
+ }
+
+ return cp_convert (type, expr, complain);
+}
+
+tree
+build_reinterpret_cast (tree type, tree expr, tsubst_flags_t complain)
+{
+ tree r;
+
+ if (type == error_mark_node || expr == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
+
+ if (!TREE_SIDE_EFFECTS (t)
+ && type_dependent_expression_p (expr))
+ /* There might turn out to be side effects inside expr. */
+ TREE_SIDE_EFFECTS (t) = 1;
+ return convert_from_reference (t);
+ }
+
+ r = build_reinterpret_cast_1 (type, expr, /*c_cast_p=*/false,
+ /*valid_p=*/NULL, complain);
+ if (r != error_mark_node)
+ maybe_warn_about_useless_cast (type, expr, complain);
+ return r;
+}
+
+/* Perform a const_cast from EXPR to TYPE. If the cast is valid,
+ return an appropriate expression. Otherwise, return
+ error_mark_node. If the cast is not valid, and COMPLAIN is true,
+ then a diagnostic will be issued. If VALID_P is non-NULL, we are
+ performing a C-style cast, its value upon return will indicate
+ whether or not the conversion succeeded. */
+
+static tree
+build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain,
+ bool *valid_p)
+{
+ tree src_type;
+ tree reference_type;
+
+ /* Callers are responsible for handling error_mark_node as a
+ destination type. */
+ gcc_assert (dst_type != error_mark_node);
+ /* In a template, callers should be building syntactic
+ representations of casts, not using this machinery. */
+ gcc_assert (!processing_template_decl);
+
+ /* Assume the conversion is invalid. */
+ if (valid_p)
+ *valid_p = false;
+
+ if (!POINTER_TYPE_P (dst_type) && !TYPE_PTRDATAMEM_P (dst_type))
+ {
+ if (complain & tf_error)
+ error ("invalid use of const_cast with type %qT, "
+ "which is not a pointer, "
+ "reference, nor a pointer-to-data-member type", dst_type);
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE)
+ {
+ if (complain & tf_error)
+ error ("invalid use of const_cast with type %qT, which is a pointer "
+ "or reference to a function type", dst_type);
+ return error_mark_node;
+ }
+
+ /* Save casted types in the function's used types hash table. */
+ used_types_insert (dst_type);
+
+ src_type = TREE_TYPE (expr);
+ /* Expressions do not really have reference types. */
+ if (TREE_CODE (src_type) == REFERENCE_TYPE)
+ src_type = TREE_TYPE (src_type);
+
+ /* [expr.const.cast]
+
+ For two object types T1 and T2, if a pointer to T1 can be explicitly
+ converted to the type "pointer to T2" using a const_cast, then the
+ following conversions can also be made:
+
+ -- an lvalue of type T1 can be explicitly converted to an lvalue of
+ type T2 using the cast const_cast<T2&>;
+
+ -- a glvalue of type T1 can be explicitly converted to an xvalue of
+ type T2 using the cast const_cast<T2&&>; and
+
+ -- if T1 is a class type, a prvalue of type T1 can be explicitly
+ converted to an xvalue of type T2 using the cast const_cast<T2&&>. */
+
+ if (TREE_CODE (dst_type) == REFERENCE_TYPE)
+ {
+ reference_type = dst_type;
+ if (!TYPE_REF_IS_RVALUE (dst_type)
+ ? real_lvalue_p (expr)
+ : (CLASS_TYPE_P (TREE_TYPE (dst_type))
+ ? lvalue_p (expr)
+ : lvalue_or_rvalue_with_address_p (expr)))
+ /* OK. */;
+ else
+ {
+ if (complain & tf_error)
+ error ("invalid const_cast of an rvalue of type %qT to type %qT",
+ src_type, dst_type);
+ return error_mark_node;
+ }
+ dst_type = build_pointer_type (TREE_TYPE (dst_type));
+ src_type = build_pointer_type (src_type);
+ }
+ else
+ {
+ reference_type = NULL_TREE;
+ /* If the destination type is not a reference type, the
+ lvalue-to-rvalue, array-to-pointer, and function-to-pointer
+ conversions are performed. */
+ src_type = type_decays_to (src_type);
+ if (src_type == error_mark_node)
+ return error_mark_node;
+ }
+
+ if (TYPE_PTR_P (src_type) || TYPE_PTRDATAMEM_P (src_type))
+ {
+ if (comp_ptr_ttypes_const (dst_type, src_type))
+ {
+ if (valid_p)
+ {
+ *valid_p = true;
+ /* This cast is actually a C-style cast. Issue a warning if
+ the user is making a potentially unsafe cast. */
+ check_for_casting_away_constness (src_type, dst_type,
+ CAST_EXPR, complain);
+ }
+ if (reference_type)
+ {
+ expr = cp_build_addr_expr (expr, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+ expr = build_nop (reference_type, expr);
+ return convert_from_reference (expr);
+ }
+ else
+ {
+ expr = decay_conversion (expr, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ /* build_c_cast puts on a NOP_EXPR to make the result not an
+ lvalue. Strip such NOP_EXPRs if VALUE is being used in
+ non-lvalue context. */
+ if (TREE_CODE (expr) == NOP_EXPR
+ && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
+ expr = TREE_OPERAND (expr, 0);
+ return build_nop (dst_type, expr);
+ }
+ }
+ else if (valid_p
+ && !at_least_as_qualified_p (TREE_TYPE (dst_type),
+ TREE_TYPE (src_type)))
+ check_for_casting_away_constness (src_type, dst_type, CAST_EXPR,
+ complain);
+ }
+
+ if (complain & tf_error)
+ error ("invalid const_cast from type %qT to type %qT",
+ src_type, dst_type);
+ return error_mark_node;
+}
+
+tree
+build_const_cast (tree type, tree expr, tsubst_flags_t complain)
+{
+ tree r;
+
+ if (type == error_mark_node || error_operand_p (expr))
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ tree t = build_min (CONST_CAST_EXPR, type, expr);
+
+ if (!TREE_SIDE_EFFECTS (t)
+ && type_dependent_expression_p (expr))
+ /* There might turn out to be side effects inside expr. */
+ TREE_SIDE_EFFECTS (t) = 1;
+ return convert_from_reference (t);
+ }
+
+ r = build_const_cast_1 (type, expr, complain, /*valid_p=*/NULL);
+ if (r != error_mark_node)
+ maybe_warn_about_useless_cast (type, expr, complain);
+ return r;
+}
+
+/* Like cp_build_c_cast, but for the c-common bits. */
+
+tree
+build_c_cast (location_t /*loc*/, tree type, tree expr)
+{
+ return cp_build_c_cast (type, expr, tf_warning_or_error);
+}
+
+/* Build an expression representing an explicit C-style cast to type
+ TYPE of expression EXPR. */
+
+tree
+cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
+{
+ tree value = expr;
+ tree result;
+ bool valid_p;
+
+ if (type == error_mark_node || error_operand_p (expr))
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ tree t = build_min (CAST_EXPR, type,
+ tree_cons (NULL_TREE, value, NULL_TREE));
+ /* We don't know if it will or will not have side effects. */
+ TREE_SIDE_EFFECTS (t) = 1;
+ return convert_from_reference (t);
+ }
+
+ /* Casts to a (pointer to a) specific ObjC class (or 'id' or
+ 'Class') should always be retained, because this information aids
+ in method lookup. */
+ if (objc_is_object_ptr (type)
+ && objc_is_object_ptr (TREE_TYPE (expr)))
+ return build_nop (type, expr);
+
+ /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
+ Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */
+ if (TREE_CODE (type) != REFERENCE_TYPE
+ && TREE_CODE (value) == NOP_EXPR
+ && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
+ value = TREE_OPERAND (value, 0);
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ /* Allow casting from T1* to T2[] because Cfront allows it.
+ NIHCL uses it. It is not valid ISO C++ however. */
+ if (TYPE_PTR_P (TREE_TYPE (expr)))
+ {
+ if (complain & tf_error)
+ permerror (input_location, "ISO C++ forbids casting to an array type %qT", type);
+ else
+ return error_mark_node;
+ type = build_pointer_type (TREE_TYPE (type));
+ }
+ else
+ {
+ if (complain & tf_error)
+ error ("ISO C++ forbids casting to an array type %qT", type);
+ return error_mark_node;
+ }
+ }
+
+ if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
+ {
+ if (complain & tf_error)
+ error ("invalid cast to function type %qT", type);
+ return error_mark_node;
+ }
+
+ if (TYPE_PTR_P (type)
+ && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
+ /* Casting to an integer of smaller size is an error detected elsewhere. */
+ && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
+ /* Don't warn about converting any constant. */
+ && !TREE_CONSTANT (value))
+ warning_at (input_location, OPT_Wint_to_pointer_cast,
+ "cast to pointer from integer of different size");
+
+ /* A C-style cast can be a const_cast. */
+ result = build_const_cast_1 (type, value, complain & tf_warning,
+ &valid_p);
+ if (valid_p)
+ {
+ if (result != error_mark_node)
+ maybe_warn_about_useless_cast (type, value, complain);
+ return result;
+ }
+
+ /* Or a static cast. */
+ result = build_static_cast_1 (type, value, /*c_cast_p=*/true,
+ &valid_p, complain);
+ /* Or a reinterpret_cast. */
+ if (!valid_p)
+ result = build_reinterpret_cast_1 (type, value, /*c_cast_p=*/true,
+ &valid_p, complain);
+ /* The static_cast or reinterpret_cast may be followed by a
+ const_cast. */
+ if (valid_p
+ /* A valid cast may result in errors if, for example, a
+ conversion to an ambiguous base class is required. */
+ && !error_operand_p (result))
+ {
+ tree result_type;
+
+ maybe_warn_about_useless_cast (type, value, complain);
+
+ /* Non-class rvalues always have cv-unqualified type. */
+ if (!CLASS_TYPE_P (type))
+ type = TYPE_MAIN_VARIANT (type);
+ result_type = TREE_TYPE (result);
+ if (!CLASS_TYPE_P (result_type) && TREE_CODE (type) != REFERENCE_TYPE)
+ result_type = TYPE_MAIN_VARIANT (result_type);
+ /* If the type of RESULT does not match TYPE, perform a
+ const_cast to make it match. If the static_cast or
+ reinterpret_cast succeeded, we will differ by at most
+ cv-qualification, so the follow-on const_cast is guaranteed
+ to succeed. */
+ if (!same_type_p (non_reference (type), non_reference (result_type)))
+ {
+ result = build_const_cast_1 (type, result, false, &valid_p);
+ gcc_assert (valid_p);
+ }
+ return result;
+ }
+
+ return error_mark_node;
+}
+
+/* For use from the C common bits. */
+tree
+build_modify_expr (location_t /*location*/,
+ tree lhs, tree /*lhs_origtype*/,
+ enum tree_code modifycode,
+ location_t /*rhs_location*/, tree rhs,
+ tree /*rhs_origtype*/)
+{
+ return cp_build_modify_expr (lhs, modifycode, rhs, tf_warning_or_error);
+}
+
+/* Build an assignment expression of lvalue LHS from value RHS.
+ MODIFYCODE is the code for a binary operator that we use
+ to combine the old value of LHS with RHS to get the new value.
+ Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.
+
+ C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed. */
+
+tree
+cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
+ tsubst_flags_t complain)
+{
+ tree result;
+ tree newrhs = rhs;
+ tree lhstype = TREE_TYPE (lhs);
+ tree olhstype = lhstype;
+ bool plain_assign = (modifycode == NOP_EXPR);
+
+ /* Avoid duplicate error messages from operands that had errors. */
+ if (error_operand_p (lhs) || error_operand_p (rhs))
+ return error_mark_node;
+
+ /* Handle control structure constructs used as "lvalues". */
+ switch (TREE_CODE (lhs))
+ {
+ /* Handle --foo = 5; as these are valid constructs in C++. */
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
+ lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
+ stabilize_reference (TREE_OPERAND (lhs, 0)),
+ TREE_OPERAND (lhs, 1));
+ newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0),
+ modifycode, rhs, complain);
+ if (newrhs == error_mark_node)
+ return error_mark_node;
+ return build2 (COMPOUND_EXPR, lhstype, lhs, newrhs);
+
+ /* Handle (a, b) used as an "lvalue". */
+ case COMPOUND_EXPR:
+ newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 1),
+ modifycode, rhs, complain);
+ if (newrhs == error_mark_node)
+ return error_mark_node;
+ return build2 (COMPOUND_EXPR, lhstype,
+ TREE_OPERAND (lhs, 0), newrhs);
+
+ case MODIFY_EXPR:
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
+ lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
+ stabilize_reference (TREE_OPERAND (lhs, 0)),
+ TREE_OPERAND (lhs, 1));
+ newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs,
+ complain);
+ if (newrhs == error_mark_node)
+ return error_mark_node;
+ return build2 (COMPOUND_EXPR, lhstype, lhs, newrhs);
+
+ case MIN_EXPR:
+ case MAX_EXPR:
+ /* MIN_EXPR and MAX_EXPR are currently only permitted as lvalues,
+ when neither operand has side-effects. */
+ if (!lvalue_or_else (lhs, lv_assign, complain))
+ return error_mark_node;
+
+ gcc_assert (!TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))
+ && !TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 1)));
+
+ lhs = build3 (COND_EXPR, TREE_TYPE (lhs),
+ build2 (TREE_CODE (lhs) == MIN_EXPR ? LE_EXPR : GE_EXPR,
+ boolean_type_node,
+ TREE_OPERAND (lhs, 0),
+ TREE_OPERAND (lhs, 1)),
+ TREE_OPERAND (lhs, 0),
+ TREE_OPERAND (lhs, 1));
+ /* Fall through. */
+
+ /* Handle (a ? b : c) used as an "lvalue". */
+ case COND_EXPR:
+ {
+ /* Produce (a ? (b = rhs) : (c = rhs))
+ except that the RHS goes through a save-expr
+ so the code to compute it is only emitted once. */
+ tree cond;
+ tree preeval = NULL_TREE;
+
+ if (VOID_TYPE_P (TREE_TYPE (rhs)))
+ {
+ if (complain & tf_error)
+ error ("void value not ignored as it ought to be");
+ return error_mark_node;
+ }
+
+ rhs = stabilize_expr (rhs, &preeval);
+
+ /* Check this here to avoid odd errors when trying to convert
+ a throw to the type of the COND_EXPR. */
+ if (!lvalue_or_else (lhs, lv_assign, complain))
+ return error_mark_node;
+
+ cond = build_conditional_expr
+ (input_location, TREE_OPERAND (lhs, 0),
+ cp_build_modify_expr (TREE_OPERAND (lhs, 1),
+ modifycode, rhs, complain),
+ cp_build_modify_expr (TREE_OPERAND (lhs, 2),
+ modifycode, rhs, complain),
+ complain);
+
+ if (cond == error_mark_node)
+ return cond;
+ /* Make sure the code to compute the rhs comes out
+ before the split. */
+ if (preeval)
+ cond = build2 (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
+ return cond;
+ }
+
+ default:
+ break;
+ }
+
+ if (modifycode == INIT_EXPR)
+ {
+ if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
+ /* Do the default thing. */;
+ else if (TREE_CODE (rhs) == CONSTRUCTOR)
+ {
+ /* Compound literal. */
+ if (! same_type_p (TREE_TYPE (rhs), lhstype))
+ /* Call convert to generate an error; see PR 11063. */
+ rhs = convert (lhstype, rhs);
+ result = build2 (INIT_EXPR, lhstype, lhs, rhs);
+ TREE_SIDE_EFFECTS (result) = 1;
+ return result;
+ }
+ else if (! MAYBE_CLASS_TYPE_P (lhstype))
+ /* Do the default thing. */;
+ else
+ {
+ vec<tree, va_gc> *rhs_vec = make_tree_vector_single (rhs);
+ result = build_special_member_call (lhs, complete_ctor_identifier,
+ &rhs_vec, lhstype, LOOKUP_NORMAL,
+ complain);
+ release_tree_vector (rhs_vec);
+ if (result == NULL_TREE)
+ return error_mark_node;
+ return result;
+ }
+ }
+ else
+ {
+ lhs = require_complete_type_sfinae (lhs, complain);
+ if (lhs == error_mark_node)
+ return error_mark_node;
+
+ if (modifycode == NOP_EXPR)
+ {
+ if (c_dialect_objc ())
+ {
+ result = objc_maybe_build_modify_expr (lhs, rhs);
+ if (result)
+ return result;
+ }
+
+ /* `operator=' is not an inheritable operator. */
+ if (! MAYBE_CLASS_TYPE_P (lhstype))
+ /* Do the default thing. */;
+ else
+ {
+ result = build_new_op (input_location, MODIFY_EXPR,
+ LOOKUP_NORMAL, lhs, rhs,
+ make_node (NOP_EXPR), /*overload=*/NULL,
+ complain);
+ if (result == NULL_TREE)
+ return error_mark_node;
+ return result;
+ }
+ lhstype = olhstype;
+ }
+ else
+ {
+ tree init = NULL_TREE;
+
+ /* A binary op has been requested. Combine the old LHS
+ value with the RHS producing the value we should actually
+ store into the LHS. */
+ gcc_assert (!((TREE_CODE (lhstype) == REFERENCE_TYPE
+ && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype)))
+ || MAYBE_CLASS_TYPE_P (lhstype)));
+
+ /* Preevaluate the RHS to make sure its evaluation is complete
+ before the lvalue-to-rvalue conversion of the LHS:
+
+ [expr.ass] With respect to an indeterminately-sequenced
+ function call, the operation of a compound assignment is a
+ single evaluation. [ Note: Therefore, a function call shall
+ not intervene between the lvalue-to-rvalue conversion and the
+ side effect associated with any single compound assignment
+ operator. -- end note ] */
+ lhs = stabilize_reference (lhs);
+ rhs = rvalue (rhs);
+ rhs = stabilize_expr (rhs, &init);
+ newrhs = cp_build_binary_op (input_location,
+ modifycode, lhs, rhs,
+ complain);
+ if (newrhs == error_mark_node)
+ {
+ if (complain & tf_error)
+ error (" in evaluation of %<%Q(%#T, %#T)%>", modifycode,
+ TREE_TYPE (lhs), TREE_TYPE (rhs));
+ return error_mark_node;
+ }
+
+ if (init)
+ newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs);
+
+ /* Now it looks like a plain assignment. */
+ modifycode = NOP_EXPR;
+ if (c_dialect_objc ())
+ {
+ result = objc_maybe_build_modify_expr (lhs, newrhs);
+ if (result)
+ return result;
+ }
+ }
+ gcc_assert (TREE_CODE (lhstype) != REFERENCE_TYPE);
+ gcc_assert (TREE_CODE (TREE_TYPE (newrhs)) != REFERENCE_TYPE);
+ }
+
+ /* The left-hand side must be an lvalue. */
+ if (!lvalue_or_else (lhs, lv_assign, complain))
+ return error_mark_node;
+
+ /* Warn about modifying something that is `const'. Don't warn if
+ this is initialization. */
+ if (modifycode != INIT_EXPR
+ && (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)
+ /* Functions are not modifiable, even though they are
+ lvalues. */
+ || TREE_CODE (TREE_TYPE (lhs)) == FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (lhs)) == METHOD_TYPE
+ /* If it's an aggregate and any field is const, then it is
+ effectively const. */
+ || (CLASS_TYPE_P (lhstype)
+ && C_TYPE_FIELDS_READONLY (lhstype))))
+ {
+ if (complain & tf_error)
+ cxx_readonly_error (lhs, lv_assign);
+ else
+ return error_mark_node;
+ }
+
+ /* If storing into a structure or union member, it may have been given a
+ lowered bitfield type. We need to convert to the declared type first,
+ so retrieve it now. */
+
+ olhstype = unlowered_expr_type (lhs);
+
+ /* Convert new value to destination type. */
+
+ if (TREE_CODE (lhstype) == ARRAY_TYPE)
+ {
+ int from_array;
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (newrhs))
+ {
+ if (modifycode != INIT_EXPR)
+ {
+ if (complain & tf_error)
+ error ("assigning to an array from an initializer list");
+ return error_mark_node;
+ }
+ if (check_array_initializer (lhs, lhstype, newrhs))
+ return error_mark_node;
+ newrhs = digest_init (lhstype, newrhs, complain);
+ if (newrhs == error_mark_node)
+ return error_mark_node;
+ }
+
+ else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
+ TYPE_MAIN_VARIANT (TREE_TYPE (newrhs))))
+ {
+ if (complain & tf_error)
+ error ("incompatible types in assignment of %qT to %qT",
+ TREE_TYPE (rhs), lhstype);
+ return error_mark_node;
+ }
+
+ /* Allow array assignment in compiler-generated code. */
+ else if (!current_function_decl
+ || !DECL_DEFAULTED_FN (current_function_decl))
+ {
+ /* This routine is used for both initialization and assignment.
+ Make sure the diagnostic message differentiates the context. */
+ if (complain & tf_error)
+ {
+ if (modifycode == INIT_EXPR)
+ error ("array used as initializer");
+ else
+ error ("invalid array assignment");
+ }
+ return error_mark_node;
+ }
+
+ from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
+ ? 1 + (modifycode != INIT_EXPR): 0;
+ return build_vec_init (lhs, NULL_TREE, newrhs,
+ /*explicit_value_init_p=*/false,
+ from_array, complain);
+ }
+
+ if (modifycode == INIT_EXPR)
+ /* Calls with INIT_EXPR are all direct-initialization, so don't set
+ LOOKUP_ONLYCONVERTING. */
+ newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
+ ICR_INIT, NULL_TREE, 0,
+ complain);
+ else
+ newrhs = convert_for_assignment (olhstype, newrhs, ICR_ASSIGN,
+ NULL_TREE, 0, complain, LOOKUP_IMPLICIT);
+
+ if (!same_type_p (lhstype, olhstype))
+ newrhs = cp_convert_and_check (lhstype, newrhs, complain);
+
+ if (modifycode != INIT_EXPR)
+ {
+ if (TREE_CODE (newrhs) == CALL_EXPR
+ && TYPE_NEEDS_CONSTRUCTING (lhstype))
+ newrhs = build_cplus_new (lhstype, newrhs, complain);
+
+ /* Can't initialize directly from a TARGET_EXPR, since that would
+ cause the lhs to be constructed twice, and possibly result in
+ accidental self-initialization. So we force the TARGET_EXPR to be
+ expanded without a target. */
+ if (TREE_CODE (newrhs) == TARGET_EXPR)
+ newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
+ TREE_OPERAND (newrhs, 0));
+ }
+
+ if (newrhs == error_mark_node)
+ return error_mark_node;
+
+ if (c_dialect_objc () && flag_objc_gc)
+ {
+ result = objc_generate_write_barrier (lhs, modifycode, newrhs);
+
+ if (result)
+ return result;
+ }
+
+ result = build2 (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
+ lhstype, lhs, newrhs);
+
+ TREE_SIDE_EFFECTS (result) = 1;
+ if (!plain_assign)
+ TREE_NO_WARNING (result) = 1;
+
+ return result;
+}
+
+tree
+build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
+ tree rhs, tsubst_flags_t complain)
+{
+ if (processing_template_decl)
+ return build_min_nt_loc (loc, MODOP_EXPR, lhs,
+ build_min_nt_loc (loc, modifycode, NULL_TREE,
+ NULL_TREE), rhs);
+
+ if (modifycode != NOP_EXPR)
+ {
+ tree rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs,
+ make_node (modifycode), /*overload=*/NULL,
+ complain);
+ if (rval)
+ {
+ TREE_NO_WARNING (rval) = 1;
+ return rval;
+ }
+ }
+ return cp_build_modify_expr (lhs, modifycode, rhs, complain);
+}
+
+/* Helper function for get_delta_difference which assumes FROM is a base
+ class of TO. Returns a delta for the conversion of pointer-to-member
+ of FROM to pointer-to-member of TO. If the conversion is invalid and
+ tf_error is not set in COMPLAIN returns error_mark_node, otherwise
+ returns zero. If FROM is not a base class of TO, returns NULL_TREE.
+ If C_CAST_P is true, this conversion is taking place as part of a
+ C-style cast. */
+
+static tree
+get_delta_difference_1 (tree from, tree to, bool c_cast_p,
+ tsubst_flags_t complain)
+{
+ tree binfo;
+ base_kind kind;
+
+ binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check,
+ &kind, complain);
+
+ if (binfo == error_mark_node)
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+
+ error (" in pointer to member function conversion");
+ return size_zero_node;
+ }
+ else if (binfo)
+ {
+ if (kind != bk_via_virtual)
+ return BINFO_OFFSET (binfo);
+ else
+ /* FROM is a virtual base class of TO. Issue an error or warning
+ depending on whether or not this is a reinterpret cast. */
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+
+ error ("pointer to member conversion via virtual base %qT",
+ BINFO_TYPE (binfo_from_vbase (binfo)));
+
+ return size_zero_node;
+ }
+ }
+ else
+ return NULL_TREE;
+}
+
+/* Get difference in deltas for different pointer to member function
+ types. If the conversion is invalid and tf_error is not set in
+ COMPLAIN, returns error_mark_node, otherwise returns an integer
+ constant of type PTRDIFF_TYPE_NODE and its value is zero if the
+ conversion is invalid. If ALLOW_INVERSE_P is true, then allow reverse
+ conversions as well. If C_CAST_P is true this conversion is taking
+ place as part of a C-style cast.
+
+ Note that the naming of FROM and TO is kind of backwards; the return
+ value is what we add to a TO in order to get a FROM. They are named
+ this way because we call this function to find out how to convert from
+ a pointer to member of FROM to a pointer to member of TO. */
+
+static tree
+get_delta_difference (tree from, tree to,
+ bool allow_inverse_p,
+ bool c_cast_p, tsubst_flags_t complain)
+{
+ tree result;
+
+ if (same_type_ignoring_top_level_qualifiers_p (from, to))
+ /* Pointer to member of incomplete class is permitted*/
+ result = size_zero_node;
+ else
+ result = get_delta_difference_1 (from, to, c_cast_p, complain);
+
+ if (result == error_mark_node)
+ return error_mark_node;
+
+ if (!result)
+ {
+ if (!allow_inverse_p)
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+
+ error_not_base_type (from, to);
+ error (" in pointer to member conversion");
+ result = size_zero_node;
+ }
+ else
+ {
+ result = get_delta_difference_1 (to, from, c_cast_p, complain);
+
+ if (result == error_mark_node)
+ return error_mark_node;
+
+ if (result)
+ result = size_diffop_loc (input_location,
+ size_zero_node, result);
+ else
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+
+ error_not_base_type (from, to);
+ error (" in pointer to member conversion");
+ result = size_zero_node;
+ }
+ }
+ }
+
+ return fold_if_not_in_template (convert_to_integer (ptrdiff_type_node,
+ result));
+}
+
+/* Return a constructor for the pointer-to-member-function TYPE using
+ the other components as specified. */
+
+tree
+build_ptrmemfunc1 (tree type, tree delta, tree pfn)
+{
+ tree u = NULL_TREE;
+ tree delta_field;
+ tree pfn_field;
+ vec<constructor_elt, va_gc> *v;
+
+ /* Pull the FIELD_DECLs out of the type. */
+ pfn_field = TYPE_FIELDS (type);
+ delta_field = DECL_CHAIN (pfn_field);
+
+ /* Make sure DELTA has the type we want. */
+ delta = convert_and_check (input_location, delta_type_node, delta);
+
+ /* Convert to the correct target type if necessary. */
+ pfn = fold_convert (TREE_TYPE (pfn_field), pfn);
+
+ /* Finish creating the initializer. */
+ vec_alloc (v, 2);
+ CONSTRUCTOR_APPEND_ELT(v, pfn_field, pfn);
+ CONSTRUCTOR_APPEND_ELT(v, delta_field, delta);
+ u = build_constructor (type, v);
+ TREE_CONSTANT (u) = TREE_CONSTANT (pfn) & TREE_CONSTANT (delta);
+ TREE_STATIC (u) = (TREE_CONSTANT (u)
+ && (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
+ != NULL_TREE)
+ && (initializer_constant_valid_p (delta, TREE_TYPE (delta))
+ != NULL_TREE));
+ return u;
+}
+
+/* Build a constructor for a pointer to member function. It can be
+ used to initialize global variables, local variable, or used
+ as a value in expressions. TYPE is the POINTER to METHOD_TYPE we
+ want to be.
+
+ If FORCE is nonzero, then force this conversion, even if
+ we would rather not do it. Usually set when using an explicit
+ cast. A C-style cast is being processed iff C_CAST_P is true.
+
+ Return error_mark_node, if something goes wrong. */
+
+tree
+build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
+ tsubst_flags_t complain)
+{
+ tree fn;
+ tree pfn_type;
+ tree to_type;
+
+ if (error_operand_p (pfn))
+ return error_mark_node;
+
+ pfn_type = TREE_TYPE (pfn);
+ to_type = build_ptrmemfunc_type (type);
+
+ /* Handle multiple conversions of pointer to member functions. */
+ if (TYPE_PTRMEMFUNC_P (pfn_type))
+ {
+ tree delta = NULL_TREE;
+ tree npfn = NULL_TREE;
+ tree n;
+
+ if (!force
+ && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn,
+ LOOKUP_NORMAL, complain))
+ {
+ if (complain & tf_error)
+ error ("invalid conversion to type %qT from type %qT",
+ to_type, pfn_type);
+ else
+ return error_mark_node;
+ }
+
+ n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
+ TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
+ force,
+ c_cast_p, complain);
+ if (n == error_mark_node)
+ return error_mark_node;
+
+ /* We don't have to do any conversion to convert a
+ pointer-to-member to its own type. But, we don't want to
+ just return a PTRMEM_CST if there's an explicit cast; that
+ cast should make the expression an invalid template argument. */
+ if (TREE_CODE (pfn) != PTRMEM_CST)
+ {
+ if (same_type_p (to_type, pfn_type))
+ return pfn;
+ else if (integer_zerop (n))
+ return build_reinterpret_cast (to_type, pfn,
+ complain);
+ }
+
+ if (TREE_SIDE_EFFECTS (pfn))
+ pfn = save_expr (pfn);
+
+ /* Obtain the function pointer and the current DELTA. */
+ if (TREE_CODE (pfn) == PTRMEM_CST)
+ expand_ptrmemfunc_cst (pfn, &delta, &npfn);
+ else
+ {
+ npfn = build_ptrmemfunc_access_expr (pfn, pfn_identifier);
+ delta = build_ptrmemfunc_access_expr (pfn, delta_identifier);
+ }
+
+ /* Just adjust the DELTA field. */
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (delta), ptrdiff_type_node));
+ if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
+ n = cp_build_binary_op (input_location,
+ LSHIFT_EXPR, n, integer_one_node,
+ complain);
+ delta = cp_build_binary_op (input_location,
+ PLUS_EXPR, delta, n, complain);
+ return build_ptrmemfunc1 (to_type, delta, npfn);
+ }
+
+ /* Handle null pointer to member function conversions. */
+ if (null_ptr_cst_p (pfn))
+ {
+ pfn = cp_build_c_cast (type, pfn, complain);
+ return build_ptrmemfunc1 (to_type,
+ integer_zero_node,
+ pfn);
+ }
+
+ if (type_unknown_p (pfn))
+ return instantiate_type (type, pfn, complain);
+
+ fn = TREE_OPERAND (pfn, 0);
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
+ /* In a template, we will have preserved the
+ OFFSET_REF. */
+ || (processing_template_decl && TREE_CODE (fn) == OFFSET_REF));
+ return make_ptrmem_cst (to_type, fn);
+}
+
+/* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST
+ given by CST.
+
+ ??? There is no consistency as to the types returned for the above
+ values. Some code acts as if it were a sizetype and some as if it were
+ integer_type_node. */
+
+void
+expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn)
+{
+ tree type = TREE_TYPE (cst);
+ tree fn = PTRMEM_CST_MEMBER (cst);
+ tree ptr_class, fn_class;
+
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
+
+ /* The class that the function belongs to. */
+ fn_class = DECL_CONTEXT (fn);
+
+ /* The class that we're creating a pointer to member of. */
+ ptr_class = TYPE_PTRMEMFUNC_OBJECT_TYPE (type);
+
+ /* First, calculate the adjustment to the function's class. */
+ *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0,
+ /*c_cast_p=*/0, tf_warning_or_error);
+
+ if (!DECL_VIRTUAL_P (fn))
+ *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type),
+ build_addr_func (fn, tf_warning_or_error));
+ else
+ {
+ /* If we're dealing with a virtual function, we have to adjust 'this'
+ again, to point to the base which provides the vtable entry for
+ fn; the call will do the opposite adjustment. */
+ tree orig_class = DECL_CONTEXT (fn);
+ tree binfo = binfo_or_else (orig_class, fn_class);
+ *delta = build2 (PLUS_EXPR, TREE_TYPE (*delta),
+ *delta, BINFO_OFFSET (binfo));
+ *delta = fold_if_not_in_template (*delta);
+
+ /* We set PFN to the vtable offset at which the function can be
+ found, plus one (unless ptrmemfunc_vbit_in_delta, in which
+ case delta is shifted left, and then incremented). */
+ *pfn = DECL_VINDEX (fn);
+ *pfn = build2 (MULT_EXPR, integer_type_node, *pfn,
+ TYPE_SIZE_UNIT (vtable_entry_type));
+ *pfn = fold_if_not_in_template (*pfn);
+
+ switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
+ {
+ case ptrmemfunc_vbit_in_pfn:
+ *pfn = build2 (PLUS_EXPR, integer_type_node, *pfn,
+ integer_one_node);
+ *pfn = fold_if_not_in_template (*pfn);
+ break;
+
+ case ptrmemfunc_vbit_in_delta:
+ *delta = build2 (LSHIFT_EXPR, TREE_TYPE (*delta),
+ *delta, integer_one_node);
+ *delta = fold_if_not_in_template (*delta);
+ *delta = build2 (PLUS_EXPR, TREE_TYPE (*delta),
+ *delta, integer_one_node);
+ *delta = fold_if_not_in_template (*delta);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ *pfn = build_nop (TYPE_PTRMEMFUNC_FN_TYPE (type), *pfn);
+ *pfn = fold_if_not_in_template (*pfn);
+ }
+}
+
+/* Return an expression for PFN from the pointer-to-member function
+ given by T. */
+
+static tree
+pfn_from_ptrmemfunc (tree t)
+{
+ if (TREE_CODE (t) == PTRMEM_CST)
+ {
+ tree delta;
+ tree pfn;
+
+ expand_ptrmemfunc_cst (t, &delta, &pfn);
+ if (pfn)
+ return pfn;
+ }
+
+ return build_ptrmemfunc_access_expr (t, pfn_identifier);
+}
+
+/* Return an expression for DELTA from the pointer-to-member function
+ given by T. */
+
+static tree
+delta_from_ptrmemfunc (tree t)
+{
+ if (TREE_CODE (t) == PTRMEM_CST)
+ {
+ tree delta;
+ tree pfn;
+
+ expand_ptrmemfunc_cst (t, &delta, &pfn);
+ if (delta)
+ return delta;
+ }
+
+ return build_ptrmemfunc_access_expr (t, delta_identifier);
+}
+
+/* Convert value RHS to type TYPE as preparation for an assignment to
+ an lvalue of type TYPE. ERRTYPE indicates what kind of error the
+ implicit conversion is. If FNDECL is non-NULL, we are doing the
+ conversion in order to pass the PARMNUMth argument of FNDECL.
+ If FNDECL is NULL, we are doing the conversion in function pointer
+ argument passing, conversion in initialization, etc. */
+
+static tree
+convert_for_assignment (tree type, tree rhs,
+ impl_conv_rhs errtype, tree fndecl, int parmnum,
+ tsubst_flags_t complain, int flags)
+{
+ tree rhstype;
+ enum tree_code coder;
+
+ /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
+ if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
+ rhs = TREE_OPERAND (rhs, 0);
+
+ rhstype = TREE_TYPE (rhs);
+ coder = TREE_CODE (rhstype);
+
+ if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE
+ && vector_types_convertible_p (type, rhstype, true))
+ {
+ rhs = mark_rvalue_use (rhs);
+ return convert (type, rhs);
+ }
+
+ if (rhs == error_mark_node || rhstype == error_mark_node)
+ return error_mark_node;
+ if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
+ return error_mark_node;
+
+ /* The RHS of an assignment cannot have void type. */
+ if (coder == VOID_TYPE)
+ {
+ if (complain & tf_error)
+ error ("void value not ignored as it ought to be");
+ return error_mark_node;
+ }
+
+ if (c_dialect_objc ())
+ {
+ int parmno;
+ tree selector;
+ tree rname = fndecl;
+
+ switch (errtype)
+ {
+ case ICR_ASSIGN:
+ parmno = -1;
+ break;
+ case ICR_INIT:
+ parmno = -2;
+ break;
+ default:
+ selector = objc_message_selector ();
+ parmno = parmnum;
+ if (selector && parmno > 1)
+ {
+ rname = selector;
+ parmno -= 1;
+ }
+ }
+
+ if (objc_compare_types (type, rhstype, parmno, rname))
+ {
+ rhs = mark_rvalue_use (rhs);
+ return convert (type, rhs);
+ }
+ }
+
+ /* [expr.ass]
+
+ The expression is implicitly converted (clause _conv_) to the
+ cv-unqualified type of the left operand.
+
+ We allow bad conversions here because by the time we get to this point
+ we are committed to doing the conversion. If we end up doing a bad
+ conversion, convert_like will complain. */
+ if (!can_convert_arg_bad (type, rhstype, rhs, flags, complain))
+ {
+ /* When -Wno-pmf-conversions is use, we just silently allow
+ conversions from pointers-to-members to plain pointers. If
+ the conversion doesn't work, cp_convert will complain. */
+ if (!warn_pmf2ptr
+ && TYPE_PTR_P (type)
+ && TYPE_PTRMEMFUNC_P (rhstype))
+ rhs = cp_convert (strip_top_quals (type), rhs, complain);
+ else
+ {
+ if (complain & tf_error)
+ {
+ /* If the right-hand side has unknown type, then it is an
+ overloaded function. Call instantiate_type to get error
+ messages. */
+ if (rhstype == unknown_type_node)
+ instantiate_type (type, rhs, tf_warning_or_error);
+ else if (fndecl)
+ error ("cannot convert %qT to %qT for argument %qP to %qD",
+ rhstype, type, parmnum, fndecl);
+ else
+ switch (errtype)
+ {
+ case ICR_DEFAULT_ARGUMENT:
+ error ("cannot convert %qT to %qT in default argument",
+ rhstype, type);
+ break;
+ case ICR_ARGPASS:
+ error ("cannot convert %qT to %qT in argument passing",
+ rhstype, type);
+ break;
+ case ICR_CONVERTING:
+ error ("cannot convert %qT to %qT",
+ rhstype, type);
+ break;
+ case ICR_INIT:
+ error ("cannot convert %qT to %qT in initialization",
+ rhstype, type);
+ break;
+ case ICR_RETURN:
+ error ("cannot convert %qT to %qT in return",
+ rhstype, type);
+ break;
+ case ICR_ASSIGN:
+ error ("cannot convert %qT to %qT in assignment",
+ rhstype, type);
+ break;
+ default:
+ gcc_unreachable();
+ }
+ }
+ return error_mark_node;
+ }
+ }
+ if (warn_suggest_attribute_format)
+ {
+ const enum tree_code codel = TREE_CODE (type);
+ if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
+ && coder == codel
+ && check_missing_format_attribute (type, rhstype)
+ && (complain & tf_warning))
+ switch (errtype)
+ {
+ case ICR_ARGPASS:
+ case ICR_DEFAULT_ARGUMENT:
+ if (fndecl)
+ warning (OPT_Wsuggest_attribute_format,
+ "parameter %qP of %qD might be a candidate "
+ "for a format attribute", parmnum, fndecl);
+ else
+ warning (OPT_Wsuggest_attribute_format,
+ "parameter might be a candidate "
+ "for a format attribute");
+ break;
+ case ICR_CONVERTING:
+ warning (OPT_Wsuggest_attribute_format,
+ "target of conversion might be a candidate "
+ "for a format attribute");
+ break;
+ case ICR_INIT:
+ warning (OPT_Wsuggest_attribute_format,
+ "target of initialization might be a candidate "
+ "for a format attribute");
+ break;
+ case ICR_RETURN:
+ warning (OPT_Wsuggest_attribute_format,
+ "return type might be a candidate "
+ "for a format attribute");
+ break;
+ case ICR_ASSIGN:
+ warning (OPT_Wsuggest_attribute_format,
+ "left-hand side of assignment might be a candidate "
+ "for a format attribute");
+ break;
+ default:
+ gcc_unreachable();
+ }
+ }
+
+ /* If -Wparentheses, warn about a = b = c when a has type bool and b
+ does not. */
+ if (warn_parentheses
+ && TREE_CODE (type) == BOOLEAN_TYPE
+ && TREE_CODE (rhs) == MODIFY_EXPR
+ && !TREE_NO_WARNING (rhs)
+ && TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE
+ && (complain & tf_warning))
+ {
+ location_t loc = EXPR_LOC_OR_LOC (rhs, input_location);
+
+ warning_at (loc, OPT_Wparentheses,
+ "suggest parentheses around assignment used as truth value");
+ TREE_NO_WARNING (rhs) = 1;
+ }
+
+ return perform_implicit_conversion_flags (strip_top_quals (type), rhs,
+ complain, flags);
+}
+
+/* Convert RHS to be of type TYPE.
+ If EXP is nonzero, it is the target of the initialization.
+ ERRTYPE indicates what kind of error the implicit conversion is.
+
+ Two major differences between the behavior of
+ `convert_for_assignment' and `convert_for_initialization'
+ are that references are bashed in the former, while
+ copied in the latter, and aggregates are assigned in
+ the former (operator=) while initialized in the
+ latter (X(X&)).
+
+ If using constructor make sure no conversion operator exists, if one does
+ exist, an ambiguity exists. */
+
+tree
+convert_for_initialization (tree exp, tree type, tree rhs, int flags,
+ impl_conv_rhs errtype, tree fndecl, int parmnum,
+ tsubst_flags_t complain)
+{
+ enum tree_code codel = TREE_CODE (type);
+ tree rhstype;
+ enum tree_code coder;
+
+ /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
+ Strip such NOP_EXPRs, since RHS is used in non-lvalue context. */
+ if (TREE_CODE (rhs) == NOP_EXPR
+ && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0))
+ && codel != REFERENCE_TYPE)
+ rhs = TREE_OPERAND (rhs, 0);
+
+ if (type == error_mark_node
+ || rhs == error_mark_node
+ || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
+ return error_mark_node;
+
+ if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
+ && TREE_CODE (type) != ARRAY_TYPE
+ && (TREE_CODE (type) != REFERENCE_TYPE
+ || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
+ || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
+ && !TYPE_REFFN_P (type))
+ || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
+ rhs = decay_conversion (rhs, complain);
+
+ rhstype = TREE_TYPE (rhs);
+ coder = TREE_CODE (rhstype);
+
+ if (coder == ERROR_MARK)
+ return error_mark_node;
+
+ /* We accept references to incomplete types, so we can
+ return here before checking if RHS is of complete type. */
+
+ if (codel == REFERENCE_TYPE)
+ {
+ /* This should eventually happen in convert_arguments. */
+ int savew = 0, savee = 0;
+
+ if (fndecl)
+ savew = warningcount + werrorcount, savee = errorcount;
+ rhs = initialize_reference (type, rhs, flags, complain);
+
+ if (fndecl
+ && (warningcount + werrorcount > savew || errorcount > savee))
+ inform (input_location,
+ "in passing argument %P of %q+D", parmnum, fndecl);
+
+ return rhs;
+ }
+
+ if (exp != 0)
+ exp = require_complete_type_sfinae (exp, complain);
+ if (exp == error_mark_node)
+ return error_mark_node;
+
+ rhstype = non_reference (rhstype);
+
+ type = complete_type (type);
+
+ if (DIRECT_INIT_EXPR_P (type, rhs))
+ /* Don't try to do copy-initialization if we already have
+ direct-initialization. */
+ return rhs;
+
+ if (MAYBE_CLASS_TYPE_P (type))
+ return perform_implicit_conversion_flags (type, rhs, complain, flags);
+
+ return convert_for_assignment (type, rhs, errtype, fndecl, parmnum,
+ complain, flags);
+}
+
+/* If RETVAL is the address of, or a reference to, a local variable or
+ temporary give an appropriate warning. */
+
+static void
+maybe_warn_about_returning_address_of_local (tree retval)
+{
+ tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
+ tree whats_returned = retval;
+
+ for (;;)
+ {
+ if (TREE_CODE (whats_returned) == COMPOUND_EXPR)
+ whats_returned = TREE_OPERAND (whats_returned, 1);
+ else if (CONVERT_EXPR_P (whats_returned)
+ || TREE_CODE (whats_returned) == NON_LVALUE_EXPR)
+ whats_returned = TREE_OPERAND (whats_returned, 0);
+ else
+ break;
+ }
+
+ if (TREE_CODE (whats_returned) != ADDR_EXPR)
+ return;
+ whats_returned = TREE_OPERAND (whats_returned, 0);
+
+ if (TREE_CODE (valtype) == REFERENCE_TYPE)
+ {
+ if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
+ || TREE_CODE (whats_returned) == TARGET_EXPR)
+ {
+ warning (OPT_Wreturn_local_addr, "returning reference to temporary");
+ return;
+ }
+ if (VAR_P (whats_returned)
+ && DECL_NAME (whats_returned)
+ && TEMP_NAME_P (DECL_NAME (whats_returned)))
+ {
+ warning (OPT_Wreturn_local_addr, "reference to non-lvalue returned");
+ return;
+ }
+ }
+
+ while (TREE_CODE (whats_returned) == COMPONENT_REF
+ || TREE_CODE (whats_returned) == ARRAY_REF)
+ whats_returned = TREE_OPERAND (whats_returned, 0);
+
+ if (DECL_P (whats_returned)
+ && DECL_NAME (whats_returned)
+ && DECL_FUNCTION_SCOPE_P (whats_returned)
+ && !is_capture_proxy (whats_returned)
+ && !(TREE_STATIC (whats_returned)
+ || TREE_PUBLIC (whats_returned)))
+ {
+ if (TREE_CODE (valtype) == REFERENCE_TYPE)
+ warning (OPT_Wreturn_local_addr, "reference to local variable %q+D returned",
+ whats_returned);
+ else
+ warning (OPT_Wreturn_local_addr, "address of local variable %q+D returned",
+ whats_returned);
+ return;
+ }
+}
+
+/* Check that returning RETVAL from the current function is valid.
+ Return an expression explicitly showing all conversions required to
+ change RETVAL into the function return type, and to assign it to
+ the DECL_RESULT for the function. Set *NO_WARNING to true if
+ code reaches end of non-void function warning shouldn't be issued
+ on this RETURN_EXPR. */
+
+tree
+check_return_expr (tree retval, bool *no_warning)
+{
+ tree result;
+ /* The type actually returned by the function. */
+ tree valtype;
+ /* The type the function is declared to return, or void if
+ the declared type is incomplete. */
+ tree functype;
+ int fn_returns_value_p;
+ bool named_return_value_okay_p;
+
+ *no_warning = false;
+
+ if (flag_cilkplus && retval && contains_cilk_spawn_stmt (retval))
+ {
+ error_at (EXPR_LOCATION (retval), "use of %<_Cilk_spawn%> in a return "
+ "statement is not allowed");
+ return NULL_TREE;
+ }
+
+ /* A `volatile' function is one that isn't supposed to return, ever.
+ (This is a G++ extension, used to get better code for functions
+ that call the `volatile' function.) */
+ if (TREE_THIS_VOLATILE (current_function_decl))
+ warning (0, "function declared %<noreturn%> has a %<return%> statement");
+
+ /* Check for various simple errors. */
+ if (DECL_DESTRUCTOR_P (current_function_decl))
+ {
+ if (retval)
+ error ("returning a value from a destructor");
+ return NULL_TREE;
+ }
+ else if (DECL_CONSTRUCTOR_P (current_function_decl))
+ {
+ if (in_function_try_handler)
+ /* If a return statement appears in a handler of the
+ function-try-block of a constructor, the program is ill-formed. */
+ error ("cannot return from a handler of a function-try-block of a constructor");
+ else if (retval)
+ /* You can't return a value from a constructor. */
+ error ("returning a value from a constructor");
+ return NULL_TREE;
+ }
+
+ if (processing_template_decl)
+ {
+ current_function_returns_value = 1;
+ if (check_for_bare_parameter_packs (retval))
+ retval = error_mark_node;
+ return retval;
+ }
+
+ functype = TREE_TYPE (TREE_TYPE (current_function_decl));
+
+ /* Deduce auto return type from a return statement. */
+ if (current_function_auto_return_pattern)
+ {
+ tree auto_node;
+ tree type;
+
+ if (!retval && !is_auto (current_function_auto_return_pattern))
+ {
+ /* Give a helpful error message. */
+ error ("return-statement with no value, in function returning %qT",
+ current_function_auto_return_pattern);
+ inform (input_location, "only plain %<auto%> return type can be "
+ "deduced to %<void%>");
+ type = error_mark_node;
+ }
+ else if (retval && BRACE_ENCLOSED_INITIALIZER_P (retval))
+ {
+ error ("returning initializer list");
+ type = error_mark_node;
+ }
+ else
+ {
+ if (!retval)
+ retval = void_zero_node;
+ auto_node = type_uses_auto (current_function_auto_return_pattern);
+ type = do_auto_deduction (current_function_auto_return_pattern,
+ retval, auto_node);
+ }
+
+ if (type == error_mark_node)
+ /* Leave it. */;
+ else if (functype == current_function_auto_return_pattern)
+ apply_deduced_return_type (current_function_decl, type);
+ else
+ /* A mismatch should have been diagnosed in do_auto_deduction. */
+ gcc_assert (same_type_p (type, functype));
+ functype = type;
+ }
+
+ /* When no explicit return-value is given in a function with a named
+ return value, the named return value is used. */
+ result = DECL_RESULT (current_function_decl);
+ valtype = TREE_TYPE (result);
+ gcc_assert (valtype != NULL_TREE);
+ fn_returns_value_p = !VOID_TYPE_P (valtype);
+ if (!retval && DECL_NAME (result) && fn_returns_value_p)
+ retval = result;
+
+ /* Check for a return statement with no return value in a function
+ that's supposed to return a value. */
+ if (!retval && fn_returns_value_p)
+ {
+ if (functype != error_mark_node)
+ permerror (input_location, "return-statement with no value, in "
+ "function returning %qT", valtype);
+ /* Remember that this function did return. */
+ current_function_returns_value = 1;
+ /* And signal caller that TREE_NO_WARNING should be set on the
+ RETURN_EXPR to avoid control reaches end of non-void function
+ warnings in tree-cfg.c. */
+ *no_warning = true;
+ }
+ /* Check for a return statement with a value in a function that
+ isn't supposed to return a value. */
+ else if (retval && !fn_returns_value_p)
+ {
+ if (VOID_TYPE_P (TREE_TYPE (retval)))
+ /* You can return a `void' value from a function of `void'
+ type. In that case, we have to evaluate the expression for
+ its side-effects. */
+ finish_expr_stmt (retval);
+ else
+ permerror (input_location, "return-statement with a value, in function "
+ "returning 'void'");
+ current_function_returns_null = 1;
+
+ /* There's really no value to return, after all. */
+ return NULL_TREE;
+ }
+ else if (!retval)
+ /* Remember that this function can sometimes return without a
+ value. */
+ current_function_returns_null = 1;
+ else
+ /* Remember that this function did return a value. */
+ current_function_returns_value = 1;
+
+ /* Check for erroneous operands -- but after giving ourselves a
+ chance to provide an error about returning a value from a void
+ function. */
+ if (error_operand_p (retval))
+ {
+ current_function_return_value = error_mark_node;
+ return error_mark_node;
+ }
+
+ /* Only operator new(...) throw(), can return NULL [expr.new/13]. */
+ if ((DECL_OVERLOADED_OPERATOR_P (current_function_decl) == NEW_EXPR
+ || DECL_OVERLOADED_OPERATOR_P (current_function_decl) == VEC_NEW_EXPR)
+ && !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
+ && ! flag_check_new
+ && retval && null_ptr_cst_p (retval))
+ warning (0, "%<operator new%> must not return NULL unless it is "
+ "declared %<throw()%> (or -fcheck-new is in effect)");
+
+ /* Effective C++ rule 15. See also start_function. */
+ if (warn_ecpp
+ && DECL_NAME (current_function_decl) == ansi_assopname(NOP_EXPR))
+ {
+ bool warn = true;
+
+ /* The function return type must be a reference to the current
+ class. */
+ if (TREE_CODE (valtype) == REFERENCE_TYPE
+ && same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
+ {
+ /* Returning '*this' is obviously OK. */
+ if (retval == current_class_ref)
+ warn = false;
+ /* If we are calling a function whose return type is the same of
+ the current class reference, it is ok. */
+ else if (INDIRECT_REF_P (retval)
+ && TREE_CODE (TREE_OPERAND (retval, 0)) == CALL_EXPR)
+ warn = false;
+ }
+
+ if (warn)
+ warning (OPT_Weffc__, "%<operator=%> should return a reference to %<*this%>");
+ }
+
+ /* The fabled Named Return Value optimization, as per [class.copy]/15:
+
+ [...] For a function with a class return type, if the expression
+ in the return statement is the name of a local object, and the cv-
+ unqualified type of the local object is the same as the function
+ return type, an implementation is permitted to omit creating the tem-
+ porary object to hold the function return value [...]
+
+ So, if this is a value-returning function that always returns the same
+ local variable, remember it.
+
+ It might be nice to be more flexible, and choose the first suitable
+ variable even if the function sometimes returns something else, but
+ then we run the risk of clobbering the variable we chose if the other
+ returned expression uses the chosen variable somehow. And people expect
+ this restriction, anyway. (jason 2000-11-19)
+
+ See finish_function and finalize_nrv for the rest of this optimization. */
+
+ named_return_value_okay_p =
+ (retval != NULL_TREE
+ /* Must be a local, automatic variable. */
+ && VAR_P (retval)
+ && DECL_CONTEXT (retval) == current_function_decl
+ && ! TREE_STATIC (retval)
+ /* And not a lambda or anonymous union proxy. */
+ && !DECL_HAS_VALUE_EXPR_P (retval)
+ && (DECL_ALIGN (retval) <= DECL_ALIGN (result))
+ /* The cv-unqualified type of the returned value must be the
+ same as the cv-unqualified return type of the
+ function. */
+ && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
+ (TYPE_MAIN_VARIANT (functype)))
+ /* And the returned value must be non-volatile. */
+ && ! TYPE_VOLATILE (TREE_TYPE (retval)));
+
+ if (fn_returns_value_p && flag_elide_constructors)
+ {
+ if (named_return_value_okay_p
+ && (current_function_return_value == NULL_TREE
+ || current_function_return_value == retval))
+ current_function_return_value = retval;
+ else
+ current_function_return_value = error_mark_node;
+ }
+
+ /* We don't need to do any conversions when there's nothing being
+ returned. */
+ if (!retval)
+ return NULL_TREE;
+
+ /* Do any required conversions. */
+ if (retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
+ /* No conversions are required. */
+ ;
+ else
+ {
+ int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
+
+ /* The functype's return type will have been set to void, if it
+ was an incomplete type. Just treat this as 'return;' */
+ if (VOID_TYPE_P (functype))
+ return error_mark_node;
+
+ /* Under C++0x [12.8/16 class.copy], a returned lvalue is sometimes
+ treated as an rvalue for the purposes of overload resolution to
+ favor move constructors over copy constructors.
+
+ Note that these conditions are similar to, but not as strict as,
+ the conditions for the named return value optimization. */
+ if ((cxx_dialect != cxx98)
+ && ((VAR_P (retval) && !DECL_HAS_VALUE_EXPR_P (retval))
+ || TREE_CODE (retval) == PARM_DECL)
+ && DECL_CONTEXT (retval) == current_function_decl
+ && !TREE_STATIC (retval)
+ && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
+ (TYPE_MAIN_VARIANT (functype)))
+ /* This is only interesting for class type. */
+ && CLASS_TYPE_P (functype))
+ flags = flags | LOOKUP_PREFER_RVALUE;
+
+ /* First convert the value to the function's return type, then
+ to the type of return value's location to handle the
+ case that functype is smaller than the valtype. */
+ retval = convert_for_initialization
+ (NULL_TREE, functype, retval, flags, ICR_RETURN, NULL_TREE, 0,
+ tf_warning_or_error);
+ retval = convert (valtype, retval);
+
+ /* If the conversion failed, treat this just like `return;'. */
+ if (retval == error_mark_node)
+ return retval;
+ /* We can't initialize a register from a AGGR_INIT_EXPR. */
+ else if (! cfun->returns_struct
+ && TREE_CODE (retval) == TARGET_EXPR
+ && TREE_CODE (TREE_OPERAND (retval, 1)) == AGGR_INIT_EXPR)
+ retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
+ TREE_OPERAND (retval, 0));
+ else
+ maybe_warn_about_returning_address_of_local (retval);
+ }
+
+ /* Actually copy the value returned into the appropriate location. */
+ if (retval && retval != result)
+ retval = build2 (INIT_EXPR, TREE_TYPE (result), result, retval);
+
+ return retval;
+}
+
+
+/* Returns nonzero if the pointer-type FROM can be converted to the
+ pointer-type TO via a qualification conversion. If CONSTP is -1,
+ then we return nonzero if the pointers are similar, and the
+ cv-qualification signature of FROM is a proper subset of that of TO.
+
+ If CONSTP is positive, then all outer pointers have been
+ const-qualified. */
+
+static int
+comp_ptr_ttypes_real (tree to, tree from, int constp)
+{
+ bool to_more_cv_qualified = false;
+ bool is_opaque_pointer = false;
+
+ for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
+ {
+ if (TREE_CODE (to) != TREE_CODE (from))
+ return 0;
+
+ if (TREE_CODE (from) == OFFSET_TYPE
+ && !same_type_p (TYPE_OFFSET_BASETYPE (from),
+ TYPE_OFFSET_BASETYPE (to)))
+ return 0;
+
+ /* Const and volatile mean something different for function types,
+ so the usual checks are not appropriate. */
+ if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
+ {
+ if (!at_least_as_qualified_p (to, from))
+ return 0;
+
+ if (!at_least_as_qualified_p (from, to))
+ {
+ if (constp == 0)
+ return 0;
+ to_more_cv_qualified = true;
+ }
+
+ if (constp > 0)
+ constp &= TYPE_READONLY (to);
+ }
+
+ if (TREE_CODE (to) == VECTOR_TYPE)
+ is_opaque_pointer = vector_targets_convertible_p (to, from);
+
+ if (!TYPE_PTR_P (to) && !TYPE_PTRDATAMEM_P (to))
+ return ((constp >= 0 || to_more_cv_qualified)
+ && (is_opaque_pointer
+ || same_type_ignoring_top_level_qualifiers_p (to, from)));
+ }
+}
+
+/* When comparing, say, char ** to char const **, this function takes
+ the 'char *' and 'char const *'. Do not pass non-pointer/reference
+ types to this function. */
+
+int
+comp_ptr_ttypes (tree to, tree from)
+{
+ return comp_ptr_ttypes_real (to, from, 1);
+}
+
+/* Returns true iff FNTYPE is a non-class type that involves
+ error_mark_node. We can get FUNCTION_TYPE with buried error_mark_node
+ if a parameter type is ill-formed. */
+
+bool
+error_type_p (const_tree type)
+{
+ tree t;
+
+ switch (TREE_CODE (type))
+ {
+ case ERROR_MARK:
+ return true;
+
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ case OFFSET_TYPE:
+ return error_type_p (TREE_TYPE (type));
+
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ if (error_type_p (TREE_TYPE (type)))
+ return true;
+ for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
+ if (error_type_p (TREE_VALUE (t)))
+ return true;
+ return false;
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (type))
+ return error_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type));
+ return false;
+
+ default:
+ return false;
+ }
+}
+
+/* Returns true if to and from are (possibly multi-level) pointers to the same
+ type or inheritance-related types, regardless of cv-quals. */
+
+bool
+ptr_reasonably_similar (const_tree to, const_tree from)
+{
+ for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
+ {
+ /* Any target type is similar enough to void. */
+ if (VOID_TYPE_P (to))
+ return !error_type_p (from);
+ if (VOID_TYPE_P (from))
+ return !error_type_p (to);
+
+ if (TREE_CODE (to) != TREE_CODE (from))
+ return false;
+
+ if (TREE_CODE (from) == OFFSET_TYPE
+ && comptypes (TYPE_OFFSET_BASETYPE (to),
+ TYPE_OFFSET_BASETYPE (from),
+ COMPARE_BASE | COMPARE_DERIVED))
+ continue;
+
+ if (TREE_CODE (to) == VECTOR_TYPE
+ && vector_types_convertible_p (to, from, false))
+ return true;
+
+ if (TREE_CODE (to) == INTEGER_TYPE
+ && TYPE_PRECISION (to) == TYPE_PRECISION (from))
+ return true;
+
+ if (TREE_CODE (to) == FUNCTION_TYPE)
+ return !error_type_p (to) && !error_type_p (from);
+
+ if (!TYPE_PTR_P (to))
+ {
+ /* When either type is incomplete avoid DERIVED_FROM_P,
+ which may call complete_type (c++/57942). */
+ bool b = !COMPLETE_TYPE_P (to) || !COMPLETE_TYPE_P (from);
+ return comptypes
+ (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
+ b ? COMPARE_STRICT : COMPARE_BASE | COMPARE_DERIVED);
+ }
+ }
+}
+
+/* Return true if TO and FROM (both of which are POINTER_TYPEs or
+ pointer-to-member types) are the same, ignoring cv-qualification at
+ all levels. */
+
+bool
+comp_ptr_ttypes_const (tree to, tree from)
+{
+ bool is_opaque_pointer = false;
+
+ for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
+ {
+ if (TREE_CODE (to) != TREE_CODE (from))
+ return false;
+
+ if (TREE_CODE (from) == OFFSET_TYPE
+ && same_type_p (TYPE_OFFSET_BASETYPE (from),
+ TYPE_OFFSET_BASETYPE (to)))
+ continue;
+
+ if (TREE_CODE (to) == VECTOR_TYPE)
+ is_opaque_pointer = vector_targets_convertible_p (to, from);
+
+ if (!TYPE_PTR_P (to))
+ return (is_opaque_pointer
+ || same_type_ignoring_top_level_qualifiers_p (to, from));
+ }
+}
+
+/* Returns the type qualifiers for this type, including the qualifiers on the
+ elements for an array type. */
+
+int
+cp_type_quals (const_tree type)
+{
+ int quals;
+ /* This CONST_CAST is okay because strip_array_types returns its
+ argument unmodified and we assign it to a const_tree. */
+ type = strip_array_types (CONST_CAST_TREE (type));
+ if (type == error_mark_node
+ /* Quals on a FUNCTION_TYPE are memfn quals. */
+ || TREE_CODE (type) == FUNCTION_TYPE)
+ return TYPE_UNQUALIFIED;
+ quals = TYPE_QUALS (type);
+ /* METHOD and REFERENCE_TYPEs should never have quals. */
+ gcc_assert ((TREE_CODE (type) != METHOD_TYPE
+ && TREE_CODE (type) != REFERENCE_TYPE)
+ || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE))
+ == TYPE_UNQUALIFIED));
+ return quals;
+}
+
+/* Returns the function-ref-qualifier for TYPE */
+
+cp_ref_qualifier
+type_memfn_rqual (const_tree type)
+{
+ gcc_assert (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE);
+
+ if (!FUNCTION_REF_QUALIFIED (type))
+ return REF_QUAL_NONE;
+ else if (FUNCTION_RVALUE_QUALIFIED (type))
+ return REF_QUAL_RVALUE;
+ else
+ return REF_QUAL_LVALUE;
+}
+
+/* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
+ METHOD_TYPE. */
+
+int
+type_memfn_quals (const_tree type)
+{
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ return TYPE_QUALS (type);
+ else if (TREE_CODE (type) == METHOD_TYPE)
+ return cp_type_quals (class_of_this_parm (type));
+ else
+ gcc_unreachable ();
+}
+
+/* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to
+ MEMFN_QUALS and its ref-qualifier to RQUAL. */
+
+tree
+apply_memfn_quals (tree type, cp_cv_quals memfn_quals, cp_ref_qualifier rqual)
+{
+ /* Could handle METHOD_TYPE here if necessary. */
+ gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
+ if (TYPE_QUALS (type) == memfn_quals
+ && type_memfn_rqual (type) == rqual)
+ return type;
+
+ /* This should really have a different TYPE_MAIN_VARIANT, but that gets
+ complex. */
+ tree result = build_qualified_type (type, memfn_quals);
+ result = build_exception_variant (result, TYPE_RAISES_EXCEPTIONS (type));
+ return build_ref_qualified_type (result, rqual);
+}
+
+/* Returns nonzero if TYPE is const or volatile. */
+
+bool
+cv_qualified_p (const_tree type)
+{
+ int quals = cp_type_quals (type);
+ return (quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)) != 0;
+}
+
+/* Returns nonzero if the TYPE contains a mutable member. */
+
+bool
+cp_has_mutable_p (const_tree type)
+{
+ /* This CONST_CAST is okay because strip_array_types returns its
+ argument unmodified and we assign it to a const_tree. */
+ type = strip_array_types (CONST_CAST_TREE(type));
+
+ return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type);
+}
+
+/* Set TREE_READONLY and TREE_VOLATILE on DECL as indicated by the
+ TYPE_QUALS. For a VAR_DECL, this may be an optimistic
+ approximation. In particular, consider:
+
+ int f();
+ struct S { int i; };
+ const S s = { f(); }
+
+ Here, we will make "s" as TREE_READONLY (because it is declared
+ "const") -- only to reverse ourselves upon seeing that the
+ initializer is non-constant. */
+
+void
+cp_apply_type_quals_to_decl (int type_quals, tree decl)
+{
+ tree type = TREE_TYPE (decl);
+
+ if (type == error_mark_node)
+ return;
+
+ if (TREE_CODE (decl) == TYPE_DECL)
+ return;
+
+ gcc_assert (!(TREE_CODE (type) == FUNCTION_TYPE
+ && type_quals != TYPE_UNQUALIFIED));
+
+ /* Avoid setting TREE_READONLY incorrectly. */
+ /* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr
+ constructor can produce constant init, so rely on cp_finish_decl to
+ clear TREE_READONLY if the variable has non-constant init. */
+
+ /* If the type has (or might have) a mutable component, that component
+ might be modified. */
+ if (TYPE_HAS_MUTABLE_P (type) || !COMPLETE_TYPE_P (type))
+ type_quals &= ~TYPE_QUAL_CONST;
+
+ c_apply_type_quals_to_decl (type_quals, decl);
+}
+
+/* Subroutine of casts_away_constness. Make T1 and T2 point at
+ exemplar types such that casting T1 to T2 is casting away constness
+ if and only if there is no implicit conversion from T1 to T2. */
+
+static void
+casts_away_constness_r (tree *t1, tree *t2, tsubst_flags_t complain)
+{
+ int quals1;
+ int quals2;
+
+ /* [expr.const.cast]
+
+ For multi-level pointer to members and multi-level mixed pointers
+ and pointers to members (conv.qual), the "member" aspect of a
+ pointer to member level is ignored when determining if a const
+ cv-qualifier has been cast away. */
+ /* [expr.const.cast]
+
+ For two pointer types:
+
+ X1 is T1cv1,1 * ... cv1,N * where T1 is not a pointer type
+ X2 is T2cv2,1 * ... cv2,M * where T2 is not a pointer type
+ K is min(N,M)
+
+ casting from X1 to X2 casts away constness if, for a non-pointer
+ type T there does not exist an implicit conversion (clause
+ _conv_) from:
+
+ Tcv1,(N-K+1) * cv1,(N-K+2) * ... cv1,N *
+
+ to
+
+ Tcv2,(M-K+1) * cv2,(M-K+2) * ... cv2,M *. */
+ if ((!TYPE_PTR_P (*t1) && !TYPE_PTRDATAMEM_P (*t1))
+ || (!TYPE_PTR_P (*t2) && !TYPE_PTRDATAMEM_P (*t2)))
+ {
+ *t1 = cp_build_qualified_type (void_type_node,
+ cp_type_quals (*t1));
+ *t2 = cp_build_qualified_type (void_type_node,
+ cp_type_quals (*t2));
+ return;
+ }
+
+ quals1 = cp_type_quals (*t1);
+ quals2 = cp_type_quals (*t2);
+
+ if (TYPE_PTRDATAMEM_P (*t1))
+ *t1 = TYPE_PTRMEM_POINTED_TO_TYPE (*t1);
+ else
+ *t1 = TREE_TYPE (*t1);
+ if (TYPE_PTRDATAMEM_P (*t2))
+ *t2 = TYPE_PTRMEM_POINTED_TO_TYPE (*t2);
+ else
+ *t2 = TREE_TYPE (*t2);
+
+ casts_away_constness_r (t1, t2, complain);
+ *t1 = build_pointer_type (*t1);
+ *t2 = build_pointer_type (*t2);
+ *t1 = cp_build_qualified_type (*t1, quals1);
+ *t2 = cp_build_qualified_type (*t2, quals2);
+}
+
+/* Returns nonzero if casting from TYPE1 to TYPE2 casts away
+ constness.
+
+ ??? This function returns non-zero if casting away qualifiers not
+ just const. We would like to return to the caller exactly which
+ qualifiers are casted away to give more accurate diagnostics.
+*/
+
+static bool
+casts_away_constness (tree t1, tree t2, tsubst_flags_t complain)
+{
+ if (TREE_CODE (t2) == REFERENCE_TYPE)
+ {
+ /* [expr.const.cast]
+
+ Casting from an lvalue of type T1 to an lvalue of type T2
+ using a reference cast casts away constness if a cast from an
+ rvalue of type "pointer to T1" to the type "pointer to T2"
+ casts away constness. */
+ t1 = (TREE_CODE (t1) == REFERENCE_TYPE ? TREE_TYPE (t1) : t1);
+ return casts_away_constness (build_pointer_type (t1),
+ build_pointer_type (TREE_TYPE (t2)),
+ complain);
+ }
+
+ if (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2))
+ /* [expr.const.cast]
+
+ Casting from an rvalue of type "pointer to data member of X
+ of type T1" to the type "pointer to data member of Y of type
+ T2" casts away constness if a cast from an rvalue of type
+ "pointer to T1" to the type "pointer to T2" casts away
+ constness. */
+ return casts_away_constness
+ (build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t1)),
+ build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)),
+ complain);
+
+ /* Casting away constness is only something that makes sense for
+ pointer or reference types. */
+ if (!TYPE_PTR_P (t1) || !TYPE_PTR_P (t2))
+ return false;
+
+ /* Top-level qualifiers don't matter. */
+ t1 = TYPE_MAIN_VARIANT (t1);
+ t2 = TYPE_MAIN_VARIANT (t2);
+ casts_away_constness_r (&t1, &t2, complain);
+ if (!can_convert (t2, t1, complain))
+ return true;
+
+ return false;
+}
+
+/* If T is a REFERENCE_TYPE return the type to which T refers.
+ Otherwise, return T itself. */
+
+tree
+non_reference (tree t)
+{
+ if (t && TREE_CODE (t) == REFERENCE_TYPE)
+ t = TREE_TYPE (t);
+ return t;
+}
+
+
+/* Return nonzero if REF is an lvalue valid for this language;
+ otherwise, print an error message and return zero. USE says
+ how the lvalue is being used and so selects the error message. */
+
+int
+lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
+{
+ cp_lvalue_kind kind = lvalue_kind (ref);
+
+ if (kind == clk_none)
+ {
+ if (complain & tf_error)
+ lvalue_error (input_location, use);
+ return 0;
+ }
+ else if (kind & (clk_rvalueref|clk_class))
+ {
+ if (!(complain & tf_error))
+ return 0;
+ if (kind & clk_class)
+ /* Make this a permerror because we used to accept it. */
+ permerror (input_location, "using temporary as lvalue");
+ else
+ error ("using xvalue (rvalue reference) as lvalue");
+ }
+ return 1;
+}
+
+/* Return true if a user-defined literal operator is a raw operator. */
+
+bool
+check_raw_literal_operator (const_tree decl)
+{
+ tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ tree argtype;
+ int arity;
+ bool maybe_raw_p = false;
+
+ /* Count the number and type of arguments and check for ellipsis. */
+ for (argtype = argtypes, arity = 0;
+ argtype && argtype != void_list_node;
+ ++arity, argtype = TREE_CHAIN (argtype))
+ {
+ tree t = TREE_VALUE (argtype);
+
+ if (same_type_p (t, const_string_type_node))
+ maybe_raw_p = true;
+ }
+ if (!argtype)
+ return false; /* Found ellipsis. */
+
+ if (!maybe_raw_p || arity != 1)
+ return false;
+
+ return true;
+}
+
+
+/* Return true if a user-defined literal operator has one of the allowed
+ argument types. */
+
+bool
+check_literal_operator_args (const_tree decl,
+ bool *long_long_unsigned_p, bool *long_double_p)
+{
+ tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
+
+ *long_long_unsigned_p = false;
+ *long_double_p = false;
+ if (processing_template_decl || processing_specialization)
+ return argtypes == void_list_node;
+ else
+ {
+ tree argtype;
+ int arity;
+ int max_arity = 2;
+
+ /* Count the number and type of arguments and check for ellipsis. */
+ for (argtype = argtypes, arity = 0;
+ argtype && argtype != void_list_node;
+ argtype = TREE_CHAIN (argtype))
+ {
+ tree t = TREE_VALUE (argtype);
+ ++arity;
+
+ if (TYPE_PTR_P (t))
+ {
+ bool maybe_raw_p = false;
+ t = TREE_TYPE (t);
+ if (cp_type_quals (t) != TYPE_QUAL_CONST)
+ return false;
+ t = TYPE_MAIN_VARIANT (t);
+ if ((maybe_raw_p = same_type_p (t, char_type_node))
+ || same_type_p (t, wchar_type_node)
+ || same_type_p (t, char16_type_node)
+ || same_type_p (t, char32_type_node))
+ {
+ argtype = TREE_CHAIN (argtype);
+ if (!argtype)
+ return false;
+ t = TREE_VALUE (argtype);
+ if (maybe_raw_p && argtype == void_list_node)
+ return true;
+ else if (same_type_p (t, size_type_node))
+ {
+ ++arity;
+ continue;
+ }
+ else
+ return false;
+ }
+ }
+ else if (same_type_p (t, long_long_unsigned_type_node))
+ {
+ max_arity = 1;
+ *long_long_unsigned_p = true;
+ }
+ else if (same_type_p (t, long_double_type_node))
+ {
+ max_arity = 1;
+ *long_double_p = true;
+ }
+ else if (same_type_p (t, char_type_node))
+ max_arity = 1;
+ else if (same_type_p (t, wchar_type_node))
+ max_arity = 1;
+ else if (same_type_p (t, char16_type_node))
+ max_arity = 1;
+ else if (same_type_p (t, char32_type_node))
+ max_arity = 1;
+ else
+ return false;
+ }
+ if (!argtype)
+ return false; /* Found ellipsis. */
+
+ if (arity != max_arity)
+ return false;
+
+ return true;
+ }
+}
diff --git a/gcc-4.9/gcc/cp/typeck2.c b/gcc-4.9/gcc/cp/typeck2.c
new file mode 100644
index 000000000..bd21ad8c3
--- /dev/null
+++ b/gcc-4.9/gcc/cp/typeck2.c
@@ -0,0 +1,2074 @@
+/* Report error messages, build initializers, and perform
+ some front-end optimizations for C++ compiler.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Hacked by Michael Tiemann (tiemann@cygnus.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* This file is part of the C++ front end.
+ It contains routines to build C++ expressions given their operands,
+ including computing the types of the result, C and C++ specific error
+ checks, and some optimization. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stor-layout.h"
+#include "varasm.h"
+#include "intl.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "diagnostic-core.h"
+
+static tree
+process_init_constructor (tree type, tree init, tsubst_flags_t complain);
+
+
+/* Print an error message stemming from an attempt to use
+ BASETYPE as a base class for TYPE. */
+
+tree
+error_not_base_type (tree basetype, tree type)
+{
+ if (TREE_CODE (basetype) == FUNCTION_DECL)
+ basetype = DECL_CONTEXT (basetype);
+ error ("type %qT is not a base type for type %qT", basetype, type);
+ return error_mark_node;
+}
+
+tree
+binfo_or_else (tree base, tree type)
+{
+ tree binfo = lookup_base (type, base, ba_unique,
+ NULL, tf_warning_or_error);
+
+ if (binfo == error_mark_node)
+ return NULL_TREE;
+ else if (!binfo)
+ error_not_base_type (base, type);
+ return binfo;
+}
+
+/* According to ARM $7.1.6, "A `const' object may be initialized, but its
+ value may not be changed thereafter. */
+
+void
+cxx_readonly_error (tree arg, enum lvalue_use errstring)
+{
+
+/* This macro is used to emit diagnostics to ensure that all format
+ strings are complete sentences, visible to gettext and checked at
+ compile time. */
+
+#define ERROR_FOR_ASSIGNMENT(AS, ASM, IN, DE, ARG) \
+ do { \
+ switch (errstring) \
+ { \
+ case lv_assign: \
+ error(AS, ARG); \
+ break; \
+ case lv_asm: \
+ error(ASM, ARG); \
+ break; \
+ case lv_increment: \
+ error (IN, ARG); \
+ break; \
+ case lv_decrement: \
+ error (DE, ARG); \
+ break; \
+ default: \
+ gcc_unreachable (); \
+ } \
+ } while (0)
+
+ /* Handle C++-specific things first. */
+
+ if (VAR_P (arg)
+ && DECL_LANG_SPECIFIC (arg)
+ && DECL_IN_AGGR_P (arg)
+ && !TREE_STATIC (arg))
+ ERROR_FOR_ASSIGNMENT (G_("assignment of "
+ "constant field %qD"),
+ G_("constant field %qD "
+ "used as %<asm%> output"),
+ G_("increment of "
+ "constant field %qD"),
+ G_("decrement of "
+ "constant field %qD"),
+ arg);
+ else if (INDIRECT_REF_P (arg)
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))) == REFERENCE_TYPE
+ && (VAR_P (TREE_OPERAND (arg, 0))
+ || TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL))
+ ERROR_FOR_ASSIGNMENT (G_("assignment of "
+ "read-only reference %qD"),
+ G_("read-only reference %qD "
+ "used as %<asm%> output"),
+ G_("increment of "
+ "read-only reference %qD"),
+ G_("decrement of "
+ "read-only reference %qD"),
+ TREE_OPERAND (arg, 0));
+ else
+ readonly_error (input_location, arg, errstring);
+}
+
+
+/* Structure that holds information about declarations whose type was
+ incomplete and we could not check whether it was abstract or not. */
+
+struct GTY((chain_next ("%h.next"))) pending_abstract_type {
+ /* Declaration which we are checking for abstractness. It is either
+ a DECL node, or an IDENTIFIER_NODE if we do not have a full
+ declaration available. */
+ tree decl;
+
+ /* Type which will be checked for abstractness. */
+ tree type;
+
+ /* Kind of use in an unnamed declarator. */
+ abstract_class_use use;
+
+ /* Position of the declaration. This is only needed for IDENTIFIER_NODEs,
+ because DECLs already carry locus information. */
+ location_t locus;
+
+ /* Link to the next element in list. */
+ struct pending_abstract_type* next;
+};
+
+
+/* Compute the hash value of the node VAL. This function is used by the
+ hash table abstract_pending_vars. */
+
+static hashval_t
+pat_calc_hash (const void* val)
+{
+ const struct pending_abstract_type *pat =
+ (const struct pending_abstract_type *) val;
+ return (hashval_t) TYPE_UID (pat->type);
+}
+
+
+/* Compare node VAL1 with the type VAL2. This function is used by the
+ hash table abstract_pending_vars. */
+
+static int
+pat_compare (const void* val1, const void* val2)
+{
+ const struct pending_abstract_type *const pat1 =
+ (const struct pending_abstract_type *) val1;
+ const_tree const type2 = (const_tree)val2;
+
+ return (pat1->type == type2);
+}
+
+/* Hash table that maintains pending_abstract_type nodes, for which we still
+ need to check for type abstractness. The key of the table is the type
+ of the declaration. */
+static GTY ((param_is (struct pending_abstract_type)))
+htab_t abstract_pending_vars = NULL;
+
+static int abstract_virtuals_error_sfinae (tree, tree, abstract_class_use, tsubst_flags_t);
+
+/* This function is called after TYPE is completed, and will check if there
+ are pending declarations for which we still need to verify the abstractness
+ of TYPE, and emit a diagnostic (through abstract_virtuals_error) if TYPE
+ turned out to be incomplete. */
+
+void
+complete_type_check_abstract (tree type)
+{
+ void **slot;
+ struct pending_abstract_type *pat;
+ location_t cur_loc = input_location;
+
+ gcc_assert (COMPLETE_TYPE_P (type));
+
+ if (!abstract_pending_vars)
+ return;
+
+ /* Retrieve the list of pending declarations for this type. */
+ slot = htab_find_slot_with_hash (abstract_pending_vars, type,
+ (hashval_t)TYPE_UID (type), NO_INSERT);
+ if (!slot)
+ return;
+ pat = (struct pending_abstract_type*)*slot;
+ gcc_assert (pat);
+
+ /* If the type is not abstract, do not do anything. */
+ if (CLASSTYPE_PURE_VIRTUALS (type))
+ {
+ struct pending_abstract_type *prev = 0, *next;
+
+ /* Reverse the list to emit the errors in top-down order. */
+ for (; pat; pat = next)
+ {
+ next = pat->next;
+ pat->next = prev;
+ prev = pat;
+ }
+ pat = prev;
+
+ /* Go through the list, and call abstract_virtuals_error for each
+ element: it will issue a diagnostic if the type is abstract. */
+ while (pat)
+ {
+ gcc_assert (type == pat->type);
+
+ /* Tweak input_location so that the diagnostic appears at the correct
+ location. Notice that this is only needed if the decl is an
+ IDENTIFIER_NODE. */
+ input_location = pat->locus;
+ abstract_virtuals_error_sfinae (pat->decl, pat->type, pat->use,
+ tf_warning_or_error);
+ pat = pat->next;
+ }
+ }
+
+ htab_clear_slot (abstract_pending_vars, slot);
+
+ input_location = cur_loc;
+}
+
+
+/* If TYPE has abstract virtual functions, issue an error about trying
+ to create an object of that type. DECL is the object declared, or
+ NULL_TREE if the declaration is unavailable, in which case USE specifies
+ the kind of invalid use. Returns 1 if an error occurred; zero if
+ all was well. */
+
+static int
+abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
+ tsubst_flags_t complain)
+{
+ vec<tree, va_gc> *pure;
+
+ /* This function applies only to classes. Any other entity can never
+ be abstract. */
+ if (!CLASS_TYPE_P (type))
+ return 0;
+ type = TYPE_MAIN_VARIANT (type);
+
+#if 0
+ /* Instantiation here seems to be required by the standard,
+ but breaks e.g. boost::bind. FIXME! */
+ /* In SFINAE, non-N3276 context, force instantiation. */
+ if (!(complain & (tf_error|tf_decltype)))
+ complete_type (type);
+#endif
+
+ /* If the type is incomplete, we register it within a hash table,
+ so that we can check again once it is completed. This makes sense
+ only for objects for which we have a declaration or at least a
+ name. */
+ if (!COMPLETE_TYPE_P (type) && (complain & tf_error))
+ {
+ void **slot;
+ struct pending_abstract_type *pat;
+
+ gcc_assert (!decl || DECL_P (decl) || identifier_p (decl));
+
+ if (!abstract_pending_vars)
+ abstract_pending_vars = htab_create_ggc (31, &pat_calc_hash,
+ &pat_compare, NULL);
+
+ slot = htab_find_slot_with_hash (abstract_pending_vars, type,
+ (hashval_t)TYPE_UID (type), INSERT);
+
+ pat = ggc_alloc_pending_abstract_type ();
+ pat->type = type;
+ pat->decl = decl;
+ pat->use = use;
+ pat->locus = ((decl && DECL_P (decl))
+ ? DECL_SOURCE_LOCATION (decl)
+ : input_location);
+
+ pat->next = (struct pending_abstract_type *) *slot;
+ *slot = pat;
+
+ return 0;
+ }
+
+ if (!TYPE_SIZE (type))
+ /* TYPE is being defined, and during that time
+ CLASSTYPE_PURE_VIRTUALS holds the inline friends. */
+ return 0;
+
+ pure = CLASSTYPE_PURE_VIRTUALS (type);
+ if (!pure)
+ return 0;
+
+ if (!(complain & tf_error))
+ return 1;
+
+ if (decl)
+ {
+ if (VAR_P (decl))
+ error ("cannot declare variable %q+D to be of abstract "
+ "type %qT", decl, type);
+ else if (TREE_CODE (decl) == PARM_DECL)
+ {
+ if (DECL_NAME (decl))
+ error ("cannot declare parameter %q+D to be of abstract type %qT",
+ decl, type);
+ else
+ error ("cannot declare parameter to be of abstract type %qT",
+ type);
+ }
+ else if (TREE_CODE (decl) == FIELD_DECL)
+ error ("cannot declare field %q+D to be of abstract type %qT",
+ decl, type);
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
+ error ("invalid abstract return type for member function %q+#D", decl);
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ error ("invalid abstract return type for function %q+#D", decl);
+ else if (identifier_p (decl))
+ /* Here we do not have location information. */
+ error ("invalid abstract type %qT for %qE", type, decl);
+ else
+ error ("invalid abstract type for %q+D", decl);
+ }
+ else switch (use)
+ {
+ case ACU_ARRAY:
+ error ("creating array of %qT, which is an abstract class type", type);
+ break;
+ case ACU_CAST:
+ error ("invalid cast to abstract class type %qT", type);
+ break;
+ case ACU_NEW:
+ error ("invalid new-expression of abstract class type %qT", type);
+ break;
+ case ACU_RETURN:
+ error ("invalid abstract return type %qT", type);
+ break;
+ case ACU_PARM:
+ error ("invalid abstract parameter type %qT", type);
+ break;
+ case ACU_THROW:
+ error ("expression of abstract class type %qT cannot "
+ "be used in throw-expression", type);
+ break;
+ case ACU_CATCH:
+ error ("cannot declare catch parameter to be of abstract "
+ "class type %qT", type);
+ break;
+ default:
+ error ("cannot allocate an object of abstract type %qT", type);
+ }
+
+ /* Only go through this once. */
+ if (pure->length ())
+ {
+ unsigned ix;
+ tree fn;
+
+ inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
+ " because the following virtual functions are pure within %qT:",
+ type);
+
+ FOR_EACH_VEC_ELT (*pure, ix, fn)
+ if (! DECL_CLONED_FUNCTION_P (fn)
+ || DECL_COMPLETE_DESTRUCTOR_P (fn))
+ inform (input_location, "\t%+#D", fn);
+
+ /* Now truncate the vector. This leaves it non-null, so we know
+ there are pure virtuals, but empty so we don't list them out
+ again. */
+ pure->truncate (0);
+ }
+
+ return 1;
+}
+
+int
+abstract_virtuals_error_sfinae (tree decl, tree type, tsubst_flags_t complain)
+{
+ return abstract_virtuals_error_sfinae (decl, type, ACU_UNKNOWN, complain);
+}
+
+int
+abstract_virtuals_error_sfinae (abstract_class_use use, tree type,
+ tsubst_flags_t complain)
+{
+ return abstract_virtuals_error_sfinae (NULL_TREE, type, use, complain);
+}
+
+
+/* Wrapper for the above function in the common case of wanting errors. */
+
+int
+abstract_virtuals_error (tree decl, tree type)
+{
+ return abstract_virtuals_error_sfinae (decl, type, tf_warning_or_error);
+}
+
+int
+abstract_virtuals_error (abstract_class_use use, tree type)
+{
+ return abstract_virtuals_error_sfinae (use, type, tf_warning_or_error);
+}
+
+/* Print an error message for invalid use of an incomplete type.
+ VALUE is the expression that was used (or 0 if that isn't known)
+ and TYPE is the type that was invalid. DIAG_KIND indicates the
+ type of diagnostic (see diagnostic.def). */
+
+void
+cxx_incomplete_type_diagnostic (const_tree value, const_tree type,
+ diagnostic_t diag_kind)
+{
+ int decl = 0;
+
+ gcc_assert (diag_kind == DK_WARNING
+ || diag_kind == DK_PEDWARN
+ || diag_kind == DK_ERROR);
+
+ /* Avoid duplicate error message. */
+ if (TREE_CODE (type) == ERROR_MARK)
+ return;
+
+ if (value != 0 && (VAR_P (value)
+ || TREE_CODE (value) == PARM_DECL
+ || TREE_CODE (value) == FIELD_DECL))
+ {
+ emit_diagnostic (diag_kind, input_location, 0,
+ "%q+D has incomplete type", value);
+ decl = 1;
+ }
+ retry:
+ /* We must print an error message. Be clever about what it says. */
+
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ if (!decl)
+ emit_diagnostic (diag_kind, input_location, 0,
+ "invalid use of incomplete type %q#T", type);
+ if (!TYPE_TEMPLATE_INFO (type))
+ emit_diagnostic (diag_kind, input_location, 0,
+ "forward declaration of %q+#T", type);
+ else
+ emit_diagnostic (diag_kind, input_location, 0,
+ "declaration of %q+#T", type);
+ break;
+
+ case VOID_TYPE:
+ emit_diagnostic (diag_kind, input_location, 0,
+ "invalid use of %qT", type);
+ break;
+
+ case ARRAY_TYPE:
+ if (TYPE_DOMAIN (type))
+ {
+ type = TREE_TYPE (type);
+ goto retry;
+ }
+ emit_diagnostic (diag_kind, input_location, 0,
+ "invalid use of array with unspecified bounds");
+ break;
+
+ case OFFSET_TYPE:
+ bad_member:
+ {
+ tree member = TREE_OPERAND (value, 1);
+ if (is_overloaded_fn (member))
+ member = get_first_fn (member);
+ if (DECL_FUNCTION_MEMBER_P (member)
+ && ! flag_ms_extensions)
+ emit_diagnostic (diag_kind, input_location, 0,
+ "invalid use of member function "
+ "(did you forget the %<()%> ?)");
+ else
+ emit_diagnostic (diag_kind, input_location, 0,
+ "invalid use of member "
+ "(did you forget the %<&%> ?)");
+ }
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ if (is_auto (type))
+ emit_diagnostic (diag_kind, input_location, 0,
+ "invalid use of %<auto%>");
+ else
+ emit_diagnostic (diag_kind, input_location, 0,
+ "invalid use of template type parameter %qT", type);
+ break;
+
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ emit_diagnostic (diag_kind, input_location, 0,
+ "invalid use of template template parameter %qT",
+ TYPE_NAME (type));
+ break;
+
+ case TYPENAME_TYPE:
+ emit_diagnostic (diag_kind, input_location, 0,
+ "invalid use of dependent type %qT", type);
+ break;
+
+ case LANG_TYPE:
+ if (type == init_list_type_node)
+ {
+ emit_diagnostic (diag_kind, input_location, 0,
+ "invalid use of brace-enclosed initializer list");
+ break;
+ }
+ gcc_assert (type == unknown_type_node);
+ if (value && TREE_CODE (value) == COMPONENT_REF)
+ goto bad_member;
+ else if (value && TREE_CODE (value) == ADDR_EXPR)
+ emit_diagnostic (diag_kind, input_location, 0,
+ "address of overloaded function with no contextual "
+ "type information");
+ else if (value && TREE_CODE (value) == OVERLOAD)
+ emit_diagnostic (diag_kind, input_location, 0,
+ "overloaded function with no contextual type information");
+ else
+ emit_diagnostic (diag_kind, input_location, 0,
+ "insufficient contextual information to determine type");
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Backward-compatibility interface to incomplete_type_diagnostic;
+ required by ../tree.c. */
+#undef cxx_incomplete_type_error
+void
+cxx_incomplete_type_error (const_tree value, const_tree type)
+{
+ cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
+}
+
+
+/* The recursive part of split_nonconstant_init. DEST is an lvalue
+ expression to which INIT should be assigned. INIT is a CONSTRUCTOR.
+ Return true if the whole of the value was initialized by the
+ generated statements. */
+
+static bool
+split_nonconstant_init_1 (tree dest, tree init)
+{
+ unsigned HOST_WIDE_INT idx;
+ tree field_index, value;
+ tree type = TREE_TYPE (dest);
+ tree inner_type = NULL;
+ bool array_type_p = false;
+ bool complete_p = true;
+ HOST_WIDE_INT num_split_elts = 0;
+
+ switch (TREE_CODE (type))
+ {
+ case ARRAY_TYPE:
+ inner_type = TREE_TYPE (type);
+ array_type_p = true;
+ /* FALLTHRU */
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx,
+ field_index, value)
+ {
+ /* The current implementation of this algorithm assumes that
+ the field was set for all the elements. This is usually done
+ by process_init_constructor. */
+ gcc_assert (field_index);
+
+ if (!array_type_p)
+ inner_type = TREE_TYPE (field_index);
+
+ if (TREE_CODE (value) == CONSTRUCTOR)
+ {
+ tree sub;
+
+ if (array_type_p)
+ sub = build4 (ARRAY_REF, inner_type, dest, field_index,
+ NULL_TREE, NULL_TREE);
+ else
+ sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
+ NULL_TREE);
+
+ if (!split_nonconstant_init_1 (sub, value))
+ complete_p = false;
+ num_split_elts++;
+ }
+ else if (!initializer_constant_valid_p (value, inner_type))
+ {
+ tree code;
+ tree sub;
+
+ /* FIXME: Ordered removal is O(1) so the whole function is
+ worst-case quadratic. This could be fixed using an aside
+ bitmap to record which elements must be removed and remove
+ them all at the same time. Or by merging
+ split_non_constant_init into process_init_constructor_array,
+ that is separating constants from non-constants while building
+ the vector. */
+ CONSTRUCTOR_ELTS (init)->ordered_remove (idx);
+ --idx;
+
+ if (TREE_CODE (field_index) == RANGE_EXPR)
+ {
+ /* Use build_vec_init to initialize a range. */
+ tree low = TREE_OPERAND (field_index, 0);
+ tree hi = TREE_OPERAND (field_index, 1);
+ sub = build4 (ARRAY_REF, inner_type, dest, low,
+ NULL_TREE, NULL_TREE);
+ sub = cp_build_addr_expr (sub, tf_warning_or_error);
+ tree max = size_binop (MINUS_EXPR, hi, low);
+ code = build_vec_init (sub, max, value, false, 0,
+ tf_warning_or_error);
+ add_stmt (code);
+ if (tree_fits_shwi_p (max))
+ num_split_elts += tree_to_shwi (max);
+ }
+ else
+ {
+ if (array_type_p)
+ sub = build4 (ARRAY_REF, inner_type, dest, field_index,
+ NULL_TREE, NULL_TREE);
+ else
+ sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
+ NULL_TREE);
+
+ code = build2 (INIT_EXPR, inner_type, sub, value);
+ code = build_stmt (input_location, EXPR_STMT, code);
+ code = maybe_cleanup_point_expr_void (code);
+ add_stmt (code);
+ if (type_build_dtor_call (inner_type))
+ {
+ code = (build_special_member_call
+ (sub, complete_dtor_identifier, NULL, inner_type,
+ LOOKUP_NORMAL, tf_warning_or_error));
+ if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type))
+ finish_eh_cleanup (code);
+ }
+ }
+
+ num_split_elts++;
+ }
+ }
+ break;
+
+ case VECTOR_TYPE:
+ if (!initializer_constant_valid_p (init, type))
+ {
+ tree code;
+ tree cons = copy_node (init);
+ CONSTRUCTOR_ELTS (init) = NULL;
+ code = build2 (MODIFY_EXPR, type, dest, cons);
+ code = build_stmt (input_location, EXPR_STMT, code);
+ add_stmt (code);
+ num_split_elts += CONSTRUCTOR_NELTS (init);
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ /* The rest of the initializer is now a constant. */
+ TREE_CONSTANT (init) = 1;
+ return complete_p && complete_ctor_at_level_p (TREE_TYPE (init),
+ num_split_elts, inner_type);
+}
+
+/* A subroutine of store_init_value. Splits non-constant static
+ initializer INIT into a constant part and generates code to
+ perform the non-constant part of the initialization to DEST.
+ Returns the code for the runtime init. */
+
+static tree
+split_nonconstant_init (tree dest, tree init)
+{
+ tree code;
+
+ if (TREE_CODE (init) == CONSTRUCTOR)
+ {
+ code = push_stmt_list ();
+ if (split_nonconstant_init_1 (dest, init))
+ init = NULL_TREE;
+ code = pop_stmt_list (code);
+ DECL_INITIAL (dest) = init;
+ TREE_READONLY (dest) = 0;
+ }
+ else
+ code = build2 (INIT_EXPR, TREE_TYPE (dest), dest, init);
+
+ return code;
+}
+
+/* Perform appropriate conversions on the initial value of a variable,
+ store it in the declaration DECL,
+ and print any error messages that are appropriate.
+ If the init is invalid, store an ERROR_MARK.
+
+ C++: Note that INIT might be a TREE_LIST, which would mean that it is
+ a base class initializer for some aggregate type, hopefully compatible
+ with DECL. If INIT is a single element, and DECL is an aggregate
+ type, we silently convert INIT into a TREE_LIST, allowing a constructor
+ to be called.
+
+ If INIT is a TREE_LIST and there is no constructor, turn INIT
+ into a CONSTRUCTOR and use standard initialization techniques.
+ Perhaps a warning should be generated?
+
+ Returns code to be executed if initialization could not be performed
+ for static variable. In that case, caller must emit the code. */
+
+tree
+store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
+{
+ tree value, type;
+
+ /* If variable's type was invalidly declared, just ignore it. */
+
+ type = TREE_TYPE (decl);
+ if (TREE_CODE (type) == ERROR_MARK)
+ return NULL_TREE;
+
+ if (MAYBE_CLASS_TYPE_P (type))
+ {
+ if (TREE_CODE (init) == TREE_LIST)
+ {
+ error ("constructor syntax used, but no constructor declared "
+ "for type %qT", type);
+ init = build_constructor_from_list (init_list_type_node, nreverse (init));
+ }
+ }
+ else if (TREE_CODE (init) == TREE_LIST
+ && TREE_TYPE (init) != unknown_type_node)
+ {
+ gcc_assert (TREE_CODE (decl) != RESULT_DECL);
+
+ if (TREE_CODE (init) == TREE_LIST
+ && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+ {
+ error ("cannot initialize arrays using this syntax");
+ return NULL_TREE;
+ }
+ else
+ /* We get here with code like `int a (2);' */
+ init = build_x_compound_expr_from_list (init, ELK_INIT,
+ tf_warning_or_error);
+ }
+
+ /* End of special C++ code. */
+
+ if (flags & LOOKUP_ALREADY_DIGESTED)
+ value = init;
+ else
+ /* Digest the specified initializer into an expression. */
+ value = digest_init_flags (type, init, flags);
+
+ value = extend_ref_init_temps (decl, value, cleanups);
+
+ /* In C++0x constant expression is a semantic, not syntactic, property.
+ In C++98, make sure that what we thought was a constant expression at
+ template definition time is still constant and otherwise perform this
+ as optimization, e.g. to fold SIZEOF_EXPRs in the initializer. */
+ if (decl_maybe_constant_var_p (decl) || TREE_STATIC (decl))
+ {
+ bool const_init;
+ value = fold_non_dependent_expr (value);
+ if (DECL_DECLARED_CONSTEXPR_P (decl)
+ || DECL_IN_AGGR_P (decl))
+ {
+ /* Diagnose a non-constant initializer for constexpr. */
+ if (processing_template_decl
+ && !require_potential_constant_expression (value))
+ value = error_mark_node;
+ else
+ value = cxx_constant_value (value);
+ }
+ value = maybe_constant_init (value);
+ const_init = (reduced_constant_expression_p (value)
+ || error_operand_p (value));
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = const_init;
+ TREE_CONSTANT (decl) = const_init && decl_maybe_constant_var_p (decl);
+ }
+
+ /* If the initializer is not a constant, fill in DECL_INITIAL with
+ the bits that are constant, and then return an expression that
+ will perform the dynamic initialization. */
+ if (value != error_mark_node
+ && (TREE_SIDE_EFFECTS (value)
+ || array_of_runtime_bound_p (type)
+ || ! reduced_constant_expression_p (value)))
+ {
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (type))
+ || array_of_runtime_bound_p (type)))
+ /* For an array, we only need/want a single cleanup region rather
+ than one per element. */
+ return build_vec_init (decl, NULL_TREE, value, false, 1,
+ tf_warning_or_error);
+ else
+ return split_nonconstant_init (decl, value);
+ }
+ /* If the value is a constant, just put it in DECL_INITIAL. If DECL
+ is an automatic variable, the middle end will turn this into a
+ dynamic initialization later. */
+ DECL_INITIAL (decl) = value;
+ return NULL_TREE;
+}
+
+
+/* Give errors about narrowing conversions within { }. */
+
+void
+check_narrowing (tree type, tree init)
+{
+ tree ftype = unlowered_expr_type (init);
+ bool ok = true;
+ REAL_VALUE_TYPE d;
+
+ if (!warn_narrowing || !ARITHMETIC_TYPE_P (type))
+ return;
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (init)
+ && TREE_CODE (type) == COMPLEX_TYPE)
+ {
+ tree elttype = TREE_TYPE (type);
+ if (CONSTRUCTOR_NELTS (init) > 0)
+ check_narrowing (elttype, CONSTRUCTOR_ELT (init, 0)->value);
+ if (CONSTRUCTOR_NELTS (init) > 1)
+ check_narrowing (elttype, CONSTRUCTOR_ELT (init, 1)->value);
+ return;
+ }
+
+ init = maybe_constant_value (fold_non_dependent_expr_sfinae (init, tf_none));
+
+ if (TREE_CODE (type) == INTEGER_TYPE
+ && TREE_CODE (ftype) == REAL_TYPE)
+ ok = false;
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
+ && CP_INTEGRAL_TYPE_P (type))
+ {
+ if (TREE_CODE (ftype) == ENUMERAL_TYPE)
+ /* Check for narrowing based on the values of the enumeration. */
+ ftype = ENUM_UNDERLYING_TYPE (ftype);
+ if ((tree_int_cst_lt (TYPE_MAX_VALUE (type),
+ TYPE_MAX_VALUE (ftype))
+ || tree_int_cst_lt (TYPE_MIN_VALUE (ftype),
+ TYPE_MIN_VALUE (type)))
+ && (TREE_CODE (init) != INTEGER_CST
+ || !int_fits_type_p (init, type)))
+ ok = false;
+ }
+ else if (TREE_CODE (ftype) == REAL_TYPE
+ && TREE_CODE (type) == REAL_TYPE)
+ {
+ if (TYPE_PRECISION (type) < TYPE_PRECISION (ftype))
+ {
+ if (TREE_CODE (init) == REAL_CST)
+ {
+ /* Issue 703: Loss of precision is OK as long as the value is
+ within the representable range of the new type. */
+ REAL_VALUE_TYPE r;
+ d = TREE_REAL_CST (init);
+ real_convert (&r, TYPE_MODE (type), &d);
+ if (real_isinf (&r))
+ ok = false;
+ }
+ else
+ ok = false;
+ }
+ }
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
+ && TREE_CODE (type) == REAL_TYPE)
+ {
+ ok = false;
+ if (TREE_CODE (init) == INTEGER_CST)
+ {
+ d = real_value_from_int_cst (0, init);
+ if (exact_real_truncate (TYPE_MODE (type), &d))
+ ok = true;
+ }
+ }
+
+ if (!ok)
+ {
+ if (cxx_dialect >= cxx11)
+ pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
+ "narrowing conversion of %qE from %qT to %qT inside { }",
+ init, ftype, type);
+ else
+ warning_at (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
+ "narrowing conversion of %qE from %qT to %qT inside { } "
+ "is ill-formed in C++11", init, ftype, type);
+ }
+}
+
+/* Process the initializer INIT for a variable of type TYPE, emitting
+ diagnostics for invalid initializers and converting the initializer as
+ appropriate.
+
+ For aggregate types, it assumes that reshape_init has already run, thus the
+ initializer will have the right shape (brace elision has been undone).
+
+ NESTED is true iff we are being called for an element of a CONSTRUCTOR. */
+
+static tree
+digest_init_r (tree type, tree init, bool nested, int flags,
+ tsubst_flags_t complain)
+{
+ enum tree_code code = TREE_CODE (type);
+
+ if (error_operand_p (init))
+ return error_mark_node;
+
+ gcc_assert (init);
+
+ /* We must strip the outermost array type when completing the type,
+ because the its bounds might be incomplete at the moment. */
+ if (!complete_type_or_maybe_complain (TREE_CODE (type) == ARRAY_TYPE
+ ? TREE_TYPE (type) : type, NULL_TREE,
+ complain))
+ return error_mark_node;
+
+ /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue
+ (g++.old-deja/g++.law/casts2.C). */
+ if (TREE_CODE (init) == NON_LVALUE_EXPR)
+ init = TREE_OPERAND (init, 0);
+
+ /* Initialization of an array of chars from a string constant. The initializer
+ can be optionally enclosed in braces, but reshape_init has already removed
+ them if they were present. */
+ if (code == ARRAY_TYPE)
+ {
+ tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
+ if (char_type_p (typ1)
+ /*&& init */
+ && TREE_CODE (init) == STRING_CST)
+ {
+ tree char_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init)));
+
+ if (TYPE_PRECISION (typ1) == BITS_PER_UNIT)
+ {
+ if (char_type != char_type_node)
+ {
+ if (complain & tf_error)
+ error ("char-array initialized from wide string");
+ return error_mark_node;
+ }
+ }
+ else
+ {
+ if (char_type == char_type_node)
+ {
+ if (complain & tf_error)
+ error ("int-array initialized from non-wide string");
+ return error_mark_node;
+ }
+ else if (char_type != typ1)
+ {
+ if (complain & tf_error)
+ error ("int-array initialized from incompatible "
+ "wide string");
+ return error_mark_node;
+ }
+ }
+
+ if (type != TREE_TYPE (init))
+ {
+ init = copy_node (init);
+ TREE_TYPE (init) = type;
+ }
+ if (TYPE_DOMAIN (type) != 0 && TREE_CONSTANT (TYPE_SIZE (type)))
+ {
+ int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
+ size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
+ /* In C it is ok to subtract 1 from the length of the string
+ because it's ok to ignore the terminating null char that is
+ counted in the length of the constant, but in C++ this would
+ be invalid. */
+ if (size < TREE_STRING_LENGTH (init))
+ permerror (input_location, "initializer-string for array "
+ "of chars is too long");
+ }
+ return init;
+ }
+ }
+
+ /* Handle scalar types (including conversions) and references. */
+ if ((TREE_CODE (type) != COMPLEX_TYPE
+ || BRACE_ENCLOSED_INITIALIZER_P (init))
+ && (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE))
+ {
+ tree *exp;
+
+ if (nested)
+ check_narrowing (type, init);
+ init = convert_for_initialization (0, type, init, flags,
+ ICR_INIT, NULL_TREE, 0,
+ complain);
+ exp = &init;
+
+ /* Skip any conversions since we'll be outputting the underlying
+ constant. */
+ while (CONVERT_EXPR_P (*exp)
+ || TREE_CODE (*exp) == NON_LVALUE_EXPR)
+ exp = &TREE_OPERAND (*exp, 0);
+
+ *exp = cplus_expand_constant (*exp);
+
+ return init;
+ }
+
+ /* Come here only for aggregates: records, arrays, unions, complex numbers
+ and vectors. */
+ gcc_assert (TREE_CODE (type) == ARRAY_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE
+ || TREE_CODE (type) == RECORD_TYPE
+ || TREE_CODE (type) == UNION_TYPE
+ || TREE_CODE (type) == COMPLEX_TYPE);
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (init)
+ && !TYPE_NON_AGGREGATE_CLASS (type))
+ return process_init_constructor (type, init, complain);
+ else
+ {
+ if (COMPOUND_LITERAL_P (init) && TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (complain & tf_error)
+ error ("cannot initialize aggregate of type %qT with "
+ "a compound literal", type);
+
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && !BRACE_ENCLOSED_INITIALIZER_P (init))
+ {
+ /* Allow the result of build_array_copy and of
+ build_value_init_noctor. */
+ if ((TREE_CODE (init) == VEC_INIT_EXPR
+ || TREE_CODE (init) == CONSTRUCTOR)
+ && (same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (init))))
+ return init;
+
+ if (complain & tf_error)
+ error ("array must be initialized with a brace-enclosed"
+ " initializer");
+ return error_mark_node;
+ }
+
+ return convert_for_initialization (NULL_TREE, type, init,
+ flags,
+ ICR_INIT, NULL_TREE, 0,
+ complain);
+ }
+}
+
+tree
+digest_init (tree type, tree init, tsubst_flags_t complain)
+{
+ return digest_init_r (type, init, false, LOOKUP_IMPLICIT, complain);
+}
+
+tree
+digest_init_flags (tree type, tree init, int flags)
+{
+ return digest_init_r (type, init, false, flags, tf_warning_or_error);
+}
+
+/* Set of flags used within process_init_constructor to describe the
+ initializers. */
+#define PICFLAG_ERRONEOUS 1
+#define PICFLAG_NOT_ALL_CONSTANT 2
+#define PICFLAG_NOT_ALL_SIMPLE 4
+
+/* Given an initializer INIT, return the flag (PICFLAG_*) which better
+ describe it. */
+
+static int
+picflag_from_initializer (tree init)
+{
+ if (init == error_mark_node)
+ return PICFLAG_ERRONEOUS;
+ else if (!TREE_CONSTANT (init))
+ return PICFLAG_NOT_ALL_CONSTANT;
+ else if (!initializer_constant_valid_p (init, TREE_TYPE (init)))
+ return PICFLAG_NOT_ALL_SIMPLE;
+ return 0;
+}
+
+/* Adjust INIT for going into a CONSTRUCTOR. */
+
+static tree
+massage_init_elt (tree type, tree init, tsubst_flags_t complain)
+{
+ init = digest_init_r (type, init, true, LOOKUP_IMPLICIT, complain);
+ /* Strip a simple TARGET_EXPR when we know this is an initializer. */
+ if (TREE_CODE (init) == TARGET_EXPR
+ && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (init))))
+ init = TARGET_EXPR_INITIAL (init);
+ /* When we defer constant folding within a statement, we may want to
+ defer this folding as well. */
+ tree t = fold_non_dependent_expr_sfinae (init, complain);
+ t = maybe_constant_value (t);
+ if (TREE_CONSTANT (t))
+ init = t;
+ return init;
+}
+
+/* Subroutine of process_init_constructor, which will process an initializer
+ INIT for an array or vector of type TYPE. Returns the flags (PICFLAG_*)
+ which describe the initializers. */
+
+static int
+process_init_constructor_array (tree type, tree init,
+ tsubst_flags_t complain)
+{
+ unsigned HOST_WIDE_INT i, len = 0;
+ int flags = 0;
+ bool unbounded = false;
+ constructor_elt *ce;
+ vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (init);
+
+ gcc_assert (TREE_CODE (type) == ARRAY_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE);
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree domain = TYPE_DOMAIN (type);
+ if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain)))
+ len = (tree_to_double_int (TYPE_MAX_VALUE (domain))
+ - tree_to_double_int (TYPE_MIN_VALUE (domain))
+ + double_int_one)
+ .ext (TYPE_PRECISION (TREE_TYPE (domain)),
+ TYPE_UNSIGNED (TREE_TYPE (domain)))
+ .low;
+ else
+ unbounded = true; /* Take as many as there are. */
+ }
+ else
+ /* Vectors are like simple fixed-size arrays. */
+ len = TYPE_VECTOR_SUBPARTS (type);
+
+ /* There must not be more initializers than needed. */
+ if (!unbounded && vec_safe_length (v) > len)
+ {
+ if (complain & tf_error)
+ error ("too many initializers for %qT", type);
+ else
+ return PICFLAG_ERRONEOUS;
+ }
+
+ FOR_EACH_VEC_SAFE_ELT (v, i, ce)
+ {
+ if (ce->index)
+ {
+ gcc_assert (TREE_CODE (ce->index) == INTEGER_CST);
+ if (compare_tree_int (ce->index, i) != 0)
+ {
+ ce->value = error_mark_node;
+ sorry ("non-trivial designated initializers not supported");
+ }
+ }
+ else
+ ce->index = size_int (i);
+ gcc_assert (ce->value);
+ ce->value = massage_init_elt (TREE_TYPE (type), ce->value, complain);
+
+ if (ce->value != error_mark_node)
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (type), TREE_TYPE (ce->value)));
+
+ flags |= picflag_from_initializer (ce->value);
+ }
+
+ /* No more initializers. If the array is unbounded, we are done. Otherwise,
+ we must add initializers ourselves. */
+ if (!unbounded)
+ for (; i < len; ++i)
+ {
+ tree next;
+
+ if (type_build_ctor_call (TREE_TYPE (type)))
+ {
+ /* If this type needs constructors run for default-initialization,
+ we can't rely on the back end to do it for us, so make the
+ initialization explicit by list-initializing from {}. */
+ next = build_constructor (init_list_type_node, NULL);
+ next = massage_init_elt (TREE_TYPE (type), next, complain);
+ if (initializer_zerop (next))
+ /* The default zero-initialization is fine for us; don't
+ add anything to the CONSTRUCTOR. */
+ next = NULL_TREE;
+ }
+ else if (!zero_init_p (TREE_TYPE (type)))
+ next = build_zero_init (TREE_TYPE (type),
+ /*nelts=*/NULL_TREE,
+ /*static_storage_p=*/false);
+ else
+ /* The default zero-initialization is fine for us; don't
+ add anything to the CONSTRUCTOR. */
+ next = NULL_TREE;
+
+ if (next)
+ {
+ flags |= picflag_from_initializer (next);
+ CONSTRUCTOR_APPEND_ELT (v, size_int (i), next);
+ }
+ }
+
+ CONSTRUCTOR_ELTS (init) = v;
+ return flags;
+}
+
+/* Subroutine of process_init_constructor, which will process an initializer
+ INIT for a class of type TYPE. Returns the flags (PICFLAG_*) which describe
+ the initializers. */
+
+static int
+process_init_constructor_record (tree type, tree init,
+ tsubst_flags_t complain)
+{
+ vec<constructor_elt, va_gc> *v = NULL;
+ int flags = 0;
+ tree field;
+ unsigned HOST_WIDE_INT idx = 0;
+
+ gcc_assert (TREE_CODE (type) == RECORD_TYPE);
+ gcc_assert (!CLASSTYPE_VBASECLASSES (type));
+ gcc_assert (!TYPE_BINFO (type)
+ || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)));
+ gcc_assert (!TYPE_POLYMORPHIC_P (type));
+
+ /* Generally, we will always have an index for each initializer (which is
+ a FIELD_DECL, put by reshape_init), but compound literals don't go trough
+ reshape_init. So we need to handle both cases. */
+ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ {
+ tree next;
+ tree type;
+
+ if (!DECL_NAME (field) && DECL_C_BIT_FIELD (field))
+ continue;
+
+ if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
+ continue;
+
+ /* If this is a bitfield, first convert to the declared type. */
+ type = TREE_TYPE (field);
+ if (DECL_BIT_FIELD_TYPE (field))
+ type = DECL_BIT_FIELD_TYPE (field);
+ if (type == error_mark_node)
+ return PICFLAG_ERRONEOUS;
+
+ if (idx < vec_safe_length (CONSTRUCTOR_ELTS (init)))
+ {
+ constructor_elt *ce = &(*CONSTRUCTOR_ELTS (init))[idx];
+ if (ce->index)
+ {
+ /* We can have either a FIELD_DECL or an IDENTIFIER_NODE. The
+ latter case can happen in templates where lookup has to be
+ deferred. */
+ gcc_assert (TREE_CODE (ce->index) == FIELD_DECL
+ || identifier_p (ce->index));
+ if (ce->index != field
+ && ce->index != DECL_NAME (field))
+ {
+ ce->value = error_mark_node;
+ sorry ("non-trivial designated initializers not supported");
+ }
+ }
+
+ gcc_assert (ce->value);
+ next = massage_init_elt (type, ce->value, complain);
+ ++idx;
+ }
+ else if (type_build_ctor_call (TREE_TYPE (field)))
+ {
+ /* If this type needs constructors run for
+ default-initialization, we can't rely on the back end to do it
+ for us, so build up TARGET_EXPRs. If the type in question is
+ a class, just build one up; if it's an array, recurse. */
+ next = build_constructor (init_list_type_node, NULL);
+ /* Call this direct-initialization pending DR 1518 resolution so
+ that explicit default ctors don't break valid C++03 code. */
+ CONSTRUCTOR_IS_DIRECT_INIT (next) = true;
+ next = massage_init_elt (TREE_TYPE (field), next, complain);
+
+ /* Warn when some struct elements are implicitly initialized. */
+ warning (OPT_Wmissing_field_initializers,
+ "missing initializer for member %qD", field);
+ }
+ else
+ {
+ if (TREE_READONLY (field))
+ {
+ if (complain & tf_error)
+ error ("uninitialized const member %qD", field);
+ else
+ return PICFLAG_ERRONEOUS;
+ }
+ else if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))
+ {
+ if (complain & tf_error)
+ error ("member %qD with uninitialized const fields", field);
+ else
+ return PICFLAG_ERRONEOUS;
+ }
+ else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
+ {
+ if (complain & tf_error)
+ error ("member %qD is uninitialized reference", field);
+ else
+ return PICFLAG_ERRONEOUS;
+ }
+
+ /* Warn when some struct elements are implicitly initialized
+ to zero. */
+ warning (OPT_Wmissing_field_initializers,
+ "missing initializer for member %qD", field);
+
+ if (!zero_init_p (TREE_TYPE (field)))
+ next = build_zero_init (TREE_TYPE (field), /*nelts=*/NULL_TREE,
+ /*static_storage_p=*/false);
+ else
+ /* The default zero-initialization is fine for us; don't
+ add anything to the CONSTRUCTOR. */
+ continue;
+ }
+
+ /* If this is a bitfield, now convert to the lowered type. */
+ if (type != TREE_TYPE (field))
+ next = cp_convert_and_check (TREE_TYPE (field), next, complain);
+ flags |= picflag_from_initializer (next);
+ CONSTRUCTOR_APPEND_ELT (v, field, next);
+ }
+
+ if (idx < vec_safe_length (CONSTRUCTOR_ELTS (init)))
+ {
+ if (complain & tf_error)
+ error ("too many initializers for %qT", type);
+ else
+ return PICFLAG_ERRONEOUS;
+ }
+
+ CONSTRUCTOR_ELTS (init) = v;
+ return flags;
+}
+
+/* Subroutine of process_init_constructor, which will process a single
+ initializer INIT for a union of type TYPE. Returns the flags (PICFLAG_*)
+ which describe the initializer. */
+
+static int
+process_init_constructor_union (tree type, tree init,
+ tsubst_flags_t complain)
+{
+ constructor_elt *ce;
+ int len;
+
+ /* If the initializer was empty, use default zero initialization. */
+ if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
+ return 0;
+
+ len = CONSTRUCTOR_ELTS (init)->length ();
+ if (len > 1)
+ {
+ if (!(complain & tf_error))
+ return PICFLAG_ERRONEOUS;
+ error ("too many initializers for %qT", type);
+ CONSTRUCTOR_ELTS (init)->block_remove (1, len-1);
+ }
+
+ ce = &(*CONSTRUCTOR_ELTS (init))[0];
+
+ /* If this element specifies a field, initialize via that field. */
+ if (ce->index)
+ {
+ if (TREE_CODE (ce->index) == FIELD_DECL)
+ ;
+ else if (identifier_p (ce->index))
+ {
+ /* This can happen within a cast, see g++.dg/opt/cse2.C. */
+ tree name = ce->index;
+ tree field;
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ if (DECL_NAME (field) == name)
+ break;
+ if (!field)
+ {
+ if (complain & tf_error)
+ error ("no field %qD found in union being initialized",
+ field);
+ ce->value = error_mark_node;
+ }
+ ce->index = field;
+ }
+ else
+ {
+ gcc_assert (TREE_CODE (ce->index) == INTEGER_CST
+ || TREE_CODE (ce->index) == RANGE_EXPR);
+ if (complain & tf_error)
+ error ("index value instead of field name in union initializer");
+ ce->value = error_mark_node;
+ }
+ }
+ else
+ {
+ /* Find the first named field. ANSI decided in September 1990
+ that only named fields count here. */
+ tree field = TYPE_FIELDS (type);
+ while (field && (!DECL_NAME (field) || TREE_CODE (field) != FIELD_DECL))
+ field = TREE_CHAIN (field);
+ if (field == NULL_TREE)
+ {
+ if (complain & tf_error)
+ error ("too many initializers for %qT", type);
+ ce->value = error_mark_node;
+ }
+ ce->index = field;
+ }
+
+ if (ce->value && ce->value != error_mark_node)
+ ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, complain);
+
+ return picflag_from_initializer (ce->value);
+}
+
+/* Process INIT, a constructor for a variable of aggregate type TYPE. The
+ constructor is a brace-enclosed initializer, and will be modified in-place.
+
+ Each element is converted to the right type through digest_init, and
+ missing initializers are added following the language rules (zero-padding,
+ etc.).
+
+ After the execution, the initializer will have TREE_CONSTANT if all elts are
+ constant, and TREE_STATIC set if, in addition, all elts are simple enough
+ constants that the assembler and linker can compute them.
+
+ The function returns the initializer itself, or error_mark_node in case
+ of error. */
+
+static tree
+process_init_constructor (tree type, tree init, tsubst_flags_t complain)
+{
+ int flags;
+
+ gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
+
+ if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
+ flags = process_init_constructor_array (type, init, complain);
+ else if (TREE_CODE (type) == RECORD_TYPE)
+ flags = process_init_constructor_record (type, init, complain);
+ else if (TREE_CODE (type) == UNION_TYPE)
+ flags = process_init_constructor_union (type, init, complain);
+ else
+ gcc_unreachable ();
+
+ if (flags & PICFLAG_ERRONEOUS)
+ return error_mark_node;
+
+ TREE_TYPE (init) = type;
+ if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
+ cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0);
+ if (flags & PICFLAG_NOT_ALL_CONSTANT)
+ /* Make sure TREE_CONSTANT isn't set from build_constructor. */
+ TREE_CONSTANT (init) = false;
+ else
+ {
+ TREE_CONSTANT (init) = 1;
+ if (!(flags & PICFLAG_NOT_ALL_SIMPLE))
+ TREE_STATIC (init) = 1;
+ }
+ return init;
+}
+
+/* Given a structure or union value DATUM, construct and return
+ the structure or union component which results from narrowing
+ that value to the base specified in BASETYPE. For example, given the
+ hierarchy
+
+ class L { int ii; };
+ class A : L { ... };
+ class B : L { ... };
+ class C : A, B { ... };
+
+ and the declaration
+
+ C x;
+
+ then the expression
+
+ x.A::ii refers to the ii member of the L part of
+ the A part of the C object named by X. In this case,
+ DATUM would be x, and BASETYPE would be A.
+
+ I used to think that this was nonconformant, that the standard specified
+ that first we look up ii in A, then convert x to an L& and pull out the
+ ii part. But in fact, it does say that we convert x to an A&; A here
+ is known as the "naming class". (jason 2000-12-19)
+
+ BINFO_P points to a variable initialized either to NULL_TREE or to the
+ binfo for the specific base subobject we want to convert to. */
+
+tree
+build_scoped_ref (tree datum, tree basetype, tree* binfo_p)
+{
+ tree binfo;
+
+ if (datum == error_mark_node)
+ return error_mark_node;
+ if (*binfo_p)
+ binfo = *binfo_p;
+ else
+ binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check,
+ NULL, tf_warning_or_error);
+
+ if (!binfo || binfo == error_mark_node)
+ {
+ *binfo_p = NULL_TREE;
+ if (!binfo)
+ error_not_base_type (basetype, TREE_TYPE (datum));
+ return error_mark_node;
+ }
+
+ *binfo_p = binfo;
+ return build_base_path (PLUS_EXPR, datum, binfo, 1,
+ tf_warning_or_error);
+}
+
+/* Build a reference to an object specified by the C++ `->' operator.
+ Usually this just involves dereferencing the object, but if the
+ `->' operator is overloaded, then such overloads must be
+ performed until an object which does not have the `->' operator
+ overloaded is found. An error is reported when circular pointer
+ delegation is detected. */
+
+tree
+build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
+{
+ tree orig_expr = expr;
+ tree type = TREE_TYPE (expr);
+ tree last_rval = NULL_TREE;
+ vec<tree, va_gc> *types_memoized = NULL;
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (expr))
+ return build_min_nt_loc (loc, ARROW_EXPR, expr);
+ expr = build_non_dependent_expr (expr);
+ }
+
+ if (MAYBE_CLASS_TYPE_P (type))
+ {
+ struct tinst_level *actual_inst = current_instantiation ();
+ tree fn = NULL;
+
+ while ((expr = build_new_op (loc, COMPONENT_REF,
+ LOOKUP_NORMAL, expr, NULL_TREE, NULL_TREE,
+ &fn, complain)))
+ {
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ if (fn && DECL_USE_TEMPLATE (fn))
+ push_tinst_level (fn);
+ fn = NULL;
+
+ if (vec_member (TREE_TYPE (expr), types_memoized))
+ {
+ if (complain & tf_error)
+ error ("circular pointer delegation detected");
+ return error_mark_node;
+ }
+
+ vec_safe_push (types_memoized, TREE_TYPE (expr));
+ last_rval = expr;
+ }
+
+ while (current_instantiation () != actual_inst)
+ pop_tinst_level ();
+
+ if (last_rval == NULL_TREE)
+ {
+ if (complain & tf_error)
+ error ("base operand of %<->%> has non-pointer type %qT", type);
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (TREE_TYPE (last_rval)) == REFERENCE_TYPE)
+ last_rval = convert_from_reference (last_rval);
+ }
+ else
+ last_rval = decay_conversion (expr, complain);
+
+ if (TYPE_PTR_P (TREE_TYPE (last_rval)))
+ {
+ if (processing_template_decl)
+ {
+ expr = build_min (ARROW_EXPR, TREE_TYPE (TREE_TYPE (last_rval)),
+ orig_expr);
+ TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (last_rval);
+ return expr;
+ }
+
+ return cp_build_indirect_ref (last_rval, RO_NULL, complain);
+ }
+
+ if (complain & tf_error)
+ {
+ if (types_memoized)
+ error ("result of %<operator->()%> yields non-pointer result");
+ else
+ error ("base operand of %<->%> is not a pointer");
+ }
+ return error_mark_node;
+}
+
+/* Return an expression for "DATUM .* COMPONENT". DATUM has not
+ already been checked out to be of aggregate type. */
+
+tree
+build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
+{
+ tree ptrmem_type;
+ tree objtype;
+ tree type;
+ tree binfo;
+ tree ctype;
+
+ if (error_operand_p (datum) || error_operand_p (component))
+ return error_mark_node;
+
+ datum = mark_lvalue_use (datum);
+ component = mark_rvalue_use (component);
+
+ ptrmem_type = TREE_TYPE (component);
+ if (!TYPE_PTRMEM_P (ptrmem_type))
+ {
+ if (complain & tf_error)
+ error ("%qE cannot be used as a member pointer, since it is of "
+ "type %qT", component, ptrmem_type);
+ return error_mark_node;
+ }
+
+ objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
+ if (! MAYBE_CLASS_TYPE_P (objtype))
+ {
+ if (complain & tf_error)
+ error ("cannot apply member pointer %qE to %qE, which is of "
+ "non-class type %qT", component, datum, objtype);
+ return error_mark_node;
+ }
+
+ type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type);
+ ctype = complete_type (TYPE_PTRMEM_CLASS_TYPE (ptrmem_type));
+
+ if (!COMPLETE_TYPE_P (ctype))
+ {
+ if (!same_type_p (ctype, objtype))
+ goto mismatch;
+ binfo = NULL;
+ }
+ else
+ {
+ binfo = lookup_base (objtype, ctype, ba_check, NULL, complain);
+
+ if (!binfo)
+ {
+ mismatch:
+ if (complain & tf_error)
+ error ("pointer to member type %qT incompatible with object "
+ "type %qT", type, objtype);
+ return error_mark_node;
+ }
+ else if (binfo == error_mark_node)
+ return error_mark_node;
+ }
+
+ if (TYPE_PTRDATAMEM_P (ptrmem_type))
+ {
+ cp_lvalue_kind kind = lvalue_kind (datum);
+ tree ptype;
+
+ /* Compute the type of the field, as described in [expr.ref].
+ There's no such thing as a mutable pointer-to-member, so
+ things are not as complex as they are for references to
+ non-static data members. */
+ type = cp_build_qualified_type (type,
+ (cp_type_quals (type)
+ | cp_type_quals (TREE_TYPE (datum))));
+
+ datum = build_address (datum);
+
+ /* Convert object to the correct base. */
+ if (binfo)
+ {
+ datum = build_base_path (PLUS_EXPR, datum, binfo, 1, complain);
+ if (datum == error_mark_node)
+ return error_mark_node;
+ }
+
+ /* Build an expression for "object + offset" where offset is the
+ value stored in the pointer-to-data-member. */
+ ptype = build_pointer_type (type);
+ datum = fold_build_pointer_plus (fold_convert (ptype, datum), component);
+ datum = cp_build_indirect_ref (datum, RO_NULL, complain);
+ if (datum == error_mark_node)
+ return error_mark_node;
+
+ /* If the object expression was an rvalue, return an rvalue. */
+ if (kind & clk_class)
+ datum = rvalue (datum);
+ else if (kind & clk_rvalueref)
+ datum = move (datum);
+ return datum;
+ }
+ else
+ {
+ /* 5.5/6: In a .* expression whose object expression is an rvalue, the
+ program is ill-formed if the second operand is a pointer to member
+ function with ref-qualifier &. In a .* expression whose object
+ expression is an lvalue, the program is ill-formed if the second
+ operand is a pointer to member function with ref-qualifier &&. */
+ if (FUNCTION_REF_QUALIFIED (type))
+ {
+ bool lval = real_lvalue_p (datum);
+ if (lval && FUNCTION_RVALUE_QUALIFIED (type))
+ {
+ if (complain & tf_error)
+ error ("pointer-to-member-function type %qT requires an rvalue",
+ ptrmem_type);
+ return error_mark_node;
+ }
+ else if (!lval && !FUNCTION_RVALUE_QUALIFIED (type))
+ {
+ if (complain & tf_error)
+ error ("pointer-to-member-function type %qT requires an lvalue",
+ ptrmem_type);
+ return error_mark_node;
+ }
+ }
+ return build2 (OFFSET_REF, type, datum, component);
+ }
+}
+
+/* Return a tree node for the expression TYPENAME '(' PARMS ')'. */
+
+tree
+build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
+{
+ /* This is either a call to a constructor,
+ or a C cast in C++'s `functional' notation. */
+
+ /* The type to which we are casting. */
+ tree type;
+ vec<tree, va_gc> *parmvec;
+
+ if (error_operand_p (exp) || parms == error_mark_node)
+ return error_mark_node;
+
+ if (TREE_CODE (exp) == TYPE_DECL)
+ {
+ type = TREE_TYPE (exp);
+
+ if (complain & tf_warning
+ && TREE_DEPRECATED (type)
+ && DECL_ARTIFICIAL (exp))
+ warn_deprecated_use (type, NULL_TREE);
+ }
+ else
+ type = exp;
+
+ /* We need to check this explicitly, since value-initialization of
+ arrays is allowed in other situations. */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (complain & tf_error)
+ error ("functional cast to array type %qT", type);
+ return error_mark_node;
+ }
+
+ if (type_uses_auto (type))
+ {
+ if (complain & tf_error)
+ error ("invalid use of %<auto%>");
+ return error_mark_node;
+ }
+
+ if (processing_template_decl)
+ {
+ tree t;
+
+ /* Diagnose this even in a template. We could also try harder
+ to give all the usual errors when the type and args are
+ non-dependent... */
+ if (TREE_CODE (type) == REFERENCE_TYPE && !parms)
+ {
+ if (complain & tf_error)
+ error ("invalid value-initialization of reference type");
+ return error_mark_node;
+ }
+
+ t = build_min (CAST_EXPR, type, parms);
+ /* We don't know if it will or will not have side effects. */
+ TREE_SIDE_EFFECTS (t) = 1;
+ return t;
+ }
+
+ if (! MAYBE_CLASS_TYPE_P (type))
+ {
+ if (parms == NULL_TREE)
+ {
+ if (VOID_TYPE_P (type))
+ return void_zero_node;
+ return build_value_init (cv_unqualified (type), complain);
+ }
+
+ /* This must build a C cast. */
+ parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain);
+ return cp_build_c_cast (type, parms, complain);
+ }
+
+ /* Prepare to evaluate as a call to a constructor. If this expression
+ is actually used, for example,
+
+ return X (arg1, arg2, ...);
+
+ then the slot being initialized will be filled in. */
+
+ if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
+ return error_mark_node;
+ if (abstract_virtuals_error_sfinae (ACU_CAST, type, complain))
+ return error_mark_node;
+
+ /* [expr.type.conv]
+
+ If the expression list is a single-expression, the type
+ conversion is equivalent (in definedness, and if defined in
+ meaning) to the corresponding cast expression. */
+ if (parms && TREE_CHAIN (parms) == NULL_TREE)
+ return cp_build_c_cast (type, TREE_VALUE (parms), complain);
+
+ /* [expr.type.conv]
+
+ The expression T(), where T is a simple-type-specifier for a
+ non-array complete object type or the (possibly cv-qualified)
+ void type, creates an rvalue of the specified type, which is
+ value-initialized. */
+
+ if (parms == NULL_TREE)
+ {
+ exp = build_value_init (type, complain);
+ exp = get_target_expr_sfinae (exp, complain);
+ return exp;
+ }
+
+ /* Call the constructor. */
+ parmvec = make_tree_vector ();
+ for (; parms != NULL_TREE; parms = TREE_CHAIN (parms))
+ vec_safe_push (parmvec, TREE_VALUE (parms));
+ exp = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ &parmvec, type, LOOKUP_NORMAL, complain);
+ release_tree_vector (parmvec);
+
+ if (exp == error_mark_node)
+ return error_mark_node;
+
+ return build_cplus_new (type, exp, complain);
+}
+
+
+/* Add new exception specifier SPEC, to the LIST we currently have.
+ If it's already in LIST then do nothing.
+ Moan if it's bad and we're allowed to. COMPLAIN < 0 means we
+ know what we're doing. */
+
+tree
+add_exception_specifier (tree list, tree spec, int complain)
+{
+ bool ok;
+ tree core = spec;
+ bool is_ptr;
+ diagnostic_t diag_type = DK_UNSPECIFIED; /* none */
+
+ if (spec == error_mark_node)
+ return list;
+
+ gcc_assert (spec && (!list || TREE_VALUE (list)));
+
+ /* [except.spec] 1, type in an exception specifier shall not be
+ incomplete, or pointer or ref to incomplete other than pointer
+ to cv void. */
+ is_ptr = TYPE_PTR_P (core);
+ if (is_ptr || TREE_CODE (core) == REFERENCE_TYPE)
+ core = TREE_TYPE (core);
+ if (complain < 0)
+ ok = true;
+ else if (VOID_TYPE_P (core))
+ ok = is_ptr;
+ else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM)
+ ok = true;
+ else if (processing_template_decl)
+ ok = true;
+ else
+ {
+ ok = true;
+ /* 15.4/1 says that types in an exception specifier must be complete,
+ but it seems more reasonable to only require this on definitions
+ and calls. So just give a pedwarn at this point; we will give an
+ error later if we hit one of those two cases. */
+ if (!COMPLETE_TYPE_P (complete_type (core)))
+ diag_type = DK_PEDWARN; /* pedwarn */
+ }
+
+ if (ok)
+ {
+ tree probe;
+
+ for (probe = list; probe; probe = TREE_CHAIN (probe))
+ if (same_type_p (TREE_VALUE (probe), spec))
+ break;
+ if (!probe)
+ list = tree_cons (NULL_TREE, spec, list);
+ }
+ else
+ diag_type = DK_ERROR; /* error */
+
+ if (diag_type != DK_UNSPECIFIED
+ && (complain & tf_warning_or_error))
+ cxx_incomplete_type_diagnostic (NULL_TREE, core, diag_type);
+
+ return list;
+}
+
+/* Like nothrow_spec_p, but don't abort on deferred noexcept. */
+
+static bool
+nothrow_spec_p_uninst (const_tree spec)
+{
+ if (DEFERRED_NOEXCEPT_SPEC_P (spec))
+ return false;
+ return nothrow_spec_p (spec);
+}
+
+/* Combine the two exceptions specifier lists LIST and ADD, and return
+ their union. If FN is non-null, it's the source of ADD. */
+
+tree
+merge_exception_specifiers (tree list, tree add, tree fn)
+{
+ tree noex, orig_list;
+
+ /* No exception-specifier or noexcept(false) are less strict than
+ anything else. Prefer the newer variant (LIST). */
+ if (!list || list == noexcept_false_spec)
+ return list;
+ else if (!add || add == noexcept_false_spec)
+ return add;
+
+ /* noexcept(true) and throw() are stricter than anything else.
+ As above, prefer the more recent one (LIST). */
+ if (nothrow_spec_p_uninst (add))
+ return list;
+
+ noex = TREE_PURPOSE (list);
+ if (DEFERRED_NOEXCEPT_SPEC_P (add))
+ {
+ /* If ADD is a deferred noexcept, we must have been called from
+ process_subob_fn. For implicitly declared functions, we build up
+ a list of functions to consider at instantiation time. */
+ if (noex && operand_equal_p (noex, boolean_true_node, 0))
+ noex = NULL_TREE;
+ gcc_assert (fn && (!noex || is_overloaded_fn (noex)));
+ noex = build_overload (fn, noex);
+ }
+ else if (nothrow_spec_p_uninst (list))
+ return add;
+ else
+ gcc_checking_assert (!TREE_PURPOSE (add)
+ || cp_tree_equal (noex, TREE_PURPOSE (add)));
+
+ /* Combine the dynamic-exception-specifiers, if any. */
+ orig_list = list;
+ for (; add && TREE_VALUE (add); add = TREE_CHAIN (add))
+ {
+ tree spec = TREE_VALUE (add);
+ tree probe;
+
+ for (probe = orig_list; probe && TREE_VALUE (probe);
+ probe = TREE_CHAIN (probe))
+ if (same_type_p (TREE_VALUE (probe), spec))
+ break;
+ if (!probe)
+ {
+ spec = build_tree_list (NULL_TREE, spec);
+ TREE_CHAIN (spec) = list;
+ list = spec;
+ }
+ }
+
+ /* Keep the noexcept-specifier at the beginning of the list. */
+ if (noex != TREE_PURPOSE (list))
+ list = tree_cons (noex, TREE_VALUE (list), TREE_CHAIN (list));
+
+ return list;
+}
+
+/* Subroutine of build_call. Ensure that each of the types in the
+ exception specification is complete. Technically, 15.4/1 says that
+ they need to be complete when we see a declaration of the function,
+ but we should be able to get away with only requiring this when the
+ function is defined or called. See also add_exception_specifier. */
+
+void
+require_complete_eh_spec_types (tree fntype, tree decl)
+{
+ tree raises;
+ /* Don't complain about calls to op new. */
+ if (decl && DECL_ARTIFICIAL (decl))
+ return;
+ for (raises = TYPE_RAISES_EXCEPTIONS (fntype); raises;
+ raises = TREE_CHAIN (raises))
+ {
+ tree type = TREE_VALUE (raises);
+ if (type && !COMPLETE_TYPE_P (type))
+ {
+ if (decl)
+ error
+ ("call to function %qD which throws incomplete type %q#T",
+ decl, type);
+ else
+ error ("call to function which throws incomplete type %q#T",
+ decl);
+ }
+ }
+}
+
+
+#include "gt-cp-typeck2.h"
diff --git a/gcc-4.9/gcc/cp/vtable-class-hierarchy.c b/gcc-4.9/gcc/cp/vtable-class-hierarchy.c
new file mode 100644
index 000000000..6da17c731
--- /dev/null
+++ b/gcc-4.9/gcc/cp/vtable-class-hierarchy.c
@@ -0,0 +1,1346 @@
+/* Copyright (C) 2012-2014 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Virtual Table Pointer Security Pass - Detect corruption of vtable pointers
+ before using them for virtual method dispatches. */
+
+/* This file is part of the vtable security feature implementation.
+ The vtable security feature is designed to detect when a virtual
+ call is about to be made through an invalid vtable pointer
+ (possibly due to data corruption or malicious attacks). The
+ compiler finds every virtual call, and inserts a verification call
+ before the virtual call. The verification call takes the actual
+ vtable pointer value in the object through which the virtual call
+ is being made, and compares the vtable pointer against a set of all
+ valid vtable pointers that the object could contain (this set is
+ based on the declared type of the object). If the pointer is in
+ the valid set, execution is allowed to continue; otherwise the
+ program is halted.
+
+ There are several pieces needed in order to make this work: 1. For
+ every virtual class in the program (i.e. a class that contains
+ virtual methods), we need to build the set of all possible valid
+ vtables that an object of that class could point to. This includes
+ vtables for any class(es) that inherit from the class under
+ consideration. 2. For every such data set we build up, we need a
+ way to find and reference the data set. This is complicated by the
+ fact that the real vtable addresses are not known until runtime,
+ when the program is loaded into memory, but we need to reference the
+ sets at compile time when we are inserting verification calls into
+ the program. 3. We need to find every virtual call in the program,
+ and insert the verification call (with the appropriate arguments)
+ before the virtual call. 4. We need some runtime library pieces:
+ the code to build up the data sets at runtime; the code to actually
+ perform the verification using the data sets; and some code to set
+ protections on the data sets, so they themselves do not become
+ hacker targets.
+
+ To find and reference the set of valid vtable pointers for any given
+ virtual class, we create a special global varible for each virtual
+ class. We refer to this as the "vtable map variable" for that
+ class. The vtable map variable has the type "void *", and is
+ initialized by the compiler to NULL. At runtime when the set of
+ valid vtable pointers for a virtual class, e.g. class Foo, is built,
+ the vtable map variable for class Foo is made to point to the set.
+ During compile time, when the compiler is inserting verification
+ calls into the program, it passes the vtable map variable for the
+ appropriate class to the verification call, so that at runtime the
+ verification call can find the appropriate data set.
+
+ The actual set of valid vtable pointers for a virtual class,
+ e.g. class Foo, cannot be built until runtime, when the vtables get
+ loaded into memory and their addresses are known. But the knowledge
+ about which vtables belong in which class' hierarchy is only known
+ at compile time. Therefore at compile time we collect class
+ hierarchy and vtable information about every virtual class, and we
+ generate calls to build up the data sets at runtime. To build the
+ data sets, we call one of the functions we add to the runtime
+ library, __VLTRegisterPair. __VLTRegisterPair takes two arguments,
+ a vtable map variable and the address of a vtable. If the vtable
+ map variable is currently NULL, it creates a new data set (hash
+ table), makes the vtable map variable point to the new data set, and
+ inserts the vtable address into the data set. If the vtable map
+ variable is not NULL, it just inserts the vtable address into the
+ data set. In order to make sure that our data sets are built before
+ any verification calls happen, we create a special constructor
+ initialization function for each compilation unit, give it a very
+ high initialization priority, and insert all of our calls to
+ __VLTRegisterPair into our special constructor initialization
+ function.
+
+ The vtable verification feature is controlled by the flag
+ '-fvtable-verify='. There are three flavors of this:
+ '-fvtable-verify=std', '-fvtable-verify=preinit', and
+ '-fvtable-verify=none'. If the option '-fvtable-verfy=preinit' is
+ used, then our constructor initialization function gets put into the
+ preinit array. This is necessary if there are data sets that need
+ to be built very early in execution. If the constructor
+ initialization function gets put into the preinit array, the we also
+ add calls to __VLTChangePermission at the beginning and end of the
+ function. The call at the beginning sets the permissions on the
+ data sets and vtable map variables to read/write, and the one at the
+ end makes them read-only. If the '-fvtable-verify=std' option is
+ used, the constructor initialization functions are executed at their
+ normal time, and the __VLTChangePermission calls are handled
+ differently (see the comments in libstdc++-v3/libsupc++/vtv_rts.cc).
+ The option '-fvtable-verify=none' turns off vtable verification.
+
+ This file contains code to find and record the class hierarchies for
+ the virtual classes in a program, and all the vtables associated
+ with each such class; to generate the vtable map variables; and to
+ generate the constructor initialization function (with the calls to
+ __VLTRegisterPair, and __VLTChangePermission). The main data
+ structures used for collecting the class hierarchy data and
+ building/maintaining the vtable map variable data are defined in
+ gcc/vtable-verify.h, because they are used both here and in
+ gcc/vtable-verify.c. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "cp-tree.h"
+#include "output.h"
+#include "cgraph.h"
+#include "tree-iterator.h"
+#include "vtable-verify.h"
+#include "gimplify.h"
+#include "stringpool.h"
+#include "stor-layout.h"
+
+static int num_calls_to_regset = 0;
+static int num_calls_to_regpair = 0;
+static int current_set_size;
+
+/* Mark these specially since they need to be stored in precompiled
+ header IR. */
+static GTY (()) vec<tree, va_gc> *vlt_saved_class_info;
+static GTY (()) tree vlt_register_pairs_fndecl = NULL_TREE;
+static GTY (()) tree vlt_register_set_fndecl = NULL_TREE;
+
+struct work_node {
+ struct vtv_graph_node *node;
+ struct work_node *next;
+};
+
+struct vtbl_map_node *vtable_find_or_create_map_decl (tree);
+
+/* As part of vtable verification the compiler generates and inserts
+ calls to __VLTVerifyVtablePointer, which is in libstdc++. This
+ function builds and initializes the function decl that is used
+ in generating those function calls.
+
+ In addition to __VLTVerifyVtablePointer there is also
+ __VLTVerifyVtablePointerDebug which can be used in place of
+ __VLTVerifyVtablePointer, and which takes extra parameters and
+ outputs extra information, to help debug problems. The debug
+ version of this function is generated and used if flag_vtv_debug is
+ true.
+
+ The signatures for these functions are:
+
+ void * __VLTVerifyVtablePointer (void **, void*);
+ void * __VLTVerifyVtablePointerDebug (void**, void *, char *, char *);
+*/
+
+void
+vtv_build_vtable_verify_fndecl (void)
+{
+ tree func_type = NULL_TREE;
+
+ if (verify_vtbl_ptr_fndecl != NULL_TREE
+ && TREE_CODE (verify_vtbl_ptr_fndecl) != ERROR_MARK)
+ return;
+
+ if (flag_vtv_debug)
+ {
+ func_type = build_function_type_list (const_ptr_type_node,
+ build_pointer_type (ptr_type_node),
+ const_ptr_type_node,
+ const_string_type_node,
+ const_string_type_node,
+ NULL_TREE);
+ verify_vtbl_ptr_fndecl =
+ build_lang_decl (FUNCTION_DECL,
+ get_identifier ("__VLTVerifyVtablePointerDebug"),
+ func_type);
+ }
+ else
+ {
+ func_type = build_function_type_list (const_ptr_type_node,
+ build_pointer_type (ptr_type_node),
+ const_ptr_type_node,
+ NULL_TREE);
+ verify_vtbl_ptr_fndecl =
+ build_lang_decl (FUNCTION_DECL,
+ get_identifier ("__VLTVerifyVtablePointer"),
+ func_type);
+ }
+
+ TREE_NOTHROW (verify_vtbl_ptr_fndecl) = 1;
+ DECL_ATTRIBUTES (verify_vtbl_ptr_fndecl)
+ = tree_cons (get_identifier ("leaf"), NULL,
+ DECL_ATTRIBUTES (verify_vtbl_ptr_fndecl));
+ DECL_PURE_P (verify_vtbl_ptr_fndecl) = 1;
+ TREE_PUBLIC (verify_vtbl_ptr_fndecl) = 1;
+ DECL_PRESERVE_P (verify_vtbl_ptr_fndecl) = 1;
+}
+
+/* As part of vtable verification the compiler generates and inserts
+ calls to __VLTRegisterSet and __VLTRegisterPair, which are in
+ libsupc++. This function builds and initializes the function decls
+ that are used in generating those function calls.
+
+ The signatures for these functions are:
+
+ void __VLTRegisterSetDebug (void **, const void *, std::size_t,
+ size_t, void **);
+
+ void __VLTRegisterSet (void **, const void *, std::size_t,
+ size_t, void **);
+
+ void __VLTRegisterPairDebug (void **, const void *, size_t,
+ const void *, const char *, const char *);
+
+ void __VLTRegisterPair (void **, const void *, size_t, const void *);
+*/
+
+static void
+init_functions (void)
+{
+ tree register_set_type;
+ tree register_pairs_type;
+
+ if (vlt_register_set_fndecl != NULL_TREE)
+ return;
+
+ gcc_assert (vlt_register_pairs_fndecl == NULL_TREE);
+ gcc_assert (vlt_register_set_fndecl == NULL_TREE);
+
+ /* Build function decl for __VLTRegisterSet*. */
+
+ register_set_type = build_function_type_list
+ (void_type_node,
+ build_pointer_type (ptr_type_node),
+ const_ptr_type_node,
+ size_type_node,
+ size_type_node,
+ build_pointer_type (ptr_type_node),
+ NULL_TREE);
+
+ if (flag_vtv_debug)
+ vlt_register_set_fndecl = build_lang_decl
+ (FUNCTION_DECL,
+ get_identifier ("__VLTRegisterSetDebug"),
+ register_set_type);
+ else
+ vlt_register_set_fndecl = build_lang_decl
+ (FUNCTION_DECL,
+ get_identifier ("__VLTRegisterSet"),
+ register_set_type);
+
+
+ TREE_NOTHROW (vlt_register_set_fndecl) = 1;
+ DECL_ATTRIBUTES (vlt_register_set_fndecl) =
+ tree_cons (get_identifier ("leaf"), NULL,
+ DECL_ATTRIBUTES (vlt_register_set_fndecl));
+ DECL_EXTERNAL(vlt_register_set_fndecl) = 1;
+ TREE_PUBLIC (vlt_register_set_fndecl) = 1;
+ DECL_PRESERVE_P (vlt_register_set_fndecl) = 1;
+ SET_DECL_LANGUAGE (vlt_register_set_fndecl, lang_cplusplus);
+
+ /* Build function decl for __VLTRegisterPair*. */
+
+ if (flag_vtv_debug)
+ {
+ register_pairs_type = build_function_type_list (void_type_node,
+ build_pointer_type
+ (ptr_type_node),
+ const_ptr_type_node,
+ size_type_node,
+ const_ptr_type_node,
+ const_string_type_node,
+ const_string_type_node,
+ NULL_TREE);
+
+ vlt_register_pairs_fndecl = build_lang_decl
+ (FUNCTION_DECL,
+ get_identifier ("__VLTRegisterPairDebug"),
+ register_pairs_type);
+ }
+ else
+ {
+ register_pairs_type = build_function_type_list (void_type_node,
+ build_pointer_type
+ (ptr_type_node),
+ const_ptr_type_node,
+ size_type_node,
+ const_ptr_type_node,
+ NULL_TREE);
+
+ vlt_register_pairs_fndecl = build_lang_decl
+ (FUNCTION_DECL,
+ get_identifier ("__VLTRegisterPair"),
+ register_pairs_type);
+ }
+
+ TREE_NOTHROW (vlt_register_pairs_fndecl) = 1;
+ DECL_ATTRIBUTES (vlt_register_pairs_fndecl) =
+ tree_cons (get_identifier ("leaf"), NULL,
+ DECL_ATTRIBUTES (vlt_register_pairs_fndecl));
+ DECL_EXTERNAL(vlt_register_pairs_fndecl) = 1;
+ TREE_PUBLIC (vlt_register_pairs_fndecl) = 1;
+ DECL_PRESERVE_P (vlt_register_pairs_fndecl) = 1;
+ SET_DECL_LANGUAGE (vlt_register_pairs_fndecl, lang_cplusplus);
+
+}
+
+/* This is a helper function for
+ vtv_compute_class_hierarchy_transitive_closure. It adds a
+ vtv_graph_node to the WORKLIST, which is a linked list of
+ seen-but-not-yet-processed nodes. INSERTED is a bitmap, one bit
+ per node, to help make sure that we don't insert a node into the
+ worklist more than once. Each node represents a class somewhere in
+ our class hierarchy information. Every node in the graph gets added
+ to the worklist exactly once and removed from the worklist exactly
+ once (when all of its children have been processed). */
+
+static void
+add_to_worklist (struct work_node **worklist, struct vtv_graph_node *node,
+ sbitmap inserted)
+{
+ struct work_node *new_work_node;
+
+ if (bitmap_bit_p (inserted, node->class_uid))
+ return;
+
+ new_work_node = XNEW (struct work_node);
+ new_work_node->next = *worklist;
+ new_work_node->node = node;
+ *worklist = new_work_node;
+
+ bitmap_set_bit (inserted, node->class_uid);
+}
+
+/* This is a helper function for
+ vtv_compute_class_hierarchy_transitive_closure. It goes through
+ the WORKLIST of class hierarchy nodes looking for a "leaf" node,
+ i.e. a node whose children in the hierarchy have all been
+ processed. When it finds the next leaf node, it removes it from
+ the linked list (WORKLIST) and returns the node. */
+
+static struct vtv_graph_node *
+find_and_remove_next_leaf_node (struct work_node **worklist)
+{
+ struct work_node *prev, *cur;
+ struct vtv_graph_node *ret_val = NULL;
+
+ for (prev = NULL, cur = *worklist; cur; prev = cur, cur = cur->next)
+ {
+ if ((cur->node->children).length() == cur->node->num_processed_children)
+ {
+ if (prev == NULL)
+ (*worklist) = cur->next;
+ else
+ prev->next = cur->next;
+
+ cur->next = NULL;
+ ret_val = cur->node;
+ free (cur);
+ return ret_val;
+ }
+ }
+
+ return NULL;
+}
+
+/* In our class hierarchy graph, each class node contains a bitmap,
+ with one bit for each class in the hierarchy. The bits are set for
+ classes that are descendants in the graph of the current node.
+ Initially the descendants bitmap is only set for immediate
+ descendants. This function traverses the class hierarchy graph,
+ bottom up, filling in the transitive closures for the descendants
+ as we rise up the graph. */
+
+void
+vtv_compute_class_hierarchy_transitive_closure (void)
+{
+ struct work_node *worklist = NULL;
+ sbitmap inserted = sbitmap_alloc (num_vtable_map_nodes);
+ unsigned i;
+ unsigned j;
+
+ /* Note: Every node in the graph gets added to the worklist exactly
+ once and removed from the worklist exactly once (when all of its
+ children have been processed). Each node's children edges are
+ followed exactly once, and each node's parent edges are followed
+ exactly once. So this algorithm is roughly O(V + 2E), i.e.
+ O(E + V). */
+
+ /* Set-up: */
+ /* Find all the "leaf" nodes in the graph, and add them to the worklist. */
+ bitmap_clear (inserted);
+ for (j = 0; j < num_vtable_map_nodes; ++j)
+ {
+ struct vtbl_map_node *cur = vtbl_map_nodes_vec[j];
+ if (cur->class_info
+ && ((cur->class_info->children).length() == 0)
+ && ! (bitmap_bit_p (inserted, cur->class_info->class_uid)))
+ add_to_worklist (&worklist, cur->class_info, inserted);
+ }
+
+ /* Main work: pull next leaf node off work list, process it, add its
+ parents to the worklist, where a 'leaf' node is one that has no
+ children, or all of its children have been processed. */
+ while (worklist)
+ {
+ struct vtv_graph_node *temp_node =
+ find_and_remove_next_leaf_node (&worklist);
+
+ gcc_assert (temp_node != NULL);
+ temp_node->descendants = sbitmap_alloc (num_vtable_map_nodes);
+ bitmap_clear (temp_node->descendants);
+ bitmap_set_bit (temp_node->descendants, temp_node->class_uid);
+ for (i = 0; i < (temp_node->children).length(); ++i)
+ bitmap_ior (temp_node->descendants, temp_node->descendants,
+ temp_node->children[i]->descendants);
+ for (i = 0; i < (temp_node->parents).length(); ++i)
+ {
+ temp_node->parents[i]->num_processed_children =
+ temp_node->parents[i]->num_processed_children + 1;
+ if (!bitmap_bit_p (inserted, temp_node->parents[i]->class_uid))
+ add_to_worklist (&worklist, temp_node->parents[i], inserted);
+ }
+ }
+}
+
+/* Keep track of which pairs we have already created __VLTRegisterPair
+ calls for, to prevent creating duplicate calls within the same
+ compilation unit. VTABLE_DECL is the var decl for the vtable of
+ the (descendant) class that we are adding to our class hierarchy
+ data. VPTR_ADDRESS is an expression for calculating the correct
+ offset into the vtable (VTABLE_DECL). It is the actual vtable
+ pointer address that will be stored in our list of valid vtable
+ pointers for BASE_CLASS. BASE_CLASS is the record_type node for
+ the base class to whose hiearchy we want to add
+ VPTR_ADDRESS. (VTABLE_DECL should be the vtable for BASE_CLASS or
+ one of BASE_CLASS' descendents. */
+
+static bool
+check_and_record_registered_pairs (tree vtable_decl, tree vptr_address,
+ tree base_class)
+{
+ unsigned offset;
+ struct vtbl_map_node *base_vtable_map_node;
+ bool inserted_something = false;
+
+
+ if (TREE_CODE (vptr_address) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (vptr_address, 0)) == MEM_REF)
+ vptr_address = TREE_OPERAND (vptr_address, 0);
+
+ if (TREE_OPERAND_LENGTH (vptr_address) > 1)
+ offset = TREE_INT_CST_LOW (TREE_OPERAND (vptr_address, 1));
+ else
+ offset = 0;
+
+ base_vtable_map_node = vtbl_map_get_node (TYPE_MAIN_VARIANT (base_class));
+
+ inserted_something = vtbl_map_node_registration_insert
+ (base_vtable_map_node,
+ vtable_decl,
+ offset);
+ return !inserted_something;
+}
+
+/* Given an IDENTIFIER_NODE, build and return a string literal based on it. */
+
+static tree
+build_string_from_id (tree identifier)
+{
+ int len;
+
+ gcc_assert (TREE_CODE (identifier) == IDENTIFIER_NODE);
+
+ len = IDENTIFIER_LENGTH (identifier);
+ return build_string_literal (len + 1, IDENTIFIER_POINTER (identifier));
+}
+
+/* A class may contain secondary vtables in it, for various reasons.
+ This function goes through the decl chain of a class record looking
+ for any fields that point to secondary vtables, and adding calls to
+ __VLTRegisterPair for the secondary vtable pointers.
+
+ BASE_CLASS_DECL_ARG is an expression for the address of the vtable
+ map variable for the BASE_CLASS (whose hierarchy we are currently
+ updating). BASE_CLASS is the record_type node for the base class.
+ RECORD_TYPE is the record_type node for the descendant class that
+ we are possibly adding to BASE_CLASS's hierarchy. BODY is the
+ function body for the constructor init function to which we are
+ adding our calls to __VLTRegisterPair. */
+
+static void
+register_construction_vtables (tree base_class, tree record_type,
+ vec<tree> *vtable_ptr_array)
+{
+ tree vtbl_var_decl;
+
+ if (TREE_CODE (record_type) != RECORD_TYPE)
+ return;
+
+ vtbl_var_decl = CLASSTYPE_VTABLES (record_type);
+
+ if (CLASSTYPE_VBASECLASSES (record_type))
+ {
+ tree vtt_decl;
+ bool already_registered = false;
+ tree val_vtbl_decl = NULL_TREE;
+
+ vtt_decl = DECL_CHAIN (vtbl_var_decl);
+
+ /* Check to see if we have found a VTT. Add its data if appropriate. */
+ if (vtt_decl)
+ {
+ tree values = DECL_INITIAL (vtt_decl);
+ if (TREE_ASM_WRITTEN (vtt_decl)
+ && values != NULL_TREE
+ && TREE_CODE (values) == CONSTRUCTOR
+ && TREE_CODE (TREE_TYPE (values)) == ARRAY_TYPE)
+ {
+ unsigned HOST_WIDE_INT cnt;
+ constructor_elt *ce;
+
+ /* Loop through the initialization values for this
+ vtable to get all the correct vtable pointer
+ addresses that we need to add to our set of valid
+ vtable pointers for the current base class. This may
+ result in adding more than just the element assigned
+ to the primary vptr of the class, so we may end up
+ with more vtable pointers than are strictly
+ necessary. */
+
+ for (cnt = 0;
+ vec_safe_iterate (CONSTRUCTOR_ELTS (values),
+ cnt, &ce);
+ cnt++)
+ {
+ tree value = ce->value;
+
+ /* Search for the ADDR_EXPR operand within the value. */
+
+ while (value
+ && TREE_OPERAND (value, 0)
+ && TREE_CODE (TREE_OPERAND (value, 0)) == ADDR_EXPR)
+ value = TREE_OPERAND (value, 0);
+
+ /* The VAR_DECL for the vtable should be the first
+ argument of the ADDR_EXPR, which is the first
+ argument of value.*/
+
+ if (TREE_OPERAND (value, 0))
+ val_vtbl_decl = TREE_OPERAND (value, 0);
+
+ while (TREE_CODE (val_vtbl_decl) != VAR_DECL
+ && TREE_OPERAND (val_vtbl_decl, 0))
+ val_vtbl_decl = TREE_OPERAND (val_vtbl_decl, 0);
+
+ gcc_assert (TREE_CODE (val_vtbl_decl) == VAR_DECL);
+
+ /* Check to see if we already have this vtable pointer in
+ our valid set for this base class. */
+
+ already_registered = check_and_record_registered_pairs
+ (val_vtbl_decl,
+ value,
+ base_class);
+
+ if (already_registered)
+ continue;
+
+ /* Add this vtable pointer to our set of valid
+ pointers for the base class. */
+
+ vtable_ptr_array->safe_push (value);
+ current_set_size++;
+ }
+ }
+ }
+ }
+}
+
+/* This function iterates through all the vtables it can find from the
+ BINFO of a class, to make sure we have found ALL of the vtables
+ that an object of that class could point to. Generate calls to
+ __VLTRegisterPair for those vtable pointers that we find.
+
+ BINFO is the tree_binfo node for the BASE_CLASS. BODY is the
+ function body for the constructor init function to which we are
+ adding calls to __VLTRegisterPair. ARG1 is an expression for the
+ address of the vtable map variable (for the BASE_CLASS), that will
+ point to the updated data set. BASE_CLASS is the record_type node
+ for the base class whose set of valid vtable pointers we are
+ updating. STR1 and STR2 are all debugging information, to be passed
+ as parameters to __VLTRegisterPairDebug. STR1 represents the name
+ of the vtable map variable to be updated by the call. Similarly,
+ STR2 represents the name of the class whose vtable pointer is being
+ added to the hierarchy. */
+
+static void
+register_other_binfo_vtables (tree binfo, tree base_class,
+ vec<tree> *vtable_ptr_array)
+{
+ unsigned ix;
+ tree base_binfo;
+ tree vtable_decl;
+ bool already_registered;
+
+ if (binfo == NULL_TREE)
+ return;
+
+ for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
+ {
+ if ((!BINFO_PRIMARY_P (base_binfo)
+ || BINFO_VIRTUAL_P (base_binfo))
+ && (vtable_decl = get_vtbl_decl_for_binfo (base_binfo)))
+ {
+ tree vtable_address = build_vtbl_address (base_binfo);
+
+ already_registered = check_and_record_registered_pairs
+ (vtable_decl,
+ vtable_address,
+ base_class);
+ if (!already_registered)
+ {
+ vtable_ptr_array->safe_push (vtable_address);
+ current_set_size++;
+ }
+ }
+
+ register_other_binfo_vtables (base_binfo, base_class, vtable_ptr_array);
+ }
+}
+
+/* The set of valid vtable pointers for any given class are stored in
+ a hash table. For reasons of efficiency, that hash table size is
+ always a power of two. In order to try to prevent re-sizing the
+ hash tables very often, we pass __VLTRegisterPair an initial guess
+ as to the number of entries the hashtable will eventually need
+ (rounded up to the nearest power of two). This function takes the
+ class information we have collected for a particular class,
+ CLASS_NODE, and calculates the hash table size guess. */
+
+static int
+guess_num_vtable_pointers (struct vtv_graph_node *class_node)
+{
+ tree vtbl;
+ int total_num_vtbls = 0;
+ int num_vtbls_power_of_two = 1;
+ unsigned i;
+
+ for (i = 0; i < num_vtable_map_nodes; ++i)
+ if (bitmap_bit_p (class_node->descendants, i))
+ {
+ tree class_type = vtbl_map_nodes_vec[i]->class_info->class_type;
+ for (vtbl = CLASSTYPE_VTABLES (class_type); vtbl;
+ vtbl = DECL_CHAIN (vtbl))
+ {
+ total_num_vtbls++;
+ if (total_num_vtbls > num_vtbls_power_of_two)
+ num_vtbls_power_of_two <<= 1;
+ }
+ }
+ return num_vtbls_power_of_two;
+}
+
+/* A simple hash function on strings */
+/* Be careful about changing this routine. The values generated will
+ be stored in the calls to InitSet. So, changing this routine may
+ cause a binary incompatibility. */
+
+static uint32_t
+vtv_string_hash (const char *in)
+{
+ const char *s = in;
+ uint32_t h = 0;
+
+ gcc_assert (in != NULL);
+ for ( ; *s; ++s)
+ h = 5 * h + *s;
+ return h;
+}
+
+static char *
+get_log_file_name (const char *fname)
+{
+ const char *tmp_dir = concat (dump_dir_name, NULL);
+ char *full_name;
+ int dir_len;
+ int fname_len;
+
+ dir_len = strlen (tmp_dir);
+ fname_len = strlen (fname);
+
+ full_name = XNEWVEC (char, dir_len + fname_len + 1);
+ strcpy (full_name, tmp_dir);
+ strcpy (full_name + dir_len, fname);
+
+ return full_name;
+}
+
+static void
+write_out_current_set_data (tree base_class, int set_size)
+{
+ static int class_data_log_fd = -1;
+ char buffer[1024];
+ int bytes_written __attribute__ ((unused));
+ char *file_name = get_log_file_name ("vtv_class_set_sizes.log");
+
+ if (class_data_log_fd == -1)
+ class_data_log_fd = open (file_name,
+ O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
+
+ if (class_data_log_fd == -1)
+ {
+ warning_at (UNKNOWN_LOCATION, 0,
+ "unable to open log file %<vtv_class_set_sizes.log%>: %m");
+ return;
+ }
+
+ snprintf (buffer, sizeof (buffer), "%s %d\n",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (base_class))),
+ set_size);
+ bytes_written = write (class_data_log_fd, buffer, strlen (buffer));
+}
+
+static tree
+build_key_buffer_arg (tree base_ptr_var_decl)
+{
+ const int key_type_fixed_size = 8;
+ uint32_t len1 = IDENTIFIER_LENGTH (DECL_NAME (base_ptr_var_decl));
+ uint32_t hash_value = vtv_string_hash (IDENTIFIER_POINTER
+ (DECL_NAME (base_ptr_var_decl)));
+ void *key_buffer = xmalloc (len1 + key_type_fixed_size);
+ uint32_t *value_ptr = (uint32_t *) key_buffer;
+ tree ret_value;
+
+ /* Set the len and hash for the string. */
+ *value_ptr = len1;
+ value_ptr++;
+ *value_ptr = hash_value;
+
+ /* Now copy the string representation of the vtbl map name... */
+ memcpy ((char *) key_buffer + key_type_fixed_size,
+ IDENTIFIER_POINTER (DECL_NAME (base_ptr_var_decl)),
+ len1);
+
+ /* ... and build a string literal from it. This will make a copy
+ so the key_bufffer is not needed anymore after this. */
+ ret_value = build_string_literal (len1 + key_type_fixed_size,
+ (char *) key_buffer);
+ free (key_buffer);
+ return ret_value;
+}
+
+static void
+insert_call_to_register_set (tree class_name,
+ vec<tree> *vtbl_ptr_array, tree body, tree arg1,
+ tree arg2, tree size_hint_arg)
+{
+ tree call_expr;
+ int num_args = vtbl_ptr_array->length();
+ char *array_arg_name = ACONCAT (("__vptr_array_",
+ IDENTIFIER_POINTER (class_name), NULL));
+ tree array_arg_type = build_array_type_nelts (build_pointer_type
+ (build_pointer_type
+ (void_type_node)),
+ num_args);
+ tree array_arg = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+ get_identifier (array_arg_name),
+ array_arg_type);
+ int k;
+
+ vec<constructor_elt, va_gc> *array_elements;
+ vec_alloc (array_elements, num_args);
+
+ tree initial = NULL_TREE;
+ tree arg3 = NULL_TREE;
+
+ TREE_PUBLIC (array_arg) = 0;
+ DECL_EXTERNAL (array_arg) = 0;
+ TREE_STATIC (array_arg) = 1;
+ DECL_ARTIFICIAL (array_arg) = 0;
+ TREE_READONLY (array_arg) = 1;
+ DECL_IGNORED_P (array_arg) = 0;
+ DECL_PRESERVE_P (array_arg) = 0;
+ DECL_VISIBILITY (array_arg) = VISIBILITY_HIDDEN;
+
+ for (k = 0; k < num_args; ++k)
+ {
+ CONSTRUCTOR_APPEND_ELT (array_elements, NULL_TREE, (*vtbl_ptr_array)[k]);
+ }
+
+ initial = build_constructor (TREE_TYPE (array_arg), array_elements);
+
+ TREE_CONSTANT (initial) = 1;
+ TREE_STATIC (initial) = 1;
+ DECL_INITIAL (array_arg) = initial;
+ relayout_decl (array_arg);
+ varpool_finalize_decl (array_arg);
+
+ arg3 = build1 (ADDR_EXPR, TYPE_POINTER_TO (TREE_TYPE (array_arg)), array_arg);
+
+ TREE_TYPE (arg3) = build_pointer_type (TREE_TYPE (array_arg));
+
+ call_expr = build_call_expr (vlt_register_set_fndecl, 5, arg1,
+ arg2, /* set_symbol_key */
+ size_hint_arg, build_int_cst (size_type_node,
+ num_args),
+ arg3);
+ append_to_statement_list (call_expr, &body);
+ num_calls_to_regset++;
+}
+
+static void
+insert_call_to_register_pair (vec<tree> *vtbl_ptr_array, tree arg1,
+ tree arg2, tree size_hint_arg, tree str1,
+ tree str2, tree body)
+{
+ tree call_expr;
+ int num_args = vtbl_ptr_array->length();
+ tree vtable_address = NULL_TREE;
+
+ if (num_args == 0)
+ vtable_address = build_int_cst (build_pointer_type (void_type_node), 0);
+ else
+ vtable_address = (*vtbl_ptr_array)[0];
+
+ if (flag_vtv_debug)
+ call_expr = build_call_expr (vlt_register_pairs_fndecl, 6, arg1, arg2,
+ size_hint_arg, vtable_address, str1, str2);
+ else
+ call_expr = build_call_expr (vlt_register_pairs_fndecl, 4, arg1, arg2,
+ size_hint_arg, vtable_address);
+
+ append_to_statement_list (call_expr, &body);
+ num_calls_to_regpair++;
+}
+
+static void
+output_set_info (tree record_type, vec<tree> vtbl_ptr_array)
+{
+ static int vtv_debug_log_fd = -1;
+ char buffer[1024];
+ int bytes_written __attribute__ ((unused));
+ int array_len = vtbl_ptr_array.length();
+ const char *class_name =
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (record_type)));
+ char *file_name = get_log_file_name ("vtv_set_ptr_data.log");
+
+ if (vtv_debug_log_fd == -1)
+ vtv_debug_log_fd = open (file_name,
+ O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
+ if (vtv_debug_log_fd == -1)
+ {
+ warning_at (UNKNOWN_LOCATION, 0,
+ "unable to open log file %<vtv_set_ptr_data.log%>: %m");
+ return;
+ }
+
+ for (int i = 0; i < array_len; ++i)
+ {
+ const char *vptr_name = "unknown";
+ int vptr_offset = 0;
+
+ if (TREE_CODE (vtbl_ptr_array[i]) == POINTER_PLUS_EXPR)
+ {
+ tree arg0 = TREE_OPERAND (vtbl_ptr_array[i], 0);
+ tree arg1 = TREE_OPERAND (vtbl_ptr_array[i], 1);
+
+ if (TREE_CODE (arg0) == ADDR_EXPR)
+ arg0 = TREE_OPERAND (arg0, 0);
+
+ if (TREE_CODE (arg0) == VAR_DECL)
+ vptr_name = IDENTIFIER_POINTER (DECL_NAME (arg0));
+
+ if (TREE_CODE (arg1) == INTEGER_CST)
+ vptr_offset = TREE_INT_CST_LOW (arg1);
+ }
+
+ snprintf (buffer, sizeof (buffer), "%s %s %s + %d\n",
+ main_input_filename, class_name, vptr_name, vptr_offset);
+ bytes_written = write (vtv_debug_log_fd, buffer, strlen(buffer));
+ }
+
+}
+
+/* This function goes through our internal class hierarchy & vtable
+ pointer data structure and outputs calls to __VLTRegisterPair for
+ every class-vptr pair (for those classes whose vtable would be
+ output in the current compilation unit). These calls get put into
+ our constructor initialization function. BODY is the function
+ body, so far, of our constructor initialization function, to which we
+ add the calls. */
+
+static bool
+register_all_pairs (tree body)
+{
+ bool registered_at_least_one = false;
+ vec<tree> *vtbl_ptr_array = NULL;
+ unsigned j;
+
+ for (j = 0; j < num_vtable_map_nodes; ++j)
+ {
+ struct vtbl_map_node *current = vtbl_map_nodes_vec[j];
+ unsigned i = 0;
+ tree base_class = current->class_info->class_type;
+ tree base_ptr_var_decl = current->vtbl_map_decl;
+ tree arg1;
+ tree arg2;
+ tree new_type;
+ tree str1 = NULL_TREE;
+ tree str2 = NULL_TREE;
+ size_t size_hint;
+ tree size_hint_arg;
+
+ gcc_assert (current->class_info != NULL);
+
+
+ if (flag_vtv_debug)
+ str1 = build_string_from_id (DECL_NAME (base_ptr_var_decl));
+
+ new_type = build_pointer_type (TREE_TYPE (base_ptr_var_decl));
+ arg1 = build1 (ADDR_EXPR, new_type, base_ptr_var_decl);
+
+ /* We need a fresh vector for each iteration. */
+ if (vtbl_ptr_array)
+ vec_free (vtbl_ptr_array);
+
+ vec_alloc (vtbl_ptr_array, 10);
+
+ for (i = 0; i < num_vtable_map_nodes; ++i)
+ if (bitmap_bit_p (current->class_info->descendants, i))
+ {
+ struct vtbl_map_node *vtbl_class_node = vtbl_map_nodes_vec[i];
+ tree class_type = vtbl_class_node->class_info->class_type;
+
+ if (class_type
+ && (TREE_CODE (class_type) == RECORD_TYPE))
+ {
+ bool already_registered;
+
+ tree binfo = TYPE_BINFO (class_type);
+ tree vtable_decl;
+ bool vtable_should_be_output = false;
+
+ vtable_decl = CLASSTYPE_VTABLES (class_type);
+
+ /* Handle main vtable for this class. */
+
+ if (vtable_decl)
+ {
+ vtable_should_be_output = TREE_ASM_WRITTEN (vtable_decl);
+ str2 = build_string_from_id (DECL_NAME (vtable_decl));
+ }
+
+ if (vtable_decl && vtable_should_be_output)
+ {
+ tree vtable_address = build_vtbl_address (binfo);
+
+ already_registered = check_and_record_registered_pairs
+ (vtable_decl,
+ vtable_address,
+ base_class);
+
+
+ if (!already_registered)
+ {
+ vtbl_ptr_array->safe_push (vtable_address);
+
+ /* Find and handle any 'extra' vtables associated
+ with this class, via virtual inheritance. */
+ register_construction_vtables (base_class, class_type,
+ vtbl_ptr_array);
+
+ /* Find and handle any 'extra' vtables associated
+ with this class, via multiple inheritance. */
+ register_other_binfo_vtables (binfo, base_class,
+ vtbl_ptr_array);
+ }
+ }
+ }
+ }
+ current_set_size = vtbl_ptr_array->length();
+
+ /* Sometimes we need to initialize the set symbol even if we are
+ not adding any vtable pointers to the set in the current
+ compilation unit. In that case, we need to initialize the
+ set to our best guess as to what the eventual size of the set
+ hash table will be (to prevent having to re-size the hash
+ table later). */
+
+ size_hint = guess_num_vtable_pointers (current->class_info);
+
+ /* If we have added vtable pointers to the set in this
+ compilation unit, adjust the size hint for the set's hash
+ table appropriately. */
+ if (vtbl_ptr_array->length() > 0)
+ {
+ unsigned len = vtbl_ptr_array->length();
+ while ((size_t) len > size_hint)
+ size_hint <<= 1;
+ }
+ size_hint_arg = build_int_cst (size_type_node, size_hint);
+
+ /* Get the key-buffer argument. */
+ arg2 = build_key_buffer_arg (base_ptr_var_decl);
+
+ if (str2 == NULL_TREE)
+ str2 = build_string_literal (strlen ("unknown") + 1,
+ "unknown");
+
+ if (flag_vtv_debug)
+ output_set_info (current->class_info->class_type,
+ *vtbl_ptr_array);
+
+ if (vtbl_ptr_array->length() > 1)
+ {
+ insert_call_to_register_set (current->class_name,
+ vtbl_ptr_array, body, arg1, arg2,
+ size_hint_arg);
+ registered_at_least_one = true;
+ }
+ else
+ {
+
+ if (vtbl_ptr_array->length() > 0
+ || (current->is_used
+ || (current->registered.size() > 0)))
+ {
+ insert_call_to_register_pair (vtbl_ptr_array,
+ arg1, arg2, size_hint_arg, str1,
+ str2, body);
+ registered_at_least_one = true;
+ }
+ }
+
+ if (flag_vtv_counts && current_set_size > 0)
+ write_out_current_set_data (base_class, current_set_size);
+
+ }
+
+ return registered_at_least_one;
+}
+
+/* Given a tree containing a class type (CLASS_TYPE), this function
+ finds and returns the class hierarchy node for that class in our
+ data structure. */
+
+static struct vtv_graph_node *
+find_graph_node (tree class_type)
+{
+ struct vtbl_map_node *vtbl_node;
+
+ vtbl_node = vtbl_map_get_node (TYPE_MAIN_VARIANT (class_type));
+ if (vtbl_node)
+ return vtbl_node->class_info;
+
+ return NULL;
+}
+
+/* Add base class/derived class pair to our internal class hierarchy
+ data structure. BASE_NODE is our vtv_graph_node that corresponds
+ to a base class. DERIVED_NODE is our vtv_graph_node that
+ corresponds to a class that is a descendant of the base class
+ (possibly the base class itself). */
+
+static void
+add_hierarchy_pair (struct vtv_graph_node *base_node,
+ struct vtv_graph_node *derived_node)
+{
+ (base_node->children).safe_push (derived_node);
+ (derived_node->parents).safe_push (base_node);
+}
+
+/* This functions adds a new base class/derived class relationship to
+ our class hierarchy data structure. Both parameters are trees
+ representing the class types, i.e. RECORD_TYPE trees.
+ DERIVED_CLASS can be the same as BASE_CLASS. */
+
+static void
+update_class_hierarchy_information (tree base_class,
+ tree derived_class)
+{
+ struct vtv_graph_node *base_node = find_graph_node (base_class);
+ struct vtv_graph_node *derived_node = find_graph_node (derived_class);
+
+ add_hierarchy_pair (base_node, derived_node);
+}
+
+
+static void
+write_out_vtv_count_data (void)
+{
+ static int vtv_count_log_fd = -1;
+ char buffer[1024];
+ int unused_vtbl_map_vars = 0;
+ int bytes_written __attribute__ ((unused));
+ char *file_name = get_log_file_name ("vtv_count_data.log");
+
+ if (vtv_count_log_fd == -1)
+ vtv_count_log_fd = open (file_name,
+ O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
+ if (vtv_count_log_fd == -1)
+ {
+ warning_at (UNKNOWN_LOCATION, 0,
+ "unable to open log file %<vtv_count_data.log%>: %m");
+ return;
+ }
+
+ for (unsigned i = 0; i < num_vtable_map_nodes; ++i)
+ {
+ struct vtbl_map_node *current = vtbl_map_nodes_vec[i];
+ if (!current->is_used
+ && current->registered.size() == 0)
+ unused_vtbl_map_vars++;
+ }
+
+ snprintf (buffer, sizeof (buffer), "%s %d %d %d %d %d\n",
+ main_input_filename, total_num_virtual_calls,
+ total_num_verified_vcalls, num_calls_to_regset,
+ num_calls_to_regpair, unused_vtbl_map_vars);
+
+ bytes_written = write (vtv_count_log_fd, buffer, strlen (buffer));
+}
+
+/* This function calls register_all_pairs, which actually generates
+ all the calls to __VLTRegisterPair (in the verification constructor
+ init function). It also generates the calls to
+ __VLTChangePermission, if the verification constructor init
+ function is going into the preinit array. INIT_ROUTINE_BODY is
+ the body of our constructior initialization function, to which we
+ add our function calls.*/
+
+bool
+vtv_register_class_hierarchy_information (tree init_routine_body)
+{
+ bool registered_something = false;
+
+ init_functions ();
+
+ if (num_vtable_map_nodes == 0)
+ return false;
+
+ /* Add class hierarchy pairs to the vtable map data structure. */
+ registered_something = register_all_pairs (init_routine_body);
+
+ if (flag_vtv_counts)
+ write_out_vtv_count_data ();
+
+ return registered_something;
+}
+
+
+/* Generate the special constructor function that calls
+ __VLTChangePermission and __VLTRegisterPairs, and give it a very
+ high initialization priority. */
+
+void
+vtv_generate_init_routine (void)
+{
+ tree init_routine_body;
+ bool vtable_classes_found = false;
+
+ push_lang_context (lang_name_c);
+
+ /* The priority for this init function (constructor) is carefully
+ chosen so that it will happen after the calls to unprotect the
+ memory used for vtable verification and before the memory is
+ protected again. */
+ init_routine_body = vtv_start_verification_constructor_init_function ();
+
+ vtable_classes_found =
+ vtv_register_class_hierarchy_information (init_routine_body);
+
+ if (vtable_classes_found)
+ {
+ tree vtv_fndecl =
+ vtv_finish_verification_constructor_init_function (init_routine_body);
+ TREE_STATIC (vtv_fndecl) = 1;
+ TREE_USED (vtv_fndecl) = 1;
+ DECL_PRESERVE_P (vtv_fndecl) = 1;
+ if (flag_vtable_verify == VTV_PREINIT_PRIORITY)
+ DECL_STATIC_CONSTRUCTOR (vtv_fndecl) = 0;
+
+ gimplify_function_tree (vtv_fndecl);
+ cgraph_add_new_function (vtv_fndecl, false);
+
+ cgraph_process_new_functions ();
+
+ if (flag_vtable_verify == VTV_PREINIT_PRIORITY)
+ assemble_vtv_preinit_initializer (vtv_fndecl);
+
+ }
+ pop_lang_context ();
+}
+
+/* This funtion takes a tree containing a class type (BASE_TYPE), and
+ it either finds the existing vtbl_map_node for that class in our
+ data structure, or it creates a new node and adds it to the data
+ structure if there is not one for the class already. As part of
+ this process it also creates the global vtable map variable for the
+ class. */
+
+struct vtbl_map_node *
+vtable_find_or_create_map_decl (tree base_type)
+{
+ char *var_name = NULL;
+ struct vtbl_map_node *vtable_map_node = NULL;
+
+ /* Verify the type has an associated vtable. */
+ if (!TYPE_BINFO (base_type) || !BINFO_VTABLE (TYPE_BINFO (base_type)))
+ return NULL;
+
+ /* Create map lookup symbol for base class */
+ var_name = get_mangled_vtable_map_var_name (base_type);
+
+ /* We've already created the variable; just look it. */
+ vtable_map_node = vtbl_map_get_node (TYPE_MAIN_VARIANT (base_type));
+
+ if (!vtable_map_node || (vtable_map_node->vtbl_map_decl == NULL_TREE))
+ {
+ /* If we haven't already created the *__vtable_map global
+ variable for this class, do so now, and add it to the
+ varpool, to make sure it gets saved and written out. */
+
+ tree var_decl = NULL;
+ tree var_type = build_pointer_type (void_type_node);
+ tree initial_value = integer_zero_node;
+
+ var_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+ get_identifier (var_name), var_type);
+
+ DECL_EXTERNAL (var_decl) = 0;
+ TREE_STATIC (var_decl) = 1;
+ DECL_VISIBILITY (var_decl) = VISIBILITY_HIDDEN;
+ SET_DECL_ASSEMBLER_NAME (var_decl, get_identifier (var_name));
+ DECL_ARTIFICIAL (var_decl) = 1;
+ /* We cannot mark this variable as read-only because we want to be
+ able to write to it at runtime. */
+ TREE_READONLY (var_decl) = 0;
+ DECL_IGNORED_P (var_decl) = 1;
+ DECL_PRESERVE_P (var_decl) = 1;
+
+ /* Put these mmap variables in thr .vtable_map_vars section, so
+ we can find and protect them. */
+
+ DECL_SECTION_NAME (var_decl) = build_string (strlen (".vtable_map_vars"),
+ ".vtable_map_vars");
+ DECL_HAS_IMPLICIT_SECTION_NAME_P (var_decl) = true;
+ DECL_INITIAL (var_decl) = initial_value;
+
+ comdat_linkage (var_decl);
+
+ varpool_finalize_decl (var_decl);
+ if (!vtable_map_node)
+ vtable_map_node =
+ find_or_create_vtbl_map_node (TYPE_MAIN_VARIANT (base_type));
+ if (vtable_map_node->vtbl_map_decl == NULL_TREE)
+ vtable_map_node->vtbl_map_decl = var_decl;
+ }
+
+ gcc_assert (vtable_map_node);
+ return vtable_map_node;
+}
+
+/* This function is used to build up our class hierarchy data for a
+ particular class. TYPE is the record_type tree node for the
+ class. */
+
+static void
+vtv_insert_single_class_info (tree type)
+{
+ if (flag_vtable_verify)
+ {
+ tree binfo = TYPE_BINFO (type);
+ tree base_binfo;
+ struct vtbl_map_node *own_map;
+ int i;
+
+ /* First make sure to create the map for this record type. */
+ own_map = vtable_find_or_create_map_decl (type);
+ if (own_map == NULL)
+ return;
+
+ /* Go through the list of all base classes for the current
+ (derived) type, make sure the *__vtable_map global variable
+ for the base class exists, and add the base class/derived
+ class pair to the class hierarchy information we are
+ accumulating (for vtable pointer verification). */
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ {
+ tree tree_val = BINFO_TYPE (base_binfo);
+ struct vtbl_map_node *vtable_map_node = NULL;
+
+ vtable_map_node = vtable_find_or_create_map_decl (tree_val);
+
+ if (vtable_map_node != NULL)
+ update_class_hierarchy_information (tree_val, type);
+ }
+ }
+}
+
+/* This function adds classes we are interested in to a list of
+ classes. RECORD is the record_type node for the class we are
+ adding to the list. */
+
+void
+vtv_save_class_info (tree record)
+{
+ if (!flag_vtable_verify || TREE_CODE (record) == UNION_TYPE)
+ return;
+
+ if (!vlt_saved_class_info)
+ vec_alloc (vlt_saved_class_info, 10);
+
+ gcc_assert (TREE_CODE (record) == RECORD_TYPE);
+
+ vec_safe_push (vlt_saved_class_info, record);
+}
+
+
+/* This function goes through the list of classes we saved and calls
+ vtv_insert_single_class_info on each one, to build up our class
+ hierarchy data structure. */
+
+void
+vtv_recover_class_info (void)
+{
+ tree current_class;
+ unsigned i;
+
+ if (vlt_saved_class_info)
+ {
+ for (i = 0; i < vlt_saved_class_info->length(); ++i)
+ {
+ current_class = (*vlt_saved_class_info)[i];
+ gcc_assert (TREE_CODE (current_class) == RECORD_TYPE);
+ vtv_insert_single_class_info (current_class);
+ }
+ }
+}
+
+#include "gt-cp-vtable-class-hierarchy.h"