Commit ad1a6d45 by Nathan Sidwell Committed by Nathan Sidwell

extend.texi (Deprecated Features): Deprecate implicit typename.

	* doc/extend.texi (Deprecated Features): Deprecate implicit
	typename. Document that named return and initializer lists are now
	removed.
cp:
	* decl.c (grokdeclarator): Deprecated implicit typename use.
testsuite:
	* g++.old-deja/g++.brendan/crash56.C: Adjust implicit typename.
	* g++.old-deja/g++.jason/2371.C: Likewise.
	* g++.old-deja/g++.jason/template33.C: Likewise.
	* g++.old-deja/g++.jason/template34.C: Likewise.
	* g++.old-deja/g++.jason/template36.C: Likewise.
	* g++.old-deja/g++.oliva/typename1.C: Likewise.
	* g++.old-deja/g++.oliva/typename2.C: Likewise.
	* g++.old-deja/g++.other/typename1.C: Likewise.
	* g++.old-deja/g++.pt/inherit2.C: Likewise.
	* g++.old-deja/g++.pt/nontype5.C: Likewise.
	* g++.old-deja/g++.pt/typename11.C: Likewise.
	* g++.old-deja/g++.pt/typename14.C: Likewise.
	* g++.old-deja/g++.pt/typename16.C: Likewise.
	* g++.old-deja/g++.pt/typename3.C: Likewise.
	* g++.old-deja/g++.pt/typename4.C: Likewise.
	* g++.old-deja/g++.pt/typename5.C: Likewise.
	* g++.old-deja/g++.pt/typename7.C: Likewise.
	* g++.old-deja/g++.robertl/eb9.C: Likewise.

