Skip to content

Commit 576283c

Browse files
committed
[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
1 parent 3ab947e commit 576283c

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

clang/include/clang/AST/ASTTypeTraits.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,10 @@ enum TraversalKind {
5151
class ASTNodeKind {
5252
public:
5353
/// Empty identifier. It matches nothing.
54-
ASTNodeKind() : KindId(NKI_None) {}
54+
constexpr ASTNodeKind() : KindId(NKI_None) {}
5555

5656
/// Construct an identifier for T.
57-
template <class T>
58-
static ASTNodeKind getFromNodeKind() {
57+
template <class T> static constexpr ASTNodeKind getFromNodeKind() {
5958
return ASTNodeKind(KindToKindId<T>::Id);
6059
}
6160

@@ -71,12 +70,12 @@ class ASTNodeKind {
7170
/// \}
7271

7372
/// Returns \c true if \c this and \c Other represent the same kind.
74-
bool isSame(ASTNodeKind Other) const {
73+
constexpr bool isSame(ASTNodeKind Other) const {
7574
return KindId != NKI_None && KindId == Other.KindId;
7675
}
7776

7877
/// Returns \c true only for the default \c ASTNodeKind()
79-
bool isNone() const { return KindId == NKI_None; }
78+
constexpr bool isNone() const { return KindId == NKI_None; }
8079

8180
/// Returns \c true if \c this is a base kind of (or same as) \c Other.
8281
/// \param Distance If non-null, used to return the distance between \c this
@@ -87,7 +86,7 @@ class ASTNodeKind {
8786
StringRef asStringRef() const;
8887

8988
/// Strict weak ordering for ASTNodeKind.
90-
bool operator<(const ASTNodeKind &Other) const {
89+
constexpr bool operator<(const ASTNodeKind &Other) const {
9190
return KindId < Other.KindId;
9291
}
9392

@@ -121,7 +120,7 @@ class ASTNodeKind {
121120

122121
/// Check if the given ASTNodeKind identifies a type that offers pointer
123122
/// identity. This is useful for the fast path in DynTypedNode.
124-
bool hasPointerIdentity() const {
123+
constexpr bool hasPointerIdentity() const {
125124
return KindId > NKI_LastKindWithoutPointerIdentity;
126125
}
127126

@@ -165,7 +164,7 @@ class ASTNodeKind {
165164
};
166165

167166
/// Use getFromNodeKind<T>() to construct the kind.
168-
ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
167+
constexpr ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
169168

170169
/// Returns \c true if \c Base is a base kind of (or same as) \c
171170
/// Derived.

clang/unittests/AST/ASTTypeTraitsTest.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,47 @@ TEST(ASTNodeKind, UnknownKind) {
117117
EXPECT_FALSE(DNT<Foo>().isSame(DNT<Foo>()));
118118
}
119119

120+
template <typename T>
121+
constexpr bool HasPointerIdentity =
122+
ASTNodeKind::getFromNodeKind<T>().hasPointerIdentity();
123+
124+
TEST(ASTNodeKind, ConstexprHasPointerIdentity) {
125+
EXPECT_TRUE(HasPointerIdentity<Decl>);
126+
EXPECT_TRUE(HasPointerIdentity<Stmt>);
127+
EXPECT_FALSE(HasPointerIdentity<TypeLoc>);
128+
EXPECT_FALSE(HasPointerIdentity<QualType>);
129+
EXPECT_FALSE(HasPointerIdentity<Foo>);
130+
131+
constexpr bool DefaultConstructedHasPointerIdentity =
132+
ASTNodeKind().hasPointerIdentity();
133+
EXPECT_FALSE(DefaultConstructedHasPointerIdentity);
134+
}
135+
136+
template <typename T, typename U>
137+
constexpr bool NodeKindIsSame =
138+
ASTNodeKind::getFromNodeKind<T>().isSame(ASTNodeKind::getFromNodeKind<U>());
139+
140+
TEST(ASTNodeKind, ConstexprIsSame) {
141+
EXPECT_TRUE((NodeKindIsSame<Decl, Decl>));
142+
EXPECT_FALSE((NodeKindIsSame<Decl, VarDecl>));
143+
EXPECT_FALSE((NodeKindIsSame<Foo, Foo>));
144+
145+
constexpr bool DefaultConstructedIsSameToDefaultConstructed =
146+
ASTNodeKind().isSame(ASTNodeKind());
147+
EXPECT_FALSE(DefaultConstructedIsSameToDefaultConstructed);
148+
}
149+
150+
template <typename T>
151+
constexpr bool NodeKindIsNone = ASTNodeKind::getFromNodeKind<T>().isNone();
152+
153+
TEST(ASTNodeKind, ConstexprIsNone) {
154+
EXPECT_FALSE(NodeKindIsNone<Decl>);
155+
EXPECT_TRUE(NodeKindIsNone<Foo>);
156+
157+
constexpr bool DefaultConstructedIsNone = ASTNodeKind().isNone();
158+
EXPECT_TRUE(DefaultConstructedIsNone);
159+
}
160+
120161
TEST(ASTNodeKind, Name) {
121162
EXPECT_EQ("<None>", ASTNodeKind().asStringRef());
122163
#define VERIFY_NAME(Node) EXPECT_EQ(#Node, DNT<Node>().asStringRef());

0 commit comments

Comments
 (0)