Tweaks to C++0x deduced auto type support:
 * Flag indicating 'we're parsing this auto typed variable's initializer' moved from VarDecl to Sema
 * Temporary template parameter list for auto deduction is now allocated on the stack.
 * Deduced 'auto' types are now uniqued.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126139 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 23a3c24..78d49b7 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -466,6 +466,12 @@
     checkUndefinedInternals(*this);
   }
 
+  // Check we've noticed that we're no longer parsing the initializer for every
+  // variable. If we miss cases, then at best we have a performance issue and
+  // at worst a rejects-valid bug.
+  assert(ParsingInitForAutoVars.empty() &&
+         "Didn't unmark var as having its initializer parsed");
+
   TUScope = 0;
 }
 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index dd30c12..3c62c18 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3026,11 +3026,11 @@
     NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(),
                             II, R, TInfo, SC, SCAsWritten);
 
-    // If this decl has an auto type in need of deduction, mark the VarDecl so
-    // we can diagnose uses of it in its own initializer.
-    if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto) {
-      NewVD->setParsingAutoInit(R->getContainedAutoType());
-    }
+    // If this decl has an auto type in need of deduction, make a note of the
+    // Decl so we can diagnose uses of it in its own initializer.
+    if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto &&
+        R->getContainedAutoType())
+      ParsingInitForAutoVars.insert(NewVD);
 
     if (D.isInvalidType() || Invalid)
       NewVD->setInvalidDecl();
@@ -4534,8 +4534,6 @@
 
   // C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
   if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
-    VDecl->setParsingAutoInit(false);
-
     QualType DeducedType;
     if (!DeduceAutoType(VDecl->getType(), Init, DeducedType)) {
       Diag(VDecl->getLocation(), diag::err_auto_var_deduction_failure)
@@ -4800,9 +4798,8 @@
   if (!VD) return;
 
   // Auto types are meaningless if we can't make sense of the initializer.
-  if (VD->isParsingAutoInit()) {
-    VD->setParsingAutoInit(false);
-    VD->setInvalidDecl();
+  if (ParsingInitForAutoVars.count(D)) {
+    D->setInvalidDecl();
     return;
   }
 
@@ -4840,8 +4837,6 @@
 
     // C++0x [dcl.spec.auto]p3
     if (TypeMayContainAuto && Type->getContainedAutoType()) {
-      Var->setParsingAutoInit(false);
-
       Diag(Var->getLocation(), diag::err_auto_var_requires_init)
         << Var->getDeclName() << Type;
       Var->setInvalidDecl();
@@ -5044,6 +5039,14 @@
     FinalizeVarWithDestructor(var, recordType);
 }
 
+/// FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform
+/// any semantic actions necessary after any initializer has been attached.
+void
+Sema::FinalizeDeclaration(Decl *ThisDecl) {
+  // Note that we are no longer parsing the initializer for this declaration.
+  ParsingInitForAutoVars.erase(ThisDecl);
+}
+
 Sema::DeclGroupPtrTy
 Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
                               Decl **Group, unsigned NumDecls) {
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index e8abab8..c125346 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1078,6 +1078,8 @@
   if (Deleted) // FIXME: Source location is not very good.
     SetDeclDeleted(Member, D.getSourceRange().getBegin());
 
+  FinalizeDeclaration(Member);
+
   if (isInstField)
     FieldCollector->Add(cast<FieldDecl>(Member));
   return Member;
@@ -5972,8 +5974,6 @@
 
   // C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
   if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
-    VDecl->setParsingAutoInit(false);
-
     // FIXME: n3225 doesn't actually seem to indicate this is ill-formed
     if (Exprs.size() > 1) {
       Diag(Exprs.get()[1]->getSourceRange().getBegin(),
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index e7d167e..4ac3538 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -76,12 +76,10 @@
   }
 
   // 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;
-    }
+  if (ParsingInitForAutoVars.count(D)) {
+    Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer)
+      << D->getDeclName();
+    return true;
   }
 
   // See if the decl is deprecated.
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index bd0a618..139fafb 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -3004,12 +3004,12 @@
   LocalInstantiationScope InstScope(*this);
 
   // Build template<class TemplParam> void Func(FuncParam);
-  NamedDecl *TemplParam
-    = TemplateTypeParmDecl::Create(Context, 0, Loc, 0, 0, 0, false, false);
-  TemplateParameterList *TemplateParams
-    = TemplateParameterList::Create(Context, Loc, Loc, &TemplParam, 1, Loc);
-
   QualType TemplArg = Context.getTemplateTypeParmType(0, 0, false);
+  TemplateTypeParmDecl TemplParam(0, Loc, 0, false, TemplArg, false);
+  NamedDecl *TemplParamPtr = &TemplParam;
+  FixedSizeTemplateParameterList<1> TemplateParams(Loc, Loc, &TemplParamPtr,
+                                                   Loc);
+
   QualType FuncParam =
     SubstituteAutoTransform(*this, TemplArg).TransformType(Type);
 
@@ -3018,13 +3018,13 @@
   Deduced.resize(1);
   QualType InitType = Init->getType();
   unsigned TDF = 0;
-  if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams,
+  if (AdjustFunctionParmAndArgTypesForDeduction(*this, &TemplateParams,
                                                 FuncParam, InitType, Init,
                                                 TDF))
     return false;
 
   TemplateDeductionInfo Info(Context, Loc);
-  if (::DeduceTemplateArguments(*this, TemplateParams,
+  if (::DeduceTemplateArguments(*this, &TemplateParams,
                                 FuncParam, InitType, Info, Deduced,
                                 TDF))
     return false;