[clang-tools-extra] 55db533 - [clang-tidy] Add redundant qualified alias check (#180404)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Mar 14 15:18:30 PDT 2026
Author: Daniil Dudkin
Date: 2026-03-15T01:18:25+03:00
New Revision: 55db533b74fe0872a4a6644223a3ea77a152eaa4
URL: https://github.com/llvm/llvm-project/commit/55db533b74fe0872a4a6644223a3ea77a152eaa4
DIFF: https://github.com/llvm/llvm-project/commit/55db533b74fe0872a4a6644223a3ea77a152eaa4.diff
LOG: [clang-tidy] Add redundant qualified alias check (#180404)
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. `OnlyNamespaceScope` controls whether
local/class scopes are included (default `false`).
Depends on: #183940 #183941
Added:
clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp
clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.h
clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp
Modified:
clang-tools-extra/clang-tidy/readability/CMakeLists.txt
clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst
Removed:
################################################################################
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..a306f205a8447
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.cpp
@@ -0,0 +1,220 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <cassert>
+#include <optional>
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+struct TypeLocInfo {
+ TypeLoc Loc;
+ bool HasQualifier = false;
+};
+
+} // namespace
+
+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<TypeLocInfo> getTypeLocInfo(TypeLoc TL) {
+ if (TL.isNull())
+ return std::nullopt;
+
+ const auto MakeTypeLocInfo = [](auto TypeTL) {
+ const bool HasQualifier =
+ static_cast<bool>(TypeTL.getQualifierLoc().getNestedNameSpecifier());
+ return TypeLocInfo{TypeTL, HasQualifier};
+ };
+
+ if (const auto TypedefTL = TL.getAs<TypedefTypeLoc>())
+ return MakeTypeLocInfo(TypedefTL);
+
+ if (const auto TagTL = TL.getAs<TagTypeLoc>())
+ return MakeTypeLocInfo(TagTL);
+
+ return std::nullopt;
+}
+
+static const NamedDecl *getNamedDeclFromTypeLoc(TypeLoc TL) {
+ if (const auto TypedefTL = TL.getAs<TypedefTypeLoc>())
+ return TypedefTL.getDecl();
+ if (const auto TagTL = TL.getAs<TagTypeLoc>())
+ return TagTL.getDecl();
+ return nullptr;
+}
+
+static bool hasSameUnqualifiedName(const NamedDecl *LHS, const NamedDecl *RHS) {
+ return LHS->getName() == RHS->getName();
+}
+
+static bool isNamespaceLikeDeclContext(const DeclContext *DC) {
+ return isa<TranslationUnitDecl, NamespaceDecl>(DC);
+}
+
+static bool canUseUsingDeclarationForTarget(const TypeAliasDecl *Alias,
+ const NamedDecl *Target) {
+ const DeclContext *AliasContext = Alias->getDeclContext()->getRedeclContext();
+ const DeclContext *TargetContext =
+ Target->getDeclContext()->getRedeclContext();
+
+ const auto *AliasRecord = dyn_cast<CXXRecordDecl>(AliasContext);
+ if (!AliasRecord)
+ return isNamespaceLikeDeclContext(TargetContext);
+
+ const auto *TargetRecord = dyn_cast<CXXRecordDecl>(TargetContext);
+ return TargetRecord && AliasRecord->isDerivedFrom(TargetRecord);
+}
+
+static bool hasTrailingSyntaxAfterRhsType(TypeLoc TL, const SourceManager &SM,
+ const LangOptions &LangOpts) {
+ const SourceLocation TypeEndLoc = TL.getEndLoc();
+ if (TypeEndLoc.isInvalid() || TypeEndLoc.isMacroID())
+ return true;
+ const std::optional<Token> NextToken =
+ utils::lexer::findNextTokenSkippingComments(TypeEndLoc, SM, LangOpts);
+ return !NextToken || NextToken->isNot(tok::semi);
+}
+
+namespace {
+
+AST_MATCHER(TypeAliasDecl, isAliasTemplate) {
+ return Node.getDescribedAliasTemplate() != nullptr;
+}
+
+AST_MATCHER(NamedDecl, isInMacro) { return Node.getLocation().isMacroID(); }
+
+AST_MATCHER(TypeAliasDecl, hasAliasAttributes) {
+ if (Node.hasAttrs())
+ return true;
+ const TypeSourceInfo *TSI = Node.getTypeSourceInfo();
+ if (!TSI)
+ return false;
+ for (TypeLoc CurTL = TSI->getTypeLoc(); !CurTL.isNull();
+ CurTL = CurTL.getNextTypeLoc())
+ if (CurTL.getAs<AttributedTypeLoc>())
+ return true;
+ return false;
+}
+
+AST_MATCHER(TypeLoc, isNonDependentTypeLoc) {
+ return !Node.getType().isNull() && !Node.getType()->isDependentType();
+}
+
+AST_MATCHER(TypeLoc, isNonElaboratedTypeLoc) {
+ const auto IsNonElaboratedTypeLoc = [](auto TL) {
+ return !TL.isNull() && !TL.getElaboratedKeywordLoc().isValid();
+ };
+ return IsNonElaboratedTypeLoc(Node.getAs<TypedefTypeLoc>()) ||
+ IsNonElaboratedTypeLoc(Node.getAs<TagTypeLoc>());
+}
+
+AST_MATCHER(TypeLoc, isMacroFreeTypeLoc) {
+ const ASTContext &Context = Finder->getASTContext();
+ return !hasMacroInRange(Node.getSourceRange(), Context.getSourceManager(),
+ Context.getLangOpts());
+}
+
+AST_MATCHER(TypeLoc, hasNoTrailingSyntaxAfterTypeLoc) {
+ const ASTContext &Context = Finder->getASTContext();
+ return !hasTrailingSyntaxAfterRhsType(Node, Context.getSourceManager(),
+ Context.getLangOpts());
+}
+
+AST_MATCHER(TypeAliasDecl, hasUsingDeclarationEquivalentTarget) {
+ const TypeSourceInfo *TSI = Node.getTypeSourceInfo();
+ if (!TSI)
+ return false;
+ const std::optional<TypeLocInfo> TypeInfo = getTypeLocInfo(TSI->getTypeLoc());
+ if (!TypeInfo || !TypeInfo->HasQualifier)
+ return false;
+ const NamedDecl *Target = getNamedDeclFromTypeLoc(TypeInfo->Loc);
+ return Target && hasSameUnqualifiedName(&Node, Target) &&
+ canUseUsingDeclarationForTarget(&Node, Target);
+}
+
+} // namespace
+
+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) {
+ const auto ControlFlowInitStatementMatcher = stmt(
+ anyOf(mapAnyOf(ifStmt, switchStmt, cxxForRangeStmt)
+ .with(hasInitStatement(stmt(equalsBoundNode("initDeclStmt")))),
+ forStmt(hasLoopInit(stmt(equalsBoundNode("initDeclStmt"))))));
+
+ const auto AliasPreconditions =
+ allOf(unless(isInMacro()), unless(isAliasTemplate()),
+ unless(hasAliasAttributes()));
+ const auto InControlFlowInit =
+ allOf(hasParent(declStmt().bind("initDeclStmt")),
+ hasAncestor(ControlFlowInitStatementMatcher));
+ const auto RewriteableTypeLoc =
+ typeLoc(allOf(isNonDependentTypeLoc(), isNonElaboratedTypeLoc(),
+ isMacroFreeTypeLoc(), hasNoTrailingSyntaxAfterTypeLoc()))
+ .bind("loc");
+
+ const auto RedundantQualifiedAliasMatcher = typeAliasDecl(
+ AliasPreconditions, unless(InControlFlowInit),
+ hasUsingDeclarationEquivalentTarget(), hasTypeLoc(RewriteableTypeLoc));
+
+ if (OnlyNamespaceScope) {
+ Finder->addMatcher(typeAliasDecl(RedundantQualifiedAliasMatcher,
+ hasDeclContext(anyOf(translationUnitDecl(),
+ namespaceDecl())))
+ .bind("alias"),
+ this);
+ return;
+ }
+ Finder->addMatcher(RedundantQualifiedAliasMatcher.bind("alias"), this);
+}
+
+void RedundantQualifiedAliasCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ const auto *Alias = Result.Nodes.getNodeAs<TypeAliasDecl>("alias");
+ assert(Alias && "matcher must bind alias");
+ const auto *WrittenTLNode = Result.Nodes.getNodeAs<TypeLoc>("loc");
+ assert(WrittenTLNode && "matcher must bind loc");
+ const TypeLoc WrittenTL = *WrittenTLNode;
+
+ const SourceManager &SM = *Result.SourceManager;
+ const LangOptions &LangOpts = getLangOpts();
+
+ const SourceLocation AliasLoc = Alias->getLocation();
+ const SourceLocation RhsBeginLoc = WrittenTL.getBeginLoc();
+ const CharSourceRange EqualRange = utils::lexer::findTokenTextInRange(
+ CharSourceRange::getCharRange(AliasLoc, RhsBeginLoc), SM, LangOpts,
+ [](const Token &Tok) { return Tok.is(tok::equal); });
+ if (EqualRange.isInvalid())
+ return;
+
+ auto Diag = diag(Alias->getLocation(),
+ "type alias is redundant; use a using-declaration instead");
+
+ Diag << FixItHint::CreateRemoval(Alias->getLocation())
+ << FixItHint::CreateRemoval(EqualRange.getBegin());
+}
+
+} // 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..4290f36c70952
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/RedundantQualifiedAliasCheck.h
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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;
+ }
+ std::optional<TraversalKind> getCheckTraversalKind() const override {
+ return TK_IgnoreUnlessSpelledInSource;
+ }
+ 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 bdffdb8709405..751550c2e0940 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -154,6 +154,12 @@ New checks
Suggests insertion of ``std::move(...)`` to turn copy assignment operator
calls into move assignment ones, when deemed valid and profitable.
+- New :doc:`readability-redundant-qualified-alias
+ <clang-tidy/checks/readability/redundant-qualified-alias>` check.
+
+ Finds redundant identity type aliases that re-expose a qualified name and can
+ be replaced with a ``using`` declaration.
+
- 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 fcde0ea474913..ceab1e9414951 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -417,6 +417,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..b1af171ae5093
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-qualified-alias.rst
@@ -0,0 +1,30 @@
+.. title:: clang-tidy - readability-redundant-qualified-alias
+
+readability-redundant-qualified-alias
+=====================================
+
+Finds redundant identity type aliases that re-expose a qualified name and can
+be replaced with a ``using`` declaration.
+
+.. code-block:: c++
+
+ using seconds = std::chrono::seconds;
+
+ // becomes
+
+ using std::chrono::seconds;
+
+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.
+
+Options
+-------
+
+.. option:: OnlyNamespaceScope
+
+ When `true`, only consider aliases declared in a namespace or the
+ translation unit. When `false`, also consider aliases declared inside
+ classes, functions, and lambdas. Default is `false`.
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..63fd558084370
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-qualified-alias.cpp
@@ -0,0 +1,203 @@
+// 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 }}'
+// RUN: %check_clang_tidy -check-suffixes=,CXX23 -std=c++23-or-later %s readability-redundant-qualified-alias %t
+// RUN: %check_clang_tidy -check-suffixes=NS,NS-CXX23 -std=c++23-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 {};
+enum PlainEnum { V0 };
+enum class ScopedEnum { V1 };
+struct Commented {};
+struct AfterType {};
+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 {};
+struct Outer {
+ struct Inner {};
+};
+
+using Foo = n1::Foo;
+// 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]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-FIXES: using ::n1::Bar;
+
+using Attr = n1::Attr __attribute__((aligned(8)));
+// 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 alias_attr {
+using Foo [[deprecated("alias attr")]] = 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 alias_attr
+
+using Deep = n2::n3::Deep;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-FIXES: using n2::n3::Deep;
+
+using TypedefFoo = td::TypedefFoo;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-FIXES: using td::TypedefFoo;
+
+using GlobalType = ::GlobalType;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-FIXES: using ::GlobalType;
+
+using PlainEnum = n1::PlainEnum;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-FIXES: using n1::PlainEnum;
+
+using ScopedEnum = n1::ScopedEnum;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-FIXES: using n1::ScopedEnum;
+
+using Inner = Outer::Inner;
+// 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 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-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>
+struct Vec {};
+} // namespace templ
+
+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-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]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-FIXES: using{{[ ]+}}/*comment*/{{[ ]+}}n1::Commented;
+
+using AfterType = n1::AfterType /*rhs-comment*/;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-MESSAGES-NS: :[[@LINE-2]]:7: warning: type alias is redundant; use a using-declaration instead
+// CHECK-FIXES: using n1::AfterType /*rhs-comment*/;
+
+#define DECL_END ;
+using MacroDeclEnd = n1::MacroType DECL_END
+// 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 ALIAS MacroType
+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-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-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;
+};
+
+struct Derived : Base {
+ using T = Base::T;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-FIXES: using Base::T;
+};
+
+struct ClassScopeNamespaceAlias {
+ 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
+};
+
+void local_scope() {
+ using LocalType = n1::LocalType;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-MESSAGES-NS-NOT: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-FIXES: using n1::LocalType;
+}
+
+#if __cplusplus >= 202302L
+void cxx23_init_statement_scope(bool Cond) {
+ if (using Foo = n1::Foo; Cond) {
+ }
+ // CHECK-MESSAGES-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-MESSAGES-NS-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+
+ switch (using Bar = ::n1::Bar; 0) {
+ default:
+ break;
+ }
+ // CHECK-MESSAGES-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-MESSAGES-NS-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+
+ for (using Deep = n2::n3::Deep; Cond;) {
+ Cond = false;
+ }
+ // CHECK-MESSAGES-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-MESSAGES-NS-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+
+ int Values[] = {0};
+ for (using GlobalType = ::GlobalType; int V : Values) {
+ (void)V;
+ }
+ // CHECK-MESSAGES-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+ // CHECK-MESSAGES-NS-CXX23-NOT: warning: type alias is redundant; use a using-declaration instead
+}
+#endif // __cplusplus >= 202302L
More information about the cfe-commits
mailing list