22 typeLoc(unless(hasAncestor(decl(isInstantiated())))).bind(
"typeLoc"),
25 if (!getLangOpts().CPlusPlus20)
28 const auto InImplicitTypenameContext = anyOf(
30 typedefNameDecl(), templateTypeParmDecl(), nonTypeTemplateParmDecl(),
31 friendDecl(), fieldDecl(),
32 varDecl(hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl())),
33 unless(parmVarDecl())),
34 parmVarDecl(hasParent(expr(requiresExpr()))),
35 parmVarDecl(hasParent(typeLoc(hasParent(decl(
36 anyOf(cxxMethodDecl(), hasParent(friendDecl()),
37 functionDecl(has(nestedNameSpecifier())),
38 cxxDeductionGuideDecl(hasDeclContext(recordDecl())))))))),
40 functionDecl(unless(cxxConversionDecl()))))),
41 hasParent(expr(anyOf(cxxNamedCastExpr(), cxxNewExpr()))));
43 typeLoc(InImplicitTypenameContext).bind(
"dependentTypeLoc"),
this);
47 const TypeLoc TL = [&] {
48 if (
const auto *TL = Result.Nodes.getNodeAs<TypeLoc>(
"typeLoc"))
49 return TL->getType()->isDependentType() ? TypeLoc() : *TL;
51 auto TL = *Result.Nodes.getNodeAs<TypeLoc>(
"dependentTypeLoc");
52 while (
const TypeLoc Next = TL.getNextTypeLoc())
60 const SourceLocation ElaboratedKeywordLoc = [&] {
61 if (
const auto CastTL = TL.getAs<TypedefTypeLoc>())
62 return CastTL.getElaboratedKeywordLoc();
64 if (
const auto CastTL = TL.getAs<TagTypeLoc>())
65 return CastTL.getElaboratedKeywordLoc();
67 if (
const auto CastTL = TL.getAs<DeducedTemplateSpecializationTypeLoc>())
68 return CastTL.getElaboratedKeywordLoc();
70 if (
const auto CastTL = TL.getAs<TemplateSpecializationTypeLoc>())
71 return CastTL.getElaboratedKeywordLoc();
73 if (
const auto CastTL = TL.getAs<DependentNameTypeLoc>())
74 return CastTL.getElaboratedKeywordLoc();
76 return SourceLocation();
79 if (ElaboratedKeywordLoc.isInvalid())
82 if (Token ElaboratedKeyword;
83 Lexer::getRawToken(ElaboratedKeywordLoc, ElaboratedKeyword,
84 *Result.SourceManager, getLangOpts()) ||
85 ElaboratedKeyword.getRawIdentifier() !=
"typename")
88 diag(ElaboratedKeywordLoc,
"redundant 'typename'")
89 << FixItHint::CreateRemoval(ElaboratedKeywordLoc);