diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 30 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 63 |
5 files changed, 75 insertions, 45 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 629dc58958..c181a568b5 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -622,7 +622,7 @@ namespace { unsigned NumUnexpanded, bool &ShouldExpand, bool &RetainExpansion, - unsigned &NumExpansions) { + llvm::Optional<unsigned> &NumExpansions) { return getSema().CheckParameterPacksForExpansion(EllipsisLoc, PatternRange, Unexpanded, NumUnexpanded, @@ -1260,7 +1260,9 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, // We still have unexpanded parameter packs, which means that // our function parameter is still a function parameter pack. // Therefore, make its type a pack expansion type. - NewDI = CheckPackExpansion(NewDI, ExpansionTL.getEllipsisLoc()); + // FIXME: Variadic templates num expansions. + NewDI = CheckPackExpansion(NewDI, ExpansionTL.getEllipsisLoc(), + llvm::Optional<unsigned>()); } } else { NewDI = SubstType(OldDI, TemplateArgs, OldParm->getLocation(), @@ -1360,7 +1362,7 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation, Unexpanded); bool ShouldExpand = false; bool RetainExpansion = false; - unsigned NumExpansions = 0; + llvm::Optional<unsigned> NumExpansions; if (CheckParameterPacksForExpansion(Base->getEllipsisLoc(), Base->getSourceRange(), Unexpanded.data(), Unexpanded.size(), @@ -1373,7 +1375,7 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation, // If we should expand this pack expansion now, do so. if (ShouldExpand) { - for (unsigned I = 0; I != NumExpansions; ++I) { + for (unsigned I = 0; I != *NumExpansions; ++I) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I); TypeSourceInfo *BaseTypeLoc = SubstType(Base->getTypeSourceInfo(), diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index a18bfbafc0..6b5713a2fa 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1977,7 +1977,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, bool Expand = false; bool RetainExpansion = false; - unsigned NumExpansions = 0; + llvm::Optional<unsigned> NumExpansions + = PackExpansion->getNumExpansions(); if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(), SourceRange(), Unexpanded.data(), @@ -1990,7 +1991,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, if (!Expand) { // We can't expand this pack expansion into separate arguments yet; - // just substitute into the argument pack. + // just substitute into the pattern and create a new pack expansion + // type. Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); QualType T = SemaRef.SubstType(PackExpansion->getPattern(), TemplateArgs, @@ -1998,13 +2000,14 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, if (T.isNull()) break; + T = SemaRef.Context.getPackExpansionType(T, NumExpansions); Exceptions.push_back(T); continue; } // Substitute into the pack expansion pattern for each template bool Invalid = false; - for (unsigned ArgIdx = 0; ArgIdx != NumExpansions; ++ArgIdx) { + for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, ArgIdx); QualType T = SemaRef.SubstType(PackExpansion->getPattern(), @@ -2384,7 +2387,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, collectUnexpandedParameterPacks(BaseTL, Unexpanded); bool ShouldExpand = false; bool RetainExpansion = false; - unsigned NumExpansions = 0; + llvm::Optional<unsigned> NumExpansions; if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(), BaseTL.getSourceRange(), Unexpanded.data(), @@ -2399,7 +2402,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, assert(ShouldExpand && "Partial instantiation of base initializer?"); // Loop over all of the arguments in the argument pack(s), - for (unsigned I = 0; I != NumExpansions; ++I) { + for (unsigned I = 0; I != *NumExpansions; ++I) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I); // Instantiate the initializer. diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index dc5013c25d..899b58e558 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -368,7 +368,8 @@ TypeResult Sema::ActOnPackExpansion(ParsedType Type, if (!TSInfo) return true; - TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc); + TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, + llvm::Optional<unsigned>()); if (!TSResult) return true; @@ -376,11 +377,12 @@ TypeResult Sema::ActOnPackExpansion(ParsedType Type, } TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern, - SourceLocation EllipsisLoc) { + SourceLocation EllipsisLoc, + llvm::Optional<unsigned> NumExpansions) { // Create the pack expansion type and source-location information. QualType Result = CheckPackExpansion(Pattern->getType(), Pattern->getTypeLoc().getSourceRange(), - EllipsisLoc); + EllipsisLoc, NumExpansions); if (Result.isNull()) return 0; @@ -397,7 +399,8 @@ TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern, QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange, - SourceLocation EllipsisLoc) { + SourceLocation EllipsisLoc, + llvm::Optional<unsigned> NumExpansions) { // C++0x [temp.variadic]p5: // The pattern of a pack expansion shall name one or more // parameter packs that are not expanded by a nested pack @@ -408,7 +411,7 @@ QualType Sema::CheckPackExpansion(QualType Pattern, return QualType(); } - return Context.getPackExpansionType(Pattern); + return Context.getPackExpansionType(Pattern, NumExpansions); } ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) { @@ -450,7 +453,7 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, bool &RetainExpansion, - unsigned &NumExpansions) { + llvm::Optional<unsigned> &NumExpansions) { ShouldExpand = true; RetainExpansion = false; std::pair<IdentifierInfo *, SourceLocation> FirstPack; @@ -527,7 +530,7 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, RetainExpansion = true; } - if (!HaveFirstPack) { + if (!NumExpansions) { // The is the first pack we've seen for which we have an argument. // Record it. NumExpansions = NewPackSize; @@ -537,13 +540,18 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, continue; } - if (NewPackSize != NumExpansions) { + if (NewPackSize != *NumExpansions) { // C++0x [temp.variadic]p5: // All of the parameter packs expanded by a pack expansion shall have // the same number of arguments specified. - Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) - << FirstPack.first << Name << NumExpansions << NewPackSize - << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second); + if (HaveFirstPack) + Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) + << FirstPack.first << Name << *NumExpansions << NewPackSize + << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second); + else + Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel) + << Name << *NumExpansions << NewPackSize + << SourceRange(Unexpanded[I].second); return true; } } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index ada8a1d8a2..e843ca5fca 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1927,7 +1927,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S, << T << D.getSourceRange(); D.setEllipsisLoc(SourceLocation()); } else { - T = Context.getPackExpansionType(T); + T = Context.getPackExpansionType(T, llvm::Optional<unsigned>()); } break; @@ -1941,7 +1941,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S, // parameter packs in the type of the non-type template parameter, then // it expands those parameter packs. if (T->containsUnexpandedParameterPack()) - T = Context.getPackExpansionType(T); + T = Context.getPackExpansionType(T, llvm::Optional<unsigned>()); else if (!getLangOptions().CPlusPlus0x) Diag(D.getEllipsisLoc(), diag::err_variadic_templates); break; diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 4127d5045a..f2496c2f1a 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -227,8 +227,12 @@ public: /// C++0x [temp.arg.explicit]p9. /// /// \param NumExpansions The number of separate arguments that will be in - /// the expanded form of the corresponding pack expansion. Must be set when - /// \c ShouldExpand is \c true. + /// the expanded form of the corresponding pack expansion. This is both an + /// input and an output parameter, which can be set by the caller if the + /// number of expansions is known a priori (e.g., due to a prior substitution) + /// and will be set by the callee when the number of expansions is known. + /// The callee must set this value when \c ShouldExpand is \c true; it may + /// set this value in other cases. /// /// \returns true if an error occurred (e.g., because the parameter packs /// are to be instantiated with arguments of different lengths), false @@ -240,7 +244,7 @@ public: unsigned NumUnexpanded, bool &ShouldExpand, bool &RetainExpansion, - unsigned &NumExpansions) { + llvm::Optional<unsigned> &NumExpansions) { ShouldExpand = false; return false; } @@ -814,8 +818,10 @@ public: /// Subclasses may override this routine to provide different behavior. QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange, - SourceLocation EllipsisLoc) { - return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc); + SourceLocation EllipsisLoc, + llvm::Optional<unsigned> NumExpansions) { + return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc, + NumExpansions); } /// \brief Build a new nested-name-specifier given the prefix and an @@ -2165,7 +2171,8 @@ public: /// for a template argument. Subclasses may override this routine to provide /// different behavior. TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern, - SourceLocation EllipsisLoc) { + SourceLocation EllipsisLoc, + llvm::Optional<unsigned> NumExpansions) { switch (Pattern.getArgument().getKind()) { case TemplateArgument::Expression: { ExprResult Result @@ -2195,7 +2202,8 @@ public: case TemplateArgument::Type: if (TypeSourceInfo *Expansion = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(), - EllipsisLoc)) + EllipsisLoc, + NumExpansions)) return TemplateArgumentLoc(TemplateArgument(Expansion->getType()), Expansion); break; @@ -2300,7 +2308,7 @@ bool TreeTransform<Derived>::TransformExprs(Expr **Inputs, // be expanded. bool Expand = true; bool RetainExpansion = false; - unsigned NumExpansions = 0; + llvm::Optional<unsigned> NumExpansions; if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded.data(), @@ -2318,6 +2326,7 @@ bool TreeTransform<Derived>::TransformExprs(Expr **Inputs, if (OutPattern.isInvalid()) return true; + // FIXME: Variadic templates NumExpansions ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(), Expansion->getEllipsisLoc()); if (Out.isInvalid()) @@ -2331,7 +2340,7 @@ bool TreeTransform<Derived>::TransformExprs(Expr **Inputs, // The transform has determined that we should perform an elementwise // expansion of the pattern. Do so. - for (unsigned I = 0; I != NumExpansions; ++I) { + for (unsigned I = 0; I != *NumExpansions; ++I) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); ExprResult Out = getDerived().TransformExpr(Pattern); if (Out.isInvalid()) @@ -2817,8 +2826,10 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First, // We have a pack expansion, for which we will be substituting into // the pattern. SourceLocation Ellipsis; + llvm::Optional<unsigned> OrigNumExpansions; TemplateArgumentLoc Pattern - = In.getPackExpansionPattern(Ellipsis, getSema().Context); + = In.getPackExpansionPattern(Ellipsis, OrigNumExpansions, + getSema().Context); llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); @@ -2828,7 +2839,7 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First, // be expanded. bool Expand = true; bool RetainExpansion = false; - unsigned NumExpansions = 0; + llvm::Optional<unsigned> NumExpansions = OrigNumExpansions; if (getDerived().TryExpandParameterPacks(Ellipsis, Pattern.getSourceRange(), Unexpanded.data(), @@ -2847,7 +2858,8 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First, if (getDerived().TransformTemplateArgument(Pattern, OutPattern)) return true; - Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis); + Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis, + NumExpansions); if (Out.getArgument().isNull()) return true; @@ -2857,14 +2869,15 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First, // The transform has determined that we should perform an elementwise // expansion of the pattern. Do so. - for (unsigned I = 0; I != NumExpansions; ++I) { + for (unsigned I = 0; I != *NumExpansions; ++I) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); if (getDerived().TransformTemplateArgument(Pattern, Out)) return true; if (Out.getArgument().containsUnexpandedParameterPack()) { - Out = getDerived().RebuildPackExpansion(Out, Ellipsis); + Out = getDerived().RebuildPackExpansion(Out, Ellipsis, + OrigNumExpansions); if (Out.getArgument().isNull()) return true; } @@ -2880,7 +2893,8 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First, if (getDerived().TransformTemplateArgument(Pattern, Out)) return true; - Out = getDerived().RebuildPackExpansion(Out, Ellipsis); + Out = getDerived().RebuildPackExpansion(Out, Ellipsis, + OrigNumExpansions); if (Out.getArgument().isNull()) return true; @@ -3497,7 +3511,7 @@ bool TreeTransform<Derived>:: // Determine whether we should expand the parameter packs. bool ShouldExpand = false; bool RetainExpansion = false; - unsigned NumExpansions = 0; + llvm::Optional<unsigned> NumExpansions; if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(), Unexpanded.data(), @@ -3512,7 +3526,7 @@ bool TreeTransform<Derived>:: // Expand the function parameter pack into multiple, separate // parameters. getDerived().ExpandingFunctionParameterPack(OldParm); - for (unsigned I = 0; I != NumExpansions; ++I) { + for (unsigned I = 0; I != *NumExpansions; ++I) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); ParmVarDecl *NewParm = getDerived().TransformFunctionTypeParam(OldParm); @@ -3546,6 +3560,7 @@ bool TreeTransform<Derived>:: // expansion. } + // FIXME: Variadic templates num expansions Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); ParmVarDecl *NewParm = getDerived().TransformFunctionTypeParam(OldParm); if (!NewParm) @@ -3561,6 +3576,7 @@ bool TreeTransform<Derived>:: // declaration for this parameter. QualType OldType = ParamTypes[i]; bool IsPackExpansion = false; + llvm::Optional<unsigned> NumExpansions; if (const PackExpansionType *Expansion = dyn_cast<PackExpansionType>(OldType)) { // We have a function parameter pack that may need to be expanded. @@ -3571,7 +3587,6 @@ bool TreeTransform<Derived>:: // Determine whether we should expand the parameter packs. bool ShouldExpand = false; bool RetainExpansion = false; - unsigned NumExpansions = 0; if (getDerived().TryExpandParameterPacks(Loc, SourceRange(), Unexpanded.data(), Unexpanded.size(), @@ -3584,7 +3599,7 @@ bool TreeTransform<Derived>:: if (ShouldExpand) { // Expand the function parameter pack into multiple, separate // parameters. - for (unsigned I = 0; I != NumExpansions; ++I) { + for (unsigned I = 0; I != *NumExpansions; ++I) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); QualType NewType = getDerived().TransformType(Pattern); if (NewType.isNull()) @@ -3624,7 +3639,8 @@ bool TreeTransform<Derived>:: return true; if (IsPackExpansion) - NewType = getSema().Context.getPackExpansionType(NewType); + NewType = getSema().Context.getPackExpansionType(NewType, + NumExpansions); OutParamTypes.push_back(NewType); if (PVars) @@ -4259,7 +4275,8 @@ QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB, Pattern != TL.getPatternLoc().getType()) { Result = getDerived().RebuildPackExpansionType(Pattern, TL.getPatternLoc().getSourceRange(), - TL.getEllipsisLoc()); + TL.getEllipsisLoc(), + TL.getTypePtr()->getNumExpansions()); if (Result.isNull()) return QualType(); } @@ -6818,7 +6835,7 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) { UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc()); bool ShouldExpand = false; bool RetainExpansion = false; - unsigned NumExpansions = 0; + llvm::Optional<unsigned> NumExpansions; if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(), &Unexpanded, 1, ShouldExpand, RetainExpansion, @@ -6832,7 +6849,7 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) { // that stores that length. return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(), - NumExpansions); + *NumExpansions); } template<typename Derived> |