From-SVN: r47927
parent 3f2c5d1a
2001-12-12 Nathan Sidwell <nathan@codesourcery.com>
* doc/extend.texi (Deprecated Features): Deprecate implicit
typename. Document that named return and initializer lists are now
removed.
2001-12-11 Roger Sayle <roger@eyesopen.com> 2001-12-11 Roger Sayle <roger@eyesopen.com>
* except.c (reachable_next_level): Handle ERT_UNKNOWN to avoid * except.c (reachable_next_level): Handle ERT_UNKNOWN to avoid
......
2001-12-12 Nathan Sidwell <nathan@codesourcery.com>
* decl.c (grokdeclarator): Deprecated implicit typename use.
2001-12-11 Nathan Sidwell <nathan@codesourcery.com> 2001-12-11 Nathan Sidwell <nathan@codesourcery.com>
PR g++/51 PR g++/51
......
...@@ -10137,6 +10137,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -10137,6 +10137,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
type = integer_type_node; type = integer_type_node;
} }
if (type && TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type))
{
/* The implicit typename extension is deprecated and will be
removed. Warn about its use now. */
cp_warning ("`%T' is implicitly a typename", type);
cp_deprecated ("implicit typename");
/* Now remove its implicitness, so that we don't warn again.
For instance this might be a typedef, and we do not want to
warn on uses of the typedef itself. Simply clearing the
TREE_TYPE is insufficient. */
type = copy_node (type);
TREE_TYPE (type) = NULL_TREE;
}
ctype = NULL_TREE; ctype = NULL_TREE;
......
...@@ -5450,11 +5450,19 @@ parameters, as C++ demands. This feature has been removed, except where ...@@ -5450,11 +5450,19 @@ parameters, as C++ demands. This feature has been removed, except where
it is required for backwards compatibility @xref{Backwards Compatibility}. it is required for backwards compatibility @xref{Backwards Compatibility}.
@end table @end table
The named return value extension has been deprecated, and will be The named return value extension has been deprecated, and is now
removed from g++ at some point. removed from g++.
The use of initializer lists with new expressions has been deprecated, The use of initializer lists with new expressions has been deprecated,
and will be removed from g++ at some point. and is now removed from g++.
Floating and complex non-type template parameters have been deprecated,
and are now removed from g++.
The implicit typename extension has been deprecated and will be removed
from g++ at some point. In some cases g++ determines that a dependant
type such as @code{TPL<T>::X} is a type without needing a
@code{typename} keyword, contrary to the standard.
@node Backwards Compatibility @node Backwards Compatibility
@section Backwards Compatibility @section Backwards Compatibility
...@@ -5477,7 +5485,7 @@ the end of the scope which contained the for statement (rather than just ...@@ -5477,7 +5485,7 @@ the end of the scope which contained the for statement (rather than just
within the for scope). G++ retains this, but issues a warning, if such a within the for scope). G++ retains this, but issues a warning, if such a
variable is accessed outside the for scope. variable is accessed outside the for scope.
@item implicit C language @item Implicit C language
Old C system header files did not contain an @code{extern "C" @{@dots{}@}} Old C system header files did not contain an @code{extern "C" @{@dots{}@}}
scope to set the language. On such systems, all header files are scope to set the language. On such systems, all header files are
implicitly scoped inside a C language scope. Also, an empty prototype implicitly scoped inside a C language scope. Also, an empty prototype
......
2001-12-12 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.brendan/crash56.C: Adjust implicit typename.
* g++.old-deja/g++.jason/2371.C: Likewise.
* g++.old-deja/g++.jason/template33.C: Likewise.
* g++.old-deja/g++.jason/template34.C: Likewise.
* g++.old-deja/g++.jason/template36.C: Likewise.
* g++.old-deja/g++.oliva/typename1.C: Likewise.
* g++.old-deja/g++.oliva/typename2.C: Likewise.
* g++.old-deja/g++.other/typename1.C: Likewise.
* g++.old-deja/g++.pt/inherit2.C: Likewise.
* g++.old-deja/g++.pt/nontype5.C: Likewise.
* g++.old-deja/g++.pt/typename11.C: Likewise.
* g++.old-deja/g++.pt/typename14.C: Likewise.
* g++.old-deja/g++.pt/typename16.C: Likewise.
* g++.old-deja/g++.pt/typename3.C: Likewise.
* g++.old-deja/g++.pt/typename4.C: Likewise.
* g++.old-deja/g++.pt/typename5.C: Likewise.
* g++.old-deja/g++.pt/typename7.C: Likewise.
* g++.old-deja/g++.robertl/eb9.C: Likewise.
2001-12-11 Nathan Sidwell <nathan@codesourcery.com> 2001-12-11 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/other/linkage1.C: New test. * g++.dg/other/linkage1.C: New test.
......
...@@ -140,10 +140,13 @@ public: ...@@ -140,10 +140,13 @@ public:
ListD<T>::length; ListD<T>::length;
ListD<T>::empty; ListD<T>::empty;
ListD<T>::clear; ListD<T>::clear;
typedef ListD<T>::Vix Vix; typedef typename ListD<T>::Vix Vix;
ListD<T>::first; ListD<T>::first;
ListD<T>::next; ListD<T>::next;
ListD<T>::operator(); ListD<T>::operator();
using ListD<T>::NORMAL;
using ListD<T>::REMOVE_CURRENT;
}; };
extern "C" { extern "C" {
extern void __eprintf (const char *, const char *, unsigned, const char *); extern void __eprintf (const char *, const char *, unsigned, const char *);
...@@ -255,7 +258,7 @@ template<class T> ...@@ -255,7 +258,7 @@ template<class T>
void void
SetLD<T>::add(const ListD<T>& other) SetLD<T>::add(const ListD<T>& other)
{ {
ListD<T>::Vix x; typename ListD<T>::Vix x;
for (first(x); 0 != x; next(x)) for (first(x); 0 != x; next(x))
add(other(x)); add(other(x));
} }
...@@ -270,7 +273,7 @@ template<class T> ...@@ -270,7 +273,7 @@ template<class T>
void void
SetLD<T>::remove(const T& item) SetLD<T>::remove(const T& item)
{ {
Action a = NORMAL; typename ListD<T>::Action a = NORMAL;
Vix x; Vix x;
for (first(x); 0 != x && REMOVE_CURRENT != a; next(x, a)) for (first(x); 0 != x && REMOVE_CURRENT != a; next(x, a))
a = operator()(x) == item ? REMOVE_CURRENT: NORMAL;// ERROR - .* a = operator()(x) == item ? REMOVE_CURRENT: NORMAL;// ERROR - .*
...@@ -292,7 +295,7 @@ operator==(const SetLD<T>& a, const SetLD<T>& b) ...@@ -292,7 +295,7 @@ operator==(const SetLD<T>& a, const SetLD<T>& b)
{ {
if (a.length() != b.length()) if (a.length() != b.length())
return FALSE; return FALSE;
SetLD<T>::Vix x; typename SetLD<T>::Vix x;
for (a.first(x); 0 != x; a.next(x)) { for (a.first(x); 0 != x; a.next(x)) {
if ( ! b.contains(a(x)) ) if ( ! b.contains(a(x)) )
return FALSE; return FALSE;
...@@ -313,7 +316,7 @@ operator<=(const SetLD<T>& a, const SetLD<T>& b) ...@@ -313,7 +316,7 @@ operator<=(const SetLD<T>& a, const SetLD<T>& b)
{ {
if (a.length() > b.length()) if (a.length() > b.length())
return FALSE; return FALSE;
SetLD<T>::Vix x; typename SetLD<T>::Vix x;
for (x=a.first(); 0 != x; a.next(x)) { for (x=a.first(); 0 != x; a.next(x)) {
if ( ! b.contains(a(x)) ) if ( ! b.contains(a(x)) )
return FALSE; return FALSE;
......
# 1 "SetLS.cc"
// GROUPS passed templates nested-classes // GROUPS passed templates nested-classes
// Special g++ Options: // Special g++ Options:
// //
...@@ -14,7 +13,6 @@ ...@@ -14,7 +13,6 @@
#include <iostream> #include <iostream>
using namespace std; using namespace std;
# 1 "../../templates/SetLS.h" 1
// -*- C++ -*- // -*- C++ -*-
...@@ -38,10 +36,8 @@ using namespace std; ...@@ -38,10 +36,8 @@ using namespace std;
#define XTRUE true #define XTRUE true
#define XFALSE false #define XFALSE false
# 37 "../../templates/SetLS.h"
# 1 "../../templates/ListS.h" 1
// -*- C++ -*- // -*- C++ -*-
...@@ -63,7 +59,6 @@ using namespace std; ...@@ -63,7 +59,6 @@ using namespace std;
# 1 "/projects/gnu-cygnus/gnu-cygnus-14/mips/lib/gcc-lib/decstation/cygnus-reno-1/g++-include/bool.h" 1 3
// Defining XTRUE and XFALSE is usually a Bad Idea, // Defining XTRUE and XFALSE is usually a Bad Idea,
// because you will probably be inconsistent with anyone // because you will probably be inconsistent with anyone
// else who had the same clever idea. // else who had the same clever idea.
...@@ -77,9 +72,7 @@ using namespace std; ...@@ -77,9 +72,7 @@ using namespace std;
# 23 "../../templates/ListS.h" 2
# 37 "../../templates/ListS.h"
...@@ -189,7 +182,6 @@ public: ...@@ -189,7 +182,6 @@ public:
{ check(x); { check(x);
return x.index->item; } return x.index->item; }
protected: protected:
# 154 "../../templates/ListS.h"
unsigned count; unsigned count;
...@@ -320,10 +312,8 @@ ListS<T>::remove_head_filling(T* fill) ...@@ -320,10 +312,8 @@ ListS<T>::remove_head_filling(T* fill)
} }
# 40 "../../templates/SetLS.h" 2
# 62 "../../templates/SetLS.h"
template<class T> template<class T>
class SetLS { class SetLS {
...@@ -361,11 +351,11 @@ public: ...@@ -361,11 +351,11 @@ public:
private: private:
friend class SetLS<T>; friend class SetLS<T>;
Vix(const SetLS<T> *o, const ListS<T>::Vix& x): owner(o), vix(x) Vix(const SetLS<T> *o, const typename ListS<T>::Vix& x): owner(o), vix(x)
{ } { }
const SetLS<T> *owner; const SetLS<T> *owner;
ListS<T>::Vix vix; typename ListS<T>::Vix vix;
}; };
friend class Vix; friend class Vix;
...@@ -422,7 +412,6 @@ SetLS<T>::contains(const T& item) const ...@@ -422,7 +412,6 @@ SetLS<T>::contains(const T& item) const
} }
# 17 "SetLS.cc" 2
......
...@@ -12,6 +12,6 @@ public: ...@@ -12,6 +12,6 @@ public:
}; };
template <class T> template <class T>
A<T>::muni A<T>::f() { return X; } typename A<T>::muni A<T>::f() { return X; }
template class A<int>; template class A<int>;
...@@ -14,7 +14,7 @@ int gen_cmp(const T& a, const T& b) { ...@@ -14,7 +14,7 @@ int gen_cmp(const T& a, const T& b) {
} }
template<class T> template<class T>
Set<T>::Compare Set<T>::cmp1 = &gen_cmp; typename Set<T>::Compare Set<T>::cmp1 = &gen_cmp;
template<class T> template<class T>
int (*Set<T>::cmp2)(const T&, const T&) = &gen_cmp; int (*Set<T>::cmp2)(const T&, const T&) = &gen_cmp;
......
...@@ -18,6 +18,7 @@ struct base_trait { ...@@ -18,6 +18,7 @@ struct base_trait {
typedef base1 base; typedef base1 base;
}; };
template<>
struct base_trait<float> { struct base_trait<float> {
typedef base2 base; typedef base2 base;
}; };
...@@ -25,7 +26,7 @@ struct base_trait<float> { ...@@ -25,7 +26,7 @@ struct base_trait<float> {
template<class T> template<class T>
class weird : public base_trait<T>::base { class weird : public base_trait<T>::base {
public: public:
typedef base_trait<T>::base base; typedef typename base_trait<T>::base base;
base f (); base f ();
int base::* g (); int base::* g ();
...@@ -35,14 +36,18 @@ public: ...@@ -35,14 +36,18 @@ public:
}; };
template <class T> template <class T>
weird<T>::base weird<T>::f () typename weird<T>::base weird<T>::f ()
{ {
return base(); return base();
} }
// The standard does not allow this case; the `typename' keyword may
// not appear in a ptr-operator.
#if 0
template <class T> template <class T>
int weird<T>::base::* weird<T>::g () int typename weird<T>::base::* weird<T>::g ()
{ return 0; } { return 0; }
#endif
int main() int main()
{ {
......
...@@ -12,6 +12,5 @@ template <class T> struct bar { ...@@ -12,6 +12,5 @@ template <class T> struct bar {
}; };
template <class T> struct baz { template <class T> struct baz {
typedef bar<T>::foo foo; // ERROR - missing typename - XFAIL *-*-* typedef bar<T>::foo foo; // ERROR - missing typename
void m(foo);
}; };
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Based on a test case by Louidor Erez <s3824888@techst02.technion.ac.il> // Based on a test case by Louidor Erez <s3824888@techst02.technion.ac.il>
// Build don't link: // Build don't link:
// Special g++ Options: -pedantic // Special g++ Options: -pedantic -Wno-deprecated
template<class T> template<class T>
class Vector { class Vector {
...@@ -13,5 +13,5 @@ public: ...@@ -13,5 +13,5 @@ public:
template<class T> template<class T>
void f() void f()
{ {
Vector<T>::iterator i = 0; // ERROR - missing typename - XFAIL *-*-* Vector<T>::iterator i = 0; // WARNING - missing typename
} }
// Test that we warn about unqualified references to implicit typenames.
// Special g++ Options:
// Build don't link: // Build don't link:
template <class T> struct A { // Make sure we make the right unqualified class a friend
struct AA { }; // See PR c++/4403
struct AB { };
struct AC { }; template <class T> struct A
{
struct AA;
struct AC;
};
template <class T> class B
:public A<T>
{
friend struct B::AA; // OK, this has an implicit typename
// as if it is 'friend struct typename B::AA'
// (I think there's a defect report
// about that)
friend struct AC; // this makes ::AC a friend *not* A<T>::AC
private: // only our friends can get out values
static T valueA_AA;
static T valueA_AC;
static T value_AC;
};
template <typename T> T B<T>::valueA_AA;
template <typename T> T B<T>::valueA_AC;// ERROR - private - XFAIL *-*-*
template <typename T> T B<T>::value_AC; // gets bogus error - XFAIL *-*-*
// this one is a friend
template <class T> struct A<T>::AA
{
int M ()
{
return B<T>::valueA_AA;
}
};
// this is not a friend
template <class T> struct A<T>::AC
{
T M ()
{
return B<T>::valueA_AC; // ERROR - within this context - XFAIL *-*-*
}
}; };
template <class T> struct B: public A<T> { // this is a friend
friend struct B::AA; // OK struct AC
friend AB; // WARNING - needs class-key {
friend struct AC; // WARNING - refers to ::AC int M ()
{
return B<int>::value_AC; // gets bogus error - XFAIL *-*-*
}
}; };
B<int> b; B<int> b;
A<int>::AA a_aa;
A<int>::AC a_ac;
AC ac;
int main () { } int main ()
{
a_aa.M ();
a_ac.M ();
ac.M ();
}
...@@ -11,13 +11,13 @@ struct A { ...@@ -11,13 +11,13 @@ struct A {
typedef int F(); typedef int F();
}; };
template<class T, A<T>::F f> template<class T, typename A<T>::F f>
struct B { struct B {
static int g() { return f(); }; static int g() { return f(); };
}; };
int f() { return 0; }; int f() { return 0; }
int main() { int main() {
return B<int,&f>::g(); // ERROR - could not convert arg return B<int,&f>::g(); // ERROR - could not convert arg
}; }
// Build don't link: // Build don't link:
// Special g++ Options: // Special g++ Options: -Wno-deprecated
template <class T, int I> template <class T, int I>
struct S { struct S {
...@@ -7,8 +7,7 @@ struct S { ...@@ -7,8 +7,7 @@ struct S {
}; };
template <class T, class U, int I> template <class T, class U, int I>
S<T,I>::X f(T, U) S<T,I>::X f(T, U) { // WARNING - implicit typename
{
S<T, I>::X(); S<T, I>::X();
return S<T, I>::X(); return S<T, I>::X();
} }
......
// Build don't link: // Build don't link:
// Special g++ Options: // Special g++ Options: -Wno-deprecated
template <class T> template <class T>
struct B { struct B {
...@@ -10,6 +10,6 @@ template <class T> ...@@ -10,6 +10,6 @@ template <class T>
struct S : public B<T> struct S : public B<T>
{ {
struct I { struct I {
void f(X x); void f(X x); // WARNING - implicit typename
}; };
}; };
// Build don't run: // Build don't run:
// Special g++ Options: // Special g++ Options: -Wno-deprecated
struct B { struct B {
typedef int I; typedef int I;
...@@ -11,7 +11,7 @@ struct D1 : public B { ...@@ -11,7 +11,7 @@ struct D1 : public B {
template <class T> template <class T>
struct D2 : public D1<T> { struct D2 : public D1<T> {
I i; I i; // WARNING - implicit typename
}; };
template <> template <>
......
// Build don't link: // Build don't link:
// Special g++ Options: // Special g++ Options: -Wno-deprecated
template <class T> template <class T>
struct A struct A
...@@ -11,11 +11,10 @@ struct A ...@@ -11,11 +11,10 @@ struct A
template <class U> template <class U>
struct B : public A<U> struct B : public A<U>
{ {
A_Type Func(); A_Type Func(); // WARNING - implicit typename
}; };
template <class U> template <class U>
B<U>::A_Type B<U>::Func() B<U>::A_Type B<U>::Func() { // WARNING - implicit typename
{
} }
// Build don't link: // Build don't link:
// Special g++ Options: // Special g++ Options: -Wno-deprecated
template <class T> template <class T>
struct A struct A
...@@ -17,11 +17,10 @@ struct B : public A<U> ...@@ -17,11 +17,10 @@ struct B : public A<U>
template <class U> template <class U>
struct C : public B<U> struct C : public B<U>
{ {
A_Type Func(); A_Type Func(); // WARNING - implicit typename
}; };
template <class U> template <class U>
C<U>::A_Type C<U>::Func() C<U>::A_Type C<U>::Func() { // WARNING - implicit typename
{
} }
// Build don't link: // Build don't link:
// Special g++ Options: // Special g++ Options: -Wno-deprecated
template <class T> template <class T>
struct A struct A
...@@ -17,11 +17,10 @@ struct B : public A<U> ...@@ -17,11 +17,10 @@ struct B : public A<U>
template <class U> template <class U>
struct C : public B<U> struct C : public B<U>
{ {
void Func(A_Type); void Func(A_Type); // WARNING - implicit typename
}; };
template <class U> template <class U>
void C<U>::Func(A_Type) void C<U>::Func(A_Type) { // WARNING - implicit typename
{
} }
...@@ -15,6 +15,6 @@ template <class T> ...@@ -15,6 +15,6 @@ template <class T>
struct D : public A <C <T> > { struct D : public A <C <T> > {
void f () void f ()
{ {
B* new_entries = (B *) 0; B* new_entries = (B *) 0; // WARNING - implicit typename
} }
}; };
...@@ -15,7 +15,8 @@ public: ...@@ -15,7 +15,8 @@ public:
template <class Key> template <class Key>
d0om_Hashmap<Key>::value_type* d0om_Hashmap<Key>::iterator::operator-> () const typename d0om_Hashmap<Key>::value_type*
d0om_Hashmap<Key>::iterator::operator-> () const
{ {
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment