diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index fff5366775cd2a08718fac8877ac1718c1b7bfa0..a8a47d5b54bd1fe4f2a2a63bcd4b90cd60393f58 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -1453,7 +1453,7 @@ c and d. Given enum C { Green }; - enum S { Red }; + enum class S { Red }; C c; S s; @@ -2418,6 +2418,33 @@ designatorCountIs(2) </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FieldDecl.html">FieldDecl</a>></td><td class="name" onclick="toggle('hasBitWidth0')"><a name="hasBitWidth0Anchor">hasBitWidth</a></td><td>unsigned Width</td></tr> +<tr><td colspan="4" class="doc" id="hasBitWidth0"><pre>Matches non-static data members that are bit-fields. + +Given + class C { + int a : 2; + int b : 4; + int c : 2; + }; +fieldDecl(isBitField()) + matches 'int a;' and 'int c;' but not 'int b;'. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FieldDecl.html">FieldDecl</a>></td><td class="name" onclick="toggle('isBitField0')"><a name="isBitField0Anchor">isBitField</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isBitField0"><pre>Matches non-static data members that are bit-fields. + +Given + class C { + int a : 2; + int b; + }; +fieldDecl(isBitField()) + matches 'int a;' but not 'int b;'. +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>></td><td class="name" onclick="toggle('equals1')"><a name="equals1Anchor">equals</a></td><td>ValueT Value</td></tr> <tr><td colspan="4" class="doc" id="equals1"><pre>Matches literals that are equal to the given value. diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 5ba154d335ae35561210b15575230ffe658c1a99..a5465189930c80e0f7b8340f19b8a014486f5d7f 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -519,6 +519,38 @@ AST_MATCHER(Decl, isPrivate) { return Node.getAccess() == AS_private; } +/// \brief Matches non-static data members that are bit-fields. +/// +/// Given +/// \code +/// class C { +/// int a : 2; +/// int b; +/// }; +/// \endcode +/// fieldDecl(isBitField()) +/// matches 'int a;' but not 'int b;'. +AST_MATCHER(FieldDecl, isBitField) { + return Node.isBitField(); +} + +/// \brief Matches non-static data members that are bit-fields. +/// +/// Given +/// \code +/// class C { +/// int a : 2; +/// int b : 4; +/// int c : 2; +/// }; +/// \endcode +/// fieldDecl(isBitField()) +/// matches 'int a;' and 'int c;' but not 'int b;'. +AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) { + return Node.isBitField() && + Node.getBitWidthValue(Finder->getASTContext()) == Width; +} + /// \brief Matches a declaration that has been implicitly added /// by the compiler (eg. implicit default/copy constructors). AST_MATCHER(Decl, isImplicit) { diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp index b6479b093109c6c6d67dc7c1114bd685d7351bf5..d8ddf55733fd31877d74f7081c2267b2fd47ac08 100644 --- a/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/lib/ASTMatchers/Dynamic/Registry.cpp @@ -208,6 +208,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(hasAttr); REGISTER_MATCHER(hasAutomaticStorageDuration); REGISTER_MATCHER(hasBase); + REGISTER_MATCHER(hasBitWidth); REGISTER_MATCHER(hasBody); REGISTER_MATCHER(hasCanonicalType); REGISTER_MATCHER(hasCaseConstant); @@ -283,6 +284,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(isAnyPointer); REGISTER_MATCHER(isArrow); REGISTER_MATCHER(isBaseInitializer); + REGISTER_MATCHER(isBitField); REGISTER_MATCHER(isCatchAll); REGISTER_MATCHER(isClass); REGISTER_MATCHER(isConst); diff --git a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 7deed85440d03d63d8769b610188ea293bad4706..28b462e746f0bff37e85211f04f7486a0bf2a74d 100644 --- a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -1366,6 +1366,14 @@ TEST(Member, MatchesMember) { memberExpr(hasDeclaration(fieldDecl(hasType(isInteger())))))); } +TEST(Member, BitFields) { + EXPECT_TRUE(matches("class C { int a : 2; int b; };", + fieldDecl(isBitField(), hasName("a")))); + EXPECT_TRUE(notMatches("class C { int a : 2; int b; };", + fieldDecl(isBitField(), hasName("b")))); + EXPECT_TRUE(matches("class C { int a : 2; int b : 4; };", + fieldDecl(isBitField(), hasBitWidth(2), hasName("a")))); +} TEST(Member, UnderstandsAccess) { EXPECT_TRUE(matches(