summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog480
-rw-r--r--gcc/cp/call.c152
-rw-r--r--gcc/cp/class.c478
-rw-r--r--gcc/cp/config-lang.in2
-rw-r--r--gcc/cp/constexpr.c3
-rw-r--r--gcc/cp/constraint.cc2
-rw-r--r--gcc/cp/cp-array-notation.c4
-rw-r--r--gcc/cp/cp-gimplify.c3
-rw-r--r--gcc/cp/cp-lang.c24
-rw-r--r--gcc/cp/cp-objcp-common.c7
-rw-r--r--gcc/cp/cp-tree.h137
-rw-r--r--gcc/cp/cp-ubsan.c3
-rw-r--r--gcc/cp/cxx-pretty-print.c19
-rw-r--r--gcc/cp/decl.c223
-rw-r--r--gcc/cp/decl2.c220
-rw-r--r--gcc/cp/error.c5
-rw-r--r--gcc/cp/except.c2
-rw-r--r--gcc/cp/friend.c2
-rw-r--r--gcc/cp/init.c16
-rw-r--r--gcc/cp/lambda.c7
-rw-r--r--gcc/cp/lex.c100
-rw-r--r--gcc/cp/mangle.c74
-rw-r--r--gcc/cp/method.c70
-rw-r--r--gcc/cp/name-lookup.c165
-rw-r--r--gcc/cp/optimize.c6
-rw-r--r--gcc/cp/parser.c249
-rw-r--r--gcc/cp/pt.c444
-rw-r--r--gcc/cp/ptree.c1
-rw-r--r--gcc/cp/rtti.c10
-rw-r--r--gcc/cp/search.c233
-rw-r--r--gcc/cp/semantics.c60
-rw-r--r--gcc/cp/tree.c31
-rw-r--r--gcc/cp/typeck.c3
33 files changed, 1843 insertions, 1392 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a06de8ba8c7..76d1de09c4d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,483 @@
+2017-07-31 Jan Hubicka <hubicka@ucw.cz>
+ Martin Liska <mliska@suse.cz>
+
+ * pt.c (tsubst_copy): Copy PREDICT_EXPR.
+ * semantics.c (finish_goto_stmt): Build gimple predict
+ stament.
+ * constexpr.c (potential_constant_expression_1): Handle
+ PREDICT_EXPR.
+
+2017-07-31 Martin Liska <mliska@suse.cz>
+
+ PR sanitize/81530
+ * cp-gimplify.c (cp_genericize): Guard condition with flag_sanitize_p
+ also with current_function_decl non-null equality.
+ * cp-ubsan.c (cp_ubsan_instrument_vptr_p): Likewise.
+ * decl.c (compute_array_index_type): Likewise.
+ * init.c (finish_length_check): Likewise.
+ * typeck.c (cp_build_binary_op): Likewise.
+
+2017-07-29 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-objcp-common.c (cp_decl_dwarf_attribute): Handle
+ DW_AT_export_symbols.
+ * name-lookup.c (emit_debug_info_using_namespace): Add IMPLICIT
+ argument, pass it through to the debug hook.
+ (finish_namespace_using_directive): Adjust
+ emit_debug_info_using_namespace caller.
+ (push_namespace): Likewise. Call it after setting
+ DECL_NAMESPACE_INLINE_P.
+ (cp_emit_debug_info_for_using): Pass false as new argument to
+ the imported_module_or_decl debug hook.
+
+2017-07-28 Trevor Saunders <tbsaunde+gcc@tbsaunde.org>
+
+ * lex.c (copy_decl): Adjust.
+ (copy_type): Likewise.
+
+2017-07-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/71570
+ * lambda.c (add_capture): Early return if we cannot capture by
+ reference.
+
+2017-07-26 Jason Merrill <jason@redhat.com>
+
+ P0702R1 - List deduction of vector.
+ * pt.c (do_class_deduction): Special-case deduction from a single
+ element of related type.
+
+2017-07-26 Leonid Koppel <lkoppel@uwaterloo.ca>
+
+ PR c++/67054 - Inherited ctor with non-default-constructible members
+ * method.c (walk_field_subobs) Consider member initializers (NSDMIs)
+ when deducing an inheriting constructor.
+
+2017-07-21 Nathan Sidwell <nathan@acm.org>
+
+ * search.c (lookup_conversion_operator): Return overloads.
+ (lookup_fnfields_idx_nolazy): Absorb into ...
+ (lookup_fnfields_slot_nolaxy): ... here.
+ (lookup_fnfields_1): Absorb into ...
+ (lookup_fnfields_slot): ... here.
+
+ Remove special CDtor METHOD_VEC slots.
+ * cp-tree.h (CLASSTYPE_CONSTRUCTOR_SLOT,
+ CLASSTYPE_DESTRUCTOR_SLOT): Delete.
+ (CLASSTYPE_CONSTRUCTORS): Use lookup_fnfields_slot_nolazy.
+ (CLASSTYPE_DESTRUCTOR): Likewise.
+ * class (add_method): Don't use special cdtor slots.
+ * search.c (lookup_fnfields_idx_nolazy): Likewise.
+ (look_for_overrides_here): Use lookup_fnfields_slot.
+ * semantics (classtype_has_nothrow_assign_or_copy_p): Likewise.
+
+ * call.c (add_candidates): Move decls to initialization. Don't
+ use !!.
+
+2017-07-20 Nathan Sidwell <nathan@acm.org>
+
+ Remove TYPE_METHODS.
+ * class.c (maybe_warn_about_overly_private_class,
+ finish_struct_methods, one_inheriting_sig, count_fields,
+ add_fields_to_record_type, check_field_decls, check_methods,
+ clone_function_decl, set_method_tm_attributes,
+ finalize_literal_type_property, check_bases_and_members,
+ create_vtable_ptr, determine_key_method,
+ unreverse_member_declarations, finish_struct,
+ add_vcall_offset_vtbl_entries_1): Member fns are on TYPE_FIELDS.
+ * decl.c (fixup_anonymous_aggr): Likewise.
+ * decl2.c (reset_type_linkage_2): Likewise.
+ * method.c (after_nsdmi_defaulted_late_checks,
+ lazily_declare_fn): Likewise.
+ * optimize.c (maybe_thunk_body, maybe_clone_body): Likewise.
+ * pt.c (instantiate_class_template_1, tsubst_expr,
+ do_type_instantiation, instantiate_pending_templates): Likewise.
+ * search.c (lookup_field_1): Likewise.
+ * semantics.c (finish_member_declaration,
+ finish_omp_declare_simd_methods): Likewise.
+
+2017-07-19 Nathan Sidwell <nathan@acm.org>
+
+ * class.c (add_implicitly_declared_members): Use
+ classtype_has_move_assign_or_move_ctor_p.
+ (classtype_has_move_assign_or_move_ctor,
+ classtype_has_user_move_assign_or_move_ctor_p): Merge into ...
+ (classtype_has_move_assign_or_move_ctor_p): ... this new function.
+ * cp-tree.h (classtype_has_user_move_assign_or_move_ctor_p):
+ Replace with ...
+ (classtype_has_move_assign_or_move_ctor_p): ... this.
+ * method.c (maybe_explain_implicit_delete, lazily_declare_fn): Adjust.
+ * tree.c (type_has_nontrivial_copy_init): Adjust.
+
+ * cp-tree.h (PACK_EXPANSION_PARAMETER_PACKS,
+ PACK_EXPANSION_EXTRA_ARGS): Use TYPE_{MIN,MAX}_VALUE_RAW.
+
+2017-07-18 Nathan Sidwell <nathan@acm.org>
+
+ * cp-array-notation.c (build_array_notation_ref): Use
+ TYPE_{MIN,MAX}_VALUE.
+
+ * class.c (classtype_has_move_assign_or_move_ctor): Declare.
+ (add_implicitly_declared_members): Use it.
+ (type_has_move_constructor, type_has_move_assign): Merge into ...
+ (classtype_has_move_assign_or_move_ctor): ... this new function.
+ * cp-tree.h (type_has_move_constructor, type_has_move_assign): Delete.
+
+2017-07-17 Volker Reichelt <v.reichelt@netcologne.de>
+
+ * parser.c (cp_parser_decl_specifier_seq): Add fix-it hints for
+ friend outside class and obsolete auto as storage-class-specifier.
+
+2017-07-17 Nathan Sidwell <nathan@acm.org>
+
+ * class.c (maybe_warn_about_overly_private_class): Ignore public
+ copy ctors.
+
+ * class.c (type_has_user_declared_move_constructor,
+ type_has_user_declared_move_assign): Combine into ...
+ (classtype_has_user_move_assign_or_move_ctor_p): ... this new function.
+ * cp-tree.h (type_has_user_declared_move_constructor,
+ type_has_user_declared_move_assign): Combine into ...
+ (classtype_has_user_move_assign_or_move_ctor_p): ... this. Declare.
+ * method.c (maybe_explain_implicit_delete): Use it.
+ (lazily_declare_fn): Use it.
+ * tree.c (type_has_nontrivial_copy_init): Use it.
+
+ * semantics.c (classtype_has_nothrow_assign_or_copy_p): Clarify
+ semantics, simplify implementation.
+
+2017-07-16 Volker Reichelt <v.reichelt@netcologne.de>
+
+ * parser.c (cp_parser_cast_expression): Use %q#T instead of %qT
+ in old-style cast diagnostic.
+ * typeck.c (maybe_warn_about_useless_cast): Use %q#T instead of %qT
+ in useless cast diagnostic.
+ * error.c (type_to_string): Remove enum special handling.
+
+2017-07-14 David Malcolm <dmalcolm@redhat.com>
+
+ * name-lookup.c (get_std_name_hint): Add '<' and '>' around
+ the header names.
+ (maybe_suggest_missing_header): Update for addition of '<' and '>'
+ to above. Provide a fix-it hint.
+ * pt.c: Include "gcc-rich-location.h"
+ (listify): Attempt to add fix-it hint for missing
+ #include <initializer_list>.
+ * rtti.c: Include "gcc-rich-location.h".
+ (typeid_ok_p): Attempt to add fix-it hint for missing
+ #include <typeinfo>.
+
+2017-07-12 Jason Merrill <jason@redhat.com>
+
+ P0512R0 - Deduction from an initializer list.
+ * pt.c (do_class_deduction): Do list deduction in two phases.
+
+2017-07-12 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (DECL_CONSTRUCTOR_P, DECL_MAYBE_IN_CHARGE_CONSTRUCTOR,
+ DECL_DESTRUCTOR_P, DECL_MAYBE_IN_CHARGE_DESTRCTOR): Look at
+ identifier flags.
+ * decl.c (grokfndecl): Set DECL_CXX_CONSTRUCTOR and
+ DECL_CXX_DESTRUCTOR explicitly.
+ * decl2.c (grokclassfn): Likewise.
+ * friend.c (do_friend): Likewise.
+ * method.c (make_thunk, make_alias_for,
+ implicitly_declare_fn): Likewise.
+
+2017-07-11 Jason Merrill <jason@redhat.com>
+
+ Core DR 393
+ * decl.c (grokparms): Downgrade error about array of unknown bound
+ to pedwarn and disable it for C++17.
+
+2017-07-11 Nathan Sidwell <nathan@acm.org>
+
+ * decl2.c (reset_type_linkage_2): Dont't change ctor name.
+
+2017-07-10 Martin Sebor <msebor@redhat.com>
+
+ * cp-tree.h (cp_operator_id, cp_assignment_operator_id): Document.
+
+2017-07-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/81204 - parse error with dependent template-name
+ * parser.c (cp_parser_lookup_name): Revert previous change.
+
+2017-07-06 David Malcolm <dmalcolm@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_RUN_LANG_SELFTESTS): Define as
+ selftest::run_cp_tests.
+ (selftest::run_cp_tests): New function.
+ * cp-tree.h (selftest::run_cp_tests): New decl.
+
+2017-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_decomposition_declaration): Replace
+ decomposition declaration with structured binding in diagnostics.
+ * decl.c (cp_finish_decomp): Likewise.
+ (grokdeclarator): Likewise.
+
+ PR c++/81258
+ * parser.c (cp_parser_decomposition_declaration): Diagnose invalid
+ forms of structured binding initializers.
+
+2017-07-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/65775
+ * decl.c (grokdeclarator): Move checks on function return type after
+ the splice_late_return_type call; if declspecs->locations[ds_type_spec]
+ is UNKNOWN_LOCATION fall back to input_location.
+
+2017-07-03 David Malcolm <dmalcolm@redhat.com>
+
+ * parser.c (enum required_token): Fix spelling of
+ RT_INTERATION to RT_ITERATION.
+ (cp_parser_iteration_statement): Likewise.
+ (cp_parser_required_error): Likewise.
+
+2017-06-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/81257 - ICE with invalid ::template.
+ PR c++/54769 - wrong lookup of dependent template-name.
+ * parser.c (cp_parser_template_name): Revert part of last change.
+
+2017-06-30 Nathan Sidwell <nathan@acm.org>
+
+ * config-lang.in (gtfiles): Add cp/lex.c.
+ * cp-tree.h (mangle_convop_name_for_type): Rename ...
+ (make_conv_op_name): ... here. Move to lex.
+ * lambda.c (maybe_add_lambda_conv_op): Update.
+ * parser.c (cp_parser_conversion_function_id): Update.
+ * pt.c (tsubst_decl, tsubst_baselink, tsubst_copy,
+ tsubst_copy_and_build): Update.
+ * semantics.c (apply_deduced_return_type): Update.
+ * mangle.c (conv_type_hasher, conv_type_names,
+ mangle_conv_op_name_for_type): Move to ...
+ * lex.c (conv_type_hasher, conv_type_names, make_convop_name):
+ ... here. Rename.
+
+2017-06-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/80014
+ * parser.c (cp_parser_postfix_expression): Construct a location
+ for typeid expressions.
+
+2017-06-30 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (lookup_fnfields_1, class_method_index_for_fn): Don't
+ declare.
+ (lookup_all_conversions): Declare.
+ * class.c (get_basefndecls): Use lookup_fnfields_slot.
+ * decl.c (register_dtor_fn): Use lookup_fnfields_slot.
+ * decl2.c (check_class_fn): Use lookup_fnfields_slot. Rework
+ diagnostics.
+ * pt.c (retrieve_specialization): Use lookup_fnfields_slot.
+ (check_explicit_specialization): Use lookup_fnfields_slot_nolazy,
+ lookup_all_conversions.
+ * search.c (lookup_fnfields_1): Make static.
+ (lookup_all_conversions): New.
+ (class_method_index_for_fn): Delete.
+ * semantics.c (classtype_has_nothrow_assign_or_copy_p): Use
+ lookup_fnfields_slot.
+
+ * call.c (build_new_method_call_1): Use constructo_name to get
+ ctor name. Move argument processing earlier to merge cdtor
+ handling blocks.
+ * decl.c (grokfndecl): Cdtors have special names.
+ * method.c (implicitly_declare_fn): Likewise. Simplify flag setting.
+ * pt.c (check_explicit_specialization): Cdtor name is already
+ special.
+ * search.c (class_method_index_for_fn): Likewise.
+
+ PR c++/81229
+ * name-lookup.c (do_pushdecl): Reset IDENTIFIER_TYPE when finding
+ a matching TYPE_DECL.
+
+2017-06-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * class.c (add_method): Change pair of errors to error + inform.
+ (handle_using_decl): Likewise.
+
+2017-06-29 Jason Merrill <jason@redhat.com>
+
+ * constexpr.c, error.c, tree.c: Remove WITH_CLEANUP_EXPR handling.
+
+ PR c++/81180 - ICE with C++17 deduction of member class template.
+ * pt.c (build_deduction_guide): Correct member template handling.
+
+ PR c++/81188 - matching decltype of member function call.
+ * tree.c (cp_tree_equal): Remove COMPONENT_REF special case.
+
+2017-06-29 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/81247
+ * parser.c (cp_parser_namespace_definition): Immediately close the
+ namespace if there's no open-brace.
+ * name-lookup.c (do_pushdecl): Reset OLD when pushing into new
+ namespace.
+
+2017-06-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/81164 - ICE with invalid inherited constructor.
+ * search.c (binfo_direct_p): New.
+ * name-lookup.c (do_class_using_decl): Use it.
+
+2017-06-29 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (THIS_NAME, IN_CHARGE_NAME, VTBL_PTR_TYPE,
+ VTABLE_DELTA_NAME, VTABLE_PFN_NAME): Delete.
+ * decl.c (initialize_predefined_identifiers): Name cdtor special
+ names consistently. Use literals for above deleted defines.
+ (cxx_init_decl_processing): Use literal for vtbl_ptr_type name,
+
+ * lex.c (maybe_add_lang_type_raw): Exit early, rather than use a
+ flag.
+
+ * call.c (check_dtor_name): Use constructor_name for enums too.
+ (build_new_method_call_1): Use constructor_name for cdtors and
+ show ~ for dtor.
+ * class.c (build_self_reference): Use TYPE_NAME to get name of
+ self reference.
+ * name-lookup (constructor_name): Use DECL_NAME directly.
+ (constructor_name_p): Reimplement.
+ (push_class_level_binding_1): Use TYPE_NAME directly.
+
+ * class.c (finish_struct): Use OVL_P.
+ (get_vfield_name): Measure constructor_name length.
+ * cp-tree.h (SET_CLASS_TYPE_P): Add RECORD_OR_UNION_CHECK.
+ (NON_UNION_CLASS_TYPE_P): Check RECORD_TYPE up front.
+ * cxx-pretty-print.c (is_destructor_name): Delete.
+ (pp_cxx_unqualified_id): Remove bogus destructor name checking.
+ * decl.c (grokfndecl): Move cheap checks first when looking for
+ implicit extern cness.
+
+ * parser.c (cp_parser_direct_declarator): Reorder if to avoid
+ indentation. Remove unnecessary assignment of constructor name.
+
+ Whitespace cleanups.
+ * call.c (name_as_c_string): Move CONST_CAST to return.
+ (build_new_method_call_1): Remove unneeded bracing.
+ * class.c (include_empty_classes): Unbreak line.
+ * constraint.cc (tsubst_check_constraint): Add space.
+ * cp-tree.h (lang_decl_ns): Add comment.
+ (PTRMEM_CST_MEMBER): Break line.
+ * decl.c (grokfndecl): Add blank lines. Unbreak some others.
+ (grokdeclarator): Remove lines, move declaration to first use.
+ * decl2.c (decl_needed_p): Fix indentation.
+ (c_parse_final_cleanups): Remove blank line.
+ * method.c (implicitly_declare_fn): Move declaration to first use.
+ * search.c (current_scope): Add blank lines.
+
+2017-06-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/72764 - ICE with invalid template typename.
+ * decl.c (build_typename_type): No longer static.
+ * tree.c (strip_typedefs): Use it instead of make_typename_type.
+
+ PR c++/69300 - ICE with self-referential noexcept
+ * pt.c (maybe_instantiate_noexcept): Check for recursion.
+
+ PR c++/61022 - error with variadic template template parm
+ * pt.c (convert_template_argument): Keep the TYPE_PACK_EXPANSION.
+
+ PR c++/72801 - ICE with variadic partial specialization
+ * pt.c (unify_pack_expansion): Use PACK_EXPANSION_EXTRA_ARGS.
+
+ PR c++/55639 - partial specialization with ::template
+ * parser.c (cp_parser_class_head): Handle ::template.
+
+ PR c++/45976 - error with ::template in declarator.
+ * pt.c (resolve_typename_type): Fix TEMPLATE_ID_EXPR handling.
+
+ PR c++/54769 - wrong lookup of dependent template-name.
+ * parser.c (cp_parser_template_name): Handle dependent object type.
+ (cp_parser_nested_name_specifier_opt): Make template_keyword_p a
+ parameter.
+ (cp_parser_id_expression): Pass it.
+ (cp_parser_diagnose_invalid_type_name): Handle TEMPLATE_ID_EXPR.
+
+ * parser.c (cp_parser_template_id): Use the range location on the
+ TEMPLATE_ID_EXPR.
+
+ PR c++/81204 - parse error with dependent template-name
+ * parser.c (cp_parser_lookup_name): Disqualify function templates
+ after lookup.
+
+2017-06-27 Nathan Sidwell <nathan@acm.org>
+
+ * pt.c (tsubst_decl <FUNCTION_DECL>): Move var decls to
+ initialization point. Don't unnecessarily check for ctor name.
+
+ * cp-tree.h (CLASSTYPE_DESTRUCTORS): Rename to ...
+ (CLASSTYPE_DESTRUCTOR): ... this.
+ * class.c (accessible_nvdtor_p,
+ maybe_warn_about_overly_private_class,
+ add_implicitly_declared_members,
+ clone_constructors_and_destructors, type_has_virtual_destructor):
+ Adjust for CLASSTYPE_DESTRUCTOR.
+ (deduce_noexcept_on_destructors): Absorb into ...
+ (check_bases_and_members): ... here.
+ * except.c (dtor_nothrow): Adjust for CLASSTYPE_DESTRUCTOR.
+ * init.c (build_delete): Likewise.
+ * parser.c (cp_parser_lookup_name): Likewise.
+ * pt.c (check_explicit_specialization): Likewise.
+ * rtti.c (emit_support_tinfos): Likewise.
+ * search.c (lookup_fnfields_idx_nolazy): Likewise.
+
+ Kill IDENTIFIER_TEMPLATE.
+ * cp-tree.h (lang_identifier): Remove class_template_info field.
+ (IDENTIFIER_TEMPLATE): Delete.
+ * name-lookup.c (constructor_name_full): Subsume into ...
+ (constructor_name): ... here. Don't check IDENTIFIER_TEMPLATE.
+ (constructor_name_p): Likewise.
+ * mangle.c (write_source_name): Likewise.
+ * ptree.c (cxx_print_identifier): Likewise.
+
+2017-06-27 Marek Polacek <polacek@redhat.com>
+
+ PR bootstrap/81216
+ * parser.c (cp_parser_already_scoped_statement): Initialize
+ LOC_AFTER_LABELS.
+
+2017-06-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/81215 - deduction failure with variadic TTP.
+ * pt.c (unify_bound_ttp_args): Restore old logic for C++14 and down.
+
+2017-06-26 Martin Sebor <msebor@redhat.com>
+
+ PR c++/81169
+ * call.c (maybe_warn_class_memaccess): Preserve explicit conversions
+ to detect casting away cv-qualifiers.
+
+2017-06-26 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (lang_decl_fn): Remove assignment_operator_p field.
+ (DECL_COMPLETE_CONSTRUCTOR_P): Directly compare
+ identifier.
+ (DECL_BASE_CONSTRUCTOR_P, DECL_COMPLETE_DESTRUCTOR_P,
+ DECL_BASE_DESTRUCTOR_P, DECL_DELETING_DESTRUCTOR_P): Likewise.
+ (DECL_ASSIGNMENT_OPERATOR_P): Use IDENTIFIER_ASSIGN_OP_P.
+ * decl.c (grok_op_properties): Adjust identifier checking.
+ * init.c (expand_default_init): Adjust identifier descision.
+ * method.c (implicitly_declare_fn): Don't use
+ DECL_ASSIGNMENT_OPERATOR_P.
+ * search.c (lookup_fnfields_1): Use IDENTIFIER_CTOR_P,
+ IDENTIFIER_DTOR_P.
+ * call.c (in_charge_arg_for_name): Reimplement.
+ (build_special_member_call): Use IDENTIFIER_CDTOR_P,
+ IDENTIFIER_DTOR_P.
+
+2017-06-26 Marek Polacek <polacek@redhat.com>
+
+ PR c/80116
+ * parser.c (cp_parser_statement): Add a default argument. Save the
+ location of the expression-statement after labels have been parsed.
+ (cp_parser_implicitly_scoped_statement): Set the location of the
+ body of the conditional after parsing all the labels. Call
+ warn_for_multistatement_macros.
+ (cp_parser_already_scoped_statement): Likewise.
+
2017-06-24 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/62315
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 2fc29da1c7a..e74d48daa8b 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -231,9 +231,8 @@ check_dtor_name (tree basetype, tree name)
else if (identifier_p (name))
{
if ((MAYBE_CLASS_TYPE_P (basetype)
- && name == constructor_name (basetype))
- || (TREE_CODE (basetype) == ENUMERAL_TYPE
- && name == TYPE_IDENTIFIER (basetype)))
+ || TREE_CODE (basetype) == ENUMERAL_TYPE)
+ && name == constructor_name (basetype))
return true;
else
name = get_type_value (name);
@@ -5424,8 +5423,8 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
{
tree ctype;
const vec<tree, va_gc> *non_static_args;
- bool check_list_ctor;
- bool check_converting;
+ bool check_list_ctor = false;
+ bool check_converting = false;
unification_kind_t strict;
if (!fns)
@@ -5436,7 +5435,7 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
if (DECL_CONV_FN_P (fn))
{
check_list_ctor = false;
- check_converting = !!(flags & LOOKUP_ONLYCONVERTING);
+ check_converting = (flags & LOOKUP_ONLYCONVERTING) != 0;
if (flags & LOOKUP_NO_CONVERSION)
/* We're doing return_type(x). */
strict = DEDUCE_CONV;
@@ -5453,18 +5452,13 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
{
if (DECL_CONSTRUCTOR_P (fn))
{
- check_list_ctor = !!(flags & LOOKUP_LIST_ONLY);
+ check_list_ctor = (flags & LOOKUP_LIST_ONLY) != 0;
/* 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;
}
@@ -5477,9 +5471,6 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
for (lkp_iterator iter (fns); iter; ++iter)
{
- tree fn_first_arg;
- const vec<tree, va_gc> *fn_args;
-
fn = *iter;
if (check_converting && DECL_NONCONVERTING_P (fn))
@@ -5487,10 +5478,13 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
if (check_list_ctor && !is_list_ctor (fn))
continue;
- /* Figure out which set of arguments to use. */
+ tree fn_first_arg = NULL_TREE;
+ const vec<tree, va_gc> *fn_args = args;
+
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
{
- /* If this function is a non-static member and we didn't get an
+ /* Figure out where the object arg comes from. 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)
{
@@ -5507,12 +5501,6 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
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,
@@ -8340,7 +8328,10 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args)
if (!dest || !TREE_TYPE (dest) || !POINTER_TYPE_P (TREE_TYPE (dest)))
return;
- STRIP_NOPS (dest);
+ /* Remove the outermost (usually implicit) conversion to the void*
+ argument type. */
+ if (TREE_CODE (dest) == NOP_EXPR)
+ dest = TREE_OPERAND (dest, 0);
tree srctype = NULL_TREE;
@@ -8357,7 +8348,7 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args)
if (current_function_decl
&& (DECL_CONSTRUCTOR_P (current_function_decl)
|| DECL_DESTRUCTOR_P (current_function_decl))
- && is_this_parameter (dest))
+ && is_this_parameter (tree_strip_nop_conversions (dest)))
{
tree ctx = DECL_CONTEXT (current_function_decl);
bool special = same_type_ignoring_top_level_qualifiers_p (ctx, desttype);
@@ -8677,20 +8668,22 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
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;
+ if (IDENTIFIER_CTOR_P (name))
+ {
+ if (name == complete_ctor_identifier)
+ return integer_one_node;
+ gcc_checking_assert (name == base_ctor_identifier);
+ }
+ else
+ {
+ if (name == complete_dtor_identifier)
+ return integer_two_node;
+ else if (name == deleting_dtor_identifier)
+ return integer_three_node;
+ gcc_checking_assert (name == base_dtor_identifier);
+ }
+
+ return integer_zero_node;
}
/* We've built up a constructor call RET. Complain if it delegates to the
@@ -8729,11 +8722,7 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
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
+ gcc_assert (IDENTIFIER_CDTOR_P (name)
|| name == cp_assignment_operator_id (NOP_EXPR));
if (TYPE_P (binfo))
{
@@ -8753,9 +8742,7 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
instance = build_dummy_object (class_type);
else
{
- if (name == complete_dtor_identifier
- || name == base_dtor_identifier
- || name == deleting_dtor_identifier)
+ if (IDENTIFIER_DTOR_P (name))
gcc_assert (args == NULL || vec_safe_is_empty (*args));
/* Convert to the base class, if necessary. */
@@ -8879,7 +8866,7 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
static char *
name_as_c_string (tree name, tree type, bool *free_p)
{
- char *pretty_name;
+ const char *pretty_name;
/* Assume that we will not allocate memory. */
*free_p = false;
@@ -8887,7 +8874,7 @@ name_as_c_string (tree name, tree type, bool *free_p)
if (IDENTIFIER_CDTOR_P (name))
{
pretty_name
- = CONST_CAST (char *, identifier_to_locale (IDENTIFIER_POINTER (constructor_name (type))));
+ = identifier_to_locale (IDENTIFIER_POINTER (constructor_name (type)));
/* For a destructor, add the '~'. */
if (IDENTIFIER_DTOR_P (name))
{
@@ -8906,9 +8893,9 @@ name_as_c_string (tree name, tree type, bool *free_p)
*free_p = true;
}
else
- pretty_name = CONST_CAST (char *, identifier_to_locale (IDENTIFIER_POINTER (name)));
+ pretty_name = identifier_to_locale (IDENTIFIER_POINTER (name));
- return pretty_name;
+ return CONST_CAST (char *, pretty_name);
}
/* Build a call to "INSTANCE.FN (ARGS)". If FN_P is non-NULL, it will
@@ -8996,6 +8983,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
if (! (complain & tf_error))
return error_mark_node;
+ name = constructor_name (basetype);
if (permerror (input_location,
"cannot call constructor %<%T::%D%> directly",
basetype, name))
@@ -9006,6 +8994,19 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
return call;
}
+ /* 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);
+
+
/* 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"
@@ -9015,35 +9016,18 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
skip_first_for_error = false;
if (IDENTIFIER_CDTOR_P (name))
{
- /* Callers should explicitly indicate whether they want to construct
+ /* Callers should explicitly indicate whether they want to ctor
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))
- {
+ /* It's OK to call destructors and constructors on cv-qualified
+ objects. Therefore, convert the INSTANCE to the unqualified
+ type, if necessary. */
if (!same_type_p (basetype, TREE_TYPE (instance)))
{
instance = build_this (instance);
@@ -9051,8 +9035,8 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
instance = build_fold_indirect_ref (instance);
}
}
- if (DECL_DESTRUCTOR_P (fn))
- name = complete_dtor_identifier;
+ else
+ gcc_assert (!DECL_DESTRUCTOR_P (fn) && !DECL_CONSTRUCTOR_P (fn));
/* For the overload resolution we need to find the actual `this`
that would be captured if the call turns out to be to a
@@ -9119,11 +9103,10 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
&candidates, complain);
}
else
- {
- add_candidates (fns, first_mem_arg, user_args, optype,
- explicit_targs, template_only, conversion_path,
- access_binfo, flags, &candidates, complain);
- }
+ 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, false, &any_viable_p);
@@ -9141,17 +9124,18 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
{
tree arglist = build_tree_list_vec (user_args);
tree errname = name;
+ bool twiddle = false;
if (IDENTIFIER_CDTOR_P (errname))
{
- tree fn = DECL_ORIGIN (OVL_FIRST (fns));
- errname = DECL_NAME (fn);
+ twiddle = IDENTIFIER_DTOR_P (errname);
+ errname = constructor_name (basetype);
}
if (explicit_targs)
errname = lookup_template_function (errname, explicit_targs);
if (skip_first_for_error)
arglist = TREE_CHAIN (arglist);
- error ("no matching function for call to %<%T::%E(%A)%#V%>",
- basetype, errname, arglist,
+ error ("no matching function for call to %<%T::%s%E(%A)%#V%>",
+ basetype, &"~"[!twiddle], errname, arglist,
TREE_TYPE (instance));
}
print_z_candidates (location_of (name), candidates);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 1243f33605f..508570bdb04 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1039,50 +1039,39 @@ add_method (tree type, tree method, bool via_using)
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;
- else
- {
- tree m;
+ 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)
+ 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_FIRST (m);
+ if (template_conv_p)
{
- m = OVL_FIRST (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;
+ 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];
@@ -1217,10 +1206,11 @@ add_method (tree type, tree method, bool via_using)
continue;
}
error_at (DECL_SOURCE_LOCATION (method),
- "%q#D", method);
- error_at (DECL_SOURCE_LOCATION (fn),
- "conflicts with version inherited from %qT",
- basef);
+ "%q#D conflicts with version inherited from %qT",
+ method, basef);
+ inform (DECL_SOURCE_LOCATION (fn),
+ "version inherited from %qT declared here",
+ basef);
}
/* Otherwise defer to the other function. */
return false;
@@ -1238,8 +1228,10 @@ add_method (tree type, tree method, bool via_using)
}
else
{
- error ("%q+#D cannot be overloaded", method);
- error ("with %q+#D", fn);
+ error_at (DECL_SOURCE_LOCATION (method),
+ "%q#D cannot be overloaded with %q#D", method, fn);
+ inform (DECL_SOURCE_LOCATION (fn),
+ "previous declaration %q#D", fn);
return false;
}
}
@@ -1253,7 +1245,7 @@ add_method (tree type, tree method, bool via_using)
if (conv_p)
TYPE_HAS_CONVERSION (type) = 1;
- else if (slot >= CLASSTYPE_FIRST_CONVERSION_SLOT && !complete_p)
+ else if (!complete_p && !IDENTIFIER_CDTOR_P (DECL_NAME (method)))
push_class_level_binding (DECL_NAME (method), current_fns);
if (insert_p)
@@ -1371,16 +1363,21 @@ handle_using_decl (tree using_decl, tree t)
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",
- old_value);
+ error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T "
+ "because of local method %q#D with same name",
+ using_decl, t, old_value);
+ inform (DECL_SOURCE_LOCATION (old_value),
+ "local method %q#D declared here", 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);
+ error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T "
+ "because of local member %q#D with same name",
+ using_decl, t, old_value);
+ inform (DECL_SOURCE_LOCATION (old_value),
+ "local member %q#D declared here", old_value);
return;
}
@@ -1711,7 +1708,7 @@ inherit_targ_abi_tags (tree t)
static bool
accessible_nvdtor_p (tree t)
{
- tree dtor = CLASSTYPE_DESTRUCTORS (t);
+ tree dtor = CLASSTYPE_DESTRUCTOR (t);
/* An implicitly declared destructor is always public. And,
if it were virtual, we would have created it by now. */
@@ -2141,7 +2138,6 @@ 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
@@ -2171,26 +2167,26 @@ maybe_warn_about_overly_private_class (tree t)
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))
+ for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
+ if (!DECL_DECLARES_FUNCTION_P (fn))
+ /* Not a function. */;
+ else if (DECL_ARTIFICIAL (fn))
+ /* We're not interested in compiler-generated methods; they don't
+ provide any way to call private members. */;
+ else if (!TREE_PRIVATE (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;
+ 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;
+ 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)
{
@@ -2220,22 +2216,22 @@ maybe_warn_about_overly_private_class (tree t)
/* 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;
- }
+ if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
+ if (TREE_PRIVATE (dtor))
+ {
+ 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)))
+ && !CLASSTYPE_LAZY_DEFAULT_CTOR (t))
{
bool nonprivate_ctor = false;
+ tree copy_or_move = NULL_TREE;
/* If a non-template class does not define a copy
constructor, one is defined for it, enabling it to avoid
@@ -2252,13 +2248,15 @@ maybe_warn_about_overly_private_class (tree t)
else
for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t));
!nonprivate_ctor && iter; ++iter)
- /* 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 (*iter))
+ if (TREE_PRIVATE (*iter))
+ continue;
+ else if (copy_fn_p (*iter) || move_fn_p (*iter))
+ /* Ideally, we wouldn't count 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. */
+ copy_or_move = *iter;
+ else
nonprivate_ctor = true;
if (!nonprivate_ctor)
@@ -2266,6 +2264,10 @@ maybe_warn_about_overly_private_class (tree t)
warning (OPT_Wctor_dtor_privacy,
"%q#T only defines private constructors and has no friends",
t);
+ if (copy_or_move)
+ inform (DECL_SOURCE_LOCATION (copy_or_move),
+ "%q#D is public, but requires an existing %q#T object",
+ copy_or_move, t);
return;
}
}
@@ -2359,7 +2361,6 @@ resort_type_method_vec (void* obj,
static void
finish_struct_methods (tree t)
{
- tree fn_fields;
vec<tree, va_gc> *method_vec;
int slot, len;
@@ -2370,9 +2371,9 @@ finish_struct_methods (tree t)
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;
+ for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
+ if (DECL_DECLARES_FUNCTION_P (fn))
+ DECL_IN_AGGR_P (fn) = false;
/* Issue warnings about private constructors and such. If there are
no methods, then some public defaults are generated. */
@@ -2380,6 +2381,7 @@ finish_struct_methods (tree t)
/* The type conversion ops have to live at the front of the vec, so we
can't sort them. */
+ tree fn_fields;
for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
method_vec->iterate (slot, &fn_fields);
++slot)
@@ -2958,29 +2960,25 @@ modify_all_vtables (tree t, tree virtuals)
static void
get_basefndecls (tree name, tree t, vec<tree> *base_fndecls)
{
- int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
- int i;
+ bool found_decls = false;
/* Find virtual functions in T with the indicated NAME. */
- i = lookup_fnfields_1 (t, name);
- bool found_decls = false;
- if (i != -1)
- for (ovl_iterator iter ((*CLASSTYPE_METHOD_VEC (t))[i]); iter; ++iter)
- {
- tree method = *iter;
+ for (ovl_iterator iter (lookup_fnfields_slot (t, name)); iter; ++iter)
+ {
+ tree method = *iter;
- if (TREE_CODE (method) == FUNCTION_DECL
- && DECL_VINDEX (method))
- {
- base_fndecls->safe_push (method);
- found_decls = true;
- }
- }
+ if (TREE_CODE (method) == FUNCTION_DECL && DECL_VINDEX (method))
+ {
+ base_fndecls->safe_push (method);
+ found_decls = true;
+ }
+ }
if (found_decls)
return;
- for (i = 0; i < n_baseclasses; i++)
+ int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
+ for (int i = 0; i < n_baseclasses; i++)
{
tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), i));
get_basefndecls (name, basetype, base_fndecls);
@@ -3295,6 +3293,8 @@ declare_virt_assop_and_dtor (tree t)
static void
one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
{
+ gcc_assert (TYPE_MAIN_VARIANT (t) == t);
+
/* We don't declare an inheriting ctor that would be a default,
copy or move ctor for derived or base. */
if (nparms == 0)
@@ -3312,11 +3312,11 @@ one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
parmlist = tree_cons (NULL_TREE, parms[i], parmlist);
tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
t, false, ctor, parmlist);
- gcc_assert (TYPE_MAIN_VARIANT (t) == t);
+
if (add_method (t, fn, false))
{
- DECL_CHAIN (fn) = TYPE_METHODS (t);
- TYPE_METHODS (t) = fn;
+ DECL_CHAIN (fn) = TYPE_FIELDS (t);
+ TYPE_FIELDS (t) = fn;
}
}
@@ -3366,18 +3366,17 @@ 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))
+ if (!CLASSTYPE_DESTRUCTOR (t))
/* In general, we create destructors lazily. */
CLASSTYPE_LAZY_DESTRUCTOR (t) = 1;
+ bool move_ok = false;
+ if (cxx_dialect >= cxx11 && CLASSTYPE_LAZY_DESTRUCTOR (t)
+ && !TYPE_HAS_COPY_CTOR (t) && !TYPE_HAS_COPY_ASSIGN (t)
+ && !classtype_has_move_assign_or_move_ctor_p (t, false))
+ move_ok = true;
+
/* [class.ctor]
If there is no user-declared constructor for a class, a default
@@ -3456,7 +3455,9 @@ count_fields (tree fields)
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)))
+ if (DECL_DECLARES_FUNCTION_P (x))
+ /* Functions are dealt with separately. */;
+ else 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;
@@ -3474,7 +3475,9 @@ add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, in
tree x;
for (x = fields; x; x = DECL_CHAIN (x))
{
- if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
+ if (DECL_DECLARES_FUNCTION_P (x))
+ /* Functions are handled separately. */;
+ else 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;
@@ -3731,6 +3734,10 @@ check_field_decls (tree t, tree *access_decls,
|| TREE_CODE (x) == TEMPLATE_DECL)
continue;
+ if (TREE_CODE (x) == FUNCTION_DECL)
+ /* FIXME: We should fold in the checking from check_methods. */
+ continue;
+
/* If we've gotten this far, it's a data member, possibly static,
or an enumerator. */
if (TREE_CODE (x) != CONST_DECL)
@@ -4655,39 +4662,42 @@ build_base_fields (record_layout_info rli,
}
}
-/* Go through the TYPE_METHODS of T issuing any appropriate
+/* Go through the TYPE_FIELDS 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 (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
+ if (DECL_DECLARES_FUNCTION_P (x))
+ {
+ check_for_override (x, t);
+
+ if (DECL_PURE_VIRTUAL_P (x)
+ && (TREE_CODE (x) != FUNCTION_DECL || ! 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 (TREE_CODE (x) == FUNCTION_DECL && DECL_VINDEX (x))
+ {
+ TYPE_POLYMORPHIC_P (t) = 1;
+ if (DECL_PURE_VIRTUAL_P (x))
+ vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
+ }
- for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x))
- {
- check_for_override (x, t);
- if (DECL_PURE_VIRTUAL_P (x) && (TREE_CODE (x) != FUNCTION_DECL || ! 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 (TREE_CODE (x) == FUNCTION_DECL && 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;
- if (!DECL_VIRTUAL_P (x)
- && lookup_attribute ("transaction_safe_dynamic", DECL_ATTRIBUTES (x)))
- error_at (DECL_SOURCE_LOCATION (x),
- "%<transaction_safe_dynamic%> may only be specified for "
- "a virtual function");
- }
+ /* 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;
+ if (!DECL_VIRTUAL_P (x)
+ && lookup_attribute ("transaction_safe_dynamic",
+ DECL_ATTRIBUTES (x)))
+ error_at (DECL_SOURCE_LOCATION (x),
+ "%<transaction_safe_dynamic%> may only be specified for "
+ "a virtual function");
+ }
}
/* FN is a constructor or destructor. Clone the declaration to create
@@ -4893,7 +4903,7 @@ clone_function_decl (tree fn, bool update_methods)
/* 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
+ means it will go second on the TYPE_FIELDS list -- and that
corresponds to the correct layout order in the virtual
function table.
@@ -5015,8 +5025,9 @@ clone_constructors_and_destructors (tree t)
we no longer need to know that. */
for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
clone_function_decl (*iter, /*update_methods=*/true);
- for (ovl_iterator iter (CLASSTYPE_DESTRUCTORS (t)); iter; ++iter)
- clone_function_decl (*iter, /*update_methods=*/true);
+
+ if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
+ clone_function_decl (dtor, /*update_methods=*/true);
}
/* Deduce noexcept for a destructor DTOR. */
@@ -5029,24 +5040,6 @@ deduce_noexcept_on_destructor (tree dtor)
noexcept_deferred_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 (ovl_iterator iter (CLASSTYPE_DESTRUCTORS (t)); iter; ++iter)
- deduce_noexcept_on_destructor (*iter);
-}
-
/* 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. */
@@ -5182,11 +5175,10 @@ set_method_tm_attributes (tree t)
/* 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);
- }
+ for (fndecl = TYPE_FIELDS (t); fndecl; fndecl = DECL_CHAIN (fndecl))
+ if (DECL_DECLARES_FUNCTION_P (fndecl)
+ && !find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+ apply_tm_attr (fndecl, class_tm_attr);
}
/* Returns true if FN is a default constructor. */
@@ -5460,93 +5452,42 @@ type_has_virtual_destructor (tree type)
return false;
gcc_assert (COMPLETE_TYPE_P (type));
- dtor = CLASSTYPE_DESTRUCTORS (type);
+ dtor = CLASSTYPE_DESTRUCTOR (type);
return (dtor && DECL_VIRTUAL_P (dtor));
}
-/* Returns true iff class T has a move constructor. */
+/* Returns true iff T, a class, has a move-assignment or
+ move-constructor. Does not lazily declare either.
+ If USER_P is false, any move function will do. If it is true, the
+ move function must be user-declared.
-bool
-type_has_move_constructor (tree t)
-{
- 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 (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
- if (move_fn_p (*iter))
- return true;
-
- return false;
-}
-
-/* Returns true iff class T has a move assignment operator. */
+ Note that user-declared here is different from "user-provided",
+ which doesn't include functions that are defaulted in the
+ class. */
bool
-type_has_move_assign (tree t)
+classtype_has_move_assign_or_move_ctor_p (tree t, bool user_p)
{
- if (CLASSTYPE_LAZY_MOVE_ASSIGN (t))
- {
- gcc_assert (COMPLETE_TYPE_P (t));
- lazily_declare_fn (sfk_move_assignment, t);
- }
-
- for (ovl_iterator iter (lookup_fnfields_slot_nolazy
- (t, cp_assignment_operator_id (NOP_EXPR)));
- iter; ++iter)
- if (move_fn_p (*iter))
- 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)
-{
- if (CLASSTYPE_LAZY_MOVE_CTOR (t))
- return false;
+ gcc_assert (user_p
+ || (!CLASSTYPE_LAZY_MOVE_CTOR (t)
+ && !CLASSTYPE_LAZY_MOVE_ASSIGN (t)));
if (!CLASSTYPE_METHOD_VEC (t))
return false;
- for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
- {
- tree fn = *iter;
- if (move_fn_p (fn) && !DECL_ARTIFICIAL (fn))
+ if (!CLASSTYPE_LAZY_MOVE_CTOR (t))
+ for (ovl_iterator iter (lookup_fnfields_slot_nolazy (t, ctor_identifier));
+ iter; ++iter)
+ if ((!user_p || !DECL_ARTIFICIAL (*iter)) && move_fn_p (*iter))
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)
-{
- if (CLASSTYPE_LAZY_MOVE_ASSIGN (t))
- return false;
-
- for (ovl_iterator iter (lookup_fnfields_slot_nolazy
- (t, cp_assignment_operator_id (NOP_EXPR)));
- iter; ++iter)
- {
- tree fn = *iter;
- if (move_fn_p (fn) && !DECL_ARTIFICIAL (fn))
+ if (!CLASSTYPE_LAZY_MOVE_ASSIGN (t))
+ for (ovl_iterator iter (lookup_fnfields_slot_nolazy
+ (t, cp_assignment_operator_id (NOP_EXPR)));
+ iter; ++iter)
+ if ((!user_p || !DECL_ARTIFICIAL (*iter)) && move_fn_p (*iter))
return true;
- }
-
+
return false;
}
@@ -5719,9 +5660,9 @@ finalize_literal_type_property (tree t)
/* C++14 DR 1684 removed this restriction. */
if (cxx_dialect < cxx14
&& !CLASSTYPE_LITERAL_P (t) && !LAMBDA_TYPE_P (t))
- for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
- if (DECL_DECLARED_CONSTEXPR_P (fn)
- && TREE_CODE (fn) != TEMPLATE_DECL
+ for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
+ if (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_DECLARED_CONSTEXPR_P (fn)
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
&& !DECL_CONSTRUCTOR_P (fn))
{
@@ -5851,10 +5792,11 @@ check_bases_and_members (tree t)
of potential interest. */
check_bases (t, &cant_have_const_ctor, &no_const_asn_ref);
- /* Deduce noexcept on destructors. This needs to happen after we've set
+ /* Deduce noexcept on destructor. This needs to happen after we've set
triviality flags appropriately for our bases. */
if (cxx_dialect >= cxx11)
- deduce_noexcept_on_destructors (t);
+ if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
+ deduce_noexcept_on_destructor (dtor);
/* Check all the method declarations. */
check_methods (t);
@@ -5982,8 +5924,10 @@ check_bases_and_members (tree t)
/* 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))
+ for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
+ if (DECL_DECLARES_FUNCTION_P (fn)
+ && !DECL_ARTIFICIAL (fn)
+ && DECL_DEFAULTED_IN_CLASS_P (fn))
{
int copy = copy_fn_p (fn);
if (copy > 0)
@@ -6042,7 +5986,7 @@ 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))
+ for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
if (TREE_CODE (fn) == FUNCTION_DECL
&& DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
&& TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
@@ -6312,8 +6256,7 @@ include_empty_classes (record_layout_info rli)
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);
+ 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
&& tree_int_cst_lt (rli_size, eoc))
@@ -6702,8 +6645,7 @@ determine_key_method (tree type)
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))
+ for (method = TYPE_FIELDS (type); method; method = DECL_CHAIN (method))
if (TREE_CODE (method) == FUNCTION_DECL
&& DECL_VINDEX (method) != NULL_TREE
&& ! DECL_DECLARED_INLINE_P (method)
@@ -7395,11 +7337,11 @@ unreverse_member_declarations (tree t)
/* 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. */
+ /* For the TYPE_FIELDS, only the non TYPE_DECLs are in reverse
+ order, so we can't just use nreverse. Due to stat_hack
+ chicanery in finish_member_declarations. */
prev = NULL_TREE;
for (x = TYPE_FIELDS (t);
x && TREE_CODE (x) != TYPE_DECL;
@@ -7409,6 +7351,7 @@ unreverse_member_declarations (tree t)
DECL_CHAIN (x) = prev;
prev = x;
}
+
if (prev)
{
DECL_CHAIN (TYPE_FIELDS (t)) = x;
@@ -7449,8 +7392,8 @@ finish_struct (tree t, tree attributes)
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))
+ for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
+ if (TREE_CODE (x) == FUNCTION_DECL && 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
@@ -7461,7 +7404,7 @@ finish_struct (tree t, tree attributes)
if (TREE_CODE (x) == USING_DECL)
{
tree fn = strip_using_decl (x);
- if (is_overloaded_fn (fn))
+ if (OVL_P (fn))
for (lkp_iterator iter (fn); iter; ++iter)
add_method (t, *iter, true);
}
@@ -7475,7 +7418,6 @@ finish_struct (tree t, tree attributes)
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
@@ -8522,7 +8464,6 @@ static tree
get_vfield_name (tree type)
{
tree binfo, base_binfo;
- char *buf;
for (binfo = TYPE_BINFO (type);
BINFO_N_BASE_BINFOS (binfo);
@@ -8536,10 +8477,10 @@ get_vfield_name (tree type)
}
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)));
+ tree ctor_name = constructor_name (type);
+ char *buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
+ + IDENTIFIER_LENGTH (ctor_name) + 2);
+ sprintf (buf, VFIELD_NAME_FORMAT, IDENTIFIER_POINTER (ctor_name));
return get_identifier (buf);
}
@@ -8569,9 +8510,8 @@ print_class_statistics (void)
void
build_self_reference (void)
{
- tree name = constructor_name (current_class_type);
+ tree name = DECL_NAME (TYPE_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;
@@ -8582,7 +8522,7 @@ build_self_reference (void)
if (processing_template_decl)
value = push_template_decl (value);
- saved_cas = current_access_specifier;
+ tree saved_cas = current_access_specifier;
current_access_specifier = access_public_node;
finish_member_declaration (value);
current_access_specifier = saved_cas;
@@ -9983,7 +9923,7 @@ add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid)
/* The ABI requires that the methods be processed in declaration
order. */
- for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo));
+ for (orig_fn = TYPE_FIELDS (BINFO_TYPE (binfo));
orig_fn;
orig_fn = DECL_CHAIN (orig_fn))
if (TREE_CODE (orig_fn) == FUNCTION_DECL && DECL_VINDEX (orig_fn))
diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in
index d0a96a07b5a..c009570b63d 100644
--- a/gcc/cp/config-lang.in
+++ b/gcc/cp/config-lang.in
@@ -45,7 +45,7 @@ gtfiles="\
\$(srcdir)/cp/except.c \
\$(srcdir)/cp/friend.c \
\$(srcdir)/cp/init.c \
-\$(srcdir)/cp/lambda.c \
+\$(srcdir)/cp/lambda.c \$(srcdir)/cp/lex.c \
\$(srcdir)/cp/mangle.c \$(srcdir)/cp/method.c \
\$(srcdir)/cp/name-lookup.c \
\$(srcdir)/cp/parser.c \$(srcdir)/cp/pt.c \
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 5a574524866..29ba2c3dac2 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -4519,7 +4519,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
/* GCC internal stuff. */
case VA_ARG_EXPR:
case OBJ_TYPE_REF:
- case WITH_CLEANUP_EXPR:
case NON_DEPENDENT_EXPR:
case BASELINK:
case OFFSET_REF:
@@ -5533,7 +5532,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
case BIND_EXPR:
return RECUR (BIND_EXPR_BODY (t), want_rval);
- case WITH_CLEANUP_EXPR:
case CLEANUP_POINT_EXPR:
case MUST_NOT_THROW_EXPR:
case TRY_CATCH_EXPR:
@@ -5784,6 +5782,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
case CLEANUP_STMT:
case EMPTY_CLASS_EXPR:
+ case PREDICT_EXPR:
return false;
case GOTO_EXPR:
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 6fd4bde22e5..64a8ea926d2 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1580,7 +1580,7 @@ tsubst_check_constraint (tree t, tree args,
/* Substitute through by building an template-id expression
and then substituting into that. */
- tree expr = build_nt(TEMPLATE_ID_EXPR, tmpl, targs);
+ tree expr = build_nt (TEMPLATE_ID_EXPR, tmpl, targs);
++processing_template_decl;
tree result = tsubst_expr (expr, args, complain, in_decl, false);
--processing_template_decl;
diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c
index 36d66245224..31be7d685ba 100644
--- a/gcc/cp/cp-array-notation.c
+++ b/gcc/cp/cp-array-notation.c
@@ -1375,8 +1375,8 @@ build_array_notation_ref (location_t loc, tree array, tree start, tree length,
"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);
+ start = cp_fold_convert (ptrdiff_type_node, TYPE_MIN_VALUE (domain));
+ length = size_binop (PLUS_EXPR, TYPE_MAX_VALUE (domain), size_one_node);
length = cp_fold_convert (ptrdiff_type_node, length);
}
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index f010f6c63be..a9563b1a8cd 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -1668,7 +1668,8 @@ cp_genericize (tree fndecl)
walk_tree's hash functionality. */
cp_genericize_tree (&DECL_SAVED_TREE (fndecl), true);
- if (sanitize_flags_p (SANITIZE_RETURN))
+ if (sanitize_flags_p (SANITIZE_RETURN)
+ && current_function_decl != NULL_TREE)
cp_ubsan_maybe_instrument_return (fndecl);
/* Do everything else. */
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index defcbdc79a9..805319a4185 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -79,6 +79,11 @@ static tree cxx_enum_underlying_base_type (const_tree);
#undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
#define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE cxx_enum_underlying_base_type
+#if CHECKING_P
+#undef LANG_HOOKS_RUN_LANG_SELFTESTS
+#define LANG_HOOKS_RUN_LANG_SELFTESTS selftest::run_cp_tests
+#endif /* #if CHECKING_P */
+
/* Each front end provides its own lang hook initializer. */
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -229,6 +234,25 @@ tree cxx_enum_underlying_base_type (const_tree type)
return underlying_type;
}
+#if CHECKING_P
+
+namespace selftest {
+
+/* Implementation of LANG_HOOKS_RUN_LANG_SELFTESTS for the C++ frontend. */
+
+void
+run_cp_tests (void)
+{
+ /* Run selftests shared within the C family. */
+ c_family_tests ();
+
+ /* Additional C++-specific tests. */
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
+
#include "gt-cp-cp-lang.h"
#include "gtype-cp.h"
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 5a7da5b4957..4475b6cb911 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -212,6 +212,13 @@ cp_decl_dwarf_attribute (const_tree decl, int attr)
}
break;
+ case DW_AT_export_symbols:
+ if (TREE_CODE (decl) == NAMESPACE_DECL
+ && (DECL_NAMESPACE_INLINE_P (decl)
+ || (DECL_NAME (decl) == NULL_TREE && dwarf_version >= 5)))
+ return 1;
+ break;
+
default:
break;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 33dde158dae..115cdaff61e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -206,8 +206,19 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
/* std::align_val_t */
#define align_type_node cp_global_trees[CPTI_ALIGN_TYPE]
-/* We cache these tree nodes so as to call get_identifier less
- frequently. */
+/* We cache these tree nodes so as to call get_identifier less frequently.
+ For identifiers for functions, including special member functions such
+ as ctors and assignment operators, the nodes can be used (among other
+ things) to iterate over their overloads defined by/for a type. For
+ example:
+
+ tree ovlid = cp_assignment_operator_id (NOP_EXPR);
+ tree overloads = lookup_fnfields_slot (type, ovlid);
+ for (ovl_iterator it (overloads); it; ++it) { ... }
+
+ iterates over the set of implicitly and explicitly defined overloads
+ of the assignment operator for type (including the copy and move
+ assignment operators, whether deleted or not). */
/* The name of a constructor that takes an in-charge parameter to
decide whether or not to construct virtual base classes. */
@@ -228,6 +239,18 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
/* 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]
+
+/* The name of the identifier used internally to represent operator CODE. */
+#define cp_operator_id(CODE) \
+ (operator_name_info[(int) (CODE)].identifier)
+
+/* The name of the identifier used to represent assignment operator CODE,
+ both simple (i.e., operator= with CODE == NOP_EXPR) and compound (e.g.,
+ operator+= with CODE == PLUS_EXPR). Includes copy and move assignment.
+ Use copy_fn_p() to test specifically for copy assignment. */
+#define cp_assignment_operator_id(CODE) \
+ (assignment_operator_name_info[(int) (CODE)].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
@@ -527,7 +550,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
struct GTY(()) lang_identifier {
struct c_common_identifier c_common;
cxx_binding *bindings;
- tree class_template_info;
tree label_value;
};
@@ -954,9 +976,6 @@ enum GTY(()) abstract_class_use {
/* Macros for access to language-specific slots in an identifier. */
-#define IDENTIFIER_TEMPLATE(NODE) \
- (LANG_IDENTIFIER_CAST (NODE)->class_template_info)
-
/* The IDENTIFIER_BINDING is the innermost cxx_binding for the
identifier. Its PREVIOUS is the next outermost binding. Each
VALUE field is a DECL for the associated declaration. Thus,
@@ -1772,10 +1791,6 @@ struct GTY(()) language_function {
#define current_function_auto_return_pattern \
(cp_function_chain->x_auto_return_pattern)
-#define cp_operator_id(CODE) \
- (operator_name_info[(int) (CODE)].identifier)
-#define cp_assignment_operator_id(CODE) \
- (assignment_operator_name_info[(int) (CODE)].identifier)
/* In parser.c. */
extern tree cp_literal_operator_id (const char *);
@@ -1817,7 +1832,7 @@ enum languages { lang_c, lang_cplusplus };
/* 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))
+ (TYPE_LANG_FLAG_5 (RECORD_OR_UNION_CHECK (T)) = (VAL))
/* Nonzero if T is a class type. Zero for template type parameters,
typename types, and so forth. */
@@ -1826,7 +1841,7 @@ enum languages { lang_c, lang_cplusplus };
/* 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)
+ (TREE_CODE (T) == RECORD_TYPE && TYPE_LANG_FLAG_5 (T))
/* Keep these checks in ascending code order. */
#define RECORD_OR_UNION_CODE_P(T) \
@@ -2133,29 +2148,21 @@ struct GTY(()) lang_type {
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
+#define CLASSTYPE_FIRST_CONVERSION_SLOT 0
/* 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])
+ (lookup_fnfields_slot_nolazy (NODE, ctor_identifier))
-/* A FUNCTION_DECL for the destructor for NODE. These are the
+/* A FUNCTION_DECL for the destructor for NODE. This is 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)
+#define CLASSTYPE_DESTRUCTOR(NODE) \
+ (lookup_fnfields_slot_nolazy (NODE, dtor_identifier))
/* A dictionary of the nested user-defined-types (class-types, or enums)
found within this class. This table includes nested member class
@@ -2182,11 +2189,9 @@ struct GTY(()) lang_type {
/* The type corresponding to NODE when NODE is used as a base class,
i.e., NODE without virtual base classes or tail padding. */
-
#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)) \
@@ -2495,25 +2500,27 @@ struct GTY(()) lang_decl_fn {
struct lang_decl_min min;
/* In an overloaded operator, this is the value of
- DECL_OVERLOADED_OPERATOR_P. */
+ DECL_OVERLOADED_OPERATOR_P.
+ FIXME: We should really do better in compressing this. */
ENUM_BITFIELD (tree_code) operator_code : 16;
unsigned global_ctor_p : 1;
unsigned global_dtor_p : 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;
- /* 2 spare bits on 32-bit hosts, 34 on 64-bit hosts. */
+ /* 3 spare bits. */
+
+ /* 32-bits padding on 64-bit host. */
/* For a non-thunk function decl, this is a tree list of
friendly classes. For a thunk function decl, it is the
@@ -2559,7 +2566,9 @@ struct GTY(()) lang_decl_ns {
vec<tree, va_gc> *usings;
vec<tree, va_gc> *inlinees;
- /* Map from IDENTIFIER nodes to DECLS. */
+ /* Map from IDENTIFIER nodes to DECLS. It'd be nice to have this
+ inline, but as the hash_map has a dtor, we can't then put this
+ struct into a union (until moving to c++11). */
hash_map<lang_identifier *, tree> *bindings;
};
@@ -2689,26 +2698,23 @@ struct GTY(()) lang_decl {
/* 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))
+ IDENTIFIER_CTOR_P (DECL_NAME (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)
+ (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)
+ (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))
+ (DECL_NAME (NODE) == ctor_identifier)
/* Nonzero if NODE (a FUNCTION_DECL) is a copy constructor. */
#define DECL_COPY_CONSTRUCTOR_P(NODE) \
@@ -2721,32 +2727,28 @@ struct GTY(()) lang_decl {
/* Nonzero if NODE (a FUNCTION_DECL or TEMPLATE_DECL)
is a destructor. */
#define DECL_DESTRUCTOR_P(NODE) \
- DECL_CXX_DESTRUCTOR_P (STRIP_TEMPLATE (NODE))
+ IDENTIFIER_DTOR_P (DECL_NAME (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))
+ (DECL_NAME (NODE) == dtor_identifier)
/* 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)
+ (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)
+ (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)
+ (DECL_NAME (NODE) == deleting_dtor_identifier)
/* Nonzero if NODE (a FUNCTION_DECL) is a cloned constructor or
destructor. */
@@ -2836,9 +2838,7 @@ struct GTY(()) lang_decl {
(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
+ associated with the overloaded 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. */
@@ -2848,7 +2848,7 @@ struct GTY(()) lang_decl {
/* Nonzero if NODE is an assignment operator (including += and such). */
#define DECL_ASSIGNMENT_OPERATOR_P(NODE) \
- (LANG_DECL_FN_CHECK (NODE)->assignment_operator_p)
+ IDENTIFIER_ASSIGN_OP_P (DECL_NAME (NODE))
/* For FUNCTION_DECLs: nonzero means that this function is a
constructor or a destructor with an extra in-charge parameter to
@@ -3514,13 +3514,13 @@ extern void decl_shadowed_for_var_insert (tree, tree);
#define PACK_EXPANSION_PARAMETER_PACKS(NODE) \
*(TREE_CODE (NODE) == EXPR_PACK_EXPANSION \
? &TREE_OPERAND (NODE, 1) \
- : &TYPE_MINVAL (TYPE_PACK_EXPANSION_CHECK (NODE)))
+ : &TYPE_MIN_VALUE_RAW (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) \
+ ? &TYPE_MAX_VALUE_RAW (NODE) \
: &TREE_OPERAND ((NODE), 2))
/* True iff this pack expansion is within a function context. */
@@ -4322,7 +4322,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
/* 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)
+#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)))
@@ -5202,14 +5203,6 @@ extern GTY(()) vec<tree, va_gc> *keyed_classes;
#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"
@@ -6022,10 +6015,7 @@ 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 classtype_has_move_assign_or_move_ctor_p (tree, bool user_declared);
extern bool type_build_ctor_call (tree);
extern bool type_build_dtor_call (tree);
extern void explain_non_literal_class (tree);
@@ -6097,6 +6087,7 @@ 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 build_typename_type (tree, tree, tree, tag_types);
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);
@@ -6340,6 +6331,7 @@ extern void yyungetc (int, int);
extern tree unqualified_name_lookup_error (tree,
location_t = UNKNOWN_LOCATION);
extern tree unqualified_fn_lookup_error (cp_expr);
+extern tree make_conv_op_name (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);
@@ -6581,10 +6573,9 @@ 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_all_conversions (tree);
extern tree lookup_fnfields (tree, tree, int);
extern tree lookup_member (tree, tree, int, bool,
tsubst_flags_t,
@@ -6612,6 +6603,7 @@ extern tree dfs_walk_all (tree, tree (*) (tree, void *),
extern tree dfs_walk_once (tree, tree (*) (tree, void *),
tree (*) (tree, void *), void *);
extern tree binfo_via_virtual (tree, tree);
+extern bool binfo_direct_p (tree);
extern tree build_baselink (tree, tree, tree, tree);
extern tree adjust_result_of_qualified_name_lookup
(tree, tree, tree);
@@ -7194,7 +7186,6 @@ 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, 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);
@@ -7378,6 +7369,12 @@ extern tree cp_ubsan_maybe_instrument_downcast (location_t, tree, tree, tree);
extern tree cp_ubsan_maybe_instrument_cast_to_vbase (location_t, tree, tree);
extern void cp_ubsan_maybe_initialize_vtbl_ptrs (tree);
+#if CHECKING_P
+namespace selftest {
+ extern void run_cp_tests (void);
+} // namespace selftest
+#endif /* #if CHECKING_P */
+
/* Inline bodies. */
inline tree
diff --git a/gcc/cp/cp-ubsan.c b/gcc/cp/cp-ubsan.c
index f00f870bd3e..3be607c0a42 100644
--- a/gcc/cp/cp-ubsan.c
+++ b/gcc/cp/cp-ubsan.c
@@ -36,6 +36,9 @@ cp_ubsan_instrument_vptr_p (tree type)
if (!sanitize_flags_p (SANITIZE_VPTR))
return false;
+ if (current_function_decl == NULL_TREE)
+ return false;
+
if (type)
{
type = TYPE_MAIN_VARIANT (type);
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index 5398e3dd87d..edaee04d7fb 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -88,14 +88,6 @@ pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
/* 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
@@ -162,16 +154,7 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
else if (IDENTIFIER_CONV_OP_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);
- }
+ pp_cxx_tree_identifier (pp, t);
break;
case TEMPLATE_ID_EXPR:
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 0361357a14e..4ec38b82aa9 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3594,7 +3594,7 @@ struct typename_hasher : ggc_ptr_hash<tree_node>
static GTY (()) hash_table<typename_hasher> *typename_htab;
-static tree
+tree
build_typename_type (tree context, tree name, tree fullname,
enum tag_types tag_type)
{
@@ -3955,16 +3955,16 @@ initialize_predefined_identifiers (void)
/* 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, cik_ctor},
- {"__base_ctor ", &base_ctor_identifier, cik_ctor},
- {"__comp_ctor ", &complete_ctor_identifier, cik_ctor},
+ {"__ct_base ", &base_ctor_identifier, cik_ctor},
+ {"__ct_comp ", &complete_ctor_identifier, cik_ctor},
{"__dt ", &dtor_identifier, cik_dtor},
- {"__comp_dtor ", &complete_dtor_identifier, cik_dtor},
- {"__base_dtor ", &base_dtor_identifier, cik_dtor},
- {"__deleting_dtor ", &deleting_dtor_identifier, cik_dtor},
- {IN_CHARGE_NAME, &in_charge_identifier, cik_normal},
- {THIS_NAME, &this_identifier, cik_normal},
- {VTABLE_DELTA_NAME, &delta_identifier, cik_normal},
- {VTABLE_PFN_NAME, &pfn_identifier, cik_normal},
+ {"__dt_base ", &base_dtor_identifier, cik_dtor},
+ {"__dt_comp ", &complete_dtor_identifier, cik_dtor},
+ {"__dt_del ", &deleting_dtor_identifier, cik_dtor},
+ {"__in_chrg", &in_charge_identifier, cik_normal},
+ {"this", &this_identifier, cik_normal},
+ {"__delta", &delta_identifier, cik_normal},
+ {"__pfn", &pfn_identifier, cik_normal},
{"_vptr", &vptr_identifier, cik_normal},
{"__vtt_parm", &vtt_parm_identifier, cik_normal},
{"::", &global_identifier, cik_normal},
@@ -4094,7 +4094,7 @@ cxx_init_decl_processing (void)
vtable_entry_type = build_pointer_type (vfunc_type);
}
- record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
+ record_builtin_type (RID_MAX, "__vtbl_ptr_type", vtable_entry_type);
vtbl_type_node
= build_cplus_array_type (vtable_entry_type, NULL_TREE);
@@ -4549,8 +4549,6 @@ push_throw_library_fn (tree name, tree 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;
@@ -4559,29 +4557,12 @@ fixup_anonymous_aggr (tree t)
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");
- }
+ /* Splice the implicitly generated functions out of TYPE_FIELDS. */
+ for (tree probe, *prev_p = &TYPE_FIELDS (t); (probe = *prev_p);)
+ if (TREE_CODE (probe) == FUNCTION_DECL && DECL_ARTIFICIAL (probe))
+ *prev_p = DECL_CHAIN (probe);
+ else
+ prev_p = &DECL_CHAIN (probe);
/* Anonymous aggregates cannot have fields with ctors, dtors or complex
assignment operators (because they cannot have these methods themselves).
@@ -7486,8 +7467,8 @@ cp_finish_decomp (tree decl, tree first, unsigned int count)
if (init == error_mark_node || eltype == error_mark_node)
{
- inform (dloc, "in initialization of decomposition variable %qD",
- v[i]);
+ inform (dloc, "in initialization of structured binding "
+ "variable %qD", v[i]);
goto error_out;
}
/* Save the decltype away before reference collapse. */
@@ -7849,12 +7830,8 @@ register_dtor_fn (tree decl)
use_dtor = ob_parm && CLASS_TYPE_P (type);
if (use_dtor)
{
- int idx;
+ cleanup = lookup_fnfields_slot (type, complete_dtor_identifier);
- /* 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);
@@ -8502,9 +8479,11 @@ grokfndecl (tree ctype,
/* Allocate space to hold the vptr bit if needed. */
SET_DECL_ALIGN (decl, MINIMUM_METHOD_BOUNDARY);
}
+
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;
@@ -8515,22 +8494,22 @@ grokfndecl (tree ctype,
case sfk_constructor:
case sfk_copy_constructor:
case sfk_move_constructor:
- DECL_CONSTRUCTOR_P (decl) = 1;
+ DECL_CXX_CONSTRUCTOR_P (decl) = 1;
+ DECL_NAME (decl) = ctor_identifier;
break;
case sfk_destructor:
- DECL_DESTRUCTOR_P (decl) = 1;
+ DECL_CXX_DESTRUCTOR_P (decl) = 1;
+ DECL_NAME (decl) = dtor_identifier;
break;
default:
break;
}
- if (friendp
- && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
+ if (friendp && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
{
if (funcdef_flag)
- error
- ("defining explicit specialization %qD in friend declaration",
- orig_declarator);
+ error ("defining explicit specialization %qD in friend declaration",
+ orig_declarator);
else
{
tree fns = TREE_OPERAND (orig_declarator, 0);
@@ -8580,16 +8559,18 @@ grokfndecl (tree 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))))
+ if (ctype == NULL_TREE
+ && DECL_FILE_SCOPE_P (decl)
&& current_lang_name == lang_name_cplusplus
- && ctype == NULL_TREE
- && DECL_FILE_SCOPE_P (decl))
+ && (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))))))
SET_DECL_LANGUAGE (decl, lang_c);
/* Should probably propagate const out from type to decl I bet (mrs). */
@@ -9132,7 +9113,6 @@ build_ptrmemfunc_type (tree type)
this method instead of type_hash_canon, because it only does a
simple equality check on the list of field members. */
-
t = TYPE_PTRMEMFUNC_TYPE (type);
if (t)
return t;
@@ -9502,7 +9482,8 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
stabilize_vla_size (itype);
- if (sanitize_flags_p (SANITIZE_VLA))
+ if (sanitize_flags_p (SANITIZE_VLA)
+ && current_function_decl != NULL_TREE)
{
/* We have to add 1 -- in the ubsan routine we generate
LE_EXPR rather than LT_EXPR. */
@@ -9993,6 +9974,8 @@ grokdeclarator (const cp_declarator *declarator,
declspecs->locations);
if (typespec_loc == UNKNOWN_LOCATION)
typespec_loc = declspecs->locations[ds_type_spec];
+ if (typespec_loc == UNKNOWN_LOCATION)
+ typespec_loc = input_location;
/* Look inside a declarator for the name being declared
and get it as a string, for an error message. */
@@ -10068,8 +10051,6 @@ grokdeclarator (const cp_declarator *declarator,
{
case BIT_NOT_EXPR:
{
- tree type;
-
if (innermost_code != cdk_function)
{
error ("declaration of %qD as non-function", decl);
@@ -10082,7 +10063,7 @@ grokdeclarator (const cp_declarator *declarator,
return error_mark_node;
}
- type = TREE_OPERAND (decl, 0);
+ tree type = TREE_OPERAND (decl, 0);
if (TYPE_P (type))
type = constructor_name (type);
name = identifier_to_locale (IDENTIFIER_POINTER (type));
@@ -10138,7 +10119,7 @@ grokdeclarator (const cp_declarator *declarator,
break;
case cdk_decomp:
- name = "decomposition";
+ name = "structured binding";
break;
case cdk_error:
@@ -10592,43 +10573,43 @@ grokdeclarator (const cp_declarator *declarator,
? declarator->declarator->id_loc : declarator->id_loc);
if (inlinep)
error_at (declspecs->locations[ds_inline],
- "decomposition declaration cannot be declared %<inline%>");
+ "structured binding declaration cannot be %<inline%>");
if (typedef_p)
error_at (declspecs->locations[ds_typedef],
- "decomposition declaration cannot be declared %<typedef%>");
+ "structured binding declaration cannot be %<typedef%>");
if (constexpr_p)
- error_at (declspecs->locations[ds_constexpr], "decomposition "
- "declaration cannot be declared %<constexpr%>");
+ error_at (declspecs->locations[ds_constexpr], "structured "
+ "binding declaration cannot be %<constexpr%>");
if (thread_p)
error_at (declspecs->locations[ds_thread],
- "decomposition declaration cannot be declared %qs",
+ "structured binding declaration cannot be %qs",
declspecs->gnu_thread_keyword_p
? "__thread" : "thread_local");
if (concept_p)
error_at (declspecs->locations[ds_concept],
- "decomposition declaration cannot be declared %<concept%>");
+ "structured binding declaration cannot be %<concept%>");
switch (storage_class)
{
case sc_none:
break;
case sc_register:
- error_at (loc, "decomposition declaration cannot be declared "
+ error_at (loc, "structured binding declaration cannot be "
"%<register%>");
break;
case sc_static:
- error_at (loc, "decomposition declaration cannot be declared "
+ error_at (loc, "structured binding declaration cannot be "
"%<static%>");
break;
case sc_extern:
- error_at (loc, "decomposition declaration cannot be declared "
+ error_at (loc, "structured binding declaration cannot be "
"%<extern%>");
break;
case sc_mutable:
- error_at (loc, "decomposition declaration cannot be declared "
+ error_at (loc, "structured binding declaration cannot be "
"%<mutable%>");
break;
case sc_auto:
- error_at (loc, "decomposition declaration cannot be declared "
+ error_at (loc, "structured binding declaration cannot be "
"C++98 %<auto%>");
break;
default:
@@ -10639,8 +10620,8 @@ grokdeclarator (const cp_declarator *declarator,
{
if (type != error_mark_node)
{
- error_at (loc, "decomposition declaration cannot be declared "
- "with type %qT", type);
+ error_at (loc, "structured binding declaration cannot have "
+ "type %qT", type);
inform (loc,
"type must be cv-qualified %<auto%> or reference to "
"cv-qualified %<auto%>");
@@ -10825,33 +10806,7 @@ grokdeclarator (const cp_declarator *declarator,
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_at (typespec_loc, 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;
- }
-
- /* 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;
- }
+ /* Declaring a function type. */
input_location = declspecs->locations[ds_type_spec];
abstract_virtuals_error (ACU_RETURN, type);
@@ -10959,7 +10914,35 @@ grokdeclarator (const cp_declarator *declarator,
return error_mark_node;
if (late_return_type)
- late_return_type_p = true;
+ {
+ late_return_type_p = true;
+ type_quals = cp_type_quals (type);
+ }
+
+ if (type_quals != TYPE_UNQUALIFIED)
+ {
+ if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type))
+ warning_at (typespec_loc, 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;
+ }
+
+ /* Error about some types functions can't return. */
+
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ error_at (typespec_loc, "%qs declared as function returning "
+ "a function", name);
+ return error_mark_node;
+ }
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ error_at (typespec_loc, "%qs declared as function returning "
+ "an array", name);
+ return error_mark_node;
+ }
if (ctype == NULL_TREE
&& decl_context == FIELD
@@ -12590,9 +12573,11 @@ grokparms (tree parmlist, tree *parms)
}
else if (abstract_virtuals_error (decl, type))
any_error = 1; /* Seems like a good idea. */
- else if (POINTER_TYPE_P (type))
+ else if (cxx_dialect < cxx1z
+ && POINTER_TYPE_P (type))
{
- /* [dcl.fct]/6, parameter types cannot contain pointers
+ /* Before C++17 DR 393:
+ [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);
@@ -12608,12 +12593,13 @@ grokparms (tree parmlist, tree *parms)
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);
+ pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic,
+ 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)
@@ -12925,14 +12911,15 @@ grok_op_properties (tree decl, bool complain)
{
/* It'd be nice to hang something else of the identifier to
find CODE more directly. */
+ bool assign_op = IDENTIFIER_ASSIGN_OP_P (name);
const operator_name_info_t *oni
- = (IDENTIFIER_ASSIGN_OP_P (name)
- ? assignment_operator_name_info : operator_name_info);
- DECL_ASSIGNMENT_OPERATOR_P (decl) = IDENTIFIER_ASSIGN_OP_P (name);
+ = (assign_op ? assignment_operator_name_info : operator_name_info);
+
if (false)
;
#define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, KIND) \
- else if (oni[int (CODE)].identifier == name) \
+ else if (assign_op == (KIND == cik_assign_op) \
+ && oni[int (CODE)].identifier == name) \
operator_code = (CODE);
#include "operators.def"
#undef DEF_OPERATOR
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a4751460e06..2a52f8ca3e2 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -342,7 +342,7 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags)
DECL_CONTEXT (function) = ctype;
if (flags == DTOR_FLAG)
- DECL_DESTRUCTOR_P (function) = 1;
+ DECL_CXX_DESTRUCTOR_P (function) = 1;
if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))
maybe_retrofit_in_chrg (function);
@@ -558,10 +558,6 @@ check_member_template (tree tmpl)
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))
@@ -594,7 +590,7 @@ check_classfn (tree ctype, tree function, tree template_parms)
}
/* OK, is this a definition of a member template? */
- is_template = (template_parms != NULL_TREE);
+ bool is_template = (template_parms != NULL_TREE);
/* [temp.mem]
@@ -608,111 +604,88 @@ check_classfn (tree ctype, tree function, tree template_parms)
/* 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);
-
- for (ovl_iterator iter ((*methods)[ix]); iter; ++iter)
- {
- tree fndecl = *iter;
- tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
- tree 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;
-
- // Include constraints in the match.
- tree c1 = get_constraints (function);
- tree c2 = get_constraints (fndecl);
-
- /* 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)))
- && equivalent_constraints (c1, c2)
- && (DECL_TEMPLATE_SPECIALIZATION (function)
- == DECL_TEMPLATE_SPECIALIZATION (fndecl))
- && (!DECL_TEMPLATE_SPECIALIZATION (function)
- || (DECL_TI_TEMPLATE (function)
- == DECL_TI_TEMPLATE (fndecl))))
- {
- if (pushed_scope)
- pop_scope (pushed_scope);
- return fndecl;
- }
- }
-
- error_at (DECL_SOURCE_LOCATION (function),
- "prototype for %q#D does not match any in class %qT",
- function, ctype);
+ tree pushed_scope = push_scope (ctype);
+ tree matched = NULL_TREE;
+ tree fns = lookup_fnfields_slot (ctype, DECL_NAME (function));
+
+ for (ovl_iterator iter (fns); !matched && iter; ++iter)
+ {
+ tree fndecl = *iter;
+ tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
+ tree 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;
- const char *format = NULL;
- tree first = OVL_FIRST ((*methods)[ix]);
- bool is_conv_op = DECL_CONV_FN_P (first);
- tree prev = NULL_TREE;
+ /* ref-qualifier or absence of same must match. */
+ if (type_memfn_rqual (TREE_TYPE (function))
+ != type_memfn_rqual (TREE_TYPE (fndecl)))
+ continue;
- if (is_conv_op)
- ix = CLASSTYPE_FIRST_CONVERSION_SLOT;
- do
- {
- ovl_iterator iter ((*methods)[ix++]);
- if (is_conv_op && !DECL_CONV_FN_P (*iter))
- break;
- for (; iter; ++iter)
- {
- if (prev)
- {
- if (!format)
- format = N_("candidates are: %+#D");
- error (format, prev);
- format = " %+#D";
- }
- prev = *iter;
- }
- }
- while (is_conv_op && size_t (ix) < methods->length ());
- if (prev)
+ // Include constraints in the match.
+ tree c1 = get_constraints (function);
+ tree c2 = get_constraints (fndecl);
+
+ /* 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)))
+ && equivalent_constraints (c1, c2)
+ && (DECL_TEMPLATE_SPECIALIZATION (function)
+ == DECL_TEMPLATE_SPECIALIZATION (fndecl))
+ && (!DECL_TEMPLATE_SPECIALIZATION (function)
+ || (DECL_TI_TEMPLATE (function) == DECL_TI_TEMPLATE (fndecl))))
+ matched = fndecl;
+ }
+
+ if (!matched)
+ {
+ if (!COMPLETE_TYPE_P (ctype))
+ cxx_incomplete_type_error (function, ctype);
+ else
{
- if (!format)
- format = N_("candidate is: %+#D");
- error (format, prev);
+ if (DECL_CONV_FN_P (function))
+ fns = lookup_all_conversions (ctype);
+
+ error_at (DECL_SOURCE_LOCATION (function),
+ "no declaration matches %q#D", function);
+ if (fns)
+ print_candidates (fns);
+ else if (DECL_CONV_FN_P (function))
+ inform (DECL_SOURCE_LOCATION (function),
+ "no conversion operators declared");
+ else
+ inform (DECL_SOURCE_LOCATION (function),
+ "no functions named %qD", function);
+ inform (DECL_SOURCE_LOCATION (TYPE_NAME (ctype)),
+ "%#qT defined here", ctype);
}
+ matched = error_mark_node;
}
- 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;
+
+ return matched;
}
/* DECL is a function with vague linkage. Remember it so that at the
@@ -1992,12 +1965,14 @@ decl_needed_p (tree decl)
/* 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;
+ return true;
+
/* Virtual functions might be needed for devirtualization. */
if (flag_devirtualize
&& TREE_CODE (decl) == FUNCTION_DECL
&& DECL_VIRTUAL_P (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;
@@ -2617,6 +2592,7 @@ reset_decl_linkage (tree decl)
determine_visibility (decl);
tentative_decl_linkage (decl);
}
+
static void
reset_type_linkage_2 (tree type)
{
@@ -2640,25 +2616,14 @@ reset_type_linkage_2 (tree type)
for (tree m = TYPE_FIELDS (type); m; m = DECL_CHAIN (m))
{
tree mem = STRIP_TEMPLATE (m);
- if (VAR_P (mem))
+ if (TREE_CODE (mem) == VAR_DECL || TREE_CODE (mem) == FUNCTION_DECL)
reset_decl_linkage (mem);
}
- for (tree m = TYPE_METHODS (type); m; m = DECL_CHAIN (m))
- {
- tree mem = STRIP_TEMPLATE (m);
- reset_decl_linkage (mem);
- if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (mem))
- {
- /* Also update its name, for cxx_dwarf_name. */
- DECL_NAME (mem) = TYPE_IDENTIFIER (type);
- if (m != mem)
- DECL_NAME (m) = TYPE_IDENTIFIER (type);
- }
- }
binding_table_foreach (CLASSTYPE_NESTED_UTDS (type),
bt_reset_linkage_2, NULL);
}
}
+
static void
bt_reset_linkage_2 (binding_entry b, void */*data*/)
{
@@ -4803,7 +4768,6 @@ c_parse_final_cleanups (void)
perform_deferred_noexcept_checks ();
finish_repo ();
-
fini_constexpr ();
/* The entire file is now complete. If requested, dump everything
@@ -5030,19 +4994,13 @@ mark_used (tree decl, tsubst_flags_t complain)
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)
+ if (DECL_ARTIFICIAL (decl)
+ && 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");
+ else if (complain & tf_error)
{
error ("use of deleted function %qD", decl);
if (!maybe_explain_implicit_delete (decl))
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 86fa804b317..2497c7f6d23 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -2664,7 +2664,6 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
break;
case TRY_CATCH_EXPR:
- case WITH_CLEANUP_EXPR:
case CLEANUP_POINT_EXPR:
dump_expr (pp, TREE_OPERAND (t, 0), flags);
break;
@@ -3173,10 +3172,6 @@ type_to_string (tree typ, int verbose)
if (len == aka_len && memcmp (p, p+aka_start, len) == 0)
p[len] = '\0';
}
-
- if (typ && TYPE_P (typ) && TREE_CODE (typ) == ENUMERAL_TYPE)
- pp_string (cxx_pp, M_(" {enum}"));
-
return pp_ggc_formatted_text (cxx_pp);
}
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 9e41ec451af..208e52a405b 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -218,7 +218,7 @@ dtor_nothrow (tree type)
if (CLASSTYPE_LAZY_DESTRUCTOR (type))
lazily_declare_fn (sfk_destructor, type);
- return TREE_NOTHROW (CLASSTYPE_DESTRUCTORS (type));
+ return TREE_NOTHROW (CLASSTYPE_DESTRUCTOR (type));
}
/* Build up a call to __cxa_end_catch, to destroy the exception object
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index a3c2ed09472..ef93bfe39ec 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -529,7 +529,7 @@ do_friend (tree ctype, tree declarator, tree decl,
/* A method friend. */
if (flags == NO_SPECIAL && declarator == cname)
- DECL_CONSTRUCTOR_P (decl) = 1;
+ DECL_CXX_CONSTRUCTOR_P (decl) = 1;
grokclassfn (ctype, decl, flags);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 90abd23a267..3fe8f18b2a9 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1718,7 +1718,6 @@ 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
@@ -1846,10 +1845,9 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
}
else
{
- if (true_exp == exp)
- ctor_name = complete_ctor_identifier;
- else
- ctor_name = base_ctor_identifier;
+ tree ctor_name = (true_exp == exp
+ ? complete_ctor_identifier : base_ctor_identifier);
+
rval = build_special_member_call (exp, ctor_name, &parms, binfo, flags,
complain);
}
@@ -3912,7 +3910,8 @@ finish_length_check (tree atype, tree iterator, tree obase, unsigned n)
}
/* Don't check an array new when -fno-exceptions. */
}
- else if (sanitize_flags_p (SANITIZE_BOUNDS))
+ else if (sanitize_flags_p (SANITIZE_BOUNDS)
+ && current_function_decl != NULL_TREE)
{
/* Make sure the last element of the initializer is in bounds. */
finish_expr_stmt
@@ -4582,8 +4581,7 @@ build_delete (tree otype, tree addr, special_function_kind auto_delete,
&& MAYBE_CLASS_TYPE_P (type) && !CLASSTYPE_FINAL (type)
&& TYPE_POLYMORPHIC_P (type))
{
- tree dtor;
- dtor = CLASSTYPE_DESTRUCTORS (type);
+ tree dtor = CLASSTYPE_DESTRUCTOR (type);
if (!dtor || !DECL_VINDEX (dtor))
{
if (CLASSTYPE_PURE_VIRTUALS (type))
@@ -4673,7 +4671,7 @@ build_delete (tree otype, tree addr, special_function_kind auto_delete,
/* 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))
+ else if (!DECL_VIRTUAL_P (CLASSTYPE_DESTRUCTOR (type))
&& auto_delete == sfk_deleting_destructor)
{
/* We will use ADDR multiple times so we must save it. */
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 41d4921c1db..14ff6c2ae43 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -529,7 +529,10 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
else if (id != this_identifier && by_reference_p)
{
if (!lvalue_p (initializer))
- error ("cannot capture %qE by reference", initializer);
+ {
+ error ("cannot capture %qE by reference", initializer);
+ return error_mark_node;
+ }
}
else
{
@@ -1088,7 +1091,7 @@ maybe_add_lambda_conv_op (tree type)
/* First build up the conversion op. */
tree rettype = build_pointer_type (stattype);
- tree name = mangle_conv_op_name_for_type (rettype);
+ tree name = make_conv_op_name (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);
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 2fa26739c80..097fbb547d2 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -531,6 +531,74 @@ unqualified_fn_lookup_error (cp_expr name_expr)
return unqualified_name_lookup_error (name, loc);
}
+struct conv_type_hasher : ggc_ptr_hash<tree_node>
+{
+ static hashval_t hash (tree);
+ static bool equal (tree, tree);
+};
+
+/* 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 (()) hash_table<conv_type_hasher> *conv_type_names;
+
+/* Hash a node (VAL1) in the table. */
+
+hashval_t
+conv_type_hasher::hash (tree val)
+{
+ return (hashval_t) TYPE_UID (TREE_TYPE (val));
+}
+
+/* Compare VAL1 (a node in the table) with VAL2 (a TYPE). */
+
+bool
+conv_type_hasher::equal (tree val1, tree val2)
+{
+ return TREE_TYPE (val1) == val2;
+}
+
+/* Return an identifier for a conversion operator to TYPE. We can
+ get from the returned identifier to the type. */
+
+tree
+make_conv_op_name (tree type)
+{
+ tree *slot;
+ tree identifier;
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ if (conv_type_names == NULL)
+ conv_type_names = hash_table<conv_type_hasher>::create_ggc (31);
+
+ slot = conv_type_names->find_slot_with_hash (type,
+ (hashval_t) TYPE_UID (type),
+ INSERT);
+ identifier = *slot;
+ if (!identifier)
+ {
+ char buffer[64];
+
+ /* Create a unique name corresponding to TYPE. */
+ sprintf (buffer, "operator %lu",
+ (unsigned long) conv_type_names->elements ());
+ 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 the identifier kind so we know later it's a conversion. */
+ set_identifier_kind (identifier, cik_conv_op);
+ }
+
+ return identifier;
+}
+
/* 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(). */
@@ -698,7 +766,7 @@ copy_decl (tree decl MEM_STAT_DECL)
{
tree copy;
- copy = copy_node_stat (decl PASS_MEM_STAT);
+ copy = copy_node (decl PASS_MEM_STAT);
cxx_dup_lang_specific_decl (copy);
return copy;
}
@@ -731,7 +799,7 @@ copy_type (tree type MEM_STAT_DECL)
{
tree copy;
- copy = copy_node_stat (type PASS_MEM_STAT);
+ copy = copy_node (type PASS_MEM_STAT);
copy_lang_type (copy);
return copy;
}
@@ -741,21 +809,21 @@ copy_type (tree type MEM_STAT_DECL)
static bool
maybe_add_lang_type_raw (tree t)
{
- bool add = (RECORD_OR_UNION_CODE_P (TREE_CODE (t))
- || TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM);
- if (add)
- {
- TYPE_LANG_SPECIFIC (t)
- = (struct lang_type *) (ggc_internal_cleared_alloc
- (sizeof (struct lang_type)));
+ if (!(RECORD_OR_UNION_CODE_P (TREE_CODE (t))
+ || TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM))
+ return false;
+
+ TYPE_LANG_SPECIFIC (t)
+ = (struct lang_type *) (ggc_internal_cleared_alloc
+ (sizeof (struct lang_type)));
- if (GATHER_STATISTICS)
- {
- tree_node_counts[(int)lang_type] += 1;
- tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
- }
+ if (GATHER_STATISTICS)
+ {
+ tree_node_counts[(int)lang_type] += 1;
+ tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
}
- return add;
+
+ return true;
}
tree
@@ -799,3 +867,5 @@ in_main_input_context (void)
else
return filename_cmp (main_input_filename, LOCATION_FILE (input_location)) == 0;
}
+
+#include "gt-cp-lex.h"
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index e23591315c9..8bb26a9902b 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1460,11 +1460,6 @@ 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));
}
@@ -4181,75 +4176,6 @@ mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset,
return result;
}
-struct conv_type_hasher : ggc_ptr_hash<tree_node>
-{
- static hashval_t hash (tree);
- static bool equal (tree, tree);
-};
-
-/* 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 (()) hash_table<conv_type_hasher> *conv_type_names;
-
-/* Hash a node (VAL1) in the table. */
-
-hashval_t
-conv_type_hasher::hash (tree val)
-{
- return (hashval_t) TYPE_UID (TREE_TYPE (val));
-}
-
-/* Compare VAL1 (a node in the table) with VAL2 (a TYPE). */
-
-bool
-conv_type_hasher::equal (tree val1, tree val2)
-{
- return TREE_TYPE (val1) == 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)
-{
- tree *slot;
- tree identifier;
-
- if (type == error_mark_node)
- return error_mark_node;
-
- if (conv_type_names == NULL)
- conv_type_names = hash_table<conv_type_hasher>::create_ggc (31);
-
- slot = conv_type_names->find_slot_with_hash (type,
- (hashval_t) TYPE_UID (type),
- INSERT);
- identifier = *slot;
- if (!identifier)
- {
- char buffer[64];
-
- /* Create a unique name corresponding to TYPE. */
- sprintf (buffer, "operator %lu",
- (unsigned long) conv_type_names->elements ());
- 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 the identifier kind so we know later it's a conversion. */
- set_identifier_kind (identifier, cik_conv_op);
- }
-
- return identifier;
-}
-
/* Handle ABI backwards compatibility for past bugs where we didn't call
check_abi_tags in places where it's needed: call check_abi_tags and warn if
it makes a difference. If FOR_DECL is non-null, it's the declaration
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index fe4b2afe7db..8b07f526473 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -137,8 +137,8 @@ make_thunk (tree function, bool this_adjusting,
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_CXX_DESTRUCTOR_P (thunk) = 0;
+ DECL_CXX_CONSTRUCTOR_P (thunk) = 0;
DECL_EXTERNAL (thunk) = 1;
DECL_ARTIFICIAL (thunk) = 1;
/* The THUNK is not a pending inline, even if the FUNCTION is. */
@@ -223,8 +223,8 @@ make_alias_for (tree target, tree newid)
if (TREE_CODE (alias) == FUNCTION_DECL)
{
DECL_SAVED_FUNCTION_DATA (alias) = NULL;
- DECL_DESTRUCTOR_P (alias) = 0;
- DECL_CONSTRUCTOR_P (alias) = 0;
+ DECL_CXX_DESTRUCTOR_P (alias) = 0;
+ DECL_CXX_CONSTRUCTOR_P (alias) = 0;
DECL_PENDING_INLINE_P (alias) = 0;
DECL_DECLARED_INLINE_P (alias) = 0;
DECL_INITIAL (alias) = error_mark_node;
@@ -1342,7 +1342,7 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
if (bad && deleted_p)
*deleted_p = true;
}
- else if (sfk == sfk_constructor)
+ else if (sfk == sfk_constructor || sfk == sfk_inheriting_constructor)
{
bool bad;
@@ -1808,10 +1808,8 @@ maybe_explain_implicit_delete (tree decl)
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)))
+ && (sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
+ && classtype_has_move_assign_or_move_ctor_p (ctype, true))
{
inform (DECL_SOURCE_LOCATION (decl),
"%q#D is implicitly declared as deleted because %qT "
@@ -1968,12 +1966,12 @@ implicitly_declare_fn (special_function_kind kind, tree type,
{
case sfk_destructor:
/* Destructor. */
- name = constructor_name (type);
+ name = dtor_identifier;
break;
case sfk_constructor:
/* Default constructor. */
- name = constructor_name (type);
+ name = ctor_identifier;
break;
case sfk_copy_constructor:
@@ -1982,7 +1980,6 @@ implicitly_declare_fn (special_function_kind kind, tree type,
case sfk_move_assignment:
case sfk_inheriting_constructor:
{
- bool move_p;
if (kind == sfk_copy_assignment
|| kind == sfk_move_assignment)
{
@@ -1990,7 +1987,7 @@ implicitly_declare_fn (special_function_kind kind, tree type,
name = cp_assignment_operator_id (NOP_EXPR);
}
else
- name = constructor_name (type);
+ name = ctor_identifier;
if (kind == sfk_inheriting_constructor)
parameter_types = inherited_parms;
@@ -2000,8 +1997,8 @@ implicitly_declare_fn (special_function_kind kind, tree type,
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);
+ bool 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);
@@ -2054,16 +2051,14 @@ implicitly_declare_fn (special_function_kind kind, tree type,
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;
+
+ if (!IDENTIFIER_CDTOR_P (name))
+ /* Assignment operator. */
+ SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
+ else if (IDENTIFIER_CTOR_P (name))
+ DECL_CXX_CONSTRUCTOR_P (fn) = true;
else
- {
- DECL_ASSIGNMENT_OPERATOR_P (fn) = 1;
- SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
- }
+ DECL_CXX_DESTRUCTOR_P (fn) = true;
SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY);
@@ -2251,8 +2246,10 @@ after_nsdmi_defaulted_late_checks (tree t)
return;
if (t == error_mark_node)
return;
- for (tree fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
- if (!DECL_ARTIFICIAL (fn) && DECL_DEFAULTED_IN_CLASS_P (fn))
+ for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
+ if (!DECL_ARTIFICIAL (fn)
+ && DECL_DECLARES_FUNCTION_P (fn)
+ && DECL_DEFAULTED_IN_CLASS_P (fn))
{
tree fn_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
if (UNEVALUATED_NOEXCEPT_SPEC_P (fn_spec))
@@ -2375,31 +2372,34 @@ lazily_declare_fn (special_function_kind sfk, tree type)
/* [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)))
+ if ((sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
+ && classtype_has_move_assign_or_move_ctor_p (type, true))
DECL_DELETED_FN (fn) = true;
- /* A destructor may be virtual. */
+ /* Destructors and assignment operators 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. */
bool added = add_method (type, fn, false);
gcc_assert (added);
- /* Add it to TYPE_METHODS. */
+
+ /* Add it to TYPE_FIELDS. */
if (sfk == sfk_destructor
&& DECL_VIRTUAL_P (fn))
/* The ABI requires that a virtual destructor go at the end of the
vtable. */
- TYPE_METHODS (type) = chainon (TYPE_METHODS (type), fn);
+ TYPE_FIELDS (type) = chainon (TYPE_FIELDS (type), fn);
else
{
- DECL_CHAIN (fn) = TYPE_METHODS (type);
- TYPE_METHODS (type) = fn;
+ DECL_CHAIN (fn) = TYPE_FIELDS (type);
+ TYPE_FIELDS (type) = fn;
}
+ /* Propagate TYPE_FIELDS. */
+ fixup_type_variants (type);
+
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))
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 0df546a2e6a..4dc19da6ade 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2354,9 +2354,13 @@ do_pushdecl (tree decl, bool is_friend)
; /* Ignore using decls here. */
else if (tree match = duplicate_decls (decl, *iter, is_friend))
{
- if (iter.hidden_p ()
- && match != error_mark_node
- && !DECL_HIDDEN_P (match))
+ if (match == error_mark_node)
+ ;
+ else if (TREE_CODE (match) == TYPE_DECL)
+ /* The IDENTIFIER will have the type referring to the
+ now-smashed TYPE_DECL, because ...? Reset it. */
+ SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (match));
+ else if (iter.hidden_p () && !DECL_HIDDEN_P (match))
{
/* Unhiding a previously hidden decl. */
tree head = iter.reveal_node (old);
@@ -2422,6 +2426,9 @@ do_pushdecl (tree decl, bool is_friend)
{
ns = current_namespace;
slot = find_namespace_slot (ns, name, true);
+ /* Update OLD to reflect the namespace we're going to be
+ pushing into. */
+ old = MAYBE_STAT_DECL (*slot);
}
old = update_binding (level, binding, slot, old, decl, is_friend);
@@ -3183,27 +3190,14 @@ set_identifier_type_value (tree id, tree decl)
}
/* 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. */
+ specified class. */
tree
constructor_name (tree type)
{
- tree name;
- name = constructor_name_full (type);
- if (IDENTIFIER_TEMPLATE (name))
- name = IDENTIFIER_TEMPLATE (name);
- return name;
+ tree decl = TYPE_NAME (TYPE_MAIN_VARIANT (type));
+
+ return decl ? DECL_NAME (decl) : NULL_TREE;
}
/* Returns TRUE if NAME is the name for the constructor for TYPE,
@@ -3212,27 +3206,16 @@ constructor_name (tree 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))
+ if (name && name == constructor_name (type))
return true;
+
return false;
}
@@ -3981,7 +3964,7 @@ push_class_level_binding_1 (tree name, tree 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))
+ && DECL_NAME (x) == DECL_NAME (TYPE_NAME (current_class_type)))
{
tree scope = context_for_name_lookup (x);
if (TYPE_P (scope) && same_type_p (scope, current_class_type))
@@ -4191,8 +4174,7 @@ do_class_using_decl (tree scope, tree name)
return NULL_TREE;
}
}
- else if (name == ctor_identifier
- && BINFO_INHERITANCE_CHAIN (BINFO_INHERITANCE_CHAIN (binfo)))
+ else if (name == ctor_identifier && !binfo_direct_p (binfo))
{
error ("cannot inherit constructors from indirect base %qT", scope);
return NULL_TREE;
@@ -4778,7 +4760,7 @@ suggest_alternatives_for (location_t location, tree name,
/* Subroutine of maybe_suggest_missing_header for handling unrecognized names
for some of the most common names within "std::".
Given non-NULL NAME, a name for lookup within "std::", return the header
- name defining it within the C++ Standard Library (without '<' and '>'),
+ name defining it within the C++ Standard Library (with '<' and '>'),
or NULL. */
static const char *
@@ -4791,61 +4773,61 @@ get_std_name_hint (const char *name)
};
static const std_name_hint hints[] = {
/* <array>. */
- {"array", "array"}, // C++11
+ {"array", "<array>"}, // C++11
/* <deque>. */
- {"deque", "deque"},
+ {"deque", "<deque>"},
/* <forward_list>. */
- {"forward_list", "forward_list"}, // C++11
+ {"forward_list", "<forward_list>"}, // C++11
/* <fstream>. */
- {"basic_filebuf", "fstream"},
- {"basic_ifstream", "fstream"},
- {"basic_ofstream", "fstream"},
- {"basic_fstream", "fstream"},
+ {"basic_filebuf", "<fstream>"},
+ {"basic_ifstream", "<fstream>"},
+ {"basic_ofstream", "<fstream>"},
+ {"basic_fstream", "<fstream>"},
/* <iostream>. */
- {"cin", "iostream"},
- {"cout", "iostream"},
- {"cerr", "iostream"},
- {"clog", "iostream"},
- {"wcin", "iostream"},
- {"wcout", "iostream"},
- {"wclog", "iostream"},
+ {"cin", "<iostream>"},
+ {"cout", "<iostream>"},
+ {"cerr", "<iostream>"},
+ {"clog", "<iostream>"},
+ {"wcin", "<iostream>"},
+ {"wcout", "<iostream>"},
+ {"wclog", "<iostream>"},
/* <list>. */
- {"list", "list"},
+ {"list", "<list>"},
/* <map>. */
- {"map", "map"},
- {"multimap", "map"},
+ {"map", "<map>"},
+ {"multimap", "<map>"},
/* <queue>. */
- {"queue", "queue"},
- {"priority_queue", "queue"},
+ {"queue", "<queue>"},
+ {"priority_queue", "<queue>"},
/* <ostream>. */
- {"ostream", "ostream"},
- {"wostream", "ostream"},
- {"ends", "ostream"},
- {"flush", "ostream"},
- {"endl", "ostream"},
+ {"ostream", "<ostream>"},
+ {"wostream", "<ostream>"},
+ {"ends", "<ostream>"},
+ {"flush", "<ostream>"},
+ {"endl", "<ostream>"},
/* <set>. */
- {"set", "set"},
- {"multiset", "set"},
+ {"set", "<set>"},
+ {"multiset", "<set>"},
/* <sstream>. */
- {"basic_stringbuf", "sstream"},
- {"basic_istringstream", "sstream"},
- {"basic_ostringstream", "sstream"},
- {"basic_stringstream", "sstream"},
+ {"basic_stringbuf", "<sstream>"},
+ {"basic_istringstream", "<sstream>"},
+ {"basic_ostringstream", "<sstream>"},
+ {"basic_stringstream", "<sstream>"},
/* <stack>. */
- {"stack", "stack"},
+ {"stack", "<stack>"},
/* <string>. */
- {"string", "string"},
- {"wstring", "string"},
- {"u16string", "string"},
- {"u32string", "string"},
+ {"string", "<string>"},
+ {"wstring", "<string>"},
+ {"u16string", "<string>"},
+ {"u32string", "<string>"},
/* <unordered_map>. */
- {"unordered_map", "unordered_map"}, // C++11
- {"unordered_multimap", "unordered_map"}, // C++11
+ {"unordered_map", "<unordered_map>"}, // C++11
+ {"unordered_multimap", "<unordered_map>"}, // C++11
/* <unordered_set>. */
- {"unordered_set", "unordered_set"}, // C++11
- {"unordered_multiset", "unordered_set"}, // C++11
+ {"unordered_set", "<unordered_set>"}, // C++11
+ {"unordered_multiset", "<unordered_set>"}, // C++11
/* <vector>. */
- {"vector", "vector"},
+ {"vector", "<vector>"},
};
const size_t num_hints = sizeof (hints) / sizeof (hints[0]);
for (size_t i = 0; i < num_hints; i++)
@@ -4876,10 +4858,14 @@ maybe_suggest_missing_header (location_t location, tree name, tree scope)
const char *name_str = IDENTIFIER_POINTER (name);
const char *header_hint = get_std_name_hint (name_str);
if (header_hint)
- inform (location,
- "%<std::%s%> is defined in header %<<%s>%>;"
- " did you forget to %<#include <%s>%>?",
- name_str, header_hint, header_hint);
+ {
+ gcc_rich_location richloc (location);
+ maybe_add_include_fixit (&richloc, header_hint);
+ inform_at_rich_loc (&richloc,
+ "%<std::%s%> is defined in header %qs;"
+ " did you forget to %<#include %s%>?",
+ name_str, header_hint, header_hint);
+ }
}
/* Look for alternatives for NAME, an IDENTIFIER_NODE for which name
@@ -6059,11 +6045,12 @@ add_using_namespace (vec<tree, va_gc> *&usings, tree target)
/* Tell the debug system of a using directive. */
static void
-emit_debug_info_using_namespace (tree from, tree target)
+emit_debug_info_using_namespace (tree from, tree target, bool implicit)
{
/* Emit debugging info. */
tree context = from != global_namespace ? from : NULL_TREE;
- debug_hooks->imported_module_or_decl (target, NULL_TREE, context, false);
+ debug_hooks->imported_module_or_decl (target, NULL_TREE, context, false,
+ implicit);
}
/* Process a namespace-scope using directive. */
@@ -6078,7 +6065,7 @@ finish_namespace_using_directive (tree target, tree attribs)
add_using_namespace (DECL_NAMESPACE_USING (current_namespace),
ORIGINAL_NAMESPACE (target));
emit_debug_info_using_namespace (current_namespace,
- ORIGINAL_NAMESPACE (target));
+ ORIGINAL_NAMESPACE (target), false);
if (attribs == error_mark_node)
return;
@@ -6237,14 +6224,14 @@ push_namespace (tree name, bool make_inline)
else if (TREE_PUBLIC (current_namespace))
TREE_PUBLIC (ns) = 1;
- if (name == anon_identifier || make_inline)
- emit_debug_info_using_namespace (current_namespace, ns);
-
if (make_inline)
{
DECL_NAMESPACE_INLINE_P (ns) = true;
vec_safe_push (DECL_NAMESPACE_INLINEES (current_namespace), ns);
}
+
+ if (name == anon_identifier || make_inline)
+ emit_debug_info_using_namespace (current_namespace, ns, true);
}
}
@@ -6372,8 +6359,8 @@ cp_emit_debug_info_for_using (tree t, tree context)
if (building_stmt_list_p ())
add_stmt (build_stmt (input_location, USING_STMT, fn));
else
- debug_hooks->imported_module_or_decl (fn,
- NULL_TREE, context, false);
+ debug_hooks->imported_module_or_decl (fn, NULL_TREE, context,
+ false, false);
}
}
}
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index d646ef73803..a1c387092d4 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -326,7 +326,7 @@ maybe_thunk_body (tree fn, bool force)
}
args = XALLOCAVEC (tree, max_parms);
- /* We know that any clones immediately follow FN in TYPE_METHODS. */
+ /* We know that any clones immediately follow FN in TYPE_FIELDS. */
FOR_EACH_CLONE (clone, fn)
{
tree clone_parm;
@@ -447,7 +447,7 @@ maybe_clone_body (tree fn)
if (!tree_versionable_function_p (fn))
need_alias = true;
- /* We know that any clones immediately follow FN in the TYPE_METHODS
+ /* We know that any clones immediately follow FN in the TYPE_FIELDS
list. */
push_to_top_level ();
for (idx = 0; idx < 3; idx++)
@@ -516,7 +516,7 @@ maybe_clone_body (tree fn)
/* Emit the DWARF1 abstract instance. */
(*debug_hooks->deferred_inline_function) (fn);
- /* We know that any clones immediately follow FN in the TYPE_METHODS list. */
+ /* We know that any clones immediately follow FN in the TYPE_FIELDS. */
for (idx = 0; idx < 3; idx++)
{
tree parm;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 634047e5d05..88d0b2b250d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -173,7 +173,7 @@ enum required_token {
RT_AT_THROW, /* @throw */
RT_SELECT, /* selection-statement */
- RT_INTERATION, /* iteration-statement */
+ RT_ITERATION, /* iteration-statement */
RT_JUMP, /* jump-statement */
RT_CLASS_KEY, /* class-key */
RT_CLASS_TYPENAME_TEMPLATE, /* class, typename, or template */
@@ -2039,7 +2039,7 @@ static cp_expr cp_parser_id_expression
static cp_expr cp_parser_unqualified_id
(cp_parser *, bool, bool, bool, bool);
static tree cp_parser_nested_name_specifier_opt
- (cp_parser *, bool, bool, bool, bool);
+ (cp_parser *, bool, bool, bool, bool, bool = false);
static tree cp_parser_nested_name_specifier
(cp_parser *, bool, bool, bool, bool);
static tree cp_parser_qualifying_entity
@@ -2102,7 +2102,7 @@ static void cp_parser_lambda_body
/* Statements [gram.stmt.stmt] */
static void cp_parser_statement
- (cp_parser *, tree, bool, bool *, vec<tree> * = NULL);
+ (cp_parser *, tree, bool, bool *, vec<tree> * = NULL, location_t * = NULL);
static void cp_parser_label_for_labeled_statement
(cp_parser *, tree);
static tree cp_parser_expression_statement
@@ -3253,6 +3253,10 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
error_at (location_of (id),
"%qE in namespace %qE does not name a template type",
id, parser->scope);
+ else if (TREE_CODE (id) == TEMPLATE_ID_EXPR)
+ error_at (location_of (id),
+ "%qE in namespace %qE does not name a template type",
+ TREE_OPERAND (id, 0), parser->scope);
else
error_at (location_of (id),
"%qE in namespace %qE does not name a type",
@@ -3296,6 +3300,10 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
error_at (location_of (id),
"%qE in %q#T does not name a template type",
id, parser->scope);
+ else if (TREE_CODE (id) == TEMPLATE_ID_EXPR)
+ error_at (location_of (id),
+ "%qE in %q#T does not name a template type",
+ TREE_OPERAND (id, 0), parser->scope);
else
error_at (location_of (id),
"%qE in %q#T does not name a type",
@@ -5420,16 +5428,21 @@ cp_parser_id_expression (cp_parser *parser,
/* Look for the optional `::' operator. */
global_scope_p
- = (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false)
- != NULL_TREE);
+ = (!template_keyword_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)
+ declarator_p,
+ template_keyword_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)
@@ -5874,7 +5887,8 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
bool typename_keyword_p,
bool check_dependency_p,
bool type_p,
- bool is_declaration)
+ bool is_declaration,
+ bool template_keyword_p /* = false */)
{
bool success = false;
cp_token_position start = 0;
@@ -5892,7 +5906,6 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
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. */
@@ -5967,8 +5980,6 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
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. */
@@ -6531,7 +6542,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_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);
+ cp_token *close_paren = 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);
@@ -6545,13 +6557,26 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* 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);
+ close_paren
+ = 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))
postfix_expression = error_mark_node;
+
+ /* Construct a location e.g. :
+ typeid (expr)
+ ^~~~~~~~~~~~~
+ ranging from the start of the "typeid" token to the final closing
+ paren, with the caret at the start. */
+ if (close_paren)
+ {
+ location_t typeid_loc
+ = make_location (start_loc, start_loc, close_paren->location);
+ postfix_expression.set_location (typeid_loc);
+ }
}
break;
@@ -8865,7 +8890,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
maybe_add_cast_fixit (&rich_loc, open_paren_loc, close_paren_loc,
expr, type);
warning_at_rich_loc (&rich_loc, OPT_Wold_style_cast,
- "use of old-style cast to %qT", type);
+ "use of old-style cast to %q#T", type);
}
/* Only type conversions to integral or enumeration types
@@ -10637,7 +10662,8 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
static void
cp_parser_statement (cp_parser* parser, tree in_statement_expr,
- bool in_compound, bool *if_p, vec<tree> *chain)
+ bool in_compound, bool *if_p, vec<tree> *chain,
+ location_t *loc_after_labels)
{
tree statement, std_attrs = NULL_TREE;
cp_token *token;
@@ -10830,6 +10856,10 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
if (cp_parser_parse_definitely (parser))
return;
}
+ /* All preceding labels have been parsed at this point. */
+ if (loc_after_labels != NULL)
+ *loc_after_labels = statement_location;
+
/* Look for an expression-statement instead. */
statement = cp_parser_expression_statement (parser, in_statement_expr);
@@ -12031,7 +12061,7 @@ cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep)
token_indent_info guard_tinfo;
/* Peek at the next token. */
- token = cp_parser_require (parser, CPP_KEYWORD, RT_INTERATION);
+ token = cp_parser_require (parser, CPP_KEYWORD, RT_ITERATION);
if (!token)
return error_mark_node;
@@ -12370,6 +12400,7 @@ cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p,
{
tree statement;
location_t body_loc = cp_lexer_peek_token (parser->lexer)->location;
+ location_t body_loc_after_labels = UNKNOWN_LOCATION;
token_indent_info body_tinfo
= get_token_indent_info (cp_lexer_peek_token (parser->lexer));
@@ -12399,7 +12430,8 @@ cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p,
/* Create a compound-statement. */
statement = begin_compound_stmt (0);
/* Parse the dependent-statement. */
- cp_parser_statement (parser, NULL_TREE, false, if_p, chain);
+ cp_parser_statement (parser, NULL_TREE, false, if_p, chain,
+ &body_loc_after_labels);
/* Finish the dummy compound-statement. */
finish_compound_stmt (statement);
}
@@ -12408,6 +12440,11 @@ cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p,
= get_token_indent_info (cp_lexer_peek_token (parser->lexer));
warn_for_misleading_indentation (guard_tinfo, body_tinfo, next_tinfo);
+ if (body_loc_after_labels != UNKNOWN_LOCATION
+ && next_tinfo.type != CPP_SEMICOLON)
+ warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
+ guard_tinfo.location, guard_tinfo.keyword);
+
/* Return the statement. */
return statement;
}
@@ -12426,11 +12463,19 @@ cp_parser_already_scoped_statement (cp_parser* parser, bool *if_p,
{
token_indent_info body_tinfo
= get_token_indent_info (cp_lexer_peek_token (parser->lexer));
+ location_t loc_after_labels = UNKNOWN_LOCATION;
- cp_parser_statement (parser, NULL_TREE, false, if_p);
+ cp_parser_statement (parser, NULL_TREE, false, if_p, NULL,
+ &loc_after_labels);
token_indent_info next_tinfo
= get_token_indent_info (cp_lexer_peek_token (parser->lexer));
warn_for_misleading_indentation (guard_tinfo, body_tinfo, next_tinfo);
+
+ if (loc_after_labels != UNKNOWN_LOCATION
+ && next_tinfo.type != CPP_SEMICOLON)
+ warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
+ guard_tinfo.location,
+ guard_tinfo.keyword);
}
else
{
@@ -13105,7 +13150,7 @@ cp_parser_decomposition_declaration (cp_parser *parser,
}
if (cxx_dialect < cxx1z)
- pedwarn (loc, 0, "decomposition declaration only available with "
+ pedwarn (loc, 0, "structured bindings only available with "
"-std=c++1z or -std=gnu++1z");
tree pushed_scope;
@@ -13154,7 +13199,7 @@ cp_parser_decomposition_declaration (cp_parser *parser,
if (v.is_empty ())
{
- error_at (loc, "empty decomposition declaration");
+ error_at (loc, "empty structured binding declaration");
decl = error_mark_node;
}
@@ -13165,6 +13210,16 @@ cp_parser_decomposition_declaration (cp_parser *parser,
*init_loc = cp_lexer_peek_token (parser->lexer)->location;
tree initializer = cp_parser_initializer (parser, &is_direct_init,
&non_constant_p);
+ if (initializer == NULL_TREE
+ || (TREE_CODE (initializer) == TREE_LIST
+ && TREE_CHAIN (initializer))
+ || (TREE_CODE (initializer) == CONSTRUCTOR
+ && CONSTRUCTOR_NELTS (initializer) != 1))
+ {
+ error_at (loc, "invalid initializer for structured binding "
+ "declaration");
+ initializer = error_mark_node;
+ }
if (decl != error_mark_node)
{
@@ -13327,7 +13382,9 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
case RID_FRIEND:
if (!at_class_scope_p ())
{
- error_at (token->location, "%<friend%> used outside of class");
+ gcc_rich_location richloc (token->location);
+ richloc.add_fixit_remove ();
+ error_at_rich_loc (&richloc, "%<friend%> used outside of class");
cp_lexer_purge_token (parser->lexer);
}
else
@@ -13389,10 +13446,13 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
/* 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__11_compat, "%<auto%>"
- " changes meaning in C++11; please remove it");
+ /* Complain about `auto' as a storage specifier, if
+ we're complaining about C++0x compatibility. */
+ gcc_rich_location richloc (token->location);
+ richloc.add_fixit_remove ();
+ warning_at_rich_loc (&richloc, OPT_Wc__11_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,
@@ -14036,7 +14096,7 @@ cp_parser_conversion_function_id (cp_parser* parser)
/* If the TYPE is invalid, indicate failure. */
if (type == error_mark_node)
return error_mark_node;
- return mangle_conv_op_name_for_type (type);
+ return make_conv_op_name (type);
}
/* Parse a conversion-type-id:
@@ -15502,17 +15562,17 @@ cp_parser_template_id (cp_parser *parser,
/* 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)
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_TEMPLATE_ID)
{
cp_lexer_consume_token (parser->lexer);
- return saved_checks_value (next_token->u.tree_check_value);
+ return saved_checks_value (token->u.tree_check_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
+ if ((token->type != CPP_NAME && token->keyword != RID_OPERATOR)
+ || (token->type == CPP_NAME
&& !cp_parser_nth_token_starts_template_argument_list_p
(parser, 2)))
{
@@ -15603,9 +15663,19 @@ cp_parser_template_id (cp_parser *parser,
arguments = cp_parser_enclosed_template_argument_list (parser);
}
+ /* Set the location to be of the form:
+ template-name < template-argument-list [opt] >
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ with caret == start at the start of the template-name,
+ ranging until the closing '>'. */
+ location_t finish_loc
+ = get_finish (cp_lexer_previous_token (parser->lexer)->location);
+ location_t combined_loc
+ = make_location (token->location, token->location, finish_loc);
+
/* Build a representation of the specialization. */
if (identifier_p (templ))
- template_id = build_min_nt_loc (next_token->location,
+ template_id = build_min_nt_loc (combined_loc,
TEMPLATE_ID_EXPR,
templ, arguments);
else if (DECL_TYPE_TEMPLATE_P (templ)
@@ -15632,7 +15702,7 @@ cp_parser_template_id (cp_parser *parser,
{
template_id = lookup_template_variable (templ, arguments);
if (TREE_CODE (template_id) == TEMPLATE_ID_EXPR)
- SET_EXPR_LOCATION (template_id, next_token->location);
+ SET_EXPR_LOCATION (template_id, combined_loc);
}
else
{
@@ -15644,7 +15714,7 @@ cp_parser_template_id (cp_parser *parser,
template_id = lookup_template_function (templ, arguments);
if (TREE_CODE (template_id) == TEMPLATE_ID_EXPR)
- SET_EXPR_LOCATION (template_id, next_token->location);
+ SET_EXPR_LOCATION (template_id, combined_loc);
}
/* If parsing tentatively, replace the sequence of tokens that makes
@@ -15660,20 +15730,8 @@ cp_parser_template_id (cp_parser *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;
-
- /* Update the location to be of the form:
- template-name < template-argument-list [opt] >
- ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- with caret == start at the start of the template-name,
- ranging until the closing '>'. */
- location_t finish_loc
- = get_finish (cp_lexer_previous_token (parser->lexer)->location);
- location_t combined_loc
- = make_location (token->location, token->location, finish_loc);
token->location = combined_loc;
/* We must mark the lookup as kept, so we don't throw it away on
@@ -15843,15 +15901,19 @@ cp_parser_template_name (cp_parser* parser,
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))))
+ if (template_keyword_p)
{
- /* We're optimizing away the call to cp_parser_lookup_name, but we
- still need to do this. */
- parser->context->object_type = NULL_TREE;
- return identifier;
+ tree scope = (parser->scope ? parser->scope
+ : parser->context->object_type);
+ if (scope && TYPE_P (scope)
+ && (!CLASS_TYPE_P (scope)
+ || (check_dependency_p && dependent_type_p (scope))))
+ {
+ /* We're optimizing away the call to cp_parser_lookup_name, but
+ we still need to do this. */
+ parser->context->object_type = NULL_TREE;
+ return identifier;
+ }
}
}
@@ -18359,13 +18421,14 @@ cp_parser_namespace_definition (cp_parser* parser)
warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace);
/* Look for the `{' to validate starting the namespace. */
- cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
-
- /* Parse the body of the namespace. */
- cp_parser_namespace_body (parser);
+ if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ {
+ /* Parse the body of the namespace. */
+ cp_parser_namespace_body (parser);
- /* Look for the final `}'. */
- cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ /* Look for the final `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ }
if (has_visibility)
pop_visibility (1);
@@ -20068,26 +20131,8 @@ cp_parser_direct_declarator (cp_parser* parser,
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
+
+ if (!class_type || !same_type_p (name_type, class_type))
{
/* We do not attempt to print the declarator
here because we do not have enough
@@ -20097,6 +20142,21 @@ cp_parser_direct_declarator (cp_parser* parser,
declarator = cp_error_declarator;
break;
}
+ else 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;
+ }
+ unqualified_name = constructor_name (class_type);
}
if (class_type)
@@ -20126,14 +20186,10 @@ cp_parser_direct_declarator (cp_parser* parser,
struct S {
friend void N::S();
}; */
- && !(friend_p
- && class_type != qualifying_scope)
+ && (!friend_p || class_type == qualifying_scope)
&& constructor_name_p (unqualified_name,
class_type))
- {
- unqualified_name = constructor_name (class_type);
- sfk = sfk_constructor;
- }
+ sfk = sfk_constructor;
else if (is_overloaded_fn (unqualified_name)
&& DECL_CONSTRUCTOR_P (get_first_fn
(unqualified_name)))
@@ -22564,6 +22620,9 @@ cp_parser_class_head (cp_parser* parser,
/*is_declaration=*/false);
/* If there was a nested-name-specifier, then there *must* be an
identifier. */
+
+ cp_token *bad_template_keyword = NULL;
+
if (nested_name_specifier)
{
type_start_token = cp_lexer_peek_token (parser->lexer);
@@ -22585,6 +22644,8 @@ cp_parser_class_head (cp_parser* parser,
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);
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
+ bad_template_keyword = cp_lexer_consume_token (parser->lexer);
type = cp_parser_class_name (parser,
/*typename_keyword_p=*/false,
/*template_keyword_p=*/false,
@@ -22704,6 +22765,12 @@ cp_parser_class_head (cp_parser* parser,
{
tree scope;
+ if (bad_template_keyword)
+ /* [temp.names]: in a qualified-id formed by a class-head-name, the
+ keyword template shall not appear at the top level. */
+ pedwarn (bad_template_keyword->location, OPT_Wpedantic,
+ "keyword %<template%> not allowed in class-head-name");
+
/* Reject typedef-names in class heads. */
if (!DECL_IMPLICIT_TYPEDEF_P (type))
{
@@ -25659,12 +25726,14 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
/* 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);
+
+ if (tree dtor = CLASSTYPE_DESTRUCTOR (type))
+ return dtor;
+
+ return error_mark_node;
}
/* By this point, the NAME should be an ordinary identifier. If
@@ -28009,7 +28078,7 @@ cp_parser_required_error (cp_parser *parser,
case RT_SELECT:
cp_parser_error (parser, "expected selection-statement");
return;
- case RT_INTERATION:
+ case RT_ITERATION:
cp_parser_error (parser, "expected iteration-statement");
return;
case RT_JUMP:
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 392fba07714..ee4e6b11334 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "type-utils.h"
#include "gimplify.h"
+#include "gcc-rich-location.h"
/* The type of functions taking a tree, and some additional data, and
returning an int. */
@@ -1196,15 +1197,10 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash)
= 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. */
- int 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. */
- vec<tree, va_gc> *methods = CLASSTYPE_METHOD_VEC (class_specialization);
- for (ovl_iterator iter ((*methods)[idx]); iter; ++iter)
+
+ /* Find the instance of TMPL. */
+ tree fns = lookup_fnfields_slot (class_specialization, DECL_NAME (tmpl));
+ for (ovl_iterator iter (fns); iter; ++iter)
{
tree fn = *iter;
if (DECL_TEMPLATE_INFO (fn) && DECL_TI_TEMPLATE (fn) == tmpl
@@ -2876,15 +2872,12 @@ check_explicit_specialization (tree declarator,
/* 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))
+ if (DECL_CONSTRUCTOR_P (decl)
+ ? !TYPE_HAS_USER_CONSTRUCTOR (ctype)
+ : !CLASSTYPE_DESTRUCTOR (ctype))
{
/* From [temp.expl.spec]:
@@ -2898,42 +2891,19 @@ check_explicit_specialization (tree declarator,
return error_mark_node;
}
- name = is_constructor ? ctor_identifier : dtor_identifier;
+ name = DECL_NAME (decl);
}
- if (!DECL_CONV_FN_P (decl))
- {
- idx = lookup_fnfields_1 (ctype, name);
- if (idx >= 0)
- fns = (*CLASSTYPE_METHOD_VEC (ctype))[idx];
- }
+ tree fns = NULL_TREE;
+ if (DECL_CONV_FN_P (decl))
+ /* 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'.
+ Grab all the conversion operators, and then select from
+ them. */
+ fns = lookup_all_conversions (ctype);
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_FIRST (ovl)))
- /* There are no more conversion functions. */
- break;
-
- /* Glue all these conversion functions together
- with those we already have. */
- fns = lookup_add (ovl, fns);
- }
- }
+ fns = lookup_fnfields_slot_nolazy (ctype, name);
if (fns == NULL_TREE)
{
@@ -7170,26 +7140,68 @@ unify_bound_ttp_args (tree tparms, tree targs, tree parm, tree& arg,
parmvec = expand_template_argument_pack (parmvec);
argvec = expand_template_argument_pack (argvec);
- tree nparmvec = parmvec;
if (flag_new_ttp)
{
/* In keeping with P0522R0, adjust P's template arguments
to apply to A's template; then flatten it again. */
+ tree nparmvec = parmvec;
nparmvec = coerce_ttp_args_for_tta (arg, parmvec, tf_none);
nparmvec = expand_template_argument_pack (nparmvec);
- }
- if (unify (tparms, targs, nparmvec, argvec,
- UNIFY_ALLOW_NONE, explain_p))
- return 1;
+ if (unify (tparms, targs, nparmvec, argvec,
+ UNIFY_ALLOW_NONE, explain_p))
+ return 1;
- /* If the P0522 adjustment eliminated a pack expansion, deduce
- empty packs. */
- if (flag_new_ttp
- && TREE_VEC_LENGTH (nparmvec) < TREE_VEC_LENGTH (parmvec)
- && unify_pack_expansion (tparms, targs, parmvec, argvec,
- DEDUCE_EXACT, /*sub*/true, explain_p))
- return 1;
+ /* If the P0522 adjustment eliminated a pack expansion, deduce
+ empty packs. */
+ if (flag_new_ttp
+ && TREE_VEC_LENGTH (nparmvec) < TREE_VEC_LENGTH (parmvec)
+ && unify_pack_expansion (tparms, targs, parmvec, argvec,
+ DEDUCE_EXACT, /*sub*/true, explain_p))
+ return 1;
+ }
+ else
+ {
+ /* 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, which is allowed under N2555. */
+
+ int len = TREE_VEC_LENGTH (parmvec);
+
+ /* Check if the parameters end in a pack, making them
+ variadic. */
+ int parm_variadic_p = 0;
+ if (len > 0
+ && PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, len - 1)))
+ parm_variadic_p = 1;
+
+ for (int 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 (int i = 0; i < len - parm_variadic_p; ++i)
+ if (unify (tparms, targs,
+ TREE_VEC_ELT (parmvec, i),
+ TREE_VEC_ELT (argvec, i),
+ UNIFY_ALLOW_NONE, explain_p))
+ return 1;
+
+ if (parm_variadic_p
+ && unify_pack_expansion (tparms, targs,
+ parmvec, argvec,
+ DEDUCE_EXACT,
+ /*subr=*/true, explain_p))
+ return 1;
+ }
return 0;
}
@@ -7653,7 +7665,7 @@ convert_template_argument (tree parm,
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);
+ val = orig_arg;
else
{
tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
@@ -10539,7 +10551,6 @@ instantiate_class_template_1 (tree type)
}
else if (DECL_DECLARES_FUNCTION_P (t))
{
- /* Build new TYPE_METHODS. */
tree r;
if (TREE_CODE (t) == TEMPLATE_DECL)
@@ -12235,22 +12246,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
case FUNCTION_DECL:
{
- tree ctx;
- tree argvec = NULL_TREE;
- tree *friends;
- tree gen_tmpl;
- tree type;
- int member;
- int args_depth;
- int parms_depth;
+ tree gen_tmpl, argvec;
/* 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;
-
/* If T is not dependent, just return it. */
if (!uses_template_parms (DECL_TI_ARGS (t)))
RETURN (t);
@@ -12268,9 +12270,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
/* 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)
+ if (tree spec = retrieve_specialization (gen_tmpl, argvec, hash))
{
r = spec;
break;
@@ -12308,11 +12308,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
which we can spot because the pattern will be a
specialization in this case. */
- args_depth = TMPL_ARGS_DEPTH (args);
- parms_depth =
+ int args_depth = TMPL_ARGS_DEPTH (args);
+ int parms_depth =
TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (t)));
- if (args_depth > parms_depth
- && !DECL_TEMPLATE_SPECIALIZATION (t))
+
+ if (args_depth > parms_depth && !DECL_TEMPLATE_SPECIALIZATION (t))
args = get_innermost_template_args (args, parms_depth);
}
else
@@ -12329,23 +12329,18 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
new decl (R) with appropriate types so that we can call
determine_specialization. */
gen_tmpl = NULL_TREE;
+ argvec = 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|tf_fndecl_type, in_decl);
+ tree ctx = DECL_CONTEXT (t);
+ bool member = ctx && TYPE_P (ctx);
+
+ if (member)
+ ctx = tsubst_aggr_type (ctx, args,
+ complain, t, /*entering_scope=*/1);
+
+ tree type = tsubst (TREE_TYPE (t), args,
+ complain | tf_fndecl_type, in_decl);
if (type == error_mark_node)
RETURN (error_mark_node);
@@ -12390,7 +12385,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
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_NAME (r) = make_conv_op_name (TREE_TYPE (type));
DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args,
complain, t);
@@ -12465,14 +12460,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
DECL_TEMPLATE_INFO (r) = NULL_TREE;
/* Copy the list of befriending classes. */
- for (friends = &DECL_BEFRIENDING_CLASSES (r);
+ for (tree *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);
+ TREE_VALUE (*friends)
+ = tsubst (TREE_VALUE (*friends), args, complain, in_decl);
}
if (DECL_CONSTRUCTOR_P (r) || DECL_DESTRUCTOR_P (r))
@@ -14248,7 +14242,7 @@ tsubst_baselink (tree baselink, tree object_type,
tree name = OVL_NAME (fns);
if (IDENTIFIER_CONV_OP_P (name))
- name = mangle_conv_op_name_for_type (optype);
+ name = make_conv_op_name (optype);
baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
if (!baselink)
@@ -15038,7 +15032,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (IDENTIFIER_CONV_OP_P (t))
{
tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
- return mangle_conv_op_name_for_type (new_type);
+ return make_conv_op_name (new_type);
}
else
return t;
@@ -15111,6 +15105,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return tsubst_binary_left_fold (t, args, complain, in_decl);
case BINARY_RIGHT_FOLD_EXPR:
return tsubst_binary_right_fold (t, args, complain, in_decl);
+ case PREDICT_EXPR:
+ return t;
default:
/* We shouldn't get here, but keep going if !flag_checking. */
@@ -16142,13 +16138,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
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=*/false,
+ for (tree fld = TYPE_FIELDS (tmp); fld; fld = DECL_CHAIN (fld))
+ if ((VAR_P (fld)
+ || (TREE_CODE (fld) == FUNCTION_DECL
+ && !DECL_ARTIFICIAL (fld)))
+ && DECL_TEMPLATE_INSTANTIATION (fld))
+ instantiate_decl (fld, /*defer_ok=*/false,
/*expl_inst_class=*/false);
}
break;
@@ -16671,7 +16669,7 @@ tsubst_copy_and_build (tree t,
if (IDENTIFIER_CONV_OP_P (t))
{
tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
- t = mangle_conv_op_name_for_type (new_type);
+ t = make_conv_op_name (new_type);
}
/* Look up the name. */
@@ -20019,6 +20017,9 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
tree pack, packs = NULL_TREE;
int i, start = TREE_VEC_LENGTH (packed_parms) - 1;
+ /* Add in any args remembered from an earlier partial instantiation. */
+ targs = add_to_template_args (PACK_EXPANSION_EXTRA_ARGS (parm), targs);
+
packed_args = expand_template_argument_pack (packed_args);
int len = TREE_VEC_LENGTH (packed_args);
@@ -22135,18 +22136,6 @@ bt_instantiate_type_proc (binding_entry entry, void *data)
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=*/true,
- /*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,
@@ -22256,12 +22245,9 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
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:
+ /* In contrast to implicit instantiation, where only the
+ declarations, and not the definitions, of members are
+ instantiated, we have here:
[temp.explicit]
@@ -22270,27 +22256,28 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
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)
- && user_provided_p (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);
- }
+ 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. */
+ for (tree fld = TYPE_FIELDS (t); fld; fld = DECL_CHAIN (fld))
+ if ((VAR_P (fld)
+ || (TREE_CODE (fld) == FUNCTION_DECL
+ && !static_p
+ && user_provided_p (fld)))
+ && DECL_TEMPLATE_INSTANTIATION (fld))
+ {
+ mark_decl_instantiated (fld, extern_p);
+ if (! extern_p)
+ instantiate_decl (fld, /*defer_ok=*/true,
+ /*expl_inst_class_mem_p=*/true);
+ }
+
+ 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
@@ -22529,8 +22516,20 @@ maybe_instantiate_noexcept (tree fn)
if (TREE_CODE (noex) == DEFERRED_NOEXCEPT)
{
+ static hash_set<tree>* fns = new hash_set<tree>;
+ bool added = false;
if (DEFERRED_NOEXCEPT_PATTERN (noex) == NULL_TREE)
spec = get_defaulted_eh_spec (fn);
+ else if (!(added = !fns->add (fn)))
+ {
+ /* If hash_set::add returns true, the element was already there. */
+ location_t loc = EXPR_LOC_OR_LOC (DEFERRED_NOEXCEPT_PATTERN (noex),
+ DECL_SOURCE_LOCATION (fn));
+ error_at (loc,
+ "exception specification of %qD depends on itself",
+ fn);
+ spec = noexcept_false_spec;
+ }
else if (push_tinst_level (fn))
{
push_access_scope (fn);
@@ -22551,6 +22550,9 @@ maybe_instantiate_noexcept (tree fn)
else
spec = noexcept_false_spec;
+ if (added)
+ fns->remove (fn);
+
TREE_TYPE (fn) = build_exception_variant (fntype, spec);
}
@@ -23067,19 +23069,20 @@ instantiate_pending_templates (int retries)
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,
+ for (tree fld = TYPE_FIELDS (instantiation);
+ fld; fld = TREE_CHAIN (fld))
+ if ((VAR_P (fld)
+ || (TREE_CODE (fld) == FUNCTION_DECL
+ && !DECL_ARTIFICIAL (fld)))
+ && DECL_TEMPLATE_INSTANTIATION (fld))
+ instantiate_decl (fld,
/*defer_ok=*/false,
/*expl_inst_class_mem_p=*/false);
+
if (COMPLETE_TYPE_P (instantiation))
reconsider = 1;
}
@@ -24599,26 +24602,38 @@ resolve_typename_type (tree type, bool only_current_p)
/* 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. */
+ tree fullname = TYPENAME_TYPE_FULLNAME (type);
if (!decl)
/*nop*/;
- else if (identifier_p (TYPENAME_TYPE_FULLNAME (type))
+ else if (identifier_p (fullname)
&& 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
+ else if (TREE_CODE (fullname) == 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);
+ tree tmpl = TREE_OPERAND (fullname, 0);
+ if (TREE_CODE (tmpl) == IDENTIFIER_NODE)
+ {
+ /* We get here with a plain identifier because a previous tentative
+ parse of the nested-name-specifier as part of a ptr-operator saw
+ ::template X<A>. The use of ::template is necessary in a
+ ptr-operator, but wrong in a declarator-id.
+
+ [temp.names]: In a qualified-id of a declarator-id, the keyword
+ template shall not appear at the top level. */
+ pedwarn (EXPR_LOC_OR_LOC (fullname, input_location), OPT_Wpedantic,
+ "keyword %<template%> not allowed in declarator-id");
+ tmpl = decl;
+ }
+ tree args = TREE_OPERAND (fullname, 1);
/* Instantiate the template. */
result = lookup_template_class (tmpl, args, NULL_TREE, NULL_TREE,
- /*entering_scope=*/0,
+ /*entering_scope=*/true,
tf_error | tf_user);
if (result == error_mark_node)
result = NULL_TREE;
@@ -24843,8 +24858,12 @@ listify (tree arg)
if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
{
- error ("deducing from brace-enclosed initializer list requires "
- "#include <initializer_list>");
+ gcc_rich_location richloc (input_location);
+ maybe_add_include_fixit (&richloc, "<initializer_list>");
+ error_at_rich_loc (&richloc,
+ "deducing from brace-enclosed initializer list"
+ " requires #include <initializer_list>");
+
return error_mark_node;
}
tree argvec = make_tree_vec (1);
@@ -25161,17 +25180,16 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain)
}
else
{
+ ++processing_template_decl;
+
+ tree fn_tmpl
+ = (TREE_CODE (ctor) == TEMPLATE_DECL ? ctor
+ : DECL_TI_TEMPLATE (ctor));
if (outer_args)
- ctor = tsubst (ctor, outer_args, complain, ctor);
+ fn_tmpl = tsubst (fn_tmpl, outer_args, complain, ctor);
+ ctor = DECL_TEMPLATE_RESULT (fn_tmpl);
+
type = DECL_CONTEXT (ctor);
- tree fn_tmpl;
- if (TREE_CODE (ctor) == TEMPLATE_DECL)
- {
- fn_tmpl = ctor;
- ctor = DECL_TEMPLATE_RESULT (fn_tmpl);
- }
- else
- fn_tmpl = DECL_TI_TEMPLATE (ctor);
tparms = DECL_TEMPLATE_PARMS (fn_tmpl);
/* If type is a member class template, DECL_TI_ARGS (ctor) will have
@@ -25193,7 +25211,6 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain)
/* For a member template constructor, we need to flatten the two
template parameter lists into one, and then adjust the function
signature accordingly. This gets...complicated. */
- ++processing_template_decl;
tree save_parms = current_template_parms;
/* For a member template we should have two levels of parms/args, one
@@ -25254,8 +25271,8 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain)
ci = tsubst_constraint_info (ci, tsubst_args, complain, ctor);
current_template_parms = save_parms;
- --processing_template_decl;
}
+ --processing_template_decl;
}
if (!memtmpl)
@@ -25307,14 +25324,38 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
tree type = TREE_TYPE (tmpl);
+ bool try_list_ctor = false;
+
vec<tree,va_gc> *args;
if (init == NULL_TREE
|| TREE_CODE (init) == TREE_LIST)
args = make_tree_vector_from_list (init);
- else if (BRACE_ENCLOSED_INITIALIZER_P (init)
- && !TYPE_HAS_LIST_CTOR (type)
- && !is_std_init_list (type))
- args = make_tree_vector_from_ctor (init);
+ else if (BRACE_ENCLOSED_INITIALIZER_P (init))
+ {
+ try_list_ctor = TYPE_HAS_LIST_CTOR (type);
+ if (try_list_ctor && CONSTRUCTOR_NELTS (init) == 1)
+ {
+ /* As an exception, the first phase in 16.3.1.7 (considering the
+ initializer list as a single argument) is omitted if the
+ initializer list consists of a single expression of type cv U,
+ where U is a specialization of C or a class derived from a
+ specialization of C. */
+ tree elt = CONSTRUCTOR_ELT (init, 0)->value;
+ tree etype = TREE_TYPE (elt);
+
+ tree tparms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
+ tree targs = make_tree_vec (TREE_VEC_LENGTH (tparms));
+ int err = unify (tparms, targs, type, etype,
+ UNIFY_ALLOW_DERIVED, /*explain*/false);
+ if (err == 0)
+ try_list_ctor = false;
+ ggc_free (targs);
+ }
+ if (try_list_ctor || is_std_init_list (type))
+ args = make_tree_vector_single (init);
+ else
+ args = make_tree_vector_from_ctor (init);
+ }
else
args = make_tree_vector_single (init);
@@ -25369,13 +25410,43 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
saw_ctor = true;
}
- if (args->length () < 2)
+ tree call = error_mark_node;
+
+ /* If this is list-initialization and the class has a list constructor, first
+ try deducing from the list as a single argument, as [over.match.list]. */
+ tree list_cands = NULL_TREE;
+ if (try_list_ctor && cands)
+ for (lkp_iterator iter (cands); iter; ++iter)
+ {
+ tree dg = *iter;
+ if (is_list_ctor (dg))
+ list_cands = lookup_add (dg, list_cands);
+ }
+ if (list_cands)
+ {
+ ++cp_unevaluated_operand;
+ call = build_new_function_call (list_cands, &args, tf_decltype);
+ --cp_unevaluated_operand;
+
+ if (call == error_mark_node)
+ {
+ /* That didn't work, now try treating the list as a sequence of
+ arguments. */
+ release_tree_vector (args);
+ args = make_tree_vector_from_ctor (init);
+ }
+ }
+
+ /* Maybe generate an implicit deduction guide. */
+ if (call == error_mark_node && args->length () < 2)
{
tree gtype = NULL_TREE;
if (args->length () == 1)
+ /* Generate a copy guide. */
gtype = build_reference_type (type);
else if (!saw_ctor)
+ /* Generate a default guide. */
gtype = type;
if (gtype)
@@ -25397,22 +25468,29 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
return error_mark_node;
}
- ++cp_unevaluated_operand;
- tree t = build_new_function_call (cands, &args, tf_decltype);
+ if (call == error_mark_node)
+ {
+ ++cp_unevaluated_operand;
+ call = build_new_function_call (cands, &args, tf_decltype);
+ --cp_unevaluated_operand;
+ }
- if (t == error_mark_node && (complain & tf_warning_or_error))
+ if (call == error_mark_node && (complain & tf_warning_or_error))
{
error ("class template argument deduction failed:");
- t = build_new_function_call (cands, &args, complain | tf_decltype);
+
+ ++cp_unevaluated_operand;
+ call = build_new_function_call (cands, &args, complain | tf_decltype);
+ --cp_unevaluated_operand;
+
if (elided)
inform (input_location, "explicit deduction guides not considered "
"for copy-initialization");
}
- --cp_unevaluated_operand;
release_tree_vector (args);
- return cp_build_qualified_type (TREE_TYPE (t), cp_type_quals (ptype));
+ return cp_build_qualified_type (TREE_TYPE (call), cp_type_quals (ptype));
}
/* Replace occurrences of 'auto' in TYPE with the appropriate type deduced
diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c
index 7b69dbe2b89..d377efc8cc5 100644
--- a/gcc/cp/ptree.c
+++ b/gcc/cp/ptree.c
@@ -181,7 +181,6 @@ cxx_print_identifier (FILE *file, tree node, int indent)
fprintf (file, "%s local bindings <%p>", get_identifier_kind_name (node),
(void *) IDENTIFIER_BINDING (node));
print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
- print_node (file, "template", IDENTIFIER_TEMPLATE (node), indent + 4);
}
void
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index ff72ce538b2..a660cdd9413 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "stor-layout.h"
#include "c-family/c-pragma.h"
+#include "gcc-rich-location.h"
/* C++ returns type information to the user in struct type_info
objects. We also use type information to implement dynamic_cast and
@@ -316,7 +317,12 @@ typeid_ok_p (void)
if (!COMPLETE_TYPE_P (const_type_info_type_node))
{
- error ("must %<#include <typeinfo>%> before using %<typeid%>");
+ gcc_rich_location richloc (input_location);
+ maybe_add_include_fixit (&richloc, "<typeinfo>");
+ error_at_rich_loc (&richloc,
+ "must %<#include <typeinfo>%> before using"
+ " %<typeid%>");
+
return false;
}
@@ -1556,7 +1562,7 @@ emit_support_tinfos (void)
bltn_type = TREE_TYPE (bltn_type);
if (!COMPLETE_TYPE_P (bltn_type))
return;
- tree dtor = CLASSTYPE_DESTRUCTORS (bltn_type);
+ tree dtor = CLASSTYPE_DESTRUCTOR (bltn_type);
if (!dtor || DECL_EXTERNAL (dtor))
return;
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 00f895c5d7d..469a88b4c6f 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -444,6 +444,10 @@ lookup_field_1 (tree type, tree name, bool want_type)
{
tree decl = field;
+ if (DECL_DECLARES_FUNCTION_P (decl))
+ /* Functions are kep separately, at the moment. */
+ continue;
+
if (GATHER_STATISTICS)
n_fields_searched++;
@@ -507,10 +511,13 @@ current_scope (void)
&& 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;
}
@@ -1523,86 +1530,67 @@ lookup_fnfields (tree xbasetype, tree name, int protect)
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. */
+/* Return the conversion operators in CLASS_TYPE corresponding to
+ "operator TYPE ()". Only CLASS_TYPE itself is searched; this
+ routine does not scan the base classes of CLASS_TYPE. */
-static int
+static tree
lookup_conversion_operator (tree class_type, tree type)
{
- int tpl_slot = -1;
+ tree tpls = NULL_TREE;
if (TYPE_HAS_CONVERSION (class_type))
{
- int i;
- tree fn;
+ tree fns;
vec<tree, va_gc> *methods = CLASSTYPE_METHOD_VEC (class_type);
- for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
- vec_safe_iterate (methods, i, &fn); ++i)
+ for (int i = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ vec_safe_iterate (methods, i, &fns); ++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_FIRST (fn);
+ tree fn = OVL_FIRST (fns);
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;
+ tpls = fns;
else if (same_type_p (DECL_CONV_FN_TYPE (fn), type))
- return i;
+ return fns;
}
}
- return tpl_slot;
+ return tpls;
}
-/* 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. */
+/* TYPE is a class type. Return the member functions in the method
+ vector with name NAME. Does not lazily declare implicitly-declared
+ member functions. */
-static int
-lookup_fnfields_idx_nolazy (tree type, tree name)
+tree
+lookup_fnfields_slot_nolazy (tree type, tree name)
{
- vec<tree, va_gc> *method_vec;
- tree fn;
- size_t i;
-
- if (!CLASS_TYPE_P (type))
- return -1;
-
- method_vec = CLASSTYPE_METHOD_VEC (type);
+ vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (type);
if (!method_vec)
- return -1;
+ return NULL_TREE;
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_CONV_OP_P (name))
return lookup_conversion_operator (type, TREE_TYPE (name));
/* Skip the conversion operators. */
+ int i;
+ tree fns;
for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
- vec_safe_iterate (method_vec, i, &fn);
+ vec_safe_iterate (method_vec, i, &fns);
++i)
- if (!DECL_CONV_FN_P (OVL_FIRST (fn)))
+ if (!DECL_CONV_FN_P (OVL_FIRST (fns)))
break;
/* If the type is complete, use binary search. */
@@ -1620,42 +1608,39 @@ lookup_fnfields_idx_nolazy (tree type, tree name)
if (GATHER_STATISTICS)
n_outer_fields_searched++;
- tree tmp = (*method_vec)[i];
- tmp = OVL_NAME (tmp);
- if (tmp > name)
+ fns = (*method_vec)[i];
+ tree fn_name = OVL_NAME (fns);
+ if (fn_name > name)
hi = i;
- else if (tmp < name)
+ else if (fn_name < name)
lo = i + 1;
else
- return i;
+ return fns;
}
}
else
- for (; vec_safe_iterate (method_vec, i, &fn); ++i)
+ for (; vec_safe_iterate (method_vec, i, &fns); ++i)
{
if (GATHER_STATISTICS)
n_outer_fields_searched++;
- if (OVL_NAME (fn) == name)
- return i;
+ if (OVL_NAME (fns) == name)
+ return fns;
}
- return -1;
+ return NULL_TREE;
}
-/* 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. */
+/* TYPE is a class type. Return the overloads in
+ the method vector with name NAME. Lazily create ctors etc. */
-int
-lookup_fnfields_1 (tree type, tree name)
+tree
+lookup_fnfields_slot (tree type, tree name)
{
- if (!CLASS_TYPE_P (type))
- return -1;
+ type = complete_type (type);
if (COMPLETE_TYPE_P (type))
{
- if ((name == ctor_identifier
- || name == base_ctor_identifier
- || name == complete_ctor_identifier))
+ if (IDENTIFIER_CTOR_P (name))
{
if (CLASSTYPE_LAZY_DEFAULT_CTOR (type))
lazily_declare_fn (sfk_constructor, type);
@@ -1671,55 +1656,40 @@ lookup_fnfields_1 (tree type, tree name)
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);
+ else if (IDENTIFIER_DTOR_P (name))
+ {
+ if (CLASSTYPE_LAZY_DESTRUCTOR (type))
+ lazily_declare_fn (sfk_destructor, type);
+ }
}
- return lookup_fnfields_idx_nolazy (type, name);
+ return lookup_fnfields_slot_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. */
+/* Collect all the conversion operators of KLASS. */
tree
-lookup_fnfields_slot (tree type, tree name)
+lookup_all_conversions (tree klass)
{
- int ix = lookup_fnfields_1 (complete_type (type), name);
- if (ix < 0)
- return NULL_TREE;
- return (*CLASSTYPE_METHOD_VEC (type))[ix];
-}
+ tree lkp = NULL_TREE;
-/* 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. */
+ if (vec<tree, va_gc> *methods = CLASSTYPE_METHOD_VEC (klass))
+ {
+ tree ovl;
+ for (int idx = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ methods->iterate (idx, &ovl); ++idx)
+ {
+ if (!DECL_CONV_FN_P (OVL_FIRST (ovl)))
+ /* There are no more conversion functions. */
+ break;
-int
-class_method_index_for_fn (tree class_type, tree function)
-{
- gcc_assert (DECL_DECLARES_FUNCTION_P (function));
+ lkp = lookup_add (ovl, lkp);
+ }
+ }
- return lookup_fnfields_1 (class_type,
- DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
- DECL_DESTRUCTOR_P (function) ? dtor_identifier :
- DECL_NAME (function));
+ return lkp;
}
-
/* 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.
@@ -2415,37 +2385,26 @@ look_for_overrides (tree type, tree fndecl)
tree
look_for_overrides_here (tree type, tree fndecl)
{
- int ix;
+ tree ovl = lookup_fnfields_slot (type, DECL_NAME (fndecl));
- /* 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)
- for (ovl_iterator iter ((*CLASSTYPE_METHOD_VEC (type))[ix]); iter; ++iter)
- {
- tree fn = *iter;
+ for (ovl_iterator iter (ovl); iter; ++iter)
+ {
+ tree fn = *iter;
- 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;
- }
+ 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;
}
@@ -2976,6 +2935,28 @@ binfo_via_virtual (tree binfo, tree limit)
return NULL_TREE;
}
+/* BINFO is for a base class in some hierarchy. Return true iff it is a
+ direct base. */
+
+bool
+binfo_direct_p (tree binfo)
+{
+ tree d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
+ if (BINFO_INHERITANCE_CHAIN (d_binfo))
+ /* A second inheritance chain means indirect. */
+ return false;
+ if (!BINFO_VIRTUAL_P (binfo))
+ /* Non-virtual, so only one inheritance chain means direct. */
+ return true;
+ /* A virtual base looks like a direct base, so we need to look through the
+ direct bases to see if it's there. */
+ tree b_binfo;
+ for (int i = 0; BINFO_BASE_ITERATE (d_binfo, i, b_binfo); ++i)
+ if (b_binfo == binfo)
+ return true;
+ return false;
+}
+
/* 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. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 9589b47dd64..f56d00fd8f3 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "omp-general.h"
#include "convert.h"
#include "gomp-constants.h"
+#include "predict.h"
/* There routines provide a modular interface to perform many parsing
operations. They may therefore be used during actual parsing, or
@@ -630,6 +631,7 @@ finish_goto_stmt (tree destination)
check_goto (destination);
+ add_stmt (build_predict_expr (PRED_GOTO, NOT_TAKEN));
return add_stmt (build_stmt (input_location, GOTO_EXPR, destination));
}
@@ -3037,9 +3039,9 @@ finish_member_declaration (tree decl)
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. */
+ /* Put the decl on the TYPE_FIELDS list. Note that this is built up
+ in reverse order. We reverse it (to obtain declaration order) in
+ finish_struct. */
if (DECL_DECLARES_FUNCTION_P (decl))
{
/* We also need to add this function to the
@@ -3047,8 +3049,8 @@ finish_member_declaration (tree decl)
if (add_method (current_class_type, decl, false))
{
gcc_assert (TYPE_MAIN_VARIANT (current_class_type) == current_class_type);
- DECL_CHAIN (decl) = TYPE_METHODS (current_class_type);
- TYPE_METHODS (current_class_type) = decl;
+ 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);
@@ -5794,7 +5796,7 @@ finish_omp_declare_simd_methods (tree t)
if (processing_template_decl)
return;
- for (tree x = TYPE_METHODS (t); x; x = DECL_CHAIN (x))
+ for (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
{
if (TREE_CODE (TREE_TYPE (x)) != METHOD_TYPE)
continue;
@@ -9072,52 +9074,34 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
}
/* Called from trait_expr_value to evaluate either __has_nothrow_assign or
- __has_nothrow_copy, depending on assign_p. */
+ __has_nothrow_copy, depending on assign_p. Returns true iff all
+ the copy {ctor,assign} fns are nothrow. */
static bool
classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p)
{
- tree fns;
+ tree fns = NULL_TREE;
if (assign_p)
- {
- int ix;
- ix = lookup_fnfields_1 (type, cp_assignment_operator_id (NOP_EXPR));
- if (ix < 0)
- return false;
- fns = (*CLASSTYPE_METHOD_VEC (type))[ix];
- }
+ fns = lookup_fnfields_slot (type, cp_assignment_operator_id (NOP_EXPR));
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;
+ fns = lookup_fnfields_slot (type, ctor_identifier);
+ bool saw_copy = false;
for (ovl_iterator iter (fns); iter; ++iter)
{
tree fn = *iter;
-
- if (assign_p)
+
+ if (copy_fn_p (fn) > 0)
{
- if (copy_fn_p (fn) == 0)
- continue;
+ saw_copy = true;
+ maybe_instantiate_noexcept (fn);
+ if (!TYPE_NOTHROW_P (TREE_TYPE (fn)))
+ return false;
}
- else if (copy_fn_p (fn) <= 0)
- continue;
-
- maybe_instantiate_noexcept (fn);
- if (!TYPE_NOTHROW_P (TREE_TYPE (fn)))
- return false;
}
- return true;
+ return saw_copy;
}
/* Actually evaluates the trait. */
@@ -9401,7 +9385,7 @@ apply_deduced_return_type (tree fco, tree return_type)
}
if (DECL_CONV_FN_P (fco))
- DECL_NAME (fco) = mangle_conv_op_name_for_type (return_type);
+ DECL_NAME (fco) = make_conv_op_name (return_type);
TREE_TYPE (fco) = change_return_type (return_type, TREE_TYPE (fco));
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index bb17278c611..2122450c653 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -90,7 +90,6 @@ lvalue_kind (const_tree ref)
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));
@@ -1503,13 +1502,13 @@ strip_typedefs (tree t, bool *remove_attributes)
break;
case TYPENAME_TYPE:
{
+ bool changed = false;
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);
@@ -1533,12 +1532,15 @@ strip_typedefs (tree t, bool *remove_attributes)
else
ggc_free (new_args);
}
- result = make_typename_type (strip_typedefs (TYPE_CONTEXT (t),
- remove_attributes),
- fullname, typename_type, tf_none);
- /* Handle 'typedef typename A::N N;' */
- if (typedef_variant_p (result))
- result = TYPE_MAIN_VARIANT (DECL_ORIGINAL_TYPE (TYPE_NAME (result)));
+ tree ctx = strip_typedefs (TYPE_CONTEXT (t), remove_attributes);
+ if (!changed && ctx == TYPE_CONTEXT (t) && !typedef_variant_p (t))
+ return t;
+ tree name = fullname;
+ if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR)
+ name = TREE_OPERAND (fullname, 0);
+ /* Use build_typename_type rather than make_typename_type because we
+ don't want to resolve it here, just strip typedefs. */
+ result = build_typename_type (ctx, name, fullname, typename_type);
}
break;
case DECLTYPE_TYPE:
@@ -3581,16 +3583,6 @@ cp_tree_equal (tree t1, tree t2)
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
@@ -3984,8 +3976,7 @@ type_has_nontrivial_copy_init (const_tree type)
else if (CLASSTYPE_LAZY_COPY_CTOR (t))
{
saw_copy = true;
- if (type_has_user_declared_move_constructor (t)
- || type_has_user_declared_move_assign (t))
+ if (classtype_has_move_assign_or_move_ctor_p (t, true))
/* [class.copy]/8 If the class definition declares a move
constructor or move assignment operator, the implicitly declared
copy constructor is defined as deleted.... */;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 1c15f29eb3d..3dc64045e1a 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5256,6 +5256,7 @@ cp_build_binary_op (location_t location,
if (sanitize_flags_p ((SANITIZE_SHIFT
| SANITIZE_DIVIDE | SANITIZE_FLOAT_DIVIDE))
+ && current_function_decl != NULL_TREE
&& !processing_template_decl
&& (doing_div_or_mod || doing_shift))
{
@@ -6681,7 +6682,7 @@ maybe_warn_about_useless_cast (tree type, tree expr, tsubst_flags_t complain)
? xvalue_p (expr) : 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);
+ warning (OPT_Wuseless_cast, "useless cast to type %q#T", type);
}
}