Index: clang-tools-extra/trunk/clang-tidy/performance/TypePromotionInMathFnCheck.h =================================================================== --- clang-tools-extra/trunk/clang-tidy/performance/TypePromotionInMathFnCheck.h +++ clang-tools-extra/trunk/clang-tidy/performance/TypePromotionInMathFnCheck.h @@ -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 { @@ -27,10 +28,16 @@ /// 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 IncludeInserter; + const utils::IncludeSorter::IncludeStyle IncludeStyle; }; } // namespace performance Index: clang-tools-extra/trunk/clang-tidy/performance/TypePromotionInMathFnCheck.cpp =================================================================== --- clang-tools-extra/trunk/clang-tidy/performance/TypePromotionInMathFnCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/performance/TypePromotionInMathFnCheck.cpp @@ -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; @@ -27,6 +29,26 @@ } } // 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( + 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; @@ -153,18 +175,29 @@ 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 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 if the function we're suggesting is declared in + // and it's not already included. We never have to suggest including + // , because the functions we're suggesting moving away from are all + // declared in . + if (FnInCmath) + if (auto IncludeFixit = IncludeInserter->CreateIncludeInsertion( + Result.Context->getSourceManager().getFileID(Call->getLocStart()), + "cmath", /*IsAngled=*/true)) + Diag << *IncludeFixit; } } // namespace performance Index: clang-tools-extra/trunk/test/clang-tidy/performance-type-promotion-in-math-fn.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/performance-type-promotion-in-math-fn.cpp +++ clang-tools-extra/trunk/test/clang-tidy/performance-type-promotion-in-math-fn.cpp @@ -1,5 +1,7 @@ // RUN: %check_clang_tidy %s performance-type-promotion-in-math-fn %t +// CHECK-FIXES: #include + double acos(double); double acosh(double); double asin(double);