diff options
author | Mark Mitchell <mmitchel@gcc.gnu.org> | 1998-10-15 11:27:43 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1998-10-15 11:27:43 +0000 |
commit | 45869a6cab14c0904d21a0a6699dee73d9cbbe4b (patch) | |
tree | 2411eb0474f73e5c07a2298b3088b34464cf149a /gcc | |
parent | 80fba193dd65d41044e3175d95e5a3b29d2ab353 (diff) | |
download | gcc-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')
-rw-r--r-- | gcc/cp/cp-tree.def | 5 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/decl.c | 60 | ||||
-rw-r--r-- | gcc/cp/search.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/typename14.C | 15 |
5 files changed, 78 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; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename14.C b/gcc/testsuite/g++.old-deja/g++.pt/typename14.C new file mode 100644 index 0000000..7365b66 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/typename14.C @@ -0,0 +1,15 @@ +// 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); + }; +}; |