2010-12-16 01:38:57 +08:00
|
|
|
//===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//===----------------------------------------------------------------------===/
|
|
|
|
//
|
|
|
|
// This file implements semantic analysis for C++0x variadic templates.
|
|
|
|
//===----------------------------------------------------------------------===/
|
|
|
|
|
|
|
|
#include "clang/Sema/Sema.h"
|
2014-01-07 19:51:46 +08:00
|
|
|
#include "TypeLocBuilder.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/AST/Expr.h"
|
|
|
|
#include "clang/AST/RecursiveASTVisitor.h"
|
|
|
|
#include "clang/AST/TypeLoc.h"
|
2011-01-05 01:33:58 +08:00
|
|
|
#include "clang/Sema/Lookup.h"
|
2010-12-20 10:24:11 +08:00
|
|
|
#include "clang/Sema/ParsedTemplate.h"
|
2012-07-25 11:56:55 +08:00
|
|
|
#include "clang/Sema/ScopeInfo.h"
|
2010-12-16 01:38:57 +08:00
|
|
|
#include "clang/Sema/SemaInternal.h"
|
2010-12-21 06:05:00 +08:00
|
|
|
#include "clang/Sema/Template.h"
|
2010-12-16 01:38:57 +08:00
|
|
|
|
|
|
|
using namespace clang;
|
|
|
|
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// Visitor that collects unexpanded parameter packs
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
/// \brief A class that collects unexpanded parameter packs.
|
|
|
|
class CollectUnexpandedParameterPacksVisitor :
|
|
|
|
public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
|
|
|
|
{
|
|
|
|
typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
|
|
|
|
inherited;
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
|
2012-07-25 11:56:55 +08:00
|
|
|
bool InLambda;
|
|
|
|
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
public:
|
|
|
|
explicit CollectUnexpandedParameterPacksVisitor(
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
|
2012-07-25 11:56:55 +08:00
|
|
|
: Unexpanded(Unexpanded), InLambda(false) { }
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
|
2010-12-21 07:07:20 +08:00
|
|
|
bool shouldWalkTypesOfTypeLocs() const { return false; }
|
|
|
|
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Recording occurrences of (unexpanded) parameter packs.
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/// \brief Record occurrences of template type parameter packs.
|
|
|
|
bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
|
|
|
|
if (TL.getTypePtr()->isParameterPack())
|
|
|
|
Unexpanded.push_back(std::make_pair(TL.getTypePtr(), TL.getNameLoc()));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Record occurrences of template type parameter packs
|
|
|
|
/// when we don't have proper source-location information for
|
|
|
|
/// them.
|
|
|
|
///
|
|
|
|
/// Ideally, this routine would never be used.
|
|
|
|
bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
|
|
|
|
if (T->isParameterPack())
|
|
|
|
Unexpanded.push_back(std::make_pair(T, SourceLocation()));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-01-20 05:32:01 +08:00
|
|
|
/// \brief Record occurrences of function and non-type template
|
2010-12-24 07:51:58 +08:00
|
|
|
/// parameter packs in an expression.
|
|
|
|
bool VisitDeclRefExpr(DeclRefExpr *E) {
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
if (E->getDecl()->isParameterPack())
|
|
|
|
Unexpanded.push_back(std::make_pair(E->getDecl(), E->getLocation()));
|
2010-12-24 07:51:58 +08:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-01-05 23:48:55 +08:00
|
|
|
/// \brief Record occurrences of template template parameter packs.
|
|
|
|
bool TraverseTemplateName(TemplateName Template) {
|
|
|
|
if (TemplateTemplateParmDecl *TTP
|
|
|
|
= dyn_cast_or_null<TemplateTemplateParmDecl>(
|
|
|
|
Template.getAsTemplateDecl()))
|
|
|
|
if (TTP->isParameterPack())
|
|
|
|
Unexpanded.push_back(std::make_pair(TTP, SourceLocation()));
|
|
|
|
|
|
|
|
return inherited::TraverseTemplateName(Template);
|
|
|
|
}
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
/// \brief Suppress traversal into Objective-C container literal
|
|
|
|
/// elements that are pack expansions.
|
|
|
|
bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
|
|
|
|
if (!E->containsUnexpandedParameterPack())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
|
|
|
|
ObjCDictionaryElement Element = E->getKeyValueElement(I);
|
|
|
|
if (Element.isPackExpansion())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
TraverseStmt(Element.Key);
|
|
|
|
TraverseStmt(Element.Value);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Pruning the search for unexpanded parameter packs.
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/// \brief Suppress traversal into statements and expressions that
|
|
|
|
/// do not contain unexpanded parameter packs.
|
|
|
|
bool TraverseStmt(Stmt *S) {
|
2012-07-25 11:56:55 +08:00
|
|
|
Expr *E = dyn_cast_or_null<Expr>(S);
|
|
|
|
if ((E && E->containsUnexpandedParameterPack()) || InLambda)
|
|
|
|
return inherited::TraverseStmt(S);
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
|
2012-07-25 11:56:55 +08:00
|
|
|
return true;
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Suppress traversal into types that do not contain
|
|
|
|
/// unexpanded parameter packs.
|
|
|
|
bool TraverseType(QualType T) {
|
2012-07-25 11:56:55 +08:00
|
|
|
if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda)
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
return inherited::TraverseType(T);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Suppress traversel into types with location information
|
|
|
|
/// that do not contain unexpanded parameter packs.
|
|
|
|
bool TraverseTypeLoc(TypeLoc TL) {
|
2012-07-25 11:56:55 +08:00
|
|
|
if ((!TL.getType().isNull() &&
|
|
|
|
TL.getType()->containsUnexpandedParameterPack()) ||
|
|
|
|
InLambda)
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
return inherited::TraverseTypeLoc(TL);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-12-16 05:57:59 +08:00
|
|
|
/// \brief Suppress traversal of non-parameter declarations, since
|
|
|
|
/// they cannot contain unexpanded parameter packs.
|
|
|
|
bool TraverseDecl(Decl *D) {
|
2012-07-25 11:56:55 +08:00
|
|
|
if ((D && isa<ParmVarDecl>(D)) || InLambda)
|
2010-12-16 05:57:59 +08:00
|
|
|
return inherited::TraverseDecl(D);
|
|
|
|
|
2012-07-25 11:56:55 +08:00
|
|
|
return true;
|
2010-12-16 05:57:59 +08:00
|
|
|
}
|
2011-01-06 01:40:24 +08:00
|
|
|
|
|
|
|
/// \brief Suppress traversal of template argument pack expansions.
|
|
|
|
bool TraverseTemplateArgument(const TemplateArgument &Arg) {
|
|
|
|
if (Arg.isPackExpansion())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return inherited::TraverseTemplateArgument(Arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Suppress traversal of template argument pack expansions.
|
|
|
|
bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
|
|
|
|
if (ArgLoc.getArgument().isPackExpansion())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return inherited::TraverseTemplateArgumentLoc(ArgLoc);
|
|
|
|
}
|
2012-07-25 11:56:55 +08:00
|
|
|
|
|
|
|
/// \brief Note whether we're traversing a lambda containing an unexpanded
|
|
|
|
/// parameter pack. In this case, the unexpanded pack can occur anywhere,
|
|
|
|
/// including all the places where we normally wouldn't look. Within a
|
|
|
|
/// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
|
|
|
|
/// outside an expression.
|
|
|
|
bool TraverseLambdaExpr(LambdaExpr *Lambda) {
|
|
|
|
// The ContainsUnexpandedParameterPack bit on a lambda is always correct,
|
|
|
|
// even if it's contained within another lambda.
|
|
|
|
if (!Lambda->containsUnexpandedParameterPack())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
bool WasInLambda = InLambda;
|
|
|
|
InLambda = true;
|
|
|
|
|
|
|
|
// If any capture names a function parameter pack, that pack is expanded
|
|
|
|
// when the lambda is expanded.
|
|
|
|
for (LambdaExpr::capture_iterator I = Lambda->capture_begin(),
|
2013-05-16 14:20:58 +08:00
|
|
|
E = Lambda->capture_end();
|
|
|
|
I != E; ++I) {
|
|
|
|
if (I->capturesVariable()) {
|
|
|
|
VarDecl *VD = I->getCapturedVar();
|
2012-07-25 11:56:55 +08:00
|
|
|
if (VD->isParameterPack())
|
|
|
|
Unexpanded.push_back(std::make_pair(VD, I->getLocation()));
|
2013-05-16 14:20:58 +08:00
|
|
|
}
|
|
|
|
}
|
2012-07-25 11:56:55 +08:00
|
|
|
|
|
|
|
inherited::TraverseLambdaExpr(Lambda);
|
|
|
|
|
|
|
|
InLambda = WasInLambda;
|
|
|
|
return true;
|
|
|
|
}
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
};
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
|
2014-08-12 07:30:23 +08:00
|
|
|
/// \brief Determine whether it's possible for an unexpanded parameter pack to
|
|
|
|
/// be valid in this location. This only happens when we're in a declaration
|
|
|
|
/// that is nested within an expression that could be expanded, such as a
|
|
|
|
/// lambda-expression within a function call.
|
|
|
|
///
|
|
|
|
/// This is conservatively correct, but may claim that some unexpanded packs are
|
|
|
|
/// permitted when they are not.
|
|
|
|
bool Sema::isUnexpandedParameterPackPermitted() {
|
|
|
|
for (auto *SI : FunctionScopes)
|
|
|
|
if (isa<sema::LambdaScopeInfo>(SI))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
/// \brief Diagnose all of the unexpanded parameter packs in the given
|
|
|
|
/// vector.
|
2012-07-25 11:56:55 +08:00
|
|
|
bool
|
2011-10-25 11:44:56 +08:00
|
|
|
Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
|
|
|
|
UnexpandedParameterPackContext UPPC,
|
2012-02-22 17:38:11 +08:00
|
|
|
ArrayRef<UnexpandedParameterPack> Unexpanded) {
|
2011-10-25 11:44:56 +08:00
|
|
|
if (Unexpanded.empty())
|
2012-07-25 11:56:55 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// If we are within a lambda expression, that lambda contains an unexpanded
|
|
|
|
// parameter pack, and we are done.
|
|
|
|
// FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it
|
|
|
|
// later.
|
|
|
|
for (unsigned N = FunctionScopes.size(); N; --N) {
|
|
|
|
if (sema::LambdaScopeInfo *LSI =
|
|
|
|
dyn_cast<sema::LambdaScopeInfo>(FunctionScopes[N-1])) {
|
|
|
|
LSI->ContainsUnexpandedParameterPack = true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2011-10-25 11:44:56 +08:00
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<SourceLocation, 4> Locations;
|
|
|
|
SmallVector<IdentifierInfo *, 4> Names;
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
|
|
|
|
|
|
|
|
for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
|
2014-05-26 14:22:03 +08:00
|
|
|
IdentifierInfo *Name = nullptr;
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
if (const TemplateTypeParmType *TTP
|
|
|
|
= Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
|
2011-05-01 09:05:51 +08:00
|
|
|
Name = TTP->getIdentifier();
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
else
|
|
|
|
Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
|
|
|
|
|
2014-11-19 15:49:47 +08:00
|
|
|
if (Name && NamesKnown.insert(Name).second)
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
Names.push_back(Name);
|
|
|
|
|
|
|
|
if (Unexpanded[I].second.isValid())
|
|
|
|
Locations.push_back(Unexpanded[I].second);
|
|
|
|
}
|
|
|
|
|
2015-03-28 01:23:14 +08:00
|
|
|
DiagnosticBuilder DB = Diag(Loc, diag::err_unexpanded_parameter_pack)
|
|
|
|
<< (int)UPPC << (int)Names.size();
|
|
|
|
for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I)
|
|
|
|
DB << Names[I];
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
|
|
|
|
for (unsigned I = 0, N = Locations.size(); I != N; ++I)
|
|
|
|
DB << SourceRange(Locations[I]);
|
2012-07-25 11:56:55 +08:00
|
|
|
return true;
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
}
|
|
|
|
|
2010-12-16 01:38:57 +08:00
|
|
|
bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
|
|
|
|
TypeSourceInfo *T,
|
|
|
|
UnexpandedParameterPackContext UPPC) {
|
|
|
|
// C++0x [temp.variadic]p5:
|
|
|
|
// An appearance of a name of a parameter pack that is not expanded is
|
|
|
|
// ill-formed.
|
|
|
|
if (!T->getType()->containsUnexpandedParameterPack())
|
|
|
|
return false;
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
|
|
|
|
T->getTypeLoc());
|
|
|
|
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
|
2012-07-25 11:56:55 +08:00
|
|
|
return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
|
2010-12-16 01:38:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
|
2010-12-16 08:46:58 +08:00
|
|
|
UnexpandedParameterPackContext UPPC) {
|
2010-12-16 01:38:57 +08:00
|
|
|
// C++0x [temp.variadic]p5:
|
|
|
|
// An appearance of a name of a parameter pack that is not expanded is
|
|
|
|
// ill-formed.
|
|
|
|
if (!E->containsUnexpandedParameterPack())
|
|
|
|
return false;
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
|
Introduce a RecursiveASTVisitor subclass that finds all unexpanded
parameter packs within a statement, type, etc. Use this visitor to
provide improved diagnostics for the presence of unexpanded parameter
packs in a full expression, base type, declaration type, etc., by
highlighting the unexpanded parameter packs and providing their names,
e.g.,
test/CXX/temp/temp.decls/temp.variadic/p5.cpp:28:85: error: declaration type
contains unexpanded parameter packs 'VeryInnerTypes',
'OuterTypes', ...
...VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types;
~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ^
llvm-svn: 121883
2010-12-16 03:43:21 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
|
|
|
|
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
|
2012-07-25 11:56:55 +08:00
|
|
|
return DiagnoseUnexpandedParameterPacks(E->getLocStart(), UPPC, Unexpanded);
|
2010-12-16 01:38:57 +08:00
|
|
|
}
|
2010-12-16 08:46:58 +08:00
|
|
|
|
|
|
|
bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
|
|
|
|
UnexpandedParameterPackContext UPPC) {
|
|
|
|
// C++0x [temp.variadic]p5:
|
|
|
|
// An appearance of a name of a parameter pack that is not expanded is
|
|
|
|
// ill-formed.
|
|
|
|
if (!SS.getScopeRep() ||
|
|
|
|
!SS.getScopeRep()->containsUnexpandedParameterPack())
|
|
|
|
return false;
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
|
2010-12-16 08:46:58 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded)
|
|
|
|
.TraverseNestedNameSpecifier(SS.getScopeRep());
|
|
|
|
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
|
2012-07-25 11:56:55 +08:00
|
|
|
return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
|
|
|
|
UPPC, Unexpanded);
|
2010-12-16 08:46:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
|
|
|
|
UnexpandedParameterPackContext UPPC) {
|
|
|
|
// C++0x [temp.variadic]p5:
|
|
|
|
// An appearance of a name of a parameter pack that is not expanded is
|
|
|
|
// ill-formed.
|
|
|
|
switch (NameInfo.getName().getNameKind()) {
|
|
|
|
case DeclarationName::Identifier:
|
|
|
|
case DeclarationName::ObjCZeroArgSelector:
|
|
|
|
case DeclarationName::ObjCOneArgSelector:
|
|
|
|
case DeclarationName::ObjCMultiArgSelector:
|
|
|
|
case DeclarationName::CXXOperatorName:
|
|
|
|
case DeclarationName::CXXLiteralOperatorName:
|
|
|
|
case DeclarationName::CXXUsingDirective:
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case DeclarationName::CXXConstructorName:
|
|
|
|
case DeclarationName::CXXDestructorName:
|
|
|
|
case DeclarationName::CXXConversionFunctionName:
|
2010-12-17 01:19:19 +08:00
|
|
|
// FIXME: We shouldn't need this null check!
|
2010-12-16 09:40:04 +08:00
|
|
|
if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
|
|
|
|
return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
|
|
|
|
|
|
|
|
if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
|
2010-12-16 08:46:58 +08:00
|
|
|
return false;
|
2010-12-16 09:40:04 +08:00
|
|
|
|
2010-12-16 08:46:58 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
|
2010-12-16 08:46:58 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded)
|
2010-12-16 09:40:04 +08:00
|
|
|
.TraverseType(NameInfo.getName().getCXXNameType());
|
2010-12-16 08:46:58 +08:00
|
|
|
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
|
2012-07-25 11:56:55 +08:00
|
|
|
return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
|
2010-12-16 08:46:58 +08:00
|
|
|
}
|
2010-12-16 16:48:57 +08:00
|
|
|
|
|
|
|
bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
|
|
|
|
TemplateName Template,
|
|
|
|
UnexpandedParameterPackContext UPPC) {
|
|
|
|
|
|
|
|
if (Template.isNull() || !Template.containsUnexpandedParameterPack())
|
|
|
|
return false;
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
|
2010-12-16 16:48:57 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded)
|
|
|
|
.TraverseTemplateName(Template);
|
|
|
|
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
|
2012-07-25 11:56:55 +08:00
|
|
|
return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
|
2010-12-16 16:48:57 +08:00
|
|
|
}
|
|
|
|
|
2011-01-04 04:35:03 +08:00
|
|
|
bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
|
|
|
|
UnexpandedParameterPackContext UPPC) {
|
|
|
|
if (Arg.getArgument().isNull() ||
|
|
|
|
!Arg.getArgument().containsUnexpandedParameterPack())
|
|
|
|
return false;
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
|
2011-01-04 04:35:03 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded)
|
|
|
|
.TraverseTemplateArgumentLoc(Arg);
|
|
|
|
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
|
2012-07-25 11:56:55 +08:00
|
|
|
return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
|
2011-01-04 04:35:03 +08:00
|
|
|
}
|
|
|
|
|
2010-12-23 05:19:48 +08:00
|
|
|
void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
|
2010-12-23 05:19:48 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded)
|
|
|
|
.TraverseTemplateArgument(Arg);
|
|
|
|
}
|
|
|
|
|
2010-12-21 06:05:00 +08:00
|
|
|
void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
|
2010-12-21 06:05:00 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded)
|
|
|
|
.TraverseTemplateArgumentLoc(Arg);
|
|
|
|
}
|
|
|
|
|
2010-12-21 08:52:54 +08:00
|
|
|
void Sema::collectUnexpandedParameterPacks(QualType T,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
|
2010-12-21 08:52:54 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
|
|
|
|
}
|
|
|
|
|
2011-01-04 06:36:02 +08:00
|
|
|
void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
|
2011-01-04 06:36:02 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
|
2016-12-19 18:09:25 +08:00
|
|
|
}
|
2011-01-04 06:36:02 +08:00
|
|
|
|
2016-12-19 18:09:25 +08:00
|
|
|
void Sema::collectUnexpandedParameterPacks(CXXScopeSpec &SS,
|
|
|
|
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
|
|
|
|
NestedNameSpecifier *Qualifier = SS.getScopeRep();
|
|
|
|
if (!Qualifier)
|
|
|
|
return;
|
|
|
|
|
|
|
|
NestedNameSpecifierLoc QualifierLoc(Qualifier, SS.location_data());
|
2011-10-25 11:44:56 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded)
|
2016-12-19 18:09:25 +08:00
|
|
|
.TraverseNestedNameSpecifierLoc(QualifierLoc);
|
2011-10-25 11:44:56 +08:00
|
|
|
}
|
|
|
|
|
2016-12-19 18:09:25 +08:00
|
|
|
void Sema::collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo,
|
|
|
|
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
|
2011-10-25 11:44:56 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded)
|
|
|
|
.TraverseDeclarationNameInfo(NameInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-20 10:24:11 +08:00
|
|
|
ParsedTemplateArgument
|
|
|
|
Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
|
|
|
|
SourceLocation EllipsisLoc) {
|
|
|
|
if (Arg.isInvalid())
|
|
|
|
return Arg;
|
|
|
|
|
|
|
|
switch (Arg.getKind()) {
|
|
|
|
case ParsedTemplateArgument::Type: {
|
|
|
|
TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
|
|
|
|
if (Result.isInvalid())
|
|
|
|
return ParsedTemplateArgument();
|
|
|
|
|
|
|
|
return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
|
|
|
|
Arg.getLocation());
|
|
|
|
}
|
|
|
|
|
2011-01-04 01:17:50 +08:00
|
|
|
case ParsedTemplateArgument::NonType: {
|
|
|
|
ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
|
|
|
|
if (Result.isInvalid())
|
|
|
|
return ParsedTemplateArgument();
|
|
|
|
|
|
|
|
return ParsedTemplateArgument(Arg.getKind(), Result.get(),
|
|
|
|
Arg.getLocation());
|
|
|
|
}
|
|
|
|
|
2010-12-20 10:24:11 +08:00
|
|
|
case ParsedTemplateArgument::Template:
|
2011-01-06 01:40:24 +08:00
|
|
|
if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
|
|
|
|
SourceRange R(Arg.getLocation());
|
|
|
|
if (Arg.getScopeSpec().isValid())
|
|
|
|
R.setBegin(Arg.getScopeSpec().getBeginLoc());
|
|
|
|
Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
|
|
|
|
<< R;
|
|
|
|
return ParsedTemplateArgument();
|
|
|
|
}
|
|
|
|
|
|
|
|
return Arg.getTemplatePackExpansion(EllipsisLoc);
|
2010-12-20 10:24:11 +08:00
|
|
|
}
|
|
|
|
llvm_unreachable("Unhandled template argument kind?");
|
|
|
|
}
|
|
|
|
|
|
|
|
TypeResult Sema::ActOnPackExpansion(ParsedType Type,
|
|
|
|
SourceLocation EllipsisLoc) {
|
|
|
|
TypeSourceInfo *TSInfo;
|
|
|
|
GetTypeFromParser(Type, &TSInfo);
|
|
|
|
if (!TSInfo)
|
|
|
|
return true;
|
|
|
|
|
2013-02-21 09:47:18 +08:00
|
|
|
TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, None);
|
2010-12-21 06:05:00 +08:00
|
|
|
if (!TSResult)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return CreateParsedType(TSResult->getType(), TSResult);
|
|
|
|
}
|
|
|
|
|
2013-02-21 06:23:23 +08:00
|
|
|
TypeSourceInfo *
|
|
|
|
Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc,
|
|
|
|
Optional<unsigned> NumExpansions) {
|
2011-01-13 01:07:58 +08:00
|
|
|
// Create the pack expansion type and source-location information.
|
|
|
|
QualType Result = CheckPackExpansion(Pattern->getType(),
|
|
|
|
Pattern->getTypeLoc().getSourceRange(),
|
2011-01-15 01:04:44 +08:00
|
|
|
EllipsisLoc, NumExpansions);
|
2011-01-13 01:07:58 +08:00
|
|
|
if (Result.isNull())
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
2013-06-08 04:31:48 +08:00
|
|
|
|
|
|
|
TypeLocBuilder TLB;
|
|
|
|
TLB.pushFullCopy(Pattern->getTypeLoc());
|
|
|
|
PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result);
|
2010-12-20 10:24:11 +08:00
|
|
|
TL.setEllipsisLoc(EllipsisLoc);
|
2013-06-08 04:31:48 +08:00
|
|
|
|
|
|
|
return TLB.getTypeSourceInfo(Context, Result);
|
2010-12-20 10:24:11 +08:00
|
|
|
}
|
2010-12-21 08:52:54 +08:00
|
|
|
|
2013-02-21 06:23:23 +08:00
|
|
|
QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
|
2011-01-15 01:04:44 +08:00
|
|
|
SourceLocation EllipsisLoc,
|
2013-02-21 06:23:23 +08:00
|
|
|
Optional<unsigned> NumExpansions) {
|
2011-01-13 01:07:58 +08:00
|
|
|
// 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)
|
|
|
|
<< PatternRange;
|
|
|
|
return QualType();
|
|
|
|
}
|
|
|
|
|
2011-01-15 01:04:44 +08:00
|
|
|
return Context.getPackExpansionType(Pattern, NumExpansions);
|
2011-01-13 01:07:58 +08:00
|
|
|
}
|
|
|
|
|
2011-01-04 01:17:50 +08:00
|
|
|
ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
|
2013-02-21 09:47:18 +08:00
|
|
|
return CheckPackExpansion(Pattern, EllipsisLoc, None);
|
2011-01-15 05:20:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
|
2013-02-21 06:23:23 +08:00
|
|
|
Optional<unsigned> NumExpansions) {
|
2011-01-04 01:17:50 +08:00
|
|
|
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.
|
2014-05-29 22:05:12 +08:00
|
|
|
return new (Context)
|
|
|
|
PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
|
2011-01-04 01:17:50 +08:00
|
|
|
}
|
2010-12-21 08:52:54 +08:00
|
|
|
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
/// \brief Retrieve the depth and index of a parameter pack.
|
|
|
|
static std::pair<unsigned, unsigned>
|
|
|
|
getDepthAndIndex(NamedDecl *ND) {
|
|
|
|
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
|
|
|
|
return std::make_pair(TTP->getDepth(), TTP->getIndex());
|
|
|
|
|
|
|
|
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND))
|
|
|
|
return std::make_pair(NTTP->getDepth(), NTTP->getIndex());
|
|
|
|
|
|
|
|
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
|
|
|
|
return std::make_pair(TTP->getDepth(), TTP->getIndex());
|
|
|
|
}
|
|
|
|
|
2013-02-21 06:23:23 +08:00
|
|
|
bool Sema::CheckParameterPacksForExpansion(
|
|
|
|
SourceLocation EllipsisLoc, SourceRange PatternRange,
|
|
|
|
ArrayRef<UnexpandedParameterPack> Unexpanded,
|
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
|
|
|
|
bool &RetainExpansion, Optional<unsigned> &NumExpansions) {
|
2010-12-21 08:52:54 +08:00
|
|
|
ShouldExpand = true;
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
RetainExpansion = false;
|
2010-12-21 08:52:54 +08:00
|
|
|
std::pair<IdentifierInfo *, SourceLocation> FirstPack;
|
|
|
|
bool HaveFirstPack = false;
|
|
|
|
|
2011-09-22 10:34:54 +08:00
|
|
|
for (ArrayRef<UnexpandedParameterPack>::iterator i = Unexpanded.begin(),
|
|
|
|
end = Unexpanded.end();
|
|
|
|
i != end; ++i) {
|
2010-12-21 08:52:54 +08:00
|
|
|
// Compute the depth and index for this parameter pack.
|
2011-01-24 01:04:59 +08:00
|
|
|
unsigned Depth = 0, Index = 0;
|
2010-12-21 08:52:54 +08:00
|
|
|
IdentifierInfo *Name;
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
bool IsFunctionParameterPack = false;
|
2010-12-21 08:52:54 +08:00
|
|
|
|
|
|
|
if (const TemplateTypeParmType *TTP
|
2011-09-22 10:34:54 +08:00
|
|
|
= i->first.dyn_cast<const TemplateTypeParmType *>()) {
|
2010-12-21 08:52:54 +08:00
|
|
|
Depth = TTP->getDepth();
|
|
|
|
Index = TTP->getIndex();
|
2011-05-01 09:05:51 +08:00
|
|
|
Name = TTP->getIdentifier();
|
2010-12-21 08:52:54 +08:00
|
|
|
} else {
|
2011-09-22 10:34:54 +08:00
|
|
|
NamedDecl *ND = i->first.get<NamedDecl *>();
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
if (isa<ParmVarDecl>(ND))
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
IsFunctionParameterPack = true;
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
else
|
2014-03-02 21:01:17 +08:00
|
|
|
std::tie(Depth, Index) = getDepthAndIndex(ND);
|
|
|
|
|
2010-12-21 08:52:54 +08:00
|
|
|
Name = ND->getIdentifier();
|
|
|
|
}
|
|
|
|
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
// Determine the size of this argument pack.
|
|
|
|
unsigned NewPackSize;
|
|
|
|
if (IsFunctionParameterPack) {
|
|
|
|
// Figure out whether we're instantiating to an argument pack or not.
|
|
|
|
typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
|
|
|
|
|
|
|
|
llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
|
|
|
|
= CurrentInstantiationScope->findInstantiationOf(
|
2011-09-22 10:34:54 +08:00
|
|
|
i->first.get<NamedDecl *>());
|
2011-02-18 03:38:27 +08:00
|
|
|
if (Instantiation->is<DeclArgumentPack *>()) {
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
// We could expand this function parameter pack.
|
|
|
|
NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
|
|
|
|
} else {
|
|
|
|
// We can't expand this function parameter pack, so we can't expand
|
|
|
|
// the pack expansion.
|
|
|
|
ShouldExpand = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// If we don't have a template argument at this depth/index, then we
|
|
|
|
// cannot expand the pack expansion. Make a note of this, but we still
|
|
|
|
// want to check any parameter packs we *do* have arguments for.
|
|
|
|
if (Depth >= TemplateArgs.getNumLevels() ||
|
|
|
|
!TemplateArgs.hasTemplateArgument(Depth, Index)) {
|
|
|
|
ShouldExpand = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Determine the size of the argument pack.
|
|
|
|
NewPackSize = TemplateArgs(Depth, Index).pack_size();
|
2010-12-21 08:52:54 +08:00
|
|
|
}
|
|
|
|
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
// C++0x [temp.arg.explicit]p9:
|
|
|
|
// Template argument deduction can extend the sequence of template
|
|
|
|
// arguments corresponding to a template parameter pack, even when the
|
|
|
|
// sequence contains explicitly specified template arguments.
|
2016-05-26 20:55:34 +08:00
|
|
|
if (!IsFunctionParameterPack && CurrentInstantiationScope) {
|
2011-01-21 07:15:49 +08:00
|
|
|
if (NamedDecl *PartialPack
|
|
|
|
= CurrentInstantiationScope->getPartiallySubstitutedPack()){
|
|
|
|
unsigned PartialDepth, PartialIndex;
|
2014-03-02 21:01:17 +08:00
|
|
|
std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
|
2011-01-21 07:15:49 +08:00
|
|
|
if (PartialDepth == Depth && PartialIndex == Index)
|
|
|
|
RetainExpansion = true;
|
|
|
|
}
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
}
|
2011-01-21 07:15:49 +08:00
|
|
|
|
2011-01-15 01:04:44 +08:00
|
|
|
if (!NumExpansions) {
|
2010-12-21 08:52:54 +08:00
|
|
|
// The is the first pack we've seen for which we have an argument.
|
|
|
|
// Record it.
|
|
|
|
NumExpansions = NewPackSize;
|
|
|
|
FirstPack.first = Name;
|
2011-09-22 10:34:54 +08:00
|
|
|
FirstPack.second = i->second;
|
2010-12-21 08:52:54 +08:00
|
|
|
HaveFirstPack = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-01-15 01:04:44 +08:00
|
|
|
if (NewPackSize != *NumExpansions) {
|
2010-12-21 08:52:54 +08:00
|
|
|
// C++0x [temp.variadic]p5:
|
|
|
|
// All of the parameter packs expanded by a pack expansion shall have
|
|
|
|
// the same number of arguments specified.
|
2011-01-15 01:04:44 +08:00
|
|
|
if (HaveFirstPack)
|
|
|
|
Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
|
|
|
|
<< FirstPack.first << Name << *NumExpansions << NewPackSize
|
2011-09-22 10:34:54 +08:00
|
|
|
<< SourceRange(FirstPack.second) << SourceRange(i->second);
|
2011-01-15 01:04:44 +08:00
|
|
|
else
|
|
|
|
Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
|
|
|
|
<< Name << *NumExpansions << NewPackSize
|
2011-09-22 10:34:54 +08:00
|
|
|
<< SourceRange(i->second);
|
2010-12-21 08:52:54 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2016-10-20 06:18:42 +08:00
|
|
|
|
2010-12-21 08:52:54 +08:00
|
|
|
return false;
|
|
|
|
}
|
2010-12-24 06:44:42 +08:00
|
|
|
|
2013-02-21 06:23:23 +08:00
|
|
|
Optional<unsigned> Sema::getNumArgumentsInExpansion(QualType T,
|
2011-01-11 11:14:20 +08:00
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs) {
|
|
|
|
QualType Pattern = cast<PackExpansionType>(T)->getPattern();
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
|
2011-01-11 11:14:20 +08:00
|
|
|
CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);
|
|
|
|
|
2013-02-21 06:23:23 +08:00
|
|
|
Optional<unsigned> Result;
|
2011-01-11 11:14:20 +08:00
|
|
|
for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
|
|
|
|
// Compute the depth and index for this parameter pack.
|
|
|
|
unsigned Depth;
|
|
|
|
unsigned Index;
|
|
|
|
|
|
|
|
if (const TemplateTypeParmType *TTP
|
|
|
|
= Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
|
|
|
|
Depth = TTP->getDepth();
|
|
|
|
Index = TTP->getIndex();
|
|
|
|
} else {
|
|
|
|
NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
|
|
|
|
if (isa<ParmVarDecl>(ND)) {
|
|
|
|
// Function parameter pack.
|
|
|
|
typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
|
|
|
|
|
|
|
|
llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
|
|
|
|
= CurrentInstantiationScope->findInstantiationOf(
|
|
|
|
Unexpanded[I].first.get<NamedDecl *>());
|
2012-07-18 09:29:05 +08:00
|
|
|
if (Instantiation->is<Decl*>())
|
|
|
|
// The pattern refers to an unexpanded pack. We're not ready to expand
|
|
|
|
// this pack yet.
|
2013-02-21 09:47:18 +08:00
|
|
|
return None;
|
2012-07-18 09:29:05 +08:00
|
|
|
|
|
|
|
unsigned Size = Instantiation->get<DeclArgumentPack *>()->size();
|
|
|
|
assert((!Result || *Result == Size) && "inconsistent pack sizes");
|
|
|
|
Result = Size;
|
2011-01-11 11:14:20 +08:00
|
|
|
continue;
|
|
|
|
}
|
2014-03-02 21:01:17 +08:00
|
|
|
|
|
|
|
std::tie(Depth, Index) = getDepthAndIndex(ND);
|
2011-01-11 11:14:20 +08:00
|
|
|
}
|
|
|
|
if (Depth >= TemplateArgs.getNumLevels() ||
|
|
|
|
!TemplateArgs.hasTemplateArgument(Depth, Index))
|
2012-07-18 09:29:05 +08:00
|
|
|
// The pattern refers to an unknown template argument. We're not ready to
|
|
|
|
// expand this pack yet.
|
2013-02-21 09:47:18 +08:00
|
|
|
return None;
|
2011-01-11 11:14:20 +08:00
|
|
|
|
|
|
|
// Determine the size of the argument pack.
|
2012-07-18 09:29:05 +08:00
|
|
|
unsigned Size = TemplateArgs(Depth, Index).pack_size();
|
|
|
|
assert((!Result || *Result == Size) && "inconsistent pack sizes");
|
|
|
|
Result = Size;
|
2011-01-11 11:14:20 +08:00
|
|
|
}
|
|
|
|
|
2012-07-18 09:29:05 +08:00
|
|
|
return Result;
|
2011-01-11 11:14:20 +08:00
|
|
|
}
|
|
|
|
|
2010-12-24 06:44:42 +08:00
|
|
|
bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
|
|
|
|
const DeclSpec &DS = D.getDeclSpec();
|
|
|
|
switch (DS.getTypeSpecType()) {
|
|
|
|
case TST_typename:
|
2011-05-19 13:37:45 +08:00
|
|
|
case TST_typeofType:
|
2011-10-07 07:00:33 +08:00
|
|
|
case TST_underlyingType:
|
|
|
|
case TST_atomic: {
|
2010-12-24 06:44:42 +08:00
|
|
|
QualType T = DS.getRepAsType().get();
|
|
|
|
if (!T.isNull() && T->containsUnexpandedParameterPack())
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case TST_typeofExpr:
|
|
|
|
case TST_decltype:
|
|
|
|
if (DS.getRepAsExpr() &&
|
|
|
|
DS.getRepAsExpr()->containsUnexpandedParameterPack())
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TST_unspecified:
|
|
|
|
case TST_void:
|
|
|
|
case TST_char:
|
|
|
|
case TST_wchar:
|
|
|
|
case TST_char16:
|
|
|
|
case TST_char32:
|
|
|
|
case TST_int:
|
2012-04-04 14:24:32 +08:00
|
|
|
case TST_int128:
|
2011-10-15 07:23:15 +08:00
|
|
|
case TST_half:
|
2010-12-24 06:44:42 +08:00
|
|
|
case TST_float:
|
|
|
|
case TST_double:
|
2016-05-09 16:52:33 +08:00
|
|
|
case TST_float128:
|
2010-12-24 06:44:42 +08:00
|
|
|
case TST_bool:
|
|
|
|
case TST_decimal32:
|
|
|
|
case TST_decimal64:
|
|
|
|
case TST_decimal128:
|
|
|
|
case TST_enum:
|
|
|
|
case TST_union:
|
|
|
|
case TST_struct:
|
2012-09-01 02:45:21 +08:00
|
|
|
case TST_interface:
|
2010-12-24 06:44:42 +08:00
|
|
|
case TST_class:
|
|
|
|
case TST_auto:
|
2015-11-11 10:02:15 +08:00
|
|
|
case TST_auto_type:
|
2013-04-27 00:15:35 +08:00
|
|
|
case TST_decltype_auto:
|
2016-04-08 21:40:33 +08:00
|
|
|
#define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t:
|
2016-04-13 16:33:41 +08:00
|
|
|
#include "clang/Basic/OpenCLImageTypes.def"
|
2011-04-10 06:50:59 +08:00
|
|
|
case TST_unknown_anytype:
|
2010-12-24 06:44:42 +08:00
|
|
|
case TST_error:
|
|
|
|
break;
|
|
|
|
}
|
2014-08-30 05:08:16 +08:00
|
|
|
|
2010-12-24 06:44:42 +08:00
|
|
|
for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
|
|
|
|
const DeclaratorChunk &Chunk = D.getTypeObject(I);
|
|
|
|
switch (Chunk.Kind) {
|
|
|
|
case DeclaratorChunk::Pointer:
|
|
|
|
case DeclaratorChunk::Reference:
|
|
|
|
case DeclaratorChunk::Paren:
|
2016-01-09 20:53:17 +08:00
|
|
|
case DeclaratorChunk::Pipe:
|
2014-08-30 05:08:16 +08:00
|
|
|
case DeclaratorChunk::BlockPointer:
|
2010-12-24 06:44:42 +08:00
|
|
|
// These declarator chunks cannot contain any parameter packs.
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DeclaratorChunk::Array:
|
2014-08-30 05:08:16 +08:00
|
|
|
if (Chunk.Arr.NumElts &&
|
|
|
|
Chunk.Arr.NumElts->containsUnexpandedParameterPack())
|
|
|
|
return true;
|
|
|
|
break;
|
2010-12-24 06:44:42 +08:00
|
|
|
case DeclaratorChunk::Function:
|
2014-08-30 05:08:16 +08:00
|
|
|
for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) {
|
|
|
|
ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param);
|
|
|
|
QualType ParamTy = Param->getType();
|
|
|
|
assert(!ParamTy.isNull() && "Couldn't parse type?");
|
|
|
|
if (ParamTy->containsUnexpandedParameterPack()) return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) {
|
Store decls in prototypes on the declarator instead of in the AST
This saves two pointers from FunctionDecl that were being used for some
rare and questionable C-only functionality. The DeclsInPrototypeScope
ArrayRef was added in r151712 in order to parse this kind of C code:
enum e {x, y};
int f(enum {y, x} n) {
return x; // should return 1, not 0
}
The challenge is that we parse 'int f(enum {y, x} n)' it its own
function prototype scope that gets popped before we build the
FunctionDecl for 'f'. The original change was doing two questionable
things:
1. Saving all tag decls introduced in prototype scope on a TU-global
Sema variable. This is problematic when you have cases like this, where
'x' and 'y' shouldn't be visible in 'f':
void f(void (*fp)(enum { x, y } e)) { /* no x */ }
This patch fixes that, so now 'f' can't see 'x', which is consistent
with GCC.
2. Storing the decls in FunctionDecl in ActOnFunctionDeclarator so that
they could be used in ActOnStartOfFunctionDef. This is just an
inefficient way to move information around. The AST lives forever, but
the list of non-parameter decls in prototype scope is short lived.
Moving these things to the Declarator solves both of these issues.
Reviewers: rsmith
Subscribers: jmolloy, cfe-commits
Differential Revision: https://reviews.llvm.org/D27279
llvm-svn: 289225
2016-12-10 01:14:05 +08:00
|
|
|
for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) {
|
2014-08-30 05:08:16 +08:00
|
|
|
if (Chunk.Fun.Exceptions[i]
|
|
|
|
.Ty.get()
|
|
|
|
->containsUnexpandedParameterPack())
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else if (Chunk.Fun.getExceptionSpecType() == EST_ComputedNoexcept &&
|
|
|
|
Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack())
|
|
|
|
return true;
|
|
|
|
|
2014-12-30 10:06:40 +08:00
|
|
|
if (Chunk.Fun.hasTrailingReturnType()) {
|
|
|
|
QualType T = Chunk.Fun.getTrailingReturnType().get();
|
|
|
|
if (!T.isNull() && T->containsUnexpandedParameterPack())
|
|
|
|
return true;
|
|
|
|
}
|
2014-08-30 05:08:16 +08:00
|
|
|
break;
|
|
|
|
|
2010-12-24 06:44:42 +08:00
|
|
|
case DeclaratorChunk::MemberPointer:
|
|
|
|
if (Chunk.Mem.Scope().getScopeRep() &&
|
|
|
|
Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2011-01-05 01:33:58 +08:00
|
|
|
|
2012-01-14 07:10:36 +08:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
// Callback to only accept typo corrections that refer to parameter packs.
|
|
|
|
class ParameterPackValidatorCCC : public CorrectionCandidateCallback {
|
|
|
|
public:
|
2014-03-12 12:55:44 +08:00
|
|
|
bool ValidateCandidate(const TypoCorrection &candidate) override {
|
2012-01-14 07:10:36 +08:00
|
|
|
NamedDecl *ND = candidate.getCorrectionDecl();
|
|
|
|
return ND && ND->isParameterPack();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
2012-01-14 07:10:36 +08:00
|
|
|
|
2011-01-05 01:33:58 +08:00
|
|
|
/// \brief Called when an expression computing the size of a parameter pack
|
|
|
|
/// is parsed.
|
|
|
|
///
|
|
|
|
/// \code
|
|
|
|
/// template<typename ...Types> struct count {
|
|
|
|
/// static const unsigned value = sizeof...(Types);
|
|
|
|
/// };
|
|
|
|
/// \endcode
|
|
|
|
///
|
|
|
|
//
|
|
|
|
/// \param OpLoc The location of the "sizeof" keyword.
|
|
|
|
/// \param Name The name of the parameter pack whose size will be determined.
|
|
|
|
/// \param NameLoc The source location of the name of the parameter pack.
|
|
|
|
/// \param RParenLoc The location of the closing parentheses.
|
|
|
|
ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
|
|
|
|
SourceLocation OpLoc,
|
|
|
|
IdentifierInfo &Name,
|
|
|
|
SourceLocation NameLoc,
|
|
|
|
SourceLocation RParenLoc) {
|
|
|
|
// C++0x [expr.sizeof]p5:
|
|
|
|
// The identifier in a sizeof... expression shall name a parameter pack.
|
|
|
|
LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
|
|
|
|
LookupName(R, S);
|
2014-05-26 14:22:03 +08:00
|
|
|
|
|
|
|
NamedDecl *ParameterPack = nullptr;
|
2011-01-05 01:33:58 +08:00
|
|
|
switch (R.getResultKind()) {
|
|
|
|
case LookupResult::Found:
|
|
|
|
ParameterPack = R.getFoundDecl();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LookupResult::NotFound:
|
|
|
|
case LookupResult::NotFoundInCurrentInstantiation:
|
2014-10-28 02:07:29 +08:00
|
|
|
if (TypoCorrection Corrected =
|
|
|
|
CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr,
|
|
|
|
llvm::make_unique<ParameterPackValidatorCCC>(),
|
|
|
|
CTK_ErrorRecovery)) {
|
2013-08-17 08:46:16 +08:00
|
|
|
diagnoseTypo(Corrected,
|
|
|
|
PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name,
|
|
|
|
PDiag(diag::note_parameter_pack_here));
|
2012-01-14 07:10:36 +08:00
|
|
|
ParameterPack = Corrected.getCorrectionDecl();
|
2011-01-05 01:33:58 +08:00
|
|
|
}
|
2013-08-17 08:46:16 +08:00
|
|
|
|
2011-01-05 01:33:58 +08:00
|
|
|
case LookupResult::FoundOverloaded:
|
|
|
|
case LookupResult::FoundUnresolvedValue:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LookupResult::Ambiguous:
|
|
|
|
DiagnoseAmbiguousLookup(R);
|
|
|
|
return ExprError();
|
|
|
|
}
|
|
|
|
|
2011-01-06 05:11:38 +08:00
|
|
|
if (!ParameterPack || !ParameterPack->isParameterPack()) {
|
2011-01-05 01:33:58 +08:00
|
|
|
Diag(NameLoc, diag::err_sizeof_pack_no_pack_name)
|
|
|
|
<< &Name;
|
|
|
|
return ExprError();
|
|
|
|
}
|
|
|
|
|
2013-02-02 08:25:55 +08:00
|
|
|
MarkAnyDeclReferenced(OpLoc, ParameterPack, true);
|
2012-03-02 05:32:56 +08:00
|
|
|
|
2015-09-24 05:41:42 +08:00
|
|
|
return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc,
|
|
|
|
RParenLoc);
|
2011-01-05 01:33:58 +08:00
|
|
|
}
|
2013-06-20 12:11:21 +08:00
|
|
|
|
|
|
|
TemplateArgumentLoc
|
|
|
|
Sema::getTemplateArgumentPackExpansionPattern(
|
|
|
|
TemplateArgumentLoc OrigLoc,
|
|
|
|
SourceLocation &Ellipsis, Optional<unsigned> &NumExpansions) const {
|
|
|
|
const TemplateArgument &Argument = OrigLoc.getArgument();
|
|
|
|
assert(Argument.isPackExpansion());
|
|
|
|
switch (Argument.getKind()) {
|
|
|
|
case TemplateArgument::Type: {
|
|
|
|
// FIXME: We shouldn't ever have to worry about missing
|
|
|
|
// type-source info!
|
|
|
|
TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo();
|
|
|
|
if (!ExpansionTSInfo)
|
|
|
|
ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(),
|
|
|
|
Ellipsis);
|
|
|
|
PackExpansionTypeLoc Expansion =
|
|
|
|
ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>();
|
|
|
|
Ellipsis = Expansion.getEllipsisLoc();
|
|
|
|
|
|
|
|
TypeLoc Pattern = Expansion.getPatternLoc();
|
|
|
|
NumExpansions = Expansion.getTypePtr()->getNumExpansions();
|
|
|
|
|
|
|
|
// We need to copy the TypeLoc because TemplateArgumentLocs store a
|
|
|
|
// TypeSourceInfo.
|
|
|
|
// FIXME: Find some way to avoid the copy?
|
|
|
|
TypeLocBuilder TLB;
|
|
|
|
TLB.pushFullCopy(Pattern);
|
|
|
|
TypeSourceInfo *PatternTSInfo =
|
|
|
|
TLB.getTypeSourceInfo(Context, Pattern.getType());
|
|
|
|
return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
|
|
|
|
PatternTSInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
case TemplateArgument::Expression: {
|
|
|
|
PackExpansionExpr *Expansion
|
|
|
|
= cast<PackExpansionExpr>(Argument.getAsExpr());
|
|
|
|
Expr *Pattern = Expansion->getPattern();
|
|
|
|
Ellipsis = Expansion->getEllipsisLoc();
|
|
|
|
NumExpansions = Expansion->getNumExpansions();
|
|
|
|
return TemplateArgumentLoc(Pattern, Pattern);
|
|
|
|
}
|
|
|
|
|
|
|
|
case TemplateArgument::TemplateExpansion:
|
|
|
|
Ellipsis = OrigLoc.getTemplateEllipsisLoc();
|
|
|
|
NumExpansions = Argument.getNumTemplateExpansions();
|
|
|
|
return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
|
|
|
|
OrigLoc.getTemplateQualifierLoc(),
|
|
|
|
OrigLoc.getTemplateNameLoc());
|
|
|
|
|
|
|
|
case TemplateArgument::Declaration:
|
|
|
|
case TemplateArgument::NullPtr:
|
|
|
|
case TemplateArgument::Template:
|
|
|
|
case TemplateArgument::Integral:
|
|
|
|
case TemplateArgument::Pack:
|
|
|
|
case TemplateArgument::Null:
|
|
|
|
return TemplateArgumentLoc();
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Invalid TemplateArgument Kind!");
|
|
|
|
}
|
2014-11-08 13:07:16 +08:00
|
|
|
|
2016-10-20 06:18:42 +08:00
|
|
|
Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
|
|
|
|
assert(Arg.containsUnexpandedParameterPack());
|
|
|
|
|
|
|
|
// If this is a substituted pack, grab that pack. If not, we don't know
|
|
|
|
// the size yet.
|
|
|
|
// FIXME: We could find a size in more cases by looking for a substituted
|
|
|
|
// pack anywhere within this argument, but that's not necessary in the common
|
|
|
|
// case for 'sizeof...(A)' handling.
|
|
|
|
TemplateArgument Pack;
|
|
|
|
switch (Arg.getKind()) {
|
|
|
|
case TemplateArgument::Type:
|
|
|
|
if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>())
|
|
|
|
Pack = Subst->getArgumentPack();
|
|
|
|
else
|
|
|
|
return None;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TemplateArgument::Expression:
|
|
|
|
if (auto *Subst =
|
|
|
|
dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr()))
|
|
|
|
Pack = Subst->getArgumentPack();
|
|
|
|
else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr())) {
|
|
|
|
for (ParmVarDecl *PD : *Subst)
|
|
|
|
if (PD->isParameterPack())
|
|
|
|
return None;
|
|
|
|
return Subst->getNumExpansions();
|
|
|
|
} else
|
|
|
|
return None;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TemplateArgument::Template:
|
|
|
|
if (SubstTemplateTemplateParmPackStorage *Subst =
|
|
|
|
Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack())
|
|
|
|
Pack = Subst->getArgumentPack();
|
|
|
|
else
|
|
|
|
return None;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TemplateArgument::Declaration:
|
|
|
|
case TemplateArgument::NullPtr:
|
|
|
|
case TemplateArgument::TemplateExpansion:
|
|
|
|
case TemplateArgument::Integral:
|
|
|
|
case TemplateArgument::Pack:
|
|
|
|
case TemplateArgument::Null:
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that no argument in the pack is itself a pack expansion.
|
|
|
|
for (TemplateArgument Elem : Pack.pack_elements()) {
|
|
|
|
// There's no point recursing in this case; we would have already
|
|
|
|
// expanded this pack expansion into the enclosing pack if we could.
|
|
|
|
if (Elem.isPackExpansion())
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
return Pack.pack_size();
|
|
|
|
}
|
|
|
|
|
2014-11-08 13:07:16 +08:00
|
|
|
static void CheckFoldOperand(Sema &S, Expr *E) {
|
|
|
|
if (!E)
|
|
|
|
return;
|
|
|
|
|
|
|
|
E = E->IgnoreImpCasts();
|
2016-10-20 08:55:15 +08:00
|
|
|
auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
|
|
|
|
if ((OCE && OCE->isInfixBinaryOp()) || isa<BinaryOperator>(E) ||
|
|
|
|
isa<AbstractConditionalOperator>(E)) {
|
2014-11-08 13:07:16 +08:00
|
|
|
S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand)
|
|
|
|
<< E->getSourceRange()
|
|
|
|
<< FixItHint::CreateInsertion(E->getLocStart(), "(")
|
|
|
|
<< FixItHint::CreateInsertion(E->getLocEnd(), ")");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
|
|
|
|
tok::TokenKind Operator,
|
|
|
|
SourceLocation EllipsisLoc, Expr *RHS,
|
|
|
|
SourceLocation RParenLoc) {
|
|
|
|
// LHS and RHS must be cast-expressions. We allow an arbitrary expression
|
|
|
|
// in the parser and reduce down to just cast-expressions here.
|
|
|
|
CheckFoldOperand(*this, LHS);
|
|
|
|
CheckFoldOperand(*this, RHS);
|
|
|
|
|
|
|
|
// [expr.prim.fold]p3:
|
|
|
|
// In a binary fold, op1 and op2 shall be the same fold-operator, and
|
|
|
|
// either e1 shall contain an unexpanded parameter pack or e2 shall contain
|
|
|
|
// an unexpanded parameter pack, but not both.
|
|
|
|
if (LHS && RHS &&
|
|
|
|
LHS->containsUnexpandedParameterPack() ==
|
|
|
|
RHS->containsUnexpandedParameterPack()) {
|
|
|
|
return Diag(EllipsisLoc,
|
|
|
|
LHS->containsUnexpandedParameterPack()
|
|
|
|
? diag::err_fold_expression_packs_both_sides
|
|
|
|
: diag::err_pack_expansion_without_parameter_packs)
|
|
|
|
<< LHS->getSourceRange() << RHS->getSourceRange();
|
|
|
|
}
|
|
|
|
|
|
|
|
// [expr.prim.fold]p2:
|
|
|
|
// In a unary fold, the cast-expression shall contain an unexpanded
|
|
|
|
// parameter pack.
|
|
|
|
if (!LHS || !RHS) {
|
|
|
|
Expr *Pack = LHS ? LHS : RHS;
|
|
|
|
assert(Pack && "fold expression with neither LHS nor RHS");
|
|
|
|
if (!Pack->containsUnexpandedParameterPack())
|
|
|
|
return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
|
|
|
|
<< Pack->getSourceRange();
|
|
|
|
}
|
|
|
|
|
|
|
|
BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator);
|
|
|
|
return BuildCXXFoldExpr(LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc);
|
|
|
|
}
|
|
|
|
|
|
|
|
ExprResult Sema::BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
|
|
|
|
BinaryOperatorKind Operator,
|
|
|
|
SourceLocation EllipsisLoc, Expr *RHS,
|
|
|
|
SourceLocation RParenLoc) {
|
|
|
|
return new (Context) CXXFoldExpr(Context.DependentTy, LParenLoc, LHS,
|
|
|
|
Operator, EllipsisLoc, RHS, RParenLoc);
|
|
|
|
}
|
|
|
|
|
|
|
|
ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
|
|
|
|
BinaryOperatorKind Operator) {
|
|
|
|
// [temp.variadic]p9:
|
|
|
|
// If N is zero for a unary fold-expression, the value of the expression is
|
|
|
|
// && -> true
|
|
|
|
// || -> false
|
|
|
|
// , -> void()
|
|
|
|
// if the operator is not listed [above], the instantiation is ill-formed.
|
|
|
|
//
|
|
|
|
// Note that we need to use something like int() here, not merely 0, to
|
|
|
|
// prevent the result from being a null pointer constant.
|
|
|
|
QualType ScalarType;
|
|
|
|
switch (Operator) {
|
|
|
|
case BO_LOr:
|
|
|
|
return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_false);
|
|
|
|
case BO_LAnd:
|
|
|
|
return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_true);
|
|
|
|
case BO_Comma:
|
|
|
|
ScalarType = Context.VoidTy;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return Diag(EllipsisLoc, diag::err_fold_expression_empty)
|
|
|
|
<< BinaryOperator::getOpcodeStr(Operator);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new (Context) CXXScalarValueInitExpr(
|
|
|
|
ScalarType, Context.getTrivialTypeSourceInfo(ScalarType, EllipsisLoc),
|
|
|
|
EllipsisLoc);
|
|
|
|
}
|