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