diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1c46adf99a1..84064326f4d 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9126,12 +9126,12 @@ grokdeclarator (const cp_declarator *declarator, if (!declarator->u.function.late_return_type) { error ("%qs function uses %<auto%> type specifier without" - " late return type", name); + " trailing return type", name); return error_mark_node; } else if (!is_auto (type)) { - error ("%qs function with late return type has" + error ("%qs function with trailing return type has" " %qT as its type rather than plain %<auto%>", name, type); return error_mark_node; @@ -9139,8 +9139,14 @@ grokdeclarator (const cp_declarator *declarator, } else if (declarator->u.function.late_return_type) { - error ("%qs function with late return type not declared" - " with %<auto%> type specifier", name); + if (cxx_dialect < cxx0x) + /* Not using maybe_warn_cpp0x because this should + always be an error. */ + error ("trailing return type only available with " + "-std=c++11 or -std=gnu++11"); + else + error ("%qs function with trailing return type not " + "declared with %<auto%> type specifier", name); return error_mark_node; } } @@ -11336,6 +11342,9 @@ check_elaborated_type_specifier (enum tag_types tag_code, { tree type; + if (decl == error_mark_node) + return error_mark_node; + /* In the case of: struct S { struct S *p; }; @@ -11355,10 +11364,15 @@ check_elaborated_type_specifier (enum tag_types tag_code, type, tag_name (tag_code)); return error_mark_node; } + /* Accept bound template template parameters. */ + else if (allow_template_p + && TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM) + ; /* [dcl.type.elab] - If the identifier resolves to a typedef-name or a template - type-parameter, the elaborated-type-specifier is ill-formed. + If the identifier resolves to a typedef-name or the + simple-template-id resolves to an alias template + specialization, the elaborated-type-specifier is ill-formed. In other words, the only legitimate declaration to use in the elaborated type specifier is the implicit typedef created when @@ -11367,8 +11381,13 @@ check_elaborated_type_specifier (enum tag_types tag_code, && !DECL_SELF_REFERENCE_P (decl) && tag_code != typename_type) { - error ("using typedef-name %qD after %qs", decl, tag_name (tag_code)); - error ("%q+D has a previous declaration here", decl); + if (alias_template_specialization_p (type)) + error ("using alias template specialization %qT after %qs", + type, tag_name (tag_code)); + else + error ("using typedef-name %qD after %qs", decl, tag_name (tag_code)); + inform (DECL_SOURCE_LOCATION (decl), + "%qD has a previous declaration here", decl); return error_mark_node; } else if (TREE_CODE (type) != RECORD_TYPE @@ -11988,8 +12007,22 @@ start_enum (tree name, tree enumtype, tree underlying_type, *is_new = true; } prevtype = enumtype; - enumtype = cxx_make_type (ENUMERAL_TYPE); - enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current); + + /* Do not push the decl more than once, unless we need to + compare underlying types at instantiation time */ + if (!enumtype + || (underlying_type + && dependent_type_p (underlying_type)) + || (ENUM_UNDERLYING_TYPE (enumtype) + && dependent_type_p (ENUM_UNDERLYING_TYPE (enumtype)))) + { + enumtype = cxx_make_type (ENUMERAL_TYPE); + enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current); + } + else + enumtype = xref_tag (enum_type, name, /*tag_scope=*/ts_current, + false); + if (enumtype == error_mark_node) return error_mark_node; |