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);
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.
///
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;
--- /dev/null
+// RUN: %clang_cc1 -verify -emit-llvm-only %s
+
+// rdar://problem/7838962
+namespace test0 {
+ template<typename T> unsigned f0() {
+ return T::MaxSize; // expected-error {{'int' cannot be used prior to '::'}}
+ };
+ template<typename T> class A {
+ void Allocate(unsigned Alignment
+ = f0<T>()) // expected-note {{in instantiation}}
+ {}
+ };
+ void f1(A<int> x) { x.Allocate(); }
+
+}