diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ExprCXX.cpp | 12 | ||||
-rw-r--r-- | lib/AST/ExprClassification.cpp | 3 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 1 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 5 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 4 | ||||
-rw-r--r-- | lib/AST/TemplateBase.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 38 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 7 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 13 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 9 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/ExprEngine.cpp | 1 |
13 files changed, 102 insertions, 19 deletions
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index cbd33f2dc4..4592e5f571 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -1025,3 +1025,15 @@ Stmt::child_iterator CXXNoexceptExpr::child_begin() { Stmt::child_iterator CXXNoexceptExpr::child_end() { return child_iterator(&Operand + 1); } + +SourceRange PackExpansionExpr::getSourceRange() const { + return SourceRange(Pattern->getLocStart(), EllipsisLoc); +} + +Stmt::child_iterator PackExpansionExpr::child_begin() { + return child_iterator(&Pattern); +} + +Stmt::child_iterator PackExpansionExpr::child_end() { + return child_iterator(&Pattern + 1); +} diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp index 4cf393d788..f437804c29 100644 --- a/lib/AST/ExprClassification.cpp +++ b/lib/AST/ExprClassification.cpp @@ -304,6 +304,9 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::CXXUuidofExprClass: return Cl::CL_LValue; + + case Expr::PackExpansionExprClass: + return ClassifyInternal(Ctx, cast<PackExpansionExpr>(E)->getPattern()); } llvm_unreachable("unhandled expression kind in classification"); diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 8797880411..c39b3983d3 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2634,6 +2634,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case Expr::BlockDeclRefExprClass: case Expr::NoStmtClass: case Expr::OpaqueValueExprClass: + case Expr::PackExpansionExprClass: return ICEDiag(2, E->getLocStart()); case Expr::GNUNullExprClass: diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 6bbe8f9cd9..cc90526736 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -1246,6 +1246,11 @@ void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { OS << ")"; } +void StmtPrinter::VisitPackExpansionExpr(clang::PackExpansionExpr *E) { + PrintExpr(E->getPattern()); + OS << "..."; +} + // Obj-C void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index 66c067b7b1..820eb06416 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -832,6 +832,10 @@ void StmtProfiler::VisitCXXNoexceptExpr(CXXNoexceptExpr *S) { VisitExpr(S); } +void StmtProfiler::VisitPackExpansionExpr(PackExpansionExpr *S) { + VisitExpr(S); +} + void StmtProfiler::VisitOpaqueValueExpr(OpaqueValueExpr *E) { VisitExpr(E); } diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp index 04e8a389cf..c971519961 100644 --- a/lib/AST/TemplateBase.cpp +++ b/lib/AST/TemplateBase.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/FoldingSet.h" @@ -72,15 +73,14 @@ bool TemplateArgument::isPackExpansion() const { return false; case Type: - return llvm::isa<PackExpansionType>(getAsType()); + return isa<PackExpansionType>(getAsType()); case Template: // FIXME: Template template pack expansions. break; case Expression: - // FIXME: Expansion pack expansions. - break; + return isa<PackExpansionExpr>(getAsExpr()); } return false; @@ -199,9 +199,11 @@ TemplateArgument TemplateArgument::getPackExpansionPattern() const { return getAsType()->getAs<PackExpansionType>()->getPattern(); case Expression: + return cast<PackExpansionExpr>(getAsExpr())->getPattern(); + case Template: // FIXME: Variadic templates. - llvm_unreachable("Expression and template pack expansions unsupported"); + llvm_unreachable("Template pack expansions unsupported"); case Declaration: case Integral: @@ -343,10 +345,14 @@ TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis, PatternTSInfo); } - case TemplateArgument::Expression: + case TemplateArgument::Expression: { + Expr *Pattern = cast<PackExpansionExpr>(Argument.getAsExpr())->getPattern(); + return TemplateArgumentLoc(Pattern, Pattern); + } + case TemplateArgument::Template: // FIXME: Variadic templates. - llvm_unreachable("Expression and template pack expansions unsupported"); + llvm_unreachable("Template pack expansions unsupported"); case TemplateArgument::Declaration: case TemplateArgument::Integral: diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index a45403e467..0aa9f402f9 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -2043,7 +2043,11 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { Out << "LDnE"; break; } - + + case Expr::PackExpansionExprClass: + Out << "sp"; + mangleExpression(cast<PackExpansionExpr>(E)->getPattern()); + break; } } diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 4a667cdf57..99b6daceed 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -2926,6 +2926,10 @@ MarkUsedTemplateParameters(Sema &SemaRef, bool OnlyDeduced, unsigned Depth, llvm::SmallVectorImpl<bool> &Used) { + // We can deduce from a pack expansion. + if (const PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(E)) + E = Expansion->getPattern(); + // FIXME: if !OnlyDeduced, we have to walk the whole subexpression to // find other occurrences of template parameters. const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E); diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 3dac8a0408..030a0423f7 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -79,9 +79,6 @@ namespace { // FIXME: Record occurrences of template template parameter packs. - // FIXME: Once we have pack expansions in the AST, block their - // traversal. - //------------------------------------------------------------------------ // Pruning the search for unexpanded parameter packs. //------------------------------------------------------------------------ @@ -299,14 +296,17 @@ Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg, Arg.getLocation()); } - case ParsedTemplateArgument::NonType: - Diag(EllipsisLoc, diag::err_pack_expansion_unsupported) - << 0; - return ParsedTemplateArgument(); - + case ParsedTemplateArgument::NonType: { + ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc); + if (Result.isInvalid()) + return ParsedTemplateArgument(); + + return ParsedTemplateArgument(Arg.getKind(), Result.get(), + Arg.getLocation()); + } + case ParsedTemplateArgument::Template: - Diag(EllipsisLoc, diag::err_pack_expansion_unsupported) - << 1; + Diag(EllipsisLoc, diag::err_pack_expansion_unsupported); return ParsedTemplateArgument(); } llvm_unreachable("Unhandled template argument kind?"); @@ -352,6 +352,24 @@ TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern, return TSResult; } +ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) { + if (!Pattern) + return ExprError(); + + // 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) + << Pattern->getSourceRange(); + return ExprError(); + } + + // Create the pack expansion expression and source-location information. + return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern, + EllipsisLoc)); +} bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, SourceRange PatternRange, diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index de13084fbc..992b849904 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -6439,6 +6439,13 @@ TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) { template<typename Derived> ExprResult +TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) { + llvm_unreachable("pack expansion expression in unhandled context"); + return ExprError(); +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) { return SemaRef.Owned(E); } diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index aa669b34b3..4703c633fb 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -176,7 +176,8 @@ namespace clang { void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E); void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E); void VisitCXXNoexceptExpr(CXXNoexceptExpr *E); - + void VisitPackExpansionExpr(PackExpansionExpr *E); + void VisitOpaqueValueExpr(OpaqueValueExpr *E); }; } @@ -1287,6 +1288,12 @@ void ASTStmtReader::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { E->Operand = Reader.ReadSubExpr(); } +void ASTStmtReader::VisitPackExpansionExpr(PackExpansionExpr *E) { + VisitExpr(E); + E->EllipsisLoc = ReadSourceLocation(Record, Idx); + E->Pattern = Reader.ReadSubExpr(); +} + void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) { VisitExpr(E); } @@ -1809,6 +1816,10 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { S = new (Context) CXXNoexceptExpr(Empty); break; + case EXPR_PACK_EXPANSION: + S = new (Context) PackExpansionExpr(Empty); + break; + case EXPR_OPAQUE_VALUE: S = new (Context) OpaqueValueExpr(Empty); break; diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 89c293fe6c..27261dbb2a 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -150,7 +150,7 @@ namespace clang { void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E); void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E); void VisitCXXNoexceptExpr(CXXNoexceptExpr *E); - + void VisitPackExpansionExpr(PackExpansionExpr *E); void VisitOpaqueValueExpr(OpaqueValueExpr *E); }; } @@ -1296,6 +1296,13 @@ void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { Code = serialization::EXPR_CXX_NOEXCEPT; } +void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) { + VisitExpr(E); + Writer.AddSourceLocation(E->getEllipsisLoc(), Record); + Writer.AddStmt(E->getPattern()); + Code = serialization::EXPR_PACK_EXPANSION; +} + void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) { VisitExpr(E); Code = serialization::EXPR_OPAQUE_VALUE; diff --git a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp index c522e72210..9fef6d87be 100644 --- a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp @@ -771,6 +771,7 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred, case Stmt::UnresolvedLookupExprClass: case Stmt::UnresolvedMemberExprClass: case Stmt::CXXNoexceptExprClass: + case Stmt::PackExpansionExprClass: { SaveAndRestore<bool> OldSink(Builder->BuildSinks); Builder->BuildSinks = true; |