[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