cp-tree.h (finish_base_specifier): New function.

* cp-tree.h (finish_base_specifier): New function.
	* parse.y (base_class): Use it.
	* semantics.c (finish_base_specifier): Define it.
	* parse.y (structsp): Warn on use of typename outside of template
	declarations.

From-SVN: r22055
This commit is contained in:
Mark Mitchell 1998-08-28 12:06:56 +00:00 committed by Mark Mitchell
parent 9231189b62
commit ea6021e832
6 changed files with 459 additions and 505 deletions

View file

@ -1,3 +1,12 @@
1998-08-28 Mark Mitchell <mark@markmitchell.com>
* cp-tree.h (finish_base_specifier): New function.
* parse.y (base_class): Use it.
* semantics.c (finish_base_specifier): Define it.
* parse.y (structsp): Warn on use of typename outside of template
declarations.
1998-08-27 Jason Merrill <jason@yorick.cygnus.com>
* lex.c (handle_cp_pragma): Remove #pragma vtable.

View file

@ -2943,6 +2943,7 @@ extern tree finish_member_class_template PROTO((tree, tree));
extern void finish_template_decl PROTO((tree));
extern tree finish_template_type PROTO((tree, tree, int));
extern void enter_scope_of PROTO((tree));
extern tree finish_base_specifier PROTO((tree, tree, int));
/* in sig.c */
extern tree build_signature_pointer_type PROTO((tree, int, int));

File diff suppressed because it is too large Load diff

View file

@ -2090,7 +2090,9 @@ structsp:
$$.new_type_flag = 0; }
| TYPENAME_KEYWORD typename_sub
{ $$.t = $2;
$$.new_type_flag = 0; }
$$.new_type_flag = 0;
if (!processing_template_decl)
cp_pedwarn ("using `typename' outside of template"); }
/* C++ extensions, merged with C to avoid shift/reduce conflicts */
| class_head left_curly
opt.component_decl_list '}' maybe_attribute
@ -2251,71 +2253,13 @@ base_class_list:
base_class:
base_class.1
{
tree type;
if ($1 == NULL_TREE)
{
error ("invalid base class");
type = error_mark_node;
}
else
type = TREE_TYPE ($1);
if (! is_aggr_type (type, 1))
$$ = NULL_TREE;
else if (current_aggr == signature_type_node
&& (! type) && (! IS_SIGNATURE (type)))
{
error ("class name not allowed as base signature");
$$ = NULL_TREE;
}
else if (current_aggr == signature_type_node)
{
sorry ("signature inheritance, base type `%s' ignored",
IDENTIFIER_POINTER ($$));
$$ = build_tree_list (access_public_node, type);
}
else if (type && IS_SIGNATURE (type))
{
error ("signature name not allowed as base class");
$$ = NULL_TREE;
}
else
$$ = build_tree_list (access_default_node, type);
}
{ $$ = finish_base_specifier (access_default_node, $1,
current_aggr
== signature_type_node); }
| base_class_access_list see_typename base_class.1
{
tree type;
if ($3 == NULL_TREE)
{
error ("invalid base class");
type = error_mark_node;
}
else
type = TREE_TYPE ($3);
if (current_aggr == signature_type_node)
error ("access and source specifiers not allowed in signature");
if (! is_aggr_type (type, 1))
$$ = NULL_TREE;
else if (current_aggr == signature_type_node
&& (! type) && (! IS_SIGNATURE (type)))
{
error ("class name not allowed as base signature");
$$ = NULL_TREE;
}
else if (current_aggr == signature_type_node)
{
sorry ("signature inheritance, base type `%s' ignored",
IDENTIFIER_POINTER ($$));
$$ = build_tree_list (access_public_node, type);
}
else if (type && IS_SIGNATURE (type))
{
error ("signature name not allowed as base class");
$$ = NULL_TREE;
}
else
$$ = build_tree_list ($$, type);
}
{ $$ = finish_base_specifier ($1, $3,
current_aggr
== signature_type_node); }
;
base_class.1:
@ -2868,7 +2812,6 @@ functional_cast:
| typespec fcast_or_absdcl %prec EMPTY
{ $$ = reparse_absdcl_as_expr ($1.t, $2); }
;
type_name:
TYPENAME
| SELFNAME

View file

@ -1436,3 +1436,53 @@ enter_scope_of (sr)
TREE_COMPLEXITY (sr) = current_class_depth;
}
}
/* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER.
Return a TREE_LIST containing the ACCESS_SPECIFIER and the
BASE_CLASS, or NULL_TREE if an error occurred. The
ACCESSS_SPECIFIER is one of
access_{default,public,protected_private}[_virtual]_node.*/
tree
finish_base_specifier (access_specifier, base_class,
current_aggr_is_signature)
tree access_specifier;
tree base_class;
int current_aggr_is_signature;
{
tree type;
tree result;
if (base_class == NULL_TREE)
{
error ("invalid base class");
type = error_mark_node;
}
else
type = TREE_TYPE (base_class);
if (current_aggr_is_signature && access_specifier)
error ("access and source specifiers not allowed in signature");
if (! is_aggr_type (type, 1))
result = NULL_TREE;
else if (current_aggr_is_signature
&& (! type) && (! IS_SIGNATURE (type)))
{
error ("class name not allowed as base signature");
result = NULL_TREE;
}
else if (current_aggr_is_signature)
{
sorry ("signature inheritance, base type `%s' ignored",
IDENTIFIER_POINTER (access_specifier));
result = build_tree_list (access_public_node, type);
}
else if (type && IS_SIGNATURE (type))
{
error ("signature name not allowed as base class");
result = NULL_TREE;
}
else
result = build_tree_list (access_specifier, type);
return result;
}

View file

@ -0,0 +1,7 @@
// Build don't link:
struct S {
typedef int I;
};
void f(typename S::I); // ERROR - using typename outside of template