aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Expr.cpp1
-rw-r--r--lib/AST/ExprCXX.cpp28
-rw-r--r--lib/AST/ExprClassification.cpp1
-rw-r--r--lib/AST/ExprConstant.cpp1
-rw-r--r--lib/AST/ItaniumMangle.cpp10
-rw-r--r--lib/AST/StmtPrinter.cpp4
-rw-r--r--lib/AST/StmtProfile.cpp8
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp1
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp93
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp3
-rw-r--r--lib/Sema/TreeTransform.h7
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp15
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp11
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp1
14 files changed, 181 insertions, 3 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 2ede77ec03..ea82cf7531 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2646,6 +2646,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx) const {
case UnresolvedMemberExprClass:
case PackExpansionExprClass:
case SubstNonTypeTemplateParmPackExprClass:
+ case FunctionParmPackExprClass:
llvm_unreachable("shouldn't see dependent / unresolved nodes here");
case DeclRefExprClass:
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 72e17b7417..e6076f007f 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -1299,6 +1299,34 @@ TemplateArgument SubstNonTypeTemplateParmPackExpr::getArgumentPack() const {
return TemplateArgument(Arguments, NumArguments);
}
+FunctionParmPackExpr::FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack,
+ SourceLocation NameLoc,
+ unsigned NumParams,
+ Decl * const *Params)
+ : Expr(FunctionParmPackExprClass, T, VK_LValue, OK_Ordinary,
+ true, true, true, true),
+ ParamPack(ParamPack), NameLoc(NameLoc), NumParameters(NumParams) {
+ if (Params)
+ std::uninitialized_copy(Params, Params + NumParams,
+ reinterpret_cast<Decl**>(this+1));
+}
+
+FunctionParmPackExpr *
+FunctionParmPackExpr::Create(ASTContext &Context, QualType T,
+ ParmVarDecl *ParamPack, SourceLocation NameLoc,
+ llvm::ArrayRef<Decl*> Params) {
+ return new (Context.Allocate(sizeof(FunctionParmPackExpr) +
+ sizeof(ParmVarDecl*) * Params.size()))
+ FunctionParmPackExpr(T, ParamPack, NameLoc, Params.size(), Params.data());
+}
+
+FunctionParmPackExpr *
+FunctionParmPackExpr::CreateEmpty(ASTContext &Context, unsigned NumParams) {
+ return new (Context.Allocate(sizeof(FunctionParmPackExpr) +
+ sizeof(ParmVarDecl*) * NumParams))
+ FunctionParmPackExpr(QualType(), 0, SourceLocation(), 0, 0);
+}
+
TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
ArrayRef<TypeSourceInfo *> Args,
SourceLocation RParenLoc,
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index f16d70b5da..24ec6bb020 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -134,6 +134,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
// ObjC instance variables are lvalues
// FIXME: ObjC++0x might have different rules
case Expr::ObjCIvarRefExprClass:
+ case Expr::FunctionParmPackExprClass:
return Cl::CL_LValue;
// C99 6.5.2.5p5 says that compound literals are lvalues.
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 2cd7f04e92..8f3f84d07d 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -6480,6 +6480,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
case Expr::OpaqueValueExprClass:
case Expr::PackExpansionExprClass:
case Expr::SubstNonTypeTemplateParmPackExprClass:
+ case Expr::FunctionParmPackExprClass:
case Expr::AsTypeExprClass:
case Expr::ObjCIndirectCopyRestoreExprClass:
case Expr::MaterializeTemporaryExprClass:
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 0b8a4c89f8..1a663a055d 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -2809,7 +2809,15 @@ recurse:
// };
Out << "_SUBSTPACK_";
break;
-
+
+ case Expr::FunctionParmPackExprClass: {
+ // FIXME: not clear how to mangle this!
+ const FunctionParmPackExpr *FPPE = cast<FunctionParmPackExpr>(E);
+ Out << "v110_SUBSTPACK";
+ mangleFunctionParam(FPPE->getParameterPack());
+ break;
+ }
+
case Expr::DependentScopeDeclRefExprClass: {
const DependentScopeDeclRefExpr *DRE = cast<DependentScopeDeclRefExpr>(E);
mangleUnresolvedName(DRE->getQualifier(), 0, DRE->getDeclName(), Arity);
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 0cf3aaf558..a64049b8d2 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1647,6 +1647,10 @@ void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
Visit(Node->getReplacement());
}
+void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
+ OS << *E->getParameterPack();
+}
+
void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
PrintExpr(Node->GetTemporaryExpr());
}
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 5d7f9f8ede..0c3186fec2 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -973,6 +973,14 @@ void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
Visit(E->getReplacement());
}
+void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
+ VisitExpr(S);
+ VisitDecl(S->getParameterPack());
+ ID.AddInteger(S->getNumExpansions());
+ for (FunctionParmPackExpr::iterator I = S->begin(), E = S->end(); I != E; ++I)
+ VisitDecl(*I);
+}
+
void StmtProfiler::VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *S) {
VisitExpr(S);
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index e6266fb086..e0e0d20310 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -1029,6 +1029,7 @@ CanThrowResult Sema::canThrow(const Expr *E) {
case Expr::PseudoObjectExprClass:
case Expr::SubstNonTypeTemplateParmExprClass:
case Expr::SubstNonTypeTemplateParmPackExprClass:
+ case Expr::FunctionParmPackExprClass:
case Expr::UnaryExprOrTypeTraitExprClass:
case Expr::UnresolvedLookupExprClass:
case Expr::UnresolvedMemberExprClass:
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index d3367c4ee9..fc8371bf21 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -802,11 +802,24 @@ namespace {
ExprResult TransformPredefinedExpr(PredefinedExpr *E);
ExprResult TransformDeclRefExpr(DeclRefExpr *E);
ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+
ExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
NonTypeTemplateParmDecl *D);
ExprResult TransformSubstNonTypeTemplateParmPackExpr(
SubstNonTypeTemplateParmPackExpr *E);
-
+
+ /// \brief Rebuild a DeclRefExpr for a ParmVarDecl reference.
+ ExprResult RebuildParmVarDeclRefExpr(ParmVarDecl *PD, SourceLocation Loc);
+
+ /// \brief Transform a reference to a function parameter pack.
+ ExprResult TransformFunctionParmPackRefExpr(DeclRefExpr *E,
+ ParmVarDecl *PD);
+
+ /// \brief Transform a FunctionParmPackExpr which was built when we couldn't
+ /// expand a function parameter pack reference which refers to an expanded
+ /// pack.
+ ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);
+
QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
FunctionProtoTypeLoc TL);
QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
@@ -1230,8 +1243,81 @@ TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr(
}
ExprResult
+TemplateInstantiator::RebuildParmVarDeclRefExpr(ParmVarDecl *PD,
+ SourceLocation Loc) {
+ DeclarationNameInfo NameInfo(PD->getDeclName(), Loc);
+ return getSema().BuildDeclarationNameExpr(CXXScopeSpec(), NameInfo, PD);
+}
+
+ExprResult
+TemplateInstantiator::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
+ if (getSema().ArgumentPackSubstitutionIndex != -1) {
+ // We can expand this parameter pack now.
+ ParmVarDecl *D = E->getExpansion(getSema().ArgumentPackSubstitutionIndex);
+ ValueDecl *VD = cast_or_null<ValueDecl>(TransformDecl(E->getExprLoc(), D));
+ if (!VD)
+ return ExprError();
+ return RebuildParmVarDeclRefExpr(cast<ParmVarDecl>(VD), E->getExprLoc());
+ }
+
+ QualType T = TransformType(E->getType());
+ if (T.isNull())
+ return ExprError();
+
+ // Transform each of the parameter expansions into the corresponding
+ // parameters in the instantiation of the function decl.
+ llvm::SmallVector<Decl*, 8> Parms;
+ Parms.reserve(E->getNumExpansions());
+ for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
+ I != End; ++I) {
+ ParmVarDecl *D =
+ cast_or_null<ParmVarDecl>(TransformDecl(E->getExprLoc(), *I));
+ if (!D)
+ return ExprError();
+ Parms.push_back(D);
+ }
+
+ return FunctionParmPackExpr::Create(getSema().Context, T,
+ E->getParameterPack(),
+ E->getParameterPackLocation(), Parms);
+}
+
+ExprResult
+TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E,
+ ParmVarDecl *PD) {
+ typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
+ llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found
+ = getSema().CurrentInstantiationScope->findInstantiationOf(PD);
+ assert(Found && "no instantiation for parameter pack");
+
+ Decl *TransformedDecl;
+ if (DeclArgumentPack *Pack = Found->dyn_cast<DeclArgumentPack *>()) {
+ // If this is a reference to a function parameter pack which we can substitute
+ // but can't yet expand, build a FunctionParmPackExpr for it.
+ if (getSema().ArgumentPackSubstitutionIndex == -1) {
+ QualType T = TransformType(E->getType());
+ if (T.isNull())
+ return ExprError();
+ return FunctionParmPackExpr::Create(getSema().Context, T, PD,
+ E->getExprLoc(), *Pack);
+ }
+
+ TransformedDecl = (*Pack)[getSema().ArgumentPackSubstitutionIndex];
+ } else {
+ TransformedDecl = Found->get<Decl*>();
+ }
+
+ // We have either an unexpanded pack or a specific expansion.
+ return RebuildParmVarDeclRefExpr(cast<ParmVarDecl>(TransformedDecl),
+ E->getExprLoc());
+}
+
+ExprResult
TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
NamedDecl *D = E->getDecl();
+
+ // Handle references to non-type template parameters and non-type template
+ // parameter packs.
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
if (NTTP->getDepth() < TemplateArgs.getNumLevels())
return TransformTemplateParmRefExpr(E, NTTP);
@@ -1240,6 +1326,11 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
// FindInstantiatedDecl will find it in the local instantiation scope.
}
+ // Handle references to function parameter packs.
+ if (ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
+ if (PD->isParameterPack())
+ return TransformFunctionParmPackRefExpr(E, PD);
+
return TreeTransform<TemplateInstantiator>::TransformDeclRefExpr(E);
}
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 55462ff09b..15afd1f6c9 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3397,7 +3397,8 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
if (Decl *FD = Found->dyn_cast<Decl *>())
return cast<NamedDecl>(FD);
- unsigned PackIdx = ArgumentPackSubstitutionIndex;
+ int PackIdx = ArgumentPackSubstitutionIndex;
+ assert(PackIdx != -1 && "found declaration pack but not pack expanding");
return cast<NamedDecl>((*Found->get<DeclArgumentPack *>())[PackIdx]);
}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 0c1f1a42a0..3d9a6ca11b 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -8321,6 +8321,13 @@ TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
template<typename Derived>
ExprResult
+TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
+ // Default behavior is to do nothing with this transformation.
+ return SemaRef.Owned(E);
+}
+
+template<typename Derived>
+ExprResult
TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
MaterializeTemporaryExpr *E) {
return getDerived().TransformExpr(E->GetTemporaryExpr());
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 6ca450b9fb..cfe22b5208 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1468,6 +1468,16 @@ void ASTStmtReader::VisitSubstNonTypeTemplateParmPackExpr(
E->NameLoc = ReadSourceLocation(Record, Idx);
}
+void ASTStmtReader::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
+ VisitExpr(E);
+ E->NumParameters = Record[Idx++];
+ E->ParamPack = ReadDeclAs<ParmVarDecl>(Record, Idx);
+ E->NameLoc = ReadSourceLocation(Record, Idx);
+ ParmVarDecl **Parms = reinterpret_cast<ParmVarDecl**>(E+1);
+ for (unsigned i = 0, n = E->NumParameters; i != n; ++i)
+ Parms[i] = ReadDeclAs<ParmVarDecl>(Record, Idx);
+}
+
void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
VisitExpr(E);
E->Temporary = Reader.ReadSubExpr();
@@ -2183,6 +2193,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
case EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK:
S = new (Context) SubstNonTypeTemplateParmPackExpr(Empty);
break;
+
+ case EXPR_FUNCTION_PARM_PACK:
+ S = FunctionParmPackExpr::CreateEmpty(Context,
+ Record[ASTStmtReader::NumExprFields]);
+ break;
case EXPR_MATERIALIZE_TEMPORARY:
S = new (Context) MaterializeTemporaryExpr(Empty);
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 5fa08d256c..9ca8130586 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1481,6 +1481,17 @@ void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
}
+void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
+ VisitExpr(E);
+ Record.push_back(E->getNumExpansions());
+ Writer.AddDeclRef(E->getParameterPack(), Record);
+ Writer.AddSourceLocation(E->getParameterPackLocation(), Record);
+ for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
+ I != End; ++I)
+ Writer.AddDeclRef(*I, Record);
+ Code = serialization::EXPR_FUNCTION_PARM_PACK;
+}
+
void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
VisitExpr(E);
Writer.AddStmt(E->Temporary);
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index d177b60a50..4d4faf6d0b 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -526,6 +526,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::CXXNoexceptExprClass:
case Stmt::PackExpansionExprClass:
case Stmt::SubstNonTypeTemplateParmPackExprClass:
+ case Stmt::FunctionParmPackExprClass:
case Stmt::SEHTryStmtClass:
case Stmt::SEHExceptStmtClass:
case Stmt::LambdaExprClass: