This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: More cleanups for new parser
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 24 Jun 2002 12:16:35 -0700
- Subject: C++ PATCH: More cleanups for new parser
- Reply-to: mark at codesourcery dot com
Here are some more cleanups designed to bring the new parser a little
closer to compiling again...
Tested on i686-pc-linux-gnu.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
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.
Index: class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.452
diff -c -p -r1.452 class.c
*** class.c 18 Jun 2002 16:05:31 -0000 1.452
--- class.c 24 Jun 2002 19:09:42 -0000
*************** finish_struct (t, attributes)
*** 5310,5321 ****
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));
! }
return t;
}
--- 5310,5317 ----
else
error ("trying to finish struct, but kicked out due to previous parse errors");
! if (processing_template_decl && at_function_scope_p ())
! add_stmt (build_min (TAG_DEFN, t));
return t;
}
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.720
diff -c -p -r1.720 cp-tree.h
*** cp-tree.h 23 Jun 2002 20:10:06 -0000 1.720
--- cp-tree.h 24 Jun 2002 19:09:43 -0000
*************** extern int flag_new_for_scope;
*** 2546,2551 ****
--- 2546,2562 ----
#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))
*************** extern void begin_only_namespace_names
*** 3812,3817 ****
--- 3823,3829 ----
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));
*************** extern void init_search_processing PARA
*** 4174,4179 ****
--- 4186,4192 ----
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));
*************** extern tree finish_pseudo_destructor_cal
*** 4261,4266 ****
--- 4274,4280 ----
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));
Index: decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.911
diff -c -p -r1.911 decl.c
*** decl.c 4 Jun 2002 07:10:04 -0000 1.911
--- decl.c 24 Jun 2002 19:09:46 -0000
*************** warn_about_implicit_typename_lookup (typ
*** 5921,5926 ****
--- 5921,5985 ----
}
}
+ /* 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
*************** finish_enum (enumtype)
*** 13171,13181 ****
postponed until the template is instantiated. */
if (processing_template_decl)
{
! tree scope = current_scope ();
! if (scope && TREE_CODE (scope) == FUNCTION_DECL)
add_stmt (build_min (TAG_DEFN, enumtype));
-
-
return;
}
--- 13230,13237 ----
postponed until the template is instantiated. */
if (processing_template_decl)
{
! if (at_function_scope_p ())
add_stmt (build_min (TAG_DEFN, enumtype));
return;
}
Index: lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.285
diff -c -p -r1.285 lex.c
*** lex.c 23 Jun 2002 20:10:08 -0000 1.285
--- lex.c 24 Jun 2002 19:09:47 -0000
*************** do_identifier (token, parsing, args)
*** 1208,1252 ****
}
}
! 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);
! }
! }
! }
/* TREE_USED is set in `hack_identifier'. */
if (TREE_CODE (id) == CONST_DECL)
{
--- 1208,1215 ----
}
}
! id = check_for_out_of_scope_variable (id);
!
/* TREE_USED is set in `hack_identifier'. */
if (TREE_CODE (id) == CONST_DECL)
{
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parse.y,v
retrieving revision 1.264
diff -c -p -r1.264 parse.y
*** parse.y 23 Jun 2002 20:10:08 -0000 1.264
--- parse.y 24 Jun 2002 19:09:47 -0000
*************** check_class_key (key, aggr)
*** 308,314 ****
/* __func__, __FUNCTION__ or __PRETTY_FUNCTION__.
yylval contains an IDENTIFIER_NODE which indicates which one. */
! %token VAR_FUNC_NAME
/* String constants in raw form.
yylval is a STRING_CST node. */
--- 308,314 ----
/* __func__, __FUNCTION__ or __PRETTY_FUNCTION__.
yylval contains an IDENTIFIER_NODE which indicates which one. */
! %token <ttype> VAR_FUNC_NAME
/* String constants in raw form.
yylval is a STRING_CST node. */
*************** primary:
*** 1624,1634 ****
TYPE_DOMAIN (TREE_TYPE ($$)));
}
| VAR_FUNC_NAME
! {
! $$ = fname_decl (C_RID_CODE ($$), $$);
! if (processing_template_decl)
! $$ = build_min_nt (LOOKUP_EXPR, DECL_NAME ($$));
! }
| '(' expr ')'
{ $$ = finish_parenthesized_expr ($2); }
| '(' expr_or_declarator_intern ')'
--- 1624,1630 ----
TYPE_DOMAIN (TREE_TYPE ($$)));
}
| VAR_FUNC_NAME
! { $$ = finish_fname ($1); }
| '(' expr ')'
{ $$ = finish_parenthesized_expr ($2); }
| '(' expr_or_declarator_intern ')'
*************** primary:
*** 1637,1644 ****
| '(' error ')'
{ $$ = error_mark_node; }
| '('
! { tree scope = current_scope ();
! if (!scope || TREE_CODE (scope) != FUNCTION_DECL)
{
error ("braced-group within expression allowed only inside a function");
YYERROR;
--- 1633,1639 ----
| '(' error ')'
{ $$ = error_mark_node; }
| '('
! { if (!at_function_scope_p ())
{
error ("braced-group within expression allowed only inside a function");
YYERROR;
Index: search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.229
diff -c -p -r1.229 search.c
*** search.c 4 Jun 2002 07:10:21 -0000 1.229
--- search.c 24 Jun 2002 19:09:48 -0000
*************** at_function_scope_p ()
*** 581,586 ****
--- 581,595 ----
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
Index: semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.264
diff -c -p -r1.264 semantics.c
*** semantics.c 18 Jun 2002 16:21:25 -0000 1.264
--- semantics.c 24 Jun 2002 19:09:48 -0000
*************** finish_id_expr (expr)
*** 1437,1442 ****
--- 1437,1456 ----
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
*************** check_multiple_declarators ()
*** 2025,2033 ****
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)
/* It's OK to write `template <class T> void f() { int i, j;}'. */
return;
--- 2039,2045 ----
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; };'. */
! if (at_function_scope_p ())
/* It's OK to write `template <class T> void f() { int i, j;}'. */
return;