diff options
author | Mitchell Balan <mitchell@stellarscience.com> | 2019-11-15 14:30:41 -0500 |
---|---|---|
committer | Mitchell Balan <mitchell@stellarscience.com> | 2019-11-15 16:09:10 -0500 |
commit | 782392db8122cafb5e0e4ad5fe0c24c46f11b2b7 (patch) | |
tree | c2c6a97f0751be9826f468ea388dffe192da165d /clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp | |
parent | 9c1baa23526c6d7d06eafefbf82d73bfe9bb3aaf (diff) | |
download | bcm5719-llvm-782392db8122cafb5e0e4ad5fe0c24c46f11b2b7.tar.gz bcm5719-llvm-782392db8122cafb5e0e4ad5fe0c24c46f11b2b7.zip |
[clang-tidy] modernize-use-using work with multi-argument templates
Summary:
If clang-tidy's modernize-use-using feature finds any commas that are not within parentheses, it won't create a fix. That means it won't change lines like:
typedef std::pair<int, int> Point;
to
using Point = std::pair<int, int>;
or even:
typedef std::map<std::string, Foo> MyMap;
typedef std::vector<int,MyCustomAllocator<int>> MyVector;
This patch allows the fix to apply to lines with commas if they are within parentheses or angle brackets that were not themselves within parentheses.
Reviewers: alexfh, hokein, aaron.ballman
Patch by: poelmanc
Subscribers: jonathanmeier, cfe-commits
Tags: #clang, #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D67460
Diffstat (limited to 'clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp')
-rw-r--r-- | clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp index bd234623d9e..c9ca8a6114a 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp @@ -39,25 +39,46 @@ static bool CheckRemoval(SourceManager &SM, SourceLocation StartLoc, File.begin(), TokenBegin, File.end()); Token Tok; - int ParenLevel = 0; + int NestingLevel = 0; // Parens, braces, and square brackets + int AngleBracketLevel = 0; bool FoundTypedef = false; while (!DeclLexer.LexFromRawLexer(Tok) && !Tok.is(tok::semi)) { switch (Tok.getKind()) { case tok::l_brace: - case tok::r_brace: - // This might be the `typedef struct {...} T;` case. - return false; + if (NestingLevel == 0 && AngleBracketLevel == 0) { + // At top level, this might be the `typedef struct {...} T;` case. + // Inside parens, square brackets, or angle brackets it's not. + return false; + } + ++NestingLevel; + break; case tok::l_paren: - ParenLevel++; + case tok::l_square: + ++NestingLevel; break; + case tok::r_brace: case tok::r_paren: - ParenLevel--; + case tok::r_square: + --NestingLevel; + break; + case tok::less: + // If not nested in paren/brace/square bracket, treat as opening angle bracket. + if (NestingLevel == 0) + ++AngleBracketLevel; + break; + case tok::greater: + // Per C++ 17 Draft N4659, Section 17.2/3 + // https://timsong-cpp.github.io/cppwp/n4659/temp.names#3: + // "When parsing a template-argument-list, the first non-nested > is + // taken as the ending delimiter rather than a greater-than operator." + // If not nested in paren/brace/square bracket, treat as closing angle bracket. + if (NestingLevel == 0) + --AngleBracketLevel; break; case tok::comma: - if (ParenLevel == 0) { - // If there is comma and we are not between open parenthesis then it is - // two or more declarations in this chain. + if (NestingLevel == 0 && AngleBracketLevel == 0) { + // If there is a non-nested comma we have two or more declarations in this chain. return false; } break; @@ -88,8 +109,7 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) { if (StartLoc.isMacroID() && IgnoreMacros) return; - auto Diag = - diag(StartLoc, "use 'using' instead of 'typedef'"); + auto Diag = diag(StartLoc, "use 'using' instead of 'typedef'"); // do not fix if there is macro or array if (MatchedDecl->getUnderlyingType()->isArrayType() || StartLoc.isMacroID()) |