diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-12 17:07:58 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-12 17:07:58 +0000 |
commit | 2fc1bb76e719d0620b4a6e2134413933b21ca6b6 (patch) | |
tree | 1892f43a3d00d796f550f720b4492cc0d0fae77b /lib/Sema | |
parent | 4ba2a17694148e16eaa8d3917f657ffcd3667be4 (diff) |
Teach TreeTransform how to transform a pack expansion type into
another pack expansion type. This can happen when rebuilding types in
the current instantiation.
Fixes <rdar://problem/8848837> (Clang crashing on libc++ <functional>).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123316 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 31 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 30 |
2 files changed, 49 insertions, 12 deletions
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 63a8394d67..473dcb7d1f 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -377,18 +377,13 @@ TypeResult Sema::ActOnPackExpansion(ParsedType Type, TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc) { - // 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 - // expansion. - if (!Pattern->getType()->containsUnexpandedParameterPack()) { - Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) - << Pattern->getTypeLoc().getSourceRange(); + // Create the pack expansion type and source-location information. + QualType Result = CheckPackExpansion(Pattern->getType(), + Pattern->getTypeLoc().getSourceRange(), + EllipsisLoc); + if (Result.isNull()) return 0; - } - // Create the pack expansion type and source-location information. - QualType Result = Context.getPackExpansionType(Pattern->getType()); TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result); PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc()); TL.setEllipsisLoc(EllipsisLoc); @@ -400,6 +395,22 @@ TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern, return TSResult; } +QualType Sema::CheckPackExpansion(QualType Pattern, + SourceRange PatternRange, + SourceLocation EllipsisLoc) { + // 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 + // expansion. + if (!Pattern->containsUnexpandedParameterPack()) { + Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) + << PatternRange; + return QualType(); + } + + return Context.getPackExpansionType(Pattern); +} + ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) { if (!Pattern) return ExprError(); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index e63cc7da7c..f601d5c047 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -808,6 +808,16 @@ public: return SemaRef.Context.getElaboratedType(Keyword, NNS, T); } + /// \brief Build a new pack expansion type. + /// + /// By default, builds a new PackExpansionType type from the given pattern. + /// Subclasses may override this routine to provide different behavior. + QualType RebuildPackExpansionType(QualType Pattern, + SourceRange PatternRange, + SourceLocation EllipsisLoc) { + return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc); + } + /// \brief Build a new nested-name-specifier given the prefix and an /// identifier that names the next step in the nested-name-specifier. /// @@ -4232,8 +4242,24 @@ QualType TreeTransform<Derived>:: template<typename Derived> QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB, PackExpansionTypeLoc TL) { - llvm_unreachable("Caller must expansion pack expansion types"); - return QualType(); + QualType Pattern + = getDerived().TransformType(TLB, TL.getPatternLoc()); + if (Pattern.isNull()) + return QualType(); + + QualType Result = TL.getType(); + if (getDerived().AlwaysRebuild() || + Pattern != TL.getPatternLoc().getType()) { + Result = getDerived().RebuildPackExpansionType(Pattern, + TL.getPatternLoc().getSourceRange(), + TL.getEllipsisLoc()); + if (Result.isNull()) + return QualType(); + } + + PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result); + NewT.setEllipsisLoc(TL.getEllipsisLoc()); + return Result; } template<typename Derived> |