Index: clang-tidy/misc/SwappedArgumentsCheck.cpp =================================================================== --- clang-tidy/misc/SwappedArgumentsCheck.cpp +++ clang-tidy/misc/SwappedArgumentsCheck.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ASTContext.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/SmallPtrSet.h" +#include "../utils/FixItHintUtils.h" using namespace clang::ast_matchers; @@ -46,25 +47,9 @@ Cast->getCastKind() == CK_PointerToBoolean; } -/// \brief Get a StringRef representing a SourceRange. -static StringRef getAsString(const MatchFinder::MatchResult &Result, - SourceRange R) { - const SourceManager &SM = *Result.SourceManager; - // Don't even try to resolve macro or include contraptions. Not worth emitting - // a fixit for. - if (R.getBegin().isMacroID() || - !SM.isWrittenInSameFile(R.getBegin(), R.getEnd())) - return StringRef(); - - const char *Begin = SM.getCharacterData(R.getBegin()); - const char *End = SM.getCharacterData(Lexer::getLocForEndOfToken( - R.getEnd(), 0, SM, Result.Context->getLangOpts())); - - return StringRef(Begin, End - Begin); -} - -void SwappedArgumentsCheck::check(const MatchFinder::MatchResult &Result) { - auto *Call = Result.Nodes.getStmtAs("call"); +void SwappedArgumentsCheck::check(const MatchFinder::MatchResult &Result) {\ + const ASTContext &Ctx = *Result.Context; + const auto *Call = Result.Nodes.getStmtAs("call"); llvm::SmallPtrSet UsedArgs; for (unsigned I = 1, E = Call->getNumArgs(); I < E; ++I) { @@ -99,23 +84,13 @@ continue; // Emit a warning and fix-its that swap the arguments. - SourceRange LHSRange = LHS->getSourceRange(), - RHSRange = RHS->getSourceRange(); - auto D = - diag(Call->getLocStart(), "argument with implicit conversion from %0 " + diag(Call->getLocStart(), "argument with implicit conversion from %0 " "to %1 followed by argument converted from " "%2 to %3, potentially swapped arguments.") << LHS->getType() << LHSFrom->getType() << RHS->getType() - << RHSFrom->getType() << LHSRange << RHSRange; - - StringRef RHSString = getAsString(Result, RHSRange); - StringRef LHSString = getAsString(Result, LHSRange); - if (!LHSString.empty() && !RHSString.empty()) { - D << FixItHint::CreateReplacement( - CharSourceRange::getTokenRange(LHSRange), RHSString) - << FixItHint::CreateReplacement( - CharSourceRange::getTokenRange(RHSRange), LHSString); - } + << RHSFrom->getType() + << utils::fixit::CreateReplacement(*LHS, *RHS, Ctx) + << utils::fixit::CreateReplacement(*RHS, *LHS, Ctx); // Remember that we emitted a warning for this argument. UsedArgs.insert(RHSCast); Index: clang-tidy/performance/ForRangeCopyCheck.cpp =================================================================== --- clang-tidy/performance/ForRangeCopyCheck.cpp +++ clang-tidy/performance/ForRangeCopyCheck.cpp @@ -66,9 +66,9 @@ diag(LoopVar.getLocation(), "the loop variable's type is not a reference type; this creates a " "copy in each iteration; consider making this a reference") - << utils::create_fix_it::changeVarDeclToReference(LoopVar, Context); + << utils::fixit::changeVarDeclToReference(LoopVar, Context); if (!LoopVar.getType().isConstQualified()) - Diagnostic << utils::create_fix_it::changeVarDeclToConst(LoopVar); + Diagnostic << utils::fixit::changeVarDeclToConst(LoopVar); return true; } @@ -84,8 +84,8 @@ diag(LoopVar.getLocation(), "loop variable is copied but only used as const reference; consider " "making it a const reference") - << utils::create_fix_it::changeVarDeclToConst(LoopVar) - << utils::create_fix_it::changeVarDeclToReference(LoopVar, Context); + << utils::fixit::changeVarDeclToConst(LoopVar) + << utils::fixit::changeVarDeclToReference(LoopVar, Context); return true; } Index: clang-tidy/performance/UnnecessaryCopyInitialization.cpp =================================================================== --- clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -24,9 +24,9 @@ if (Var.getLocation().isMacroID()) return; - Diagnostic << utils::create_fix_it::changeVarDeclToReference(Var, Context); + Diagnostic << utils::fixit::changeVarDeclToReference(Var, Context); if (!Var.getType().isLocalConstQualified()) - Diagnostic << utils::create_fix_it::changeVarDeclToConst(Var); + Diagnostic << utils::fixit::changeVarDeclToConst(Var); } } // namespace Index: clang-tidy/performance/UnnecessaryValueParamCheck.cpp =================================================================== --- clang-tidy/performance/UnnecessaryValueParamCheck.cpp +++ clang-tidy/performance/UnnecessaryValueParamCheck.cpp @@ -79,10 +79,10 @@ for (const auto *FunctionDecl = Function; FunctionDecl != nullptr; FunctionDecl = FunctionDecl->getPreviousDecl()) { const auto &CurrentParam = *FunctionDecl->getParamDecl(Index); - Diag << utils::create_fix_it::changeVarDeclToReference(CurrentParam, - *Result.Context); + Diag << utils::fixit::changeVarDeclToReference(CurrentParam, + *Result.Context); if (!IsConstQualified) - Diag << utils::create_fix_it::changeVarDeclToConst(CurrentParam); + Diag << utils::fixit::changeVarDeclToConst(CurrentParam); } } Index: clang-tidy/utils/FixItHintUtils.h =================================================================== --- clang-tidy/utils/FixItHintUtils.h +++ clang-tidy/utils/FixItHintUtils.h @@ -16,7 +16,36 @@ namespace clang { namespace tidy { namespace utils { -namespace create_fix_it { +namespace fixit { + +inline SourceRange getSourceRange(const SourceRange &Range) { + return Range; +} + +template +SourceRange getSourceRange(const T &Node) { + return Node.getSourceRange(); +} + +StringRef getText(SourceRange Range, const ASTContext &Context); + +template +StringRef getText(const T& Node, const ASTContext& Context) { + return getText(getSourceRange(Node), Context); +} + +template +FixItHint CreateRemoval(const T& Node) { + return FixItHint::CreateRemoval(getSourceRange(Node)); +} + +template +FixItHint CreateReplacement(const D &Destination, const S &Source, + const ASTContext &Context) { + return FixItHint::CreateReplacement( + getSourceRange(Destination), + getText(Source, Context)); +} /// \brief Creates fix to make VarDecl a reference by adding '&'. FixItHint changeVarDeclToReference(const VarDecl &Var, ASTContext &Context); Index: clang-tidy/utils/FixItHintUtils.cpp =================================================================== --- clang-tidy/utils/FixItHintUtils.cpp +++ clang-tidy/utils/FixItHintUtils.cpp @@ -10,11 +10,19 @@ #include "FixItHintUtils.h" #include "LexerUtils.h" #include "clang/AST/ASTContext.h" +#include "clang/Lex/Lexer.h" namespace clang { namespace tidy { namespace utils { -namespace create_fix_it { +namespace fixit { + +StringRef getText(SourceRange Range, const ASTContext &Context) { + return + Lexer::getSourceText( + CharSourceRange::getTokenRange(Range), + Context.getSourceManager(), Context.getLangOpts()); +} FixItHint changeVarDeclToReference(const VarDecl &Var, ASTContext &Context) { SourceLocation AmpLocation = Var.getLocation();