diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-08-11 05:31:07 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-08-11 05:31:07 +0000 |
commit | b98b1991c7ad1eaedb863bdbdd784ec164277675 (patch) | |
tree | bda94228daf1885ce26082a2be141dfdf9e417de /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | e955e7221a9cf335a089f548c01e854dca95ca99 (diff) |
Refactor the template-instantiation logic for expressions into a
generic tree transformation (also used for recanonicalization) and a
small amount of template-instantiation-specific logic.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78645 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 120 |
1 files changed, 112 insertions, 8 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 8f877a8b56..4d164ea12e 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -316,24 +316,30 @@ namespace { /// \brief Returns the name of the entity being instantiated, if any. DeclarationName getBaseEntity() { return Entity; } - /// \brief Transforms an expression by instantiating it with the given - /// template arguments. - Sema::OwningExprResult TransformExpr(Expr *E); - /// \brief Transform the given declaration by instantiating a reference to /// this declaration. Decl *TransformDecl(Decl *D); + Sema::OwningStmtResult TransformStmt(Stmt *S) { + return SemaRef.InstantiateStmt(S, TemplateArgs); + } + + Sema::OwningStmtResult TransformCompoundStmt(CompoundStmt *S, + bool IsStmtExpr) { + return SemaRef.InstantiateCompoundStmt(S, TemplateArgs, IsStmtExpr); + } + + Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E); + + Sema::OwningExprResult + TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E); + /// \brief Transforms a template type parameter type by performing /// substitution of the corresponding template type argument. QualType TransformTemplateTypeParmType(const TemplateTypeParmType *T); }; } -Sema::OwningExprResult TemplateInstantiator::TransformExpr(Expr *E) { - return getSema().InstantiateExpr(E, TemplateArgs); -} - Decl *TemplateInstantiator::TransformDecl(Decl *D) { if (TemplateTemplateParmDecl *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(D)) { @@ -351,6 +357,93 @@ Decl *TemplateInstantiator::TransformDecl(Decl *D) { return SemaRef.InstantiateCurrentDeclRef(cast_or_null<NamedDecl>(D)); } +Sema::OwningExprResult +TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) { + // FIXME: Clean this up a bit + NamedDecl *D = E->getDecl(); + if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) { + assert(NTTP->getDepth() == 0 && "No nested templates yet"); + + // If the corresponding template argument is NULL or non-existent, it's + // because we are performing instantiation from explicitly-specified + // template arguments in a function template, but there were some + // arguments left unspecified. + if (NTTP->getPosition() >= TemplateArgs.size() || + TemplateArgs[NTTP->getPosition()].isNull()) + return SemaRef.Owned(E); // FIXME: Clone the expression! + + const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()]; + + // The template argument itself might be an expression, in which + // case we just return that expression. + if (Arg.getKind() == TemplateArgument::Expression) + // FIXME: Clone the expression! + return SemaRef.Owned(Arg.getAsExpr()); + + if (Arg.getKind() == TemplateArgument::Declaration) { + ValueDecl *VD = cast<ValueDecl>(Arg.getAsDecl()); + + // FIXME: Can VD ever have a dependent type? + return SemaRef.BuildDeclRefExpr(VD, VD->getType(), E->getLocation(), + false, false); + } + + assert(Arg.getKind() == TemplateArgument::Integral); + QualType T = Arg.getIntegralType(); + if (T->isCharType() || T->isWideCharType()) + return SemaRef.Owned(new (SemaRef.Context) CharacterLiteral( + Arg.getAsIntegral()->getZExtValue(), + T->isWideCharType(), + T, + E->getSourceRange().getBegin())); + if (T->isBooleanType()) + return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr( + Arg.getAsIntegral()->getBoolValue(), + T, + E->getSourceRange().getBegin())); + + assert(Arg.getAsIntegral()->getBitWidth() == SemaRef.Context.getIntWidth(T)); + return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral( + *Arg.getAsIntegral(), + T, + E->getSourceRange().getBegin())); + } + + if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D)) { + // FIXME: instantiate each decl in the overload set + return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(Ovl, + SemaRef.Context.OverloadTy, + E->getLocation(), + false, false)); + } + + NamedDecl *InstD = SemaRef.InstantiateCurrentDeclRef(D); + if (!InstD) + return SemaRef.ExprError(); + + // FIXME: nested-name-specifier for QualifiedDeclRefExpr + return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD, + /*FIXME:*/false, + /*FIXME:*/0, + /*FIXME:*/false); +} + +Sema::OwningExprResult +TemplateInstantiator::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) { + VarDecl *Var + = cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(), + SemaRef.CurContext, + TemplateArgs)); + if (!Var) + return SemaRef.ExprError(); + + SemaRef.CurrentInstantiationScope->InstantiatedLocal(E->getVarDecl(), Var); + return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr( + E->getStartLoc(), + SourceLocation(), + Var)); +} + QualType TemplateInstantiator::TransformTemplateTypeParmType( const TemplateTypeParmType *T) { @@ -711,6 +804,17 @@ void Sema::InstantiateClassTemplateSpecializationMembers( ClassTemplateSpec->getTemplateArgs()); } +Sema::OwningExprResult +Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) { + if (!E) + return Owned(E); + + TemplateInstantiator Instantiator(*this, TemplateArgs, + SourceLocation(), + DeclarationName()); + return Instantiator.TransformExpr(E); +} + /// \brief Instantiate a nested-name-specifier. NestedNameSpecifier * Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS, |