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/SemaTemplateInstantiate.cpp | |
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/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
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. /// |