Implement more of C++0x 'auto'. A variable with an auto type specifier must have an initializer. Also, move some tests around to match the C++0x draft better.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75322 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index fd368c4..7a9faac 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1006,7 +1006,7 @@
   case NullPtr:           return "nullptr_t";
   case Overload:          return "<overloaded function type>";
   case Dependent:         return "<dependent type>";
-  case UndeducedAuto:     return "<undeduced auto type>";
+  case UndeducedAuto:     return "auto";
   }
 }
 
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 5566751..1ddd20a 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -465,7 +465,9 @@
                                             CommaLocs.data(), RParenLoc);
     }
   } else {
-    Actions.ActOnUninitializedDecl(ThisDecl);
+    bool TypeContainsUndeducedAuto = 
+      D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
+    Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsUndeducedAuto);
   }
 
   return ThisDecl;
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 9eb03e3..c2a484e 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -473,7 +473,7 @@
 
   virtual void AddInitializerToDecl(DeclPtrTy dcl, FullExprArg init);
   void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit);
-  void ActOnUninitializedDecl(DeclPtrTy dcl);
+  void ActOnUninitializedDecl(DeclPtrTy dcl, bool TypeContainsUndeducedAuto);
   virtual void SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc);
   virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
                                                  DeclPtrTy *Group,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 2c24dc9..9c3ef2f 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2756,7 +2756,8 @@
   return;
 }
 
-void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) {
+void Sema::ActOnUninitializedDecl(DeclPtrTy dcl, 
+                                  bool TypeContainsUndeducedAuto) {
   Decl *RealDecl = dcl.getAs<Decl>();
 
   // If there is no declaration, there was an error parsing it. Just ignore it.
@@ -2784,6 +2785,14 @@
       return;
     }
 
+    // C++0x [dcl.spec.auto]p3
+    if (TypeContainsUndeducedAuto) {
+      Diag(Var->getLocation(), diag::err_auto_var_requires_init)
+        << Var->getDeclName() << Type;
+      Var->setInvalidDecl();
+      return;
+    }
+    
     // C++ [dcl.init]p9:
     //
     //   If no initializer is specified for an object, and the object