re PR c++/37140 (type inherited from base class not recognized)
2014-02-02 Fabien Chene <fabien@gcc.gnu.org> PR c++/37140 * parser.c (cp_parser_nonclass_name): Call strip_using_decl and move the code handling dependent USING_DECLs... * name-lookup.c (strip_using_decl): ...Here. 2014-02-02 Fabien Chene <fabien@gcc.gnu.org> PR c++/37140 * g++.dg/template/using27.C: New. * g++.dg/template/using28.C: New. * g++.dg/template/using29.C: New. From-SVN: r207408
This commit is contained in:
parent
7f82286eb6
commit
1c50676a20
@ -14812,25 +14812,7 @@ cp_parser_nonclass_name (cp_parser* parser)
|
||||
/* Look up the type-name. */
|
||||
type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
type_decl = strip_using_decl (type_decl);
|
||||
|
||||
if (TREE_CODE (type_decl) != TYPE_DECL
|
||||
&& (objc_is_id (identifier) || objc_is_class_name (identifier)))
|
||||
|
33
gcc/testsuite/g++.dg/template/using27.C
Normal file
33
gcc/testsuite/g++.dg/template/using27.C
Normal file
@ -0,0 +1,33 @@
|
||||
// PR c++/37140
|
||||
|
||||
struct X
|
||||
{
|
||||
typedef int nested_type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct A
|
||||
{
|
||||
typedef X type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct B : A<T>
|
||||
{
|
||||
using typename A<T>::type;
|
||||
typename type::nested_type x;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct C : B<T>
|
||||
{
|
||||
using typename B<T>::type;
|
||||
typename type::nested_type y;
|
||||
};
|
||||
|
||||
struct D : C<int>
|
||||
{
|
||||
using C<int>::type;
|
||||
type::nested_type z;
|
||||
};
|
||||
|
17
gcc/testsuite/g++.dg/template/using28.C
Normal file
17
gcc/testsuite/g++.dg/template/using28.C
Normal file
@ -0,0 +1,17 @@
|
||||
// PR c++/37140
|
||||
|
||||
struct C
|
||||
{
|
||||
static const int block_size = 1;
|
||||
};
|
||||
|
||||
template <typename T> struct A {
|
||||
typedef C type;
|
||||
};
|
||||
|
||||
template <typename T> struct B : public A<T> {
|
||||
using typename A<T>::type;
|
||||
static const int block_size = type::block_size;
|
||||
};
|
||||
|
||||
template class B<int>;
|
21
gcc/testsuite/g++.dg/template/using29.C
Normal file
21
gcc/testsuite/g++.dg/template/using29.C
Normal file
@ -0,0 +1,21 @@
|
||||
// PR c++/58047
|
||||
|
||||
template <int N>
|
||||
struct print_arg { };
|
||||
|
||||
struct const_holder {
|
||||
static const int CONSTANT = 42;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct identity {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct test_case : public identity<T> {
|
||||
using typename identity<T>::type;
|
||||
print_arg<type::CONSTANT> printer;
|
||||
};
|
||||
|
||||
template struct test_case<const_holder>;
|
Loading…
Reference in New Issue
Block a user