diff --git a/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp index 5f2519ce9d5c3..0816625b1937d 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp @@ -18,9 +18,9 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { void RedundantTypenameCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(typeLoc(unless(hasAncestor(decl(isInstantiated())))) - .bind("nonDependentTypeLoc"), - this); + Finder->addMatcher( + typeLoc(unless(hasAncestor(decl(isInstantiated())))).bind("typeLoc"), + this); if (!getLangOpts().CPlusPlus20) return; @@ -44,38 +44,34 @@ void RedundantTypenameCheck::registerMatchers(MatchFinder *Finder) { } void RedundantTypenameCheck::check(const MatchFinder::MatchResult &Result) { + const TypeLoc TL = [&] { + if (const auto *TL = Result.Nodes.getNodeAs("typeLoc")) + return TL->getType()->isDependentType() ? TypeLoc() : *TL; + + auto TL = *Result.Nodes.getNodeAs("dependentTypeLoc"); + while (const TypeLoc Next = TL.getNextTypeLoc()) + TL = Next; + return TL; + }(); + + if (TL.isNull()) + return; + const SourceLocation ElaboratedKeywordLoc = [&] { - if (const auto *NonDependentTypeLoc = - Result.Nodes.getNodeAs("nonDependentTypeLoc")) { - if (NonDependentTypeLoc->getType()->isDependentType()) - return SourceLocation(); - - if (const auto TL = NonDependentTypeLoc->getAs()) - return TL.getElaboratedKeywordLoc(); - - if (const auto TL = NonDependentTypeLoc->getAs()) - return TL.getElaboratedKeywordLoc(); - - if (const auto TL = NonDependentTypeLoc - ->getAs()) - return TL.getElaboratedKeywordLoc(); - - if (const auto TL = - NonDependentTypeLoc->getAs()) - return TL.getElaboratedKeywordLoc(); - } else { - TypeLoc InnermostTypeLoc = - *Result.Nodes.getNodeAs("dependentTypeLoc"); - while (const TypeLoc Next = InnermostTypeLoc.getNextTypeLoc()) - InnermostTypeLoc = Next; - - if (const auto TL = InnermostTypeLoc.getAs()) - return TL.getElaboratedKeywordLoc(); - - if (const auto TL = - InnermostTypeLoc.getAs()) - return TL.getElaboratedKeywordLoc(); - } + if (const auto CastTL = TL.getAs()) + return CastTL.getElaboratedKeywordLoc(); + + if (const auto CastTL = TL.getAs()) + return CastTL.getElaboratedKeywordLoc(); + + if (const auto CastTL = TL.getAs()) + return CastTL.getElaboratedKeywordLoc(); + + if (const auto CastTL = TL.getAs()) + return CastTL.getElaboratedKeywordLoc(); + + if (const auto CastTL = TL.getAs()) + return CastTL.getElaboratedKeywordLoc(); return SourceLocation(); }(); diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp index e8fcd9bcd5731..96bd7b6412724 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-typename.cpp @@ -271,13 +271,21 @@ WHOLE_DECLARATION_IN_MACRO; template struct Wrapper {}; template struct ClassWrapper { - using R = T; - Wrapper f(); + using R = T; + Wrapper f(); + R g(); }; template Wrapper::R> ClassWrapper::f() { - return {}; + return {}; +} + +template +typename ClassWrapper::R ClassWrapper::g() { +// CHECK-MESSAGES-20: :[[@LINE-1]]:1: warning: redundant 'typename' [readability-redundant-typename] +// CHECK-FIXES-20: ClassWrapper::R ClassWrapper::g() { + return {}; } template struct StructWrapper {}; @@ -285,9 +293,17 @@ template class ClassWithNestedStruct { struct Nested {}; StructWrapper f(); + Nested g(); }; template StructWrapper::Nested> ClassWithNestedStruct::f() { return {}; } + +template +typename ClassWithNestedStruct::Nested ClassWithNestedStruct::g() { +// CHECK-MESSAGES-20: :[[@LINE-1]]:1: warning: redundant 'typename' [readability-redundant-typename] +// CHECK-FIXES-20: ClassWithNestedStruct::Nested ClassWithNestedStruct::g() { + return {}; +}