diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-10-25 03:44:56 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-10-25 03:44:56 +0000 |
commit | 65019acfc46ffb191fac4e781ac0c4b8d0c8434e (patch) | |
tree | 7162170291c99c1201ad447a852873a489a146ce /lib/Sema | |
parent | 42edac0092749eff3ba881d1b9a425b4f1c9c049 (diff) |
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
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 47 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 3 |
4 files changed, 55 insertions, 17 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 2726906c1b..9267860d15 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4700,10 +4700,24 @@ Sema::CheckMicrosoftIfExistsSymbol(Scope *S, 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 d39731b90c..d2641888bd 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1307,7 +1307,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, = 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 e383db9350..b219c20459 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -155,10 +155,13 @@ namespace { /// \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 @@ DiagnoseUnexpandedParameterPacks(Sema &S, SourceLocation Loc, } 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 @@ bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, 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 @@ bool Sema::DiagnoseUnexpandedParameterPack(Expr *E, 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 @@ bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, 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 @@ bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, 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 @@ bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, 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 @@ bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, 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 @@ void Sema::collectUnexpandedParameterPacks(TypeLoc TL, 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 dde8a974c9..46bd05b14b 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -5805,6 +5805,9 @@ TreeTransform<Derived>::TransformMSDependentExistsStmt( case Sema::IER_Dependent: Dependent = true; break; + + case Sema::IER_Error: + return StmtError(); } // We need to continue with the instantiation, so do so now. |