Check for unexpanded parameter packs in the name that guards a
Microsoft __if_exists/__if_not_exists statement. Also note that we
weren't traversing DeclarationNameInfo *at all* within the
RecursiveASTVisitor, which would be rather fatal for variadic
templates.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142906 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 2726906..9267860 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -4700,10 +4700,24 @@
   return IER_DoesNotExist;  
 }
 
-Sema::IfExistsResult Sema::CheckMicrosoftIfExistsSymbol(Scope *S,
-                                                        CXXScopeSpec &SS,
-                                                        UnqualifiedId &Name) {
+Sema::IfExistsResult 
+Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
+                                   bool IsIfExists, CXXScopeSpec &SS,
+                                   UnqualifiedId &Name) {
   DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name);
+  
+  // Check for unexpanded parameter packs.
+  SmallVector<UnexpandedParameterPack, 4> Unexpanded;
+  collectUnexpandedParameterPacks(SS, Unexpanded);
+  collectUnexpandedParameterPacks(TargetNameInfo, Unexpanded);
+  if (!Unexpanded.empty()) {
+    DiagnoseUnexpandedParameterPacks(KeywordLoc,
+                                     IsIfExists? UPPC_IfExists 
+                                               : UPPC_IfNotExists, 
+                                     Unexpanded);
+    return IER_Error;
+  }
+  
   return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo);
 }
 
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index d39731b..d264188 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1307,7 +1307,7 @@
         = cast<TemplateTemplateParmDecl>(*NewParam);
 
       // Check for unexpanded parameter packs, recursively.
-      if (DiagnoseUnexpandedParameterPacks(*this, NewTemplateParm)) {
+      if (::DiagnoseUnexpandedParameterPacks(*this, NewTemplateParm)) {
         Invalid = true;
         continue;
       }
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index e383db9..b219c20 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -155,10 +155,13 @@
 
 /// \brief Diagnose all of the unexpanded parameter packs in the given
 /// vector.
-static void 
-DiagnoseUnexpandedParameterPacks(Sema &S, SourceLocation Loc,
-                                 Sema::UnexpandedParameterPackContext UPPC,
+void
+Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
+                                       UnexpandedParameterPackContext UPPC,
              const SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
+  if (Unexpanded.empty())
+    return;
+  
   SmallVector<SourceLocation, 4> Locations;
   SmallVector<IdentifierInfo *, 4> Names;
   llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
@@ -179,13 +182,13 @@
   }
 
   DiagnosticBuilder DB
-    = Names.size() == 0? S.Diag(Loc, diag::err_unexpanded_parameter_pack_0)
+    = Names.size() == 0? Diag(Loc, diag::err_unexpanded_parameter_pack_0)
                            << (int)UPPC
-    : Names.size() == 1? S.Diag(Loc, diag::err_unexpanded_parameter_pack_1)
+    : Names.size() == 1? Diag(Loc, diag::err_unexpanded_parameter_pack_1)
                            << (int)UPPC << Names[0]
-    : Names.size() == 2? S.Diag(Loc, diag::err_unexpanded_parameter_pack_2)
+    : Names.size() == 2? Diag(Loc, diag::err_unexpanded_parameter_pack_2)
                            << (int)UPPC << Names[0] << Names[1]
-    : S.Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more)
+    : Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more)
         << (int)UPPC << Names[0] << Names[1];
 
   for (unsigned I = 0, N = Locations.size(); I != N; ++I)
@@ -205,7 +208,7 @@
   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
                                                               T->getTypeLoc());
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
+  DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
   return true;
 }
 
@@ -220,7 +223,7 @@
   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(*this, E->getLocStart(), UPPC, Unexpanded);
+  DiagnoseUnexpandedParameterPacks(E->getLocStart(), UPPC, Unexpanded);
   return true;
 }
 
@@ -237,7 +240,7 @@
   CollectUnexpandedParameterPacksVisitor(Unexpanded)
     .TraverseNestedNameSpecifier(SS.getScopeRep());
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(*this, SS.getRange().getBegin(), 
+  DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(), 
                                    UPPC, Unexpanded);
   return true;
 }
@@ -274,7 +277,7 @@
   CollectUnexpandedParameterPacksVisitor(Unexpanded)
     .TraverseType(NameInfo.getName().getCXXNameType());
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(*this, NameInfo.getLoc(), UPPC, Unexpanded);
+  DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
   return true;
 }
 
@@ -289,7 +292,7 @@
   CollectUnexpandedParameterPacksVisitor(Unexpanded)
     .TraverseTemplateName(Template);
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
+  DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
   return true;
 }
 
@@ -303,7 +306,7 @@
   CollectUnexpandedParameterPacksVisitor(Unexpanded)
     .TraverseTemplateArgumentLoc(Arg);
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(*this, Arg.getLocation(), UPPC, Unexpanded);
+  DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
   return true;  
 }
 
@@ -329,6 +332,24 @@
   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);  
 }  
 
+void Sema::collectUnexpandedParameterPacks(CXXScopeSpec &SS,
+                                           SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
+  NestedNameSpecifier *Qualifier = SS.getScopeRep();
+  if (!Qualifier)
+    return;
+  
+  NestedNameSpecifierLoc QualifierLoc(Qualifier, SS.location_data());
+  CollectUnexpandedParameterPacksVisitor(Unexpanded)
+    .TraverseNestedNameSpecifierLoc(QualifierLoc);
+}
+
+void Sema::collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo,
+                         SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
+  CollectUnexpandedParameterPacksVisitor(Unexpanded)
+    .TraverseDeclarationNameInfo(NameInfo);
+}
+
+
 ParsedTemplateArgument 
 Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
                          SourceLocation EllipsisLoc) {
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index dde8a97..46bd05b 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -5805,6 +5805,9 @@
   case Sema::IER_Dependent:
     Dependent = true;
     break;
+      
+  case Sema::IER_Error:
+    return StmtError();
   }
   
   // We need to continue with the instantiation, so do so now.