diff options
author | John McCall <rjmccall@apple.com> | 2010-04-09 17:38:44 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-04-09 17:38:44 +0000 |
commit | 6cd3b9fb8a29bb70fff01719bdde238723d67c10 (patch) | |
tree | 48b28e5ab0edee1fdf1dd4d80aae549fe42a91d7 /lib/Sema | |
parent | 1a4221cbe1912421ed7e29d0bbac39e9792af8a2 (diff) |
Instantiate default argument expressions even if their associated parameter
type isn't dependent. Fixes rdar://problem/7838962.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100871 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.h | 5 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 50 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 7 |
3 files changed, 59 insertions, 3 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 65c5793be8..3250870d63 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -3638,6 +3638,11 @@ public: const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity); + TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T, + const MultiLevelTemplateArgumentList &TemplateArgs, + SourceLocation Loc, + DeclarationName Entity); + OwningExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs); diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index d21862b71e..6895364abf 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -959,6 +959,56 @@ QualType Sema::SubstType(QualType T, return Instantiator.TransformType(T); } +static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) { + if (T->getType()->isDependentType()) + return true; + + TypeLoc TL = T->getTypeLoc(); + if (!isa<FunctionProtoTypeLoc>(TL)) + return false; + + FunctionProtoTypeLoc FP = cast<FunctionProtoTypeLoc>(TL); + for (unsigned I = 0, E = FP.getNumArgs(); I != E; ++I) { + ParmVarDecl *P = FP.getArg(I); + + // TODO: currently we always rebuild expressions. When we + // properly get lazier about this, we should use the same + // logic to avoid rebuilding prototypes here. + if (P->hasInit()) + return true; + } + + return false; +} + +/// A form of SubstType intended specifically for instantiating the +/// type of a FunctionDecl. Its purpose is solely to force the +/// instantiation of default-argument expressions. +TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T, + const MultiLevelTemplateArgumentList &Args, + SourceLocation Loc, + DeclarationName Entity) { + assert(!ActiveTemplateInstantiations.empty() && + "Cannot perform an instantiation without some context on the " + "instantiation stack"); + + if (!NeedsInstantiationAsFunctionType(T)) + return T; + + TemplateInstantiator Instantiator(*this, Args, Loc, Entity); + + TypeLocBuilder TLB; + + TypeLoc TL = T->getTypeLoc(); + TLB.reserve(TL.getFullDataSize()); + + QualType Result = Instantiator.TransformType(TLB, TL, QualType()); + if (Result.isNull()) + return 0; + + return TLB.getTypeSourceInfo(Context, Result); +} + /// \brief Perform substitution on the base class specifiers of the /// given class template specialization. /// diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 1ac854c770..82270451cb 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1826,9 +1826,10 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, TypeSourceInfo *OldTInfo = D->getTypeSourceInfo(); assert(OldTInfo && "substituting function without type source info"); assert(Params.empty() && "parameter vector is non-empty at start"); - TypeSourceInfo *NewTInfo = SemaRef.SubstType(OldTInfo, TemplateArgs, - D->getTypeSpecStartLoc(), - D->getDeclName()); + TypeSourceInfo *NewTInfo + = SemaRef.SubstFunctionDeclType(OldTInfo, TemplateArgs, + D->getTypeSpecStartLoc(), + D->getDeclName()); if (!NewTInfo) return 0; |