From 370478b178a3bdf01988c16782c90add8aea26aa Mon Sep 17 00:00:00 2001 From: dodji Date: Mon, 7 Nov 2011 21:28:50 +0000 Subject: PR c++/45114 - Support C++11 alias-declaration gcc/cp/ * cp-tree.h (TYPE_DECL_ALIAS_P, TYPE_ALIAS_P) (DECL_TYPE_TEMPLATE_P, DECL_ALIAS_TEMPLATE_P): New accessor macros. (TYPE_TEMPLATE_INFO): Get template info of an alias template specializations from its TYPE_DECL. (SET_TYPE_TEMPLATE_INFO): Set template info of alias template specializations into its TYPE_DECL. (DECL_CLASS_TEMPLATE_P): Re-write using the new DECL_TYPE_TEMPLATE_P. (enum cp_decl_spec): Add new ds_alias enumerator. (alias_type_or_template_p, alias_template_specialization_p): Declare new functions. * parser.c (cp_parser_alias_declaration): New static function. (cp_parser_check_decl_spec): Add "using" name for the `alias' declspec. (cp_parser_type_name): Update comment. Support simple-template-id representing alias template specializations in c++0x mode. (cp_parser_qualifying_entity): Update comment. Use cp_parser_type_name. (cp_parser_block_declaration): Handle alias-declaration in c++11. Update comment. (cp_parser_template_id): Handle specializations of alias templates. (cp_parser_member_declaration): Add alias-declaration production to comment. Support alias-declarations. (cp_parser_template_declaration_after_export): Handle alias templates in c++11. * decl.c (make_typename_type, make_unbound_class_template): Accept alias templates. (grokdeclarator): Set TYPE_DECL_ALIAS_P on alias declarations. * decl2.c (grokfield): Move template creation after setting up the TYPE_DECL of the alias, so that the TEMPLATE_DECL of the alias template actually carries the right type-id of the alias declaration. * pt.c (alias_type_or_template_p) (alias_template_specialization_p): Define new public functions. (maybe_process_partial_specialization): Reject partial specializations of alias templates. (primary_template_instantiation_p): Consider alias template instantiations. (push_template_decl_real): Assert that TYPE_DECLs of alias templates are different from those of class template. Store template info onto the TYPE_DECL of the alias template. (convert_template_argument): Strip aliases from template arguments. (lookup_template_class_1): Handle the creation of the specialization of an alias template. (tsubst_decl): Create a substituted copy of the TYPE_DECL of an member alias template. (tsubst): Handle substituting into the type of an alias template. Handle substituting UNBOUND_CLASS_TEMPLATE into BOUND_TEMPLATE_TEMPLATE_PARM. (do_type_instantiation): Better diagnostics when trying to explicitely instantiate a non-class template. * search.c (lookup_field_1, lookup_field_r): Support looking up alias templates. * semantics.c (finish_template_type): For instantiations of alias templates, return the TYPE_DECL of the actual alias and not the one of the aliased type. * error.c (dump_alias_template_specialization): New static function. (dump_type): Handle printing of alias templates and their specializations. templates. (dump_aggr_type): For specialization of alias templates, fetch arguments from the right place. (dump_decl): Print an alias-declaration like `using decl = type;' (dump_template_decl): Support printing of alias templates. gcc/testsuite/ * g++.dg/cpp0x/alias-decl-0.C: New test case. * g++.dg/cpp0x/alias-decl-1.C: Likewise. * g++.dg/cpp0x/alias-decl-3.C: Likewise. * g++.dg/cpp0x/alias-decl-4.C: Likewise. * g++.dg/cpp0x/alias-decl-6.C: Likewise. * g++.dg/cpp0x/alias-decl-7.C: Likewise. * g++.dg/cpp0x/alias-decl-8.C: Likewise. * g++.dg/cpp0x/alias-decl-9.C: Likewise. * g++.dg/cpp0x/alias-decl-10.C: Likewise. * g++.dg/ext/alias-decl-attr1.C: Likewise. * g++.dg/ext/alias-decl-attr2.C: Likewise. * g++.dg/ext/alias-decl-attr3.C: Likewise. * g++.dg/ext/alias-decl-attr4.C: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181118 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/error.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 8 deletions(-) (limited to 'gcc/cp/error.c') diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 0bee6b4105c..841366f58fa 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -61,6 +61,7 @@ static const char *op_to_string (enum tree_code); static const char *parm_to_string (int); static const char *type_to_string (tree, int); +static void dump_alias_template_specialization (tree, int); static void dump_type (tree, int); static void dump_typename (tree, int); static void dump_simple_decl (tree, tree, int); @@ -330,6 +331,23 @@ dump_template_bindings (tree parms, tree args, VEC(tree,gc)* typenames) } } +/* Dump a human-readable equivalent of the alias template + specialization of T. */ + +static void +dump_alias_template_specialization (tree t, int flags) +{ + tree name; + + gcc_assert (alias_template_specialization_p (t)); + + name = TYPE_IDENTIFIER (t); + pp_cxx_tree_identifier (cxx_pp, name); + dump_template_parms (TYPE_TEMPLATE_INFO (t), + /*primary=*/false, + flags & ~TFF_TEMPLATE_HEADER); +} + /* Dump a human-readable equivalent of TYPE. FLAGS controls the format. */ @@ -344,10 +362,15 @@ dump_type (tree t, int flags) { tree decl = TYPE_NAME (t); if ((flags & TFF_CHASE_TYPEDEF) - || DECL_SELF_REFERENCE_P (decl) - || (!flag_pretty_templates - && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))) + || DECL_SELF_REFERENCE_P (decl) + || (!flag_pretty_templates + && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))) t = strip_typedefs (t); + else if (alias_template_specialization_p (t)) + { + dump_alias_template_specialization (t, flags); + return; + } else if (same_type_p (t, TREE_TYPE (decl))) t = decl; else @@ -588,7 +611,10 @@ dump_aggr_type (tree t, int flags) if (name) { - typdef = !DECL_ARTIFICIAL (name); + typdef = (!DECL_ARTIFICIAL (name) + /* An alias specialization is not considered to be a + typedef. */ + && !alias_template_specialization_p (t)); if ((typdef && ((flags & TFF_CHASE_TYPEDEF) @@ -613,7 +639,7 @@ dump_aggr_type (tree t, int flags) { /* Because the template names are mangled, we have to locate the most general template, and use that name. */ - tree tpl = CLASSTYPE_TI_TEMPLATE (t); + tree tpl = TYPE_TI_TEMPLATE (t); while (DECL_TEMPLATE_INFO (tpl)) tpl = DECL_TI_TEMPLATE (tpl); @@ -952,6 +978,18 @@ dump_decl (tree t, int flags) dump_type (TREE_TYPE (t), flags); break; } + if (TYPE_DECL_ALIAS_P (t) + && (flags & TFF_DECL_SPECIFIERS + || flags & TFF_CLASS_KEY_OR_ENUM)) + { + pp_cxx_ws_string (cxx_pp, "using"); + dump_decl (DECL_NAME (t), flags); + pp_cxx_whitespace (cxx_pp); + pp_cxx_ws_string (cxx_pp, "="); + pp_cxx_whitespace (cxx_pp); + dump_type (DECL_ORIGINAL_TYPE (t), flags); + break; + } if ((flags & TFF_DECL_SPECIFIERS) && !DECL_SELF_REFERENCE_P (t)) pp_cxx_ws_string (cxx_pp, "typedef"); @@ -1196,13 +1234,14 @@ dump_template_decl (tree t, int flags) } } - if (DECL_TEMPLATE_RESULT (t) - && TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) + if (DECL_CLASS_TEMPLATE_P (t)) dump_type (TREE_TYPE (t), ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0))); else if (DECL_TEMPLATE_RESULT (t) - && TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL) + && (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL + /* Alias template. */ + || DECL_TYPE_TEMPLATE_P (t))) dump_decl (DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME); else { -- cgit v1.2.1