Adds the IgnoreBitFieldsWidths option to readability-magic-numbers.
using namespace clang::ast_matchers;
using namespace clang::ast_type_traits;
-namespace {
+namespace clang {
-bool isUsedToInitializeAConstant(const MatchFinder::MatchResult &Result,
- const DynTypedNode &Node) {
+static bool isUsedToInitializeAConstant(const MatchFinder::MatchResult &Result,
+ const DynTypedNode &Node) {
- const auto *AsDecl = Node.get<clang::DeclaratorDecl>();
+ const auto *AsDecl = Node.get<DeclaratorDecl>();
if (AsDecl) {
if (AsDecl->getType().isConstQualified())
return true;
return AsDecl->isImplicit();
}
- if (Node.get<clang::EnumConstantDecl>() != nullptr)
+ if (Node.get<EnumConstantDecl>() != nullptr)
return true;
return llvm::any_of(Result.Context->getParents(Node),
});
}
-} // namespace
+static bool isUsedToDefineABitField(const MatchFinder::MatchResult &Result,
+ const DynTypedNode &Node) {
+ const auto *AsFieldDecl = Node.get<FieldDecl>();
+ if (AsFieldDecl && AsFieldDecl->isBitField())
+ return true;
+
+ return llvm::any_of(Result.Context->getParents(Node),
+ [&Result](const DynTypedNode &Parent) {
+ return isUsedToDefineABitField(Result, Parent);
+ });
+}
-namespace clang {
namespace tidy {
namespace readability {
: ClangTidyCheck(Name, Context),
IgnoreAllFloatingPointValues(
Options.get("IgnoreAllFloatingPointValues", false)),
+ IgnoreBitFieldsWidths(Options.get("IgnoreBitFieldsWidths", true)),
IgnorePowersOf2IntegerValues(
Options.get("IgnorePowersOf2IntegerValues", false)) {
// Process the set of ignored integer values.
return BufferIdentifier.empty();
}
+bool MagicNumbersCheck::isBitFieldWidth(
+ const clang::ast_matchers::MatchFinder::MatchResult &Result,
+ const IntegerLiteral &Literal) const {
+ return IgnoreBitFieldsWidths &&
+ llvm::any_of(Result.Context->getParents(Literal),
+ [&Result](const DynTypedNode &Parent) {
+ return isUsedToDefineABitField(Result, Parent);
+ });
+}
+
} // namespace readability
} // namespace tidy
} // namespace clang
const FloatingLiteral *) const {
return false;
}
-
bool isSyntheticValue(const clang::SourceManager *SourceManager,
const IntegerLiteral *Literal) const;
+ bool isBitFieldWidth(const clang::ast_matchers::MatchFinder::MatchResult &,
+ const FloatingLiteral &) const {
+ return false;
+ }
+
+ bool isBitFieldWidth(const clang::ast_matchers::MatchFinder::MatchResult &Result,
+ const IntegerLiteral &Literal) const;
+
template <typename L>
void checkBoundMatch(const ast_matchers::MatchFinder::MatchResult &Result,
const char *BoundName) {
if (isSyntheticValue(Result.SourceManager, MatchedLiteral))
return;
+ if (isBitFieldWidth(Result, *MatchedLiteral))
+ return;
+
const StringRef LiteralSourceText = Lexer::getSourceText(
CharSourceRange::getTokenRange(MatchedLiteral->getSourceRange()),
*Result.SourceManager, getLangOpts());
}
const bool IgnoreAllFloatingPointValues;
+ const bool IgnoreBitFieldsWidths;
const bool IgnorePowersOf2IntegerValues;
constexpr static unsigned SensibleNumberOfMagicValueExceptions = 16;
Finds classes, structs, and unions that contain redundant member
access specifiers.
+- Improved :doc:`readability-magic-numbers
+ <clang-tidy/checks/readability-magic-numbers>` check.
+
+ The check now supports the ``IgnoreBitFieldsWidths`` option to suppress
+ the warning for numbers used to specify bit field widths.
+
- New :doc:`readability-make-member-function-const
<clang-tidy/checks/readability-make-member-function-const>` check.
Boolean value indicating whether to accept all floating point values without
warning. Default value is `false`.
+.. option:: IgnoreBitFieldsWidths
+
+ Boolean value indicating whether to accept magic numbers as bit field widths
+ without warning. This is useful for example for register definitions which
+ are generated from hardware specifications. Default value is `true`.
--- /dev/null
+// RUN: %check_clang_tidy %s readability-magic-numbers %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: readability-magic-numbers.IgnoredIntegerValues, value: "1;2;10;100;"}]}' \
+// RUN: --
+
+struct HardwareGateway {
+ /*
+ * The configuration suppresses the warnings for the bitfields...
+ */
+ unsigned int Some: 5;
+ unsigned int Bits: 7;
+ unsigned int: 7;
+ unsigned int: 0;
+ unsigned int Rest: 13;
+
+ /*
+ * ... but other fields trigger the warning.
+ */
+ unsigned int Another[3];
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+};
+
// RUN: -config='{CheckOptions: \
// RUN: [{key: readability-magic-numbers.IgnoredIntegerValues, value: "0;1;2;10;100;"}, \
// RUN: {key: readability-magic-numbers.IgnoredFloatingPointValues, value: "3.14;2.71828;9.81;10000.0;101.0;0x1.2p3"}, \
+// RUN: {key: readability-magic-numbers.IgnoreBitFieldsWidths, value: 0}, \
// RUN: {key: readability-magic-numbers.IgnorePowersOf2IntegerValues, value: 1}]}' \
// RUN: --
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
}
+struct HardwareGateway {
+ unsigned int Some: 5;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 5 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+ unsigned int Bits: 7;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 7 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+ unsigned int: 6;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 6 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+ unsigned int Flag: 1; // no warning since this is suppressed by IgnoredIntegerValues rule
+ unsigned int: 0; // no warning since this is suppressed by IgnoredIntegerValues rule
+ unsigned int Rest: 13;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 13 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+ //
+ unsigned int Another[3];
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+};
+
+
/*
* Clean code
*/