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:
Fabien Chêne 2014-02-02 21:02:37 +01:00
parent 7f82286eb6
commit 1c50676a20
4 changed files with 72 additions and 19 deletions

View File

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

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

View 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>;

View 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>;