re PR c++/14258 (typename in a using declaration not supported)

gcc/testsuite/ChangeLog

2011-12-11  Fabien Chene  <fabien@gcc.gnu.org>

	PR c++/14258
	* g++.dg/template/using16.C: New.
	* g++.dg/template/using17.C: New.

gcc/cp/ChangeLog

2011-12-11  Fabien Chene  <fabien@gcc.gnu.org>

	PR c++/14258
	* cp-tree.h (USING_DECL_TYPENAME_P): New macro.
	* parser.c (cp_parser_nonclass_name): Handle using declarations
	that refer to a dependent type.
	(cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if
	the using declaration refers to a dependent type.

From-SVN: r182292
This commit is contained in:
Fabien Chêne 2011-12-13 19:46:58 +01:00
parent 863ea6cf55
commit 0f8fa9b678
6 changed files with 133 additions and 4 deletions

View File

@ -1,3 +1,12 @@
2011-12-13 Fabien Chêne <fabien@gcc.gnu.org>
PR c++/14258
* cp-tree.h (USING_DECL_TYPENAME_P): New macro.
* parser.c (cp_parser_nonclass_name): Handle using declarations
that refer to a dependent type.
(cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if
the using declaration refers to a dependent type.
2011-12-12 Jakub Jelinek <jakub@redhat.com>
PR c++/51496

View File

@ -130,6 +130,7 @@ c-common.h, not after.
DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL)
FUNCTION_PARAMETER_PACK_P (in PARM_DECL)
USING_DECL_TYPENAME_P (in USING_DECL)
2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL)
3: DECL_IN_AGGR_P.
@ -2521,6 +2522,9 @@ extern void decl_shadowed_for_var_insert (tree, tree);
/* The decls named by a using decl. */
#define USING_DECL_DECLS(NODE) DECL_INITIAL (USING_DECL_CHECK (NODE))
/* Non zero if the using decl refers to a dependent type. */
#define USING_DECL_TYPENAME_P(NODE) DECL_LANG_FLAG_1 (USING_DECL_CHECK (NODE))
/* In a VAR_DECL, true if we have a shadowed local variable
in the shadowed var table for this VAR_DECL. */
#define DECL_HAS_SHADOWED_FOR_VAR_P(NODE) \

View File

@ -13807,9 +13807,26 @@ cp_parser_nonclass_name (cp_parser* parser)
/* Look up the type-name. */
type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
/* If it is a using decl, use its underlying decl. */
type_decl = strip_using_decl (type_decl);
if (TREE_CODE (type_decl) == USING_DECL)
{
if (!DECL_DEPENDENT_P (type_decl))
type_decl = strip_using_decl (type_decl);
else if (USING_DECL_TYPENAME_P (type_decl))
{
/* We have found a type introduced by a using
declaration at class scope that refers to a dependent
type.
using typename :: [opt] nested-name-specifier unqualified-id ;
*/
type_decl = make_typename_type (TREE_TYPE (type_decl),
DECL_NAME (type_decl),
typename_type, tf_error);
if (type_decl != error_mark_node)
type_decl = TYPE_NAME (type_decl);
}
}
if (TREE_CODE (type_decl) != TYPE_DECL
&& (objc_is_id (identifier) || objc_is_class_name (identifier)))
{
@ -14947,6 +14964,9 @@ cp_parser_using_declaration (cp_parser* parser,
/* Create the USING_DECL. */
decl = do_class_using_decl (parser->scope, identifier);
if (typename_p)
USING_DECL_TYPENAME_P (decl) = 1;
if (check_for_bare_parameter_packs (decl))
return false;
else
@ -18900,7 +18920,11 @@ cp_parser_member_declaration (cp_parser* parser)
parser->colon_corrects_to_scope_p = false;
if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
goto out;
{
warning (OPT_Wdeprecated, "access declarations are deprecated; "
"employ using declarations instead");
goto out;
}
/* Parse the decl-specifier-seq. */
decl_spec_token_start = cp_lexer_peek_token (parser->lexer);

View File

@ -1,3 +1,9 @@
2011-12-11 Fabien Chêne <fabien@gcc.gnu.org>
PR c++/14258
* g++.dg/template/using16.C: New.
* g++.dg/template/using17.C: New.
2011-12-13 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/51362

View File

@ -0,0 +1,42 @@
// { dg-do compile }
template <class T>
struct A
{
typedef T type;
};
template <class T>
struct B
{
class type
{
type(); // { dg-error "private" }
};
};
template <class T>
struct C : A<T>, B<T>
{
using typename B<T>::type;
void f()
{
type j; // { dg-error "context" }
}
};
template class C<int>; // { dg-message "required" }
template <class T>
struct D
{
typedef T type;
};
template <class T>
class E : D<T>
{
using typename D<T>::type; // { dg-message "previous" }
using typename D<T>::type; // { dg-error "redeclaration" }
};

View File

@ -0,0 +1,44 @@
// PR c++/14258
// { dg-do run }
template<typename T>
struct A
{
typedef T type;
typedef A type2;
};
template<typename T>
struct B : A<T>
{
using typename A<T>::type;
type t;
using typename A<T>::type2;
type f()
{
type i = 1;
return i;
}
};
int main()
{
B<int>::type t = 4;
if (t != 4)
__builtin_abort();
B<double> b;
b.t = 3;
if (b.t != 3)
__builtin_abort();
B<long> b2;
if (b2.f() != 1)
__builtin_abort();
B<double>::type2::type tt = 12;
if (tt != 12)
__builtin_abort();
}