https://github.com/higher-performance created https://github.com/llvm/llvm-project/pull/90634
There are currently no AST matchers for the equivalent of `std::is_trivial`, `std::is_trivially_default_constructible`, `std::is_trivially_copyable`, and the like. This pull request adds matchers to check if records and their member functions are trivial. It does _not_ attempt to handle other trivial entities (such as pointers). >From 125ec4eba659ef889baeb92f18ec230a72fe3e9a Mon Sep 17 00:00:00 2001 From: higher-performance <113926...@users.noreply.github.com> Date: Tue, 30 Apr 2024 11:32:45 -0600 Subject: [PATCH] Add isTrivial() and isTriviallyCopyable() AST matchers --- clang/include/clang/ASTMatchers/ASTMatchers.h | 37 +++++++++++++++++++ .../ASTMatchers/ASTMatchersNarrowingTest.cpp | 27 ++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 2f71053d030f68..f8529105f8d034 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -5440,6 +5440,43 @@ AST_MATCHER(FunctionDecl, isDefaulted) { return Node.isDefaulted(); } +/// Matches trivial methods and types. +/// +/// Given: +/// \code +/// class A { A(); }; +/// A::A() = default; +/// class B { B() = default; }; +/// \endcode +/// cxxMethodDecl(isTrivial()) +/// matches the declaration of B, but not A. +AST_POLYMORPHIC_MATCHER(isTrivial, + AST_POLYMORPHIC_SUPPORTED_TYPES(CXXMethodDecl, + CXXRecordDecl)) { + if (const auto *E = dyn_cast<CXXMethodDecl>(&Node)) + return E->isTrivial(); + if (const auto *E = dyn_cast<CXXRecordDecl>(&Node)) { + const auto *Def = Node.getDefinition(); + return Def && Def->isTrivial(); + } + return false; +} + +/// Matches trivially copyable types. +/// +/// Given: +/// \code +/// class A { A(const A &); }; +/// A::A(const A &) = default; +/// class B { B(const B &) = default; }; +/// \endcode +/// cxxMethodDecl(isTriviallyCopyable()) +/// matches the declaration of B, but not A. +AST_MATCHER(CXXRecordDecl, isTriviallyCopyable) { + CXXRecordDecl *Def = Node.getDefinition(); + return Def && Def->isTriviallyCopyable(); +} + /// Matches weak function declarations. /// /// Given: diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 87774b00956a5a..9c648588ba970c 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -1849,6 +1849,33 @@ TEST_P(ASTMatchersTest, IsDeleted) { functionDecl(hasName("Func"), isDeleted()))); } +TEST_P(ASTMatchersTest, IsTrivial) { + if (!GetParam().isCXX()) { + return; + } + + EXPECT_TRUE(notMatches("class A { A(); };", + cxxRecordDecl(hasName("A"), isTrivial()))); + EXPECT_TRUE(matches("class B { B() = default; };", + cxxRecordDecl(hasName("B"), isTrivial()))); + + EXPECT_TRUE(notMatches("class A { ~A(); }; A::~A() = default;", + cxxMethodDecl(hasName("~A"), isTrivial()))); + EXPECT_TRUE(matches("class B { ~B() = default; };", + cxxMethodDecl(hasName("~B"), isTrivial()))); +} + +TEST_P(ASTMatchersTest, IsTriviallyCopyable) { + if (!GetParam().isCXX()) { + return; + } + + EXPECT_TRUE(notMatches("class A { ~A(); }; A::~A() = default;", + cxxRecordDecl(hasName("A"), isTriviallyCopyable()))); + EXPECT_TRUE(matches("class B { ~B() = default; };", + cxxRecordDecl(hasName("B"), isTriviallyCopyable()))); +} + TEST_P(ASTMatchersTest, IsNoThrow_DynamicExceptionSpec) { if (!GetParam().supportsCXXDynamicExceptionSpecification()) { return; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits