aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mmitchel@gcc.gnu.org>1998-10-15 11:27:43 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-10-15 11:27:43 +0000
commit45869a6cab14c0904d21a0a6699dee73d9cbbe4b (patch)
tree2411eb0474f73e5c07a2298b3088b34464cf149a /gcc/cp
parent80fba193dd65d41044e3175d95e5a3b29d2ab353 (diff)
downloadgcc-45869a6cab14c0904d21a0a6699dee73d9cbbe4b.zip
gcc-45869a6cab14c0904d21a0a6699dee73d9cbbe4b.tar.gz
gcc-45869a6cab14c0904d21a0a6699dee73d9cbbe4b.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/cp-tree.def5
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/decl.c60
-rw-r--r--gcc/cp/search.c15
4 files changed, 63 insertions, 22 deletions
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 20a0117..2b24969 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -143,7 +143,10 @@ DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", 't', 0)
The TYPE_FIELDS value will be a TEMPLATE_PARM_INDEX. */
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)
/* A thunk is a stub function.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6632f8a..6a74d26 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1337,6 +1337,10 @@ struct lang_decl
&& !CLASSTYPE_USE_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)
/* 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));
extern tree namespace_binding PROTO((tree, tree));
extern void set_namespace_binding PROTO((tree, 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 lookup_name_nonclass PROTO((tree));
extern tree lookup_function_nonclass PROTO((tree, tree));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 8d9337f..8facd96 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4776,11 +4776,51 @@ lookup_namespace_name (namespace, name)
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
make_typename_type (context, name)
tree context, name;
{
- tree t, d;
+ tree t;
tree fullname;
if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
@@ -4846,22 +4886,8 @@ make_typename_type (context, name)
return TREE_TYPE (t);
}
}
-
- if (processing_template_decl)
- 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;
+
+ return build_typename_type (context, name, fullname, NULL_TREE);
}
/* Select the right _DECL from multiple choices. */
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index be6cffc..50afeee 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1178,7 +1178,14 @@ lookup_field (xbasetype, name, protect, want_type)
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
&& processing_template_decl
&& ! currently_open_class (BINFO_TYPE (rval_binfo))
@@ -1191,9 +1198,9 @@ lookup_field (xbasetype, name, protect, want_type)
== current_class_type))
break;
- entry = make_typename_type (BINFO_TYPE (binfo), name);
- TREE_TYPE (entry) = TREE_TYPE (rval);
- rval = TYPE_MAIN_DECL (entry);
+ entry = build_typename_type (BINFO_TYPE (binfo), name, name,
+ TREE_TYPE (rval));
+ return TYPE_STUB_DECL (entry);
}
return rval;