Diagnose invalid uses of tagged types with a missing tag.  For example, in:

struct xyz { int y; };
enum abc { ZZZ };

static xyz b;
abc c;

we used to produce:

t2.c:4:8: error: unknown type name 'xyz'
static xyz b;
       ^
t2.c:5:1: error: unknown type name 'abc'
abc c;
^

we now produce:

t2.c:4:8: error: use of tagged type 'xyz' without 'struct' tag
static xyz b;
       ^
       struct
t2.c:5:1: error: use of tagged type 'abc' without 'enum' tag
abc c;
^
enum

GCC produces the normal:
t2.c:4: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘b’
t2.c:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’

rdar://6783347


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68914 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 603b8b3..8ce624b 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -139,6 +139,29 @@
   return 0;
 }
 
+/// isTagName() - This method is called *for error recovery purposes only*
+/// to determine if the specified name is a valid tag name ("struct foo").  If
+/// so, this returns the TST for the tag corresponding to it (TST_enum,
+/// TST_union, TST_struct, TST_class).  This is used to diagnose cases in C
+/// where the user forgot to specify the tag.
+DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) {
+  // Do a tag name lookup in this scope.
+  LookupResult R = LookupName(S, &II, LookupTagName, false, false);
+  if (R.getKind() == LookupResult::Found)
+    if (const TagDecl *TD = dyn_cast<TagDecl>(R.getAsDecl())) {
+      switch (TD->getTagKind()) {
+      case TagDecl::TK_struct: return DeclSpec::TST_struct;
+      case TagDecl::TK_union:  return DeclSpec::TST_union;
+      case TagDecl::TK_class:  return DeclSpec::TST_class;
+      case TagDecl::TK_enum:   return DeclSpec::TST_enum;
+      }
+    }
+  
+  return DeclSpec::TST_unspecified;
+}
+
+
+
 DeclContext *Sema::getContainingDC(DeclContext *DC) {
   if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) {
     // A C++ out-of-line method will return to the file declaration context.