Index: lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -1512,7 +1512,7 @@ } static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) { - if (T->getType()->isInstantiationDependentType() || + if (T->getType()->isInstantiationDependentType() || T->getType()->isVariablyModifiedType()) return true; @@ -1522,22 +1522,12 @@ FunctionProtoTypeLoc FP = TL.castAs(); for (unsigned I = 0, E = FP.getNumParams(); I != E; ++I) { - ParmVarDecl *P = FP.getParam(I); - // This must be synthesized from a typedef. - if (!P) continue; - - // The parameter's type as written might be dependent even if the - // decayed type was not dependent. - if (TypeSourceInfo *TSInfo = P->getTypeSourceInfo()) - if (TSInfo->getType()->isInstantiationDependentType()) - return true; + if (!FP.getParam(I)) continue; - // 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->hasDefaultArg()) - return true; + // If there are any parameters, a new TypeSourceInfo that refers to the + // instantiated parameters must be built. + return true; } return false; @@ -1556,7 +1546,7 @@ assert(!ActiveTemplateInstantiations.empty() && "Cannot perform an instantiation without some context on the " "instantiation stack"); - + if (!NeedsInstantiationAsFunctionType(T)) return T; Index: unittests/ASTMatchers/ASTMatchersTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersTest.cpp +++ unittests/ASTMatchers/ASTMatchersTest.cpp @@ -4276,6 +4276,17 @@ declRefExpr(to(decl(hasAncestor(decl())))))); } +TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) { + EXPECT_TRUE(matches("struct PartitionAllocator {\n" + " template\n" + " static int quantizedSize(int count) {\n" + " return count;\n" + " }\n" + " void f() { quantizedSize(10); }\n" + "};", + declRefExpr(to(decl(hasAncestor(decl())))))); +} + TEST(HasParent, MatchesAllParents) { EXPECT_TRUE(matches( "template struct C { static void f() { 42; } };"