summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateVariadic.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-12-20 02:24:11 +0000
committerDouglas Gregor <dgregor@apple.com>2010-12-20 02:24:11 +0000
commitd2fa766ad03ebb5e5170c7593ade7c322fe174e8 (patch)
tree8b9fb3ac9db5e439bc1d64886e34277b46140de2 /clang/lib/Sema/SemaTemplateVariadic.cpp
parent17a06b7efab559f0ae8df678524d6e3c3dfd3d52 (diff)
downloadbcm5719-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.cpp60
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);
+}
OpenPOWER on IntegriCloud