https://github.com/localspook updated https://github.com/llvm/llvm-project/pull/149694
>From 823bfd458a0e03125d84fd676fbc284f09b50a5b Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Sat, 19 Jul 2025 23:43:55 -0700 Subject: [PATCH] [clang-tidy] Make `modernize-use-using`'s fixits more robust --- .../clang-tidy/modernize/UseUsingCheck.cpp | 194 ++++-------------- .../clang-tidy/modernize/UseUsingCheck.h | 10 +- clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checkers/modernize/use-using-macros.cpp | 5 - .../checkers/modernize/use-using.cpp | 100 +++++---- 5 files changed, 90 insertions(+), 223 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp index 936a906651f16..fc49d7b820109 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp @@ -7,14 +7,12 @@ //===----------------------------------------------------------------------===// #include "UseUsingCheck.h" -#include "../utils/LexerUtils.h" -#include "clang/AST/DeclGroup.h" +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TokenKinds.h" #include "clang/Lex/Lexer.h" -#include <string> using namespace clang::ast_matchers; namespace { @@ -22,15 +20,13 @@ namespace { AST_MATCHER(clang::LinkageSpecDecl, isExternCLinkage) { return Node.getLanguage() == clang::LinkageSpecLanguageIDs::C; } + } // namespace namespace clang::tidy::modernize { static constexpr llvm::StringLiteral ExternCDeclName = "extern-c-decl"; -static constexpr llvm::StringLiteral ParentDeclName = "parent-decl"; -static constexpr llvm::StringLiteral TagDeclName = "tag-decl"; static constexpr llvm::StringLiteral TypedefName = "typedef"; -static constexpr llvm::StringLiteral DeclStmtName = "decl-stmt"; UseUsingCheck::UseUsingCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), @@ -47,66 +43,14 @@ void UseUsingCheck::registerMatchers(MatchFinder *Finder) { typedefDecl( unless(isInstantiated()), optionally(hasAncestor( - linkageSpecDecl(isExternCLinkage()).bind(ExternCDeclName))), - anyOf(hasParent(decl().bind(ParentDeclName)), - hasParent(declStmt().bind(DeclStmtName)))) + linkageSpecDecl(isExternCLinkage()).bind(ExternCDeclName)))) .bind(TypedefName), this); - - // This matcher is used to find tag declarations in source code within - // typedefs. They appear in the AST just *prior* to the typedefs. - Finder->addMatcher( - tagDecl( - anyOf(allOf(unless(anyOf(isImplicit(), - classTemplateSpecializationDecl())), - anyOf(hasParent(decl().bind(ParentDeclName)), - hasParent(declStmt().bind(DeclStmtName)))), - // We want the parent of the ClassTemplateDecl, not the parent - // of the specialization. - classTemplateSpecializationDecl(hasAncestor(classTemplateDecl( - anyOf(hasParent(decl().bind(ParentDeclName)), - hasParent(declStmt().bind(DeclStmtName)))))))) - .bind(TagDeclName), - this); } void UseUsingCheck::check(const MatchFinder::MatchResult &Result) { - const auto *ParentDecl = Result.Nodes.getNodeAs<Decl>(ParentDeclName); - - if (!ParentDecl) { - const auto *ParentDeclStmt = Result.Nodes.getNodeAs<DeclStmt>(DeclStmtName); - if (ParentDeclStmt) { - if (ParentDeclStmt->isSingleDecl()) - ParentDecl = ParentDeclStmt->getSingleDecl(); - else - ParentDecl = - ParentDeclStmt->getDeclGroup().getDeclGroup() - [ParentDeclStmt->getDeclGroup().getDeclGroup().size() - 1]; - } - } - - if (!ParentDecl) - return; - - const SourceManager &SM = *Result.SourceManager; - const LangOptions &LO = getLangOpts(); - - // Match CXXRecordDecl only to store the range of the last non-implicit full - // declaration, to later check whether it's within the typdef itself. - const auto *MatchedTagDecl = Result.Nodes.getNodeAs<TagDecl>(TagDeclName); - if (MatchedTagDecl) { - // It is not sufficient to just track the last TagDecl that we've seen, - // because if one struct or union is nested inside another, the last TagDecl - // before the typedef will be the nested one (PR#50990). Therefore, we also - // keep track of the parent declaration, so that we can look up the last - // TagDecl that is a sibling of the typedef in the AST. - if (MatchedTagDecl->isThisDeclarationADefinition()) - LastTagDeclRanges[ParentDecl] = MatchedTagDecl->getSourceRange(); - return; - } - - const auto *MatchedDecl = Result.Nodes.getNodeAs<TypedefDecl>(TypedefName); - if (MatchedDecl->getLocation().isInvalid()) + const auto &MatchedDecl = *Result.Nodes.getNodeAs<TypedefDecl>(TypedefName); + if (MatchedDecl.getLocation().isInvalid()) return; const auto *ExternCDecl = @@ -114,116 +58,50 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) { if (ExternCDecl && IgnoreExternC) return; - SourceLocation StartLoc = MatchedDecl->getBeginLoc(); - - if (StartLoc.isMacroID() && IgnoreMacros) - return; - static constexpr llvm::StringLiteral UseUsingWarning = "use 'using' instead of 'typedef'"; - // Warn at StartLoc but do not fix if there is macro or array. - if (MatchedDecl->getUnderlyingType()->isArrayType() || StartLoc.isMacroID()) { - diag(StartLoc, UseUsingWarning); + if (MatchedDecl.getBeginLoc().isMacroID()) { + // Warn but do not fix if there is a macro. + if (!IgnoreMacros) + diag(MatchedDecl.getBeginLoc(), UseUsingWarning); return; } - const TypeLoc TL = MatchedDecl->getTypeSourceInfo()->getTypeLoc(); - - auto [Type, QualifierStr] = [MatchedDecl, this, &TL, &SM, - &LO]() -> std::pair<std::string, std::string> { - SourceRange TypeRange = TL.getSourceRange(); - - // Function pointer case, get the left and right side of the identifier - // without the identifier. - if (TypeRange.fullyContains(MatchedDecl->getLocation())) { - const auto RangeLeftOfIdentifier = CharSourceRange::getCharRange( - TypeRange.getBegin(), MatchedDecl->getLocation()); - const auto RangeRightOfIdentifier = CharSourceRange::getCharRange( - Lexer::getLocForEndOfToken(MatchedDecl->getLocation(), 0, SM, LO), - Lexer::getLocForEndOfToken(TypeRange.getEnd(), 0, SM, LO)); - const std::string VerbatimType = - (Lexer::getSourceText(RangeLeftOfIdentifier, SM, LO) + - Lexer::getSourceText(RangeRightOfIdentifier, SM, LO)) - .str(); - return {VerbatimType, ""}; - } - - StringRef ExtraReference = ""; - if (MainTypeEndLoc.isValid() && TypeRange.fullyContains(MainTypeEndLoc)) { - // Each type introduced in a typedef can specify being a reference or - // pointer type seperately, so we need to sigure out if the new using-decl - // needs to be to a reference or pointer as well. - const SourceLocation Tok = utils::lexer::findPreviousAnyTokenKind( - MatchedDecl->getLocation(), SM, LO, tok::TokenKind::star, - tok::TokenKind::amp, tok::TokenKind::comma, - tok::TokenKind::kw_typedef); - - ExtraReference = Lexer::getSourceText( - CharSourceRange::getCharRange(Tok, Tok.getLocWithOffset(1)), SM, LO); - - if (ExtraReference != "*" && ExtraReference != "&") - ExtraReference = ""; - - TypeRange.setEnd(MainTypeEndLoc); - } - return { - Lexer::getSourceText(CharSourceRange::getTokenRange(TypeRange), SM, LO) - .str(), - ExtraReference.str()}; - }(); - StringRef Name = MatchedDecl->getName(); - SourceRange ReplaceRange = MatchedDecl->getSourceRange(); + const SourceManager &SM = *Result.SourceManager; + const LangOptions &LO = getLangOpts(); // typedefs with multiple comma-separated definitions produce multiple // consecutive TypedefDecl nodes whose SourceRanges overlap. Each range starts // at the "typedef" and then continues *across* previous definitions through // the end of the current TypedefDecl definition. - // But also we need to check that the ranges belong to the same file because - // different files may contain overlapping ranges. - std::string Using = "using "; - if (ReplaceRange.getBegin().isMacroID() || - (Result.SourceManager->getFileID(ReplaceRange.getBegin()) != - Result.SourceManager->getFileID(LastReplacementEnd)) || - (ReplaceRange.getBegin() >= LastReplacementEnd)) { - // This is the first (and possibly the only) TypedefDecl in a typedef. Save - // Type and Name in case we find subsequent TypedefDecl's in this typedef. - FirstTypedefType = Type; - FirstTypedefName = Name.str(); - MainTypeEndLoc = TL.getEndLoc(); + const SourceRange RemovalRange = { + Lexer::findPreviousToken(MatchedDecl.getLocation(), SM, LO, + /*IncludeComments=*/true) + ->getEndLoc(), + Lexer::getLocForEndOfToken(MatchedDecl.getLocation(), 1, SM, LO)}; + if (NextTypedefStartsANewSequence) { + diag(MatchedDecl.getBeginLoc(), UseUsingWarning) + << FixItHint::CreateReplacement( + {MatchedDecl.getBeginLoc(), + Lexer::getLocForEndOfToken(MatchedDecl.getBeginLoc(), 0, SM, + LO)}, + ("using " + MatchedDecl.getName() + " =").str()) + << FixItHint::CreateRemoval(RemovalRange); + FirstTypedefName = MatchedDecl.getName(); } else { - // This is additional TypedefDecl in a comma-separated typedef declaration. - // Start replacement *after* prior replacement and separate with semicolon. - ReplaceRange.setBegin(LastReplacementEnd); - Using = ";\nusing "; - - // If this additional TypedefDecl's Type starts with the first TypedefDecl's - // type, make this using statement refer back to the first type, e.g. make - // "typedef int Foo, *Foo_p;" -> "using Foo = int;\nusing Foo_p = Foo*;" - if (Type == FirstTypedefType && !QualifierStr.empty()) - Type = FirstTypedefName; - } - - if (!ReplaceRange.getEnd().isMacroID()) { - const SourceLocation::IntTy Offset = - MatchedDecl->getFunctionType() ? 0 : Name.size(); - LastReplacementEnd = ReplaceRange.getEnd().getLocWithOffset(Offset); + diag(LastCommaOrSemi, UseUsingWarning) + << FixItHint::CreateReplacement( + LastCommaOrSemi, + (";\nusing " + MatchedDecl.getName() + " = " + FirstTypedefName) + .str()) + << FixItHint::CreateRemoval(RemovalRange); } - auto Diag = diag(ReplaceRange.getBegin(), UseUsingWarning); - - // If typedef contains a full tag declaration, extract its full text. - auto LastTagDeclRange = LastTagDeclRanges.find(ParentDecl); - if (LastTagDeclRange != LastTagDeclRanges.end() && - LastTagDeclRange->second.isValid() && - ReplaceRange.fullyContains(LastTagDeclRange->second)) { - Type = std::string(Lexer::getSourceText( - CharSourceRange::getTokenRange(LastTagDeclRange->second), SM, LO)); - if (Type.empty()) - return; - } - - std::string Replacement = (Using + Name + " = " + Type + QualifierStr).str(); - Diag << FixItHint::CreateReplacement(ReplaceRange, Replacement); + const Token CommaOrSemi = *Lexer::findNextToken( + MatchedDecl.getEndLoc(), SM, LO, /*IncludeComments=*/false); + NextTypedefStartsANewSequence = CommaOrSemi.isNot(tok::TokenKind::comma); + LastCommaOrSemi = CommaOrSemi.getLocation(); } + } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h index 1e54bbf23c984..2f113e3d9e076 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h @@ -18,15 +18,11 @@ namespace clang::tidy::modernize { /// For the user-facing documentation see: /// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-using.html class UseUsingCheck : public ClangTidyCheck { - const bool IgnoreMacros; const bool IgnoreExternC; - SourceLocation LastReplacementEnd; - llvm::DenseMap<const Decl *, SourceRange> LastTagDeclRanges; - - std::string FirstTypedefType; - std::string FirstTypedefName; - SourceLocation MainTypeEndLoc; + bool NextTypedefStartsANewSequence = true; + StringRef FirstTypedefName; + SourceLocation LastCommaOrSemi; public: UseUsingCheck(StringRef Name, ClangTidyContext *Context); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 07ebf8008928d..5bfdf8bf85686 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -102,6 +102,10 @@ New check aliases Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Improved :doc:`modernize-use-using + <clang-tidy/checks/modernize/use-using>` check by removing many incorrect + fixits and providing fixits where before there was only a warning. + Removed checks ^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using-macros.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using-macros.cpp index 092bc6666bb1c..c03cbc4d557fc 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using-macros.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using-macros.cpp @@ -9,11 +9,6 @@ CODE; // CHECK-FIXES: CODE; struct Foo; -#define Bar Baz -typedef Foo Bar; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' -// CHECK-FIXES: #define Bar Baz -// CHECK-FIXES: using Baz = Foo; #define TYPEDEF typedef TYPEDEF Foo Bak; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using.cpp index 8288f39126a11..09921f26ad911 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using.cpp @@ -1,9 +1,5 @@ // RUN: %check_clang_tidy %s modernize-use-using %t -- -- -fno-delayed-template-parsing -I %S/Inputs/use-using/ -typedef int Type; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using] -// CHECK-FIXES: using Type = int; - typedef long LL; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using LL = long; @@ -16,6 +12,18 @@ typedef Bla Bla2; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using Bla2 = Bla; +typedef const int ConstInt; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: using ConstInt = const int; + +typedef const int *const ConstPtrToConstInt; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: using ConstPtrToConstInt = const int *const; + +typedef struct foo_s {} * foo_t; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: using foo_t = struct foo_s {} *; + typedef void (*type)(int, int); // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using type = void (*)(int, int); @@ -87,8 +95,24 @@ typedef int bla1, bla2, bla3; // CHECK-MESSAGES: :[[@LINE-2]]:17: warning: use 'using' instead of 'typedef' // CHECK-MESSAGES: :[[@LINE-3]]:23: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using bla1 = int; -// CHECK-FIXES-NEXT: using bla2 = int; -// CHECK-FIXES-NEXT: using bla3 = int; +// CHECK-FIXES-NEXT: using bla2 = bla1; +// CHECK-FIXES-NEXT: using bla3 = bla1; + +typedef int I, &LVal, &&RVal, *Ptr, *const ConstPtr, Vec3[3], (*Fn)(); +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-MESSAGES: :[[@LINE-2]]:14: warning: use 'using' instead of 'typedef' +// CHECK-MESSAGES: :[[@LINE-3]]:21: warning: use 'using' instead of 'typedef' +// CHECK-MESSAGES: :[[@LINE-4]]:29: warning: use 'using' instead of 'typedef' +// CHECK-MESSAGES: :[[@LINE-5]]:35: warning: use 'using' instead of 'typedef' +// CHECK-MESSAGES: :[[@LINE-6]]:52: warning: use 'using' instead of 'typedef' +// CHECK-MESSAGES: :[[@LINE-7]]:61: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: using I = int; +// CHECK-FIXES-NEXT: using LVal = I &; +// CHECK-FIXES-NEXT: using RVal = I &&; +// CHECK-FIXES-NEXT: using Ptr = I *; +// CHECK-FIXES-NEXT: using ConstPtr = I *const; +// CHECK-FIXES-NEXT: using Vec3 = I[3]; +// CHECK-FIXES-NEXT: using Fn = I (*)(); #define CODE typedef int INT @@ -97,11 +121,6 @@ CODE; // CHECK-FIXES: CODE; struct Foo; -#define Bar Baz -typedef Foo Bar; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' -// CHECK-FIXES: #define Bar Baz -// CHECK-FIXES: using Baz = Foo; #define TYPEDEF typedef TYPEDEF Foo Bak; @@ -118,38 +137,16 @@ typedef struct Foo Bap; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using Bap = struct Foo; -struct Foo typedef Bap2; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' -// CHECK-FIXES: using Bap2 = struct Foo; - -Foo typedef Bap3; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' -// CHECK-FIXES: using Bap3 = Foo; - typedef struct Unknown Baq; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using Baq = struct Unknown; -struct Unknown2 typedef Baw; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' -// CHECK-FIXES: using Baw = struct Unknown2; - -int typedef Bax; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' -// CHECK-FIXES: using Bax = int; - typedef struct Q1 { int a; } S1; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using S1 = struct Q1 { int a; }; typedef struct { int b; } S2; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using S2 = struct { int b; }; -struct Q2 { int c; } typedef S3; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' -// CHECK-FIXES: using S3 = struct Q2 { int c; }; -struct { int d; } typedef S4; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' -// CHECK-FIXES: using S4 = struct { int d; }; namespace my_space { class my_cclass {}; @@ -158,14 +155,18 @@ namespace my_space { // CHECK-FIXES: using FuncType = my_cclass; } -#define lol 4 -typedef unsigned Map[lol]; +typedef int UnknownExtent[]; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' +// CHECK-FIXES: using UnknownExtent = int[]; + +typedef double Matrix3x3[3][3]; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' -// CHECK-FIXES: typedef unsigned Map[lol]; +// CHECK-FIXES: using Matrix3x3 = double[3][3]; -typedef void (*fun_type)(); +#define lol 4 +typedef unsigned Map[lol]; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' -// CHECK-FIXES: using fun_type = void (*)(); +// CHECK-FIXES: using Map = unsigned[lol]; namespace template_instantiations { template <typename T> @@ -202,13 +203,13 @@ typedef S<(0 > 0), int> S_t, *S_p; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using S_t = S<(0 > 0), int>; -// CHECK-FIXES-NEXT: using S_p = S_t*; +// CHECK-FIXES-NEXT: using S_p = S_t *; typedef S<(0 < 0), int> S2_t, *S2_p; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using S2_t = S<(0 < 0), int>; -// CHECK-FIXES-NEXT: using S2_p = S2_t*; +// CHECK-FIXES-NEXT: using S2_p = S2_t *; typedef S<(0 > 0 && (3 > 1) && (1 < 1)), int> S3_t; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' @@ -223,7 +224,7 @@ typedef Q<b[0 < 0]> Q_t, *Q_p; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using Q_t = Q<b[0 < 0]>; -// CHECK-FIXES-NEXT: using Q_p = Q_t*; +// CHECK-FIXES-NEXT: using Q_p = Q_t *; typedef Q<b[0 < 0]> Q2_t; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' @@ -239,7 +240,7 @@ typedef Q<T{0 < 0}.b> Q3_t, *Q3_p; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using Q3_t = Q<T{0 < 0}.b>; -// CHECK-FIXES-NEXT: using Q3_p = Q3_t*; +// CHECK-FIXES-NEXT: using Q3_p = Q3_t *; typedef Q<T{0 < 0}.b> Q3_t; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' @@ -271,13 +272,13 @@ typedef Variadic<Variadic<int, bool, Q<T{0 < 0}.b> >, S<(0 < 0), Variadic<Q<b[0 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-MESSAGES: :[[@LINE-2]]:103: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using Variadic_t = Variadic<Variadic<int, bool, Q<T{0 < 0}.b> >, S<(0 < 0), Variadic<Q<b[0 < 0]> > > >; -// CHECK-FIXES-NEXT: using Variadic_p = Variadic_t*; +// CHECK-FIXES-NEXT: using Variadic_p = Variadic_t *; typedef struct { int a; } R_t, *R_p; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-MESSAGES: :[[@LINE-2]]:30: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using R_t = struct { int a; }; -// CHECK-FIXES-NEXT: using R_p = R_t*; +// CHECK-FIXES-NEXT: using R_p = R_t *; typedef enum { ea1, eb1 } EnumT1; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' @@ -350,7 +351,6 @@ namespace ISSUE_72179 typedef int a; // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'using' instead of 'typedef' [modernize-use-using] // CHECK-FIXES: using a = int; - } void foo2() @@ -384,13 +384,6 @@ namespace ISSUE_72179 // CHECK-FIXES: const auto foo4 = [](int a){using d = int;}; } - -typedef int* int_ptr, *int_ptr_ptr; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using] -// CHECK-MESSAGES: :[[@LINE-2]]:21: warning: use 'using' instead of 'typedef' [modernize-use-using] -// CHECK-FIXES: using int_ptr = int*; -// CHECK-FIXES-NEXT: using int_ptr_ptr = int_ptr*; - #ifndef SpecialMode #define SomeMacro(x) x #else @@ -401,7 +394,7 @@ class SomeMacro(GH33760) { }; typedef void(SomeMacro(GH33760)::* FunctionType)(float, int); // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using] -// CHECK-FIXES: using FunctionType = void(SomeMacro(GH33760)::* )(float, int); +// CHECK-FIXES: using FunctionType = void(SomeMacro(GH33760)::*)(float, int); #define CDECL __attribute((cdecl)) @@ -433,6 +426,7 @@ typedef GH95716 foo; namespace GH97009 { typedef double PointType[3]; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef' [modernize-use-using] +// CHECK-FIXES: using PointType = double[3]; typedef bool (*Function)(PointType, PointType); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef' [modernize-use-using] // CHECK-FIXES: using Function = bool (*)(PointType, PointType); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits