From: Douglas Gregor Date: Fri, 7 Jan 2011 19:35:17 +0000 (+0000) Subject: When instantiating the arguments to an initializer, use the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=91fc73e7ffb1fa1da0276518359d3bd4ed11c843;p=clang When instantiating the arguments to an initializer, use the TreeTransform version of TransformExprs() rather than explicit loop, so that we expand pack expansions properly. Test cast coming soon... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123014 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 096a8e2564..bcb7666f43 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -3897,6 +3897,25 @@ public: llvm::SmallVectorImpl *OutParams = 0); ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs); + + /// \brief Substitute the given template arguments into a list of + /// expressions, expanding pack expansions if required. + /// + /// \param Exprs The list of expressions to substitute into. + /// + /// \param NumExprs The number of expressions in \p Exprs. + /// + /// \param IsCall Whether this is some form of call, in which case + /// default arguments will be dropped. + /// + /// \param TemplateArgs The set of template arguments to substitute. + /// + /// \param Outputs Will receive all of the substituted arguments. + /// + /// \returns true if an error occurred, false otherwise. + bool SubstExprs(Expr **Exprs, unsigned NumExprs, bool IsCall, + const MultiLevelTemplateArgumentList &TemplateArgs, + llvm::SmallVectorImpl &Outputs); StmtResult SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs); diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 71ccb06212..394f50ef69 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1868,6 +1868,18 @@ Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) { return Instantiator.TransformExpr(E); } +bool Sema::SubstExprs(Expr **Exprs, unsigned NumExprs, bool IsCall, + const MultiLevelTemplateArgumentList &TemplateArgs, + llvm::SmallVectorImpl &Outputs) { + if (NumExprs == 0) + return false; + + TemplateInstantiator Instantiator(*this, TemplateArgs, + SourceLocation(), + DeclarationName()); + return Instantiator.TransformExprs(Exprs, NumExprs, IsCall, Outputs); +} + /// \brief Do template substitution on a nested-name-specifier. NestedNameSpecifier * Sema::SubstNestedNameSpecifier(NestedNameSpecifier *NNS, diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 2ef688b0eb..649fbf6625 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -166,29 +166,6 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) { return Typedef; } -/// \brief Instantiate the arguments provided as part of initialization. -/// -/// \returns true if an error occurred, false otherwise. -static bool InstantiateInitializationArguments(Sema &SemaRef, - Expr **Args, unsigned NumArgs, - const MultiLevelTemplateArgumentList &TemplateArgs, - ASTOwningVector &InitArgs) { - for (unsigned I = 0; I != NumArgs; ++I) { - // When we hit the first defaulted argument, break out of the loop: - // we don't pass those default arguments on. - if (Args[I]->isDefaultArgument()) - break; - - ExprResult Arg = SemaRef.SubstExpr(Args[I], TemplateArgs); - if (Arg.isInvalid()) - return true; - - InitArgs.push_back(Arg.release()); - } - - return false; -} - /// \brief Instantiate an initializer, breaking it into separate /// initialization arguments. /// @@ -226,17 +203,14 @@ static bool InstantiateInitializer(Sema &S, Expr *Init, if (ParenListExpr *ParenList = dyn_cast(Init)) { LParenLoc = ParenList->getLParenLoc(); RParenLoc = ParenList->getRParenLoc(); - return InstantiateInitializationArguments(S, ParenList->getExprs(), - ParenList->getNumExprs(), - TemplateArgs, NewArgs); + return S.SubstExprs(ParenList->getExprs(), ParenList->getNumExprs(), + true, TemplateArgs, NewArgs); } if (CXXConstructExpr *Construct = dyn_cast(Init)) { if (!isa(Construct)) { - if (InstantiateInitializationArguments(S, - Construct->getArgs(), - Construct->getNumArgs(), - TemplateArgs, NewArgs)) + if (S.SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true, + TemplateArgs, NewArgs)) return true; // FIXME: Fake locations!