diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 107 |
1 files changed, 67 insertions, 40 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 150e8662a5e..ea1a08d2674 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3296,7 +3296,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, error ("%qD used without template parameters", name); return error_mark_node; } - gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); + gcc_assert (identifier_p (name)); gcc_assert (TYPE_P (context)); if (!MAYBE_CLASS_TYPE_P (context)) @@ -3402,7 +3402,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list, name = TYPE_IDENTIFIER (name); else if (DECL_P (name)) name = DECL_NAME (name); - gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); + gcc_assert (identifier_p (name)); if (!dependent_type_p (context) || currently_open_class (context)) @@ -4781,7 +4781,7 @@ check_array_designated_initializer (const constructor_elt *ce, } else { - gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE); + gcc_assert (identifier_p (ce->index)); error ("name %qD used in a GNU-style designated " "initializer for an array", ce->index); } @@ -6434,11 +6434,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, /* Check for abstractness of the type. Notice that there is no need to strip array types here since the check for those types is already done within create_array_type_for_decl. */ - if (TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) - abstract_virtuals_error (decl, TREE_TYPE (type)); - else - abstract_virtuals_error (decl, type); + abstract_virtuals_error (decl, type); if (TREE_TYPE (decl) == error_mark_node) /* No initialization required. */ @@ -6758,10 +6754,9 @@ register_dtor_fn (tree decl) "__aeabi_atexit"), and DECL is a class object, we can just pass the destructor to "__cxa_atexit"; we don't have to build a temporary function to do the cleanup. */ - ob_parm = (DECL_THREAD_LOCAL_P (decl) - || (flag_use_cxa_atexit - && !targetm.cxx.use_atexit_for_cxa_atexit ())); - dso_parm = ob_parm; + dso_parm = (flag_use_cxa_atexit + && !targetm.cxx.use_atexit_for_cxa_atexit ()); + ob_parm = (DECL_THREAD_LOCAL_P (decl) || dso_parm); use_dtor = ob_parm && CLASS_TYPE_P (type); if (use_dtor) { @@ -6825,7 +6820,7 @@ register_dtor_fn (tree decl) before passing it in, to avoid spurious errors. */ addr = build_nop (ptr_type_node, addr); } - else if (ob_parm) + else /* Since the cleanup functions we build ignore the address they're given, there's no reason to pass the actual address in, and, in general, it's cheaper to pass NULL than any @@ -6835,6 +6830,10 @@ register_dtor_fn (tree decl) if (dso_parm) arg2 = cp_build_addr_expr (get_dso_handle_node (), tf_warning_or_error); + else if (ob_parm) + /* Just pass NULL to the dso handle parm if we don't actually + have a DSO handle on this target. */ + arg2 = null_pointer_node; else arg2 = NULL_TREE; @@ -7414,8 +7413,7 @@ grokfndecl (tree ctype, == current_class_type); fns = TREE_OPERAND (fns, 1); } - gcc_assert (TREE_CODE (fns) == IDENTIFIER_NODE - || TREE_CODE (fns) == OVERLOAD); + gcc_assert (identifier_p (fns) || TREE_CODE (fns) == OVERLOAD); DECL_TEMPLATE_INFO (decl) = build_template_info (fns, args); for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t)) @@ -7773,7 +7771,7 @@ grokvardecl (tree type, tree decl; tree explicit_scope; - gcc_assert (!name || TREE_CODE (name) == IDENTIFIER_NODE); + gcc_assert (!name || identifier_p (name)); /* Compute the scope in which to place the variable, but remember whether or not that scope was explicitly specified by the user. */ @@ -8510,7 +8508,7 @@ check_var_type (tree identifier, tree type) { if (!identifier) error ("unnamed variable or field declared void"); - else if (TREE_CODE (identifier) == IDENTIFIER_NODE) + else if (identifier_p (identifier)) { gcc_assert (!IDENTIFIER_OPNAME_P (identifier)); error ("variable or field %qE declared void", identifier); @@ -8653,6 +8651,7 @@ grokdeclarator (const cp_declarator *declarator, bool template_type_arg = false; bool template_parm_flag = false; bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr); + source_location saved_loc = input_location; const char *errmsg; signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed); @@ -8778,7 +8777,7 @@ grokdeclarator (const cp_declarator *declarator, tree fns = TREE_OPERAND (decl, 0); dname = fns; - if (TREE_CODE (dname) != IDENTIFIER_NODE) + if (!identifier_p (dname)) { gcc_assert (is_overloaded_fn (dname)); dname = DECL_NAME (get_first_fn (dname)); @@ -8787,7 +8786,7 @@ grokdeclarator (const cp_declarator *declarator, /* Fall through. */ case IDENTIFIER_NODE: - if (TREE_CODE (decl) == IDENTIFIER_NODE) + if (identifier_p (decl)) dname = decl; if (C_IS_RESERVED_WORD (dname)) @@ -8852,7 +8851,7 @@ grokdeclarator (const cp_declarator *declarator, } if (dname - && TREE_CODE (dname) == IDENTIFIER_NODE + && identifier_p (dname) && UDLIT_OPER_P (dname) && innermost_code != cdk_function) { @@ -8977,7 +8976,7 @@ grokdeclarator (const cp_declarator *declarator, common. With no options, it is allowed. With -Wreturn-type, it is a warning. It is only an error with -pedantic-errors. */ is_main = (funcdef_flag - && dname && TREE_CODE (dname) == IDENTIFIER_NODE + && dname && identifier_p (dname) && MAIN_NAME_P (dname) && ctype == NULL_TREE && in_namespace == NULL_TREE @@ -9337,7 +9336,6 @@ grokdeclarator (const cp_declarator *declarator, if (declspecs->std_attributes) { /* Apply the c++11 attributes to the type preceding them. */ - source_location saved_loc = input_location; input_location = declspecs->locations[ds_std_attribute]; decl_attributes (&type, declspecs->std_attributes, 0); input_location = saved_loc; @@ -9425,11 +9423,10 @@ grokdeclarator (const cp_declarator *declarator, error ("%qs declared as function returning an array", name); return error_mark_node; } - /* When decl_context == NORMAL we emit a better error message - later in abstract_virtuals_error. */ - if (decl_context == TYPENAME && ABSTRACT_CLASS_TYPE_P (type)) - error ("%qs declared as function returning an abstract " - "class type", name); + + input_location = declspecs->locations[ds_type_spec]; + abstract_virtuals_error (ACU_RETURN, type); + input_location = saved_loc; /* Pick up type qualifiers which should be applied to `this'. */ memfn_quals = declarator->u.function.qualifiers; @@ -9632,9 +9629,11 @@ grokdeclarator (const cp_declarator *declarator, but to the target of the pointer. */ type_quals = TYPE_UNQUALIFIED; + /* This code used to handle METHOD_TYPE, but I don't think it's + possible to get it here anymore. */ + gcc_assert (TREE_CODE (type) != METHOD_TYPE); if (declarator->kind == cdk_ptrmem - && (TREE_CODE (type) == FUNCTION_TYPE - || (memfn_quals && TREE_CODE (type) == METHOD_TYPE))) + && TREE_CODE (type) == FUNCTION_TYPE) { memfn_quals |= type_memfn_quals (type); type = build_memfn_type (type, @@ -10800,9 +10799,8 @@ static tree local_variable_p_walkfn (tree *tp, int *walk_subtrees, void * /*data*/) { - /* Check DECL_NAME to avoid including temporaries. We don't check - DECL_ARTIFICIAL because we do want to complain about 'this'. */ - if (local_variable_p (*tp) && DECL_NAME (*tp)) + if (local_variable_p (*tp) + && (!DECL_ARTIFICIAL (*tp) || DECL_NAME (*tp) == this_identifier)) return *tp; else if (TYPE_P (*tp)) *walk_subtrees = 0; @@ -11890,13 +11888,14 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, static tree xref_tag_1 (enum tag_types tag_code, tree name, - tag_scope scope, bool template_header_p) + tag_scope orig_scope, bool template_header_p) { enum tree_code code; tree t; tree context = NULL_TREE; + tag_scope scope; - gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); + gcc_assert (identifier_p (name)); switch (tag_code) { @@ -11914,6 +11913,11 @@ xref_tag_1 (enum tag_types tag_code, tree name, gcc_unreachable (); } + if (orig_scope == ts_lambda) + scope = ts_current; + else + scope = orig_scope; + /* In case of anonymous name, xref_tag is only called to make type node and push name. Name lookup is not required. */ if (ANON_AGGRNAME_P (name)) @@ -11987,6 +11991,10 @@ xref_tag_1 (enum tag_types tag_code, tree name, { t = make_class_type (code); TYPE_CONTEXT (t) = context; + if (orig_scope == ts_lambda) + /* Remember that we're declaring a lambda to avoid bogus errors + in push_template_decl. */ + CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node; t = pushtag (name, t, scope); } } @@ -12314,7 +12322,7 @@ start_enum (tree name, tree enumtype, tree underlying_type, bool scoped_enum_p, bool *is_new) { tree prevtype = NULL_TREE; - gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); + gcc_assert (identifier_p (name)); if (is_new) *is_new = false; @@ -14009,7 +14017,10 @@ grokmethod (cp_decl_specifier_seq *declspecs, /* VAR is a VAR_DECL. If its type is incomplete, remember VAR so that - we can lay it out later, when and if its type becomes complete. */ + we can lay it out later, when and if its type becomes complete. + + Also handle constexpr pointer to member variables where the initializer + is an unlowered PTRMEM_CST because the class isn't complete yet. */ void maybe_register_incomplete_var (tree var) @@ -14034,6 +14045,15 @@ maybe_register_incomplete_var (tree var) incomplete_var iv = {var, inner_type}; vec_safe_push (incomplete_vars, iv); } + else if (TYPE_PTRMEM_P (inner_type) + && DECL_INITIAL (var) + && TREE_CODE (DECL_INITIAL (var)) == PTRMEM_CST) + { + tree context = TYPE_PTRMEM_CLASS_TYPE (inner_type); + gcc_assert (TYPE_BEING_DEFINED (context)); + incomplete_var iv = {var, context}; + vec_safe_push (incomplete_vars, iv); + } } } @@ -14053,10 +14073,17 @@ complete_vars (tree type) { tree var = iv->decl; tree type = TREE_TYPE (var); - /* Complete the type of the variable. The VAR_DECL itself - will be laid out in expand_expr. */ - complete_type (type); - cp_apply_type_quals_to_decl (cp_type_quals (type), var); + + if (TYPE_PTRMEM_P (type)) + DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var)); + else + { + /* Complete the type of the variable. The VAR_DECL itself + will be laid out in expand_expr. */ + complete_type (type); + cp_apply_type_quals_to_decl (cp_type_quals (type), var); + } + /* Remove this entry from the list. */ incomplete_vars->unordered_remove (ix); } |