Implement the C++0x deduced 'auto' feature.

This fixes PR 8738, 9060 and 9132.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126069 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index df49ad5..65b57c3 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -75,6 +75,15 @@
     }
   }
 
+  // See if this is an auto-typed variable whose initializer we are parsing.
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (VD->isParsingAutoInit()) {
+      Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer)
+        << D->getDeclName();
+      return true;
+    }
+  }
+
   // See if the decl is deprecated.
   if (const DeprecatedAttr *DA = D->getAttr<DeprecatedAttr>())
     EmitDeprecationWarning(D, DA->getMessage(), Loc, UnknownObjCClass);
@@ -964,13 +973,6 @@
 Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
                        const DeclarationNameInfo &NameInfo,
                        const CXXScopeSpec *SS) {
-  if (Ty == Context.UndeducedAutoTy) {
-    Diag(NameInfo.getLoc(),
-         diag::err_auto_variable_cannot_appear_in_own_initializer)
-      << D->getDeclName();
-    return ExprError();
-  }
-
   MarkDeclarationReferenced(NameInfo.getLoc(), D);
 
   Expr *E = DeclRefExpr::Create(Context,
@@ -9650,26 +9652,18 @@
   if (!BT || !BT->isPlaceholderType()) return Owned(E);
 
   // If this is overload, check for a single overload.
-  if (BT->getKind() == BuiltinType::Overload) {
-    if (FunctionDecl *Specialization
-          = ResolveSingleFunctionTemplateSpecialization(E)) {
-      // The access doesn't really matter in this case.
-      DeclAccessPair Found = DeclAccessPair::make(Specialization,
-                                                  Specialization->getAccess());
-      E = FixOverloadedFunctionReference(E, Found, Specialization);
-      if (!E) return ExprError();
-      return Owned(E);
-    }
+  assert(BT->getKind() == BuiltinType::Overload);
 
-    Diag(Loc, diag::err_ovl_unresolvable) << E->getSourceRange();
-    return ExprError();
+  if (FunctionDecl *Specialization
+        = ResolveSingleFunctionTemplateSpecialization(E)) {
+    // The access doesn't really matter in this case.
+    DeclAccessPair Found = DeclAccessPair::make(Specialization,
+                                                Specialization->getAccess());
+    E = FixOverloadedFunctionReference(E, Found, Specialization);
+    if (!E) return ExprError();
+    return Owned(E);
   }
 
-  // Otherwise it's a use of undeduced auto.
-  assert(BT->getKind() == BuiltinType::UndeducedAuto);
-
-  DeclRefExpr *DRE = cast<DeclRefExpr>(E->IgnoreParens());
-  Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer)
-    << DRE->getDecl() << E->getSourceRange();
+  Diag(Loc, diag::err_ovl_unresolvable) << E->getSourceRange();
   return ExprError();
 }