diff options
author | Alex Samuel <samuel@codesourcery.com> | 1999-09-02 17:29:11 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-09-02 17:29:11 +0000 |
commit | ec4f972f6cd8c1801cb78b2e81c52529e70d39a5 (patch) | |
tree | 492aa30784ce56f2ba6a183212d10e2c1ca60463 /gcc | |
parent | d0668a73936a55ac7dbb3d62d94a9da6c1cc46cf (diff) | |
download | gcc-ec4f972f6cd8c1801cb78b2e81c52529e70d39a5.zip gcc-ec4f972f6cd8c1801cb78b2e81c52529e70d39a5.tar.gz gcc-ec4f972f6cd8c1801cb78b2e81c52529e70d39a5.tar.bz2 |
decl2.c (arg_assoc_template_arg): New prototype.
* decl2.c (arg_assoc_template_arg): New prototype. New function.
(arg_assoc_class): Use arg_assoc_template_arg for template
arguments.
(arg_assoc): Likewise.
* pt.c (mangle_class_name_for_template): Allow member template
template arguments.
From-SVN: r29060
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 74 | ||||
-rw-r--r-- | gcc/cp/pt.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/ttp57.C | 45 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/ttp58.C | 48 |
5 files changed, 155 insertions, 31 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0bf24e0..0577dfc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +1999-09-01 Alex Samuel <samuel@codesourcery.com> + + * decl2.c (arg_assoc_template_arg): New prototype. New function. + (arg_assoc_class): Use arg_assoc_template_arg for template + arguments. + (arg_assoc): Likewise. + * pt.c (mangle_class_name_for_template): Allow member template + template arguments. + 1999-09-02 Nathan Sidwell <nathan@acm.org> * call.c (build_conditional_expr): Warn on enum mismatches. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 5eb4a67..f2aebe6 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4544,6 +4544,7 @@ static int arg_assoc_type PROTO((struct arg_lookup*, tree)); static int add_function PROTO((struct arg_lookup *, tree)); static int arg_assoc_namespace PROTO((struct arg_lookup *, tree)); static int arg_assoc_class PROTO((struct arg_lookup *, tree)); +static int arg_assoc_template_arg PROTO((struct arg_lookup*, tree)); /* Add a function to the lookup structure. Returns 1 on error. */ @@ -4607,6 +4608,46 @@ arg_assoc_namespace (k, scope) return 0; } +/* Adds everything associated with a template argument to the lookup + structure. Returns 1 on error. */ + +static int +arg_assoc_template_arg (k, arg) + struct arg_lookup* k; + tree arg; +{ + /* [basic.lookup.koenig] + + If T is a template-id, its associated namespaces and classes are + ... the namespaces and classes associated with the types of the + template arguments provided for template type parameters + (excluding template template parameters); the namespaces in which + any template template arguments are defined; and the classes in + which any member templates used as template template arguments + are defined. [Note: non-type template arguments do not + contribute to the set of associated namespaces. ] */ + + /* Consider first template template arguments. */ + if (TREE_CODE (arg) == TEMPLATE_DECL) + { + tree ctx = CP_DECL_CONTEXT (arg); + + /* It's not a member template. */ + if (TREE_CODE (ctx) == NAMESPACE_DECL) + return arg_assoc_namespace (k, ctx); + /* Otherwise, it must be member template. */ + else + return arg_assoc_class (k, ctx); + } + /* It's not a template template argument, but it is a type template + argument. */ + else if (TREE_CODE_CLASS (TREE_CODE (arg)) == 't') + return arg_assoc_type (k, arg); + /* It's a non-type template argument. */ + else + return 0; +} + /* Adds everything associated with class to the lookup structure. Returns 1 on error. */ @@ -4653,8 +4694,8 @@ arg_assoc_class (k, type) if (CLASSTYPE_TEMPLATE_INFO (type)) { list = innermost_args (CLASSTYPE_TI_ARGS (type)); - for (i = 0; i < TREE_VEC_LENGTH (list); ++i) - arg_assoc (k, TREE_VEC_ELT (list, i)); + for (i = 0; i < TREE_VEC_LENGTH (list); ++i) + arg_assoc_template_arg (k, TREE_VEC_ELT (list, i)); } return 0; @@ -4761,14 +4802,7 @@ arg_assoc (k, n) If T is a template-id, its associated namespaces and classes are the namespace in which the template is defined; for - member templates, the member template's class; the namespaces - and classes associated with the types of the template - arguments provided for template type parameters (excluding - template template parameters); the namespaces in which any - template template arguments are defined; and the classes in - which any member templates used as template template - arguments are defined. [Note: non-type template arguments do - not contribute to the set of associated namespaces. ] */ + member templates, the member template's class... */ tree template = TREE_OPERAND (n, 0); tree args = TREE_OPERAND (n, 1); tree ctx; @@ -4793,24 +4827,8 @@ arg_assoc (k, n) /* Now the arguments. */ for (arg = args; arg != NULL_TREE; arg = TREE_CHAIN (arg)) - { - tree t = TREE_VALUE (arg); - - if (TREE_CODE (t) == TEMPLATE_DECL) - { - ctx = CP_DECL_CONTEXT (t); - if (TREE_CODE (ctx) == NAMESPACE_DECL) - { - if (arg_assoc_namespace (k, ctx) == 1) - return 1; - } - else if (arg_assoc_class (k, ctx) == 1) - return 1; - } - else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't' - && arg_assoc_type (k, t) == 1) - return 1; - } + if (arg_assoc_template_arg (k, TREE_VALUE (arg)) == 1) + return 1; } else { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 15d5fdf..bc50c0f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3538,9 +3538,13 @@ mangle_class_name_for_template (name, parms, arglist) /* Already substituted with real template. Just output the template name here */ tree context = DECL_CONTEXT (arg); - if (context) - { - my_friendly_assert (TREE_CODE (context) == NAMESPACE_DECL, 980422); + if (context) + { + /* The template may be defined in a namespace, or + may be a member template. */ + my_friendly_assert (TREE_CODE (context) == NAMESPACE_DECL + || CLASS_TYPE_P (context), + 980422); cat(decl_as_string (DECL_CONTEXT (arg), 0)); cat("::"); } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp57.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp57.C new file mode 100644 index 0000000..7c7c938 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/ttp57.C @@ -0,0 +1,45 @@ +// Build don't link: +// Origin: Alex Samuel <samuel@codesourcery.com> + +namespace NS +{ + +template <class T, int V> +struct Base +{ +}; + +template <class T> +struct Z +{ + const static int value_ = false; +}; + +template <class T> +struct A : + public Base <T, Z<T>::value_> +{ +}; + +template <class T> +void f(T) +{ +} + +} + + +template <template <class T> class U> +struct B +{ +}; + + +int +main () +{ + B<NS::A> ba; + f (ba); // Koenig lookup + return 0; +} + diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp58.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp58.C new file mode 100644 index 0000000..6620580 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/ttp58.C @@ -0,0 +1,48 @@ +// Build don't link: +// Origin: Alex Samuel <samuel@codesourcery.com> + +namespace NS +{ + +template <class T, int V> +struct Base +{ +}; + +template <class T> +struct Z +{ + const static int value_ = false; +}; + +class Outer +{ + template <class T> + struct A : + public Base <T, Z<T>::value_> + { + }; +}; + +template <class T> +void f(T) +{ +} + +} + + +template <template <class T> class U> +struct B +{ +}; + + +int +main () +{ + B<NS::Outer::A> ba; + f (ba); // Koenig lookup + return 0; +} + |