https://github.com/unterumarmung updated https://github.com/llvm/llvm-project/pull/180404
>From a52f79dde31f06861ba2d9391398823de0065368 Mon Sep 17 00:00:00 2001 From: Daniil Dudkin <[email protected]> Date: Sun, 8 Feb 2026 14:16:43 +0300 Subject: [PATCH 1/2] [clang-tidy] Add redundant qualified alias check Introduce `readability-redundant-qualified-alias` to flag identity type aliases that repeat a qualified name and suggest using-declarations when safe. The check is conservative: it skips macros, elaborated keywords, dependent types, and templates, and it suppresses fix-its when comments appear between the alias name and '='. `OnlyNamespaceScope` controls whether local/class scopes are included (default false). --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../readability/ReadabilityTidyModule.cpp | 3 + .../RedundantQualifiedAliasCheck.cpp | 256 ++++++++++++++++++ .../RedundantQualifiedAliasCheck.h | 37 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../readability/redundant-qualified-alias.rst | 29 ++ .../readability/redundant-qualified-alias.cpp | 122 +++++++++ 8 files changed, 455 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index f1f3cde32feff..686e7c19d650b 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -47,6 +47,7 @@ add_clang_library(clangTidyReadabilityModule STATIC RedundantMemberInitCheck.cpp RedundantParenthesesCheck.cpp RedundantPreprocessorCheck.cpp + RedundantQualifiedAliasCheck.cpp RedundantSmartptrGetCheck.cpp RedundantStringCStrCheck.cpp RedundantStringInitCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index c582dc98eac6b..8e9e00b23c84a 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -49,6 +49,7 @@ #include "RedundantMemberInitCheck.h" #include "RedundantParenthesesCheck.h" #include "RedundantPreprocessorCheck.h" +#include "RedundantQualifiedAliasCheck.h" #include "RedundantSmartptrGetCheck.h" #include "RedundantStringCStrCheck.h" #include "RedundantStringInitCheck.h" @@ -148,6 +149,8 @@ class ReadabilityModule : public ClangTidyModule { "readability-redundant-parentheses"); CheckFactories.registerCheck<RedundantPreprocessorCheck>( "readability-redundant-preprocessor"); + CheckFactories.registerCheck<RedundantQualifiedAliasCheck>( + "readability-redundant-qualified-alias"); CheckFactories.registerCheck<RedundantTypenameCheck>( "readability-redundant-typename"); CheckFactories.registerCheck<ReferenceToConstructedTemporaryCheck>( diff --git a/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp new file mode 100644 index 0000000000000..c6f59cf0e0306 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp @@ -0,0 +1,256 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "RedundantQualifiedAliasCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/AST/Decl.h" +#include "clang/AST/TypeLoc.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" +#include <optional> + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +namespace { + +struct NominalTypeLocInfo { + TypeLoc Loc; + bool HasQualifier = false; +}; + +struct EqualTokenInfo { + SourceLocation AfterEqualLoc; + bool SawComment = false; +}; + +} // namespace + +static bool isInNamespaceOrTU(const Decl *D) { + const DeclContext *DC = D->getDeclContext(); + return DC && (DC->isTranslationUnit() || isa<NamespaceDecl>(DC)); +} + +static bool isAliasTemplate(const TypeAliasDecl *Alias) { + return Alias->getDescribedAliasTemplate() != nullptr; +} + +static bool hasMacroInRange(SourceRange Range, const SourceManager &SM, + const LangOptions &LangOpts) { + if (Range.isInvalid()) + return true; + return utils::lexer::rangeContainsExpansionsOrDirectives(Range, SM, LangOpts); +} + +static std::optional<NominalTypeLocInfo> peelToNominalTypeLoc(TypeLoc TL) { + while (!TL.isNull()) { + if (const auto ParenTL = TL.getAs<ParenTypeLoc>()) { + TL = ParenTL.getInnerLoc(); + continue; + } + if (const auto AttrTL = TL.getAs<AttributedTypeLoc>()) { + // Preserve any attributes by rewriting only the alias name and '='. + TL = AttrTL.getModifiedLoc(); + continue; + } + + if (const auto TypedefTL = TL.getAs<TypedefTypeLoc>()) { + // Avoid rewriting aliases that use an elaborated keyword + // (class/struct/enum). + if (TypedefTL.getElaboratedKeywordLoc().isValid()) + return std::nullopt; + const bool HasQualifier = static_cast<bool>( + TypedefTL.getQualifierLoc().getNestedNameSpecifier()); + return NominalTypeLocInfo{TypedefTL, HasQualifier}; + } + + if (const auto TagTL = TL.getAs<TagTypeLoc>()) { + // Avoid rewriting aliases that use an elaborated keyword + // (class/struct/enum). + if (TagTL.getElaboratedKeywordLoc().isValid()) + return std::nullopt; + const bool HasQualifier = + static_cast<bool>(TagTL.getQualifierLoc().getNestedNameSpecifier()); + return NominalTypeLocInfo{TagTL, HasQualifier}; + } + + return std::nullopt; + } + return std::nullopt; +} + +static const NamedDecl *getNamedDeclFromNominalTypeLoc(TypeLoc TL) { + if (const auto TypedefTL = TL.getAs<TypedefTypeLoc>()) + return TypedefTL.getTypePtr()->getDecl(); + if (const auto TagTL = TL.getAs<TagTypeLoc>()) + return TagTL.getDecl(); + return nullptr; +} + +static bool hasSameUnqualifiedName(const TypeAliasDecl *Alias, + const NamedDecl *Target) { + return Alias->getName() == Target->getName(); +} + +static std::optional<EqualTokenInfo> +findEqualTokenAfter(SourceLocation StartLoc, SourceLocation LimitLoc, + const SourceManager &SM, const LangOptions &LangOpts) { + if (StartLoc.isInvalid() || LimitLoc.isInvalid()) + return std::nullopt; + if (StartLoc.isMacroID() || LimitLoc.isMacroID()) + return std::nullopt; + if (!SM.isBeforeInTranslationUnit(StartLoc, LimitLoc)) + return std::nullopt; + + const SourceLocation SpellingStart = SM.getSpellingLoc(StartLoc); + const SourceLocation SpellingLimit = SM.getSpellingLoc(LimitLoc); + const FileID File = SM.getFileID(SpellingStart); + if (File != SM.getFileID(SpellingLimit)) + return std::nullopt; + + const StringRef Buf = SM.getBufferData(File); + const char *StartChar = SM.getCharacterData(SpellingStart); + Lexer Lex(SpellingStart, LangOpts, StartChar, StartChar, Buf.end()); + Lex.SetCommentRetentionState(true); + + Token Tok; + bool SawComment = false; + do { + Lex.LexFromRawLexer(Tok); + if (Tok.is(tok::comment)) + SawComment = true; + if (Tok.is(tok::equal)) { + Token NextTok; + Lex.LexFromRawLexer(NextTok); + // Return the location *after* '=' so removal is token-preserving. + return EqualTokenInfo{NextTok.getLocation(), SawComment}; + } + } while (Tok.isNot(tok::eof) && Tok.getLocation() < SpellingLimit); + + return std::nullopt; +} + +static std::optional<FixItHint> buildRemovalFixItAfterEqual( + const TypeAliasDecl *Alias, SourceLocation AfterEqualLoc, + const SourceManager &SM, const LangOptions &LangOpts) { + SourceLocation AliasLoc = Alias->getLocation(); + if (AliasLoc.isInvalid() || AfterEqualLoc.isInvalid()) + return std::nullopt; + if (AliasLoc.isMacroID() || AfterEqualLoc.isMacroID()) + return std::nullopt; + + AliasLoc = Lexer::GetBeginningOfToken(AliasLoc, SM, LangOpts); + if (AliasLoc.isInvalid()) + return std::nullopt; + + const CharSourceRange RemovalRange = Lexer::makeFileCharRange( + CharSourceRange::getCharRange(AliasLoc, AfterEqualLoc), SM, LangOpts); + if (RemovalRange.isInvalid()) + return std::nullopt; + + if (hasMacroInRange(RemovalRange.getAsRange(), SM, LangOpts)) + // Avoid rewriting tokens that come from macro expansions. + return std::nullopt; + + return FixItHint::CreateRemoval(RemovalRange); +} + +RedundantQualifiedAliasCheck::RedundantQualifiedAliasCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + OnlyNamespaceScope(Options.get("OnlyNamespaceScope", false)) {} + +void RedundantQualifiedAliasCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "OnlyNamespaceScope", OnlyNamespaceScope); +} + +void RedundantQualifiedAliasCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(typeAliasDecl().bind("alias"), this); +} + +void RedundantQualifiedAliasCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *Alias = Result.Nodes.getNodeAs<TypeAliasDecl>("alias"); + if (!Alias) + return; + + if (OnlyNamespaceScope && !isInNamespaceOrTU(Alias)) + return; + + if (isAliasTemplate(Alias)) + return; + + if (Alias->getLocation().isInvalid() || Alias->getLocation().isMacroID()) + return; + + const TypeSourceInfo *TSI = Alias->getTypeSourceInfo(); + if (!TSI) + return; + + const TypeLoc WrittenTL = TSI->getTypeLoc(); + if (WrittenTL.isNull()) + return; + + if (WrittenTL.getType()->isDependentType()) + return; + + const SourceManager &SM = *Result.SourceManager; + const LangOptions &LangOpts = getLangOpts(); + if (hasMacroInRange(WrittenTL.getSourceRange(), SM, LangOpts)) + return; + + const std::optional<NominalTypeLocInfo> NominalInfo = + peelToNominalTypeLoc(WrittenTL); + if (!NominalInfo) + return; + + if (!NominalInfo->HasQualifier) + // Unqualified RHS would not gain anything from a using-declaration. + return; + + const TypeLoc NominalTL = NominalInfo->Loc; + const NamedDecl *Target = getNamedDeclFromNominalTypeLoc(NominalTL); + if (!Target) + return; + + if (!hasSameUnqualifiedName(Alias, Target)) + return; + + const SourceLocation AliasLoc = Alias->getLocation(); + const SourceLocation RhsBeginLoc = WrittenTL.getBeginLoc(); + const CharSourceRange AliasToRhsRange = Lexer::makeFileCharRange( + CharSourceRange::getCharRange(AliasLoc, RhsBeginLoc), SM, LangOpts); + if (AliasToRhsRange.isInvalid()) + return; + if (hasMacroInRange(AliasToRhsRange.getAsRange(), SM, LangOpts)) + return; + + std::optional<EqualTokenInfo> EqualInfo = + findEqualTokenAfter(AliasLoc, RhsBeginLoc, SM, LangOpts); + if (!EqualInfo || EqualInfo->AfterEqualLoc.isInvalid()) + return; + + auto Diag = diag(Alias->getLocation(), + "type alias is redundant; use a using-declaration instead"); + + if (EqualInfo->SawComment) { + // Suppress fix-it: avoid deleting comments between alias name and '='. + return; + } + + if (const std::optional<FixItHint> Fix = buildRemovalFixItAfterEqual( + Alias, EqualInfo->AfterEqualLoc, SM, LangOpts)) { + Diag << *Fix; + } +} + +} // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.h new file mode 100644 index 0000000000000..201ce73f3594a --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.h @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTQUALIFIEDALIASCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTQUALIFIEDALIASCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// Finds identity type aliases to qualified names that can be expressed as +/// using-declarations. +/// +/// For the user-facing documentation see: +/// https://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-qualified-alias.html +class RedundantQualifiedAliasCheck : public ClangTidyCheck { +public: + RedundantQualifiedAliasCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; // C++11 or later. + } + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + const bool OnlyNamespaceScope; +}; + +} // namespace clang::tidy::readability + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTQUALIFIEDALIASCHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 84c1269658bb8..caf8fa7983a6d 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -128,6 +128,12 @@ New checks Finds and removes redundant conversions from ``std::[w|u8|u16|u32]string_view`` to ``std::[...]string`` in call expressions expecting ``std::[...]string_view``. +- New :doc:`readability-redundant-qualified-alias + <clang-tidy/checks/readability/redundant-qualified-alias>` check. + + Finds redundant identity type aliases of the form ``using X = ns::X;`` and + suggests rewriting them as using-declarations when safe. + - New :doc:`readability-trailing-comma <clang-tidy/checks/readability/trailing-comma>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 0eabd9929dc39..75bc868cf0066 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -414,6 +414,7 @@ Clang-Tidy Checks :doc:`readability-redundant-member-init <readability/redundant-member-init>`, "Yes" :doc:`readability-redundant-parentheses <readability/redundant-parentheses>`, "Yes" :doc:`readability-redundant-preprocessor <readability/redundant-preprocessor>`, + :doc:`readability-redundant-qualified-alias <readability/redundant-qualified-alias>`, "Yes" :doc:`readability-redundant-smartptr-get <readability/redundant-smartptr-get>`, "Yes" :doc:`readability-redundant-string-cstr <readability/redundant-string-cstr>`, "Yes" :doc:`readability-redundant-string-init <readability/redundant-string-init>`, "Yes" diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst new file mode 100644 index 0000000000000..37b2551c70a3d --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst @@ -0,0 +1,29 @@ +.. title:: clang-tidy - readability-redundant-qualified-alias + +readability-redundant-qualified-alias +===================================== + +Finds redundant identity type aliases that simply re-expose a qualified name +and can be replaced with a using-declaration. + +.. code-block:: c++ + + using CommentToken = clang::tidy::utils::lexer::CommentToken; + + // becomes + + using clang::tidy::utils::lexer::CommentToken; + +The check is conservative and only warns when the alias name exactly matches +the unqualified name of a non-dependent, non-specialized named type written +with a qualifier. It skips alias templates, dependent forms, elaborated +keywords (``class``, ``struct``, ``enum``, ``typename``), and cases involving +macros or comments between the alias name and ``=``. + +Options +------- + +.. option:: OnlyNamespaceScope + + When false (default), consider aliases declared in any scope. When true, + only consider aliases declared in a namespace or the translation unit. diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp new file mode 100644 index 0000000000000..ef5f391934eb2 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp @@ -0,0 +1,122 @@ +// RUN: %check_clang_tidy -std=c++11-or-later %s readability-redundant-qualified-alias %t +// RUN: %check_clang_tidy -check-suffix=NS -std=c++11-or-later %s readability-redundant-qualified-alias %t -- \ +// RUN: -config='{CheckOptions: { readability-redundant-qualified-alias.OnlyNamespaceScope: true }}' + +namespace n1 { +struct Foo {}; +struct Bar {}; +struct Attr {}; +struct Commented {}; +struct Elab {}; +struct MacroEq {}; +struct MacroType {}; +struct PtrType {}; +struct LocalType {}; +} // namespace n1 + +namespace n2 { +namespace n3 { +struct Deep {}; +} // namespace n3 +} // namespace n2 + +namespace td { +typedef n1::Foo TypedefFoo; +} // namespace td + +struct GlobalType {}; + +using Foo = n1::Foo; +// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-FIXES: using n1::Foo; + +using Bar = ::n1::Bar; +// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-FIXES: using ::n1::Bar; + +using Attr = n1::Attr __attribute__((aligned(8))); +// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-FIXES: using n1::Attr __attribute__((aligned(8))); + +using Deep = n2::n3::Deep; +// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-FIXES: using n2::n3::Deep; + +using TypedefFoo = td::TypedefFoo; +// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-FIXES: using td::TypedefFoo; + +using GlobalType = ::GlobalType; +// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-FIXES: using ::GlobalType; + +using Builtin = int; +// CHECK-FIXES: using Builtin = int; + +using PtrType = n1::PtrType *; +// CHECK-FIXES: using PtrType = n1::PtrType *; + +namespace templ { +template <typename T> +struct Vec {}; +} // namespace templ + +using Vec = templ::Vec<int>; +// CHECK-FIXES: using Vec = templ::Vec<int>; + +namespace templ_alias { +template <typename T> +using Foo = n1::Foo; +} // namespace templ_alias + +template <typename T> +struct Dependent { + using X = typename T::X; +}; + +using Elab = class n1::Elab; +// CHECK-FIXES: using Elab = class n1::Elab; + +using Commented /*comment*/ = n1::Commented; +// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-FIXES: using Commented /*comment*/ = n1::Commented; + +#define ALIAS MacroType +using ALIAS = n1::MacroType; +// CHECK-FIXES: #define ALIAS MacroType +// CHECK-FIXES: using ALIAS = n1::MacroType; + +#define RHS n1::MacroType +using MacroType = RHS; +// CHECK-FIXES: #define RHS n1::MacroType +// CHECK-FIXES: using MacroType = RHS; + +#define EQ = +using MacroEq EQ n1::MacroEq; +// CHECK-FIXES: #define EQ = +// CHECK-FIXES: using MacroEq EQ n1::MacroEq; + +struct Base { + using T = n1::Foo; +}; + +struct Derived : Base { + using T = Base::T; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] + // CHECK-FIXES: using Base::T; + // CHECK-FIXES-NS: using T = Base::T; +}; + +void local_scope() { + using LocalType = n1::LocalType; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] + // CHECK-FIXES: using n1::LocalType; + // CHECK-FIXES-NS: using LocalType = n1::LocalType; +} >From f49fe8762dba813d623fa68d1edf545f370a4ebd Mon Sep 17 00:00:00 2001 From: Daniil Dudkin <[email protected]> Date: Sun, 8 Feb 2026 17:52:11 +0300 Subject: [PATCH 2/2] Fix review comments --- .../readability/redundant-qualified-alias.cpp | 63 +++++++++++-------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp index ef5f391934eb2..32931c7d6191b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp @@ -27,40 +27,42 @@ typedef n1::Foo TypedefFoo; struct GlobalType {}; using Foo = n1::Foo; -// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] -// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] // CHECK-FIXES: using n1::Foo; using Bar = ::n1::Bar; -// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] -// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] // CHECK-FIXES: using ::n1::Bar; using Attr = n1::Attr __attribute__((aligned(8))); -// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] -// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] // CHECK-FIXES: using n1::Attr __attribute__((aligned(8))); using Deep = n2::n3::Deep; -// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] -// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] // CHECK-FIXES: using n2::n3::Deep; using TypedefFoo = td::TypedefFoo; -// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] -// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] // CHECK-FIXES: using td::TypedefFoo; using GlobalType = ::GlobalType; -// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] -// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] // CHECK-FIXES: using ::GlobalType; using Builtin = int; -// CHECK-FIXES: using Builtin = int; +// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead +// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead using PtrType = n1::PtrType *; -// CHECK-FIXES: using PtrType = n1::PtrType *; +// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead +// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead namespace templ { template <typename T> @@ -68,40 +70,45 @@ struct Vec {}; } // namespace templ using Vec = templ::Vec<int>; -// CHECK-FIXES: using Vec = templ::Vec<int>; +// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead +// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead namespace templ_alias { template <typename T> using Foo = n1::Foo; +// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead +// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead } // namespace templ_alias template <typename T> struct Dependent { using X = typename T::X; + // CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead + // CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead }; using Elab = class n1::Elab; -// CHECK-FIXES: using Elab = class n1::Elab; +// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead +// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead using Commented /*comment*/ = n1::Commented; -// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] -// CHECK-MESSAGES-NS: :[[@LINE-2]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] +// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] // CHECK-FIXES: using Commented /*comment*/ = n1::Commented; - #define ALIAS MacroType using ALIAS = n1::MacroType; -// CHECK-FIXES: #define ALIAS MacroType -// CHECK-FIXES: using ALIAS = n1::MacroType; +// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead +// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead #define RHS n1::MacroType using MacroType = RHS; -// CHECK-FIXES: #define RHS n1::MacroType -// CHECK-FIXES: using MacroType = RHS; +// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead +// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead #define EQ = using MacroEq EQ n1::MacroEq; -// CHECK-FIXES: #define EQ = -// CHECK-FIXES: using MacroEq EQ n1::MacroEq; +// CHECK-MESSAGES-NOT: warning: type alias is redundant; use a using-declaration instead +// CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead struct Base { using T = n1::Foo; @@ -109,14 +116,16 @@ struct Base { struct Derived : Base { using T = Base::T; - // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] + // CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead // CHECK-FIXES: using Base::T; // CHECK-FIXES-NS: using T = Base::T; }; void local_scope() { using LocalType = n1::LocalType; - // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: type alias is redundant; use a using-declaration instead [readability-redundant-qualified-alias] + // CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead // CHECK-FIXES: using n1::LocalType; // CHECK-FIXES-NS: using LocalType = n1::LocalType; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
