aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2002-06-24 19:18:43 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2002-06-24 19:18:43 +0000
commit5f261ba970a894543b1c8c30f71c7eb2a234ba93 (patch)
treebe46d82b47945fa6f5b787b66f752af4d7711a6b
parent87912be720118115eded3786b807a34cfb0f0a81 (diff)
downloadgcc-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
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/cp/class.c8
-rw-r--r--gcc/cp/cp-tree.h14
-rw-r--r--gcc/cp/decl.c64
-rw-r--r--gcc/cp/lex.c41
-rw-r--r--gcc/cp/parse.y11
-rw-r--r--gcc/cp/search.c9
-rw-r--r--gcc/cp/semantics.c18
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;