Commit 5f261ba9 by Mark Mitchell Committed by Mark Mitchell

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
parent 87912be7
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> 2002-06-23 Mark Mitchell <mark@codesourcery.com>
* parse.y (parse_scoped_id): New function. * parse.y (parse_scoped_id): New function.
......
...@@ -5310,12 +5310,8 @@ finish_struct (t, attributes) ...@@ -5310,12 +5310,8 @@ finish_struct (t, attributes)
else else
error ("trying to finish struct, but kicked out due to previous parse errors"); error ("trying to finish struct, but kicked out due to previous parse errors");
if (processing_template_decl) if (processing_template_decl && at_function_scope_p ())
{ add_stmt (build_min (TAG_DEFN, t));
tree scope = current_scope ();
if (scope && TREE_CODE (scope) == FUNCTION_DECL)
add_stmt (build_min (TAG_DEFN, t));
}
return t; return t;
} }
......
...@@ -2546,6 +2546,17 @@ extern int flag_new_for_scope; ...@@ -2546,6 +2546,17 @@ extern int flag_new_for_scope;
#define ARITHMETIC_TYPE_P(TYPE) \ #define ARITHMETIC_TYPE_P(TYPE) \
(CP_INTEGRAL_TYPE_P (TYPE) || TREE_CODE (TYPE) == REAL_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 /* Nonzero for _TYPE means that the _TYPE defines
at least one constructor. */ at least one constructor. */
#define TYPE_HAS_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1 (NODE)) #define TYPE_HAS_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1 (NODE))
...@@ -3812,6 +3823,7 @@ extern void begin_only_namespace_names PARAMS ((void)); ...@@ -3812,6 +3823,7 @@ extern void begin_only_namespace_names PARAMS ((void));
extern void end_only_namespace_names PARAMS ((void)); extern void end_only_namespace_names PARAMS ((void));
extern tree namespace_ancestor PARAMS ((tree, tree)); extern tree namespace_ancestor PARAMS ((tree, tree));
extern tree unqualified_namespace_lookup PARAMS ((tree, int, 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 lookup_using_namespace PARAMS ((tree, tree, tree, tree, int, tree *));
extern int qualified_lookup_using_namespace PARAMS ((tree, tree, tree, int)); extern int qualified_lookup_using_namespace PARAMS ((tree, tree, tree, int));
extern tree build_library_fn PARAMS ((tree, tree)); extern tree build_library_fn PARAMS ((tree, tree));
...@@ -4174,6 +4186,7 @@ extern void init_search_processing PARAMS ((void)); ...@@ -4174,6 +4186,7 @@ extern void init_search_processing PARAMS ((void));
extern void reinit_search_statistics PARAMS ((void)); extern void reinit_search_statistics PARAMS ((void));
extern tree current_scope PARAMS ((void)); extern tree current_scope PARAMS ((void));
extern int at_function_scope_p 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 context_for_name_lookup PARAMS ((tree));
extern tree lookup_conversions PARAMS ((tree)); extern tree lookup_conversions PARAMS ((tree));
extern tree binfo_for_vtable PARAMS ((tree)); extern tree binfo_for_vtable PARAMS ((tree));
...@@ -4261,6 +4274,7 @@ extern tree finish_pseudo_destructor_call_expr PARAMS ((tree, tree, 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_qualified_call_expr PARAMS ((tree, tree));
extern tree finish_unary_op_expr PARAMS ((enum tree_code, tree)); extern tree finish_unary_op_expr PARAMS ((enum tree_code, tree));
extern tree finish_id_expr PARAMS ((tree)); extern tree finish_id_expr PARAMS ((tree));
extern tree finish_fname (tree);
extern void save_type_access_control PARAMS ((tree)); extern void save_type_access_control PARAMS ((tree));
extern void reset_type_access_control PARAMS ((void)); extern void reset_type_access_control PARAMS ((void));
extern void decl_type_access_control PARAMS ((tree)); extern void decl_type_access_control PARAMS ((tree));
......
...@@ -5921,6 +5921,65 @@ warn_about_implicit_typename_lookup (typename, binding) ...@@ -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 /* Look up NAME in the current binding level and its superiors in the
namespace of variables, functions and typedefs. Return a ..._DECL namespace of variables, functions and typedefs. Return a ..._DECL
node of some kind representing its definition if there is only one node of some kind representing its definition if there is only one
...@@ -13171,11 +13230,8 @@ finish_enum (enumtype) ...@@ -13171,11 +13230,8 @@ finish_enum (enumtype)
postponed until the template is instantiated. */ postponed until the template is instantiated. */
if (processing_template_decl) if (processing_template_decl)
{ {
tree scope = current_scope (); if (at_function_scope_p ())
if (scope && TREE_CODE (scope) == FUNCTION_DECL)
add_stmt (build_min (TAG_DEFN, enumtype)); add_stmt (build_min (TAG_DEFN, enumtype));
return; return;
} }
......
...@@ -1208,45 +1208,8 @@ do_identifier (token, parsing, args) ...@@ -1208,45 +1208,8 @@ do_identifier (token, parsing, args)
} }
} }
if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id)) id = check_for_out_of_scope_variable (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);
}
}
}
/* TREE_USED is set in `hack_identifier'. */ /* TREE_USED is set in `hack_identifier'. */
if (TREE_CODE (id) == CONST_DECL) if (TREE_CODE (id) == CONST_DECL)
{ {
......
...@@ -308,7 +308,7 @@ check_class_key (key, aggr) ...@@ -308,7 +308,7 @@ check_class_key (key, aggr)
/* __func__, __FUNCTION__ or __PRETTY_FUNCTION__. /* __func__, __FUNCTION__ or __PRETTY_FUNCTION__.
yylval contains an IDENTIFIER_NODE which indicates which one. */ yylval contains an IDENTIFIER_NODE which indicates which one. */
%token VAR_FUNC_NAME %token <ttype> VAR_FUNC_NAME
/* String constants in raw form. /* String constants in raw form.
yylval is a STRING_CST node. */ yylval is a STRING_CST node. */
...@@ -1624,11 +1624,7 @@ primary: ...@@ -1624,11 +1624,7 @@ primary:
TYPE_DOMAIN (TREE_TYPE ($$))); TYPE_DOMAIN (TREE_TYPE ($$)));
} }
| VAR_FUNC_NAME | VAR_FUNC_NAME
{ { $$ = finish_fname ($1); }
$$ = fname_decl (C_RID_CODE ($$), $$);
if (processing_template_decl)
$$ = build_min_nt (LOOKUP_EXPR, DECL_NAME ($$));
}
| '(' expr ')' | '(' expr ')'
{ $$ = finish_parenthesized_expr ($2); } { $$ = finish_parenthesized_expr ($2); }
| '(' expr_or_declarator_intern ')' | '(' expr_or_declarator_intern ')'
...@@ -1637,8 +1633,7 @@ primary: ...@@ -1637,8 +1633,7 @@ primary:
| '(' error ')' | '(' error ')'
{ $$ = error_mark_node; } { $$ = error_mark_node; }
| '(' | '('
{ tree scope = current_scope (); { if (!at_function_scope_p ())
if (!scope || TREE_CODE (scope) != FUNCTION_DECL)
{ {
error ("braced-group within expression allowed only inside a function"); error ("braced-group within expression allowed only inside a function");
YYERROR; YYERROR;
......
...@@ -581,6 +581,15 @@ at_function_scope_p () ...@@ -581,6 +581,15 @@ at_function_scope_p ()
return cs && TREE_CODE (cs) == FUNCTION_DECL; 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. */ /* Return the scope of DECL, as appropriate when doing name-lookup. */
tree tree
......
...@@ -1437,6 +1437,20 @@ finish_id_expr (expr) ...@@ -1437,6 +1437,20 @@ finish_id_expr (expr)
return 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; static tree current_type_lookups;
/* Perform deferred access control for types used in the type of a /* Perform deferred access control for types used in the type of a
...@@ -2025,9 +2039,7 @@ check_multiple_declarators () ...@@ -2025,9 +2039,7 @@ check_multiple_declarators ()
We don't just use PROCESSING_TEMPLATE_DECL for the first We don't just use PROCESSING_TEMPLATE_DECL for the first
condition since that would disallow the perfectly legal code, condition since that would disallow the perfectly legal code,
like `template <class T> struct S { int i, j; };'. */ like `template <class T> struct S { int i, j; };'. */
tree scope = current_scope (); if (at_function_scope_p ())
if (scope && TREE_CODE (scope) == FUNCTION_DECL)
/* It's OK to write `template <class T> void f() { int i, j;}'. */ /* It's OK to write `template <class T> void f() { int i, j;}'. */
return; return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment