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 namespace { 19 AST_MATCHER(Type, isStrictlyInteger) { 20 return Node.isIntegerType() && !Node.isAnyCharacterType() && 21 !Node.isBooleanType(); 22 } 23 } // namespace 24 25 void UseToStringCheck::registerMatchers(MatchFinder *Finder) { 26 if (!getLangOpts().CPlusPlus) 27 return; 28 29 Finder->addMatcher( 30 callExpr( 31 hasDeclaration(functionDecl( 32 returns(hasDeclaration(classTemplateSpecializationDecl( 33 hasName("std::basic_string"), 34 hasTemplateArgument(0, 35 templateArgument().bind("char_type"))))), 36 hasName("boost::lexical_cast"), 37 hasParameter(0, hasType(qualType(has(substTemplateTypeParmType( 38 isStrictlyInteger()))))))), 39 argumentCountIs(1), unless(isInTemplateInstantiation())) 40 .bind("to_string"), 41 this); 42 } 43 44 void UseToStringCheck::check(const MatchFinder::MatchResult &Result) { 45 const auto *Call = Result.Nodes.getNodeAs<CallExpr>("to_string"); 46 auto CharType = 47 Result.Nodes.getNodeAs<TemplateArgument>("char_type")->getAsType(); 48 49 StringRef StringType; 50 if (CharType->isSpecificBuiltinType(BuiltinType::Char_S) || 51 CharType->isSpecificBuiltinType(BuiltinType::Char_U)) 52 StringType = "string"; 53 else if (CharType->isSpecificBuiltinType(BuiltinType::WChar_S) || 54 CharType->isSpecificBuiltinType(BuiltinType::WChar_U)) 55 StringType = "wstring"; 56 else 57 return; 58 59 auto Loc = Call->getLocStart(); 60 auto Diag = 61 diag(Loc, "use std::to_%0 instead of boost::lexical_cast<std::%0>") 62 << StringType; 63 64 if (Loc.isMacroID()) 65 return; 66 67 Diag << FixItHint::CreateReplacement( 68 CharSourceRange::getCharRange(Call->getLocStart(), 69 Call->getArg(0)->getLocStart()), 70 (llvm::Twine("std::to_") + StringType + "(").str()); 71 } 72 73 } // namespace boost 74 } // namespace tidy 75 } // namespace clang 76