Skip to content

Commit 125ec4e

Browse files
author
higher-performance
committed
Add isTrivial() and isTriviallyCopyable() AST matchers
1 parent 25ebbe3 commit 125ec4e

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5440,6 +5440,43 @@ AST_MATCHER(FunctionDecl, isDefaulted) {
54405440
return Node.isDefaulted();
54415441
}
54425442

5443+
/// Matches trivial methods and types.
5444+
///
5445+
/// Given:
5446+
/// \code
5447+
/// class A { A(); };
5448+
/// A::A() = default;
5449+
/// class B { B() = default; };
5450+
/// \endcode
5451+
/// cxxMethodDecl(isTrivial())
5452+
/// matches the declaration of B, but not A.
5453+
AST_POLYMORPHIC_MATCHER(isTrivial,
5454+
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXMethodDecl,
5455+
CXXRecordDecl)) {
5456+
if (const auto *E = dyn_cast<CXXMethodDecl>(&Node))
5457+
return E->isTrivial();
5458+
if (const auto *E = dyn_cast<CXXRecordDecl>(&Node)) {
5459+
const auto *Def = Node.getDefinition();
5460+
return Def && Def->isTrivial();
5461+
}
5462+
return false;
5463+
}
5464+
5465+
/// Matches trivially copyable types.
5466+
///
5467+
/// Given:
5468+
/// \code
5469+
/// class A { A(const A &); };
5470+
/// A::A(const A &) = default;
5471+
/// class B { B(const B &) = default; };
5472+
/// \endcode
5473+
/// cxxMethodDecl(isTriviallyCopyable())
5474+
/// matches the declaration of B, but not A.
5475+
AST_MATCHER(CXXRecordDecl, isTriviallyCopyable) {
5476+
CXXRecordDecl *Def = Node.getDefinition();
5477+
return Def && Def->isTriviallyCopyable();
5478+
}
5479+
54435480
/// Matches weak function declarations.
54445481
///
54455482
/// Given:

clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,6 +1849,33 @@ TEST_P(ASTMatchersTest, IsDeleted) {
18491849
functionDecl(hasName("Func"), isDeleted())));
18501850
}
18511851

1852+
TEST_P(ASTMatchersTest, IsTrivial) {
1853+
if (!GetParam().isCXX()) {
1854+
return;
1855+
}
1856+
1857+
EXPECT_TRUE(notMatches("class A { A(); };",
1858+
cxxRecordDecl(hasName("A"), isTrivial())));
1859+
EXPECT_TRUE(matches("class B { B() = default; };",
1860+
cxxRecordDecl(hasName("B"), isTrivial())));
1861+
1862+
EXPECT_TRUE(notMatches("class A { ~A(); }; A::~A() = default;",
1863+
cxxMethodDecl(hasName("~A"), isTrivial())));
1864+
EXPECT_TRUE(matches("class B { ~B() = default; };",
1865+
cxxMethodDecl(hasName("~B"), isTrivial())));
1866+
}
1867+
1868+
TEST_P(ASTMatchersTest, IsTriviallyCopyable) {
1869+
if (!GetParam().isCXX()) {
1870+
return;
1871+
}
1872+
1873+
EXPECT_TRUE(notMatches("class A { ~A(); }; A::~A() = default;",
1874+
cxxRecordDecl(hasName("A"), isTriviallyCopyable())));
1875+
EXPECT_TRUE(matches("class B { ~B() = default; };",
1876+
cxxRecordDecl(hasName("B"), isTriviallyCopyable())));
1877+
}
1878+
18521879
TEST_P(ASTMatchersTest, IsNoThrow_DynamicExceptionSpec) {
18531880
if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
18541881
return;

0 commit comments

Comments
 (0)