Patch for PR7409. Remove multiple error on invalid typedefs. Once the
first error is emitted, suppress additional errors when using the invalid
typedefs. Also, change the handling of types inside instantiations to be
more descriptive.
Patch attached and available in Code Review:
http://codereview.appspot.com/4430069/
Index: test/SemaTemplate/instantiate-member-expr.cpp
===================================================================
--- test/SemaTemplate/instantiate-member-expr.cpp (revision 130254)
+++ test/SemaTemplate/instantiate-member-expr.cpp (working copy)
@@ -54,7 +54,7 @@
namespace test2 {
template <class T> struct A {
void foo() {
- T::bar(); // expected-error {{type 'int' cannot}}
+ T::bar(); // expected-error {{type 'T' cannot}}
}
};
Index: test/SemaTemplate/typename-specifier.cpp
===================================================================
--- test/SemaTemplate/typename-specifier.cpp (revision 130254)
+++ test/SemaTemplate/typename-specifier.cpp (working copy)
@@ -40,7 +40,7 @@
// expected-error {{no type named 'type' in 'B'}} \
// FIXME: location info for error above isn't very good \
// expected-error 2{{typename specifier refers to non-type member 'type'}} \
- // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
+ // expected-error{{type 'T' cannot be used prior to '::' because it has no members}}
};
}
@@ -71,3 +71,34 @@
::Y<A>::type ip7 = &i;
::Y<B>::type ip8 = &i; // expected-note{{in instantiation of template class 'Y<B>' requested here}}
::Y<C>::type ip9 = &i; // expected-note{{in instantiation of template class 'Y<C>' requested here}}
+
+template<typename T> struct D {
+ typedef typename T::foo foo; // expected-error {{type 'T' cannot be used prior to '::' because it has no members}}
+ typedef typename foo::bar bar;
+};
+
+D<long> struct_D; // expected-note {{in instantiation of template class 'D<long>' requested here}}
+
+template<typename T> struct E {
+ typedef typename T::foo foo;
+ typedef typename foo::bar bar; // expected-error {{type 'foo' (aka 'typename T::foo') cannot be used prior to '::' because it has no members}}
+};
+
+struct F {
+ typedef double foo;
+};
+
+E<F> struct_E; // expected-note {{in instantiation of template class 'E<F>' requested here}}
+
+template<typename T> struct G {
+ typedef typename T::foo foo;
+ typedef typename foo::bar bar;
+};
+
+struct H {
+ struct foo {
+ typedef double bar;
+ };
+};
+
+G<H> struct_G;
Index: test/CXX/temp/temp.spec/temp.inst/p11.cpp
===================================================================
--- test/CXX/temp/temp.spec/temp.inst/p11.cpp (revision 130254)
+++ test/CXX/temp/temp.spec/temp.inst/p11.cpp (working copy)
@@ -3,7 +3,7 @@
// rdar://problem/7838962
namespace test0 {
template<typename T> unsigned f0() {
- return T::MaxSize; // expected-error {{'int' cannot be used prior to '::'}}
+ return T::MaxSize; // expected-error {{'T' cannot be used prior to '::'}}
};
template<typename T> struct A {
void Allocate(unsigned Alignment
Index: test/SemaCXX/destructor.cpp
===================================================================
--- test/SemaCXX/destructor.cpp (revision 130254)
+++ test/SemaCXX/destructor.cpp (working copy)
@@ -97,7 +97,7 @@
public:
void *operator new(__SIZE_TYPE__);
void operator delete(void *p) {
- T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}}
+ T::deleteIt(p); // expected-error {{type 'T' cannot be used prior to '::'}}
}
virtual ~A() {}
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h (revision 130254)
+++ lib/Sema/TreeTransform.h (working copy)
@@ -2530,9 +2530,13 @@
Q.getLocalEndLoc());
break;
}
-
- SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
- << TL.getType() << SS.getRange();
+ // If the namespace is an invalid type def, don't emit an error because
+ // a previous error should have already been emitted.
+ TypedefTypeLoc* TTL = dyn_cast<TypedefTypeLoc>(&TL);
+ if (!TTL || !TTL->getTypedefNameDecl()->isInvalidDecl()) {
+ SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
+ << NNS.getTypeLoc().getType() << SS.getRange();
+ }
return NestedNameSpecifierLoc();
}
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits