diff options
| author | Douglas Gregor <dgregor@apple.com> | 2011-01-04 00:32:56 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2011-01-04 00:32:56 +0000 |
| commit | 44e7df67d963de48125873d82eed90821c8a370d (patch) | |
| tree | 17d6e34b294f0c7d7fa2c2bca2e0ff4a443e7c11 /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | |
| parent | bd9dfb2e297bb29f33d631566bcf0b6db6e3f61e (diff) | |
| download | bcm5719-llvm-44e7df67d963de48125873d82eed90821c8a370d.tar.gz bcm5719-llvm-44e7df67d963de48125873d82eed90821c8a370d.zip | |
Implement pack expansion of base initializers, so that we can
initialize those lovely mixins that come from pack expansions of base
specifiers.
llvm-svn: 122793
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 9db3a8cacfe..60a942ac2fa 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2362,6 +2362,69 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, SourceLocation LParenLoc, RParenLoc; ASTOwningVector<Expr*> NewArgs(*this); + SourceLocation EllipsisLoc; + + if (Init->isPackExpansion()) { + // This is a pack expansion. We should expand it now. + TypeLoc BaseTL = Init->getBaseClassInfo()->getTypeLoc(); + llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; + collectUnexpandedParameterPacks(BaseTL, Unexpanded); + bool ShouldExpand = false; + unsigned NumExpansions = 0; + if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(), + BaseTL.getSourceRange(), + Unexpanded.data(), + Unexpanded.size(), + TemplateArgs, ShouldExpand, + NumExpansions)) { + AnyErrors = true; + New->setInvalidDecl(); + continue; + } + assert(ShouldExpand && "Partial instantiation of base initializer?"); + + // Loop over all of the arguments in the argument pack(s), + for (unsigned I = 0; I != NumExpansions; ++I) { + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I); + + // Instantiate the initializer. + if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs, + LParenLoc, NewArgs, RParenLoc)) { + AnyErrors = true; + break; + } + + // Instantiate the base type. + TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(), + TemplateArgs, + Init->getSourceLocation(), + New->getDeclName()); + if (!BaseTInfo) { + AnyErrors = true; + break; + } + + // Build the initializer. + MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(), + BaseTInfo, + (Expr **)NewArgs.data(), + NewArgs.size(), + Init->getLParenLoc(), + Init->getRParenLoc(), + New->getParent(), + SourceLocation()); + if (NewInit.isInvalid()) { + AnyErrors = true; + break; + } + + NewInits.push_back(NewInit.get()); + NewArgs.clear(); + } + + continue; + } + // Instantiate the initializer. if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs, LParenLoc, NewArgs, RParenLoc)) { @@ -2386,7 +2449,8 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, NewArgs.size(), Init->getLParenLoc(), Init->getRParenLoc(), - New->getParent()); + New->getParent(), + EllipsisLoc); } else if (Init->isMemberInitializer()) { FieldDecl *Member = cast<FieldDecl>(FindInstantiatedDecl( Init->getMemberLocation(), |

