diff options
Diffstat (limited to 'clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp')
-rw-r--r-- | clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp index 55a518c1aec..de525926c89 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp @@ -25,9 +25,10 @@ void UseUsingCheck::registerMatchers(MatchFinder *Finder) { // Checks if 'typedef' keyword can be removed - we do it only if // it is the only declaration in a declaration chain. -static bool CheckRemoval(SourceManager &SM, const SourceLocation &LocStart, - const SourceLocation &LocEnd, ASTContext &Context) { - std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(LocStart); +static bool CheckRemoval(SourceManager &SM, SourceLocation StartLoc, + ASTContext &Context) { + assert(StartLoc.isFileID() && "StartLoc must not be in a macro"); + std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(StartLoc); StringRef File = SM.getBufferData(LocInfo.first); const char *TokenBegin = File.data() + LocInfo.second; Lexer DeclLexer(SM.getLocForStartOfFile(LocInfo.first), Context.getLangOpts(), @@ -35,28 +36,39 @@ static bool CheckRemoval(SourceManager &SM, const SourceLocation &LocStart, Token Tok; int ParenLevel = 0; + bool FoundTypedef = false; - while (!DeclLexer.LexFromRawLexer(Tok)) { - if (SM.isBeforeInTranslationUnit(LocEnd, Tok.getLocation())) - break; - if (Tok.getKind() == tok::TokenKind::l_paren) + 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; + case tok::l_paren: ParenLevel++; - if (Tok.getKind() == tok::TokenKind::r_paren) + break; + case tok::r_paren: ParenLevel--; - if (Tok.getKind() == tok::TokenKind::semi) break; - // if there is comma and we are not between open parenthesis then it is - // two or more declatarions in this chain - if (ParenLevel == 0 && Tok.getKind() == tok::TokenKind::comma) - return false; - - if (Tok.is(tok::TokenKind::raw_identifier)) { - if (Tok.getRawIdentifier() == "typedef") - return true; + 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. + return false; + } + break; + case tok::raw_identifier: + if (Tok.getRawIdentifier() == "typedef") { + FoundTypedef = true; + } + break; + default: + break; } } - return false; + // Sanity check against weird macro cases. + return FoundTypedef; } void UseUsingCheck::check(const MatchFinder::MatchResult &Result) { @@ -67,14 +79,19 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) { auto &Context = *Result.Context; auto &SM = *Result.SourceManager; + if (auto *D = MatchedDecl->getUnderlyingType()->getAsCXXRecordDecl()) { + //TypeLoc TL = MatchedDecl->getTypeSourceInfo()->getTypeLoc(); + llvm::errs() << D->getNameAsString() << "\n"; + } + auto Diag = diag(MatchedDecl->getLocStart(), "use 'using' instead of 'typedef'"); - if (MatchedDecl->getLocStart().isMacroID()) + SourceLocation StartLoc = MatchedDecl->getLocStart(); + if (StartLoc.isMacroID()) return; - if (CheckRemoval(SM, MatchedDecl->getLocStart(), MatchedDecl->getLocEnd(), - Context)) { + if (CheckRemoval(SM, StartLoc, Context)) { Diag << FixItHint::CreateReplacement( MatchedDecl->getSourceRange(), "using " + MatchedDecl->getNameAsString() + " = " + |