aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2008-09-08 16:52:44 -0400
committerJason Merrill <jason@gcc.gnu.org>2008-09-08 16:52:44 -0400
commitb344d949d25164341ca4532ce067af1b254198a0 (patch)
tree0142184b1cea337fc342e6818257e4f6cb77fa58 /gcc/cp/decl.c
parent37022b7c72c96135c90798684598f39fd1371b40 (diff)
downloadgcc-b344d949d25164341ca4532ce067af1b254198a0.zip
gcc-b344d949d25164341ca4532ce067af1b254198a0.tar.gz
gcc-b344d949d25164341ca4532ce067af1b254198a0.tar.bz2
re PR c++/37302 (function parameters are declared too late)
PR c++/37302 * parser.c (cp_parser_parameter_declaration_list): Process the PARM_DECLs as we go and push them. Return a TREE_LIST. (cp_parser_parameter_declaration_clause): Return a TREE_LIST. (cp_parser_direct_declarator): Create a binding level and suppress deprecated warnings in the parameter list. (make_call_declarator): PARMS is now a tree. * cp-tree.h (struct cp_declarator): Function parms are now a tree. * decl.h (enum deprecated_states, deprecated_state): Move here. * decl.c: From here. (type_is_deprecated): New fn. (grokparms): PARMLIST is a tree now. Warn about parms that use deprecated types. * mangle.c (write_expression): Handle PARM_DECL, CALL_EXPR and 0-operand cast. * pt.c (tsubst) [DECLTYPE_TYPE]: Set skip_evaluation. (tsubst_copy) [PARM_DECL]: Handle a PARM_DECL used outside of a function. * name-lookup.c (pushtag): Look through function parameter scopes. (pushdecl_maybe_friend): Don't set DECL_CONTEXT on a PARM_DECL when we're parsing a function declarator. From-SVN: r140120
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c81
1 files changed, 45 insertions, 36 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index c045353..3348d28 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -54,7 +54,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-flow.h"
#include "pointer-set.h"
-static tree grokparms (cp_parameter_declarator *, tree *);
+static tree grokparms (tree parmlist, tree *);
static const char *redeclaration_error_message (tree, tree);
static int decl_jump_unsafe (tree);
@@ -236,13 +236,7 @@ VEC(tree, gc) *deferred_mark_used_calls;
with __attribute__((deprecated)). An object declared as
__attribute__((deprecated)) suppresses warnings of uses of other
deprecated items. */
-
-enum deprecated_states {
- DEPRECATED_NORMAL,
- DEPRECATED_SUPPRESS
-};
-
-static enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
+enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
/* A TREE_LIST of VAR_DECLs. The TREE_PURPOSE is a RECORD_TYPE or
@@ -9494,6 +9488,32 @@ check_default_argument (tree decl, tree arg)
return arg;
}
+/* Returns a deprecated type used within TYPE, or NULL_TREE if none. */
+
+static tree
+type_is_deprecated (tree type)
+{
+ enum tree_code code;
+ if (TREE_DEPRECATED (type))
+ return type;
+ if (TYPE_NAME (type)
+ && TREE_DEPRECATED (TYPE_NAME (type)))
+ return type;
+
+ code = TREE_CODE (type);
+
+ if (code == POINTER_TYPE || code == REFERENCE_TYPE
+ || code == OFFSET_TYPE || code == FUNCTION_TYPE
+ || code == METHOD_TYPE || code == ARRAY_TYPE)
+ return type_is_deprecated (TREE_TYPE (type));
+
+ if (TYPE_PTRMEMFUNC_P (type))
+ return type_is_deprecated
+ (TREE_TYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type))));
+
+ return NULL_TREE;
+}
+
/* Decode the list of parameter types for a function type.
Given the list of things declared inside the parens,
return a list of types.
@@ -9504,41 +9524,31 @@ check_default_argument (tree decl, tree arg)
*PARMS is set to the chain of PARM_DECLs created. */
static tree
-grokparms (cp_parameter_declarator *first_parm, tree *parms)
+grokparms (tree parmlist, tree *parms)
{
tree result = NULL_TREE;
tree decls = NULL_TREE;
- int ellipsis = !first_parm || first_parm->ellipsis_p;
- cp_parameter_declarator *parm;
+ tree parm;
int any_error = 0;
- struct pointer_set_t *unique_decls = pointer_set_create ();
- for (parm = first_parm; parm != NULL; parm = parm->next)
+ for (parm = parmlist; parm != NULL_TREE; parm = TREE_CHAIN (parm))
{
tree type = NULL_TREE;
- tree init = parm->default_argument;
- tree attrs;
- tree decl;
+ tree init = TREE_PURPOSE (parm);
+ tree decl = TREE_VALUE (parm);
- if (parm == no_parameters)
+ if (parm == void_list_node)
break;
- attrs = parm->decl_specifiers.attributes;
- parm->decl_specifiers.attributes = NULL_TREE;
- decl = grokdeclarator (parm->declarator, &parm->decl_specifiers,
- PARM, init != NULL_TREE, &attrs);
if (! decl || TREE_TYPE (decl) == error_mark_node)
continue;
- if (attrs)
- cplus_decl_attributes (&decl, attrs, 0);
-
type = TREE_TYPE (decl);
if (VOID_TYPE_P (type))
{
if (same_type_p (type, void_type_node)
&& DECL_SELF_REFERENCE_P (type)
- && !DECL_NAME (decl) && !result && !parm->next && !ellipsis)
+ && !DECL_NAME (decl) && !result && TREE_CHAIN (parm) == void_list_node)
/* this is a parmlist of `(void)', which is ok. */
break;
cxx_incomplete_type_error (decl, type);
@@ -9561,6 +9571,13 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms)
if (type != error_mark_node)
{
+ if (deprecated_state != DEPRECATED_SUPPRESS)
+ {
+ tree deptype = type_is_deprecated (type);
+ if (deptype)
+ warn_deprecated_use (deptype);
+ }
+
/* Top-level qualifiers on the parameters are
ignored for function types. */
type = cp_build_qualified_type (type, 0);
@@ -9603,28 +9620,20 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms)
if (TREE_CODE (decl) == PARM_DECL
&& FUNCTION_PARAMETER_PACK_P (decl)
- && parm->next)
+ && TREE_CHAIN (parm)
+ && TREE_CHAIN (parm) != void_list_node)
error ("parameter packs must be at the end of the parameter list");
- if (DECL_NAME (decl))
- {
- if (pointer_set_contains (unique_decls, DECL_NAME (decl)))
- error ("multiple parameters named %qE", DECL_NAME (decl));
- else
- pointer_set_insert (unique_decls, DECL_NAME (decl));
- }
-
TREE_CHAIN (decl) = decls;
decls = decl;
result = tree_cons (init, type, result);
}
decls = nreverse (decls);
result = nreverse (result);
- if (!ellipsis)
+ if (parm)
result = chainon (result, void_list_node);
*parms = decls;
- pointer_set_destroy (unique_decls);
return result;
}