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
This commit is contained in:
Alex Samuel 1999-09-02 17:29:11 +00:00 committed by Mark Mitchell
parent d0668a7393
commit ec4f972f6c
5 changed files with 155 additions and 31 deletions

View File

@ -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.

View File

@ -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
{

View File

@ -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("::");
}

View File

@ -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;
}

View File

@ -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;
}