1 //===--- MagicNumbersCheck.h - clang-tidy-----------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MAGICNUMBERSCHECK_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MAGICNUMBERSCHECK_H
12 #include "../ClangTidyCheck.h"
13 #include "clang/Lex/Lexer.h"
14 #include <llvm/ADT/APFloat.h>
15 #include <llvm/ADT/SmallVector.h>
17 namespace clang::tidy::readability
{
19 /// Detects magic numbers, integer and floating point literals embedded in code.
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
{
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
;
31 bool isConstant(const clang::ast_matchers::MatchFinder::MatchResult
&Result
,
32 const clang::Expr
&ExprResult
) const;
34 bool isIgnoredValue(const IntegerLiteral
*Literal
) const;
35 bool isIgnoredValue(const FloatingLiteral
*Literal
) const;
37 bool isSyntheticValue(const clang::SourceManager
*,
38 const FloatingLiteral
*) const {
41 bool isSyntheticValue(const clang::SourceManager
*SourceManager
,
42 const IntegerLiteral
*Literal
) const;
44 bool isBitFieldWidth(const clang::ast_matchers::MatchFinder::MatchResult
&,
45 const FloatingLiteral
&) const {
49 bool isBitFieldWidth(const clang::ast_matchers::MatchFinder::MatchResult
&Result
,
50 const IntegerLiteral
&Literal
) const;
52 bool isUserDefinedLiteral(
53 const clang::ast_matchers::MatchFinder::MatchResult
&Result
,
54 const clang::Expr
&Literal
) const;
57 void checkBoundMatch(const ast_matchers::MatchFinder::MatchResult
&Result
,
58 const char *BoundName
) {
59 const L
*MatchedLiteral
= Result
.Nodes
.getNodeAs
<L
>(BoundName
);
63 if (Result
.SourceManager
->isMacroBodyExpansion(
64 MatchedLiteral
->getLocation()))
67 if (isIgnoredValue(MatchedLiteral
))
70 if (isConstant(Result
, *MatchedLiteral
))
73 if (isSyntheticValue(Result
.SourceManager
, MatchedLiteral
))
76 if (isBitFieldWidth(Result
, *MatchedLiteral
))
79 if (IgnoreUserDefinedLiterals
&&
80 isUserDefinedLiteral(Result
, *MatchedLiteral
))
83 const StringRef LiteralSourceText
= Lexer::getSourceText(
84 CharSourceRange::getTokenRange(MatchedLiteral
->getSourceRange()),
85 *Result
.SourceManager
, getLangOpts());
87 diag(MatchedLiteral
->getLocation(),
88 "%0 is a magic number; consider replacing it with a named constant")
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
;
100 constexpr static unsigned SensibleNumberOfMagicValueExceptions
= 16;
102 constexpr static llvm::APFloat::roundingMode DefaultRoundingMode
=
103 llvm::APFloat::rmNearestTiesToEven
;
105 llvm::SmallVector
<int64_t, SensibleNumberOfMagicValueExceptions
>
106 IgnoredIntegerValues
;
107 llvm::SmallVector
<float, SensibleNumberOfMagicValueExceptions
>
108 IgnoredFloatingPointValues
;
109 llvm::SmallVector
<double, SensibleNumberOfMagicValueExceptions
>
110 IgnoredDoublePointValues
;
113 } // namespace clang::tidy::readability
115 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MAGICNUMBERSCHECK_H