diff options
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 795e6025d96..fd086a4f7f7 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1653,6 +1653,7 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> { typedef RecursiveASTVisitor<DependencyChecker> super; unsigned Depth; + bool FindLessThanDepth; // Whether we're looking for a use of a template parameter that makes the // overall construct type-dependent / a dependent type. This is strictly @@ -1663,25 +1664,16 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> { bool Match; SourceLocation MatchLoc; - DependencyChecker(unsigned Depth, bool IgnoreNonTypeDependent) - : Depth(Depth), IgnoreNonTypeDependent(IgnoreNonTypeDependent), - Match(false) {} + DependencyChecker(unsigned Depth, bool IgnoreNonTypeDependent, + bool FindLessThanDepth = false) + : Depth(Depth), FindLessThanDepth(FindLessThanDepth), + IgnoreNonTypeDependent(IgnoreNonTypeDependent), Match(false) {} DependencyChecker(TemplateParameterList *Params, bool IgnoreNonTypeDependent) - : IgnoreNonTypeDependent(IgnoreNonTypeDependent), Match(false) { - NamedDecl *ND = Params->getParam(0); - if (TemplateTypeParmDecl *PD = dyn_cast<TemplateTypeParmDecl>(ND)) { - Depth = PD->getDepth(); - } else if (NonTypeTemplateParmDecl *PD = - dyn_cast<NonTypeTemplateParmDecl>(ND)) { - Depth = PD->getDepth(); - } else { - Depth = cast<TemplateTemplateParmDecl>(ND)->getDepth(); - } - } + : DependencyChecker(Params->getDepth(), IgnoreNonTypeDependent) {} bool Matches(unsigned ParmDepth, SourceLocation Loc = SourceLocation()) { - if (ParmDepth >= Depth) { + if (FindLessThanDepth ^ (ParmDepth >= Depth)) { Match = true; MatchLoc = Loc; return true; @@ -5838,6 +5830,15 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, return E; } +static bool isDependentOnOuter(NonTypeTemplateParmDecl *NTTP) { + if (NTTP->getDepth() == 0 || !NTTP->getType()->isDependentType()) + return false; + DependencyChecker Checker(NTTP->getDepth(), /*IgnoreNonTypeDependent*/ false, + /*FindLessThanDepth*/ true); + Checker.TraverseType(NTTP->getType()); + return Checker.Match; +} + /// \brief Match two template parameters within template parameter lists. static bool MatchTemplateParameterKind(Sema &S, NamedDecl *New, NamedDecl *Old, bool Complain, @@ -5894,11 +5895,10 @@ static bool MatchTemplateParameterKind(Sema &S, NamedDecl *New, NamedDecl *Old, // If we are matching a template template argument to a template // template parameter and one of the non-type template parameter types - // is dependent, then we must wait until template instantiation time - // to actually compare the arguments. + // is dependent on an outer template's parameter, then we must wait until + // template instantiation time to actually compare the arguments. if (Kind == Sema::TPL_TemplateTemplateArgumentMatch && - (OldNTTP->getType()->isDependentType() || - NewNTTP->getType()->isDependentType())) + (isDependentOnOuter(OldNTTP) || isDependentOnOuter(NewNTTP))) return true; if (!S.Context.hasSameType(OldNTTP->getType(), NewNTTP->getType())) { |