11 #include "../utils/LexerUtils.h"
13 using namespace clang::ast_matchers;
19 void UseUsingCheck::registerMatchers(MatchFinder *
Finder) {
20 if (!getLangOpts().CPlusPlus11)
22 Finder->addMatcher(typedefDecl().bind(
"typedef"),
this);
28 const SourceLocation &LocEnd, ASTContext &
Context,
29 SourceRange &ResultRange) {
30 FileID FID = SM.getFileID(LocEnd);
31 llvm::MemoryBuffer *Buffer = SM.getBuffer(FID, LocEnd);
32 Lexer DeclLexer(SM.getLocForStartOfFile(FID), Context.getLangOpts(),
33 Buffer->getBufferStart(), SM.getCharacterData(LocStart),
34 Buffer->getBufferEnd());
37 int parenthesisLevel = 0;
39 while (!DeclLexer.LexFromRawLexer(DeclToken)) {
40 if (DeclToken.getKind() == tok::TokenKind::l_paren)
42 if (DeclToken.getKind() == tok::TokenKind::r_paren)
44 if (DeclToken.getKind() == tok::TokenKind::semi)
48 if (parenthesisLevel == 0 && DeclToken.getKind() == tok::TokenKind::comma)
51 if (DeclToken.isOneOf(tok::TokenKind::identifier,
52 tok::TokenKind::raw_identifier)) {
53 auto TokenStr = DeclToken.getRawIdentifier().str();
55 if (TokenStr ==
"typedef") {
57 SourceRange(DeclToken.getLocation(), DeclToken.getEndLoc());
63 assert(result &&
"No typedef found");
68 void UseUsingCheck::check(
const MatchFinder::MatchResult &
Result) {
69 const auto *MatchedDecl = Result.Nodes.getNodeAs<TypedefDecl>(
"typedef");
70 if (MatchedDecl->getLocation().isInvalid())
73 auto &
Context = *Result.Context;
74 auto &
SM = *Result.SourceManager;
77 diag(MatchedDecl->getLocStart(),
"use 'using' instead of 'typedef'");
78 if (MatchedDecl->getLocStart().isMacroID()) {
81 SourceRange RemovalRange;
82 if (
CheckRemoval(
SM, MatchedDecl->getLocStart(), MatchedDecl->getLocEnd(),
84 Diag << FixItHint::CreateReplacement(
85 MatchedDecl->getSourceRange(),
86 "using " + MatchedDecl->getNameAsString() +
" = " +
87 MatchedDecl->getUnderlyingType().getAsString(getLangOpts()));
std::unique_ptr< ast_matchers::MatchFinder > Finder
ClangTidyContext & Context
static bool CheckRemoval(SourceManager &SM, const SourceLocation &LocStart, const SourceLocation &LocEnd, ASTContext &Context, SourceRange &ResultRange)