diff options
author | Mark Mitchell <mark@codesourcery.com> | 2002-06-24 19:18:43 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2002-06-24 19:18:43 +0000 |
commit | 5f261ba970a894543b1c8c30f71c7eb2a234ba93 (patch) | |
tree | be46d82b47945fa6f5b787b66f752af4d7711a6b /gcc | |
parent | 87912be720118115eded3786b807a34cfb0f0a81 (diff) | |
download | gcc-5f261ba970a894543b1c8c30f71c7eb2a234ba93.zip gcc-5f261ba970a894543b1c8c30f71c7eb2a234ba93.tar.gz gcc-5f261ba970a894543b1c8c30f71c7eb2a234ba93.tar.bz2 |
cp-tree.h (SCALAR_TYPE_P): New macro.
* cp-tree.h (SCALAR_TYPE_P): New macro.
(check_for_out_of_scope_variable): New function.
(at_class_scope_p): Likewise.
(finish_fname): Likewise.
* class.c (finish_struct): Use at_function_scope_p.
* decl.c (check_for_out_of_scope_variable): New function, split
out from do_identifier.
(finish_enum): Use at_function_scope_p.
* lex.c (do_identifier): Use check_for_out_of_scope_variable.
* parse.y (VAR_FUNC_NAME): Give it <ttype>. Use finish_fname.
(primary): Use at_function_scope_p.
* search.c (at_class_scope_p): New function.
* semantics.c (finish_fname): Likewise.
(check_multiple_declarators): Use at_function_scope_p.
From-SVN: r54962
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/cp/class.c | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 14 | ||||
-rw-r--r-- | gcc/cp/decl.c | 64 | ||||
-rw-r--r-- | gcc/cp/lex.c | 41 | ||||
-rw-r--r-- | gcc/cp/parse.y | 11 | ||||
-rw-r--r-- | gcc/cp/search.c | 9 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 18 |
8 files changed, 122 insertions, 60 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6cbaf2a..869c255 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +2002-06-24 Mark Mitchell <mark@codesourcery.com> + + * cp-tree.h (SCALAR_TYPE_P): New macro. + (check_for_out_of_scope_variable): New function. + (at_class_scope_p): Likewise. + (finish_fname): Likewise. + * class.c (finish_struct): Use at_function_scope_p. + * decl.c (check_for_out_of_scope_variable): New function, split + out from do_identifier. + (finish_enum): Use at_function_scope_p. + * lex.c (do_identifier): Use check_for_out_of_scope_variable. + * parse.y (VAR_FUNC_NAME): Give it <ttype>. Use finish_fname. + (primary): Use at_function_scope_p. + * search.c (at_class_scope_p): New function. + * semantics.c (finish_fname): Likewise. + (check_multiple_declarators): Use at_function_scope_p. + 2002-06-23 Mark Mitchell <mark@codesourcery.com> * parse.y (parse_scoped_id): New function. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 09a0385..0577c76 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5310,12 +5310,8 @@ finish_struct (t, attributes) else error ("trying to finish struct, but kicked out due to previous parse errors"); - if (processing_template_decl) - { - tree scope = current_scope (); - if (scope && TREE_CODE (scope) == FUNCTION_DECL) - add_stmt (build_min (TAG_DEFN, t)); - } + if (processing_template_decl && at_function_scope_p ()) + add_stmt (build_min (TAG_DEFN, t)); return t; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6b39ada..32b2412 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2546,6 +2546,17 @@ extern int flag_new_for_scope; #define ARITHMETIC_TYPE_P(TYPE) \ (CP_INTEGRAL_TYPE_P (TYPE) || TREE_CODE (TYPE) == REAL_TYPE) +/* [basic.types] + + Arithmetic types, enumeration types, pointer types, and + pointer-to-member types, are collectively called scalar types. */ +#define SCALAR_TYPE_P(TYPE) \ + (ARITHMETIC_TYPE_P (TYPE) \ + || TREE_CODE (TYPE) == ENUMERAL_TYPE \ + || TYPE_PTR_P (TYPE) \ + || TYPE_PTRMEM_P (TYPE) \ + || TYPE_PTRMEMFUNC_P (TYPE)) + /* Nonzero for _TYPE means that the _TYPE defines at least one constructor. */ #define TYPE_HAS_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1 (NODE)) @@ -3812,6 +3823,7 @@ extern void begin_only_namespace_names PARAMS ((void)); extern void end_only_namespace_names PARAMS ((void)); extern tree namespace_ancestor PARAMS ((tree, tree)); extern tree unqualified_namespace_lookup PARAMS ((tree, int, tree *)); +extern tree check_for_out_of_scope_variable (tree); extern int lookup_using_namespace PARAMS ((tree, tree, tree, tree, int, tree *)); extern int qualified_lookup_using_namespace PARAMS ((tree, tree, tree, int)); extern tree build_library_fn PARAMS ((tree, tree)); @@ -4174,6 +4186,7 @@ extern void init_search_processing PARAMS ((void)); extern void reinit_search_statistics PARAMS ((void)); extern tree current_scope PARAMS ((void)); extern int at_function_scope_p PARAMS ((void)); +extern bool at_class_scope_p (void); extern tree context_for_name_lookup PARAMS ((tree)); extern tree lookup_conversions PARAMS ((tree)); extern tree binfo_for_vtable PARAMS ((tree)); @@ -4261,6 +4274,7 @@ extern tree finish_pseudo_destructor_call_expr PARAMS ((tree, tree, tree)); extern tree finish_qualified_call_expr PARAMS ((tree, tree)); extern tree finish_unary_op_expr PARAMS ((enum tree_code, tree)); extern tree finish_id_expr PARAMS ((tree)); +extern tree finish_fname (tree); extern void save_type_access_control PARAMS ((tree)); extern void reset_type_access_control PARAMS ((void)); extern void decl_type_access_control PARAMS ((tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index dc75876..3a6e7a1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5921,6 +5921,65 @@ warn_about_implicit_typename_lookup (typename, binding) } } +/* Check to see whether or not DECL is a variable that would have been + in scope under the ARM, but is not in scope under the ANSI/ISO + standard. If so, issue an error message. If name lookup would + work in both cases, but return a different result, this function + returns the result of ANSI/ISO lookup. Otherwise, it returns + DECL. */ + +tree +check_for_out_of_scope_variable (tree decl) +{ + tree shadowed; + + /* We only care about out of scope variables. */ + if (!(TREE_CODE (decl) == VAR_DECL && DECL_DEAD_FOR_LOCAL (decl))) + return decl; + + shadowed = DECL_SHADOWED_FOR_VAR (decl); + while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL + && DECL_DEAD_FOR_LOCAL (shadowed)) + shadowed = DECL_SHADOWED_FOR_VAR (shadowed); + if (!shadowed) + shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (decl)); + if (shadowed) + { + if (!DECL_ERROR_REPORTED (decl)) + { + warning ("name lookup of `%D' changed", + DECL_NAME (decl)); + cp_warning_at (" matches this `%D' under ISO standard rules", + shadowed); + cp_warning_at (" matches this `%D' under old rules", decl); + DECL_ERROR_REPORTED (decl) = 1; + } + return shadowed; + } + + /* If we have already complained about this declaration, there's no + need to do it again. */ + if (DECL_ERROR_REPORTED (decl)) + return decl; + + DECL_ERROR_REPORTED (decl) = 1; + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))) + { + error ("name lookup of `%D' changed for new ISO `for' scoping", + DECL_NAME (decl)); + cp_error_at (" cannot use obsolete binding at `%D' because it has a destructor", decl); + return error_mark_node; + } + else + { + pedwarn ("name lookup of `%D' changed for new ISO `for' scoping", + DECL_NAME (decl)); + cp_pedwarn_at (" using obsolete binding at `%D'", decl); + } + + return decl; +} + /* Look up NAME in the current binding level and its superiors in the namespace of variables, functions and typedefs. Return a ..._DECL node of some kind representing its definition if there is only one @@ -13171,11 +13230,8 @@ finish_enum (enumtype) postponed until the template is instantiated. */ if (processing_template_decl) { - tree scope = current_scope (); - if (scope && TREE_CODE (scope) == FUNCTION_DECL) + if (at_function_scope_p ()) add_stmt (build_min (TAG_DEFN, enumtype)); - - return; } diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index a5e0b10..feadd69 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -1208,45 +1208,8 @@ do_identifier (token, parsing, args) } } - if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id)) - { - tree shadowed = DECL_SHADOWED_FOR_VAR (id); - while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL - && DECL_DEAD_FOR_LOCAL (shadowed)) - shadowed = DECL_SHADOWED_FOR_VAR (shadowed); - if (!shadowed) - shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (id)); - if (shadowed) - { - if (!DECL_ERROR_REPORTED (id)) - { - warning ("name lookup of `%s' changed", - IDENTIFIER_POINTER (token)); - cp_warning_at (" matches this `%D' under ISO standard rules", - shadowed); - cp_warning_at (" matches this `%D' under old rules", id); - DECL_ERROR_REPORTED (id) = 1; - } - id = shadowed; - } - else if (!DECL_ERROR_REPORTED (id)) - { - DECL_ERROR_REPORTED (id) = 1; - if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (id))) - { - error ("name lookup of `%s' changed for new ISO `for' scoping", - IDENTIFIER_POINTER (token)); - cp_error_at (" cannot use obsolete binding at `%D' because it has a destructor", id); - id = error_mark_node; - } - else - { - pedwarn ("name lookup of `%s' changed for new ISO `for' scoping", - IDENTIFIER_POINTER (token)); - cp_pedwarn_at (" using obsolete binding at `%D'", id); - } - } - } + id = check_for_out_of_scope_variable (id); + /* TREE_USED is set in `hack_identifier'. */ if (TREE_CODE (id) == CONST_DECL) { diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 31a9ee0..acb45ab 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -308,7 +308,7 @@ check_class_key (key, aggr) /* __func__, __FUNCTION__ or __PRETTY_FUNCTION__. yylval contains an IDENTIFIER_NODE which indicates which one. */ -%token VAR_FUNC_NAME +%token <ttype> VAR_FUNC_NAME /* String constants in raw form. yylval is a STRING_CST node. */ @@ -1624,11 +1624,7 @@ primary: TYPE_DOMAIN (TREE_TYPE ($$))); } | VAR_FUNC_NAME - { - $$ = fname_decl (C_RID_CODE ($$), $$); - if (processing_template_decl) - $$ = build_min_nt (LOOKUP_EXPR, DECL_NAME ($$)); - } + { $$ = finish_fname ($1); } | '(' expr ')' { $$ = finish_parenthesized_expr ($2); } | '(' expr_or_declarator_intern ')' @@ -1637,8 +1633,7 @@ primary: | '(' error ')' { $$ = error_mark_node; } | '(' - { tree scope = current_scope (); - if (!scope || TREE_CODE (scope) != FUNCTION_DECL) + { if (!at_function_scope_p ()) { error ("braced-group within expression allowed only inside a function"); YYERROR; diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 9617796..b7ba0bc 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -581,6 +581,15 @@ at_function_scope_p () return cs && TREE_CODE (cs) == FUNCTION_DECL; } +/* Returns true if the innermost active scope is a class scope. */ + +bool +at_class_scope_p () +{ + tree cs = current_scope (); + return cs && TYPE_P (cs); +} + /* Return the scope of DECL, as appropriate when doing name-lookup. */ tree diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c6c3047..0f671ae 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1437,6 +1437,20 @@ finish_id_expr (expr) return expr; } +/* Return the declaration for the function-name variable indicated by + ID. */ + +tree +finish_fname (tree id) +{ + tree decl; + + decl = fname_decl (C_RID_CODE (id), id); + if (processing_template_decl) + decl = build_min_nt (LOOKUP_EXPR, DECL_NAME (decl)); + return decl; +} + static tree current_type_lookups; /* Perform deferred access control for types used in the type of a @@ -2025,9 +2039,7 @@ check_multiple_declarators () We don't just use PROCESSING_TEMPLATE_DECL for the first condition since that would disallow the perfectly legal code, like `template <class T> struct S { int i, j; };'. */ - tree scope = current_scope (); - - if (scope && TREE_CODE (scope) == FUNCTION_DECL) + if (at_function_scope_p ()) /* It's OK to write `template <class T> void f() { int i, j;}'. */ return; |