diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-03 17:17:50 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-03 17:17:50 +0000 |
commit | be230c36e32142cbdcdbe9c97511d097beeecbab (patch) | |
tree | a9c32a8f84720ac278c7bd11ab45b5d12859a7a0 | |
parent | 9917401b32f26b16ae6053d07903ac147b64a43b (diff) |
Implement support for pack expansions whose pattern is a non-type
template argument (described by an expression, of course). For
example:
template<int...> struct int_tuple { };
template<int ...Values>
struct square {
typedef int_tuple<(Values*Values)...> type;
};
It also lays the foundation for pack expansions in an initializer-list.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122751 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/ExprCXX.h | 55 | ||||
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 1 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | include/clang/Basic/StmtNodes.td | 1 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 11 | ||||
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 4 | ||||
-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 | ||||
-rw-r--r-- | test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp | 49 | ||||
-rw-r--r-- | tools/libclang/CXCursor.cpp | 1 |
21 files changed, 223 insertions, 22 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index eea15effac..bd7d3f09c3 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -2571,6 +2571,61 @@ public: virtual child_iterator child_end(); }; +/// \brief Represents a C++0x pack expansion that produces a sequence of +/// expressions. +/// +/// A pack expansion expression contains a pattern (which itself is an +/// expression) followed by an ellipsis. For example: +/// +/// \code +/// template<typename F, typename ...Types> +/// void forward(F f, Types &&...args) { +/// f(static_cast<Types&&>(args)...); +/// } +/// \endcode +/// +/// Here, the argument to the function object \c f is a pack expansion whose +/// pattern is \c static_cast<Types&&>(args). When the \c forward function +/// template is instantiated, the pack expansion will instantiate to zero or +/// or more function arguments to the function object \c f. +class PackExpansionExpr : public Expr { + SourceLocation EllipsisLoc; + Stmt *Pattern; + + friend class ASTStmtReader; + +public: + PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc) + : Expr(PackExpansionExprClass, T, Pattern->getValueKind(), + Pattern->getObjectKind(), /*TypeDependent=*/true, + /*ValueDependent=*/true, /*ContainsUnexpandedParameterPack=*/false), + EllipsisLoc(EllipsisLoc), + Pattern(Pattern) { } + + PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) { } + + /// \brief Retrieve the pattern of the pack expansion. + Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); } + + /// \brief Retrieve the pattern of the pack expansion. + const Expr *getPattern() const { return reinterpret_cast<Expr *>(Pattern); } + + /// \brief Retrieve the location of the ellipsis that describes this pack + /// expansion. + SourceLocation getEllipsisLoc() const { return EllipsisLoc; } + + virtual SourceRange getSourceRange() const; + + static bool classof(const Stmt *T) { + return T->getStmtClass() == PackExpansionExprClass; + } + static bool classof(const PackExpansionExpr *) { return true; } + + // Iterators + virtual child_iterator child_begin(); + virtual child_iterator child_end(); +}; + inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() { if (isa<UnresolvedLookupExpr>(this)) return cast<UnresolvedLookupExpr>(this)->getExplicitTemplateArgs(); diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 435ebc65ea..258e186b7a 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1820,6 +1820,7 @@ DEF_TRAVERSE_STMT(UnaryOperator, { }) DEF_TRAVERSE_STMT(BinaryOperator, { }) DEF_TRAVERSE_STMT(CompoundAssignOperator, { }) DEF_TRAVERSE_STMT(CXXNoexceptExpr, { }) +DEF_TRAVERSE_STMT(PackExpansionExpr, { }) // These literals (all of them) do not need any action. DEF_TRAVERSE_STMT(IntegerLiteral, { }) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index f2d3c0085c..eb123b9fe9 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1871,7 +1871,7 @@ def err_ellipsis_in_declarator_not_parameter : Error< // Unsupported variadic templates features def err_pack_expansion_unsupported : Error< - "clang does not yet support %select{non-type|template}0 pack expansions">; + "clang does not yet support template pack expansions">; def err_pack_expansion_instantiation_unsupported : Error< "clang cannot yet instantiate pack expansions">; def err_pack_expansion_mismatch_unsupported : Error< diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index 0e2fb575e6..890f02b75d 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -111,6 +111,7 @@ def OverloadExpr : DStmt<Expr, 1>; def UnresolvedLookupExpr : DStmt<OverloadExpr>; def UnresolvedMemberExpr : DStmt<OverloadExpr>; def CXXNoexceptExpr : DStmt<Expr>; +def PackExpansionExpr : DStmt<Expr>; // Obj-C Expressions. def ObjCStringLiteral : DStmt<Expr>; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 57f480f95d..05bb1258c1 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -3279,7 +3279,7 @@ public: ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc); - /// \brief Invoked when parsing a type follows by an ellipsis, which + /// \brief Invoked when parsing a type followed by an ellipsis, which /// creates a pack expansion. /// /// \param Type The type preceding the ellipsis, which will become @@ -3293,6 +3293,15 @@ public: TypeSourceInfo *CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc); + /// \brief Invoked when parsing an expression followed by an ellipsis, which + /// creates a pack expansion. + /// + /// \param Pattern The expression preceding the ellipsis, which will become + /// the pattern of the pack expansion. + /// + /// \param EllipsisLoc The location of the ellipsis. + ExprResult ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc); + /// \brief Determine whether we could expand a pack expansion with the /// given set of parameter packs into separate arguments by repeatedly /// transforming the pattern. diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 8665fb6465..fcc8d53d42 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -929,7 +929,9 @@ namespace clang { EXPR_CXX_NOEXCEPT, // CXXNoexceptExpr EXPR_OPAQUE_VALUE, // OpaqueValueExpr - EXPR_BINARY_TYPE_TRAIT // BinaryTypeTraitExpr + EXPR_BINARY_TYPE_TRAIT, // BinaryTypeTraitExpr + + EXPR_PACK_EXPANSION // PackExpansionExpr }; /// \brief The kinds of designators that can occur in a 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; diff --git a/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp b/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp index 6a5e989d1a..d9a3b5c27f 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp @@ -64,3 +64,52 @@ namespace Replace { int check0[is_same<EverythingToInt<tuple<double, float>>::type, tuple<int, int>>::value? 1 : -1]; } + +namespace Multiply { + template<int ...Values> + struct double_values { + typedef int_tuple<Values*2 ...> type; + }; + + int check0[is_same<double_values<1, 2, -3>::type, + int_tuple<2, 4, -6>>::value? 1 : -1]; + + template<int ...Values> + struct square { + typedef int_tuple<(Values*Values)...> type; + }; + + int check1[is_same<square<1, 2, -3>::type, + int_tuple<1, 4, 9>>::value? 1 : -1]; + + template<typename IntTuple> struct square_tuple; + + template<int ...Values> + struct square_tuple<int_tuple<Values...>> { + typedef int_tuple<(Values*Values)...> type; + }; + + int check2[is_same<square_tuple<int_tuple<1, 2, -3>>::type, + int_tuple<1, 4, 9>>::value? 1 : -1]; +} + +namespace Indices { + template<unsigned I, unsigned N, typename IntTuple> + struct build_indices_impl; + + template<unsigned I, unsigned N, int ...Indices> + struct build_indices_impl<I, N, int_tuple<Indices...> > + : build_indices_impl<I+1, N, int_tuple<Indices..., I> > { + }; + + template<unsigned N, int ...Indices> + struct build_indices_impl<N, N, int_tuple<Indices...> > { + typedef int_tuple<Indices...> type; + }; + + template<unsigned N> + struct build_indices : build_indices_impl<0, N, int_tuple<> > { }; + + int check0[is_same<build_indices<5>::type, + int_tuple<0, 1, 2, 3, 4>>::value? 1 : -1]; +} diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index 86b5ce1c4c..22758f9ba4 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -164,6 +164,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, case Stmt::ShuffleVectorExprClass: case Stmt::BlockExprClass: case Stmt::OpaqueValueExprClass: + case Stmt::PackExpansionExprClass: K = CXCursor_UnexposedExpr; break; |