File indexing completed on 2026-05-10 08:36:22
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MAGICNUMBERSCHECK_H
0010 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MAGICNUMBERSCHECK_H
0011
0012 #include "../ClangTidyCheck.h"
0013 #include "clang/Lex/Lexer.h"
0014 #include <llvm/ADT/APFloat.h>
0015 #include <llvm/ADT/SmallVector.h>
0016
0017 namespace clang::tidy::readability {
0018
0019
0020
0021
0022
0023 class MagicNumbersCheck : public ClangTidyCheck {
0024 public:
0025 MagicNumbersCheck(StringRef Name, ClangTidyContext *Context);
0026 void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
0027 void registerMatchers(ast_matchers::MatchFinder *Finder) override;
0028 void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
0029
0030 private:
0031 bool isConstant(const clang::ast_matchers::MatchFinder::MatchResult &Result,
0032 const clang::Expr &ExprResult) const;
0033
0034 bool isIgnoredValue(const IntegerLiteral *Literal) const;
0035 bool isIgnoredValue(const FloatingLiteral *Literal) const;
0036
0037 bool isSyntheticValue(const clang::SourceManager *,
0038 const FloatingLiteral *) const {
0039 return false;
0040 }
0041 bool isSyntheticValue(const clang::SourceManager *SourceManager,
0042 const IntegerLiteral *Literal) const;
0043
0044 bool isBitFieldWidth(const clang::ast_matchers::MatchFinder::MatchResult &,
0045 const FloatingLiteral &) const {
0046 return false;
0047 }
0048
0049 bool isBitFieldWidth(const clang::ast_matchers::MatchFinder::MatchResult &Result,
0050 const IntegerLiteral &Literal) const;
0051
0052 bool isUserDefinedLiteral(
0053 const clang::ast_matchers::MatchFinder::MatchResult &Result,
0054 const clang::Expr &Literal) const;
0055
0056 template <typename L>
0057 void checkBoundMatch(const ast_matchers::MatchFinder::MatchResult &Result,
0058 const char *BoundName) {
0059 const L *MatchedLiteral = Result.Nodes.getNodeAs<L>(BoundName);
0060 if (!MatchedLiteral)
0061 return;
0062
0063 if (Result.SourceManager->isMacroBodyExpansion(
0064 MatchedLiteral->getLocation()))
0065 return;
0066
0067 if (isIgnoredValue(MatchedLiteral))
0068 return;
0069
0070 if (isConstant(Result, *MatchedLiteral))
0071 return;
0072
0073 if (isSyntheticValue(Result.SourceManager, MatchedLiteral))
0074 return;
0075
0076 if (isBitFieldWidth(Result, *MatchedLiteral))
0077 return;
0078
0079 if (IgnoreUserDefinedLiterals &&
0080 isUserDefinedLiteral(Result, *MatchedLiteral))
0081 return;
0082
0083 const StringRef LiteralSourceText = Lexer::getSourceText(
0084 CharSourceRange::getTokenRange(MatchedLiteral->getSourceRange()),
0085 *Result.SourceManager, getLangOpts());
0086
0087 diag(MatchedLiteral->getLocation(),
0088 "%0 is a magic number; consider replacing it with a named constant")
0089 << LiteralSourceText;
0090 }
0091
0092 const bool IgnoreAllFloatingPointValues;
0093 const bool IgnoreBitFieldsWidths;
0094 const bool IgnorePowersOf2IntegerValues;
0095 const bool IgnoreTypeAliases;
0096 const bool IgnoreUserDefinedLiterals;
0097 const StringRef RawIgnoredIntegerValues;
0098 const StringRef RawIgnoredFloatingPointValues;
0099
0100 constexpr static unsigned SensibleNumberOfMagicValueExceptions = 16;
0101
0102 constexpr static llvm::APFloat::roundingMode DefaultRoundingMode =
0103 llvm::APFloat::rmNearestTiesToEven;
0104
0105 llvm::SmallVector<int64_t, SensibleNumberOfMagicValueExceptions>
0106 IgnoredIntegerValues;
0107 llvm::SmallVector<float, SensibleNumberOfMagicValueExceptions>
0108 IgnoredFloatingPointValues;
0109 llvm::SmallVector<double, SensibleNumberOfMagicValueExceptions>
0110 IgnoredDoublePointValues;
0111 };
0112
0113 }
0114
0115 #endif