Commit 45869a6c by Mark Mitchell

cp-tree.def (TYPENAME_TYPE): Add to documentation.

	* cp-tree.def (TYPENAME_TYPE): Add to documentation.
	* cp-tree.h (TYPENAME_TYPE_FULLNAME): Document.
	(build_typename_type): New function.
	* decl.c (build_typename_type): Broken out from ...
	(make_typename_type): Use it.
	* search.c (lookup_field): Likewise.

From-SVN: r23110
parent 80fba193
...@@ -143,7 +143,10 @@ DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", 't', 0) ...@@ -143,7 +143,10 @@ DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", 't', 0)
The TYPE_FIELDS value will be a TEMPLATE_PARM_INDEX. */ The TYPE_FIELDS value will be a TEMPLATE_PARM_INDEX. */
DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", 't', 0) DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", 't', 0)
/* A type designated by 'typename T::t'. */ /* A type designated by `typename T::t'. TYPE_CONTEXT is `T',
TYPE_NAME is a TYPE_DECL for `t'. If TREE_TYPE is present, this
type was generated by the implicit typename extension, and the
TREE_TYPE is a _TYPE from a baseclass of `T'. */
DEFTREECODE (TYPENAME_TYPE, "typename_type", 't', 0) DEFTREECODE (TYPENAME_TYPE, "typename_type", 't', 0)
/* A thunk is a stub function. /* A thunk is a stub function.
......
...@@ -1337,6 +1337,10 @@ struct lang_decl ...@@ -1337,6 +1337,10 @@ struct lang_decl
&& !CLASSTYPE_USE_TEMPLATE (NODE) \ && !CLASSTYPE_USE_TEMPLATE (NODE) \
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))) && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))
/* The name used by the user to name the typename type. Typically,
this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the
corresponding TYPE_DECL. However, this may also be a
TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'. */
#define TYPENAME_TYPE_FULLNAME(NODE) CLASSTYPE_SIZE (NODE) #define TYPENAME_TYPE_FULLNAME(NODE) CLASSTYPE_SIZE (NODE)
/* Nonzero in INTEGER_CST means that this int is negative by dint of /* Nonzero in INTEGER_CST means that this int is negative by dint of
...@@ -2543,6 +2547,7 @@ extern tree binding_for_name PROTO((tree, tree)); ...@@ -2543,6 +2547,7 @@ extern tree binding_for_name PROTO((tree, tree));
extern tree namespace_binding PROTO((tree, tree)); extern tree namespace_binding PROTO((tree, tree));
extern void set_namespace_binding PROTO((tree, tree, tree)); extern void set_namespace_binding PROTO((tree, tree, tree));
extern tree lookup_namespace_name PROTO((tree, tree)); extern tree lookup_namespace_name PROTO((tree, tree));
extern tree build_typename_type PROTO((tree, tree, tree, tree));
extern tree make_typename_type PROTO((tree, tree)); extern tree make_typename_type PROTO((tree, tree));
extern tree lookup_name_nonclass PROTO((tree)); extern tree lookup_name_nonclass PROTO((tree));
extern tree lookup_function_nonclass PROTO((tree, tree)); extern tree lookup_function_nonclass PROTO((tree, tree));
......
...@@ -4776,11 +4776,51 @@ lookup_namespace_name (namespace, name) ...@@ -4776,11 +4776,51 @@ lookup_namespace_name (namespace, name)
return error_mark_node; return error_mark_node;
} }
/* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is
the type of `T', NAME is the IDENTIFIER_NODE for `t'. If BASE_TYPE
is non-NULL, this type is being created by the implicit typename
extension, and BASE_TYPE is a type named `t' in some base class of
`T' which depends on template parameters.
Returns the new TYPENAME_TYPE. */
tree
build_typename_type (context, name, fullname, base_type)
tree context;
tree name;
tree fullname;
tree base_type;
{
tree t;
tree d;
if (processing_template_decl)
push_obstacks (&permanent_obstack, &permanent_obstack);
/* Build the TYPENAME_TYPE. */
t = make_lang_type (TYPENAME_TYPE);
TYPE_CONTEXT (t) = FROB_CONTEXT (context);
TYPENAME_TYPE_FULLNAME (t) = fullname;
TREE_TYPE (t) = base_type;
CLASSTYPE_GOT_SEMICOLON (t) = 1;
/* Build the corresponding TYPE_DECL. */
d = build_decl (TYPE_DECL, name, t);
TYPE_NAME (TREE_TYPE (d)) = d;
TYPE_STUB_DECL (TREE_TYPE (d)) = d;
DECL_CONTEXT (d) = FROB_CONTEXT (context);
if (processing_template_decl)
pop_obstacks ();
return t;
}
tree tree
make_typename_type (context, name) make_typename_type (context, name)
tree context, name; tree context, name;
{ {
tree t, d; tree t;
tree fullname; tree fullname;
if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
...@@ -4846,22 +4886,8 @@ make_typename_type (context, name) ...@@ -4846,22 +4886,8 @@ make_typename_type (context, name)
return TREE_TYPE (t); return TREE_TYPE (t);
} }
} }
if (processing_template_decl) return build_typename_type (context, name, fullname, NULL_TREE);
push_obstacks (&permanent_obstack, &permanent_obstack);
t = make_lang_type (TYPENAME_TYPE);
TYPENAME_TYPE_FULLNAME (t) = fullname;
d = build_decl (TYPE_DECL, name, t);
if (processing_template_decl)
pop_obstacks ();
TYPE_CONTEXT (t) = FROB_CONTEXT (context);
TYPE_NAME (TREE_TYPE (d)) = d;
TYPE_STUB_DECL (TREE_TYPE (d)) = d;
DECL_CONTEXT (d) = FROB_CONTEXT (context);
CLASSTYPE_GOT_SEMICOLON (t) = 1;
return t;
} }
/* Select the right _DECL from multiple choices. */ /* Select the right _DECL from multiple choices. */
......
...@@ -1178,7 +1178,14 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1178,7 +1178,14 @@ lookup_field (xbasetype, name, protect, want_type)
rval = error_mark_node; rval = error_mark_node;
} }
/* Do implicit typename stuff. */ /* Do implicit typename stuff. This code also handles out-of-class
definitions of nested classes whose enclosing class is a
template. For example:
template <class T> struct S { struct I { void f(); }; };
template <class T> void S<T>::I::f() {}
will come through here to handle `S<T>::I'. */
if (rval && TREE_CODE (rval) == TYPE_DECL if (rval && TREE_CODE (rval) == TYPE_DECL
&& processing_template_decl && processing_template_decl
&& ! currently_open_class (BINFO_TYPE (rval_binfo)) && ! currently_open_class (BINFO_TYPE (rval_binfo))
...@@ -1191,9 +1198,9 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1191,9 +1198,9 @@ lookup_field (xbasetype, name, protect, want_type)
== current_class_type)) == current_class_type))
break; break;
entry = make_typename_type (BINFO_TYPE (binfo), name); entry = build_typename_type (BINFO_TYPE (binfo), name, name,
TREE_TYPE (entry) = TREE_TYPE (rval); TREE_TYPE (rval));
rval = TYPE_MAIN_DECL (entry); return TYPE_STUB_DECL (entry);
} }
return rval; return rval;
......
// Build don't link:
// Special g++ Options:
template <class T>
struct B {
typedef T X;
};
template <class T>
struct S : public B<T>
{
struct I {
void f(X x);
};
};
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