diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-04 17:33:58 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-04 17:33:58 +0000 |
commit | ee8aff06f6a96214731de17b2cb6df407c6c1820 (patch) | |
tree | b3ceca1e1f5b668c492de0c8ddec937e78b228fa /lib/Sema/SemaTemplateVariadic.cpp | |
parent | bb03f5dbc23fb9aa1dfdf6a1dfdb192aa56b6b1c (diff) |
Implement the sizeof...(pack) expression to compute the length of a
parameter pack.
Note that we're missing proper libclang support for the new
SizeOfPackExpr expression node.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122813 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateVariadic.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 92df1fd863..4e01ec2407 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -10,6 +10,7 @@ //===----------------------------------------------------------------------===/ #include "clang/Sema/Sema.h" +#include "clang/Sema/Lookup.h" #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/Template.h" @@ -533,3 +534,71 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { return false; } + +/// \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); + + NamedDecl *ParameterPack = 0; + switch (R.getResultKind()) { + case LookupResult::Found: + ParameterPack = R.getFoundDecl(); + break; + + case LookupResult::NotFound: + case LookupResult::NotFoundInCurrentInstantiation: + if (DeclarationName CorrectedName = CorrectTypo(R, S, 0, 0, false, + CTC_NoKeywords)) { + // FIXME: Variadic templates function parameter packs. + if (NamedDecl *CorrectedResult = R.getAsSingle<NamedDecl>()) + if (CorrectedResult->isTemplateParameterPack()) { + ParameterPack = CorrectedResult; + Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest) + << &Name << CorrectedName + << FixItHint::CreateReplacement(NameLoc, + CorrectedName.getAsString()); + Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here) + << CorrectedName; + } + } + + case LookupResult::FoundOverloaded: + case LookupResult::FoundUnresolvedValue: + break; + + case LookupResult::Ambiguous: + DiagnoseAmbiguousLookup(R); + return ExprError(); + } + + // FIXME: Variadic templates function parameter packs. + if (!ParameterPack || !ParameterPack->isTemplateParameterPack()) { + Diag(NameLoc, diag::err_sizeof_pack_no_pack_name) + << &Name; + return ExprError(); + } + + return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc, + ParameterPack, NameLoc, RParenLoc); +} |