aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog16
-rw-r--r--gcc/cp/cp-tree.h20
-rw-r--r--gcc/cp/lex.c65
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/search.c9
-rw-r--r--gcc/testsuite/g++.dg/template/ttp1.C9
-rw-r--r--gcc/testsuite/g++.dg/template/typename1.C9
7 files changed, 112 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 58e1f98..2b1b453 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,21 @@
2001-10-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ * cp-tree.h (TYPE_BINFO): Update comment.
+ (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): New macro.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Use template_info.
+ (TYPENAME_TYPE_FULLNAME): Use TYPE_FIELDS.
+ (copy_type): Prototype new function.
+ * lex.c (copy_lang_decl): Gather tree node statistics.
+ (copy_lang_type): New function.
+ (copy_type): Likewise.
+ (cp_make_lang_type): Create lang_type for
+ BOUND_TEMPLATE_TEMPLATE_PARM. Set TYPE_BINFO for TYPENAME_TYPE
+ and BOUND_TEMPLATE_TEMPLATE_PARM.
+ * pt.c (tsubst): Use copy_type instead of copy_node.
+ * search.c (lookup_field_1): Ignore TYPENAME_TYPE.
+
+2001-10-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
* pt.c (determine_specialization): Ignore functions without
DECL_TEMPLATE_INFO.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4f6bcab..34ef95a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -114,9 +114,6 @@ Boston, MA 02111-1307, USA. */
TYPE_BINFO
For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO.
- For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME.
- For a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM,
- this is TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
For a FUNCTION_TYPE or METHOD_TYPE, this is TYPE_RAISES_EXCEPTIONS
BINFO_VIRTUALS
@@ -193,6 +190,14 @@ Boston, MA 02111-1307, USA. */
__FUNCTION__); \
__t; })
+#define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) \
+({ const tree __t = NODE; \
+ enum tree_code __c = TREE_CODE(__t); \
+ if (__c != BOUND_TEMPLATE_TEMPLATE_PARM) \
+ tree_check_failed (__t, BOUND_TEMPLATE_TEMPLATE_PARM, \
+ __FILE__, __LINE__, __FUNCTION__); \
+ __t; })
+
#else /* not ENABLE_TREE_CHECKING, or not gcc */
#define VAR_OR_FUNCTION_DECL_CHECK(NODE) NODE
@@ -2147,8 +2152,10 @@ struct lang_decl
non-type template parameters. */
#define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (ENUMERAL_TYPE_CHECK (NODE)))
-/* Template information for a bound template template parameter. */
-#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE))
+/* Template information for a template template parameter. */
+#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) \
+ (TYPE_LANG_SPECIFIC(BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \
+ ->template_info)
/* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */
#define TYPE_TEMPLATE_INFO(NODE) \
@@ -2311,7 +2318,7 @@ struct lang_decl
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) TYPE_BINFO (NODE)
+#define TYPENAME_TYPE_FULLNAME(NODE) (TYPE_FIELDS (NODE))
/* Nonzero if NODE is an implicit typename. */
#define IMPLICIT_TYPENAME_P(NODE) \
@@ -3859,6 +3866,7 @@ extern tree identifier_typedecl_value PARAMS ((tree));
extern tree build_lang_decl PARAMS ((enum tree_code, tree, tree));
extern void retrofit_lang_decl PARAMS ((tree));
extern tree copy_decl PARAMS ((tree));
+extern tree copy_type PARAMS ((tree));
extern tree cp_make_lang_type PARAMS ((enum tree_code));
extern tree make_aggr_type PARAMS ((enum tree_code));
extern void compiler_error PARAMS ((const char *, ...))
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 57daab4..ec44566 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -1552,6 +1552,11 @@ copy_lang_decl (node)
ld = (struct lang_decl *) ggc_alloc (size);
memcpy (ld, DECL_LANG_SPECIFIC (node), size);
DECL_LANG_SPECIFIC (node) = ld;
+
+#ifdef GATHER_STATISTICS
+ tree_node_counts[(int)lang_decl] += 1;
+ tree_node_sizes[(int)lang_decl] += size;
+#endif
}
/* Copy DECL, including any language-specific parts. */
@@ -1567,14 +1572,51 @@ copy_decl (decl)
return copy;
}
+/* Replace the shared language-specific parts of NODE with a new copy. */
+
+void
+copy_lang_type (node)
+ tree node;
+{
+ int size;
+ struct lang_type *lt;
+
+ if (! TYPE_LANG_SPECIFIC (node))
+ return;
+
+ size = sizeof (struct lang_type);
+ lt = (struct lang_type *) ggc_alloc (size);
+ memcpy (lt, TYPE_LANG_SPECIFIC (node), size);
+ TYPE_LANG_SPECIFIC (node) = lt;
+
+#ifdef GATHER_STATISTICS
+ tree_node_counts[(int)lang_type] += 1;
+ tree_node_sizes[(int)lang_type] += size;
+#endif
+}
+
+/* Copy TYPE, including any language-specific parts. */
+
+tree
+copy_type (type)
+ tree type;
+{
+ tree copy;
+
+ copy = copy_node (type);
+ copy_lang_type (copy);
+ return copy;
+}
+
tree
cp_make_lang_type (code)
enum tree_code code;
{
register tree t = make_node (code);
- /* Set up some flags that give proper default behavior. */
- if (IS_AGGR_TYPE_CODE (code))
+ /* Create lang_type structure. */
+ if (IS_AGGR_TYPE_CODE (code)
+ || code == BOUND_TEMPLATE_TEMPLATE_PARM)
{
struct lang_type *pi;
@@ -1582,6 +1624,16 @@ cp_make_lang_type (code)
ggc_alloc_cleared (sizeof (struct lang_type)));
TYPE_LANG_SPECIFIC (t) = pi;
+
+#ifdef GATHER_STATISTICS
+ tree_node_counts[(int)lang_type] += 1;
+ tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
+#endif
+ }
+
+ /* Set up some flags that give proper default behavior. */
+ if (IS_AGGR_TYPE_CODE (code))
+ {
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
@@ -1589,11 +1641,6 @@ cp_make_lang_type (code)
presence of parse errors, the normal was of assuring this
might not ever get executed, so we lay it out *immediately*. */
build_pointer_type (t);
-
-#ifdef GATHER_STATISTICS
- tree_node_counts[(int)lang_type] += 1;
- tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
-#endif
}
else
/* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits. But,
@@ -1605,7 +1652,9 @@ cp_make_lang_type (code)
since they can be virtual base types, and we then need a
canonical binfo for them. Ideally, this would be done lazily for
all types. */
- if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM)
+ if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM
+ || code == BOUND_TEMPLATE_TEMPLATE_PARM
+ || code == TYPENAME_TYPE)
TYPE_BINFO (t) = make_binfo (size_zero_node, t, NULL_TREE, NULL_TREE);
return t;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 229bccc..cd68629 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6429,7 +6429,7 @@ tsubst (t, args, complain, in_decl)
}
else
{
- r = copy_node (t);
+ r = copy_type (t);
TEMPLATE_TYPE_PARM_INDEX (r)
= reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
r, levels);
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index f543f0d..4c3249b 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -564,11 +564,14 @@ lookup_field_1 (type, name)
register tree field;
if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
- || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
- /* The TYPE_FIELDS of a TEMPLATE_TYPE_PARM are not fields at all;
+ || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (type) == TYPENAME_TYPE)
+ /* The TYPE_FIELDS of a TEMPLATE_TYPE_PARM and
+ BOUND_TEMPLATE_TEMPLATE_PARM are not fields at all;
instead TYPE_FIELDS is the TEMPLATE_PARM_INDEX. (Miraculously,
the code often worked even when we treated the index as a list
- of fields!) */
+ of fields!)
+ The TYPE_FIELDS of TYPENAME_TYPE is its TYPENAME_TYPE_FULLNAME. */
return NULL_TREE;
if (TYPE_NAME (type)
diff --git a/gcc/testsuite/g++.dg/template/ttp1.C b/gcc/testsuite/g++.dg/template/ttp1.C
new file mode 100644
index 0000000..7b32302
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp1.C
@@ -0,0 +1,9 @@
+// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+// { dg-do compile }
+
+template <template <typename T> class A >
+class B : virtual A<void>
+{
+ typedef int INT;
+ INT i;
+};
diff --git a/gcc/testsuite/g++.dg/template/typename1.C b/gcc/testsuite/g++.dg/template/typename1.C
new file mode 100644
index 0000000..86658c5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typename1.C
@@ -0,0 +1,9 @@
+// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+// { dg-do compile }
+
+template <class T>
+class B : virtual T::A
+{
+ typedef int INT;
+ INT i;
+};