diff options
Diffstat (limited to 'contrib/gcc/cp')
-rw-r--r-- | contrib/gcc/cp/decl.c | 154 |
1 files changed, 87 insertions, 67 deletions
diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c index 6c7cece..451993e 100644 --- a/contrib/gcc/cp/decl.c +++ b/contrib/gcc/cp/decl.c @@ -1380,10 +1380,7 @@ duplicate_decls (tree newdecl, tree olddecl) else return NULL_TREE; } - - /* Already complained about this, so don't do so again. */ - else if (current_class_type == NULL_TREE - || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type) + else { error ("conflicting declaration '%#D'", newdecl); cp_error_at ("'%D' has a previous declaration as `%#D'", @@ -2647,16 +2644,7 @@ make_typename_type (tree context, tree name, tsubst_flags_t complain) return error_mark_node; } my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 20030802); - - if (TREE_CODE (context) == NAMESPACE_DECL) - { - /* We can get here from typename_sub0 in the explicit_template_type - expansion. Just fail. */ - if (complain & tf_error) - error ("no class template named `%#T' in `%#T'", - name, context); - return error_mark_node; - } + my_friendly_assert (TYPE_P (context), 20050905); if (!dependent_type_p (context) || currently_open_class (context)) @@ -4919,6 +4907,16 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) "initialized", decl); init = NULL_TREE; } + if (DECL_EXTERNAL (decl) && init) + { + /* The static data member cannot be initialized by a + non-constant when being declared. */ + error ("`%D' cannot be initialized by a non-constant expression" + " when being declared", decl); + DECL_INITIALIZED_IN_CLASS_P (decl) = 0; + init = NULL_TREE; + } + /* Handle: [dcl.init] @@ -5718,7 +5716,7 @@ grokfndecl (tree ctype, } if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))) - grok_op_properties (decl, friendp, /*complain=*/true); + grok_op_properties (decl, /*complain=*/true); if (ctype && decl_function_context (decl)) DECL_NO_STATIC_CHAIN (decl) = 1; @@ -5893,6 +5891,7 @@ grokvardecl (tree type, tree scope) { tree decl; + tree explicit_scope; RID_BIT_TYPE specbits; my_friendly_assert (!name || TREE_CODE (name) == IDENTIFIER_NODE, @@ -5900,7 +5899,9 @@ grokvardecl (tree type, specbits = *specbits_in; - /* Compute the scope in which to place the variable. */ + /* Compute the scope in which to place the variable, but remember + whether or not that scope was explicitly specified by the user. */ + explicit_scope = scope; if (!scope) { /* An explicit "extern" specifier indicates a namespace-scope @@ -5929,8 +5930,8 @@ grokvardecl (tree type, else decl = build_decl (VAR_DECL, name, type); - if (scope && TREE_CODE (scope) == NAMESPACE_DECL) - set_decl_namespace (decl, scope, 0); + if (explicit_scope && TREE_CODE (explicit_scope) == NAMESPACE_DECL) + set_decl_namespace (decl, explicit_scope, 0); else DECL_CONTEXT (decl) = scope; @@ -7187,8 +7188,8 @@ grokdeclarator (tree declarator, if (virtualp && staticp == 2) { - error ("member `%D' cannot be declared both virtual and static", - dname); + error ("member `%D' cannot be declared both virtual and static", dname); + RIDBIT_RESET (RID_STATIC, specbits); staticp = 0; } friendp = RIDBIT_SETP (RID_FRIEND, specbits); @@ -9004,7 +9005,7 @@ unary_op_p (enum tree_code code) errors are issued for invalid declarations. */ bool -grok_op_properties (tree decl, int friendp, bool complain) +grok_op_properties (tree decl, bool complain) { tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); tree argtype; @@ -9012,20 +9013,24 @@ grok_op_properties (tree decl, int friendp, bool complain) tree name = DECL_NAME (decl); enum tree_code operator_code; int arity; + bool ellipsis_p; bool ok; + tree class_type; /* Assume that the declaration is valid. */ ok = true; - /* Count the number of arguments. */ + /* Count the number of arguments. and check for ellipsis */ for (argtype = argtypes, arity = 0; argtype && argtype != void_list_node; argtype = TREE_CHAIN (argtype)) ++arity; + ellipsis_p = !argtype; - if (current_class_type == NULL_TREE) - friendp = 1; - + class_type = DECL_CONTEXT (decl); + if (class_type && !CLASS_TYPE_P (class_type)) + class_type = NULL_TREE; + if (DECL_CONV_FN_P (decl)) operator_code = TYPE_EXPR; else @@ -9053,30 +9058,28 @@ grok_op_properties (tree decl, int friendp, bool complain) my_friendly_assert (operator_code != LAST_CPLUS_TREE_CODE, 20000526); SET_OVERLOADED_OPERATOR_CODE (decl, operator_code); - if (! friendp) - { - switch (operator_code) - { - case NEW_EXPR: - TYPE_HAS_NEW_OPERATOR (current_class_type) = 1; - break; + if (class_type) + switch (operator_code) + { + case NEW_EXPR: + TYPE_HAS_NEW_OPERATOR (class_type) = 1; + break; - case DELETE_EXPR: - TYPE_GETS_DELETE (current_class_type) |= 1; - break; + case DELETE_EXPR: + TYPE_GETS_DELETE (class_type) |= 1; + break; - case VEC_NEW_EXPR: - TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1; - break; + case VEC_NEW_EXPR: + TYPE_HAS_ARRAY_NEW_OPERATOR (class_type) = 1; + break; - case VEC_DELETE_EXPR: - TYPE_GETS_DELETE (current_class_type) |= 2; - break; + case VEC_DELETE_EXPR: + TYPE_GETS_DELETE (class_type) |= 2; + break; - default: - break; - } - } + default: + break; + } if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR) TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl)); @@ -9130,37 +9133,46 @@ grok_op_properties (tree decl, int friendp, bool complain) if (operator_code == CALL_EXPR) return ok; - if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl)) + /* Warn about conversion operators that will never be used. */ + if (IDENTIFIER_TYPENAME_P (name) + && ! DECL_TEMPLATE_INFO (decl) + && warn_conversion + /* Warn only declaring the function; there is no need to + warn again about out-of-class definitions. */ + && class_type == current_class_type) { tree t = TREE_TYPE (name); - if (! friendp) + int ref = (TREE_CODE (t) == REFERENCE_TYPE); + const char *what = 0; + + if (ref) + t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); + + if (TREE_CODE (t) == VOID_TYPE) + what = "void"; + else if (class_type) { - int ref = (TREE_CODE (t) == REFERENCE_TYPE); - const char *what = 0; - - if (ref) - t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); - - if (TREE_CODE (t) == VOID_TYPE) - what = "void"; - else if (t == current_class_type) + if (t == class_type) what = "the same type"; /* Don't force t to be complete here. */ else if (IS_AGGR_TYPE (t) && COMPLETE_TYPE_P (t) - && DERIVED_FROM_P (t, current_class_type)) + && DERIVED_FROM_P (t, class_type)) what = "a base class"; - - if (what && warn_conversion) - warning ("conversion to %s%s will never use a type conversion operator", - ref ? "a reference to " : "", what); } + + if (what) + warning ("conversion to %s%s will never use a type conversion operator", + ref ? "a reference to " : "", what); } + if (operator_code == COND_EXPR) { /* 13.4.0.3 */ error ("ISO C++ prohibits overloading operator ?:"); } + else if (ellipsis_p) + error ("`%D' must not have variable number of arguments", decl); else if (ambi_op_p (operator_code)) { if (arity == 1) @@ -9325,9 +9337,11 @@ tag_name (enum tag_types code) case class_type: return "class"; case union_type: - return "union "; + return "union"; case enum_type: return "enum"; + case typename_type: + return "typename"; default: abort (); } @@ -9365,7 +9379,8 @@ check_elaborated_type_specifier (enum tag_types tag_code, In other words, the only legitimate declaration to use in the elaborated type specifier is the implicit typedef created when the type is declared. */ - if (!DECL_IMPLICIT_TYPEDEF_P (decl)) + if (!DECL_IMPLICIT_TYPEDEF_P (decl) + && tag_code != typename_type) { error ("using typedef-name `%D' after `%s'", decl, tag_name (tag_code)); return IS_AGGR_TYPE (type) ? type : error_mark_node; @@ -9379,7 +9394,8 @@ check_elaborated_type_specifier (enum tag_types tag_code, } else if (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE - && tag_code != enum_type) + && tag_code != enum_type + && tag_code != typename_type) { error ("`%T' referred to as `%s'", type, tag_name (tag_code)); return error_mark_node; @@ -10301,7 +10317,11 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) class scope, current_class_type will be NULL_TREE until set above by push_nested_class.) */ if (processing_template_decl) - decl1 = push_template_decl (decl1); + { + tree newdecl1 = push_template_decl (decl1); + if (newdecl1 != error_mark_node) + decl1 = newdecl1; + } /* We are now in the scope of the function being defined. */ current_function_decl = decl1; @@ -10315,6 +10335,8 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) must be complete when you define the function. */ if (! processing_template_decl) check_function_type (decl1, current_function_parms); + /* Make sure no default arg is missing. */ + check_default_args (decl1); /* Build the return declaration for the function. */ restype = TREE_TYPE (fntype); @@ -10378,8 +10400,6 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) /* We need to set the DECL_CONTEXT. */ if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1)) DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1)); - /* And make sure we have enough default args. */ - check_default_args (decl1); } fntype = TREE_TYPE (decl1); } |