[cfe-commits] r122527 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ lib/AST/ lib/Sema/ lib/Serialization/ test/CXX/dcl.decl/dcl.meaning/dcl.fct/ test/CXX/temp/temp.decls/temp.variadic/
Douglas Gregor
dgregor at apple.com
Thu Dec 23 15:51:58 PST 2010
Author: dgregor
Date: Thu Dec 23 17:51:58 2010
New Revision: 122527
URL: http://llvm.org/viewvc/llvm-project?rev=122527&view=rev
Log:
Add an AST representation for non-type template parameter
packs, e.g.,
template<typename T, unsigned ...Dims> struct multi_array;
along with semantic analysis support for finding unexpanded non-type
template parameter packs in types, expressions, and so on.
Template instantiation involving non-type template parameter packs
probably doesn't work yet. That'll come soon.
Modified:
cfe/trunk/include/clang/AST/DeclTemplate.h
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/AST/DeclTemplate.cpp
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp
cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Thu Dec 23 17:51:58 2010
@@ -990,17 +990,27 @@
/// it was inherited.
llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
+ // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
+ // down here to save memory.
+
+ /// \brief Whether this non-type template parameter is a parameter pack.
+ bool ParameterPack;
+
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo)
+ bool ParameterPack, TypeSourceInfo *TInfo)
: VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, SC_None, SC_None),
- TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false)
+ TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
+ ParameterPack(ParameterPack)
{ }
+ friend class ASTDeclReader;
+
public:
static NonTypeTemplateParmDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
- unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo);
+ unsigned P, IdentifierInfo *Id, QualType T, bool ParameterPack,
+ TypeSourceInfo *TInfo);
using TemplateParmPosition::getDepth;
using TemplateParmPosition::setDepth;
@@ -1042,6 +1052,17 @@
DefaultArgumentAndInherited.setInt(false);
}
+ /// \brief Whether this parameter is a non-type template parameter pack.
+ ///
+ /// If the parameter is a parameter pack, the type may be a
+ /// \c PackExpansionType. In the following example, the \c Dims parameter
+ /// is a parameter pack (whose type is 'unsigned').
+ ///
+ /// \code
+ /// template<typename T, unsigned ...Dims> struct multi_array;
+ /// \endcode
+ bool isParameterPack() const { return ParameterPack; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Dec 23 17:51:58 2010
@@ -3564,6 +3564,7 @@
Stmt *CopyConstructorVal;
public:
// FIXME: Fix type/value dependence!
+ // FIXME: Variadic templates.
BlockDeclRefExpr(ValueDecl *d, QualType t, ExprValueKind VK,
SourceLocation l, bool ByRef, bool constAdded = false,
Stmt *copyConstructorVal = 0)
Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Thu Dec 23 17:51:58 2010
@@ -47,6 +47,8 @@
def err_invalid_storage_class_in_func_decl : Error<
"invalid storage class specifier in function declarator">;
def err_expected_namespace_name : Error<"expected namespace name">;
+def err_variadic_templates : Error<
+ "variadic templates are only allowed in C++0x">;
// Sema && Lex
def ext_longlong : Extension<
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Thu Dec 23 17:51:58 2010
@@ -374,9 +374,6 @@
def err_explicit_spec_non_template : Error<
"explicit %select{specialization|instantiation}0 of non-template "
"%select{class|struct|union}1 %2">;
-
-def err_variadic_templates : Error<
- "variadic templates are only allowed in C++0x">;
def err_default_template_template_parameter_not_template : Error<
"default template argument for a template template parameter must be a class "
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Dec 23 17:51:58 2010
@@ -1876,8 +1876,6 @@
"clang cannot yet instantiate pack expansions with mismatched pack levels">;
def err_function_parameter_pack_unsupported : Error<
"clang does not yet support function parameter packs">;
-def err_non_type_parameter_pack_unsupported : Error<
- "clang does not yet support non-type template parameter packs">;
def err_unexpected_typedef : Error<
"unexpected type name %0: expected expression">;
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Dec 23 17:51:58 2010
@@ -109,6 +109,7 @@
SourceLocation(), NTTP->getDepth(),
NTTP->getPosition(), 0,
getCanonicalType(NTTP->getType()),
+ NTTP->isParameterPack(),
0));
else
CanonParams.push_back(getCanonicalTemplateTemplateParmDecl(
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Dec 23 17:51:58 2010
@@ -3414,7 +3414,7 @@
Importer.getToContext().getTranslationUnitDecl(),
Loc, D->getDepth(), D->getPosition(),
Name.getAsIdentifierInfo(),
- T, TInfo);
+ T, D->isParameterPack(), TInfo);
}
Decl *
Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Thu Dec 23 17:51:58 2010
@@ -110,7 +110,9 @@
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;
}
Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Thu Dec 23 17:51:58 2010
@@ -390,8 +390,9 @@
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 {
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Dec 23 17:51:58 2010
@@ -208,8 +208,14 @@
// 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,
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Dec 23 17:51:58 2010
@@ -632,16 +632,12 @@
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 @@
}
// 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;
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Dec 23 17:51:58 2010
@@ -1506,11 +1506,12 @@
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();
Modified: cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp Thu Dec 23 17:51:58 2010
@@ -63,8 +63,21 @@
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 @@
/// \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;
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Dec 23 17:51:58 2010
@@ -1504,6 +1504,8 @@
// 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:
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Dec 23 17:51:58 2010
@@ -1156,6 +1156,7 @@
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 @@
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);
Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Thu Dec 23 17:51:58 2010
@@ -994,6 +994,7 @@
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());
Modified: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp Thu Dec 23 17:51:58 2010
@@ -11,12 +11,12 @@
// [ Note: Otherwise, the parameter-declaration is part of a
// template-parameter-list and the parameter pack is a template
// parameter pack; see 14.1. -- end note ]
-template<int ...N> // FIXME: temporary expected-error{{clang does not yet support non-type template parameter packs}}
+template<int ...N>
struct X0 { };
template<typename ...Types>
struct X1 {
- template<Types ...Values> struct Inner; // FIXME: temporary expected-error{{clang does not yet support non-type template parameter packs}}
+ template<Types ...Values> struct Inner;
};
// A declarator-id or abstract-declarator containing an ellipsis shall
Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp?rev=122527&r1=122526&r2=122527&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp Thu Dec 23 17:51:58 2010
@@ -128,6 +128,26 @@
};
// FIXME: Test for unexpanded parameter packs in each of the expression nodes.
+template<int ...Values>
+void test_unexpanded_in_exprs() {
+ // PredefinedExpr is uninteresting
+ // DeclRefExpr
+ Values; // expected-error{{expression contains unexpanded parameter pack 'Values'}}
+ // IntegerLiteral is uninteresting
+ // FloatingLiteral is uninteresting
+ // ImaginaryLiteral is uninteresting
+ // StringLiteral is uninteresting
+ // CharacterLiteral is uninteresting
+ (Values); // expected-error{{expression contains unexpanded parameter pack 'Values'}}
+ // UnaryOperator
+ -Values; // expected-error{{expression contains unexpanded parameter pack 'Values'}}
+ // OffsetOfExpr
+ struct OffsetMe {
+ int array[17];
+ };
+ __builtin_offsetof(OffsetMe, array[Values]); // expected-error{{expression contains unexpanded parameter pack 'Values'}}
+ // FIXME: continue this...
+}
template<typename ... Types>
void TestPPNameFunc(int i) {
More information about the cfe-commits
mailing list