1 //===--- MagicNumbersCheck.h - clang-tidy-----------------------*- C++ -*-===// 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 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MAGICNUMBERSCHECK_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MAGICNUMBERSCHECK_H 11 12 #include "../ClangTidyCheck.h" 13 #include "clang/Lex/Lexer.h" 14 #include <llvm/ADT/APFloat.h> 15 #include <llvm/ADT/SmallVector.h> 16 17 namespace clang { 18 namespace tidy { 19 namespace readability { 20 21 /// Detects magic numbers, integer and floating point literals embedded in code. 22 /// 23 /// For the user-facing documentation see: 24 /// http://clang.llvm.org/extra/clang-tidy/checks/readability-magic-numbers.html 25 class MagicNumbersCheck : public ClangTidyCheck { 26 public: 27 MagicNumbersCheck(StringRef Name, ClangTidyContext *Context); 28 void storeOptions(ClangTidyOptions::OptionMap &Opts) override; 29 void registerMatchers(ast_matchers::MatchFinder *Finder) override; 30 void check(const ast_matchers::MatchFinder::MatchResult &Result) override; 31 32 private: 33 bool isConstant(const clang::ast_matchers::MatchFinder::MatchResult &Result, 34 const clang::Expr &ExprResult) const; 35 36 bool isIgnoredValue(const IntegerLiteral *Literal) const; 37 bool isIgnoredValue(const FloatingLiteral *Literal) const; 38 isSyntheticValue(const clang::SourceManager *,const FloatingLiteral *)39 bool isSyntheticValue(const clang::SourceManager *, 40 const FloatingLiteral *) const { 41 return false; 42 } 43 bool isSyntheticValue(const clang::SourceManager *SourceManager, 44 const IntegerLiteral *Literal) const; 45 isBitFieldWidth(const clang::ast_matchers::MatchFinder::MatchResult &,const FloatingLiteral &)46 bool isBitFieldWidth(const clang::ast_matchers::MatchFinder::MatchResult &, 47 const FloatingLiteral &) const { 48 return false; 49 } 50 51 bool isBitFieldWidth(const clang::ast_matchers::MatchFinder::MatchResult &Result, 52 const IntegerLiteral &Literal) const; 53 54 template <typename L> checkBoundMatch(const ast_matchers::MatchFinder::MatchResult & Result,const char * BoundName)55 void checkBoundMatch(const ast_matchers::MatchFinder::MatchResult &Result, 56 const char *BoundName) { 57 const L *MatchedLiteral = Result.Nodes.getNodeAs<L>(BoundName); 58 if (!MatchedLiteral) 59 return; 60 61 if (Result.SourceManager->isMacroBodyExpansion( 62 MatchedLiteral->getLocation())) 63 return; 64 65 if (isIgnoredValue(MatchedLiteral)) 66 return; 67 68 if (isConstant(Result, *MatchedLiteral)) 69 return; 70 71 if (isSyntheticValue(Result.SourceManager, MatchedLiteral)) 72 return; 73 74 if (isBitFieldWidth(Result, *MatchedLiteral)) 75 return; 76 77 const StringRef LiteralSourceText = Lexer::getSourceText( 78 CharSourceRange::getTokenRange(MatchedLiteral->getSourceRange()), 79 *Result.SourceManager, getLangOpts()); 80 81 diag(MatchedLiteral->getLocation(), 82 "%0 is a magic number; consider replacing it with a named constant") 83 << LiteralSourceText; 84 } 85 86 const bool IgnoreAllFloatingPointValues; 87 const bool IgnoreBitFieldsWidths; 88 const bool IgnorePowersOf2IntegerValues; 89 const std::string RawIgnoredIntegerValues; 90 const std::string RawIgnoredFloatingPointValues; 91 92 constexpr static unsigned SensibleNumberOfMagicValueExceptions = 16; 93 94 constexpr static llvm::APFloat::roundingMode DefaultRoundingMode = 95 llvm::APFloat::rmNearestTiesToEven; 96 97 llvm::SmallVector<int64_t, SensibleNumberOfMagicValueExceptions> 98 IgnoredIntegerValues; 99 llvm::SmallVector<float, SensibleNumberOfMagicValueExceptions> 100 IgnoredFloatingPointValues; 101 llvm::SmallVector<double, SensibleNumberOfMagicValueExceptions> 102 IgnoredDoublePointValues; 103 }; 104 105 } // namespace readability 106 } // namespace tidy 107 } // namespace clang 108 109 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MAGICNUMBERSCHECK_H 110