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);
}
/// \}
/// 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
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;
}
/// 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;
}
};
/// 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.
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());