]> granicus.if.org Git - clang/blobdiff - include/clang/AST/ASTTypeTraits.h
Header guard canonicalization, clang part.
[clang] / include / clang / AST / ASTTypeTraits.h
index 087ad5609001c418a2fd8db9d8168feb929495c2..98cab648d5830936c165bc8fa53c0d50d17fc296 100644 (file)
@@ -13,8 +13,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_AST_AST_TYPE_TRAITS_H
-#define LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+#ifndef LLVM_CLANG_AST_ASTTYPETRAITS_H
+#define LLVM_CLANG_AST_ASTTYPETRAITS_H
 
 #include "clang/AST/ASTFwd.h"
 #include "clang/AST/Decl.h"
@@ -57,11 +57,18 @@ public:
   bool isSame(ASTNodeKind Other) const;
 
   /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
-  bool isBaseOf(ASTNodeKind Other) const;
+  /// \param Distance If non-null, used to return the distance between \c this
+  /// and \c Other in the class hierarchy.
+  bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
 
   /// \brief String representation of the kind.
   StringRef asStringRef() const;
 
+  /// \brief Strict weak ordering for ASTNodeKind.
+  bool operator<(const ASTNodeKind &Other) const {
+    return KindId < Other.KindId;
+  }
+
 private:
   /// \brief Kind ids.
   ///
@@ -91,7 +98,9 @@ private:
 
   /// \brief Returns \c true if \c Base is a base kind of (or same as) \c
   ///   Derived.
-  static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
+  /// \param Distance If non-null, used to return the distance between \c Base
+  /// and \c Derived in the class hierarchy.
+  static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
 
   /// \brief Helper meta-function to convert a kind T to its enum value.
   ///
@@ -133,6 +142,11 @@ KIND_TO_KIND_ID(Type)
 #include "clang/AST/TypeNodes.def"
 #undef KIND_TO_KIND_ID
 
+inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
+  OS << K.asStringRef();
+  return OS;
+}
+
 /// \brief A dynamically typed AST node container.
 ///
 /// Stores an AST node in a type safe way. This allows writing code that
@@ -198,8 +212,8 @@ public:
     return getMemoizationData() < Other.getMemoizationData();
   }
   bool operator==(const DynTypedNode &Other) const {
-    // Nodes with different types cannot be equal.
-    if (!NodeKind.isSame(Other.NodeKind))
+    if (!NodeKind.isBaseOf(Other.NodeKind) &&
+        !Other.NodeKind.isBaseOf(NodeKind))
       return false;
 
     // FIXME: Implement for other types.
@@ -223,7 +237,7 @@ private:
     static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
       if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind))
         return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
-      return NULL;
+      return nullptr;
     }
     static DynTypedNode create(const BaseT &Node) {
       DynTypedNode Result;
@@ -238,7 +252,7 @@ private:
     static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
       if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
         return *reinterpret_cast<T *const *>(Storage);
-      return NULL;
+      return nullptr;
     }
     static DynTypedNode create(const T &Node) {
       DynTypedNode Result;
@@ -253,7 +267,7 @@ private:
     static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
       if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
         return reinterpret_cast<const T *>(Storage);
-      return NULL;
+      return nullptr;
     }
     static DynTypedNode create(const T &Node) {
       DynTypedNode Result;
@@ -283,18 +297,18 @@ private:
 
 template <typename T>
 struct DynTypedNode::BaseConverter<
-    T, typename llvm::enable_if<llvm::is_base_of<
-           Decl, T> >::type> : public DynCastPtrConverter<T, Decl> {};
+    T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
+    : public DynCastPtrConverter<T, Decl> {};
 
 template <typename T>
 struct DynTypedNode::BaseConverter<
-    T, typename llvm::enable_if<llvm::is_base_of<
-           Stmt, T> >::type> : public DynCastPtrConverter<T, Stmt> {};
+    T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
+    : public DynCastPtrConverter<T, Stmt> {};
 
 template <typename T>
 struct DynTypedNode::BaseConverter<
-    T, typename llvm::enable_if<llvm::is_base_of<
-           Type, T> >::type> : public DynCastPtrConverter<T, Type> {};
+    T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
+    : public DynCastPtrConverter<T, Type> {};
 
 template <>
 struct DynTypedNode::BaseConverter<
@@ -341,10 +355,10 @@ inline const void *DynTypedNode::getMemoizationData() const {
   } else if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind)) {
     return BaseConverter<NestedNameSpecifier>::get(NodeKind, Storage.buffer);
   }
-  return NULL;
+  return nullptr;
 }
 
 } // end namespace ast_type_traits
 } // end namespace clang
 
-#endif // LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+#endif