| //===--- FblMoveCheck.cpp - clang-tidy ------------------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "FblMoveCheck.h" |
| #include "clang/AST/ASTContext.h" |
| #include "clang/ASTMatchers/ASTMatchFinder.h" |
| #include "clang/Frontend/CompilerInstance.h" |
| #include "clang/Lex/Lexer.h" |
| #include "llvm/ADT/Optional.h" |
| |
| using namespace clang::ast_matchers; |
| |
| namespace clang { |
| namespace tidy { |
| namespace zircon { |
| |
| void FblMoveCheck::registerMatchers(MatchFinder *Finder) { |
| Finder->addMatcher( |
| callExpr(callee(functionDecl( |
| allOf(hasDeclContext(namespaceDecl(hasName("::fbl"))), |
| hasName("move"))))) |
| .bind("call"), |
| this); |
| |
| Finder->addMatcher( |
| callExpr(callee(functionDecl( |
| allOf(hasDeclContext(namespaceDecl(hasName("::fbl"))), |
| hasName("forward"))))) |
| .bind("call"), |
| this); |
| } |
| |
| void FblMoveCheck::registerPPCallbacks(CompilerInstance &Compiler) { |
| Inserter = llvm::make_unique<utils::IncludeInserter>( |
| Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle); |
| Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks()); |
| } |
| |
| void FblMoveCheck::check(const MatchFinder::MatchResult &Result) { |
| |
| const auto *E = Result.Nodes.getNodeAs<CallExpr>("call"); |
| std::string Name = E->getDirectCallee()->getNameAsString(); |
| |
| // Find the end of the name of the call. |
| SourceManager &SM = *Result.SourceManager; |
| SourceLocation Start = E->getBeginLoc(); |
| SourceLocation End = E->getEndLoc(); |
| |
| // If it's a macro, we want to extract information about the macro instead of |
| // the expr. |
| if (Start.isMacroID()) { |
| Start = SM.getSpellingLoc(Start); |
| End = SM.getSpellingLoc(End); |
| } |
| |
| bool Invalid = false; |
| StringRef Statement = Lexer::getSourceText( |
| CharSourceRange::getCharRange(Start, End), SM, getLangOpts(), &Invalid); |
| if (Invalid) |
| return; |
| |
| // Find the template bracket, or find the lparen if the bracket isn't there. |
| size_t LParen = Statement.find('<'); |
| if (LParen == std::string::npos) |
| LParen = Statement.find('('); |
| if (LParen == std::string::npos) |
| // If there isn't an lparen, we want the whole statement. |
| End = Start.getLocWithOffset(Statement.size()); |
| else |
| // Remove the lparen from the size range, since we just want the call. |
| End = Start.getLocWithOffset(LParen - 1); |
| |
| DiagnosticBuilder Diag = |
| diag(Start, "fbl::%0 is deprecated, use std::%1 instead") |
| << Name << Name |
| << FixItHint::CreateReplacement(SourceRange(Start, End), "std::" + Name); |
| |
| // Add in the <utility> header. |
| if (llvm::Optional<FixItHint> IncludeFixit = |
| Inserter->CreateIncludeInsertion(SM.getFileID(Start), "utility", |
| /*IsAngled=*/true)) { |
| Diag << *IncludeFixit; |
| } |
| } |
| |
| void FblMoveCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { |
| Options.store(Opts, "IncludeStyle", IncludeStyle); |
| } |
| |
| } // namespace zircon |
| } // namespace tidy |
| } // namespace clang |