diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-31 17:21:17 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-31 17:21:17 +0000 |
commit | 550d9b28fd586db541eb6dd36f3c10d114e483d8 (patch) | |
tree | b01023c9c5330b297f5388de6ac1a22dadc028b1 /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | df7c3b955e31a6951822f2adf36e98543ef14c7e (diff) |
Implement "incremental" template instantiation for non-type template
parameters and template type parameters, which occurs when
substituting into the declarations of member templates inside class
templates. This eliminates errors about our inability to "reduce
non-type template parameter depth", fixing PR5311.
Also fixes a bug when instantiating a template type parameter
declaration in a member template, where we weren't properly reducing
the template parameter's depth.
LLVM's StringSwitch header now parses.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85669 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 99 |
1 files changed, 50 insertions, 49 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 8fab8f62e4..e79511f923 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -562,58 +562,59 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) { // FIXME: Clean this up a bit NamedDecl *D = E->getDecl(); if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) { - if (NTTP->getDepth() >= TemplateArgs.getNumLevels()) { - assert(false && "Cannot reduce non-type template parameter depth yet"); - return getSema().ExprError(); - } - - // 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 (!TemplateArgs.hasTemplateArgument(NTTP->getDepth(), - NTTP->getPosition())) - return SemaRef.Owned(E->Retain()); - - const TemplateArgument &Arg = TemplateArgs(NTTP->getDepth(), - NTTP->getPosition()); - - // The template argument itself might be an expression, in which - // case we just return that expression. - if (Arg.getKind() == TemplateArgument::Expression) - return SemaRef.Owned(Arg.getAsExpr()->Retain()); - - if (Arg.getKind() == TemplateArgument::Declaration) { - ValueDecl *VD = cast<ValueDecl>(Arg.getAsDecl()); - - VD = cast_or_null<ValueDecl>( - getSema().FindInstantiatedDecl(VD, TemplateArgs)); - if (!VD) - return SemaRef.ExprError(); - - return SemaRef.BuildDeclRefExpr(VD, VD->getType(), E->getLocation(), - /*FIXME:*/false, /*FIXME:*/false); - } + if (NTTP->getDepth() < TemplateArgs.getNumLevels()) { + + // 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 (!TemplateArgs.hasTemplateArgument(NTTP->getDepth(), + NTTP->getPosition())) + return SemaRef.Owned(E->Retain()); + + const TemplateArgument &Arg = TemplateArgs(NTTP->getDepth(), + NTTP->getPosition()); + + // The template argument itself might be an expression, in which + // case we just return that expression. + if (Arg.getKind() == TemplateArgument::Expression) + return SemaRef.Owned(Arg.getAsExpr()->Retain()); + + if (Arg.getKind() == TemplateArgument::Declaration) { + ValueDecl *VD = cast<ValueDecl>(Arg.getAsDecl()); + + VD = cast_or_null<ValueDecl>( + getSema().FindInstantiatedDecl(VD, TemplateArgs)); + if (!VD) + return SemaRef.ExprError(); + + return SemaRef.BuildDeclRefExpr(VD, VD->getType(), E->getLocation(), + /*FIXME:*/false, /*FIXME:*/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(), + 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())); + } + + // We have a non-type template parameter that isn't fully substituted; + // FindInstantiatedDecl will find it in the local instantiation scope. } NamedDecl *InstD = SemaRef.FindInstantiatedDecl(D, TemplateArgs); |