On 10/27/2011 03:10 PM, Dodji Seketeli wrote:
+/* Setter for the TYPE_DECL_ALIAS_P proprety above. */
+#define SET_TYPE_DECL_ALIAS_P(NODE, VAL) \
+ (DECL_LANG_FLAG_6 (TYPE_DECL_CHECK (NODE)) = (VAL))
This seems unnecessary.
+#define TYPE_DECL_NAMES_ALIAS_TEMPLATE_P(NODE) \
+ (TYPE_DECL_ALIAS_P (NODE) \
+ && DECL_LANG_SPECIFIC (NODE)
\
+ && DECL_TI_TEMPLATE (NODE) \
+ && same_type_p (TREE_TYPE (NODE), TREE_TYPE (DECL_TI_TEMPLATE (NODE))))
I don't think same_type_p is the test you want here, as it ignores
typedefs. How about
DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (NODE)) == (NODE)
?
+#define TYPE_ALIAS_P(NODE) \
+ (TYPE_P (NODE) \
+ && DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \
+ && TYPE_DECL_ALIAS_P (TYPE_NAME (NODE)))
Why check DECL_LANG_SPECIFIC?
+ /*If T is a specialization of an alias template, then we don't
+ want to take this 'if' branch; we want to print it as if it
+ was a specialization of class template. */
I think we want to handle them specially within this if.
- else if (same_type_p (t, TREE_TYPE (decl)))
+ else if (same_type_p (t, TREE_TYPE (decl))
+ && /* If T is the type of an alias template then we
+ want to let dump_decl print it like an alias
+ template. */
+ TYPE_DECL_NAMES_ALIAS_TEMPLATE_P (decl))
This change restricts the existing test to only apply to alias templates.
Also, I would think we would want to handle the uninstantiated alias the
same as instantiations.
You need some tests for printing of aliases in error messages. Only one
of the current tests prints an alias:
/home/jason/gt/gcc/testsuite/g++.dg/cpp0x/alias-decl-1.C:5:26: error: partial
specialization of alias template 'using AA0 = struct A0<int, T>'
This should have the template header. So here:
> + if (DECL_ALIAS_TEMPLATE_P (TI_TEMPLATE (get_template_info
(type))))
> + {
> + error ("partial specialization of alias template %qD",
> + TYPE_NAME (type));
> + return error_mark_node;
> + }
We should pass the template to error, rather than the instantiation.
But when I try that I see that it prints
template<class T, class U> struct AA0<T, U>
instead, so more fixing is needed.
+ else if (DECL_ALIAS_TEMPLATE_P (t))
+ {
+ tree tmpl;
+ result = get_aliased_type (DECL_TEMPLATE_RESULT (t));
+ tmpl = TI_TEMPLATE (get_template_info (result));
+ /* If RESULT is just the naming of TMPL, return TMPL. */
+ if (same_type_p (result,
+ TREE_TYPE (DECL_TEMPLATE_RESULT (tmpl))))
+ result = tmpl;
+ }
What is this trying to achieve? When we pass in a template, sometimes
it returns a type and sometimes a template? That seems odd.
+ else
+ /* Strip template aliases from TEMPLATE_DECL nodes,
+ similarly to what is done by
+ canonicalize_type_argument for types above. */
+ val = strip_alias (val);
I don't think this is right. Alias templates are never deduced, but
that doesn't seem to mean that they can't be used as template template
arguments. Both clang and EDG accept this testcase:
template <class T, class U> struct same;
template <class T> struct same<T,T> {};
template <class T> using Ptr = T*;
template <template <class> class T> struct A {
template <class U> using X = T<U>;
};
same<A<Ptr>::X<int>,int*> s;
+ if (ctx == DECL_CONTEXT (t)
+ && (TREE_CODE (t) != TYPE_DECL
+ /* ... unless T is an alias declaration; in
+ which case our caller can be willing to
+ create a specialization of the alias
+ template represented by T. If we hand her
+ T, she is going to clobber it. So we'll
+ contruct a new T in this case, just like
+ for the case where T is not a class
+ member. */
+ || !TYPE_DECL_ALIAS_P (t)))
I'm guessing that what this is trying to solve is the case of an
instantiation of a member alias template? In that case the problem is
that the member is a template, and this code is assuming a non-template
member. Let's check for that instead of alias-declarations, as the
existing code ought to work fine for regular alias members.
+ else if (TYPE_DECL_ALIAS_P (decl))
+ /* fall through. */;
Why not set r here, as for the other cases? It seems like this way you
will lose cv-quals added to an alias.
Jason