xref: /llvm-project/clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp (revision 7d2ea6c422d3f5712b7253407005e1a465a76946)
15625f656SPiotr Padlewski //===--- UseToStringCheck.cpp - clang-tidy---------------------------------===//
25625f656SPiotr Padlewski //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65625f656SPiotr Padlewski //
75625f656SPiotr Padlewski //===----------------------------------------------------------------------===//
85625f656SPiotr Padlewski 
95625f656SPiotr Padlewski #include "UseToStringCheck.h"
105625f656SPiotr Padlewski 
115625f656SPiotr Padlewski using namespace clang::ast_matchers;
125625f656SPiotr Padlewski 
13*7d2ea6c4SCarlos Galvez namespace clang::tidy::boost {
145625f656SPiotr Padlewski 
15f8c99297SBenjamin Kramer namespace {
AST_MATCHER(Type,isStrictlyInteger)165625f656SPiotr Padlewski AST_MATCHER(Type, isStrictlyInteger) {
175625f656SPiotr Padlewski   return Node.isIntegerType() && !Node.isAnyCharacterType() &&
185625f656SPiotr Padlewski          !Node.isBooleanType();
195625f656SPiotr Padlewski }
20f8c99297SBenjamin Kramer } // namespace
215625f656SPiotr Padlewski 
registerMatchers(MatchFinder * Finder)225625f656SPiotr Padlewski void UseToStringCheck::registerMatchers(MatchFinder *Finder) {
235625f656SPiotr Padlewski   Finder->addMatcher(
245625f656SPiotr Padlewski       callExpr(
255625f656SPiotr Padlewski           hasDeclaration(functionDecl(
265625f656SPiotr Padlewski               returns(hasDeclaration(classTemplateSpecializationDecl(
275625f656SPiotr Padlewski                   hasName("std::basic_string"),
285625f656SPiotr Padlewski                   hasTemplateArgument(0,
295625f656SPiotr Padlewski                                       templateArgument().bind("char_type"))))),
305625f656SPiotr Padlewski               hasName("boost::lexical_cast"),
315625f656SPiotr Padlewski               hasParameter(0, hasType(qualType(has(substTemplateTypeParmType(
325625f656SPiotr Padlewski                                   isStrictlyInteger()))))))),
335625f656SPiotr Padlewski           argumentCountIs(1), unless(isInTemplateInstantiation()))
345625f656SPiotr Padlewski           .bind("to_string"),
355625f656SPiotr Padlewski       this);
365625f656SPiotr Padlewski }
375625f656SPiotr Padlewski 
check(const MatchFinder::MatchResult & Result)385625f656SPiotr Padlewski void UseToStringCheck::check(const MatchFinder::MatchResult &Result) {
395625f656SPiotr Padlewski   const auto *Call = Result.Nodes.getNodeAs<CallExpr>("to_string");
405625f656SPiotr Padlewski   auto CharType =
415625f656SPiotr Padlewski       Result.Nodes.getNodeAs<TemplateArgument>("char_type")->getAsType();
425625f656SPiotr Padlewski 
435625f656SPiotr Padlewski   StringRef StringType;
445625f656SPiotr Padlewski   if (CharType->isSpecificBuiltinType(BuiltinType::Char_S) ||
455625f656SPiotr Padlewski       CharType->isSpecificBuiltinType(BuiltinType::Char_U))
465625f656SPiotr Padlewski     StringType = "string";
475625f656SPiotr Padlewski   else if (CharType->isSpecificBuiltinType(BuiltinType::WChar_S) ||
485625f656SPiotr Padlewski            CharType->isSpecificBuiltinType(BuiltinType::WChar_U))
495625f656SPiotr Padlewski     StringType = "wstring";
505625f656SPiotr Padlewski   else
515625f656SPiotr Padlewski     return;
525625f656SPiotr Padlewski 
5343465bf3SStephen Kelly   auto Loc = Call->getBeginLoc();
545625f656SPiotr Padlewski   auto Diag =
555625f656SPiotr Padlewski       diag(Loc, "use std::to_%0 instead of boost::lexical_cast<std::%0>")
565625f656SPiotr Padlewski       << StringType;
575625f656SPiotr Padlewski 
585625f656SPiotr Padlewski   if (Loc.isMacroID())
595625f656SPiotr Padlewski     return;
605625f656SPiotr Padlewski 
615625f656SPiotr Padlewski   Diag << FixItHint::CreateReplacement(
6243465bf3SStephen Kelly       CharSourceRange::getCharRange(Call->getBeginLoc(),
6343465bf3SStephen Kelly                                     Call->getArg(0)->getBeginLoc()),
645625f656SPiotr Padlewski       (llvm::Twine("std::to_") + StringType + "(").str());
655625f656SPiotr Padlewski }
665625f656SPiotr Padlewski 
67*7d2ea6c4SCarlos Galvez } // namespace clang::tidy::boost
68