[clang] 576283c - [clang] Support `constexpr` for some `ASTNodeKind` member functions
Eric Li via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 13 10:01:32 PDT 2022
Author: Eric Li
Date: 2022-10-13T13:00:48-04:00
New Revision: 576283c3a8ef5078b3ec12fa442c14f3a1b5fea2
URL: https://github.com/llvm/llvm-project/commit/576283c3a8ef5078b3ec12fa442c14f3a1b5fea2
DIFF: https://github.com/llvm/llvm-project/commit/576283c3a8ef5078b3ec12fa442c14f3a1b5fea2.diff
LOG: [clang] Support `constexpr` for some `ASTNodeKind` member functions
Add `constexpr` support for:
* The `getFromNodeKind` factory function
* `isSame`
* `isNone`
* `hasPointerIdentity`
This enables these functions to be used in SFINAE context for AST node
types.
Differential Revision: https://reviews.llvm.org/D135816
Added:
Modified:
clang/include/clang/AST/ASTTypeTraits.h
clang/unittests/AST/ASTTypeTraitsTest.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h
index cd6b5143bf79..8713221a7378 100644
--- a/clang/include/clang/AST/ASTTypeTraits.h
+++ b/clang/include/clang/AST/ASTTypeTraits.h
@@ -51,11 +51,10 @@ enum TraversalKind {
class ASTNodeKind {
public:
/// Empty identifier. It matches nothing.
- ASTNodeKind() : KindId(NKI_None) {}
+ constexpr ASTNodeKind() : KindId(NKI_None) {}
/// Construct an identifier for T.
- template <class T>
- static ASTNodeKind getFromNodeKind() {
+ template <class T> static constexpr ASTNodeKind getFromNodeKind() {
return ASTNodeKind(KindToKindId<T>::Id);
}
@@ -71,12 +70,12 @@ class ASTNodeKind {
/// \}
/// Returns \c true if \c this and \c Other represent the same kind.
- bool isSame(ASTNodeKind Other) const {
+ constexpr bool isSame(ASTNodeKind Other) const {
return KindId != NKI_None && KindId == Other.KindId;
}
/// Returns \c true only for the default \c ASTNodeKind()
- bool isNone() const { return KindId == NKI_None; }
+ constexpr bool isNone() const { return KindId == NKI_None; }
/// Returns \c true if \c this is a base kind of (or same as) \c Other.
/// \param Distance If non-null, used to return the distance between \c this
@@ -87,7 +86,7 @@ class ASTNodeKind {
StringRef asStringRef() const;
/// Strict weak ordering for ASTNodeKind.
- bool operator<(const ASTNodeKind &Other) const {
+ constexpr bool operator<(const ASTNodeKind &Other) const {
return KindId < Other.KindId;
}
@@ -121,7 +120,7 @@ class ASTNodeKind {
/// Check if the given ASTNodeKind identifies a type that offers pointer
/// identity. This is useful for the fast path in DynTypedNode.
- bool hasPointerIdentity() const {
+ constexpr bool hasPointerIdentity() const {
return KindId > NKI_LastKindWithoutPointerIdentity;
}
@@ -165,7 +164,7 @@ class ASTNodeKind {
};
/// Use getFromNodeKind<T>() to construct the kind.
- ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
+ constexpr ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
/// Returns \c true if \c Base is a base kind of (or same as) \c
/// Derived.
diff --git a/clang/unittests/AST/ASTTypeTraitsTest.cpp b/clang/unittests/AST/ASTTypeTraitsTest.cpp
index 9fcb00630209..dcea32d1f1c0 100644
--- a/clang/unittests/AST/ASTTypeTraitsTest.cpp
+++ b/clang/unittests/AST/ASTTypeTraitsTest.cpp
@@ -117,6 +117,47 @@ TEST(ASTNodeKind, UnknownKind) {
EXPECT_FALSE(DNT<Foo>().isSame(DNT<Foo>()));
}
+template <typename T>
+constexpr bool HasPointerIdentity =
+ ASTNodeKind::getFromNodeKind<T>().hasPointerIdentity();
+
+TEST(ASTNodeKind, ConstexprHasPointerIdentity) {
+ EXPECT_TRUE(HasPointerIdentity<Decl>);
+ EXPECT_TRUE(HasPointerIdentity<Stmt>);
+ EXPECT_FALSE(HasPointerIdentity<TypeLoc>);
+ EXPECT_FALSE(HasPointerIdentity<QualType>);
+ EXPECT_FALSE(HasPointerIdentity<Foo>);
+
+ constexpr bool DefaultConstructedHasPointerIdentity =
+ ASTNodeKind().hasPointerIdentity();
+ EXPECT_FALSE(DefaultConstructedHasPointerIdentity);
+}
+
+template <typename T, typename U>
+constexpr bool NodeKindIsSame =
+ ASTNodeKind::getFromNodeKind<T>().isSame(ASTNodeKind::getFromNodeKind<U>());
+
+TEST(ASTNodeKind, ConstexprIsSame) {
+ EXPECT_TRUE((NodeKindIsSame<Decl, Decl>));
+ EXPECT_FALSE((NodeKindIsSame<Decl, VarDecl>));
+ EXPECT_FALSE((NodeKindIsSame<Foo, Foo>));
+
+ constexpr bool DefaultConstructedIsSameToDefaultConstructed =
+ ASTNodeKind().isSame(ASTNodeKind());
+ EXPECT_FALSE(DefaultConstructedIsSameToDefaultConstructed);
+}
+
+template <typename T>
+constexpr bool NodeKindIsNone = ASTNodeKind::getFromNodeKind<T>().isNone();
+
+TEST(ASTNodeKind, ConstexprIsNone) {
+ EXPECT_FALSE(NodeKindIsNone<Decl>);
+ EXPECT_TRUE(NodeKindIsNone<Foo>);
+
+ constexpr bool DefaultConstructedIsNone = ASTNodeKind().isNone();
+ EXPECT_TRUE(DefaultConstructedIsNone);
+}
+
TEST(ASTNodeKind, Name) {
EXPECT_EQ("<None>", ASTNodeKind().asStringRef());
#define VERIFY_NAME(Node) EXPECT_EQ(#Node, DNT<Node>().asStringRef());
More information about the cfe-commits
mailing list