aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp1
-rw-r--r--lib/AST/ASTImporter.cpp2
-rw-r--r--lib/AST/DeclBase.cpp4
-rw-r--r--lib/AST/DeclTemplate.cpp5
-rw-r--r--lib/AST/Expr.cpp10
-rw-r--r--lib/Sema/SemaTemplate.cpp12
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp3
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp21
-rw-r--r--lib/Sema/SemaType.cpp2
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp3
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp1
11 files changed, 44 insertions, 20 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e20b1ed63f..eaf222cafa 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -109,6 +109,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
SourceLocation(), NTTP->getDepth(),
NTTP->getPosition(), 0,
getCanonicalType(NTTP->getType()),
+ NTTP->isParameterPack(),
0));
else
CanonParams.push_back(getCanonicalTemplateTemplateParmDecl(
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 7ff217e334..7d6c90519b 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -3414,7 +3414,7 @@ ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
Importer.getToContext().getTranslationUnitDecl(),
Loc, D->getDepth(), D->getPosition(),
Name.getAsIdentifierInfo(),
- T, TInfo);
+ T, D->isParameterPack(), TInfo);
}
Decl *
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 843e907dea..75ea2df27e 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -110,7 +110,9 @@ void Decl::add(Kind k) {
bool Decl::isTemplateParameterPack() const {
if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(this))
return TTP->isParameterPack();
-
+ if (const NonTypeTemplateParmDecl *NTTP
+ = llvm::dyn_cast<NonTypeTemplateParmDecl>(this))
+ return NTTP->isParameterPack();
return false;
}
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 422e5e30f8..dff956c6dc 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -390,8 +390,9 @@ NonTypeTemplateParmDecl *
NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D, unsigned P,
IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo) {
- return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, TInfo);
+ bool ParameterPack, TypeSourceInfo *TInfo) {
+ return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, ParameterPack,
+ TInfo);
}
SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 5d0e0e3093..d8bb0af018 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -208,8 +208,14 @@ void DeclRefExpr::computeDependence() {
// member of an unknown specialization.
// (handled by DependentScopeDeclRefExpr)
- // FIXME: Variadic templates require that we compute whether this
- // declaration reference contains an unexpanded parameter pack.
+ // Determine whether this expression contains any unexpanded parameter
+ // packs.
+ // Is the declaration a parameter pack?
+ if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
+ if (NTTP->isParameterPack())
+ ExprBits.ContainsUnexpandedParameterPack = true;
+ }
+ // FIXME: Variadic templates function parameter packs.
}
DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 7357e94490..a487825bb3 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -632,16 +632,12 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
Invalid = true;
}
- if (D.hasEllipsis()) {
- // FIXME: Variadic templates.
- Diag(D.getEllipsisLoc(), diag::err_non_type_parameter_pack_unsupported);
- Invalid = true;
- }
-
+ bool IsParameterPack = D.hasEllipsis();
NonTypeTemplateParmDecl *Param
= NonTypeTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(),
D.getIdentifierLoc(),
- Depth, Position, ParamName, T, TInfo);
+ Depth, Position, ParamName, T,
+ IsParameterPack, TInfo);
if (Invalid)
Param->setInvalidDecl();
@@ -652,7 +648,7 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
}
// Check the well-formedness of the default template argument, if provided.
- if (Default) {
+ if (Default) {
// Check for unexpanded parameter packs.
if (DiagnoseUnexpandedParameterPack(Default, UPPC_DefaultArgument))
return Param;
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 54c509544f..9db3a8cacf 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1506,11 +1506,12 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
Invalid = true;
}
+ // FIXME: Variadic templates.
NonTypeTemplateParmDecl *Param
= NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
D->getDepth() - TemplateArgs.getNumLevels(),
D->getPosition(), D->getIdentifier(), T,
- DI);
+ D->isParameterPack(), DI);
if (Invalid)
Param->setInvalidDecl();
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index d9c7e72a86..fe30ba5845 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -63,8 +63,21 @@ namespace {
return true;
}
- // FIXME: Record occurrences of non-type and template template
- // parameter packs.
+ /// \brief Record occurrences of (FIXME: function and) non-type template
+ /// parameter packs in an expression.
+ bool VisitDeclRefExpr(DeclRefExpr *E) {
+ if (NonTypeTemplateParmDecl *NTTP
+ = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) {
+ if (NTTP->isParameterPack())
+ Unexpanded.push_back(std::make_pair(NTTP, E->getLocation()));
+ }
+
+ // FIXME: Function parameter packs.
+
+ return true;
+ }
+
+ // FIXME: Record occurrences of template template parameter packs.
// FIXME: Once we have pack expansions in the AST, block their
// traversal.
@@ -95,8 +108,8 @@ namespace {
/// \brief Suppress traversel into types with location information
/// that do not contain unexpanded parameter packs.
bool TraverseTypeLoc(TypeLoc TL) {
- if (!TL.getType().isNull() && TL.
- getType()->containsUnexpandedParameterPack())
+ if (!TL.getType().isNull() &&
+ TL.getType()->containsUnexpandedParameterPack())
return inherited::TraverseTypeLoc(TL);
return true;
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index e693c8d4da..46ec0fe109 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1504,6 +1504,8 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
// it expands those parameter packs.
if (T->containsUnexpandedParameterPack())
T = Context.getPackExpansionType(T);
+ else if (!getLangOptions().CPlusPlus0x)
+ Diag(D.getEllipsisLoc(), diag::err_variadic_templates);
break;
case Declarator::FileContext:
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 6100d65757..f2183ea695 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1156,6 +1156,7 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
D->setDepth(Record[Idx++]);
D->setPosition(Record[Idx++]);
// Rest of NonTypeTemplateParmDecl.
+ D->ParameterPack = Record[Idx++];
if (Record[Idx++]) {
Expr *DefArg = Reader.ReadExpr(F);
bool Inherited = Record[Idx++];
@@ -1429,7 +1430,7 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
break;
case DECL_NON_TYPE_TEMPLATE_PARM:
D = NonTypeTemplateParmDecl::Create(*Context, 0, SourceLocation(), 0,0,0,
- QualType(),0);
+ QualType(), false, 0);
break;
case DECL_TEMPLATE_TEMPLATE_PARM:
D = TemplateTemplateParmDecl::Create(*Context, 0, SourceLocation(),0,0,0,0);
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index aa145c415b..add6cd343d 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -994,6 +994,7 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
Record.push_back(D->getDepth());
Record.push_back(D->getPosition());
// Rest of NonTypeTemplateParmDecl.
+ Record.push_back(D->isParameterPack());
Record.push_back(D->getDefaultArgument() != 0);
if (D->getDefaultArgument()) {
Writer.AddStmt(D->getDefaultArgument());