1 //===--- UseToStringCheck.cpp - clang-tidy---------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "UseToStringCheck.h" 11 12 using namespace clang::ast_matchers; 13 14 namespace clang { 15 namespace tidy { 16 namespace boost { 17 18 AST_MATCHER(Type, isStrictlyInteger) { 19 return Node.isIntegerType() && !Node.isAnyCharacterType() && 20 !Node.isBooleanType(); 21 } 22 23 void UseToStringCheck::registerMatchers(MatchFinder *Finder) { 24 if (!getLangOpts().CPlusPlus) 25 return; 26 27 Finder->addMatcher( 28 callExpr( 29 hasDeclaration(functionDecl( 30 returns(hasDeclaration(classTemplateSpecializationDecl( 31 hasName("std::basic_string"), 32 hasTemplateArgument(0, 33 templateArgument().bind("char_type"))))), 34 hasName("boost::lexical_cast"), 35 hasParameter(0, hasType(qualType(has(substTemplateTypeParmType( 36 isStrictlyInteger()))))))), 37 argumentCountIs(1), unless(isInTemplateInstantiation())) 38 .bind("to_string"), 39 this); 40 } 41 42 void UseToStringCheck::check(const MatchFinder::MatchResult &Result) { 43 const auto *Call = Result.Nodes.getNodeAs<CallExpr>("to_string"); 44 auto CharType = 45 Result.Nodes.getNodeAs<TemplateArgument>("char_type")->getAsType(); 46 47 StringRef StringType; 48 if (CharType->isSpecificBuiltinType(BuiltinType::Char_S) || 49 CharType->isSpecificBuiltinType(BuiltinType::Char_U)) 50 StringType = "string"; 51 else if (CharType->isSpecificBuiltinType(BuiltinType::WChar_S) || 52 CharType->isSpecificBuiltinType(BuiltinType::WChar_U)) 53 StringType = "wstring"; 54 else 55 return; 56 57 auto Loc = Call->getLocStart(); 58 auto Diag = 59 diag(Loc, "use std::to_%0 instead of boost::lexical_cast<std::%0>") 60 << StringType; 61 62 if (Loc.isMacroID()) 63 return; 64 65 Diag << FixItHint::CreateReplacement( 66 CharSourceRange::getCharRange(Call->getLocStart(), 67 Call->getArg(0)->getExprLoc()), 68 (llvm::Twine("std::to_") + StringType + "(").str()); 69 } 70 71 } // namespace boost 72 } // namespace tidy 73 } // namespace clang 74