summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2011-05-07 01:36:37 +0000
committerRichard Trieu <rtrieu@google.com>2011-05-07 01:36:37 +0000
commitde756fbbd711a0b5c8c05e6817f35307d496eec4 (patch)
tree292a9c4a05964b289a0c9d12112b6fb3580869d9
parent63697e5025f65c60953fd0ca72203d60715924e9 (diff)
downloadbcm5719-llvm-de756fbbd711a0b5c8c05e6817f35307d496eec4.tar.gz
bcm5719-llvm-de756fbbd711a0b5c8c05e6817f35307d496eec4.zip
Patch for PR 7409 - only error on definition of invalid typedefs. Suppress errors for additional uses of this invalid typedef.
llvm-svn: 131043
-rw-r--r--clang/lib/Sema/TreeTransform.h10
-rw-r--r--clang/test/SemaTemplate/typename-specifier.cpp31
2 files changed, 38 insertions, 3 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index da60fccf7ed..c45d02a56c6 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -2568,9 +2568,13 @@ TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
Q.getLocalEndLoc());
break;
}
-
- SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
- << TL.getType() << SS.getRange();
+ // If the nested-name-specifier 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)
+ << TL.getType() << SS.getRange();
+ }
return NestedNameSpecifierLoc();
}
}
diff --git a/clang/test/SemaTemplate/typename-specifier.cpp b/clang/test/SemaTemplate/typename-specifier.cpp
index 4c788f6a8a3..7898a20d6e1 100644
--- a/clang/test/SemaTemplate/typename-specifier.cpp
+++ b/clang/test/SemaTemplate/typename-specifier.cpp
@@ -71,3 +71,34 @@ struct C {
::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 'long' 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 'double') 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;
OpenPOWER on IntegriCloud