]> granicus.if.org Git - clang/commitdiff
Enhance the diagnostic for referring to a typedef with an elaborated name to be
authorNick Lewycky <nicholas@mxc.ca>
Mon, 24 Jan 2011 19:01:04 +0000 (19:01 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Mon, 24 Jan 2011 19:01:04 +0000 (19:01 +0000)
as useful in a templated context as it is without templates. Fixes PR8755!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124136 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/TreeTransform.h
test/SemaCXX/PR8755.cpp [new file with mode: 0644]

index 1cb24e70bf62dfdbaacd119dd9fdcc99a930823c..3390dd7badc75384f5c171d9f058cc7968bb3f4a 100644 (file)
@@ -796,9 +796,28 @@ public:
     }
 
     if (!Tag) {
-      // FIXME: Would be nice to highlight just the source range.
-      SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
-        << Kind << Id << DC;
+      // Check where the name exists but isn't a tag type and use that to emit
+      // better diagnostics.
+      LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
+      SemaRef.LookupQualifiedName(Result, DC);
+      switch (Result.getResultKind()) {
+        case LookupResult::Found:
+        case LookupResult::FoundOverloaded:
+        case LookupResult::FoundUnresolvedValue: {
+         NamedDecl *SomeDecl = Result.getRepresentativeDecl();
+          unsigned Kind = 0;
+          if (isa<TypedefDecl>(SomeDecl)) Kind = 1;
+          else if (isa<ClassTemplateDecl>(SomeDecl)) Kind = 2;
+          SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag) << Kind;
+          SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
+          break;
+       }
+        default:
+          // FIXME: Would be nice to highlight just the source range.
+          SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
+            << Kind << Id << DC;
+          break;
+      }
       return QualType();
     }
 
diff --git a/test/SemaCXX/PR8755.cpp b/test/SemaCXX/PR8755.cpp
new file mode 100644 (file)
index 0000000..07778dd
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <typename T>
+struct A {
+  typedef int iterator;  // expected-note{{declared here}}
+};
+
+template <typename T>
+void f() {
+  class A <T> ::iterator foo;  // expected-error{{elaborated type refers to a typedef}}
+}
+
+void g() {
+  f<int>();  // expected-note{{in instantiation of function template}}
+}
+