Skip to content

Commit

Permalink
[clang-tidy] Suggest including <cmath> if necessary in type-promotion…
Browse files Browse the repository at this point in the history
…-in-math-fn-check.

Reviewers: alexfh

Subscribers: JDevlieghere, cfe-commits

Differential Revision: https://reviews.llvm.org/D27748

llvm-svn: 289637
  • Loading branch information
Justin Lebar committed Dec 14, 2016
1 parent 268b3ab commit 2edf6f1
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 10 deletions.
Expand Up @@ -10,6 +10,8 @@
#include "TypePromotionInMathFnCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/StringSet.h"

using namespace clang::ast_matchers;
Expand All @@ -27,6 +29,26 @@ AST_MATCHER_P(Type, isBuiltinType, BuiltinType::Kind, Kind) {
}
} // anonymous namespace

TypePromotionInMathFnCheck::TypePromotionInMathFnCheck(
StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
IncludeStyle(utils::IncludeSorter::parseIncludeStyle(
Options.get("IncludeStyle", "llvm"))) {}

void TypePromotionInMathFnCheck::registerPPCallbacks(
CompilerInstance &Compiler) {
IncludeInserter = llvm::make_unique<utils::IncludeInserter>(
Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle);
Compiler.getPreprocessor().addPPCallbacks(
IncludeInserter->CreatePPCallbacks());
}

void TypePromotionInMathFnCheck::storeOptions(
ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle",
utils::IncludeSorter::toString(IncludeStyle));
}

void TypePromotionInMathFnCheck::registerMatchers(MatchFinder *Finder) {
constexpr BuiltinType::Kind IntTy = BuiltinType::Int;
constexpr BuiltinType::Kind LongTy = BuiltinType::Long;
Expand Down Expand Up @@ -153,18 +175,29 @@ void TypePromotionInMathFnCheck::check(const MatchFinder::MatchResult &Result) {
bool StdFnRequiresCpp11 = Cpp11OnlyFns.count(OldFnName);

std::string NewFnName;
bool FnInCmath = false;
if (getLangOpts().CPlusPlus &&
(!StdFnRequiresCpp11 || getLangOpts().CPlusPlus11))
(!StdFnRequiresCpp11 || getLangOpts().CPlusPlus11)) {
NewFnName = ("std::" + OldFnName).str();
else
FnInCmath = true;
} else {
NewFnName = (OldFnName + "f").str();
}

diag(Call->getExprLoc(), "call to '%0' promotes float to double")
<< OldFnName << FixItHint::CreateReplacement(
Call->getCallee()->getSourceRange(), NewFnName);

// FIXME: Perhaps we should suggest #include <cmath> if we suggest a cmath
// function and cmath is not already included.
auto Diag = diag(Call->getExprLoc(), "call to '%0' promotes float to double")
<< OldFnName
<< FixItHint::CreateReplacement(
Call->getCallee()->getSourceRange(), NewFnName);

// Suggest including <cmath> if the function we're suggesting is declared in
// <cmath> and it's not already included. We never have to suggest including
// <math.h>, because the functions we're suggesting moving away from are all
// declared in <math.h>.
if (FnInCmath)
if (auto IncludeFixit = IncludeInserter->CreateIncludeInsertion(
Result.Context->getSourceManager().getFileID(Call->getLocStart()),
"cmath", /*IsAngled=*/true))
Diag << *IncludeFixit;
}

} // namespace performance
Expand Down
Expand Up @@ -11,6 +11,7 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_TYPE_PROMOTION_IN_MATH_FN_H

#include "../ClangTidy.h"
#include "../utils/IncludeInserter.h"

namespace clang {
namespace tidy {
Expand All @@ -27,10 +28,16 @@ namespace performance {
/// http://clang.llvm.org/extra/clang-tidy/checks/performance-type-promotion-in-math-fn.html
class TypePromotionInMathFnCheck : public ClangTidyCheck {
public:
TypePromotionInMathFnCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
TypePromotionInMathFnCheck(StringRef Name, ClangTidyContext *Context);

void registerPPCallbacks(CompilerInstance &Compiler) override;
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;

private:
std::unique_ptr<utils::IncludeInserter> IncludeInserter;
const utils::IncludeSorter::IncludeStyle IncludeStyle;
};

} // namespace performance
Expand Down
@@ -1,5 +1,7 @@
// RUN: %check_clang_tidy %s performance-type-promotion-in-math-fn %t

// CHECK-FIXES: #include <cmath>

double acos(double);
double acosh(double);
double asin(double);
Expand Down

0 comments on commit 2edf6f1

Please sign in to comment.