UseToStringCheck.cpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. //===--- UseToStringCheck.cpp - clang-tidy---------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "UseToStringCheck.h"
  9. using namespace clang::ast_matchers;
  10. namespace clang::tidy::boost {
  11. namespace {
  12. AST_MATCHER(Type, isStrictlyInteger) {
  13. return Node.isIntegerType() && !Node.isAnyCharacterType() &&
  14. !Node.isBooleanType();
  15. }
  16. } // namespace
  17. void UseToStringCheck::registerMatchers(MatchFinder *Finder) {
  18. Finder->addMatcher(
  19. callExpr(
  20. hasDeclaration(functionDecl(
  21. returns(hasDeclaration(classTemplateSpecializationDecl(
  22. hasName("std::basic_string"),
  23. hasTemplateArgument(0,
  24. templateArgument().bind("char_type"))))),
  25. hasName("boost::lexical_cast"),
  26. hasParameter(0, hasType(qualType(has(substTemplateTypeParmType(
  27. isStrictlyInteger()))))))),
  28. argumentCountIs(1), unless(isInTemplateInstantiation()))
  29. .bind("to_string"),
  30. this);
  31. }
  32. void UseToStringCheck::check(const MatchFinder::MatchResult &Result) {
  33. const auto *Call = Result.Nodes.getNodeAs<CallExpr>("to_string");
  34. auto CharType =
  35. Result.Nodes.getNodeAs<TemplateArgument>("char_type")->getAsType();
  36. StringRef StringType;
  37. if (CharType->isSpecificBuiltinType(BuiltinType::Char_S) ||
  38. CharType->isSpecificBuiltinType(BuiltinType::Char_U))
  39. StringType = "string";
  40. else if (CharType->isSpecificBuiltinType(BuiltinType::WChar_S) ||
  41. CharType->isSpecificBuiltinType(BuiltinType::WChar_U))
  42. StringType = "wstring";
  43. else
  44. return;
  45. auto Loc = Call->getBeginLoc();
  46. auto Diag =
  47. diag(Loc, "use std::to_%0 instead of boost::lexical_cast<std::%0>")
  48. << StringType;
  49. if (Loc.isMacroID())
  50. return;
  51. Diag << FixItHint::CreateReplacement(
  52. CharSourceRange::getCharRange(Call->getBeginLoc(),
  53. Call->getArg(0)->getBeginLoc()),
  54. (llvm::Twine("std::to_") + StringType + "(").str());
  55. }
  56. } // namespace clang::tidy::boost