diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-12-20 02:24:11 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-12-20 02:24:11 +0000 |
commit | d2fa766ad03ebb5e5170c7593ade7c322fe174e8 (patch) | |
tree | 8b9fb3ac9db5e439bc1d64886e34277b46140de2 /clang/lib/Sema/SemaTemplateVariadic.cpp | |
parent | 17a06b7efab559f0ae8df678524d6e3c3dfd3d52 (diff) | |
download | bcm5719-llvm-d2fa766ad03ebb5e5170c7593ade7c322fe174e8.tar.gz bcm5719-llvm-d2fa766ad03ebb5e5170c7593ade7c322fe174e8.zip |
Introduce a new type, PackExpansionType, to capture types that are
pack expansions, e.g. given
template<typename... Types> struct tuple;
template<typename... Types>
struct tuple_of_refs {
typedef tuple<Types&...> types;
};
the type of the "types" typedef is a PackExpansionType whose pattern
is Types&.
This commit introduces support for creating pack expansions for
template type arguments, as above, but not for any other kind of pack
expansion, nor for any form of instantiation.
llvm-svn: 122223
Diffstat (limited to 'clang/lib/Sema/SemaTemplateVariadic.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateVariadic.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index f190b3c7743..321f38397d5 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -10,6 +10,7 @@ //===----------------------------------------------------------------------===/ #include "clang/Sema/Sema.h" +#include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/SemaInternal.h" #include "clang/AST/Expr.h" #include "clang/AST/RecursiveASTVisitor.h" @@ -254,3 +255,62 @@ bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, return true; } +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()); + } + + case ParsedTemplateArgument::NonType: + Diag(EllipsisLoc, diag::err_pack_expansion_unsupported) + << 0; + return ParsedTemplateArgument(); + + case ParsedTemplateArgument::Template: + Diag(EllipsisLoc, diag::err_pack_expansion_unsupported) + << 1; + return ParsedTemplateArgument(); + } + llvm_unreachable("Unhandled template argument kind?"); + return ParsedTemplateArgument(); +} + +TypeResult Sema::ActOnPackExpansion(ParsedType Type, + SourceLocation EllipsisLoc) { + TypeSourceInfo *TSInfo; + GetTypeFromParser(Type, &TSInfo); + if (!TSInfo) + return true; + + // 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 (!TSInfo->getType()->containsUnexpandedParameterPack()) { + Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) + << TSInfo->getTypeLoc().getSourceRange(); + return true; + } + + // Create the pack expansion type and source-location information. + QualType Result = Context.getPackExpansionType(TSInfo->getType()); + TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result); + PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc()); + TL.setEllipsisLoc(EllipsisLoc); + + // Copy over the source-location information from the type. + memcpy(TL.getNextTypeLoc().getOpaqueData(), + TSInfo->getTypeLoc().getOpaqueData(), + TSInfo->getTypeLoc().getFullDataSize()); + return CreateParsedType(Result, TSResult); +} |