diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h --- a/clang/include/clang/AST/ASTTypeTraits.h +++ b/clang/include/clang/AST/ASTTypeTraits.h @@ -51,11 +51,10 @@ class ASTNodeKind { public: /// Empty identifier. It matches nothing. - ASTNodeKind() : KindId(NKI_None) {} + constexpr ASTNodeKind() : KindId(NKI_None) {} /// Construct an identifier for T. - template - static ASTNodeKind getFromNodeKind() { + template static constexpr ASTNodeKind getFromNodeKind() { return ASTNodeKind(KindToKindId::Id); } @@ -71,12 +70,12 @@ /// \} /// 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 @@ 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 @@ /// 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 @@ }; /// Use getFromNodeKind() 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 --- a/clang/unittests/AST/ASTTypeTraitsTest.cpp +++ b/clang/unittests/AST/ASTTypeTraitsTest.cpp @@ -117,6 +117,47 @@ EXPECT_FALSE(DNT().isSame(DNT())); } +template +constexpr bool HasPointerIdentity = + ASTNodeKind::getFromNodeKind().hasPointerIdentity(); + +TEST(ASTNodeKind, ConstexprHasPointerIdentity) { + EXPECT_TRUE(HasPointerIdentity); + EXPECT_TRUE(HasPointerIdentity); + EXPECT_FALSE(HasPointerIdentity); + EXPECT_FALSE(HasPointerIdentity); + EXPECT_FALSE(HasPointerIdentity); + + constexpr bool DefaultConstructedHasPointerIdentity = + ASTNodeKind().hasPointerIdentity(); + EXPECT_FALSE(DefaultConstructedHasPointerIdentity); +} + +template +constexpr bool NodeKindIsSame = + ASTNodeKind::getFromNodeKind().isSame(ASTNodeKind::getFromNodeKind()); + +TEST(ASTNodeKind, ConstexprIsSame) { + EXPECT_TRUE((NodeKindIsSame)); + EXPECT_FALSE((NodeKindIsSame)); + EXPECT_FALSE((NodeKindIsSame)); + + constexpr bool DefaultConstructedIsSameToDefaultConstructed = + ASTNodeKind().isSame(ASTNodeKind()); + EXPECT_FALSE(DefaultConstructedIsSameToDefaultConstructed); +} + +template +constexpr bool NodeKindIsNone = ASTNodeKind::getFromNodeKind().isNone(); + +TEST(ASTNodeKind, ConstexprIsNone) { + EXPECT_FALSE(NodeKindIsNone); + EXPECT_TRUE(NodeKindIsNone); + + constexpr bool DefaultConstructedIsNone = ASTNodeKind().isNone(); + EXPECT_TRUE(DefaultConstructedIsNone); +} + TEST(ASTNodeKind, Name) { EXPECT_EQ("", ASTNodeKind().asStringRef()); #define VERIFY_NAME(Node) EXPECT_EQ(#Node, DNT().asStringRef());