Commit 3d7de1fa by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (lang_type): Add documentation.

	* cp-tree.h (lang_type): Add documentation.
	* decl2.c (handle_class_head): Create template declarations here,
	as appropriate.
	* parse.y (class_head): Return whether or not we entered a new
	scope, as well as the type named.
	(named_class_head): Likewise.
	(named_complex_class_head_sans_basetype): Likewise.
	(structsp): Adjust accordingly.  Pop scope when required.
	* parse.c: Regenerated.
	* pt.c (check_default_tmpl_args): Robustify.
	(redeclare_class_template): Likewise.
	(instantiate_class_template): An instantiation of an
	anonymous union is itself an anonymous union.
	* semantics.c (begin_class_definition): Don't create template
	declarations here.

From-SVN: r26475
parent 08967681
1999-04-15 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (lang_type): Add documentation.
* decl2.c (handle_class_head): Create template declarations here,
as appropriate.
* parse.y (class_head): Return whether or not we entered a new
scope, as well as the type named.
(named_class_head): Likewise.
(named_complex_class_head_sans_basetype): Likewise.
(structsp): Adjust accordingly. Pop scope when required.
* parse.c: Regenerated.
* pt.c (check_default_tmpl_args): Robustify.
(redeclare_class_template): Likewise.
(instantiate_class_template): An instantiation of an
anonymous union is itself an anonymous union.
* semantics.c (begin_class_definition): Don't create template
declarations here.
1999-04-15 Jason Merrill <jason@yorick.cygnus.com>
* parse.y (after_type_declarator_intern): New nonterminal.
......@@ -23,7 +41,7 @@
(pop_nested_class): Likewise.
* decl.c (poplevel_class): Declare it here, and make it static.
(poplevel): Handle class scopes.
(pop_level_class): Don't take an rgument. Simplify.
(poplevel_class): Don't take an rgument. Simplify.
(pop_everything): Pass no arguments to pop_nested_class.
(cp_finish_decl): Pass no arguments to popclass.
(grokdeclarator): Pass no arguments to pop_nested_class.
......
......@@ -737,6 +737,9 @@ struct lang_type
unsigned is_partial_instantiation : 1;
unsigned has_mutable : 1;
unsigned com_interface : 1;
/* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template.
If so, make sure to copy it in instantiate_class_template! */
/* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a
......
......@@ -5040,23 +5040,41 @@ mark_used (decl)
instantiate_decl (decl);
}
/* Helper function for named_class_head_sans_basetype nonterminal. */
/* Helper function for named_class_head_sans_basetype nonterminal. We
have just seen something of the form `AGGR SCOPE::ID'. Return a
TYPE_DECL for the type declared by ID in SCOPE. */
tree
handle_class_head (aggr, scope, id)
tree aggr, scope, id;
{
tree decl;
if (TREE_CODE (id) == TYPE_DECL)
return id;
if (DECL_CLASS_TEMPLATE_P (id))
return DECL_TEMPLATE_RESULT (id);
decl = id;
else if (DECL_CLASS_TEMPLATE_P (id))
decl = DECL_TEMPLATE_RESULT (id);
else
{
if (scope)
cp_error ("`%T' does not have a nested type named `%D'", scope, id);
else
cp_error ("no file-scope type named `%D'", id);
decl = TYPE_MAIN_DECL (xref_tag (aggr, make_anon_name (), 1));
}
if (scope)
cp_error ("`%T' does not have a nested type named `%D'", scope, id);
else
cp_error ("no file-scope type named `%D'", id);
/* This syntax is only allowed when we're defining a type, so we
enter the SCOPE. */
push_scope (CP_DECL_CONTEXT (decl));
/* If we see something like:
id = xref_tag
(aggr, make_anon_name (), 1);
return TYPE_MAIN_DECL (id);
template <typename T> struct S::I ....
we must create a TEMPLATE_DECL for the nested type. */
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
decl = push_template_decl (decl);
return decl;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -239,10 +239,11 @@ empty_parms ()
%type <ttype> component_constructor_declarator
%type <ttype> fn.def2 return_id fn.defpen constructor_declarator
%type <itype> ctor_initializer_opt function_try_block
%type <ttype> named_class_head named_class_head_sans_basetype
%type <ttype> named_complex_class_head_sans_basetype
%type <ttype> named_class_head_sans_basetype
%type <ftype> class_head named_class_head
%type <ftype> named_complex_class_head_sans_basetype
%type <ttype> unnamed_class_head
%type <ttype> class_head base_class_list
%type <ttype> base_class_list
%type <ttype> base_class_access_list
%type <ttype> base_class maybe_base_class_list base_class.1
%type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers
......@@ -2140,7 +2141,7 @@ structsp:
cp_pedwarn ("using `typename' outside of template"); }
/* C++ extensions, merged with C to avoid shift/reduce conflicts */
| class_head '{'
{ $<ttype>1 = begin_class_definition ($<ttype>1); }
{ $1.t = begin_class_definition ($1.t); }
opt.component_decl_list '}' maybe_attribute
{
int semi;
......@@ -2149,7 +2150,7 @@ structsp:
yychar = YYLEX;
semi = yychar == ';';
$<ttype>$ = finish_class_definition ($1, $6, semi);
$<ttype>$ = finish_class_definition ($1.t, $6, semi);
}
pending_defargs
{
......@@ -2158,20 +2159,24 @@ structsp:
pending_inlines
{
finish_inline_definitions ();
if ($1.new_type_flag)
pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL ($<ttype>7)));
$$.t = $<ttype>7;
$$.new_type_flag = 1;
}
| class_head %prec EMPTY
{
if ($1.new_type_flag)
pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL ($1.t)));
$$.new_type_flag = 0;
if (TYPE_BINFO ($1) == NULL_TREE)
if (TYPE_BINFO ($1.t) == NULL_TREE)
{
cp_error ("%T is not a class type", $1);
cp_error ("%T is not a class type", $1.t);
$$.t = error_mark_node;
}
else
{
$$.t = $1;
$$.t = $1.t;
/* struct B: public A; is not accepted by the WP grammar. */
if (TYPE_BINFO_BASETYPES ($$.t) && !TYPE_SIZE ($$.t)
&& ! TYPE_BEING_DEFINED ($$.t))
......@@ -2228,63 +2233,77 @@ named_complex_class_head_sans_basetype:
aggr nested_name_specifier identifier
{
current_aggr = $1;
$$ = handle_class_head ($1, $2, $3);
$$.t = handle_class_head ($1, $2, $3);
$$.new_type_flag = 1;
}
| aggr global_scope nested_name_specifier identifier
{
current_aggr = $1;
$$ = handle_class_head ($1, $3, $4);
$$.t = handle_class_head ($1, $3, $4);
$$.new_type_flag = 1;
}
| aggr global_scope identifier
{
current_aggr = $1;
$$ = handle_class_head ($1, NULL_TREE, $3);
$$.t = handle_class_head ($1, NULL_TREE, $3);
$$.new_type_flag = 1;
}
| aggr apparent_template_type
{ current_aggr = $$; $$ = $2; }
{
current_aggr = $1;
$$.t = $2;
$$.new_type_flag = 0;
}
| aggr nested_name_specifier apparent_template_type
{ current_aggr = $$; $$ = $3; }
{
current_aggr = $1;
$$.t = $3;
if (CP_DECL_CONTEXT ($$.t))
push_scope (CP_DECL_CONTEXT ($$.t));
$$.new_type_flag = 1;
}
;
named_class_head:
named_class_head_sans_basetype %prec EMPTY
{ $$ = xref_tag (current_aggr, $1, 1); }
{
$$.t = xref_tag (current_aggr, $1, 1);
$$.new_type_flag = 0;
}
| named_class_head_sans_basetype_defn
{ $<ttype>$ = xref_tag (current_aggr, $1, 0); }
/* Class name is unqualified, so we look for base classes
in the current scope. */
maybe_base_class_list %prec EMPTY
{
$$ = $<ttype>2;
$$.t = $<ttype>2;
$$.new_type_flag = 0;
if ($3)
xref_basetypes (current_aggr, $1, $<ttype>2, $3);
}
| named_complex_class_head_sans_basetype
{
if ($1 != error_mark_node)
push_scope (CP_DECL_CONTEXT ($1));
}
maybe_base_class_list
{
if ($1 != error_mark_node)
if ($1.t != error_mark_node)
{
pop_scope (CP_DECL_CONTEXT ($1));
$$ = TREE_TYPE ($1);
$$.t = TREE_TYPE ($1.t);
$$.new_type_flag = $1.new_type_flag;
if (current_aggr == union_type_node
&& TREE_CODE ($$) != UNION_TYPE)
cp_pedwarn ("`union' tag used in declaring `%#T'", $$);
else if (TREE_CODE ($$) == UNION_TYPE
&& TREE_CODE ($$.t) != UNION_TYPE)
cp_pedwarn ("`union' tag used in declaring `%#T'",
$$.t);
else if (TREE_CODE ($$.t) == UNION_TYPE
&& current_aggr != union_type_node)
cp_pedwarn ("non-`union' tag used in declaring `%#T'", $$);
else if (TREE_CODE ($$) == RECORD_TYPE)
else if (TREE_CODE ($$.t) == RECORD_TYPE)
/* We might be specializing a template with a different
class-key; deal. */
CLASSTYPE_DECLARED_CLASS ($$) = (current_aggr
== class_type_node);
if ($3)
CLASSTYPE_DECLARED_CLASS ($$.t)
= (current_aggr == class_type_node);
if ($2)
{
maybe_process_partial_specialization ($$);
xref_basetypes (current_aggr, $1, $$, $3);
maybe_process_partial_specialization ($$.t);
xref_basetypes (current_aggr, $1.t, $$.t, $2);
}
}
}
......@@ -2296,8 +2315,16 @@ unnamed_class_head:
yyungetc ('{', 1); }
;
/* The tree output of this nonterminal a declarationf or the type
named. If NEW_TYPE_FLAG is set, then the name used in this
class-head was explicitly qualified, e.g.: `struct X::Y'. We have
already called push_scope for X. */
class_head:
unnamed_class_head
{
$$.t = $1;
$$.new_type_flag = 0;
}
| named_class_head
;
......
......@@ -2170,6 +2170,7 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
if (current_class_type
&& !TYPE_BEING_DEFINED (current_class_type)
&& DECL_REAL_CONTEXT (decl) == current_class_type
&& DECL_LANG_SPECIFIC (decl)
&& DECL_DEFINED_IN_CLASS_P (decl))
/* We already checked these parameters when the template was
declared, so there's no need to do it again now. This is an
......@@ -2495,10 +2496,17 @@ redeclare_class_template (type, parms)
tree type;
tree parms;
{
tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
tree tmpl;
tree tmpl_parms;
int i;
if (!TYPE_TEMPLATE_INFO (type))
{
cp_error ("`%T' is not a template type", type);
return;
}
tmpl = TYPE_TI_TEMPLATE (type);
if (!PRIMARY_TEMPLATE_P (tmpl))
/* The type is nested in some template class. Nothing to worry
about here; there are no new template parameters for the nested
......@@ -4816,6 +4824,8 @@ instantiate_class_template (type)
TYPE_PACKED (type) = TYPE_PACKED (pattern);
TYPE_ALIGN (type) = TYPE_ALIGN (pattern);
TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */
if (ANON_UNION_TYPE_P (pattern))
SET_ANON_UNION_TYPE_P (type);
/* We must copy the arguments to the permanent obstack since
during the tsubst'ing below they may wind up in the
......
......@@ -1290,11 +1290,6 @@ begin_class_definition (t)
pushtag (TYPE_IDENTIFIER (t), t, 0);
}
maybe_process_partial_specialization (t);
if (processing_template_decl
&& ! CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
&& TYPE_CONTEXT (t) && TYPE_P (TYPE_CONTEXT (t))
&& ! current_class_type)
push_template_decl (TYPE_STUB_DECL (t));
pushclass (t, 1);
TYPE_BEING_DEFINED (t) = 1;
/* Reset the interface data, at the earliest possible
......
// Origin: Mark Mitchell <mark@codesourcery.com>
int main()
{
typedef double I;
struct S1 {
typedef char I;
struct S2;
};
struct S1::S2 {
typedef I J;
};
return !(sizeof (S1::S2::J) == 1);
}
// Build don't link:
// Origin: David Mazieres <dm@amsterdam.lcs.mit.edu>
template<class T> struct vector_base {
typedef T elm_t;
protected:
union {
double alignment_hack;
char defbuf_space[2 * sizeof (elm_t)];
};
elm_t *def_basep () { return reinterpret_cast<elm_t *> (defbuf_space); }
};
template<class T> struct vector : public vector_base<T> {
vector () { def_basep (); }
};
vector<int> iv;
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